@xopcai/xopc 0.0.312 → 0.0.314
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-C3yV1y_l.js → auth-DKo-NMUY.js} +18 -1
- package/dist/browser-ext/dist/background.js +68 -2
- package/dist/browser-ext/dist/sidepanel.html +1 -1
- package/dist/browser-ext/dist/sidepanel.js +1 -1
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
- package/dist/extensions/telegram/src/inbound-processor.js +1 -1
- package/dist/extensions/telegram/src/plugin.js +2 -2
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BVIJMP8w.js → agent-avatar-dicebear-BFkjfurL.js} +1 -1
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-BdOZ6q8Z.js +1 -0
- package/dist/gateway/static/root/assets/{agents-D6g_SeWI.js → agents-CCcavsHq.js} +1 -1
- package/dist/gateway/static/root/assets/{api-_aHQA8bd.js → api-BYhRsTAc.js} +1 -1
- package/dist/gateway/static/root/assets/{app-link-CKueEVbT.js → app-link-nL8iPwEr.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-CLg_aXYG.js → app-management-settings-panel-B4kihr-A.js} +1 -1
- package/dist/gateway/static/root/assets/appearance-settings-N9sYmNOx.js +1 -0
- package/dist/gateway/static/root/assets/apps-page-BMcy10_s.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-CHO3heHX.js → archive-plugin-k_SuYWyV.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-BsmsBCI2.js → attachment-load-DRv5QWUK.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-CftigJlf.js → automations-page-CkJV3DN0.js} +1 -1
- package/dist/gateway/static/root/assets/automations-workspace-BEa2doeR.js +7 -0
- package/dist/gateway/static/root/assets/{binary-plugins-CRCLWBo2.js → binary-plugins-Dg3h3TA7.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-D0LDiOTT.js → block-editor-DVhdHntT.js} +29 -29
- package/dist/gateway/static/root/assets/{browser-automation-inputs-C611KRBx.js → browser-automation-inputs-BMRYUW8_.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-automations-page-Djyv3vy-.js → browser-automations-page-Byv6-FY2.js} +2 -2
- package/dist/gateway/static/root/assets/browser-settings-page-DRCHGFpO.js +3 -0
- package/dist/gateway/static/root/assets/capabilities-D0S3DuAD.js +1 -0
- package/dist/gateway/static/root/assets/capabilities-settings-panel-mxRP0gl0.js +8 -0
- package/dist/gateway/static/root/assets/channels-settings-DBt_6GsB.js +1 -0
- package/dist/gateway/static/root/assets/{chat-terminal-dock-CIsKqdET.js → chat-terminal-dock-D4AHa51o.js} +2 -2
- package/dist/gateway/static/root/assets/{computer-settings-page-C0YL9J7m.js → computer-settings-page-eXPe500D.js} +1 -1
- package/dist/gateway/static/root/assets/connector-service-page-BQTFlq_k.js +1 -0
- package/dist/gateway/static/root/assets/connectors-page-BKeBWwcI.js +2 -0
- package/dist/gateway/static/root/assets/conversation-identity-Cw0n9uzK.js +1 -0
- package/dist/gateway/static/root/assets/{date-picker-CDsfv8R0.js → date-picker-7MtovynY.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-DvhPj3CZ.js → dependency-picker-Bj_xkXID.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-Cyg8XMpL.js → desktop-pet-CTmba9zH.js} +1 -1
- package/dist/gateway/static/root/assets/desktop-pet-settings-DNM_BlWN.js +1 -0
- package/dist/gateway/static/root/assets/device-pairing-wizard-C2XE0QhT.js +1 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-D-AVJU3q.js → extension-debug-page-J_olaL7e.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-DrFoQ9xt.js → extension-page-pK5RvqN8.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-DxWjESC1.js → extension-settings-page-BwroEN08.js} +1 -1
- package/dist/gateway/static/root/assets/files-BK6enEvD.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-config-swr-DUDX42qY.js → gateway-config-swr-FuJTIg_a.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-settings-CLLDp23J.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-Cf8OxlvY.js → gateway-startup-retry-CKg_gu8_.js} +1 -1
- package/dist/gateway/static/root/assets/home-page-B5Epb1PH.js +1 -0
- package/dist/gateway/static/root/assets/{image-generation-api-D2YorS--.js → image-generation-api-Bo6NZ7zb.js} +1 -1
- package/dist/gateway/static/root/assets/{imports-page-BKucJlXI.js → imports-page-C8-hX8gS.js} +1 -1
- package/dist/gateway/static/root/assets/index-14F1yGJI.js +89 -0
- package/dist/gateway/static/root/assets/index-cB7rWIDY.css +1 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BxLXD-yU.js → keyboard-shortcuts-settings-BkBEjUZD.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-6jC3vQpY.js +2 -0
- package/dist/gateway/static/root/assets/{local-apps-page-BAsQJQKJ.js → local-apps-page-CrbKIixo.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-DA0Z5jM_.js → locale-store-CvGwNbml.js} +1 -1
- package/dist/gateway/static/root/assets/logs-page-DBHlZts9.js +2 -0
- package/dist/gateway/static/root/assets/management-settings-DsUWLu5m.js +1 -0
- package/dist/gateway/static/root/assets/{markdown-view-DYGPxPee.js → markdown-view-nXo5nrsv.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-CQtQzLyg.js → media-plugins-upxXJ-4l.js} +1 -1
- package/dist/gateway/static/root/assets/messages-B_AwRroN.js +3 -0
- package/dist/gateway/static/root/assets/note-detail-panel-0Q9TOtJG.js +5 -0
- package/dist/gateway/static/root/assets/notes-page-D0NmcwNw.js +8 -0
- package/dist/gateway/static/root/assets/page-context-capture-button-DUyA-K4L.js +1 -0
- package/dist/gateway/static/root/assets/{page-tabs-B6DjkyMM.js → page-tabs-Cl-NFPNr.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-Dn57uLhr.js → preview-open-alternatives-DX81PwJ3.js} +1 -1
- package/dist/gateway/static/root/assets/product-delivery-chCjIpvu.js +1 -0
- package/dist/gateway/static/root/assets/{product-open-page-H2YMk8TY.js → product-open-page-CrfIGwm8.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-BVfVrYmn.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-nM9a9XNS.js +1 -0
- package/dist/gateway/static/root/assets/{registry-api-C0DCx3wv.js → registry-api-CHxgohY0.js} +1 -1
- package/dist/gateway/static/root/assets/remote-access-hub-C8b_k88G.js +1 -0
- package/dist/gateway/static/root/assets/runtime-tools-settings-panel-D3dLOW04.js +5 -0
- package/dist/gateway/static/root/assets/scenes-page-DEowreZV.js +2 -0
- package/dist/gateway/static/root/assets/{schema-form-CblI9WUA.js → schema-form-ZxuIvD2_.js} +1 -1
- package/dist/gateway/static/root/assets/schemas-88fK3zzl.js +64 -0
- package/dist/gateway/static/root/assets/sessions-page-B_nPhera.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-BqhIOuus.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-BAaVyxJH.js → settings-form-section-TZRfg4yo.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-CKNPbm5q.js → settings-page-a8qcJpdZ.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-layout-DqNCGKxQ.js → settings-page-layout-BfvlRT9q.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-CRj5Ruqn.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page-BzMfp_HM.js → share-preview-page-DCt1pTWB.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-BNbXPk--.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-CNMCLbav.js +1 -0
- package/dist/gateway/static/root/assets/{skills-page-DIht92q6.js → skills-page-BIOcg44X.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page.utils-DLYRiEn3.js → skills-page.utils-CgZdzT4I.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-yYs4YgYk.js → system-settings-panel-_YaRncA6.js} +1 -1
- package/dist/gateway/static/root/assets/task-detail-page-CAcfAG-c.js +1 -0
- package/dist/gateway/static/root/assets/tasks-CDR_RVbQ.js +1 -0
- package/dist/gateway/static/root/assets/{tunnel-api-BasDYxvx.js → tunnel-api-uOupJOoS.js} +1 -1
- package/dist/gateway/static/root/assets/turn-outcome-D0SnyZ3Z.js +1 -0
- package/dist/gateway/static/root/assets/{use-autosave-CWAUHhcb.js → use-autosave-BezzHBLE.js} +1 -1
- package/dist/gateway/static/root/assets/user-model-page-BFFeneDq.js +2 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-Kc4UlxZs.js → voice-api-key-field-BmYifdwL.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-config-api-DTyMdGOR.js → voice-config-api-D_5Q2_A3.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-BPC_c9dO.js → work-discovery-overlay-4DmyEckJ.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-DBTciOrq.js → workflow-run-setup-panel-DeZe8bTZ.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-Sv4hEc6W.js +6 -0
- package/dist/gateway/static/root/index.html +16 -16
- package/dist/package.js +1 -1
- package/dist/packages/computer-control-contract/src/index.js +10 -1
- package/dist/packages/gateway-contract/src/app-context.js +55 -0
- package/dist/packages/gateway-contract/src/automations.js +16 -17
- package/dist/packages/gateway-contract/src/capabilities.js +1078 -0
- package/dist/packages/gateway-contract/src/extension-capabilities.js +26 -0
- package/dist/packages/gateway-contract/src/home.js +3 -3
- package/dist/packages/gateway-contract/src/index.js +8 -0
- package/dist/packages/gateway-contract/src/product-delivery.js +19 -4
- package/dist/packages/gateway-contract/src/scenes.js +199 -0
- package/dist/packages/gateway-contract/src/task-runs.js +8 -4
- package/dist/packages/gateway-contract/src/tasks.js +5 -4
- package/dist/packages/realtime-client/src/index.js +17 -4
- package/dist/src/agent/agent-manager.d.ts +1 -0
- package/dist/src/agent/agent-manager.js +1 -0
- package/dist/src/agent/child-agent-factory.d.ts +2 -0
- package/dist/src/agent/child-agent-factory.js +5 -0
- package/dist/src/agent/commands/approved-verification.d.ts +14 -0
- package/dist/src/agent/commands/approved-verification.js +48 -0
- package/dist/src/agent/context/execution-scope.js +2 -1
- package/dist/src/agent/context/project-context.js +2 -1
- package/dist/src/agent/external-tools/cliProvider.js +123 -75
- package/dist/src/agent/external-tools/composio-provider.d.ts +1 -1
- package/dist/src/agent/external-tools/composio-provider.js +70 -12
- package/dist/src/agent/external-tools/endpoint-provider.js +14 -1
- package/dist/src/agent/inbound/turn-dispatcher.d.ts +2 -0
- package/dist/src/agent/inbound/turn-dispatcher.js +2 -1
- package/dist/src/agent/memory/compaction-chunks.d.ts +6 -1
- package/dist/src/agent/memory/compaction-chunks.js +16 -3
- package/dist/src/agent/memory/compaction-ledger.d.ts +3 -1
- package/dist/src/agent/memory/compaction-ledger.js +31 -18
- package/dist/src/agent/memory/compaction-request.d.ts +2 -0
- package/dist/src/agent/memory/compaction-request.js +6 -1
- package/dist/src/agent/memory/compaction.d.ts +19 -1
- package/dist/src/agent/memory/compaction.js +112 -30
- package/dist/src/agent/service/process-direct-streaming.d.ts +3 -0
- package/dist/src/agent/service/process-direct-streaming.js +19 -10
- package/dist/src/agent/service.js +1 -0
- package/dist/src/agent/service.types.d.ts +1 -0
- package/dist/src/agent/skills/config.js +2 -0
- package/dist/src/agent/skills/format-skills-prompt.js +14 -1
- package/dist/src/agent/skills/index.js +16 -8
- package/dist/src/agent/skills/types.d.ts +1 -1
- package/dist/src/agent/source-context/app-context.d.ts +4 -0
- package/dist/src/agent/source-context/app-context.js +36 -0
- package/dist/src/agent/source-context/injector.js +1 -0
- package/dist/src/agent/source-context/types.d.ts +5 -1
- package/dist/src/agent/tasks/task-judge-service.js +2 -1
- package/dist/src/agent/tool-manuals/computer.d.ts +1 -1
- package/dist/src/agent/tool-manuals/computer.js +1 -1
- package/dist/src/agent/tools/automation-tool.d.ts +12 -1
- package/dist/src/agent/tools/automation-tool.js +106 -32
- package/dist/src/agent/tools/factory.d.ts +1 -0
- package/dist/src/agent/tools/factory.js +6 -1
- package/dist/src/agent/tools/scoped-workspace-tools.d.ts +8 -0
- package/dist/src/agent/tools/scoped-workspace-tools.js +81 -0
- package/dist/src/agent/tools/xopc-use-tool.d.ts +6 -3
- package/dist/src/agent/tools/xopc-use-tool.js +997 -908
- package/dist/src/agent/workflow/subagent-runner.js +1 -0
- package/dist/src/agent-config/index.js +2 -2
- package/dist/src/agent-config/schema.d.ts +5 -0
- package/dist/src/agent-config/schema.js +14 -10
- package/dist/src/automations/api/routes.js +244 -164
- package/dist/src/automations/capabilities/drafts.d.ts +4 -0
- package/dist/src/automations/capabilities/drafts.js +95 -0
- package/dist/src/automations/capabilities/read.d.ts +4 -0
- package/dist/src/automations/capabilities/read.js +119 -0
- package/dist/src/automations/capabilities/write.d.ts +349 -0
- package/dist/src/automations/capabilities/write.js +172 -0
- package/dist/src/automations/domain/index.js +2 -2
- package/dist/src/automations/domain/validation.d.ts +77 -77
- package/dist/src/automations/domain/validation.js +9 -6
- package/dist/src/automations/draft/automation-draft-validator.d.ts +2 -2
- package/dist/src/automations/index.js +6 -6
- package/dist/src/automations/service/automation-service.d.ts +31 -0
- package/dist/src/automations/service/automation-service.js +213 -75
- package/dist/src/automations/service/index.js +2 -2
- package/dist/src/automations/storage/automation-repository.d.ts +2 -0
- package/dist/src/automations/storage/automation-repository.js +9 -1
- package/dist/src/automations/storage/automation-run-repository.d.ts +4 -1
- package/dist/src/automations/storage/automation-run-repository.js +16 -3
- package/dist/src/automations/storage/index.js +3 -3
- package/dist/src/browser/automations/schema.d.ts +1 -1
- package/dist/src/browser/automations/service.d.ts +1 -1
- package/dist/src/browser/observation/format.js +4 -0
- package/dist/src/capabilities/adapters/http.d.ts +4 -0
- package/dist/src/capabilities/adapters/http.js +44 -0
- package/dist/src/capabilities/readiness/from-config.js +11 -7
- package/dist/src/capabilities/runtime/app-context.d.ts +3 -0
- package/dist/src/capabilities/runtime/app-context.js +72 -0
- package/dist/src/capabilities/runtime/atomic-operations.d.ts +11 -0
- package/dist/src/capabilities/runtime/atomic-operations.js +34 -0
- package/dist/src/capabilities/runtime/dispatcher.d.ts +67 -0
- package/dist/src/capabilities/runtime/dispatcher.js +170 -0
- package/dist/src/capabilities/runtime/errors.d.ts +6 -0
- package/dist/src/capabilities/runtime/errors.js +11 -0
- package/dist/src/capabilities/runtime/external-operations.d.ts +16 -0
- package/dist/src/capabilities/runtime/external-operations.js +92 -0
- package/dist/src/capabilities/runtime/product.d.ts +12 -0
- package/dist/src/capabilities/runtime/product.js +69 -0
- package/dist/src/capabilities/runtime/settings.d.ts +3 -0
- package/dist/src/capabilities/runtime/settings.js +27 -0
- package/dist/src/channels/index.js +2 -2
- package/dist/src/channels/manager.js +1 -1
- package/dist/src/cli/cli-log-level-preset.d.ts +2 -0
- package/dist/src/cli/cli-log-level-preset.js +4 -0
- package/dist/src/cli/command-catalog.js +4 -0
- package/dist/src/cli/command-loaders.js +1 -0
- package/dist/src/cli/command-manifest.js +4 -0
- package/dist/src/cli/commands/channels.js +1 -1
- package/dist/src/cli/commands/connectors.js +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +1 -1
- package/dist/src/cli/commands/mcp.d.ts +1 -0
- package/dist/src/cli/commands/mcp.js +51 -0
- package/dist/src/cli/commands/models.js +1 -1
- package/dist/src/cli/commands/onboard.js +1 -1
- package/dist/src/cli/commands/project.js +1 -1
- package/dist/src/computer/broker.d.ts +0 -1
- package/dist/src/computer/broker.js +4 -6
- package/dist/src/computer/evaluation-harness.d.ts +45 -0
- package/dist/src/computer/evaluation-harness.js +108 -0
- package/dist/src/computer/model-adapter.d.ts +37 -2
- package/dist/src/computer/model-adapter.js +333 -42
- package/dist/src/computer/model-policy.d.ts +4 -1
- package/dist/src/computer/model-policy.js +11 -3
- package/dist/src/computer/release-gate.d.ts +22 -0
- package/dist/src/computer/release-gate.js +19 -0
- package/dist/src/computer/runtime.js +14 -10
- package/dist/src/computer/task-state.d.ts +1 -0
- package/dist/src/computer/task-state.js +1 -0
- package/dist/src/config/models-json.d.ts +14 -8
- package/dist/src/config/models-json.js +1 -1
- package/dist/src/config/schema.d.ts +4 -0
- package/dist/src/config/schema.js +3 -9
- package/dist/src/connectors/composio-sessions.d.ts +4 -2
- package/dist/src/connectors/composio-sessions.js +10 -9
- package/dist/src/connectors/composio.js +10 -8
- package/dist/src/discussions/action-tasks.js +2 -1
- package/dist/src/discussions/recording.js +1 -1
- package/dist/src/execution-environments/local-worktree-manager.d.ts +1 -0
- package/dist/src/execution-environments/local-worktree-manager.js +13 -2
- package/dist/src/extensions/activation-context.js +3 -3
- package/dist/src/extensions/api.js +1 -1
- package/dist/src/extensions/normalize-manifest.js +6 -1
- package/dist/src/extensions/sdk/index.js +1 -1
- package/dist/src/extensions/sdk/media.js +1 -1
- package/dist/src/extensions/types/manifest.d.ts +3 -0
- package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
- package/dist/src/gateway/hono/lib/config-payload.d.ts +1 -0
- package/dist/src/gateway/hono/middleware/scopes.js +1 -1
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js +5 -2
- package/dist/src/gateway/hono/routes/capability-operations.d.ts +3 -0
- package/dist/src/gateway/hono/routes/capability-operations.js +52 -0
- package/dist/src/gateway/hono/routes/lazy-bundles.js +16 -0
- package/dist/src/gateway/hono/routes/local-app-capabilities.d.ts +4 -0
- package/dist/src/gateway/hono/routes/local-app-capabilities.js +41 -0
- package/dist/src/gateway/hono/routes/local-apps.js +41 -9
- package/dist/src/gateway/hono/routes/models.js +2 -2
- package/dist/src/gateway/hono/routes/notes.js +215 -146
- package/dist/src/gateway/hono/routes/projects.js +217 -374
- package/dist/src/gateway/hono/routes/scenes.js +188 -75
- package/dist/src/gateway/hono/routes/session-input-handler.d.ts +60 -16
- package/dist/src/gateway/hono/routes/session-input-handler.js +43 -1
- package/dist/src/gateway/hono/routes/sessions.js +17 -0
- package/dist/src/gateway/hono/routes/status.js +1 -1
- package/dist/src/gateway/hono/routes/tasks.js +182 -326
- package/dist/src/gateway/hono/routes/user-model-refresh.js +1 -1
- package/dist/src/gateway/hono/routes/voice.js +4 -4
- package/dist/src/gateway/hono/routes/workflows.js +1 -1
- package/dist/src/gateway/media-access.js +2 -1
- package/dist/src/gateway/mobile-privacy.js +2 -2
- package/dist/src/gateway/scenes/host.js +14 -3
- package/dist/src/gateway/scenes/mailContext.js +1 -1
- package/dist/src/gateway/scenes/slackThreadSource.d.ts +41 -0
- package/dist/src/gateway/scenes/slackThreadSource.js +168 -0
- package/dist/src/gateway/security/gateway-scopes.d.ts +1 -1
- package/dist/src/gateway/security/gateway-scopes.js +5 -0
- package/dist/src/gateway/service/app-context-access.d.ts +11 -0
- package/dist/src/gateway/service/app-context-access.js +70 -0
- package/dist/src/gateway/service/run-gateway-agent.js +11 -2
- package/dist/src/gateway/service/session-input-coordinator.js +54 -15
- package/dist/src/gateway/service/sessions-api.d.ts +1 -0
- package/dist/src/gateway/service/sessions-api.js +3 -0
- package/dist/src/gateway/service/task-conversation-query-service.d.ts +3 -1
- package/dist/src/gateway/service/task-conversation-query-service.js +32 -3
- package/dist/src/gateway/service.d.ts +3 -0
- package/dist/src/gateway/service.js +69 -15
- package/dist/src/gateway/session-context-summary.js +2 -1
- package/dist/src/{tasks/task-outbox-dispatcher.d.ts → infra/domain-outbox-dispatcher.d.ts} +2 -2
- package/dist/src/{tasks/task-outbox-dispatcher.js → infra/domain-outbox-dispatcher.js} +10 -9
- package/dist/src/infra/operation-context.d.ts +2 -0
- package/dist/src/infra/operation-context.js +16 -0
- package/dist/src/local-apps/capabilities/contracts.d.ts +2 -0
- package/dist/src/local-apps/capabilities/contracts.js +32 -0
- package/dist/src/local-apps/capabilities/read.d.ts +3 -0
- package/dist/src/local-apps/capabilities/read.js +48 -0
- package/dist/src/local-apps/capabilities/runtime.d.ts +16 -0
- package/dist/src/local-apps/capabilities/runtime.js +66 -0
- package/dist/src/local-apps/capabilities/write.d.ts +3 -0
- package/dist/src/local-apps/capabilities/write.js +35 -0
- package/dist/src/local-apps/release-lock.d.ts +2 -0
- package/dist/src/local-apps/release-lock.js +20 -0
- package/dist/src/local-apps/runtime-entry.d.ts +0 -2
- package/dist/src/local-apps/runtime-entry.js +1 -14
- package/dist/src/local-apps/scaffold.js +4 -1
- package/dist/src/local-apps/service.d.ts +24 -1
- package/dist/src/local-apps/service.js +186 -43
- package/dist/src/local-apps/store.js +0 -2
- package/dist/src/mcp/capability-server.d.ts +4 -0
- package/dist/src/mcp/capability-server.js +96 -0
- package/dist/src/mcp/channel-bridge.js +1 -1
- package/dist/src/mcp/gateway-http-client.d.ts +7 -0
- package/dist/src/mcp/gateway-http-client.js +27 -5
- package/dist/src/media-understanding/openai-compatible-audio.js +1 -1
- package/dist/src/notes/agent-context.js +1 -1
- package/dist/src/notes/capabilities/read.d.ts +3 -0
- package/dist/src/notes/capabilities/read.js +96 -0
- package/dist/src/notes/capabilities/write.d.ts +7 -0
- package/dist/src/notes/capabilities/write.js +152 -0
- package/dist/src/notes/index.js +1 -1
- package/dist/src/notes/service.d.ts +12 -4
- package/dist/src/notes/service.js +188 -175
- package/dist/src/notes/store.d.ts +14 -9
- package/dist/src/notes/store.js +81 -21
- package/dist/src/notifications/service.d.ts +1 -0
- package/dist/src/notifications/service.js +5 -0
- package/dist/src/platform/client.d.ts +1 -1
- package/dist/src/platform/contracts.d.ts +1 -1
- package/dist/src/projects/capabilities/read.d.ts +3 -0
- package/dist/src/projects/capabilities/read.js +81 -0
- package/dist/src/projects/capabilities/write.d.ts +9 -0
- package/dist/src/projects/capabilities/write.js +260 -0
- package/dist/src/projects/index.js +2 -2
- package/dist/src/projects/project-change-events.d.ts +2 -0
- package/dist/src/projects/project-change-events.js +18 -0
- package/dist/src/projects/project-service.d.ts +11 -0
- package/dist/src/projects/project-service.js +121 -42
- package/dist/src/projects/project-store.js +12 -2
- package/dist/src/projects/project-workspace-creation.d.ts +3 -0
- package/dist/src/projects/project-workspace-creation.js +45 -0
- package/dist/src/projects/workspace-project.js +6 -0
- package/dist/src/providers/model-catalog-types.d.ts +2 -1
- package/dist/src/providers/model-reference-auditor.js +4 -4
- package/dist/src/providers/model-supplements.js +13 -3
- package/dist/src/providers/presentation.js +3 -3
- package/dist/src/providers/xopc-cloud-model-source.js +4 -2
- package/dist/src/realtime/runtime.js +4 -0
- package/dist/src/scenes/capabilities/read.d.ts +3 -0
- package/dist/src/scenes/capabilities/read.js +187 -0
- package/dist/src/scenes/capabilities/write.d.ts +3 -0
- package/dist/src/scenes/capabilities/write.js +151 -0
- package/dist/src/scenes/contracts.d.ts +2 -105
- package/dist/src/scenes/contracts.js +3 -88
- package/dist/src/scenes/execution.d.ts +1 -1
- package/dist/src/scenes/httpServices.d.ts +2 -0
- package/dist/src/scenes/inbox.d.ts +1 -0
- package/dist/src/scenes/inbox.js +7 -7
- package/dist/src/scenes/preferences.d.ts +3 -24
- package/dist/src/scenes/preferences.js +8 -30
- package/dist/src/scenes/repository.d.ts +1 -0
- package/dist/src/scenes/repository.js +7 -3
- package/dist/src/scenes/resultNotifications.js +2 -2
- package/dist/src/scenes/schedule.d.ts +1 -8
- package/dist/src/scenes/schedule.js +3 -15
- package/dist/src/scenes/service.d.ts +6 -0
- package/dist/src/scenes/service.js +29 -25
- package/dist/src/scenes/taskFollowUp/agentExecutor.d.ts +36 -0
- package/dist/src/scenes/taskFollowUp/agentExecutor.js +149 -0
- package/dist/src/scenes/taskFollowUp/branchInventory.d.ts +38 -0
- package/dist/src/scenes/taskFollowUp/branchInventory.js +70 -0
- package/dist/src/scenes/taskFollowUp/contracts.d.ts +91 -0
- package/dist/src/scenes/taskFollowUp/contracts.js +100 -0
- package/dist/src/scenes/taskFollowUp/resources.d.ts +19 -0
- package/dist/src/scenes/taskFollowUp/resources.js +97 -0
- package/dist/src/scenes/taskFollowUp/service.d.ts +810 -0
- package/dist/src/scenes/taskFollowUp/service.js +710 -0
- package/dist/src/scenes/taskFollowUp/workspaceFingerprint.d.ts +2 -0
- package/dist/src/scenes/taskFollowUp/workspaceFingerprint.js +46 -0
- package/dist/src/scenes/templates.d.ts +2 -2
- package/dist/src/scenes/templates.js +1 -1
- package/dist/src/session/session-find.d.ts +17 -0
- package/dist/src/session/session-find.js +56 -0
- package/dist/src/session/store.d.ts +4 -0
- package/dist/src/session/store.js +43 -7
- package/dist/src/share/note-share-revocation.d.ts +3 -0
- package/dist/src/share/note-share-revocation.js +26 -0
- package/dist/src/storage/sqlite/migrations/190_scene_development.sql +37 -0
- package/dist/src/storage/sqlite/migrations/191_scene_task_follow_up.sql +27 -0
- package/dist/src/storage/sqlite/migrations/192_capability_operations.sql +20 -0
- package/dist/src/storage/sqlite/migrations/193_note_file_cleanup.sql +8 -0
- package/dist/src/storage/sqlite/migrations/194_capability_external_outcomes.sql +11 -0
- package/dist/src/storage/sqlite/migrations/195_automation_deleted_revisions.sql +4 -0
- package/dist/src/storage/sqlite/migrations/196_automation_run_requests.sql +23 -0
- package/dist/src/storage/sqlite/migrations/197_note_deletion_cleanup.sql +8 -0
- package/dist/src/storage/sqlite/migrations/198_project_workspace_creation.sql +7 -0
- package/dist/src/storage/sqlite/migrations/199_scene_resource_events.sql +488 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
- package/dist/src/storage/sqlite/migrations/runner.js +6 -3
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/storage/sqlite/transaction.d.ts +5 -0
- package/dist/src/storage/sqlite/transaction.js +34 -3
- package/dist/src/tasks/capabilities/management.d.ts +195 -0
- package/dist/src/tasks/capabilities/management.js +111 -0
- package/dist/src/tasks/capabilities/read.d.ts +2 -0
- package/dist/src/tasks/capabilities/read.js +141 -0
- package/dist/src/tasks/capabilities/relations.d.ts +204 -0
- package/dist/src/tasks/capabilities/relations.js +140 -0
- package/dist/src/tasks/capabilities/runs.d.ts +2 -0
- package/dist/src/tasks/capabilities/runs.js +89 -0
- package/dist/src/tasks/capabilities/write.d.ts +207 -0
- package/dist/src/tasks/capabilities/write.js +107 -0
- package/dist/src/tasks/home-query-service.js +3 -2
- package/dist/src/tasks/index.d.ts +0 -1
- package/dist/src/tasks/index.js +9 -9
- package/dist/src/tasks/project-operating-view-service.js +2 -1
- package/dist/src/tasks/task-application-service.d.ts +1 -0
- package/dist/src/tasks/task-application-service.js +3 -2
- package/dist/src/tasks/task-change-events.js +5 -3
- package/dist/src/tasks/task-context-assembler.js +2 -1
- package/dist/src/tasks/task-deletion-service.js +2 -1
- package/dist/src/tasks/task-dependency-service.js +2 -1
- package/dist/src/tasks/task-handoff-service.js +2 -1
- package/dist/src/tasks/task-read-model-projector.js +2 -1
- package/dist/src/tasks/task-repository.d.ts +12 -7
- package/dist/src/tasks/task-repository.js +175 -154
- package/dist/src/tasks/task-run-coordinator.js +2 -1
- package/dist/src/tasks/task-run-dispatcher.js +2 -1
- package/dist/src/tasks/task-run-repository.d.ts +1 -0
- package/dist/src/tasks/task-run-repository.js +29 -14
- package/dist/src/tasks/task-signal-service.js +2 -1
- package/dist/src/tui/backends/embedded-backend.js +1 -1
- package/dist/src/tui/backends/gateway-realtime-backend.js +1 -1
- package/dist/src/tui/tui-commands.js +1 -1
- package/dist/src/user-context/config.d.ts +13 -0
- package/dist/src/user-context/config.js +2 -0
- package/dist/src/voice/platform-catalog.d.ts +1 -1
- package/dist/src/voice/realtime/runtime.js +3 -3
- package/dist/src/voice/stt/providers/alibaba-transcription.js +1 -1
- package/dist/src/voice/stt/providers/xopc-cloud-transcription.js +1 -1
- package/dist/src/voice/tts/providers/xopc-cloud-speech.js +1 -1
- package/dist/src/work-discovery/incremental-repository.js +1 -1
- package/dist/src/work-discovery/index.js +1 -1
- package/dist/src/work-discovery/repository.d.ts +1 -1
- package/dist/src/work-discovery/repository.js +3 -2
- package/dist/src/work-discovery/service.d.ts +4 -0
- package/dist/src/work-discovery/service.js +36 -11
- package/dist/src/workflows/context/workflow-context.js +3 -2
- package/dist/src/workflows/service/workflow-run-service.js +2 -1
- package/package.json +6 -2
- package/skills/THIRD_PARTY_NOTICES.md +2 -2
- package/skills/documents/xlsx/SKILL.md +5 -0
- package/skills/engineering/build-xopc-local-app/SKILL.md +2 -0
- package/skills/tools/find-skills/SKILL.md +3 -0
- package/dist/gateway/static/root/assets/activity-store-DVUTs1fk.js +0 -1
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-K3hTmu9d.js +0 -1
- package/dist/gateway/static/root/assets/appearance-settings-CU52MfIT.js +0 -1
- package/dist/gateway/static/root/assets/apps-page-ZpA1-6ad.js +0 -1
- package/dist/gateway/static/root/assets/automations-workspace-IEAxKRME.js +0 -7
- package/dist/gateway/static/root/assets/browser-settings-page-CU4VWsmX.js +0 -3
- package/dist/gateway/static/root/assets/capabilities-settings-panel-C9XQk3HL.js +0 -8
- package/dist/gateway/static/root/assets/channels-settings-Bqlhjooi.js +0 -1
- package/dist/gateway/static/root/assets/connector-service-page-BmH17JnO.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-zkx8Q-e6.js +0 -2
- package/dist/gateway/static/root/assets/desktop-pet-settings-CE4GOlMM.js +0 -1
- package/dist/gateway/static/root/assets/device-pairing-wizard-CdKJqnnw.js +0 -1
- package/dist/gateway/static/root/assets/files-Be5viEFY.js +0 -1
- package/dist/gateway/static/root/assets/gateway-realtime-CGOW0-b4.js +0 -1
- package/dist/gateway/static/root/assets/gateway-realtime-store-D4um_sV7.js +0 -1
- package/dist/gateway/static/root/assets/gateway-settings-CgXp2zq4.js +0 -1
- package/dist/gateway/static/root/assets/home-page-D6Idk732.js +0 -1
- package/dist/gateway/static/root/assets/index-1wIKA-kM.css +0 -1
- package/dist/gateway/static/root/assets/index-PFQHPGgi.js +0 -79
- package/dist/gateway/static/root/assets/local-app-workbench-page-BmAqTRb4.js +0 -2
- package/dist/gateway/static/root/assets/logs-page-ZjVYXXyM.js +0 -2
- package/dist/gateway/static/root/assets/management-settings-CSTkYVOZ.js +0 -1
- package/dist/gateway/static/root/assets/messages-4BtQKYlM.js +0 -3
- package/dist/gateway/static/root/assets/note-detail-panel-DuXCt-MM.js +0 -5
- package/dist/gateway/static/root/assets/notes-page-BjOgBVq5.js +0 -8
- package/dist/gateway/static/root/assets/product-delivery-CrAI8ZEa.js +0 -1
- package/dist/gateway/static/root/assets/project-detail-page-0zi4-i9X.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-B18OxmJj.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-z-DxbuaE.js +0 -1
- package/dist/gateway/static/root/assets/runtime-tools-settings-panel-DGsBTbo6.js +0 -5
- package/dist/gateway/static/root/assets/scenes-page-Bgba03B_.js +0 -1
- package/dist/gateway/static/root/assets/schemas-BaskVM5g.js +0 -64
- package/dist/gateway/static/root/assets/sessions-page-B1t3bMsm.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-CBX0Ezhf.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-Bw71C2X3.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-BoVDQolc.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-DtTptpAt.js +0 -1
- package/dist/gateway/static/root/assets/task-detail-page-vgkiGo-D.js +0 -1
- package/dist/gateway/static/root/assets/theme-store-CegIlB8d.js +0 -1
- package/dist/gateway/static/root/assets/user-model-page-CAGafNfP.js +0 -2
- package/dist/gateway/static/root/assets/workflows-page-CSxHVs1p.js +0 -6
- package/skills/creative/algorithmic-art/SKILL.md +0 -44
- package/skills/creative/algorithmic-art/templates/generator-template.js +0 -27
- package/skills/creative/algorithmic-art/templates/viewer.html +0 -27
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import { ExtensionCapabilityBindingsSchema, extensionCapabilityPermissions } from "../../packages/gateway-contract/src/extension-capabilities.js";
|
|
2
|
+
import { init_src } from "../../packages/gateway-contract/src/index.js";
|
|
1
3
|
import { LOCAL_APP_RUNTIME_ENTRY, LOCAL_APP_RUNTIME_SOURCE } from "./runtime-entry.js";
|
|
2
4
|
import { dirname, join } from "node:path";
|
|
3
5
|
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
4
6
|
//#region src/local-apps/scaffold.ts
|
|
7
|
+
init_src();
|
|
5
8
|
const LOCAL_APP_PERMISSIONS = ["theme", "storage"];
|
|
6
9
|
function writeText(root, relativePath, content) {
|
|
7
10
|
const target = join(root, relativePath);
|
|
@@ -111,7 +114,7 @@ button?.addEventListener('click', () => {
|
|
|
111
114
|
function readLocalAppPermissions(workspaceRoot) {
|
|
112
115
|
try {
|
|
113
116
|
const raw = JSON.parse(readFileSync(join(workspaceRoot, "xopc.extension.json"), "utf8"));
|
|
114
|
-
return Array.isArray(raw.ui?.permissions) ? raw.ui.permissions.filter((permission) => typeof permission === "string") : [];
|
|
117
|
+
return [...Array.isArray(raw.ui?.permissions) ? raw.ui.permissions.filter((permission) => typeof permission === "string") : [], ...extensionCapabilityPermissions(ExtensionCapabilityBindingsSchema.parse(raw.ui?.capabilities ?? []))];
|
|
115
118
|
} catch {
|
|
116
119
|
return [];
|
|
117
120
|
}
|
|
@@ -3,6 +3,10 @@ import type { ExtensionLoader } from '../extensions/index.js';
|
|
|
3
3
|
import type { ProjectService } from '../projects/index.js';
|
|
4
4
|
import { LocalAppStore } from './store.js';
|
|
5
5
|
import type { CreateLocalAppInput, LocalApp, LocalAppAcceptanceRun, LocalAppDetail, LocalAppPreviewTarget, LocalAppValidationResult, LocalAppUiGrant, RecordLocalAppAcceptanceInput } from './types.js';
|
|
6
|
+
export declare class LocalAppRevisionConflictError extends Error {
|
|
7
|
+
}
|
|
8
|
+
export declare class LocalAppAcceptanceValidationError extends Error {
|
|
9
|
+
}
|
|
6
10
|
export interface LocalAppServiceOptions {
|
|
7
11
|
projects: ProjectService;
|
|
8
12
|
workspaceRoot: string;
|
|
@@ -18,20 +22,39 @@ export declare class LocalAppService {
|
|
|
18
22
|
private readonly options;
|
|
19
23
|
private readonly store;
|
|
20
24
|
constructor(options: LocalAppServiceOptions, store?: LocalAppStore);
|
|
25
|
+
private recoveryRoot;
|
|
26
|
+
private recoveryMarker;
|
|
27
|
+
/** Reconcile interrupted mutations before any extension code or request can run. */
|
|
28
|
+
recoverPendingReleases(): Promise<void>;
|
|
29
|
+
private recoverReleases;
|
|
30
|
+
private mutateRelease;
|
|
21
31
|
list(): LocalApp[];
|
|
22
32
|
get(id: string): LocalAppDetail | null;
|
|
23
33
|
getUiGrant(extensionId: string): LocalAppUiGrant;
|
|
24
|
-
|
|
34
|
+
getCapabilityAccess(extensionId: string, expectedManifestDigest: string): {
|
|
35
|
+
releaseId: string;
|
|
36
|
+
bindings: {
|
|
37
|
+
id: "xopc.notes.get" | "xopc.notes.list" | "xopc.tasks.get" | "xopc.tasks.list" | "xopc.notes.create" | "xopc.notes.update" | "xopc.notes.append";
|
|
38
|
+
majorVersion: number;
|
|
39
|
+
descriptorDigest: string;
|
|
40
|
+
}[];
|
|
41
|
+
};
|
|
42
|
+
grantUiPermissions(extensionId: string, expectedManifestDigest: string): LocalAppUiGrant;
|
|
25
43
|
create(input: CreateLocalAppInput): LocalAppDetail;
|
|
26
44
|
resolvePreview(previewToken: string): LocalAppPreviewTarget | null;
|
|
27
45
|
validate(id: string): LocalAppValidationResult;
|
|
28
46
|
recordAcceptance(id: string, input: RecordLocalAppAcceptanceInput): LocalAppAcceptanceRun;
|
|
47
|
+
flushAcceptanceEvents(): void;
|
|
29
48
|
private releaseRoot;
|
|
30
49
|
private refreshExtensions;
|
|
31
50
|
private assertInstalledRuntime;
|
|
32
51
|
private activateArtifact;
|
|
33
52
|
install(id: string): Promise<LocalAppDetail>;
|
|
53
|
+
private installRelease;
|
|
34
54
|
rollback(id: string, releaseId: string): Promise<LocalAppDetail>;
|
|
55
|
+
private rollbackRelease;
|
|
35
56
|
setEnabled(id: string, enabled: boolean): Promise<LocalAppDetail>;
|
|
57
|
+
private setReleaseEnabled;
|
|
36
58
|
uninstall(id: string): Promise<LocalAppDetail>;
|
|
59
|
+
private uninstallRelease;
|
|
37
60
|
}
|
|
@@ -1,18 +1,29 @@
|
|
|
1
1
|
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
|
+
import { currentOperationId, init_operation_context } from "../infra/operation-context.js";
|
|
5
|
+
import { afterSqliteCommit, init_transaction, runSqliteWriteTransaction } from "../storage/sqlite/transaction.js";
|
|
6
|
+
import { ExtensionCapabilityBindingsSchema, extensionCapabilityPermissions } from "../../packages/gateway-contract/src/extension-capabilities.js";
|
|
7
|
+
import { init_src } from "../../packages/gateway-contract/src/index.js";
|
|
4
8
|
import { init_paths, resolveExtensionsDir } from "../config/paths.js";
|
|
5
9
|
import { LocalAppStore } from "./store.js";
|
|
6
10
|
import { slugifyProjectName } from "../projects/project-store.js";
|
|
11
|
+
import { CapabilityError } from "../capabilities/runtime/errors.js";
|
|
12
|
+
import { DomainOutboxDispatcher } from "../infra/domain-outbox-dispatcher.js";
|
|
13
|
+
import { validateLocalAppCapabilityContracts } from "./capabilities/contracts.js";
|
|
7
14
|
import { readLocalAppAcceptanceConfig } from "./acceptance.js";
|
|
8
|
-
import { LOCAL_APP_RUNTIME_ENTRY, LOCAL_APP_RUNTIME_SOURCE
|
|
15
|
+
import { LOCAL_APP_RUNTIME_ENTRY, LOCAL_APP_RUNTIME_SOURCE } from "./runtime-entry.js";
|
|
9
16
|
import { readLocalAppPermissions, scaffoldLocalApp } from "./scaffold.js";
|
|
17
|
+
import { withLocalAppReleaseLock } from "./release-lock.js";
|
|
10
18
|
import { basename, join, relative, resolve, sep } from "node:path";
|
|
11
|
-
import { cpSync, existsSync, lstatSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, renameSync, rmSync } from "node:fs";
|
|
12
|
-
import { createHash, randomBytes } from "node:crypto";
|
|
19
|
+
import { cpSync, existsSync, lstatSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
20
|
+
import { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
13
21
|
//#region src/local-apps/service.ts
|
|
22
|
+
init_src();
|
|
14
23
|
init_paths();
|
|
15
24
|
init_logger();
|
|
25
|
+
init_transaction();
|
|
26
|
+
init_operation_context();
|
|
16
27
|
const log = createLogger("LocalApps");
|
|
17
28
|
const RELEASE_COPY_EXCLUDED_NAMES = new Set([".git", "node_modules"]);
|
|
18
29
|
const UI_ONLY_PERMISSIONS = new Set([
|
|
@@ -20,6 +31,21 @@ const UI_ONLY_PERMISSIONS = new Set([
|
|
|
20
31
|
"storage",
|
|
21
32
|
"notification"
|
|
22
33
|
]);
|
|
34
|
+
function cleanupReleaseStaging(path) {
|
|
35
|
+
try {
|
|
36
|
+
rmSync(path, {
|
|
37
|
+
recursive: true,
|
|
38
|
+
force: true
|
|
39
|
+
});
|
|
40
|
+
} catch (err) {
|
|
41
|
+
log.warn({
|
|
42
|
+
err,
|
|
43
|
+
path
|
|
44
|
+
}, "Local app staging cleanup failed; retained for inspection");
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
var LocalAppRevisionConflictError = class extends Error {};
|
|
48
|
+
var LocalAppAcceptanceValidationError = class extends Error {};
|
|
23
49
|
function requireText(value, label) {
|
|
24
50
|
const trimmed = value.trim();
|
|
25
51
|
if (!trimmed) throw new Error(`${label} is required`);
|
|
@@ -118,7 +144,7 @@ function permissionsFromManifestJson(manifestJson) {
|
|
|
118
144
|
if (!manifestJson) return [];
|
|
119
145
|
try {
|
|
120
146
|
const manifest = JSON.parse(manifestJson);
|
|
121
|
-
return Array.isArray(manifest.ui?.permissions) ? manifest.ui.permissions.filter((value) => typeof value === "string") : [];
|
|
147
|
+
return [...Array.isArray(manifest.ui?.permissions) ? manifest.ui.permissions.filter((value) => typeof value === "string") : [], ...extensionCapabilityPermissions(ExtensionCapabilityBindingsSchema.parse(manifest.ui?.capabilities ?? []))];
|
|
122
148
|
} catch {
|
|
123
149
|
return [];
|
|
124
150
|
}
|
|
@@ -135,10 +161,11 @@ function validateLocalAppPackage(root, extensionId) {
|
|
|
135
161
|
const resolvedPath = resolve(root, declaredPath);
|
|
136
162
|
if (!resolvedPath.startsWith(`${resolvedRoot}${sep}`) || !existsSync(resolvedPath) || !lstatSync(resolvedPath).isFile()) throw new Error(`Declared app file is missing or unsafe: ${declaredPath}`);
|
|
137
163
|
}
|
|
138
|
-
const trustedRuntime = manifest.main === ".xopc/runtime/local-ui.js" ? LOCAL_APP_RUNTIME_SOURCE :
|
|
164
|
+
const trustedRuntime = manifest.main === ".xopc/runtime/local-ui.js" ? LOCAL_APP_RUNTIME_SOURCE : null;
|
|
139
165
|
if (trustedRuntime === null || readFileSync(join(root, manifest.main), "utf8") !== trustedRuntime) throw new Error(`Phase 1 local apps must use the xopc-owned runtime entry: ${LOCAL_APP_RUNTIME_ENTRY}`);
|
|
140
166
|
const unsupported = (Array.isArray(manifest.ui.permissions) ? manifest.ui.permissions.filter((value) => typeof value === "string") : []).filter((permission) => !UI_ONLY_PERMISSIONS.has(permission));
|
|
141
167
|
if (unsupported.length) throw new Error(`Phase 1 local apps cannot request: ${unsupported.join(", ")}`);
|
|
168
|
+
validateLocalAppCapabilityContracts(manifest.ui.capabilities);
|
|
142
169
|
const html = readFileSync(join(root, manifest.ui.main), "utf8");
|
|
143
170
|
if (/<script\b(?![^>]*\bsrc=)[^>]*>/i.test(html)) throw new Error("Inline scripts are blocked in local app previews");
|
|
144
171
|
if (/(?:src|href)\s*=\s*["']https?:\/\//i.test(html)) throw new Error("Remote scripts, styles, and frames are blocked in Phase 1 local apps");
|
|
@@ -156,6 +183,80 @@ var LocalAppService = class {
|
|
|
156
183
|
this.options = options;
|
|
157
184
|
this.store = store;
|
|
158
185
|
}
|
|
186
|
+
recoveryRoot() {
|
|
187
|
+
return join(resolveStateDir(), "local-apps", "pending-releases");
|
|
188
|
+
}
|
|
189
|
+
recoveryMarker(id) {
|
|
190
|
+
if (!/^[a-zA-Z0-9-]+$/.test(id)) throw new Error("Invalid local app id");
|
|
191
|
+
return join(this.recoveryRoot(), id);
|
|
192
|
+
}
|
|
193
|
+
/** Reconcile interrupted mutations before any extension code or request can run. */
|
|
194
|
+
async recoverPendingReleases() {
|
|
195
|
+
return withLocalAppReleaseLock(resolveExtensionsDir(), () => this.recoverReleases());
|
|
196
|
+
}
|
|
197
|
+
async recoverReleases() {
|
|
198
|
+
if (!existsSync(this.recoveryRoot())) return;
|
|
199
|
+
for (const id of readdirSync(this.recoveryRoot())) {
|
|
200
|
+
const marker = this.recoveryMarker(id);
|
|
201
|
+
const app = this.store.get(id);
|
|
202
|
+
if (!app) throw new Error(`Pending local app recovery has no database record: ${id}`);
|
|
203
|
+
if (!/^[a-zA-Z0-9-]+$/.test(app.extensionId)) throw new Error("Invalid local app extension id");
|
|
204
|
+
const extensionsDir = resolveExtensionsDir();
|
|
205
|
+
mkdirSync(extensionsDir, { recursive: true });
|
|
206
|
+
const target = join(extensionsDir, app.extensionId);
|
|
207
|
+
if (app.installationState === "installed") {
|
|
208
|
+
const release = app.activeReleaseId ? this.store.getRelease(id, app.activeReleaseId) : null;
|
|
209
|
+
if (!release || resolve(release.artifactPath) !== resolve(this.releaseRoot(id), `v${release.version}`)) throw new Error(`Local app recovery release is unavailable: ${id}`);
|
|
210
|
+
validateLocalAppPackage(release.artifactPath, app.extensionId);
|
|
211
|
+
if (hashDirectory(release.artifactPath) !== release.sourceHash) throw new Error(`Local app recovery integrity check failed: ${id}`);
|
|
212
|
+
const staging = mkdtempSync(join(extensionsDir, ".local-app-recover-"));
|
|
213
|
+
try {
|
|
214
|
+
const replacement = join(staging, app.extensionId);
|
|
215
|
+
cpSync(release.artifactPath, replacement, {
|
|
216
|
+
recursive: true,
|
|
217
|
+
filter: shouldCopyReleasePath
|
|
218
|
+
});
|
|
219
|
+
rmSync(target, {
|
|
220
|
+
recursive: true,
|
|
221
|
+
force: true
|
|
222
|
+
});
|
|
223
|
+
renameSync(replacement, target);
|
|
224
|
+
} finally {
|
|
225
|
+
cleanupReleaseStaging(staging);
|
|
226
|
+
}
|
|
227
|
+
} else rmSync(target, {
|
|
228
|
+
recursive: true,
|
|
229
|
+
force: true
|
|
230
|
+
});
|
|
231
|
+
const config = this.options.getConfig();
|
|
232
|
+
const saved = await this.options.saveConfig(app.installationState === "installed" ? setExtensionActivation(config, app.extensionId, app.enabled) : removeExtensionActivation(config, app.extensionId));
|
|
233
|
+
if (!saved.saved) throw new Error(saved.error ?? `Local app recovery config save failed: ${id}`);
|
|
234
|
+
const orphan = join(this.releaseRoot(id), `v${app.draftVersion}`);
|
|
235
|
+
if (!this.store.listReleases(id).some((release) => resolve(release.artifactPath) === resolve(orphan)) && existsSync(orphan)) renameSync(orphan, join(mkdtempSync(join(this.releaseRoot(id), ".interrupted-")), "package"));
|
|
236
|
+
this.refreshExtensions("local-app-recovery");
|
|
237
|
+
rmSync(marker);
|
|
238
|
+
log.info({
|
|
239
|
+
appId: id,
|
|
240
|
+
releaseId: app.activeReleaseId
|
|
241
|
+
}, "Interrupted local app release recovered");
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
async mutateRelease(id, action) {
|
|
245
|
+
return withLocalAppReleaseLock(resolveExtensionsDir(), async () => {
|
|
246
|
+
await this.recoverReleases();
|
|
247
|
+
if (!this.store.get(id)) throw new Error("Local app not found");
|
|
248
|
+
const marker = this.recoveryMarker(id);
|
|
249
|
+
mkdirSync(this.recoveryRoot(), { recursive: true });
|
|
250
|
+
writeFileSync(marker, "", {
|
|
251
|
+
flag: "wx",
|
|
252
|
+
mode: 384,
|
|
253
|
+
flush: true
|
|
254
|
+
});
|
|
255
|
+
const result = await action();
|
|
256
|
+
rmSync(marker);
|
|
257
|
+
return result;
|
|
258
|
+
});
|
|
259
|
+
}
|
|
159
260
|
list() {
|
|
160
261
|
return this.store.list();
|
|
161
262
|
}
|
|
@@ -177,8 +278,11 @@ var LocalAppService = class {
|
|
|
177
278
|
const discovered = !release ? this.options.getExtensionLoader()?.discoverExtensions().find((extension) => extension.id === extensionId) : null;
|
|
178
279
|
if (!release && !discovered) throw new Error("Extension UI manifest not found");
|
|
179
280
|
const manifestJson = release?.manifestJson ?? JSON.stringify(discovered.manifest);
|
|
180
|
-
const manifestDigest = createHash("sha256").update(
|
|
181
|
-
|
|
281
|
+
const manifestDigest = createHash("sha256").update(release ? JSON.stringify({
|
|
282
|
+
manifestJson,
|
|
283
|
+
sourceHash: release.sourceHash
|
|
284
|
+
}) : manifestJson).digest("hex");
|
|
285
|
+
const permissions = release ? permissionsFromManifestJson(manifestJson).toSorted() : [...discovered.manifest.ui?.permissions ?? [], ...extensionCapabilityPermissions(discovered.manifest.ui?.capabilities ?? [])].toSorted();
|
|
182
286
|
const grant = this.store.getUiGrant(extensionId, manifestDigest);
|
|
183
287
|
const granted = Boolean(grant && JSON.stringify(grant.permissions.toSorted()) === JSON.stringify(permissions));
|
|
184
288
|
return {
|
|
@@ -190,9 +294,26 @@ var LocalAppService = class {
|
|
|
190
294
|
grantedAt: granted ? grant?.grantedAt : void 0
|
|
191
295
|
};
|
|
192
296
|
}
|
|
193
|
-
|
|
297
|
+
getCapabilityAccess(extensionId, expectedManifestDigest) {
|
|
298
|
+
const app = this.store.findByExtensionId(extensionId);
|
|
299
|
+
const config = extensionConfigRecord(this.options.getConfig());
|
|
300
|
+
if (app && existsSync(this.recoveryMarker(app.id))) throw new CapabilityError("FORBIDDEN", "Local app release mutation or recovery is pending");
|
|
301
|
+
if (!app || !app.enabled || app.installationState !== "installed" || !app.activeReleaseId || stringIds(config.disabled).includes(extensionId) || !stringIds(config.enabled).includes(extensionId)) throw new CapabilityError("FORBIDDEN", "Local app is not enabled and installed");
|
|
302
|
+
const grant = this.getUiGrant(extensionId);
|
|
303
|
+
if (!grant.granted) throw new CapabilityError("FORBIDDEN", "Local app permissions have not been granted");
|
|
304
|
+
if (grant.manifestDigest !== expectedManifestDigest) throw new CapabilityError("CONTRACT_CHANGED", "Local app release changed");
|
|
305
|
+
const release = this.store.getRelease(app.id, app.activeReleaseId);
|
|
306
|
+
if (!release) throw new CapabilityError("FORBIDDEN", "Local app release is unavailable");
|
|
307
|
+
const manifest = JSON.parse(release.manifestJson);
|
|
308
|
+
return {
|
|
309
|
+
releaseId: release.id,
|
|
310
|
+
bindings: ExtensionCapabilityBindingsSchema.parse(manifest.ui?.capabilities ?? [])
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
grantUiPermissions(extensionId, expectedManifestDigest) {
|
|
194
314
|
const current = this.getUiGrant(extensionId);
|
|
195
315
|
if (!current.manifestDigest) throw new Error("Extension UI manifest not found");
|
|
316
|
+
if (current.manifestDigest !== expectedManifestDigest) throw new Error("Extension release changed; review permissions again");
|
|
196
317
|
return this.store.saveUiGrant({
|
|
197
318
|
extensionId,
|
|
198
319
|
appId: current.appId,
|
|
@@ -306,10 +427,10 @@ var LocalAppService = class {
|
|
|
306
427
|
const app = this.store.get(id);
|
|
307
428
|
if (!app) throw new Error("Local app not found");
|
|
308
429
|
const validation = this.validate(id);
|
|
309
|
-
if (validation.status !== "healthy" || !validation.sourceHash) throw new
|
|
310
|
-
if (input.sourceHash !== validation.sourceHash) throw new
|
|
311
|
-
if (input.status !== "passed" && input.status !== "failed") throw new
|
|
312
|
-
if (!Number.isInteger(input.interactiveCount) || input.interactiveCount < 0 || input.interactiveCount > 1e4) throw new
|
|
430
|
+
if (validation.status !== "healthy" || !validation.sourceHash) throw new LocalAppAcceptanceValidationError("The current draft must pass static validation before acceptance can be recorded");
|
|
431
|
+
if (input.sourceHash !== validation.sourceHash) throw new LocalAppRevisionConflictError("Acceptance result is stale because the draft changed");
|
|
432
|
+
if (input.status !== "passed" && input.status !== "failed") throw new LocalAppAcceptanceValidationError("Invalid acceptance status");
|
|
433
|
+
if (!Number.isInteger(input.interactiveCount) || input.interactiveCount < 0 || input.interactiveCount > 1e4) throw new LocalAppAcceptanceValidationError("Invalid acceptance interactive count");
|
|
313
434
|
const requiredIds = new Set([
|
|
314
435
|
"document",
|
|
315
436
|
"content",
|
|
@@ -322,23 +443,33 @@ var LocalAppService = class {
|
|
|
322
443
|
"failed",
|
|
323
444
|
"skipped"
|
|
324
445
|
]);
|
|
325
|
-
if (!Array.isArray(input.checks) || input.checks.length < requiredIds.size || input.checks.length > allowedIds.size) throw new
|
|
446
|
+
if (!Array.isArray(input.checks) || input.checks.length < requiredIds.size || input.checks.length > allowedIds.size) throw new LocalAppAcceptanceValidationError("Automatic acceptance must include every required check");
|
|
326
447
|
const seenIds = /* @__PURE__ */ new Set();
|
|
327
448
|
for (const check of input.checks) {
|
|
328
|
-
if (!allowedIds.has(check.id) || seenIds.has(check.id)) throw new
|
|
329
|
-
if (!allowedStatuses.has(check.status)) throw new
|
|
330
|
-
if (typeof check.message !== "string" || !check.message.trim() || check.message.length > 500) throw new
|
|
449
|
+
if (!allowedIds.has(check.id) || seenIds.has(check.id)) throw new LocalAppAcceptanceValidationError("Invalid automatic acceptance check");
|
|
450
|
+
if (!allowedStatuses.has(check.status)) throw new LocalAppAcceptanceValidationError("Invalid automatic acceptance check status");
|
|
451
|
+
if (typeof check.message !== "string" || !check.message.trim() || check.message.length > 500) throw new LocalAppAcceptanceValidationError("Invalid automatic acceptance check message");
|
|
331
452
|
seenIds.add(check.id);
|
|
332
453
|
}
|
|
333
|
-
if ([...requiredIds].some((checkId) => !seenIds.has(checkId))) throw new
|
|
334
|
-
if ((input.checks.some((check) => check.status === "failed") ? "failed" : "passed") !== input.status) throw new
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
454
|
+
if ([...requiredIds].some((checkId) => !seenIds.has(checkId))) throw new LocalAppAcceptanceValidationError("Automatic acceptance must include every required check");
|
|
455
|
+
if ((input.checks.some((check) => check.status === "failed") ? "failed" : "passed") !== input.status) throw new LocalAppAcceptanceValidationError("Acceptance status does not match its checks");
|
|
456
|
+
if (input.status === "passed" && input.checks.some((check) => requiredIds.has(check.id) && check.status !== "passed" && !(check.id === "interaction" && check.status === "skipped" && input.interactiveCount === 0))) throw new LocalAppAcceptanceValidationError("Passed acceptance cannot skip required checks");
|
|
457
|
+
return runSqliteWriteTransaction((db) => {
|
|
458
|
+
const run = this.store.recordAcceptance(app.id, input);
|
|
459
|
+
db.prepare(`INSERT INTO domain_outbox
|
|
460
|
+
(event_id, event_type, subject_kind, subject_id, correlation_id, payload_json, created_at, operation_id)
|
|
461
|
+
VALUES (?, 'local_app.acceptance_recorded', 'local_app', ?, ?, ?, ?, ?)`).run(randomUUID(), app.id, run.id, JSON.stringify({
|
|
462
|
+
appId: app.id,
|
|
463
|
+
sourceHash: run.sourceHash,
|
|
464
|
+
status: run.status,
|
|
465
|
+
acceptanceId: run.id
|
|
466
|
+
}), run.createdAt, currentOperationId() ?? null);
|
|
467
|
+
afterSqliteCommit(() => this.flushAcceptanceEvents());
|
|
468
|
+
return run;
|
|
340
469
|
});
|
|
341
|
-
|
|
470
|
+
}
|
|
471
|
+
flushAcceptanceEvents() {
|
|
472
|
+
new DomainOutboxDispatcher((event) => this.options.emit(event.type, event.payload)).drain(100, "local_app");
|
|
342
473
|
}
|
|
343
474
|
releaseRoot(appId) {
|
|
344
475
|
return join(resolveStateDir(), "local-apps", "releases", appId);
|
|
@@ -369,18 +500,21 @@ var LocalAppService = class {
|
|
|
369
500
|
const staged = join(transactionRoot, input.app.extensionId);
|
|
370
501
|
const backup = join(transactionRoot, "previous");
|
|
371
502
|
const target = join(extensionsDir, input.app.extensionId);
|
|
372
|
-
cpSync(input.artifactPath, staged, {
|
|
373
|
-
recursive: true,
|
|
374
|
-
filter: shouldCopyReleasePath
|
|
375
|
-
});
|
|
376
503
|
let hadPrevious = false;
|
|
504
|
+
let targetInstalled = false;
|
|
505
|
+
let canCleanup = false;
|
|
377
506
|
let configSaved = false;
|
|
378
507
|
try {
|
|
508
|
+
cpSync(input.artifactPath, staged, {
|
|
509
|
+
recursive: true,
|
|
510
|
+
filter: shouldCopyReleasePath
|
|
511
|
+
});
|
|
379
512
|
if (existsSync(target)) {
|
|
380
513
|
renameSync(target, backup);
|
|
381
514
|
hadPrevious = true;
|
|
382
515
|
}
|
|
383
516
|
renameSync(staged, target);
|
|
517
|
+
targetInstalled = true;
|
|
384
518
|
validateLocalAppPackage(target, input.app.extensionId);
|
|
385
519
|
const saved = await this.options.saveConfig(input.nextConfig);
|
|
386
520
|
if (!saved.saved) throw new Error(saved.error ?? "Failed to update local app activation");
|
|
@@ -388,12 +522,14 @@ var LocalAppService = class {
|
|
|
388
522
|
this.refreshExtensions(input.source);
|
|
389
523
|
this.assertInstalledRuntime(input.app, target);
|
|
390
524
|
input.commit();
|
|
525
|
+
canCleanup = true;
|
|
391
526
|
} catch (error) {
|
|
392
|
-
if (existsSync(target)) rmSync(target, {
|
|
527
|
+
if (targetInstalled && existsSync(target)) rmSync(target, {
|
|
393
528
|
recursive: true,
|
|
394
529
|
force: true
|
|
395
530
|
});
|
|
396
531
|
if (hadPrevious && existsSync(backup)) renameSync(backup, target);
|
|
532
|
+
canCleanup = true;
|
|
397
533
|
if (configSaved) {
|
|
398
534
|
const restored = await this.options.saveConfig(previousConfig);
|
|
399
535
|
if (!restored.saved) log.error({
|
|
@@ -404,13 +540,13 @@ var LocalAppService = class {
|
|
|
404
540
|
this.refreshExtensions(`${input.source}-rollback`);
|
|
405
541
|
throw error;
|
|
406
542
|
} finally {
|
|
407
|
-
|
|
408
|
-
recursive: true,
|
|
409
|
-
force: true
|
|
410
|
-
});
|
|
543
|
+
if (canCleanup) cleanupReleaseStaging(transactionRoot);
|
|
411
544
|
}
|
|
412
545
|
}
|
|
413
546
|
async install(id) {
|
|
547
|
+
return this.mutateRelease(id, () => this.installRelease(id));
|
|
548
|
+
}
|
|
549
|
+
async installRelease(id) {
|
|
414
550
|
const app = this.store.get(id);
|
|
415
551
|
if (!app) throw new Error("Local app not found");
|
|
416
552
|
const releaseRoot = this.releaseRoot(app.id);
|
|
@@ -452,10 +588,7 @@ var LocalAppService = class {
|
|
|
452
588
|
});
|
|
453
589
|
throw error;
|
|
454
590
|
} finally {
|
|
455
|
-
|
|
456
|
-
recursive: true,
|
|
457
|
-
force: true
|
|
458
|
-
});
|
|
591
|
+
cleanupReleaseStaging(stagingRoot);
|
|
459
592
|
}
|
|
460
593
|
const next = this.get(id);
|
|
461
594
|
this.options.emit("local_app.installed", {
|
|
@@ -471,11 +604,15 @@ var LocalAppService = class {
|
|
|
471
604
|
return next;
|
|
472
605
|
}
|
|
473
606
|
async rollback(id, releaseId) {
|
|
607
|
+
return this.mutateRelease(id, () => this.rollbackRelease(id, releaseId));
|
|
608
|
+
}
|
|
609
|
+
async rollbackRelease(id, releaseId) {
|
|
474
610
|
const app = this.store.get(id);
|
|
475
611
|
if (!app) throw new Error("Local app not found");
|
|
476
612
|
const release = this.store.getRelease(id, releaseId);
|
|
477
613
|
if (!release || !release.artifactPath || !existsSync(release.artifactPath)) throw new Error("Local app release artifact is unavailable");
|
|
478
614
|
validateLocalAppPackage(release.artifactPath, app.extensionId);
|
|
615
|
+
if (hashDirectory(release.artifactPath) !== release.sourceHash) throw new Error("Release artifact integrity check failed; rollback was not applied");
|
|
479
616
|
await this.activateArtifact({
|
|
480
617
|
app,
|
|
481
618
|
artifactPath: release.artifactPath,
|
|
@@ -493,6 +630,9 @@ var LocalAppService = class {
|
|
|
493
630
|
return this.get(id);
|
|
494
631
|
}
|
|
495
632
|
async setEnabled(id, enabled) {
|
|
633
|
+
return this.mutateRelease(id, () => this.setReleaseEnabled(id, enabled));
|
|
634
|
+
}
|
|
635
|
+
async setReleaseEnabled(id, enabled) {
|
|
496
636
|
const app = this.store.get(id);
|
|
497
637
|
if (!app) throw new Error("Local app not found");
|
|
498
638
|
if (app.installationState !== "installed") throw new Error("Install the local app before changing its enabled state");
|
|
@@ -510,6 +650,9 @@ var LocalAppService = class {
|
|
|
510
650
|
return this.get(id);
|
|
511
651
|
}
|
|
512
652
|
async uninstall(id) {
|
|
653
|
+
return this.mutateRelease(id, () => this.uninstallRelease(id));
|
|
654
|
+
}
|
|
655
|
+
async uninstallRelease(id) {
|
|
513
656
|
const app = this.store.get(id);
|
|
514
657
|
if (!app) throw new Error("Local app not found");
|
|
515
658
|
const extensionsDir = resolveExtensionsDir();
|
|
@@ -519,6 +662,7 @@ var LocalAppService = class {
|
|
|
519
662
|
const backup = join(transactionRoot, app.extensionId);
|
|
520
663
|
const previousConfig = this.options.getConfig();
|
|
521
664
|
let moved = false;
|
|
665
|
+
let canCleanup = false;
|
|
522
666
|
let configSaved = false;
|
|
523
667
|
try {
|
|
524
668
|
if (existsSync(target)) {
|
|
@@ -529,17 +673,16 @@ var LocalAppService = class {
|
|
|
529
673
|
if (!saved.saved) throw new Error(saved.error ?? "Failed to uninstall local app");
|
|
530
674
|
configSaved = true;
|
|
531
675
|
this.store.markUninstalled(id);
|
|
532
|
-
|
|
676
|
+
canCleanup = true;
|
|
533
677
|
} catch (error) {
|
|
534
678
|
if (moved && existsSync(backup)) renameSync(backup, target);
|
|
679
|
+
canCleanup = true;
|
|
535
680
|
if (configSaved) await this.options.saveConfig(previousConfig);
|
|
536
681
|
throw error;
|
|
537
682
|
} finally {
|
|
538
|
-
|
|
539
|
-
recursive: true,
|
|
540
|
-
force: true
|
|
541
|
-
});
|
|
683
|
+
if (canCleanup) cleanupReleaseStaging(transactionRoot);
|
|
542
684
|
}
|
|
685
|
+
this.refreshExtensions("local-app-uninstall");
|
|
543
686
|
this.options.emit("local_app.uninstalled", {
|
|
544
687
|
appId: id,
|
|
545
688
|
projectId: app.projectId
|
|
@@ -548,4 +691,4 @@ var LocalAppService = class {
|
|
|
548
691
|
}
|
|
549
692
|
};
|
|
550
693
|
//#endregion
|
|
551
|
-
export { LocalAppService };
|
|
694
|
+
export { LocalAppAcceptanceValidationError, LocalAppRevisionConflictError, LocalAppService };
|
|
@@ -132,8 +132,6 @@ var LocalAppStore = class {
|
|
|
132
132
|
}
|
|
133
133
|
recordAcceptance(appId, input) {
|
|
134
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
135
|
const row = {
|
|
138
136
|
run_id: randomUUID(),
|
|
139
137
|
app_id: appId,
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
2
|
+
import { type GatewayHttpClient } from './gateway-http-client.js';
|
|
3
|
+
/** An opt-in HTTP proxy, not a new principal or an approval authority. */
|
|
4
|
+
export declare function createCapabilityMcpServer(client: Pick<GatewayHttpClient, 'getJson' | 'postJson'>, capabilityIds: readonly string[]): Server;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { PACKAGE_VERSION, init_package_version } from "../package-version.js";
|
|
2
|
+
import { CapabilityCallSchema } from "../../packages/gateway-contract/src/capabilities.js";
|
|
3
|
+
import { init_src } from "../../packages/gateway-contract/src/index.js";
|
|
4
|
+
import { GatewayHttpError } from "./gateway-http-client.js";
|
|
5
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
6
|
+
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
7
|
+
//#region src/mcp/capability-server.ts
|
|
8
|
+
init_src();
|
|
9
|
+
init_package_version();
|
|
10
|
+
const BASE = "/api/capabilities/operations";
|
|
11
|
+
/** An opt-in HTTP proxy, not a new principal or an approval authority. */
|
|
12
|
+
function createCapabilityMcpServer(client, capabilityIds) {
|
|
13
|
+
if (!capabilityIds.length || capabilityIds.some((id) => !/^xopc\.[a-z0-9_.]+$/.test(id))) throw new Error("At least one explicit xopc capability ID is required (wildcards are not supported)");
|
|
14
|
+
const allowed = new Set(capabilityIds);
|
|
15
|
+
const server = new Server({
|
|
16
|
+
name: "xopc-capabilities",
|
|
17
|
+
version: PACKAGE_VERSION
|
|
18
|
+
}, { capabilities: { tools: {} } });
|
|
19
|
+
const catalog = async () => {
|
|
20
|
+
return (await client.getJson(BASE)).capabilities.filter((item) => allowed.has(item.id) && item.surfaces.includes("http"));
|
|
21
|
+
};
|
|
22
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: (await catalog()).map((item) => ({
|
|
23
|
+
name: item.id,
|
|
24
|
+
description: `${item.description}\nGateway HTTP proxy. Use the discovered contract unchanged. Writes require a stable idempotencyKey; never retry an uncertain write with a new key.`,
|
|
25
|
+
inputSchema: {
|
|
26
|
+
type: "object",
|
|
27
|
+
additionalProperties: false,
|
|
28
|
+
required: [
|
|
29
|
+
"majorVersion",
|
|
30
|
+
"descriptorDigest",
|
|
31
|
+
"input",
|
|
32
|
+
...item.effect === "read" ? [] : ["idempotencyKey"]
|
|
33
|
+
],
|
|
34
|
+
properties: {
|
|
35
|
+
majorVersion: {
|
|
36
|
+
type: "integer",
|
|
37
|
+
const: item.majorVersion
|
|
38
|
+
},
|
|
39
|
+
descriptorDigest: {
|
|
40
|
+
type: "string",
|
|
41
|
+
const: item.descriptorDigest
|
|
42
|
+
},
|
|
43
|
+
input: item.inputSchema,
|
|
44
|
+
idempotencyKey: {
|
|
45
|
+
type: "string",
|
|
46
|
+
minLength: 1,
|
|
47
|
+
maxLength: 200
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
annotations: {
|
|
52
|
+
readOnlyHint: item.effect === "read",
|
|
53
|
+
destructiveHint: item.effect === "destructive",
|
|
54
|
+
openWorldHint: true
|
|
55
|
+
}
|
|
56
|
+
})) }));
|
|
57
|
+
server.setRequestHandler(CallToolRequestSchema, async ({ params }) => {
|
|
58
|
+
const fail = (code, operationId) => ({
|
|
59
|
+
isError: true,
|
|
60
|
+
content: [{
|
|
61
|
+
type: "text",
|
|
62
|
+
text: JSON.stringify({
|
|
63
|
+
code,
|
|
64
|
+
...operationId ? { operationId } : {}
|
|
65
|
+
})
|
|
66
|
+
}]
|
|
67
|
+
});
|
|
68
|
+
if (!allowed.has(params.name)) return fail("FORBIDDEN");
|
|
69
|
+
const parsed = CapabilityCallSchema.safeParse(params.arguments);
|
|
70
|
+
if (!parsed.success) return fail("INVALID_INPUT");
|
|
71
|
+
let dispatched = false;
|
|
72
|
+
let write = false;
|
|
73
|
+
try {
|
|
74
|
+
const descriptor = (await catalog()).find((item) => item.id === params.name);
|
|
75
|
+
if (!descriptor) return fail("FORBIDDEN");
|
|
76
|
+
if (parsed.data.majorVersion !== descriptor.majorVersion || parsed.data.descriptorDigest !== descriptor.descriptorDigest) return fail("CONTRACT_CHANGED");
|
|
77
|
+
write = descriptor.effect !== "read";
|
|
78
|
+
if (write && !parsed.data.idempotencyKey) return fail("INVALID_INPUT");
|
|
79
|
+
dispatched = true;
|
|
80
|
+
const result = await client.postJson(`${BASE}/${encodeURIComponent(params.name)}/invocations`, parsed.data);
|
|
81
|
+
return {
|
|
82
|
+
content: [{
|
|
83
|
+
type: "text",
|
|
84
|
+
text: JSON.stringify(result)
|
|
85
|
+
}],
|
|
86
|
+
structuredContent: result
|
|
87
|
+
};
|
|
88
|
+
} catch (error) {
|
|
89
|
+
if (error instanceof GatewayHttpError) return fail(error.code ?? (error.status === 401 || error.status === 403 ? "FORBIDDEN" : dispatched && write ? "OUTCOME_UNKNOWN" : "UNAVAILABLE"), error.operationId);
|
|
90
|
+
return fail(dispatched && write ? "OUTCOME_UNKNOWN" : "UNAVAILABLE");
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
return server;
|
|
94
|
+
}
|
|
95
|
+
//#endregion
|
|
96
|
+
export { createCapabilityMcpServer };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { createLogger } from "../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../utils/logger.js";
|
|
3
3
|
import { init_loader, loadConfig } from "../config/loader.js";
|
|
4
|
+
import { createGatewayHttpClientFromConfig, resolveGatewayHttpBaseUrl } from "./gateway-http-client.js";
|
|
4
5
|
import { RealtimeClient } from "../../packages/realtime-client/src/index.js";
|
|
5
6
|
import { toConversation } from "./channel-shared.js";
|
|
6
|
-
import { createGatewayHttpClientFromConfig, resolveGatewayHttpBaseUrl } from "./gateway-http-client.js";
|
|
7
7
|
import { createRequire } from "node:module";
|
|
8
8
|
import crypto from "node:crypto";
|
|
9
9
|
//#region src/mcp/channel-bridge.ts
|
|
@@ -1,5 +1,12 @@
|
|
|
1
|
+
import { type CapabilityErrorCode } from '@xopcai/gateway-contract';
|
|
1
2
|
import type { Config } from '../config/schema.js';
|
|
2
3
|
import { type GatewayCredential } from '../gateway/credential.js';
|
|
4
|
+
export declare class GatewayHttpError extends Error {
|
|
5
|
+
readonly status: number;
|
|
6
|
+
readonly code?: CapabilityErrorCode;
|
|
7
|
+
readonly operationId?: string;
|
|
8
|
+
constructor(status: number, code?: CapabilityErrorCode, operationId?: string);
|
|
9
|
+
}
|
|
3
10
|
export type GatewayHttpClientOptions = {
|
|
4
11
|
baseUrl: string;
|
|
5
12
|
credential?: GatewayCredential;
|