@xopcai/xopc 0.0.320 → 0.0.323
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/dist/browser-ext/dist/assets/{auth-DKo-NMUY.js → auth-DocRzRlS.js} +95 -21
- package/dist/browser-ext/dist/background.js +1 -1
- package/dist/browser-ext/dist/sidepanel.html +1 -1
- package/dist/browser-ext/dist/sidepanel.js +18 -2
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BXLU0HJa.js → agent-avatar-dicebear-DFzmThVi.js} +1 -1
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-CAFHadiy.js +1 -0
- package/dist/gateway/static/root/assets/agent-plugin-dialog-DYFYiuig.js +1 -0
- package/dist/gateway/static/root/assets/{agents-hrbGiOHn.js → agents-BqIlB5Co.js} +1 -1
- package/dist/gateway/static/root/assets/{app-link-nL8iPwEr.js → app-link-C6gA5Nck.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-C0jEvonH.js → app-management-settings-panel-BgvMRGWe.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-ByVRv2Oe.js → appearance-settings-CliHU03A.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-Drt3Foi9.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-CMITc1PQ.js → archive-plugin-DnuPpm0u.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-B5Z1PKHm.js → attachment-load-BiwaK0ie.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-BOcXqVar.js → automations-page-CJSISGQH.js} +1 -1
- package/dist/gateway/static/root/assets/automations-workspace-B-Eduqwz.js +7 -0
- package/dist/gateway/static/root/assets/{binary-plugins-BkRb9adx.js → binary-plugins-KDjduQZO.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-DsmDlkC2.js → block-editor-bclvgove.js} +3 -3
- package/dist/gateway/static/root/assets/{browser-automation-inputs-BgBH3eFk.js → browser-automation-inputs-CfQ2T9t6.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-automations-page-e3KpurLo.js → browser-automations-page-Cxq38Nnp.js} +2 -2
- package/dist/gateway/static/root/assets/browser-settings-page-Dwgir6mu.js +3 -0
- package/dist/gateway/static/root/assets/capabilities-settings-panel-H5L5vynP.js +8 -0
- package/dist/gateway/static/root/assets/capabilities-uFKh3Hd0.js +1 -0
- package/dist/gateway/static/root/assets/channels-settings-RFBRYe5S.js +1 -0
- package/dist/gateway/static/root/assets/{chat-terminal-dock-DUdkU1C5.js → chat-terminal-dock-DKQC62nQ.js} +2 -2
- package/dist/gateway/static/root/assets/{computer-settings-page-C6WR9Syy.js → computer-settings-page-D1whpIqL.js} +1 -1
- package/dist/gateway/static/root/assets/{connector-service-page-SVKcySx0.js → connector-service-page-BAuYTgf5.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-page-Px-v3Q6Q.js +2 -0
- package/dist/gateway/static/root/assets/{date-picker-DBD5yedi.js → date-picker-CfCo3lqh.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-HE41Co5W.js → dependency-picker-DOuVO2M1.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-DH9EU9O3.js → desktop-pet-D9tu6Bhu.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-Br6Z1Vau.js → desktop-pet-settings-CQPXub2f.js} +1 -1
- package/dist/gateway/static/root/assets/device-pairing-wizard-DxkOYSut.js +1 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-CFjVNb1m.js → extension-debug-page-CtWClPz-.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-BQ3ldBhh.js → extension-page-BHh9HLCz.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-CaXnWbRI.js → extension-settings-page-BdT3v5Uh.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-swr-DgFmBSH9.js → gateway-config-swr-1eqyz9vZ.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-settings-CZas_Ekx.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-C7h3xef0.js → gateway-startup-retry-C4rsW6vJ.js} +1 -1
- package/dist/gateway/static/root/assets/home-page-w3_aWeNt.js +1 -0
- package/dist/gateway/static/root/assets/{image-generation-api-DJ1xaz2p.js → image-generation-api-B5DXMylk.js} +1 -1
- package/dist/gateway/static/root/assets/{imports-page-CaB54QIp.js → imports-page-B1JH0G5j.js} +1 -1
- package/dist/gateway/static/root/assets/index--3c0awkr.js +121 -0
- package/dist/gateway/static/root/assets/index-CNc4N4TX.css +1 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-DnvHvKQJ.js → keyboard-shortcuts-settings-DGrLJ8Yh.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-BYKrJpFF.js +1 -0
- package/dist/gateway/static/root/assets/local-apps-Bpja8nC6.js +1 -0
- package/dist/gateway/static/root/assets/local-apps-page-DqjStqbL.js +1 -0
- package/dist/gateway/static/root/assets/{locale-store-C4RjTd0C.js → locale-store-BIkcRr3t.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-N0q5DxnI.js → logs-page-Dl4kM4Na.js} +2 -2
- package/dist/gateway/static/root/assets/management-settings-gCfH4cwH.js +1 -0
- package/dist/gateway/static/root/assets/{markdown-view-DkPzc50Z.js → markdown-view-Ck_5MADq.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-BzLYE9lj.js → media-plugins-DTsZqgo6.js} +1 -1
- package/dist/gateway/static/root/assets/messages-7VAhscYe.js +3 -0
- package/dist/gateway/static/root/assets/note-detail-panel-j6sioeL1.js +5 -0
- package/dist/gateway/static/root/assets/notes-page-CMvvHv0f.js +8 -0
- package/dist/gateway/static/root/assets/{page-context-capture-button-DVnGa7Lu.js → page-context-capture-button-DTI_g4tz.js} +1 -1
- package/dist/gateway/static/root/assets/{page-tabs-q6lpN9OD.js → page-tabs-CfW_Q-K5.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-Ck63fJaQ.js → preview-open-alternatives-CuPN-vAn.js} +1 -1
- package/dist/gateway/static/root/assets/product-delivery-bv3z8Xkh.js +1 -0
- package/dist/gateway/static/root/assets/product-open-page-BHjxRz1E.js +1 -0
- package/dist/gateway/static/root/assets/project-detail-page-C9K_e-EV.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-Bk-es4i9.js +1 -0
- package/dist/gateway/static/root/assets/{registry-api-CRnytFLF.js → registry-api-BAAZUGnU.js} +1 -1
- package/dist/gateway/static/root/assets/remote-access-hub-CLGJNA42.js +1 -0
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-Bu3XyrDI.js → runtime-tools-settings-panel-CHJBJKL1.js} +2 -2
- package/dist/gateway/static/root/assets/{scenes-page-B_5HOUzl.js → scenes-page-ClLAD1pz.js} +2 -2
- package/dist/gateway/static/root/assets/{schema-form-CbOOKW1B.js → schema-form-FQAit5HL.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-Xj8MkXN1.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-DwALV8mi.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-D3UN4rb4.js → settings-form-section-BDc6bw1q.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-BHztZayW.js → settings-page-DnhxBJjV.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-layout-nskqtzZs.js → settings-page-layout-D3KNSQ5g.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-BtukdJ-z.js → setup-status-panel-F0rCQ-2a.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-DbYXEqur.js → share-preview-page-DVQCRxwK.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-C7hf6Cov.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-xPrFejRE.js +1 -0
- package/dist/gateway/static/root/assets/{skills-page-CK9Jeaur.js → skills-page-RdDYu7Yj.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page.utils-B44aWbyL.js → skills-page.utils-mDwC9UJ-.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-BwqpUGv_.js → system-settings-panel-Bk7GrMij.js} +1 -1
- package/dist/gateway/static/root/assets/task-detail-page-2A966jFY.js +1 -0
- package/dist/gateway/static/root/assets/{tunnel-api-BKTZzQIT.js → tunnel-api-D3Aquraj.js} +1 -1
- package/dist/gateway/static/root/assets/{use-autosave-BB1JBOCz.js → use-autosave-C1xQ-sHn.js} +1 -1
- package/dist/gateway/static/root/assets/user-model-page-CnBxPBVe.js +2 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-C-HsgED9.js → voice-api-key-field-DCNECvcp.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-config-api-DvJKYYA0.js → voice-config-api-B-_niUTU.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-K3e5ONUo.js → work-discovery-overlay-BrGx_JS_.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-dXRTHBoE.js → workflow-run-setup-panel-CmmC2Pdr.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-BZVpqw4T.js +6 -0
- package/dist/gateway/static/root/index.html +12 -11
- package/dist/package.js +1 -1
- package/dist/packages/gateway-contract/src/capabilities.js +4 -110
- package/dist/packages/gateway-contract/src/chat-previews.js +73 -0
- package/dist/packages/gateway-contract/src/index.js +6 -0
- package/dist/packages/gateway-contract/src/local-apps.js +215 -0
- package/dist/packages/gateway-contract/src/product-delivery.js +62 -17
- package/dist/packages/gateway-contract/src/user-turn-document.js +60 -0
- package/dist/src/agent/agent-manager.d.ts +1 -0
- package/dist/src/agent/agent-manager.js +5 -4
- package/dist/src/agent/background-review/run-background-review.js +1 -1
- package/dist/src/agent/embedded/model-runtime.js +1 -1
- package/dist/src/agent/embedded/run-for-session.js +1 -1
- package/dist/src/agent/embedded/transcript-runtime.d.ts +3 -0
- package/dist/src/agent/embedded/transcript-runtime.js +6 -0
- package/dist/src/agent/external-tools/cliProvider.js +4 -1
- package/dist/src/agent/external-tools/composio-provider.js +9 -3
- package/dist/src/agent/external-tools/gateway-tools.js +17 -10
- package/dist/src/agent/external-tools/mcp-provider.d.ts +3 -1
- package/dist/src/agent/external-tools/mcp-provider.js +91 -6
- package/dist/src/agent/external-tools/service.d.ts +2 -1
- package/dist/src/agent/external-tools/service.js +8 -3
- package/dist/src/agent/external-tools/types.d.ts +9 -0
- package/dist/src/agent/image/tool-model-config.js +1 -1
- package/dist/src/agent/mcp/bundle-mcp-config.js +37 -5
- package/dist/src/agent/mcp/bundle-mcp-gateway.d.ts +1 -0
- package/dist/src/agent/mcp/bundle-mcp-gateway.js +1 -0
- package/dist/src/agent/mcp/bundle-mcp-names.js +2 -1
- package/dist/src/agent/mcp/bundle-mcp-runtime.js +33 -1
- package/dist/src/agent/mcp/bundle-mcp-types.d.ts +4 -0
- package/dist/src/agent/mcp/index.js +1 -1
- package/dist/src/agent/mcp/mcp-stdio-transport.d.ts +1 -0
- package/dist/src/agent/mcp/mcp-stdio-transport.js +10 -0
- package/dist/src/agent/mcp/mcp-transport.js +12 -8
- package/dist/src/agent/mcp/oauth/index.js +1 -1
- package/dist/src/agent/mcp/oauth/mcp-oauth-manager.d.ts +6 -1
- package/dist/src/agent/mcp/oauth/mcp-oauth-manager.js +70 -14
- package/dist/src/agent/mcp/oauth/mcp-oauth-provider.js +1 -1
- package/dist/src/agent/mcp/oauth/mcp-oauth-session.d.ts +2 -0
- package/dist/src/agent/mcp/oauth/mcp-oauth-session.js +12 -0
- package/dist/src/agent/mcp/oauth/mcp-oauth-store.d.ts +3 -0
- package/dist/src/agent/mcp/oauth/mcp-oauth-store.js +14 -2
- package/dist/src/agent/mcp/plugin-http-fetch.d.ts +2 -0
- package/dist/src/agent/mcp/plugin-http-fetch.js +56 -0
- package/dist/src/agent/service/process-direct-streaming.js +27 -12
- package/dist/src/agent/service.js +3 -2
- package/dist/src/agent/service.types.d.ts +2 -0
- package/dist/src/agent/session/session-inspector.js +1 -1
- package/dist/src/agent/skills/hub-lock.js +1 -1
- package/dist/src/agent/skills/hub-pull.js +1 -1
- package/dist/src/agent/skills/index.js +8 -1
- package/dist/src/agent/skills/skill-manager.d.ts +2 -0
- package/dist/src/agent/skills/skill-manager.js +8 -0
- package/dist/src/agent/skills/skill-sources.js +17 -0
- package/dist/src/agent/skills/types.d.ts +3 -1
- package/dist/src/agent/source-context/injector.js +10 -5
- package/dist/src/agent/source-context/types.d.ts +3 -0
- package/dist/src/agent/source-context/types.js +8 -2
- package/dist/src/agent/tasks/task-judge-service.js +3 -3
- package/dist/src/agent/tool-manuals/xopc-use.d.ts +1 -1
- package/dist/src/agent/tool-manuals/xopc-use.js +12 -2
- package/dist/src/agent/tools/automation-tool.js +1 -1
- package/dist/src/agent/tools/factory.d.ts +1 -0
- package/dist/src/agent/tools/factory.js +2 -1
- package/dist/src/agent/tools/search/registry.js +4 -1
- package/dist/src/agent/tools/workflow-tool.js +1 -1
- package/dist/src/agent/tools/write.js +1 -1
- package/dist/src/agent/tools/xopc-use-tool.d.ts +4 -2
- package/dist/src/agent/tools/xopc-use-tool.js +120 -12
- package/dist/src/ai-assist/text-assist.js +1 -1
- package/dist/src/auth/credentials.js +2 -2
- package/dist/src/auth/oauth/xopc-cloud.js +1 -1
- package/dist/src/auth/profiles/store.js +1 -1
- package/dist/src/auth/sync-provider-auth.js +2 -2
- package/dist/src/browser/providers/browser-ext-install.js +1 -1
- package/dist/src/chat-commands/agent-edit.js +1 -1
- package/dist/src/chat-previews/index.d.ts +2 -0
- package/dist/src/chat-previews/index.js +3 -0
- package/dist/src/chat-previews/service.d.ts +27 -0
- package/dist/src/chat-previews/service.js +106 -0
- package/dist/src/chat-previews/store.d.ts +28 -0
- package/dist/src/chat-previews/store.js +77 -0
- package/dist/src/cli/commands/agent.js +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/doctor/checks/provider-auth.js +3 -3
- package/dist/src/cli/commands/extension-agent-plugin.d.ts +8 -0
- package/dist/src/cli/commands/extension-agent-plugin.js +82 -0
- package/dist/src/cli/commands/extension-marketplace.js +44 -4
- package/dist/src/cli/commands/extension.js +35 -3
- package/dist/src/cli/commands/models.js +1 -1
- package/dist/src/computer/runtime.js +1 -1
- package/dist/src/config/index.js +4 -4
- package/dist/src/config/loader.js +2 -2
- package/dist/src/config/models-json.js +2 -2
- package/dist/src/config/schema.js +2 -2
- package/dist/src/connectors/account-selection.js +1 -1
- package/dist/src/connectors/connection-candidates.d.ts +4 -1
- package/dist/src/connectors/connection-candidates.js +8 -2
- package/dist/src/connectors/connection-capabilities.d.ts +2 -2
- package/dist/src/connectors/connection-capabilities.js +3 -1
- package/dist/src/connectors/connection-recovery-service.d.ts +6 -1
- package/dist/src/connectors/connection-recovery-service.js +138 -26
- package/dist/src/connectors/plugin-mcp-recovery.d.ts +28 -0
- package/dist/src/connectors/plugin-mcp-recovery.js +90 -0
- package/dist/src/extensions/agent-plugins/auth.d.ts +39 -0
- package/dist/src/extensions/agent-plugins/auth.js +156 -0
- package/dist/src/extensions/agent-plugins/connection.d.ts +8 -0
- package/dist/src/extensions/agent-plugins/connection.js +41 -0
- package/dist/src/extensions/agent-plugins/health.d.ts +4 -0
- package/dist/src/extensions/agent-plugins/health.js +48 -0
- package/dist/src/extensions/agent-plugins/inventory.d.ts +53 -0
- package/dist/src/extensions/agent-plugins/inventory.js +34 -0
- package/dist/src/extensions/agent-plugins/mcp-adapter.d.ts +3 -0
- package/dist/src/extensions/agent-plugins/mcp-adapter.js +47 -0
- package/dist/src/extensions/agent-plugins/sources.d.ts +5 -0
- package/dist/src/extensions/agent-plugins/sources.js +72 -0
- package/dist/src/extensions/agent-plugins/store.d.ts +61 -0
- package/dist/src/extensions/agent-plugins/store.js +305 -0
- package/dist/src/extensions/agent-plugins/validation.d.ts +59 -0
- package/dist/src/extensions/agent-plugins/validation.js +211 -0
- package/dist/src/extensions/lockfile.js +1 -1
- package/dist/src/extensions/update.js +1 -1
- package/dist/src/gateway/agents-admin.js +1 -1
- package/dist/src/gateway/chat-stream/mapper.js +10 -3
- package/dist/src/gateway/file-path-classifier.js +1 -1
- package/dist/src/gateway/hono/lib/config-payload.js +1 -1
- package/dist/src/gateway/hono/routes/agent-plugins.d.ts +3 -0
- package/dist/src/gateway/hono/routes/agent-plugins.js +166 -0
- package/dist/src/gateway/hono/routes/agent-stream.js +14 -0
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js +4 -2
- package/dist/src/gateway/hono/routes/chat-previews.d.ts +3 -0
- package/dist/src/gateway/hono/routes/chat-previews.js +41 -0
- package/dist/src/gateway/hono/routes/connection-waits.js +4 -2
- package/dist/src/gateway/hono/routes/index.js +2 -0
- package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
- package/dist/src/gateway/hono/routes/local-apps.js +71 -39
- package/dist/src/gateway/hono/routes/mcp.js +48 -21
- package/dist/src/gateway/hono/routes/models.js +1 -1
- package/dist/src/gateway/hono/routes/session-input-handler.d.ts +4 -0
- package/dist/src/gateway/hono/routes/session-input-handler.js +22 -0
- package/dist/src/gateway/hono/routes/side-chats.js +11 -0
- package/dist/src/gateway/service/agent-runner.js +7 -1
- package/dist/src/gateway/service/config-coordinator.js +1 -1
- package/dist/src/gateway/service/marketplace-service.d.ts +1 -0
- package/dist/src/gateway/service/marketplace-service.js +15 -1
- package/dist/src/gateway/service/session-input-coordinator.js +3 -3
- package/dist/src/gateway/service.d.ts +5 -1
- package/dist/src/gateway/service.js +19 -5
- package/dist/src/gateway/side-chat/index.d.ts +3 -1
- package/dist/src/gateway/side-chat/index.js +2 -1
- package/dist/src/gateway/side-chat/manager.d.ts +16 -0
- package/dist/src/gateway/side-chat/manager.js +40 -6
- package/dist/src/gateway/side-chat/promotion-service.d.ts +19 -0
- package/dist/src/gateway/side-chat/promotion-service.js +111 -0
- package/dist/src/gateway/side-chat/run-service.js +1 -0
- package/dist/src/gateway/side-chat/types.d.ts +1 -1
- package/dist/src/local-apps/artifact-files.d.ts +3 -0
- package/dist/src/local-apps/artifact-files.js +45 -0
- package/dist/src/local-apps/capabilities/write.js +1 -1
- package/dist/src/local-apps/fix-guidance.d.ts +3 -0
- package/dist/src/local-apps/fix-guidance.js +75 -0
- package/dist/src/local-apps/index.d.ts +2 -1
- package/dist/src/local-apps/scaffold.d.ts +5 -0
- package/dist/src/local-apps/scaffold.js +18 -5
- package/dist/src/local-apps/service.d.ts +18 -3
- package/dist/src/local-apps/service.js +106 -64
- package/dist/src/local-apps/snapshot-store.d.ts +8 -0
- package/dist/src/local-apps/snapshot-store.js +68 -0
- package/dist/src/local-apps/types.d.ts +4 -87
- package/dist/src/notes/service.js +1 -1
- package/dist/src/providers/auth-runtime/resolve-auth.js +1 -1
- package/dist/src/providers/index.js +2 -2
- package/dist/src/providers/model-catalog-persistence.js +1 -1
- package/dist/src/providers/model-registry.js +1 -1
- package/dist/src/providers/register-runtime-providers.js +1 -1
- package/dist/src/session/client-history.d.ts +3 -1
- package/dist/src/session/client-history.js +10 -3
- package/dist/src/session/index.d.ts +1 -1
- package/dist/src/session/manager.d.ts +4 -0
- package/dist/src/session/manager.js +6 -0
- package/dist/src/session/session-context-for-llm.d.ts +12 -1
- package/dist/src/session/session-context-for-llm.js +16 -2
- package/dist/src/session/store.d.ts +14 -0
- package/dist/src/session/store.js +17 -0
- package/dist/src/session/stored-rows-to-file-entries.js +10 -1
- package/dist/src/session/transcript-outline.js +10 -3
- package/dist/src/storage/sqlite/connection-wait-repository.js +9 -3
- package/dist/src/storage/sqlite/migrations/202_chat_previews.sql +26 -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/row-mappers.js +6 -1
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/tui/backends/embedded-backend.js +1 -1
- package/dist/src/tui/tui-commands.js +1 -1
- package/dist/src/tui/tui-startup-resources.js +1 -1
- package/dist/src/tui/tui.js +2 -2
- package/dist/src/voice/tts/audio.js +1 -1
- package/dist/src/work-discovery/service.js +2 -2
- package/dist/src/workflows/service/workflow-run-service.js +1 -1
- package/package.json +4 -4
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-BGCqlTcR.js +0 -1
- package/dist/gateway/static/root/assets/api-DEneywgz.js +0 -1
- package/dist/gateway/static/root/assets/apps-page-vC87gAyb.js +0 -1
- package/dist/gateway/static/root/assets/automations-workspace-CzYmREol.js +0 -7
- package/dist/gateway/static/root/assets/browser-settings-page-BxaSzUIU.js +0 -3
- package/dist/gateway/static/root/assets/capabilities-D0S3DuAD.js +0 -1
- package/dist/gateway/static/root/assets/capabilities-settings-panel-CFCu-8da.js +0 -8
- package/dist/gateway/static/root/assets/channels-settings-CENp82yt.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-g_KTZWCb.js +0 -2
- package/dist/gateway/static/root/assets/device-pairing-wizard-DO7jp0ep.js +0 -1
- package/dist/gateway/static/root/assets/gateway-settings-BkeSEBxk.js +0 -1
- package/dist/gateway/static/root/assets/home-page-KoQXV4hp.js +0 -1
- package/dist/gateway/static/root/assets/index-ZxnWUdPv.css +0 -1
- package/dist/gateway/static/root/assets/index-u4709aCa.js +0 -89
- package/dist/gateway/static/root/assets/local-app-workbench-page-7QX0YFa7.js +0 -2
- package/dist/gateway/static/root/assets/local-apps-page-RSAl-NhO.js +0 -1
- package/dist/gateway/static/root/assets/management-settings-C_cb0Kue.js +0 -1
- package/dist/gateway/static/root/assets/messages-M5xl1fHE.js +0 -3
- package/dist/gateway/static/root/assets/note-detail-panel-CVWst-Er.js +0 -5
- package/dist/gateway/static/root/assets/notes-page-BFwCgIls.js +0 -8
- package/dist/gateway/static/root/assets/product-delivery-chCjIpvu.js +0 -1
- package/dist/gateway/static/root/assets/product-open-page-BIGvTs9n.js +0 -1
- package/dist/gateway/static/root/assets/project-detail-page-BFEtpkcf.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-CHr-P2z4.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-PhEyHSOb.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-CmIhlHPS.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-CCOTu1jb.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-CG1sll8V.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-Byq23h9c.js +0 -1
- package/dist/gateway/static/root/assets/task-detail-page-D5q-wk_d.js +0 -1
- package/dist/gateway/static/root/assets/user-model-page-DE3ZeJL3.js +0 -2
- package/dist/gateway/static/root/assets/workflows-page-DGZaETmN.js +0 -6
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createLogger } from "../../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../../utils/logger.js";
|
|
3
|
+
import { parseUserTurnDocument, userTurnDocumentRefIds } from "../../../../packages/gateway-contract/src/user-turn-document.js";
|
|
3
4
|
import { browserPageContextsInputSchema } from "../../../../packages/gateway-contract/src/browser-page-context.js";
|
|
4
5
|
import { init_src } from "../../../../packages/gateway-contract/src/index.js";
|
|
5
6
|
import { endpointTurnClaimSchema, init_src as init_src$1 } from "../../../../packages/endpoint-tools-protocol/src/index.js";
|
|
@@ -24,6 +25,13 @@ init_providers();
|
|
|
24
25
|
init_logger();
|
|
25
26
|
const MAX_TURN_CONTEXTS = 5;
|
|
26
27
|
const log = createLogger("Gateway:SessionInput");
|
|
28
|
+
function contextDocumentIsValid(content, refs) {
|
|
29
|
+
if (!refs) return false;
|
|
30
|
+
const document = parseUserTurnDocument(content);
|
|
31
|
+
if (!document) return true;
|
|
32
|
+
const available = new Set(refs.flatMap((ref) => ref.refId ? [ref.refId] : []));
|
|
33
|
+
return userTurnDocumentRefIds(document).every((refId) => available.has(refId));
|
|
34
|
+
}
|
|
27
35
|
async function submitSessionInput(c, deps, conversationId, options) {
|
|
28
36
|
const body = await c.req.json().catch(() => null);
|
|
29
37
|
if (!body || !conversationId) return c.json({
|
|
@@ -51,6 +59,13 @@ async function submitSessionInput(c, deps, conversationId, options) {
|
|
|
51
59
|
}
|
|
52
60
|
}, 400);
|
|
53
61
|
const content = typeof body.content === "string" ? body.content : "";
|
|
62
|
+
if (!contextDocumentIsValid(content, contextRefs)) return c.json({
|
|
63
|
+
ok: false,
|
|
64
|
+
error: {
|
|
65
|
+
code: "BAD_REQUEST",
|
|
66
|
+
message: "Input contains an unknown context reference"
|
|
67
|
+
}
|
|
68
|
+
}, 400);
|
|
54
69
|
if (options?.taskConversation && isTaskDestructiveCommand(content)) return c.json({
|
|
55
70
|
ok: false,
|
|
56
71
|
error: {
|
|
@@ -239,6 +254,13 @@ async function replaceLatestSessionTurn(c, deps, conversationId, targetTurnId) {
|
|
|
239
254
|
}
|
|
240
255
|
}, 400);
|
|
241
256
|
const content = typeof body.content === "string" ? body.content : "";
|
|
257
|
+
if (!contextDocumentIsValid(content, contextRefs)) return c.json({
|
|
258
|
+
ok: false,
|
|
259
|
+
error: {
|
|
260
|
+
code: "BAD_REQUEST",
|
|
261
|
+
message: "Input contains an unknown context reference"
|
|
262
|
+
}
|
|
263
|
+
}, 400);
|
|
242
264
|
const contentError = validateWebchatContent(content);
|
|
243
265
|
if (contentError) return c.json({
|
|
244
266
|
ok: false,
|
|
@@ -157,6 +157,17 @@ function registerSideChatRoutes(authenticated, deps) {
|
|
|
157
157
|
return respondSideChatError(c, error);
|
|
158
158
|
}
|
|
159
159
|
});
|
|
160
|
+
authenticated.post("/api/side-chats/:sideChatId/promote", deps.chatRateLimitMiddleware, async (c) => {
|
|
161
|
+
try {
|
|
162
|
+
const result = await service.sideChatPromotions.promote(c.req.param("sideChatId"), readClientInstanceId(c));
|
|
163
|
+
return c.json({
|
|
164
|
+
ok: true,
|
|
165
|
+
...result
|
|
166
|
+
}, result.created ? 201 : 200);
|
|
167
|
+
} catch (error) {
|
|
168
|
+
return respondSideChatError(c, error);
|
|
169
|
+
}
|
|
170
|
+
});
|
|
160
171
|
authenticated.delete("/api/side-chats/:sideChatId", async (c) => {
|
|
161
172
|
try {
|
|
162
173
|
return await service.sideChatRuns.dispose(c.req.param("sideChatId"), readClientInstanceId(c)) ? c.json({ ok: true }) : c.json({
|
|
@@ -87,7 +87,13 @@ var GatewayAgentRunner = class {
|
|
|
87
87
|
});
|
|
88
88
|
}
|
|
89
89
|
if (unique.size > MAX_TURN_CONTEXTS) throw new Error(`A message can reference at most ${MAX_TURN_CONTEXTS} sources`);
|
|
90
|
-
const contexts = await Promise.all([...unique.values()].map((ref) =>
|
|
90
|
+
const contexts = await Promise.all([...unique.values()].map(async (ref) => {
|
|
91
|
+
const context = await opts.resolveTurnContext(ref, conversationId);
|
|
92
|
+
return context && ref.refId ? {
|
|
93
|
+
...context,
|
|
94
|
+
refId: ref.refId
|
|
95
|
+
} : context;
|
|
96
|
+
}));
|
|
91
97
|
if (contexts.some((context) => context === null)) throw new Error("A referenced source is unavailable or has changed; select it again");
|
|
92
98
|
return fitSourceContextsToBudget(contexts.filter((context) => context !== null));
|
|
93
99
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
-
import { getModelRegistry } from "../../providers/model-registry.js";
|
|
4
3
|
import { loadConfig, saveConfig } from "../../config/loader.js";
|
|
4
|
+
import { getModelRegistry } from "../../providers/model-registry.js";
|
|
5
5
|
import { init_providers } from "../../providers/index.js";
|
|
6
6
|
import { disposeAllSessionMcpRuntimes } from "../../agent/mcp/bundle-mcp-runtime.js";
|
|
7
7
|
import { reloadImageGenerationProviders } from "../../agent/image/generation/provider-registry.js";
|
|
@@ -52,6 +52,7 @@ export interface SkillSourceInstallResultPayload extends SkillInstallResultPaylo
|
|
|
52
52
|
contentHash: string;
|
|
53
53
|
}
|
|
54
54
|
export interface ExtensionMarketplacePackageDetailPayload extends MarketplacePackageDetail {
|
|
55
|
+
format?: 'native-extension' | 'agent-plugin';
|
|
55
56
|
installability: {
|
|
56
57
|
available: boolean;
|
|
57
58
|
reason?: string;
|
|
@@ -2,12 +2,14 @@ import { resolveStateDir } from "../../config/paths-state.js";
|
|
|
2
2
|
import { createLogger } from "../../utils/logger/index.js";
|
|
3
3
|
import { init_logger } from "../../utils/logger.js";
|
|
4
4
|
import { init_paths, resolveExtensionsDir } from "../../config/paths.js";
|
|
5
|
+
import { getExtensionLockfileManager } from "../../extensions/lockfile.js";
|
|
6
|
+
import { AgentPluginStore } from "../../extensions/agent-plugins/store.js";
|
|
5
7
|
import { createSkillConfigManager } from "../../agent/skills/config.js";
|
|
6
8
|
import { resolveWorkspaceSkillsDir, resolveWorkspaceSkillsLockPath } from "../../agent/skills/workspace-skills-dir.js";
|
|
7
9
|
import { removeSkillsLockEntry } from "../../agent/skills/hub-lock.js";
|
|
8
10
|
import { deleteManagedSkill, installSkillFromZip, listManagedSkillDirs } from "../../agent/skills/managed-store.js";
|
|
9
11
|
import { normalizeSkillInstallTarget } from "../../agent/skills/install-target.js";
|
|
10
|
-
import {
|
|
12
|
+
import { isAgentPluginArchive, withAgentPluginArchive } from "../../extensions/agent-plugins/sources.js";
|
|
11
13
|
import { existsSync, rmSync } from "node:fs";
|
|
12
14
|
//#region src/gateway/service/marketplace-service.ts
|
|
13
15
|
/**
|
|
@@ -206,6 +208,18 @@ var GatewayMarketplaceService = class {
|
|
|
206
208
|
const resolved = await resolveExtensionZipDownloadUrl(base, packageName.trim());
|
|
207
209
|
const buffer = await downloadExtensionStoreZipBuffer(base, resolved.downloadUrl);
|
|
208
210
|
verifyStoreArtifactSha256(buffer, resolved.sha256);
|
|
211
|
+
if (isAgentPluginArchive(buffer)) {
|
|
212
|
+
const plan = withAgentPluginArchive(buffer, (path) => new AgentPluginStore().inspect(path));
|
|
213
|
+
return {
|
|
214
|
+
...detail,
|
|
215
|
+
format: "agent-plugin",
|
|
216
|
+
manifest: plan.manifest,
|
|
217
|
+
installability: {
|
|
218
|
+
available: true,
|
|
219
|
+
sha256: resolved.sha256
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
}
|
|
209
223
|
const { peekExtensionManifestFromStoreZip, peekExtensionPackageJsonFromStoreZip } = await import("../../extensions/install.js");
|
|
210
224
|
const manifest = peekExtensionManifestFromStoreZip(buffer);
|
|
211
225
|
const packageJson = peekExtensionPackageJsonFromStoreZip(buffer);
|
|
@@ -24,11 +24,11 @@ function sameAppContext(input, existing) {
|
|
|
24
24
|
return isDeepStrictEqual(identity(input.sourceContexts), identity(existing.contextSnapshots));
|
|
25
25
|
}
|
|
26
26
|
function contextRefsMatchFrozenSnapshot(requested, frozen) {
|
|
27
|
-
const editable = frozen?.filter((ref) => ref.kind === "note" || ref.kind === "task") ?? [];
|
|
27
|
+
const editable = frozen?.filter((ref) => ref.kind === "note" || ref.kind === "task" || ref.kind === "file" || ref.kind === "session" || ref.kind === "browser_tab" || ref.kind === "mcp_resource") ?? [];
|
|
28
28
|
if (requested.length !== editable.length) return false;
|
|
29
29
|
return requested.every((ref, index) => {
|
|
30
30
|
const snapshot = editable[index];
|
|
31
|
-
return snapshot?.kind === ref.kind && snapshot.sourceId === ref.sourceId && ref.expectedVersion === snapshot.version;
|
|
31
|
+
return snapshot?.kind === ref.kind && snapshot.sourceId === ref.sourceId && snapshot.refId === ref.refId && ref.expectedVersion === snapshot.version;
|
|
32
32
|
});
|
|
33
33
|
}
|
|
34
34
|
var SessionInputCoordinator = class {
|
|
@@ -311,7 +311,7 @@ var SessionInputCoordinator = class {
|
|
|
311
311
|
const existing = getSessionInputById(conversationId, id);
|
|
312
312
|
if (!contextRefsMatchFrozenSnapshot(body.contextRefs, existing?.contextRefs)) try {
|
|
313
313
|
const resolved = await this.deps.prepareContexts(conversationId, body.contextRefs) ?? [];
|
|
314
|
-
sourceContexts = fitSourceContextsToBudget([...existing?.contextSnapshots?.filter((source) => source.kind
|
|
314
|
+
sourceContexts = fitSourceContextsToBudget([...existing?.contextSnapshots?.filter((source) => source.kind === "app_context" || source.kind === "browser_page") ?? [], ...resolved]);
|
|
315
315
|
} catch (err) {
|
|
316
316
|
log.warn({
|
|
317
317
|
err,
|
|
@@ -8,12 +8,13 @@ import { NotesService } from '../notes/index.js';
|
|
|
8
8
|
import { WorkflowRunService } from '../workflows/service/workflow-run-service.js';
|
|
9
9
|
import { ExtensionLoader } from '../extensions/index.js';
|
|
10
10
|
import { SessionIndex } from '../session/index.js';
|
|
11
|
-
import { EphemeralSideChatManager, SideChatRunService } from './side-chat/index.js';
|
|
11
|
+
import { EphemeralSideChatManager, SideChatPromotionService, SideChatRunService } from './side-chat/index.js';
|
|
12
12
|
import type { Config } from '../config/schema.js';
|
|
13
13
|
import { type ResolvedGatewayAuth } from './auth.js';
|
|
14
14
|
import { ModelCatalogSyncService } from '../providers/model-catalog-sync-service.js';
|
|
15
15
|
import { ProjectService } from '../projects/index.js';
|
|
16
16
|
import { LocalAppService } from '../local-apps/index.js';
|
|
17
|
+
import { ChatPreviewService } from '../chat-previews/index.js';
|
|
17
18
|
import { TaskConversationRepository } from '../tasks/task-conversation-repository.js';
|
|
18
19
|
import { type BrowserAutomationService } from '../browser/automations/index.js';
|
|
19
20
|
import { GatewaySessionsApi } from './service/sessions-api.js';
|
|
@@ -86,6 +87,7 @@ export declare class GatewayService {
|
|
|
86
87
|
/** Process-local, non-persistent side conversations forked from durable sessions. */
|
|
87
88
|
readonly sideChats: EphemeralSideChatManager;
|
|
88
89
|
readonly sideChatRuns: SideChatRunService;
|
|
90
|
+
readonly sideChatPromotions: SideChatPromotionService;
|
|
89
91
|
/**
|
|
90
92
|
* Session CRUD / search / compaction / tag-archive-pin / stats — the gateway
|
|
91
93
|
* REST surface for sessions. Routes should depend on this narrow service
|
|
@@ -107,6 +109,8 @@ export declare class GatewayService {
|
|
|
107
109
|
readonly discussionSealer: DiscussionSealer;
|
|
108
110
|
/** Local user-created apps, their coder projects, previews, and installs. */
|
|
109
111
|
readonly localApps: LocalAppService;
|
|
112
|
+
/** Immutable, conversation-scoped UI previews that do not create projects. */
|
|
113
|
+
readonly chatPreviews: ChatPreviewService;
|
|
110
114
|
get sceneAccess(): SceneAccess | undefined;
|
|
111
115
|
constructor(serviceConfig?: GatewayServiceConfig);
|
|
112
116
|
/** Lazy AgentService — constructed on first use or during `start()`. */
|
|
@@ -18,17 +18,17 @@ import { getSessionConfig } from "../storage/sqlite/config-repository.js";
|
|
|
18
18
|
import "../storage/sqlite/index.js";
|
|
19
19
|
import { getAgentDefaultModelRef, init_schema } from "../config/schema.js";
|
|
20
20
|
import { init_agent_scope, listAgentEntries, normalizeAgentId, resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agent/agent-scope.js";
|
|
21
|
+
import { init_agent_session_key, resolveAgentMainConversationId } from "../routing/agent-session-key.js";
|
|
22
|
+
import { init_session_key, resolveConversationId, sanitizeSegment } from "../routing/session-key.js";
|
|
23
|
+
import { getDefaultAgentId, init_resolve_route } from "../routing/resolve-route.js";
|
|
24
|
+
import { resolveEffectiveAgentProfileForSession } from "../config/agent-profile.js";
|
|
21
25
|
import { init_paths, resolveConfigPath, resolveExtensionsDir } from "../config/paths.js";
|
|
22
|
-
import { prewarmModelRegistry } from "../providers/model-registry.js";
|
|
23
26
|
import { areExtensionsGloballyDisabled } from "../extensions/discover-extensions.js";
|
|
24
27
|
import { buildExtensionMetadataSnapshot } from "../extensions/extension-metadata-snapshot.js";
|
|
25
28
|
import { buildChannelCatalogForConfig, buildChannelCatalogFromSnapshot, init_channel_catalog_service } from "../channels/catalog/channel-catalog-service.js";
|
|
26
29
|
import { loadConfig, saveConfig } from "../config/loader.js";
|
|
27
|
-
import {
|
|
28
|
-
import { init_session_key, resolveConversationId, sanitizeSegment } from "../routing/session-key.js";
|
|
29
|
-
import { getDefaultAgentId, init_resolve_route } from "../routing/resolve-route.js";
|
|
30
|
+
import { prewarmModelRegistry } from "../providers/model-registry.js";
|
|
30
31
|
import { init_providers, providers_exports } from "../providers/index.js";
|
|
31
|
-
import { resolveEffectiveAgentProfileForSession } from "../config/agent-profile.js";
|
|
32
32
|
import { TaskConversationRepository } from "../tasks/task-conversation-repository.js";
|
|
33
33
|
import { getEmbeddedExecutionSession } from "../agent/embedded/execution-context.js";
|
|
34
34
|
import { disposeAllSessionMcpRuntimes } from "../agent/mcp/bundle-mcp-runtime.js";
|
|
@@ -64,6 +64,8 @@ import { ensureStarterAgentsInitialized } from "../agent/starter-agents.js";
|
|
|
64
64
|
import { setPairingBroadcastSink } from "../channels/pairing/pairing-events.js";
|
|
65
65
|
import { registerClarificationChannelRuntime } from "./clarify-runtime.js";
|
|
66
66
|
import { ChannelManager } from "../channels/manager.js";
|
|
67
|
+
import { ChatPreviewService } from "../chat-previews/service.js";
|
|
68
|
+
import "../chat-previews/index.js";
|
|
67
69
|
import { getWorkspacePath } from "../config/workspace-path-helpers.js";
|
|
68
70
|
import "../config/index.js";
|
|
69
71
|
import { ManagedComposioEventPoller } from "../connectors/composio-managed-events.js";
|
|
@@ -100,6 +102,7 @@ import { WorkflowRunService } from "../workflows/service/workflow-run-service.js
|
|
|
100
102
|
import { WorkflowSessionBridge } from "../workflows/service/workflow-session-bridge.js";
|
|
101
103
|
import { EphemeralSideChatManager } from "./side-chat/manager.js";
|
|
102
104
|
import { SideChatRunService } from "./side-chat/run-service.js";
|
|
105
|
+
import { SideChatPromotionService } from "./side-chat/promotion-service.js";
|
|
103
106
|
import "./side-chat/index.js";
|
|
104
107
|
import { wireTunnelEventsToGateway } from "../tunnel/gateway-lifecycle.js";
|
|
105
108
|
import { getExposureManager } from "../remote-access/exposure-manager.js";
|
|
@@ -301,6 +304,7 @@ var GatewayService = class {
|
|
|
301
304
|
/** Process-local, non-persistent side conversations forked from durable sessions. */
|
|
302
305
|
sideChats;
|
|
303
306
|
sideChatRuns;
|
|
307
|
+
sideChatPromotions;
|
|
304
308
|
/**
|
|
305
309
|
* Session CRUD / search / compaction / tag-archive-pin / stats — the gateway
|
|
306
310
|
* REST surface for sessions. Routes should depend on this narrow service
|
|
@@ -329,6 +333,8 @@ var GatewayService = class {
|
|
|
329
333
|
discussionSealer;
|
|
330
334
|
/** Local user-created apps, their coder projects, previews, and installs. */
|
|
331
335
|
localApps;
|
|
336
|
+
/** Immutable, conversation-scoped UI previews that do not create projects. */
|
|
337
|
+
chatPreviews;
|
|
332
338
|
get sceneAccess() {
|
|
333
339
|
return this.sceneHost ? {
|
|
334
340
|
services: this.sceneHost.http,
|
|
@@ -467,6 +473,7 @@ var GatewayService = class {
|
|
|
467
473
|
getExtensionLoader: () => this.extensionLoader,
|
|
468
474
|
emit: (type, payload) => this.emit(type, payload)
|
|
469
475
|
});
|
|
476
|
+
this.chatPreviews = new ChatPreviewService({ localApps: this.localApps });
|
|
470
477
|
this.agentRunner = new GatewayAgentRunner({
|
|
471
478
|
validateConnectionResume: async (input) => {
|
|
472
479
|
for (const source of input.contextSnapshots ?? []) if (source.kind === "app_context") await checkAppContextAccess(source, this.appContextDispatcher(), this.auth);
|
|
@@ -529,6 +536,7 @@ var GatewayService = class {
|
|
|
529
536
|
let sideChatRuns;
|
|
530
537
|
this.sideChats = new EphemeralSideChatManager({
|
|
531
538
|
getParentMetadata: (conversationId) => this.sessionIndex.getSessionMetadata(conversationId),
|
|
539
|
+
getParentConfig: async (conversationId) => getSessionConfig(conversationId),
|
|
532
540
|
loadParentMessages: (conversationId) => this.sessionIndex.getStore().load(conversationId),
|
|
533
541
|
getDefaultModelRef: (conversationId) => this.ensureAgentService().getModelForSession(conversationId),
|
|
534
542
|
getDefaultThinkingLevel: (conversationId) => this.ensureAgentService().getThinkingLevelForSession(conversationId),
|
|
@@ -550,6 +558,11 @@ var GatewayService = class {
|
|
|
550
558
|
publishRealtime: (topic, event, data) => this.realtime.broker.publish(topic, event, data),
|
|
551
559
|
completeRealtimeTopic: (topic) => this.realtime.completeTopic(topic)
|
|
552
560
|
});
|
|
561
|
+
this.sideChatPromotions = new SideChatPromotionService({
|
|
562
|
+
manager: this.sideChats,
|
|
563
|
+
sessionIndex: this.sessionIndex,
|
|
564
|
+
getAgentService: () => this.ensureAgentService()
|
|
565
|
+
});
|
|
553
566
|
this.sessions = new GatewaySessionsApi({
|
|
554
567
|
sessionIndex: this.sessionIndex,
|
|
555
568
|
getAgentService: () => this.ensureAgentService(),
|
|
@@ -627,6 +640,7 @@ var GatewayService = class {
|
|
|
627
640
|
getProjectService: () => this.projects,
|
|
628
641
|
getWorkDiscovery: () => this._workDiscovery ?? void 0,
|
|
629
642
|
getLocalAppService: () => this.localApps,
|
|
643
|
+
getChatPreviewService: () => this.chatPreviews,
|
|
630
644
|
dispatchTaskEvents: () => this.dispatchTaskEvents(),
|
|
631
645
|
dispatchTaskRuns: () => this.dispatchTaskRuns(),
|
|
632
646
|
getWorkflowRunService: () => this.createWorkflowRunService(),
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export { EphemeralSideChatManager, SideChatError, parseThinkingLevel } from './manager.js';
|
|
2
|
-
export type { EphemeralSideChatManagerOptions } from './manager.js';
|
|
2
|
+
export type { EphemeralSideChatManagerOptions, SideChatPromotionSnapshot } from './manager.js';
|
|
3
3
|
export { validateSideChatSelections } from './context-snapshot.js';
|
|
4
4
|
export { SideChatRunService } from './run-service.js';
|
|
5
|
+
export { SideChatPromotionService } from './promotion-service.js';
|
|
6
|
+
export type { SideChatPromotionResult, SideChatPromotionServiceOptions } from './promotion-service.js';
|
|
5
7
|
export type { CreateSideChatInput, SideChatConfig, SideChatContextSnapshot, SideChatSelection, SideChatStatus, SideChatView, } from './types.js';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { validateSideChatSelections } from "./context-snapshot.js";
|
|
2
2
|
import { EphemeralSideChatManager, SideChatError, parseThinkingLevel } from "./manager.js";
|
|
3
3
|
import { SideChatRunService } from "./run-service.js";
|
|
4
|
-
|
|
4
|
+
import { SideChatPromotionService } from "./promotion-service.js";
|
|
5
|
+
export { EphemeralSideChatManager, SideChatError, SideChatPromotionService, SideChatRunService, parseThinkingLevel, validateSideChatSelections };
|
|
@@ -1,7 +1,18 @@
|
|
|
1
1
|
import type { AgentMessage, ThinkingLevel } from '@earendil-works/pi-agent-core';
|
|
2
2
|
import { InMemoryTranscriptRuntime } from '../../agent/embedded/transcript-runtime.js';
|
|
3
|
+
import type { SessionAgentConfig } from '../../session/config-types.js';
|
|
4
|
+
import type { TranscriptStoredRow } from '../../session/session-context-for-llm.js';
|
|
3
5
|
import type { SessionMetadata } from '../../session/types.js';
|
|
4
6
|
import type { CreateSideChatInput, SideChatConfig, SideChatStatus, SideChatView } from './types.js';
|
|
7
|
+
export interface SideChatPromotionSnapshot {
|
|
8
|
+
id: string;
|
|
9
|
+
parentMetadata: SessionMetadata;
|
|
10
|
+
parentConfig: SessionAgentConfig | null;
|
|
11
|
+
context: SideChatView['context'];
|
|
12
|
+
config: SideChatConfig;
|
|
13
|
+
contextMessages: AgentMessage[];
|
|
14
|
+
conversationRows: TranscriptStoredRow[];
|
|
15
|
+
}
|
|
5
16
|
export declare class SideChatError extends Error {
|
|
6
17
|
readonly code: 'INVALID_REQUEST' | 'NOT_FOUND' | 'PARENT_NOT_FOUND' | 'LIMIT_REACHED' | 'CAPACITY_REACHED' | 'CONFLICT' | 'EXPIRED';
|
|
7
18
|
readonly reason?: 'idle' | 'waiting';
|
|
@@ -9,6 +20,7 @@ export declare class SideChatError extends Error {
|
|
|
9
20
|
}
|
|
10
21
|
export interface EphemeralSideChatManagerOptions {
|
|
11
22
|
getParentMetadata: (conversationId: string) => Promise<SessionMetadata | null>;
|
|
23
|
+
getParentConfig?: (conversationId: string) => Promise<SessionAgentConfig | null>;
|
|
12
24
|
loadParentMessages: (conversationId: string) => Promise<AgentMessage[]>;
|
|
13
25
|
getDefaultModelRef: (conversationId: string) => string;
|
|
14
26
|
getDefaultThinkingLevel?: (conversationId: string) => ThinkingLevel;
|
|
@@ -39,12 +51,16 @@ export declare class EphemeralSideChatManager {
|
|
|
39
51
|
get(id: string, clientInstanceId: string): SideChatView;
|
|
40
52
|
getRuntime(id: string, clientInstanceId: string): InMemoryTranscriptRuntime;
|
|
41
53
|
getMessages(id: string, clientInstanceId: string): AgentMessage[];
|
|
54
|
+
beginPromotion(id: string, clientInstanceId: string): SideChatPromotionSnapshot;
|
|
55
|
+
cancelPromotion(id: string, clientInstanceId: string): void;
|
|
42
56
|
updateConfig(id: string, clientInstanceId: string, patch: Partial<SideChatConfig>): SideChatView;
|
|
43
57
|
heartbeat(id: string, clientInstanceId: string): SideChatView;
|
|
44
58
|
extend(id: string, clientInstanceId: string): SideChatView;
|
|
45
59
|
setStatus(id: string, clientInstanceId: string, status: SideChatStatus, runId?: string): SideChatView;
|
|
46
60
|
waitForInput(id: string, clientInstanceId: string, clarification: NonNullable<SideChatView['clarification']>, status?: 'waiting-input' | 'waiting-approval'): void;
|
|
47
61
|
dispose(id: string, clientInstanceId: string): Promise<boolean>;
|
|
62
|
+
disposePromoted(id: string, clientInstanceId: string): Promise<boolean>;
|
|
63
|
+
private disposeEntry;
|
|
48
64
|
disposeClient(clientInstanceId: string): Promise<number>;
|
|
49
65
|
sweepExpired(at?: number): Promise<number>;
|
|
50
66
|
disposeAll(): Promise<void>;
|
|
@@ -70,6 +70,7 @@ var EphemeralSideChatManager = class {
|
|
|
70
70
|
const metadata = await this.options.getParentMetadata(parentConversationId);
|
|
71
71
|
if (!metadata || !metadata.transcriptId) throw new SideChatError("Parent session not found", "PARENT_NOT_FOUND");
|
|
72
72
|
const parentMessages = await this.options.loadParentMessages(parentConversationId);
|
|
73
|
+
const parentConfig = await this.options.getParentConfig?.(parentConversationId) ?? null;
|
|
73
74
|
if (this.stopped) throw new SideChatError("Gateway is stopping", "CAPACITY_REACHED");
|
|
74
75
|
let selections;
|
|
75
76
|
try {
|
|
@@ -110,7 +111,9 @@ var EphemeralSideChatManager = class {
|
|
|
110
111
|
createdAt
|
|
111
112
|
}),
|
|
112
113
|
config,
|
|
113
|
-
runtime
|
|
114
|
+
runtime,
|
|
115
|
+
parentMetadata: structuredClone(metadata),
|
|
116
|
+
parentConfig: structuredClone(parentConfig)
|
|
114
117
|
};
|
|
115
118
|
this.entries.set(id, entry);
|
|
116
119
|
return this.toView(entry);
|
|
@@ -127,6 +130,29 @@ var EphemeralSideChatManager = class {
|
|
|
127
130
|
entry.messageCount = messages.length;
|
|
128
131
|
return structuredClone(messages);
|
|
129
132
|
}
|
|
133
|
+
beginPromotion(id, clientInstanceId) {
|
|
134
|
+
const entry = this.requireEntry(id, clientInstanceId);
|
|
135
|
+
if (entry.status !== "idle") throw new SideChatError("Side chat is busy", "CONFLICT");
|
|
136
|
+
const conversationRows = entry.runtime.loadConversationRows();
|
|
137
|
+
if (entry.runtime.loadConversationMessages().length === 0) throw new SideChatError("Side chat has no messages to save", "INVALID_REQUEST");
|
|
138
|
+
entry.status = "promoting";
|
|
139
|
+
entry.expiresAt = null;
|
|
140
|
+
return structuredClone({
|
|
141
|
+
id: entry.id,
|
|
142
|
+
parentMetadata: entry.parentMetadata,
|
|
143
|
+
parentConfig: entry.parentConfig,
|
|
144
|
+
context: entry.context,
|
|
145
|
+
config: entry.config,
|
|
146
|
+
contextMessages: entry.runtime.loadBaselineMessages(),
|
|
147
|
+
conversationRows
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
cancelPromotion(id, clientInstanceId) {
|
|
151
|
+
const entry = this.requireEntry(id, clientInstanceId);
|
|
152
|
+
if (entry.status !== "promoting") return;
|
|
153
|
+
entry.status = "idle";
|
|
154
|
+
this.touchEntry(entry);
|
|
155
|
+
}
|
|
130
156
|
updateConfig(id, clientInstanceId, patch) {
|
|
131
157
|
const entry = this.requireEntry(id, clientInstanceId);
|
|
132
158
|
if (entry.status !== "idle") throw new SideChatError("Cannot change config while a run is active", "CONFLICT");
|
|
@@ -162,6 +188,14 @@ var EphemeralSideChatManager = class {
|
|
|
162
188
|
this.requireEntry(id, clientInstanceId).clarification = clarification;
|
|
163
189
|
}
|
|
164
190
|
async dispose(id, clientInstanceId) {
|
|
191
|
+
const entry = this.entries.get(id);
|
|
192
|
+
if (entry?.clientInstanceId === clientInstanceId && entry.status === "promoting") throw new SideChatError("Side chat is being saved", "CONFLICT");
|
|
193
|
+
return this.disposeEntry(id, clientInstanceId);
|
|
194
|
+
}
|
|
195
|
+
disposePromoted(id, clientInstanceId) {
|
|
196
|
+
return this.disposeEntry(id, clientInstanceId);
|
|
197
|
+
}
|
|
198
|
+
async disposeEntry(id, clientInstanceId) {
|
|
165
199
|
const entry = this.entries.get(id);
|
|
166
200
|
if (!entry) {
|
|
167
201
|
const pending = this.disposals.get(id);
|
|
@@ -187,8 +221,8 @@ var EphemeralSideChatManager = class {
|
|
|
187
221
|
return cleanup;
|
|
188
222
|
}
|
|
189
223
|
async disposeClient(clientInstanceId) {
|
|
190
|
-
const ids = [...this.entries.values()].filter((entry) => entry.clientInstanceId === clientInstanceId).map((entry) => entry.id);
|
|
191
|
-
await Promise.all(ids.map((id) => this.
|
|
224
|
+
const ids = [...this.entries.values()].filter((entry) => entry.clientInstanceId === clientInstanceId && entry.status !== "promoting").map((entry) => entry.id);
|
|
225
|
+
await Promise.all(ids.map((id) => this.disposeEntry(id, clientInstanceId)));
|
|
192
226
|
return ids.length;
|
|
193
227
|
}
|
|
194
228
|
async sweepExpired(at = this.now()) {
|
|
@@ -201,7 +235,7 @@ var EphemeralSideChatManager = class {
|
|
|
201
235
|
if (this.sweepTimer) clearInterval(this.sweepTimer);
|
|
202
236
|
this.stopped = true;
|
|
203
237
|
const entries = [...this.entries.values()];
|
|
204
|
-
await Promise.all(entries.map((entry) => this.
|
|
238
|
+
await Promise.all(entries.map((entry) => this.disposeEntry(entry.id, entry.clientInstanceId)));
|
|
205
239
|
await Promise.all([...this.disposals.values()].map((entry) => entry.promise));
|
|
206
240
|
this.expired.clear();
|
|
207
241
|
}
|
|
@@ -229,7 +263,7 @@ var EphemeralSideChatManager = class {
|
|
|
229
263
|
removeAt: this.now() + DEFAULT_IDLE_TTL_MS
|
|
230
264
|
});
|
|
231
265
|
this.pruneExpiredRecords(this.now());
|
|
232
|
-
const cleanup = this.
|
|
266
|
+
const cleanup = this.disposeEntry(entry.id, entry.clientInstanceId);
|
|
233
267
|
try {
|
|
234
268
|
this.options.onExpired?.(entry.id, entry.clientInstanceId, reason);
|
|
235
269
|
} catch (err) {
|
|
@@ -245,7 +279,7 @@ var EphemeralSideChatManager = class {
|
|
|
245
279
|
while (this.expired.size > MAX_EXPIRED_RECORDS) this.expired.delete(this.expired.keys().next().value);
|
|
246
280
|
}
|
|
247
281
|
toView(entry) {
|
|
248
|
-
const { runtime: _runtime, ...view } = entry;
|
|
282
|
+
const { runtime: _runtime, parentMetadata: _parentMetadata, parentConfig: _parentConfig, ...view } = entry;
|
|
249
283
|
return structuredClone({
|
|
250
284
|
...view,
|
|
251
285
|
serverNow: new Date(this.now()).toISOString()
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { AgentService } from '../../agent/service.js';
|
|
2
|
+
import type { SessionIndex } from '../../session/manager.js';
|
|
3
|
+
import type { SessionMetadata } from '../../session/types.js';
|
|
4
|
+
import { EphemeralSideChatManager } from './manager.js';
|
|
5
|
+
export interface SideChatPromotionResult {
|
|
6
|
+
conversationId: string;
|
|
7
|
+
created: boolean;
|
|
8
|
+
session: SessionMetadata;
|
|
9
|
+
}
|
|
10
|
+
export interface SideChatPromotionServiceOptions {
|
|
11
|
+
manager: EphemeralSideChatManager;
|
|
12
|
+
sessionIndex: SessionIndex;
|
|
13
|
+
getAgentService: () => AgentService;
|
|
14
|
+
}
|
|
15
|
+
export declare class SideChatPromotionService {
|
|
16
|
+
private readonly options;
|
|
17
|
+
constructor(options: SideChatPromotionServiceOptions);
|
|
18
|
+
promote(sideChatId: string, clientInstanceId: string): Promise<SideChatPromotionResult>;
|
|
19
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { createLogger } from "../../utils/logger/index.js";
|
|
2
|
+
import { init_logger } from "../../utils/logger.js";
|
|
3
|
+
import { init_session_context_for_llm, isRuntimeOnlyTranscriptMessage } from "../../session/session-context-for-llm.js";
|
|
4
|
+
import { SideChatError } from "./manager.js";
|
|
5
|
+
//#region src/gateway/side-chat/promotion-service.ts
|
|
6
|
+
init_session_context_for_llm();
|
|
7
|
+
init_logger();
|
|
8
|
+
const log = createLogger("Gateway:SideChatPromotion");
|
|
9
|
+
var SideChatPromotionService = class {
|
|
10
|
+
constructor(options) {
|
|
11
|
+
this.options = options;
|
|
12
|
+
}
|
|
13
|
+
async promote(sideChatId, clientInstanceId) {
|
|
14
|
+
const existing = await this.options.sessionIndex.getSessionMetadata(sideChatId);
|
|
15
|
+
if (existing) {
|
|
16
|
+
if (existing.customData?.promotedFromSideChatId !== sideChatId) throw new SideChatError("A session already uses this side chat id", "CONFLICT");
|
|
17
|
+
return {
|
|
18
|
+
conversationId: sideChatId,
|
|
19
|
+
created: false,
|
|
20
|
+
session: existing
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
const snapshot = this.options.manager.beginPromotion(sideChatId, clientInstanceId);
|
|
24
|
+
const parent = snapshot.parentMetadata;
|
|
25
|
+
const agentId = parent.routing?.agentId?.trim() || parent.agentId;
|
|
26
|
+
const chatId = `chat_${sideChatId}`;
|
|
27
|
+
const rows = [{
|
|
28
|
+
type: "side_chat_origin",
|
|
29
|
+
version: 1,
|
|
30
|
+
parentConversationId: snapshot.context.parentConversationId,
|
|
31
|
+
parentTranscriptId: snapshot.context.parentTranscriptId,
|
|
32
|
+
createdAt: snapshot.context.createdAt,
|
|
33
|
+
contentHash: snapshot.context.contentHash,
|
|
34
|
+
contextMessages: snapshot.contextMessages
|
|
35
|
+
}, ...snapshot.conversationRows.filter((row) => !isRuntimeOnlyTranscriptMessage(row))];
|
|
36
|
+
try {
|
|
37
|
+
await this.options.sessionIndex.createSessionFromRows({
|
|
38
|
+
targetKey: sideChatId,
|
|
39
|
+
cwd: parent.cwd || "",
|
|
40
|
+
metadata: {
|
|
41
|
+
agentId,
|
|
42
|
+
sourceChannel: "webchat",
|
|
43
|
+
sourceChatId: `default:direct:${chatId}`,
|
|
44
|
+
sessionType: "chat",
|
|
45
|
+
tags: [...new Set([...parent.tags ?? [], "side-chat"])],
|
|
46
|
+
projectId: parent.projectId,
|
|
47
|
+
parentConversationId: snapshot.context.parentConversationId,
|
|
48
|
+
hiddenFromSessionList: false,
|
|
49
|
+
routing: {
|
|
50
|
+
agentId,
|
|
51
|
+
source: "webchat",
|
|
52
|
+
accountId: "default",
|
|
53
|
+
peerKind: "direct",
|
|
54
|
+
peerId: chatId
|
|
55
|
+
},
|
|
56
|
+
customData: {
|
|
57
|
+
genericNewChatShell: false,
|
|
58
|
+
promotedFromSideChatId: sideChatId,
|
|
59
|
+
promotedFromParentTranscriptId: snapshot.context.parentTranscriptId,
|
|
60
|
+
sideChatContextHash: snapshot.context.contentHash,
|
|
61
|
+
promotedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
rows,
|
|
65
|
+
config: {
|
|
66
|
+
...snapshot.parentConfig ?? {},
|
|
67
|
+
modelOverride: snapshot.config.modelRef,
|
|
68
|
+
thinkingLevel: snapshot.config.thinkingLevel
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
} catch (error) {
|
|
72
|
+
this.options.manager.cancelPromotion(sideChatId, clientInstanceId);
|
|
73
|
+
throw error;
|
|
74
|
+
}
|
|
75
|
+
const firstUserText = snapshot.conversationRows.find((row) => isAgentMessageWithRole(row, "user"));
|
|
76
|
+
if (firstUserText) try {
|
|
77
|
+
this.options.getAgentService().enqueueProvisionalSessionTitle(sideChatId, messageText(firstUserText));
|
|
78
|
+
} catch (err) {
|
|
79
|
+
log.warn({
|
|
80
|
+
err,
|
|
81
|
+
sideChatId,
|
|
82
|
+
phase: "side_chat_promote_title"
|
|
83
|
+
}, "Saved side chat but title generation could not start");
|
|
84
|
+
}
|
|
85
|
+
await this.options.manager.disposePromoted(sideChatId, clientInstanceId).catch((err) => {
|
|
86
|
+
log.warn({
|
|
87
|
+
err,
|
|
88
|
+
sideChatId,
|
|
89
|
+
phase: "side_chat_promote_cleanup"
|
|
90
|
+
}, "Saved side chat but cleanup failed");
|
|
91
|
+
});
|
|
92
|
+
const session = await this.options.sessionIndex.getSessionMetadata(sideChatId);
|
|
93
|
+
if (!session) throw new Error(`Promoted session not found: ${sideChatId}`);
|
|
94
|
+
return {
|
|
95
|
+
conversationId: sideChatId,
|
|
96
|
+
created: true,
|
|
97
|
+
session
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
function isAgentMessageWithRole(row, role) {
|
|
102
|
+
return Boolean(row && typeof row === "object" && row.role === role);
|
|
103
|
+
}
|
|
104
|
+
function messageText(message) {
|
|
105
|
+
const content = message.content;
|
|
106
|
+
if (typeof content === "string") return content.trim();
|
|
107
|
+
if (!Array.isArray(content)) return "";
|
|
108
|
+
return content.filter((part) => Boolean(part && typeof part === "object" && part.type === "text" && typeof part.text === "string")).map((part) => part.text).join("\n").trim();
|
|
109
|
+
}
|
|
110
|
+
//#endregion
|
|
111
|
+
export { SideChatPromotionService };
|
|
@@ -16,6 +16,7 @@ var SideChatRunService = class {
|
|
|
16
16
|
const text = input.content.trim();
|
|
17
17
|
if (!text && !input.attachments?.length) throw new SideChatError("content or attachments are required", "INVALID_REQUEST");
|
|
18
18
|
const sideChat = this.options.manager.get(sideChatId, clientInstanceId);
|
|
19
|
+
if (sideChat.status !== "idle") throw new SideChatError("A side chat run is already active", "CONFLICT");
|
|
19
20
|
if (this.activeBySideChat.has(sideChatId)) throw new SideChatError("A side chat run is already active", "CONFLICT");
|
|
20
21
|
const run = {
|
|
21
22
|
sideChatId,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ThinkingLevel } from '@earendil-works/pi-agent-core';
|
|
2
|
-
export type SideChatStatus = 'idle' | 'running' | 'waiting-approval' | 'waiting-input' | 'closing';
|
|
2
|
+
export type SideChatStatus = 'idle' | 'running' | 'waiting-approval' | 'waiting-input' | 'promoting' | 'closing';
|
|
3
3
|
export type SideChatSelection = {
|
|
4
4
|
id: string;
|
|
5
5
|
type: 'message';
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { basename, join, relative } from "node:path";
|
|
2
|
+
import { readFileSync, readdirSync } from "node:fs";
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
4
|
+
//#region src/local-apps/artifact-files.ts
|
|
5
|
+
const EXCLUDED_NAMES = new Set([
|
|
6
|
+
".git",
|
|
7
|
+
"node_modules",
|
|
8
|
+
".DS_Store"
|
|
9
|
+
]);
|
|
10
|
+
function shouldCopyLocalAppPath(path) {
|
|
11
|
+
return !EXCLUDED_NAMES.has(basename(path));
|
|
12
|
+
}
|
|
13
|
+
function hashLocalAppDirectory(root) {
|
|
14
|
+
const hash = createHash("sha256");
|
|
15
|
+
const visit = (dir) => {
|
|
16
|
+
const entries = readdirSync(dir, { withFileTypes: true }).filter((entry) => !EXCLUDED_NAMES.has(entry.name)).toSorted((a, b) => a.name.localeCompare(b.name));
|
|
17
|
+
for (const entry of entries) {
|
|
18
|
+
const path = join(dir, entry.name);
|
|
19
|
+
const relativePath = relative(root, path);
|
|
20
|
+
hash.update(relativePath);
|
|
21
|
+
if (entry.isDirectory()) visit(path);
|
|
22
|
+
else if (entry.isFile()) hash.update(readFileSync(path));
|
|
23
|
+
else throw new Error(`Unsupported local app entry: ${relativePath}`);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
visit(root);
|
|
27
|
+
return hash.digest("hex");
|
|
28
|
+
}
|
|
29
|
+
function localAppFileHashes(root) {
|
|
30
|
+
const hashes = /* @__PURE__ */ new Map();
|
|
31
|
+
const visit = (dir) => {
|
|
32
|
+
const entries = readdirSync(dir, { withFileTypes: true }).filter((entry) => !EXCLUDED_NAMES.has(entry.name)).toSorted((a, b) => a.name.localeCompare(b.name));
|
|
33
|
+
for (const entry of entries) {
|
|
34
|
+
const path = join(dir, entry.name);
|
|
35
|
+
const relativePath = relative(root, path);
|
|
36
|
+
if (entry.isDirectory()) visit(path);
|
|
37
|
+
else if (entry.isFile()) hashes.set(relativePath, createHash("sha256").update(readFileSync(path)).digest("hex"));
|
|
38
|
+
else throw new Error(`Unsupported local app entry: ${relativePath}`);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
visit(root);
|
|
42
|
+
return hashes;
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
export { hashLocalAppDirectory, localAppFileHashes, shouldCopyLocalAppPath };
|