Showing preview only (3,750K chars total). Download the full file or copy to clipboard to get everything.
Repository: codexu/note-gen
Branch: dev
Commit: 67bb0200a36b
Files: 605
Total size: 3.5 MB
Directory structure:
gitextract_k__2zx16/
├── .eslintrc.json
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.yml
│ │ ├── config.yml
│ │ └── feature_request.yml
│ └── workflows/
│ └── release.yml
├── .gitignore
├── .vscode/
│ └── settings.json
├── LICENSE
├── README.md
├── components.json
├── messages/
│ ├── en.json
│ ├── ja.json
│ ├── pt-BR.json
│ ├── zh-TW.json
│ └── zh.json
├── next.config.ts
├── package.json
├── postcss.config.mjs
├── public/
│ └── markdown/
│ ├── github-markdown-dark.css
│ └── github-markdown-light.css
├── scripts/
│ └── sync-version.sh
├── src/
│ ├── app/
│ │ ├── core/
│ │ │ ├── index.d.ts
│ │ │ ├── layout.tsx
│ │ │ ├── main/
│ │ │ │ ├── chat/
│ │ │ │ │ ├── agent-execution-status.tsx
│ │ │ │ │ ├── agent-history.tsx
│ │ │ │ │ ├── agent-panel-with-rag.tsx
│ │ │ │ │ ├── chat-clipboard.tsx
│ │ │ │ │ ├── chat-content.tsx
│ │ │ │ │ ├── chat-empty.tsx
│ │ │ │ │ ├── chat-footer.tsx
│ │ │ │ │ ├── chat-header.tsx
│ │ │ │ │ ├── chat-images.tsx
│ │ │ │ │ ├── chat-input.tsx
│ │ │ │ │ ├── chat-preview.tsx
│ │ │ │ │ ├── chat-send.tsx
│ │ │ │ │ ├── chat-thinking.tsx
│ │ │ │ │ ├── chat.css
│ │ │ │ │ ├── clear-chat.tsx
│ │ │ │ │ ├── clear-context.tsx
│ │ │ │ │ ├── clipboard-listener.tsx
│ │ │ │ │ ├── clipboard-monitor.tsx
│ │ │ │ │ ├── file-link.tsx
│ │ │ │ │ ├── file-selector.tsx
│ │ │ │ │ ├── history-dropdown.tsx
│ │ │ │ │ ├── image-attachments.tsx
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ ├── mcp-button.tsx
│ │ │ │ │ ├── mcp-tool-call.tsx
│ │ │ │ │ ├── message-control/
│ │ │ │ │ │ ├── condensed-indicator.tsx
│ │ │ │ │ │ ├── copy-control.tsx
│ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ ├── mark-text.tsx
│ │ │ │ │ │ ├── message-info.tsx
│ │ │ │ │ │ ├── note-output.tsx
│ │ │ │ │ │ ├── read-aloud-control.tsx
│ │ │ │ │ │ └── translate-control.tsx
│ │ │ │ │ ├── model-select.tsx
│ │ │ │ │ ├── new-chat.tsx
│ │ │ │ │ ├── onboarding-typing.ts
│ │ │ │ │ ├── prompt-select.tsx
│ │ │ │ │ ├── quote-display.tsx
│ │ │ │ │ ├── quote-preview.ts
│ │ │ │ │ ├── rag-switch.tsx
│ │ │ │ │ └── streaming-smoother.ts
│ │ │ │ ├── editor/
│ │ │ │ │ ├── editor-layout.tsx
│ │ │ │ │ ├── empty-state-actions.ts
│ │ │ │ │ ├── empty-state.tsx
│ │ │ │ │ ├── folder/
│ │ │ │ │ │ ├── folder-stats.tsx
│ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ ├── skill-detail.tsx
│ │ │ │ │ │ └── skills-list.tsx
│ │ │ │ │ ├── image/
│ │ │ │ │ │ ├── image-editor.css
│ │ │ │ │ │ ├── image-editor.tsx
│ │ │ │ │ │ └── image-footer.tsx
│ │ │ │ │ ├── markdown/
│ │ │ │ │ │ ├── ai-completion.tsx
│ │ │ │ │ │ ├── ai-suggestion-floating.tsx
│ │ │ │ │ │ ├── ai-suggestion.ts
│ │ │ │ │ │ ├── bubble-menu.tsx
│ │ │ │ │ │ ├── export-menu.tsx
│ │ │ │ │ │ ├── floating-table-menu.tsx
│ │ │ │ │ │ ├── footer-bar/
│ │ │ │ │ │ │ ├── copy-button.tsx
│ │ │ │ │ │ │ ├── export-button.tsx
│ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ ├── outline-toggle.tsx
│ │ │ │ │ │ │ ├── vector-calc.tsx
│ │ │ │ │ │ │ └── word-count.tsx
│ │ │ │ │ │ ├── image-bubble-menu.tsx
│ │ │ │ │ │ ├── markdown-input-rules.ts
│ │ │ │ │ │ ├── markdown-paragraph.ts
│ │ │ │ │ │ ├── math-editor-dialog.tsx
│ │ │ │ │ │ ├── math-extension.tsx
│ │ │ │ │ │ ├── md-editor-wrapper.tsx
│ │ │ │ │ │ ├── mermaid-extension.tsx
│ │ │ │ │ │ ├── mobile-editor-context-bar-view-model.ts
│ │ │ │ │ │ ├── mobile-editor-context-bar.tsx
│ │ │ │ │ │ ├── mobile-editor-more-sheet.tsx
│ │ │ │ │ │ ├── mobile-selection-context.ts
│ │ │ │ │ │ ├── outline.tsx
│ │ │ │ │ │ ├── quote-mark.ts
│ │ │ │ │ │ ├── quote-session.ts
│ │ │ │ │ │ ├── search-navigation.ts
│ │ │ │ │ │ ├── search-replace-panel.tsx
│ │ │ │ │ │ ├── slash-command/
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── slash-command-portal.tsx
│ │ │ │ │ │ │ ├── slash-menu.tsx
│ │ │ │ │ │ │ └── suggestion.tsx
│ │ │ │ │ │ ├── style.css
│ │ │ │ │ │ ├── sync/
│ │ │ │ │ │ │ ├── conflict-dialog.tsx
│ │ │ │ │ │ │ ├── history-sheet.tsx
│ │ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ │ ├── pull-button.tsx
│ │ │ │ │ │ │ ├── sync-button.tsx
│ │ │ │ │ │ │ └── sync-tools.tsx
│ │ │ │ │ │ ├── table-toolbar.tsx
│ │ │ │ │ │ └── tiptap-editor.tsx
│ │ │ │ │ ├── onboarding-state.ts
│ │ │ │ │ ├── tab-bar.tsx
│ │ │ │ │ └── unsupported-file.tsx
│ │ │ │ ├── file/
│ │ │ │ │ ├── file-actions.tsx
│ │ │ │ │ ├── file-footer.tsx
│ │ │ │ │ ├── file-item.tsx
│ │ │ │ │ ├── file-manager.tsx
│ │ │ │ │ ├── file-toolbar.tsx
│ │ │ │ │ ├── folder-item/
│ │ │ │ │ │ ├── copy-folder.tsx
│ │ │ │ │ │ ├── cut-folder.tsx
│ │ │ │ │ │ ├── delete-folder.tsx
│ │ │ │ │ │ ├── duplicate-folder.tsx
│ │ │ │ │ │ ├── folder-vector-menu.tsx
│ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ ├── new-file.tsx
│ │ │ │ │ │ ├── new-folder.tsx
│ │ │ │ │ │ ├── paste-in-folder.tsx
│ │ │ │ │ │ ├── paste-into-folder.js
│ │ │ │ │ │ ├── paste-target.js
│ │ │ │ │ │ ├── paste-target.spec.mjs
│ │ │ │ │ │ ├── rename-folder.tsx
│ │ │ │ │ │ ├── sync-folder.tsx
│ │ │ │ │ │ └── view-directory.tsx
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ ├── mobile-action-menu.tsx
│ │ │ │ │ ├── root-drop.js
│ │ │ │ │ ├── root-drop.spec.mjs
│ │ │ │ │ ├── vector-knowledge-menu.tsx
│ │ │ │ │ └── workspace-selector.tsx
│ │ │ │ ├── left-sidebar.tsx
│ │ │ │ ├── mark/
│ │ │ │ │ ├── clipboard.tsx
│ │ │ │ │ ├── control-file.tsx
│ │ │ │ │ ├── control-image.tsx
│ │ │ │ │ ├── control-link.tsx
│ │ │ │ │ ├── control-recording.tsx
│ │ │ │ │ ├── control-scan.tsx
│ │ │ │ │ ├── control-text.tsx
│ │ │ │ │ ├── control-todo.tsx
│ │ │ │ │ ├── crop.css
│ │ │ │ │ ├── image-gallery.tsx
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ ├── mark-actions.tsx
│ │ │ │ │ ├── mark-empty.tsx
│ │ │ │ │ ├── mark-filter-popover.tsx
│ │ │ │ │ ├── mark-filters.mjs
│ │ │ │ │ ├── mark-filters.spec.mjs
│ │ │ │ │ ├── mark-header.tsx
│ │ │ │ │ ├── mark-item.tsx
│ │ │ │ │ ├── mark-list-card-view.tsx
│ │ │ │ │ ├── mark-list-compact-view.tsx
│ │ │ │ │ ├── mark-list-default-view.tsx
│ │ │ │ │ ├── mark-list-item-content.tsx
│ │ │ │ │ ├── mark-list.tsx
│ │ │ │ │ ├── mark-loading.tsx
│ │ │ │ │ ├── mark-mobile-actions.tsx
│ │ │ │ │ ├── mark-toolbar.tsx
│ │ │ │ │ ├── mark-type-meta.ts
│ │ │ │ │ ├── mark-view-mode-toggle.tsx
│ │ │ │ │ ├── mark-view-mode.mjs
│ │ │ │ │ ├── mark-view-mode.spec.mjs
│ │ │ │ │ ├── organize-notes.tsx
│ │ │ │ │ ├── organize-onboarding.ts
│ │ │ │ │ ├── tag-item.tsx
│ │ │ │ │ ├── tag-manage.tsx
│ │ │ │ │ ├── tag-mobile-actions.tsx
│ │ │ │ │ ├── todo-edit-button.tsx
│ │ │ │ │ ├── todo-edit-dialog.tsx
│ │ │ │ │ ├── todo-form.tsx
│ │ │ │ │ └── todo-item-content.tsx
│ │ │ │ └── page.tsx
│ │ │ └── setting/
│ │ │ ├── about/
│ │ │ │ ├── page.tsx
│ │ │ │ ├── setting-about.tsx
│ │ │ │ └── updater.tsx
│ │ │ ├── ai/
│ │ │ │ ├── create.tsx
│ │ │ │ ├── default-models.tsx
│ │ │ │ ├── model-card.tsx
│ │ │ │ ├── modelSelect.tsx
│ │ │ │ └── page.tsx
│ │ │ ├── audio/
│ │ │ │ ├── page.tsx
│ │ │ │ └── setting.tsx
│ │ │ ├── chat/
│ │ │ │ ├── condense-settings.tsx
│ │ │ │ ├── page.tsx
│ │ │ │ ├── primary-model-settings.tsx
│ │ │ │ └── toolbar-settings.tsx
│ │ │ ├── components/
│ │ │ │ ├── default-models-settings.tsx
│ │ │ │ ├── model-select.tsx
│ │ │ │ ├── setting-base.tsx
│ │ │ │ ├── setting-tab.tsx
│ │ │ │ └── upload-store.tsx
│ │ │ ├── config.tsx
│ │ │ ├── defaultModel/
│ │ │ │ ├── page.tsx
│ │ │ │ └── setting.tsx
│ │ │ ├── dev/
│ │ │ │ ├── page.tsx
│ │ │ │ ├── set-config.tsx
│ │ │ │ └── setting-dev.tsx
│ │ │ ├── editor/
│ │ │ │ ├── centered-content.tsx
│ │ │ │ ├── commit.tsx
│ │ │ │ ├── completion.tsx
│ │ │ │ ├── outline.tsx
│ │ │ │ ├── page.tsx
│ │ │ │ └── show-undo-redo.tsx
│ │ │ ├── file/
│ │ │ │ ├── page.tsx
│ │ │ │ ├── setting-assets.tsx
│ │ │ │ └── setting-workspace.tsx
│ │ │ ├── general/
│ │ │ │ ├── interface-settings/
│ │ │ │ │ ├── content-text-scale.tsx
│ │ │ │ │ ├── custom-theme.tsx
│ │ │ │ │ ├── file-manager-text-size.tsx
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ ├── language.tsx
│ │ │ │ │ ├── record-text-size.tsx
│ │ │ │ │ ├── scale.tsx
│ │ │ │ │ ├── theme-color-picker.tsx
│ │ │ │ │ ├── theme-presets.tsx
│ │ │ │ │ └── theme.tsx
│ │ │ │ ├── page.tsx
│ │ │ │ └── tool-settings.tsx
│ │ │ ├── imageHosting/
│ │ │ │ ├── github.tsx
│ │ │ │ ├── page.tsx
│ │ │ │ ├── picgo.tsx
│ │ │ │ ├── s3.tsx
│ │ │ │ ├── setting-switch.tsx
│ │ │ │ └── smms.tsx
│ │ │ ├── imageMethod/
│ │ │ │ ├── ocr.tsx
│ │ │ │ ├── page.tsx
│ │ │ │ ├── setDefault.tsx
│ │ │ │ └── vlm.tsx
│ │ │ ├── layout.tsx
│ │ │ ├── mcp/
│ │ │ │ ├── connection-test.tsx
│ │ │ │ ├── json-import-dialog.tsx
│ │ │ │ ├── page.tsx
│ │ │ │ ├── runtime-environment-card.tsx
│ │ │ │ ├── server-config-dialog.tsx
│ │ │ │ ├── server-list.tsx
│ │ │ │ └── tool-browser.tsx
│ │ │ ├── memories/
│ │ │ │ └── page.tsx
│ │ │ ├── page.tsx
│ │ │ ├── prompt/
│ │ │ │ ├── page.tsx
│ │ │ │ └── setting-prompt.tsx
│ │ │ ├── rag/
│ │ │ │ ├── model-setting.tsx
│ │ │ │ ├── page.tsx
│ │ │ │ └── settings.tsx
│ │ │ ├── readAloud/
│ │ │ │ ├── page.tsx
│ │ │ │ └── setting.tsx
│ │ │ ├── record/
│ │ │ │ ├── model-settings.tsx
│ │ │ │ ├── page.tsx
│ │ │ │ └── toolbar-settings.tsx
│ │ │ ├── shortcuts/
│ │ │ │ ├── page.tsx
│ │ │ │ └── shorcut-input.tsx
│ │ │ ├── skills/
│ │ │ │ ├── components/
│ │ │ │ │ ├── global-skills-manager.tsx
│ │ │ │ │ ├── project-skills-list.tsx
│ │ │ │ │ ├── skill-card.tsx
│ │ │ │ │ └── skills-settings.tsx
│ │ │ │ └── page.tsx
│ │ │ ├── sync/
│ │ │ │ ├── components/
│ │ │ │ │ └── sync-platform-card.tsx
│ │ │ │ ├── gitea-sync.tsx
│ │ │ │ ├── gitee-sync.tsx
│ │ │ │ ├── github-sync.tsx
│ │ │ │ ├── gitlab-sync.tsx
│ │ │ │ ├── page.tsx
│ │ │ │ ├── s3-sync.tsx
│ │ │ │ └── webdav-sync.tsx
│ │ │ └── template/
│ │ │ ├── page.tsx
│ │ │ └── setting-template.tsx
│ │ ├── error.tsx
│ │ ├── global-error.tsx
│ │ ├── globals.css
│ │ ├── layout.tsx
│ │ ├── mobile/
│ │ │ ├── chat/
│ │ │ │ ├── components/
│ │ │ │ │ ├── chat-attachments-drawer.tsx
│ │ │ │ │ ├── chat-settings-drawer.tsx
│ │ │ │ │ ├── chat-tools-drawer.tsx
│ │ │ │ │ ├── clear-chat.tsx
│ │ │ │ │ ├── clear-context.tsx
│ │ │ │ │ ├── clipboard-toggle.tsx
│ │ │ │ │ ├── mcp-selector.tsx
│ │ │ │ │ ├── mobile-chat-header.tsx
│ │ │ │ │ ├── model-selector.tsx
│ │ │ │ │ ├── new-chat.tsx
│ │ │ │ │ ├── prompt-selector.tsx
│ │ │ │ │ └── rag-toggle.tsx
│ │ │ │ └── page.tsx
│ │ │ ├── layout.tsx
│ │ │ ├── mobile-styles.css
│ │ │ ├── record/
│ │ │ │ ├── mobile-mark-header.tsx
│ │ │ │ ├── mobile-record-stream.tsx
│ │ │ │ └── page.tsx
│ │ │ ├── setting/
│ │ │ │ ├── components/
│ │ │ │ │ └── setting-tab.tsx
│ │ │ │ ├── page.tsx
│ │ │ │ └── pages/
│ │ │ │ ├── ai/
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── audio/
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── chat/
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── defaultModel/
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── dev/
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── editor/
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── file/
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── general/
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── imageHosting/
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── imageMethod/
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── layout.tsx
│ │ │ │ ├── mcp/
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── prompt/
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── rag/
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── readAloud/
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── record/
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── skills/
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── sync/
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── template/
│ │ │ │ │ └── page.tsx
│ │ │ │ └── theme/
│ │ │ │ └── page.tsx
│ │ │ └── writing/
│ │ │ ├── browser-utils.ts
│ │ │ ├── custom-header.tsx
│ │ │ ├── entry-list-item.tsx
│ │ │ ├── mobile-editor.tsx
│ │ │ ├── name-input-dialog.tsx
│ │ │ ├── page.tsx
│ │ │ └── types.ts
│ │ ├── model-config.ts
│ │ ├── not-found.tsx
│ │ └── page.tsx
│ ├── components/
│ │ ├── activity/
│ │ │ ├── activity-day-detail.tsx
│ │ │ ├── activity-drawer.tsx
│ │ │ ├── activity-heatmap.tsx
│ │ │ ├── activity-legend.tsx
│ │ │ └── activity-panel.tsx
│ │ ├── app-footbar.tsx
│ │ ├── app-sidebar.tsx
│ │ ├── app-status.tsx
│ │ ├── audio-player.tsx
│ │ ├── bottom-bar-icon-button.tsx
│ │ ├── console-filter.tsx
│ │ ├── draggable-toolbar-item.tsx
│ │ ├── image-viewer.tsx
│ │ ├── local-image.tsx
│ │ ├── memories/
│ │ │ ├── memory-form.tsx
│ │ │ ├── memory-item.tsx
│ │ │ ├── memory-list.tsx
│ │ │ └── memory-stats.tsx
│ │ ├── mobile-record-tools.tsx
│ │ ├── mobile-statusbar.tsx
│ │ ├── onboarding-spotlight-position.ts
│ │ ├── onboarding-spotlight.tsx
│ │ ├── open-broswer.tsx
│ │ ├── pin-toggle.tsx
│ │ ├── providers/
│ │ │ └── NextIntlProvider.tsx
│ │ ├── recording-dialog.tsx
│ │ ├── recording-indicator.tsx
│ │ ├── search-dialog.tsx
│ │ ├── simple-mobile-tool.tsx
│ │ ├── sync-confirm-dialog.tsx
│ │ ├── sync-status-badge.tsx
│ │ ├── theme-provider.tsx
│ │ ├── title-bar-toolbars/
│ │ │ └── sync-toggle.tsx
│ │ ├── title-bar.tsx
│ │ ├── tooltip-button.tsx
│ │ └── ui/
│ │ ├── accordion.tsx
│ │ ├── agent-plan.tsx
│ │ ├── alert-dialog.tsx
│ │ ├── alert.tsx
│ │ ├── avatar.tsx
│ │ ├── badge.tsx
│ │ ├── breadcrumb.tsx
│ │ ├── button.tsx
│ │ ├── calendar.tsx
│ │ ├── card.tsx
│ │ ├── carousel.tsx
│ │ ├── checkbox.tsx
│ │ ├── collapsible.tsx
│ │ ├── command.tsx
│ │ ├── context-menu.tsx
│ │ ├── dialog.tsx
│ │ ├── diff-viewer.tsx
│ │ ├── drawer.tsx
│ │ ├── dropdown-menu.tsx
│ │ ├── empty.tsx
│ │ ├── enhanced-context-menu.tsx
│ │ ├── expandable-tabs.tsx
│ │ ├── form.tsx
│ │ ├── hover-card.tsx
│ │ ├── input.tsx
│ │ ├── item.tsx
│ │ ├── kbd.tsx
│ │ ├── label.tsx
│ │ ├── popover.tsx
│ │ ├── progress.tsx
│ │ ├── radio-group.tsx
│ │ ├── resizable.tsx
│ │ ├── scroll-area.tsx
│ │ ├── select.tsx
│ │ ├── separator.tsx
│ │ ├── sheet.tsx
│ │ ├── shine-border.tsx
│ │ ├── sidebar.tsx
│ │ ├── skeleton.tsx
│ │ ├── slider.tsx
│ │ ├── swipe-back.tsx
│ │ ├── switch.tsx
│ │ ├── table.tsx
│ │ ├── tabs.tsx
│ │ ├── textarea.tsx
│ │ ├── toast.tsx
│ │ ├── toaster.tsx
│ │ ├── toggle.tsx
│ │ └── tooltip.tsx
│ ├── config/
│ │ ├── emitters.ts
│ │ ├── shortcut.ts
│ │ └── sync-exclusions.ts
│ ├── contexts/
│ │ └── text-size-context.tsx
│ ├── db/
│ │ ├── activity.ts
│ │ ├── chats.ts
│ │ ├── conversations.ts
│ │ ├── index.ts
│ │ ├── marks.ts
│ │ ├── memories.ts
│ │ ├── notes.ts
│ │ ├── tags.ts
│ │ └── vector.ts
│ ├── hooks/
│ │ ├── use-file-shortcuts.ts
│ │ ├── use-mobile.tsx
│ │ ├── use-sync-manager.ts
│ │ ├── use-sync-settings.ts
│ │ ├── use-toast.ts
│ │ ├── use-toolbar-shortcuts.ts
│ │ ├── use-username.ts
│ │ ├── useAiCompletion.ts
│ │ └── useI18n.ts
│ ├── i18n/
│ │ └── request.ts
│ ├── lib/
│ │ ├── activity/
│ │ │ ├── aggregate.ts
│ │ │ ├── events.ts
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ ├── agent/
│ │ │ ├── agent-handler.ts
│ │ │ ├── auto-final-answer.ts
│ │ │ ├── i18n.ts
│ │ │ ├── parse-action-input.ts
│ │ │ ├── react-diff-helpers.ts
│ │ │ ├── react.ts
│ │ │ ├── session-approval.ts
│ │ │ ├── tool-confirmation-display.ts
│ │ │ ├── tool-policy.ts
│ │ │ ├── tools/
│ │ │ │ ├── chat-tools.ts
│ │ │ │ ├── editor-tools.ts
│ │ │ │ ├── folder-tools.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── mark-tools.ts
│ │ │ │ ├── memory-tools.ts
│ │ │ │ ├── note-tools.ts
│ │ │ │ ├── system-tools.ts
│ │ │ │ └── tag-tools.ts
│ │ │ └── types.ts
│ │ ├── ai/
│ │ │ ├── chat.ts
│ │ │ ├── completion.ts
│ │ │ ├── condense.ts
│ │ │ ├── description.ts
│ │ │ ├── embedding.ts
│ │ │ ├── history-messages.ts
│ │ │ ├── index.ts
│ │ │ ├── placeholder.ts
│ │ │ ├── rewrite.ts
│ │ │ ├── token-counter.ts
│ │ │ ├── translate.ts
│ │ │ ├── types.ts
│ │ │ └── utils.ts
│ │ ├── audio-converter.ts
│ │ ├── audio.ts
│ │ ├── bm25.ts
│ │ ├── check.ts
│ │ ├── context/
│ │ │ └── loader.ts
│ │ ├── default-filename.ts
│ │ ├── editor-layout-styles.ts
│ │ ├── emitter.ts
│ │ ├── event-report.ts
│ │ ├── files.ts
│ │ ├── folder-vector.ts
│ │ ├── fuzzy-search.ts
│ │ ├── image-handler.ts
│ │ ├── imageHosting/
│ │ │ ├── github.ts
│ │ │ ├── index.ts
│ │ │ ├── picgo.ts
│ │ │ ├── s3.ts
│ │ │ └── smms.ts
│ │ ├── infographic.ts
│ │ ├── locales.ts
│ │ ├── mark-to-markdown.ts
│ │ ├── markdown.ts
│ │ ├── mcp/
│ │ │ ├── client.ts
│ │ │ ├── index.ts
│ │ │ ├── init.ts
│ │ │ ├── integration.ts
│ │ │ ├── runtime-assistant.ts
│ │ │ ├── server-manager.ts
│ │ │ ├── tools.ts
│ │ │ └── types.ts
│ │ ├── ocr.ts
│ │ ├── outline-preferences.ts
│ │ ├── outline-styles.ts
│ │ ├── path.ts
│ │ ├── pdf.ts
│ │ ├── rag.ts
│ │ ├── record-navigation.ts
│ │ ├── search-utils.ts
│ │ ├── shortcut/
│ │ │ ├── quick-record-text.ts
│ │ │ └── show-window.ts
│ │ ├── skills/
│ │ │ ├── dependency-installer.ts
│ │ │ ├── executor.ts
│ │ │ ├── index.ts
│ │ │ ├── manager.ts
│ │ │ ├── parser.ts
│ │ │ ├── path-utils.ts
│ │ │ ├── runtime-paths.ts
│ │ │ ├── runtime.ts
│ │ │ ├── types.ts
│ │ │ ├── utils.ts
│ │ │ └── validator.ts
│ │ ├── speech/
│ │ │ ├── capabilities.ts
│ │ │ ├── preferences.ts
│ │ │ ├── resolver.ts
│ │ │ ├── runtime.ts
│ │ │ ├── transcription-fallback.ts
│ │ │ └── types.ts
│ │ ├── sync/
│ │ │ ├── auto-sync.ts
│ │ │ ├── conflict-resolution.ts
│ │ │ ├── encode-fetch.ts
│ │ │ ├── filename-utils.ts
│ │ │ ├── folder-sync-helper.ts
│ │ │ ├── folder-sync.ts
│ │ │ ├── gitea.ts
│ │ │ ├── gitea.types.ts
│ │ │ ├── gitee.ts
│ │ │ ├── github.ts
│ │ │ ├── github.types.ts
│ │ │ ├── gitlab.ts
│ │ │ ├── gitlab.types.ts
│ │ │ ├── remote-file.ts
│ │ │ ├── repo-utils.ts
│ │ │ ├── s3.ts
│ │ │ ├── sync-manager.ts
│ │ │ ├── sync-push-queue.ts
│ │ │ └── webdav.ts
│ │ ├── template-range-utils.ts
│ │ ├── theme-utils.ts
│ │ ├── toolbar-shortcuts.ts
│ │ ├── utils.ts
│ │ ├── vector-document-key.js
│ │ ├── vector-document-key.spec.mjs
│ │ └── workspace.ts
│ ├── stores/
│ │ ├── article.ts
│ │ ├── chat.ts
│ │ ├── clipboard.ts
│ │ ├── imageHosting.ts
│ │ ├── mark.ts
│ │ ├── mcp.ts
│ │ ├── memories.ts
│ │ ├── prompt.ts
│ │ ├── ragSettings.ts
│ │ ├── recording.ts
│ │ ├── setting.ts
│ │ ├── settingsSync.ts
│ │ ├── shortcut.ts
│ │ ├── sidebar.ts
│ │ ├── skills.ts
│ │ ├── speech-recognition.ts
│ │ ├── sync-confirm.ts
│ │ ├── sync.ts
│ │ ├── tag.ts
│ │ ├── update.ts
│ │ └── vector.ts
│ └── types/
│ ├── sync.ts
│ └── theme.ts
├── src-tauri/
│ ├── .gitignore
│ ├── Cargo.toml
│ ├── Info.plist
│ ├── build.rs
│ ├── capabilities/
│ │ ├── default.json
│ │ └── desktop.json
│ ├── icons/
│ │ └── icon.icns
│ ├── src/
│ │ ├── app_setup.rs
│ │ ├── backup.rs
│ │ ├── device.rs
│ │ ├── fuzzy_search.rs
│ │ ├── keywords.rs
│ │ ├── lib.rs
│ │ ├── main.rs
│ │ ├── mcp.rs
│ │ ├── mcp_runtime.rs
│ │ ├── screenshot.rs
│ │ ├── skills.rs
│ │ ├── statusbar.rs
│ │ ├── tray.rs
│ │ └── window.rs
│ ├── tauri.conf.json
│ └── tauri.ios.conf.json
└── tsconfig.json
================================================
FILE CONTENTS
================================================
================================================
FILE: .eslintrc.json
================================================
{
"root": true,
"extends": ["next/core-web-vitals", "next/typescript"],
"rules": {
"react-hooks/exhaustive-deps": "off",
"@typescript-eslint/no-explicit-any": "off"
},
"ignorePatterns": [
"docs/**"
]
}
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.yml
================================================
name: 🐞 提交 Bug
title: '[bug] '
description: 详细的描述一个 Bug
labels: ['type: bug']
body:
- type: markdown
attributes:
value: |
## 首先请阅读
1. 请先搜索 [note-gen/issues](https://github.com/codexu/note-gen/issues) 中是否已存在此问题。
2. 尝试下载最新版本的 NoteGen 并测试是否还存在此问题。
3. 请确保这是 App 的问题,而不是 AI 或代理等问题。
4. 请按照提交要求详细的描述 Bug,提供全面的信息。
5. 请在社区内友善发言。
- type: textarea
id: description
attributes:
label: 详细描述这个 Bug
description: 请详细的描述这个 Bug,包括重现步骤、预期行为和实际行为,如果可以建议附带截图或视频。
placeholder: Bug description
validations:
required: true
- type: input
id: version
attributes:
label: NoteGen 版本
placeholder: 请填写你当前使用的 NoteGen 版本。
validations:
required: true
- type: dropdown
id: os
attributes:
label: 操作系统
multiple: true
options:
- Windows
- macOS
- Linux
- Android
- iOS
validations:
required: true
- type: textarea
id: log
attributes:
label: 报错日志
description: 可以通过右键呼出开发者工具,将报错信息粘贴在此处。
placeholder: Bug logs
================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
contact_links:
- name: 💬 讨论问题
url: https://github.com/codexu/note-gen/discussions
about: 提出问题并与其他 NoteGen 用户或维护者交谈
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.yml
================================================
name: 💡 改进建议
title: '[feat] '
description: 你有什么好的灵感?
labels: ['type: feat']
body:
- type: textarea
id: problem
attributes:
label: 描述你的建议
description: 清楚的描述这个建议可以解决什么问题
validations:
required: true
================================================
FILE: .github/workflows/release.yml
================================================
name: 'publish'
on:
push:
branches:
- release
jobs:
build-android:
outputs:
appVersion: ${{ steps.get_version.outputs.version }}
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 9
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: lts/*
cache: 'pnpm'
- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
with:
targets: aarch64-linux-android,armv7-linux-androideabi,i686-linux-android,x86_64-linux-android
- name: Setup Android SDK
uses: android-actions/setup-android@v3
- name: Install Android NDK
run: |
echo "y" | sdkmanager "ndk;29.0.14206865"
echo "ANDROID_NDK_HOME=$ANDROID_HOME/ndk/29.0.14206865" >> $GITHUB_ENV
echo "NDK_HOME=$ANDROID_HOME/ndk/29.0.14206865" >> $GITHUB_ENV
- name: Cache Rust dependencies
uses: actions/cache@v4
with:
path: |
~/.cargo/registry/index
~/.cargo/registry/cache
~/.cargo/git/db
src-tauri/target
key: ${{ runner.os }}-cargo-android-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-android-
- name: Install frontend dependencies
run: pnpm install
- name: Build frontend
run: pnpm build
- name: Setup NDK toolchain
run: |
export PATH=$PATH:$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin
ln -sf llvm-ranlib $ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-ranlib || true
- name: Initialize and Build Android
run: |
export PATH=$PATH:$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin
# Initialize Android project if not exists
if [ ! -d "src-tauri/gen/android" ]; then
echo "📱 Initializing Android project..."
pnpm tauri android init
else
echo "✅ Android project already initialized"
fi
# Verify initialization
if [ ! -d "src-tauri/gen/android" ]; then
echo "❌ Android initialization failed"
exit 1
fi
# Set custom Android icon
echo "🎨 Setting custom Android icon..."
ICON_SOURCE="public/app-ios-icon.png"
MIPMAP_DIRS=(
"src-tauri/gen/android/app/src/main/res/mipmap-mdpi"
"src-tauri/gen/android/app/src/main/res/mipmap-hdpi"
"src-tauri/gen/android/app/src/main/res/mipmap-xhdpi"
"src-tauri/gen/android/app/src/main/res/mipmap-xxhdpi"
"src-tauri/gen/android/app/src/main/res/mipmap-xxxhdpi"
)
# Install ImageMagick for icon conversion
sudo apt-get update && sudo apt-get install -y imagemagick
# Generate different sizes
convert "$ICON_SOURCE" -resize 48x48 "${MIPMAP_DIRS[0]}/ic_launcher.png"
convert "$ICON_SOURCE" -resize 72x72 "${MIPMAP_DIRS[1]}/ic_launcher.png"
convert "$ICON_SOURCE" -resize 96x96 "${MIPMAP_DIRS[2]}/ic_launcher.png"
convert "$ICON_SOURCE" -resize 144x144 "${MIPMAP_DIRS[3]}/ic_launcher.png"
convert "$ICON_SOURCE" -resize 192x192 "${MIPMAP_DIRS[4]}/ic_launcher.png"
echo "✅ Android icon set successfully"
echo "🔨 Building Android APK and AAB..."
pnpm tauri android build --apk --aab
- name: Decode keystore
env:
ANDROID_KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
run: |
echo "$ANDROID_KEYSTORE_BASE64" | base64 -d > src-tauri/android-release.keystore
ls -la src-tauri/android-release.keystore
- name: Get version
id: get_version
run: |
VERSION=$(grep -o '"version": *"[^"]*"' src-tauri/tauri.conf.json | head -1 | sed 's/"version": *"\(.*\)"/\1/')
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Version: $VERSION"
- name: Sign and Rename APK
env:
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
run: |
cd src-tauri
APK_PATH="gen/android/app/build/outputs/apk/universal/release/app-universal-release-unsigned.apk"
VERSION="${{ steps.get_version.outputs.version }}"
SIGNED_APK="gen/android/app/build/outputs/apk/universal/release/NoteGen_${VERSION}_android-universal.apk"
if [ ! -f "$APK_PATH" ]; then
echo "❌ APK file not found at $APK_PATH"
ls -la gen/android/app/build/outputs/apk/universal/release/ || true
exit 1
fi
echo "📝 Signing APK with apksigner (V1 + V2 signatures)..."
$ANDROID_HOME/build-tools/$(ls $ANDROID_HOME/build-tools | tail -n 1)/apksigner sign \
--ks android-release.keystore \
--ks-key-alias note-gen \
--ks-pass pass:"$ANDROID_KEYSTORE_PASSWORD" \
--key-pass pass:"$ANDROID_KEY_PASSWORD" \
--out "$SIGNED_APK" \
"$APK_PATH"
echo "✅ APK signed successfully"
# Verify signature
echo "🔍 Verifying APK signature..."
$ANDROID_HOME/build-tools/$(ls $ANDROID_HOME/build-tools | tail -n 1)/apksigner verify --verbose "$SIGNED_APK"
# Show file info
ls -lh "$SIGNED_APK"
- name: Rename AAB
run: |
cd src-tauri
VERSION="${{ steps.get_version.outputs.version }}"
AAB_PATH="gen/android/app/build/outputs/bundle/universalRelease/app-universal-release.aab"
RENAMED_AAB="gen/android/app/build/outputs/bundle/universalRelease/NoteGen_${VERSION}_android-universal.aab"
if [ -f "$AAB_PATH" ]; then
mv "$AAB_PATH" "$RENAMED_AAB"
echo "✅ AAB renamed to: $RENAMED_AAB"
ls -lh "$RENAMED_AAB"
fi
- name: Upload APK as artifact
uses: actions/upload-artifact@v4
with:
name: android-apk
path: src-tauri/gen/android/app/build/outputs/apk/universal/release/NoteGen_*.apk
if-no-files-found: error
- name: Upload AAB as artifact
uses: actions/upload-artifact@v4
with:
name: android-aab
path: src-tauri/gen/android/app/build/outputs/bundle/universalRelease/NoteGen_*.aab
if-no-files-found: warn
- name: Upload to Release
uses: softprops/action-gh-release@v1
with:
tag_name: note-gen-v${{ steps.get_version.outputs.version }}
files: |
src-tauri/gen/android/app/build/outputs/apk/universal/release/NoteGen_*.apk
src-tauri/gen/android/app/build/outputs/bundle/universalRelease/NoteGen_*.aab
draft: false
prerelease: false
- name: Cleanup keystore
if: always()
run: |
rm -f src-tauri/android-release.keystore
upgradeLink-upload-android:
needs: build-android
permissions:
contents: write
runs-on: ubuntu-latest
steps:
- name: Send Android APK to UpgradeLink
uses: toolsetlink/upgradelink-action@3.0.2
with:
access_key: ${{ secrets.UPGRADE_LINK_ACCESS_KEY }}
access_secret: ${{ secrets.UPGRADE_LINK_ACCESS_SECRET }}
config: |
{
"app_type": "file",
"request": {
"app_key": "${{ secrets.UPGRADE_LINK_ANDROID_APP_KEY }}",
"version": "${{ needs.build-android.outputs.appVersion }}",
"url": "https://github.com/${{ github.repository }}/releases/download/note-gen-v${{ needs.build-android.outputs.appVersion }}/NoteGen_${{ needs.build-android.outputs.appVersion }}_android-universal.apk",
"prompt_upgrade_content": "新版本已发布,包含重要功能更新和 bug 修复"
}
}
publish-tauri:
outputs:
appVersion: ${{ steps.set_output.outputs.appVersion }}
permissions:
contents: write
strategy:
fail-fast: false
matrix:
include:
- platform: 'macos-latest'
args: '--target aarch64-apple-darwin'
- platform: 'macos-latest'
args: '--target x86_64-apple-darwin'
- platform: 'ubuntu-24.04'
args: '--bundles deb,rpm'
- platform: 'windows-latest'
args: ''
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 9
run_install: true
- name: setup node
uses: actions/setup-node@v4
with:
node-version: lts/*
cache: 'pnpm'
- name: install Rust stable
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.platform == 'macos-latest' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }}
- name: install dependencies (ubuntu only)
if: matrix.platform == 'ubuntu-24.04'
run: |
sudo apt-get update
sudo apt-get install pkg-config libclang-dev libxcb1-dev libxrandr-dev libdbus-1-dev libpipewire-0.3-dev libwayland-dev libegl-dev libglib2.0-dev libgtk-3-dev libwebkit2gtk-4.1-dev libgbm-dev libappindicator3-dev librsvg2-dev patchelf
- name: install frontend dependencies
run: pnpm install
- name: Import Apple Certificate
if: matrix.platform == 'macos-latest'
env:
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD || 'temporary_keychain_password' }}
run: |
# Create variables
CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
# Import certificate from secrets
echo -n "$APPLE_CERTIFICATE" | base64 --decode -o $CERTIFICATE_PATH
# Create temporary keychain
security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
# Import certificate to keychain
security import $CERTIFICATE_PATH -P "$APPLE_CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
security list-keychain -d user -s $KEYCHAIN_PATH
# Enable codesigning from a non user interactive shell
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
- uses: tauri-apps/tauri-action@v0.5.23
id: tauri-action
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
with:
tagName: note-gen-v__VERSION__
releaseName: 'NoteGen v__VERSION__'
releaseBody: 'See the assets to download this version and install.'
releaseDraft: false
prerelease: false
args: ${{ matrix.args }}
- name: Generate release tag
id: save_tag
if: matrix.platform == 'ubuntu-24.04'
run: |
# 调试输出
echo ${{ steps.tauri-action.outputs.appVersion }}
# 输出到步骤级
echo "appVersion=${{ steps.tauri-action.outputs.appVersion }}" >> $GITHUB_OUTPUT
- name: Set job output
id: set_output
if: matrix.platform == 'ubuntu-24.04'
run: |
# 注意:这里引用的是 save_tag 步骤的 tag_name 输出
echo "appVersion=${{ steps.save_tag.outputs.appVersion }}" >> $GITHUB_OUTPUT
- name: Cleanup keychain
if: matrix.platform == 'macos-latest' && always()
run: |
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
security delete-keychain $KEYCHAIN_PATH || true
upgradeLink-upload:
needs: publish-tauri
permissions:
contents: write
runs-on: ubuntu-latest
steps:
- name: Send a request to UpgradeLink
uses: toolsetlink/upgradelink-action@3.0.2
with:
access_key: ${{ secrets.UPGRADE_LINK_ACCESS_KEY }}
access_secret: ${{ secrets.UPGRADE_LINK_ACCESS_SECRET }}
config: |
{
"app_type": "tauri",
"request": {
"app_key": "${{ secrets.UPGRADE_LINK_TAURI_KEY }}",
"latest_json_url": "https://github.com/${{ github.repository }}/releases/download/note-gen-v${{ needs.publish-tauri.outputs.appVersion }}/latest.json"
}
}
================================================
FILE: .gitignore
================================================
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
node_modules
./dist
dist-ssr
src-tauri/gen/*
!src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/
*.local
target/*
.claude/*
.superpowers/*
.agents/*
/docs/*/*
skills-lock.json
/.pnp
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/versions
# testing
/coverage
*.test.*
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# Android signing keys
*.keystore
*.jks
android-app.keystore
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# env files (can opt-in for committing if needed)
.env*
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts
docs/.vitepress/dist
docs/.vitepress/cache
.idea
# Exclude all markdown files in root directory except README.md
/*.md
!README.md
# backup files
*.backup
.backup
# worktrees
.worktrees
================================================
FILE: .vscode/settings.json
================================================
{
"marscode.codeCompletionPro": {
"enableCodeCompletionPro": false
},
"marscode.enableInlineCommand": false,
"i18n-ally.localesPaths": [
"messages",
"src/i18n"
]
}
================================================
FILE: LICENSE
================================================
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2025 codexu, https://notegen.top/.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.
================================================
FILE: README.md
================================================
# NoteGen

[](https://github.com/codexu/note-gen)
[](https://gitcode.com/codexu/note-gen)

[](https://app.netlify.com/projects/note-gen-docs/deploys)


<div>
<a href="https://trendshift.io/repositories/12784" target="_blank"><img src="https://trendshift.io/api/badge/repositories/12784" alt="codexu%2Fnote-gen | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
<a href="https://hellogithub.com/repository/0163cb946dca44cc8905dbe34c2c987b" target="_blank"><img src="https://abroad.hellogithub.com/v1/widgets/recommend.svg?rid=0163cb946dca44cc8905dbe34c2c987b&claim_uid=YJ39kIMBz1TGAvc" alt="Featured|HelloGitHub" style="width: 250px; height: 54px;" width="250" height="54" /></a>
<a href="https://www.producthunt.com/products/notegen-2?embed=true&utm_source=badge-featured&utm_medium=badge&utm_source=badge-notegen-2" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=956348&theme=light&t=1749194675492" alt="NoteGen - A cross-platform Markdown note-taking application | Product Hunt" style="width: 250px; height: 54px;" width="250" height="54" /></a>
</div>
## 我正在寻找工作 / Looking For Work
我是一名全栈(侧重前端)开发者,目前正在寻找新的工作机会,欢迎联系我!
I am a full-stack (with a focus on front-end) developer, currently looking for new job opportunities. Feel free to contact me!
我希望可以获取一份远程办公的工作,或在北京的公司上班。
I am looking for a remote job or a position in a company based in Beijing.
Email: xu461229187@gmail.com
## Guide
🖥️ Official Document: [English](https://notegen.top/en/) | [简体中文](https://notegen.top/cn/)
💬 Join [WeChat/QQ Group](https://github.com/codexu/note-gen/discussions/110), [Discord](https://discord.gg/SXyVZGpbpk), [Telegram](https://t.me/notegen)
NoteGen is a cross-platform `Markdown` note-taking application dedicated to using AI to bridge recording and writing, organizing fragmented knowledge into a readable note.

## Features
- 🚀 Lightweight (25MB), free, no ads.
- 🌐 Cross-platform support.
- 🆓 Free AI and sync solutions.
- 📦 Out-of-the-box RAG support.
- 🔌 MCP support for AI tool integration.
- 🤖 Intelligent agents for automated note processing.
- ✍️ Quick note-taking for fragmented information.
- 📝 Native Markdown storage format.
## Download
|  |  |  |  |  |
| --- | --- | --- | --- | --- |
| ✅ beta | ✅ beta | ✅ beta | 🛠️ alpha | 🛠️ alpha |
| [Download](https://notegen.top/en/docs/download#desktop-beta) | [Download](https://notegen.top/en/docs/download#desktop-beta) | [Download](https://notegen.top/en/docs/download#desktop-beta) | [Download](https://notegen.top/en/docs/download#android) | [TestFlight](https://testflight.apple.com/join/8KjFRTCq) |
> [UpgradeLink offers application upgrade and download services](http://upgrade.toolsetlink.com/upgrade/example/tauri-example.html)
## From Recording to Writing
Traditional note-taking apps typically don't offer note-taking functionality, but NoteGen makes it easier for you to record scattered knowledge points and avoid disrupting your train of thought while taking notes.
NoteGen is divided into three parts: Recording, Notes, and AI Dialogue. They have the following features:
- You don't need to consider the order and logic of recording, AI will help you organize the notes into well-organized and coherent ones.
- AI Dialogue is a feature that allows you to interact with AI in real-time, helping you to better understand and remember the content you are recording.
- The note-taking feature can help you optimize the details of your notes independently.
## Contribute
- [Read contribution guide](https://notegen.top/en/docs/contributing)
- [Update plans](https://github.com/codexu/note-gen/issues/46)
- [Submit bugs or improvement suggestions](https://github.com/codexu/note-gen/issues)
- [Discussions](https://github.com/codexu/note-gen/discussions)
## Contributors
<a href="https://github.com/codexu/note-gen/graphs/contributors">
<img src="https://contrib.rocks/image?repo=codexu/note-gen" />
</a>
## Thanks
Special thanks to our technology partners who make NoteGen better:
**[SiliconFlow](https://cloud.siliconflow.cn/i/O2ciJeZw)** - Providing free AI model services, powering NoteGen's intelligent features with high-quality AI capabilities.
<a href="https://cloud.siliconflow.cn/i/O2ciJeZw" target="_blank">
<img width="240" src="https://s2.loli.net/2025/09/10/KWPOA5XhIGmYTV9.png" />
</a>
**[UpgradeLink](http://upgrade.toolsetlink.com/upgrade/example/tauri-example.html)** - Providing reliable installation and upgrade services, ensuring seamless software updates for users.
<a href="http://upgrade.toolsetlink.com/upgrade/example/tauri-example.html" target="_blank">
<img width="240" src="https://s2.loli.net/2025/09/10/Ks4EayU9HguXDMF.png" />
</a>
---
We also thank other partners for their service support
<div>
<a href="https://www.qiniu.com/products/ai-token-api?utm_source=NoteGen" target="_blank">
<img src="https://s2.loli.net/2025/06/11/OKJq542lTs7U9xg.png" />
</a>
<a href="https://share.302.ai/jfFrIP" target="_blank">
<img src="https://s2.loli.net/2025/07/01/dPlkU1tejnDyV4S.png" />
</a>
<a href="https://www.shengsuanyun.com/?from=CH_KAFLGC9O" target="_blank">
<img src="https://s2.loli.net/2025/09/15/CcVRbTUBtf7ZvNl.png" />
</a>
<a href="https://ai.gitee.com/" target="_blank">
<img src="https://s2.loli.net/2025/09/15/wmnBWfyACMz9pVc.png" />
</a>
<a href="https://www.netlify.com" target="_blank">
<img src="https://s2.loli.net/2025/09/16/yJ64xIlrhdABt9o.png" />
</a>
<a href="https://skywork.ai/p/bY47ky" target="_blank">
<img src="https://s2.loli.net/2025/09/16/mTzMCQ8tZLfJNk5.png" />
</a>
</div>
================================================
FILE: components.json
================================================
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "tailwind.config.ts",
"css": "src/app/globals.css",
"baseColor": "zinc",
"cssVariables": true,
"prefix": ""
},
"iconLibrary": "lucide",
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"registries": {
"@magicui": "https://magicui.design/r/{name}.json"
}
}
================================================
FILE: messages/en.json
================================================
{
"app": {
"title": "Note Generator",
"description": "Your AI-powered note taking assistant"
},
"common": {
"save": "Save",
"cancel": "Cancel",
"delete": "Delete",
"edit": "Edit",
"create": "Create",
"theme": "Theme",
"light": "Light",
"dark": "Dark",
"system": "System",
"pin": "Pin",
"unpin": "Unpin",
"settings": "Settings",
"back": "Back",
"sync": "Sync",
"language": "Language",
"confirm": "Confirm",
"selectPrompt": "Select Prompt",
"prompt": "Prompt",
"success": "Success",
"error": "Failed",
"defaultFileName": "Untitled",
"restartToApply": ", please restart the application for the configuration to take effect",
"unsaved": "Unsaved",
"saving": "Saving...",
"close": "Close",
"open": "Open",
"add": "Add",
"remove": "Remove",
"search": "Search",
"filter": "Filter",
"sort": "Sort",
"export": "Export",
"import": "Import",
"refresh": "Refresh",
"loading": "Loading...",
"all": "All",
"today": "Today",
"yesterday": "Yesterday",
"warning": "Warning",
"info": "Info",
"configureSync": "Configure Sync"
},
"settings": {
"defaultModels": {
"title": "Default Models"
},
"others": "Advanced",
"general": {
"title": "General Settings",
"desc": "Here, you can configure basic application settings, including interface theme, language and other options.",
"interface": {
"title": "Interface Settings",
"theme": {
"title": "Theme",
"desc": "Choose the application's appearance theme",
"options": {
"light": "Light",
"dark": "Dark",
"system": "System"
}
},
"language": {
"title": "Language",
"desc": "Choose the application's display language"
},
"scale": {
"title": "Interface Scale",
"desc": "Adjust the overall scale of the application interface",
"placeholder": "Select scale ratio"
},
"contentTextScale": {
"title": "Content Scale",
"desc": "Adjust the text size in editor and chat Markdown content"
},
"fileManagerTextSize": {
"title": "File Manager Text Size",
"desc": "Adjust the text size of file and folder lists in the file manager"
},
"recordTextSize": {
"title": "Record Text Size",
"desc": "Adjust the text size of record items in the record list"
},
"customCss": {
"title": "Custom CSS",
"desc": "Add custom CSS styles to override the application's default styles",
"button": "Edit CSS",
"dialogTitle": "Custom CSS",
"dialogDesc": "Enter custom CSS code below to override the application's default styles. Click save to apply changes.",
"placeholder": "Enter custom CSS code here",
"save": "Save",
"cancel": "Cancel"
},
"customTheme": {
"title": "Custom Theme Colors",
"desc": "Customize application theme colors including background, foreground, border, etc.",
"button": "Edit Colors",
"dialogTitle": "Custom Theme Colors",
"dialogDesc": "Configure custom theme colors. Color changes are saved and applied in real-time, overriding both light and dark themes.",
"close": "Close",
"reset": "Reset All",
"tabs": {
"custom": "Custom",
"presets": "Presets",
"importExport": "Import/Export"
},
"export": {
"title": "Export Color Scheme",
"button": "Generate Export Code",
"placeholder": "Click the generate button to export current color scheme as code"
},
"import": {
"title": "Import Color Scheme",
"button": "Import Scheme",
"placeholder": "Paste the JSON code of the color scheme"
},
"colors": {
"background": "Background",
"foreground": "Foreground",
"card": "Card Background",
"cardForeground": "Card Foreground",
"primary": "Primary",
"primaryForeground": "Primary Foreground",
"secondary": "Secondary",
"secondaryForeground": "Secondary Foreground",
"third": "Third",
"thirdForeground": "Third Foreground",
"muted": "Muted",
"mutedForeground": "Muted Foreground",
"accent": "Accent",
"accentForeground": "Accent Foreground",
"border": "Border",
"shadow": "Shadow"
},
"presets": {
"apply": "Apply",
"reset": {
"name": "Reset to Default"
},
"default": {
"name": "Default White"
},
"ocean": {
"name": "Ocean Blue"
},
"forest": {
"name": "Forest Green"
},
"sunset": {
"name": "Sunset Red"
},
"lavender": {
"name": "Lavender Purple"
},
"midnight": {
"name": "Midnight Dark"
},
"deepSea": {
"name": "Deep Sea"
},
"darkForest": {
"name": "Dark Forest"
},
"darkViolet": {
"name": "Dark Violet"
},
"coralWarm": {
"name": "Coral Warm"
},
"slateGray": {
"name": "Slate Gray"
},
"darkGold": {
"name": "Dark Gold"
},
"beigeWarm": {
"name": "Beige Warm"
},
"beigeDark": {
"name": "Beige Dark"
}
}
},
"tray": {
"enabled": {
"title": "Enable Tray",
"desc": "Choose to minimize to tray or close app when window is closed"
}
}
},
"tools": {
"title": "Tool Settings",
"desc": "Configure display and sorting of various toolbar buttons",
"chatToolbar": {
"title": "Chat Toolbar",
"desc": "Customize the display order and visibility of chat toolbar buttons",
"button": "Configure",
"dialogTitle": "Configure Chat Toolbar",
"dialogDesc": "Drag tools to adjust order, use switches to show or hide",
"groups": {
"pc": "PC",
"mobile": "Mobile",
"bottom": "Bottom Toolbar",
"topLeft": "Top Toolbar - Left",
"topRight": "Top Toolbar - Right"
}
},
"recordToolbar": {
"title": "Record Toolbar",
"desc": "Customize the display order and visibility of record toolbar buttons",
"button": "Configure",
"dialogTitle": "Configure Record Toolbar",
"dialogDesc": "Drag tools to adjust order, use switches to show or hide"
}
}
},
"rag": {
"title": "Knowledge Base",
"desc": "Here, you can configure knowledge base related settings, knowledge base based on RAG technology, through embedding models to convert text into vectors, then through vector search to achieve intelligent search and intelligent answers.",
"settingsTitle": "Parameter Settings",
"settingsDesc": "By adjusting parameters, you can more precisely control the retrieval effect of the knowledge base.",
"deleteVectorConfirm": "Are you sure you want to clear the knowledge base?",
"deleteVectorSuccess": "Knowledge base cleared successfully",
"enable": "Enable knowledge base search",
"enableDesc": "Enabling it will make AI search your notes when answering questions, providing more accurate answers.",
"chunkSize": "Chunk size",
"chunkSizeDesc": "The maximum number of characters for text chunking. Larger chunks may contain more context, but will increase vector calculation complexity.",
"chunkOverlap": "Chunk overlap",
"chunkOverlapDesc": "The number of overlapping characters between text chunks. Larger overlaps can maintain context continuity.",
"resultCount": "Result count",
"resultCountDesc": "The number of related documents returned when searching. The more documents, the more information provided, but may also introduce noise.",
"similarityThreshold": "Similarity threshold",
"similarityThresholdDesc": "The minimum similarity threshold between documents and queries. Only documents exceeding this threshold will be returned. The value range is 0.0-1.0, the higher the threshold, the stricter the requirement.",
"resetToDefaults": "Reset to defaults",
"deleteVector": "Clear knowledge base",
"topPDesc": "Top P parameter controls the diversity of text generated by the model. Smaller values make the output more deterministic, while larger values make it more diverse."
},
"mcp": {
"title": "MCP",
"desc": "Model Context Protocol allows AI to call external tools and access resources, extending AI capabilities.",
"enableTitle": "Enable MCP",
"enableDesc": "When enabled, AI can call tools provided by configured MCP servers.",
"servers": "Server List",
"serversDesc": "Manage MCP server configurations. Each server can provide different tools and resources.",
"addServer": "Add Server",
"addFirstServer": "Add First Server",
"editServer": "Edit Server",
"serverName": "Server Name",
"serverNamePlaceholder": "e.g., File System Server",
"serverEnabled": "Enable Server",
"serverEnabledDesc": "When enabled, this server will automatically connect and provide tools.",
"serverType": "Server Type",
"stdio": "Local Command",
"http": "HTTP Service",
"command": "Command",
"args": "Arguments",
"argsDesc": "Command line arguments, separated by spaces",
"env": "Environment Variables",
"envDesc": "Environment variable configuration in JSON format",
"url": "Service URL",
"headers": "Request Headers",
"headersDesc": "HTTP request headers in JSON format",
"testConnection": "Test Connection",
"test": "Test",
"testSuccess": "Connection test successful",
"testFailed": "Connection test failed",
"connected": "Connected",
"connecting": "Connecting",
"disconnected": "Disconnected",
"error": "Error",
"tools": "Tools",
"noServers": "MCP service not enabled",
"noServersFound": "No matching servers found",
"serverAdded": "Server added successfully",
"serverUpdated": "Server updated successfully",
"serverDeleted": "Server deleted successfully",
"deleteServerTitle": "Delete Server",
"deleteServerDesc": "Are you sure you want to delete this server? This action cannot be undone.",
"nameRequired": "Please enter server name",
"commandRequired": "Please enter command",
"urlRequired": "Please enter service URL",
"toolBrowser": "Tool Browser",
"searchTools": "Search tools...",
"noToolsFound": "No tools found",
"parameters": "Parameters",
"testAll": "Test All Connections",
"testAllCompleted": "All connection tests completed",
"testAllFailed": "Connection test failed",
"save": "Save",
"cancel": "Cancel",
"delete": "Delete",
"importJson": "Import JSON",
"jsonImportTitle": "Import Server Configuration from JSON",
"jsonImportDesc": "Paste the mcpServers configuration format for MCP servers",
"jsonInput": "JSON Configuration",
"jsonInputHelp": "Supports mcpServers format, automatically uses server name as key",
"jsonRequired": "Please enter JSON configuration",
"jsonEmpty": "JSON configuration cannot be empty",
"jsonInvalidJson": "Invalid JSON format",
"jsonInvalidFormat": "Invalid configuration format, must contain name and type fields",
"jsonInvalidType": "Server type must be stdio or http",
"jsonMissingCommand": "stdio type server must specify command",
"jsonMissingUrl": "http type server must specify url",
"jsonImportSuccess": "Successfully imported {count} server(s)",
"jsonImportSkipped": "Skipped {count} existing server(s)",
"jsonImportNoServers": "No servers were imported",
"import": "Import",
"mobileHttpOnlyTitle": "Desktop-only local command MCP",
"mobileHttpOnlyDesc": "Local command MCP servers are only supported on desktop. Mobile currently supports HTTP MCP only.",
"runtimeEnvironment": "Runtime Environment",
"runtimeEnvironmentDesc": "Check whether the required local runtime is available before testing the MCP server.",
"checkEnvironment": "Check Environment",
"recheckEnvironment": "Re-check Environment",
"runtimeCheckFailed": "Environment check failed",
"detectedLauncher": "Detected launcher",
"runtimeInstalled": "Installed",
"runtimeMissing": "Missing",
"runtimeVersion": "Version",
"runtimeInstalledSummary": "{installed}/{total} installed",
"showRuntimeDetails": "Show runtime details",
"hideRuntimeDetails": "Hide runtime details",
"runtimeNotChecked": "This runtime has not been checked yet.",
"runtimeCurrentUserScope": "Recommended command targets the current user environment when supported.",
"runtimeManualOnly": "Automatic install is not available for this runtime on the current platform. Please install it manually and run the check again.",
"installRuntime": "Install Runtime",
"runtimeInstallTitle": "Install runtime",
"runtimeInstallDesc": "NoteGen will run the following install command after confirmation.",
"runtimeInstallPreparing": "Preparing install",
"runtimeInstallRunning": "Installing",
"runtimeInstallCompleted": "Install completed",
"runtimeInstallCancelled": "Cancelled",
"runtimeInstallFailedState": "Install failed",
"runtimeInstallLogs": "Install logs",
"runtimeInstallWaitingLogs": "Waiting for install output...",
"runtimeInstallClose": "Close",
"runtimeInstallCancel": "Stop install",
"runtimeInstallCancelledByUser": "Cancellation requested by user.",
"runtimeInstallCancelFailed": "Failed to stop install",
"runtimeInstallSuccess": "Runtime installation completed",
"runtimeInstallFailed": "Runtime installation failed",
"runtimeNoGuidedSupport": "No guided runtime assistance is available for this command yet."
},
"skills": {
"title": "Skills",
"desc": "Skills are reusable AI capability packages that allow AI assistants to automatically apply specific behavioral patterns based on tasks.",
"enable": "Enable Skills",
"enableDesc": "When enabled, AI can use configured Skills",
"autoMatch": "Auto-match Skills",
"autoMatchDesc": "Automatically select appropriate Skills based on user input",
"project": "Workspace Skills",
"global": "Global Skills",
"globalPath": "Global Skills Storage Location",
"openInFileManager": "Open in File Manager",
"createSkill": "Create Skill",
"editSkill": "Edit Skill",
"deleteSkill": "Delete Skill",
"exportSkill": "Export Skill",
"importSkill": "Import Skill",
"selectSkillZip": "Select Skill zip file",
"importSuccess": "Import successful",
"importError": "Import failed",
"imported": "imported",
"importing": "Importing...",
"skillName": "Skill Name",
"skillDescription": "Description",
"skillVersion": "Version",
"skillAuthor": "Author",
"allowedTools": "Allowed Tools",
"userInvocable": "Show in Slash Menu",
"instructions": "Instructions",
"instructionsPlaceholder": "Enter detailed instructions for AI...",
"importHelp": "Support importing Skills in zip format. The zip file must contain a SKILL.md file.",
"metadata": "Metadata",
"content": "Instructions",
"noSkills": "No Skills yet",
"noSkillsDesc": "Create or import Skills to get started",
"noSkillsGlobal": "No global Skills yet",
"noSkillsGlobalDesc": "Create or import Skills to use across all projects",
"emptyWorkspace": "No Skills in workspace",
"emptyWorkspaceDesc": "Create SKILL.md files in the skills folder to add Skills",
"basicSettings": "Basic Settings",
"installedGlobalSkills": "Installed Global Skills",
"nameRequired": "Please enter Skill name",
"descriptionRequired": "Please enter description",
"namePlaceholder": "note-organizer",
"versionPlaceholder": "1.0.0",
"descriptionPlaceholder": "Automatically organize and optimize note structure...",
"authorPlaceholder": "Your Name",
"descriptionHelp": "Used for AI matching, describes the Skill's functionality and use cases",
"allowedToolsHelp": "These tools can be used without user confirmation",
"userInvocableHelp": "Users can manually trigger via /skill-name",
"instructionsHelp": "Detailed instructions for AI, supports Markdown format",
"deleteSkillTitle": "Delete Skill",
"deleteSkillDesc": "Are you sure you want to delete this Skill? This action cannot be undone.",
"skillDeleted": "Skill deleted successfully"
},
"editor": {
"title": "Editor Settings",
"interfaceSettings": "Interface Settings",
"desc": "Here, you can customize the editor, creating a writing experience tailored to your needs.",
"centeredContent": "Centered Content",
"centeredContentDesc": "When enabled, editor content will be centered with margins on both sides.",
"outlineEnable": "Default outline enabled",
"outlineEnableDesc": "Enabling it will make the outline visible by default.",
"outlinePosition": "Outline position",
"outlinePositionDesc": "Set outline position.",
"outlinePositionOptions": {
"left": "Left",
"right": "Right"
},
"showUndoRedo": "Undo/Redo buttons",
"showUndoRedoDesc": "Show undo and redo buttons in the editor tab bar.",
"completion": {
"title": "Auto Completion",
"model": {
"title": "Quick Completion Model",
"desc": "Select the model for AI inline completion in editor"
}
},
"commit": {
"title": "Auto Commit Message",
"model": {
"title": "Commit Model",
"desc": "For automatically generating Git commit messages based on file changes"
}
},
"mermaid": {
"title": "Diagram",
"rendering": "Rendering...",
"renderError": "Render error",
"clickToEdit": "Click to edit source",
"clickToAdd": "Click to add diagram",
"placeholder": "Enter Mermaid diagram code...",
"preview": "Preview",
"done": "Done",
"diagramTypes": {
"flowchart": "Flowchart",
"sequence": "Sequence",
"classDiagram": "Class Diagram",
"stateDiagram": "State Diagram",
"er": "ER Diagram",
"gantt": "Gantt",
"pie": "Pie Chart",
"journey": "Journey"
},
"templates": {
"flowchart": "graph TD\n A[Start] --> B[Process]\n B --> C[End]",
"sequence": "sequenceDiagram\n participant Alice\n participant Bob\n Alice->>Bob: Hello\n Bob-->>Alice: Reply",
"classDiagram": "classDiagram\n Animal <|-- Duck\n Animal <|-- Fish\n Animal : +int age\n Animal : +String gender",
"stateDiagram": "stateDiagram-v2\n [*] --> Active\n Active --> [*]",
"er": "erDiagram\n CUSTOMER ||--o{ ORDER : places\n CUSTOMER ||--o{ DELIVERY-ADDRESS : uses",
"gantt": "gantt\n title Project Plan\n dateFormat YYYY-MM-DD\n section Phase 1\n Task1 :a1, 2024-01-01, 30d\n section Phase 2\n Task2 :after a1, 20d",
"pie": "pie title Resource Allocation\n \"CPU\" : 45\n \"Memory\" : 30\n \"Storage\" : 25",
"journey": "journey\n title My Daily Work\n section Morning\n Commute : 7:00, 5\n Work : 9:00, 8"
}
}
},
"record": {
"title": "Record Settings",
"desc": "Configure record-related settings here, including record description and toolbar configuration.",
"model": {
"title": "Model Settings",
"markDesc": {
"title": "Record Description",
"desc": "For processing OCR-recognized records and generating record descriptions"
}
},
"toolbar": {
"title": "Toolbar Settings",
"recordToolbar": {
"title": "Record Toolbar",
"desc": "Customize the visibility and order of record toolbar buttons",
"button": "Configure",
"text": {
"desc": "Record text content"
},
"recording": {
"desc": "Voice recording function"
},
"scan": {
"desc": "Scan and recognize text from images"
},
"image": {
"desc": "Upload images to notes"
},
"link": {
"desc": "Record web links"
},
"file": {
"desc": "Upload files to notes"
},
"todo": {
"desc": "Create todo items"
}
}
}
},
"uploadStore": {
"uploadConfirm": "Upload configuration please ensure the sync repository is private, otherwise the data will be leaked!",
"downloadConfirm": "Download configuration will cover local configuration and restart to take effect!",
"uploadSuccess": "Upload success",
"downloadSuccess": "Download success",
"upload": "Upload",
"download": "Download"
},
"about": {
"title": "About",
"desc": "A note-taking assistant focused on record and writing.",
"version": "NoteGen v{version}",
"checkReleases": "Check Release History",
"language": "Language",
"checkUpdate": "Check for Updates",
"checkError": "Failed to check for updates",
"updateAvailable": "Update to new version",
"updateDownloading": "Updating {downloaded} / {contentLength}",
"updateInstalled": "Restart app",
"noUpdate": "Current version is the latest",
"ignoreVersion": "Ignore this version",
"ignoreVersionSuccess": "This version update has been ignored",
"items": {
"home": {
"title": "Home",
"buttonName": "Open",
"desc": "Visit the website to learn more about NoteGen."
},
"guide": {
"title": "Guide",
"buttonName": "Open",
"desc": "View configuration guide, learn how to configure models, sync, etc. information."
},
"github": {
"title": "GitHub",
"buttonName": "View",
"desc": "If NoteGen helps you, please give a star to encourage!"
},
"releases": {
"title": "Update Log",
"buttonName": "View",
"desc": "View update log, learn more about NoteGen's updates."
},
"issues": {
"title": "Issue Feedback",
"buttonName": "Feedback",
"desc": "If you find a bug in NoteGen, please feedback here."
},
"discussions": {
"title": "Discussions",
"buttonName": "Discuss",
"desc": "If you want to discuss with the author or other users, you can join the group discussion."
}
}
},
"memories": {
"title": "Memory Management",
"desc": "AI long-term memory feature that lets AI remember your writing preferences, experiences, and note-taking habits.",
"stats": {
"total": "Total Memories",
"preferences": "Preferences",
"memories": "Memories"
},
"form": {
"title": "Add New Memory",
"categoryDescription": "Memories are divided into two types:",
"preferenceDescription": "Preferences: Settings like language, format, style - always loaded in conversations",
"memoryDescription": "Memories: Facts, experiences, expertise - intelligently matched based on conversation context",
"contentLabel": "Memory Content",
"contentPlaceholder": "e.g., I prefer Chinese responses, I'm a React expert...",
"categoryLabel": "Type",
"preferenceLabel": "Preference",
"memoryLabel": "Memory",
"preferenceDesc": "Language, format, style, etc.",
"memoryDesc": "Facts, experience, expertise, etc.",
"save": "Save Memory",
"saving": "Saving..."
},
"listTitle": "My Memories",
"addMemory": "Add Memory",
"empty": "No memories yet, add your first memory!",
"emptyHint": "You can add memories manually, or use phrases like \"please remember\" or \"remember this\" in conversations to let AI automatically create memories.",
"preference": "Preference",
"memory": "Memory",
"replaced": "Replaced",
"accessCount": "Accessed {count} times",
"tabs": {
"all": "All",
"preference": "Preferences",
"memory": "Memories"
},
"success": "Success",
"saved": "Memory saved",
"updated": "Memory updated (similar memory replaced)",
"deleted": "Memory deleted",
"cleared": "All memories cleared",
"found": "Found {count} memories",
"error": "Error",
"errorEmpty": "Please enter memory content",
"errorSave": "Failed to save",
"errorDelete": "Failed to delete",
"errorList": "Failed to get memory list",
"errorEmbedding": "Failed to generate embedding, please check embedding model configuration",
"errorClear": "Failed to clear"
},
"defaultModel": {
"title": "Default Model",
"desc": "Here, you can use different models for different scenes, to improve efficiency and reduce costs.",
"tooltip": "Use main model",
"noModel": "Do not use",
"placeholder": "Please select or search for models",
"main": "Main model",
"options": {
"primaryModel": {
"title": "Main model",
"desc": "As the main model for all scenarios, this model is used if other dialogue models do not select the default model."
},
"markDesc": {
"title": "Record Description",
"desc": "Used to process records after OCR recognition, generating record descriptions."
},
"placeholder": {
"title": "AI Suggestion",
"desc": "AI suggestion prompt for generating placeholder content in the record page AI conversation."
},
"completion": {
"title": "Fast Completion",
"desc": "AI inline completion for Markdown editor, similar to GitHub Copilot, quickly generates continuation content."
},
"commit": {
"title": "Auto Generate Commit Message",
"desc": "Used to automatically generate Git commit messages, intelligently generating descriptive commit messages based on file content changes."
},
"embedding": {
"title": "Embedding Model",
"desc": "Used for text embedding and vectorization scenarios."
},
"reranking": {
"title": "Reranking Model",
"desc": "Used for reordering and optimizing search results."
},
"condense": {
"title": "Condense Model",
"desc": "Used to compress historical conversation content to save token usage"
}
},
"mainModel": "Main Model"
},
"audio": {
"title": "Audio Settings",
"desc": "Here, you can configure audio settings, including text-to-speech (TTS) and speech-to-text (STT) functions.",
"mode": {
"title": "Mode",
"auto": "Auto (Recommended)",
"local": "Local only",
"model": "Model only"
},
"tts": {
"title": "Text-to-Speech (TTS)",
"desc": "Configure read aloud functionality to provide voice playback for chat content.",
"modeDesc": "Prefer browser and system voices by default, and use a model only when needed for a better experience.",
"model": {
"title": "TTS Model",
"desc": "Optional. Configure a model to enhance auto mode or to power model-only mode."
},
"speed": {
"title": "Speech Rate",
"desc": "Adjust the playback speed of the voice, ranging from 0.5x to 2x speed, with 1x being the normal speed."
}
},
"stt": {
"title": "Speech-to-Text (STT)",
"desc": "Configure voice recognition to convert speech to text records.",
"modeDesc": "Prefer native browser recognition by default, and fall back to a model when local support is unavailable.",
"model": {
"title": "STT Model",
"desc": "Optional. Configure a model for auto fallback or for model-only mode."
}
}
},
"readAloud": {
"title": "Read Aloud",
"desc": "Configure read aloud behavior. System voices are preferred by default, with model speech as an enhancement.",
"options": {
"mode": {
"title": "Mode",
"desc": "Auto mode prefers system voices and only tries a model when local speech is unavailable.",
"auto": "Auto (Recommended)",
"local": "Local only",
"model": "Model only"
},
"audioModel": {
"title": "Read Aloud Model",
"desc": "Optional. Configure a model to enhance auto mode or to power model-only mode."
},
"speed": {
"title": "Speed",
"desc": "Adjust read aloud speed from 0.5x to 2x, with 1x as the default rate."
}
}
},
"prompt": {
"title": "Prompt",
"promptTitle": "Prompt Title",
"desc": "Here, you can add and manage prompts, helping AI better understand your needs.",
"addPrompt": "Add Prompt",
"selectPrompt": "Select Prompt",
"configPrompt": "Configure Prompt",
"noContent": "No content",
"addPromptDesc": "Please enter the prompt name and content, helping AI better understand your needs.",
"promptTitlePlaceholder": "Please enter the prompt name",
"promptContentPlaceholder": "Please enter the prompt content",
"promptContent": "Prompt Content",
"optimizePrompt": "Optimize Prompt",
"optimizing": "Optimizing...",
"optimizeSuccess": "Prompt optimized successfully",
"optimizeFailed": "Failed to optimize prompt, please try again later",
"noContentToOptimize": "Please enter prompt content first"
},
"sync": {
"title": "Sync",
"desc": "Here, you can configure the synchronization repository, which can help you synchronize records, markdown files, system configurations and other information.",
"selectPlatform": "Select Sync Platform",
"platformSettings": "Select Platform",
"settings": "Sync Settings",
"platformDesc": "Configure Token and repository information to enable sync",
"moreSettings": "More Settings",
"repoStatus": "Repository Status",
"syncRepo": "Sync Repository",
"syncRepoDesc": "Sync markdown files in writing",
"imageRepo": "Image Repository",
"imageRepoDesc": "Sync your images to repository, using jsdelivr for acceleration",
"status": {
"connected": "Connected",
"disconnected": "Disconnected",
"failed": "Connection Failed",
"unconfigured": "Not Configured"
},
"uploadRecords": "Upload Records & Config",
"downloadConfig": "Download Records & Config",
"cloudSync": "Records & Config Sync",
"localBackupAll": "Local Backup (All)",
"private": "Private",
"public": "Public",
"createdAt": "Created {time}",
"updatedAt": "Last updated {time}",
"newToken": "Create Access Token",
"newTokenDesc": "When creating a new token, please make sure to check the repo permission, and after configuration, it will automatically create a file repository (private) and an image repository.",
"giteeTokenDesc": "Gitee personal access token is used for data synchronization. It needs repository read and write permissions. After configuration, it will automatically create a file repository (private) and an image repository.",
"imageRepoSetting": "Enable Image Hosting",
"imageRepoSettingDesc": "You have already configured an image repository, you can choose to use the image repository or use local storage.",
"jsdelivrSetting": "jsDelivr",
"autoSyncDesc": "When enabled, the editor will automatically sync to GitHub 10 seconds after input stops",
"giteeAutoSyncDesc": "When enabled, the editor will automatically sync to Gitee 10 seconds after input stops",
"customSyncRepo": "Custom Sync Repository Name",
"customSyncRepoDesc": "Leave empty to use default repository name",
"customImageRepo": "Custom Image Repository Name",
"customImageRepoDesc": "Leave empty to use default repository name",
"backupMethod": "Backup Method",
"backupMethodDesc": "After setting as the primary backup method, all sync-related functions in writing will use the current backup method (except for image hosting)",
"createRepo": "Create Repository",
"creating": "Creating",
"checkRepo": "Check Repository",
"checking": "Checking",
"enterToken": "Please enter Access Token",
"enterTokenHint": "Please enter Access Token first to check repository status",
"defaultRepoName": "Default: {name}",
"gitlabInstanceType": "GitLab Instance Type",
"gitlabInstanceTypeDesc": "Select the type of GitLab instance to connect to",
"gitlabInstanceTypePlaceholder": "Select GitLab Instance Type",
"gitlabInstanceTypeOptions": {
"selfHosted": "Self-hosted Instance",
"selfHostedDesc": "Enter your self-hosted GitLab server address (e.g., https://gitlab.example.com)"
},
"gitlabAccessTokenDesc": "Create a personal access token at {instanceDisplayName}, requires api permission",
"giteaInstanceType": "Gitea Instance Type",
"giteaInstanceTypeDesc": "Select the type of Gitea instance to connect to",
"giteaInstanceTypePlaceholder": "Select Gitea Instance Type",
"giteaInstanceTypeOptions": {
"selfHosted": "Self-hosted Instance",
"selfHostedDesc": "Enter your self-hosted Gitea server address (e.g., https://gitea.example.com)"
},
"giteaAccessTokenDesc": "Create a personal access token at {instanceDisplayName}, requires full repository permission",
"s3": {
"title": "S3 Sync",
"description": "Sync your notes using S3-compatible storage",
"status": "Connection Status",
"connected": "Connected",
"connecting": "Connecting",
"disconnected": "Disconnected",
"accessKeyId": "Access Key ID",
"accessKeyIdPlaceholder": "Please enter Access Key ID",
"secretAccessKey": "Secret Access Key",
"secretAccessKeyPlaceholder": "Please enter Secret Access Key",
"region": "Region",
"bucket": "Bucket",
"bucketPlaceholder": "Please enter bucket name",
"endpoint": "Endpoint",
"pathPrefix": "Path Prefix",
"pathPrefixPlaceholder": "Please enter path prefix",
"pathPrefixDesc": "Used to differentiate files between different users, similar to repository name",
"customDomain": "Custom Domain",
"testConnection": "Test Connection",
"testing": "Testing",
"saveConfig": "Save Config",
"saving": "Saving"
},
"webdav": {
"title": "WebDAV Sync",
"description": "Sync your notes using WebDAV protocol",
"status": "Connection Status",
"connected": "Connected",
"connecting": "Connecting",
"disconnected": "Disconnected",
"url": "Server URL",
"urlPlaceholder": "Please enter WebDAV server URL",
"urlDesc": "Supports Synology, QNAP, Nextcloud and other WebDAV services",
"username": "Username",
"usernamePlaceholder": "Please enter username",
"password": "Password",
"passwordPlaceholder": "Please enter password",
"pathPrefix": "Path Prefix",
"pathPrefixPlaceholder": "Please enter path prefix",
"pathPrefixDesc": "Used to differentiate files between different users",
"testConnection": "Test Connection",
"testing": "Testing",
"saveConfig": "Save Config",
"saving": "Saving"
},
"autoSync": "Auto Sync",
"autoSyncOptions": {
"placeholder": "Select auto sync time",
"disabled": "Disabled",
"2s": "2 seconds",
"3s": "3 seconds",
"5s": "5 seconds",
"10s": "10 seconds",
"20s": "20 seconds",
"30s": "30 seconds",
"1m": "1 minute",
"2m": "2 minutes"
},
"autoPullOnOpen": "Auto pull when opening files",
"autoPullOnOpenDesc": "When opening a file, automatically pull remote version if newer",
"autoPullOnSwitch": "Auto pull when switching files",
"autoPullOnSwitchDesc": "When switching to another file, automatically pull remote version if newer",
"exclusions": {
"title": "Sync Exclusion Configuration",
"desc": "The following settings will not be synced across devices as they are device-specific",
"workspacePath": "Workspace Path",
"workspaceHistory": "Workspace History",
"assetsPath": "Assets Path",
"uiScale": "UI Scale",
"contentTextScale": "Content Text Scale",
"customCss": "Custom CSS",
"reason": "These settings may differ across devices, excluding them from sync prevents path errors and other issues"
},
"settingsSync": {
"uploadSuccess": "Settings uploaded successfully",
"uploadFailed": "Failed to upload settings",
"downloadSuccess": "Settings downloaded successfully",
"downloadFailed": "Failed to download settings",
"autoSync": "Settings will be automatically synced during upload/download (excluding device-specific settings like workspace path)"
},
"jsdelivrSettingDesc": "Use jsdelivr to accelerate image access."
},
"imageHosting": {
"title": "Image Hosting",
"desc": "Here, you can configure image hosting services for storing and managing your images.",
"type": "Select Platform",
"typeDesc": "Select image hosting service provider",
"customRepoName": "Custom Repository Name",
"customRepoNameDesc": "Leave empty to use default repository name",
"isPrimaryBackup": "Current {type} primary image hosting method",
"setPrimaryBackup": "Set as Primary Image Hosting",
"smms": {
"token": {
"desc": "Please create and input SM.MS Token.",
"createToken": "Create Token"
},
"disk": "Disk Usage",
"error": "Failed to get, please check network or Token is correct."
},
"picgo": {
"desc": "PicGo server URL",
"ok": "Service is running, please ensure PicGo image hosting is configured.",
"error": "Service is not running, please ensure PicGo (v2.2.0+) is running, otherwise image upload will fail."
},
"github": {
"title": "GitHub Image Hosting",
"description": "Use GitHub repository as image storage service",
"repoStatus": "Repository Status",
"repoExists": "Repository Exists",
"repoNotExists": "Repository Not Found",
"checking": "Checking",
"creating": "Creating",
"manualCreateTitle": "Manual Repository Creation Required",
"manualCreateDesc": "Please follow these steps to create the image hosting repository:",
"createSteps": {
"step1": "Visit GitHub and log in to your account",
"step2": "Click the \"+\" button in the top right corner, select \"New repository\"",
"step3": "Set repository name to:",
"step4": "Optionally set as private repository (recommended)",
"step5": "Click \"Create repository\" to complete creation",
"step6": "After creation, click the \"Recheck\" button below"
},
"createNewRepo": "Create New Repository",
"recheckRepo": "Recheck",
"recheckingRepo": "Checking...",
"createRepo": "Create Repository",
"creatingRepo": "Creating..."
},
"s3": {
"title": "S3 Object Storage",
"description": "Configure AWS S3 or S3-compatible object storage service as image hosting",
"status": "Connection Status",
"connected": "Connected",
"connecting": "Connecting",
"disconnected": "Disconnected",
"accessKeyId": "Access Key ID",
"accessKeyIdPlaceholder": "Enter Access Key ID",
"secretAccessKey": "Secret Access Key",
"secretAccessKeyPlaceholder": "Enter Secret Access Key",
"region": "Region",
"bucket": "Bucket",
"bucketPlaceholder": "Enter bucket name",
"advancedSettings": "Advanced Settings",
"endpoint": "Custom Endpoint",
"endpointDesc": "Leave empty for AWS S3, or enter S3-compatible service endpoint",
"customDomain": "Custom Domain",
"customDomainDesc": "Optional, custom domain for accessing images",
"pathPrefix": "Path Prefix",
"pathPrefixDesc": "Optional, path prefix for image storage",
"save": "Save Configuration",
"test": "Test Connection",
"setAsPrimary": "Set as Primary",
"error": "Configuration Error",
"requiredFields": "Please fill in required fields: Access Key ID, Secret Access Key, Region and Bucket",
"saveSuccess": "Configuration Saved",
"saveSuccessDesc": "S3 configuration has been saved",
"saveError": "Failed to Save Configuration",
"testSuccess": "Connection Test Successful",
"testSuccessDesc": "S3 connection is working, ready to upload images",
"testFailed": "Connection Test Failed",
"testFailedDesc": "Please check configuration and network connection",
"testFirstDesc": "Please test connection successfully before setting as primary",
"setPrimarySuccess": "Set Successfully",
"setPrimarySuccessDesc": "S3 has been set as primary image hosting"
}
},
"imageMethod": {
"title": "Image Recognition",
"desc": "Here, you can configure image recognition related settings, supporting OCR and VLM two ways.",
"enable": {
"title": "Enable Image Recognition",
"desc": "When enabled, images will be automatically recognized during screenshot and image recording. When disabled, image recognition will be skipped."
},
"setPrimary": "Set as default",
"isPrimary": "{type} has been set as default",
"ocr": {
"title": "OCR",
"languagePacks": "Language Pack",
"checkModels": "Here you can search all models",
"modelInstruction": "Comma separated, for example: eng,chi_sim"
},
"vlm": {
"title": "Visual Language Model",
"desc": "Use visual language model to recognize image content."
}
},
"backupSync": {
"title": "Backup Data",
"desc": "Here, you can use other methods to backup your data, you can regularly backup to ensure data security.",
"localBackup": {
"tabTitle": "Local Backup",
"export": {
"title": "Export Backup",
"desc": "Package application data into a .zip file and save to specified location.",
"button": "Choose Location and Export",
"simpleButton": "Export",
"exporting": "Exporting..."
},
"import": {
"title": "Import Backup",
"desc": "Restore application data from .zip file, will overwrite all current data.",
"button": "Choose File and Import",
"importing": "Importing...",
"warning": "Import operation will overwrite all current data, please ensure important content is backed up!"
},
"exportDialog": {
"title": "Choose backup file save location"
},
"importDialog": {
"title": "Choose backup file to import"
},
"exportSuccess": "Backup exported successfully!",
"exportError": "Backup export failed",
"importSuccess": "Backup imported successfully! Application will restart to apply changes.",
"importError": "Backup import failed",
"restartConfirm": "Import completed! Restart application now to apply changes?"
}
},
"template": {
"title": "Template",
"desc": "Here you can create and manage custom organization templates to help AI organize record content according to your needs.",
"customTemplate": "Custom Template",
"addTemplate": "Add Custom Template",
"deleteConfirm": "Are you sure to delete this template?",
"status": "Status",
"name": "Name",
"content": "Content",
"scope": "Scope",
"selectScope": "Select Scope",
"addTemplateDesc": "Please enter the custom template name and content, helping AI better understand your needs.",
"editTemplate": "Edit Custom Template",
"noContent": "No content",
"range": {
"all": "All",
"today": "Today",
"week": "Past Week",
"month": "Past Month",
"threeMonth": "Past 3 Months",
"year": "Past Year"
}
},
"shortcut": {
"title": "Shortcuts",
"screenshot": "Screenshot Record",
"link": "Link Record",
"textRecord": "Text Record",
"windowPin": "Window Pin"
},
"theme": {
"title": "Theme Settings",
"desc": "Customize application theme colors",
"appTheme": "App Color Scheme",
"previewTheme": "Preview Content Theme",
"codeTheme": "Code Block Highlight Theme",
"selectTheme": "Select Theme"
},
"dev": {
"title": "Developer",
"desc": "Here you can configure developer options, including network proxy, data cleanup, and configuration file management.",
"clearData": "Clear Data",
"clearDataConfirm": "Are you sure to clear data?",
"proxy": "Proxy, used to solve network problems, after configuration, it is recommended to restart the application.",
"proxyPlaceholder": "Enter proxy address",
"proxyTitle": "Network Proxy",
"clearDataTitle": "Clear Data",
"clearDataDesc": "Clear data information, including system configuration and database (including records).",
"clearFileTitle": "Clear Files",
"clearFileDesc": "Clear files, including images and articles.",
"clearButton": "Clear",
"configFileTitle": "Config File Management",
"configFileDesc": "Import and export configuration files. Importing will overwrite current configuration and take effect after restart.",
"importConfigTitle": "Import Config File",
"exportConfigTitle": "Export Config File",
"importConfigSuccessMobile": "Config downloaded successfully, please restart the app manually",
"exportConfigSuccess": "Export successful",
"importButton": "Import",
"exportButton": "Export"
},
"chat": {
"title": "Chat Settings",
"desc": "Configure chat-related settings here, including summary generation.",
"primaryModel": {
"title": "Primary Model",
"model": {
"title": "Primary Chat Model",
"desc": "Select the main AI model for daily conversations"
}
},
"toolbar": {
"title": "Toolbar Settings",
"chatToolbar": {
"title": "Chat Toolbar",
"desc": "Customize the visibility and order of chat toolbar buttons",
"button": "Configure",
"modelSelect": {
"desc": "Switch the AI model for conversation"
},
"promptSelect": {
"desc": "Select the preset prompt for the conversation"
},
"chatLanguage": {
"desc": "Set the language for the conversation"
},
"chatLink": {
"title": "Link Tag",
"desc": "Link note content of the current tag to conversation context"
},
"fileLink": {
"desc": "Link files or folders to the conversation context"
},
"mcpButton": {
"desc": "Select and connect MCP servers to use external tools"
},
"ragSwitch": {
"title": "Knowledge Base",
"desc": "Enable vector knowledge base retrieval"
},
"clipboardMonitor": {
"title": "Clipboard Monitor",
"desc": "Automatically monitor clipboard content changes"
},
"newChat": {
"desc": "Start a new conversation"
},
"clearContext": {
"desc": "Clear conversation context, keep chat history"
},
"clearChat": {
"desc": "Delete all chat records"
}
}
},
"condense": {
"title": "Conversation Summary",
"enable": {
"title": "Enable Summary",
"desc": "Automatically compress long conversations to save token usage"
},
"model": {
"title": "Summary Model",
"desc": "Select the AI model for generating summaries",
"placeholder": "Use primary model"
},
"threshold": {
"title": "Trigger Threshold",
"desc": "Check compression when AI messages exceed this count"
},
"minToken": {
"title": "Min Token Count",
"desc": "Only compress messages exceeding this token count"
},
"keepLatest": {
"title": "Keep Latest",
"desc": "Keep the latest N AI messages uncompressed"
},
"maxLength": {
"title": "Max Summary Length",
"desc": "Control the maximum word count of generated summaries"
},
"prompt": {
"title": "Custom Summary Prompt",
"desc": "Customize the prompt template for generating summaries",
"label": "Prompt Template",
"placeholder": "Enter custom prompt...",
"help": "Use {content} as a placeholder for original content",
"save": "Save",
"reset": "Reset to Default"
}
},
"conversationTitle": {
"title": "Conversation Title",
"model": {
"title": "Title Generation Model",
"desc": "Select the AI model for generating conversation titles"
}
},
"inspiration": {
"title": "Inspiration Model",
"model": {
"title": "Quick Prompt Generator",
"desc": "Generate quick prompt suggestions to help users start conversations"
}
}
},
"ai": {
"title": "Model Management",
"desc": "Here, you can add and manage various custom model services. After configuration, you will unlock AI-related features, such as organization and conversation functions.",
"modelTitle": "Custom Name",
"modelConfigTitle": "Model Config",
"modelConfigDesc": "Every configuration corresponds to an AI model, you can create new configurations through templates or custom.",
"providerInfo": "Provider Information",
"providerInfoDesc": "This configuration is created based on a provider template, with name and URL pre-configured.",
"create": "Create",
"createDesc": "Select an empty configuration or create a new configuration using the supplier template.",
"createSection": {
"title": "Custom Model Configuration",
"descWithoutModels": "Add custom AI model configurations to use more powerful model services."
},
"config": "Config",
"custom": "Custom",
"addCustomModel": "Custom",
"deleteCustomModel": "Delete",
"deleteCustomModelConfirm": "Are you sure to delete this custom model?",
"copyConfig": "Copy",
"builtin": "Built-in",
"modelSupport": "Only supports AI models with OpenAI protocol",
"apiKeyUrl": "Create API Key",
"modelType": {
"title": "Model Type",
"desc": "Select the type of AI model based on its capability",
"chat": "Chat",
"image": "Image",
"video": "Video",
"tts": "Text-to-Speech",
"stt": "Speech-to-Text",
"embedding": "Embedding",
"rerank": "Reranking"
},
"modelList": {
"error": {
"title": "Failed to get model list",
"description": "Please check if API Key or network is correct"
}
},
"selectModel": "Please select a model",
"modelProviderDesc": "Custom models only support AI models with OpenAI protocol.",
"modelTitleDesc": "Custom name, used to identify AI models, please do not repeat.",
"modelBaseUrlDesc": "You only need to configure the version number, for example: https://api.openai.com/v1, the suffix will be automatically added.",
"modelDesc": "Some models support getting model list, if not supported please manually configure.",
"temperatureDesc": "Controls randomness of output. Lower values make generated content more deterministic.",
"topPDesc": "A nucleus sampling method, where the model considers the results of tokens with top_p probability mass. So 0.1 means only consider the top 10% probability mass. Usually we suggest to change this or temperature but not both.",
"customHeaders": "Custom Headers",
"customHeadersDesc": "Add custom HTTP headers with key-value pairs.",
"headerKey": "Key",
"headerValue": "Value",
"addHeader": "Add Header",
"connectionSuccess": "AI connection test passed",
"voice": "Voice Type",
"voiceDesc": "Specify the voice type for audio models, such as 'alloy', 'echo', 'fable', etc.",
"voicePlaceholder": "Enter voice type, e.g.: alloy",
"defaultModels": {
"title": "Default Free Models",
"desc": "NoteGen provides free AI model services for users, enabling basic functionality without configuration.",
"chatModel": {
"name": "Qwen/Qwen3-8B",
"type": "Chat Model",
"desc": "Suitable for daily conversations and text generation"
},
"embeddingModel": {
"name": "BAAI/bge-m3",
"type": "Embedding Model",
"desc": "Used for text vectorization and semantic search"
},
"visionModel": {
"name": "OpenGVLab/InternVL2-8B",
"type": "Vision Model",
"desc": "Supports image understanding and visual Q&A"
},
"completionModel": {
"name": "Fast Completion",
"type": "Completion Model",
"desc": "AI inline completion for Markdown editor, similar to GitHub Copilot, quickly generates continuation content"
},
"poweredBy": "Powered by SiliconFlow"
},
"connectionFailed": "Connection Failed",
"enableStream": "Stream Response",
"enableStreamDesc": "Enable streaming response to display generated content in real-time, but some models may not support this feature.",
"selectConfig": "Please select a configuration",
"models": "Model List",
"modelsDesc": "Manage all models under the current configuration here. Each model can have different types and parameters.",
"addModel": "Add Model",
"newModel": "New Model",
"checkConnection": "Test Connection",
"model": "Model"
},
"ocr": {
"title": "OCR",
"languagePacks": "Language Packs",
"checkModels": "Check all models here",
"modelInstruction": "Separate with commas, e.g.: eng,chi_sim"
},
"file": {
"title": "File Settings",
"desc": "Here, you can manage workspace settings and other file-related options.",
"workspace": {
"title": "Workspace Settings",
"desc": "Set the application's workspace directory where files will be saved",
"current": "Current Workspace Path",
"defaultPath": "Default Workspace",
"default": "Using default workspace path",
"custom": "Using custom workspace path",
"select": "Select Workspace Directory",
"reset": "Reset to Default Path",
"history": "History Paths",
"selectFromHistory": "Select workspace from history",
"clearHistory": "Clear History",
"actions": "Actions",
"searchPlaceholder": "Search workspace paths...",
"noResults": "No results found"
},
"info": {
"title": "Workspace Information",
"desc": "After changing the workspace, you need to restart the application for the changes to take full effect. Files in the new workspace will be displayed after restart."
},
"toast": {
"updated": "Workspace Updated",
"updatedDesc": "Workspace set to: {path}",
"reset": "Workspace Reset",
"resetDesc": "Restored to default workspace",
"error": "Workspace Selection Failed",
"errorDesc": "Unable to select workspace directory, please try again",
"resetError": "Workspace Reset Failed",
"resetErrorDesc": "Unable to reset to default workspace, please try again"
},
"assets": {
"title": "Assets Path",
"desc": "Set the path where resources (e.g. images, videos, files etc.) used in writing will be saved. Resources will be saved at the same level as the currently edited markdown file.",
"select": "Set the path where resources used in writing will be saved"
}
},
"shortcuts": {
"title": "Shortcuts",
"desc": "Here, you can configure shortcuts to help you use NoteGen more efficiently.",
"resetDefaults": "Reset",
"clear": "Clear",
"noShortcut": "No Shortcut",
"shortcuts": {
"openWindow": {
"title": "Open/Hide Window",
"desc": "Open/Hide the main window."
},
"quickRecordText": {
"title": "Quick Record Text",
"desc": "Quickly open the main window and switch to text recording."
}
}
}
},
"record": {
"trash": {
"title": "Empty Trash",
"confirm": "Are you sure to empty the trash?",
"records": "{count} records can be restored",
"empty": "Empty",
"restoreAll": "Restore All",
"close": "Close Trash"
},
"queue": {
"ocr": "OCR recognition",
"ai": "AI content recognition",
"upload": "Upload to image host",
"jsdelivr": "Notify jsdelivr cache",
"save": "Save",
"recording": "Recording...",
"recorded": "Recorded",
"record": "Record",
"detected": "Detected"
},
"mark": {
"empty": "No records yet",
"loading": "Loading...",
"createdAt": "Created At",
"type": {
"scan": "Scan",
"image": "Image",
"screenshot": "Screenshot",
"text": "Text",
"recording": "Recording",
"file": "File",
"link": "Link",
"todo": "Todo",
"pdf": "PDF",
"upload": "Upload Record",
"download": "Download Record",
"uploadTo": "Sync from local to {provider}",
"downloadFrom": "Sync from {provider} to local"
},
"uploadSuccess": "Record upload success",
"downloadSuccess": "Record download success",
"desc": "Description",
"content": "Content",
"progress": {
"cacheImage": "Caching image",
"ocr": "OCR recognition",
"aiAnalysis": "AI content analysis",
"uploadImage": "Uploading to image host",
"jsdelivrCache": "Notifying jsdelivr cache",
"cacheFile": "Caching file",
"cacheScreenshot": "Caching screenshot",
"textAnalysis": "Text analysis",
"save": "Saving",
"saveImage": "Saving image",
"newToken": "Create access token",
"newTokenDesc": "New token must be configured with repo permission, configuration will automatically create file repository (private) and image repository."
},
"imageGallery": {
"expand": "Expand",
"collapse": "Collapse"
},
"text": {
"title": "Record Text",
"description": "Record a piece of text, which will be inserted into the appropriate position when organizing notes.",
"characterCount": "{count} characters",
"save": "Save",
"autoReadClipboard": "Auto-read clipboard text"
},
"link": {
"title": "Record Link",
"description": "Enter a webpage link, and the system will automatically crawl the page content and save it",
"save": "Save",
"autoReadClipboard": "Auto-read clipboard link"
},
"todo": {
"title": "Todo Record",
"description": "Create todo items to manage your tasks",
"titlePlaceholder": "Enter todo title...",
"descriptionPlaceholder": "Enter detailed description (optional)",
"priority": "Priority",
"priorityLow": "Low",
"priorityMedium": "Medium",
"priorityHigh": "High",
"dateRange": "Date Range",
"dateRangePlaceholder": "Select date range",
"dueDate": "Due Date",
"dueDatePlaceholder": "Select date",
"save": "Create Todo",
"saveEdit": "Save",
"edit": "Edit Todo",
"editDescription": "Modify the details of the todo item",
"cancel": "Cancel",
"selectTag": "Select Tag",
"completed": "Completed",
"uncompleted": "Uncompleted"
},
"clipboard": {
"detectedImage": "Clipboard image detected",
"detectedText": "Clipboard text detected"
},
"tag": {
"searchPlaceholder": "Create or search tags...",
"noResults": "No matching tags found",
"quickAdd": "Quick Create",
"pinned": "Pinned",
"others": "Others",
"rename": "Rename",
"delete": "Delete",
"pin": "Pin",
"unpin": "Unpin",
"newTag": "New Tag",
"newTagPlaceholder": "Enter tag name...",
"add": "Add"
},
"mark": {
"empty": "No records",
"emptyHint": "Use the toolbar at the top to create your first record!",
"type": {
"text": "Text"
},
"chat": {
"modeSelect": {
"chat": "Chat",
"agent": "Agent"
},
"agent": {
"running": "Agent Running",
"thinking": "Thinking",
"acting": "Acting",
"observation": "Observation",
"thought": "Thought",
"action": "Action",
"toolCalls": "Tool Calls",
"confirmation": {
"title": "Confirm Action",
"description": "The agent wants to perform the following action. Please confirm to continue.",
"tool": "Tool",
"parameters": "Parameters",
"cancel": "Cancel",
"confirm": "Confirm",
"confirmed": "Confirmed",
"cancelled": "Cancelled"
}
},
"placeholder": {
"default": "Ask questions or organize your notes into an article...",
"noApiKey": "API Key not configured, AI chat feature is unavailable...",
"on": "AI Suggestion On",
"off": "AI Suggestion Off"
},
"header": {
"configApiKey": "Configure API KEY",
"clearChat": "Clear Chat",
"configPrompt": "Configure Prompt",
"selectPrompt": "Select Prompt"
},
"clipboard": {
"image": {
"detected": "Image detected in clipboard:",
"recording": "Recording...",
"recorded": "Recorded",
"record": "Record"
},
"text": {
"detected": "Text detected in clipboard:",
"recorded": "Recorded",
"record": "Record"
}
},
"messageControl": {
"words": "words",
"summary": "Summary"
},
"mcp": {
"maxIterationsReached": "Maximum tool call iterations reached",
"toolCall": "MCP Server",
"params": "Parameters",
"result": "Result",
"copy": "Copy",
"paramsCopied": "Parameters copied",
"resultCopied": "Result copied",
"calling": "Calling",
"success": "Completed",
"error": "Failed"
},
"empty": {
"title": "Start AI Conversation",
"subtitle": "Use Chat or Agent mode to interact with AI",
"currentModel": "Current Model",
"currentPrompt": "Current Prompt",
"currentMode": "Conversation Mode",
"noModel": "No model set",
"noPrompt": "No prompt set",
"configureModel": "Configure Model",
"recentConversations": "Recent Conversations",
"deleteConversation": "Delete conversation",
"conversationHistory": "History",
"viewMore": "View more",
"messages": "messages",
"searchPlaceholder": "Search conversations...",
"noMatchingConversations": "No matching conversations found",
"noConversationHistory": "No conversation history",
"quickPrompts": {
"title": "Quick Start",
"writeNote": "Help me write a note",
"summarize": "Help me summarize this content",
"brainstorm": "Help me brainstorm ideas",
"explain": "Help me explain this concept"
},
"modeHint": "Click the",
"modeHintSuffix": "button on the left side of the input box to switch conversation mode"
},
"content": {
"organize": "Organize your records into an article:"
},
"note": {
"writing": "Write",
"convert": "Convert Article",
"description": "The current note is generated by AI and cannot be edited. Convert the current note to an article (generate a local file) for secondary creation in the writing page.",
"filename": "Filename",
"selectFolder": "Select folder",
"rootDirectory": "Root directory",
"deleteTag": "Delete current tag, records and notes (can be restored from trash)",
"warning": "After conversion, you will be redirected to the writing page.",
"convert_button": "Convert"
},
"mark": {
"recorded": "Recorded",
"record": "Record"
},
"send": "Send"
},
"text": {
"title": "Record Text",
"description": "Record a piece of text, which will be inserted into the appropriate position when organizing notes.",
"characterCount": "{count} characters",
"save": "Save"
},
"clipboard": {
"detectedImage": "Clipboard image detected",
"detectedText": "Clipboard text detected"
},
"tag": {
"searchPlaceholder": "Create or search tags...",
"noResults": "No matching tags found",
"quickAdd": "Quick Create",
"pinned": "Pinned",
"others": "Others",
"rename": "Rename",
"delete": "Delete",
"pin": "Pin",
"unpin": "Unpin"
},
"progress": {
"cacheImage": "Caching image",
"ocr": "OCR recognition",
"aiAnalysis": "AI content analysis",
"uploadImage": "Uploading to image host",
"jsdelivrCache": "Notifying jsdelivr cache",
"cacheFile": "Caching file",
"cacheScreenshot": "Caching screenshot",
"textAnalysis": "Text analysis",
"save": "Saving",
"saveImage": "Saving image"
}
},
"toolbar": {
"search": "Search",
"filter": {
"title": "Filter",
"description": "Instantly narrow records by content, time, and type.",
"search": "Search",
"searchPlaceholder": "Search record text, description, or link",
"type": "Type",
"time": "Time",
"tag": "Tag",
"allTags": "All tags",
"clear": "Clear filters",
"selectAllTypes": "Select all types",
"clearTypes": "Clear type selection",
"timeOptions": {
"all": "All time",
"today": "Today",
"last7Days": "Last 7 days",
"last30Days": "Last 30 days"
}
},
"trash": "Trash",
"restore": "Restore",
"delete": "Delete",
"deleteConfirm": "Are you sure to delete?",
"moveTag": "Move Tag",
"convertTo": "Convert to {type}",
"copyLink": "Copy Link",
"copied": "Copied to clipboard!",
"regenerateDesc": "Regenerate Description",
"viewFolder": "View Folder",
"viewFile": "View Original File",
"deleteForever": "Delete Forever",
"sortByName": "Sort by Name",
"sortByCreated": "Sort by Created",
"sortByModified": "Sort by Modified",
"sortAsc": "Sort Ascending",
"sortDesc": "Sort Descending",
"sort": "Sort",
"processingVectors": "Processing Vector Data",
"calculateVectors": "Calculate Document Vectors",
"multiSelect": "Multi Select",
"exitMultiSelect": "Exit Multi Select",
"organizeNotes": "Organize Notes",
"organizeSuccess": "Notes organized successfully: {title}",
"organizeError": "Failed to organize notes",
"currentTag": "Current Tag",
"text": "Record Text",
"recording": "Recording Record",
"scan": "Scan Image",
"image": "Upload Image",
"link": "Record Link",
"file": "Upload File",
"todo": "Todo Record",
"closeTrash": "Close Trash",
"selectAll": "Select All",
"deselectAll": "Deselect All",
"selectedCount": "{count} items selected",
"visibleCount": "{count} records",
"moveSelectedTags": "Move selected {count} items",
"deleteSelected": "Delete selected {count} items",
"deleteSelectedForever": "Permanently delete selected {count} items",
"view": {
"list": "List view",
"compact": "Compact view",
"cards": "Card view"
}
},
"list": {
"title": "Records",
"emptyFiltered": "No matching records",
"emptyFilteredHint": "Try adjusting the search or filters",
"filteredLabel": "{count} filtered",
"filtered": "Filtered",
"filteredByTag": "tag",
"filteredByType": "{count} types",
"filteredSummary": "Showing {count} results · {filters}",
"searchChip": "Search: {value}",
"time": {
"today": "Today",
"last7Days": "Last 7 days",
"last30Days": "Last 30 days"
}
},
"note": {
"organizeAs": "Organize as",
"template": "Template",
"setting": "Settings",
"confirm": "确认",
"cancel": "取消",
"removeThinking": "移除思考过程",
"stop": "Stop"
}
},
"chat": {
"condensing": "Condensing context...",
"condensed": {
"message": "Condensed {count} historical messages"
},
"empty": {
"features": [
{
"chat": "Chat with AI bot"
},
{
"linked": "Linked with your records or notes"
},
{
"clipboard": "Recognize clipboard records or images"
},
{
"organize": "Organize your records into notes"
}
],
"title": "Start chatting with AI",
"subtitle": "Interact with AI using Chat or Agent mode",
"currentModel": "Current Model",
"currentPrompt": "Current Prompt",
"currentMode": "Conversation Mode",
"noModel": "No model set",
"noPrompt": "No prompt set",
"configureModel": "Configure Model",
"recentConversations": "Recent Conversations",
"deleteConversation": "Delete Conversation",
"conversationHistory": "History",
"viewMore": "View More",
"messages": "messages",
"searchPlaceholder": "Search conversations...",
"noMatchingConversations": "No matching conversations found",
"noConversationHistory": "No conversation history yet",
"quickPrompts": {
"title": "快速开始",
"writeNote": "帮我写一篇笔记",
"summarize": "帮我总结这段内容",
"brainstorm": "帮我头脑风暴一些想法",
"explain": "帮我解释这个概念"
}
},
"newChat": "New Chat with New Tag",
"removeChat": "Remove Chat with Current Tag",
"confirmNew": "Create New Tag",
"confirmNewDescription": "Are you sure you want to create a new tag to start a conversation?",
"confirmRemove": "Delete Tag",
"confirmRemoveDescription": "Please note that deleting this tag will also delete all records within it. Please confirm again.",
"content": {
"organize": "Organize your records into an article:"
},
"quote": {
"lineSingle": "Quoted from {fileName} line {line}",
"lineRange": "Quoted from {fileName} lines {startLine}-{endLine}",
"noLine": "Quoted from {fileName}"
},
"note": {
"organize": "Organize",
"writing": "Write",
"convert": "Convert Article",
"description": "The current note is generated by AI and cannot be edited. Convert the current note to an article (generate a local file) for secondary creation in the writing page.",
"filename": "Filename",
"selectFolder": "Select folder",
"rootDirectory": "Root directory",
"deleteTag": "Delete current tag, records and notes (can be restored from trash)",
"warning": "After conversion, you will be redirected to the writing page.",
"convert_button": "Convert",
"organizeAs": "Organize your records into an article:",
"templateContent": "Template content",
"recordRange": "Record range",
"filterThinkingContent": "Remove thinking content from records",
"startOrganize": "Start organizing",
"manageTemplate": "Manage template",
"cancel": "Cancel",
"stop": "Stop"
},
"mark": {
"recorded": "Recorded",
"record": "Record"
},
"input": {
"organize": "Organize",
"chat": "Chat",
"placeholder": {
"default": "Type a message...",
"noApiKey": "No API Key configured, can't use AI chat...",
"on": "AI suggestions on",
"off": "AI suggestions off",
"noPrimaryModel": "No primary model configured, can't use AI chat..."
},
"translate": {
"tooltip": "Translate",
"translating": "Translating...",
"showOriginal": "Show Original",
"alreadyTranslated": "Translated to"
},
"clipboardMonitor": {
"enable": "Clipboard monitoring (on)",
"disable": "Clipboard monitoring (off)"
},
"send": "Send",
"stop": "Stop",
"stopped": "Conversation stopped",
"terminate": "Terminate",
"tagLink": {
"on": "Linked to tag",
"off": "Not linked to tag"
},
"modelSelect": {
"tooltip": "Select AI model",
"placeholder": "Search AI models",
"noModel": "No model found"
},
"promptSelect": {
"tooltip": "Select prompt",
"placeholder": "Search prompts"
},
"newChat": "New Chat",
"mcp": {
"tooltip": "MCP server"
},
"chatLanguage": {
"tooltip": "Select chat language",
"placeholder": "Search language"
},
"rag": {
"notSupported": "Vector model is not supported",
"enabled": "Knowledge Base Search (Enabled)",
"disabled": "Knowledge Base Search (Disabled)"
},
"modeSelect": {
"tooltip": "Select input mode",
"chat": "Chat mode",
"gen": "Organize mode",
"translate": "Translate mode"
},
"chatModeSelect": {
"chatDescription": "Quick conversation, analysis-first",
"agentDescription": "Smart assistant, can execute actions"
},
"attachImage": "Attach images",
"imageSelector": {
"title": "Select Images",
"local": "Local Files",
"records": "From Records",
"selectFiles": "Select Local Images",
"noRecords": "No image records available",
"cancel": "Cancel",
"confirm": "Confirm"
},
"agent": {
"running": "Agent Running",
"thinking": "Thinking",
"analyzingRequest": "Agent is analyzing your request...",
"acting": "Acting",
"observation": "Observation",
"thought": "Thought",
"action": "Action",
"toolCalls": "Tool Calls",
"autoFinal": {
"createNote": "Created note \"{name}\".",
"createFile": "Created file \"{name}\"."
},
"confirmation": {
"title": "Confirm Action",
"description": "The agent wants to perform the following action. Please confirm to continue.",
"tool": "Tool",
"parameters": "Parameters",
"cancel": "Cancel",
"confirm": "Confirm",
"confirmed": "Confirmed",
"cancelled": "Cancelled",
"fallback": {
"title": "Review action",
"description": "Please confirm the target and content of this action."
},
"params": {
"filePath": "File path",
"content": "File content",
"sourcePath": "Source path",
"targetPath": "Target path",
"files": "Files",
"newName": "New name",
"scriptName": "Script name",
"command": "Command"
},
"tools": {
"create_file": {
"title": "Create file",
"description": "A new file will be created in the workspace."
},
"create_files_batch": {
"title": "Create files",
"description": "Multiple new files will be created in the workspace."
},
"rename_file": {
"title": "Rename file",
"description": "The selected file will be renamed."
},
"move_file": {
"title": "Move file",
"description": "The file will be moved to a new location."
},
"copy_file": {
"title": "Copy file",
"description": "A copy of the file will be created at the target location."
},
"replace_editor_content": {
"title": "Replace editor content",
"description": "The current editor content will be replaced."
},
"insert_at_cursor": {
"title": "Insert at cursor",
"description": "Content will be inserted at the current cursor position."
},
"delete_markdown_file": {
"title": "Delete file",
"description": "The selected file will be permanently deleted."
},
"execute_skill_script": {
"title": "Run script",
"description": "A skill-provided script or command will be executed."
}
}
}
},
"fileLink": {
"tooltip": "Link File",
"selectFile": "Select File",
"linkedFile": "Linked File",
"searchPlaceholder": "Search files...",
"noFiles": "No files found",
"loading": "Loading..."
}
},
"header": {
"configApiKey": "Configure API KEY",
"clearChat": "Clear Chat",
"selectPrompt": "Select Prompt",
"noModel": "AI model not selected",
"configPrompt": "Configure Prompt"
},
"clipboard": {
"image": {
"detected": "Image detected in clipboard:",
"recording": "Recording...",
"recorded": "Recorded",
"record": "Record"
},
"text": {
"detected": "Text detected in clipboard:",
"recorded": "Recorded",
"record": "Record"
}
},
"messageControl": {
"words": "words",
"summary": "Summary",
"readAloud": "Read Aloud",
"playing": "Playing",
"loading": "Loading",
"stop": "Stop Playing",
"copy": "Copy",
"copied": "Copied"
},
"ragSources": {
"label": "Found {count} notes in knowledge base",
"openFile": "Open file"
},
"preview": {
"close": "Close",
"copy": "Copy",
"copied": "Copied!"
},
"control": {
"edit": "Edit",
"save": "Save",
"cancel": "Cancel",
"delete": "Delete",
"deleteConfirm": "Are you sure to delete this message?"
}
},
"tag": {
"add": "Add Tag",
"edit": "Edit Tag",
"delete": "Delete Tag",
"deleteConfirm": "Are you sure to delete this tag?",
"placeholder": "Enter tag name"
}
},
"search": {
"placeholder": "Search notes and articles...",
"results": "{count} search results",
"noResults": "No search results",
"tryDifferentKeywords": "Try using different keywords",
"mode": {
"fuzzy": "Fuzzy",
"exact": "Exact"
},
"item": {
"record": "Record",
"article": "Article",
"matches": "{count} matches",
"scanType": "scan"
}
},
"image": {
"root": "Image Repository",
"noData": {
"title": "Sync feature not enabled",
"desc": "Please go to the system settings page to configure Github sync.",
"goToSettings": "Go to Settings",
"howToUse": "How to use sync feature?"
}
},
"navigation": {
"chat": "Chat",
"record": "Record",
"quickRecord": "Quick Record",
"write": "Write",
"search": "Search",
"githubImageHosting": "Github Image Hosting",
"login": "Login",
"loading": "Loading",
"view": "View",
"logout": "Logout",
"setting": "Settings",
"activity": "Activity",
"files": "Notes",
"outline": "Outline",
"showLeftSidebar": "Show Left Sidebar",
"hideLeftSidebar": "Hide Left Sidebar",
"showCenterPanel": "Show Editor",
"hideCenterPanel": "Hide Editor",
"showRightSidebar": "Show Right Sidebar",
"hideRightSidebar": "Hide Right Sidebar",
"searchPlaceholder": "Search notes or records..."
},
"activity": {
"title": "Activity Calendar",
"description": "Review your daily records, chats, and writing activity in one place. This first version is derived from existing records, user chats, and note modification times.",
"drawer": {
"title": "Activity",
"description": "Quickly review today's status and your recent activity trend.",
"today": "Today"
},
"loading": "Loading activity data...",
"empty": "No activity data yet",
"refresh": "Refresh",
"summary": {
"totalCount": "Total Activity",
"activeDays": "Active Days",
"records": "Records",
"chats": "Chats",
"writing": "Writing"
},
"labels": {
"record": "Record",
"writing": "Writing",
"chat": "Chat"
},
"heatmap": {
"title": "Last 26 Weeks",
"range": "{startDate} - {endDate}",
"less": "Less",
"more": "More",
"dayCount": "activities",
"emptyDay": "No activity"
},
"detail": {
"title": "Day Details",
"empty": "Select a day to inspect its activity details."
}
},
"marks": {
"types": {
"screenshot": "Screenshot",
"text": "Text",
"image": "Image"
}
},
"tags": {
"inspiration": "Inspiration"
},
"sync": {
"status": "Sync Repository Status",
"imageRepo": "Image Repository",
"articleRepo": "Article Repository"
},
"ai": {
"thinking": "Thinking",
"error": {
"title": "AI Error",
"noAddress": "Please set AI address first"
}
},
"article": {
"sync": {
"syncingRemote": "Pulling remote file...",
"syncComplete": "Sync Complete",
"pullingRemote": "Fetching latest content from remote server..."
},
"syncConfirm": {
"title": "Remote File Update Detected",
"description": "File {fileName} has remote updates",
"commitInfo": "Latest Commit Info",
"commitMessage": "Commit Message",
"author": "Author",
"changes": "Changes",
"confirmMessage": "Are you sure you want to pull the remote version and overwrite the local file? This action cannot be undone.",
"cancel": "Cancel",
"confirmPull": "Confirm Pull"
},
"emptyState": {
"title": "Start Creating",
"subtitle": "Select a file to start editing, or create a new note",
"tip": "💡 Tip: You can also select files from the left sidebar",
"actions": {
"newNote": {
"title": "Create Note",
"desc": "Create a new Markdown note"
},
"newRecord": {
"title": "Create Record",
"desc": "Open text recording feature"
},
"globalSearch": {
"title": "Global Search",
"desc": "Quickly find your note content"
},
"openWorkspace": {
"title": "Open Workspace",
"desc": "Select or switch workspace directory"
}
},
"onboarding": {
"title": "Onboarding",
"subtitle": "Walk through these three tasks to learn the core NoteGen flow.",
"dismiss": "Skip onboarding",
"reopen": "Show onboarding again",
"start": "Start",
"viewHint": "Show hint",
"continue": "Continue",
"completed": "Done",
"allDone": "All getting-started tasks are complete. You've already tried the core NoteGen workflow.",
"stepLabel": "Task ({current}/{total})",
"stepCompletedLabel": "Completed Task ({current}/{total})",
"afterOrganizeDialog": {
"title": "Completed Task (2/3)",
"description": "You've turned the record into a note. Do you want to continue and use the AI Agent to turn this note into a bilingual version?",
"confirm": "Continue",
"cancel": "Not now"
},
"agentPrompt": {
"label": "Sample Prompt",
"use": "Use This Prompt",
"intro": "Please directly revise the note I just organized into a bilingual Chinese-English version.",
"requirement1": "",
"requirement2": "",
"requirement3": "",
"requirement4": "",
"outro": ""
},
"steps": {
"createRecord": {
"title": "Create your first record",
"desc": "Save a sample record and learn where quick capture lives."
},
"organizeNote": {
"title": "Organize it into a note",
"desc": "Turn that record into a structured note."
},
"aiPolish": {
"title": "Use Agent for bilingual translation",
"desc": "Use the AI Agent to turn the note you just organized into a bilingual version."
}
},
"completedStates": {
"create-record": {
"title": "Your first record is saved",
"desc": "You now know where quick capture lives."
},
"organize-note": {
"title": "Your record is now a note",
"desc": "Next, try using AI to revise the note."
},
"ai-polish": {
"title": "You used the Agent on the note",
"desc": "You've completed the flow from capture to note organization to Agent-assisted processing."
}
},
"spotlight": {
"create-record": {
"title": "This is the quick record entry",
"desc": "Click here to open text capture. We'll preload a sample record so you can save it right away."
},
"organize-note": {
"title": "This button organizes records into a note",
"desc": "Use it to turn your captured record into a full Markdown note."
},
"ai-polish": {
"title": "Use the Agent on the note you just created here",
"desc": "Insert the sample prompt into chat and send it. The Agent will generate a bilingual version based on the current note."
}
}
}
},
"unsupportedFile": {
"title": "Cannot Preview This File",
"fileName": "File Name",
"filePath": "File Path",
"fileSize": "File Size",
"modifiedTime": "Modified Time",
"createdTime": "Created Time",
"pathCopied": "Path copied",
"openExternal": "Open with External App",
"openDirectory": "Open File Directory"
},
"file": {
"toolbar": {
"accessRepo": "Access Repository",
"loadingSync": "Loading sync info",
"configSync": "Configure Sync",
"newArticle": "New Article",
"newFolder": "New Folder",
"refresh": "Refresh",
"toggleFolders": "Toggle Folders",
"expandAll": "Expand All",
"collapseAll": "Collapse All",
"sortByName": "Sort by Name",
"sortByCreated": "Sort by Created",
"sortByModified": "Sort by Modified",
"sortAsc": "Sort Ascending",
"sortDesc": "Sort Descending",
"sort": "Sort",
"hideCloudFiles": "Hide Cloud Files",
"showCloudFiles": "Show Cloud Files",
"processingVectors": "Processing Vector Data",
"calculateVectors": "Knowledge Base Calculation (Full)",
"importMarkdown": "Import",
"importing": "Importing...",
"importSuccess": "Import Successful",
"importSuccessDesc": "Successfully imported {count} files",
"importError": "Import Failed"
},
"sync": {
"syncingRemote": "Pulling remote file...",
"syncComplete": "Sync Complete",
"pullingRemote": "Fetching latest content from remote server...",
"pullComplete": "Pull Complete"
},
"context": {
"viewDirectory": "View Directory",
"cut": "Cut",
"copy": "Copy",
"paste": "Paste",
"rename": "Rename",
"deleteSyncFile": "Delete Sync File",
"deleteLocalFile": "Delete Local File",
"delete": "Delete",
"confirmDelete": "Are you sure you want to delete the folder \"{name}\"? This will delete the folder and all its contents.",
"deleteSuccess": "Deleted successfully",
"deleteFailed": "Delete failed",
"newFile": "New File",
"newFolder": "New Folder",
"syncFolder": "Sync Folder",
"syncFolderDesc": "Sync all Markdown files in the current folder",
"syncFolderSuccess": "Sync folder success",
"syncFolderError": "Sync folder error",
"syncFolderProgress": "Syncing folder...",
"deleteSyncFileSuccess": "Delete Sync File Success",
"deleteSyncFileError": "Delete Sync File Error",
"knowledgeBase": "Knowledge Base",
"calculateVectors": "Calculate Vectors",
"updateVectors": "Update Vectors",
"deleteVectors": "Delete Vectors",
"includeInKB": "Include in Knowledge Base",
"includeInKBFile": "Include in Knowledge Base",
"autoVectorCalc": "Auto Vector Calculation",
"vectorCalculated": "Vector Updated",
"vectorCalcCompleted": "Vector Calculation Completed",
"vectorCalcFailed": "Vector Calculation Failed",
"vectorDeleted": "Vector Deleted",
"vectorDeleteFailed": "Delete Vector Failed",
"batchCalcSuccess": "Successfully calculated vectors for {count} files",
"batchCalcPartial": "Calculation completed: {success} succeeded, {failed} failed",
"batchCalcFailed": "Batch vector calculation failed",
"batchDeleteSuccess": "Successfully deleted vectors for {count} files",
"batchDeletePartial": "Deletion completed: {success} succeeded, {failed} failed",
"batchDeleteFailed": "Batch vector deletion failed",
"noMarkdownFiles": "No Markdown files in folder",
"includedInKB": "Included in Knowledge Base",
"excludedFromKB": "Excluded from Knowledge Base",
"autoCalcEnabled": "Auto vector calculation enabled",
"autoCalcDisabled": "Auto vector calculation disabled",
"settingFailed": "Setting failed",
"confirmDeleteVectors": "Are you sure you want to delete vectors for {count} files?"
},
"folderView": {
"vectorDbNotEnabled": "Vector database not enabled",
"calculateVectors": "Calculate Vectors",
"indexed": "Indexed",
"vectorCount": "Vector Count",
"databaseSize": "Database Size",
"lastCalculated": "Last Calculated",
"never": "Never",
"calculating": "Calculating...",
"failed": "Failed",
"recalculateVectors": "Recalculate Vectors",
"skills": "Skills",
"skillNotFound": "Skill Not Found",
"skillNotFoundDesc": "Cannot find Skill with ID {id}",
"loadingSkills": "Loading Skills...",
"loadingSkill": "Loading Skill...",
"globalSkills": "Global Skills",
"workspaceSkills": "Workspace Skills",
"instructions": "Instructions",
"examples": "Examples",
"scripts": "Scripts",
"references": "References",
"assets": "Assets"
},
"error": {
"fileExists": "File name already exists"
},
"clipboard": {
"copied": "Copied to clipboard",
"cut": "Cut to clipboard",
"pasted": "Pasted successfully",
"pasteFailed": "Paste operation failed",
"empty": "Clipboard is empty",
"confirmOverwrite": "File already exists, do you want to overwrite it?",
"mark": {
"title": "Records",
"tooltip": "Use Records",
"description": "Convert records into content to insert into the article.",
"noRecords": "No records",
"ocrNoContent": "OCR did not recognize any content"
},
"question": {
"tooltip": "Q&A",
"selectContent": "Please select content first",
"promptTemplate": "Reference text: \n{content}\nBased on the question: \n{question}\n, directly provide the answer content."
},
"continue": {
"tooltip": "Continue",
"promptTemplate": "Based on the preceding text: \n{content}\n continue writing and return content not exceeding 100 words.\nYou can reference the following text: \n{endContent}\n, but avoid duplicating its content."
},
"polish": {
"tooltip": "Polish",
"selectContent": "Please select content first",
"promptTemplate": "Polish this text: \n{content}\n, keep the language unchanged, fix typos and grammatical errors, directly return the polished result."
},
"eraser": {
"tooltip": "Simplify",
"selectContent": "Please select content first",
"promptTemplate": "Simplify this text: \n{content}\n, this text is too verbose, reduce the word count by at least half, keep the language unchanged, directly return the optimized result."
},
"expansion": {
"tooltip": "Expand",
"selectContent": "Please select content first",
"promptTemplate": "Expand this text: \n{content}\n, this text is too short, increase the word count by at least half, keep the language unchanged, directly return the expanded result."
},
"translation": {
"tooltip": "Translate",
"description": "Translate the selected text",
"selectContent": "Please select content first",
"promptTemplate": "Translate this text: \n{content}\n, into {language}, directly return the translated result."
},
"notSupported": "Operation not supported"
},
"mobile": {
"cancel": "Cancel",
"create": "Create",
"save": "Save",
"emptyDir": "This folder is empty",
"root": "Root",
"openFiles": "Open files",
"remote": "Remote file",
"remoteFileNotPulled": "Cloud only · Tap to pull",
"remoteFolderOnly": "Cloud-only folder",
"file": "File",
"folder": "Folder",
"folderChildren": "{files} files · {folders} folders",
"filePlaceholder": "example.md",
"folderPlaceholder": "example-folder"
},
"deleteConfirm": "Are you sure you want to delete this file?"
},
"editor": {
"copySuccess": "Copy Success",
"copySuccessDescription": "Copied to clipboard",
"search": {
"placeholder": "Find in document",
"replacePlaceholder": "Replace with",
"caseSensitive": "Case sensitive",
"replace": "Replace",
"replaceAll": "Replace all",
"findPrev": "Previous",
"findNext": "Next"
},
"floatbar": {
"quote": {
"tooltip": "Quote"
},
"readAloud": {
"start": "Read Aloud",
"stop": "Stop Reading",
"loading": "Loading..."
}
},
"toolbar": {
"organize": {
"tooltip": "Organize Notes"
},
"mark": {
"title": "Records",
"tooltip": "Records",
"description": "Convert records into content to insert into the article.",
"noRecords": "No records",
"ocrNoContent": "OCR did not recognize any content"
},
"question": {
"tooltip": "Q&A",
"selectContent": "Please select content first",
"promptTemplate": "Reference text: \n{content}\nBased on the question: \n{question}\n, directly provide the answer content."
},
"continue": {
"tooltip": "Continue",
"promptTemplate": "Based on the preceding text: \n{content}\n continue writing and return content not exceeding 100 words.\nYou can reference the following text: \n{endContent}\n, but avoid duplicating its content."
},
"polish": {
"tooltip": "Polish",
"selectContent": "Please select content first",
"promptTemplate": "Polish this text: \n{content}\n, keep the language unchanged, fix typos and grammatical errors, directly return the polished result."
},
"eraser": {
"tooltip": "Simplify",
"selectContent": "Please select content first",
"promptTemplate": "Simplify this text: \n{content}\n, this text is too verbose, reduce the word count by at least half, keep the language unchanged, directly return the optimized result."
},
"expansion": {
"tooltip": "Expand",
"selectContent": "Please select content first",
"promptTemplate": "Expand this text: \n{content}\n, this text is too short, increase the word count by at least half, keep the language unchanged, directly return the expanded result."
},
"translation": {
"tooltip": "Translate",
"description": "Translate the selected text",
"selectContent": "Please select content first",
"promptTemplate": "Translate this text: \n{content}\n, into {language}, directly return the translated result.",
"fail": "Translation failed",
"failNoSelection": "Please select text to translate",
"translating": "Translating",
"translatingTo": "Translating to {language}...",
"success": "Translation complete",
"successTo": "Translated to {language}",
"customLanguage": "Custom language...",
"customLanguagePlaceholder": "Enter target language, e.g., English, Japanese, etc.",
"customLanguageEmpty": "Please enter target language",
"customLanguageExample": "e.g., English, Japanese, French, etc."
}
},
"upload": {
"error": "Upload failed",
"needToken": "Upload images need to configure accessToken",
"uploading": "Uploading image"
},
"saveDialog": {
"title": "Save File",
"emptyContent": "Empty Content",
"emptyContentDesc": "Please enter content before saving",
"success": "Save Successful",
"successDesc": "File saved successfully",
"error": "Save Failed",
"errorDesc": "Failed to save file, please try again"
}
},
"footer": {
"wordCount": "Word Count",
"pull": {
"pull": "Pull",
"checking": "Checking for updates...",
"noUpdate": "No remote updates",
"clickToPull": "Click to pull remote updates",
"pullSuccess": "Pull Successful",
"pullFailed": "Pull Failed",
"ignored": "Ignored",
"ignoreUpdate": "Ignore This Update"
},
"sync": {
"push": "Push",
"pushed": "Pushed",
"syncing": "Pushing",
"syncFailed": "Push Failed",
"checkNetworkOrToken": "Please check network connection or token",
"quickSync": "Quick Sync"
},
"history": {
"loadingHistory": "Loading history",
"historyRecords": "History Records",
"noHistory": "No History",
"loading": "Loading",
"recordsCount": "records",
"filterQuickSync": "Filter Quick Syncs",
"committedAt": "committed at",
"pull": "Pull",
"quickSync": "Quick Sync"
},
"vectorCalc": {
"tooltip": {
"default": "Vector Index Status",
"none": "Click to start vector calculation",
"indexed": "Indexed",
"pending": "Pending update, click to calculate now",
"calculating": "Calculating..."
},
"status": {
"calculating": "Calculating"
}
}
}
},
"mobile": {
"chat": {
"drawer": {
"settings": {
"title": "Chat Settings"
},
"tools": {
"title": "Tools",
"newChat": "New Chat",
"start": "Start"
},
"attachments": {
"title": "Attachments",
"gallery": "Gallery",
"camera": "Camera",
"file": "File",
"linkNote": "Link Note"
}
}
}
},
"mcp": {
"selectServers": "MCP Servers",
"searchServers": "Search servers...",
"noServers": "MCP service not enabled",
"noServersFound": "No matching servers found",
"addServer": "Add server...",
"goToSettings": "Go to Settings",
"close": "Close",
"navigate": "Select",
"confirm": "Confirm",
"tools": "tools",
"connecting": "Connecting",
"disconnected": "Disconnected"
},
"recording": {
"title": "Voice Recording",
"description": "Click the microphone button to start recording, the system will automatically recognize and convert to text",
"recording": "Recording",
"paused": "Paused",
"ready": "Ready",
"processing": "Processing...",
"cancel": "Cancel",
"error": "Error",
"success": "Success",
"noModelConfigured": "Speech recognition model not configured, please configure in settings first",
"speechUnavailable": "The current speech recognition mode is unavailable. Check local speech support or model configuration.",
"fallbackToModel": "Local speech recognition is unavailable, so the app switched to model transcription automatically.",
"startError": "Unable to start recording",
"noAudioData": "No audio data recorded",
"transcriptionSuccess": "Speech recognition completed",
"transcriptionEmpty": "Recognition result is empty",
"transcriptionError": "Speech recognition failed",
"configureModel": "Configure model",
"retryTranscription": "Retry transcription",
"retrying": "Retrying...",
"retrySuccess": "Transcription updated",
"retryError": "Retry transcription failed",
"noContentDetected": "No content detected",
"doubleClickToSelectFile": "Double click to select audio file",
"mode": {
"builtin": "Browser Recognition",
"builtinDesc": "Free, real-time recognition",
"model": "AI Model Recognition",
"modelDesc": "Requires STT model, more accurate"
}
},
"footer": {
"wordCount": "Words",
"sync": {
"sync": "Sync",
"synced": "Synced",
"syncing": "Syncing",
"syncFailed": "Sync Failed",
"checkNetworkOrToken": "Please check network connection or token",
"quickSync": "Quick Sync"
},
"history": {
"loadingHistory": "Loading history",
"historyRecords": "History Records",
"noHistory": "No History",
"loading": "Loading",
"recordsCount": "records",
"filterQuickSync": "Filter Quick Syncs",
"committedAt": "committed at",
"pull": "Pull",
"quickSync": "Quick Sync"
},
"vectorCalc": {
"tooltip": "Vector Calculation: Auto-calculate 30s after editing, or click to calculate now",
"calculating": "Calculating",
"pending": "Pending {progress}%",
"synced": "Synced"
}
},
"quickRecord": {
"description": "Click to select a recording tool and quickly create records"
},
"editor": {
"placeholder": "Type / to open menu, or start writing...",
"outline": {
"title": "Outline",
"open": "Open Outline",
"close": "Close Outline"
},
"translation": {
"fail": "Translation failed",
"failNoSelection": "Please select text to translate",
"translating": "Translating...",
"translatingTo": "Translating to {language}...",
"success": "Translation complete",
"successTo": "Translated to {language}",
"customLanguageEmpty": "Please enter target language",
"customLanguageExample": "e.g., English, Japanese, French, etc."
},
"quoteDisplay": {
"fromFile": "Quoted from {fileName}",
"line": "Quoted from {fileName} line {line}",
"lines": "Quoted from {fileName} lines {start}-{end}"
},
"bubbleMenu": {
"ai": "AI",
"polish": "Polish",
"concise": "Concise",
"expand": "Expand",
"translate": "Translate",
"translateSubtitle": "Translate to",
"quoteToChat": "Quote to Chat",
"link": "Link",
"linkPlaceholder": "Enter link URL",
"confirm": "Confirm",
"cancel": "Cancel",
"bold": "Bold",
"italic": "Italic",
"strike": "Strikethrough",
"underline": "Underline",
"inlineCode": "Inline Code",
"highlight": "Highlight",
"blockquote": "Quote",
"bulletList": "Bullet List",
"orderedList": "Numbered List",
"taskList": "Task List",
"codeBlock": "Code Block",
"languages": {
"English": "English",
"Japanese": "Japanese",
"Korean": "Korean",
"French": "French",
"German": "German",
"Spanish": "Spanish",
"Portuguese": "Portuguese",
"Russian": "Russian",
"Arabic": "Arabic"
},
"customLanguagePlaceholder": "Custom language..."
},
"aiSuggestion": {
"accept": "Accept",
"reject": "Reject",
"generating": "Generating...",
"abort": "Abort"
},
"image": {
"insert": "Insert Image",
"uploading": "Uploading...",
"uploadSuccess": "Image uploaded to image hosting",
"saveSuccess": "Image saved locally",
"uploadFailed": "Failed to insert image",
"sizeSmall": "Small (25%)",
"sizeMedium": "Medium (50%)",
"sizeLarge": "Large (75%)",
"sizeOriginal": "Original Size",
"editAlt": "Edit Alt Text",
"editSrc": "Edit URL",
"altPlaceholder": "Enter alt text...",
"srcPlaceholder": "Enter image URL...",
"delete": "Delete Image",
"confirm": "Confirm",
"cancel": "Cancel"
},
"mermaid": {
"rendering": "Rendering...",
"renderError": "Render error",
"clickToEdit": "Click to edit source",
"clickToAdd": "Click to add diagram",
"placeholder": "Enter Mermaid diagram code...",
"preview": "Preview",
"done": "Done",
"diagramTypes": {
"flowchart": "Flowchart",
"sequence": "Sequence",
"classDiagram": "Class Diagram",
"stateDiagram": "State Diagram",
"er": "ER Diagram",
"gantt": "Gantt",
"pie": "Pie Chart",
"journey": "Journey"
},
"templates": {
"flowchart": "graph TD\n A[Start] --> B[Process]\n B --> C[End]",
"sequence": "sequenceDiagram\n participant Alice\n participant Bob\n Alice->>Bob: Hello\n Bob-->>Alice: Reply",
"classDiagram": "classDiagram\n Animal <|-- Duck\n Animal <|-- Fish\n Animal : +int age\n Animal : +String gender",
"stateDiagram": "stateDiagram-v2\n [*] --> Active\n Active --> [*]",
"er": "erDiagram\n CUSTOMER ||--o{ ORDER : places\n CUSTOMER ||--o{ DELIVERY-ADDRESS : uses",
"gantt": "gantt\n title Project Plan\n dateFormat YYYY-MM-DD\n section Phase 1\n Task1 :a1, 2024-01-01, 30d\n section Phase 2\n Task2 :after a1, 20d",
"pie": "pie title Resource Allocation\n \"CPU\" : 45\n \"Memory\" : 30\n \"Storage\" : 25",
"journey": "journey\n title My Daily Work\n section Morning\n Commute : 7:00, 5\n Work : 9:00, 8"
}
},
"slashCommand": {
"groups": {
"ai": "AI",
"heading": "Heading",
"list": "List",
"block": "Block",
"align": "Align",
"embed": "Embed",
"math": "Math",
"chart": "Chart"
},
"items": {
"continue": "Continue",
"continueDesc": "AI continue writing content",
"heading1": "Heading 1",
"heading1Desc": "Large heading",
"heading2": "Heading 2",
"heading2Desc": "Medium heading",
"heading3": "Heading 3",
"heading3Desc": "Small heading",
"bulletList": "Bullet List",
"bulletListDesc": "Create a simple bullet list",
"orderedList": "Ordered List",
"orderedListDesc": "Create a numbered list",
"taskList": "Task List",
"taskListDesc": "Create a checklist with checkboxes",
"image": "Image",
"imageDesc": "Insert local or hosted image",
"table": "Table",
"tableDesc": "Insert a table",
"blockquote": "Quote",
"blockquoteDesc": "Capture quoted content",
"codeBlock": "Code Block",
"codeBlockDesc": "Capture code snippets",
"divider": "Divider",
"dividerDesc": "Create a horizontal divider",
"inlineMath": "Inline Math",
"inlineMathDesc": "Insert inline LaTeX formula",
"blockMath": "Block Math",
"blockMathDesc": "Insert block LaTeX formula",
"flowchart": "Flowchart",
"flowchartDesc": "Insert a flowchart",
"sequence": "Sequence Diagram",
"sequenceDesc": "Insert a sequence diagram",
"gantt": "Gantt Chart",
"ganttDesc": "Insert a Gantt chart",
"classDiagram": "Class Diagram",
"classDiagramDesc": "Insert a class diagram",
"stateDiagram": "State Diagram",
"stateDiagramDesc": "Insert a state diagram",
"pie": "Pie Chart",
"pieDesc": "Insert a pie chart",
"erDiagram": "ER Diagram",
"erDiagramDesc": "Insert an entity relationship diagram",
"journey": "Journey Map",
"journeyDesc": "Insert a user journey map"
},
"imageUpload": {
"success": "Upload successful",
"saveSuccess": "Save successful",
"savePath": "Saved to: {path}",
"failed": "Failed to insert image"
}
}
},
"tabContext": {
"close": "Close",
"closeOthers": "Close Others",
"closeAll": "Close All",
"closeLeft": "Close Left",
"closeRight": "Close Right"
}
}
================================================
FILE: messages/ja.json
================================================
{
"app": {
"title": "ノート生成ツール",
"description": "あなたのAI搭載ノートアシスタント"
},
"common": {
"save": "保存",
"cancel": "キャンセル",
"delete": "削除",
"confirm": "確認",
"edit": "編集",
"create": "作成",
"theme": "テーマ",
"light": "ライトモード",
"dark": "ダークモード",
"system": "システム設定に従う",
"pin": "ピン留め",
"unpin": "ピン留めを解除",
"settings": "設定",
"back": "戻る",
"sync": "同期",
"language": "言語",
"success": "成功",
"error": "失敗",
"defaultFileName": "無題のドキュメント",
"restartToApply": "、設定を有効にするにはアプリケーションを再起動してください",
"close": "閉じる",
"open": "開く",
"add": "追加",
"remove": "削除",
"search": "検索",
"filter": "フィルター",
"sort": "並べ替え",
"export": "エクスポート",
"import": "インポート",
"refresh": "更新",
"loading": "読み込み中...",
"warning": "警告",
"info": "情報",
"unsaved": "未保存",
"saving": "保存中...",
"configureSync": "同期を構成"
},
"settings": {
"defaultModels": {
"title": "デフォルトモデル"
},
"others": "その他",
"general": {
"title": "一般設定",
"desc": "ここでは、アプリケーションの基本設定を構成できます。インターフェースのテーマ、言語などのオプションが含まれます。",
"interface": {
"title": "インターフェース設定",
"theme": {
"title": "テーマ",
"desc": "アプリケーションの外観テーマを選択",
"options": {
"light": "ライトモード",
"dark": "ダークモード",
"system": "システム設定に従う"
}
},
"language": {
"title": "言語",
"desc": "アプリケーションの表示言語を選択"
},
"scale": {
"title": "インターフェーススケール",
"desc": "アプリケーションインターフェースの全体的なスケールを調整",
"placeholder": "スケール比率を選択"
},
"contentTextScale": {
"title": "本文スケール",
"desc": "エディターとチャットの Markdown コンテンツのテキストサイズを調整"
},
"fileManagerTextSize": {
"title": "ファイルマネージャーのテキストサイズ",
"desc": "ファイルマネージャーのファイルとフォルダーリストのテキストサイズを調整"
},
"recordTextSize": {
"title": "記録のテキストサイズ",
"desc": "記録リストの記録項目のテキストサイズを調整"
},
"customCss": {
"title": "カスタム CSS",
"desc": "カスタム CSS スタイルを追加してアプリケーションのデフォルトスタイルを上書き",
"button": "CSS を編集",
"dialogTitle": "カスタム CSS",
"dialogDesc": "以下にカスタム CSS コードを入力して、アプリケーションのデフォルトスタイルを上書きします。保存をクリックして変更を適用します。",
"placeholder": "ここにカスタム CSS コードを入力",
"save": "保存",
"cancel": "キャンセル"
},
"tray": {
"enabled": {
"title": "トレイを有効にする",
"desc": "ウィンドウを閉じる時にトレイに最小化するかアプリを終了するか選択"
}
},
"customTheme": {
"title": "自定义主题颜色",
"desc": "自定义应用的主题颜色,包括背景色、前景色、边框色等",
"button": "编辑颜色",
"dialogTitle": "自定义主题颜色",
"dialogDesc": "配置自定义主题颜色。颜色更改会实时保存并生效,同时覆盖亮色和暗色主题。",
"close": "閉じる",
"reset": "重置全部",
"tabs": {
"custom": "自定义",
"presets": "预设方案",
"importExport": "导入导出"
},
"export": {
"title": "导出配色方案",
"button": "生成导出代码",
"placeholder": "点击生成按钮将当前配色导出为代码"
},
"import": {
"title": "导入配色方案",
"button": "导入配色",
"placeholder": "粘贴配色方案的 JSON 代码"
},
"colors": {
"background": "背景色",
"foreground": "前景色",
"card": "卡片背景色",
"cardForeground": "卡片前景色",
"primary": "主色调",
"primaryForeground": "主色调前景色",
"secondary": "次要色调",
"secondaryForeground": "次要色调前景色",
"third": "第三色调",
"thirdForeground": "第三色调前景色",
"muted": "柔和色",
"mutedForeground": "柔和色前景色",
"accent": "强调色",
"accentForeground": "强调色前景色",
"border": "边框色",
"shadow": "阴影色"
},
"presets": {
"apply": "应用",
"reset": {
"name": "恢复默认"
},
"default": {
"name": "默认白色"
},
"ocean": {
"name": "海洋蓝"
},
"forest": {
"name": "森林绿"
},
"sunset": {
"name": "日落红"
},
"lavender": {
"name": "薰衣草紫"
},
"midnight": {
"name": "午夜暗"
},
"deepSea": {
"name": "深海蓝"
},
"darkForest": {
"name": "暗夜绿"
},
"darkViolet": {
"name": "紫罗兰暗"
},
"coralWarm": {
"name": "珊瑚暖"
},
"slateGray": {
"name": "石板灰"
},
"darkGold": {
"name": "暗夜金"
},
"beigeWarm": {
"name": "米黄暖"
},
"beigeDark": {
"name": "米黄暗"
}
}
}
},
"tools": {
"title": "ツール設定",
"chatToolbar": {
"title": "チャットツールバー",
"desc": "チャットツールバーボタンの表示順序と可視性をカスタマイズ",
"button": "設定",
"dialogTitle": "チャットツールバーを構成",
"dialogDesc": "ツールをドラッグして順序を調整し、スイッチを使用して表示または非表示を制御",
"groups": {
"pc": "PC",
"mobile": "モバイル",
"bottom": "下部ツールバー",
"topLeft": "上部ツールバー - 左側",
"topRight": "上部ツールバー - 右側"
}
},
"recordToolbar": {
"title": "記録ツールバー",
"desc": "記録ツールバーボタンの表示順序と可視性をカスタマイズ",
"button": "設定",
"dialogTitle": "記録ツールバーを構成",
"dialogDesc": "ツールをドラッグして順序を調整し、スイッチを使用して表示または非表示を制御"
},
"desc": "配置各种工具栏按钮的显示和排序"
}
},
"rag": {
"title": "知識庫",
"desc": "ここでは、知識庫に関する設定を構成できます。知識庫は、RAG技術に基づいて、埋め込みモデルを使用してテキストをベクトルに変換し、ベクトル検索を介して智能的な検索と智能的な回答を達成します。",
"settingsTitle": "パラメータ設定",
"settingsDesc": "パラメータを調整することで、知識庫の検索結果をより正確に制御できます。",
"deleteVectorConfirm": "知識庫を空にしますか?",
"deleteVectorSuccess": "知識庫を空にしました",
"enable": "知識庫検索を有効にする",
"enableDesc": "有効にすると、AI は回答問題時にあなたのノート内容を検索して、より正確な回答を提供します。",
"chunkSize": "ブロックサイズ",
"chunkSizeDesc": "テキストをブロックに分割する最大文字数。より大きなブロックはより多くの文脈を含む可能性がありますが、ベクトル計算の複雑さを増加させます。",
"chunkOverlap": "重叠サイズ",
"chunkOverlapDesc": "テキストブロック間の重叠文字数。より大きな重叠は上下文の連続性を維持できます。",
"resultCount": "検索結果数",
"resultCountDesc": "検索時に返される関連するドキュメント数。数が多いと提供される情報がより豊富かもしれませんが、ノイズも増加する可能性があります。",
"similarityThreshold": "類似度閾値",
"similarityThresholdDesc": "ドキュメントとクエリの最小類似度閾値。この閾値を超えるドキュメントのみが返されます。値の範囲は 0.0-1.0、高いほど厳格です。",
"resetToDefaults": "デフォルト値に戻す",
"deleteVector": "知識庫を空にする",
"topPDesc": "Top P パラメータはモデルが生成するテキストの多様性を制御します。値が小さいほど出力は決定论的になり、値が大きいほど多様になります。"
},
"mcp": {
"title": "MCP",
"desc": "Model Context Protocol により、AI は外部ツールを呼び出してリソースにアクセスでき、AI の能力を拡張します。",
"servers": "サーバーリスト",
"serversDesc": "MCP サーバー設定を管理します。各サーバーは異なるツールとリソースを提供できます。",
"addServer": "サーバーを追加",
"addFirstServer": "最初のサーバーを追加",
"editServer": "サーバーを編集",
"serverName": "サーバー名",
"serverNamePlaceholder": "例:ファイルシステムサーバー",
"serverEnabled": "サーバーを有効にする",
"serverEnabledDesc": "有効にすると、このサーバーは自動的に接続してツールを提供します。",
"serverType": "サーバータイプ",
"stdio": "ローカルコマンド",
"http": "HTTP サービス",
"command": "コマンド",
"args": "引数",
"argsDesc": "コマンドライン引数、スペースで区切る",
"env": "環境変数",
"envDesc": "JSON 形式の環境変数設定",
"url": "サービス URL",
"headers": "リクエストヘッダー",
"headersDesc": "JSON 形式の HTTP リクエストヘッダー",
"testConnection": "接続テスト",
"test": "テスト",
"testSuccess": "接続テスト成功",
"testFailed": "接続テスト失敗",
"connected": "接続済み",
"connecting": "接続中",
"disconnected": "未接続",
"error": "エラー",
"tools": "ツール",
"noServers": "MCP サービスが有効になっていません",
"noServersFound": "一致するサーバーが見つかりません",
"serverAdded": "サーバーを追加しました",
"serverUpdated": "サーバーを更新しました",
"serverDeleted": "サーバーを削除しました",
"deleteServerTitle": "サーバーを削除",
"deleteServerDesc": "このサーバーを削除してもよろしいですか?この操作は元に戻せません。",
"nameRequired": "サーバー名を入力してください",
"commandRequired": "コマンドを入力してください",
"urlRequired": "サービス URL を入力してください",
"toolBrowser": "ツールブラウザ",
"searchTools": "ツールを検索...",
"noToolsFound": "ツールが見つかりません",
"parameters": "パラメータ",
"testAll": "すべての接続をテスト",
"testAllCompleted": "すべての接続テストが完了しました",
"testAllFailed": "接続テストに失敗しました",
"save": "保存",
"cancel": "キャンセル",
"delete": "削除",
"importJson": "JSON をインポート",
"jsonImportTitle": "JSON からサーバー設定をインポート",
"jsonImportDesc": "MCP サーバーの mcpServers 設定形式を貼り付けます",
"jsonInput": "JSON 設定",
"jsonInputHelp": "mcpServers 形式をサポート、サーバー名が自動的に key として使用されます",
"jsonRequired": "JSON 設定を入力してください",
"jsonEmpty": "JSON 設定は空にできません",
"jsonInvalidJson": "JSON 形式が無効です",
"jsonInvalidFormat": "設定形式が無効です、name と type フィールドを含む必要があります",
"jsonInvalidType": "サーバータイプは stdio または http である必要があります",
"jsonMissingCommand": "stdio タイプのサーバーは command を指定する必要があります",
"jsonMissingUrl": "http タイプのサーバーは url を指定する必要があります",
"jsonImportSuccess": "{count} 個のサーバーを正常にインポートしました",
"jsonImportSkipped": "{count} 個の既存サーバーをスキップしました",
"jsonImportNoServers": "サーバーがインポートされませんでした",
"import": "インポート",
"mobileHttpOnlyTitle": "ローカルコマンド MCP はデスクトップ専用です",
"mobileHttpOnlyDesc": "ローカルコマンド型 MCP サーバーはデスクトップでのみ利用できます。モバイルでは現在 HTTP MCP のみサポートします。",
"runtimeEnvironment": "ランタイム環境",
"runtimeEnvironmentDesc": "MCP サーバーをテストする前に、必要なローカルランタイムが利用可能か確認します。",
"checkEnvironment": "環境を確認",
"recheckEnvironment": "再チェック",
"runtimeCheckFailed": "環境チェックに失敗しました",
"detectedLauncher": "検出されたランチャー",
"runtimeInstalled": "インストール済み",
"runtimeMissing": "未検出",
"runtimeVersion": "バージョン",
"runtimeInstalledSummary": "{installed}/{total} がインストール済み",
"showRuntimeDetails": "ランタイムの詳細を表示",
"hideRuntimeDetails": "ランタイムの詳細を隠す",
"runtimeNotChecked": "このランタイムはまだ確認していません。",
"runtimeCurrentUserScope": "対応している場合、推奨コマンドは現在のユーザー環境にインストールします。",
"runtimeManualOnly": "このプラットフォームでは自動インストールに対応していません。手動でインストールしてから再チェックしてください。",
"installRuntime": "ランタイムをインストール",
"runtimeInstallTitle": "ランタイムをインストール",
"runtimeInstallDesc": "確認後、NoteGen は以下のインストールコマンドを実行します。",
"runtimeInstallPreparing": "インストールを準備中",
"runtimeInstallRunning": "インストール中",
"runtimeInstallCompleted": "インストール完了",
"runtimeInstallCancelled": "キャンセル済み",
"runtimeInstallFailedState": "インストール失敗",
"runtimeInstallLogs": "インストールログ",
"runtimeInstallWaitingLogs": "インストール出力を待機中...",
"runtimeInstallClose": "閉じる",
"runtimeInstallCancel": "インストールを停止",
"runtimeInstallCancelledByUser": "ユーザーがインストールのキャンセルを要求しました。",
"runtimeInstallCancelFailed": "インストールの停止に失敗しました",
"runtimeInstallSuccess": "ランタイムのインストールが完了しました",
"runtimeInstallFailed": "ランタイムのインストールに失敗しました",
"runtimeNoGuidedSupport": "このコマンドにはまだガイド付きランタイム補助がありません。"
,
"enableTitle": "启用 MCP 功能",
"enableDesc": "启用后,AI 可以调用配置的 MCP 服务器提供的工具。"
},
"editor": {
"title": "エディター設定",
"interfaceSettings": "インターフェース設定",
"desc": "ここでは、エディターをカスタマイズして、より適した書き込み体験を提供できます。",
"centeredContent": "コンテンツを中央に表示",
"centeredContentDesc": "有効にすると、コンテンツを中央に表示し、両側に余白を設けます。",
"outlineEnable": "アウトラインを有効にする",
"outlineEnableDesc": "アウトラインを有効にすると、アウトラインが表示されます。",
"outlinePosition": "アウトライン位置",
"outlinePositionDesc": "アウトライン位置を設定します。",
"outlinePositionOptions": {
"left": "左側",
"right": "右側"
},
"showUndoRedo": "元に戻す/やり直しボタン",
"showUndoRedoDesc": "エディターのタブバーに元に戻すボタンとやり直しボタンを表示します。",
"completion": {
"title": "自動補完",
"model": {
"title": "自動補完モデル",
"desc": "エディターの AI インライン補完に使用するモデルを選択"
}
},
"commit": {
"title": "自動コミットメッセージ",
"model": {
"title": "コミットモデル",
"desc": "ファイルの変更に基づいて Git コミットメッセージを自動生成するためのモデル"
}
},
"mermaid": {
"title": " диаграмма",
"rendering": "レンダリング中...",
"renderError": "レンダリングエラー",
"clickToEdit": "クリックしてソースを編集",
"clickToAdd": "クリックして диаграммаを追加",
"placeholder": "Mermaid диаграммаコードを入力...",
"preview": "プレビュー",
"done": "完了",
"diagramTypes": {
"flowchart": "フローチャート",
"sequence": "シーケンス",
"classDiagram": "クラス図",
"stateDiagram": "ステート図",
"er": "ER図",
"gantt": "ガントチャート",
"pie": "円グラフ",
"journey": "ジャーニー"
},
"templates": {
"flowchart": "graph TD\n A[開始] --> B[処理]\n B --> C[終了]",
"sequence": "sequenceDiagram\n participant Alice\n participant Bob\n Alice->>Bob: こんにちは\n Bob-->>Alice: 返信",
"classDiagram": "classDiagram\n Animal <|-- Duck\n Animal <|-- Fish\n Animal : +int age\n Animal : +String gender",
"stateDiagram": "stateDiagram-v2\n [*] --> Active\n Active --> [*]",
"er": "erDiagram\n CUSTOMER ||--o{ ORDER : places\n CUSTOMER ||--o{ DELIVERY-ADDRESS : uses",
"gantt": "gantt\n title プロジェクト計画\n dateFormat YYYY-MM-DD\n section 第一フェーズ\n タスク1 :a1, 2024-01-01, 30d\n section 第二フェーズ\n タスク2 :after a1, 20d",
"pie": "pie title リソース割り当て\n \"CPU\" : 45\n \"メモリ\" : 30\n \"ストレージ\" : 25",
"journey": "journey\n title 私の日常工作\n section 午前\n 通勤 : 7:00, 5\n 仕事 : 9:00, 8"
}
}
},
"record": {
"title": "記録設定",
"desc": "ここでは、記録関連の設定を構成できます。記録の説明やツールバーの設定などが含まれます。",
"model": {
"title": "モデル設定",
"markDesc": {
"title": "記録説明",
"desc": "OCR で認識された記録を処理し、記録の説明を生成するためのモデル"
}
},
"toolbar": {
"title": "ツールバー設定",
"recordToolbar": {
"title": "記録ツールバー",
"desc": "記録ツールバーボタンの表示順序と可視性をカスタマイズ",
"button": "設定",
"text": {
"desc": "记录文本内容"
},
"recording": {
"desc": "录音记录功能"
},
"scan": {
"desc": "扫描识别图片中的文字"
},
"image": {
"desc": "上传图片到笔记"
},
"link": {
"desc": "记录网页链接"
},
"file": {
"desc": "上传文件到笔记"
},
"todo": {
"desc": "创建待办事项"
}
}
}
},
"uploadStore": {
"uploadConfirm": "同期リポジトリをプライベートに設定してください。",
"downloadConfirm": "ダウンロード配置をローカル配置に上書きし、再起動して有効になります。",
"uploadSuccess": "配置を成功しました",
"downloadSuccess": "配置を成功しました",
"upload": "Upload",
"download": "Download"
},
"prompt": {
"title": "マスク",
"promptTitle": "マスク名称",
"desc": "ここでマスクを追加・管理し、AIがあなたのニーズをよりよく理解できるようにします。",
"addPrompt": "マスクを追加",
"selectPrompt": "マスクを選択",
"configPrompt": "マスクを設定",
"noContent": "内容がありません",
"addPromptDesc": "マスク名と内容を入力し、AIがあなたのニーズをよりよく理解できるようにしてください。",
"promptTitlePlaceholder": "マスク名を入力してください",
"promptContentPlaceholder": "マスク内容を入力してください",
"promptContent": "マスク内容",
"optimizePrompt": "プロンプト最適化",
"optimizing": "最適化中...",
"optimizeSuccess": "プロンプトの最適化が成功しました",
"optimizeFailed": "プロンプトの最適化に失敗しました。後でもう一度お試しください",
"noContentToOptimize": "まずプロンプト内容を入力してください"
},
"memories": {
"title": "記憶管理",
"desc": "AI長期記憶機能で、AIがあなたの執筆設定、知識ベース、メモ習慣を記憶します。",
"stats": {
"total": "総記憶数",
"preferences": "設定",
"knowledge": "知識",
"memories": "记忆"
},
"form": {
"title": "新しい記憶を追加",
"contentLabel": "記憶の内容",
"contentPlaceholder": "例:中国語で回答してほしい、Reactエキスパートです...",
"categoryLabel": "タイプ",
"preferenceDesc": "設定(言語、形式、スタイルなど)",
"knowledgeDesc": "知識(事実、経験、専門分野など)",
"save": "記憶を保存",
"saving": "保存中...",
"categoryDescription": "记忆分为两种类型:",
"preferenceDescription": "偏好:语言、格式、风格等设置,每次对话都会自动加载",
"memoryDescription": "记忆:事实、经验、专长等信息,根据对话内容智能匹配",
"preferenceLabel": "偏好",
"memoryLabel": "记忆",
"memoryDesc": "事实、经验、专长等"
},
"listTitle": "マイ記憶",
"addMemory": "記憶を追加",
"empty": "まだ記憶がありません。最初の記憶を追加しましょう!",
"emptyHint": "手動で記憶を追加するか、会話で「覚えて」「これを覚えて」などのフレーズを使うとAIが自動的に記憶を作成します。",
"preference": "設定",
"knowledge": "知識",
"replaced": "置換済み",
"accessCount": "{count} 回アクセス",
"tabs": {
"all": "すべて",
"preference": "設定",
"knowledge": "知識",
"memory": "记忆"
},
"success": "成功",
"saved": "記憶を保存しました",
"updated": "記憶を更新しました(類似の記憶を置換)",
"deleted": "記憶を削除しました",
"cleared": "すべての記憶をクリアしました",
"found": "{count} 件の記憶が見つかりました",
"error": "エラー",
"errorEmpty": "記憶の内容を入力してください",
"errorSave": "保存に失敗しました",
"errorDelete": "削除に失敗しました",
"errorList": "記憶リストの取得に失敗しました",
"errorEmbedding": "埋め込みの生成に失敗しました。埋め込みモデルの設定を確認してください",
"errorClear": "クリアに失敗しました",
"memory": "记忆"
},
"defaultModel": {
"title": "デフォルトモデル",
"desc": "ここでは、異なるシーンに応じて異なるモデルを使用し、効率を高めコストを削減できます。",
"tooltip": "メインモデルを使用",
"noModel": "使用しない",
"placeholder": "モデルを選択または検索してください",
"main": "メインモデル",
"options": {
"primaryModel": {
"title": "メインモデル",
"desc": "すべてのシーンのメインモデルとして、他の会話モデルがデフォルトモデルを選択していない場合、このモデルを使用します。"
},
"markDesc": {
"title": "記録の説明",
"desc": "OCR認識後の記録を処理し、記録の説明を生成します。"
},
"placeholder": {
"title": "AI提案",
"desc": "記録ページのAI会話プレースホルダーコンテンツ生成用のAI提案プロンプト。"
},
"completion": {
"title": "高速補完",
"desc": "Markdownエディタ用のAIインライン補完、GitHub Copilotに類似、素早く続きの内容を生成します。"
},
"commit": {
"title": "コミットメッセージを自動生成",
"desc": "Gitコミットメッセージを自動生成するために使用され、ファイルの内容変更に基づいて記述的なコミットメッセージをインテリジェントに生成します。"
},
"embedding": {
"title": "埋め込みモデル",
"desc": "テキスト埋め込みとベクトル化のシナリオに使用されます。"
},
"reranking": {
"title": "再ランキングモデル",
"desc": "検索結果の並べ替えと最適化に使用されます。"
},
"condense": {
"title": "摘要模型",
"desc": "用于压缩历史对话内容,节省 token 使用量"
}
},
"mainModel": "メインモデル"
},
"readAloud": {
"title": "音声読み上げ",
"desc": "ここでは、音声読み上げ関連の設定を構成し、チャットコンテンツに音声再生機能を提供できます。",
"noModel": "モデルを使用しない",
"options": {
"audioModel": {
"title": "音声モデル",
"desc": "テキストから音声への変換にAIモデルを選択し、様々な音声タイプとパラメータ設定をサポートします。"
},
"speed": {
"title": "読み上げ速度",
"desc": "音声の再生速度を調整します。0.25倍から4倍の範囲で設定でき、1倍が通常の速度です。"
}
}
},
"about": {
"title": "このアプリについて",
"desc": "記録と執筆に特化したメモ取りアシスタント。",
"version": "NoteGen v{version}",
"checkReleases": "過去のバージョンを確認",
"language": "言語",
"checkUpdate": "アップデートを確認",
"checkError": "アップデートの確認に失敗しました",
"updateAvailable": "新しいバージョンが利用可能です",
"updateDownloading": "更新中 {downloaded} / {contentLength}",
"updateInstalled": "アプリを再起動",
"noUpdate": "現在は最新バージョンです",
"ignoreVersion": "このバージョンを無視",
"ignoreVersionSuccess": "このバージョンの更新を無視しました",
"items": {
"home": {
"title": "公式サイト",
"buttonName": "表示",
"desc": "公式サイトを表示して、NoteGenの詳細を確認できます。"
},
"guide": {
"title": "ガイド",
"buttonName": "表示",
"desc": "配置ガイドを表示して、モデル、同期などの情報の設定方法を学ぶことができます。"
},
"github": {
"title": "GitHub",
"buttonName": "表示",
"desc": "NoteGenが役立った場合は、鼓励するには、GitHubにスターを付けてください!"
},
"releases": {
"title": "更新日志",
"buttonName": "表示",
"desc": "更新日志を表示して、NoteGenの更新内容を確認できます。"
},
"issues": {
"title": "問題報告",
"buttonName": "報告",
"desc": "NoteGenにバグを見つけた場合は、ここに報告してください。"
},
"discussions": {
"title": "ディスカッション",
"buttonName": "参加",
"desc": "作者や他のユーザーとディスカッションを参加できます。"
}
}
},
"sync": {
"title": "同期",
"desc": "ここでは、同期リポジトリを設定することができます。ログ、markdownファイル、システム設定などの情報を同期するのに役立ちます。",
"selectPlatform": "同期プラットフォームを選択",
"platformSettings": "プラットフォームを選択",
"settings": "同期設定",
"platformDesc": "Tokenとリポジトリ情報を設定して同期を有効にします",
"moreSettings": "その他の設定",
"repoStatus": "リポジトリの状態",
"syncRepo": "同期リポジトリ",
"syncRepoDesc": "執筆中のMarkdownファイルを同期",
"imageRepo": "画像ホスティング倉庫",
"imageRepoDesc": "あなたの画像を画像ホスティングリポジトリに同期します。",
"status": {
"connected": "接続済み",
"disconnected": "未接続",
"failed": "接続失敗",
"unconfigured": "未設定"
},
"uploadRecords": "レコードと設定をアップロード",
"downloadConfig": "レコードと設定をダウンロード",
"cloudSync": "レコードと設定の同期",
"localBackupAll": "ローカルバックアップ(全て)",
"private": "非公開",
"public": "公開",
"createdAt": "{time} に作成",
"updatedAt": "最終更新: {time}",
"newToken": "作成 access token",
"newTokenDesc": "新しいトークンを作成する際は必ずrepo権限を選択してください。設定後、自動的にプライベートリポジトリと画像ホスティングリポジトリが作成されます。",
"giteeTokenDesc": "Giteeの個人アクセストークンはデータ同期に使用されます。リポジトリの読み書き権限が必要です。設定後、自動的にファイルリポジトリ(プライベート)と画像リポジトリが作成されます。",
"imageRepoSetting": "画像ホスティングを有効化",
"imageRepoSettingDesc": "画像ホスティングリポジトリが設定されています。有効にすると画像はそちらに保存され、無効の場合はローカル保存となります。",
"jsdelivrSetting": "jsDelivr",
"jsdelivrSettingDesc": "jsdelivrを利用して画像アクセスを高速化します。",
"autoSync": "自動同期",
"autoSyncDesc": "有効にすると、エディターは入力停止から10秒後にGitHubに自動同期します",
"giteeAutoSyncDesc": "有効にすると、エディターは入力停止から10秒後にGiteeに自動同期します",
"customSyncRepo": "カスタム同期リポジトリ名",
"customSyncRepoDesc": "空白の場合はデフォルトのリポジトリ名を使用",
"customImageRepo": "カスタム画像リポジトリ名",
"customImageRepoDesc": "空白の場合はデフォルトのリポジトリ名を使用",
"backupMethod": "バックアップ方法",
"backupMethodDesc": "主要バックアップ方法として設定すると、文章作成中のすべての同期関連機能が現在のバックアップ方法を使用します(画像ホスティング機能を除く)",
"createRepo": "リポジトリを作成",
"creating": "作成中",
"checkRepo": "リポジトリを確認",
"checking": "確認中",
"enterToken": "Access Tokenを入力してください",
"enterTokenHint": "リポジトリ的状态を確認するには、先にAccess Tokenを入力してください",
"gitlabInstanceType": "GitLab インスタンスタイプ",
"gitlabInstanceTypeDesc": "接続する GitLab インスタンスタイプを選択してください",
"gitlabInstanceTypePlaceholder": "GitLab インスタンスタイプを選択してください",
"gitlabInstanceTypeOptions": {
"selfHosted": "自建インスタンス",
"selfHostedDesc": "自建 GitLab インスタンスの URL を入力してください(例:https://gitlab.example.com)"
},
"gitlabAccessTokenDesc": "{instanceDisplayName}でパーソナルアクセストークンを作成するには、api権限が必要です",
"autoSyncOptions": {
"placeholder": "自動同期時間",
"disabled": "無効",
"2s": "2 秒",
"3s": "3 秒",
"5s": "5 秒",
"10s": "10 秒",
"20s": "20 秒",
"30s": "30 秒",
"1m": "1 分",
"2m": "2 分"
},
"autoPullOnOpen": "ファイルを開く時に自動プル",
"autoPullOnOpenDesc": "ファイルを開く時、リモートに新しいバージョンがある場合は自動的にプルしてローカルを上書き",
"autoPullOnSwitch": "ファイルを切り替える時に自動プル",
"autoPullOnSwitchDesc": "他のファイルに切り替える時、リモートに新しいバージョンがある場合は自動的にプルしてローカルを上書き",
"exclusions": {
"title": "同期除外設定",
"desc": "以下の設定はデバイス固有のものであるため、デバイス間で同期されません",
"workspacePath": "ワークスペースパス",
"workspaceHistory": "ワークスペース履歴",
"assetsPath": "リソースパス",
"uiScale": "UIスケール",
"contentTextScale": "コンテンツテキストスケール",
"customCss": "カスタムCSS",
"reason": "これらの設定はデバイスによって異なる場合があるため、同期から除外することでパスエラーなどの問題を回避できます"
},
"settingsSync": {
"uploadSuccess": "設定のアップロードに成功しました",
"uploadFailed": "設定のアップロードに失敗しました",
"downloadSuccess": "設定のダウンロードに成功しました",
"downloadFailed": "設定のダウンロードに失敗しました",
"autoSync": "アップロード/ダウンロード時に設定が自動的に同期されます(ワークスペースパスなどのデバイス固有の設定を除く)"
},
"defaultRepoName": "默认: {name}",
"giteaInstanceType": "Gitea 实例类型",
"giteaInstanceTypeDesc": "选择要连接的 Gitea 实例类型",
"giteaInstanceTypePlaceholder": "选择 Gitea 实例类型",
"giteaInstanceTypeOptions": {
"selfHosted": "自建实例",
"selfHostedDesc": "输入您的自建 Gitea 服务器地址(如:https://gitea.example.com)"
},
"giteaAccessTokenDesc": "在 {instanceDisplayName} 创建个人访问令牌,需要完整的 repository 权限",
"s3": {
"title": "S3 同期",
"description": "S3互換ストレージを使用してノートを同期します",
"status": "接続状態",
"connected": "接続済み",
"connecting": "接続中",
"disconnected": "未接続",
"accessKeyId": "Access Key ID",
"accessKeyIdPlaceholder": "Access Key IDを入力してください",
"secretAccessKey": "Secret Access Key",
"secretAccessKeyPlaceholder": "Secret Access Keyを入力してください",
"region": "リージョン",
"bucket": "バケット",
"bucketPlaceholder": "バケット名を入力してください",
"endpoint": "エンドポイント",
"pathPrefix": "パスプレフィックス",
"pathPrefixPlaceholder": "パスプレフィックスを入力してください",
"pathPrefixDesc": "異なるユーザーのファイルを区別するために使用、リポジトリ名に類似",
"customDomain": "カスタムドメイン",
"testConnection": "接続テスト",
"testing": "テスト中",
"saveConfig": "設定を保存",
"saving": "保存中"
},
"webdav": {
"title": "WebDAV 同期",
"description": "WebDAVプロトコルを使用してノートを同期します",
"status": "接続状態",
"connected": "接続済み",
"connecting": "接続中",
"disconnected": "未接続",
"url": "サーバーURL",
"urlPlaceholder": "WebDAV サーバーURLを入力してください",
"urlDesc": "Synology、QNAP、Nextcloud などのWebDAVサービスをサポート",
"username": "ユーザー名",
"usernamePlaceholder": "ユーザー名を入力してください",
"password": "パスワード",
"passwordPlaceholder": "パスワードを入力してください",
"pathPrefix": "パスプレフィックス",
"pathPrefixPlaceholder": "パスプレフィックスを入力してください",
"pathPrefixDesc": "異なるユーザーのファイルを区別するために使用",
"testConnection": "接続テスト",
"testing": "テスト中",
"saveConfig": "設定を保存",
"saving": "保存中"
}
},
"imageHosting": {
"title": "画像ホスティング",
"desc": "ここでは、画像の保存と管理のための画像ホスティングサービスを設定できます。",
"type": "プラットフォームを選択",
"typeDesc": "画像ホスティングサービスを選択",
"customRepoName": "カスタムリポジトリ名",
"customRepoNameDesc": "空白の場合はデフォルトのリポジトリ名を使用",
"isPrimaryBackup": "現在の {type} 主要バックアップ方法",
"setPrimaryBackup": "主要バックアップ方法として設定",
"smms": {
"token": {
"desc": "SM.MS Token を入力してください。",
"createToken": "Token を作成"
},
"disk": "磁盘使用",
"error": "取得失敗、ネットワークや Token の正しさを確認してください。"
gitextract_k__2zx16/ ├── .eslintrc.json ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.yml │ │ ├── config.yml │ │ └── feature_request.yml │ └── workflows/ │ └── release.yml ├── .gitignore ├── .vscode/ │ └── settings.json ├── LICENSE ├── README.md ├── components.json ├── messages/ │ ├── en.json │ ├── ja.json │ ├── pt-BR.json │ ├── zh-TW.json │ └── zh.json ├── next.config.ts ├── package.json ├── postcss.config.mjs ├── public/ │ └── markdown/ │ ├── github-markdown-dark.css │ └── github-markdown-light.css ├── scripts/ │ └── sync-version.sh ├── src/ │ ├── app/ │ │ ├── core/ │ │ │ ├── index.d.ts │ │ │ ├── layout.tsx │ │ │ ├── main/ │ │ │ │ ├── chat/ │ │ │ │ │ ├── agent-execution-status.tsx │ │ │ │ │ ├── agent-history.tsx │ │ │ │ │ ├── agent-panel-with-rag.tsx │ │ │ │ │ ├── chat-clipboard.tsx │ │ │ │ │ ├── chat-content.tsx │ │ │ │ │ ├── chat-empty.tsx │ │ │ │ │ ├── chat-footer.tsx │ │ │ │ │ ├── chat-header.tsx │ │ │ │ │ ├── chat-images.tsx │ │ │ │ │ ├── chat-input.tsx │ │ │ │ │ ├── chat-preview.tsx │ │ │ │ │ ├── chat-send.tsx │ │ │ │ │ ├── chat-thinking.tsx │ │ │ │ │ ├── chat.css │ │ │ │ │ ├── clear-chat.tsx │ │ │ │ │ ├── clear-context.tsx │ │ │ │ │ ├── clipboard-listener.tsx │ │ │ │ │ ├── clipboard-monitor.tsx │ │ │ │ │ ├── file-link.tsx │ │ │ │ │ ├── file-selector.tsx │ │ │ │ │ ├── history-dropdown.tsx │ │ │ │ │ ├── image-attachments.tsx │ │ │ │ │ ├── index.tsx │ │ │ │ │ ├── mcp-button.tsx │ │ │ │ │ ├── mcp-tool-call.tsx │ │ │ │ │ ├── message-control/ │ │ │ │ │ │ ├── condensed-indicator.tsx │ │ │ │ │ │ ├── copy-control.tsx │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ ├── mark-text.tsx │ │ │ │ │ │ ├── message-info.tsx │ │ │ │ │ │ ├── note-output.tsx │ │ │ │ │ │ ├── read-aloud-control.tsx │ │ │ │ │ │ └── translate-control.tsx │ │ │ │ │ ├── model-select.tsx │ │ │ │ │ ├── new-chat.tsx │ │ │ │ │ ├── onboarding-typing.ts │ │ │ │ │ ├── prompt-select.tsx │ │ │ │ │ ├── quote-display.tsx │ │ │ │ │ ├── quote-preview.ts │ │ │ │ │ ├── rag-switch.tsx │ │ │ │ │ └── streaming-smoother.ts │ │ │ │ ├── editor/ │ │ │ │ │ ├── editor-layout.tsx │ │ │ │ │ ├── empty-state-actions.ts │ │ │ │ │ ├── empty-state.tsx │ │ │ │ │ ├── folder/ │ │ │ │ │ │ ├── folder-stats.tsx │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ ├── skill-detail.tsx │ │ │ │ │ │ └── skills-list.tsx │ │ │ │ │ ├── image/ │ │ │ │ │ │ ├── image-editor.css │ │ │ │ │ │ ├── image-editor.tsx │ │ │ │ │ │ └── image-footer.tsx │ │ │ │ │ ├── markdown/ │ │ │ │ │ │ ├── ai-completion.tsx │ │ │ │ │ │ ├── ai-suggestion-floating.tsx │ │ │ │ │ │ ├── ai-suggestion.ts │ │ │ │ │ │ ├── bubble-menu.tsx │ │ │ │ │ │ ├── export-menu.tsx │ │ │ │ │ │ ├── floating-table-menu.tsx │ │ │ │ │ │ ├── footer-bar/ │ │ │ │ │ │ │ ├── copy-button.tsx │ │ │ │ │ │ │ ├── export-button.tsx │ │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ │ ├── outline-toggle.tsx │ │ │ │ │ │ │ ├── vector-calc.tsx │ │ │ │ │ │ │ └── word-count.tsx │ │ │ │ │ │ ├── image-bubble-menu.tsx │ │ │ │ │ │ ├── markdown-input-rules.ts │ │ │ │ │ │ ├── markdown-paragraph.ts │ │ │ │ │ │ ├── math-editor-dialog.tsx │ │ │ │ │ │ ├── math-extension.tsx │ │ │ │ │ │ ├── md-editor-wrapper.tsx │ │ │ │ │ │ ├── mermaid-extension.tsx │ │ │ │ │ │ ├── mobile-editor-context-bar-view-model.ts │ │ │ │ │ │ ├── mobile-editor-context-bar.tsx │ │ │ │ │ │ ├── mobile-editor-more-sheet.tsx │ │ │ │ │ │ ├── mobile-selection-context.ts │ │ │ │ │ │ ├── outline.tsx │ │ │ │ │ │ ├── quote-mark.ts │ │ │ │ │ │ ├── quote-session.ts │ │ │ │ │ │ ├── search-navigation.ts │ │ │ │ │ │ ├── search-replace-panel.tsx │ │ │ │ │ │ ├── slash-command/ │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ ├── slash-command-portal.tsx │ │ │ │ │ │ │ ├── slash-menu.tsx │ │ │ │ │ │ │ └── suggestion.tsx │ │ │ │ │ │ ├── style.css │ │ │ │ │ │ ├── sync/ │ │ │ │ │ │ │ ├── conflict-dialog.tsx │ │ │ │ │ │ │ ├── history-sheet.tsx │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ ├── pull-button.tsx │ │ │ │ │ │ │ ├── sync-button.tsx │ │ │ │ │ │ │ └── sync-tools.tsx │ │ │ │ │ │ ├── table-toolbar.tsx │ │ │ │ │ │ └── tiptap-editor.tsx │ │ │ │ │ ├── onboarding-state.ts │ │ │ │ │ ├── tab-bar.tsx │ │ │ │ │ └── unsupported-file.tsx │ │ │ │ ├── file/ │ │ │ │ │ ├── file-actions.tsx │ │ │ │ │ ├── file-footer.tsx │ │ │ │ │ ├── file-item.tsx │ │ │ │ │ ├── file-manager.tsx │ │ │ │ │ ├── file-toolbar.tsx │ │ │ │ │ ├── folder-item/ │ │ │ │ │ │ ├── copy-folder.tsx │ │ │ │ │ │ ├── cut-folder.tsx │ │ │ │ │ │ ├── delete-folder.tsx │ │ │ │ │ │ ├── duplicate-folder.tsx │ │ │ │ │ │ ├── folder-vector-menu.tsx │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ ├── new-file.tsx │ │ │ │ │ │ ├── new-folder.tsx │ │ │ │ │ │ ├── paste-in-folder.tsx │ │ │ │ │ │ ├── paste-into-folder.js │ │ │ │ │ │ ├── paste-target.js │ │ │ │ │ │ ├── paste-target.spec.mjs │ │ │ │ │ │ ├── rename-folder.tsx │ │ │ │ │ │ ├── sync-folder.tsx │ │ │ │ │ │ └── view-directory.tsx │ │ │ │ │ ├── index.tsx │ │ │ │ │ ├── mobile-action-menu.tsx │ │ │ │ │ ├── root-drop.js │ │ │ │ │ ├── root-drop.spec.mjs │ │ │ │ │ ├── vector-knowledge-menu.tsx │ │ │ │ │ └── workspace-selector.tsx │ │ │ │ ├── left-sidebar.tsx │ │ │ │ ├── mark/ │ │ │ │ │ ├── clipboard.tsx │ │ │ │ │ ├── control-file.tsx │ │ │ │ │ ├── control-image.tsx │ │ │ │ │ ├── control-link.tsx │ │ │ │ │ ├── control-recording.tsx │ │ │ │ │ ├── control-scan.tsx │ │ │ │ │ ├── control-text.tsx │ │ │ │ │ ├── control-todo.tsx │ │ │ │ │ ├── crop.css │ │ │ │ │ ├── image-gallery.tsx │ │ │ │ │ ├── index.tsx │ │ │ │ │ ├── mark-actions.tsx │ │ │ │ │ ├── mark-empty.tsx │ │ │ │ │ ├── mark-filter-popover.tsx │ │ │ │ │ ├── mark-filters.mjs │ │ │ │ │ ├── mark-filters.spec.mjs │ │ │ │ │ ├── mark-header.tsx │ │ │ │ │ ├── mark-item.tsx │ │ │ │ │ ├── mark-list-card-view.tsx │ │ │ │ │ ├── mark-list-compact-view.tsx │ │ │ │ │ ├── mark-list-default-view.tsx │ │ │ │ │ ├── mark-list-item-content.tsx │ │ │ │ │ ├── mark-list.tsx │ │ │ │ │ ├── mark-loading.tsx │ │ │ │ │ ├── mark-mobile-actions.tsx │ │ │ │ │ ├── mark-toolbar.tsx │ │ │ │ │ ├── mark-type-meta.ts │ │ │ │ │ ├── mark-view-mode-toggle.tsx │ │ │ │ │ ├── mark-view-mode.mjs │ │ │ │ │ ├── mark-view-mode.spec.mjs │ │ │ │ │ ├── organize-notes.tsx │ │ │ │ │ ├── organize-onboarding.ts │ │ │ │ │ ├── tag-item.tsx │ │ │ │ │ ├── tag-manage.tsx │ │ │ │ │ ├── tag-mobile-actions.tsx │ │ │ │ │ ├── todo-edit-button.tsx │ │ │ │ │ ├── todo-edit-dialog.tsx │ │ │ │ │ ├── todo-form.tsx │ │ │ │ │ └── todo-item-content.tsx │ │ │ │ └── page.tsx │ │ │ └── setting/ │ │ │ ├── about/ │ │ │ │ ├── page.tsx │ │ │ │ ├── setting-about.tsx │ │ │ │ └── updater.tsx │ │ │ ├── ai/ │ │ │ │ ├── create.tsx │ │ │ │ ├── default-models.tsx │ │ │ │ ├── model-card.tsx │ │ │ │ ├── modelSelect.tsx │ │ │ │ └── page.tsx │ │ │ ├── audio/ │ │ │ │ ├── page.tsx │ │ │ │ └── setting.tsx │ │ │ ├── chat/ │ │ │ │ ├── condense-settings.tsx │ │ │ │ ├── page.tsx │ │ │ │ ├── primary-model-settings.tsx │ │ │ │ └── toolbar-settings.tsx │ │ │ ├── components/ │ │ │ │ ├── default-models-settings.tsx │ │ │ │ ├── model-select.tsx │ │ │ │ ├── setting-base.tsx │ │ │ │ ├── setting-tab.tsx │ │ │ │ └── upload-store.tsx │ │ │ ├── config.tsx │ │ │ ├── defaultModel/ │ │ │ │ ├── page.tsx │ │ │ │ └── setting.tsx │ │ │ ├── dev/ │ │ │ │ ├── page.tsx │ │ │ │ ├── set-config.tsx │ │ │ │ └── setting-dev.tsx │ │ │ ├── editor/ │ │ │ │ ├── centered-content.tsx │ │ │ │ ├── commit.tsx │ │ │ │ ├── completion.tsx │ │ │ │ ├── outline.tsx │ │ │ │ ├── page.tsx │ │ │ │ └── show-undo-redo.tsx │ │ │ ├── file/ │ │ │ │ ├── page.tsx │ │ │ │ ├── setting-assets.tsx │ │ │ │ └── setting-workspace.tsx │ │ │ ├── general/ │ │ │ │ ├── interface-settings/ │ │ │ │ │ ├── content-text-scale.tsx │ │ │ │ │ ├── custom-theme.tsx │ │ │ │ │ ├── file-manager-text-size.tsx │ │ │ │ │ ├── index.tsx │ │ │ │ │ ├── language.tsx │ │ │ │ │ ├── record-text-size.tsx │ │ │ │ │ ├── scale.tsx │ │ │ │ │ ├── theme-color-picker.tsx │ │ │ │ │ ├── theme-presets.tsx │ │ │ │ │ └── theme.tsx │ │ │ │ ├── page.tsx │ │ │ │ └── tool-settings.tsx │ │ │ ├── imageHosting/ │ │ │ │ ├── github.tsx │ │ │ │ ├── page.tsx │ │ │ │ ├── picgo.tsx │ │ │ │ ├── s3.tsx │ │ │ │ ├── setting-switch.tsx │ │ │ │ └── smms.tsx │ │ │ ├── imageMethod/ │ │ │ │ ├── ocr.tsx │ │ │ │ ├── page.tsx │ │ │ │ ├── setDefault.tsx │ │ │ │ └── vlm.tsx │ │ │ ├── layout.tsx │ │ │ ├── mcp/ │ │ │ │ ├── connection-test.tsx │ │ │ │ ├── json-import-dialog.tsx │ │ │ │ ├── page.tsx │ │ │ │ ├── runtime-environment-card.tsx │ │ │ │ ├── server-config-dialog.tsx │ │ │ │ ├── server-list.tsx │ │ │ │ └── tool-browser.tsx │ │ │ ├── memories/ │ │ │ │ └── page.tsx │ │ │ ├── page.tsx │ │ │ ├── prompt/ │ │ │ │ ├── page.tsx │ │ │ │ └── setting-prompt.tsx │ │ │ ├── rag/ │ │ │ │ ├── model-setting.tsx │ │ │ │ ├── page.tsx │ │ │ │ └── settings.tsx │ │ │ ├── readAloud/ │ │ │ │ ├── page.tsx │ │ │ │ └── setting.tsx │ │ │ ├── record/ │ │ │ │ ├── model-settings.tsx │ │ │ │ ├── page.tsx │ │ │ │ └── toolbar-settings.tsx │ │ │ ├── shortcuts/ │ │ │ │ ├── page.tsx │ │ │ │ └── shorcut-input.tsx │ │ │ ├── skills/ │ │ │ │ ├── components/ │ │ │ │ │ ├── global-skills-manager.tsx │ │ │ │ │ ├── project-skills-list.tsx │ │ │ │ │ ├── skill-card.tsx │ │ │ │ │ └── skills-settings.tsx │ │ │ │ └── page.tsx │ │ │ ├── sync/ │ │ │ │ ├── components/ │ │ │ │ │ └── sync-platform-card.tsx │ │ │ │ ├── gitea-sync.tsx │ │ │ │ ├── gitee-sync.tsx │ │ │ │ ├── github-sync.tsx │ │ │ │ ├── gitlab-sync.tsx │ │ │ │ ├── page.tsx │ │ │ │ ├── s3-sync.tsx │ │ │ │ └── webdav-sync.tsx │ │ │ └── template/ │ │ │ ├── page.tsx │ │ │ └── setting-template.tsx │ │ ├── error.tsx │ │ ├── global-error.tsx │ │ ├── globals.css │ │ ├── layout.tsx │ │ ├── mobile/ │ │ │ ├── chat/ │ │ │ │ ├── components/ │ │ │ │ │ ├── chat-attachments-drawer.tsx │ │ │ │ │ ├── chat-settings-drawer.tsx │ │ │ │ │ ├── chat-tools-drawer.tsx │ │ │ │ │ ├── clear-chat.tsx │ │ │ │ │ ├── clear-context.tsx │ │ │ │ │ ├── clipboard-toggle.tsx │ │ │ │ │ ├── mcp-selector.tsx │ │ │ │ │ ├── mobile-chat-header.tsx │ │ │ │ │ ├── model-selector.tsx │ │ │ │ │ ├── new-chat.tsx │ │ │ │ │ ├── prompt-selector.tsx │ │ │ │ │ └── rag-toggle.tsx │ │ │ │ └── page.tsx │ │ │ ├── layout.tsx │ │ │ ├── mobile-styles.css │ │ │ ├── record/ │ │ │ │ ├── mobile-mark-header.tsx │ │ │ │ ├── mobile-record-stream.tsx │ │ │ │ └── page.tsx │ │ │ ├── setting/ │ │ │ │ ├── components/ │ │ │ │ │ └── setting-tab.tsx │ │ │ │ ├── page.tsx │ │ │ │ └── pages/ │ │ │ │ ├── ai/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── audio/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── chat/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── defaultModel/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── dev/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── editor/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── file/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── general/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── imageHosting/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── imageMethod/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── layout.tsx │ │ │ │ ├── mcp/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── prompt/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── rag/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── readAloud/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── record/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── skills/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── sync/ │ │ │ │ │ └── page.tsx │ │ │ │ ├── template/ │ │ │ │ │ └── page.tsx │ │ │ │ └── theme/ │ │ │ │ └── page.tsx │ │ │ └── writing/ │ │ │ ├── browser-utils.ts │ │ │ ├── custom-header.tsx │ │ │ ├── entry-list-item.tsx │ │ │ ├── mobile-editor.tsx │ │ │ ├── name-input-dialog.tsx │ │ │ ├── page.tsx │ │ │ └── types.ts │ │ ├── model-config.ts │ │ ├── not-found.tsx │ │ └── page.tsx │ ├── components/ │ │ ├── activity/ │ │ │ ├── activity-day-detail.tsx │ │ │ ├── activity-drawer.tsx │ │ │ ├── activity-heatmap.tsx │ │ │ ├── activity-legend.tsx │ │ │ └── activity-panel.tsx │ │ ├── app-footbar.tsx │ │ ├── app-sidebar.tsx │ │ ├── app-status.tsx │ │ ├── audio-player.tsx │ │ ├── bottom-bar-icon-button.tsx │ │ ├── console-filter.tsx │ │ ├── draggable-toolbar-item.tsx │ │ ├── image-viewer.tsx │ │ ├── local-image.tsx │ │ ├── memories/ │ │ │ ├── memory-form.tsx │ │ │ ├── memory-item.tsx │ │ │ ├── memory-list.tsx │ │ │ └── memory-stats.tsx │ │ ├── mobile-record-tools.tsx │ │ ├── mobile-statusbar.tsx │ │ ├── onboarding-spotlight-position.ts │ │ ├── onboarding-spotlight.tsx │ │ ├── open-broswer.tsx │ │ ├── pin-toggle.tsx │ │ ├── providers/ │ │ │ └── NextIntlProvider.tsx │ │ ├── recording-dialog.tsx │ │ ├── recording-indicator.tsx │ │ ├── search-dialog.tsx │ │ ├── simple-mobile-tool.tsx │ │ ├── sync-confirm-dialog.tsx │ │ ├── sync-status-badge.tsx │ │ ├── theme-provider.tsx │ │ ├── title-bar-toolbars/ │ │ │ └── sync-toggle.tsx │ │ ├── title-bar.tsx │ │ ├── tooltip-button.tsx │ │ └── ui/ │ │ ├── accordion.tsx │ │ ├── agent-plan.tsx │ │ ├── alert-dialog.tsx │ │ ├── alert.tsx │ │ ├── avatar.tsx │ │ ├── badge.tsx │ │ ├── breadcrumb.tsx │ │ ├── button.tsx │ │ ├── calendar.tsx │ │ ├── card.tsx │ │ ├── carousel.tsx │ │ ├── checkbox.tsx │ │ ├── collapsible.tsx │ │ ├── command.tsx │ │ ├── context-menu.tsx │ │ ├── dialog.tsx │ │ ├── diff-viewer.tsx │ │ ├── drawer.tsx │ │ ├── dropdown-menu.tsx │ │ ├── empty.tsx │ │ ├── enhanced-context-menu.tsx │ │ ├── expandable-tabs.tsx │ │ ├── form.tsx │ │ ├── hover-card.tsx │ │ ├── input.tsx │ │ ├── item.tsx │ │ ├── kbd.tsx │ │ ├── label.tsx │ │ ├── popover.tsx │ │ ├── progress.tsx │ │ ├── radio-group.tsx │ │ ├── resizable.tsx │ │ ├── scroll-area.tsx │ │ ├── select.tsx │ │ ├── separator.tsx │ │ ├── sheet.tsx │ │ ├── shine-border.tsx │ │ ├── sidebar.tsx │ │ ├── skeleton.tsx │ │ ├── slider.tsx │ │ ├── swipe-back.tsx │ │ ├── switch.tsx │ │ ├── table.tsx │ │ ├── tabs.tsx │ │ ├── textarea.tsx │ │ ├── toast.tsx │ │ ├── toaster.tsx │ │ ├── toggle.tsx │ │ └── tooltip.tsx │ ├── config/ │ │ ├── emitters.ts │ │ ├── shortcut.ts │ │ └── sync-exclusions.ts │ ├── contexts/ │ │ └── text-size-context.tsx │ ├── db/ │ │ ├── activity.ts │ │ ├── chats.ts │ │ ├── conversations.ts │ │ ├── index.ts │ │ ├── marks.ts │ │ ├── memories.ts │ │ ├── notes.ts │ │ ├── tags.ts │ │ └── vector.ts │ ├── hooks/ │ │ ├── use-file-shortcuts.ts │ │ ├── use-mobile.tsx │ │ ├── use-sync-manager.ts │ │ ├── use-sync-settings.ts │ │ ├── use-toast.ts │ │ ├── use-toolbar-shortcuts.ts │ │ ├── use-username.ts │ │ ├── useAiCompletion.ts │ │ └── useI18n.ts │ ├── i18n/ │ │ └── request.ts │ ├── lib/ │ │ ├── activity/ │ │ │ ├── aggregate.ts │ │ │ ├── events.ts │ │ │ ├── index.ts │ │ │ └── types.ts │ │ ├── agent/ │ │ │ ├── agent-handler.ts │ │ │ ├── auto-final-answer.ts │ │ │ ├── i18n.ts │ │ │ ├── parse-action-input.ts │ │ │ ├── react-diff-helpers.ts │ │ │ ├── react.ts │ │ │ ├── session-approval.ts │ │ │ ├── tool-confirmation-display.ts │ │ │ ├── tool-policy.ts │ │ │ ├── tools/ │ │ │ │ ├── chat-tools.ts │ │ │ │ ├── editor-tools.ts │ │ │ │ ├── folder-tools.ts │ │ │ │ ├── index.ts │ │ │ │ ├── mark-tools.ts │ │ │ │ ├── memory-tools.ts │ │ │ │ ├── note-tools.ts │ │ │ │ ├── system-tools.ts │ │ │ │ └── tag-tools.ts │ │ │ └── types.ts │ │ ├── ai/ │ │ │ ├── chat.ts │ │ │ ├── completion.ts │ │ │ ├── condense.ts │ │ │ ├── description.ts │ │ │ ├── embedding.ts │ │ │ ├── history-messages.ts │ │ │ ├── index.ts │ │ │ ├── placeholder.ts │ │ │ ├── rewrite.ts │ │ │ ├── token-counter.ts │ │ │ ├── translate.ts │ │ │ ├── types.ts │ │ │ └── utils.ts │ │ ├── audio-converter.ts │ │ ├── audio.ts │ │ ├── bm25.ts │ │ ├── check.ts │ │ ├── context/ │ │ │ └── loader.ts │ │ ├── default-filename.ts │ │ ├── editor-layout-styles.ts │ │ ├── emitter.ts │ │ ├── event-report.ts │ │ ├── files.ts │ │ ├── folder-vector.ts │ │ ├── fuzzy-search.ts │ │ ├── image-handler.ts │ │ ├── imageHosting/ │ │ │ ├── github.ts │ │ │ ├── index.ts │ │ │ ├── picgo.ts │ │ │ ├── s3.ts │ │ │ └── smms.ts │ │ ├── infographic.ts │ │ ├── locales.ts │ │ ├── mark-to-markdown.ts │ │ ├── markdown.ts │ │ ├── mcp/ │ │ │ ├── client.ts │ │ │ ├── index.ts │ │ │ ├── init.ts │ │ │ ├── integration.ts │ │ │ ├── runtime-assistant.ts │ │ │ ├── server-manager.ts │ │ │ ├── tools.ts │ │ │ └── types.ts │ │ ├── ocr.ts │ │ ├── outline-preferences.ts │ │ ├── outline-styles.ts │ │ ├── path.ts │ │ ├── pdf.ts │ │ ├── rag.ts │ │ ├── record-navigation.ts │ │ ├── search-utils.ts │ │ ├── shortcut/ │ │ │ ├── quick-record-text.ts │ │ │ └── show-window.ts │ │ ├── skills/ │ │ │ ├── dependency-installer.ts │ │ │ ├── executor.ts │ │ │ ├── index.ts │ │ │ ├── manager.ts │ │ │ ├── parser.ts │ │ │ ├── path-utils.ts │ │ │ ├── runtime-paths.ts │ │ │ ├── runtime.ts │ │ │ ├── types.ts │ │ │ ├── utils.ts │ │ │ └── validator.ts │ │ ├── speech/ │ │ │ ├── capabilities.ts │ │ │ ├── preferences.ts │ │ │ ├── resolver.ts │ │ │ ├── runtime.ts │ │ │ ├── transcription-fallback.ts │ │ │ └── types.ts │ │ ├── sync/ │ │ │ ├── auto-sync.ts │ │ │ ├── conflict-resolution.ts │ │ │ ├── encode-fetch.ts │ │ │ ├── filename-utils.ts │ │ │ ├── folder-sync-helper.ts │ │ │ ├── folder-sync.ts │ │ │ ├── gitea.ts │ │ │ ├── gitea.types.ts │ │ │ ├── gitee.ts │ │ │ ├── github.ts │ │ │ ├── github.types.ts │ │ │ ├── gitlab.ts │ │ │ ├── gitlab.types.ts │ │ │ ├── remote-file.ts │ │ │ ├── repo-utils.ts │ │ │ ├── s3.ts │ │ │ ├── sync-manager.ts │ │ │ ├── sync-push-queue.ts │ │ │ └── webdav.ts │ │ ├── template-range-utils.ts │ │ ├── theme-utils.ts │ │ ├── toolbar-shortcuts.ts │ │ ├── utils.ts │ │ ├── vector-document-key.js │ │ ├── vector-document-key.spec.mjs │ │ └── workspace.ts │ ├── stores/ │ │ ├── article.ts │ │ ├── chat.ts │ │ ├── clipboard.ts │ │ ├── imageHosting.ts │ │ ├── mark.ts │ │ ├── mcp.ts │ │ ├── memories.ts │ │ ├── prompt.ts │ │ ├── ragSettings.ts │ │ ├── recording.ts │ │ ├── setting.ts │ │ ├── settingsSync.ts │ │ ├── shortcut.ts │ │ ├── sidebar.ts │ │ ├── skills.ts │ │ ├── speech-recognition.ts │ │ ├── sync-confirm.ts │ │ ├── sync.ts │ │ ├── tag.ts │ │ ├── update.ts │ │ └── vector.ts │ └── types/ │ ├── sync.ts │ └── theme.ts ├── src-tauri/ │ ├── .gitignore │ ├── Cargo.toml │ ├── Info.plist │ ├── build.rs │ ├── capabilities/ │ │ ├── default.json │ │ └── desktop.json │ ├── icons/ │ │ └── icon.icns │ ├── src/ │ │ ├── app_setup.rs │ │ ├── backup.rs │ │ ├── device.rs │ │ ├── fuzzy_search.rs │ │ ├── keywords.rs │ │ ├── lib.rs │ │ ├── main.rs │ │ ├── mcp.rs │ │ ├── mcp_runtime.rs │ │ ├── screenshot.rs │ │ ├── skills.rs │ │ ├── statusbar.rs │ │ ├── tray.rs │ │ └── window.rs │ ├── tauri.conf.json │ └── tauri.ios.conf.json └── tsconfig.json
SYMBOL INDEX (1980 symbols across 517 files)
FILE: src-tauri/build.rs
function main (line 1) | fn main() {
FILE: src-tauri/src/app_setup.rs
function setup_app (line 7) | pub fn setup_app(app: &mut App) -> Result<(), Box<dyn std::error::Error>> {
FILE: src-tauri/src/backup.rs
function import_app_data_from_file (line 13) | pub async fn import_app_data_from_file(
function export_app_data (line 86) | pub async fn export_app_data(app_handle: AppHandle, output_path: String)...
function import_app_data (line 127) | pub async fn import_app_data(app_handle: AppHandle, zip_path: String) ->...
function copy_dir_recursive (line 189) | fn copy_dir_recursive(src: &Path, dest: &Path) -> Result<(), String> {
function compress_dir (line 211) | fn compress_dir(src_dir: &Path, dest_file: &Path) -> Result<(), String> {
function add_dir_to_zip (line 233) | fn add_dir_to_zip<W: Write + Seek>(
function extract_zip (line 276) | fn extract_zip(zip_path: &Path, dest_dir: &Path) -> Result<(), String> {
FILE: src-tauri/src/device.rs
function get_device_id (line 6) | pub fn get_device_id() -> Result<String, String> {
function get_device_id (line 14) | pub fn get_device_id() -> Result<String, String> {
function get_device_id (line 21) | pub fn get_device_id() -> Result<String, String> {
function get_or_create_device_id (line 27) | fn get_or_create_device_id() -> Result<String, String> {
FILE: src-tauri/src/fuzzy_search.rs
type SearchItem (line 9) | pub struct SearchItem {
type MatchInfo (line 22) | pub struct MatchInfo {
type FuzzySearchResult (line 29) | pub struct FuzzySearchResult {
function search_item (line 36) | fn search_item(
function fuzzy_search (line 96) | pub fn fuzzy_search(
function fuzzy_search_parallel (line 139) | pub fn fuzzy_search_parallel(
FILE: src-tauri/src/keywords.rs
type Keyword (line 11) | pub struct Keyword {
function get_jieba (line 16) | fn get_jieba() -> &'static Jieba {
function get_text_rank (line 24) | fn get_text_rank() -> TextRank {
function get_stop_words (line 30) | fn get_stop_words() -> HashSet<&'static str> {
function is_stop_word (line 49) | fn is_stop_word(word: &str) -> bool {
function extract_english_words (line 58) | fn extract_english_words(text: &str) -> Vec<String> {
function rank_keywords (line 78) | pub fn rank_keywords(text: &str, top_k: usize, allowed_pos: Option<Vec<S...
FILE: src-tauri/src/lib.rs
function run (line 14) | pub fn run() {
FILE: src-tauri/src/main.rs
function main (line 25) | fn main() {
FILE: src-tauri/src/mcp.rs
type McpServerManager (line 12) | pub struct McpServerManager {
method new (line 17) | pub fn new() -> Self {
function encode_mcp_message (line 24) | fn encode_mcp_message(message: &str) -> Vec<u8> {
function read_mcp_message (line 28) | fn read_mcp_message<R: Read>(reader: &mut R) -> Result<String, String> {
function find_npx_path (line 94) | fn find_npx_path() -> Option<String> {
function start_mcp_stdio_server (line 172) | pub async fn start_mcp_stdio_server(
function stop_mcp_server (line 277) | pub async fn stop_mcp_server(
function send_mcp_message (line 299) | pub async fn send_mcp_message(
function writes_newline_delimited_message (line 337) | fn writes_newline_delimited_message() {
function reads_single_json_line_message (line 348) | fn reads_single_json_line_message() {
function reads_single_framed_message (line 359) | fn reads_single_framed_message() {
function rejects_missing_content_length_header (line 370) | fn rejects_missing_content_length_header() {
function rejects_truncated_framed_message (line 380) | fn rejects_truncated_framed_message() {
FILE: src-tauri/src/mcp_runtime.rs
type RuntimeKind (line 15) | pub enum RuntimeKind {
type RuntimeRequirement (line 25) | pub struct RuntimeRequirement {
type InstallRecipe (line 32) | pub struct InstallRecipe {
type RuntimeCheckResult (line 43) | pub struct RuntimeCheckResult {
type RuntimeInspection (line 53) | pub struct RuntimeInspection {
type InstallExecutionResult (line 62) | pub struct InstallExecutionResult {
type RuntimeInstallManager (line 71) | pub struct RuntimeInstallManager {
method new (line 77) | pub fn new() -> Self {
type InstallProgressStage (line 84) | pub enum InstallProgressStage {
type InstallProgressEvent (line 94) | pub struct InstallProgressEvent {
type CancelInstallResult (line 104) | pub struct CancelInstallResult {
function normalize_launcher (line 109) | fn normalize_launcher(command: &str, args: &[String]) -> String {
function classify_runtime_requirement (line 130) | pub fn classify_runtime_requirement(command: &str, args: &[String]) -> R...
function install_recipe_for (line 144) | pub fn install_recipe_for(kind: &RuntimeKind, platform: &str) -> Option<...
function current_platform (line 227) | fn current_platform() -> &'static str {
function find_command_path (line 237) | fn find_command_path(command: &str) -> Option<PathBuf> {
function version_args_for (line 258) | fn version_args_for(command: &str) -> &'static [&'static str] {
function read_command_version (line 265) | fn read_command_version(command: &str, path: &Path) -> Result<Option<Str...
function inspect_requirement (line 288) | fn inspect_requirement(requirement: &RuntimeRequirement) -> RuntimeInspe...
function install_recipe_command (line 310) | fn install_recipe_command(recipe_id: &str) -> Option<(&'static str, Vec<...
function configure_install_command (line 344) | fn configure_install_command(command: &mut TokioCommand) {
function configure_install_command (line 349) | fn configure_install_command(_command: &mut TokioCommand) {}
function configure_install_command (line 352) | fn configure_install_command(_command: &mut TokioCommand) {}
function kill_install_process (line 355) | async fn kill_install_process(pid: u32) -> Result<(), String> {
function kill_install_process (line 366) | async fn kill_install_process(pid: u32) -> Result<(), String> {
function kill_install_process (line 376) | async fn kill_install_process(_pid: u32) -> Result<(), String> {
function final_install_stage (line 380) | fn final_install_stage(success: bool, cancelled: bool) -> InstallProgres...
function emit_install_event (line 390) | fn emit_install_event<R: Runtime>(
function collect_process_output (line 411) | async fn collect_process_output<R: Runtime>(
function inspect_mcp_runtime (line 444) | pub async fn inspect_mcp_runtime(command: String, args: Vec<String>) -> ...
function install_mcp_runtime (line 450) | pub async fn install_mcp_runtime(
function cancel_mcp_runtime_install (line 573) | pub async fn cancel_mcp_runtime_install(
function classifies_combined_npx_command (line 620) | fn classifies_combined_npx_command() {
function classifies_python_command_with_args (line 631) | fn classifies_python_command_with_args() {
function returns_macos_recipe_for_uvx (line 642) | fn returns_macos_recipe_for_uvx() {
function uses_bun_dot_com_installer_for_bun (line 650) | fn uses_bun_dot_com_installer_for_bun() {
function returns_none_for_unknown_runtime (line 658) | fn returns_none_for_unknown_runtime() {
function final_install_stage_returns_completed_on_success (line 665) | fn final_install_stage_returns_completed_on_success() {
function final_install_stage_returns_failed_on_error (line 673) | fn final_install_stage_returns_failed_on_error() {
function final_install_stage_returns_cancelled_when_requested (line 678) | fn final_install_stage_returns_cancelled_when_requested() {
function runtime_install_manager_starts_empty (line 683) | fn runtime_install_manager_starts_empty() {
FILE: src-tauri/src/screenshot.rs
type ScreenshotImage (line 9) | pub struct ScreenshotImage {
function normalized (line 19) | fn normalized(s: &str) -> String {
function screenshot (line 33) | pub fn screenshot(app: AppHandle) -> Vec<ScreenshotImage> {
FILE: src-tauri/src/skills.rs
function import_skill_zip (line 7) | pub async fn import_skill_zip(app_handle: AppHandle, zip_path: String) -...
function copy_dir_recursive (line 110) | fn copy_dir_recursive(src: &Path, dest: &Path) -> Result<(), String> {
FILE: src-tauri/src/statusbar.rs
function set_statusbar_color (line 4) | pub fn set_statusbar_color(color: String, is_dark: bool) -> Result<(), S...
FILE: src-tauri/src/tray.rs
constant ID_SHOW_MAIN (line 9) | pub const ID_SHOW_MAIN: &str = "show-main";
constant ID_SETTINGS (line 10) | pub const ID_SETTINGS: &str = "settings";
constant ID_QUIT (line 11) | pub const ID_QUIT: &str = "quit";
function create_tray (line 13) | pub fn create_tray<R: Runtime>(app: &AppHandle<R>) -> tauri::Result<taur...
function handle_menu_event (line 47) | fn handle_menu_event<R: Runtime>(app: &AppHandle<R>, id: &str) {
FILE: src-tauri/src/window.rs
function setup_window_events (line 3) | pub fn setup_window_events(app: &AppHandle) -> tauri::Result<()> {
function handle_window_event (line 15) | fn handle_window_event(event: &WindowEvent, window: &tauri::WebviewWindo...
function handle_window_event (line 27) | fn handle_window_event(event: &WindowEvent, window: &tauri::WebviewWindo...
function handle_single_instance (line 38) | pub fn handle_single_instance(app: &AppHandle, _argv: Vec<String>, _cwd:...
function handle_macos_reopen (line 64) | pub fn handle_macos_reopen(app_handle: &AppHandle, has_visible_windows: ...
FILE: src/app/core/index.d.ts
type ScreenshotImage (line 2) | interface ScreenshotImage {
FILE: src/app/core/layout.tsx
function RootLayout (line 29) | function RootLayout({
FILE: src/app/core/main/chat/agent-execution-status.tsx
function AgentExecutionStatus (line 9) | function AgentExecutionStatus() {
FILE: src/app/core/main/chat/agent-history.tsx
type AgentHistoryProps (line 4) | interface AgentHistoryProps {
function AgentHistory (line 12) | function AgentHistory({ historyJson }: AgentHistoryProps) {
FILE: src/app/core/main/chat/agent-panel-with-rag.tsx
type RagSourceDetail (line 9) | interface RagSourceDetail {
type AgentPanelWithRagProps (line 15) | interface AgentPanelWithRagProps {
function AgentPanelWithRag (line 71) | function AgentPanelWithRag({
FILE: src/app/core/main/chat/chat-clipboard.tsx
function ChatClipboard (line 20) | function ChatClipboard({chat}: { chat: Chat }) {
FILE: src/app/core/main/chat/chat-content.tsx
constant BOTTOM_THRESHOLD (line 24) | const BOTTOM_THRESHOLD = 24
constant USER_SCROLL_GRACE_MS (line 25) | const USER_SCROLL_GRACE_MS = 300
FILE: src/app/core/main/chat/chat-empty.tsx
function formatRelativeTime (line 20) | function formatRelativeTime(timestamp: number, locale: string): string {
function ChatEmpty (line 25) | function ChatEmpty() {
FILE: src/app/core/main/chat/chat-footer.tsx
function ChatFooter (line 9) | function ChatFooter() {
FILE: src/app/core/main/chat/chat-header.tsx
function formatRelativeTime (line 25) | function formatRelativeTime(timestamp: number, locale: string): string {
function ChatHeader (line 30) | function ChatHeader() {
FILE: src/app/core/main/chat/chat-images.tsx
type ChatImagesProps (line 6) | interface ChatImagesProps {
function ChatImages (line 10) | function ChatImages({ images }: ChatImagesProps) {
FILE: src/app/core/main/chat/chat-input.tsx
type SortableToolbarItemProps (line 51) | interface SortableToolbarItemProps {
function addToHistory (line 162) | function addToHistory(input: string) {
function navigateHistory (line 172) | function navigateHistory(direction: 'up' | 'down', currentText: string) {
function removeLinkedFile (line 203) | function removeLinkedFile() {
function removeImage (line 208) | function removeImage(id: string) {
function removeQuote (line 212) | function removeQuote() {
function handleSelectLocalImages (line 216) | async function handleSelectLocalImages() {
function handleSelectFromGallery (line 250) | async function handleSelectFromGallery() {
function handleImageInputChange (line 260) | async function handleImageInputChange(event: React.ChangeEvent<HTMLInput...
function handlePaste (line 286) | async function handlePaste(e: React.ClipboardEvent) {
function handleSent (line 331) | function handleSent() {
function genInputPlaceholder (line 348) | async function genInputPlaceholder() {
function insertPlaceholder (line 383) | function insertPlaceholder() {
function generateFilePreview (line 500) | async function generateFilePreview(filePath: string, isCustom: boolean):...
function linkCurrentResource (line 549) | async function linkCurrentResource() {
FILE: src/app/core/main/chat/chat-preview.tsx
type ThemeType (line 17) | type ThemeType = 'light' | 'dark' | 'system';
type ChatPreviewProps (line 19) | type ChatPreviewProps = {
constant MIN_RENDER_INTERVAL_MS (line 24) | const MIN_RENDER_INTERVAL_MS = 33;
function ChatPreview (line 26) | function ChatPreview({text, streaming = false}: ChatPreviewProps) {
FILE: src/app/core/main/chat/chat-send.tsx
type QuoteData (line 21) | interface QuoteData {
type ChatSendProps (line 32) | interface ChatSendProps {
function handleAgentMode (line 215) | async function handleAgentMode(imageUrls: string[]) {
function handleSubmit (line 565) | async function handleSubmit() {
FILE: src/app/core/main/chat/chat-thinking.tsx
function ChatThinking (line 6) | function ChatThinking({chat}: { chat: Chat }) {
FILE: src/app/core/main/chat/clear-chat.tsx
function ClearChat (line 9) | function ClearChat() {
FILE: src/app/core/main/chat/clear-context.tsx
function ClearContext (line 10) | function ClearContext() {
FILE: src/app/core/main/chat/clipboard-listener.tsx
function ClipboardListener (line 11) | function ClipboardListener() {
FILE: src/app/core/main/chat/clipboard-monitor.tsx
function ClipboardMonitor (line 8) | function ClipboardMonitor() {
FILE: src/app/core/main/chat/file-link.tsx
type FileLinkProps (line 9) | interface FileLinkProps {
function FileLink (line 14) | function FileLink({ onFileLinkClick, disabled = false }: FileLinkProps) {
type LinkedResourceDisplayProps (line 32) | interface LinkedResourceDisplayProps {
function LinkedFileDisplay (line 37) | function LinkedFileDisplay({ linkedResource, onFileRemove }: LinkedResou...
FILE: src/app/core/main/chat/file-selector.tsx
type FileSelectorProps (line 11) | interface FileSelectorProps {
function FileSelector (line 17) | function FileSelector({ onFileSelect, onClose, isOpen }: FileSelectorPro...
FILE: src/app/core/main/chat/history-dropdown.tsx
type HistoryDropdownProps (line 17) | interface HistoryDropdownProps {
function HistoryDropdown (line 27) | function HistoryDropdown({
FILE: src/app/core/main/chat/image-attachments.tsx
type ImageAttachment (line 7) | interface ImageAttachment {
type ImageAttachmentsProps (line 14) | interface ImageAttachmentsProps {
function ImageAttachments (line 19) | function ImageAttachments({ images, onRemove }: ImageAttachmentsProps) {
FILE: src/app/core/main/chat/index.tsx
function Chat (line 8) | function Chat() {
FILE: src/app/core/main/chat/mcp-button.tsx
function McpButton (line 24) | function McpButton() {
FILE: src/app/core/main/chat/mcp-tool-call.tsx
type McpToolCallCardProps (line 11) | interface McpToolCallCardProps {
function McpToolCallCard (line 15) | function McpToolCallCard({ toolCall }: McpToolCallCardProps) {
FILE: src/app/core/main/chat/message-control/condensed-indicator.tsx
type CondensedIndicatorProps (line 10) | interface CondensedIndicatorProps {
function CondensedIndicator (line 14) | function CondensedIndicator({ chat }: CondensedIndicatorProps) {
FILE: src/app/core/main/chat/message-control/copy-control.tsx
type CopyControlProps (line 8) | interface CopyControlProps {
function CopyControl (line 13) | function CopyControl({ chat, translatedContent }: CopyControlProps) {
FILE: src/app/core/main/chat/message-control/index.tsx
function MessageControl (line 14) | function MessageControl({chat, children}: {chat: Chat, children: React.R...
FILE: src/app/core/main/chat/message-control/mark-text.tsx
function MarkText (line 11) | function MarkText({chat}: {chat: Chat}) {
FILE: src/app/core/main/chat/message-control/message-info.tsx
type MessageInfoProps (line 9) | interface MessageInfoProps {
function MessageInfo (line 13) | function MessageInfo({ chat }: MessageInfoProps) {
FILE: src/app/core/main/chat/message-control/note-output.tsx
function NoteOutput (line 29) | function NoteOutput({chat}: {chat: Chat}) {
FILE: src/app/core/main/chat/message-control/read-aloud-control.tsx
type ReadAloudControlProps (line 9) | interface ReadAloudControlProps {
function ReadAloudControl (line 14) | function ReadAloudControl({ chat, translatedContent }: ReadAloudControlP...
FILE: src/app/core/main/chat/message-control/translate-control.tsx
type TranslateControlProps (line 15) | interface TranslateControlProps {
function TranslateControl (line 20) | function TranslateControl({ chat, onTranslatedContent }: TranslateContro...
FILE: src/app/core/main/chat/model-select.tsx
type GroupedModel (line 27) | interface GroupedModel {
function ModelSelect (line 33) | function ModelSelect() {
FILE: src/app/core/main/chat/new-chat.tsx
function NewChat (line 8) | function NewChat() {
FILE: src/app/core/main/chat/onboarding-typing.ts
function buildTypingFrames (line 1) | function buildTypingFrames(text: string, chunkSize: number) {
FILE: src/app/core/main/chat/prompt-select.tsx
function PromptSelect (line 12) | function PromptSelect() {
FILE: src/app/core/main/chat/quote-display.tsx
type QuoteData (line 7) | interface QuoteData {
type QuoteDisplayProps (line 18) | interface QuoteDisplayProps {
function QuoteDisplay (line 23) | function QuoteDisplay({ quoteData, onRemove }: QuoteDisplayProps) {
FILE: src/app/core/main/chat/quote-preview.ts
function getQuotePreview (line 1) | function getQuotePreview(content: string, limit = 160) {
FILE: src/app/core/main/chat/rag-switch.tsx
function RagSwitch (line 11) | function RagSwitch() {
FILE: src/app/core/main/chat/streaming-smoother.ts
type SmootherState (line 1) | type SmootherState = {
type SmootherStepResult (line 6) | type SmootherStepResult = SmootherState & {
constant MIN_CHARS_PER_SECOND (line 10) | const MIN_CHARS_PER_SECOND = 28;
constant MID_CHARS_PER_SECOND (line 11) | const MID_CHARS_PER_SECOND = 52;
constant HIGH_CHARS_PER_SECOND (line 12) | const HIGH_CHARS_PER_SECOND = 96;
constant MAX_CHARS_PER_SECOND (line 13) | const MAX_CHARS_PER_SECOND = 160;
function getAdaptiveCharsPerSecond (line 15) | function getAdaptiveCharsPerSecond(backlog: number): number {
function advanceStreamingSmoother (line 22) | function advanceStreamingSmoother(
FILE: src/app/core/main/editor/editor-layout.tsx
constant MARKDOWN_EXTENSIONS (line 42) | const MARKDOWN_EXTENSIONS = new Set([
constant IMAGE_EXTENSIONS (line 49) | const IMAGE_EXTENSIONS = new Set(['jpg', 'jpeg', 'png', 'gif', 'bmp', 'w...
constant ONBOARDING_PROGRESS_STORE_KEY (line 50) | const ONBOARDING_PROGRESS_STORE_KEY = 'desktopOnboardingProgress'
function EditorLayout (line 52) | function EditorLayout() {
FILE: src/app/core/main/editor/empty-state-actions.ts
function createNewNoteFromEmptyState (line 1) | async function createNewNoteFromEmptyState({
constant ONBOARDING_SAMPLE_RECORD (line 12) | const ONBOARDING_SAMPLE_RECORD = `这是我在 NoteGen 里的第一条记录。
function startCreateRecordOnboardingStep (line 19) | async function startCreateRecordOnboardingStep({
function getOnboardingAgentPrompt (line 30) | function getOnboardingAgentPrompt({
function getOnboardingSpotlightTarget (line 44) | function getOnboardingSpotlightTarget(step: 'create-record' | 'organize-...
function isMarkdownPath (line 55) | function isMarkdownPath(path: string) {
type OnboardingFileTreeNode (line 59) | type OnboardingFileTreeNode = {
function computedOnboardingPath (line 71) | function computedOnboardingPath(node: OnboardingFileTreeNode): string {
function getPathPriority (line 85) | function getPathPriority(path: string) {
function flattenFileTree (line 99) | function flattenFileTree(tree: OnboardingFileTreeNode[]): Array<{ path: ...
function findRecentOnboardingFile (line 120) | function findRecentOnboardingFile({
FILE: src/app/core/main/editor/empty-state.tsx
type ActionItem (line 17) | interface ActionItem {
type EmptyStateProps (line 25) | interface EmptyStateProps {
function EmptyState (line 35) | function EmptyState({
FILE: src/app/core/main/editor/folder/folder-stats.tsx
type FolderStats (line 19) | interface FolderStats {
type FolderStatsViewProps (line 27) | interface FolderStatsViewProps {
function FolderStatsView (line 32) | function FolderStatsView({ folderPath, folderFiles }: FolderStatsViewPro...
FILE: src/app/core/main/editor/folder/index.tsx
type FolderViewProps (line 14) | interface FolderViewProps {
function collectFiles (line 19) | function collectFiles(tree: ReturnType<typeof useArticleStore.getState>[...
function FolderView (line 67) | function FolderView({ folderPath }: FolderViewProps) {
FILE: src/app/core/main/editor/folder/skill-detail.tsx
type SkillDetailViewProps (line 7) | interface SkillDetailViewProps {
function SkillDetailView (line 11) | function SkillDetailView({ skillContent }: SkillDetailViewProps) {
FILE: src/app/core/main/editor/folder/skills-list.tsx
type SkillsListViewProps (line 8) | interface SkillsListViewProps {
function SkillsListView (line 12) | function SkillsListView({ skills }: SkillsListViewProps) {
FILE: src/app/core/main/editor/image/image-editor.tsx
type ImageEditorProps (line 27) | interface ImageEditorProps {
function ImageEditor (line 31) | function ImageEditor({ filePath }: ImageEditorProps) {
FILE: src/app/core/main/editor/image/image-footer.tsx
type ImageFooterProps (line 7) | interface ImageFooterProps {
function ImageFooter (line 13) | function ImageFooter({ filePath, imageWidth, imageHeight }: ImageFooterP...
FILE: src/app/core/main/editor/markdown/ai-completion.tsx
type AICompletionProps (line 9) | interface AICompletionProps {
type SuggestionItem (line 15) | interface SuggestionItem {
function AICompletionPopup (line 21) | function AICompletionPopup({ items, onSelect, onDismiss }: {
function useAIAutocomplete (line 96) | function useAIAutocomplete({ editor, isEnabled, onComplete }: AICompleti...
FILE: src/app/core/main/editor/markdown/ai-suggestion-floating.tsx
type AISuggestionFloatingProps (line 9) | interface AISuggestionFloatingProps {
type SuggestionData (line 13) | interface SuggestionData {
type PositionData (line 20) | interface PositionData {
function AISuggestionFloating (line 24) | function AISuggestionFloating({ editor }: AISuggestionFloatingProps) {
FILE: src/app/core/main/editor/markdown/ai-suggestion.ts
type AISuggestionOptions (line 3) | interface AISuggestionOptions {
type Commands (line 8) | interface Commands<ReturnType> {
method addOptions (line 20) | addOptions() {
method addAttributes (line 26) | addAttributes() {
method parseHTML (line 49) | parseHTML() {
method renderHTML (line 57) | renderHTML({ HTMLAttributes }) {
method addCommands (line 68) | addCommands() {
FILE: src/app/core/main/editor/markdown/bubble-menu.tsx
constant POPULAR_LANGUAGES (line 29) | const POPULAR_LANGUAGES = [
type BubbleMenuProps (line 41) | interface BubbleMenuProps {
function BubbleMenu (line 49) | function BubbleMenu({
FILE: src/app/core/main/editor/markdown/export-menu.tsx
type ExportMenuProps (line 17) | interface ExportMenuProps {
function ExportMenu (line 21) | function ExportMenu({ editor }: ExportMenuProps) {
FILE: src/app/core/main/editor/markdown/floating-table-menu.tsx
type FloatingTableMenuProps (line 16) | interface FloatingTableMenuProps {
function FloatingTableMenu (line 20) | function FloatingTableMenu({ editor }: FloatingTableMenuProps) {
FILE: src/app/core/main/editor/markdown/footer-bar/copy-button.tsx
type CopyButtonProps (line 14) | interface CopyButtonProps {
type CopyFormat (line 18) | type CopyFormat = 'markdown' | 'html' | 'json' | 'text'
function CopyButton (line 20) | function CopyButton({ editor }: CopyButtonProps) {
FILE: src/app/core/main/editor/markdown/footer-bar/export-button.tsx
type ExportButtonProps (line 16) | interface ExportButtonProps {
function ExportButton (line 20) | function ExportButton({ editor }: ExportButtonProps) {
FILE: src/app/core/main/editor/markdown/footer-bar/index.tsx
type FooterBarProps (line 10) | interface FooterBarProps {
function FooterBar (line 16) | function FooterBar({
FILE: src/app/core/main/editor/markdown/footer-bar/outline-toggle.tsx
type OutlineToggleProps (line 7) | interface OutlineToggleProps {
function OutlineToggle (line 13) | function OutlineToggle({
FILE: src/app/core/main/editor/markdown/footer-bar/vector-calc.tsx
type VectorCalcProps (line 8) | interface VectorCalcProps {
function VectorCalc (line 13) | function VectorCalc({
FILE: src/app/core/main/editor/markdown/footer-bar/word-count.tsx
type WordCountProps (line 6) | interface WordCountProps {
function WordCount (line 10) | function WordCount({ editor }: WordCountProps) {
FILE: src/app/core/main/editor/markdown/image-bubble-menu.tsx
type ImageBubbleMenuProps (line 8) | interface ImageBubbleMenuProps {
type ImageInfo (line 12) | interface ImageInfo {
type EditMode (line 19) | type EditMode = 'none' | 'alt' | 'src'
function ImageBubbleMenu (line 21) | function ImageBubbleMenu({ editor }: ImageBubbleMenuProps) {
FILE: src/app/core/main/editor/markdown/markdown-input-rules.ts
method addInputRules (line 12) | addInputRules() {
FILE: src/app/core/main/editor/markdown/markdown-paragraph.ts
type MarkdownParagraphOptions (line 3) | interface MarkdownParagraphOptions {
type Commands (line 8) | interface Commands<ReturnType> {
constant EMPTY_PARAGRAPH_MARKDOWN (line 15) | const EMPTY_PARAGRAPH_MARKDOWN = ' '
constant NBSP_CHAR (line 16) | const NBSP_CHAR = '\u00A0'
method addOptions (line 23) | addOptions() {
method parseHTML (line 33) | parseHTML() {
method renderHTML (line 37) | renderHTML({ HTMLAttributes }) {
method addCommands (line 70) | addCommands() {
method addKeyboardShortcuts (line 80) | addKeyboardShortcuts() {
FILE: src/app/core/main/editor/markdown/math-editor-dialog.tsx
type MathEditorDialogProps (line 10) | interface MathEditorDialogProps {
function MathEditorDialog (line 19) | function MathEditorDialog({
FILE: src/app/core/main/editor/markdown/math-extension.tsx
function InlineMathView (line 10) | function InlineMathView({ node, updateAttributes }: ReactNodeViewProps) {
function BlockMathView (line 76) | function BlockMathView({ node, updateAttributes }: ReactNodeViewProps) {
method addAttributes (line 147) | addAttributes() {
method parseHTML (line 155) | parseHTML() {
method renderHTML (line 168) | renderHTML({ HTMLAttributes }) {
method addNodeView (line 172) | addNodeView() {
method renderMarkdown (line 202) | renderMarkdown(node, _helpers) {
method parseMarkdown (line 207) | parseMarkdown(token, _helpers) {
method addAttributes (line 221) | addAttributes() {
method parseHTML (line 229) | parseHTML() {
method renderHTML (line 242) | renderHTML({ HTMLAttributes }) {
method addNodeView (line 246) | addNodeView() {
method renderMarkdown (line 276) | renderMarkdown(node, _helpers) {
method parseMarkdown (line 281) | parseMarkdown(token, _helpers) {
FILE: src/app/core/main/editor/markdown/md-editor-wrapper.tsx
type MdEditorProps (line 13) | interface MdEditorProps {
function MdEditor (line 18) | function MdEditor({ tabContentsRef, filePath }: MdEditorProps) {
FILE: src/app/core/main/editor/markdown/mermaid-extension.tsx
constant DIAGRAM_TYPES (line 27) | const DIAGRAM_TYPES = [
function detectDiagramType (line 39) | function detectDiagramType(code: string): string {
function MermaidDiagramView (line 52) | function MermaidDiagramView({ node, updateAttributes }: ReactNodeViewPro...
method addAttributes (line 217) | addAttributes() {
method parseHTML (line 228) | parseHTML() {
method renderHTML (line 235) | renderHTML({ HTMLAttributes }) {
method addNodeView (line 239) | addNodeView() {
method renderMarkdown (line 270) | renderMarkdown(node, _helpers) {
method parseMarkdown (line 275) | parseMarkdown(token, _helpers) {
FILE: src/app/core/main/editor/markdown/mobile-editor-context-bar-view-model.ts
constant ACTION_META (line 23) | const ACTION_META = {
function buildMobileEditorContextBarViewModel (line 46) | function buildMobileEditorContextBarViewModel(actions: string[] = []) {
FILE: src/app/core/main/editor/markdown/mobile-editor-context-bar.tsx
type MobileContextMode (line 7) | type MobileContextMode = 'text' | 'image' | 'table'
type MobileContextAction (line 9) | type MobileContextAction =
type MobileEditorContextBarProps (line 22) | interface MobileEditorContextBarProps {
function MobileEditorContextBar (line 29) | function MobileEditorContextBar({
FILE: src/app/core/main/editor/markdown/mobile-editor-more-sheet.tsx
type MobileSheetMode (line 7) | type MobileSheetMode = 'ai' | 'image-src' | 'image-alt' | 'table-align' ...
type MobileEditorMoreSheetProps (line 9) | interface MobileEditorMoreSheetProps {
function ActionButton (line 22) | function ActionButton({ label, onClick, destructive = false }: { label: ...
function MobileEditorMoreSheet (line 34) | function MobileEditorMoreSheet({
FILE: src/app/core/main/editor/markdown/mobile-selection-context.ts
constant PRIMARY_ACTIONS (line 1) | const PRIMARY_ACTIONS = {
type TextSelectionContextInput (line 7) | type TextSelectionContextInput = {
type ImageSelectionContextInput (line 14) | type ImageSelectionContextInput = {
type TableSelectionContextInput (line 21) | type TableSelectionContextInput = {
type MobileSelectionContextInput (line 26) | type MobileSelectionContextInput =
function getMobileContextPrimaryActions (line 33) | function getMobileContextPrimaryActions(mode: keyof typeof PRIMARY_ACTIO...
function buildMobileSelectionContext (line 37) | function buildMobileSelectionContext(input: MobileSelectionContextInput) {
function isMobileSelectionContextStale (line 82) | function isMobileSelectionContextStale(
FILE: src/app/core/main/editor/markdown/outline.tsx
type HeadingItem (line 10) | interface HeadingItem {
type OutlineProps (line 18) | interface OutlineProps {
function Outline (line 24) | function Outline({ editor, isOpen, position = 'right' }: OutlineProps) {
FILE: src/app/core/main/editor/markdown/quote-mark.ts
type QuoteOptions (line 3) | interface QuoteOptions {
type Commands (line 8) | interface Commands<ReturnType> {
method addOptions (line 19) | addOptions() {
method addAttributes (line 25) | addAttributes() {
method parseHTML (line 33) | parseHTML() {
method renderHTML (line 41) | renderHTML({ HTMLAttributes }) {
method addCommands (line 49) | addCommands() {
FILE: src/app/core/main/editor/markdown/quote-session.ts
function shouldRestorePendingQuote (line 3) | function shouldRestorePendingQuote(
FILE: src/app/core/main/editor/markdown/search-navigation.ts
function getResultIndexToFocus (line 1) | function getResultIndexToFocus(
FILE: src/app/core/main/editor/markdown/search-replace-panel.tsx
type SearchAndReplaceStorage (line 11) | interface SearchAndReplaceStorage {
type SearchReplacePanelProps (line 19) | interface SearchReplacePanelProps {
function getSearchAndReplaceStorage (line 26) | function getSearchAndReplaceStorage(editor: Editor): SearchAndReplaceSto...
function setSearchTerm (line 32) | function setSearchTerm(editor: Editor, term: string) {
function setReplaceTerm (line 44) | function setReplaceTerm(editor: Editor, term: string) {
function setSearchCaseSensitive (line 55) | function setSearchCaseSensitive(editor: Editor, value: boolean) {
function nextResult (line 66) | function nextResult(editor: Editor) {
function prevResult (line 94) | function prevResult(editor: Editor) {
function replaceCurrent (line 122) | function replaceCurrent(editor: Editor) {
function replaceAll (line 138) | function replaceAll(editor: Editor) {
function clearSearch (line 159) | function clearSearch(editor: Editor) {
function SearchReplacePanel (line 173) | function SearchReplacePanel({ editor, open, onOpenChange }: SearchReplac...
FILE: src/app/core/main/editor/markdown/slash-command/index.ts
type Commands (line 9) | interface Commands<ReturnType> {
method addOptions (line 19) | addOptions() {
method addProseMirrorPlugins (line 31) | addProseMirrorPlugins() {
method addCommands (line 43) | addCommands() {
FILE: src/app/core/main/editor/markdown/slash-command/slash-command-portal.tsx
type MenuState (line 8) | interface MenuState {
constant MENU_MAX_HEIGHT (line 16) | const MENU_MAX_HEIGHT = 256 // max-h-64 = 256px
constant MENU_MIN_WIDTH (line 17) | const MENU_MIN_WIDTH = 144 // min-w-36 = 144px
constant MARGIN (line 18) | const MARGIN = 8
function calculateMenuPosition (line 20) | function calculateMenuPosition(clientRect: DOMRect): { top: number; left...
FILE: src/app/core/main/editor/markdown/slash-command/slash-menu.tsx
type SlashMenuProps (line 9) | interface SlashMenuProps {
type SlashMenuRef (line 15) | interface SlashMenuRef {
FILE: src/app/core/main/editor/markdown/slash-command/suggestion.tsx
type SlashCommandItem (line 32) | interface SlashCommandItem {
type SlashCommandTranslations (line 64) | interface SlashCommandTranslations {
function filterItems (line 130) | function filterItems(items: SlashCommandItem[], query: string): SlashCom...
function findSlashMatch (line 496) | function findSlashMatch(config: {
function setMenuKeyDownHandler (line 536) | function setMenuKeyDownHandler(handler: ((props: { event: KeyboardEvent ...
FILE: src/app/core/main/editor/markdown/sync/conflict-dialog.tsx
type ConflictDialogProps (line 18) | interface ConflictDialogProps {
function computeDiff (line 27) | function computeDiff(oldText: string, newText: string): { type: 'equal' ...
function ConflictDialog (line 69) | function ConflictDialog({
FILE: src/app/core/main/editor/markdown/sync/history-sheet.tsx
type CommitInfo (line 19) | interface CommitInfo {
type SyncProvider (line 28) | type SyncProvider = 'github' | 'gitee' | 'gitlab' | 'gitea'
type HistorySheetProps (line 30) | interface HistorySheetProps {
function HistorySheet (line 34) | function HistorySheet({ editor }: HistorySheetProps) {
FILE: src/app/core/main/editor/markdown/sync/pull-button.tsx
type PullButtonProps (line 15) | interface PullButtonProps {
type PullStatus (line 20) | type PullStatus = 'idle' | 'checking' | 'update-available' | 'pulling' |...
function PullButton (line 22) | function PullButton({ editor }: PullButtonProps) {
FILE: src/app/core/main/editor/markdown/sync/sync-button.tsx
function SyncButton (line 15) | function SyncButton() {
FILE: src/app/core/main/editor/markdown/sync/sync-tools.tsx
type SyncToolsProps (line 11) | interface SyncToolsProps {
function SyncTools (line 15) | function SyncTools({ editor }: SyncToolsProps) {
FILE: src/app/core/main/editor/markdown/table-toolbar.tsx
type TableToolbarProps (line 15) | interface TableToolbarProps {
function TableToolbar (line 19) | function TableToolbar({ editor }: TableToolbarProps) {
FILE: src/app/core/main/editor/markdown/tiptap-editor.tsx
function lineToPosition (line 70) | function lineToPosition(doc: ProseMirrorNode, line: number): number {
method addProseMirrorPlugins (line 107) | addProseMirrorPlugins() {
function looksLikeMarkdown (line 138) | function looksLikeMarkdown(text: string): boolean {
type TipTapEditorProps (line 152) | interface TipTapEditorProps {
type MobileSelectionContext (line 168) | type MobileSelectionContext =
type MobileSheetMode (line 190) | type MobileSheetMode = 'ai' | 'image-src' | 'image-alt' | 'table-align' ...
function TipTapEditor (line 192) | function TipTapEditor({
FILE: src/app/core/main/editor/onboarding-state.ts
type OnboardingStepId (line 1) | type OnboardingStepId = 'create-record' | 'organize-note' | 'ai-polish'
type OnboardingCompletionFeedbackMode (line 2) | type OnboardingCompletionFeedbackMode = 'inline' | 'dialog'
type OnboardingProgress (line 4) | interface OnboardingProgress {
constant ONBOARDING_STEP_ORDER (line 9) | const ONBOARDING_STEP_ORDER: OnboardingStepId[] = [
function createDefaultOnboardingProgress (line 15) | function createDefaultOnboardingProgress(): OnboardingProgress {
function normalizeOnboardingProgress (line 26) | function normalizeOnboardingProgress(value: unknown): OnboardingProgress {
function markOnboardingStepDone (line 48) | function markOnboardingStepDone(
function getActiveOnboardingStep (line 61) | function getActiveOnboardingStep(progress: OnboardingProgress): Onboardi...
function getNextOnboardingStep (line 65) | function getNextOnboardingStep(
function isOnboardingComplete (line 76) | function isOnboardingComplete(progress: OnboardingProgress): boolean {
function shouldShowOnboardingTasks (line 80) | function shouldShowOnboardingTasks(progress: OnboardingProgress): boolean {
function getCompletionFeedbackMode (line 84) | function getCompletionFeedbackMode(
FILE: src/app/core/main/editor/tab-bar.tsx
type TabInfo (line 36) | interface TabInfo {
type TabBarProps (line 43) | interface TabBarProps {
function SortableTabWithMenu (line 57) | function SortableTabWithMenu({
function TabBar (line 207) | function TabBar({
FILE: src/app/core/main/editor/unsupported-file.tsx
type FileMetadata (line 11) | interface FileMetadata {
type UnsupportedFileProps (line 17) | interface UnsupportedFileProps {
function UnsupportedFile (line 21) | function UnsupportedFile({ filePath }: UnsupportedFileProps) {
FILE: src/app/core/main/file/file-actions.tsx
function FileActions (line 15) | function FileActions() {
FILE: src/app/core/main/file/file-footer.tsx
function FileFooter (line 23) | function FileFooter() {
FILE: src/app/core/main/file/file-item.tsx
type Platform (line 33) | type Platform = 'macos' | 'windows' | 'linux' | 'unknown'
function FileItem (line 35) | function FileItem({ item, focusSidebar }: { item: DirTree; focusSidebar?...
FILE: src/app/core/main/file/file-manager.tsx
function filterFileTree (line 12) | function filterFileTree(tree: DirTree[], showCloud: boolean): DirTree[] {
function Tree (line 23) | function Tree({ item, focusSidebar }: { item: DirTree; focusSidebar: () ...
function FileManager (line 56) | function FileManager({ focusSidebar }: { focusSidebar: () => void }) {
FILE: src/app/core/main/file/file-toolbar.tsx
function FileToolbar (line 19) | function FileToolbar() {
FILE: src/app/core/main/file/folder-item/copy-folder.tsx
type CopyFolderProps (line 10) | interface CopyFolderProps {
function CopyFolder (line 15) | function CopyFolder({ item, shortcut }: CopyFolderProps) {
FILE: src/app/core/main/file/folder-item/cut-folder.tsx
type CutFolderProps (line 10) | interface CutFolderProps {
function CutFolder (line 15) | function CutFolder({ item, shortcut }: CutFolderProps) {
FILE: src/app/core/main/file/folder-item/delete-folder.tsx
type DeleteFolderProps (line 13) | interface DeleteFolderProps {
function DeleteFolder (line 18) | function DeleteFolder({ item, shortcut }: DeleteFolderProps) {
FILE: src/app/core/main/file/folder-item/duplicate-folder.tsx
type DuplicateFolderProps (line 9) | interface DuplicateFolderProps {
function DuplicateFolder (line 14) | function DuplicateFolder({ item, shortcut }: DuplicateFolderProps) {
FILE: src/app/core/main/file/folder-item/folder-vector-menu.tsx
type FolderVectorMenuProps (line 11) | interface FolderVectorMenuProps {
function FolderVectorMenu (line 15) | function FolderVectorMenu({ item }: FolderVectorMenuProps) {
FILE: src/app/core/main/file/folder-item/index.tsx
function FolderItem (line 32) | function FolderItem({ item, focusSidebar }: { item: DirTree; focusSideba...
FILE: src/app/core/main/file/folder-item/new-file.tsx
type NewFileProps (line 8) | interface NewFileProps {
function NewFile (line 12) | function NewFile({ item }: NewFileProps) {
FILE: src/app/core/main/file/folder-item/new-folder.tsx
type NewFolderProps (line 7) | interface NewFolderProps {
function NewFolder (line 11) | function NewFolder({ item }: NewFolderProps) {
FILE: src/app/core/main/file/folder-item/paste-in-folder.tsx
type PasteInFolderProps (line 10) | interface PasteInFolderProps {
function PasteInFolder (line 15) | function PasteInFolder({ item, shortcut }: PasteInFolderProps) {
FILE: src/app/core/main/file/folder-item/paste-into-folder.js
function pasteIntoFolder (line 9) | async function pasteIntoFolder({
FILE: src/app/core/main/file/folder-item/paste-target.js
function getPasteTargetDirectory (line 1) | function getPasteTargetDirectory(folderPath) {
FILE: src/app/core/main/file/folder-item/rename-folder.tsx
type RenameFolderProps (line 8) | interface RenameFolderProps {
function RenameFolder (line 15) | function RenameFolder({ item, onStartRename, shortcut }: RenameFolderPro...
FILE: src/app/core/main/file/folder-item/sync-folder.tsx
function SyncFolder (line 9) | function SyncFolder({ item }: { item: DirTree }) {
FILE: src/app/core/main/file/folder-item/view-directory.tsx
type ViewDirectoryProps (line 9) | interface ViewDirectoryProps {
function ViewDirectory (line 13) | function ViewDirectory({ item }: ViewDirectoryProps) {
FILE: src/app/core/main/file/index.tsx
type Platform (line 11) | type Platform = 'macos' | 'windows' | 'linux' | 'unknown'
function useFileManagerShortcuts (line 17) | function useFileManagerShortcuts() {
function FileSidebar (line 245) | function FileSidebar() {
FILE: src/app/core/main/file/mobile-action-menu.tsx
type MobileActionMenuProps (line 11) | interface MobileActionMenuProps {
function MobileActionMenu (line 16) | function MobileActionMenu({ children, className }: MobileActionMenuProps) {
FILE: src/app/core/main/file/root-drop.js
function sanitizeDroppedFileName (line 1) | function sanitizeDroppedFileName(fileName) {
function writeDroppedFileToRoot (line 5) | async function writeDroppedFileToRoot(deps, payload) {
FILE: src/app/core/main/file/vector-knowledge-menu.tsx
type VectorKnowledgeMenuProps (line 12) | interface VectorKnowledgeMenuProps {
function VectorKnowledgeMenu (line 18) | function VectorKnowledgeMenu({ item, hasVector, onVectorUpdated }: Vecto...
FILE: src/app/core/main/file/workspace-selector.tsx
function WorkspaceSelector (line 10) | function WorkspaceSelector() {
FILE: src/app/core/main/left-sidebar.tsx
constant SIDEBAR_TABS (line 14) | const SIDEBAR_TABS = [
function LeftSidebar (line 19) | function LeftSidebar() {
FILE: src/app/core/main/mark/clipboard.tsx
function Clipboard (line 20) | function Clipboard() {
FILE: src/app/core/main/mark/control-file.tsx
function ControlFile (line 33) | function ControlFile() {
FILE: src/app/core/main/mark/control-image.tsx
function ControlImage (line 20) | function ControlImage() {
FILE: src/app/core/main/mark/control-link.tsx
function ControlLink (line 40) | function ControlLink() {
FILE: src/app/core/main/mark/control-recording.tsx
function ControlRecording (line 23) | function ControlRecording() {
FILE: src/app/core/main/mark/control-scan.tsx
function ControlScan (line 38) | function ControlScan() {
FILE: src/app/core/main/mark/control-text.tsx
function ControlText (line 39) | function ControlText() {
FILE: src/app/core/main/mark/control-todo.tsx
function ControlTodo (line 34) | function ControlTodo() {
FILE: src/app/core/main/mark/image-gallery.tsx
type ImageGalleryProps (line 27) | interface ImageGalleryProps {
function ImageItem (line 32) | function ImageItem({ mark }: { mark: Mark }) {
function ImageGallery (line 171) | function ImageGallery({ marks }: ImageGalleryProps) {
FILE: src/app/core/main/mark/index.tsx
function NoteSidebar (line 15) | function NoteSidebar() {
FILE: src/app/core/main/mark/mark-actions.tsx
function MarkActions (line 11) | function MarkActions() {
FILE: src/app/core/main/mark/mark-empty.tsx
function MarkEmpty (line 4) | function MarkEmpty() {
FILE: src/app/core/main/mark/mark-filter-popover.tsx
constant TIME_OPTIONS (line 16) | const TIME_OPTIONS: RecordTimePreset[] = ['all', 'today', 'last7Days', '...
function MarkFilterPopover (line 18) | function MarkFilterPopover() {
FILE: src/app/core/main/mark/mark-filters.mjs
constant DAY_IN_MS (line 1) | const DAY_IN_MS = 24 * 60 * 60 * 1000
constant VALID_TYPES (line 2) | const VALID_TYPES = new Set(['scan', 'text', 'image', 'link', 'file', 'r...
constant VALID_TIME_PRESETS (line 3) | const VALID_TIME_PRESETS = new Set(['all', 'today', 'last7Days', 'last30...
function normalizeText (line 5) | function normalizeText(value) {
function matchesTimePreset (line 9) | function matchesTimePreset(createdAt, timePreset, now) {
function matchesSearch (line 41) | function matchesSearch(mark, search) {
function normalizeRecordFilters (line 53) | function normalizeRecordFilters(filters) {
function buildRecordFilterSummary (line 70) | function buildRecordFilterSummary(filters) {
function filterMarks (line 87) | function filterMarks(marks, filters) {
FILE: src/app/core/main/mark/mark-header.tsx
function MarkHeader (line 39) | function MarkHeader() {
type SortableToolbarItemProps (line 137) | interface SortableToolbarItemProps {
function SortableToolbarItem (line 141) | function SortableToolbarItem({ id }: SortableToolbarItemProps) {
FILE: src/app/core/main/mark/mark-item.tsx
type MarkItemVariant (line 147) | type MarkItemVariant = 'list' | 'compact' | 'cards'
FILE: src/app/core/main/mark/mark-list-card-view.tsx
function MarkListCardView (line 6) | function MarkListCardView({ marks }: { marks: Mark[] }) {
FILE: src/app/core/main/mark/mark-list-compact-view.tsx
function MarkListCompactView (line 6) | function MarkListCompactView({ marks }: { marks: Mark[] }) {
FILE: src/app/core/main/mark/mark-list-default-view.tsx
function MarkListDefaultView (line 6) | function MarkListDefaultView({ marks }: { marks: Mark[] }) {
FILE: src/app/core/main/mark/mark-list-item-content.tsx
type ParsedTodoMark (line 4) | type ParsedTodoMark = {
type MarkListItemContent (line 11) | type MarkListItemContent = {
constant DEFAULT_TODO (line 19) | const DEFAULT_TODO: ParsedTodoMark = {
function compactText (line 26) | function compactText(value?: string) {
function splitTitleAndPreview (line 30) | function splitTitleAndPreview(value?: string) {
function parseTodoMarkContent (line 42) | function parseTodoMarkContent(mark: Mark): ParsedTodoMark {
function getMarkListItemContent (line 59) | function getMarkListItemContent(mark: Mark): MarkListItemContent {
FILE: src/app/core/main/mark/mark-loading.tsx
function MarkLoading (line 7) | function MarkLoading({mark}: {mark: MarkQueue}){
FILE: src/app/core/main/mark/mark-mobile-actions.tsx
type MarkMobileActionsProps (line 20) | interface MarkMobileActionsProps {
function MarkMobileActions (line 37) | function MarkMobileActions({
FILE: src/app/core/main/mark/mark-toolbar.tsx
function MarkToolbar (line 9) | function MarkToolbar() {
FILE: src/app/core/main/mark/mark-type-meta.ts
constant MARK_TYPE_OPTIONS (line 4) | const MARK_TYPE_OPTIONS: Mark["type"][] = ['text', 'recording', 'scan', ...
type MarkTypeTone (line 6) | type MarkTypeTone = {
constant MARK_TYPE_TONES (line 12) | const MARK_TYPE_TONES: Record<Mark["type"], MarkTypeTone> = {
function getMarkTypeChipClasses (line 50) | function getMarkTypeChipClasses(type: Mark["type"], active: boolean) {
function getMarkTypeListBadgeClasses (line 54) | function getMarkTypeListBadgeClasses(type: Mark["type"], textSize?: stri...
FILE: src/app/core/main/mark/mark-view-mode-toggle.tsx
type MarkViewModeToggleProps (line 9) | type MarkViewModeToggleProps = {
constant VIEW_MODE_ITEMS (line 14) | const VIEW_MODE_ITEMS: Array<{
function MarkViewModeToggle (line 23) | function MarkViewModeToggle({ value, onChange }: MarkViewModeToggleProps) {
FILE: src/app/core/main/mark/mark-view-mode.mjs
constant RECORD_VIEW_MODES (line 1) | const RECORD_VIEW_MODES = ["list", "compact", "cards"]
function normalizeRecordViewMode (line 3) | function normalizeRecordViewMode(value) {
FILE: src/app/core/main/mark/organize-notes.tsx
type OrganizeNotesProps (line 36) | interface OrganizeNotesProps {
function initGenTemplates (line 56) | async function initGenTemplates() {
FILE: src/app/core/main/mark/organize-onboarding.ts
function shouldEmitOrganizeOnboardingComplete (line 1) | function shouldEmitOrganizeOnboardingComplete({
FILE: src/app/core/main/mark/tag-item.tsx
function ItemIcon (line 16) | function ItemIcon({ isLocked=false, isPin=false }) {
function ItemContent (line 28) | function ItemContent({ value, isEditing, onChange }: { value: string, is...
function TagItem (line 51) | function TagItem(
FILE: src/app/core/main/mark/tag-manage.tsx
function AccordionItemWrapper (line 60) | function AccordionItemWrapper({
function SortableTagItem (line 100) | function SortableTagItem({ tag, children }: { tag: Tag; children: React....
function TagManage (line 129) | function TagManage() {
FILE: src/app/core/main/mark/tag-mobile-actions.tsx
type TagMobileActionsProps (line 14) | interface TagMobileActionsProps {
function TagMobileActions (line 21) | function TagMobileActions({ tag, onRename, onDelete, isEditing }: TagMob...
FILE: src/app/core/main/mark/todo-edit-button.tsx
type TodoEditTriggerProps (line 8) | type TodoEditTriggerProps = {
function TodoEditTrigger (line 14) | function TodoEditTrigger({ mark, className, children }: TodoEditTriggerP...
FILE: src/app/core/main/mark/todo-edit-dialog.tsx
type Priority (line 22) | type Priority = 'low' | 'medium' | 'high'
type TodoData (line 24) | interface TodoData {
type TodoEditDialogProps (line 31) | interface TodoEditDialogProps {
function TodoEditDialog (line 37) | function TodoEditDialog({ mark, open, onOpenChange }: TodoEditDialogProp...
FILE: src/app/core/main/mark/todo-form.tsx
type Priority (line 8) | type Priority = 'low' | 'medium' | 'high'
type TodoFormData (line 10) | interface TodoFormData {
type TodoFormProps (line 16) | interface TodoFormProps {
function TodoForm (line 26) | function TodoForm({
FILE: src/app/core/main/mark/todo-item-content.tsx
type TodoData (line 18) | interface TodoData {
function TodoItemContent (line 25) | function TodoItemContent({ mark }: { mark: Mark }) {
FILE: src/app/core/main/page.tsx
function getDefaultLayout (line 17) | function getDefaultLayout(layoutKey: string) {
function ResizableWrapper (line 58) | function ResizableWrapper() {
function Page (line 237) | function Page() {
FILE: src/app/core/setting/about/page.tsx
function AboutPage (line 6) | function AboutPage() {
FILE: src/app/core/setting/about/setting-about.tsx
function SettingAbout (line 10) | function SettingAbout({id, icon}: {id: string, icon?: React.ReactNode}) {
function AboutItem (line 70) | function AboutItem({url, title, desc, icon, buttonName}: {url: string, t...
FILE: src/app/core/setting/about/updater.tsx
function Updater (line 15) | function Updater() {
FILE: src/app/core/setting/ai/create.tsx
type CreateConfigProps (line 32) | interface CreateConfigProps {
function CreateConfigDialog (line 38) | function CreateConfigDialog({ open, setOpen, onConfigCreated }: { open: ...
function CreateConfig (line 130) | function CreateConfig({ hasCustomModels = false, onConfigCreated }: Crea...
function ProviderItem (line 169) | function ProviderItem({item, onClick}: {item: AiConfig, onClick: (model:...
FILE: src/app/core/setting/ai/default-models.tsx
function DefaultModelsSection (line 10) | function DefaultModelsSection() {
FILE: src/app/core/setting/ai/model-card.tsx
type ModelCardProps (line 23) | interface ModelCardProps {
function ModelCard (line 30) | function ModelCard({ modelConfig, aiConfig, onUpdate, onDelete }: ModelC...
FILE: src/app/core/setting/ai/modelSelect.tsx
function ModelSelect (line 22) | function ModelSelect(
FILE: src/app/core/setting/ai/page.tsx
function AiPage (line 32) | function AiPage() {
FILE: src/app/core/setting/audio/page.tsx
function AudioPage (line 7) | function AudioPage() {
FILE: src/app/core/setting/audio/setting.tsx
function Setting (line 12) | function Setting() {
FILE: src/app/core/setting/chat/condense-settings.tsx
function CondenseSettings (line 17) | function CondenseSettings() {
FILE: src/app/core/setting/chat/page.tsx
function ChatSettingsPage (line 10) | function ChatSettingsPage() {
FILE: src/app/core/setting/chat/primary-model-settings.tsx
function PrimaryModelSettings (line 15) | function PrimaryModelSettings() {
FILE: src/app/core/setting/chat/toolbar-settings.tsx
constant TOOL_CONFIGS (line 31) | const TOOL_CONFIGS = {
type SortableItemProps (line 60) | interface SortableItemProps {
function SortableItem (line 67) | function SortableItem({ item, config, onToggle, t }: SortableItemProps) {
function ToolbarSettings (line 114) | function ToolbarSettings() {
FILE: src/app/core/setting/components/default-models-settings.tsx
type DefaultModelsSettingsProps (line 15) | interface DefaultModelsSettingsProps {
function DefaultModelsSettings (line 19) | function DefaultModelsSettings({ type }: DefaultModelsSettingsProps) {
FILE: src/app/core/setting/components/model-select.tsx
type GroupedModel (line 28) | interface GroupedModel {
function ModelSelect (line 34) | function ModelSelect({modelKey}: {modelKey: string}) {
FILE: src/app/core/setting/components/setting-base.tsx
function SettingType (line 1) | function SettingType(
function FormItem (line 17) | function FormItem({title, desc, children}: { title: string, desc?: strin...
FILE: src/app/core/setting/components/setting-tab.tsx
function SettingTab (line 10) | function SettingTab() {
FILE: src/app/core/setting/components/upload-store.tsx
function UploadStore (line 19) | function UploadStore() {
FILE: src/app/core/setting/config.tsx
type ModelType (line 108) | type ModelType = 'chat' | 'image' | 'video' | 'tts' | 'stt' | 'embedding...
type ModelConfig (line 110) | interface ModelConfig {
type AiConfig (line 120) | interface AiConfig {
type Model (line 139) | interface Model {
FILE: src/app/core/setting/defaultModel/page.tsx
function DefaultModelPage (line 7) | function DefaultModelPage() {
FILE: src/app/core/setting/defaultModel/setting.tsx
function Setting (line 6) | function Setting() {
FILE: src/app/core/setting/dev/page.tsx
function DevPage (line 6) | function DevPage() {
FILE: src/app/core/setting/dev/set-config.tsx
function SetConfig (line 12) | function SetConfig() {
FILE: src/app/core/setting/dev/setting-dev.tsx
function SettingDev (line 15) | function SettingDev({id, icon}: {id: string, icon?: React.ReactNode}) {
FILE: src/app/core/setting/editor/centered-content.tsx
function CenteredContent (line 8) | function CenteredContent() {
FILE: src/app/core/setting/editor/commit.tsx
function Commit (line 15) | function Commit() {
FILE: src/app/core/setting/editor/completion.tsx
function Completion (line 15) | function Completion() {
FILE: src/app/core/setting/editor/outline.tsx
function Outline (line 15) | function Outline() {
FILE: src/app/core/setting/editor/page.tsx
function EditorSettingPage (line 10) | function EditorSettingPage() {
FILE: src/app/core/setting/editor/show-undo-redo.tsx
function ShowUndoRedo (line 8) | function ShowUndoRedo() {
FILE: src/app/core/setting/file/page.tsx
function SettingFilePage (line 8) | function SettingFilePage() {
FILE: src/app/core/setting/file/setting-assets.tsx
function SettingAssets (line 7) | function SettingAssets() {
FILE: src/app/core/setting/file/setting-workspace.tsx
function SettingWorkspace (line 16) | function SettingWorkspace() {
FILE: src/app/core/setting/general/interface-settings/content-text-scale.tsx
function ContentTextScaleSettings (line 8) | function ContentTextScaleSettings() {
FILE: src/app/core/setting/general/interface-settings/custom-theme.tsx
type ColorScheme (line 19) | interface ColorScheme {
function CustomThemeSettings (line 42) | function CustomThemeSettings() {
FILE: src/app/core/setting/general/interface-settings/file-manager-text-size.tsx
function FileManagerTextSizeSettings (line 16) | function FileManagerTextSizeSettings() {
FILE: src/app/core/setting/general/interface-settings/index.tsx
function InterfaceSettings (line 10) | function InterfaceSettings() {
FILE: src/app/core/setting/general/interface-settings/language.tsx
function LanguageSettings (line 15) | function LanguageSettings() {
FILE: src/app/core/setting/general/interface-settings/record-text-size.tsx
function RecordTextSizeSettings (line 16) | function RecordTextSizeSettings() {
FILE: src/app/core/setting/general/interface-settings/scale.tsx
function ScaleSettings (line 10) | function ScaleSettings() {
FILE: src/app/core/setting/general/interface-settings/theme-color-picker.tsx
type ThemeColorPickerProps (line 9) | interface ThemeColorPickerProps {
function ThemeColorPicker (line 32) | function ThemeColorPicker({ colors, onColorChange, t }: ThemeColorPicker...
type ColorInputProps (line 85) | interface ColorInputProps {
function ColorInput (line 92) | function ColorInput({ label, value, defaultColor, onChange }: ColorInput...
FILE: src/app/core/setting/general/interface-settings/theme-presets.tsx
type ColorScheme (line 5) | interface ColorScheme {
type ThemePresetsProps (line 29) | interface ThemePresetsProps {
function ThemePresets (line 35) | function ThemePresets({ onApplyPreset, onResetDefault, t }: ThemePresets...
FILE: src/app/core/setting/general/interface-settings/theme.tsx
function ThemeSettings (line 9) | function ThemeSettings() {
FILE: src/app/core/setting/general/page.tsx
function GeneralSettingsPage (line 8) | function GeneralSettingsPage() {
FILE: src/app/core/setting/general/tool-settings.tsx
function ToolSettings (line 5) | function ToolSettings() {
FILE: src/app/core/setting/imageHosting/github.tsx
function GithubImageHosting (line 23) | function GithubImageHosting() {
FILE: src/app/core/setting/imageHosting/page.tsx
function ImageHostingPage (line 22) | function ImageHostingPage() {
FILE: src/app/core/setting/imageHosting/picgo.tsx
constant DEFAULT_URL (line 10) | const DEFAULT_URL = 'http://127.0.0.1:36677'
function PicgoImageHosting (line 12) | function PicgoImageHosting() {
FILE: src/app/core/setting/imageHosting/s3.tsx
type S3Config (line 15) | interface S3Config {
function S3ImageHosting (line 25) | function S3ImageHosting() {
FILE: src/app/core/setting/imageHosting/setting-switch.tsx
function SettingSwitch (line 6) | function SettingSwitch() {
FILE: src/app/core/setting/imageHosting/smms.tsx
constant CREATE_TOKEN_URL (line 13) | const CREATE_TOKEN_URL = 'https://sm.ms/home/apitoken'
function SMMSImageHosting (line 15) | function SMMSImageHosting() {
FILE: src/app/core/setting/imageMethod/ocr.tsx
function OcrSetting (line 10) | function OcrSetting() {
FILE: src/app/core/setting/imageMethod/page.tsx
function ImageMethod (line 17) | function ImageMethod() {
FILE: src/app/core/setting/imageMethod/setDefault.tsx
function SetDefault (line 7) | function SetDefault({type}: {type: 'ocr' | 'vlm'}) {
FILE: src/app/core/setting/imageMethod/vlm.tsx
function VlmSetting (line 7) | function VlmSetting() {
FILE: src/app/core/setting/layout.tsx
function SettingLayout (line 5) | function SettingLayout({
FILE: src/app/core/setting/mcp/connection-test.tsx
type ConnectionTestProps (line 10) | interface ConnectionTestProps {
function ConnectionTest (line 14) | function ConnectionTest({ server }: ConnectionTestProps) {
FILE: src/app/core/setting/mcp/json-import-dialog.tsx
type JsonImportDialogProps (line 32) | interface JsonImportDialogProps {
function JsonImportDialog (line 37) | function JsonImportDialog({ open, onOpenChange }: JsonImportDialogProps) {
FILE: src/app/core/setting/mcp/page.tsx
function McpSettingPage (line 12) | function McpSettingPage() {
FILE: src/app/core/setting/mcp/runtime-environment-card.tsx
type RuntimeDefinition (line 31) | type RuntimeDefinition = {
constant RUNTIMES (line 37) | const RUNTIMES: RuntimeDefinition[] = [
function RuntimeEnvironmentCard (line 44) | function RuntimeEnvironmentCard() {
FILE: src/app/core/setting/mcp/server-config-dialog.tsx
type ServerConfigDialogProps (line 40) | interface ServerConfigDialogProps {
function ServerConfigDialog (line 46) | function ServerConfigDialog({
FILE: src/app/core/setting/mcp/server-list.tsx
function ServerList (line 38) | function ServerList() {
FILE: src/app/core/setting/mcp/tool-browser.tsx
function ToolBrowser (line 13) | function ToolBrowser() {
FILE: src/app/core/setting/memories/page.tsx
function MemoriesSettingsPage (line 8) | function MemoriesSettingsPage() {
FILE: src/app/core/setting/page.tsx
function Page (line 7) | function Page() {
FILE: src/app/core/setting/prompt/page.tsx
function PromptSetting (line 6) | function PromptSetting() {
FILE: src/app/core/setting/prompt/setting-prompt.tsx
function SettingPrompt (line 37) | function SettingPrompt({id, icon}: {id: string, icon?: React.ReactNode}) {
FILE: src/app/core/setting/rag/model-setting.tsx
function ModelSetting (line 6) | function ModelSetting() {
FILE: src/app/core/setting/rag/page.tsx
function PromptSetting (line 9) | function PromptSetting() {
FILE: src/app/core/setting/rag/settings.tsx
function Settings (line 13) | function Settings() {
FILE: src/app/core/setting/readAloud/page.tsx
function ReadAloudPage (line 7) | function ReadAloudPage() {
FILE: src/app/core/setting/readAloud/setting.tsx
function Setting (line 12) | function Setting() {
FILE: src/app/core/setting/record/model-settings.tsx
function ModelSettings (line 15) | function ModelSettings() {
FILE: src/app/core/setting/record/page.tsx
function RecordSettingPage (line 9) | function RecordSettingPage() {
FILE: src/app/core/setting/record/toolbar-settings.tsx
constant TOOL_CONFIGS (line 33) | const TOOL_CONFIGS = {
type SortableItemProps (line 72) | interface SortableItemProps {
function SortableItem (line 79) | function SortableItem({ item, config, onToggle, t }: SortableItemProps) {
function ToolbarSettings (line 126) | function ToolbarSettings() {
FILE: src/app/core/setting/shortcuts/page.tsx
function ShortcutsPage (line 10) | function ShortcutsPage() {
FILE: src/app/core/setting/shortcuts/shorcut-input.tsx
function ShortcutsInput (line 12) | function ShortcutsInput({
FILE: src/app/core/setting/skills/components/global-skills-manager.tsx
function GlobalSkillsManager (line 13) | function GlobalSkillsManager() {
FILE: src/app/core/setting/skills/components/project-skills-list.tsx
function ProjectSkillsList (line 9) | function ProjectSkillsList() {
FILE: src/app/core/setting/skills/components/skill-card.tsx
type SkillCardProps (line 23) | interface SkillCardProps {
function SkillCard (line 28) | function SkillCard({ skill, onRefresh }: SkillCardProps) {
FILE: src/app/core/setting/skills/components/skills-settings.tsx
function SkillsSettings (line 5) | function SkillsSettings() {
FILE: src/app/core/setting/skills/page.tsx
function SkillsSettingPage (line 10) | function SkillsSettingPage() {
FILE: src/app/core/setting/sync/components/sync-platform-card.tsx
type SyncPlatformConfig (line 14) | interface SyncPlatformConfig {
type SyncPlatformCardProps (line 23) | interface SyncPlatformCardProps {
function SyncPlatformCard (line 37) | function SyncPlatformCard({
function StatusBadge (line 203) | function StatusBadge({ state }: { state: SyncStateEnum }) {
FILE: src/app/core/setting/sync/gitea-sync.tsx
function GiteaSync (line 22) | function GiteaSync() {
FILE: src/app/core/setting/sync/gitee-sync.tsx
function GiteeSync (line 20) | function GiteeSync() {
FILE: src/app/core/setting/sync/github-sync.tsx
constant GITHUB_CONFIG (line 15) | const GITHUB_CONFIG = {
function GithubSync (line 24) | function GithubSync() {
FILE: src/app/core/setting/sync/gitlab-sync.tsx
function GitlabSync (line 22) | function GitlabSync() {
FILE: src/app/core/setting/sync/page.tsx
function SyncPage (line 22) | function SyncPage() {
FILE: src/app/core/setting/sync/s3-sync.tsx
function S3Sync (line 15) | function S3Sync() {
FILE: src/app/core/setting/sync/webdav-sync.tsx
function WebDAVSync (line 15) | function WebDAVSync() {
FILE: src/app/core/setting/template/page.tsx
function TemplatePage (line 6) | function TemplatePage() {
FILE: src/app/core/setting/template/setting-template.tsx
function SettingTemplate (line 36) | function SettingTemplate({id, icon}: {id: string, icon?: React.ReactNode...
FILE: src/app/error.tsx
function Error (line 6) | function Error({
FILE: src/app/global-error.tsx
function GlobalError (line 6) | function GlobalError({
FILE: src/app/layout.tsx
function RootLayout (line 11) | function RootLayout({
FILE: src/app/mobile/chat/components/chat-attachments-drawer.tsx
type ChatAttachmentsDrawerProps (line 20) | interface ChatAttachmentsDrawerProps {
function ChatAttachmentsDrawer (line 26) | function ChatAttachmentsDrawer({
FILE: src/app/mobile/chat/components/chat-settings-drawer.tsx
function ChatSettingsDrawer (line 17) | function ChatSettingsDrawer() {
FILE: src/app/mobile/chat/components/chat-tools-drawer.tsx
function ChatToolsDrawer (line 18) | function ChatToolsDrawer() {
FILE: src/app/mobile/chat/components/clear-chat.tsx
function MobileClearChat (line 9) | function MobileClearChat() {
FILE: src/app/mobile/chat/components/clear-context.tsx
function MobileClearContext (line 9) | function MobileClearContext() {
FILE: src/app/mobile/chat/components/clipboard-toggle.tsx
function ClipboardToggle (line 11) | function ClipboardToggle() {
FILE: src/app/mobile/chat/components/mcp-selector.tsx
function McpListContent (line 19) | function McpListContent() {
function McpSelector (line 94) | function McpSelector() {
FILE: src/app/mobile/chat/components/mobile-chat-header.tsx
function formatRelativeTime (line 25) | function formatRelativeTime(timestamp: number, locale: string): string {
function MobileChatHeader (line 30) | function MobileChatHeader() {
FILE: src/app/mobile/chat/components/model-selector.tsx
type GroupedModel (line 19) | interface GroupedModel {
function ModelListContent (line 25) | function ModelListContent({
function ModelSelector (line 75) | function ModelSelector() {
FILE: src/app/mobile/chat/components/new-chat.tsx
function MobileNewChat (line 8) | function MobileNewChat() {
FILE: src/app/mobile/chat/components/prompt-selector.tsx
function PromptListContent (line 17) | function PromptListContent({
function PromptSelector (line 60) | function PromptSelector() {
FILE: src/app/mobile/chat/components/rag-toggle.tsx
function RagToggle (line 12) | function RagToggle() {
FILE: src/app/mobile/chat/page.tsx
function Chat (line 7) | function Chat() {
FILE: src/app/mobile/layout.tsx
function RootLayout (line 28) | function RootLayout({
FILE: src/app/mobile/record/mobile-mark-header.tsx
function MobileMarkHeader (line 11) | function MobileMarkHeader() {
FILE: src/app/mobile/record/mobile-record-stream.tsx
constant TIME_OPTIONS (line 25) | const TIME_OPTIONS: RecordTimePreset[] = ['all', 'today', 'last7Days', '...
function getMarkPreview (line 27) | function getMarkPreview(mark: Mark): string {
function MobileRecordStream (line 34) | function MobileRecordStream() {
FILE: src/app/mobile/record/page.tsx
function Record (line 5) | function Record() {
FILE: src/app/mobile/setting/components/setting-tab.tsx
function SettingTab (line 8) | function SettingTab() {
FILE: src/app/mobile/setting/page.tsx
function Setting (line 6) | function Setting() {
FILE: src/app/mobile/setting/pages/ai/page.tsx
function AIPage (line 5) | function AIPage() {
FILE: src/app/mobile/setting/pages/audio/page.tsx
function AudioPage (line 5) | function AudioPage() {
FILE: src/app/mobile/setting/pages/chat/page.tsx
function ChatSettingsPage (line 9) | function ChatSettingsPage() {
FILE: src/app/mobile/setting/pages/defaultModel/page.tsx
function DefaultModelPage (line 5) | function DefaultModelPage() {
FILE: src/app/mobile/setting/pages/dev/page.tsx
function DevPage (line 5) | function DevPage() {
FILE: src/app/mobile/setting/pages/editor/page.tsx
function EditorPage (line 5) | function EditorPage() {
FILE: src/app/mobile/setting/pages/file/page.tsx
function FilePage (line 5) | function FilePage() {
FILE: src/app/mobile/setting/pages/general/page.tsx
function GeneralSettingsPage (line 7) | function GeneralSettingsPage() {
FILE: src/app/mobile/setting/pages/imageHosting/page.tsx
function ImageHostingPage (line 5) | function ImageHostingPage() {
FILE: src/app/mobile/setting/pages/imageMethod/page.tsx
function ImageMethodPage (line 5) | function ImageMethodPage() {
FILE: src/app/mobile/setting/pages/layout.tsx
function RootLayout (line 8) | function RootLayout({
FILE: src/app/mobile/setting/pages/mcp/page.tsx
function McpSettingPage (line 8) | function McpSettingPage() {
FILE: src/app/mobile/setting/pages/prompt/page.tsx
function PromptPage (line 5) | function PromptPage() {
FILE: src/app/mobile/setting/pages/rag/page.tsx
function RAGPage (line 5) | function RAGPage() {
FILE: src/app/mobile/setting/pages/readAloud/page.tsx
function ReadAloudPage (line 5) | function ReadAloudPage() {
FILE: src/app/mobile/setting/pages/record/page.tsx
function RecordSettingsPage (line 8) | function RecordSettingsPage() {
FILE: src/app/mobile/setting/pages/skills/page.tsx
function SkillsPage (line 8) | function SkillsPage() {
FILE: src/app/mobile/setting/pages/sync/page.tsx
function SyncPage (line 5) | function SyncPage() {
FILE: src/app/mobile/setting/pages/template/page.tsx
function TemplatePage (line 5) | function TemplatePage() {
FILE: src/app/mobile/setting/pages/theme/page.tsx
type ColorScheme (line 15) | interface ColorScheme {
function ThemeSettingsPage (line 305) | function ThemeSettingsPage() {
FILE: src/app/mobile/writing/browser-utils.ts
function normalizePath (line 3) | function normalizePath(path: string) {
function parentPath (line 7) | function parentPath(path: string) {
function isMarkdownFile (line 12) | function isMarkdownFile(node: DirTree) {
function getNodeByPath (line 16) | function getNodeByPath(tree: DirTree[], path: string): DirTree | null {
function getChildrenByPath (line 32) | function getChildrenByPath(tree: DirTree[], path: string): DirTree[] {
FILE: src/app/mobile/writing/custom-header.tsx
function WritingHeader (line 34) | function WritingHeader() {
FILE: src/app/mobile/writing/entry-list-item.tsx
type EntryAction (line 8) | type EntryAction = {
type EntryListItemProps (line 17) | interface EntryListItemProps {
function EntryListItem (line 26) | function EntryListItem({
FILE: src/app/mobile/writing/mobile-editor.tsx
function MobileEditor (line 12) | function MobileEditor() {
FILE: src/app/mobile/writing/name-input-dialog.tsx
type NameInputDialogProps (line 13) | interface NameInputDialogProps {
function NameInputDialog (line 26) | function NameInputDialog({
FILE: src/app/mobile/writing/page.tsx
function Writing (line 8) | function Writing() {
FILE: src/app/mobile/writing/types.ts
type BrowserEntry (line 1) | type BrowserEntry = {
FILE: src/app/not-found.tsx
function NotFound (line 9) | function NotFound() {
FILE: src/app/page.tsx
function Home (line 7) | function Home() {
FILE: src/components/activity/activity-day-detail.tsx
type ActivityDayDetailProps (line 6) | interface ActivityDayDetailProps {
function getSourceLabel (line 23) | function getSourceLabel(source: ActivityEntry['source'], labels: Activit...
function renderSourceBadge (line 31) | function renderSourceBadge(entry: ActivityEntry, labels: ActivityDayDeta...
function formatEntryBucket (line 44) | function formatEntryBucket(timestamp: number) {
function formatEntryTime (line 51) | function formatEntryTime(timestamp: number) {
function normalizeText (line 58) | function normalizeText(value?: string) {
function getEntryBodyText (line 62) | function getEntryBodyText(entry: ActivityEntry) {
function getWritingMergeKey (line 70) | function getWritingMergeKey(entry: ActivityEntry) {
function dedupeGroupEntries (line 74) | function dedupeGroupEntries(entries: ActivityEntry[]) {
function groupEntriesByBucket (line 96) | function groupEntriesByBucket(entries: ActivityEntry[]) {
function ActivityDayDetail (line 112) | function ActivityDayDetail({ day, compact = false, labels }: ActivityDay...
FILE: src/components/activity/activity-drawer.tsx
type ActivityDrawerProps (line 10) | interface ActivityDrawerProps {
function ActivityDrawer (line 15) | function ActivityDrawer({ open, onOpenChange }: ActivityDrawerProps) {
FILE: src/components/activity/activity-heatmap.tsx
type ActivityHeatmapProps (line 7) | interface ActivityHeatmapProps {
function getIntensityLevel (line 18) | function getIntensityLevel(totalCount: number) {
constant LEVEL_CLASSES (line 26) | const LEVEL_CLASSES = [
function ActivityHeatmap (line 34) | function ActivityHeatmap({
FILE: src/components/activity/activity-legend.tsx
type ActivityLegendProps (line 3) | interface ActivityLegendProps {
constant LEVEL_CLASSES (line 8) | const LEVEL_CLASSES = [
function ActivityLegend (line 16) | function ActivityLegend({ lowLabel, highLabel }: ActivityLegendProps) {
FILE: src/components/activity/activity-panel.tsx
type ActivityPanelProps (line 13) | interface ActivityPanelProps {
function ActivityPanel (line 21) | function ActivityPanel({
FILE: src/components/app-footbar.tsx
type NormalNavButtonProps (line 23) | interface NormalNavButtonProps {
function NormalNavButton (line 33) | function NormalNavButton({ item, isActive, onClick }: NormalNavButtonPro...
type AvatarNavButtonProps (line 52) | interface AvatarNavButtonProps {
function AvatarNavButton (line 62) | function AvatarNavButton({ item, isActive, avatarUrl, onClick }: AvatarN...
function AppFootbar (line 90) | function AppFootbar() {
FILE: src/components/app-sidebar.tsx
type AppSidebarProps (line 22) | interface AppSidebarProps {
function AppSidebar (line 26) | function AppSidebar({ onSearchClick }: AppSidebarProps) {
FILE: src/components/app-status.tsx
function AppStatus (line 8) | function AppStatus() {
FILE: src/components/audio-player.tsx
type AudioPlayerProps (line 9) | interface AudioPlayerProps {
function AudioPlayer (line 14) | function AudioPlayer({ audioPath, compact = false }: AudioPlayerProps) {
FILE: src/components/bottom-bar-icon-button.tsx
type BottomBarIconButtonProps (line 7) | type BottomBarIconButtonProps = {
function BottomBarIconButton (line 16) | function BottomBarIconButton({
FILE: src/components/console-filter.tsx
function ConsoleFilter (line 5) | function ConsoleFilter() {
FILE: src/components/draggable-toolbar-item.tsx
type DraggableToolbarItemProps (line 5) | interface DraggableToolbarItemProps {
function DraggableToolbarItem (line 12) | function DraggableToolbarItem({
FILE: src/components/image-viewer.tsx
function ImageViewer (line 8) | function ImageViewer({url, path, imageClassName}: {url: string, path?: s...
FILE: src/components/local-image.tsx
function LocalImage (line 6) | function LocalImage({ onLoad, src, ...props }: React.ComponentProps<type...
FILE: src/components/memories/memory-form.tsx
type MemoryFormProps (line 13) | interface MemoryFormProps {
function MemoryForm (line 17) | function MemoryForm({ onSuccess }: MemoryFormProps) {
FILE: src/components/memories/memory-item.tsx
type MemoryItemProps (line 9) | interface MemoryItemProps {
function MemoryItem (line 14) | function MemoryItem({ memory, onDelete }: MemoryItemProps) {
FILE: src/components/memories/memory-list.tsx
type TabValue (line 21) | type TabValue = 'all' | 'preference' | 'memory'
function MemoryList (line 23) | function MemoryList() {
FILE: src/components/memories/memory-stats.tsx
function MemoryStats (line 8) | function MemoryStats() {
FILE: src/components/mobile-record-tools.tsx
type MobileRecordToolsProps (line 12) | interface MobileRecordToolsProps {
function MobileRecordTools (line 16) | function MobileRecordTools({ onClose }: MobileRecordToolsProps) {
FILE: src/components/mobile-statusbar.tsx
function MobileStatusBar (line 6) | function MobileStatusBar() {
FILE: src/components/onboarding-spotlight-position.ts
type SpotlightRect (line 1) | interface SpotlightRect {
function getSpotlightTooltipPosition (line 8) | function getSpotlightTooltipPosition({
FILE: src/components/onboarding-spotlight.tsx
type OnboardingSpotlightProps (line 6) | interface OnboardingSpotlightProps {
function measureTarget (line 13) | function measureTarget(targetId: string): SpotlightRect | null {
function OnboardingSpotlight (line 28) | function OnboardingSpotlight({
FILE: src/components/pin-toggle.tsx
function PinToggle (line 12) | function PinToggle() {
FILE: src/components/providers/NextIntlProvider.tsx
function loadMessages (line 5) | async function loadMessages(locale: string) {
function loadFallbackMessages (line 16) | async function loadFallbackMessages() {
function deepMerge (line 21) | function deepMerge(target: any, source: any): any {
function NextIntlProvider (line 39) | function NextIntlProvider({ children }: { children: React.ReactNode }) {
FILE: src/components/recording-dialog.tsx
type RecordingDialogProps (line 18) | interface RecordingDialogProps {
function RecordingDialog (line 24) | function RecordingDialog({ open, onOpenChange, onTranscriptionComplete }...
FILE: src/components/recording-indicator.tsx
function RecordingIndicator (line 10) | function RecordingIndicator() {
FILE: src/components/search-dialog.tsx
type SearchDialogProps (line 31) | interface SearchDialogProps {
type SearchFilter (line 36) | type SearchFilter = 'all' | 'record' | 'article'
type EnhancedSearchResult (line 38) | interface EnhancedSearchResult {
function SearchDialog (line 56) | function SearchDialog({ open, onOpenChange }: SearchDialogProps) {
FILE: src/components/simple-mobile-tool.tsx
type SimpleMobileToolProps (line 7) | interface SimpleMobileToolProps {
function SimpleMobileTool (line 12) | function SimpleMobileTool({ toolId, onToolClick }: SimpleMobileToolProps) {
FILE: src/components/sync-confirm-dialog.tsx
function SyncConfirmDialog (line 40) | function SyncConfirmDialog() {
FILE: src/components/sync-status-badge.tsx
type SyncStatusType (line 10) | type SyncStatusType = 'synced' | 'local_newer' | 'remote_newer' | 'confl...
type SyncStatusBadgeProps (line 12) | interface SyncStatusBadgeProps {
function SyncStatusBadge (line 19) | function SyncStatusBadge({ path, showLabel = false, className, badgeProp...
function SyncStatusIcon (line 134) | function SyncStatusIcon({ path, className }: { path?: string; className?...
function SyncStatusLabel (line 139) | function SyncStatusLabel({ path, className }: { path?: string; className...
FILE: src/components/theme-provider.tsx
function ThemeProvider (line 6) | function ThemeProvider({
FILE: src/components/title-bar-toolbars/sync-toggle.tsx
type GitlabInstanceType (line 39) | enum GitlabInstanceType {
constant GITLAB_INSTANCES (line 46) | const GITLAB_INSTANCES: Record<GitlabInstanceType, { name: string; baseU...
function getGitlabApiBaseUrl (line 62) | async function getGitlabApiBaseUrl(): Promise<string> {
function encodePath (line 102) | function encodePath(path: string, filename?: string): string {
function encodeGitLabPath (line 108) | function encodeGitLabPath(path: string, filename?: string): string {
function requestGitHub (line 113) | async function requestGitHub(method: string, url: string, body?: object) {
function requestGitee (line 134) | async function requestGitee(method: string, url: string, body?: object) {
function requestGitLab (line 152) | async function requestGitLab(method: string, url: string, body?: object) {
function requestGitea (line 181) | async function requestGitea(method: string, url: string, body?: object) {
function githubUpload (line 201) | async function githubUpload({ file, path, filename, sha, repo, accessTok...
function githubGetFile (line 208) | async function githubGetFile({ path, repo, accessToken, githubUsername }: {
function giteeUpload (line 216) | async function giteeUpload({ file, path, filename, sha, repo, accessToke...
function giteeGetFile (line 223) | async function giteeGetFile({ path, repo, accessToken, giteeUsername }: {
function gitlabUpload (line 231) | async function gitlabUpload({ file, path, filename, sha, accessToken, pr...
function gitlabGetFile (line 256) | async function gitlabGetFile({ path, accessToken, projectId }: {
function giteaUpload (line 265) | async function giteaUpload({ file, path, filename, sha, repo, accessToke...
function giteaGetFile (line 290) | async function giteaGetFile({ path, repo, accessToken, giteaUsername }: {
type ProviderStatus (line 299) | type ProviderStatus = 'connected' | 'disconnected' | 'failed' | 'unconfi...
type ProviderInfo (line 301) | interface ProviderInfo {
function SyncToggle (line 307) | function SyncToggle() {
FILE: src/components/title-bar.tsx
type Platform (line 43) | type Platform = 'macos' | 'windows' | 'linux' | 'unknown'
type TitleBarProps (line 45) | interface TitleBarProps {
function TitleBar (line 51) | function TitleBar({ onSearchClick, onActivityClick, activityOpen = false...
FILE: src/components/tooltip-button.tsx
function TooltipButton (line 5) | function TooltipButton(
FILE: src/components/ui/agent-plan.tsx
type ToolCall (line 27) | interface ToolCall {
type ConfirmationRecord (line 41) | interface ConfirmationRecord {
type ReActStep (line 51) | interface ReActStep {
type AgentPlanProps (line 62) | interface AgentPlanProps {
type DisplayStep (line 103) | interface DisplayStep {
function AgentPlan (line 117) | function AgentPlan({
FILE: src/components/ui/badge.tsx
type BadgeProps (line 26) | interface BadgeProps
function Badge (line 30) | function Badge({ className, variant, ...props }: BadgeProps) {
FILE: src/components/ui/button.tsx
type ButtonProps (line 37) | interface ButtonProps
FILE: src/components/ui/calendar.tsx
type CalendarProps (line 10) | type CalendarProps = React.ComponentProps<typeof DayPicker>
function Calendar (line 12) | function Calendar({
FILE: src/components/ui/carousel.tsx
type CarouselApi (line 12) | type CarouselApi = UseEmblaCarouselType[1]
type UseCarouselParameters (line 13) | type UseCarouselParameters = Parameters<typeof useEmblaCarousel>
type CarouselOptions (line 14) | type CarouselOptions = UseCarouselParameters[0]
type CarouselPlugin (line 15) | type CarouselPlugin = UseCarouselParameters[1]
type CarouselProps (line 17) | type CarouselProps = {
type CarouselContextProps (line 24) | type CarouselContextProps = {
function useCarousel (line 35) | function useCarousel() {
FILE: src/components/ui/diff-viewer.tsx
type DiffViewerProps (line 7) | interface DiffViewerProps {
type DiffLine (line 22) | interface DiffLine {
function DiffViewer (line 28) | function DiffViewer({
type InlineDiffProps (line 208) | interface InlineDiffProps {
function InlineDiff (line 214) | function InlineDiff({ original, modified, className }: InlineDiffProps) {
FILE: src/components/ui/empty.tsx
function Empty (line 5) | function Empty({ className, ...props }: React.ComponentProps<"div">) {
function EmptyHeader (line 18) | function EmptyHeader({ className, ...props }: React.ComponentProps<"div"...
function EmptyMedia (line 46) | function EmptyMedia({
function EmptyTitle (line 61) | function EmptyTitle({ className, ...props }: React.ComponentProps<"div">) {
function EmptyDescription (line 71) | function EmptyDescription({ className, ...props }: React.ComponentProps<...
function EmptyContent (line 84) | function EmptyContent({ className, ...props }: React.ComponentProps<"div...
FILE: src/components/ui/enhanced-context-menu.tsx
type ContextMenuSubTriggerProps (line 21) | interface ContextMenuSubTriggerProps extends React.ComponentPropsWithout...
type ContextMenuItemProps (line 82) | interface ContextMenuItemProps extends React.ComponentPropsWithoutRef<ty...
type ContextMenuCheckboxItemProps (line 117) | interface ContextMenuCheckboxItemProps extends React.ComponentPropsWitho...
type ContextMenuRadioItemProps (line 150) | interface ContextMenuRadioItemProps extends React.ComponentPropsWithoutR...
type ContextMenuLabelProps (line 181) | interface ContextMenuLabelProps extends React.ComponentPropsWithoutRef<t...
type ContextMenuShortcutProps (line 219) | interface ContextMenuShortcutProps extends React.HTMLAttributes<HTMLSpan...
FILE: src/components/ui/expandable-tabs.tsx
type Tab (line 9) | interface Tab {
type Separator (line 15) | interface Separator {
type TabItem (line 21) | type TabItem = Tab | Separator;
type ExpandableTabsProps (line 23) | interface ExpandableTabsProps {
function ExpandableTabs (line 52) | function ExpandableTabs({
FILE: src/components/ui/form.tsx
type FormFieldContextValue (line 20) | type FormFieldContextValue<
type FormItemContextValue (line 67) | type FormItemContextValue = {
FILE: src/components/ui/item.tsx
function ItemGroup (line 8) | function ItemGroup({ className, ...props }: React.ComponentProps<"div">) {
function ItemSeparator (line 19) | function ItemSeparator({
function Item (line 54) | function Item({
function ItemMedia (line 91) | function ItemMedia({
function ItemContent (line 106) | function ItemContent({ className, ...props }: React.ComponentProps<"div"...
function ItemTitle (line 119) | function ItemTitle({ className, ...props }: React.ComponentProps<"div">) {
function ItemDescription (line 132) | function ItemDescription({ className, ...props }: React.ComponentProps<"...
function ItemActions (line 146) | function ItemActions({ className, ...props }: React.ComponentProps<"div"...
function ItemHeader (line 156) | function ItemHeader({ className, ...props }: React.ComponentProps<"div">) {
function ItemFooter (line 169) | function ItemFooter({ className, ...props }: React.ComponentProps<"div">) {
FILE: src/components/ui/sheet.tsx
type SheetContentProps (line 52) | interface SheetContentProps
FILE: src/components/ui/shine-border.tsx
type ShineBorderProps (line 7) | interface ShineBorderProps extends React.HTMLAttributes<HTMLDivElement> {
function ShineBorder (line 30) | function ShineBorder({
FILE: src/components/ui/sidebar.tsx
constant SIDEBAR_COOKIE_NAME (line 22) | const SIDEBAR_COOKIE_NAME = "sidebar:state"
constant SIDEBAR_COOKIE_MAX_AGE (line 23) | const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7
constant SIDEBAR_WIDTH (line 24) | const SIDEBAR_WIDTH = "16rem"
constant SIDEBAR_WIDTH_MOBILE (line 25) | const SIDEBAR_WIDTH_MOBILE = "18rem"
constant SIDEBAR_WIDTH_ICON (line 26) | const SIDEBAR_WIDTH_ICON = "3rem"
constant SIDEBAR_KEYBOARD_SHORTCUT (line 27) | const SIDEBAR_KEYBOARD_SHORTCUT = "b"
type SidebarContext (line 29) | type SidebarContext = {
function useSidebar (line 41) | function useSidebar() {
FILE: src/components/ui/skeleton.tsx
function Skeleton (line 3) | function Skeleton({
FILE: src/components/ui/swipe-back.tsx
type SwipeBackProps (line 6) | interface SwipeBackProps {
function SwipeBack (line 12) | function SwipeBack({
FILE: src/components/ui/toast.tsx
type ToastProps (line 115) | type ToastProps = React.ComponentPropsWithoutRef<typeof Toast>
type ToastActionElement (line 117) | type ToastActionElement = React.ReactElement<typeof ToastAction>
FILE: src/components/ui/toaster.tsx
function Toaster (line 13) | function Toaster() {
FILE: src/config/emitters.ts
type EmitterShortcutEvents (line 1) | enum EmitterShortcutEvents {
type EmitterRecordEvents (line 8) | enum EmitterRecordEvents {
FILE: src/config/shortcut.ts
type ShortcutSettings (line 1) | enum ShortcutSettings {
type ShortcutDefault (line 8) | enum ShortcutDefault {
FILE: src/config/sync-exclusions.ts
type SyncExcludePattern (line 5) | interface SyncExcludePattern {
constant DEFAULT_SYNC_EXCLUDE_PATTERNS (line 11) | const DEFAULT_SYNC_EXCLUDE_PATTERNS: SyncExcludePattern[] = [
function shouldExclude (line 22) | function shouldExclude(path: string): boolean {
function matchPattern (line 35) | function matchPattern(pattern: string, path: string): boolean {
function getExcludePatterns (line 52) | function getExcludePatterns(): string[] {
constant SYNC_EXCLUDED_FIELDS (line 59) | const SYNC_EXCLUDED_FIELDS: string[] = [
function shouldExcludeFromSync (line 69) | function shouldExcludeFromSync(fieldName: string): boolean {
function filterSyncData (line 74) | function filterSyncData<T extends Record<string, any>>(data: T): Partial...
function mergeSyncData (line 87) | function mergeSyncData<T extends Record<string, any>>(
FILE: src/contexts/text-size-context.tsx
type TextSizeContextType (line 6) | interface TextSizeContextType {
function useTextSize (line 15) | function useTextSize() {
type TextSizeProviderProps (line 23) | interface TextSizeProviderProps {
function TextSizeProvider (line 27) | function TextSizeProvider({ children }: TextSizeProviderProps) {
FILE: src/db/activity.ts
type ActivityEventSource (line 7) | type ActivityEventSource = 'record' | 'chat' | 'writing'
type ActivityEvent (line 9) | interface ActivityEvent {
type InsertActivityEventInput (line 20) | interface InsertActivityEventInput {
function initActivityDb (line 30) | async function initActivityDb() {
function insertActivityEvent (line 68) | async function insertActivityEvent(event: InsertActivityEventInput) {
function getAllActivityEvents (line 88) | async function getAllActivityEvents() {
function getLatestWritingEventTimestamp (line 97) | async function getLatestWritingEventTimestamp(path: string) {
function recordWritingActivity (line 110) | async function recordWritingActivity(params: {
function backfillActivityEvents (line 135) | async function backfillActivityEvents() {
FILE: src/db/chats.ts
type Role (line 5) | type Role = 'system' | 'user'
type ChatType (line 6) | type ChatType = 'chat' | 'note' | 'clipboard' | 'clear' | 'condensed'
type Chat (line 8) | interface Chat {
function initChatsDb (line 30) | async function initChatsDb() {
function insertChat (line 163) | async function insertChat(chat: Omit<Chat, 'id' | 'createdAt'>) {
function getChats (line 186) | async function getChats(tagId: number) {
function getChatsByConversation (line 196) | async function getChatsByConversation(conversationId: number) {
function getAllChats (line 206) | async function getAllChats() {
function insertChats (line 216) | async function insertChats(chats: Chat[]) {
function deleteAllChats (line 235) | async function deleteAllChats() {
function updateChat (line 244) | async function updateChat(chat: Chat) {
function clearChatsByTagId (line 252) | async function clearChatsByTagId(tagId: number) {
function updateChatsInsertedById (line 260) | async function updateChatsInsertedById(id: number) {
function deleteChat (line 268) | async function deleteChat(id: number) {
function updateChats (line 275) | async function updateChats(chats: Chat[]) {
function deleteChats (line 290) | async function deleteChats(ids: number[]) {
function updateChatCondensedContent (line 310) | async function updateChatCondensedContent(chatId: number, condensedConte...
FILE: src/db/conversations.ts
type Conversation (line 3) | interface Conversation {
function initConversationsDb (line 13) | async function initConversationsDb() {
function migrateExistingChats (line 48) | async function migrateExistingChats() {
function createConversation (line 107) | async function createConversation(title: string): Promise<number> {
function getAllConversations (line 118) | async function getAllConversations(): Promise<Conversation[]> {
function getConversation (line 128) | async function getConversation(id: number): Promise<Conversation | null> {
function updateConversationTitle (line 138) | async function updateConversationTitle(id: number, title: string): Promi...
function updateConversationMessageCount (line 147) | async function updateConversationMessageCount(id: number, delta: number)...
function updateConversationTime (line 156) | async function updateConversationTime(id: number): Promise<void> {
function deleteConversation (line 165) | async function deleteConversation(id: number): Promise<void> {
function toggleConversationPin (line 180) | async function toggleConversationPin(id: number): Promise<boolean> {
function syncConversationMessageCount (line 194) | async function syncConversationMessageCount(conversationId: number): Pro...
FILE: src/db/index.ts
function getDb (line 8) | async function getDb() {
function initAllDatabases (line 13) | async function initAllDatabases() {
FILE: src/db/marks.ts
type Mark (line 6) | interface Mark {
function initMarksDb (line 19) | async function initMarksDb() {
function getMarks (line 39) | async function getMarks(id: number) {
function insertMark (line 45) | async function insertMark(mark: Partial<Mark>) {
function getAllMarks (line 67) | async function getAllMarks() {
function updateMark (line 72) | async function updateMark(mark: Mark) {
function restoreMark (line 81) | async function restoreMark(id: number) {
function delMark (line 90) | async function delMark(id: number) {
function deleteAllMarks (line 104) | async function deleteAllMarks() {
function insertMarks (line 109) | async function insertMarks(marks: Partial<Mark>[]) {
function delMarkForever (line 124) | async function delMarkForever(id: number) {
function clearTrash (line 129) | async function clearTrash() {
function updateMarks (line 134) | async function updateMarks(marks: Mark[]) {
function deleteMarks (line 149) | async function deleteMarks(ids: number[]) {
function restoreMarks (line 165) | async function restoreMarks(ids: number[]) {
FILE: src/db/memories.ts
type MemoryCategory (line 4) | type MemoryCategory = 'preference' | 'memory'
type Memory (line 6) | interface Memory {
constant PREFERENCE_KEYWORDS (line 19) | const PREFERENCE_KEYWORDS = [
function categorizeMemory (line 27) | function categorizeMemory(content: string): MemoryCategory {
function cosineSimilarity (line 38) | function cosineSimilarity(vecA: number[], vecB: number[]): number {
function generateUUID (line 61) | function generateUUID(): string {
function initMemoriesDb (line 72) | async function initMemoriesDb() {
function upsertMemory (line 101) | async function upsertMemory(
function getAllMemories (line 189) | async function getAllMemories(): Promise<Memory[]> {
function getMemoriesByCategory (line 203) | async function getMemoriesByCategory(category: MemoryCategory): Promise<...
function getSimilarMemories (line 218) | async function getSimilarMemories(
function getMemoryById (line 249) | async function getMemoryById(id: string): Promise<Memory | null> {
function updateMemoryAccess (line 264) | async function updateMemoryAccess(id: string): Promise<void> {
function updateMemory (line 275) | async function updateMemory(
function deleteMemory (line 307) | async function deleteMemory(id: string): Promise<void> {
function clearAllMemories (line 318) | async function clearAllMemories(): Promise<void> {
function getMemoryStats (line 328) | async function getMemoryStats(): Promise<{
FILE: src/db/notes.ts
type Note (line 4) | interface Note {
function initNotesDb (line 14) | async function initNotesDb() {
function insertNote (line 32) | async function insertNote(note: Partial<Note>) {
function getNoteByTagId (line 41) | async function getNoteByTagId(tagId: number) {
function getNoteById (line 46) | async function getNoteById(id: number) {
function getNotesByTagId (line 52) | async function getNotesByTagId(tagId: number) {
function delNote (line 58) | async function delNote(id: number) {
FILE: src/db/tags.ts
type Tag (line 4) | interface Tag {
function initTagsDb (line 14) | async function initTagsDb() {
function getTags (line 53) | async function getTags() {
function insertTag (line 67) | async function insertTag(tag: Partial<Tag>) {
function updateTag (line 75) | async function updateTag(tag: Tag) {
function delTag (line 83) | async function delTag(id: number) {
function deleteAllTags (line 88) | async function deleteAllTags() {
function insertTags (line 93) | async function insertTags(tags: Tag[]) {
function updateTagsOrder (line 113) | async function updateTagsOrder(tags: { id: number; sortOrder: number }[]) {
FILE: src/db/vector.ts
type VectorDocument (line 4) | interface VectorDocument {
type CachedVector (line 14) | interface CachedVector {
class VectorCache (line 23) | class VectorCache {
method getVersion (line 30) | getVersion(): number {
method getAll (line 35) | getAll(): CachedVector[] {
method getByFilename (line 40) | getByFilename(filename: string): CachedVector[] {
method update (line 46) | async update() {
method add (line 83) | add(doc: VectorDocument) {
method deleteByFilename (line 106) | deleteByFilename(filename: string) {
method needsUpdate (line 116) | needsUpdate(): boolean {
function initVectorDb (line 125) | async function initVectorDb() {
function upsertVectorDocument (line 149) | async function upsertVectorDocument(doc: Omit<VectorDocument, 'id'>) {
function getVectorDocumentsByFilename (line 166) | async function getVectorDocumentsByFilename(filename: string) {
function deleteVectorDocumentsByFilename (line 173) | async function deleteVectorDocumentsByFilename(filename: string) {
function checkVectorDocumentExists (line 183) | async function checkVectorDocumentExists(filename: string) {
function getSimilarDocuments (line 192) | async function getSimilarDocuments(
function cosineSimilarity (line 228) | function cosineSimilarity(vecA: number[], vecB: number[]): number {
function clearVectorDb (line 249) | async function clearVectorDb() {
function getAllVectorDocumentFilenames (line 259) | async function getAllVectorDocumentFilenames() {
function refreshVectorCache (line 266) | async function refreshVectorCache() {
FILE: src/hooks/use-file-shortcuts.ts
type Platform (line 6) | type Platform = 'macos' | 'windows' | 'linux' | 'unknown'
type FileShortcutsProps (line 8) | interface FileShortcutsProps {
function useFileShortcuts (line 25) | function useFileShortcuts({
FILE: src/hooks/use-mobile.tsx
constant MOBILE_BREAKPOINT (line 3) | const MOBILE_BREAKPOINT = 768
function useIsMobile (line 5) | function useIsMobile() {
FILE: src/hooks/use-sync-manager.ts
type UseSyncManagerOptions (line 8) | interface UseSyncManagerOptions {
function useSyncManager (line 13) | function useSyncManager(path?: string, options: UseSyncManagerOptions = ...
FILE: src/hooks/use-sync-settings.ts
function getStore (line 11) | async function getStore(): Promise<Store> {
type SyncPlatformStatus (line 20) | interface SyncPlatformStatus {
type UseSyncSettingsReturn (line 27) | interface UseSyncSettingsReturn {
function useSyncSettings (line 52) | function useSyncSettings(): UseSyncSettingsReturn {
FILE: src/hooks/use-toast.ts
constant TOAST_LIMIT (line 11) | const TOAST_LIMIT = 1
constant TOAST_REMOVE_DELAY (line 12) | const TOAST_REMOVE_DELAY = 1000000
type ToasterToast (line 14) | type ToasterToast = ToastProps & {
function genId (line 31) | function genId() {
type ActionType (line 36) | type ActionType = typeof actionTypes
type Action (line 38) | type Action =
type State (line 56) | interface State {
function dispatch (line 137) | function dispatch(action: Action) {
type Toast (line 144) | type Toast = Omit<ToasterToast, "id">
function toast (line 146) | function toast({ ...props }: Toast) {
function useToast (line 175) | function useToast() {
FILE: src/hooks/use-toolbar-shortcuts.ts
type Platform (line 7) | type Platform = 'macos' | 'windows' | 'linux' | 'unknown'
function useToolbarShortcuts (line 9) | function useToolbarShortcuts() {
FILE: src/hooks/use-username.ts
function useUsername (line 7) | function useUsername() {
function getS3BucketName (line 30) | async function getS3BucketName(): Promise<string | null> {
FILE: src/hooks/useAiCompletion.ts
type UseAiCompletionOptions (line 4) | interface UseAiCompletionOptions {
function useAiCompletion (line 9) | function useAiCompletion(options: UseAiCompletionOptions = {}) {
FILE: src/hooks/useI18n.ts
constant LANGUAGE_KEY (line 3) | const LANGUAGE_KEY = 'app-language';
function useI18n (line 5) | function useI18n() {
FILE: src/lib/activity/aggregate.ts
constant DEFAULT_COUNTS (line 3) | const DEFAULT_COUNTS: Record<ActivitySource, number> = Object.freeze({
function formatDayKey (line 9) | function formatDayKey(timestamp: number, timeZone?: string) {
function cloneCounts (line 18) | function cloneCounts(): Record<ActivitySource, number> {
function summarizeActivityEntries (line 26) | function summarizeActivityEntries(entries: ActivityEntry[], options: { t...
function shiftDay (line 53) | function shiftDay(day: string, amount: number) {
function buildActivityHeatmap (line 59) | function buildActivityHeatmap(
FILE: src/lib/activity/events.ts
constant DEFAULT_WRITING_SESSION_WINDOW_MS (line 1) | const DEFAULT_WRITING_SESSION_WINDOW_MS = 30 * 60 * 1000
function shouldCreateWritingSession (line 3) | function shouldCreateWritingSession(
function truncateActivityText (line 15) | function truncateActivityText(value: string | undefined, maxLength = 120) {
FILE: src/lib/activity/index.ts
function getBrowserTimeZone (line 7) | function getBrowserTimeZone() {
function getDefaultRange (line 11) | function getDefaultRange() {
function loadActivityEntries (line 22) | async function loadActivityEntries(): Promise<ActivityEntry[]> {
function buildTotals (line 36) | function buildTotals(days: ActivityDaySummary[]) {
function loadActivityCalendarData (line 55) | async function loadActivityCalendarData(): Promise<ActivityCalendarData> {
FILE: src/lib/activity/types.ts
type ActivitySource (line 1) | type ActivitySource = 'record' | 'chat' | 'writing'
type ActivityEntry (line 3) | interface ActivityEntry {
type ActivityDaySummary (line 14) | interface ActivityDaySummary {
type ActivityHeatmapWeek (line 21) | interface ActivityHeatmapWeek {
type ActivityCalendarData (line 25) | interface ActivityCalendarData {
FILE: src/lib/agent/agent-handler.ts
type AgentHandlerConfig (line 9) | interface AgentHandlerConfig {
class AgentHandler (line 29) | class AgentHandler {
method constructor (line 33) | constructor(config: AgentHandlerConfig) {
method execute (line 37) | async execute(
method stop (line 215) | stop() {
method getAvailableSkills (line 226) | private async getAvailableSkills(): Promise<string[]> {
method getSkillsInfo (line 259) | private async getSkillsInfo(): Promise<Array<{ id: string; name: strin...
FILE: src/lib/agent/auto-final-answer.ts
type AutoFinalAnswerDescriptor (line 1) | interface AutoFinalAnswerDescriptor {
type AutoFinalAnswerInput (line 7) | interface AutoFinalAnswerInput {
constant CONTINUATION_FAILURE_PATTERNS (line 13) | const CONTINUATION_FAILURE_PATTERNS = [
function shouldRecoverWithAutoFinalAnswer (line 21) | function shouldRecoverWithAutoFinalAnswer(thought: string): boolean {
function getAutoFinalAnswerDescriptor (line 26) | function getAutoFinalAnswerDescriptor(
FILE: src/lib/agent/parse-action-input.ts
function closeJsonStructures (line 1) | function closeJsonStructures(jsonStr: string): string {
function escapeLiteralNewlinesInStrings (line 58) | function escapeLiteralNewlinesInStrings(jsonStr: string): string {
function parseActionInputJson (line 100) | function parseActionInputJson(jsonStr: string): Record<string, any> | nu...
FILE: src/lib/agent/react-diff-helpers.ts
function replaceLinesInRange (line 5) | function replaceLinesInRange(
function searchReplaceContent (line 40) | function searchReplaceContent(
function insertLinesAtPosition (line 69) | function insertLinesAtPosition(
function deleteLinesInRange (line 92) | function deleteLinesInRange(
FILE: src/lib/agent/react.ts
function buildIterationUserMessage (line 19) | function buildIterationUserMessage(
function normalizeLinkedCandidate (line 40) | function normalizeLinkedCandidate(candidate: unknown): string {
function getLinkedFileName (line 44) | function getLinkedFileName(path: unknown): string {
function matchesLinkedFileCandidate (line 49) | function matchesLinkedFileCandidate(
function shouldBlockRedundantLinkedFileRead (line 69) | function shouldBlockRedundantLinkedFileRead(
function isExplicitTagOrMarkIntent (line 95) | function isExplicitTagOrMarkIntent(userInput: string): boolean {
function shouldKeepFocusOnLinkedNote (line 99) | function shouldKeepFocusOnLinkedNote(
function isSuccessfulObservation (line 120) | function isSuccessfulObservation(observation?: string): boolean {
function shouldBlockRepeatedNoteExploration (line 130) | function shouldBlockRepeatedNoteExploration(
type ReActConfig (line 157) | interface ReActConfig {
class ReActAgent (line 183) | class ReActAgent {
method constructor (line 198) | constructor(config: ReActConfig) {
method stop (line 205) | stop() {
method isStopped (line 214) | isStopped(): boolean {
method run (line 218) | async run(
method buildSystemPrompt (line 443) | private async buildSystemPrompt(): Promise<string> {
method think (line 702) | private async think(
method parseAction (line 910) | private parseAction(thought: string): { tool: string; params: Record<s...
method act (line 1000) | private async act(toolName: string, params: Record<string, any>, thoug...
method normalizeToolParams (line 1256) | private normalizeToolParams(toolName: string, params: Record<string, a...
method normalizeCreateFileParams (line 1315) | private normalizeCreateFileParams(params: Record<string, any>): Record...
method getQuotedInsertDirective (line 1368) | private getQuotedInsertDirective(): 'before' | 'after' | 'around' | nu...
method buildQuotedInsertContent (line 1391) | private buildQuotedInsertContent(
method extractTitleFromThought (line 1437) | private extractTitleFromThought(thought: string): string {
method formatMcpResult (line 1458) | private formatMcpResult(toolDescription: string, data: any): string {
method getSteps (line 1486) | getSteps(): ReActStep[] {
method getCurrentIteration (line 1490) | getCurrentIteration(): number {
method formatSkillsInstructions (line 1498) | private formatSkillsInstructions(): string {
method extractMentionedSkills (line 1643) | private extractMentionedSkills(thought: string): string[] {
method extractFinalAnswer (line 1673) | private extractFinalAnswer(content: string): string | null {
method isToolAuthorized (line 1706) | isToolAuthorized(toolName: string): boolean {
method evaluateToolPolicy (line 1722) | private evaluateToolPolicy(
method getPolicyAdjustmentMessage (line 1769) | private getPolicyAdjustmentMessage(toolName: string, reason: string): ...
method isPolicyAdjustmentObservation (line 1801) | private isPolicyAdjustmentObservation(observation?: string): boolean {
method isRedundantLinkedFileRead (line 1811) | private isRedundantLinkedFileRead(toolName: string, params: Record<str...
method isSupportOnlyTool (line 1821) | private isSupportOnlyTool(toolName?: string): boolean {
method hasSubstantiveSuccessfulAction (line 1829) | private hasSubstantiveSuccessfulAction(): boolean {
method validateFinalAnswerReadiness (line 1845) | private validateFinalAnswerReadiness(userInput: string, finalAnswer: s...
FILE: src/lib/agent/session-approval.ts
type SessionApprovalScope (line 3) | interface SessionApprovalScope {
function isRecoverableWriteToolLocally (line 8) | function isRecoverableWriteToolLocally(toolName: string, tool: Tool | un...
function classifySkillScriptPathLocally (line 41) | function classifySkillScriptPathLocally(arg: string): 'generated-runtime...
function getSessionApprovalScope (line 59) | function getSessionApprovalScope(
function matchesSessionApproval (line 91) | function matchesSessionApproval(
FILE: src/lib/agent/tool-confirmation-display.ts
type ToolConfirmationDisplayConfig (line 1) | interface ToolConfirmationDisplayConfig {
type ConfirmationPreviewField (line 9) | interface ConfirmationPreviewField {
type ConfirmationPreview (line 16) | interface ConfirmationPreview {
constant TOOL_CONFIRMATION_DISPLAY (line 22) | const TOOL_CONFIRMATION_DISPLAY: Record<string, ToolConfirmationDisplayC...
function getToolConfirmationDisplay (line 74) | function getToolConfirmationDisplay(toolName: string): ToolConfirmationD...
function formatConfirmationPreview (line 78) | function formatConfirmationPreview(
FILE: src/lib/agent/tool-policy.ts
type ToolRiskLevel (line 1) | type ToolRiskLevel = 'low' | 'medium' | 'high'
type IntentPolicy (line 3) | interface IntentPolicy {
type ToolPolicyEvaluationInput (line 9) | interface ToolPolicyEvaluationInput {
type ToolPolicyEvaluationResult (line 15) | interface ToolPolicyEvaluationResult {
constant HIGH_RISK_TOOLS (line 21) | const HIGH_RISK_TOOLS = new Set([
constant MEDIUM_RISK_TOOLS (line 37) | const MEDIUM_RISK_TOOLS = new Set([
constant READ_ONLY_TOOLS (line 60) | const READ_ONLY_TOOLS = new Set([
function deriveIntentPolicy (line 75) | function deriveIntentPolicy(userInput: string): IntentPolicy {
function formatIntentPolicyForPrompt (line 133) | function formatIntentPolicyForPrompt(intentPolicy: IntentPolicy): string {
function isExecuteTool (line 147) | function isExecuteTool(toolName: string): boolean {
function isDestructiveTool (line 151) | function isDestructiveTool(toolName: string): boolean {
function isReadOnlyTool (line 160) | function isReadOnlyTool(toolName: string): boolean {
function getToolRiskLevel (line 169) | function getToolRiskLevel(toolName: string, category: string): ToolRiskL...
function evaluateIntentAwareToolPolicy (line 200) | function evaluateIntentAwareToolPolicy(
function isRecoverableWriteTool (line 245) | function isRecoverableWriteTool(toolName: string, category: string): boo...
FILE: src/lib/agent/tools/index.ts
function convertMcpToolToAgentTool (line 28) | function convertMcpToolToAgentTool(serverId: string, tool: any): Tool {
function mapJsonSchemaTypeToToolType (line 76) | function mapJsonSchemaTypeToToolType(jsonType: string): Tool['parameters...
function getAllTools (line 91) | function getAllTools(): Tool[] {
function getAllToolsAsync (line 109) | async function getAllToolsAsync(): Promise<Tool[]> {
function getAllToolsSync (line 144) | function getAllToolsSync(): Tool[] {
function reloadMcpTools (line 154) | async function reloadMcpTools(): Promise<void> {
function getToolByName (line 160) | function getToolByName(name: string): Tool | undefined {
function getToolsByCategory (line 164) | function getToolsByCategory(category: Tool['category']): Tool[] {
function getToolDescriptions (line 168) | function getToolDescriptions(): string {
FILE: src/lib/agent/tools/mark-tools.ts
function getCurrentTagId (line 9) | function getCurrentTagId(tagId?: number): number {
FILE: src/lib/agent/tools/note-tools.ts
function normalizeLinkedCandidate (line 11) | function normalizeLinkedCandidate(candidate: unknown): string {
function getLinkedFileName (line 15) | function getLinkedFileName(path: unknown): string {
function matchesLinkedFileCandidate (line 20) | function matchesLinkedFileCandidate(
function getBatchLinkedFileReadPlan (line 40) | function getBatchLinkedFileReadPlan(
FILE: src/lib/agent/types.ts
type ToolParameterType (line 1) | type ToolParameterType = 'string' | 'number' | 'boolean' | 'array' | 'ob...
type ToolParameter (line 3) | interface ToolParameter {
type Tool (line 11) | interface Tool {
type ToolResult (line 20) | interface ToolResult {
type ToolCall (line 27) | interface ToolCall {
type ConfirmationRecord (line 36) | interface ConfirmationRecord {
type AgentState (line 46) | interface AgentState {
type ReActStep (line 88) | interface ReActStep {
FILE: src/lib/ai/chat.ts
function fetchAi (line 10) | async function fetchAi(
function fetchAiStream (line 53) | async function fetchAiStream(
function fetchAiStreamToken (line 434) | async function fetchAiStreamToken(text: string, onUpdate: (content: stri...
FILE: src/lib/ai/completion.ts
function cleanupCompletion (line 6) | function cleanupCompletion(text: string): string {
function fetchCompletion (line 24) | async function fetchCompletion(context: string, abortSignal?: AbortSigna...
function fetchCompletionStream (line 72) | async function fetchCompletionStream(
FILE: src/lib/ai/condense.ts
constant CONDENSE_THRESHOLD (line 7) | const CONDENSE_THRESHOLD = 3 // AI 消息超过 3 条时检查压缩
constant MIN_TOKEN_TO_CONDENSE (line 8) | const MIN_TOKEN_TO_CONDENSE = 100 // 单条消息超过 100 token 才压缩
function getCondensableChats (line 17) | function getCondensableChats(chats: Chat[], keepLatestCount: number): Ch...
function shouldCondense (line 34) | async function shouldCondense(chatsAfterClear: Chat[]): Promise<boolean> {
function condenseChats (line 61) | async function condenseChats(chatsAfterClear: Chat[]): Promise<Array<{ c...
FILE: src/lib/ai/description.ts
function fetchAiDesc (line 9) | async function fetchAiDesc(text: string) {
function fetchAiDescByImage (line 39) | async function fetchAiDescByImage(base64: string) {
FILE: src/lib/ai/embedding.ts
type EmbeddingResponse (line 7) | interface EmbeddingResponse {
function getEmbeddingModelInfo (line 24) | async function getEmbeddingModelInfo() {
function getRerankModelInfo (line 65) | async function getRerankModelInfo() {
function checkRerankModelAvailable (line 106) | async function checkRerankModelAvailable(): Promise<boolean> {
function fetchEmbedding (line 153) | async function fetchEmbedding(text: string): Promise<number[] | null> {
function rerankDocuments (line 208) | async function rerankDocuments(
FILE: src/lib/ai/history-messages.ts
type ChatLike (line 1) | type ChatLike = {
type MessageLike (line 8) | type MessageLike = {
function getChatsAfterLastClear (line 16) | function getChatsAfterLastClear<T extends ChatLike>(chats: T[]): T[] {
function buildChatHistoryForAI (line 24) | function buildChatHistoryForAI(chats: ChatLike[], systemPrompt?: string)...
function buildMessagesWithHistory (line 56) | function buildMessagesWithHistory(
FILE: src/lib/ai/placeholder.ts
type QuickPrompt (line 4) | interface QuickPrompt {
function getInspirationModelConfig (line 13) | async function getInspirationModelConfig() {
function fetchAiPlaceholder (line 43) | async function fetchAiPlaceholder(text: string): Promise<string | false> {
function fetchAiQuickPrompts (line 101) | async function fetchAiQuickPrompts(text: string): Promise<QuickPrompt[]> {
function fetchAiSinglePrompt (line 207) | async function fetchAiSinglePrompt(text: string): Promise<string> {
FILE: src/lib/ai/rewrite.ts
function fetchAiPolish (line 8) | async function fetchAiPolish(text: string): Promise<string> {
function fetchAiConcise (line 44) | async function fetchAiConcise(text: string): Promise<string> {
function fetchAiExpand (line 80) | async function fetchAiExpand(text: string): Promise<string> {
function fetchAiPolishStream (line 117) | async function fetchAiPolishStream(
function fetchAiConciseStream (line 171) | async function fetchAiConciseStream(
function fetchAiExpandStream (line 225) | async function fetchAiExpandStream(
FILE: src/lib/ai/token-counter.ts
function estimateTokens (line 7) | function estimateTokens(text: string): number {
function estimateChatTokens (line 17) | function estimateChatTokens(chats: Chat[]): number {
function estimateUserTokens (line 26) | function estimateUserTokens(chats: Chat[]): number {
FILE: src/lib/ai/translate.ts
function fetchAiTranslate (line 9) | async function fetchAiTranslate(text: string, targetLanguage: string): P...
FILE: src/lib/ai/types.ts
type OpenAIResult (line 1) | interface OpenAIResult {
type Usage (line 11) | interface Usage {
type OpenAIChoice (line 17) | interface OpenAIChoice {
type Message (line 24) | interface Message {
type AiModel (line 29) | interface AiModel {
type GeminiResult (line 36) | interface GeminiResult {
type GeminiCandidate (line 41) | interface GeminiCandidate {
type SafetyRating (line 53) | interface SafetyRating {
type PromptFeedback (line 58) | interface PromptFeedback {
FILE: src/lib/ai/utils.ts
function getPromptContent (line 10) | async function getPromptContent(): Promise<string> {
function getAISettings (line 31) | async function getAISettings(modelType?: string): Promise<AiConfig | und...
function validateAIService (line 82) | async function validateAIService(baseURL: string | undefined): Promise<s...
function convertImageToBase64 (line 97) | async function convertImageToBase64(imageUrl: string): Promise<string | ...
function handleAIError (line 148) | function handleAIError(error: any, showToast = true): string | null {
function prepareMessages (line 171) | async function prepareMessages(
function createOpenAIClient (line 264) | async function createOpenAIClient(AiConfig?: AiConfig) {
FILE: src/lib/audio-converter.ts
function convertToWav (line 4) | async function convertToWav(audioBlob: Blob): Promise<Blob> {
function audioBufferToWav (line 30) | function audioBufferToWav(audioBuffer: AudioBuffer): Blob {
function interleave (line 70) | function interleave(leftChannel: Float32Array, rightChannel: Float32Arra...
function writeString (line 83) | function writeString(view: DataView, offset: number, string: string) {
function floatTo16BitPCM (line 89) | function floatTo16BitPCM(view: DataView, offset: number, input: Float32A...
FILE: src/lib/audio.ts
function speakWithSystemVoice (line 9) | function speakWithSystemVoice(
function stopSystemVoice (line 51) | function stopSystemVoice(): void {
type AudioSpeechRequest (line 57) | interface AudioSpeechRequest {
type AudioSpeechResponse (line 64) | interface AudioSpeechResponse {
function resolveCurrentSpeechEngine (line 68) | function resolveCurrentSpeechEngine(task: SpeechTask) {
function fetchAudioSpeech (line 82) | async function fetchAudioSpeech(text: string, customVoice?: string, cust...
class AudioController (line 176) | class AudioController {
method constructor (line 182) | constructor(onPlayingChange?: (playing: boolean) => void) {
method playAudioBuffer (line 189) | async playAudioBuffer(audioBuffer: ArrayBuffer): Promise<void> {
method stop (line 234) | stop(): void {
method cleanup (line 249) | private cleanup(): void {
method getIsPlaying (line 261) | getIsPlaying(): boolean {
function playAudioBuffer (line 269) | function playAudioBuffer(audioBuffer: ArrayBuffer): Promise<void> {
function textToSpeechAndPlay (line 278) | async function textToSpeechAndPlay(
function stopCurrentAudio (line 352) | function stopCurrentAudio(): void {
function getCurrentAudioPlayingState (line 364) | function getCurrentAudioPlayingState(): boolean {
type AudioTranscriptionRequest (line 371) | interface AudioTranscriptionRequest {
type AudioTranscriptionResponse (line 379) | interface AudioTranscriptionResponse {
function transcribeRecording (line 385) | async function transcribeRecording(audioBlob: Blob): Promise<string> {
function fetchAudioTranscription (line 398) | async function fetchAudioTranscription(audioBlob: Blob): Promise<string> {
FILE: src/lib/bm25.ts
type BM25Document (line 9) | interface BM25Document {
type BM25Result (line 17) | interface BM25Result {
class BM25Index (line 25) | class BM25Index {
method constructor (line 36) | constructor(k1: number = 1.2, b: number = 0.75) {
method tokenize (line 49) | private tokenize(text: string): string[] {
method index (line 81) | index(documents: BM25Document[]): void {
method calculateIDF (line 119) | private calculateIDF(N: number): void {
method search (line 142) | search(query: string, limit: number = 10): BM25Result[] {
method update (line 188) | update(document: BM25Document): void {
method delete (line 202) | delete(docId: string): void {
method size (line 223) | size(): number {
method clear (line 230) | clear(): void {
function initBM25Index (line 248) | function initBM25Index(documents: BM25Document[]): BM25Index {
function getBM25Index (line 259) | function getBM25Index(): BM25Index | null {
function clearBM25Index (line 266) | function clearBM25Index(): void {
FILE: src/lib/check.ts
function isMobileDevice (line 8) | function isMobileDevice() {
function checkIsTauri (line 32) | function checkIsTauri(): boolean {
FILE: src/lib/context/loader.ts
type ContextResult (line 7) | interface ContextResult {
class ContextLoader (line 15) | class ContextLoader {
method cosineSimilarity (line 22) | private cosineSimilarity(vecA: number[], vecB: number[]): number {
method getContextForQuery (line 47) | async getContextForQuery(query: string): Promise<ContextResult> {
method formatMemoriesForPrompt (line 115) | formatMemoriesForPrompt(context: ContextResult): string {
method clearCache (line 137) | clearCache(): void {
FILE: src/lib/default-filename.ts
function generateUniqueFilename (line 10) | async function generateUniqueFilename(parentPath: string = '', baseName:...
function generateCopyFilename (line 51) | async function generateCopyFilename(parentPath: string, originalName: st...
function generateCopyFoldername (line 103) | async function generateCopyFoldername(parentPath: string, originalName: ...
FILE: src/lib/editor-layout-styles.ts
function getEditorContentContainerClass (line 1) | function getEditorContentContainerClass(options: {
FILE: src/lib/emitter.ts
type Events (line 6) | interface Events {
FILE: src/lib/event-report.ts
constant API_CONFIG (line 13) | const API_CONFIG = {
type EventType (line 21) | enum EventType {
type AppStartEventData (line 28) | interface AppStartEventData {
type AppUpgradeDownloadEventData (line 37) | interface AppUpgradeDownloadEventData {
type AppUpgradeUpgradeEventData (line 47) | interface AppUpgradeUpgradeEventData {
type EventData (line 57) | type EventData = AppStartEventData | AppUpgradeDownloadEventData | AppUp...
type ReportRequestBody (line 60) | interface ReportRequestBody {
function generateRFC3339Timestamp (line 71) | function generateRFC3339Timestamp(): string {
function generateNonce (line 79) | function generateNonce(): string {
function generateSignature (line 89) | function generateSignature(
function getVersionCode (line 106) | async function getVersionCode(): Promise<number> {
function getDeviceId (line 130) | async function getDeviceId(): Promise<string | undefined> {
function getDeviceInfo (line 143) | async function getDeviceInfo() {
function reportEvent (line 167) | async function reportEvent(
function reportAppStart (line 221) | async function reportAppStart(): Promise<boolean> {
function reportAppUpgradeDownload (line 245) | async function reportAppUpgradeDownload(
function reportAppUpgradeUpgrade (line 272) | async function reportAppUpgradeUpgrade(
FILE: src/lib/files.ts
type MarkdownFile (line 5) | interface MarkdownFile {
type LinkedFolder (line 21) | interface LinkedFolder {
type LinkedResource (line 30) | type LinkedResource = MarkdownFile | LinkedFolder;
function isLinkedFolder (line 33) | function isLinkedFolder(resource: LinkedResource): resource is LinkedFol...
function collectMarkdownFiles (line 38) | async function collectMarkdownFiles(folderPath: string): Promise<Array<{...
function getAllMarkdownFiles (line 85) | async function getAllMarkdownFiles(includeMetadata: boolean = false): Pr...
FILE: src/lib/folder-vector.ts
type FolderVectorMode (line 6) | type FolderVectorMode = 'missing' | 'recalculate';
type CalculateFolderVectorsOptions (line 8) | interface CalculateFolderVectorsOptions {
type CalculateFolderVectorsResult (line 21) | interface CalculateFolderVectorsResult {
function calculateFolderVectors (line 29) | async function calculateFolderVectors({
FILE: src/lib/fuzzy-search.ts
type SearchItem (line 4) | interface SearchItem {
type MatchInfo (line 22) | interface MatchInfo {
type FuzzySearchResult (line 29) | interface FuzzySearchResult {
type FuzzySearchOptions (line 37) | interface FuzzySearchOptions {
class RustFuzzySearch (line 45) | class RustFuzzySearch {
method constructor (line 50) | constructor(items: any[], options: Partial<FuzzySearchOptions> = {}) {
method search (line 62) | async search(query: string): Promise<FuzzySearchResult[]> {
method searchParallel (line 96) | async searchParallel(query: string): Promise<FuzzySearchResult[]> {
FILE: src/lib/image-handler.ts
type ImageUploadResult (line 9) | interface ImageUploadResult {
function handleImageUpload (line 24) | async function handleImageUpload(
function saveImageLocally (line 78) | async function saveImageLocally(file: File, markdownPath: string): Promi...
function ensureDirectoryExists (line 137) | async function ensureDirectoryExists(dirPath: string): Promise<void> {
function isImageHostingConfigured (line 161) | async function isImageHostingConfigured(): Promise<boolean> {
function fileToBase64 (line 172) | function fileToBase64(file: File): Promise<string> {
FILE: src/lib/imageHosting/github.ts
function createImageRepo (line 10) | async function createImageRepo(name: string, isPrivate?: boolean) {
function checkImageRepoState (line 54) | async function checkImageRepoState(name: string) {
function uploadImageByGithub (line 89) | async function uploadImageByGithub(file: File) {
function getImageFiles (line 165) | async function getImageFiles({ path }: { path: string }) {
FILE: src/lib/imageHosting/index.ts
function uploadImage (line 7) | async function uploadImage(file: File) {
FILE: src/lib/imageHosting/picgo.ts
type PicgoImageHostingSetting (line 7) | interface PicgoImageHostingSetting {
function uploadImageByPicgo (line 12) | async function uploadImageByPicgo(image: File) {
function checkPicgoState (line 52) | async function checkPicgoState() {
FILE: src/lib/imageHosting/s3.ts
type S3Config (line 6) | interface S3Config {
function generateSignature (line 17) | async function generateSignature(
function sha256Hex (line 84) | async function sha256Hex(data: string): Promise<string> {
function hmacSha256 (line 92) | async function hmacSha256(key: CryptoKey, data: string): Promise<ArrayBu...
function hmacSha256Hex (line 97) | async function hmacSha256Hex(key: CryptoKey, data: string): Promise<stri...
function getSignatureKey (line 104) | async function getSignatureKey(key: string, dateStamp: string, regionNam...
function testS3Connection (line 158) | async function testS3Connection(config: S3Config): Promise<boolean> {
function uploadImageByS3 (line 281) | async function uploadImageByS3(file: File): Promise<string | undefined> {
FILE: src/lib/imageHosting/smms.ts
constant BASE_URL (line 4) | const BASE_URL = 'https://sm.ms/api/v2'
type SMMSImageHostingSetting (line 6) | interface SMMSImageHostingSetting {
type SMMSUserInfo (line 10) | interface SMMSUserInfo {
function uploadImageBySmms (line 22) | async function uploadImageBySmms(file: File) {
function getUserInfo (line 50) | async function getUserInfo() {
FILE: src/lib/infographic.ts
type InfographicThemeMode (line 12) | type InfographicThemeMode = 'dark' | 'light';
type InfographicRenderOptions (line 14) | interface InfographicRenderOptions {
constant INFOGRAPHIC_LANGUAGE (line 18) | const INFOGRAPHIC_LANGUAGE = 'infographic';
constant INFOGRAPHIC_CONTAINER_CLASS (line 19) | const INFOGRAPHIC_CONTAINER_CLASS = 'infographic-diagram';
constant INFOGRAPHIC_MIN_HEIGHT (line 20) | const INFOGRAPHIC_MIN_HEIGHT = 120;
constant DATA_PROCESSED_ATTR (line 22) | const DATA_PROCESSED_ATTR = 'data-infographic-processed';
constant DATA_CODE_ATTR (line 23) | const DATA_CODE_ATTR = 'data-infographic-code';
constant DATA_THEME_ATTR (line 24) | const DATA_THEME_ATTR = 'data-infographic-theme';
constant DATA_RENDER_ID_ATTR (line 25) | const DATA_RENDER_ID_ATTR = 'data-infographic-render-id';
FILE: src/lib/mark-to-markdown.ts
function markToMarkdown (line 6) | function markToMarkdown(mark: Mark): string {
FILE: src/lib/markdown.ts
function extractTitle (line 2) | function extractTitle(content: string) {
FILE: src/lib/mcp/client.ts
class MCPClient (line 17) | class MCPClient {
method constructor (line 22) | constructor(config: MCPServerConfig) {
method connect (line 29) | async connect(): Promise<void> {
method connectStdio (line 40) | private async connectStdio(): Promise<void> {
method connectHttp (line 56) | private async connectHttp(): Promise<void> {
method initialize (line 67) | async initialize(): Promise<InitializeResult> {
method listTools (line 84) | async listTools(): Promise<MCPTool[]> {
method callTool (line 109) | async callTool(name: string, args: any = {}): Promise<CallToolResult> {
method listResources (line 125) | async listResources(): Promise<MCPResource[]> {
method readResource (line 137) | async readResource(uri: string): Promise<string> {
method disconnect (line 149) | async disconnect(): Promise<void> {
method sendRequest (line 163) | private async sendRequest(method: string, params: any): Promise<any> {
method sendStdioRequest (line 181) | private async sendStdioRequest(request: JSONRPCRequest): Promise<any> {
method sendHttpRequest (line 203) | private async sendHttpRequest(request: JSONRPCRequest): Promise<any> {
FILE: src/lib/mcp/init.ts
function initMcp (line 8) | async function initMcp() {
function cleanupMcp (line 26) | async function cleanupMcp() {
FILE: src/lib/mcp/integration.ts
class MCPIntegration (line 10) | class MCPIntegration {
method constructor (line 13) | private constructor() {}
method getInstance (line 15) | static getInstance(): MCPIntegration {
method initialize (line 26) | async initialize(): Promise<void> {
method handleToolCall (line 35) | async handleToolCall(
method cleanup (line 80) | async cleanup(): Promise<void> {
FILE: src/lib/mcp/runtime-assistant.ts
type MCPRuntimeKind (line 3) | type MCPRuntimeKind =
type MCPInstallRecipe (line 11) | interface MCPInstallRecipe {
type MCPRuntimeCheckResult (line 20) | interface MCPRuntimeCheckResult {
type MCPRuntimeInspection (line 28) | interface MCPRuntimeInspection {
type MCPRuntimeInstallResult (line 35) | interface MCPRuntimeInstallResult {
type MCPCancelInstallResult (line 43) | interface MCPCancelInstallResult {
type MCPInstallProgressStage (line 48) | type MCPInstallProgressStage =
type MCPInstallProgressEvent (line 55) | interface MCPInstallProgressEvent {
function inspectMcpRuntime (line 63) | async function inspectMcpRuntime(command: string, args: string[] = []): ...
function installMcpRuntime (line 67) | async function installMcpRuntime(recipeId: string): Promise<MCPRuntimeIn...
function cancelMcpRuntimeInstall (line 71) | async function cancelMcpRuntimeInstall(recipeId: string): Promise<MCPCan...
FILE: src/lib/mcp/server-manager.ts
type MCPBatchTestResult (line 11) | interface MCPBatchTestResult {
class MCPServerManager (line 25) | class MCPServerManager {
method constructor (line 29) | private constructor() {}
method getInstance (line 31) | static getInstance(): MCPServerManager {
method connectServer (line 41) | async connectServer(config: MCPServerConfig): Promise<void> {
method disconnectServer (line 102) | async disconnectServer(serverId: string): Promise<void> {
method reconnectServer (line 121) | async reconnectServer(config: MCPServerConfig): Promise<void> {
method connectEnabledServers (line 126) | async connectEnabledServers(servers: MCPServerConfig[]): Promise<void> {
method getServerTools (line 143) | getServerTools(serverId: string): MCPTool[] {
method getAllTools (line 152) | getAllTools(): Map<string, MCPTool[]> {
method callTool (line 171) | async callTool(
method getServerResources (line 187) | getServerResources(serverId: string): MCPResource[] {
method readResource (line 196) | async readResource(serverId: string, uri: string): Promise<string> {
method disconnectAll (line 208) | async disconnectAll(): Promise<void> {
method testConnection (line 219) | async testConnection(config: MCPServerConfig): Promise<boolean> {
method testConnections (line 267) | async testConnections(configs: MCPServerConfig[]): Promise<MCPBatchTes...
FILE: src/lib/mcp/tools.ts
function getSelectedServerTools (line 8) | function getSelectedServerTools(): Array<{
function getOpenAIFunctions (line 35) | function getOpenAIFunctions(selectedServerIds: string[]): any[] {
function searchTools (line 64) | function searchTools(query: string): Array<{
function callTool (line 86) | async function callTool(
function validateToolArgs (line 97) | function validateToolArgs(tool: MCPTool, args: any): {
function formatToolResult (line 128) | function formatToolResult(result: CallToolResult): string {
function toolToOpenAIFunction (line 144) | function toolToOpenAIFunction(tool: MCPTool) {
FILE: src/lib/mcp/types.ts
type MCPServerType (line 6) | type MCPServerType = 'stdio' | 'http'
type MCPServerConfig (line 9) | interface MCPServerConfig {
type MCPTool (line 30) | interface MCPTool {
type MCPResource (line 41) | interface MCPResource {
type JSONRPCRequest (line 49) | interface JSONRPCRequest {
type JSONRPCResponse (line 57) | interface JSONRPCResponse {
type InitializeResult (line 69) | interface InitializeResult {
type CallToolResult (line 83) | interface CallToolResult {
type ServerStatus (line 94) | type ServerStatus = 'disconnected' | 'connecting' | 'connected' | 'error'
type MCPServerState (line 97) | interface MCPServerState {
FILE: src/lib/ocr.ts
function ocr (line 5) | async function ocr(path: string): Promise<string> {
FILE: src/lib/outline-preferences.ts
type OutlinePosition (line 1) | type OutlinePosition = 'left' | 'right'
constant DEFAULT_OUTLINE_POSITION (line 3) | const DEFAULT_OUTLINE_POSITION: OutlinePosition = 'right'
function normalizeOutlinePosition (line 5) | function normalizeOutlinePosition(value: unknown): OutlinePosition {
function isOutlineOnLeft (line 9) | function isOutlineOnLeft(position: OutlinePosition): boolean {
FILE: src/lib/outline-styles.ts
function getOutlinePanelClass (line 1) | function getOutlinePanelClass(position: 'left' | 'right' = 'right') {
function getOutlineHeadingTextClass (line 5) | function getOutlineHeadingTextClass() {
FILE: src/lib/path.ts
function computedParentPath (line 4) | function computedParentPath(item: DirTree) {
function getCurrentFolder (line 18) | function getCurrentFolder(path: string, fileTree: DirTree[]) {
FILE: src/lib/pdf.ts
function isTextItem (line 12) | function isTextItem(item: any): item is { str: string; transform: number...
function ocrPage (line 19) | async function ocrPage(canvas: HTMLCanvasElement, pageNum: number): Prom...
function extractTextFromPDF (line 47) | async function extractTextFromPDF(
function extractTextWithOCR (line 145) | async function extractTextWithOCR(
function extractTextFromPDFFile (line 185) | async function extractTextFromPDFFile(file: File): Promise<string> {
function getPDFInfo (line 220) | async function getPDFInfo(filePath: string): Promise<{ numPages: number ...
function getPDFInfoFromFile (line 242) | async function getPDFInfoFromFile(file: File): Promise<{ numPages: numbe...
FILE: src/lib/rag.ts
function handleRAGError (line 28) | function handleRAGError(error: unknown, context: string, showToast: bool...
function generateContentHash (line 44) | function generateContentHash(content: string): string {
function runWithConcurrencyLimit (line 51) | async function runWithConcurrencyLimit<T>(
function chunkText (line 96) | function chunkText(
function initBM25Search (line 181) | async function initBM25Search(): Promise<void> {
constant STOP_WORDS (line 203) | const STOP_WORDS = new Set([
constant SYNONYM_DICT (line 221) | const SYNONYM_DICT: Record<string, string[]> = {
function isStopWord (line 249) | function isStopWord(keyword: string): boolean {
type QueryVariant (line 257) | interface QueryVariant {
function expandWithSynonyms (line 269) | function expandWithSynonyms(query: string, maxVariants: number = 3): Que...
function transformQueries (line 315) | function transformQueries(
function expandWithSentenceWindow (line 353) | async function expandWithSentenceWindow(
function searchWithBM25 (line 432) | async function searchWithBM25(query: string, limit: number = 10): Promis...
function processMarkdownFile (line 445) | async function processMarkdownFile(
function getWorkspaceFiles (line 518) | async function getWorkspaceFiles(): Promise<DirTree[]> {
function processAllMarkdownFiles (line 574) | async function processAllMarkdownFiles(onProgress?: (current: number, to...
function getFilePath (line 654) | async function getFilePath(item: DirTree): Promise<string> {
type SearchItem (line 676) | interface SearchItem {
type FuzzySearchResult (line 694) | interface FuzzySearchResult {
function collectMarkdownContents (line 708) | async function collectMarkdownContents(): Promise<SearchItem[]> {
type SearchResult (line 762) | interface SearchResult {
type Keyword (line 775) | interface Keyword {
type RagSource (line 783) | interface RagSource {
function getContextForQuery (line 794) | async function getContextForQuery(keywords: Keyword[]): Promise<{
type NormalizationConfig (line 1081) | interface NormalizationConfig {
function normalizeScore (line 1092) | function normalizeScore(
function calculateHybridScore (line 1135) | function calculateHybridScore(
function mergeResultsByDocument (line 1176) | function mergeResultsByDocument(
function calculateContentOverlap (line 1258) | function calculateContentOverlap(content1: string, content2: string): nu...
function handleFileUpdate (line 1281) | async function handleFileUpdate(filePath: string, content: string): Prom...
function checkEmbeddingModelAvailable (line 1294) | async function checkEmbeddingModelAvailable(): Promise<boolean> {
function showVectorProcessingToast (line 1308) | function showVectorProcessingToast(message: string) {
function collectMarkdownContentsInFolder (line 1318) | async function collectMarkdownContentsInFolder(folderPath: string): Prom...
function getContextForQueryInFolder (line 1394) | async function getContextForQueryInFolder(
FILE: src/lib/record-navigation.ts
function handleRecordComplete (line 9) | function handleRecordComplete(router?: any) {
FILE: src/lib/search-utils.ts
type SearchMatch (line 1) | interface SearchMatch {
type SearchableItem (line 8) | interface SearchableItem {
type SearchResult (line 15) | interface SearchResult<T = any> {
function findExactMatches (line 26) | function findExactMatches(text: string, query: string): SearchMatch[] {
function findFuzzyMatches (line 54) | function findFuzzyMatches(text: string, query: string): SearchMatch[] {
function calculateScore (line 100) | function calculateScore(
function generateHighlight (line 125) | function generateHighlight(text: string, matches: SearchMatch[], maxLeng...
function search (line 146) | function search<T extends SearchableItem>(
FILE: src/lib/shortcut/quick-record-text.ts
function initQuickRecordText (line 4) | function initQuickRecordText() {
FILE: src/lib/shortcut/show-window.ts
function initShowWindow (line 4) | function initShowWindow() {
FILE: src/lib/skills/dependency-installer.ts
type DependencyInfo (line 13) | interface DependencyInfo {
type InstallResult (line 23) | interface InstallResult {
type DependencyInstallRequest (line 30) | interface DependencyInstallRequest {
constant MODULE_TO_PACKAGE (line 40) | const MODULE_TO_PACKAGE: Record<string, { python?: string; node?: string...
function parseDependencyError (line 61) | function parseDependencyError(stderr: string): DependencyInfo | null {
function commandExists (line 123) | async function commandExists(cmd: string): Promise<boolean> {
function detectNodePackageManager (line 132) | async function detectNodePackageManager(workingDirectory: string): Promi...
function detectPythonCommand (line 154) | async function detectPythonCommand(preferred: string): Promise<string | ...
function installDependency (line 173) | async function installDependency(dep: DependencyInfo, targetDir?: string...
function handleDependencyError (line 261) | async function handleDependencyError(stderr: string, targetDir?: string)...
function ensureDependencyForCommand (line 271) | async function ensureDependencyForCommand(
FILE: src/lib/skills/executor.ts
class SkillExecutor (line 30) | class SkillExecutor {
method formatSkillForExecution (line 47) | formatSkillForExecution(skill: SkillContent, userInput: string): string {
method formatSkillsAsSystemPrompt (line 124) | formatSkillsAsSystemPrompt(skills: SkillContent[]): string {
method formatSkillAsSystemPrompt (line 186) | formatSkillAsSystemPrompt(skill: SkillContent): string {
method executeScript (line 202) | async executeScript(
method executeScriptByType (line 249) | private async executeScriptByType(
method getScripts (line 316) | getScripts(skill: SkillContent): SkillScript[] {
method hasScript (line 327) | hasScript(skill: SkillContent, scriptName: string): boolean {
method getMetadataSummary (line 342) | getMetadataSummary(skill: SkillContent): string {
method loadReference (line 361) | async loadReference(
method loadAsset (line 400) | async loadAsset(
method createExecutionRecord (line 444) | createExecutionRecord(
method getExecutionHistory (line 476) | getExecutionHistory(limit?: number): SkillExecutionRecord[] {
method getSkillExecutionHistory (line 490) | getSkillExecutionHistory(skillId: string, limit?: number): SkillExecut...
method clearExecutionHistory (line 501) | clearExecutionHistory(): void {
method isToolAllowed (line 516) | isToolAllowed(skill: SkillContent, toolName: string): boolean {
method getAllowedTools (line 529) | getAllowedTools(skill: SkillContent): string[] {
method generateRecordId (line 540) | private generateRecordId(): string {
method createExecutionResult (line 556) | createExecutionResult(
FILE: src/lib/skills/manager.ts
class SkillManager (line 47) | class SkillManager {
method initialize (line 60) | async initialize(): Promise<void> {
method reload (line 72) | async reload(): Promise<void> {
method discoverSkills (line 86) | async discoverSkills(): Promise<void> {
method discoverProjectSkills (line 97) | private async discoverProjectSkills(): Promise<void> {
method discoverGlobalSkills (line 121) | private async discoverGlobalSkills(): Promise<void> {
method loadSkillFromDirectory (line 145) | private async loadSkillFromDirectory(
method loadScriptsFromDirectory (line 333) | private async loadScriptsFromDirectory(
method loadReferencesFromDirectory (line 400) | private async loadReferencesFromDirectory(
method loadAssetsFromDirectory (line 444) | private async loadAssetsFromDirectory(
method loadRootMdFiles (line 507) | private async loadRootMdFiles(
method registerSkill (line 555) | registerSkill(skill: SkillContent): void {
method unregisterSkill (line 562) | unregisterSkill(skillId: string): void {
method getAllSkills (line 574) | getAllSkills(): SkillContent[] {
method getSkillsByScope (line 581) | getSkillsByScope(scope: SkillScope): SkillContent[] {
method getEnabledSkills (line 590) | async getEnabledSkills(): Promise<SkillContent[]> {
method getUserInvocableSkills (line 599) | getUserInvocableSkills(): SkillContent[] {
method getSkill (line 608) | getSkill(id: string): SkillContent | undefined {
method hasSkill (line 615) | hasSkill(id: string): boolean {
method getSkillScripts (line 622) | getSkillScripts(skillId: string): SkillScript[] {
method getSkillReferences (line 630) | getSkillReferences(skillId: string): SkillReference[] {
method getSkillAssets (line 638) | getSkillAssets(skillId: string): SkillAsset[] {
method matchRelevantSkills (line 654) | async matchRelevantSkills(
method calculateMatchScore (line 681) | private calculateMatchScore(
method extractKeywords (line 722) | private extractKeywords(description: string): string[] {
method hasSemanticOverlap (line 760) | private hasSemanticOverlap(text1: string, text2: string): boolean {
method validateSkill (line 782) | validateSkill(content: string): { valid: boolean; errors: string[] } {
method fileExists (line 806) | private async fileExists(
method directoryExists (line 828) | private async directoryExists(
method listSkillDirectories (line 838) | private async listSkillDirectories(
method readFileContent (line 873) | private async readFileContent(
method getSkillFileInfo (line 891) | getSkillFileInfo(id: string): SkillFileInfo | undefined {
method getAllSkillFileInfo (line 898) | getAllSkillFileInfo(): SkillFileInfo[] {
function resetSkillManager (line 910) | function resetSkillManager(): void {
FILE: src/lib/skills/parser.ts
function parseSkillFile (line 26) | function parseSkillFile(content: string): ParsedSkillFile {
function parseYamlMetadata (line 64) | function parseYamlMetadata(yamlContent: string): SkillYamlMetadata {
function parseValue (line 212) | function parseValue(value: string): string {
function parseAllowedTools (line 235) | function parseAllowedTools(value: string): string[] {
function parseBoolean (line 266) | function parseBoolean(value: string): boolean {
function serializeSkillFile (line 282) | function serializeSkillFile(
function generateSkillId (line 352) | function generateSkillId(directoryName: string): string {
function isValidSkillId (line 371) | function isValidSkillId(id: string): boolean {
function isValidSkillName (line 390) | function isValidSkillName(name: string): boolean {
function isValidSkillDescription (line 410) | function isValidSkillDescription(description: string): boolean {
function detectScriptType (line 421) | function detectScriptType(filename: string, content?: string): ScriptTyp...
function extractReferenceLinks (line 453) | function extractReferenceLinks(content: string): string[] {
function extractScriptReferences (line 473) | function extractScriptReferences(content: string): string[] {
FILE: src/lib/skills/path-utils.ts
function resolveSkillDirectory (line 18) | async function resolveSkillDirectory(
function resolveScriptRelativePath (line 54) | function resolveScriptRelativePath(
function escapeShellArg (line 86) | function escapeShellArg(arg: string): string {
function buildShellCommand (line 106) | function buildShellCommand(
FILE: src/lib/skills/runtime-paths.ts
type ClassifiedSkillScriptPath (line 1) | interface ClassifiedSkillScriptPath {
function hasScriptExtension (line 6) | function hasScriptExtension(filePath: string): boolean {
function classifySkillScriptPath (line 10) | function classifySkillScriptPath(arg: string): ClassifiedSkillScriptPath {
FILE: src/lib/skills/runtime.ts
type SkillRuntimeContext (line 10) | interface SkillRuntimeContext {
type SkillExecutionRequest (line 22) | interface SkillExecutionRequest {
type SkillExecutionData (line 29) | interface SkillExecutionData {
type SkillExecutionOutcome (line 42) | interface SkillExecutionOutcome {
constant OUTPUT_FILE_EXTENSIONS (line 49) | const OUTPUT_FILE_EXTENSIONS = new Set([
constant SCRIPT_FILE_EXTENSIONS (line 65) | const SCRIPT_FILE_EXTENSIONS = new Set(['js', 'mjs', 'cjs', 'py', 'sh', ...
function getExtension (line 67) | function getExtension(filePath: string): string {
function isScriptLikeFile (line 73) | function isScriptLikeFile(filePath: string): boolean {
function isOutputLikeFile (line 77) | function isOutputLikeFile(filePath: string): boolean {
function isAbsolutePath (line 81) | function isAbsolutePath(filePath: string): boolean {
function isSkillBuiltInPath (line 85) | function isSkillBuiltInPath(filePath: string): boolean {
function isSafeRelativePath (line 89) | function isSafeRelativePath(filePath: string): boolean {
function toPosixPath (line 93) | function toPosixPath(filePath: string): string {
function pathExists (line 97) | async function pathExists(filePath: string, baseDir?: BaseDirectory): Pr...
function ensureDir (line 105) | async function ensureDir(dir: string, baseDir?: BaseDirectory): Promise<...
function resolveWritableRuntimeDir (line 115) | async function resolveWritableRuntimeDir(
function resolveContext (line 131) | async function resolveContext(skillId: string): Promise<SkillRuntimeCont...
function normalizeArg (line 167) | async function normalizeArg(arg: string, context: SkillRuntimeContext): ...
function parseCommand (line 228) | function parseCommand(command: string, args: string[]): { cmd: string; c...
function normalizeExecutionPlan (line 243) | async function normalizeExecutionPlan(
function determineWorkingDirectory (line 286) | function determineWorkingDirectory(
function snapshotOutputFiles (line 301) | async function snapshotOutputFiles(context: SkillRuntimeContext): Promis...
function collectGeneratedOutputs (line 316) | async function collectGeneratedOutputs(context: SkillRuntimeContext, pre...
function executeSkillRuntime (line 407) | async function executeSkillRuntime(
FILE: src/lib/skills/types.ts
type SkillScope (line 15) | type SkillScope = 'global' | 'project'
type ScriptType (line 20) | type ScriptType = 'python' | 'bash' | 'javascript' | 'node' | 'shell'
type SkillScript (line 25) | interface SkillScript {
type SkillReference (line 35) | interface SkillReference {
type SkillAsset (line 44) | interface SkillAsset {
type SkillMetadata (line 54) | interface SkillMetadata {
type SkillContent (line 91) | interface SkillContent {
type SkillYamlMetadata (line 108) | interface SkillYamlMetadata {
type SkillDependency (line 132) | interface SkillDependency {
type ParsedSkillFile (line 141) | interface ParsedSkillFile {
type ValidationResult (line 154) | interface ValidationResult {
type ValidationError (line 163) | interface ValidationError {
type ValidationWarning (line 172) | interface ValidationWarning {
type ScriptExecutionResult (line 185) | interface ScriptExecutionResult {
type SkillExecutionResult (line 197) | interface SkillExecutionResult {
type SkillExecutionRecord (line 210) | interface SkillExecutionRecord {
type SkillFileInfo (line 226) | interface SkillFileInfo {
type SkillMatchScore (line 257) | interface SkillMatchScore {
constant SKILL_FILE_NAME (line 270) | const SKILL_FILE_NAME = 'SKILL.md'
constant SCRIPTS_DIR_NAME (line 275) | const SCRIPTS_DIR_NAME = 'scripts'
constant REFERENCES_DIR_NAME (line 276) | const REFERENCES_DIR_NAME = 'references'
constant ASSETS_DIR_NAME (line 277) | const ASSETS_DIR_NAME = 'assets'
constant REFERENCE_FILE_NAME (line 283) | const REFERENCE_FILE_NAME = 'REFERENCE.md'
constant EXAMPLES_FILE_NAME (line 284) | const EXAMPLES_FILE_NAME = 'EXAMPLES.md'
constant KEYWORDS_FILE_NAME (line 285) | const KEYWORDS_FILE_NAME = 'KEYWORDS.md'
constant SKILLS_DIR_NAME (line 290) | const SKILLS_DIR_NAME = 'skills'
constant DEFAULT_SKILL_VERSION (line 295) | const DEFAULT_SKILL_VERSION = '1.0.0'
constant DEFAULT_SKILL_ENABLED (line 296) | const DEFAULT_SKILL_ENABLED = true
constant DEFAULT_USER_INVOCABLE (line 297) | const DEFAULT_USER_INVOCABLE = true
constant SCRIPT_EXTENSIONS (line 302) | const SCRIPT_EXTENSIONS: Record<ScriptType, string[]> = {
constant SCRIPT_SHEBANG (line 313) | const SCRIPT_SHEBANG: Record<ScriptType, string[]> = {
FILE: src/lib/skills/utils.ts
function isSkillsFolder (line 19) | function isSkillsFolder(folderName: string): boolean {
function isInSkillsFolder (line 26) | function isInSkillsFolder(path: string): boolean {
function isInSkillSubdirectory (line 37) | function isInSkillSubdirectory(path: string): {
function getSkillsFolderIcon (line 90) | function getSkillsFolderIcon(): string {
function shouldHideKnowledgeBaseOptions (line 97) | function shouldHideKnowledgeBaseOptions(folderName: string, filePath: st...
function filterKnowledgeBaseMenuItems (line 104) | function filterKnowledgeBaseMenuItems(
function extractSkillIdFromPath (line 124) | function extractSkillIdFromPath(path: string): string | null {
function isSkillSubfolder (line 146) | function isSkillSubfolder(path: string): boolean {
function isSkillFile (line 153) | function isSkillFile(fileName: string): boolean {
function getSkillDirectoryStructure (line 161) | function getSkillDirectoryStructure(): {
function formatSkillList (line 191) | function formatSkillList(skills: Array<{ id: string; name: string; descr...
function validateSkillDirectoryStructure (line 211) | function validateSkillDirectoryStructure(files: string[]): {
function getMigrationGuide (line 266) | function getMigrationGuide(): {
function getSkillTemplate (line 307) | function getSkillTemplate(skillName: string, description: string): string {
FILE: src/lib/skills/validator.ts
function validateSkillYamlMetadata (line 31) | function validateSkillYamlMetadata(metadata: SkillYamlMetadata): Validat...
function validateSkillContent (line 156) | function validateSkillContent(skill: SkillContent): ValidationResult {
function validateSkillId (line 233) | function validateSkillId(id: string): boolean {
function isValidVersion (line 247) | function isValidVersion(version: string): boolean {
function isValidToolName (line 257) | function isValidToolName(toolName: string): boolean {
function formatValidationResult (line 273) | function formatValidationResult(result: ValidationResult): string {
function getValidationSummary (line 305) | function getValidationSummary(result: ValidationResult): string {
FILE: src/lib/speech/capabilities.ts
function getSpeechCapabilities (line 3) | function getSpeechCapabilities({ audioModel, sttModel }: SpeechCapabilit...
FILE: src/lib/speech/preferences.ts
function normalizeSpeechMode (line 3) | function normalizeSpeechMode(value: unknown): SpeechMode {
FILE: src/lib/speech/resolver.ts
function getAvailability (line 3) | function getAvailability(task: SpeechTask, capabilities: SpeechCapabilit...
function resolveSpeechEngine (line 17) | function resolveSpeechEngine(
FILE: src/lib/speech/runtime.ts
type SpeechPreferenceInput (line 5) | interface SpeechPreferenceInput extends SpeechCapabilityInput {
function resolvePreferredSpeechEngine (line 10) | function resolvePreferredSpeechEngine(
function shouldFallbackToModelAfterLocalFailure (line 21) | function shouldFallbackToModelAfterLocalFailure(settings: SpeechPreferen...
FILE: src/lib/speech/transcription-fallback.ts
constant NO_TRANSCRIPTION_MESSAGE (line 1) | const NO_TRANSCRIPTION_MESSAGE = 'No transcription. Configure a speech r...
function getTranscriptionFallbackMessage (line 3) | function getTranscriptionFallbackMessage(sttModel: string): string {
FILE: src/lib/speech/types.ts
type SpeechTask (line 1) | type SpeechTask = 'tts' | 'stt'
type SpeechMode (line 3) | type SpeechMode = 'auto' | 'local' | 'model'
type SpeechEngine (line 5) | type SpeechEngine = 'local' | 'model'
type SpeechCapabilities (line 7) | interface SpeechCapabilities {
type SpeechCapabilityInput (line 14) | interface SpeechCapabilityInput {
type SpeechEngineResolution (line 19) | interface SpeechEngineResolution {
FILE: src/lib/sync/auto-sync.ts
function getStore (line 34) | async function getStore(): Promise<Store> {
function getGitlabBranch (line 44) | async function getGitlabBranch(): Promise<string> {
function getGiteaBranch (line 52) | async function getGiteaBranch(): Promise<string> {
function getLocalRecordedSha (line 60) | async function getLocalRecordedSha(filePath: string): Promise<string | n...
function setLocalRecordedSha (line 69) | async function setLocalRecordedSha(filePath: string, sha: string): Promi...
type FileMetadata (line 76) | interface FileMetadata {
type SyncResult (line 85) | interface SyncResult {
function calculateFileSha (line 96) | async function calculateFileSha(content: string): Promise<string> {
function getLocalFileMetadata (line 107) | async function getLocalFileMetadata(path: string): Promise<FileMetadata> {
function getRemoteFileInfo (line 160) | async function getRemoteFileInfo(path: string): Promise<{ sha?: string; ...
function compareFileVersions (line 248) | async function compareFileVersions(path: string): Promise<SyncResult> {
function pullRemoteFile (line 392) | async function pullRemoteFile(path: string): Promise<string> {
function ensureDirectoryExists (line 467) | async function ensureDirectoryExists(filePath: string): Promise<void> {
function saveLocalFile (line 508) | async function saveLocalFile(path: string, content: string): Promise<voi...
function getRemoteCommitInfo (line 535) | async function getRemoteCommitInfo(path: string): Promise<{
function autoSyncIfNeeded (line 621) | async function autoSyncIfNeeded(path: string, options: {
function performSync (line 690) | async function performSync(path: string, enableConflictResolution: boole...
function hasNetworkConnection (line 800) | async function hasNetworkConnection(): Promise<boolean> {
function compareS3FileVersions (line 874) | async function compareS3FileVersions(path: string): Promise<SyncResult> {
function compareWebDAVFileVersions (line 959) | async function compareWebDAVFileVersions(path: string): Promise<SyncResu...
FILE: src/lib/sync/conflict-resolution.ts
type ConflictResolutionStrategy (line 7) | type ConflictResolutionStrategy = 'local' | 'remote' | 'manual'
type ConflictResolution (line 9) | interface ConflictResolution {
type SyncLock (line 14) | interface SyncLock {
function getDeviceId (line 24) | async function getDeviceId(): Promise<string> {
function getUserName (line 41) | async function getUserName(): Promise<string> {
function checkFileLock (line 49) | async function checkFileLock(filePath: string): Promise<SyncLock | null> {
function acquireFileLock (line 80) | async function acquireFileLock(filePath: string): Promise<boolean> {
function releaseFileLock (line 117) | async function releaseFileLock(filePath: string): Promise<void> {
function detectAndHandleConflict (line 138) | async function detectAndHandleConflict(
function analyzeConflictType (line 186) | function analyzeConflictType(localContent: string, remoteContent: string...
function analyzeConflictTypeExported (line 212) | function analyzeConflictTypeExported(localContent: string, remoteContent...
function resolveConflict (line 224) | async function resolveConflict(
function promptUserForResolution (line 244) | async function promptUserForResolution(
function mergeSimpleContent (line 272) | function mergeSimpleContent(localContent: string, remoteContent: string)...
function cleanupExpiredLocks (line 306) | async function cleanupExpiredLocks(): Promise<void> {
function getFileSyncStatus (line 331) | async function getFileSyncStatus(filePath: string): Promise<{
function updateFileSyncTime (line 355) | async function updateFileSyncTime(filePath: string): Promise<void> {
function getFileRestoreTime (line 367) | async function getFileRestoreTime(filePath: string): Promise<number | un...
function updateFileRestoreTime (line 376) | async function updateFileRestoreTime(filePath: string): Promise<void> {
FILE: src/lib/sync/encode-fetch.ts
constant ERROR_REQUEST_CANCELLED (line 4) | const ERROR_REQUEST_CANCELLED = 'Request canceled';
function fetch (line 6) | async function fetch(input: string, init?: RequestInit & ClientOptions) {
FILE: src/lib/sync/filename-utils.ts
function sanitizeFileName (line 6) | function sanitizeFileName(fileName: string): string {
function sanitizeFilePath (line 52) | function sanitizeFilePath(filePath: string): string {
function hasInvalidFileNameChars (line 68) | function hasInvalidFileNameChars(fileName: string): boolean {
function getSafeFileName (line 80) | function getSafeFileName(originalFileName: string): string {
FILE: src/lib/sync/folder-sync-helper.ts
function getFolderSync (line 8) | function getFolderSync(): FolderSync {
function syncFolderByItem (line 15) | async function syncFolderByItem(item: DirTree): Promise<FolderSyncResult> {
function showFolderSyncToast (line 21) | function showFolderSyncToast(result: FolderSyncResult) {
FILE: src/lib/sync/folder-sync.ts
type FolderSyncResult (line 12) | interface FolderSyncResult {
class FolderSync (line 21) | class FolderSync {
method constructor (line 24) | constructor() {
method init (line 31) | private async init() {
method syncFolder (line 36) | async syncFolder(localFolderPath: string): Promise<FolderSyncResult> {
method _getGithubTreeFiles (line 153) | async _getGithubTreeFiles(
method _githubBatchCommit (line 191) | async _githubBatchCommit(
method _getGiteeFiles (line 279) | async _getGiteeFiles(repo: string, path: string = ''): Promise<Record<...
method _getGiteaFiles (line 324) | async _getGiteaFiles(repo: string, path: string = ''): Promise<Record<...
method _giteeBatchCommit (line 386) | async _giteeBatchCommit(
method _gitlabBatchCommit (line 449) | async _gitlabBatchCommit(
method _giteaBatchCommit (line 510) | async _giteaBatchCommit(
method _s3BatchUpload (line 616) | async _s3BatchUpload(
method _webdavBatchUpload (line 647) | async _webdavBatchUpload(
FILE: src/lib/sync/gitea.ts
function getGiteaApiBaseUrl (line 19) | async function getGiteaApiBaseUrl(): Promise<string> {
function getCommonHeaders (line 46) | async function getCommonHeaders(): Promise<any> {
function getProxyConfig (line 63) | async function getProxyConfig(): Promise<Proxy | undefined> {
function uploadFile (line 73) | async function uploadFile({
function updateFileContent (line 232) | async function updateFileContent({
function getFiles (line 272) | async function getFiles({ path, repo, sha }: { path: string; repo: strin...
function deleteFile (line 351) | async function deleteFile({ path, sha, repo }: { path: string; sha?: str...
function getFileCommits (line 417) | async function getFileCommits({ path, repo }: { path: string; repo: stri...
function getFileContentFromCommit (line 464) | async function getFileContentFromCommit({ path, ref, repo }: { path: str...
function getFileContent (line 545) | async function getFileContent({ path, ref, repo }: { path: string; ref: ...
function getUserInfo (line 605) | async function getUserInfo(token?: string): Promise<GiteaUserInfo> {
function checkSyncRepoState (line 657) | async function checkSyncRepoState(name: string): Promise<GiteaRepository...
function createSyncRepo (line 704) | async function createSyncRepo(name: string, isPrivate: boolean = true): ...
FILE: src/lib/sync/gitea.types.ts
type GiteaInstanceType (line 2) | enum GiteaInstanceType {
type GiteaInstanceConfig (line 8) | interface GiteaInstanceConfig {
constant GITEA_INSTANCES (line 16) | const GITEA_INSTANCES: Record<GiteaInstanceType, GiteaInstanceConfig> = {
type GiteaError (line 32) | interface GiteaError {
type GiteaUserInfo (line 38) | interface GiteaUserInfo {
type GiteaRepositoryInfo (line 63) | interface GiteaRepositoryInfo {
type GiteaFileContent (line 141) | interface GiteaFileContent {
type GiteaDirectoryItem (line 161) | interface GiteaDirectoryItem {
type GiteaCommit (line 179) | interface GiteaCommit {
type GiteaResponse (line 238) | type GiteaResponse<T> = {
FILE: src/lib/sync/gitee.ts
type GiteeResponse (line 10) | type GiteeResponse<T> = {
function fileToBase64 (line 17) | async function fileToBase64(file: File) {
type GiteeError (line 31) | interface GiteeError {
type GiteeRepoInfo (line 37) | interface GiteeRepoInfo {
type GiteeFile (line 102) | interface GiteeFile {
type Links (line 115) | interface Links {
function looksLikeFilePath (line 120) | function looksLikeFilePath(path?: string) {
function uploadFile (line 125) | async function uploadFile(
function getFiles (line 231) | async function getFiles({ path, repo, ref }: { path: string, repo: strin...
function deleteFile (line 286) | async function deleteFile({ path, sha, repo }: { path: string, sha: stri...
function getFileCommits (line 340) | async function getFileCommits({ path, repo }: { path: string, repo: stri...
function getUserInfo (line 379) | async function getUserInfo() {
function checkSyncRepoState (line 423) | async function checkSyncRepoState(name: string) {
function createSyncRepo (line 471) | async function createSyncRepo(name: string, isPrivate?: boolean) {
FILE: src/lib/sync/github.ts
function uint8ArrayToBase64 (line 8) | function uint8ArrayToBase64(data: Uint8Array) {
function fileToBase64 (line 13) | async function fileToBase64(file: File) {
type GithubFile (line 26) | interface GithubFile {
type Links (line 40) | interface Links {
function uploadFile (line 46) | async function uploadFile(
function getFiles (line 115) | async function getFiles({ path, repo, ref }: { path: string, repo: strin...
function deleteFile (line 173) | async function deleteFile(
function getFileCommits (line 230) | async function getFileCommits({ path, repo }: { path: string, repo: stri...
function getUserInfo (line 279) | async function getUserInfo(token?: string) {
function checkSyncRepoState (line 320) | async function checkSyncRepoState(name: string) {
function createSyncRepo (line 356) | async function createSyncRepo(name: string, isPrivate?: boolean) {
function getRelease (line 400) | async function getRelease() {
FILE: src/lib/sync/github.types.ts
type RepoNames (line 1) | enum RepoNames {
type GithubError (line 6) | interface GithubError {
type UserInfo (line 12) | interface UserInfo {
type ResCommit (line 49) | interface ResCommit {
type Parent (line 61) | interface Parent {
type Author2 (line 67) | interface Author2 {
type Commit (line 89) | interface Commit {
type Verification (line 99) | interface Verification {
type Tree (line 107) | interface Tree {
type Author (line 112) | interface Author {
type GithubContent (line 118) | interface GithubContent {
type Links (line 131) | interface Links {
type GithubRepoInfo (line 137) | interface GithubRepoInfo {
type Permissions (line 234) | interface Permissions {
type Owner (line 242) | interface Owner {
type SyncStateEnum (line 264) | enum SyncStateEnum {
type OctokitResponse (line 272) | type OctokitResponse<T> = {
FILE: src/lib/sync/gitlab.ts
function getGitlabApiBaseUrl (line 19) | async function getGitlabApiBaseUrl(): Promise<string> {
function getCommonHeaders (line 46) | async function getCommonHeaders(): Promise<any> {
function getProxyConfig (line 63) | async function getProxyConfig(): Promise<Proxy | undefined> {
function uploadFile (line 73) | async function uploadFile({
function getFiles (line 260) | async function getFiles({ path, repo }: { path: string; repo: string }) {
function deleteFile (line 357) | async function deleteFile({ path, repo }: { path: string; sha?: string; ...
function getFileCommits (line 424) | async function getFileCommits({ path, repo }: { path: string; repo: stri...
function getFileContent (line 466) | async function getFileContent({ path, ref, repo }: { path: string; ref: ...
function getUserInfo (line 525) | async function getUserInfo(token?: string): Promise<GitlabUserInfo> {
function checkSyncProjectState (line 577) | async function checkSyncProjectState(name: string): Promise<GitlabProjec...
function createSyncProject (line 630) | async function createSyncProject(name: string, isPrivate: boolean = true...
FILE: src/lib/sync/gitlab.types.ts
type GitlabInstanceType (line 2) | enum GitlabInstanceType {
type GitlabInstanceConfig (line 9) | interface GitlabInstanceConfig {
constant GITLAB_INSTANCES (line 17) | const GITLAB_INSTANCES: Record<GitlabInstanceType, GitlabInstanceConfig>...
type GitlabError (line 39) | interface GitlabError {
type GitlabUserInfo (line 45) | interface GitlabUserInfo {
type GitlabProjectInfo (line 64) | interface GitlabProjectInfo {
type GitlabFile (line 118) | interface GitlabFile {
type GitlabRepositoryFile (line 132) | interface GitlabRepositoryFile {
type GitlabCommit (line 141) | interface GitlabCommit {
type GitlabResponse (line 159) | type GitlabResponse<T> = {
FILE: src/lib/sync/remote-file.ts
function normalizeSegment (line 1) | function normalizeSegment(segment: string) {
function encodePath (line 5) | function encodePath(path: string) {
function buildRepoContentPath (line 13) | function buildRepoContentPath({
function buildRepoContentsEndpoint (line 39) | function buildRepoContentsEndpoint(path?: string) {
type RemoteDirectoryEntry (line 47) | type RemoteDirectoryEntry = {
function pickNestedFileEntry (line 54) | function pickNestedFileEntry(entries: RemoteDirectoryEntry[], requestedP...
function getRemoteFileContent (line 71) | function getRemoteFileContent(file: unknown, path: string) {
function decodeBase64ToString (line 88) | function decodeBase64ToString(content: unknown) {
FILE: src/lib/sync/repo-utils.ts
function getActualRepoName (line 10) | async function getActualRepoName(
function getSyncRepoName (line 52) | async function getSyncRepoName(platform: 'github' | 'gitee' | 'gitlab' |...
function getImageRepoName (line 60) | async function getImageRepoName(): Promise<string> {
FILE: src/lib/sync/s3.ts
function generateSignature (line 11) | async function generateSignature(
function sha256Hex (line 85) | async function sha256Hex(data: string): Promise<string> {
function hmacSha256 (line 93) | async function hmacSha256(key: CryptoKey, data: string): Promise<ArrayBu...
function hmacSha256Hex (line 98) | async function hmacSha256Hex(key: CryptoKey, data: string): Promise<stri...
function getSignatureKey (line 105) | async function getSignatureKey(
function buildS3Url (line 168) | function buildS3Url(config: S3Config, key: string): string {
function buildS3BaseUrl (line 213) | function buildS3BaseUrl(config: S3Config): string {
function testS3Connection (line 241) | async function testS3Connection(config: S3Config, proxy?: Proxy): Promis...
function s3Upload (line 362) | async function s3Upload(
function s3Download (line 417) | async function s3Download(
function s3Delete (line 472) | async function s3Delete(config: S3Config, key: string, proxy?: Proxy): P...
function s3ListObjects (line 511) | async function s3ListObjects(
function parseListObjectsResponse (line 572) | function parseListObjectsResponse(
function s3HeadObject (line 617) | async function s3HeadObject(
FILE: src/lib/sync/sync-manager.ts
function getGitlabBranch (line 22) | async function getGitlabBranch(): Promise<string> {
function getGiteaBranch (line 30) | async function getGiteaBranch(): Promise<string> {
function getS3Config (line 38) | async function getS3Config(): Promise<S3Config | null> {
function getWebDAVConfig (line 50) | async function getWebDAVConfig(): Promise<WebDAVConfig | null> {
type SyncConfig (line 60) | interface SyncConfig {
type SyncState (line 77) | interface SyncState {
type SyncResult (line 86) | interface SyncResult {
type SyncLog (line 94) | interface SyncLog {
class SyncManager (line 103) | class SyncManager {
method constructor (line 115) | constructor() {
method loadConfig (line 122) | async loadConfig(): Promise<void> {
method saveConfig (line 151) | async saveConfig(): Promise<void> {
method updateConfig (line 164) | async updateConfig(config: Partial<SyncConfig>): Promise<void> {
method getConfig (line 172) | getConfig(): SyncConfig {
method getState (line 179) | getState(): SyncState {
method getCurrentPlatform (line 186) | async getCurrentPlatform(): Promise<string> {
method calculateSha (line 194) | async calculateSha(content: string): Promise<string> {
method getLocalSha (line 201) | async getLocalSha(path: string): Promise<string | null> {
method getRemoteSha (line 209) | async getRemoteSha(path: string): Promise<string | null> {
method pushFile (line 217) | async pushFile(path: string, content: string): Promise<SyncResult> {
method pullFile (line 306) | async pullFile(path: string): Promise<SyncResult> {
method deleteRemoteFile (line 396) | async deleteRemoteFile(path: string): Promise<SyncResult> {
method resolveConflict (line 466) | async resolveConflict(path: string, strategy: 'ask' | 'local' | 'remot...
method syncFile (line 515) | async syncFile(path: string, options: {
method onSave (line 592) | async onSave(path: string): Promise<void> {
method onOpen (line 625) | async onOpen(path: string): Promise<{ updated: boolean; content?: stri...
method processSyncQueue (line 674) | private async processSyncQueue(): Promise<void> {
method syncAll (line 706) | async syncAll(paths: string[]): Promise<SyncResult[]> {
method logSync (line 720) | private async logSync(filePath: string, action: 'push' | 'pull' | 'del...
method getLogs (line 747) | async getLogs(limit?: number): Promise<SyncLog[]> {
method clearLogs (line 760) | async clearLogs(): Promise<void> {
method getFileSyncStatus (line 772) | async getFileSyncStatus(path: string): Promise<SyncState['syncStatus']> {
function getSyncManager (line 799) | function getSyncManager(): SyncManager {
function syncOnSave (line 807) | async function syncOnSave(path: string): Promise<void> {
function syncOnOpen (line 812) | async function syncOnOpen(path: string): Promise<{ updated: boolean; con...
function syncSingleFile (line 817) | async function syncSingleFile(path: string, onConflict?: (local: string,...
function isSyncConfigured (line 826) | async function isSyncConfigured(): Promise<boolean> {
FILE: src/lib/sync/sync-push-queue.ts
function getS3Config (line 17) | async function getS3Config(): Promise<S3Config | null> {
function getWebDAVConfig (line 29) | async function getWebDAVConfig(): Promise<WebDAVConfig | null> {
function getProxyConfig (line 41) | async function getProxyConfig(): Promise<{ all: string } | undefined> {
type PushTask (line 47) | interface PushTask {
class SyncPushQueue (line 63) | class SyncPushQueue {
method IDLE_THRESHOLD (line 69) | private get IDLE_THRESHOLD(): number {
method init (line 87) | init() {
method initListeners (line 93) | private initListeners() {
method removeListeners (line 122) | private removeListeners() {
method addTask (line 145) | addTask(path: string) {
method scheduleFlush (line 173) | private scheduleFlush() {
method flush (line 203) | private async flush() {
method pushToRemote (line 249) | private async pushToRemote(path: string): Promise<{ success: boolean; ...
method getRemoteSha (line 524) | private async getRemoteSha(path: string): Promise<string | undefined> {
method forcePush (line 537) | async forcePush(path: string): Promise<{ success: boolean; sha?: strin...
method generateCommitMessage (line 688) | private async generateCommitMessage(path: string, content: string): Pr...
method clear (line 706) | clear() {
function getSyncPushQueue (line 718) | function getSyncPushQueue(): SyncPushQueue {
FILE: src/lib/sync/webdav.ts
function buildAuthHeader (line 12) | function buildAuthHeader(username: string, password: string): string {
function buildWebDAVUrl (line 19) | function buildWebDAVUrl(config: WebDAVConfig, key: string): string {
function testWebDAVConnection (line 29) | async function testWebDAVConnection(config: WebDAVConfig, proxy?: Proxy)...
function ensureParentDirsExist (line 51) | async function ensureParentDirsExist(
function webdavUpload (line 84) | async function webdavUpload(
function webdavDownload (line 125) | async function webdavDownload(
function webdavDelete (line 163) | async function webdavDelete(config: WebDAVConfig, key: string, proxy?: P...
function webdavHeadObject (line 185) | async function webdavHeadObject(
function webdavListObjects (line 223) | async function webdavListObjects(
function parsePropfindResponse (line 263) | function parsePropfindResponse(
function webdavMkcol (line 336) | async function webdavMkcol(
FILE: src/lib/template-range-utils.ts
function getTemplateRangeLabel (line 9) | function getTemplateRangeLabel(range: GenTemplateRange, t: (key: string)...
function getTemplateRangeOptions (line 30) | function getTemplateRangeOptions(t: (key: string) => string) {
FILE: src/lib/theme-utils.ts
function hslToCssValue (line 6) | function hslToCssValue(hsl: HSLValue): string {
function applyThemeColors (line 16) | function applyThemeColors(colors: CustomThemeColors): void {
function removeThemeColors (line 59) | function removeThemeColors(): void {
function hexToHsl (line 86) | function hexToHsl(hex: string): HSLValue | null {
function hslToHex (line 137) | function hslToHex(hsl: HSLValue): string {
FILE: src/lib/toolbar-shortcuts.ts
type Platform (line 1) | type Platform = 'macos' | 'windows' | 'linux' | 'unknown'
type ToolbarShortcutEventLike (line 3) | interface ToolbarShortcutEventLike {
function resolveToolbarShortcutIndex (line 12) | function resolveToolbarShortcutIndex(
FILE: src/lib/utils.ts
function cn (line 7) | function cn(...inputs: ClassValue[]) {
function convertImage (line 11) | async function convertImage(path: string) {
function convertImageByWorkspace (line 17) | async function convertImageByWorkspace(path: string) {
function convertBytesToSize (line 28) | function convertBytesToSize(bytes: number) {
function arrayBuffer2String (line 37) | function arrayBuffer2String(buffer: ArrayBuffer) {
function scrollToBottom (line 42) | function scrollToBottom() {
FILE: src/lib/vector-document-key.js
function getVectorDocumentKey (line 1) | function getVectorDocumentKey(filePath) {
function buildVectorIndexedMap (line 5) | function buildVectorIndexedMap(vectorDocuments) {
FILE: src/lib/workspace.ts
function getWorkspacePath (line 10) | async function getWorkspacePath(): Promise<{ path: string, isCustom: boo...
function getFilePathOptions (line 35) | async function getFilePathOptions(relativePath: string): Promise<{ path:...
function getDefaultArticleAbsolutePath (line 56) | async function getDefaultArticleAbsolutePath(relativePath: string): Prom...
function getGenericPathOptions (line 74) | async function getGenericPathOptions(path: string, prefix?: string): Pro...
function toWorkspaceRelativePath (line 111) | async function toWorkspaceRelativePath(path: string): Promise<string> {
function normalizeWorkspaceRelativePath (line 137) | async function normalizeWorkspaceRelativePath(relativePath: string): Pro...
FILE: src/stores/article.ts
function getStore (line 29) | async function getStore(): Promise<Store> {
type SortType (line 36) | type SortType = 'name' | 'created' | 'modified' | 'none'
type SortDirection (line 37) | type SortDirection = 'asc' | 'desc'
type DirTree (line 39) | interface DirTree extends DirEntry {
type Article (line 52) | interface Article {
function isLikelyFilePath (line 72) | function isLikelyFilePath(path: string): boolean {
function getFolderPathsToExpand (line 77) | function getFolderPathsToExpand(path: string): string[] {
function createLocalTreeNode (line 84) | function createLocalTreeNode(name: string, isDirectory: boolean, parent?...
function insertNodeIntoTree (line 100) | function insertNodeIntoTree(tree: DirTree[], relativePath: string, isDir...
function removeNodeFromTree (line 129) | function removeNodeFromTree(tree: DirTree[], relativePath: string): DirT...
function attachNodeToTree (line 154) | function attachNodeToTree(tree: DirTree[], relativePath: string, node: D...
type NoteState (line 183) | interface NoteState {
function loadFolderChildren (line 803) | async function loadFolderChildren(workspace: any, folder: DirTree, paren...
FILE: src/stores/chat.ts
type PendingQuote (line 18) | interface PendingQuote {
type McpToolCall (line 30) | interface McpToolCall {
type ChatState (line 42) | interface ChatState {
FILE: src/stores/clipboard.ts
type ClipboardItem (line 3) | interface ClipboardItem {
type ClipboardOperation (line 11) | type ClipboardOperation = 'copy' | 'cut' | 'none'
type ClipboardState (line 13) | interface ClipboardState {
FILE: src/stores/imageHosting.ts
type S3Config (line 7) | interface S3Config {
type MarkState (line 17) | interface MarkState {
method getImages (line 75) | async getImages() {
FILE: src/stores/mark.ts
type MarkQueue (line 17) | interface MarkQueue {
type RecordTimePreset (line 25) | type RecordTimePreset = 'all' | 'today' | 'last7Days' | 'last30Days'
type RecordViewMode (line 26) | type RecordViewMode = 'list' | 'compact' | 'cards'
type RecordFilters (line 28) | interface RecordFilters {
constant DEFAULT_RECORD_FILTERS (line 35) | const DEFAULT_RECORD_FILTERS: RecordFilters = {
function persistRecordFilters (line 42) | async function persistRecordFilters(recordFilters: RecordFilters) {
function persistRecordViewMode (line 47) | async function persistRecordViewMode(recordViewMode: RecordViewMode) {
type MarkState (line 52) | interface MarkState {
FILE: src/stores/mcp.ts
type MCPState (line 5) | interface MCPState {
FILE: src/stores/memories.ts
type MemoriesState (line 5) | interface MemoriesState {
FILE: src/stores/prompt.ts
type Prompt (line 4) | interface Prompt {
type PromptState (line 11) | interface PromptState {
FILE: src/stores/ragSettings.ts
type RagSettings (line 6) | interface RagSettings {
constant DEFAULT_RAG_SETTINGS (line 18) | const DEFAULT_RAG_SETTINGS: RagSettings = {
type RagSettingsState (line 26) | interface RagSettingsState extends RagSettings {
FILE: src/stores/recording.ts
type RecordingState (line 3) | interface RecordingState {
FILE: src/stores/setting.ts
type GenTemplateRange (line 14) | enum GenTemplateRange {
type GenTemplate (line 23) | interface GenTemplate {
type SettingState (line 31) | interface SettingState {
type ChatToolbarItem (line 260) | interface ChatToolbarItem {
type RecordToolbarItem (line 266) | interface RecordToolbarItem {
FILE: src/stores/settingsSync.ts
type SettingsSyncState (line 11) | interface SettingsSyncState {
FILE: src/stores/shortcut.ts
type Shortcut (line 6) | interface Shortcut {
type SettingState (line 11) | interface SettingState {
function bindShortcut (line 29) | async function bindShortcut(shortcut: Shortcut) {
FILE: src/stores/sidebar.ts
type SidebarState (line 5) | interface SidebarState {
FILE: src/stores/skills.ts
type SkillsState (line 6) | interface SkillsState {
FILE: src/stores/speech-recognition.ts
type SpeechRecognitionEvent (line 4) | interface SpeechRecognitionEvent extends Event {
type SpeechRecognitionResultList (line 9) | interface SpeechRecognitionResultList {
type SpeechRecognitionResult (line 15) | interface SpeechRecognitionResult {
type SpeechRecognitionAlternative (line 22) | interface SpeechRecognitionAlternative {
type SpeechRecognition (line 27) | interface SpeechRecognition extends EventTarget {
type Window (line 42) | interface Window {
type SpeechRecognitionState (line 48) | interface SpeechRecognitionState {
FILE: src/stores/sync-confirm.ts
type SyncConfirmState (line 3) | interface SyncConfirmState {
FILE: src/stores/sync.ts
type SyncState (line 7) | interface SyncState {
FILE: src/stores/tag.ts
type TagState (line 14) | interface TagState {
FILE: src/stores/update.ts
type UpdateState (line 5) | interface UpdateState {
FILE: src/stores/vector.ts
type VectorState (line 7) | interface VectorState {
FILE: src/types/sync.ts
type SyncPlatform (line 1) | type SyncPlatform = 'github' | 'gitee' | 'gitlab' | 'gitea' | 's3' | 'we...
type SyncPlatformType (line 3) | type SyncPlatformType = {
constant SYNC_PLATFORMS (line 9) | const SYNC_PLATFORMS: SyncPlatform[] = ['github', 'gitee', 'gitlab', 'gi...
constant SYNC_PLATFORM_INFO (line 11) | const SYNC_PLATFORM_INFO: Record<SyncPlatform, SyncPlatformType> = {
type S3Config (line 20) | interface S3Config {
type WebDAVConfig (line 30) | interface WebDAVConfig {
FILE: src/types/theme.ts
type CustomThemeColors (line 6) | interface CustomThemeColors {
type HSLValue (line 50) | type HSLValue = [number, number, number]
constant THEME_VARIABLE_MAP (line 55) | const THEME_VARIABLE_MAP = {
Condensed preview — 605 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (3,859K chars).
[
{
"path": ".eslintrc.json",
"chars": 226,
"preview": "{\n \"root\": true,\n \"extends\": [\"next/core-web-vitals\", \"next/typescript\"],\n \"rules\": {\n \"react-hooks/exhaustive-dep"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report.yml",
"chars": 1110,
"preview": "name: 🐞 提交 Bug\ntitle: '[bug] '\ndescription: 详细的描述一个 Bug\nlabels: ['type: bug']\n\nbody:\n - type: markdown\n attributes:\n"
},
{
"path": ".github/ISSUE_TEMPLATE/config.yml",
"chars": 124,
"preview": "contact_links:\n - name: 💬 讨论问题\n url: https://github.com/codexu/note-gen/discussions\n about: 提出问题并与其他 NoteGen 用户或维"
},
{
"path": ".github/ISSUE_TEMPLATE/feature_request.yml",
"chars": 228,
"preview": "name: 💡 改进建议\ntitle: '[feat] '\ndescription: 你有什么好的灵感?\nlabels: ['type: feat']\n\nbody:\n - type: textarea\n id: problem\n "
},
{
"path": ".github/workflows/release.yml",
"chars": 13197,
"preview": "name: 'publish'\n\non:\n push:\n branches:\n - release\n\njobs:\n build-android:\n outputs:\n appVersion: ${{ st"
},
{
"path": ".gitignore",
"chars": 892,
"preview": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\nnode_modules\n\n./di"
},
{
"path": ".vscode/settings.json",
"chars": 185,
"preview": "{\n \"marscode.codeCompletionPro\": {\n \"enableCodeCompletionPro\": false\n },\n \"marscode.enableInlineCommand\": false,\n "
},
{
"path": "LICENSE",
"chars": 35129,
"preview": " GNU GENERAL PUBLIC LICENSE\n Version 3, 29 June 2007\n\n Copyright (C) 2025 codex"
},
{
"path": "README.md",
"chars": 6831,
"preview": "# NoteGen\n\n.Config} */\nconst config = {\n plugins: {\n \"@tailwindcss/postcss\": {},\n },\n}"
},
{
"path": "public/markdown/github-markdown-dark.css",
"chars": 21223,
"preview": "/* dark */\n.markdown-body {\n color-scheme: dark;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n marg"
},
{
"path": "public/markdown/github-markdown-light.css",
"chars": 21223,
"preview": "/* light */\n.markdown-body {\n color-scheme: light;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n ma"
},
{
"path": "scripts/sync-version.sh",
"chars": 620,
"preview": "#!/bin/bash\n\n# 同步版本号脚本\n# 从 tauri.conf.json 读取版本号并更新 iOS Info.plist\n\n# 获取当前版本号\nVERSION=$(node -p \"require('./src-tauri/ta"
},
{
"path": "src/app/core/index.d.ts",
"chars": 233,
"preview": "declare module \"note-gen/screenshot\" {\n export interface ScreenshotImage {\n name: string;\n path: string"
},
{
"path": "src/app/core/layout.tsx",
"chars": 5527,
"preview": "'use client'\n\nimport { ThemeProvider } from \"@/components/theme-provider\"\nimport useSettingStore from \"@/stores/setting\""
},
{
"path": "src/app/core/main/chat/agent-execution-status.tsx",
"chars": 2987,
"preview": "import * as React from \"react\"\nimport useChatStore from \"@/stores/chat\"\nimport { AgentPanelWithRag } from \"./agent-panel"
},
{
"path": "src/app/core/main/chat/agent-history.tsx",
"chars": 459,
"preview": "import * as React from \"react\"\nimport { AgentPlan } from \"@/components/ui/agent-plan\"\n\ninterface AgentHistoryProps {\n h"
},
{
"path": "src/app/core/main/chat/agent-panel-with-rag.tsx",
"chars": 8693,
"preview": "\"use client\"\nimport * as React from \"react\"\nimport { AgentPlan } from \"@/components/ui/agent-plan\"\nimport { FileText, Ch"
},
{
"path": "src/app/core/main/chat/chat-clipboard.tsx",
"chars": 6680,
"preview": "'use client'\nimport { useState, useEffect } from 'react';\nimport { BaseDirectory, copyFile, exists, mkdir, readFile } fr"
},
{
"path": "src/app/core/main/chat/chat-content.tsx",
"chars": 16717,
"preview": "import React from 'react'\nimport useChatStore from '@/stores/chat'\nimport useTagStore from '@/stores/tag'\nimport { Arrow"
},
{
"path": "src/app/core/main/chat/chat-empty.tsx",
"chars": 7618,
"preview": "'use client'\n\nimport { useTranslations } from 'next-intl'\nimport useChatStore from '@/stores/chat'\nimport { useMemo, use"
},
{
"path": "src/app/core/main/chat/chat-footer.tsx",
"chars": 2710,
"preview": "\"use client\"\n\nimport { BotMessageSquare, BotOff, Drama } from \"lucide-react\"\nimport usePromptStore from \"@/stores/prompt"
},
{
"path": "src/app/core/main/chat/chat-header.tsx",
"chars": 6209,
"preview": "\"use client\"\n\nimport { useState, useMemo } from 'react'\nimport { MessageSquarePlus, ChevronDown, Search, Trash2 } from \""
},
{
"path": "src/app/core/main/chat/chat-images.tsx",
"chars": 1606,
"preview": "\"use client\"\nimport Image from \"next/image\"\nimport { useState } from \"react\"\nimport { Dialog, DialogContent } from \"@/co"
},
{
"path": "src/app/core/main/chat/chat-input.tsx",
"chars": 24948,
"preview": "\"use client\"\nimport * as React from \"react\"\nimport { useEffect, useMemo, useRef, useState, useCallback } from \"react\"\nim"
},
{
"path": "src/app/core/main/chat/chat-preview.tsx",
"chars": 9694,
"preview": "'use client'\nimport useSettingStore from \"@/stores/setting\";\nimport React, { useEffect, useRef, useState, useCallback } "
},
{
"path": "src/app/core/main/chat/chat-send.tsx",
"chars": 20466,
"preview": "\"use client\"\nimport { Send, Square } from \"lucide-react\"\nimport useSettingStore from \"@/stores/setting\"\nimport useChatSt"
},
{
"path": "src/app/core/main/chat/chat-thinking.tsx",
"chars": 2438,
"preview": "import { Chat } from \"@/db/chats\";\nimport { useState, useEffect, useRef } from \"react\";\nimport { Brain, ChevronRight, Lo"
},
{
"path": "src/app/core/main/chat/chat.css",
"chars": 4851,
"preview": "@keyframes gradient {\n 0% {\n background-position: 0% 50%;\n }\n 50% {\n background-position: 100% 50%;\n }\n 100% "
},
{
"path": "src/app/core/main/chat/clear-chat.tsx",
"chars": 634,
"preview": "\"use client\"\nimport * as React from \"react\"\nimport { Eraser } from \"lucide-react\"\nimport { TooltipButton } from \"@/compo"
},
{
"path": "src/app/core/main/chat/clear-context.tsx",
"chars": 985,
"preview": "\"use client\"\n\nimport React from \"react\"\nimport { AlignVerticalJustifyCenter } from \"lucide-react\"\nimport { TooltipButton"
},
{
"path": "src/app/core/main/chat/clipboard-listener.tsx",
"chars": 2398,
"preview": "'use client'\nimport { clear, hasImage, hasText, readImageBase64, readText } from \"tauri-plugin-clipboard-api\";\nimport { "
},
{
"path": "src/app/core/main/chat/clipboard-monitor.tsx",
"chars": 1555,
"preview": "\"use client\"\nimport { useTranslations } from 'next-intl'\nimport { Clipboard, ClipboardX } from 'lucide-react'\nimport { T"
},
{
"path": "src/app/core/main/chat/file-link.tsx",
"chars": 1901,
"preview": "\"use client\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { AtSign, X, FolderOpen } from \"lucide-react\"\nimpor"
},
{
"path": "src/app/core/main/chat/file-selector.tsx",
"chars": 5131,
"preview": "\"use client\"\n\nimport { useState, useEffect, useRef } from \"react\"\nimport { Input } from \"@/components/ui/input\"\nimport {"
},
{
"path": "src/app/core/main/chat/history-dropdown.tsx",
"chars": 4798,
"preview": "'use client'\n\nimport { useState, useMemo } from 'react'\nimport { ChevronDown, Search, Trash2 } from 'lucide-react'\nimpor"
},
{
"path": "src/app/core/main/chat/image-attachments.tsx",
"chars": 1581,
"preview": "\"use client\"\nimport { X } from \"lucide-react\"\nimport { Button } from \"@/components/ui/button\"\nimport Image from \"next/im"
},
{
"path": "src/app/core/main/chat/index.tsx",
"chars": 516,
"preview": "'use client'\nimport { ChatHeader } from './chat-header'\nimport { ChatFooter } from './chat-footer'\nimport { ChatInput } "
},
{
"path": "src/app/core/main/chat/mcp-button.tsx",
"chars": 4655,
"preview": "'use client'\n\nimport * as React from 'react'\nimport { useState } from 'react'\nimport { ServerCrash, Server, Plug, PlugZa"
},
{
"path": "src/app/core/main/chat/mcp-tool-call.tsx",
"chars": 3152,
"preview": "'use client'\n\nimport { McpToolCall } from '@/stores/chat'\nimport { Card } from '@/components/ui/card'\nimport { Badge } f"
},
{
"path": "src/app/core/main/chat/message-control/condensed-indicator.tsx",
"chars": 960,
"preview": "import { Chat } from \"@/db/chats\"\nimport { FileText } from \"lucide-react\"\nimport {\n Popover,\n PopoverContent,\n Popove"
},
{
"path": "src/app/core/main/chat/message-control/copy-control.tsx",
"chars": 1591,
"preview": "import { TooltipButton } from \"@/components/tooltip-button\"\nimport { Chat } from \"@/db/chats\"\nimport { Copy, Check } fro"
},
{
"path": "src/app/core/main/chat/message-control/index.tsx",
"chars": 2228,
"preview": "import { Chat } from \"@/db/chats\"\nimport useChatStore from \"@/stores/chat\"\nimport { XIcon } from \"lucide-react\"\nimport {"
},
{
"path": "src/app/core/main/chat/message-control/mark-text.tsx",
"chars": 1986,
"preview": "import { TooltipButton } from \"@/components/tooltip-button\"\nimport { Chat } from \"@/db/chats\"\nimport { insertMark } from"
},
{
"path": "src/app/core/main/chat/message-control/message-info.tsx",
"chars": 584,
"preview": "import { Button } from \"@/components/ui/button\"\nimport { Chat } from \"@/db/chats\"\nimport dayjs from \"dayjs\"\nimport { Clo"
},
{
"path": "src/app/core/main/chat/message-control/note-output.tsx",
"chars": 5371,
"preview": "'use client'\nimport { Button } from \"@/components/ui/button\"\nimport { Checkbox } from \"@/components/ui/checkbox\"\nimport "
},
{
"path": "src/app/core/main/chat/message-control/read-aloud-control.tsx",
"chars": 2494,
"preview": "import { TooltipButton } from \"@/components/tooltip-button\"\nimport { Chat } from \"@/db/chats\"\nimport { Volume2, VolumeX,"
},
{
"path": "src/app/core/main/chat/message-control/translate-control.tsx",
"chars": 2609,
"preview": "import { Chat } from \"@/db/chats\"\nimport { GlobeIcon, Loader2 } from \"lucide-react\"\nimport { useTranslations } from \"nex"
},
{
"path": "src/app/core/main/chat/model-select.tsx",
"chars": 4605,
"preview": "import * as React from \"react\"\nimport { useEffect, useState } from \"react\"\nimport { ModelConfig } from \"../../setting/co"
},
{
"path": "src/app/core/main/chat/new-chat.tsx",
"chars": 676,
"preview": "\"use client\"\nimport * as React from \"react\"\nimport { MessageSquarePlus } from \"lucide-react\"\nimport { TooltipButton } fr"
},
{
"path": "src/app/core/main/chat/onboarding-typing.ts",
"chars": 282,
"preview": "export function buildTypingFrames(text: string, chunkSize: number) {\n const size = Math.max(1, chunkSize)\n const frame"
},
{
"path": "src/app/core/main/chat/prompt-select.tsx",
"chars": 2256,
"preview": "import * as React from \"react\"\nimport { useEffect } from \"react\"\nimport { useTranslations } from \"next-intl\"\nimport { Dr"
},
{
"path": "src/app/core/main/chat/quote-display.tsx",
"chars": 2152,
"preview": "import { X } from \"lucide-react\"\nimport { Button } from \"@/components/ui/button\"\nimport { useTranslations } from \"next-i"
},
{
"path": "src/app/core/main/chat/quote-preview.ts",
"chars": 176,
"preview": "export function getQuotePreview(content: string, limit = 160) {\n if (!content || content.length <= limit) {\n return "
},
{
"path": "src/app/core/main/chat/rag-switch.tsx",
"chars": 1340,
"preview": "\"use client\"\n\nimport { useState } from 'react'\nimport { Database, DatabaseZap } from 'lucide-react'\nimport { useTranslat"
},
{
"path": "src/app/core/main/chat/streaming-smoother.ts",
"chars": 1473,
"preview": "export type SmootherState = {\n carryChars: number;\n displayedLength: number;\n};\n\nexport type SmootherStepResult = Smoo"
},
{
"path": "src/app/core/main/editor/editor-layout.tsx",
"chars": 22763,
"preview": "'use client'\n\nimport { useEffect, useState, useCallback, useRef } from 'react'\nimport useArticleStore, { findFolderInTre"
},
{
"path": "src/app/core/main/editor/empty-state-actions.ts",
"chars": 4032,
"preview": "export async function createNewNoteFromEmptyState({\n setLeftSidebarTab,\n newFile,\n}: {\n setLeftSidebarTab: (tab: 'fil"
},
{
"path": "src/app/core/main/editor/empty-state.tsx",
"chars": 12088,
"preview": "'use client'\n\nimport { FileText, MessageSquareText, Search, FolderOpen } from 'lucide-react'\nimport useArticleStore from"
},
{
"path": "src/app/core/main/editor/folder/folder-stats.tsx",
"chars": 7611,
"preview": "'use client'\n\nimport { useState, useEffect, useCallback } from 'react'\nimport { Folder, Database, Clock, RefreshCw, Load"
},
{
"path": "src/app/core/main/editor/folder/index.tsx",
"chars": 5131,
"preview": "'use client'\n\nimport { useEffect, useMemo } from 'react'\nimport { Loader2, Sparkles } from 'lucide-react'\nimport { useTr"
},
{
"path": "src/app/core/main/editor/folder/skill-detail.tsx",
"chars": 3219,
"preview": "'use client'\n\nimport { Sparkles } from 'lucide-react'\nimport { useTranslations } from 'next-intl'\nimport { SkillContent "
},
{
"path": "src/app/core/main/editor/folder/skills-list.tsx",
"chars": 4026,
"preview": "'use client'\n\nimport { useState } from 'react'\nimport { Sparkles } from 'lucide-react'\nimport { useTranslations } from '"
},
{
"path": "src/app/core/main/editor/image/image-editor.css",
"chars": 381,
"preview": ".image-editor {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n background: var(--background"
},
{
"path": "src/app/core/main/editor/image/image-editor.tsx",
"chars": 10653,
"preview": "'use client'\n\nimport { useEffect, useState, useRef } from 'react'\nimport { Cropper, CropperRef } from 'react-advanced-cr"
},
{
"path": "src/app/core/main/editor/image/image-footer.tsx",
"chars": 2091,
"preview": "'use client'\n\nimport { useEffect, useState } from 'react'\nimport { getWorkspacePath, getFilePathOptions } from '@/lib/wo"
},
{
"path": "src/app/core/main/editor/markdown/ai-completion.tsx",
"chars": 6468,
"preview": "'use client'\n\nimport { Editor } from '@tiptap/core'\nimport { ReactRenderer } from '@tiptap/react'\nimport tippy from 'tip"
},
{
"path": "src/app/core/main/editor/markdown/ai-suggestion-floating.tsx",
"chars": 8494,
"preview": "'use client'\n\nimport { Editor } from '@tiptap/react'\nimport { Check, X, Sparkles, Loader2, CircleX } from 'lucide-react'"
},
{
"path": "src/app/core/main/editor/markdown/ai-suggestion.ts",
"chars": 1975,
"preview": "import { Mark, mergeAttributes } from '@tiptap/core'\n\nexport interface AISuggestionOptions {\n HTMLAttributes: Record<st"
},
{
"path": "src/app/core/main/editor/markdown/bubble-menu.tsx",
"chars": 18876,
"preview": "'use client'\n\nimport { Editor } from '@tiptap/react'\nimport {\n Bold,\n Italic,\n Strikethrough,\n Underline,\n Code,\n "
},
{
"path": "src/app/core/main/editor/markdown/export-menu.tsx",
"chars": 8515,
"preview": "'use client'\n\nimport { Editor } from '@tiptap/react'\nimport {\n FileText,\n FileCode,\n FileJson,\n Download,\n FileType"
},
{
"path": "src/app/core/main/editor/markdown/floating-table-menu.tsx",
"chars": 8474,
"preview": "'use client'\n\nimport { Editor } from '@tiptap/react'\nimport {\n TableIcon,\n Columns,\n Rows,\n Trash2,\n AlignLeft,\n A"
},
{
"path": "src/app/core/main/editor/markdown/footer-bar/copy-button.tsx",
"chars": 2822,
"preview": "'use client'\n\nimport { Editor } from '@tiptap/react'\nimport { Copy, FileCode, FileJson, FileText } from 'lucide-react'\ni"
},
{
"path": "src/app/core/main/editor/markdown/footer-bar/export-button.tsx",
"chars": 5220,
"preview": "'use client'\n\nimport { Editor } from '@tiptap/react'\nimport { Download, FileCode, FileJson, FileText } from 'lucide-reac"
},
{
"path": "src/app/core/main/editor/markdown/footer-bar/index.tsx",
"chars": 1114,
"preview": "'use client'\n\nimport { Editor } from '@tiptap/react'\nimport { WordCount } from './word-count'\nimport { CopyButton } from"
},
{
"path": "src/app/core/main/editor/markdown/footer-bar/outline-toggle.tsx",
"chars": 857,
"preview": "'use client'\n\nimport { Editor } from '@tiptap/react'\nimport { List, ListCollapse } from 'lucide-react'\nimport { useTrans"
},
{
"path": "src/app/core/main/editor/markdown/footer-bar/vector-calc.tsx",
"chars": 2901,
"preview": "'use client'\n\nimport { Database, Sparkles } from 'lucide-react'\nimport { useCallback, useState } from 'react'\nimport { c"
},
{
"path": "src/app/core/main/editor/markdown/footer-bar/word-count.tsx",
"chars": 457,
"preview": "'use client'\n\nimport { Editor } from '@tiptap/react'\nimport { useMemo } from 'react'\n\ninterface WordCountProps {\n edito"
},
{
"path": "src/app/core/main/editor/markdown/image-bubble-menu.tsx",
"chars": 8982,
"preview": "'use client'\n\nimport { Editor } from '@tiptap/react'\nimport { Trash2, Link, Type } from 'lucide-react'\nimport { useState"
},
{
"path": "src/app/core/main/editor/markdown/markdown-input-rules.ts",
"chars": 5313,
"preview": "'use client'\n\nimport { Extension } from '@tiptap/core'\n\n/**\n * Markdown input rules for Tiptap\n * Supports: headings, bl"
},
{
"path": "src/app/core/main/editor/markdown/markdown-paragraph.ts",
"chars": 1716,
"preview": "import { mergeAttributes, Node } from '@tiptap/core'\n\nexport interface MarkdownParagraphOptions {\n HTMLAttributes: Reco"
},
{
"path": "src/app/core/main/editor/markdown/math-editor-dialog.tsx",
"chars": 3724,
"preview": "'use client'\n\nimport { useState, useEffect, useMemo } from 'react'\nimport katex from 'katex'\nimport { Sigma } from 'luci"
},
{
"path": "src/app/core/main/editor/markdown/math-extension.tsx",
"chars": 8157,
"preview": "'use client'\n\nimport { Node, mergeAttributes } from '@tiptap/core'\nimport { ReactNodeViewRenderer, NodeViewWrapper, Reac"
},
{
"path": "src/app/core/main/editor/markdown/md-editor-wrapper.tsx",
"chars": 16315,
"preview": "'use client'\n\nimport useArticleStore from '@/stores/article'\nimport { useEffect, useState, useCallback, useRef, RefObjec"
},
{
"path": "src/app/core/main/editor/markdown/mermaid-extension.tsx",
"chars": 8346,
"preview": "'use client'\n\nimport { Node, mergeAttributes } from '@tiptap/core'\nimport { ReactNodeViewRenderer, NodeViewWrapper, Reac"
},
{
"path": "src/app/core/main/editor/markdown/mobile-editor-context-bar-view-model.ts",
"chars": 1627,
"preview": "import {\n Sparkles,\n Quote,\n Bold,\n Highlighter,\n MoreHorizontal,\n Link2,\n Type,\n Trash2,\n Rows3,\n Columns3,\n "
},
{
"path": "src/app/core/main/editor/markdown/mobile-editor-context-bar.tsx",
"chars": 1988,
"preview": "'use client'\n\nimport { cn } from '@/lib/utils'\nimport { Button } from '@/components/ui/button'\nimport { buildMobileEdito"
},
{
"path": "src/app/core/main/editor/markdown/mobile-editor-more-sheet.tsx",
"chars": 3790,
"preview": "'use client'\n\nimport { Drawer, DrawerContent, DrawerHeader, DrawerTitle } from '@/components/ui/drawer'\nimport { Input }"
},
{
"path": "src/app/core/main/editor/markdown/mobile-selection-context.ts",
"chars": 2469,
"preview": "const PRIMARY_ACTIONS = {\n text: ['quote', 'ai', 'bold', 'highlight', 'italic', 'underline', 'strike', 'code', 'blockqu"
},
{
"path": "src/app/core/main/editor/markdown/outline.tsx",
"chars": 9527,
"preview": "'use client'\n\nimport { Editor } from '@tiptap/react'\nimport { Heading1, Heading2, Heading3 } from 'lucide-react'\nimport "
},
{
"path": "src/app/core/main/editor/markdown/quote-mark.ts",
"chars": 1225,
"preview": "import { Mark, mergeAttributes } from '@tiptap/core'\n\nexport interface QuoteOptions {\n HTMLAttributes: Record<string, s"
},
{
"path": "src/app/core/main/editor/markdown/quote-session.ts",
"chars": 533,
"preview": "import type { PendingQuote } from '@/stores/chat'\n\nexport function shouldRestorePendingQuote(\n pendingQuote: PendingQuo"
},
{
"path": "src/app/core/main/editor/markdown/search-navigation.ts",
"chars": 318,
"preview": "export function getResultIndexToFocus(\n results: Array<{ from: number; to: number }>,\n requestedIndex = 0\n): number {\n"
},
{
"path": "src/app/core/main/editor/markdown/search-replace-panel.tsx",
"chars": 11533,
"preview": "'use client'\n\nimport { Editor } from '@tiptap/react'\nimport { TextSelection } from '@tiptap/pm/state'\nimport { useState,"
},
{
"path": "src/app/core/main/editor/markdown/slash-command/index.ts",
"chars": 1366,
"preview": "import { Extension, type Editor, type RawCommands } from '@tiptap/core'\nimport { Suggestion, SuggestionPluginKey } from "
},
{
"path": "src/app/core/main/editor/markdown/slash-command/slash-command-portal.tsx",
"chars": 4082,
"preview": "'use client'\n\nimport { useEffect, useState, useCallback, useRef } from 'react'\nimport { Editor } from '@tiptap/react'\nim"
},
{
"path": "src/app/core/main/editor/markdown/slash-command/slash-menu.tsx",
"chars": 8107,
"preview": "'use client'\n\nimport { useCallback, useEffect, useMemo, useState, forwardRef, useImperativeHandle, useRef } from 'react'"
},
{
"path": "src/app/core/main/editor/markdown/slash-command/suggestion.tsx",
"chars": 17488,
"preview": "import {\n Heading1,\n Heading2,\n Heading3,\n List,\n ListOrdered,\n CheckSquare,\n Quote,\n Code,\n Table,\n Minus,\n "
},
{
"path": "src/app/core/main/editor/markdown/style.css",
"chars": 22253,
"preview": "/* Markdown Editor Styles */\n\n/* ========================\n Tiptap 编辑器核心样式\n ======================== */\n\n.tiptap-edit"
},
{
"path": "src/app/core/main/editor/markdown/sync/conflict-dialog.tsx",
"chars": 5722,
"preview": "'use client'\n\nimport { useState, useEffect } from 'react'\nimport { Editor } from '@tiptap/react'\nimport {\n Dialog,\n Di"
},
{
"path": "src/app/core/main/editor/markdown/sync/history-sheet.tsx",
"chars": 13076,
"preview": "'use client'\n\nimport { History, ExternalLink, RotateCcw } from 'lucide-react'\nimport { useCallback, useEffect, useState "
},
{
"path": "src/app/core/main/editor/markdown/sync/index.ts",
"chars": 174,
"preview": "export { SyncTools } from './sync-tools'\nexport { SyncButton } from './sync-button'\nexport { PullButton } from './pull-b"
},
{
"path": "src/app/core/main/editor/markdown/sync/pull-button.tsx",
"chars": 12910,
"preview": "'use client'\n\nimport { Editor } from '@tiptap/react'\nimport { ArrowDownCircle, Loader2 } from 'lucide-react'\nimport { us"
},
{
"path": "src/app/core/main/editor/markdown/sync/sync-button.tsx",
"chars": 9458,
"preview": "'use client'\n\nimport { ArrowUpCircle, CheckCircle, Loader2, XCircle } from 'lucide-react'\nimport { useCallback, useEffec"
},
{
"path": "src/app/core/main/editor/markdown/sync/sync-tools.tsx",
"chars": 1292,
"preview": "'use client'\nimport { Editor } from '@tiptap/react'\nimport { useTranslations } from 'next-intl'\nimport { SyncButton } fr"
},
{
"path": "src/app/core/main/editor/markdown/table-toolbar.tsx",
"chars": 4730,
"preview": "'use client'\n\nimport { Editor } from '@tiptap/react'\nimport {\n Table as TableIcon,\n Columns,\n Rows,\n Trash2,\n Align"
},
{
"path": "src/app/core/main/editor/markdown/tiptap-editor.tsx",
"chars": 74379,
"preview": "'use client'\n\nimport { useEditor, EditorContent } from '@tiptap/react'\nimport StarterKit from '@tiptap/starter-kit'\nimpo"
},
{
"path": "src/app/core/main/editor/onboarding-state.ts",
"chars": 2474,
"preview": "export type OnboardingStepId = 'create-record' | 'organize-note' | 'ai-polish'\nexport type OnboardingCompletionFeedbackM"
},
{
"path": "src/app/core/main/editor/tab-bar.tsx",
"chars": 13787,
"preview": "'use client'\n\nimport { useCallback, useRef, useState, useEffect, memo } from 'react'\nimport { X, FileText, Folder, Plus,"
},
{
"path": "src/app/core/main/editor/unsupported-file.tsx",
"chars": 6331,
"preview": "'use client'\n\nimport { useEffect, useState } from 'react'\nimport { File, FolderOpen, ExternalLink } from 'lucide-react'\n"
},
{
"path": "src/app/core/main/file/file-actions.tsx",
"chars": 4436,
"preview": "\"use client\"\n\nimport { TooltipButton } from \"@/components/tooltip-button\"\nimport { FilePlus, FolderPlus, FolderInput, Lo"
},
{
"path": "src/app/core/main/file/file-footer.tsx",
"chars": 8239,
"preview": "'use client'\n\nimport { Button } from \"@/components/ui/button\"\nimport { FolderOpen, FolderSync, SortAsc, SortDesc, Chevro"
},
{
"path": "src/app/core/main/file/file-item.tsx",
"chars": 38381,
"preview": "import { ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuSeparator, ContextMenuTrigger, ContextMenuShortcut"
},
{
"path": "src/app/core/main/file/file-manager.tsx",
"chars": 6300,
"preview": "'use client'\nimport React, { useEffect, useState, useMemo } from \"react\"\nimport { Collapsible, CollapsibleContent } from"
},
{
"path": "src/app/core/main/file/file-toolbar.tsx",
"chars": 3517,
"preview": "\"use client\"\nimport {\n FolderGit2, \n LoaderCircle,\n BookA,\n} from \"lucide-react\"\nimport * as React from \"react\"\nimpor"
},
{
"path": "src/app/core/main/file/folder-item/copy-folder.tsx",
"chars": 1214,
"preview": "import { ContextMenuItem, ContextMenuShortcut } from \"@/components/ui/enhanced-context-menu\";\nimport { DirTree } from \"@"
},
{
"path": "src/app/core/main/file/folder-item/cut-folder.tsx",
"chars": 1263,
"preview": "import { ContextMenuItem, ContextMenuShortcut } from \"@/components/ui/enhanced-context-menu\";\nimport { DirTree } from \"@"
},
{
"path": "src/app/core/main/file/folder-item/delete-folder.tsx",
"chars": 4569,
"preview": "import { ContextMenuItem, ContextMenuShortcut } from \"@/components/ui/enhanced-context-menu\";\nimport useArticleStore, { "
},
{
"path": "src/app/core/main/file/folder-item/duplicate-folder.tsx",
"chars": 3597,
"preview": "import { ContextMenuItem, ContextMenuShortcut } from \"@/components/ui/enhanced-context-menu\";\nimport { DirTree } from \"@"
},
{
"path": "src/app/core/main/file/folder-item/folder-vector-menu.tsx",
"chars": 5341,
"preview": "import { ContextMenuItem } from \"@/components/ui/enhanced-context-menu\";\nimport { useTranslations } from \"next-intl\";\nim"
},
{
"path": "src/app/core/main/file/folder-item/index.tsx",
"chars": 27281,
"preview": "import { ContextMenu, ContextMenuContent, ContextMenuSeparator, ContextMenuTrigger, ContextMenuSub, ContextMenuSubTrigge"
},
{
"path": "src/app/core/main/file/folder-item/new-file.tsx",
"chars": 1746,
"preview": "import { ContextMenuItem } from \"@/components/ui/enhanced-context-menu\";\nimport useArticleStore, { DirTree } from \"@/sto"
},
{
"path": "src/app/core/main/file/folder-item/new-folder.tsx",
"chars": 1069,
"preview": "import { ContextMenuItem } from \"@/components/ui/enhanced-context-menu\";\nimport useArticleStore, { DirTree } from \"@/sto"
},
{
"path": "src/app/core/main/file/folder-item/paste-in-folder.tsx",
"chars": 1534,
"preview": "import { ContextMenuItem, ContextMenuShortcut } from \"@/components/ui/enhanced-context-menu\";\nimport useArticleStore, { "
},
{
"path": "src/app/core/main/file/folder-item/paste-into-folder.js",
"chars": 3762,
"preview": "import { BaseDirectory, mkdir, readDir, readTextFile, remove, writeTextFile } from \"@tauri-apps/plugin-fs\"\n\nimport { toa"
},
{
"path": "src/app/core/main/file/folder-item/paste-target.js",
"chars": 76,
"preview": "export function getPasteTargetDirectory(folderPath) {\n return folderPath\n}\n"
},
{
"path": "src/app/core/main/file/folder-item/paste-target.spec.mjs",
"chars": 430,
"preview": "import test from 'node:test'\nimport assert from 'node:assert/strict'\n\nimport { getPasteTargetDirectory } from './paste-t"
},
{
"path": "src/app/core/main/file/folder-item/rename-folder.tsx",
"chars": 1353,
"preview": "import { ContextMenuItem, ContextMenuShortcut } from \"@/components/ui/enhanced-context-menu\";\nimport { Kbd } from \"@/com"
},
{
"path": "src/app/core/main/file/folder-item/sync-folder.tsx",
"chars": 1563,
"preview": "import { ContextMenuItem } from \"@/components/ui/enhanced-context-menu\";\nimport { RefreshCw } from \"lucide-react\";\nimpor"
},
{
"path": "src/app/core/main/file/folder-item/view-directory.tsx",
"chars": 1269,
"preview": "import { ContextMenuItem } from \"@/components/ui/enhanced-context-menu\";\nimport { DirTree } from \"@/stores/article\";\nimp"
},
{
"path": "src/app/core/main/file/index.tsx",
"chars": 7500,
"preview": "'use client'\n\nimport React, { useEffect, useState, useCallback, useRef } from \"react\"\nimport { FileManager } from \"./fil"
},
{
"path": "src/app/core/main/file/mobile-action-menu.tsx",
"chars": 1182,
"preview": "'use client'\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-me"
},
{
"path": "src/app/core/main/file/root-drop.js",
"chars": 637,
"preview": "export function sanitizeDroppedFileName(fileName) {\n return fileName.replace(/\\s+/g, '_')\n}\n\nexport async function writ"
},
{
"path": "src/app/core/main/file/root-drop.spec.mjs",
"chars": 1702,
"preview": "import test from 'node:test'\nimport assert from 'node:assert/strict'\n\nimport { sanitizeDroppedFileName, writeDroppedFile"
},
{
"path": "src/app/core/main/file/vector-knowledge-menu.tsx",
"chars": 5746,
"preview": "import { ContextMenuItem, ContextMenuSeparator, ContextMenuSub, ContextMenuSubTrigger, ContextMenuSubContent } from \"@/c"
},
{
"path": "src/app/core/main/file/workspace-selector.tsx",
"chars": 2398,
"preview": "'use client'\n\nimport { Select, SelectContent, SelectItem, SelectTrigger } from \"@/components/ui/select\"\nimport { FolderO"
},
{
"path": "src/app/core/main/left-sidebar.tsx",
"chars": 2787,
"preview": "'use client'\n\nimport { Tabs, TabsContent } from \"@/components/ui/tabs\"\nimport { Files, Highlighter } from \"lucide-react\""
},
{
"path": "src/app/core/main/mark/clipboard.tsx",
"chars": 6928,
"preview": "'use client'\nimport { clear, hasImage, hasText, readImageBase64, readText } from \"tauri-plugin-clipboard-api\";\nimport { "
},
{
"path": "src/app/core/main/mark/control-file.tsx",
"chars": 3835,
"preview": "import { TooltipButton } from \"@/components/tooltip-button\"\nimport { FilePlus } from \"lucide-react\"\nimport { useTranslat"
},
{
"path": "src/app/core/main/mark/control-image.tsx",
"chars": 8281,
"preview": "import { TooltipButton } from \"@/components/tooltip-button\"\nimport { insertMark, Mark } from \"@/db/marks\"\nimport { useTr"
},
{
"path": "src/app/core/main/mark/control-link.tsx",
"chars": 12571,
"preview": "import { TooltipButton } from \"@/components/tooltip-button\"\nimport { Button } from \"@/components/ui/button\"\nimport { Che"
},
{
"path": "src/app/core/main/mark/control-recording.tsx",
"chars": 11229,
"preview": "import { insertMark } from \"@/db/marks\"\nimport useMarkStore from \"@/stores/mark\"\nimport useTagStore from \"@/stores/tag\"\n"
},
{
"path": "src/app/core/main/mark/control-scan.tsx",
"chars": 7233,
"preview": "'use client'\nimport { TooltipButton } from \"@/components/tooltip-button\"\nimport { useTranslations } from 'next-intl'\nimp"
},
{
"path": "src/app/core/main/mark/control-text.tsx",
"chars": 8998,
"preview": "import { TooltipButton } from \"@/components/tooltip-button\"\nimport { Button } from \"@/components/ui/button\"\nimport { Che"
},
{
"path": "src/app/core/main/mark/control-todo.tsx",
"chars": 4744,
"preview": "import { TooltipButton } from \"@/components/tooltip-button\"\nimport { Button } from \"@/components/ui/button\"\nimport { use"
},
{
"path": "src/app/core/main/mark/crop.css",
"chars": 143,
"preview": ".cropper-bg{\n background-image: none !important;\n background-color: #000 !important;\n}\n\n.cropper-line{\n background-co"
},
{
"path": "src/app/core/main/mark/image-gallery.tsx",
"chars": 7141,
"preview": "'use client'\n\nimport { Mark, delMark, updateMark } from \"@/db/marks\"\nimport { useState, useEffect } from \"react\"\nimport "
},
{
"path": "src/app/core/main/mark/index.tsx",
"chars": 1763,
"preview": "'use client'\n\nimport { useTranslations } from 'next-intl'\nimport React from \"react\"\nimport { useEffect } from \"react\"\nim"
},
{
"path": "src/app/core/main/mark/mark-actions.tsx",
"chars": 1571,
"preview": "\"use client\"\n\nimport { TooltipButton } from \"@/components/tooltip-button\"\nimport { Trash2, XCircle, Sparkles } from \"luc"
},
{
"path": "src/app/core/main/mark/mark-empty.tsx",
"chars": 387,
"preview": "import { Highlighter } from \"lucide-react\";\nimport { useTranslations } from 'next-intl';\n\nexport default function MarkEm"
},
{
"path": "src/app/core/main/mark/mark-filter-popover.tsx",
"chars": 5635,
"preview": "\"use client\"\n\nimport { useState } from \"react\"\nimport { useTranslations } from \"next-intl\"\nimport { Filter, RotateCcw, S"
},
{
"path": "src/app/core/main/mark/mark-filters.mjs",
"chars": 2982,
"preview": "const DAY_IN_MS = 24 * 60 * 60 * 1000\nconst VALID_TYPES = new Set(['scan', 'text', 'image', 'link', 'file', 'recording',"
},
{
"path": "src/app/core/main/mark/mark-filters.spec.mjs",
"chars": 3125,
"preview": "import test from 'node:test'\nimport assert from 'node:assert/strict'\n\nimport { buildRecordFilterSummary, filterMarks, no"
},
{
"path": "src/app/core/main/mark/mark-header.tsx",
"chars": 5049,
"preview": "\"use client\"\nimport { useTranslations } from 'next-intl'\nimport * as React from \"react\"\nimport { initMarksDb } from \"@/d"
},
{
"path": "src/app/core/main/mark/mark-item.tsx",
"chars": 28658,
"preview": "'use client'\nimport React from \"react\"\nimport { delMark, delMarkForever, Mark, restoreMark, updateMark } from \"@/db/mark"
},
{
"path": "src/app/core/main/mark/mark-list-card-view.tsx",
"chars": 456,
"preview": "'use client'\n\nimport type { Mark } from \"@/db/marks\"\nimport { MarkItem } from \"./mark-item\"\n\nexport function MarkListCar"
},
{
"path": "src/app/core/main/mark/mark-list-compact-view.tsx",
"chars": 337,
"preview": "'use client'\n\nimport type { Mark } from \"@/db/marks\"\nimport { MarkItem } from \"./mark-item\"\n\nexport function MarkListCom"
},
{
"path": "src/app/core/main/mark/mark-list-default-view.tsx",
"chars": 332,
"preview": "'use client'\n\nimport type { Mark } from \"@/db/marks\"\nimport { MarkItem } from \"./mark-item\"\n\nexport function MarkListDef"
},
{
"path": "src/app/core/main/mark/mark-list-item-content.tsx",
"chars": 2866,
"preview": "import type { Mark } from \"@/db/marks\"\nimport type { Priority } from \"./todo-form\"\n\nexport type ParsedTodoMark = {\n tit"
},
{
"path": "src/app/core/main/mark/mark-list.tsx",
"chars": 3755,
"preview": "'use client'\n\nimport React from \"react\"\nimport { useTranslations } from \"next-intl\";\nimport type { Mark } from \"@/db/mar"
},
{
"path": "src/app/core/main/mark/mark-loading.tsx",
"chars": 1121,
"preview": "'use client'\nimport { MarkQueue } from \"@/stores/mark\";\nimport { LoaderCircle } from \"lucide-react\";\nimport { useTransla"
},
{
"path": "src/app/core/main/mark/mark-mobile-actions.tsx",
"chars": 5145,
"preview": "'use client'\n\nimport { useTranslations } from 'next-intl'\nimport { MoreVertical, FolderOpen, File, Link2, RefreshCw, Tra"
},
{
"path": "src/app/core/main/mark/mark-toolbar.tsx",
"chars": 2479,
"preview": "'use client'\n\nimport { ListChecks, SquareCheckBig, XCircle } from \"lucide-react\";\nimport { useTranslations } from 'next-"
},
{
"path": "src/app/core/main/mark/mark-type-meta.ts",
"chars": 3808,
"preview": "import type { Mark } from \"@/db/marks\"\nimport { cn } from \"@/lib/utils\"\n\nexport const MARK_TYPE_OPTIONS: Mark[\"type\"][] "
},
{
"path": "src/app/core/main/mark/mark-view-mode-toggle.tsx",
"chars": 1142,
"preview": "'use client'\n\nimport { LayoutGrid, Rows3, StretchHorizontal } from \"lucide-react\"\nimport { useTranslations } from \"next-"
},
{
"path": "src/app/core/main/mark/mark-view-mode.mjs",
"chars": 174,
"preview": "export const RECORD_VIEW_MODES = [\"list\", \"compact\", \"cards\"]\n\nexport function normalizeRecordViewMode(value) {\n return"
},
{
"path": "src/app/core/main/mark/mark-view-mode.spec.mjs",
"chars": 482,
"preview": "import test from \"node:test\"\nimport assert from \"node:assert/strict\"\nimport { normalizeRecordViewMode } from \"./mark-vie"
},
{
"path": "src/app/core/main/mark/organize-notes.tsx",
"chars": 17964,
"preview": "\"use client\"\nimport useSettingStore, { GenTemplate, GenTemplateRange } from \"@/stores/setting\"\nimport useMarkStore from "
},
{
"path": "src/app/core/main/mark/organize-onboarding.ts",
"chars": 177,
"preview": "export function shouldEmitOrganizeOnboardingComplete({\n streamFinished,\n aborted,\n}: {\n streamFinished: boolean\n abo"
},
{
"path": "src/app/core/main/mark/tag-item.tsx",
"chars": 3750,
"preview": "import {\n ContextMenu,\n ContextMenuContent,\n ContextMenuItem,\n ContextMenuTrigger,\n} from \"@/components/ui/enhanced-"
},
{
"path": "src/app/core/main/mark/tag-manage.tsx",
"chars": 17772,
"preview": "\"use client\"\nimport * as React from \"react\"\nimport { useTranslations } from 'next-intl'\nimport { Plus, TagIcon, Inbox, S"
},
{
"path": "src/app/core/main/mark/tag-mobile-actions.tsx",
"chars": 1978,
"preview": "'use client'\n\nimport { useTranslations } from 'next-intl'\nimport { MoreVertical, Edit2, Trash2 } from 'lucide-react'\nimp"
},
{
"path": "src/app/core/main/mark/todo-edit-button.tsx",
"chars": 673,
"preview": "'use client'\n\nimport { useState } from \"react\"\nimport type { Mark } from \"@/db/marks\"\nimport { cn } from \"@/lib/utils\"\ni"
},
{
"path": "src/app/core/main/mark/todo-edit-dialog.tsx",
"chars": 4751,
"preview": "import { Mark } from \"@/db/marks\"\nimport { useTranslations } from 'next-intl'\nimport {\n Dialog,\n DialogContent,\n Dial"
},
{
"path": "src/app/core/main/mark/todo-form.tsx",
"chars": 3886,
"preview": "import { Label } from \"@/components/ui/label\"\nimport { Textarea } from \"@/components/ui/textarea\"\nimport { Input } from "
},
{
"path": "src/app/core/main/mark/todo-item-content.tsx",
"chars": 3844,
"preview": "import { Mark } from \"@/db/marks\"\nimport { useTranslations } from 'next-intl'\nimport dayjs from \"dayjs\"\nimport relativeT"
},
{
"path": "src/app/core/main/page.tsx",
"chars": 7605,
"preview": "'use client'\n\nimport { ResizableHandle, ResizablePanel, ResizablePanelGroup } from \"@/components/ui/resizable\"\nimport { "
},
{
"path": "src/app/core/setting/about/page.tsx",
"chars": 195,
"preview": "'use client';\n\nimport { Store } from \"lucide-react\"\nimport { SettingAbout } from \"./setting-about\";\n\nexport default func"
},
{
"path": "src/app/core/setting/about/setting-about.tsx",
"chars": 2844,
"preview": "'use client';\nimport { SettingType } from \"../components/setting-base\";\nimport { Item, ItemGroup, ItemMedia, ItemContent"
},
{
"path": "src/app/core/setting/about/updater.tsx",
"chars": 4849,
"preview": "import { relaunch } from '@tauri-apps/plugin-process';\nimport { useEffect, useState } from 'react';\nimport { Button } fr"
},
{
"path": "src/app/core/setting/ai/create.tsx",
"chars": 5624,
"preview": "import { Button } from \"@/components/ui/button\"\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,"
},
{
"path": "src/app/core/setting/ai/default-models.tsx",
"chars": 3094,
"preview": "'use client'\nimport { useTranslations } from 'next-intl';\nimport { useTheme } from 'next-themes';\nimport { Card, CardCon"
},
{
"path": "src/app/core/setting/ai/model-card.tsx",
"chars": 12875,
"preview": "'use client'\nimport { \n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n} from \"@/components/ui/accordion\"\nimpor"
},
{
"path": "src/app/core/setting/ai/modelSelect.tsx",
"chars": 6912,
"preview": "import { useEffect, useState, useRef } from \"react\";\nimport useSettingStore from \"@/stores/setting\";\nimport { Input } fr"
},
{
"path": "src/app/core/setting/ai/page.tsx",
"chars": 17170,
"preview": "'use client'\nimport { useState, useEffect } from \"react\";\nimport { useTranslations } from 'next-intl';\nimport { useLocal"
},
{
"path": "src/app/core/setting/audio/page.tsx",
"chars": 404,
"preview": "'use client';\nimport { SettingType } from \"../components/setting-base\";\nimport { Setting } from \"./setting\";\nimport { Vo"
},
{
"path": "src/app/core/setting/audio/setting.tsx",
"chars": 6282,
"preview": "import { Item, ItemGroup, ItemMedia, ItemContent, ItemTitle, ItemDescription, ItemActions } from '@/components/ui/item';"
},
{
"path": "src/app/core/setting/chat/condense-settings.tsx",
"chars": 3540,
"preview": "'use client'\n\nimport { useTranslations } from 'next-intl'\nimport {\n Item,\n ItemMedia,\n ItemContent,\n ItemTitle,\n It"
},
{
"path": "src/app/core/setting/chat/page.tsx",
"chars": 771,
"preview": "'use client'\n\nimport { useTranslations } from 'next-intl'\nimport { SettingType } from '../components/setting-base'\nimpor"
},
{
"path": "src/app/core/setting/chat/primary-model-settings.tsx",
"chars": 785,
"preview": "'use client'\n\nimport { useTranslations } from 'next-intl'\nimport {\n Item,\n ItemMedia,\n ItemContent,\n ItemTitle,\n It"
},
{
"path": "src/app/core/setting/chat/toolbar-settings.tsx",
"chars": 5454,
"preview": "'use client'\n\nimport { useTranslations } from 'next-intl'\nimport { Switch } from '@/components/ui/switch'\nimport {\n Bot"
},
{
"path": "src/app/core/setting/components/default-models-settings.tsx",
"chars": 3763,
"preview": "'use client'\n\nimport { useTranslations } from 'next-intl'\nimport {\n Item,\n ItemMedia,\n ItemContent,\n ItemTitle,\n It"
}
]
// ... and 405 more files (download for full content)
About this extraction
This page contains the full source code of the codexu/note-gen GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 605 files (3.5 MB), approximately 941.5k tokens, and a symbol index with 1980 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.