@agentprojectcontext/apx 1.24.0 → 1.27.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +42 -12
- package/skills/apx/SKILL.md +50 -119
- package/skills/apx-agency-agents/SKILL.md +141 -0
- package/skills/apx-agent/SKILL.md +100 -0
- package/skills/apx-mcp/SKILL.md +114 -0
- package/skills/apx-mcp-builder/SKILL.md +186 -0
- package/skills/apx-project/SKILL.md +100 -0
- package/skills/apx-routine/SKILL.md +138 -0
- package/skills/apx-runtime/SKILL.md +115 -0
- package/skills/apx-sessions/SKILL.md +281 -0
- package/skills/apx-skill-builder/SKILL.md +149 -0
- package/skills/apx-task/SKILL.md +95 -0
- package/skills/apx-telegram/SKILL.md +115 -0
- package/skills/apx-voice/SKILL.md +135 -0
- package/src/core/agent/constants.js +3 -0
- package/src/core/agent/ghost-guard.js +24 -0
- package/src/core/agent/index.js +35 -0
- package/src/core/agent/model-router.js +257 -0
- package/src/core/agent/prompt-builder.js +313 -0
- package/src/core/agent/prompts/channels/api.md +7 -0
- package/src/core/agent/prompts/channels/cli.md +6 -0
- package/src/core/agent/prompts/channels/code.md +20 -0
- package/src/core/agent/prompts/channels/deck.md +6 -0
- package/src/core/agent/prompts/channels/desktop.md +24 -0
- package/src/core/agent/prompts/channels/routine.md +9 -0
- package/src/core/agent/prompts/channels/telegram.md +9 -0
- package/src/core/agent/prompts/channels/terminal.md +16 -0
- package/src/core/agent/prompts/channels/web.md +7 -0
- package/src/core/agent/prompts/channels/web_sidebar.md +7 -0
- package/src/core/agent/prompts/modes/voice.md +4 -0
- package/src/core/agent/prompts/super-agent-base.md +42 -0
- package/src/core/agent/pseudo-tools.js +40 -0
- package/src/core/agent/retry.js +85 -0
- package/src/core/agent/run-agent.js +423 -0
- package/src/core/agent/self-memory.js +155 -0
- package/src/{daemon → core/agent}/tool-call-parser.js +83 -10
- package/src/core/agent/tools-overlap.js +66 -0
- package/src/core/apc-skill-sync.js +97 -0
- package/src/core/code-sessions-store.js +150 -0
- package/src/core/config.js +473 -11
- package/src/core/desktop/autostart.js +162 -0
- package/src/core/engines/_health.js +63 -0
- package/src/{daemon → core}/engines/anthropic.js +16 -0
- package/src/core/engines/gemini.js +168 -0
- package/src/core/engines/groq.js +8 -0
- package/src/{daemon → core}/engines/index.js +3 -1
- package/src/{daemon → core}/engines/mock.js +22 -0
- package/src/{daemon → core}/engines/ollama.js +35 -0
- package/src/core/engines/openai-compatible.js +145 -0
- package/src/core/engines/openai.js +8 -0
- package/src/core/engines/openrouter.js +8 -0
- package/src/core/git-baseline.js +147 -0
- package/src/core/identity.js +21 -0
- package/src/core/logging.js +1 -1
- package/src/core/mcp/index.js +14 -0
- package/src/{daemon/mcp-runner.js → core/mcp/runner.js} +18 -6
- package/src/core/mcp/sources.js +246 -0
- package/src/core/memory/active-threads.js +124 -0
- package/src/core/memory/broker.js +144 -0
- package/src/core/memory/compactor.js +186 -0
- package/src/core/memory/embed-engines/gemini.js +62 -0
- package/src/core/memory/embed-engines/index.js +148 -0
- package/src/core/memory/embed-engines/ollama.js +55 -0
- package/src/core/memory/embed-engines/openai.js +64 -0
- package/src/core/memory/embed-engines/tf.js +20 -0
- package/src/core/memory/embeddings.js +132 -0
- package/src/core/memory/index.js +161 -0
- package/src/core/memory/indexer.js +257 -0
- package/src/core/memory/store.js +231 -0
- package/src/core/messages-store.js +143 -25
- package/src/core/parser.js +78 -16
- package/src/core/scaffold.js +175 -79
- package/src/core/tasks-store.js +264 -0
- package/src/core/telegram-identity.js +126 -0
- package/src/core/tools/index.js +6 -0
- package/src/core/voice/engines/elevenlabs.js +96 -0
- package/src/core/voice/engines/gemini.js +148 -0
- package/src/core/voice/engines/index.js +144 -0
- package/src/core/voice/engines/mock.js +59 -0
- package/src/core/voice/engines/openai.js +82 -0
- package/src/core/voice/engines/piper.js +93 -0
- package/src/core/voice/index.js +3 -0
- package/src/core/voice/tts.js +89 -0
- package/src/{daemon → host/daemon}/apc-runtime-context.js +1 -1
- package/src/host/daemon/api/admin-config.js +159 -0
- package/src/host/daemon/api/admin.js +72 -0
- package/src/host/daemon/api/agents.js +284 -0
- package/src/host/daemon/api/artifacts.js +52 -0
- package/src/host/daemon/api/code.js +351 -0
- package/src/host/daemon/api/config.js +104 -0
- package/src/host/daemon/api/connections.js +42 -0
- package/src/host/daemon/api/conversations.js +161 -0
- package/src/host/daemon/api/deck.js +511 -0
- package/src/host/daemon/api/desktop.js +71 -0
- package/src/host/daemon/api/embeddings.js +65 -0
- package/src/host/daemon/api/engines.js +80 -0
- package/src/host/daemon/api/exec.js +193 -0
- package/src/host/daemon/api/health.js +10 -0
- package/src/host/daemon/api/identity.js +36 -0
- package/src/host/daemon/api/mcps.js +205 -0
- package/src/host/daemon/api/messages.js +83 -0
- package/src/host/daemon/api/pairing.js +194 -0
- package/src/host/daemon/api/plugins.js +19 -0
- package/src/host/daemon/api/projects.js +35 -0
- package/src/host/daemon/api/routines.js +84 -0
- package/src/host/daemon/api/run.js +55 -0
- package/src/host/daemon/api/runtimes.js +219 -0
- package/src/host/daemon/api/sessions-search.js +177 -0
- package/src/host/daemon/api/sessions.js +115 -0
- package/src/host/daemon/api/shared.js +217 -0
- package/src/host/daemon/api/super-agent.js +208 -0
- package/src/host/daemon/api/tasks.js +118 -0
- package/src/host/daemon/api/telegram.js +325 -0
- package/src/host/daemon/api/tools.js +21 -0
- package/src/host/daemon/api/top-level.js +131 -0
- package/src/host/daemon/api/transcribe.js +35 -0
- package/src/host/daemon/api/tts.js +44 -0
- package/src/host/daemon/api/voice.js +519 -0
- package/src/host/daemon/api/web.js +123 -0
- package/src/host/daemon/api.js +152 -0
- package/src/{daemon → host/daemon}/compact.js +1 -1
- package/src/{daemon → host/daemon}/db.js +19 -5
- package/src/{daemon/overlay-ws.js → host/daemon/desktop-ws.js} +7 -7
- package/src/host/daemon/engine-sessions.js +245 -0
- package/src/{daemon → host/daemon}/index.js +27 -10
- package/src/{daemon/plugins/overlay.js → host/daemon/plugins/desktop.js} +36 -28
- package/src/{daemon → host/daemon}/plugins/index.js +2 -2
- package/src/{daemon → host/daemon}/plugins/telegram.js +165 -33
- package/src/{daemon → host/daemon}/project-config.js +31 -7
- package/src/{daemon → host/daemon}/routines.js +27 -8
- package/src/{daemon → host/daemon}/skills-loader.js +4 -2
- package/src/{daemon → host/daemon}/smoke.js +9 -5
- package/src/{daemon → host/daemon}/super-agent-tools/helpers.js +1 -1
- package/src/host/daemon/super-agent-tools/index.js +157 -0
- package/src/{daemon → host/daemon}/super-agent-tools/registry-bridge.js +1 -1
- package/src/{daemon → host/daemon}/super-agent-tools/tools/add-project.js +2 -2
- package/src/{daemon → host/daemon}/super-agent-tools/tools/ask-questions.js +4 -0
- package/src/{daemon → host/daemon}/super-agent-tools/tools/call-agent.js +5 -2
- package/src/{daemon → host/daemon}/super-agent-tools/tools/call-runtime.js +117 -8
- package/src/host/daemon/super-agent-tools/tools/create-task.js +52 -0
- package/src/{daemon → host/daemon}/super-agent-tools/tools/import-agent.js +2 -3
- package/src/{daemon → host/daemon}/super-agent-tools/tools/list-agents.js +1 -1
- package/src/host/daemon/super-agent-tools/tools/list-tasks.js +52 -0
- package/src/{daemon → host/daemon}/super-agent-tools/tools/list-vault-agents.js +1 -1
- package/src/host/daemon/super-agent-tools/tools/read-self-memory.js +21 -0
- package/src/host/daemon/super-agent-tools/tools/remember.js +40 -0
- package/src/{daemon → host/daemon}/super-agent-tools/tools/search-messages.js +1 -1
- package/src/host/daemon/super-agent-tools/tools/search-sessions.js +134 -0
- package/src/{daemon → host/daemon}/super-agent-tools/tools/send-telegram.js +2 -2
- package/src/{daemon → host/daemon}/super-agent-tools/tools/set-identity.js +1 -1
- package/src/{daemon → host/daemon}/super-agent-tools/tools/set-permission-mode.js +1 -1
- package/src/{daemon → host/daemon}/super-agent-tools/tools/tail-messages.js +1 -1
- package/src/host/daemon/super-agent.js +129 -0
- package/src/host/daemon/token-store.js +118 -0
- package/src/host/daemon/tool-call-parser.js +2 -0
- package/src/{daemon → host/daemon}/transcription.js +1 -1
- package/src/{daemon → host/daemon}/wakeup.js +2 -2
- package/src/interfaces/cli/claude-permissions.js +33 -0
- package/src/{cli → interfaces/cli}/commands/agent.js +43 -8
- package/src/{cli → interfaces/cli}/commands/command.js +1 -1
- package/src/{cli → interfaces/cli}/commands/config.js +1 -1
- package/src/{cli → interfaces/cli}/commands/daemon.js +67 -0
- package/src/interfaces/cli/commands/desktop.js +335 -0
- package/src/interfaces/cli/commands/exec.js +92 -0
- package/src/{cli → interfaces/cli}/commands/identity.js +6 -63
- package/src/{cli → interfaces/cli}/commands/init.js +1 -1
- package/src/{cli → interfaces/cli}/commands/mcp.js +69 -10
- package/src/{cli → interfaces/cli}/commands/memory.js +2 -2
- package/src/interfaces/cli/commands/model.js +136 -0
- package/src/interfaces/cli/commands/pair.js +170 -0
- package/src/interfaces/cli/commands/project-config.js +131 -0
- package/src/{cli → interfaces/cli}/commands/project.js +1 -1
- package/src/{cli → interfaces/cli}/commands/search.js +1 -1
- package/src/interfaces/cli/commands/session.js +892 -0
- package/src/interfaces/cli/commands/sessions.js +997 -0
- package/src/{cli → interfaces/cli}/commands/setup.js +98 -4
- package/src/{cli → interfaces/cli}/commands/skills.js +117 -9
- package/src/{cli → interfaces/cli}/commands/status.js +9 -1
- package/src/{cli → interfaces/cli}/commands/sys.js +96 -17
- package/src/interfaces/cli/commands/task.js +179 -0
- package/src/interfaces/cli/commands/telegram.js +366 -0
- package/src/{cli → interfaces/cli}/commands/update.js +1 -1
- package/src/interfaces/cli/commands/voice.js +258 -0
- package/src/{cli → interfaces/cli}/http.js +6 -2
- package/src/{cli → interfaces/cli}/index.js +955 -63
- package/src/interfaces/cli/postinstall.js +34 -0
- package/src/interfaces/desktop/assets/app-icon-180.png +0 -0
- package/src/interfaces/desktop/assets/app-icon-32.png +0 -0
- package/src/interfaces/desktop/assets/app-icon.png +0 -0
- package/src/interfaces/desktop/assets/apx-logo.png +0 -0
- package/src/interfaces/desktop/assets/superagent.png +0 -0
- package/src/interfaces/desktop/assets/tray-icon.png +0 -0
- package/src/interfaces/desktop/index.html +18 -0
- package/src/interfaces/desktop/main.js +652 -0
- package/src/interfaces/desktop/preload.js +48 -0
- package/src/interfaces/desktop/renderer.js +1006 -0
- package/src/interfaces/desktop/style.css +400 -0
- package/src/{mcp → interfaces/mcp-server}/index.js +2 -2
- package/src/interfaces/tui/_shims/util-which.ts +53 -0
- package/src/{tui → interfaces/tui}/app.tsx +2 -2
- package/src/{tui → interfaces/tui}/component/prompt/index.tsx +4 -1
- package/src/{tui → interfaces/tui}/context/sdk-apx.tsx +84 -16
- package/src/interfaces/tui/context/sync-apx.tsx +398 -0
- package/src/interfaces/tui/routes/session/index.tsx +368 -0
- package/src/interfaces/tui/routes/session/message-actions.tsx +58 -0
- package/src/interfaces/tui/routes/session/sidebar-apx.tsx +114 -0
- package/src/{tui → interfaces/tui}/tsconfig.json +1 -0
- package/src/{tui → interfaces/tui}/util/clipboard.ts +1 -1
- package/src/interfaces/web/README.md +102 -0
- package/src/interfaces/web/coming-soon.html +65 -0
- package/src/interfaces/web/components.json +25 -0
- package/src/interfaces/web/dist/assets/index-BDUsA6L6.css +1 -0
- package/src/interfaces/web/dist/assets/index-CfWyjPBa.js +548 -0
- package/src/interfaces/web/dist/assets/index-CfWyjPBa.js.map +1 -0
- package/src/interfaces/web/dist/favicon/dark/android-chrome-192x192.png +0 -0
- package/src/interfaces/web/dist/favicon/dark/android-chrome-512x512.png +0 -0
- package/src/interfaces/web/dist/favicon/dark/apple-touch-icon.png +0 -0
- package/src/interfaces/web/dist/favicon/dark/favicon-16x16.png +0 -0
- package/src/interfaces/web/dist/favicon/dark/favicon-32x32.png +0 -0
- package/src/interfaces/web/dist/favicon/dark/favicon-48x48.png +0 -0
- package/src/interfaces/web/dist/favicon/dark/favicon.ico +0 -0
- package/src/interfaces/web/dist/favicon/dark/favicon.webp +0 -0
- package/src/interfaces/web/dist/favicon/dark/site.webmanifest +18 -0
- package/src/interfaces/web/dist/favicon/white/android-chrome-192x192.png +0 -0
- package/src/interfaces/web/dist/favicon/white/android-chrome-512x512.png +0 -0
- package/src/interfaces/web/dist/favicon/white/apple-touch-icon.png +0 -0
- package/src/interfaces/web/dist/favicon/white/favicon-16x16.png +0 -0
- package/src/interfaces/web/dist/favicon/white/favicon-32x32.png +0 -0
- package/src/interfaces/web/dist/favicon/white/favicon-48x48.png +0 -0
- package/src/interfaces/web/dist/favicon/white/favicon.ico +0 -0
- package/src/interfaces/web/dist/favicon/white/favicon.webp +0 -0
- package/src/interfaces/web/dist/favicon/white/site.webmanifest +18 -0
- package/src/interfaces/web/dist/index.html +27 -0
- package/src/interfaces/web/dist/logo/logo_dark.webp +0 -0
- package/src/interfaces/web/dist/logo/logo_only_dark.webp +0 -0
- package/src/interfaces/web/dist/logo/logo_only_white.webp +0 -0
- package/src/interfaces/web/dist/logo/logo_vertical_dark.webp +0 -0
- package/src/interfaces/web/dist/logo/logo_vertical_white.webp +0 -0
- package/src/interfaces/web/dist/logo/logo_white.webp +0 -0
- package/src/interfaces/web/dist/modules/superagent.png +0 -0
- package/src/interfaces/web/index.html +26 -0
- package/src/interfaces/web/package-lock.json +4253 -0
- package/src/interfaces/web/package.json +55 -0
- package/src/interfaces/web/playwright.config.ts +45 -0
- package/src/interfaces/web/pnpm-lock.yaml +2946 -0
- package/src/interfaces/web/public/favicon/dark/android-chrome-192x192.png +0 -0
- package/src/interfaces/web/public/favicon/dark/android-chrome-512x512.png +0 -0
- package/src/interfaces/web/public/favicon/dark/apple-touch-icon.png +0 -0
- package/src/interfaces/web/public/favicon/dark/favicon-16x16.png +0 -0
- package/src/interfaces/web/public/favicon/dark/favicon-32x32.png +0 -0
- package/src/interfaces/web/public/favicon/dark/favicon-48x48.png +0 -0
- package/src/interfaces/web/public/favicon/dark/favicon.ico +0 -0
- package/src/interfaces/web/public/favicon/dark/favicon.webp +0 -0
- package/src/interfaces/web/public/favicon/dark/site.webmanifest +18 -0
- package/src/interfaces/web/public/favicon/white/android-chrome-192x192.png +0 -0
- package/src/interfaces/web/public/favicon/white/android-chrome-512x512.png +0 -0
- package/src/interfaces/web/public/favicon/white/apple-touch-icon.png +0 -0
- package/src/interfaces/web/public/favicon/white/favicon-16x16.png +0 -0
- package/src/interfaces/web/public/favicon/white/favicon-32x32.png +0 -0
- package/src/interfaces/web/public/favicon/white/favicon-48x48.png +0 -0
- package/src/interfaces/web/public/favicon/white/favicon.ico +0 -0
- package/src/interfaces/web/public/favicon/white/favicon.webp +0 -0
- package/src/interfaces/web/public/favicon/white/site.webmanifest +18 -0
- package/src/interfaces/web/public/logo/logo_dark.webp +0 -0
- package/src/interfaces/web/public/logo/logo_only_dark.webp +0 -0
- package/src/interfaces/web/public/logo/logo_only_white.webp +0 -0
- package/src/interfaces/web/public/logo/logo_vertical_dark.webp +0 -0
- package/src/interfaces/web/public/logo/logo_vertical_white.webp +0 -0
- package/src/interfaces/web/public/logo/logo_white.webp +0 -0
- package/src/interfaces/web/public/modules/superagent.png +0 -0
- package/src/interfaces/web/src/App.tsx +199 -0
- package/src/interfaces/web/src/components/AddProjectDialog.tsx +121 -0
- package/src/interfaces/web/src/components/ModelCombobox.tsx +96 -0
- package/src/interfaces/web/src/components/RobyBubble.tsx +213 -0
- package/src/interfaces/web/src/components/Section.tsx +44 -0
- package/src/interfaces/web/src/components/TelegramChannelDialog.tsx +97 -0
- package/src/interfaces/web/src/components/TelegramSendDialog.tsx +48 -0
- package/src/interfaces/web/src/components/Toast.tsx +84 -0
- package/src/interfaces/web/src/components/UiSelect.tsx +74 -0
- package/src/interfaces/web/src/components/chat/Composer.tsx +43 -0
- package/src/interfaces/web/src/components/chat/ContextBar.tsx +111 -0
- package/src/interfaces/web/src/components/chat/MessageBubble.tsx +95 -0
- package/src/interfaces/web/src/components/chat/MessageList.tsx +35 -0
- package/src/interfaces/web/src/components/chat/ModelPicker.tsx +145 -0
- package/src/interfaces/web/src/components/chat/ToolCall.tsx +141 -0
- package/src/interfaces/web/src/components/code/CodeChangesTab.tsx +87 -0
- package/src/interfaces/web/src/components/code/CodeComposer.tsx +87 -0
- package/src/interfaces/web/src/components/code/CodeContextTab.tsx +83 -0
- package/src/interfaces/web/src/components/code/CodeProjectPicker.tsx +39 -0
- package/src/interfaces/web/src/components/code/CodeSessionList.tsx +97 -0
- package/src/interfaces/web/src/components/code/CodeSidePanel.tsx +44 -0
- package/src/interfaces/web/src/components/code/CodeToolTrail.tsx +29 -0
- package/src/interfaces/web/src/components/code/DiffView.tsx +67 -0
- package/src/interfaces/web/src/components/common/Qr.tsx +27 -0
- package/src/interfaces/web/src/components/common/TabLayout.tsx +46 -0
- package/src/interfaces/web/src/components/common/TabNav.tsx +113 -0
- package/src/interfaces/web/src/components/config/ConfigTabsEditor.tsx +202 -0
- package/src/interfaces/web/src/components/config/GlobalConfigEditor.tsx +42 -0
- package/src/interfaces/web/src/components/config/global-config-sections.ts +60 -0
- package/src/interfaces/web/src/components/config/project-config-sections.ts +58 -0
- package/src/interfaces/web/src/components/deck/DaemonCard.tsx +58 -0
- package/src/interfaces/web/src/components/deck/DesktopGroup.tsx +33 -0
- package/src/interfaces/web/src/components/deck/WidgetRow.tsx +100 -0
- package/src/interfaces/web/src/components/layout/Logo.tsx +59 -0
- package/src/interfaces/web/src/components/layout/ProjectAvatar.tsx +116 -0
- package/src/interfaces/web/src/components/layout/ProjectSidebar.tsx +151 -0
- package/src/interfaces/web/src/components/settings/AdvancedPanel.tsx +45 -0
- package/src/interfaces/web/src/components/settings/AppearancePanel.tsx +72 -0
- package/src/interfaces/web/src/components/settings/DefaultRouterCard.tsx +232 -0
- package/src/interfaces/web/src/components/settings/DevicesPanel.tsx +60 -0
- package/src/interfaces/web/src/components/settings/EnginesPanel.tsx +127 -0
- package/src/interfaces/web/src/components/settings/IdentityPanel.tsx +69 -0
- package/src/interfaces/web/src/components/settings/MemoryPanel.tsx +226 -0
- package/src/interfaces/web/src/components/settings/PairDeviceDialog.tsx +175 -0
- package/src/interfaces/web/src/components/settings/SuperAgentPanel.tsx +93 -0
- package/src/interfaces/web/src/components/settings/TelegramChannelsPanel.tsx +90 -0
- package/src/interfaces/web/src/components/settings/TelegramContactsPanel.tsx +101 -0
- package/src/interfaces/web/src/components/settings/TelegramGlobalPanel.tsx +100 -0
- package/src/interfaces/web/src/components/settings/TelegramRolesPanel.tsx +108 -0
- package/src/interfaces/web/src/components/settings/TelegramSettingsTabs.tsx +55 -0
- package/src/interfaces/web/src/components/settings/providers/ProviderCard.tsx +95 -0
- package/src/interfaces/web/src/components/settings/providers/ProviderModal.tsx +405 -0
- package/src/interfaces/web/src/components/settings/providers/typeStyles.ts +155 -0
- package/src/interfaces/web/src/components/settings/providers/types.ts +26 -0
- package/src/interfaces/web/src/components/ui/accordion.tsx +72 -0
- package/src/interfaces/web/src/components/ui/alert-dialog.tsx +187 -0
- package/src/interfaces/web/src/components/ui/alert.tsx +76 -0
- package/src/interfaces/web/src/components/ui/aspect-ratio.tsx +22 -0
- package/src/interfaces/web/src/components/ui/avatar.tsx +107 -0
- package/src/interfaces/web/src/components/ui/badge.tsx +52 -0
- package/src/interfaces/web/src/components/ui/breadcrumb.tsx +125 -0
- package/src/interfaces/web/src/components/ui/button-group.tsx +87 -0
- package/src/interfaces/web/src/components/ui/button.tsx +58 -0
- package/src/interfaces/web/src/components/ui/calendar.tsx +221 -0
- package/src/interfaces/web/src/components/ui/card.tsx +103 -0
- package/src/interfaces/web/src/components/ui/carousel.tsx +242 -0
- package/src/interfaces/web/src/components/ui/chart.tsx +371 -0
- package/src/interfaces/web/src/components/ui/chat-input.tsx +122 -0
- package/src/interfaces/web/src/components/ui/checkbox.tsx +29 -0
- package/src/interfaces/web/src/components/ui/collapsible.tsx +19 -0
- package/src/interfaces/web/src/components/ui/combobox.tsx +295 -0
- package/src/interfaces/web/src/components/ui/command.tsx +196 -0
- package/src/interfaces/web/src/components/ui/context-menu.tsx +271 -0
- package/src/interfaces/web/src/components/ui/dialog.tsx +158 -0
- package/src/interfaces/web/src/components/ui/direction.tsx +4 -0
- package/src/interfaces/web/src/components/ui/drawer.tsx +134 -0
- package/src/interfaces/web/src/components/ui/dropdown-menu.tsx +266 -0
- package/src/interfaces/web/src/components/ui/empty.tsx +104 -0
- package/src/interfaces/web/src/components/ui/field.tsx +236 -0
- package/src/interfaces/web/src/components/ui/hover-card.tsx +51 -0
- package/src/interfaces/web/src/components/ui/input-group.tsx +158 -0
- package/src/interfaces/web/src/components/ui/input-otp.tsx +85 -0
- package/src/interfaces/web/src/components/ui/input.tsx +20 -0
- package/src/interfaces/web/src/components/ui/item.tsx +201 -0
- package/src/interfaces/web/src/components/ui/kbd.tsx +26 -0
- package/src/interfaces/web/src/components/ui/label.tsx +20 -0
- package/src/interfaces/web/src/components/ui/menubar.tsx +280 -0
- package/src/interfaces/web/src/components/ui/native-select.tsx +61 -0
- package/src/interfaces/web/src/components/ui/navigation-menu.tsx +168 -0
- package/src/interfaces/web/src/components/ui/pagination.tsx +130 -0
- package/src/interfaces/web/src/components/ui/popover.tsx +88 -0
- package/src/interfaces/web/src/components/ui/progress.tsx +83 -0
- package/src/interfaces/web/src/components/ui/radio-group.tsx +36 -0
- package/src/interfaces/web/src/components/ui/resizable.tsx +50 -0
- package/src/interfaces/web/src/components/ui/scroll-area.tsx +53 -0
- package/src/interfaces/web/src/components/ui/select.tsx +201 -0
- package/src/interfaces/web/src/components/ui/separator.tsx +23 -0
- package/src/interfaces/web/src/components/ui/sheet.tsx +138 -0
- package/src/interfaces/web/src/components/ui/sidebar.tsx +723 -0
- package/src/interfaces/web/src/components/ui/skeleton.tsx +13 -0
- package/src/interfaces/web/src/components/ui/slider.tsx +52 -0
- package/src/interfaces/web/src/components/ui/sonner.tsx +49 -0
- package/src/interfaces/web/src/components/ui/spinner.tsx +10 -0
- package/src/interfaces/web/src/components/ui/switch.tsx +30 -0
- package/src/interfaces/web/src/components/ui/table.tsx +116 -0
- package/src/interfaces/web/src/components/ui/tabs.tsx +72 -0
- package/src/interfaces/web/src/components/ui/textarea.tsx +18 -0
- package/src/interfaces/web/src/components/ui/tip.tsx +21 -0
- package/src/interfaces/web/src/components/ui/toggle-group.tsx +87 -0
- package/src/interfaces/web/src/components/ui/toggle.tsx +45 -0
- package/src/interfaces/web/src/components/ui/tooltip.tsx +64 -0
- package/src/interfaces/web/src/components/ui.tsx +211 -0
- package/src/interfaces/web/src/components/voice/VoiceProviderList.tsx +197 -0
- package/src/interfaces/web/src/components/voice/VoiceProviderModal.tsx +213 -0
- package/src/interfaces/web/src/components/voice/VoiceSttCard.tsx +72 -0
- package/src/interfaces/web/src/components/voice/VoiceTestCard.tsx +112 -0
- package/src/interfaces/web/src/components/voice/useTtsPlayer.ts +59 -0
- package/src/interfaces/web/src/constants/index.ts +91 -0
- package/src/interfaces/web/src/hooks/use-mobile.ts +19 -0
- package/src/interfaces/web/src/hooks/useChat.ts +276 -0
- package/src/interfaces/web/src/hooks/useDaemonStatus.ts +12 -0
- package/src/interfaces/web/src/hooks/useDevices.ts +12 -0
- package/src/interfaces/web/src/hooks/useEngines.ts +10 -0
- package/src/interfaces/web/src/hooks/useGlobalConfig.ts +24 -0
- package/src/interfaces/web/src/hooks/useIdentity.ts +16 -0
- package/src/interfaces/web/src/hooks/useProjects.ts +27 -0
- package/src/interfaces/web/src/hooks/useTelegram.ts +35 -0
- package/src/interfaces/web/src/hooks/useTheme.tsx +57 -0
- package/src/interfaces/web/src/hooks/useTokenBootstrap.ts +122 -0
- package/src/interfaces/web/src/i18n/en.ts +767 -0
- package/src/interfaces/web/src/i18n/es.ts +770 -0
- package/src/interfaces/web/src/i18n/index.ts +86 -0
- package/src/interfaces/web/src/lib/api/admin.ts +30 -0
- package/src/interfaces/web/src/lib/api/agents.ts +46 -0
- package/src/interfaces/web/src/lib/api/code.ts +122 -0
- package/src/interfaces/web/src/lib/api/conversations.ts +16 -0
- package/src/interfaces/web/src/lib/api/deck.ts +106 -0
- package/src/interfaces/web/src/lib/api/desktop.ts +54 -0
- package/src/interfaces/web/src/lib/api/embeddings.ts +44 -0
- package/src/interfaces/web/src/lib/api/engines.ts +17 -0
- package/src/interfaces/web/src/lib/api/filesystem.ts +12 -0
- package/src/interfaces/web/src/lib/api/health.ts +6 -0
- package/src/interfaces/web/src/lib/api/identity.ts +7 -0
- package/src/interfaces/web/src/lib/api/mcps.ts +29 -0
- package/src/interfaces/web/src/lib/api/messages.ts +24 -0
- package/src/interfaces/web/src/lib/api/projects.ts +29 -0
- package/src/interfaces/web/src/lib/api/routines.ts +14 -0
- package/src/interfaces/web/src/lib/api/sessions.ts +16 -0
- package/src/interfaces/web/src/lib/api/super_agent.ts +29 -0
- package/src/interfaces/web/src/lib/api/tasks.ts +19 -0
- package/src/interfaces/web/src/lib/api/telegram.ts +57 -0
- package/src/interfaces/web/src/lib/api/tools.ts +13 -0
- package/src/interfaces/web/src/lib/api/voice.ts +169 -0
- package/src/interfaces/web/src/lib/api.ts +48 -0
- package/src/interfaces/web/src/lib/cn.ts +6 -0
- package/src/interfaces/web/src/lib/code-context.ts +83 -0
- package/src/interfaces/web/src/lib/config-values.ts +29 -0
- package/src/interfaces/web/src/lib/device.ts +10 -0
- package/src/interfaces/web/src/lib/http.ts +104 -0
- package/src/interfaces/web/src/lib/secrets.ts +15 -0
- package/src/interfaces/web/src/lib/utils.ts +6 -0
- package/src/interfaces/web/src/main.tsx +16 -0
- package/src/interfaces/web/src/screens/ApxAdminScreen.tsx +174 -0
- package/src/interfaces/web/src/screens/PairingScreen.tsx +105 -0
- package/src/interfaces/web/src/screens/ProjectScreen.tsx +178 -0
- package/src/interfaces/web/src/screens/SettingsScreen.tsx +111 -0
- package/src/interfaces/web/src/screens/base/AgentDefaultsTab.tsx +274 -0
- package/src/interfaces/web/src/screens/base/ComingSoon.tsx +16 -0
- package/src/interfaces/web/src/screens/base/GlobalTasksTab.tsx +53 -0
- package/src/interfaces/web/src/screens/base/LogsTab.tsx +188 -0
- package/src/interfaces/web/src/screens/base/ModelsTab.tsx +13 -0
- package/src/interfaces/web/src/screens/base/SessionsTab.tsx +58 -0
- package/src/interfaces/web/src/screens/base/WorkspacesTab.tsx +49 -0
- package/src/interfaces/web/src/screens/modules/CodeScreen.tsx +295 -0
- package/src/interfaces/web/src/screens/modules/DeckScreen.tsx +173 -0
- package/src/interfaces/web/src/screens/modules/DesktopScreen.tsx +304 -0
- package/src/interfaces/web/src/screens/modules/VoiceScreen.tsx +174 -0
- package/src/interfaces/web/src/screens/project/AgentBrainGraph.tsx +152 -0
- package/src/interfaces/web/src/screens/project/AgentDetailScreen.tsx +455 -0
- package/src/interfaces/web/src/screens/project/AgentsTab.tsx +364 -0
- package/src/interfaces/web/src/screens/project/ChatTab.tsx +198 -0
- package/src/interfaces/web/src/screens/project/ConfigTab.tsx +94 -0
- package/src/interfaces/web/src/screens/project/McpsTab.tsx +149 -0
- package/src/interfaces/web/src/screens/project/MemoriesTab.tsx +134 -0
- package/src/interfaces/web/src/screens/project/Overview.tsx +37 -0
- package/src/interfaces/web/src/screens/project/RoutinesTab.tsx +386 -0
- package/src/interfaces/web/src/screens/project/TasksTab.tsx +116 -0
- package/src/interfaces/web/src/screens/project/TelegramTab.tsx +126 -0
- package/src/interfaces/web/src/screens/project/ThreadsTab.tsx +100 -0
- package/src/interfaces/web/src/styles.css +128 -0
- package/src/interfaces/web/src/types/daemon.ts +289 -0
- package/src/interfaces/web/tailwind.config.js +53 -0
- package/src/interfaces/web/tsconfig.json +24 -0
- package/src/interfaces/web/vite.config.ts +50 -0
- package/src/cli/commands/exec.js +0 -56
- package/src/cli/commands/overlay.js +0 -253
- package/src/cli/commands/session.js +0 -395
- package/src/cli/commands/sessions.js +0 -517
- package/src/cli/commands/telegram.js +0 -77
- package/src/cli/postinstall.js +0 -75
- package/src/cli-ts/commands/agent.ts +0 -173
- package/src/cli-ts/commands/chat.ts +0 -119
- package/src/cli-ts/commands/daemon.ts +0 -112
- package/src/cli-ts/commands/exec.ts +0 -109
- package/src/cli-ts/commands/mcp.ts +0 -235
- package/src/cli-ts/commands/session.ts +0 -224
- package/src/cli-ts/commands/status.ts +0 -61
- package/src/cli-ts/http.ts +0 -36
- package/src/cli-ts/index.ts +0 -73
- package/src/cli-ts/ui.ts +0 -107
- package/src/daemon/api.js +0 -1558
- package/src/daemon/engines/gemini.js +0 -56
- package/src/daemon/engines/openai.js +0 -79
- package/src/daemon/mcp-sources.js +0 -114
- package/src/daemon/super-agent-tools/index.js +0 -84
- package/src/daemon/super-agent-tools.js +0 -1
- package/src/daemon/super-agent.js +0 -541
- package/src/overlay/index.html +0 -44
- package/src/overlay/main.js +0 -480
- package/src/overlay/preload.js +0 -34
- package/src/overlay/renderer.js +0 -371
- package/src/overlay/style.css +0 -250
- package/src/tui/context/sync-apx.tsx +0 -284
- package/src/tui/routes/session/index.tsx +0 -274
- package/src/tui/routes/session/sidebar-apx.tsx +0 -90
- /package/src/{daemon → core}/tools/browser.js +0 -0
- /package/src/{daemon → core}/tools/fetch.js +0 -0
- /package/src/{daemon → core}/tools/glob.js +0 -0
- /package/src/{daemon → core}/tools/grep.js +0 -0
- /package/src/{daemon → core}/tools/registry.js +0 -0
- /package/src/{daemon → core}/tools/search.js +0 -0
- /package/src/{daemon → host/daemon}/conversations.js +0 -0
- /package/src/{daemon → host/daemon}/env-detect.js +0 -0
- /package/src/{daemon → host/daemon}/runtimes/_spawn.js +0 -0
- /package/src/{daemon → host/daemon}/runtimes/aider.js +0 -0
- /package/src/{daemon → host/daemon}/runtimes/claude-code.js +0 -0
- /package/src/{daemon → host/daemon}/runtimes/codex.js +0 -0
- /package/src/{daemon → host/daemon}/runtimes/cursor-agent.js +0 -0
- /package/src/{daemon → host/daemon}/runtimes/gemini-cli.js +0 -0
- /package/src/{daemon → host/daemon}/runtimes/index.js +0 -0
- /package/src/{daemon → host/daemon}/runtimes/opencode.js +0 -0
- /package/src/{daemon → host/daemon}/runtimes/qwen-code.js +0 -0
- /package/src/{daemon → host/daemon}/super-agent-tools/tools/call-mcp.js +0 -0
- /package/src/{daemon → host/daemon}/super-agent-tools/tools/edit-file.js +0 -0
- /package/src/{daemon → host/daemon}/super-agent-tools/tools/list-files.js +0 -0
- /package/src/{daemon → host/daemon}/super-agent-tools/tools/list-mcps.js +0 -0
- /package/src/{daemon → host/daemon}/super-agent-tools/tools/list-projects.js +0 -0
- /package/src/{daemon → host/daemon}/super-agent-tools/tools/list-skills.js +0 -0
- /package/src/{daemon → host/daemon}/super-agent-tools/tools/load-skill.js +0 -0
- /package/src/{daemon → host/daemon}/super-agent-tools/tools/read-agent-memory.js +0 -0
- /package/src/{daemon → host/daemon}/super-agent-tools/tools/read-file.js +0 -0
- /package/src/{daemon → host/daemon}/super-agent-tools/tools/run-shell.js +0 -0
- /package/src/{daemon → host/daemon}/super-agent-tools/tools/search-files.js +0 -0
- /package/src/{daemon → host/daemon}/super-agent-tools/tools/transcribe-audio.js +0 -0
- /package/src/{daemon → host/daemon}/super-agent-tools/tools/write-file.js +0 -0
- /package/src/{daemon → host/daemon}/thinking.js +0 -0
- /package/src/{daemon → host/daemon}/whisper-server.py +0 -0
- /package/src/{daemon → host/daemon}/whisper-transcribe.py +0 -0
- /package/src/{cli → interfaces/cli}/commands/a2a.js +0 -0
- /package/src/{cli → interfaces/cli}/commands/artifact.js +0 -0
- /package/src/{cli → interfaces/cli}/commands/chat.js +0 -0
- /package/src/{cli → interfaces/cli}/commands/log.js +0 -0
- /package/src/{cli → interfaces/cli}/commands/messages.js +0 -0
- /package/src/{cli → interfaces/cli}/commands/plugins.js +0 -0
- /package/src/{cli → interfaces/cli}/commands/routine.js +0 -0
- /package/src/{cli → interfaces/cli}/commands/runtime.js +0 -0
- /package/src/{cli → interfaces/cli}/terminal-chat/renderer.js +0 -0
- /package/src/{overlay → interfaces/desktop}/package.json +0 -0
- /package/src/{tui → interfaces/tui}/_shims/cli-error.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/cli-logo.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/cli-ui.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/config-console-state.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/core-any.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/core-binary.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/core-flag.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/core-log.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/lsp-language.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/opencode-any.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/opencode-sdk-v2.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/plugin-tui.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/prompt-display.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/provider-provider.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/session-retry.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/session-schema.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/session-session.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/snapshot.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/tool-any.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/util-error.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/util-filesystem.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/util-format.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/util-iife.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/util-locale.ts +0 -0
- /package/src/{tui → interfaces/tui}/_shims/util-process.ts +0 -0
- /package/src/{tui → interfaces/tui}/asset/charge.wav +0 -0
- /package/src/{tui → interfaces/tui}/asset/pulse-a.wav +0 -0
- /package/src/{tui → interfaces/tui}/asset/pulse-b.wav +0 -0
- /package/src/{tui → interfaces/tui}/asset/pulse-c.wav +0 -0
- /package/src/{tui → interfaces/tui}/attach.ts +0 -0
- /package/src/{tui → interfaces/tui}/component/bg-pulse-render.ts +0 -0
- /package/src/{tui → interfaces/tui}/component/bg-pulse.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/border.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/dialog-agent.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/dialog-console-org.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/dialog-mcp.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/dialog-model.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/dialog-provider.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/dialog-retry-action.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/dialog-session-delete-failed.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/dialog-session-list.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/dialog-session-rename.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/dialog-skill.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/dialog-stash.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/dialog-status.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/dialog-tag.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/dialog-theme-list.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/dialog-variant.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/dialog-workspace-create.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/dialog-workspace-file-changes.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/dialog-workspace-unavailable.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/error-component.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/logo.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/plugin-route-missing.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/prompt/autocomplete.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/prompt/cwd.ts +0 -0
- /package/src/{tui → interfaces/tui}/component/prompt/frecency.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/prompt/history.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/prompt/part.ts +0 -0
- /package/src/{tui → interfaces/tui}/component/prompt/stash.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/prompt/traits.ts +0 -0
- /package/src/{tui → interfaces/tui}/component/spinner.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/startup-loading.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/todo-item.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/use-connected.tsx +0 -0
- /package/src/{tui → interfaces/tui}/component/workspace-label.tsx +0 -0
- /package/src/{tui → interfaces/tui}/config/cwd.ts +0 -0
- /package/src/{tui → interfaces/tui}/config/keybind.ts +0 -0
- /package/src/{tui → interfaces/tui}/config/tui-migrate.ts +0 -0
- /package/src/{tui → interfaces/tui}/config/tui-schema.ts +0 -0
- /package/src/{tui → interfaces/tui}/config/tui.ts +0 -0
- /package/src/{tui → interfaces/tui}/context/aggregate-failures.ts +0 -0
- /package/src/{tui → interfaces/tui}/context/args.tsx +0 -0
- /package/src/{tui → interfaces/tui}/context/command-palette.tsx +0 -0
- /package/src/{tui → interfaces/tui}/context/directory.ts +0 -0
- /package/src/{tui → interfaces/tui}/context/editor-zed.ts +0 -0
- /package/src/{tui → interfaces/tui}/context/editor.ts +0 -0
- /package/src/{tui → interfaces/tui}/context/event-apx.ts +0 -0
- /package/src/{tui → interfaces/tui}/context/event.ts +0 -0
- /package/src/{tui → interfaces/tui}/context/exit.tsx +0 -0
- /package/src/{tui → interfaces/tui}/context/helper.tsx +0 -0
- /package/src/{tui → interfaces/tui}/context/kv.tsx +0 -0
- /package/src/{tui → interfaces/tui}/context/local.tsx +0 -0
- /package/src/{tui → interfaces/tui}/context/path-format.tsx +0 -0
- /package/src/{tui → interfaces/tui}/context/project-apx.tsx +0 -0
- /package/src/{tui → interfaces/tui}/context/project.tsx +0 -0
- /package/src/{tui → interfaces/tui}/context/prompt.tsx +0 -0
- /package/src/{tui → interfaces/tui}/context/route.tsx +0 -0
- /package/src/{tui → interfaces/tui}/context/sdk.tsx +0 -0
- /package/src/{tui → interfaces/tui}/context/sync-v2.tsx +0 -0
- /package/src/{tui → interfaces/tui}/context/sync.tsx +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/aura.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/ayu.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/carbonfox.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/catppuccin-frappe.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/catppuccin-macchiato.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/catppuccin.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/cobalt2.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/cursor.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/dracula.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/everforest.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/flexoki.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/github.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/gruvbox.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/kanagawa.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/lucent-orng.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/material.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/matrix.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/mercury.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/monokai.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/nightowl.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/nord.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/one-dark.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/opencode.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/orng.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/osaka-jade.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/palenight.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/rosepine.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/solarized.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/synthwave84.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/tokyonight.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/vercel.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/vesper.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme/zenburn.json +0 -0
- /package/src/{tui → interfaces/tui}/context/theme.tsx +0 -0
- /package/src/{tui → interfaces/tui}/context/tui-config.tsx +0 -0
- /package/src/{tui → interfaces/tui}/event.ts +0 -0
- /package/src/{tui → interfaces/tui}/feature-plugins/home/footer.tsx +0 -0
- /package/src/{tui → interfaces/tui}/feature-plugins/home/tips-view.tsx +0 -0
- /package/src/{tui → interfaces/tui}/feature-plugins/home/tips.tsx +0 -0
- /package/src/{tui → interfaces/tui}/feature-plugins/sidebar/context.tsx +0 -0
- /package/src/{tui → interfaces/tui}/feature-plugins/sidebar/files.tsx +0 -0
- /package/src/{tui → interfaces/tui}/feature-plugins/sidebar/footer.tsx +0 -0
- /package/src/{tui → interfaces/tui}/feature-plugins/sidebar/lsp.tsx +0 -0
- /package/src/{tui → interfaces/tui}/feature-plugins/sidebar/mcp.tsx +0 -0
- /package/src/{tui → interfaces/tui}/feature-plugins/sidebar/todo.tsx +0 -0
- /package/src/{tui → interfaces/tui}/feature-plugins/system/plugins.tsx +0 -0
- /package/src/{tui → interfaces/tui}/feature-plugins/system/session-v2.tsx +0 -0
- /package/src/{tui → interfaces/tui}/feature-plugins/system/which-key.tsx +0 -0
- /package/src/{tui → interfaces/tui}/keymap.tsx +0 -0
- /package/src/{tui → interfaces/tui}/layer.ts +0 -0
- /package/src/{tui → interfaces/tui}/plugin/api.tsx +0 -0
- /package/src/{tui → interfaces/tui}/plugin/command-shim.ts +0 -0
- /package/src/{tui → interfaces/tui}/plugin/internal.ts +0 -0
- /package/src/{tui → interfaces/tui}/plugin/runtime.ts +0 -0
- /package/src/{tui → interfaces/tui}/plugin/slots.tsx +0 -0
- /package/src/{tui → interfaces/tui}/routes/home.tsx +0 -0
- /package/src/{tui → interfaces/tui}/routes/session/dialog-fork-from-timeline.tsx +0 -0
- /package/src/{tui → interfaces/tui}/routes/session/dialog-message.tsx +0 -0
- /package/src/{tui → interfaces/tui}/routes/session/dialog-subagent.tsx +0 -0
- /package/src/{tui → interfaces/tui}/routes/session/dialog-timeline.tsx +0 -0
- /package/src/{tui → interfaces/tui}/routes/session/footer.tsx +0 -0
- /package/src/{tui → interfaces/tui}/routes/session/permission.tsx +0 -0
- /package/src/{tui → interfaces/tui}/routes/session/question.tsx +0 -0
- /package/src/{tui → interfaces/tui}/routes/session/sidebar.tsx +0 -0
- /package/src/{tui → interfaces/tui}/routes/session/subagent-footer.tsx +0 -0
- /package/src/{tui → interfaces/tui}/run.ts +0 -0
- /package/src/{tui → interfaces/tui}/thread.ts +0 -0
- /package/src/{tui → interfaces/tui}/ui/dialog-alert.tsx +0 -0
- /package/src/{tui → interfaces/tui}/ui/dialog-confirm.tsx +0 -0
- /package/src/{tui → interfaces/tui}/ui/dialog-export-options.tsx +0 -0
- /package/src/{tui → interfaces/tui}/ui/dialog-help.tsx +0 -0
- /package/src/{tui → interfaces/tui}/ui/dialog-prompt.tsx +0 -0
- /package/src/{tui → interfaces/tui}/ui/dialog-select.tsx +0 -0
- /package/src/{tui → interfaces/tui}/ui/dialog.tsx +0 -0
- /package/src/{tui → interfaces/tui}/ui/link.tsx +0 -0
- /package/src/{tui → interfaces/tui}/ui/spinner.ts +0 -0
- /package/src/{tui → interfaces/tui}/ui/toast.tsx +0 -0
- /package/src/{tui → interfaces/tui}/util/editor.ts +0 -0
- /package/src/{tui → interfaces/tui}/util/model.ts +0 -0
- /package/src/{tui → interfaces/tui}/util/provider-origin.ts +0 -0
- /package/src/{tui → interfaces/tui}/util/revert-diff.ts +0 -0
- /package/src/{tui → interfaces/tui}/util/scroll.ts +0 -0
- /package/src/{tui → interfaces/tui}/util/selection.ts +0 -0
- /package/src/{tui → interfaces/tui}/util/signal.ts +0 -0
- /package/src/{tui → interfaces/tui}/util/sound.ts +0 -0
- /package/src/{tui → interfaces/tui}/util/transcript.ts +0 -0
- /package/src/{tui → interfaces/tui}/validate-session.ts +0 -0
- /package/src/{tui → interfaces/tui}/win32.ts +0 -0
- /package/src/{tui → interfaces/tui}/worker.ts +0 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
// Text embeddings for the cross-channel memory RAG (Pieza 2).
|
|
2
|
+
//
|
|
3
|
+
// The provider is configurable (config.memory.embeddings) and resolved through
|
|
4
|
+
// the engine registry at ./embed-engines — exactly like TTS/STT. Ships with
|
|
5
|
+
// ollama (local, default), openai, gemini, and the offline tf fallback. Pick
|
|
6
|
+
// "auto" (chain router) or a single provider; an explicit `provider` opt wins.
|
|
7
|
+
//
|
|
8
|
+
// Fallback: a deterministic, dependency-free feature-hashing term-frequency
|
|
9
|
+
// vector ("tf"). It is NOT as good as a real embedding, but it keeps the
|
|
10
|
+
// retriever working when no provider is reachable — the whole memory system
|
|
11
|
+
// must degrade gracefully, never throw into the daemon's request path.
|
|
12
|
+
//
|
|
13
|
+
// Every vector is tagged with the `embedder` that produced it (e.g.
|
|
14
|
+
// "ollama:nomic-embed-text", "openai:text-embedding-3-small", or "tf") and its
|
|
15
|
+
// `dim`. Cosine similarity is only meaningful within one embedder space, so
|
|
16
|
+
// callers must compare like with like (the store records the tag per row and
|
|
17
|
+
// the broker filters on it).
|
|
18
|
+
|
|
19
|
+
// NOTE: this module is the leaf the engine adapters import (l2normalize /
|
|
20
|
+
// tfEmbed). It also imports the registry — ESM live bindings make this safe
|
|
21
|
+
// because selectEmbedEngine is only referenced at call time, never at init.
|
|
22
|
+
import { selectEmbedEngine } from "./embed-engines/index.js";
|
|
23
|
+
|
|
24
|
+
const TF_DIM = 256;
|
|
25
|
+
|
|
26
|
+
// Deterministic 32-bit string hash (FNV-1a). Used to bucket tokens for the TF
|
|
27
|
+
// fallback embedder.
|
|
28
|
+
function fnv1a(str) {
|
|
29
|
+
let h = 0x811c9dc5;
|
|
30
|
+
for (let i = 0; i < str.length; i++) {
|
|
31
|
+
h ^= str.charCodeAt(i);
|
|
32
|
+
h = Math.imul(h, 0x01000193);
|
|
33
|
+
}
|
|
34
|
+
return h >>> 0;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function tokenize(text) {
|
|
38
|
+
return String(text || "")
|
|
39
|
+
.toLowerCase()
|
|
40
|
+
.normalize("NFKD")
|
|
41
|
+
.replace(/[̀-ͯ]/g, "")
|
|
42
|
+
.split(/[^a-z0-9_]+/)
|
|
43
|
+
.filter((t) => t.length >= 2 && t.length <= 40);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Feature-hashing TF vector, L2-normalised. Deterministic and offline.
|
|
47
|
+
export function tfEmbed(text, dim = TF_DIM) {
|
|
48
|
+
const counts = new Map();
|
|
49
|
+
for (const tok of tokenize(text)) {
|
|
50
|
+
const bucket = fnv1a(tok) % dim;
|
|
51
|
+
counts.set(bucket, (counts.get(bucket) || 0) + 1);
|
|
52
|
+
}
|
|
53
|
+
const vec = new Array(dim).fill(0);
|
|
54
|
+
for (const [bucket, c] of counts) {
|
|
55
|
+
// Sublinear TF scaling so a repeated word doesn't dominate.
|
|
56
|
+
vec[bucket] = 1 + Math.log(c);
|
|
57
|
+
}
|
|
58
|
+
return l2normalize(vec);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function l2normalize(vec) {
|
|
62
|
+
let norm = 0;
|
|
63
|
+
for (const v of vec) norm += v * v;
|
|
64
|
+
norm = Math.sqrt(norm);
|
|
65
|
+
if (norm === 0) return vec;
|
|
66
|
+
return vec.map((v) => v / norm);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function cosineSim(a, b) {
|
|
70
|
+
if (!a || !b || a.length !== b.length) return 0;
|
|
71
|
+
let dot = 0;
|
|
72
|
+
for (let i = 0; i < a.length; i++) dot += a[i] * b[i];
|
|
73
|
+
return dot; // both vectors are L2-normalised, so dot == cosine
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Embed a single string. Never throws — falls back to the offline TF embedder
|
|
77
|
+
// on any provider error/timeout. Returns { vector, embedder, dim }.
|
|
78
|
+
//
|
|
79
|
+
// opts: { globalConfig, provider, forceTf, timeoutMs, signal }
|
|
80
|
+
// - globalConfig: read config.memory.embeddings to pick the provider
|
|
81
|
+
// - provider: explicit override ("ollama"|"openai"|"gemini"|"tf"); wins over config
|
|
82
|
+
// - forceTf: skip the provider, use the offline embedder (batch fast-path)
|
|
83
|
+
function tfResult(text) {
|
|
84
|
+
const v = tfEmbed(text);
|
|
85
|
+
return { vector: v, embedder: "tf", dim: v.length };
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export async function embedOne(text, opts = {}) {
|
|
89
|
+
const clean = String(text || "").slice(0, 8000);
|
|
90
|
+
if (!clean.trim()) return tfResult("");
|
|
91
|
+
if (opts.forceTf) return tfResult(clean);
|
|
92
|
+
|
|
93
|
+
let adapter, engineConfig;
|
|
94
|
+
try {
|
|
95
|
+
({ adapter, engineConfig } = await selectEmbedEngine({
|
|
96
|
+
globalConfig: opts.globalConfig,
|
|
97
|
+
provider: opts.provider,
|
|
98
|
+
}));
|
|
99
|
+
} catch {
|
|
100
|
+
return tfResult(clean);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const timeoutMs = opts.timeoutMs || engineConfig?.timeout_ms || 4000;
|
|
104
|
+
try {
|
|
105
|
+
const out = await adapter.embed({
|
|
106
|
+
text: clean,
|
|
107
|
+
config: engineConfig || {},
|
|
108
|
+
parentEnginesCfg: opts.globalConfig?.engines,
|
|
109
|
+
timeoutMs,
|
|
110
|
+
signal: opts.signal,
|
|
111
|
+
});
|
|
112
|
+
if (!out || !Array.isArray(out.vector) || out.vector.length === 0) return tfResult(clean);
|
|
113
|
+
return out;
|
|
114
|
+
} catch {
|
|
115
|
+
return tfResult(clean);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Embed many strings. Probes the provider once with the first item; if that
|
|
120
|
+
// falls back to TF, the rest go straight to TF (so a down host doesn't cost
|
|
121
|
+
// one timeout per chunk). Returns an array of { vector, embedder, dim }.
|
|
122
|
+
export async function embedBatch(texts, opts = {}) {
|
|
123
|
+
const list = Array.isArray(texts) ? texts : [texts];
|
|
124
|
+
if (list.length === 0) return [];
|
|
125
|
+
const first = await embedOne(list[0], opts);
|
|
126
|
+
const out = [first];
|
|
127
|
+
const forceTf = first.embedder === "tf" ? { ...opts, forceTf: true } : opts;
|
|
128
|
+
for (let i = 1; i < list.length; i++) {
|
|
129
|
+
out.push(await embedOne(list[i], forceTf));
|
|
130
|
+
}
|
|
131
|
+
return out;
|
|
132
|
+
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
// Cross-channel memory subsystem — public surface + lifecycle.
|
|
2
|
+
//
|
|
3
|
+
// Pieces:
|
|
4
|
+
// 1. Auto-write → ~/.apx/memory.md (self-memory.js + the `remember` tool)
|
|
5
|
+
// 2. RAG → embeddings.js + store.js + indexer.js (this module owns
|
|
6
|
+
// the store singleton and the incremental index timer)
|
|
7
|
+
// 3. Compaction → compactor.js (+ messages-store reader changes)
|
|
8
|
+
// 4. Broker → broker.js (memoryBlockFor below)
|
|
9
|
+
//
|
|
10
|
+
// Everything is best-effort and degrades gracefully: if the store can't open,
|
|
11
|
+
// if Ollama is down, or if anything throws, the daemon keeps serving — the
|
|
12
|
+
// affected piece simply contributes nothing.
|
|
13
|
+
|
|
14
|
+
import path from "node:path";
|
|
15
|
+
import { APX_HOME } from "../config.js";
|
|
16
|
+
import { ensureSelfMemoryFile } from "../agent/self-memory.js";
|
|
17
|
+
import fs from "node:fs";
|
|
18
|
+
import { openMemoryStore } from "./store.js";
|
|
19
|
+
import { indexNewMessages, CURSOR_PATH } from "./indexer.js";
|
|
20
|
+
import { buildMemoryBlock } from "./broker.js";
|
|
21
|
+
import { compactChannelIfNeeded } from "./compactor.js";
|
|
22
|
+
import { buildActiveThreadsBlock } from "./active-threads.js";
|
|
23
|
+
|
|
24
|
+
export { compactChannelIfNeeded, buildActiveThreadsBlock };
|
|
25
|
+
|
|
26
|
+
const DB_PATH = path.join(APX_HOME, "memory.db");
|
|
27
|
+
const JSON_PATH = path.join(APX_HOME, "memory-index.jsonl");
|
|
28
|
+
|
|
29
|
+
let _store = null;
|
|
30
|
+
let _ready = null;
|
|
31
|
+
let _timer = null;
|
|
32
|
+
let _cfg = {};
|
|
33
|
+
let _indexing = false;
|
|
34
|
+
|
|
35
|
+
// Run one index pass unless one is already in flight (a full re-embed can take
|
|
36
|
+
// longer than the timer interval — overlapping passes would race on clear()).
|
|
37
|
+
function indexOnce(note) {
|
|
38
|
+
if (_indexing || !_store) return Promise.resolve();
|
|
39
|
+
_indexing = true;
|
|
40
|
+
return indexNewMessages(_store, { embed: embedOptsFromConfig(_cfg), log: note })
|
|
41
|
+
.catch(() => {})
|
|
42
|
+
.finally(() => {
|
|
43
|
+
_indexing = false;
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function memoryEnabled(config) {
|
|
48
|
+
return config?.memory?.enabled !== false;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// The embeddings provider is resolved from config.memory.embeddings inside
|
|
52
|
+
// embedOne/embedBatch via the engine registry — so all we forward here is the
|
|
53
|
+
// live config. (Legacy memory.embed_* keys are still honored by the registry's
|
|
54
|
+
// back-compat shim in embed-engines/index.js.)
|
|
55
|
+
function embedOptsFromConfig(config) {
|
|
56
|
+
return { globalConfig: config };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Boot the subsystem (Pieza 1 file creation + Pieza 2 store/index). Safe to
|
|
60
|
+
// call once from the daemon. Never throws.
|
|
61
|
+
export async function initMemory({ config, log } = {}) {
|
|
62
|
+
const note = typeof log === "function" ? log : () => {};
|
|
63
|
+
try {
|
|
64
|
+
const created = ensureSelfMemoryFile();
|
|
65
|
+
if (created) note("memory: created ~/.apx/memory.md");
|
|
66
|
+
} catch {
|
|
67
|
+
/* best-effort */
|
|
68
|
+
}
|
|
69
|
+
if (!memoryEnabled(config)) {
|
|
70
|
+
note("memory: RAG disabled by config (memory.enabled=false)");
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
_cfg = config || {};
|
|
74
|
+
_ready = (async () => {
|
|
75
|
+
try {
|
|
76
|
+
_store = await openMemoryStore({ dbPath: DB_PATH, jsonPath: JSON_PATH, log: note });
|
|
77
|
+
// Initial index in the background — never blocks boot.
|
|
78
|
+
indexOnce(note);
|
|
79
|
+
return _store;
|
|
80
|
+
} catch (e) {
|
|
81
|
+
note(`memory: store init failed (${e?.message || e})`);
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
})();
|
|
85
|
+
|
|
86
|
+
const everyMs = (config?.memory?.index_interval_s || 60) * 1000;
|
|
87
|
+
_timer = setInterval(() => indexOnce(note), everyMs);
|
|
88
|
+
if (_timer.unref) _timer.unref();
|
|
89
|
+
|
|
90
|
+
return _ready;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Rebuild the vector store from scratch under the CURRENTLY configured embedder.
|
|
94
|
+
// Switching provider/model changes the embedder space, which makes old rows
|
|
95
|
+
// (tagged with the previous embedder) invisible to new queries — they're not
|
|
96
|
+
// re-embedded incrementally because the cursor marks them as already indexed.
|
|
97
|
+
// This clears the store + cursor and re-embeds every message. Never throws.
|
|
98
|
+
export async function reindexMemory({ config } = {}) {
|
|
99
|
+
if (config) _cfg = config;
|
|
100
|
+
const store = await getMemoryStore();
|
|
101
|
+
if (!store) return { cleared: false, indexed: 0, error: "store unavailable" };
|
|
102
|
+
const before = store.count();
|
|
103
|
+
try {
|
|
104
|
+
store.clear();
|
|
105
|
+
} catch {
|
|
106
|
+
/* best-effort */
|
|
107
|
+
}
|
|
108
|
+
try {
|
|
109
|
+
fs.rmSync(CURSOR_PATH, { force: true });
|
|
110
|
+
} catch {
|
|
111
|
+
/* best-effort */
|
|
112
|
+
}
|
|
113
|
+
await indexNewMessages(store, { embed: embedOptsFromConfig(_cfg), log: () => {} }).catch(() => {});
|
|
114
|
+
return { cleared: before, indexed: store.count() };
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export async function getMemoryStore() {
|
|
118
|
+
if (_ready) {
|
|
119
|
+
try {
|
|
120
|
+
return await _ready;
|
|
121
|
+
} catch {
|
|
122
|
+
return _store;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return _store;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export function stopMemory() {
|
|
129
|
+
if (_timer) {
|
|
130
|
+
clearInterval(_timer);
|
|
131
|
+
_timer = null;
|
|
132
|
+
}
|
|
133
|
+
if (_store) {
|
|
134
|
+
try {
|
|
135
|
+
_store.close();
|
|
136
|
+
} catch {
|
|
137
|
+
/* ignore */
|
|
138
|
+
}
|
|
139
|
+
_store = null;
|
|
140
|
+
}
|
|
141
|
+
_ready = null;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Build the [MEMORIA RELEVANTE] block for a turn (Pieza 4). Never throws —
|
|
145
|
+
// returns "" on any failure so the prompt builder can drop the block.
|
|
146
|
+
export async function memoryBlockFor(message, { config, channel, budgetMs } = {}) {
|
|
147
|
+
try {
|
|
148
|
+
if (!memoryEnabled(config)) return "";
|
|
149
|
+
const store = await getMemoryStore();
|
|
150
|
+
return await buildMemoryBlock(message, {
|
|
151
|
+
store,
|
|
152
|
+
config,
|
|
153
|
+
channel,
|
|
154
|
+
budgetMs: budgetMs || config?.memory?.broker_budget_ms || 800,
|
|
155
|
+
topK: config?.memory?.rag_top_k || 5,
|
|
156
|
+
embed: embedOptsFromConfig(config),
|
|
157
|
+
});
|
|
158
|
+
} catch {
|
|
159
|
+
return "";
|
|
160
|
+
}
|
|
161
|
+
}
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
// Incremental indexer for the cross-channel memory RAG (Pieza 2).
|
|
2
|
+
//
|
|
3
|
+
// Walks ~/.apx/messages/<channel>/YYYY-MM-DD.jsonl for every channel (telegram,
|
|
4
|
+
// web, deck, voice, …) plus ~/.apx/memory.md, turns each relevant record into a
|
|
5
|
+
// chunk, embeds the NEW ones, and upserts them into the vector store.
|
|
6
|
+
//
|
|
7
|
+
// Incremental: a cursor file (~/.apx/memory-cursor.json) records the last
|
|
8
|
+
// indexed timestamp per channel, so each run only embeds messages newer than
|
|
9
|
+
// the last one. memory.md entries are re-derived every run but keyed by a
|
|
10
|
+
// content hash, so re-indexing them is idempotent (cheap, few entries).
|
|
11
|
+
//
|
|
12
|
+
// What gets indexed:
|
|
13
|
+
// - type:"user" and type:"agent" turns (full body, capped)
|
|
14
|
+
// - type:"tool" results, truncated to 400 chars, tagged [tool:<name>]
|
|
15
|
+
// - memory.md entries as separate chunks tagged [memory]
|
|
16
|
+
//
|
|
17
|
+
// Everything is best-effort — a failure logs and returns, never throws into the
|
|
18
|
+
// daemon.
|
|
19
|
+
|
|
20
|
+
import fs from "node:fs";
|
|
21
|
+
import path from "node:path";
|
|
22
|
+
import { GLOBAL_MESSAGES_DIR, APX_HOME } from "../config.js";
|
|
23
|
+
import { SELF_MEMORY_PATH, parseSelfMemoryEntries } from "../agent/self-memory.js";
|
|
24
|
+
import { embedBatch, embedOne } from "./embeddings.js";
|
|
25
|
+
|
|
26
|
+
export const CURSOR_PATH = path.join(APX_HOME, "memory-cursor.json");
|
|
27
|
+
|
|
28
|
+
const BODY_CAP = 1200; // chars kept per user/agent chunk
|
|
29
|
+
const TOOL_CAP = 400; // chars kept per tool-result chunk
|
|
30
|
+
|
|
31
|
+
function fnv1aHex(str) {
|
|
32
|
+
let h = 0x811c9dc5;
|
|
33
|
+
for (let i = 0; i < str.length; i++) {
|
|
34
|
+
h ^= str.charCodeAt(i);
|
|
35
|
+
h = Math.imul(h, 0x01000193);
|
|
36
|
+
}
|
|
37
|
+
return (h >>> 0).toString(16);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function readCursor(cursorPath) {
|
|
41
|
+
try {
|
|
42
|
+
return JSON.parse(fs.readFileSync(cursorPath, "utf8"));
|
|
43
|
+
} catch {
|
|
44
|
+
return { channels: {} };
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function writeCursor(cursorPath, cursor) {
|
|
49
|
+
try {
|
|
50
|
+
fs.mkdirSync(path.dirname(cursorPath), { recursive: true });
|
|
51
|
+
const tmp = `${cursorPath}.tmp`;
|
|
52
|
+
fs.writeFileSync(tmp, JSON.stringify(cursor, null, 2));
|
|
53
|
+
fs.renameSync(tmp, cursorPath);
|
|
54
|
+
} catch {
|
|
55
|
+
/* best-effort */
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Parse one .jsonl line into a minimal record we care about.
|
|
60
|
+
function parseLine(line) {
|
|
61
|
+
const t = line.trim();
|
|
62
|
+
if (!t) return null;
|
|
63
|
+
try {
|
|
64
|
+
return JSON.parse(t);
|
|
65
|
+
} catch {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Worth indexing? Skip trivial/noise turns ("ok", "?", "}", a lone emoji,
|
|
71
|
+
// "/reset") — they pollute retrieval (especially under the TF fallback) without
|
|
72
|
+
// carrying recallable content. Require some real text: ≥12 chars and ≥2
|
|
73
|
+
// word-tokens.
|
|
74
|
+
function meaningfulBody(body) {
|
|
75
|
+
const t = String(body || "").trim();
|
|
76
|
+
if (t.length < 12) return false;
|
|
77
|
+
if (/^\/(reset|new|start|help)\b/i.test(t)) return false;
|
|
78
|
+
const words = t.match(/[\p{L}\p{N}]{2,}/gu) || [];
|
|
79
|
+
return words.length >= 2;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Build a chunk {id, source, channel, ts, tag, text} from a raw message record,
|
|
83
|
+
// or null if it shouldn't be indexed.
|
|
84
|
+
function chunkFromMessage(obj, channel) {
|
|
85
|
+
const meta = obj.meta || {};
|
|
86
|
+
const type = obj.type || meta.type;
|
|
87
|
+
const body = String(obj.body || "").trim();
|
|
88
|
+
if (!body || !meaningfulBody(body)) return null;
|
|
89
|
+
const ts = obj.ts || "";
|
|
90
|
+
const idBase = `${channel}:${ts}:${meta.message_id ?? meta.external_id ?? fnv1aHex(body)}`;
|
|
91
|
+
if (type === "user" || type === "agent") {
|
|
92
|
+
return {
|
|
93
|
+
id: `msg:${idBase}`,
|
|
94
|
+
source: "message",
|
|
95
|
+
channel,
|
|
96
|
+
ts,
|
|
97
|
+
tag: type,
|
|
98
|
+
text: body.slice(0, BODY_CAP),
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
if (type === "tool") {
|
|
102
|
+
const toolName = meta.tool_name || meta.tool || "tool";
|
|
103
|
+
return {
|
|
104
|
+
id: `tool:${idBase}`,
|
|
105
|
+
source: "message",
|
|
106
|
+
channel,
|
|
107
|
+
ts,
|
|
108
|
+
tag: `tool:${toolName}`,
|
|
109
|
+
text: `[tool result: ${toolName}] ${body}`.slice(0, TOOL_CAP),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Collect new (not-yet-indexed) chunks from all channel message files.
|
|
116
|
+
function collectMessageChunks(store, cursor, messagesDir) {
|
|
117
|
+
const fresh = [];
|
|
118
|
+
const maxTsByChannel = {};
|
|
119
|
+
if (!fs.existsSync(messagesDir)) return { fresh, maxTsByChannel };
|
|
120
|
+
for (const channel of fs.readdirSync(messagesDir)) {
|
|
121
|
+
const dir = path.join(messagesDir, channel);
|
|
122
|
+
let stat;
|
|
123
|
+
try {
|
|
124
|
+
stat = fs.statSync(dir);
|
|
125
|
+
} catch {
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
if (!stat.isDirectory()) continue;
|
|
129
|
+
const since = cursor.channels?.[channel] || "";
|
|
130
|
+
let maxTs = since;
|
|
131
|
+
for (const f of fs.readdirSync(dir).sort()) {
|
|
132
|
+
if (!/^\d{4}-\d{2}-\d{2}\.jsonl$/.test(f)) continue;
|
|
133
|
+
// Skip whole day files older than the cursor day.
|
|
134
|
+
if (since && f.slice(0, 10) < since.slice(0, 10)) continue;
|
|
135
|
+
let text;
|
|
136
|
+
try {
|
|
137
|
+
text = fs.readFileSync(path.join(dir, f), "utf8");
|
|
138
|
+
} catch {
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
for (const line of text.split("\n")) {
|
|
142
|
+
const obj = parseLine(line);
|
|
143
|
+
if (!obj || !obj.ts) continue;
|
|
144
|
+
if (since && obj.ts <= since) continue;
|
|
145
|
+
if (obj.ts > maxTs) maxTs = obj.ts;
|
|
146
|
+
const chunk = chunkFromMessage(obj, channel);
|
|
147
|
+
if (chunk && !store.hasId(chunk.id)) fresh.push(chunk);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
if (maxTs) maxTsByChannel[channel] = maxTs;
|
|
151
|
+
}
|
|
152
|
+
return { fresh, maxTsByChannel };
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Collect memory.md entries as chunks (idempotent — keyed by content hash).
|
|
156
|
+
function collectMemoryChunks(store, memoryPath) {
|
|
157
|
+
const fresh = [];
|
|
158
|
+
let entries = [];
|
|
159
|
+
try {
|
|
160
|
+
const text = fs.readFileSync(memoryPath, "utf8");
|
|
161
|
+
entries = parseSelfMemoryEntries(text);
|
|
162
|
+
} catch {
|
|
163
|
+
return fresh;
|
|
164
|
+
}
|
|
165
|
+
for (const e of entries) {
|
|
166
|
+
const id = `memory:${e.date || "0"}:${fnv1aHex(e.text)}`;
|
|
167
|
+
if (store.hasId(id)) continue;
|
|
168
|
+
fresh.push({
|
|
169
|
+
id,
|
|
170
|
+
source: "memory",
|
|
171
|
+
channel: e.channel || "memory",
|
|
172
|
+
ts: e.ts || (e.date ? `${e.date}T00:00:00Z` : ""),
|
|
173
|
+
tag: "memory",
|
|
174
|
+
text: e.text.slice(0, BODY_CAP),
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
return fresh;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Run one incremental indexing pass. Returns { indexed, backend }.
|
|
181
|
+
// `opts.embed` overrides embedding options (baseUrl/model/timeoutMs) for tests.
|
|
182
|
+
export async function indexNewMessages(store, opts = {}) {
|
|
183
|
+
const log = typeof opts.log === "function" ? opts.log : () => {};
|
|
184
|
+
const cursorPath = opts.cursorPath || CURSOR_PATH;
|
|
185
|
+
const messagesDir = opts.messagesDir || GLOBAL_MESSAGES_DIR;
|
|
186
|
+
const memoryPath = opts.memoryPath || SELF_MEMORY_PATH;
|
|
187
|
+
const embedOpts = opts.embed || {};
|
|
188
|
+
const limit = opts.limit || 1000;
|
|
189
|
+
|
|
190
|
+
const cursor = readCursor(cursorPath);
|
|
191
|
+
cursor.channels = cursor.channels || {};
|
|
192
|
+
|
|
193
|
+
// Embedder-consistency guard. Cosine only works within one embedder space, so
|
|
194
|
+
// the whole store must share an embedder family ("ollama" vs "tf"). Probe the
|
|
195
|
+
// currently-active embedder and reconcile:
|
|
196
|
+
// - upgrade (tf → ollama, i.e. Ollama came back): wipe + full re-index so
|
|
197
|
+
// the history is re-embedded in the better space.
|
|
198
|
+
// - downgrade (ollama → tf, i.e. Ollama went down): skip this pass entirely
|
|
199
|
+
// so we never pollute a good nomic store with TF rows.
|
|
200
|
+
const probe = await embedOne("apx memory embedder probe", embedOpts);
|
|
201
|
+
const family = probe.embedder.startsWith("ollama") ? "ollama" : "tf";
|
|
202
|
+
const stored = cursor.embedder || null;
|
|
203
|
+
if (stored && stored !== family && store.count() > 0) {
|
|
204
|
+
if (family === "ollama") {
|
|
205
|
+
try {
|
|
206
|
+
store.clear?.();
|
|
207
|
+
} catch {
|
|
208
|
+
/* ignore */
|
|
209
|
+
}
|
|
210
|
+
cursor.channels = {};
|
|
211
|
+
log(`memory: embedder ${stored}→ollama — full re-index`);
|
|
212
|
+
} else {
|
|
213
|
+
log("memory: Ollama unavailable — skipping index to keep embedder consistent");
|
|
214
|
+
cursor.embedder = stored; // keep the good signature
|
|
215
|
+
writeCursor(cursorPath, cursor);
|
|
216
|
+
return { indexed: 0, backend: store.backend, skipped: "embedder-downgrade" };
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
cursor.embedder = family;
|
|
220
|
+
|
|
221
|
+
const { fresh: msgChunks, maxTsByChannel } = collectMessageChunks(store, cursor, messagesDir);
|
|
222
|
+
const memChunks = collectMemoryChunks(store, memoryPath);
|
|
223
|
+
let chunks = [...msgChunks, ...memChunks];
|
|
224
|
+
if (chunks.length === 0) return { indexed: 0, backend: store.backend };
|
|
225
|
+
|
|
226
|
+
// Cap per-run work so a huge first index doesn't block; the rest is picked
|
|
227
|
+
// up next pass (cursor only advances for what we actually embedded).
|
|
228
|
+
let capped = false;
|
|
229
|
+
if (chunks.length > limit) {
|
|
230
|
+
chunks = chunks.slice(0, limit);
|
|
231
|
+
capped = true;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const vecs = await embedBatch(
|
|
235
|
+
chunks.map((c) => c.text),
|
|
236
|
+
embedOpts
|
|
237
|
+
);
|
|
238
|
+
const rows = chunks.map((c, i) => ({
|
|
239
|
+
...c,
|
|
240
|
+
embedder: vecs[i].embedder,
|
|
241
|
+
dim: vecs[i].dim,
|
|
242
|
+
vector: vecs[i].vector,
|
|
243
|
+
}));
|
|
244
|
+
const indexed = store.upsert(rows);
|
|
245
|
+
|
|
246
|
+
// Only advance the per-channel cursor when we weren't capped (otherwise we'd
|
|
247
|
+
// skip the chunks that didn't fit this pass).
|
|
248
|
+
if (!capped) {
|
|
249
|
+
for (const [channel, ts] of Object.entries(maxTsByChannel)) {
|
|
250
|
+
cursor.channels[channel] = ts;
|
|
251
|
+
}
|
|
252
|
+
writeCursor(cursorPath, cursor);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
log(`memory: indexed ${indexed} chunk(s)${capped ? " (capped, more next pass)" : ""}`);
|
|
256
|
+
return { indexed, backend: store.backend, capped };
|
|
257
|
+
}
|