@xopcai/xopc 0.0.145 → 0.0.147
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/README.md +2 -2
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/demo-memory/src/index.js +6 -4
- package/dist/extensions/demo-memory/src/index.js.map +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/Combination-14nmIgxH.js +41 -0
- package/dist/gateway/static/root/assets/activity-store-DXeSSlw1.js +1 -0
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BEUxdhZx.js → agent-avatar-dicebear-CFdJKSjY.js} +1 -1
- package/dist/gateway/static/root/assets/agents-DKjbRpbA.js +2 -0
- package/dist/gateway/static/root/assets/api-Bs69B5zA.js +1 -0
- package/dist/gateway/static/root/assets/{app-management-settings-panel-CRHSZJWi.js → app-management-settings-panel-ag1ViXT_.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-BunADYJb.js → appearance-settings-C6iMpwOM.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-CpX3lBFF.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-B6vTkH2A.js → archive-plugin-Dwi3mIBy.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-BjZXzaNv.js → attachment-load-BaCDoq40.js} +1 -1
- package/dist/gateway/static/root/assets/{automation-suggestion-card-ZDA-Stg1.js → automation-suggestion-card-CwqtFgnw.js} +1 -1
- package/dist/gateway/static/root/assets/automations-page-DlupOxFQ.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-DYZfLvPz.js → binary-plugins-DoAYhsxa.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-C3MUlYC9.js → block-editor-Bw72pO7S.js} +31 -31
- package/dist/gateway/static/root/assets/browser-settings-page-BwLoUBcZ.js +8 -0
- package/dist/gateway/static/root/assets/capability-presets-api-vdbAR65Q.js +1 -0
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-BAsKbJgm.js +2 -0
- package/dist/gateway/static/root/assets/{channel-recipient-api-fTlTnWB4.js → channel-recipient-api-rTG26jpV.js} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-CxFWy0cE.js +1 -0
- package/dist/gateway/static/root/assets/channels-status-swr-OKlqTtKJ.js +1 -0
- package/dist/gateway/static/root/assets/{connector-logo-BVFNT2zW.js → connector-logo-DIMP4NWY.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-page-BjQQwX62.js +2 -0
- package/dist/gateway/static/root/assets/{desktop-pet-_jUmoXd3.js → desktop-pet-kQq2e0BN.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-DwGOy4AQ.js → desktop-pet-settings-B6vtozMY.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-akvF0F-u.js → directory-picker-path-field-Dn5-e3v4.js} +1 -1
- package/dist/gateway/static/root/assets/dist-C230izr8.js +1 -0
- package/dist/gateway/static/root/assets/dist-CxGUk8J-.js +1 -0
- package/dist/gateway/static/root/assets/dreaming-settings-BzwIujPG.js +3 -0
- package/dist/gateway/static/root/assets/extension-debug-page-D_e_hsEy.js +1 -0
- package/dist/gateway/static/root/assets/{extension-page-CwWktRNz.js → extension-page-D15CWHBd.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-CuggWOIl.js → extension-settings-page-D4P0n1om.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-B7sxIbza.js → gateway-config-api-B4qZctjG.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-DIv0eKMf.js → gateway-settings-BvndV7TP.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-DtoLihQE.js → gateway-startup-retry-BpgMunEb.js} +1 -1
- package/dist/gateway/static/root/assets/{goal-create-dialog-C4Kw0mfS.js → goal-create-dialog-DrVHKXHq.js} +1 -1
- package/dist/gateway/static/root/assets/goal-detail-page-PHlCwv68.js +4 -0
- package/dist/gateway/static/root/assets/{goals-config-api-B0jm5JaA.js → goals-config-api-B6YJB_ct.js} +1 -1
- package/dist/gateway/static/root/assets/goals-page-Hg9uyO6e.js +2 -0
- package/dist/gateway/static/root/assets/{goals-settings-N5_iL7es.js → goals-settings-BROWCIcL.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-XzH3lbRR.js → heartbeat-settings-CoCwIOIg.js} +1 -1
- package/dist/gateway/static/root/assets/index-CxkNzw3e.js +259 -0
- package/dist/gateway/static/root/assets/index-DjCSOyaN.css +1 -0
- package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-Bm_AIYQ7.js +1 -0
- package/dist/gateway/static/root/assets/local-app-workbench-page-BJWFcxwG.js +2 -0
- package/dist/gateway/static/root/assets/local-apps-page-BsiZMrEf.js +1 -0
- package/dist/gateway/static/root/assets/{locale-store-CiM-D9jA.js → locale-store-Bp8joZck.js} +1 -1
- package/dist/gateway/static/root/assets/logs-page-DOmK61ey.js +7 -0
- package/dist/gateway/static/root/assets/{markdown-split-5rJx5flj.js → markdown-split-Dy7QpaAz.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-DYXccwAd.js → media-plugins-3Lxliy9D.js} +1 -1
- package/dist/gateway/static/root/assets/messages-CQGpD-dC.js +5 -0
- package/dist/gateway/static/root/assets/models-hub-panel-DGCZom4o.js +2 -0
- package/dist/gateway/static/root/assets/{notes-page-BgLyndCO.js → notes-page-BJtT4vSf.js} +1 -1
- package/dist/gateway/static/root/assets/notes-workbench-B_bN7cOR.js +4 -0
- package/dist/gateway/static/root/assets/{page-tabs-6Al9_sGz.js → page-tabs-DKB6RDre.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-Cm3G72Hv.js → preview-open-alternatives-Br_YhYHp.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-Dq8JouJj.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-DvfL7fSe.js +1 -0
- package/dist/gateway/static/root/assets/remote-access-hub-DqwMXSXP.js +1 -0
- package/dist/gateway/static/root/assets/{save-bar-controls-BYtfzu_F.js → save-bar-controls-BgIE9BBh.js} +1 -1
- package/dist/gateway/static/root/assets/{schedule-field-CvIRc6yK.js → schedule-field-BXDP-oMz.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-CQuKx0n7.js → schema-form-Dhv-SmjG.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-B_mOZkQk.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-BHGmH6YS.js +1 -0
- package/dist/gateway/static/root/assets/{settings-collapsible-section-CF3HHM-t.js → settings-collapsible-section-CUTExnlK.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-form-section-CwWjoRN6.js → settings-form-section-CmnDhsf0.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-loading-skeleton-aUFmJa13.js → settings-loading-skeleton-B79dq-XY.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-B2UUU9TF.js → settings-page-Db8uAv3X.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-layout-DqpbTWqI.js → settings-page-layout-DaFwstQw.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-BUSEj0KK.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page-BOhlPsS1.js → share-preview-page-Bi00uXzV.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-DzsTYfuX.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-DSsdU081.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-DeB1tQZL.js +2 -0
- package/dist/gateway/static/root/assets/{system-settings-panel-CWxSvuwD.js → system-settings-panel-Cxaph7hW.js} +1 -1
- package/dist/gateway/static/root/assets/{theme-store-C9Dxcppm.js → theme-store-eCTN1RpG.js} +1 -1
- package/dist/gateway/static/root/assets/{typed-models-lib-qROAvqTw.js → typed-models-lib-CcZ_tyFY.js} +1 -1
- package/dist/gateway/static/root/assets/{use-channel-catalog-DE9cpn4G.js → use-channel-catalog-C4PWbNoi.js} +1 -1
- package/dist/gateway/static/root/assets/user-context-page-QTVMx_hG.js +1 -0
- package/dist/gateway/static/root/assets/{user-profile-fields-editor-CWxc0ghP.js → user-profile-fields-editor-CPOO9Jz5.js} +1 -1
- package/dist/gateway/static/root/assets/{user-profile-settings-panel-DW-Up6vt.js → user-profile-settings-panel-C8cgtSF7.js} +1 -1
- package/dist/gateway/static/root/assets/{utils-D53uRXVr.js → utils-CiZK2KwH.js} +1 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-b-YZtvUu.js +1 -0
- package/dist/gateway/static/root/assets/work-discovery-page-4zVDOl2G.js +1 -0
- package/dist/gateway/static/root/assets/work-item-detail-page-CHe2tfkc.js +1 -0
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-D_x9ELJp.js → workflow-run-setup-panel-8SLCYeXE.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-DEOFqiWn.js +11 -0
- package/dist/gateway/static/root/index.html +10 -9
- package/dist/package.js +1 -1
- package/dist/src/activity/types.d.ts +1 -1
- package/dist/src/agent/agent-instance-gateway.d.ts +1 -1
- package/dist/src/agent/agent-manager.d.ts +1 -1
- package/dist/src/agent/agent-manager.js +5 -4
- package/dist/src/agent/agent-manager.js.map +1 -1
- package/dist/src/agent/background-review/coordinator.js +0 -1
- package/dist/src/agent/background-review/coordinator.js.map +1 -1
- package/dist/src/agent/background-review/settings.d.ts +1 -1
- package/dist/src/agent/background-review/settings.js +10 -17
- package/dist/src/agent/background-review/settings.js.map +1 -1
- package/dist/src/agent/bootstrap/filter-bootstrap-files.d.ts +1 -1
- package/dist/src/agent/bootstrap/filter-bootstrap-files.js +1 -1
- package/dist/src/agent/bootstrap/filter-bootstrap-files.js.map +1 -1
- package/dist/src/agent/bootstrap/load-bootstrap-files.js +2 -3
- package/dist/src/agent/bootstrap/load-bootstrap-files.js.map +1 -1
- package/dist/src/agent/code-intelligence/binary.js +1 -1
- package/dist/src/agent/context/project-context.d.ts +14 -0
- package/dist/src/agent/context/project-context.js +23 -1
- package/dist/src/agent/context/project-context.js.map +1 -1
- package/dist/src/agent/context/workspace-templates/AGENTS.md +1 -1
- package/dist/src/agent/context/workspace.d.ts +1 -2
- package/dist/src/agent/context/workspace.js +2 -4
- package/dist/src/agent/context/workspace.js.map +1 -1
- package/dist/src/agent/embedded/run-for-session.js +1 -2
- package/dist/src/agent/embedded/run-for-session.js.map +1 -1
- package/dist/src/agent/embedded/run-turn.js +6 -1
- package/dist/src/agent/embedded/run-turn.js.map +1 -1
- package/dist/src/agent/embedded/types.d.ts +17 -0
- package/dist/src/agent/memory/builtin-memory-store.d.ts +2 -2
- package/dist/src/agent/memory/builtin-memory-store.js +2 -2
- package/dist/src/agent/memory/builtin-memory-store.js.map +1 -1
- package/dist/src/agent/memory/builtin-provider.d.ts +1 -3
- package/dist/src/agent/memory/builtin-provider.js +21 -48
- package/dist/src/agent/memory/builtin-provider.js.map +1 -1
- package/dist/src/agent/memory/context/planner.js +48 -9
- package/dist/src/agent/memory/context/planner.js.map +1 -1
- package/dist/src/agent/memory/context/types.d.ts +7 -1
- package/dist/src/agent/memory/context-fence.js +1 -1
- package/dist/src/agent/memory/context-fence.js.map +1 -1
- package/dist/src/agent/memory/create-memory-manager.js +2 -9
- package/dist/src/agent/memory/create-memory-manager.js.map +1 -1
- package/dist/src/agent/memory/dreaming/config.js +5 -10
- package/dist/src/agent/memory/dreaming/config.js.map +1 -1
- package/dist/src/agent/memory/dreaming/promotion-lifecycle.js +2 -2
- package/dist/src/agent/memory/dreaming/promotion-lifecycle.js.map +1 -1
- package/dist/src/agent/memory/dreaming/scope.d.ts +2 -3
- package/dist/src/agent/memory/dreaming/scope.js +8 -8
- package/dist/src/agent/memory/dreaming/scope.js.map +1 -1
- package/dist/src/agent/memory/manager.d.ts +1 -5
- package/dist/src/agent/memory/manager.js +2 -23
- package/dist/src/agent/memory/manager.js.map +1 -1
- package/dist/src/agent/memory/memory-config.d.ts +3 -3
- package/dist/src/agent/memory/memory-config.js +9 -14
- package/dist/src/agent/memory/memory-config.js.map +1 -1
- package/dist/src/agent/memory/types.d.ts +9 -5
- package/dist/src/agent/memory/understanding/service.js +21 -8
- package/dist/src/agent/memory/understanding/service.js.map +1 -1
- package/dist/src/agent/memory/understanding/types.d.ts +5 -0
- package/dist/src/agent/memory/user-context-coordinator.d.ts +1 -1
- package/dist/src/agent/memory/user-context-coordinator.js +6 -2
- package/dist/src/agent/memory/user-context-coordinator.js.map +1 -1
- package/dist/src/agent/orchestration/agent-orchestrator.js +2 -2
- package/dist/src/agent/orchestration/agent-orchestrator.js.map +1 -1
- package/dist/src/agent/prompt/memory/index.d.ts +1 -2
- package/dist/src/agent/prompt/memory/index.js +6 -7
- package/dist/src/agent/prompt/memory/index.js.map +1 -1
- package/dist/src/agent/prompt/sections/tooling.js +1 -1
- package/dist/src/agent/prompt/sections/tooling.js.map +1 -1
- package/dist/src/agent/service/direct-turn-helpers.js +13 -2
- package/dist/src/agent/service/direct-turn-helpers.js.map +1 -1
- package/dist/src/agent/tools/curated-memory-tool.js +4 -4
- package/dist/src/agent/tools/curated-memory-tool.js.map +1 -1
- package/dist/src/agent/tools/factory.d.ts +1 -1
- package/dist/src/agent/tools/factory.js +2 -2
- package/dist/src/agent/tools/factory.js.map +1 -1
- package/dist/src/agent/tools/memory-tool.js +1 -1
- package/dist/src/agent/tools/memory-tool.js.map +1 -1
- package/dist/src/agent/workflow/workflow-child-tools.js +2 -3
- package/dist/src/agent/workflow/workflow-child-tools.js.map +1 -1
- package/dist/src/agent/workspace-runtime/registry.d.ts +5 -5
- package/dist/src/agent/workspace-runtime/registry.js +6 -11
- package/dist/src/agent/workspace-runtime/registry.js.map +1 -1
- package/dist/src/agent-manifest/index.js +2 -2
- package/dist/src/agent-manifest/prompt.js +1 -7
- package/dist/src/agent-manifest/prompt.js.map +1 -1
- package/dist/src/agent-manifest/schema.d.ts +0 -598
- package/dist/src/agent-manifest/schema.js +2 -143
- package/dist/src/agent-manifest/schema.js.map +1 -1
- package/dist/src/agent-manifest/validator.js +0 -12
- package/dist/src/agent-manifest/validator.js.map +1 -1
- package/dist/src/agent-runtime/index.js +1 -1
- package/dist/src/agent-runtime/memory-runtime.d.ts +2 -2
- package/dist/src/agent-runtime/memory-runtime.js +8 -7
- package/dist/src/agent-runtime/memory-runtime.js.map +1 -1
- package/dist/src/agent-runtime/runtime-profile.d.ts +2 -0
- package/dist/src/agent-runtime/runtime-profile.js +2 -2
- package/dist/src/agent-runtime/runtime-profile.js.map +1 -1
- package/dist/src/chat-commands/agent-edit.js +1 -2
- package/dist/src/chat-commands/agent-edit.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/init.js +0 -22
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/templates.d.ts +1 -1
- package/dist/src/cli/templates.js +1 -16
- package/dist/src/cli/templates.js.map +1 -1
- package/dist/src/commands/agents.config.js +0 -10
- package/dist/src/commands/agents.config.js.map +1 -1
- package/dist/src/config/agent-profile.js +1 -1
- package/dist/src/config/index.js +2 -2
- package/dist/src/config/paths.d.ts +0 -1
- package/dist/src/config/paths.js +1 -2
- package/dist/src/config/paths.js.map +1 -1
- package/dist/src/config/schema.d.ts +118 -532
- package/dist/src/config/schema.js +32 -26
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/extensions/loader.js +2 -1
- package/dist/src/extensions/loader.js.map +1 -1
- package/dist/src/gateway/agents-admin.d.ts +0 -2
- package/dist/src/gateway/agents-admin.js +1 -7
- package/dist/src/gateway/agents-admin.js.map +1 -1
- package/dist/src/gateway/capability-presets-admin.d.ts +0 -2
- package/dist/src/gateway/capability-presets-admin.js.map +1 -1
- package/dist/src/gateway/chat-stream/mapper.js +26 -0
- package/dist/src/gateway/chat-stream/mapper.js.map +1 -1
- package/dist/src/gateway/chat-stream/protocol.d.ts +16 -1
- package/dist/src/gateway/dreaming-automation-reconciler.d.ts +0 -1
- package/dist/src/gateway/dreaming-automation-reconciler.js +41 -63
- package/dist/src/gateway/dreaming-automation-reconciler.js.map +1 -1
- package/dist/src/gateway/heartbeat/service.js +1 -1
- package/dist/src/gateway/hono/app.js +3 -1
- package/dist/src/gateway/hono/app.js.map +1 -1
- package/dist/src/gateway/hono/lib/config-payload.d.ts +0 -130
- package/dist/src/gateway/hono/lib/config-payload.js +0 -1
- package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
- package/dist/src/gateway/hono/routes/agents.js +6 -12
- package/dist/src/gateway/hono/routes/agents.js.map +1 -1
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js +6 -0
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js.map +1 -1
- package/dist/src/gateway/hono/routes/capability-presets.js +2 -2
- package/dist/src/gateway/hono/routes/capability-presets.js.map +1 -1
- package/dist/src/gateway/hono/routes/dreaming.js +9 -20
- package/dist/src/gateway/hono/routes/dreaming.js.map +1 -1
- package/dist/src/gateway/hono/routes/index.js +4 -0
- package/dist/src/gateway/hono/routes/index.js.map +1 -1
- package/dist/src/gateway/hono/routes/local-apps.d.ts +5 -0
- package/dist/src/gateway/hono/routes/local-apps.js +99 -0
- package/dist/src/gateway/hono/routes/local-apps.js.map +1 -0
- package/dist/src/gateway/hono/routes/memory.js +48 -65
- package/dist/src/gateway/hono/routes/memory.js.map +1 -1
- package/dist/src/gateway/hono/routes/projects.js +2 -2
- package/dist/src/gateway/hono/routes/projects.js.map +1 -1
- package/dist/src/gateway/hono/routes/work-discovery.d.ts +3 -0
- package/dist/src/gateway/hono/routes/work-discovery.js +150 -0
- package/dist/src/gateway/hono/routes/work-discovery.js.map +1 -0
- package/dist/src/gateway/hono/routes/you.d.ts +3 -0
- package/dist/src/gateway/hono/routes/you.js +358 -91
- package/dist/src/gateway/hono/routes/you.js.map +1 -1
- package/dist/src/gateway/service.d.ts +3 -0
- package/dist/src/gateway/service.js +12 -0
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/heartbeat/index.js +1 -1
- package/dist/src/knowledge/connected-knowledge-pipeline.js +9 -5
- package/dist/src/knowledge/connected-knowledge-pipeline.js.map +1 -1
- package/dist/src/local-apps/acceptance.d.ts +30 -0
- package/dist/src/local-apps/acceptance.js +93 -0
- package/dist/src/local-apps/acceptance.js.map +1 -0
- package/dist/src/local-apps/index.d.ts +5 -0
- package/dist/src/local-apps/index.js +4 -0
- package/dist/src/local-apps/preview-runtime-bridge.d.ts +4 -0
- package/dist/src/local-apps/preview-runtime-bridge.js +171 -0
- package/dist/src/local-apps/preview-runtime-bridge.js.map +1 -0
- package/dist/src/local-apps/runtime-entry.d.ts +8 -0
- package/dist/src/local-apps/runtime-entry.js +25 -0
- package/dist/src/local-apps/runtime-entry.js.map +1 -0
- package/dist/src/local-apps/scaffold.d.ts +8 -0
- package/dist/src/local-apps/scaffold.js +122 -0
- package/dist/src/local-apps/scaffold.js.map +1 -0
- package/dist/src/local-apps/service.d.ts +37 -0
- package/dist/src/local-apps/service.js +553 -0
- package/dist/src/local-apps/service.js.map +1 -0
- package/dist/src/local-apps/store.d.ts +44 -0
- package/dist/src/local-apps/store.js +195 -0
- package/dist/src/local-apps/store.js.map +1 -0
- package/dist/src/local-apps/types.d.ts +105 -0
- package/dist/src/local-apps/types.js +1 -0
- package/dist/src/storage/sqlite/index.d.ts +3 -2
- package/dist/src/storage/sqlite/index.js +4 -3
- package/dist/src/storage/sqlite/memory-index-repository.d.ts +2 -3
- package/dist/src/storage/sqlite/memory-index-repository.js +16 -20
- package/dist/src/storage/sqlite/memory-index-repository.js.map +1 -1
- package/dist/src/storage/sqlite/memory-records-repository.d.ts +18 -10
- package/dist/src/storage/sqlite/memory-records-repository.js +79 -34
- package/dist/src/storage/sqlite/memory-records-repository.js.map +1 -1
- package/dist/src/storage/sqlite/memory-reference-consent-repository.d.ts +27 -0
- package/dist/src/storage/sqlite/memory-reference-consent-repository.js +109 -0
- package/dist/src/storage/sqlite/memory-reference-consent-repository.js.map +1 -0
- package/dist/src/storage/sqlite/migrations/038_user_owned_memory.sql +68 -0
- package/dist/src/storage/sqlite/migrations/039_memory_reference_consents.sql +19 -0
- package/dist/src/storage/sqlite/migrations/040_local_apps.sql +32 -0
- package/dist/src/storage/sqlite/migrations/041_local_app_release_lifecycle.sql +17 -0
- package/dist/src/storage/sqlite/migrations/042_work_discovery.sql +41 -0
- package/dist/src/storage/sqlite/migrations/043_local_app_acceptance_runs.sql +16 -0
- package/dist/src/storage/sqlite/migrations/044_repair_work_discovery_foreign_keys.sql +75 -0
- package/dist/src/storage/sqlite/migrations/045_extension_ui_grants.sql +13 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
- package/dist/src/storage/sqlite/migrations/runner.js +3 -3
- package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
- package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/storage/sqlite/schema.sql +20 -0
- package/dist/src/user-context/config.d.ts +227 -0
- package/dist/src/user-context/config.js +158 -0
- package/dist/src/user-context/config.js.map +1 -0
- package/dist/src/user-context/import.d.ts +1 -1
- package/dist/src/user-context/import.js +6 -1
- package/dist/src/user-context/import.js.map +1 -1
- package/dist/src/user-context/owner.d.ts +5 -0
- package/dist/src/user-context/owner.js +9 -0
- package/dist/src/user-context/owner.js.map +1 -0
- package/dist/src/user-context/projection.d.ts +11 -9
- package/dist/src/user-context/projection.js +74 -47
- package/dist/src/user-context/projection.js.map +1 -1
- package/dist/src/user-context/runtime.d.ts +13 -0
- package/dist/src/user-context/runtime.js +36 -0
- package/dist/src/user-context/runtime.js.map +1 -0
- package/dist/src/work-discovery/analyzer.d.ts +11 -0
- package/dist/src/work-discovery/analyzer.js +171 -0
- package/dist/src/work-discovery/analyzer.js.map +1 -0
- package/dist/src/work-discovery/index.d.ts +5 -0
- package/dist/src/work-discovery/index.js +5 -0
- package/dist/src/work-discovery/probe.d.ts +12 -0
- package/dist/src/work-discovery/probe.js +335 -0
- package/dist/src/work-discovery/probe.js.map +1 -0
- package/dist/src/work-discovery/repository.d.ts +11 -0
- package/dist/src/work-discovery/repository.js +100 -0
- package/dist/src/work-discovery/repository.js.map +1 -0
- package/dist/src/work-discovery/service.d.ts +30 -0
- package/dist/src/work-discovery/service.js +387 -0
- package/dist/src/work-discovery/service.js.map +1 -0
- package/dist/src/work-discovery/types.d.ts +114 -0
- package/dist/src/work-discovery/types.js +1 -0
- package/dist/src/workflows/service/workflow-session-bridge.js +1 -1
- package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -1
- package/package.json +5 -3
- package/skills/engineering/build-xopc-local-app/SKILL.md +45 -0
- package/skills/engineering/build-xopc-local-app/references/app-contract.md +33 -0
- package/skills/engineering/build-xopc-local-app/scripts/validate-local-app.mjs +72 -0
- package/dist/gateway/static/root/assets/Combination-DolwnuKi.js +0 -41
- package/dist/gateway/static/root/assets/activity-center-store-3l9ahUqb.js +0 -1
- package/dist/gateway/static/root/assets/agents-1bpT0xRO.js +0 -2
- package/dist/gateway/static/root/assets/apps-page-Cc4JgVUQ.js +0 -1
- package/dist/gateway/static/root/assets/automations-page-mb0fdVpq.js +0 -6
- package/dist/gateway/static/root/assets/browser-settings-page-Bb0xhaMN.js +0 -8
- package/dist/gateway/static/root/assets/capability-presets-api-BV76yN9a.js +0 -1
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-CUcGKZqC.js +0 -2
- package/dist/gateway/static/root/assets/channels-settings-BlSDMGdy.js +0 -1
- package/dist/gateway/static/root/assets/channels-status-swr-CJauF1CW.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-CMgAFGvb.js +0 -2
- package/dist/gateway/static/root/assets/dist-C99RGfAH.js +0 -1
- package/dist/gateway/static/root/assets/dreaming-settings-BLetQiYY.js +0 -3
- package/dist/gateway/static/root/assets/extension-debug-page-Cof2ncxE.js +0 -1
- package/dist/gateway/static/root/assets/goal-detail-page-BMmzYpZL.js +0 -4
- package/dist/gateway/static/root/assets/goals-page-CGeT77PC.js +0 -2
- package/dist/gateway/static/root/assets/index-CSLF84-Q.css +0 -1
- package/dist/gateway/static/root/assets/index-I-ZCenVw.js +0 -259
- package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-x_v0nrIi.js +0 -1
- package/dist/gateway/static/root/assets/logs-page-BSh1t8cD.js +0 -7
- package/dist/gateway/static/root/assets/messages-Cb1VMeqP.js +0 -5
- package/dist/gateway/static/root/assets/models-hub-panel-BNpTenAI.js +0 -2
- package/dist/gateway/static/root/assets/notes-workbench-teklkhcE.js +0 -4
- package/dist/gateway/static/root/assets/project-detail-page-CCB_dKoh.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-VOAFAHYj.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-USYu64Ru.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-oGC8O5h_.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-D4rP66R1.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-Ck9keROI.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-BYLsCuqj.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-BNHUyVML.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-CpXbQH4n.js +0 -2
- package/dist/gateway/static/root/assets/user-context-page-DbNEK4Yp.js +0 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-Cs7MOrg0.js +0 -1
- package/dist/gateway/static/root/assets/work-item-detail-page-D1ziG1Pp.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-DHGV_n6i.js +0 -11
- package/dist/src/agent/context/workspace-templates/MEMORY.md +0 -33
- package/dist/src/agent/memory/access-policy.d.ts +0 -12
- package/dist/src/agent/memory/access-policy.js +0 -44
- package/dist/src/agent/memory/access-policy.js.map +0 -1
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { LocalApp, LocalAppAcceptanceRun, LocalAppRelease, LocalAppUiGrant, RecordLocalAppAcceptanceInput } from './types.js';
|
|
2
|
+
export interface StoredLocalAppRelease extends LocalAppRelease {
|
|
3
|
+
artifactPath: string;
|
|
4
|
+
manifestJson: string;
|
|
5
|
+
}
|
|
6
|
+
export declare class LocalAppStore {
|
|
7
|
+
create(input: {
|
|
8
|
+
extensionId: string;
|
|
9
|
+
projectId: string;
|
|
10
|
+
name: string;
|
|
11
|
+
description?: string;
|
|
12
|
+
idea: string;
|
|
13
|
+
workspaceRoot: string;
|
|
14
|
+
previewToken: string;
|
|
15
|
+
}): LocalApp;
|
|
16
|
+
get(id: string): LocalApp | null;
|
|
17
|
+
findByProjectId(projectId: string): LocalApp | null;
|
|
18
|
+
findByExtensionId(extensionId: string): LocalApp | null;
|
|
19
|
+
list(): LocalApp[];
|
|
20
|
+
findByPreviewToken(previewToken: string): LocalApp | null;
|
|
21
|
+
getPreviewToken(id: string): string | null;
|
|
22
|
+
listReleases(appId: string): StoredLocalAppRelease[];
|
|
23
|
+
getRelease(appId: string, releaseId: string): StoredLocalAppRelease | null;
|
|
24
|
+
listAcceptanceRuns(appId: string, limit?: number): LocalAppAcceptanceRun[];
|
|
25
|
+
getLatestAcceptanceForSource(appId: string, sourceHash: string): LocalAppAcceptanceRun | null;
|
|
26
|
+
getUiGrant(extensionId: string, manifestDigest: string): LocalAppUiGrant | null;
|
|
27
|
+
saveUiGrant(input: {
|
|
28
|
+
extensionId: string;
|
|
29
|
+
appId?: string;
|
|
30
|
+
manifestDigest: string;
|
|
31
|
+
permissions: string[];
|
|
32
|
+
}): LocalAppUiGrant;
|
|
33
|
+
recordAcceptance(appId: string, input: RecordLocalAppAcceptanceInput): LocalAppAcceptanceRun;
|
|
34
|
+
markInstalled(input: {
|
|
35
|
+
id: string;
|
|
36
|
+
version: number;
|
|
37
|
+
sourceHash: string;
|
|
38
|
+
artifactPath: string;
|
|
39
|
+
manifestJson: string;
|
|
40
|
+
}): LocalApp;
|
|
41
|
+
activateRelease(appId: string, releaseId: string): LocalApp;
|
|
42
|
+
setEnabled(appId: string, enabled: boolean): LocalApp;
|
|
43
|
+
markUninstalled(appId: string): LocalApp;
|
|
44
|
+
}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { getSqliteDatabase, runSqliteWriteTransaction } from "../storage/sqlite/transaction.js";
|
|
2
|
+
import "../storage/sqlite/index.js";
|
|
3
|
+
import { randomUUID } from "node:crypto";
|
|
4
|
+
//#region src/local-apps/store.ts
|
|
5
|
+
function fromRow(row) {
|
|
6
|
+
return {
|
|
7
|
+
id: row.app_id,
|
|
8
|
+
extensionId: row.extension_id,
|
|
9
|
+
projectId: row.project_id,
|
|
10
|
+
name: row.name,
|
|
11
|
+
description: row.description ?? void 0,
|
|
12
|
+
idea: row.idea,
|
|
13
|
+
status: row.status,
|
|
14
|
+
workspaceRoot: row.workspace_root,
|
|
15
|
+
draftVersion: row.draft_version,
|
|
16
|
+
activeVersion: row.active_version ?? void 0,
|
|
17
|
+
activeReleaseId: row.active_release_id ?? void 0,
|
|
18
|
+
installationState: row.installation_state,
|
|
19
|
+
enabled: row.enabled === 1,
|
|
20
|
+
createdAt: row.created_at,
|
|
21
|
+
updatedAt: row.updated_at,
|
|
22
|
+
installedAt: row.installed_at ?? void 0
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function releaseFromRow(row, activeReleaseId) {
|
|
26
|
+
return {
|
|
27
|
+
id: row.release_id,
|
|
28
|
+
appId: row.app_id,
|
|
29
|
+
version: row.version,
|
|
30
|
+
sourceHash: row.source_hash,
|
|
31
|
+
artifactPath: row.artifact_path ?? "",
|
|
32
|
+
manifestJson: row.manifest_json,
|
|
33
|
+
healthStatus: row.health_status,
|
|
34
|
+
createdAt: row.created_at,
|
|
35
|
+
activatedAt: row.activated_at ?? void 0,
|
|
36
|
+
isActive: row.release_id === activeReleaseId
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function acceptanceRunFromRow(row) {
|
|
40
|
+
return {
|
|
41
|
+
id: row.run_id,
|
|
42
|
+
appId: row.app_id,
|
|
43
|
+
sourceHash: row.source_hash,
|
|
44
|
+
status: row.status,
|
|
45
|
+
checks: JSON.parse(row.checks_json),
|
|
46
|
+
interactiveCount: row.interactive_count,
|
|
47
|
+
createdAt: row.created_at
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
var LocalAppStore = class {
|
|
51
|
+
create(input) {
|
|
52
|
+
const now = Date.now();
|
|
53
|
+
const id = randomUUID();
|
|
54
|
+
runSqliteWriteTransaction((db) => {
|
|
55
|
+
db.prepare(`INSERT INTO local_apps (
|
|
56
|
+
app_id, extension_id, project_id, name, description, idea, status,
|
|
57
|
+
workspace_root, preview_token, draft_version, created_at, updated_at
|
|
58
|
+
) VALUES (?, ?, ?, ?, ?, ?, 'preview_ready', ?, ?, 1, ?, ?)`).run(id, input.extensionId, input.projectId, input.name, input.description ?? null, input.idea, input.workspaceRoot, input.previewToken, now, now);
|
|
59
|
+
});
|
|
60
|
+
return this.get(id);
|
|
61
|
+
}
|
|
62
|
+
get(id) {
|
|
63
|
+
const row = getSqliteDatabase().prepare("SELECT * FROM local_apps WHERE app_id = ?").get(id);
|
|
64
|
+
return row ? fromRow(row) : null;
|
|
65
|
+
}
|
|
66
|
+
findByProjectId(projectId) {
|
|
67
|
+
const row = getSqliteDatabase().prepare("SELECT * FROM local_apps WHERE project_id = ?").get(projectId);
|
|
68
|
+
return row ? fromRow(row) : null;
|
|
69
|
+
}
|
|
70
|
+
findByExtensionId(extensionId) {
|
|
71
|
+
const row = getSqliteDatabase().prepare("SELECT * FROM local_apps WHERE extension_id = ?").get(extensionId);
|
|
72
|
+
return row ? fromRow(row) : null;
|
|
73
|
+
}
|
|
74
|
+
list() {
|
|
75
|
+
return getSqliteDatabase().prepare("SELECT * FROM local_apps ORDER BY updated_at DESC").all().map(fromRow);
|
|
76
|
+
}
|
|
77
|
+
findByPreviewToken(previewToken) {
|
|
78
|
+
const row = getSqliteDatabase().prepare("SELECT * FROM local_apps WHERE preview_token = ?").get(previewToken);
|
|
79
|
+
return row ? fromRow(row) : null;
|
|
80
|
+
}
|
|
81
|
+
getPreviewToken(id) {
|
|
82
|
+
return getSqliteDatabase().prepare("SELECT preview_token FROM local_apps WHERE app_id = ?").get(id)?.preview_token ?? null;
|
|
83
|
+
}
|
|
84
|
+
listReleases(appId) {
|
|
85
|
+
const app = this.get(appId);
|
|
86
|
+
return getSqliteDatabase().prepare("SELECT * FROM local_app_releases WHERE app_id = ? ORDER BY version DESC").all(appId).map((row) => releaseFromRow(row, app?.activeReleaseId));
|
|
87
|
+
}
|
|
88
|
+
getRelease(appId, releaseId) {
|
|
89
|
+
const app = this.get(appId);
|
|
90
|
+
const row = getSqliteDatabase().prepare("SELECT * FROM local_app_releases WHERE app_id = ? AND release_id = ?").get(appId, releaseId);
|
|
91
|
+
return row ? releaseFromRow(row, app?.activeReleaseId) : null;
|
|
92
|
+
}
|
|
93
|
+
listAcceptanceRuns(appId, limit = 20) {
|
|
94
|
+
return getSqliteDatabase().prepare("SELECT * FROM local_app_acceptance_runs WHERE app_id = ? ORDER BY created_at DESC, rowid DESC LIMIT ?").all(appId, Math.max(1, Math.min(Math.floor(limit), 100))).map(acceptanceRunFromRow);
|
|
95
|
+
}
|
|
96
|
+
getLatestAcceptanceForSource(appId, sourceHash) {
|
|
97
|
+
const row = getSqliteDatabase().prepare(`SELECT * FROM local_app_acceptance_runs
|
|
98
|
+
WHERE app_id = ? AND source_hash = ? ORDER BY created_at DESC, rowid DESC LIMIT 1`).get(appId, sourceHash);
|
|
99
|
+
return row ? acceptanceRunFromRow(row) : null;
|
|
100
|
+
}
|
|
101
|
+
getUiGrant(extensionId, manifestDigest) {
|
|
102
|
+
const row = getSqliteDatabase().prepare(`SELECT * FROM extension_ui_grants
|
|
103
|
+
WHERE extension_id = ? AND manifest_digest = ? AND revoked_at IS NULL`).get(extensionId, manifestDigest);
|
|
104
|
+
if (!row) return null;
|
|
105
|
+
return {
|
|
106
|
+
granted: true,
|
|
107
|
+
extensionId: row.extension_id,
|
|
108
|
+
appId: row.app_id ?? void 0,
|
|
109
|
+
manifestDigest: row.manifest_digest,
|
|
110
|
+
permissions: JSON.parse(row.permissions_json),
|
|
111
|
+
grantedAt: row.granted_at
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
saveUiGrant(input) {
|
|
115
|
+
const grantedAt = Date.now();
|
|
116
|
+
getSqliteDatabase().prepare(`INSERT INTO extension_ui_grants (
|
|
117
|
+
extension_id, app_id, manifest_digest, permissions_json, granted_at, revoked_at
|
|
118
|
+
) VALUES (?, ?, ?, ?, ?, NULL)
|
|
119
|
+
ON CONFLICT(extension_id, manifest_digest) DO UPDATE SET
|
|
120
|
+
app_id = excluded.app_id,
|
|
121
|
+
permissions_json = excluded.permissions_json,
|
|
122
|
+
granted_at = excluded.granted_at,
|
|
123
|
+
revoked_at = NULL`).run(input.extensionId, input.appId ?? null, input.manifestDigest, JSON.stringify(input.permissions), grantedAt);
|
|
124
|
+
return {
|
|
125
|
+
granted: true,
|
|
126
|
+
extensionId: input.extensionId,
|
|
127
|
+
appId: input.appId,
|
|
128
|
+
manifestDigest: input.manifestDigest,
|
|
129
|
+
permissions: input.permissions,
|
|
130
|
+
grantedAt
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
recordAcceptance(appId, input) {
|
|
134
|
+
const checksJson = JSON.stringify(input.checks);
|
|
135
|
+
const latest = this.listAcceptanceRuns(appId, 1)[0];
|
|
136
|
+
if (latest && latest.sourceHash === input.sourceHash && latest.status === input.status && latest.interactiveCount === input.interactiveCount && JSON.stringify(latest.checks) === checksJson) return latest;
|
|
137
|
+
const row = {
|
|
138
|
+
run_id: randomUUID(),
|
|
139
|
+
app_id: appId,
|
|
140
|
+
source_hash: input.sourceHash,
|
|
141
|
+
status: input.status,
|
|
142
|
+
checks_json: checksJson,
|
|
143
|
+
interactive_count: input.interactiveCount,
|
|
144
|
+
created_at: Date.now()
|
|
145
|
+
};
|
|
146
|
+
getSqliteDatabase().prepare(`INSERT INTO local_app_acceptance_runs (
|
|
147
|
+
run_id, app_id, source_hash, status, checks_json, interactive_count, created_at
|
|
148
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?)`).run(row.run_id, row.app_id, row.source_hash, row.status, row.checks_json, row.interactive_count, row.created_at);
|
|
149
|
+
return acceptanceRunFromRow(row);
|
|
150
|
+
}
|
|
151
|
+
markInstalled(input) {
|
|
152
|
+
const now = Date.now();
|
|
153
|
+
const releaseId = randomUUID();
|
|
154
|
+
runSqliteWriteTransaction((db) => {
|
|
155
|
+
db.prepare(`INSERT INTO local_app_releases (
|
|
156
|
+
release_id, app_id, version, source_hash, artifact_path, manifest_json,
|
|
157
|
+
health_status, created_at, activated_at
|
|
158
|
+
) VALUES (?, ?, ?, ?, ?, ?, 'healthy', ?, ?)`).run(releaseId, input.id, input.version, input.sourceHash, input.artifactPath, input.manifestJson, now, now);
|
|
159
|
+
db.prepare(`UPDATE local_apps SET status = 'installed', active_version = ?, active_release_id = ?,
|
|
160
|
+
draft_version = ?, installation_state = 'installed', enabled = 1,
|
|
161
|
+
installed_at = COALESCE(installed_at, ?), updated_at = ? WHERE app_id = ?`).run(input.version, releaseId, input.version + 1, now, now, input.id);
|
|
162
|
+
});
|
|
163
|
+
return this.get(input.id);
|
|
164
|
+
}
|
|
165
|
+
activateRelease(appId, releaseId) {
|
|
166
|
+
const release = this.getRelease(appId, releaseId);
|
|
167
|
+
if (!release) throw new Error("Local app release not found");
|
|
168
|
+
const now = Date.now();
|
|
169
|
+
runSqliteWriteTransaction((db) => {
|
|
170
|
+
db.prepare("UPDATE local_app_releases SET activated_at = ? WHERE release_id = ?").run(now, releaseId);
|
|
171
|
+
db.prepare(`UPDATE local_apps SET status = 'installed', active_version = ?, active_release_id = ?,
|
|
172
|
+
installation_state = 'installed', enabled = 1, updated_at = ? WHERE app_id = ?`).run(release.version, releaseId, now, appId);
|
|
173
|
+
});
|
|
174
|
+
return this.get(appId);
|
|
175
|
+
}
|
|
176
|
+
setEnabled(appId, enabled) {
|
|
177
|
+
const now = Date.now();
|
|
178
|
+
getSqliteDatabase().prepare("UPDATE local_apps SET enabled = ?, updated_at = ? WHERE app_id = ?").run(enabled ? 1 : 0, now, appId);
|
|
179
|
+
const app = this.get(appId);
|
|
180
|
+
if (!app) throw new Error("Local app not found");
|
|
181
|
+
return app;
|
|
182
|
+
}
|
|
183
|
+
markUninstalled(appId) {
|
|
184
|
+
const now = Date.now();
|
|
185
|
+
getSqliteDatabase().prepare(`UPDATE local_apps SET status = 'preview_ready', active_version = NULL,
|
|
186
|
+
active_release_id = NULL, installation_state = 'not_installed', enabled = 0, updated_at = ? WHERE app_id = ?`).run(now, appId);
|
|
187
|
+
const app = this.get(appId);
|
|
188
|
+
if (!app) throw new Error("Local app not found");
|
|
189
|
+
return app;
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
//#endregion
|
|
193
|
+
export { LocalAppStore };
|
|
194
|
+
|
|
195
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","names":[],"sources":["../../../src/local-apps/store.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport { getSqliteDatabase, runSqliteWriteTransaction } from '../storage/sqlite/index.js';\nimport type {\n LocalApp,\n LocalAppAcceptanceCheck,\n LocalAppAcceptanceRun,\n LocalAppRelease,\n LocalAppStatus,\n LocalAppUiGrant,\n RecordLocalAppAcceptanceInput,\n} from './types.js';\n\ntype LocalAppRow = {\n app_id: string;\n extension_id: string;\n project_id: string;\n name: string;\n description: string | null;\n idea: string;\n status: string;\n workspace_root: string;\n preview_token: string;\n draft_version: number;\n active_version: number | null;\n created_at: number;\n updated_at: number;\n installed_at: number | null;\n installation_state: string;\n enabled: number;\n active_release_id: string | null;\n};\n\ntype LocalAppReleaseRow = {\n release_id: string;\n app_id: string;\n version: number;\n source_hash: string;\n artifact_path: string | null;\n manifest_json: string;\n health_status: string;\n created_at: number;\n activated_at: number | null;\n};\n\ntype LocalAppAcceptanceRunRow = {\n run_id: string;\n app_id: string;\n source_hash: string;\n status: string;\n checks_json: string;\n interactive_count: number;\n created_at: number;\n};\n\ntype LocalAppGrantRow = {\n extension_id: string;\n app_id: string | null;\n manifest_digest: string;\n permissions_json: string;\n granted_at: number;\n revoked_at: number | null;\n};\n\nexport interface StoredLocalAppRelease extends LocalAppRelease {\n artifactPath: string;\n manifestJson: string;\n}\n\nfunction fromRow(row: LocalAppRow): LocalApp {\n return {\n id: row.app_id,\n extensionId: row.extension_id,\n projectId: row.project_id,\n name: row.name,\n description: row.description ?? undefined,\n idea: row.idea,\n status: row.status as LocalAppStatus,\n workspaceRoot: row.workspace_root,\n draftVersion: row.draft_version,\n activeVersion: row.active_version ?? undefined,\n activeReleaseId: row.active_release_id ?? undefined,\n installationState: row.installation_state as LocalApp['installationState'],\n enabled: row.enabled === 1,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n installedAt: row.installed_at ?? undefined,\n };\n}\n\nfunction releaseFromRow(row: LocalAppReleaseRow, activeReleaseId?: string): StoredLocalAppRelease {\n return {\n id: row.release_id,\n appId: row.app_id,\n version: row.version,\n sourceHash: row.source_hash,\n artifactPath: row.artifact_path ?? '',\n manifestJson: row.manifest_json,\n healthStatus: row.health_status as LocalAppRelease['healthStatus'],\n createdAt: row.created_at,\n activatedAt: row.activated_at ?? undefined,\n isActive: row.release_id === activeReleaseId,\n };\n}\n\nfunction acceptanceRunFromRow(row: LocalAppAcceptanceRunRow): LocalAppAcceptanceRun {\n return {\n id: row.run_id,\n appId: row.app_id,\n sourceHash: row.source_hash,\n status: row.status as LocalAppAcceptanceRun['status'],\n checks: JSON.parse(row.checks_json) as LocalAppAcceptanceCheck[],\n interactiveCount: row.interactive_count,\n createdAt: row.created_at,\n };\n}\n\nexport class LocalAppStore {\n create(input: {\n extensionId: string;\n projectId: string;\n name: string;\n description?: string;\n idea: string;\n workspaceRoot: string;\n previewToken: string;\n }): LocalApp {\n const now = Date.now();\n const id = randomUUID();\n runSqliteWriteTransaction((db) => {\n db.prepare(`INSERT INTO local_apps (\n app_id, extension_id, project_id, name, description, idea, status,\n workspace_root, preview_token, draft_version, created_at, updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, 'preview_ready', ?, ?, 1, ?, ?)`).run(\n id,\n input.extensionId,\n input.projectId,\n input.name,\n input.description ?? null,\n input.idea,\n input.workspaceRoot,\n input.previewToken,\n now,\n now,\n );\n });\n return this.get(id)!;\n }\n\n get(id: string): LocalApp | null {\n const row = getSqliteDatabase().prepare('SELECT * FROM local_apps WHERE app_id = ?').get(id) as LocalAppRow | undefined;\n return row ? fromRow(row) : null;\n }\n\n findByProjectId(projectId: string): LocalApp | null {\n const row = getSqliteDatabase()\n .prepare('SELECT * FROM local_apps WHERE project_id = ?')\n .get(projectId) as LocalAppRow | undefined;\n return row ? fromRow(row) : null;\n }\n\n findByExtensionId(extensionId: string): LocalApp | null {\n const row = getSqliteDatabase()\n .prepare('SELECT * FROM local_apps WHERE extension_id = ?')\n .get(extensionId) as LocalAppRow | undefined;\n return row ? fromRow(row) : null;\n }\n\n list(): LocalApp[] {\n const rows = getSqliteDatabase().prepare('SELECT * FROM local_apps ORDER BY updated_at DESC').all() as LocalAppRow[];\n return rows.map(fromRow);\n }\n\n findByPreviewToken(previewToken: string): LocalApp | null {\n const row = getSqliteDatabase().prepare('SELECT * FROM local_apps WHERE preview_token = ?').get(previewToken) as LocalAppRow | undefined;\n return row ? fromRow(row) : null;\n }\n\n getPreviewToken(id: string): string | null {\n const row = getSqliteDatabase().prepare('SELECT preview_token FROM local_apps WHERE app_id = ?').get(id) as { preview_token: string } | undefined;\n return row?.preview_token ?? null;\n }\n\n listReleases(appId: string): StoredLocalAppRelease[] {\n const app = this.get(appId);\n const rows = getSqliteDatabase()\n .prepare('SELECT * FROM local_app_releases WHERE app_id = ? ORDER BY version DESC')\n .all(appId) as LocalAppReleaseRow[];\n return rows.map((row) => releaseFromRow(row, app?.activeReleaseId));\n }\n\n getRelease(appId: string, releaseId: string): StoredLocalAppRelease | null {\n const app = this.get(appId);\n const row = getSqliteDatabase()\n .prepare('SELECT * FROM local_app_releases WHERE app_id = ? AND release_id = ?')\n .get(appId, releaseId) as LocalAppReleaseRow | undefined;\n return row ? releaseFromRow(row, app?.activeReleaseId) : null;\n }\n\n listAcceptanceRuns(appId: string, limit = 20): LocalAppAcceptanceRun[] {\n const rows = getSqliteDatabase()\n .prepare('SELECT * FROM local_app_acceptance_runs WHERE app_id = ? ORDER BY created_at DESC, rowid DESC LIMIT ?')\n .all(appId, Math.max(1, Math.min(Math.floor(limit), 100))) as LocalAppAcceptanceRunRow[];\n return rows.map(acceptanceRunFromRow);\n }\n\n getLatestAcceptanceForSource(appId: string, sourceHash: string): LocalAppAcceptanceRun | null {\n const row = getSqliteDatabase()\n .prepare(`SELECT * FROM local_app_acceptance_runs\n WHERE app_id = ? AND source_hash = ? ORDER BY created_at DESC, rowid DESC LIMIT 1`)\n .get(appId, sourceHash) as LocalAppAcceptanceRunRow | undefined;\n return row ? acceptanceRunFromRow(row) : null;\n }\n\n getUiGrant(extensionId: string, manifestDigest: string): LocalAppUiGrant | null {\n const row = getSqliteDatabase()\n .prepare(`SELECT * FROM extension_ui_grants\n WHERE extension_id = ? AND manifest_digest = ? AND revoked_at IS NULL`)\n .get(extensionId, manifestDigest) as LocalAppGrantRow | undefined;\n if (!row) return null;\n return {\n granted: true,\n extensionId: row.extension_id,\n appId: row.app_id ?? undefined,\n manifestDigest: row.manifest_digest,\n permissions: JSON.parse(row.permissions_json) as string[],\n grantedAt: row.granted_at,\n };\n }\n\n saveUiGrant(input: {\n extensionId: string;\n appId?: string;\n manifestDigest: string;\n permissions: string[];\n }): LocalAppUiGrant {\n const grantedAt = Date.now();\n getSqliteDatabase().prepare(`INSERT INTO extension_ui_grants (\n extension_id, app_id, manifest_digest, permissions_json, granted_at, revoked_at\n ) VALUES (?, ?, ?, ?, ?, NULL)\n ON CONFLICT(extension_id, manifest_digest) DO UPDATE SET\n app_id = excluded.app_id,\n permissions_json = excluded.permissions_json,\n granted_at = excluded.granted_at,\n revoked_at = NULL`).run(\n input.extensionId,\n input.appId ?? null,\n input.manifestDigest,\n JSON.stringify(input.permissions),\n grantedAt,\n );\n return {\n granted: true,\n extensionId: input.extensionId,\n appId: input.appId,\n manifestDigest: input.manifestDigest,\n permissions: input.permissions,\n grantedAt,\n };\n }\n\n recordAcceptance(appId: string, input: RecordLocalAppAcceptanceInput): LocalAppAcceptanceRun {\n const checksJson = JSON.stringify(input.checks);\n const latest = this.listAcceptanceRuns(appId, 1)[0];\n if (latest\n && latest.sourceHash === input.sourceHash\n && latest.status === input.status\n && latest.interactiveCount === input.interactiveCount\n && JSON.stringify(latest.checks) === checksJson) {\n return latest;\n }\n const row: LocalAppAcceptanceRunRow = {\n run_id: randomUUID(),\n app_id: appId,\n source_hash: input.sourceHash,\n status: input.status,\n checks_json: checksJson,\n interactive_count: input.interactiveCount,\n created_at: Date.now(),\n };\n getSqliteDatabase().prepare(`INSERT INTO local_app_acceptance_runs (\n run_id, app_id, source_hash, status, checks_json, interactive_count, created_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?)`).run(\n row.run_id,\n row.app_id,\n row.source_hash,\n row.status,\n row.checks_json,\n row.interactive_count,\n row.created_at,\n );\n return acceptanceRunFromRow(row);\n }\n\n markInstalled(input: {\n id: string;\n version: number;\n sourceHash: string;\n artifactPath: string;\n manifestJson: string;\n }): LocalApp {\n const now = Date.now();\n const releaseId = randomUUID();\n runSqliteWriteTransaction((db) => {\n db.prepare(`INSERT INTO local_app_releases (\n release_id, app_id, version, source_hash, artifact_path, manifest_json,\n health_status, created_at, activated_at\n ) VALUES (?, ?, ?, ?, ?, ?, 'healthy', ?, ?)`).run(\n releaseId,\n input.id,\n input.version,\n input.sourceHash,\n input.artifactPath,\n input.manifestJson,\n now,\n now,\n );\n db.prepare(`UPDATE local_apps SET status = 'installed', active_version = ?, active_release_id = ?,\n draft_version = ?, installation_state = 'installed', enabled = 1,\n installed_at = COALESCE(installed_at, ?), updated_at = ? WHERE app_id = ?`)\n .run(input.version, releaseId, input.version + 1, now, now, input.id);\n });\n return this.get(input.id)!;\n }\n\n activateRelease(appId: string, releaseId: string): LocalApp {\n const release = this.getRelease(appId, releaseId);\n if (!release) throw new Error('Local app release not found');\n const now = Date.now();\n runSqliteWriteTransaction((db) => {\n db.prepare('UPDATE local_app_releases SET activated_at = ? WHERE release_id = ?').run(now, releaseId);\n db.prepare(`UPDATE local_apps SET status = 'installed', active_version = ?, active_release_id = ?,\n installation_state = 'installed', enabled = 1, updated_at = ? WHERE app_id = ?`)\n .run(release.version, releaseId, now, appId);\n });\n return this.get(appId)!;\n }\n\n setEnabled(appId: string, enabled: boolean): LocalApp {\n const now = Date.now();\n getSqliteDatabase().prepare('UPDATE local_apps SET enabled = ?, updated_at = ? WHERE app_id = ?')\n .run(enabled ? 1 : 0, now, appId);\n const app = this.get(appId);\n if (!app) throw new Error('Local app not found');\n return app;\n }\n\n markUninstalled(appId: string): LocalApp {\n const now = Date.now();\n getSqliteDatabase().prepare(`UPDATE local_apps SET status = 'preview_ready', active_version = NULL,\n active_release_id = NULL, installation_state = 'not_installed', enabled = 0, updated_at = ? WHERE app_id = ?`)\n .run(now, appId);\n const app = this.get(appId);\n if (!app) throw new Error('Local app not found');\n return app;\n }\n}\n"],"mappings":";;;;AAqEA,SAAS,QAAQ,KAA4B;AAC3C,QAAO;EACL,IAAI,IAAI;EACR,aAAa,IAAI;EACjB,WAAW,IAAI;EACf,MAAM,IAAI;EACV,aAAa,IAAI,eAAe,KAAA;EAChC,MAAM,IAAI;EACV,QAAQ,IAAI;EACZ,eAAe,IAAI;EACnB,cAAc,IAAI;EAClB,eAAe,IAAI,kBAAkB,KAAA;EACrC,iBAAiB,IAAI,qBAAqB,KAAA;EAC1C,mBAAmB,IAAI;EACvB,SAAS,IAAI,YAAY;EACzB,WAAW,IAAI;EACf,WAAW,IAAI;EACf,aAAa,IAAI,gBAAgB,KAAA;EAClC;;AAGH,SAAS,eAAe,KAAyB,iBAAiD;AAChG,QAAO;EACL,IAAI,IAAI;EACR,OAAO,IAAI;EACX,SAAS,IAAI;EACb,YAAY,IAAI;EAChB,cAAc,IAAI,iBAAiB;EACnC,cAAc,IAAI;EAClB,cAAc,IAAI;EAClB,WAAW,IAAI;EACf,aAAa,IAAI,gBAAgB,KAAA;EACjC,UAAU,IAAI,eAAe;EAC9B;;AAGH,SAAS,qBAAqB,KAAsD;AAClF,QAAO;EACL,IAAI,IAAI;EACR,OAAO,IAAI;EACX,YAAY,IAAI;EAChB,QAAQ,IAAI;EACZ,QAAQ,KAAK,MAAM,IAAI,YAAY;EACnC,kBAAkB,IAAI;EACtB,WAAW,IAAI;EAChB;;AAGH,IAAa,gBAAb,MAA2B;CACzB,OAAO,OAQM;EACX,MAAM,MAAM,KAAK,KAAK;EACtB,MAAM,KAAK,YAAY;AACvB,6BAA2B,OAAO;AAChC,MAAG,QAAQ;;;mEAGkD,CAAC,IAC5D,IACA,MAAM,aACN,MAAM,WACN,MAAM,MACN,MAAM,eAAe,MACrB,MAAM,MACN,MAAM,eACN,MAAM,cACN,KACA,IACD;IACD;AACF,SAAO,KAAK,IAAI,GAAG;;CAGrB,IAAI,IAA6B;EAC/B,MAAM,MAAM,mBAAmB,CAAC,QAAQ,4CAA4C,CAAC,IAAI,GAAG;AAC5F,SAAO,MAAM,QAAQ,IAAI,GAAG;;CAG9B,gBAAgB,WAAoC;EAClD,MAAM,MAAM,mBAAmB,CAC5B,QAAQ,gDAAgD,CACxD,IAAI,UAAU;AACjB,SAAO,MAAM,QAAQ,IAAI,GAAG;;CAG9B,kBAAkB,aAAsC;EACtD,MAAM,MAAM,mBAAmB,CAC5B,QAAQ,kDAAkD,CAC1D,IAAI,YAAY;AACnB,SAAO,MAAM,QAAQ,IAAI,GAAG;;CAG9B,OAAmB;AAEjB,SADa,mBAAmB,CAAC,QAAQ,oDAAoD,CAAC,KACnF,CAAC,IAAI,QAAQ;;CAG1B,mBAAmB,cAAuC;EACxD,MAAM,MAAM,mBAAmB,CAAC,QAAQ,mDAAmD,CAAC,IAAI,aAAa;AAC7G,SAAO,MAAM,QAAQ,IAAI,GAAG;;CAG9B,gBAAgB,IAA2B;AAEzC,SADY,mBAAmB,CAAC,QAAQ,wDAAwD,CAAC,IAAI,GAC3F,EAAE,iBAAiB;;CAG/B,aAAa,OAAwC;EACnD,MAAM,MAAM,KAAK,IAAI,MAAM;AAI3B,SAHa,mBAAmB,CAC7B,QAAQ,0EAA0E,CAClF,IAAI,MACI,CAAC,KAAK,QAAQ,eAAe,KAAK,KAAK,gBAAgB,CAAC;;CAGrE,WAAW,OAAe,WAAiD;EACzE,MAAM,MAAM,KAAK,IAAI,MAAM;EAC3B,MAAM,MAAM,mBAAmB,CAC5B,QAAQ,uEAAuE,CAC/E,IAAI,OAAO,UAAU;AACxB,SAAO,MAAM,eAAe,KAAK,KAAK,gBAAgB,GAAG;;CAG3D,mBAAmB,OAAe,QAAQ,IAA6B;AAIrE,SAHa,mBAAmB,CAC7B,QAAQ,wGAAwG,CAChH,IAAI,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,MAAM,MAAM,EAAE,IAAI,CAAC,CAChD,CAAC,IAAI,qBAAqB;;CAGvC,6BAA6B,OAAe,YAAkD;EAC5F,MAAM,MAAM,mBAAmB,CAC5B,QAAQ;2FAC4E,CACpF,IAAI,OAAO,WAAW;AACzB,SAAO,MAAM,qBAAqB,IAAI,GAAG;;CAG3C,WAAW,aAAqB,gBAAgD;EAC9E,MAAM,MAAM,mBAAmB,CAC5B,QAAQ;+EACgE,CACxE,IAAI,aAAa,eAAe;AACnC,MAAI,CAAC,IAAK,QAAO;AACjB,SAAO;GACL,SAAS;GACT,aAAa,IAAI;GACjB,OAAO,IAAI,UAAU,KAAA;GACrB,gBAAgB,IAAI;GACpB,aAAa,KAAK,MAAM,IAAI,iBAAiB;GAC7C,WAAW,IAAI;GAChB;;CAGH,YAAY,OAKQ;EAClB,MAAM,YAAY,KAAK,KAAK;AAC5B,qBAAmB,CAAC,QAAQ;;;;;;;yBAOP,CAAC,IACpB,MAAM,aACN,MAAM,SAAS,MACf,MAAM,gBACN,KAAK,UAAU,MAAM,YAAY,EACjC,UACD;AACD,SAAO;GACL,SAAS;GACT,aAAa,MAAM;GACnB,OAAO,MAAM;GACb,gBAAgB,MAAM;GACtB,aAAa,MAAM;GACnB;GACD;;CAGH,iBAAiB,OAAe,OAA6D;EAC3F,MAAM,aAAa,KAAK,UAAU,MAAM,OAAO;EAC/C,MAAM,SAAS,KAAK,mBAAmB,OAAO,EAAE,CAAC;AACjD,MAAI,UACC,OAAO,eAAe,MAAM,cAC5B,OAAO,WAAW,MAAM,UACxB,OAAO,qBAAqB,MAAM,oBAClC,KAAK,UAAU,OAAO,OAAO,KAAK,WACrC,QAAO;EAET,MAAM,MAAgC;GACpC,QAAQ,YAAY;GACpB,QAAQ;GACR,aAAa,MAAM;GACnB,QAAQ,MAAM;GACd,aAAa;GACb,mBAAmB,MAAM;GACzB,YAAY,KAAK,KAAK;GACvB;AACD,qBAAmB,CAAC,QAAQ;;oCAEI,CAAC,IAC/B,IAAI,QACJ,IAAI,QACJ,IAAI,aACJ,IAAI,QACJ,IAAI,aACJ,IAAI,mBACJ,IAAI,WACL;AACD,SAAO,qBAAqB,IAAI;;CAGlC,cAAc,OAMD;EACX,MAAM,MAAM,KAAK,KAAK;EACtB,MAAM,YAAY,YAAY;AAC9B,6BAA2B,OAAO;AAChC,MAAG,QAAQ;;;oDAGmC,CAAC,IAC7C,WACA,MAAM,IACN,MAAM,SACN,MAAM,YACN,MAAM,cACN,MAAM,cACN,KACA,IACD;AACD,MAAG,QAAQ;;mFAEkE,CAC1E,IAAI,MAAM,SAAS,WAAW,MAAM,UAAU,GAAG,KAAK,KAAK,MAAM,GAAG;IACvE;AACF,SAAO,KAAK,IAAI,MAAM,GAAG;;CAG3B,gBAAgB,OAAe,WAA6B;EAC1D,MAAM,UAAU,KAAK,WAAW,OAAO,UAAU;AACjD,MAAI,CAAC,QAAS,OAAM,IAAI,MAAM,8BAA8B;EAC5D,MAAM,MAAM,KAAK,KAAK;AACtB,6BAA2B,OAAO;AAChC,MAAG,QAAQ,sEAAsE,CAAC,IAAI,KAAK,UAAU;AACrG,MAAG,QAAQ;wFACuE,CAC/E,IAAI,QAAQ,SAAS,WAAW,KAAK,MAAM;IAC9C;AACF,SAAO,KAAK,IAAI,MAAM;;CAGxB,WAAW,OAAe,SAA4B;EACpD,MAAM,MAAM,KAAK,KAAK;AACtB,qBAAmB,CAAC,QAAQ,qEAAqE,CAC9F,IAAI,UAAU,IAAI,GAAG,KAAK,MAAM;EACnC,MAAM,MAAM,KAAK,IAAI,MAAM;AAC3B,MAAI,CAAC,IAAK,OAAM,IAAI,MAAM,sBAAsB;AAChD,SAAO;;CAGT,gBAAgB,OAAyB;EACvC,MAAM,MAAM,KAAK,KAAK;AACtB,qBAAmB,CAAC,QAAQ;oHACoF,CAC7G,IAAI,KAAK,MAAM;EAClB,MAAM,MAAM,KAAK,IAAI,MAAM;AAC3B,MAAI,CAAC,IAAK,OAAM,IAAI,MAAM,sBAAsB;AAChD,SAAO"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
export type LocalAppStatus = 'preview_ready' | 'installed' | 'degraded';
|
|
2
|
+
export type LocalAppInstallationState = 'not_installed' | 'installed';
|
|
3
|
+
export type LocalAppReleaseHealth = 'healthy' | 'failed';
|
|
4
|
+
export interface LocalAppRelease {
|
|
5
|
+
id: string;
|
|
6
|
+
appId: string;
|
|
7
|
+
version: number;
|
|
8
|
+
sourceHash: string;
|
|
9
|
+
healthStatus: LocalAppReleaseHealth;
|
|
10
|
+
createdAt: number;
|
|
11
|
+
activatedAt?: number;
|
|
12
|
+
isActive: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface LocalApp {
|
|
15
|
+
id: string;
|
|
16
|
+
extensionId: string;
|
|
17
|
+
projectId: string;
|
|
18
|
+
name: string;
|
|
19
|
+
description?: string;
|
|
20
|
+
idea: string;
|
|
21
|
+
status: LocalAppStatus;
|
|
22
|
+
workspaceRoot: string;
|
|
23
|
+
draftVersion: number;
|
|
24
|
+
activeVersion?: number;
|
|
25
|
+
activeReleaseId?: string;
|
|
26
|
+
installationState: LocalAppInstallationState;
|
|
27
|
+
enabled: boolean;
|
|
28
|
+
createdAt: number;
|
|
29
|
+
updatedAt: number;
|
|
30
|
+
installedAt?: number;
|
|
31
|
+
}
|
|
32
|
+
export interface LocalAppDetail extends LocalApp {
|
|
33
|
+
previewUrl: string;
|
|
34
|
+
permissions: string[];
|
|
35
|
+
releases: LocalAppRelease[];
|
|
36
|
+
acceptanceRuns: LocalAppAcceptanceRun[];
|
|
37
|
+
}
|
|
38
|
+
export interface LocalAppUiGrant {
|
|
39
|
+
granted: boolean;
|
|
40
|
+
extensionId: string;
|
|
41
|
+
appId?: string;
|
|
42
|
+
manifestDigest?: string;
|
|
43
|
+
permissions: string[];
|
|
44
|
+
grantedAt?: number;
|
|
45
|
+
}
|
|
46
|
+
export interface LocalAppAcceptanceCheck {
|
|
47
|
+
id: 'document' | 'content' | 'interaction' | 'criteria';
|
|
48
|
+
status: 'passed' | 'failed' | 'skipped';
|
|
49
|
+
message: string;
|
|
50
|
+
}
|
|
51
|
+
export interface LocalAppAcceptanceRun {
|
|
52
|
+
id: string;
|
|
53
|
+
appId: string;
|
|
54
|
+
sourceHash: string;
|
|
55
|
+
status: 'passed' | 'failed';
|
|
56
|
+
checks: LocalAppAcceptanceCheck[];
|
|
57
|
+
interactiveCount: number;
|
|
58
|
+
createdAt: number;
|
|
59
|
+
}
|
|
60
|
+
export interface RecordLocalAppAcceptanceInput {
|
|
61
|
+
sourceHash: string;
|
|
62
|
+
status: 'passed' | 'failed';
|
|
63
|
+
checks: LocalAppAcceptanceCheck[];
|
|
64
|
+
interactiveCount: number;
|
|
65
|
+
}
|
|
66
|
+
export interface LocalAppValidationIssue {
|
|
67
|
+
code: string;
|
|
68
|
+
severity: 'error' | 'warning';
|
|
69
|
+
message: string;
|
|
70
|
+
}
|
|
71
|
+
export interface LocalAppChangedFile {
|
|
72
|
+
path: string;
|
|
73
|
+
status: 'added' | 'modified' | 'deleted';
|
|
74
|
+
}
|
|
75
|
+
export interface LocalAppAcceptanceScenarioSummary {
|
|
76
|
+
id: string;
|
|
77
|
+
name: string;
|
|
78
|
+
stepCount: number;
|
|
79
|
+
}
|
|
80
|
+
export interface LocalAppValidationResult {
|
|
81
|
+
status: 'healthy' | 'failed';
|
|
82
|
+
checkedAt: number;
|
|
83
|
+
sourceHash?: string;
|
|
84
|
+
hasDraftChanges: boolean;
|
|
85
|
+
changedFiles: LocalAppChangedFile[];
|
|
86
|
+
changedFileCount: number;
|
|
87
|
+
permissions: string[];
|
|
88
|
+
permissionDelta: {
|
|
89
|
+
added: string[];
|
|
90
|
+
removed: string[];
|
|
91
|
+
};
|
|
92
|
+
acceptanceScenarioCount: number;
|
|
93
|
+
acceptanceScenarios: LocalAppAcceptanceScenarioSummary[];
|
|
94
|
+
issues: LocalAppValidationIssue[];
|
|
95
|
+
}
|
|
96
|
+
export interface CreateLocalAppInput {
|
|
97
|
+
name: string;
|
|
98
|
+
idea: string;
|
|
99
|
+
description?: string;
|
|
100
|
+
}
|
|
101
|
+
export interface LocalAppPreviewTarget {
|
|
102
|
+
app: LocalApp;
|
|
103
|
+
previewToken: string;
|
|
104
|
+
uiRoot: string;
|
|
105
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -11,11 +11,12 @@ export { deleteSessionRecord, ensureSessionRecord, getCurrentSessionId, getGloba
|
|
|
11
11
|
export { appendTranscriptEntry, captureCompactionCheckpoint, getCompactionCheckpointDetail, listCompactionCheckpoints, loadCheckpointRows, loadLlmMessagesForSession, loadTranscriptRows, loadTranscriptRowsForSession, paginateTranscriptMessages, replaceTranscriptRows, restoreCompactionCheckpoint, } from './transcript-repository.js';
|
|
12
12
|
export { deleteNoteRecord, getNoteRecord, listNoteRecords, upsertNoteRecord, } from './notes-repository.js';
|
|
13
13
|
export { deleteNoteAgentContextRecord, getNoteAgentContextRecord, upsertNoteAgentContextRecord, type NoteAgentContextRecord, } from './note-agent-context-repository.js';
|
|
14
|
-
export {
|
|
15
|
-
export { appendMemorySignal, appendMemoryTraceEvent, deleteMemoryRecord, findLatestMemoryInjectTrace, getMemoryProviderState, getMemoryRecord, listMemorySignals, listMemoryTraceEvents, listMemoryRecords, searchMemoryRecords, setMemoryProviderState, setMemoryTraceFeedback, setLatestMemoryInjectFeedback, summarizeMemoryRecallFeedback, summarizeUserUnderstandingQuality, USER_UNDERSTANDING_REMEDIATION_POLICY, upsertMemoryRecord, type AppendMemorySignalInput, type AppendMemoryTraceEventInput, type FindLatestMemoryInjectTraceInput, type ListMemoryRecordsOptions, type MemoryRecallFeedbackSummary, type MemoryFeedbackRemediationResult, type MemorySignalRowPayload, type MemoryTraceFeedback, type MemoryTraceEventPayload, type UserUnderstandingQualityMetrics, type SearchMemoryRecordsOptions, type SetMemoryTraceFeedbackInput, type SetLatestMemoryInjectFeedbackInput, type UpsertMemoryRecordInput, } from './memory-records-repository.js';
|
|
14
|
+
export { searchMemoryIndex, syncMemoryIndex, type MemorySearchHit, } from './memory-index-repository.js';
|
|
15
|
+
export { appendMemorySignal, appendMemoryTraceEvent, deleteMemoryRecord, findLatestMemoryInjectTrace, getMemoryProviderState, getMemoryRecord, hasUnresolvedMemoryConflict, listMemorySignals, listMemoryTraceEvents, listMemoryRecords, markMemoryRecordsConflicted, searchMemoryRecords, setMemoryProviderState, setMemoryTraceFeedback, setLatestMemoryInjectFeedback, summarizeMemoryRecallFeedback, summarizeUserUnderstandingQuality, USER_UNDERSTANDING_REMEDIATION_POLICY, upsertMemoryRecord, type AppendMemorySignalInput, type AppendMemoryTraceEventInput, type FindLatestMemoryInjectTraceInput, type ListMemoryRecordsOptions, type MemoryRecallFeedbackSummary, type MemoryFeedbackRemediationResult, type MemorySignalRowPayload, type MemoryTraceFeedback, type MemoryTraceEventPayload, type UserUnderstandingQualityMetrics, type SearchMemoryRecordsOptions, type SetMemoryTraceFeedbackInput, type SetLatestMemoryInjectFeedbackInput, type UpsertMemoryRecordInput, } from './memory-records-repository.js';
|
|
16
16
|
export { attachMemoryEvidence, claimKnowledgeSourceItems, completeKnowledgeSourceItemSynthesis, deleteMemoryEvidenceForRecord, finishKnowledgeSyncRun, getKnowledgeConsumerWatermark, getKnowledgeSourceCursor, getKnowledgeSourceItem, listKnowledgeSourceItems, listKnowledgeSourceChanges, listKnowledgeSyncRuns, listMemoryEvidence, setKnowledgeSourceItemSynthesisStatus, setKnowledgeConsumerWatermark, setKnowledgeSourceCursor, startKnowledgeSyncRun, upsertKnowledgeSourceItems, } from './knowledge-repository.js';
|
|
17
17
|
export { deleteSessionConfig, getSessionConfig, hasSessionConfig, setSessionConfig, updateSessionConfig, } from './config-repository.js';
|
|
18
18
|
export { createObjectLinkRecord, getActivityEventRecord, listActivityRecords, listObjectActivityRecords, listObjectLinkRecords, listProjectActivityRecords, recordActivityEvent, } from './activity-repository.js';
|
|
19
19
|
export { appendConnectorExecutionAudit, claimConnectorWebhookDelivery, completeConnectorWebhookDelivery, consumeConnectorApproval, createConnectorApproval, decideConnectorApproval, deleteConnectorConnection, deleteConnectorInstallation, getConnectorConnection, getConnectorApproval, getConnectorInstallation, getCachedConnectorCatalogEntry, listCachedConnectorCatalogEntries, listConnectorActionMetadata, listConnectorApprovals, listConnectorConnections, listConnectorExecutionAudit, listConnectorInstallations, releaseConnectorWebhookDelivery, upsertConnectorActionMetadata, upsertConnectorCatalogEntry, upsertConnectorConnection, upsertConnectorInstallation, type CachedConnectorCatalogEntry, } from './connector-repository.js';
|
|
20
20
|
export { getUserTrustPolicy, setUserTrustPolicy, } from './user-trust-repository.js';
|
|
21
|
+
export { consumeMemoryReferenceConsent, decideMemoryReferenceConsent, ensureMemoryReferenceConsentRequest, hasMemoryReferenceConsent, listMemoryReferenceConsents, revokeMemoryReferenceConsent, type MemoryReferenceConsent, type MemoryReferenceGrantScope, } from './memory-reference-consent-repository.js';
|
|
21
22
|
export { getUserProfilePromptState, setUserProfilePromptState, } from './user-profile-setup-repository.js';
|
|
@@ -12,12 +12,13 @@ import { deleteSessionRecord, ensureSessionRecord, findSessionKeyBySessionId, ge
|
|
|
12
12
|
import { appendTranscriptEntry, captureCompactionCheckpoint, getCompactionCheckpointDetail, listCompactionCheckpoints, loadCheckpointRows, loadLlmMessagesForSession, loadTranscriptRows, loadTranscriptRowsForSession, paginateTranscriptMessages, replaceTranscriptRows, restoreCompactionCheckpoint } from "./transcript-repository.js";
|
|
13
13
|
import { deleteNoteRecord, getNoteRecord, listNoteRecords, upsertNoteRecord } from "./notes-repository.js";
|
|
14
14
|
import { deleteNoteAgentContextRecord, getNoteAgentContextRecord, upsertNoteAgentContextRecord } from "./note-agent-context-repository.js";
|
|
15
|
-
import {
|
|
16
|
-
import { USER_UNDERSTANDING_REMEDIATION_POLICY, appendMemorySignal, appendMemoryTraceEvent, deleteMemoryRecord, findLatestMemoryInjectTrace, getMemoryProviderState, getMemoryRecord, listMemoryRecords, listMemorySignals, listMemoryTraceEvents, searchMemoryRecords, setLatestMemoryInjectFeedback, setMemoryProviderState, setMemoryTraceFeedback, summarizeMemoryRecallFeedback, summarizeUserUnderstandingQuality, upsertMemoryRecord } from "./memory-records-repository.js";
|
|
15
|
+
import { searchMemoryIndex, syncMemoryIndex } from "./memory-index-repository.js";
|
|
16
|
+
import { USER_UNDERSTANDING_REMEDIATION_POLICY, appendMemorySignal, appendMemoryTraceEvent, deleteMemoryRecord, findLatestMemoryInjectTrace, getMemoryProviderState, getMemoryRecord, hasUnresolvedMemoryConflict, listMemoryRecords, listMemorySignals, listMemoryTraceEvents, markMemoryRecordsConflicted, searchMemoryRecords, setLatestMemoryInjectFeedback, setMemoryProviderState, setMemoryTraceFeedback, summarizeMemoryRecallFeedback, summarizeUserUnderstandingQuality, upsertMemoryRecord } from "./memory-records-repository.js";
|
|
17
17
|
import { attachMemoryEvidence, claimKnowledgeSourceItems, completeKnowledgeSourceItemSynthesis, deleteMemoryEvidenceForRecord, finishKnowledgeSyncRun, getKnowledgeConsumerWatermark, getKnowledgeSourceCursor, getKnowledgeSourceItem, listKnowledgeSourceChanges, listKnowledgeSourceItems, listKnowledgeSyncRuns, listMemoryEvidence, setKnowledgeConsumerWatermark, setKnowledgeSourceCursor, setKnowledgeSourceItemSynthesisStatus, startKnowledgeSyncRun, upsertKnowledgeSourceItems } from "./knowledge-repository.js";
|
|
18
18
|
import { deleteSessionConfig, getSessionConfig, hasSessionConfig, setSessionConfig, updateSessionConfig } from "./config-repository.js";
|
|
19
19
|
import { createObjectLinkRecord, getActivityEventRecord, listActivityRecords, listObjectActivityRecords, listObjectLinkRecords, listProjectActivityRecords, recordActivityEvent } from "./activity-repository.js";
|
|
20
20
|
import { appendConnectorExecutionAudit, claimConnectorWebhookDelivery, completeConnectorWebhookDelivery, consumeConnectorApproval, createConnectorApproval, decideConnectorApproval, deleteConnectorConnection, deleteConnectorInstallation, getCachedConnectorCatalogEntry, getConnectorApproval, getConnectorConnection, getConnectorInstallation, listCachedConnectorCatalogEntries, listConnectorActionMetadata, listConnectorApprovals, listConnectorConnections, listConnectorExecutionAudit, listConnectorInstallations, releaseConnectorWebhookDelivery, upsertConnectorActionMetadata, upsertConnectorCatalogEntry, upsertConnectorConnection, upsertConnectorInstallation } from "./connector-repository.js";
|
|
21
21
|
import { getUserTrustPolicy, setUserTrustPolicy } from "./user-trust-repository.js";
|
|
22
|
+
import { consumeMemoryReferenceConsent, decideMemoryReferenceConsent, ensureMemoryReferenceConsentRequest, hasMemoryReferenceConsent, listMemoryReferenceConsents, revokeMemoryReferenceConsent } from "./memory-reference-consent-repository.js";
|
|
22
23
|
import { getUserProfilePromptState, setUserProfilePromptState } from "./user-profile-setup-repository.js";
|
|
23
|
-
export { DatabaseSchemaMigrationGapError, DatabaseSchemaTooNewError, SCHEMA_META_SCHEMA_VERSION_KEY, USER_UNDERSTANDING_REMEDIATION_POLICY, XOPC_DB_BASELINE_SCHEMA_VERSION, XOPC_DB_FILENAME, XOPC_DB_SCHEMA_VERSION, appendConnectorExecutionAudit, appendMemorySignal, appendMemoryTraceEvent, appendTranscriptEntry, applyPendingMigrations, attachMemoryEvidence, buildDefaultSessionMetadata, buildGlobalSessionStats, captureCompactionCheckpoint, claimConnectorWebhookDelivery, claimKnowledgeSourceItems, classifyStoredRow, closeXopcDatabase, completeConnectorWebhookDelivery, completeKnowledgeSourceItemSynthesis, consumeConnectorApproval, createConnectorApproval, createObjectLinkRecord, decideConnectorApproval, deleteConnectorConnection, deleteConnectorInstallation, deleteMemoryEvidenceForRecord, deleteMemoryRecord, deleteNoteAgentContextRecord, deleteNoteRecord, deleteSessionConfig, deleteSessionRecord, discoverSqlMigrations, ensureSessionRecord, ensureXopcDatabaseSchema, estimateTokensFromMessages, extractFtsContent, findLatestMemoryInjectTrace, findSessionKeyBySessionId, finishKnowledgeSyncRun, getActivityEventRecord, getCachedConnectorCatalogEntry, getCompactionCheckpointDetail, getConnectorApproval, getConnectorConnection, getConnectorInstallation, getCurrentSessionId, getGlobalSessionStats, getKnowledgeConsumerWatermark, getKnowledgeSourceCursor, getKnowledgeSourceItem, getMemoryProviderState, getMemoryRecord, getNoteAgentContextRecord, getNoteRecord, getSessionConfig, getSessionMetadata, getSessionPersistedLevels, getSqliteDatabase, getUserProfilePromptState, getUserTrustPolicy, getXopcDatabase, hasSessionConfig, incrementSessionStatsOnAppend, inspectSchemaMigrationStatus, isXopcDatabaseOpen, listActivityRecords, listCachedConnectorCatalogEntries, listCompactionCheckpoints, listConnectorActionMetadata, listConnectorApprovals, listConnectorConnections, listConnectorExecutionAudit, listConnectorInstallations, listKnowledgeSourceChanges, listKnowledgeSourceItems, listKnowledgeSyncRuns, listMemoryEvidence, listMemoryRecords, listMemorySignals, listMemoryTraceEvents, listNoteRecords, listObjectActivityRecords, listObjectLinkRecords, listProjectActivityRecords, listRegisteredMigrationTargets, listSessionMetadata, listSessionsByAgent, loadCheckpointRows, loadLlmMessagesForSession, loadTranscriptRows, loadTranscriptRowsForSession, metadataToSessionInsert, openXopcDatabase, paginateTranscriptMessages, patchSessionMetadata, readSchemaVersion, readSchemaVersionForTest, recordActivityEvent, releaseConnectorWebhookDelivery, replaceTranscriptRows, requireXopcDatabase, resetSessionRecord, resetXopcDatabaseSingletonForTest,
|
|
24
|
+
export { DatabaseSchemaMigrationGapError, DatabaseSchemaTooNewError, SCHEMA_META_SCHEMA_VERSION_KEY, USER_UNDERSTANDING_REMEDIATION_POLICY, XOPC_DB_BASELINE_SCHEMA_VERSION, XOPC_DB_FILENAME, XOPC_DB_SCHEMA_VERSION, appendConnectorExecutionAudit, appendMemorySignal, appendMemoryTraceEvent, appendTranscriptEntry, applyPendingMigrations, attachMemoryEvidence, buildDefaultSessionMetadata, buildGlobalSessionStats, captureCompactionCheckpoint, claimConnectorWebhookDelivery, claimKnowledgeSourceItems, classifyStoredRow, closeXopcDatabase, completeConnectorWebhookDelivery, completeKnowledgeSourceItemSynthesis, consumeConnectorApproval, consumeMemoryReferenceConsent, createConnectorApproval, createObjectLinkRecord, decideConnectorApproval, decideMemoryReferenceConsent, deleteConnectorConnection, deleteConnectorInstallation, deleteMemoryEvidenceForRecord, deleteMemoryRecord, deleteNoteAgentContextRecord, deleteNoteRecord, deleteSessionConfig, deleteSessionRecord, discoverSqlMigrations, ensureMemoryReferenceConsentRequest, ensureSessionRecord, ensureXopcDatabaseSchema, estimateTokensFromMessages, extractFtsContent, findLatestMemoryInjectTrace, findSessionKeyBySessionId, finishKnowledgeSyncRun, getActivityEventRecord, getCachedConnectorCatalogEntry, getCompactionCheckpointDetail, getConnectorApproval, getConnectorConnection, getConnectorInstallation, getCurrentSessionId, getGlobalSessionStats, getKnowledgeConsumerWatermark, getKnowledgeSourceCursor, getKnowledgeSourceItem, getMemoryProviderState, getMemoryRecord, getNoteAgentContextRecord, getNoteRecord, getSessionConfig, getSessionMetadata, getSessionPersistedLevels, getSqliteDatabase, getUserProfilePromptState, getUserTrustPolicy, getXopcDatabase, hasMemoryReferenceConsent, hasSessionConfig, hasUnresolvedMemoryConflict, incrementSessionStatsOnAppend, inspectSchemaMigrationStatus, isXopcDatabaseOpen, listActivityRecords, listCachedConnectorCatalogEntries, listCompactionCheckpoints, listConnectorActionMetadata, listConnectorApprovals, listConnectorConnections, listConnectorExecutionAudit, listConnectorInstallations, listKnowledgeSourceChanges, listKnowledgeSourceItems, listKnowledgeSyncRuns, listMemoryEvidence, listMemoryRecords, listMemoryReferenceConsents, listMemorySignals, listMemoryTraceEvents, listNoteRecords, listObjectActivityRecords, listObjectLinkRecords, listProjectActivityRecords, listRegisteredMigrationTargets, listSessionMetadata, listSessionsByAgent, loadCheckpointRows, loadLlmMessagesForSession, loadTranscriptRows, loadTranscriptRowsForSession, markMemoryRecordsConflicted, metadataToSessionInsert, openXopcDatabase, paginateTranscriptMessages, patchSessionMetadata, readSchemaVersion, readSchemaVersionForTest, recordActivityEvent, releaseConnectorWebhookDelivery, replaceTranscriptRows, requireXopcDatabase, resetSessionRecord, resetXopcDatabaseSingletonForTest, resolveMigrationsDir, resolveSessionAgentId, resolveXopcDatabasePath, restoreCompactionCheckpoint, revokeMemoryReferenceConsent, runSqliteWriteTransaction, searchMemoryIndex, searchMemoryRecords, sessionConfigRowToConfig, sessionRowToMetadata, setKnowledgeConsumerWatermark, setKnowledgeSourceCursor, setKnowledgeSourceItemSynthesisStatus, setLatestMemoryInjectFeedback, setMemoryProviderState, setMemoryTraceFeedback, setSessionConfig, setUserProfilePromptState, setUserTrustPolicy, startKnowledgeSyncRun, summarizeMemoryRecallFeedback, summarizeUserUnderstandingQuality, syncMemoryIndex, transcriptEntryRowToStoredRow, updateSessionConfig, updateSessionStats, upsertConnectorActionMetadata, upsertConnectorCatalogEntry, upsertConnectorConnection, upsertConnectorInstallation, upsertKnowledgeSourceItems, upsertMemoryRecord, upsertNoteAgentContextRecord, upsertNoteRecord };
|
|
@@ -4,15 +4,14 @@ export type MemorySearchHit = {
|
|
|
4
4
|
score: number;
|
|
5
5
|
lineNumbers: number[];
|
|
6
6
|
};
|
|
7
|
-
export declare function resolveAgentIdFromMemoriesDir(memoriesDir: string | undefined): string;
|
|
8
7
|
export declare function syncMemoryIndex(params: {
|
|
9
|
-
|
|
8
|
+
userId: string;
|
|
10
9
|
workspaceDir: string;
|
|
11
10
|
memoriesDir?: string;
|
|
12
11
|
userMemoryPath?: string;
|
|
13
12
|
}): void;
|
|
14
13
|
export declare function searchMemoryIndex(params: {
|
|
15
|
-
|
|
14
|
+
userId: string;
|
|
16
15
|
query: string;
|
|
17
16
|
maxResults?: number;
|
|
18
17
|
minScore?: number;
|
|
@@ -8,10 +8,6 @@ const AGENT_MEMORY_FILENAME = "MEMORY.md";
|
|
|
8
8
|
const USER_MEMORY_DISPLAY_PATH = "user/MEMORY.md";
|
|
9
9
|
const MEMORY_SYNC_CACHE_TTL_MS = 3e4;
|
|
10
10
|
const memorySyncCache = /* @__PURE__ */ new Map();
|
|
11
|
-
function resolveAgentIdFromMemoriesDir(memoriesDir) {
|
|
12
|
-
if (!memoriesDir) return "main";
|
|
13
|
-
return memoriesDir.replace(/\\/g, "/").match(/\/agents\/([^/]+)\/memories\/?$/)?.[1] ?? "main";
|
|
14
|
-
}
|
|
15
11
|
function getDailyMemoryPath(baseDir, date) {
|
|
16
12
|
const d = date || /* @__PURE__ */ new Date();
|
|
17
13
|
return join(baseDir, "memory", `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}.md`);
|
|
@@ -50,23 +46,23 @@ function displayPath(baseDir, memoriesDir, userMemoryPath, absPath) {
|
|
|
50
46
|
function contentHash(content) {
|
|
51
47
|
return createHash("sha256").update(content).digest("hex");
|
|
52
48
|
}
|
|
53
|
-
function indexFile(db,
|
|
49
|
+
function indexFile(db, userId, baseDir, memoriesDir, userMemoryPath, absPath) {
|
|
54
50
|
const content = readFileSync(absPath, "utf-8");
|
|
55
51
|
const mtimeMs = statSync(absPath).mtimeMs;
|
|
56
52
|
const hash = contentHash(content);
|
|
57
53
|
const relPath = displayPath(baseDir, memoriesDir, userMemoryPath, absPath);
|
|
58
|
-
const fileId = `${
|
|
54
|
+
const fileId = `${userId}:${relPath}`;
|
|
59
55
|
const existing = db.prepare(`SELECT content_hash, mtime_ms FROM memory_files WHERE file_id = ?`).get(fileId);
|
|
60
56
|
if (existing && existing.content_hash === hash && existing.mtime_ms === mtimeMs) return;
|
|
61
57
|
db.prepare(`DELETE FROM memory_fts WHERE chunk_id IN (SELECT chunk_id FROM memory_chunks WHERE file_id = ?)`).run(fileId);
|
|
62
58
|
db.prepare(`DELETE FROM memory_chunks WHERE file_id = ?`).run(fileId);
|
|
63
59
|
db.prepare(`DELETE FROM memory_files WHERE file_id = ?`).run(fileId);
|
|
64
|
-
db.prepare(`INSERT INTO memory_files (file_id,
|
|
65
|
-
VALUES (?, ?, ?, ?, ?)`).run(fileId,
|
|
60
|
+
db.prepare(`INSERT INTO memory_files (file_id, user_id, path, mtime_ms, content_hash)
|
|
61
|
+
VALUES (?, ?, ?, ?, ?)`).run(fileId, userId, relPath, mtimeMs, hash);
|
|
66
62
|
const lines = content.split("\n");
|
|
67
63
|
const insertChunk = db.prepare(`INSERT INTO memory_chunks (chunk_id, file_id, start_line, end_line, content)
|
|
68
64
|
VALUES (?, ?, ?, ?, ?)`);
|
|
69
|
-
const insertFts = db.prepare(`INSERT INTO memory_fts (content, chunk_id,
|
|
65
|
+
const insertFts = db.prepare(`INSERT INTO memory_fts (content, chunk_id, user_id, path, start_line, end_line)
|
|
70
66
|
VALUES (?, ?, ?, ?, ?, ?)`);
|
|
71
67
|
for (let i = 0; i < lines.length; i++) {
|
|
72
68
|
const line = lines[i];
|
|
@@ -74,11 +70,11 @@ function indexFile(db, agentId, baseDir, memoriesDir, userMemoryPath, absPath) {
|
|
|
74
70
|
const lineNo = i + 1;
|
|
75
71
|
const chunkId = `${fileId}:${lineNo}`;
|
|
76
72
|
insertChunk.run(chunkId, fileId, lineNo, lineNo, line);
|
|
77
|
-
insertFts.run(line, chunkId,
|
|
73
|
+
insertFts.run(line, chunkId, userId, relPath, lineNo, lineNo);
|
|
78
74
|
}
|
|
79
75
|
}
|
|
80
76
|
function syncMemoryIndex(params) {
|
|
81
|
-
const cacheKey = `${params.
|
|
77
|
+
const cacheKey = `${params.userId}:${params.workspaceDir}:${params.memoriesDir ?? ""}:${params.userMemoryPath ?? ""}`;
|
|
82
78
|
const now = Date.now();
|
|
83
79
|
const cached = memorySyncCache.get(cacheKey);
|
|
84
80
|
if (cached && now - cached.timestamp < MEMORY_SYNC_CACHE_TTL_MS) return;
|
|
@@ -90,10 +86,10 @@ function syncMemoryIndex(params) {
|
|
|
90
86
|
runSqliteWriteTransaction((db) => {
|
|
91
87
|
const seen = /* @__PURE__ */ new Set();
|
|
92
88
|
for (const absPath of paths) {
|
|
93
|
-
seen.add(`${params.
|
|
94
|
-
indexFile(db, params.
|
|
89
|
+
seen.add(`${params.userId}:${displayPath(params.workspaceDir, params.memoriesDir, params.userMemoryPath, absPath)}`);
|
|
90
|
+
indexFile(db, params.userId, params.workspaceDir, params.memoriesDir, params.userMemoryPath, absPath);
|
|
95
91
|
}
|
|
96
|
-
const stale = db.prepare(`SELECT file_id FROM memory_files WHERE
|
|
92
|
+
const stale = db.prepare(`SELECT file_id FROM memory_files WHERE user_id = ?`).all(params.userId);
|
|
97
93
|
for (const row of stale) if (!seen.has(row.file_id)) {
|
|
98
94
|
db.prepare(`DELETE FROM memory_fts WHERE chunk_id IN (SELECT chunk_id FROM memory_chunks WHERE file_id = ?)`).run(row.file_id);
|
|
99
95
|
db.prepare(`DELETE FROM memory_chunks WHERE file_id = ?`).run(row.file_id);
|
|
@@ -102,19 +98,19 @@ function syncMemoryIndex(params) {
|
|
|
102
98
|
});
|
|
103
99
|
}
|
|
104
100
|
function searchMemoryIndex(params) {
|
|
105
|
-
const {
|
|
101
|
+
const { userId, query, maxResults = 5, minScore = .3 } = params;
|
|
106
102
|
const ftsQuery = buildFts5SearchQuery(query);
|
|
107
103
|
if (!ftsQuery) return [];
|
|
108
104
|
const db = getSqliteDatabase();
|
|
109
105
|
const rows = db.prepare(`SELECT chunk_id, path, start_line, end_line, content, bm25(memory_fts) AS rank
|
|
110
106
|
FROM memory_fts
|
|
111
|
-
WHERE memory_fts MATCH ? AND
|
|
107
|
+
WHERE memory_fts MATCH ? AND user_id = ?
|
|
112
108
|
ORDER BY rank
|
|
113
|
-
LIMIT ?`).all(ftsQuery,
|
|
109
|
+
LIMIT ?`).all(ftsQuery, userId, maxResults * 3);
|
|
114
110
|
if (rows.length === 0) return db.prepare(`SELECT chunk_id, path, start_line, end_line, content
|
|
115
111
|
FROM memory_fts
|
|
116
|
-
WHERE
|
|
117
|
-
LIMIT 500`).all(
|
|
112
|
+
WHERE user_id = ?
|
|
113
|
+
LIMIT 500`).all(userId).map((row) => ({
|
|
118
114
|
path: row.path,
|
|
119
115
|
lines: row.content,
|
|
120
116
|
score: memoryLexicalSimilarity(query, row.content),
|
|
@@ -137,6 +133,6 @@ function searchMemoryIndex(params) {
|
|
|
137
133
|
return results.slice(0, maxResults);
|
|
138
134
|
}
|
|
139
135
|
//#endregion
|
|
140
|
-
export {
|
|
136
|
+
export { searchMemoryIndex, syncMemoryIndex };
|
|
141
137
|
|
|
142
138
|
//# sourceMappingURL=memory-index-repository.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-index-repository.js","names":[],"sources":["../../../../src/storage/sqlite/memory-index-repository.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport { existsSync, readFileSync, statSync } from 'node:fs';\nimport { join, relative } from 'node:path';\n\nimport { buildFts5SearchQuery, fts5RankToScore, memoryLexicalSimilarity } from './fts.js';\nimport { getSqliteDatabase, runSqliteWriteTransaction } from './transaction.js';\n\nexport type MemorySearchHit = {\n path: string;\n lines: string;\n score: number;\n lineNumbers: number[];\n};\n\nconst AGENT_MEMORY_FILENAME = 'MEMORY.md';\nconst USER_MEMORY_DISPLAY_PATH = 'user/MEMORY.md';\nconst MEMORY_SYNC_CACHE_TTL_MS = 30_000;\n\ntype MemorySyncCache = {\n timestamp: number;\n paths: string[];\n};\n\nconst memorySyncCache = new Map<string, MemorySyncCache>();\n\nexport function resolveAgentIdFromMemoriesDir(memoriesDir: string | undefined): string {\n if (!memoriesDir) return 'main';\n const normalized = memoriesDir.replace(/\\\\/g, '/');\n const match = normalized.match(/\\/agents\\/([^/]+)\\/memories\\/?$/);\n return match?.[1] ?? 'main';\n}\n\nfunction getDailyMemoryPath(baseDir: string, date?: Date): string {\n const d = date || new Date();\n const year = d.getFullYear();\n const month = String(d.getMonth() + 1).padStart(2, '0');\n const day = String(d.getDate()).padStart(2, '0');\n return join(baseDir, 'memory', `${year}-${month}-${day}.md`);\n}\n\nfunction getCuratedMemoryPaths(memoriesDir: string | undefined, userMemoryPath: string | undefined): string[] {\n return [\n ...(memoriesDir ? [join(memoriesDir, AGENT_MEMORY_FILENAME)] : []),\n ...(userMemoryPath ? [userMemoryPath] : []),\n ].filter((p) => existsSync(p));\n}\n\nfunction collectMemoryPaths(baseDir: string, memoriesDir?: string, userMemoryPath?: string): string[] {\n const paths: string[] = [];\n paths.push(...getCuratedMemoryPaths(memoriesDir, userMemoryPath));\n\n const longTermPath = join(baseDir, 'MEMORY.md');\n if (existsSync(longTermPath)) {\n paths.push(longTermPath);\n }\n\n const memoryDir = join(baseDir, 'memory');\n if (existsSync(memoryDir)) {\n const today = new Date();\n for (let i = 0; i < 30; i++) {\n const date = new Date(today);\n date.setDate(date.getDate() - i);\n const path = getDailyMemoryPath(baseDir, date);\n if (existsSync(path)) {\n paths.push(path);\n }\n }\n }\n\n return paths;\n}\n\nfunction displayPath(\n baseDir: string,\n memoriesDir: string | undefined,\n userMemoryPath: string | undefined,\n absPath: string,\n): string {\n const normalized = absPath.replace(/\\\\/g, '/');\n if (userMemoryPath && normalized === userMemoryPath.replace(/\\\\/g, '/')) {\n return USER_MEMORY_DISPLAY_PATH;\n }\n if (memoriesDir) {\n const memoriesRoot = memoriesDir.replace(/\\\\/g, '/');\n if (normalized.startsWith(memoriesRoot)) {\n const filename = normalized.slice(memoriesRoot.length).replace(/^\\//, '');\n if (filename === AGENT_MEMORY_FILENAME) {\n return filename;\n }\n }\n }\n return relative(baseDir, absPath).replace(/\\\\/g, '/');\n}\n\nfunction contentHash(content: string): string {\n return createHash('sha256').update(content).digest('hex');\n}\n\nfunction indexFile(\n db: ReturnType<typeof getSqliteDatabase>,\n agentId: string,\n baseDir: string,\n memoriesDir: string | undefined,\n userMemoryPath: string | undefined,\n absPath: string,\n): void {\n const content = readFileSync(absPath, 'utf-8');\n const mtimeMs = statSync(absPath).mtimeMs;\n const hash = contentHash(content);\n const relPath = displayPath(baseDir, memoriesDir, userMemoryPath, absPath);\n const fileId = `${agentId}:${relPath}`;\n\n const existing = db\n .prepare(`SELECT content_hash, mtime_ms FROM memory_files WHERE file_id = ?`)\n .get(fileId) as { content_hash: string; mtime_ms: number } | undefined;\n if (existing && existing.content_hash === hash && existing.mtime_ms === mtimeMs) {\n return;\n }\n\n db.prepare(`DELETE FROM memory_fts WHERE chunk_id IN (SELECT chunk_id FROM memory_chunks WHERE file_id = ?)`).run(\n fileId,\n );\n db.prepare(`DELETE FROM memory_chunks WHERE file_id = ?`).run(fileId);\n db.prepare(`DELETE FROM memory_files WHERE file_id = ?`).run(fileId);\n\n db.prepare(\n `INSERT INTO memory_files (file_id, agent_id, path, mtime_ms, content_hash)\n VALUES (?, ?, ?, ?, ?)`,\n ).run(fileId, agentId, relPath, mtimeMs, hash);\n\n const lines = content.split('\\n');\n const insertChunk = db.prepare(\n `INSERT INTO memory_chunks (chunk_id, file_id, start_line, end_line, content)\n VALUES (?, ?, ?, ?, ?)`,\n );\n const insertFts = db.prepare(\n `INSERT INTO memory_fts (content, chunk_id, agent_id, path, start_line, end_line)\n VALUES (?, ?, ?, ?, ?, ?)`,\n );\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (!line.trim()) continue;\n const lineNo = i + 1;\n const chunkId = `${fileId}:${lineNo}`;\n insertChunk.run(chunkId, fileId, lineNo, lineNo, line);\n insertFts.run(line, chunkId, agentId, relPath, lineNo, lineNo);\n }\n}\n\nexport function syncMemoryIndex(params: {\n agentId: string;\n workspaceDir: string;\n memoriesDir?: string;\n userMemoryPath?: string;\n}): void {\n const cacheKey = `${params.agentId}:${params.workspaceDir}:${params.memoriesDir ?? ''}:${params.userMemoryPath ?? ''}`;\n const now = Date.now();\n const cached = memorySyncCache.get(cacheKey);\n if (cached && now - cached.timestamp < MEMORY_SYNC_CACHE_TTL_MS) {\n return;\n }\n\n const paths = collectMemoryPaths(params.workspaceDir, params.memoriesDir, params.userMemoryPath);\n memorySyncCache.set(cacheKey, { timestamp: now, paths });\n runSqliteWriteTransaction((db) => {\n const seen = new Set<string>();\n for (const absPath of paths) {\n seen.add(`${params.agentId}:${displayPath(params.workspaceDir, params.memoriesDir, params.userMemoryPath, absPath)}`);\n indexFile(db, params.agentId, params.workspaceDir, params.memoriesDir, params.userMemoryPath, absPath);\n }\n\n const stale = db\n .prepare(`SELECT file_id FROM memory_files WHERE agent_id = ?`)\n .all(params.agentId) as Array<{ file_id: string }>;\n for (const row of stale) {\n if (!seen.has(row.file_id)) {\n db.prepare(\n `DELETE FROM memory_fts WHERE chunk_id IN (SELECT chunk_id FROM memory_chunks WHERE file_id = ?)`,\n ).run(row.file_id);\n db.prepare(`DELETE FROM memory_chunks WHERE file_id = ?`).run(row.file_id);\n db.prepare(`DELETE FROM memory_files WHERE file_id = ?`).run(row.file_id);\n }\n }\n });\n}\n\nexport function searchMemoryIndex(params: {\n agentId: string;\n query: string;\n maxResults?: number;\n minScore?: number;\n}): MemorySearchHit[] {\n const { agentId, query, maxResults = 5, minScore = 0.3 } = params;\n const ftsQuery = buildFts5SearchQuery(query);\n if (!ftsQuery) {\n return [];\n }\n\n const db = getSqliteDatabase();\n const rows = db\n .prepare(\n `SELECT chunk_id, path, start_line, end_line, content, bm25(memory_fts) AS rank\n FROM memory_fts\n WHERE memory_fts MATCH ? AND agent_id = ?\n ORDER BY rank\n LIMIT ?`,\n )\n .all(ftsQuery, agentId, maxResults * 3) as Array<{\n chunk_id: string;\n path: string;\n start_line: number;\n end_line: number;\n content: string;\n rank: number;\n }>;\n\n if (rows.length === 0) {\n const fallbackRows = db.prepare(\n `SELECT chunk_id, path, start_line, end_line, content\n FROM memory_fts\n WHERE agent_id = ?\n LIMIT 500`,\n ).all(agentId) as Array<{\n chunk_id: string;\n path: string;\n start_line: number;\n end_line: number;\n content: string;\n }>;\n return fallbackRows\n .map((row) => ({\n path: row.path,\n lines: row.content,\n score: memoryLexicalSimilarity(query, row.content),\n lineNumbers: [row.start_line],\n }))\n .filter((result) => result.score >= minScore)\n .sort((a, b) => b.score - a.score)\n .slice(0, maxResults);\n }\n\n const bestRank = Math.min(...rows.map((row) => row.rank));\n const worstRank = Math.max(...rows.map((row) => row.rank));\n const results: MemorySearchHit[] = [];\n for (const row of rows) {\n const score = fts5RankToScore(row.rank, bestRank, worstRank);\n if (score < minScore) continue;\n results.push({\n path: row.path,\n lines: row.content,\n score,\n lineNumbers: [row.start_line],\n });\n }\n\n results.sort((a, b) => b.score - a.score);\n return results.slice(0, maxResults);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"memory-index-repository.js","names":[],"sources":["../../../../src/storage/sqlite/memory-index-repository.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport { existsSync, readFileSync, statSync } from 'node:fs';\nimport { join, relative } from 'node:path';\n\nimport { buildFts5SearchQuery, fts5RankToScore, memoryLexicalSimilarity } from './fts.js';\nimport { getSqliteDatabase, runSqliteWriteTransaction } from './transaction.js';\n\nexport type MemorySearchHit = {\n path: string;\n lines: string;\n score: number;\n lineNumbers: number[];\n};\n\nconst AGENT_MEMORY_FILENAME = 'MEMORY.md';\nconst USER_MEMORY_DISPLAY_PATH = 'user/MEMORY.md';\nconst MEMORY_SYNC_CACHE_TTL_MS = 30_000;\n\ntype MemorySyncCache = {\n timestamp: number;\n paths: string[];\n};\n\nconst memorySyncCache = new Map<string, MemorySyncCache>();\n\nfunction getDailyMemoryPath(baseDir: string, date?: Date): string {\n const d = date || new Date();\n const year = d.getFullYear();\n const month = String(d.getMonth() + 1).padStart(2, '0');\n const day = String(d.getDate()).padStart(2, '0');\n return join(baseDir, 'memory', `${year}-${month}-${day}.md`);\n}\n\nfunction getCuratedMemoryPaths(memoriesDir: string | undefined, userMemoryPath: string | undefined): string[] {\n return [\n ...(memoriesDir ? [join(memoriesDir, AGENT_MEMORY_FILENAME)] : []),\n ...(userMemoryPath ? [userMemoryPath] : []),\n ].filter((p) => existsSync(p));\n}\n\nfunction collectMemoryPaths(baseDir: string, memoriesDir?: string, userMemoryPath?: string): string[] {\n const paths: string[] = [];\n paths.push(...getCuratedMemoryPaths(memoriesDir, userMemoryPath));\n\n const longTermPath = join(baseDir, 'MEMORY.md');\n if (existsSync(longTermPath)) {\n paths.push(longTermPath);\n }\n\n const memoryDir = join(baseDir, 'memory');\n if (existsSync(memoryDir)) {\n const today = new Date();\n for (let i = 0; i < 30; i++) {\n const date = new Date(today);\n date.setDate(date.getDate() - i);\n const path = getDailyMemoryPath(baseDir, date);\n if (existsSync(path)) {\n paths.push(path);\n }\n }\n }\n\n return paths;\n}\n\nfunction displayPath(\n baseDir: string,\n memoriesDir: string | undefined,\n userMemoryPath: string | undefined,\n absPath: string,\n): string {\n const normalized = absPath.replace(/\\\\/g, '/');\n if (userMemoryPath && normalized === userMemoryPath.replace(/\\\\/g, '/')) {\n return USER_MEMORY_DISPLAY_PATH;\n }\n if (memoriesDir) {\n const memoriesRoot = memoriesDir.replace(/\\\\/g, '/');\n if (normalized.startsWith(memoriesRoot)) {\n const filename = normalized.slice(memoriesRoot.length).replace(/^\\//, '');\n if (filename === AGENT_MEMORY_FILENAME) {\n return filename;\n }\n }\n }\n return relative(baseDir, absPath).replace(/\\\\/g, '/');\n}\n\nfunction contentHash(content: string): string {\n return createHash('sha256').update(content).digest('hex');\n}\n\nfunction indexFile(\n db: ReturnType<typeof getSqliteDatabase>,\n userId: string,\n baseDir: string,\n memoriesDir: string | undefined,\n userMemoryPath: string | undefined,\n absPath: string,\n): void {\n const content = readFileSync(absPath, 'utf-8');\n const mtimeMs = statSync(absPath).mtimeMs;\n const hash = contentHash(content);\n const relPath = displayPath(baseDir, memoriesDir, userMemoryPath, absPath);\n const fileId = `${userId}:${relPath}`;\n\n const existing = db\n .prepare(`SELECT content_hash, mtime_ms FROM memory_files WHERE file_id = ?`)\n .get(fileId) as { content_hash: string; mtime_ms: number } | undefined;\n if (existing && existing.content_hash === hash && existing.mtime_ms === mtimeMs) {\n return;\n }\n\n db.prepare(`DELETE FROM memory_fts WHERE chunk_id IN (SELECT chunk_id FROM memory_chunks WHERE file_id = ?)`).run(\n fileId,\n );\n db.prepare(`DELETE FROM memory_chunks WHERE file_id = ?`).run(fileId);\n db.prepare(`DELETE FROM memory_files WHERE file_id = ?`).run(fileId);\n\n db.prepare(\n `INSERT INTO memory_files (file_id, user_id, path, mtime_ms, content_hash)\n VALUES (?, ?, ?, ?, ?)`,\n ).run(fileId, userId, relPath, mtimeMs, hash);\n\n const lines = content.split('\\n');\n const insertChunk = db.prepare(\n `INSERT INTO memory_chunks (chunk_id, file_id, start_line, end_line, content)\n VALUES (?, ?, ?, ?, ?)`,\n );\n const insertFts = db.prepare(\n `INSERT INTO memory_fts (content, chunk_id, user_id, path, start_line, end_line)\n VALUES (?, ?, ?, ?, ?, ?)`,\n );\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (!line.trim()) continue;\n const lineNo = i + 1;\n const chunkId = `${fileId}:${lineNo}`;\n insertChunk.run(chunkId, fileId, lineNo, lineNo, line);\n insertFts.run(line, chunkId, userId, relPath, lineNo, lineNo);\n }\n}\n\nexport function syncMemoryIndex(params: {\n userId: string;\n workspaceDir: string;\n memoriesDir?: string;\n userMemoryPath?: string;\n}): void {\n const cacheKey = `${params.userId}:${params.workspaceDir}:${params.memoriesDir ?? ''}:${params.userMemoryPath ?? ''}`;\n const now = Date.now();\n const cached = memorySyncCache.get(cacheKey);\n if (cached && now - cached.timestamp < MEMORY_SYNC_CACHE_TTL_MS) {\n return;\n }\n\n const paths = collectMemoryPaths(params.workspaceDir, params.memoriesDir, params.userMemoryPath);\n memorySyncCache.set(cacheKey, { timestamp: now, paths });\n runSqliteWriteTransaction((db) => {\n const seen = new Set<string>();\n for (const absPath of paths) {\n seen.add(`${params.userId}:${displayPath(params.workspaceDir, params.memoriesDir, params.userMemoryPath, absPath)}`);\n indexFile(db, params.userId, params.workspaceDir, params.memoriesDir, params.userMemoryPath, absPath);\n }\n\n const stale = db\n .prepare(`SELECT file_id FROM memory_files WHERE user_id = ?`)\n .all(params.userId) as Array<{ file_id: string }>;\n for (const row of stale) {\n if (!seen.has(row.file_id)) {\n db.prepare(\n `DELETE FROM memory_fts WHERE chunk_id IN (SELECT chunk_id FROM memory_chunks WHERE file_id = ?)`,\n ).run(row.file_id);\n db.prepare(`DELETE FROM memory_chunks WHERE file_id = ?`).run(row.file_id);\n db.prepare(`DELETE FROM memory_files WHERE file_id = ?`).run(row.file_id);\n }\n }\n });\n}\n\nexport function searchMemoryIndex(params: {\n userId: string;\n query: string;\n maxResults?: number;\n minScore?: number;\n}): MemorySearchHit[] {\n const { userId, query, maxResults = 5, minScore = 0.3 } = params;\n const ftsQuery = buildFts5SearchQuery(query);\n if (!ftsQuery) {\n return [];\n }\n\n const db = getSqliteDatabase();\n const rows = db\n .prepare(\n `SELECT chunk_id, path, start_line, end_line, content, bm25(memory_fts) AS rank\n FROM memory_fts\n WHERE memory_fts MATCH ? AND user_id = ?\n ORDER BY rank\n LIMIT ?`,\n )\n .all(ftsQuery, userId, maxResults * 3) as Array<{\n chunk_id: string;\n path: string;\n start_line: number;\n end_line: number;\n content: string;\n rank: number;\n }>;\n\n if (rows.length === 0) {\n const fallbackRows = db.prepare(\n `SELECT chunk_id, path, start_line, end_line, content\n FROM memory_fts\n WHERE user_id = ?\n LIMIT 500`,\n ).all(userId) as Array<{\n chunk_id: string;\n path: string;\n start_line: number;\n end_line: number;\n content: string;\n }>;\n return fallbackRows\n .map((row) => ({\n path: row.path,\n lines: row.content,\n score: memoryLexicalSimilarity(query, row.content),\n lineNumbers: [row.start_line],\n }))\n .filter((result) => result.score >= minScore)\n .sort((a, b) => b.score - a.score)\n .slice(0, maxResults);\n }\n\n const bestRank = Math.min(...rows.map((row) => row.rank));\n const worstRank = Math.max(...rows.map((row) => row.rank));\n const results: MemorySearchHit[] = [];\n for (const row of rows) {\n const score = fts5RankToScore(row.rank, bestRank, worstRank);\n if (score < minScore) continue;\n results.push({\n path: row.path,\n lines: row.content,\n score,\n lineNumbers: [row.start_line],\n });\n }\n\n results.sort((a, b) => b.score - a.score);\n return results.slice(0, maxResults);\n}\n"],"mappings":"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"}
|