Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
d1269bc
Fixed weird margin error on heading. Fixed list numbering bug
milaiwi Apr 26, 2025
1a9dfce
Fixed weird margin error on headings. Fixed list numbering bug
milaiwi Apr 26, 2025
62ad58b
Fixed pasting on non-media files.
milaiwi Apr 27, 2025
6d88c62
Fixed pasting on non-media files.
milaiwi Apr 27, 2025
ad9638a
Merged with fix pasting
milaiwi Apr 27, 2025
b6c8aeb
Fixed header bugs and pasting bugs
milaiwi Apr 27, 2025
08007bb
Working on cleaning up semantic-similarity
milaiwi May 2, 2025
187dab5
Made structural changes to editor -- currentFilePatha and semanticCha…
milaiwi May 2, 2025
ea0e789
Hard coded double bracket linkage to a file with serialization and pa…
milaiwi May 3, 2025
99e7611
Added dynamic linking, just need ot configure it and make it more cle…
milaiwi May 3, 2025
44d735a
Able to link between files. Changed editor structure. Fixed logic aro…
milaiwi May 3, 2025
c1b9a31
Working LinkToolbarPositioner but need to change content that displays
milaiwi May 4, 2025
6dddc7d
Added caching for link similar files
milaiwi May 5, 2025
14272e1
Working linking between files. Need to create a difference between in…
milaiwi May 6, 2025
8387172
Fixed internal and external linking
milaiwi May 6, 2025
64878dd
Configuring link layout
milaiwi May 6, 2025
5f69f60
Converting to Menu
milaiwi May 6, 2025
edc6c6c
LinkToolContent working but need to add keystrokes
milaiwi May 7, 2025
428f768
Converted XStacks and YStacks to Menu
milaiwi May 7, 2025
28f2e74
Add deduping for semanticService.ts
milaiwi May 7, 2025
478256f
Extended blocknote. Added linking
milaiwi May 7, 2025
68df180
Extended blocknote. Added linking
milaiwi May 7, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 32 additions & 2 deletions electron/main/filesystem/filesystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,19 +112,26 @@ export function GetFilesInfoListForListOfPaths(paths: string[]): FileInfo[] {
return fileInfoListWithoutDuplicates
}

export function createFileRecursive(filePath: string, content: string, charset?: BufferEncoding): void {
export function createFileRecursive(filePath: string, content: string, charset?: BufferEncoding): FileInfo | null {
const dirname = path.dirname(filePath)

if (!fs.existsSync(dirname)) {
fs.mkdirSync(dirname, { recursive: true })
}

if (fs.existsSync(filePath)) {
return
return null
}
const filePathWithExtension = addExtensionToFilenameIfNoExtensionPresent(filePath, markdownExtensions, '.md')

fs.writeFileSync(filePathWithExtension, content, charset)
return {
name: path.basename(filePathWithExtension),
path: filePathWithExtension,
relativePath: path.relative(dirname, filePathWithExtension),
dateModified: new Date(),
dateCreated: new Date(),
}
}
Comment on lines +115 to 135
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: The function now returns a FileInfo object with hardcoded dates. Consider using the actual file stats (mtime and birthtime) from fs.statSync() after file creation for accuracy.

Suggested change
export function createFileRecursive(filePath: string, content: string, charset?: BufferEncoding): FileInfo | null {
const dirname = path.dirname(filePath)
if (!fs.existsSync(dirname)) {
fs.mkdirSync(dirname, { recursive: true })
}
if (fs.existsSync(filePath)) {
return
return null
}
const filePathWithExtension = addExtensionToFilenameIfNoExtensionPresent(filePath, markdownExtensions, '.md')
fs.writeFileSync(filePathWithExtension, content, charset)
return {
name: path.basename(filePathWithExtension),
path: filePathWithExtension,
relativePath: path.relative(dirname, filePathWithExtension),
dateModified: new Date(),
dateCreated: new Date(),
}
}
export function createFileRecursive(filePath: string, content: string, charset?: BufferEncoding): FileInfo | null {
const dirname = path.dirname(filePath)
if (!fs.existsSync(dirname)) {
fs.mkdirSync(dirname, { recursive: true })
}
if (fs.existsSync(filePath)) {
return null
}
const filePathWithExtension = addExtensionToFilenameIfNoExtensionPresent(filePath, markdownExtensions, '.md')
fs.writeFileSync(filePathWithExtension, content, charset)
const stats = fs.statSync(filePathWithExtension)
return {
name: path.basename(filePathWithExtension),
path: filePathWithExtension,
relativePath: path.relative(dirname, filePathWithExtension),
dateModified: stats.mtime,
dateCreated: stats.birthtime,
}
}


export function updateFileListForRenderer(win: BrowserWindow, directory: string): void {
Expand Down Expand Up @@ -194,3 +201,26 @@ export function splitDirectoryPathIntoBaseAndRepo(fullPath: string) {

return { localModelPath, repoName }
}

export function findFileRecursive(dir: string, filename: string): string | null {
const files = fs.readdirSync(dir)
const basename = path.parse(filename).name

for (const file of files) {
const fullPath = path.resolve(dir, file)
const stat = fs.statSync(fullPath)

if (stat.isDirectory()) {
const result = findFileRecursive(fullPath, filename)
if (result) return result
} else {
// Check if files match
const fileName = path.parse(file).name
if (fileName === basename) {
return fullPath
}
}
}

return null
}
Comment on lines +205 to +226
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: The recursive file search doesn't handle file extensions, which could lead to incorrect matches when multiple files have the same basename but different extensions.

19 changes: 16 additions & 3 deletions electron/main/filesystem/ipcHandlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { StoreSchema } from '../electron-store/storeConfig'
import { handleFileRename, updateFileInTable } from '../vector-database/tableHelperFunctions'

import { GetFilesInfoTree, createFileRecursive, isHidden, GetFilesInfoListForListOfPaths } from './filesystem'
import { FileInfoTree, WriteFileProps, RenameFileProps, FileInfoWithContent } from './types'
import { FileInfoTree, WriteFileProps, RenameFileProps, FileInfoWithContent, FileInfo } from './types'
import ImageStorage from './storage/ImageStore'
import VideoStorage from './storage/VideoStore'

Expand Down Expand Up @@ -145,8 +145,10 @@ const registerFileHandlers = (store: Store<StoreSchema>, _windowsManager: Window
await updateFileInTable(windowInfo.dbTableClient, filePath)
})

ipcMain.handle('create-file', async (event, filePath: string, content: string): Promise<void> => {
createFileRecursive(filePath, content, 'utf-8')
ipcMain.handle('create-file', async (event, filePath: string, content: string): Promise<FileInfo | undefined> => {
const fileObject = createFileRecursive(filePath, content, 'utf-8')
if (fileObject) return fileObject
return undefined
})

ipcMain.handle('create-directory', async (event, dirPath: string): Promise<void> => {
Expand Down Expand Up @@ -217,6 +219,17 @@ const registerFileHandlers = (store: Store<StoreSchema>, _windowsManager: Window
})
return result.filePaths
})

ipcMain.handle('get-file-info', (event, absolutePath: string, parentRelativePath: string): FileInfo => {
const fileInfo = fs.statSync(absolutePath)
return {
name: path.basename(absolutePath),
path: absolutePath,
relativePath: parentRelativePath,
dateModified: fileInfo.mtime,
dateCreated: fileInfo.birthtime, // Add the birthtime property here
}
})
Comment on lines +223 to +232
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: get-file-info doesn't handle errors from fs.statSync which could crash the app. Should use try/catch

Suggested change
ipcMain.handle('get-file-info', (event, absolutePath: string, parentRelativePath: string): FileInfo => {
const fileInfo = fs.statSync(absolutePath)
return {
name: path.basename(absolutePath),
path: absolutePath,
relativePath: parentRelativePath,
dateModified: fileInfo.mtime,
dateCreated: fileInfo.birthtime, // Add the birthtime property here
}
})
ipcMain.handle('get-file-info', (event, absolutePath: string, parentRelativePath: string): FileInfo => {
try {
const fileInfo = fs.statSync(absolutePath)
return {
name: path.basename(absolutePath),
path: absolutePath,
relativePath: parentRelativePath,
dateModified: fileInfo.mtime,
dateCreated: fileInfo.birthtime,
}
} catch (error) {
throw new Error(`Failed to get file info: ${error}`)
}
})

}

export default registerFileHandlers
5 changes: 5 additions & 0 deletions electron/main/path/ipcHandlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ const registerPathHandlers = () => {
)

ipcMain.handle('path-ext-name', (event, pathString: string) => path.extname(pathString))

ipcMain.handle('find-absolute-path', (event, filePath: string) => {
const absolutePath = path.resolve(filePath)
return absolutePath
})
}

export default registerPathHandlers
3 changes: 1 addition & 2 deletions electron/main/vector-database/lanceTableWrapper.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Connection, Table as LanceDBTable, MetricType, makeArrowTable } from 'vectordb'

import { EmbeddingModelConfig } from '../electron-store/storeConfig'

import { EnhancedEmbeddingFunction, createEmbeddingFunction } from './embeddings'
Expand Down Expand Up @@ -102,7 +101,7 @@ class LanceDBTableWrapper {
}

async search(query: string, limit: number, filter?: string): Promise<DBQueryResult[]> {
const lanceQuery = await this.lanceTable.search(query).metricType(MetricType.Cosine).limit(limit)
const lanceQuery = this.lanceTable.search(query).metricType(MetricType.Cosine).limit(limit)

if (filter) {
lanceQuery.prefilter(true)
Expand Down
3 changes: 3 additions & 0 deletions electron/main/vector-database/schema.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Schema, Field, Utf8, FixedSizeList, Float32, Float64, DateUnit, Date_ as ArrowDate } from 'apache-arrow'

export interface DBEntry {
name: string
notepath: string
content: string
subnoteindex: number
Expand All @@ -15,6 +16,7 @@ export interface DBQueryResult extends DBEntry {
export const chunksize = 500

export enum DatabaseFields {
NAME = 'name',
NOTE_PATH = 'notepath',
VECTOR = 'vector',
CONTENT = 'content',
Expand All @@ -27,6 +29,7 @@ export enum DatabaseFields {

const CreateDatabaseSchema = (vectorDim: number): Schema => {
const schemaFields = [
new Field(DatabaseFields.NAME, new Utf8(), false),
new Field(DatabaseFields.NOTE_PATH, new Utf8(), false),
new Field(DatabaseFields.VECTOR, new FixedSizeList(vectorDim, new Field('item', new Float32())), false),
new Field(DatabaseFields.CONTENT, new Utf8(), false),
Expand Down
4 changes: 4 additions & 0 deletions electron/main/vector-database/tableHelperFunctions.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as fs from 'fs'
import * as fsPromises from 'fs/promises'
import path from 'path'

import { BrowserWindow } from 'electron'
import { chunkMarkdownByHeadingsAndByCharsIfBig } from '../common/chunking'
Expand All @@ -20,6 +21,7 @@ const convertFileTypeToDBType = async (file: FileInfo): Promise<DBEntry[]> => {
const fileContent = readFile(file.path)
const chunks = await chunkMarkdownByHeadingsAndByCharsIfBig(fileContent)
const entries = chunks.map((content, index) => ({
name: file.name,
notepath: file.path,
content,
subnoteindex: index,
Expand Down Expand Up @@ -169,8 +171,10 @@ export const updateFileInTable = async (dbTable: LanceDBTableWrapper, filePath:
await dbTable.deleteDBItemsByFilePaths([filePath])
const content = readFile(filePath)
const chunkedContentList = await chunkMarkdownByHeadingsAndByCharsIfBig(content)
const fileName = path.basename(filePath).split('.')[0]
const stats = fs.statSync(filePath)
const dbEntries = chunkedContentList.map((_content, index) => ({
name: fileName,
notepath: filePath,
content: _content,
subnoteindex: index,
Expand Down
12 changes: 10 additions & 2 deletions electron/preload/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@ import {
TamaguiThemeTypes,
} from 'electron/main/electron-store/storeConfig'
import { SearchProps } from 'electron/main/electron-store/types'
import { FileInfoTree, FileInfoWithContent, RenameFileProps, WriteFileProps } from 'electron/main/filesystem/types'
import {
FileInfo,
FileInfoTree,
FileInfoWithContent,
RenameFileProps,
WriteFileProps,
} from 'electron/main/filesystem/types'
import { DBQueryResult } from 'electron/main/vector-database/schema'

import { AgentConfig, ChatMetadata, Chat } from '@/lib/llm/types'
Expand Down Expand Up @@ -102,12 +108,14 @@ const fileSystem = {
getVideo: createIPCHandler<(fileName: string) => Promise<string | null>>('get-video'),
isDirectory: createIPCHandler<(filePath: string) => Promise<boolean>>('is-directory'),
renameFile: createIPCHandler<(renameFileProps: RenameFileProps) => Promise<void>>('rename-file'),
createFile: createIPCHandler<(filePath: string, content: string) => Promise<void>>('create-file'),
createFile: createIPCHandler<(filePath: string, content: string) => Promise<FileInfo | undefined>>('create-file'),
createDirectory: createIPCHandler<(dirPath: string) => Promise<void>>('create-directory'),
checkFileExists: createIPCHandler<(filePath: string) => Promise<boolean>>('check-file-exists'),
deleteFile: createIPCHandler<(filePath: string) => Promise<void>>('delete-file'),
getAllFilenamesInDirectory: createIPCHandler<(dirName: string) => Promise<string[]>>('get-files-in-directory'),
getFiles: createIPCHandler<(filePaths: string[]) => Promise<FileInfoWithContent[]>>('get-files'),
getFileInfo:
createIPCHandler<(absolutePath: string, parentRelativePath: string) => Promise<FileInfo>>('get-file-info'),
}

const path = {
Expand Down
109 changes: 94 additions & 15 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,8 @@
"vaul": "^1.0.0",
"vectordb": "0.4.10",
"yjs": "^13.6.23",
"zod": "^3.23.8"
"zod": "^3.23.8",
"zustand": "^5.0.3"
},
"devDependencies": {
"@electron/notarize": "2.3.2",
Expand Down
Loading