@xopcai/xopc 0.0.89 → 0.0.90
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
- package/dist/extensions/feishu/src/workflow-progress.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 +2 -2
- package/dist/extensions/weixin/src/auth/accounts.js +1 -1
- package/dist/extensions/weixin/src/cdn/upload.js +1 -1
- package/dist/extensions/weixin/src/media/data-url.js +1 -1
- package/dist/extensions/weixin/src/messaging/debug-mode.js +1 -1
- package/dist/extensions/weixin/src/messaging/inbound.js +1 -1
- package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
- package/dist/extensions/weixin/src/plugin.js +1 -1
- package/dist/extensions/weixin/src/storage/sync-buf.js +1 -1
- package/dist/extensions/weixin/src/workflow-progress.js +1 -1
- package/dist/gateway/static/root/assets/agents-cPvvYLXo.js +222 -0
- package/dist/gateway/static/root/assets/apps-page-Bk1_P5FJ.js +1 -0
- package/dist/gateway/static/root/assets/channels-settings-CZoeQwHz.js +1 -0
- package/dist/gateway/static/root/assets/{channels-status-swr-DaHGkRF1.js → channels-status-swr-BrtH2VzC.js} +1 -1
- package/dist/gateway/static/root/assets/circle-check-C23XjkUj.js +1 -0
- package/dist/gateway/static/root/assets/cron-api-CyqbgfHM.js +1 -0
- package/dist/gateway/static/root/assets/cron-dreaming-jobs-Ip703-qM.js +2 -0
- package/dist/gateway/static/root/assets/cron-page-BpLdiQN8.js +1 -0
- package/dist/gateway/static/root/assets/dist-BpAiK86n.js +1 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-CtuKJ9tE.js → extension-debug-page-D6Ak0STa.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-ykzjOkR5.js → extension-page-Q0P3d6DW.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-Ce2qrdpO.js → extension-settings-page-CL55LwU_.js} +1 -1
- package/dist/gateway/static/root/assets/eye-DAfL1U7M.js +1 -0
- package/dist/gateway/static/root/assets/{fetch-C9FFJjuH.js → fetch-Dqa9iTWl.js} +1 -1
- package/dist/gateway/static/root/assets/{field-primitives-BFcrNeTU.js → field-primitives-HUR6JElP.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-config-api-CEg4Vr9R.js → heartbeat-config-api-DusckjUX.js} +1 -1
- package/dist/gateway/static/root/assets/{index-CZfy9oxs.js → index-BYcGfwcE.js} +97 -97
- package/dist/gateway/static/root/assets/index-V7MQ7834.css +1 -0
- package/dist/gateway/static/root/assets/logs-page-_HcZ2fgK.js +1 -0
- package/dist/gateway/static/root/assets/sessions-page-iezSMjho.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-BqdzA28u.js → settings-form-section-a0qGVOlr.js} +1 -1
- package/dist/gateway/static/root/assets/settings-page-C9_nYQwM.js +3 -0
- package/dist/gateway/static/root/assets/{share-preview-page-Di5Bzh4g.js → share-preview-page-DExl7CJy.js} +1 -1
- package/dist/gateway/static/root/assets/skills-page-BlgGD93t.js +2 -0
- package/dist/gateway/static/root/assets/{theme-store-CNqbmTNV.js → theme-store-C0Ehmdo5.js} +1 -1
- package/dist/gateway/static/root/assets/url-fxyYANfA.js +3 -0
- package/dist/gateway/static/root/assets/{utils-BWm2tG2w.js → utils-DRQryzdn.js} +1 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-D0viACE2.js +1 -0
- package/dist/gateway/static/root/assets/workflow-page.utils-DnG8JBhV.js +1 -0
- package/dist/gateway/static/root/assets/workflows-page-BvMobnJP.js +27 -0
- package/dist/gateway/static/root/index.html +7 -5
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.js +7 -7
- package/dist/src/agent/agent-scope.js +1 -1
- package/dist/src/agent/bootstrap/load-bootstrap-files.js +1 -1
- package/dist/src/agent/context/workspace-seed.js +2 -2
- package/dist/src/agent/goals/goal-run-store.js +4 -4
- package/dist/src/agent/goals/persistent-goal-service.js +1 -1
- package/dist/src/agent/goals/post-turn.js +2 -2
- package/dist/src/agent/image/load-image-media.js +2 -2
- package/dist/src/agent/ipc/bus.js +1 -1
- package/dist/src/agent/ipc/inbox.js +2 -2
- package/dist/src/agent/ipc/socket.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 +1 -1
- package/dist/src/agent/memory/builtin-memory-store.js +1 -1
- package/dist/src/agent/memory/dreaming/deep-promotion.js +1 -1
- package/dist/src/agent/memory/dreaming/events.js +1 -1
- package/dist/src/agent/memory/dreaming/last-run.js +1 -1
- package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
- package/dist/src/agent/memory/dreaming/preview.js +1 -1
- package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
- package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
- package/dist/src/agent/memory/dreaming/utils.js +1 -1
- package/dist/src/agent/memory/plugin-discovery.js +1 -1
- package/dist/src/agent/models/manager.js +1 -1
- package/dist/src/agent/prompt/service-prompt-builder.js +2 -2
- package/dist/src/agent/reply/post-compaction-context.js +1 -1
- package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
- package/dist/src/agent/sandbox/path-policy.js +2 -2
- package/dist/src/agent/service/build-direct-message-content.js +1 -1
- package/dist/src/agent/service.js +4 -4
- package/dist/src/agent/session/session-inspector.js +1 -1
- package/dist/src/agent/skills/config.js +1 -1
- package/dist/src/agent/skills/hub-hash.js +2 -2
- package/dist/src/agent/skills/hub-lock.js +1 -1
- package/dist/src/agent/skills/hub-pull.js +2 -2
- package/dist/src/agent/skills/index.js +1 -1
- package/dist/src/agent/skills/managed-store.js +1 -1
- package/dist/src/agent/skills/marketplace/adapters/skillhub/adapter.js +20 -18
- package/dist/src/agent/skills/marketplace/adapters/skillhub/adapter.js.map +1 -1
- package/dist/src/agent/skills/scanner.js +1 -1
- package/dist/src/agent/skills/skill-manage-ops.js +1 -1
- package/dist/src/agent/skills/skill-manager.js +1 -1
- package/dist/src/agent/tools/cronjob-tool.d.ts +6 -0
- package/dist/src/agent/tools/cronjob-tool.js +74 -9
- package/dist/src/agent/tools/cronjob-tool.js.map +1 -1
- package/dist/src/agent/tools/dreaming-tool.js +1 -1
- package/dist/src/agent/tools/edit.d.ts +5 -1
- package/dist/src/agent/tools/edit.js +7 -5
- package/dist/src/agent/tools/edit.js.map +1 -1
- package/dist/src/agent/tools/factory.js +3 -3
- package/dist/src/agent/tools/factory.js.map +1 -1
- package/dist/src/agent/tools/image-generate-tool.js +1 -1
- package/dist/src/agent/tools/send-media.js +1 -1
- package/dist/src/agent/tools/skill-manage-tool.js +1 -1
- package/dist/src/agent/tools/workflow-tool.js +1 -1
- package/dist/src/agent/tools/write.d.ts +5 -1
- package/dist/src/agent/tools/write.js +8 -6
- package/dist/src/agent/tools/write.js.map +1 -1
- package/dist/src/agent/workflow/agent-progress.js +2 -0
- package/dist/src/agent/workflow/agent-progress.js.map +1 -1
- package/dist/src/agent/workflow/builtins/client-proposal.d.ts +12 -0
- package/dist/src/agent/workflow/builtins/client-proposal.js +155 -0
- package/dist/src/agent/workflow/builtins/client-proposal.js.map +1 -0
- package/dist/src/agent/workflow/builtins/competitor-scan.d.ts +12 -0
- package/dist/src/agent/workflow/builtins/competitor-scan.js +150 -0
- package/dist/src/agent/workflow/builtins/competitor-scan.js.map +1 -0
- package/dist/src/agent/workflow/builtins/content-draft.d.ts +13 -0
- package/dist/src/agent/workflow/builtins/content-draft.js +146 -0
- package/dist/src/agent/workflow/builtins/content-draft.js.map +1 -0
- package/dist/src/agent/workflow/builtins/content-repurpose.d.ts +11 -0
- package/dist/src/agent/workflow/builtins/content-repurpose.js +137 -0
- package/dist/src/agent/workflow/builtins/content-repurpose.js.map +1 -0
- package/dist/src/agent/workflow/builtins/decision-compare.d.ts +13 -0
- package/dist/src/agent/workflow/builtins/decision-compare.js +173 -0
- package/dist/src/agent/workflow/builtins/decision-compare.js.map +1 -0
- package/dist/src/agent/workflow/builtins/inbox-triage.d.ts +11 -0
- package/dist/src/agent/workflow/builtins/inbox-triage.js +148 -0
- package/dist/src/agent/workflow/builtins/inbox-triage.js.map +1 -0
- package/dist/src/agent/workflow/builtins/index.d.ts +10 -1
- package/dist/src/agent/workflow/builtins/index.js +46 -1
- package/dist/src/agent/workflow/builtins/index.js.map +1 -1
- package/dist/src/agent/workflow/builtins/meeting-prep.d.ts +12 -0
- package/dist/src/agent/workflow/builtins/meeting-prep.js +144 -0
- package/dist/src/agent/workflow/builtins/meeting-prep.js.map +1 -0
- package/dist/src/agent/workflow/builtins/offer-design.d.ts +12 -0
- package/dist/src/agent/workflow/builtins/offer-design.js +161 -0
- package/dist/src/agent/workflow/builtins/offer-design.js.map +1 -0
- package/dist/src/agent/workflow/builtins/weekly-review.d.ts +12 -0
- package/dist/src/agent/workflow/builtins/weekly-review.js +131 -0
- package/dist/src/agent/workflow/builtins/weekly-review.js.map +1 -0
- package/dist/src/agent/workflow/catalog.js +1 -1
- package/dist/src/agent/workflow/step-labels.js +2 -2
- package/dist/src/agent/workflow/step-labels.js.map +1 -1
- package/dist/src/agent/workflow/subagent-runner.js +3 -1
- package/dist/src/agent/workflow/subagent-runner.js.map +1 -1
- package/dist/src/agent/workflow/types.d.ts +4 -0
- package/dist/src/auth/credentials.js +3 -3
- package/dist/src/auth/profiles/store.js +1 -1
- package/dist/src/auth/sync-provider-auth.js +1 -1
- package/dist/src/browser/cache-dir-policy.js +1 -1
- package/dist/src/browser/cdp-local-launcher.js +2 -2
- package/dist/src/browser/providers/browser-ext-install.js +3 -3
- package/dist/src/browser/providers/cloakbrowser.js +4 -4
- package/dist/src/browser/providers/playwright-doctor.js +1 -1
- package/dist/src/browser/stealth.js +1 -1
- package/dist/src/channels/attachments/inbound-persist.js +1 -1
- package/dist/src/channels/attachments/outbound-tts-persist.js +1 -1
- package/dist/src/channels/outbound/persist-store.js +1 -1
- package/dist/src/channels/pairing/allow-from-file.js +1 -1
- package/dist/src/channels/pairing/pairing-store.js +2 -2
- package/dist/src/chat-commands/agent-edit.d.ts +4 -0
- package/dist/src/chat-commands/agent-edit.js +136 -0
- package/dist/src/chat-commands/agent-edit.js.map +1 -0
- package/dist/src/chat-commands/builtins/config.js +2 -2
- package/dist/src/chat-commands/context.js +1 -1
- package/dist/src/chat-commands/index.d.ts +1 -0
- package/dist/src/chat-commands/index.js +3 -1
- package/dist/src/chat-commands/index.js.map +1 -1
- package/dist/src/cli/bin.js +2 -0
- package/dist/src/cli/bin.js.map +1 -1
- package/dist/src/cli/commands/config.js +1 -1
- package/dist/src/cli/commands/cron.js +42 -3
- package/dist/src/cli/commands/cron.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/config-health.js +1 -1
- package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
- package/dist/src/cli/commands/doctor/checks/session-integrity.js +79 -56
- package/dist/src/cli/commands/doctor/checks/session-integrity.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/state-integrity.js +1 -1
- package/dist/src/cli/commands/doctor/checks/workspace-status.js +1 -1
- package/dist/src/cli/commands/extension-dev.js +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +1 -1
- package/dist/src/cli/commands/extension-pack.js +1 -1
- package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
- package/dist/src/cli/commands/gateway/logs.js +1 -1
- package/dist/src/cli/commands/image.js +1 -1
- package/dist/src/cli/commands/init.js +4 -4
- package/dist/src/cli/commands/onboard.js +1 -1
- package/dist/src/cli/commands/update.js +86 -79
- package/dist/src/cli/commands/update.js.map +1 -1
- package/dist/src/cli/utils/init-workspace-core.js +2 -2
- package/dist/src/commands/agents.config.d.ts +3 -2
- package/dist/src/commands/agents.config.js +5 -2
- package/dist/src/commands/agents.config.js.map +1 -1
- package/dist/src/config/agent-profile.js +1 -1
- package/dist/src/config/agent-typed-models.d.ts +2 -7
- package/dist/src/config/agent-typed-models.js +3 -14
- package/dist/src/config/agent-typed-models.js.map +1 -1
- package/dist/src/config/gateway-bind.js +1 -1
- package/dist/src/config/index.js +5 -5
- package/dist/src/config/loader.js +2 -2
- package/dist/src/config/localized-text.d.ts +6 -0
- package/dist/src/config/localized-text.js +42 -0
- package/dist/src/config/localized-text.js.map +1 -0
- package/dist/src/config/models-json.d.ts +6 -6
- package/dist/src/config/models-json.js +2 -2
- package/dist/src/config/paths-state.js +1 -1
- package/dist/src/config/profile.js +2 -2
- package/dist/src/config/schema.d.ts +6 -21
- package/dist/src/config/schema.js +4 -4
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/config/workspace-path.js +1 -1
- package/dist/src/cron/executor.d.ts +2 -0
- package/dist/src/cron/executor.js +113 -3
- package/dist/src/cron/executor.js.map +1 -1
- package/dist/src/cron/persistence.js +1 -1
- package/dist/src/cron/run-log-store.js +1 -1
- package/dist/src/cron/types.d.ts +8 -1
- package/dist/src/cron/validation.d.ts +4 -0
- package/dist/src/cron/validation.js +4 -3
- package/dist/src/cron/validation.js.map +1 -1
- package/dist/src/cron/workflow-run-completion.d.ts +23 -0
- package/dist/src/cron/workflow-run-completion.js +72 -0
- package/dist/src/cron/workflow-run-completion.js.map +1 -0
- package/dist/src/daemon/constants.js +1 -1
- package/dist/src/daemon/install-plan.js +2 -2
- package/dist/src/daemon/launchd.js +2 -2
- package/dist/src/daemon/schtasks.js +2 -2
- package/dist/src/daemon/systemd.js +2 -2
- package/dist/src/extensions/bundle-mcp.js +1 -1
- package/dist/src/extensions/discover-extensions.js +1 -1
- package/dist/src/extensions/health.js +1 -1
- package/dist/src/extensions/loader.js +1 -1
- package/dist/src/extensions/lockfile.js +2 -2
- package/dist/src/extensions/update.d.ts +51 -0
- package/dist/src/extensions/update.js +260 -0
- package/dist/src/extensions/update.js.map +1 -0
- package/dist/src/gateway/agents-admin.d.ts +15 -8
- package/dist/src/gateway/agents-admin.js +78 -29
- package/dist/src/gateway/agents-admin.js.map +1 -1
- package/dist/src/gateway/file-path-classifier.js +2 -2
- package/dist/src/gateway/heartbeat/service.js +1 -1
- package/dist/src/gateway/hono/lib/config-payload.d.ts +5 -0
- package/dist/src/gateway/hono/lib/config-payload.js +3 -2
- package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
- package/dist/src/gateway/hono/lib/extension-store.js +2 -2
- package/dist/src/gateway/hono/lib/static-ui.js +2 -2
- package/dist/src/gateway/hono/middleware/auth.d.ts +2 -0
- package/dist/src/gateway/hono/middleware/auth.js +12 -7
- package/dist/src/gateway/hono/middleware/auth.js.map +1 -1
- package/dist/src/gateway/hono/oauth.js +1 -1
- package/dist/src/gateway/hono/routes/agents.js +56 -13
- package/dist/src/gateway/hono/routes/agents.js.map +1 -1
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
- package/dist/src/gateway/hono/routes/config-patch/agents.js +1 -1
- package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
- package/dist/src/gateway/hono/routes/dreaming.js +1 -1
- package/dist/src/gateway/hono/routes/host-fs.js +2 -2
- package/dist/src/gateway/hono/routes/models.js +1 -1
- package/dist/src/gateway/hono/routes/shares.js +1 -1
- package/dist/src/gateway/hono/routes/update.js +55 -107
- package/dist/src/gateway/hono/routes/update.js.map +1 -1
- package/dist/src/gateway/hono/routes/workflows.js +3 -1
- package/dist/src/gateway/hono/routes/workflows.js.map +1 -1
- package/dist/src/gateway/hono/routes/workspace.js +4 -4
- package/dist/src/gateway/lock.js +3 -3
- package/dist/src/gateway/ports.js +1 -1
- package/dist/src/gateway/server.js +2 -0
- package/dist/src/gateway/server.js.map +1 -1
- package/dist/src/gateway/service/agent-runner.js +2 -2
- package/dist/src/gateway/service/marketplace-service.js +2 -2
- package/dist/src/gateway/service.js +3 -2
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/gateway/workspace-fs-file-list.js +1 -1
- package/dist/src/heartbeat/index.js +1 -1
- package/dist/src/infra/brew.d.ts +4 -0
- package/dist/src/infra/brew.js +20 -0
- package/dist/src/infra/brew.js.map +1 -0
- package/dist/src/infra/package-json.d.ts +2 -0
- package/dist/src/infra/package-json.js +23 -0
- package/dist/src/infra/package-json.js.map +1 -0
- package/dist/src/infra/package-update-steps.d.ts +35 -0
- package/dist/src/infra/package-update-steps.js +304 -0
- package/dist/src/infra/package-update-steps.js.map +1 -0
- package/dist/src/infra/path-env.d.ts +11 -0
- package/dist/src/infra/path-env.js +90 -0
- package/dist/src/infra/path-env.js.map +1 -0
- package/dist/src/infra/path-prepend.d.ts +7 -0
- package/dist/src/infra/path-prepend.js +44 -0
- package/dist/src/infra/path-prepend.js.map +1 -0
- package/dist/src/infra/restart.js +2 -2
- package/dist/src/infra/stable-node-path.d.ts +2 -0
- package/dist/src/infra/stable-node-path.js +28 -0
- package/dist/src/infra/stable-node-path.js.map +1 -0
- package/dist/src/infra/update-check.js +1 -1
- package/dist/src/infra/update-global.d.ts +30 -23
- package/dist/src/infra/update-global.js +114 -65
- package/dist/src/infra/update-global.js.map +1 -1
- package/dist/src/infra/update-lock.js +3 -3
- package/dist/src/infra/update-log.d.ts +1 -0
- package/dist/src/infra/update-log.js +12 -0
- package/dist/src/infra/update-log.js.map +1 -0
- package/dist/src/infra/update-restart.d.ts +20 -0
- package/dist/src/infra/update-restart.js +165 -0
- package/dist/src/infra/update-restart.js.map +1 -0
- package/dist/src/infra/update-runner.d.ts +89 -1
- package/dist/src/infra/update-runner.js +604 -173
- package/dist/src/infra/update-runner.js.map +1 -1
- package/dist/src/infra/update-startup.d.ts +3 -0
- package/dist/src/infra/update-startup.js +10 -6
- package/dist/src/infra/update-startup.js.map +1 -1
- package/dist/src/infra/write-file-atomic.js +2 -2
- package/dist/src/providers/auth-runtime/auth-profile-store.js +1 -1
- package/dist/src/providers/index.js +2 -2
- package/dist/src/providers/model-registry.js +1 -1
- package/dist/src/routing/resolve-route.d.ts +3 -1
- package/dist/src/routing/resolve-route.js.map +1 -1
- package/dist/src/session/config-store.js +2 -2
- package/dist/src/session/init-session-turn.js +2 -2
- package/dist/src/session/parity/jsonl-transcript-io.js +2 -2
- package/dist/src/session/parity/sessions-json-file.js +1 -1
- package/dist/src/session/parity/transcript-file-lock.js +2 -2
- package/dist/src/session/parity/transcript-paths.js +1 -1
- package/dist/src/session/resolve-session.js +4 -4
- package/dist/src/session/search-index-cache.js +1 -1
- package/dist/src/session/search-index.js +1 -1
- package/dist/src/session/session-title.js +2 -2
- package/dist/src/session/store.d.ts +5 -3
- package/dist/src/session/store.js +71 -25
- package/dist/src/session/store.js.map +1 -1
- package/dist/src/share/share-auto.js +2 -2
- package/dist/src/share/share-store.js +3 -3
- package/dist/src/share/share-thumbnail.js +2 -2
- package/dist/src/share/share-zip.js +1 -1
- package/dist/src/share/site-share-store.js +3 -3
- package/dist/src/share/site-static-serve.js +1 -1
- package/dist/src/tui/clipboard-image.js +3 -3
- package/dist/src/tui/theme-manager.js +1 -1
- package/dist/src/tui/tui-keybindings-file.js +1 -1
- package/dist/src/tui/tui-scoped-models.js +2 -2
- package/dist/src/tui/tui-settings.js +1 -1
- package/dist/src/tui/tui.js +3 -3
- package/dist/src/tunnel/frpc-binary.js +3 -3
- package/dist/src/tunnel/frpc-config.js +1 -1
- package/dist/src/tunnel/frpc-extract.js +1 -1
- package/dist/src/tunnel/tunnel-state.js +1 -1
- package/dist/src/utils/logger/audit.js +1 -1
- package/dist/src/utils/logger/log-store.js +1 -1
- package/dist/src/utils/logger/rotation.js +1 -1
- package/dist/src/utils/logger/stats.d.ts +1 -1
- package/dist/src/voice/tts/audio.js +1 -1
- package/dist/src/voice/tts/providers/edge-speech.js +2 -2
- package/dist/src/workflows/domain/event.d.ts +3 -0
- package/dist/src/workflows/domain/run.d.ts +3 -0
- package/dist/src/workflows/domain/run.js.map +1 -1
- package/dist/src/workflows/engine/projector.js +17 -0
- package/dist/src/workflows/engine/projector.js.map +1 -1
- package/dist/src/workflows/engine/workflow-engine.js +127 -0
- package/dist/src/workflows/engine/workflow-engine.js.map +1 -1
- package/dist/src/workflows/index.js +1 -1
- package/dist/src/workflows/service/run-view-to-snapshot.js +3 -1
- package/dist/src/workflows/service/run-view-to-snapshot.js.map +1 -1
- package/dist/src/workflows/service/workflow-run-service.d.ts +1 -0
- package/dist/src/workflows/service/workflow-run-service.js +4 -1
- package/dist/src/workflows/service/workflow-run-service.js.map +1 -1
- package/dist/src/workflows/service/workflow-session-bridge.js +1 -1
- package/dist/src/workflows/store/event-store.js +1 -1
- package/dist/src/workflows/store/run-store.js +1 -1
- package/package.json +1 -1
- package/dist/gateway/static/root/assets/agents-B6PJB07W.js +0 -222
- package/dist/gateway/static/root/assets/apps-page-BOr0B1wv.js +0 -1
- package/dist/gateway/static/root/assets/channels-settings-BelUKggl.js +0 -1
- package/dist/gateway/static/root/assets/cron-api-CjOg-BIj.js +0 -1
- package/dist/gateway/static/root/assets/cron-dreaming-jobs-DueM3rBz.js +0 -2
- package/dist/gateway/static/root/assets/cron-page-DhoZmZXb.js +0 -1
- package/dist/gateway/static/root/assets/dist-6LecgDx5.js +0 -1
- package/dist/gateway/static/root/assets/index-CiN1cQiQ.css +0 -1
- package/dist/gateway/static/root/assets/logs-page-BwWLfqvd.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-DV5WN8uk.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-CfOBRbPX.js +0 -3
- package/dist/gateway/static/root/assets/skills-page-D0H5Kaxg.js +0 -2
- package/dist/gateway/static/root/assets/url-aYn-Rj1C.js +0 -7
- package/dist/gateway/static/root/assets/voice-api-key-field-X2UfnHeq.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-BOPpO3NG.js +0 -27
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import { createLogger } from "../utils/logger/index.js";
|
|
2
|
+
import { init_logger } from "../utils/logger.js";
|
|
3
|
+
import { init_paths, resolveBundledExtensionsDir, resolveExtensionsDir } from "../config/paths.js";
|
|
4
|
+
import { init_loader, loadConfig } from "../config/loader.js";
|
|
5
|
+
import { getExtensionLockfileManager } from "./lockfile.js";
|
|
6
|
+
import { installExtensionFromStoreZip, installFromNpm } from "./install.js";
|
|
7
|
+
import { findExtension } from "./marketplace.js";
|
|
8
|
+
import { downloadExtensionStoreZipBuffer, resolveExtensionZipDownloadUrl, resolveExtensionsStoreBaseUrl } from "../agent/skills/marketplace/adapters/store/store-api-client.js";
|
|
9
|
+
import { existsSync, readFileSync, readdirSync, rmSync } from "node:fs";
|
|
10
|
+
import { join } from "node:path";
|
|
11
|
+
import semver from "semver";
|
|
12
|
+
//#region src/extensions/update.ts
|
|
13
|
+
/**
|
|
14
|
+
* Post-update extension sync — refresh lockfile-managed npm / store extensions.
|
|
15
|
+
*/
|
|
16
|
+
init_paths();
|
|
17
|
+
init_loader();
|
|
18
|
+
init_logger();
|
|
19
|
+
const log = createLogger("ExtensionUpdate");
|
|
20
|
+
const MANIFEST = "xopc.extension.json";
|
|
21
|
+
function readInstalledExtensionVersion(targetDir, extensionId) {
|
|
22
|
+
const manifestPath = join(targetDir, extensionId, MANIFEST);
|
|
23
|
+
if (!existsSync(manifestPath)) return;
|
|
24
|
+
try {
|
|
25
|
+
const raw = JSON.parse(readFileSync(manifestPath, "utf-8"));
|
|
26
|
+
return (typeof raw.version === "string" ? semver.valid(raw.version) : null) ?? void 0;
|
|
27
|
+
} catch {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
async function resolveNpmPackageForId(extensionId) {
|
|
32
|
+
return (await findExtension(extensionId))?.npmPackage;
|
|
33
|
+
}
|
|
34
|
+
async function upsertNpmExtensionLock(lock, targetDir, result, spec) {
|
|
35
|
+
if (!result.extensionId) return;
|
|
36
|
+
const reg = await findExtension(result.extensionId);
|
|
37
|
+
const resolved = reg?.npmPackage ?? spec;
|
|
38
|
+
let ver = reg?.version ?? "0.0.0";
|
|
39
|
+
try {
|
|
40
|
+
const raw = readFileSync(join(targetDir, result.extensionId, MANIFEST), "utf-8");
|
|
41
|
+
const m = JSON.parse(raw);
|
|
42
|
+
const mv = typeof m.version === "string" ? semver.valid(m.version) : null;
|
|
43
|
+
if (mv) ver = mv;
|
|
44
|
+
} catch {}
|
|
45
|
+
await lock.upsert(result.extensionId, {
|
|
46
|
+
name: result.extensionId,
|
|
47
|
+
version: ver,
|
|
48
|
+
resolved,
|
|
49
|
+
source: "npm"
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
async function installExtensionFromStoreWithLock(params) {
|
|
53
|
+
try {
|
|
54
|
+
const { downloadUrl, version } = await resolveExtensionZipDownloadUrl(params.storeBase, params.packageName, params.version);
|
|
55
|
+
const result = await installExtensionFromStoreZip(await downloadExtensionStoreZipBuffer(params.storeBase, downloadUrl), params.targetDir);
|
|
56
|
+
if (!result.ok || !result.extensionId) return {
|
|
57
|
+
ok: false,
|
|
58
|
+
error: result.error ?? "install failed"
|
|
59
|
+
};
|
|
60
|
+
await params.lock.upsert(result.extensionId, {
|
|
61
|
+
name: result.extensionId,
|
|
62
|
+
version,
|
|
63
|
+
resolved: params.packageName,
|
|
64
|
+
source: "store"
|
|
65
|
+
});
|
|
66
|
+
return {
|
|
67
|
+
ok: true,
|
|
68
|
+
extensionId: result.extensionId,
|
|
69
|
+
version
|
|
70
|
+
};
|
|
71
|
+
} catch (err) {
|
|
72
|
+
return {
|
|
73
|
+
ok: false,
|
|
74
|
+
error: err instanceof Error ? err.message : String(err)
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function listBundledExtensionIds() {
|
|
79
|
+
const ids = /* @__PURE__ */ new Set();
|
|
80
|
+
const bundledDir = resolveBundledExtensionsDir();
|
|
81
|
+
if (!bundledDir || !existsSync(bundledDir)) return ids;
|
|
82
|
+
for (const entry of readdirSync(bundledDir, { withFileTypes: true })) if (entry.isDirectory()) ids.add(entry.name);
|
|
83
|
+
return ids;
|
|
84
|
+
}
|
|
85
|
+
async function syncExtensionsForUpdateChannel(params) {
|
|
86
|
+
const logger = params.logger ?? {};
|
|
87
|
+
const summary = {
|
|
88
|
+
skippedBundled: [],
|
|
89
|
+
warnings: []
|
|
90
|
+
};
|
|
91
|
+
const skipIds = /* @__PURE__ */ new Set();
|
|
92
|
+
if (params.channel !== "dev") return {
|
|
93
|
+
skipIds,
|
|
94
|
+
summary
|
|
95
|
+
};
|
|
96
|
+
const data = await getExtensionLockfileManager().load();
|
|
97
|
+
const bundledIds = listBundledExtensionIds();
|
|
98
|
+
for (const extensionId of Object.keys(data.extensions)) {
|
|
99
|
+
if (!bundledIds.has(extensionId)) continue;
|
|
100
|
+
skipIds.add(extensionId);
|
|
101
|
+
summary.skippedBundled.push(extensionId);
|
|
102
|
+
logger.info?.(`Skipping "${extensionId}" on dev channel (bundled copy preferred).`);
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
skipIds,
|
|
106
|
+
summary
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
async function updateSingleExtension(params) {
|
|
110
|
+
const { extensionId, entry, targetDir, storeBase, lock, timeoutMs, logger } = params;
|
|
111
|
+
const currentVersion = readInstalledExtensionVersion(targetDir, extensionId);
|
|
112
|
+
if (entry.source === "store") {
|
|
113
|
+
const pkgName = entry.resolved?.trim() || extensionId;
|
|
114
|
+
if (existsSync(join(targetDir, extensionId))) rmSync(join(targetDir, extensionId), {
|
|
115
|
+
recursive: true,
|
|
116
|
+
force: true
|
|
117
|
+
});
|
|
118
|
+
const result = await installExtensionFromStoreWithLock({
|
|
119
|
+
storeBase,
|
|
120
|
+
packageName: pkgName,
|
|
121
|
+
targetDir,
|
|
122
|
+
lock
|
|
123
|
+
});
|
|
124
|
+
if (result.ok === false) {
|
|
125
|
+
logger.error?.(`Failed to update ${extensionId}: ${result.error}`);
|
|
126
|
+
return {
|
|
127
|
+
extensionId,
|
|
128
|
+
status: "error",
|
|
129
|
+
message: result.error,
|
|
130
|
+
currentVersion
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
const nextVersion = result.version;
|
|
134
|
+
const status = currentVersion && nextVersion && currentVersion === nextVersion ? "unchanged" : "updated";
|
|
135
|
+
return {
|
|
136
|
+
extensionId,
|
|
137
|
+
status,
|
|
138
|
+
currentVersion,
|
|
139
|
+
nextVersion,
|
|
140
|
+
message: status === "unchanged" ? `${extensionId} is up to date (${currentVersion}).` : `Updated ${extensionId}: ${currentVersion ?? "unknown"} -> ${nextVersion}.`
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
if (entry.source !== "npm") return {
|
|
144
|
+
extensionId,
|
|
145
|
+
status: "skipped",
|
|
146
|
+
message: `Skipping "${extensionId}" (source: ${entry.source}).`
|
|
147
|
+
};
|
|
148
|
+
const spec = entry.resolved?.trim() || await resolveNpmPackageForId(extensionId);
|
|
149
|
+
if (!spec) return {
|
|
150
|
+
extensionId,
|
|
151
|
+
status: "skipped",
|
|
152
|
+
message: `Skipping "${extensionId}" (could not resolve npm package).`
|
|
153
|
+
};
|
|
154
|
+
if (existsSync(join(targetDir, extensionId))) rmSync(join(targetDir, extensionId), {
|
|
155
|
+
recursive: true,
|
|
156
|
+
force: true
|
|
157
|
+
});
|
|
158
|
+
const installResult = await installFromNpm(spec, targetDir, timeoutMs);
|
|
159
|
+
if (!installResult.ok) {
|
|
160
|
+
const message = installResult.error ?? "npm install failed";
|
|
161
|
+
logger.error?.(`Failed to update ${extensionId}: ${message}`);
|
|
162
|
+
return {
|
|
163
|
+
extensionId,
|
|
164
|
+
status: "error",
|
|
165
|
+
message,
|
|
166
|
+
currentVersion
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
await upsertNpmExtensionLock(lock, targetDir, installResult, spec);
|
|
170
|
+
const nextVersion = (installResult.extensionId ? readInstalledExtensionVersion(targetDir, installResult.extensionId) : void 0) ?? entry.version;
|
|
171
|
+
const resolvedId = installResult.extensionId ?? extensionId;
|
|
172
|
+
const status = currentVersion && nextVersion && currentVersion === nextVersion ? "unchanged" : "updated";
|
|
173
|
+
return {
|
|
174
|
+
extensionId: resolvedId,
|
|
175
|
+
status,
|
|
176
|
+
currentVersion,
|
|
177
|
+
nextVersion,
|
|
178
|
+
message: status === "unchanged" ? `${resolvedId} is up to date (${currentVersion}).` : `Updated ${resolvedId}: ${currentVersion ?? "unknown"} -> ${nextVersion}.`
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
async function updateNpmInstalledExtensions(params) {
|
|
182
|
+
const logger = params.logger ?? {};
|
|
183
|
+
const config = params.config ?? loadConfig();
|
|
184
|
+
const targetDir = resolveExtensionsDir();
|
|
185
|
+
const storeBase = resolveExtensionsStoreBaseUrl(config);
|
|
186
|
+
const lock = getExtensionLockfileManager();
|
|
187
|
+
const data = await lock.load();
|
|
188
|
+
const ids = params.extensionIds?.length ? params.extensionIds : Object.keys(data.extensions);
|
|
189
|
+
if (ids.length === 0) return {
|
|
190
|
+
outcomes: [],
|
|
191
|
+
status: "skipped"
|
|
192
|
+
};
|
|
193
|
+
const outcomes = [];
|
|
194
|
+
let hasError = false;
|
|
195
|
+
for (const extensionId of ids) {
|
|
196
|
+
if (params.skipIds?.has(extensionId)) {
|
|
197
|
+
outcomes.push({
|
|
198
|
+
extensionId,
|
|
199
|
+
status: "skipped",
|
|
200
|
+
message: `Skipping "${extensionId}" (channel sync).`
|
|
201
|
+
});
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
const entry = data.extensions[extensionId];
|
|
205
|
+
if (!entry) {
|
|
206
|
+
outcomes.push({
|
|
207
|
+
extensionId,
|
|
208
|
+
status: "skipped",
|
|
209
|
+
message: `No lockfile entry for "${extensionId}".`
|
|
210
|
+
});
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
const outcome = await updateSingleExtension({
|
|
214
|
+
extensionId,
|
|
215
|
+
entry,
|
|
216
|
+
targetDir,
|
|
217
|
+
storeBase,
|
|
218
|
+
lock,
|
|
219
|
+
timeoutMs: params.timeoutMs,
|
|
220
|
+
logger
|
|
221
|
+
});
|
|
222
|
+
outcomes.push(outcome);
|
|
223
|
+
if (outcome.status === "error") hasError = true;
|
|
224
|
+
else if (outcome.status === "updated") log.info({
|
|
225
|
+
extensionId: outcome.extensionId,
|
|
226
|
+
nextVersion: outcome.nextVersion
|
|
227
|
+
}, outcome.message);
|
|
228
|
+
}
|
|
229
|
+
return {
|
|
230
|
+
outcomes,
|
|
231
|
+
status: hasError ? "error" : "ok"
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
async function runPostUpdateExtensionSync(params) {
|
|
235
|
+
const logger = params.logger ?? {
|
|
236
|
+
info: (message) => log.info(message),
|
|
237
|
+
warn: (message) => log.warn(message),
|
|
238
|
+
error: (message) => log.error(message)
|
|
239
|
+
};
|
|
240
|
+
const channelSyncResult = await syncExtensionsForUpdateChannel({
|
|
241
|
+
channel: params.channel,
|
|
242
|
+
config: params.config,
|
|
243
|
+
logger
|
|
244
|
+
});
|
|
245
|
+
const updateResult = await updateNpmInstalledExtensions({
|
|
246
|
+
skipIds: channelSyncResult.skipIds,
|
|
247
|
+
config: params.config,
|
|
248
|
+
timeoutMs: params.timeoutMs,
|
|
249
|
+
logger
|
|
250
|
+
});
|
|
251
|
+
return {
|
|
252
|
+
status: updateResult.status,
|
|
253
|
+
outcomes: updateResult.outcomes,
|
|
254
|
+
channelSync: channelSyncResult.summary
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
//#endregion
|
|
258
|
+
export { runPostUpdateExtensionSync, syncExtensionsForUpdateChannel, updateNpmInstalledExtensions };
|
|
259
|
+
|
|
260
|
+
//# sourceMappingURL=update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.js","names":["marketplace.findExtension"],"sources":["../../../src/extensions/update.ts"],"sourcesContent":["/**\n * Post-update extension sync — refresh lockfile-managed npm / store extensions.\n */\n\nimport { existsSync, readFileSync, readdirSync, rmSync } from 'node:fs';\nimport { join } from 'node:path';\nimport semver from 'semver';\n\nimport {\n downloadExtensionStoreZipBuffer,\n resolveExtensionZipDownloadUrl,\n resolveExtensionsStoreBaseUrl,\n} from '../agent/skills/marketplace/adapters/store/store-api-client.js';\nimport type { Config } from '../config/schema.js';\nimport { resolveBundledExtensionsDir, resolveExtensionsDir } from '../config/paths.js';\nimport { loadConfig } from '../config/loader.js';\nimport type { UpdateChannel } from '../infra/update-channels.js';\nimport { createLogger } from '../utils/logger.js';\nimport {\n installExtensionFromStoreZip,\n installFromNpm,\n type InstallResult,\n} from './install.js';\nimport {\n getExtensionLockfileManager,\n type ExtensionLockEntry,\n} from './lockfile.js';\nimport * as marketplace from './marketplace.js';\n\nconst log = createLogger('ExtensionUpdate');\n\nconst MANIFEST = 'xopc.extension.json';\n\nexport type ExtensionUpdateLogger = {\n info?: (message: string) => void;\n warn?: (message: string) => void;\n error?: (message: string) => void;\n};\n\nexport type ExtensionUpdateStatus = 'updated' | 'unchanged' | 'skipped' | 'error';\n\nexport type ExtensionUpdateOutcome = {\n extensionId: string;\n status: ExtensionUpdateStatus;\n message: string;\n currentVersion?: string;\n nextVersion?: string;\n};\n\nexport type ExtensionChannelSyncSummary = {\n skippedBundled: string[];\n warnings: string[];\n};\n\nexport type ExtensionPostUpdateResult = {\n status: 'ok' | 'error' | 'skipped';\n outcomes: ExtensionUpdateOutcome[];\n channelSync?: ExtensionChannelSyncSummary;\n};\n\nfunction readInstalledExtensionVersion(targetDir: string, extensionId: string): string | undefined {\n const manifestPath = join(targetDir, extensionId, MANIFEST);\n if (!existsSync(manifestPath)) {\n return undefined;\n }\n try {\n const raw = JSON.parse(readFileSync(manifestPath, 'utf-8')) as { version?: string };\n const version = typeof raw.version === 'string' ? semver.valid(raw.version) : null;\n return version ?? undefined;\n } catch {\n return undefined;\n }\n}\n\nasync function resolveNpmPackageForId(extensionId: string): Promise<string | undefined> {\n const found = await marketplace.findExtension(extensionId);\n return found?.npmPackage;\n}\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 });\n}\n\nasync function installExtensionFromStoreWithLock(params: {\n storeBase: string;\n packageName: string;\n version?: string;\n targetDir: string;\n lock: ReturnType<typeof getExtensionLockfileManager>;\n}): Promise<{ ok: true; extensionId: string; version: string } | { ok: false; error: string }> {\n try {\n const { downloadUrl, version } = await resolveExtensionZipDownloadUrl(\n params.storeBase,\n params.packageName,\n params.version,\n );\n const buf = await downloadExtensionStoreZipBuffer(params.storeBase, downloadUrl);\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 });\n return { ok: true, extensionId: result.extensionId, version };\n } catch (err) {\n return { ok: false, error: err instanceof Error ? err.message : String(err) };\n }\n}\n\nfunction listBundledExtensionIds(): Set<string> {\n const ids = new Set<string>();\n const bundledDir = resolveBundledExtensionsDir();\n if (!bundledDir || !existsSync(bundledDir)) {\n return ids;\n }\n for (const entry of readdirSync(bundledDir, { withFileTypes: true })) {\n if (entry.isDirectory()) {\n ids.add(entry.name);\n }\n }\n return ids;\n}\n\nexport async function syncExtensionsForUpdateChannel(params: {\n channel: UpdateChannel;\n config?: Config;\n logger?: ExtensionUpdateLogger;\n}): Promise<{ skipIds: Set<string>; summary: ExtensionChannelSyncSummary }> {\n const logger = params.logger ?? {};\n const summary: ExtensionChannelSyncSummary = {\n skippedBundled: [],\n warnings: [],\n };\n const skipIds = new Set<string>();\n\n if (params.channel !== 'dev') {\n return { skipIds, summary };\n }\n\n const lock = getExtensionLockfileManager();\n const data = await lock.load();\n const bundledIds = listBundledExtensionIds();\n\n for (const extensionId of Object.keys(data.extensions)) {\n if (!bundledIds.has(extensionId)) {\n continue;\n }\n skipIds.add(extensionId);\n summary.skippedBundled.push(extensionId);\n logger.info?.(`Skipping \"${extensionId}\" on dev channel (bundled copy preferred).`);\n }\n\n return { skipIds, summary };\n}\n\nasync function updateSingleExtension(params: {\n extensionId: string;\n entry: ExtensionLockEntry;\n targetDir: string;\n storeBase: string;\n lock: ReturnType<typeof getExtensionLockfileManager>;\n timeoutMs?: number;\n logger?: ExtensionUpdateLogger;\n}): Promise<ExtensionUpdateOutcome> {\n const { extensionId, entry, targetDir, storeBase, lock, timeoutMs, logger } = params;\n const currentVersion = readInstalledExtensionVersion(targetDir, extensionId);\n\n if (entry.source === 'store') {\n const pkgName = entry.resolved?.trim() || extensionId;\n if (existsSync(join(targetDir, extensionId))) {\n rmSync(join(targetDir, extensionId), { recursive: true, force: true });\n }\n const result = await installExtensionFromStoreWithLock({\n storeBase,\n packageName: pkgName,\n targetDir,\n lock,\n });\n if (result.ok === false) {\n logger.error?.(`Failed to update ${extensionId}: ${result.error}`);\n return {\n extensionId,\n status: 'error',\n message: result.error,\n currentVersion,\n };\n }\n const nextVersion = result.version;\n const status =\n currentVersion && nextVersion && currentVersion === nextVersion ? 'unchanged' : 'updated';\n return {\n extensionId,\n status,\n currentVersion,\n nextVersion,\n message:\n status === 'unchanged'\n ? `${extensionId} is up to date (${currentVersion}).`\n : `Updated ${extensionId}: ${currentVersion ?? 'unknown'} -> ${nextVersion}.`,\n };\n }\n\n if (entry.source !== 'npm') {\n return {\n extensionId,\n status: 'skipped',\n message: `Skipping \"${extensionId}\" (source: ${entry.source}).`,\n };\n }\n\n const spec = entry.resolved?.trim() || (await resolveNpmPackageForId(extensionId));\n if (!spec) {\n return {\n extensionId,\n status: 'skipped',\n message: `Skipping \"${extensionId}\" (could not resolve npm package).`,\n };\n }\n\n if (existsSync(join(targetDir, extensionId))) {\n rmSync(join(targetDir, extensionId), { recursive: true, force: true });\n }\n\n const installResult = await installFromNpm(spec, targetDir, timeoutMs);\n if (!installResult.ok) {\n const message = installResult.error ?? 'npm install failed';\n logger.error?.(`Failed to update ${extensionId}: ${message}`);\n return {\n extensionId,\n status: 'error',\n message,\n currentVersion,\n };\n }\n\n await upsertNpmExtensionLock(lock, targetDir, installResult, spec);\n const nextVersion =\n (installResult.extensionId\n ? readInstalledExtensionVersion(targetDir, installResult.extensionId)\n : undefined) ?? entry.version;\n const resolvedId = installResult.extensionId ?? extensionId;\n const status =\n currentVersion && nextVersion && currentVersion === nextVersion ? 'unchanged' : 'updated';\n return {\n extensionId: resolvedId,\n status,\n currentVersion,\n nextVersion,\n message:\n status === 'unchanged'\n ? `${resolvedId} is up to date (${currentVersion}).`\n : `Updated ${resolvedId}: ${currentVersion ?? 'unknown'} -> ${nextVersion}.`,\n };\n}\n\nexport async function updateNpmInstalledExtensions(params: {\n extensionIds?: string[];\n skipIds?: Set<string>;\n config?: Config;\n timeoutMs?: number;\n logger?: ExtensionUpdateLogger;\n}): Promise<{ outcomes: ExtensionUpdateOutcome[]; status: 'ok' | 'error' | 'skipped' }> {\n const logger = params.logger ?? {};\n const config = params.config ?? loadConfig();\n const targetDir = resolveExtensionsDir();\n const storeBase = resolveExtensionsStoreBaseUrl(config);\n const lock = getExtensionLockfileManager();\n const data = await lock.load();\n\n const ids = params.extensionIds?.length\n ? params.extensionIds\n : Object.keys(data.extensions);\n\n if (ids.length === 0) {\n return { outcomes: [], status: 'skipped' };\n }\n\n const outcomes: ExtensionUpdateOutcome[] = [];\n let hasError = false;\n\n for (const extensionId of ids) {\n if (params.skipIds?.has(extensionId)) {\n outcomes.push({\n extensionId,\n status: 'skipped',\n message: `Skipping \"${extensionId}\" (channel sync).`,\n });\n continue;\n }\n\n const entry = data.extensions[extensionId];\n if (!entry) {\n outcomes.push({\n extensionId,\n status: 'skipped',\n message: `No lockfile entry for \"${extensionId}\".`,\n });\n continue;\n }\n\n const outcome = await updateSingleExtension({\n extensionId,\n entry,\n targetDir,\n storeBase,\n lock,\n timeoutMs: params.timeoutMs,\n logger,\n });\n outcomes.push(outcome);\n if (outcome.status === 'error') {\n hasError = true;\n } else if (outcome.status === 'updated') {\n log.info(\n { extensionId: outcome.extensionId, nextVersion: outcome.nextVersion },\n outcome.message,\n );\n }\n }\n\n return { outcomes, status: hasError ? 'error' : 'ok' };\n}\n\nexport async function runPostUpdateExtensionSync(params: {\n channel: UpdateChannel;\n config?: Config;\n timeoutMs?: number;\n logger?: ExtensionUpdateLogger;\n}): Promise<ExtensionPostUpdateResult> {\n const logger = params.logger ?? {\n info: (message) => log.info(message),\n warn: (message) => log.warn(message),\n error: (message) => log.error(message),\n };\n\n const channelSyncResult = await syncExtensionsForUpdateChannel({\n channel: params.channel,\n config: params.config,\n logger,\n });\n\n const updateResult = await updateNpmInstalledExtensions({\n skipIds: channelSyncResult.skipIds,\n config: params.config,\n timeoutMs: params.timeoutMs,\n logger,\n });\n\n return {\n status: updateResult.status,\n outcomes: updateResult.outcomes,\n channelSync: channelSyncResult.summary,\n };\n}\n"],"mappings":"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"}
|
|
@@ -2,16 +2,20 @@
|
|
|
2
2
|
* Gateway REST helpers for multi-agent management.
|
|
3
3
|
*/
|
|
4
4
|
import type { Config } from '../config/schema.js';
|
|
5
|
+
import type { LocalizedText } from '../config/localized-text.js';
|
|
5
6
|
import type { AgentTypedModel } from '../config/schema.js';
|
|
6
7
|
export type GatewayAgentTypedModelsInfo = {
|
|
7
8
|
defaults: AgentTypedModel[];
|
|
8
|
-
entry?: AgentTypedModel[];
|
|
9
9
|
effective: AgentTypedModel[];
|
|
10
10
|
};
|
|
11
11
|
export type GatewayAgentRow = {
|
|
12
12
|
id: string;
|
|
13
13
|
name?: string;
|
|
14
14
|
description?: string;
|
|
15
|
+
localized?: {
|
|
16
|
+
name?: LocalizedText;
|
|
17
|
+
description?: LocalizedText;
|
|
18
|
+
};
|
|
15
19
|
/** Value from `IDENTITY.md` **Avatar:** line when present (may be URL, `xopc:…`, etc.). */
|
|
16
20
|
avatar?: string;
|
|
17
21
|
workspace: string;
|
|
@@ -41,20 +45,24 @@ export type GatewayAgentsListResponse = {
|
|
|
41
45
|
};
|
|
42
46
|
/** Extract `**Avatar:**` value from profile IDENTITY.md (same line shape as the gateway console parser). */
|
|
43
47
|
export declare function extractAvatarFromIdentityMarkdown(content: string): string | undefined;
|
|
44
|
-
export declare function listGatewayAgents(cfg: Config
|
|
48
|
+
export declare function listGatewayAgents(cfg: Config, options?: {
|
|
49
|
+
locale?: string;
|
|
50
|
+
}): Promise<GatewayAgentsListResponse>;
|
|
45
51
|
export type CreateAgentBody = {
|
|
46
52
|
/** Display name stored on the agent entry. */
|
|
47
|
-
name:
|
|
53
|
+
name: LocalizedText;
|
|
48
54
|
/** Optional id seed; normalized agent id defaults from `name` when omitted. */
|
|
49
55
|
id?: string;
|
|
50
56
|
workspace: string;
|
|
51
57
|
model?: string;
|
|
52
58
|
agentDir?: string;
|
|
53
|
-
description?:
|
|
59
|
+
description?: LocalizedText;
|
|
54
60
|
/** Initial `agents.list[].tools.disable` for the new entry. */
|
|
55
61
|
toolsDisable?: string[];
|
|
56
62
|
/** Profile markdown files to write after seeding (e.g. `IDENTITY.md`, `SOUL.md`). */
|
|
57
63
|
profileFiles?: Record<string, string>;
|
|
64
|
+
/** Clone from an existing agent id — copies config entry fields and profile directory. */
|
|
65
|
+
cloneFrom?: string;
|
|
58
66
|
};
|
|
59
67
|
export type AgentAdminHttpStatus = 400 | 404 | 409;
|
|
60
68
|
export type AgentAdminResult<T> = {
|
|
@@ -80,10 +88,11 @@ export declare function prepareCreateAgentsBatch(cfg: Config, bodies: CreateAgen
|
|
|
80
88
|
}>;
|
|
81
89
|
export declare function finalizeCreateAgentDirs(cfg: Config, agentId: string, opts?: {
|
|
82
90
|
profileFiles?: Record<string, string>;
|
|
91
|
+
cloneFrom?: string;
|
|
83
92
|
}): Promise<AgentAdminResult<void>>;
|
|
84
93
|
export type UpdateAgentBody = {
|
|
85
|
-
name?:
|
|
86
|
-
description?:
|
|
94
|
+
name?: LocalizedText;
|
|
95
|
+
description?: LocalizedText | null;
|
|
87
96
|
workspace?: string;
|
|
88
97
|
model?: string | null;
|
|
89
98
|
agentDir?: string | null;
|
|
@@ -92,8 +101,6 @@ export type UpdateAgentBody = {
|
|
|
92
101
|
skills?: string[] | null;
|
|
93
102
|
/** Replace `agents.list[].tools.disable`; `null` clears entry-level disables. */
|
|
94
103
|
toolsDisable?: string[] | null;
|
|
95
|
-
/** Replace `agents.list[].models`; `null` removes entry overrides (inherit defaults). */
|
|
96
|
-
models?: AgentTypedModel[] | null;
|
|
97
104
|
};
|
|
98
105
|
export declare function prepareUpdateAgent(cfg: Config, agentIdRaw: string, body: UpdateAgentBody): AgentAdminResult<{
|
|
99
106
|
nextConfig: Config;
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { DEFAULT_AGENT_ID, init_agent_scope, listAgentEntries, normalizeAgentId, resolveAgentDir, resolveAgentProfileDir, resolveAgentWorkspaceDir, resolveDefaultAgentId, resolveUserPath, validateAgentIdForNewAgent } from "../agent/agent-scope.js";
|
|
2
|
-
import { resolveEffectiveAgentProfile } from "../config/agent-profile.js";
|
|
3
2
|
import { WORKSPACE_FILES, init_paths } from "../config/paths.js";
|
|
3
|
+
import { init_localized_text, normalizeLocalizedText, resolveLocalizedText } from "../config/localized-text.js";
|
|
4
|
+
import { resolveEffectiveAgentProfile } from "../config/agent-profile.js";
|
|
4
5
|
import { AGENT_PROFILE_MARKDOWN_SYSTEM_FILES } from "../agent/context/workspace.js";
|
|
5
6
|
import { isPathUnderWorkspace, resolveWorkspaceSafePath } from "./workspace-editor-path.js";
|
|
6
7
|
import { applyAgentConfig, findAgentEntryIndex, pruneAgentConfig, removeAgentDirsFromDisk } from "../commands/agents.config.js";
|
|
7
|
-
import { resolveEffectiveTypedModels } from "../config/agent-typed-models.js";
|
|
8
8
|
import { GATEWAY_BUILTIN_TOOL_IDS } from "./agent-builtin-tools.js";
|
|
9
9
|
import { seedAgentProfileMarkdownFiles } from "../agent/context/workspace-seed.js";
|
|
10
|
-
import {
|
|
10
|
+
import { cp, mkdir, readFile, readdir, realpath, stat, unlink, writeFile } from "node:fs/promises";
|
|
11
11
|
import { join, resolve } from "node:path";
|
|
12
|
-
import { mkdir, readFile, realpath, stat, unlink, writeFile } from "node:fs/promises";
|
|
13
12
|
//#region src/gateway/agents-admin.ts
|
|
14
13
|
/**
|
|
15
14
|
* Gateway REST helpers for multi-agent management.
|
|
16
15
|
*/
|
|
17
16
|
init_agent_scope();
|
|
17
|
+
init_localized_text();
|
|
18
18
|
init_paths();
|
|
19
19
|
const EDITABLE_PROFILE_MARKDOWN_NAMES = new Set([...AGENT_PROFILE_MARKDOWN_SYSTEM_FILES, WORKSPACE_FILES.BOOTSTRAP]);
|
|
20
20
|
function collectAgentIdsForList(cfg) {
|
|
@@ -36,7 +36,7 @@ function extractAvatarFromIdentityMarkdown(content) {
|
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
|
-
async function listGatewayAgents(cfg) {
|
|
39
|
+
async function listGatewayAgents(cfg, options = {}) {
|
|
40
40
|
const defaultId = resolveDefaultAgentId(cfg);
|
|
41
41
|
const agents = [];
|
|
42
42
|
const defaultsSkills = cfg.agents?.defaults?.skills;
|
|
@@ -51,23 +51,29 @@ async function listGatewayAgents(cfg) {
|
|
|
51
51
|
} : void 0;
|
|
52
52
|
const entrySkills = entry?.skills;
|
|
53
53
|
const entryDisable = entry?.tools?.disable ?? [];
|
|
54
|
-
const
|
|
55
|
-
const effectiveTypedModels = [...resolveEffectiveTypedModels(cfg, id).values()];
|
|
54
|
+
const effectiveTypedModels = [...defaultsTypedModels];
|
|
56
55
|
let avatar;
|
|
57
56
|
try {
|
|
58
57
|
avatar = extractAvatarFromIdentityMarkdown(await readFile(join(resolveAgentProfileDir(cfg, id), WORKSPACE_FILES.IDENTITY), "utf-8"));
|
|
59
58
|
} catch {}
|
|
59
|
+
const localizedName = normalizeLocalizedText(entry?.name);
|
|
60
|
+
const localizedDescription = normalizeLocalizedText(entry?.description);
|
|
61
|
+
const displayName = resolveLocalizedText(localizedName, options.locale);
|
|
62
|
+
const displayDescription = resolveLocalizedText(localizedDescription, options.locale);
|
|
60
63
|
agents.push({
|
|
61
64
|
id,
|
|
62
|
-
...
|
|
63
|
-
...
|
|
65
|
+
...displayName ? { name: displayName } : {},
|
|
66
|
+
...displayDescription ? { description: displayDescription } : {},
|
|
67
|
+
...localizedName || localizedDescription ? { localized: {
|
|
68
|
+
...localizedName ? { name: localizedName } : {},
|
|
69
|
+
...localizedDescription ? { description: localizedDescription } : {}
|
|
70
|
+
} } : {},
|
|
64
71
|
...avatar ? { avatar } : {},
|
|
65
72
|
workspace: profile.resolvedWorkspacePath,
|
|
66
73
|
profileDir: resolveAgentProfileDir(cfg, id),
|
|
67
74
|
...model ? { model } : {},
|
|
68
75
|
typedModels: {
|
|
69
76
|
defaults: [...defaultsTypedModels],
|
|
70
|
-
...entryTypedModels !== void 0 ? { entry: [...entryTypedModels] } : {},
|
|
71
77
|
effective: effectiveTypedModels
|
|
72
78
|
},
|
|
73
79
|
isDefault: id === defaultId,
|
|
@@ -99,8 +105,9 @@ function requireNonMain(id) {
|
|
|
99
105
|
return null;
|
|
100
106
|
}
|
|
101
107
|
function prepareCreateAgent(cfg, body) {
|
|
102
|
-
const
|
|
103
|
-
|
|
108
|
+
const normalizedName = normalizeLocalizedText(body.name);
|
|
109
|
+
const nameSeed = resolveLocalizedText(normalizedName, "en") ?? "";
|
|
110
|
+
if (!nameSeed) return {
|
|
104
111
|
ok: false,
|
|
105
112
|
error: "name is required",
|
|
106
113
|
status: 400
|
|
@@ -111,7 +118,7 @@ function prepareCreateAgent(cfg, body) {
|
|
|
111
118
|
error: "workspace is required",
|
|
112
119
|
status: 400
|
|
113
120
|
};
|
|
114
|
-
const idRes = validateAgentIdForNewAgent(body.id,
|
|
121
|
+
const idRes = validateAgentIdForNewAgent(body.id, nameSeed);
|
|
115
122
|
if (idRes.ok === false) return {
|
|
116
123
|
ok: false,
|
|
117
124
|
error: idRes.error,
|
|
@@ -139,25 +146,53 @@ function prepareCreateAgent(cfg, body) {
|
|
|
139
146
|
};
|
|
140
147
|
}
|
|
141
148
|
}
|
|
149
|
+
let cloneSourceEntry;
|
|
150
|
+
if (body.cloneFrom) {
|
|
151
|
+
const srcId = normalizeAgentId(body.cloneFrom);
|
|
152
|
+
cloneSourceEntry = listAgentEntries(cfg).find((e) => normalizeAgentId(e.id) === srcId);
|
|
153
|
+
if (!cloneSourceEntry && srcId !== resolveDefaultAgentId(cfg)) return {
|
|
154
|
+
ok: false,
|
|
155
|
+
error: `source agent "${srcId}" not found`,
|
|
156
|
+
status: 404
|
|
157
|
+
};
|
|
158
|
+
}
|
|
142
159
|
const wsAbs = resolveUserPath(workspace);
|
|
160
|
+
const effectiveModel = body.model?.trim() ? body.model.trim() : cloneSourceEntry?.model?.primary;
|
|
143
161
|
let next = applyAgentConfig(cfg, {
|
|
144
162
|
agentId,
|
|
145
|
-
name,
|
|
163
|
+
name: normalizedName,
|
|
146
164
|
workspace: wsAbs,
|
|
147
|
-
...
|
|
165
|
+
...effectiveModel ? { model: effectiveModel } : {},
|
|
148
166
|
...body.agentDir?.trim() ? { agentDir: body.agentDir.trim() } : {},
|
|
149
|
-
...body.description
|
|
167
|
+
...normalizeLocalizedText(body.description) ? { description: normalizeLocalizedText(body.description) } : {}
|
|
150
168
|
});
|
|
151
|
-
|
|
169
|
+
const toolsDisable = body.toolsDisable ?? cloneSourceEntry?.tools?.disable;
|
|
170
|
+
if (toolsDisable !== void 0) {
|
|
152
171
|
const list = [...listAgentEntries(next)];
|
|
153
172
|
const idx = findAgentEntryIndex(list, agentId);
|
|
154
173
|
if (idx >= 0) {
|
|
155
174
|
const entry = { ...list[idx] };
|
|
156
|
-
const disable =
|
|
175
|
+
const disable = toolsDisable.map((s) => String(s).trim()).filter(Boolean);
|
|
157
176
|
entry.tools = {
|
|
158
177
|
...entry.tools,
|
|
159
178
|
disable
|
|
160
179
|
};
|
|
180
|
+
if (cloneSourceEntry?.skills !== void 0 && body.cloneFrom) entry.skills = [...cloneSourceEntry.skills];
|
|
181
|
+
list[idx] = entry;
|
|
182
|
+
next = {
|
|
183
|
+
...next,
|
|
184
|
+
agents: {
|
|
185
|
+
...next.agents,
|
|
186
|
+
list
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
} else if (cloneSourceEntry && body.cloneFrom) {
|
|
191
|
+
const list = [...listAgentEntries(next)];
|
|
192
|
+
const idx = findAgentEntryIndex(list, agentId);
|
|
193
|
+
if (idx >= 0) {
|
|
194
|
+
const entry = { ...list[idx] };
|
|
195
|
+
if (cloneSourceEntry.skills !== void 0) entry.skills = [...cloneSourceEntry.skills];
|
|
161
196
|
list[idx] = entry;
|
|
162
197
|
next = {
|
|
163
198
|
...next,
|
|
@@ -210,7 +245,24 @@ async function finalizeCreateAgentDirs(cfg, agentId, opts) {
|
|
|
210
245
|
await mkdir(profilePath, { recursive: true });
|
|
211
246
|
await mkdir(adPath, { recursive: true });
|
|
212
247
|
const id = normalizeAgentId(agentId);
|
|
213
|
-
|
|
248
|
+
const displayName = resolveLocalizedText(normalizeLocalizedText(listAgentEntries(cfg).find((e) => normalizeAgentId(e.id) === id)?.name), "en") || id;
|
|
249
|
+
if (opts?.cloneFrom) {
|
|
250
|
+
const srcProfilePath = resolveAgentProfileDir(cfg, normalizeAgentId(opts.cloneFrom));
|
|
251
|
+
try {
|
|
252
|
+
if ((await stat(srcProfilePath)).isDirectory()) {
|
|
253
|
+
const srcFiles = await readdir(srcProfilePath);
|
|
254
|
+
for (const fileName of srcFiles) {
|
|
255
|
+
const srcFile = join(srcProfilePath, fileName);
|
|
256
|
+
const dstFile = join(profilePath, fileName);
|
|
257
|
+
try {
|
|
258
|
+
if ((await stat(srcFile)).isFile()) await cp(srcFile, dstFile);
|
|
259
|
+
} catch {}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
} catch {
|
|
263
|
+
seedAgentProfileMarkdownFiles(profilePath, wsPath, { displayName });
|
|
264
|
+
}
|
|
265
|
+
} else seedAgentProfileMarkdownFiles(profilePath, wsPath, { displayName });
|
|
214
266
|
const profileFiles = opts?.profileFiles;
|
|
215
267
|
if (profileFiles && Object.keys(profileFiles).length > 0) for (const [name, content] of Object.entries(profileFiles)) {
|
|
216
268
|
const written = await writeAgentProfileFile(cfg, agentId, name, content);
|
|
@@ -239,11 +291,14 @@ function prepareUpdateAgent(cfg, agentIdRaw, body) {
|
|
|
239
291
|
};
|
|
240
292
|
const entry = { ...list[idx] };
|
|
241
293
|
if (body.name !== void 0) {
|
|
242
|
-
const
|
|
243
|
-
if (
|
|
294
|
+
const nextName = normalizeLocalizedText(body.name);
|
|
295
|
+
if (nextName) entry.name = nextName;
|
|
296
|
+
}
|
|
297
|
+
if (body.description !== void 0) {
|
|
298
|
+
const nextDescription = body.description === null ? void 0 : normalizeLocalizedText(body.description);
|
|
299
|
+
if (nextDescription) entry.description = nextDescription;
|
|
300
|
+
else delete entry.description;
|
|
244
301
|
}
|
|
245
|
-
if (body.description !== void 0) if (body.description === null || String(body.description).trim() === "") delete entry.description;
|
|
246
|
-
else entry.description = String(body.description).trim();
|
|
247
302
|
if (body.workspace !== void 0) {
|
|
248
303
|
const w = body.workspace.trim();
|
|
249
304
|
if (w) entry.workspace = resolveUserPath(w);
|
|
@@ -278,12 +333,6 @@ function prepareUpdateAgent(cfg, agentIdRaw, body) {
|
|
|
278
333
|
disable: next
|
|
279
334
|
};
|
|
280
335
|
}
|
|
281
|
-
if (body.models !== void 0) if (body.models === null) delete entry.models;
|
|
282
|
-
else {
|
|
283
|
-
const normalized = normalizePatchTypedModels(body.models);
|
|
284
|
-
if (normalized === null || normalized === void 0) delete entry.models;
|
|
285
|
-
else entry.models = normalized;
|
|
286
|
-
}
|
|
287
336
|
list[idx] = entry;
|
|
288
337
|
let next = {
|
|
289
338
|
...cfg,
|