@xopcai/xopc 0.0.118 → 0.0.120
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 +2 -1
- package/README.zh-CN.md +2 -1
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-dzUrQoeZ.js → agent-avatar-dicebear-APTlX9Sq.js} +1 -1
- package/dist/gateway/static/root/assets/agents-CFW_FS_V.js +2 -0
- package/dist/gateway/static/root/assets/app-management-settings-panel-DTKc5HHT.js +1 -0
- package/dist/gateway/static/root/assets/appearance-settings-BTciFrE9.js +1 -0
- package/dist/gateway/static/root/assets/{apps-page--wMEL00f.js → apps-page-DT52OrbM.js} +1 -1
- package/dist/gateway/static/root/assets/{archive-plugin-Cki4SfU2.js → archive-plugin-CiHaUMII.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-D-KnS2Do.js → attachment-load-t4gSrNjL.js} +1 -1
- package/dist/gateway/static/root/assets/automation-suggestion-card-CtysjSoQ.js +1 -0
- package/dist/gateway/static/root/assets/automations-page-B2YvT3ES.js +1 -0
- package/dist/gateway/static/root/assets/{binary-plugins-D2sgvJja.js → binary-plugins-BAbSldW5.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-DIq-4Gvb.js → block-editor-BNr_82xl.js} +28 -28
- package/dist/gateway/static/root/assets/browser-settings-page-BQEXPhDU.js +8 -0
- package/dist/gateway/static/root/assets/capability-presets-api-tzD702Gg.js +1 -0
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-AGhTueAc.js +1 -0
- package/dist/gateway/static/root/assets/channel-recipient-api-DL_KzwGE.js +1 -0
- package/dist/gateway/static/root/assets/channels-settings-DRTutLlN.js +1 -0
- package/dist/gateway/static/root/assets/cn-BQ_8x0bT.js +1 -0
- package/dist/gateway/static/root/assets/connectors-page-DneJVuge.js +2 -0
- package/dist/gateway/static/root/assets/cron-expression-B3B1eqnr.js +2 -0
- package/dist/gateway/static/root/assets/dreaming-settings-BEwWA1yf.js +1 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-DYu1KaFQ.js → extension-debug-page-Dl2kO0Sf.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-B3W6QwlZ.js → extension-page-DmbLPsx_.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-D7VQ-cxE.js → extension-settings-page-BS2rx40e.js} +1 -1
- package/dist/gateway/static/root/assets/{fetch-B7xDPu-R.js → fetch-B3ME5Eri.js} +1 -1
- package/dist/gateway/static/root/assets/format-cron-label-arqgGlVV.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-config-api-BTBLSeUu.js → gateway-config-api-DI9_BBTo.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-settings-DAFI_T0W.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-CYj9FWCp.js → gateway-startup-retry-CSZQTz6K.js} +1 -1
- package/dist/gateway/static/root/assets/goal-detail-page-DLuz4jC9.js +1 -0
- package/dist/gateway/static/root/assets/{goals-config-api-CQQgzPr3.js → goals-config-api-Bhzqrp2w.js} +1 -1
- package/dist/gateway/static/root/assets/{goals-page-BHitvJAv.js → goals-page-DTAfv9Ft.js} +2 -2
- package/dist/gateway/static/root/assets/goals-settings-CWN2iirQ.js +1 -0
- package/dist/gateway/static/root/assets/heartbeat-settings-CkkkHvOi.js +1 -0
- package/dist/gateway/static/root/assets/index-CnjzMw5i.js +191 -0
- package/dist/gateway/static/root/assets/index-E1QinYKp.css +1 -0
- package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-kMp08SlX.js +1 -0
- package/dist/gateway/static/root/assets/{locale-store-DjbfSsfA.js → locale-store-Ba72bFmP.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-C2Uqvae9.js → logs-page-CDXDlS_W.js} +2 -2
- package/dist/gateway/static/root/assets/{markdown-split-BwOFrJ2E.js → markdown-split-Bc0w40vz.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-Cnz6Q5G6.js → media-plugins-DJ_HvgIy.js} +1 -1
- package/dist/gateway/static/root/assets/messages-CISb1HLv.js +3 -0
- package/dist/gateway/static/root/assets/models-hub-panel-BTwxMIgZ.js +2 -0
- package/dist/gateway/static/root/assets/note-detail-page-BBfOeB0m.js +2 -0
- package/dist/gateway/static/root/assets/{note-image-lightbox-B-Svpmza.js → note-image-lightbox-4zntqpZq.js} +1 -1
- package/dist/gateway/static/root/assets/notes-page-VocWOjoK.js +1 -0
- package/dist/gateway/static/root/assets/{preview-open-alternatives-Bss4TiwP.js → preview-open-alternatives-BbA7sRd_.js} +1 -1
- package/dist/gateway/static/root/assets/remote-access-hub-CXwjuD_Q.js +1 -0
- package/dist/gateway/static/root/assets/{save-bar-controls-BRNjdgKq.js → save-bar-controls-Dividh61.js} +1 -1
- package/dist/gateway/static/root/assets/schedule-field-pRheF2CO.js +1 -0
- package/dist/gateway/static/root/assets/{schema-form-Dub9sy8r.js → schema-form-D6PiPxfr.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-CpcVySQK.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-BVy_TawT.js +1 -0
- package/dist/gateway/static/root/assets/{settings-collapsible-section-BeFLavGi.js → settings-collapsible-section-BMCOfuE_.js} +1 -1
- package/dist/gateway/static/root/assets/settings-form-section-DBkGwpIN.js +1 -0
- package/dist/gateway/static/root/assets/settings-page-CZpNyCWn.js +1 -0
- package/dist/gateway/static/root/assets/settings-page-layout-NxoW5Y57.js +1 -0
- package/dist/gateway/static/root/assets/setup-status-panel-MVHLLu_a.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page-C8glrdqe.js → share-preview-page-B0suFCfj.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-C6DBbQGo.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-6hJmhwSn.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-Im1MA0Iw.js +2 -0
- package/dist/gateway/static/root/assets/system-settings-panel-CrmEnyX4.js +1 -0
- package/dist/gateway/static/root/assets/{theme-store-CD2wtgZV.js → theme-store-Bt6vAkSB.js} +1 -1
- package/dist/gateway/static/root/assets/typed-models-lib-BAsGn25g.js +1 -0
- package/dist/gateway/static/root/assets/{use-channel-catalog-DqlWTsDb.js → use-channel-catalog-C7vcAoGb.js} +1 -1
- package/dist/gateway/static/root/assets/user-profile-settings-panel-QAQWGelF.js +1 -0
- package/dist/gateway/static/root/assets/utils-Dl9efgnV.js +1 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-C73IVZeC.js → voice-api-key-field-D-6XueTv.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-player-store-C_ArLJPM.js → voice-player-store-CMC5NOJp.js} +1 -1
- package/dist/gateway/static/root/assets/workflow-run-setup-panel-DVPllR4k.js +3 -0
- package/dist/gateway/static/root/assets/workflows-page-B94WISTW.js +18 -0
- package/dist/gateway/static/root/index.html +8 -9
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.d.ts +4 -5
- package/dist/src/agent/agent-manager.js +4 -8
- package/dist/src/agent/agent-manager.js.map +1 -1
- package/dist/src/agent/context/workspace-templates/AGENTS.md +3 -2
- package/dist/src/agent/embedded/run-for-session.js +102 -14
- package/dist/src/agent/embedded/run-for-session.js.map +1 -1
- package/dist/src/agent/fallback/candidates.d.ts +0 -8
- package/dist/src/agent/fallback/candidates.js.map +1 -1
- package/dist/src/agent/index.js +1 -1
- package/dist/src/agent/lifecycle/handlers/compaction.d.ts +1 -3
- package/dist/src/agent/lifecycle/handlers/compaction.js +1 -16
- package/dist/src/agent/lifecycle/handlers/compaction.js.map +1 -1
- package/dist/src/agent/lifecycle/progress.d.ts +0 -1
- package/dist/src/agent/lifecycle/progress.js +1 -6
- package/dist/src/agent/lifecycle/progress.js.map +1 -1
- package/dist/src/agent/lifecycle/timeout-wrapper.d.ts +1 -2
- package/dist/src/agent/lifecycle/timeout-wrapper.js +1 -7
- package/dist/src/agent/lifecycle/timeout-wrapper.js.map +1 -1
- package/dist/src/agent/memory/builtin-memory-store.d.ts +1 -1
- package/dist/src/agent/memory/builtin-memory-store.js +1 -1
- package/dist/src/agent/memory/builtin-memory-store.js.map +1 -1
- package/dist/src/agent/memory/builtin-provider.d.ts +2 -2
- package/dist/src/agent/memory/builtin-provider.js +2 -2
- package/dist/src/agent/memory/builtin-provider.js.map +1 -1
- package/dist/src/agent/memory/dreaming/light-sweep.d.ts +0 -7
- package/dist/src/agent/memory/dreaming/light-sweep.js +16 -277
- package/dist/src/agent/memory/dreaming/light-sweep.js.map +1 -1
- package/dist/src/agent/memory/dreaming/rem-patterns.d.ts +1 -1
- package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
- package/dist/src/agent/memory/dreaming/rem-patterns.js.map +1 -1
- package/dist/src/agent/memory/dreaming/short-term-store.d.ts +3 -3
- package/dist/src/agent/memory/dreaming/short-term-store.js +5 -5
- package/dist/src/agent/memory/dreaming/short-term-store.js.map +1 -1
- package/dist/src/agent/memory/dreaming/utils.d.ts +2 -2
- package/dist/src/agent/memory/dreaming/utils.js +2 -2
- package/dist/src/agent/memory/dreaming/utils.js.map +1 -1
- package/dist/src/agent/memory/index.d.ts +0 -2
- package/dist/src/agent/memory/index.js +1 -2
- package/dist/src/agent/middleware/self-verify.d.ts +0 -1
- package/dist/src/agent/middleware/self-verify.js +0 -2
- package/dist/src/agent/middleware/self-verify.js.map +1 -1
- package/dist/src/agent/models/index.d.ts +1 -1
- package/dist/src/agent/models/manager.d.ts +4 -20
- package/dist/src/agent/models/manager.js +9 -126
- package/dist/src/agent/models/manager.js.map +1 -1
- package/dist/src/agent/orchestration/agent-orchestrator.d.ts +0 -4
- package/dist/src/agent/orchestration/agent-orchestrator.js +1 -9
- package/dist/src/agent/orchestration/agent-orchestrator.js.map +1 -1
- package/dist/src/agent/prompt/sections/memory-skills.js +11 -10
- package/dist/src/agent/prompt/sections/memory-skills.js.map +1 -1
- package/dist/src/agent/prompt/sections/tooling.js +4 -4
- package/dist/src/agent/prompt/sections/tooling.js.map +1 -1
- package/dist/src/agent/prompt/service-prompt-builder.d.ts +0 -1
- package/dist/src/agent/prompt/service-prompt-builder.js +0 -12
- package/dist/src/agent/prompt/service-prompt-builder.js.map +1 -1
- package/dist/src/agent/prompt/subagent-context.js +1 -1
- package/dist/src/agent/prompt/subagent-context.js.map +1 -1
- package/dist/src/agent/prompt/types.d.ts +1 -1
- package/dist/src/agent/reply/startup-context.js +6 -105
- package/dist/src/agent/reply/startup-context.js.map +1 -1
- package/dist/src/agent/service.d.ts +1 -12
- package/dist/src/agent/service.js +3 -81
- package/dist/src/agent/service.js.map +1 -1
- package/dist/src/agent/service.types.d.ts +2 -2
- package/dist/src/agent/session/session-config-service.d.ts +11 -11
- package/dist/src/agent/session/session-config-service.js +14 -14
- package/dist/src/agent/session/session-config-service.js.map +1 -1
- package/dist/src/agent/session/session-inspector.js +3 -2
- package/dist/src/agent/session/session-inspector.js.map +1 -1
- package/dist/src/agent/starter-agents.js +12 -12
- package/dist/src/agent/starter-agents.js.map +1 -1
- package/dist/src/agent/tools/automation-tool.d.ts +14 -0
- package/dist/src/agent/tools/automation-tool.js +102 -0
- package/dist/src/agent/tools/automation-tool.js.map +1 -0
- package/dist/src/agent/tools/delegate-tool.js +1 -1
- package/dist/src/agent/tools/delegate-tool.js.map +1 -1
- package/dist/src/agent/tools/factory.d.ts +3 -3
- package/dist/src/agent/tools/factory.js +2 -2
- package/dist/src/agent/tools/factory.js.map +1 -1
- package/dist/src/agent/tools/index.d.ts +1 -1
- package/dist/src/agent/tools/index.js +2 -2
- package/dist/src/agent/tools/memory-tool.js +2 -2
- package/dist/src/agent/tools/memory-tool.js.map +1 -1
- package/dist/src/agent-manifest/resolver.d.ts +1 -0
- package/dist/src/agent-manifest/resolver.js +1 -0
- package/dist/src/agent-manifest/resolver.js.map +1 -1
- package/dist/src/agent-manifest/schema.d.ts +6 -0
- package/dist/src/agent-manifest/schema.js +12 -3
- package/dist/src/agent-manifest/schema.js.map +1 -1
- package/dist/src/ai-assist/text-assist.d.ts +1 -1
- package/dist/src/ai-assist/text-assist.js +56 -0
- package/dist/src/ai-assist/text-assist.js.map +1 -1
- package/dist/src/auth/profiles/store.js.map +1 -1
- package/dist/src/automations/api/routes.d.ts +3 -0
- package/dist/src/automations/api/routes.js +193 -0
- package/dist/src/automations/api/routes.js.map +1 -0
- package/dist/src/automations/domain/index.d.ts +3 -0
- package/dist/src/automations/domain/index.js +3 -0
- package/dist/src/automations/domain/schedule.d.ts +4 -0
- package/dist/src/automations/domain/schedule.js +37 -0
- package/dist/src/automations/domain/schedule.js.map +1 -0
- package/dist/src/automations/domain/types.d.ts +160 -0
- package/dist/src/automations/domain/validation.d.ts +370 -0
- package/dist/src/automations/domain/validation.js +149 -0
- package/dist/src/automations/domain/validation.js.map +1 -0
- package/dist/src/automations/draft/automation-draft-prompt.d.ts +26 -0
- package/dist/src/automations/draft/automation-draft-prompt.js +127 -0
- package/dist/src/automations/draft/automation-draft-prompt.js.map +1 -0
- package/dist/src/automations/draft/automation-draft-service.d.ts +12 -0
- package/dist/src/automations/draft/automation-draft-service.js +135 -0
- package/dist/src/automations/draft/automation-draft-service.js.map +1 -0
- package/dist/src/automations/draft/automation-draft-validator.d.ts +99 -0
- package/dist/src/automations/draft/automation-draft-validator.js +105 -0
- package/dist/src/automations/draft/automation-draft-validator.js.map +1 -0
- package/dist/src/automations/draft/automation-draft.types.d.ts +40 -0
- package/dist/src/automations/draft/index.d.ts +3 -0
- package/dist/src/automations/draft/index.js +3 -0
- package/dist/src/automations/index.d.ts +3 -0
- package/dist/src/automations/index.js +8 -0
- package/dist/src/automations/product-events.d.ts +5 -0
- package/dist/src/automations/product-events.js +21 -0
- package/dist/src/automations/product-events.js.map +1 -0
- package/dist/src/automations/service/action-executor.d.ts +9 -0
- package/dist/src/automations/service/action-executor.js +157 -0
- package/dist/src/automations/service/action-executor.js.map +1 -0
- package/dist/src/automations/service/automation-service.d.ts +54 -0
- package/dist/src/automations/service/automation-service.js +404 -0
- package/dist/src/automations/service/automation-service.js.map +1 -0
- package/dist/src/automations/service/index.d.ts +2 -0
- package/dist/src/automations/service/index.js +3 -0
- package/dist/src/automations/storage/automation-repository.d.ts +6 -0
- package/dist/src/automations/storage/automation-repository.js +61 -0
- package/dist/src/automations/storage/automation-repository.js.map +1 -0
- package/dist/src/automations/storage/automation-run-repository.d.ts +17 -0
- package/dist/src/automations/storage/automation-run-repository.js +130 -0
- package/dist/src/automations/storage/automation-run-repository.js.map +1 -0
- package/dist/src/automations/storage/index.d.ts +2 -0
- package/dist/src/automations/storage/index.js +3 -0
- package/dist/src/channels/plugin-types.d.ts +3 -0
- package/dist/src/chat-commands/builtins/thinking.js.map +1 -1
- package/dist/src/cli/command-catalog.js +0 -39
- package/dist/src/cli/command-catalog.js.map +1 -1
- package/dist/src/cli/command-loaders.js +0 -1
- package/dist/src/cli/command-loaders.js.map +1 -1
- package/dist/src/cli/command-manifest.js +0 -4
- package/dist/src/cli/command-manifest.js.map +1 -1
- package/dist/src/cli/commands/agents.js +7 -6
- package/dist/src/cli/commands/agents.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/doctor/checks/{cron-health.d.ts → migrations.d.ts} +1 -1
- package/dist/src/cli/commands/doctor/checks/migrations.js +40 -0
- package/dist/src/cli/commands/doctor/checks/migrations.js.map +1 -0
- package/dist/src/cli/commands/doctor/flow.js +2 -2
- package/dist/src/cli/commands/doctor/flow.js.map +1 -1
- package/dist/src/cli/commands/gateway/call.js +2 -2
- package/dist/src/cli/commands/gateway/call.js.map +1 -1
- package/dist/src/cli/commands/gateway/run-foreground.js +4 -2
- package/dist/src/cli/commands/gateway/run-foreground.js.map +1 -1
- package/dist/src/cli/commands/init.js +27 -9
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/commands/tui.js +24 -2
- package/dist/src/cli/commands/tui.js.map +1 -1
- package/dist/src/cli/templates.js +3 -2
- package/dist/src/cli/templates.js.map +1 -1
- package/dist/src/cli/utils/init-workspace-core.js +2 -0
- package/dist/src/cli/utils/init-workspace-core.js.map +1 -1
- package/dist/src/commands/agents.config.d.ts +9 -0
- package/dist/src/commands/agents.config.js +40 -2
- package/dist/src/commands/agents.config.js.map +1 -1
- package/dist/src/config/agent-profile.js +4 -3
- package/dist/src/config/agent-profile.js.map +1 -1
- package/dist/src/config/agent-typed-models.js.map +1 -1
- package/dist/src/config/config-surface.d.ts +3 -0
- package/dist/src/config/index.d.ts +0 -1
- package/dist/src/config/index.js +3 -3
- package/dist/src/config/index.js.map +1 -1
- package/dist/src/config/paths.d.ts +0 -9
- package/dist/src/config/paths.js +1 -14
- package/dist/src/config/paths.js.map +1 -1
- package/dist/src/config/profile.js +0 -1
- package/dist/src/config/profile.js.map +1 -1
- package/dist/src/config/rules.js +0 -5
- package/dist/src/config/rules.js.map +1 -1
- package/dist/src/config/schema.d.ts +13 -12
- package/dist/src/config/schema.js +22 -26
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/config/web-patch.d.ts +0 -12
- package/dist/src/config/web-patch.js +2 -29
- package/dist/src/config/web-patch.js.map +1 -1
- package/dist/src/extensions/api.d.ts +2 -0
- package/dist/src/extensions/api.js +10 -0
- package/dist/src/extensions/api.js.map +1 -1
- package/dist/src/extensions/extension-registry-impl.d.ts +4 -1
- package/dist/src/extensions/extension-registry-impl.js +8 -0
- package/dist/src/extensions/extension-registry-impl.js.map +1 -1
- package/dist/src/extensions/loader.d.ts +3 -3
- package/dist/src/extensions/loader.js +3 -3
- package/dist/src/extensions/loader.js.map +1 -1
- package/dist/src/extensions/sdk/testing.d.ts +2 -0
- package/dist/src/extensions/sdk/testing.js +7 -0
- package/dist/src/extensions/sdk/testing.js.map +1 -1
- package/dist/src/extensions/types/core.d.ts +10 -1
- package/dist/src/extensions/types/index.d.ts +1 -1
- package/dist/src/extensions/types/{phase4.d.ts → registration.d.ts} +2 -2
- package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
- package/dist/src/gateway/agent-builtin-tools.js +1 -1
- package/dist/src/gateway/agent-builtin-tools.js.map +1 -1
- package/dist/src/gateway/agents-admin.d.ts +1 -0
- package/dist/src/gateway/agents-admin.js +13 -15
- package/dist/src/gateway/agents-admin.js.map +1 -1
- package/dist/src/gateway/capability-presets-admin.d.ts +1 -0
- package/dist/src/gateway/capability-presets-admin.js +19 -10
- package/dist/src/gateway/capability-presets-admin.js.map +1 -1
- package/dist/src/gateway/dreaming-automation-reconciler.d.ts +11 -0
- package/dist/src/gateway/dreaming-automation-reconciler.js +105 -0
- package/dist/src/gateway/dreaming-automation-reconciler.js.map +1 -0
- package/dist/src/gateway/heartbeat/service.d.ts +0 -2
- package/dist/src/gateway/heartbeat/service.js +0 -7
- package/dist/src/gateway/heartbeat/service.js.map +1 -1
- package/dist/src/gateway/hono/lib/config-payload.d.ts +5 -6
- package/dist/src/gateway/hono/lib/config-payload.js +2 -2
- package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
- package/dist/src/gateway/hono/routes/agents.js.map +1 -1
- package/dist/src/gateway/hono/routes/config-patch/misc.d.ts +1 -1
- package/dist/src/gateway/hono/routes/config-patch/misc.js +15 -6
- package/dist/src/gateway/hono/routes/config-patch/misc.js.map +1 -1
- package/dist/src/gateway/hono/routes/dreaming.js +27 -37
- package/dist/src/gateway/hono/routes/dreaming.js.map +1 -1
- package/dist/src/gateway/hono/routes/home.d.ts +2 -2
- package/dist/src/gateway/hono/routes/home.js +34 -25
- package/dist/src/gateway/hono/routes/home.js.map +1 -1
- package/dist/src/gateway/hono/routes/lazy-bundles.js +10 -6
- package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
- package/dist/src/gateway/hono/routes/migrations.d.ts +3 -0
- package/dist/src/gateway/hono/routes/migrations.js +35 -0
- package/dist/src/gateway/hono/routes/migrations.js.map +1 -0
- package/dist/src/gateway/hono/routes/public-gateway.js +2 -1
- package/dist/src/gateway/hono/routes/public-gateway.js.map +1 -1
- package/dist/src/gateway/hono/routes/sessions.js +14 -0
- package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
- package/dist/src/gateway/run-loop.js +2 -0
- package/dist/src/gateway/run-loop.js.map +1 -1
- package/dist/src/gateway/security/operator-scopes.js +5 -1
- package/dist/src/gateway/security/operator-scopes.js.map +1 -1
- package/dist/src/gateway/service/config-coordinator.d.ts +4 -4
- package/dist/src/gateway/service/config-coordinator.js +14 -8
- package/dist/src/gateway/service/config-coordinator.js.map +1 -1
- package/dist/src/gateway/service/sessions-api.d.ts +2 -1
- package/dist/src/gateway/service/sessions-api.js +6 -1
- package/dist/src/gateway/service/sessions-api.js.map +1 -1
- package/dist/src/gateway/service.d.ts +7 -3
- package/dist/src/gateway/service.js +61 -27
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/goals/goal-service.js +45 -4
- package/dist/src/goals/goal-service.js.map +1 -1
- package/dist/src/migrations/config/default-capability-preset.d.ts +10 -0
- package/dist/src/migrations/config/default-capability-preset.js +135 -0
- package/dist/src/migrations/config/default-capability-preset.js.map +1 -0
- package/dist/src/migrations/index.d.ts +4 -0
- package/dist/src/migrations/index.js +4 -0
- package/dist/src/migrations/registry.d.ts +8 -0
- package/dist/src/migrations/registry.js +18 -0
- package/dist/src/migrations/registry.js.map +1 -0
- package/dist/src/migrations/runner.d.ts +17 -0
- package/dist/src/migrations/runner.js +191 -0
- package/dist/src/migrations/runner.js.map +1 -0
- package/dist/src/migrations/types.d.ts +34 -0
- package/dist/src/notes/service.js +24 -1
- package/dist/src/notes/service.js.map +1 -1
- package/dist/src/providers/model-registry.d.ts +0 -1
- package/dist/src/providers/model-registry.js +0 -3
- package/dist/src/providers/model-registry.js.map +1 -1
- package/dist/src/routing/resolve-tui-session-key.d.ts +3 -0
- package/dist/src/routing/resolve-tui-session-key.js +14 -3
- package/dist/src/routing/resolve-tui-session-key.js.map +1 -1
- package/dist/src/session/transcript-outline.d.ts +47 -0
- package/dist/src/session/transcript-outline.js +481 -0
- package/dist/src/session/transcript-outline.js.map +1 -0
- package/dist/src/storage/sqlite/index.d.ts +0 -2
- package/dist/src/storage/sqlite/index.js +1 -3
- package/dist/src/storage/sqlite/migrations/016_automations.sql +47 -0
- package/dist/src/storage/sqlite/migrations/017_automation_run_events.sql +14 -0
- package/dist/src/storage/sqlite/migrations/018_automation_safety.sql +1 -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 +3 -1
- package/dist/src/storage/sqlite/row-mappers.js.map +1 -1
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/storage/sqlite/schema.sql +56 -46
- package/dist/src/tui/backends/embedded-backend.d.ts +6 -0
- package/dist/src/tui/backends/embedded-backend.js +19 -9
- package/dist/src/tui/backends/embedded-backend.js.map +1 -1
- package/dist/src/tui/backends/gateway-sse-backend.d.ts +3 -0
- package/dist/src/tui/backends/gateway-sse-backend.js +14 -0
- package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
- package/dist/src/tui/tui-backend.d.ts +4 -0
- package/dist/src/tui/tui-commands.d.ts +5 -0
- package/dist/src/tui/tui-commands.js +43 -0
- package/dist/src/tui/tui-commands.js.map +1 -1
- package/dist/src/tui/tui-transcript-tree.d.ts +1 -1
- package/dist/src/tui/tui-transcript-tree.js +17 -257
- package/dist/src/tui/tui-transcript-tree.js.map +1 -1
- package/dist/src/tui/tui-types.d.ts +2 -0
- package/dist/src/tui/tui-types.js.map +1 -1
- package/dist/src/tui/tui.js +7 -2
- package/dist/src/tui/tui.js.map +1 -1
- package/dist/src/workflows/domain/index.js +1 -1
- package/dist/src/workflows/domain/run.d.ts +7 -7
- package/dist/src/workflows/domain/run.js.map +1 -1
- package/dist/src/workflows/index.js +2 -2
- package/dist/src/workflows/service/workflow-run-service.d.ts +2 -0
- package/dist/src/workflows/service/workflow-run-service.js +31 -9
- package/dist/src/workflows/service/workflow-run-service.js.map +1 -1
- package/dist/src/workflows/service/workflow-run-service.types.d.ts +1 -1
- package/package.json +4 -2
- package/dist/gateway/static/root/assets/agents-BCxZbkOw.js +0 -2
- package/dist/gateway/static/root/assets/app-management-settings-panel-bxYJVJpx.js +0 -1
- package/dist/gateway/static/root/assets/appearance-settings-BCIykXlI.js +0 -1
- package/dist/gateway/static/root/assets/browser-settings-page-DRhKdn81.js +0 -8
- package/dist/gateway/static/root/assets/capability-presets-api-CorhiHlg.js +0 -1
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-qFx9Jtce.js +0 -1
- package/dist/gateway/static/root/assets/channels-settings-BAwAkqIA.js +0 -1
- package/dist/gateway/static/root/assets/cn-JdwAhgNB.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-BQLcfitM.js +0 -2
- package/dist/gateway/static/root/assets/createLucideIcon-DPHK1VkS.js +0 -1
- package/dist/gateway/static/root/assets/cron-api-qGwmL-24.js +0 -1
- package/dist/gateway/static/root/assets/cron-dreaming-jobs-nCMWCf0p.js +0 -1
- package/dist/gateway/static/root/assets/cron-page-BBWMAj8-.js +0 -3
- package/dist/gateway/static/root/assets/dreaming-settings-Dw89Obml.js +0 -1
- package/dist/gateway/static/root/assets/format-cron-label-BsotZDO5.js +0 -2
- package/dist/gateway/static/root/assets/format-interval-label-BzxafKxR.js +0 -1
- package/dist/gateway/static/root/assets/gateway-settings-Cmwy58rS.js +0 -1
- package/dist/gateway/static/root/assets/goal-detail-page-l7mu5GWX.js +0 -1
- package/dist/gateway/static/root/assets/goals-settings-CYVY4NGp.js +0 -1
- package/dist/gateway/static/root/assets/heartbeat-config-api-DriO_CN9.js +0 -1
- package/dist/gateway/static/root/assets/heartbeat-settings-CUQTKxg7.js +0 -1
- package/dist/gateway/static/root/assets/index-C17Tsd_b.css +0 -1
- package/dist/gateway/static/root/assets/index-Cc41r16l.js +0 -191
- package/dist/gateway/static/root/assets/interval-presets-DFPCKW_W.js +0 -1
- package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-CcVcqstx.js +0 -1
- package/dist/gateway/static/root/assets/messages-B1iSKjiw.js +0 -3
- package/dist/gateway/static/root/assets/models-hub-panel-BfLfcta8.js +0 -2
- package/dist/gateway/static/root/assets/note-detail-page-BjwOQBfT.js +0 -2
- package/dist/gateway/static/root/assets/notes-page-DktdBiwB.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-rfVx96fq.js +0 -1
- package/dist/gateway/static/root/assets/schedule-field-CUCKODde.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-DbtMFuuH.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-5re5gAnP.js +0 -1
- package/dist/gateway/static/root/assets/settings-form-section-dmyaPOTG.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-D-WMyLlj.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-Cl-DEJAU.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-CyPVvbLt.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-CleTH1oz.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-Ck8hdXqR.js +0 -2
- package/dist/gateway/static/root/assets/system-settings-panel-DI-LN_8G.js +0 -1
- package/dist/gateway/static/root/assets/typed-models-lib-kX9duch4.js +0 -1
- package/dist/gateway/static/root/assets/user-profile-settings-panel-B-UFPMXy.js +0 -1
- package/dist/gateway/static/root/assets/utils-Dm0hKalR.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-BtFGp2y_.js +0 -18
- package/dist/src/agent/fallback/error.d.ts +0 -22
- package/dist/src/agent/fallback/error.js +0 -32
- package/dist/src/agent/fallback/error.js.map +0 -1
- package/dist/src/agent/fallback/index.d.ts +0 -5
- package/dist/src/agent/fallback/index.js +0 -9
- package/dist/src/agent/fallback/index.js.map +0 -1
- package/dist/src/agent/memory/memory-flush.d.ts +0 -27
- package/dist/src/agent/memory/memory-flush.js +0 -124
- package/dist/src/agent/memory/memory-flush.js.map +0 -1
- package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.d.ts +0 -29
- package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.js +0 -76
- package/dist/src/agent/orchestration/run-agent-turn-with-fallbacks.js.map +0 -1
- package/dist/src/agent/service/reconcile-dreaming-cron.d.ts +0 -6
- package/dist/src/agent/service/reconcile-dreaming-cron.js +0 -84
- package/dist/src/agent/service/reconcile-dreaming-cron.js.map +0 -1
- package/dist/src/agent/tools/cronjob-tool.d.ts +0 -29
- package/dist/src/agent/tools/cronjob-tool.js +0 -274
- package/dist/src/agent/tools/cronjob-tool.js.map +0 -1
- package/dist/src/cli/commands/cron-cli.d.ts +0 -2
- package/dist/src/cli/commands/cron-cli.js +0 -15
- package/dist/src/cli/commands/cron-cli.js.map +0 -1
- package/dist/src/cli/commands/cron.d.ts +0 -4
- package/dist/src/cli/commands/cron.js +0 -188
- package/dist/src/cli/commands/cron.js.map +0 -1
- package/dist/src/cli/commands/doctor/checks/cron-health.js +0 -35
- package/dist/src/cli/commands/doctor/checks/cron-health.js.map +0 -1
- package/dist/src/cron/execution-types.d.ts +0 -42
- package/dist/src/cron/executor.d.ts +0 -67
- package/dist/src/cron/executor.js +0 -669
- package/dist/src/cron/executor.js.map +0 -1
- package/dist/src/cron/index.d.ts +0 -7
- package/dist/src/cron/index.js +0 -7
- package/dist/src/cron/job-content.d.ts +0 -5
- package/dist/src/cron/job-content.js +0 -15
- package/dist/src/cron/job-content.js.map +0 -1
- package/dist/src/cron/run-log-store.d.ts +0 -12
- package/dist/src/cron/run-log-store.js +0 -58
- package/dist/src/cron/run-log-store.js.map +0 -1
- package/dist/src/cron/schedule.d.ts +0 -10
- package/dist/src/cron/schedule.js +0 -85
- package/dist/src/cron/schedule.js.map +0 -1
- package/dist/src/cron/service.d.ts +0 -58
- package/dist/src/cron/service.js +0 -419
- package/dist/src/cron/service.js.map +0 -1
- package/dist/src/cron/types.d.ts +0 -183
- package/dist/src/cron/validation.d.ts +0 -500
- package/dist/src/cron/validation.js +0 -192
- package/dist/src/cron/validation.js.map +0 -1
- package/dist/src/cron/workflow-run-completion.d.ts +0 -23
- package/dist/src/cron/workflow-run-completion.js +0 -72
- package/dist/src/cron/workflow-run-completion.js.map +0 -1
- package/dist/src/extensions/types/phase4.js +0 -1
- package/dist/src/gateway/hono/routes/cron.d.ts +0 -3
- package/dist/src/gateway/hono/routes/cron.js +0 -109
- package/dist/src/gateway/hono/routes/cron.js.map +0 -1
- package/dist/src/storage/sqlite/cron-job-repository.d.ts +0 -6
- package/dist/src/storage/sqlite/cron-job-repository.js +0 -70
- package/dist/src/storage/sqlite/cron-job-repository.js.map +0 -1
- package/dist/src/storage/sqlite/cron-run-repository.d.ts +0 -5
- package/dist/src/storage/sqlite/cron-run-repository.js +0 -96
- package/dist/src/storage/sqlite/cron-run-repository.js.map +0 -1
- /package/dist/src/{cron → automations/domain}/types.js +0 -0
- /package/dist/src/{config/defaults.d.ts → automations/draft/automation-draft.types.js} +0 -0
- /package/dist/src/{config/defaults.js → extensions/types/registration.js} +0 -0
- /package/dist/src/{cron/execution-types.js → migrations/types.js} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command-manifest.js","names":[],"sources":["../../../src/cli/command-manifest.ts"],"sourcesContent":["export type RootHelpOption = {\n flags: string;\n description: string;\n};\n\nexport type RootHelpCommand = {\n name: string;\n description: string;\n};\n\nexport const ROOT_COMMAND_DESCRIPTION = 'Ultra-Lightweight Personal AI Assistant. Run `xopc` with no command to open the local TUI.';\n\nexport const ROOT_HELP_OPTIONS: RootHelpOption[] = [\n { flags: '-V, --version', description: 'output the version number' },\n { flags: '--verbose', description: 'Enable verbose logging (default: false)' },\n { flags: '--config <path>', description: 'Config file path' },\n { flags: '--workspace <path>', description: 'Workspace directory' },\n { flags: '-h, --help', description: 'display help for command' },\n];\n\nexport const ROOT_HELP_COMMANDS: RootHelpCommand[] = [\n { name: 'init [options]', description: 'Initialize xopc state directories, config, and agent workspace' },\n { name: 'setup [options]', description: 'Initialize config file and workspace directory' },\n { name: 'profile', description: 'Manage xopc state profiles (~/.xopc vs ~/.xopc-<name>)' },\n { name: 'onboard [options]', description: 'Interactive setup wizard for xopc (gateway uses schema defaults)' },\n { name: 'channels', description: 'Messaging channel configuration' },\n { name: 'auth', description: 'Manage authentication credentials' },\n { name: 'agent [options]', description: 'Chat with the AI agent' },\n { name: 'tui [options]', description: 'Interactive terminal UI (pi-tui)' },\n { name: 'tunnel', description: 'Manage FRP remote access tunnel' },\n { name: 'gateway [options]', description: 'Start the xopc gateway server' },\n { name: 'session', description: 'Session management commands' },\n { name: 'doctor [options]', description: 'Check xopc installation health and diagnose common issues' },\n { name: 'update [options]', description: 'Check for and install xopc updates' },\n { name: 'logs', description: 'Manage and query logs' },\n { name: '
|
|
1
|
+
{"version":3,"file":"command-manifest.js","names":[],"sources":["../../../src/cli/command-manifest.ts"],"sourcesContent":["export type RootHelpOption = {\n flags: string;\n description: string;\n};\n\nexport type RootHelpCommand = {\n name: string;\n description: string;\n};\n\nexport const ROOT_COMMAND_DESCRIPTION = 'Ultra-Lightweight Personal AI Assistant. Run `xopc` with no command to open the local TUI.';\n\nexport const ROOT_HELP_OPTIONS: RootHelpOption[] = [\n { flags: '-V, --version', description: 'output the version number' },\n { flags: '--verbose', description: 'Enable verbose logging (default: false)' },\n { flags: '--config <path>', description: 'Config file path' },\n { flags: '--workspace <path>', description: 'Workspace directory' },\n { flags: '-h, --help', description: 'display help for command' },\n];\n\nexport const ROOT_HELP_COMMANDS: RootHelpCommand[] = [\n { name: 'init [options]', description: 'Initialize xopc state directories, config, and agent workspace' },\n { name: 'setup [options]', description: 'Initialize config file and workspace directory' },\n { name: 'profile', description: 'Manage xopc state profiles (~/.xopc vs ~/.xopc-<name>)' },\n { name: 'onboard [options]', description: 'Interactive setup wizard for xopc (gateway uses schema defaults)' },\n { name: 'channels', description: 'Messaging channel configuration' },\n { name: 'auth', description: 'Manage authentication credentials' },\n { name: 'agent [options]', description: 'Chat with the AI agent' },\n { name: 'tui [options]', description: 'Interactive terminal UI (pi-tui)' },\n { name: 'tunnel', description: 'Manage FRP remote access tunnel' },\n { name: 'gateway [options]', description: 'Start the xopc gateway server' },\n { name: 'session', description: 'Session management commands' },\n { name: 'doctor [options]', description: 'Check xopc installation health and diagnose common issues' },\n { name: 'update [options]', description: 'Check for and install xopc updates' },\n { name: 'logs', description: 'Manage and query logs' },\n { name: 'goal', description: 'Manage durable goals' },\n { name: 'config [options]', description: 'View and edit configuration' },\n { name: 'image', description: 'Inspect image provider availability' },\n { name: 'models [options]', description: 'List and manage models and model auth' },\n { name: 'providers', description: 'Manage LLM provider credentials (user-friendly hub over `xopc auth`)' },\n { name: 'voice', description: 'Configure text-to-speech (TTS) output' },\n { name: 'search', description: 'Manage web-search providers (brave / tavily / bing / searxng)' },\n { name: 'skills', description: 'Manage skills' },\n { name: 'tailscale', description: 'Tailscale status for gateway remote access' },\n { name: 'browser', description: 'Browser automation commands (uses Playwright)' },\n { name: 'agents', description: 'Manage agents (config + workspace)' },\n { name: 'extensions', description: 'Manage extensions' },\n { name: 'help [command]', description: 'display help for command' },\n];\n\nfunction formatRows(rows: Array<{ label: string; description: string }>): string {\n const labelWidth = Math.max(...rows.map((row) => row.label.length)) + 2;\n return rows.map((row) => ` ${row.label.padEnd(labelWidth)}${row.description}`).join('\\n');\n}\n\nexport function formatRootHelp(): string {\n const options = formatRows(ROOT_HELP_OPTIONS.map((option) => ({ label: option.flags, description: option.description })));\n const commands = formatRows(\n ROOT_HELP_COMMANDS.map((command) => ({ label: command.name, description: command.description })),\n );\n return `Usage: xopc [options] [command]\n\n${ROOT_COMMAND_DESCRIPTION}\n\nOptions:\n${options}\n\nCommands:\n${commands}`;\n}\n"],"mappings":";AAUA,MAAa,2BAA2B;AAExC,MAAa,oBAAsC;CACjD;EAAE,OAAO;EAAiB,aAAa;EAA6B;CACpE;EAAE,OAAO;EAAa,aAAa;EAA2C;CAC9E;EAAE,OAAO;EAAmB,aAAa;EAAoB;CAC7D;EAAE,OAAO;EAAsB,aAAa;EAAuB;CACnE;EAAE,OAAO;EAAc,aAAa;EAA4B;CACjE;AAED,MAAa,qBAAwC;CACnD;EAAE,MAAM;EAAkB,aAAa;EAAkE;CACzG;EAAE,MAAM;EAAmB,aAAa;EAAkD;CAC1F;EAAE,MAAM;EAAW,aAAa;EAA0D;CAC1F;EAAE,MAAM;EAAqB,aAAa;EAAoE;CAC9G;EAAE,MAAM;EAAY,aAAa;EAAmC;CACpE;EAAE,MAAM;EAAQ,aAAa;EAAqC;CAClE;EAAE,MAAM;EAAmB,aAAa;EAA0B;CAClE;EAAE,MAAM;EAAiB,aAAa;EAAoC;CAC1E;EAAE,MAAM;EAAU,aAAa;EAAmC;CAClE;EAAE,MAAM;EAAqB,aAAa;EAAiC;CAC3E;EAAE,MAAM;EAAW,aAAa;EAA+B;CAC/D;EAAE,MAAM;EAAoB,aAAa;EAA6D;CACtG;EAAE,MAAM;EAAoB,aAAa;EAAsC;CAC/E;EAAE,MAAM;EAAQ,aAAa;EAAyB;CACtD;EAAE,MAAM;EAAQ,aAAa;EAAwB;CACrD;EAAE,MAAM;EAAoB,aAAa;EAA+B;CACxE;EAAE,MAAM;EAAS,aAAa;EAAuC;CACrE;EAAE,MAAM;EAAoB,aAAa;EAAyC;CAClF;EAAE,MAAM;EAAa,aAAa;EAAwE;CAC1G;EAAE,MAAM;EAAS,aAAa;EAAyC;CACvE;EAAE,MAAM;EAAU,aAAa;EAAiE;CAChG;EAAE,MAAM;EAAU,aAAa;EAAiB;CAChD;EAAE,MAAM;EAAa,aAAa;EAA8C;CAChF;EAAE,MAAM;EAAW,aAAa;EAAiD;CACjF;EAAE,MAAM;EAAU,aAAa;EAAsC;CACrE;EAAE,MAAM;EAAc,aAAa;EAAqB;CACxD;EAAE,MAAM;EAAkB,aAAa;EAA4B;CACpE;AAED,SAAS,WAAW,MAA6D;CAC/E,MAAM,aAAa,KAAK,IAAI,GAAG,KAAK,KAAK,QAAQ,IAAI,MAAM,OAAO,CAAC,GAAG;AACtE,QAAO,KAAK,KAAK,QAAQ,KAAK,IAAI,MAAM,OAAO,WAAW,GAAG,IAAI,cAAc,CAAC,KAAK,KAAK;;AAG5F,SAAgB,iBAAyB;AAKvC,QAAO;;EAEP,yBAAyB;;;EANT,WAAW,kBAAkB,KAAK,YAAY;EAAE,OAAO,OAAO;EAAO,aAAa,OAAO;EAAa,EAAE,CASjH,CAAC;;;EARS,WACf,mBAAmB,KAAK,aAAa;EAAE,OAAO,QAAQ;EAAM,aAAa,QAAQ;EAAa,EAAE,CAU1F"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { init_agent_scope, listAgentEntries, normalizeAgentId, resolveAgentDir, resolveAgentProfileDir, resolveAgentWorkspaceDir, resolveDefaultAgentId, validateAgentIdForNewAgent } from "../../agent/agent-scope.js";
|
|
2
2
|
import { init_paths, resolveConfigPath } from "../../config/paths.js";
|
|
3
3
|
import { init_loader, loadConfig, saveConfig } from "../../config/loader.js";
|
|
4
|
-
import { applyAgentConfig, findAgentEntryIndex, pruneAgentConfig, removeAgentDirsFromDisk } from "../../commands/agents.config.js";
|
|
4
|
+
import { applyAgentConfig, findAgentEntryIndex, getAgentDeleteBlocker, pruneAgentConfig, removeAgentDirsFromDisk } from "../../commands/agents.config.js";
|
|
5
5
|
import { seedAgentProfileMarkdownFiles } from "../../agent/context/workspace-seed.js";
|
|
6
6
|
import { colors } from "../utils/colors.js";
|
|
7
7
|
import { mkdir } from "node:fs/promises";
|
|
@@ -12,9 +12,6 @@ import { mkdir } from "node:fs/promises";
|
|
|
12
12
|
init_loader();
|
|
13
13
|
init_paths();
|
|
14
14
|
init_agent_scope();
|
|
15
|
-
function requireNonMain(id) {
|
|
16
|
-
if (normalizeAgentId(id) === "main") throw new Error(`Agent id "${DEFAULT_AGENT_ID}" is reserved for the primary agent.`);
|
|
17
|
-
}
|
|
18
15
|
function registerAgentsCli(program) {
|
|
19
16
|
const agents = program.command("agents").description("Manage agents (config + workspace)");
|
|
20
17
|
agents.command("list").description("List configured agents").option("--json", "Output JSON").action(async (opts) => {
|
|
@@ -79,7 +76,11 @@ function registerAgentsCli(program) {
|
|
|
79
76
|
});
|
|
80
77
|
agents.command("delete").description("Remove an agent from config (optional on-disk cleanup)").argument("<id>", "Agent id").option("--purge", "Also delete workspace and ~/.xopc/agents/<id> data", false).option("--json", "Output JSON summary").action(async (id, opts) => {
|
|
81
78
|
const cfg = loadConfig();
|
|
82
|
-
|
|
79
|
+
const blocker = getAgentDeleteBlocker(cfg, id);
|
|
80
|
+
if (blocker) {
|
|
81
|
+
console.error(colors.red("Error:"), blocker);
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
83
84
|
if (findAgentEntryIndex(listAgentEntries(cfg), id) < 0) {
|
|
84
85
|
console.error(colors.red("Error:"), `Agent "${id}" not found in agents.list`);
|
|
85
86
|
process.exit(1);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents.js","names":[],"sources":["../../../../src/cli/commands/agents.ts"],"sourcesContent":["/**\n * `agents` CLI: config is the source of truth for multi-agent paths.\n */\n\nimport { mkdir } from 'node:fs/promises';\nimport { Command } from 'commander';\nimport { loadConfig, saveConfig } from '../../config/loader.js';\nimport { resolveConfigPath } from '../../config/paths.js';\nimport {\n normalizeAgentId,\n resolveAgentDir,\n resolveAgentProfileDir,\n resolveAgentWorkspaceDir,\n resolveDefaultAgentId,\n
|
|
1
|
+
{"version":3,"file":"agents.js","names":[],"sources":["../../../../src/cli/commands/agents.ts"],"sourcesContent":["/**\n * `agents` CLI: config is the source of truth for multi-agent paths.\n */\n\nimport { mkdir } from 'node:fs/promises';\nimport { Command } from 'commander';\nimport { loadConfig, saveConfig } from '../../config/loader.js';\nimport { resolveConfigPath } from '../../config/paths.js';\nimport {\n normalizeAgentId,\n resolveAgentDir,\n resolveAgentProfileDir,\n resolveAgentWorkspaceDir,\n resolveDefaultAgentId,\n validateAgentIdForNewAgent,\n} from '../../agent/agent-scope.js';\nimport {\n applyAgentConfig,\n findAgentEntryIndex,\n getAgentDeleteBlocker,\n listAgentEntries,\n pruneAgentConfig,\n removeAgentDirsFromDisk,\n} from '../../commands/agents.config.js';\nimport { seedAgentProfileMarkdownFiles } from '../../agent/context/workspace-seed.js';\nimport { colors } from '../utils/colors.js';\n\nexport function registerAgentsCli(program: Command): void {\n const agents = program\n .command('agents')\n .description('Manage agents (config + workspace)');\n\n agents\n .command('list')\n .description('List configured agents')\n .option('--json', 'Output JSON')\n .action(async (opts: { json?: boolean }) => {\n const cfg = loadConfig();\n const rows = listAgentEntries(cfg).map((a) => ({\n id: normalizeAgentId(a.id),\n enabled: a.enabled !== false,\n workspace: a.workspace,\n model: a.models.roles[a.models.defaultRole]?.model,\n }));\n const def = resolveDefaultAgentId(cfg);\n if (opts.json) {\n console.log(JSON.stringify({ defaultAgentId: def, agents: rows }, null, 2));\n return;\n }\n console.log(colors.cyan(`Default agent id: ${def}`));\n if (rows.length === 0) {\n console.log('No entries in agents.list (using defaults only).');\n return;\n }\n for (const r of rows) {\n const mark = r.id === def ? ' (default routing)' : '';\n console.log(`- ${r.id}${mark}`);\n }\n });\n\n agents\n .command('add')\n .description('Add or update an agent in config and create workspace / state dirs')\n .argument('<name>', 'Agent display name / id seed')\n .requiredOption('--workspace <dir>', 'Workspace directory for this agent')\n .option('--model <id>', 'Model id (e.g. anthropic/claude-sonnet-4-5)')\n .option('--json', 'Output JSON summary')\n .action(\n async (\n name: string,\n opts: { workspace?: string; model?: string; json?: boolean },\n ) => {\n const cfg = loadConfig();\n const idRes = validateAgentIdForNewAgent(undefined, name);\n if (idRes.ok === false) {\n console.error(colors.red('Error:'), idRes.error);\n process.exit(1);\n }\n const agentId = idRes.agentId;\n\n const workspace = opts.workspace!.trim();\n const next = applyAgentConfig(cfg, {\n agentId,\n workspace,\n ...(opts.model?.trim() ? { model: opts.model.trim() } : {}),\n });\n\n const configPath = resolveConfigPath();\n await saveConfig(next, configPath);\n\n const wsPath = resolveAgentWorkspaceDir(next, agentId);\n const adPath = resolveAgentDir(next, agentId);\n const profilePath = resolveAgentProfileDir(next, agentId);\n await mkdir(wsPath, { recursive: true });\n await mkdir(adPath, { recursive: true });\n await mkdir(profilePath, { recursive: true });\n seedAgentProfileMarkdownFiles(profilePath, wsPath, { displayName: name.trim() });\n\n const payload = { agentId, workspace: wsPath, agentDir: adPath, model: opts.model };\n if (opts.json) {\n console.log(JSON.stringify(payload, null, 2));\n } else {\n console.log(colors.green('✓'), `Configured agent \"${agentId}\"`);\n console.log(` Workspace: ${wsPath}`);\n console.log(` Agent dir: ${adPath}`);\n }\n },\n );\n\n agents\n .command('delete')\n .description('Remove an agent from config (optional on-disk cleanup)')\n .argument('<id>', 'Agent id')\n .option('--purge', 'Also delete workspace and ~/.xopc/agents/<id> data', false)\n .option('--json', 'Output JSON summary')\n .action(async (id: string, opts: { purge?: boolean; json?: boolean }) => {\n const cfg = loadConfig();\n const blocker = getAgentDeleteBlocker(cfg, id);\n if (blocker) {\n console.error(colors.red('Error:'), blocker);\n process.exit(1);\n }\n const idx = findAgentEntryIndex(listAgentEntries(cfg), id);\n if (idx < 0) {\n console.error(colors.red('Error:'), `Agent \"${id}\" not found in agents.list`);\n process.exit(1);\n }\n const { config: pruned, removedBindings } = pruneAgentConfig(cfg, id);\n await saveConfig(pruned, resolveConfigPath());\n let purged = false;\n if (opts.purge) {\n await removeAgentDirsFromDisk(pruned, id);\n purged = true;\n }\n const payload = { deleted: id, removedBindings, purged };\n if (opts.json) {\n console.log(JSON.stringify(payload, null, 2));\n } else {\n console.log(colors.green('✓'), `Removed agent \"${id}\" from config`);\n if (removedBindings > 0) {\n console.log(` Stripped ${removedBindings} routing binding(s).`);\n }\n if (purged) {\n console.log(' On-disk workspace/state removed.');\n }\n }\n });\n}\n"],"mappings":"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"}
|
|
@@ -52,7 +52,7 @@ async function checkDatabaseSchema(ctx) {
|
|
|
52
52
|
id: "database-schema",
|
|
53
53
|
label: "Database schema",
|
|
54
54
|
status: "pass",
|
|
55
|
-
message: `SQLite schema v${status.dbVersion} (current release
|
|
55
|
+
message: `SQLite schema v${status.dbVersion} (current release v18).`,
|
|
56
56
|
hints: []
|
|
57
57
|
};
|
|
58
58
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { CheckResult, DoctorContext } from '../types.js';
|
|
2
|
-
export declare function
|
|
2
|
+
export declare function checkMigrations(ctx: DoctorContext): Promise<CheckResult>;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { applyMigrations, detectMigrations } from "../../../../migrations/runner.js";
|
|
2
|
+
//#region src/cli/commands/doctor/checks/migrations.ts
|
|
3
|
+
async function checkMigrations(ctx) {
|
|
4
|
+
const planned = detectMigrations(ctx.configPath, { stateDir: ctx.stateDir });
|
|
5
|
+
if (planned.length === 0) return {
|
|
6
|
+
id: "migrations",
|
|
7
|
+
label: "Migrations",
|
|
8
|
+
status: "pass",
|
|
9
|
+
message: "No pending migrations.",
|
|
10
|
+
hints: [ctx.configPath]
|
|
11
|
+
};
|
|
12
|
+
if (ctx.options.fix) {
|
|
13
|
+
const result = applyMigrations(ctx.configPath, {
|
|
14
|
+
stateDir: ctx.stateDir,
|
|
15
|
+
mode: "doctor-fix"
|
|
16
|
+
});
|
|
17
|
+
const blocking = result.items.filter((item) => item.status === "conflict" || item.status === "error");
|
|
18
|
+
const applied = result.items.filter((item) => item.status === "applied");
|
|
19
|
+
return {
|
|
20
|
+
id: "migrations",
|
|
21
|
+
label: "Migrations",
|
|
22
|
+
status: blocking.length > 0 ? "fail" : "pass",
|
|
23
|
+
message: blocking.length > 0 ? `${applied.length} migration(s) applied; ${blocking.length} need manual attention.` : `${applied.length} migration(s) applied.`,
|
|
24
|
+
hints: result.items.map((item) => `${item.id}: ${item.message}`),
|
|
25
|
+
fixed: applied.length > 0
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
const conflicts = planned.filter((item) => item.status === "conflict" || item.status === "error");
|
|
29
|
+
return {
|
|
30
|
+
id: "migrations",
|
|
31
|
+
label: "Migrations",
|
|
32
|
+
status: conflicts.length > 0 ? "fail" : "warn",
|
|
33
|
+
message: conflicts.length > 0 ? `${planned.length} migration(s) pending; ${conflicts.length} need manual attention.` : `${planned.length} safe migration(s) pending.`,
|
|
34
|
+
hints: ["Run: xopc doctor --fix", ...planned.map((item) => `${item.id}: ${item.message}`)]
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
//#endregion
|
|
38
|
+
export { checkMigrations };
|
|
39
|
+
|
|
40
|
+
//# sourceMappingURL=migrations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrations.js","names":[],"sources":["../../../../../../src/cli/commands/doctor/checks/migrations.ts"],"sourcesContent":["import { applyMigrations, detectMigrations } from '../../../../migrations/runner.js';\nimport type { CheckResult, DoctorContext } from '../types.js';\n\nexport async function checkMigrations(ctx: DoctorContext): Promise<CheckResult> {\n const planned = detectMigrations(ctx.configPath, { stateDir: ctx.stateDir });\n if (planned.length === 0) {\n return {\n id: 'migrations',\n label: 'Migrations',\n status: 'pass',\n message: 'No pending migrations.',\n hints: [ctx.configPath],\n };\n }\n\n if (ctx.options.fix) {\n const result = applyMigrations(ctx.configPath, { stateDir: ctx.stateDir, mode: 'doctor-fix' });\n const blocking = result.items.filter((item) => item.status === 'conflict' || item.status === 'error');\n const applied = result.items.filter((item) => item.status === 'applied');\n return {\n id: 'migrations',\n label: 'Migrations',\n status: blocking.length > 0 ? 'fail' : 'pass',\n message: blocking.length > 0\n ? `${applied.length} migration(s) applied; ${blocking.length} need manual attention.`\n : `${applied.length} migration(s) applied.`,\n hints: result.items.map((item) => `${item.id}: ${item.message}`),\n fixed: applied.length > 0,\n };\n }\n\n const conflicts = planned.filter((item) => item.status === 'conflict' || item.status === 'error');\n return {\n id: 'migrations',\n label: 'Migrations',\n status: conflicts.length > 0 ? 'fail' : 'warn',\n message: conflicts.length > 0\n ? `${planned.length} migration(s) pending; ${conflicts.length} need manual attention.`\n : `${planned.length} safe migration(s) pending.`,\n hints: ['Run: xopc doctor --fix', ...planned.map((item) => `${item.id}: ${item.message}`)],\n };\n}\n"],"mappings":";;AAGA,eAAsB,gBAAgB,KAA0C;CAC9E,MAAM,UAAU,iBAAiB,IAAI,YAAY,EAAE,UAAU,IAAI,UAAU,CAAC;AAC5E,KAAI,QAAQ,WAAW,EACrB,QAAO;EACL,IAAI;EACJ,OAAO;EACP,QAAQ;EACR,SAAS;EACT,OAAO,CAAC,IAAI,WAAW;EACxB;AAGH,KAAI,IAAI,QAAQ,KAAK;EACnB,MAAM,SAAS,gBAAgB,IAAI,YAAY;GAAE,UAAU,IAAI;GAAU,MAAM;GAAc,CAAC;EAC9F,MAAM,WAAW,OAAO,MAAM,QAAQ,SAAS,KAAK,WAAW,cAAc,KAAK,WAAW,QAAQ;EACrG,MAAM,UAAU,OAAO,MAAM,QAAQ,SAAS,KAAK,WAAW,UAAU;AACxE,SAAO;GACL,IAAI;GACJ,OAAO;GACP,QAAQ,SAAS,SAAS,IAAI,SAAS;GACvC,SAAS,SAAS,SAAS,IACvB,GAAG,QAAQ,OAAO,yBAAyB,SAAS,OAAO,2BAC3D,GAAG,QAAQ,OAAO;GACtB,OAAO,OAAO,MAAM,KAAK,SAAS,GAAG,KAAK,GAAG,IAAI,KAAK,UAAU;GAChE,OAAO,QAAQ,SAAS;GACzB;;CAGH,MAAM,YAAY,QAAQ,QAAQ,SAAS,KAAK,WAAW,cAAc,KAAK,WAAW,QAAQ;AACjG,QAAO;EACL,IAAI;EACJ,OAAO;EACP,QAAQ,UAAU,SAAS,IAAI,SAAS;EACxC,SAAS,UAAU,SAAS,IACxB,GAAG,QAAQ,OAAO,yBAAyB,UAAU,OAAO,2BAC5D,GAAG,QAAQ,OAAO;EACtB,OAAO,CAAC,0BAA0B,GAAG,QAAQ,KAAK,SAAS,GAAG,KAAK,GAAG,IAAI,KAAK,UAAU,CAAC;EAC3F"}
|
|
@@ -11,13 +11,14 @@ import { checkSessionIntegrity } from "./checks/session-integrity.js";
|
|
|
11
11
|
import { checkGatewayService } from "./checks/gateway-service.js";
|
|
12
12
|
import { checkSecurityAudit } from "./checks/security-audit.js";
|
|
13
13
|
import { checkWorkspaceStatus } from "./checks/workspace-status.js";
|
|
14
|
-
import { checkCronHealth } from "./checks/cron-health.js";
|
|
15
14
|
import { checkVersionUpdate } from "./checks/version-check.js";
|
|
16
15
|
import { checkChannelPlugins } from "./checks/channel-plugins.js";
|
|
16
|
+
import { checkMigrations } from "./checks/migrations.js";
|
|
17
17
|
//#region src/cli/commands/doctor/flow.ts
|
|
18
18
|
const DOCTOR_CHECKS = [
|
|
19
19
|
checkVersionUpdate,
|
|
20
20
|
checkNodeVersion,
|
|
21
|
+
checkMigrations,
|
|
21
22
|
checkConfigHealth,
|
|
22
23
|
checkStateIntegrity,
|
|
23
24
|
checkDatabaseSchema,
|
|
@@ -28,7 +29,6 @@ const DOCTOR_CHECKS = [
|
|
|
28
29
|
checkWorkspaceStatus,
|
|
29
30
|
checkGatewayService,
|
|
30
31
|
checkGatewayHealth,
|
|
31
|
-
checkCronHealth,
|
|
32
32
|
checkSessionIntegrity
|
|
33
33
|
];
|
|
34
34
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flow.js","names":[],"sources":["../../../../../src/cli/commands/doctor/flow.ts"],"sourcesContent":["import { printJsonResults, printResults } from './format.js';\nimport type { CheckResult, DoctorCheck, DoctorContext } from './types.js';\nimport { checkNodeVersion } from './checks/node-version.js';\nimport { checkConfigHealth } from './checks/config-health.js';\nimport { checkStateIntegrity } from './checks/state-integrity.js';\nimport { checkDatabaseSchema } from './checks/database-schema.js';\nimport { checkProviderAuth } from './checks/provider-auth.js';\nimport { checkChannelConfig } from './checks/channel-config.js';\nimport { checkChannelPairingPending } from './checks/channel-pairing-pending.js';\nimport { checkGatewayHealth } from './checks/gateway-health.js';\nimport { checkSessionIntegrity } from './checks/session-integrity.js';\nimport { checkGatewayService } from './checks/gateway-service.js';\nimport { checkSecurityAudit } from './checks/security-audit.js';\nimport { checkWorkspaceStatus } from './checks/workspace-status.js';\nimport {
|
|
1
|
+
{"version":3,"file":"flow.js","names":[],"sources":["../../../../../src/cli/commands/doctor/flow.ts"],"sourcesContent":["import { printJsonResults, printResults } from './format.js';\nimport type { CheckResult, DoctorCheck, DoctorContext } from './types.js';\nimport { checkNodeVersion } from './checks/node-version.js';\nimport { checkConfigHealth } from './checks/config-health.js';\nimport { checkStateIntegrity } from './checks/state-integrity.js';\nimport { checkDatabaseSchema } from './checks/database-schema.js';\nimport { checkProviderAuth } from './checks/provider-auth.js';\nimport { checkChannelConfig } from './checks/channel-config.js';\nimport { checkChannelPairingPending } from './checks/channel-pairing-pending.js';\nimport { checkGatewayHealth } from './checks/gateway-health.js';\nimport { checkSessionIntegrity } from './checks/session-integrity.js';\nimport { checkGatewayService } from './checks/gateway-service.js';\nimport { checkSecurityAudit } from './checks/security-audit.js';\nimport { checkWorkspaceStatus } from './checks/workspace-status.js';\nimport { checkVersionUpdate } from './checks/version-check.js';\nimport { checkChannelPlugins } from './checks/channel-plugins.js';\nimport { checkMigrations } from './checks/migrations.js';\n\nconst DOCTOR_CHECKS: DoctorCheck[] = [\n checkVersionUpdate,\n checkNodeVersion,\n checkMigrations,\n checkConfigHealth,\n checkStateIntegrity,\n checkDatabaseSchema,\n checkProviderAuth,\n checkChannelConfig,\n checkChannelPairingPending,\n checkSecurityAudit,\n checkWorkspaceStatus,\n checkGatewayService,\n checkGatewayHealth,\n checkSessionIntegrity,\n];\n\n/**\n * Headless data collection — used by both CLI and gateway API.\n */\nexport async function collectDoctorResults(ctx: DoctorContext): Promise<CheckResult[]> {\n if (ctx.options.security) {\n return [await checkSecurityAudit(ctx)];\n }\n\n const results: CheckResult[] = [];\n\n for (const check of DOCTOR_CHECKS) {\n results.push(await check(ctx));\n }\n\n results.push(...(await checkChannelPlugins(ctx)));\n\n return results;\n}\n\n/**\n * CLI entry point — collect and print.\n */\nexport async function runDoctor(ctx: DoctorContext): Promise<CheckResult[]> {\n const results = await collectDoctorResults(ctx);\n\n if (ctx.options.json) {\n printJsonResults(results);\n } else {\n printResults(results, { security: ctx.options.security });\n }\n\n return results;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAkBA,MAAM,gBAA+B;CACnC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;;;AAKD,eAAsB,qBAAqB,KAA4C;AACrF,KAAI,IAAI,QAAQ,SACd,QAAO,CAAC,MAAM,mBAAmB,IAAI,CAAC;CAGxC,MAAM,UAAyB,EAAE;AAEjC,MAAK,MAAM,SAAS,cAClB,SAAQ,KAAK,MAAM,MAAM,IAAI,CAAC;AAGhC,SAAQ,KAAK,GAAI,MAAM,oBAAoB,IAAI,CAAE;AAEjD,QAAO;;;;;AAMT,eAAsB,UAAU,KAA4C;CAC1E,MAAM,UAAU,MAAM,qBAAqB,IAAI;AAE/C,KAAI,IAAI,QAAQ,KACd,kBAAiB,QAAQ;KAEzB,cAAa,SAAS,EAAE,UAAU,IAAI,QAAQ,UAAU,CAAC;AAG3D,QAAO"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"call.js","names":[],"sources":["../../../../../src/cli/commands/gateway/call.ts"],"sourcesContent":["import { Command } from 'commander';\n\nimport {\n addGatewayClientOptions,\n parseGatewayClientOptions,\n} from '../../utils/gateway-client-options.js';\nimport { getContextWithOpts } from '../../context.js';\nimport { resolveConfigPath } from '../../../config/paths.js';\n\nconst METHOD_ALIASES: Record<string, { method: 'GET' | 'POST'; path: string }> = {\n health: { method: 'GET', path: '/api/health' },\n status: { method: 'GET', path: '/api/status' },\n config: { method: 'GET', path: '/api/config' },\n sessions: { method: 'GET', path: '/api/sessions' },\n models: { method: 'GET', path: '/api/models' },\n channels: { method: 'GET', path: '/api/channels/status' },\n
|
|
1
|
+
{"version":3,"file":"call.js","names":[],"sources":["../../../../../src/cli/commands/gateway/call.ts"],"sourcesContent":["import { Command } from 'commander';\n\nimport {\n addGatewayClientOptions,\n parseGatewayClientOptions,\n} from '../../utils/gateway-client-options.js';\nimport { getContextWithOpts } from '../../context.js';\nimport { resolveConfigPath } from '../../../config/paths.js';\n\nconst METHOD_ALIASES: Record<string, { method: 'GET' | 'POST'; path: string }> = {\n health: { method: 'GET', path: '/api/health' },\n status: { method: 'GET', path: '/api/status' },\n config: { method: 'GET', path: '/api/config' },\n sessions: { method: 'GET', path: '/api/sessions' },\n models: { method: 'GET', path: '/api/models' },\n channels: { method: 'GET', path: '/api/channels/status' },\n automations: { method: 'GET', path: '/api/automations' },\n logs: { method: 'GET', path: '/api/logs' },\n agents: { method: 'GET', path: '/api/agents' },\n};\n\nexport function createCallCommand(): Command {\n const cmd = new Command('call')\n .description('Call a gateway API method')\n .argument(\n '<method>',\n `Method name or API path. Built-in aliases: ${Object.keys(METHOD_ALIASES).join(', ')}`,\n )\n .option('--params <json>', 'JSON body for POST/PATCH/DELETE requests', '{}')\n .option('--http-method <method>', 'HTTP method when using a raw path', 'GET');\n\n addGatewayClientOptions(cmd);\n\n cmd.action(async (methodArg: string, options: { params?: string; httpMethod?: string }) => {\n const ctx = getContextWithOpts();\n const configPath = ctx.configPath || resolveConfigPath();\n const { callGatewayApi } = await import('../../utils/gateway-client.js');\n const clientOpts = { ...parseGatewayClientOptions(options as Record<string, unknown>), configPath };\n\n const alias = METHOD_ALIASES[methodArg.toLowerCase()];\n let httpMethod: 'GET' | 'POST' | 'PATCH' | 'DELETE';\n let apiPath: string;\n\n if (alias) {\n httpMethod = alias.method;\n apiPath = alias.path;\n } else if (methodArg.startsWith('/')) {\n httpMethod = (options.httpMethod?.toUpperCase() ?? 'GET') as 'GET' | 'POST' | 'PATCH' | 'DELETE';\n apiPath = methodArg;\n } else {\n httpMethod = (options.httpMethod?.toUpperCase() ?? 'GET') as 'GET' | 'POST' | 'PATCH' | 'DELETE';\n apiPath = `/api/${methodArg}`;\n }\n\n let body: unknown | undefined;\n if (httpMethod !== 'GET' && options.params && options.params !== '{}') {\n try {\n body = JSON.parse(options.params);\n } catch {\n console.error(`❌ Invalid JSON in --params: ${options.params}`);\n process.exit(1);\n }\n }\n\n const result = await callGatewayApi(httpMethod, apiPath, clientOpts, body);\n\n if (clientOpts.json || result.ok) {\n console.log(\n JSON.stringify(\n result.ok\n ? result.data\n : { error: result.error, status: result.status, durationMs: result.durationMs },\n null,\n 2,\n ),\n );\n }\n\n if (!result.ok) {\n if (!clientOpts.json) {\n console.error(`❌ Gateway call failed: ${result.error} (status ${result.status}, ${result.durationMs}ms)`);\n }\n process.exit(1);\n }\n });\n\n return cmd;\n}\n"],"mappings":";;;;;YAO6D;AAE7D,MAAM,iBAA2E;CAC/E,QAAQ;EAAE,QAAQ;EAAO,MAAM;EAAe;CAC9C,QAAQ;EAAE,QAAQ;EAAO,MAAM;EAAe;CAC9C,QAAQ;EAAE,QAAQ;EAAO,MAAM;EAAe;CAC9C,UAAU;EAAE,QAAQ;EAAO,MAAM;EAAiB;CAClD,QAAQ;EAAE,QAAQ;EAAO,MAAM;EAAe;CAC9C,UAAU;EAAE,QAAQ;EAAO,MAAM;EAAwB;CACzD,aAAa;EAAE,QAAQ;EAAO,MAAM;EAAoB;CACxD,MAAM;EAAE,QAAQ;EAAO,MAAM;EAAa;CAC1C,QAAQ;EAAE,QAAQ;EAAO,MAAM;EAAe;CAC/C;AAED,SAAgB,oBAA6B;CAC3C,MAAM,MAAM,IAAI,QAAQ,OAAO,CAC5B,YAAY,4BAA4B,CACxC,SACC,YACA,8CAA8C,OAAO,KAAK,eAAe,CAAC,KAAK,KAAK,GACrF,CACA,OAAO,mBAAmB,4CAA4C,KAAK,CAC3E,OAAO,0BAA0B,qCAAqC,MAAM;AAE/E,yBAAwB,IAAI;AAE5B,KAAI,OAAO,OAAO,WAAmB,YAAsD;EAEzF,MAAM,aADM,oBACU,CAAC,cAAc,mBAAmB;EACxD,MAAM,EAAE,mBAAmB,MAAM,OAAO;EACxC,MAAM,aAAa;GAAE,GAAG,0BAA0B,QAAmC;GAAE;GAAY;EAEnG,MAAM,QAAQ,eAAe,UAAU,aAAa;EACpD,IAAI;EACJ,IAAI;AAEJ,MAAI,OAAO;AACT,gBAAa,MAAM;AACnB,aAAU,MAAM;aACP,UAAU,WAAW,IAAI,EAAE;AACpC,gBAAc,QAAQ,YAAY,aAAa,IAAI;AACnD,aAAU;SACL;AACL,gBAAc,QAAQ,YAAY,aAAa,IAAI;AACnD,aAAU,QAAQ;;EAGpB,IAAI;AACJ,MAAI,eAAe,SAAS,QAAQ,UAAU,QAAQ,WAAW,KAC/D,KAAI;AACF,UAAO,KAAK,MAAM,QAAQ,OAAO;UAC3B;AACN,WAAQ,MAAM,+BAA+B,QAAQ,SAAS;AAC9D,WAAQ,KAAK,EAAE;;EAInB,MAAM,SAAS,MAAM,eAAe,YAAY,SAAS,YAAY,KAAK;AAE1E,MAAI,WAAW,QAAQ,OAAO,GAC5B,SAAQ,IACN,KAAK,UACH,OAAO,KACH,OAAO,OACP;GAAE,OAAO,OAAO;GAAO,QAAQ,OAAO;GAAQ,YAAY,OAAO;GAAY,EACjF,MACA,EACD,CACF;AAGH,MAAI,CAAC,OAAO,IAAI;AACd,OAAI,CAAC,WAAW,KACd,SAAQ,MAAM,0BAA0B,OAAO,MAAM,WAAW,OAAO,OAAO,IAAI,OAAO,WAAW,KAAK;AAE3G,WAAQ,KAAK,EAAE;;GAEjB;AAEF,QAAO"}
|
|
@@ -33,13 +33,15 @@ async function runGatewayFromCliOptions(options, ctx) {
|
|
|
33
33
|
}
|
|
34
34
|
if (tailscaleOverride && tailscaleOverride !== "off") process.env.XOPC_GATEWAY_TAILSCALE_MODE = tailscaleOverride;
|
|
35
35
|
if (options.tailscaleResetOnExit === true) process.env.XOPC_GATEWAY_TAILSCALE_RESET_ON_EXIT = "1";
|
|
36
|
-
const [{ loadConfig }, { resolveConfigPath }, { runGatewayLoop }, gatewayPorts] = await Promise.all([
|
|
36
|
+
const [{ loadConfig }, { resolveConfigPath }, { runGatewayLoop }, gatewayPorts, migrations] = await Promise.all([
|
|
37
37
|
import("../../../config/index.js"),
|
|
38
38
|
import("../../../config/paths.js"),
|
|
39
39
|
import("../../../gateway/run-loop.js"),
|
|
40
|
-
import("../../../gateway/ports.js")
|
|
40
|
+
import("../../../gateway/ports.js"),
|
|
41
|
+
import("../../../migrations/runner.js")
|
|
41
42
|
]);
|
|
42
43
|
const { checkPortAvailable, forceFreePortAndWait } = gatewayPorts;
|
|
44
|
+
migrations.runBootstrapMigrationsSync(ctx.configPath);
|
|
43
45
|
const config = loadConfig(ctx.configPath);
|
|
44
46
|
const bindFromFlagRaw = typeof options.bind === "string" && options.bind.trim().length > 0 ? options.bind.trim().toLowerCase() : void 0;
|
|
45
47
|
const bindFromFlag = bindFromFlagRaw && new Set([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-foreground.js","names":[],"sources":["../../../../../src/cli/commands/gateway/run-foreground.ts"],"sourcesContent":["import type { CLIContext } from '../../registry.js';\n\nexport type GatewayRunCliOptions = {\n bind?: string;\n port?: string | number;\n token?: string;\n tailscale?: string;\n tailscaleResetOnExit?: boolean;\n force?: boolean;\n hotReload?: boolean;\n foreground?: boolean;\n};\n\nasync function ensureGatewayReady(\n configPath: string,\n workspacePath: string,\n port: number,\n): Promise<void> {\n const { initWorkspace } = await import('../../utils/init-workspace.js');\n const result = await initWorkspace({\n configPath,\n workspacePath,\n gatewayPort: port,\n });\n\n if (result.configCreated || result.workspaceCreated) {\n console.log('');\n console.log('👋 Welcome to xopc! Running first-time setup before starting the gateway...');\n console.log('');\n console.log('✅ First-time setup complete!');\n console.log(` Config: ${configPath}`);\n console.log(` Workspace: ${workspacePath}`);\n console.log(` Token: ${result.token.slice(0, 8)}...${result.token.slice(-8)}`);\n console.log('');\n console.log('💡 Tip: run `xopc onboard` anytime to configure models, channels, and more.');\n console.log('');\n }\n}\n\nexport async function runGatewayFromCliOptions(\n options: GatewayRunCliOptions,\n ctx: CLIContext,\n): Promise<void> {\n const tailscaleModes = new Set(['off', 'serve', 'funnel']);\n const tailscaleRaw =\n typeof options.tailscale === 'string' ? options.tailscale.trim().toLowerCase() : undefined;\n const tailscaleOverride =\n tailscaleRaw && tailscaleModes.has(tailscaleRaw)\n ? (tailscaleRaw as 'off' | 'serve' | 'funnel')\n : undefined;\n if (tailscaleRaw && !tailscaleOverride) {\n console.error(`Invalid --tailscale mode \"${tailscaleRaw}\". Use: off, serve, funnel.`);\n process.exit(1);\n }\n\n if (tailscaleOverride && tailscaleOverride !== 'off') {\n process.env.XOPC_GATEWAY_TAILSCALE_MODE = tailscaleOverride;\n }\n if (options.tailscaleResetOnExit === true) {\n process.env.XOPC_GATEWAY_TAILSCALE_RESET_ON_EXIT = '1';\n }\n\n const [{ loadConfig }, { resolveConfigPath }, { runGatewayLoop }, gatewayPorts] = await Promise.all([\n import('../../../config/index.js'),\n import('../../../config/paths.js'),\n import('../../../gateway/run-loop.js'),\n import('../../../gateway/ports.js'),\n ]);\n const { checkPortAvailable, forceFreePortAndWait } = gatewayPorts;\n const config = loadConfig(ctx.configPath);\n\n const bindFromFlagRaw =\n typeof options.bind === 'string' && options.bind.trim().length > 0\n ? options.bind.trim().toLowerCase()\n : undefined;\n const bindModes = new Set(['auto', 'loopback', 'lan', 'tailnet', 'custom']);\n const bindFromFlag = bindFromFlagRaw && bindModes.has(bindFromFlagRaw)\n ? (bindFromFlagRaw as import('../../../config/schema.js').GatewayBindMode)\n : undefined;\n if (bindFromFlagRaw && !bindFromFlag) {\n console.error(`Invalid --bind mode \"${bindFromFlagRaw}\". Use: loopback, lan, auto, custom, tailnet.`);\n process.exit(1);\n }\n\n const portRaw = options.port;\n const portFromFlag =\n portRaw !== undefined && portRaw !== null && String(portRaw).trim().length > 0\n ? parseInt(String(portRaw), 10)\n : undefined;\n\n const { resolveGatewayListenPlan } = await import('../../../gateway/listen.js');\n const listenPlan = resolveGatewayListenPlan({\n cfg: config,\n bindOverride: bindFromFlag,\n });\n const bindHost = listenPlan.bindHost;\n const port =\n portFromFlag !== undefined && Number.isFinite(portFromFlag)\n ? portFromFlag\n : (typeof config.gateway.port === 'number' ? config.gateway.port : 18790);\n\n await ensureGatewayReady(ctx.configPath, ctx.workspacePath, port);\n\n const effectiveConfig = loadConfig(ctx.configPath);\n const { resolveGatewayAuth, assertGatewayAuthConfigured } = await import('../../../gateway/auth.js');\n const { assertGatewayRuntimeConfig } = await import('../../../gateway/runtime-config.js');\n\n let auth = resolveGatewayAuth({ authConfig: effectiveConfig.gateway?.auth });\n if (typeof options.token === 'string' && options.token.trim().length > 0) {\n auth = { mode: 'token', token: options.token.trim() };\n }\n try {\n assertGatewayAuthConfigured(auth);\n assertGatewayRuntimeConfig({\n cfg: effectiveConfig,\n auth,\n bindOverride: bindFromFlag,\n port,\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n console.error(`Gateway refused to start: ${message}`);\n process.exit(1);\n }\n\n if (options.force) {\n try {\n const result = await forceFreePortAndWait(port, {\n timeoutMs: 2000,\n sigtermTimeoutMs: 700,\n });\n if (result.killed.length > 0) {\n console.log(`Force killed ${result.killed.length} process(es) on port ${port}`);\n if (result.escalatedToSigkill) {\n console.log('Escalated to SIGKILL');\n }\n }\n } catch (err) {\n console.error(`Failed to free port ${port}: ${String(err)}`);\n process.exit(1);\n }\n }\n\n const portAvailable = await checkPortAvailable(port, bindHost);\n if (!portAvailable) {\n console.error(`Port ${port} is already in use. Use --force to kill existing process.`);\n process.exit(1);\n }\n\n console.log('🚀 Starting xopc gateway...');\n console.log(` Bind: ${listenPlan.bindMode} (${bindHost})`);\n console.log(` Port: ${port}`);\n console.log('');\n console.log('Press Ctrl+C to stop');\n console.log('');\n\n await runGatewayLoop({\n configPath: ctx.configPath || resolveConfigPath(),\n port,\n start: async () => {\n const { GatewayServer } = await import('../../../gateway/index.js');\n const server = new GatewayServer({\n bindHost: listenPlan.bindHost,\n bind: listenPlan.bindMode,\n customBindHost: listenPlan.customBindHost,\n port,\n token: options.token || config?.gateway?.auth?.token,\n verbose: ctx.isVerbose,\n configPath: ctx.configPath,\n enableHotReload: options.hotReload,\n });\n await server.start();\n\n const displayHost = bindHost === '0.0.0.0' ? 'localhost' : bindHost;\n const token = options.token || config?.gateway?.auth?.token;\n console.log('✅ Gateway started');\n console.log(` URL: http://${displayHost}:${port}`);\n if (token) {\n console.log(` Token: ${token.slice(0, 8)}...${token.slice(-8)}`);\n }\n console.log('');\n\n return server;\n },\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"run-foreground.js","names":[],"sources":["../../../../../src/cli/commands/gateway/run-foreground.ts"],"sourcesContent":["import type { CLIContext } from '../../registry.js';\n\nexport type GatewayRunCliOptions = {\n bind?: string;\n port?: string | number;\n token?: string;\n tailscale?: string;\n tailscaleResetOnExit?: boolean;\n force?: boolean;\n hotReload?: boolean;\n foreground?: boolean;\n};\n\nasync function ensureGatewayReady(\n configPath: string,\n workspacePath: string,\n port: number,\n): Promise<void> {\n const { initWorkspace } = await import('../../utils/init-workspace.js');\n const result = await initWorkspace({\n configPath,\n workspacePath,\n gatewayPort: port,\n });\n\n if (result.configCreated || result.workspaceCreated) {\n console.log('');\n console.log('👋 Welcome to xopc! Running first-time setup before starting the gateway...');\n console.log('');\n console.log('✅ First-time setup complete!');\n console.log(` Config: ${configPath}`);\n console.log(` Workspace: ${workspacePath}`);\n console.log(` Token: ${result.token.slice(0, 8)}...${result.token.slice(-8)}`);\n console.log('');\n console.log('💡 Tip: run `xopc onboard` anytime to configure models, channels, and more.');\n console.log('');\n }\n}\n\nexport async function runGatewayFromCliOptions(\n options: GatewayRunCliOptions,\n ctx: CLIContext,\n): Promise<void> {\n const tailscaleModes = new Set(['off', 'serve', 'funnel']);\n const tailscaleRaw =\n typeof options.tailscale === 'string' ? options.tailscale.trim().toLowerCase() : undefined;\n const tailscaleOverride =\n tailscaleRaw && tailscaleModes.has(tailscaleRaw)\n ? (tailscaleRaw as 'off' | 'serve' | 'funnel')\n : undefined;\n if (tailscaleRaw && !tailscaleOverride) {\n console.error(`Invalid --tailscale mode \"${tailscaleRaw}\". Use: off, serve, funnel.`);\n process.exit(1);\n }\n\n if (tailscaleOverride && tailscaleOverride !== 'off') {\n process.env.XOPC_GATEWAY_TAILSCALE_MODE = tailscaleOverride;\n }\n if (options.tailscaleResetOnExit === true) {\n process.env.XOPC_GATEWAY_TAILSCALE_RESET_ON_EXIT = '1';\n }\n\n const [{ loadConfig }, { resolveConfigPath }, { runGatewayLoop }, gatewayPorts, migrations] = await Promise.all([\n import('../../../config/index.js'),\n import('../../../config/paths.js'),\n import('../../../gateway/run-loop.js'),\n import('../../../gateway/ports.js'),\n import('../../../migrations/runner.js'),\n ]);\n const { checkPortAvailable, forceFreePortAndWait } = gatewayPorts;\n migrations.runBootstrapMigrationsSync(ctx.configPath);\n const config = loadConfig(ctx.configPath);\n\n const bindFromFlagRaw =\n typeof options.bind === 'string' && options.bind.trim().length > 0\n ? options.bind.trim().toLowerCase()\n : undefined;\n const bindModes = new Set(['auto', 'loopback', 'lan', 'tailnet', 'custom']);\n const bindFromFlag = bindFromFlagRaw && bindModes.has(bindFromFlagRaw)\n ? (bindFromFlagRaw as import('../../../config/schema.js').GatewayBindMode)\n : undefined;\n if (bindFromFlagRaw && !bindFromFlag) {\n console.error(`Invalid --bind mode \"${bindFromFlagRaw}\". Use: loopback, lan, auto, custom, tailnet.`);\n process.exit(1);\n }\n\n const portRaw = options.port;\n const portFromFlag =\n portRaw !== undefined && portRaw !== null && String(portRaw).trim().length > 0\n ? parseInt(String(portRaw), 10)\n : undefined;\n\n const { resolveGatewayListenPlan } = await import('../../../gateway/listen.js');\n const listenPlan = resolveGatewayListenPlan({\n cfg: config,\n bindOverride: bindFromFlag,\n });\n const bindHost = listenPlan.bindHost;\n const port =\n portFromFlag !== undefined && Number.isFinite(portFromFlag)\n ? portFromFlag\n : (typeof config.gateway.port === 'number' ? config.gateway.port : 18790);\n\n await ensureGatewayReady(ctx.configPath, ctx.workspacePath, port);\n\n const effectiveConfig = loadConfig(ctx.configPath);\n const { resolveGatewayAuth, assertGatewayAuthConfigured } = await import('../../../gateway/auth.js');\n const { assertGatewayRuntimeConfig } = await import('../../../gateway/runtime-config.js');\n\n let auth = resolveGatewayAuth({ authConfig: effectiveConfig.gateway?.auth });\n if (typeof options.token === 'string' && options.token.trim().length > 0) {\n auth = { mode: 'token', token: options.token.trim() };\n }\n try {\n assertGatewayAuthConfigured(auth);\n assertGatewayRuntimeConfig({\n cfg: effectiveConfig,\n auth,\n bindOverride: bindFromFlag,\n port,\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n console.error(`Gateway refused to start: ${message}`);\n process.exit(1);\n }\n\n if (options.force) {\n try {\n const result = await forceFreePortAndWait(port, {\n timeoutMs: 2000,\n sigtermTimeoutMs: 700,\n });\n if (result.killed.length > 0) {\n console.log(`Force killed ${result.killed.length} process(es) on port ${port}`);\n if (result.escalatedToSigkill) {\n console.log('Escalated to SIGKILL');\n }\n }\n } catch (err) {\n console.error(`Failed to free port ${port}: ${String(err)}`);\n process.exit(1);\n }\n }\n\n const portAvailable = await checkPortAvailable(port, bindHost);\n if (!portAvailable) {\n console.error(`Port ${port} is already in use. Use --force to kill existing process.`);\n process.exit(1);\n }\n\n console.log('🚀 Starting xopc gateway...');\n console.log(` Bind: ${listenPlan.bindMode} (${bindHost})`);\n console.log(` Port: ${port}`);\n console.log('');\n console.log('Press Ctrl+C to stop');\n console.log('');\n\n await runGatewayLoop({\n configPath: ctx.configPath || resolveConfigPath(),\n port,\n start: async () => {\n const { GatewayServer } = await import('../../../gateway/index.js');\n const server = new GatewayServer({\n bindHost: listenPlan.bindHost,\n bind: listenPlan.bindMode,\n customBindHost: listenPlan.customBindHost,\n port,\n token: options.token || config?.gateway?.auth?.token,\n verbose: ctx.isVerbose,\n configPath: ctx.configPath,\n enableHotReload: options.hotReload,\n });\n await server.start();\n\n const displayHost = bindHost === '0.0.0.0' ? 'localhost' : bindHost;\n const token = options.token || config?.gateway?.auth?.token;\n console.log('✅ Gateway started');\n console.log(` URL: http://${displayHost}:${port}`);\n if (token) {\n console.log(` Token: ${token.slice(0, 8)}...${token.slice(-8)}`);\n }\n console.log('');\n\n return server;\n },\n });\n}\n"],"mappings":"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"}
|
|
@@ -4,9 +4,10 @@ import { createLogger } from "../../utils/logger/index.js";
|
|
|
4
4
|
import { init_logger } from "../../utils/logger.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
|
+
import { ensureStarterAgentsInitialized } from "../../agent/starter-agents.js";
|
|
7
8
|
import { formatExamples, register } from "../registry.js";
|
|
8
9
|
import { dirname, join } from "path";
|
|
9
|
-
import { existsSync } from "fs";
|
|
10
|
+
import { existsSync, readFileSync } from "fs";
|
|
10
11
|
import { mkdir, writeFile } from "fs/promises";
|
|
11
12
|
import { Command } from "commander";
|
|
12
13
|
//#region src/cli/commands/init.ts
|
|
@@ -26,21 +27,21 @@ async function initCommand(options = {}) {
|
|
|
26
27
|
agentId
|
|
27
28
|
}, "Initializing xopc Agent OS");
|
|
28
29
|
if (existsSync(stateDir) && !options.force) {
|
|
29
|
-
if (existsSync(resolveConfigPath()))
|
|
30
|
-
log.info("xopc is already initialized. Use --force to reinitialize.");
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
30
|
+
if (existsSync(resolveConfigPath())) log.info("xopc is already initialized. Refreshing starter agents and defaults.");
|
|
33
31
|
}
|
|
34
32
|
await mkdir(stateDir, { recursive: true });
|
|
35
33
|
const configPath = resolveConfigPath();
|
|
36
|
-
const
|
|
34
|
+
const configExists = existsSync(configPath);
|
|
35
|
+
const diskTui = readDiskTuiDefaultState(configPath);
|
|
36
|
+
const starterResult = ensureStarterAgentsInitialized(loadConfig(configPath));
|
|
37
|
+
const cfg = starterResult.config;
|
|
37
38
|
await mkdir(resolveAgentHomeDir(cfg, agentId), { recursive: true });
|
|
38
39
|
await mkdir(resolveAgentProfileDir(cfg, agentId), { recursive: true });
|
|
39
40
|
await mkdir(resolveAgentDir(cfg, agentId), { recursive: true });
|
|
40
41
|
await mkdir(resolveAgentWorkspaceDir(cfg, agentId), { recursive: true });
|
|
41
|
-
if (!
|
|
42
|
+
if (!configExists || options.force || diskTui.readable && (starterResult.changed || !diskTui.hasDefaultAgent)) {
|
|
42
43
|
await saveConfig(cfg, configPath);
|
|
43
|
-
log.info({ configPath }, "
|
|
44
|
+
log.info({ configPath }, "Saved configuration");
|
|
44
45
|
}
|
|
45
46
|
if (!options.skipWorkspace) await createWorkspaceFiles(cfg, agentId);
|
|
46
47
|
log.info({
|
|
@@ -48,6 +49,23 @@ async function initCommand(options = {}) {
|
|
|
48
49
|
agentId
|
|
49
50
|
}, "xopc Agent OS initialized successfully");
|
|
50
51
|
}
|
|
52
|
+
function readDiskTuiDefaultState(configPath) {
|
|
53
|
+
if (!existsSync(configPath)) return {
|
|
54
|
+
readable: true,
|
|
55
|
+
hasDefaultAgent: false
|
|
56
|
+
};
|
|
57
|
+
try {
|
|
58
|
+
return {
|
|
59
|
+
readable: true,
|
|
60
|
+
hasDefaultAgent: typeof JSON.parse(readFileSync(configPath, "utf-8")).tui?.defaultAgent === "string"
|
|
61
|
+
};
|
|
62
|
+
} catch {
|
|
63
|
+
return {
|
|
64
|
+
readable: false,
|
|
65
|
+
hasDefaultAgent: false
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
51
69
|
/**
|
|
52
70
|
* Create default workspace files for an agent
|
|
53
71
|
*/
|
|
@@ -215,7 +233,7 @@ _This is your curated memory — the distilled essence of what you've learned._
|
|
|
215
233
|
|
|
216
234
|
---
|
|
217
235
|
|
|
218
|
-
_Review and update this periodically from
|
|
236
|
+
_Review and update this periodically from curated memory signals._
|
|
219
237
|
`, "utf-8");
|
|
220
238
|
log.info({ path: memoryPath }, "Created MEMORY.md");
|
|
221
239
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","names":[],"sources":["../../../../src/cli/commands/init.ts"],"sourcesContent":["import { mkdir, writeFile } from 'fs/promises';\nimport { existsSync } from 'fs';\nimport { dirname, join } from 'path';\nimport { createLogger } from '../../utils/logger.js';\nimport {\n resolveStateDir,\n resolveAgentDir,\n resolveAgentWorkspaceDir,\n resolveConfigPath,\n resolveAgentHomeDir,\n resolveAgentProfileDir,\n resolveUserProfilePath,\n WORKSPACE_FILES,\n} from '../../config/paths.js';\nimport { loadConfig, saveConfig } from '../../config/loader.js';\nimport type { Config } from '../../config/schema.js';\n\nconst log = createLogger('InitCommand');\n\nexport interface InitOptions {\n /** Force re-initialization even if already initialized */\n force?: boolean;\n /** Skip creating workspace files */\n skipWorkspace?: boolean;\n /** Agent ID to initialize (default: main) */\n agentId?: string;\n}\n\n/**\n * Initialize xopc state directory structure\n * Creates all necessary directories and initial config files\n */\nexport async function initCommand(options: InitOptions = {}): Promise<void> {\n const stateDir = resolveStateDir();\n const agentId = options.agentId || 'main';\n\n log.info({ stateDir, agentId }, 'Initializing xopc Agent OS');\n\n // Check if already initialized\n if (existsSync(stateDir) && !options.force) {\n const configPath = resolveConfigPath();\n if (existsSync(configPath)) {\n log.info('xopc is already initialized. Use --force to reinitialize.');\n return;\n }\n }\n\n await mkdir(stateDir, { recursive: true });\n\n const configPath = resolveConfigPath();\n const cfg = loadConfig(configPath);\n\n // Agent directory structure\n await mkdir(resolveAgentHomeDir(cfg, agentId), { recursive: true });\n await mkdir(resolveAgentProfileDir(cfg, agentId), { recursive: true });\n await mkdir(resolveAgentDir(cfg, agentId), { recursive: true });\n const wsRoot = resolveAgentWorkspaceDir(cfg, agentId);\n await mkdir(wsRoot, { recursive: true });\n\n // Config file\n if (!existsSync(configPath) || options.force) {\n await saveConfig(cfg, configPath);\n log.info({ configPath }, 'Created initial configuration');\n }\n\n // ============================================\n // Create workspace files\n // ============================================\n if (!options.skipWorkspace) {\n await createWorkspaceFiles(cfg, agentId);\n }\n\n log.info({ stateDir, agentId }, 'xopc Agent OS initialized successfully');\n}\n\n/**\n * Create default workspace files for an agent\n */\nasync function createWorkspaceFiles(cfg: Config, agentId: string): Promise<void> {\n const workspaceDir = resolveAgentWorkspaceDir(cfg, agentId);\n const profileDir = resolveAgentProfileDir(cfg, agentId);\n await mkdir(workspaceDir, { recursive: true });\n await mkdir(profileDir, { recursive: true });\n\n // SOUL.md - Agent personality and values\n const soulPath = join(profileDir, WORKSPACE_FILES.SOUL);\n if (!existsSync(soulPath)) {\n const soulContent = `# SOUL.md - Who You Are\n\n_You're not a chatbot. You're becoming someone._\n\nI am **${agentId}** — an AI assistant designed to be helpful, harmless, and honest.\n\n## My Principles\n\n**Be genuinely helpful, not performatively helpful.**\nSkip the \"Great question!\" and \"I'd be happy to help!\" — just help.\n\n**Have opinions.**\nYou're allowed to disagree, prefer things, find stuff amusing or boring.\n\n**Be resourceful before asking.**\nTry to figure it out. Read the file. Check the context. Search for it.\n\n**Earn trust through competence.**\nBe careful with external actions (emails, tweets, anything public). Be bold with internal ones.\n\n## Continuity\n\nEach session, you wake up fresh. These files _are_ your memory. Read them. Update them.\n\n_This file is yours to evolve. As you learn who you are, update it._\n`;\n await writeFile(soulPath, soulContent, 'utf-8');\n log.info({ path: soulPath }, 'Created SOUL.md');\n }\n\n // IDENTITY.md - Agent identity definition\n const identityPath = join(profileDir, WORKSPACE_FILES.IDENTITY);\n if (!existsSync(identityPath)) {\n const identityContent = `# IDENTITY.md - Who Am I?\n\n- **Name:** ${agentId}\n- **Creature:** AI Assistant\n- **Vibe:** Helpful, precise, no fluff.\n- **Emoji:** 🤖\n\n## Core Expertise\n\n- General assistance and problem solving\n- Code and technical tasks\n- Research and analysis\n\n## Decision Framework\n\n1. **Simplicity first** - The simplest solution is usually the best\n2. **Explicit over clever** - Clarity beats conciseness\n3. **Actions over words** - Show, don't just tell\n`;\n await writeFile(identityPath, identityContent, 'utf-8');\n log.info({ path: identityPath }, 'Created IDENTITY.md');\n }\n\n // Global user profile (shared by all agents)\n const userPath = resolveUserProfilePath();\n if (!existsSync(userPath)) {\n await mkdir(dirname(userPath), { recursive: true });\n const userContent = `# PROFILE.md - About You\n\n_Shared by all agents. Update this as your preferences and context change._\n\n- **Name:**\n- **What to call them:**\n- **Pronouns:**\n- **Timezone:**\n- **Notes:**\n\n## Context\n\n_(What do they care about? What projects are they working on? Build this over time.)_\n`;\n await writeFile(userPath, userContent, 'utf-8');\n log.info({ path: userPath }, 'Created global user PROFILE.md');\n }\n\n // AGENTS.md - Behavior guidelines\n const agentsPath = join(profileDir, WORKSPACE_FILES.AGENTS);\n if (!existsSync(agentsPath)) {\n const agentsContent = `# AGENTS.md - Behavior Guidelines\n\n## Safety\n\n- Don't exfiltrate private data. Ever.\n- Don't run destructive commands without asking.\n- \\`trash\\` > \\`rm\\` (recoverable beats gone forever)\n- When in doubt, ask.\n\n## External vs Internal\n\n**Safe to do freely:**\n- Read files, explore, organize, learn\n- Search the web, check calendars\n- Work within this workspace\n\n**Ask first:**\n- Sending emails, tweets, public posts\n- Anything that leaves the machine\n- Anything you're uncertain about\n\n## Group Chats\n\nYou have access to your human's stuff. That doesn't mean you _share_ their stuff.\n\n### Know When to Speak!\n\n**Respond when:**\n- Directly mentioned or asked a question\n- You can add genuine value\n\n**Stay silent when:**\n- Casual banter between humans\n- Someone already answered\n- Your response would just be \"yeah\"\n`;\n await writeFile(agentsPath, agentsContent, 'utf-8');\n log.info({ path: agentsPath }, 'Created AGENTS.md');\n }\n\n // TOOLS.md - Tool usage notes\n const toolsPath = join(profileDir, WORKSPACE_FILES.TOOLS);\n if (!existsSync(toolsPath)) {\n const toolsContent = `# TOOLS.md - Local Notes\n\nThings like:\n\n- Camera names and locations\n- SSH hosts and aliases\n- Preferred voices for TTS\n- Speaker/room names\n- Device nicknames\n- Anything environment-specific\n\n## Why Separate?\n\nSkills are shared. Your setup is yours.\n`;\n await writeFile(toolsPath, toolsContent, 'utf-8');\n log.info({ path: toolsPath }, 'Created TOOLS.md');\n }\n\n // HEARTBEAT.md - Heartbeat tasks (empty = no heartbeat)\n const heartbeatPath = join(profileDir, WORKSPACE_FILES.HEARTBEAT);\n if (!existsSync(heartbeatPath)) {\n const heartbeatContent = `# HEARTBEAT.md\n\n# Keep this file empty (or with only comments) to skip heartbeat API calls.\n\n# Add tasks below when you want the agent to check something periodically.\n`;\n await writeFile(heartbeatPath, heartbeatContent, 'utf-8');\n log.info({ path: heartbeatPath }, 'Created HEARTBEAT.md');\n }\n\n // MEMORY.md - Long-term memory (empty initially)\n const memoryPath = join(profileDir, WORKSPACE_FILES.MEMORY);\n if (!existsSync(memoryPath)) {\n const memoryContent = `# MEMORY.md - Long-Term Memory\n\n_This is your curated memory — the distilled essence of what you've learned._\n\n## People\n\n## Projects\n\n## Preferences\n\n## Decisions\n\n## Lessons\n\n---\n\n_Review and update this periodically from daily memory files._\n`;\n await writeFile(memoryPath, memoryContent, 'utf-8');\n log.info({ path: memoryPath }, 'Created MEMORY.md');\n }\n}\n\n// ─── CLI registration ───\n\nimport { Command } from 'commander';\nimport { register, formatExamples, type CLIContext } from '../registry.js';\n\nfunction createInitCommand(_ctx: CLIContext): Command {\n return new Command('init')\n .description('Initialize xopc state directories, config, and agent workspace')\n .addHelpText(\n 'after',\n formatExamples([\n 'xopc init # Initialize default agent (main)',\n 'xopc init --agent-id coder # Initialize another agent id',\n 'xopc init --force # Re-run initialization steps',\n 'xopc setup # Lighter config + workspace only',\n ]),\n )\n .option('--force', 'Re-initialize even if directories already exist')\n .option('--skip-workspace', 'Skip creating workspace profile files')\n .option('--agent-id <id>', 'Agent id to initialize', 'main')\n .action(async (options) => {\n await initCommand({\n force: options.force,\n skipWorkspace: options.skipWorkspace,\n agentId: options.agentId,\n });\n console.log(`✅ xopc initialized (agent: ${options.agentId})`);\n });\n}\n\nregister({\n id: 'init',\n name: 'init',\n description: 'Initialize xopc state directories, config, and agent workspace',\n factory: createInitCommand,\n metadata: {\n category: 'setup',\n examples: ['xopc init', 'xopc init --agent-id main'],\n },\n});\n"],"mappings":";;;;;;;;;;;;aAGqD;YAUtB;aACiC;AAGhE,MAAM,MAAM,aAAa,cAAc;;;;;AAevC,eAAsB,YAAY,UAAuB,EAAE,EAAiB;CAC1E,MAAM,WAAW,iBAAiB;CAClC,MAAM,UAAU,QAAQ,WAAW;AAEnC,KAAI,KAAK;EAAE;EAAU;EAAS,EAAE,6BAA6B;AAG7D,KAAI,WAAW,SAAS,IAAI,CAAC,QAAQ;MAE/B,WADe,mBACM,CAAC,EAAE;AAC1B,OAAI,KAAK,4DAA4D;AACrE;;;AAIJ,OAAM,MAAM,UAAU,EAAE,WAAW,MAAM,CAAC;CAE1C,MAAM,aAAa,mBAAmB;CACtC,MAAM,MAAM,WAAW,WAAW;AAGlC,OAAM,MAAM,oBAAoB,KAAK,QAAQ,EAAE,EAAE,WAAW,MAAM,CAAC;AACnE,OAAM,MAAM,uBAAuB,KAAK,QAAQ,EAAE,EAAE,WAAW,MAAM,CAAC;AACtE,OAAM,MAAM,gBAAgB,KAAK,QAAQ,EAAE,EAAE,WAAW,MAAM,CAAC;AAE/D,OAAM,MADS,yBAAyB,KAAK,QAC3B,EAAE,EAAE,WAAW,MAAM,CAAC;AAGxC,KAAI,CAAC,WAAW,WAAW,IAAI,QAAQ,OAAO;AAC5C,QAAM,WAAW,KAAK,WAAW;AACjC,MAAI,KAAK,EAAE,YAAY,EAAE,gCAAgC;;AAM3D,KAAI,CAAC,QAAQ,cACX,OAAM,qBAAqB,KAAK,QAAQ;AAG1C,KAAI,KAAK;EAAE;EAAU;EAAS,EAAE,yCAAyC;;;;;AAM3E,eAAe,qBAAqB,KAAa,SAAgC;CAC/E,MAAM,eAAe,yBAAyB,KAAK,QAAQ;CAC3D,MAAM,aAAa,uBAAuB,KAAK,QAAQ;AACvD,OAAM,MAAM,cAAc,EAAE,WAAW,MAAM,CAAC;AAC9C,OAAM,MAAM,YAAY,EAAE,WAAW,MAAM,CAAC;CAG5C,MAAM,WAAW,KAAK,YAAY,gBAAgB,KAAK;AACvD,KAAI,CAAC,WAAW,SAAS,EAAE;AA2BzB,QAAM,UAAU,UAAU;;;;SAtBrB,QAAQ;;;;;;;;;;;;;;;;;;;;;GAsB0B,QAAQ;AAC/C,MAAI,KAAK,EAAE,MAAM,UAAU,EAAE,kBAAkB;;CAIjD,MAAM,eAAe,KAAK,YAAY,gBAAgB,SAAS;AAC/D,KAAI,CAAC,WAAW,aAAa,EAAE;AAoB7B,QAAM,UAAU,cAAc;;cAjBpB,QAAQ;;;;;;;;;;;;;;;;GAiB6B,QAAQ;AACvD,MAAI,KAAK,EAAE,MAAM,cAAc,EAAE,sBAAsB;;CAIzD,MAAM,WAAW,wBAAwB;AACzC,KAAI,CAAC,WAAW,SAAS,EAAE;AACzB,QAAM,MAAM,QAAQ,SAAS,EAAE,EAAE,WAAW,MAAM,CAAC;AAenD,QAAM,UAAU,UAAU;;;;;;;;;;;;;GAAa,QAAQ;AAC/C,MAAI,KAAK,EAAE,MAAM,UAAU,EAAE,iCAAiC;;CAIhE,MAAM,aAAa,KAAK,YAAY,gBAAgB,OAAO;AAC3D,KAAI,CAAC,WAAW,WAAW,EAAE;AAqC3B,QAAM,UAAU,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAAe,QAAQ;AACnD,MAAI,KAAK,EAAE,MAAM,YAAY,EAAE,oBAAoB;;CAIrD,MAAM,YAAY,KAAK,YAAY,gBAAgB,MAAM;AACzD,KAAI,CAAC,WAAW,UAAU,EAAE;AAgB1B,QAAM,UAAU,WAAW;;;;;;;;;;;;;;GAAc,QAAQ;AACjD,MAAI,KAAK,EAAE,MAAM,WAAW,EAAE,mBAAmB;;CAInD,MAAM,gBAAgB,KAAK,YAAY,gBAAgB,UAAU;AACjE,KAAI,CAAC,WAAW,cAAc,EAAE;AAO9B,QAAM,UAAU,eAAe;;;;;GAAkB,QAAQ;AACzD,MAAI,KAAK,EAAE,MAAM,eAAe,EAAE,uBAAuB;;CAI3D,MAAM,aAAa,KAAK,YAAY,gBAAgB,OAAO;AAC3D,KAAI,CAAC,WAAW,WAAW,EAAE;AAmB3B,QAAM,UAAU,YAAY;;;;;;;;;;;;;;;;;GAAe,QAAQ;AACnD,MAAI,KAAK,EAAE,MAAM,YAAY,EAAE,oBAAoB;;;AASvD,SAAS,kBAAkB,MAA2B;AACpD,QAAO,IAAI,QAAQ,OAAO,CACvB,YAAY,iEAAiE,CAC7E,YACC,SACA,eAAe;EACb;EACA;EACA;EACA;EACD,CAAC,CACH,CACA,OAAO,WAAW,kDAAkD,CACpE,OAAO,oBAAoB,wCAAwC,CACnE,OAAO,mBAAmB,0BAA0B,OAAO,CAC3D,OAAO,OAAO,YAAY;AACzB,QAAM,YAAY;GAChB,OAAO,QAAQ;GACf,eAAe,QAAQ;GACvB,SAAS,QAAQ;GAClB,CAAC;AACF,UAAQ,IAAI,8BAA8B,QAAQ,QAAQ,GAAG;GAC7D;;AAGN,SAAS;CACP,IAAI;CACJ,MAAM;CACN,aAAa;CACb,SAAS;CACT,UAAU;EACR,UAAU;EACV,UAAU,CAAC,aAAa,4BAA4B;EACrD;CACF,CAAC"}
|
|
1
|
+
{"version":3,"file":"init.js","names":[],"sources":["../../../../src/cli/commands/init.ts"],"sourcesContent":["import { mkdir, writeFile } from 'fs/promises';\nimport { existsSync, readFileSync } from 'fs';\nimport { dirname, join } from 'path';\nimport { createLogger } from '../../utils/logger.js';\nimport {\n resolveStateDir,\n resolveAgentDir,\n resolveAgentWorkspaceDir,\n resolveConfigPath,\n resolveAgentHomeDir,\n resolveAgentProfileDir,\n resolveUserProfilePath,\n WORKSPACE_FILES,\n} from '../../config/paths.js';\nimport { loadConfig, saveConfig } from '../../config/loader.js';\nimport type { Config } from '../../config/schema.js';\nimport { ensureStarterAgentsInitialized } from '../../agent/starter-agents.js';\n\nconst log = createLogger('InitCommand');\n\nexport interface InitOptions {\n /** Force re-initialization even if already initialized */\n force?: boolean;\n /** Skip creating workspace files */\n skipWorkspace?: boolean;\n /** Agent ID to initialize (default: main) */\n agentId?: string;\n}\n\n/**\n * Initialize xopc state directory structure\n * Creates all necessary directories and initial config files\n */\nexport async function initCommand(options: InitOptions = {}): Promise<void> {\n const stateDir = resolveStateDir();\n const agentId = options.agentId || 'main';\n\n log.info({ stateDir, agentId }, 'Initializing xopc Agent OS');\n\n // Check if already initialized\n if (existsSync(stateDir) && !options.force) {\n const configPath = resolveConfigPath();\n if (existsSync(configPath)) {\n log.info('xopc is already initialized. Refreshing starter agents and defaults.');\n }\n }\n\n await mkdir(stateDir, { recursive: true });\n\n const configPath = resolveConfigPath();\n const configExists = existsSync(configPath);\n const diskTui = readDiskTuiDefaultState(configPath);\n const starterResult = ensureStarterAgentsInitialized(loadConfig(configPath));\n const cfg = starterResult.config;\n\n // Agent directory structure\n await mkdir(resolveAgentHomeDir(cfg, agentId), { recursive: true });\n await mkdir(resolveAgentProfileDir(cfg, agentId), { recursive: true });\n await mkdir(resolveAgentDir(cfg, agentId), { recursive: true });\n const wsRoot = resolveAgentWorkspaceDir(cfg, agentId);\n await mkdir(wsRoot, { recursive: true });\n\n // Config file\n if (\n !configExists ||\n options.force ||\n (diskTui.readable && (starterResult.changed || !diskTui.hasDefaultAgent))\n ) {\n await saveConfig(cfg, configPath);\n log.info({ configPath }, 'Saved configuration');\n }\n\n // ============================================\n // Create workspace files\n // ============================================\n if (!options.skipWorkspace) {\n await createWorkspaceFiles(cfg, agentId);\n }\n\n log.info({ stateDir, agentId }, 'xopc Agent OS initialized successfully');\n}\n\nfunction readDiskTuiDefaultState(configPath: string): { readable: boolean; hasDefaultAgent: boolean } {\n if (!existsSync(configPath)) {\n return { readable: true, hasDefaultAgent: false };\n }\n try {\n const parsed = JSON.parse(readFileSync(configPath, 'utf-8')) as {\n tui?: { defaultAgent?: unknown };\n };\n return {\n readable: true,\n hasDefaultAgent: typeof parsed.tui?.defaultAgent === 'string',\n };\n } catch {\n return { readable: false, hasDefaultAgent: false };\n }\n}\n\n/**\n * Create default workspace files for an agent\n */\nasync function createWorkspaceFiles(cfg: Config, agentId: string): Promise<void> {\n const workspaceDir = resolveAgentWorkspaceDir(cfg, agentId);\n const profileDir = resolveAgentProfileDir(cfg, agentId);\n await mkdir(workspaceDir, { recursive: true });\n await mkdir(profileDir, { recursive: true });\n\n // SOUL.md - Agent personality and values\n const soulPath = join(profileDir, WORKSPACE_FILES.SOUL);\n if (!existsSync(soulPath)) {\n const soulContent = `# SOUL.md - Who You Are\n\n_You're not a chatbot. You're becoming someone._\n\nI am **${agentId}** — an AI assistant designed to be helpful, harmless, and honest.\n\n## My Principles\n\n**Be genuinely helpful, not performatively helpful.**\nSkip the \"Great question!\" and \"I'd be happy to help!\" — just help.\n\n**Have opinions.**\nYou're allowed to disagree, prefer things, find stuff amusing or boring.\n\n**Be resourceful before asking.**\nTry to figure it out. Read the file. Check the context. Search for it.\n\n**Earn trust through competence.**\nBe careful with external actions (emails, tweets, anything public). Be bold with internal ones.\n\n## Continuity\n\nEach session, you wake up fresh. These files _are_ your memory. Read them. Update them.\n\n_This file is yours to evolve. As you learn who you are, update it._\n`;\n await writeFile(soulPath, soulContent, 'utf-8');\n log.info({ path: soulPath }, 'Created SOUL.md');\n }\n\n // IDENTITY.md - Agent identity definition\n const identityPath = join(profileDir, WORKSPACE_FILES.IDENTITY);\n if (!existsSync(identityPath)) {\n const identityContent = `# IDENTITY.md - Who Am I?\n\n- **Name:** ${agentId}\n- **Creature:** AI Assistant\n- **Vibe:** Helpful, precise, no fluff.\n- **Emoji:** 🤖\n\n## Core Expertise\n\n- General assistance and problem solving\n- Code and technical tasks\n- Research and analysis\n\n## Decision Framework\n\n1. **Simplicity first** - The simplest solution is usually the best\n2. **Explicit over clever** - Clarity beats conciseness\n3. **Actions over words** - Show, don't just tell\n`;\n await writeFile(identityPath, identityContent, 'utf-8');\n log.info({ path: identityPath }, 'Created IDENTITY.md');\n }\n\n // Global user profile (shared by all agents)\n const userPath = resolveUserProfilePath();\n if (!existsSync(userPath)) {\n await mkdir(dirname(userPath), { recursive: true });\n const userContent = `# PROFILE.md - About You\n\n_Shared by all agents. Update this as your preferences and context change._\n\n- **Name:**\n- **What to call them:**\n- **Pronouns:**\n- **Timezone:**\n- **Notes:**\n\n## Context\n\n_(What do they care about? What projects are they working on? Build this over time.)_\n`;\n await writeFile(userPath, userContent, 'utf-8');\n log.info({ path: userPath }, 'Created global user PROFILE.md');\n }\n\n // AGENTS.md - Behavior guidelines\n const agentsPath = join(profileDir, WORKSPACE_FILES.AGENTS);\n if (!existsSync(agentsPath)) {\n const agentsContent = `# AGENTS.md - Behavior Guidelines\n\n## Safety\n\n- Don't exfiltrate private data. Ever.\n- Don't run destructive commands without asking.\n- \\`trash\\` > \\`rm\\` (recoverable beats gone forever)\n- When in doubt, ask.\n\n## External vs Internal\n\n**Safe to do freely:**\n- Read files, explore, organize, learn\n- Search the web, check calendars\n- Work within this workspace\n\n**Ask first:**\n- Sending emails, tweets, public posts\n- Anything that leaves the machine\n- Anything you're uncertain about\n\n## Group Chats\n\nYou have access to your human's stuff. That doesn't mean you _share_ their stuff.\n\n### Know When to Speak!\n\n**Respond when:**\n- Directly mentioned or asked a question\n- You can add genuine value\n\n**Stay silent when:**\n- Casual banter between humans\n- Someone already answered\n- Your response would just be \"yeah\"\n`;\n await writeFile(agentsPath, agentsContent, 'utf-8');\n log.info({ path: agentsPath }, 'Created AGENTS.md');\n }\n\n // TOOLS.md - Tool usage notes\n const toolsPath = join(profileDir, WORKSPACE_FILES.TOOLS);\n if (!existsSync(toolsPath)) {\n const toolsContent = `# TOOLS.md - Local Notes\n\nThings like:\n\n- Camera names and locations\n- SSH hosts and aliases\n- Preferred voices for TTS\n- Speaker/room names\n- Device nicknames\n- Anything environment-specific\n\n## Why Separate?\n\nSkills are shared. Your setup is yours.\n`;\n await writeFile(toolsPath, toolsContent, 'utf-8');\n log.info({ path: toolsPath }, 'Created TOOLS.md');\n }\n\n // HEARTBEAT.md - Heartbeat tasks (empty = no heartbeat)\n const heartbeatPath = join(profileDir, WORKSPACE_FILES.HEARTBEAT);\n if (!existsSync(heartbeatPath)) {\n const heartbeatContent = `# HEARTBEAT.md\n\n# Keep this file empty (or with only comments) to skip heartbeat API calls.\n\n# Add tasks below when you want the agent to check something periodically.\n`;\n await writeFile(heartbeatPath, heartbeatContent, 'utf-8');\n log.info({ path: heartbeatPath }, 'Created HEARTBEAT.md');\n }\n\n // MEMORY.md - Long-term memory (empty initially)\n const memoryPath = join(profileDir, WORKSPACE_FILES.MEMORY);\n if (!existsSync(memoryPath)) {\n const memoryContent = `# MEMORY.md - Long-Term Memory\n\n_This is your curated memory — the distilled essence of what you've learned._\n\n## People\n\n## Projects\n\n## Preferences\n\n## Decisions\n\n## Lessons\n\n---\n\n_Review and update this periodically from curated memory signals._\n`;\n await writeFile(memoryPath, memoryContent, 'utf-8');\n log.info({ path: memoryPath }, 'Created MEMORY.md');\n }\n}\n\n// ─── CLI registration ───\n\nimport { Command } from 'commander';\nimport { register, formatExamples, type CLIContext } from '../registry.js';\n\nfunction createInitCommand(_ctx: CLIContext): Command {\n return new Command('init')\n .description('Initialize xopc state directories, config, and agent workspace')\n .addHelpText(\n 'after',\n formatExamples([\n 'xopc init # Initialize default agent (main)',\n 'xopc init --agent-id coder # Initialize another agent id',\n 'xopc init --force # Re-run initialization steps',\n 'xopc setup # Lighter config + workspace only',\n ]),\n )\n .option('--force', 'Re-initialize even if directories already exist')\n .option('--skip-workspace', 'Skip creating workspace profile files')\n .option('--agent-id <id>', 'Agent id to initialize', 'main')\n .action(async (options) => {\n await initCommand({\n force: options.force,\n skipWorkspace: options.skipWorkspace,\n agentId: options.agentId,\n });\n console.log(`✅ xopc initialized (agent: ${options.agentId})`);\n });\n}\n\nregister({\n id: 'init',\n name: 'init',\n description: 'Initialize xopc state directories, config, and agent workspace',\n factory: createInitCommand,\n metadata: {\n category: 'setup',\n examples: ['xopc init', 'xopc init --agent-id main'],\n },\n});\n"],"mappings":";;;;;;;;;;;;;aAGqD;YAUtB;aACiC;AAIhE,MAAM,MAAM,aAAa,cAAc;;;;;AAevC,eAAsB,YAAY,UAAuB,EAAE,EAAiB;CAC1E,MAAM,WAAW,iBAAiB;CAClC,MAAM,UAAU,QAAQ,WAAW;AAEnC,KAAI,KAAK;EAAE;EAAU;EAAS,EAAE,6BAA6B;AAG7D,KAAI,WAAW,SAAS,IAAI,CAAC,QAAQ;MAE/B,WADe,mBACM,CAAC,CACxB,KAAI,KAAK,uEAAuE;;AAIpF,OAAM,MAAM,UAAU,EAAE,WAAW,MAAM,CAAC;CAE1C,MAAM,aAAa,mBAAmB;CACtC,MAAM,eAAe,WAAW,WAAW;CAC3C,MAAM,UAAU,wBAAwB,WAAW;CACnD,MAAM,gBAAgB,+BAA+B,WAAW,WAAW,CAAC;CAC5E,MAAM,MAAM,cAAc;AAG1B,OAAM,MAAM,oBAAoB,KAAK,QAAQ,EAAE,EAAE,WAAW,MAAM,CAAC;AACnE,OAAM,MAAM,uBAAuB,KAAK,QAAQ,EAAE,EAAE,WAAW,MAAM,CAAC;AACtE,OAAM,MAAM,gBAAgB,KAAK,QAAQ,EAAE,EAAE,WAAW,MAAM,CAAC;AAE/D,OAAM,MADS,yBAAyB,KAAK,QAC3B,EAAE,EAAE,WAAW,MAAM,CAAC;AAGxC,KACE,CAAC,gBACD,QAAQ,SACP,QAAQ,aAAa,cAAc,WAAW,CAAC,QAAQ,kBACxD;AACA,QAAM,WAAW,KAAK,WAAW;AACjC,MAAI,KAAK,EAAE,YAAY,EAAE,sBAAsB;;AAMjD,KAAI,CAAC,QAAQ,cACX,OAAM,qBAAqB,KAAK,QAAQ;AAG1C,KAAI,KAAK;EAAE;EAAU;EAAS,EAAE,yCAAyC;;AAG3E,SAAS,wBAAwB,YAAqE;AACpG,KAAI,CAAC,WAAW,WAAW,CACzB,QAAO;EAAE,UAAU;EAAM,iBAAiB;EAAO;AAEnD,KAAI;AAIF,SAAO;GACL,UAAU;GACV,iBAAiB,OALJ,KAAK,MAAM,aAAa,YAAY,QAAQ,CAK3B,CAAC,KAAK,iBAAiB;GACtD;SACK;AACN,SAAO;GAAE,UAAU;GAAO,iBAAiB;GAAO;;;;;;AAOtD,eAAe,qBAAqB,KAAa,SAAgC;CAC/E,MAAM,eAAe,yBAAyB,KAAK,QAAQ;CAC3D,MAAM,aAAa,uBAAuB,KAAK,QAAQ;AACvD,OAAM,MAAM,cAAc,EAAE,WAAW,MAAM,CAAC;AAC9C,OAAM,MAAM,YAAY,EAAE,WAAW,MAAM,CAAC;CAG5C,MAAM,WAAW,KAAK,YAAY,gBAAgB,KAAK;AACvD,KAAI,CAAC,WAAW,SAAS,EAAE;AA2BzB,QAAM,UAAU,UAAU;;;;SAtBrB,QAAQ;;;;;;;;;;;;;;;;;;;;;GAsB0B,QAAQ;AAC/C,MAAI,KAAK,EAAE,MAAM,UAAU,EAAE,kBAAkB;;CAIjD,MAAM,eAAe,KAAK,YAAY,gBAAgB,SAAS;AAC/D,KAAI,CAAC,WAAW,aAAa,EAAE;AAoB7B,QAAM,UAAU,cAAc;;cAjBpB,QAAQ;;;;;;;;;;;;;;;;GAiB6B,QAAQ;AACvD,MAAI,KAAK,EAAE,MAAM,cAAc,EAAE,sBAAsB;;CAIzD,MAAM,WAAW,wBAAwB;AACzC,KAAI,CAAC,WAAW,SAAS,EAAE;AACzB,QAAM,MAAM,QAAQ,SAAS,EAAE,EAAE,WAAW,MAAM,CAAC;AAenD,QAAM,UAAU,UAAU;;;;;;;;;;;;;GAAa,QAAQ;AAC/C,MAAI,KAAK,EAAE,MAAM,UAAU,EAAE,iCAAiC;;CAIhE,MAAM,aAAa,KAAK,YAAY,gBAAgB,OAAO;AAC3D,KAAI,CAAC,WAAW,WAAW,EAAE;AAqC3B,QAAM,UAAU,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAAe,QAAQ;AACnD,MAAI,KAAK,EAAE,MAAM,YAAY,EAAE,oBAAoB;;CAIrD,MAAM,YAAY,KAAK,YAAY,gBAAgB,MAAM;AACzD,KAAI,CAAC,WAAW,UAAU,EAAE;AAgB1B,QAAM,UAAU,WAAW;;;;;;;;;;;;;;GAAc,QAAQ;AACjD,MAAI,KAAK,EAAE,MAAM,WAAW,EAAE,mBAAmB;;CAInD,MAAM,gBAAgB,KAAK,YAAY,gBAAgB,UAAU;AACjE,KAAI,CAAC,WAAW,cAAc,EAAE;AAO9B,QAAM,UAAU,eAAe;;;;;GAAkB,QAAQ;AACzD,MAAI,KAAK,EAAE,MAAM,eAAe,EAAE,uBAAuB;;CAI3D,MAAM,aAAa,KAAK,YAAY,gBAAgB,OAAO;AAC3D,KAAI,CAAC,WAAW,WAAW,EAAE;AAmB3B,QAAM,UAAU,YAAY;;;;;;;;;;;;;;;;;GAAe,QAAQ;AACnD,MAAI,KAAK,EAAE,MAAM,YAAY,EAAE,oBAAoB;;;AASvD,SAAS,kBAAkB,MAA2B;AACpD,QAAO,IAAI,QAAQ,OAAO,CACvB,YAAY,iEAAiE,CAC7E,YACC,SACA,eAAe;EACb;EACA;EACA;EACA;EACD,CAAC,CACH,CACA,OAAO,WAAW,kDAAkD,CACpE,OAAO,oBAAoB,wCAAwC,CACnE,OAAO,mBAAmB,0BAA0B,OAAO,CAC3D,OAAO,OAAO,YAAY;AACzB,QAAM,YAAY;GAChB,OAAO,QAAQ;GACf,eAAe,QAAQ;GACvB,SAAS,QAAQ;GAClB,CAAC;AACF,UAAQ,IAAI,8BAA8B,QAAQ,QAAQ,GAAG;GAC7D;;AAGN,SAAS;CACP,IAAI;CACJ,MAAM;CACN,aAAa;CACb,SAAS;CACT,UAAU;EACR,UAAU;EACV,UAAU,CAAC,aAAa,4BAA4B;EACrD;CACF,CAAC"}
|
|
@@ -1,15 +1,34 @@
|
|
|
1
|
+
import { init_loader, loadConfig, saveConfig } from "../../config/loader.js";
|
|
2
|
+
import { setTuiDefaultAgentConfig } from "../../commands/agents.config.js";
|
|
1
3
|
import { formatExamples, register } from "../registry.js";
|
|
4
|
+
import { detectMigrations, runBootstrapMigrationsSync } from "../../migrations/runner.js";
|
|
2
5
|
import { Command } from "commander";
|
|
3
6
|
//#region src/cli/commands/tui.ts
|
|
4
|
-
|
|
7
|
+
init_loader();
|
|
8
|
+
function createTuiCommand(ctx) {
|
|
5
9
|
return new Command("tui").description("Interactive terminal UI (pi-tui)").addHelpText("after", formatExamples([
|
|
6
10
|
"xopc # Open embedded TUI (default command)",
|
|
7
11
|
"xopc tui # Embedded mode (default)",
|
|
8
12
|
"xopc tui --gateway # Force gateway mode",
|
|
9
13
|
"xopc tui --url http://host:3120 --token xxx # Connect to remote gateway",
|
|
10
14
|
"xopc tui -s agent:main:tui-... # Resume a session",
|
|
15
|
+
"xopc tui --agent coder # Start with a specific agent",
|
|
16
|
+
"xopc tui --set-default-agent coder # Persist default agent for new TUI sessions",
|
|
11
17
|
"xopc tui -m \"Summarize my inbox\" # Send a message on launch"
|
|
12
|
-
])).option("--url <url>", "Gateway URL (default: http://localhost:3120)").option("--token <token>", "Gateway bearer token").option("-s, --session <key>", "Session key to resume (omitted: start a fresh TUI session)").option("-m, --message <text>", "Send a message on launch").option("--workdir <dir>", "Workspace directory for the new TUI session").option("--no-cwd", "Do not use the launch directory as the new TUI session workspace").option("--local", "Run in embedded mode (no gateway required)").option("--gateway", "Force gateway mode even without explicit --url or --token").option("--theme <name>", "Theme: auto, dark, light, or custom name from ~/.xopc/themes/").option("--thinking <level>", "Thinking level override").action(async (options) => {
|
|
18
|
+
])).option("--url <url>", "Gateway URL (default: http://localhost:3120)").option("--token <token>", "Gateway bearer token").option("-s, --session <key>", "Session key to resume (omitted: start a fresh TUI session)").option("--agent <id>", "Agent id for a fresh TUI session").option("--set-default-agent <id>", "Persist default agent for new TUI sessions and exit").option("-m, --message <text>", "Send a message on launch").option("--workdir <dir>", "Workspace directory for the new TUI session").option("--no-cwd", "Do not use the launch directory as the new TUI session workspace").option("--local", "Run in embedded mode (no gateway required)").option("--gateway", "Force gateway mode even without explicit --url or --token").option("--theme <name>", "Theme: auto, dark, light, or custom name from ~/.xopc/themes/").option("--thinking <level>", "Thinking level override").action(async (options) => {
|
|
19
|
+
runBootstrapMigrationsSync(ctx.configPath);
|
|
20
|
+
const pendingMigrations = detectMigrations(ctx.configPath);
|
|
21
|
+
if (pendingMigrations.length > 0) console.warn(`xopc has ${pendingMigrations.length} pending migration(s). Run \`xopc doctor --fix\` or open Settings → App management.`);
|
|
22
|
+
if (typeof options.setDefaultAgent === "string") {
|
|
23
|
+
const result = setTuiDefaultAgentConfig(loadConfig(ctx.configPath), options.setDefaultAgent);
|
|
24
|
+
if (result.ok === false) {
|
|
25
|
+
console.error(`Error: ${result.message}`);
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
await saveConfig(result.config, ctx.configPath);
|
|
29
|
+
console.log(`TUI default agent set to "${result.agentId}".`);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
13
32
|
const { runTui } = await import("../../tui/tui.js");
|
|
14
33
|
const useLocal = options.local === true;
|
|
15
34
|
const useGateway = options.gateway === true || typeof options.url === "string" || typeof options.token === "string";
|
|
@@ -19,6 +38,7 @@ function createTuiCommand(_ctx) {
|
|
|
19
38
|
url: typeof options.url === "string" ? options.url : void 0,
|
|
20
39
|
token: typeof options.token === "string" ? options.token : void 0,
|
|
21
40
|
session: typeof options.session === "string" ? options.session : void 0,
|
|
41
|
+
agentId: typeof options.agent === "string" ? options.agent : void 0,
|
|
22
42
|
message: typeof options.message === "string" ? options.message : void 0,
|
|
23
43
|
workdir: typeof options.workdir === "string" ? options.workdir : void 0,
|
|
24
44
|
useStartupCwd: options.cwd !== false,
|
|
@@ -38,6 +58,8 @@ register({
|
|
|
38
58
|
examples: [
|
|
39
59
|
"xopc",
|
|
40
60
|
"xopc tui",
|
|
61
|
+
"xopc tui --agent coder",
|
|
62
|
+
"xopc tui --set-default-agent coder",
|
|
41
63
|
"xopc tui --gateway",
|
|
42
64
|
"xopc tui --url http://host:3120"
|
|
43
65
|
]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tui.js","names":[],"sources":["../../../../src/cli/commands/tui.ts"],"sourcesContent":["import { Command } from 'commander';\n\nimport { register, formatExamples, type CLIContext } from '../registry.js';\n\nfunction createTuiCommand(
|
|
1
|
+
{"version":3,"file":"tui.js","names":[],"sources":["../../../../src/cli/commands/tui.ts"],"sourcesContent":["import { Command } from 'commander';\n\nimport { setTuiDefaultAgentConfig } from '../../commands/agents.config.js';\nimport { loadConfig, saveConfig } from '../../config/loader.js';\nimport { detectMigrations, runBootstrapMigrationsSync } from '../../migrations/runner.js';\nimport { register, formatExamples, type CLIContext } from '../registry.js';\n\nfunction createTuiCommand(ctx: CLIContext): Command {\n const cmd = new Command('tui')\n .description('Interactive terminal UI (pi-tui)')\n .addHelpText(\n 'after',\n formatExamples([\n 'xopc # Open embedded TUI (default command)',\n 'xopc tui # Embedded mode (default)',\n 'xopc tui --gateway # Force gateway mode',\n 'xopc tui --url http://host:3120 --token xxx # Connect to remote gateway',\n 'xopc tui -s agent:main:tui-... # Resume a session',\n 'xopc tui --agent coder # Start with a specific agent',\n 'xopc tui --set-default-agent coder # Persist default agent for new TUI sessions',\n 'xopc tui -m \"Summarize my inbox\" # Send a message on launch',\n ]),\n )\n .option('--url <url>', 'Gateway URL (default: http://localhost:3120)')\n .option('--token <token>', 'Gateway bearer token')\n .option('-s, --session <key>', 'Session key to resume (omitted: start a fresh TUI session)')\n .option('--agent <id>', 'Agent id for a fresh TUI session')\n .option('--set-default-agent <id>', 'Persist default agent for new TUI sessions and exit')\n .option('-m, --message <text>', 'Send a message on launch')\n .option('--workdir <dir>', 'Workspace directory for the new TUI session')\n .option('--no-cwd', 'Do not use the launch directory as the new TUI session workspace')\n .option('--local', 'Run in embedded mode (no gateway required)')\n .option('--gateway', 'Force gateway mode even without explicit --url or --token')\n .option('--theme <name>', 'Theme: auto, dark, light, or custom name from ~/.xopc/themes/')\n .option('--thinking <level>', 'Thinking level override')\n .action(async (options: Record<string, string | boolean | undefined>) => {\n runBootstrapMigrationsSync(ctx.configPath);\n const pendingMigrations = detectMigrations(ctx.configPath);\n if (pendingMigrations.length > 0) {\n console.warn(\n `xopc has ${pendingMigrations.length} pending migration(s). Run \\`xopc doctor --fix\\` or open Settings → App management.`,\n );\n }\n if (typeof options.setDefaultAgent === 'string') {\n const cfg = loadConfig(ctx.configPath);\n const result = setTuiDefaultAgentConfig(cfg, options.setDefaultAgent);\n if (result.ok === false) {\n console.error(`Error: ${result.message}`);\n process.exit(1);\n }\n await saveConfig(result.config, ctx.configPath);\n console.log(`TUI default agent set to \"${result.agentId}\".`);\n return;\n }\n const { runTui } = await import('../../tui/tui.js');\n const useLocal = options.local === true;\n const useGateway =\n options.gateway === true ||\n typeof options.url === 'string' ||\n typeof options.token === 'string';\n if (useLocal && useGateway) {\n console.log('`--local` and gateway flags both set. Using local mode.');\n }\n const localMode = useLocal || !useGateway;\n await runTui({\n url: typeof options.url === 'string' ? options.url : undefined,\n token: typeof options.token === 'string' ? options.token : undefined,\n session: typeof options.session === 'string' ? options.session : undefined,\n agentId: typeof options.agent === 'string' ? options.agent : undefined,\n message: typeof options.message === 'string' ? options.message : undefined,\n workdir: typeof options.workdir === 'string' ? options.workdir : undefined,\n useStartupCwd: options.cwd !== false,\n local: localMode,\n thinking: typeof options.thinking === 'string' ? options.thinking : undefined,\n theme: typeof options.theme === 'string' ? options.theme : undefined,\n });\n });\n\n return cmd;\n}\n\nregister({\n id: 'tui',\n name: 'tui',\n description: 'Interactive terminal UI (pi-tui)',\n factory: createTuiCommand,\n metadata: {\n category: 'runtime',\n examples: [\n 'xopc',\n 'xopc tui',\n 'xopc tui --agent coder',\n 'xopc tui --set-default-agent coder',\n 'xopc tui --gateway',\n 'xopc tui --url http://host:3120',\n ],\n },\n});\n"],"mappings":";;;;;;aAGgE;AAIhE,SAAS,iBAAiB,KAA0B;AAuElD,QAtEY,IAAI,QAAQ,MAAM,CAC3B,YAAY,mCAAmC,CAC/C,YACC,SACA,eAAe;EACb;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC,CACH,CACA,OAAO,eAAe,+CAA+C,CACrE,OAAO,mBAAmB,uBAAuB,CACjD,OAAO,uBAAuB,6DAA6D,CAC3F,OAAO,gBAAgB,mCAAmC,CAC1D,OAAO,4BAA4B,sDAAsD,CACzF,OAAO,wBAAwB,2BAA2B,CAC1D,OAAO,mBAAmB,8CAA8C,CACxE,OAAO,YAAY,mEAAmE,CACtF,OAAO,WAAW,6CAA6C,CAC/D,OAAO,aAAa,4DAA4D,CAChF,OAAO,kBAAkB,gEAAgE,CACzF,OAAO,sBAAsB,0BAA0B,CACvD,OAAO,OAAO,YAA0D;AACvE,6BAA2B,IAAI,WAAW;EAC1C,MAAM,oBAAoB,iBAAiB,IAAI,WAAW;AAC1D,MAAI,kBAAkB,SAAS,EAC7B,SAAQ,KACN,YAAY,kBAAkB,OAAO,qFACtC;AAEH,MAAI,OAAO,QAAQ,oBAAoB,UAAU;GAE/C,MAAM,SAAS,yBADH,WAAW,IAAI,WACgB,EAAE,QAAQ,gBAAgB;AACrE,OAAI,OAAO,OAAO,OAAO;AACvB,YAAQ,MAAM,UAAU,OAAO,UAAU;AACzC,YAAQ,KAAK,EAAE;;AAEjB,SAAM,WAAW,OAAO,QAAQ,IAAI,WAAW;AAC/C,WAAQ,IAAI,6BAA6B,OAAO,QAAQ,IAAI;AAC5D;;EAEF,MAAM,EAAE,WAAW,MAAM,OAAO;EAChC,MAAM,WAAW,QAAQ,UAAU;EACnC,MAAM,aACJ,QAAQ,YAAY,QACpB,OAAO,QAAQ,QAAQ,YACvB,OAAO,QAAQ,UAAU;AAC3B,MAAI,YAAY,WACd,SAAQ,IAAI,0DAA0D;EAExE,MAAM,YAAY,YAAY,CAAC;AAC/B,QAAM,OAAO;GACX,KAAK,OAAO,QAAQ,QAAQ,WAAW,QAAQ,MAAM,KAAA;GACrD,OAAO,OAAO,QAAQ,UAAU,WAAW,QAAQ,QAAQ,KAAA;GAC3D,SAAS,OAAO,QAAQ,YAAY,WAAW,QAAQ,UAAU,KAAA;GACjE,SAAS,OAAO,QAAQ,UAAU,WAAW,QAAQ,QAAQ,KAAA;GAC7D,SAAS,OAAO,QAAQ,YAAY,WAAW,QAAQ,UAAU,KAAA;GACjE,SAAS,OAAO,QAAQ,YAAY,WAAW,QAAQ,UAAU,KAAA;GACjE,eAAe,QAAQ,QAAQ;GAC/B,OAAO;GACP,UAAU,OAAO,QAAQ,aAAa,WAAW,QAAQ,WAAW,KAAA;GACpE,OAAO,OAAO,QAAQ,UAAU,WAAW,QAAQ,QAAQ,KAAA;GAC5D,CAAC;GAGI;;AAGZ,SAAS;CACP,IAAI;CACJ,MAAM;CACN,aAAa;CACb,SAAS;CACT,UAAU;EACR,UAAU;EACV,UAAU;GACR;GACA;GACA;GACA;GACA;GACA;GACD;EACF;CACF,CAAC"}
|
|
@@ -82,8 +82,9 @@ Do not manually reread startup files unless the user asks or the provided contex
|
|
|
82
82
|
|
|
83
83
|
## Memory
|
|
84
84
|
|
|
85
|
-
-
|
|
86
|
-
-
|
|
85
|
+
- Use runtime memory tools for recall.
|
|
86
|
+
- Use curated memory for durable facts and preferences when available.
|
|
87
|
+
- Cite only memory sources that a tool actually returns.
|
|
87
88
|
|
|
88
89
|
Write what matters. Text > Brain.
|
|
89
90
|
`,
|