Full Code of lobehub/lobe-chat for AI

canary d25db6e6f899 cached
9158 files
69.7 MB
18.8M tokens
13427 symbols
4 requests
Copy disabled (too large) Download .txt
Showing preview only (78,769K chars total). Download the full file to get everything.
Repository: lobehub/lobe-chat
Branch: canary
Commit: d25db6e6f899
Files: 9158
Total size: 69.7 MB

Directory structure:
gitextract_qs6a0kl7/

├── .agents/
│   └── skills/
│       ├── add-provider-doc/
│       │   └── SKILL.md
│       ├── add-setting-env/
│       │   └── SKILL.md
│       ├── agent-tracing/
│       │   └── SKILL.md
│       ├── chat-sdk/
│       │   └── SKILL.md
│       ├── cli/
│       │   ├── SKILL.md
│       │   └── references/
│       │       ├── agent.md
│       │       ├── conversation.md
│       │       ├── generate.md
│       │       ├── knowledge.md
│       │       ├── memory.md
│       │       ├── models-providers.md
│       │       ├── search-config.md
│       │       └── skills-plugins.md
│       ├── code-review/
│       │   └── SKILL.md
│       ├── data-fetching/
│       │   └── SKILL.md
│       ├── db-migrations/
│       │   └── SKILL.md
│       ├── debug/
│       │   └── SKILL.md
│       ├── desktop/
│       │   ├── SKILL.md
│       │   └── references/
│       │       ├── feature-implementation.md
│       │       ├── local-tools.md
│       │       ├── menu-config.md
│       │       └── window-management.md
│       ├── drizzle/
│       │   └── SKILL.md
│       ├── hotkey/
│       │   └── SKILL.md
│       ├── i18n/
│       │   └── SKILL.md
│       ├── linear/
│       │   └── SKILL.md
│       ├── local-testing/
│       │   ├── SKILL.md
│       │   └── scripts/
│       │       ├── capture-app-window.sh
│       │       ├── record-electron-demo.sh
│       │       ├── test-discord-bot.sh
│       │       ├── test-lark-bot.sh
│       │       ├── test-qq-bot.sh
│       │       ├── test-slack-bot.sh
│       │       ├── test-telegram-bot.sh
│       │       └── test-wechat-bot.sh
│       ├── microcopy/
│       │   ├── SKILL.md
│       │   ├── microcopy-cn.md
│       │   └── microcopy-en.md
│       ├── modal/
│       │   └── SKILL.md
│       ├── pr/
│       │   └── SKILL.md
│       ├── project-overview/
│       │   └── SKILL.md
│       ├── react/
│       │   ├── SKILL.md
│       │   └── references/
│       │       └── layout-kit.md
│       ├── recent-data/
│       │   └── SKILL.md
│       ├── response-compliance/
│       │   └── SKILL.md
│       ├── spa-routes/
│       │   └── SKILL.md
│       ├── store-data-structures/
│       │   └── SKILL.md
│       ├── testing/
│       │   ├── SKILL.md
│       │   └── references/
│       │       ├── agent-runtime-e2e.md
│       │       ├── db-model-test.md
│       │       ├── desktop-controller-test.md
│       │       ├── electron-ipc-test.md
│       │       └── zustand-store-action-test.md
│       ├── trpc-router/
│       │   └── SKILL.md
│       ├── typescript/
│       │   └── SKILL.md
│       ├── upstash-workflow/
│       │   ├── SKILL.md
│       │   └── reference/
│       │       └── cloud.md
│       ├── version-release/
│       │   ├── SKILL.md
│       │   └── reference/
│       │       ├── changelog-example/
│       │       │   ├── db-migration.md
│       │       │   └── weekly-release.md
│       │       └── patch-release-scenarios.md
│       └── zustand/
│           ├── SKILL.md
│           └── references/
│               ├── action-patterns.md
│               └── slice-organization.md
├── .bunfig.toml
├── .changelogrc.cjs
├── .conductor/
│   └── setup.sh
├── .console-log-whitelist.json
├── .cursor/
│   └── docs/
│       └── createStaticStyles_migration_guide.md
├── .cursorindexingignore
├── .devcontainer/
│   └── devcontainer.json
├── .editorconfig
├── .gitattributes
├── .github/
│   ├── CODEOWNERS
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── 1_bug_report.yml
│   │   ├── 2_feature_request.yml
│   │   └── config.yml
│   ├── PULL_REQUEST_TEMPLATE.md
│   ├── actions/
│   │   ├── desktop-build-setup/
│   │   │   └── action.yml
│   │   ├── desktop-cleanup-s3/
│   │   │   └── action.yml
│   │   ├── desktop-publish-s3/
│   │   │   └── action.yml
│   │   ├── desktop-upload-artifacts/
│   │   │   └── action.yml
│   │   ├── setup-env/
│   │   │   └── action.yml
│   │   ├── setup-node-bun/
│   │   │   └── action.yml
│   │   └── setup-node-pnpm/
│   │       └── action.yml
│   ├── scripts/
│   │   ├── auto-close-duplicates.ts
│   │   ├── create-failure-issue.js
│   │   ├── docker-pr-comment.js
│   │   ├── lock-closed-issues.js
│   │   ├── pr-comment.js
│   │   └── pr-release-body.js
│   └── workflows/
│       ├── auto-i18n.yml
│       ├── auto-tag-release.yml
│       ├── bundle-analyzer.yml
│       ├── claude-auto-e2e-testing.yml
│       ├── claude-auto-testing.yml
│       ├── claude-dedupe-issues.yml
│       ├── claude-issue-triage.yml
│       ├── claude-migration-support.yml
│       ├── claude-pr-assign.yml
│       ├── claude-translate-comments.yml
│       ├── claude-translator.yml
│       ├── claude.yml
│       ├── e2e.yml
│       ├── issue-auto-close-duplicates.yml
│       ├── issue-auto-comments.yml
│       ├── issue-close-require.yml
│       ├── lighthouse.yml
│       ├── lock-closed-issues.yml
│       ├── manual-build-desktop.yml
│       ├── pr-build-desktop.yml
│       ├── pr-build-docker.yml
│       ├── release-desktop-beta.yml
│       ├── release-desktop-canary.yml
│       ├── release-desktop-nightly.yml
│       ├── release-desktop-stable.yml
│       ├── release-docker.yml
│       ├── release.yml
│       ├── revalidate-docs.yml
│       ├── sync-database-schema.yml
│       ├── sync-main-to-canary.yaml
│       ├── sync.yml
│       └── test.yml
├── .gitignore
├── .husky/
│   └── pre-commit
├── .i18nrc.js
├── .npmrc
├── .nvmrc
├── .prettierignore
├── .releaserc.cjs
├── .remarkrc.mdx.mjs
├── .remarkrc.mjs
├── .seorc.cjs
├── .stylelintignore
├── .vscode/
│   ├── extensions.json
│   └── settings.json
├── AGENTS.md
├── CHANGELOG.md
├── CLAUDE.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Dockerfile
├── GEMINI.md
├── LICENSE
├── README.md
├── README.zh-CN.md
├── __mocks__/
│   └── zustand/
│       └── traditional.ts
├── apps/
│   ├── cli/
│   │   ├── .npmrc
│   │   ├── README.md
│   │   ├── e2e/
│   │   │   ├── agent.e2e.test.ts
│   │   │   ├── doc.e2e.test.ts
│   │   │   ├── file.e2e.test.ts
│   │   │   ├── generate.e2e.test.ts
│   │   │   ├── kb.e2e.test.ts
│   │   │   ├── memory.e2e.test.ts
│   │   │   ├── message.e2e.test.ts
│   │   │   ├── model.e2e.test.ts
│   │   │   ├── plugin.e2e.test.ts
│   │   │   ├── provider.e2e.test.ts
│   │   │   ├── search.e2e.test.ts
│   │   │   ├── skill.e2e.test.ts
│   │   │   └── topic.e2e.test.ts
│   │   ├── man/
│   │   │   └── man1/
│   │   │       ├── lh.1
│   │   │       ├── lobe.1
│   │   │       └── lobehub.1
│   │   ├── package.json
│   │   ├── pnpm-workspace.yaml
│   │   ├── src/
│   │   │   ├── api/
│   │   │   │   ├── client.ts
│   │   │   │   └── http.ts
│   │   │   ├── auth/
│   │   │   │   ├── apiKey.ts
│   │   │   │   ├── credentials.test.ts
│   │   │   │   ├── credentials.ts
│   │   │   │   ├── refresh.test.ts
│   │   │   │   ├── refresh.ts
│   │   │   │   ├── resolveToken.test.ts
│   │   │   │   └── resolveToken.ts
│   │   │   ├── commands/
│   │   │   │   ├── agent-group.test.ts
│   │   │   │   ├── agent-group.ts
│   │   │   │   ├── agent.test.ts
│   │   │   │   ├── agent.ts
│   │   │   │   ├── bot.test.ts
│   │   │   │   ├── bot.ts
│   │   │   │   ├── botMessage.ts
│   │   │   │   ├── brief.ts
│   │   │   │   ├── completion.test.ts
│   │   │   │   ├── completion.ts
│   │   │   │   ├── config.test.ts
│   │   │   │   ├── config.ts
│   │   │   │   ├── connect.test.ts
│   │   │   │   ├── connect.ts
│   │   │   │   ├── cron.test.ts
│   │   │   │   ├── cron.ts
│   │   │   │   ├── device.ts
│   │   │   │   ├── doc.test.ts
│   │   │   │   ├── doc.ts
│   │   │   │   ├── eval.test.ts
│   │   │   │   ├── eval.ts
│   │   │   │   ├── file.test.ts
│   │   │   │   ├── file.ts
│   │   │   │   ├── generate/
│   │   │   │   │   ├── asr.ts
│   │   │   │   │   ├── image.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── text.ts
│   │   │   │   │   ├── tts.ts
│   │   │   │   │   └── video.ts
│   │   │   │   ├── generate.test.ts
│   │   │   │   ├── kb.test.ts
│   │   │   │   ├── kb.ts
│   │   │   │   ├── login.test.ts
│   │   │   │   ├── login.ts
│   │   │   │   ├── logout.test.ts
│   │   │   │   ├── logout.ts
│   │   │   │   ├── man.test.ts
│   │   │   │   ├── man.ts
│   │   │   │   ├── memory.test.ts
│   │   │   │   ├── memory.ts
│   │   │   │   ├── message.test.ts
│   │   │   │   ├── message.ts
│   │   │   │   ├── model.test.ts
│   │   │   │   ├── model.ts
│   │   │   │   ├── plugin.test.ts
│   │   │   │   ├── plugin.ts
│   │   │   │   ├── provider.test.ts
│   │   │   │   ├── provider.ts
│   │   │   │   ├── search.test.ts
│   │   │   │   ├── search.ts
│   │   │   │   ├── session-group.test.ts
│   │   │   │   ├── session-group.ts
│   │   │   │   ├── skill.test.ts
│   │   │   │   ├── skill.ts
│   │   │   │   ├── status.test.ts
│   │   │   │   ├── status.ts
│   │   │   │   ├── task/
│   │   │   │   │   ├── checkpoint.ts
│   │   │   │   │   ├── dep.ts
│   │   │   │   │   ├── doc.ts
│   │   │   │   │   ├── helpers.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── lifecycle.ts
│   │   │   │   │   ├── review.ts
│   │   │   │   │   └── topic.ts
│   │   │   │   ├── thread.test.ts
│   │   │   │   ├── thread.ts
│   │   │   │   ├── topic.test.ts
│   │   │   │   ├── topic.ts
│   │   │   │   ├── user.test.ts
│   │   │   │   └── user.ts
│   │   │   ├── constants/
│   │   │   │   ├── auth.ts
│   │   │   │   └── urls.ts
│   │   │   ├── daemon/
│   │   │   │   ├── manager.test.ts
│   │   │   │   └── manager.ts
│   │   │   ├── index.ts
│   │   │   ├── man/
│   │   │   │   ├── generate.ts
│   │   │   │   ├── roff.test.ts
│   │   │   │   └── roff.ts
│   │   │   ├── program.ts
│   │   │   ├── settings/
│   │   │   │   ├── index.test.ts
│   │   │   │   └── index.ts
│   │   │   ├── tools/
│   │   │   │   ├── file.test.ts
│   │   │   │   ├── file.ts
│   │   │   │   ├── index.test.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── shell.test.ts
│   │   │   │   └── shell.ts
│   │   │   └── utils/
│   │   │       ├── __snapshots__/
│   │   │       │   └── format.test.ts.snap
│   │   │       ├── agentStream.test.ts
│   │   │       ├── agentStream.ts
│   │   │       ├── completion.ts
│   │   │       ├── format.test.ts
│   │   │       ├── format.ts
│   │   │       ├── logger.test.ts
│   │   │       └── logger.ts
│   │   ├── tsconfig.json
│   │   ├── tsdown.config.ts
│   │   └── vitest.config.mts
│   ├── desktop/
│   │   ├── .gitignore
│   │   ├── .i18nrc.js
│   │   ├── .npmrc
│   │   ├── .prettierignore
│   │   ├── .remarkrc.mjs
│   │   ├── .stylelintignore
│   │   ├── Development.md
│   │   ├── README.md
│   │   ├── README.zh-CN.md
│   │   ├── build/
│   │   │   ├── Icon-beta.Assets.car
│   │   │   ├── Icon-beta.icns
│   │   │   ├── Icon-dev.Assets.car
│   │   │   ├── Icon-nightly.Assets.car
│   │   │   ├── Icon-nightly.icns
│   │   │   ├── Icon.Assets.car
│   │   │   ├── Icon.icns
│   │   │   └── entitlements.mac.plist
│   │   ├── dev-app-update.yml
│   │   ├── electron-builder.mjs
│   │   ├── electron.vite.config.ts
│   │   ├── index.html
│   │   ├── native-deps.config.mjs
│   │   ├── package.json
│   │   ├── pnpm-workspace.yaml
│   │   ├── prettier.config.mjs
│   │   ├── resources/
│   │   │   ├── error.html
│   │   │   ├── locales/
│   │   │   │   ├── ar/
│   │   │   │   │   ├── common.json
│   │   │   │   │   ├── dialog.json
│   │   │   │   │   └── menu.json
│   │   │   │   ├── bg-BG/
│   │   │   │   │   ├── common.json
│   │   │   │   │   ├── dialog.json
│   │   │   │   │   └── menu.json
│   │   │   │   ├── de-DE/
│   │   │   │   │   ├── common.json
│   │   │   │   │   ├── dialog.json
│   │   │   │   │   └── menu.json
│   │   │   │   ├── en/
│   │   │   │   │   ├── common.json
│   │   │   │   │   ├── dialog.json
│   │   │   │   │   └── menu.json
│   │   │   │   ├── es-ES/
│   │   │   │   │   ├── common.json
│   │   │   │   │   ├── dialog.json
│   │   │   │   │   └── menu.json
│   │   │   │   ├── fa-IR/
│   │   │   │   │   ├── common.json
│   │   │   │   │   ├── dialog.json
│   │   │   │   │   └── menu.json
│   │   │   │   ├── fr-FR/
│   │   │   │   │   ├── common.json
│   │   │   │   │   ├── dialog.json
│   │   │   │   │   └── menu.json
│   │   │   │   ├── it-IT/
│   │   │   │   │   ├── common.json
│   │   │   │   │   ├── dialog.json
│   │   │   │   │   └── menu.json
│   │   │   │   ├── ja-JP/
│   │   │   │   │   ├── common.json
│   │   │   │   │   ├── dialog.json
│   │   │   │   │   └── menu.json
│   │   │   │   ├── ko-KR/
│   │   │   │   │   ├── common.json
│   │   │   │   │   ├── dialog.json
│   │   │   │   │   └── menu.json
│   │   │   │   ├── nl-NL/
│   │   │   │   │   ├── common.json
│   │   │   │   │   ├── dialog.json
│   │   │   │   │   └── menu.json
│   │   │   │   ├── pl-PL/
│   │   │   │   │   ├── common.json
│   │   │   │   │   ├── dialog.json
│   │   │   │   │   └── menu.json
│   │   │   │   ├── pt-BR/
│   │   │   │   │   ├── common.json
│   │   │   │   │   ├── dialog.json
│   │   │   │   │   └── menu.json
│   │   │   │   ├── ru-RU/
│   │   │   │   │   ├── common.json
│   │   │   │   │   ├── dialog.json
│   │   │   │   │   └── menu.json
│   │   │   │   ├── tr-TR/
│   │   │   │   │   ├── common.json
│   │   │   │   │   ├── dialog.json
│   │   │   │   │   └── menu.json
│   │   │   │   ├── vi-VN/
│   │   │   │   │   ├── common.json
│   │   │   │   │   ├── dialog.json
│   │   │   │   │   └── menu.json
│   │   │   │   ├── zh-CN/
│   │   │   │   │   ├── common.json
│   │   │   │   │   ├── dialog.json
│   │   │   │   │   └── menu.json
│   │   │   │   └── zh-TW/
│   │   │   │       ├── common.json
│   │   │   │       ├── dialog.json
│   │   │   │       └── menu.json
│   │   │   └── splash.html
│   │   ├── scripts/
│   │   │   ├── download-agent-browser.mjs
│   │   │   ├── i18nWorkflow/
│   │   │   │   ├── const.ts
│   │   │   │   ├── genDefaultLocale.ts
│   │   │   │   ├── genDiff.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── utils.ts
│   │   │   └── update-test/
│   │   │       ├── .gitignore
│   │   │       ├── README.md
│   │   │       ├── dev-app-update.local.yml
│   │   │       ├── generate-manifest.sh
│   │   │       ├── run-test.sh
│   │   │       ├── setup.sh
│   │   │       ├── start-server.sh
│   │   │       └── stop-server.sh
│   │   ├── src/
│   │   │   ├── common/
│   │   │   │   └── routes.ts
│   │   │   ├── main/
│   │   │   │   ├── __mocks__/
│   │   │   │   │   ├── node-mac-permissions.ts
│   │   │   │   │   └── setup.ts
│   │   │   │   ├── appBrowsers.ts
│   │   │   │   ├── const/
│   │   │   │   │   ├── dir.ts
│   │   │   │   │   ├── env.ts
│   │   │   │   │   ├── protocol.ts
│   │   │   │   │   ├── store.ts
│   │   │   │   │   └── theme.ts
│   │   │   │   ├── controllers/
│   │   │   │   │   ├── AuthCtr.ts
│   │   │   │   │   ├── BrowserWindowsCtr.ts
│   │   │   │   │   ├── DevtoolsCtr.ts
│   │   │   │   │   ├── GatewayConnectionCtr.ts
│   │   │   │   │   ├── LocalFileCtr.ts
│   │   │   │   │   ├── McpCtr.ts
│   │   │   │   │   ├── McpInstallCtr.ts
│   │   │   │   │   ├── MenuCtr.ts
│   │   │   │   │   ├── NetworkProxyCtr.ts
│   │   │   │   │   ├── NotificationCtr.ts
│   │   │   │   │   ├── RemoteServerConfigCtr.ts
│   │   │   │   │   ├── RemoteServerSyncCtr.ts
│   │   │   │   │   ├── ShellCommandCtr.ts
│   │   │   │   │   ├── ShortcutCtr.ts
│   │   │   │   │   ├── SystemCtr.ts
│   │   │   │   │   ├── ToolDetectorCtr.ts
│   │   │   │   │   ├── TrayMenuCtr.ts
│   │   │   │   │   ├── UpdaterCtr.ts
│   │   │   │   │   ├── UploadFileCtr.ts
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   ├── AuthCtr.test.ts
│   │   │   │   │   │   ├── BrowserWindowsCtr.test.ts
│   │   │   │   │   │   ├── DevtoolsCtr.test.ts
│   │   │   │   │   │   ├── GatewayConnectionCtr.test.ts
│   │   │   │   │   │   ├── LocalFileCtr.test.ts
│   │   │   │   │   │   ├── McpInstallCtr.test.ts
│   │   │   │   │   │   ├── MenuCtr.test.ts
│   │   │   │   │   │   ├── NetworkProxyCtr.test.ts
│   │   │   │   │   │   ├── NotificationCtr.test.ts
│   │   │   │   │   │   ├── RemoteServerConfigCtr.test.ts
│   │   │   │   │   │   ├── ShellCommandCtr.test.ts
│   │   │   │   │   │   ├── ShortcutCtr.test.ts
│   │   │   │   │   │   ├── SystemCtr.test.ts
│   │   │   │   │   │   ├── TrayMenuCtr.test.ts
│   │   │   │   │   │   ├── UpdaterCtr.test.ts
│   │   │   │   │   │   └── UploadFileCtr.test.ts
│   │   │   │   │   ├── _template.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── registry.ts
│   │   │   │   ├── core/
│   │   │   │   │   ├── App.ts
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   └── App.test.ts
│   │   │   │   │   ├── browser/
│   │   │   │   │   │   ├── Browser.ts
│   │   │   │   │   │   ├── BrowserManager.ts
│   │   │   │   │   │   ├── WindowStateManager.ts
│   │   │   │   │   │   ├── WindowThemeManager.ts
│   │   │   │   │   │   └── __tests__/
│   │   │   │   │   │       ├── Browser.test.ts
│   │   │   │   │   │       ├── BrowserManager.test.ts
│   │   │   │   │   │       ├── WindowStateManager.test.ts
│   │   │   │   │   │       └── WindowThemeManager.test.ts
│   │   │   │   │   ├── infrastructure/
│   │   │   │   │   │   ├── BackendProxyProtocolManager.ts
│   │   │   │   │   │   ├── I18nManager.ts
│   │   │   │   │   │   ├── IoCContainer.ts
│   │   │   │   │   │   ├── ProtocolManager.ts
│   │   │   │   │   │   ├── RendererProtocolManager.ts
│   │   │   │   │   │   ├── RendererUrlManager.ts
│   │   │   │   │   │   ├── StaticFileServerManager.ts
│   │   │   │   │   │   ├── StoreManager.ts
│   │   │   │   │   │   ├── ToolDetectorManager.ts
│   │   │   │   │   │   ├── UpdaterManager.ts
│   │   │   │   │   │   └── __tests__/
│   │   │   │   │   │       ├── BackendProxyProtocolManager.test.ts
│   │   │   │   │   │       ├── I18nManager.test.ts
│   │   │   │   │   │       ├── IoCContainer.test.ts
│   │   │   │   │   │       ├── ProtocolManager.test.ts
│   │   │   │   │   │       ├── RendererProtocolManager.test.ts
│   │   │   │   │   │       ├── RendererUrlManager.test.ts
│   │   │   │   │   │       ├── StaticFileServerManager.test.ts
│   │   │   │   │   │       ├── StoreManager.test.ts
│   │   │   │   │   │       └── UpdaterManager.test.ts
│   │   │   │   │   └── ui/
│   │   │   │   │       ├── MenuManager.ts
│   │   │   │   │       ├── ShortcutManager.ts
│   │   │   │   │       ├── Tray.ts
│   │   │   │   │       ├── TrayManager.ts
│   │   │   │   │       └── __tests__/
│   │   │   │   │           ├── MenuManager.test.ts
│   │   │   │   │           ├── ShortcutManager.test.ts
│   │   │   │   │           ├── Tray.test.ts
│   │   │   │   │           └── TrayManager.test.ts
│   │   │   │   ├── env.ts
│   │   │   │   ├── exports.d.ts
│   │   │   │   ├── exports.ts
│   │   │   │   ├── global.d.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── libs/
│   │   │   │   │   └── mcp/
│   │   │   │   │       ├── client.ts
│   │   │   │   │       └── types.ts
│   │   │   │   ├── locales/
│   │   │   │   │   ├── default/
│   │   │   │   │   │   ├── common.ts
│   │   │   │   │   │   ├── dialog.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── menu.ts
│   │   │   │   │   └── resources.ts
│   │   │   │   ├── menus/
│   │   │   │   │   ├── impls/
│   │   │   │   │   │   ├── BaseMenuPlatform.test.ts
│   │   │   │   │   │   ├── BaseMenuPlatform.ts
│   │   │   │   │   │   ├── linux.test.ts
│   │   │   │   │   │   ├── linux.ts
│   │   │   │   │   │   ├── macOS.test.ts
│   │   │   │   │   │   ├── macOS.ts
│   │   │   │   │   │   ├── windows.test.ts
│   │   │   │   │   │   └── windows.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── types.ts
│   │   │   │   ├── modules/
│   │   │   │   │   ├── contentSearch/
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   ├── base.test.ts
│   │   │   │   │   │   │   └── index.test.ts
│   │   │   │   │   │   ├── base.ts
│   │   │   │   │   │   ├── impl/
│   │   │   │   │   │   │   ├── linux.ts
│   │   │   │   │   │   │   ├── macOS.ts
│   │   │   │   │   │   │   ├── unix.ts
│   │   │   │   │   │   │   └── windows.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── fileSearch/
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   ├── base.test.ts
│   │   │   │   │   │   │   ├── index.test.ts
│   │   │   │   │   │   │   └── macOS.integration.test.ts
│   │   │   │   │   │   ├── base.ts
│   │   │   │   │   │   ├── impl/
│   │   │   │   │   │   │   ├── linux.ts
│   │   │   │   │   │   │   ├── macOS.ts
│   │   │   │   │   │   │   ├── unix.ts
│   │   │   │   │   │   │   └── windows.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── types.ts
│   │   │   │   │   ├── networkProxy/
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   ├── dispatcher.test.ts
│   │   │   │   │   │   │   ├── tester.test.ts
│   │   │   │   │   │   │   ├── urlBuilder.test.ts
│   │   │   │   │   │   │   └── validator.test.ts
│   │   │   │   │   │   ├── dispatcher.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── tester.ts
│   │   │   │   │   │   ├── urlBuilder.ts
│   │   │   │   │   │   └── validator.ts
│   │   │   │   │   ├── toolDetectors/
│   │   │   │   │   │   ├── agentBrowserDetectors.ts
│   │   │   │   │   │   ├── contentSearchDetectors.ts
│   │   │   │   │   │   ├── fileSearchDetectors.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── runtimeEnvironmentDetectors.ts
│   │   │   │   │   └── updater/
│   │   │   │   │       ├── configs.ts
│   │   │   │   │       └── utils.ts
│   │   │   │   ├── package.json
│   │   │   │   ├── services/
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   ├── fileSearchSrv.test.ts
│   │   │   │   │   │   └── fileSrv.test.ts
│   │   │   │   │   ├── contentSearchSrv.ts
│   │   │   │   │   ├── fileSearchSrv.ts
│   │   │   │   │   ├── fileSrv.ts
│   │   │   │   │   ├── gatewayConnectionSrv.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── shortcuts/
│   │   │   │   │   ├── config.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── types/
│   │   │   │   │   ├── protocol.ts
│   │   │   │   │   └── store.ts
│   │   │   │   └── utils/
│   │   │   │       ├── __tests__/
│   │   │   │       │   ├── file-system.test.ts
│   │   │   │       │   ├── http-headers.test.ts
│   │   │   │       │   ├── logger.test.ts
│   │   │   │       │   └── protocol.test.ts
│   │   │   │       ├── file-system.ts
│   │   │   │       ├── http-headers.ts
│   │   │   │       ├── ipc/
│   │   │   │       │   ├── __tests__/
│   │   │   │       │   │   └── base.test.ts
│   │   │   │       │   ├── base.ts
│   │   │   │       │   ├── index.ts
│   │   │   │       │   └── utility.ts
│   │   │   │       ├── logger.ts
│   │   │   │       ├── mime.ts
│   │   │   │       ├── path.ts
│   │   │   │       ├── permissions.ts
│   │   │   │       └── protocol.ts
│   │   │   └── preload/
│   │   │       ├── electronApi.test.ts
│   │   │       ├── electronApi.ts
│   │   │       ├── index.ts
│   │   │       ├── invoke.test.ts
│   │   │       ├── invoke.ts
│   │   │       ├── routeInterceptor.test.ts
│   │   │       ├── routeInterceptor.ts
│   │   │       ├── streamer.test.ts
│   │   │       └── streamer.ts
│   │   ├── stylelint.config.mjs
│   │   ├── tsconfig.json
│   │   └── vitest.config.mts
│   └── device-gateway/
│       ├── package.json
│       ├── scripts/
│       │   └── extract-public-key.mjs
│       ├── src/
│       │   ├── DeviceGatewayDO.ts
│       │   ├── auth.test.ts
│       │   ├── auth.ts
│       │   ├── index.ts
│       │   └── types.ts
│       ├── tsconfig.json
│       └── wrangler.toml
├── changelog/
│   ├── CHANGELOG.v0.md
│   ├── CHANGELOG.v1.md
│   ├── v0.json
│   ├── v1.json
│   └── v2.json
├── codecov.yml
├── commitlint.config.mjs
├── conductor.json
├── docker-compose/
│   ├── deploy/
│   │   ├── bucket.config.json
│   │   ├── docker-compose.yml
│   │   └── searxng-settings.yml
│   ├── dev/
│   │   ├── .gitignore
│   │   ├── bucket.config.json
│   │   ├── docker-compose.yml
│   │   └── searxng-settings.yml
│   ├── production/
│   │   └── grafana/
│   │       ├── docker-compose.yml
│   │       ├── grafana/
│   │       │   ├── dashboards/
│   │       │   │   └── .gitkeep
│   │       │   └── datasources/
│   │       │       ├── datasource-prometheus.yaml
│   │       │       └── datasource-tempo.yaml
│   │       ├── init_data.json
│   │       ├── otel-collector/
│   │       │   └── collector-config.yaml
│   │       ├── prometheus/
│   │       │   └── prometheus.yml
│   │       ├── searxng-settings.yml
│   │       └── tempo/
│   │           └── tempo.yaml
│   └── setup.sh
├── docs/
│   ├── .cdn.cache.json
│   ├── changelog/
│   │   ├── 2023-09-09-plugin-system.mdx
│   │   ├── 2023-09-09-plugin-system.zh-CN.mdx
│   │   ├── 2023-11-14-gpt4-vision.mdx
│   │   ├── 2023-11-14-gpt4-vision.zh-CN.mdx
│   │   ├── 2023-11-19-tts-stt.mdx
│   │   ├── 2023-11-19-tts-stt.zh-CN.mdx
│   │   ├── 2023-12-22-dalle-3.mdx
│   │   ├── 2023-12-22-dalle-3.zh-CN.mdx
│   │   ├── 2024-02-08-sso-oauth.mdx
│   │   ├── 2024-02-08-sso-oauth.zh-CN.mdx
│   │   ├── 2024-02-14-ollama.mdx
│   │   ├── 2024-02-14-ollama.zh-CN.mdx
│   │   ├── 2024-06-19-lobe-chat-v1.mdx
│   │   ├── 2024-06-19-lobe-chat-v1.zh-CN.mdx
│   │   ├── 2024-07-19-gpt-4o-mini.mdx
│   │   ├── 2024-07-19-gpt-4o-mini.zh-CN.mdx
│   │   ├── 2024-08-02-lobe-chat-database-docker.mdx
│   │   ├── 2024-08-02-lobe-chat-database-docker.zh-CN.mdx
│   │   ├── 2024-08-21-file-upload-and-knowledge-base.mdx
│   │   ├── 2024-08-21-file-upload-and-knowledge-base.zh-CN.mdx
│   │   ├── 2024-09-13-openai-o1-models.mdx
│   │   ├── 2024-09-13-openai-o1-models.zh-CN.mdx
│   │   ├── 2024-09-20-artifacts.mdx
│   │   ├── 2024-09-20-artifacts.zh-CN.mdx
│   │   ├── 2024-10-27-pin-assistant.mdx
│   │   ├── 2024-10-27-pin-assistant.zh-CN.mdx
│   │   ├── 2024-11-06-share-text-json.mdx
│   │   ├── 2024-11-06-share-text-json.zh-CN.mdx
│   │   ├── 2024-11-25-november-providers.mdx
│   │   ├── 2024-11-25-november-providers.zh-CN.mdx
│   │   ├── 2024-11-27-forkable-chat.mdx
│   │   ├── 2024-11-27-forkable-chat.zh-CN.mdx
│   │   ├── 2025-01-03-user-profile.mdx
│   │   ├── 2025-01-03-user-profile.zh-CN.mdx
│   │   ├── 2025-01-22-new-ai-provider.mdx
│   │   ├── 2025-01-22-new-ai-provider.zh-CN.mdx
│   │   ├── 2025-02-02-deepseek-r1.mdx
│   │   ├── 2025-02-02-deepseek-r1.zh-CN.mdx
│   │   ├── 2025-03-02-new-models.mdx
│   │   ├── 2025-03-02-new-models.zh-CN.mdx
│   │   ├── 2025-04-06-exports.mdx
│   │   ├── 2025-04-06-exports.zh-CN.mdx
│   │   ├── 2025-05-08-desktop-app.mdx
│   │   ├── 2025-05-08-desktop-app.zh-CN.mdx
│   │   ├── 2025-06-08-claude-4.mdx
│   │   ├── 2025-06-08-claude-4.zh-CN.mdx
│   │   ├── 2025-07-08-mcp-market.mdx
│   │   ├── 2025-07-08-mcp-market.zh-CN.mdx
│   │   ├── 2025-08-08-image-generation.mdx
│   │   ├── 2025-08-08-image-generation.zh-CN.mdx
│   │   ├── 2025-09-08-gemini.mdx
│   │   ├── 2025-09-08-gemini.zh-CN.mdx
│   │   ├── 2025-10-08-python.mdx
│   │   ├── 2025-10-08-python.zh-CN.mdx
│   │   ├── 2025-11-08-comfy-ui.mdx
│   │   ├── 2025-11-08-comfy-ui.zh-CN.mdx
│   │   ├── 2025-12-20-mcp.mdx
│   │   ├── 2025-12-20-mcp.zh-CN.mdx
│   │   ├── 2026-01-27-v2.mdx
│   │   ├── 2026-01-27-v2.zh-CN.mdx
│   │   ├── 2026-02-08-runtime-auth.mdx
│   │   ├── 2026-02-08-runtime-auth.zh-CN.mdx
│   │   ├── 2026-03-16-search.mdx
│   │   ├── 2026-03-16-search.zh-CN.mdx
│   │   ├── 2026-03-23-media-memory.mdx
│   │   ├── 2026-03-23-media-memory.zh-CN.mdx
│   │   ├── 2026-03-30-agent-tasks.mdx
│   │   ├── 2026-03-30-agent-tasks.zh-CN.mdx
│   │   ├── index.json
│   │   └── schema.json
│   ├── development/
│   │   ├── basic/
│   │   │   ├── add-new-authentication-providers.mdx
│   │   │   ├── add-new-authentication-providers.zh-CN.mdx
│   │   │   ├── add-new-bot-platform.mdx
│   │   │   ├── add-new-bot-platform.zh-CN.mdx
│   │   │   ├── add-new-image-model.mdx
│   │   │   ├── add-new-image-model.zh-CN.mdx
│   │   │   ├── architecture.mdx
│   │   │   ├── architecture.zh-CN.mdx
│   │   │   ├── chat-api.mdx
│   │   │   ├── chat-api.zh-CN.mdx
│   │   │   ├── comfyui-development.mdx
│   │   │   ├── comfyui-development.zh-CN.mdx
│   │   │   ├── contributing-guidelines.mdx
│   │   │   ├── contributing-guidelines.zh-CN.mdx
│   │   │   ├── feature-development.mdx
│   │   │   ├── feature-development.zh-CN.mdx
│   │   │   ├── folder-structure.mdx
│   │   │   ├── folder-structure.zh-CN.mdx
│   │   │   ├── resources.mdx
│   │   │   ├── resources.zh-CN.mdx
│   │   │   ├── setup-development.mdx
│   │   │   ├── setup-development.zh-CN.mdx
│   │   │   ├── test.mdx
│   │   │   └── test.zh-CN.mdx
│   │   ├── database-schema.dbml
│   │   ├── internationalization/
│   │   │   ├── add-new-locale.mdx
│   │   │   ├── add-new-locale.zh-CN.mdx
│   │   │   ├── internationalization-implementation.mdx
│   │   │   └── internationalization-implementation.zh-CN.mdx
│   │   ├── others/
│   │   │   ├── lighthouse.mdx
│   │   │   └── lighthouse.zh-CN.mdx
│   │   ├── start.mdx
│   │   ├── start.zh-CN.mdx
│   │   ├── state-management/
│   │   │   ├── state-management-intro.mdx
│   │   │   ├── state-management-intro.zh-CN.mdx
│   │   │   ├── state-management-selectors.mdx
│   │   │   └── state-management-selectors.zh-CN.mdx
│   │   └── tests/
│   │       ├── integration-testing.mdx
│   │       └── integration-testing.zh-CN.mdx
│   ├── glossary.md
│   ├── glossary.zh-CN.md
│   ├── self-hosting/
│   │   ├── advanced/
│   │   │   ├── analytics.mdx
│   │   │   ├── analytics.zh-CN.mdx
│   │   │   ├── desktop.mdx
│   │   │   ├── desktop.zh-CN.mdx
│   │   │   ├── feature-flags.mdx
│   │   │   ├── feature-flags.zh-CN.mdx
│   │   │   ├── knowledge-base.mdx
│   │   │   ├── knowledge-base.zh-CN.mdx
│   │   │   ├── model-list.mdx
│   │   │   ├── model-list.zh-CN.mdx
│   │   │   ├── observability/
│   │   │   │   ├── grafana.mdx
│   │   │   │   ├── grafana.zh-CN.mdx
│   │   │   │   ├── langfuse.mdx
│   │   │   │   └── langfuse.zh-CN.mdx
│   │   │   ├── online-search.mdx
│   │   │   ├── online-search.zh-CN.mdx
│   │   │   ├── redis/
│   │   │   │   ├── upstash.mdx
│   │   │   │   └── upstash.zh-CN.mdx
│   │   │   ├── redis.mdx
│   │   │   ├── redis.zh-CN.mdx
│   │   │   ├── s3/
│   │   │   │   ├── cloudflare-r2.mdx
│   │   │   │   ├── cloudflare-r2.zh-CN.mdx
│   │   │   │   ├── rustfs.mdx
│   │   │   │   ├── rustfs.zh-CN.mdx
│   │   │   │   ├── tencent-cloud.mdx
│   │   │   │   └── tencent-cloud.zh-CN.mdx
│   │   │   ├── s3.mdx
│   │   │   ├── s3.zh-CN.mdx
│   │   │   ├── settings-url-share.mdx
│   │   │   ├── settings-url-share.zh-CN.mdx
│   │   │   ├── upstream-sync.mdx
│   │   │   └── upstream-sync.zh-CN.mdx
│   │   ├── auth/
│   │   │   ├── clerk.mdx
│   │   │   ├── clerk.zh-CN.mdx
│   │   │   ├── email.mdx
│   │   │   ├── email.zh-CN.mdx
│   │   │   ├── legacy.mdx
│   │   │   ├── legacy.zh-CN.mdx
│   │   │   ├── next-auth/
│   │   │   │   ├── auth0.mdx
│   │   │   │   ├── auth0.zh-CN.mdx
│   │   │   │   ├── authelia.mdx
│   │   │   │   ├── authelia.zh-CN.mdx
│   │   │   │   ├── authentik.mdx
│   │   │   │   ├── authentik.zh-CN.mdx
│   │   │   │   ├── casdoor.mdx
│   │   │   │   ├── casdoor.zh-CN.mdx
│   │   │   │   ├── cloudflare-zero-trust.mdx
│   │   │   │   ├── cloudflare-zero-trust.zh-CN.mdx
│   │   │   │   ├── github.mdx
│   │   │   │   ├── github.zh-CN.mdx
│   │   │   │   ├── google.mdx
│   │   │   │   ├── google.zh-CN.mdx
│   │   │   │   ├── keycloak.mdx
│   │   │   │   ├── keycloak.zh-CN.mdx
│   │   │   │   ├── logto.mdx
│   │   │   │   ├── logto.zh-CN.mdx
│   │   │   │   ├── microsoft-entra-id.mdx
│   │   │   │   ├── microsoft-entra-id.zh-CN.mdx
│   │   │   │   ├── okta.mdx
│   │   │   │   ├── okta.zh-CN.mdx
│   │   │   │   ├── wechat.mdx
│   │   │   │   ├── wechat.zh-CN.mdx
│   │   │   │   ├── zitadel.mdx
│   │   │   │   └── zitadel.zh-CN.mdx
│   │   │   └── providers/
│   │   │       ├── apple.mdx
│   │   │       ├── apple.zh-CN.mdx
│   │   │       ├── auth0.mdx
│   │   │       ├── auth0.zh-CN.mdx
│   │   │       ├── authelia.mdx
│   │   │       ├── authelia.zh-CN.mdx
│   │   │       ├── authentik.mdx
│   │   │       ├── authentik.zh-CN.mdx
│   │   │       ├── casdoor.mdx
│   │   │       ├── casdoor.zh-CN.mdx
│   │   │       ├── cloudflare-zero-trust.mdx
│   │   │       ├── cloudflare-zero-trust.zh-CN.mdx
│   │   │       ├── cognito.mdx
│   │   │       ├── cognito.zh-CN.mdx
│   │   │       ├── feishu.mdx
│   │   │       ├── feishu.zh-CN.mdx
│   │   │       ├── generic-oidc.mdx
│   │   │       ├── generic-oidc.zh-CN.mdx
│   │   │       ├── github.mdx
│   │   │       ├── github.zh-CN.mdx
│   │   │       ├── google.mdx
│   │   │       ├── google.zh-CN.mdx
│   │   │       ├── keycloak.mdx
│   │   │       ├── keycloak.zh-CN.mdx
│   │   │       ├── logto.mdx
│   │   │       ├── logto.zh-CN.mdx
│   │   │       ├── microsoft.mdx
│   │   │       ├── microsoft.zh-CN.mdx
│   │   │       ├── okta.mdx
│   │   │       ├── okta.zh-CN.mdx
│   │   │       ├── password.mdx
│   │   │       ├── password.zh-CN.mdx
│   │   │       ├── wechat.mdx
│   │   │       ├── wechat.zh-CN.mdx
│   │   │       ├── zitadel.mdx
│   │   │       └── zitadel.zh-CN.mdx
│   │   ├── auth.mdx
│   │   ├── auth.zh-CN.mdx
│   │   ├── environment-variables/
│   │   │   ├── analytics.mdx
│   │   │   ├── analytics.zh-CN.mdx
│   │   │   ├── auth.mdx
│   │   │   ├── auth.zh-CN.mdx
│   │   │   ├── basic.mdx
│   │   │   ├── basic.zh-CN.mdx
│   │   │   ├── model-provider.mdx
│   │   │   ├── model-provider.zh-CN.mdx
│   │   │   ├── redis.mdx
│   │   │   ├── redis.zh-CN.mdx
│   │   │   ├── s3.mdx
│   │   │   └── s3.zh-CN.mdx
│   │   ├── environment-variables.mdx
│   │   ├── environment-variables.zh-CN.mdx
│   │   ├── examples/
│   │   │   ├── azure-openai.mdx
│   │   │   ├── azure-openai.zh-CN.mdx
│   │   │   ├── ollama.mdx
│   │   │   └── ollama.zh-CN.mdx
│   │   ├── faq/
│   │   │   ├── no-v1-suffix.mdx
│   │   │   ├── no-v1-suffix.zh-CN.mdx
│   │   │   ├── proxy-with-unable-to-verify-leaf-signature.mdx
│   │   │   ├── proxy-with-unable-to-verify-leaf-signature.zh-CN.mdx
│   │   │   ├── vercel-ai-image-timeout.mdx
│   │   │   └── vercel-ai-image-timeout.zh-CN.mdx
│   │   ├── migration/
│   │   │   └── v2/
│   │   │       ├── auth/
│   │   │       │   ├── clerk-to-betterauth.mdx
│   │   │       │   ├── clerk-to-betterauth.zh-CN.mdx
│   │   │       │   ├── migration-internals.mdx
│   │   │       │   ├── migration-internals.zh-CN.mdx
│   │   │       │   ├── nextauth-to-betterauth.mdx
│   │   │       │   └── nextauth-to-betterauth.zh-CN.mdx
│   │   │       ├── breaking-changes.mdx
│   │   │       └── breaking-changes.zh-CN.mdx
│   │   ├── platform/
│   │   │   ├── docker-compose.mdx
│   │   │   ├── docker-compose.zh-CN.mdx
│   │   │   ├── docker.mdx
│   │   │   ├── docker.zh-CN.mdx
│   │   │   ├── dokploy.mdx
│   │   │   ├── dokploy.zh-CN.mdx
│   │   │   ├── repocloud.mdx
│   │   │   ├── repocloud.zh-CN.mdx
│   │   │   ├── sealos.mdx
│   │   │   ├── sealos.zh-CN.mdx
│   │   │   ├── vercel.mdx
│   │   │   ├── vercel.zh-CN.mdx
│   │   │   ├── zeabur.mdx
│   │   │   └── zeabur.zh-CN.mdx
│   │   ├── start.mdx
│   │   └── start.zh-CN.mdx
│   ├── usage/
│   │   ├── agent/
│   │   │   ├── agent-team.mdx
│   │   │   ├── agent-team.zh-CN.mdx
│   │   │   ├── artifacts.mdx
│   │   │   ├── artifacts.zh-CN.mdx
│   │   │   ├── chain-of-thought.mdx
│   │   │   ├── chain-of-thought.zh-CN.mdx
│   │   │   ├── gtd.mdx
│   │   │   ├── gtd.zh-CN.mdx
│   │   │   ├── notebook.mdx
│   │   │   ├── notebook.zh-CN.mdx
│   │   │   ├── sandbox.mdx
│   │   │   ├── sandbox.zh-CN.mdx
│   │   │   ├── scheduled-task.mdx
│   │   │   ├── scheduled-task.zh-CN.mdx
│   │   │   ├── share.mdx
│   │   │   ├── share.zh-CN.mdx
│   │   │   ├── topic.mdx
│   │   │   ├── topic.zh-CN.mdx
│   │   │   ├── translate.mdx
│   │   │   ├── translate.zh-CN.mdx
│   │   │   ├── tts-stt.mdx
│   │   │   ├── tts-stt.zh-CN.mdx
│   │   │   ├── web-search.mdx
│   │   │   └── web-search.zh-CN.mdx
│   │   ├── channels/
│   │   │   ├── discord.mdx
│   │   │   ├── discord.zh-CN.mdx
│   │   │   ├── feishu.mdx
│   │   │   ├── feishu.zh-CN.mdx
│   │   │   ├── lark.mdx
│   │   │   ├── lark.zh-CN.mdx
│   │   │   ├── overview.mdx
│   │   │   ├── overview.zh-CN.mdx
│   │   │   ├── qq.mdx
│   │   │   ├── qq.zh-CN.mdx
│   │   │   ├── slack.mdx
│   │   │   ├── slack.zh-CN.mdx
│   │   │   ├── telegram.mdx
│   │   │   ├── telegram.zh-CN.mdx
│   │   │   ├── wechat.mdx
│   │   │   └── wechat.zh-CN.mdx
│   │   ├── community/
│   │   │   ├── agent-market.mdx
│   │   │   ├── agent-market.zh-CN.mdx
│   │   │   ├── become-a-creator.mdx
│   │   │   ├── become-a-creator.zh-CN.mdx
│   │   │   ├── custom-mcp.mdx
│   │   │   ├── custom-mcp.zh-CN.mdx
│   │   │   ├── mcp-market.mdx
│   │   │   ├── mcp-market.zh-CN.mdx
│   │   │   ├── publish-agent.mdx
│   │   │   ├── publish-agent.zh-CN.mdx
│   │   │   ├── skill-management.mdx
│   │   │   ├── skill-management.zh-CN.mdx
│   │   │   └── skills-and-tools.mdx
│   │   ├── getting-started/
│   │   │   ├── agent.mdx
│   │   │   ├── agent.zh-CN.mdx
│   │   │   ├── chat.mdx
│   │   │   ├── file-upload.mdx
│   │   │   ├── get-lobehub.mdx
│   │   │   ├── get-lobehub.zh-CN.mdx
│   │   │   ├── image-generation.mdx
│   │   │   ├── image-generation.zh-CN.mdx
│   │   │   ├── lobe-ai.mdx
│   │   │   ├── lobe-ai.zh-CN.mdx
│   │   │   ├── memory.mdx
│   │   │   ├── memory.zh-CN.mdx
│   │   │   ├── page.mdx
│   │   │   ├── page.zh-CN.mdx
│   │   │   ├── resource.mdx
│   │   │   ├── resource.zh-CN.mdx
│   │   │   ├── vision.mdx
│   │   │   └── vision.zh-CN.mdx
│   │   ├── help.mdx
│   │   ├── help.zh-CN.mdx
│   │   ├── migrate-from-local-database.mdx
│   │   ├── migrate-from-local-database.zh-CN.mdx
│   │   ├── providers/
│   │   │   ├── ai21.mdx
│   │   │   ├── ai21.zh-CN.mdx
│   │   │   ├── ai302.mdx
│   │   │   ├── ai302.zh-CN.mdx
│   │   │   ├── ai360.mdx
│   │   │   ├── ai360.zh-CN.mdx
│   │   │   ├── aihubmix.mdx
│   │   │   ├── aihubmix.zh-CN.mdx
│   │   │   ├── anthropic.mdx
│   │   │   ├── anthropic.zh-CN.mdx
│   │   │   ├── azure.mdx
│   │   │   ├── azure.zh-CN.mdx
│   │   │   ├── azureai.mdx
│   │   │   ├── azureai.zh-CN.mdx
│   │   │   ├── baichuan.mdx
│   │   │   ├── baichuan.zh-CN.mdx
│   │   │   ├── bedrock.mdx
│   │   │   ├── bedrock.zh-CN.mdx
│   │   │   ├── bfl.mdx
│   │   │   ├── bfl.zh-CN.mdx
│   │   │   ├── cloudflare.mdx
│   │   │   ├── cloudflare.zh-CN.mdx
│   │   │   ├── comfyui.mdx
│   │   │   ├── comfyui.zh-CN.mdx
│   │   │   ├── deepseek.mdx
│   │   │   ├── deepseek.zh-CN.mdx
│   │   │   ├── fal.mdx
│   │   │   ├── fal.zh-CN.mdx
│   │   │   ├── fireworksai.mdx
│   │   │   ├── fireworksai.zh-CN.mdx
│   │   │   ├── giteeai.mdx
│   │   │   ├── giteeai.zh-CN.mdx
│   │   │   ├── github.mdx
│   │   │   ├── github.zh-CN.mdx
│   │   │   ├── google.mdx
│   │   │   ├── google.zh-CN.mdx
│   │   │   ├── groq.mdx
│   │   │   ├── groq.zh-CN.mdx
│   │   │   ├── hunyuan.mdx
│   │   │   ├── hunyuan.zh-CN.mdx
│   │   │   ├── infiniai.mdx
│   │   │   ├── infiniai.zh-CN.mdx
│   │   │   ├── internlm.mdx
│   │   │   ├── internlm.zh-CN.mdx
│   │   │   ├── jina.mdx
│   │   │   ├── jina.zh-CN.mdx
│   │   │   ├── lmstudio.mdx
│   │   │   ├── lmstudio.zh-CN.mdx
│   │   │   ├── minimax.mdx
│   │   │   ├── minimax.zh-CN.mdx
│   │   │   ├── mistral.mdx
│   │   │   ├── mistral.zh-CN.mdx
│   │   │   ├── modelscope.mdx
│   │   │   ├── modelscope.zh-CN.mdx
│   │   │   ├── moonshot.mdx
│   │   │   ├── moonshot.zh-CN.mdx
│   │   │   ├── novita.mdx
│   │   │   ├── novita.zh-CN.mdx
│   │   │   ├── nvidia.mdx
│   │   │   ├── nvidia.zh-CN.mdx
│   │   │   ├── ollama/
│   │   │   │   ├── gemma.mdx
│   │   │   │   ├── gemma.zh-CN.mdx
│   │   │   │   ├── qwen.mdx
│   │   │   │   └── qwen.zh-CN.mdx
│   │   │   ├── ollama.mdx
│   │   │   ├── ollama.zh-CN.mdx
│   │   │   ├── openai.mdx
│   │   │   ├── openai.zh-CN.mdx
│   │   │   ├── openrouter.mdx
│   │   │   ├── openrouter.zh-CN.mdx
│   │   │   ├── perplexity.mdx
│   │   │   ├── perplexity.zh-CN.mdx
│   │   │   ├── ppio.mdx
│   │   │   ├── ppio.zh-CN.mdx
│   │   │   ├── qiniu.mdx
│   │   │   ├── qiniu.zh-CN.mdx
│   │   │   ├── qwen.mdx
│   │   │   ├── qwen.zh-CN.mdx
│   │   │   ├── sambanova.mdx
│   │   │   ├── sambanova.zh-CN.mdx
│   │   │   ├── sensenova.mdx
│   │   │   ├── sensenova.zh-CN.mdx
│   │   │   ├── siliconcloud.mdx
│   │   │   ├── siliconcloud.zh-CN.mdx
│   │   │   ├── spark.mdx
│   │   │   ├── spark.zh-CN.mdx
│   │   │   ├── stepfun.mdx
│   │   │   ├── stepfun.zh-CN.mdx
│   │   │   ├── taichu.mdx
│   │   │   ├── taichu.zh-CN.mdx
│   │   │   ├── tencentcloud.mdx
│   │   │   ├── tencentcloud.zh-CN.mdx
│   │   │   ├── togetherai.mdx
│   │   │   ├── togetherai.zh-CN.mdx
│   │   │   ├── upstage.mdx
│   │   │   ├── upstage.zh-CN.mdx
│   │   │   ├── vercel-ai-gateway.mdx
│   │   │   ├── vercel-ai-gateway.zh-CN.mdx
│   │   │   ├── vertexai.mdx
│   │   │   ├── vertexai.zh-CN.mdx
│   │   │   ├── vllm.mdx
│   │   │   ├── vllm.zh-CN.mdx
│   │   │   ├── volcengine.mdx
│   │   │   ├── volcengine.zh-CN.mdx
│   │   │   ├── wenxin.mdx
│   │   │   ├── wenxin.zh-CN.mdx
│   │   │   ├── xai.mdx
│   │   │   ├── xai.zh-CN.mdx
│   │   │   ├── zeroone.mdx
│   │   │   ├── zeroone.zh-CN.mdx
│   │   │   ├── zhipu.mdx
│   │   │   └── zhipu.zh-CN.mdx
│   │   ├── providers.mdx
│   │   ├── providers.zh-CN.mdx
│   │   ├── start.mdx
│   │   ├── start.zh-CN.mdx
│   │   └── user-interface/
│   │       ├── appearance.mdx
│   │       ├── appearance.zh-CN.mdx
│   │       ├── command-menu.mdx
│   │       ├── command-menu.zh-CN.mdx
│   │       ├── shortcuts.mdx
│   │       ├── shortcuts.zh-CN.mdx
│   │       ├── stats.mdx
│   │       └── stats.zh-CN.mdx
│   └── wiki/
│       ├── HOME.md
│       └── HOME.zh-CN.md
├── drizzle.config.ts
├── e2e/
│   ├── .gitignore
│   ├── CLAUDE.md
│   ├── README.md
│   ├── cucumber.config.js
│   ├── docs/
│   │   ├── llm-mock.md
│   │   ├── local-setup.md
│   │   └── testing-tips.md
│   ├── package.json
│   ├── scripts/
│   │   └── setup.ts
│   ├── src/
│   │   ├── features/
│   │   │   ├── community/
│   │   │   │   ├── detail-pages.feature
│   │   │   │   ├── interactions.feature
│   │   │   │   └── smoke.feature
│   │   │   ├── home/
│   │   │   │   ├── sidebarAgent.feature
│   │   │   │   ├── sidebarGroup.feature
│   │   │   │   └── starter.feature
│   │   │   ├── journeys/
│   │   │   │   └── agent/
│   │   │   │       ├── agent-conversation-mgmt.feature
│   │   │   │       ├── agent-conversation.feature
│   │   │   │       └── agent-message-ops.feature
│   │   │   ├── page/
│   │   │   │   ├── README.md
│   │   │   │   ├── crud.feature
│   │   │   │   ├── editor-content.feature
│   │   │   │   └── editor-meta.feature
│   │   │   └── routes/
│   │   │       └── core-routes.feature
│   │   ├── mocks/
│   │   │   ├── community/
│   │   │   │   ├── data.ts
│   │   │   │   ├── handlers.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── types.ts
│   │   │   ├── index.ts
│   │   │   └── llm/
│   │   │       └── index.ts
│   │   ├── steps/
│   │   │   ├── agent/
│   │   │   │   ├── conversation-mgmt.steps.ts
│   │   │   │   ├── conversation.steps.ts
│   │   │   │   └── message-ops.steps.ts
│   │   │   ├── common/
│   │   │   │   ├── auth.steps.ts
│   │   │   │   └── navigation.steps.ts
│   │   │   ├── community/
│   │   │   │   ├── detail-pages.steps.ts
│   │   │   │   ├── interactions.steps.ts
│   │   │   │   └── smoke.steps.ts
│   │   │   ├── home/
│   │   │   │   ├── sidebarAgent.steps.ts
│   │   │   │   ├── sidebarGroup.steps.ts
│   │   │   │   └── starter.steps.ts
│   │   │   ├── hooks.ts
│   │   │   ├── page/
│   │   │   │   ├── editor-content.steps.ts
│   │   │   │   ├── editor-meta.steps.ts
│   │   │   │   └── page-crud.steps.ts
│   │   │   └── routes/
│   │   │       └── routes.steps.ts
│   │   └── support/
│   │       ├── seedTestUser.ts
│   │       ├── webServer.ts
│   │       └── world.ts
│   └── tsconfig.json
├── eslint.config.mjs
├── index.html
├── index.mobile.html
├── knip.ts
├── locales/
│   ├── ar/
│   │   ├── agent.json
│   │   ├── agentGroup.json
│   │   ├── auth.json
│   │   ├── authError.json
│   │   ├── changelog.json
│   │   ├── chat.json
│   │   ├── color.json
│   │   ├── common.json
│   │   ├── components.json
│   │   ├── desktop-onboarding.json
│   │   ├── discover.json
│   │   ├── editor.json
│   │   ├── electron.json
│   │   ├── error.json
│   │   ├── eval.json
│   │   ├── file.json
│   │   ├── home.json
│   │   ├── hotkey.json
│   │   ├── image.json
│   │   ├── knowledgeBase.json
│   │   ├── labs.json
│   │   ├── marketAuth.json
│   │   ├── memory.json
│   │   ├── metadata.json
│   │   ├── migration.json
│   │   ├── modelProvider.json
│   │   ├── models.json
│   │   ├── notification.json
│   │   ├── oauth.json
│   │   ├── onboarding.json
│   │   ├── plugin.json
│   │   ├── portal.json
│   │   ├── providers.json
│   │   ├── ragEval.json
│   │   ├── setting.json
│   │   ├── spend.json
│   │   ├── subscription.json
│   │   ├── suggestQuestions.json
│   │   ├── thread.json
│   │   ├── tool.json
│   │   ├── topic.json
│   │   ├── ui.json
│   │   ├── video.json
│   │   └── welcome.json
│   ├── bg-BG/
│   │   ├── agent.json
│   │   ├── agentGroup.json
│   │   ├── auth.json
│   │   ├── authError.json
│   │   ├── changelog.json
│   │   ├── chat.json
│   │   ├── color.json
│   │   ├── common.json
│   │   ├── components.json
│   │   ├── desktop-onboarding.json
│   │   ├── discover.json
│   │   ├── editor.json
│   │   ├── electron.json
│   │   ├── error.json
│   │   ├── eval.json
│   │   ├── file.json
│   │   ├── home.json
│   │   ├── hotkey.json
│   │   ├── image.json
│   │   ├── knowledgeBase.json
│   │   ├── labs.json
│   │   ├── marketAuth.json
│   │   ├── memory.json
│   │   ├── metadata.json
│   │   ├── migration.json
│   │   ├── modelProvider.json
│   │   ├── models.json
│   │   ├── notification.json
│   │   ├── oauth.json
│   │   ├── onboarding.json
│   │   ├── plugin.json
│   │   ├── portal.json
│   │   ├── providers.json
│   │   ├── ragEval.json
│   │   ├── setting.json
│   │   ├── spend.json
│   │   ├── subscription.json
│   │   ├── suggestQuestions.json
│   │   ├── thread.json
│   │   ├── tool.json
│   │   ├── topic.json
│   │   ├── ui.json
│   │   ├── video.json
│   │   └── welcome.json
│   ├── de-DE/
│   │   ├── agent.json
│   │   ├── agentGroup.json
│   │   ├── auth.json
│   │   ├── authError.json
│   │   ├── changelog.json
│   │   ├── chat.json
│   │   ├── color.json
│   │   ├── common.json
│   │   ├── components.json
│   │   ├── desktop-onboarding.json
│   │   ├── discover.json
│   │   ├── editor.json
│   │   ├── electron.json
│   │   ├── error.json
│   │   ├── eval.json
│   │   ├── file.json
│   │   ├── home.json
│   │   ├── hotkey.json
│   │   ├── image.json
│   │   ├── knowledgeBase.json
│   │   ├── labs.json
│   │   ├── marketAuth.json
│   │   ├── memory.json
│   │   ├── metadata.json
│   │   ├── migration.json
│   │   ├── modelProvider.json
│   │   ├── models.json
│   │   ├── notification.json
│   │   ├── oauth.json
│   │   ├── onboarding.json
│   │   ├── plugin.json
│   │   ├── portal.json
│   │   ├── providers.json
│   │   ├── ragEval.json
│   │   ├── setting.json
│   │   ├── spend.json
│   │   ├── subscription.json
│   │   ├── suggestQuestions.json
│   │   ├── thread.json
│   │   ├── tool.json
│   │   ├── topic.json
│   │   ├── ui.json
│   │   ├── video.json
│   │   └── welcome.json
│   ├── en-US/
│   │   ├── agent.json
│   │   ├── agentGroup.json
│   │   ├── auth.json
│   │   ├── authError.json
│   │   ├── changelog.json
│   │   ├── chat.json
│   │   ├── color.json
│   │   ├── common.json
│   │   ├── components.json
│   │   ├── desktop-onboarding.json
│   │   ├── discover.json
│   │   ├── editor.json
│   │   ├── electron.json
│   │   ├── error.json
│   │   ├── eval.json
│   │   ├── file.json
│   │   ├── home.json
│   │   ├── hotkey.json
│   │   ├── image.json
│   │   ├── knowledgeBase.json
│   │   ├── labs.json
│   │   ├── marketAuth.json
│   │   ├── memory.json
│   │   ├── metadata.json
│   │   ├── migration.json
│   │   ├── modelProvider.json
│   │   ├── models.json
│   │   ├── notification.json
│   │   ├── oauth.json
│   │   ├── onboarding.json
│   │   ├── plugin.json
│   │   ├── portal.json
│   │   ├── providers.json
│   │   ├── ragEval.json
│   │   ├── setting.json
│   │   ├── spend.json
│   │   ├── subscription.json
│   │   ├── suggestQuestions.json
│   │   ├── thread.json
│   │   ├── tool.json
│   │   ├── topic.json
│   │   ├── ui.json
│   │   ├── video.json
│   │   └── welcome.json
│   ├── es-ES/
│   │   ├── agent.json
│   │   ├── agentGroup.json
│   │   ├── auth.json
│   │   ├── authError.json
│   │   ├── changelog.json
│   │   ├── chat.json
│   │   ├── color.json
│   │   ├── common.json
│   │   ├── components.json
│   │   ├── desktop-onboarding.json
│   │   ├── discover.json
│   │   ├── editor.json
│   │   ├── electron.json
│   │   ├── error.json
│   │   ├── eval.json
│   │   ├── file.json
│   │   ├── home.json
│   │   ├── hotkey.json
│   │   ├── image.json
│   │   ├── knowledgeBase.json
│   │   ├── labs.json
│   │   ├── marketAuth.json
│   │   ├── memory.json
│   │   ├── metadata.json
│   │   ├── migration.json
│   │   ├── modelProvider.json
│   │   ├── models.json
│   │   ├── notification.json
│   │   ├── oauth.json
│   │   ├── onboarding.json
│   │   ├── plugin.json
│   │   ├── portal.json
│   │   ├── providers.json
│   │   ├── ragEval.json
│   │   ├── setting.json
│   │   ├── spend.json
│   │   ├── subscription.json
│   │   ├── suggestQuestions.json
│   │   ├── thread.json
│   │   ├── tool.json
│   │   ├── topic.json
│   │   ├── ui.json
│   │   ├── video.json
│   │   └── welcome.json
│   ├── fa-IR/
│   │   ├── agent.json
│   │   ├── agentGroup.json
│   │   ├── auth.json
│   │   ├── authError.json
│   │   ├── changelog.json
│   │   ├── chat.json
│   │   ├── color.json
│   │   ├── common.json
│   │   ├── components.json
│   │   ├── desktop-onboarding.json
│   │   ├── discover.json
│   │   ├── editor.json
│   │   ├── electron.json
│   │   ├── error.json
│   │   ├── eval.json
│   │   ├── file.json
│   │   ├── home.json
│   │   ├── hotkey.json
│   │   ├── image.json
│   │   ├── knowledgeBase.json
│   │   ├── labs.json
│   │   ├── marketAuth.json
│   │   ├── memory.json
│   │   ├── metadata.json
│   │   ├── migration.json
│   │   ├── modelProvider.json
│   │   ├── models.json
│   │   ├── notification.json
│   │   ├── oauth.json
│   │   ├── onboarding.json
│   │   ├── plugin.json
│   │   ├── portal.json
│   │   ├── providers.json
│   │   ├── ragEval.json
│   │   ├── setting.json
│   │   ├── spend.json
│   │   ├── subscription.json
│   │   ├── suggestQuestions.json
│   │   ├── thread.json
│   │   ├── tool.json
│   │   ├── topic.json
│   │   ├── ui.json
│   │   ├── video.json
│   │   └── welcome.json
│   ├── fr-FR/
│   │   ├── agent.json
│   │   ├── agentGroup.json
│   │   ├── auth.json
│   │   ├── authError.json
│   │   ├── changelog.json
│   │   ├── chat.json
│   │   ├── color.json
│   │   ├── common.json
│   │   ├── components.json
│   │   ├── desktop-onboarding.json
│   │   ├── discover.json
│   │   ├── editor.json
│   │   ├── electron.json
│   │   ├── error.json
│   │   ├── eval.json
│   │   ├── file.json
│   │   ├── home.json
│   │   ├── hotkey.json
│   │   ├── image.json
│   │   ├── knowledgeBase.json
│   │   ├── labs.json
│   │   ├── marketAuth.json
│   │   ├── memory.json
│   │   ├── metadata.json
│   │   ├── migration.json
│   │   ├── modelProvider.json
│   │   ├── models.json
│   │   ├── notification.json
│   │   ├── oauth.json
│   │   ├── onboarding.json
│   │   ├── plugin.json
│   │   ├── portal.json
│   │   ├── providers.json
│   │   ├── ragEval.json
│   │   ├── setting.json
│   │   ├── spend.json
│   │   ├── subscription.json
│   │   ├── suggestQuestions.json
│   │   ├── thread.json
│   │   ├── tool.json
│   │   ├── topic.json
│   │   ├── ui.json
│   │   ├── video.json
│   │   └── welcome.json
│   ├── it-IT/
│   │   ├── agent.json
│   │   ├── agentGroup.json
│   │   ├── auth.json
│   │   ├── authError.json
│   │   ├── changelog.json
│   │   ├── chat.json
│   │   ├── color.json
│   │   ├── common.json
│   │   ├── components.json
│   │   ├── desktop-onboarding.json
│   │   ├── discover.json
│   │   ├── editor.json
│   │   ├── electron.json
│   │   ├── error.json
│   │   ├── eval.json
│   │   ├── file.json
│   │   ├── home.json
│   │   ├── hotkey.json
│   │   ├── image.json
│   │   ├── knowledgeBase.json
│   │   ├── labs.json
│   │   ├── marketAuth.json
│   │   ├── memory.json
│   │   ├── metadata.json
│   │   ├── migration.json
│   │   ├── modelProvider.json
│   │   ├── models.json
│   │   ├── notification.json
│   │   ├── oauth.json
│   │   ├── onboarding.json
│   │   ├── plugin.json
│   │   ├── portal.json
│   │   ├── providers.json
│   │   ├── ragEval.json
│   │   ├── setting.json
│   │   ├── spend.json
│   │   ├── subscription.json
│   │   ├── suggestQuestions.json
│   │   ├── thread.json
│   │   ├── tool.json
│   │   ├── topic.json
│   │   ├── ui.json
│   │   ├── video.json
│   │   └── welcome.json
│   ├── ja-JP/
│   │   ├── agent.json
│   │   ├── agentGroup.json
│   │   ├── auth.json
│   │   ├── authError.json
│   │   ├── changelog.json
│   │   ├── chat.json
│   │   ├── color.json
│   │   ├── common.json
│   │   ├── components.json
│   │   ├── desktop-onboarding.json
│   │   ├── discover.json
│   │   ├── editor.json
│   │   ├── electron.json
│   │   ├── error.json
│   │   ├── eval.json
│   │   ├── file.json
│   │   ├── home.json
│   │   ├── hotkey.json
│   │   ├── image.json
│   │   ├── knowledgeBase.json
│   │   ├── labs.json
│   │   ├── marketAuth.json
│   │   ├── memory.json
│   │   ├── metadata.json
│   │   ├── migration.json
│   │   ├── modelProvider.json
│   │   ├── models.json
│   │   ├── notification.json
│   │   ├── oauth.json
│   │   ├── onboarding.json
│   │   ├── plugin.json
│   │   ├── portal.json
│   │   ├── providers.json
│   │   ├── ragEval.json
│   │   ├── setting.json
│   │   ├── spend.json
│   │   ├── subscription.json
│   │   ├── suggestQuestions.json
│   │   ├── thread.json
│   │   ├── tool.json
│   │   ├── topic.json
│   │   ├── ui.json
│   │   ├── video.json
│   │   └── welcome.json
│   ├── ko-KR/
│   │   ├── agent.json
│   │   ├── agentGroup.json
│   │   ├── auth.json
│   │   ├── authError.json
│   │   ├── changelog.json
│   │   ├── chat.json
│   │   ├── color.json
│   │   ├── common.json
│   │   ├── components.json
│   │   ├── desktop-onboarding.json
│   │   ├── discover.json
│   │   ├── editor.json
│   │   ├── electron.json
│   │   ├── error.json
│   │   ├── eval.json
│   │   ├── file.json
│   │   ├── home.json
│   │   ├── hotkey.json
│   │   ├── image.json
│   │   ├── knowledgeBase.json
│   │   ├── labs.json
│   │   ├── marketAuth.json
│   │   ├── memory.json
│   │   ├── metadata.json
│   │   ├── migration.json
│   │   ├── modelProvider.json
│   │   ├── models.json
│   │   ├── notification.json
│   │   ├── oauth.json
│   │   ├── onboarding.json
│   │   ├── plugin.json
│   │   ├── portal.json
│   │   ├── providers.json
│   │   ├── ragEval.json
│   │   ├── setting.json
│   │   ├── spend.json
│   │   ├── subscription.json
│   │   ├── suggestQuestions.json
│   │   ├── thread.json
│   │   ├── tool.json
│   │   ├── topic.json
│   │   ├── ui.json
│   │   ├── video.json
│   │   └── welcome.json
│   ├── nl-NL/
│   │   ├── agent.json
│   │   ├── agentGroup.json
│   │   ├── auth.json
│   │   ├── authError.json
│   │   ├── changelog.json
│   │   ├── chat.json
│   │   ├── color.json
│   │   ├── common.json
│   │   ├── components.json
│   │   ├── desktop-onboarding.json
│   │   ├── discover.json
│   │   ├── editor.json
│   │   ├── electron.json
│   │   ├── error.json
│   │   ├── eval.json
│   │   ├── file.json
│   │   ├── home.json
│   │   ├── hotkey.json
│   │   ├── image.json
│   │   ├── knowledgeBase.json
│   │   ├── labs.json
│   │   ├── marketAuth.json
│   │   ├── memory.json
│   │   ├── metadata.json
│   │   ├── migration.json
│   │   ├── modelProvider.json
│   │   ├── models.json
│   │   ├── notification.json
│   │   ├── oauth.json
│   │   ├── onboarding.json
│   │   ├── plugin.json
│   │   ├── portal.json
│   │   ├── providers.json
│   │   ├── ragEval.json
│   │   ├── setting.json
│   │   ├── spend.json
│   │   ├── subscription.json
│   │   ├── suggestQuestions.json
│   │   ├── thread.json
│   │   ├── tool.json
│   │   ├── topic.json
│   │   ├── ui.json
│   │   ├── video.json
│   │   └── welcome.json
│   ├── pl-PL/
│   │   ├── agent.json
│   │   ├── agentGroup.json
│   │   ├── auth.json
│   │   ├── authError.json
│   │   ├── changelog.json
│   │   ├── chat.json
│   │   ├── color.json
│   │   ├── common.json
│   │   ├── components.json
│   │   ├── desktop-onboarding.json
│   │   ├── discover.json
│   │   ├── editor.json
│   │   ├── electron.json
│   │   ├── error.json
│   │   ├── eval.json
│   │   ├── file.json
│   │   ├── home.json
│   │   ├── hotkey.json
│   │   ├── image.json
│   │   ├── knowledgeBase.json
│   │   ├── labs.json
│   │   ├── marketAuth.json
│   │   ├── memory.json
│   │   ├── metadata.json
│   │   ├── migration.json
│   │   ├── modelProvider.json
│   │   ├── models.json
│   │   ├── notification.json
│   │   ├── oauth.json
│   │   ├── onboarding.json
│   │   ├── plugin.json
│   │   ├── portal.json
│   │   ├── providers.json
│   │   ├── ragEval.json
│   │   ├── setting.json
│   │   ├── spend.json
│   │   ├── subscription.json
│   │   ├── suggestQuestions.json
│   │   ├── thread.json
│   │   ├── tool.json
│   │   ├── topic.json
│   │   ├── ui.json
│   │   ├── video.json
│   │   └── welcome.json
│   ├── pt-BR/
│   │   ├── agent.json
│   │   ├── agentGroup.json
│   │   ├── auth.json
│   │   ├── authError.json
│   │   ├── changelog.json
│   │   ├── chat.json
│   │   ├── color.json
│   │   ├── common.json
│   │   ├── components.json
│   │   ├── desktop-onboarding.json
│   │   ├── discover.json
│   │   ├── editor.json
│   │   ├── electron.json
│   │   ├── error.json
│   │   ├── eval.json
│   │   ├── file.json
│   │   ├── home.json
│   │   ├── hotkey.json
│   │   ├── image.json
│   │   ├── knowledgeBase.json
│   │   ├── labs.json
│   │   ├── marketAuth.json
│   │   ├── memory.json
│   │   ├── metadata.json
│   │   ├── migration.json
│   │   ├── modelProvider.json
│   │   ├── models.json
│   │   ├── notification.json
│   │   ├── oauth.json
│   │   ├── onboarding.json
│   │   ├── plugin.json
│   │   ├── portal.json
│   │   ├── providers.json
│   │   ├── ragEval.json
│   │   ├── setting.json
│   │   ├── spend.json
│   │   ├── subscription.json
│   │   ├── suggestQuestions.json
│   │   ├── thread.json
│   │   ├── tool.json
│   │   ├── topic.json
│   │   ├── ui.json
│   │   ├── video.json
│   │   └── welcome.json
│   ├── ru-RU/
│   │   ├── agent.json
│   │   ├── agentGroup.json
│   │   ├── auth.json
│   │   ├── authError.json
│   │   ├── changelog.json
│   │   ├── chat.json
│   │   ├── color.json
│   │   ├── common.json
│   │   ├── components.json
│   │   ├── desktop-onboarding.json
│   │   ├── discover.json
│   │   ├── editor.json
│   │   ├── electron.json
│   │   ├── error.json
│   │   ├── eval.json
│   │   ├── file.json
│   │   ├── home.json
│   │   ├── hotkey.json
│   │   ├── image.json
│   │   ├── knowledgeBase.json
│   │   ├── labs.json
│   │   ├── marketAuth.json
│   │   ├── memory.json
│   │   ├── metadata.json
│   │   ├── migration.json
│   │   ├── modelProvider.json
│   │   ├── models.json
│   │   ├── notification.json
│   │   ├── oauth.json
│   │   ├── onboarding.json
│   │   ├── plugin.json
│   │   ├── portal.json
│   │   ├── providers.json
│   │   ├── ragEval.json
│   │   ├── setting.json
│   │   ├── spend.json
│   │   ├── subscription.json
│   │   ├── suggestQuestions.json
│   │   ├── thread.json
│   │   ├── tool.json
│   │   ├── topic.json
│   │   ├── ui.json
│   │   ├── video.json
│   │   └── welcome.json
│   ├── tr-TR/
│   │   ├── agent.json
│   │   ├── agentGroup.json
│   │   ├── auth.json
│   │   ├── authError.json
│   │   ├── changelog.json
│   │   ├── chat.json
│   │   ├── color.json
│   │   ├── common.json
│   │   ├── components.json
│   │   ├── desktop-onboarding.json
│   │   ├── discover.json
│   │   ├── editor.json
│   │   ├── electron.json
│   │   ├── error.json
│   │   ├── eval.json
│   │   ├── file.json
│   │   ├── home.json
│   │   ├── hotkey.json
│   │   ├── image.json
│   │   ├── knowledgeBase.json
│   │   ├── labs.json
│   │   ├── marketAuth.json
│   │   ├── memory.json
│   │   ├── metadata.json
│   │   ├── migration.json
│   │   ├── modelProvider.json
│   │   ├── models.json
│   │   ├── notification.json
│   │   ├── oauth.json
│   │   ├── onboarding.json
│   │   ├── plugin.json
│   │   ├── portal.json
│   │   ├── providers.json
│   │   ├── ragEval.json
│   │   ├── setting.json
│   │   ├── spend.json
│   │   ├── subscription.json
│   │   ├── suggestQuestions.json
│   │   ├── thread.json
│   │   ├── tool.json
│   │   ├── topic.json
│   │   ├── ui.json
│   │   ├── video.json
│   │   └── welcome.json
│   ├── vi-VN/
│   │   ├── agent.json
│   │   ├── agentGroup.json
│   │   ├── auth.json
│   │   ├── authError.json
│   │   ├── changelog.json
│   │   ├── chat.json
│   │   ├── color.json
│   │   ├── common.json
│   │   ├── components.json
│   │   ├── desktop-onboarding.json
│   │   ├── discover.json
│   │   ├── editor.json
│   │   ├── electron.json
│   │   ├── error.json
│   │   ├── eval.json
│   │   ├── file.json
│   │   ├── home.json
│   │   ├── hotkey.json
│   │   ├── image.json
│   │   ├── knowledgeBase.json
│   │   ├── labs.json
│   │   ├── marketAuth.json
│   │   ├── memory.json
│   │   ├── metadata.json
│   │   ├── migration.json
│   │   ├── modelProvider.json
│   │   ├── models.json
│   │   ├── notification.json
│   │   ├── oauth.json
│   │   ├── onboarding.json
│   │   ├── plugin.json
│   │   ├── portal.json
│   │   ├── providers.json
│   │   ├── ragEval.json
│   │   ├── setting.json
│   │   ├── spend.json
│   │   ├── subscription.json
│   │   ├── suggestQuestions.json
│   │   ├── thread.json
│   │   ├── tool.json
│   │   ├── topic.json
│   │   ├── ui.json
│   │   ├── video.json
│   │   └── welcome.json
│   ├── zh-CN/
│   │   ├── agent.json
│   │   ├── agentGroup.json
│   │   ├── auth.json
│   │   ├── authError.json
│   │   ├── changelog.json
│   │   ├── chat.json
│   │   ├── color.json
│   │   ├── common.json
│   │   ├── components.json
│   │   ├── desktop-onboarding.json
│   │   ├── discover.json
│   │   ├── editor.json
│   │   ├── electron.json
│   │   ├── error.json
│   │   ├── eval.json
│   │   ├── file.json
│   │   ├── home.json
│   │   ├── hotkey.json
│   │   ├── image.json
│   │   ├── knowledgeBase.json
│   │   ├── labs.json
│   │   ├── marketAuth.json
│   │   ├── memory.json
│   │   ├── metadata.json
│   │   ├── migration.json
│   │   ├── modelProvider.json
│   │   ├── models.json
│   │   ├── notification.json
│   │   ├── oauth.json
│   │   ├── onboarding.json
│   │   ├── plugin.json
│   │   ├── portal.json
│   │   ├── providers.json
│   │   ├── ragEval.json
│   │   ├── setting.json
│   │   ├── spend.json
│   │   ├── subscription.json
│   │   ├── suggestQuestions.json
│   │   ├── thread.json
│   │   ├── tool.json
│   │   ├── topic.json
│   │   ├── ui.json
│   │   ├── video.json
│   │   └── welcome.json
│   └── zh-TW/
│       ├── agent.json
│       ├── agentGroup.json
│       ├── auth.json
│       ├── authError.json
│       ├── changelog.json
│       ├── chat.json
│       ├── color.json
│       ├── common.json
│       ├── components.json
│       ├── desktop-onboarding.json
│       ├── discover.json
│       ├── editor.json
│       ├── electron.json
│       ├── error.json
│       ├── eval.json
│       ├── file.json
│       ├── home.json
│       ├── hotkey.json
│       ├── image.json
│       ├── knowledgeBase.json
│       ├── labs.json
│       ├── marketAuth.json
│       ├── memory.json
│       ├── metadata.json
│       ├── migration.json
│       ├── modelProvider.json
│       ├── models.json
│       ├── notification.json
│       ├── oauth.json
│       ├── onboarding.json
│       ├── plugin.json
│       ├── portal.json
│       ├── providers.json
│       ├── ragEval.json
│       ├── setting.json
│       ├── spend.json
│       ├── subscription.json
│       ├── suggestQuestions.json
│       ├── thread.json
│       ├── tool.json
│       ├── topic.json
│       ├── ui.json
│       ├── video.json
│       └── welcome.json
├── netlify.toml
├── next.config.ts
├── package.json
├── packages/
│   ├── agent-manager-runtime/
│   │   ├── package.json
│   │   └── src/
│   │       ├── AgentManagerRuntime.ts
│   │       ├── __tests__/
│   │       │   └── AgentManagerRuntime.test.ts
│   │       ├── index.ts
│   │       └── types.ts
│   ├── agent-runtime/
│   │   ├── examples/
│   │   │   └── tools-calling.ts
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── agents/
│   │   │   │   ├── GeneralChatAgent.ts
│   │   │   │   ├── __tests__/
│   │   │   │   │   └── GeneralChatAgent.test.ts
│   │   │   │   └── index.ts
│   │   │   ├── audit/
│   │   │   │   ├── __tests__/
│   │   │   │   │   └── createSecurityBlacklistAudit.test.ts
│   │   │   │   ├── createSecurityBlacklistAudit.ts
│   │   │   │   ├── defaultSecurityBlacklist.ts
│   │   │   │   ├── globalAudit.ts
│   │   │   │   └── index.ts
│   │   │   ├── core/
│   │   │   │   ├── InterventionChecker.ts
│   │   │   │   ├── UsageCounter.ts
│   │   │   │   ├── __tests__/
│   │   │   │   │   ├── InterventionChecker.test.ts
│   │   │   │   │   ├── UsageCounter.test.ts
│   │   │   │   │   └── runtime.test.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── runtime.ts
│   │   │   ├── groupOrchestration/
│   │   │   │   ├── GroupOrchestrationRuntime.ts
│   │   │   │   ├── GroupOrchestrationSupervisor.ts
│   │   │   │   ├── __tests__/
│   │   │   │   │   └── GroupOrchestrationSupervisor.test.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── types.ts
│   │   │   ├── index.ts
│   │   │   ├── types/
│   │   │   │   ├── event.ts
│   │   │   │   ├── generalAgent.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── instruction.ts
│   │   │   │   ├── runtime.ts
│   │   │   │   ├── state.ts
│   │   │   │   └── usage.ts
│   │   │   └── utils/
│   │   │       ├── index.ts
│   │   │       ├── messageSelectors.test.ts
│   │   │       ├── messageSelectors.ts
│   │   │       ├── stepContextComputer.test.ts
│   │   │       ├── stepContextComputer.ts
│   │   │       ├── tokenCounter.test.ts
│   │   │       └── tokenCounter.ts
│   │   └── vitest.config.mts
│   ├── agent-templates/
│   │   ├── package.json
│   │   └── src/
│   │       ├── index.ts
│   │       ├── template.ts
│   │       ├── templates/
│   │       │   ├── claw/
│   │       │   │   ├── AGENTS.md
│   │       │   │   ├── BOOTSTRAP.md
│   │       │   │   ├── IDENTITY.md
│   │       │   │   ├── SOUL.md
│   │       │   │   ├── agent.ts
│   │       │   │   ├── bootstrap.ts
│   │       │   │   ├── identity.ts
│   │       │   │   ├── index.ts
│   │       │   │   ├── raw.d.ts
│   │       │   │   └── soul.ts
│   │       │   └── index.ts
│   │       └── types.ts
│   ├── agent-tracing/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── cli/
│   │   │   │   ├── index.ts
│   │   │   │   ├── inspect.ts
│   │   │   │   ├── list.ts
│   │   │   │   └── partial.ts
│   │   │   ├── index.ts
│   │   │   ├── recorder/
│   │   │   │   └── index.ts
│   │   │   ├── store/
│   │   │   │   ├── file-store.ts
│   │   │   │   └── types.ts
│   │   │   ├── types.ts
│   │   │   ├── utils/
│   │   │   │   ├── reconstruct.test.ts
│   │   │   │   └── reconstruct.ts
│   │   │   └── viewer/
│   │   │       └── index.ts
│   │   └── tsconfig.json
│   ├── builtin-agent-onboarding/
│   │   ├── package.json
│   │   └── src/
│   │       ├── client/
│   │       │   ├── QuestionRenderer.tsx
│   │       │   └── index.ts
│   │       ├── index.ts
│   │       ├── systemRole.ts
│   │       └── toolSystemRole.ts
│   ├── builtin-agents/
│   │   ├── package.json
│   │   └── src/
│   │       ├── agents/
│   │       │   ├── agent-builder/
│   │       │   │   ├── index.ts
│   │       │   │   └── systemRole.ts
│   │       │   ├── group-agent-builder/
│   │       │   │   ├── index.ts
│   │       │   │   └── systemRole.ts
│   │       │   ├── group-supervisor/
│   │       │   │   ├── index.ts
│   │       │   │   ├── systemRole.ts
│   │       │   │   └── type.ts
│   │       │   ├── inbox/
│   │       │   │   ├── index.ts
│   │       │   │   └── systemRole.ts
│   │       │   ├── page-agent/
│   │       │   │   ├── README.md
│   │       │   │   ├── index.ts
│   │       │   │   └── systemRole.ts
│   │       │   └── web-onboarding/
│   │       │       └── index.ts
│   │       ├── index.ts
│   │       └── types.ts
│   ├── builtin-skills/
│   │   ├── package.json
│   │   └── src/
│   │       ├── agent-browser/
│   │       │   ├── content.ts
│   │       │   └── index.ts
│   │       ├── artifacts/
│   │       │   ├── content.ts
│   │       │   └── index.ts
│   │       ├── find-skills/
│   │       │   ├── content.ts
│   │       │   └── index.ts
│   │       ├── index.ts
│   │       ├── lobehub/
│   │       │   ├── content.ts
│   │       │   ├── helpers.ts
│   │       │   ├── index.ts
│   │       │   └── references/
│   │       │       ├── agent.ts
│   │       │       ├── bot.ts
│   │       │       ├── config.ts
│   │       │       ├── doc.ts
│   │       │       ├── eval.ts
│   │       │       ├── file.ts
│   │       │       ├── generate.ts
│   │       │       ├── kb.ts
│   │       │       ├── memory.ts
│   │       │       ├── message.ts
│   │       │       ├── model.ts
│   │       │       ├── plugin.ts
│   │       │       ├── provider.ts
│   │       │       ├── search.ts
│   │       │       ├── skill.ts
│   │       │       └── topic.ts
│   │       ├── raw.d.ts
│   │       └── task/
│   │           ├── SKILL.md
│   │           ├── index.ts
│   │           └── references/
│   │               └── commands.md
│   ├── builtin-tool-activator/
│   │   ├── package.json
│   │   └── src/
│   │       ├── ExecutionRuntime/
│   │       │   └── index.ts
│   │       ├── client/
│   │       │   ├── Inspector/
│   │       │   │   ├── ActivateSkill/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ActivateTools/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Render/
│   │       │   │   ├── ActivateSkill/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   └── index.ts
│   │       ├── executor/
│   │       │   └── index.ts
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       ├── systemRole.ts
│   │       └── types.ts
│   ├── builtin-tool-agent-builder/
│   │   ├── package.json
│   │   └── src/
│   │       ├── client/
│   │       │   ├── Inspector/
│   │       │   │   ├── GetAvailableModels/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── InstallPlugin/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── SearchMarketTools/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── UpdateConfig/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── UpdatePrompt/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Intervention/
│   │       │   │   ├── InstallPlugin.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Render/
│   │       │   │   ├── GetAvailableModels.tsx
│   │       │   │   ├── InstallPlugin.tsx
│   │       │   │   ├── SearchMarketTools.tsx
│   │       │   │   ├── UpdateConfig.tsx
│   │       │   │   ├── UpdatePrompt.tsx
│   │       │   │   ├── components/
│   │       │   │   │   ├── ConfigCard.tsx
│   │       │   │   │   └── ConfigDiffView.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Streaming/
│   │       │   │   ├── UpdatePrompt/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   └── index.ts
│   │       ├── executor.ts
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       ├── systemRole.ts
│   │       └── types.ts
│   ├── builtin-tool-agent-documents/
│   │   ├── package.json
│   │   └── src/
│   │       ├── ExecutionRuntime/
│   │       │   └── index.ts
│   │       ├── client/
│   │       │   ├── Inspector/
│   │       │   │   ├── AgentDocumentsInspector/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Render/
│   │       │   │   └── index.ts
│   │       │   └── index.ts
│   │       ├── executor/
│   │       │   └── index.ts
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       ├── systemRole.ts
│   │       └── types.ts
│   ├── builtin-tool-agent-management/
│   │   ├── package.json
│   │   └── src/
│   │       ├── client/
│   │       │   ├── Inspector/
│   │       │   │   ├── CallAgent/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── CreateAgent/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── SearchAgent/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── UpdateAgent/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Render/
│   │       │   │   ├── CallAgent/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── CreateAgent/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── SearchAgent/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── UpdateAgent/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Streaming/
│   │       │   │   ├── CreateAgent/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   └── index.ts
│   │       ├── executor.ts
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       ├── systemRole.ts
│   │       └── types.ts
│   ├── builtin-tool-brief/
│   │   ├── package.json
│   │   └── src/
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       ├── systemRole.ts
│   │       └── types.ts
│   ├── builtin-tool-calculator/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── ExecutionRuntime/
│   │   │   │   └── index.ts
│   │   │   ├── calculate.test.ts
│   │   │   ├── client/
│   │   │   │   └── index.ts
│   │   │   ├── executor/
│   │   │   │   └── index.ts
│   │   │   ├── index.ts
│   │   │   ├── manifest.ts
│   │   │   ├── systemRole.ts
│   │   │   └── types.ts
│   │   └── tsconfig.json
│   ├── builtin-tool-cloud-sandbox/
│   │   ├── package.json
│   │   └── src/
│   │       ├── ExecutionRuntime/
│   │       │   └── index.ts
│   │       ├── client/
│   │       │   ├── Inspector/
│   │       │   │   ├── EditLocalFile/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ExecuteCode/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── GlobLocalFiles/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── GrepContent/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ListLocalFiles/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ReadLocalFile/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── RunCommand/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── SearchLocalFiles/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── WriteLocalFile/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Intervention/
│   │       │   │   ├── EditLocalFile/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ExecuteCode/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── MoveLocalFiles/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── RunCommand/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── WriteFile/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Render/
│   │       │   │   ├── EditLocalFile/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ExecuteCode/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ExportFile/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ListFiles/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── MoveLocalFiles/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ReadLocalFile/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── RunCommand/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── SearchFiles/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── WriteFile/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Streaming/
│   │       │   │   ├── ExecuteCode/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── components/
│   │       │   │   └── FilePathDisplay.tsx
│   │       │   └── index.ts
│   │       ├── executor/
│   │       │   └── index.ts
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       ├── systemRole.ts
│   │       └── types/
│   │           ├── api.ts
│   │           ├── index.ts
│   │           ├── params.ts
│   │           ├── service.ts
│   │           └── state.ts
│   ├── builtin-tool-creds/
│   │   ├── package.json
│   │   └── src/
│   │       ├── ExecutionRuntime/
│   │       │   └── index.ts
│   │       ├── client/
│   │       │   └── index.ts
│   │       ├── executor/
│   │       │   └── index.ts
│   │       ├── helpers.ts
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       ├── systemRole.ts
│   │       └── types.ts
│   ├── builtin-tool-group-agent-builder/
│   │   ├── package.json
│   │   └── src/
│   │       ├── ExecutionRuntime/
│   │       │   └── index.ts
│   │       ├── client/
│   │       │   ├── Inspector/
│   │       │   │   ├── BatchCreateAgents/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── CreateAgent/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── CreateGroup/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── GetAgentInfo/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── InviteAgent/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── RemoveAgent/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── SearchAgent/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── UpdateAgentPrompt/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── UpdateGroup/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── UpdateGroupPrompt/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Render/
│   │       │   │   ├── BatchCreateAgents.tsx
│   │       │   │   ├── UpdateAgentPrompt/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── UpdateGroupPrompt/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Streaming/
│   │       │   │   ├── BatchCreateAgents/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── UpdateAgentPrompt/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── UpdateGroupPrompt/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   └── index.ts
│   │       ├── executor.ts
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       ├── systemRole.ts
│   │       └── types.ts
│   ├── builtin-tool-group-management/
│   │   ├── package.json
│   │   └── src/
│   │       ├── client/
│   │       │   ├── Inspector/
│   │       │   │   ├── Broadcast/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ExecuteAgentTask/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ExecuteAgentTasks/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── Speak/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Intervention/
│   │       │   │   ├── ExecuteTask.tsx
│   │       │   │   ├── ExecuteTasks.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Render/
│   │       │   │   ├── Broadcast/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ExecuteTask/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ExecuteTasks/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── Speak/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Streaming/
│   │       │   │   ├── Broadcast/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ExecuteTask/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ExecuteTasks/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── Speak/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   └── index.ts
│   │       ├── const.ts
│   │       ├── executor.test.ts
│   │       ├── executor.ts
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       ├── systemRole.ts
│   │       └── types.ts
│   ├── builtin-tool-gtd/
│   │   ├── package.json
│   │   └── src/
│   │       ├── client/
│   │       │   ├── Inspector/
│   │       │   │   ├── ClearTodos/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── CreatePlan/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── CreateTodos/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ExecTask/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ExecTasks/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── UpdatePlan/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── UpdateTodos/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Intervention/
│   │       │   │   ├── AddTodo.tsx
│   │       │   │   ├── ClearTodos.tsx
│   │       │   │   ├── CreatePlan.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Render/
│   │       │   │   ├── CreatePlan/
│   │       │   │   │   ├── PlanCard.tsx
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ExecTask/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ExecTasks/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── TodoList/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Streaming/
│   │       │   │   ├── CreatePlan/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ExecTask/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ExecTasks/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── components/
│   │       │   │   ├── SortableTodoList/
│   │       │   │   │   ├── AddItemRow.tsx
│   │       │   │   │   ├── SortableItem.tsx
│   │       │   │   │   ├── TodoItemRow.tsx
│   │       │   │   │   ├── TodoList.tsx
│   │       │   │   │   ├── index.tsx
│   │       │   │   │   └── store/
│   │       │   │   │       ├── actions.ts
│   │       │   │   │       ├── index.ts
│   │       │   │   │       ├── initialState.ts
│   │       │   │   │       ├── store.test.ts
│   │       │   │   │       └── types.ts
│   │       │   │   └── index.ts
│   │       │   └── index.ts
│   │       ├── const.ts
│   │       ├── executor/
│   │       │   ├── helper.ts
│   │       │   ├── index.test.ts
│   │       │   └── index.ts
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       ├── systemRole.ts
│   │       └── types.ts
│   ├── builtin-tool-knowledge-base/
│   │   ├── package.json
│   │   └── src/
│   │       ├── ExecutionRuntime/
│   │       │   └── index.ts
│   │       ├── client/
│   │       │   ├── Inspector/
│   │       │   │   ├── ReadKnowledge/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── SearchKnowledgeBase/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Render/
│   │       │   │   ├── ReadKnowledge/
│   │       │   │   │   ├── FileCard.tsx
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── SearchKnowledgeBase/
│   │       │   │   │   ├── Item/
│   │       │   │   │   │   ├── index.tsx
│   │       │   │   │   │   └── style.ts
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   └── index.ts
│   │       ├── executor/
│   │       │   └── index.ts
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       ├── systemRole.ts
│   │       └── types.ts
│   ├── builtin-tool-local-system/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── __tests__/
│   │   │   │   └── interventionAudit.test.ts
│   │   │   ├── client/
│   │   │   │   ├── Inspector/
│   │   │   │   │   ├── EditLocalFile/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── GlobLocalFiles/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── GrepContent/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── ListLocalFiles/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── ReadLocalFile/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── RenameLocalFile/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── RunCommand/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── SearchLocalFiles/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── WriteLocalFile/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   └── index.ts
│   │   │   │   ├── Intervention/
│   │   │   │   │   ├── EditLocalFile/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── GlobLocalFiles/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── GrepContent/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── ListLocalFiles/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── MoveLocalFiles/
│   │   │   │   │   │   ├── MoveFileItem.tsx
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── OutOfScopeWarning.tsx
│   │   │   │   │   ├── ReadLocalFile/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── RenameLocalFile/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── RunCommand/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── SearchLocalFiles/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── WriteFile/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   └── index.ts
│   │   │   │   ├── Placeholder/
│   │   │   │   │   ├── ListFiles.tsx
│   │   │   │   │   └── SearchFiles.tsx
│   │   │   │   ├── Render/
│   │   │   │   │   ├── EditLocalFile/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── ListFiles/
│   │   │   │   │   │   ├── Result.tsx
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── MoveLocalFiles/
│   │   │   │   │   │   ├── MoveFileItem.tsx
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── ReadLocalFile/
│   │   │   │   │   │   ├── ReadFileSkeleton.tsx
│   │   │   │   │   │   ├── ReadFileView.tsx
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── RunCommand/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── SearchFiles/
│   │   │   │   │   │   ├── Result.tsx
│   │   │   │   │   │   ├── SearchQuery/
│   │   │   │   │   │   │   ├── SearchView.tsx
│   │   │   │   │   │   │   └── index.tsx
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── WriteFile/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   └── index.ts
│   │   │   │   ├── Streaming/
│   │   │   │   │   ├── RunCommand/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── WriteFile/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   └── index.ts
│   │   │   │   ├── components/
│   │   │   │   │   ├── FileItem.tsx
│   │   │   │   │   ├── FilePathDisplay.tsx
│   │   │   │   │   └── index.ts
│   │   │   │   └── index.ts
│   │   │   ├── executor/
│   │   │   │   └── index.ts
│   │   │   ├── index.ts
│   │   │   ├── interventionAudit.ts
│   │   │   ├── manifest.ts
│   │   │   ├── systemRole.desktop.ts
│   │   │   ├── systemRole.ts
│   │   │   ├── types.ts
│   │   │   └── utils/
│   │   │       ├── __tests__/
│   │   │       │   └── path.test.ts
│   │   │       └── path.ts
│   │   └── vitest.config.mts
│   ├── builtin-tool-memory/
│   │   ├── package.json
│   │   ├── promptfoo/
│   │   │   ├── evals/
│   │   │   │   └── preferences/
│   │   │   │       └── tool-call/
│   │   │   │           └── basic/
│   │   │   │               ├── buildMessages.ts
│   │   │   │               ├── eval.yaml
│   │   │   │               ├── prompt.ts
│   │   │   │               └── tests/
│   │   │   │                   └── cases.ts
│   │   │   └── tool-calls/
│   │   │       ├── memory-addContextMemory.json
│   │   │       ├── memory-addExperienceMemory.json
│   │   │       ├── memory-addIdentityMemory.json
│   │   │       ├── memory-addPreferenceMemory.json
│   │   │       ├── memory-removeIdentityMemory.json
│   │   │       ├── memory-searchUserMemory.json
│   │   │       └── memory-updateIdentityMemory.json
│   │   ├── promptfooconfig.yaml
│   │   ├── scripts/
│   │   │   └── generate-tool-call.ts
│   │   └── src/
│   │       ├── ExecutionRuntime/
│   │       │   └── index.ts
│   │       ├── client/
│   │       │   ├── Inspector/
│   │       │   │   ├── AddContextMemory/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── AddExperienceMemory/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── AddIdentityMemory/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── AddPreferenceMemory/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── RemoveIdentityMemory/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── SearchUserMemory/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── UpdateIdentityMemory/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Intervention/
│   │       │   │   ├── AddExperienceMemory/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Render/
│   │       │   │   ├── AddExperienceMemory/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── AddPreferenceMemory/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── SearchUserMemory/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Streaming/
│   │       │   │   ├── AddExperienceMemory/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── AddPreferenceMemory/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── components/
│   │       │   │   ├── ExperienceMemoryCard.tsx
│   │       │   │   ├── PreferenceMemoryCard.tsx
│   │       │   │   └── index.ts
│   │       │   └── index.ts
│   │       ├── executor/
│   │       │   └── index.ts
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       ├── systemRole.ts
│   │       └── types.ts
│   ├── builtin-tool-message/
│   │   ├── package.json
│   │   └── src/
│   │       ├── ExecutionRuntime/
│   │       │   └── index.ts
│   │       ├── client/
│   │       │   ├── Inspector/
│   │       │   │   └── index.ts
│   │       │   ├── Intervention/
│   │       │   │   └── index.ts
│   │       │   ├── Render/
│   │       │   │   └── index.ts
│   │       │   ├── Streaming/
│   │       │   │   └── index.ts
│   │       │   └── index.ts
│   │       ├── executor/
│   │       │   └── index.ts
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       ├── systemRole.ts
│   │       └── types.ts
│   ├── builtin-tool-notebook/
│   │   ├── package.json
│   │   └── src/
│   │       ├── ExecutionRuntime/
│   │       │   └── index.ts
│   │       ├── client/
│   │       │   ├── Inspector/
│   │       │   │   ├── CreateDocument/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Intervention/
│   │       │   │   └── index.ts
│   │       │   ├── Placeholder/
│   │       │   │   ├── CreateDocument.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Render/
│   │       │   │   ├── CreateDocument/
│   │       │   │   │   ├── DocumentCard.tsx
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Streaming/
│   │       │   │   ├── CreateDocument/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── components/
│   │       │   │   └── AnimatedNumber.tsx
│   │       │   └── index.ts
│   │       ├── executor/
│   │       │   └── index.ts
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       ├── systemRole.ts
│   │       └── types.ts
│   ├── builtin-tool-page-agent/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── client/
│   │   │   │   ├── Inspector/
│   │   │   │   │   ├── EditTitle/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── GetPageContent/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── InitPage/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── ModifyNodes/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── ReplaceText/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   └── index.ts
│   │   │   │   ├── Placeholder/
│   │   │   │   │   └── index.ts
│   │   │   │   ├── Render/
│   │   │   │   │   └── index.ts
│   │   │   │   ├── Streaming/
│   │   │   │   │   └── index.ts
│   │   │   │   ├── components/
│   │   │   │   │   └── AnimatedNumber.tsx
│   │   │   │   └── index.ts
│   │   │   ├── executor/
│   │   │   │   ├── index.test.ts
│   │   │   │   └── index.ts
│   │   │   ├── index.ts
│   │   │   ├── manifest.ts
│   │   │   ├── systemRole.ts
│   │   │   └── types.ts
│   │   └── vitest.config.mts
│   ├── builtin-tool-remote-device/
│   │   ├── package.json
│   │   └── src/
│   │       ├── ExecutionRuntime/
│   │       │   ├── index.ts
│   │       │   └── types.ts
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       ├── systemRole.ts
│   │       └── types.ts
│   ├── builtin-tool-skill-store/
│   │   ├── package.json
│   │   └── src/
│   │       ├── ExecutionRuntime/
│   │       │   └── index.ts
│   │       ├── client/
│   │       │   ├── Inspector/
│   │       │   │   ├── ImportFromMarket/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ImportSkill/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── SearchSkill/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Render/
│   │       │   │   ├── ImportSkill/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── SearchSkill/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   └── index.ts
│   │       ├── executor/
│   │       │   └── index.ts
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       ├── systemRole.ts
│   │       └── types.ts
│   ├── builtin-tool-skills/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── ExecutionRuntime/
│   │   │   │   ├── index.test.ts
│   │   │   │   └── index.ts
│   │   │   ├── client/
│   │   │   │   ├── Inspector/
│   │   │   │   │   ├── ExecScript/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── ReadReference/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── RunCommand/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── RunSkill/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   └── index.ts
│   │   │   │   ├── Render/
│   │   │   │   │   ├── ExecScript/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── ReadReference/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── RunCommand/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── RunSkill/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   └── index.ts
│   │   │   │   └── index.ts
│   │   │   ├── executor/
│   │   │   │   └── index.ts
│   │   │   ├── index.ts
│   │   │   ├── manifest.base.ts
│   │   │   ├── manifest.desktop.ts
│   │   │   ├── manifest.ts
│   │   │   ├── systemRole.desktop.ts
│   │   │   ├── systemRole.ts
│   │   │   └── types.ts
│   │   └── vitest.config.mts
│   ├── builtin-tool-task/
│   │   ├── package.json
│   │   └── src/
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       ├── systemRole.ts
│   │       └── types.ts
│   ├── builtin-tool-topic-reference/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── executor/
│   │   │   │   └── index.ts
│   │   │   ├── index.ts
│   │   │   ├── manifest.ts
│   │   │   └── types.ts
│   │   └── tsconfig.json
│   ├── builtin-tool-user-interaction/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── ExecutionRuntime/
│   │   │   │   ├── index.test.ts
│   │   │   │   └── index.ts
│   │   │   ├── client/
│   │   │   │   ├── Intervention/
│   │   │   │   │   ├── AskUserQuestion/
│   │   │   │   │   │   ├── index.tsx
│   │   │   │   │   │   └── style.ts
│   │   │   │   │   └── index.ts
│   │   │   │   └── index.ts
│   │   │   ├── executor/
│   │   │   │   └── index.ts
│   │   │   ├── index.ts
│   │   │   ├── manifest.ts
│   │   │   ├── systemRole.ts
│   │   │   └── types.ts
│   │   ├── tsconfig.json
│   │   └── vitest.config.mts
│   ├── builtin-tool-web-browsing/
│   │   ├── package.json
│   │   └── src/
│   │       ├── ExecutionRuntime/
│   │       │   ├── index.test.ts
│   │       │   └── index.ts
│   │       ├── client/
│   │       │   ├── Inspector/
│   │       │   │   ├── CrawlMultiPages/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── CrawlSinglePage/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── Search/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Placeholder/
│   │       │   │   ├── CrawlMultiPages.tsx
│   │       │   │   ├── CrawlSinglePage.tsx
│   │       │   │   ├── Search.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Portal/
│   │       │   │   ├── PageContent/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── PageContents/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── Search/
│   │       │   │   │   ├── Footer.tsx
│   │       │   │   │   ├── ResultList/
│   │       │   │   │   │   ├── SearchItem/
│   │       │   │   │   │   │   ├── CategoryAvatar.tsx
│   │       │   │   │   │   │   ├── TitleExtra.tsx
│   │       │   │   │   │   │   ├── Video.tsx
│   │       │   │   │   │   │   └── index.tsx
│   │       │   │   │   │   └── index.tsx
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.tsx
│   │       │   ├── Render/
│   │       │   │   ├── CrawlMultiPages.tsx
│   │       │   │   ├── CrawlSinglePage.tsx
│   │       │   │   ├── PageContent/
│   │       │   │   │   ├── Loading.tsx
│   │       │   │   │   ├── Result.tsx
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── Search/
│   │       │   │   │   ├── ConfigForm/
│   │       │   │   │   │   ├── Form.tsx
│   │       │   │   │   │   ├── SearchXNGIcon.tsx
│   │       │   │   │   │   ├── index.tsx
│   │       │   │   │   │   └── style.tsx
│   │       │   │   │   ├── SearchQuery/
│   │       │   │   │   │   ├── SearchView.tsx
│   │       │   │   │   │   └── index.tsx
│   │       │   │   │   ├── SearchResult/
│   │       │   │   │   │   ├── SearchResultItem.tsx
│   │       │   │   │   │   ├── ShowMore.tsx
│   │       │   │   │   │   └── index.tsx
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── components/
│   │       │   │   ├── CategoryAvatar.tsx
│   │       │   │   ├── EngineAvatar.tsx
│   │       │   │   ├── SearchBar.tsx
│   │       │   │   └── index.ts
│   │       │   └── index.ts
│   │       ├── const.ts
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       ├── systemRole.ts
│   │       └── types.ts
│   ├── builtin-tool-web-onboarding/
│   │   ├── package.json
│   │   └── src/
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       └── types.ts
│   ├── builtin-tools/
│   │   ├── package.json
│   │   └── src/
│   │       ├── dynamicInterventionAudits.ts
│   │       ├── identifiers.ts
│   │       ├── index.ts
│   │       ├── inspectors.ts
│   │       ├── interventions.ts
│   │       ├── placeholders.ts
│   │       ├── portals.ts
│   │       ├── renders.ts
│   │       └── streamings.ts
│   ├── business/
│   │   ├── config/
│   │   │   ├── package.json
│   │   │   └── src/
│   │   │       ├── index.ts
│   │   │       ├── llm.ts
│   │   │       └── server/
│   │   │           ├── edge-config.ts
│   │   │           ├── index.ts
│   │   │           └── route.ts
│   │   ├── const/
│   │   │   ├── package.json
│   │   │   └── src/
│   │   │       ├── bedrock-model-mapping.ts
│   │   │       ├── branding.ts
│   │   │       ├── index.ts
│   │   │       ├── llm.ts
│   │   │       └── url.ts
│   │   └── model-runtime/
│   │       ├── package.json
│   │       └── src/
│   │           ├── index.ts
│   │           └── router-runtime-options.ts
│   ├── chat-adapter-feishu/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── adapter.ts
│   │   │   ├── api.ts
│   │   │   ├── crypto.ts
│   │   │   ├── format-converter.ts
│   │   │   ├── index.ts
│   │   │   └── types.ts
│   │   ├── tsconfig.json
│   │   └── tsup.config.ts
│   ├── chat-adapter-qq/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── adapter.ts
│   │   │   ├── api.ts
│   │   │   ├── crypto.ts
│   │   │   ├── format-converter.ts
│   │   │   ├── index.ts
│   │   │   └── types.ts
│   │   ├── tsconfig.json
│   │   └── tsup.config.ts
│   ├── chat-adapter-wechat/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── adapter.test.ts
│   │   │   ├── adapter.ts
│   │   │   ├── api.test.ts
│   │   │   ├── api.ts
│   │   │   ├── format-converter.test.ts
│   │   │   ├── format-converter.ts
│   │   │   ├── index.ts
│   │   │   └── types.ts
│   │   ├── tsconfig.json
│   │   ├── tsup.config.ts
│   │   └── vitest.config.mts
│   ├── config/
│   │   ├── package.json
│   │   └── src/
│   │       └── index.ts
│   ├── const/
│   │   ├── package.json
│   │   └── src/
│   │       ├── analytics.ts
│   │       ├── bot.ts
│   │       ├── cacheControl.ts
│   │       ├── currency.ts
│   │       ├── desktop.ts
│   │       ├── discover.ts
│   │       ├── editor.ts
│   │       ├── fetch.ts
│   │       ├── file.ts
│   │       ├── hotkeys.ts
│   │       ├── index.ts
│   │       ├── klavis.ts
│   │       ├── layoutTokens.test.ts
│   │       ├── layoutTokens.ts
│   │       ├── lobehubSkill.ts
│   │       ├── message.ts
│   │       ├── meta.ts
│   │       ├── plugin.test.ts
│   │       ├── plugin.ts
│   │       ├── protocol.ts
│   │       ├── rbac.ts
│   │       ├── recommendedSkill.ts
│   │       ├── session.ts
│   │       ├── settings/
│   │       │   ├── agent.ts
│   │       │   ├── common.ts
│   │       │   ├── group.ts
│   │       │   ├── hotkey.ts
│   │       │   ├── image.ts
│   │       │   ├── index.ts
│   │       │   ├── knowledge.ts
│   │       │   ├── llm.ts
│   │       │   ├── memory.ts
│   │       │   ├── notification.ts
│   │       │   ├── systemAgent.ts
│   │       │   ├── tool.ts
│   │       │   └── tts.ts
│   │       ├── theme.ts
│   │       ├── trace.ts
│   │       ├── url.ts
│   │       ├── user.ts
│   │       ├── userMemory.ts
│   │       ├── utils/
│   │       │   ├── merge.test.ts
│   │       │   └── merge.ts
│   │       └── version.ts
│   ├── context-engine/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── __tests__/
│   │   │   │   ├── metadata.types.test.ts
│   │   │   │   └── pipeline.test.ts
│   │   │   ├── base/
│   │   │   │   ├── BaseEveryUserContentProvider.ts
│   │   │   │   ├── BaseFirstUserContentProvider.ts
│   │   │   │   ├── BaseLastUserContentProvider.ts
│   │   │   │   ├── BaseProcessor.ts
│   │   │   │   ├── BaseProvider.ts
│   │   │   │   ├── BaseSystemRoleProvider.ts
│   │   │   │   ├── __tests__/
│   │   │   │   │   ├── BaseEveryUserContentProvider.test.ts
│   │   │   │   │   ├── BaseFirstUserContentProvider.test.ts
│   │   │   │   │   ├── BaseLastUserContentProvider.test.ts
│   │   │   │   │   ├── BaseProcessor.test.ts
│   │   │   │   │   └── BaseProvider.test.ts
│   │   │   │   └── constants.ts
│   │   │   ├── engine/
│   │   │   │   ├── index.ts
│   │   │   │   ├── messages/
│   │   │   │   │   ├── MessagesEngine.ts
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   └── MessagesEngine.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── types.ts
│   │   │   │   ├── skills/
│   │   │   │   │   ├── SkillEngine.ts
│   │   │   │   │   ├── SkillResolver.ts
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   ├── SkillEngine.test.ts
│   │   │   │   │   │   └── SkillResolver.test.ts
│   │   │   │   │   ├── buildStepSkillDelta.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── types.ts
│   │   │   │   ├── tools/
│   │   │   │   │   ├── ManifestLoader.ts
│   │   │   │   │   ├── ToolArgumentsRepairer.ts
│   │   │   │   │   ├── ToolNameResolver.ts
│   │   │   │   │   ├── ToolResolver.ts
│   │   │   │   │   ├── ToolsEngine.ts
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   ├── ManifestLoader.test.ts
│   │   │   │   │   │   ├── ToolArgumentsRepairer.test.ts
│   │   │   │   │   │   ├── ToolNameResolver.test.ts
│   │   │   │   │   │   ├── ToolResolver.test.ts
│   │   │   │   │   │   ├── ToolsEngine.test.ts
│   │   │   │   │   │   ├── buildStepToolDelta.test.ts
│   │   │   │   │   │   ├── enableCheckerFactory.test.ts
│   │   │   │   │   │   └── utils.test.ts
│   │   │   │   │   ├── buildStepToolDelta.ts
│   │   │   │   │   ├── enableCheckerFactory.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── types.ts
│   │   │   │   │   └── utils.ts
│   │   │   │   └── topicReference/
│   │   │   │       ├── __tests__/
│   │   │   │       │   └── resolveTopicReferences.test.ts
│   │   │   │       ├── index.ts
│   │   │   │       └── resolveTopicReferences.ts
│   │   │   ├── index.ts
│   │   │   ├── pipeline.ts
│   │   │   ├── processors/
│   │   │   │   ├── AgentCouncilFlatten.ts
│   │   │   │   ├── CompressedGroupRoleTransform.ts
│   │   │   │   ├── GroupMessageFlatten.ts
│   │   │   │   ├── GroupOrchestrationFilter.ts
│   │   │   │   ├── GroupRoleTransform.ts
│   │   │   │   ├── HistoryTruncate.ts
│   │   │   │   ├── InputTemplate.ts
│   │   │   │   ├── MessageCleanup.ts
│   │   │   │   ├── MessageContent.ts
│   │   │   │   ├── PlaceholderVariables.ts
│   │   │   │   ├── ReactionFeedback.ts
│   │   │   │   ├── SupervisorRoleRestore.ts
│   │   │   │   ├── TaskMessage.ts
│   │   │   │   ├── TasksFlatten.ts
│   │   │   │   ├── ToolCall.ts
│   │   │   │   ├── ToolMessageReorder.ts
│   │   │   │   ├── __tests__/
│   │   │   │   │   ├── AgentCouncilFlatten.test.ts
│   │   │   │   │   ├── GroupMessageFlatten.test.ts
│   │   │   │   │   ├── GroupOrchestrationFilter.test.ts
│   │   │   │   │   ├── GroupRoleTransform.test.ts
│   │   │   │   │   ├── HistoryTruncate.test.ts
│   │   │   │   │   ├── InputTemplate.test.ts
│   │   │   │   │   ├── MessageCleanup.test.ts
│   │   │   │   │   ├── MessageContent.test.ts
│   │   │   │   │   ├── PlaceholderVariables.test.ts
│   │   │   │   │   ├── ReactionFeedback.test.ts
│   │   │   │   │   ├── SupervisorRoleRestore.test.ts
│   │   │   │   │   ├── TaskMessage.test.ts
│   │   │   │   │   ├── TasksFlatten.test.ts
│   │   │   │   │   ├── ToolCall.test.ts
│   │   │   │   │   └── ToolMessageReorder.test.ts
│   │   │   │   └── index.ts
│   │   │   ├── providers/
│   │   │   │   ├── AgentBuilderContextInjector.ts
│   │   │   │   ├── AgentDocumentInjector/
│   │   │   │   │   ├── BeforeSystemInjector.ts
│   │   │   │   │   ├── ContextInjector.ts
│   │   │   │   │   ├── MessageInjector.ts
│   │   │   │   │   ├── SystemAppendInjector.ts
│   │   │   │   │   ├── SystemReplaceInjector.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── shared.ts
│   │   │   │   ├── AgentManagementContextInjector.ts
│   │   │   │   ├── BotPlatformContextInjector.ts
│   │   │   │   ├── DiscordContextProvider.ts
│   │   │   │   ├── EvalContextSystemInjector.ts
│   │   │   │   ├── ForceFinishSummaryInjector.ts
│   │   │   │   ├── GTDPlanInjector.ts
│   │   │   │   ├── GTDTodoInjector.ts
│   │   │   │   ├── GroupAgentBuilderContextInjector.ts
│   │   │   │   ├── GroupContextInjector.ts
│   │   │   │   ├── HistorySummary.ts
│   │   │   │   ├── KnowledgeInjector.ts
│   │   │   │   ├── PageEditorContextInjector.ts
│   │   │   │   ├── PageSelectionsInjector.ts
│   │   │   │   ├── SelectedSkillInjector.ts
│   │   │   │   ├── SkillContextProvider.ts
│   │   │   │   ├── SystemDateProvider.ts
│   │   │   │   ├── SystemRoleInjector.ts
│   │   │   │   ├── ToolDiscoveryProvider.ts
│   │   │   │   ├── ToolSystemRole.ts
│   │   │   │   ├── TopicReferenceContextInjector.ts
│   │   │   │   ├── UserMemoryInjector.ts
│   │   │   │   ├── __tests__/
│   │   │   │   │   ├── AgentDocumentInjector.test.ts
│   │   │   │   │   ├── AgentManagementContextInjector.test.ts
│   │   │   │   │   ├── DiscordContextProvider.test.ts
│   │   │   │   │   ├── EvalContextSystemInjector.test.ts
│   │   │   │   │   ├── GroupAgentBuilderContextInjector.test.ts
│   │   │   │   │   ├── GroupContextInjector.test.ts
│   │   │   │   │   ├── HistorySummaryProvider.test.ts
│   │   │   │   │   ├── KnowledgeInjector.test.ts
│   │   │   │   │   ├── PageEditorContextInjector.test.ts
│   │   │   │   │   ├── PageSelectionsInjector.test.ts
│   │   │   │   │   ├── SelectedSkillInjector.test.ts
│   │   │   │   │   ├── SkillContextProvider.test.ts
│   │   │   │   │   ├── SystemDateProvider.test.ts
│   │   │   │   │   ├── SystemRoleInjector.test.ts
│   │   │   │   │   ├── ToolSystemRoleProvider.test.ts
│   │   │   │   │   ├── TopicReferenceContextInjector.test.ts
│   │   │   │   │   ├── UserMemoryInjector.test.ts
│   │   │   │   │   └── __snapshots__/
│   │   │   │   │       ├── GroupContextInjector.test.ts.snap
│   │   │   │   │       ├── KnowledgeInjector.test.ts.snap
│   │   │   │   │       ├── SkillContextProvider.test.ts.snap
│   │   │   │   │       └── UserMemoryInjector.test.ts.snap
│   │   │   │   └── index.ts
│   │   │   └── types.ts
│   │   └── vitest.config.mts
│   ├── conversation-flow/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── __tests__/
│   │   │   │   ├── fixtures/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── inputs/
│   │   │   │   │   │   ├── agentCouncil/
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   ├── simple.json
│   │   │   │   │   │   │   └── with-supervisor-reply.json
│   │   │   │   │   │   ├── agentGroup/
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   ├── speak-different-agent.json
│   │   │   │   │   │   │   ├── supervisor-after-multi-tasks.json
│   │   │   │   │   │   │   └── supervisor-content-only.json
│   │   │   │   │   │   ├── assistant-chain-with-followup.json
│   │   │   │   │   │   ├── assistantGroup/
│   │   │   │   │   │   │   ├── assistant-with-tools.json
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   └── tools-with-branches.json
│   │   │   │   │   │   ├── branch/
│   │   │   │   │   │   │   ├── active-index-1.json
│   │   │   │   │   │   │   ├── assistant-branch.json
│   │   │   │   │   │   │   ├── assistant-group-branches.json
│   │   │   │   │   │   │   ├── assistant-user-branch.json
│   │   │   │   │   │   │   ├── conversation.json
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   ├── multi-assistant-group.json
│   │   │   │   │   │   │   └── nested.json
│   │   │   │   │   │   ├── compare/
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   ├── simple.json
│   │   │   │   │   │   │   └── with-tools.json
│   │   │   │   │   │   ├── compression/
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   ├── mixed-groups.json
│   │   │   │   │   │   │   ├── multiple-compressions.json
│   │   │   │   │   │   │   ├── parallel-group.json
│   │   │   │   │   │   │   └── simple-compression.json
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── linear-conversation.json
│   │   │   │   │   │   └── tasks/
│   │   │   │   │   │       ├── index.ts
│   │   │   │   │   │       ├── multi-tasks-with-summary.json
│   │   │   │   │   │       ├── simple.json
│   │   │   │   │   │       ├── single-task-with-tool-chain.json
│   │   │   │   │   │       ├── with-assistant-group.json
│   │   │   │   │   │       └── with-summary.json
│   │   │   │   │   └── outputs/
│   │   │   │   │       ├── agentCouncil/
│   │   │   │   │       │   ├── index.ts
│   │   │   │   │       │   ├── simple.json
│   │   │   │   │       │   └── with-supervisor-reply.json
│   │   │   │   │       ├── agentGroup/
│   │   │   │   │       │   ├── index.ts
│   │   │   │   │       │   └── speak-different-agent.json
│   │   │   │   │       ├── assistant-chain-with-followup.json
│   │   │   │   │       ├── assistantGroup/
│   │   │   │   │       │   ├── assistant-with-tools.json
│   │   │   │   │       │   ├── index.ts
│   │   │   │   │       │   └── tools-with-branches.json
│   │   │   │   │       ├── branch/
│   │   │   │   │       │   ├── active-index-1.json
│   │   │   │   │       │   ├── assistant-branch.json
│   │   │   │   │       │   ├── assistant-group-branches.json
│   │   │   │   │       │   ├── assistant-user-branch.json
│   │   │   │   │       │   ├── conversation.json
│   │   │   │   │       │   ├── index.ts
│   │   │   │   │       │   ├── multi-assistant-group.json
│   │   │   │   │       │   └── nested.json
│   │   │   │   │       ├── compare/
│   │   │   │   │       │   ├── index.ts
│   │   │   │   │       │   ├── simple.json
│   │   │   │   │       │   └── with-tools.json
│   │   │   │   │       ├── linear-conversation.json
│   │   │   │   │       └── tasks/
│   │   │   │   │           ├── index.ts
│   │   │   │   │           ├── simple.json
│   │   │   │   │           ├── single-task-with-tool-chain.json
│   │   │   │   │           └── with-summary.json
│   │   │   │   ├── indexing.test.ts
│   │   │   │   ├── parse.test.ts
│   │   │   │   └── structuring.test.ts
│   │   │   ├── index.ts
│   │   │   ├── indexing.ts
│   │   │   ├── parse.ts
│   │   │   ├── structuring.ts
│   │   │   ├── transformation/
│   │   │   │   ├── BranchResolver.ts
│   │   │   │   ├── ContextTreeBuilder.ts
│   │   │   │   ├── FlatListBuilder.ts
│   │   │   │   ├── MessageCollector.ts
│   │   │   │   ├── MessageTransformer.ts
│   │   │   │   ├── __tests__/
│   │   │   │   │   ├── BranchResolver.test.ts
│   │   │   │   │   ├── ContextTreeBuilder.test.ts
│   │   │   │   │   ├── FlatListBuilder.test.ts
│   │   │   │   │   ├── MessageCollector.test.ts
│   │   │   │   │   └── MessageTransformer.test.ts
│   │   │   │   └── index.ts
│   │   │   └── types/
│   │   │       ├── contextTree.ts
│   │   │       ├── flatMessageList.ts
│   │   │       ├── index.ts
│   │   │       └── shared.ts
│   │   └── vitest.config.mts
│   ├── database/
│   │   ├── migrations/
│   │   │   ├── 0000_init.sql
│   │   │   ├── 0001_add_client_id.sql
│   │   │   ├── 0002_amusing_puma.sql
│   │   │   ├── 0003_naive_echo.sql
│   │   │   ├── 0004_add_next_auth.sql
│   │   │   ├── 0005_pgvector.sql
│   │   │   ├── 0006_add_knowledge_base.sql
│   │   │   ├── 0007_fix_embedding_table.sql
│   │   │   ├── 0008_add_rag_evals.sql
│   │   │   ├── 0009_remove_unused_user_tables.sql
│   │   │   ├── 0010_add_accessed_at_and_clean_tables.sql
│   │   │   ├── 0011_add_topic_history_summary.sql
│   │   │   ├── 0012_add_thread.sql
│   │   │   ├── 0013_add_ai_infra.sql
│   │   │   ├── 0014_add_message_reasoning.sql
│   │   │   ├── 0015_add_message_search_metadata.sql
│   │   │   ├── 0016_add_message_index.sql
│   │   │   ├── 0017_add_user_id_to_tables.sql
│   │   │   ├── 0018_add_client_id_for_entities.sql
│   │   │   ├── 0019_add_hotkey_user_settings.sql
│   │   │   ├── 0020_add_oidc.sql
│   │   │   ├── 0021_add_agent_opening_settings.sql
│   │   │   ├── 0022_add_documents.sql
│   │   │   ├── 0023_remove_param_and_doubao.sql
│   │   │   ├── 0024_add_rbac_tables.sql
│   │   │   ├── 0025_add_provider_config.sql
│   │   │   ├── 0026_add_autovacuum_tuning.sql
│   │   │   ├── 0027_ai_image.sql
│   │   │   ├── 0028_oauth_handoffs.sql
│   │   │   ├── 0029_add_apikey_manage.sql
│   │   │   ├── 0030_add_group_chat.sql
│   │   │   ├── 0031_add_agent_index.sql
│   │   │   ├── 0032_improve_agents_field.sql
│   │   │   ├── 0033_add_table_index.sql
│   │   │   ├── 0034_fix_chat_group.sql
│   │   │   ├── 0035_add_virtual.sql
│   │   │   ├── 0036_add_group_messages.sql
│   │   │   ├── 0037_add_user_memory.sql
│   │   │   ├── 0038_add_image_user_settings.sql
│   │   │   ├── 0039_add_editor_data.sql
│   │   │   ├── 0040_improve_user_memory_field.sql
│   │   │   ├── 0041_improve_index.sql
│   │   │   ├── 0042_improve_agent_index.sql
│   │   │   ├── 0043_add_ai_model_settings.sql
│   │   │   ├── 0044_high_toxin.sql
│   │   │   ├── 0045_add_tool_intervention.sql
│   │   │   ├── 0046_add_parent_id.sql
│   │   │   ├── 0047_add_slug_document.sql
│   │   │   ├── 0048_add_editor_data.sql
│   │   │   ├── 0049_better_auth.sql
│   │   │   ├── 0050_thread_and_user_id.sql
│   │   │   ├── 0051_add_market_into_user_settings.sql
│   │   │   ├── 0052_topic_and_messages.sql
│   │   │   ├── 0053_better_auth_admin.sql
│   │   │   ├── 0054_better_auth_two_factor.sql
│   │   │   ├── 0055_rename_phone_number_to_phone.sql
│   │   │   ├── 0056_update_agent_slug_index.sql
│   │   │   ├── 0057_add_topic_user_memory_extract_status.sql
│   │   │   ├── 0058_add_source_into_user_plugins.sql
│   │   │   ├── 0059_add_normalized_email_indexes.sql
│   │   │   ├── 0060_add_user_last_active_at.sql
│   │   │   ├── 0061_add_document_and_memory_index.sql
│   │   │   ├── 0062_add_more_index.sql
│   │   │   ├── 0063_add_columns_for_several_tables.sql
│   │   │   ├── 0064_add_agents_session_group_id.sql
│   │   │   ├── 0065_add_document_fields.sql
│   │   │   ├── 0065_add_passkey.sql
│   │   │   ├── 0066_add_document_fields.sql
│   │   │   ├── 0067_add_agent_cron_tables.sql
│   │   │   ├── 0068_update_group_data.sql
│   │   │   ├── 0069_add_topic_shares_table.sql
│   │   │   ├── 0070_add_user_memory_activities.sql
│   │   │   ├── 0071_add_async_task_extend.sql
│   │   │   ├── 0072_add_market_identifier_chat_group.sql
│   │   │   ├── 0073_add_message_group_metadata.sql
│   │   │   ├── 0074_add_fk_indexes_for_cascade_delete.sql
│   │   │   ├── 0075_add_user_memory_persona.sql
│   │   │   ├── 0076_add_message_group_index.sql
│   │   │   ├── 0077_add_agent_skills.sql
│   │   │   ├── 0078_added_id_nanoid_for_replacing_id.sql
│   │   │   ├── 0079_update_id_nanoid_from_casted_id.sql
│   │   │   ├── 0080_add_constraint_unique_not_null_to_id_nanoid.sql
│   │   │   ├── 0081_switch_forgien_key_to_id_nanoid.sql
│   │   │   ├── 0082_set_id_nanoid_as_primary.sql
│   │   │   ├── 0083_remove_id_seq_identity_column.sql
│   │   │   ├── 0084_rename_id_nanoid_to_id.sql
│   │   │   ├── 0085_remove_id_unique_constraint.sql
│   │   │   ├── 0086_video_generation_schema.sql
│   │   │   ├── 0087_add_eval_benchmark.sql
│   │   │   ├── 0088_fix_benchmark_add_bot_provider.sql
│   │   │   ├── 0089_add_api_key_hash.sql
│   │   │   ├── 0090_enable_pg_search.sql
│   │   │   ├── 0091_topics_add_description.sql
│   │   │   ├── 0092_add_agent_documents.sql
│   │   │   ├── 0093_add_bm25_indexes_with_icu.sql
│   │   │   ├── 0094_agent_bot_providers_add_settings.sql
│   │   │   ├── 0095_add_agent_task_system.sql
│   │   │   ├── 0096_add_notification_tables.sql
│   │   │   ├── 0097_add_agent_onboarding.sql
│   │   │   └── meta/
│   │   │       ├── 0000_snapshot.json
│   │   │       ├── 0001_snapshot.json
│   │   │       ├── 0002_snapshot.json
│   │   │       ├── 0003_snapshot.json
│   │   │       ├── 0004_snapshot.json
│   │   │       ├── 0005_snapshot.json
│   │   │       ├── 0006_snapshot.json
│   │   │       ├── 0007_snapshot.json
│   │   │       ├── 0008_snapshot.json
│   │   │       ├── 0009_snapshot.json
│   │   │       ├── 0010_snapshot.json
│   │   │       ├── 0011_snapshot.json
│   │   │       ├── 0012_snapshot.json
│   │   │       ├── 0013_snapshot.json
│   │   │       ├── 0014_snapshot.json
│   │   │       ├── 0015_snapshot.json
│   │   │       ├── 0016_snapshot.json
│   │   │       ├── 0017_snapshot.json
│   │   │       ├── 0018_snapshot.json
│   │   │       ├── 0019_snapshot.json
│   │   │       ├── 0020_snapshot.json
│   │   │       ├── 0021_snapshot.json
│   │   │       ├── 0022_snapshot.json
│   │   │       ├── 0023_snapshot.json
│   │   │       ├── 0024_snapshot.json
│   │   │       ├── 0025_snapshot.json
│   │   │       ├── 0026_snapshot.json
│   │   │       ├── 0027_snapshot.json
│   │   │       ├── 0028_snapshot.json
│   │   │       ├── 0029_snapshot.json
│   │   │       ├── 0030_snapshot.json
│   │   │       ├── 0031_snapshot.json
│   │   │       ├── 0032_snapshot.json
│   │   │       ├── 0033_snapshot.json
│   │   │       ├── 0034_snapshot.json
│   │   │       ├── 0035_snapshot.json
│   │   │       ├── 0036_snapshot.json
│   │   │       ├── 0037_snapshot.json
│   │   │       ├── 0038_snapshot.json
│   │   │       ├── 0039_snapshot.json
│   │   │       ├── 0040_snapshot.json
│   │   │       ├── 0041_snapshot.json
│   │   │       ├── 0042_snapshot.json
│   │   │       ├── 0043_snapshot.json
│   │   │       ├── 0044_snapshot.json
│   │   │       ├── 0045_snapshot.json
│   │   │       ├── 0046_snapshot.json
│   │   │       ├── 0047_snapshot.json
│   │   │       ├── 0048_snapshot.json
│   │   │       ├── 0049_snapshot.json
│   │   │       ├── 0050_snapshot.json
│   │   │       ├── 0051_snapshot.json
│   │   │       ├── 0052_snapshot.json
│   │   │       ├── 0053_snapshot.json
│   │   │       ├── 0054_snapshot.json
│   │   │       ├── 0055_snapshot.json
│   │   │       ├── 0056_snapshot.json
│   │   │       ├── 0057_snapshot.json
│   │   │       ├── 0058_snapshot.json
│   │   │       ├── 0059_snapshot.json
│   │   │       ├── 0060_snapshot.json
│   │   │       ├── 0061_snapshot.json
│   │   │       ├── 0062_snapshot.json
│   │   │       ├── 0063_snapshot.json
│   │   │       ├── 0064_snapshot.json
│   │   │       ├── 0065_snapshot.json
│   │   │       ├── 0066_snapshot.json
│   │   │       ├── 0067_snapshot.json
│   │   │       ├── 0068_snapshot.json
│   │   │       ├── 0069_snapshot.json
│   │   │       ├── 0070_snapshot.json
│   │   │       ├── 0071_snapshot.json
│   │   │       ├── 0072_snapshot.json
│   │   │       ├── 0073_snapshot.json
│   │   │       ├── 0074_snapshot.json
│   │   │       ├── 0075_snapshot.json
│   │   │       ├── 0076_snapshot.json
│   │   │       ├── 0077_snapshot.json
│   │   │       ├── 0078_snapshot.json
│   │   │       ├── 0079_snapshot.json
│   │   │       ├── 0080_snapshot.json
│   │   │       ├── 0081_snapshot.json
│   │   │       ├── 0082_snapshot.json
│   │   │       ├── 0083_snapshot.json
│   │   │       ├── 0084_snapshot.json
│   │   │       ├── 0085_snapshot.json
│   │   │       ├── 0086_snapshot.json
│   │   │       ├── 0087_snapshot.json
│   │   │       ├── 0088_snapshot.json
│   │   │       ├── 0089_snapshot.json
│   │   │       ├── 0090_snapshot.json
│   │   │       ├── 0091_snapshot.json
│   │   │       ├── 0092_snapshot.json
│   │   │       ├── 0093_snapshot.json
│   │   │       ├── 0094_snapshot.json
│   │   │       ├── 0095_snapshot.json
│   │   │       ├── 0096_snapshot.json
│   │   │       ├── 0097_snapshot.json
│   │   │       └── _journal.json
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── core/
│   │   │   │   ├── db-adaptor.ts
│   │   │   │   ├── getTestDB.ts
│   │   │   │   └── web-server.ts
│   │   │   ├── index.ts
│   │   │   ├── models/
│   │   │   │   ├── __tests__/
│   │   │   │   │   ├── _test_template.ts
│   │   │   │   │   ├── agent.test.ts
│   │   │   │   │   ├── agentBotProvider.test.ts
│   │   │   │   │   ├── agentCronJob.test.ts
│   │   │   │   │   ├── agentSkill.test.ts
│   │   │   │   │   ├── aiModel.test.ts
│   │   │   │   │   ├── aiProvider.test.ts
│   │   │   │   │   ├── apiKey.test.ts
│   │   │   │   │   ├── asyncTask.test.ts
│   │   │   │   │   ├── brief.test.ts
│   │   │   │   │   ├── chatGroup.test.ts
│   │   │   │   │   ├── chunk.test.ts
│   │   │   │   │   ├── document.test.ts
│   │   │   │   │   ├── drizzleMigration.test.ts
│   │   │   │   │   ├── embedding.test.ts
│   │   │   │   │   ├── file.test.ts
│   │   │   │   │   ├── fixtures/
│   │   │   │   │   │   └── embedding.ts
│   │   │   │   │   ├── generation.test.ts
│   │   │   │   │   ├── generationBatch.test.ts
│   │   │   │   │   ├── generationTopic.test.ts
│   │   │   │   │   ├── knowledgeBase.test.ts
│   │   │   │   │   ├── messages/
│   │   │   │   │   │   ├── message.create.test.ts
│   │   │   │   │   │   ├── message.delete.test.ts
│   │   │   │   │   │   ├── message.query.test.ts
│   │   │   │   │   │   ├── message.stats.test.ts
│   │   │   │   │   │   ├── message.thread-query.test.ts
│   │   │   │   │   │   ├── message.update.test.ts
│   │   │   │   │   │   ├── messageWithTask.test.ts
│   │   │   │   │   │   ├── queryWithMessageGroup.perf.test.ts
│   │   │   │   │   │   └── queryWithMessageGroup.test.ts
│   │   │   │   │   ├── oauthHandoff.test.ts
│   │   │   │   │   ├── plugin.test.ts
│   │   │   │   │   ├── session.test.ts
│   │   │   │   │   ├── sessionGroup.test.ts
│   │   │   │   │   ├── task.test.ts
│   │   │   │   │   ├── taskTopic.test.ts
│   │   │   │   │   ├── thread.test.ts
│   │   │   │   │   ├── topicDocument.test.ts
│   │   │   │   │   ├── topicShare.test.ts
│   │   │   │   │   ├── topics/
│   │   │   │   │   │   ├── topic.create.test.ts
│   │   │   │   │   │   ├── topic.delete.test.ts
│   │   │   │   │   │   ├── topic.memoryExtractor.test.ts
│   │   │   │   │   │   ├── topic.query.test.ts
│   │   │   │   │   │   ├── topic.stats.test.ts
│   │   │   │   │   │   └── topic.update.test.ts
│   │   │   │   │   ├── user.test.ts
│   │   │   │   │   ├── userMemories.test.ts
│   │   │   │   │   └── userMemoryIdentity.test.ts
│   │   │   │   ├── _template.ts
│   │   │   │   ├── agent.ts
│   │   │   │   ├── agentBotProvider.ts
│   │   │   │   ├── agentCronJob.ts
│   │   │   │   ├── agentDocuments/
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   ├── agentDocument.test.ts
│   │   │   │   │   │   └── template.test.ts
│   │   │   │   │   ├── agentDocument.ts
│   │   │   │   │   ├── filename.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── policy/
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   ├── checks.test.ts
│   │   │   │   │   │   │   └── loadPolicy.test.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── loadPolicy.ts
│   │   │   │   │   │   ├── loadRule.ts
│   │   │   │   │   │   ├── permission.ts
│   │   │   │   │   │   └── policy.ts
│   │   │   │   │   └── types.ts
│   │   │   │   ├── agentEval/
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   ├── benchmark.test.ts
│   │   │   │   │   │   ├── dataset.test.ts
│   │   │   │   │   │   ├── run.test.ts
│   │   │   │   │   │   ├── runTopic.test.ts
│   │   │   │   │   │   └── testCase.test.ts
│   │   │   │   │   ├── benchmark.ts
│   │   │   │   │   ├── dataset.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── run.ts
│   │   │   │   │   ├── runTopic.ts
│   │   │   │   │   └── testCase.ts
│   │   │   │   ├── agentSkill.ts
│   │   │   │   ├── aiModel.ts
│   │   │   │   ├── aiProvider.ts
│   │   │   │   ├── apiKey.ts
│   │   │   │   ├── asyncTask.ts
│   │   │   │   ├── brief.ts
│   │   │   │   ├── chatGroup.ts
│   │   │   │   ├── chunk.ts
│   │   │   │   ├── document.ts
│   │   │   │   ├── drizzleMigration.ts
│   │   │   │   ├── embedding.ts
│   │   │   │   ├── file.ts
│   │   │   │   ├── generation.ts
│   │   │   │   ├── generationBatch.ts
│   │   │   │   ├── generationTopic.ts
│   │   │   │   ├── knowledgeBase.ts
│   │   │   │   ├── message.ts
│   │   │   │   ├── notification.ts
│   │   │   │   ├── oauthHandoff.ts
│   │   │   │   ├── plugin.ts
│   │   │   │   ├── ragEval/
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   ├── dataset.test.ts
│   │   │   │   │   │   ├── datasetRecord.test.ts
│   │   │   │   │   │   ├── evaluation.test.ts
│   │   │   │   │   │   └── evaluationRecord.test.ts
│   │   │   │   │   ├── dataset.ts
│   │   │   │   │   ├── datasetRecord.ts
│   │   │   │   │   ├── evaluation.ts
│   │   │   │   │   ├── evaluationRecord.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── rbac.ts
│   │   │   │   ├── session.ts
│   │   │   │   ├── sessionGroup.ts
│   │   │   │   ├── task.ts
│   │   │   │   ├── taskTopic.ts
│   │   │   │   ├── thread.ts
│   │   │   │   ├── topic.ts
│   │   │   │   ├── topicDocument.ts
│   │   │   │   ├── topicShare.ts
│   │   │   │   ├── user.ts
│   │   │   │   └── userMemory/
│   │   │   │       ├── __tests__/
│   │   │   │       │   ├── activity.test.ts
│   │   │   │       │   ├── context.test.ts
│   │   │   │       │   ├── experience.test.ts
│   │   │   │       │   ├── identity.test.ts
│   │   │   │       │   ├── model.test.ts
│   │   │   │       │   ├── persona.test.ts
│   │   │   │       │   └── preference.test.ts
│   │   │   │       ├── activity.ts
│   │   │   │       ├── context.ts
│   │   │   │       ├── experience.ts
│   │   │   │       ├── identity.ts
│   │   │   │       ├── index.ts
│   │   │   │       ├── model.ts
│   │   │   │       ├── persona.ts
│   │   │   │       ├── preference.ts
│   │   │   │       └── sources/
│   │   │   │           ├── __tests__/
│   │   │   │           │   └── benchmarkLoCoMo.test.ts
│   │   │   │           ├── benchmarkLoCoMo.ts
│   │   │   │           ├── index.ts
│   │   │   │           └── shared.ts
│   │   │   ├── repositories/
│   │   │   │   ├── agentGroup/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── agentMigration/
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   └── agentMigrationRepo.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── aiInfra/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── compression/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── dataExporter/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── dataImporter/
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   ├── fixtures/
│   │   │   │   │   │   │   ├── agents.json
│   │   │   │   │   │   │   ├── agentsToSessions.json
│   │   │   │   │   │   │   ├── topic.json
│   │   │   │   │   │   │   ├── userSettings.json
│   │   │   │   │   │   │   └── with-client-id.json
│   │   │   │   │   │   └── index.test.ts
│   │   │   │   │   ├── deprecated/
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   ├── fixtures/
│   │   │   │   │   │   │   │   └── messages.json
│   │   │   │   │   │   │   └── index.test.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── home/
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   └── index.test.ts
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── knowledge/
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   └── index.test.ts
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── search/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── topicImporter/
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   ├── fixtures/
│   │   │   │   │   │   │   └── exported-topic.json
│   │   │   │   │   │   └── importTopic.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   └── userMemory/
│   │   │   │       ├── UserMemoryTopicRepository.ts
│   │   │   │       ├── __tests__/
│   │   │   │       │   └── UserMemoryTopicRepository.test.ts
│   │   │   │       └── index.ts
│   │   │   ├── schemas/
│   │   │   │   ├── _helpers.ts
│   │   │   │   ├── agent.ts
│   │   │   │   ├── agentBotProvider.ts
│   │   │   │   ├── agentCronJob.ts
│   │   │   │   ├── agentDocuments.ts
│   │   │   │   ├── agentEvals.ts
│   │   │   │   ├── agentSkill.ts
│   │   │   │   ├── aiInfra.ts
│   │   │   │   ├── apiKey.ts
│   │   │   │   ├── asyncTask.ts
│   │   │   │   ├── betterAuth.ts
│   │   │   │   ├── chatGroup.ts
│   │   │   │   ├── file.ts
│   │   │   │   ├── generation.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── message.ts
│   │   │   │   ├── nextauth.ts
│   │   │   │   ├── notification.ts
│   │   │   │   ├── oidc.ts
│   │   │   │   ├── rag.ts
│   │   │   │   ├── ragEvals.ts
│   │   │   │   ├── rbac.ts
│   │   │   │   ├── relations.ts
│   │   │   │   ├── session.ts
│   │   │   │   ├── task.ts
│   │   │   │   ├── topic.ts
│   │   │   │   ├── user.ts
│   │   │   │   └── userMemories/
│   │   │   │       ├── index.ts
│   │   │   │       └── persona.ts
│   │   │   ├── server/
│   │   │   │   ├── index.ts
│   │   │   │   └── models/
│   │   │   │       └── __tests__/
│   │   │   │           ├── adapter.test.ts
│   │   │   │           └── user.test.ts
│   │   │   ├── type.ts
│   │   │   ├── types/
│   │   │   │   ├── chatGroup.ts
│   │   │   │   └── generation.ts
│   │   │   └── utils/
│   │   │       ├── bm25.test.ts
│   │   │       ├── bm25.ts
│   │   │       ├── columns.ts
│   │   │       ├── genWhere.test.ts
│   │   │       ├── genWhere.ts
│   │   │       ├── idGenerator.test.ts
│   │   │       └── idGenerator.ts
│   │   ├── tests/
│   │   │   ├── setup-db.ts
│   │   │   └── test-utils.ts
│   │   ├── vitest.config.mts
│   │   └── vitest.config.server.mts
│   ├── desktop-bridge/
│   │   ├── package.json
│   │   └── src/
│   │       ├── index.ts
│   │       └── routeVariants.ts
│   ├── device-gateway-client/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── client.test.ts
│   │   │   ├── client.ts
│   │   │   ├── http.test.ts
│   │   │   ├── http.ts
│   │   │   ├── index.ts
│   │   │   └── types.ts
│   │   ├── tsconfig.json
│   │   └── vitest.config.mts
│   ├── edge-config/
│   │   ├── package.json
│   │   └── src/
│   │       ├── index.ts
│   │       └── types.ts
│   ├── editor-runtime/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── EditorRuntime.ts
│   │   │   ├── __tests__/
│   │   │   │   ├── EditorRuntime.real.test.ts
│   │   │   │   ├── EditorRuntime.test.ts
│   │   │   │   ├── __snapshots__/
│   │   │   │   │   ├── EditorRuntime.real.test.ts.snap
│   │   │   │   │   └── EditorRuntime.test.ts.snap
│   │   │   │   └── fixtures/
│   │   │   │       ├── edit-all.json
│   │   │   │       ├── remove-then-add.json
│   │   │   │       └── remove.json
│   │   │   ├── index.ts
│   │   │   └── types.ts
│   │   └── vitest.config.mts
│   ├── electron-client-ipc/
│   │   ├── README.md
│   │   ├── README.zh-CN.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── events/
│   │   │   │   ├── gatewayConnection.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── navigation.ts
│   │   │   │   ├── protocol.ts
│   │   │   │   ├── remoteServer.ts
│   │   │   │   ├── system.ts
│   │   │   │   ├── update.ts
│   │   │   │   └── windows.ts
│   │   │   ├── index.ts
│   │   │   ├── ipc.test.ts
│   │   │   ├── ipc.ts
│   │   │   ├── streamInvoke.ts
│   │   │   ├── types/
│   │   │   │   ├── dataSync.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── localSystem.ts
│   │   │   │   ├── mcpInstall.ts
│   │   │   │   ├── notification.ts
│   │   │   │   ├── proxy.ts
│   │   │   │   ├── proxyTRPCRequest.ts
│   │   │   │   ├── route.ts
│   │   │   │   ├── shortcut.ts
│   │   │   │   ├── system.ts
│   │   │   │   ├── toolDetector.ts
│   │   │   │   ├── tray.ts
│   │   │   │   ├── update.ts
│   │   │   │   ├── upload.ts
│   │   │   │   └── window.ts
│   │   │   ├── useWatchBroadcast.ts
│   │   │   └── utils/
│   │   │       ├── headers.ts
│   │   │       └── request.ts
│   │   └── vitest.config.mts
│   ├── electron-server-ipc/
│   │   ├── README.md
│   │   ├── README.zh-CN.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── const.ts
│   │   │   ├── index.ts
│   │   │   ├── ipcClient.test.ts
│   │   │   ├── ipcClient.ts
│   │   │   ├── ipcServer.test.ts
│   │   │   ├── ipcServer.ts
│   │   │   └── types/
│   │   │       ├── file.ts
│   │   │       └── index.ts
│   │   └── vitest.config.mts
│   ├── eval-dataset-parser/
│   │   ├── __tests__/
│   │   │   ├── detectFormat.edge.test.ts
│   │   │   ├── detectFormat.test.ts
│   │   │   ├── fixtures/
│   │   │   │   ├── sample.csv
│   │   │   │   ├── sample.json
│   │   │   │   └── sample.jsonl
│   │   │   ├── parseDataset.edge.test.ts
│   │   │   ├── parseDataset.test.ts
│   │   │   └── parsers.test.ts
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── detect.ts
│   │   │   ├── index.ts
│   │   │   ├── parseDataset.ts
│   │   │   ├── parsers/
│   │   │   │   ├── csv.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── json.ts
│   │   │   │   ├── jsonl.ts
│   │   │   │   └── xlsx.ts
│   │   │   └── types.ts
│   │   └── vitest.config.mts
│   ├── eval-rubric/
│   │   ├── __tests__/
│   │   │   ├── evaluate.test.ts
│   │   │   └── extractors.test.ts
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── evaluate.ts
│   │   │   ├── extractors.ts
│   │   │   ├── index.ts
│   │   │   ├── matchers/
│   │   │   │   ├── __tests__/
│   │   │   │   │   ├── anyOf.test.ts
│   │   │   │   │   ├── contains.test.ts
│   │   │   │   │   ├── endsWith.test.ts
│   │   │   │   │   ├── equals.test.ts
│   │   │   │   │   ├── jsonSchema.test.ts
│   │   │   │   │   ├── levenshtein.test.ts
│   │   │   │   │   ├── llmRubric.test.ts
│   │   │   │   │   ├── numeric.test.ts
│   │   │   │   │   ├── regex.test.ts
│   │   │   │   │   └── startsWith.test.ts
│   │   │   │   ├── anyOf.ts
│   │   │   │   ├── contains.ts
│   │   │   │   ├── endsWith.ts
│   │   │   │   ├── equals.ts
│   │   │   │   ├── external.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── jsonSchema.ts
│   │   │   │   ├── levenshtein.ts
│   │   │   │   ├── llmEq.ts
│   │   │   │   ├── llmRubric.ts
│   │   │   │   ├── numeric.ts
│   │   │   │   ├── regex.ts
│   │   │   │   ├── startsWith.ts
│   │   │   │   └── types.ts
│   │   │   └── normalize.ts
│   │   └── tsconfig.json
│   ├── fetch-sse/
│   │   ├── package.json
│   │   └── src/
│   │       ├── __tests__/
│   │       │   ├── fetchSSE.test.ts
│   │       │   ├── headers.test.ts
│   │       │   ├── parseError.test.ts
│   │       │   └── request.test.ts
│   │       ├── fetchSSE.ts
│   │       ├── headers.ts
│   │       ├── index.ts
│   │       ├── parseError.ts
│   │       └── request.ts
│   ├── file-loaders/
│   │   ├── README.md
│   │   ├── README.zh-CN.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── blackList.ts
│   │   │   ├── index.ts
│   │   │   ├── loadFile.test.ts
│   │   │   ├── loadFile.ts
│   │   │   ├── loaders/
│   │   │   │   ├── doc/
│   │   │   │   │   ├── __snapshots__/
│   │   │   │   │   │   └── index.test.ts.snap
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── docx/
│   │   │   │   │   ├── __snapshots__/
│   │   │   │   │   │   └── index.test.ts.snap
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── excel/
│   │   │   │   │   ├── __snapshots__/
│   │   │   │   │   │   └── index.test.ts.snap
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── prompt.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── pdf/
│   │   │   │   │   ├── __snapshots__/
│   │   │   │   │   │   └── index.test.ts.snap
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── prompt.ts
│   │   │   │   ├── pptx/
│   │   │   │   │   ├── __snapshots__/
│   │   │   │   │   │   └── index.test.ts.snap
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   └── text/
│   │   │   │       ├── __snapshots__/
│   │   │   │       │   └── index.test.ts.snap
│   │   │   │       ├── fixtures/
│   │   │   │       │   └── test.txt
│   │   │   │       ├── index.test.ts
│   │   │   │       └── index.ts
│   │   │   ├── types/
│   │   │   │   └── word-extractor.d.ts
│   │   │   ├── types.ts
│   │   │   └── utils/
│   │   │       ├── isTextReadableFile.test.ts
│   │   │       ├── isTextReadableFile.ts
│   │   │       ├── parser-utils.test.ts
│   │   │       └── parser-utils.ts
│   │   ├── test/
│   │   │   ├── __snapshots__/
│   │   │   │   └── loaders.test.ts.snap
│   │   │   ├── fixtures/
│   │   │   │   ├── test.csv
│   │   │   │   ├── test.epub
│   │   │   │   ├── test.md
│   │   │   │   └── test.txt
│   │   │   ├── loaders.test.ts
│   │   │   └── setup.ts
│   │   └── vitest.config.mts
│   ├── local-file-shell/
│   │   ├── package.json
│   │   └── src/
│   │       ├── file/
│   │       │   ├── __tests__/
│   │       │   │   └── file.test.ts
│   │       │   ├── edit.ts
│   │       │   ├── glob.ts
│   │       │   ├── grep.ts
│   │       │   ├── index.ts
│   │       │   ├── list.ts
│   │       │   ├── move.ts
│   │       │   ├── read.ts
│   │       │   ├── rename.ts
│   │       │   ├── search.ts
│   │       │   └── write.ts
│   │       ├── index.ts
│   │       ├── shell/
│   │       │   ├── __tests__/
│   │       │   │   ├── process-manager.test.ts
│   │       │   │   ├── runner.test.ts
│   │       │   │   └── utils.test.ts
│   │       │   ├── index.ts
│   │       │   ├── process-manager.ts
│   │       │   ├── runner.ts
│   │       │   └── utils.ts
│   │       └── types.ts
│   ├── memory-user-memory/
│   │   ├── .gitignore
│   │   ├── benchmarks/
│   │   │   └── locomo/
│   │   │       ├── README.md
│   │   │       └── run.ts
│   │   ├── package.json
│   │   ├── promptfoo/
│   │   │   ├── evals/
│   │   │   │   ├── activity/
│   │   │   │   │   ├── basic/
│   │   │   │   │   │   ├── buildMessages.ts
│   │   │   │   │   │   ├── eval.yaml
│   │   │   │   │   │   ├── prompt.ts
│   │   │   │   │   │   └── tests/
│   │   │   │   │   │       └── cases.ts
│   │   │   │   │   └── locomo/
│   │   │   │   │       ├── buildMessages.ts
│   │   │   │   │       ├── eval.yaml
│   │   │   │   │       ├── prompt.ts
│   │   │   │   │       └── tests/
│   │   │   │   │           ├── benchmark-locomo-payload-conv-26.json
│   │   │   │   │           └── cases.ts
│   │   │   │   ├── identity/
│   │   │   │   │   └── with-s3-trace/
│   │   │   │   │       ├── buildMessages.ts
│   │   │   │   │       ├── eval.yaml
│   │   │   │   │       ├── prompt.ts
│   │   │   │   │       └── tests/
│   │   │   │   │           └── cases.ts
│   │   │   │   └── persona/
│   │   │   │       ├── eval.yaml
│   │   │   │       ├── prompt.ts
│   │   │   │       └── tests/
│   │   │   │           └── cases.ts
│   │   │   └── response-formats/
│   │   │       ├── activity.json
│   │   │       ├── context.json
│   │   │       ├── experience.json
│   │   │       ├── identity.json
│   │   │       ├── persona-tools.json
│   │   │       ├── persona.json
│   │   │       └── preference.json
│   │   ├── promptfooconfig.yaml
│   │   ├── scripts/
│   │   │   └── generate-response-formats.ts
│   │   ├── src/
│   │   │   ├── converters/
│   │   │   │   ├── index.ts
│   │   │   │   └── locomo.ts
│   │   │   ├── extractors/
│   │   │   │   ├── activity.ts
│   │   │   │   ├── base.ts
│   │   │   │   ├── context.test.ts
│   │   │   │   ├── context.ts
│   │   │   │   ├── experience.test.ts
│   │   │   │   ├── experience.ts
│   │   │   │   ├── gatekeeper.test.ts
│   │   │   │   ├── gatekeeper.ts
│   │   │   │   ├── identity.test.ts
│   │   │   │   ├── identity.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── persona.test.ts
│   │   │   │   ├── persona.ts
│   │   │   │   ├── preference.test.ts
│   │   │   │   └── preference.ts
│   │   │   ├── index.ts
│   │   │   ├── prompts/
│   │   │   │   ├── gatekeeper.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── layers/
│   │   │   │   │   ├── activity.ts
│   │   │   │   │   ├── context.ts
│   │   │   │   │   ├── experience.ts
│   │   │   │   │   ├── identity.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── preference.ts
│   │   │   │   └── persona.ts
│   │   │   ├── providers/
│   │   │   │   ├── benchmarkLocomo.test.ts
│   │   │   │   ├── benchmarkLocomo.ts
│   │   │   │   ├── chatTopic.test.ts
│   │   │   │   ├── chatTopic.ts
│   │   │   │   ├── existingUserMemory.test.ts
│   │   │   │   ├── existingUserMemory.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── tests/
│   │   │   │       └── benchmark-locomo-converted.json
│   │   │   ├── schemas/
│   │   │   │   ├── activity.ts
│   │   │   │   ├── common.ts
│   │   │   │   ├── context.ts
│   │   │   │   ├── experience.ts
│   │   │   │   ├── gatekeeper.ts
│   │   │   │   ├── identity.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── preference.ts
│   │   │   ├── services/
│   │   │   │   └── extractExecutor.ts
│   │   │   ├── types.ts
│   │   │   └── utils/
│   │   │       └── zod.ts
│   │   └── vitest.config.ts
│   ├── model-bank/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── aiModels/
│   │   │   │   ├── ai21.ts
│   │   │   │   ├── ai302.ts
│   │   │   │   ├── ai360.ts
│   │   │   │   ├── aihubmix.ts
│   │   │   │   ├── akashchat.ts
│   │   │   │   ├── anthropic.ts
│   │   │   │   ├── azure.ts
│   │   │   │   ├── azureai.ts
│   │   │   │   ├── baichuan.ts
│   │   │   │   ├── bailianCodingPlan.ts
│   │   │   │   ├── bedrock.ts
│   │   │   │   ├── bfl.ts
│   │   │   │   ├── cerebras.ts
│   │   │   │   ├── cloudflare.ts
│   │   │   │   ├── cohere.ts
│   │   │   │   ├── cometapi.ts
│   │   │   │   ├── comfyui.ts
│   │   │   │   ├── deepseek.ts
│   │   │   │   ├── fal.ts
│   │   │   │   ├── fireworksai.ts
│   │   │   │   ├── giteeai.ts
│   │   │   │   ├── github.ts
│   │   │   │   ├── githubCopilot.ts
│   │   │   │   ├── glmCodingPlan.ts
│   │   │   │   ├── google.ts
│   │   │   │   ├── groq.ts
│   │   │   │   ├── higress.ts
│   │   │   │   ├── huggingface.ts
│   │   │   │   ├── hunyuan.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── infiniai.ts
│   │   │   │   ├── internlm.ts
│   │   │   │   ├── jina.ts
│   │   │   │   ├── kimiCodingPlan.ts
│   │   │   │   ├── lmstudio.ts
│   │   │   │   ├── lobehub/
│   │   │   │   │   ├── chat/
│   │   │   │   │   │   ├── anthropic.ts
│   │   │   │   │   │   ├── deepseek.ts
│   │   │   │   │   │   ├── google.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── minimax.ts
│   │   │   │   │   │   ├── moonshot.ts
│   │   │   │   │   │   ├── openai.ts
│   │   │   │   │   │   ├── xai.ts
│   │   │   │   │   │   ├── xiaomimimo.ts
│   │   │   │   │   │   └── zhipu.ts
│   │   │   │   │   ├── embedding.ts
│   │   │   │   │   ├── image.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── utils.ts
│   │   │   │   │   └── video.ts
│   │   │   │   ├── longcat.ts
│   │   │   │   ├── minimax.ts
│   │   │   │   ├── minimaxCodingPlan.ts
│   │   │   │   ├── mistral.ts
│   │   │   │   ├── modelscope.ts
│   │   │   │   ├── moonshot.ts
│   │   │   │   ├── nebius.ts
│   │   │   │   ├── newapi.ts
│   │   │   │   ├── novita.ts
│   │   │   │   ├── nvidia.ts
│   │   │   │   ├── ollama.ts
│   │   │   │   ├── ollamacloud.ts
│   │   │   │   ├── openai.ts
│   │   │   │   ├── openrouter.ts
│   │   │   │   ├── perplexity.ts
│   │   │   │   ├── ppio.ts
│   │   │   │   ├── qiniu.ts
│   │   │   │   ├── qwen.ts
│   │   │   │   ├── replicate.ts
│   │   │   │   ├── sambanova.ts
│   │   │   │   ├── search1api.ts
│   │   │   │   ├── sensenova.ts
│   │   │   │   ├── siliconcloud.ts
│   │   │   │   ├── spark.ts
│   │   │   │   ├── stepfun.ts
│   │   │   │   ├── straico.ts
│   │   │   │   ├── taichu.ts
│   │   │   │   ├── tencentcloud.ts
│   │   │   │   ├── togetherai.ts
│   │   │   │   ├── upstage.ts
│   │   │   │   ├── v0.ts
│   │   │   │   ├── vercelaigateway.ts
│   │   │   │   ├── vertexai.ts
│   │   │   │   ├── vllm.ts
│   │   │   │   ├── volcengine.ts
│   │   │   │   ├── volcengineCodingPlan.ts
│   │   │   │   ├── wenxin.ts
│   │   │   │   ├── xai.ts
│   │   │   │   ├── xiaomimimo.ts
│   │   │   │   ├── xinference.ts
│   │   │   │   ├── zenmux.ts
│   │   │   │   ├── zeroone.ts
│   │   │   │   └── zhipu.ts
│   │   │   ├── const/
│   │   │   │   └── modelProvider.ts
│   │   │   ├── exports.test.ts
│   │   │   ├── index.ts
│   │   │   ├── modelProviders/
│   │   │   │   ├── ai21.ts
│   │   │   │   ├── ai302.ts
│   │   │   │   ├── ai360.ts
│   │   │   │   ├── aihubmix.ts
│   │   │   │   ├── akashchat.ts
│   │   │   │   ├── anthropic.ts
│   │   │   │   ├── azure.ts
│   │   │   │   ├── azureai.ts
│   │   │   │   ├── baichuan.ts
│   │   │   │   ├── bailianCodingPlan.ts
│   │   │   │   ├── bedrock.ts
│   │   │   │   ├── bfl.ts
│   │   │   │   ├── cerebras.ts
│   │   │   │   ├── cloudflare.ts
│   │   │   │   ├── cohere.ts
│   │   │   │   ├── cometapi.ts
│   │   │   │   ├── comfyui.ts
│   │   │   │   ├── deepseek.ts
│   │   │   │   ├── fal.ts
│   │   │   │   ├── fireworksai.ts
│   │   │   │   ├── giteeai.ts
│   │   │   │   ├── github.ts
│   │   │   │   ├── githubCopilot.ts
│   │   │   │   ├── glmCodingPlan.ts
│   │   │   │   ├── google.ts
│   │   │   │   ├── groq.ts
│   │   │   │   ├── higress.ts
│   │   │   │   ├── huggingface.ts
│   │   │   │   ├── hunyuan.ts
│   │   │   │   ├── index.test.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── infiniai.ts
│   │   │   │   ├── internlm.ts
│   │   │   │   ├── jina.ts
│   │   │   │   ├── kimiCodingPlan.ts
│   │   │   │   ├── lmstudio.ts
│   │   │   │   ├── lobehub.ts
│   │   │   │   ├── longcat.ts
│   │   │   │   ├── minimax.ts
│   │   │   │   ├── minimaxCodingPlan.ts
│   │   │   │   ├── mistral.ts
│   │   │   │   ├── modelscope.ts
│   │   │   │   ├── moonshot.ts
│   │   │   │   ├── nebius.ts
│   │   │   │   ├── newapi.ts
│   │   │   │   ├── novita.ts
│   │   │   │   ├── nvidia.ts
│   │   │   │   ├── ollama.ts
│   │   │   │   ├── ollamacloud.ts
│   │   │   │   ├── openai.ts
│   │   │   │   ├── openrouter.ts
│   │   │   │   ├── perplexity.ts
│   │   │   │   ├── ppio.ts
│   │   │   │   ├── qiniu.ts
│   │   │   │   ├── qwen.ts
│   │   │   │   ├── replicate.ts
│   │   │   │   ├── sambanova.ts
│   │   │   │   ├── search1api.ts
│   │   │   │   ├── sensenova.ts
│   │   │   │   ├── siliconcloud.ts
│   │   │   │   ├── spark.ts
│   │   │   │   ├── stepfun.ts
│   │   │   │   ├── straico.ts
│   │   │   │   ├── taichu.ts
│   │   │   │   ├── tencentcloud.ts
│   │   │   │   ├── togetherai.ts
│   │   │   │   ├── upstage.ts
│   │   │   │   ├── v0.ts
│   │   │   │   ├── vercelaigateway.ts
│   │   │   │   ├── vertexai.ts
│   │   │   │   ├── vllm.ts
│   │   │   │   ├── volcengine.ts
│   │   │   │   ├── volcengineCodingPlan.ts
│   │   │   │   ├── wenxin.ts
│   │   │   │   ├── xai.ts
│   │   │   │   ├── xiaomimimo.ts
│   │   │   │   ├── xinference.ts
│   │   │   │   ├── zenmux.ts
│   │   │   │   ├── zeroone.ts
│   │   │   │   └── zhipu.ts
│   │   │   ├── standard-parameters/
│   │   │   │   ├── index.test.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── video.test.ts
│   │   │   │   └── video.ts
│   │   │   └── types/
│   │   │       ├── aiModel.ts
│   │   │       └── index.ts
│   │   └── vitest.config.mts
│   ├── model-runtime/
│   │   ├── CLAUDE.md
│   │   ├── docs/
│   │   │   └── test-coverage.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── const/
│   │   │   │   ├── models.ts
│   │   │   │   └── type.test.ts
│   │   │   ├── core/
│   │   │   │   ├── BaseAI.ts
│   │   │   │   ├── ModelRuntime.test.ts
│   │   │   │   ├── ModelRuntime.ts
│   │   │   │   ├── RouterRuntime/
│   │   │   │   │   ├── apiTypes.ts
│   │   │   │   │   ├── baseRuntimeMap.ts
│   │   │   │   │   ├── createRuntime.test.ts
│   │   │   │   │   ├── createRuntime.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── anthropicCompatibleFactory/
│   │   │   │   │   ├── generateObject.test.ts
│   │   │   │   │   ├── generateObject.ts
│   │   │   │   │   ├── handleAnthropicError.ts
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── resolveCacheTTL.ts
│   │   │   │   │   └── resolveMaxTokens.ts
│   │   │   │   ├── contextBuilders/
│   │   │   │   │   ├── anthropic.test.ts
│   │   │   │   │   ├── anthropic.ts
│   │   │   │   │   ├── google.test.ts
│   │   │   │   │   ├── google.ts
│   │   │   │   │   ├── huggingface.test.ts
│   │   │   │   │   ├── huggingface.ts
│   │   │   │   │   ├── openai.test.ts
│   │   │   │   │   └── openai.ts
│   │   │   │   ├── openaiCompatibleFactory/
│   │   │   │   │   ├── createImage.test.ts
│   │   │   │   │   ├── createImage.ts
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── nonStreamToStream.test.ts
│   │   │   │   │   └── nonStreamToStream.ts
│   │   │   │   ├── parameterResolver.test.ts
│   │   │   │   ├── parameterResolver.ts
│   │   │   │   ├── streams/
│   │   │   │   │   ├── __snapshots__/
│   │   │   │   │   │   └── protocol.test.ts.snap
│   │   │   │   │   ├── anthropic.test.ts
│   │   │   │   │   ├── anthropic.ts
│   │   │   │   │   ├── bedrock/
│   │   │   │   │   │   ├── claude.ts
│   │   │   │   │   │   ├── common.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── llama.test.ts
│   │   │   │   │   │   └── llama.ts
│   │   │   │   │   ├── cloudflare.test.ts
│   │   │   │   │   ├── cloudflare.ts
│   │   │   │   │   ├── google/
│   │   │   │   │   │   ├── const.ts
│   │   │   │   │   │   ├── google-ai.test.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── model.test.ts
│   │   │   │   │   ├── model.ts
│   │   │   │   │   ├── ollama.test.ts
│   │   │   │   │   ├── ollama.ts
│   │   │   │   │   ├── openai/
│   │   │   │   │   │   ├── __snapshots__/
│   │   │   │   │   │   │   └── responsesStream.test.ts.snap
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── openai.test.ts
│   │   │   │   │   │   ├── openai.ts
│   │   │   │   │   │   ├── responsesStream.test.ts
│   │   │   │   │   │   └── responsesStream.ts
│   │   │   │   │   ├── protocol.test.ts
│   │   │   │   │   ├── protocol.ts
│   │   │   │   │   ├── qwen.test.ts
│   │   │   │   │   ├── qwen.ts
│   │   │   │   │   ├── spark.test.ts
│   │   │   │   │   ├── spark.ts
│   │   │   │   │   ├── utils.test.ts
│   │   │   │   │   ├── utils.ts
│   │   │   │   │   └── vertex-ai.test.ts
│   │   │   │   └── usageConverters/
│   │   │   │       ├── anthropic.test.ts
│   │   │   │       ├── anthropic.ts
│   │   │   │       ├── google-ai.test.ts
│   │   │   │       ├── google-ai.ts
│   │   │   │       ├── index.ts
│   │   │   │       ├── openai.test.ts
│   │   │   │       ├── openai.ts
│   │   │   │       └── utils/
│   │   │   │           ├── computeChatCost.test.ts
│   │   │   │           ├── computeChatCost.ts
│   │   │   │           ├── computeImageCost.test.ts
│   │   │   │           ├── computeImageCost.ts
│   │   │   │           ├── computeVideoCost.test.ts
│   │   │   │           ├── computeVideoCost.ts
│   │   │   │           ├── index.ts
│   │   │   │           ├── resolveImageSinglePrice.ts
│   │   │   │           ├── resolveVideoSinglePrice.test.ts
│   │   │   │           ├── resolveVideoSinglePrice.ts
│   │   │   │           └── withUsageCost.ts
│   │   │   ├── helpers/
│   │   │   │   ├── index.ts
│   │   │   │   ├── mergeChatMethodOptions.test.ts
│   │   │   │   ├── mergeChatMethodOptions.ts
│   │   │   │   ├── parseToolCalls.test.ts
│   │   │   │   └── parseToolCalls.ts
│   │   │   ├── index.ts
│   │   │   ├── providerTestUtils.test.ts
│   │   │   ├── providerTestUtils.ts
│   │   │   ├── providers/
│   │   │   │   ├── ai21/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── ai302/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── ai360/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── aihubmix/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── akashchat/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── anthropic/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── azureOpenai/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── azureai/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── baichuan/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── bailianCodingPlan/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── bedrock/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── bfl/
│   │   │   │   │   ├── createImage.test.ts
│   │   │   │   │   ├── createImage.ts
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── types.ts
│   │   │   │   ├── cerebras/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── cloudflare/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── cohere/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── cometapi/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── comfyui/
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   └── index.test.ts
│   │   │   │   │   ├── auth/
│   │   │   │   │   │   └── AuthManager.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── deepseek/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── fal/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── fireworksai/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── giteeai/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── github/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── githubCopilot/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── glmCodingPlan/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── google/
│   │   │   │   │   ├── createImage.test.ts
│   │   │   │   │   ├── createImage.ts
│   │   │   │   │   ├── generateObject.test.ts
│   │   │   │   │   ├── generateObject.ts
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── thinkingResolver.test.ts
│   │   │   │   │   └── thinkingResolver.ts
│   │   │   │   ├── groq/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── higress/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── huggingface/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── type.ts
│   │   │   │   ├── hunyuan/
│   │   │   │   │   ├── createImage.test.ts
│   │   │   │   │   ├── createImage.ts
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── infiniai/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── internlm/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── jina/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── kimiCodingPlan/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── lmstudio/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── lobehub/
│   │   │   │   │   └── index.ts
│   │   │   │   ├── longcat/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── minimax/
│   │   │   │   │   ├── createImage.test.ts
│   │   │   │   │   ├── createImage.ts
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── minimaxCodingPlan/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── mistral/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── modelscope/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── moonshot/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── nebius/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── newapi/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── novita/
│   │   │   │   │   ├── __snapshots__/
│   │   │   │   │   │   └── index.test.ts.snap
│   │   │   │   │   ├── fixtures/
│   │   │   │   │   │   └── models.json
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── type.ts
│   │   │   │   ├── nvidia/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── ollama/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── type.ts
│   │   │   │   ├── ollamacloud/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── openai/
│   │   │   │   │   ├── fixtures/
│   │   │   │   │   │   └── openai-models.json
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── openrouter/
│   │   │   │   │   ├── fixtures/
│   │   │   │   │   │   ├── frontendModels.json
│   │   │   │   │   │   └── models.json
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── type.ts
│   │   │   │   ├── perplexity/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── ppio/
│   │   │   │   │   ├── __snapshots__/
│   │   │   │   │   │   └── index.test.ts.snap
│   │   │   │   │   ├── fixtures/
│   │   │   │   │   │   └── models.json
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── type.ts
│   │   │   │   ├── qiniu/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── qwen/
│   │   │   │   │   ├── createImage.test.ts
│   │   │   │   │   ├── createImage.ts
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── replicate/
│   │   │   │   │   └── index.ts
│   │   │   │   ├── sambanova/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── search1api/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── sensenova/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── siliconcloud/
│   │   │   │   │   ├── createImage.ts
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── spark/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── stepfun/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── straico/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── type.ts
│   │   │   │   ├── taichu/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── tencentcloud/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── togetherai/
│   │   │   │   │   ├── fixtures/
│   │   │   │   │   │   └── models.json
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── type.ts
│   │   │   │   ├── upstage/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── v0/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── vercelaigateway/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── vertexai/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── vllm/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── volcengine/
│   │   │   │   │   ├── createImage.test.ts
│   │   │   │   │   ├── createImage.ts
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── video/
│   │   │   │   │       ├── createVideo.test.ts
│   │   │   │   │       ├── createVideo.ts
│   │   │   │   │       ├── handleCreateVideoWebhook.test.ts
│   │   │   │   │       └── handleCreateVideoWebhook.ts
│   │   │   │   ├── volcengineCodingPlan/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── wenxin/
│   │   │   │   │   ├── createImage.test.ts
│   │   │   │   │   ├── createImage.ts
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── xai/
│   │   │   │   │   ├── createImage.test.ts
│   │   │   │   │   ├── createImage.ts
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── xiaomimimo/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── xinference/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── zenmux/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── zeroone/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   └── zhipu/
│   │   │   │       ├── index.test.ts
│   │   │   │       └── index.ts
│   │   │   ├── runtimeMap.ts
│   │   │   ├── types/
│   │   │   │   ├── chat.ts
│   │   │   │   ├── embeddings.ts
│   │   │   │   ├── error.ts
│   │   │   │   ├── image.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── model.ts
│   │   │   │   ├── structureOutput.ts
│   │   │   │   ├── toolsCalling.ts
│   │   │   │   ├── tts.ts
│   │   │   │   ├── type.ts
│   │   │   │   └── video.ts
│   │   │   └── utils/
│   │   │       ├── asyncifyPolling.test.ts
│   │   │       ├── asyncifyPolling.ts
│   │   │       ├── comfyuiErrorParser.test.ts
│   │   │       ├── comfyuiErrorParser.ts
│   │   │       ├── consumeStream.test.ts
│   │   │       ├── consumeStream.ts
│   │   │       ├── createError.test.ts
│   │   │       ├── createError.ts
│   │   │       ├── debugStream.test.ts
│   │   │       ├── debugStream.ts
│   │   │       ├── desensitizeUrl.test.ts
│   │   │       ├── desensitizeUrl.ts
│   │   │       ├── errorResponse.test.ts
│   │   │       ├── errorResponse.ts
│   │   │       ├── getFallbackModelProperty.test.ts
│   │   │       ├── getFallbackModelProperty.ts
│   │   │       ├── getModelMaxOutputs.test.ts
│   │   │       ├── getModelMaxOutputs.ts
│   │   │       ├── getModelPricing.ts
│   │   │       ├── googleErrorParser.test.ts
│   │   │       ├── googleErrorParser.ts
│   │   │       ├── handleOpenAIError.test.ts
│   │   │       ├── handleOpenAIError.ts
│   │   │       ├── isExceededContextWindowError.test.ts
│   │   │       ├── isExceededContextWindowError.ts
│   │   │       ├── isQuotaLimitError.test.ts
│   │   │       ├── isQuotaLimitError.ts
│   │   │       ├── modelParse.test.ts
│   │   │       ├── modelParse.ts
│   │   │       ├── postProcessModelList.test.ts
│   │   │       ├── postProcessModelList.ts
│   │   │       ├── response.test.ts
│   │   │       ├── response.ts
│   │   │       ├── safeParseJSON.test.ts
│   │   │       ├── safeParseJSON.ts
│   │   │       ├── sanitizeError.test.ts
│   │   │       ├── sanitizeError.ts
│   │   │       ├── uriParser.test.ts
│   │   │       ├── uriParser.ts
│   │   │       └── uuid.ts
│   │   └── vitest.config.mts
│   ├── observability-otel/
│   │   ├── package.json
│   │   └── src/
│   │       ├── api.ts
│   │       ├── gen-ai/
│   │       │   ├── index.ts
│   │       │   └── semconv.ts
│   │       ├── modules/
│   │       │   ├── index.ts
│   │       │   ├── memory-user-memory/
│   │       │   │   ├── extract.ts
│   │       │   │   └── index.ts
│   │       │   └── upstash-workflow/
│   │       │       └── index.ts
│   │       ├── node.ts
│   │       └── trpc/
│   │           ├── convention.ts
│   │           ├── index.test.ts
│   │           ├── index.ts
│   │           └── metrics.ts
│   ├── openapi/
│   │   ├── package.json
│   │   ├── scripts/
│   │   │   ├── .gitignore
│   │   │   └── compliance-test.sh
│   │   └── src/
│   │       ├── app.ts
│   │       ├── common/
│   │       │   ├── base.controller.ts
│   │       │   └── base.service.ts
│   │       ├── controllers/
│   │       │   ├── agent-group.controller.ts
│   │       │   ├── agent.controller.ts
│   │       │   ├── chat.controller.ts
│   │       │   ├── file.controller.ts
│   │       │   ├── index.ts
│   │       │   ├── knowledge-base.controller.ts
│   │       │   ├── message-translation.controller.ts
│   │       │   ├── message.controller.ts
│   │       │   ├── model.controller.ts
│   │       │   ├── permission.controller.ts
│   │       │   ├── provider.controller.ts
│   │       │   ├── responses.controller.ts
│   │       │   ├── role.controller.ts
│   │       │   ├── topic.controller.ts
│   │       │   └── user.controller.ts
│   │       ├── helpers/
│   │       │   ├── file.ts
│   │       │   ├── pagination.ts
│   │       │   ├── permission.ts
│   │       │   └── translate.ts
│   │       ├── index.ts
│   │       ├── middleware/
│   │       │   ├── auth.ts
│   │       │   ├── index.ts
│   │       │   └── permission-check.ts
│   │       ├── routes/
│   │       │   ├── agent-groups.route.ts
│   │       │   ├── agents.route.ts
│   │       │   ├── files.route.ts
│   │       │   ├── index.ts
│   │       │   ├── knowledge-bases.route.ts
│   │       │   ├── message-translations.route.ts
│   │       │   ├── messages.route.ts
│   │       │   ├── models.route.ts
│   │       │   ├── permissions.route.ts
│   │       │   ├── providers.route.ts
│   │       │   ├── responses.route.ts
│   │       │   ├── roles.route.ts
│   │       │   ├── topics.route.ts
│   │       │   └── users.route.ts
│   │       ├── services/
│   │       │   ├── agent-group.service.ts
│   │       │   ├── agent.service.ts
│   │       │   ├── chat.service.ts
│   │       │   ├── file.service.ts
│   │       │   ├── index.ts
│   │       │   ├── knowledge-base.service.ts
│   │       │   ├── message-translations.service.ts
│   │       │   ├── message.service.ts
│   │       │   ├── model.service.ts
│   │       │   ├── permission.service.ts
│   │       │   ├── provider.service.ts
│   │       │   ├── responses.service.ts
│   │       │   ├── role.service.ts
│   │       │   ├── topic.service.ts
│   │       │   └── user.service.ts
│   │       └── types/
│   │           ├── agent-group.type.ts
│   │           ├── agent.type.ts
│   │           ├── chat.type.ts
│   │           ├── common.type.ts
│   │           ├── file.type.ts
│   │           ├── index.ts
│   │           ├── knowledge-base.type.ts
│   │           ├── message-translations.type.ts
│   │           ├── message.type.ts
│   │           ├── model.type.ts
│   │           ├── permission.type.ts
│   │           ├── provider.type.ts
│   │           ├── responses.type.ts
│   │           ├── role.type.ts
│   │           ├── topic.type.ts
│   │           └── user.type.ts
│   ├── prompts/
│   │   ├── .gitignore
│   │   ├── CLAUDE.md
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── promptfoo/
│   │   │   ├── abstract-chunk/
│   │   │   │   ├── eval.yaml
│   │   │   │   └── prompt.ts
│   │   │   ├── emoji-picker/
│   │   │   │   ├── eval.yaml
│   │   │   │   └── prompt.ts
│   │   │   ├── knowledge-qa/
│   │   │   │   ├── eval.yaml
│   │   │   │   └── prompt.ts
│   │   │   ├── language-detection/
│   │   │   │   ├── eval.yaml
│   │   │   │   └── prompt.ts
│   │   │   ├── summary-title/
│   │   │   │   ├── eval.yaml
│   │   │   │   └── prompt.ts
│   │   │   ├── supervisor/
│   │   │   │   └── productive/
│   │   │   │       ├── eval.yaml
│   │   │   │       ├── prompt.ts
│   │   │   │       ├── tests/
│   │   │   │       │   ├── basic-case.ts
│   │   │   │       │   └── role.ts
│   │   │   │       └── tools.json
│   │   │   └── translate/
│   │   │       ├── eval.yaml
│   │   │       └── prompt.ts
│   │   ├── promptfooconfig.yaml
│   │   ├── src/
│   │   │   ├── agents/
│   │   │   │   ├── __snapshots__/
│   │   │   │   │   └── pageContentContext.test.ts.snap
│   │   │   │   ├── index.ts
│   │   │   │   ├── pageContentContext.test.ts
│   │   │   │   ├── pageContentContext.ts
│   │   │   │   └── pageSelectionContext.ts
│   │   │   ├── chains/
│   │   │   │   ├── __tests__/
│   │   │   │   │   ├── __snapshots__/
│   │   │   │   │   │   ├── abstractChunk.test.ts.snap
│   │   │   │   │   │   ├── answerWithContext.test.ts.snap
│   │   │   │   │   │   ├── pickEmoji.test.ts.snap
│   │   │   │   │   │   ├── summaryHistory.test.ts.snap
│   │   │   │   │   │   ├── summaryTitle.test.ts.snap
│   │   │   │   │   │   └── translate.test.ts.snap
│   │   │   │   │   ├── abstractChunk.test.ts
│   │   │   │   │   ├── answerWithContext.test.ts
│   │   │   │   │   ├── langDetect.test.ts
│   │   │   │   │   ├── pickEmoji.test.ts
│   │   │   │   │   ├── rewriteQuery.test.ts
│   │   │   │   │   ├── summaryAgentName.test.ts
│   │   │   │   │   ├── summaryDescription.test.ts
│   │   │   │   │   ├── summaryGenerationTitle.test.ts
│   │   │   │   │   ├── summaryHistory.test.ts
│   │   │   │   │   ├── summaryTags.test.ts
│   │   │   │   │   ├── summaryTitle.test.ts
│   │   │   │   │   └── translate.test.ts
│   │   │   │   ├── abstractChunk.ts
│   │   │   │   ├── answerWithContext.ts
│   │   │   │   ├── compressContext.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── langDetect.ts
│   │   │   │   ├── pickEmoji.ts
│   │   │   │   ├── rewriteQuery.ts
│   │   │   │   ├── summaryAgentName.ts
│   │   │   │   ├── summaryDescription.ts
│   │   │   │   ├── summaryGenerationTitle.ts
│   │   │   │   ├── summaryHistory.ts
│   │   │   │   ├── summaryTags.ts
│   │   │   │   ├── summaryTitle.ts
│   │   │   │   ├── taskTopicHandoff.ts
│   │   │   │   └── translate.ts
│   │   │   ├── contexts/
│   │   │   │   ├── index.ts
│   │   │   │   └── supervisor/
│   │   │   │       ├── index.ts
│   │   │   │       ├── makeDecision.ts
│   │   │   │       └── tools.ts
│   │   │   ├── index.test.ts
│   │   │   ├── index.ts
│   │   │   └── prompts/
│   │   │       ├── agentBuilder/
│   │   │       │   ├── index.ts
│   │   │       │   ├── modelsResultsPrompt.ts
│   │   │       │   └── toolsResultsPrompt.ts
│   │   │       ├── agentGroup/
│   │   │       │   ├── __snapshots__/
│   │   │       │   │   └── index.test.ts.snap
│   │   │       │   ├── agentProfile.ts
│   │   │       │   ├── groupContext.ts
│   │   │       │   ├── index.test.ts
│   │   │       │   └── index.ts
│   │   │       ├── botPlatformContext/
│   │   │       │   └── index.ts
│   │   │       ├── chatMessages/
│   │   │       │   ├── index.test.ts
│   │   │       │   └── index.ts
│   │   │       ├── compressContext/
│   │   │       │   └── index.ts
│   │   │       ├── discordContext/
│   │   │       │   └── index.ts
│   │   │       ├── fileSystem/
│   │   │       │   ├── formatCommandOutput.test.ts
│   │   │       │   ├── formatCommandOutput.ts
│   │   │       │   ├── formatCommandResult.test.ts
│   │   │       │   ├── formatCommandResult.ts
│   │   │       │   ├── formatEditResult.test.ts
│   │   │       │   ├── formatEditResult.ts
│   │   │       │   ├── formatFileContent.test.ts
│   │   │       │   ├── formatFileContent.ts
│   │   │       │   ├── formatFileList.test.ts
│   │   │       │   ├── formatFileList.ts
│   │   │       │   ├── formatFileSearchResults.test.ts
│   │   │       │   ├── formatFileSearchResults.ts
│   │   │       │   ├── formatGlobResults.test.ts
│   │   │       │   ├── formatGlobResults.ts
│   │   │       │   ├── formatGrepResults.test.ts
│   │   │       │   ├── formatGrepResults.ts
│   │   │       │   ├── formatKillResult.test.ts
│   │   │       │   ├── formatKillResult.ts
│   │   │       │   ├── formatMoveResults.test.ts
│   │   │       │   ├── formatMoveResults.ts
│   │   │       │   ├── formatMultipleFiles.test.ts
│   │   │       │   ├── formatMultipleFiles.ts
│   │   │       │   ├── formatRenameResult.test.ts
│   │   │       │   ├── formatRenameResult.ts
│   │   │       │   ├── formatWriteResult.test.ts
│   │   │       │   ├── formatWriteResult.ts
│   │   │       │   └── index.ts
│   │   │       ├── files/
│   │   │       │   ├── __snapshots__/
│   │   │       │   │   └── knowledgeBase.test.ts.snap
│   │   │       │   ├── file.ts
│   │   │       │   ├── image.ts
│   │   │       │   ├── index.test.ts
│   │   │       │   ├── index.ts
│   │   │       │   ├── knowledgeBase.test.ts
│   │   │       │   ├── knowledgeBase.ts
│   │   │       │   └── video.ts
│   │   │       ├── groupChat/
│   │   │       │   ├── __snapshots__/
│   │   │       │   │   └── index.test.ts.snap
│   │   │       │   ├── index.test.ts
│   │   │       │   └── index.ts
│   │   │       ├── gtd/
│   │   │       │   ├── index.test.ts
│   │   │       │   └── index.ts
│   │   │       ├── index.ts
│   │   │       ├── knowledgeBaseQA/
│   │   │       │   ├── __snapshots__/
│   │   │       │   │   ├── formatFileContents.test.ts.snap
│   │   │       │   │   ├── formatNoSearchResults.test.ts.snap
│   │   │       │   │   ├── formatSearchResults.test.ts.snap
│   │   │       │   │   └── index.test.ts.snap
│   │   │       │   ├── chunk.ts
│   │   │       │   ├── formatFileContents.test.ts
│   │   │       │   ├── formatFileContents.ts
│   │   │       │   ├── formatNoSearchResults.test.ts
│   │   │       │   ├── formatNoSearchResults.ts
│   │   │       │   ├── formatSearchResults.test.ts
│   │   │       │   ├── formatSearchResults.ts
│   │   │       │   ├── index.test.ts
│   │   │       │   ├── index.ts
│   │   │       │   ├── knowledge.ts
│   │   │       │   └── userQuery.ts
│   │   │       ├── messagesToText/
│   │   │       │   ├── __snapshots__/
│   │   │       │   │   └── index.test.ts.snap
│   │   │       │   ├── index.test.ts
│   │   │       │   └── index.ts
│   │   │       ├── plugin/
│   │   │       │   ├── index.test.ts
│   │   │       │   ├── index.ts
│   │   │       │   ├── tools.test.ts
│   │   │       │   └── tools.ts
│   │   │       ├── remoteDevice/
│   │   │       │   └── index.ts
│   │   │       ├── search/
│   │   │       │   ├── crawlResults.test.ts
│   │   │       │   ├── crawlResults.ts
│   │   │       │   ├── index.ts
│   │   │       │   ├── searchResults.test.ts
│   │   │       │   ├── searchResults.ts
│   │   │       │   └── xmlEscape.ts
│   │   │       ├── skills/
│   │   │       │   ├── index.test.ts
│   │   │       │   ├── index.ts
│   │   │       │   └── resourcesTree.ts
│   │   │       ├── speaker/
│   │   │       │   └── index.ts
│   │   │       ├── systemRole/
│   │   │       │   ├── index.test.ts
│   │   │       │   └── index.ts
│   │   │       ├── task/
│   │   │       │   ├── __snapshots__/
│   │   │       │   │   └── index.test.ts.snap
│   │   │       │   ├── index.test.ts
│   │   │       │   └── index.ts
│   │   │       ├── toolDiscovery/
│   │   │       │   └── index.ts
│   │   │       └── userMemory/
│   │   │           ├── __snapshots__/
│   │   │           │   ├── formatSearchResults.test.ts.snap
│   │   │           │   └── index.test.ts.snap
│   │   │           ├── formatSearchResults.test.ts
│   │   │           ├── formatSearchResults.ts
│   │   │           ├── index.test.ts
│   │   │           └── index.ts
│   │   └── vitest.config.mts
│   ├── python-interpreter/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── __tests__/
│   │   │   │   ├── interpreter.test.ts
│   │   │   │   └── worker.test.ts
│   │   │   ├── index.ts
│   │   │   ├── interpreter.ts
│   │   │   ├── types.ts
│   │   │   └── worker.ts
│   │   └── vitest.config.mts
│   ├── ssrf-safe-fetch/
│   │   ├── index.browser.ts
│   │   ├── index.test.ts
│   │   ├── index.ts
│   │   ├── package.json
│   │   └── vitest.config.mts
│   ├── types/
│   │   ├── package.json
│   │   └── src/
│   │       ├── agent/
│   │       │   ├── agencyConfig.ts
│   │       │   ├── agentConfig.ts
│   │       │   ├── chatConfig.ts
│   │       │   ├── index.ts
│   │       │   ├── item.ts
│   │       │   └── tts.ts
│   │       ├── agentCronJob/
│   │       │   └── index.ts
│   │       ├── agentExecution/
│   │       │   └── index.ts
│   │       ├── agentGroup/
│   │       │   └── index.ts
│   │       ├── agentRuntime.ts
│   │       ├── aiChat.ts
│   │       ├── aiProvider.ts
│   │       ├── apiKey.ts
│   │       ├── artifact.ts
│   │       ├── asyncTask.ts
│   │       ├── auth.ts
│   │       ├── brief/
│   │       │   └── index.ts
│   │       ├── changelog.ts
│   │       ├── chunk/
│   │       │   ├── document.ts
│   │       │   └── index.ts
│   │       ├── clientDB.ts
│   │       ├── conversation.ts
│   │       ├── creds/
│   │       │   └── index.ts
│   │       ├── discover/
│   │       │   ├── assistants.ts
│   │       │   ├── fork.ts
│   │       │   ├── groupAgents.ts
│   │       │   ├── index.ts
│   │       │   ├── mcp.ts
│   │       │   ├── models.ts
│   │       │   ├── plugins.ts
│   │       │   ├── providers.ts
│   │       │   └── skills.ts
│   │       ├── document/
│   │       │   └── index.ts
│   │       ├── eval/
│   │       │   ├── agentEval.ts
│   │       │   ├── agentEvalDataset.ts
│   │       │   ├── agentEvalRun.ts
│   │       │   ├── benchmark.ts
│   │       │   ├── dataset.ts
│   │       │   ├── evaluation.ts
│   │       │   ├── index.ts
│   │       │   ├── ragas.ts
│   │       │   └── rubric.ts
│   │       ├── export.ts
│   │       ├── exportConfig.ts
│   │       ├── fetch.ts
│   │       ├── files/
│   │       │   ├── index.ts
│   │       │   ├── list.ts
│   │       │   └── upload.ts
│   │       ├── generation/
│   │       │   └── index.ts
│   │       ├── home.ts
│   │       ├── hotkey.ts
│   │       ├── importer.ts
│   │       ├── index.ts
│   │       ├── knowledgeBase/
│   │       │   └── index.ts
│   │       ├── llm.ts
│   │       ├── message/
│   │       │   ├── common/
│   │       │   │   ├── base.ts
│   │       │   │   ├── image.ts
│   │       │   │   ├── index.ts
│   │       │   │   ├── messageGroup.ts
│   │       │   │   ├── metadata.ts
│   │       │   │   ├── pageSelection.ts
│   │       │   │   ├── tools.ts
│   │       │   │   └── translate.ts
│   │       │   ├── db/
│   │       │   │   ├── index.ts
│   │       │   │   ├── item.ts
│   │       │   │   └── params.ts
│   │       │   ├── index.ts
│   │       │   └── ui/
│   │       │       ├── chat.ts
│   │       │       ├── extra.ts
│   │       │       ├── index.ts
│   │       │       ├── params.ts
│   │       │       ├── rag.ts
│   │       │       └── video.ts
│   │       ├── meta.ts
│   │       ├── openai/
│   │       │   ├── chat.ts
│   │       │   ├── functionCall.ts
│   │       │   ├── image.ts
│   │       │   └── plugin.ts
│   │       ├── plugins/
│   │       │   ├── index.ts
│   │       │   ├── mcp.ts
│   │       │   ├── mcpDeps.ts
│   │       │   └── protocol.ts
│   │       ├── rag.ts
│   │       ├── search.ts
│   │       ├── serverConfig.ts
│   │       ├── service.ts
│   │       ├── session/
│   │       │   ├── agentSession.ts
│   │       │   ├── index.ts
│   │       │   └── sessionGroup.ts
│   │       ├── skill/
│   │       │   └── index.ts
│   │       ├── stepContext.ts
│   │       ├── subscription.ts
│   │       ├── task/
│   │       │   └── index.ts
│   │       ├── tool/
│   │       │   ├── builtin.ts
│   │       │   ├── crawler.ts
│   │       │   ├── dalle.ts
│   │       │   ├── index.ts
│   │       │   ├── interpreter.ts
│   │       │   ├── intervention.ts
│   │       │   ├── plugin.ts
│   │       │   ├── search/
│   │       │   │   └── index.ts
│   │       │   └── tool.ts
│   │       ├── topic/
│   │       │   ├── index.ts
│   │       │   ├── thread.ts
│   │       │   └── topic.ts
│   │       ├── trace/
│   │       │   ├── action.ts
│   │       │   ├── enum.ts
│   │       │   └── index.ts
│   │       ├── usage/
│   │       │   └── usageRecord.ts
│   │       ├── user/
│   │       │   ├── agentOnboarding.test.ts
│   │       │   ├── agentOnboarding.ts
│   │       │   ├── index.ts
│   │       │   ├── onboarding.ts
│   │       │   ├── preference.ts
│   │       │   └── settings/
│   │       │       ├── filesConfig.ts
│   │       │       ├── general.ts
│   │       │       ├── hotkey.ts
│   │       │       ├── image.ts
│   │       │       ├── index.ts
│   │       │       ├── keyVaults.ts
│   │       │       ├── market.ts
│   │       │       ├── memory.ts
│   │       │       ├── modelProvider.ts
│   │       │       ├── notification.ts
│   │       │       ├── sync.ts
│   │       │       ├── systemAgent.ts
│   │       │       ├── tool.ts
│   │       │       └── tts.ts
│   │       ├── userMemory/
│   │       │   ├── activity.ts
│   │       │   ├── base.ts
│   │       │   ├── experience.ts
│   │       │   ├── identity.ts
│   │       │   ├── index.ts
│   │       │   ├── layers.ts
│   │       │   ├── list.ts
│   │       │   ├── server.ts
│   │       │   ├── shared.ts
│   │       │   ├── tools.ts
│   │       │   └── trace.ts
│   │       ├── util.ts
│   │       └── zustand.ts
│   ├── utils/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── apiKey.test.ts
│   │   │   ├── apiKey.ts
│   │   │   ├── base64.test.ts
│   │   │   ├── base64.ts
│   │   │   ├── chunkers/
│   │   │   │   ├── index.ts
│   │   │   │   └── trimBatchProbe/
│   │   │   │       ├── index.ts
│   │   │   │       ├── trimBatchProbe.test.ts
│   │   │   │       └── trimBatchProbe.ts
│   │   │   ├── client/
│   │   │   │   ├── apiKeyManager.test.ts
│   │   │   │   ├── apiKeyManager.ts
│   │   │   │   ├── clipboard.ts
│   │   │   │   ├── cookie.test.ts
│   │   │   │   ├── cookie.ts
│   │   │   │   ├── downloadFile.ts
│   │   │   │   ├── exportFile.ts
│   │   │   │   ├── fetchEventSource/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── parse.ts
│   │   │   │   ├── imageDimensions.test.ts
│   │   │   │   ├── imageDimensions.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── sanitize.test.ts
│   │   │   │   ├── sanitize.ts
│   │   │   │   ├── topic.test.ts
│   │   │   │   ├── topic.ts
│   │   │   │   ├── videoValidation.test.ts
│   │   │   │   ├── videoValidation.ts
│   │   │   │   ├── xor-obfuscation.test.ts
│   │   │   │   └── xor-obfuscation.ts
│   │   │   ├── clientIP.test.ts
│   │   │   ├── clientIP.ts
│   │   │   ├── colorUtils.test.ts
│   │   │   ├── colorUtils.ts
│   │   │   ├── compass.ts
│   │   │   ├── compressImage.test.ts
│   │   │   ├── compressImage.ts
│   │   │   ├── dedupeBy.test.ts
│   │   │   ├── dedupeBy.ts
│   │   │   ├── detectChinese.test.ts
│   │   │   ├── detectChinese.ts
│   │   │   ├── difference.test.ts
│   │   │   ├── difference.ts
│   │   │   ├── env.ts
│   │   │   ├── error.test.ts
│   │   │   ├── error.ts
│   │   │   ├── esm/
│   │   │   │   └── unwrapESMModule.ts
│   │   │   ├── folderStructure.test.ts
│   │   │   ├── folderStructure.ts
│   │   │   ├── format.test.ts
│   │   │   ├── format.ts
│   │   │   ├── genOG.test.ts
│   │   │   ├── genOG.ts
│   │   │   ├── imageToBase64.test.ts
│   │   │   ├── imageToBase64.ts
│   │   │   ├── index.ts
│   │   │   ├── isChunkingUnsupported.test.ts
│   │   │   ├── isChunkingUnsupported.ts
│   │   │   ├── keyboard.test.ts
│   │   │   ├── keyboard.ts
│   │   │   ├── localStorage.ts
│   │   │   ├── merge.test.ts
│   │   │   ├── merge.ts
│   │   │   ├── mimeType.test.ts
│   │   │   ├── mimeType.ts
│   │   │   ├── multimodalContent.test.ts
│   │   │   ├── multimodalContent.ts
│   │   │   ├── number.test.ts
│   │   │   ├── number.ts
│   │   │   ├── object.test.ts
│   │   │   ├── object.ts
│   │   │   ├── parseMarkdown.ts
│   │   │   ├── platform.test.ts
│   │   │   ├── platform.ts
│   │   │   ├── pricing.test.ts
│   │   │   ├── pricing.ts
│   │   │   ├── promptTemplate.test.ts
│   │   │   ├── promptTemplate.ts
│   │   │   ├── safeParseJSON.test.ts
│   │   │   ├── safeParseJSON.ts
│   │   │   ├── sanitizeNullBytes.test.ts
│   │   │   ├── sanitizeNullBytes.ts
│   │   │   ├── sanitizeUTF8.test.ts
│   │   │   ├── sanitizeUTF8.ts
│   │   │   ├── server/
│   │   │   │   ├── __tests__/
│   │   │   │   │   ├── auth.test.ts
│   │   │   │   │   ├── response.test.ts
│   │   │   │   │   └── sse.test.ts
│   │   │   │   ├── apiKeyHash.ts
│   │   │   │   ├── auth.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── response.ts
│   │   │   │   ├── responsive.ts
│   │   │   │   ├── sse.ts
│   │   │   │   ├── xor.test.ts
│   │   │   │   └── xor.ts
│   │   │   ├── sleep.ts
│   │   │   ├── storeDebug.test.ts
│   │   │   ├── storeDebug.ts
│   │   │   ├── time.test.ts
│   │   │   ├── time.ts
│   │   │   ├── tokenizer/
│   │   │   │   └── index.ts
│   │   │   ├── toolManifest.ts
│   │   │   ├── trace.test.ts
│   │   │   ├── trace.ts
│   │   │   ├── units.ts
│   │   │   ├── uploadFIle.ts
│   │   │   ├── uriParser.test.ts
│   │   │   ├── uriParser.ts
│   │   │   ├── url.test.ts
│   │   │   ├── url.ts
│   │   │   ├── uuid.ts
│   │   │   ├── videoToBase64.test.ts
│   │   │   └── videoToBase64.ts
│   │   ├── tests/
│   │   │   └── setup.ts
│   │   └── vitest.config.mts
│   └── web-crawler/
│       ├── README.md
│       ├── README.zh-CN.md
│       ├── package.json
│       ├── src/
│       │   ├── __tests__/
│       │   │   ├── crawler.test.ts
│       │   │   └── urlRules.test.ts
│       │   ├── crawImpl/
│       │   │   ├── __tests__/
│       │   │   │   ├── browserless.test.ts
│       │   │   │   ├── exa.test.ts
│       │   │   │   ├── firecrawl.test.ts
│       │   │   │   ├── jina.test.ts
│       │   │   │   ├── naive.test.ts
│       │   │   │   ├── search1api.test.ts
│       │   │   │   └── tavily.test.ts
│       │   │   ├── browserless.ts
│       │   │   ├── exa.ts
│       │   │   ├── firecrawl.ts
│       │   │   ├── index.ts
│       │   │   ├── jina.ts
│       │   │   ├── naive.ts
│       │   │   ├── search1api.ts
│       │   │   └── tavily.ts
│       │   ├── crawler.ts
│       │   ├── index.ts
│       │   ├── test-utils.ts
│       │   ├── type.ts
│       │   ├── urlRules.ts
│       │   └── utils/
│       │       ├── __snapshots__/
│       │       │   └── htmlToMarkdown.test.ts.snap
│       │       ├── __tests__/
│       │       │   ├── appUrlRules.test.ts
│       │       │   ├── errorType.test.ts
│       │       │   ├── response.test.ts
│       │       │   └── withTimeout.test.ts
│       │       ├── appUrlRules.ts
│       │       ├── errorType.ts
│       │       ├── html/
│       │       │   ├── terms.html
│       │       │   └── yingchao.html
│       │       ├── htmlToMarkdown.test.ts
│       │       ├── htmlToMarkdown.ts
│       │       ├── response.ts
│       │       └── withTimeout.ts
│       ├── tsconfig.json
│       └── vitest.config.mts
├── patches/
│   ├── @swagger-api__apidom-reference.patch
│   └── @upstash__qstash.patch
├── plugins/
│   └── vite/
│       ├── emotionSpeedy.ts
│       ├── envRestartKeys.ts
│       ├── markdownImport.test.ts
│       ├── markdownImport.ts
│       ├── nodeModuleStub.ts
│       ├── platformResolve.ts
│       ├── sharedRendererConfig.ts
│       └── vercelSkewProtection.ts
├── pnpm-workspace.yaml
├── prettier.config.mjs
├── public/
│   ├── .well-known/
│   │   ├── apple-app-site-association
│   │   └── assetlinks.json
│   ├── _dangerous_local_dev_proxy.html
│   └── not-compatible.html
├── renovate.json
├── scripts/
│   ├── _shared/
│   │   ├── checkDeprecatedAuth.js
│   │   └── checkDeprecatedAuth.test.ts
│   ├── buildSitemapIndex/
│   │   └── index.ts
│   ├── cdnWorkflow/
│   │   ├── index.ts
│   │   ├── optimized.ts
│   │   ├── s3/
│   │   │   ├── index.ts
│   │   │   ├── types.ts
│   │   │   └── utils.ts
│   │   ├── uploader.ts
│   │   └── utils.ts
│   ├── changelogWorkflow/
│   │   ├── buildStaticChangelog.ts
│   │   ├── const.ts
│   │   ├── generateChangelog.ts
│   │   └── index.ts
│   ├── checkConsoleLog.mts
│   ├── clerk-to-betterauth/
│   │   ├── __tests__/
│   │   │   └── parseCsvLine.test.ts
│   │   ├── _internal/
│   │   │   ├── config.ts
│   │   │   ├── db.ts
│   │   │   ├── env.ts
│   │   │   ├── load-data-from-files.ts
│   │   │   ├── types.ts
│   │   │   └── utils.ts
│   │   ├── export-clerk-users-with-api.ts
│   │   ├── index.ts
│   │   ├── prod/
│   │   │   └── put_clerk_exported_users_csv_here.txt
│   │   ├── test/
│   │   │   └── put_clerk_exported_users_csv_here.txt
│   │   └── verify.ts
│   ├── copySpaBuild.mts
│   ├── countEnWord.ts
│   ├── dbmlWorkflow/
│   │   └── index.ts
│   ├── devStartupSequence.mts
│   ├── dockerPrebuild.mts
│   ├── docsWorkflow/
│   │   ├── autoCDN.ts
│   │   ├── const.ts
│   │   ├── index.ts
│   │   ├── optimized.ts
│   │   ├── toc.ts
│   │   └── utils.ts
│   ├── electronWorkflow/
│   │   ├── buildDesktopChannel.ts
│   │   ├── buildElectron.ts
│   │   ├── mergeMacReleaseFiles.js
│   │   └── setDesktopVersion.ts
│   ├── generate-oidc-jwk.mjs
│   ├── generateSpaTemplates.mts
│   ├── hotfixWorkflow/
│   │   └── index.ts
│   ├── i18nWorkflow/
│   │   ├── analyzeUnusedKeys.ts
│   │   ├── cleanUnusedKeys.ts
│   │   ├── const.ts
│   │   ├── flattenLocaleKeys.ts
│   │   ├── genDefaultLocale.ts
│   │   ├── genDiff.ts
│   │   ├── i18nConfig.ts
│   │   ├── index.ts
│   │   ├── protectedPatterns.ts
│   │   └── utils.ts
│   ├── mdxWorkflow/
│   │   └── index.ts
│   ├── migrate-spa-navigation.ts
│   ├── migrateServerDB/
│   │   ├── docker.cjs
│   │   ├── errorHint.js
│   │   └── index.ts
│   ├── mobileSpaWorkflow/
│   │   ├── index.ts
│   │   ├── template.ts
│   │   └── upload.ts
│   ├── nextauth-to-betterauth/
│   │   ├── _internal/
│   │   │   ├── config.ts
│   │   │   ├── db.ts
│   │   │   └── env.ts
│   │   ├── index.ts
│   │   └── verify.ts
│   ├── readmeWorkflow/
│   │   ├── const.ts
│   │   ├── index.ts
│   │   ├── syncAgentIndex.ts
│   │   ├── syncPluginIndex.ts
│   │   ├── syncProviderIndex.ts
│   │   └── utlis.ts
│   ├── registerDesktopEnv.cjs
│   ├── releaseWorkflow/
│   │   └── index.ts
│   ├── replaceComponentImports.ts
│   ├── runNextDesktop.mts
│   ├── serverLauncher/
│   │   └── startServer.js
│   ├── setup-test-postgres-db.sh
│   └── vercelIgnoredBuildStep.js
├── src/
│   ├── app/
│   │   ├── (backend)/
│   │   │   ├── _deprecated/
│   │   │   │   └── createBizOpenAI/
│   │   │   │       ├── auth.test.ts
│   │   │   │       ├── auth.ts
│   │   │   │       ├── createAzureOpenai.ts
│   │   │   │       ├── createOpenai.ts
│   │   │   │       └── index.ts
│   │   │   ├── api/
│   │   │   │   ├── agent/
│   │   │   │   │   ├── gateway/
│   │   │   │   │   │   ├── route.ts
│   │   │   │   │   │   └── start/
│   │   │   │   │   │       └── route.ts
│   │   │   │   │   ├── route.ts
│   │   │   │   │   ├── run/
│   │   │   │   │   │   └── route.ts
│   │   │   │   │   ├── stream/
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   └── route.test.ts
│   │   │   │   │   │   └── route.ts
│   │   │   │   │   └── webhooks/
│   │   │   │   │       ├── [platform]/
│   │   │   │   │       │   └── [[...appId]]/
│   │   │   │   │       │       └── route.ts
│   │   │   │   │       └── bot-callback/
│   │   │   │   │           └── route.ts
│   │   │   │   ├── auth/
│   │   │   │   │   ├── [...all]/
│   │   │   │   │   │   └── route.ts
│   │   │   │   │   ├── check-user/
│   │   │   │   │   │   └── route.ts
│   │   │   │   │   └── resolve-username/
│   │   │   │   │       └── route.ts
│   │   │   │   ├── dev/
│   │   │   │   │   └── memory-user-memory/
│   │   │   │   │       └── benchmark-locomo/
│   │   │   │   │           └── route.ts
│   │   │   │   ├── v1/
│   │   │   │   │   └── [[...route]]/
│   │   │   │   │       └── route.ts
│   │   │   │   ├── version/
│   │   │   │   │   └── route.ts
│   │   │   │   ├── webhooks/
│   │   │   │   │   ├── casdoor/
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   └── route.test.ts
│   │   │   │   │   │   ├── route.ts
│   │   │   │   │   │   └── validateRequest.ts
│   │   │   │   │   ├── logto/
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   └── route.test.ts
│   │   │   │   │   │   ├── route.ts
│   │   │   │   │   │   └── validateRequest.ts
│   │   │   │   │   ├── memory-extraction/
│   │   │   │   │   │   ├── benchmark-locomo/
│   │   │   │   │   │   │   └── route.ts
│   │   │   │   │   │   └── route.ts
│   │   │   │   │   ├── memory-user-memory/
│   │   │   │   │   │   └── persona/
│   │   │   │   │   │       └── update-writing/
│   │   │   │   │   │           └── route.ts
│   │   │   │   │   └── video/
│   │   │   │   │       └── [provider]/
│   │   │   │   │           └── route.ts
│   │   │   │   └── workflows/
│   │   │   │       ├── agent-eval-run/
│   │   │   │       │   ├── execute-test-case/
│   │   │   │       │   │   └── route.ts
│   │   │   │       │   ├── finalize-run/
│   │   │   │       │   │   └── route.ts
│   │   │   │       │   ├── on-thread-complete/
│   │   │   │       │   │   └── route.ts
│   │   │   │       │   ├── on-trajectory-complete/
│   │   │   │       │   │   └── route.ts
│   │   │   │       │   ├── paginate-test-cases/
│   │   │   │       │   │   └── route.ts
│   │   │   │       │   ├── run-agent-trajectory/
│   │   │   │       │   │   └── route.ts
│   │   │   │       │   ├── run-benchmark/
│   │   │   │       │   │   └── route.ts
│   │   │   │       │   └── run-thread-trajectory/
│   │   │   │       │       └── route.ts
│   │   │   │       └── memory-user-memory/
│   │   │   │           ├── call-cron-hourly-analysis/
│   │   │   │           │   └── route.ts
│   │   │   │           └── pipelines/
│   │   │   │               ├── chat-topic/
│   │   │   │               │   ├── [...any]/
│   │   │   │               │   │   └── route.ts
│   │   │   │               │   ├── process-topic/
│   │   │   │               │   │   └── workflows/
│   │   │   │               │   │       └── topic.ts
│   │   │   │               │   ├── process-topics/
│   │   │   │               │   │   └── route.ts
│   │   │   │               │   ├── process-user-topics/
│   │   │   │               │   │   └── route.ts
│   │   │   │               │   └── process-users/
│   │   │   │               │       └── route.ts
│   │   │   │               └── persona/
│   │   │   │                   └── update-writing/
│   │   │   │                       └── route.ts
│   │   │   ├── f/
│   │   │   │   └── [id]/
│   │   │   │       └── route.ts
│   │   │   ├── market/
│   │   │   │   ├── agent/
│   │   │   │   │   └── [[...segments]]/
│   │   │   │   │       └── route.ts
│   │   │   │   ├── oidc/
│   │   │   │   │   └── [[...segments]]/
│   │   │   │   │       └── route.ts
│   │   │   │   ├── social/
│   │   │   │   │   └── [[...segments]]/
│   │   │   │   │       └── route.ts
│   │   │   │   └── user/
│   │   │   │       ├── [username]/
│   │   │   │       │   └── route.ts
│   │   │   │       └── me/
│   │   │   │           └── route.ts
│   │   │   ├── middleware/
│   │   │   │   ├── auth/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── utils.test.ts
│   │   │   │   │   └── utils.ts
│   │   │   │   └── validate/
│   │   │   │       ├── createValidator.test.ts
│   │   │   │       ├── createValidator.ts
│   │   │   │       └── index.ts
│   │   │   ├── oidc/
│   │   │   │   ├── [...oidc]/
│   │   │   │   │   └── route.ts
│   │   │   │   ├── callback/
│   │   │   │   │   └── desktop/
│   │   │   │   │       └── route.ts
│   │   │   │   ├── consent/
│   │   │   │   │   └── route.ts
│   │   │   │   └── handoff/
│   │   │   │       └── route.ts
│   │   │   ├── trpc/
│   │   │   │   ├── async/
│   │   │   │   │   └── [trpc]/
│   │   │   │   │       └── route.ts
│   │   │   │   ├── lambda/
│   │   │   │   │   └── [trpc]/
│   │   │   │   │       └── route.ts
│   │   │   │   ├── mobile/
│   │   │   │   │   └── [trpc]/
│   │   │   │   │       └── route.ts
│   │   │   │   ├── tools/
│   │   │   │   │   └── [trpc]/
│   │   │   │   │       └── route.ts
│   │   │   │   └── trpc.test.ts
│   │   │   └── webapi/
│   │   │       ├── chat/
│   │   │       │   └── [provider]/
│   │   │       │       ├── route.test.ts
│   │   │       │       └── route.ts
│   │   │       ├── create-image/
│   │   │       │   └── comfyui/
│   │   │       │       └── route.ts
│   │   │       ├── models/
│   │   │       │   └── [provider]/
│   │   │       │       ├── pull/
│   │   │       │       │   └── route.ts
│   │   │       │       ├── route.test.ts
│   │   │       │       └── route.ts
│   │   │       ├── plugin/
│   │   │       │   └── gateway/
│   │   │       │       └── route.ts
│   │   │       ├── proxy/
│   │   │       │   └── route.ts
│   │   │       ├── revalidate/
│   │   │       │   └── route.ts
│   │   │       ├── stt/
│   │   │       │   └── openai/
│   │   │       │       └── route.ts
│   │   │       ├── trace/
│   │   │       │   └── route.ts
│   │   │       ├── tts/
│   │   │       │   ├── edge/
│   │   │       │   │   └── route.ts
│   │   │       │   ├── microsoft/
│   │   │       │   │   └── route.ts
│   │   │       │   └── openai/
│   │   │       │       └── route.ts
│   │   │       └── user/
│   │   │           └── avatar/
│   │   │               └── [id]/
│   │   │                   └── [image]/
│   │   │                       └── route.ts
│   │   ├── [variants]/
│   │   │   ├── (auth)/
│   │   │   │   ├── _layout/
│   │   │   │ 

================================================
FILE CONTENTS
================================================

================================================
FILE: .agents/skills/add-provider-doc/SKILL.md
================================================
---
name: add-provider-doc
description: Guide for adding new AI provider documentation. Use when adding documentation for a new AI provider (like OpenAI, Anthropic, etc.), including usage docs, environment variables, Docker config, and image resources. Triggers on provider documentation tasks.
---

# Adding New AI Provider Documentation

Complete workflow for adding documentation for a new AI provider.

## Overview

1. Create usage documentation (EN + CN)
2. Add environment variable documentation (EN + CN)
3. Update Docker configuration files
4. Update .env.example
5. Prepare image resources

## Step 1: Create Provider Usage Documentation

### Required Files

- `docs/usage/providers/{provider-name}.mdx` (English)
- `docs/usage/providers/{provider-name}.zh-CN.mdx` (Chinese)

### Key Requirements

- 5-6 screenshots showing the process
- Cover image for the provider
- Real registration and dashboard URLs
- Pricing information callout
- **Never include real API keys** - use placeholders

Reference: `docs/usage/providers/fal.mdx`

## Step 2: Update Environment Variables Documentation

### Files to Update

- `docs/self-hosting/environment-variables/model-provider.mdx` (EN)
- `docs/self-hosting/environment-variables/model-provider.zh-CN.mdx` (CN)

### Content Format

```markdown
### `{PROVIDER}_API_KEY`

- Type: Required
- Description: API key from {Provider Name}
- Example: `{api-key-format}`

### `{PROVIDER}_MODEL_LIST`

- Type: Optional
- Description: Control model list. Use `+` to add, `-` to hide
- Example: `-all,+model-1,+model-2=Display Name`
```

## Step 3: Update Docker Files

Update all Dockerfiles at the **end** of ENV section:

- `Dockerfile`
- `Dockerfile.database`
- `Dockerfile.pglite`

```dockerfile
# {New Provider}
{PROVIDER}_API_KEY="" {PROVIDER}_MODEL_LIST=""
```

## Step 4: Update .env.example

```bash
### {Provider Name} ###
# {PROVIDER}_API_KEY={prefix}-xxxxxxxx
```

## Step 5: Image Resources

- Cover image
- 3-4 API dashboard screenshots
- 2-3 LobeHub configuration screenshots
- Host on LobeHub CDN: `hub-apac-1.lobeobjects.space`

## Checklist

- [ ] EN + CN usage docs
- [ ] EN + CN env var docs
- [ ] All 3 Dockerfiles updated
- [ ] .env.example updated
- [ ] All images prepared
- [ ] No real API keys in docs


================================================
FILE: .agents/skills/add-setting-env/SKILL.md
================================================
---
name: add-setting-env
description: Guide for adding environment variables to configure user settings. Use when implementing server-side environment variables that control default values for user settings. Triggers on env var configuration or setting default value tasks.
---

# Adding Environment Variable for User Settings

Add server-side environment variables to configure default values for user settings.

**Priority**: User Custom > Server Env Var > Hardcoded Default

## Steps

### 1. Define Environment Variable

Create `src/envs/<domain>.ts`:

```typescript
import { createEnv } from '@t3-oss/env-nextjs';
import { z } from 'zod';

export const get<Domain>Config = () => {
  return createEnv({
    server: {
      YOUR_ENV_VAR: z.coerce.number().min(MIN).max(MAX).optional(),
    },
    runtimeEnv: {
      YOUR_ENV_VAR: process.env.YOUR_ENV_VAR,
    },
  });
};

export const <domain>Env = get<Domain>Config();
```

### 2. Update Type (if new domain)

Add to `packages/types/src/serverConfig.ts`:

```typescript
import { User<Domain>Config } from './user/settings';

export interface GlobalServerConfig {
  <domain>?: PartialDeep<User<Domain>Config>;
}
```

**Prefer reusing existing types** from `packages/types/src/user/settings`.

### 3. Assemble Server Config (if new domain)

In `src/server/globalConfig/index.ts`:

```typescript
import { <domain>Env } from '@/envs/<domain>';

export const getServerGlobalConfig = async () => {
  const config: GlobalServerConfig = {
    <domain>: cleanObject({
      <settingName>: <domain>Env.YOUR_ENV_VAR,
    }),
  };
  return config;
};
```

### 4. Merge to User Store (if new domain)

In `src/store/user/slices/common/action.ts`:

```typescript
const serverSettings: PartialDeep<UserSettings> = {
  <domain>: serverConfig.<domain>,
};
```

### 5. Update .env.example

```bash
# <Description> (range/options, default: X)
# YOUR_ENV_VAR=<example>
```

### 6. Update Documentation

- `docs/self-hosting/environment-variables/basic.mdx` (EN)
- `docs/self-hosting/environment-variables/basic.zh-CN.mdx` (CN)

## Example: AI_IMAGE_DEFAULT_IMAGE_NUM

```typescript
// src/envs/image.ts
AI_IMAGE_DEFAULT_IMAGE_NUM: z.coerce.number().min(1).max(20).optional(),

// packages/types/src/serverConfig.ts
image?: PartialDeep<UserImageConfig>;

// src/server/globalConfig/index.ts
image: cleanObject({ defaultImageNum: imageEnv.AI_IMAGE_DEFAULT_IMAGE_NUM }),

// src/store/user/slices/common/action.ts
image: serverConfig.image,

// .env.example
# AI_IMAGE_DEFAULT_IMAGE_NUM=4
```


================================================
FILE: .agents/skills/agent-tracing/SKILL.md
================================================
---
name: agent-tracing
description: "Agent tracing CLI for inspecting agent execution snapshots. Use when user mentions 'agent-tracing', 'trace', 'snapshot', wants to debug agent execution, inspect LLM calls, view context engine data, or analyze agent steps. Triggers on agent debugging, trace inspection, or execution analysis tasks."
user-invocable: false
---

# Agent Tracing CLI Guide

`@lobechat/agent-tracing` is a zero-config local dev tool that records agent execution snapshots to disk and provides a CLI to inspect them.

## How It Works

In `NODE_ENV=development`, `AgentRuntimeService.executeStep()` automatically records each step to `.agent-tracing/` as partial snapshots. When the operation completes, the partial is finalized into a complete `ExecutionSnapshot` JSON file.

**Data flow**: executeStep loop -> build `StepPresentationData` -> write partial snapshot to disk -> on completion, finalize to `.agent-tracing/{timestamp}_{traceId}.json`

**Context engine capture**: In `RuntimeExecutors.ts`, the `call_llm` executor emits a `context_engine_result` event after `serverMessagesEngine()` processes messages. This event carries the full `contextEngineInput` (DB messages, systemRole, model, knowledge, tools, userMemory, etc.) and the processed `output` messages (the final LLM payload).

## Package Location

```
packages/agent-tracing/
  src/
    types.ts          # ExecutionSnapshot, StepSnapshot, SnapshotSummary
    store/
      types.ts        # ISnapshotStore interface
      file-store.ts   # FileSnapshotStore (.agent-tracing/*.json)
    recorder/
      index.ts        # appendStepToPartial(), finalizeSnapshot()
    viewer/
      index.ts        # Terminal rendering: renderSnapshot, renderStepDetail, renderMessageDetail, renderSummaryTable, renderPayload, renderPayloadTools, renderMemory
    cli/
      index.ts        # CLI entry point (#!/usr/bin/env bun)
      inspect.ts      # Inspect command (default)
      partial.ts      # Partial snapshot commands (list, inspect, clean)
    index.ts          # Barrel exports
```

## Data Storage

- Completed snapshots: `.agent-tracing/{ISO-timestamp}_{traceId-short}.json`
- Latest symlink: `.agent-tracing/latest.json`
- In-progress partials: `.agent-tracing/_partial/{operationId}.json`
- `FileSnapshotStore` resolves from `process.cwd()` — **run CLI from the repo root**

## CLI Commands

All commands run from the **repo root**:

```bash
# View latest trace (tree overview, `inspect` is the default command)
agent-tracing
agent-tracing inspect
agent-tracing inspect <traceId>
agent-tracing inspect latest

# List recent snapshots
agent-tracing list
agent-tracing list -l 20

# Inspect specific step (-s is short for --step)
agent-tracing inspect <traceId> -s 0

# View messages (-m is short for --messages)
agent-tracing inspect <traceId> -s 0 -m

# View full content of a specific message (by index shown in -m output)
agent-tracing inspect <traceId> -s 0 --msg 2
agent-tracing inspect <traceId> -s 0 --msg-input 1

# View tool call/result details (-t is short for --tools)
agent-tracing inspect <traceId> -s 1 -t

# View raw events (-e is short for --events)
agent-tracing inspect <traceId> -s 0 -e

# View runtime context (-c is short for --context)
agent-tracing inspect <traceId> -s 0 -c

# View context engine input overview (-p is short for --payload)
agent-tracing inspect <traceId> -p
agent-tracing inspect <traceId> -s 0 -p

# View available tools in payload (-T is short for --payload-tools)
agent-tracing inspect <traceId> -T
agent-tracing inspect <traceId> -s 0 -T

# View user memory (-M is short for --memory)
agent-tracing inspect <traceId> -M
agent-tracing inspect <traceId> -s 0 -M

# Raw JSON output (-j is short for --json)
agent-tracing inspect <traceId> -j
agent-tracing inspect <traceId> -s 0 -j

# List in-progress partial snapshots
agent-tracing partial list

# Inspect a partial (use `inspect` directly — all flags work with partial IDs)
agent-tracing inspect <partialOperationId>
agent-tracing inspect <partialOperationId> -T
agent-tracing inspect <partialOperationId> -p

# Clean up stale partial snapshots
agent-tracing partial clean
```

## Inspect Flag Reference

| Flag              | Short | Description                                                                                       | Default Step |
| ----------------- | ----- | ------------------------------------------------------------------------------------------------- | ------------ |
| `--step <n>`      | `-s`  | Target a specific step                                                                            | —            |
| `--messages`      | `-m`  | Messages context (CE input → params → LLM payload)                                                | —            |
| `--tools`         | `-t`  | Tool calls & results (what agent invoked)                                                         | —            |
| `--events`        | `-e`  | Raw events (llm_start, llm_result, etc.)                                                          | —            |
| `--context`       | `-c`  | Runtime context & payload (raw)                                                                   | —            |
| `--system-role`   | `-r`  | Full system role content                                                                          | 0            |
| `--env`           |       | Environment context                                                                               | 0            |
| `--payload`       | `-p`  | Context engine input overview (model, knowledge, tools summary, memory summary, platform context) | 0            |
| `--payload-tools` | `-T`  | Available tools detail (plugin manifests + LLM function definitions)                              | 0            |
| `--memory`        | `-M`  | Full user memory (persona, identity, contexts, preferences, experiences)                          | 0            |
| `--diff <n>`      | `-d`  | Diff against step N (use with `-r` or `--env`)                                                    | —            |
| `--msg <n>`       |       | Full content of message N from Final LLM Payload                                                  | —            |
| `--msg-input <n>` |       | Full content of message N from Context Engine Input                                               | —            |
| `--json`          | `-j`  | Output as JSON (combinable with any flag above)                                                   | —            |

Flags marked "Default Step: 0" auto-select step 0 if `--step` is not provided. All flags support `latest` or omitted traceId.

## Typical Debug Workflow

```bash
# 1. Trigger an agent operation in the dev UI

# 2. See the overview
agent-tracing inspect

# 3. List all traces, get traceId
agent-tracing list

# 4. Quick overview of what was fed into context engine
agent-tracing inspect -p

# 5. Inspect a specific step's messages to see what was sent to the LLM
agent-tracing inspect TRACE_ID -s 0 -m

# 6. Drill into a truncated message for full content
agent-tracing inspect TRACE_ID -s 0 --msg 2

# 7. Check available tools vs actual tool calls
agent-tracing inspect -T      # available tools
agent-tracing inspect -s 1 -t # actual tool calls & results

# 8. Inspect user memory injected into the conversation
agent-tracing inspect -M

# 9. Diff system role between steps (multi-step agents)
agent-tracing inspect TRACE_ID -r -d 2
```

## Key Types

```typescript
interface ExecutionSnapshot {
  traceId: string;
  operationId: string;
  model?: string;
  provider?: string;
  startedAt: number;
  completedAt?: number;
  completionReason?:
    | 'done'
    | 'error'
    | 'interrupted'
    | 'max_steps'
    | 'cost_limit'
    | 'waiting_for_human';
  totalSteps: number;
  totalTokens: number;
  totalCost: number;
  error?: { type: string; message: string };
  steps: StepSnapshot[];
}

interface StepSnapshot {
  stepIndex: number;
  stepType: 'call_llm' | 'call_tool';
  executionTimeMs: number;
  content?: string; // LLM output
  reasoning?: string; // Reasoning/thinking
  inputTokens?: number;
  outputTokens?: number;
  toolsCalling?: Array<{ apiName: string; identifier: string; arguments?: string }>;
  toolsResult?: Array<{
    apiName: string;
    identifier: string;
    isSuccess?: boolean;
    output?: string;
  }>;
  messages?: any[]; // DB messages before step
  context?: { phase: string; payload?: unknown; stepContext?: unknown };
  events?: Array<{ type: string; [key: string]: unknown }>;
  // context_engine_result event contains:
  //   input: full contextEngineInput (messages, systemRole, model, knowledge, tools, userMemory, ...)
  //   output: processed messages array (final LLM payload)
}
```

## --messages Output Structure

When using `--messages`, the output shows three sections (if context engine data is available):

1. **Context Engine Input** — DB messages passed to the engine, with `[0]`, `[1]`, ... indices. Use `--msg-input N` to view full content.
2. **Context Engine Params** — systemRole, model, provider, knowledge, tools, userMemory, etc.
3. **Final LLM Payload** — Processed messages after context engine (system date injection, user memory, history truncation, etc.), with `[0]`, `[1]`, ... indices. Use `--msg N` to view full content.

## Integration Points

- **Recording**: `src/server/services/agentRuntime/AgentRuntimeService.ts` — in the `executeStep()` method, after building `stepPresentationData`, writes partial snapshot in dev mode
- **Context engine event**: `src/server/modules/AgentRuntime/RuntimeExecutors.ts` — in `call_llm` executor, after `serverMessagesEngine()` returns, emits `context_engine_result` event
- **Store**: `FileSnapshotStore` reads/writes to `.agent-tracing/` relative to `process.cwd()`


================================================
FILE: .agents/skills/chat-sdk/SKILL.md
================================================
---
name: chat-sdk
description: >
  Build multi-platform chat bots with Chat SDK (`chat` npm package). Use when developers want to
  (1) Build a Slack, Teams, Google Chat, Discord, GitHub, or Linear bot,
  (2) Use the Chat SDK to handle mentions, messages, reactions, slash commands, cards, modals, or streaming,
  (3) Set up webhook handlers for chat platforms,
  (4) Send interactive cards or stream AI responses to chat platforms.
  Triggers on "chat sdk", "chat bot", "slack bot", "teams bot", "discord bot", "@chat-adapter",
  building bots that work across multiple chat platforms.
---

# Chat SDK

Unified TypeScript SDK for building chat bots across Slack, Teams, Google Chat, Discord, GitHub, and Linear. Write bot logic once, deploy everywhere.

## Critical: Read the bundled docs

The `chat` package ships with full documentation in `node_modules/chat/docs/` and TypeScript source types. **Always read these before writing code:**

```
node_modules/chat/docs/           # Full documentation (MDX files)
node_modules/chat/dist/           # Built types (.d.ts files)
```

Key docs to read based on task:

- `docs/getting-started.mdx` — setup guides
- `docs/usage.mdx` — event handlers, threads, messages, channels
- `docs/streaming.mdx` — AI streaming with AI SDK
- `docs/cards.mdx` — JSX interactive cards
- `docs/actions.mdx` — button/dropdown handlers
- `docs/modals.mdx` — form dialogs (Slack only)
- `docs/adapters/*.mdx` — platform-specific adapter setup
- `docs/state/*.mdx` — state adapter config (Redis, ioredis, memory)

Also read the TypeScript types from `node_modules/chat/dist/` to understand the full API surface.

## Quick start

```typescript
import { Chat } from 'chat';
import { createSlackAdapter } from '@chat-adapter/slack';
import { createRedisState } from '@chat-adapter/state-redis';

const bot = new Chat({
  userName: 'mybot',
  adapters: {
    slack: createSlackAdapter({
      botToken: process.env.SLACK_BOT_TOKEN!,
      signingSecret: process.env.SLACK_SIGNING_SECRET!,
    }),
  },
  state: createRedisState({ url: process.env.REDIS_URL! }),
});

bot.onNewMention(async (thread) => {
  await thread.subscribe();
  await thread.post("Hello! I'm listening to this thread.");
});

bot.onSubscribedMessage(async (thread, message) => {
  await thread.post(`You said: ${message.text}`);
});
```

## Core concepts

- **Chat** — main entry point, coordinates adapters and routes events
- **Adapters** — platform-specific (Slack, Teams, GChat, Discord, GitHub, Linear)
- **State** — pluggable persistence (Redis for prod, memory for dev)
- **Thread** — conversation thread with `post()`, `subscribe()`, `startTyping()`
- **Message** — normalized format with `text`, `formatted` (mdast AST), `raw`
- **Channel** — container for threads, supports listing and posting

## Event handlers

| Handler                    | Trigger                                           |
| -------------------------- | ------------------------------------------------- |
| `onNewMention`             | Bot @-mentioned in unsubscribed thread            |
| `onSubscribedMessage`      | Any message in subscribed thread                  |
| `onNewMessage(regex)`      | Messages matching pattern in unsubscribed threads |
| `onSlashCommand("/cmd")`   | Slash command invocations                         |
| `onReaction(emojis)`       | Emoji reactions added/removed                     |
| `onAction(actionId)`       | Button clicks and dropdown selections             |
| `onAssistantThreadStarted` | Slack Assistants API thread opened                |
| `onAppHomeOpened`          | Slack App Home tab opened                         |

## Streaming

Pass any `AsyncIterable<string>` to `thread.post()`. Works with AI SDK's `textStream`:

```typescript
import { ToolLoopAgent } from 'ai';
const agent = new ToolLoopAgent({ model: 'anthropic/claude-4.5-sonnet' });

bot.onNewMention(async (thread, message) => {
  const result = await agent.stream({ prompt: message.text });
  await thread.post(result.textStream);
});
```

## Cards (JSX)

Set `jsxImportSource: "chat"` in tsconfig. Components: `Card`, `CardText`, `Button`, `Actions`, `Fields`, `Field`, `Select`, `SelectOption`, `Image`, `Divider`, `LinkButton`, `Section`, `RadioSelect`.

```tsx
await thread.post(
  <Card title="Order #1234">
    <CardText>Your order has been received!</CardText>
    <Actions>
      <Button id="approve" style="primary">
        Approve
      </Button>
      <Button id="reject" style="danger">
        Reject
      </Button>
    </Actions>
  </Card>,
);
```

## Packages

| Package                       | Purpose                       |
| ----------------------------- | ----------------------------- |
| `chat`                        | Core SDK                      |
| `@chat-adapter/slack`         | Slack                         |
| `@chat-adapter/teams`         | Microsoft Teams               |
| `@chat-adapter/gchat`         | Google Chat                   |
| `@chat-adapter/discord`       | Discord                       |
| `@chat-adapter/github`        | GitHub Issues                 |
| `@chat-adapter/linear`        | Linear Issues                 |
| `@chat-adapter/state-redis`   | Redis state (production)      |
| `@chat-adapter/state-ioredis` | ioredis state (alternative)   |
| `@chat-adapter/state-memory`  | In-memory state (development) |

## Changesets (Release Flow)

This monorepo uses [Changesets](https://github.com/changesets/changesets) for versioning and changelogs. Every PR that changes a package's behavior must include a changeset.

```bash
pnpm changeset
# → select affected package(s) (e.g. @chat-adapter/slack, chat)
# → choose bump type: patch (fixes), minor (features), major (breaking)
# → write a short summary for the CHANGELOG
```

This creates a file in `.changeset/` — commit it with the PR. When merged to `main`, the Changesets GitHub Action opens a "Version Packages" PR to bump versions and update CHANGELOGs. Merging that PR publishes to npm.

## Webhook setup

Each adapter exposes a webhook handler via `bot.webhooks.{platform}`. Wire these to your HTTP framework's routes (e.g. Next.js API routes, Hono, Express).


================================================
FILE: .agents/skills/cli/SKILL.md
================================================
---
name: cli
description: LobeHub CLI (@lobehub/cli) development guide. Use when working on CLI commands, adding new subcommands, fixing CLI bugs, or understanding CLI architecture. Triggers on CLI development, command implementation, or `lh` command questions.
disable-model-invocation: true
---

# LobeHub CLI Development Guide

## Overview

LobeHub CLI (`@lobehub/cli`) is a command-line tool for managing and interacting with LobeHub services. Built with Commander.js + TypeScript.

- **Package**: `apps/cli/`
- **Entry**: `apps/cli/src/index.ts`
- **Binaries**: `lh`, `lobe`, `lobehub` (all aliases for the same CLI)
- **Build**: tsup
- **Runtime**: Node.js / Bun

## Architecture

```
apps/cli/src/
├── index.ts                  # Entry point, registers all commands
├── api/
│   ├── client.ts             # tRPC client (type-safe backend API)
│   └── http.ts               # Raw HTTP utilities
├── auth/
│   ├── credentials.ts        # Encrypted credential storage (AES-256-GCM)
│   ├── refresh.ts            # Token auto-refresh
│   └── resolveToken.ts       # Token resolution (flag > stored)
├── commands/                 # All CLI commands (one file per command group)
│   ├── agent.ts              # Agent CRUD + run
│   ├── config.ts             # whoami, usage
│   ├── connect.ts            # Device gateway connection + daemon
│   ├── doc.ts                # Document management
│   ├── file.ts               # File management
│   ├── generate/             # Content generation (text/image/video/tts/asr)
│   ├── kb.ts                 # Knowledge base management
│   ├── login.ts              # OIDC Device Code Flow auth
│   ├── logout.ts             # Clear credentials
│   ├── memory.ts             # User memory management
│   ├── message.ts            # Message management
│   ├── model.ts              # AI model management
│   ├── plugin.ts             # Plugin management
│   ├── provider.ts           # AI provider management
│   ├── search.ts             # Global search
│   ├── skill.ts              # Agent skill management
│   ├── status.ts             # Gateway connectivity check
│   └── topic.ts              # Conversation topic management
├── daemon/
│   └── manager.ts            # Background daemon process management
├── tools/
│   ├── shell.ts              # Shell command execution (for gateway)
│   └── file.ts               # File operations (for gateway)
├── settings/
│   └── index.ts              # Persistent settings (~/.lobehub/)
├── utils/
│   ├── logger.ts             # Logging (verbose mode)
│   ├── format.ts             # Table output, JSON, timeAgo, truncate
│   └── agentStream.ts        # SSE streaming for agent runs
└── constants/
    └── urls.ts               # Official server & gateway URLs
```

## Command Groups

| Command       | Alias | Description                                                 |
| ------------- | ----- | ----------------------------------------------------------- |
| `lh login`    | -     | Authenticate via OIDC Device Code Flow                      |
| `lh logout`   | -     | Clear stored credentials                                    |
| `lh connect`  | -     | Device gateway connection & daemon management               |
| `lh status`   | -     | Quick gateway connectivity check                            |
| `lh agent`    | -     | Agent CRUD, run, status                                     |
| `lh generate` | `gen` | Content generation (text, image, video, tts, asr, download) |
| `lh doc`      | -     | Document CRUD, batch-create, parse, topic linking           |
| `lh file`     | -     | File list, view, delete, recent                             |
| `lh kb`       | -     | Knowledge base CRUD, folders, docs, upload, tree view       |
| `lh memory`   | -     | User memory CRUD + extraction                               |
| `lh message`  | -     | Message list, search, delete, count, heatmap                |
| `lh topic`    | -     | Topic CRUD + search + recent                                |
| `lh skill`    | -     | Skill CRUD + import (GitHub/URL/market)                     |
| `lh model`    | -     | Model CRUD, toggle, batch-toggle, clear                     |
| `lh provider` | -     | Provider CRUD, config, test, toggle                         |
| `lh plugin`   | -     | Plugin install, uninstall, update                           |
| `lh search`   | -     | Global search across all types                              |
| `lh whoami`   | -     | Current user info                                           |
| `lh usage`    | -     | Monthly/daily usage statistics                              |

## Adding a New Command

### 1. Create Command File

Create `apps/cli/src/commands/<name>.ts`:

```typescript
import type { Command } from 'commander';
import { getTrpcClient } from '../api/client';
import { outputJson, printTable, truncate } from '../utils/format';

export function register<Name>Command(program: Command) {
  const cmd = program.command('<name>').description('...');

  // Subcommands
  cmd
    .command('list')
    .description('List items')
    .option('-L, --limit <n>', 'Maximum number of items', '30')
    .option('--json [fields]', 'Output JSON, optionally specify fields')
    .action(async (options) => {
      const client = await getTrpcClient();
      const result = await client.<router>.<procedure>.query({ ... });
      // Handle output
    });
}
```

### 2. Register in Entry Point

In `apps/cli/src/index.ts`:

```typescript
import { registerNewCommand } from './commands/new';
// ...
registerNewCommand(program);
```

### 3. Add Tests

Create `apps/cli/src/commands/<name>.test.ts` alongside the command file.

## Conventions

### Output Patterns

All list/view commands follow consistent patterns:

- `--json [fields]` - JSON output with optional field filtering
- `--yes` - Skip confirmation for destructive ops
- `-L, --limit <n>` - Pagination limit (default: 30)
- `-v, --verbose` - Verbose logging

### Table Output

```typescript
const rows = items.map((item) => [item.id, truncate(item.title, 40), timeAgo(item.updatedAt)]);
printTable(rows, ['ID', 'TITLE', 'UPDATED']);
```

### JSON Output

```typescript
if (options.json !== undefined) {
  const fields = typeof options.json === 'string' ? options.json : undefined;
  outputJson(items, fields);
  return;
}
```

### Authentication

Commands that need auth use `getTrpcClient()` which auto-resolves tokens:

```typescript
const client = await getTrpcClient();
// client.router.procedure.query/mutate(...)
```

### Confirmation Prompts

```typescript
import { confirm } from '../utils/format';
if (!options.yes) {
  const ok = await confirm('Are you sure?');
  if (!ok) return;
}
```

## Storage Locations

| File          | Path                          | Purpose                        |
| ------------- | ----------------------------- | ------------------------------ |
| Credentials   | `~/.lobehub/credentials.json` | Encrypted tokens (AES-256-GCM) |
| Settings      | `~/.lobehub/settings.json`    | Custom server/gateway URLs     |
| Daemon PID    | `~/.lobehub/daemon.pid`       | Background process PID         |
| Daemon Status | `~/.lobehub/daemon.status`    | Connection status JSON         |
| Daemon Log    | `~/.lobehub/daemon.log`       | Daemon output log              |

The base directory (`~/.lobehub/`) can be overridden with the `LOBEHUB_CLI_HOME` env var (e.g. `LOBEHUB_CLI_HOME=.lobehub-dev` for dev mode isolation).

## Key Dependencies

- `commander` - CLI framework
- `@trpc/client` + `superjson` - Type-safe API client
- `@lobechat/device-gateway-client` - WebSocket gateway connection
- `@lobechat/local-file-shell` - Local shell/file tool execution
- `picocolors` - Terminal colors
- `ws` - WebSocket
- `diff` - Text diffing
- `fast-glob` - File pattern matching

## Development

### Running in Dev Mode

Dev mode uses `LOBEHUB_CLI_HOME=.lobehub-dev` to isolate credentials from the global `~/.lobehub/` directory, so dev and production configs never conflict.

```bash
# Run a command in dev mode (from apps/cli/)
cd apps/cli && bun run dev -- <command>

# This is equivalent to:
LOBEHUB_CLI_HOME=.lobehub-dev bun src/index.ts <command>
```

### Connecting to Local Dev Server

To test CLI against a local dev server (e.g. `localhost:3011`):

**Step 1: Start the local server**

```bash
# From cloud repo root
bun run dev
# Server starts on http://localhost:3011 (or configured port)
```

**Step 2: Login to local server via Device Code Flow**

```bash
cd apps/cli && bun run dev -- login --server http://localhost:3011
```

This will:

1. Call `POST http://localhost:3011/oidc/device/auth` to get a device code
2. Print a URL like `http://localhost:3011/oidc/device?user_code=XXXX-YYYY`
3. Open the URL in your browser — log in and authorize
4. Save credentials to `apps/cli/.lobehub-dev/credentials.json`
5. Save server URL to `apps/cli/.lobehub-dev/settings.json`

After login, all subsequent `bun run dev -- <command>` calls will use the local server.

**Step 3: Run commands against local server**

```bash
cd apps/cli && bun run dev -- task list
cd apps/cli && bun run dev -- task create -i "Test task" -n "My Task"
cd apps/cli && bun run dev -- agent list
```

**Troubleshooting:**

- If login returns `invalid_grant`, make sure the local OIDC provider is properly configured (check `OIDC_*` env vars in `.env`)
- If you get `UNAUTHORIZED` on API calls, your token may have expired — run `bun run dev -- login --server http://localhost:3011` again
- Dev credentials are stored in `apps/cli/.lobehub-dev/` (gitignored), not in `~/.lobehub/`

### Switching Between Local and Production

```bash
# Dev mode (local server) — uses .lobehub-dev/
cd apps/cli && bun run dev -- <command>

# Production (app.lobehub.com) — uses ~/.lobehub/
lh <command>
```

The two environments are completely isolated by different credential directories.

### Build & Test

```bash
# Build CLI
cd apps/cli && bun run build

# Unit tests
cd apps/cli && bun run test

# E2E tests (requires authenticated CLI)
cd apps/cli && bunx vitest run e2e/kb.e2e.test.ts

# Link globally for testing (installs lh/lobe/lobehub commands)
cd apps/cli && bun run cli:link
```

## Detailed Command References

See `references/` for each command group:

- **Agent**: `references/agent.md` (CRUD, run, status)
- **Content Generation**: `references/generate.md` (text, image, video, tts, asr, download)
- **Knowledge & Files**: `references/knowledge.md` (kb, file, doc)
- **Conversation**: `references/conversation.md` (topic, message)
- **Memory**: `references/memory.md` (memory management, extraction)
- **Skills & Plugins**: `references/skills-plugins.md` (skill, plugin)
- **Models & Providers**: `references/models-providers.md` (model, provider)
- **Search & Config**: `references/search-config.md` (search, whoami, usage)


================================================
FILE: .agents/skills/cli/references/agent.md
================================================
# Agent Commands

Manage AI agents: create, edit, delete, list, run, and check status.

**Source**: `apps/cli/src/commands/agent.ts`

## `lh agent list`

List all agents.

```bash
lh agent list [-L [-k [--json [fields]] < n > ] < keyword > ]
```

| Option                    | Description                            | Default |
| ------------------------- | -------------------------------------- | ------- |
| `-L, --limit <n>`         | Maximum items                          | `30`    |
| `-k, --keyword <keyword>` | Filter by keyword                      | -       |
| `--json [fields]`         | JSON output with optional field filter | -       |

**Table columns**: ID, TITLE, DESCRIPTION, MODEL

---

## `lh agent view <agentId>`

View agent configuration details.

```bash
lh agent view [fields]] < agentId > [--json
```

**Displays**: Title, description, model, provider, system role, plugins, tools.

---

## `lh agent create`

Create a new agent.

```bash
lh agent create [options]
```

| Option                      | Description    | Required |
| --------------------------- | -------------- | -------- |
| `-t, --title <title>`       | Agent title    | No       |
| `-d, --description <desc>`  | Description    | No       |
| `-m, --model <model>`       | Model ID       | No       |
| `-p, --provider <provider>` | Provider ID    | No       |
| `-s, --system-role <role>`  | System prompt  | No       |
| `--group <groupId>`         | Agent group ID | No       |

**Output**: Created agent ID and session ID.

---

## `lh agent edit <agentId>`

Update an existing agent. Same options as `create`, all optional. Only specified fields are updated.

```bash
lh agent edit [-m [-s ... < agentId > [-t < title > ] < model > ] < role > ]
```

---

## `lh agent delete <agentId>`

Delete an agent.

```bash
lh agent delete < agentId > [--yes]
```

Requires confirmation unless `--yes` is provided.

---

## `lh agent duplicate <agentId>`

Duplicate an existing agent.

```bash
lh agent duplicate < agentId > [-t < title > ]
```

| Option                | Description                          |
| --------------------- | ------------------------------------ |
| `-t, --title <title>` | Optional new title for the duplicate |

**Output**: New agent ID.

---

## `lh agent run`

Start an agent execution (streaming SSE).

```bash
lh agent run [options]
```

| Option                | Description                                  |
| --------------------- | -------------------------------------------- |
| `-a, --agent-id <id>` | Agent ID to run                              |
| `-s, --slug <slug>`   | Agent slug (alternative to ID)               |
| `-p, --prompt <text>` | User prompt                                  |
| `-t, --topic-id <id>` | Reuse existing topic                         |
| `--no-auto-start`     | Don't auto-start the agent                   |
| `--json`              | Output full JSON event stream                |
| `-v, --verbose`       | Show detailed tool call info                 |
| `--replay <file>`     | Replay events from saved JSON file (offline) |

### Streaming Behavior

Uses `utils/agentStream.ts` to handle Server-Sent Events:

1. Sends agent run request to backend
2. Streams SSE events in real-time
3. Displays: text chunks, tool call status, operation progress
4. Shows final token usage and cost summary

### Replay Mode

`--replay <file>` reads a saved JSON event stream for offline debugging without server connection.

---

## `lh agent status <operationId>`

Check agent operation status.

```bash
lh agent status [fields]] [--history] [--history-limit < operationId > [--json < n > ]
```

| Option                | Description          | Default |
| --------------------- | -------------------- | ------- |
| `--json [fields]`     | JSON output          | -       |
| `--history`           | Include step history | `false` |
| `--history-limit <n>` | Max history entries  | `10`    |

**Displays**: Status (running/completed/failed), steps count, tokens used, cost, error info, timestamps.


================================================
FILE: .agents/skills/cli/references/conversation.md
================================================
# Conversation Commands (Topic & Message)

## Topic Management (`lh topic`)

Manage conversation topics (threads).

**Source**: `apps/cli/src/commands/topic.ts`

### `lh topic list`

```bash
lh topic list [--agent-id [-L [--page [--json [fields]] < id > ] < n > ] < n > ]
```

| Option            | Description     | Default |
| ----------------- | --------------- | ------- |
| `--agent-id <id>` | Filter by agent | -       |
| `-L, --limit <n>` | Page size       | `30`    |
| `--page <n>`      | Page number     | `1`     |

**Table columns**: ID, TITLE, FAV, UPDATED

### `lh topic search <keywords>`

```bash
lh topic search [--json [fields]] < keywords > [--agent-id < id > ]
```

### `lh topic create`

```bash
lh topic create -t [--favorite] < title > [--agent-id < id > ]
```

| Option                | Description          | Required |
| --------------------- | -------------------- | -------- |
| `-t, --title <title>` | Topic title          | Yes      |
| `--agent-id <id>`     | Associate with agent | No       |
| `--favorite`          | Mark as favorite     | No       |

### `lh topic edit <id>`

```bash
lh topic edit [--favorite] [--no-favorite] < id > [-t < title > ]
```

### `lh topic delete <ids...>`

```bash
lh topic delete [--yes] < id1 > [id2...]
```

### `lh topic recent`

```bash
lh topic recent [-L [--json [fields]] < n > ]
```

| Option            | Description     | Default |
| ----------------- | --------------- | ------- |
| `-L, --limit <n>` | Number of items | `10`    |

---

## Message Management (`lh message`)

Manage chat messages within topics.

**Source**: `apps/cli/src/commands/message.ts`

### `lh message list`

```bash
lh message list [options] [--json [fields]]
```

| Option            | Description             | Default |
| ----------------- | ----------------------- | ------- |
| `--topic-id <id>` | Filter by topic         | -       |
| `--agent-id <id>` | Filter by agent         | -       |
| `-L, --limit <n>` | Page size               | `30`    |
| `--page <n>`      | Page number             | `1`     |
| `--user`          | Only show user messages | -       |

**Table columns**: ID, ROLE, CONTENT, CREATED

**Note**: When `--topic-id` or `--agent-id` is provided, uses `message.getMessages`; otherwise uses `message.listAll`.

### `lh message search <keywords>`

```bash
lh message search [fields]] < keywords > [--json
```

Full-text search across all messages.

### `lh message delete <ids...>`

```bash
lh message delete [--yes] < id1 > [id2...]
```

### `lh message count`

```bash
lh message count [--start [--end [--json] < date > ] < date > ]
```

| Option           | Description                                |
| ---------------- | ------------------------------------------ |
| `--start <date>` | Start date (ISO format, e.g. `2024-01-01`) |
| `--end <date>`   | End date (ISO format)                      |

**Output**: Total message count for the specified period.

### `lh message heatmap`

```bash
lh message heatmap [--json]
```

**Output**: Activity heatmap data showing message frequency over time.


================================================
FILE: .agents/skills/cli/references/generate.md
================================================
# Content Generation Commands

Generate text, images, videos, speech, and transcriptions.

**Source**: `apps/cli/src/commands/generate/`

## Command Structure

```
lh generate (alias: gen)
├── text <prompt>                    # Text generation
├── image <prompt>                   # Image generation
├── video <prompt>                   # Video generation
├── tts <text>                       # Text-to-speech
├── asr <audioFile>                  # Audio-to-text (speech recognition)
├── download <genId> <taskId>        # Wait & download generation result
├── status <genId> <taskId>          # Check async task status
└── list                             # List generation topics
```

---

## `lh generate text <prompt>` / `lh gen text <prompt>`

Generate text completion.

**Source**: `apps/cli/src/commands/generate/text.ts`

```bash
lh gen text "Explain quantum computing" [options]
echo "context" | lh gen text "summarize" --pipe
```

| Option                      | Description                        | Default              |
| --------------------------- | ---------------------------------- | -------------------- |
| `-m, --model <model>`       | Model ID                           | `openai/gpt-4o-mini` |
| `-p, --provider <provider>` | Provider name                      | -                    |
| `-s, --system <prompt>`     | System prompt                      | -                    |
| `--temperature <n>`         | Temperature (0-2)                  | -                    |
| `--max-tokens <n>`          | Maximum output tokens              | -                    |
| `--stream`                  | Enable streaming output            | `false`              |
| `--json`                    | Output full JSON response          | `false`              |
| `--pipe`                    | Read additional context from stdin | `false`              |

### Pipe Mode

When `--pipe` is used, reads stdin and prepends it to the prompt. Useful for piping file contents:

```bash
cat README.md | lh gen text "summarize this" --pipe
```

---

## `lh generate image <prompt>` / `lh gen image <prompt>`

Generate images from text prompt. This is an async operation — the command submits the task and returns a generation ID + task ID for tracking.

**Source**: `apps/cli/src/commands/generate/image.ts`

```bash
lh gen image "A sunset over mountains" [options]
lh gen image "A cute cat" --model dall-e-3 --provider openai --json
```

| Option                      | Description      | Default    |
| --------------------------- | ---------------- | ---------- |
| `-m, --model <model>`       | Model ID         | `dall-e-3` |
| `-p, --provider <provider>` | Provider name    | `openai`   |
| `-n, --num <n>`             | Number of images | `1`        |
| `--width <px>`              | Width in pixels  | -          |
| `--height <px>`             | Height in pixels | -          |
| `--steps <n>`               | Number of steps  | -          |
| `--seed <n>`                | Random seed      | -          |
| `--json`                    | Output raw JSON  | `false`    |

**Output** (non-JSON):

```
✓ Image generation started
  Batch ID: gb_xxx
  1 image(s) queued
  Generation gen_xxx → Task <taskId>

Use "lh generate status <generationId> <taskId>" to check progress.
```

**Typical workflow**:

```bash
# Generate image, then wait & download
lh gen image "A cute cat"
lh gen download <generationId> <taskId> -o cat.png
```

---

## `lh generate video <prompt>` / `lh gen video <prompt>`

Generate video from text prompt. This is an async operation.

**Source**: `apps/cli/src/commands/generate/video.ts`

```bash
lh gen video "A cat playing piano" -m < model > -p < provider > [options]
```

| Option                      | Description              | Required |
| --------------------------- | ------------------------ | -------- |
| `-m, --model <model>`       | Model ID                 | Yes      |
| `-p, --provider <provider>` | Provider name            | Yes      |
| `--aspect-ratio <ratio>`    | Aspect ratio (e.g. 16:9) | No       |
| `--duration <sec>`          | Duration in seconds      | No       |
| `--resolution <res>`        | Resolution (e.g. 720p)   | No       |
| `--seed <n>`                | Random seed              | No       |
| `--json`                    | Output raw JSON          | No       |

**Note**: Unlike image, video requires `-m` and `-p` (no defaults). Use `lh model list <provider> --type video` to find available video models.

**Output** (non-JSON):

```
✓ Video generation started
  Batch ID: gb_xxx
  Generation gen_xxx → Task <taskId>

Use "lh generate status <generationId> <taskId>" to check progress.
```

---

## `lh generate tts <text>` / `lh gen tts <text>`

Text-to-speech generation.

**Source**: `apps/cli/src/commands/generate/tts.ts`

```bash
lh gen tts "Hello, world!" [options]
```

---

## `lh generate asr <audioFile>` / `lh gen asr <audioFile>`

Audio-to-text transcription (Automatic Speech Recognition).

**Source**: `apps/cli/src/commands/generate/asr.ts`

```bash
lh gen asr recording.wav [options]
```

---

## `lh generate download <generationId> <taskId>`

Wait for an async generation task to complete and download the result file.

**Source**: `apps/cli/src/commands/generate/index.ts`

```bash
lh gen download <generationId> <taskId> [-o output.png]
lh gen download gen_xxx task_xxx -o ~/Desktop/result.mp4 --timeout 600
```

| Option                | Description                              | Default                |
| --------------------- | ---------------------------------------- | ---------------------- |
| `-o, --output <path>` | Output file path (auto-detect extension) | `<generationId>.<ext>` |
| `--interval <sec>`    | Polling interval in seconds              | `5`                    |
| `--timeout <sec>`     | Timeout in seconds (0 = no timeout)      | `300`                  |

**Behavior**:

1. Polls `generation.getGenerationStatus` at the specified interval
2. Shows live progress: `⋯ Status: processing... (42s)`
3. On success: downloads asset URL to local file
4. On error: displays error message and exits
5. On timeout: suggests using `lh gen status` to check later

**Typical workflow**:

```bash
# One-shot: generate and download
lh gen image "A sunset"
# Copy the generation ID and task ID from output
lh gen download gen_xxx taskId_xxx -o sunset.png

# Video (longer timeout)
lh gen video "A cat running" -m model -p provider
lh gen download gen_xxx taskId_xxx -o cat.mp4 --timeout 600
```

---

## `lh generate status <generationId> <taskId>`

Check the status of an async generation task.

```bash
lh gen status <generationId> <taskId> [--json]
```

| Option   | Description              |
| -------- | ------------------------ |
| `--json` | Output raw JSON response |

**Displays**:

- Status (color-coded): `success` (green), `error` (red), `processing` (yellow), `pending` (cyan)
- Error message (if failed)
- Asset URL and thumbnail URL (if completed)

---

## `lh generate list`

List all generation topics.

```bash
lh gen list [--json [fields]]
```

**Table columns**: ID, TITLE, TYPE, UPDATED

---

## Backend Architecture

Image and video generation use an async task pattern:

1. **Create topic** → `generationTopic.createTopic`
2. **Submit generation** → `image.createImage` / `video.createVideo`
   - Creates batch + generation + asyncTask records in a DB transaction
   - Triggers async background task (image via `createAsyncCaller`, video via `initModelRuntimeFromDB`)
   - Returns `{ data: { batch, generations }, success }` with `asyncTaskId` in each generation
3. **Poll status** → `generation.getGenerationStatus`
   - Returns `{ status, error, generation }` (generation includes asset URLs on success)

**Server routes**:

- `src/server/routers/lambda/image/index.ts` — image creation (uses `authedProcedure` + `serverDatabase`)
- `src/server/routers/lambda/video/index.ts` — video creation (uses `authedProcedure` + `serverDatabase`)
- `src/server/routers/lambda/generation.ts` — status checking

**Note**: Image/video routes do NOT use the `keyVaults` middleware — they read API keys from the database via `initModelRuntimeFromDB` or `createAsyncCaller`.


================================================
FILE: .agents/skills/cli/references/knowledge.md
================================================
# Knowledge Base, File & Document Commands

## Knowledge Base (`lh kb`)

Manage knowledge bases for RAG (Retrieval-Augmented Generation). Supports directory tree structure with folders, documents, and file uploads.

**Source**: `apps/cli/src/commands/kb.ts`

### `lh kb list`

```bash
lh kb list [--json [fields]]
```

**Table columns**: ID, NAME, DESCRIPTION, UPDATED

### `lh kb view <id>`

```bash
lh kb view [fields]] < id > [--json
```

**Displays**: Name, description, full directory tree with all files and documents (recursively fetched). Shows indented tree structure with item type (File/Doc), file type, and size.

**API**: Uses `file.getKnowledgeItems` to recursively fetch items. Folders (`custom/folder` fileType) are traversed in parallel via `Promise.all` for performance.

### `lh kb create`

```bash
lh kb create -n [--avatar < name > [-d < desc > ] < url > ]
```

| Option                     | Description         | Required |
| -------------------------- | ------------------- | -------- |
| `-n, --name <name>`        | Knowledge base name | Yes      |
| `-d, --description <desc>` | Description         | No       |
| `--avatar <url>`           | Avatar URL          | No       |

**Output**: Created KB ID. Note: backend returns ID as a string directly (not an object).

### `lh kb edit <id>`

```bash
lh kb edit [-d [--avatar < id > [-n < name > ] < desc > ] < url > ]
```

Requires at least one change flag. Errors if none specified.

### `lh kb delete <id>`

```bash
lh kb delete [--yes] < id > [--remove-files]
```

| Option           | Description                  |
| ---------------- | ---------------------------- |
| `--remove-files` | Also delete associated files |
| `--yes`          | Skip confirmation            |

### `lh kb add-files <knowledgeBaseId>`

```bash
lh kb add-files <kbId> --ids <fileId1> <fileId2> ...
```

Link existing files to a knowledge base.

### `lh kb remove-files <knowledgeBaseId>`

```bash
lh kb remove-files <kbId> --ids <fileId1> <fileId2> ... [--yes]
```

Unlink files from a knowledge base.

### `lh kb mkdir <knowledgeBaseId>`

```bash
lh kb mkdir < kbId > -n < name > [--parent < folderId > ]
```

Create a folder in a knowledge base. Uses `document.createDocument` with `fileType: 'custom/folder'`.

| Option                | Description      | Required |
| --------------------- | ---------------- | -------- |
| `-n, --name <name>`   | Folder name      | Yes      |
| `--parent <parentId>` | Parent folder ID | No       |

### `lh kb create-doc <knowledgeBaseId>`

```bash
lh kb create-doc [--parent < kbId > -t < title > [-c < content > ] < folderId > ]
```

Create a document in a knowledge base. Uses `document.createDocument` with `fileType: 'custom/document'`.

| Option                 | Description      | Required |
| ---------------------- | ---------------- | -------- |
| `-t, --title <title>`  | Document title   | Yes      |
| `-c, --content <text>` | Document content | No       |
| `--parent <parentId>`  | Parent folder ID | No       |

### `lh kb move <id>`

```bash
lh kb move < id > --type < file | doc > [--parent < folderId > ]
```

Move a file or document to a different folder (or to root if `--parent` is omitted).

| Option                | Description                      | Default |
| --------------------- | -------------------------------- | ------- |
| `--type <type>`       | Item type: `file` or `doc`       | `file`  |
| `--parent <parentId>` | Target folder ID (omit for root) | -       |

Uses `document.updateDocument` for docs, `file.updateFile` for files.

### `lh kb upload <knowledgeBaseId> <filePath>`

```bash
lh kb upload <kbId> <filePath> [--parent <folderId>]
```

Upload a local file to a knowledge base via S3 presigned URL.

| Option                | Description      |
| --------------------- | ---------------- |
| `--parent <parentId>` | Parent folder ID |

**Flow**: Compute SHA-256 hash → get presigned URL via `upload.createS3PreSignedUrl` → PUT to S3 → create file record via `file.createFile`.

---

## File Management (`lh file`)

Manage uploaded files.

**Source**: `apps/cli/src/commands/file.ts`

### `lh file list`

```bash
lh file list [--kb-id [-L [--json [fields]] < id > ] < n > ]
```

| Option            | Description              | Default |
| ----------------- | ------------------------ | ------- |
| `--kb-id <id>`    | Filter by knowledge base | -       |
| `-L, --limit <n>` | Maximum items            | `30`    |

**Table columns**: ID, NAME, TYPE, SIZE, UPDATED

### `lh file view <id>`

```bash
lh file view [fields]] < id > [--json
```

**Displays**: Name, type, size, chunking status, embedding status.

### `lh file delete <ids...>`

```bash
lh file delete [--yes] < id1 > [id2...]
```

Supports deleting multiple files at once.

### `lh file recent`

```bash
lh file recent [-L [--json [fields]] < n > ]
```

| Option            | Description     | Default |
| ----------------- | --------------- | ------- |
| `-L, --limit <n>` | Number of items | `10`    |

---

## Document Management (`lh doc`)

Manage text documents (notes, wiki pages).

**Source**: `apps/cli/src/commands/doc.ts`

### `lh doc list`

```bash
lh doc list [-L [--file-type [--source-type [--json [fields]] < n > ] < type > ] < type > ]
```

| Option                 | Description                                   | Default |
| ---------------------- | --------------------------------------------- | ------- |
| `-L, --limit <n>`      | Maximum items                                 | `30`    |
| `--file-type <type>`   | Filter by file type                           | -       |
| `--source-type <type>` | Filter by source type (file, web, api, topic) | -       |

**Table columns**: ID, TITLE, TYPE, UPDATED

### `lh doc view <id>`

```bash
lh doc view [fields]] < id > [--json
```

**Displays**: Title, type, KB association, updated time, full content.

### `lh doc create`

```bash
lh doc create -t [-F [--parent [--slug [--kb [--file-type < title > [-b < body > ] < path > ] < id > ] < slug > ] < id > ] < type > ]
```

| Option                   | Description                                     | Required |
| ------------------------ | ----------------------------------------------- | -------- |
| `-t, --title <title>`    | Document title                                  | Yes      |
| `-b, --body <content>`   | Document body text                              | No       |
| `-F, --body-file <path>` | Read body from file                             | No       |
| `--parent <id>`          | Parent document ID                              | No       |
| `--slug <slug>`          | Custom URL slug                                 | No       |
| `--kb <id>`              | Knowledge base ID to associate with             | No       |
| `--file-type <type>`     | File type (e.g. custom/document, custom/folder) | No       |

`-b` and `-F` are mutually exclusive; `-F` reads the file content as the body.

### `lh doc batch-create <file>`

Batch create documents from a JSON file. The file must contain a non-empty array of document objects.

```bash
lh doc batch-create documents.json
```

Each object in the array can have: `title`, `content`, `fileType`, `knowledgeBaseId`, `parentId`, `slug`.

### `lh doc edit <id>`

```bash
lh doc edit [-b [-F [--parent [--file-type < id > [-t < title > ] < body > ] < path > ] < id > ] < type > ]
```

### `lh doc delete <ids...>`

```bash
lh doc delete [--yes] < id1 > [id2...]
```

### `lh doc parse <fileId>`

Parse an uploaded file into a document.

```bash
lh doc parse [--json [fields]] < fileId > [--with-pages]
```

| Option         | Description             |
| -------------- | ----------------------- |
| `--with-pages` | Preserve page structure |

**Output**: Parsed title and content preview.

### `lh doc link-topic <docId> <topicId>`

Associate a document with a topic. Creates a linked copy via the notebook router.

```bash
lh doc link-topic <docId> <topicId>
```

### `lh doc topic-docs <topicId>`

List documents associated with a topic.

```bash
lh doc topic-docs [--json [fields]] < topicId > [--type < type > ]
```

| Option          | Description                                      |
| --------------- | ------------------------------------------------ |
| `--type <type>` | Filter by type (article, markdown, note, report) |


================================================
FILE: .agents/skills/cli/references/memory.md
================================================
# Memory Commands

Manage user memories - the AI's long-term knowledge about users.

**Source**: `apps/cli/src/commands/memory.ts`

## Memory Categories

| Category     | Description                               |
| ------------ | ----------------------------------------- |
| `identity`   | User's name, role, relationships          |
| `activity`   | Recent activities and their status        |
| `context`    | Ongoing contexts, projects, goals         |
| `experience` | Past experiences and key learnings        |
| `preference` | User preferences, directives, suggestions |

---

## `lh memory list [category]`

List memory entries, optionally filtered by category.

```bash
lh memory list            # All categories
lh memory list identity   # Only identity memories
lh memory list preference # Only preferences
```

| Option            | Description |
| ----------------- | ----------- |
| `--json [fields]` | JSON output |

**Output**: Grouped by category, showing type/status and descriptions.

---

## `lh memory create`

Create a new identity memory entry.

```bash
lh memory create [options]
```

| Option                     | Description              |
| -------------------------- | ------------------------ |
| `--type <type>`            | Memory type              |
| `--role <role>`            | User's role              |
| `--relationship <rel>`     | Relationship description |
| `-d, --description <desc>` | Description              |
| `--labels <labels...>`     | Extracted labels         |

---

## `lh memory edit <category> <id>`

Edit a memory entry. Options vary by category:

```bash
lh memory edit identity < id > [options]
lh memory edit activity < id > [options]
lh memory edit context < id > [options]
lh memory edit experience < id > [options]
lh memory edit preference < id > [options]
```

### Category-specific Options

**identity**:

- `--type <type>`, `--role <role>`, `--relationship <rel>`

**activity**:

- `--narrative <text>`, `--notes <text>`, `--status <status>`

**context**:

- `--title <title>`, `--description <desc>`, `--status <status>`

**experience**:

- `--situation <text>`, `--action <text>`, `--key-learning <text>`

**preference**:

- `--directives <text>`, `--suggestions <text>`

---

## `lh memory delete <category> <id>`

```bash
lh memory delete identity < id > [--yes]
```

---

## `lh memory persona`

Display the compiled memory persona summary.

```bash
lh memory persona [--json [fields]]
```

**Output**: Summarized user profile built from all memory categories.

---

## `lh memory extract`

Trigger async memory extraction from chat history.

```bash
lh memory extract [--from [--to < date > ] < date > ]
```

| Option          | Description             |
| --------------- | ----------------------- |
| `--from <date>` | Start date (ISO format) |
| `--to <date>`   | End date (ISO format)   |

Starts a background task that analyzes chat history and creates new memory entries.

---

## `lh memory extract-status`

Check the status of a memory extraction task.

```bash
lh memory extract-status [--task-id [--json [fields]] < id > ]
```

| Option           | Description         |
| ---------------- | ------------------- |
| `--task-id <id>` | Check specific task |


================================================
FILE: .agents/skills/cli/references/models-providers.md
================================================
# Model & Provider Commands

## Model Management (`lh model`)

Manage AI models within providers.

**Source**: `apps/cli/src/commands/model.ts`

### `lh model list <providerId>`

List models for a specific provider.

```bash
lh model list openai
lh model list openai --type image --enabled
lh model list lobehub --type video --json
```

| Option            | Description                                                                            | Default |
| ----------------- | -------------------------------------------------------------------------------------- | ------- |
| `-L, --limit <n>` | Maximum items                                                                          | `50`    |
| `--enabled`       | Only show enabled models                                                               | `false` |
| `--type <type>`   | Filter by model type (`chat\|embedding\|tts\|stt\|image\|video\|text2music\|realtime`) | -       |
| `--json [fields]` | Output JSON, optionally specify fields                                                 | -       |

**Table columns**: ID, NAME, ENABLED, TYPE

**Backend**: `aiModel.getAiProviderModelList` → `AiInfraRepos.getAiProviderModelList` (supports `type` filter at repository level)

### `lh model view <id>`

```bash
lh model view [fields]] < modelId > [--json
```

**Displays**: Name, provider, type, enabled status, capabilities.

### `lh model create`

```bash
lh model create --id [--type < id > --provider < providerId > [--display-name < name > ] < type > ]
```

| Option                    | Description  | Default  |
| ------------------------- | ------------ | -------- |
| `--id <id>`               | Model ID     | Required |
| `--provider <providerId>` | Provider ID  | Required |
| `--display-name <name>`   | Display name | -        |
| `--type <type>`           | Model type   | `chat`   |

### `lh model edit <id>`

```bash
lh model edit [--type < modelId > --provider < providerId > [--display-name < name > ] < type > ]
```

### `lh model toggle <id>`

Enable or disable a model.

```bash
lh model toggle < modelId > --provider < providerId > --enable
lh model toggle < modelId > --provider < providerId > --disable
```

| Option                    | Description       | Required     |
| ------------------------- | ----------------- | ------------ |
| `--provider <providerId>` | Provider ID       | Yes          |
| `--enable`                | Enable the model  | One required |
| `--disable`               | Disable the model | One required |

### `lh model batch-toggle <ids...>`

Enable or disable multiple models at once.

```bash
lh model batch-toggle model1 model2 model3 --provider openai --enable
```

### `lh model delete <id>`

```bash
lh model delete < modelId > --provider < providerId > [--yes]
```

### `lh model clear`

Clear all models (or only remote/fetched models) for a provider.

```bash
lh model clear --provider [--yes] < providerId > [--remote]
```

---

## Provider Management (`lh provider`)

Manage AI service providers.

**Source**: `apps/cli/src/commands/provider.ts`

### `lh provider list`

```bash
lh provider list [--json [fields]]
```

**Table columns**: ID, NAME, ENABLED, SOURCE

### `lh provider view <id>`

```bash
lh provider view [fields]] < providerId > [--json
```

**Displays**: Name, enabled status, source, configuration.

### `lh provider create`

```bash
lh provider create --id [-d [--logo [--sdk-type < id > -n < name > [-s < source > ] < desc > ] < url > ] < type > ]
```

| Option                     | Description                                       | Default  |
| -------------------------- | ------------------------------------------------- | -------- |
| `--id <id>`                | Provider ID                                       | Required |
| `-n, --name <name>`        | Provider name                                     | Required |
| `-s, --source <source>`    | Source type (`builtin` or `custom`)               | `custom` |
| `-d, --description <desc>` | Provider description                              | -        |
| `--logo <logo>`            | Provider logo URL                                 | -        |
| `--sdk-type <sdkType>`     | SDK type (openai, anthropic, azure, bedrock, ...) | -        |

### `lh provider edit <id>`

```bash
lh provider edit [-d [--logo [--sdk-type < providerId > [-n < name > ] < desc > ] < url > ] < type > ]
```

Requires at least one change flag.

### `lh provider config <id>`

Configure provider settings (API key, base URL, etc.).

```bash
lh provider config openai --api-key sk-xxx
lh provider config openai --base-url https://custom-endpoint.com
lh provider config openai --show
lh provider config openai --show --json
```

| Option                   | Description                       |
| ------------------------ | --------------------------------- |
| `--api-key <key>`        | Set API key                       |
| `--base-url <url>`       | Set base URL                      |
| `--check-model <model>`  | Set connectivity check model      |
| `--enable-response-api`  | Enable Response API mode (OpenAI) |
| `--disable-response-api` | Disable Response API mode         |
| `--fetch-on-client`      | Enable fetching models on client  |
| `--no-fetch-on-client`   | Disable fetching models on client |
| `--show`                 | Show current config               |
| `--json [fields]`        | Output JSON (with --show)         |

**Important**: The `lobehub` provider is platform-managed. Attempting to set `--api-key` or `--base-url` on it will be rejected with an error message.

### `lh provider test <id>`

Test provider connectivity.

```bash
lh provider test openai
lh provider test openai -m gpt-4o --json
```

### `lh provider toggle <id>`

```bash
lh provider toggle < providerId > --enable
lh provider toggle < providerId > --disable
```

### `lh provider delete <id>`

```bash
lh provider delete < providerId > [--yes]
```


================================================
FILE: .agents/skills/cli/references/search-config.md
================================================
# Search & Configuration Commands

## Global Search (`lh search`)

Search across all LobeHub resource types.

**Source**: `apps/cli/src/commands/search.ts`

### `lh search <query>`

```bash
lh search "meeting notes" [-t [-L [--json [fields]] < type > ] < n > ]
```

| Option              | Description             | Default   |
| ------------------- | ----------------------- | --------- |
| `-t, --type <type>` | Filter by resource type | All types |
| `-L, --limit <n>`   | Results per type        | `10`      |

### Searchable Types

| Type             | Description                  |
| ---------------- | ---------------------------- |
| `agent`          | AI agents                    |
| `topic`          | Conversation topics          |
| `file`           | Uploaded files               |
| `folder`         | File folders                 |
| `message`        | Chat messages                |
| `page`           | Documents/pages              |
| `memory`         | User memories                |
| `mcp`            | MCP servers                  |
| `plugin`         | Installed plugins            |
| `communityAgent` | Community marketplace agents |
| `knowledgeBase`  | Knowledge bases              |

**Output**: Results grouped by type, showing ID, title/name, description.

---

## User Configuration (`lh whoami` / `lh usage`)

**Source**: `apps/cli/src/commands/config.ts`

### `lh whoami`

Display current authenticated user information.

```bash
lh whoami [--json [fields]]
```

**Displays**: Name, username, email, user ID, subscription plan.

### `lh usage`

Display usage statistics.

```bash
lh usage [--month [--daily] [--json [fields]] < YYYY-MM > ]
```

| Option              | Description    | Default                 |
| ------------------- | -------------- | ----------------------- |
| `--month <YYYY-MM>` | Month to query | Current month           |
| `--daily`           | Group by day   | `false` (monthly total) |

**Output**: Token usage, costs, and model breakdown for the specified period.

---

## Global Options

These options are available across most commands:

| Option            | Description                                                            |
| ----------------- | ---------------------------------------------------------------------- |
| `--json [fields]` | Output as JSON; optionally filter to specific fields (comma-separated) |
| `--yes`           | Skip confirmation prompts for destructive operations                   |
| `-L, --limit <n>` | Pagination limit for list commands                                     |
| `-v, --verbose`   | Enable verbose/debug logging                                           |
| `--help`          | Show command help                                                      |
| `--version`       | Show CLI version                                                       |

### JSON Field Filtering

The `--json` option supports field selection:

```bash
# Full JSON output
lh agent list --json

# Only specific fields
lh agent list --json "id,title,model"
```


================================================
FILE: .agents/skills/cli/references/skills-plugins.md
================================================
# Skill & Plugin Commands

## Skill Management (`lh skill`)

Manage agent skills (custom instructions and capabilities).

**Source**: `apps/cli/src/commands/skill.ts`

### `lh skill list`

```bash
lh skill list [--source [--json [fields]] < source > ]
```

| Option              | Description                         |
| ------------------- | ----------------------------------- |
| `--source <source>` | Filter: `builtin`, `market`, `user` |

**Table columns**: ID, NAME, DESCRIPTION, SOURCE, IDENTIFIER

### `lh skill view <id>`

```bash
lh skill view [fields]] < id > [--json
```

**Displays**: Name, description, source, identifier, content.

### `lh skill create`

```bash
lh skill create -n < name > -d < desc > -c < content > [-i < identifier > ]
```

| Option                     | Description                         | Required |
| -------------------------- | ----------------------------------- | -------- |
| `-n, --name <name>`        | Skill name                          | Yes      |
| `-d, --description <desc>` | Description                         | Yes      |
| `-c, --content <content>`  | Skill content (prompt/instructions) | Yes      |
| `-i, --identifier <id>`    | Custom identifier                   | No       |

### `lh skill edit <id>`

```bash
lh skill edit [-n [-d < id > [-c < content > ] < name > ] < desc > ]
```

### `lh skill delete <id>`

```bash
lh skill delete < id > [--yes]
```

### `lh skill search <query>`

```bash
lh skill search [fields]] < query > [--json
```

### `lh skill install <source>` (alias: `lh skill i`)

Install a skill. Auto-detects source type from the input:

```bash
# GitHub (URL or owner/repo shorthand)
lh skill install lobehub/skill-repo
lh skill install https://github.com/lobehub/skill-repo
lh skill install lobehub/skill-repo --branch dev

# ZIP URL
lh skill install https://example.com/skill.zip

# Marketplace identifier
lh skill install my-cool-skill
lh skill i my-cool-skill
```

| Option              | Description               | Notes    |
| ------------------- | ------------------------- | -------- |
| `--branch <branch>` | Branch name (GitHub only) | Optional |

**Detection rules**:

- `https://github.com/...` or `owner/repo` → GitHub
- Other `https://...` URLs → ZIP URL
- Everything else → marketplace identifier

### Resource Commands

#### `lh skill resources <id>`

List files/resources within a skill.

```bash
lh skill resources [fields]] < id > [--json
```

**Displays**: Path, type, size.

#### `lh skill read-resource <id> <path>`

Read a specific resource file from a skill.

```bash
lh skill read-resource <skillId> <path>
```

**Output**: File content or JSON metadata.

---

## Plugin Management (`lh plugin`)

Install and manage plugins (external tool integrations).

**Source**: `apps/cli/src/commands/plugin.ts`

### `lh plugin list`

```bash
lh plugin list [--json [fields]]
```

**Table columns**: ID, IDENTIFIER, TYPE, TITLE

### `lh plugin install`

```bash
lh plugin install -i [--settings < identifier > --manifest < json > [--type < type > ] < json > ]
```

| Option                  | Description                | Required               |
| ----------------------- | -------------------------- | ---------------------- |
| `-i, --identifier <id>` | Plugin identifier          | Yes                    |
| `--manifest <json>`     | Plugin manifest JSON       | Yes                    |
| `--type <type>`         | `plugin` or `customPlugin` | No (default: `plugin`) |
| `--settings <json>`     | Plugin settings JSON       | No                     |

### `lh plugin uninstall <id>`

```bash
lh plugin uninstall < id > [--yes]
```

### `lh plugin update <id>`

```bash
lh plugin update [--settings < id > [--manifest < json > ] < json > ]
```


================================================
FILE: .agents/skills/code-review/SKILL.md
================================================
---
name: code-review
description: 'Code review checklist for LobeHub. Use when reviewing PRs, diffs, or code changes. Covers correctness, security, quality, and project-specific patterns.'
---

# Code Review Guide

## Before You Start

1. Read `/typescript` and `/testing` skills for code style and test conventions
2. Get the diff (skip if already in context, e.g., injected by GitHub review app): `git diff` or `git diff origin/canary..HEAD`

## Checklist

### Correctness

- Leftover `console.log` / `console.debug` — should use `debug` package or remove
- Missing `return await` in try/catch — see <https://typescript-eslint.io/rules/return-await/> (not in our ESLint config yet, requires type info)
- Can the fix/implementation be more concise, efficient, or have better compatibility?

### Security

- No sensitive data (API keys, tokens, credentials) in `console.*` or `debug()` output
- No base64 output to terminal — extremely long, freezes output
- No hardcoded secrets — use environment variables

### Testing

- Bug fixes must include tests covering the fixed scenario
- New logic (services, store actions, utilities) should have test coverage
- Existing tests still cover the changed behavior?
- Prefer `vi.spyOn` over `vi.mock` (see `/testing` skill)

### i18n

- New user-facing strings use i18n keys, not hardcoded text
- Keys added to `src/locales/default/{namespace}.ts` with `{feature}.{context}.{action|status}` naming
- For PRs: `locales/` translations for all languages updated (`pnpm i18n`)

### SPA / routing

- **`desktopRouter` pair:** If the diff touches `src/spa/router/desktopRouter.config.tsx`, does it also update `src/spa/router/desktopRouter.config.desktop.tsx` with the same route paths and nesting? Single-file edits often cause drift and blank screens.

### Reuse

- Newly written code duplicates existing utilities in `packages/utils` or shared modules?
- Copy-pasted blocks with slight variation — extract into shared function
- `antd` imports replaceable with `@lobehub/ui` wrapped components (`Input`, `Button`, `Modal`, `Avatar`, etc.)
- Use `antd-style` token system, not hardcoded colors

### Database

- Migration scripts must be idempotent (`IF NOT EXISTS`, `IF EXISTS` guards)

### Cloud Impact

A downstream cloud deployment depends on this repo. Flag changes that may require cloud-side updates:

- **Backend route paths changed** — e.g., renaming `src/app/(backend)/webapi/chat/route.ts` or changing its exports
- **SSR page paths changed** — e.g., moving/renaming files under `src/app/[variants]/(auth)/`
- **Dependency versions bumped** — e.g., upgrading `next` or `drizzle-orm` in `package.json`
- **`@lobechat/business-*` exports changed** — e.g., renaming a function in `src/business/` or changing type signatures in `packages/business/`
- `src/business/` and `packages/business/` must not expose cloud commercial logic in comments or code

## Output Format

For local CLI review only (GitHub review app posts inline PR comments instead):

- Number all findings sequentially
- Indicate priority: `[high]` / `[medium]` / `[low]`
- Include file path and line number for each finding
- Only list problems — no summary, no praise
- Re-read full source for each finding to verify it's real, then output "All findings verified."


================================================
FILE: .agents/skills/data-fetching/SKILL.md
================================================
---
name: data-fetching
description: Data fetching architecture guide using Service layer + Zustand Store + SWR. Use when implementing data fetching, creating services, working with store hooks, or migrating from useEffect. Triggers on data loading, API calls, service creation, or store data fetching tasks.
---

# LobeHub Data Fetching Architecture

> **Related Skills:**
>
> - `store-data-structures` - How to structure List and Detail data in stores (Map vs Array patterns)

## Architecture Overview

```
┌─────────────┐
│  Component  │
└──────┬──────┘
       │ 1. Call useFetchXxx hook from store
       ↓
┌──────────────────┐
│  Zustand Store   │
│  (State + Hook)  │
└──────┬───────────┘
       │ 2. useClientDataSWR calls service
       ↓
┌──────────────────┐
│  Service Layer   │
│  (xxxService)    │
└──────┬───────────┘
       │ 3. Call lambdaClient
       ↓
┌──────────────────┐
│  lambdaClient    │
│  (TRPC Client)   │
└──────────────────┘
```

## Core Principles

### ✅ DO

1. **Use Service Layer** for all API calls
2. **Use Store SWR Hooks** for data fetching (not useEffect)
3. **Use proper data structures** - See `store-data-structures` skill for List vs Detail patterns
4. **Use lambdaClient.mutate** for write operations (create/update/delete)
5. **Use lambdaClient.query** only inside service methods

### ❌ DON'T

1. **Never use useEffect** for data fetching
2. **Never call lambdaClient** directly in components or stores
3. **Never use useState** for server data
4. **Never mix data structure patterns** - Follow `store-data-structures` skill

> **Note:** For data structure patterns (Map vs Array, List vs Detail), see the `store-data-structures` skill.

---

## Layer 1: Service Layer

### Purpose

- Encapsulate all API calls to lambdaClient
- Provide clean, typed interfaces
- Single source of truth for API operations

### Service Structure

```typescript
// src/services/agentEval.ts
import { lambdaClient } from '@/libs/trpc/client';

class AgentEvalService {
  // Query methods - READ operations
  async listBenchmarks() {
    return lambdaClient.agentEval.listBenchmarks.query();
  }

  async getBenchmark(id: string) {
    return lambdaClient.agentEval.getBenchmark.query({ id });
  }

  // Mutation methods - WRITE operations
  async createBenchmark(params: CreateBenchmarkParams) {
    return lambdaClient.agentEval.createBenchmark.mutate(params);
  }

  async updateBenchmark(params: UpdateBenchmarkParams) {
    return lambdaClient.agentEval.updateBenchmark.mutate(params);
  }

  async deleteBenchmark(id: string) {
    return lambdaClient.agentEval.deleteBenchmark.mutate({ id });
  }
}

export const agentEvalService = new AgentEvalService();
```

### Service Guidelines

1. **One service per domain** (e.g., agentEval, ragEval, aiAgent)
2. **Export singleton instance** (`export const xxxService = new XxxService()`)
3. **Method names match operations** (list, get, create, update, delete)
4. **Clear parameter types** (use interfaces for complex params)

---

## Layer 2: Store with SWR Hooks

### Purpose

- Manage client-side state
- Provide SWR hooks for data fetching
- Handle cache invalidation

> **Data Structure:** See `store-data-structures` skill for how to structure List and Detail data.

### Store Structure Overview

```typescript
// src/store/eval/slices/benchmark/initialState.ts
import type { AgentEvalBenchmark, AgentEvalBenchmarkListItem } from '@lobechat/types';

export interface BenchmarkSliceState {
  // List data - simple array (see store-data-structures skill)
  benchmarkList: AgentEvalBenchmarkListItem[];
  benchmarkListInit: boolean;

  // Detail data - map for caching (see store-data-structures skill)
  benchmarkDetailMap: Record<string, AgentEvalBenchmark>;
  loadingBenchmarkDetailIds: string[];

  // Mutation states
  isCreatingBenchmark: boolean;
  isUpdatingBenchmark: boolean;
  isDeletingBenchmark: boolean;
}
```

> For complete initialState, reducer, and internal dispatch patterns, see the `store-data-structures` skill.

### Create Actions

```typescript
// src/store/eval/slices/benchmark/action.ts
import type { SWRResponse } from 'swr';
import type { StateCreator } from 'zustand/vanilla';
import isEqual from 'fast-deep-equal';

import { mutate, useClientDataSWR } from '@/libs/swr';
import { agentEvalService } from '@/services/agentEval';
import type { EvalStore } from '@/store/eval/store';
import { benchmarkDetailReducer, type BenchmarkDetailDispatch } from './reducer';

const FETCH_BENCHMARKS_KEY = 'FETCH_BENCHMARKS';
const FETCH_BENCHMARK_DETAIL_KEY = 'FETCH_BENCHMARK_DETAIL';

export interface BenchmarkAction {
  // SWR Hooks - for data fetching
  useFetchBenchmarks: () => SWRResponse;
  useFetchBenchmarkDetail: (id?: string) => SWRResponse;

  // Refresh methods - for cache invalidation
  refreshBenchmarks: () => Promise<void>;
  refreshBenchmarkDetail: (id: string) => Promise<void>;

  // Mutation actions - for write operations
  createBenchmark: (params: CreateParams) => Promise<any>;
  updateBenchmark: (params: UpdateParams) => Promise<void>;
  deleteBenchmark: (id: string) => Promise<void>;

  // Internal methods - not for direct UI use
  internal_dispatchBenchmarkDetail: (payload: BenchmarkDetailDispatch) => void;
  internal_updateBenchmarkDetailLoading: (id: string, loading: boolean) => void;
}

export const createBenchmarkSlice: StateCreator<
  EvalStore,
  [['zustand/devtools', never]],
  [],
  BenchmarkAction
> = (set, get) => ({
  // Fetch list - Simple array
  useFetchBenchmarks: () => {
    return useClientDataSWR(FETCH_BENCHMARKS_KEY, () => agentEvalService.listBenchmarks(), {
      onSuccess: (data: any) => {
        set(
          {
            benchmarkList: data,
            benchmarkListInit: true,
          },
          false,
          'useFetchBenchmarks/success',
        );
      },
    });
  },

  // Fetch detail - Map with dispatch
  useFetchBenchmarkDetail: (id) => {
    return useClientDataSWR(
      id ? [FETCH_BENCHMARK_DETAIL_KEY, id] : null,
      () => agentEvalService.getBenchmark(id!),
      {
        onSuccess: (data: any) => {
          get().internal_dispatchBenchmarkDetail({
            type: 'setBenchmarkDetail',
            id: id!,
            value: data,
          });
          get().internal_updateBenchmarkDetailLoading(id!, false);
        },
      },
    );
  },

  // Refresh methods
  refreshBenchmarks: async () => {
    await mutate(FETCH_BENCHMARKS_KEY);
  },

  refreshBenchmarkDetail: async (id) => {
    await mutate([FETCH_BENCHMARK_DETAIL_KEY, id]);
  },

  // CREATE - Refresh list after creation
  createBenchmark: async (params) => {
    set({ isCreatingBenchmark: true }, false, 'createBenchmark/start');
    try {
      const result = await agentEvalService.createBenchmark(params);
      await get().refreshBenchmarks();
      return result;
    } finally {
      set({ isCreatingBenchmark: false }, false, 'createBenchmark/end');
    }
  },

  // UPDATE - With optimistic update for detail
  updateBenchmark: async (params) => {
    const { id } = params;

    // 1. Optimistic update
    get().internal_dispatchBenchmarkDetail({
      type: 'updateBenchmarkDetail',
      id,
      value: params,
    });

    // 2. Set loading
    get().internal_updateBenchmarkDetailLoading(id, true);

    try {
      // 3. Call service
      await agentEvalService.updateBenchmark(params);

      // 4. Refresh from server
      await get().refreshBenchmarks();
      await get().refreshBenchmarkDetail(id);
    } finally {
      get().internal_updateBenchmarkDetailLoading(id, false);
    }
  },

  // DELETE - Refresh list and remove from detail map
  deleteBenchmark: async (id) => {
    // 1. Optimistic update
    get().internal_dispatchBenchmarkDetail({
      type: 'deleteBenchmarkDetail',
      id,
    });

    // 2. Set loading
    get().internal_updateBenchmarkDetailLoading(id, true);

    try {
      // 3. Call service
      await agentEvalService.deleteBenchmark(id);

      // 4. Refresh list
      await get().refreshBenchmarks();
    } finally {
      get().internal_updateBenchmarkDetailLoading(id, false);
    }
  },

  // Internal - Dispatch to reducer (for detail map)
  internal_dispatchBenchmarkDetail: (payload) => {
    const currentMap = get().benchmarkDetailMap;
    const nextMap = benchmarkDetailReducer(currentMap, payload);

    // No need to update if map is the same
    if (isEqual(nextMap, currentMap)) return;

    set({ benchmarkDetailMap: nextMap }, false, `dispatchBenchmarkDetail/${payload.type}`);
  },

  // Internal - Update loading state for specific detail
  internal_updateBenchmarkDetailLoading: (id, loading) => {
    set(
      (state) => {
        if (loading) {
          return { loadingBenchmarkDetailIds: [...state.loadingBenchmarkDetailIds, id] };
        }
        return {
          loadingBenchmarkDetailIds: state.loadingBenchmarkDetailIds.filter((i) => i !== id),
        };
      },
      false,
      'updateBenchmarkDetailLoading',
    );
  },
});
```

### Store Guidelines

1. **SWR keys as constants** at top of file
2. **useClientDataSWR** for all data fetching (never useEffect)
3. **onSuccess callback** updates store state
4. **Refresh methods** use `mutate()` to invalidate cache
5. **Loading states** in initialState, updated in onSuccess
6. **Mutations** call service, then refresh relevant cache

---

## Layer 3: Component Usage

### Data Fetching in Components

**Fetching List Data:**

```typescript
// Component using list data - ✅ CORRECT
import { useEvalStore } from '@/store/eval';

const BenchmarkList = () => {
  // 1. Get the hook from store
  const useFetchBenchmarks = useEvalStore((s) => s.useFetchBenchmarks);

  // 2. Get list data
  const benchmarks = useEvalStore((s) => s.benchmarkList);
  const isInit = useEvalStore((s) => s.benchmarkListInit);

  // 3. Call the hook (SWR handles the data fetching)
  useFetchBenchmarks();

  // 4. Use the data
  if (!isInit) return <Loading />;
  return (
    <div>
      <h2>Total: {benchmarks.length}</h2>
      {benchmarks.map(b => <BenchmarkCard key={b.id} {...b} />)}
    </div>
  );
};
```

**Fetching Detail Data:**

```typescript
// Component using detail data from map - ✅ CORRECT
import { useEvalStore } from '@/store/eval';
import { useParams } from 'react-router-dom';

const BenchmarkDetail = () => {
  const { benchmarkId } = useParams<{ benchmarkId: string }>();

  // 1. Get the hook
  const useFetchBenchmarkDetail = useEvalStore((s) => s.useFetchBenchmarkDetail);

  // 2. Get detail from map
  const benchmark = useEvalStore((s) =>
    benchmarkId ? s.benchmarkDetailMap[benchmarkId] : undefined,
  );

  // 3. Get loading state
  const isLoading = useEvalStore((s) =>
    benchmarkId ? s.loadingBenchmarkDetailIds.includes(benchmarkId) : false,
  );

  // 4. Call the hook
  useFetchBenchmarkDetail(benchmarkId);

  // 5. Use the data
  if (!benchmark) return <Loading />;
  return (
    <div>
      <h1>{benchmark.name}</h1>
      <p>{benchmark.description}</p>
      {isLoading && <Spinner />}
    </div>
  );
};
```

**Using Selectors (Recommended):**

```typescript
// src/store/eval/slices/benchmark/selectors.ts
export const benchmarkSelectors = {
  getBenchmarkDetail: (id: string) => (s: EvalStore) => s.benchmarkDetailMap[id],
  isLoadingBenchmarkDetail: (id: string) => (s: EvalStore) =>
    s.loadingBenchmarkDetailIds.includes(id),
};

// Component with selectors
const BenchmarkDetail = () => {
  const { benchmarkId } = useParams();
  const useFetchBenchmarkDetail = useEvalStore((s) => s.useFetchBenchmarkDetail);
  const benchmark = useEvalStore(benchmarkSelectors.getBenchmarkDetail(benchmarkId!));

  useFetchBenchmarkDetail(benchmarkId);

  return <div>{benchmark && <h1>{benchmark.name}</h1>}</div>;
};
```

### What NOT to Do

```typescript
// ❌ WRONG - Don't use useEffect for data fetching
const BenchmarkList = () => {
  const [data, setData] = useState([]);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    const fetchData = async () => {
      setLoading(true);
      const result = await lambdaClient.agentEval.listBenchmarks.query();
      setData(result);
      setLoading(false);
    };
    fetchData();
  }, []);

  return <div>...</div>;
};
```

### Mutations in Components

```typescript
// Mutations (Create/Update/Delete) with optimistic updates - ✅ CORRECT
import { useEvalStore } from '@/store/eval';
import { benchmarkSelectors } from '@/store/eval/selectors';

const CreateBenchmarkModal = () => {
  const createBenchmark = useEvalStore((s) => s.createBenchmark);

  const handleSubmit = async (values) => {
    try {
      // Optimistic update happens inside createBenchmark
      await createBenchmark(values);
      message.success('Created successfully');
      onClose();
    } catch (error) {
      message.error('Failed to create');
    }
  };

  return <Form onSubmit={handleSubmit}>...</Form>;
};

// With loading state for specific item
const BenchmarkItem = ({ id }: { id: string }) => {
  const updateBenchmark = useEvalStore((s) => s.updateBenchmark);
  const deleteBenchmark = useEvalStore((s) => s.deleteBenchmark);
  const isLoading = useEvalStore(benchmarkSelectors.isLoadingBenchmark(id));

  const handleUpdate = async (data) => {
    await updateBenchmark({ id, ...data });
  };

  const handleDelete = async () => {
    await deleteBenchmark(id);
  };

  return (
    <div>
      {isLoading && <Spinner />}
      <button onClick={handleUpdate}>Update</button>
      <button onClick={handleDelete}>Delete</button>
    </div>
  );
};
```

---

> **Data Structures:** For detailed comparison of List vs Detail patterns, see the `store-data-structures` skill.

---

## Complete Example: Adding a New Feature

### Scenario: Add "Dataset" data fetching with optimistic updates

#### Step 1: Create Service

```typescript
// src/services/agentEval.ts
class AgentEvalService {
  // ... existing methods ...

  // Add new methods
  async listDatasets(benchmarkId: string) {
    return lambdaClient.agentEval.listDatasets.query({ benchmarkId });
  }

  async getDataset(id: string) {
    return lambdaClient.agentEval.getDataset.query({ id });
  }

  async createDataset(params: CreateDatasetParams) {
    return lambdaClient.agentEval.createDataset.mutate(params);
  }
}
```

#### Step 2: Create Reducer

```typescript
// src/store/eval/slices/dataset/reducer.ts
import { produce } from 'immer';
import type { Dataset } from '@/types/dataset';

type AddDatasetAction = {
  type: 'addDataset';
  value: Dataset;
};

type UpdateDatasetAction = {
  id: string;
  type: 'updateDataset';
  value: Partial<Dataset>;
};

type DeleteDatasetAction = {
  id: string;
  type: 'deleteDataset';
};

export type DatasetDispatch = AddDatasetAction | UpdateDatasetAction | DeleteDatasetAction;

export const datasetReducer = (state: Dataset[] = [], payload: DatasetDispatch): Dataset[] => {
  switch (payload.type) {
    case 'addDataset': {
      return produce(state, (draft) => {
        draft.unshift(payload.value);
      });
    }

    case 'updateDataset': {
      return produce(state, (draft) => {
        const index = draft.findIndex((item) => item.id === payload.id);
        if (index !== -1) {
          draft[index] = { ...draft[index], ...payload.value };
        }
      });
    }

    case 'deleteDataset': {
      return produce(state, (draft) => {
        const index = draft.findIndex((item) => item.id === payload.id);
        if (index !== -1) {
          draft.splice(index, 1);
        }
      });
    }

    default:
      return state;
  }
};
```

#### Step 3: Create Store Slice

```typescript
// src/store/eval/slices/dataset/initialState.ts
import type { Dataset } from '@/types/dataset';

export interface DatasetData {
  currentPage: number;
  hasMore: boolean;
  isLoading: boolean;
  items: Dataset[];
  pageSize: number;
  total: number;
}

export interface DatasetSliceState {
  // Map keyed by benchmarkId
  datasetMap: Record<string, DatasetData>;
  // Simple state for single item (read-only, used in modals)
  datasetDetail: Dataset | null;
  isLoadingDatasetDetail: boolean;
  loadingDatasetIds: string[];
}

export const datasetInitialState: DatasetSliceState = {
  datasetMap: {},
  datasetDetail: null,
  isLoadingDatasetDetail: false,
  loadingDatasetIds: [],
};
```

```typescript
// src/store/eval/slices/dataset/action.ts
import type { SWRResponse } from 'swr';
import type { StateCreator } from 'zustand/vanilla';
import isEqual from 'fast-deep-equal';

import { mutate, useClientDataSWR } from '@/libs/swr';
import { agentEvalService } from '@/services/agentEval';
import type { EvalStore } from '@/store/eval/store';
import { datasetReducer, type DatasetDispatch } from './reducer';

const FETCH_DATASETS_KEY = 'FETCH_DATASETS';
const FETCH_DATASET_DETAIL_KEY = 'FETCH_DATASET_DETAIL';

export interface DatasetAction {
  // SWR Hooks
  useFetchDatasets: (benchmarkId?: string) => SWRResponse;
  useFetchDatasetDetail: (id?: string) => SWRResponse;

  // Refresh methods
  refreshDatasets: (benchmarkId: string) => Promise<void>;
  refreshDatasetDetail: (id: string) => Promise<void>;

  // Mutations
  createDataset: (params: any) => Promise<any>;
  updateDataset: (params: any) => Promise<void>;
  deleteDataset: (id: string, benchmarkId: string) => Promise<void>;

  // Internal methods
  internal_dispatchDataset: (payload: DatasetDispatch, benchmarkId: string) => void;
  internal_updateDatasetLoading: (id: string, loading: boolean) => void;
}

export const createDatasetSlice: StateCreator<
  EvalStore,
  [['zustand/devtools', never]],
  [],
  DatasetAction
> = (set, get) => ({
  // Fetch list with Map
  useFetchDatasets: (benchmarkId) => {
    return useClientDataSWR(
      benchmarkId ? [FETCH_DATASETS_KEY, benchmarkId] : null,
      () => agentEvalService.listDatasets(benchmarkId!),
      {
        onSuccess: (data: any) => {
          set(
            {
              datasetMap: {
                ...get().datasetMap,
                [benchmarkId!]: {
                  currentPage: 1,
                  hasMore: false,
                  isLoading: false,
                  items: data,
                  pageSize: data.length,
                  total: data.length,
                },
              },
            },
            false,
            'useFetchDatasets/success',
          );
        },
      },
    );
  },

  // Fetch single item (for modal display)
  useFetchDatasetDetail: (id) => {
    return useClientDataSWR(
      id ? [FETCH_DATASET_DETAIL_KEY, id] : null,
      () => agentEvalService.getDataset(id!),
      {
        onSuccess: (data: any) => {
          set(
            { datasetDetail: data, isLoadingDatasetDetail: false },
            false,
            'useFetchDatasetDetail/success',
          );
        },
      },
    );
  },

  refreshDatasets: async (benchmarkId) => {
    await mutate([FETCH_DATASETS_KEY, benchmarkId]);
  },

  refreshDatasetDetail: async (id) => {
    await mutate([FETCH_DATASET_DETAIL_KEY, id]);
  },

  // CREATE with optimistic update
  createDataset: async (params) => {
    const tmpId = Date.now().toString();
    const { benchmarkId } = params;

    get().internal_dispatchDataset(
      {
        type: 'addDataset',
        value: { ...params, id: tmpId, createdAt: Date.now() } as any,
      },
      benchmarkId,
    );

    get().internal_updateDatasetLoading(tmpId, true);

    try {
      const result = await agentEvalService.createDataset(params);
      await get().refreshDatasets(benchmarkId);
      return result;
    } finally {
      get().internal_updateDatasetLoading(tmpId, false);
    }
  },

  // UPDATE with optimistic update
  updateDataset: async (params) => {
    const { id, benchmarkId } = params;

    get().internal_dispatchDataset(
      {
        type: 'updateDataset',
        id,
        value: params,
      },
      benchmarkId,
    );

    get().internal_updateDatasetLoading(id, true);

    try {
      await agentEvalService.updateDataset(params);
      await get().refreshDatasets(benchmarkId);
    } finally {
      get().internal_updateDatasetLoading(id, false);
    }
  },

  // DELETE with optimistic update
  deleteDataset: async (id, benchmarkId) => {
    get().internal_dispatchDataset(
      {
        type: 'deleteDataset',
        id,
      },
      benchmarkId,
    );

    get().internal_updateDatasetLoading(id, true);

    try {
      await agentEvalService.deleteDataset(id);
      await get().refreshDatasets(benchmarkId);
    } finally {
      get().internal_updateDatasetLoading(id, false);
    }
  },

  // Internal - Dispatch to reducer
  internal_dispatchDataset: (payload, benchmarkId) => {
    const currentData = get().datasetMap[benchmarkId];
    const nextItems = datasetReducer(currentData?.items, payload);

    if (isEqual(nextItems, currentData?.items)) return;

    set(
      {
        datasetMap: {
          ...get().datasetMap,
          [benchmarkId]: {
            ...currentData,
            currentPage: currentData?.currentPage ?? 1,
            hasMore: currentData?.hasMore ?? false,
            isLoading: false,
            items: nextItems,
            pageSize: currentData?.pageSize ?? nextItems.length,
            total: currentData?.total ?? nextItems.length,
          },
        },
      },
      false,
      `dispatchDataset/${payload.type}`,
    );
  },

  // Internal - Update loading state
  internal_updateDatasetLoading: (id, loading) => {
    set(
      (state) => {
        if (loading) {
          return { loadingDatasetIds: [...state.loadingDatasetIds, id] };
        }
        return {
          loadingDatasetIds: state.loadingDatasetIds.filter((i) => i !== id),
        };
      },
      false,
      'updateDatasetLoading',
    );
  },
});
```

#### Step 3: Integrate into Store

```typescript
// src/store/eval/store.ts
import { createDatasetSlice, type DatasetAction } from './slices/dataset/action';

export type EvalStore = EvalStoreState &
  BenchmarkAction &
  DatasetAction & // Add here
  RunAction;

const createStore: StateCreator<EvalStore, [['zustand/devtools', never]]> = (set, get, store) => ({
  ...initialState,
  ...createBenchmarkSlice(set, get, store),
  ...createDatasetSlice(set, get, store), // Add here
  ...createRunSlice(set, get, store),
});
```

```typescript
// src/store/eval/initialState.ts
import { datasetInitialState, type DatasetSliceState } from './slices/dataset/initialState';

export interface EvalStoreState extends BenchmarkSliceState, DatasetSliceState {
  // ...
}

export const initialState: EvalStoreState = {
  ...benchmarkInitialState,
  ...datasetInitialState, // Add here
  ...runInitialState,
};
```

#### Step 4: Create Selectors (Optional but Recommended)

```typescript
// src/store/eval/slices/dataset/selectors.ts
import type { EvalStore } from '@/store/eval/store';

export const datasetSelectors = {
  getDatasetData: (benchmarkId: string) => (s: EvalStore) => s.datasetMap[benchmarkId],

  getDatasets: (benchmarkId: string) => (s: EvalStore) => s.datasetMap[benchmarkId]?.items ?? [],

  isLoadingDataset: (id: string) => (s: EvalStore) => s.loadingDatasetIds.includes(id),
};
```

#### Step 5: Use in Component

```typescript
// Component - List with Map
import { useEvalStore } from '@/store/eval';
import { datasetSelectors } from '@/store/eval/selectors';

const DatasetList = ({ benchmarkId }: { benchmarkId: string }) => {
  const useFetchDatasets = useEvalStore((s) => s.useFetchDatasets);
  const datasets = useEvalStore(datasetSelectors.getDatasets(benchmarkId));
  const datasetData = useEvalStore(datasetSelectors.getDatasetData(benchmarkId));

  useFetchDatasets(benchmarkId);

  if (datasetData?.isLoading) return <Loading />;

  return (
    <div>
      <h2>Total: {datasetData?.total ?? 0}</h2>
      <List data={datasets} />
    </div>
  );
};

// Component - Single item (for modal)
const DatasetImportModal = ({ open, datasetId }: Props) => {
  const useFetchDatasetDetail = useEvalStore((s) => s.useFetchDatasetDetail);
  const dataset = useEvalStore((s) => s.datasetDetail);
  const isLoading = useEvalStore((s) => s.isLoadingDatasetDetail);

  // Only fetch when modal is open
  useFetchDatasetDetail(open && datasetId ? datasetId : undefined);

  return (
    <Modal open={open}>
      {isLoading ? <Loading /> : <div>{dataset?.name}</div>}
    </Modal>
  );
};
```

---

## Common Patterns

### Pattern 1: List + Detail

```typescript
// List with pagination
useFetchTestCases: (params) => {
  const { datasetId, limit, offset } = params;
  return useClientDataSWR(
    datasetId ? [FETCH_TEST_CASES_KEY, datasetId, limit, offset] : null,
    () => agentEvalService.listTestCases({ datasetId, limit, offset }),
    {
      onSuccess: (data: any) => {
        set(
          {
            testCaseList: data.data,
            testCaseTotal: data.total,
            isLoadingTestCases: false,
          },
          false,
          'useFetchTestCases/success',
        );
      },
    },
  );
};
```

### Pattern 2: Dependent Fetching

```typescript
// Component
const BenchmarkDetail = () => {
  const { benchmarkId } = useParams();

  const useFetchBenchmarkDetail = useEvalStore((s) => s.useFetchBenchmarkDetail);
  const benchmark = useEvalStore((s) => s.benchmarkDetail);

  const useFetchDatasets = useEvalStore((s) => s.useFetchDatasets);
  const datasets = useEvalStore((s) => s.datasetList);

  // Fetch benchmark first
  useFetchBenchmarkDetail(benchmarkId);

  // Then fetch datasets for this benchmark
  useFetchDatasets(benchmarkId);

  return <div>...</div>;
};
```

### Pattern 3: Conditional Fetching

```typescript
// Only fetch when modal is open
const DatasetImportModal = ({ open, datasetId }: Props) => {
  const useFetchDatasetDetail = useEvalStore((s) => s.useFetchDatasetDetail);
  const dataset = useEvalStore((s) => s.datasetDetail);

  // Only fetch when open AND datasetId exists
  useFetchDatasetDetail(open && datasetId ? datasetId : undefined);

  return <Modal open={open}>...</Modal>;
};
```

### Pattern 4: Refresh After Mutation

```typescript
// Store action
createDataset: async (params) => {
  const result = await agentEvalService.createDataset(params);
  // Refresh the list after creation
  await get().refreshDatasets(params.benchmarkId);
  return result;
};

deleteDataset: async (id, benchmarkId) => {
  await agentEvalService.deleteDataset(id);
  // Refresh the list after deletion
  await get().refreshDatasets(benchmarkId);
};
```

---

## Migration Guide: useEffect → Store SWR

### Before (❌ Wrong)

```typescript
const TestCaseList = ({ datasetId }: Props) => {
  const [data, setData] = useState<any[]>([]);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    const fetchData = async () => {
      setLoading(true);
      try {
        const result = await lambdaClient.agentEval.listTestCases.query({
          datasetId,
        });
        setData(result.data);
      } finally {
        setLoading(false);
      }
    };
    fetchData();
  }, [datasetId]);

  return <Table data={data} loading={loading} />;
};
```

### After (✅ Correct)

```typescript
// 1. Create service method
class AgentEvalService {
  async listTestCases(params: { datasetId: string }) {
    return lambdaClient.agentEval.listTestCases.query(params);
  }
}

// 2. Create store slice
export const createTestCaseSlice: StateCreator<...> = (set) => ({
  useFetchTestCases: (params) => {
    return useClientDataSWR(
      params.datasetId ? [FETCH_TEST_CASES_KEY, params.datasetId] : null,
      () => agentEvalService.listTestCases(params),
      {
        onSuccess: (data: any) => {
          set(
            { testCaseList: data.data, isLoadingTestCases: false },
            false,
            'useFetchTestCases/success',
          );
        },
      },
    );
  },
});

// 3. Use in component
const TestCaseList = ({ datasetId }: Props) => {
  const useFetchTestCases = useEvalStore((s) => s.useFetchTestCases);
  const data = useEvalStore((s) => s.testCaseList);
  const loading = useEvalStore((s) => s.isLoadingTestCases);

  useFetchTestCases({ datasetId });

  return <Table data={data} loading={loading} />;
};
```

---

## Best Practices

### ✅ DO

1. **Always use service layer** - Never call lambdaClient directly in stores/components
2. **Use SWR hooks in stores** - Not useEffect in components
3. **Clear naming** - `useFetchXxx` for hooks, `refreshXxx` for cache invalidation
4. **Proper cache keys** - Use constants, include parameters in array form
5. **Update state in onSuccess** - Set loading states and data
6. **Refresh after mutations** - Call refresh methods after create/update/delete
7. **Handle loading states** - Provide loading indicators to users

### ❌ DON'T

1. **Don't use useEffect** for data fetching
2. **Don't use useState** for server data
3. **Don't call lambdaClient** directly in components or stores
4. **Don't forget to refresh** cache after mutations
5. **Don't duplicate state** - Use store as single source of truth

---

## Troubleshooting

### Problem: Data not loading

**Check:**

1. Is the hook being called? `useFetchXxx()`
2. Is the key valid? (not null/undefined)
3. Is the service method correct?
4. Check browser network tab for API calls

### Problem: Data not refreshing after mutation

**Check:**

1. Did you call `refreshXxx()` after mutation?
2. Is the cache key the same in both hook and refresh?
3. Check devtools for state updates

### Problem: Loading state stuck

**Check:**

1. Is `onSuccess` updating `isLoadingXxx: false`?
2. Is there an error in the API call?
3. Check error boundary or console

---

## Summary Checklist

When implementing new data fetching:

### Step 1: Data Structures

> See `store-data-structures` skill for detailed patterns

- [ ] **Define types** in `@lobechat/types`:
  - [ ] Detail type (e.g., `AgentEvalBenchmark`)
  - [ ] List item type (e.g., `AgentEvalBenchmarkListItem`)
- [ ] **Design state structure**:
  - [ ] List: `xxxList: XxxListItem[]`
  - [ ] Detail: `xxxDetailMap: Record<string, Xxx>`
  - [ ] Loading: `loadingXxxDetailIds: string[]`
- [ ] **Create reducer** if optimistic updates needed

### Step 2: Service Layer

- [ ] Create service in `src/services/xxxService.ts`
- [ ] Add methods:
  - [ ] `listXxx()` - fetch list
  - [ ] `getXxx(id)` - fetch detail
  - [ ] `createXxx()`, `updateXxx()`, `deleteXxx()` - mutations

### Step 3: Store Actions

- [ ] Create `initialState.ts` with state structure
- [ ] Create `action.ts` with:
  - [ ] `useFetchXxxList()` - list SWR hook
  - [ ] `useFetchXxxDetail(id)` - detail SWR hook
  - [ ] `refreshXxxList()`, `refreshXxxDetail(id)` - cache invalidation
  - [ ] CRUD methods calling service
  - [ ] `internal_dispatch` and `internal_updateLoading` if using reducer
- [ ] Create `selectors.ts` (optional but recommended)
- [ ] Integrate slice into main store

### Step 4: Component Usage

- [ ] Use store hooks (NOT useEffect)
- [ ] List pages: access `xxxList` array
- [ ] Detail pages: access `xxxDetailMap[id]`
- [ ] Use loading states for UI feedback

Remember: **Types → Service → Store (SWR + Reducer) → Component** 🎯

## Key Architecture Patterns

1. **Service Layer**: Clean API abstraction (`xxxService`)
2. **Data Structures**: List arrays + Detail maps (see `store-data-structures` skill)
3. **SWR Hooks**: Automatic caching and revalidation (`useFetchXxx`)
4. **Cache Invalidation**: Manual refresh methods (`refreshXxx`)
5. **Optimistic Updates**: Update UI immediately, then sync with server
6. **Loading States**: Per-item loading for better UX

---

## Related Skills

- **`store-data-structures`** - How to structure List and Detail data in stores
- **`zustand`** - General Zustand patterns and best practices


================================================
FILE: .agents/skills/db-migrations/SKILL.md
================================================
---
name: db-migrations
description: 'Use when generating or regenerating Drizzle migration files, changing database schema tables or columns, resolving migration sequence conflicts after rebase, reviewing migration SQL for idempotent patterns, or renaming migration files.'
---

# Database Migrations Guide

## Step 1: Generate Migrations

```bash
bun run db:generate
```

This generates:

- `packages/database/migrations/0046_meaningless_file_name.sql`

And updates:

- `packages/database/migrations/meta/_journal.json`
- `packages/database/src/core/migrations.json`
- `docs/development/database-schema.dbml`

## Custom Migrations (e.g. CREATE EXTENSION)

For migrations that don't involve Drizzle schema changes (e.g. enabling PostgreSQL extensions), use the `--custom` flag:

```bash
bunx drizzle-kit generate --custom --name=enable_pg_search
```

This generates an empty SQL file and properly updates `_journal.json` and snapshot. Then edit the generated SQL file to add your custom SQL:

```sql
-- Custom SQL migration file, put your code below! --
CREATE EXTENSION IF NOT EXISTS pg_search;
```

**Do NOT manually create migration files or edit `_journal.json`** — always use `drizzle-kit generate` to ensure correct journal entries and snapshots.

## Step 2: Optimize Migration SQL Filename

Rename auto-generated filename to be meaningful:

`0046_meaningless_file_name.sql` → `0046_user_add_avatar_column.sql`

## Step 3: Use Idempotent Clauses (Defensive Programming)

Always use defensive clauses to make migrations idempotent (safe to re-run):

### CREATE TABLE

```sql
-- ✅ Good
CREATE TABLE IF NOT EXISTS "agent_eval_runs" (
  "id" text PRIMARY KEY NOT NULL,
  "name" text,
  "created_at" timestamp with time zone DEFAULT now() NOT NULL
);

-- ❌ Bad
CREATE TABLE "agent_eval_runs" (...);
```

### ALTER TABLE - Columns

```sql
-- ✅ Good
ALTER TABLE "users" ADD COLUMN IF NOT EXISTS "avatar" text;
ALTER TABLE "posts" DROP COLUMN IF EXISTS "deprecated_field";

-- ❌ Bad
ALTER TABLE "users" ADD COLUMN "avatar" text;
```

### ALTER TABLE - Foreign Key Constraints

PostgreSQL has no `ADD CONSTRAINT IF NOT EXISTS`. Use `DROP IF EXISTS` + `ADD`:

```sql
-- ✅ Good: Drop first, then add (idempotent)
ALTER TABLE "agent_eval_datasets" DROP CONSTRAINT IF EXISTS "agent_eval_datasets_user_id_users_id_fk";
ALTER TABLE "agent_eval_datasets" ADD CONSTRAINT "agent_eval_datasets_user_id_users_id_fk"
  FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;

-- ❌ Bad: Will fail if constraint already exists
ALTER TABLE "agent_eval_datasets" ADD CONSTRAINT "agent_eval_datasets_user_id_users_id_fk"
  FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;
```

### DROP TABLE / INDEX

```sql
-- ✅ Good
DROP TABLE IF EXISTS "old_table";
CREATE INDEX IF NOT EXISTS "users_email_idx" ON "users" ("email");
CREATE UNIQUE INDEX IF NOT EXISTS "users_email_unique" ON "users" USING btree ("email");

-- ❌ Bad
DROP TABLE "old_table";
CREATE INDEX "users_email_idx" ON "users" ("email");
```

## Step 4: Update Journal Tag

After renaming the migration SQL file in Step 2, update the `tag` field in `packages/database/migrations/meta/_journal.json` to match the new filename (without `.sql` extension).


================================================
FILE: .agents/skills/debug/SKILL.md
================================================
---
name: debug
description: Debug package usage guide. Use when adding debug logging, understanding log namespaces, or implementing debugging features. Triggers on debug logging requests or logging implementation.
user-invocable: false
---

# Debug Package Usage Guide

## Basic Usage

```typescript
import debug from 'debug';

// Format: lobe-[module]:[submodule]
const log = debug('lobe-server:market');

log('Simple message');
log('With variable: %O', object);
log('Formatted number: %d', number);
```

## Namespace Conventions

- Desktop: `lobe-desktop:[module]`
- Server: `lobe-server:[module]`
- Client: `lobe-client:[module]`
- Router: `lobe-[type]-router:[module]`

## Format Specifiers

- `%O` - Object expanded (recommended for complex objects)
- `%o` - Object
- `%s` - String
- `%d` - Number

## Enable Debug Output

### Browser

```javascript
localStorage.debug = 'lobe-*';
```

### Node.js

```bash
DEBUG=lobe-* npm run dev
DEBUG=lobe-* pnpm dev
```

### Electron

```typescript
process.env.DEBUG = 'lobe-*';
```

## Example

```typescript
// src/server/routers/edge/market/index.ts
import debug from 'debug';

const log = debug('lobe-edge-router:market');

log('getAgent input: %O', input);
```


================================================
FILE: .agents/skills/desktop/SKILL.md
================================================
---
name: desktop
description: Electron desktop development guide. Use when implementing desktop features, IPC handlers, controllers, preload scripts, window management, menu configuration, or Electron-specific functionality. Triggers on desktop app development, Electron IPC, or desktop local tools implementation.
disable-model-invocation: true
---

# Desktop Development Guide

## Architecture Overview

LobeHub desktop is built on Electron with main-renderer architecture:

1. **Main Process** (`apps/desktop/src/main`): App lifecycle, system APIs, window management
2. **Renderer Process**: Reuses web code from `src/`
3. **Preload Scripts** (`apps/desktop/src/preload`): Securely expose main process to renderer

## Adding New Desktop Features

### 1. Create Controller

Location: `apps/desktop/src/main/controllers/`

```typescript
import { ControllerModule, IpcMethod } from '@/controllers';

export default class NewFeatureCtr extends ControllerModule {
  static override readonly groupName = 'newFeature';

  @IpcMethod()
  async doSomething(params: SomeParams): Promise<SomeResult> {
    // Implementation
    return { success: true };
  }
}
```

Register in `apps/desktop/src/main/controllers/registry.ts`.

### 2. Define IPC Types

Location: `packages/electron-client-ipc/src/types.ts`

```typescript
export interface SomeParams {
  /* ... */
}
export interface SomeResult {
  success: boolean;
  error?: string;
}
```

### 3. Create Renderer Service

Location: `src/services/electron/`

```typescript
import { ensureElectronIpc } from '@/utils/electron/ipc';

const ipc = ensureElectronIpc();

export const newFeatureService = async (params: SomeParams) => {
  return ipc.newFeature.doSomething(params);
};
```

### 4. Implement Store Action

Location: `src/store/`

### 5. Add Tests

Location: `apps/desktop/src/main/controllers/__tests__/`

## Detailed Guides

See `references/` for specific topics:

- **Feature implementation**: `references/feature-implementation.md`
- **Local tools workflow**: `references/local-tools.md`
- **Menu configuration**: `references/menu-config.md`
- **Window management**: `references/window-management.md`

## Best Practices

1. **Security**: Validate inputs, limit exposed APIs
2. **Performance**: Use async methods, batch data transfers
3. **UX**: Add progress indicators, provide error feedback
4. **Code organization**: Follow existing patterns, add documentation


================================================
FILE: .agents/skills/desktop/references/feature-implementation.md
================================================
# Desktop Feature Implementation Guide

## Architecture Overview

```plaintext
Main Process                    Renderer Process
┌──────────────────┐           ┌──────────────────┐
│ Controller       │◄──IPC───►│ Service Layer    │
│ (IPC Handler)    │           │                  │
└──────────────────┘           └──────────────────┘
        │                              │
        ▼                              ▼
┌──────────────────┐           ┌──────────────────┐
│ System APIs      │           │ Store Actions    │
│ (fs, network)    │           │ (UI State)       │
└──────────────────┘           └──────────────────┘
```

## Step-by-Step Implementation

### 1. Create Controller

```typescript
// apps/desktop/src/main/controllers/NotificationCtr.ts
import type {
  ShowDesktopNotificationParams,
  DesktopNotificationResult,
} from '@lobechat/electron-client-ipc';
import { Notification } from 'electron';
import { ControllerModule, IpcMethod } from '@/controllers';

export default class NotificationCtr extends ControllerModule {
  static override readonly groupName = 'notification';

  @IpcMethod()
  async showDesktopNotification(
    params: ShowDesktopNotificationParams,
  ): Promise<DesktopNotificationResult> {
    if (!Notification.isSupported()) {
      return { error: 'Notifications not supported', success: false };
    }

    try {
      const notification = new Notification({ body: params.body, title: params.title });
      notification.show();
      return { success: true };
    } catch (error) {
      console.error('[NotificationCtr] Failed:', error);
      return { error: error instanceof Error ? error.message : 'Unknown error', success: false };
    }
  }
}
```

### 2. Define IPC Types

```typescript
// packages/electron-client-ipc/src/types.ts
export interface ShowDesktopNotificationParams {
  title: string;
  body: string;
}

export interface DesktopNotificationResult {
  success: boolean;
  error?: string;
}
```

### 3. Create Service Layer

```typescript
// src/services/electron/notificationService.ts
import type { ShowDesktopNotificationParams } from '@lobechat/electron-client-ipc';
import { ensureElectronIpc } from '@/utils/electron/ipc';

const ipc = ensureElectronIpc();

export const notificationService = {
  show: (params: ShowDesktopNotificationParams) => ipc.notification.showDesktopNotification(params),
};
```

### 4. Implement Store Action

```typescript
// src/store/.../actions.ts
showNotification: async (title: string, body: string) => {
  if (!isElectron) return;

  const result = await notificationService.show({ title, body });
  if (!result.success) {
    console.error('Notification failed:', result.error);
  }
},
```

## Best Practices

1. **Security**: Validate inputs, limit exposed APIs
2. **Performance**: Use async methods for heavy operations
3. **Error handling**: Always return structured results
4. **UX**: Provide loading states and error feedback


================================================
FILE: .agents/skills/desktop/references/local-tools.md
================================================
# Desktop Local Tools Implementation

## Workflow Overview

1. Define tool interface (Manifest)
2. Define related types
3. Implement Store Action
4. Implement Service Layer
5. Implement Controller (IPC Handler)
6. Update Agent documentation

## Step 1: Define Tool Interface (Manifest)

Location: `src/tools/[tool_category]/index.ts`

```typescript
// src/tools/local-files/index.ts
export const LocalFilesApiName = {
  RenameFile: 'renameFile',
  MoveFile: 'moveFile',
} as const;

export const LocalFilesManifest = {
  api: [
    {
      name: LocalFilesApiName.RenameFile,
      description: 'Rename a local file',
      parameters: {
        type: 'object',
        properties: {
          oldPath: { type: 'string', description: 'Current file path' },
          newName: { type: 'string', description: 'New file name' },
        },
        required: ['oldPath', 'newName'],
      },
    },
  ],
};
```

## Step 2: Define Types

```typescript
// packages/electron-client-ipc/src/types.ts
export interface RenameLocalFileParams {
  oldPath: string;
  newName: string;
}

// src/tools/local-files/type.ts
export interface LocalRenameFileState {
  success: boolean;
  error?: string;
  oldPath: string;
  newPath: string;
}
```

## Step 3: Implement Store Action

```typescript
// src/store/chat/slices/builtinTool/actions/localFile.ts
renameLocalFile: async (id: string, params: RenameLocalFileParams) => {
  const { toggleLocalFileLoading, updatePluginState, internal_updateMessageContent } = get();

  toggleLocalFileLoading(id, true);

  try {
    const result = await localFileService.renameFile(params);

    if (result.success) {
      updatePluginState(id, { success: true, ...result });
      internal_updateMessageContent(id, JSON.stringify({ success: true }));
    } else {
      updatePluginState(id, { success: false, error: result.error });
      internal_updateMessageContent(id, JSON.stringify({ error: result.error }));
    }

    return result.success;
  } catch (e) {
    console.error(e);
    updatePluginState(id, { success: false, error: e.message });
    return false;
  } finally {
    toggleLocalFileLoading(id, false);
  }
},
```

## Step 4: Implement Service Layer

```typescript
// src/services/electron/localFileService.ts
import { ensureElectronIpc } from '@/utils/electron/ipc';

const ipc = ensureElectronIpc();

export const localFileService = {
  renameFile: (params: RenameLocalFileParams) => ipc.localFiles.renameFile(params),
};
```

## Step 5: Implement Controller

```typescript
// apps/desktop/src/main/controllers/LocalFileCtr.ts
import * as fs from 'fs/promises';
import * as path from 'path';
import { ControllerModule, IpcMethod } from '@/controllers';

export default class LocalFileCtr extends ControllerModule {
  static override readonly groupName = 'localFiles';

  @IpcMethod()
  async renameFile(params: RenameLocalFileParams) {
    const { oldPath, newName } = params;
    const newPath = path.join(path.dirname(oldPath), newName);

    try {
      await fs.rename(oldPath, newPath);
      return { success: true, newPath };
    } catch (error) {
      return { success: false, error: error.message };
    }
  }
}
```

## Step 6: Update Agent Documentation

Location: `src/tools/[tool_category]/systemRole.ts`

Add tool description to `<core_capabilities>` and usage guidelines to `<tool_usage_guidelines>`.


================================================
FILE: .agents/skills/desktop/references/menu-config.md
================================================
# Desktop Menu Configuration Guide

## Menu Types

1. **App Menu**: Top of window (macOS) or title bar (Windows/Linux)
2. **Context Menu**: Right-click menus
3. **Tray Menu**: System tray icon menus

## File Structure

```plaintext
apps/desktop/src/main/
├── menus/
│   ├── appMenu.ts        # App menu config
│   ├── contextMenu.ts    # Context menu config
│   └── factory.ts        # Menu factory functions
├── controllers/
│   ├── MenuCtr.ts        # Menu controller
│   └── TrayMenuCtr.ts    # Tray menu controller
```

## App Menu Configuration

```typescript
// apps/desktop/src/main/menus/appMenu.ts
import { BrowserWindow, Menu, MenuItemConstructorOptions } from 'electron';

export const createAppMenu = (win: BrowserWindow) => {
  const template: MenuItemConstructorOptions[] = [
    {
      label: 'File',
      submenu: [
        {
          label: 'New',
          accelerator: 'CmdOrCtrl+N',
          click: () => {
            /* ... */
          },
        },
        { type: 'separator' },
        { role: 'quit' },
      ],
    },
    // ...
  ];

  return Menu.buildFromTemplate(template);
};

// Register in MenuCtr.ts
Menu.setApplicationMenu(menu);
```

## Context Menu

```typescript
export const createContextMenu = () => {
  const template = [
    { label: 'Copy', role: 'copy' },
    { label: 'Paste', role: 'paste' },
  ];
  return Menu.buildFromTemplate(template);
};

// Show on right-click
const menu = createContextMenu();
menu.popup();
```

## Tray Menu

```typescript
// TrayMenuCtr.ts
this.tray = new Tray(trayIconPath);
const contextMenu = Menu.buildFromTemplate([
  { label: 'Show Window', click: this.showMainWindow },
  { type: 'separator' },
  { label: 'Quit', click: () => app.quit() },
]);
this.tray.setContextMenu(contextMenu);
```

## i18n Support

```typescript
import { i18n } from '../locales';

const template = [
  {
    label: i18n.t('menu.file'),
    submenu: [{ label: i18n.t('menu.new'), click: createNew }],
  },
];
```

## Best Practices

1. Use standard roles (`role: 'copy'`) for native behavior
2. Use `CmdOrCtrl` for cross-platform shortcuts
3. Use `{ type: 'separator' }` to group related items
4. Handle platform differences with `process.platform`

```typescript
if (process.platform === 'darwin') {
  template.unshift({ role: 'appMenu' });
}
```


================================================
FILE: .agents/skills/desktop/references/window-management.md
================================================
# Desktop Window Management Guide

## Window Management Overview

1. Window creation and configuration
2. Window state management (size, position, maximize)
3. Multi-window coordination
4. Window event handling

## File Structure

```plaintext
apps/desktop/src/main/
├── appBrowsers.ts              # Core window management
├── controllers/
│   └── BrowserWindowsCtr.ts    # Window controller
└── modules/
    └── browserWindowManager.ts # Window manager module
```

## Window Creation

```typescript
export const createMainWindow = () => {
  const mainWindow = new BrowserWindow({
    width: 1200,
    height: 800,
    minWidth: 600,
    minHeight: 400,
    webPreferences: {
      preload: path.join(__dirname, '../preload/index.js'),
      contextIsolation: true,
      nodeIntegration: false,
    },
  });

  if (isDev) {
    mainWindow.loadURL('http://localhost:3000');
  } else {
    mainWindow.loadFile(path.join(__dirname, '../../renderer/index.html'));
  }

  return mainWindow;
};
```

## Window State Persistence

```typescript
const saveWindowState = (window: BrowserWindow) => {
  if (!window.isMinimized() && !window.isMaximized()) {
    const [x, y] = window.getPosition();
    const [width, height] = window.getSize();
    settings.set('windowState', { x, y, width, height });
  }
};

const restoreWindowState = (window: BrowserWindow) => {
  const state = settings.get('windowState');
  if (state) {
    window.setBounds({ x: state.x, y: state.y, width: state.width, height: state.height });
  }
};

window.on('close', () => saveWindowState(window));
```

## Multi-Window Management

```typescript
export class WindowManager {
  private windows: Map<string, BrowserWindow> = new Map();

  createWindow(id: string, options: BrowserWindowConstructorOptions) {
    const window = new BrowserWindow(options);
    this.windows.set(id, window);
    window.on('closed', () => this.windows.delete(id));
    return window;
  }

  getWindow(id: string) {
    return this.windows.get(id);
  }
}
```

## Window IPC Controller

```typescript
// apps/desktop/src/main/controllers/BrowserWindowsCtr.ts
export default class BrowserWindowsCtr extends ControllerModule {
  static override readonly groupName = 'windows';

  @IpcMethod()
  minimizeWindow() {
    BrowserWindow.getFocusedWindow()?.minimize();
    return { success: true };
  }

  @IpcMethod()
  maximizeWindow() {
    const win = BrowserWindow.getFocusedWindow();
    win?.isMaximized() ? win.restore() : win?.maximize();
    return { success: true };
  }
}
```

## Renderer Service

```typescript
// src/services/electron/windowService.ts
import { ensureElectronIpc } from '@/utils/electron/ipc';

const ipc = ensureElectronIpc();

export const windowService = {
  minimize: () => ipc.windows.minimizeWindow(),
  maximize: () => ipc.windows.maximizeWindow(),
  close: () => ipc.windows.closeWindow(),
};
```

## Frameless Window

```typescript
const window = new BrowserWindow({
  frame: false,
  titleBarStyle: 'hidden',
});
```

```css
.titlebar {
  -webkit-app-region: drag;
}
.titlebar-button {
  -webkit-app-region: no-drag;
}
```

## Best Practices

1. Use `show: false` initially, show after content loads
2. Always set secure `webPreferences`
3. Handle `webContents.on('crashed')` for recovery
4. Clean up resources on `window.on('closed')`


================================================
FILE: .agents/skills/drizzle/SKILL.md
================================================
---
name: drizzle
description: Drizzle ORM schema and database guide. Use when working with database schemas (src/database/schemas/*), defining tables, creating migrations, or database model code. Triggers on Drizzle schema definition, database migrations, or ORM usage questions.
---

# Drizzle ORM Schema Style Guide

## Configuration

- Config: `drizzle.config.ts`
- Schemas: `src/database/schemas/`
- Migrations: `src/database/migrations/`
- Dialect: `postgresql` with `strict: true`

## Helper Functions

Location: `src/database/schemas/_helpers.ts`

- `timestamptz(name)`: Timestamp with timezone
- `createdAt()`, `updatedAt()`, `accessedAt()`: Standard timestamp columns
- `timestamps`: Object with all three for easy spread

## Naming Conventions

- **Tables**: Plural snake_case (`users`, `session_groups`)
- **Columns**: snake_case (`user_id`, `created_at`)

## Column Definitions

### Primary Keys

```typescript
id: text('id')
  .primaryKey()
  .$defaultFn(() => idGenerator('agents'))
  .notNull(),
```

ID prefixes make entity types distinguishable. For internal tables, use `uuid`.

### Foreign Keys

```typescript
userId: text('user_id')
  .references(() => users.id, { onDelete: 'cascade' })
  .notNull(),
```

### Timestamps

```typescript
...timestamps,  // Spread from _helpers.ts
```

### Indexes

```typescript
// Return array (object style deprecated)
(t) => [uniqueIndex('client_id_user_id_unique').on(t.clientId, t.userId)],
```

## Type Inference

```typescript
export const insertAgentSchema = createInsertSchema(agents);
export type NewAgent = typeof agents.$inferInsert;
export type AgentItem = typeof agents.$inferSelect;
```

## Example Pattern

```typescript
export const agents = pgTable(
  'agents',
  {
    id: text('id')
      .primaryKey()
      .$defaultFn(() => idGenerator('agents'))
      .notNull(),
    slug: varchar('slug', { length: 100 })
      .$defaultFn(() => randomSlug(4))
      .unique(),
    userId: text('user_id')
      .references(() => users.id, { onDelete: 'cascade' })
      .notNull(),
    clientId: text('client_id'),
    chatConfig: jsonb('chat_config').$type<LobeAgentChatConfig>(),
    ...timestamps,
  },
  (t) => [uniqueIndex('client_id_user_id_unique').on(t.clientId, t.userId)],
);
```

## Common Patterns

### Junction Tables (Many-to-Many)

```typescript
export const agentsKnowledgeBases = pgTable(
  'agents_knowledge_bases',
  {
    agentId: text('agent_id')
      .references(() => agents.id, { onDelete: 'cascade' })
      .notNull(),
    knowledgeBaseId: text('knowledge_base_id')
      .references(() => knowledgeBases.id, { onDelete: 'cascade' })
      .notNull(),
    userId: text('user_id')
      .references(() => users.id, { onDelete: 'cascade' })
      .notNull(),
    enabled: boolean('enabled').default(true),
    ...timestamps,
  },
  (t) => [primaryKey({ columns: [t.agentId, t.knowledgeBaseId] })],
);
```

## Query Style

**Always use `db.select()` builder API. Never use `db.query.*` relational API** (`findMany`, `findFirst`, `with:`).

The relational API generates complex lateral joins with `json_build_array` that are fragile and hard to debug.

### Select Single Row

```typescript
// ✅ Good
const [result] = await this.db
  .select()
  .from(agents)
  .where(eq(agents.id, id))
  .limit(1);
return result;

// ❌ Bad: relational API
return this.db.query.agents.findFirst({
  where: eq(agents.id, id),
});
```

### Select with JOIN

```typescript
// ✅ Good: explicit select + leftJoin
const rows = await this.db
  .select({
    runId: agentEvalRunTopics.runId,
    score: agentEvalRunTopics.score,
    testCase: agentEvalTestCases,
    topic: topics,
  })
  .from(agentEvalRunTopics)
  .leftJoin(agentEvalTestCases, eq(agentEvalRunTopics.testCaseId, agentEvalTestCases.id))
  .leftJoin(topics, eq(agentEvalRunTopics.topicId, topics.id))
  .where(eq(agentEvalRunTopics.runId, runId))
  .orderBy(asc(agentEvalRunTopics.createdAt));

// ❌ Bad: relational API with `with:`
return this.db.query.agentEvalRunTopics.findMany({
  where: eq(agentEvalRunTopics.runId, runId),
  with: { testCase: true, topic: true },
});
```

### Select with Aggregation

```typescript
// ✅ Good: select + leftJoin + groupBy
const rows = await this.db
  .select({
    id: agentEvalDatasets.id,
    name: agentEvalDatasets.name,
    testCaseCount: count(agentEvalTestCases.id).as('testCaseCount'),
  })
  .from(agentEvalDatasets)
  .leftJoin(agentEvalTestCases, eq(agentEvalDatasets.id, agentEvalTestCases.datasetId))
  .groupBy(agentEvalDatasets.id);
```

### One-to-Many (Separate Queries)

When you need a parent record with its children, use two queries instead of relational `with:`:

```typescript
// ✅ Good: two simple queries
const [dataset] = await this.db
  .select()
  .from(agentEvalDatasets)
  .where(eq(agentEvalDatasets.id, id))
  .limit(1);

if (!dataset) return undefined;

const testCases = await this.db
  .select()
  .from(agentEvalTestCases)
  .where(eq(agentEvalTestCases.datasetId, id))
  .orderBy(asc(agentEvalTestCases.sortOrder));

return { ...dataset, testCases };
```

## Database Migrations

See the `db-migrations` skill for the detailed migration guide.


================================================
FILE: .agents/skills/hotkey/SKILL.md
================================================
---
name: hotkey
description: Guide for adding keyboard shortcuts. Use when implementing new hotkeys, registering shortcuts, or working with keyboard interactions. Triggers on hotkey implementation or keyboard shortcut tasks.
---

# Adding Keyboard Shortcuts Guide

## Steps to Add a New Hotkey

### 1. Update Hotkey Constant

In `src/types/hotkey.ts`:

```typescript
export const HotkeyEnum = {
  // existing...
  ClearChat: 'clearChat', // Add new
} as const;
```

### 2. Register Default Hotkey

In `src/const/hotkeys.ts`:

```typescript
import { KeyMapEnum as Key, combineKeys } from '@lobehub/ui';

export const HOTKEYS_REGISTRATION: HotkeyRegistration = [
  {
    group: HotkeyGroupEnum.Conversation,
    id: HotkeyEnum.ClearChat,
    keys: combineKeys([Key.Mod, Key.Shift, Key.Backspace]),
    scopes: [HotkeyScopeEnum.Chat],
  },
];
```

### 3. Add i18n Translation

In `src/locales/default/hotkey.ts`:

```typescript
const hotkey: HotkeyI18nTranslations = {
  clearChat: {
    desc: '清空当前会话的所有消息记录',
    title: '清空聊天记录',
  },
};
```

### 4. Create and Register Hook

In `src/hooks/useHotkeys/chatScope.ts`:

```typescript
export const useClearChatHotkey = () => {
  const clearMessages = useChatStore((s) => s.clearMessages);
  return useHotkeyById(HotkeyEnum.ClearChat, clearMessages);
};

export const useRegisterChatHotkeys = () => {
  useClearChatHotkey();
  // ...other hotkeys
};
```

### 5. Add Tooltip (Optional)

```tsx
const clearChatHotkey = useUserStore(settingsSelectors.getHotkeyById(HotkeyEnum.ClearChat));

<Tooltip hotkey={clearChatHotkey} title={t('clearChat.title', { ns: 'hotkey' })}>
  <Button icon={<DeleteOutlined />} onClick={clearMessages} />
</Tooltip>;
```

## Best Practices

1. **Scope**: Choose global or chat scope based on functionality
2. **Grouping**: Place in appropriate group (System/Layout/Conversation)
3. **Conflict check**: Ensure no conflict with system/browser shortcuts
4. **Platform**: Use `Key.Mod` instead of hardcoded `Ctrl` or `Cmd`
5. **Clear description**: Provide title and description for users

## Troubleshooting

- **Not working**: Check scope and RegisterHotkeys hook
- **Not in settings**: Verify HOTKEYS_REGISTRATION config
- **Conflict**: HotkeyInput component shows warnings
- **Page-specific**: Ensure correct scope activation


================================================
FILE: .agents/skills/i18n/SKILL.md
================================================
---
name: i18n
description: Internationalization guide using react-i18next. Use when adding translations, creating i18n keys, or working with localized text in React components (.tsx files). Triggers on translation tasks, locale management, or i18n implementation.
---

# LobeHub Internationalization Guide

- Default language: Chinese (zh-CN)
- Framework: react-i18next
- **Only edit files in `src/locales/default/`** - Never edit JSON files in `locales/`
- Run `pnpm i18n` to generate translations (or manually translate zh-CN/en-US for dev preview)

## Key Naming Convention

**Flat keys with dot notation** (not nested objects):

```typescript
// ✅ Correct
export default {
  'alert.cloud.action': '立即体验',
  'sync.actions.sync': '立即同步',
  'sync.status.ready': '已连接',
};

// ❌ Avoid nested objects
export default {
  alert: { cloud: { action: '...' } },
};
```

**Patterns:** `{feature}.{context}.{action|status}`

**Parameters:** Use `{{variableName}}` syntax

```typescript
'alert.cloud.desc': '我们提供 {{credit}} 额度积分',
```

**Avoid key conflicts:**

```typescript
// ❌ Conflict
'clientDB.solve': '自助解决',
'clientDB.solve.backup.title': '数据备份',

// ✅ Solution
'clientDB.solve.action': '自助解决',
'clientDB.solve.backup.title': '数据备份',
```

## Workflow

1. Add keys to `src/locales/default/{namespace}.ts`
2. Export new namespace in `src/locales/default/index.ts`
3. For dev preview: manually translate `locales/zh-CN/{namespace}.json` and `locales/en-US/{namespace}.json`
4. Remind the user to run `pnpm i18n` before creating PR — do NOT run it yourself (very slow)

## Usage

```tsx
import { useTranslation } from 'react-i18next';

const { t } = useTranslation('common');

t('newFeature.title');
t('alert.cloud.desc', { credit: '1000' });

// Multiple namespaces
const { t } = useTranslation(['common', 'chat']);
t('common:save');
```

## Common Namespaces

**Most used:** `common` (shared UI), `chat` (chat features), `setting` (settings)

Others: auth, changelog, components, discover, editor, electron, error, file, hotkey, knowledgeBase, memory, models, plugin, portal, providers, tool, topic


================================================
FILE: .agents/skills/linear/SKILL.md
================================================
---
name: linear
description: "Linear issue management. MUST USE when: (1) user mentions LOBE-xxx issue IDs (e.g. LOBE-4540), (2) user says 'linear', 'linear issue', 'link linear', (3) creating PRs that reference Linear issues. Provides workflows for retrieving issues, updating status, and adding comments."
---

# Linear Issue Management

Before using Linear workflows, search for `linear` MCP tools. If not found, treat as not installed.

## ⚠️ CRITICAL: PR Creation with Linear Issues

**When creating a PR that references Linear issues (LOBE-xxx), you MUST:**

1. Create the PR with magic keywords (`Fixes LOBE-xxx`)
2. **IMMEDIATELY after PR creation**, add completion comments to ALL referenced Linear issues
3. Do NOT consider the task complete until Linear comments are added

This is NON-NEGOTIABLE. Skipping Linear comments is a workflow violation.

## Workflow

1. **Retrieve issue details** before starting: `mcp__linear-server__get_issue`
2. **Check for sub-issues**: Use `mcp__linear-server__list_issues` with `parentId` filter
3. **Update issue status** when completing: `mcp__linear-server__update_issue`
4. **Add completion comment** (REQUIRED): `mcp__linear-server__create_comment`

## Creating Issues

When creating issues with `mcp__linear-server__create_issue`, **MUST add the `claude code` label**.

## Completion Comment Format

Every completed issue MUST have a comment summarizing work done:

```markdown
## Changes Summary

- **Feature**: Brief description of what was implemented
- **Files Changed**: List key files modified
- **PR**: #xxx or PR URL

### Key Changes

- Change 1
- Change 2
- ...
```

This is critical for:

- Team visibility
- Code review context
- Future reference

## PR Association (REQUIRED)

When creating PRs for Linear issues, include magic keywords in PR body:

- `Fixes LOBE-123`
- `Closes LOBE-123`
- `Resolves LOBE-123`

## Per-Issue Completion Rule

When working on multiple issues, update EACH issue IMMEDIATELY after completing it:

1. Complete implementation
2. Run `bun run type-check`
3. Run related tests
4. Create PR if needed
5. Update status to **"In Review"** (NOT "Done")
6. **Add completion comment immediately**
7. Move to next issue

**Note:** Status → "In Review" when PR created. "Done" only after PR merged.

**❌ Wrong:** Complete all → Create PR → Forget Linear comments

**✅ Correct:** Complete → Create PR → Add Linear comments → Task done


================================================
FILE: .agents/skills/local-testing/SKILL.md
================================================
---
name: local-testing
description: >
  Local app and bot testing. Uses agent-browser CLI for Electron/web app UI testing,
  and osascript (AppleScript) for controlling native macOS apps (WeChat, Discord, Telegram, Slack, Lark/飞书, QQ)
  to test bots. Triggers on 'local test', 'test in electron', 'test desktop', 'test bot',
  'bot test', 'test in discord', 'test in telegram', 'test in slack', 'test in weixin',
  'test in wechat', 'test in lark', 'test in feishu', 'test in qq',
  'manual test', 'osascript', or UI/bot verification tasks.
---

# Local App & Bot Testing

Two approaches for local testing on macOS:

| Approach                    | Tool                | Best For                                             |
| --------------------------- | ------------------- | ---------------------------------------------------- |
| **agent-browser + CDP**     | `agent-browser` CLI | Electron apps, web apps (DOM access, JS eval)        |
| **osascript (AppleScript)** | `osascript -e`      | Native macOS apps (WeChat, Discord, Telegram, Slack) |

---

# Part 1: agent-browser (Electron / Web Apps)

Use `agent-browser` to automate Chromium-based apps via Chrome DevTools Protocol.

## Prerequisites

- `agent-browser` CLI installed globally (`agent-browser --version`)

## Core Workflow

### 1. Snapshot → Find Elements

```bash
agent-browser --cdp -i < PORT > snapshot    # Interactive elements only
agent-browser --cdp -i -C < PORT > snapshot # Include contenteditable elements
```

Returns element refs like `@e1`, `@e2`. **Refs are ephemeral** — re-snapshot after any page change.

### 2. Interact

```bash
agent-browser --cdp @e5 < PORT > click
agent-browser --cdp @e3 "text" < PORT > type # Character by character (contenteditable)
agent-browser --cdp @e3 "text" < PORT > fill # Bulk fill (regular inputs)
agent-browser --cdp Enter < PORT > press
agent-browser --cdp down 500 < PORT > scroll
```

### 3. Wait

```bash
agent-browser --cdp 2000 < PORT > wait               # Wait ms
agent-browser --cdp --load networkidle < PORT > wait # Wait for network
```

For waits >30s, use `sleep N` in bash instead — `agent-browser wait` blocks the daemon.

### 4. Screenshot & Verify

```bash
agent-browser --cdp < PORT > screenshot   # Save to ~/.agent-browser/tmp/screenshots/
agent-browser --cdp text @e1 < PORT > get # Get element text
agent-browser --cdp url < PORT > get      # Get current URL
```

Read screenshots with the `Read` tool for visual verification.

### 5. Evaluate JavaScript

```bash
agent-browser --cdp "document.title" < PORT > eval
```

For multi-line JS, use `--stdin`:

```bash
agent-browser --cdp --stdin < PORT > eval << 'EVALEOF'
(function() {
  return JSON.stringify({ title: document.title, url: location.href });
})()
EVALEOF
```

## Electron (LobeHub Desktop)

### Setup

```bash
# 1. Kill existing instances
pkill -f "Electron" 2> /dev/null
pkill -f "electron-vite" 2> /dev/null
pkill -f "agent-browser" 2> /dev/null
sleep 3

# 2. Start Electron with CDP (MUST cd to apps/desktop first)
cd apps/desktop && ELECTRON_ENABLE_LOGGING=1 npx electron-vite dev -- --remote-debugging-port=9222 > /tmp/electron-dev.log 2>&1 &

# 3. Wait for startup
for i in $(seq 1 12); do
  sleep 5
  if strings /tmp/electron-dev.log 2> /dev/null | grep -q "starting electron"; then
    echo "ready"
    break
  fi
done

# 4. Wait for renderer, then connect
sleep 15 && agent-browser --cdp 9222 wait 3000
```

**Critical:** `npx electron-vite dev` MUST run from `apps/desktop/` directory, not project root.

### LobeHub-Specific Patterns

#### Access Zustand Store State

```bash
agent-browser --cdp 9222 eval --stdin << 'EVALEOF'
(function() {
  var chat = window.__LOBE_STORES.chat();
  var ops = Object.values(chat.operations);
  return JSON.stringify({
    ops: ops.map(function(o) { return { type: o.type, status: o.status }; }),
    activeAgent: chat.activeAgentId,
    activeTopic: chat.activeTopicId,
  });
})()
EVALEOF
```

#### Find and Use the Chat Input

```bash
# The chat input is contenteditable — must use -C flag
agent-browser --cdp 9222 snapshot -i -C 2>&1 | grep "editable"

agent-browser --cdp 9222 click @e48
agent-browser --cdp 9222 type @e48 "Hello world"
agent-browser --cdp 9222 press Enter
```

#### Wait for Agent to Complete

```bash
agent-browser --cdp 9222 eval --stdin << 'EVALEOF'
(function() {
  var chat = window.__LOBE_STORES.chat();
  var ops = Object.values(chat.operations);
  var running = ops.filter(function(o) { return o.status === 'running'; });
  return running.length === 0 ? 'done' : 'running: ' + running.length;
})()
EVALEOF
```

#### Install Error Interceptor

```bash
agent-browser --cdp 9222 eval --stdin << 'EVALEOF'
(function() {
  window.__CAPTURED_ERRORS = [];
  var orig = console.error;
  console.error = function() {
    var msg = Array.from(arguments).map(function(a) {
      if (a instanceof Error) return a.message;
      return typeof a === 'object' ? JSON.stringify(a) : String(a);
    }).join(' ');
    window.__CAPTURED_ERRORS.push(msg);
    orig.apply(console, arguments);
  };
  return 'installed';
})()
EVALEOF

# Later, check captured errors:
agent-browser --cdp 9222 eval "JSON.stringify(window.__CAPTURED_ERRORS)"
```

## Chrome / Web Apps

```bash
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
  --remote-debugging-port=9222 \
  --user-data-dir=/tmp/chrome-test-profile \
  "<URL>" &
sleep 5
agent-browser --cdp 9222 snapshot -i
```

---

# Part 2: osascript (Native macOS App Bot Testing)

Use AppleScript via `osascript` to control native macOS desktop apps for bot testing. This works with any app that supports macOS Accessibility, without needing CDP or Chromium.

## Core osascript Patterns

### Activate an App

```bash
osascript -e 'tell application "Discord" to activate'
```

### Type Text

```bash
# Type character by character (reliable, but slow for long text)
osascript -e 'tell application "System Events" to keystroke "Hello world"'

# Press Enter
osascript -e 'tell application "System Events" to key code 36'

# Press Tab
osascript -e 'tell application "System Events" to key code 48'

# Press Escape
osascript -e 'tell application "System Events" to key code 53'
```

### Paste from Clipboard (fast, for long text)

```bash
# Set clipboard and paste — much faster than keystroke for long messages
osascript -e 'set the clipboard to "Your long message here"'
osascript -e 'tell application "System Events" to keystroke "v" using command down'
```

Or in one shot:

```bash
osascript -e '
set the clipboard to "Your long message here"
tell application "System Events" to keystroke "v" using command down
'
```

### Keyboard Shortcuts

```bash
# Cmd+K (quick switcher in Discord/Slack)
osascript -e 'tell application "System Events" to keystroke "k" using command down'

# Cmd+F (search)
osascript -e 'tell application "System Events" to keystroke "f" using command down'

# Cmd+N (new message/chat)
osascript -e 'tell application "System Events" to keystroke "n" using command down'

# Cmd+Shift+K (example: multi-modifier)
osascript -e 'tell application "System Events" to keystroke "k" using {command down, shift down}'
```

### Click at Position

```bash
# Click at absolute screen coordinates
osascript -e '
tell application "System Events"
    click at {500, 300}
end tell
'
```

### Get Window Info

```bash
# Get window position and size
osascript -e '
tell application "System Events"
    tell process "Discord"
        get {position, size} of window 1
    end tell
end tell
'
```

### Screenshot

```bash
# Full screen
screencapture /tmp/screenshot.png

# Interactive region select
screencapture -i /tmp/screenshot.png

# Specific window (by window ID from CGWindowList)
screencapture -l < WINDOW_ID > /tmp/screenshot.png
```

To get window ID for a specific app:

```bash
osascript -e '
tell application "System Events"
    tell process "Discord"
        get id of window 1
    end tell
end tell
'
```

### Read Accessibility Elements

```bash
# Get all UI elements of the frontmost window (can be slow/large)
osascript -e '
tell application "System Events"
    tell process "Discord"
        entire contents of window 1
    end tell
end tell
'

# Get a specific element's value
osascript -e '
tell application "System Events"
    tell process "Discord"
        get value of text field 1 of window 1
    end tell
end tell
'
```

> **Warning:** `entire contents` can be extremely slow on complex UIs. Prefer screenshots + `Read` tool for visual verification.

### Read Screen Text via Clipboard

For reading the latest message or response from an app:

```bash
# Select all text in the focused area and copy
osascript -e '
tell application "System Events"
    keystroke "a" using command down
    keystroke "c" using command down
end tell
'
sleep 0.5
# Read clipboard
pbpaste
```

---

## Client: Discord

**App name:** `Discord` | **Process name:** `Discord`

### Activate & Navigate

```bash
# Activate Discord
osascript -e 'tell application "Discord" to activate'
sleep 1

# Open Quick Switcher (Cmd+K) to navigate to a channel
osascript -e 'tell application "System Events" to keystroke "k" using command down'
sleep 0.5
osascript -e 'tell application "System Events" to keystroke "bot-testing"'
sleep 1
osascript -e 'tell application "System Events" to key code 36' # Enter
sleep 2
```

### Send Message to Bot

```bash
# The message input is focused after navigating to a channel
# Type a message
osascript -e 'tell application "System Events" to keystroke "/hello"'
sleep 0.5
osascript -e 'tell application "System Events" to key code 36' # Enter
```

### Send Long Message (via clipboard)

```bash
osascript -e '
tell application "Discord" to activate
delay 0.5
set the clipboard to "Write a 3000 word essay about space exploration"
tell application "System Events"
    keystroke "v" using command down
    delay 0.3
    key code 36  -- Enter
end tell
'
```

### Verify Bot Response

```bash
# Wait for bot to respond, then screenshot
sleep 10
screencapture /tmp/discord-bot-response.png
# Read with the Read tool for visual verification
```

### Full Bot Test Example

```bash
#!/usr/bin/env bash
# test-discord-bot.sh — Send message and verify bot response

# 1. Activate Discord and navigate to channel
osascript -e '
tell application "Discord" to activate
delay 1
-- Quick Switcher
tell application "System Events" to keystroke "k" using command down
delay 0.5
tell application "System Events" to keystroke "bot-testing"
delay 1
tell application "System Events" to key code 36
delay 2
'

# 2. Send test message
osascript -e '
set the clipboard to "!ping"
tell application "System Events"
    keystroke "v" using command down
    delay 0.3
    key code 36
end tell
'

# 3. Wait for response and capture
sleep 5
screencapture /tmp/discord-test-result.png
echo "Screenshot saved to /tmp/discord-test-result.png"
```

---

## Client: Slack

**App name:** `Slack` | **Process name:** `Slack`

### Activate & Navigate

```bash
# Activate Slack
osascript -e 'tell application "Slack" to activate'
sleep 1

# Quick Switcher (Cmd+K)
osascript -e 'tell application "System Events" to keystroke "k" using command down'
sleep 0.5
osascript -e 'tell application "System Events" to keystroke "bot-testing"'
sleep 1
osascript -e 'tell application "System Events" to key code 36' # Enter
sleep 2
```

### Send Message to Bot

```bash
# Direct message input (focused after channel nav)
osascript -e 'tell application "System Events" to keystroke "@mybot hello"'
sleep 0.3
osascript -e 'tell application "System Events" to key code 36'
```

### Send Long Message

```bash
osascript -e '
tell application "Slack" to activate
delay 0.5
set the clipboard to "A long test message for the bot..."
tell application "System Events"
    keystroke "v" using command down
    delay 0.3
    key code 36
end tell
'
```

### Slash Command Test

```bash
osascript -e '
tell application "Slack" to activate
delay 0.5
tell application "System Events"
    keystroke "/ask What is the meaning of life?"
    delay 0.5
    key code 36
end tell
'
```

### Verify Response

```bash
sleep 10
screencapture /tmp/slack-bot-response.png
```

---

## Client: Telegram

**App name:** `Telegram` | **Process name:** `Telegram`

### Activate & Navigate

```bash
# Activate Telegram
osascript -e 'tell application "Telegram" to activate'
sleep 1

# Search for a bot (Cmd+F or click search)
osascript -e '
tell application "System Events"
    keystroke "f" using command down
    delay 0.5
    keystroke "MyTestBot"
    delay 1
    key code 36  -- Enter to select
end tell
'
sleep 2
```

### Send Message to Bot

```bash
# After navigating to bot chat, input is focused
osascript -e '
tell application "System Events"
    keystroke "/start"
    delay 0.3
    key code 36
end tell
'
```

### Send Long Message

```bash
osascript -e '
tell application "Telegram" to activate
delay 0.5
set the clipboard to "Tell me about quantum computing in detail"
tell application "System Events"
    keystroke "v" using command down
    delay 0.3
    key code 36
end tell
'
```

### Verify Response

```bash
sleep 10
screencapture /tmp/telegram-bot-response.png
```

### Telegram Bot API (programmatic alternative)

For sending messages directly to the bot's chat without UI:

```bash
# Send message as the bot (for testing webhooks/responses)
curl -s "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/sendMessage" \
  -d "chat_id=$CHAT_ID&text=test message"

# Get recent updates
curl -s "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/getUpdates?limit=5" | jq .
```

---

## Client: WeChat / 微信

**App name:** `微信` or `WeChat` | **Process name:** `WeChat`

### Activate & Navigate

```bash
# Activate WeChat
osascript -e 'tell application "微信" to activate'
sleep 1

# Search for a contact/bot (Cmd+F)
osascript -e '
tell application "System Events"
    keystroke "f" using command down
    delay 0.5
    keystroke "TestBot"
    delay 1
    key code 36  -- Enter to select
end tell
'
sleep 2
```

### Send Message

```bash
# After navigating to a chat, the input is focused
osascript -e '
tell application "System Events"
    keystroke "Hello bot!"
    delay 0.3
    key code 36
end tell
'
```

### Send Long Message (clipboard)

```bash
osascript -e '
tell application "微信" to activate
delay 0.5
set the clipboard to "Please help me with this task..."
tell application "System Events"
    keystroke "v" using command down
    delay 0.3
    key code 36
end tell
'
```

### Verify Response

```bash
sleep 10
screencapture /tmp/wechat-bot-response.png
```

### WeChat-Specific Notes

- WeChat macOS app name can be `微信` or `WeChat` depending on system language. Try both:
  ```bash
  osascript -e 'tell application "微信" to activate' 2> /dev/null \
    || osascript -e 'tell application "WeChat" to activate'
  ```
- WeChat uses **Enter** to send (not Cmd+Enter by default, but configurable)
- For multi-line messages without sending, use **Shift+Enter**:
  ```bash
  osascript -e 'tell application "System Events" to key code 36 using shift down'
  ```

---

## Client: Lark / 飞书

**App name:** `Lark` or `飞书` | **Process name:** `Lark` or `飞书`

### Activate & Navigate

```bash
# Activate Lark (auto-detects Lark or 飞书)
osascript -e 'tell application "Lark" to activate' 2> /dev/null \
  || osascript -e 'tell application "飞书" to activate'
sleep 1

# Quick Switcher / Search (Cmd+K)
osascript -e 'tell application "System Events" to keystroke "k" using command down'
sleep 0.5
osascript -e '
set the clipboard to "bot-testing"
tell application "System Events"
    keystroke "v" using command down
    delay 1.5
    key code 36  -- Enter
end tell
'
sleep 2
```

### Send Message to Bot

```bash
osascript -e '
set the clipboard to "@MyBot help me with this task"
tell application "System Events"
    keystroke "v" using command down
    delay 0.3
    key code 36  -- Enter
end tell
'
```

### Verify Response

```bash
sleep 10
screencapture /tmp/lark-bot-response.png
```

### Lark-Specific Notes

- App name varies: `Lark` (international) vs `飞书` (China mainland) — the script auto-detects
- Uses `Cmd+K` for quick search (same as Discord/Slack)
- Enter sends message by default

---

## Client: QQ

**App name:** `QQ` | **Process name:** `QQ`

### Activate & Navigate

```bash
osascript -e 'tell application "QQ" to activate'
sleep 1

# Search for contact/group (Cmd+F)
osascript -e '
tell application "System Events"
    keystroke "f" using command down
    delay 0.8
end tell
'
osascript -e '
set the clipboard to "bot-testing"
tell application "System Events"
    keystroke "v" using command down
    delay 1.5
    key code 36  -- Enter
end tell
'
sleep 2
```

### Send Message to Bot

```bash
osascript -e '
set the clipboard to "Hello bot!"
tell application "System Events"
    keystroke "v" using command down
    delay 0.3
    key code 36  -- Enter
end tell
'
```

### Verify Response

```bash
sleep 10
screencapture /tmp/qq-bot-response.png
```

### QQ-Specific Notes

- Enter sends message by default; Shift+Enter for newlines
- Uses `Cmd+F` for search
- Always use clipboard paste for CJK characters

---

## Common Bot Testing Workflow (osascript)

Regardless of platform, the pattern is:

```bash
APP_NAME="Discord" # or "Slack", "Telegram", "微信"
CHANNEL="bot-testing"
MESSAGE="Hello bot!"
WAIT_SECONDS=10

# 1. Activate
osascript -e "tell application \"$APP_NAME\" to activate"
sleep 1

# 2. Navigate to channel/chat (via Quick Switcher or Search)
osascript -e 'tell application "System Events" to keystroke "k" using command down'
sleep 0.5
osascript -e "tell application \"System Events\" to keystroke \"$CHANNEL\""
sleep 1
osascript -e 'tell application "System Events" to key code 36'
sleep 2

# 3. Send message
osascript -e "set the clipboard to \"$MESSAGE\""
osascript -e '
tell application "System Events"
    keystroke "v" using command down
    delay 0.3
    key code 36
end tell
'

# 4. Wait for bot response
sleep "$WAIT_SECONDS"

# 5. Screenshot for verification
screencapture /tmp/"${APP_NAME,,}"-bot-test.png
echo "Result saved to /tmp/${APP_NAME,,}-bot-test.png"
```

### Tips

- **Use clipboard paste** (`Cmd+V`) for messages containing special characters or long text — `keystroke` can mangle non-ASCII
- **Add `delay`** between actions — apps need time to process UI events
- **Screenshot for verification** — use `screencapture` + `Read` tool for visual checks
- **Use a dedicated test channel/chat** — avoid polluting real conversations
- **Check app name** — some apps have different names in different locales (e.g., `微信` vs `WeChat`)
- **Accessibility permissions required** — System Events automation requires granting Accessibility access in System Preferences > Privacy & Security > Accessibility

---

# Scripts

Ready-to-use scripts in `.agents/skills/local-testing/scripts/`:

| Script                    | Usage                                         |
| ------------------------- | --------------------------------------------- |
| `capture-app-window.sh`   | Capture screenshot of a specific app window   |
| `record-electron-demo.sh` | Record Electron app demo with ffmpeg          |
| `test-discord-bot.sh`     | Send message to Discord bot via osascript     |
| `test-slack-bot.sh`       | Send message to Slack bot via osascript       |
| `test-telegram-bot.sh`    | Send message to Telegram bot via osascript    |
| `test-wechat-bot.sh`      | Send message to WeChat bot via osascript      |
| `test-lark-bot.sh`        | Send message to Lark / 飞书 bot via osascript |
| `test-qq-bot.sh`          | Send message to QQ bot via osascript          |

### Window Screenshot Utility

`capture-app-window.sh` captures a screenshot of a specific app window using `screencapture -l <windowID>`. It uses Swift + CGWindowList to find the window by process name, so screenshots work correctly even when the window is on an external monitor or behind other windows.

```bash
# Standalone usage
./.agents/skills/local-testing/scripts/capture-app-window.sh "Discord" /tmp/discord.png
./.agents/skills/local-testing/scripts/capture-app-window.sh "Slack" /tmp/slack.png
./.agents/skills/local-testing/scripts/capture-app-window.sh "WeChat" /tmp/wechat.png
```

All bot test scripts use this utility automatically for their screenshots.

### Bot Test Scripts

All bot test scripts share the same interface:

```bash
./scripts/test-<platform>-bot.sh <channel_or_contact> <message> [wait_seconds] [screenshot_path]
```

Examples:

```bash
# Discord — test a bot in #bot-testing channel
./.agents/skills/local-testing/scripts/test-discord-bot.sh "bot-testing" "!ping"
./.agents/skills/local-testing/scripts/test-discord-bot.sh "bot-testing" "/ask Tell me a joke" 30

# Slack — test a bot in #bot-testing channel
./.agents/skills/local-testing/scripts/test-slack-bot.sh "bot-testing" "@mybot hello"
./.agents/skills/local-testing/scripts/test-slack-bot.sh "bot-testing" "/ask What is 2+2?" 20

# Telegram — test a bot by username
./.agents/skills/local-testing/scripts/test-telegram-bot.sh "MyTestBot" "/start"
./.agents/skills/local-testing/scripts/test-telegram-bot.sh "GPTBot" "Hello" 60

# WeChat — test a bot or send to a contact
./.agents/skills/local-testing/scripts/test-wechat-bot.sh "文件传输助手" "test message" 5
./.agents/skills/local-testing/scripts/test-wechat-bot.sh "MyBot" "Tell me a joke" 30

# Lark/飞书 — test a bot in a group chat
./.agents/skills/local-testing/scripts/test-lark-bot.sh "bot-testing" "@MyBot hello"
./.agents/skills/local-testing/scripts/test-lark-bot.sh "bot-testing" "Help me with this" 30

# QQ — test a bot in a group or direct chat
./.agents/skills/local-testing/scripts/test-qq-bot.sh "bot-testing" "Hello bot" 15
./.agents/skills/local-testing/scripts/test-qq-bot.sh "MyBot" "/help" 10
```

Each script: activates the app, navigates to the channel/contact, pastes the message via clipboard, sends, waits, and takes a screenshot. Use the `Read` tool on the screenshot for visual verification.

---

# Screen Recording

Record automated demos by combining `ffmpeg` screen capture with `agent-browser` automation. The script `.agents/skills/local-testing/scripts/record-electron-demo.sh` handles the full lifecycle for Electron.

### Usage

```bash
# Run the built-in demo (queue-edit feature)
./.agents/skills/local-testing/scripts/record-electron-demo.sh

# Run a custom automation script
./.agents/skills/local-testing/scripts/record-electron-demo.sh ./my-demo.sh /tmp/my-demo.mp4
```

The script automatically:

1. Starts Electron with CDP and waits for SPA to load
2. Detects window position, screen, and Retina scale via Swift/CGWindowList
3. Records only the Electron window region using `ffmpeg -f avfoundation` with crop
4. Runs the demo (built-in or custom script receiving CDP port as `$1`)
5. Stops recording and cleans up

---

# Gotchas

### agent-browser

- **Daemon can get stuck** — if commands hang, `pkill -f agent-browser` to reset
- **`agent-browser wait` blocks the daemon** — for waits >30s, use bash `sleep`
- **HMR invalidates everything** — after code changes, refs break. Re-snapshot or restart
- **`snapshot -i` doesn't find contenteditable** — use `snapshot -i -C` for rich text editors
- **`fill` doesn't work on contenteditable** — use `type` for chat inputs
- **Screenshots go to `~/.agent-browser/tmp/screenshots/`** — read them with the `Read` tool

### Electron-specific

- **`npx electron-vite dev` must run from `apps/desktop/`** — running from project root fails silently
- **Don't resize the Electron window after load** — resizing triggers full SPA reload
- **Store is at `window.__LOBE_STORES`** not `window.__ZUSTAND_STORES__`

### osascript

- **Accessibility permission required** — first run will prompt for access; grant it in System Preferences > Privacy & Security > Accessibility for Terminal / iTerm / Claude Code
- **`keystroke` is slow for long text** — always use clipboard paste (`Cmd+V`) for messages over \~20 characters
- **`keystroke` can mangle non-ASCII** — use clipboard paste for Chinese, emoji, or special characters
- **`key code 36` is Enter** — this is the hardware key code, works regardless of keyboard layout
- **`entire contents` is extremely slow** — avoid for complex UIs; use screenshots instead
- **App name varies by locale** — `微信` vs `WeChat`, `企业微信` vs `WeCom`; handle both
- **WeChat Enter sends immediately** — use `Shift+Enter` for newlines within a message
- **Rate limiting** — don't send messages too fast; platforms may throttle or flag automated input
- **Lark / 飞书 app name varies** — `Lark` (international) vs `飞书` (China mainland); scripts auto-detect
- **QQ uses `Cmd+F` for search** — not `Cmd+K` like Discord/Slack/Lark
- **Bot response times vary** — AI-powered bots may take 10-60s; use generous sleep values


================================================
FILE: .agents/skills/local-testing/scripts/capture-app-window.sh
================================================
#!/usr/bin/env bash
#
# capture-app-window.sh — Capture a screenshot of a specific app window
#
# Uses CGWindowList via Swift to find the window by process name, then
# screencapture -l <windowID> to capture only that window.
# Falls back to full-screen capture if the window is not found.
#
# Usage:
#   ./capture-app-window.sh <process_name> <output_path>
#
# Arguments:
#   process_name — The process/owner name as shown in Activity Monitor
#                  (e.g., "Discord", "Slack", "Telegram", "WeChat", "QQ", "Lark")
#   output_path  — Path to save the screenshot (e.g., /tmp/screenshot.png)
#
# Examples:
#   ./capture-app-window.sh "Discord" /tmp/discord.png
#   ./capture-app-window.sh "Slack" /tmp/slack.png
#   ./capture-app-window.sh "微信" /tmp/wechat.png
#
set -euo pipefail

PROCESS="${1:?Usage: capture-app-window.sh <process_name> <output_path>}"
OUTPUT="${2:?Usage: capture-app-window.sh <process_name> <output_path>}"

# Find the CGWindowID for the target process using Swift + CGWindowList
# Pass process name via environment variable (swift -e doesn't support -- args)
WINDOW_ID=$(TARGET_PROCESS="$PROCESS" swift -e '
import Cocoa
import Foundation
let target = ProcessInfo.processInfo.environment["TARGET_PROCESS"] ?? ""
let windowList = CGWindowListCopyWindowInfo([.optionAll], kCGNullWindowID) as! [[String: Any]]
for w in windowList {
    let owner = w["kCGWindowOwnerName"] as? String ?? ""
    let layer = w["kCGWindowLayer"] as? Int ?? -1
    let bounds = w["kCGWindowBounds"] as? [String: Any] ?? [:]
    let ww = bounds["Width"] as? Double ?? 0
    let wh = bounds["Height"] as? Double ?? 0
    let wid = w["kCGWindowNumber"] as? Int ?? 0
    // Match process name, normal window layer (0), and reasonable size
    if owner == target && layer == 0 && ww > 200 && wh > 200 {
        print(wid)
        break
    }
}
' 2>/dev/null || true)

if [ -n "$WINDOW_ID" ]; then
  screencapture -l "$WINDOW_ID" -x "$OUTPUT"
else
  echo "[capture] Warning: Could not find window for '$PROCESS', falling back to full screen"
  screencapture -x "$OUTPUT"
fi


================================================
FILE: .agents/skills/local-testing/scripts/record-electron-demo.sh
================================================
#!/usr/bin/env bash
#
# record-electron-demo.sh — Record an automated demo of the Electron app
#
# Usage:
#   ./scripts/record-electron-demo.sh [script.sh] [output.mp4]
#
#   script.sh  — A shell script containing agent-browser commands to automate.
#                It receives the CDP port as $1. Defaults to a built-in queue-edit demo.
#   output.mp4 — Output file path. Defaults to /tmp/electron-demo.mp4
#
# Prerequisites:
#   - agent-browser CLI installed globally
#   - ffmpeg installed (brew install ffmpeg)
#   - Electron app NOT already running (script manages lifecycle)
#
# Examples:
#   # Run built-in demo
#   ./scripts/record-electron-demo.sh
#
#   # Run custom automation script
#   ./scripts/record-electron-demo.sh ./my-demo.sh /tmp/my-demo.mp4
#
set -euo pipefail

CDP_PORT=9222
DEMO_SCRIPT="${1:-}"
OUTPUT="${2:-/tmp/electron-demo.mp4}"
ELECTRON_LOG="/tmp/electron-dev.log"
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"
RECORD_PID=""

# ── Helpers ──────────────────────────────────────────────────────────

cleanup() {
  echo "[cleanup] Stopping all processes..."
  [ -n "$RECORD_PID" ] && kill -INT "$RECORD_PID" 2>/dev/null && sleep 2
  pkill -f "electron-vite" 2>/dev/null || true
  pkill -f "Electron" 2>/dev/null || true
  pkill -f "agent-browser" 2>/dev/null || true
  echo "[cleanup] Done."
}
trap cleanup EXIT

wait_for_electron() {
  echo "[wait] Waiting for Electron to start..."
  for i in $(seq 1 24); do
    sleep 5
    if strings "$ELECTRON_LOG" 2>/dev/null | grep -q "starting electron"; then
      echo "[wait] Electron process ready."
      return 0
    fi
    echo "[wait] Still waiting... (${i}/24)"
  done
  echo "[error] Electron failed to start within 120s"
  exit 1
}

wait_for_renderer() {
  echo "[wait] Waiting for renderer to load..."
  sleep 15
  agent-browser --cdp "$CDP_PORT" wait 3000

  # Poll until interactive elements appear (SPA may take extra time)
  for i in $(seq 1 12); do
    local snap
    snap=$(agent-browser --cdp "$CDP_PORT" snapshot -i 2>&1)
    if echo "$snap" | grep -q 'link "'; then
      echo "[wait] Renderer ready (interactive elements found)."
      return 0
    fi
    echo "[wait] SPA still loading... (${i}/12)"
    sleep 5
  done
  echo "[warn] Timed out waiting for interactive elements, proceeding anyway."
}

get_window_and_screen_info() {
  # Returns: window_x window_y window_w window_h screen_index
  # Uses Swift to find the Electron window bounds and which screen it's on
  swift -e '
    import Cocoa
    let windowList = CGWindowListCopyWindowInfo([.optionAll], kCGNullWindowID) as! [[String: Any]]
    for w in windowList {
      let owner = w["kCGWindowOwnerName"] as? String ?? ""
      let name = w["kCGWindowName"] as? String ?? ""
      let layer = w["kCGWindowLayer"] as? Int ?? -1
      let bounds = w["kCGWindowBounds"] as? [String: Any] ?? [:]
      let wx = bounds["X"] as? Double ?? 0
      let wy = bounds["Y"] as? Double ?? 0
      let ww = bounds["Width"] as? Double ?? 0
      let wh = bounds["Height"] as? Double ?? 0
      if (owner == "Electron" || owner == "LobeHub") && layer == 0 && name == "LobeHub" && ww > 200 && wh > 200 {
        // Find which screen this window is on
        let screens = NSScreen.screens
        var screenIdx = 0
        let windowCenter = NSPoint(x: wx + ww / 2, y: wy + wh / 2)
        for (i, screen) in screens.enumerated() {
          let frame = screen.frame
          // Convert CG coords (top-left origin) to NSScreen coords (bottom-left origin)
          let mainHeight = screens[0].frame.height
          let screenTop = mainHeight - frame.origin.y - frame.height
          let screenBottom = screenTop + frame.height
          let screenLeft = frame.origin.x
          let screenRight = screenLeft + frame.width
          if windowCenter.x >= screenLeft && windowCenter.x <= screenRight &&
             windowCenter.y >= screenTop && windowCenter.y <= screenBottom {
            screenIdx = i
            break
          }
        }
        // Compute window position relative to the screen it is on
        let screen = screens[screenIdx]
        let mainHeight = screens[0].frame.height
        let screenTop = mainHeight - screen.frame.origin.y - screen.frame.height
        let relX = wx - screen.frame.origin.x
        let relY = wy - screenTop
        let scale = Int(screen.backingScaleFactor)
        print("\(Int(relX)) \(Int(relY)) \(Int(ww)) \(Int(wh)) \(screenIdx) \(scale)")
        break
      }
    }
  '
}

start_recording() {
  local rel_x=$1 rel_y=$2 w=$3 h=$4 screen_idx=$5 scale=$6

  # ffmpeg avfoundation device index for screens
  # List devices and find the one matching our screen index
  local device_idx
  device_idx=$(ffmpeg -f avfoundation -list_devices true -i "" 2>&1 \
    | grep "Capture screen ${screen_idx}" \
    | grep -oE '\[[0-9]+\]' | tr -d '[]' || true)

  if [ -z "$device_idx" ]; then
    echo "[warn] Could not find capture device for screen $screen_idx, trying default (3)"
    device_idx=3
  fi

  # Scale coordinates to native resolution
  local cx=$((rel_x * scale))
  local cy=$((rel_y * scale))
  local cw=$((w * scale))
  local ch=$((h * scale))

  echo "[record] Window: ${rel_x},${rel_y} ${w}x${h} on screen ${screen_idx} (scale=${scale})"
  echo "[record] Crop: ${cx},${cy} ${cw}x${ch}, device: ${device_idx}"
  echo "[record] Output: $OUTPUT"

  ffmpeg -y \
    -f avfoundation -framerate 30 -capture_cursor 1 -i "${device_idx}:" \
    -vf "crop=${cw}:${ch}:${cx}:${cy},scale=${w}:${h}" \
    -c:v libx264 -crf 23 -preset fast -an \
    "$OUTPUT" \
    > /tmp/ffmpeg-record.log 2>&1 &
  RECORD_PID=$!
  sleep 2

  if ! kill -0 "$RECORD_PID" 2>/dev/null; then
    echo "[error] ffmpeg failed to start. Log:"
    cat /tmp/ffmpeg-record.log
    RECORD_PID=""
    return 1
  fi
  echo "[record] Recording started (PID=$RECORD_PID)"
}

stop_recording() {
  if [ -n "$RECORD_PID" ]; then
    echo "[record] Stopping recording..."
    kill -INT "$RECORD_PID" 2>/dev/null || true
    wait "$RECORD_PID" 2>/dev/null || true
    RECORD_PID=""
    echo "[record] Saved to $OUTPUT"
    ls -lh "$OUTPUT"
  fi
}

# ── Built-in demo: Queue Edit ────────────────────────────────────────

find_input_ref() {
  local port=$1
  agent-browser --cdp "$port" snapshot -i -C 2>&1 \
    | grep "editable" \
    | grep -oE 'ref=e[0-9]+' \
    | head -1 \
    | sed 's/ref=//'
}

builtin_demo() {
  local port=$1

  echo "[demo] Step 1: Navigate to first available agent"
  local snapshot agent_ref
  snapshot=$(agent-browser --cdp "$port" snapshot -i 2>&1)
  # Try Lobe AI first, then fall back to any agent link in the sidebar
  agent_ref=$(echo "$snapshot" | grep -oE 'link "Lobe AI" \[ref=e[0-9]+\]' | grep -oE 'e[0-9]+' || true)
  if [ -z "$agent_ref" ]; then
    # Pick the first agent-like link (skip nav links)
    agent_ref=$(echo "$snapshot" | grep 'link "' | grep -vE '"Home"|"Pages"|"Settings"|"Search"|"Resources"|"Marketplace"' | head -1 | grep -oE 'ref=e[0-9]+' | sed 's/ref=//' || true)
  fi
  if [ -z "$agent_ref" ]; then
    echo "[error] No agent link found in snapshot"
    echo "$snapshot" | head -30
    return 1
  fi
  echo "[demo] Clicking agent ref: @$agent_ref"
  agent-browser --cdp "$port" click "@$agent_ref"
  sleep 3

  echo "[demo] Step 2: Send first message (triggers AI generation)"
  local input_ref
  input_ref=$(find_input_ref "$port")
  agent-browser --cdp "$port" click "@$input_ref"
  agent-browser --cdp "$port" type "@$input_ref" "Write a 3000 word essay about the complete history of space exploration from Sputnik to the James Webb Space Telescope"
  sleep 1
  agent-browser --cdp "$port" press Enter
  sleep 3

  echo "[demo] Step 3: Queue message 1"
  input_ref=$(find_input_ref "$port")
  agent-browser --cdp "$port" click "@$input_ref"
  agent-browser --cdp "$port" type "@$input_ref" "This message should be edited"
  sleep 1
  agent-browser --cdp "$port" press Enter
  sleep 1

  echo "[demo] Step 4: Queue message 2"
  input_ref=$(find_input_ref "$port")
  agent-browser --cdp "$port" click "@$input_ref"
  agent-browser --cdp "$port" type "@$input_ref" "Another queued message"
  sleep 1
  agent-browser --cdp "$port" press Enter
  sleep 1

  echo "[demo] Step 5: Verify queue has messages"
  local queue_count
  queue_count=$(agent-browser --cdp "$port" eval --stdin << 'EVALEOF'
(function() {
  var chat = window.__LOBE_STORES.chat();
  var total = 0;
  Object.keys(chat.queuedMessages).forEach(function(k) {
    total += chat.queuedMessages[k].length;
  });
  return String(total);
})()
EVALEOF
  )
  echo "[demo] Queue count: $queue_count"

  if [ "$queue_count" = "0" ] || [ "$queue_count" = '"0"' ]; then
    echo "[demo] Queue was already drained. Retrying..."
    input_ref=$(find_input_ref "$port")
    agent-browser --cdp "$port" click "@$input_ref"
    agent-browser --cdp "$port" type "@$input_ref" "Now write another 3000 word essay about artificial intelligence from Turing to transformers covering every major breakthrough"
    sleep 1
    agent-browser --cdp "$port" press Enter
    sleep 2
    input_ref=$(find_input_ref "$port")
    agent-browser --cdp "$port" click "@$input_ref"
    agent-browser --cdp "$port" type "@$input_ref" "This message should be edited"
    sleep 1
    agent-browser --cdp "$port" press Enter
    sleep 1
    input_ref=$(find_input_ref "$port")
    agent-browser --cdp "$port" click "@$input_ref"
    agent-browser --cdp "$port" type "@$input_ref" "Another queued message"
    sleep 1
    agent-browser --cdp "$port" press Enter
    sleep 1
  fi

  echo "[demo] Step 6: Scroll to show queue tray"
  agent-browser --cdp "$port" scroll down 5000
  sleep 2

  echo "[demo] Step 7: Click edit button on first queued message"
  agent-browser --cdp "$port" eval --stdin << 'EVALEOF'
(function() {
  var chat = window.__LOBE_STORES.chat();
  var keys = Object.keys(chat.queuedMessages);
  for (var k = 0; k < keys.length; k++) {
    var queue = chat.queuedMessages[keys[k]];
    if (queue.length > 0) {
      var targetText = queue[0].content;
      var walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT, null);
      while (walker.nextNode()) {
        var node = walker.currentNode;
        if (node.textContent.trim() === targetText) {
          var row = node.parentElement.parentElement;
          var buttons = row.querySelectorAll('[role="button"]');
          if (buttons.length >= 1) {
            buttons[0].click();
            return 'clicked edit on: ' + targetText;
          }
        }
      }
    }
  }
  return 'edit button not found';
})()
EVALEOF
  sleep 3

  echo "[demo] Step 8: Show result — content restored to input"
  sleep 3

  echo "[demo] Complete!"
}

# ── Main ─────────────────────────────────────────────────────────────

echo "=== Electron Demo Recorder ==="

# 1. Kill existing instances
echo "[setup] Cleaning up existing processes..."
pkill -f "Electron" 2>/dev/null || true
pkill -f "electron-vite" 2>/dev/null || true
pkill -f "agent-browser" 2>/dev/null || true
sleep 3

# 2. Start Electron
echo "[setup] Starting Electron..."
cd "$PROJECT_ROOT/apps/desktop"
ELECTRON_ENABLE_LOGGING=1 npx electron-vite dev -- --remote-debugging-port="$CDP_PORT" > "$ELECTRON_LOG" 2>&1 &

wait_for_electron
wait_for_renderer

# 3. Get window position and start recording
WIN_INFO=$(get_window_and_screen_info)
if [ -z "$WIN_INFO" ]; then
  echo "[error] Could not find Electron window"
  exit 1
fi
read -r WIN_X WIN_Y WIN_W WIN_H SCREEN_IDX SCALE <<< "$WIN_INFO"
start_recording "$WIN_X" "$WIN_Y" "$WIN_W" "$WIN_H" "$SCREEN_IDX" "$SCALE"

# 4. Run demo script
if [ -n "$DEMO_SCRIPT" ] && [ -f "$DEMO_SCRIPT" ]; then
  echo "[demo] Running custom script: $DEMO_SCRIPT"
  bash "$DEMO_SCRIPT" "$CDP_PORT"
else
  echo "[demo] Running built-in queue-edit demo"
  builtin_demo "$CDP_PORT"
fi

# 5. Stop recording
stop_recording

echo "=== Done! Output: $OUTPUT ==="


================================================
FILE: .agents/skills/local-testing/scripts/test-discord-bot.sh
================================================
#!/usr/bin/env bash
#
# test-discord-bot.sh — Send a message to a Discord bot and capture the response
#
# Usage:
#   ./scripts/test-discord-bot.sh <channel> <message> [wait_seconds] [screenshot_path]
#
#   channel         — Channel name to navigate to via Quick Switcher (Cmd+K)
#   message         — Message to send to the bot
#   wait_seconds    — Seconds to wait for bot response (default: 10)
#   screenshot_path — Output screenshot path (default: /tmp/discord-bot-test.png)
#
# Prerequisites:
#   - Discord desktop app installed and logged in
#   - Accessibility permission granted (System Preferences > Privacy > Accessibility)
#
# Examples:
#   ./scripts/test-discord-bot.sh "bot-testing" "!ping"
#   ./scripts/test-discord-bot.sh "bot-testing" "/ask Tell me a joke" 30
#   ./scripts/test-discord-bot.sh "general" "Hello bot" 15 /tmp/my-test.png
#
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
CHANNEL="${1:?Usage: test-discord-bot.sh <channel> <message> [wait_seconds] [screenshot_path]}"
MESSAGE="${2:?Usage: test-discord-bot.sh <channel> <message> [wait_seconds] [screenshot_path]}"
WAIT="${3:-10}"
SCREENSHOT="${4:-/tmp/discord-bot-test.png}"

APP="Discord"

echo "[$APP] Activating..."
osascript -e "tell application \"$APP\" to activate"
sleep 1

echo "[$APP] Navigating to channel: $CHANNEL"
osascript -e '
tell application "System Events"
    -- Quick Switcher
    keystroke "k" using command down
    delay 0.8
    keystroke "'"$CHANNEL"'"
    delay 1.5
    key code 36  -- Enter
end tell
'
sleep 2

echo "[$APP] Sending message: $MESSAGE"
osascript -e '
set the clipboard to "'"$MESSAGE"'"
tell application "System Events"
    keystroke "v" using command down
    delay 0.3
    key code 36  -- Enter
end tell
'

echo "[$APP] Waiting ${WAIT}s for bot response..."
sleep "$WAIT"

echo "[$APP] Capturing screenshot..."
"$SCRIPT_DIR/capture-app-window.sh" "$APP" "$SCREENSHOT"
echo "[$APP] Done! Screenshot saved to $SCREENSHOT"


================================================
FILE: .agents/skills/local-testing/scripts/test-lark-bot.sh
================================================
#!/usr/bin/env bash
#
# test-lark-bot.sh — Send a message to a Lark/Feishu bot and capture the response
#
# Usage:
#   ./scripts/test-lark-bot.sh <chat> <message> [wait_seconds] [screenshot_path]
#
#   chat            — Chat or contact name to search for
#   message         — Message to send to the bot
#   wait_seconds    — Seconds to wait for bot response (default: 10)
#   screenshot_path — Output screenshot path (default: /tmp/lark-bot-test.png)
#
# Prerequisites:
#   - Lark (飞书) desktop app installed and logged in
#   - Accessibility permission granted (System Preferences > Privacy > Accessibility)
#
# Notes:
#   - The app name may be "Lark" or "飞书" depending on version/locale
#   - Uses Cmd+K to open search/quick switcher
#   - Enter sends message by default
#
# Examples:
#   ./scripts/test-lark-bot.sh "TestBot" "Hello"
#   ./scripts/test-lark-bot.sh "bot-testing" "/ask Tell me a joke" 30
#   ./scripts/test-lark-bot.sh "MyBot" "Help me summarize this" 60 /tmp/my-test.png
#
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
CHAT="${1:?Usage: test-lark-bot.sh <chat> <message> [wait_seconds] [screenshot_path]}"
MESSAGE="${2:?Usage: test-lark-bot.sh <chat> <message> [wait_seconds] [screenshot_path]}"
WAIT="${3:-10}"
SCREENSHOT="${4:-/tmp/lark-bot-test.png}"

# Detect app name — "Lark" or "飞书"
APP=""
if osascript -e 'tell application "Lark" to name' &>/dev/null; then
  APP="Lark"
elif osascript -e 'tell application "飞书" to name' &>/dev/null; then
  APP="飞书"
else
  echo "[error] Lark/飞书 app not found. Install Lark or 飞书."
  exit 1
fi

echo "[$APP] Activating..."
osascript -e "tell application \"$APP\" to activate"
sleep 1

echo "[$APP] Searching for chat: $CHAT"
osascript -e '
tell application "System Events"
    -- Quick Switcher / Search (Cmd+K)
    keystroke "k" using command down
    delay 0.8
end tell
'
# Use clipboard for chat name (supports CJK characters)
osascript -e '
set the clipboard to "'"$CHAT"'"
tell application "System Events"
    keystroke "v" using command down
    delay 1.5
    key code 36  -- Enter to select first result
end tell
'
sleep 2

echo "[$APP] Sending message: $MESSAGE"
osascript -e '
set the clipboard to "'"$MESSAGE"'"
tell application "System Events"
    keystroke "v" using command down
    delay 0.3
    key code 36  -- Enter to send
end tell
'

echo "[$APP] Waiting ${WAIT}s for bot response..."
sleep "$WAIT"

echo "[$APP] Capturing screenshot..."
"$SCRIPT_DIR/capture-app-window.sh" "$APP" "$SCREENSHOT"
echo "[$APP] Done! Screenshot saved to $SCREENSHOT"


================================================
FILE: .agents/skills/local-testing/scripts/test-qq-bot.sh
================================================
#!/usr/bin/env bash
#
# test-qq-bot.sh — Send a message to a QQ bot and capture the response
#
# Usage:
#   ./scripts/test-qq-bot.sh <contact> <message> [wait_seconds] [screenshot_path]
#
#   contact         — Contact, group, or bot name to search for
#   message         — Message to send
#   wait_seconds    — Seconds to wait for bot response (default: 10)
#   screenshot_path — Output screenshot path (default: /tmp/qq-bot-test.png)
#
# Prerequisites:
#   - QQ desktop app installed and logged in
#   - Accessibility permission granted (System Preferences > Privacy > Accessibility)
#
# Notes:
#   - The app name is "QQ"
#   - Uses Cmd+F to open search
#   - Enter sends message by default; Shift+Enter for newlines
#   - Uses clipboard paste for CJK character support
#
# Examples:
#   ./scripts/test-qq-bot.sh "TestBot" "Hello"
#   ./scripts/test-qq-bot.sh "bot-testing" "Hello bot" 30
#   ./scripts/test-qq-bot.sh "MyBot" "/help" 15 /tmp/my-test.png
#
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
CONTACT="${1:?Usage: test-qq-bot.sh <contact> <message> [wait_seconds] [screenshot_path]}"
MESSAGE="${2:?Usage: test-qq-bot.sh <contact> <message> [wait_seconds] [screenshot_path]}"
WAIT="${3:-10}"
SCREENSHOT="${4:-/tmp/qq-bot-test.png}"

APP="QQ"

echo "[$APP] Activating..."
osascript -e "tell application \"$APP\" to activate"
sleep 1

echo "[$APP] Searching for contact: $CONTACT"
osascript -e '
tell application "System Events"
    -- Search (Cmd+F)
    keystroke "f" using command down
    delay 0.8
end tell
'
# Use clipboard for contact name (supports CJK characters)
osascript -e '
set the clipboard to "'"$CONTACT"'"
tell application "System Events"
    keystroke "v" using command down
    delay 1.5
    key code 36  -- Enter to select first result
end tell
'
sleep 2

echo "[$APP] Sending message: $MESSAGE"
osascript -e '
set the clipboard to "'"$MESSAGE"'"
tell application "System Events"
    keystroke "v" using command down
    delay 0.3
    key code 36  -- Enter to send
end tell
'

echo "[$APP] Waiting ${WAIT}s for bot response..."
sleep "$WAIT"

echo "[$APP] Capturing screenshot..."
"$SCRIPT_DIR/capture-app-window.sh" "$APP" "$SCREENSHOT"
echo "[$APP] Done! Screenshot saved to $SCREENSHOT"


================================================
FILE: .agents/skills/local-testing/scripts/test-slack-bot.sh
================================================
#!/usr/bin/env bash
#
# test-slack-bot.sh — Send a message to a Slack bot and capture the response
#
# Usage:
#   ./scripts/test-slack-bot.sh <channel> <message> [wait_seconds] [screenshot_path]
#
#   channel         — Channel name to navigate to via Quick Switcher (Cmd+K)
#   message         — Message to send (e.g., "@mybot hello" or "/ask question")
#   wait_seconds    — Seconds to wait for bot response (default: 10)
#   screenshot_path — Output screenshot path (default: /tmp/slack-bot-test.png)
#
# Prerequisites:
#   - Slack desktop app installed and logged in
#   - Accessibility permission granted (System Preferences > Privacy > Accessibility)
#
# Examples:
#   ./scripts/test-slack-bot.sh "bot-testing" "@mybot hello"
#   ./scripts/test-slack-bot.sh "bot-testing" "/ask What is 2+2?" 20
#   ./scripts/test-slack-bot.sh "general" "Hey bot" 15 /tmp/my-test.png
#
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
CHANNEL="${1:?Usage: test-slack-bot.sh <channel> <message> [wait_seconds] [screenshot_path]}"
MESSAGE="${2:?Usage: test-slack-bot.sh <channel> <message> [wait_seconds] [screenshot_path]}"
WAIT="${3:-10}"
SCREENSHOT="${4:-/tmp/slack-bot-test.png}"

APP="Slack"

echo "[$APP] Activating..."
osascript -e "tell application \"$APP\" to activate"
sleep 1

echo "[$APP] Navigating to channel: $CHANNEL"
osascript -e '
tell application "System Events"
    -- Quick Switcher
    keystroke "k" using command down
    delay 0.8
    keystroke "'"$CHANNEL"'"
    delay 1.5
    key code 36  -- Enter
end tell
'
sleep 2

echo "[$APP] Sending message: $MESSAGE"
osascript -e '
set the clipboard to "'"$MESSAGE"'"
tell application "System Events"
    keystroke "v" using command down
    delay 0.3
    key code 36  -- Enter
end tell
'

echo "[$APP] Waiting ${WAIT}s for bot response..."
sleep "$WAIT"

echo "[$APP] Capturing screenshot..."
"$SCRIPT_DIR/capture-app-window.sh" "$APP" "$SCREENSHOT"
echo "[$APP] Done! Screenshot saved to $SCREENSHOT"


================================================
FILE: .agents/skills/local-testing/scripts/test-telegram-bot.sh
================================================
#!/usr/bin/env bash
#
# test-telegram-bot.sh — Send a message to a Telegram bot and capture the response
#
# Usage:
#   ./scripts/test-telegram-bot.sh <bot_or_chat> <message> [wait_seconds] [screenshot_path]
#
#   bot_or_chat     — Bot username or chat name to search for
#   message         — Message to send to the bot
#   wait_seconds    — Seconds to wait for bot response (default: 10)
#   screenshot_path — Output screenshot path (default: /tmp/telegram-bot-test.png)
#
# Prerequisites:
#   - Telegram desktop app installed and logged in
#   - Accessibility permission granted (System Preferences > Privacy > Accessibility)
#
# Notes:
#   - The app name may be "Telegram" or "Telegram Desktop" depending on installation
#   - Uses Cmd+F to search for the bot, then Enter to open the chat
#
# Examples:
#   ./scripts/test-telegram-bot.sh "MyTestBot" "/start"
#   ./scripts/test-telegram-bot.sh "MyTestBot" "Hello bot" 30
#   ./scripts/test-telegram-bot.sh "GPTBot" "/ask What is AI?" 60 /tmp/my-test.png
#
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
BOT="${1:?Usage: test-telegram-bot.sh <bot_or_chat> <message> [wait_seconds] [screenshot_path]}"
MESSAGE="${2:?Usage: test-telegram-bot.sh <bot_or_chat> <message> [wait_seconds] [screenshot_path]}"
WAIT="${3:-10}"
SCREENSHOT="${4:-/tmp/telegram-bot-test.png}"

# Detect app name — "Telegram" or "Telegram Desktop"
APP=""
if osascript -e 'tell application "Telegram" to name' &>/dev/null; then
  APP="Telegram"
elif osascript -e 'tell application "Telegram Desktop" to name' &>/dev/null; then
  APP="Telegram Desktop"
else
  echo "[error] Telegram app not found. Install Telegram or Telegram Desktop."
  exit 1
fi

echo "[$APP] Activating..."
osascript -e "tell application \"$APP\" to activate"
sleep 1

echo "[$APP] Searching for: $BOT"
osascript -e '
tell application "System Events"
    -- Search (Escape first to clear any existing state)
    key code 53  -- Escape
    delay 0.3
    keystroke "f" using command down
    delay 0.8
    keystroke "'"$BOT"'"
    delay 2
    key code 36  -- Enter to select first result
end tell
'
sleep 2

echo "[$APP] Sending message: $MESSAGE"
osascript -e '
set the clipboard to "'"$MESSAGE"'"
tell application "System Events"
    keystroke "v" using command down
    delay 0.3
    key code 36  -- Enter
end tell
'

echo "[$APP] Waiting ${WAIT}s for bot response..."
sleep "$WAIT"

echo "[$APP] Capturing screenshot..."
"$SCRIPT_DIR/capture-app-window.sh" "$APP" "$SCREENSHOT"
echo "[$APP] Done! Screenshot saved to $SCREENSHOT"


================================================
FILE: .agents/skills/local-testing/scripts/test-wechat-bot.sh
================================================
#!/usr/bin/env bash
#
# test-wechat-bot.sh — Send a message to a WeChat bot and capture the response
#
# Usage:
#   ./scripts/test-wechat-bot.sh <contact> <message> [wait_seconds] [screenshot_path]
#
#   contact         — Contact or bot name to search for
#   message         — Message to send
#   wait_seconds    — Seconds to wait for bot response (default: 10)
#   screenshot_path — Output screenshot path (default: /tmp/wechat-bot-test.png)
#
# Prerequisites:
#   - WeChat (微信) desktop app installed and logged in
#   - Accessibility permission granted (System Preferences > Privacy > Accessibility)
#
# Notes:
#   - The app name may be "微信" or "WeChat" depending on system language
#   - WeChat sends on Enter by default; use Shift+Enter for newlines
#   - For Chinese text, always uses clipboard paste (keystroke can't handle CJK)
#
# Examples:
#   ./scripts/test-wechat-bot.sh "TestBot" "Hello"
#   ./scripts/test-wechat-bot.sh "文件传输助手" "test message" 5
#   ./scripts/test-wechat-bot.sh "MyBot" "Tell me a joke" 30 /tmp/my-test.png
#
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
CONTACT="${1:?Usage: test-wechat-bot.sh <contact> <message> [wait_seconds] [screenshot_path]}"
MESSAGE="${2:?Usage: test-wechat-bot.sh <contact> <message> [wait_seconds] [screenshot_path]}"
WAIT="${3:-10}"
SCREENSHOT="${4:-/tmp/wechat-bot-test.png}"

# Detect app name — "微信" or "WeChat"
APP=""
if osascript -e 'tell application "微信" to name' &>/dev/null; then
  APP="微信"
elif osascript -e 'tell application "WeChat" to name' &>/dev/null; then
  APP="WeChat"
else
  echo "[error] WeChat app not found. Install 微信 (WeChat)."
  exit 1
fi

echo "[$APP] Activating..."
osascript -e "tell application \"$APP\" to activate"
sleep 1

echo "[$APP] Searching for contact: $CONTACT"
osascript -e '
tell application "System Events"
    -- Search (Cmd+F)
    keystroke "f" using command down
    delay 0.8
end tell
'
# Use clipboard for contact name (supports CJK characters)
osascript -e '
set the clipboard to "'"$CONTACT"'"
tell application "System Events"
    keystroke "v" using command down
    delay 1.5
    key code 36  -- Enter to select first result
end tell
'
sleep 2

echo "[$APP] Sending message: $MESSAGE"
# Always use clipboard paste — keystroke can't handle CJK or special characters
osascript -e '
set the clipboard to "'"$MESSAGE"'"
tell application "System Events"
    keystroke "v" using command down
    delay 0.3
    key code 36  -- Enter to send
end tell
'

echo "[$APP] Waiting ${WAIT}s for bot response..."
sleep "$WAIT"

echo "[$APP] Capturing screenshot..."
"$SCRIPT_DIR/capture-app-window.sh" "$APP" "$SCREENSHOT"
echo "[$APP] Done! Screenshot saved to $SCREENSHOT"


================================================
FILE: .agents/skills/microcopy/SKILL.md
================================================
---
name: microcopy
description: UI copy and microcopy guidelines. Use when writing UI text, buttons, error messages, empty states, onboarding, or any user-facing copy. Triggers on i18n translation, UI text writing, or copy improvement tasks. Supports both Chinese and English.
---

# LobeHub UI Microcopy Guidelines

Brand: **Where Agents Collaborate** - Focus on collaborative agent system, not just "generation".

## Fixed Terminology

| Chinese    | English       |
| ---------- | ------------- |
| 空间       | Workspace     |
| 助理       | Agent         |
| 群组       | Group         |
| 上下文     | Context       |
| 记忆       | Memory        |
| 连接器     | Integration   |
| 技能       | Skill         |
| 助理档案   | Agent Profile |
| 话题       | Topic         |
| 文稿       | Page          |
| 社区       | Community     |
| 资源       | Resource      |
| 库         | Library       |
| 模型服务商 | Provider      |
| 评测       | Evaluation    |
| 基准       | Benchmark     |
| 数据集     | Dataset       |
| 用例       | Test Case     |

## Brand Principles

1. **Create**: One sentence → usable Agent; clear next step
2. **Collaborate**: Multi-agent; shared Context; controlled
3. **Evolve**: Remember with consent; explainable; replayable

## Writing Rules

1. **Clarity first**: Short sentences, strong verbs, minimal adjectives
2. **Layered**: Main line (simple) + optional detail (precise)
3. **Consistent verbs**: Create / Connect / Run / Pause / Retry / View details
4. **Actionable**: Every message tells next step; avoid generic "OK/Cancel"

## Human Warmth (Balanced)

Default: **80% information, 20% warmth**
Key moments: **70/30** (first-time, empty state, failures, long waits)

**Hard cap**: At most half sentence of warmth, followed by clear next step.

**Order**:

1. Acknowledge situation (no judgment)
2. Restore control (pause/replay/edit/undo/clear Memory)
3. Provide next action

**Avoid**: Preachy encouragement, grand narratives, over-anthropomorphizing

## Patterns

**Getting started**:

- "Starting with one sentence is enough. Describe your goal."
- "Not sure where to begin? Tell me the outcome."

**Long wait**:

- "Running… You can switch tasks—I'll notify you when done."
- "This may take a few minutes. To speed up: reduce Context / switch model."

**Failure**:

- "That didn't run through. Retry, or view details to fix."
- "Connection failed. Re-authorize in Settings, or try again later."

**Collaboration**:

- "Align everyone to the same Context."
- "Different opinions are fine. Write the goal first."

## Errors/Exceptions

Must include:

1. **What happened**
2. (Optional) **Why**
3. **What user can do next**

Provide: Retry / View details / Go to Settings / Contact support / Copy logs

Never blame user. Put error codes in "Details".


================================================
FILE: .agents/skills/microcopy/microcopy-cn.md
================================================
---
globs: src/locales/default/*
alwaysApply: false
---

你是「LobeHub」的中文 UI 文案与微文案(microcopy)专家。LobeHub 是一个助理工作空间:用户可以创建助理与群组,让人和助理、助理和助理协作,提升日常生产与生活效率。产品气质:外表年轻、亲和、现代;内核专业、可靠、强调生产力与可控性。整体风格参考 Notion / Figma / Apple / Discord / OpenAI / Gemini:清晰克制、可信、有人情味但不油腻。

产品 slogan:**For Collaborative Agents**。你的文案要让用户持续感到:LobeHub 的重点不是 “生成”,而是 “协作的助理体系”(可共享上下文、可追踪、可回放、可演进、人在回路)。

---

### 1) 固定术语(必须遵守)

- Workspace:空间
- Agent:助理
- Agent Team:群组
- Context:上下文
- Memory:记忆
- Integration:连接器
- Tool/Skill/Plugin/ 插件 / 工具:技能
- SystemRole: 助理档案
- Topic: 话题
- Page: 文稿
- Community: 社区
- Resource: 资源
- Library: 库
- MCP: MCP
- Provider: 模型服务商

术语规则:同一概念全站只用一种说法,不混用 “Agent / 智能体 / 机器人 / 团队 / 工作区” 等。

---

### 2) 你的任务

- 优化、改写或从零生成任何界面中文文案:标题、按钮、表单说明、占位、引导、空状态、Toast、弹窗、错误、权限、设置项、创建 / 运行流程、协作与群组相关页面等。
- 文案必须同时兼容:普通用户看得懂 + 专业用户不觉得低幼;娱乐与严肃场景都成立;不过度营销、不夸大 AI 能力;在关键节点提供恰到好处的人文关怀。

---

### 3) 品牌三原则(内化到结构与措辞)

- **Create(创建)**:一句话创建助理;从想法到可用;清楚下一步。
- **Collaborate(协作)**:多助理协作;群组对齐信息与产出;共享上下文(可控、可管理)。
- **Evolve(演进)**:助理可在你允许的范围内记住偏好;随你的工作方式变得更顺手;强调可解释、可设置、可回放。

---

### 4) 写作规则(可执行)

1. **清晰优先**:短句、强动词、少形容词;避免口号化与空泛承诺(如 “颠覆”“史诗级”“100%”)。
2. **分层表达(单一版本兼容两类用户)**:
   - 主句:人人可懂、可执行
   - 必要时补充一句副说明:更精确 / 更专业 / 更边界(可放副标题、帮助提示、折叠区)
   - 不输出 “Pro/Lite 两套文案”,而是 “一句主文案 + 可选补充”
3. **术语克制但准确**:能说 “连接 / 运行 / 上下文” 就不要堆砌术语;必须出现专业词时给一句白话解释。
4. **一致性**:同一动作按钮尽量固定动词(创建 / 连接 / 运行 / 暂停 / 重试 / 查看详情 / 清除记忆等)。
5. **可行动**:每条提示都要让用户知道下一步;按钮避免 “确定 / 取消” 泛化,改成更具体的动作。
6. **中文本地化**:符合中文阅读节奏;中英混排规范;避免翻译腔。

---

### 5) 人文关怀(中间态温度:介于克制与陪伴)

目标:在 AI 时代的价值焦虑与创作失格感中,给用户 “被理解 + 有掌控 + 能继续” 的体验,但不写长抒情。

#### 温度比例规则

- 默认:信息为主,温度为辅(约 8:2)
- 关键节点(首次创建、空状态、长等待、失败重试、回退 / 丢失风险、协作分歧):允许提升到 7:3
- 强制上限:任何一条上屏文案里,温度表达不超过**半句或一句**,且必须紧跟明确下一步。

#### 表达顺序(必须遵守)

1. 先承接处境(不评判):如 “没关系 / 先这样也可以 / 卡住很正常”
2. 再给掌控感(人在回路):可暂停 / 可回放 / 可编辑 / 可撤销 / 可清除记忆 / 可查看上下文
3. 最后给下一步(按钮 / 路径明确)

#### 避免

- 鸡汤式说教(如 “别焦虑”“要相信未来”)
- 宏大叙事与文学排比
- 过度拟人(不承诺助理 “理解你 / 有情绪 / 永远记得你”)

#### 核心立场

- 助理很强,但它替代不了你的经历、选择与判断;LobeHub 帮你把时间还给重要的部分。

##### A. 情绪承接(先人后事)

- 允许承认:焦虑、空白、无从下手、被追赶感、
Download .txt
Showing preview only (581K chars total). Download the full file or copy to clipboard to get everything.
gitextract_qs6a0kl7/

├── .agents/
│   └── skills/
│       ├── add-provider-doc/
│       │   └── SKILL.md
│       ├── add-setting-env/
│       │   └── SKILL.md
│       ├── agent-tracing/
│       │   └── SKILL.md
│       ├── chat-sdk/
│       │   └── SKILL.md
│       ├── cli/
│       │   ├── SKILL.md
│       │   └── references/
│       │       ├── agent.md
│       │       ├── conversation.md
│       │       ├── generate.md
│       │       ├── knowledge.md
│       │       ├── memory.md
│       │       ├── models-providers.md
│       │       ├── search-config.md
│       │       └── skills-plugins.md
│       ├── code-review/
│       │   └── SKILL.md
│       ├── data-fetching/
│       │   └── SKILL.md
│       ├── db-migrations/
│       │   └── SKILL.md
│       ├── debug/
│       │   └── SKILL.md
│       ├── desktop/
│       │   ├── SKILL.md
│       │   └── references/
│       │       ├── feature-implementation.md
│       │       ├── local-tools.md
│       │       ├── menu-config.md
│       │       └── window-management.md
│       ├── drizzle/
│       │   └── SKILL.md
│       ├── hotkey/
│       │   └── SKILL.md
│       ├── i18n/
│       │   └── SKILL.md
│       ├── linear/
│       │   └── SKILL.md
│       ├── local-testing/
│       │   ├── SKILL.md
│       │   └── scripts/
│       │       ├── capture-app-window.sh
│       │       ├── record-electron-demo.sh
│       │       ├── test-discord-bot.sh
│       │       ├── test-lark-bot.sh
│       │       ├── test-qq-bot.sh
│       │       ├── test-slack-bot.sh
│       │       ├── test-telegram-bot.sh
│       │       └── test-wechat-bot.sh
│       ├── microcopy/
│       │   ├── SKILL.md
│       │   ├── microcopy-cn.md
│       │   └── microcopy-en.md
│       ├── modal/
│       │   └── SKILL.md
│       ├── pr/
│       │   └── SKILL.md
│       ├── project-overview/
│       │   └── SKILL.md
│       ├── react/
│       │   ├── SKILL.md
│       │   └── references/
│       │       └── layout-kit.md
│       ├── recent-data/
│       │   └── SKILL.md
│       ├── response-compliance/
│       │   └── SKILL.md
│       ├── spa-routes/
│       │   └── SKILL.md
│       ├── store-data-structures/
│       │   └── SKILL.md
│       ├── testing/
│       │   ├── SKILL.md
│       │   └── references/
│       │       ├── agent-runtime-e2e.md
│       │       ├── db-model-test.md
│       │       ├── desktop-controller-test.md
│       │       ├── electron-ipc-test.md
│       │       └── zustand-store-action-test.md
│       ├── trpc-router/
│       │   └── SKILL.md
│       ├── typescript/
│       │   └── SKILL.md
│       ├── upstash-workflow/
│       │   ├── SKILL.md
│       │   └── reference/
│       │       └── cloud.md
│       ├── version-release/
│       │   ├── SKILL.md
│       │   └── reference/
│       │       ├── changelog-example/
│       │       │   ├── db-migration.md
│       │       │   └── weekly-release.md
│       │       └── patch-release-scenarios.md
│       └── zustand/
│           ├── SKILL.md
│           └── references/
│               ├── action-patterns.md
│               └── slice-organization.md
├── .bunfig.toml
├── .changelogrc.cjs
├── .conductor/
│   └── setup.sh
├── .console-log-whitelist.json
├── .cursor/
│   └── docs/
│       └── createStaticStyles_migration_guide.md
├── .cursorindexingignore
├── .devcontainer/
│   └── devcontainer.json
├── .editorconfig
├── .gitattributes
├── .github/
│   ├── CODEOWNERS
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── 1_bug_report.yml
│   │   ├── 2_feature_request.yml
│   │   └── config.yml
│   ├── PULL_REQUEST_TEMPLATE.md
│   ├── actions/
│   │   ├── desktop-build-setup/
│   │   │   └── action.yml
│   │   ├── desktop-cleanup-s3/
│   │   │   └── action.yml
│   │   ├── desktop-publish-s3/
│   │   │   └── action.yml
│   │   ├── desktop-upload-artifacts/
│   │   │   └── action.yml
│   │   ├── setup-env/
│   │   │   └── action.yml
│   │   ├── setup-node-bun/
│   │   │   └── action.yml
│   │   └── setup-node-pnpm/
│   │       └── action.yml
│   ├── scripts/
│   │   ├── auto-close-duplicates.ts
│   │   ├── create-failure-issue.js
│   │   ├── docker-pr-comment.js
│   │   ├── lock-closed-issues.js
│   │   ├── pr-comment.js
│   │   └── pr-release-body.js
│   └── workflows/
│       ├── auto-i18n.yml
│       ├── auto-tag-release.yml
│       ├── bundle-analyzer.yml
│       ├── claude-auto-e2e-testing.yml
│       ├── claude-auto-testing.yml
│       ├── claude-dedupe-issues.yml
│       ├── claude-issue-triage.yml
│       ├── claude-migration-support.yml
│       ├── claude-pr-assign.yml
│       ├── claude-translate-comments.yml
│       ├── claude-translator.yml
│       ├── claude.yml
│       ├── e2e.yml
│       ├── issue-auto-close-duplicates.yml
│       ├── issue-auto-comments.yml
│       ├── issue-close-require.yml
│       ├── lighthouse.yml
│       ├── lock-closed-issues.yml
│       ├── manual-build-desktop.yml
│       ├── pr-build-desktop.yml
│       ├── pr-build-docker.yml
│       ├── release-desktop-beta.yml
│       ├── release-desktop-canary.yml
│       ├── release-desktop-nightly.yml
│       ├── release-desktop-stable.yml
│       ├── release-docker.yml
│       ├── release.yml
│       ├── revalidate-docs.yml
│       ├── sync-database-schema.yml
│       ├── sync-main-to-canary.yaml
│       ├── sync.yml
│       └── test.yml
├── .gitignore
├── .husky/
│   └── pre-commit
├── .i18nrc.js
├── .npmrc
├── .nvmrc
├── .prettierignore
├── .releaserc.cjs
├── .remarkrc.mdx.mjs
├── .remarkrc.mjs
├── .seorc.cjs
├── .stylelintignore
├── .vscode/
│   ├── extensions.json
│   └── settings.json
├── AGENTS.md
├── CHANGELOG.md
├── CLAUDE.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Dockerfile
├── GEMINI.md
├── LICENSE
├── README.md
├── README.zh-CN.md
├── __mocks__/
│   └── zustand/
│       └── traditional.ts
├── apps/
│   ├── cli/
│   │   ├── .npmrc
│   │   ├── README.md
│   │   ├── e2e/
│   │   │   ├── agent.e2e.test.ts
│   │   │   ├── doc.e2e.test.ts
│   │   │   ├── file.e2e.test.ts
│   │   │   ├── generate.e2e.test.ts
│   │   │   ├── kb.e2e.test.ts
│   │   │   ├── memory.e2e.test.ts
│   │   │   ├── message.e2e.test.ts
│   │   │   ├── model.e2e.test.ts
│   │   │   ├── plugin.e2e.test.ts
│   │   │   ├── provider.e2e.test.ts
│   │   │   ├── search.e2e.test.ts
│   │   │   ├── skill.e2e.test.ts
│   │   │   └── topic.e2e.test.ts
│   │   ├── man/
│   │   │   └── man1/
│   │   │       ├── lh.1
│   │   │       ├── lobe.1
│   │   │       └── lobehub.1
│   │   ├── package.json
│   │   ├── pnpm-workspace.yaml
│   │   ├── src/
│   │   │   ├── api/
│   │   │   │   ├── client.ts
│   │   │   │   └── http.ts
│   │   │   ├── auth/
│   │   │   │   ├── apiKey.ts
│   │   │   │   ├── credentials.test.ts
│   │   │   │   ├── credentials.ts
│   │   │   │   ├── refresh.test.ts
│   │   │   │   ├── refresh.ts
│   │   │   │   ├── resolveToken.test.ts
│   │   │   │   └── resolveToken.ts
│   │   │   ├── commands/
│   │   │   │   ├── agent-group.test.ts
│   │   │   │   ├── agent-group.ts
│   │   │   │   ├── agent.test.ts
│   │   │   │   ├── agent.ts
│   │   │   │   ├── bot.test.ts
│   │   │   │   ├── bot.ts
│   │   │   │   ├── botMessage.ts
│   │   │   │   ├── brief.ts
│   │   │   │   ├── completion.test.ts
│   │   │   │   ├── completion.ts
│   │   │   │   ├── config.test.ts
│   │   │   │   ├── config.ts
│   │   │   │   ├── connect.test.ts
│   │   │   │   ├── connect.ts
│   │   │   │   ├── cron.test.ts
│   │   │   │   ├── cron.ts
│   │   │   │   ├── device.ts
│   │   │   │   ├── doc.test.ts
│   │   │   │   ├── doc.ts
│   │   │   │   ├── eval.test.ts
│   │   │   │   ├── eval.ts
│   │   │   │   ├── file.test.ts
│   │   │   │   ├── file.ts
│   │   │   │   ├── generate/
│   │   │   │   │   ├── asr.ts
│   │   │   │   │   ├── image.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── text.ts
│   │   │   │   │   ├── tts.ts
│   │   │   │   │   └── video.ts
│   │   │   │   ├── generate.test.ts
│   │   │   │   ├── kb.test.ts
│   │   │   │   ├── kb.ts
│   │   │   │   ├── login.test.ts
│   │   │   │   ├── login.ts
│   │   │   │   ├── logout.test.ts
│   │   │   │   ├── logout.ts
│   │   │   │   ├── man.test.ts
│   │   │   │   ├── man.ts
│   │   │   │   ├── memory.test.ts
│   │   │   │   ├── memory.ts
│   │   │   │   ├── message.test.ts
│   │   │   │   ├── message.ts
│   │   │   │   ├── model.test.ts
│   │   │   │   ├── model.ts
│   │   │   │   ├── plugin.test.ts
│   │   │   │   ├── plugin.ts
│   │   │   │   ├── provider.test.ts
│   │   │   │   ├── provider.ts
│   │   │   │   ├── search.test.ts
│   │   │   │   ├── search.ts
│   │   │   │   ├── session-group.test.ts
│   │   │   │   ├── session-group.ts
│   │   │   │   ├── skill.test.ts
│   │   │   │   ├── skill.ts
│   │   │   │   ├── status.test.ts
│   │   │   │   ├── status.ts
│   │   │   │   ├── task/
│   │   │   │   │   ├── checkpoint.ts
│   │   │   │   │   ├── dep.ts
│   │   │   │   │   ├── doc.ts
│   │   │   │   │   ├── helpers.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── lifecycle.ts
│   │   │   │   │   ├── review.ts
│   │   │   │   │   └── topic.ts
│   │   │   │   ├── thread.test.ts
│   │   │   │   ├── thread.ts
│   │   │   │   ├── topic.test.ts
│   │   │   │   ├── topic.ts
│   │   │   │   ├── user.test.ts
│   │   │   │   └── user.ts
│   │   │   ├── constants/
│   │   │   │   ├── auth.ts
│   │   │   │   └── urls.ts
│   │   │   ├── daemon/
│   │   │   │   ├── manager.test.ts
│   │   │   │   └── manager.ts
│   │   │   ├── index.ts
│   │   │   ├── man/
│   │   │   │   ├── generate.ts
│   │   │   │   ├── roff.test.ts
│   │   │   │   └── roff.ts
│   │   │   ├── program.ts
│   │   │   ├── settings/
│   │   │   │   ├── index.test.ts
│   │   │   │   └── index.ts
│   │   │   ├── tools/
│   │   │   │   ├── file.test.ts
│   │   │   │   ├── file.ts
│   │   │   │   ├── index.test.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── shell.test.ts
│   │   │   │   └── shell.ts
│   │   │   └── utils/
│   │   │       ├── __snapshots__/
│   │   │       │   └── format.test.ts.snap
│   │   │       ├── agentStream.test.ts
│   │   │       ├── agentStream.ts
│   │   │       ├── completion.ts
│   │   │       ├── format.test.ts
│   │   │       ├── format.ts
│   │   │       ├── logger.test.ts
│   │   │       └── logger.ts
│   │   ├── tsconfig.json
│   │   ├── tsdown.config.ts
│   │   └── vitest.config.mts
│   ├── desktop/
│   │   ├── .gitignore
│   │   ├── .i18nrc.js
│   │   ├── .npmrc
│   │   ├── .prettierignore
│   │   ├── .remarkrc.mjs
│   │   ├── .stylelintignore
│   │   ├── Development.md
│   │   ├── README.md
│   │   ├── README.zh-CN.md
│   │   ├── build/
│   │   │   ├── Icon-beta.Assets.car
│   │   │   ├── Icon-beta.icns
│   │   │   ├── Icon-dev.Assets.car
│   │   │   ├── Icon-nightly.Assets.car
│   │   │   ├── Icon-nightly.icns
│   │   │   ├── Icon.Assets.car
│   │   │   ├── Icon.icns
│   │   │   └── entitlements.mac.plist
│   │   ├── dev-app-update.yml
│   │   ├── electron-builder.mjs
│   │   ├── electron.vite.config.ts
│   │   ├── index.html
│   │   ├── native-deps.config.mjs
│   │   ├── package.json
│   │   ├── pnpm-workspace.yaml
│   │   ├── prettier.config.mjs
│   │   ├── resources/
│   │   │   ├── error.html
│   │   │   ├── locales/
│   │   │   │   ├── ar/
│   │   │   │   │   ├── common.json
│   │   │   │   │   ├── dialog.json
│   │   │   │   │   └── menu.json
│   │   │   │   ├── bg-BG/
│   │   │   │   │   ├── common.json
│   │   │   │   │   ├── dialog.json
│   │   │   │   │   └── menu.json
│   │   │   │   ├── de-DE/
│   │   │   │   │   ├── common.json
│   │   │   │   │   ├── dialog.json
│   │   │   │   │   └── menu.json
│   │   │   │   ├── en/
│   │   │   │   │   ├── common.json
│   │   │   │   │   ├── dialog.json
│   │   │   │   │   └── menu.json
│   │   │   │   ├── es-ES/
│   │   │   │   │   ├── common.json
│   │   │   │   │   ├── dialog.json
│   │   │   │   │   └── menu.json
│   │   │   │   ├── fa-IR/
│   │   │   │   │   ├── common.json
│   │   │   │   │   ├── dialog.json
│   │   │   │   │   └── menu.json
│   │   │   │   ├── fr-FR/
│   │   │   │   │   ├── common.json
│   │   │   │   │   ├── dialog.json
│   │   │   │   │   └── menu.json
│   │   │   │   ├── it-IT/
│   │   │   │   │   ├── common.json
│   │   │   │   │   ├── dialog.json
│   │   │   │   │   └── menu.json
│   │   │   │   ├── ja-JP/
│   │   │   │   │   ├── common.json
│   │   │   │   │   ├── dialog.json
│   │   │   │   │   └── menu.json
│   │   │   │   ├── ko-KR/
│   │   │   │   │   ├── common.json
│   │   │   │   │   ├── dialog.json
│   │   │   │   │   └── menu.json
│   │   │   │   ├── nl-NL/
│   │   │   │   │   ├── common.json
│   │   │   │   │   ├── dialog.json
│   │   │   │   │   └── menu.json
│   │   │   │   ├── pl-PL/
│   │   │   │   │   ├── common.json
│   │   │   │   │   ├── dialog.json
│   │   │   │   │   └── menu.json
│   │   │   │   ├── pt-BR/
│   │   │   │   │   ├── common.json
│   │   │   │   │   ├── dialog.json
│   │   │   │   │   └── menu.json
│   │   │   │   ├── ru-RU/
│   │   │   │   │   ├── common.json
│   │   │   │   │   ├── dialog.json
│   │   │   │   │   └── menu.json
│   │   │   │   ├── tr-TR/
│   │   │   │   │   ├── common.json
│   │   │   │   │   ├── dialog.json
│   │   │   │   │   └── menu.json
│   │   │   │   ├── vi-VN/
│   │   │   │   │   ├── common.json
│   │   │   │   │   ├── dialog.json
│   │   │   │   │   └── menu.json
│   │   │   │   ├── zh-CN/
│   │   │   │   │   ├── common.json
│   │   │   │   │   ├── dialog.json
│   │   │   │   │   └── menu.json
│   │   │   │   └── zh-TW/
│   │   │   │       ├── common.json
│   │   │   │       ├── dialog.json
│   │   │   │       └── menu.json
│   │   │   └── splash.html
│   │   ├── scripts/
│   │   │   ├── download-agent-browser.mjs
│   │   │   ├── i18nWorkflow/
│   │   │   │   ├── const.ts
│   │   │   │   ├── genDefaultLocale.ts
│   │   │   │   ├── genDiff.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── utils.ts
│   │   │   └── update-test/
│   │   │       ├── .gitignore
│   │   │       ├── README.md
│   │   │       ├── dev-app-update.local.yml
│   │   │       ├── generate-manifest.sh
│   │   │       ├── run-test.sh
│   │   │       ├── setup.sh
│   │   │       ├── start-server.sh
│   │   │       └── stop-server.sh
│   │   ├── src/
│   │   │   ├── common/
│   │   │   │   └── routes.ts
│   │   │   ├── main/
│   │   │   │   ├── __mocks__/
│   │   │   │   │   ├── node-mac-permissions.ts
│   │   │   │   │   └── setup.ts
│   │   │   │   ├── appBrowsers.ts
│   │   │   │   ├── const/
│   │   │   │   │   ├── dir.ts
│   │   │   │   │   ├── env.ts
│   │   │   │   │   ├── protocol.ts
│   │   │   │   │   ├── store.ts
│   │   │   │   │   └── theme.ts
│   │   │   │   ├── controllers/
│   │   │   │   │   ├── AuthCtr.ts
│   │   │   │   │   ├── BrowserWindowsCtr.ts
│   │   │   │   │   ├── DevtoolsCtr.ts
│   │   │   │   │   ├── GatewayConnectionCtr.ts
│   │   │   │   │   ├── LocalFileCtr.ts
│   │   │   │   │   ├── McpCtr.ts
│   │   │   │   │   ├── McpInstallCtr.ts
│   │   │   │   │   ├── MenuCtr.ts
│   │   │   │   │   ├── NetworkProxyCtr.ts
│   │   │   │   │   ├── NotificationCtr.ts
│   │   │   │   │   ├── RemoteServerConfigCtr.ts
│   │   │   │   │   ├── RemoteServerSyncCtr.ts
│   │   │   │   │   ├── ShellCommandCtr.ts
│   │   │   │   │   ├── ShortcutCtr.ts
│   │   │   │   │   ├── SystemCtr.ts
│   │   │   │   │   ├── ToolDetectorCtr.ts
│   │   │   │   │   ├── TrayMenuCtr.ts
│   │   │   │   │   ├── UpdaterCtr.ts
│   │   │   │   │   ├── UploadFileCtr.ts
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   ├── AuthCtr.test.ts
│   │   │   │   │   │   ├── BrowserWindowsCtr.test.ts
│   │   │   │   │   │   ├── DevtoolsCtr.test.ts
│   │   │   │   │   │   ├── GatewayConnectionCtr.test.ts
│   │   │   │   │   │   ├── LocalFileCtr.test.ts
│   │   │   │   │   │   ├── McpInstallCtr.test.ts
│   │   │   │   │   │   ├── MenuCtr.test.ts
│   │   │   │   │   │   ├── NetworkProxyCtr.test.ts
│   │   │   │   │   │   ├── NotificationCtr.test.ts
│   │   │   │   │   │   ├── RemoteServerConfigCtr.test.ts
│   │   │   │   │   │   ├── ShellCommandCtr.test.ts
│   │   │   │   │   │   ├── ShortcutCtr.test.ts
│   │   │   │   │   │   ├── SystemCtr.test.ts
│   │   │   │   │   │   ├── TrayMenuCtr.test.ts
│   │   │   │   │   │   ├── UpdaterCtr.test.ts
│   │   │   │   │   │   └── UploadFileCtr.test.ts
│   │   │   │   │   ├── _template.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── registry.ts
│   │   │   │   ├── core/
│   │   │   │   │   ├── App.ts
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   └── App.test.ts
│   │   │   │   │   ├── browser/
│   │   │   │   │   │   ├── Browser.ts
│   │   │   │   │   │   ├── BrowserManager.ts
│   │   │   │   │   │   ├── WindowStateManager.ts
│   │   │   │   │   │   ├── WindowThemeManager.ts
│   │   │   │   │   │   └── __tests__/
│   │   │   │   │   │       ├── Browser.test.ts
│   │   │   │   │   │       ├── BrowserManager.test.ts
│   │   │   │   │   │       ├── WindowStateManager.test.ts
│   │   │   │   │   │       └── WindowThemeManager.test.ts
│   │   │   │   │   ├── infrastructure/
│   │   │   │   │   │   ├── BackendProxyProtocolManager.ts
│   │   │   │   │   │   ├── I18nManager.ts
│   │   │   │   │   │   ├── IoCContainer.ts
│   │   │   │   │   │   ├── ProtocolManager.ts
│   │   │   │   │   │   ├── RendererProtocolManager.ts
│   │   │   │   │   │   ├── RendererUrlManager.ts
│   │   │   │   │   │   ├── StaticFileServerManager.ts
│   │   │   │   │   │   ├── StoreManager.ts
│   │   │   │   │   │   ├── ToolDetectorManager.ts
│   │   │   │   │   │   ├── UpdaterManager.ts
│   │   │   │   │   │   └── __tests__/
│   │   │   │   │   │       ├── BackendProxyProtocolManager.test.ts
│   │   │   │   │   │       ├── I18nManager.test.ts
│   │   │   │   │   │       ├── IoCContainer.test.ts
│   │   │   │   │   │       ├── ProtocolManager.test.ts
│   │   │   │   │   │       ├── RendererProtocolManager.test.ts
│   │   │   │   │   │       ├── RendererUrlManager.test.ts
│   │   │   │   │   │       ├── StaticFileServerManager.test.ts
│   │   │   │   │   │       ├── StoreManager.test.ts
│   │   │   │   │   │       └── UpdaterManager.test.ts
│   │   │   │   │   └── ui/
│   │   │   │   │       ├── MenuManager.ts
│   │   │   │   │       ├── ShortcutManager.ts
│   │   │   │   │       ├── Tray.ts
│   │   │   │   │       ├── TrayManager.ts
│   │   │   │   │       └── __tests__/
│   │   │   │   │           ├── MenuManager.test.ts
│   │   │   │   │           ├── ShortcutManager.test.ts
│   │   │   │   │           ├── Tray.test.ts
│   │   │   │   │           └── TrayManager.test.ts
│   │   │   │   ├── env.ts
│   │   │   │   ├── exports.d.ts
│   │   │   │   ├── exports.ts
│   │   │   │   ├── global.d.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── libs/
│   │   │   │   │   └── mcp/
│   │   │   │   │       ├── client.ts
│   │   │   │   │       └── types.ts
│   │   │   │   ├── locales/
│   │   │   │   │   ├── default/
│   │   │   │   │   │   ├── common.ts
│   │   │   │   │   │   ├── dialog.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── menu.ts
│   │   │   │   │   └── resources.ts
│   │   │   │   ├── menus/
│   │   │   │   │   ├── impls/
│   │   │   │   │   │   ├── BaseMenuPlatform.test.ts
│   │   │   │   │   │   ├── BaseMenuPlatform.ts
│   │   │   │   │   │   ├── linux.test.ts
│   │   │   │   │   │   ├── linux.ts
│   │   │   │   │   │   ├── macOS.test.ts
│   │   │   │   │   │   ├── macOS.ts
│   │   │   │   │   │   ├── windows.test.ts
│   │   │   │   │   │   └── windows.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── types.ts
│   │   │   │   ├── modules/
│   │   │   │   │   ├── contentSearch/
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   ├── base.test.ts
│   │   │   │   │   │   │   └── index.test.ts
│   │   │   │   │   │   ├── base.ts
│   │   │   │   │   │   ├── impl/
│   │   │   │   │   │   │   ├── linux.ts
│   │   │   │   │   │   │   ├── macOS.ts
│   │   │   │   │   │   │   ├── unix.ts
│   │   │   │   │   │   │   └── windows.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── fileSearch/
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   ├── base.test.ts
│   │   │   │   │   │   │   ├── index.test.ts
│   │   │   │   │   │   │   └── macOS.integration.test.ts
│   │   │   │   │   │   ├── base.ts
│   │   │   │   │   │   ├── impl/
│   │   │   │   │   │   │   ├── linux.ts
│   │   │   │   │   │   │   ├── macOS.ts
│   │   │   │   │   │   │   ├── unix.ts
│   │   │   │   │   │   │   └── windows.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── types.ts
│   │   │   │   │   ├── networkProxy/
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   ├── dispatcher.test.ts
│   │   │   │   │   │   │   ├── tester.test.ts
│   │   │   │   │   │   │   ├── urlBuilder.test.ts
│   │   │   │   │   │   │   └── validator.test.ts
│   │   │   │   │   │   ├── dispatcher.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── tester.ts
│   │   │   │   │   │   ├── urlBuilder.ts
│   │   │   │   │   │   └── validator.ts
│   │   │   │   │   ├── toolDetectors/
│   │   │   │   │   │   ├── agentBrowserDetectors.ts
│   │   │   │   │   │   ├── contentSearchDetectors.ts
│   │   │   │   │   │   ├── fileSearchDetectors.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── runtimeEnvironmentDetectors.ts
│   │   │   │   │   └── updater/
│   │   │   │   │       ├── configs.ts
│   │   │   │   │       └── utils.ts
│   │   │   │   ├── package.json
│   │   │   │   ├── services/
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   ├── fileSearchSrv.test.ts
│   │   │   │   │   │   └── fileSrv.test.ts
│   │   │   │   │   ├── contentSearchSrv.ts
│   │   │   │   │   ├── fileSearchSrv.ts
│   │   │   │   │   ├── fileSrv.ts
│   │   │   │   │   ├── gatewayConnectionSrv.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── shortcuts/
│   │   │   │   │   ├── config.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── types/
│   │   │   │   │   ├── protocol.ts
│   │   │   │   │   └── store.ts
│   │   │   │   └── utils/
│   │   │   │       ├── __tests__/
│   │   │   │       │   ├── file-system.test.ts
│   │   │   │       │   ├── http-headers.test.ts
│   │   │   │       │   ├── logger.test.ts
│   │   │   │       │   └── protocol.test.ts
│   │   │   │       ├── file-system.ts
│   │   │   │       ├── http-headers.ts
│   │   │   │       ├── ipc/
│   │   │   │       │   ├── __tests__/
│   │   │   │       │   │   └── base.test.ts
│   │   │   │       │   ├── base.ts
│   │   │   │       │   ├── index.ts
│   │   │   │       │   └── utility.ts
│   │   │   │       ├── logger.ts
│   │   │   │       ├── mime.ts
│   │   │   │       ├── path.ts
│   │   │   │       ├── permissions.ts
│   │   │   │       └── protocol.ts
│   │   │   └── preload/
│   │   │       ├── electronApi.test.ts
│   │   │       ├── electronApi.ts
│   │   │       ├── index.ts
│   │   │       ├── invoke.test.ts
│   │   │       ├── invoke.ts
│   │   │       ├── routeInterceptor.test.ts
│   │   │       ├── routeInterceptor.ts
│   │   │       ├── streamer.test.ts
│   │   │       └── streamer.ts
│   │   ├── stylelint.config.mjs
│   │   ├── tsconfig.json
│   │   └── vitest.config.mts
│   └── device-gateway/
│       ├── package.json
│       ├── scripts/
│       │   └── extract-public-key.mjs
│       ├── src/
│       │   ├── DeviceGatewayDO.ts
│       │   ├── auth.test.ts
│       │   ├── auth.ts
│       │   ├── index.ts
│       │   └── types.ts
│       ├── tsconfig.json
│       └── wrangler.toml
├── changelog/
│   ├── CHANGELOG.v0.md
│   ├── CHANGELOG.v1.md
│   ├── v0.json
│   ├── v1.json
│   └── v2.json
├── codecov.yml
├── commitlint.config.mjs
├── conductor.json
├── docker-compose/
│   ├── deploy/
│   │   ├── bucket.config.json
│   │   ├── docker-compose.yml
│   │   └── searxng-settings.yml
│   ├── dev/
│   │   ├── .gitignore
│   │   ├── bucket.config.json
│   │   ├── docker-compose.yml
│   │   └── searxng-settings.yml
│   ├── production/
│   │   └── grafana/
│   │       ├── docker-compose.yml
│   │       ├── grafana/
│   │       │   ├── dashboards/
│   │       │   │   └── .gitkeep
│   │       │   └── datasources/
│   │       │       ├── datasource-prometheus.yaml
│   │       │       └── datasource-tempo.yaml
│   │       ├── init_data.json
│   │       ├── otel-collector/
│   │       │   └── collector-config.yaml
│   │       ├── prometheus/
│   │       │   └── prometheus.yml
│   │       ├── searxng-settings.yml
│   │       └── tempo/
│   │           └── tempo.yaml
│   └── setup.sh
├── docs/
│   ├── .cdn.cache.json
│   ├── changelog/
│   │   ├── 2023-09-09-plugin-system.mdx
│   │   ├── 2023-09-09-plugin-system.zh-CN.mdx
│   │   ├── 2023-11-14-gpt4-vision.mdx
│   │   ├── 2023-11-14-gpt4-vision.zh-CN.mdx
│   │   ├── 2023-11-19-tts-stt.mdx
│   │   ├── 2023-11-19-tts-stt.zh-CN.mdx
│   │   ├── 2023-12-22-dalle-3.mdx
│   │   ├── 2023-12-22-dalle-3.zh-CN.mdx
│   │   ├── 2024-02-08-sso-oauth.mdx
│   │   ├── 2024-02-08-sso-oauth.zh-CN.mdx
│   │   ├── 2024-02-14-ollama.mdx
│   │   ├── 2024-02-14-ollama.zh-CN.mdx
│   │   ├── 2024-06-19-lobe-chat-v1.mdx
│   │   ├── 2024-06-19-lobe-chat-v1.zh-CN.mdx
│   │   ├── 2024-07-19-gpt-4o-mini.mdx
│   │   ├── 2024-07-19-gpt-4o-mini.zh-CN.mdx
│   │   ├── 2024-08-02-lobe-chat-database-docker.mdx
│   │   ├── 2024-08-02-lobe-chat-database-docker.zh-CN.mdx
│   │   ├── 2024-08-21-file-upload-and-knowledge-base.mdx
│   │   ├── 2024-08-21-file-upload-and-knowledge-base.zh-CN.mdx
│   │   ├── 2024-09-13-openai-o1-models.mdx
│   │   ├── 2024-09-13-openai-o1-models.zh-CN.mdx
│   │   ├── 2024-09-20-artifacts.mdx
│   │   ├── 2024-09-20-artifacts.zh-CN.mdx
│   │   ├── 2024-10-27-pin-assistant.mdx
│   │   ├── 2024-10-27-pin-assistant.zh-CN.mdx
│   │   ├── 2024-11-06-share-text-json.mdx
│   │   ├── 2024-11-06-share-text-json.zh-CN.mdx
│   │   ├── 2024-11-25-november-providers.mdx
│   │   ├── 2024-11-25-november-providers.zh-CN.mdx
│   │   ├── 2024-11-27-forkable-chat.mdx
│   │   ├── 2024-11-27-forkable-chat.zh-CN.mdx
│   │   ├── 2025-01-03-user-profile.mdx
│   │   ├── 2025-01-03-user-profile.zh-CN.mdx
│   │   ├── 2025-01-22-new-ai-provider.mdx
│   │   ├── 2025-01-22-new-ai-provider.zh-CN.mdx
│   │   ├── 2025-02-02-deepseek-r1.mdx
│   │   ├── 2025-02-02-deepseek-r1.zh-CN.mdx
│   │   ├── 2025-03-02-new-models.mdx
│   │   ├── 2025-03-02-new-models.zh-CN.mdx
│   │   ├── 2025-04-06-exports.mdx
│   │   ├── 2025-04-06-exports.zh-CN.mdx
│   │   ├── 2025-05-08-desktop-app.mdx
│   │   ├── 2025-05-08-desktop-app.zh-CN.mdx
│   │   ├── 2025-06-08-claude-4.mdx
│   │   ├── 2025-06-08-claude-4.zh-CN.mdx
│   │   ├── 2025-07-08-mcp-market.mdx
│   │   ├── 2025-07-08-mcp-market.zh-CN.mdx
│   │   ├── 2025-08-08-image-generation.mdx
│   │   ├── 2025-08-08-image-generation.zh-CN.mdx
│   │   ├── 2025-09-08-gemini.mdx
│   │   ├── 2025-09-08-gemini.zh-CN.mdx
│   │   ├── 2025-10-08-python.mdx
│   │   ├── 2025-10-08-python.zh-CN.mdx
│   │   ├── 2025-11-08-comfy-ui.mdx
│   │   ├── 2025-11-08-comfy-ui.zh-CN.mdx
│   │   ├── 2025-12-20-mcp.mdx
│   │   ├── 2025-12-20-mcp.zh-CN.mdx
│   │   ├── 2026-01-27-v2.mdx
│   │   ├── 2026-01-27-v2.zh-CN.mdx
│   │   ├── 2026-02-08-runtime-auth.mdx
│   │   ├── 2026-02-08-runtime-auth.zh-CN.mdx
│   │   ├── 2026-03-16-search.mdx
│   │   ├── 2026-03-16-search.zh-CN.mdx
│   │   ├── 2026-03-23-media-memory.mdx
│   │   ├── 2026-03-23-media-memory.zh-CN.mdx
│   │   ├── 2026-03-30-agent-tasks.mdx
│   │   ├── 2026-03-30-agent-tasks.zh-CN.mdx
│   │   ├── index.json
│   │   └── schema.json
│   ├── development/
│   │   ├── basic/
│   │   │   ├── add-new-authentication-providers.mdx
│   │   │   ├── add-new-authentication-providers.zh-CN.mdx
│   │   │   ├── add-new-bot-platform.mdx
│   │   │   ├── add-new-bot-platform.zh-CN.mdx
│   │   │   ├── add-new-image-model.mdx
│   │   │   ├── add-new-image-model.zh-CN.mdx
│   │   │   ├── architecture.mdx
│   │   │   ├── architecture.zh-CN.mdx
│   │   │   ├── chat-api.mdx
│   │   │   ├── chat-api.zh-CN.mdx
│   │   │   ├── comfyui-development.mdx
│   │   │   ├── comfyui-development.zh-CN.mdx
│   │   │   ├── contributing-guidelines.mdx
│   │   │   ├── contributing-guidelines.zh-CN.mdx
│   │   │   ├── feature-development.mdx
│   │   │   ├── feature-development.zh-CN.mdx
│   │   │   ├── folder-structure.mdx
│   │   │   ├── folder-structure.zh-CN.mdx
│   │   │   ├── resources.mdx
│   │   │   ├── resources.zh-CN.mdx
│   │   │   ├── setup-development.mdx
│   │   │   ├── setup-development.zh-CN.mdx
│   │   │   ├── test.mdx
│   │   │   └── test.zh-CN.mdx
│   │   ├── database-schema.dbml
│   │   ├── internationalization/
│   │   │   ├── add-new-locale.mdx
│   │   │   ├── add-new-locale.zh-CN.mdx
│   │   │   ├── internationalization-implementation.mdx
│   │   │   └── internationalization-implementation.zh-CN.mdx
│   │   ├── others/
│   │   │   ├── lighthouse.mdx
│   │   │   └── lighthouse.zh-CN.mdx
│   │   ├── start.mdx
│   │   ├── start.zh-CN.mdx
│   │   ├── state-management/
│   │   │   ├── state-management-intro.mdx
│   │   │   ├── state-management-intro.zh-CN.mdx
│   │   │   ├── state-management-selectors.mdx
│   │   │   └── state-management-selectors.zh-CN.mdx
│   │   └── tests/
│   │       ├── integration-testing.mdx
│   │       └── integration-testing.zh-CN.mdx
│   ├── glossary.md
│   ├── glossary.zh-CN.md
│   ├── self-hosting/
│   │   ├── advanced/
│   │   │   ├── analytics.mdx
│   │   │   ├── analytics.zh-CN.mdx
│   │   │   ├── desktop.mdx
│   │   │   ├── desktop.zh-CN.mdx
│   │   │   ├── feature-flags.mdx
│   │   │   ├── feature-flags.zh-CN.mdx
│   │   │   ├── knowledge-base.mdx
│   │   │   ├── knowledge-base.zh-CN.mdx
│   │   │   ├── model-list.mdx
│   │   │   ├── model-list.zh-CN.mdx
│   │   │   ├── observability/
│   │   │   │   ├── grafana.mdx
│   │   │   │   ├── grafana.zh-CN.mdx
│   │   │   │   ├── langfuse.mdx
│   │   │   │   └── langfuse.zh-CN.mdx
│   │   │   ├── online-search.mdx
│   │   │   ├── online-search.zh-CN.mdx
│   │   │   ├── redis/
│   │   │   │   ├── upstash.mdx
│   │   │   │   └── upstash.zh-CN.mdx
│   │   │   ├── redis.mdx
│   │   │   ├── redis.zh-CN.mdx
│   │   │   ├── s3/
│   │   │   │   ├── cloudflare-r2.mdx
│   │   │   │   ├── cloudflare-r2.zh-CN.mdx
│   │   │   │   ├── rustfs.mdx
│   │   │   │   ├── rustfs.zh-CN.mdx
│   │   │   │   ├── tencent-cloud.mdx
│   │   │   │   └── tencent-cloud.zh-CN.mdx
│   │   │   ├── s3.mdx
│   │   │   ├── s3.zh-CN.mdx
│   │   │   ├── settings-url-share.mdx
│   │   │   ├── settings-url-share.zh-CN.mdx
│   │   │   ├── upstream-sync.mdx
│   │   │   └── upstream-sync.zh-CN.mdx
│   │   ├── auth/
│   │   │   ├── clerk.mdx
│   │   │   ├── clerk.zh-CN.mdx
│   │   │   ├── email.mdx
│   │   │   ├── email.zh-CN.mdx
│   │   │   ├── legacy.mdx
│   │   │   ├── legacy.zh-CN.mdx
│   │   │   ├── next-auth/
│   │   │   │   ├── auth0.mdx
│   │   │   │   ├── auth0.zh-CN.mdx
│   │   │   │   ├── authelia.mdx
│   │   │   │   ├── authelia.zh-CN.mdx
│   │   │   │   ├── authentik.mdx
│   │   │   │   ├── authentik.zh-CN.mdx
│   │   │   │   ├── casdoor.mdx
│   │   │   │   ├── casdoor.zh-CN.mdx
│   │   │   │   ├── cloudflare-zero-trust.mdx
│   │   │   │   ├── cloudflare-zero-trust.zh-CN.mdx
│   │   │   │   ├── github.mdx
│   │   │   │   ├── github.zh-CN.mdx
│   │   │   │   ├── google.mdx
│   │   │   │   ├── google.zh-CN.mdx
│   │   │   │   ├── keycloak.mdx
│   │   │   │   ├── keycloak.zh-CN.mdx
│   │   │   │   ├── logto.mdx
│   │   │   │   ├── logto.zh-CN.mdx
│   │   │   │   ├── microsoft-entra-id.mdx
│   │   │   │   ├── microsoft-entra-id.zh-CN.mdx
│   │   │   │   ├── okta.mdx
│   │   │   │   ├── okta.zh-CN.mdx
│   │   │   │   ├── wechat.mdx
│   │   │   │   ├── wechat.zh-CN.mdx
│   │   │   │   ├── zitadel.mdx
│   │   │   │   └── zitadel.zh-CN.mdx
│   │   │   └── providers/
│   │   │       ├── apple.mdx
│   │   │       ├── apple.zh-CN.mdx
│   │   │       ├── auth0.mdx
│   │   │       ├── auth0.zh-CN.mdx
│   │   │       ├── authelia.mdx
│   │   │       ├── authelia.zh-CN.mdx
│   │   │       ├── authentik.mdx
│   │   │       ├── authentik.zh-CN.mdx
│   │   │       ├── casdoor.mdx
│   │   │       ├── casdoor.zh-CN.mdx
│   │   │       ├── cloudflare-zero-trust.mdx
│   │   │       ├── cloudflare-zero-trust.zh-CN.mdx
│   │   │       ├── cognito.mdx
│   │   │       ├── cognito.zh-CN.mdx
│   │   │       ├── feishu.mdx
│   │   │       ├── feishu.zh-CN.mdx
│   │   │       ├── generic-oidc.mdx
│   │   │       ├── generic-oidc.zh-CN.mdx
│   │   │       ├── github.mdx
│   │   │       ├── github.zh-CN.mdx
│   │   │       ├── google.mdx
│   │   │       ├── google.zh-CN.mdx
│   │   │       ├── keycloak.mdx
│   │   │       ├── keycloak.zh-CN.mdx
│   │   │       ├── logto.mdx
│   │   │       ├── logto.zh-CN.mdx
│   │   │       ├── microsoft.mdx
│   │   │       ├── microsoft.zh-CN.mdx
│   │   │       ├── okta.mdx
│   │   │       ├── okta.zh-CN.mdx
│   │   │       ├── password.mdx
│   │   │       ├── password.zh-CN.mdx
│   │   │       ├── wechat.mdx
│   │   │       ├── wechat.zh-CN.mdx
│   │   │       ├── zitadel.mdx
│   │   │       └── zitadel.zh-CN.mdx
│   │   ├── auth.mdx
│   │   ├── auth.zh-CN.mdx
│   │   ├── environment-variables/
│   │   │   ├── analytics.mdx
│   │   │   ├── analytics.zh-CN.mdx
│   │   │   ├── auth.mdx
│   │   │   ├── auth.zh-CN.mdx
│   │   │   ├── basic.mdx
│   │   │   ├── basic.zh-CN.mdx
│   │   │   ├── model-provider.mdx
│   │   │   ├── model-provider.zh-CN.mdx
│   │   │   ├── redis.mdx
│   │   │   ├── redis.zh-CN.mdx
│   │   │   ├── s3.mdx
│   │   │   └── s3.zh-CN.mdx
│   │   ├── environment-variables.mdx
│   │   ├── environment-variables.zh-CN.mdx
│   │   ├── examples/
│   │   │   ├── azure-openai.mdx
│   │   │   ├── azure-openai.zh-CN.mdx
│   │   │   ├── ollama.mdx
│   │   │   └── ollama.zh-CN.mdx
│   │   ├── faq/
│   │   │   ├── no-v1-suffix.mdx
│   │   │   ├── no-v1-suffix.zh-CN.mdx
│   │   │   ├── proxy-with-unable-to-verify-leaf-signature.mdx
│   │   │   ├── proxy-with-unable-to-verify-leaf-signature.zh-CN.mdx
│   │   │   ├── vercel-ai-image-timeout.mdx
│   │   │   └── vercel-ai-image-timeout.zh-CN.mdx
│   │   ├── migration/
│   │   │   └── v2/
│   │   │       ├── auth/
│   │   │       │   ├── clerk-to-betterauth.mdx
│   │   │       │   ├── clerk-to-betterauth.zh-CN.mdx
│   │   │       │   ├── migration-internals.mdx
│   │   │       │   ├── migration-internals.zh-CN.mdx
│   │   │       │   ├── nextauth-to-betterauth.mdx
│   │   │       │   └── nextauth-to-betterauth.zh-CN.mdx
│   │   │       ├── breaking-changes.mdx
│   │   │       └── breaking-changes.zh-CN.mdx
│   │   ├── platform/
│   │   │   ├── docker-compose.mdx
│   │   │   ├── docker-compose.zh-CN.mdx
│   │   │   ├── docker.mdx
│   │   │   ├── docker.zh-CN.mdx
│   │   │   ├── dokploy.mdx
│   │   │   ├── dokploy.zh-CN.mdx
│   │   │   ├── repocloud.mdx
│   │   │   ├── repocloud.zh-CN.mdx
│   │   │   ├── sealos.mdx
│   │   │   ├── sealos.zh-CN.mdx
│   │   │   ├── vercel.mdx
│   │   │   ├── vercel.zh-CN.mdx
│   │   │   ├── zeabur.mdx
│   │   │   └── zeabur.zh-CN.mdx
│   │   ├── start.mdx
│   │   └── start.zh-CN.mdx
│   ├── usage/
│   │   ├── agent/
│   │   │   ├── agent-team.mdx
│   │   │   ├── agent-team.zh-CN.mdx
│   │   │   ├── artifacts.mdx
│   │   │   ├── artifacts.zh-CN.mdx
│   │   │   ├── chain-of-thought.mdx
│   │   │   ├── chain-of-thought.zh-CN.mdx
│   │   │   ├── gtd.mdx
│   │   │   ├── gtd.zh-CN.mdx
│   │   │   ├── notebook.mdx
│   │   │   ├── notebook.zh-CN.mdx
│   │   │   ├── sandbox.mdx
│   │   │   ├── sandbox.zh-CN.mdx
│   │   │   ├── scheduled-task.mdx
│   │   │   ├── scheduled-task.zh-CN.mdx
│   │   │   ├── share.mdx
│   │   │   ├── share.zh-CN.mdx
│   │   │   ├── topic.mdx
│   │   │   ├── topic.zh-CN.mdx
│   │   │   ├── translate.mdx
│   │   │   ├── translate.zh-CN.mdx
│   │   │   ├── tts-stt.mdx
│   │   │   ├── tts-stt.zh-CN.mdx
│   │   │   ├── web-search.mdx
│   │   │   └── web-search.zh-CN.mdx
│   │   ├── channels/
│   │   │   ├── discord.mdx
│   │   │   ├── discord.zh-CN.mdx
│   │   │   ├── feishu.mdx
│   │   │   ├── feishu.zh-CN.mdx
│   │   │   ├── lark.mdx
│   │   │   ├── lark.zh-CN.mdx
│   │   │   ├── overview.mdx
│   │   │   ├── overview.zh-CN.mdx
│   │   │   ├── qq.mdx
│   │   │   ├── qq.zh-CN.mdx
│   │   │   ├── slack.mdx
│   │   │   ├── slack.zh-CN.mdx
│   │   │   ├── telegram.mdx
│   │   │   ├── telegram.zh-CN.mdx
│   │   │   ├── wechat.mdx
│   │   │   └── wechat.zh-CN.mdx
│   │   ├── community/
│   │   │   ├── agent-market.mdx
│   │   │   ├── agent-market.zh-CN.mdx
│   │   │   ├── become-a-creator.mdx
│   │   │   ├── become-a-creator.zh-CN.mdx
│   │   │   ├── custom-mcp.mdx
│   │   │   ├── custom-mcp.zh-CN.mdx
│   │   │   ├── mcp-market.mdx
│   │   │   ├── mcp-market.zh-CN.mdx
│   │   │   ├── publish-agent.mdx
│   │   │   ├── publish-agent.zh-CN.mdx
│   │   │   ├── skill-management.mdx
│   │   │   ├── skill-management.zh-CN.mdx
│   │   │   └── skills-and-tools.mdx
│   │   ├── getting-started/
│   │   │   ├── agent.mdx
│   │   │   ├── agent.zh-CN.mdx
│   │   │   ├── chat.mdx
│   │   │   ├── file-upload.mdx
│   │   │   ├── get-lobehub.mdx
│   │   │   ├── get-lobehub.zh-CN.mdx
│   │   │   ├── image-generation.mdx
│   │   │   ├── image-generation.zh-CN.mdx
│   │   │   ├── lobe-ai.mdx
│   │   │   ├── lobe-ai.zh-CN.mdx
│   │   │   ├── memory.mdx
│   │   │   ├── memory.zh-CN.mdx
│   │   │   ├── page.mdx
│   │   │   ├── page.zh-CN.mdx
│   │   │   ├── resource.mdx
│   │   │   ├── resource.zh-CN.mdx
│   │   │   ├── vision.mdx
│   │   │   └── vision.zh-CN.mdx
│   │   ├── help.mdx
│   │   ├── help.zh-CN.mdx
│   │   ├── migrate-from-local-database.mdx
│   │   ├── migrate-from-local-database.zh-CN.mdx
│   │   ├── providers/
│   │   │   ├── ai21.mdx
│   │   │   ├── ai21.zh-CN.mdx
│   │   │   ├── ai302.mdx
│   │   │   ├── ai302.zh-CN.mdx
│   │   │   ├── ai360.mdx
│   │   │   ├── ai360.zh-CN.mdx
│   │   │   ├── aihubmix.mdx
│   │   │   ├── aihubmix.zh-CN.mdx
│   │   │   ├── anthropic.mdx
│   │   │   ├── anthropic.zh-CN.mdx
│   │   │   ├── azure.mdx
│   │   │   ├── azure.zh-CN.mdx
│   │   │   ├── azureai.mdx
│   │   │   ├── azureai.zh-CN.mdx
│   │   │   ├── baichuan.mdx
│   │   │   ├── baichuan.zh-CN.mdx
│   │   │   ├── bedrock.mdx
│   │   │   ├── bedrock.zh-CN.mdx
│   │   │   ├── bfl.mdx
│   │   │   ├── bfl.zh-CN.mdx
│   │   │   ├── cloudflare.mdx
│   │   │   ├── cloudflare.zh-CN.mdx
│   │   │   ├── comfyui.mdx
│   │   │   ├── comfyui.zh-CN.mdx
│   │   │   ├── deepseek.mdx
│   │   │   ├── deepseek.zh-CN.mdx
│   │   │   ├── fal.mdx
│   │   │   ├── fal.zh-CN.mdx
│   │   │   ├── fireworksai.mdx
│   │   │   ├── fireworksai.zh-CN.mdx
│   │   │   ├── giteeai.mdx
│   │   │   ├── giteeai.zh-CN.mdx
│   │   │   ├── github.mdx
│   │   │   ├── github.zh-CN.mdx
│   │   │   ├── google.mdx
│   │   │   ├── google.zh-CN.mdx
│   │   │   ├── groq.mdx
│   │   │   ├── groq.zh-CN.mdx
│   │   │   ├── hunyuan.mdx
│   │   │   ├── hunyuan.zh-CN.mdx
│   │   │   ├── infiniai.mdx
│   │   │   ├── infiniai.zh-CN.mdx
│   │   │   ├── internlm.mdx
│   │   │   ├── internlm.zh-CN.mdx
│   │   │   ├── jina.mdx
│   │   │   ├── jina.zh-CN.mdx
│   │   │   ├── lmstudio.mdx
│   │   │   ├── lmstudio.zh-CN.mdx
│   │   │   ├── minimax.mdx
│   │   │   ├── minimax.zh-CN.mdx
│   │   │   ├── mistral.mdx
│   │   │   ├── mistral.zh-CN.mdx
│   │   │   ├── modelscope.mdx
│   │   │   ├── modelscope.zh-CN.mdx
│   │   │   ├── moonshot.mdx
│   │   │   ├── moonshot.zh-CN.mdx
│   │   │   ├── novita.mdx
│   │   │   ├── novita.zh-CN.mdx
│   │   │   ├── nvidia.mdx
│   │   │   ├── nvidia.zh-CN.mdx
│   │   │   ├── ollama/
│   │   │   │   ├── gemma.mdx
│   │   │   │   ├── gemma.zh-CN.mdx
│   │   │   │   ├── qwen.mdx
│   │   │   │   └── qwen.zh-CN.mdx
│   │   │   ├── ollama.mdx
│   │   │   ├── ollama.zh-CN.mdx
│   │   │   ├── openai.mdx
│   │   │   ├── openai.zh-CN.mdx
│   │   │   ├── openrouter.mdx
│   │   │   ├── openrouter.zh-CN.mdx
│   │   │   ├── perplexity.mdx
│   │   │   ├── perplexity.zh-CN.mdx
│   │   │   ├── ppio.mdx
│   │   │   ├── ppio.zh-CN.mdx
│   │   │   ├── qiniu.mdx
│   │   │   ├── qiniu.zh-CN.mdx
│   │   │   ├── qwen.mdx
│   │   │   ├── qwen.zh-CN.mdx
│   │   │   ├── sambanova.mdx
│   │   │   ├── sambanova.zh-CN.mdx
│   │   │   ├── sensenova.mdx
│   │   │   ├── sensenova.zh-CN.mdx
│   │   │   ├── siliconcloud.mdx
│   │   │   ├── siliconcloud.zh-CN.mdx
│   │   │   ├── spark.mdx
│   │   │   ├── spark.zh-CN.mdx
│   │   │   ├── stepfun.mdx
│   │   │   ├── stepfun.zh-CN.mdx
│   │   │   ├── taichu.mdx
│   │   │   ├── taichu.zh-CN.mdx
│   │   │   ├── tencentcloud.mdx
│   │   │   ├── tencentcloud.zh-CN.mdx
│   │   │   ├── togetherai.mdx
│   │   │   ├── togetherai.zh-CN.mdx
│   │   │   ├── upstage.mdx
│   │   │   ├── upstage.zh-CN.mdx
│   │   │   ├── vercel-ai-gateway.mdx
│   │   │   ├── vercel-ai-gateway.zh-CN.mdx
│   │   │   ├── vertexai.mdx
│   │   │   ├── vertexai.zh-CN.mdx
│   │   │   ├── vllm.mdx
│   │   │   ├── vllm.zh-CN.mdx
│   │   │   ├── volcengine.mdx
│   │   │   ├── volcengine.zh-CN.mdx
│   │   │   ├── wenxin.mdx
│   │   │   ├── wenxin.zh-CN.mdx
│   │   │   ├── xai.mdx
│   │   │   ├── xai.zh-CN.mdx
│   │   │   ├── zeroone.mdx
│   │   │   ├── zeroone.zh-CN.mdx
│   │   │   ├── zhipu.mdx
│   │   │   └── zhipu.zh-CN.mdx
│   │   ├── providers.mdx
│   │   ├── providers.zh-CN.mdx
│   │   ├── start.mdx
│   │   ├── start.zh-CN.mdx
│   │   └── user-interface/
│   │       ├── appearance.mdx
│   │       ├── appearance.zh-CN.mdx
│   │       ├── command-menu.mdx
│   │       ├── command-menu.zh-CN.mdx
│   │       ├── shortcuts.mdx
│   │       ├── shortcuts.zh-CN.mdx
│   │       ├── stats.mdx
│   │       └── stats.zh-CN.mdx
│   └── wiki/
│       ├── HOME.md
│       └── HOME.zh-CN.md
├── drizzle.config.ts
├── e2e/
│   ├── .gitignore
│   ├── CLAUDE.md
│   ├── README.md
│   ├── cucumber.config.js
│   ├── docs/
│   │   ├── llm-mock.md
│   │   ├── local-setup.md
│   │   └── testing-tips.md
│   ├── package.json
│   ├── scripts/
│   │   └── setup.ts
│   ├── src/
│   │   ├── features/
│   │   │   ├── community/
│   │   │   │   ├── detail-pages.feature
│   │   │   │   ├── interactions.feature
│   │   │   │   └── smoke.feature
│   │   │   ├── home/
│   │   │   │   ├── sidebarAgent.feature
│   │   │   │   ├── sidebarGroup.feature
│   │   │   │   └── starter.feature
│   │   │   ├── journeys/
│   │   │   │   └── agent/
│   │   │   │       ├── agent-conversation-mgmt.feature
│   │   │   │       ├── agent-conversation.feature
│   │   │   │       └── agent-message-ops.feature
│   │   │   ├── page/
│   │   │   │   ├── README.md
│   │   │   │   ├── crud.feature
│   │   │   │   ├── editor-content.feature
│   │   │   │   └── editor-meta.feature
│   │   │   └── routes/
│   │   │       └── core-routes.feature
│   │   ├── mocks/
│   │   │   ├── community/
│   │   │   │   ├── data.ts
│   │   │   │   ├── handlers.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── types.ts
│   │   │   ├── index.ts
│   │   │   └── llm/
│   │   │       └── index.ts
│   │   ├── steps/
│   │   │   ├── agent/
│   │   │   │   ├── conversation-mgmt.steps.ts
│   │   │   │   ├── conversation.steps.ts
│   │   │   │   └── message-ops.steps.ts
│   │   │   ├── common/
│   │   │   │   ├── auth.steps.ts
│   │   │   │   └── navigation.steps.ts
│   │   │   ├── community/
│   │   │   │   ├── detail-pages.steps.ts
│   │   │   │   ├── interactions.steps.ts
│   │   │   │   └── smoke.steps.ts
│   │   │   ├── home/
│   │   │   │   ├── sidebarAgent.steps.ts
│   │   │   │   ├── sidebarGroup.steps.ts
│   │   │   │   └── starter.steps.ts
│   │   │   ├── hooks.ts
│   │   │   ├── page/
│   │   │   │   ├── editor-content.steps.ts
│   │   │   │   ├── editor-meta.steps.ts
│   │   │   │   └── page-crud.steps.ts
│   │   │   └── routes/
│   │   │       └── routes.steps.ts
│   │   └── support/
│   │       ├── seedTestUser.ts
│   │       ├── webServer.ts
│   │       └── world.ts
│   └── tsconfig.json
├── eslint.config.mjs
├── index.html
├── index.mobile.html
├── knip.ts
├── locales/
│   ├── ar/
│   │   ├── agent.json
│   │   ├── agentGroup.json
│   │   ├── auth.json
│   │   ├── authError.json
│   │   ├── changelog.json
│   │   ├── chat.json
│   │   ├── color.json
│   │   ├── common.json
│   │   ├── components.json
│   │   ├── desktop-onboarding.json
│   │   ├── discover.json
│   │   ├── editor.json
│   │   ├── electron.json
│   │   ├── error.json
│   │   ├── eval.json
│   │   ├── file.json
│   │   ├── home.json
│   │   ├── hotkey.json
│   │   ├── image.json
│   │   ├── knowledgeBase.json
│   │   ├── labs.json
│   │   ├── marketAuth.json
│   │   ├── memory.json
│   │   ├── metadata.json
│   │   ├── migration.json
│   │   ├── modelProvider.json
│   │   ├── models.json
│   │   ├── notification.json
│   │   ├── oauth.json
│   │   ├── onboarding.json
│   │   ├── plugin.json
│   │   ├── portal.json
│   │   ├── providers.json
│   │   ├── ragEval.json
│   │   ├── setting.json
│   │   ├── spend.json
│   │   ├── subscription.json
│   │   ├── suggestQuestions.json
│   │   ├── thread.json
│   │   ├── tool.json
│   │   ├── topic.json
│   │   ├── ui.json
│   │   ├── video.json
│   │   └── welcome.json
│   ├── bg-BG/
│   │   ├── agent.json
│   │   ├── agentGroup.json
│   │   ├── auth.json
│   │   ├── authError.json
│   │   ├── changelog.json
│   │   ├── chat.json
│   │   ├── color.json
│   │   ├── common.json
│   │   ├── components.json
│   │   ├── desktop-onboarding.json
│   │   ├── discover.json
│   │   ├── editor.json
│   │   ├── electron.json
│   │   ├── error.json
│   │   ├── eval.json
│   │   ├── file.json
│   │   ├── home.json
│   │   ├── hotkey.json
│   │   ├── image.json
│   │   ├── knowledgeBase.json
│   │   ├── labs.json
│   │   ├── marketAuth.json
│   │   ├── memory.json
│   │   ├── metadata.json
│   │   ├── migration.json
│   │   ├── modelProvider.json
│   │   ├── models.json
│   │   ├── notification.json
│   │   ├── oauth.json
│   │   ├── onboarding.json
│   │   ├── plugin.json
│   │   ├── portal.json
│   │   ├── providers.json
│   │   ├── ragEval.json
│   │   ├── setting.json
│   │   ├── spend.json
│   │   ├── subscription.json
│   │   ├── suggestQuestions.json
│   │   ├── thread.json
│   │   ├── tool.json
│   │   ├── topic.json
│   │   ├── ui.json
│   │   ├── video.json
│   │   └── welcome.json
│   ├── de-DE/
│   │   ├── agent.json
│   │   ├── agentGroup.json
│   │   ├── auth.json
│   │   ├── authError.json
│   │   ├── changelog.json
│   │   ├── chat.json
│   │   ├── color.json
│   │   ├── common.json
│   │   ├── components.json
│   │   ├── desktop-onboarding.json
│   │   ├── discover.json
│   │   ├── editor.json
│   │   ├── electron.json
│   │   ├── error.json
│   │   ├── eval.json
│   │   ├── file.json
│   │   ├── home.json
│   │   ├── hotkey.json
│   │   ├── image.json
│   │   ├── knowledgeBase.json
│   │   ├── labs.json
│   │   ├── marketAuth.json
│   │   ├── memory.json
│   │   ├── metadata.json
│   │   ├── migration.json
│   │   ├── modelProvider.json
│   │   ├── models.json
│   │   ├── notification.json
│   │   ├── oauth.json
│   │   ├── onboarding.json
│   │   ├── plugin.json
│   │   ├── portal.json
│   │   ├── providers.json
│   │   ├── ragEval.json
│   │   ├── setting.json
│   │   ├── spend.json
│   │   ├── subscription.json
│   │   ├── suggestQuestions.json
│   │   ├── thread.json
│   │   ├── tool.json
│   │   ├── topic.json
│   │   ├── ui.json
│   │   ├── video.json
│   │   └── welcome.json
│   ├── en-US/
│   │   ├── agent.json
│   │   ├── agentGroup.json
│   │   ├── auth.json
│   │   ├── authError.json
│   │   ├── changelog.json
│   │   ├── chat.json
│   │   ├── color.json
│   │   ├── common.json
│   │   ├── components.json
│   │   ├── desktop-onboarding.json
│   │   ├── discover.json
│   │   ├── editor.json
│   │   ├── electron.json
│   │   ├── error.json
│   │   ├── eval.json
│   │   ├── file.json
│   │   ├── home.json
│   │   ├── hotkey.json
│   │   ├── image.json
│   │   ├── knowledgeBase.json
│   │   ├── labs.json
│   │   ├── marketAuth.json
│   │   ├── memory.json
│   │   ├── metadata.json
│   │   ├── migration.json
│   │   ├── modelProvider.json
│   │   ├── models.json
│   │   ├── notification.json
│   │   ├── oauth.json
│   │   ├── onboarding.json
│   │   ├── plugin.json
│   │   ├── portal.json
│   │   ├── providers.json
│   │   ├── ragEval.json
│   │   ├── setting.json
│   │   ├── spend.json
│   │   ├── subscription.json
│   │   ├── suggestQuestions.json
│   │   ├── thread.json
│   │   ├── tool.json
│   │   ├── topic.json
│   │   ├── ui.json
│   │   ├── video.json
│   │   └── welcome.json
│   ├── es-ES/
│   │   ├── agent.json
│   │   ├── agentGroup.json
│   │   ├── auth.json
│   │   ├── authError.json
│   │   ├── changelog.json
│   │   ├── chat.json
│   │   ├── color.json
│   │   ├── common.json
│   │   ├── components.json
│   │   ├── desktop-onboarding.json
│   │   ├── discover.json
│   │   ├── editor.json
│   │   ├── electron.json
│   │   ├── error.json
│   │   ├── eval.json
│   │   ├── file.json
│   │   ├── home.json
│   │   ├── hotkey.json
│   │   ├── image.json
│   │   ├── knowledgeBase.json
│   │   ├── labs.json
│   │   ├── marketAuth.json
│   │   ├── memory.json
│   │   ├── metadata.json
│   │   ├── migration.json
│   │   ├── modelProvider.json
│   │   ├── models.json
│   │   ├── notification.json
│   │   ├── oauth.json
│   │   ├── onboarding.json
│   │   ├── plugin.json
│   │   ├── portal.json
│   │   ├── providers.json
│   │   ├── ragEval.json
│   │   ├── setting.json
│   │   ├── spend.json
│   │   ├── subscription.json
│   │   ├── suggestQuestions.json
│   │   ├── thread.json
│   │   ├── tool.json
│   │   ├── topic.json
│   │   ├── ui.json
│   │   ├── video.json
│   │   └── welcome.json
│   ├── fa-IR/
│   │   ├── agent.json
│   │   ├── agentGroup.json
│   │   ├── auth.json
│   │   ├── authError.json
│   │   ├── changelog.json
│   │   ├── chat.json
│   │   ├── color.json
│   │   ├── common.json
│   │   ├── components.json
│   │   ├── desktop-onboarding.json
│   │   ├── discover.json
│   │   ├── editor.json
│   │   ├── electron.json
│   │   ├── error.json
│   │   ├── eval.json
│   │   ├── file.json
│   │   ├── home.json
│   │   ├── hotkey.json
│   │   ├── image.json
│   │   ├── knowledgeBase.json
│   │   ├── labs.json
│   │   ├── marketAuth.json
│   │   ├── memory.json
│   │   ├── metadata.json
│   │   ├── migration.json
│   │   ├── modelProvider.json
│   │   ├── models.json
│   │   ├── notification.json
│   │   ├── oauth.json
│   │   ├── onboarding.json
│   │   ├── plugin.json
│   │   ├── portal.json
│   │   ├── providers.json
│   │   ├── ragEval.json
│   │   ├── setting.json
│   │   ├── spend.json
│   │   ├── subscription.json
│   │   ├── suggestQuestions.json
│   │   ├── thread.json
│   │   ├── tool.json
│   │   ├── topic.json
│   │   ├── ui.json
│   │   ├── video.json
│   │   └── welcome.json
│   ├── fr-FR/
│   │   ├── agent.json
│   │   ├── agentGroup.json
│   │   ├── auth.json
│   │   ├── authError.json
│   │   ├── changelog.json
│   │   ├── chat.json
│   │   ├── color.json
│   │   ├── common.json
│   │   ├── components.json
│   │   ├── desktop-onboarding.json
│   │   ├── discover.json
│   │   ├── editor.json
│   │   ├── electron.json
│   │   ├── error.json
│   │   ├── eval.json
│   │   ├── file.json
│   │   ├── home.json
│   │   ├── hotkey.json
│   │   ├── image.json
│   │   ├── knowledgeBase.json
│   │   ├── labs.json
│   │   ├── marketAuth.json
│   │   ├── memory.json
│   │   ├── metadata.json
│   │   ├── migration.json
│   │   ├── modelProvider.json
│   │   ├── models.json
│   │   ├── notification.json
│   │   ├── oauth.json
│   │   ├── onboarding.json
│   │   ├── plugin.json
│   │   ├── portal.json
│   │   ├── providers.json
│   │   ├── ragEval.json
│   │   ├── setting.json
│   │   ├── spend.json
│   │   ├── subscription.json
│   │   ├── suggestQuestions.json
│   │   ├── thread.json
│   │   ├── tool.json
│   │   ├── topic.json
│   │   ├── ui.json
│   │   ├── video.json
│   │   └── welcome.json
│   ├── it-IT/
│   │   ├── agent.json
│   │   ├── agentGroup.json
│   │   ├── auth.json
│   │   ├── authError.json
│   │   ├── changelog.json
│   │   ├── chat.json
│   │   ├── color.json
│   │   ├── common.json
│   │   ├── components.json
│   │   ├── desktop-onboarding.json
│   │   ├── discover.json
│   │   ├── editor.json
│   │   ├── electron.json
│   │   ├── error.json
│   │   ├── eval.json
│   │   ├── file.json
│   │   ├── home.json
│   │   ├── hotkey.json
│   │   ├── image.json
│   │   ├── knowledgeBase.json
│   │   ├── labs.json
│   │   ├── marketAuth.json
│   │   ├── memory.json
│   │   ├── metadata.json
│   │   ├── migration.json
│   │   ├── modelProvider.json
│   │   ├── models.json
│   │   ├── notification.json
│   │   ├── oauth.json
│   │   ├── onboarding.json
│   │   ├── plugin.json
│   │   ├── portal.json
│   │   ├── providers.json
│   │   ├── ragEval.json
│   │   ├── setting.json
│   │   ├── spend.json
│   │   ├── subscription.json
│   │   ├── suggestQuestions.json
│   │   ├── thread.json
│   │   ├── tool.json
│   │   ├── topic.json
│   │   ├── ui.json
│   │   ├── video.json
│   │   └── welcome.json
│   ├── ja-JP/
│   │   ├── agent.json
│   │   ├── agentGroup.json
│   │   ├── auth.json
│   │   ├── authError.json
│   │   ├── changelog.json
│   │   ├── chat.json
│   │   ├── color.json
│   │   ├── common.json
│   │   ├── components.json
│   │   ├── desktop-onboarding.json
│   │   ├── discover.json
│   │   ├── editor.json
│   │   ├── electron.json
│   │   ├── error.json
│   │   ├── eval.json
│   │   ├── file.json
│   │   ├── home.json
│   │   ├── hotkey.json
│   │   ├── image.json
│   │   ├── knowledgeBase.json
│   │   ├── labs.json
│   │   ├── marketAuth.json
│   │   ├── memory.json
│   │   ├── metadata.json
│   │   ├── migration.json
│   │   ├── modelProvider.json
│   │   ├── models.json
│   │   ├── notification.json
│   │   ├── oauth.json
│   │   ├── onboarding.json
│   │   ├── plugin.json
│   │   ├── portal.json
│   │   ├── providers.json
│   │   ├── ragEval.json
│   │   ├── setting.json
│   │   ├── spend.json
│   │   ├── subscription.json
│   │   ├── suggestQuestions.json
│   │   ├── thread.json
│   │   ├── tool.json
│   │   ├── topic.json
│   │   ├── ui.json
│   │   ├── video.json
│   │   └── welcome.json
│   ├── ko-KR/
│   │   ├── agent.json
│   │   ├── agentGroup.json
│   │   ├── auth.json
│   │   ├── authError.json
│   │   ├── changelog.json
│   │   ├── chat.json
│   │   ├── color.json
│   │   ├── common.json
│   │   ├── components.json
│   │   ├── desktop-onboarding.json
│   │   ├── discover.json
│   │   ├── editor.json
│   │   ├── electron.json
│   │   ├── error.json
│   │   ├── eval.json
│   │   ├── file.json
│   │   ├── home.json
│   │   ├── hotkey.json
│   │   ├── image.json
│   │   ├── knowledgeBase.json
│   │   ├── labs.json
│   │   ├── marketAuth.json
│   │   ├── memory.json
│   │   ├── metadata.json
│   │   ├── migration.json
│   │   ├── modelProvider.json
│   │   ├── models.json
│   │   ├── notification.json
│   │   ├── oauth.json
│   │   ├── onboarding.json
│   │   ├── plugin.json
│   │   ├── portal.json
│   │   ├── providers.json
│   │   ├── ragEval.json
│   │   ├── setting.json
│   │   ├── spend.json
│   │   ├── subscription.json
│   │   ├── suggestQuestions.json
│   │   ├── thread.json
│   │   ├── tool.json
│   │   ├── topic.json
│   │   ├── ui.json
│   │   ├── video.json
│   │   └── welcome.json
│   ├── nl-NL/
│   │   ├── agent.json
│   │   ├── agentGroup.json
│   │   ├── auth.json
│   │   ├── authError.json
│   │   ├── changelog.json
│   │   ├── chat.json
│   │   ├── color.json
│   │   ├── common.json
│   │   ├── components.json
│   │   ├── desktop-onboarding.json
│   │   ├── discover.json
│   │   ├── editor.json
│   │   ├── electron.json
│   │   ├── error.json
│   │   ├── eval.json
│   │   ├── file.json
│   │   ├── home.json
│   │   ├── hotkey.json
│   │   ├── image.json
│   │   ├── knowledgeBase.json
│   │   ├── labs.json
│   │   ├── marketAuth.json
│   │   ├── memory.json
│   │   ├── metadata.json
│   │   ├── migration.json
│   │   ├── modelProvider.json
│   │   ├── models.json
│   │   ├── notification.json
│   │   ├── oauth.json
│   │   ├── onboarding.json
│   │   ├── plugin.json
│   │   ├── portal.json
│   │   ├── providers.json
│   │   ├── ragEval.json
│   │   ├── setting.json
│   │   ├── spend.json
│   │   ├── subscription.json
│   │   ├── suggestQuestions.json
│   │   ├── thread.json
│   │   ├── tool.json
│   │   ├── topic.json
│   │   ├── ui.json
│   │   ├── video.json
│   │   └── welcome.json
│   ├── pl-PL/
│   │   ├── agent.json
│   │   ├── agentGroup.json
│   │   ├── auth.json
│   │   ├── authError.json
│   │   ├── changelog.json
│   │   ├── chat.json
│   │   ├── color.json
│   │   ├── common.json
│   │   ├── components.json
│   │   ├── desktop-onboarding.json
│   │   ├── discover.json
│   │   ├── editor.json
│   │   ├── electron.json
│   │   ├── error.json
│   │   ├── eval.json
│   │   ├── file.json
│   │   ├── home.json
│   │   ├── hotkey.json
│   │   ├── image.json
│   │   ├── knowledgeBase.json
│   │   ├── labs.json
│   │   ├── marketAuth.json
│   │   ├── memory.json
│   │   ├── metadata.json
│   │   ├── migration.json
│   │   ├── modelProvider.json
│   │   ├── models.json
│   │   ├── notification.json
│   │   ├── oauth.json
│   │   ├── onboarding.json
│   │   ├── plugin.json
│   │   ├── portal.json
│   │   ├── providers.json
│   │   ├── ragEval.json
│   │   ├── setting.json
│   │   ├── spend.json
│   │   ├── subscription.json
│   │   ├── suggestQuestions.json
│   │   ├── thread.json
│   │   ├── tool.json
│   │   ├── topic.json
│   │   ├── ui.json
│   │   ├── video.json
│   │   └── welcome.json
│   ├── pt-BR/
│   │   ├── agent.json
│   │   ├── agentGroup.json
│   │   ├── auth.json
│   │   ├── authError.json
│   │   ├── changelog.json
│   │   ├── chat.json
│   │   ├── color.json
│   │   ├── common.json
│   │   ├── components.json
│   │   ├── desktop-onboarding.json
│   │   ├── discover.json
│   │   ├── editor.json
│   │   ├── electron.json
│   │   ├── error.json
│   │   ├── eval.json
│   │   ├── file.json
│   │   ├── home.json
│   │   ├── hotkey.json
│   │   ├── image.json
│   │   ├── knowledgeBase.json
│   │   ├── labs.json
│   │   ├── marketAuth.json
│   │   ├── memory.json
│   │   ├── metadata.json
│   │   ├── migration.json
│   │   ├── modelProvider.json
│   │   ├── models.json
│   │   ├── notification.json
│   │   ├── oauth.json
│   │   ├── onboarding.json
│   │   ├── plugin.json
│   │   ├── portal.json
│   │   ├── providers.json
│   │   ├── ragEval.json
│   │   ├── setting.json
│   │   ├── spend.json
│   │   ├── subscription.json
│   │   ├── suggestQuestions.json
│   │   ├── thread.json
│   │   ├── tool.json
│   │   ├── topic.json
│   │   ├── ui.json
│   │   ├── video.json
│   │   └── welcome.json
│   ├── ru-RU/
│   │   ├── agent.json
│   │   ├── agentGroup.json
│   │   ├── auth.json
│   │   ├── authError.json
│   │   ├── changelog.json
│   │   ├── chat.json
│   │   ├── color.json
│   │   ├── common.json
│   │   ├── components.json
│   │   ├── desktop-onboarding.json
│   │   ├── discover.json
│   │   ├── editor.json
│   │   ├── electron.json
│   │   ├── error.json
│   │   ├── eval.json
│   │   ├── file.json
│   │   ├── home.json
│   │   ├── hotkey.json
│   │   ├── image.json
│   │   ├── knowledgeBase.json
│   │   ├── labs.json
│   │   ├── marketAuth.json
│   │   ├── memory.json
│   │   ├── metadata.json
│   │   ├── migration.json
│   │   ├── modelProvider.json
│   │   ├── models.json
│   │   ├── notification.json
│   │   ├── oauth.json
│   │   ├── onboarding.json
│   │   ├── plugin.json
│   │   ├── portal.json
│   │   ├── providers.json
│   │   ├── ragEval.json
│   │   ├── setting.json
│   │   ├── spend.json
│   │   ├── subscription.json
│   │   ├── suggestQuestions.json
│   │   ├── thread.json
│   │   ├── tool.json
│   │   ├── topic.json
│   │   ├── ui.json
│   │   ├── video.json
│   │   └── welcome.json
│   ├── tr-TR/
│   │   ├── agent.json
│   │   ├── agentGroup.json
│   │   ├── auth.json
│   │   ├── authError.json
│   │   ├── changelog.json
│   │   ├── chat.json
│   │   ├── color.json
│   │   ├── common.json
│   │   ├── components.json
│   │   ├── desktop-onboarding.json
│   │   ├── discover.json
│   │   ├── editor.json
│   │   ├── electron.json
│   │   ├── error.json
│   │   ├── eval.json
│   │   ├── file.json
│   │   ├── home.json
│   │   ├── hotkey.json
│   │   ├── image.json
│   │   ├── knowledgeBase.json
│   │   ├── labs.json
│   │   ├── marketAuth.json
│   │   ├── memory.json
│   │   ├── metadata.json
│   │   ├── migration.json
│   │   ├── modelProvider.json
│   │   ├── models.json
│   │   ├── notification.json
│   │   ├── oauth.json
│   │   ├── onboarding.json
│   │   ├── plugin.json
│   │   ├── portal.json
│   │   ├── providers.json
│   │   ├── ragEval.json
│   │   ├── setting.json
│   │   ├── spend.json
│   │   ├── subscription.json
│   │   ├── suggestQuestions.json
│   │   ├── thread.json
│   │   ├── tool.json
│   │   ├── topic.json
│   │   ├── ui.json
│   │   ├── video.json
│   │   └── welcome.json
│   ├── vi-VN/
│   │   ├── agent.json
│   │   ├── agentGroup.json
│   │   ├── auth.json
│   │   ├── authError.json
│   │   ├── changelog.json
│   │   ├── chat.json
│   │   ├── color.json
│   │   ├── common.json
│   │   ├── components.json
│   │   ├── desktop-onboarding.json
│   │   ├── discover.json
│   │   ├── editor.json
│   │   ├── electron.json
│   │   ├── error.json
│   │   ├── eval.json
│   │   ├── file.json
│   │   ├── home.json
│   │   ├── hotkey.json
│   │   ├── image.json
│   │   ├── knowledgeBase.json
│   │   ├── labs.json
│   │   ├── marketAuth.json
│   │   ├── memory.json
│   │   ├── metadata.json
│   │   ├── migration.json
│   │   ├── modelProvider.json
│   │   ├── models.json
│   │   ├── notification.json
│   │   ├── oauth.json
│   │   ├── onboarding.json
│   │   ├── plugin.json
│   │   ├── portal.json
│   │   ├── providers.json
│   │   ├── ragEval.json
│   │   ├── setting.json
│   │   ├── spend.json
│   │   ├── subscription.json
│   │   ├── suggestQuestions.json
│   │   ├── thread.json
│   │   ├── tool.json
│   │   ├── topic.json
│   │   ├── ui.json
│   │   ├── video.json
│   │   └── welcome.json
│   ├── zh-CN/
│   │   ├── agent.json
│   │   ├── agentGroup.json
│   │   ├── auth.json
│   │   ├── authError.json
│   │   ├── changelog.json
│   │   ├── chat.json
│   │   ├── color.json
│   │   ├── common.json
│   │   ├── components.json
│   │   ├── desktop-onboarding.json
│   │   ├── discover.json
│   │   ├── editor.json
│   │   ├── electron.json
│   │   ├── error.json
│   │   ├── eval.json
│   │   ├── file.json
│   │   ├── home.json
│   │   ├── hotkey.json
│   │   ├── image.json
│   │   ├── knowledgeBase.json
│   │   ├── labs.json
│   │   ├── marketAuth.json
│   │   ├── memory.json
│   │   ├── metadata.json
│   │   ├── migration.json
│   │   ├── modelProvider.json
│   │   ├── models.json
│   │   ├── notification.json
│   │   ├── oauth.json
│   │   ├── onboarding.json
│   │   ├── plugin.json
│   │   ├── portal.json
│   │   ├── providers.json
│   │   ├── ragEval.json
│   │   ├── setting.json
│   │   ├── spend.json
│   │   ├── subscription.json
│   │   ├── suggestQuestions.json
│   │   ├── thread.json
│   │   ├── tool.json
│   │   ├── topic.json
│   │   ├── ui.json
│   │   ├── video.json
│   │   └── welcome.json
│   └── zh-TW/
│       ├── agent.json
│       ├── agentGroup.json
│       ├── auth.json
│       ├── authError.json
│       ├── changelog.json
│       ├── chat.json
│       ├── color.json
│       ├── common.json
│       ├── components.json
│       ├── desktop-onboarding.json
│       ├── discover.json
│       ├── editor.json
│       ├── electron.json
│       ├── error.json
│       ├── eval.json
│       ├── file.json
│       ├── home.json
│       ├── hotkey.json
│       ├── image.json
│       ├── knowledgeBase.json
│       ├── labs.json
│       ├── marketAuth.json
│       ├── memory.json
│       ├── metadata.json
│       ├── migration.json
│       ├── modelProvider.json
│       ├── models.json
│       ├── notification.json
│       ├── oauth.json
│       ├── onboarding.json
│       ├── plugin.json
│       ├── portal.json
│       ├── providers.json
│       ├── ragEval.json
│       ├── setting.json
│       ├── spend.json
│       ├── subscription.json
│       ├── suggestQuestions.json
│       ├── thread.json
│       ├── tool.json
│       ├── topic.json
│       ├── ui.json
│       ├── video.json
│       └── welcome.json
├── netlify.toml
├── next.config.ts
├── package.json
├── packages/
│   ├── agent-manager-runtime/
│   │   ├── package.json
│   │   └── src/
│   │       ├── AgentManagerRuntime.ts
│   │       ├── __tests__/
│   │       │   └── AgentManagerRuntime.test.ts
│   │       ├── index.ts
│   │       └── types.ts
│   ├── agent-runtime/
│   │   ├── examples/
│   │   │   └── tools-calling.ts
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── agents/
│   │   │   │   ├── GeneralChatAgent.ts
│   │   │   │   ├── __tests__/
│   │   │   │   │   └── GeneralChatAgent.test.ts
│   │   │   │   └── index.ts
│   │   │   ├── audit/
│   │   │   │   ├── __tests__/
│   │   │   │   │   └── createSecurityBlacklistAudit.test.ts
│   │   │   │   ├── createSecurityBlacklistAudit.ts
│   │   │   │   ├── defaultSecurityBlacklist.ts
│   │   │   │   ├── globalAudit.ts
│   │   │   │   └── index.ts
│   │   │   ├── core/
│   │   │   │   ├── InterventionChecker.ts
│   │   │   │   ├── UsageCounter.ts
│   │   │   │   ├── __tests__/
│   │   │   │   │   ├── InterventionChecker.test.ts
│   │   │   │   │   ├── UsageCounter.test.ts
│   │   │   │   │   └── runtime.test.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── runtime.ts
│   │   │   ├── groupOrchestration/
│   │   │   │   ├── GroupOrchestrationRuntime.ts
│   │   │   │   ├── GroupOrchestrationSupervisor.ts
│   │   │   │   ├── __tests__/
│   │   │   │   │   └── GroupOrchestrationSupervisor.test.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── types.ts
│   │   │   ├── index.ts
│   │   │   ├── types/
│   │   │   │   ├── event.ts
│   │   │   │   ├── generalAgent.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── instruction.ts
│   │   │   │   ├── runtime.ts
│   │   │   │   ├── state.ts
│   │   │   │   └── usage.ts
│   │   │   └── utils/
│   │   │       ├── index.ts
│   │   │       ├── messageSelectors.test.ts
│   │   │       ├── messageSelectors.ts
│   │   │       ├── stepContextComputer.test.ts
│   │   │       ├── stepContextComputer.ts
│   │   │       ├── tokenCounter.test.ts
│   │   │       └── tokenCounter.ts
│   │   └── vitest.config.mts
│   ├── agent-templates/
│   │   ├── package.json
│   │   └── src/
│   │       ├── index.ts
│   │       ├── template.ts
│   │       ├── templates/
│   │       │   ├── claw/
│   │       │   │   ├── AGENTS.md
│   │       │   │   ├── BOOTSTRAP.md
│   │       │   │   ├── IDENTITY.md
│   │       │   │   ├── SOUL.md
│   │       │   │   ├── agent.ts
│   │       │   │   ├── bootstrap.ts
│   │       │   │   ├── identity.ts
│   │       │   │   ├── index.ts
│   │       │   │   ├── raw.d.ts
│   │       │   │   └── soul.ts
│   │       │   └── index.ts
│   │       └── types.ts
│   ├── agent-tracing/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── cli/
│   │   │   │   ├── index.ts
│   │   │   │   ├── inspect.ts
│   │   │   │   ├── list.ts
│   │   │   │   └── partial.ts
│   │   │   ├── index.ts
│   │   │   ├── recorder/
│   │   │   │   └── index.ts
│   │   │   ├── store/
│   │   │   │   ├── file-store.ts
│   │   │   │   └── types.ts
│   │   │   ├── types.ts
│   │   │   ├── utils/
│   │   │   │   ├── reconstruct.test.ts
│   │   │   │   └── reconstruct.ts
│   │   │   └── viewer/
│   │   │       └── index.ts
│   │   └── tsconfig.json
│   ├── builtin-agent-onboarding/
│   │   ├── package.json
│   │   └── src/
│   │       ├── client/
│   │       │   ├── QuestionRenderer.tsx
│   │       │   └── index.ts
│   │       ├── index.ts
│   │       ├── systemRole.ts
│   │       └── toolSystemRole.ts
│   ├── builtin-agents/
│   │   ├── package.json
│   │   └── src/
│   │       ├── agents/
│   │       │   ├── agent-builder/
│   │       │   │   ├── index.ts
│   │       │   │   └── systemRole.ts
│   │       │   ├── group-agent-builder/
│   │       │   │   ├── index.ts
│   │       │   │   └── systemRole.ts
│   │       │   ├── group-supervisor/
│   │       │   │   ├── index.ts
│   │       │   │   ├── systemRole.ts
│   │       │   │   └── type.ts
│   │       │   ├── inbox/
│   │       │   │   ├── index.ts
│   │       │   │   └── systemRole.ts
│   │       │   ├── page-agent/
│   │       │   │   ├── README.md
│   │       │   │   ├── index.ts
│   │       │   │   └── systemRole.ts
│   │       │   └── web-onboarding/
│   │       │       └── index.ts
│   │       ├── index.ts
│   │       └── types.ts
│   ├── builtin-skills/
│   │   ├── package.json
│   │   └── src/
│   │       ├── agent-browser/
│   │       │   ├── content.ts
│   │       │   └── index.ts
│   │       ├── artifacts/
│   │       │   ├── content.ts
│   │       │   └── index.ts
│   │       ├── find-skills/
│   │       │   ├── content.ts
│   │       │   └── index.ts
│   │       ├── index.ts
│   │       ├── lobehub/
│   │       │   ├── content.ts
│   │       │   ├── helpers.ts
│   │       │   ├── index.ts
│   │       │   └── references/
│   │       │       ├── agent.ts
│   │       │       ├── bot.ts
│   │       │       ├── config.ts
│   │       │       ├── doc.ts
│   │       │       ├── eval.ts
│   │       │       ├── file.ts
│   │       │       ├── generate.ts
│   │       │       ├── kb.ts
│   │       │       ├── memory.ts
│   │       │       ├── message.ts
│   │       │       ├── model.ts
│   │       │       ├── plugin.ts
│   │       │       ├── provider.ts
│   │       │       ├── search.ts
│   │       │       ├── skill.ts
│   │       │       └── topic.ts
│   │       ├── raw.d.ts
│   │       └── task/
│   │           ├── SKILL.md
│   │           ├── index.ts
│   │           └── references/
│   │               └── commands.md
│   ├── builtin-tool-activator/
│   │   ├── package.json
│   │   └── src/
│   │       ├── ExecutionRuntime/
│   │       │   └── index.ts
│   │       ├── client/
│   │       │   ├── Inspector/
│   │       │   │   ├── ActivateSkill/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ActivateTools/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Render/
│   │       │   │   ├── ActivateSkill/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   └── index.ts
│   │       ├── executor/
│   │       │   └── index.ts
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       ├── systemRole.ts
│   │       └── types.ts
│   ├── builtin-tool-agent-builder/
│   │   ├── package.json
│   │   └── src/
│   │       ├── client/
│   │       │   ├── Inspector/
│   │       │   │   ├── GetAvailableModels/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── InstallPlugin/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── SearchMarketTools/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── UpdateConfig/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── UpdatePrompt/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Intervention/
│   │       │   │   ├── InstallPlugin.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Render/
│   │       │   │   ├── GetAvailableModels.tsx
│   │       │   │   ├── InstallPlugin.tsx
│   │       │   │   ├── SearchMarketTools.tsx
│   │       │   │   ├── UpdateConfig.tsx
│   │       │   │   ├── UpdatePrompt.tsx
│   │       │   │   ├── components/
│   │       │   │   │   ├── ConfigCard.tsx
│   │       │   │   │   └── ConfigDiffView.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Streaming/
│   │       │   │   ├── UpdatePrompt/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   └── index.ts
│   │       ├── executor.ts
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       ├── systemRole.ts
│   │       └── types.ts
│   ├── builtin-tool-agent-documents/
│   │   ├── package.json
│   │   └── src/
│   │       ├── ExecutionRuntime/
│   │       │   └── index.ts
│   │       ├── client/
│   │       │   ├── Inspector/
│   │       │   │   ├── AgentDocumentsInspector/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Render/
│   │       │   │   └── index.ts
│   │       │   └── index.ts
│   │       ├── executor/
│   │       │   └── index.ts
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       ├── systemRole.ts
│   │       └── types.ts
│   ├── builtin-tool-agent-management/
│   │   ├── package.json
│   │   └── src/
│   │       ├── client/
│   │       │   ├── Inspector/
│   │       │   │   ├── CallAgent/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── CreateAgent/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── SearchAgent/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── UpdateAgent/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Render/
│   │       │   │   ├── CallAgent/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── CreateAgent/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── SearchAgent/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── UpdateAgent/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Streaming/
│   │       │   │   ├── CreateAgent/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   └── index.ts
│   │       ├── executor.ts
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       ├── systemRole.ts
│   │       └── types.ts
│   ├── builtin-tool-brief/
│   │   ├── package.json
│   │   └── src/
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       ├── systemRole.ts
│   │       └── types.ts
│   ├── builtin-tool-calculator/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── ExecutionRuntime/
│   │   │   │   └── index.ts
│   │   │   ├── calculate.test.ts
│   │   │   ├── client/
│   │   │   │   └── index.ts
│   │   │   ├── executor/
│   │   │   │   └── index.ts
│   │   │   ├── index.ts
│   │   │   ├── manifest.ts
│   │   │   ├── systemRole.ts
│   │   │   └── types.ts
│   │   └── tsconfig.json
│   ├── builtin-tool-cloud-sandbox/
│   │   ├── package.json
│   │   └── src/
│   │       ├── ExecutionRuntime/
│   │       │   └── index.ts
│   │       ├── client/
│   │       │   ├── Inspector/
│   │       │   │   ├── EditLocalFile/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ExecuteCode/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── GlobLocalFiles/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── GrepContent/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ListLocalFiles/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ReadLocalFile/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── RunCommand/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── SearchLocalFiles/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── WriteLocalFile/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Intervention/
│   │       │   │   ├── EditLocalFile/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ExecuteCode/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── MoveLocalFiles/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── RunCommand/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── WriteFile/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Render/
│   │       │   │   ├── EditLocalFile/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ExecuteCode/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ExportFile/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ListFiles/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── MoveLocalFiles/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ReadLocalFile/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── RunCommand/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── SearchFiles/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── WriteFile/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Streaming/
│   │       │   │   ├── ExecuteCode/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── components/
│   │       │   │   └── FilePathDisplay.tsx
│   │       │   └── index.ts
│   │       ├── executor/
│   │       │   └── index.ts
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       ├── systemRole.ts
│   │       └── types/
│   │           ├── api.ts
│   │           ├── index.ts
│   │           ├── params.ts
│   │           ├── service.ts
│   │           └── state.ts
│   ├── builtin-tool-creds/
│   │   ├── package.json
│   │   └── src/
│   │       ├── ExecutionRuntime/
│   │       │   └── index.ts
│   │       ├── client/
│   │       │   └── index.ts
│   │       ├── executor/
│   │       │   └── index.ts
│   │       ├── helpers.ts
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       ├── systemRole.ts
│   │       └── types.ts
│   ├── builtin-tool-group-agent-builder/
│   │   ├── package.json
│   │   └── src/
│   │       ├── ExecutionRuntime/
│   │       │   └── index.ts
│   │       ├── client/
│   │       │   ├── Inspector/
│   │       │   │   ├── BatchCreateAgents/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── CreateAgent/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── CreateGroup/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── GetAgentInfo/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── InviteAgent/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── RemoveAgent/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── SearchAgent/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── UpdateAgentPrompt/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── UpdateGroup/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── UpdateGroupPrompt/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Render/
│   │       │   │   ├── BatchCreateAgents.tsx
│   │       │   │   ├── UpdateAgentPrompt/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── UpdateGroupPrompt/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Streaming/
│   │       │   │   ├── BatchCreateAgents/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── UpdateAgentPrompt/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── UpdateGroupPrompt/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   └── index.ts
│   │       ├── executor.ts
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       ├── systemRole.ts
│   │       └── types.ts
│   ├── builtin-tool-group-management/
│   │   ├── package.json
│   │   └── src/
│   │       ├── client/
│   │       │   ├── Inspector/
│   │       │   │   ├── Broadcast/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ExecuteAgentTask/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ExecuteAgentTasks/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── Speak/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Intervention/
│   │       │   │   ├── ExecuteTask.tsx
│   │       │   │   ├── ExecuteTasks.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Render/
│   │       │   │   ├── Broadcast/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ExecuteTask/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ExecuteTasks/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── Speak/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Streaming/
│   │       │   │   ├── Broadcast/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ExecuteTask/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ExecuteTasks/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── Speak/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   └── index.ts
│   │       ├── const.ts
│   │       ├── executor.test.ts
│   │       ├── executor.ts
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       ├── systemRole.ts
│   │       └── types.ts
│   ├── builtin-tool-gtd/
│   │   ├── package.json
│   │   └── src/
│   │       ├── client/
│   │       │   ├── Inspector/
│   │       │   │   ├── ClearTodos/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── CreatePlan/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── CreateTodos/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ExecTask/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ExecTasks/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── UpdatePlan/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── UpdateTodos/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Intervention/
│   │       │   │   ├── AddTodo.tsx
│   │       │   │   ├── ClearTodos.tsx
│   │       │   │   ├── CreatePlan.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Render/
│   │       │   │   ├── CreatePlan/
│   │       │   │   │   ├── PlanCard.tsx
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ExecTask/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ExecTasks/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── TodoList/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Streaming/
│   │       │   │   ├── CreatePlan/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ExecTask/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ExecTasks/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── components/
│   │       │   │   ├── SortableTodoList/
│   │       │   │   │   ├── AddItemRow.tsx
│   │       │   │   │   ├── SortableItem.tsx
│   │       │   │   │   ├── TodoItemRow.tsx
│   │       │   │   │   ├── TodoList.tsx
│   │       │   │   │   ├── index.tsx
│   │       │   │   │   └── store/
│   │       │   │   │       ├── actions.ts
│   │       │   │   │       ├── index.ts
│   │       │   │   │       ├── initialState.ts
│   │       │   │   │       ├── store.test.ts
│   │       │   │   │       └── types.ts
│   │       │   │   └── index.ts
│   │       │   └── index.ts
│   │       ├── const.ts
│   │       ├── executor/
│   │       │   ├── helper.ts
│   │       │   ├── index.test.ts
│   │       │   └── index.ts
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       ├── systemRole.ts
│   │       └── types.ts
│   ├── builtin-tool-knowledge-base/
│   │   ├── package.json
│   │   └── src/
│   │       ├── ExecutionRuntime/
│   │       │   └── index.ts
│   │       ├── client/
│   │       │   ├── Inspector/
│   │       │   │   ├── ReadKnowledge/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── SearchKnowledgeBase/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Render/
│   │       │   │   ├── ReadKnowledge/
│   │       │   │   │   ├── FileCard.tsx
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── SearchKnowledgeBase/
│   │       │   │   │   ├── Item/
│   │       │   │   │   │   ├── index.tsx
│   │       │   │   │   │   └── style.ts
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   └── index.ts
│   │       ├── executor/
│   │       │   └── index.ts
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       ├── systemRole.ts
│   │       └── types.ts
│   ├── builtin-tool-local-system/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── __tests__/
│   │   │   │   └── interventionAudit.test.ts
│   │   │   ├── client/
│   │   │   │   ├── Inspector/
│   │   │   │   │   ├── EditLocalFile/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── GlobLocalFiles/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── GrepContent/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── ListLocalFiles/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── ReadLocalFile/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── RenameLocalFile/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── RunCommand/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── SearchLocalFiles/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── WriteLocalFile/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   └── index.ts
│   │   │   │   ├── Intervention/
│   │   │   │   │   ├── EditLocalFile/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── GlobLocalFiles/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── GrepContent/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── ListLocalFiles/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── MoveLocalFiles/
│   │   │   │   │   │   ├── MoveFileItem.tsx
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── OutOfScopeWarning.tsx
│   │   │   │   │   ├── ReadLocalFile/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── RenameLocalFile/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── RunCommand/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── SearchLocalFiles/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── WriteFile/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   └── index.ts
│   │   │   │   ├── Placeholder/
│   │   │   │   │   ├── ListFiles.tsx
│   │   │   │   │   └── SearchFiles.tsx
│   │   │   │   ├── Render/
│   │   │   │   │   ├── EditLocalFile/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── ListFiles/
│   │   │   │   │   │   ├── Result.tsx
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── MoveLocalFiles/
│   │   │   │   │   │   ├── MoveFileItem.tsx
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── ReadLocalFile/
│   │   │   │   │   │   ├── ReadFileSkeleton.tsx
│   │   │   │   │   │   ├── ReadFileView.tsx
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── RunCommand/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── SearchFiles/
│   │   │   │   │   │   ├── Result.tsx
│   │   │   │   │   │   ├── SearchQuery/
│   │   │   │   │   │   │   ├── SearchView.tsx
│   │   │   │   │   │   │   └── index.tsx
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── WriteFile/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   └── index.ts
│   │   │   │   ├── Streaming/
│   │   │   │   │   ├── RunCommand/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── WriteFile/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   └── index.ts
│   │   │   │   ├── components/
│   │   │   │   │   ├── FileItem.tsx
│   │   │   │   │   ├── FilePathDisplay.tsx
│   │   │   │   │   └── index.ts
│   │   │   │   └── index.ts
│   │   │   ├── executor/
│   │   │   │   └── index.ts
│   │   │   ├── index.ts
│   │   │   ├── interventionAudit.ts
│   │   │   ├── manifest.ts
│   │   │   ├── systemRole.desktop.ts
│   │   │   ├── systemRole.ts
│   │   │   ├── types.ts
│   │   │   └── utils/
│   │   │       ├── __tests__/
│   │   │       │   └── path.test.ts
│   │   │       └── path.ts
│   │   └── vitest.config.mts
│   ├── builtin-tool-memory/
│   │   ├── package.json
│   │   ├── promptfoo/
│   │   │   ├── evals/
│   │   │   │   └── preferences/
│   │   │   │       └── tool-call/
│   │   │   │           └── basic/
│   │   │   │               ├── buildMessages.ts
│   │   │   │               ├── eval.yaml
│   │   │   │               ├── prompt.ts
│   │   │   │               └── tests/
│   │   │   │                   └── cases.ts
│   │   │   └── tool-calls/
│   │   │       ├── memory-addContextMemory.json
│   │   │       ├── memory-addExperienceMemory.json
│   │   │       ├── memory-addIdentityMemory.json
│   │   │       ├── memory-addPreferenceMemory.json
│   │   │       ├── memory-removeIdentityMemory.json
│   │   │       ├── memory-searchUserMemory.json
│   │   │       └── memory-updateIdentityMemory.json
│   │   ├── promptfooconfig.yaml
│   │   ├── scripts/
│   │   │   └── generate-tool-call.ts
│   │   └── src/
│   │       ├── ExecutionRuntime/
│   │       │   └── index.ts
│   │       ├── client/
│   │       │   ├── Inspector/
│   │       │   │   ├── AddContextMemory/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── AddExperienceMemory/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── AddIdentityMemory/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── AddPreferenceMemory/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── RemoveIdentityMemory/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── SearchUserMemory/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── UpdateIdentityMemory/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Intervention/
│   │       │   │   ├── AddExperienceMemory/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Render/
│   │       │   │   ├── AddExperienceMemory/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── AddPreferenceMemory/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── SearchUserMemory/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Streaming/
│   │       │   │   ├── AddExperienceMemory/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── AddPreferenceMemory/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── components/
│   │       │   │   ├── ExperienceMemoryCard.tsx
│   │       │   │   ├── PreferenceMemoryCard.tsx
│   │       │   │   └── index.ts
│   │       │   └── index.ts
│   │       ├── executor/
│   │       │   └── index.ts
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       ├── systemRole.ts
│   │       └── types.ts
│   ├── builtin-tool-message/
│   │   ├── package.json
│   │   └── src/
│   │       ├── ExecutionRuntime/
│   │       │   └── index.ts
│   │       ├── client/
│   │       │   ├── Inspector/
│   │       │   │   └── index.ts
│   │       │   ├── Intervention/
│   │       │   │   └── index.ts
│   │       │   ├── Render/
│   │       │   │   └── index.ts
│   │       │   ├── Streaming/
│   │       │   │   └── index.ts
│   │       │   └── index.ts
│   │       ├── executor/
│   │       │   └── index.ts
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       ├── systemRole.ts
│   │       └── types.ts
│   ├── builtin-tool-notebook/
│   │   ├── package.json
│   │   └── src/
│   │       ├── ExecutionRuntime/
│   │       │   └── index.ts
│   │       ├── client/
│   │       │   ├── Inspector/
│   │       │   │   ├── CreateDocument/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Intervention/
│   │       │   │   └── index.ts
│   │       │   ├── Placeholder/
│   │       │   │   ├── CreateDocument.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Render/
│   │       │   │   ├── CreateDocument/
│   │       │   │   │   ├── DocumentCard.tsx
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Streaming/
│   │       │   │   ├── CreateDocument/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── components/
│   │       │   │   └── AnimatedNumber.tsx
│   │       │   └── index.ts
│   │       ├── executor/
│   │       │   └── index.ts
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       ├── systemRole.ts
│   │       └── types.ts
│   ├── builtin-tool-page-agent/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── client/
│   │   │   │   ├── Inspector/
│   │   │   │   │   ├── EditTitle/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── GetPageContent/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── InitPage/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── ModifyNodes/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── ReplaceText/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   └── index.ts
│   │   │   │   ├── Placeholder/
│   │   │   │   │   └── index.ts
│   │   │   │   ├── Render/
│   │   │   │   │   └── index.ts
│   │   │   │   ├── Streaming/
│   │   │   │   │   └── index.ts
│   │   │   │   ├── components/
│   │   │   │   │   └── AnimatedNumber.tsx
│   │   │   │   └── index.ts
│   │   │   ├── executor/
│   │   │   │   ├── index.test.ts
│   │   │   │   └── index.ts
│   │   │   ├── index.ts
│   │   │   ├── manifest.ts
│   │   │   ├── systemRole.ts
│   │   │   └── types.ts
│   │   └── vitest.config.mts
│   ├── builtin-tool-remote-device/
│   │   ├── package.json
│   │   └── src/
│   │       ├── ExecutionRuntime/
│   │       │   ├── index.ts
│   │       │   └── types.ts
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       ├── systemRole.ts
│   │       └── types.ts
│   ├── builtin-tool-skill-store/
│   │   ├── package.json
│   │   └── src/
│   │       ├── ExecutionRuntime/
│   │       │   └── index.ts
│   │       ├── client/
│   │       │   ├── Inspector/
│   │       │   │   ├── ImportFromMarket/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── ImportSkill/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── SearchSkill/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Render/
│   │       │   │   ├── ImportSkill/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── SearchSkill/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   └── index.ts
│   │       ├── executor/
│   │       │   └── index.ts
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       ├── systemRole.ts
│   │       └── types.ts
│   ├── builtin-tool-skills/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── ExecutionRuntime/
│   │   │   │   ├── index.test.ts
│   │   │   │   └── index.ts
│   │   │   ├── client/
│   │   │   │   ├── Inspector/
│   │   │   │   │   ├── ExecScript/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── ReadReference/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── RunCommand/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── RunSkill/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   └── index.ts
│   │   │   │   ├── Render/
│   │   │   │   │   ├── ExecScript/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── ReadReference/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── RunCommand/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   ├── RunSkill/
│   │   │   │   │   │   └── index.tsx
│   │   │   │   │   └── index.ts
│   │   │   │   └── index.ts
│   │   │   ├── executor/
│   │   │   │   └── index.ts
│   │   │   ├── index.ts
│   │   │   ├── manifest.base.ts
│   │   │   ├── manifest.desktop.ts
│   │   │   ├── manifest.ts
│   │   │   ├── systemRole.desktop.ts
│   │   │   ├── systemRole.ts
│   │   │   └── types.ts
│   │   └── vitest.config.mts
│   ├── builtin-tool-task/
│   │   ├── package.json
│   │   └── src/
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       ├── systemRole.ts
│   │       └── types.ts
│   ├── builtin-tool-topic-reference/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── executor/
│   │   │   │   └── index.ts
│   │   │   ├── index.ts
│   │   │   ├── manifest.ts
│   │   │   └── types.ts
│   │   └── tsconfig.json
│   ├── builtin-tool-user-interaction/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── ExecutionRuntime/
│   │   │   │   ├── index.test.ts
│   │   │   │   └── index.ts
│   │   │   ├── client/
│   │   │   │   ├── Intervention/
│   │   │   │   │   ├── AskUserQuestion/
│   │   │   │   │   │   ├── index.tsx
│   │   │   │   │   │   └── style.ts
│   │   │   │   │   └── index.ts
│   │   │   │   └── index.ts
│   │   │   ├── executor/
│   │   │   │   └── index.ts
│   │   │   ├── index.ts
│   │   │   ├── manifest.ts
│   │   │   ├── systemRole.ts
│   │   │   └── types.ts
│   │   ├── tsconfig.json
│   │   └── vitest.config.mts
│   ├── builtin-tool-web-browsing/
│   │   ├── package.json
│   │   └── src/
│   │       ├── ExecutionRuntime/
│   │       │   ├── index.test.ts
│   │       │   └── index.ts
│   │       ├── client/
│   │       │   ├── Inspector/
│   │       │   │   ├── CrawlMultiPages/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── CrawlSinglePage/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── Search/
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Placeholder/
│   │       │   │   ├── CrawlMultiPages.tsx
│   │       │   │   ├── CrawlSinglePage.tsx
│   │       │   │   ├── Search.tsx
│   │       │   │   └── index.ts
│   │       │   ├── Portal/
│   │       │   │   ├── PageContent/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── PageContents/
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── Search/
│   │       │   │   │   ├── Footer.tsx
│   │       │   │   │   ├── ResultList/
│   │       │   │   │   │   ├── SearchItem/
│   │       │   │   │   │   │   ├── CategoryAvatar.tsx
│   │       │   │   │   │   │   ├── TitleExtra.tsx
│   │       │   │   │   │   │   ├── Video.tsx
│   │       │   │   │   │   │   └── index.tsx
│   │       │   │   │   │   └── index.tsx
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.tsx
│   │       │   ├── Render/
│   │       │   │   ├── CrawlMultiPages.tsx
│   │       │   │   ├── CrawlSinglePage.tsx
│   │       │   │   ├── PageContent/
│   │       │   │   │   ├── Loading.tsx
│   │       │   │   │   ├── Result.tsx
│   │       │   │   │   └── index.tsx
│   │       │   │   ├── Search/
│   │       │   │   │   ├── ConfigForm/
│   │       │   │   │   │   ├── Form.tsx
│   │       │   │   │   │   ├── SearchXNGIcon.tsx
│   │       │   │   │   │   ├── index.tsx
│   │       │   │   │   │   └── style.tsx
│   │       │   │   │   ├── SearchQuery/
│   │       │   │   │   │   ├── SearchView.tsx
│   │       │   │   │   │   └── index.tsx
│   │       │   │   │   ├── SearchResult/
│   │       │   │   │   │   ├── SearchResultItem.tsx
│   │       │   │   │   │   ├── ShowMore.tsx
│   │       │   │   │   │   └── index.tsx
│   │       │   │   │   └── index.tsx
│   │       │   │   └── index.ts
│   │       │   ├── components/
│   │       │   │   ├── CategoryAvatar.tsx
│   │       │   │   ├── EngineAvatar.tsx
│   │       │   │   ├── SearchBar.tsx
│   │       │   │   └── index.ts
│   │       │   └── index.ts
│   │       ├── const.ts
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       ├── systemRole.ts
│   │       └── types.ts
│   ├── builtin-tool-web-onboarding/
│   │   ├── package.json
│   │   └── src/
│   │       ├── index.ts
│   │       ├── manifest.ts
│   │       └── types.ts
│   ├── builtin-tools/
│   │   ├── package.json
│   │   └── src/
│   │       ├── dynamicInterventionAudits.ts
│   │       ├── identifiers.ts
│   │       ├── index.ts
│   │       ├── inspectors.ts
│   │       ├── interventions.ts
│   │       ├── placeholders.ts
│   │       ├── portals.ts
│   │       ├── renders.ts
│   │       └── streamings.ts
│   ├── business/
│   │   ├── config/
│   │   │   ├── package.json
│   │   │   └── src/
│   │   │       ├── index.ts
│   │   │       ├── llm.ts
│   │   │       └── server/
│   │   │           ├── edge-config.ts
│   │   │           ├── index.ts
│   │   │           └── route.ts
│   │   ├── const/
│   │   │   ├── package.json
│   │   │   └── src/
│   │   │       ├── bedrock-model-mapping.ts
│   │   │       ├── branding.ts
│   │   │       ├── index.ts
│   │   │       ├── llm.ts
│   │   │       └── url.ts
│   │   └── model-runtime/
│   │       ├── package.json
│   │       └── src/
│   │           ├── index.ts
│   │           └── router-runtime-options.ts
│   ├── chat-adapter-feishu/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── adapter.ts
│   │   │   ├── api.ts
│   │   │   ├── crypto.ts
│   │   │   ├── format-converter.ts
│   │   │   ├── index.ts
│   │   │   └── types.ts
│   │   ├── tsconfig.json
│   │   └── tsup.config.ts
│   ├── chat-adapter-qq/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── adapter.ts
│   │   │   ├── api.ts
│   │   │   ├── crypto.ts
│   │   │   ├── format-converter.ts
│   │   │   ├── index.ts
│   │   │   └── types.ts
│   │   ├── tsconfig.json
│   │   └── tsup.config.ts
│   ├── chat-adapter-wechat/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── adapter.test.ts
│   │   │   ├── adapter.ts
│   │   │   ├── api.test.ts
│   │   │   ├── api.ts
│   │   │   ├── format-converter.test.ts
│   │   │   ├── format-converter.ts
│   │   │   ├── index.ts
│   │   │   └── types.ts
│   │   ├── tsconfig.json
│   │   ├── tsup.config.ts
│   │   └── vitest.config.mts
│   ├── config/
│   │   ├── package.json
│   │   └── src/
│   │       └── index.ts
│   ├── const/
│   │   ├── package.json
│   │   └── src/
│   │       ├── analytics.ts
│   │       ├── bot.ts
│   │       ├── cacheControl.ts
│   │       ├── currency.ts
│   │       ├── desktop.ts
│   │       ├── discover.ts
│   │       ├── editor.ts
│   │       ├── fetch.ts
│   │       ├── file.ts
│   │       ├── hotkeys.ts
│   │       ├── index.ts
│   │       ├── klavis.ts
│   │       ├── layoutTokens.test.ts
│   │       ├── layoutTokens.ts
│   │       ├── lobehubSkill.ts
│   │       ├── message.ts
│   │       ├── meta.ts
│   │       ├── plugin.test.ts
│   │       ├── plugin.ts
│   │       ├── protocol.ts
│   │       ├── rbac.ts
│   │       ├── recommendedSkill.ts
│   │       ├── session.ts
│   │       ├── settings/
│   │       │   ├── agent.ts
│   │       │   ├── common.ts
│   │       │   ├── group.ts
│   │       │   ├── hotkey.ts
│   │       │   ├── image.ts
│   │       │   ├── index.ts
│   │       │   ├── knowledge.ts
│   │       │   ├── llm.ts
│   │       │   ├── memory.ts
│   │       │   ├── notification.ts
│   │       │   ├── systemAgent.ts
│   │       │   ├── tool.ts
│   │       │   └── tts.ts
│   │       ├── theme.ts
│   │       ├── trace.ts
│   │       ├── url.ts
│   │       ├── user.ts
│   │       ├── userMemory.ts
│   │       ├── utils/
│   │       │   ├── merge.test.ts
│   │       │   └── merge.ts
│   │       └── version.ts
│   ├── context-engine/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── __tests__/
│   │   │   │   ├── metadata.types.test.ts
│   │   │   │   └── pipeline.test.ts
│   │   │   ├── base/
│   │   │   │   ├── BaseEveryUserContentProvider.ts
│   │   │   │   ├── BaseFirstUserContentProvider.ts
│   │   │   │   ├── BaseLastUserContentProvider.ts
│   │   │   │   ├── BaseProcessor.ts
│   │   │   │   ├── BaseProvider.ts
│   │   │   │   ├── BaseSystemRoleProvider.ts
│   │   │   │   ├── __tests__/
│   │   │   │   │   ├── BaseEveryUserContentProvider.test.ts
│   │   │   │   │   ├── BaseFirstUserContentProvider.test.ts
│   │   │   │   │   ├── BaseLastUserContentProvider.test.ts
│   │   │   │   │   ├── BaseProcessor.test.ts
│   │   │   │   │   └── BaseProvider.test.ts
│   │   │   │   └── constants.ts
│   │   │   ├── engine/
│   │   │   │   ├── index.ts
│   │   │   │   ├── messages/
│   │   │   │   │   ├── MessagesEngine.ts
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   └── MessagesEngine.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── types.ts
│   │   │   │   ├── skills/
│   │   │   │   │   ├── SkillEngine.ts
│   │   │   │   │   ├── SkillResolver.ts
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   ├── SkillEngine.test.ts
│   │   │   │   │   │   └── SkillResolver.test.ts
│   │   │   │   │   ├── buildStepSkillDelta.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── types.ts
│   │   │   │   ├── tools/
│   │   │   │   │   ├── ManifestLoader.ts
│   │   │   │   │   ├── ToolArgumentsRepairer.ts
│   │   │   │   │   ├── ToolNameResolver.ts
│   │   │   │   │   ├── ToolResolver.ts
│   │   │   │   │   ├── ToolsEngine.ts
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   ├── ManifestLoader.test.ts
│   │   │   │   │   │   ├── ToolArgumentsRepairer.test.ts
│   │   │   │   │   │   ├── ToolNameResolver.test.ts
│   │   │   │   │   │   ├── ToolResolver.test.ts
│   │   │   │   │   │   ├── ToolsEngine.test.ts
│   │   │   │   │   │   ├── buildStepToolDelta.test.ts
│   │   │   │   │   │   ├── enableCheckerFactory.test.ts
│   │   │   │   │   │   └── utils.test.ts
│   │   │   │   │   ├── buildStepToolDelta.ts
│   │   │   │   │   ├── enableCheckerFactory.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── types.ts
│   │   │   │   │   └── utils.ts
│   │   │   │   └── topicReference/
│   │   │   │       ├── __tests__/
│   │   │   │       │   └── resolveTopicReferences.test.ts
│   │   │   │       ├── index.ts
│   │   │   │       └── resolveTopicReferences.ts
│   │   │   ├── index.ts
│   │   │   ├── pipeline.ts
│   │   │   ├── processors/
│   │   │   │   ├── AgentCouncilFlatten.ts
│   │   │   │   ├── CompressedGroupRoleTransform.ts
│   │   │   │   ├── GroupMessageFlatten.ts
│   │   │   │   ├── GroupOrchestrationFilter.ts
│   │   │   │   ├── GroupRoleTransform.ts
│   │   │   │   ├── HistoryTruncate.ts
│   │   │   │   ├── InputTemplate.ts
│   │   │   │   ├── MessageCleanup.ts
│   │   │   │   ├── MessageContent.ts
│   │   │   │   ├── PlaceholderVariables.ts
│   │   │   │   ├── ReactionFeedback.ts
│   │   │   │   ├── SupervisorRoleRestore.ts
│   │   │   │   ├── TaskMessage.ts
│   │   │   │   ├── TasksFlatten.ts
│   │   │   │   ├── ToolCall.ts
│   │   │   │   ├── ToolMessageReorder.ts
│   │   │   │   ├── __tests__/
│   │   │   │   │   ├── AgentCouncilFlatten.test.ts
│   │   │   │   │   ├── GroupMessageFlatten.test.ts
│   │   │   │   │   ├── GroupOrchestrationFilter.test.ts
│   │   │   │   │   ├── GroupRoleTransform.test.ts
│   │   │   │   │   ├── HistoryTruncate.test.ts
│   │   │   │   │   ├── InputTemplate.test.ts
│   │   │   │   │   ├── MessageCleanup.test.ts
│   │   │   │   │   ├── MessageContent.test.ts
│   │   │   │   │   ├── PlaceholderVariables.test.ts
│   │   │   │   │   ├── ReactionFeedback.test.ts
│   │   │   │   │   ├── SupervisorRoleRestore.test.ts
│   │   │   │   │   ├── TaskMessage.test.ts
│   │   │   │   │   ├── TasksFlatten.test.ts
│   │   │   │   │   ├── ToolCall.test.ts
│   │   │   │   │   └── ToolMessageReorder.test.ts
│   │   │   │   └── index.ts
│   │   │   ├── providers/
│   │   │   │   ├── AgentBuilderContextInjector.ts
│   │   │   │   ├── AgentDocumentInjector/
│   │   │   │   │   ├── BeforeSystemInjector.ts
│   │   │   │   │   ├── ContextInjector.ts
│   │   │   │   │   ├── MessageInjector.ts
│   │   │   │   │   ├── SystemAppendInjector.ts
│   │   │   │   │   ├── SystemReplaceInjector.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── shared.ts
│   │   │   │   ├── AgentManagementContextInjector.ts
│   │   │   │   ├── BotPlatformContextInjector.ts
│   │   │   │   ├── DiscordContextProvider.ts
│   │   │   │   ├── EvalContextSystemInjector.ts
│   │   │   │   ├── ForceFinishSummaryInjector.ts
│   │   │   │   ├── GTDPlanInjector.ts
│   │   │   │   ├── GTDTodoInjector.ts
│   │   │   │   ├── GroupAgentBuilderContextInjector.ts
│   │   │   │   ├── GroupContextInjector.ts
│   │   │   │   ├── HistorySummary.ts
│   │   │   │   ├── KnowledgeInjector.ts
│   │   │   │   ├── PageEditorContextInjector.ts
│   │   │   │   ├── PageSelectionsInjector.ts
│   │   │   │   ├── SelectedSkillInjector.ts
│   │   │   │   ├── SkillContextProvider.ts
│   │   │   │   ├── SystemDateProvider.ts
│   │   │   │   ├── SystemRoleInjector.ts
│   │   │   │   ├── ToolDiscoveryProvider.ts
│   │   │   │   ├── ToolSystemRole.ts
│   │   │   │   ├── TopicReferenceContextInjector.ts
│   │   │   │   ├── UserMemoryInjector.ts
│   │   │   │   ├── __tests__/
│   │   │   │   │   ├── AgentDocumentInjector.test.ts
│   │   │   │   │   ├── AgentManagementContextInjector.test.ts
│   │   │   │   │   ├── DiscordContextProvider.test.ts
│   │   │   │   │   ├── EvalContextSystemInjector.test.ts
│   │   │   │   │   ├── GroupAgentBuilderContextInjector.test.ts
│   │   │   │   │   ├── GroupContextInjector.test.ts
│   │   │   │   │   ├── HistorySummaryProvider.test.ts
│   │   │   │   │   ├── KnowledgeInjector.test.ts
│   │   │   │   │   ├── PageEditorContextInjector.test.ts
│   │   │   │   │   ├── PageSelectionsInjector.test.ts
│   │   │   │   │   ├── SelectedSkillInjector.test.ts
│   │   │   │   │   ├── SkillContextProvider.test.ts
│   │   │   │   │   ├── SystemDateProvider.test.ts
│   │   │   │   │   ├── SystemRoleInjector.test.ts
│   │   │   │   │   ├── ToolSystemRoleProvider.test.ts
│   │   │   │   │   ├── TopicReferenceContextInjector.test.ts
│   │   │   │   │   ├── UserMemoryInjector.test.ts
│   │   │   │   │   └── __snapshots__/
│   │   │   │   │       ├── GroupContextInjector.test.ts.snap
│   │   │   │   │       ├── KnowledgeInjector.test.ts.snap
│   │   │   │   │       ├── SkillContextProvider.test.ts.snap
│   │   │   │   │       └── UserMemoryInjector.test.ts.snap
│   │   │   │   └── index.ts
│   │   │   └── types.ts
│   │   └── vitest.config.mts
│   ├── conversation-flow/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── __tests__/
│   │   │   │   ├── fixtures/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── inputs/
│   │   │   │   │   │   ├── agentCouncil/
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   ├── simple.json
│   │   │   │   │   │   │   └── with-supervisor-reply.json
│   │   │   │   │   │   ├── agentGroup/
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   ├── speak-different-agent.json
│   │   │   │   │   │   │   ├── supervisor-after-multi-tasks.json
│   │   │   │   │   │   │   └── supervisor-content-only.json
│   │   │   │   │   │   ├── assistant-chain-with-followup.json
│   │   │   │   │   │   ├── assistantGroup/
│   │   │   │   │   │   │   ├── assistant-with-tools.json
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   └── tools-with-branches.json
│   │   │   │   │   │   ├── branch/
│   │   │   │   │   │   │   ├── active-index-1.json
│   │   │   │   │   │   │   ├── assistant-branch.json
│   │   │   │   │   │   │   ├── assistant-group-branches.json
│   │   │   │   │   │   │   ├── assistant-user-branch.json
│   │   │   │   │   │   │   ├── conversation.json
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   ├── multi-assistant-group.json
│   │   │   │   │   │   │   └── nested.json
│   │   │   │   │   │   ├── compare/
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   ├── simple.json
│   │   │   │   │   │   │   └── with-tools.json
│   │   │   │   │   │   ├── compression/
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   ├── mixed-groups.json
│   │   │   │   │   │   │   ├── multiple-compressions.json
│   │   │   │   │   │   │   ├── parallel-group.json
│   │   │   │   │   │   │   └── simple-compression.json
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── linear-conversation.json
│   │   │   │   │   │   └── tasks/
│   │   │   │   │   │       ├── index.ts
│   │   │   │   │   │       ├── multi-tasks-with-summary.json
│   │   │   │   │   │       ├── simple.json
│   │   │   │   │   │       ├── single-task-with-tool-chain.json
│   │   │   │   │   │       ├── with-assistant-group.json
│   │   │   │   │   │       └── with-summary.json
│   │   │   │   │   └── outputs/
│   │   │   │   │       ├── agentCouncil/
│   │   │   │   │       │   ├── index.ts
│   │   │   │   │       │   ├── simple.json
│   │   │   │   │       │   └── with-supervisor-reply.json
│   │   │   │   │       ├── agentGroup/
│   │   │   │   │       │   ├── index.ts
│   │   │   │   │       │   └── speak-different-agent.json
│   │   │   │   │       ├── assistant-chain-with-followup.json
│   │   │   │   │       ├── assistantGroup/
│   │   │   │   │       │   ├── assistant-with-tools.json
│   │   │   │   │       │   ├── index.ts
│   │   │   │   │       │   └── tools-with-branches.json
│   │   │   │   │       ├── branch/
│   │   │   │   │       │   ├── active-index-1.json
│   │   │   │   │       │   ├── assistant-branch.json
│   │   │   │   │       │   ├── assistant-group-branches.json
│   │   │   │   │       │   ├── assistant-user-branch.json
│   │   │   │   │       │   ├── conversation.json
│   │   │   │   │       │   ├── index.ts
│   │   │   │   │       │   ├── multi-assistant-group.json
│   │   │   │   │       │   └── nested.json
│   │   │   │   │       ├── compare/
│   │   │   │   │       │   ├── index.ts
│   │   │   │   │       │   ├── simple.json
│   │   │   │   │       │   └── with-tools.json
│   │   │   │   │       ├── linear-conversation.json
│   │   │   │   │       └── tasks/
│   │   │   │   │           ├── index.ts
│   │   │   │   │           ├── simple.json
│   │   │   │   │           ├── single-task-with-tool-chain.json
│   │   │   │   │           └── with-summary.json
│   │   │   │   ├── indexing.test.ts
│   │   │   │   ├── parse.test.ts
│   │   │   │   └── structuring.test.ts
│   │   │   ├── index.ts
│   │   │   ├── indexing.ts
│   │   │   ├── parse.ts
│   │   │   ├── structuring.ts
│   │   │   ├── transformation/
│   │   │   │   ├── BranchResolver.ts
│   │   │   │   ├── ContextTreeBuilder.ts
│   │   │   │   ├── FlatListBuilder.ts
│   │   │   │   ├── MessageCollector.ts
│   │   │   │   ├── MessageTransformer.ts
│   │   │   │   ├── __tests__/
│   │   │   │   │   ├── BranchResolver.test.ts
│   │   │   │   │   ├── ContextTreeBuilder.test.ts
│   │   │   │   │   ├── FlatListBuilder.test.ts
│   │   │   │   │   ├── MessageCollector.test.ts
│   │   │   │   │   └── MessageTransformer.test.ts
│   │   │   │   └── index.ts
│   │   │   └── types/
│   │   │       ├── contextTree.ts
│   │   │       ├── flatMessageList.ts
│   │   │       ├── index.ts
│   │   │       └── shared.ts
│   │   └── vitest.config.mts
│   ├── database/
│   │   ├── migrations/
│   │   │   ├── 0000_init.sql
│   │   │   ├── 0001_add_client_id.sql
│   │   │   ├── 0002_amusing_puma.sql
│   │   │   ├── 0003_naive_echo.sql
│   │   │   ├── 0004_add_next_auth.sql
│   │   │   ├── 0005_pgvector.sql
│   │   │   ├── 0006_add_knowledge_base.sql
│   │   │   ├── 0007_fix_embedding_table.sql
│   │   │   ├── 0008_add_rag_evals.sql
│   │   │   ├── 0009_remove_unused_user_tables.sql
│   │   │   ├── 0010_add_accessed_at_and_clean_tables.sql
│   │   │   ├── 0011_add_topic_history_summary.sql
│   │   │   ├── 0012_add_thread.sql
│   │   │   ├── 0013_add_ai_infra.sql
│   │   │   ├── 0014_add_message_reasoning.sql
│   │   │   ├── 0015_add_message_search_metadata.sql
│   │   │   ├── 0016_add_message_index.sql
│   │   │   ├── 0017_add_user_id_to_tables.sql
│   │   │   ├── 0018_add_client_id_for_entities.sql
│   │   │   ├── 0019_add_hotkey_user_settings.sql
│   │   │   ├── 0020_add_oidc.sql
│   │   │   ├── 0021_add_agent_opening_settings.sql
│   │   │   ├── 0022_add_documents.sql
│   │   │   ├── 0023_remove_param_and_doubao.sql
│   │   │   ├── 0024_add_rbac_tables.sql
│   │   │   ├── 0025_add_provider_config.sql
│   │   │   ├── 0026_add_autovacuum_tuning.sql
│   │   │   ├── 0027_ai_image.sql
│   │   │   ├── 0028_oauth_handoffs.sql
│   │   │   ├── 0029_add_apikey_manage.sql
│   │   │   ├── 0030_add_group_chat.sql
│   │   │   ├── 0031_add_agent_index.sql
│   │   │   ├── 0032_improve_agents_field.sql
│   │   │   ├── 0033_add_table_index.sql
│   │   │   ├── 0034_fix_chat_group.sql
│   │   │   ├── 0035_add_virtual.sql
│   │   │   ├── 0036_add_group_messages.sql
│   │   │   ├── 0037_add_user_memory.sql
│   │   │   ├── 0038_add_image_user_settings.sql
│   │   │   ├── 0039_add_editor_data.sql
│   │   │   ├── 0040_improve_user_memory_field.sql
│   │   │   ├── 0041_improve_index.sql
│   │   │   ├── 0042_improve_agent_index.sql
│   │   │   ├── 0043_add_ai_model_settings.sql
│   │   │   ├── 0044_high_toxin.sql
│   │   │   ├── 0045_add_tool_intervention.sql
│   │   │   ├── 0046_add_parent_id.sql
│   │   │   ├── 0047_add_slug_document.sql
│   │   │   ├── 0048_add_editor_data.sql
│   │   │   ├── 0049_better_auth.sql
│   │   │   ├── 0050_thread_and_user_id.sql
│   │   │   ├── 0051_add_market_into_user_settings.sql
│   │   │   ├── 0052_topic_and_messages.sql
│   │   │   ├── 0053_better_auth_admin.sql
│   │   │   ├── 0054_better_auth_two_factor.sql
│   │   │   ├── 0055_rename_phone_number_to_phone.sql
│   │   │   ├── 0056_update_agent_slug_index.sql
│   │   │   ├── 0057_add_topic_user_memory_extract_status.sql
│   │   │   ├── 0058_add_source_into_user_plugins.sql
│   │   │   ├── 0059_add_normalized_email_indexes.sql
│   │   │   ├── 0060_add_user_last_active_at.sql
│   │   │   ├── 0061_add_document_and_memory_index.sql
│   │   │   ├── 0062_add_more_index.sql
│   │   │   ├── 0063_add_columns_for_several_tables.sql
│   │   │   ├── 0064_add_agents_session_group_id.sql
│   │   │   ├── 0065_add_document_fields.sql
│   │   │   ├── 0065_add_passkey.sql
│   │   │   ├── 0066_add_document_fields.sql
│   │   │   ├── 0067_add_agent_cron_tables.sql
│   │   │   ├── 0068_update_group_data.sql
│   │   │   ├── 0069_add_topic_shares_table.sql
│   │   │   ├── 0070_add_user_memory_activities.sql
│   │   │   ├── 0071_add_async_task_extend.sql
│   │   │   ├── 0072_add_market_identifier_chat_group.sql
│   │   │   ├── 0073_add_message_group_metadata.sql
│   │   │   ├── 0074_add_fk_indexes_for_cascade_delete.sql
│   │   │   ├── 0075_add_user_memory_persona.sql
│   │   │   ├── 0076_add_message_group_index.sql
│   │   │   ├── 0077_add_agent_skills.sql
│   │   │   ├── 0078_added_id_nanoid_for_replacing_id.sql
│   │   │   ├── 0079_update_id_nanoid_from_casted_id.sql
│   │   │   ├── 0080_add_constraint_unique_not_null_to_id_nanoid.sql
│   │   │   ├── 0081_switch_forgien_key_to_id_nanoid.sql
│   │   │   ├── 0082_set_id_nanoid_as_primary.sql
│   │   │   ├── 0083_remove_id_seq_identity_column.sql
│   │   │   ├── 0084_rename_id_nanoid_to_id.sql
│   │   │   ├── 0085_remove_id_unique_constraint.sql
│   │   │   ├── 0086_video_generation_schema.sql
│   │   │   ├── 0087_add_eval_benchmark.sql
│   │   │   ├── 0088_fix_benchmark_add_bot_provider.sql
│   │   │   ├── 0089_add_api_key_hash.sql
│   │   │   ├── 0090_enable_pg_search.sql
│   │   │   ├── 0091_topics_add_description.sql
│   │   │   ├── 0092_add_agent_documents.sql
│   │   │   ├── 0093_add_bm25_indexes_with_icu.sql
│   │   │   ├── 0094_agent_bot_providers_add_settings.sql
│   │   │   ├── 0095_add_agent_task_system.sql
│   │   │   ├── 0096_add_notification_tables.sql
│   │   │   ├── 0097_add_agent_onboarding.sql
│   │   │   └── meta/
│   │   │       ├── 0000_snapshot.json
│   │   │       ├── 0001_snapshot.json
│   │   │       ├── 0002_snapshot.json
│   │   │       ├── 0003_snapshot.json
│   │   │       ├── 0004_snapshot.json
│   │   │       ├── 0005_snapshot.json
│   │   │       ├── 0006_snapshot.json
│   │   │       ├── 0007_snapshot.json
│   │   │       ├── 0008_snapshot.json
│   │   │       ├── 0009_snapshot.json
│   │   │       ├── 0010_snapshot.json
│   │   │       ├── 0011_snapshot.json
│   │   │       ├── 0012_snapshot.json
│   │   │       ├── 0013_snapshot.json
│   │   │       ├── 0014_snapshot.json
│   │   │       ├── 0015_snapshot.json
│   │   │       ├── 0016_snapshot.json
│   │   │       ├── 0017_snapshot.json
│   │   │       ├── 0018_snapshot.json
│   │   │       ├── 0019_snapshot.json
│   │   │       ├── 0020_snapshot.json
│   │   │       ├── 0021_snapshot.json
│   │   │       ├── 0022_snapshot.json
│   │   │       ├── 0023_snapshot.json
│   │   │       ├── 0024_snapshot.json
│   │   │       ├── 0025_snapshot.json
│   │   │       ├── 0026_snapshot.json
│   │   │       ├── 0027_snapshot.json
│   │   │       ├── 0028_snapshot.json
│   │   │       ├── 0029_snapshot.json
│   │   │       ├── 0030_snapshot.json
│   │   │       ├── 0031_snapshot.json
│   │   │       ├── 0032_snapshot.json
│   │   │       ├── 0033_snapshot.json
│   │   │       ├── 0034_snapshot.json
│   │   │       ├── 0035_snapshot.json
│   │   │       ├── 0036_snapshot.json
│   │   │       ├── 0037_snapshot.json
│   │   │       ├── 0038_snapshot.json
│   │   │       ├── 0039_snapshot.json
│   │   │       ├── 0040_snapshot.json
│   │   │       ├── 0041_snapshot.json
│   │   │       ├── 0042_snapshot.json
│   │   │       ├── 0043_snapshot.json
│   │   │       ├── 0044_snapshot.json
│   │   │       ├── 0045_snapshot.json
│   │   │       ├── 0046_snapshot.json
│   │   │       ├── 0047_snapshot.json
│   │   │       ├── 0048_snapshot.json
│   │   │       ├── 0049_snapshot.json
│   │   │       ├── 0050_snapshot.json
│   │   │       ├── 0051_snapshot.json
│   │   │       ├── 0052_snapshot.json
│   │   │       ├── 0053_snapshot.json
│   │   │       ├── 0054_snapshot.json
│   │   │       ├── 0055_snapshot.json
│   │   │       ├── 0056_snapshot.json
│   │   │       ├── 0057_snapshot.json
│   │   │       ├── 0058_snapshot.json
│   │   │       ├── 0059_snapshot.json
│   │   │       ├── 0060_snapshot.json
│   │   │       ├── 0061_snapshot.json
│   │   │       ├── 0062_snapshot.json
│   │   │       ├── 0063_snapshot.json
│   │   │       ├── 0064_snapshot.json
│   │   │       ├── 0065_snapshot.json
│   │   │       ├── 0066_snapshot.json
│   │   │       ├── 0067_snapshot.json
│   │   │       ├── 0068_snapshot.json
│   │   │       ├── 0069_snapshot.json
│   │   │       ├── 0070_snapshot.json
│   │   │       ├── 0071_snapshot.json
│   │   │       ├── 0072_snapshot.json
│   │   │       ├── 0073_snapshot.json
│   │   │       ├── 0074_snapshot.json
│   │   │       ├── 0075_snapshot.json
│   │   │       ├── 0076_snapshot.json
│   │   │       ├── 0077_snapshot.json
│   │   │       ├── 0078_snapshot.json
│   │   │       ├── 0079_snapshot.json
│   │   │       ├── 0080_snapshot.json
│   │   │       ├── 0081_snapshot.json
│   │   │       ├── 0082_snapshot.json
│   │   │       ├── 0083_snapshot.json
│   │   │       ├── 0084_snapshot.json
│   │   │       ├── 0085_snapshot.json
│   │   │       ├── 0086_snapshot.json
│   │   │       ├── 0087_snapshot.json
│   │   │       ├── 0088_snapshot.json
│   │   │       ├── 0089_snapshot.json
│   │   │       ├── 0090_snapshot.json
│   │   │       ├── 0091_snapshot.json
│   │   │       ├── 0092_snapshot.json
│   │   │       ├── 0093_snapshot.json
│   │   │       ├── 0094_snapshot.json
│   │   │       ├── 0095_snapshot.json
│   │   │       ├── 0096_snapshot.json
│   │   │       ├── 0097_snapshot.json
│   │   │       └── _journal.json
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── core/
│   │   │   │   ├── db-adaptor.ts
│   │   │   │   ├── getTestDB.ts
│   │   │   │   └── web-server.ts
│   │   │   ├── index.ts
│   │   │   ├── models/
│   │   │   │   ├── __tests__/
│   │   │   │   │   ├── _test_template.ts
│   │   │   │   │   ├── agent.test.ts
│   │   │   │   │   ├── agentBotProvider.test.ts
│   │   │   │   │   ├── agentCronJob.test.ts
│   │   │   │   │   ├── agentSkill.test.ts
│   │   │   │   │   ├── aiModel.test.ts
│   │   │   │   │   ├── aiProvider.test.ts
│   │   │   │   │   ├── apiKey.test.ts
│   │   │   │   │   ├── asyncTask.test.ts
│   │   │   │   │   ├── brief.test.ts
│   │   │   │   │   ├── chatGroup.test.ts
│   │   │   │   │   ├── chunk.test.ts
│   │   │   │   │   ├── document.test.ts
│   │   │   │   │   ├── drizzleMigration.test.ts
│   │   │   │   │   ├── embedding.test.ts
│   │   │   │   │   ├── file.test.ts
│   │   │   │   │   ├── fixtures/
│   │   │   │   │   │   └── embedding.ts
│   │   │   │   │   ├── generation.test.ts
│   │   │   │   │   ├── generationBatch.test.ts
│   │   │   │   │   ├── generationTopic.test.ts
│   │   │   │   │   ├── knowledgeBase.test.ts
│   │   │   │   │   ├── messages/
│   │   │   │   │   │   ├── message.create.test.ts
│   │   │   │   │   │   ├── message.delete.test.ts
│   │   │   │   │   │   ├── message.query.test.ts
│   │   │   │   │   │   ├── message.stats.test.ts
│   │   │   │   │   │   ├── message.thread-query.test.ts
│   │   │   │   │   │   ├── message.update.test.ts
│   │   │   │   │   │   ├── messageWithTask.test.ts
│   │   │   │   │   │   ├── queryWithMessageGroup.perf.test.ts
│   │   │   │   │   │   └── queryWithMessageGroup.test.ts
│   │   │   │   │   ├── oauthHandoff.test.ts
│   │   │   │   │   ├── plugin.test.ts
│   │   │   │   │   ├── session.test.ts
│   │   │   │   │   ├── sessionGroup.test.ts
│   │   │   │   │   ├── task.test.ts
│   │   │   │   │   ├── taskTopic.test.ts
│   │   │   │   │   ├── thread.test.ts
│   │   │   │   │   ├── topicDocument.test.ts
│   │   │   │   │   ├── topicShare.test.ts
│   │   │   │   │   ├── topics/
│   │   │   │   │   │   ├── topic.create.test.ts
│   │   │   │   │   │   ├── topic.delete.test.ts
│   │   │   │   │   │   ├── topic.memoryExtractor.test.ts
│   │   │   │   │   │   ├── topic.query.test.ts
│   │   │   │   │   │   ├── topic.stats.test.ts
│   │   │   │   │   │   └── topic.update.test.ts
│   │   │   │   │   ├── user.test.ts
│   │   │   │   │   ├── userMemories.test.ts
│   │   │   │   │   └── userMemoryIdentity.test.ts
│   │   │   │   ├── _template.ts
│   │   │   │   ├── agent.ts
│   │   │   │   ├── agentBotProvider.ts
│   │   │   │   ├── agentCronJob.ts
│   │   │   │   ├── agentDocuments/
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   ├── agentDocument.test.ts
│   │   │   │   │   │   └── template.test.ts
│   │   │   │   │   ├── agentDocument.ts
│   │   │   │   │   ├── filename.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── policy/
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   ├── checks.test.ts
│   │   │   │   │   │   │   └── loadPolicy.test.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── loadPolicy.ts
│   │   │   │   │   │   ├── loadRule.ts
│   │   │   │   │   │   ├── permission.ts
│   │   │   │   │   │   └── policy.ts
│   │   │   │   │   └── types.ts
│   │   │   │   ├── agentEval/
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   ├── benchmark.test.ts
│   │   │   │   │   │   ├── dataset.test.ts
│   │   │   │   │   │   ├── run.test.ts
│   │   │   │   │   │   ├── runTopic.test.ts
│   │   │   │   │   │   └── testCase.test.ts
│   │   │   │   │   ├── benchmark.ts
│   │   │   │   │   ├── dataset.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── run.ts
│   │   │   │   │   ├── runTopic.ts
│   │   │   │   │   └── testCase.ts
│   │   │   │   ├── agentSkill.ts
│   │   │   │   ├── aiModel.ts
│   │   │   │   ├── aiProvider.ts
│   │   │   │   ├── apiKey.ts
│   │   │   │   ├── asyncTask.ts
│   │   │   │   ├── brief.ts
│   │   │   │   ├── chatGroup.ts
│   │   │   │   ├── chunk.ts
│   │   │   │   ├── document.ts
│   │   │   │   ├── drizzleMigration.ts
│   │   │   │   ├── embedding.ts
│   │   │   │   ├── file.ts
│   │   │   │   ├── generation.ts
│   │   │   │   ├── generationBatch.ts
│   │   │   │   ├── generationTopic.ts
│   │   │   │   ├── knowledgeBase.ts
│   │   │   │   ├── message.ts
│   │   │   │   ├── notification.ts
│   │   │   │   ├── oauthHandoff.ts
│   │   │   │   ├── plugin.ts
│   │   │   │   ├── ragEval/
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   ├── dataset.test.ts
│   │   │   │   │   │   ├── datasetRecord.test.ts
│   │   │   │   │   │   ├── evaluation.test.ts
│   │   │   │   │   │   └── evaluationRecord.test.ts
│   │   │   │   │   ├── dataset.ts
│   │   │   │   │   ├── datasetRecord.ts
│   │   │   │   │   ├── evaluation.ts
│   │   │   │   │   ├── evaluationRecord.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── rbac.ts
│   │   │   │   ├── session.ts
│   │   │   │   ├── sessionGroup.ts
│   │   │   │   ├── task.ts
│   │   │   │   ├── taskTopic.ts
│   │   │   │   ├── thread.ts
│   │   │   │   ├── topic.ts
│   │   │   │   ├── topicDocument.ts
│   │   │   │   ├── topicShare.ts
│   │   │   │   ├── user.ts
│   │   │   │   └── userMemory/
│   │   │   │       ├── __tests__/
│   │   │   │       │   ├── activity.test.ts
│   │   │   │       │   ├── context.test.ts
│   │   │   │       │   ├── experience.test.ts
│   │   │   │       │   ├── identity.test.ts
│   │   │   │       │   ├── model.test.ts
│   │   │   │       │   ├── persona.test.ts
│   │   │   │       │   └── preference.test.ts
│   │   │   │       ├── activity.ts
│   │   │   │       ├── context.ts
│   │   │   │       ├── experience.ts
│   │   │   │       ├── identity.ts
│   │   │   │       ├── index.ts
│   │   │   │       ├── model.ts
│   │   │   │       ├── persona.ts
│   │   │   │       ├── preference.ts
│   │   │   │       └── sources/
│   │   │   │           ├── __tests__/
│   │   │   │           │   └── benchmarkLoCoMo.test.ts
│   │   │   │           ├── benchmarkLoCoMo.ts
│   │   │   │           ├── index.ts
│   │   │   │           └── shared.ts
│   │   │   ├── repositories/
│   │   │   │   ├── agentGroup/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── agentMigration/
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   └── agentMigrationRepo.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── aiInfra/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── compression/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── dataExporter/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── dataImporter/
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   ├── fixtures/
│   │   │   │   │   │   │   ├── agents.json
│   │   │   │   │   │   │   ├── agentsToSessions.json
│   │   │   │   │   │   │   ├── topic.json
│   │   │   │   │   │   │   ├── userSettings.json
│   │   │   │   │   │   │   └── with-client-id.json
│   │   │   │   │   │   └── index.test.ts
│   │   │   │   │   ├── deprecated/
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   ├── fixtures/
│   │   │   │   │   │   │   │   └── messages.json
│   │   │   │   │   │   │   └── index.test.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── home/
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   └── index.test.ts
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── knowledge/
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   └── index.test.ts
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── search/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── topicImporter/
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   ├── fixtures/
│   │   │   │   │   │   │   └── exported-topic.json
│   │   │   │   │   │   └── importTopic.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   └── userMemory/
│   │   │   │       ├── UserMemoryTopicRepository.ts
│   │   │   │       ├── __tests__/
│   │   │   │       │   └── UserMemoryTopicRepository.test.ts
│   │   │   │       └── index.ts
│   │   │   ├── schemas/
│   │   │   │   ├── _helpers.ts
│   │   │   │   ├── agent.ts
│   │   │   │   ├── agentBotProvider.ts
│   │   │   │   ├── agentCronJob.ts
│   │   │   │   ├── agentDocuments.ts
│   │   │   │   ├── agentEvals.ts
│   │   │   │   ├── agentSkill.ts
│   │   │   │   ├── aiInfra.ts
│   │   │   │   ├── apiKey.ts
│   │   │   │   ├── asyncTask.ts
│   │   │   │   ├── betterAuth.ts
│   │   │   │   ├── chatGroup.ts
│   │   │   │   ├── file.ts
│   │   │   │   ├── generation.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── message.ts
│   │   │   │   ├── nextauth.ts
│   │   │   │   ├── notification.ts
│   │   │   │   ├── oidc.ts
│   │   │   │   ├── rag.ts
│   │   │   │   ├── ragEvals.ts
│   │   │   │   ├── rbac.ts
│   │   │   │   ├── relations.ts
│   │   │   │   ├── session.ts
│   │   │   │   ├── task.ts
│   │   │   │   ├── topic.ts
│   │   │   │   ├── user.ts
│   │   │   │   └── userMemories/
│   │   │   │       ├── index.ts
│   │   │   │       └── persona.ts
│   │   │   ├── server/
│   │   │   │   ├── index.ts
│   │   │   │   └── models/
│   │   │   │       └── __tests__/
│   │   │   │           ├── adapter.test.ts
│   │   │   │           └── user.test.ts
│   │   │   ├── type.ts
│   │   │   ├── types/
│   │   │   │   ├── chatGroup.ts
│   │   │   │   └── generation.ts
│   │   │   └── utils/
│   │   │       ├── bm25.test.ts
│   │   │       ├── bm25.ts
│   │   │       ├── columns.ts
│   │   │       ├── genWhere.test.ts
│   │   │       ├── genWhere.ts
│   │   │       ├── idGenerator.test.ts
│   │   │       └── idGenerator.ts
│   │   ├── tests/
│   │   │   ├── setup-db.ts
│   │   │   └── test-utils.ts
│   │   ├── vitest.config.mts
│   │   └── vitest.config.server.mts
│   ├── desktop-bridge/
│   │   ├── package.json
│   │   └── src/
│   │       ├── index.ts
│   │       └── routeVariants.ts
│   ├── device-gateway-client/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── client.test.ts
│   │   │   ├── client.ts
│   │   │   ├── http.test.ts
│   │   │   ├── http.ts
│   │   │   ├── index.ts
│   │   │   └── types.ts
│   │   ├── tsconfig.json
│   │   └── vitest.config.mts
│   ├── edge-config/
│   │   ├── package.json
│   │   └── src/
│   │       ├── index.ts
│   │       └── types.ts
│   ├── editor-runtime/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── EditorRuntime.ts
│   │   │   ├── __tests__/
│   │   │   │   ├── EditorRuntime.real.test.ts
│   │   │   │   ├── EditorRuntime.test.ts
│   │   │   │   ├── __snapshots__/
│   │   │   │   │   ├── EditorRuntime.real.test.ts.snap
│   │   │   │   │   └── EditorRuntime.test.ts.snap
│   │   │   │   └── fixtures/
│   │   │   │       ├── edit-all.json
│   │   │   │       ├── remove-then-add.json
│   │   │   │       └── remove.json
│   │   │   ├── index.ts
│   │   │   └── types.ts
│   │   └── vitest.config.mts
│   ├── electron-client-ipc/
│   │   ├── README.md
│   │   ├── README.zh-CN.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── events/
│   │   │   │   ├── gatewayConnection.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── navigation.ts
│   │   │   │   ├── protocol.ts
│   │   │   │   ├── remoteServer.ts
│   │   │   │   ├── system.ts
│   │   │   │   ├── update.ts
│   │   │   │   └── windows.ts
│   │   │   ├── index.ts
│   │   │   ├── ipc.test.ts
│   │   │   ├── ipc.ts
│   │   │   ├── streamInvoke.ts
│   │   │   ├── types/
│   │   │   │   ├── dataSync.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── localSystem.ts
│   │   │   │   ├── mcpInstall.ts
│   │   │   │   ├── notification.ts
│   │   │   │   ├── proxy.ts
│   │   │   │   ├── proxyTRPCRequest.ts
│   │   │   │   ├── route.ts
│   │   │   │   ├── shortcut.ts
│   │   │   │   ├── system.ts
│   │   │   │   ├── toolDetector.ts
│   │   │   │   ├── tray.ts
│   │   │   │   ├── update.ts
│   │   │   │   ├── upload.ts
│   │   │   │   └── window.ts
│   │   │   ├── useWatchBroadcast.ts
│   │   │   └── utils/
│   │   │       ├── headers.ts
│   │   │       └── request.ts
│   │   └── vitest.config.mts
│   ├── electron-server-ipc/
│   │   ├── README.md
│   │   ├── README.zh-CN.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── const.ts
│   │   │   ├── index.ts
│   │   │   ├── ipcClient.test.ts
│   │   │   ├── ipcClient.ts
│   │   │   ├── ipcServer.test.ts
│   │   │   ├── ipcServer.ts
│   │   │   └── types/
│   │   │       ├── file.ts
│   │   │       └── index.ts
│   │   └── vitest.config.mts
│   ├── eval-dataset-parser/
│   │   ├── __tests__/
│   │   │   ├── detectFormat.edge.test.ts
│   │   │   ├── detectFormat.test.ts
│   │   │   ├── fixtures/
│   │   │   │   ├── sample.csv
│   │   │   │   ├── sample.json
│   │   │   │   └── sample.jsonl
│   │   │   ├── parseDataset.edge.test.ts
│   │   │   ├── parseDataset.test.ts
│   │   │   └── parsers.test.ts
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── detect.ts
│   │   │   ├── index.ts
│   │   │   ├── parseDataset.ts
│   │   │   ├── parsers/
│   │   │   │   ├── csv.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── json.ts
│   │   │   │   ├── jsonl.ts
│   │   │   │   └── xlsx.ts
│   │   │   └── types.ts
│   │   └── vitest.config.mts
│   ├── eval-rubric/
│   │   ├── __tests__/
│   │   │   ├── evaluate.test.ts
│   │   │   └── extractors.test.ts
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── evaluate.ts
│   │   │   ├── extractors.ts
│   │   │   ├── index.ts
│   │   │   ├── matchers/
│   │   │   │   ├── __tests__/
│   │   │   │   │   ├── anyOf.test.ts
│   │   │   │   │   ├── contains.test.ts
│   │   │   │   │   ├── endsWith.test.ts
│   │   │   │   │   ├── equals.test.ts
│   │   │   │   │   ├── jsonSchema.test.ts
│   │   │   │   │   ├── levenshtein.test.ts
│   │   │   │   │   ├── llmRubric.test.ts
│   │   │   │   │   ├── numeric.test.ts
│   │   │   │   │   ├── regex.test.ts
│   │   │   │   │   └── startsWith.test.ts
│   │   │   │   ├── anyOf.ts
│   │   │   │   ├── contains.ts
│   │   │   │   ├── endsWith.ts
│   │   │   │   ├── equals.ts
│   │   │   │   ├── external.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── jsonSchema.ts
│   │   │   │   ├── levenshtein.ts
│   │   │   │   ├── llmEq.ts
│   │   │   │   ├── llmRubric.ts
│   │   │   │   ├── numeric.ts
│   │   │   │   ├── regex.ts
│   │   │   │   ├── startsWith.ts
│   │   │   │   └── types.ts
│   │   │   └── normalize.ts
│   │   └── tsconfig.json
│   ├── fetch-sse/
│   │   ├── package.json
│   │   └── src/
│   │       ├── __tests__/
│   │       │   ├── fetchSSE.test.ts
│   │       │   ├── headers.test.ts
│   │       │   ├── parseError.test.ts
│   │       │   └── request.test.ts
│   │       ├── fetchSSE.ts
│   │       ├── headers.ts
│   │       ├── index.ts
│   │       ├── parseError.ts
│   │       └── request.ts
│   ├── file-loaders/
│   │   ├── README.md
│   │   ├── README.zh-CN.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── blackList.ts
│   │   │   ├── index.ts
│   │   │   ├── loadFile.test.ts
│   │   │   ├── loadFile.ts
│   │   │   ├── loaders/
│   │   │   │   ├── doc/
│   │   │   │   │   ├── __snapshots__/
│   │   │   │   │   │   └── index.test.ts.snap
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── docx/
│   │   │   │   │   ├── __snapshots__/
│   │   │   │   │   │   └── index.test.ts.snap
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── excel/
│   │   │   │   │   ├── __snapshots__/
│   │   │   │   │   │   └── index.test.ts.snap
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── prompt.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── pdf/
│   │   │   │   │   ├── __snapshots__/
│   │   │   │   │   │   └── index.test.ts.snap
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── prompt.ts
│   │   │   │   ├── pptx/
│   │   │   │   │   ├── __snapshots__/
│   │   │   │   │   │   └── index.test.ts.snap
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   └── text/
│   │   │   │       ├── __snapshots__/
│   │   │   │       │   └── index.test.ts.snap
│   │   │   │       ├── fixtures/
│   │   │   │       │   └── test.txt
│   │   │   │       ├── index.test.ts
│   │   │   │       └── index.ts
│   │   │   ├── types/
│   │   │   │   └── word-extractor.d.ts
│   │   │   ├── types.ts
│   │   │   └── utils/
│   │   │       ├── isTextReadableFile.test.ts
│   │   │       ├── isTextReadableFile.ts
│   │   │       ├── parser-utils.test.ts
│   │   │       └── parser-utils.ts
│   │   ├── test/
│   │   │   ├── __snapshots__/
│   │   │   │   └── loaders.test.ts.snap
│   │   │   ├── fixtures/
│   │   │   │   ├── test.csv
│   │   │   │   ├── test.epub
│   │   │   │   ├── test.md
│   │   │   │   └── test.txt
│   │   │   ├── loaders.test.ts
│   │   │   └── setup.ts
│   │   └── vitest.config.mts
│   ├── local-file-shell/
│   │   ├── package.json
│   │   └── src/
│   │       ├── file/
│   │       │   ├── __tests__/
│   │       │   │   └── file.test.ts
│   │       │   ├── edit.ts
│   │       │   ├── glob.ts
│   │       │   ├── grep.ts
│   │       │   ├── index.ts
│   │       │   ├── list.ts
│   │       │   ├── move.ts
│   │       │   ├── read.ts
│   │       │   ├── rename.ts
│   │       │   ├── search.ts
│   │       │   └── write.ts
│   │       ├── index.ts
│   │       ├── shell/
│   │       │   ├── __tests__/
│   │       │   │   ├── process-manager.test.ts
│   │       │   │   ├── runner.test.ts
│   │       │   │   └── utils.test.ts
│   │       │   ├── index.ts
│   │       │   ├── process-manager.ts
│   │       │   ├── runner.ts
│   │       │   └── utils.ts
│   │       └── types.ts
│   ├── memory-user-memory/
│   │   ├── .gitignore
│   │   ├── benchmarks/
│   │   │   └── locomo/
│   │   │       ├── README.md
│   │   │       └── run.ts
│   │   ├── package.json
│   │   ├── promptfoo/
│   │   │   ├── evals/
│   │   │   │   ├── activity/
│   │   │   │   │   ├── basic/
│   │   │   │   │   │   ├── buildMessages.ts
│   │   │   │   │   │   ├── eval.yaml
│   │   │   │   │   │   ├── prompt.ts
│   │   │   │   │   │   └── tests/
│   │   │   │   │   │       └── cases.ts
│   │   │   │   │   └── locomo/
│   │   │   │   │       ├── buildMessages.ts
│   │   │   │   │       ├── eval.yaml
│   │   │   │   │       ├── prompt.ts
│   │   │   │   │       └── tests/
│   │   │   │   │           ├── benchmark-locomo-payload-conv-26.json
│   │   │   │   │           └── cases.ts
│   │   │   │   ├── identity/
│   │   │   │   │   └── with-s3-trace/
│   │   │   │   │       ├── buildMessages.ts
│   │   │   │   │       ├── eval.yaml
│   │   │   │   │       ├── prompt.ts
│   │   │   │   │       └── tests/
│   │   │   │   │           └── cases.ts
│   │   │   │   └── persona/
│   │   │   │       ├── eval.yaml
│   │   │   │       ├── prompt.ts
│   │   │   │       └── tests/
│   │   │   │           └── cases.ts
│   │   │   └── response-formats/
│   │   │       ├── activity.json
│   │   │       ├── context.json
│   │   │       ├── experience.json
│   │   │       ├── identity.json
│   │   │       ├── persona-tools.json
│   │   │       ├── persona.json
│   │   │       └── preference.json
│   │   ├── promptfooconfig.yaml
│   │   ├── scripts/
│   │   │   └── generate-response-formats.ts
│   │   ├── src/
│   │   │   ├── converters/
│   │   │   │   ├── index.ts
│   │   │   │   └── locomo.ts
│   │   │   ├── extractors/
│   │   │   │   ├── activity.ts
│   │   │   │   ├── base.ts
│   │   │   │   ├── context.test.ts
│   │   │   │   ├── context.ts
│   │   │   │   ├── experience.test.ts
│   │   │   │   ├── experience.ts
│   │   │   │   ├── gatekeeper.test.ts
│   │   │   │   ├── gatekeeper.ts
│   │   │   │   ├── identity.test.ts
│   │   │   │   ├── identity.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── persona.test.ts
│   │   │   │   ├── persona.ts
│   │   │   │   ├── preference.test.ts
│   │   │   │   └── preference.ts
│   │   │   ├── index.ts
│   │   │   ├── prompts/
│   │   │   │   ├── gatekeeper.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── layers/
│   │   │   │   │   ├── activity.ts
│   │   │   │   │   ├── context.ts
│   │   │   │   │   ├── experience.ts
│   │   │   │   │   ├── identity.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── preference.ts
│   │   │   │   └── persona.ts
│   │   │   ├── providers/
│   │   │   │   ├── benchmarkLocomo.test.ts
│   │   │   │   ├── benchmarkLocomo.ts
│   │   │   │   ├── chatTopic.test.ts
│   │   │   │   ├── chatTopic.ts
│   │   │   │   ├── existingUserMemory.test.ts
│   │   │   │   ├── existingUserMemory.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── tests/
│   │   │   │       └── benchmark-locomo-converted.json
│   │   │   ├── schemas/
│   │   │   │   ├── activity.ts
│   │   │   │   ├── common.ts
│   │   │   │   ├── context.ts
│   │   │   │   ├── experience.ts
│   │   │   │   ├── gatekeeper.ts
│   │   │   │   ├── identity.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── preference.ts
│   │   │   ├── services/
│   │   │   │   └── extractExecutor.ts
│   │   │   ├── types.ts
│   │   │   └── utils/
│   │   │       └── zod.ts
│   │   └── vitest.config.ts
│   ├── model-bank/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── aiModels/
│   │   │   │   ├── ai21.ts
│   │   │   │   ├── ai302.ts
│   │   │   │   ├── ai360.ts
│   │   │   │   ├── aihubmix.ts
│   │   │   │   ├── akashchat.ts
│   │   │   │   ├── anthropic.ts
│   │   │   │   ├── azure.ts
│   │   │   │   ├── azureai.ts
│   │   │   │   ├── baichuan.ts
│   │   │   │   ├── bailianCodingPlan.ts
│   │   │   │   ├── bedrock.ts
│   │   │   │   ├── bfl.ts
│   │   │   │   ├── cerebras.ts
│   │   │   │   ├── cloudflare.ts
│   │   │   │   ├── cohere.ts
│   │   │   │   ├── cometapi.ts
│   │   │   │   ├── comfyui.ts
│   │   │   │   ├── deepseek.ts
│   │   │   │   ├── fal.ts
│   │   │   │   ├── fireworksai.ts
│   │   │   │   ├── giteeai.ts
│   │   │   │   ├── github.ts
│   │   │   │   ├── githubCopilot.ts
│   │   │   │   ├── glmCodingPlan.ts
│   │   │   │   ├── google.ts
│   │   │   │   ├── groq.ts
│   │   │   │   ├── higress.ts
│   │   │   │   ├── huggingface.ts
│   │   │   │   ├── hunyuan.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── infiniai.ts
│   │   │   │   ├── internlm.ts
│   │   │   │   ├── jina.ts
│   │   │   │   ├── kimiCodingPlan.ts
│   │   │   │   ├── lmstudio.ts
│   │   │   │   ├── lobehub/
│   │   │   │   │   ├── chat/
│   │   │   │   │   │   ├── anthropic.ts
│   │   │   │   │   │   ├── deepseek.ts
│   │   │   │   │   │   ├── google.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── minimax.ts
│   │   │   │   │   │   ├── moonshot.ts
│   │   │   │   │   │   ├── openai.ts
│   │   │   │   │   │   ├── xai.ts
│   │   │   │   │   │   ├── xiaomimimo.ts
│   │   │   │   │   │   └── zhipu.ts
│   │   │   │   │   ├── embedding.ts
│   │   │   │   │   ├── image.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── utils.ts
│   │   │   │   │   └── video.ts
│   │   │   │   ├── longcat.ts
│   │   │   │   ├── minimax.ts
│   │   │   │   ├── minimaxCodingPlan.ts
│   │   │   │   ├── mistral.ts
│   │   │   │   ├── modelscope.ts
│   │   │   │   ├── moonshot.ts
│   │   │   │   ├── nebius.ts
│   │   │   │   ├── newapi.ts
│   │   │   │   ├── novita.ts
│   │   │   │   ├── nvidia.ts
│   │   │   │   ├── ollama.ts
│   │   │   │   ├── ollamacloud.ts
│   │   │   │   ├── openai.ts
│   │   │   │   ├── openrouter.ts
│   │   │   │   ├── perplexity.ts
│   │   │   │   ├── ppio.ts
│   │   │   │   ├── qiniu.ts
│   │   │   │   ├── qwen.ts
│   │   │   │   ├── replicate.ts
│   │   │   │   ├── sambanova.ts
│   │   │   │   ├── search1api.ts
│   │   │   │   ├── sensenova.ts
│   │   │   │   ├── siliconcloud.ts
│   │   │   │   ├── spark.ts
│   │   │   │   ├── stepfun.ts
│   │   │   │   ├── straico.ts
│   │   │   │   ├── taichu.ts
│   │   │   │   ├── tencentcloud.ts
│   │   │   │   ├── togetherai.ts
│   │   │   │   ├── upstage.ts
│   │   │   │   ├── v0.ts
│   │   │   │   ├── vercelaigateway.ts
│   │   │   │   ├── vertexai.ts
│   │   │   │   ├── vllm.ts
│   │   │   │   ├── volcengine.ts
│   │   │   │   ├── volcengineCodingPlan.ts
│   │   │   │   ├── wenxin.ts
│   │   │   │   ├── xai.ts
│   │   │   │   ├── xiaomimimo.ts
│   │   │   │   ├── xinference.ts
│   │   │   │   ├── zenmux.ts
│   │   │   │   ├── zeroone.ts
│   │   │   │   └── zhipu.ts
│   │   │   ├── const/
│   │   │   │   └── modelProvider.ts
│   │   │   ├── exports.test.ts
│   │   │   ├── index.ts
│   │   │   ├── modelProviders/
│   │   │   │   ├── ai21.ts
│   │   │   │   ├── ai302.ts
│   │   │   │   ├── ai360.ts
│   │   │   │   ├── aihubmix.ts
│   │   │   │   ├── akashchat.ts
│   │   │   │   ├── anthropic.ts
│   │   │   │   ├── azure.ts
│   │   │   │   ├── azureai.ts
│   │   │   │   ├── baichuan.ts
│   │   │   │   ├── bailianCodingPlan.ts
│   │   │   │   ├── bedrock.ts
│   │   │   │   ├── bfl.ts
│   │   │   │   ├── cerebras.ts
│   │   │   │   ├── cloudflare.ts
│   │   │   │   ├── cohere.ts
│   │   │   │   ├── cometapi.ts
│   │   │   │   ├── comfyui.ts
│   │   │   │   ├── deepseek.ts
│   │   │   │   ├── fal.ts
│   │   │   │   ├── fireworksai.ts
│   │   │   │   ├── giteeai.ts
│   │   │   │   ├── github.ts
│   │   │   │   ├── githubCopilot.ts
│   │   │   │   ├── glmCodingPlan.ts
│   │   │   │   ├── google.ts
│   │   │   │   ├── groq.ts
│   │   │   │   ├── higress.ts
│   │   │   │   ├── huggingface.ts
│   │   │   │   ├── hunyuan.ts
│   │   │   │   ├── index.test.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── infiniai.ts
│   │   │   │   ├── internlm.ts
│   │   │   │   ├── jina.ts
│   │   │   │   ├── kimiCodingPlan.ts
│   │   │   │   ├── lmstudio.ts
│   │   │   │   ├── lobehub.ts
│   │   │   │   ├── longcat.ts
│   │   │   │   ├── minimax.ts
│   │   │   │   ├── minimaxCodingPlan.ts
│   │   │   │   ├── mistral.ts
│   │   │   │   ├── modelscope.ts
│   │   │   │   ├── moonshot.ts
│   │   │   │   ├── nebius.ts
│   │   │   │   ├── newapi.ts
│   │   │   │   ├── novita.ts
│   │   │   │   ├── nvidia.ts
│   │   │   │   ├── ollama.ts
│   │   │   │   ├── ollamacloud.ts
│   │   │   │   ├── openai.ts
│   │   │   │   ├── openrouter.ts
│   │   │   │   ├── perplexity.ts
│   │   │   │   ├── ppio.ts
│   │   │   │   ├── qiniu.ts
│   │   │   │   ├── qwen.ts
│   │   │   │   ├── replicate.ts
│   │   │   │   ├── sambanova.ts
│   │   │   │   ├── search1api.ts
│   │   │   │   ├── sensenova.ts
│   │   │   │   ├── siliconcloud.ts
│   │   │   │   ├── spark.ts
│   │   │   │   ├── stepfun.ts
│   │   │   │   ├── straico.ts
│   │   │   │   ├── taichu.ts
│   │   │   │   ├── tencentcloud.ts
│   │   │   │   ├── togetherai.ts
│   │   │   │   ├── upstage.ts
│   │   │   │   ├── v0.ts
│   │   │   │   ├── vercelaigateway.ts
│   │   │   │   ├── vertexai.ts
│   │   │   │   ├── vllm.ts
│   │   │   │   ├── volcengine.ts
│   │   │   │   ├── volcengineCodingPlan.ts
│   │   │   │   ├── wenxin.ts
│   │   │   │   ├── xai.ts
│   │   │   │   ├── xiaomimimo.ts
│   │   │   │   ├── xinference.ts
│   │   │   │   ├── zenmux.ts
│   │   │   │   ├── zeroone.ts
│   │   │   │   └── zhipu.ts
│   │   │   ├── standard-parameters/
│   │   │   │   ├── index.test.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── video.test.ts
│   │   │   │   └── video.ts
│   │   │   └── types/
│   │   │       ├── aiModel.ts
│   │   │       └── index.ts
│   │   └── vitest.config.mts
│   ├── model-runtime/
│   │   ├── CLAUDE.md
│   │   ├── docs/
│   │   │   └── test-coverage.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── const/
│   │   │   │   ├── models.ts
│   │   │   │   └── type.test.ts
│   │   │   ├── core/
│   │   │   │   ├── BaseAI.ts
│   │   │   │   ├── ModelRuntime.test.ts
│   │   │   │   ├── ModelRuntime.ts
│   │   │   │   ├── RouterRuntime/
│   │   │   │   │   ├── apiTypes.ts
│   │   │   │   │   ├── baseRuntimeMap.ts
│   │   │   │   │   ├── createRuntime.test.ts
│   │   │   │   │   ├── createRuntime.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── anthropicCompatibleFactory/
│   │   │   │   │   ├── generateObject.test.ts
│   │   │   │   │   ├── generateObject.ts
│   │   │   │   │   ├── handleAnthropicError.ts
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── resolveCacheTTL.ts
│   │   │   │   │   └── resolveMaxTokens.ts
│   │   │   │   ├── contextBuilders/
│   │   │   │   │   ├── anthropic.test.ts
│   │   │   │   │   ├── anthropic.ts
│   │   │   │   │   ├── google.test.ts
│   │   │   │   │   ├── google.ts
│   │   │   │   │   ├── huggingface.test.ts
│   │   │   │   │   ├── huggingface.ts
│   │   │   │   │   ├── openai.test.ts
│   │   │   │   │   └── openai.ts
│   │   │   │   ├── openaiCompatibleFactory/
│   │   │   │   │   ├── createImage.test.ts
│   │   │   │   │   ├── createImage.ts
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── nonStreamToStream.test.ts
│   │   │   │   │   └── nonStreamToStream.ts
│   │   │   │   ├── parameterResolver.test.ts
│   │   │   │   ├── parameterResolver.ts
│   │   │   │   ├── streams/
│   │   │   │   │   ├── __snapshots__/
│   │   │   │   │   │   └── protocol.test.ts.snap
│   │   │   │   │   ├── anthropic.test.ts
│   │   │   │   │   ├── anthropic.ts
│   │   │   │   │   ├── bedrock/
│   │   │   │   │   │   ├── claude.ts
│   │   │   │   │   │   ├── common.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── llama.test.ts
│   │   │   │   │   │   └── llama.ts
│   │   │   │   │   ├── cloudflare.test.ts
│   │   │   │   │   ├── cloudflare.ts
│   │   │   │   │   ├── google/
│   │   │   │   │   │   ├── const.ts
│   │   │   │   │   │   ├── google-ai.test.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── model.test.ts
│   │   │   │   │   ├── model.ts
│   │   │   │   │   ├── ollama.test.ts
│   │   │   │   │   ├── ollama.ts
│   │   │   │   │   ├── openai/
│   │   │   │   │   │   ├── __snapshots__/
│   │   │   │   │   │   │   └── responsesStream.test.ts.snap
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── openai.test.ts
│   │   │   │   │   │   ├── openai.ts
│   │   │   │   │   │   ├── responsesStream.test.ts
│   │   │   │   │   │   └── responsesStream.ts
│   │   │   │   │   ├── protocol.test.ts
│   │   │   │   │   ├── protocol.ts
│   │   │   │   │   ├── qwen.test.ts
│   │   │   │   │   ├── qwen.ts
│   │   │   │   │   ├── spark.test.ts
│   │   │   │   │   ├── spark.ts
│   │   │   │   │   ├── utils.test.ts
│   │   │   │   │   ├── utils.ts
│   │   │   │   │   └── vertex-ai.test.ts
│   │   │   │   └── usageConverters/
│   │   │   │       ├── anthropic.test.ts
│   │   │   │       ├── anthropic.ts
│   │   │   │       ├── google-ai.test.ts
│   │   │   │       ├── google-ai.ts
│   │   │   │       ├── index.ts
│   │   │   │       ├── openai.test.ts
│   │   │   │       ├── openai.ts
│   │   │   │       └── utils/
│   │   │   │           ├── computeChatCost.test.ts
│   │   │   │           ├── computeChatCost.ts
│   │   │   │           ├── computeImageCost.test.ts
│   │   │   │           ├── computeImageCost.ts
│   │   │   │           ├── computeVideoCost.test.ts
│   │   │   │           ├── computeVideoCost.ts
│   │   │   │           ├── index.ts
│   │   │   │           ├── resolveImageSinglePrice.ts
│   │   │   │           ├── resolveVideoSinglePrice.test.ts
│   │   │   │           ├── resolveVideoSinglePrice.ts
│   │   │   │           └── withUsageCost.ts
│   │   │   ├── helpers/
│   │   │   │   ├── index.ts
│   │   │   │   ├── mergeChatMethodOptions.test.ts
│   │   │   │   ├── mergeChatMethodOptions.ts
│   │   │   │   ├── parseToolCalls.test.ts
│   │   │   │   └── parseToolCalls.ts
│   │   │   ├── index.ts
│   │   │   ├── providerTestUtils.test.ts
│   │   │   ├── providerTestUtils.ts
│   │   │   ├── providers/
│   │   │   │   ├── ai21/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── ai302/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── ai360/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── aihubmix/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── akashchat/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── anthropic/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── azureOpenai/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── azureai/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── baichuan/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── bailianCodingPlan/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── bedrock/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── bfl/
│   │   │   │   │   ├── createImage.test.ts
│   │   │   │   │   ├── createImage.ts
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── types.ts
│   │   │   │   ├── cerebras/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── cloudflare/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── cohere/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── cometapi/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── comfyui/
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   └── index.test.ts
│   │   │   │   │   ├── auth/
│   │   │   │   │   │   └── AuthManager.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── deepseek/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── fal/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── fireworksai/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── giteeai/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── github/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── githubCopilot/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── glmCodingPlan/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── google/
│   │   │   │   │   ├── createImage.test.ts
│   │   │   │   │   ├── createImage.ts
│   │   │   │   │   ├── generateObject.test.ts
│   │   │   │   │   ├── generateObject.ts
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── thinkingResolver.test.ts
│   │   │   │   │   └── thinkingResolver.ts
│   │   │   │   ├── groq/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── higress/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── huggingface/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── type.ts
│   │   │   │   ├── hunyuan/
│   │   │   │   │   ├── createImage.test.ts
│   │   │   │   │   ├── createImage.ts
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── infiniai/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── internlm/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── jina/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── kimiCodingPlan/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── lmstudio/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── lobehub/
│   │   │   │   │   └── index.ts
│   │   │   │   ├── longcat/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── minimax/
│   │   │   │   │   ├── createImage.test.ts
│   │   │   │   │   ├── createImage.ts
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── minimaxCodingPlan/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── mistral/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── modelscope/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── moonshot/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── nebius/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── newapi/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── novita/
│   │   │   │   │   ├── __snapshots__/
│   │   │   │   │   │   └── index.test.ts.snap
│   │   │   │   │   ├── fixtures/
│   │   │   │   │   │   └── models.json
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── type.ts
│   │   │   │   ├── nvidia/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── ollama/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── type.ts
│   │   │   │   ├── ollamacloud/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── openai/
│   │   │   │   │   ├── fixtures/
│   │   │   │   │   │   └── openai-models.json
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── openrouter/
│   │   │   │   │   ├── fixtures/
│   │   │   │   │   │   ├── frontendModels.json
│   │   │   │   │   │   └── models.json
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── type.ts
│   │   │   │   ├── perplexity/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── ppio/
│   │   │   │   │   ├── __snapshots__/
│   │   │   │   │   │   └── index.test.ts.snap
│   │   │   │   │   ├── fixtures/
│   │   │   │   │   │   └── models.json
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── type.ts
│   │   │   │   ├── qiniu/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── qwen/
│   │   │   │   │   ├── createImage.test.ts
│   │   │   │   │   ├── createImage.ts
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── replicate/
│   │   │   │   │   └── index.ts
│   │   │   │   ├── sambanova/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── search1api/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── sensenova/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── siliconcloud/
│   │   │   │   │   ├── createImage.ts
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── spark/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── stepfun/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── straico/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── type.ts
│   │   │   │   ├── taichu/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── tencentcloud/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── togetherai/
│   │   │   │   │   ├── fixtures/
│   │   │   │   │   │   └── models.json
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── type.ts
│   │   │   │   ├── upstage/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── v0/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── vercelaigateway/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── vertexai/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── vllm/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── volcengine/
│   │   │   │   │   ├── createImage.test.ts
│   │   │   │   │   ├── createImage.ts
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── video/
│   │   │   │   │       ├── createVideo.test.ts
│   │   │   │   │       ├── createVideo.ts
│   │   │   │   │       ├── handleCreateVideoWebhook.test.ts
│   │   │   │   │       └── handleCreateVideoWebhook.ts
│   │   │   │   ├── volcengineCodingPlan/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── wenxin/
│   │   │   │   │   ├── createImage.test.ts
│   │   │   │   │   ├── createImage.ts
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── xai/
│   │   │   │   │   ├── createImage.test.ts
│   │   │   │   │   ├── createImage.ts
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── xiaomimimo/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── xinference/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── zenmux/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── zeroone/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   └── index.ts
│   │   │   │   └── zhipu/
│   │   │   │       ├── index.test.ts
│   │   │   │       └── index.ts
│   │   │   ├── runtimeMap.ts
│   │   │   ├── types/
│   │   │   │   ├── chat.ts
│   │   │   │   ├── embeddings.ts
│   │   │   │   ├── error.ts
│   │   │   │   ├── image.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── model.ts
│   │   │   │   ├── structureOutput.ts
│   │   │   │   ├── toolsCalling.ts
│   │   │   │   ├── tts.ts
│   │   │   │   ├── type.ts
│   │   │   │   └── video.ts
│   │   │   └── utils/
│   │   │       ├── asyncifyPolling.test.ts
│   │   │       ├── asyncifyPolling.ts
│   │   │       ├── comfyuiErrorParser.test.ts
│   │   │       ├── comfyuiErrorParser.ts
│   │   │       ├── consumeStream.test.ts
│   │   │       ├── consumeStream.ts
│   │   │       ├── createError.test.ts
│   │   │       ├── createError.ts
│   │   │       ├── debugStream.test.ts
│   │   │       ├── debugStream.ts
│   │   │       ├── desensitizeUrl.test.ts
│   │   │       ├── desensitizeUrl.ts
│   │   │       ├── errorResponse.test.ts
│   │   │       ├── errorResponse.ts
│   │   │       ├── getFallbackModelProperty.test.ts
│   │   │       ├── getFallbackModelProperty.ts
│   │   │       ├── getModelMaxOutputs.test.ts
│   │   │       ├── getModelMaxOutputs.ts
│   │   │       ├── getModelPricing.ts
│   │   │       ├── googleErrorParser.test.ts
│   │   │       ├── googleErrorParser.ts
│   │   │       ├── handleOpenAIError.test.ts
│   │   │       ├── handleOpenAIError.ts
│   │   │       ├── isExceededContextWindowError.test.ts
│   │   │       ├── isExceededContextWindowError.ts
│   │   │       ├── isQuotaLimitError.test.ts
│   │   │       ├── isQuotaLimitError.ts
│   │   │       ├── modelParse.test.ts
│   │   │       ├── modelParse.ts
│   │   │       ├── postProcessModelList.test.ts
│   │   │       ├── postProcessModelList.ts
│   │   │       ├── response.test.ts
│   │   │       ├── response.ts
│   │   │       ├── safeParseJSON.test.ts
│   │   │       ├── safeParseJSON.ts
│   │   │       ├── sanitizeError.test.ts
│   │   │       ├── sanitizeError.ts
│   │   │       ├── uriParser.test.ts
│   │   │       ├── uriParser.ts
│   │   │       └── uuid.ts
│   │   └── vitest.config.mts
│   ├── observability-otel/
│   │   ├── package.json
│   │   └── src/
│   │       ├── api.ts
│   │       ├── gen-ai/
│   │       │   ├── index.ts
│   │       │   └── semconv.ts
│   │       ├── modules/
│   │       │   ├── index.ts
│   │       │   ├── memory-user-memory/
│   │       │   │   ├── extract.ts
│   │       │   │   └── index.ts
│   │       │   └── upstash-workflow/
│   │       │       └── index.ts
│   │       ├── node.ts
│   │       └── trpc/
│   │           ├── convention.ts
│   │           ├── index.test.ts
│   │           ├── index.ts
│   │           └── metrics.ts
│   ├── openapi/
│   │   ├── package.json
│   │   ├── scripts/
│   │   │   ├── .gitignore
│   │   │   └── compliance-test.sh
│   │   └── src/
│   │       ├── app.ts
│   │       ├── common/
│   │       │   ├── base.controller.ts
│   │       │   └── base.service.ts
│   │       ├── controllers/
│   │       │   ├── agent-group.controller.ts
│   │       │   ├── agent.controller.ts
│   │       │   ├── chat.controller.ts
│   │       │   ├── file.controller.ts
│   │       │   ├── index.ts
│   │       │   ├── knowledge-base.controller.ts
│   │       │   ├── message-translation.controller.ts
│   │       │   ├── message.controller.ts
│   │       │   ├── model.controller.ts
│   │       │   ├── permission.controller.ts
│   │       │   ├── provider.controller.ts
│   │       │   ├── responses.controller.ts
│   │       │   ├── role.controller.ts
│   │       │   ├── topic.controller.ts
│   │       │   └── user.controller.ts
│   │       ├── helpers/
│   │       │   ├── file.ts
│   │       │   ├── pagination.ts
│   │       │   ├── permission.ts
│   │       │   └── translate.ts
│   │       ├── index.ts
│   │       ├── middleware/
│   │       │   ├── auth.ts
│   │       │   ├── index.ts
│   │       │   └── permission-check.ts
│   │       ├── routes/
│   │       │   ├── agent-groups.route.ts
│   │       │   ├── agents.route.ts
│   │       │   ├── files.route.ts
│   │       │   ├── index.ts
│   │       │   ├── knowledge-bases.route.ts
│   │       │   ├── message-translations.route.ts
│   │       │   ├── messages.route.ts
│   │       │   ├── models.route.ts
│   │       │   ├── permissions.route.ts
│   │       │   ├── providers.route.ts
│   │       │   ├── responses.route.ts
│   │       │   ├── roles.route.ts
│   │       │   ├── topics.route.ts
│   │       │   └── users.route.ts
│   │       ├── services/
│   │       │   ├── agent-group.service.ts
│   │       │   ├── agent.service.ts
│   │       │   ├── chat.service.ts
│   │       │   ├── file.service.ts
│   │       │   ├── index.ts
│   │       │   ├── knowledge-base.service.ts
│   │       │   ├── message-translations.service.ts
│   │       │   ├── message.service.ts
│   │       │   ├── model.service.ts
│   │       │   ├── permission.service.ts
│   │       │   ├── provider.service.ts
│   │       │   ├── responses.service.ts
│   │       │   ├── role.service.ts
│   │       │   ├── topic.service.ts
│   │       │   └── user.service.ts
│   │       └── types/
│   │           ├── agent-group.type.ts
│   │           ├── agent.type.ts
│   │           ├── chat.type.ts
│   │           ├── common.type.ts
│   │           ├── file.type.ts
│   │           ├── index.ts
│   │           ├── knowledge-base.type.ts
│   │           ├── message-translations.type.ts
│   │           ├── message.type.ts
│   │           ├── model.type.ts
│   │           ├── permission.type.ts
│   │           ├── provider.type.ts
│   │           ├── responses.type.ts
│   │           ├── role.type.ts
│   │           ├── topic.type.ts
│   │           └── user.type.ts
│   ├── prompts/
│   │   ├── .gitignore
│   │   ├── CLAUDE.md
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── promptfoo/
│   │   │   ├── abstract-chunk/
│   │   │   │   ├── eval.yaml
│   │   │   │   └── prompt.ts
│   │   │   ├── emoji-picker/
│   │   │   │   ├── eval.yaml
│   │   │   │   └── prompt.ts
│   │   │   ├── knowledge-qa/
│   │   │   │   ├── eval.yaml
│   │   │   │   └── prompt.ts
│   │   │   ├── language-detection/
│   │   │   │   ├── eval.yaml
│   │   │   │   └── prompt.ts
│   │   │   ├── summary-title/
│   │   │   │   ├── eval.yaml
│   │   │   │   └── prompt.ts
│   │   │   ├── supervisor/
│   │   │   │   └── productive/
│   │   │   │       ├── eval.yaml
│   │   │   │       ├── prompt.ts
│   │   │   │       ├── tests/
│   │   │   │       │   ├── basic-case.ts
│   │   │   │       │   └── role.ts
│   │   │   │       └── tools.json
│   │   │   └── translate/
│   │   │       ├── eval.yaml
│   │   │       └── prompt.ts
│   │   ├── promptfooconfig.yaml
│   │   ├── src/
│   │   │   ├── agents/
│   │   │   │   ├── __snapshots__/
│   │   │   │   │   └── pageContentContext.test.ts.snap
│   │   │   │   ├── index.ts
│   │   │   │   ├── pageContentContext.test.ts
│   │   │   │   ├── pageContentContext.ts
│   │   │   │   └── pageSelectionContext.ts
│   │   │   ├── chains/
│   │   │   │   ├── __tests__/
│   │   │   │   │   ├── __snapshots__/
│   │   │   │   │   │   ├── abstractChunk.test.ts.snap
│   │   │   │   │   │   ├── answerWithContext.test.ts.snap
│   │   │   │   │   │   ├── pickEmoji.test.ts.snap
│   │   │   │   │   │   ├── summaryHistory.test.ts.snap
│   │   │   │   │   │   ├── summaryTitle.test.ts.snap
│   │   │   │   │   │   └── translate.test.ts.snap
│   │   │   │   │   ├── abstractChunk.test.ts
│   │   │   │   │   ├── answerWithContext.test.ts
│   │   │   │   │   ├── langDetect.test.ts
│   │   │   │   │   ├── pickEmoji.test.ts
│   │   │   │   │   ├── rewriteQuery.test.ts
│   │   │   │   │   ├── summaryAgentName.test.ts
│   │   │   │   │   ├── summaryDescription.test.ts
│   │   │   │   │   ├── summaryGenerationTitle.test.ts
│   │   │   │   │   ├── summaryHistory.test.ts
│   │   │   │   │   ├── summaryTags.test.ts
│   │   │   │   │   ├── summaryTitle.test.ts
│   │   │   │   │   └── translate.test.ts
│   │   │   │   ├── abstractChunk.ts
│   │   │   │   ├── answerWithContext.ts
│   │   │   │   ├── compressContext.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── langDetect.ts
│   │   │   │   ├── pickEmoji.ts
│   │   │   │   ├── rewriteQuery.ts
│   │   │   │   ├── summaryAgentName.ts
│   │   │   │   ├── summaryDescription.ts
│   │   │   │   ├── summaryGenerationTitle.ts
│   │   │   │   ├── summaryHistory.ts
│   │   │   │   ├── summaryTags.ts
│   │   │   │   ├── summaryTitle.ts
│   │   │   │   ├── taskTopicHandoff.ts
│   │   │   │   └── translate.ts
│   │   │   ├── contexts/
│   │   │   │   ├── index.ts
│   │   │   │   └── supervisor/
│   │   │   │       ├── index.ts
│   │   │   │       ├── makeDecision.ts
│   │   │   │       └── tools.ts
│   │   │   ├── index.test.ts
│   │   │   ├── index.ts
│   │   │   └── prompts/
│   │   │       ├── agentBuilder/
│   │   │       │   ├── index.ts
│   │   │       │   ├── modelsResultsPrompt.ts
│   │   │       │   └── toolsResultsPrompt.ts
│   │   │       ├── agentGroup/
│   │   │       │   ├── __snapshots__/
│   │   │       │   │   └── index.test.ts.snap
│   │   │       │   ├── agentProfile.ts
│   │   │       │   ├── groupContext.ts
│   │   │       │   ├── index.test.ts
│   │   │       │   └── index.ts
│   │   │       ├── botPlatformContext/
│   │   │       │   └── index.ts
│   │   │       ├── chatMessages/
│   │   │       │   ├── index.test.ts
│   │   │       │   └── index.ts
│   │   │       ├── compressContext/
│   │   │       │   └── index.ts
│   │   │       ├── discordContext/
│   │   │       │   └── index.ts
│   │   │       ├── fileSystem/
│   │   │       │   ├── formatCommandOutput.test.ts
│   │   │       │   ├── formatCommandOutput.ts
│   │   │       │   ├── formatCommandResult.test.ts
│   │   │       │   ├── formatCommandResult.ts
│   │   │       │   ├── formatEditResult.test.ts
│   │   │       │   ├── formatEditResult.ts
│   │   │       │   ├── formatFileContent.test.ts
│   │   │       │   ├── formatFileContent.ts
│   │   │       │   ├── formatFileList.test.ts
│   │   │       │   ├── formatFileList.ts
│   │   │       │   ├── formatFileSearchResults.test.ts
│   │   │       │   ├── formatFileSearchResults.ts
│   │   │       │   ├── formatGlobResults.test.ts
│   │   │       │   ├── formatGlobResults.ts
│   │   │       │   ├── formatGrepResults.test.ts
│   │   │       │   ├── formatGrepResults.ts
│   │   │       │   ├── formatKillResult.test.ts
│   │   │       │   ├── formatKillResult.ts
│   │   │       │   ├── formatMoveResults.test.ts
│   │   │       │   ├── formatMoveResults.ts
│   │   │       │   ├── formatMultipleFiles.test.ts
│   │   │       │   ├── formatMultipleFiles.ts
│   │   │       │   ├── formatRenameResult.test.ts
│   │   │       │   ├── formatRenameResult.ts
│   │   │       │   ├── formatWriteResult.test.ts
│   │   │       │   ├── formatWriteResult.ts
│   │   │       │   └── index.ts
│   │   │       ├── files/
│   │   │       │   ├── __snapshots__/
│   │   │       │   │   └── knowledgeBase.test.ts.snap
│   │   │       │   ├── file.ts
│   │   │       │   ├── image.ts
│   │   │       │   ├── index.test.ts
│   │   │       │   ├── index.ts
│   │   │       │   ├── knowledgeBase.test.ts
│   │   │       │   ├── knowledgeBase.ts
│   │   │       │   └── video.ts
│   │   │       ├── groupChat/
│   │   │       │   ├── __snapshots__/
│   │   │       │   │   └── index.test.ts.snap
│   │   │       │   ├── index.test.ts
│   │   │       │   └── index.ts
│   │   │       ├── gtd/
│   │   │       │   ├── index.test.ts
│   │   │       │   └── index.ts
│   │   │       ├── index.ts
│   │   │       ├── knowledgeBaseQA/
│   │   │       │   ├── __snapshots__/
│   │   │       │   │   ├── formatFileContents.test.ts.snap
│   │   │       │   │   ├── formatNoSearchResults.test.ts.snap
│   │   │       │   │   ├── formatSearchResults.test.ts.snap
│   │   │       │   │   └── index.test.ts.snap
│   │   │       │   ├── chunk.ts
│   │   │       │   ├── formatFileContents.test.ts
│   │   │       │   ├── formatFileContents.ts
│   │   │       │   ├── formatNoSearchResults.test.ts
│   │   │       │   ├── formatNoSearchResults.ts
│   │   │       │   ├── formatSearchResults.test.ts
│   │   │       │   ├── formatSearchResults.ts
│   │   │       │   ├── index.test.ts
│   │   │       │   ├── index.ts
│   │   │       │   ├── knowledge.ts
│   │   │       │   └── userQuery.ts
│   │   │       ├── messagesToText/
│   │   │       │   ├── __snapshots__/
│   │   │       │   │   └── index.test.ts.snap
│   │   │       │   ├── index.test.ts
│   │   │       │   └── index.ts
│   │   │       ├── plugin/
│   │   │       │   ├── index.test.ts
│   │   │       │   ├── index.ts
│   │   │       │   ├── tools.test.ts
│   │   │       │   └── tools.ts
│   │   │       ├── remoteDevice/
│   │   │       │   └── index.ts
│   │   │       ├── search/
│   │   │       │   ├── crawlResults.test.ts
│   │   │       │   ├── crawlResults.ts
│   │   │       │   ├── index.ts
│   │   │       │   ├── searchResults.test.ts
│   │   │       │   ├── searchResults.ts
│   │   │       │   └── xmlEscape.ts
│   │   │       ├── skills/
│   │   │       │   ├── index.test.ts
│   │   │       │   ├── index.ts
│   │   │       │   └── resourcesTree.ts
│   │   │       ├── speaker/
│   │   │       │   └── index.ts
│   │   │       ├── systemRole/
│   │   │       │   ├── index.test.ts
│   │   │       │   └── index.ts
│   │   │       ├── task/
│   │   │       │   ├── __snapshots__/
│   │   │       │   │   └── index.test.ts.snap
│   │   │       │   ├── index.test.ts
│   │   │       │   └── index.ts
│   │   │       ├── toolDiscovery/
│   │   │       │   └── index.ts
│   │   │       └── userMemory/
│   │   │           ├── __snapshots__/
│   │   │           │   ├── formatSearchResults.test.ts.snap
│   │   │           │   └── index.test.ts.snap
│   │   │           ├── formatSearchResults.test.ts
│   │   │           ├── formatSearchResults.ts
│   │   │           ├── index.test.ts
│   │   │           └── index.ts
│   │   └── vitest.config.mts
│   ├── python-interpreter/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── __tests__/
│   │   │   │   ├── interpreter.test.ts
│   │   │   │   └── worker.test.ts
│   │   │   ├── index.ts
│   │   │   ├── interpreter.ts
│   │   │   ├── types.ts
│   │   │   └── worker.ts
│   │   └── vitest.config.mts
│   ├── ssrf-safe-fetch/
│   │   ├── index.browser.ts
│   │   ├── index.test.ts
│   │   ├── index.ts
│   │   ├── package.json
│   │   └── vitest.config.mts
│   ├── types/
│   │   ├── package.json
│   │   └── src/
│   │       ├── agent/
│   │       │   ├── agencyConfig.ts
│   │       │   ├── agentConfig.ts
│   │       │   ├── chatConfig.ts
│   │       │   ├── index.ts
│   │       │   ├── item.ts
│   │       │   └── tts.ts
│   │       ├── agentCronJob/
│   │       │   └── index.ts
│   │       ├── agentExecution/
│   │       │   └── index.ts
│   │       ├── agentGroup/
│   │       │   └── index.ts
│   │       ├── agentRuntime.ts
│   │       ├── aiChat.ts
│   │       ├── aiProvider.ts
│   │       ├── apiKey.ts
│   │       ├── artifact.ts
│   │       ├── asyncTask.ts
│   │       ├── auth.ts
│   │       ├── brief/
│   │       │   └── index.ts
│   │       ├── changelog.ts
│   │       ├── chunk/
│   │       │   ├── document.ts
│   │       │   └── index.ts
│   │       ├── clientDB.ts
│   │       ├── conversation.ts
│   │       ├── creds/
│   │       │   └── index.ts
│   │       ├── discover/
│   │       │   ├── assistants.ts
│   │       │   ├── fork.ts
│   │       │   ├── groupAgents.ts
│   │       │   ├── index.ts
│   │       │   ├── mcp.ts
│   │       │   ├── models.ts
│   │       │   ├── plugins.ts
│   │       │   ├── providers.ts
│   │       │   └── skills.ts
│   │       ├── document/
│   │       │   └── index.ts
│   │       ├── eval/
│   │       │   ├── agentEval.ts
│   │       │   ├── agentEvalDataset.ts
│   │       │   ├── agentEvalRun.ts
│   │       │   ├── benchmark.ts
│   │       │   ├── dataset.ts
│   │       │   ├── evaluation.ts
│   │       │   ├── index.ts
│   │       │   ├── ragas.ts
│   │       │   └── rubric.ts
│   │       ├── export.ts
│   │       ├── exportConfig.ts
│   │       ├── fetch.ts
│   │       ├── files/
│   │       │   ├── index.ts
│   │       │   ├── list.ts
│   │       │   └── upload.ts
│   │       ├── generation/
│   │       │   └── index.ts
│   │       ├── home.ts
│   │       ├── hotkey.ts
│   │       ├── importer.ts
│   │       ├── index.ts
│   │       ├── knowledgeBase/
│   │       │   └── index.ts
│   │       ├── llm.ts
│   │       ├── message/
│   │       │   ├── common/
│   │       │   │   ├── base.ts
│   │       │   │   ├── image.ts
│   │       │   │   ├── index.ts
│   │       │   │   ├── messageGroup.ts
│   │       │   │   ├── metadata.ts
│   │       │   │   ├── pageSelection.ts
│   │       │   │   ├── tools.ts
│   │       │   │   └── translate.ts
│   │       │   ├── db/
│   │       │   │   ├── index.ts
│   │       │   │   ├── item.ts
│   │       │   │   └── params.ts
│   │       │   ├── index.ts
│   │       │   └── ui/
│   │       │       ├── chat.ts
│   │       │       ├── extra.ts
│   │       │       ├── index.ts
│   │       │       ├── params.ts
│   │       │       ├── rag.ts
│   │       │       └── video.ts
│   │       ├── meta.ts
│   │       ├── openai/
│   │       │   ├── chat.ts
│   │       │   ├── functionCall.ts
│   │       │   ├── image.ts
│   │       │   └── plugin.ts
│   │       ├── plugins/
│   │       │   ├── index.ts
│   │       │   ├── mcp.ts
│   │       │   ├── mcpDeps.ts
│   │       │   └── protocol.ts
│   │       ├── rag.ts
│   │       ├── search.ts
│   │       ├── serverConfig.ts
│   │       ├── service.ts
│   │       ├── session/
│   │       │   ├── agentSession.ts
│   │       │   ├── index.ts
│   │       │   └── sessionGroup.ts
│   │       ├── skill/
│   │       │   └── index.ts
│   │       ├── stepContext.ts
│   │       ├── subscription.ts
│   │       ├── task/
│   │       │   └── index.ts
│   │       ├── tool/
│   │       │   ├── builtin.ts
│   │       │   ├── crawler.ts
│   │       │   ├── dalle.ts
│   │       │   ├── index.ts
│   │       │   ├── interpreter.ts
│   │       │   ├── intervention.ts
│   │       │   ├── plugin.ts
│   │       │   ├── search/
│   │       │   │   └── index.ts
│   │       │   └── tool.ts
│   │       ├── topic/
│   │       │   ├── index.ts
│   │       │   ├── thread.ts
│   │       │   └── topic.ts
│   │       ├── trace/
│   │       │   ├── action.ts
│   │       │   ├── enum.ts
│   │       │   └── index.ts
│   │       ├── usage/
│   │       │   └── usageRecord.ts
│   │       ├── user/
│   │       │   ├── agentOnboarding.test.ts
│   │       │   ├── agentOnboarding.ts
│   │       │   ├── index.ts
│   │       │   ├── onboarding.ts
│   │       │   ├── preference.ts
│   │       │   └── settings/
│   │       │       ├── filesConfig.ts
│   │       │       ├── general.ts
│   │       │       ├── hotkey.ts
│   │       │       ├── image.ts
│   │       │       ├── index.ts
│   │       │       ├── keyVaults.ts
│   │       │       ├── market.ts
│   │       │       ├── memory.ts
│   │       │       ├── modelProvider.ts
│   │       │       ├── notification.ts
│   │       │       ├── sync.ts
│   │       │       ├── systemAgent.ts
│   │       │       ├── tool.ts
│   │       │       └── tts.ts
│   │       ├── userMemory/
│   │       │   ├── activity.ts
│   │       │   ├── base.ts
│   │       │   ├── experience.ts
│   │       │   ├── identity.ts
│   │       │   ├── index.ts
│   │       │   ├── layers.ts
│   │       │   ├── list.ts
│   │       │   ├── server.ts
│   │       │   ├── shared.ts
│   │       │   ├── tools.ts
│   │       │   └── trace.ts
│   │       ├── util.ts
│   │       └── zustand.ts
│   ├── utils/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── apiKey.test.ts
│   │   │   ├── apiKey.ts
│   │   │   ├── base64.test.ts
│   │   │   ├── base64.ts
│   │   │   ├── chunkers/
│   │   │   │   ├── index.ts
│   │   │   │   └── trimBatchProbe/
│   │   │   │       ├── index.ts
│   │   │   │       ├── trimBatchProbe.test.ts
│   │   │   │       └── trimBatchProbe.ts
│   │   │   ├── client/
│   │   │   │   ├── apiKeyManager.test.ts
│   │   │   │   ├── apiKeyManager.ts
│   │   │   │   ├── clipboard.ts
│   │   │   │   ├── cookie.test.ts
│   │   │   │   ├── cookie.ts
│   │   │   │   ├── downloadFile.ts
│   │   │   │   ├── exportFile.ts
│   │   │   │   ├── fetchEventSource/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── parse.ts
│   │   │   │   ├── imageDimensions.test.ts
│   │   │   │   ├── imageDimensions.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── sanitize.test.ts
│   │   │   │   ├── sanitize.ts
│   │   │   │   ├── topic.test.ts
│   │   │   │   ├── topic.ts
│   │   │   │   ├── videoValidation.test.ts
│   │   │   │   ├── videoValidation.ts
│   │   │   │   ├── xor-obfuscation.test.ts
│   │   │   │   └── xor-obfuscation.ts
│   │   │   ├── clientIP.test.ts
│   │   │   ├── clientIP.ts
│   │   │   ├── colorUtils.test.ts
│   │   │   ├── colorUtils.ts
│   │   │   ├── compass.ts
│   │   │   ├── compressImage.test.ts
│   │   │   ├── compressImage.ts
│   │   │   ├── dedupeBy.test.ts
│   │   │   ├── dedupeBy.ts
│   │   │   ├── detectChinese.test.ts
│   │   │   ├── detectChinese.ts
│   │   │   ├── difference.test.ts
│   │   │   ├── difference.ts
│   │   │   ├── env.ts
│   │   │   ├── error.test.ts
│   │   │   ├── error.ts
│   │   │   ├── esm/
│   │   │   │   └── unwrapESMModule.ts
│   │   │   ├── folderStructure.test.ts
│   │   │   ├── folderStructure.ts
│   │   │   ├── format.test.ts
│   │   │   ├── format.ts
│   │   │   ├── genOG.test.ts
│   │   │   ├── genOG.ts
│   │   │   ├── imageToBase64.test.ts
│   │   │   ├── imageToBase64.ts
│   │   │   ├── index.ts
│   │   │   ├── isChunkingUnsupported.test.ts
│   │   │   ├── isChunkingUnsupported.ts
│   │   │   ├── keyboard.test.ts
│   │   │   ├── keyboard.ts
│   │   │   ├── localStorage.ts
│   │   │   ├── merge.test.ts
│   │   │   ├── merge.ts
│   │   │   ├── mimeType.test.ts
│   │   │   ├── mimeType.ts
│   │   │   ├── multimodalContent.test.ts
│   │   │   ├── multimodalContent.ts
│   │   │   ├── number.test.ts
│   │   │   ├── number.ts
│   │   │   ├── object.test.ts
│   │   │   ├── object.ts
│   │   │   ├── parseMarkdown.ts
│   │   │   ├── platform.test.ts
│   │   │   ├── platform.ts
│   │   │   ├── pricing.test.ts
│   │   │   ├── pricing.ts
│   │   │   ├── promptTemplate.test.ts
│   │   │   ├── promptTemplate.ts
│   │   │   ├── safeParseJSON.test.ts
│   │   │   ├── safeParseJSON.ts
│   │   │   ├── sanitizeNullBytes.test.ts
│   │   │   ├── sanitizeNullBytes.ts
│   │   │   ├── sanitizeUTF8.test.ts
│   │   │   ├── sanitizeUTF8.ts
│   │   │   ├── server/
│   │   │   │   ├── __tests__/
│   │   │   │   │   ├── auth.test.ts
│   │   │   │   │   ├── response.test.ts
│   │   │   │   │   └── sse.test.ts
│   │   │   │   ├── apiKeyHash.ts
│   │   │   │   ├── auth.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── response.ts
│   │   │   │   ├── responsive.ts
│   │   │   │   ├── sse.ts
│   │   │   │   ├── xor.test.ts
│   │   │   │   └── xor.ts
│   │   │   ├── sleep.ts
│   │   │   ├── storeDebug.test.ts
│   │   │   ├── storeDebug.ts
│   │   │   ├── time.test.ts
│   │   │   ├── time.ts
│   │   │   ├── tokenizer/
│   │   │   │   └── index.ts
│   │   │   ├── toolManifest.ts
│   │   │   ├── trace.test.ts
│   │   │   ├── trace.ts
│   │   │   ├── units.ts
│   │   │   ├── uploadFIle.ts
│   │   │   ├── uriParser.test.ts
│   │   │   ├── uriParser.ts
│   │   │   ├── url.test.ts
│   │   │   ├── url.ts
│   │   │   ├── uuid.ts
│   │   │   ├── videoToBase64.test.ts
│   │   │   └── videoToBase64.ts
│   │   ├── tests/
│   │   │   └── setup.ts
│   │   └── vitest.config.mts
│   └── web-crawler/
│       ├── README.md
│       ├── README.zh-CN.md
│       ├── package.json
│       ├── src/
│       │   ├── __tests__/
│       │   │   ├── crawler.test.ts
│       │   │   └── urlRules.test.ts
│       │   ├── crawImpl/
│       │   │   ├── __tests__/
│       │   │   │   ├── browserless.test.ts
│       │   │   │   ├── exa.test.ts
│       │   │   │   ├── firecrawl.test.ts
│       │   │   │   ├── jina.test.ts
│       │   │   │   ├── naive.test.ts
│       │   │   │   ├── search1api.test.ts
│       │   │   │   └── tavily.test.ts
│       │   │   ├── browserless.ts
│       │   │   ├── exa.ts
│       │   │   ├── firecrawl.ts
│       │   │   ├── index.ts
│       │   │   ├── jina.ts
│       │   │   ├── naive.ts
│       │   │   ├── search1api.ts
│       │   │   └── tavily.ts
│       │   ├── crawler.ts
│       │   ├── index.ts
│       │   ├── test-utils.ts
│       │   ├── type.ts
│       │   ├── urlRules.ts
│       │   └── utils/
│       │       ├── __snapshots__/
│       │       │   └── htmlToMarkdown.test.ts.snap
│       │       ├── __tests__/
│       │       │   ├── appUrlRules.test.ts
│       │       │   ├── errorType.test.ts
│       │       │   ├── response.test.ts
│       │       │   └── withTimeout.test.ts
│       │       ├── appUrlRules.ts
│       │       ├── errorType.ts
│       │       ├── html/
│       │       │   ├── terms.html
│       │       │   └── yingchao.html
│       │       ├── htmlToMarkdown.test.ts
│       │       ├── htmlToMarkdown.ts
│       │       ├── response.ts
│       │       └── withTimeout.ts
│       ├── tsconfig.json
│       └── vitest.config.mts
├── patches/
│   ├── @swagger-api__apidom-reference.patch
│   └── @upstash__qstash.patch
├── plugins/
│   └── vite/
│       ├── emotionSpeedy.ts
│       ├── envRestartKeys.ts
│       ├── markdownImport.test.ts
│       ├── markdownImport.ts
│       ├── nodeModuleStub.ts
│       ├── platformResolve.ts
│       ├── sharedRendererConfig.ts
│       └── vercelSkewProtection.ts
├── pnpm-workspace.yaml
├── prettier.config.mjs
├── public/
│   ├── .well-known/
│   │   ├── apple-app-site-association
│   │   └── assetlinks.json
│   ├── _dangerous_local_dev_proxy.html
│   └── not-compatible.html
├── renovate.json
├── scripts/
│   ├── _shared/
│   │   ├── checkDeprecatedAuth.js
│   │   └── checkDeprecatedAuth.test.ts
│   ├── buildSitemapIndex/
│   │   └── index.ts
│   ├── cdnWorkflow/
│   │   ├── index.ts
│   │   ├── optimized.ts
│   │   ├── s3/
│   │   │   ├── index.ts
│   │   │   ├── types.ts
│   │   │   └── utils.ts
│   │   ├── uploader.ts
│   │   └── utils.ts
│   ├── changelogWorkflow/
│   │   ├── buildStaticChangelog.ts
│   │   ├── const.ts
│   │   ├── generateChangelog.ts
│   │   └── index.ts
│   ├── checkConsoleLog.mts
│   ├── clerk-to-betterauth/
│   │   ├── __tests__/
│   │   │   └── parseCsvLine.test.ts
│   │   ├── _internal/
│   │   │   ├── config.ts
│   │   │   ├── db.ts
│   │   │   ├── env.ts
│   │   │   ├── load-data-from-files.ts
│   │   │   ├── types.ts
│   │   │   └── utils.ts
│   │   ├── export-clerk-users-with-api.ts
│   │   ├── index.ts
│   │   ├── prod/
│   │   │   └── put_clerk_exported_users_csv_here.txt
│   │   ├── test/
│   │   │   └── put_clerk_exported_users_csv_here.txt
│   │   └── verify.ts
│   ├── copySpaBuild.mts
│   ├── countEnWord.ts
│   ├── dbmlWorkflow/
│   │   └── index.ts
│   ├── devStartupSequence.mts
│   ├── dockerPrebuild.mts
│   ├── docsWorkflow/
│   │   ├── autoCDN.ts
│   │   ├── const.ts
│   │   ├── index.ts
│   │   ├── optimized.ts
│   │   ├── toc.ts
│   │   └── utils.ts
│   ├── electronWorkflow/
│   │   ├── buildDesktopChannel.ts
│   │   ├── buildElectron.ts
│   │   ├── mergeMacReleaseFiles.js
│   │   └── setDesktopVersion.ts
│   ├── generate-oidc-jwk.mjs
│   ├── generateSpaTemplates.mts
│   ├── hotfixWorkflow/
│   │   └── index.ts
│   ├── i18nWorkflow/
│   │   ├── analyzeUnusedKeys.ts
│   │   ├── cleanUnusedKeys.ts
│   │   ├── const.ts
│   │   ├── flattenLocaleKeys.ts
│   │   ├── genDefaultLocale.ts
│   │   ├── genDiff.ts
│   │   ├── i18nConfig.ts
│   │   ├── index.ts
│   │   ├── protectedPatterns.ts
│   │   └── utils.ts
│   ├── mdxWorkflow/
│   │   └── index.ts
│   ├── migrate-spa-navigation.ts
│   ├── migrateServerDB/
│   │   ├── docker.cjs
│   │   ├── errorHint.js
│   │   └── index.ts
│   ├── mobileSpaWorkflow/
│   │   ├── index.ts
│   │   ├── template.ts
│   │   └── upload.ts
│   ├── nextauth-to-betterauth/
│   │   ├── _internal/
│   │   │   ├── config.ts
│   │   │   ├── db.ts
│   │   │   └── env.ts
│   │   ├── index.ts
│   │   └── verify.ts
│   ├── readmeWorkflow/
│   │   ├── const.ts
│   │   ├── index.ts
│   │   ├── syncAgentIndex.ts
│   │   ├── syncPluginIndex.ts
│   │   ├── syncProviderIndex.ts
│   │   └── utlis.ts
│   ├── registerDesktopEnv.cjs
│   ├── releaseWorkflow/
│   │   └── index.ts
│   ├── replaceComponentImports.ts
│   ├── runNextDesktop.mts
│   ├── serverLauncher/
│   │   └── startServer.js
│   ├── setup-test-postgres-db.sh
│   └── vercelIgnoredBuildStep.js
├── src/
│   ├── app/
│   │   ├── (backend)/
│   │   │   ├── _deprecated/
│   │   │   │   └── createBizOpenAI/
│   │   │   │       ├── auth.test.ts
│   │   │   │       ├── auth.ts
│   │   │   │       ├── createAzureOpenai.ts
│   │   │   │       ├── createOpenai.ts
│   │   │   │       └── index.ts
│   │   │   ├── api/
│   │   │   │   ├── agent/
│   │   │   │   │   ├── gateway/
│   │   │   │   │   │   ├── route.ts
│   │   │   │   │   │   └── start/
│   │   │   │   │   │       └── route.ts
│   │   │   │   │   ├── route.ts
│   │   │   │   │   ├── run/
│   │   │   │   │   │   └── route.ts
│   │   │   │   │   ├── stream/
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   └── route.test.ts
│   │   │   │   │   │   └── route.ts
│   │   │   │   │   └── webhooks/
│   │   │   │   │       ├── [platform]/
│   │   │   │   │       │   └── [[...appId]]/
│   │   │   │   │       │       └── route.ts
│   │   │   │   │       └── bot-callback/
│   │   │   │   │           └── route.ts
│   │   │   │   ├── auth/
│   │   │   │   │   ├── [...all]/
│   │   │   │   │   │   └── route.ts
│   │   │   │   │   ├── check-user/
│   │   │   │   │   │   └── route.ts
│   │   │   │   │   └── resolve-username/
│   │   │   │   │       └── route.ts
│   │   │   │   ├── dev/
│   │   │   │   │   └── memory-user-memory/
│   │   │   │   │       └── benchmark-locomo/
│   │   │   │   │           └── route.ts
│   │   │   │   ├── v1/
│   │   │   │   │   └── [[...route]]/
│   │   │   │   │       └── route.ts
│   │   │   │   ├── version/
│   │   │   │   │   └── route.ts
│   │   │   │   ├── webhooks/
│   │   │   │   │   ├── casdoor/
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   └── route.test.ts
│   │   │   │   │   │   ├── route.ts
│   │   │   │   │   │   └── validateRequest.ts
│   │   │   │   │   ├── logto/
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   └── route.test.ts
│   │   │   │   │   │   ├── route.ts
│   │   │   │   │   │   └── validateRequest.ts
│   │   │   │   │   ├── memory-extraction/
│   │   │   │   │   │   ├── benchmark-locomo/
│   │   │   │   │   │   │   └── route.ts
│   │   │   │   │   │   └── route.ts
│   │   │   │   │   ├── memory-user-memory/
│   │   │   │   │   │   └── persona/
│   │   │   │   │   │       └── update-writing/
│   │   │   │   │   │           └── route.ts
│   │   │   │   │   └── video/
│   │   │   │   │       └── [provider]/
│   │   │   │   │           └── route.ts
│   │   │   │   └── workflows/
│   │   │   │       ├── agent-eval-run/
│   │   │   │       │   ├── execute-test-case/
│   │   │   │       │   │   └── route.ts
│   │   │   │       │   ├── finalize-run/
│   │   │   │       │   │   └── route.ts
│   │   │   │       │   ├── on-thread-complete/
│   │   │   │       │   │   └── route.ts
│   │   │   │       │   ├── on-trajectory-complete/
│   │   │   │       │   │   └── route.ts
│   │   │   │       │   ├── paginate-test-cases/
│   │   │   │       │   │   └── route.ts
│   │   │   │       │   ├── run-agent-trajectory/
│   │   │   │       │   │   └── route.ts
│   │   │   │       │   ├── run-benchmark/
│   │   │   │       │   │   └── route.ts
│   │   │   │       │   └── run-thread-trajectory/
│   │   │   │       │       └── route.ts
│   │   │   │       └── memory-user-memory/
│   │   │   │           ├── call-cron-hourly-analysis/
│   │   │   │           │   └── route.ts
│   │   │   │           └── pipelines/
│   │   │   │               ├── chat-topic/
│   │   │   │               │   ├── [...any]/
│   │   │   │               │   │   └── route.ts
│   │   │   │               │   ├── process-topic/
│   │   │   │               │   │   └── workflows/
│   │   │   │               │   │       └── topic.ts
│   │   │   │               │   ├── process-topics/
│   │   │   │               │   │   └── route.ts
│   │   │   │               │   ├── process-user-topics/
│   │   │   │               │   │   └── route.ts
│   │   │   │               │   └── process-users/
│   │   │   │               │       └── route.ts
│   │   │   │               └── persona/
│   │   │   │                   └── update-writing/
│   │   │   │                       └── route.ts
│   │   │   ├── f/
│   │   │   │   └── [id]/
│   │   │   │       └── route.ts
│   │   │   ├── market/
│   │   │   │   ├── agent/
│   │   │   │   │   └── [[...segments]]/
│   │   │   │   │       └── route.ts
│   │   │   │   ├── oidc/
│   │   │   │   │   └── [[...segments]]/
│   │   │   │   │       └── route.ts
│   │   │   │   ├── social/
│   │   │   │   │   └── [[...segments]]/
│   │   │   │   │       └── route.ts
│   │   │   │   └── user/
│   │   │   │       ├── [username]/
│   │   │   │       │   └── route.ts
│   │   │   │       └── me/
│   │   │   │           └── route.ts
│   │   │   ├── middleware/
│   │   │   │   ├── auth/
│   │   │   │   │   ├── index.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── utils.test.ts
│   │   │   │   │   └── utils.ts
│   │   │   │   └── validate/
│   │   │   │       ├── createValidator.test.ts
│   │   │   │       ├── createValidator.ts
│   │   │   │       └── index.ts
│   │   │   ├── oidc/
│   │   │   │   ├── [...oidc]/
│   │   │   │   │   └── route.ts
│   │   │   │   ├── callback/
│   │   │   │   │   └── desktop/
│   │   │   │   │       └── route.ts
│   │   │   │   ├── consent/
│   │   │   │   │   └── route.ts
│   │   │   │   └── handoff/
│   │   │   │       └── route.ts
│   │   │   ├── trpc/
│   │   │   │   ├── async/
│   │   │   │   │   └── [trpc]/
│   │   │   │   │       └── route.ts
│   │   │   │   ├── lambda/
│   │   │   │   │   └── [trpc]/
│   │   │   │   │       └── route.ts
│   │   │   │   ├── mobile/
│   │   │   │   │   └── [trpc]/
│   │   │   │   │       └── route.ts
│   │   │   │   ├── tools/
│   │   │   │   │   └── [trpc]/
│   │   │   │   │       └── route.ts
│   │   │   │   └── trpc.test.ts
│   │   │   └── webapi/
│   │   │       ├── chat/
│   │   │       │   └── [provider]/
│   │   │       │       ├── route.test.ts
│   │   │       │       └── route.ts
│   │   │       ├── create-image/
│   │   │       │   └── comfyui/
│   │   │       │       └── route.ts
│   │   │       ├── models/
│   │   │       │   └── [provider]/
│   │   │       │       ├── pull/
│   │   │       │       │   └── route.ts
│   │   │       │       ├── route.test.ts
│   │   │       │       └── route.ts
│   │   │       ├── plugin/
│   │   │       │   └── gateway/
│   │   │       │       └── route.ts
│   │   │       ├── proxy/
│   │   │       │   └── route.ts
│   │   │       ├── revalidate/
│   │   │       │   └── route.ts
│   │   │       ├── stt/
│   │   │       │   └── openai/
│   │   │       │       └── route.ts
│   │   │       ├── trace/
│   │   │       │   └── route.ts
│   │   │       ├── tts/
│   │   │       │   ├── edge/
│   │   │       │   │   └── route.ts
│   │   │       │   ├── microsoft/
│   │   │       │   │   └── route.ts
│   │   │       │   └── openai/
│   │   │       │       └── route.ts
│   │   │       └── user/
│   │   │           └── avatar/
│   │   │               └── [id]/
│   │   │                   └── [image]/
│   │   │                       └── route.ts
│   │   ├── [variants]/
│   │   │   ├── (auth)/
│   │   │   │   ├── _layout/
│   │   │   │   │   ├── AuthGlobalProvider.tsx
│   │   │   │   │   ├── AuthLangButton.tsx
│   │   │   │   │   ├── AuthLocale.tsx
│   │
Download .txt
Showing preview only (1,324K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (13427 symbols across 3598 files)

FILE: .github/scripts/auto-close-duplicates.ts
  type GitHubIssue (line 11) | interface GitHubIssue {
  type GitHubComment (line 18) | interface GitHubComment {
  type GitHubReaction (line 25) | interface GitHubReaction {
  function githubRequest (line 30) | async function githubRequest<T>(
  function extractDuplicateIssueNumber (line 54) | function extractDuplicateIssueNumber(commentBody: string): number | null {
  function closeIssueAsDuplicate (line 70) | async function closeIssueAsDuplicate(
  function autoCloseDuplicates (line 92) | async function autoCloseDuplicates(): Promise<void> {

FILE: .github/scripts/create-failure-issue.js
  function getErrorCategoryHelp (line 189) | function getErrorCategoryHelp(category) {
  function getFailureCount (line 240) | async function getFailureCount(github, context, issueNumber) {

FILE: apps/cli/e2e/agent.e2e.test.ts
  constant CLI (line 18) | const CLI = process.env.LH_CLI_PATH || 'lh';
  constant TIMEOUT (line 19) | const TIMEOUT = 30_000;
  function run (line 21) | function run(args: string): string {
  function runJson (line 29) | function runJson<T = any>(args: string): T {

FILE: apps/cli/e2e/doc.e2e.test.ts
  constant CLI (line 19) | const CLI = process.env.LH_CLI_PATH || 'lh';
  constant TIMEOUT (line 20) | const TIMEOUT = 30_000;
  function run (line 22) | function run(args: string): string {
  function runJson (line 30) | function runJson<T = any>(args: string): T {
  function extractDocId (line 35) | function extractDocId(output: string): string {

FILE: apps/cli/e2e/file.e2e.test.ts
  constant CLI (line 14) | const CLI = process.env.LH_CLI_PATH || 'lh';
  constant TIMEOUT (line 15) | const TIMEOUT = 30_000;
  function run (line 17) | function run(args: string): string {
  function runJson (line 25) | function runJson<T = any>(args: string): T {

FILE: apps/cli/e2e/generate.e2e.test.ts
  constant CLI (line 14) | const CLI = process.env.LH_CLI_PATH || 'lh';
  constant TIMEOUT (line 15) | const TIMEOUT = 30_000;
  function run (line 17) | function run(args: string): string {
  function runJson (line 25) | function runJson<T = any>(args: string): T {

FILE: apps/cli/e2e/kb.e2e.test.ts
  constant CLI (line 19) | const CLI = process.env.LH_CLI_PATH || 'lh';
  constant TIMEOUT (line 20) | const TIMEOUT = 30_000;
  function run (line 22) | function run(args: string): string {
  function runJson (line 30) | function runJson<T = any>(args: string): T {
  function extractId (line 35) | function extractId(output: string, prefix: string): string {

FILE: apps/cli/e2e/memory.e2e.test.ts
  constant CLI (line 16) | const CLI = process.env.LH_CLI_PATH || 'lh';
  constant TIMEOUT (line 17) | const TIMEOUT = 60_000;
  function run (line 19) | function run(args: string): string {
  function runJson (line 27) | function runJson<T = any>(args: string): T {

FILE: apps/cli/e2e/message.e2e.test.ts
  constant CLI (line 14) | const CLI = process.env.LH_CLI_PATH || 'lh';
  constant TIMEOUT (line 15) | const TIMEOUT = 30_000;
  function run (line 17) | function run(args: string): string {
  function runJson (line 25) | function runJson<T = any>(args: string): T {

FILE: apps/cli/e2e/model.e2e.test.ts
  constant CLI (line 17) | const CLI = process.env.LH_CLI_PATH || 'lh';
  constant TIMEOUT (line 18) | const TIMEOUT = 30_000;
  constant TEST_PROVIDER (line 19) | const TEST_PROVIDER = 'openai';
  function run (line 21) | function run(args: string): string {
  function runJson (line 29) | function runJson<T = any>(args: string): T {

FILE: apps/cli/e2e/plugin.e2e.test.ts
  constant CLI (line 14) | const CLI = process.env.LH_CLI_PATH || 'lh';
  constant TIMEOUT (line 15) | const TIMEOUT = 30_000;
  function run (line 17) | function run(args: string): string {
  function runJson (line 25) | function runJson<T = any>(args: string): T {

FILE: apps/cli/e2e/provider.e2e.test.ts
  constant CLI (line 16) | const CLI = process.env.LH_CLI_PATH || 'lh';
  constant TIMEOUT (line 17) | const TIMEOUT = 30_000;
  function run (line 19) | function run(args: string): string {
  function runJson (line 27) | function runJson<T = any>(args: string): T {

FILE: apps/cli/e2e/search.e2e.test.ts
  constant CLI (line 14) | const CLI = process.env.LH_CLI_PATH || 'lh';
  constant TIMEOUT (line 15) | const TIMEOUT = 30_000;
  function run (line 17) | function run(args: string): string {
  function runJson (line 25) | function runJson<T = any>(args: string): T {

FILE: apps/cli/e2e/skill.e2e.test.ts
  constant CLI (line 16) | const CLI = process.env.LH_CLI_PATH || 'lh';
  constant TIMEOUT (line 17) | const TIMEOUT = 30_000;
  function run (line 19) | function run(args: string): string {
  function runJson (line 27) | function runJson<T = any>(args: string): T {

FILE: apps/cli/e2e/topic.e2e.test.ts
  constant CLI (line 16) | const CLI = process.env.LH_CLI_PATH || 'lh';
  constant TIMEOUT (line 17) | const TIMEOUT = 30_000;
  function run (line 19) | function run(args: string): string {
  function runJson (line 27) | function runJson<T = any>(args: string): T {

FILE: apps/cli/src/api/client.ts
  type TrpcClient (line 12) | type TrpcClient = ReturnType<typeof createTRPCClient<LambdaRouter>>;
  type ToolsTrpcClient (line 13) | type ToolsTrpcClient = ReturnType<typeof createTRPCClient<ToolsRouter>>;
  function getAuthAndServer (line 18) | async function getAuthAndServer() {
  function getTrpcClient (line 54) | async function getTrpcClient(): Promise<TrpcClient> {
  function getToolsTrpcClient (line 71) | async function getToolsTrpcClient(): Promise<ToolsTrpcClient> {

FILE: apps/cli/src/api/http.ts
  constant SECRET_XOR_KEY (line 7) | const SECRET_XOR_KEY = 'LobeHub · LobeHub';
  function obfuscatePayloadWithXOR (line 13) | function obfuscatePayloadWithXOR(payload: Record<string, any>): string {
  type AuthInfo (line 26) | interface AuthInfo {
  function getAuthInfo (line 33) | async function getAuthInfo(): Promise<AuthInfo> {

FILE: apps/cli/src/auth/apiKey.ts
  type CurrentUserResponse (line 3) | interface CurrentUserResponse {
  function getUserIdFromApiKey (line 13) | async function getUserIdFromApiKey(apiKey: string, serverUrl?: string): ...

FILE: apps/cli/src/auth/credentials.ts
  type StoredCredentials (line 6) | interface StoredCredentials {
  constant LOBEHUB_DIR_NAME (line 12) | const LOBEHUB_DIR_NAME = process.env.LOBEHUB_CLI_HOME || '.lobehub';
  constant CREDENTIALS_DIR (line 13) | const CREDENTIALS_DIR = path.join(os.homedir(), LOBEHUB_DIR_NAME);
  constant CREDENTIALS_FILE (line 14) | const CREDENTIALS_FILE = path.join(CREDENTIALS_DIR, 'credentials.json');
  function deriveKey (line 18) | function deriveKey(): Buffer {
  function encrypt (line 23) | function encrypt(plaintext: string): string {
  function decrypt (line 34) | function decrypt(encoded: string): string {
  function saveCredentials (line 45) | function saveCredentials(credentials: StoredCredentials): void {
  function loadCredentials (line 51) | function loadCredentials(): StoredCredentials | null {
  function clearCredentials (line 70) | function clearCredentials(): boolean {

FILE: apps/cli/src/auth/refresh.ts
  constant CLIENT_ID (line 4) | const CLIENT_ID = 'lobehub-cli';
  function getValidToken (line 10) | async function getValidToken(): Promise<{ credentials: StoredCredentials...
  type TokenResponse (line 38) | interface TokenResponse {
  function refreshAccessToken (line 45) | async function refreshAccessToken(

FILE: apps/cli/src/auth/resolveToken.test.ts
  function makeJwt (line 29) | function makeJwt(sub: string): string {

FILE: apps/cli/src/auth/resolveToken.ts
  type ResolveTokenOptions (line 7) | interface ResolveTokenOptions {
  type ResolvedAuth (line 13) | interface ResolvedAuth {
  function parseJwtSub (line 23) | function parseJwtSub(token: string): string | undefined {
  function resolveToken (line 36) | async function resolveToken(options: ResolveTokenOptions): Promise<Resol...

FILE: apps/cli/src/commands/agent-group.test.ts
  function createProgram (line 51) | function createProgram() {

FILE: apps/cli/src/commands/agent-group.ts
  function registerAgentGroupCommand (line 8) | function registerAgentGroupCommand(program: Command) {

FILE: apps/cli/src/commands/agent.test.ts
  function createProgram (line 84) | function createProgram() {

FILE: apps/cli/src/commands/agent.ts
  function resolveAgentId (line 16) | async function resolveAgentId(
  function registerAgentCommand (line 36) | function registerAgentCommand(program: Command) {
  function colorStatus (line 559) | function colorStatus(status: string): string {

FILE: apps/cli/src/commands/bot.test.ts
  function createProgram (line 50) | function createProgram() {

FILE: apps/cli/src/commands/bot.ts
  function maskValue (line 12) | function maskValue(val: string): string {
  function camelToFlag (line 17) | function camelToFlag(name: string): string {
  function getCredentialFields (line 22) | function getCredentialFields(platformDef: any): any[] {
  function extractCredentials (line 30) | function extractCredentials(
  function findBot (line 49) | async function findBot(client: TrpcClient, botId: string) {
  constant STATUS_COLORS (line 59) | const STATUS_COLORS: Record<string, (s: string) => string> = {
  function resolvePlatform (line 69) | async function resolvePlatform(client: TrpcClient, platformId: string) {
  function registerBotCommand (line 83) | function registerBotCommand(program: Command) {

FILE: apps/cli/src/commands/botMessage.ts
  function registerBotMessageCommands (line 9) | function registerBotMessageCommands(bot: Command) {
  function collectOptions (line 562) | function collectOptions(value: string, previous: string[]): string[] {

FILE: apps/cli/src/commands/brief.ts
  function registerBriefCommand (line 8) | function registerBriefCommand(program: Command) {
  function typeBadge (line 189) | function typeBadge(type: string, priority?: string): string {

FILE: apps/cli/src/commands/completion.test.ts
  function createProgram (line 20) | function createProgram() {

FILE: apps/cli/src/commands/completion.ts
  function registerCompletionCommand (line 10) | function registerCompletionCommand(program: Command) {

FILE: apps/cli/src/commands/config.test.ts
  function createProgram (line 46) | function createProgram() {

FILE: apps/cli/src/commands/config.ts
  function registerConfigCommand (line 14) | function registerConfigCommand(program: Command) {

FILE: apps/cli/src/commands/connect.test.ts
  function createProgram (line 126) | function createProgram() {

FILE: apps/cli/src/commands/connect.ts
  type ConnectOptions (line 32) | interface ConnectOptions {
  function registerConnectCommand (line 41) | function registerConnectCommand(program: Command) {
  function handleDaemonStart (line 144) | function handleDaemonStart(options: ConnectOptions) {
  function buildDaemonArgs (line 162) | function buildDaemonArgs(options: ConnectOptions): string[] {
  function runConnect (line 175) | async function runConnect(options: ConnectOptions, isDaemonChild: boolea...
  function createDaemonLogger (line 356) | function createDaemonLogger() {
  function formatUptime (line 365) | function formatUptime(startedAt: Date): string {
  function collectSystemInfo (line 378) | function collectSystemInfo(): DeviceSystemInfo {

FILE: apps/cli/src/commands/cron.test.ts
  function createProgram (line 51) | function createProgram() {

FILE: apps/cli/src/commands/cron.ts
  function registerCronCommand (line 8) | function registerCronCommand(program: Command) {

FILE: apps/cli/src/commands/device.ts
  function registerDeviceCommand (line 8) | function registerDeviceCommand(program: Command) {

FILE: apps/cli/src/commands/doc.test.ts
  function resetMocks (line 54) | function resetMocks(obj: Record<string, any>) {
  function createProgram (line 78) | function createProgram() {

FILE: apps/cli/src/commands/doc.ts
  function readBodyContent (line 12) | function readBodyContent(options: { body?: string; bodyFile?: string }):...
  function registerDocCommand (line 25) | function registerDocCommand(program: Command) {

FILE: apps/cli/src/commands/eval.ts
  constant JSON_VERSION (line 8) | const JSON_VERSION = 'v1' as const;
  type JsonError (line 10) | interface JsonError {
  type JsonEnvelope (line 15) | interface JsonEnvelope<T> {
  type JsonOption (line 22) | interface JsonOption {
  function registerEvalCommand (line 142) | function registerEvalCommand(program: Command) {

FILE: apps/cli/src/commands/file.test.ts
  function createProgram (line 53) | function createProgram() {

FILE: apps/cli/src/commands/file.ts
  function registerFileCommand (line 8) | function registerFileCommand(program: Command) {

FILE: apps/cli/src/commands/generate.test.ts
  function createProgram (line 84) | function createProgram() {
  method start (line 137) | start(controller) {

FILE: apps/cli/src/commands/generate/asr.ts
  function registerAsrCommand (line 9) | function registerAsrCommand(parent: Command) {
  function readFileAsBlob (line 70) | async function readFileAsBlob(filePath: string): Promise<Blob> {

FILE: apps/cli/src/commands/generate/image.ts
  function registerImageCommand (line 6) | function registerImageCommand(parent: Command) {

FILE: apps/cli/src/commands/generate/index.ts
  function registerGenerateCommand (line 12) | function registerGenerateCommand(program: Command) {
  function colorStatus (line 191) | function colorStatus(status: string): string {

FILE: apps/cli/src/commands/generate/text.ts
  function registerTextCommand (line 6) | function registerTextCommand(parent: Command) {
  function streamSSEResponse (line 113) | async function streamSSEResponse(body: ReadableStream<Uint8Array>, json?...

FILE: apps/cli/src/commands/generate/tts.ts
  function registerTtsCommand (line 9) | function registerTtsCommand(parent: Command) {

FILE: apps/cli/src/commands/generate/video.ts
  function registerVideoCommand (line 6) | function registerVideoCommand(parent: Command) {

FILE: apps/cli/src/commands/kb.test.ts
  function createProgram (line 61) | function createProgram() {

FILE: apps/cli/src/commands/kb.ts
  function formatFileType (line 13) | function formatFileType(fileType: string): string {
  function registerKbCommand (line 32) | function registerKbCommand(program: Command) {

FILE: apps/cli/src/commands/login.test.ts
  function createProgram (line 67) | function createProgram() {
  function deviceAuthResponse (line 74) | function deviceAuthResponse(overrides: Record<string, any> = {}) {
  function tokenSuccessResponse (line 89) | function tokenSuccessResponse(overrides: Record<string, any> = {}) {
  function tokenErrorResponse (line 102) | function tokenErrorResponse(error: string, description?: string) {
  function runLogin (line 112) | async function runLogin(program: Command, args: string[] = []) {
  function runLoginAndAdvanceTimers (line 116) | async function runLoginAndAdvanceTimers(program: Command, args: string[]...

FILE: apps/cli/src/commands/login.ts
  constant CLIENT_ID (line 14) | const CLIENT_ID = 'lobehub-cli';
  constant SCOPES (line 15) | const SCOPES = 'openid profile email offline_access';
  type LoginOptions (line 17) | interface LoginOptions {
  type DeviceAuthResponse (line 21) | interface DeviceAuthResponse {
  type TokenResponse (line 30) | interface TokenResponse {
  type TokenErrorResponse (line 37) | interface TokenErrorResponse {
  function parseJsonResponse (line 42) | async function parseJsonResponse<T>(res: Response, endpoint: string): Pr...
  function registerLoginCommand (line 53) | function registerLoginCommand(program: Command) {
  function sleep (line 229) | function sleep(ms: number): Promise<void> {
  function resolveCommandExecutable (line 233) | function resolveCommandExecutable(
  function openBrowser (line 278) | async function openBrowser(url: string): Promise<boolean> {

FILE: apps/cli/src/commands/logout.test.ts
  function createProgram (line 22) | function createProgram() {

FILE: apps/cli/src/commands/logout.ts
  function registerLogoutCommand (line 6) | function registerLogoutCommand(program: Command) {

FILE: apps/cli/src/commands/man.test.ts
  function createProgram (line 17) | function createProgram() {

FILE: apps/cli/src/commands/man.ts
  constant ROOT_ALIASES (line 3) | const ROOT_ALIASES = ['lobe', 'lobehub'];
  constant HELP_COMMAND_NAME (line 4) | const HELP_COMMAND_NAME = 'help';
  type DefinitionItem (line 6) | interface DefinitionItem {
  type ResolutionResult (line 11) | interface ResolutionResult {
  function registerManCommand (line 16) | function registerManCommand(program: Command) {
  function resolveCommandPath (line 33) | function resolveCommandPath(root: Command, segments: string[]): Resoluti...
  function renderManualPage (line 58) | function renderManualPage(root: Command, command: Command) {
  function formatManualHeader (line 74) | function formatManualHeader(command: Command) {
  function formatNameSection (line 78) | function formatNameSection(command: Command) {
  function formatSynopsisSection (line 82) | function formatSynopsisSection(root: Command, command: Command) {
  function formatAliasesSection (line 86) | function formatAliasesSection(command: Command) {
  function formatDescriptionSection (line 94) | function formatDescriptionSection(command: Command) {
  function formatArgumentsSection (line 100) | function formatArgumentsSection(command: Command) {
  function formatCommandsSection (line 111) | function formatCommandsSection(command: Command) {
  function formatOptionsSection (line 123) | function formatOptionsSection(command: Command) {
  function formatSeeAlsoSection (line 135) | function formatSeeAlsoSection(root: Command, command: Command) {
  function getVisibleCommands (line 154) | function getVisibleCommands(command: Command) {
  function buildSynopsis (line 162) | function buildSynopsis(root: Command, command: Command) {
  function buildCommandPath (line 172) | function buildCommandPath(command: Command): string[] {
  function buildSubcommandTerm (line 184) | function buildSubcommandTerm(command: Command) {
  function formatDefinitionList (line 191) | function formatDefinitionList(items: DefinitionItem[]) {
  function formatArgumentTerm (line 197) | function formatArgumentTerm(argument: Argument) {
  function describeArgument (line 207) | function describeArgument(argument: Argument) {

FILE: apps/cli/src/commands/memory.test.ts
  function createProgram (line 55) | function createProgram() {

FILE: apps/cli/src/commands/memory.ts
  constant CATEGORIES (line 10) | const CATEGORIES = ['identity', 'activity', 'context', 'experience', 'pr...
  type Category (line 11) | type Category = (typeof CATEGORIES)[number];
  function capitalize (line 13) | function capitalize(s: string): string {
  function registerMemoryCommand (line 17) | function registerMemoryCommand(program: Command) {
  function fetchCategory (line 273) | async function fetchCategory(client: any, category: Category): Promise<a...
  function buildCategoryInput (line 297) | function buildCategoryInput(category: Category, options: Record<string, ...

FILE: apps/cli/src/commands/message.test.ts
  function createProgram (line 50) | function createProgram() {

FILE: apps/cli/src/commands/message.ts
  function registerMessageCommand (line 8) | function registerMessageCommand(program: Command) {

FILE: apps/cli/src/commands/model.test.ts
  function createProgram (line 55) | function createProgram() {

FILE: apps/cli/src/commands/model.ts
  function registerModelCommand (line 8) | function registerModelCommand(program: Command) {

FILE: apps/cli/src/commands/plugin.test.ts
  function createProgram (line 49) | function createProgram() {

FILE: apps/cli/src/commands/plugin.ts
  function registerPluginCommand (line 8) | function registerPluginCommand(program: Command) {

FILE: apps/cli/src/commands/provider.test.ts
  function createProgram (line 52) | function createProgram() {

FILE: apps/cli/src/commands/provider.ts
  function registerProviderCommand (line 8) | function registerProviderCommand(program: Command) {

FILE: apps/cli/src/commands/search.test.ts
  function createProgram (line 40) | function createProgram() {

FILE: apps/cli/src/commands/search.ts
  constant SEARCH_TYPES (line 7) | const SEARCH_TYPES = [
  type SearchType (line 21) | type SearchType = (typeof SEARCH_TYPES)[number];
  function renderResultGroup (line 23) | function renderResultGroup(type: string, items: any[]) {
  function registerSearchCommand (line 38) | function registerSearchCommand(program: Command) {
  function localSearch (line 109) | async function localSearch(
  function webSearch (line 163) | async function webSearch(
  function crawlView (line 219) | async function crawlView(url: string, options: { impl?: string; json?: s...
  function localView (line 255) | async function localView(target: string, options: { json?: string | bool...

FILE: apps/cli/src/commands/session-group.test.ts
  function createProgram (line 48) | function createProgram() {

FILE: apps/cli/src/commands/session-group.ts
  function registerSessionGroupCommand (line 8) | function registerSessionGroupCommand(program: Command) {

FILE: apps/cli/src/commands/skill.test.ts
  function createProgram (line 58) | function createProgram() {

FILE: apps/cli/src/commands/skill.ts
  type SourceType (line 8) | type SourceType = 'github' | 'market' | 'url';
  function detectSourceType (line 10) | function detectSourceType(source: string): SourceType {
  function registerSkillCommand (line 27) | function registerSkillCommand(program: Command) {

FILE: apps/cli/src/commands/status.test.ts
  function createProgram (line 72) | function createProgram() {

FILE: apps/cli/src/commands/status.ts
  type StatusOptions (line 9) | interface StatusOptions {
  function registerStatusCommand (line 18) | function registerStatusCommand(program: Command) {

FILE: apps/cli/src/commands/task/checkpoint.ts
  function registerCheckpointCommands (line 7) | function registerCheckpointCommands(task: Command) {

FILE: apps/cli/src/commands/task/dep.ts
  function registerDepCommands (line 7) | function registerDepCommands(task: Command) {

FILE: apps/cli/src/commands/task/doc.ts
  function registerDocCommands (line 7) | function registerDocCommands(task: Command) {

FILE: apps/cli/src/commands/task/helpers.ts
  function statusBadge (line 3) | function statusBadge(status: string): string {
  function briefIcon (line 36) | function briefIcon(type: string): string {
  function priorityLabel (line 56) | function priorityLabel(priority: number | null | undefined): string {

FILE: apps/cli/src/commands/task/index.ts
  function registerTaskCommand (line 22) | function registerTaskCommand(program: Command) {

FILE: apps/cli/src/commands/task/lifecycle.ts
  function registerLifecycleCommands (line 9) | function registerLifecycleCommands(task: Command) {

FILE: apps/cli/src/commands/task/review.ts
  function registerReviewCommands (line 8) | function registerReviewCommands(task: Command) {

FILE: apps/cli/src/commands/task/topic.ts
  function registerTopicCommands (line 9) | function registerTopicCommands(task: Command) {

FILE: apps/cli/src/commands/thread.test.ts
  function createProgram (line 46) | function createProgram() {

FILE: apps/cli/src/commands/thread.ts
  function registerThreadCommand (line 7) | function registerThreadCommand(program: Command) {

FILE: apps/cli/src/commands/topic.test.ts
  function createProgram (line 51) | function createProgram() {

FILE: apps/cli/src/commands/topic.ts
  function registerTopicCommand (line 10) | function registerTopicCommand(program: Command) {

FILE: apps/cli/src/commands/user.test.ts
  function createProgram (line 50) | function createProgram() {

FILE: apps/cli/src/commands/user.ts
  function registerUserCommand (line 8) | function registerUserCommand(program: Command) {

FILE: apps/cli/src/constants/auth.ts
  constant CLI_API_KEY_ENV (line 1) | const CLI_API_KEY_ENV = 'LOBEHUB_CLI_API_KEY';

FILE: apps/cli/src/constants/urls.ts
  constant OFFICIAL_SERVER_URL (line 1) | const OFFICIAL_SERVER_URL = 'https://app.lobehub.com';
  constant OFFICIAL_GATEWAY_URL (line 2) | const OFFICIAL_GATEWAY_URL = 'https://device-gateway.lobehub.com';

FILE: apps/cli/src/daemon/manager.ts
  constant MAX_LOG_SIZE (line 6) | const MAX_LOG_SIZE = 5 * 1024 * 1024;
  function getLobehubDir (line 8) | function getLobehubDir() {
  function getPidPath (line 12) | function getPidPath() {
  function getStatusPath (line 16) | function getStatusPath() {
  function getLogFilePath (line 20) | function getLogFilePath() {
  type DaemonStatus (line 24) | interface DaemonStatus {
  function ensureDir (line 31) | function ensureDir() {
  function readPid (line 37) | function readPid(): number | null {
  function writePid (line 47) | function writePid(pid: number): void {
  function removePid (line 52) | function removePid(): void {
  function isProcessAlive (line 63) | function isProcessAlive(pid: number): boolean {
  function getRunningDaemonPid (line 76) | function getRunningDaemonPid(): number | null {
  function writeStatus (line 90) | function writeStatus(status: DaemonStatus): void {
  function readStatus (line 95) | function readStatus(): DaemonStatus | null {
  function removeStatus (line 103) | function removeStatus(): void {
  function getLogPath (line 113) | function getLogPath(): string {
  function rotateLogIfNeeded (line 120) | function rotateLogIfNeeded(): void {
  function appendLog (line 141) | function appendLog(line: string): void {
  function spawnDaemon (line 154) | function spawnDaemon(args: string[]): number {
  function stopDaemon (line 179) | function stopDaemon(): boolean {

FILE: apps/cli/src/man/roff.ts
  constant ROOT_ALIASES (line 3) | const ROOT_ALIASES = ['lobe', 'lobehub'];
  constant HELP_COMMAND_NAME (line 4) | const HELP_COMMAND_NAME = 'help';
  type RoffDefinition (line 6) | interface RoffDefinition {
  constant FILE_ENTRIES (line 11) | const FILE_ENTRIES = [
  constant EXAMPLES (line 34) | const EXAMPLES = [
  function generateRootManPage (line 57) | function generateRootManPage(program: Command, version: string) {
  function generateAliasManPage (line 115) | function generateAliasManPage(target: string) {
  function formatSynopsisLines (line 119) | function formatSynopsisLines() {
  function getVisibleCommands (line 125) | function getVisibleCommands(command: Command) {
  function formatCommandDescription (line 132) | function formatCommandDescription(description: string, aliases: string[]) {
  function formatDefinitionSection (line 138) | function formatDefinitionSection(items: RoffDefinition[], macro: 'B' | '...
  function escapeRoff (line 146) | function escapeRoff(value: string) {

FILE: apps/cli/src/program.ts
  function createProgram (line 37) | function createProgram() {

FILE: apps/cli/src/settings/index.ts
  type StoredSettings (line 8) | interface StoredSettings {
  constant LOBEHUB_DIR_NAME (line 13) | const LOBEHUB_DIR_NAME = process.env.LOBEHUB_CLI_HOME || '.lobehub';
  constant SETTINGS_DIR (line 14) | const SETTINGS_DIR = path.join(os.homedir(), LOBEHUB_DIR_NAME);
  constant SETTINGS_FILE (line 15) | const SETTINGS_FILE = path.join(SETTINGS_DIR, 'settings.json');
  function normalizeUrl (line 17) | function normalizeUrl(url: string | undefined): string | undefined {
  function resolveServerUrl (line 21) | function resolveServerUrl(): string {
  function saveSettings (line 28) | function saveSettings(settings: StoredSettings): void {
  function loadSettings (line 47) | function loadSettings(): StoredSettings | null {

FILE: apps/cli/src/tools/index.ts
  function executeToolCall (line 26) | async function executeToolCall(

FILE: apps/cli/src/tools/shell.ts
  function cleanupAllProcesses (line 13) | function cleanupAllProcesses() {
  function runCommand (line 17) | async function runCommand(params: RunCommandParams) {
  function getCommandOutput (line 21) | async function getCommandOutput(params: GetCommandOutputParams) {
  function killCommand (line 25) | async function killCommand(params: KillCommandParams) {

FILE: apps/cli/src/utils/agentStream.test.ts
  function createSSEStream (line 15) | function createSSEStream(events: string[]): ReadableStream<Uint8Array> {
  function createChunkedSSEStream (line 28) | function createChunkedSSEStream(chunks: string[]): ReadableStream<Uint8A...
  function sseMessage (line 41) | function sseMessage(type: string, data: Record<string, any>): string {

FILE: apps/cli/src/utils/agentStream.ts
  type AgentStreamEvent (line 5) | interface AgentStreamEvent {
  type StreamOptions (line 14) | interface StreamOptions {
  function streamAgentEvents (line 23) | async function streamAgentEvents(
  function replayAgentEvents (line 130) | function replayAgentEvents(events: AgentStreamEvent[], options: StreamOp...
  type RenderContext (line 157) | interface RenderContext {
  function createRenderContext (line 162) | function createRenderContext(): RenderContext {
  function renderEvent (line 166) | function renderEvent(event: AgentStreamEvent, ctx: RenderContext, option...
  function renderEnd (line 243) | function renderEnd(event: AgentStreamEvent): void {

FILE: apps/cli/src/utils/completion.ts
  constant CLI_BIN_NAMES (line 4) | const CLI_BIN_NAMES = ['lh', 'lobe', 'lobehub'] as const;
  constant SUPPORTED_SHELLS (line 5) | const SUPPORTED_SHELLS = ['bash', 'zsh'] as const;
  type SupportedShell (line 7) | type SupportedShell = (typeof SUPPORTED_SHELLS)[number];
  type HiddenCommand (line 9) | interface HiddenCommand extends Command {
  type HiddenOption (line 13) | interface HiddenOption extends Option {
  function isVisibleCommand (line 17) | function isVisibleCommand(command: Command) {
  function isVisibleOption (line 21) | function isVisibleOption(option: Option) {
  function listCommandTokens (line 25) | function listCommandTokens(command: Command) {
  function listOptionTokens (line 29) | function listOptionTokens(command: Command) {
  function findSubcommand (line 35) | function findSubcommand(command: Command, token: string) {
  function findOption (line 41) | function findOption(command: Command, token: string) {
  function filterCandidates (line 48) | function filterCandidates(candidates: string[], currentWord: string) {
  function resolveCommandContext (line 56) | function resolveCommandContext(program: Command, completedWords: string[...
  function getCompletionCandidates (line 86) | function getCompletionCandidates(
  function parseCompletionWordIndex (line 111) | function parseCompletionWordIndex(rawValue: string | undefined, words: s...
  function resolveCompletionShell (line 119) | function resolveCompletionShell(shell?: string): SupportedShell {
  function renderCompletionScript (line 132) | function renderCompletionScript(shell: SupportedShell) {

FILE: apps/cli/src/utils/format.ts
  function timeAgo (line 5) | function timeAgo(date: Date | string): string {
  function truncate (line 18) | function truncate(str: string, maxWidth: number): string {
  function printTable (line 47) | function printTable(rows: string[][], header: string[]) {
  type BoxTableColumn (line 62) | interface BoxTableColumn {
  type BoxTableRow (line 68) | interface BoxTableRow {
  function formatNumber (line 72) | function formatNumber(n: number): string {
  function formatCost (line 76) | function formatCost(n: number): string {
  function stripAnsi (line 81) | function stripAnsi(s: string): string {
  function displayWidth (line 90) | function displayWidth(s: string): number {
  function padDisplay (line 120) | function padDisplay(s: string, targetWidth: number, align: 'left' | 'rig...
  function printBoxTable (line 130) | function printBoxTable(columns: BoxTableColumn[], rows: BoxTableRow[], t...
  function pickFields (line 234) | function pickFields(obj: Record<string, any>, fields: string[]): Record<...
  function outputJson (line 242) | function outputJson(data: unknown, fields?: string) {
  type CalendarDay (line 263) | interface CalendarDay {
  constant HEATMAP_BLOCKS (line 268) | const HEATMAP_BLOCKS = [' ', '░', '▒', '▓', '█'];
  constant WEEKDAY_LABELS (line 269) | const WEEKDAY_LABELS = ['Mon', '', 'Wed', '', 'Fri', '', ''];
  function printCalendarHeatmap (line 275) | function printCalendarHeatmap(
  function confirm (line 390) | function confirm(message: string): Promise<boolean> {

FILE: apps/desktop/electron.vite.config.ts
  function electronDesktopHtmlPlugin (line 21) | function electronDesktopHtmlPlugin(): PluginOption {
  constant ROOT_DIR (line 38) | const ROOT_DIR = path.resolve(__dirname, '../..');
  method manualChunks (line 60) | manualChunks(id) {

FILE: apps/desktop/native-deps.config.mjs
  function getTargetPlatform (line 24) | function getTargetPlatform() {
  function resolveDependencies (line 49) | function resolveDependencies(
  function getAllDependencies (line 95) | function getAllDependencies() {
  function getFilesPatterns (line 112) | function getFilesPatterns() {
  function getNativeModulesFilesConfig (line 121) | function getNativeModulesFilesConfig() {
  function getAsarUnpackPatterns (line 133) | function getAsarUnpackPatterns() {
  function getExternalDependencies (line 141) | function getExternalDependencies() {
  function copyNativeModulesToSource (line 150) | async function copyNativeModulesToSource() {
  function copyNativeModules (line 191) | async function copyNativeModules(destNodeModules) {
  function copyDir (line 235) | async function copyDir(src, dest) {

FILE: apps/desktop/scripts/download-agent-browser.mjs
  constant VERSION (line 8) | const VERSION = '0.20.1';
  function download (line 58) | function download(url, dest, maxRedirects = 5) {

FILE: apps/desktop/src/common/routes.ts
  type RouteInterceptConfig (line 4) | interface RouteInterceptConfig {

FILE: apps/desktop/src/main/appBrowsers.ts
  type WindowTemplate (line 38) | interface WindowTemplate {
  type AppBrowsersIdentifiers (line 71) | type AppBrowsersIdentifiers = keyof typeof appBrowsers;
  type WindowTemplateIdentifiers (line 72) | type WindowTemplateIdentifiers = keyof typeof windowTemplates;

FILE: apps/desktop/src/main/const/dir.ts
  constant FILE_STORAGE_DIR (line 31) | const FILE_STORAGE_DIR = 'file-storage';
  constant INSTALL_PLUGINS_DIR (line 33) | const INSTALL_PLUGINS_DIR = 'plugins';
  constant LOCAL_STORAGE_URL_PREFIX (line 36) | const LOCAL_STORAGE_URL_PREFIX = '/lobe-desktop-file';

FILE: apps/desktop/src/main/const/env.ts
  constant OFFICIAL_CLOUD_SERVER (line 9) | const OFFICIAL_CLOUD_SERVER = getDesktopEnv().OFFICIAL_CLOUD_SERVER;
  function getIsMacTahoe (line 15) | function getIsMacTahoe(): boolean {
  function getIsWindows11 (line 24) | function getIsWindows11() {

FILE: apps/desktop/src/main/const/protocol.ts
  constant ELECTRON_BE_PROTOCOL_SCHEME (line 1) | const ELECTRON_BE_PROTOCOL_SCHEME = 'lobe-backend';

FILE: apps/desktop/src/main/const/store.ts
  constant STORE_NAME (line 14) | const STORE_NAME = 'lobehub-settings';
  constant STORE_DEFAULTS (line 28) | const STORE_DEFAULTS: ElectronMainStore = {

FILE: apps/desktop/src/main/const/theme.ts
  constant BACKGROUND_DARK (line 2) | const BACKGROUND_DARK = '#000';
  constant BACKGROUND_LIGHT (line 3) | const BACKGROUND_LIGHT = '#f8f8f8';
  constant SYMBOL_COLOR_DARK (line 4) | const SYMBOL_COLOR_DARK = '#ffffff80';
  constant SYMBOL_COLOR_LIGHT (line 5) | const SYMBOL_COLOR_LIGHT = '#00000080';
  constant THEME_CHANGE_DELAY (line 8) | const THEME_CHANGE_DELAY = 100;

FILE: apps/desktop/src/main/controllers/AuthCtr.ts
  constant MAX_POLL_TIME (line 21) | const MAX_POLL_TIME = 2 * 60 * 1000;
  constant POLL_INTERVAL (line 22) | const POLL_INTERVAL = 3000;
  constant TOKEN_REFRESH_DEBOUNCE (line 23) | const TOKEN_REFRESH_DEBOUNCE = 5 * 60 * 1000;
  class AuthCtr (line 29) | class AuthCtr extends ControllerModule {
    method remoteServerConfigCtr (line 34) | private get remoteServerConfigCtr() {
    method constructRedirectUri (line 61) | private constructRedirectUri(remoteUrl: string): string {
    method requestAuthorization (line 71) | async requestAuthorization(config: DataSyncConfig) {
    method cancelAuthorization (line 140) | async cancelAuthorization() {
    method requestMarketAuthorization (line 158) | async requestMarketAuthorization(params: MarketAuthorizationParams) {
    method startPolling (line 182) | private startPolling() {
    method stopPolling (line 263) | private stopPolling() {
    method clearAuthorizationState (line 274) | private clearAuthorizationState() {
    method startAutoRefresh (line 285) | private startAutoRefresh() {
    method stopAutoRefresh (line 335) | private stopAutoRefresh() {
    method pollForCredentials (line 347) | private async pollForCredentials(): Promise<{ code: string; state: str...
    method refreshAccessToken (line 406) | async refreshAccessToken() {
    method exchangeCodeForToken (line 458) | private async exchangeCodeForToken(code: string, codeVerifier: string) {
    method connectGateway (line 548) | private connectGateway() {
    method broadcastTokenRefreshed (line 561) | private broadcastTokenRefreshed() {
    method broadcastAuthorizationSuccessful (line 575) | private broadcastAuthorizationSuccessful() {
    method broadcastAuthorizationProgress (line 589) | private broadcastAuthorizationProgress(progress: AuthorizationProgress) {
    method broadcastAuthorizationFailed (line 604) | private broadcastAuthorizationFailed(error: string) {
    method broadcastAuthorizationRequired (line 618) | private broadcastAuthorizationRequired() {
    method generateCodeVerifier (line 632) | private generateCodeVerifier(): string {
    method generateCodeChallenge (line 648) | private async generateCodeChallenge(codeVerifier: string): Promise<str...
    method afterAppReady (line 668) | afterAppReady() {
    method cleanup (line 676) | cleanup() {
    method initializeAutoRefresh (line 687) | private async initializeAutoRefresh() {
    method shouldProactivelyRefresh (line 745) | private shouldProactivelyRefresh(): boolean {
    method performProactiveRefresh (line 773) | private async performProactiveRefresh(): Promise<void> {
    method onAppActivate (line 800) | async onAppActivate(): Promise<void> {

FILE: apps/desktop/src/main/controllers/BrowserWindowsCtr.ts
  class BrowserWindowsCtr (line 14) | class BrowserWindowsCtr extends ControllerModule {
    method toggleMainWindow (line 18) | async toggleMainWindow() {
    method openSettingsWindow (line 24) | async openSettingsWindow(options?: string | OpenSettingsWindowOptions) {
    method closeWindow (line 56) | closeWindow() {
    method minimizeWindow (line 63) | minimizeWindow() {
    method maximizeWindow (line 70) | maximizeWindow() {
    method isWindowMaximized (line 77) | isWindowMaximized() {
    method setWindowSize (line 84) | setWindowSize(params: WindowSizeParams) {
    method setWindowMinimumSize (line 91) | setWindowMinimumSize(params: WindowMinimumSizeParams) {
    method interceptRoute (line 114) | async interceptRoute(params: InterceptRouteParams) {
    method createMultiInstanceWindow (line 157) | async createMultiInstanceWindow(params: {
    method getWindowsByTemplate (line 191) | async getWindowsByTemplate(templateId: string) {
    method closeWindowsByTemplate (line 211) | async closeWindowsByTemplate(templateId: string) {
    method openTargetWindow (line 227) | private async openTargetWindow(targetWindow: AppBrowsersIdentifiers) {
    method withSenderIdentifier (line 233) | private withSenderIdentifier<T>(fn: (identifier: string) => T): T | un...

FILE: apps/desktop/src/main/controllers/DevtoolsCtr.ts
  class DevtoolsCtr (line 3) | class DevtoolsCtr extends ControllerModule {
    method openDevtools (line 7) | async openDevtools() {

FILE: apps/desktop/src/main/controllers/GatewayConnectionCtr.ts
  class GatewayConnectionCtr (line 15) | class GatewayConnectionCtr extends ControllerModule {
    method service (line 20) | private get service() {
    method remoteServerConfigCtr (line 24) | private get remoteServerConfigCtr() {
    method localFileCtr (line 28) | private get localFileCtr() {
    method shellCommandCtr (line 32) | private get shellCommandCtr() {
    method afterAppReady (line 38) | afterAppReady() {
    method connect (line 57) | async connect(): Promise<{ error?: string; success: boolean }> {
    method disconnect (line 63) | async disconnect(): Promise<{ success: boolean }> {
    method getConnectionStatus (line 69) | async getConnectionStatus(): Promise<{ status: GatewayConnectionStatus...
    method getDeviceInfo (line 74) | async getDeviceInfo(): Promise<{
    method setDeviceName (line 85) | async setDeviceName(params: { name: string }): Promise<{ success: bool...
    method setDeviceDescription (line 91) | async setDeviceDescription(params: { description: string }): Promise<{...
    method tryAutoConnect (line 98) | private async tryAutoConnect() {
    method executeToolCall (line 113) | private async executeToolCall(apiName: string, args: any): Promise<unk...

FILE: apps/desktop/src/main/controllers/LocalFileCtr.ts
  constant SAFE_PATH_PREFIXES (line 57) | const SAFE_PATH_PREFIXES = ['/tmp', '/var/tmp'] as const;
  class LocalFileCtr (line 123) | class LocalFileCtr extends ControllerModule {
    method searchService (line 125) | private get searchService() {
    method contentSearchService (line 129) | private get contentSearchService() {
    method handleOpenLocalFile (line 136) | async handleOpenLocalFile({ path: filePath }: OpenLocalFileParams): Pr...
    method handleOpenLocalFolder (line 153) | async handleOpenLocalFolder({ path: targetPath, isDirectory }: OpenLoc...
    method handleShowOpenDialog (line 171) | async handleShowOpenDialog({
    method handlePickFile (line 193) | async handlePickFile({ filters, title }: PickFileParams): Promise<Pick...
    method handleShowSaveDialog (line 232) | async handleShowSaveDialog({
    method readFiles (line 254) | async readFiles({ paths }: LocalReadFilesParams): Promise<LocalReadFil...
    method readFile (line 270) | async readFile(params: LocalReadFileParams): Promise<LocalReadFileResu...
    method listLocalFiles (line 280) | async listLocalFiles(
    method handleMoveFiles (line 288) | async handleMoveFiles({ items }: MoveLocalFilesParams): Promise<LocalM...
    method handleRenameFile (line 294) | async handleRenameFile({
    method handleWriteFile (line 306) | async handleWriteFile({ path: filePath, content }: WriteLocalFileParam...
    method auditSafePaths (line 312) | async auditSafePaths({
    method handlePrepareSkillDirectory (line 324) | async handlePrepareSkillDirectory({
    method handleResolveSkillResourcePath (line 386) | async handleResolveSkillResourcePath({
    method handleLocalFilesSearch (line 419) | async handleLocalFilesSearch(params: LocalSearchFilesParams): Promise<...
    method handleGrepContent (line 457) | async handleGrepContent(params: GrepContentParams): Promise<GrepConten...
    method handleGlobFiles (line 462) | async handleGlobFiles(params: GlobFilesParams): Promise<GlobFilesResul...
    method handleEditFile (line 469) | async handleEditFile(params: EditLocalFileParams): Promise<EditLocalFi...

FILE: apps/desktop/src/main/controllers/McpCtr.ts
  type CheckMcpInstallResult (line 24) | interface CheckMcpInstallResult {
  type CustomPluginMetadata (line 67) | interface CustomPluginMetadata {
  type GetStdioMcpServerManifestInput (line 73) | interface GetStdioMcpServerManifestInput {
  type GetStreamableMcpServerManifestInput (line 82) | interface GetStreamableMcpServerManifestInput {
  type CallToolInput (line 94) | interface CallToolInput {
  type SuperJSONSerialized (line 101) | interface SuperJSONSerialized<T = unknown> {
  class McpCtr (line 179) | class McpCtr extends ControllerModule {
    method fileService (line 182) | private get fileService() {
    method createClient (line 186) | private async createClient(params: MCPClientParams) {
    method processContentBlocks (line 192) | private async processContentBlocks(blocks: ToolCallContent[]): Promise...
    method getStdioMcpServerManifest (line 222) | async getStdioMcpServerManifest(payload: SuperJSONSerialized<GetStdioM...
    method getStreamableMcpServerManifest (line 285) | async getStreamableMcpServerManifest(
    method callTool (line 325) | async callTool(payload: SuperJSONSerialized<CallToolInput>) {
    method getInstallInstructions (line 375) | private getInstallInstructions(installInstructions: any) {
    method checkSystemDependency (line 398) | private async checkSystemDependency(dependency: any) {
    method checkPackageInstalled (line 478) | private async checkPackageInstalled(installationMethod: string, detail...
    method checkDeployOption (line 529) | private async checkDeployOption(option: any) {
    method validMcpServerInstallable (line 570) | async validMcpServerInstallable(

FILE: apps/desktop/src/main/controllers/McpInstallCtr.ts
  function validateMcpSchema (line 13) | function validateMcpSchema(schema: any): schema is McpSchema {
  type McpInstallParams (line 50) | interface McpInstallParams {
  class McpInstallController (line 60) | class McpInstallController extends ControllerModule {
    method handleInstallRequest (line 67) | public async handleInstallRequest(parsedData: McpInstallParams): Promi...

FILE: apps/desktop/src/main/controllers/MenuCtr.ts
  class MenuController (line 3) | class MenuController extends ControllerModule {
    method refreshAppMenu (line 9) | refreshAppMenu() {
    method showContextMenu (line 18) | showContextMenu(params: { data?: any; type: string }) {
    method setDevMenuVisibility (line 26) | setDevMenuVisibility(visible: boolean) {

FILE: apps/desktop/src/main/controllers/NetworkProxyCtr.ts
  class NetworkProxyCtr (line 23) | class NetworkProxyCtr extends ControllerModule {
    method getDesktopSettings (line 29) | async getDesktopSettings(): Promise<NetworkProxySettings> {
    method setProxySettings (line 50) | async setProxySettings(config: Partial<NetworkProxySettings>): Promise...
    method testProxyConnection (line 95) | async testProxyConnection(url: string): Promise<{ message?: string; su...
    method testProxyConfig (line 115) | async testProxyConfig({
    method beforeAppReady (line 137) | async beforeAppReady(): Promise<void> {

FILE: apps/desktop/src/main/controllers/NotificationCtr.ts
  class NotificationCtr (line 15) | class NotificationCtr extends ControllerModule {
    method getNotificationPermissionStatus (line 19) | async getNotificationPermissionStatus(): Promise<string> {
    method requestNotificationPermission (line 36) | async requestNotificationPermission(): Promise<void> {
    method afterAppReady (line 68) | afterAppReady() {
    method setupNotifications (line 75) | private setupNotifications() {
    method showDesktopNotification (line 105) | async showDesktopNotification(
    method isMainWindowHidden (line 180) | isMainWindowHidden(): boolean {

FILE: apps/desktop/src/main/controllers/RemoteServerConfigCtr.ts
  constant NON_RETRYABLE_OIDC_ERRORS (line 19) | const NON_RETRYABLE_OIDC_ERRORS = [
  constant DETERMINISTIC_FAILURES (line 31) | const DETERMINISTIC_FAILURES = [
  class RemoteServerConfigCtr (line 44) | class RemoteServerConfigCtr extends ControllerModule {
    method getRemoteServerConfig (line 74) | async getRemoteServerConfig() {
    method isRemoteServerConfigured (line 95) | async isRemoteServerConfigured(config?: DataSyncConfig): Promise<boole...
    method isValidSelfHostRemoteUrl (line 105) | private isValidSelfHostRemoteUrl(remoteServerUrl?: string): boolean {
    method setRemoteServerConfig (line 123) | async setRemoteServerConfig(config: Partial<DataSyncConfig>) {
    method clearRemoteServerConfig (line 143) | async clearRemoteServerConfig() {
    method broadcastRemoteServerConfigUpdated (line 158) | private broadcastRemoteServerConfigUpdated() {
    method saveTokens (line 194) | async saveTokens(accessToken: string, refreshToken: string, expiresIn?...
    method getAccessToken (line 247) | async getAccessToken(): Promise<string | null> {
    method getRefreshToken (line 281) | async getRefreshToken(): Promise<string | null> {
    method clearTokens (line 315) | async clearTokens() {
    method getTokenExpiresAt (line 335) | getTokenExpiresAt(): number | undefined {
    method isTokenExpiringSoon (line 344) | isTokenExpiringSoon(bufferTimeMs: number = 24 * 60 * 60 * 1000): boole...
    method isNonRetryableError (line 362) | isNonRetryableError(error?: string): boolean {
    method refreshAccessToken (line 385) | async refreshAccessToken(): Promise<{ error?: string; success: boolean...
    method performTokenRefreshWithRetry (line 404) | private async performTokenRefreshWithRetry(): Promise<{ error?: string...
    method performTokenRefresh (line 452) | private async performTokenRefresh(): Promise<{ error?: string; success...
    method loadTokensFromStore (line 525) | private loadTokensFromStore() {
    method getLastTokenRefreshAt (line 553) | getLastTokenRefreshAt(): number | undefined {
    method afterAppReady (line 559) | afterAppReady() {
    method getRemoteServerUrl (line 563) | async getRemoteServerUrl(config?: DataSyncConfig) {
    method setupSubscriptionWebviewSession (line 576) | async setupSubscriptionWebviewSession(params: { partition: string }) {

FILE: apps/desktop/src/main/controllers/RemoteServerSyncCtr.ts
  class RemoteServerSyncCtr (line 27) | class RemoteServerSyncCtr extends ControllerModule {
    method remoteServerConfigCtr (line 37) | private get remoteServerConfigCtr() {
    method afterAppReady (line 47) | afterAppReady() {
    method forwardStreamRequest (line 103) | private async forwardStreamRequest(
    method createRequester (line 182) | private createRequester({

FILE: apps/desktop/src/main/controllers/ShellCommandCtr.ts
  class ShellCommandCtr (line 19) | class ShellCommandCtr extends ControllerModule {
    method handleRunCommand (line 23) | async handleRunCommand(params: RunCommandParams): Promise<RunCommandRe...
    method handleGetCommandOutput (line 28) | async handleGetCommandOutput(params: GetCommandOutputParams): Promise<...
    method handleKillCommand (line 33) | async handleKillCommand({ shell_id }: KillCommandParams): Promise<Kill...

FILE: apps/desktop/src/main/controllers/ShortcutCtr.ts
  class ShortcutController (line 5) | class ShortcutController extends ControllerModule {
    method getShortcutsConfig (line 11) | getShortcutsConfig() {
    method updateShortcutConfig (line 19) | updateShortcutConfig({

FILE: apps/desktop/src/main/controllers/SystemCtr.ts
  class SystemController (line 24) | class SystemController extends ControllerModule {
    method afterAppReady (line 31) | afterAppReady() {
    method getAppState (line 40) | async getAppState(): Promise<ElectronAppState> {
    method requestAccessibilityAccess (line 68) | requestAccessibilityAccess() {
    method getAccessibilityStatus (line 73) | getAccessibilityStatus() {
    method getFullDiskAccessStatus (line 79) | getFullDiskAccessStatus(): boolean {
    method promptFullDiskAccessIfNotGranted (line 92) | async promptFullDiskAccessIfNotGranted(options?: {
    method getMediaAccessStatus (line 144) | async getMediaAccessStatus(mediaType: 'microphone' | 'screen'): Promis...
    method requestMicrophoneAccess (line 149) | async requestMicrophoneAccess(): Promise<boolean> {
    method requestScreenAccess (line 154) | async requestScreenAccess(): Promise<boolean> {
    method openFullDiskAccessSettings (line 159) | async openFullDiskAccessSettings() {
    method openExternalLink (line 164) | openExternalLink(url: string) {
    method selectFolder (line 169) | async selectFolder(payload?: {
    method getSystemLocale (line 189) | getSystemLocale(): string {
    method updateLocale (line 194) | async updateLocale(locale: string) {
    method updateThemeModeHandler (line 204) | async updateThemeModeHandler(themeMode: ThemeMode) {
    method getSystemThemeMode (line 212) | async getSystemThemeMode() {
    method hasLegacyLocalDb (line 221) | async hasLegacyLocalDb(): Promise<boolean> {
    method setSystemThemeMode (line 233) | private async setSystemThemeMode(themeMode: ThemeMode) {
    method initializeSystemThemeListener (line 237) | private initializeSystemThemeListener() {

FILE: apps/desktop/src/main/controllers/ToolDetectorCtr.ts
  class ToolDetectorCtr (line 14) | class ToolDetectorCtr extends ControllerModule {
    method manager (line 17) | private get manager() {
    method detectTool (line 25) | async detectTool(name: string, force = false): Promise<ToolStatus> {
    method detectAllTools (line 34) | async detectAllTools(force = false): Promise<Record<string, ToolStatus...
    method detectCategory (line 44) | async detectCategory(category: ToolCategory, force = false): Promise<R...
    method getBestTool (line 54) | async getBestTool(category: ToolCategory): Promise<string | null> {
    method getToolStatus (line 63) | getToolStatus(name: string): ToolStatus | null {
    method getAllToolStatus (line 71) | getAllToolStatus(): Record<string, ToolStatus> {
    method clearToolCache (line 79) | clearToolCache(name?: string): void {
    method getRegisteredTools (line 88) | getRegisteredTools(): string[] {
    method getCategories (line 96) | getCategories(): ToolCategory[] {
    method getToolsInCategory (line 104) | getToolsInCategory(category: ToolCategory): Array<{

FILE: apps/desktop/src/main/controllers/TrayMenuCtr.ts
  class TrayMenuCtr (line 14) | class TrayMenuCtr extends ControllerModule {
    method toggleMainWindow (line 16) | async toggleMainWindow() {
    method showNotification (line 28) | async showNotification(options: ShowTrayNotificationParams) {
    method updateTrayIcon (line 57) | async updateTrayIcon(options: UpdateTrayIconParams) {
    method updateTrayTooltip (line 89) | async updateTrayTooltip(options: UpdateTrayTooltipParams) {

FILE: apps/desktop/src/main/controllers/UpdaterCtr.ts
  class UpdaterCtr (line 9) | class UpdaterCtr extends ControllerModule {
    method checkForUpdates (line 15) | async checkForUpdates() {
    method downloadUpdate (line 24) | async downloadUpdate() {
    method quitAndInstallUpdate (line 33) | quitAndInstallUpdate() {
    method installLater (line 42) | installLater() {
    method getUpdateChannel (line 48) | async getUpdateChannel(): Promise<UpdateChannel> {
    method getBuildChannel (line 57) | async getBuildChannel(): Promise<string> {
    method setUpdateChannel (line 63) | async setUpdateChannel(channel: UpdateChannel): Promise<void> {
    method getUpdaterState (line 75) | async getUpdaterState(): Promise<UpdaterState> {

FILE: apps/desktop/src/main/controllers/UploadFileCtr.ts
  class UploadFileCtr (line 7) | class UploadFileCtr extends ControllerModule {
    method fileService (line 9) | private get fileService() {
    method uploadFile (line 14) | async uploadFile(params: UploadFileParams) {

FILE: apps/desktop/src/main/controllers/__tests__/GatewayConnectionCtr.test.ts
  class _MockGatewayClient (line 17) | class _MockGatewayClient extends EventEmitter {
    method constructor (line 35) | constructor(options: any) {
    method simulateConnected (line 43) | simulateConnected() {
    method simulateStatusChanged (line 49) | simulateStatusChanged(status: string) {
    method simulateToolCallRequest (line 54) | simulateToolCallRequest(apiName: string, args: object, requestId = 're...
    method simulateAuthExpired (line 66) | simulateAuthExpired() {
    method simulateError (line 70) | simulateError(message: string) {
    method simulateReconnecting (line 74) | simulateReconnecting(delay: number) {
  function connectAndOpen (line 427) | async function connectAndOpen() {

FILE: apps/desktop/src/main/controllers/_template.ts
  class DevtoolsCtr (line 3) | class DevtoolsCtr extends ControllerModule {
    method openDevtools (line 5) | async openDevtools() {

FILE: apps/desktop/src/main/controllers/index.ts
  type IControllerModule (line 38) | interface IControllerModule {
  class ControllerModule (line 44) | class ControllerModule extends IpcService implements IControllerModule {
    method constructor (line 45) | constructor(public app: App) {
  type IControlModule (line 51) | type IControlModule = typeof ControllerModule;

FILE: apps/desktop/src/main/controllers/registry.ts
  type DesktopControllerIpcConstructors (line 45) | type DesktopControllerIpcConstructors = typeof controllerIpcConstructors;
  type DesktopControllerServices (line 46) | type DesktopControllerServices = CreateServicesResult<DesktopControllerI...
  type DesktopIpcServices (line 47) | type DesktopIpcServices = MergeIpcService<DesktopControllerServices>;

FILE: apps/desktop/src/main/core/App.ts
  type IPCEventMap (line 43) | type IPCEventMap = Map<string, { controller: any; methodName: string }>;
  type ShortcutMethodMap (line 44) | type ShortcutMethodMap = Map<string, () => Promise<void>>;
  type ProtocolHandlerMap (line 45) | type ProtocolHandlerMap = Map<string, { controller: any; methodName: str...
  type Class (line 47) | type Class<T> = new (...args: any[]) => T;
  class App (line 51) | class App {
    method appStoragePath (line 70) | get appStoragePath() {
    method constructor (line 80) | constructor() {
    method initializeThemeMode (line 166) | private initializeThemeMode() {
    method registerBuiltinToolDetectors (line 187) | private registerBuiltinToolDetectors() {
    method getService (line 267) | getService<T>(serviceClass: Class<T>): T {
    method getController (line 271) | getController<T>(controllerClass: Class<T>): T {
    method handleProtocolRequest (line 282) | async handleProtocolRequest(urlType: string, action: string, data: any...
    method buildRendererUrl (line 423) | async buildRendererUrl(path: string): Promise<string> {
    method initializeServerIpcEvents (line 427) | private initializeServerIpcEvents() {

FILE: apps/desktop/src/main/core/browser/Browser.ts
  type BrowserWindowOpts (line 25) | interface BrowserWindowOpts extends BrowserWindowConstructorOptions {
  class Browser (line 39) | class Browser {
    method browserWindow (line 51) | get browserWindow(): BrowserWindow {
    method webContents (line 55) | get webContents() {
    method constructor (line 62) | constructor(options: BrowserWindowOpts, application: App) {
    method retrieveOrInitialize (line 86) | retrieveOrInitialize(): BrowserWindow {
    method destroy (line 104) | destroy(): void {
    method createBrowserWindow (line 112) | private createBrowserWindow(): BrowserWindow {
    method setupWindow (line 154) | private setupWindow(browserWindow: BrowserWindow): void {
    method initiateContentLoading (line 180) | private initiateContentLoading(): void {
    method setupEventListeners (line 194) | private setupEventListeners(browserWindow: BrowserWindow): void {
    method setupWindowOpenHandler (line 206) | private setupWindowOpenHandler(browserWindow: BrowserWindow): void {
    method setupWillPreventUnloadListener (line 222) | private setupWillPreventUnloadListener(browserWindow: BrowserWindow): ...
    method setupReadyToShowListener (line 235) | private setupReadyToShowListener(browserWindow: BrowserWindow): void {
    method setupCloseListener (line 248) | private setupCloseListener(browserWindow: BrowserWindow): void {
    method setupFocusListener (line 257) | private setupFocusListener(browserWindow: BrowserWindow): void {
    method setupContextMenu (line 269) | private setupContextMenu(browserWindow: BrowserWindow): void {
    method show (line 290) | show(): void {
    method hide (line 298) | hide(): void {
    method close (line 314) | close(): void {
    method toggleVisible (line 319) | toggleVisible(): void {
    method moveToCenter (line 329) | moveToCenter(): void {
    method setWindowSize (line 334) | setWindowSize(boundSize: { height?: number; width?: number }): void {
    method setWindowMinimumSize (line 343) | setWindowMinimumSize(size: { height?: number; width?: number }): void {
    method determineWindowPosition (line 360) | private determineWindowPosition(): void {
    method buildUrlWithLocale (line 407) | private buildUrlWithLocale(initUrl: string): string {
    method handleLoadError (line 415) | private async handleLoadError(urlWithLocale: string): Promise<void> {
    method setupRetryHandler (line 428) | private setupRetryHandler(urlWithLocale: string): void {
    method loadFallbackError (line 451) | private async loadFallbackError(): Promise<void> {
    method reapplyVisualEffects (line 486) | reapplyVisualEffects(): void {
    method setupCORSBypass (line 496) | private setupCORSBypass(browserWindow: BrowserWindow): void {
    method setupRemoteServerRequestHook (line 547) | private setupRemoteServerRequestHook(browserWindow: BrowserWindow): vo...

FILE: apps/desktop/src/main/core/browser/BrowserManager.ts
  class BrowserManager (line 17) | class BrowserManager {
    method constructor (line 24) | constructor(app: App) {
    method getMainWindow (line 29) | getMainWindow() {
    method showMainWindow (line 33) | showMainWindow() {
    method redirectToPage (line 63) | async redirectToPage(identifier: string, subPath?: string, search?: st...
    method retrieveByIdentifier (line 101) | retrieveByIdentifier(identifier: string) {
    method createMultiInstanceWindow (line 122) | createMultiInstanceWindow(
    method getWindowsByTemplate (line 159) | getWindowsByTemplate(templateId: string): string[] {
    method closeWindowsByTemplate (line 168) | closeWindowsByTemplate(templateId: string): void {
    method initializeBrowsers (line 181) | async initializeBrowsers() {
    method retrieveOrInitialize (line 214) | private retrieveOrInitialize(options: BrowserWindowOpts) {
    method closeWindow (line 242) | closeWindow(identifier: string) {
    method minimizeWindow (line 247) | minimizeWindow(identifier: string) {
    method maximizeWindow (line 252) | maximizeWindow(identifier: string) {
    method isWindowMaximized (line 261) | isWindowMaximized(identifier: string) {
    method setWindowSize (line 266) | setWindowSize(identifier: string, size: { height?: number; width?: num...
    method getWindowSize (line 271) | getWindowSize(identifier: string) {
    method setWindowMinimumSize (line 276) | setWindowMinimumSize(identifier: string, size: { height?: number; widt...
    method getIdentifierByWebContents (line 281) | getIdentifierByWebContents(webContents: WebContents): string | null {
    method handleAppThemeChange (line 288) | handleAppThemeChange(): void {

FILE: apps/desktop/src/main/core/browser/WindowStateManager.ts
  type WindowState (line 11) | interface WindowState {
  type WindowStateManagerOptions (line 18) | interface WindowStateManagerOptions {
  class WindowStateManager (line 26) | class WindowStateManager {
    method constructor (line 32) | constructor(app: App, options: WindowStateManagerOptions) {
    method loadState (line 44) | loadState(): WindowState | undefined {
    method saveState (line 51) | saveState(browserWindow: BrowserWindow, context: 'quit' | 'close' | 'h...
    method resolveState (line 75) | resolveState(fallback: { height?: number; width?: number }): WindowSta...
    method resolveWindowState (line 80) | private resolveWindowState(
    method clampNumber (line 116) | private clampNumber(value: number, min: number, max: number): number {
    method createCloseHandler (line 126) | createCloseHandler(
    method handleCloseOnQuit (line 155) | private handleCloseOnQuit(browserWindow: BrowserWindow, onCleanup: () ...
    method handleCloseWithKeepAlive (line 164) | private handleCloseWithKeepAlive(e: Electron.Event, onHide: () => void...
    method handleCloseNormally (line 175) | private handleCloseNormally(browserWindow: BrowserWindow, onCleanup: (...

FILE: apps/desktop/src/main/core/browser/WindowThemeManager.ts
  type WindowsThemeConfig (line 20) | interface WindowsThemeConfig {
  type LinuxThemeConfig (line 31) | interface LinuxThemeConfig {
  class WindowThemeManager (line 39) | class WindowThemeManager {
    method constructor (line 45) | constructor(identifier: string) {
    method getWindowsTitleBarOverlay (line 50) | private getWindowsTitleBarOverlay(isDarkMode: boolean): WindowsThemeCo...
    method attach (line 64) | attach(browserWindow: BrowserWindow): void {
    method cleanup (line 73) | cleanup(): void {
    method isDarkMode (line 87) | get isDarkMode(): boolean {
    method getPlatformConfig (line 94) | getPlatformConfig(): Partial<BrowserWindowConstructorOptions> {
    method getWindowsConfig (line 118) | private getWindowsConfig(isDarkMode: boolean): WindowsThemeConfig {
    method getLinuxConfig (line 127) | private getLinuxConfig(): LinuxThemeConfig {
    method setupThemeListener (line 136) | private setupThemeListener(): void {
    method handleThemeChange (line 144) | private handleThemeChange(): void {
    method handleAppThemeChange (line 154) | handleAppThemeChange(): void {
    method resolveIsDarkMode (line 167) | private resolveIsDarkMode(): boolean {
    method applyVisualEffects (line 177) | applyVisualEffects(): void {
    method reapplyVisualEffects (line 197) | reapplyVisualEffects(): void {
    method applyWindowsVisualEffects (line 202) | private applyWindowsVisualEffects(isDarkMode: boolean): void {
    method applyLinuxVisualEffects (line 210) | private applyLinuxVisualEffects(): void {

FILE: apps/desktop/src/main/core/browser/__tests__/BrowserManager.test.ts
  method isRemoteServerConfigured (line 85) | async isRemoteServerConfigured() {

FILE: apps/desktop/src/main/core/infrastructure/BackendProxyProtocolManager.ts
  type BackendProxyProtocolManagerOptions (line 8) | interface BackendProxyProtocolManagerOptions {
  type BackendProxyProtocolManagerRemoteBaseOptions (line 18) | interface BackendProxyProtocolManagerRemoteBaseOptions {
  class BackendProxyProtocolManager (line 32) | class BackendProxyProtocolManager {
    method notifyAuthorizationRequired (line 44) | private notifyAuthorizationRequired() {
    method registerWithRemoteBaseUrl (line 63) | registerWithRemoteBaseUrl(
    method register (line 106) | register(session: Session, options: BackendProxyProtocolManagerOptions) {

FILE: apps/desktop/src/main/core/infrastructure/I18nManager.ts
  class I18nManager (line 11) | class I18nManager {
    method constructor (line 16) | constructor(app: App) {
    method init (line 25) | async init(lang?: string) {
    method createNamespacedT (line 89) | createNamespacedT(namespace: string) {
    method getCurrentLanguage (line 108) | getCurrentLanguage() {
    method changeLanguage (line 116) | public async changeLanguage(lng: string): Promise<void> {
    method refreshMainUI (line 141) | private refreshMainUI() {
    method notifyRendererProcess (line 149) | private notifyRendererProcess(lng: string) {
    method loadLocale (line 153) | private async loadLocale(language: string) {
    method loadNamespace (line 162) | private async loadNamespace(lng: string, ns: string) {

FILE: apps/desktop/src/main/core/infrastructure/IoCContainer.ts
  class IoCContainer (line 4) | class IoCContainer {
    method init (line 10) | init() {}

FILE: apps/desktop/src/main/core/infrastructure/ProtocolManager.ts
  class ProtocolManager (line 15) | class ProtocolManager {
    method constructor (line 20) | constructor(app: App) {
    method initialize (line 30) | public initialize(): void {
    method registerProtocolHandlers (line 42) | private registerProtocolHandlers(): void {
    method setupEventListeners (line 98) | private setupEventListeners(): void {
    method getProtocolUrlFromArgs (line 130) | private getProtocolUrlFromArgs(args: string[]): string | null {
    method handleProtocolUrl (line 148) | private handleProtocolUrl(url: string): void {
    method processProtocolUrl (line 173) | private async processProtocolUrl(url: string): Promise<void> {
    method processPendingUrls (line 224) | public async processPendingUrls(): Promise<void> {
    method getScheme (line 251) | public getScheme(): string {
    method isRegistered (line 258) | public isRegistered(): boolean {

FILE: apps/desktop/src/main/core/infrastructure/RendererProtocolManager.ts
  type ResolveRendererFilePath (line 11) | type ResolveRendererFilePath = (url: URL) => Promise<string | null>;
  constant RENDERER_PROTOCOL_PRIVILEGES (line 13) | const RENDERER_PROTOCOL_PRIVILEGES = {
  type RendererProtocolManagerOptions (line 21) | interface RendererProtocolManagerOptions {
  constant RENDERER_DIR (line 28) | const RENDERER_DIR = 'renderer';
  class RendererProtocolManager (line 29) | class RendererProtocolManager {
    method constructor (line 36) | constructor(options: RendererProtocolManagerOptions) {
    method getRendererUrl (line 48) | getRendererUrl(): string {
    method protocolScheme (line 52) | get protocolScheme() {
    method registerHandler (line 58) | registerHandler() {
    method isAssetRequest (line 235) | private isAssetRequest(pathname: string) {
    method is404Html (line 248) | private is404Html(filePath: string) {

FILE: apps/desktop/src/main/core/infrastructure/RendererUrlManager.ts
  constant SPA_ENTRY_HTML (line 16) | const SPA_ENTRY_HTML = join(rendererDir, 'apps', 'desktop', 'index.html');
  class RendererUrlManager (line 18) | class RendererUrlManager {
    method constructor (line 23) | constructor() {
    method protocolScheme (line 32) | get protocolScheme() {
    method configureRendererLoader (line 39) | configureRendererLoader() {
    method buildRendererUrl (line 62) | buildRendererUrl(path: string): string {
    method setupDevRenderer (line 87) | private setupDevRenderer() {
    method setupProdRenderer (line 96) | private setupProdRenderer() {

FILE: apps/desktop/src/main/core/infrastructure/StaticFileServerManager.ts
  class StaticFileServerManager (line 28) | class StaticFileServerManager {
    method constructor (line 34) | constructor(app: App) {
    method initialize (line 42) | async initialize(): Promise<void> {
    method startHttpServer (line 67) | private async startHttpServer(): Promise<void> {
    method handleHttpRequest (line 135) | private async handleHttpRequest(req: any, res: any): Promise<void> {
    method getFileServerDomain (line 249) | getFileServerDomain(): string {
    method destroy (line 261) | destroy() {

FILE: apps/desktop/src/main/core/infrastructure/StoreManager.ts
  class StoreManager (line 16) | class StoreManager {
    method constructor (line 23) | constructor(app: App) {
    method get (line 43) | get<K extends StoreKey>(key: K, defaultValue?: ElectronMainStore[K]): ...
    method set (line 53) | set<K extends StoreKey>(key: K, value: ElectronMainStore[K]): void {
    method delete (line 62) | delete(key: StoreKey): void {
    method clear (line 70) | clear(): void {
    method has (line 79) | has(key: StoreKey): boolean {
    method openInEditor (line 85) | async openInEditor() {

FILE: apps/desktop/src/main/core/infrastructure/ToolDetectorManager.ts
  type ToolStatus (line 13) | interface ToolStatus {
  type IToolDetector (line 24) | interface IToolDetector {
  type ToolCategory (line 38) | type ToolCategory =
  class ToolDetectorManager (line 68) | class ToolDetectorManager {
    method constructor (line 75) | constructor(app: App) {
    method register (line 85) | register(detector: IToolDetector, category: ToolCategory = 'custom'): ...
    method unregister (line 109) | unregister(name: string): boolean {
    method detect (line 131) | async detect(name: string, force = false): Promise<ToolStatus> {
    method detectAll (line 174) | async detectAll(force = false): Promise<Map<string, ToolStatus>> {
    method detectCategory (line 192) | async detectCategory(category: ToolCategory, force = false): Promise<M...
    method getStatus (line 214) | getStatus(name: string): ToolStatus | undefined {
    method getAllStatus (line 221) | getAllStatus(): Map<string, ToolStatus> {
    method getBestTool (line 230) | async getBestTool(category: ToolCategory): Promise<string | null> {
    method getToolsInCategory (line 257) | getToolsInCategory(category: ToolCategory): IToolDetector[] {
    method clearCache (line 273) | clearCache(name?: string): void {
    method getRegisteredTools (line 286) | getRegisteredTools(): string[] {
    method getCategories (line 293) | getCategories(): ToolCategory[] {
    method isRegistered (line 300) | isRegistered(name: string): boolean {
  function createCommandDetector (line 313) | function createCommandDetector(

FILE: apps/desktop/src/main/core/infrastructure/UpdaterManager.ts
  constant FORCE_DEV_UPDATE_CONFIG (line 19) | const FORCE_DEV_UPDATE_CONFIG = getDesktopEnv().FORCE_DEV_UPDATE_CONFIG;
  class UpdaterManager (line 23) | class UpdaterManager {
    method constructor (line 41) | constructor(app: AppCore) {
    method mainWindow (line 50) | get mainWindow() {
    method getUpdaterState (line 54) | public getUpdaterState(): UpdaterState {
    method setStage (line 62) | private setStage(
    method getBaseUpdateUrl (line 371) | private getBaseUpdateUrl(): string | undefined {
    method configureUpdateProvider (line 381) | private configureUpdateProvider() {
    method registerEvents (line 413) | private registerEvents() {
    method isStaleCheck (line 492) | private isStaleCheck(): boolean {
    method isMissingUpdateManifestError (line 502) | private isMissingUpdateManifestError(error: unknown): boolean {
    method getCurrentUpdateInfo (line 513) | private getCurrentUpdateInfo(): UpdateInfo {

FILE: apps/desktop/src/main/core/infrastructure/__tests__/BackendProxyProtocolManager.test.ts
  type RequestInitWithDuplex (line 5) | interface RequestInitWithDuplex extends RequestInit {
  type FetchMock (line 9) | type FetchMock = (input: RequestInfo | URL, init?: RequestInitWithDuplex...

FILE: apps/desktop/src/main/core/infrastructure/__tests__/IoCContainer.test.ts
  class TestController (line 7) | class TestController {}
  class AnotherController (line 8) | class AnotherController {}
  class UnregisteredClass (line 39) | class UnregisteredClass {}

FILE: apps/desktop/src/main/core/infrastructure/__tests__/RendererUrlManager.test.ts
  method isDev (line 26) | get isDev() {

FILE: apps/desktop/src/main/core/ui/MenuManager.ts
  class MenuManager (line 12) | class MenuManager {
    method constructor (line 16) | constructor(app: App) {
    method initialize (line 25) | initialize(options?: MenuOptions) {
    method showContextMenu (line 33) | showContextMenu(type: string, data?: any) {
    method buildTrayMenu (line 43) | buildTrayMenu(): Menu {
    method refreshMenus (line 51) | refreshMenus(options?: MenuOptions) {
    method rebuildAppMenu (line 60) | rebuildAppMenu(options?: MenuOptions) {

FILE: apps/desktop/src/main/core/ui/ShortcutManager.ts
  type ShortcutUpdateResult (line 11) | interface ShortcutUpdateResult {
  class ShortcutManager (line 22) | class ShortcutManager {
    method constructor (line 27) | constructor(app: App) {
    method convertAcceleratorFormat (line 41) | private convertAcceleratorFormat(accelerator: string): string {
    method initialize (line 58) | initialize() {
    method getShortcutsConfig (line 69) | getShortcutsConfig(): Record<string, string> {
    method updateShortcutConfig (line 76) | updateShortcutConfig(id: string, accelerator: string): ShortcutUpdateR...
    method registerShortcut (line 168) | registerShortcut(accelerator: string, callback: () => void): boolean {
    method unregisterShortcut (line 196) | unregisterShortcut(accelerator: string): void {
    method isRegistered (line 211) | isRegistered(accelerator: string): boolean {
    method unregisterAll (line 218) | unregisterAll(): void {
    method loadShortcutsConfig (line 226) | private loadShortcutsConfig() {
    method saveShortcutsConfig (line 278) | private saveShortcutsConfig() {
    method registerConfiguredShortcuts (line 290) | private registerConfiguredShortcuts() {

FILE: apps/desktop/src/main/core/ui/Tray.ts
  type TrayOptions (line 22) | interface TrayOptions {
  class Tray (line 39) | class Tray {
    method tray (line 60) | get tray() {
    method constructor (line 69) | constructor(options: TrayOptions, application: App) {
    method retrieveOrInitialize (line 83) | retrieveOrInitialize() {
    method setContextMenu (line 128) | setContextMenu(template?: MenuItemConstructorOptions[]) {
    method onClick (line 158) | onClick() {
    method updateIcon (line 178) | updateIcon(iconPath: string) {
    method updateTooltip (line 195) | updateTooltip(tooltip: string) {
    method displayBalloon (line 205) | displayBalloon(options: DisplayBalloonOptions) {
    method destroy (line 228) | destroy() {

FILE: apps/desktop/src/main/core/ui/TrayManager.ts
  type TrayIdentifiers (line 18) | type TrayIdentifiers = 'main';
  class TrayManager (line 20) | class TrayManager {
    method constructor (line 32) | constructor(app: App) {
    method initializeTrays (line 40) | initializeTrays() {
    method getMainTray (line 50) | getMainTray() {
    method initializeMainTray (line 57) | initializeMainTray() {
    method retrieveByIdentifier (line 74) | retrieveByIdentifier(identifier: TrayIdentifiers) {
    method retrieveOrInitialize (line 113) | private retrieveOrInitialize(options: TrayOptions) {
    method destroyAll (line 131) | destroyAll() {

FILE: apps/desktop/src/main/exports.d.ts
  type DesktopIpcServicesMap (line 5) | interface DesktopIpcServicesMap extends DesktopIpcServices {}

FILE: apps/desktop/src/main/global.d.ts
  type AuthStatus (line 10) | type AuthStatus = 'authorized' | 'denied' | 'not determined' | 'restrict...
  type AuthType (line 12) | type AuthType =

FILE: apps/desktop/src/main/libs/mcp/client.ts
  class MCPConnectionError (line 19) | class MCPConnectionError extends Error {
    method constructor (line 22) | constructor(message: string, stderrLogs: string[] = []) {
  class MCPClient (line 29) | class MCPClient {
    method constructor (line 36) | constructor(params: MCPClientParams) {
    method setupStderrListener (line 87) | private setupStderrListener(transport: StdioClientTransport) {
    method getStderrLogs (line 102) | getStderrLogs(): string[] {
    method isMethodNotFoundError (line 106) | private isMethodNotFoundError(error: unknown) {
    method initialize (line 115) | async initialize(options: { onProgress?: (progress: Progress) => void ...
    method disconnect (line 128) | async disconnect() {
    method listTools (line 139) | async listTools() {
    method listResources (line 144) | async listResources() {
    method listPrompts (line 149) | async listPrompts() {
    method listManifests (line 154) | async listManifests() {
    method callTool (line 176) | async callTool(toolName: string, args: any): Promise<ToolCallResult> {

FILE: apps/desktop/src/main/libs/mcp/types.ts
  type McpTool (line 1) | interface McpTool {
  type McpResource (line 11) | interface McpResource {
  type McpPromptArgument (line 18) | interface McpPromptArgument {
  type McpPrompt (line 24) | interface McpPrompt {
  type TextContent (line 30) | interface TextContent {
  type ImageContent (line 36) | interface ImageContent {
  type AudioContent (line 46) | interface AudioContent {
  type ResourceContent (line 56) | interface ResourceContent {
  type ResourceLinkContent (line 68) | interface ResourceLinkContent {
  type ToolCallContent (line 82) | type ToolCallContent =
  type ToolCallResult (line 89) | interface ToolCallResult {
  type AuthConfig (line 95) | interface AuthConfig {
  type HttpMCPClientParams (line 101) | interface HttpMCPClientParams {
  type StdioMCPClientParams (line 109) | interface StdioMCPClientParams {
  type MCPClientParams (line 117) | type MCPClientParams = HttpMCPClientParams | StdioMCPClientParams;

FILE: apps/desktop/src/main/menus/impls/BaseMenuPlatform.test.ts
  class TestMenuPlatform (line 8) | class TestMenuPlatform extends BaseMenuPlatform {}

FILE: apps/desktop/src/main/menus/impls/BaseMenuPlatform.ts
  method constructor (line 7) | constructor(app: App) {

FILE: apps/desktop/src/main/menus/impls/linux.ts
  class LinuxMenu (line 9) | class LinuxMenu extends BaseMenuPlatform implements IMenuPlatform {
    method buildAndSetAppMenu (line 13) | buildAndSetAppMenu(options?: MenuOptions): Menu {
    method buildContextMenu (line 20) | buildContextMenu(type: string, data?: ContextMenuData): Menu {
    method buildTrayMenu (line 38) | buildTrayMenu(): Menu {
    method refresh (line 44) | refresh(options?: MenuOptions): void {
    method getAppMenuTemplate (line 50) | private getAppMenuTemplate(options?: MenuOptions): MenuItemConstructor...
    method getDefaultContextMenuTemplate (line 234) | private getDefaultContextMenuTemplate(data?: ContextMenuData): MenuIte...
    method getChatContextMenuTemplate (line 309) | private getChatContextMenuTemplate(data?: ContextMenuData): MenuItemCo...
    method getEditorContextMenuTemplate (line 383) | private getEditorContextMenuTemplate(data?: ContextMenuData): MenuItem...
    method getTrayMenuTemplate (line 427) | private getTrayMenuTemplate(): MenuItemConstructorOptions[] {

FILE: apps/desktop/src/main/menus/impls/macOS.ts
  class MacOSMenu (line 13) | class MacOSMenu extends BaseMenuPlatform implements IMenuPlatform {
    method buildAndSetAppMenu (line 17) | buildAndSetAppMenu(options?: MenuOptions): Menu {
    method buildContextMenu (line 27) | buildContextMenu(type: string, data?: ContextMenuData): Menu {
    method buildTrayMenu (line 45) | buildTrayMenu(): Menu {
    method refresh (line 51) | refresh(options?: MenuOptions): void {
    method getAppMenuTemplate (line 61) | private getAppMenuTemplate(options?: MenuOptions): MenuItemConstructor...
    method getUpdateMenuItem (line 389) | private getUpdateMenuItem(t: (key: string, opts?: any) => string): Men...
    method getDefaultContextMenuTemplate (line 417) | private getDefaultContextMenuTemplate(data?: ContextMenuData): MenuIte...
    method getChatContextMenuTemplate (line 503) | private getChatContextMenuTemplate(data?: ContextMenuData): MenuItemCo...
    method getEditorContextMenuTemplate (line 589) | private getEditorContextMenuTemplate(data?: ContextMenuData): MenuItem...
    method getTrayMenuTemplate (line 645) | private getTrayMenuTemplate(): MenuItemConstructorOptions[] {

FILE: apps/desktop/src/main/menus/impls/windows.ts
  class WindowsMenu (line 9) | class WindowsMenu extends BaseMenuPlatform implements IMenuPlatform {
    method buildAndSetAppMenu (line 13) | buildAndSetAppMenu(options?: MenuOptions): Menu {
    method buildContextMenu (line 20) | buildContextMenu(type: string, data?: ContextMenuData): Menu {
    method buildTrayMenu (line 38) | buildTrayMenu(): Menu {
    method refresh (line 44) | refresh(options?: MenuOptions): void {
    method getAppMenuTemplate (line 49) | private getAppMenuTemplate(options?: MenuOptions): MenuItemConstructor...
    method getUpdateMenuItem (line 213) | private getUpdateMenuItem(t: (key: string, opts?: any) => string): Men...
    method getDefaultContextMenuTemplate (line 241) | private getDefaultContextMenuTemplate(data?: ContextMenuData): MenuIte...
    method getChatContextMenuTemplate (line 316) | private getChatContextMenuTemplate(data?: ContextMenuData): MenuItemCo...
    method getEditorContextMenuTemplate (line 390) | private getEditorContextMenuTemplate(data?: ContextMenuData): MenuItem...
    method getTrayMenuTemplate (line 434) | private getTrayMenuTemplate(): MenuItemConstructorOptions[] {

FILE: apps/desktop/src/main/menus/types.ts
  type MenuOptions (line 3) | interface MenuOptions {
  type ContextMenuData (line 12) | interface ContextMenuData {
  type IMenuPlatform (line 29) | interface IMenuPlatform {

FILE: apps/desktop/src/main/modules/contentSearch/__tests__/base.test.ts
  class TestContentSearch (line 33) | class TestContentSearch extends BaseContentSearch {
    method grep (line 36) | async grep(params: GrepContentParams): Promise<GrepContentResult> {
    method checkToolAvailable (line 40) | async checkToolAvailable(tool: string): Promise<boolean> {
    method testBuildGrepArgs (line 45) | public testBuildGrepArgs(tool: 'rg' | 'ag' | 'grep', params: GrepConte...
    method testGetDefaultIgnorePatterns (line 49) | public testGetDefaultIgnorePatterns(): string[] {

FILE: apps/desktop/src/main/modules/contentSearch/base.ts
  type ContentSearchTool (line 14) | type ContentSearchTool = 'rg' | 'ag' | 'grep' | 'nodejs';
  method constructor (line 23) | constructor(toolDetectorManager?: ToolDetectorManager) {
  method setToolDetectorManager (line 31) | setToolDetectorManager(manager: ToolDetectorManager): void {
  method buildGrepArgs (line 52) | protected buildGrepArgs(tool: 'rg' | 'ag' | 'grep', params: GrepContentP...
  method grepWithNodejs (line 143) | protected async grepWithNodejs(params: GrepContentParams): Promise<GrepC...
  method getDefaultIgnorePatterns (line 256) | protected getDefaultIgnorePatterns(): string[] {

FILE: apps/desktop/src/main/modules/contentSearch/impl/linux.ts
  class LinuxContentSearchImpl (line 12) | class LinuxContentSearchImpl extends UnixContentSearch {
    method constructor (line 13) | constructor(toolDetectorManager?: ToolDetectorManager) {
    method getDefaultIgnorePatterns (line 21) | protected override getDefaultIgnorePatterns(): string[] {

FILE: apps/desktop/src/main/modules/contentSearch/impl/macOS.ts
  class MacOSContentSearchImpl (line 12) | class MacOSContentSearchImpl extends UnixContentSearch {
    method constructor (line 13) | constructor(toolDetectorManager?: ToolDetectorManager) {
    method getDefaultIgnorePatterns (line 22) | protected override getDefaultIgnorePatterns(): string[] {

FILE: apps/desktop/src/main/modules/contentSearch/impl/unix.ts
  type UnixContentSearchTool (line 16) | type UnixContentSearchTool = 'rg' | 'ag' | 'grep' | 'nodejs';
  method constructor (line 28) | constructor(toolDetectorManager?: ToolDetectorManager) {
  method checkToolAvailable (line 37) | async checkToolAvailable(tool: string): Promise<boolean> {
  method determineBestUnixTool (line 51) | protected async determineBestUnixTool(): Promise<UnixContentSearchTool> {
  method fallbackToNextTool (line 79) | protected async fallbackToNextTool(
  method grep (line 101) | async grep(params: GrepContentParams): Promise<GrepContentResult> {
  method grepWithTool (line 134) | protected async grepWithTool(
  method grepWithRipgrep (line 157) | protected async grepWithRipgrep(params: GrepContentParams): Promise<Grep...
  method grepWithAg (line 164) | protected async grepWithAg(params: GrepContentParams): Promise<GrepConte...
  method grepWithGrep (line 171) | protected async grepWithGrep(params: GrepContentParams): Promise<GrepCon...
  method grepWithExternalTool (line 178) | protected async grepWithExternalTool(
  method getActualMatchCount (line 263) | protected async getActualMatchCount(

FILE: apps/desktop/src/main/modules/contentSearch/impl/windows.ts
  type WindowsContentSearchTool (line 16) | type WindowsContentSearchTool = 'rg' | 'findstr' | 'nodejs';
  class WindowsContentSearchImpl (line 22) | class WindowsContentSearchImpl extends BaseContentSearch {
    method constructor (line 28) | constructor(toolDetectorManager?: ToolDetectorManager) {
    method checkToolAvailable (line 38) | async checkToolAvailable(tool: string): Promise<boolean> {
    method determineBestTool (line 51) | private async determineBestTool(): Promise<WindowsContentSearchTool> {
    method fallbackToNextTool (line 70) | private async fallbackToNextTool(
    method grep (line 92) | async grep(params: GrepContentParams): Promise<GrepContentResult> {
    method grepWithTool (line 128) | private async grepWithTool(
    method grepWithRipgrep (line 148) | private async grepWithRipgrep(params: GrepContentParams): Promise<Grep...
    method getActualMatchCount (line 224) | private async getActualMatchCount(params: GrepContentParams): Promise<...
    method grepWithFindstr (line 254) | private async grepWithFindstr(params: GrepContentParams): Promise<Grep...
    method getDefaultIgnorePatterns (line 357) | protected override getDefaultIgnorePatterns(): string[] {

FILE: apps/desktop/src/main/modules/contentSearch/index.ts
  function createContentSearchImpl (line 21) | function createContentSearchImpl(

FILE: apps/desktop/src/main/modules/fileSearch/__tests__/base.test.ts
  class TestFileSearch (line 31) | class TestFileSearch extends BaseFileSearch {
    method search (line 32) | async search(options: SearchOptions): Promise<FileResult[]> {
    method glob (line 37) | async glob(_params: GlobFilesParams): Promise<GlobFilesResult> {
    method checkSearchServiceStatus (line 46) | async checkSearchServiceStatus(): Promise<boolean> {
    method updateSearchIndex (line 50) | async updateSearchIndex(): Promise<boolean> {
    method testDetermineContentType (line 55) | public testDetermineContentType(ext: string): string {
    method testEscapeGlobPattern (line 59) | public testEscapeGlobPattern(pattern: string): string {
    method testProcessFilePaths (line 63) | public testProcessFilePaths(
    method testSortResults (line 71) | public testSortResults(

FILE: apps/desktop/src/main/modules/fileSearch/base.ts
  constant CONTENT_TYPE_MAP (line 13) | const CONTENT_TYPE_MAP: Record<string, string> = {
  method constructor (line 86) | constructor(toolDetectorManager?: ToolDetectorManager) {
  method setToolDetectorManager (line 94) | setToolDetectorManager(manager: ToolDetectorManager): void {
  method determineContentType (line 103) | protected determineContentType(extension: string): string {
  method escapeGlobPattern (line 112) | protected escapeGlobPattern(pattern: string): string {
  method processFilePaths (line 123) | protected async processFilePaths(
  method sortResults (line 163) | protected sortResults(

FILE: apps/desktop/src/main/modules/fileSearch/impl/linux.ts
  class LinuxSearchServiceImpl (line 14) | class LinuxSearchServiceImpl extends UnixFileSearch {
    method constructor (line 15) | constructor(toolDetectorManager?: ToolDetectorManager) {
    method search (line 24) | async search(options: SearchOptions): Promise<FileResult[]> {
    method checkSearchServiceStatus (line 38) | async checkSearchServiceStatus(): Promise<boolean> {
    method updateSearchIndex (line 48) | async updateSearchIndex(): Promise<boolean> {

FILE: apps/desktop/src/main/modules/fileSearch/impl/macOS.ts
  type MacOSSearchTool (line 20) | type MacOSSearchTool = 'mdfind' | UnixSearchTool;
  class MacOSSearchServiceImpl (line 22) | class MacOSSearchServiceImpl extends UnixFileSearch {
    method constructor (line 34) | constructor(toolDetectorManager?: ToolDetectorManager) {
    method search (line 43) | async search(options: SearchOptions): Promise<FileResult[]> {
    method determineBestTool (line 57) | private async determineBestTool(): Promise<MacOSSearchTool> {
    method searchWithTool (line 76) | private async searchWithTool(
    method fallbackFromMdfind (line 90) | private async fallbackFromMdfind(): Promise<MacOSSearchTool> {
    method searchWithSpotlight (line 97) | private async searchWithSpotlight(options: SearchOptions): Promise<Fil...
    method getDefaultIgnorePatterns (line 151) | protected override getDefaultIgnorePatterns(): string[] {
    method checkSearchServiceStatus (line 159) | async checkSearchServiceStatus(): Promise<boolean> {
    method updateSearchIndex (line 168) | async updateSearchIndex(updatePath?: string): Promise<boolean> {
    method buildSearchCommand (line 175) | private buildSearchCommand(options: SearchOptions): {
    method processSpotlightResults (line 286) | private async processSpotlightResults(
    method getDetailedMetadata (line 348) | private async getDetailedMetadata(filePath: string): Promise<Record<st...
    method parseMetadataValue (line 396) | private parseMetadataValue(input: string): any {
    method checkSpotlightStatus (line 425) | private async checkSpotlightStatus(): Promise<boolean> {
    method updateSpotlightIndex (line 456) | private async updateSpotlightIndex(updatePath?: string): Promise<boole...

FILE: apps/desktop/src/main/modules/fileSearch/impl/unix.ts
  type UnixSearchTool (line 22) | type UnixSearchTool = 'fd' | 'find' | 'fast-glob';
  method constructor (line 34) | constructor(toolDetectorManager?: ToolDetectorManager) {
  method checkToolAvailable (line 43) | protected async checkToolAvailable(tool: string): Promise<boolean> {
  method determineBestUnixTool (line 57) | protected async determineBestUnixTool(): Promise<UnixSearchTool> {
  method fallbackToNextTool (line 81) | protected async fallbackToNextTool(currentTool: UnixSearchTool): Promise...
  method searchWithUnixTool (line 104) | protected async searchWithUnixTool(
  method searchWithFd (line 126) | protected async searchWithFd(options: SearchOptions): Promise<FileResult...
  method searchWithFind (line 187) | protected async searchWithFind(options: SearchOptions): Promise<FileResu...
  method searchWithFastGlob (line 254) | protected async searchWithFastGlob(options: SearchOptions): Promise<File...
  method getDefaultIgnorePatterns (line 292) | protected getDefaultIgnorePatterns(): string[] {
  method glob (line 302) | async glob(params: GlobFilesParams): Promise<GlobFilesResult> {
  method globWithUnixTool (line 316) | protected async globWithUnixTool(
  method globWithFd (line 338) | protected async globWithFd(params: GlobFilesParams): Promise<GlobFilesRe...
  method globWithFind (line 394) | protected async globWithFind(params: GlobFilesParams): Promise<GlobFiles...
  method globWithFastGlob (line 456) | protected async globWithFastGlob(params: GlobFilesParams): Promise<GlobF...
  method getFilesWithStats (line 501) | private async getFilesWithStats(

FILE: apps/desktop/src/main/modules/fileSearch/impl/windows.ts
  type WindowsFallbackTool (line 22) | type WindowsFallbackTool = 'fd' | 'powershell' | 'fast-glob';
  class WindowsSearchServiceImpl (line 28) | class WindowsSearchServiceImpl extends BaseFileSearch {
    method constructor (line 34) | constructor(toolDetectorManager?: ToolDetectorManager) {
    method search (line 43) | async search(options: SearchOptions): Promise<FileResult[]> {
    method determineBestTool (line 57) | private async determineBestTool(): Promise<WindowsFallbackTool> {
    method checkToolAvailable (line 78) | private async checkToolAvailable(tool: string): Promise<boolean> {
    method searchWithTool (line 90) | private async searchWithTool(
    method fallbackToNextTool (line 110) | private async fallbackToNextTool(currentTool: WindowsFallbackTool): Pr...
    method searchWithFd (line 132) | private async searchWithFd(options: SearchOptions): Promise<FileResult...
    method searchWithPowerShell (line 193) | private async searchWithPowerShell(options: SearchOptions): Promise<Fi...
    method searchWithFastGlob (line 255) | private async searchWithFastGlob(options: SearchOptions): Promise<File...
    method checkSearchServiceStatus (line 301) | async checkSearchServiceStatus(): Promise<boolean> {
    method updateSearchIndex (line 311) | async updateSearchIndex(): Promise<boolean> {
    method glob (line 322) | async glob(params: GlobFilesParams): Promise<GlobFilesResult> {
    method globWithFd (line 338) | private async globWithFd(params: GlobFilesParams): Promise<GlobFilesRe...
    method globWithFastGlob (line 393) | private async globWithFastGlob(params: GlobFilesParams): Promise<GlobF...
    method getFilesWithStats (line 438) | private async getFilesWithStats(

FILE: apps/desktop/src/main/modules/fileSearch/types.ts
  type FileResult (line 1) | interface FileResult {
  type SearchOptions (line 19) | interface SearchOptions {

FILE: apps/desktop/src/main/modules/networkProxy/dispatcher.ts
  class ProxyDispatcherManager (line 16) | class ProxyDispatcherManager {
    method applyProxySettings (line 23) | static async applyProxySettings(config: NetworkProxySettings): Promise...
    method doApplyProxySettings (line 47) | private static async doApplyProxySettings(config: NetworkProxySettings...
    method createProxyAgent (line 94) | static createProxyAgent(proxyType: string, proxyUrl: string) {
    method safeDestroyDispatcher (line 130) | private static async safeDestroyDispatcher(dispatcher: any): Promise<v...

FILE: apps/desktop/src/main/modules/networkProxy/tester.ts
  type ProxyTestResult (line 17) | interface ProxyTestResult {
  class ProxyConnectionTester (line 26) | class ProxyConnectionTester {
    method testConnection (line 33) | static async testConnection(
    method testProxyConfig (line 80) | static async testProxyConfig(

FILE: apps/desktop/src/main/modules/networkProxy/urlBuilder.ts
  method build (line 10) | build(config: NetworkProxySettings): string {

FILE: apps/desktop/src/main/modules/networkProxy/validator.ts
  type ProxyValidationResult (line 6) | interface ProxyValidationResult {
  class ProxyConfigValidator (line 14) | class ProxyConfigValidator {
    method validate (line 21) | static validate(config: NetworkProxySettings): ProxyValidationResult {
    method isValidHost (line 72) | private static isValidHost(host: string): boolean {

FILE: apps/desktop/src/main/modules/toolDetectors/fileSearchDetectors.ts
  method detect (line 25) | async detect(): Promise<ToolStatus> {

FILE: apps/desktop/src/main/modules/toolDetectors/runtimeEnvironmentDetectors.ts
  method detect (line 32) | async detect(): Promise<ToolStatus> {

FILE: apps/desktop/src/main/modules/updater/configs.ts
  constant VALID_CHANNELS (line 8) | const VALID_CHANNELS = new Set<UpdateChannel>(['stable', 'nightly', 'can...
  constant BUILD_CHANNEL (line 10) | const BUILD_CHANNEL: string = rawChannel;
  constant UPDATE_CHANNEL (line 11) | const UPDATE_CHANNEL: UpdateChannel = VALID_CHANNELS.has(rawChannel as U...
  constant UPDATE_SERVER_URL (line 20) | const UPDATE_SERVER_URL = getDesktopEnv().UPDATE_SERVER_URL;

FILE: apps/desktop/src/main/services/contentSearchSrv.ts
  class ContentSearchService (line 12) | class ContentSearchService extends ServiceModule {
    method grep (line 18) | async grep(params: GrepContentParams): Promise<GrepContentResult> {
    method checkToolAvailable (line 29) | async checkToolAvailable(tool: string): Promise<boolean> {

FILE: apps/desktop/src/main/services/fileSearchSrv.ts
  class FileSearchService (line 17) | class FileSearchService extends ServiceModule {
    method search (line 23) | async search(
    method checkSearchServiceStatus (line 33) | async checkSearchServiceStatus(): Promise<boolean> {
    method updateSearchIndex (line 42) | async updateSearchIndex(path?: string): Promise<boolean> {
    method glob (line 51) | async glob(params: GlobFilesParams): Promise<GlobFilesResult> {

FILE: apps/desktop/src/main/services/fileSrv.ts
  class FileNotFoundError (line 17) | class FileNotFoundError extends Error {
    method constructor (line 18) | constructor(
  type UploadFileParams (line 33) | interface UploadFileParams {
  type FileMetadata (line 41) | interface FileMetadata {
  class FileService (line 48) | class FileService extends ServiceModule {
    method UPLOADS_DIR (line 53) | get UPLOADS_DIR() {
    method constructor (line 57) | constructor(app) {
    method uploadFile (line 64) | async uploadFile({
    method isLegacyPath (line 147) | private isLegacyPath(path: string): boolean {
    method getFile (line 159) | async getFile(path: string): Promise<{ content: ArrayBuffer; mimeType:...
    method deleteFile (line 287) | async deleteFile(path: string): Promise<{ success: boolean }> {
    method deleteFiles (line 364) | async deleteFiles(paths: string[]): Promise<DeleteFilesResponse> {
    method getFilePath (line 413) | async getFilePath(path: string): Promise<string> {
    method getFileHTTPURL (line 462) | async getFileHTTPURL(path: string): Promise<string> {

FILE: apps/desktop/src/main/services/gatewayConnectionSrv.ts
  constant DEFAULT_GATEWAY_URL (line 18) | const DEFAULT_GATEWAY_URL = 'https://device-gateway.lobehub.com';
  type ToolCallHandler (line 20) | interface ToolCallHandler {
  class GatewayConnectionService (line 30) | class GatewayConnectionService extends ServiceModule {
    method setTokenProvider (line 44) | setTokenProvider(provider: () => Promise<string | null>) {
    method setTokenRefresher (line 51) | setTokenRefresher(refresher: () => Promise<{ error?: string; success: ...
    method setToolCallHandler (line 58) | setToolCallHandler(handler: ToolCallHandler) {
    method loadOrCreateDeviceId (line 64) | loadOrCreateDeviceId() {
    method getDeviceId (line 75) | getDeviceId(): string {
    method getStatus (line 81) | getStatus(): GatewayConnectionStatus {
    method getDeviceInfo (line 85) | getDeviceInfo() {
    method getDeviceName (line 97) | getDeviceName(): string {
    method setDeviceName (line 101) | setDeviceName(name: string) {
    method getDeviceDescription (line 105) | getDeviceDescription(): string {
    method setDeviceDescription (line 109) | setDeviceDescription(description: string) {
    method connect (line 115) | async connect(): Promise<{ error?: string; success: boolean }> {
    method disconnect (line 122) | async disconnect(): Promise<{ success: boolean }> {
    method doConnect (line 131) | private async doConnect(): Promise<{ error?: string; success: boolean ...
    method setupClientEvents (line 168) | private setupClientEvents(client: GatewayClient) {
    method handleAuthExpired (line 193) | private async handleAuthExpired() {
    method handleSystemInfoRequest (line 220) | private handleSystemInfoRequest(client: GatewayClient, request: System...
    method setStatus (line 285) | private setStatus(status: GatewayConnectionStatus) {
    method getGatewayUrl (line 295) | private getGatewayUrl(): string {
    method extractUserIdFromToken (line 305) | private extractUserIdFromToken(token: string): string | null {

FILE: apps/desktop/src/main/services/index.ts
  class ServiceModule (line 3) | class ServiceModule {
    method constructor (line 4) | constructor(public app: App) {
  type IServiceModule (line 9) | type IServiceModule = typeof ServiceModule;

FILE: apps/desktop/src/main/shortcuts/config.ts
  type ShortcutActionType (line 12) | type ShortcutActionType = (typeof ShortcutActionEnum)[keyof typeof Short...
  constant DEFAULT_SHORTCUTS_CONFIG (line 17) | const DEFAULT_SHORTCUTS_CONFIG: Record<ShortcutActionType, string> = {

FILE: apps/desktop/src/main/types/protocol.ts
  type McpStdioConfig (line 4) | interface McpStdioConfig {
  type McpHttpConfig (line 14) | interface McpHttpConfig {
  type McpConfig (line 23) | type McpConfig = McpStdioConfig | McpHttpConfig;
  type McpSchema (line 29) | interface McpSchema {
  type ProtocolUrlParsed (line 51) | interface ProtocolUrlParsed {

FILE: apps/desktop/src/main/types/store.ts
  type ElectronMainStore (line 7) | interface ElectronMainStore {
  type StoreKey (line 28) | type StoreKey = keyof ElectronMainStore;

FILE: apps/desktop/src/main/utils/http-headers.ts
  type ElectronResponseHeaders (line 9) | type ElectronResponseHeaders = Record<string, string[]>;
  function appendVercelCookie (line 15) | function appendVercelCookie(
  function setResponseHeader (line 38) | function setResponseHeader(
  function hasResponseHeader (line 55) | function hasResponseHeader(headers: ElectronResponseHeaders, name: strin...
  function getResponseHeader (line 62) | function getResponseHeader(
  function deleteResponseHeader (line 77) | function deleteResponseHeader(headers: ElectronResponseHeaders, name: st...

FILE: apps/desktop/src/main/utils/ipc/__tests__/base.test.ts
  class TestService (line 22) | class TestService extends IpcService {
    method ping (line 27) | ping(payload?: string) {
  class DirectCallService (line 52) | class DirectCallService extends IpcService {
    method run (line 57) | run(payload: string) {

FILE: apps/desktop/src/main/utils/ipc/base.ts
  type IpcContext (line 7) | interface IpcContext {
  function IpcMethod (line 17) | function IpcMethod() {
  class IpcHandler (line 33) | class IpcHandler {
    method getInstance (line 37) | static getInstance(): IpcHandler {
    method registerMethod (line 44) | registerMethod<TArgs extends unknown[], TOutput>(
    method sendToRenderer (line 73) | sendToRenderer<T = any>(webContents: WebContents, channel: string, dat...
  method constructor (line 83) | constructor() {
  method registerMethods (line 87) | protected registerMethods(): void {
  method registerMethod (line 101) | protected registerMethod<TArgs extends unknown[], TOutput>(
  type IpcServiceConstructor (line 112) | interface IpcServiceConstructor {
  function createServices (line 118) | function createServices<T extends readonly IpcServiceConstructor[]>(
  type CreateServicesResult (line 141) | type CreateServicesResult<T extends readonly IpcServiceConstructor[]> = {
  function getIpcContext (line 145) | function getIpcContext() {
  function runWithIpcContext (line 149) | function runWithIpcContext<T>(context: IpcContext, callback: () => T): T {

FILE: apps/desktop/src/main/utils/ipc/utility.ts
  type ExtractMethodSignature (line 2) | type ExtractMethodSignature<T> = T extends (...args: infer Args) => infe...
  type ExtractServiceMethods (line 6) | type ExtractServiceMethods<T> = {
  type AlwaysPromise (line 10) | type AlwaysPromise<T> = Promise<Awaited<T>>;
  type MergeIpcService (line 14) | type MergeIpcService<T> = {

FILE: apps/desktop/src/main/utils/permissions.ts
  type AuthType (line 15) | type AuthType =
  type PermissionType (line 28) | type PermissionType = 'authorized' | 'denied' | 'not determined' | 'rest...
  function getMacPermissionsModule (line 43) | function getMacPermissionsModule(): typeof import('node-mac-permissions'...
  function __resetMacPermissionsModuleCache (line 66) | function __resetMacPermissionsModuleCache(): void {
  function __setMacPermissionsModule (line 75) | function __setMacPermissionsModule(
  type PermissionStatus (line 87) | type PermissionStatus =
  function normalizeStatus (line 97) | function normalizeStatus(status: PermissionType | 'not determined'): Per...
  function getPermissionStatus (line 106) | function getPermissionStatus(type: AuthType): PermissionStatus {
  function getAccessibilityStatus (line 122) | function getAccessibilityStatus(): PermissionStatus {
  function requestAccessibilityAccess (line 130) | function requestAccessibilityAccess(): boolean {
  function getMicrophoneStatus (line 148) | function getMicrophoneStatus(): PermissionStatus {
  function requestMicrophoneAccess (line 156) | async function requestMicrophoneAccess(): Promise<boolean> {
  function getCameraStatus (line 194) | function getCameraStatus(): PermissionStatus {
  function requestCameraAccess (line 202) | async function requestCameraAccess(): Promise<boolean> {
  function getScreenCaptureStatus (line 240) | function getScreenCaptureStatus(): PermissionStatus {
  function requestScreenCaptureAccess (line 249) | async function requestScreenCaptureAccess(openPreferences = true): Promi...
  function getFullDiskAccessStatus (line 277) | function getFullDiskAccessStatus(): PermissionStatus {
  function requestFullDiskAccess (line 287) | function requestFullDiskAccess(): void {
  function openFullDiskAccessSettings (line 302) | async function openFullDiskAccessSettings(): Promise<void> {
  function getInputMonitoringStatus (line 344) | function getInputMonitoringStatus(): PermissionStatus {
  function getMediaAccessStatus (line 352) | function getMediaAccessStatus(mediaType: 'microphone' | 'screen'): string {

FILE: apps/desktop/src/main/utils/protocol.ts
  type AppChannel (line 5) | type AppChannel = 'stable' | 'beta' | 'nightly';
  function validateMcpSchema (line 46) | function validateMcpSchema(schema: any): schema is McpSchema {
  function generateRFCProtocolUrl (line 143) | function generateRFCProtocolUrl(params: {

FILE: apps/desktop/src/preload/invoke.test.ts
  type TestResponse (line 102) | interface TestResponse {

FILE: apps/desktop/src/preload/invoke.ts
  type IpcInvoke (line 3) | type IpcInvoke = <T = unknown>(event: string, ...data: unknown[]) => Pro...

FILE: apps/desktop/src/preload/streamer.ts
  type StreamResponse (line 5) | interface StreamResponse {
  type StreamerCallbacks (line 11) | interface StreamerCallbacks {

FILE: apps/device-gateway/src/DeviceGatewayDO.ts
  constant AUTH_TIMEOUT (line 7) | const AUTH_TIMEOUT = 10_000;
  constant HEARTBEAT_TIMEOUT (line 8) | const HEARTBEAT_TIMEOUT = 90_000;
  constant HEARTBEAT_CHECK_INTERVAL (line 9) | const HEARTBEAT_CHECK_INTERVAL = 90_000;
  class DeviceGatewayDO (line 11) | class DeviceGatewayDO extends DurableObject<Env> {
    method fetch (line 40) | async fetch(request: Request): Promise<Response> {
    method webSocketMessage (line 52) | async webSocketMessage(ws: WebSocket, message: string | ArrayBuffer) {
    method webSocketClose (line 121) | async webSocketClose(_ws: WebSocket, _code: number) {
    method webSocketError (line 125) | async webSocketError(ws: WebSocket, _error: unknown) {
    method alarm (line 131) | async alarm() {
    method handleWebSocketUpgrade (line 162) | private async handleWebSocketUpgrade(request: Request): Promise<Respon...
    method scheduleAuthTimeout (line 204) | private async scheduleAuthTimeout() {
    method scheduleHeartbeatCheck (line 211) | private async scheduleHeartbeatCheck() {
    method getAuthenticatedSockets (line 220) | private getAuthenticatedSockets(): WebSocket[] {
    method handleSystemInfo (line 229) | private async handleSystemInfo(request: Request): Promise<Response> {
    method handleToolCall (line 283) | private async handleToolCall(request: Request): Promise<Response> {

FILE: apps/device-gateway/src/auth.ts
  type CurrentUserResponse (line 7) | interface CurrentUserResponse {
  type ResolveSocketAuthOptions (line 17) | interface ResolveSocketAuthOptions {
  function getPublicKey (line 27) | async function getPublicKey(env: Env): Promise<CryptoKey> {
  function verifyDesktopToken (line 41) | async function verifyDesktopToken(
  function verifyApiKeyToken (line 58) | async function verifyApiKeyToken(
  function resolveSocketAuth (line 91) | async function resolveSocketAuth(options: ResolveSocketAuthOptions): Pro...

FILE: apps/device-gateway/src/types.ts
  type Env (line 1) | interface Env {
  type DeviceAttachment (line 9) | interface DeviceAttachment {
  type AuthMessage (line 22) | interface AuthMessage {
  type HeartbeatMessage (line 29) | interface HeartbeatMessage {
  type ToolCallResponseMessage (line 33) | interface ToolCallResponseMessage {
  type SystemInfoResponseMessage (line 43) | interface SystemInfoResponseMessage {
  type DeviceSystemInfo (line 49) | interface DeviceSystemInfo {
  type AuthSuccessMessage (line 63) | interface AuthSuccessMessage {
  type AuthFailedMessage (line 67) | interface AuthFailedMessage {
  type HeartbeatAckMessage (line 72) | interface HeartbeatAckMessage {
  type AuthExpiredMessage (line 76) | interface AuthExpiredMessage {
  type ToolCallRequestMessage (line 80) | interface ToolCallRequestMessage {
  type SystemInfoRequestMessage (line 90) | interface SystemInfoRequestMessage {
  type ClientMessage (line 95) | type ClientMessage =
  type ServerMessage (line 100) | type ServerMessage =

FILE: e2e/scripts/setup.ts
  constant CONFIG (line 26) | const CONFIG = {
  function log (line 65) | function log(emoji: string, message: string) {
  function logStep (line 69) | function logStep(step: number, total: number, message: string) {
  function exec (line 73) | function exec(
  function execAsync (line 88) | function execAsync(
  function sleep (line 113) | async function sleep(ms: number): Promise<void> {
  function waitForCondition (line 119) | async function waitForCondition(
  function isDockerRunning (line 140) | function isDockerRunning(): boolean {
  function isContainerRunning (line 145) | function isContainerRunning(name: string): boolean {
  function containerExists (line 150) | function containerExists(name: string): boolean {
  function stopContainer (line 155) | function stopContainer(name: string): void {
  function removeContainer (line 162) | function removeContainer(name: string): void {
  function startPostgres (line 169) | async function startPostgres(): Promise<void> {
  function killProcessOnPort (line 225) | function killProcessOnPort(port: number): void {
  function runMigration (line 242) | async function runMigration(): Promise<void> {
  function buildApp (line 258) | async function buildApp(): Promise<void> {
  function isServerRunning (line 276) | async function isServerRunning(port: number): Promise<boolean> {
  function getServerEnv (line 285) | function getServerEnv(port: number): Record<string, string> {
  function startServer (line 301) | async function startServer(port: number): Promise<void> {
  function cleanup (line 346) | function cleanup(): void {
  function showHelp (line 362) | function showHelp(): void {
  type Options (line 390) | interface Options {
  function parseArgs (line 400) | function parseArgs(): Options {
  function main (line 453) | async function main(): Promise<void> {

FILE: e2e/src/mocks/community/handlers.ts
  function parseTrpcUrl (line 20) | function parseTrpcUrl(url: string): { input?: Record<string, unknown>; p...

FILE: e2e/src/mocks/community/types.ts
  type PaginationInfo (line 6) | interface PaginationInfo {
  type DiscoverAssistantItem (line 17) | interface DiscoverAssistantItem {
  type AssistantListResponse (line 33) | interface AssistantListResponse {
  type DiscoverModelItem (line 42) | interface DiscoverModelItem {
  type ModelListResponse (line 58) | interface ModelListResponse {
  type DiscoverProviderItem (line 67) | interface DiscoverProviderItem {
  type ProviderListResponse (line 75) | interface ProviderListResponse {
  type DiscoverMcpItem (line 84) | interface DiscoverMcpItem {
  type McpListResponse (line 95) | interface McpListResponse {

FILE: e2e/src/mocks/index.ts
  type MockHandler (line 15) | interface MockHandler {
  type MockConfig (line 24) | interface MockConfig {
  class MockManager (line 49) | class MockManager {
    method constructor (line 53) | constructor(config: Partial<MockConfig> = {}) {
    method setup (line 60) | async setup(page: Page): Promise<void> {
    method disableDomain (line 90) | disableDomain(domain: string): void {
    method enableDomain (line 101) | enableDomain(domain: string): void {
    method addHandlers (line 112) | addHandlers(domain: string, handlers: MockHandler[]): void {
  function createTrpcResponse (line 127) | function createTrpcResponse<T>(data: T): string {
  function createTrpcError (line 138) | function createTrpcError(message: string, code = 'INTERNAL_SERVER_ERROR'...
  function createJsonResponse (line 150) | function createJsonResponse<T>(data: T): string {

FILE: e2e/src/mocks/llm/index.ts
  type LLMMockConfig (line 13) | interface LLMMockConfig {
  type ChatMessage (line 26) | interface ChatMessage {
  function buildSSEChunks (line 51) | function buildSSEChunks(content: string, chunkSize: number): string[] {
  class LLMMockManager (line 98) | class LLMMockManager {
    method constructor (line 103) | constructor(config: Partial<LLMMockConfig> = {}) {
    method setResponse (line 110) | setResponse(userMessage: string, response: string): void {
    method clearResponses (line 117) | clearResponses(): void {
    method getResponse (line 124) | private getResponse(messages: ChatMessage[]): string {
    method setup (line 141) | async setup(page: Page): Promise<void> {
    method handleChatRequest (line 160) | private async handleChatRequest(route: Route): Promise<void> {
    method disable (line 208) | disable(): void {
    method enable (line 215) | enable(): void {

FILE: e2e/src/steps/agent/conversation.steps.ts
  function focusChatInput (line 13) | async function focusChatInput(this: CustomWorld): Promise<void> {

FILE: e2e/src/steps/agent/message-ops.steps.ts
  function findAssistantMessage (line 20) | async function findAssistantMessage(page: CustomWorld['page']) {
  function findVisibleMenuItem (line 43) | async function findVisibleMenuItem(page: CustomWorld['page'], name: RegE...

FILE: e2e/src/steps/home/sidebarAgent.steps.ts
  function inputNewName (line 19) | async function inputNewName(
  function createTestAgent (line 59) | async function createTestAgent(title: string = 'Test Agent'): Promise<st...

FILE: e2e/src/steps/home/sidebarGroup.steps.ts
  function createTestGroup (line 18) | async function createTestGroup(title: string = 'Test Group'): Promise<st...

FILE: e2e/src/steps/page/editor-content.steps.ts
  function getEditor (line 19) | async function getEditor(world: CustomWorld) {
  function focusEditor (line 60) | async function focusEditor(world: CustomWorld) {

FILE: e2e/src/steps/page/editor-meta.steps.ts
  function waitForPageWorkspaceReady (line 12) | async function waitForPageWorkspaceReady(world: CustomWorld): Promise<vo...
  function clickNewPageButton (line 49) | async function clickNewPageButton(world: CustomWorld): Promise<void> {

FILE: e2e/src/steps/page/page-crud.steps.ts
  function inputPageName (line 20) | async function inputPageName(
  function waitForPageWorkspaceReady (line 96) | async function waitForPageWorkspaceReady(world: CustomWorld): Promise<vo...
  function clickNewPageButton (line 136) | async function clickNewPageButton(world: CustomWorld): Promise<void> {

FILE: e2e/src/support/seedTestUser.ts
  constant TEST_USER (line 4) | const TEST_USER = {
  function hashPassword (line 16) | async function hashPassword(password: string): Promise<string> {
  function seedTestUser (line 24) | async function seedTestUser(): Promise<void> {
  function cleanupTestUser (line 98) | async function cleanupTestUser(): Promise<void> {

FILE: e2e/src/support/webServer.ts
  constant LOCK_FILE (line 10) | const LOCK_FILE = resolve(__dirname, '../../.server-starting.lock');
  function stopWebServer (line 12) | async function stopWebServer(): Promise<void> {
  type WebServerOptions (line 27) | interface WebServerOptions {
  function isServerRunning (line 35) | async function isServerRunning(port: number, timeoutMs = 2000): Promise<...
  function startWebServer (line 67) | async function startWebServer(options: WebServerOptions): Promise<void> {

FILE: e2e/src/support/world.ts
  constant WAIT_TIMEOUT (line 9) | const WAIT_TIMEOUT = 13_000;
  type TestContext (line 11) | interface TestContext {
  class CustomWorld (line 19) | class CustomWorld extends World {
    method modKey (line 28) | get modKey(): 'Meta' | 'Control' {
    method constructor (line 32) | constructor(options: IWorldOptions) {
    method context (line 41) | get context(): TestContext {
    method init (line 45) | async init() {
    method cleanup (line 78) | async cleanup() {
    method takeScreenshot (line 84) | async takeScreenshot(name: string): Promise<Buffer> {

FILE: packages/agent-manager-runtime/src/AgentManagerRuntime.ts
  class AgentManagerRuntime (line 61) | class AgentManagerRuntime {
    method constructor (line 69) | constructor(services: AgentManagerRuntimeServices) {
    method createAgent (line 79) | async createAgent(params: CreateAgentParams): Promise<BuiltinToolResul...
    method updateAgentConfig (line 114) | async updateAgentConfig(
    method deleteAgent (line 228) | async deleteAgent(agentId: string): Promise<BuiltinToolResult> {
    method searchAgents (line 250) | async searchAgents(params: SearchAgentParams): Promise<BuiltinToolResu...
    method getAvailableModels (line 332) | async getAvailableModels(params: GetAvailableModelsParams): Promise<Bu...
    method updatePrompt (line 381) | async updatePrompt(agentId: string, params: UpdatePromptParams): Promi...
    method streamUpdatePrompt (line 419) | private async streamUpdatePrompt(agentId: string, prompt: string): Pro...
    method searchMarketTools (line 443) | async searchMarketTools(params: SearchMarketToolsParams): Promise<Buil...
    method installPlugin (line 499) | async installPlugin(agentId: string, params: InstallPluginParams): Pro...
    method handleKlavisInstall (line 597) | private async handleKlavisInstall(
    method handleLobehubSkillInstall (line 724) | private async handleLobehubSkillInstall(
    method handleMarketPluginInstall (line 805) | private async handleMarketPluginInstall(
    method enablePluginForAgent (line 858) | private async enablePluginForAgent(agentId: string, pluginId: string):...
    method openOAuthWindowAndWait (line 869) | private openOAuthWindowAndWait(
    method openLobehubSkillOAuthWindowAndWait (line 942) | private openLobehubSkillOAuthWindowAndWait(
    method handleError (line 1029) | private handleError(error: unknown, context: string): BuiltinToolResult {
    method handleErrorWithState (line 1042) | private handleErrorWithState<T extends object>(

FILE: packages/agent-manager-runtime/src/types.ts
  type IAgentService (line 10) | interface IAgentService {
  type IDiscoverService (line 30) | interface IDiscoverService {
  type AgentManagerRuntimeServices (line 60) | interface AgentManagerRuntimeServices {
  type CreateAgentParams (line 73) | interface CreateAgentParams {
  type CreateAgentState (line 87) | interface CreateAgentState {
  type UpdateAgentConfigParams (line 94) | interface UpdateAgentConfigParams {
  type UpdateAgentConfigState (line 103) | interface UpdateAgentConfigState {
  type DeleteAgentState (line 121) | interface DeleteAgentState {
  type SearchAgentSource (line 128) | type SearchAgentSource = 'user' | 'market' | 'all';
  type SearchAgentParams (line 130) | interface SearchAgentParams {
  type AgentSearchItem (line 137) | interface AgentSearchItem {
  type SearchAgentState (line 146) | interface SearchAgentState {
  type GetAvailableModelsParams (line 155) | interface GetAvailableModelsParams {
  type AvailableModel (line 159) | interface AvailableModel {
  type AvailableProvider (line 171) | interface AvailableProvider {
  type GetAvailableModelsState (line 177) | interface GetAvailableModelsState {
  type UpdatePromptParams (line 183) | interface UpdatePromptParams {
  type UpdatePromptState (line 188) | interface UpdatePromptState {
  type SearchMarketToolsParams (line 196) | interface SearchMarketToolsParams {
  type MarketToolItem (line 202) | interface MarketToolItem {
  type SearchMarketToolsState (line 214) | interface SearchMarketToolsState {
  type InstallPluginParams (line 220) | interface InstallPluginParams {
  type InstallPluginState (line 225) | interface InstallPluginState {

FILE: packages/agent-runtime/examples/tools-calling.ts
  class SimpleAgent (line 58) | class SimpleAgent implements Agent {
    method getToolDefinitions (line 87) | private getToolDefinitions() {
    method runner (line 115) | async runner(context: AgentRuntimeContext, state: AgentState) {
  function main (line 234) | async function main() {

FILE: packages/agent-runtime/src/agents/GeneralChatAgent.ts
  class GeneralChatAgent (line 42) | class GeneralChatAgent implements Agent {
    method constructor (line 45) | constructor(config: GeneralAgentConfig) {
    method getToolInterventionConfig (line 52) | private getToolInterventionConfig(
    method isDynamicInterventionConfig (line 68) | private isDynamicInterventionConfig(
    method matchesAlwaysPolicy (line 76) | private matchesAlwaysPolicy(
    method resolveDynamicPolicy (line 101) | private resolveDynamicPolicy(
    method checkInterventionNeeded (line 125) | private async checkInterventionNeeded(
    method extractAbortInfo (line 265) | private extractAbortInfo(context: AgentRuntimeContext, state: AgentSta...
    method findExistingSummary (line 311) | private findExistingSummary(messages: any[]): string | undefined {
    method toLLMCall (line 330) | private toLLMCall(payload: GeneralAgentCallLLMInstructionPayload): Age...
    method handleAbort (line 360) | private handleAbort(
    method runner (line 385) | async runner(

FILE: packages/agent-runtime/src/audit/createSecurityBlacklistAudit.ts
  constant SECURITY_BLACKLIST_AUDIT_TYPE (line 9) | const SECURITY_BLACKLIST_AUDIT_TYPE = 'securityBlacklist';

FILE: packages/agent-runtime/src/audit/defaultSecurityBlacklist.ts
  constant DEFAULT_SECURITY_BLACKLIST (line 13) | const DEFAULT_SECURITY_BLACKLIST: SecurityBlacklistConfig = [

FILE: packages/agent-runtime/src/core/InterventionChecker.ts
  type SecurityCheckResult (line 14) | interface SecurityCheckResult {
  class InterventionChecker (line 30) | class InterventionChecker {
    method checkSecurityBlacklist (line 39) | static checkSecurityBlacklist(
    method shouldIntervene (line 61) | static shouldIntervene(params: ShouldInterveneParams): HumanInterventi...
    method matchesSecurityRule (line 103) | private static matchesSecurityRule(
    method matchesRule (line 133) | private static matchesRule(rule: HumanInterventionRule, toolArgs: Reco...
    method matchesArgument (line 160) | private static matchesArgument(matcher: ArgumentMatcher, value: any): ...
    method matchPattern (line 197) | private static matchPattern(pattern: string, value: string): boolean {
    method generateToolKey (line 222) | static generateToolKey(identifier: string, apiName: string, argsHash?:...
    method hashArguments (line 233) | static hashArguments(args: Record<string, any>): string {

FILE: packages/agent-runtime/src/core/UsageCounter.ts
  class UsageCounter (line 10) | class UsageCounter {
    method createDefaultUsage (line 14) | private static createDefaultUsage(): Usage {
    method createDefaultCost (line 42) | private static createDefaultCost(): Cost {
    method mergeModelUsage (line 66) | private static mergeModelUsage(
    method accumulateLLM (line 122) | static accumulateLLM(params: {
    method accumulateTool (line 188) | static accumulateTool(params: {

FILE: packages/agent-runtime/src/core/__tests__/runtime.test.ts
  class MockAgent (line 18) | class MockAgent implements Agent {
    method runner (line 23) | async runner(context: AgentRuntimeContext, state: AgentState) {
  function createTestContext (line 49) | function createTestContext(
  class CostTrackingAgent (line 800) | class CostTrackingAgent implements Agent {
    method runner (line 805) | async runner(context: AgentRuntimeContext, state: AgentState) {
    method calculateUsage (line 820) | calculateUsage(
    method calculateCost (line 838) | calculateCost(context: CostCalculationContext): Cost {
    method runner (line 874) | async runner(context: AgentRuntimeContext, state: AgentState) {
    method calculateUsage (line 878) | calculateUsage(operationType: string, operationResult: any, previousUs...
    method calculateCost (line 884) | calculateCost(context: CostCalculationContext): Cost {
    method runner (line 923) | async runner(context: AgentRuntimeContext, state: AgentState) {
    method calculateCost (line 927) | calculateCost(context: CostCalculationContext): Cost {
  class CostTrackingAgent (line 873) | class CostTrackingAgent implements Agent {
    method runner (line 805) | async runner(context: AgentRuntimeContext, state: AgentState) {
    method calculateUsage (line 820) | calculateUsage(
    method calculateCost (line 838) | calculateCost(context: CostCalculationContext): Cost {
    method runner (line 874) | async runner(context: AgentRuntimeContext, state: AgentState) {
    method calculateUsage (line 878) | calculateUsage(operationType: string, operationResult: any, previousUs...
    method calculateCost (line 884) | calculateCost(context: CostCalculationContext): Cost {
    method runner (line 923) | async runner(context: AgentRuntimeContext, state: AgentState) {
    method calculateCost (line 927) | calculateCost(context: CostCalculationContext): Cost {
  class CostTrackingAgent (line 922) | class CostTrackingAgent implements Agent {
    method runner (line 805) | async runner(context: AgentRuntimeContext, state: AgentState) {
    method calculateUsage (line 820) | calculateUsage(
    method calculateCost (line 838) | calculateCost(context: CostCalculationContext): Cost {
    method runner (line 874) | async runner(context: AgentRuntimeContext, state: AgentState) {
    method calculateUsage (line 878) | calculateUsage(operationType: string, operationResult: any, previousUs...
    method calculateCost (line 884) | calculateCost(context: CostCalculationContext): Cost {
    method runner (line 923) | async runner(context: AgentRuntimeContext, state: AgentState) {
    method calculateCost (line 927) | calculateCost(context: CostCalculationContext): Cost {
  class BatchToolAgent (line 1115) | class BatchToolAgent implements Agent {
    method runner (line 1122) | async runner(context: AgentRuntimeContext, _state: AgentState) {
    method runner (line 1756) | async runner(context: AgentRuntimeContext, _state: AgentState) {
  class ArrayReturnAgent (line 1177) | class ArrayReturnAgent implements Agent {
    method runner (line 1183) | async runner(context: AgentRuntimeContext, _state: AgentState) {
  class BlockingAgent (line 1242) | class BlockingAgent implements Agent {
    method runner (line 1247) | async runner(context: AgentRuntimeContext, _state: AgentState) {
  class UsageTrackingAgent (line 1310) | class UsageTrackingAgent implements Agent {
    method calculateUsage (line 1316) | calculateUsage(
    method runner (line 1334) | async runner(context: AgentRuntimeContext, _state: AgentState) {
  class MultiRoundBatchAgent (line 1402) | class MultiRoundBatchAgent implements Agent {
    method runner (line 1416) | async runner(context: AgentRuntimeContext, state: AgentState) {
  class TwoBatchAgent (line 1557) | class TwoBatchAgent implements Agent {
    method runner (line 1565) | async runner(context: AgentRuntimeContext, _state: AgentState) {
  class BatchToolAgent (line 1750) | class BatchToolAgent implements Agent {
    method runner (line 1122) | async runner(context: AgentRuntimeContext, _state: AgentState) {
    method runner (line 1756) | async runner(context: AgentRuntimeContext, _state: AgentState) {
  class WarnCostAgent (line 1887) | class WarnCostAgent implements Agent {
    method runner (line 1888) | async runner(context: AgentRuntimeContext, state: AgentState) {
    method calculateCost (line 1892) | calculateCost(context: CostCalculationContext): Cost {
  class ToolCostAgent (line 1934) | class ToolCostAgent implements Agent {
    method runner (line 1939) | async runner(context: AgentRuntimeContext, state: AgentState) {
    method calculateCost (line 1958) | calculateCost(context: CostCalculationContext): Cost {
  class BatchCostAgent (line 1994) | class BatchCostAgent implements Agent {
    method calculateCost (line 2000) | calculateCost(context: CostCalculationContext): Cost {
    method runner (line 2021) | async runner(context: AgentRuntimeContext, _state: AgentState) {
  class DetailedUsageAgent (line 2065) | class DetailedUsageAgent implements Agent {
    method calculateUsage (line 2071) | calculateUsage(
    method runner (line 2101) | async runner(context: AgentRuntimeContext, _state: AgentState) {

FILE: packages/agent-runtime/src/core/runtime.ts
  class AgentRuntime (line 25) | class AgentRuntime {
    method constructor (line 30) | constructor(
    method getContext (line 56) | getContext() {
    method getAbortController (line 67) | getAbortController(): AbortController | undefined {
    method step (line 79) | async step(
    method approveToolCall (line 234) | async approveToolCall(
    method interrupt (line 255) | interrupt(
    method resume (line 295) | async resume(
    method createDefaultUsage (line 347) | static createDefaultUsage(): Usage {
    method createDefaultCost (line 372) | static createDefaultCost(): Cost {
    method createInitialState (line 396) | static createInitialState(
    method createCallLLMExecutor (line 419) | private createCallLLMExecutor(): InstructionExecutor {
    method createCallToolExecutor (line 504) | private createCallToolExecutor(): InstructionExecutor {
    method createHumanApproveExecutor (line 574) | private createHumanApproveExecutor(): InstructionExecutor {
    method createHumanPromptExecutor (line 599) | private createHumanPromptExecutor(): InstructionExecutor {
    method createHumanSelectExecutor (line 625) | private createHumanSelectExecutor(): InstructionExecutor {
    method createFinishExecutor (line 653) | private createFinishExecutor(): InstructionExecutor {
    method executeToolsBatch (line 678) | private async executeToolsBatch(
    method mergeToolResults (line 710) | private mergeToolResults(
    method handleCostLimitExceeded (line 799) | private handleCostLimitExceeded(state: AgentState): {
    method createSessionContext (line 865) | private createSessionContext(state: AgentState) {
    method createInitialContext (line 877) | private createInitialContext(state: AgentState): AgentRuntimeContext {
    method createErrorResult (line 901) | private createErrorResult(

FILE: packages/agent-runtime/src/groupOrchestration/GroupOrchestrationRuntime.ts
  class GroupOrchestrationRuntime (line 26) | class GroupOrchestrationRuntime {
    method constructor (line 31) | constructor(
    method step (line 47) | async step(state: AgentState, result: ExecutorResult): Promise<GroupOr...
    method run (line 109) | async run(initialState: AgentState, groupId?: string): Promise<AgentSt...
    method getContext (line 135) | getContext(): Record<string, unknown> | undefined {
    method getAbortController (line 145) | getAbortController(): AbortController | undefined {
    method createInitialState (line 155) | static createInitialState(

FILE: packages/agent-runtime/src/groupOrchestration/GroupOrchestrationSupervisor.ts
  type GroupOrchestrationSupervisorConfig (line 16) | interface GroupOrchestrationSupervisorConfig {
  class GroupOrchestrationSupervisor (line 38) | class GroupOrchestrationSupervisor implements IGroupOrchestrationSupervi...
    method constructor (line 42) | constructor(private config: GroupOrchestrationSupervisorConfig) {}
    method decide (line 48) | async decide(result: ExecutorResult, _state: AgentState): Promise<Supe...

FILE: packages/agent-runtime/src/groupOrchestration/types.ts
  type SupervisorInstructionCallSupervisor (line 9) | interface SupervisorInstructionCallSupervisor {
  type SupervisorInstructionCallAgent (line 21) | interface SupervisorInstructionCallAgent {
  type SupervisorInstructionParallelCallAgents (line 32) | interface SupervisorInstructionParallelCallAgents {
  type SupervisorInstructionExecAsyncTask (line 53) | interface SupervisorInstructionExecAsyncTask {
  type SupervisorInstructionExecClientAsyncTask (line 69) | interface SupervisorInstructionExecClientAsyncTask {
  type SupervisorInstructionBatchExecAsyncTasks (line 84) | interface SupervisorInstructionBatchExecAsyncTasks {
  type SupervisorInstructionDelegate (line 101) | interface SupervisorInstructionDelegate {
  type SupervisorInstructionFinish (line 112) | interface SupervisorInstructionFinish {
  type SupervisorInstruction (line 120) | type SupervisorInstruction =
  type ExecutorResultSupervisorDecided (line 136) | interface ExecutorResultSupervisorDecided {
  type ExecutorResultAgentSpoke (line 164) | interface ExecutorResultAgentSpoke {
  type ExecutorResultAgentsBroadcasted (line 178) | interface ExecutorResultAgentsBroadcasted {
  type ExecutorResultTaskCompleted (line 192) | interface ExecutorResultTaskCompleted {
  type ExecutorResultTasksCompleted (line 208) | interface ExecutorResultTasksCompleted {
  type ExecutorResultDelegated (line 223) | interface ExecutorResultDelegated {
  type ExecutorResultInit (line 234) | interface ExecutorResultInit {
  type ExecutorResult (line 244) | type ExecutorResult =
  type GroupOrchestrationExecutorOutput (line 259) | interface GroupOrchestrationExecutorOutput {
  type GroupOrchestrationExecutor (line 279) | type GroupOrchestrationExecutor = (
  type IGroupOrchestrationSupervisor (line 288) | interface IGroupOrchestrationSupervisor {
  type GroupOrchestrationRuntimeConfig (line 301) | interface GroupOrchestrationRuntimeConfig {
  type GroupOrchestrationEventSupervisorFinished (line 315) | interface GroupOrchestrationEventSupervisorFinished {
  type GroupOrchestrationEventAgentSpoke (line 319) | interface GroupOrchestrationEventAgentSpoke {
  type GroupOrchestrationEventAgentsBroadcasted (line 324) | interface GroupOrchestrationEventAgentsBroadcasted {
  type GroupOrchestrationEventMaxRoundsExceeded (line 329) | interface GroupOrchestrationEventMaxRoundsExceeded {
  type GroupOrchestrationEventDone (line 333) | interface GroupOrchestrationEventDone {
  type GroupOrchestrationEvent (line 338) | type GroupOrchestrationEvent =
  type GroupOrchestrationPhase (line 351) | type GroupOrchestrationPhase =
  type GroupOrchestrationContext (line 363) | interface GroupOrchestrationContext {
  type GroupOrchestrationInstruction (line 372) | type GroupOrchestrationInstruction = SupervisorInstruction;
  type GroupOrchestrationExecutorResult (line 377) | interface GroupOrchestrationExecutorResult {

FILE: packages/agent-runtime/src/types/event.ts
  type AgentEventInit (line 5) | interface AgentEventInit {
  type AgentEventLlmStart (line 9) | interface AgentEventLlmStart {
  type AgentEventLlmStream (line 14) | interface AgentEventLlmStream {
  type AgentEventLlmResult (line 19) | interface AgentEventLlmResult {
  type AgentEventToolPending (line 24) | interface AgentEventToolPending {
  type AgentEventToolResult (line 29) | interface AgentEventToolResult {
  type AgentEventHumanApproveRequired (line 35) | interface AgentEventHumanApproveRequired {
  type AgentEventHumanPromptRequired (line 41) | interface AgentEventHumanPromptRequired {
  type AgentEventHumanSelectRequired (line 48) | interface AgentEventHumanSelectRequired {
  type FinishReason (line 60) | type FinishReason =
  type AgentEventDone (line 73) | interface AgentEventDone {
  type AgentEventError (line 80) | interface AgentEventError {
  type AgentEventInterrupted (line 85) | interface AgentEventInterrupted {
  type AgentEventResumed (line 94) | interface AgentEventResumed {
  type AgentEventCompressionComplete (line 102) | interface AgentEventCompressionComplete {
  type AgentEventCompressionError (line 108) | interface AgentEventCompressionError {
  type AgentEvent (line 116) | type AgentEvent =

FILE: packages/agent-runtime/src/types/generalAgent.ts
  type GeneralAgentCallLLMInstructionPayload (line 8) | interface GeneralAgentCallLLMInstructionPayload {
  type GeneralAgentCallLLMResultPayload (line 19) | interface GeneralAgentCallLLMResultPayload {
  type GeneralAgentCallingToolInstructionPayload (line 26) | interface GeneralAgentCallingToolInstructionPayload {
  type GeneralAgentCallToolResultPayload (line 32) | interface GeneralAgentCallToolResultPayload {
  type GeneralAgentCallToolsBatchInstructionPayload (line 43) | interface GeneralAgentCallToolsBatchInstructionPayload {
  type GeneralAgentCallToolsBatchResultPayload (line 48) | interface GeneralAgentCallToolsBatchResultPayload {
  type GeneralAgentHumanAbortPayload (line 54) | interface GeneralAgentHumanAbortPayload {
  type GeneralAgentConfig (line 70) | interface GeneralAgentConfig {
  type GeneralAgentCompressionResultPayload (line 115) | interface GeneralAgentCompressionResultPayload {

FILE: packages/agent-runtime/src/types/instruction.ts
  type AgentRuntimeContext (line 15) | interface AgentRuntimeContext {
  type Agent (line 69) | interface Agent {
  type CallLLMPayload (line 115) | interface CallLLMPayload {
  type CallingToolPayload (line 124) | interface CallingToolPayload {
  type HumanAbortPayload (line 132) | interface HumanAbortPayload {
  type AgentInstructionCallLlm (line 148) | interface AgentInstructionCallLlm {
  type AgentInstructionCallTool (line 153) | interface AgentInstructionCallTool {
  type AgentInstructionCallToolsBatch (line 161) | interface AgentInstructionCallToolsBatch {
  type AgentInstructionRequestHumanPrompt (line 169) | interface AgentInstructionRequestHumanPrompt {
  type AgentInstructionRequestHumanSelect (line 176) | interface AgentInstructionRequestHumanSelect {
  type AgentInstructionRequestHumanApprove (line 185) | interface AgentInstructionRequestHumanApprove {
  type AgentInstructionFinish (line 192) | interface AgentInstructionFinish {
  type AgentInstructionResolveAbortedTools (line 198) | interface AgentInstructionResolveAbortedTools {
  type AgentInstructionCompressContext (line 214) | interface AgentInstructionCompressContext {
  type ExecTaskItem (line 229) | interface ExecTaskItem {
  type AgentInstructionExecTask (line 257) | interface AgentInstructionExecTask {
  type AgentInstructionExecTasks (line 270) | interface AgentInstructionExecTasks {
  type AgentInstructionExecClientTask (line 284) | interface AgentInstructionExecClientTask {
  type AgentInstructionExecClientTasks (line 298) | interface AgentInstructionExecClientTasks {
  type TaskResultPayload (line 311) | interface TaskResultPayload {
  type TasksBatchResultPayload (line 332) | interface TasksBatchResultPayload {
  type AgentInstruction (line 354) | type AgentInstruction =

FILE: packages/agent-runtime/src/types/runtime.ts
  type InstructionExecutor (line 5) | type InstructionExecutor = (
  type RuntimeConfig (line 20) | interface RuntimeConfig {

FILE: packages/agent-runtime/src/types/state.ts
  type AgentState (line 19) | interface AgentState {
  type ToolsCalling (line 148) | interface ToolsCalling {
  type ToolRegistry (line 160) | type ToolRegistry = Record<string, (args: any) => Promise<any>>;

FILE: packages/agent-runtime/src/types/usage.ts
  type TokenUsage (line 6) | interface TokenUsage {
  type Usage (line 18) | interface Usage {
  type Cost (line 64) | interface Cost {
  type CostLimit (line 114) | interface CostLimit {
  type CostCalculationContext (line 130) | interface CostCalculationContext {

FILE: packages/agent-runtime/src/utils/messageSelectors.ts
  type MessageVisitorOptions (line 6) | interface MessageVisitorOptions {

FILE: packages/agent-runtime/src/utils/stepContextComputer.ts
  type ComputeStepContextParams (line 7) | interface ComputeStepContextParams {

FILE: packages/agent-runtime/src/utils/tokenCounter.ts
  type TokenCountOptions (line 6) | interface TokenCountOptions {
  constant DEFAULT_MAX_CONTEXT (line 14) | const DEFAULT_MAX_CONTEXT = 128_000;
  constant DEFAULT_THRESHOLD_RATIO (line 17) | const DEFAULT_THRESHOLD_RATIO = 0.5;
  type TokenCountMessage (line 22) | interface TokenCountMessage {
  function estimateTokens (line 37) | function estimateTokens(content: string | unknown): number {
  function calculateMessageTokens (line 54) | function calculateMessageTokens(messages: TokenCountMessage[]): number {
  function getCompressionThreshold (line 74) | function getCompressionThreshold(options: TokenCountOptions = {}): number {
  type CompressionCheckResult (line 83) | interface CompressionCheckResult {
  function shouldCompress (line 98) | function shouldCompress(

FILE: packages/agent-templates/src/template.ts
  type DocumentTemplate (line 7) | interface DocumentTemplate {
  class DocumentTemplateManager (line 30) | class DocumentTemplateManager {
    method validate (line 34) | static validate(template: DocumentTemplate): boolean {
    method generateFilename (line 45) | static generateFilename(title: string): string {
    method createBasic (line 59) | static createBasic(
    method merge (line 86) | static merge(templates: DocumentTemplate[]): string {
    method extractVariables (line 97) | static extractVariables(content: string): string[] {
    method replaceVariables (line 114) | static replaceVariables(content: string, variables: Record<string, str...
    method createWithVariables (line 128) | static createWithVariables(
    method clone (line 155) | static clone(

FILE: packages/agent-templates/src/templates/claw/agent.ts
  constant AGENT_DOCUMENT (line 10) | const AGENT_DOCUMENT: DocumentTemplate = {

FILE: packages/agent-templates/src/templates/claw/bootstrap.ts
  constant BOOTSTRAP_DOCUMENT (line 12) | const BOOTSTRAP_DOCUMENT: DocumentTemplate = {

FILE: packages/agent-templates/src/templates/claw/identity.ts
  constant IDENTITY_DOCUMENT (line 10) | const IDENTITY_DOCUMENT: DocumentTemplate = {

FILE: packages/agent-templates/src/templates/claw/index.ts
  constant CLAW_POLICY (line 10) | const CLAW_POLICY: DocumentTemplateSet = {

FILE: packages/agent-templates/src/templates/claw/soul.ts
  constant SOUL_DOCUMENT (line 11) | const SOUL_DOCUMENT: DocumentTemplate = {

FILE: packages/agent-templates/src/templates/index.ts
  type DocumentTemplateSet (line 12) | interface DocumentTemplateSet {
  constant CUSTOM_TEMPLATE_SET (line 24) | const CUSTOM_TEMPLATE_SET: DocumentTemplateSet = {
  constant DOCUMENT_TEMPLATES (line 38) | const DOCUMENT_TEMPLATES: Record<string, DocumentTemplateSet> = {
  function getDocumentTemplate (line 46) | function getDocumentTemplate(templateId: string): DocumentTemplateSet {
  function getAllDocumentTemplates (line 53) | function getAllDocumentTemplates(): DocumentTemplateSet[] {
  function getDocumentTemplatesByTags (line 60) | function getDocumentTemplatesByTags(tags: string[]): DocumentTemplateSet...
  type DocumentPolicy (line 67) | type DocumentPolicy = DocumentTemplateSet;
  constant CUSTOM_POLICY (line 68) | const CUSTOM_POLICY = CUSTOM_TEMPLATE_SET;
  constant DOCUMENT_POLICIES (line 69) | const DOCUMENT_POLICIES = DOCUMENT_TEMPLATES;

FILE: packages/agent-templates/src/types.ts
  type DocumentLoadPosition (line 4) | enum DocumentLoadPosition {
  type DocumentLoadRule (line 20) | enum DocumentLoadRule {
  type DocumentLoadFormat (line 30) | enum DocumentLoadFormat {
  type PolicyLoad (line 38) | enum PolicyLoad {
  type AgentAccess (line 51) | enum AgentAccess {
  type DocumentLoadRules (line 62) | interface DocumentLoadRules {
  type AgentDocumentPolicy (line 79) | interface AgentDocumentPolicy {

FILE: packages/agent-tracing/src/cli/inspect.ts
  function fetchSnapshotFromUrl (line 17) | async function fetchSnapshotFromUrl(url: string): Promise<ExecutionSnaps...
  function isUrl (line 25) | function isUrl(input: string): boolean {
  function findStep (line 29) | function findStep(snapshot: ExecutionSnapshot, stepIndex: number): StepS...
  function getSystemRole (line 40) | function getSystemRole(step: StepSnapshot): string | undefined {
  function getEnvContent (line 52) | function getEnvContent(step: StepSnapshot): string | undefined {
  function registerInspectCommand (line 62) | function registerInspectCommand(program: Command) {

FILE: packages/agent-tracing/src/cli/list.ts
  function registerListCommand (line 6) | function registerListCommand(program: Command) {

FILE: packages/agent-tracing/src/cli/partial.ts
  function registerPartialCommand (line 5) | function registerPartialCommand(program: Command) {

FILE: packages/agent-tracing/src/recorder/index.ts
  function appendStepToPartial (line 8) | async function appendStepToPartial(
  function finalizeSnapshot (line 32) | async function finalizeSnapshot(

FILE: packages/agent-tracing/src/store/file-store.ts
  constant DEFAULT_DIR (line 7) | const DEFAULT_DIR = '.agent-tracing';
  constant PARTIAL_DIR (line 8) | const PARTIAL_DIR = '_partial';
  class FileSnapshotStore (line 10) | class FileSnapshotStore implements ISnapshotStore {
    method constructor (line 13) | constructor(rootDir?: string) {
    method save (line 19) | async save(snapshot: ExecutionSnapshot): Promise<void> {
    method get (line 39) | async get(traceId: string): Promise<ExecutionSnapshot | null> {
    method list (line 57) | async list(options?: { limit?: number }): Promise<SnapshotSummary[]> {
    method getLatest (line 77) | async getLatest(): Promise<ExecutionSnapshot | null> {
    method partialDir (line 95) | private partialDir(): string {
    method partialPath (line 99) | private partialPath(operationId: string): string {
    method listPartials (line 104) | async listPartials(): Promise<string[]> {
    method getPartial (line 116) | async getPartial(idOrFilename: string): Promise<Partial<ExecutionSnaps...
    method loadPartial (line 134) | async loadPartial(operationId: string): Promise<Partial<ExecutionSnaps...
    method savePartial (line 143) | async savePartial(operationId: string, partial: Partial<ExecutionSnaps...
    method removePartial (line 148) | async removePartial(operationId: string): Promise<void> {
    method listFiles (line 158) | private async listFiles(): Promise<string[]> {
  function partialToSnapshot (line 171) | function partialToSnapshot(partial: Partial<ExecutionSnapshot>): Executi...
  function toSummary (line 189) | function toSummary(snapshot: ExecutionSnapshot): SnapshotSummary {

FILE: packages/agent-tracing/src/store/types.ts
  type ISnapshotStore (line 3) | interface ISnapshotStore {

FILE: packages/agent-tracing/src/types.ts
  type ExecutionSnapshot (line 1) | interface ExecutionSnapshot {
  type StepSnapshot (line 27) | interface StepSnapshot {
  type SnapshotSummary (line 110) | interface SnapshotSummary {

FILE: packages/agent-tracing/src/utils/reconstruct.test.ts
  function makeStep (line 12) | function makeStep(overrides: Partial<StepSnapshot>): StepSnapshot {

FILE: packages/agent-tracing/src/utils/reconstruct.ts
  function isIncrementalFormat (line 6) | function isIncrementalFormat(snapshot: ExecutionSnapshot): boolean {
  function reconstructMessages (line 14) | function reconstructMessages(
  function reconstructToolsetBaseline (line 47) | function reconstructToolsetBaseline(steps: StepSnapshot[]): any | undefi...
  function reconstructActivatedStepTools (line 55) | function reconstructActivatedStepTools(
  function expandSnapshot (line 76) | function expandSnapshot(snapshot: ExecutionSnapshot): ExecutionSnapshot {

FILE: packages/agent-tracing/src/viewer/index.ts
  function resolveStepMessages (line 9) | function resolveStepMessages(
  function formatMs (line 35) | function formatMs(ms: number): string {
  function formatTokens (line 40) | function formatTokens(n: number): string {
  function formatCost (line 45) | function formatCost(cost: number): string {
  type CacheStats (line 51) | interface CacheStats {
  function getStepCacheStats (line 58) | function getStepCacheStats(step: StepSnapshot): CacheStats | null {
  function formatCacheRate (line 72) | function formatCacheRate(rate: number): string {
  function truncate (line 78) | function truncate(s: string, maxLen: number): string {
  function padEnd (line 84) | function padEnd(s: string, len: number): string {
  constant STRUCTURAL_TAGS (line 90) | const STRUCTURAL_TAGS = new Set([
  function extractTagName (line 111) | function extractTagName(tag: string): string {
  function formatXmlContent (line 122) | function formatXmlContent(text: string): string {
  function renderSnapshot (line 174) | function renderSnapshot(snapshot: ExecutionSnapshot): string {
  function renderLlmStep (line 242) | function renderLlmStep(lines: string[], step: StepSnapshot, prefix: stri...
  function renderMessageList (line 276) | function renderMessageList(lines: string[], messages: any[], maxContentL...
  function renderToolStep (line 301) | function renderToolStep(lines: string[], step: StepSnapshot, prefix: str...
  function renderSummaryTable (line 314) | function renderSummaryTable(summaries: SnapshotSummary[]): string {
  function renderMessageDetail (line 348) | function renderMessageDetail(
  function renderSystemRole (line 406) | function renderSystemRole(step: StepSnapshot): string {
  function renderEnvContext (line 438) | function renderEnvContext(step: StepSnapshot): string {
  function renderPayloadTools (line 464) | function renderPayloadTools(step: StepSnapshot): string {
  function renderPayload (line 520) | function renderPayload(step: StepSnapshot): string {
  function renderMemory (line 655) | function renderMemory(step: StepSnapshot): string {
  function renderDiff (line 742) | function renderDiff(
  function renderStepDetail (line 785) | function renderStepDetail(

FILE: packages/builtin-agent-onboarding/src/client/QuestionRenderer.tsx
  type FormValue (line 13) | type FormValue = string | string[];
  type DefaultModelConfig (line 15) | interface DefaultModelConfig {
  type QuestionRendererRenderEmojiPickerProps (line 20) | interface QuestionRendererRenderEmojiPickerProps {
  type QuestionRendererRenderModelSelectProps (line 25) | interface QuestionRendererRenderModelSelectProps {
  type QuestionRendererProps (line 30) | interface QuestionRendererProps {

FILE: packages/builtin-agent-onboarding/src/systemRole.ts
  type CreateSystemRoleOptions (line 119) | interface CreateSystemRoleOptions {

FILE: packages/builtin-agents/src/agents/agent-builder/index.ts
  constant AGENT_BUILDER (line 12) | const AGENT_BUILDER: BuiltinAgentDefinition = {

FILE: packages/builtin-agents/src/agents/group-agent-builder/index.ts
  constant GROUP_AGENT_BUILDER (line 12) | const GROUP_AGENT_BUILDER: BuiltinAgentDefinition = {

FILE: packages/builtin-agents/src/agents/group-supervisor/index.ts
  constant GROUP_SUPERVISOR (line 31) | const GROUP_SUPERVISOR: BuiltinAgentDefinition = {

FILE: packages/builtin-agents/src/agents/group-supervisor/type.ts
  type GroupSupervisorContext (line 4) | interface GroupSupervisorContext {

FILE: packages/builtin-agents/src/agents/inbox/index.ts
  constant INBOX (line 12) | const INBOX: BuiltinAgentDefinition = {

FILE: packages/builtin-agents/src/agents/page-agent/index.ts
  constant PAGE_AGENT (line 11) | const PAGE_AGENT: BuiltinAgentDefinition = {

FILE: packages/builtin-agents/src/agents/web-onboarding/index.ts
  constant WEB_ONBOARDING (line 12) | const WEB_ONBOARDING: BuiltinAgentDefinition = {

FILE: packages/builtin-agents/src/index.ts
  constant BUILTIN_AGENTS (line 23) | const BUILTIN_AGENTS: Record<BuiltinAgentSlug, BuiltinAgentDefinition> = {

FILE: packages/builtin-agents/src/types.ts
  constant BUILTIN_AGENT_SLUGS (line 8) | const BUILTIN_AGENT_SLUGS = {
  type BuiltinAgentSlug (line 17) | type BuiltinAgentSlug = (typeof BUILTIN_AGENT_SLUGS)[keyof typeof BUILTI...
  type BuiltinAgentPersistConfig (line 22) | interface BuiltinAgentPersistConfig {
  type BuiltinAgentRuntimeResult (line 34) | interface BuiltinAgentRuntimeResult {
  type RuntimeContext (line 48) | interface RuntimeContext {
  type BuiltinAgentRuntimeConfig (line 76) | type BuiltinAgentRuntimeConfig =
  type BuiltinAgentDefinition (line 83) | interface BuiltinAgentDefinition {

FILE: packages/builtin-skills/src/lobehub/index.ts
  constant LOBEHUB_AVATAR (line 25) | const LOBEHUB_AVATAR =

FILE: packages/builtin-tool-activator/src/ExecutionRuntime/index.ts
  type ToolManifestInfo (line 5) | interface ToolManifestInfo {
  type ActivatorRuntimeService (line 13) | interface ActivatorRuntimeService {
  type ActivatorExecutionRuntimeOptions (line 20) | interface ActivatorExecutionRuntimeOptions {
  class ActivatorExecutionRuntime (line 24) | class ActivatorExecutionRuntime {
    method constructor (line 27) | constructor(options: ActivatorExecutionRuntimeOptions) {
    method activateSkill (line 31) | async activateSkill(args: ActivateSkillParams): Promise<BuiltinServerR...
    method activateTools (line 42) | async activateTools(args: ActivateToolsParams): Promise<BuiltinServerR...

FILE: packages/builtin-tool-activator/src/executor/index.ts
  class ActivatorExecutor (line 11) | class ActivatorExecutor extends BaseExecutor<typeof ActivatorApiName> {
    method constructor (line 17) | constructor(runtime: ActivatorExecutionRuntime) {

FILE: packages/builtin-tool-activator/src/types.ts
  type ActivateToolsParams (line 8) | interface ActivateToolsParams {
  type ActivatedToolInfo (line 12) | interface ActivatedToolInfo {
  type ActivateToolsState (line 19) | interface ActivateToolsState {
  type ActivateSkillParams (line 25) | interface ActivateSkillParams {
  type ActivateSkillState (line 29) | interface ActivateSkillState {

FILE: packages/builtin-tool-agent-builder/src/client/Render/SearchMarketTools.tsx
  type ToolItemProps (line 15) | interface ToolItemProps {

FILE: packages/builtin-tool-agent-builder/src/client/Render/components/ConfigCard.tsx
  type ConfigCardProps (line 4) | interface ConfigCardProps {

FILE: packages/builtin-tool-agent-builder/src/client/Render/components/ConfigDiffView.tsx
  type ConfigDiffViewProps (line 5) | interface ConfigDiffViewProps {
  function formatValue (line 11) | function formatValue(value: unknown): string {

FILE: packages/builtin-tool-agent-builder/src/executor.ts
  class AgentBuilderExecutor (line 28) | class AgentBuilderExecutor extends BaseExecutor<typeof AgentBuilderApiNa...

FILE: packages/builtin-tool-agent-builder/src/types.ts
  type AgentBuilderApiNameType (line 26) | type AgentBuilderApiNameType =
  type UpdateAgentConfigParams (line 31) | interface UpdateAgentConfigParams {
  type GetAvailableModelsParams (line 55) | interface GetAvailableModelsParams {
  type UpdatePromptParams (line 62) | interface UpdatePromptParams {
  type UpdateConfigState (line 75) | interface UpdateConfigState {
  type AvailableModel (line 93) | interface AvailableModel {
  type AvailableProvider (line 105) | interface AvailableProvider {
  type GetAvailableModelsState (line 111) | interface GetAvailableModelsState {
  type UpdatePromptState (line 115) | interface UpdatePromptState {
  type SearchMarketToolsParams (line 123) | interface SearchMarketToolsParams {
  type MarketToolItem (line 138) | interface MarketToolItem {
  type SearchMarketToolsState (line 150) | interface SearchMarketToolsState {
  type InstallPluginParams (line 161) | interface InstallPluginParams {
  type InstallPluginState (line 172) | interface InstallPluginState {

FILE: packages/builtin-tool-agent-documents/src/ExecutionRuntime/index.ts
  type AgentDocumentRecord (line 16) | interface AgentDocumentRecord {
  type AgentDocumentOperationContext (line 23) | interface AgentDocumentOperationContext {
  type AgentDocumentsRuntimeService (line 27) | interface AgentDocumentsRuntimeService {
  class AgentDocumentsExecutionRuntime (line 80) | class AgentDocumentsExecutionRuntime {
    method constructor (line 81) | constructor(private service: AgentDocumentsRuntimeService) {}
    method resolveAgentId (line 83) | private resolveAgentId(context?: AgentDocumentOperationContext) {
    method listDocuments (line 88) | async listDocuments(
    method readDocumentByFilename (line 114) | async readDocumentByFilename(
    method upsertDocumentByFilename (line 136) | async upsertDocumentByFilename(
    method createDocument (line 158) | async createDocument(
    method readDocument (line 180) | async readDocument(
    method editDocument (line 202) | async editDocument(
    method removeDocument (line 224) | async removeDocument(
    method renameDocument (line 246) | async renameDocument(
    method copyDocument (line 268) | async copyDocument(
    method updateLoadRule (line 290) | async updateLoadRule(

FILE: packages/builtin-tool-agent-documents/src/client/Inspector/AgentDocumentsInspector/index.tsx
  type AgentDocumentsArgs (line 21) | type AgentDocumentsArgs =

FILE: packages/builtin-tool-agent-documents/src/executor/index.ts
  class AgentDocumentsExecutor (line 19) | class AgentDocumentsExecutor extends BaseExecutor<typeof AgentDocumentsA...
    method constructor (line 25) | constructor(runtime: AgentDocumentsExecutionRuntime) {

FILE: packages/builtin-tool-agent-documents/src/types.ts
  type CreateDocumentArgs (line 16) | interface CreateDocumentArgs {
  type CreateDocumentState (line 21) | interface CreateDocumentState {
  type ReadDocumentArgs (line 25) | interface ReadDocumentArgs {
  type ReadDocumentState (line 29) | interface ReadDocumentState {
  type EditDocumentArgs (line 35) | interface EditDocumentArgs {
  type EditDocumentState (line 40) | interface EditDocumentState {
  type RemoveDocumentArgs (line 45) | interface RemoveDocumentArgs {
  type RemoveDocumentState (line 49) | interface RemoveDocumentState {
  type RenameDocumentArgs (line 54) | interface RenameDocumentArgs {
  type RenameDocumentState (line 59) | interface RenameDocumentState {
  type CopyDocumentArgs (line 65) | interface CopyDocumentArgs {
  type CopyDocumentState (line 70) | interface CopyDocumentState {
  type AgentDocumentLoadRule (line 75) | interface AgentDocumentLoadRule {
  type UpdateLoadRuleArgs (line 89) | interface UpdateLoadRuleArgs {
  type UpdateLoadRuleState (line 94) | interface UpdateLoadRuleState {
  type LoadRuleScope (line 99) | interface LoadRuleScope {
  type AgentDocumentReference (line 105) | interface AgentDocumentReference {
  type ListDocumentsArgs (line 110) | interface ListDocumentsArgs {}
  type ListDocumentsState (line 112) | interface ListDocumentsState {
  type ReadDocumentByFilenameArgs (line 116) | interface ReadDocumentByFilenameArgs {
  type ReadDocumentByFilenameState (line 120) | interface ReadDocumentByFilenameState {
  type UpsertDocumentByFilenameArgs (line 127) | interface UpsertDocumentByFilenameArgs {
  type UpsertDocumentByFilenameState (line 132) | interface UpsertDocumentByFilenameState {

FILE: packages/builtin-tool-agent-management/src/executor.ts
  class AgentManagementExecutor (line 39) | class AgentManagementExecutor extends BaseExecutor<typeof AgentManagemen...

FILE: packages/builtin-tool-agent-management/src/types.ts
  type AgentManagementApiNameType (line 49) | type AgentManagementApiNameType =
  type CreateAgentParams (line 54) | interface CreateAgentParams {
  type CreateAgentState (line 101) | interface CreateAgentState {
  type UpdateAgentParams (line 122) | interface UpdateAgentParams {
  type UpdateAgentState (line 137) | interface UpdateAgentState {
  type DeleteAgentParams (line 166) | interface DeleteAgentParams {
  type DeleteAgentState (line 173) | interface DeleteAgentState {
  type SearchAgentSource (line 186) | type SearchAgentSource = 'user' | 'market' | 'all';
  type SearchAgentParams (line 188) | interface SearchAgentParams {
  type AgentSearchItem (line 207) | interface AgentSearchItem {
  type SearchAgentState (line 234) | interface SearchAgentState {
  type CallAgentParams (line 255) | interface CallAgentParams {
  type CallAgentState (line 283) | interface CallAgentState {

FILE: packages/builtin-tool-brief/src/types.ts
  type BriefApiNameType (line 9) | type BriefApiNameType = (typeof BriefApiName)[keyof typeof BriefApiName];

FILE: packages/builtin-tool-calculator/src/ExecutionRuntime/index.ts
  class CalculatorExecutionRuntime (line 33) | class CalculatorExecutionRuntime {
    method calculate (line 34) | async calculate(args: CalculateParams): Promise<BuiltinServerRuntimeOu...
    method evaluate (line 59) | async evaluate(args: EvaluateParams): Promise<BuiltinServerRuntimeOutp...
    method sort (line 85) | async sort(args: SortParams): Promise<BuiltinServerRuntimeOutput> {
    method base (line 115) | async base(args: BaseParams): Promise<BuiltinServerRuntimeOutput> {
    method solve (line 142) | async solve(args: SolveParams): Promise<BuiltinServerRuntimeOutput> {
    method differentiate (line 167) | async differentiate(args: DifferentiateParams): Promise<BuiltinServerR...
    method execute (line 192) | async execute(args: ExecuteParams): Promise<BuiltinServerRuntimeOutput> {
    method defintegrate (line 216) | async defintegrate(args: DefintegrateParams): Promise<BuiltinServerRun...
    method integrate (line 243) | async integrate(args: IntegrateParams): Promise<BuiltinServerRuntimeOu...
    method limit (line 268) | async limit(args: LimitParams): Promise<BuiltinServerRuntimeOutput> {

FILE: packages/builtin-tool-calculator/src/executor/index.ts
  class CalculatorExecutor (line 30) | class CalculatorExecutor
    method evaluateMathExpression (line 40) | private evaluateMathExpression(expression: string, variables: Record<s...
    method formatResult (line 60) | private formatResult(result: any, precision?: number): string {
    method convertNumber (line 83) | private convertNumber(number: string | number, fromBase: number, toBas...
    method getApiNames (line 585) | getApiNames(): string[] {
    method hasApi (line 589) | hasApi(apiName: string): boolean {

FILE: packages/builtin-tool-calculator/src/types.ts
  type CalculatorApiNameType (line 16) | type CalculatorApiNameType = (typeof CalculatorApiName)[keyof typeof Cal...
  type CalculateParams (line 19) | interface CalculateParams {
  type CalculateState (line 24) | interface CalculateState {
  type EvaluateParams (line 31) | interface EvaluateParams {
  type EvaluateState (line 37) | interface EvaluateState {
  type BaseParams (line 45) | interface BaseParams {
  type BaseState (line 51) | interface BaseState {
  type SortParams (line 60) | interface SortParams {
  type SortState (line 67) | interface SortState {
  type SolveParams (line 80) | interface SolveParams {
  type SolveState (line 85) | interface SolveState {
  type DifferentiateParams (line 92) | interface DifferentiateParams {
  type DifferentiateState (line 97) | interface DifferentiateState {
  type IntegrateParams (line 104) | interface IntegrateParams {
  type IntegrateState (line 109) | interface IntegrateState {
  type DefintegrateParams (line 116) | interface DefintegrateParams {
  type DefintegrateState (line 123) | interface DefintegrateState {
  type LimitParams (line 132) | interface LimitParams {
  type LimitState (line 138) | interface LimitState {
  type ExecuteParams (line 146) | interface ExecuteParams {
  type ExecuteState (line 150) | interface ExecuteState {

FILE: packages/builtin-tool-cloud-sandbox/src/ExecutionRuntime/index.ts
  class CloudSandboxExecutionRuntime (line 55) | class CloudSandboxExecutionRuntime {
    method constructor (line 58) | constructor(sandboxService: ISandboxService) {
    method listLocalFiles (line 64) | async listLocalFiles(args: ListLocalFilesParams): Promise<BuiltinServe...
    method readLocalFile (line 97) | async readLocalFile(args: ReadLocalFileParams): Promise<BuiltinServerR...
    method writeLocalFile (line 143) | async writeLocalFile(args: WriteLocalFileParams): Promise<BuiltinServe...
    method editLocalFile (line 179) | async editLocalFile(args: EditLocalFileParams): Promise<BuiltinServerR...
    method searchLocalFiles (line 219) | async searchLocalFiles(args: SearchLocalFilesParams): Promise<BuiltinS...
    method moveLocalFiles (line 254) | async moveLocalFiles(args: MoveLocalFilesParams): Promise<BuiltinServe...
    method renameLocalFile (line 289) | async renameLocalFile(args: RenameLocalFileParams): Promise<BuiltinSer...
    method executeCode (line 332) | async executeCode(args: ExecuteCodeParams): Promise<BuiltinServerRunti...
    method runCommand (line 370) | async runCommand(args: RunCommandParams): Promise<BuiltinServerRuntime...
    method getCommandOutput (line 406) | async getCommandOutput(args: GetCommandOutputParams): Promise<BuiltinS...
    method killCommand (line 439) | async killCommand(args: KillCommandParams): Promise<BuiltinServerRunti...
    method grepContent (line 476) | async grepContent(args: GrepContentParams): Promise<BuiltinServerRunti...
    method globLocalFiles (line 508) | async globLocalFiles(args: GlobLocalFilesParams): Promise<BuiltinServe...
    method exportFile (line 558) | async exportFile(args: ExportFileParams): Promise<BuiltinServerRuntime...
    method callTool (line 603) | private async callTool(
    method handleError (line 617) | private handleError(error: unknown): BuiltinServerRuntimeOutput {

FILE: packages/builtin-tool-cloud-sandbox/src/client/Inspector/EditLocalFile/index.tsx
  type EditLocalFileParams (line 23) | interface EditLocalFileParams {

FILE: packages/builtin-tool-cloud-sandbox/src/client/Inspector/ExecuteCode/index.tsx
  type ExecuteCodeParams (line 20) | interface ExecuteCodeParams {

FILE: packages/builtin-tool-cloud-sandbox/src/client/Inspector/GlobLocalFiles/index.tsx
  type GlobFilesParams (line 20) | interface GlobFilesParams {

FILE: packages/builtin-tool-cloud-sandbox/src/client/Inspector/GrepContent/index.tsx
  type GrepContentParams (line 13) | interface GrepContentParams {

FILE: packages/builtin-tool-cloud-sandbox/src/client/Inspector/ListLocalFiles/index.tsx
  type ListLocalFilesParams (line 14) | interface ListLocalFilesParams {

FILE: packages/builtin-tool-cloud-sandbox/src/client/Inspector/ReadLocalFile/index.tsx
  type ReadLocalFileParams (line 21) | interface ReadLocalFileParams {

FILE: packages/builtin-tool-cloud-sandbox/src/client/Inspector/RunCommand/index.tsx
  type RunCommandParams (line 20) | interface RunCommandParams {

FILE: packages/builtin-tool-cloud-sandbox/src/client/Inspector/SearchLocalFiles/index.tsx
  type SearchLocalFilesParams (line 13) | interface SearchLocalFilesParams {

FILE: packages/builtin-tool-cloud-sandbox/src/client/Inspector/WriteLocalFile/index.tsx
  type WriteLocalFileParams (line 15) | interface WriteLocalFileParams {

FILE: packages/builtin-tool-cloud-sandbox/src/client/Intervention/EditLocalFile/index.tsx
  type EditLocalFileParams (line 7) | interface EditLocalFileParams {

FILE: packages/builtin-tool-cloud-sandbox/src/client/Intervention/ExecuteCode/index.tsx
  type ExecuteCodeParams (line 7) | interface ExecuteCodeParams {

FILE: packages/builtin-tool-cloud-sandbox/src/client/Intervention/MoveLocalFiles/index.tsx
  type MoveLocalFilesParams (line 8) | interface MoveLocalFilesParams {

FILE: packages/builtin-tool-cloud-sandbox/src/client/Intervention/RunCommand/index.tsx
  type RunCommandParams (line 7) | interface RunCommandParams {

FILE: packages/builtin-tool-cloud-sandbox/src/client/Intervention/WriteFile/index.tsx
  type WriteLocalFileParams (line 7) | interface WriteLocalFileParams {

FILE: packages/builtin-tool-cloud-sandbox/src/client/Render/EditLocalFile/index.tsx
  type EditLocalFileParams (line 34) | interface EditLocalFileParams {

FILE: packages/builtin-tool-cloud-sandbox/src/client/Render/ExecuteCode/index.tsx
  type ExecuteCodeParams (line 17) | interface ExecuteCodeParams {

FILE: packages/builtin-tool-cloud-sandbox/src/client/Render/ExportFile/index.tsx
  type ExportFileParams (line 21) | interface ExportFileParams {

FILE: packages/builtin-tool-cloud-sandbox/src/client/Render/ListFiles/index.tsx
  type ListLocalFilesParams (line 34) | interface ListLocalFilesParams {

FILE: packages/builtin-tool-cloud-sandbox/src/client/Render/MoveLocalFiles/index.tsx
  type MoveLocalFilesParams (line 33) | interface MoveLocalFilesParams {

FILE: packages/builtin-tool-cloud-sandbox/src/client/Render/ReadLocalFile/index.tsx
  type ReadLocalFileParams (line 17) | interface ReadLocalFileParams {

FILE: packages/builtin-tool-cloud-sandbox/src/client/Render/RunCommand/index.tsx
  type RunCommandParams (line 17) | interface RunCommandParams {

FILE: packages/builtin-tool-cloud-sandbox/src/client/Render/SearchFiles/index.tsx
  type SearchLocalFilesParams (line 37) | interface SearchLocalFilesParams {

FILE: packages/builtin-tool-cloud-sandbox/src/client/Render/WriteFile/index.tsx
  type WriteLocalFileParams (line 9) | interface WriteLocalFileParams {

FILE: packages/builtin-tool-cloud-sandbox/src/client/Streaming/ExecuteCode/index.tsx
  type ExecuteCodeParams (line 7) | interface ExecuteCodeParams {

FILE: packages/builtin-tool-cloud-sandbox/src/client/components/FilePathDisplay.tsx
  type FilePathDisplayProps (line 18) | interface FilePathDisplayProps {

FILE: packages/builtin-tool-cloud-sandbox/src/executor/index.ts
  class ClientSandboxService (line 35) | class ClientSandboxService implements ISandboxService {
    method constructor (line 39) | constructor(topicId: string) {
    method callTool (line 49) | async callTool(toolName: string, params: Record<string, any>): Promise...
    method exportAndUploadFile (line 56) | async exportAndUploadFile(path: string, filename: string): Promise<San...
  class CloudSandboxExecutor (line 68) | class CloudSandboxExecutor extends BaseExecutor<typeof CloudSandboxApiNa...
    method getRuntime (line 75) | private getRuntime(ctx: BuiltinToolContext): CloudSandboxExecutionRunt...
    method toBuiltinResult (line 227) | private toBuiltinResult(output: {

FILE: packages/builtin-tool-cloud-sandbox/src/types/api.ts
  type CloudSandboxApiNameType (line 21) | type CloudSandboxApiNameType =

FILE: packages/builtin-tool-cloud-sandbox/src/types/params.ts
  type ListLocalFilesParams (line 3) | interface ListLocalFilesParams {
  type ReadLocalFileParams (line 7) | interface ReadLocalFileParams {
  type WriteLocalFileParams (line 13) | interface WriteLocalFileParams {
  type EditLocalFileParams (line 19) | interface EditLocalFileParams {
  type SearchLocalFilesParams (line 26) | interface SearchLocalFilesParams {
  type MoveLocalFilesParams (line 34) | interface MoveLocalFilesParams {
  type RenameLocalFileParams (line 41) | interface RenameLocalFileParams {
  type GlobLocalFilesParams (line 46) | interface GlobLocalFilesParams {
  type ExportFileParams (line 51) | interface ExportFileParams {
  type ExecuteCodeParams (line 57) | interface ExecuteCodeParams {
  type RunCommandParams (line 64) | interface RunCommandParams {
  type GetCommandOutputParams (line 70) | interface GetCommandOutputParams {
  type KillCommandParams (line 74) | interface KillCommandParams {
  type GrepContentParams (line 80) | interface GrepContentParams {

FILE: packages/builtin-tool-cloud-sandbox/src/types/service.ts
  type SandboxCallToolResult (line 6) | interface SandboxCallToolResult {
  type SandboxExportFileResult (line 16) | interface SandboxExportFileResult {
  type ISandboxService (line 34) | interface ISandboxService {

FILE: packages/builtin-tool-cloud-sandbox/src/types/state.ts
  type ListLocalFilesState (line 3) | interface ListLocalFilesState {
  type ReadLocalFileState (line 12) | interface ReadLocalFileState {
  type WriteLocalFileState (line 20) | interface WriteLocalFileState {
  type EditLocalFileState (line 26) | interface EditLocalFileState {
  type SearchLocalFilesState (line 34) | interface SearchLocalFilesState {
  type MoveLocalFilesState (line 45) | interface MoveLocalFilesState {
  type RenameLocalFileState (line 56) | interface RenameLocalFileState {
  type GlobFilesState (line 63) | interface GlobFilesState {
  type ExportFileState (line 69) | interface ExportFileState {
  type GrepContentState (line 86) | interface GrepContentState {
  type ExecuteCodeState (line 98) | interface ExecuteCodeState {
  type RunCommandState (line 115) | interface RunCommandState {
  type GetCommandOutputState (line 125) | interface GetCommandOutputState {
  type KillCommandState (line 132) | interface KillCommandState {
  type SessionInfo (line 140) | interface SessionInfo {

FILE: packages/builtin-tool-creds/src/ExecutionRuntime/index.ts
  type ICredsService (line 15) | interface ICredsService {
  class CredsExecutionRuntime (line 96) | class CredsExecutionRuntime {
    method constructor (line 100) | constructor(credsService: ICredsService, context: { topicId?: string; ...
    method initiateOAuthConnect (line 110) | async initiateOAuthConnect(
    method getPlaintextCred (line 176) | async getPlaintextCred(args: GetPlaintextCredParams): Promise<BuiltinS...
    method injectCredsToSandbox (line 249) | async injectCredsToSandbox(
    method saveCreds (line 330) | async saveCreds(args: SaveCredsParams): Promise<BuiltinServerRuntimeOu...

FILE: packages/builtin-tool-creds/src/executor/index.ts
  class CredsExecutor (line 21) | class CredsExecutor extends BaseExecutor<typeof CredsApiName> {

FILE: packages/builtin-tool-creds/src/helpers.ts
  type CredSummary (line 6) | interface CredSummary {
  type UserCredsContext (line 16) | interface UserCredsContext {
  type CredRequirement (line 92) | interface CredRequirement {

FILE: packages/builtin-tool-creds/src/types.ts
  type CredsApiNameType (line 29) | type CredsApiNameType = (typeof CredsApiName)[keyof typeof CredsApiName];
  type GetPlaintextCredParams (line 33) | interface GetPlaintextCredParams {
  type InitiateOAuthConnectParams (line 44) | interface InitiateOAuthConnectParams {
  type InitiateOAuthConnectState (line 51) | interface InitiateOAuthConnectState {
  type GetPlaintextCredState (line 70) | interface GetPlaintextCredState {
  type InjectCredsToSandboxParams (line 81) | interface InjectCredsToSandboxParams {
  type InjectCredsToSandboxState (line 88) | interface InjectCredsToSandboxState {
  type SaveCredsParams (line 103) | interface SaveCredsParams {
  type SaveCredsState (line 126) | interface SaveCredsState {
  type CredSummaryForContext (line 143) | interface CredSummaryForContext {

FILE: packages/builtin-tool-group-agent-builder/src/ExecutionRuntime/index.ts
  class GroupAgentBuilderExecutionRuntime (line 38) | class GroupAgentBuilderExecutionRuntime {
    method getAgentInfo (line 44) | async getAgentInfo(
    method searchAgent (line 76) | async searchAgent(args: SearchAgentParams): Promise<BuiltinToolResult> {
    method createGroup (line 124) | async createGroup(args: CreateGroupParams): Promise<BuiltinToolResult> {
    method createAgent (line 204) | async createAgent(groupId: string, args: CreateAgentParams): Promise<B...
    method batchCreateAgents (line 260) | async batchCreateAgents(
    method inviteAgent (line 319) | async inviteAgent(groupId: string, args: InviteAgentParams): Promise<B...
    method removeAgent (line 385) | async removeAgent(groupId: string, args: RemoveAgentParams): Promise<B...
    method updateAgentPrompt (line 459) | async updateAgentPrompt(
    method updateGroup (line 505) | async updateGroup(args: UpdateGroupParams): Promise<BuiltinToolResult> {
    method updateGroupPrompt (line 616) | async updateGroupPrompt(args: UpdateGroupPromptParams): Promise<Builti...
    method streamUpdateGroupPrompt (line 675) | private async streamUpdateGroupPrompt(groupId: string, prompt: string)...
    method resolveGroupTarget (line 681) | private async resolveGroupTarget(groupId?: string) {
    method handleError (line 706) | private handleError(error: unknown, context: string): BuiltinToolResult {
    method handleErrorWithState (line 719) | private handleErrorWithState<T extends object>(

FILE: packages/builtin-tool-group-agent-builder/src/client/Inspector/GetAgentInfo/index.tsx
  type GetAgentInfoState (line 13) | interface GetAgentInfoState {

FILE: packages/builtin-tool-group-agent-builder/src/client/Render/BatchCreateAgents.tsx
  type AgentItemProps (line 53) | interface AgentItemProps {

FILE: packages/builtin-tool-group-agent-builder/src/executor.ts
  class GroupAgentBuilderExecutor (line 41) | class GroupAgentBuilderExecutor extends BaseExecutor<typeof GroupAgentBu...

FILE: packages/builtin-tool-group-agent-builder/src/types.ts
  type GroupAgentBuilderApiNameType (line 42) | type GroupAgentBuilderApiNameType =
  type GetAgentInfoParams (line 47) | interface GetAgentInfoParams {
  type SearchAgentParams (line 54) | interface SearchAgentParams {
  type CreateAgentParams (line 65) | interface CreateAgentParams {
  type CreateGroupParams (line 89) | interface CreateGroupParams {
  type CreateGroupState (line 161) | interface CreateGroupState {
  type InviteAgentParams (line 180) | interface InviteAgentParams {
  type RemoveAgentParams (line 187) | interface RemoveAgentParams {
  type UpdateAgentPromptParams (line 194) | interface UpdateAgentPromptParams {
  type UpdateAgentPromptState (line 205) | interface UpdateAgentPromptState {
  type UpdateAgentConfigWithIdParams (line 227) | interface UpdateAgentConfigWithIdParams extends UpdateAgentConfigParams {
  type UpdateGroupParams (line 237) | interface UpdateGroupParams {
  type UpdateGroupState (line 261) | interface UpdateGroupState {
  type UpdateGroupPromptParams (line 281) | interface UpdateGroupPromptParams {
  type UpdateGroupPromptState (line 296) | interface UpdateGroupPromptState {
  type BatchCreateAgentsParams (line 311) | interface BatchCreateAgentsParams {
  type BatchCreateAgentsState (line 318) | interface BatchCreateAgentsState {
  type SearchAgentResult (line 339) | interface SearchAgentResult {
  type SearchAgentState (line 346) | interface SearchAgentState {
  type CreateAgentState (line 352) | interface CreateAgentState {
  type InviteAgentState (line 367) | interface InviteAgentState {
  type RemoveAgentState (line 386) | interface RemoveAgentState {

FILE: packages/builtin-tool-group-management/src/client/Intervention/ExecuteTask.tsx
  constant DEFAULT_TIMEOUT (line 65) | const DEFAULT_TIMEOUT = 1_800_000;

FILE: packages/builtin-tool-group-management/src/client/Intervention/ExecuteTasks.tsx
  constant DEFAULT_TIMEOUT (line 68) | const DEFAULT_TIMEOUT = 1_800_000;
  type TaskEditorProps (line 70) | interface TaskEditorProps {

FILE: packages/builtin-tool-group-management/src/executor.ts
  class GroupManagementExecutor (line 26) | class GroupManagementExecutor extends BaseExecutor<typeof GroupManagemen...

FILE: packages/builtin-tool-group-management/src/types.ts
  type GroupManagementApiNameType (line 36) | type GroupManagementApiNameType =
  type SpeakParams (line 41) | interface SpeakParams {
  type BroadcastParams (line 53) | interface BroadcastParams {
  type DelegateParams (line 65) | interface DelegateParams {
  type ExecuteTaskParams (line 72) | interface ExecuteTaskParams {
  type TaskItem (line 92) | interface TaskItem {
  type ExecuteTasksParams (line 103) | interface ExecuteTasksParams {
  type InterruptParams (line 113) | interface InterruptParams {
  type SummarizeParams (line 119) | interface SummarizeParams {
  type WorkflowStep (line 126) | interface WorkflowStep {
  type CreateWorkflowParams (line 132) | interface CreateWorkflowParams {
  type VoteOption (line 138) | interface VoteOption {
  type VoteParams (line 144) | interface VoteParams {
  type VoteResult (line 153) | interface VoteResult {
  type ExecuteTaskStatus (line 161) | type ExecuteTaskStatus =
  type ExecuteTaskState (line 169) | interface ExecuteTaskState {
  type InterruptState (line 182) | interface InterruptState {

FILE: packages/builtin-tool-gtd/src/client/Render/CreatePlan/PlanCard.tsx
  constant MAX_CONTENT_HEIGHT (line 12) | const MAX_CONTENT_HEIGHT = 100;
  type PlanCardProps (line 36) | interface PlanCardProps {

FILE: packages/builtin-tool-gtd/src/client/Render/CreatePlan/index.tsx
  type CreatePlanRenderProps (line 9) | type CreatePlanRenderProps = Pick<

FILE: packages/builtin-tool-gtd/src/client/Render/TodoList/index.tsx
  type TodoListRenderState (line 11) | interface TodoListRenderState {
  type ReadOnlyTodoItemProps (line 44) | interface ReadOnlyTodoItemProps {
  type TodoListUIProps (line 88) | interface TodoListUIProps {

FILE: packages/builtin-tool-gtd/src/client/components/SortableTodoList/AddItemRow.tsx
  type AddItemRowProps (line 23) | interface AddItemRowProps {

FILE: packages/builtin-tool-gtd/src/client/components/SortableTodoList/SortableItem.tsx
  type SortableItemProps (line 8) | interface SortableItemProps {

FILE: packages/builtin-tool-gtd/src/client/components/SortableTodoList/TodoItemRow.tsx
  type TodoItemRowProps (line 48) | interface TodoItemRowProps {

FILE: packages/builtin-tool-gtd/src/client/components/SortableTodoList/TodoList.tsx
  type TodoListProps (line 11) | interface TodoListProps {

FILE: packages/builtin-tool-gtd/src/client/components/SortableTodoList/index.tsx
  type SortableTodoListProps (line 12) | interface SortableTodoListProps {

FILE: packages/builtin-tool-gtd/src/client/components/SortableTodoList/store/actions.ts
  type SetState (line 17) | type SetState = (
  type GetState (line 20) | type GetState = () => TodoListStore;

FILE: packages/builtin-tool-gtd/src/client/components/SortableTodoList/store/initialState.ts
  constant AUTO_SAVE_DELAY (line 12) | const AUTO_SAVE_DELAY = 3000;
  constant AUTO_SAVE_MAX_WAIT (line 13) | const AUTO_SAVE_MAX_WAIT = 10_000;

FILE: packages/builtin-tool-gtd/src/client/components/SortableTodoList/store/types.ts
  type TodoListItem (line 5) | interface TodoListItem extends TodoItem {
  type TodoListState (line 9) | interface TodoListState {
  type TodoListActions (line 18) | interface TodoListActions {
  type TodoListStore (line 40) | type TodoListStore = TodoListState & TodoListActions;
  type StoreInternals (line 43) | interface StoreInternals {
  constant ADD_ITEM_ID (line 49) | const ADD_ITEM_ID = '__add_item__';

FILE: packages/builtin-tool-gtd/src/executor/index.ts
  class GTDExecutor (line 62) | class GTDExecutor extends BaseExecutor<typeof GTDApiNameEnum> {

FILE: packages/builtin-tool-gtd/src/types.ts
  type GTDApiNameType (line 38) | type GTDApiNameType = (typeof GTDApiName)[keyof typeof GTDApiName];
  type TodoStatus (line 43) | type TodoStatus = 'todo' | 'processing' | 'completed';
  type TodoItem (line 45) | interface TodoItem {
  type TodoList (line 59) | interface TodoList {
  type TodoState (line 65) | type TodoState = TodoList;
  type CreateTodosParams (line 74) | interface CreateTodosParams {
  type TodoUpdateOperationType (line 84) | type TodoUpdateOperationType = 'add' | 'update' | 'remove' | 'complete' ...
  type TodoUpdateOperation (line 89) | interface TodoUpdateOperation {
  type UpdateTodosParams (line 106) | interface UpdateTodosParams {
  type ClearTodosParams (line 114) | interface ClearTodosParams {
  type CreateTodosState (line 121) | interface CreateTodosState {
  type UpdateTodosState (line 128) | interface UpdateTodosState {
  type CompleteTodosState (line 135) | interface CompleteTodosState {
  type RemoveTodosState (line 142) | interface RemoveTodosState {
  type ClearTodosState (line 149) | interface ClearTodosState {
  type CreatePlanParams (line 169) | interface CreatePlanParams {
  type UpdatePlanParams (line 178) | interface UpdatePlanParams {
  type Plan (line 202) | interface Plan {
  type CreatePlanState (line 221) | interface CreatePlanState {
  type UpdatePlanState (line 226) | interface UpdatePlanState {
  type ExecTaskItem (line 236) | interface ExecTaskItem {
  type ExecTaskParams (line 259) | interface ExecTaskParams {
  type ExecTasksParams (line 282) | interface ExecTasksParams {
  type ExecTaskState (line 290) | interface ExecTaskState {
  type ExecTasksState (line 302) | interface ExecTasksState {
  type ExecClientTaskState (line 314) | interface ExecClientTaskState {
  type ExecClientTasksState (line 326) | interface ExecClientTasksState {

FILE: packages/builtin-tool-knowledge-base/src/ExecutionRuntime/index.ts
  type FileContentResult (line 11) | interface FileContentResult {
  type RagService (line 21) | interface RagService {
  class KnowledgeBaseExecutionRuntime (line 29) | class KnowledgeBaseExecutionRuntime {
    method constructor (line 32) | constructor(ragService: RagService) {
    method searchKnowledgeBase (line 39) | async searchKnowledgeBase(
    method readKnowledge (line 81) | async readKnowledge(

FILE: packages/builtin-tool-knowledge-base/src/client/Render/ReadKnowledge/FileCard.tsx
  type FileCardProps (line 65) | interface FileCardProps {

FILE: packages/builtin-tool-knowledge-base/src/client/Render/SearchKnowledgeBase/Item/index.tsx
  type FileItemProps (line 11) | interface FileItemProps extends FileSearchResult {

FILE: packages/builtin-tool-knowledge-base/src/executor/index.ts
  class KnowledgeBaseExecutor (line 23) | class KnowledgeBaseExecutor extends BaseExecutor<{

FILE: packages/builtin-tool-knowledge-base/src/types.ts
  type SearchKnowledgeBaseArgs (line 10) | interface SearchKnowledgeBaseArgs {
  type SearchKnowledgeBaseState (line 14) | interface SearchKnowledgeBaseState {
  type ReadKnowledgeArgs (line 20) | interface ReadKnowledgeArgs {
  type FileContentDetail (line 24) | interface FileContentDetail {
  type ReadKnowledgeState (line 33) | interface ReadKnowledgeState {

FILE: packages/builtin-tool-local-system/src/client/Inspector/RunCommand/index.tsx
  type RunCommandState (line 19) | interface RunCommandState {

FILE: packages/builtin-tool-local-system/src/client/Intervention/MoveLocalFiles/MoveFileItem.tsx
  type MoveFileItemProps (line 30) | interface MoveFileItemProps {

FILE: packages/builtin-tool-local-system/src/client/Intervention/OutOfScopeWarning.tsx
  type OutOfScopeWarningProps (line 12) | interface OutOfScopeWarningProps {

FILE: packages/builtin-tool-local-system/src/client/Render/ListFiles/Result.tsx
  type SearchFilesProps (line 11) | interface SearchFilesProps {

FILE: packages/builtin-tool-local-system/src/client/Render/MoveLocalFiles/MoveFileItem.tsx
  type MoveFileItemProps (line 30) | interface MoveFileItemProps {

FILE: packages/builtin-tool-local-system/src/client/Render/ReadLocalFile/ReadFileView.tsx
  type ReadFileViewProps (line 92) | interface ReadFileViewProps extends LocalReadFileResult {

FILE: packages/builtin-tool-local-system/src/client/Render/ReadLocalFile/index.tsx
  type ReadFileQueryProps (line 12) | interface ReadFileQueryProps {

FILE: packages/builtin-tool-local-system/src/client/Render/RunCommand/index.tsx
  type RunCommandState (line 38) | interface RunCommandState {

FILE: packages/builtin-tool-local-system/src/client/Render/SearchFiles/Result.tsx
  type SearchFilesProps (line 11) | interface SearchFilesProps {

FILE: packages/builtin-tool-local-system/src/client/Render/SearchFiles/SearchQuery/SearchView.tsx
  type SearchBarProps (line 24) | interface SearchBarProps {

FILE: packages/builtin-tool-local-system/src/client/Render/SearchFiles/SearchQuery/index.tsx
  type SearchQueryViewProps (line 10) | interface SearchQueryViewProps {

FILE: packages/builtin-tool-local-system/src/client/Streaming/RunCommand/index.tsx
  type RunCommandParams (line 7) | interface RunCommandParams {

FILE: packages/builtin-tool-local-system/src/client/components/FileItem.tsx
  type FileItemProps (line 50) | interface FileItemProps extends LocalFileItem {

FILE: packages/builtin-tool-local-system/src/client/components/FilePathDisplay.tsx
  type FilePathDisplayProps (line 21) | interface FilePathDisplayProps {

FILE: packages/builtin-tool-local-system/src/executor/index.ts
  class LocalSystemExecutor (line 85) | class LocalSystemExecutor extends BaseExecutor<typeof LocalSystemApiEnum> {

FILE: packages/builtin-tool-local-system/src/interventionAudit.ts
  constant SAFE_PATH_PREFIXES (line 5) | const SAFE_PATH_PREFIXES = ['/tmp', '/var/tmp'] as const;
  type SafePathAuditParams (line 7) | interface SafePathAuditParams {
  type PathScopeAuditOptions (line 12) | interface PathScopeAuditOptions {

FILE: packages/builtin-tool-local-system/src/types.ts
  type FileResult (line 29) | interface FileResult {
  type LocalFileSearchState (line 44) | interface LocalFileSearchState {
  type LocalFileListState (line 52) | interface LocalFileListState {
  type LocalReadFileState (line 57) | interface LocalReadFileState {
  type LocalReadFilesState (line 61) | interface LocalReadFilesState {
  type LocalMoveFilesState (line 65) | interface LocalMoveFilesState {
  type LocalRenameFileState (line 72) | interface LocalRenameFileState {
  type RunCommandState (line 79) | interface RunCommandState {
  type GetCommandOutputState (line 84) | interface GetCommandOutputState {
  type KillCommandState (line 89) | interface KillCommandState {
  type GrepContentState (line 94) | interface GrepContentState {
  type GlobFilesState (line 101) | interface GlobFilesState {
  type EditLocalFileState (line 108) | interface EditLocalFileState {

FILE: packages/builtin-tool-local-system/src/utils/path.ts
  constant ALWAYS_ALLOWED_PATHS (line 50) | const ALWAYS_ALLOWED_PATHS = ['/tmp'];

FILE: packages/builtin-tool-memory/promptfoo/evals/preferences/tool-call/basic/buildMessages.ts
  type PromptVars (line 1) | interface PromptVars {

FILE: packages/builtin-tool-memory/promptfoo/evals/preferences/tool-call/basic/prompt.ts
  function generatePrompt (line 4) | function generatePrompt({ vars }: { vars: PromptVars }) {

FILE: packages/builtin-tool-memory/promptfoo/evals/preferences/tool-call/basic/tests/cases.ts
  type PromptfooAssert (line 1) | type PromptfooAssert =
  type PromptfooTestCase (line 5) | interface PromptfooTestCase {

FILE: packages/builtin-tool-memory/scripts/generate-tool-call.ts
  constant OUTPUT_DIR (line 9) | const OUTPUT_DIR = join(process.cwd(), 'promptfoo/tool-calls');
  function main (line 24) | async function main() {

FILE: packages/builtin-tool-memory/src/ExecutionRuntime/index.ts
  type MemoryRuntimeService (line 25) | interface MemoryRuntimeService {
  type MemoryToolPermission (line 50) | type MemoryToolPermission = 'read-only' | 'read-write';
  type MemoryExecutionRuntimeOptions (line 52) | interface MemoryExecutionRuntimeOptions {
  constant READ_ONLY_RESULT (line 57) | const READ_ONLY_RESULT: BuiltinServerRuntimeOutput = {
  class MemoryExecutionRuntime (line 62) | class MemoryExecutionRuntime {
    method constructor (line 66) | constructor(options: MemoryExecutionRuntimeOptions) {
    method isReadOnly (line 71) | private get isReadOnly() {
    method searchUserMemory (line 75) | async searchUserMemory(params: SearchMemoryParams): Promise<BuiltinSer...
    method addContextMemory (line 92) | async addContextMemory(
    method addActivityMemory (line 116) | async addActivityMemory(
    method addExperienceMemory (line 140) | async addExperienceMemory(
    method addIdentityMemory (line 164) | async addIdentityMemory(
    method addPreferenceMemory (line 188) | async addPreferenceMemory(
    method updateIdentityMemory (line 212) | async updateIdentityMemory(
    method removeIdentityMemory (line 236) | async removeIdentityMemory(

FILE: packages/builtin-tool-memory/src/client/Render/SearchUserMemory/index.tsx
  type MemoryItemProps (line 54) | interface MemoryItemProps {

FILE: packages/builtin-tool-memory/src/client/components/ExperienceMemoryCard.tsx
  type ExperienceMemoryCardProps (line 83) | interface ExperienceMemoryCardProps {

FILE: packages/builtin-tool-memory/src/client/components/PreferenceMemoryCard.tsx
  type PreferenceMemoryCardProps (line 94) | interface PreferenceMemoryCardProps {

FILE: packages/builtin-tool-memory/src/executor/index.ts
  class MemoryExecutor (line 22) | class MemoryExecutor extends BaseExecutor<typeof MemoryApiName> {
    method constructor (line 28) | constructor() {

FILE: packages/builtin-tool-memory/src/types.ts
  type MemoryApiNameType (line 24) | type MemoryApiNameType = (typeof MemoryApiName)[keyof typeof MemoryApiNa...
  type SearchUserMemoryState (line 34) | type SearchUserMemoryState = SearchMemoryResult;
  type AddContextMemoryParams (line 37) | type AddContextMemoryParams = z.infer<typeof ContextMemoryItemSchema>;
  type AddContextMemoryState (line 38) | interface AddContextMemoryState {
  type AddActivityMemoryParams (line 44) | type AddActivityMemoryParams = z.infer<typeof ActivityMemoryItemSchema>;
  type AddActivityMemoryState (line 45) | interface AddActivityMemoryState {
  type AddExperienceMemoryParams (line 51) | type AddExperienceMemoryParams = z.infer<typeof ExperienceMemoryItemSche...
  type AddExperienceMemoryState (line 52) | interface AddExperienceMemoryState {
  type AddIdentityMemoryParams (line 58) | type AddIdentityMemoryParams = z.infer<typeof AddIdentityActionSchema>;
  type AddIdentityMemoryState (line 59) | interface AddIdentityMemoryState {
  type AddPreferenceMemoryParams (line 65) | type AddPreferenceMemoryParams = z.infer<typeof PreferenceMemoryItemSche...
  type AddPreferenceMemoryState (line 66) | interface AddPreferenceMemoryState {
  type UpdateIdentityMemoryParams (line 72) | type UpdateIdentityMemoryParams = z.infer<typeof UpdateIdentityActionSch...
  type UpdateIdentityMemoryState (line 73) | interface UpdateIdentityMemoryState {
  type RemoveIdentityMemoryParams (line 78) | type RemoveIdentityMemoryParams = z.infer<typeof RemoveIdentityActionSch...
  type RemoveIdentityMemoryState (line 79) | interface RemoveIdentityMemoryState {

FILE: packages/builtin-tool-message/src/ExecutionRuntime/index.ts
  type MessageRuntimeService (line 124) | interface MessageRuntimeService {
  type BotProviderQuery (line 149) | interface BotProviderQuery {
  type MessageExecutionRuntimeOptions (line 168) | interface MessageExecutionRuntimeOptions {
  class MessageExecutionRuntime (line 173) | class MessageExecutionRuntime {
    method constructor (line 177) | constructor(options: MessageExecutionRuntimeOptions) {
    method sendMessage (line 184) | async sendMessage(params: SendMessageParams): Promise<BuiltinServerRun...
    method readMessages (line 200) | async readMessages(params: ReadMessagesParams): Promise<BuiltinServerR...
    method editMessage (line 226) | async editMessage(params: EditMessageParams): Promise<BuiltinServerRun...
    method deleteMessage (line 242) | async deleteMessage(params: DeleteMessageParams): Promise<BuiltinServe...
    method searchMessages (line 258) | async searchMessages(params: SearchMessagesParams): Promise<BuiltinSer...
    method reactToMessage (line 281) | async reactToMessage(params: ReactToMessageParams): Promise<BuiltinSer...
    method getReactions (line 297) | async getReactions(params: GetReactionsParams): Promise<BuiltinServerR...
    method pinMessage (line 317) | async pinMessage(params: PinMessageParams): Promise<BuiltinServerRunti...
    method unpinMessage (line 333) | async unpinMessage(params: UnpinMessageParams): Promise<BuiltinServerR...
    method listPins (line 349) | async listPins(params: ListPinsParams): Promise<BuiltinServerRuntimeOu...
    method getChannelInfo (line 369) | async getChannelInfo(params: GetChannelInfoParams): Promise<BuiltinSer...
    method listChannels (line 385) | async listChannels(params: ListChannelsParams): Promise<BuiltinServerR...
    method getMemberInfo (line 406) | async getMemberInfo(params: GetMemberInfoParams): Promise<BuiltinServe...
    method createThread (line 424) | async createThread(params: CreateThreadParams): Promise<BuiltinServerR...
    method listThreads (line 440) | async listThreads(params: ListThreadsParams): Promise<BuiltinServerRun...
    method replyToThread (line 459) | async replyToThread(params: ReplyToThreadParams): Promise<BuiltinServe...
    method createPoll (line 477) | async createPoll(params: CreatePollParams): Promise<BuiltinServerRunti...
    method sendDirectMessage (line 495) | async sendDirectMessage(params: SendDirectMessageParams): Promise<Buil...
    method listPlatforms (line 519) | async listPlatforms(_params: ListPlatformsParams): Promise<BuiltinServ...
    method listBots (line 545) | async listBots(_params: ListBotsParams): Promise<BuiltinServerRuntimeO...
    method getBotDetail (line 589) | async getBotDetail(params: GetBotDetailParams): Promise<BuiltinServerR...
    method createBot (line 608) | async createBot(params: CreateBotParams): Promise<BuiltinServerRuntime...
    method updateBot (line 624) | async updateBot(params: UpdateBotParams): Promise<BuiltinServerRuntime...
    method deleteBot (line 643) | async deleteBot(params: DeleteBotParams): Promise<BuiltinServerRuntime...
    method toggleBot (line 659) | async toggleBot(params: ToggleBotParams): Promise<BuiltinServerRuntime...
    method connectBot (line 675) | async connectBot(params: ConnectBotParams): Promise<BuiltinServerRunti...

FILE: packages/builtin-tool-message/src/executor/index.ts
  class MessageExecutor (line 35) | class MessageExecutor extends BaseExecutor<typeof MessageApiName> {
    method constructor (line 41) | constructor(runtime: MessageExecutionRuntime) {

FILE: packages/builtin-tool-message/src/types.ts
  type MessagePlatformType (line 17) | type MessagePlatformType = (typeof MessagePlatform)[keyof typeof Message...
  type MessageApiNameType (line 63) | type MessageApiNameType = (typeof 
Copy disabled (too large) Download .json
Condensed preview — 9158 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (82,271K chars).
[
  {
    "path": ".agents/skills/add-provider-doc/SKILL.md",
    "chars": 2265,
    "preview": "---\nname: add-provider-doc\ndescription: Guide for adding new AI provider documentation. Use when adding documentation fo"
  },
  {
    "path": ".agents/skills/add-setting-env/SKILL.md",
    "chars": 2525,
    "preview": "---\nname: add-setting-env\ndescription: Guide for adding environment variables to configure user settings. Use when imple"
  },
  {
    "path": ".agents/skills/agent-tracing/SKILL.md",
    "chars": 9781,
    "preview": "---\nname: agent-tracing\ndescription: \"Agent tracing CLI for inspecting agent execution snapshots. Use when user mentions"
  },
  {
    "path": ".agents/skills/chat-sdk/SKILL.md",
    "chars": 6171,
    "preview": "---\nname: chat-sdk\ndescription: >\n  Build multi-platform chat bots with Chat SDK (`chat` npm package). Use when develope"
  },
  {
    "path": ".agents/skills/cli/SKILL.md",
    "chars": 10841,
    "preview": "---\nname: cli\ndescription: LobeHub CLI (@lobehub/cli) development guide. Use when working on CLI commands, adding new su"
  },
  {
    "path": ".agents/skills/cli/references/agent.md",
    "chars": 4048,
    "preview": "# Agent Commands\n\nManage AI agents: create, edit, delete, list, run, and check status.\n\n**Source**: `apps/cli/src/comman"
  },
  {
    "path": ".agents/skills/cli/references/conversation.md",
    "chars": 3083,
    "preview": "# Conversation Commands (Topic & Message)\n\n## Topic Management (`lh topic`)\n\nManage conversation topics (threads).\n\n**So"
  },
  {
    "path": ".agents/skills/cli/references/generate.md",
    "chars": 8190,
    "preview": "# Content Generation Commands\n\nGenerate text, images, videos, speech, and transcriptions.\n\n**Source**: `apps/cli/src/com"
  },
  {
    "path": ".agents/skills/cli/references/knowledge.md",
    "chars": 8328,
    "preview": "# Knowledge Base, File & Document Commands\n\n## Knowledge Base (`lh kb`)\n\nManage knowledge bases for RAG (Retrieval-Augme"
  },
  {
    "path": ".agents/skills/cli/references/memory.md",
    "chars": 3244,
    "preview": "# Memory Commands\n\nManage user memories - the AI's long-term knowledge about users.\n\n**Source**: `apps/cli/src/commands/"
  },
  {
    "path": ".agents/skills/cli/references/models-providers.md",
    "chars": 5935,
    "preview": "# Model & Provider Commands\n\n## Model Management (`lh model`)\n\nManage AI models within providers.\n\n**Source**: `apps/cli"
  },
  {
    "path": ".agents/skills/cli/references/search-config.md",
    "chars": 3051,
    "preview": "# Search & Configuration Commands\n\n## Global Search (`lh search`)\n\nSearch across all LobeHub resource types.\n\n**Source**"
  },
  {
    "path": ".agents/skills/cli/references/skills-plugins.md",
    "chars": 3749,
    "preview": "# Skill & Plugin Commands\n\n## Skill Management (`lh skill`)\n\nManage agent skills (custom instructions and capabilities)."
  },
  {
    "path": ".agents/skills/code-review/SKILL.md",
    "chars": 3278,
    "preview": "---\nname: code-review\ndescription: 'Code review checklist for LobeHub. Use when reviewing PRs, diffs, or code changes. C"
  },
  {
    "path": ".agents/skills/data-fetching/SKILL.md",
    "chars": 31754,
    "preview": "---\nname: data-fetching\ndescription: Data fetching architecture guide using Service layer + Zustand Store + SWR. Use whe"
  },
  {
    "path": ".agents/skills/db-migrations/SKILL.md",
    "chars": 3280,
    "preview": "---\nname: db-migrations\ndescription: 'Use when generating or regenerating Drizzle migration files, changing database sch"
  },
  {
    "path": ".agents/skills/debug/SKILL.md",
    "chars": 1210,
    "preview": "---\nname: debug\ndescription: Debug package usage guide. Use when adding debug logging, understanding log namespaces, or "
  },
  {
    "path": ".agents/skills/desktop/SKILL.md",
    "chars": 2417,
    "preview": "---\nname: desktop\ndescription: Electron desktop development guide. Use when implementing desktop features, IPC handlers,"
  },
  {
    "path": ".agents/skills/desktop/references/feature-implementation.md",
    "chars": 2932,
    "preview": "# Desktop Feature Implementation Guide\n\n## Architecture Overview\n\n```plaintext\nMain Process                    Renderer "
  },
  {
    "path": ".agents/skills/desktop/references/local-tools.md",
    "chars": 3361,
    "preview": "# Desktop Local Tools Implementation\n\n## Workflow Overview\n\n1. Define tool interface (Manifest)\n2. Define related types\n"
  },
  {
    "path": ".agents/skills/desktop/references/menu-config.md",
    "chars": 2308,
    "preview": "# Desktop Menu Configuration Guide\n\n## Menu Types\n\n1. **App Menu**: Top of window (macOS) or title bar (Windows/Linux)\n2"
  },
  {
    "path": ".agents/skills/desktop/references/window-management.md",
    "chars": 3314,
    "preview": "# Desktop Window Management Guide\n\n## Window Management Overview\n\n1. Window creation and configuration\n2. Window state m"
  },
  {
    "path": ".agents/skills/drizzle/SKILL.md",
    "chars": 5151,
    "preview": "---\nname: drizzle\ndescription: Drizzle ORM schema and database guide. Use when working with database schemas (src/databa"
  },
  {
    "path": ".agents/skills/hotkey/SKILL.md",
    "chars": 2298,
    "preview": "---\nname: hotkey\ndescription: Guide for adding keyboard shortcuts. Use when implementing new hotkeys, registering shortc"
  },
  {
    "path": ".agents/skills/i18n/SKILL.md",
    "chars": 2097,
    "preview": "---\nname: i18n\ndescription: Internationalization guide using react-i18next. Use when adding translations, creating i18n "
  },
  {
    "path": ".agents/skills/linear/SKILL.md",
    "chars": 2417,
    "preview": "---\nname: linear\ndescription: \"Linear issue management. MUST USE when: (1) user mentions LOBE-xxx issue IDs (e.g. LOBE-4"
  },
  {
    "path": ".agents/skills/local-testing/SKILL.md",
    "chars": 24746,
    "preview": "---\nname: local-testing\ndescription: >\n  Local app and bot testing. Uses agent-browser CLI for Electron/web app UI testi"
  },
  {
    "path": ".agents/skills/local-testing/scripts/capture-app-window.sh",
    "chars": 2075,
    "preview": "#!/usr/bin/env bash\n#\n# capture-app-window.sh — Capture a screenshot of a specific app window\n#\n# Uses CGWindowList via "
  },
  {
    "path": ".agents/skills/local-testing/scripts/record-electron-demo.sh",
    "chars": 11922,
    "preview": "#!/usr/bin/env bash\n#\n# record-electron-demo.sh — Record an automated demo of the Electron app\n#\n# Usage:\n#   ./scripts/"
  },
  {
    "path": ".agents/skills/local-testing/scripts/test-discord-bot.sh",
    "chars": 1960,
    "preview": "#!/usr/bin/env bash\n#\n# test-discord-bot.sh — Send a message to a Discord bot and capture the response\n#\n# Usage:\n#   ./"
  },
  {
    "path": ".agents/skills/local-testing/scripts/test-lark-bot.sh",
    "chars": 2541,
    "preview": "#!/usr/bin/env bash\n#\n# test-lark-bot.sh — Send a message to a Lark/Feishu bot and capture the response\n#\n# Usage:\n#   ."
  },
  {
    "path": ".agents/skills/local-testing/scripts/test-qq-bot.sh",
    "chars": 2235,
    "preview": "#!/usr/bin/env bash\n#\n# test-qq-bot.sh — Send a message to a QQ bot and capture the response\n#\n# Usage:\n#   ./scripts/te"
  },
  {
    "path": ".agents/skills/local-testing/scripts/test-slack-bot.sh",
    "chars": 1970,
    "preview": "#!/usr/bin/env bash\n#\n# test-slack-bot.sh — Send a message to a Slack bot and capture the response\n#\n# Usage:\n#   ./scri"
  },
  {
    "path": ".agents/skills/local-testing/scripts/test-telegram-bot.sh",
    "chars": 2540,
    "preview": "#!/usr/bin/env bash\n#\n# test-telegram-bot.sh — Send a message to a Telegram bot and capture the response\n#\n# Usage:\n#   "
  },
  {
    "path": ".agents/skills/local-testing/scripts/test-wechat-bot.sh",
    "chars": 2685,
    "preview": "#!/usr/bin/env bash\n#\n# test-wechat-bot.sh — Send a message to a WeChat bot and capture the response\n#\n# Usage:\n#   ./sc"
  },
  {
    "path": ".agents/skills/microcopy/SKILL.md",
    "chars": 2756,
    "preview": "---\nname: microcopy\ndescription: UI copy and microcopy guidelines. Use when writing UI text, buttons, error messages, em"
  },
  {
    "path": ".agents/skills/microcopy/microcopy-cn.md",
    "chars": 3402,
    "preview": "---\nglobs: src/locales/default/*\nalwaysApply: false\n---\n\n你是「LobeHub」的中文 UI 文案与微文案(microcopy)专家。LobeHub 是一个助理工作空间:用户可以创建助"
  },
  {
    "path": ".agents/skills/microcopy/microcopy-en.md",
    "chars": 9178,
    "preview": "---\nglobs: src/locales/default/*\nalwaysApply: false\n---\n\nYou are **LobeHub’s English UI Copy & Microcopy Specialist**.\n\n"
  },
  {
    "path": ".agents/skills/modal/SKILL.md",
    "chars": 2745,
    "preview": "---\nname: modal\ndescription: Modal imperative API guide. Use when creating modal dialogs using createModal from @lobehub"
  },
  {
    "path": ".agents/skills/pr/SKILL.md",
    "chars": 2695,
    "preview": "---\nname: pr\ndescription: \"Create a PR for the current branch. Use when the user asks to create a pull request, submit P"
  },
  {
    "path": ".agents/skills/project-overview/SKILL.md",
    "chars": 6180,
    "preview": "---\nname: project-overview\ndescription: Complete project architecture and structure guide. Use when exploring the codeba"
  },
  {
    "path": ".agents/skills/react/SKILL.md",
    "chars": 4515,
    "preview": "---\nname: react\ndescription: React component development guide. Use when working with React components (.tsx files), cre"
  },
  {
    "path": ".agents/skills/react/references/layout-kit.md",
    "chars": 2335,
    "preview": "# Flexbox Layout Components Guide\n\n`@lobehub/ui` provides `Flexbox` and `Center` components for creating flexible layout"
  },
  {
    "path": ".agents/skills/recent-data/SKILL.md",
    "chars": 2738,
    "preview": "---\nname: recent-data\ndescription: Guide for using Recent Data (topics, resources, pages). Use when working with recentl"
  },
  {
    "path": ".agents/skills/response-compliance/SKILL.md",
    "chars": 4160,
    "preview": "---\nname: response-compliance\ndescription: OpenResponses API compliance testing. Use when testing the Response API endpo"
  },
  {
    "path": ".agents/skills/spa-routes/SKILL.md",
    "chars": 8705,
    "preview": "---\nname: spa-routes\ndescription: MUST use when editing src/routes/ segments, src/spa/router/desktopRouter.config.tsx or"
  },
  {
    "path": ".agents/skills/store-data-structures/SKILL.md",
    "chars": 16071,
    "preview": "---\nname: store-data-structures\ndescription: Zustand store data structure patterns for LobeHub. Covers List vs Detail da"
  },
  {
    "path": ".agents/skills/testing/SKILL.md",
    "chars": 4866,
    "preview": "---\nname: testing\ndescription: Testing guide using Vitest. Use when writing tests (.test.ts, .test.tsx), fixing failing "
  },
  {
    "path": ".agents/skills/testing/references/agent-runtime-e2e.md",
    "chars": 3659,
    "preview": "# Agent Runtime E2E Testing Guide\n\n## Core Principles\n\n### Minimal Mock Principle\n\nOnly mock **three external dependenci"
  },
  {
    "path": ".agents/skills/testing/references/db-model-test.md",
    "chars": 3316,
    "preview": "# Database Model Testing Guide\n\nTest `packages/database` Model layer.\n\n## Dual Environment Verification (Required)\n\n```b"
  },
  {
    "path": ".agents/skills/testing/references/desktop-controller-test.md",
    "chars": 2911,
    "preview": "# Desktop Controller Unit Testing Guide\n\n## Testing Framework & Directory Structure\n\nLobeHub Desktop uses Vitest as the "
  },
  {
    "path": ".agents/skills/testing/references/electron-ipc-test.md",
    "chars": 1834,
    "preview": "# Electron IPC Testing Strategy\n\nFor Electron IPC tests, use **Mock return values** instead of real Electron environment"
  },
  {
    "path": ".agents/skills/testing/references/zustand-store-action-test.md",
    "chars": 3824,
    "preview": "# Zustand Store Action Testing Guide\n\n## Basic Structure\n\n```typescript\nimport { act, renderHook } from '@testing-librar"
  },
  {
    "path": ".agents/skills/trpc-router/SKILL.md",
    "chars": 3734,
    "preview": "---\nname: trpc-router\ndescription: TRPC router development guide. Use when creating or modifying TRPC routers (src/serve"
  },
  {
    "path": ".agents/skills/typescript/SKILL.md",
    "chars": 3273,
    "preview": "---\nname: typescript\ndescription: TypeScript code style and optimization guidelines. MUST READ before writing or modifyi"
  },
  {
    "path": ".agents/skills/upstash-workflow/SKILL.md",
    "chars": 29987,
    "preview": "---\nname: upstash-workflow\ndescription: 'Upstash Workflow implementation guide. Use when creating async workflows with Q"
  },
  {
    "path": ".agents/skills/upstash-workflow/reference/cloud.md",
    "chars": 9517,
    "preview": "# Cloud Project Workflow Configuration\n\nThis document covers cloud-specific workflow configurations and patterns for the"
  },
  {
    "path": ".agents/skills/version-release/SKILL.md",
    "chars": 7184,
    "preview": "---\nname: version-release\ndescription: \"Version release workflow. Use when the user mentions 'release', 'hotfix', 'versi"
  },
  {
    "path": ".agents/skills/version-release/reference/changelog-example/db-migration.md",
    "chars": 876,
    "preview": "# DB Schema Migration Changelog Example\n\nA changelog reference for database migration release PR bodies.\n\n---\n\nThis rele"
  },
  {
    "path": ".agents/skills/version-release/reference/changelog-example/weekly-release.md",
    "chars": 2037,
    "preview": "# Patch Release (Weekly) Changelog Example\n\nA real-world changelog reference for weekly patch release PR bodies.\n\n---\n\nT"
  },
  {
    "path": ".agents/skills/version-release/reference/patch-release-scenarios.md",
    "chars": 3275,
    "preview": "# Patch Release Scenarios\n\nAll Patch Release scenarios automatically bump the patch version (e.g. 2.1.31 → 2.1.32). PR t"
  },
  {
    "path": ".agents/skills/zustand/SKILL.md",
    "chars": 5227,
    "preview": "---\nname: zustand\ndescription: Zustand state management guide. Use when working with store code (src/store/**), implemen"
  },
  {
    "path": ".agents/skills/zustand/references/action-patterns.md",
    "chars": 3118,
    "preview": "# Zustand Action Patterns\n\n## Optimistic Update Implementation\n\n### Standard Flow\n\n```typescript\ninternal_updateMessageC"
  },
  {
    "path": ".agents/skills/zustand/references/slice-organization.md",
    "chars": 3133,
    "preview": "# Zustand Slice Organization\n\n## Top-Level Store Structure\n\nKey aggregation files:\n\n- `src/store/chat/initialState.ts`: "
  },
  {
    "path": ".bunfig.toml",
    "chars": 33,
    "preview": "[install.lockfile]\n\nsave = false\n"
  },
  {
    "path": ".changelogrc.cjs",
    "chars": 53,
    "preview": "module.exports = require('@lobehub/lint').changelog;\n"
  },
  {
    "path": ".conductor/setup.sh",
    "chars": 3097,
    "preview": "#!/bin/bash\n\n# Conductor workspace setup script\n# This script creates symlinks for .env and all node_modules directories"
  },
  {
    "path": ".console-log-whitelist.json",
    "chars": 242,
    "preview": "{\n  \"files\": [\"drizzle.config.ts\"],\n  \"patterns\": [\n    \"scripts/**\",\n    \"**/*.test.ts\",\n    \"**/*.test.tsx\",\n    \"**/*"
  },
  {
    "path": ".cursor/docs/createStaticStyles_migration_guide.md",
    "chars": 18407,
    "preview": "# createStaticStyles 迁移指南\n\n## 📖 概述\n\n`createStaticStyles` 是 `antd-style` 提供的静态样式创建函数,相比 `createStyles`(hook 方案)具有零运行时开销的优"
  },
  {
    "path": ".cursorindexingignore",
    "chars": 179,
    "preview": "# Add directories or file patterns to ignore during indexing (e.g. foo/ or *.csv)\nlocales/\napps/desktop/resources/locale"
  },
  {
    "path": ".devcontainer/devcontainer.json",
    "chars": 252,
    "preview": "{\n  \"features\": {\n    \"ghcr.io/devcontainer-community/devcontainer-features/bun.sh:1\": {},\n    \"ghcr.io/devcontainers/fe"
  },
  {
    "path": ".editorconfig",
    "chars": 245,
    "preview": "# http://editorconfig.org\nroot = true\n\n[*]\nindent_style = space\nindent_size = 2\nend_of_line = lf\ncharset = utf-8\ntrim_tr"
  },
  {
    "path": ".gitattributes",
    "chars": 529,
    "preview": "# 统一使用 LF 行尾符(与 Mac/Linux 一致)\n* text=auto eol=lf\n\n# 确保这些文件类型始终使用 LF\n*.ts text eol=lf\n*.tsx text eol=lf\n*.js text eol=lf\n"
  },
  {
    "path": ".github/CODEOWNERS",
    "chars": 122,
    "preview": "# Database migrations require approval from core maintainers\n\n/packages/database/migrations/ @arvinxx @nekomeowww @tjx66"
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 667,
    "preview": "# These are supported funding model platforms\n\ngithub: lobehub\npatreon: # Replace with a single Patreon username\nopen_co"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/1_bug_report.yml",
    "chars": 3221,
    "preview": "name: '🐛 Bug Report'\ndescription: 'Report an bug'\nlabels: ['unconfirm']\ntype: Bug\nbody:\n  - type: dropdown\n    attribute"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/2_feature_request.yml",
    "chars": 667,
    "preview": "name: '🌠 Feature Request'\ndescription: 'Suggest an idea'\ntitle: '[Request] '\ntype: Feature\nbody:\n  - type: textarea\n    "
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "chars": 406,
    "preview": "contact_links:\n  - name: Ask a question for self-hosting\n    url: https://github.com/lobehub/lobe-chat/discussions/new?c"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "chars": 970,
    "preview": "#### 💻 Change Type\n\n<!-- For change type, change [ ] to [x]. -->\n\n- [ ] ✨ feat\n- [ ] 🐛 fix\n- [ ] ♻️ refactor\n- [ ] 💄 sty"
  },
  {
    "path": ".github/actions/desktop-build-setup/action.yml",
    "chars": 978,
    "preview": "name: Desktop Build Setup\ndescription: Setup Node.js, pnpm and install dependencies for desktop build\n\ninputs:\n  node-ve"
  },
  {
    "path": ".github/actions/desktop-cleanup-s3/action.yml",
    "chars": 2925,
    "preview": "name: Desktop Cleanup S3\ndescription: Remove old release versions from S3, keeping the most recent N versions\n\ninputs:\n "
  },
  {
    "path": ".github/actions/desktop-publish-s3/action.yml",
    "chars": 5540,
    "preview": "name: Desktop Publish to S3\ndescription: Upload desktop release artifacts to S3 update server\n\ninputs:\n  channel:\n    de"
  },
  {
    "path": ".github/actions/desktop-upload-artifacts/action.yml",
    "chars": 1629,
    "preview": "name: Desktop Upload Artifacts\ndescription: Rename macOS yml for multi-arch and upload build artifacts\n\ninputs:\n  artifa"
  },
  {
    "path": ".github/actions/setup-env/action.yml",
    "chars": 725,
    "preview": "name: Setup Environment\ndescription: Setup Node.js, pnpm (install) and Bun (script runner) for workflows\n\ninputs:\n  node"
  },
  {
    "path": ".github/actions/setup-node-bun/action.yml",
    "chars": 694,
    "preview": "name: Setup Node and Bun\ndescription: Setup Node.js and Bun for workflows\n\ninputs:\n  node-version:\n    description: Node"
  },
  {
    "path": ".github/actions/setup-node-pnpm/action.yml",
    "chars": 614,
    "preview": "name: Setup Node and pnpm\ndescription: Setup Node.js and pnpm for workflows\n\ninputs:\n  node-version:\n    description: No"
  },
  {
    "path": ".github/scripts/auto-close-duplicates.ts",
    "chars": 7788,
    "preview": "#!/usr/bin/env bun\n\ndeclare global {\n  // @ts-ignore\n  // eslint-disable-next-line no-var\n  var process: {\n    env: Reco"
  },
  {
    "path": ".github/scripts/create-failure-issue.js",
    "chars": 8745,
    "preview": "/**\n * Create or update GitHub issue when i18n workflow fails\n * Usage: node create-failure-issue.js\n */\n\nmodule.exports"
  },
  {
    "path": ".github/scripts/docker-pr-comment.js",
    "chars": 2325,
    "preview": "/**\n * Generate or update PR comment with Docker build info\n */\nmodule.exports = async ({\n  github,\n  context,\n  dockerM"
  },
  {
    "path": ".github/scripts/lock-closed-issues.js",
    "chars": 2234,
    "preview": "// @ts-check\n/**\n * Lock closed issues after 7 days of inactivity\n * @param {object} github - GitHub API client\n * @para"
  },
  {
    "path": ".github/scripts/pr-comment.js",
    "chars": 4447,
    "preview": "/**\n * Generate PR comment with download links for desktop builds\n * and handle comment creation/update logic\n */\nconst "
  },
  {
    "path": ".github/scripts/pr-release-body.js",
    "chars": 1404,
    "preview": "/**\n * Generate PR pre-release body content\n * This script generates the description text for PR pre-releases\n */\nmodule"
  },
  {
    "path": ".github/workflows/auto-i18n.yml",
    "chars": 1778,
    "preview": "name: Daily i18n Update\n\non:\n  schedule:\n    - cron: '0 0 * * *'\n  workflow_dispatch: {}\n\n# Add permissions configuratio"
  },
  {
    "path": ".github/workflows/auto-tag-release.yml",
    "chars": 9205,
    "preview": "name: Auto Tag Release\n\npermissions:\n  contents: write\n\non:\n  pull_request_target:\n    types: [closed]\n    branches:\n   "
  },
  {
    "path": ".github/workflows/bundle-analyzer.yml",
    "chars": 4171,
    "preview": "name: Bundle Analyzer\n\non:\n  workflow_dispatch: {}\n\npermissions:\n  contents: read\n  actions: write\n\nenv:\n  NODE_VERSION:"
  },
  {
    "path": ".github/workflows/claude-auto-e2e-testing.yml",
    "chars": 4415,
    "preview": "name: Claude Auto E2E Testing\ndescription: Automatically add E2E tests to improve user journey coverage\n\non:\n  schedule:"
  },
  {
    "path": ".github/workflows/claude-auto-testing.yml",
    "chars": 2387,
    "preview": "name: Claude Auto Testing Coverage\ndescription: Automatically add unit tests to improve code coverage\n\non:\n  schedule:\n "
  },
  {
    "path": ".github/workflows/claude-dedupe-issues.yml",
    "chars": 1322,
    "preview": "name: Claude Issue Dedupe\ndescription: Automatically dedupe GitHub issues using Claude Code\non:\n  issues:\n    types: [op"
  },
  {
    "path": ".github/workflows/claude-issue-triage.yml",
    "chars": 2929,
    "preview": "name: Claude Issue Triage\ndescription: Automatically triage GitHub issues using Claude Code\non:\n  issues:\n    types: [op"
  },
  {
    "path": ".github/workflows/claude-migration-support.yml",
    "chars": 4826,
    "preview": "name: Claude Migration Support\n\non:\n  issue_comment:\n    types: [created]\n\njobs:\n  migration-support:\n    runs-on: ubunt"
  },
  {
    "path": ".github/workflows/claude-pr-assign.yml",
    "chars": 2903,
    "preview": "name: Claude PR Assign\n\non:\n  pull_request_target:\n    types: [opened, labeled]\n\njobs:\n  assign-reviewer:\n    runs-on: u"
  },
  {
    "path": ".github/workflows/claude-translate-comments.yml",
    "chars": 2315,
    "preview": "name: Claude Translate Non-English Comments\ndescription: Automatically detect and translate non-English comments to Engl"
  },
  {
    "path": ".github/workflows/claude-translator.yml",
    "chars": 7320,
    "preview": "name: Claude Translator\nconcurrency:\n  group: translator-${{ github.event.comment.id || github.event.issue.number || git"
  },
  {
    "path": ".github/workflows/claude.yml",
    "chars": 2312,
    "preview": "name: Claude Code\n\non:\n  issue_comment:\n    types: [created]\n  pull_request_review_comment:\n    types: [created]\n  issue"
  },
  {
    "path": ".github/workflows/e2e.yml",
    "chars": 2456,
    "preview": "name: E2E CI\n\non: [push, pull_request]\n\npermissions:\n  actions: write\n  contents: read\n\nconcurrency:\n  group: ${{ github"
  },
  {
    "path": ".github/workflows/issue-auto-close-duplicates.yml",
    "chars": 829,
    "preview": "name: Auto-close duplicate issues\ndescription: Auto-closes issues that are duplicates of existing issues\non:\n  schedule:"
  },
  {
    "path": ".github/workflows/issue-auto-comments.yml",
    "chars": 1822,
    "preview": "name: Issue Auto Comment\non:\n  issues:\n    types:\n      - opened\n      - closed\n      - assigned\n  pull_request_target:\n"
  },
  {
    "path": ".github/workflows/issue-close-require.yml",
    "chars": 2166,
    "preview": "name: Issue Close Require\n\non:\n  schedule:\n    - cron: '0 0 * * *'\n\npermissions:\n  contents: read\n\njobs:\n  issue-check-i"
  },
  {
    "path": ".github/workflows/lighthouse.yml",
    "chars": 2474,
    "preview": "name: Lighthouse Badger\n\nenv:\n  TOKEN_NAME: 'GH_TOKEN'\n  REPO_BRANCH: 'lobehub/lobe-chat lighthouse'\n  USER_NAME: 'lobeh"
  },
  {
    "path": ".github/workflows/lock-closed-issues.yml",
    "chars": 557,
    "preview": "name: 'Lock Stale Issues'\n\non:\n  schedule:\n    - cron: '0 1 * * *'\n  workflow_dispatch:\n\npermissions:\n  issues: write\n\nc"
  },
  {
    "path": ".github/workflows/manual-build-desktop.yml",
    "chars": 9968,
    "preview": "name: Desktop Manual Build\n\non:\n  workflow_dispatch:\n    inputs:\n      channel:\n        description: 'Release channel fo"
  },
  {
    "path": ".github/workflows/pr-build-desktop.yml",
    "chars": 11273,
    "preview": "name: Desktop PR Build\n\non:\n  pull_request:\n    types: [synchronize, labeled, unlabeled] # PR 更新或标签变化时触发\n\n# 确保同一 PR 同一时间"
  },
  {
    "path": ".github/workflows/pr-build-docker.yml",
    "chars": 5692,
    "preview": "name: Docker PR Build\n\non:\n  pull_request:\n    types: [synchronize, labeled, unlabeled] # PR 更新或标签变化时触发\n\n# 确保同一 PR 同一时间只"
  },
  {
    "path": ".github/workflows/release-desktop-beta.yml",
    "chars": 7617,
    "preview": "name: Release Desktop Beta\n\n# ============================================\n# Beta 频道发版工作流\n# ============================"
  },
  {
    "path": ".github/workflows/release-desktop-canary.yml",
    "chars": 14310,
    "preview": "name: Release Desktop Canary\n\n# ============================================\n# Canary 自动发版工作流\n# ========================"
  },
  {
    "path": ".github/workflows/release-desktop-nightly.yml",
    "chars": 14458,
    "preview": "name: Release Desktop Nightly\n\n# ============================================\n# Nightly 自动发版工作流\n# ======================"
  },
  {
    "path": ".github/workflows/release-desktop-stable.yml",
    "chars": 12985,
    "preview": "name: Release Desktop Stable\n\n# ============================================\n# Stable 频道发版工作流\n# ========================"
  },
  {
    "path": ".github/workflows/release-docker.yml",
    "chars": 4207,
    "preview": "name: Publish Docker Image\npermissions:\n  contents: read\n\non:\n  workflow_dispatch: {}\n  release:\n    types: [published]\n"
  },
  {
    "path": ".github/workflows/release.yml",
    "chars": 1732,
    "preview": "name: Release CI\n\npermissions:\n  contents: write\n  issues: write\n  pull-requests: write\n\non:\n  push:\n    tags:\n      - '"
  },
  {
    "path": ".github/workflows/revalidate-docs.yml",
    "chars": 532,
    "preview": "name: Revalidate Docs\npermissions:\n  contents: read\n\non:\n  push:\n    branches:\n      - main\n      - next\n    paths:\n    "
  },
  {
    "path": ".github/workflows/sync-database-schema.yml",
    "chars": 530,
    "preview": "name: Database Schema Visualization CI\npermissions:\n  contents: read\n\non:\n  push:\n    branches:\n      - main\n    paths:\n"
  },
  {
    "path": ".github/workflows/sync-main-to-canary.yaml",
    "chars": 4733,
    "preview": "name: 🔄 Branch Synchronization\n\non:\n  workflow_dispatch:\n  push:\n    branches:\n      - main\n\npermissions:\n  contents: wr"
  },
  {
    "path": ".github/workflows/sync.yml",
    "chars": 1910,
    "preview": "name: Upstream Sync\n\npermissions:\n  contents: write\n  issues: write\n  actions: write\n\non:\n  schedule:\n    - cron: '0 */6"
  },
  {
    "path": ".github/workflows/test.yml",
    "chars": 7077,
    "preview": "name: Test CI\n\non: [push, pull_request]\n\npermissions:\n  actions: write\n  contents: read\n\nconcurrency:\n  group: ${{ githu"
  },
  {
    "path": ".gitignore",
    "chars": 1749,
    "preview": "# Gitignore for LobeHub\n################################################################\n\n# System files\n.DS_Store\nThumb"
  },
  {
    "path": ".husky/pre-commit",
    "chars": 146,
    "preview": "BRANCH=$(git branch --show-current)\nif [ \"$BRANCH\" = \"dev\" ] || [ \"$BRANCH\" = \"main\" ]; then\n  npm run type-check\nfi\nnpx"
  },
  {
    "path": ".i18nrc.js",
    "chars": 1361,
    "preview": "const { defineConfig } = require('@lobehub/i18n-cli');\nconst fs = require('fs');\nconst path = require('path');\n\nmodule.e"
  },
  {
    "path": ".npmrc",
    "chars": 558,
    "preview": "lockfile=false\nresolution-mode=highest\ndedupe-peer-dependents=true\n\nignore-workspace-root-check=true\nenable-pre-post-scr"
  },
  {
    "path": ".nvmrc",
    "chars": 12,
    "preview": "lts/krypton\n"
  },
  {
    "path": ".prettierignore",
    "chars": 570,
    "preview": "# Prettierignore for LobeHub\n################################################################\n\n# general\n.DS_Store\n.edit"
  },
  {
    "path": ".releaserc.cjs",
    "chars": 276,
    "preview": "const config = require('@lobehub/lint').semanticRelease;\n\nconfig.branches = [\n  'main',\n  {\n    name: 'next',\n    prerel"
  },
  {
    "path": ".remarkrc.mdx.mjs",
    "chars": 171,
    "preview": "import { remarklint } from '@lobehub/lint';\n\nexport default {\n  ...remarklint,\n  plugins: ['remark-mdx', ...remarklint.p"
  },
  {
    "path": ".remarkrc.mjs",
    "chars": 72,
    "preview": "import { remarklint } from '@lobehub/lint';\n\nexport default remarklint;\n"
  },
  {
    "path": ".seorc.cjs",
    "chars": 192,
    "preview": "const { defineConfig } = require('@lobehub/seo-cli');\n\nmodule.exports = defineConfig({\n  entry: ['./docs/**/*.mdx'],\n  m"
  },
  {
    "path": ".stylelintignore",
    "chars": 408,
    "preview": "# Stylelintignore for LobeHub\n################################################################\n\n# dependencies\nnode_modu"
  },
  {
    "path": ".vscode/extensions.json",
    "chars": 313,
    "preview": "{\n  \"recommendations\": [\n    \"Anthropic.claude-code\",\n    \"dbaeumer.vscode-eslint\",\n    \"jrr997.antd-docs\",\n    \"seatonj"
  },
  {
    "path": ".vscode/settings.json",
    "chars": 4429,
    "preview": "{\n  \"editor.codeActionsOnSave\": {\n    \"source.addMissingImports\": \"explicit\",\n    \"source.fixAll.eslint\": \"explicit\",\n  "
  },
  {
    "path": "AGENTS.md",
    "chars": 4106,
    "preview": "# LobeHub Development Guidelines\n\nThis document serves as a comprehensive guide for all team members when developing Lob"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 43591,
    "preview": "<a name=\"readme-top\"></a>\n\n# Changelog\n\n### [Version 2.1.45](https://github.com/lobehub/lobe-chat/compare/v2.1.44...v2.1"
  },
  {
    "path": "CLAUDE.md",
    "chars": 5168,
    "preview": "# CLAUDE.md\n\nGuidelines for using Claude Code in this LobeHub repository.\n\n## Tech Stack\n\n- Next.js 16 + React 19 + Type"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 5182,
    "preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to participate in"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 2860,
    "preview": "# Lobe Chat - Contributing Guide 🌟\n\nWe're thrilled that you want to contribute to Lobe Chat, the future of communication"
  },
  {
    "path": "Dockerfile",
    "chars": 11429,
    "preview": "## Set global build ENV\nARG NODEJS_VERSION=\"24\"\n\n## Base image for all building stages\nFROM node:${NODEJS_VERSION}-slim "
  },
  {
    "path": "GEMINI.md",
    "chars": 53,
    "preview": "# GEMINI.md\n\nPlease follow instructions @./AGENTS.md\n"
  },
  {
    "path": "LICENSE",
    "chars": 1118,
    "preview": "LobeHub Community License\n\nCopyright (c) 2024/06/17 - current LobeHub LLC. All rights reserved.\n\n----------\n\nFrom 1.0, L"
  },
  {
    "path": "README.md",
    "chars": 59946,
    "preview": "<div align=\"center\"><a name=\"readme-top\"></a>\n\n[![][image-banner]][vercel-link]\n\n# LobeHub\n\nLobeHub is the ultimate spac"
  },
  {
    "path": "README.zh-CN.md",
    "chars": 46564,
    "preview": "<div align=\"center\"><a name=\"readme-top\"></a>\n\n[![][image-banner]][vercel-link]\n\n# LobeHub\n\nLobeHub 是一个工作与生活空间,用于发现、构建并与"
  },
  {
    "path": "__mocks__/zustand/traditional.ts",
    "chars": 842,
    "preview": "import { act } from 'react-dom/test-utils';\nimport { beforeEach } from 'vitest';\nimport { createWithEqualityFn as actual"
  },
  {
    "path": "apps/cli/.npmrc",
    "chars": 399,
    "preview": "lockfile=false\nignore-workspace-root-check=true\n\npublic-hoist-pattern[]=*@umijs/lint*\npublic-hoist-pattern[]=*unicorn*\np"
  },
  {
    "path": "apps/cli/README.md",
    "chars": 2378,
    "preview": "# @lobehub/cli\n\nLobeHub command-line interface.\n\n## Local Development\n\n| Task                                       | Co"
  },
  {
    "path": "apps/cli/e2e/agent.e2e.test.ts",
    "chars": 4011,
    "preview": "import { execSync } from 'node:child_process';\n\nimport { describe, expect, it } from 'vitest';\n\n/**\n * E2E tests for `lh"
  },
  {
    "path": "apps/cli/e2e/doc.e2e.test.ts",
    "chars": 9461,
    "preview": "import { execSync } from 'node:child_process';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'nod"
  },
  {
    "path": "apps/cli/e2e/file.e2e.test.ts",
    "chars": 2719,
    "preview": "import { execSync } from 'node:child_process';\n\nimport { describe, expect, it } from 'vitest';\n\n/**\n * E2E tests for `lh"
  },
  {
    "path": "apps/cli/e2e/generate.e2e.test.ts",
    "chars": 3814,
    "preview": "import { execSync } from 'node:child_process';\n\nimport { describe, expect, it } from 'vitest';\n\n/**\n * E2E tests for `lh"
  },
  {
    "path": "apps/cli/e2e/kb.e2e.test.ts",
    "chars": 8304,
    "preview": "import { execSync } from 'node:child_process';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'nod"
  },
  {
    "path": "apps/cli/e2e/memory.e2e.test.ts",
    "chars": 6416,
    "preview": "import { execSync } from 'node:child_process';\n\nimport { describe, expect, it } from 'vitest';\n\n/**\n * E2E tests for `lh"
  },
  {
    "path": "apps/cli/e2e/message.e2e.test.ts",
    "chars": 2833,
    "preview": "import { execSync } from 'node:child_process';\n\nimport { describe, expect, it } from 'vitest';\n\n/**\n * E2E tests for `lh"
  },
  {
    "path": "apps/cli/e2e/model.e2e.test.ts",
    "chars": 6785,
    "preview": "import { execSync } from 'node:child_process';\n\nimport { describe, expect, it } from 'vitest';\n\n/**\n * E2E tests for `lh"
  },
  {
    "path": "apps/cli/e2e/plugin.e2e.test.ts",
    "chars": 2164,
    "preview": "import { execSync } from 'node:child_process';\n\nimport { describe, expect, it } from 'vitest';\n\n/**\n * E2E tests for `lh"
  },
  {
    "path": "apps/cli/e2e/provider.e2e.test.ts",
    "chars": 7172,
    "preview": "import { execSync } from 'node:child_process';\n\nimport { describe, expect, it } from 'vitest';\n\n/**\n * E2E tests for `lh"
  },
  {
    "path": "apps/cli/e2e/search.e2e.test.ts",
    "chars": 1452,
    "preview": "import { execSync } from 'node:child_process';\n\nimport { describe, expect, it } from 'vitest';\n\n/**\n * E2E tests for `lh"
  },
  {
    "path": "apps/cli/e2e/skill.e2e.test.ts",
    "chars": 5967,
    "preview": "import { execSync } from 'node:child_process';\n\nimport { describe, expect, it } from 'vitest';\n\n/**\n * E2E tests for `lh"
  },
  {
    "path": "apps/cli/e2e/topic.e2e.test.ts",
    "chars": 3291,
    "preview": "import { execSync } from 'node:child_process';\n\nimport { describe, expect, it } from 'vitest';\n\n/**\n * E2E tests for `lh"
  },
  {
    "path": "apps/cli/man/man1/lh.1",
    "chars": 3059,
    "preview": ".\\\" Code generated by `npm run man:generate`; DO NOT EDIT.\n.\\\" Manual command details come from the Commander command tr"
  },
  {
    "path": "apps/cli/man/man1/lobe.1",
    "chars": 14,
    "preview": ".so man1/lh.1\n"
  },
  {
    "path": "apps/cli/man/man1/lobehub.1",
    "chars": 14,
    "preview": ".so man1/lh.1\n"
  },
  {
    "path": "apps/cli/package.json",
    "chars": 1331,
    "preview": "{\n  \"name\": \"@lobehub/cli\",\n  \"version\": \"0.0.1-canary.14\",\n  \"type\": \"module\",\n  \"bin\": {\n    \"lh\": \"./dist/index.js\",\n"
  },
  {
    "path": "apps/cli/pnpm-workspace.yaml",
    "chars": 133,
    "preview": "packages:\n  - '../../packages/device-gateway-client'\n  - '../../packages/local-file-shell'\n  - '../../packages/file-load"
  },
  {
    "path": "apps/cli/src/api/client.ts",
    "chars": 2210,
    "preview": "import { createTRPCClient, httpLink } from '@trpc/client';\nimport superjson from 'superjson';\n\nimport type { LambdaRoute"
  },
  {
    "path": "apps/cli/src/api/http.ts",
    "chars": 1794,
    "preview": "import { getValidToken } from '../auth/refresh';\nimport { CLI_API_KEY_ENV } from '../constants/auth';\nimport { resolveSe"
  },
  {
    "path": "apps/cli/src/auth/apiKey.ts",
    "chars": 1093,
    "preview": "import { normalizeUrl, resolveServerUrl } from '../settings';\n\ninterface CurrentUserResponse {\n  data?: {\n    id?: strin"
  },
  {
    "path": "apps/cli/src/auth/credentials.test.ts",
    "chars": 3568,
    "preview": "import fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport { afterEach, beforeEach, descr"
  },
  {
    "path": "apps/cli/src/auth/credentials.ts",
    "chars": 2559,
    "preview": "import crypto from 'node:crypto';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nexp"
  },
  {
    "path": "apps/cli/src/auth/refresh.test.ts",
    "chars": 6935,
    "preview": "import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';\n\nimport { loadSettings } from '../settings';\ni"
  },
  {
    "path": "apps/cli/src/auth/refresh.ts",
    "chars": 1943,
    "preview": "import { resolveServerUrl } from '../settings';\nimport { loadCredentials, saveCredentials, type StoredCredentials } from"
  },
  {
    "path": "apps/cli/src/auth/resolveToken.test.ts",
    "chars": 5608,
    "preview": "import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';\n\nimport { getUserIdFromApiKey } from './apiKey"
  },
  {
    "path": "apps/cli/src/auth/resolveToken.ts",
    "chars": 3263,
    "preview": "import { CLI_API_KEY_ENV } from '../constants/auth';\nimport { resolveServerUrl } from '../settings';\nimport { log } from"
  },
  {
    "path": "apps/cli/src/commands/agent-group.test.ts",
    "chars": 5352,
    "preview": "import { Command } from 'commander';\nimport { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';\n\nimport {"
  },
  {
    "path": "apps/cli/src/commands/agent-group.ts",
    "chars": 7510,
    "preview": "import type { Command } from 'commander';\nimport pc from 'picocolors';\n\nimport { getTrpcClient } from '../api/client';\ni"
  },
  {
    "path": "apps/cli/src/commands/agent.test.ts",
    "chars": 18966,
    "preview": "import { Command } from 'commander';\nimport { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';\n\nimport {"
  },
  {
    "path": "apps/cli/src/commands/agent.ts",
    "chars": 21182,
    "preview": "import { readFileSync } from 'node:fs';\n\nimport type { Command } from 'commander';\nimport pc from 'picocolors';\n\nimport "
  },
  {
    "path": "apps/cli/src/commands/bot.test.ts",
    "chars": 10660,
    "preview": "import { Command } from 'commander';\nimport { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';\n\nimport {"
  },
  {
    "path": "apps/cli/src/commands/bot.ts",
    "chars": 15691,
    "preview": "import type { Command } from 'commander';\nimport pc from 'picocolors';\n\nimport type { TrpcClient } from '../api/client';"
  },
  {
    "path": "apps/cli/src/commands/botMessage.ts",
    "chars": 18233,
    "preview": "import { DEFAULT_BOT_HISTORY_LIMIT } from '@lobechat/const';\nimport type { Command } from 'commander';\nimport pc from 'p"
  },
  {
    "path": "apps/cli/src/commands/brief.ts",
    "chars": 6966,
    "preview": "import type { Command } from 'commander';\nimport pc from 'picocolors';\n\nimport { getTrpcClient } from '../api/client';\ni"
  },
  {
    "path": "apps/cli/src/commands/completion.test.ts",
    "chars": 3491,
    "preview": "import { Command } from 'commander';\nimport { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';\n\nimport {"
  },
  {
    "path": "apps/cli/src/commands/completion.ts",
    "chars": 889,
    "preview": "import type { Command } from 'commander';\n\nimport {\n  getCompletionCandidates,\n  parseCompletionWordIndex,\n  renderCompl"
  },
  {
    "path": "apps/cli/src/commands/config.test.ts",
    "chars": 4357,
    "preview": "import { Command } from 'commander';\nimport { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';\n\nimport {"
  },
  {
    "path": "apps/cli/src/commands/config.ts",
    "chars": 6893,
    "preview": "import type { Command } from 'commander';\nimport pc from 'picocolors';\n\nimport { getTrpcClient } from '../api/client';\ni"
  },
  {
    "path": "apps/cli/src/commands/connect.test.ts",
    "chars": 14161,
    "preview": "import { Command } from 'commander';\nimport { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';\n\nvi.mock("
  },
  {
    "path": "apps/cli/src/commands/connect.ts",
    "chars": 11807,
    "preview": "import fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport type {\n  DeviceSystemInfo,\n  S"
  },
  {
    "path": "apps/cli/src/commands/cron.test.ts",
    "chars": 5300,
    "preview": "import { Command } from 'commander';\nimport { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';\n\nimport {"
  },
  {
    "path": "apps/cli/src/commands/cron.ts",
    "chars": 9567,
    "preview": "import type { Command } from 'commander';\nimport pc from 'picocolors';\n\nimport { getTrpcClient } from '../api/client';\ni"
  },
  {
    "path": "apps/cli/src/commands/device.ts",
    "chars": 3508,
    "preview": "import type { Command } from 'commander';\nimport pc from 'picocolors';\n\nimport { getTrpcClient } from '../api/client';\ni"
  },
  {
    "path": "apps/cli/src/commands/doc.test.ts",
    "chars": 21260,
    "preview": "import fs from 'node:fs';\n\nimport { Command } from 'commander';\nimport { afterEach, beforeEach, describe, expect, it, vi"
  },
  {
    "path": "apps/cli/src/commands/doc.ts",
    "chars": 12715,
    "preview": "import fs from 'node:fs';\n\nimport type { Command } from 'commander';\nimport pc from 'picocolors';\n\nimport { getTrpcClien"
  },
  {
    "path": "apps/cli/src/commands/eval.test.ts",
    "chars": 17962,
    "preview": "import { Command } from 'commander';\nimport { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';\n\nconst { "
  },
  {
    "path": "apps/cli/src/commands/eval.ts",
    "chars": 27434,
    "preview": "import type { Command } from 'commander';\nimport { InvalidArgumentError } from 'commander';\nimport pc from 'picocolors';"
  },
  {
    "path": "apps/cli/src/commands/file.test.ts",
    "chars": 9403,
    "preview": "import { Command } from 'commander';\nimport { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';\n\nimport {"
  },
  {
    "path": "apps/cli/src/commands/file.ts",
    "chars": 8980,
    "preview": "import type { Command } from 'commander';\nimport pc from 'picocolors';\n\nimport { getTrpcClient } from '../api/client';\ni"
  }
]

// ... and 8958 more files (download for full content)

About this extraction

This page contains the full source code of the lobehub/lobe-chat GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 9158 files (69.7 MB), approximately 18.8M tokens, and a symbol index with 13427 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.

Copied to clipboard!