@xopcai/xopc 0.0.141 → 0.0.143
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/activity-center-store-jITiX2vJ.js +1 -0
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BRTCpm3t.js → agent-avatar-dicebear-DiME9u_P.js} +1 -1
- package/dist/gateway/static/root/assets/agents-DzBXhZXO.js +2 -0
- package/dist/gateway/static/root/assets/{app-management-settings-panel-DaMMZBAT.js → app-management-settings-panel-Cuo7SbUP.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-BXHThPyM.js → appearance-settings-DUfdNQqk.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-CKuKK5AU.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-izB-4N4L.js → archive-plugin-B-Qk6cGr.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-CJihXa5y.js → attachment-load-Di6EEbQX.js} +1 -1
- package/dist/gateway/static/root/assets/automation-suggestion-card-DGxvRxtO.js +1 -0
- package/dist/gateway/static/root/assets/automations-page-D-FF_WKV.js +4 -0
- package/dist/gateway/static/root/assets/{binary-plugins-D3VUeG8s.js → binary-plugins-ZaOZDH2I.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-KnA0sLI3.js → block-editor-BTFhjWfg.js} +36 -36
- package/dist/gateway/static/root/assets/browser-settings-page-BvKLdEQt.js +8 -0
- package/dist/gateway/static/root/assets/{capability-presets-api-D8rRNhc6.js → capability-presets-api-BU-pVZiZ.js} +1 -1
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-DgyeEwzh.js +2 -0
- package/dist/gateway/static/root/assets/{channel-recipient-api-BWgqwC5h.js → channel-recipient-api-DuulnhIj.js} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-BbVsdD_I.js +1 -0
- package/dist/gateway/static/root/assets/channels-status-swr-B5lVrUsN.js +1 -0
- package/dist/gateway/static/root/assets/check-BODqo66o.js +1 -0
- package/dist/gateway/static/root/assets/chunk-QUQL4437-DXsxWP7r.js +4 -0
- package/dist/gateway/static/root/assets/circle-alert-RzVebuX2.js +1 -0
- package/dist/gateway/static/root/assets/connectors-page-B8QqVy3I.js +2 -0
- package/dist/gateway/static/root/assets/{desktop-pet-CzdqX001.js → desktop-pet---yzVxVR.js} +1 -1
- package/dist/gateway/static/root/assets/desktop-pet-settings-Dc3gqBJE.js +1 -0
- package/dist/gateway/static/root/assets/{directory-picker-path-field-PzlO5tSM.js → directory-picker-path-field-DCmOGLtK.js} +1 -1
- package/dist/gateway/static/root/assets/dreaming-settings-BgT5KZVe.js +3 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-DcW8Ie3r.js → extension-debug-page-ByaKTTq4.js} +1 -1
- package/dist/gateway/static/root/assets/extension-page-BmRzHAZr.js +1 -0
- package/dist/gateway/static/root/assets/extension-settings-page-JUtwIhbF.js +1 -0
- package/dist/gateway/static/root/assets/{fetch-06q5eCMA.js → fetch-8QNN25Sh.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-4VXUJtLz.js → gateway-config-api-CxicF50_.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-settings-Bz2I_EO5.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-2f7_vsv7.js → gateway-startup-retry-5YBnS9Fj.js} +1 -1
- package/dist/gateway/static/root/assets/goal-create-dialog-VcoyuZGN.js +1 -0
- package/dist/gateway/static/root/assets/goal-detail-page-Cilkap2G.js +4 -0
- package/dist/gateway/static/root/assets/{goals-config-api-BpuQTufF.js → goals-config-api-CwcHRdC0.js} +1 -1
- package/dist/gateway/static/root/assets/goals-page-C6eoni4z.js +2 -0
- package/dist/gateway/static/root/assets/goals-settings-o4i-qAOS.js +1 -0
- package/dist/gateway/static/root/assets/heartbeat-settings-DQQkETX8.js +1 -0
- package/dist/gateway/static/root/assets/index-BKRqeRHm.js +257 -0
- package/dist/gateway/static/root/assets/index-CphxClbs.css +1 -0
- package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-LT6qB-ua.js +1 -0
- package/dist/gateway/static/root/assets/logs-page-Dli2e3fS.js +7 -0
- package/dist/gateway/static/root/assets/{markdown-split-zS4KLNAf.js → markdown-split-Dw-yE2-y.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-_BgNJ9_7.js → media-plugins-D9NNNUgE.js} +1 -1
- package/dist/gateway/static/root/assets/messages-CzKxM6I4.js +5 -0
- package/dist/gateway/static/root/assets/models-hub-panel-DVn2Q1Ik.js +2 -0
- package/dist/gateway/static/root/assets/notes-page-CRgbJGgk.js +1 -0
- package/dist/gateway/static/root/assets/notes-workbench-BxZRHLWx.js +2 -0
- package/dist/gateway/static/root/assets/{page-tabs-B7sGQkgU.js → page-tabs-D4hkWVt_.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-D1ri4s_O.js → preview-open-alternatives-CIckv0uy.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-Doz53xLn.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-DoMtcRLg.js +1 -0
- package/dist/gateway/static/root/assets/remote-access-hub-BeHVEgrm.js +1 -0
- package/dist/gateway/static/root/assets/{save-bar-controls-BClrOinh.js → save-bar-controls-B0b42kB2.js} +1 -1
- package/dist/gateway/static/root/assets/{schedule-field-CL7YTwLV.js → schedule-field-BtjEkczK.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-ww4PiIje.js → schema-form-Bf0bk3i6.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-Bk4bQsBe.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-DdFyaRMm.js +1 -0
- package/dist/gateway/static/root/assets/{settings-collapsible-section-D9gEEVm2.js → settings-collapsible-section-BTKTdTNX.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-form-section-DGeEoBkb.js → settings-form-section-DL4P0sAj.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-loading-skeleton-BXUeMR37.js → settings-loading-skeleton-BV6KFNj4.js} +1 -1
- package/dist/gateway/static/root/assets/settings-page-B_4DsX5W.js +1 -0
- package/dist/gateway/static/root/assets/{settings-page-layout-CEepfbCa.js → settings-page-layout-CyGlrInB.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-DJ1_MLgX.js +1 -0
- package/dist/gateway/static/root/assets/share-preview-page-BQBV7YrV.js +2 -0
- package/dist/gateway/static/root/assets/shares-settings-0VuFLBeU.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-DO87Ckeo.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-D3VdtxAn.js +2 -0
- package/dist/gateway/static/root/assets/{system-settings-panel-W6MBJXrr.js → system-settings-panel-D85fBBuI.js} +1 -1
- package/dist/gateway/static/root/assets/{typed-models-lib-BkODXN7T.js → typed-models-lib-CwEuYrHX.js} +1 -1
- package/dist/gateway/static/root/assets/{use-channel-catalog-CTbwLZXc.js → use-channel-catalog-COXIfXcl.js} +1 -1
- package/dist/gateway/static/root/assets/user-context-page-m9JVQ73F.js +1 -0
- package/dist/gateway/static/root/assets/user-profile-fields-editor-DtQiuY7E.js +1 -0
- package/dist/gateway/static/root/assets/user-profile-settings-panel-CWM0fEpb.js +1 -0
- package/dist/gateway/static/root/assets/{utils-ZxrKHxyb.js → utils--BO6xT3u.js} +1 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-LoT3wgZ9.js +1 -0
- package/dist/gateway/static/root/assets/with-selector-aYPsXwdl.js +1 -0
- package/dist/gateway/static/root/assets/work-item-detail-page-DSTMz_mO.js +1 -0
- package/dist/gateway/static/root/assets/workflow-run-setup-panel-B35lJzvm.js +3 -0
- package/dist/gateway/static/root/assets/workflows-page-BfSm9oR8.js +11 -0
- package/dist/gateway/static/root/assets/workflows-page-DLioOiRN.css +1 -0
- package/dist/gateway/static/root/connector-icons/README.md +11 -0
- package/dist/gateway/static/root/connector-icons/airtable.svg +13 -0
- package/dist/gateway/static/root/connector-icons/asana.svg +15 -0
- package/dist/gateway/static/root/connector-icons/brave-search.svg +1 -0
- package/dist/gateway/static/root/connector-icons/clickup.svg +19 -0
- package/dist/gateway/static/root/connector-icons/composio.svg +266 -0
- package/dist/gateway/static/root/connector-icons/discord.svg +15 -0
- package/dist/gateway/static/root/connector-icons/dropbox.svg +152 -0
- package/dist/gateway/static/root/connector-icons/excel.svg +56 -0
- package/dist/gateway/static/root/connector-icons/fetch.svg +6 -0
- package/dist/gateway/static/root/connector-icons/figma.svg +178 -0
- package/dist/gateway/static/root/connector-icons/filesystem.svg +6 -0
- package/dist/gateway/static/root/connector-icons/github.svg +10 -0
- package/dist/gateway/static/root/connector-icons/gmail.svg +3 -0
- package/dist/gateway/static/root/connector-icons/google-calendar.svg +3 -0
- package/dist/gateway/static/root/connector-icons/google-docs.svg +25 -0
- package/dist/gateway/static/root/connector-icons/google-drive.svg +25 -0
- package/dist/gateway/static/root/connector-icons/google-sheets.svg +1 -0
- package/dist/gateway/static/root/connector-icons/hubspot.svg +142 -0
- package/dist/gateway/static/root/connector-icons/jira.svg +15 -0
- package/dist/gateway/static/root/connector-icons/linear.svg +5 -0
- package/dist/gateway/static/root/connector-icons/memory.svg +5 -0
- package/dist/gateway/static/root/connector-icons/microsoft-teams.svg +33 -0
- package/dist/gateway/static/root/connector-icons/notion.svg +5 -0
- package/dist/gateway/static/root/connector-icons/one-drive.svg +13 -0
- package/dist/gateway/static/root/connector-icons/outlook.svg +76 -0
- package/dist/gateway/static/root/connector-icons/playwright.svg +9 -0
- package/dist/gateway/static/root/connector-icons/salesforce.svg +17 -0
- package/dist/gateway/static/root/connector-icons/sequential-thinking.svg +8 -0
- package/dist/gateway/static/root/connector-icons/shopify.svg +5 -0
- package/dist/gateway/static/root/connector-icons/slack.svg +9 -0
- package/dist/gateway/static/root/connector-icons/spotify.svg +43 -0
- package/dist/gateway/static/root/connector-icons/stripe.svg +11 -0
- package/dist/gateway/static/root/connector-icons/telegram.svg +130 -0
- package/dist/gateway/static/root/connector-icons/time.svg +6 -0
- package/dist/gateway/static/root/connector-icons/todoist.svg +277 -0
- package/dist/gateway/static/root/connector-icons/trello.svg +19 -0
- package/dist/gateway/static/root/connector-icons/twitter.svg +128 -0
- package/dist/gateway/static/root/connector-icons/whatsapp.svg +61 -0
- package/dist/gateway/static/root/connector-icons/youtube.svg +11 -0
- package/dist/gateway/static/root/index.html +9 -6
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.d.ts +2 -0
- package/dist/src/agent/agent-manager.js +8 -0
- package/dist/src/agent/agent-manager.js.map +1 -1
- package/dist/src/agent/background-review/prompts.d.ts +1 -1
- package/dist/src/agent/background-review/prompts.js +3 -2
- package/dist/src/agent/background-review/prompts.js.map +1 -1
- package/dist/src/agent/embedded/session-runner.js +5 -5
- package/dist/src/agent/embedded/session-runner.js.map +1 -1
- package/dist/src/agent/embedded/session-tool-result-guard.js +1 -1
- package/dist/src/agent/embedded/xopc-auth-storage.d.ts +4 -3
- package/dist/src/agent/embedded/xopc-auth-storage.js +6 -6
- package/dist/src/agent/embedded/xopc-auth-storage.js.map +1 -1
- package/dist/src/agent/embedded/xopc-stream-bridge.js +1 -0
- package/dist/src/agent/embedded/xopc-stream-bridge.js.map +1 -1
- package/dist/src/agent/embedded/xopc-tools-bridge.d.ts +9 -0
- package/dist/src/agent/embedded/xopc-tools-bridge.js +71 -3
- package/dist/src/agent/embedded/xopc-tools-bridge.js.map +1 -1
- package/dist/src/agent/goals/checklist-judge.js +3 -3
- package/dist/src/agent/goals/checklist-judge.js.map +1 -1
- package/dist/src/agent/goals/judge.js +2 -2
- package/dist/src/agent/goals/judge.js.map +1 -1
- package/dist/src/agent/goals/post-turn.js +5 -4
- package/dist/src/agent/goals/post-turn.js.map +1 -1
- package/dist/src/agent/image/understanding/pi-ai-provider.js +2 -2
- package/dist/src/agent/image/understanding/pi-ai-provider.js.map +1 -1
- package/dist/src/agent/mcp/mcp-transport.js +4 -1
- package/dist/src/agent/mcp/mcp-transport.js.map +1 -1
- package/dist/src/agent/memory/compaction.js +2 -2
- package/dist/src/agent/memory/compaction.js.map +1 -1
- package/dist/src/agent/memory/context/planner.d.ts +1 -0
- package/dist/src/agent/memory/context/planner.js +60 -14
- package/dist/src/agent/memory/context/planner.js.map +1 -1
- package/dist/src/agent/memory/context/types.d.ts +3 -1
- package/dist/src/agent/memory/lifecycle.d.ts +11 -0
- package/dist/src/agent/memory/lifecycle.js +50 -0
- package/dist/src/agent/memory/lifecycle.js.map +1 -0
- package/dist/src/agent/memory/source-origin.d.ts +3 -0
- package/dist/src/agent/memory/source-origin.js +19 -0
- package/dist/src/agent/memory/source-origin.js.map +1 -0
- package/dist/src/agent/memory/understanding/service.js +5 -0
- package/dist/src/agent/memory/understanding/service.js.map +1 -1
- package/dist/src/agent/memory/user-context-coordinator.js +7 -2
- package/dist/src/agent/memory/user-context-coordinator.js.map +1 -1
- package/dist/src/agent/prompt/sections/behavior.d.ts +2 -0
- package/dist/src/agent/prompt/sections/behavior.js +30 -1
- package/dist/src/agent/prompt/sections/behavior.js.map +1 -1
- package/dist/src/agent/prompt/sections/tooling.js +1 -1
- package/dist/src/agent/prompt/sections/tooling.js.map +1 -1
- package/dist/src/agent/prompt/service-prompt-builder.js +8 -1
- package/dist/src/agent/prompt/service-prompt-builder.js.map +1 -1
- package/dist/src/agent/prompt/system-prompt.d.ts +2 -0
- package/dist/src/agent/prompt/system-prompt.js +6 -3
- package/dist/src/agent/prompt/system-prompt.js.map +1 -1
- package/dist/src/agent/service/btw-query.d.ts +4 -0
- package/dist/src/agent/service/btw-query.js +94 -13
- package/dist/src/agent/service/btw-query.js.map +1 -1
- package/dist/src/agent/service/process-direct-streaming.js +22 -0
- package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
- package/dist/src/agent/service.d.ts +2 -0
- package/dist/src/agent/service.js +9 -3
- package/dist/src/agent/service.js.map +1 -1
- package/dist/src/agent/session/session-inspector.js +9 -1
- package/dist/src/agent/session/session-inspector.js.map +1 -1
- package/dist/src/agent/starter-agents.js +1 -1
- package/dist/src/agent/starter-agents.js.map +1 -1
- package/dist/src/agent/tool-manuals/xopc-use.d.ts +1 -1
- package/dist/src/agent/tool-manuals/xopc-use.js +1 -1
- package/dist/src/agent/tool-manuals/xopc-use.js.map +1 -1
- package/dist/src/agent/tools/composio-tool.d.ts +18 -5
- package/dist/src/agent/tools/composio-tool.js +252 -35
- package/dist/src/agent/tools/composio-tool.js.map +1 -1
- package/dist/src/agent/tools/factory.js +7 -3
- package/dist/src/agent/tools/factory.js.map +1 -1
- package/dist/src/agent/tools/index.d.ts +1 -1
- package/dist/src/agent/tools/index.js +2 -2
- package/dist/src/agent/tools/session-search-tool.js +2 -2
- package/dist/src/agent/tools/session-search-tool.js.map +1 -1
- package/dist/src/agent/tools/web-extract.js +2 -2
- package/dist/src/agent/tools/web-extract.js.map +1 -1
- package/dist/src/agent/tools/workflow-tool.d.ts +0 -1
- package/dist/src/agent/tools/workflow-tool.js +3 -16
- package/dist/src/agent/tools/workflow-tool.js.map +1 -1
- package/dist/src/agent/workflow/builtins/index.d.ts +2 -28
- package/dist/src/agent/workflow/builtins/index.js +226 -41
- package/dist/src/agent/workflow/builtins/index.js.map +1 -1
- package/dist/src/agent/workflow/catalog.d.ts +32 -34
- package/dist/src/agent/workflow/catalog.js +158 -154
- package/dist/src/agent/workflow/catalog.js.map +1 -1
- package/dist/src/agent/workflow/index.d.ts +4 -6
- package/dist/src/agent/workflow/index.js +2 -5
- package/dist/src/agent/workflow/snapshot.d.ts +2 -2
- package/dist/src/agent/workflow/snapshot.js +2 -2
- package/dist/src/agent/workflow/snapshot.js.map +1 -1
- package/dist/src/agent/workflow/structured-output-tool.d.ts +2 -2
- package/dist/src/agent/workflow/structured-output-tool.js +2 -2
- package/dist/src/agent/workflow/structured-output-tool.js.map +1 -1
- package/dist/src/agent/workflow/subagent-runner.js +1 -1
- package/dist/src/agent/workflow/types.d.ts +31 -26
- package/dist/src/agent-manifest/index.d.ts +1 -0
- package/dist/src/agent-manifest/index.js +3 -1
- package/dist/src/agent-manifest/index.js.map +1 -1
- package/dist/src/agent-manifest/preset-chain.d.ts +10 -0
- package/dist/src/agent-manifest/preset-chain.js +32 -0
- package/dist/src/agent-manifest/preset-chain.js.map +1 -0
- package/dist/src/agent-manifest/resolver.js +3 -10
- package/dist/src/agent-manifest/resolver.js.map +1 -1
- package/dist/src/agent-manifest/schema.d.ts +4 -4
- package/dist/src/ai-assist/text-assist.d.ts +2 -1
- package/dist/src/ai-assist/text-assist.js +10 -23
- package/dist/src/ai-assist/text-assist.js.map +1 -1
- package/dist/src/auth/credentials.js +5 -2
- package/dist/src/auth/credentials.js.map +1 -1
- package/dist/src/auth/oauth/github-copilot.d.ts +3 -4
- package/dist/src/auth/oauth/github-copilot.js +66 -2
- package/dist/src/auth/oauth/github-copilot.js.map +1 -0
- package/dist/src/auth/oauth/index.js +2 -2
- package/dist/src/automations/api/routes.js +13 -1
- package/dist/src/automations/api/routes.js.map +1 -1
- package/dist/src/automations/domain/validation.d.ts +14 -14
- package/dist/src/automations/draft/automation-draft-service.js +3 -3
- package/dist/src/automations/draft/automation-draft-service.js.map +1 -1
- package/dist/src/automations/draft/automation-draft-validator.d.ts +3 -3
- package/dist/src/browser/providers/browser-ext-install.d.ts +11 -1
- package/dist/src/browser/providers/browser-ext-install.js +39 -14
- package/dist/src/browser/providers/browser-ext-install.js.map +1 -1
- package/dist/src/capabilities/store-connector.d.ts +0 -1
- package/dist/src/capabilities/store-connector.js +3 -5
- package/dist/src/capabilities/store-connector.js.map +1 -1
- package/dist/src/chat-commands/builtins/review.js +84 -68
- package/dist/src/chat-commands/builtins/review.js.map +1 -1
- package/dist/src/chat-commands/builtins/workflow.js +9 -54
- package/dist/src/chat-commands/builtins/workflow.js.map +1 -1
- package/dist/src/chat-commands/types.d.ts +4 -0
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/extension-create.js +2 -2
- package/dist/src/cli/commands/extension-create.js.map +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +42 -36
- package/dist/src/cli/commands/extension-marketplace.js.map +1 -1
- package/dist/src/cli/commands/extension-pack.d.ts +6 -0
- package/dist/src/cli/commands/extension-pack.js +3 -2
- package/dist/src/cli/commands/extension-pack.js.map +1 -1
- package/dist/src/commands/agents.config.d.ts +1 -0
- package/dist/src/commands/agents.config.js +1 -0
- package/dist/src/commands/agents.config.js.map +1 -1
- package/dist/src/config/schema.d.ts +6 -6
- package/dist/src/config/schema.js +6 -22
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/config/web-patch.d.ts +1 -1
- package/dist/src/connectors/approval.d.ts +2 -0
- package/dist/src/connectors/approval.js +33 -0
- package/dist/src/connectors/approval.js.map +1 -0
- package/dist/src/connectors/auth-provider-registry.d.ts +9 -0
- package/dist/src/connectors/auth-provider-registry.js +17 -0
- package/dist/src/connectors/auth-provider-registry.js.map +1 -0
- package/dist/src/connectors/builtin-catalog.js +55 -116
- package/dist/src/connectors/builtin-catalog.js.map +1 -1
- package/dist/src/connectors/catalog.js +7 -2
- package/dist/src/connectors/catalog.js.map +1 -1
- package/dist/src/connectors/composio-catalog.d.ts +19 -0
- package/dist/src/connectors/composio-catalog.js +237 -0
- package/dist/src/connectors/composio-catalog.js.map +1 -0
- package/dist/src/connectors/composio-logo.d.ts +1 -0
- package/dist/src/connectors/composio-logo.js +51 -0
- package/dist/src/connectors/composio-logo.js.map +1 -0
- package/dist/src/connectors/composio-sessions.d.ts +116 -0
- package/dist/src/connectors/composio-sessions.js +296 -0
- package/dist/src/connectors/composio-sessions.js.map +1 -0
- package/dist/src/connectors/composio-triggers.d.ts +17 -0
- package/dist/src/connectors/composio-triggers.js +48 -5
- package/dist/src/connectors/composio-triggers.js.map +1 -1
- package/dist/src/connectors/composio.d.ts +31 -2
- package/dist/src/connectors/composio.js +374 -151
- package/dist/src/connectors/composio.js.map +1 -1
- package/dist/src/connectors/connector-memory-sync.d.ts +15 -0
- package/dist/src/connectors/connector-memory-sync.js +90 -0
- package/dist/src/connectors/connector-memory-sync.js.map +1 -0
- package/dist/src/connectors/install.js +35 -92
- package/dist/src/connectors/install.js.map +1 -1
- package/dist/src/connectors/instances.js +6 -2
- package/dist/src/connectors/instances.js.map +1 -1
- package/dist/src/connectors/integration-strategy.d.ts +3 -0
- package/dist/src/connectors/integration-strategy.js +29 -0
- package/dist/src/connectors/integration-strategy.js.map +1 -0
- package/dist/src/connectors/policy.d.ts +13 -0
- package/dist/src/connectors/policy.js +48 -0
- package/dist/src/connectors/policy.js.map +1 -0
- package/dist/src/connectors/providers.js +1 -1
- package/dist/src/connectors/runtime-adapter-registry.d.ts +25 -0
- package/dist/src/connectors/runtime-adapter-registry.js +154 -0
- package/dist/src/connectors/runtime-adapter-registry.js.map +1 -0
- package/dist/src/connectors/types.d.ts +113 -4
- package/dist/src/connectors/workflow-preflight.d.ts +20 -0
- package/dist/src/connectors/workflow-preflight.js +70 -0
- package/dist/src/connectors/workflow-preflight.js.map +1 -0
- package/dist/src/extensions/install-transaction.d.ts +16 -0
- package/dist/src/extensions/install-transaction.js +76 -0
- package/dist/src/extensions/install-transaction.js.map +1 -0
- package/dist/src/extensions/install.d.ts +2 -0
- package/dist/src/extensions/install.js +23 -1
- package/dist/src/extensions/install.js.map +1 -1
- package/dist/src/gateway/agents-admin.d.ts +2 -0
- package/dist/src/gateway/agents-admin.js +7 -0
- package/dist/src/gateway/agents-admin.js.map +1 -1
- package/dist/src/gateway/capability-presets-admin.d.ts +11 -0
- package/dist/src/gateway/capability-presets-admin.js +11 -4
- package/dist/src/gateway/capability-presets-admin.js.map +1 -1
- package/dist/src/gateway/chat-stream/mapper.js +17 -0
- package/dist/src/gateway/chat-stream/mapper.js.map +1 -1
- package/dist/src/gateway/chat-stream/protocol.d.ts +18 -1
- package/dist/src/gateway/hono/lib/config-payload.d.ts +3 -3
- package/dist/src/gateway/hono/routes/agents.js +3 -0
- package/dist/src/gateway/hono/routes/agents.js.map +1 -1
- package/dist/src/gateway/hono/routes/capability-presets.js +19 -1
- package/dist/src/gateway/hono/routes/capability-presets.js.map +1 -1
- package/dist/src/gateway/hono/routes/connectors.js +188 -25
- package/dist/src/gateway/hono/routes/connectors.js.map +1 -1
- package/dist/src/gateway/hono/routes/goals.js +22 -3
- package/dist/src/gateway/hono/routes/goals.js.map +1 -1
- package/dist/src/gateway/hono/routes/home.d.ts +60 -1
- package/dist/src/gateway/hono/routes/home.js +244 -18
- package/dist/src/gateway/hono/routes/home.js.map +1 -1
- package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
- package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
- package/dist/src/gateway/hono/routes/memory.js +14 -1
- package/dist/src/gateway/hono/routes/memory.js.map +1 -1
- package/dist/src/gateway/hono/routes/models.js +1 -0
- package/dist/src/gateway/hono/routes/models.js.map +1 -1
- package/dist/src/gateway/hono/routes/projects.js +103 -2
- package/dist/src/gateway/hono/routes/projects.js.map +1 -1
- package/dist/src/gateway/hono/routes/public-gateway.js +93 -0
- package/dist/src/gateway/hono/routes/public-gateway.js.map +1 -1
- package/dist/src/gateway/hono/routes/voice.js +2 -2
- package/dist/src/gateway/hono/routes/voice.js.map +1 -1
- package/dist/src/gateway/hono/routes/workflows.js +137 -22
- package/dist/src/gateway/hono/routes/workflows.js.map +1 -1
- package/dist/src/gateway/hono/routes/you.d.ts +23 -0
- package/dist/src/gateway/hono/routes/you.js +538 -0
- package/dist/src/gateway/hono/routes/you.js.map +1 -0
- package/dist/src/gateway/hono/sse.d.ts +2 -1
- package/dist/src/gateway/hono/sse.js +2 -1
- package/dist/src/gateway/hono/sse.js.map +1 -1
- package/dist/src/gateway/service/marketplace-service.d.ts +13 -1
- package/dist/src/gateway/service/marketplace-service.js +96 -40
- package/dist/src/gateway/service/marketplace-service.js.map +1 -1
- package/dist/src/gateway/service.d.ts +2 -0
- package/dist/src/gateway/service.js +7 -1
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/goals/goal-contract-draft.js +2 -2
- package/dist/src/goals/goal-contract-draft.js.map +1 -1
- package/dist/src/goals/goal-evidence-review.js +2 -2
- package/dist/src/goals/goal-evidence-review.js.map +1 -1
- package/dist/src/goals/goal-service.d.ts +7 -5
- package/dist/src/goals/goal-service.js +25 -13
- package/dist/src/goals/goal-service.js.map +1 -1
- package/dist/src/goals/goal-store.js +46 -7
- package/dist/src/goals/goal-store.js.map +1 -1
- package/dist/src/goals/types.d.ts +24 -0
- package/dist/src/notes/service.js +2 -2
- package/dist/src/notes/service.js.map +1 -1
- package/dist/src/providers/constants.d.ts +2 -0
- package/dist/src/providers/constants.js +11 -0
- package/dist/src/providers/constants.js.map +1 -0
- package/dist/src/providers/extension-stream-bridge.js +1 -0
- package/dist/src/providers/extension-stream-bridge.js.map +1 -1
- package/dist/src/providers/index.d.ts +3 -3
- package/dist/src/providers/index.js +5 -4
- package/dist/src/providers/index.js.map +1 -1
- package/dist/src/providers/model-call.d.ts +17 -0
- package/dist/src/providers/model-call.js +60 -0
- package/dist/src/providers/model-call.js.map +1 -0
- package/dist/src/session/session-title.js +2 -2
- package/dist/src/session/session-title.js.map +1 -1
- package/dist/src/storage/sqlite/connector-repository.d.ts +49 -0
- package/dist/src/storage/sqlite/connector-repository.js +385 -0
- package/dist/src/storage/sqlite/connector-repository.js.map +1 -0
- package/dist/src/storage/sqlite/index.d.ts +3 -0
- package/dist/src/storage/sqlite/index.js +4 -1
- package/dist/src/storage/sqlite/migrations/030_connectors.sql +94 -0
- package/dist/src/storage/sqlite/migrations/031_connector_approvals.sql +24 -0
- package/dist/src/storage/sqlite/migrations/032_connector_webhook_deliveries.sql +15 -0
- package/dist/src/storage/sqlite/migrations/033_user_trust_policies.sql +6 -0
- package/dist/src/storage/sqlite/migrations/034_allow_global_auto_trust.sql +14 -0
- package/dist/src/storage/sqlite/migrations/035_user_profile_prompt_state.sql +7 -0
- package/dist/src/storage/sqlite/migrations/036_goal_outcome_metric.sql +12 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
- package/dist/src/storage/sqlite/migrations/runner.js +3 -3
- package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
- package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/storage/sqlite/user-profile-setup-repository.d.ts +3 -0
- package/dist/src/storage/sqlite/user-profile-setup-repository.js +34 -0
- package/dist/src/storage/sqlite/user-profile-setup-repository.js.map +1 -0
- package/dist/src/storage/sqlite/user-trust-repository.d.ts +3 -0
- package/dist/src/storage/sqlite/user-trust-repository.js +34 -0
- package/dist/src/storage/sqlite/user-trust-repository.js.map +1 -0
- package/dist/src/tui/components/assistant-message.js +15 -0
- package/dist/src/tui/components/assistant-message.js.map +1 -1
- package/dist/src/tui/tui-agent-events.js +85 -1
- package/dist/src/tui/tui-agent-events.js.map +1 -1
- package/dist/src/tui/tui-command-formatters.js +7 -7
- package/dist/src/tui/tui-command-formatters.js.map +1 -1
- package/dist/src/tui/tui-commands.js +1 -1
- package/dist/src/tui/tui-startup-resources.js +1 -1
- package/dist/src/user-context/import.d.ts +12 -0
- package/dist/src/user-context/import.js +48 -0
- package/dist/src/user-context/import.js.map +1 -0
- package/dist/src/user-context/profile.d.ts +37 -0
- package/dist/src/user-context/profile.js +165 -0
- package/dist/src/user-context/profile.js.map +1 -0
- package/dist/src/user-context/projection.d.ts +54 -0
- package/dist/src/user-context/projection.js +121 -0
- package/dist/src/user-context/projection.js.map +1 -0
- package/dist/src/user-context/source-recommendations.d.ts +13 -0
- package/dist/src/user-context/source-recommendations.js +86 -0
- package/dist/src/user-context/source-recommendations.js.map +1 -0
- package/dist/src/user-context/trust-policy.d.ts +11 -0
- package/dist/src/user-context/trust-policy.js +31 -0
- package/dist/src/user-context/trust-policy.js.map +1 -0
- package/dist/src/voice/tts/summarize.js +2 -2
- package/dist/src/voice/tts/summarize.js.map +1 -1
- package/dist/src/workflows/authoring/index.d.ts +1 -0
- package/dist/src/workflows/authoring/index.js +2 -0
- package/dist/src/workflows/authoring/workflow-draft-store.d.ts +33 -0
- package/dist/src/workflows/authoring/workflow-draft-store.js +74 -0
- package/dist/src/workflows/authoring/workflow-draft-store.js.map +1 -0
- package/dist/src/workflows/domain/definition-utils.d.ts +6 -4
- package/dist/src/workflows/domain/definition-utils.js +28 -26
- package/dist/src/workflows/domain/definition-utils.js.map +1 -1
- package/dist/src/workflows/domain/definition.d.ts +79 -6
- package/dist/src/workflows/domain/event.d.ts +18 -2
- package/dist/src/workflows/domain/index.js +3 -3
- package/dist/src/workflows/domain/run.d.ts +16 -2
- package/dist/src/workflows/domain/run.js.map +1 -1
- package/dist/src/workflows/domain/validation.d.ts +9 -5
- package/dist/src/workflows/domain/validation.js +183 -40
- package/dist/src/workflows/domain/validation.js.map +1 -1
- package/dist/src/workflows/draft/workflow-draft-prompt.d.ts +2 -3
- package/dist/src/workflows/draft/workflow-draft-prompt.js +31 -73
- package/dist/src/workflows/draft/workflow-draft-prompt.js.map +1 -1
- package/dist/src/workflows/draft/workflow-draft-service.js +6 -10
- package/dist/src/workflows/draft/workflow-draft-service.js.map +1 -1
- package/dist/src/workflows/draft/workflow-draft-validator.js +29 -37
- package/dist/src/workflows/draft/workflow-draft-validator.js.map +1 -1
- package/dist/src/workflows/draft/workflow-draft.types.d.ts +4 -4
- package/dist/src/workflows/engine/projector.js +43 -1
- package/dist/src/workflows/engine/projector.js.map +1 -1
- package/dist/src/workflows/engine/workflow-engine.d.ts +2 -3
- package/dist/src/workflows/engine/workflow-engine.js +24 -4
- package/dist/src/workflows/engine/workflow-engine.js.map +1 -1
- package/dist/src/workflows/index.js +4 -7
- package/dist/src/workflows/registry/catalog-workflow-definition-registry.js +1 -9
- package/dist/src/workflows/registry/catalog-workflow-definition-registry.js.map +1 -1
- package/dist/src/workflows/runtime/graph-workflow-runtime.d.ts +10 -0
- package/dist/src/workflows/runtime/graph-workflow-runtime.js +295 -0
- package/dist/src/workflows/runtime/graph-workflow-runtime.js.map +1 -0
- package/dist/src/workflows/runtime/index.d.ts +1 -2
- package/dist/src/workflows/runtime/index.js +2 -5
- package/dist/src/workflows/runtime/workflow-runtime-port.d.ts +5 -8
- package/dist/src/workflows/service/workflow-run-service.js +15 -1
- package/dist/src/workflows/service/workflow-run-service.js.map +1 -1
- package/dist/src/workflows/service/workflow-run-service.types.d.ts +2 -1
- package/package.json +8 -7
- package/dist/gateway/static/root/assets/agents-Bd863Akz.js +0 -2
- package/dist/gateway/static/root/assets/apps-page-B4omjLxa.js +0 -1
- package/dist/gateway/static/root/assets/automation-suggestion-card-fgtj5Gek.js +0 -1
- package/dist/gateway/static/root/assets/automations-page-Dz2mgjIR.js +0 -4
- package/dist/gateway/static/root/assets/browser-settings-page-DZZz5v_i.js +0 -8
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-sCHojZr4.js +0 -1
- package/dist/gateway/static/root/assets/channels-settings-UyVSnf9s.js +0 -1
- package/dist/gateway/static/root/assets/channels-status-swr-CB5FzcLf.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-BzhHiUO4.js +0 -2
- package/dist/gateway/static/root/assets/desktop-pet-settings-DqqUPC7G.js +0 -1
- package/dist/gateway/static/root/assets/dreaming-settings-BmL54kQq.js +0 -3
- package/dist/gateway/static/root/assets/extension-page-DT5cpace.js +0 -1
- package/dist/gateway/static/root/assets/extension-settings-page-CbMk4GhQ.js +0 -1
- package/dist/gateway/static/root/assets/gateway-settings-CdghmKHJ.js +0 -1
- package/dist/gateway/static/root/assets/goal-create-dialog-CAlsM9MP.js +0 -1
- package/dist/gateway/static/root/assets/goal-detail-page-CLPa4F2y.js +0 -4
- package/dist/gateway/static/root/assets/goals-page-B2VpdzfH.js +0 -2
- package/dist/gateway/static/root/assets/goals-settings-CW1NwxvV.js +0 -1
- package/dist/gateway/static/root/assets/heartbeat-settings-C86k5tff.js +0 -1
- package/dist/gateway/static/root/assets/index-B8s8Pq5U.css +0 -1
- package/dist/gateway/static/root/assets/index-ehajXmqL.js +0 -262
- package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-8xwKEhui.js +0 -1
- package/dist/gateway/static/root/assets/logs-page-C_BMONOO.js +0 -7
- package/dist/gateway/static/root/assets/messages-B-8CqAeX.js +0 -3
- package/dist/gateway/static/root/assets/models-hub-panel-Do_cwNjF.js +0 -2
- package/dist/gateway/static/root/assets/notes-page-5IdlPHaX.js +0 -1
- package/dist/gateway/static/root/assets/notes-workbench-0KsRZJIZ.js +0 -2
- package/dist/gateway/static/root/assets/project-detail-page-Dk2zB1gy.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-CJQntm2G.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-CHeZZg7O.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-9Hb_r0AG.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-PmzVFvAv.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-C5G2klUB.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-oQ8OLnw3.js +0 -1
- package/dist/gateway/static/root/assets/share-preview-page-CXtDHMSi.js +0 -2
- package/dist/gateway/static/root/assets/shares-settings-BlNoairj.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-BYV5x1KO.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-ClBcKQZP.js +0 -2
- package/dist/gateway/static/root/assets/toast-z0toXu32.js +0 -1
- package/dist/gateway/static/root/assets/user-profile-settings-panel-CeC308-E.js +0 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-BE57S-nS.js +0 -1
- package/dist/gateway/static/root/assets/work-item-detail-page-Di1ww5Aa.js +0 -1
- package/dist/gateway/static/root/assets/workflow-run-setup-panel-CzK84i-B.js +0 -3
- package/dist/gateway/static/root/assets/workflow-start-dialog-CtLTtNUB.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-CZFZdua9.js +0 -18
- package/dist/src/agent/workflow/builtins/audit-repo.d.ts +0 -13
- package/dist/src/agent/workflow/builtins/audit-repo.js +0 -183
- package/dist/src/agent/workflow/builtins/audit-repo.js.map +0 -1
- package/dist/src/agent/workflow/builtins/client-proposal.d.ts +0 -12
- package/dist/src/agent/workflow/builtins/client-proposal.js +0 -164
- package/dist/src/agent/workflow/builtins/client-proposal.js.map +0 -1
- package/dist/src/agent/workflow/builtins/competitor-scan.d.ts +0 -12
- package/dist/src/agent/workflow/builtins/competitor-scan.js +0 -164
- package/dist/src/agent/workflow/builtins/competitor-scan.js.map +0 -1
- package/dist/src/agent/workflow/builtins/content-draft.d.ts +0 -13
- package/dist/src/agent/workflow/builtins/content-draft.js +0 -159
- package/dist/src/agent/workflow/builtins/content-draft.js.map +0 -1
- package/dist/src/agent/workflow/builtins/content-repurpose.d.ts +0 -11
- package/dist/src/agent/workflow/builtins/content-repurpose.js +0 -146
- package/dist/src/agent/workflow/builtins/content-repurpose.js.map +0 -1
- package/dist/src/agent/workflow/builtins/debug-incident.d.ts +0 -13
- package/dist/src/agent/workflow/builtins/debug-incident.js +0 -177
- package/dist/src/agent/workflow/builtins/debug-incident.js.map +0 -1
- package/dist/src/agent/workflow/builtins/decision-compare.d.ts +0 -13
- package/dist/src/agent/workflow/builtins/decision-compare.js +0 -187
- package/dist/src/agent/workflow/builtins/decision-compare.js.map +0 -1
- package/dist/src/agent/workflow/builtins/implementation-plan.d.ts +0 -12
- package/dist/src/agent/workflow/builtins/implementation-plan.js +0 -185
- package/dist/src/agent/workflow/builtins/implementation-plan.js.map +0 -1
- package/dist/src/agent/workflow/builtins/inbox-triage.d.ts +0 -11
- package/dist/src/agent/workflow/builtins/inbox-triage.js +0 -158
- package/dist/src/agent/workflow/builtins/inbox-triage.js.map +0 -1
- package/dist/src/agent/workflow/builtins/meeting-prep.d.ts +0 -12
- package/dist/src/agent/workflow/builtins/meeting-prep.js +0 -152
- package/dist/src/agent/workflow/builtins/meeting-prep.js.map +0 -1
- package/dist/src/agent/workflow/builtins/multi-perspective-review.d.ts +0 -14
- package/dist/src/agent/workflow/builtins/multi-perspective-review.js +0 -171
- package/dist/src/agent/workflow/builtins/multi-perspective-review.js.map +0 -1
- package/dist/src/agent/workflow/builtins/offer-design.d.ts +0 -12
- package/dist/src/agent/workflow/builtins/offer-design.js +0 -170
- package/dist/src/agent/workflow/builtins/offer-design.js.map +0 -1
- package/dist/src/agent/workflow/builtins/pr-review.d.ts +0 -12
- package/dist/src/agent/workflow/builtins/pr-review.js +0 -178
- package/dist/src/agent/workflow/builtins/pr-review.js.map +0 -1
- package/dist/src/agent/workflow/builtins/release-check.d.ts +0 -11
- package/dist/src/agent/workflow/builtins/release-check.js +0 -174
- package/dist/src/agent/workflow/builtins/release-check.js.map +0 -1
- package/dist/src/agent/workflow/builtins/research.d.ts +0 -13
- package/dist/src/agent/workflow/builtins/research.js +0 -188
- package/dist/src/agent/workflow/builtins/research.js.map +0 -1
- package/dist/src/agent/workflow/builtins/weekly-review.d.ts +0 -12
- package/dist/src/agent/workflow/builtins/weekly-review.js +0 -139
- package/dist/src/agent/workflow/builtins/weekly-review.js.map +0 -1
- package/dist/src/agent/workflow/last-run-memory.d.ts +0 -42
- package/dist/src/agent/workflow/last-run-memory.js +0 -60
- package/dist/src/agent/workflow/last-run-memory.js.map +0 -1
- package/dist/src/agent/workflow/lint.d.ts +0 -38
- package/dist/src/agent/workflow/lint.js +0 -74
- package/dist/src/agent/workflow/lint.js.map +0 -1
- package/dist/src/agent/workflow/meta-locale.d.ts +0 -12
- package/dist/src/agent/workflow/meta-locale.js +0 -62
- package/dist/src/agent/workflow/meta-locale.js.map +0 -1
- package/dist/src/agent/workflow/parser.d.ts +0 -20
- package/dist/src/agent/workflow/parser.js +0 -152
- package/dist/src/agent/workflow/parser.js.map +0 -1
- package/dist/src/agent/workflow/runtime.d.ts +0 -34
- package/dist/src/agent/workflow/runtime.js +0 -402
- package/dist/src/agent/workflow/runtime.js.map +0 -1
- package/dist/src/connectors/oauth.d.ts +0 -22
- package/dist/src/connectors/oauth.js +0 -99
- package/dist/src/connectors/oauth.js.map +0 -1
- package/dist/src/workflows/runtime/script-runtime.d.ts +0 -3
- package/dist/src/workflows/runtime/script-runtime.js +0 -3
- package/dist/src/workflows/runtime/script-workflow-runtime.d.ts +0 -5
- package/dist/src/workflows/runtime/script-workflow-runtime.js +0 -15
- package/dist/src/workflows/runtime/script-workflow-runtime.js.map +0 -1
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { extractProfileAgentId } from "../../config/agent-profile.js";
|
|
2
2
|
import { createWorkflowCatalog } from "../../agent/workflow/catalog.js";
|
|
3
|
-
import { getLastWorkflowMemory } from "../../agent/workflow/last-run-memory.js";
|
|
4
3
|
import { commandRegistry } from "../registry.js";
|
|
5
4
|
import { bulletList, code, joinBlocks, section } from "../format-output.js";
|
|
6
5
|
//#region src/chat-commands/builtins/workflow.ts
|
|
@@ -19,13 +18,12 @@ import { bulletList, code, joinBlocks, section } from "../format-output.js";
|
|
|
19
18
|
* `/workflows` and `/workflow view` make discovery cheap, which is the missing
|
|
20
19
|
* piece.
|
|
21
20
|
*/
|
|
22
|
-
const VIEW_MAX_LINES = 200;
|
|
23
21
|
function formatEntryDetail(entry) {
|
|
24
22
|
const tags = entry.tags?.length ? `[${entry.tags.join(", ")}] ` : "";
|
|
25
23
|
const agents = entry.estimatedAgents ? ` (~${entry.estimatedAgents.min}–${entry.estimatedAgents.max} agents)` : "";
|
|
26
24
|
return `${tags}${entry.description}${agents}`;
|
|
27
25
|
}
|
|
28
|
-
function formatWorkflowListContent(entries
|
|
26
|
+
function formatWorkflowListContent(entries) {
|
|
29
27
|
const grouped = {
|
|
30
28
|
builtin: entries.filter((e) => e.source === "builtin"),
|
|
31
29
|
user: entries.filter((e) => e.source === "user")
|
|
@@ -42,8 +40,8 @@ function formatWorkflowListContent(entries, userDir) {
|
|
|
42
40
|
})))));
|
|
43
41
|
blocks.push(joinBlocks(section("How to run"), bulletList([
|
|
44
42
|
`Plain language: "run the ${exampleName} workflow"`,
|
|
45
|
-
`Inspect
|
|
46
|
-
|
|
43
|
+
`Inspect its visual structure: ${code(`/workflow view ${exampleName}`)}`,
|
|
44
|
+
"Create and edit workflows in the Workflow Studio."
|
|
47
45
|
])));
|
|
48
46
|
return joinBlocks(...blocks);
|
|
49
47
|
}
|
|
@@ -58,14 +56,13 @@ const workflowsCommand = {
|
|
|
58
56
|
"group"
|
|
59
57
|
],
|
|
60
58
|
handler: async (_ctx) => {
|
|
61
|
-
const
|
|
62
|
-
const entries = catalog.list();
|
|
59
|
+
const entries = createWorkflowCatalog().list();
|
|
63
60
|
if (entries.length === 0) return {
|
|
64
|
-
content:
|
|
61
|
+
content: "No workflows found. Create one in the Workflow Studio.",
|
|
65
62
|
success: true
|
|
66
63
|
};
|
|
67
64
|
return {
|
|
68
|
-
content: formatWorkflowListContent(entries
|
|
65
|
+
content: formatWorkflowListContent(entries),
|
|
69
66
|
success: true
|
|
70
67
|
};
|
|
71
68
|
}
|
|
@@ -96,11 +93,9 @@ const workflowCommand = {
|
|
|
96
93
|
const catalog = createWorkflowCatalog();
|
|
97
94
|
try {
|
|
98
95
|
const loaded = catalog.load(target);
|
|
99
|
-
const
|
|
100
|
-
const visible = lines.length > VIEW_MAX_LINES ? [...lines.slice(0, VIEW_MAX_LINES), `… (truncated; ${lines.length - VIEW_MAX_LINES} more lines)`] : lines;
|
|
101
|
-
const source = loaded.source === "user" ? loaded.path ?? "user" : "built-in";
|
|
96
|
+
const nodeSummary = loaded.graph.nodes.map((node) => `${node.title} (${node.kind})`).join(" → ");
|
|
102
97
|
return {
|
|
103
|
-
content: joinBlocks(`**${loaded.
|
|
98
|
+
content: joinBlocks(`**${loaded.title}** (${loaded.metadata.source}) — ${loaded.description}`, `Flow: ${nodeSummary}`, `Revision: ${loaded.revision}`),
|
|
104
99
|
success: true
|
|
105
100
|
};
|
|
106
101
|
} catch (e) {
|
|
@@ -111,33 +106,8 @@ const workflowCommand = {
|
|
|
111
106
|
}
|
|
112
107
|
}
|
|
113
108
|
if (subLower === "run" || subLower === "start") return runWorkflowFromCommand(ctx, target);
|
|
114
|
-
if (subLower === "save") {
|
|
115
|
-
if (!target) return {
|
|
116
|
-
content: `usage: ${code("/workflow save <name>")}`,
|
|
117
|
-
success: false
|
|
118
|
-
};
|
|
119
|
-
const last = getLastWorkflowMemory().get(ctx.sessionKey);
|
|
120
|
-
if (!last) return {
|
|
121
|
-
content: "No workflow has run successfully in this session yet. Run one first (e.g. ask \"run the audit_repo workflow\"), then `/workflow save <name>`.",
|
|
122
|
-
success: false
|
|
123
|
-
};
|
|
124
|
-
const catalog = createWorkflowCatalog();
|
|
125
|
-
try {
|
|
126
|
-
const script = last.metaName === target ? last.script : rewriteMetaName(last.script, target);
|
|
127
|
-
const { path } = catalog.save(target, script);
|
|
128
|
-
return {
|
|
129
|
-
content: joinBlocks(`✓ Saved workflow **${target}** → ${code(path)}`, bulletList([`Trigger with ${code(`/${target}`)} or "run the ${target} workflow"`, `Inspect with ${code(`/workflow view ${target}`)}`])),
|
|
130
|
-
success: true
|
|
131
|
-
};
|
|
132
|
-
} catch (e) {
|
|
133
|
-
return {
|
|
134
|
-
content: `error: ${e instanceof Error ? e.message : String(e)}`,
|
|
135
|
-
success: false
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
109
|
return {
|
|
140
|
-
content: joinBlocks(`Unknown subcommand "${sub}". Available: list, view ${code("<name>")},
|
|
110
|
+
content: joinBlocks(`Unknown subcommand "${sub}". Available: list, view ${code("<name>")}, run ${code("<name>")}.`, `Run directly with ${code("/workflow run <name> [--goal \"...\"] [--json '{...}']")}.`),
|
|
141
111
|
success: false
|
|
142
112
|
};
|
|
143
113
|
}
|
|
@@ -271,21 +241,6 @@ function tokenizeArgs(raw) {
|
|
|
271
241
|
}
|
|
272
242
|
return tokens;
|
|
273
243
|
}
|
|
274
|
-
/**
|
|
275
|
-
* Replace the `name` field inside the FIRST `export const meta = { ... }` literal.
|
|
276
|
-
*
|
|
277
|
-
* Why text-level (not AST re-emit)? The parser already accepted the script
|
|
278
|
-
* once (the runtime ran it), so the surrounding code is unchanged. A targeted
|
|
279
|
-
* regex on the `name: '...'` slot inside the first object literal keeps the
|
|
280
|
-
* user's formatting / comments / quote style intact, which an AST round-trip
|
|
281
|
-
* would smash. The match anchors to the first `name:` after `export const meta`
|
|
282
|
-
* and only touches that single value.
|
|
283
|
-
*/
|
|
284
|
-
function rewriteMetaName(script, newName) {
|
|
285
|
-
const re = /(export\s+const\s+meta\s*=\s*\{[^}]*?\bname\s*:\s*)(['"`])([^'"`]*)\2/;
|
|
286
|
-
if (!re.test(script)) throw new Error("could not locate meta.name in the recorded script to rewrite");
|
|
287
|
-
return script.replace(re, (_m, prefix, quote) => `${prefix}${quote}${newName}${quote}`);
|
|
288
|
-
}
|
|
289
244
|
function registerWorkflowCommands() {
|
|
290
245
|
commandRegistry.register(workflowsCommand);
|
|
291
246
|
commandRegistry.register(workflowCommand);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflow.js","names":[],"sources":["../../../../src/chat-commands/builtins/workflow.ts"],"sourcesContent":["/**\n * `/workflows` and `/workflow <subcommand>` — read-only commands for browsing\n * saved workflows.\n *\n * Why only read commands here? Slash command results are sent to the user; they\n * are NOT injected back into the agent's turn. Triggering a workflow run from\n * the slash layer would require a non-trivial cross-cutting \"inject this as the\n * next user message\" hook that doesn't exist yet. Instead, the workflow tool\n * understands `name`, and its description tells the model to prefer that route\n * whenever a user mentions a saved workflow by name. Plain text — \"run the\n * audit_repo workflow\" — works end-to-end.\n *\n * `/workflows` and `/workflow view` make discovery cheap, which is the missing\n * piece.\n */\n\nimport { commandRegistry } from '../registry.js';\nimport type { CommandContext, CommandDefinition } from '../types.js';\nimport { bulletList, code, joinBlocks, section } from '../format-output.js';\n\nimport { createWorkflowCatalog } from '../../agent/workflow/catalog.js';\nimport { getLastWorkflowMemory } from '../../agent/workflow/last-run-memory.js';\nimport type { CatalogEntry } from '../../agent/workflow/catalog.js';\nimport { extractProfileAgentId } from '../../config/agent-profile.js';\n\nconst VIEW_MAX_LINES = 200;\n\nfunction formatEntryDetail(entry: CatalogEntry): string {\n const tags = entry.tags?.length ? `[${entry.tags.join(', ')}] ` : '';\n const agents = entry.estimatedAgents\n ? ` (~${entry.estimatedAgents.min}–${entry.estimatedAgents.max} agents)`\n : '';\n return `${tags}${entry.description}${agents}`;\n}\n\nfunction formatWorkflowListContent(entries: CatalogEntry[], userDir: string): string {\n const grouped = {\n builtin: entries.filter((e) => e.source === 'builtin'),\n user: entries.filter((e) => e.source === 'user'),\n };\n const exampleName = entries[0]?.name ?? 'audit_repo';\n const blocks: string[] = [];\n\n if (grouped.user.length > 0) {\n blocks.push(\n joinBlocks(\n section('User workflows'),\n bulletList(grouped.user.map((e) => ({ label: e.name, detail: formatEntryDetail(e) }))),\n ),\n );\n }\n if (grouped.builtin.length > 0) {\n blocks.push(\n joinBlocks(\n section('Built-in workflows'),\n bulletList(grouped.builtin.map((e) => ({ label: e.name, detail: formatEntryDetail(e) }))),\n ),\n );\n }\n\n blocks.push(\n joinBlocks(\n section('How to run'),\n bulletList([\n `Plain language: \"run the ${exampleName} workflow\"`,\n `Inspect source: ${code(`/workflow view ${exampleName}`)}`,\n `Add your own: drop a ${code('.js')} at ${code(userDir)}`,\n ]),\n ),\n );\n\n return joinBlocks(...blocks);\n}\n\nconst workflowsCommand: CommandDefinition = {\n id: 'system.workflows',\n name: 'workflows',\n description: 'List saved workflows (built-in + ~/.xopc/workflows/)',\n category: 'system',\n scope: ['global', 'private', 'group'],\n handler: async (_ctx: CommandContext) => {\n const catalog = createWorkflowCatalog();\n const entries = catalog.list();\n if (entries.length === 0) {\n return {\n content: `No workflows found. Drop a script at ${code(`${catalog.userDir}/<name>.js`)} to add one.`,\n success: true,\n };\n }\n return { content: formatWorkflowListContent(entries, catalog.userDir), success: true };\n },\n};\n\nexport const workflowCommand: CommandDefinition = {\n id: 'system.workflow',\n name: 'workflow',\n description: 'Inspect or manage saved workflows. Subcommands: list, view <name>',\n category: 'system',\n scope: ['global', 'private', 'group'],\n acceptsArgs: true,\n examples: ['/workflow list', '/workflow view audit_repo'],\n handler: async (ctx: CommandContext, args: string) => {\n const trimmed = args.trim();\n if (!trimmed || trimmed.toLowerCase() === 'list') {\n return workflowsCommand.handler(ctx, '');\n }\n const [sub, ...rest] = trimmed.split(/\\s+/);\n const subLower = sub.toLowerCase();\n const target = rest.join(' ').trim();\n\n if (subLower === 'view' || subLower === 'show' || subLower === 'cat') {\n if (!target) {\n return { content: `usage: ${code('/workflow view <name>')}`, success: false };\n }\n const catalog = createWorkflowCatalog();\n try {\n const loaded = catalog.load(target);\n const lines = loaded.script.split('\\n');\n const visible =\n lines.length > VIEW_MAX_LINES\n ? [...lines.slice(0, VIEW_MAX_LINES), `… (truncated; ${lines.length - VIEW_MAX_LINES} more lines)`]\n : lines;\n const source = loaded.source === 'user' ? loaded.path ?? 'user' : 'built-in';\n return {\n content: joinBlocks(\n `**${loaded.name}** (${source}) — ${loaded.meta.description}`,\n '```js\\n' + visible.join('\\n') + '\\n```',\n ),\n success: true,\n };\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n return { content: `error: ${message}`, success: false };\n }\n }\n\n if (subLower === 'run' || subLower === 'start') {\n return runWorkflowFromCommand(ctx, target);\n }\n\n if (subLower === 'save') {\n if (!target) {\n return { content: `usage: ${code('/workflow save <name>')}`, success: false };\n }\n const last = getLastWorkflowMemory().get(ctx.sessionKey);\n if (!last) {\n return {\n content:\n 'No workflow has run successfully in this session yet. Run one first (e.g. ask \"run the audit_repo workflow\"), then `/workflow save <name>`.',\n success: false,\n };\n }\n const catalog = createWorkflowCatalog();\n try {\n // Allow the user to rename: if target differs from meta.name, rewrite it\n // before saving so the file is addressable as `target`.\n const script =\n last.metaName === target ? last.script : rewriteMetaName(last.script, target);\n const { path } = catalog.save(target, script);\n return {\n content: joinBlocks(\n `✓ Saved workflow **${target}** → ${code(path)}`,\n bulletList([\n `Trigger with ${code(`/${target}`)} or \"run the ${target} workflow\"`,\n `Inspect with ${code(`/workflow view ${target}`)}`,\n ]),\n ),\n success: true,\n };\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n return { content: `error: ${message}`, success: false };\n }\n }\n\n return {\n content: joinBlocks(\n `Unknown subcommand \"${sub}\". Available: list, view ${code('<name>')}, save ${code('<name>')}.`,\n `Run directly with ${code('/workflow run <name> [--goal \"...\"] [--json \\'{...}\\']')}.`,\n ),\n success: false,\n };\n },\n};\n\nasync function runWorkflowFromCommand(ctx: CommandContext, args: string) {\n if (!ctx.workflowRunApis) {\n return {\n content: 'Workflow runs are not available in this context.',\n success: false,\n };\n }\n\n let parsed: { name: string; goal?: string; input?: unknown };\n try {\n parsed = parseWorkflowRunArgs(args);\n } catch (err) {\n return {\n content: `error: ${err instanceof Error ? err.message : String(err)}`,\n success: false,\n };\n }\n if (!parsed.name) {\n return {\n content: `usage: ${code('/workflow run <name> [--goal \"...\"] [--json \\'{...}\\']')}`,\n success: false,\n };\n }\n\n const catalog = createWorkflowCatalog();\n try {\n catalog.load(parsed.name);\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n return { content: `error: ${message}`, success: false };\n }\n\n const agentId = extractProfileAgentId(ctx.sessionKey, ctx.config);\n const source =\n ctx.source === 'webui' || ctx.channelId === 'webchat'\n ? ({ kind: 'webui' as const, sessionKey: ctx.sessionKey })\n : ({ kind: 'chat' as const, sessionKey: ctx.sessionKey });\n const result = await ctx.workflowRunApis.startWorkflowRun({\n agentId,\n definitionId: parsed.name,\n goal: parsed.goal,\n input: parsed.input,\n parentSessionKey: ctx.sessionKey,\n source,\n });\n\n if (result.ok === false) {\n return {\n content: `error: ${result.message}`,\n success: false,\n metadata: {\n workflowRun: {\n ok: false,\n definitionId: parsed.name,\n code: result.code,\n message: result.message,\n },\n },\n };\n }\n\n const content = joinBlocks(\n `Started workflow **${parsed.name}**.`,\n bulletList([\n { label: 'runId', detail: code(result.runId) },\n { label: 'sessionKey', detail: code(result.sessionKey) },\n ]),\n );\n\n return {\n content,\n success: true,\n metadata: {\n workflowRun: {\n ok: true,\n definitionId: parsed.name,\n runId: result.runId,\n sessionKey: result.sessionKey,\n parentSessionKey: ctx.sessionKey,\n },\n },\n };\n}\n\nfunction parseWorkflowRunArgs(raw: string): { name: string; goal?: string; input?: unknown } {\n const tokens = tokenizeArgs(raw);\n const name = tokens.shift()?.trim() ?? '';\n let goal: string | undefined;\n let input: unknown;\n\n for (let i = 0; i < tokens.length; i += 1) {\n const token = tokens[i];\n if (token === '--goal' || token === '-g') {\n goal = tokens[++i]?.trim() || undefined;\n continue;\n }\n if (token.startsWith('--goal=')) {\n goal = token.slice('--goal='.length).trim() || undefined;\n continue;\n }\n if (token === '--json' || token === '--input') {\n const value = tokens[++i];\n input = parseJsonArg(value, token);\n continue;\n }\n if (token.startsWith('--json=')) {\n input = parseJsonArg(token.slice('--json='.length), '--json');\n continue;\n }\n if (token.startsWith('--input=')) {\n input = parseJsonArg(token.slice('--input='.length), '--input');\n continue;\n }\n if (!goal) {\n goal = [token, ...tokens.slice(i + 1)].join(' ').trim() || undefined;\n break;\n }\n }\n\n return { name, goal, input };\n}\n\nfunction parseJsonArg(value: string | undefined, flag: string): unknown {\n if (!value?.trim()) {\n throw new Error(`${flag} requires a JSON value`);\n }\n try {\n return JSON.parse(value);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(`${flag} is not valid JSON: ${message}`);\n }\n}\n\nfunction tokenizeArgs(raw: string): string[] {\n const tokens: string[] = [];\n const re = /\"([^\"\\\\]*(?:\\\\.[^\"\\\\]*)*)\"|'([^'\\\\]*(?:\\\\.[^'\\\\]*)*)'|(\\S+)/g;\n let match: RegExpExecArray | null;\n while ((match = re.exec(raw)) !== null) {\n const value = match[1] ?? match[2] ?? match[3] ?? '';\n tokens.push(value.replace(/\\\\([\"'\\\\])/g, '$1'));\n }\n return tokens;\n}\n\n/**\n * Replace the `name` field inside the FIRST `export const meta = { ... }` literal.\n *\n * Why text-level (not AST re-emit)? The parser already accepted the script\n * once (the runtime ran it), so the surrounding code is unchanged. A targeted\n * regex on the `name: '...'` slot inside the first object literal keeps the\n * user's formatting / comments / quote style intact, which an AST round-trip\n * would smash. The match anchors to the first `name:` after `export const meta`\n * and only touches that single value.\n */\nfunction rewriteMetaName(script: string, newName: string): string {\n const re = /(export\\s+const\\s+meta\\s*=\\s*\\{[^}]*?\\bname\\s*:\\s*)(['\"`])([^'\"`]*)\\2/;\n if (!re.test(script)) {\n throw new Error('could not locate meta.name in the recorded script to rewrite');\n }\n return script.replace(re, (_m, prefix, quote) => `${prefix}${quote}${newName}${quote}`);\n}\n\nexport function registerWorkflowCommands(): void {\n commandRegistry.register(workflowsCommand);\n commandRegistry.register(workflowCommand);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"workflow.js","names":[],"sources":["../../../../src/chat-commands/builtins/workflow.ts"],"sourcesContent":["/**\n * `/workflows` and `/workflow <subcommand>` — read-only commands for browsing\n * saved workflows.\n *\n * Why only read commands here? Slash command results are sent to the user; they\n * are NOT injected back into the agent's turn. Triggering a workflow run from\n * the slash layer would require a non-trivial cross-cutting \"inject this as the\n * next user message\" hook that doesn't exist yet. Instead, the workflow tool\n * understands `name`, and its description tells the model to prefer that route\n * whenever a user mentions a saved workflow by name. Plain text — \"run the\n * audit_repo workflow\" — works end-to-end.\n *\n * `/workflows` and `/workflow view` make discovery cheap, which is the missing\n * piece.\n */\n\nimport { commandRegistry } from '../registry.js';\nimport type { CommandContext, CommandDefinition } from '../types.js';\nimport { bulletList, code, joinBlocks, section } from '../format-output.js';\n\nimport { createWorkflowCatalog } from '../../agent/workflow/catalog.js';\nimport type { CatalogEntry } from '../../agent/workflow/catalog.js';\nimport { extractProfileAgentId } from '../../config/agent-profile.js';\n\nfunction formatEntryDetail(entry: CatalogEntry): string {\n const tags = entry.tags?.length ? `[${entry.tags.join(', ')}] ` : '';\n const agents = entry.estimatedAgents\n ? ` (~${entry.estimatedAgents.min}–${entry.estimatedAgents.max} agents)`\n : '';\n return `${tags}${entry.description}${agents}`;\n}\n\nfunction formatWorkflowListContent(entries: CatalogEntry[]): string {\n const grouped = {\n builtin: entries.filter((e) => e.source === 'builtin'),\n user: entries.filter((e) => e.source === 'user'),\n };\n const exampleName = entries[0]?.name ?? 'audit_repo';\n const blocks: string[] = [];\n\n if (grouped.user.length > 0) {\n blocks.push(\n joinBlocks(\n section('User workflows'),\n bulletList(grouped.user.map((e) => ({ label: e.name, detail: formatEntryDetail(e) }))),\n ),\n );\n }\n if (grouped.builtin.length > 0) {\n blocks.push(\n joinBlocks(\n section('Built-in workflows'),\n bulletList(grouped.builtin.map((e) => ({ label: e.name, detail: formatEntryDetail(e) }))),\n ),\n );\n }\n\n blocks.push(\n joinBlocks(\n section('How to run'),\n bulletList([\n `Plain language: \"run the ${exampleName} workflow\"`,\n `Inspect its visual structure: ${code(`/workflow view ${exampleName}`)}`,\n 'Create and edit workflows in the Workflow Studio.',\n ]),\n ),\n );\n\n return joinBlocks(...blocks);\n}\n\nconst workflowsCommand: CommandDefinition = {\n id: 'system.workflows',\n name: 'workflows',\n description: 'List saved workflows (built-in + ~/.xopc/workflows/)',\n category: 'system',\n scope: ['global', 'private', 'group'],\n handler: async (_ctx: CommandContext) => {\n const catalog = createWorkflowCatalog();\n const entries = catalog.list();\n if (entries.length === 0) {\n return {\n content: 'No workflows found. Create one in the Workflow Studio.',\n success: true,\n };\n }\n return { content: formatWorkflowListContent(entries), success: true };\n },\n};\n\nexport const workflowCommand: CommandDefinition = {\n id: 'system.workflow',\n name: 'workflow',\n description: 'Inspect or manage saved workflows. Subcommands: list, view <name>',\n category: 'system',\n scope: ['global', 'private', 'group'],\n acceptsArgs: true,\n examples: ['/workflow list', '/workflow view audit_repo'],\n handler: async (ctx: CommandContext, args: string) => {\n const trimmed = args.trim();\n if (!trimmed || trimmed.toLowerCase() === 'list') {\n return workflowsCommand.handler(ctx, '');\n }\n const [sub, ...rest] = trimmed.split(/\\s+/);\n const subLower = sub.toLowerCase();\n const target = rest.join(' ').trim();\n\n if (subLower === 'view' || subLower === 'show' || subLower === 'cat') {\n if (!target) {\n return { content: `usage: ${code('/workflow view <name>')}`, success: false };\n }\n const catalog = createWorkflowCatalog();\n try {\n const loaded = catalog.load(target);\n const nodeSummary = loaded.graph.nodes.map((node) => `${node.title} (${node.kind})`).join(' → ');\n return {\n content: joinBlocks(\n `**${loaded.title}** (${loaded.metadata.source}) — ${loaded.description}`,\n `Flow: ${nodeSummary}`,\n `Revision: ${loaded.revision}`,\n ),\n success: true,\n };\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n return { content: `error: ${message}`, success: false };\n }\n }\n\n if (subLower === 'run' || subLower === 'start') {\n return runWorkflowFromCommand(ctx, target);\n }\n\n return {\n content: joinBlocks(\n `Unknown subcommand \"${sub}\". Available: list, view ${code('<name>')}, run ${code('<name>')}.`,\n `Run directly with ${code('/workflow run <name> [--goal \"...\"] [--json \\'{...}\\']')}.`,\n ),\n success: false,\n };\n },\n};\n\nasync function runWorkflowFromCommand(ctx: CommandContext, args: string) {\n if (!ctx.workflowRunApis) {\n return {\n content: 'Workflow runs are not available in this context.',\n success: false,\n };\n }\n\n let parsed: { name: string; goal?: string; input?: unknown };\n try {\n parsed = parseWorkflowRunArgs(args);\n } catch (err) {\n return {\n content: `error: ${err instanceof Error ? err.message : String(err)}`,\n success: false,\n };\n }\n if (!parsed.name) {\n return {\n content: `usage: ${code('/workflow run <name> [--goal \"...\"] [--json \\'{...}\\']')}`,\n success: false,\n };\n }\n\n const catalog = createWorkflowCatalog();\n try {\n catalog.load(parsed.name);\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n return { content: `error: ${message}`, success: false };\n }\n\n const agentId = extractProfileAgentId(ctx.sessionKey, ctx.config);\n const source =\n ctx.source === 'webui' || ctx.channelId === 'webchat'\n ? ({ kind: 'webui' as const, sessionKey: ctx.sessionKey })\n : ({ kind: 'chat' as const, sessionKey: ctx.sessionKey });\n const result = await ctx.workflowRunApis.startWorkflowRun({\n agentId,\n definitionId: parsed.name,\n goal: parsed.goal,\n input: parsed.input,\n parentSessionKey: ctx.sessionKey,\n source,\n });\n\n if (result.ok === false) {\n return {\n content: `error: ${result.message}`,\n success: false,\n metadata: {\n workflowRun: {\n ok: false,\n definitionId: parsed.name,\n code: result.code,\n message: result.message,\n },\n },\n };\n }\n\n const content = joinBlocks(\n `Started workflow **${parsed.name}**.`,\n bulletList([\n { label: 'runId', detail: code(result.runId) },\n { label: 'sessionKey', detail: code(result.sessionKey) },\n ]),\n );\n\n return {\n content,\n success: true,\n metadata: {\n workflowRun: {\n ok: true,\n definitionId: parsed.name,\n runId: result.runId,\n sessionKey: result.sessionKey,\n parentSessionKey: ctx.sessionKey,\n },\n },\n };\n}\n\nfunction parseWorkflowRunArgs(raw: string): { name: string; goal?: string; input?: unknown } {\n const tokens = tokenizeArgs(raw);\n const name = tokens.shift()?.trim() ?? '';\n let goal: string | undefined;\n let input: unknown;\n\n for (let i = 0; i < tokens.length; i += 1) {\n const token = tokens[i];\n if (token === '--goal' || token === '-g') {\n goal = tokens[++i]?.trim() || undefined;\n continue;\n }\n if (token.startsWith('--goal=')) {\n goal = token.slice('--goal='.length).trim() || undefined;\n continue;\n }\n if (token === '--json' || token === '--input') {\n const value = tokens[++i];\n input = parseJsonArg(value, token);\n continue;\n }\n if (token.startsWith('--json=')) {\n input = parseJsonArg(token.slice('--json='.length), '--json');\n continue;\n }\n if (token.startsWith('--input=')) {\n input = parseJsonArg(token.slice('--input='.length), '--input');\n continue;\n }\n if (!goal) {\n goal = [token, ...tokens.slice(i + 1)].join(' ').trim() || undefined;\n break;\n }\n }\n\n return { name, goal, input };\n}\n\nfunction parseJsonArg(value: string | undefined, flag: string): unknown {\n if (!value?.trim()) {\n throw new Error(`${flag} requires a JSON value`);\n }\n try {\n return JSON.parse(value);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(`${flag} is not valid JSON: ${message}`);\n }\n}\n\nfunction tokenizeArgs(raw: string): string[] {\n const tokens: string[] = [];\n const re = /\"([^\"\\\\]*(?:\\\\.[^\"\\\\]*)*)\"|'([^'\\\\]*(?:\\\\.[^'\\\\]*)*)'|(\\S+)/g;\n let match: RegExpExecArray | null;\n while ((match = re.exec(raw)) !== null) {\n const value = match[1] ?? match[2] ?? match[3] ?? '';\n tokens.push(value.replace(/\\\\([\"'\\\\])/g, '$1'));\n }\n return tokens;\n}\n\nexport function registerWorkflowCommands(): void {\n commandRegistry.register(workflowsCommand);\n commandRegistry.register(workflowCommand);\n}\n"],"mappings":"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"}
|
|
@@ -112,6 +112,10 @@ export type BtwQueryOptions = {
|
|
|
112
112
|
maxTokens?: number;
|
|
113
113
|
temperature?: number;
|
|
114
114
|
modelRef?: string;
|
|
115
|
+
/** Run as an isolated one-shot task instead of adding recent session history. */
|
|
116
|
+
includeSessionContext?: boolean;
|
|
117
|
+
/** Receives visible model text as it arrives for rich command surfaces. */
|
|
118
|
+
onTextDelta?: (delta: string) => void | Promise<void>;
|
|
115
119
|
};
|
|
116
120
|
export interface CommandContext {
|
|
117
121
|
/** Unified session key */
|
|
@@ -52,7 +52,7 @@ async function checkDatabaseSchema(ctx) {
|
|
|
52
52
|
id: "database-schema",
|
|
53
53
|
label: "Database schema",
|
|
54
54
|
status: "pass",
|
|
55
|
-
message: `SQLite schema v${status.dbVersion} (current release
|
|
55
|
+
message: `SQLite schema v${status.dbVersion} (current release v36).`,
|
|
56
56
|
hints: []
|
|
57
57
|
};
|
|
58
58
|
}
|
|
@@ -109,8 +109,8 @@ function sourceFor(id, template) {
|
|
|
109
109
|
const toolName = `${id.replace(/-/g, "_")}_echo`;
|
|
110
110
|
if (template === "provider") return `import type { ExtensionApi } from '@xopcai/xopc/extension-sdk';\n\nexport default function register(api: ExtensionApi) {\n api.registerProvider({\n id: '${id}',\n name: '${id}',\n models: [],\n createStream: async function* () {\n yield { type: 'text', text: 'Provider template: implement createStream().' };\n },\n } as any);\n}\n`;
|
|
111
111
|
if (template === "ui") return `import type { ExtensionApi } from '@xopcai/xopc/extension-sdk';\n\nexport default function register(api: ExtensionApi) {\n api.logger.info('${id} UI extension loaded');\n}\n`;
|
|
112
|
-
if (template === "channel") return `import type { ExtensionApi } from '@xopcai/xopc/extension-sdk';\
|
|
113
|
-
return `import type { ExtensionApi } from '@xopcai/xopc/extension-sdk';\n\nexport default function register(api: ExtensionApi) {\n api.registerTool({\n name: '${toolName}',\n description: 'Echo input text',\n parameters: {\n type: 'object',\n properties: { text: { type: 'string' } },\n required: ['text'],\n },\n async execute(_toolCallId, params) {\n return {
|
|
112
|
+
if (template === "channel") return `import type { ChannelPlugin, ExtensionApi } from '@xopcai/xopc/extension-sdk';\n\nconst plugin: ChannelPlugin = {\n id: '${id}' as any,\n meta: { id: '${id}' as any, name: '${id}', description: '${id} channel' } as any,\n capabilities: { inbound: true, outbound: true } as any,\n async init() {},\n async start() {},\n async stop() {},\n config: {\n resolveAccounts() { return []; },\n } as any,\n};\n\nexport default function register(api: ExtensionApi) {\n api.registerChannel({ plugin });\n}\n`;
|
|
113
|
+
return `import type { ExtensionApi } from '@xopcai/xopc/extension-sdk';\n\nexport default function register(api: ExtensionApi) {\n api.registerTool({\n name: '${toolName}',\n label: 'Echo text',\n description: 'Echo input text',\n parameters: {\n type: 'object',\n properties: { text: { type: 'string' } },\n required: ['text'],\n },\n async execute(_toolCallId, params) {\n return {\n content: [{ type: 'text', text: String((params as any).text) }],\n details: {},\n };\n },\n });\n}\n`;
|
|
114
114
|
}
|
|
115
115
|
function createExtensionCreateCommand() {
|
|
116
116
|
return new Command("create").description("Create a new independent extension package").argument("<name>", "Extension id / package suffix").option("--template <type>", `Template: ${TEMPLATE_TYPES.join(", ")}`, "tool").option("--dir <path>", "Output directory (default: ./<name>)").action((name, opts) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension-create.js","names":[],"sources":["../../../../src/cli/commands/extension-create.ts"],"sourcesContent":["import { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\n\nimport { Command } from 'commander';\n\nimport { PACKAGE_VERSION } from '../../package-version.js';\nimport { colors } from '../utils/colors.js';\n\nconst TEMPLATE_TYPES = ['tool', 'ui', 'provider', 'channel'] as const;\ntype TemplateType = (typeof TEMPLATE_TYPES)[number];\n\nfunction toPackageName(name: string): string {\n return name.trim().toLowerCase().replace(/[^a-z0-9._-]+/g, '-').replace(/^-+|-+$/g, '');\n}\n\nfunction writeJson(path: string, value: unknown): void {\n writeFileSync(path, `${JSON.stringify(value, null, 2)}\\n`);\n}\n\nfunction basePackageJson(id: string, template: TemplateType): Record<string, unknown> {\n const scripts: Record<string, string> = {\n build: template === 'ui' ? 'tsc -p tsconfig.json && npm run build:ui' : 'tsc -p tsconfig.json',\n prepack: 'npm run build',\n };\n if (template === 'ui') scripts['build:ui'] = 'node scripts/build-ui.mjs';\n const devDependencies: Record<string, string> = {\n '@xopcai/xopc': `^${PACKAGE_VERSION}`,\n typescript: '^6.0.0',\n };\n if (template === 'ui') {\n devDependencies['@xopcai/extension-ui-sdk'] = `^${PACKAGE_VERSION}`;\n devDependencies.esbuild = '^0.28.1';\n }\n return {\n name: `xopc-extension-${id}`,\n version: '0.1.0',\n type: 'module',\n main: 'dist/index.js',\n files: ['dist', 'ui', 'xopc.extension.json', 'README.md', 'LICENSE'],\n keywords: ['xopc', 'xopc-extension'],\n license: 'MIT',\n scripts,\n devDependencies,\n peerDependencies: {\n '@xopcai/xopc': `>=${PACKAGE_VERSION} <1.0.0`,\n },\n peerDependenciesMeta: {\n '@xopcai/xopc': { optional: true },\n },\n };\n}\n\nfunction manifestFor(id: string, template: TemplateType): Record<string, unknown> {\n const base: Record<string, unknown> = {\n id,\n name: id.split('-').map((s) => s[0]?.toUpperCase() + s.slice(1)).join(' '),\n description: `xopc ${template} extension`,\n version: '0.1.0',\n kind: template === 'provider' ? 'provider' : template === 'channel' ? 'channel' : template === 'tool' ? 'tool' : 'utility',\n main: 'dist/index.js',\n engines: { xopc: `>=${PACKAGE_VERSION} <1.0.0` },\n };\n if (template === 'tool') {\n base.contracts = { tools: [`${id.replace(/-/g, '_')}_echo`] };\n } else if (template === 'provider') {\n base.providers = [id];\n base.contracts = { providers: [id] };\n } else if (template === 'channel') {\n base.channels = [id];\n base.contracts = { channels: [id] };\n base.activation = { onChannels: [id] };\n base.channelContributions = {\n [id]: {\n label: base.name,\n description: `Channel integration for ${base.name}`,\n configPath: `channels.${id}`,\n capabilities: { multiAccount: false, streaming: false, media: false },\n configSchema: { type: 'object', additionalProperties: true },\n },\n };\n } else {\n base.contracts = {};\n base.ui = {\n main: 'ui/panel.html',\n permissions: ['theme'],\n contributions: {\n pages: [{ id: `${id}.page`, title: base.name, path: id, entrypoint: 'ui/panel.html', showInNav: true }],\n },\n };\n }\n return base;\n}\n\nfunction buildUiScriptSource(): string {\n return `import { build } from 'esbuild';\\n\\nawait build({\\n entryPoints: ['ui/panel-entry.ts'],\\n outfile: 'ui/panel.bundle.js',\\n bundle: true,\\n format: 'esm',\\n platform: 'browser',\\n target: ['es2022'],\\n sourcemap: false,\\n});\\n`;\n}\n\nfunction uiPanelEntrySource(id: string): string {\n return `import { createExtensionClient } from '@xopcai/extension-ui-sdk';\\n\\nconst root = document.getElementById('root');\\nconst client = createExtensionClient();\\n\\nasync function main() {\\n await client.whenReady();\\n const theme = await client.theme.getTheme();\\n if (root) {\\n root.innerHTML = \\`<main style=\"font-family: system-ui; padding: 16px\">\\n <h1>${id}</h1>\\n <p>Theme mode: \\${theme.mode}</p>\\n <button id=\"notify\">Show notification</button>\\n </main>\\`;\\n document.getElementById('notify')?.addEventListener('click', () => {\\n void client.ui.showNotification({ type: 'info', message: '${id} is ready' });\\n });\\n }\\n}\\n\\nvoid main();\\n`;\n}\n\nfunction sourceFor(id: string, template: TemplateType): string {\n const toolName = `${id.replace(/-/g, '_')}_echo`;\n if (template === 'provider') {\n return `import type { ExtensionApi } from '@xopcai/xopc/extension-sdk';\\n\\nexport default function register(api: ExtensionApi) {\\n api.registerProvider({\\n id: '${id}',\\n name: '${id}',\\n models: [],\\n createStream: async function* () {\\n yield { type: 'text', text: 'Provider template: implement createStream().' };\\n },\\n } as any);\\n}\\n`;\n }\n if (template === 'ui') {\n return `import type { ExtensionApi } from '@xopcai/xopc/extension-sdk';\\n\\nexport default function register(api: ExtensionApi) {\\n api.logger.info('${id} UI extension loaded');\\n}\\n`;\n }\n if (template === 'channel') {\n return `import type { ExtensionApi } from '@xopcai/xopc/extension-sdk';\\nimport type { ChannelPlugin } from '@xopcai/xopc/extension-sdk/channel';\\n\\nconst plugin: ChannelPlugin = {\\n id: '${id}' as any,\\n meta: { id: '${id}' as any, name: '${id}', description: '${id} channel' } as any,\\n capabilities: { inbound: true, outbound: true } as any,\\n async init() {},\\n async start() {},\\n async stop() {},\\n config: {\\n resolveAccounts() { return []; },\\n } as any,\\n};\\n\\nexport default function register(api: ExtensionApi) {\\n api.registerChannel({ plugin });\\n}\\n`;\n }\n return `import type { ExtensionApi } from '@xopcai/xopc/extension-sdk';\\n\\nexport default function register(api: ExtensionApi) {\\n api.registerTool({\\n name: '${toolName}',\\n description: 'Echo input text',\\n parameters: {\\n type: 'object',\\n properties: { text: { type: 'string' } },\\n required: ['text'],\\n },\\n async execute(_toolCallId, params) {\\n return { content: [{ type: 'text', text: String((params as any).text) }] };\\n },\\n });\\n}\\n`;\n}\n\nexport function createExtensionCreateCommand(): Command {\n return new Command('create')\n .description('Create a new independent extension package')\n .argument('<name>', 'Extension id / package suffix')\n .option('--template <type>', `Template: ${TEMPLATE_TYPES.join(', ')}`, 'tool')\n .option('--dir <path>', 'Output directory (default: ./<name>)')\n .action((name: string, opts: { template: string; dir?: string }) => {\n const id = toPackageName(name);\n if (!id) {\n console.error(colors.red('error:'), 'Invalid extension name');\n process.exit(1);\n }\n const template = opts.template as TemplateType;\n if (!TEMPLATE_TYPES.includes(template)) {\n console.error(colors.red('error:'), `Unknown template: ${opts.template}`);\n process.exit(1);\n }\n const root = resolve(opts.dir?.trim() || id);\n if (existsSync(root)) {\n console.error(colors.red('error:'), `Directory already exists: ${root}`);\n process.exit(1);\n }\n mkdirSync(join(root, 'src'), { recursive: true });\n writeJson(join(root, 'package.json'), basePackageJson(id, template));\n writeJson(join(root, 'xopc.extension.json'), manifestFor(id, template));\n writeJson(join(root, 'tsconfig.json'), {\n compilerOptions: {\n target: 'ES2022',\n module: 'NodeNext',\n moduleResolution: 'NodeNext',\n declaration: true,\n outDir: 'dist',\n rootDir: 'src',\n strict: true,\n skipLibCheck: true,\n },\n include: ['src/**/*.ts'],\n });\n writeFileSync(join(root, 'src', 'index.ts'), sourceFor(id, template));\n if (template === 'ui') {\n mkdirSync(join(root, 'ui'), { recursive: true });\n mkdirSync(join(root, 'scripts'), { recursive: true });\n writeFileSync(join(root, 'ui', 'panel.html'), '<!doctype html><html><body><div id=\"root\"></div><script type=\"module\" src=\"./panel.bundle.js\"></script></body></html>\\n');\n writeFileSync(join(root, 'ui', 'panel-entry.ts'), uiPanelEntrySource(id));\n writeFileSync(join(root, 'scripts', 'build-ui.mjs'), buildUiScriptSource());\n }\n writeFileSync(join(root, 'README.md'), `# ${id}\\n\\nGenerated xopc extension.\\n`);\n writeFileSync(join(root, 'LICENSE'), 'MIT\\n');\n console.log(colors.green('✓'), `Created extension package at ${root}`);\n console.log(colors.cyan('Next:'), `cd ${root} && npm install && npm run build && xopc extensions pack . --dry-run`);\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"extension-create.js","names":[],"sources":["../../../../src/cli/commands/extension-create.ts"],"sourcesContent":["import { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\n\nimport { Command } from 'commander';\n\nimport { PACKAGE_VERSION } from '../../package-version.js';\nimport { colors } from '../utils/colors.js';\n\nconst TEMPLATE_TYPES = ['tool', 'ui', 'provider', 'channel'] as const;\ntype TemplateType = (typeof TEMPLATE_TYPES)[number];\n\nfunction toPackageName(name: string): string {\n return name.trim().toLowerCase().replace(/[^a-z0-9._-]+/g, '-').replace(/^-+|-+$/g, '');\n}\n\nfunction writeJson(path: string, value: unknown): void {\n writeFileSync(path, `${JSON.stringify(value, null, 2)}\\n`);\n}\n\nfunction basePackageJson(id: string, template: TemplateType): Record<string, unknown> {\n const scripts: Record<string, string> = {\n build: template === 'ui' ? 'tsc -p tsconfig.json && npm run build:ui' : 'tsc -p tsconfig.json',\n prepack: 'npm run build',\n };\n if (template === 'ui') scripts['build:ui'] = 'node scripts/build-ui.mjs';\n const devDependencies: Record<string, string> = {\n '@xopcai/xopc': `^${PACKAGE_VERSION}`,\n typescript: '^6.0.0',\n };\n if (template === 'ui') {\n devDependencies['@xopcai/extension-ui-sdk'] = `^${PACKAGE_VERSION}`;\n devDependencies.esbuild = '^0.28.1';\n }\n return {\n name: `xopc-extension-${id}`,\n version: '0.1.0',\n type: 'module',\n main: 'dist/index.js',\n files: ['dist', 'ui', 'xopc.extension.json', 'README.md', 'LICENSE'],\n keywords: ['xopc', 'xopc-extension'],\n license: 'MIT',\n scripts,\n devDependencies,\n peerDependencies: {\n '@xopcai/xopc': `>=${PACKAGE_VERSION} <1.0.0`,\n },\n peerDependenciesMeta: {\n '@xopcai/xopc': { optional: true },\n },\n };\n}\n\nfunction manifestFor(id: string, template: TemplateType): Record<string, unknown> {\n const base: Record<string, unknown> = {\n id,\n name: id.split('-').map((s) => s[0]?.toUpperCase() + s.slice(1)).join(' '),\n description: `xopc ${template} extension`,\n version: '0.1.0',\n kind: template === 'provider' ? 'provider' : template === 'channel' ? 'channel' : template === 'tool' ? 'tool' : 'utility',\n main: 'dist/index.js',\n engines: { xopc: `>=${PACKAGE_VERSION} <1.0.0` },\n };\n if (template === 'tool') {\n base.contracts = { tools: [`${id.replace(/-/g, '_')}_echo`] };\n } else if (template === 'provider') {\n base.providers = [id];\n base.contracts = { providers: [id] };\n } else if (template === 'channel') {\n base.channels = [id];\n base.contracts = { channels: [id] };\n base.activation = { onChannels: [id] };\n base.channelContributions = {\n [id]: {\n label: base.name,\n description: `Channel integration for ${base.name}`,\n configPath: `channels.${id}`,\n capabilities: { multiAccount: false, streaming: false, media: false },\n configSchema: { type: 'object', additionalProperties: true },\n },\n };\n } else {\n base.contracts = {};\n base.ui = {\n main: 'ui/panel.html',\n permissions: ['theme'],\n contributions: {\n pages: [{ id: `${id}.page`, title: base.name, path: id, entrypoint: 'ui/panel.html', showInNav: true }],\n },\n };\n }\n return base;\n}\n\nfunction buildUiScriptSource(): string {\n return `import { build } from 'esbuild';\\n\\nawait build({\\n entryPoints: ['ui/panel-entry.ts'],\\n outfile: 'ui/panel.bundle.js',\\n bundle: true,\\n format: 'esm',\\n platform: 'browser',\\n target: ['es2022'],\\n sourcemap: false,\\n});\\n`;\n}\n\nfunction uiPanelEntrySource(id: string): string {\n return `import { createExtensionClient } from '@xopcai/extension-ui-sdk';\\n\\nconst root = document.getElementById('root');\\nconst client = createExtensionClient();\\n\\nasync function main() {\\n await client.whenReady();\\n const theme = await client.theme.getTheme();\\n if (root) {\\n root.innerHTML = \\`<main style=\"font-family: system-ui; padding: 16px\">\\n <h1>${id}</h1>\\n <p>Theme mode: \\${theme.mode}</p>\\n <button id=\"notify\">Show notification</button>\\n </main>\\`;\\n document.getElementById('notify')?.addEventListener('click', () => {\\n void client.ui.showNotification({ type: 'info', message: '${id} is ready' });\\n });\\n }\\n}\\n\\nvoid main();\\n`;\n}\n\nfunction sourceFor(id: string, template: TemplateType): string {\n const toolName = `${id.replace(/-/g, '_')}_echo`;\n if (template === 'provider') {\n return `import type { ExtensionApi } from '@xopcai/xopc/extension-sdk';\\n\\nexport default function register(api: ExtensionApi) {\\n api.registerProvider({\\n id: '${id}',\\n name: '${id}',\\n models: [],\\n createStream: async function* () {\\n yield { type: 'text', text: 'Provider template: implement createStream().' };\\n },\\n } as any);\\n}\\n`;\n }\n if (template === 'ui') {\n return `import type { ExtensionApi } from '@xopcai/xopc/extension-sdk';\\n\\nexport default function register(api: ExtensionApi) {\\n api.logger.info('${id} UI extension loaded');\\n}\\n`;\n }\n if (template === 'channel') {\n return `import type { ChannelPlugin, ExtensionApi } from '@xopcai/xopc/extension-sdk';\\n\\nconst plugin: ChannelPlugin = {\\n id: '${id}' as any,\\n meta: { id: '${id}' as any, name: '${id}', description: '${id} channel' } as any,\\n capabilities: { inbound: true, outbound: true } as any,\\n async init() {},\\n async start() {},\\n async stop() {},\\n config: {\\n resolveAccounts() { return []; },\\n } as any,\\n};\\n\\nexport default function register(api: ExtensionApi) {\\n api.registerChannel({ plugin });\\n}\\n`;\n }\n return `import type { ExtensionApi } from '@xopcai/xopc/extension-sdk';\\n\\nexport default function register(api: ExtensionApi) {\\n api.registerTool({\\n name: '${toolName}',\\n label: 'Echo text',\\n description: 'Echo input text',\\n parameters: {\\n type: 'object',\\n properties: { text: { type: 'string' } },\\n required: ['text'],\\n },\\n async execute(_toolCallId, params) {\\n return {\\n content: [{ type: 'text', text: String((params as any).text) }],\\n details: {},\\n };\\n },\\n });\\n}\\n`;\n}\n\nexport function createExtensionCreateCommand(): Command {\n return new Command('create')\n .description('Create a new independent extension package')\n .argument('<name>', 'Extension id / package suffix')\n .option('--template <type>', `Template: ${TEMPLATE_TYPES.join(', ')}`, 'tool')\n .option('--dir <path>', 'Output directory (default: ./<name>)')\n .action((name: string, opts: { template: string; dir?: string }) => {\n const id = toPackageName(name);\n if (!id) {\n console.error(colors.red('error:'), 'Invalid extension name');\n process.exit(1);\n }\n const template = opts.template as TemplateType;\n if (!TEMPLATE_TYPES.includes(template)) {\n console.error(colors.red('error:'), `Unknown template: ${opts.template}`);\n process.exit(1);\n }\n const root = resolve(opts.dir?.trim() || id);\n if (existsSync(root)) {\n console.error(colors.red('error:'), `Directory already exists: ${root}`);\n process.exit(1);\n }\n mkdirSync(join(root, 'src'), { recursive: true });\n writeJson(join(root, 'package.json'), basePackageJson(id, template));\n writeJson(join(root, 'xopc.extension.json'), manifestFor(id, template));\n writeJson(join(root, 'tsconfig.json'), {\n compilerOptions: {\n target: 'ES2022',\n module: 'NodeNext',\n moduleResolution: 'NodeNext',\n declaration: true,\n outDir: 'dist',\n rootDir: 'src',\n strict: true,\n skipLibCheck: true,\n },\n include: ['src/**/*.ts'],\n });\n writeFileSync(join(root, 'src', 'index.ts'), sourceFor(id, template));\n if (template === 'ui') {\n mkdirSync(join(root, 'ui'), { recursive: true });\n mkdirSync(join(root, 'scripts'), { recursive: true });\n writeFileSync(join(root, 'ui', 'panel.html'), '<!doctype html><html><body><div id=\"root\"></div><script type=\"module\" src=\"./panel.bundle.js\"></script></body></html>\\n');\n writeFileSync(join(root, 'ui', 'panel-entry.ts'), uiPanelEntrySource(id));\n writeFileSync(join(root, 'scripts', 'build-ui.mjs'), buildUiScriptSource());\n }\n writeFileSync(join(root, 'README.md'), `# ${id}\\n\\nGenerated xopc extension.\\n`);\n writeFileSync(join(root, 'LICENSE'), 'MIT\\n');\n console.log(colors.green('✓'), `Created extension package at ${root}`);\n console.log(colors.cyan('Next:'), `cd ${root} && npm install && npm run build && xopc extensions pack . --dry-run`);\n });\n}\n"],"mappings":"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"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { init_paths, resolveExtensionsDir } from "../../config/paths.js";
|
|
2
2
|
import { init_loader, loadConfig } from "../../config/loader.js";
|
|
3
|
-
import { downloadExtensionStoreZipBuffer, resolveExtensionZipDownloadUrl, resolveExtensionsStoreBaseUrl } from "../../agent/skills/marketplace/adapters/store/store-api-client.js";
|
|
3
|
+
import { downloadExtensionStoreZipBuffer, resolveExtensionZipDownloadUrl, resolveExtensionsStoreBaseUrl, verifyStoreArtifactSha256 } from "../../agent/skills/marketplace/adapters/store/store-api-client.js";
|
|
4
4
|
import { getContextWithOpts } from "../context.js";
|
|
5
5
|
import { getExtensionLockfileManager } from "../../extensions/lockfile.js";
|
|
6
|
-
import {
|
|
6
|
+
import { installFromLocal, installFromNpm, peekExtensionManifestFromStoreZip } from "../../extensions/install.js";
|
|
7
|
+
import { commitStagedExtensionInstall, finalizeStagedExtensionInstall, rollbackStagedExtensionInstall, stageExtensionStoreZip } from "../../extensions/install-transaction.js";
|
|
7
8
|
import { fetchRegistry, findExtension, getExtensionMarketplaceStoreBaseUrl, listExtensions, searchExtensions } from "../../extensions/marketplace.js";
|
|
8
9
|
import { colors } from "../utils/colors.js";
|
|
9
10
|
import { validateExtensionPackageDirectory } from "./extension-pack.js";
|
|
@@ -36,13 +37,6 @@ function readInstalledSnapshots(targetDir, extensionId) {
|
|
|
36
37
|
function sha256Integrity(buffer) {
|
|
37
38
|
return `sha256-${createHash("sha256").update(buffer).digest("base64")}`;
|
|
38
39
|
}
|
|
39
|
-
function normalizeIntegrity(raw) {
|
|
40
|
-
const value = raw?.trim();
|
|
41
|
-
if (!value) return void 0;
|
|
42
|
-
if (value.startsWith("sha256-")) return value;
|
|
43
|
-
if (/^[a-f0-9]{64}$/i.test(value)) return `sha256-${Buffer.from(value, "hex").toString("base64")}`;
|
|
44
|
-
return value;
|
|
45
|
-
}
|
|
46
40
|
function printManifestSummary(params) {
|
|
47
41
|
const manifest = params.manifest;
|
|
48
42
|
console.log("");
|
|
@@ -122,15 +116,11 @@ async function upsertNpmExtensionLock(lock, targetDir, result, spec) {
|
|
|
122
116
|
}
|
|
123
117
|
async function installExtensionFromStoreWithLock(params) {
|
|
124
118
|
try {
|
|
125
|
-
const { downloadUrl, version,
|
|
119
|
+
const { downloadUrl, version, sha256 } = await resolveExtensionZipDownloadUrl(params.storeBase, params.packageName, params.version);
|
|
126
120
|
console.log(colors.cyan("📦"), `Downloading ${params.packageName}@${version} from xopc-store (${params.storeBase})…`);
|
|
127
121
|
const buf = await downloadExtensionStoreZipBuffer(params.storeBase, downloadUrl);
|
|
122
|
+
verifyStoreArtifactSha256(buf, sha256);
|
|
128
123
|
const actualIntegrity = sha256Integrity(buf);
|
|
129
|
-
const expectedIntegrity = normalizeIntegrity(expectedIntegrityRaw);
|
|
130
|
-
if (expectedIntegrity && expectedIntegrity !== actualIntegrity) return {
|
|
131
|
-
ok: false,
|
|
132
|
-
error: `Extension artifact checksum mismatch: expected ${expectedIntegrity}, got ${actualIntegrity}`
|
|
133
|
-
};
|
|
134
124
|
const manifest = peekExtensionManifestFromStoreZip(buf);
|
|
135
125
|
if (!await confirmInstall({
|
|
136
126
|
source: "store",
|
|
@@ -143,30 +133,46 @@ async function installExtensionFromStoreWithLock(params) {
|
|
|
143
133
|
ok: false,
|
|
144
134
|
error: "Install cancelled"
|
|
145
135
|
};
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
136
|
+
const transaction = await stageExtensionStoreZip(buf, params.targetDir);
|
|
137
|
+
const lockSnapshot = await params.lock.load();
|
|
138
|
+
let lockWriteStarted = false;
|
|
139
|
+
try {
|
|
140
|
+
commitStagedExtensionInstall(transaction, params.force ?? false);
|
|
141
|
+
lockWriteStarted = true;
|
|
142
|
+
await params.lock.upsert(transaction.extensionId, {
|
|
143
|
+
name: transaction.extensionId,
|
|
144
|
+
version,
|
|
145
|
+
resolved: params.packageName,
|
|
146
|
+
source: "store",
|
|
147
|
+
artifactUrl: downloadUrl,
|
|
148
|
+
integrity: actualIntegrity,
|
|
149
|
+
...readInstalledSnapshots(params.targetDir, transaction.extensionId)
|
|
151
150
|
});
|
|
151
|
+
} catch (err) {
|
|
152
|
+
const rollbackErrors = [];
|
|
153
|
+
try {
|
|
154
|
+
rollbackStagedExtensionInstall(transaction);
|
|
155
|
+
} catch (rollbackErr) {
|
|
156
|
+
rollbackErrors.push(`files: ${rollbackErr instanceof Error ? rollbackErr.message : String(rollbackErr)}`);
|
|
157
|
+
}
|
|
158
|
+
if (lockWriteStarted) try {
|
|
159
|
+
await params.lock.save(lockSnapshot);
|
|
160
|
+
} catch (rollbackErr) {
|
|
161
|
+
rollbackErrors.push(`lockfile: ${rollbackErr instanceof Error ? rollbackErr.message : String(rollbackErr)}`);
|
|
162
|
+
}
|
|
163
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
164
|
+
const suffix = rollbackErrors.length > 0 ? ` Rollback incomplete (${rollbackErrors.join("; ")}).` : "";
|
|
165
|
+
throw new Error(`${message}${suffix}`, { cause: err });
|
|
166
|
+
}
|
|
167
|
+
try {
|
|
168
|
+
finalizeStagedExtensionInstall(transaction);
|
|
169
|
+
} catch (cleanupErr) {
|
|
170
|
+
const message = cleanupErr instanceof Error ? cleanupErr.message : String(cleanupErr);
|
|
171
|
+
console.warn(colors.yellow("warning:"), `Installed extension, but temporary backup cleanup failed: ${message}`);
|
|
152
172
|
}
|
|
153
|
-
const result = await installExtensionFromStoreZip(buf, params.targetDir);
|
|
154
|
-
if (!result.ok || !result.extensionId) return {
|
|
155
|
-
ok: false,
|
|
156
|
-
error: result.error ?? "install failed"
|
|
157
|
-
};
|
|
158
|
-
await params.lock.upsert(result.extensionId, {
|
|
159
|
-
name: result.extensionId,
|
|
160
|
-
version,
|
|
161
|
-
resolved: params.packageName,
|
|
162
|
-
source: "store",
|
|
163
|
-
artifactUrl: downloadUrl,
|
|
164
|
-
integrity: actualIntegrity,
|
|
165
|
-
...readInstalledSnapshots(params.targetDir, result.extensionId)
|
|
166
|
-
});
|
|
167
173
|
return {
|
|
168
174
|
ok: true,
|
|
169
|
-
extensionId:
|
|
175
|
+
extensionId: transaction.extensionId,
|
|
170
176
|
version
|
|
171
177
|
};
|
|
172
178
|
} catch (e) {
|
|
@@ -177,7 +183,7 @@ async function installExtensionFromStoreWithLock(params) {
|
|
|
177
183
|
}
|
|
178
184
|
}
|
|
179
185
|
function createExtensionInstallCommand() {
|
|
180
|
-
return new Command("install").description("Install extension from xopc-store (store.xopc.ai), npm, or a local directory into ~/.xopc/extensions").argument("<target>", "Explicit source spec: store:<id>, npm:<package>, or a local extension directory").option("-f, --force", "
|
|
186
|
+
return new Command("install").description("Install extension from xopc-store (store.xopc.ai), npm, or a local directory into ~/.xopc/extensions").argument("<target>", "Explicit source spec: store:<id>, npm:<package>, or a local extension directory").option("-f, --force", "Replace an existing store or local extension with the same manifest id", false).option("-y, --yes", "Skip interactive install confirmation", false).action(async (target, opts) => {
|
|
181
187
|
const cfg = loadConfig(getContextWithOpts().configPath);
|
|
182
188
|
const targetDir = resolveExtensionsDir();
|
|
183
189
|
const lock = getExtensionLockfileManager();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension-marketplace.js","names":["marketplace.findExtension","marketplace.listExtensions","marketplace.searchExtensions","marketplace.fetchRegistry","marketplace.getExtensionMarketplaceStoreBaseUrl"],"sources":["../../../../src/cli/commands/extension-marketplace.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport { execSync } from 'node:child_process';\nimport { existsSync, readFileSync, statSync, rmSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\n\nimport { confirm } from '@inquirer/prompts';\nimport { Command } from 'commander';\nimport semver from 'semver';\n\nimport {\n downloadExtensionStoreZipBuffer,\n resolveExtensionZipDownloadUrl,\n resolveExtensionsStoreBaseUrl,\n} from '../../agent/skills/marketplace/adapters/store/store-api-client.js';\nimport { loadConfig } from '../../config/loader.js';\nimport { resolveExtensionsDir } from '../../config/paths.js';\nimport type { InstallResult } from '../../extensions/install.js';\nimport {\n installExtensionFromStoreZip,\n installFromLocal,\n installFromNpm,\n peekExtensionIdFromStoreZip,\n peekExtensionManifestFromStoreZip,\n} from '../../extensions/install.js';\nimport { getExtensionLockfileManager } from '../../extensions/lockfile.js';\nimport * as marketplace from '../../extensions/marketplace.js';\nimport { colors } from '../utils/colors.js';\nimport { getContextWithOpts } from '../context.js';\nimport { validateExtensionPackageDirectory } from './extension-pack.js';\n\nconst MANIFEST = 'xopc.extension.json';\n\nfunction readJsonObject(path: string): Record<string, unknown> | undefined {\n try {\n const raw = JSON.parse(readFileSync(path, 'utf-8')) as unknown;\n return typeof raw === 'object' && raw !== null && !Array.isArray(raw)\n ? (raw as Record<string, unknown>)\n : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction readInstalledSnapshots(targetDir: string, extensionId: string): {\n manifest?: Record<string, unknown>;\n packageJson?: Record<string, unknown>;\n} {\n const root = join(targetDir, extensionId);\n return {\n manifest: readJsonObject(join(root, MANIFEST)),\n packageJson: readJsonObject(join(root, 'package.json')),\n };\n}\n\nfunction sha256Integrity(buffer: Buffer): string {\n return `sha256-${createHash('sha256').update(buffer).digest('base64')}`;\n}\n\nfunction normalizeIntegrity(raw: string | undefined): string | undefined {\n const value = raw?.trim();\n if (!value) return undefined;\n if (value.startsWith('sha256-')) return value;\n if (/^[a-f0-9]{64}$/i.test(value)) {\n return `sha256-${Buffer.from(value, 'hex').toString('base64')}`;\n }\n return value;\n}\n\nfunction printManifestSummary(params: {\n source: 'store' | 'npm' | 'local';\n packageName: string;\n version?: string;\n integrity?: string;\n manifest?: Record<string, unknown>;\n}): void {\n const manifest = params.manifest;\n console.log('');\n console.log(colors.cyan('Extension install review'));\n console.log(` Source: ${params.source}`);\n console.log(` Package: ${params.packageName}${params.version ? `@${params.version}` : ''}`);\n if (params.integrity) console.log(` Integrity: ${params.integrity}`);\n if (manifest) {\n console.log(` ID: ${String(manifest.id ?? '(unknown)')}`);\n console.log(` Name: ${String(manifest.name ?? manifest.id ?? '(unknown)')}`);\n const engines = manifest.engines as Record<string, unknown> | undefined;\n if (engines?.xopc) console.log(` engines.xopc: ${String(engines.xopc)}`);\n const permissions = manifest.permissions as Record<string, unknown> | undefined;\n if (permissions) {\n console.log(' Permissions:');\n for (const [key, value] of Object.entries(permissions)) {\n console.log(` ${key}: ${Array.isArray(value) ? value.join(', ') : String(value)}`);\n }\n }\n const contracts = manifest.contracts as Record<string, unknown> | undefined;\n if (contracts) {\n console.log(' Contracts:');\n for (const [key, value] of Object.entries(contracts)) {\n if (Array.isArray(value) && value.length > 0) console.log(` ${key}: ${value.join(', ')}`);\n }\n }\n }\n console.log('');\n}\n\nasync function confirmInstall(params: Parameters<typeof printManifestSummary>[0] & { yes?: boolean }): Promise<boolean> {\n printManifestSummary(params);\n if (params.yes || !process.stdin.isTTY) return true;\n return await confirm({ message: 'Install this extension?', default: false });\n}\n\nfunction parseNameAtVersion(raw: string): { name: string; version?: string } {\n const t = raw.trim();\n const at = t.lastIndexOf('@');\n if (at <= 0 || at === t.length - 1) return { name: t };\n const maybeVer = t.slice(at + 1);\n const v = semver.valid(maybeVer);\n if (v) return { name: t.slice(0, at), version: v };\n return { name: t };\n}\n\nfunction looksLikeLocalPath(raw: string): boolean {\n const p = raw.trim();\n if (p.startsWith('./') || p.startsWith('../')) return true;\n if (p === '.' || p === '..') return true;\n try {\n const abs = resolve(process.cwd(), p);\n return existsSync(abs) && statSync(abs).isDirectory();\n } catch {\n return false;\n }\n}\n\n/** xopc-store package names: lowercase letters, digits, hyphen (see xopc-store scan). */\nconst STORE_NAME_RE = /^[a-z0-9-]{1,64}$/;\n\nasync function upsertNpmExtensionLock(\n lock: ReturnType<typeof getExtensionLockfileManager>,\n targetDir: string,\n result: InstallResult,\n spec: string,\n): Promise<void> {\n if (!result.extensionId) return;\n const reg = await marketplace.findExtension(result.extensionId);\n const resolved = reg?.npmPackage ?? spec;\n let ver = reg?.version ?? '0.0.0';\n try {\n const raw = readFileSync(join(targetDir, result.extensionId, MANIFEST), 'utf-8');\n const m = JSON.parse(raw) as { version?: string };\n const mv = typeof m.version === 'string' ? semver.valid(m.version) : null;\n if (mv) ver = mv;\n } catch {\n /* keep registry / fallback version */\n }\n await lock.upsert(result.extensionId, {\n name: result.extensionId,\n version: ver,\n resolved,\n source: 'npm',\n ...readInstalledSnapshots(targetDir, result.extensionId),\n });\n}\n\nasync function installExtensionFromStoreWithLock(params: {\n storeBase: string;\n packageName: string;\n version?: string;\n targetDir: string;\n lock: ReturnType<typeof getExtensionLockfileManager>;\n force?: boolean;\n yes?: boolean;\n}): Promise<{ ok: true; extensionId: string; version: string } | { ok: false; error: string }> {\n try {\n const { downloadUrl, version, integrity: expectedIntegrityRaw } = await resolveExtensionZipDownloadUrl(\n params.storeBase,\n params.packageName,\n params.version,\n );\n console.log(\n colors.cyan('📦'),\n `Downloading ${params.packageName}@${version} from xopc-store (${params.storeBase})…`,\n );\n const buf = await downloadExtensionStoreZipBuffer(params.storeBase, downloadUrl);\n const actualIntegrity = sha256Integrity(buf);\n const expectedIntegrity = normalizeIntegrity(expectedIntegrityRaw);\n if (expectedIntegrity && expectedIntegrity !== actualIntegrity) {\n return {\n ok: false,\n error: `Extension artifact checksum mismatch: expected ${expectedIntegrity}, got ${actualIntegrity}`,\n };\n }\n const manifest = peekExtensionManifestFromStoreZip(buf);\n const accepted = await confirmInstall({\n source: 'store',\n packageName: params.packageName,\n version,\n integrity: actualIntegrity,\n manifest,\n yes: params.yes,\n });\n if (!accepted) {\n return { ok: false, error: 'Install cancelled' };\n }\n if (params.force) {\n const id = peekExtensionIdFromStoreZip(buf);\n if (id && existsSync(join(params.targetDir, id))) {\n rmSync(join(params.targetDir, id), { recursive: true, force: true });\n }\n }\n const result = await installExtensionFromStoreZip(buf, params.targetDir);\n if (!result.ok || !result.extensionId) {\n return { ok: false, error: result.error ?? 'install failed' };\n }\n await params.lock.upsert(result.extensionId, {\n name: result.extensionId,\n version,\n resolved: params.packageName,\n source: 'store',\n artifactUrl: downloadUrl,\n integrity: actualIntegrity,\n ...readInstalledSnapshots(params.targetDir, result.extensionId),\n });\n return { ok: true, extensionId: result.extensionId, version };\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n return { ok: false, error: msg };\n }\n}\n\nexport function createExtensionInstallCommand(): Command {\n return new Command('install')\n .description(\n 'Install extension from xopc-store (store.xopc.ai), npm, or a local directory into ~/.xopc/extensions',\n )\n .argument(\n '<target>',\n 'Explicit source spec: store:<id>, npm:<package>, or a local extension directory',\n )\n .option(\n '-f, --force',\n 'Remove existing extension folder (manifest id) before store or local install',\n false,\n )\n .option('-y, --yes', 'Skip interactive install confirmation', false)\n .action(\n async (\n target: string,\n opts: { force: boolean; yes: boolean },\n ) => {\n const ctx = getContextWithOpts();\n const cfg = loadConfig(ctx.configPath);\n const targetDir = resolveExtensionsDir();\n const lock = getExtensionLockfileManager();\n\n let installTarget = target.trim();\n const storeExplicit = /^store:/i.test(installTarget);\n const npmExplicit = /^npm:/i.test(installTarget);\n if (storeExplicit) {\n installTarget = installTarget.replace(/^store:/i, '').trim();\n } else if (npmExplicit) {\n installTarget = installTarget.replace(/^npm:/i, '').trim();\n }\n if (!installTarget) {\n console.error(colors.red('error:'), 'Missing target');\n process.exit(1);\n }\n\n const storeBase = resolveExtensionsStoreBaseUrl(cfg);\n\n if (storeExplicit) {\n const { name: pkgName, version: ver } = parseNameAtVersion(installTarget);\n if (!STORE_NAME_RE.test(pkgName)) {\n console.error(\n colors.red('error:'),\n 'Invalid store package name (lowercase letters, digits, hyphen only)',\n );\n process.exit(1);\n }\n const r = await installExtensionFromStoreWithLock({\n storeBase,\n packageName: pkgName,\n version: ver,\n targetDir,\n lock,\n force: opts.force,\n yes: opts.yes,\n });\n if (r.ok === false) {\n console.error(colors.red('error:'), r.error);\n process.exit(1);\n }\n console.log(colors.green('✓'), `${r.extensionId}@${r.version} (store)`);\n return;\n }\n\n if (npmExplicit) {\n const spec = installTarget;\n console.log(colors.cyan('📦'), `Installing from npm: ${spec}…`);\n const result = await installFromNpm(spec, targetDir);\n if (!result.ok) {\n console.error(colors.red('error:'), result.error ?? 'install failed');\n process.exit(1);\n }\n await upsertNpmExtensionLock(lock, targetDir, result, spec);\n console.log(colors.green('✓'), result.extensionId ?? 'ok', '(npm)');\n return;\n }\n\n if (looksLikeLocalPath(installTarget)) {\n const sourceDir = resolve(process.cwd(), installTarget);\n if (opts.force) {\n const manifestPath = join(sourceDir, MANIFEST);\n if (existsSync(manifestPath)) {\n try {\n const raw = readFileSync(manifestPath, 'utf-8');\n const m = JSON.parse(raw) as { id?: string };\n const extId =\n typeof m.id === 'string' &&\n m.id &&\n !m.id.includes('/') &&\n !m.id.includes('\\\\')\n ? m.id\n : undefined;\n if (extId && existsSync(join(targetDir, extId))) {\n rmSync(join(targetDir, extId), { recursive: true, force: true });\n }\n } catch {\n /* installFromLocal will surface manifest errors */\n }\n }\n }\n console.log(colors.cyan('📂'), 'Installing from local directory…');\n const result = await installFromLocal(sourceDir, targetDir);\n if (!result.ok) {\n console.error(colors.red('error:'), result.error ?? 'install failed');\n process.exit(1);\n }\n console.log(colors.green('✓'), result.extensionId ?? 'ok');\n return;\n }\n\n console.error(\n colors.red('error:'),\n 'Extension installs require an explicit source: store:<id>, npm:<package>, or a local directory path.',\n );\n process.exit(1);\n },\n );\n}\n\nexport function createExtensionSearchCommand(): Command {\n return new Command('search')\n .description('Search extensions listed on xopc-store')\n .argument('[keyword]', 'Search text (omit to list all)', '')\n .option('--category <cat>', 'Filter by category')\n .option('--json', 'JSON output')\n .action(async (keyword: string, opts: { category?: string; json?: boolean }) => {\n try {\n let rows;\n if (opts.category?.trim()) {\n rows = await marketplace.listExtensions(opts.category.trim());\n if (keyword.trim()) {\n const k = keyword.trim().toLowerCase();\n rows = rows.filter(\n (e) =>\n e.id.toLowerCase().includes(k) ||\n e.name.toLowerCase().includes(k) ||\n (e.description ?? '').toLowerCase().includes(k),\n );\n }\n } else if (keyword.trim()) {\n rows = await marketplace.searchExtensions(keyword.trim());\n } else {\n const reg = await marketplace.fetchRegistry();\n rows = reg.extensions;\n }\n\n if (opts.json) {\n console.log(JSON.stringify(rows, null, 2));\n return;\n }\n\n if (rows.length === 0) {\n console.log('No extensions found.');\n return;\n }\n\n console.log(`xopc-store: ${marketplace.getExtensionMarketplaceStoreBaseUrl()}`);\n console.log('');\n for (const e of rows) {\n const badge = e.verified ? ` ${colors.green('✓')}` : '';\n console.log(`${colors.cyan(e.name)}${badge} ${colors.gray(e.version ?? '')}`);\n console.log(` id: ${e.id} npm: ${e.npmPackage}`);\n if (e.description) console.log(` ${e.description}`);\n if (e.categories?.length) console.log(` categories: ${e.categories.join(', ')}`);\n console.log('');\n }\n } catch (err) {\n console.error(colors.red('Error:'), err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n}\n\nexport function createExtensionPublishCommand(): Command {\n return new Command('publish')\n .description('Publish extension to npm (public)')\n .argument('[directory]', 'Extension root', '.')\n .option('--dry-run', 'npm publish --dry-run', false)\n .option('--access <level>', 'npm access', 'public')\n .action((dir: string, opts: { dryRun: boolean; access: string }) => {\n const root = resolve(dir || '.');\n const manifestPath = join(root, MANIFEST);\n const pkgPath = join(root, 'package.json');\n if (!existsSync(manifestPath) || !existsSync(pkgPath)) {\n console.error(colors.red('error:'), `Need ${MANIFEST} and package.json in ${root}`);\n process.exit(1);\n }\n const validation = validateExtensionPackageDirectory(root);\n for (const d of validation.diagnostics) {\n const label = d.level === 'error' ? colors.red('error') : d.level === 'warning' ? colors.yellow('warning') : colors.cyan('info');\n console.log(`${label}:`, d.message);\n }\n if (!validation.ok || !validation.manifest?.id) {\n console.error(colors.red('error:'), 'Package is not publishable as an independent extension.');\n process.exit(1);\n }\n\n const args = ['publish', `--access=${opts.access}`];\n if (opts.dryRun) args.push('--dry-run');\n console.log(colors.cyan('Running:'), `npm ${args.join(' ')}`);\n try {\n execSync(`npm ${args.join(' ')}`, { cwd: root, stdio: 'inherit' });\n } catch {\n process.exit(1);\n }\n });\n}\n\nexport function createExtensionUpdateCommand(): Command {\n return new Command('update')\n .description('Re-install extension(s) from the lockfile (npm or xopc-store) under ~/.xopc/extensions')\n .argument('[extensionId]', 'Specific extension id (default: all in lockfile)')\n .action(async (extensionId: string | undefined) => {\n const ctx = getContextWithOpts();\n const cfg = loadConfig(ctx.configPath);\n const targetDir = resolveExtensionsDir();\n const storeBase = resolveExtensionsStoreBaseUrl(cfg);\n\n const lock = getExtensionLockfileManager();\n const data = await lock.load();\n const ids = extensionId?.trim()\n ? [extensionId.trim()]\n : Object.keys(data.extensions);\n\n if (ids.length === 0) {\n console.log('No extensions in lockfile.');\n return;\n }\n\n for (const id of ids) {\n const entry = data.extensions[id];\n if (!entry) {\n console.log(colors.yellow('skip'), id, '(not in lockfile)');\n continue;\n }\n if (entry.source === 'store') {\n const pkgName = entry.resolved?.trim() || id;\n console.log(colors.cyan('Updating'), id, '←', `store:${pkgName}`);\n if (existsSync(join(targetDir, id))) {\n rmSync(join(targetDir, id), { recursive: true, force: true });\n }\n const r = await installExtensionFromStoreWithLock({\n storeBase,\n packageName: pkgName,\n targetDir,\n lock,\n yes: true,\n });\n if (r.ok === false) {\n console.error(colors.red('error:'), r.error ?? id);\n process.exit(1);\n }\n console.log(colors.green('✓'), id);\n continue;\n }\n if (entry.source !== 'npm') {\n console.log(colors.yellow('skip'), id, `(source ${entry.source})`);\n continue;\n }\n const spec = entry.resolved?.trim() || (await npmPackageForId(id));\n if (!spec) {\n console.log(colors.yellow('skip'), id, '(could not resolve npm package)');\n continue;\n }\n console.log(colors.cyan('Updating'), id, '←', spec);\n if (existsSync(join(targetDir, id))) {\n rmSync(join(targetDir, id), { recursive: true, force: true });\n }\n const result = await installFromNpm(spec, targetDir);\n if (!result.ok) {\n console.error(colors.red('error:'), result.error ?? id);\n process.exit(1);\n }\n await lock.upsert(id, {\n name: id,\n version: entry.version,\n resolved: spec,\n source: 'npm',\n ...readInstalledSnapshots(targetDir, id),\n });\n console.log(colors.green('✓'), id);\n }\n });\n}\n\nasync function npmPackageForId(id: string): Promise<string | undefined> {\n const found = await marketplace.findExtension(id);\n return found?.npmPackage;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"extension-marketplace.js","names":["marketplace.findExtension","marketplace.listExtensions","marketplace.searchExtensions","marketplace.fetchRegistry","marketplace.getExtensionMarketplaceStoreBaseUrl"],"sources":["../../../../src/cli/commands/extension-marketplace.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport { execSync } from 'node:child_process';\nimport { existsSync, readFileSync, statSync, rmSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\n\nimport { confirm } from '@inquirer/prompts';\nimport { Command } from 'commander';\nimport semver from 'semver';\n\nimport {\n downloadExtensionStoreZipBuffer,\n resolveExtensionZipDownloadUrl,\n resolveExtensionsStoreBaseUrl,\n verifyStoreArtifactSha256,\n} from '../../agent/skills/marketplace/adapters/store/store-api-client.js';\nimport { loadConfig } from '../../config/loader.js';\nimport { resolveExtensionsDir } from '../../config/paths.js';\nimport type { InstallResult } from '../../extensions/install.js';\nimport {\n installFromLocal,\n installFromNpm,\n peekExtensionManifestFromStoreZip,\n} from '../../extensions/install.js';\nimport {\n commitStagedExtensionInstall,\n finalizeStagedExtensionInstall,\n rollbackStagedExtensionInstall,\n stageExtensionStoreZip,\n} from '../../extensions/install-transaction.js';\nimport { getExtensionLockfileManager } from '../../extensions/lockfile.js';\nimport * as marketplace from '../../extensions/marketplace.js';\nimport { colors } from '../utils/colors.js';\nimport { getContextWithOpts } from '../context.js';\nimport { validateExtensionPackageDirectory } from './extension-pack.js';\n\nconst MANIFEST = 'xopc.extension.json';\n\nfunction readJsonObject(path: string): Record<string, unknown> | undefined {\n try {\n const raw = JSON.parse(readFileSync(path, 'utf-8')) as unknown;\n return typeof raw === 'object' && raw !== null && !Array.isArray(raw)\n ? (raw as Record<string, unknown>)\n : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction readInstalledSnapshots(targetDir: string, extensionId: string): {\n manifest?: Record<string, unknown>;\n packageJson?: Record<string, unknown>;\n} {\n const root = join(targetDir, extensionId);\n return {\n manifest: readJsonObject(join(root, MANIFEST)),\n packageJson: readJsonObject(join(root, 'package.json')),\n };\n}\n\nfunction sha256Integrity(buffer: Buffer): string {\n return `sha256-${createHash('sha256').update(buffer).digest('base64')}`;\n}\n\nfunction printManifestSummary(params: {\n source: 'store' | 'npm' | 'local';\n packageName: string;\n version?: string;\n integrity?: string;\n manifest?: Record<string, unknown>;\n}): void {\n const manifest = params.manifest;\n console.log('');\n console.log(colors.cyan('Extension install review'));\n console.log(` Source: ${params.source}`);\n console.log(` Package: ${params.packageName}${params.version ? `@${params.version}` : ''}`);\n if (params.integrity) console.log(` Integrity: ${params.integrity}`);\n if (manifest) {\n console.log(` ID: ${String(manifest.id ?? '(unknown)')}`);\n console.log(` Name: ${String(manifest.name ?? manifest.id ?? '(unknown)')}`);\n const engines = manifest.engines as Record<string, unknown> | undefined;\n if (engines?.xopc) console.log(` engines.xopc: ${String(engines.xopc)}`);\n const permissions = manifest.permissions as Record<string, unknown> | undefined;\n if (permissions) {\n console.log(' Permissions:');\n for (const [key, value] of Object.entries(permissions)) {\n console.log(` ${key}: ${Array.isArray(value) ? value.join(', ') : String(value)}`);\n }\n }\n const contracts = manifest.contracts as Record<string, unknown> | undefined;\n if (contracts) {\n console.log(' Contracts:');\n for (const [key, value] of Object.entries(contracts)) {\n if (Array.isArray(value) && value.length > 0) console.log(` ${key}: ${value.join(', ')}`);\n }\n }\n }\n console.log('');\n}\n\nasync function confirmInstall(params: Parameters<typeof printManifestSummary>[0] & { yes?: boolean }): Promise<boolean> {\n printManifestSummary(params);\n if (params.yes || !process.stdin.isTTY) return true;\n return await confirm({ message: 'Install this extension?', default: false });\n}\n\nfunction parseNameAtVersion(raw: string): { name: string; version?: string } {\n const t = raw.trim();\n const at = t.lastIndexOf('@');\n if (at <= 0 || at === t.length - 1) return { name: t };\n const maybeVer = t.slice(at + 1);\n const v = semver.valid(maybeVer);\n if (v) return { name: t.slice(0, at), version: v };\n return { name: t };\n}\n\nfunction looksLikeLocalPath(raw: string): boolean {\n const p = raw.trim();\n if (p.startsWith('./') || p.startsWith('../')) return true;\n if (p === '.' || p === '..') return true;\n try {\n const abs = resolve(process.cwd(), p);\n return existsSync(abs) && statSync(abs).isDirectory();\n } catch {\n return false;\n }\n}\n\n/** xopc-store package names: lowercase letters, digits, hyphen (see xopc-store scan). */\nconst STORE_NAME_RE = /^[a-z0-9-]{1,64}$/;\n\nasync function upsertNpmExtensionLock(\n lock: ReturnType<typeof getExtensionLockfileManager>,\n targetDir: string,\n result: InstallResult,\n spec: string,\n): Promise<void> {\n if (!result.extensionId) return;\n const reg = await marketplace.findExtension(result.extensionId);\n const resolved = reg?.npmPackage ?? spec;\n let ver = reg?.version ?? '0.0.0';\n try {\n const raw = readFileSync(join(targetDir, result.extensionId, MANIFEST), 'utf-8');\n const m = JSON.parse(raw) as { version?: string };\n const mv = typeof m.version === 'string' ? semver.valid(m.version) : null;\n if (mv) ver = mv;\n } catch {\n /* keep registry / fallback version */\n }\n await lock.upsert(result.extensionId, {\n name: result.extensionId,\n version: ver,\n resolved,\n source: 'npm',\n ...readInstalledSnapshots(targetDir, result.extensionId),\n });\n}\n\nasync function installExtensionFromStoreWithLock(params: {\n storeBase: string;\n packageName: string;\n version?: string;\n targetDir: string;\n lock: ReturnType<typeof getExtensionLockfileManager>;\n force?: boolean;\n yes?: boolean;\n}): Promise<{ ok: true; extensionId: string; version: string } | { ok: false; error: string }> {\n try {\n const { downloadUrl, version, sha256 } = await resolveExtensionZipDownloadUrl(\n params.storeBase,\n params.packageName,\n params.version,\n );\n console.log(\n colors.cyan('📦'),\n `Downloading ${params.packageName}@${version} from xopc-store (${params.storeBase})…`,\n );\n const buf = await downloadExtensionStoreZipBuffer(params.storeBase, downloadUrl);\n verifyStoreArtifactSha256(buf, sha256);\n const actualIntegrity = sha256Integrity(buf);\n const manifest = peekExtensionManifestFromStoreZip(buf);\n const accepted = await confirmInstall({\n source: 'store',\n packageName: params.packageName,\n version,\n integrity: actualIntegrity,\n manifest,\n yes: params.yes,\n });\n if (!accepted) {\n return { ok: false, error: 'Install cancelled' };\n }\n\n const transaction = await stageExtensionStoreZip(buf, params.targetDir);\n const lockSnapshot = await params.lock.load();\n let lockWriteStarted = false;\n try {\n commitStagedExtensionInstall(transaction, params.force ?? false);\n lockWriteStarted = true;\n await params.lock.upsert(transaction.extensionId, {\n name: transaction.extensionId,\n version,\n resolved: params.packageName,\n source: 'store',\n artifactUrl: downloadUrl,\n integrity: actualIntegrity,\n ...readInstalledSnapshots(params.targetDir, transaction.extensionId),\n });\n } catch (err) {\n const rollbackErrors: string[] = [];\n try {\n rollbackStagedExtensionInstall(transaction);\n } catch (rollbackErr) {\n rollbackErrors.push(`files: ${rollbackErr instanceof Error ? rollbackErr.message : String(rollbackErr)}`);\n }\n if (lockWriteStarted) {\n try {\n await params.lock.save(lockSnapshot);\n } catch (rollbackErr) {\n rollbackErrors.push(`lockfile: ${rollbackErr instanceof Error ? rollbackErr.message : String(rollbackErr)}`);\n }\n }\n const message = err instanceof Error ? err.message : String(err);\n const suffix = rollbackErrors.length > 0\n ? ` Rollback incomplete (${rollbackErrors.join('; ')}).`\n : '';\n throw new Error(`${message}${suffix}`, { cause: err });\n }\n\n try {\n finalizeStagedExtensionInstall(transaction);\n } catch (cleanupErr) {\n const message = cleanupErr instanceof Error ? cleanupErr.message : String(cleanupErr);\n console.warn(colors.yellow('warning:'), `Installed extension, but temporary backup cleanup failed: ${message}`);\n }\n return { ok: true, extensionId: transaction.extensionId, version };\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n return { ok: false, error: msg };\n }\n}\n\nexport function createExtensionInstallCommand(): Command {\n return new Command('install')\n .description(\n 'Install extension from xopc-store (store.xopc.ai), npm, or a local directory into ~/.xopc/extensions',\n )\n .argument(\n '<target>',\n 'Explicit source spec: store:<id>, npm:<package>, or a local extension directory',\n )\n .option(\n '-f, --force',\n 'Replace an existing store or local extension with the same manifest id',\n false,\n )\n .option('-y, --yes', 'Skip interactive install confirmation', false)\n .action(\n async (\n target: string,\n opts: { force: boolean; yes: boolean },\n ) => {\n const ctx = getContextWithOpts();\n const cfg = loadConfig(ctx.configPath);\n const targetDir = resolveExtensionsDir();\n const lock = getExtensionLockfileManager();\n\n let installTarget = target.trim();\n const storeExplicit = /^store:/i.test(installTarget);\n const npmExplicit = /^npm:/i.test(installTarget);\n if (storeExplicit) {\n installTarget = installTarget.replace(/^store:/i, '').trim();\n } else if (npmExplicit) {\n installTarget = installTarget.replace(/^npm:/i, '').trim();\n }\n if (!installTarget) {\n console.error(colors.red('error:'), 'Missing target');\n process.exit(1);\n }\n\n const storeBase = resolveExtensionsStoreBaseUrl(cfg);\n\n if (storeExplicit) {\n const { name: pkgName, version: ver } = parseNameAtVersion(installTarget);\n if (!STORE_NAME_RE.test(pkgName)) {\n console.error(\n colors.red('error:'),\n 'Invalid store package name (lowercase letters, digits, hyphen only)',\n );\n process.exit(1);\n }\n const r = await installExtensionFromStoreWithLock({\n storeBase,\n packageName: pkgName,\n version: ver,\n targetDir,\n lock,\n force: opts.force,\n yes: opts.yes,\n });\n if (r.ok === false) {\n console.error(colors.red('error:'), r.error);\n process.exit(1);\n }\n console.log(colors.green('✓'), `${r.extensionId}@${r.version} (store)`);\n return;\n }\n\n if (npmExplicit) {\n const spec = installTarget;\n console.log(colors.cyan('📦'), `Installing from npm: ${spec}…`);\n const result = await installFromNpm(spec, targetDir);\n if (!result.ok) {\n console.error(colors.red('error:'), result.error ?? 'install failed');\n process.exit(1);\n }\n await upsertNpmExtensionLock(lock, targetDir, result, spec);\n console.log(colors.green('✓'), result.extensionId ?? 'ok', '(npm)');\n return;\n }\n\n if (looksLikeLocalPath(installTarget)) {\n const sourceDir = resolve(process.cwd(), installTarget);\n if (opts.force) {\n const manifestPath = join(sourceDir, MANIFEST);\n if (existsSync(manifestPath)) {\n try {\n const raw = readFileSync(manifestPath, 'utf-8');\n const m = JSON.parse(raw) as { id?: string };\n const extId =\n typeof m.id === 'string' &&\n m.id &&\n !m.id.includes('/') &&\n !m.id.includes('\\\\')\n ? m.id\n : undefined;\n if (extId && existsSync(join(targetDir, extId))) {\n rmSync(join(targetDir, extId), { recursive: true, force: true });\n }\n } catch {\n /* installFromLocal will surface manifest errors */\n }\n }\n }\n console.log(colors.cyan('📂'), 'Installing from local directory…');\n const result = await installFromLocal(sourceDir, targetDir);\n if (!result.ok) {\n console.error(colors.red('error:'), result.error ?? 'install failed');\n process.exit(1);\n }\n console.log(colors.green('✓'), result.extensionId ?? 'ok');\n return;\n }\n\n console.error(\n colors.red('error:'),\n 'Extension installs require an explicit source: store:<id>, npm:<package>, or a local directory path.',\n );\n process.exit(1);\n },\n );\n}\n\nexport function createExtensionSearchCommand(): Command {\n return new Command('search')\n .description('Search extensions listed on xopc-store')\n .argument('[keyword]', 'Search text (omit to list all)', '')\n .option('--category <cat>', 'Filter by category')\n .option('--json', 'JSON output')\n .action(async (keyword: string, opts: { category?: string; json?: boolean }) => {\n try {\n let rows;\n if (opts.category?.trim()) {\n rows = await marketplace.listExtensions(opts.category.trim());\n if (keyword.trim()) {\n const k = keyword.trim().toLowerCase();\n rows = rows.filter(\n (e) =>\n e.id.toLowerCase().includes(k) ||\n e.name.toLowerCase().includes(k) ||\n (e.description ?? '').toLowerCase().includes(k),\n );\n }\n } else if (keyword.trim()) {\n rows = await marketplace.searchExtensions(keyword.trim());\n } else {\n const reg = await marketplace.fetchRegistry();\n rows = reg.extensions;\n }\n\n if (opts.json) {\n console.log(JSON.stringify(rows, null, 2));\n return;\n }\n\n if (rows.length === 0) {\n console.log('No extensions found.');\n return;\n }\n\n console.log(`xopc-store: ${marketplace.getExtensionMarketplaceStoreBaseUrl()}`);\n console.log('');\n for (const e of rows) {\n const badge = e.verified ? ` ${colors.green('✓')}` : '';\n console.log(`${colors.cyan(e.name)}${badge} ${colors.gray(e.version ?? '')}`);\n console.log(` id: ${e.id} npm: ${e.npmPackage}`);\n if (e.description) console.log(` ${e.description}`);\n if (e.categories?.length) console.log(` categories: ${e.categories.join(', ')}`);\n console.log('');\n }\n } catch (err) {\n console.error(colors.red('Error:'), err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n}\n\nexport function createExtensionPublishCommand(): Command {\n return new Command('publish')\n .description('Publish extension to npm (public)')\n .argument('[directory]', 'Extension root', '.')\n .option('--dry-run', 'npm publish --dry-run', false)\n .option('--access <level>', 'npm access', 'public')\n .action((dir: string, opts: { dryRun: boolean; access: string }) => {\n const root = resolve(dir || '.');\n const manifestPath = join(root, MANIFEST);\n const pkgPath = join(root, 'package.json');\n if (!existsSync(manifestPath) || !existsSync(pkgPath)) {\n console.error(colors.red('error:'), `Need ${MANIFEST} and package.json in ${root}`);\n process.exit(1);\n }\n const validation = validateExtensionPackageDirectory(root);\n for (const d of validation.diagnostics) {\n const label = d.level === 'error' ? colors.red('error') : d.level === 'warning' ? colors.yellow('warning') : colors.cyan('info');\n console.log(`${label}:`, d.message);\n }\n if (!validation.ok || !validation.manifest?.id) {\n console.error(colors.red('error:'), 'Package is not publishable as an independent extension.');\n process.exit(1);\n }\n\n const args = ['publish', `--access=${opts.access}`];\n if (opts.dryRun) args.push('--dry-run');\n console.log(colors.cyan('Running:'), `npm ${args.join(' ')}`);\n try {\n execSync(`npm ${args.join(' ')}`, { cwd: root, stdio: 'inherit' });\n } catch {\n process.exit(1);\n }\n });\n}\n\nexport function createExtensionUpdateCommand(): Command {\n return new Command('update')\n .description('Re-install extension(s) from the lockfile (npm or xopc-store) under ~/.xopc/extensions')\n .argument('[extensionId]', 'Specific extension id (default: all in lockfile)')\n .action(async (extensionId: string | undefined) => {\n const ctx = getContextWithOpts();\n const cfg = loadConfig(ctx.configPath);\n const targetDir = resolveExtensionsDir();\n const storeBase = resolveExtensionsStoreBaseUrl(cfg);\n\n const lock = getExtensionLockfileManager();\n const data = await lock.load();\n const ids = extensionId?.trim()\n ? [extensionId.trim()]\n : Object.keys(data.extensions);\n\n if (ids.length === 0) {\n console.log('No extensions in lockfile.');\n return;\n }\n\n for (const id of ids) {\n const entry = data.extensions[id];\n if (!entry) {\n console.log(colors.yellow('skip'), id, '(not in lockfile)');\n continue;\n }\n if (entry.source === 'store') {\n const pkgName = entry.resolved?.trim() || id;\n console.log(colors.cyan('Updating'), id, '←', `store:${pkgName}`);\n if (existsSync(join(targetDir, id))) {\n rmSync(join(targetDir, id), { recursive: true, force: true });\n }\n const r = await installExtensionFromStoreWithLock({\n storeBase,\n packageName: pkgName,\n targetDir,\n lock,\n yes: true,\n });\n if (r.ok === false) {\n console.error(colors.red('error:'), r.error ?? id);\n process.exit(1);\n }\n console.log(colors.green('✓'), id);\n continue;\n }\n if (entry.source !== 'npm') {\n console.log(colors.yellow('skip'), id, `(source ${entry.source})`);\n continue;\n }\n const spec = entry.resolved?.trim() || (await npmPackageForId(id));\n if (!spec) {\n console.log(colors.yellow('skip'), id, '(could not resolve npm package)');\n continue;\n }\n console.log(colors.cyan('Updating'), id, '←', spec);\n if (existsSync(join(targetDir, id))) {\n rmSync(join(targetDir, id), { recursive: true, force: true });\n }\n const result = await installFromNpm(spec, targetDir);\n if (!result.ok) {\n console.error(colors.red('error:'), result.error ?? id);\n process.exit(1);\n }\n await lock.upsert(id, {\n name: id,\n version: entry.version,\n resolved: spec,\n source: 'npm',\n ...readInstalledSnapshots(targetDir, id),\n });\n console.log(colors.green('✓'), id);\n }\n });\n}\n\nasync function npmPackageForId(id: string): Promise<string | undefined> {\n const found = await marketplace.findExtension(id);\n return found?.npmPackage;\n}\n"],"mappings":"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"}
|
|
@@ -12,4 +12,10 @@ export interface ExtensionPackageValidationResult {
|
|
|
12
12
|
ok: boolean;
|
|
13
13
|
}
|
|
14
14
|
export declare function validateExtensionPackageDirectory(dir: string): ExtensionPackageValidationResult;
|
|
15
|
+
export declare function writeStoreReadyArtifact(params: {
|
|
16
|
+
extensionDir: string;
|
|
17
|
+
outDir: string;
|
|
18
|
+
manifest: ExtensionManifest;
|
|
19
|
+
packageJson: Record<string, unknown>;
|
|
20
|
+
}): string;
|
|
15
21
|
export declare function createExtensionPackCommand(): Command;
|