@xopcai/xopc 0.0.142 → 0.0.144
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/feishu/src/workflow-progress.js +1 -1
- package/dist/extensions/telegram/src/adapters/streaming-adapter.js +1 -1
- package/dist/extensions/telegram/src/inbound-processor.js +1 -1
- package/dist/extensions/telegram/src/plugin.js +1 -1
- package/dist/extensions/telegram/src/routing-integration.js +2 -2
- package/dist/extensions/telegram/src/workflow-progress.js +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/extensions/weixin/src/api/api.js +1 -1
- package/dist/extensions/weixin/src/plugin.js +1 -1
- package/dist/extensions/weixin/src/workflow-progress.js +1 -1
- package/dist/gateway/static/root/assets/activity-center-store-jITiX2vJ.js +1 -0
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BawPxiu5.js → agent-avatar-dicebear-EAVnrCAs.js} +1 -1
- package/dist/gateway/static/root/assets/agents-5rTuJOtT.js +2 -0
- package/dist/gateway/static/root/assets/{app-management-settings-panel-81xd1p9R.js → app-management-settings-panel-Bu568NpC.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-DYeQsYU8.js → appearance-settings-DSkm9bp_.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-DWetalKp.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-D_oa7oti.js → archive-plugin-C99N0vV6.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-Cd-bwI2N.js → attachment-load-CHTDqME5.js} +1 -1
- package/dist/gateway/static/root/assets/automation-suggestion-card-CBt6U3-S.js +1 -0
- package/dist/gateway/static/root/assets/automations-page-ICUfxeOz.js +4 -0
- package/dist/gateway/static/root/assets/{binary-plugins-O8svLKWw.js → binary-plugins-BRtxOLlM.js} +1 -1
- package/dist/gateway/static/root/assets/block-editor-CUlXfgXd.js +184 -0
- package/dist/gateway/static/root/assets/browser-settings-page-D7Bj4MKi.js +8 -0
- package/dist/gateway/static/root/assets/{capability-presets-api-dJy1Eqgx.js → capability-presets-api-Bg1ntFSD.js} +1 -1
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-C-8I-Ktn.js +2 -0
- package/dist/gateway/static/root/assets/{channel-recipient-api-Bfuhp2ty.js → channel-recipient-api-DuulnhIj.js} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-Dm5EqQyK.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-BOzjh-OK.js +2 -0
- package/dist/gateway/static/root/assets/{desktop-pet-DFMfIb5F.js → desktop-pet-C-Drhqyk.js} +1 -1
- package/dist/gateway/static/root/assets/desktop-pet-settings-CRGiolqF.js +1 -0
- package/dist/gateway/static/root/assets/{directory-picker-path-field-BrYt1gAr.js → directory-picker-path-field-Dw1L3M84.js} +1 -1
- package/dist/gateway/static/root/assets/dist-SwiI0Xu3.js +1 -0
- package/dist/gateway/static/root/assets/dreaming-settings-CF21cbjo.js +3 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-Bh630pLD.js → extension-debug-page-Dcl8LJG_.js} +1 -1
- package/dist/gateway/static/root/assets/extension-page-i_BXmO_x.js +1 -0
- package/dist/gateway/static/root/assets/extension-settings-page-CWIi7xsn.js +1 -0
- package/dist/gateway/static/root/assets/{fetch-B1WtuprY.js → fetch-8QNN25Sh.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-De2N821l.js → gateway-config-api-2sLP2kkA.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-settings-DMHiZc-2.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-nEujFSDj.js → gateway-startup-retry-5YBnS9Fj.js} +1 -1
- package/dist/gateway/static/root/assets/goal-create-dialog-CAODVDiA.js +1 -0
- package/dist/gateway/static/root/assets/goal-detail-page-_d4DjmeX.js +4 -0
- package/dist/gateway/static/root/assets/{goals-config-api-DUy3eEse.js → goals-config-api-B4qeLKQS.js} +1 -1
- package/dist/gateway/static/root/assets/goals-page-lgsop664.js +2 -0
- package/dist/gateway/static/root/assets/goals-settings-Dx_1ZNgb.js +1 -0
- package/dist/gateway/static/root/assets/heartbeat-settings-DeTseEk_.js +1 -0
- package/dist/gateway/static/root/assets/index-CphxClbs.css +1 -0
- package/dist/gateway/static/root/assets/index-VWvztcst.js +257 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-CVIwwM15.js → keyboard-shortcuts-settings-BpwpMmlk.js} +1 -1
- package/dist/gateway/static/root/assets/logs-page-9_hbTg3j.js +7 -0
- package/dist/gateway/static/root/assets/{markdown-split-B_6us9j7.js → markdown-split-BTRFTK0w.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-D_fryIyj.js → media-plugins-BABfIZPU.js} +1 -1
- package/dist/gateway/static/root/assets/messages-CzKxM6I4.js +5 -0
- package/dist/gateway/static/root/assets/models-hub-panel-B1CUvZxh.js +2 -0
- package/dist/gateway/static/root/assets/notes-page-88QBHW9a.js +1 -0
- package/dist/gateway/static/root/assets/notes-workbench-CerZOeLW.js +2 -0
- package/dist/gateway/static/root/assets/{page-tabs-D_8jGlqx.js → page-tabs-je95DZOf.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-BBLMK8Mp.js → preview-open-alternatives-BJbwi7Rc.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-BmrApldl.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-tTn-k76N.js +1 -0
- package/dist/gateway/static/root/assets/remote-access-hub-DeA2-pOi.js +1 -0
- package/dist/gateway/static/root/assets/{save-bar-controls-DVS3FR5r.js → save-bar-controls-qWMQ9mod.js} +1 -1
- package/dist/gateway/static/root/assets/{schedule-field-D6vKd6-T.js → schedule-field-kxd270Gs.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-BPy4lbIh.js → schema-form-DLnD-MuD.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-D4kvvcL1.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-CI1OG4gq.js +1 -0
- package/dist/gateway/static/root/assets/{settings-collapsible-section-WzdikxPt.js → settings-collapsible-section-DQprvu5J.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-form-section-CvfzhBV-.js → settings-form-section-Cqq7Y98y.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-loading-skeleton-BxR-Ulhi.js → settings-loading-skeleton-b6rXULL5.js} +1 -1
- package/dist/gateway/static/root/assets/settings-page-BtBVz3cX.js +1 -0
- package/dist/gateway/static/root/assets/{settings-page-layout-CKefvbYi.js → settings-page-layout-BNJbtklV.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-cmclUJzS.js +1 -0
- package/dist/gateway/static/root/assets/share-preview-page--zO-A1W1.js +2 -0
- package/dist/gateway/static/root/assets/shares-settings-DNJvqA67.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-DWr_0Xgn.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-DEGsTbJx.js +2 -0
- package/dist/gateway/static/root/assets/{system-settings-panel-BokgAgf7.js → system-settings-panel-Cq9J7i7v.js} +1 -1
- package/dist/gateway/static/root/assets/{typed-models-lib-BwHlNL3L.js → typed-models-lib-CdSwi1gT.js} +1 -1
- package/dist/gateway/static/root/assets/{use-channel-catalog-DR11ap3A.js → use-channel-catalog-COXIfXcl.js} +1 -1
- package/dist/gateway/static/root/assets/user-context-page-C-V73ZaJ.js +1 -0
- package/dist/gateway/static/root/assets/user-profile-fields-editor-B1cxoGkh.js +1 -0
- package/dist/gateway/static/root/assets/user-profile-settings-panel-B8hlamVB.js +1 -0
- package/dist/gateway/static/root/assets/{utils-BKUWB-TT.js → utils-Dx01V8qF.js} +1 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-DGpIUelZ.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-fzWTxF26.js +1 -0
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-CL_rnAUB.js → workflow-run-setup-panel-Dt_x8LGg.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-Bg02zEUh.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 +10 -7
- package/dist/package.js +1 -1
- package/dist/src/activity/emitter.js +1 -1
- package/dist/src/agent/agent-manager.d.ts +2 -0
- package/dist/src/agent/agent-manager.js +12 -4
- 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/code-intelligence/binary.js +1 -1
- package/dist/src/agent/context/project-context.js +2 -2
- package/dist/src/agent/context/workspace-seed.js +2 -2
- package/dist/src/agent/embedded/run-for-session.js +1 -1
- package/dist/src/agent/embedded/session-tool-result-guard.js +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/post-turn.js +7 -6
- package/dist/src/agent/goals/post-turn.js.map +1 -1
- package/dist/src/agent/ipc/bus.js +1 -1
- package/dist/src/agent/mcp/bundle-mcp-materialize.js +1 -1
- package/dist/src/agent/mcp/bundle-mcp-runtime.js +1 -1
- package/dist/src/agent/mcp/mcp-transport-config.js +1 -1
- package/dist/src/agent/mcp/mcp-transport.js +5 -2
- package/dist/src/agent/mcp/mcp-transport.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/plugin-discovery.js +1 -1
- 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/models/manager.js +1 -1
- package/dist/src/agent/orchestration/agent-orchestrator.js +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/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 +12 -6
- package/dist/src/agent/service.js.map +1 -1
- package/dist/src/agent/session/session-inspector.js +2 -2
- package/dist/src/agent/skills/hub-pull.js +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/goal-tool.js +2 -2
- package/dist/src/agent/tools/index.d.ts +1 -1
- package/dist/src/agent/tools/index.js +2 -2
- package/dist/src/agent/tools/workflow-tool.d.ts +0 -1
- package/dist/src/agent/tools/workflow-tool.js +4 -17
- package/dist/src/agent/tools/workflow-tool.js.map +1 -1
- package/dist/src/agent/tools/xopc-use-tool.js +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/workspace-runtime/registry.js +2 -2
- 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/automations/api/routes.js +14 -2
- 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-validator.d.ts +3 -3
- package/dist/src/automations/service/action-executor.js +2 -2
- package/dist/src/browser/cdp-local-launcher.js +1 -1
- package/dist/src/browser/providers/browser-ext-install.d.ts +11 -1
- package/dist/src/browser/providers/browser-ext-install.js +42 -17
- package/dist/src/browser/providers/browser-ext-install.js.map +1 -1
- package/dist/src/browser/providers/cloakbrowser.js +2 -2
- package/dist/src/browser/providers/playwright-doctor.js +1 -1
- package/dist/src/browser/stealth.js +1 -1
- package/dist/src/capabilities/store-connector.d.ts +0 -1
- package/dist/src/capabilities/store-connector.js +4 -6
- package/dist/src/capabilities/store-connector.js.map +1 -1
- package/dist/src/chat-commands/agent-edit.js +1 -1
- package/dist/src/chat-commands/builtins/config.js +1 -1
- package/dist/src/chat-commands/builtins/goal.js +2 -2
- package/dist/src/chat-commands/builtins/review.js +72 -73
- 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/context.js +1 -1
- package/dist/src/cli/commands/agent.js +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +2 -2
- package/dist/src/cli/commands/doctor/checks/session-integrity.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 +43 -37
- 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 +4 -3
- package/dist/src/cli/commands/extension-pack.js.map +1 -1
- package/dist/src/cli/commands/goal.js +2 -2
- package/dist/src/cli/commands/init.js +1 -1
- package/dist/src/cli/commands/project.js +3 -3
- 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/gateway-bind.js +1 -1
- package/dist/src/config/index.js +1 -1
- package/dist/src/config/loader.js +1 -1
- package/dist/src/config/models-json.js +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/daemon/launchd.js +1 -1
- package/dist/src/daemon/systemd.js +1 -1
- package/dist/src/extensions/discover-extensions.js +1 -1
- 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/extensions/loader.js +2 -2
- 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/lib/static-ui.js +1 -1
- 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 +17 -4
- package/dist/src/gateway/hono/routes/memory.js.map +1 -1
- package/dist/src/gateway/hono/routes/projects.js +106 -5
- 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/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/lock.js +1 -1
- package/dist/src/gateway/ports.js +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 +13 -7
- package/dist/src/gateway/service.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/goal-workflow-judge.js +1 -1
- package/dist/src/goals/types.d.ts +24 -0
- package/dist/src/infra/ports.js +1 -1
- package/dist/src/infra/ssh-tunnel.js +1 -1
- package/dist/src/infra/update-check.js +1 -1
- package/dist/src/migrations/runner.js +1 -1
- package/dist/src/notes/service.js +3 -3
- package/dist/src/notes/store.js +1 -1
- package/dist/src/projects/project-service.js +1 -1
- package/dist/src/projects/workspace.js +1 -1
- package/dist/src/routing/agent-session-key.js +1 -1
- package/dist/src/routing/resolve-route.js +1 -1
- package/dist/src/routing/resolve-tui-session-key.js +1 -1
- package/dist/src/session/init-session-turn.js +1 -1
- package/dist/src/session/resolve-session.js +1 -1
- package/dist/src/session/session-title.js +2 -2
- package/dist/src/session/store.js +1 -1
- package/dist/src/storage/sqlite/connection.js +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/row-mappers.js +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/backends/embedded-backend.js +4 -4
- package/dist/src/tui/clipboard-image.js +1 -1
- 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 +9 -9
- package/dist/src/tui/tui-command-formatters.js.map +1 -1
- package/dist/src/tui/tui-commands.js +4 -4
- package/dist/src/tui/tui-startup-resources.js +1 -1
- package/dist/src/tui/tui.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/utils/index.js +1 -1
- package/dist/src/utils/logger/index.js +1 -1
- package/dist/src/utils/logger.js +1 -1
- package/dist/src/work-items/work-item-service.js +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 +5 -9
- 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/dist/src/workflows/service/workflow-session-bridge.js +3 -3
- package/package.json +5 -4
- package/dist/gateway/static/root/assets/agents-CyvCIHnB.js +0 -2
- package/dist/gateway/static/root/assets/apps-page-DK_Vx6nl.js +0 -1
- package/dist/gateway/static/root/assets/automation-suggestion-card-B1LV3YYv.js +0 -1
- package/dist/gateway/static/root/assets/automations-page-fzrovqhv.js +0 -4
- package/dist/gateway/static/root/assets/block-editor-Dhj5f4Bx.js +0 -184
- package/dist/gateway/static/root/assets/browser-settings-page-BDn-n-UB.js +0 -8
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-Co5ipo_Q.js +0 -1
- package/dist/gateway/static/root/assets/channels-settings-BWlpaxg9.js +0 -1
- package/dist/gateway/static/root/assets/channels-status-swr-D_jkIZLV.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-BcekbW4q.js +0 -2
- package/dist/gateway/static/root/assets/desktop-pet-settings-BJCUuL8Y.js +0 -1
- package/dist/gateway/static/root/assets/dist-Mys7eFJ5.js +0 -1
- package/dist/gateway/static/root/assets/dreaming-settings-BN1Z2mIo.js +0 -3
- package/dist/gateway/static/root/assets/extension-page-B-1KxvVy.js +0 -1
- package/dist/gateway/static/root/assets/extension-settings-page-BF9NACI3.js +0 -1
- package/dist/gateway/static/root/assets/gateway-settings-DN9sNREz.js +0 -1
- package/dist/gateway/static/root/assets/goal-create-dialog-BpoQW8cD.js +0 -1
- package/dist/gateway/static/root/assets/goal-detail-page-CBRSPd0b.js +0 -4
- package/dist/gateway/static/root/assets/goals-page-BCcBi407.js +0 -2
- package/dist/gateway/static/root/assets/goals-settings-pkTXzXkh.js +0 -1
- package/dist/gateway/static/root/assets/heartbeat-settings-ezsufgLQ.js +0 -1
- package/dist/gateway/static/root/assets/index-B8s8Pq5U.css +0 -1
- package/dist/gateway/static/root/assets/index-DcUaXYeb.js +0 -262
- package/dist/gateway/static/root/assets/logs-page-DQtTRXtj.js +0 -7
- package/dist/gateway/static/root/assets/messages-BXNELNBa.js +0 -3
- package/dist/gateway/static/root/assets/models-hub-panel-BP2M9n6Q.js +0 -2
- package/dist/gateway/static/root/assets/notes-page-CspveYaO.js +0 -1
- package/dist/gateway/static/root/assets/notes-workbench-BHwzJ0OC.js +0 -2
- package/dist/gateway/static/root/assets/project-detail-page-Dy3rsobs.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-CWKpPE0L.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-CqNRyXEo.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-MEME7ivF.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-JVd0qaSF.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-DYEbB1EV.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-dWN8BJ3z.js +0 -1
- package/dist/gateway/static/root/assets/share-preview-page-D8foINzP.js +0 -2
- package/dist/gateway/static/root/assets/shares-settings-Tgbv1s7G.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-D_YK0b_Z.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-DGytfoZK.js +0 -2
- package/dist/gateway/static/root/assets/toast-z0toXu32.js +0 -1
- package/dist/gateway/static/root/assets/user-profile-settings-panel-8YtygcJp.js +0 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-BVH71EFf.js +0 -1
- package/dist/gateway/static/root/assets/work-item-detail-page-JeTE7XNM.js +0 -1
- package/dist/gateway/static/root/assets/workflow-start-dialog-_u8Uc1ze.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-ixgk_y1l.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 +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":";;;;;;sBAK2D;AAG3D,MAAM,iBAAiB;CAAC;CAAQ;CAAM;CAAY;CAAU;AAG5D,SAAS,cAAc,MAAsB;AAC3C,QAAO,KAAK,MAAM,CAAC,aAAa,CAAC,QAAQ,kBAAkB,IAAI,CAAC,QAAQ,YAAY,GAAG;;AAGzF,SAAS,UAAU,MAAc,OAAsB;AACrD,eAAc,MAAM,GAAG,KAAK,UAAU,OAAO,MAAM,EAAE,CAAC,IAAI;;AAG5D,SAAS,gBAAgB,IAAY,UAAiD;CACpF,MAAM,UAAkC;EACtC,OAAO,aAAa,OAAO,6CAA6C;EACxE,SAAS;EACV;AACD,KAAI,aAAa,KAAM,SAAQ,cAAc;CAC7C,MAAM,kBAA0C;EAC9C,gBAAgB,IAAI;EACpB,YAAY;EACb;AACD,KAAI,aAAa,MAAM;AACrB,kBAAgB,8BAA8B,IAAI;AAClD,kBAAgB,UAAU;;AAE5B,QAAO;EACL,MAAM,kBAAkB;EACxB,SAAS;EACT,MAAM;EACN,MAAM;EACN,OAAO;GAAC;GAAQ;GAAM;GAAuB;GAAa;GAAU;EACpE,UAAU,CAAC,QAAQ,iBAAiB;EACpC,SAAS;EACT;EACA;EACA,kBAAkB,EAChB,gBAAgB,KAAK,gBAAgB,UACtC;EACD,sBAAsB,EACpB,gBAAgB,EAAE,UAAU,MAAM,EACnC;EACF;;AAGH,SAAS,YAAY,IAAY,UAAiD;CAChF,MAAM,OAAgC;EACpC;EACA,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,MAAM,EAAE,IAAI,aAAa,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,KAAK,IAAI;EAC1E,aAAa,QAAQ,SAAS;EAC9B,SAAS;EACT,MAAM,aAAa,aAAa,aAAa,aAAa,YAAY,YAAY,aAAa,SAAS,SAAS;EACjH,MAAM;EACN,SAAS,EAAE,MAAM,KAAK,gBAAgB,UAAU;EACjD;AACD,KAAI,aAAa,OACf,MAAK,YAAY,EAAE,OAAO,CAAC,GAAG,GAAG,QAAQ,MAAM,IAAI,CAAC,OAAO,EAAE;UACpD,aAAa,YAAY;AAClC,OAAK,YAAY,CAAC,GAAG;AACrB,OAAK,YAAY,EAAE,WAAW,CAAC,GAAG,EAAE;YAC3B,aAAa,WAAW;AACjC,OAAK,WAAW,CAAC,GAAG;AACpB,OAAK,YAAY,EAAE,UAAU,CAAC,GAAG,EAAE;AACnC,OAAK,aAAa,EAAE,YAAY,CAAC,GAAG,EAAE;AACtC,OAAK,uBAAuB,GACzB,KAAK;GACJ,OAAO,KAAK;GACZ,aAAa,2BAA2B,KAAK;GAC7C,YAAY,YAAY;GACxB,cAAc;IAAE,cAAc;IAAO,WAAW;IAAO,OAAO;IAAO;GACrE,cAAc;IAAE,MAAM;IAAU,sBAAsB;IAAM;GAC7D,EACF;QACI;AACL,OAAK,YAAY,EAAE;AACnB,OAAK,KAAK;GACR,MAAM;GACN,aAAa,CAAC,QAAQ;GACtB,eAAe,EACb,OAAO,CAAC;IAAE,IAAI,GAAG,GAAG;IAAQ,OAAO,KAAK;IAAM,MAAM;IAAI,YAAY;IAAiB,WAAW;IAAM,CAAC,EACxG;GACF;;AAEH,QAAO;;AAGT,SAAS,sBAA8B;AACrC,QAAO;;AAGT,SAAS,mBAAmB,IAAoB;AAC9C,QAAO,8WAA8W,GAAG,kQAAkQ,GAAG;;AAG/nB,SAAS,UAAU,IAAY,UAAgC;CAC7D,MAAM,WAAW,GAAG,GAAG,QAAQ,MAAM,IAAI,CAAC;AAC1C,KAAI,aAAa,WACf,QAAO,gKAAgK,GAAG,iBAAiB,GAAG;AAEhM,KAAI,aAAa,KACf,QAAO,gJAAgJ,GAAG;AAE5J,KAAI,aAAa,UACf,QAAO,wLAAwL,GAAG,4BAA4B,GAAG,mBAAmB,GAAG,mBAAmB,GAAG;AAE/Q,QAAO,8JAA8J,SAAS;;AAGhL,SAAgB,+BAAwC;AACtD,QAAO,IAAI,QAAQ,SAAS,CACzB,YAAY,6CAA6C,CACzD,SAAS,UAAU,gCAAgC,CACnD,OAAO,qBAAqB,aAAa,eAAe,KAAK,KAAK,IAAI,OAAO,CAC7E,OAAO,gBAAgB,uCAAuC,CAC9D,QAAQ,MAAc,SAA6C;EAClE,MAAM,KAAK,cAAc,KAAK;AAC9B,MAAI,CAAC,IAAI;AACP,WAAQ,MAAM,OAAO,IAAI,SAAS,EAAE,yBAAyB;AAC7D,WAAQ,KAAK,EAAE;;EAEjB,MAAM,WAAW,KAAK;AACtB,MAAI,CAAC,eAAe,SAAS,SAAS,EAAE;AACtC,WAAQ,MAAM,OAAO,IAAI,SAAS,EAAE,qBAAqB,KAAK,WAAW;AACzE,WAAQ,KAAK,EAAE;;EAEjB,MAAM,OAAO,QAAQ,KAAK,KAAK,MAAM,IAAI,GAAG;AAC5C,MAAI,WAAW,KAAK,EAAE;AACpB,WAAQ,MAAM,OAAO,IAAI,SAAS,EAAE,6BAA6B,OAAO;AACxE,WAAQ,KAAK,EAAE;;AAEjB,YAAU,KAAK,MAAM,MAAM,EAAE,EAAE,WAAW,MAAM,CAAC;AACjD,YAAU,KAAK,MAAM,eAAe,EAAE,gBAAgB,IAAI,SAAS,CAAC;AACpE,YAAU,KAAK,MAAM,sBAAsB,EAAE,YAAY,IAAI,SAAS,CAAC;AACvE,YAAU,KAAK,MAAM,gBAAgB,EAAE;GACrC,iBAAiB;IACf,QAAQ;IACR,QAAQ;IACR,kBAAkB;IAClB,aAAa;IACb,QAAQ;IACR,SAAS;IACT,QAAQ;IACR,cAAc;IACf;GACD,SAAS,CAAC,cAAc;GACzB,CAAC;AACF,gBAAc,KAAK,MAAM,OAAO,WAAW,EAAE,UAAU,IAAI,SAAS,CAAC;AACrE,MAAI,aAAa,MAAM;AACrB,aAAU,KAAK,MAAM,KAAK,EAAE,EAAE,WAAW,MAAM,CAAC;AAChD,aAAU,KAAK,MAAM,UAAU,EAAE,EAAE,WAAW,MAAM,CAAC;AACrD,iBAAc,KAAK,MAAM,MAAM,aAAa,EAAE,iIAA0H;AACxK,iBAAc,KAAK,MAAM,MAAM,iBAAiB,EAAE,mBAAmB,GAAG,CAAC;AACzE,iBAAc,KAAK,MAAM,WAAW,eAAe,EAAE,qBAAqB,CAAC;;AAE7E,gBAAc,KAAK,MAAM,YAAY,EAAE,KAAK,GAAG,iCAAiC;AAChF,gBAAc,KAAK,MAAM,UAAU,EAAE,QAAQ;AAC7C,UAAQ,IAAI,OAAO,MAAM,IAAI,EAAE,gCAAgC,OAAO;AACtE,UAAQ,IAAI,OAAO,KAAK,QAAQ,EAAE,MAAM,KAAK,sEAAsE;GACnH"}
|
|
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,16 +1,17 @@
|
|
|
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";
|
|
10
11
|
import { join, resolve } from "node:path";
|
|
11
12
|
import { existsSync, readFileSync, rmSync, statSync } from "node:fs";
|
|
12
|
-
import { execSync } from "node:child_process";
|
|
13
13
|
import { createHash } from "node:crypto";
|
|
14
|
+
import { execSync } from "node:child_process";
|
|
14
15
|
import { confirm } from "@inquirer/prompts";
|
|
15
16
|
import { Command } from "commander";
|
|
16
17
|
import semver from "semver";
|
|
@@ -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;
|
|
@@ -7,8 +7,8 @@ import { collectExtensionPackageDependencyIssues } from "../../extensions/packag
|
|
|
7
7
|
import { colors } from "../utils/colors.js";
|
|
8
8
|
import { basename, join, relative, resolve } from "node:path";
|
|
9
9
|
import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
|
|
10
|
-
import { execSync } from "node:child_process";
|
|
11
10
|
import { createHash } from "node:crypto";
|
|
11
|
+
import { execSync } from "node:child_process";
|
|
12
12
|
import AdmZip from "adm-zip";
|
|
13
13
|
import { Command } from "commander";
|
|
14
14
|
//#region src/cli/commands/extension-pack.ts
|
|
@@ -250,6 +250,7 @@ function writeStoreReadyArtifact(params) {
|
|
|
250
250
|
name: params.manifest.name,
|
|
251
251
|
version,
|
|
252
252
|
artifact: basename(zipPath),
|
|
253
|
+
sha256: sha256Hex,
|
|
253
254
|
integrity,
|
|
254
255
|
manifest: params.manifest,
|
|
255
256
|
packageJson: params.packageJson
|
|
@@ -262,7 +263,7 @@ function printDiagnostics(d) {
|
|
|
262
263
|
else console.log(`${colors.cyan("info")}:`, x.message);
|
|
263
264
|
}
|
|
264
265
|
function createExtensionPackCommand() {
|
|
265
|
-
return new Command("pack").description("Package an extension as a .
|
|
266
|
+
return new Command("pack").description("Package an extension as a store-ready .zip artifact set").argument("[dir]", "Extension directory (default: current working directory)", ".").option("--out <dir>", "Output directory for the artifact set (default: extension directory)", "").option("--no-build-ui", "Skip automatic \"npm run build:ui\" when defined").option("--dry-run", "Validate only; do not create an archive", false).action((dir, opts) => {
|
|
266
267
|
const validation = validateExtensionPackageDirectory(dir || ".");
|
|
267
268
|
const { extensionDir, manifest, packageJson, diagnostics } = validation;
|
|
268
269
|
const outDir = opts.out && opts.out.length > 0 ? resolve(opts.out) : extensionDir;
|
|
@@ -306,6 +307,6 @@ function createExtensionPackCommand() {
|
|
|
306
307
|
});
|
|
307
308
|
}
|
|
308
309
|
//#endregion
|
|
309
|
-
export { createExtensionPackCommand, validateExtensionPackageDirectory };
|
|
310
|
+
export { createExtensionPackCommand, validateExtensionPackageDirectory, writeStoreReadyArtifact };
|
|
310
311
|
|
|
311
312
|
//# sourceMappingURL=extension-pack.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension-pack.js","names":[],"sources":["../../../../src/cli/commands/extension-pack.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport { execSync } from 'node:child_process';\nimport { existsSync, readFileSync, readdirSync, mkdirSync, statSync, writeFileSync } from 'node:fs';\nimport { basename, join, relative, resolve } from 'node:path';\n\nimport AdmZip from 'adm-zip';\nimport { Command } from 'commander';\n\nimport { checkEngineCompatibility } from '../../extensions/engine-check.js';\nimport type { ExtensionManifest } from '../../extensions/types/index.js';\nimport { normalizeExtensionManifest } from '../../extensions/normalize-manifest.js';\nimport { collectExtensionPackageDependencyIssues } from '../../extensions/package-contract.js';\nimport { PACKAGE_VERSION } from '../../package-version.js';\nimport { createLogger } from '../../utils/logger.js';\nimport { colors } from '../utils/colors.js';\n\nconst log = createLogger('ExtensionPack');\nconst MANIFEST = 'xopc.extension.json';\n\ninterface PackContext {\n extensionDir: string;\n manifest: ExtensionManifest;\n packageJson: Record<string, unknown>;\n diagnostics: PackDiagnostic[];\n}\n\nexport interface PackDiagnostic {\n level: 'error' | 'warning' | 'info';\n message: string;\n}\n\nexport interface ExtensionPackageValidationResult {\n extensionDir: string;\n manifest: ExtensionManifest | null;\n packageJson: Record<string, unknown> | null;\n diagnostics: PackDiagnostic[];\n ok: boolean;\n}\n\nfunction isRecord(x: unknown): x is Record<string, unknown> {\n return typeof x === 'object' && x !== null && !Array.isArray(x);\n}\n\nfunction loadJson(path: string): unknown {\n return JSON.parse(readFileSync(path, 'utf-8') as string) as unknown;\n}\n\nfunction loadManifestAtRoot(\n root: string,\n diagnostics: PackDiagnostic[],\n): ExtensionManifest | null {\n const manifestPath = join(root, MANIFEST);\n if (!existsSync(manifestPath)) {\n diagnostics.push({ level: 'error', message: `Missing ${MANIFEST} in ${root}` });\n return null;\n }\n try {\n const raw = loadJson(manifestPath);\n if (!isRecord(raw)) {\n diagnostics.push({ level: 'error', message: `${MANIFEST} must be a JSON object` });\n return null;\n }\n return normalizeExtensionManifest(raw);\n } catch (e) {\n diagnostics.push({\n level: 'error',\n message: `Failed to parse ${MANIFEST}: ${e instanceof Error ? e.message : String(e)}`,\n });\n return null;\n }\n}\n\nfunction collectContributionPaths(manifest: ExtensionManifest, extRoot: string): string[] {\n const out: string[] = [];\n const ui = manifest.ui;\n if (ui?.main) out.push(join(extRoot, ui.main));\n if (ui?.icon) out.push(join(extRoot, ui.icon));\n const c = ui?.contributions;\n if (!c) return out;\n for (const p of c.sidebarPanels ?? []) {\n if (p.entrypoint) out.push(join(extRoot, p.entrypoint));\n }\n for (const p of c.settingsPanels ?? []) {\n if (p.entrypoint) out.push(join(extRoot, p.entrypoint));\n }\n for (const p of c.chatWidgets ?? []) {\n if (p.entrypoint) out.push(join(extRoot, p.entrypoint));\n }\n for (const p of c.pages ?? []) {\n if (p.entrypoint) out.push(join(extRoot, p.entrypoint));\n }\n for (const p of c.statusBarItems ?? []) {\n if (p.entrypoint) out.push(join(extRoot, p.entrypoint));\n }\n return out;\n}\n\nfunction resolveMainFile(root: string, main: string): string | null {\n const p = join(root, main);\n return existsSync(p) ? p : null;\n}\n\nfunction validateManifest(ctx: PackContext): void {\n const { manifest, extensionDir, diagnostics } = ctx;\n if (!manifest.id || !String(manifest.id).trim()) {\n diagnostics.push({ level: 'error', message: 'Manifest \"id\" is required' });\n }\n if (!manifest.main) {\n diagnostics.push({ level: 'error', message: 'Manifest \"main\" is required and must point at built JavaScript' });\n }\n const mainFile = manifest.main ? resolveMainFile(extensionDir, manifest.main) : null;\n if (!mainFile) {\n diagnostics.push({\n level: 'error',\n message: `Main entry not found: ${manifest.main ?? '(missing)'}`,\n });\n }\n\n if (manifest.ui?.main) {\n const p = join(extensionDir, manifest.ui.main);\n if (!existsSync(p)) {\n diagnostics.push({ level: 'error', message: `ui.main missing: ${manifest.ui.main}` });\n }\n }\n\n for (const p of collectContributionPaths(manifest, extensionDir)) {\n if (!existsSync(p)) {\n diagnostics.push({ level: 'error', message: `UI contribution entry missing: ${p}` });\n }\n }\n\n if (manifest.main && !/\\.(mjs|cjs|js)$/i.test(manifest.main)) {\n diagnostics.push({\n level: 'error',\n message: `Strict package contract requires manifest.main to point at built JavaScript, got \"${manifest.main}\"`,\n });\n }\n\n if (!manifest.engines?.xopc) {\n diagnostics.push({\n level: 'error',\n message: 'manifest engines.xopc is required for independent extension packages',\n });\n } else {\n const r = checkEngineCompatibility(PACKAGE_VERSION, manifest.engines.xopc);\n if (r.parseWarning) {\n diagnostics.push({\n level: 'error',\n message: `engines.xopc parse issue — ${r.reason ?? 'unknown'}`,\n });\n } else if (!r.compatible) {\n diagnostics.push({\n level: 'error',\n message: `engines.xopc not satisfied by current xopc ${PACKAGE_VERSION}: ${r.reason ?? manifest.engines.xopc}`,\n });\n }\n }\n}\n\nfunction validatePackageJson(ctx: PackContext): void {\n const { packageJson, diagnostics, extensionDir } = ctx;\n for (const issue of collectExtensionPackageDependencyIssues(packageJson, {\n strictRuntimeSdkDeps: true,\n })) {\n diagnostics.push({\n level: 'error',\n message: issue.message,\n });\n }\n\n const files = packageJson.files;\n if (Array.isArray(files)) {\n if (!files.some((f) => f === MANIFEST || f === '**/xopc.extension.json')) {\n diagnostics.push({\n level: 'error',\n message: `package.json \"files\" must include \"${MANIFEST}\" so the archive ships the manifest`,\n });\n }\n }\n\n const keywords = packageJson.keywords;\n if (Array.isArray(keywords) && !keywords.includes('xopc-extension')) {\n diagnostics.push({\n level: 'info',\n message: 'Consider adding \"xopc-extension\" to package.json keywords for discoverability',\n });\n } else if (!Array.isArray(keywords)) {\n diagnostics.push({ level: 'info', message: 'Consider adding keywords: [\"xopc-extension\", ...]' });\n }\n\n if (!existsSync(join(extensionDir, 'package.json'))) {\n diagnostics.push({ level: 'error', message: 'package.json is missing' });\n }\n}\n\nconst SECRET_FILE_RE = /(^|\\/)(\\.env(?:\\..*)?|\\.npmrc|\\.yarnrc|id_rsa|id_ed25519|.*\\.(?:pem|key|p12|pfx))$/i;\nconst SECRET_TEXT_RE = /(sk-[A-Za-z0-9_-]{20,}|xox[baprs]-[A-Za-z0-9-]{20,}|AKIA[0-9A-Z]{16}|-----BEGIN (?:RSA |OPENSSH |EC |DSA )?PRIVATE KEY-----)/;\n\nfunction scanUnsafeFiles(root: string, diagnostics: PackDiagnostic[]): void {\n const walk = (dir: string) => {\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n const full = join(dir, entry.name);\n const rel = relative(root, full).replace(/\\\\/g, '/');\n if (shouldExcludeFromArtifact(rel)) continue;\n if (SECRET_FILE_RE.test(rel)) {\n diagnostics.push({ level: 'error', message: `Unsafe secret-like file would be packaged: ${rel}` });\n continue;\n }\n if (entry.isDirectory()) {\n walk(full);\n } else if (entry.isFile()) {\n const size = statSync(full).size;\n if (size <= 1024 * 1024 && /\\.(?:js|mjs|cjs|json|html|css|md|txt|map)$/i.test(entry.name)) {\n const text = readFileSync(full, 'utf-8');\n if (SECRET_TEXT_RE.test(text)) {\n diagnostics.push({ level: 'error', message: `Potential secret token found in packaged file: ${rel}` });\n }\n }\n }\n }\n };\n walk(root);\n}\n\nexport function validateExtensionPackageDirectory(dir: string): ExtensionPackageValidationResult {\n const extensionDir = resolve(dir || '.');\n const diagnostics: PackDiagnostic[] = [];\n if (!existsSync(extensionDir) || !existsSync(join(extensionDir, 'package.json'))) {\n diagnostics.push({ level: 'error', message: `Not an extension project (no package.json): ${extensionDir}` });\n return { extensionDir, manifest: null, packageJson: null, diagnostics, ok: false };\n }\n const manifest = loadManifestAtRoot(extensionDir, diagnostics);\n let packageJson: Record<string, unknown> | null = null;\n try {\n packageJson = loadJson(join(extensionDir, 'package.json')) as Record<string, unknown>;\n if (!isRecord(packageJson)) throw new Error('package.json must be an object');\n } catch (e) {\n diagnostics.push({ level: 'error', message: e instanceof Error ? e.message : String(e) });\n }\n if (manifest && packageJson) {\n const ctx: PackContext = { extensionDir, manifest, packageJson, diagnostics };\n validateManifest(ctx);\n validatePackageJson(ctx);\n scanUnsafeFiles(extensionDir, diagnostics);\n }\n return {\n extensionDir,\n manifest,\n packageJson,\n diagnostics,\n ok: !diagnostics.some((d) => d.level === 'error'),\n };\n}\n\nfunction shouldExcludeFromArtifact(rel: string): boolean {\n const parts = rel.split(/[\\\\/]+/);\n if (parts.some((p) => p === 'node_modules' || p === '.git' || p === '.turbo' || p === '.cache')) return true;\n const name = parts.at(-1) ?? rel;\n if (name === '.DS_Store') return true;\n if (name.endsWith('.tgz') || name.endsWith('.zip') || name.endsWith('.sha256') || name.endsWith('.manifest.json')) return true;\n if (name.endsWith('.tsbuildinfo')) return true;\n return false;\n}\n\nfunction addDirectoryToZip(zip: AdmZip, root: string, dir: string): void {\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n const full = join(dir, entry.name);\n const rel = relative(root, full).replace(/\\\\/g, '/');\n if (shouldExcludeFromArtifact(rel)) continue;\n if (entry.isDirectory()) {\n addDirectoryToZip(zip, root, full);\n } else if (entry.isFile()) {\n zip.addFile(rel, readFileSync(full));\n }\n }\n}\n\nfunction writeStoreReadyArtifact(params: {\n extensionDir: string;\n outDir: string;\n manifest: ExtensionManifest;\n packageJson: Record<string, unknown>;\n}): string {\n mkdirSync(params.outDir, { recursive: true });\n const name = String(params.packageJson.name ?? params.manifest.id)\n .replace(/^@/, '')\n .replace(/[\\\\/]+/g, '-')\n .replace(/[^A-Za-z0-9._-]+/g, '-');\n const version = String(params.manifest.version ?? params.packageJson.version ?? '0.0.0');\n const base = `${name}-${version}`;\n const zipPath = join(params.outDir, `${base}.zip`);\n const zip = new AdmZip();\n addDirectoryToZip(zip, params.extensionDir, params.extensionDir);\n zip.writeZip(zipPath);\n\n const buffer = readFileSync(zipPath);\n const sha256Hex = createHash('sha256').update(buffer).digest('hex');\n const integrity = `sha256-${createHash('sha256').update(buffer).digest('base64')}`;\n writeFileSync(join(params.outDir, `${base}.sha256`), `${sha256Hex} ${basename(zipPath)}\\n`);\n writeFileSync(\n join(params.outDir, `${base}.manifest.json`),\n JSON.stringify(\n {\n id: params.manifest.id,\n name: params.manifest.name,\n version,\n artifact: basename(zipPath),\n integrity,\n manifest: params.manifest,\n packageJson: params.packageJson,\n },\n null,\n 2,\n ),\n );\n return zipPath;\n}\n\nfunction printDiagnostics(d: PackDiagnostic[]): void {\n for (const x of d) {\n if (x.level === 'error') {\n console.error(`${colors.red('error')}:`, x.message);\n } else if (x.level === 'warning') {\n console.log(`${colors.yellow('warning')}:`, x.message);\n } else {\n console.log(`${colors.cyan('info')}:`, x.message);\n }\n }\n}\n\nexport function createExtensionPackCommand(): Command {\n return new Command('pack')\n .description('Package an extension as a .tgz archive for distribution')\n .argument('[dir]', 'Extension directory (default: current working directory)', '.')\n .option('--out <dir>', 'Output directory for the .tgz (default: extension directory)', '')\n .option('--no-build-ui', 'Skip automatic \"npm run build:ui\" when defined')\n .option('--dry-run', 'Validate only; do not create an archive', false)\n .action((dir: string, opts: { out?: string; buildUi: boolean; dryRun: boolean }) => {\n const validation = validateExtensionPackageDirectory(dir || '.');\n const { extensionDir, manifest, packageJson, diagnostics } = validation;\n const outDir = opts.out && opts.out.length > 0 ? resolve(opts.out) : extensionDir;\n printDiagnostics(diagnostics);\n\n if (!validation.ok || !manifest || !packageJson) {\n console.error(colors.red('Pack validation failed (fix errors above).'));\n process.exit(1);\n }\n\n if (opts.dryRun) {\n console.log(colors.green('OK'), ' — dry run; no archive created');\n return;\n }\n\n const scripts = isRecord(packageJson.scripts) ? (packageJson.scripts as Record<string, unknown>) : null;\n if (opts.buildUi && scripts && typeof scripts['build:ui'] === 'string') {\n try {\n console.log(colors.cyan('Running'), 'npm run build:ui …');\n execSync('npm run build:ui', { cwd: extensionDir, stdio: 'inherit' });\n } catch (e) {\n console.error(\n colors.red('error:'),\n `UI build failed: ${e instanceof Error ? e.message : String(e)}`,\n );\n process.exit(1);\n }\n }\n\n let artifactPath: string;\n try {\n artifactPath = writeStoreReadyArtifact({ extensionDir, outDir, manifest, packageJson });\n } catch (e) {\n log.error({ err: e }, 'pack failed');\n console.error(colors.red('error:'), e instanceof Error ? e.message : String(e));\n process.exit(1);\n }\n\n console.log('');\n console.log(colors.green('Pack complete:'), artifactPath);\n console.log(colors.cyan('Generated:'), '.zip artifact, .sha256 checksum, .manifest.json metadata');\n console.log(colors.cyan('Next:'), 'upload the generated artifact set to store.xopc.ai or install the zip via the store pipeline.');\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"extension-pack.js","names":[],"sources":["../../../../src/cli/commands/extension-pack.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport { execSync } from 'node:child_process';\nimport { existsSync, readFileSync, readdirSync, mkdirSync, statSync, writeFileSync } from 'node:fs';\nimport { basename, join, relative, resolve } from 'node:path';\n\nimport AdmZip from 'adm-zip';\nimport { Command } from 'commander';\n\nimport { checkEngineCompatibility } from '../../extensions/engine-check.js';\nimport type { ExtensionManifest } from '../../extensions/types/index.js';\nimport { normalizeExtensionManifest } from '../../extensions/normalize-manifest.js';\nimport { collectExtensionPackageDependencyIssues } from '../../extensions/package-contract.js';\nimport { PACKAGE_VERSION } from '../../package-version.js';\nimport { createLogger } from '../../utils/logger.js';\nimport { colors } from '../utils/colors.js';\n\nconst log = createLogger('ExtensionPack');\nconst MANIFEST = 'xopc.extension.json';\n\ninterface PackContext {\n extensionDir: string;\n manifest: ExtensionManifest;\n packageJson: Record<string, unknown>;\n diagnostics: PackDiagnostic[];\n}\n\nexport interface PackDiagnostic {\n level: 'error' | 'warning' | 'info';\n message: string;\n}\n\nexport interface ExtensionPackageValidationResult {\n extensionDir: string;\n manifest: ExtensionManifest | null;\n packageJson: Record<string, unknown> | null;\n diagnostics: PackDiagnostic[];\n ok: boolean;\n}\n\nfunction isRecord(x: unknown): x is Record<string, unknown> {\n return typeof x === 'object' && x !== null && !Array.isArray(x);\n}\n\nfunction loadJson(path: string): unknown {\n return JSON.parse(readFileSync(path, 'utf-8') as string) as unknown;\n}\n\nfunction loadManifestAtRoot(\n root: string,\n diagnostics: PackDiagnostic[],\n): ExtensionManifest | null {\n const manifestPath = join(root, MANIFEST);\n if (!existsSync(manifestPath)) {\n diagnostics.push({ level: 'error', message: `Missing ${MANIFEST} in ${root}` });\n return null;\n }\n try {\n const raw = loadJson(manifestPath);\n if (!isRecord(raw)) {\n diagnostics.push({ level: 'error', message: `${MANIFEST} must be a JSON object` });\n return null;\n }\n return normalizeExtensionManifest(raw);\n } catch (e) {\n diagnostics.push({\n level: 'error',\n message: `Failed to parse ${MANIFEST}: ${e instanceof Error ? e.message : String(e)}`,\n });\n return null;\n }\n}\n\nfunction collectContributionPaths(manifest: ExtensionManifest, extRoot: string): string[] {\n const out: string[] = [];\n const ui = manifest.ui;\n if (ui?.main) out.push(join(extRoot, ui.main));\n if (ui?.icon) out.push(join(extRoot, ui.icon));\n const c = ui?.contributions;\n if (!c) return out;\n for (const p of c.sidebarPanels ?? []) {\n if (p.entrypoint) out.push(join(extRoot, p.entrypoint));\n }\n for (const p of c.settingsPanels ?? []) {\n if (p.entrypoint) out.push(join(extRoot, p.entrypoint));\n }\n for (const p of c.chatWidgets ?? []) {\n if (p.entrypoint) out.push(join(extRoot, p.entrypoint));\n }\n for (const p of c.pages ?? []) {\n if (p.entrypoint) out.push(join(extRoot, p.entrypoint));\n }\n for (const p of c.statusBarItems ?? []) {\n if (p.entrypoint) out.push(join(extRoot, p.entrypoint));\n }\n return out;\n}\n\nfunction resolveMainFile(root: string, main: string): string | null {\n const p = join(root, main);\n return existsSync(p) ? p : null;\n}\n\nfunction validateManifest(ctx: PackContext): void {\n const { manifest, extensionDir, diagnostics } = ctx;\n if (!manifest.id || !String(manifest.id).trim()) {\n diagnostics.push({ level: 'error', message: 'Manifest \"id\" is required' });\n }\n if (!manifest.main) {\n diagnostics.push({ level: 'error', message: 'Manifest \"main\" is required and must point at built JavaScript' });\n }\n const mainFile = manifest.main ? resolveMainFile(extensionDir, manifest.main) : null;\n if (!mainFile) {\n diagnostics.push({\n level: 'error',\n message: `Main entry not found: ${manifest.main ?? '(missing)'}`,\n });\n }\n\n if (manifest.ui?.main) {\n const p = join(extensionDir, manifest.ui.main);\n if (!existsSync(p)) {\n diagnostics.push({ level: 'error', message: `ui.main missing: ${manifest.ui.main}` });\n }\n }\n\n for (const p of collectContributionPaths(manifest, extensionDir)) {\n if (!existsSync(p)) {\n diagnostics.push({ level: 'error', message: `UI contribution entry missing: ${p}` });\n }\n }\n\n if (manifest.main && !/\\.(mjs|cjs|js)$/i.test(manifest.main)) {\n diagnostics.push({\n level: 'error',\n message: `Strict package contract requires manifest.main to point at built JavaScript, got \"${manifest.main}\"`,\n });\n }\n\n if (!manifest.engines?.xopc) {\n diagnostics.push({\n level: 'error',\n message: 'manifest engines.xopc is required for independent extension packages',\n });\n } else {\n const r = checkEngineCompatibility(PACKAGE_VERSION, manifest.engines.xopc);\n if (r.parseWarning) {\n diagnostics.push({\n level: 'error',\n message: `engines.xopc parse issue — ${r.reason ?? 'unknown'}`,\n });\n } else if (!r.compatible) {\n diagnostics.push({\n level: 'error',\n message: `engines.xopc not satisfied by current xopc ${PACKAGE_VERSION}: ${r.reason ?? manifest.engines.xopc}`,\n });\n }\n }\n}\n\nfunction validatePackageJson(ctx: PackContext): void {\n const { packageJson, diagnostics, extensionDir } = ctx;\n for (const issue of collectExtensionPackageDependencyIssues(packageJson, {\n strictRuntimeSdkDeps: true,\n })) {\n diagnostics.push({\n level: 'error',\n message: issue.message,\n });\n }\n\n const files = packageJson.files;\n if (Array.isArray(files)) {\n if (!files.some((f) => f === MANIFEST || f === '**/xopc.extension.json')) {\n diagnostics.push({\n level: 'error',\n message: `package.json \"files\" must include \"${MANIFEST}\" so the archive ships the manifest`,\n });\n }\n }\n\n const keywords = packageJson.keywords;\n if (Array.isArray(keywords) && !keywords.includes('xopc-extension')) {\n diagnostics.push({\n level: 'info',\n message: 'Consider adding \"xopc-extension\" to package.json keywords for discoverability',\n });\n } else if (!Array.isArray(keywords)) {\n diagnostics.push({ level: 'info', message: 'Consider adding keywords: [\"xopc-extension\", ...]' });\n }\n\n if (!existsSync(join(extensionDir, 'package.json'))) {\n diagnostics.push({ level: 'error', message: 'package.json is missing' });\n }\n}\n\nconst SECRET_FILE_RE = /(^|\\/)(\\.env(?:\\..*)?|\\.npmrc|\\.yarnrc|id_rsa|id_ed25519|.*\\.(?:pem|key|p12|pfx))$/i;\nconst SECRET_TEXT_RE = /(sk-[A-Za-z0-9_-]{20,}|xox[baprs]-[A-Za-z0-9-]{20,}|AKIA[0-9A-Z]{16}|-----BEGIN (?:RSA |OPENSSH |EC |DSA )?PRIVATE KEY-----)/;\n\nfunction scanUnsafeFiles(root: string, diagnostics: PackDiagnostic[]): void {\n const walk = (dir: string) => {\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n const full = join(dir, entry.name);\n const rel = relative(root, full).replace(/\\\\/g, '/');\n if (shouldExcludeFromArtifact(rel)) continue;\n if (SECRET_FILE_RE.test(rel)) {\n diagnostics.push({ level: 'error', message: `Unsafe secret-like file would be packaged: ${rel}` });\n continue;\n }\n if (entry.isDirectory()) {\n walk(full);\n } else if (entry.isFile()) {\n const size = statSync(full).size;\n if (size <= 1024 * 1024 && /\\.(?:js|mjs|cjs|json|html|css|md|txt|map)$/i.test(entry.name)) {\n const text = readFileSync(full, 'utf-8');\n if (SECRET_TEXT_RE.test(text)) {\n diagnostics.push({ level: 'error', message: `Potential secret token found in packaged file: ${rel}` });\n }\n }\n }\n }\n };\n walk(root);\n}\n\nexport function validateExtensionPackageDirectory(dir: string): ExtensionPackageValidationResult {\n const extensionDir = resolve(dir || '.');\n const diagnostics: PackDiagnostic[] = [];\n if (!existsSync(extensionDir) || !existsSync(join(extensionDir, 'package.json'))) {\n diagnostics.push({ level: 'error', message: `Not an extension project (no package.json): ${extensionDir}` });\n return { extensionDir, manifest: null, packageJson: null, diagnostics, ok: false };\n }\n const manifest = loadManifestAtRoot(extensionDir, diagnostics);\n let packageJson: Record<string, unknown> | null = null;\n try {\n packageJson = loadJson(join(extensionDir, 'package.json')) as Record<string, unknown>;\n if (!isRecord(packageJson)) throw new Error('package.json must be an object');\n } catch (e) {\n diagnostics.push({ level: 'error', message: e instanceof Error ? e.message : String(e) });\n }\n if (manifest && packageJson) {\n const ctx: PackContext = { extensionDir, manifest, packageJson, diagnostics };\n validateManifest(ctx);\n validatePackageJson(ctx);\n scanUnsafeFiles(extensionDir, diagnostics);\n }\n return {\n extensionDir,\n manifest,\n packageJson,\n diagnostics,\n ok: !diagnostics.some((d) => d.level === 'error'),\n };\n}\n\nfunction shouldExcludeFromArtifact(rel: string): boolean {\n const parts = rel.split(/[\\\\/]+/);\n if (parts.some((p) => p === 'node_modules' || p === '.git' || p === '.turbo' || p === '.cache')) return true;\n const name = parts.at(-1) ?? rel;\n if (name === '.DS_Store') return true;\n if (name.endsWith('.tgz') || name.endsWith('.zip') || name.endsWith('.sha256') || name.endsWith('.manifest.json')) return true;\n if (name.endsWith('.tsbuildinfo')) return true;\n return false;\n}\n\nfunction addDirectoryToZip(zip: AdmZip, root: string, dir: string): void {\n for (const entry of readdirSync(dir, { withFileTypes: true })) {\n const full = join(dir, entry.name);\n const rel = relative(root, full).replace(/\\\\/g, '/');\n if (shouldExcludeFromArtifact(rel)) continue;\n if (entry.isDirectory()) {\n addDirectoryToZip(zip, root, full);\n } else if (entry.isFile()) {\n zip.addFile(rel, readFileSync(full));\n }\n }\n}\n\nexport function writeStoreReadyArtifact(params: {\n extensionDir: string;\n outDir: string;\n manifest: ExtensionManifest;\n packageJson: Record<string, unknown>;\n}): string {\n mkdirSync(params.outDir, { recursive: true });\n const name = String(params.packageJson.name ?? params.manifest.id)\n .replace(/^@/, '')\n .replace(/[\\\\/]+/g, '-')\n .replace(/[^A-Za-z0-9._-]+/g, '-');\n const version = String(params.manifest.version ?? params.packageJson.version ?? '0.0.0');\n const base = `${name}-${version}`;\n const zipPath = join(params.outDir, `${base}.zip`);\n const zip = new AdmZip();\n addDirectoryToZip(zip, params.extensionDir, params.extensionDir);\n zip.writeZip(zipPath);\n\n const buffer = readFileSync(zipPath);\n const sha256Hex = createHash('sha256').update(buffer).digest('hex');\n const integrity = `sha256-${createHash('sha256').update(buffer).digest('base64')}`;\n writeFileSync(join(params.outDir, `${base}.sha256`), `${sha256Hex} ${basename(zipPath)}\\n`);\n writeFileSync(\n join(params.outDir, `${base}.manifest.json`),\n JSON.stringify(\n {\n id: params.manifest.id,\n name: params.manifest.name,\n version,\n artifact: basename(zipPath),\n sha256: sha256Hex,\n integrity,\n manifest: params.manifest,\n packageJson: params.packageJson,\n },\n null,\n 2,\n ),\n );\n return zipPath;\n}\n\nfunction printDiagnostics(d: PackDiagnostic[]): void {\n for (const x of d) {\n if (x.level === 'error') {\n console.error(`${colors.red('error')}:`, x.message);\n } else if (x.level === 'warning') {\n console.log(`${colors.yellow('warning')}:`, x.message);\n } else {\n console.log(`${colors.cyan('info')}:`, x.message);\n }\n }\n}\n\nexport function createExtensionPackCommand(): Command {\n return new Command('pack')\n .description('Package an extension as a store-ready .zip artifact set')\n .argument('[dir]', 'Extension directory (default: current working directory)', '.')\n .option('--out <dir>', 'Output directory for the artifact set (default: extension directory)', '')\n .option('--no-build-ui', 'Skip automatic \"npm run build:ui\" when defined')\n .option('--dry-run', 'Validate only; do not create an archive', false)\n .action((dir: string, opts: { out?: string; buildUi: boolean; dryRun: boolean }) => {\n const validation = validateExtensionPackageDirectory(dir || '.');\n const { extensionDir, manifest, packageJson, diagnostics } = validation;\n const outDir = opts.out && opts.out.length > 0 ? resolve(opts.out) : extensionDir;\n printDiagnostics(diagnostics);\n\n if (!validation.ok || !manifest || !packageJson) {\n console.error(colors.red('Pack validation failed (fix errors above).'));\n process.exit(1);\n }\n\n if (opts.dryRun) {\n console.log(colors.green('OK'), ' — dry run; no archive created');\n return;\n }\n\n const scripts = isRecord(packageJson.scripts) ? (packageJson.scripts as Record<string, unknown>) : null;\n if (opts.buildUi && scripts && typeof scripts['build:ui'] === 'string') {\n try {\n console.log(colors.cyan('Running'), 'npm run build:ui …');\n execSync('npm run build:ui', { cwd: extensionDir, stdio: 'inherit' });\n } catch (e) {\n console.error(\n colors.red('error:'),\n `UI build failed: ${e instanceof Error ? e.message : String(e)}`,\n );\n process.exit(1);\n }\n }\n\n let artifactPath: string;\n try {\n artifactPath = writeStoreReadyArtifact({ extensionDir, outDir, manifest, packageJson });\n } catch (e) {\n log.error({ err: e }, 'pack failed');\n console.error(colors.red('error:'), e instanceof Error ? e.message : String(e));\n process.exit(1);\n }\n\n console.log('');\n console.log(colors.green('Pack complete:'), artifactPath);\n console.log(colors.cyan('Generated:'), '.zip artifact, .sha256 checksum, .manifest.json metadata');\n console.log(colors.cyan('Next:'), 'upload the generated artifact set to store.xopc.ai or install the zip via the store pipeline.');\n });\n}\n"],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { closeXopcDatabase, openXopcDatabase } from "../../storage/sqlite/connection.js";
|
|
2
|
-
import "../../storage/sqlite/index.js";
|
|
3
1
|
import { init_loader, loadConfig } from "../../config/loader.js";
|
|
2
|
+
import { closeXopcDatabase, openXopcDatabase } from "../../storage/sqlite/connection.js";
|
|
4
3
|
import { GoalService } from "../../goals/goal-service.js";
|
|
5
4
|
import "../../goals/index.js";
|
|
5
|
+
import "../../storage/sqlite/index.js";
|
|
6
6
|
import { ProjectService } from "../../projects/project-service.js";
|
|
7
7
|
import { resolveProjectAgentId } from "../../projects/project-agent.js";
|
|
8
8
|
import "../../projects/index.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { resolveStateDir } from "../../config/paths-state.js";
|
|
2
|
+
import { resolveAgentWorkspaceDir } from "../../agent/agent-scope.js";
|
|
2
3
|
import { createLogger } from "../../utils/logger/index.js";
|
|
3
4
|
import { init_logger } from "../../utils/logger.js";
|
|
4
|
-
import { resolveAgentWorkspaceDir } from "../../agent/agent-scope.js";
|
|
5
5
|
import { WORKSPACE_FILES, init_paths, resolveAgentDir, resolveAgentHomeDir, resolveAgentProfileDir, resolveConfigPath, resolveUserProfilePath } from "../../config/paths.js";
|
|
6
6
|
import { init_loader, loadConfig, saveConfig } from "../../config/loader.js";
|
|
7
7
|
import { ensureStarterAgentsInitialized } from "../../agent/starter-agents.js";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { closeXopcDatabase, isXopcDatabaseOpen, openXopcDatabase } from "../../storage/sqlite/connection.js";
|
|
2
|
-
import { getSessionMetadata } from "../../storage/sqlite/session-repository.js";
|
|
3
|
-
import "../../storage/sqlite/index.js";
|
|
4
1
|
import { init_loader, loadConfig } from "../../config/loader.js";
|
|
2
|
+
import { closeXopcDatabase, isXopcDatabaseOpen, openXopcDatabase } from "../../storage/sqlite/connection.js";
|
|
5
3
|
import { GoalService } from "../../goals/goal-service.js";
|
|
6
4
|
import "../../goals/index.js";
|
|
5
|
+
import { getSessionMetadata } from "../../storage/sqlite/session-repository.js";
|
|
6
|
+
import "../../storage/sqlite/index.js";
|
|
7
7
|
import { ProjectService } from "../../projects/project-service.js";
|
|
8
8
|
import { isValidProjectAgentId, normalizeProjectAgentId } from "../../projects/project-agent.js";
|
|
9
9
|
import "../../projects/index.js";
|
|
@@ -43,6 +43,7 @@ function applyAgentConfig(cfg, params) {
|
|
|
43
43
|
const nextEntry = {
|
|
44
44
|
...base,
|
|
45
45
|
enabled: base.enabled ?? true,
|
|
46
|
+
...params.extends !== void 0 ? { extends: params.extends } : {},
|
|
46
47
|
...params.workspace ? { workspace: { root: params.workspace } } : {},
|
|
47
48
|
...params.models ? { models: params.models } : {},
|
|
48
49
|
...params.model ? { models: {
|