@xopcai/xopc 0.0.120 → 0.0.122
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 +23 -3
- package/README.zh-CN.md +23 -3
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/dashscope/src/image-generation-provider.d.ts +6 -5
- package/dist/extensions/dashscope/src/image-generation-provider.js +40 -64
- package/dist/extensions/dashscope/src/image-generation-provider.js.map +1 -1
- package/dist/extensions/dashscope/src/index.d.ts +1 -1
- package/dist/extensions/dashscope/src/index.js +2 -2
- package/dist/extensions/dashscope/xopc.extension.json +3 -2
- package/dist/extensions/minimax/src/image-generation-provider.d.ts +7 -5
- package/dist/extensions/minimax/src/image-generation-provider.js +43 -37
- package/dist/extensions/minimax/src/image-generation-provider.js.map +1 -1
- package/dist/extensions/minimax/src/index.d.ts +1 -1
- package/dist/extensions/minimax/src/index.js +2 -2
- package/dist/extensions/minimax/xopc.extension.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/Combination-HAlzriaz.js +41 -0
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-APTlX9Sq.js → agent-avatar-dicebear-CK3s5cJo.js} +1 -1
- package/dist/gateway/static/root/assets/agents-SsQrj9B-.js +2 -0
- package/dist/gateway/static/root/assets/{app-management-settings-panel-DTKc5HHT.js → app-management-settings-panel-CWsNHtTs.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-BTciFrE9.js → appearance-settings-C4b8y6iZ.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-CYb6fame.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-CiHaUMII.js → archive-plugin-DAtNW3Ia.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-t4gSrNjL.js → attachment-load-Dm-RY54y.js} +1 -1
- package/dist/gateway/static/root/assets/automation-suggestion-card-BKHewSVT.js +1 -0
- package/dist/gateway/static/root/assets/automations-page-DpOOq1nk.js +1 -0
- package/dist/gateway/static/root/assets/{binary-plugins-BAbSldW5.js → binary-plugins-BG6Xnk71.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-BNr_82xl.js → block-editor-DfndiO3h.js} +28 -28
- package/dist/gateway/static/root/assets/browser-settings-page-9nXxgh4u.js +8 -0
- package/dist/gateway/static/root/assets/{capability-presets-api-tzD702Gg.js → capability-presets-api-Cx93GLdw.js} +1 -1
- package/dist/gateway/static/root/assets/{capability-presets-settings-panel-AGhTueAc.js → capability-presets-settings-panel-D528_YFy.js} +1 -1
- package/dist/gateway/static/root/assets/{channel-recipient-api-DL_KzwGE.js → channel-recipient-api-DdPTtEs8.js} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-Ck-3h5lI.js +1 -0
- package/dist/gateway/static/root/assets/connectors-page-DL-fAqE_.js +2 -0
- package/dist/gateway/static/root/assets/directory-picker-path-field-D835EHJd.js +1 -0
- package/dist/gateway/static/root/assets/dist-Mys7eFJ5.js +1 -0
- package/dist/gateway/static/root/assets/dist-wO9a2_ID.js +1 -0
- package/dist/gateway/static/root/assets/dreaming-settings-CCa1F7Fg.js +1 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-Dl2kO0Sf.js → extension-debug-page-W2ITCPSA.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-DmbLPsx_.js → extension-page-DrvUytvn.js} +1 -1
- package/dist/gateway/static/root/assets/extension-settings-page-qM8aLT5u.js +1 -0
- package/dist/gateway/static/root/assets/{fetch-B3ME5Eri.js → fetch-ovkvM8KQ.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-DI9_BBTo.js → gateway-config-api-BB3biuD0.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-settings-mmmnIH27.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-CSZQTz6K.js → gateway-startup-retry-CanQ8UcR.js} +1 -1
- package/dist/gateway/static/root/assets/goal-create-dialog-CNqNdEkQ.js +1 -0
- package/dist/gateway/static/root/assets/goal-detail-page-Ceu5zrN6.js +1 -0
- package/dist/gateway/static/root/assets/{goals-config-api-Bhzqrp2w.js → goals-config-api-BBOX6mUl.js} +1 -1
- package/dist/gateway/static/root/assets/goals-page-BP1kfvWv.js +2 -0
- package/dist/gateway/static/root/assets/goals-settings-Bh3A7OZV.js +1 -0
- package/dist/gateway/static/root/assets/heartbeat-settings-YoYgKlfX.js +1 -0
- package/dist/gateway/static/root/assets/index-DdqSO9R2.js +191 -0
- package/dist/gateway/static/root/assets/index-jGB-2nI-.css +1 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-kMp08SlX.js → keyboard-shortcuts-settings-B4TKJHla.js} +1 -1
- package/dist/gateway/static/root/assets/logs-page-BgVk5DvZ.js +2 -0
- package/dist/gateway/static/root/assets/{markdown-split-Bc0w40vz.js → markdown-split-DcFtdLci.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-DJ_HvgIy.js → media-plugins-B6SmeLVB.js} +1 -1
- package/dist/gateway/static/root/assets/messages-B5O4OIEo.js +3 -0
- package/dist/gateway/static/root/assets/models-hub-panel-BU0x8PGP.js +2 -0
- package/dist/gateway/static/root/assets/notes-page-D6JYVP4I.js +1 -0
- package/dist/gateway/static/root/assets/notes-workbench-mqRJYnJS.js +2 -0
- package/dist/gateway/static/root/assets/{preview-open-alternatives-BbA7sRd_.js → preview-open-alternatives-C29O19s7.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-DOTgzoeh.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-DGUIb4y5.js +1 -0
- package/dist/gateway/static/root/assets/remote-access-hub-DVKKUj3u.js +1 -0
- package/dist/gateway/static/root/assets/{save-bar-controls-Dividh61.js → save-bar-controls-B4ad9GfB.js} +1 -1
- package/dist/gateway/static/root/assets/schedule-field-DdYncfLR.js +1 -0
- package/dist/gateway/static/root/assets/schema-form-BMTrDE-7.js +1 -0
- package/dist/gateway/static/root/assets/segmented-styles-BL8oLBEp.js +1 -0
- package/dist/gateway/static/root/assets/sessions-page-BVbzUWxW.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-DrNNoSqE.js +1 -0
- package/dist/gateway/static/root/assets/{settings-collapsible-section-BMCOfuE_.js → settings-collapsible-section-MwTW2eK4.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-form-section-DBkGwpIN.js → settings-form-section-Dg6LBbcr.js} +1 -1
- package/dist/gateway/static/root/assets/settings-page-CMDqgeMR.js +1 -0
- package/dist/gateway/static/root/assets/settings-page-layout-BX4T-OLF.js +1 -0
- package/dist/gateway/static/root/assets/setup-status-panel-Ce1pcFtR.js +1 -0
- package/dist/gateway/static/root/assets/share-preview-page-DWE-dUFh.js +2 -0
- package/dist/gateway/static/root/assets/shares-settings-aKSraR8l.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-CS-FU_B-.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-BaF3u0LA.js +2 -0
- package/dist/gateway/static/root/assets/{system-settings-panel-CrmEnyX4.js → system-settings-panel-Dd6Y35Cm.js} +1 -1
- package/dist/gateway/static/root/assets/{typed-models-lib-BAsGn25g.js → typed-models-lib-Cx6XV5A2.js} +1 -1
- package/dist/gateway/static/root/assets/{use-channel-catalog-C7vcAoGb.js → use-channel-catalog-D4sMbmy7.js} +1 -1
- package/dist/gateway/static/root/assets/user-profile-settings-panel-Bx-hjMQc.js +1 -0
- package/dist/gateway/static/root/assets/{utils-Dl9efgnV.js → utils-D7b_vZnv.js} +1 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-CkhbRt1q.js +1 -0
- package/dist/gateway/static/root/assets/workflow-run-setup-panel--TdohF5N.js +3 -0
- package/dist/gateway/static/root/assets/workflow-start-dialog-B0lavx_o.js +1 -0
- package/dist/gateway/static/root/assets/workflows-page-CZR05Bu_.js +18 -0
- package/dist/gateway/static/root/index.html +7 -8
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.d.ts +2 -0
- package/dist/src/agent/agent-manager.js +47 -7
- package/dist/src/agent/agent-manager.js.map +1 -1
- package/dist/src/agent/context/project-context.d.ts +19 -0
- package/dist/src/agent/context/project-context.js +90 -0
- package/dist/src/agent/context/project-context.js.map +1 -0
- package/dist/src/agent/embedded/xopc-auth-storage.d.ts +1 -5
- package/dist/src/agent/embedded/xopc-auth-storage.js +2 -8
- package/dist/src/agent/embedded/xopc-auth-storage.js.map +1 -1
- package/dist/src/agent/embedded/xopc-tools-bridge.js +23 -0
- package/dist/src/agent/embedded/xopc-tools-bridge.js.map +1 -1
- package/dist/src/agent/goals/checklist-judge.js +1 -1
- package/dist/src/agent/goals/checklist-judge.js.map +1 -1
- package/dist/src/agent/goals/goal-locale.js +2 -2
- package/dist/src/agent/goals/judge.js +1 -1
- package/dist/src/agent/goals/judge.js.map +1 -1
- package/dist/src/agent/image/tool-model-config.d.ts +2 -0
- package/dist/src/agent/image/tool-model-config.js +2 -2
- package/dist/src/agent/image/tool-model-config.js.map +1 -1
- package/dist/src/agent/image/understanding/pi-ai-provider.js +1 -1
- package/dist/src/agent/image/understanding/pi-ai-provider.js.map +1 -1
- package/dist/src/agent/memory/compaction.d.ts +1 -1
- package/dist/src/agent/memory/compaction.js +1 -1
- package/dist/src/agent/memory/compaction.js.map +1 -1
- package/dist/src/agent/memory/types.d.ts +1 -0
- package/dist/src/agent/middleware/self-verify.d.ts +3 -0
- package/dist/src/agent/middleware/self-verify.js +18 -0
- package/dist/src/agent/middleware/self-verify.js.map +1 -1
- package/dist/src/agent/orchestration/agent-event-handler.js +28 -3
- package/dist/src/agent/orchestration/agent-event-handler.js.map +1 -1
- package/dist/src/agent/prompt/sections/tooling.js +21 -5
- package/dist/src/agent/prompt/sections/tooling.js.map +1 -1
- package/dist/src/agent/prompt/service-prompt-builder.d.ts +1 -0
- package/dist/src/agent/prompt/service-prompt-builder.js +3 -0
- package/dist/src/agent/prompt/service-prompt-builder.js.map +1 -1
- package/dist/src/agent/prompt/system-prompt-params.d.ts +2 -0
- package/dist/src/agent/prompt/system-prompt-params.js +1 -0
- package/dist/src/agent/prompt/system-prompt-params.js.map +1 -1
- package/dist/src/agent/prompt/system-prompt.d.ts +2 -0
- package/dist/src/agent/prompt/system-prompt.js +14 -1
- package/dist/src/agent/prompt/system-prompt.js.map +1 -1
- package/dist/src/agent/sandbox/path-policy.js +30 -6
- package/dist/src/agent/sandbox/path-policy.js.map +1 -1
- package/dist/src/agent/service/btw-query.js +1 -1
- package/dist/src/agent/service/btw-query.js.map +1 -1
- package/dist/src/agent/service.js +4 -3
- package/dist/src/agent/service.js.map +1 -1
- package/dist/src/agent/session/session-config-service.js +6 -1
- package/dist/src/agent/session/session-config-service.js.map +1 -1
- package/dist/src/agent/session/session-hydrator.js +7 -3
- package/dist/src/agent/session/session-hydrator.js.map +1 -1
- package/dist/src/agent/session/session-inspector.js +9 -5
- package/dist/src/agent/session/session-inspector.js.map +1 -1
- package/dist/src/agent/starter-agents.js +18 -47
- package/dist/src/agent/starter-agents.js.map +1 -1
- package/dist/src/agent/tools/image-generate-tool.js +12 -1
- package/dist/src/agent/tools/image-generate-tool.js.map +1 -1
- package/dist/src/agent/tools/session-search-tool.js +1 -1
- package/dist/src/agent/tools/session-search-tool.js.map +1 -1
- package/dist/src/agent/tools/web-extract.js +1 -1
- package/dist/src/agent/tools/web-extract.js.map +1 -1
- package/dist/src/agent/workflow/index.js +2 -2
- package/dist/src/agent/workflow/runtime.js +1 -1
- package/dist/src/agent-manifest/index.js +2 -2
- package/dist/src/agent-manifest/schema.d.ts +66 -0
- package/dist/src/agent-manifest/schema.js +28 -2
- package/dist/src/agent-manifest/schema.js.map +1 -1
- package/dist/src/automations/api/routes.js +13 -2
- package/dist/src/automations/api/routes.js.map +1 -1
- package/dist/src/automations/domain/types.d.ts +2 -0
- package/dist/src/automations/domain/validation.d.ts +3 -0
- package/dist/src/automations/domain/validation.js +1 -0
- package/dist/src/automations/domain/validation.js.map +1 -1
- package/dist/src/automations/draft/automation-draft-service.js +1 -1
- package/dist/src/automations/draft/automation-draft-service.js.map +1 -1
- package/dist/src/automations/draft/automation-draft-validator.d.ts +1 -0
- package/dist/src/automations/service/action-executor.js +3 -1
- package/dist/src/automations/service/action-executor.js.map +1 -1
- package/dist/src/automations/service/automation-service.d.ts +4 -1
- package/dist/src/automations/service/automation-service.js +2 -2
- package/dist/src/automations/service/automation-service.js.map +1 -1
- package/dist/src/automations/storage/automation-repository.d.ts +3 -1
- package/dist/src/automations/storage/automation-repository.js +7 -5
- package/dist/src/automations/storage/automation-repository.js.map +1 -1
- package/dist/src/automations/storage/automation-run-repository.d.ts +1 -0
- package/dist/src/automations/storage/automation-run-repository.js +12 -1
- package/dist/src/automations/storage/automation-run-repository.js.map +1 -1
- package/dist/src/chat-commands/context.js +2 -1
- package/dist/src/chat-commands/context.js.map +1 -1
- package/dist/src/cli/command-loaders.js +1 -0
- package/dist/src/cli/command-loaders.js.map +1 -1
- package/dist/src/cli/command-manifest.js +4 -0
- package/dist/src/cli/command-manifest.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/goal.js +27 -4
- package/dist/src/cli/commands/goal.js.map +1 -1
- package/dist/src/cli/commands/onboard/model.js +161 -11
- package/dist/src/cli/commands/onboard/model.js.map +1 -1
- package/dist/src/cli/commands/project.d.ts +4 -0
- package/dist/src/cli/commands/project.js +239 -0
- package/dist/src/cli/commands/project.js.map +1 -0
- package/dist/src/config/default-model.d.ts +11 -0
- package/dist/src/config/default-model.js +19 -0
- package/dist/src/config/default-model.js.map +1 -0
- package/dist/src/config/index.js +2 -2
- package/dist/src/config/schema.d.ts +71 -11
- package/dist/src/config/schema.js +57 -22
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/connectors/registries/smithery.js +10 -9
- package/dist/src/connectors/registries/smithery.js.map +1 -1
- package/dist/src/daemon/install-plan.js +2 -1
- package/dist/src/daemon/install-plan.js.map +1 -1
- package/dist/src/gateway/global-defaults-admin.js +6 -16
- package/dist/src/gateway/global-defaults-admin.js.map +1 -1
- package/dist/src/gateway/hono/lib/config-payload.d.ts +24 -0
- package/dist/src/gateway/hono/routes/agents.js +1 -79
- package/dist/src/gateway/hono/routes/agents.js.map +1 -1
- package/dist/src/gateway/hono/routes/goals.js +51 -4
- package/dist/src/gateway/hono/routes/goals.js.map +1 -1
- package/dist/src/gateway/hono/routes/index.js +2 -0
- package/dist/src/gateway/hono/routes/index.js.map +1 -1
- package/dist/src/gateway/hono/routes/memory.js +5 -1
- package/dist/src/gateway/hono/routes/memory.js.map +1 -1
- package/dist/src/gateway/hono/routes/models.js +132 -14
- package/dist/src/gateway/hono/routes/models.js.map +1 -1
- package/dist/src/gateway/hono/routes/notes.js +5 -0
- package/dist/src/gateway/hono/routes/notes.js.map +1 -1
- package/dist/src/gateway/hono/routes/projects.d.ts +3 -0
- package/dist/src/gateway/hono/routes/projects.js +578 -0
- package/dist/src/gateway/hono/routes/projects.js.map +1 -0
- package/dist/src/gateway/hono/routes/sessions.js +47 -7
- package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
- package/dist/src/gateway/hono/routes/voice.js +1 -1
- package/dist/src/gateway/hono/routes/voice.js.map +1 -1
- package/dist/src/gateway/hono/routes/workflows.js +27 -4
- package/dist/src/gateway/hono/routes/workflows.js.map +1 -1
- package/dist/src/gateway/image-capabilities.d.ts +11 -1
- package/dist/src/gateway/image-capabilities.js +32 -43
- package/dist/src/gateway/image-capabilities.js.map +1 -1
- package/dist/src/gateway/service.d.ts +3 -0
- package/dist/src/gateway/service.js +10 -3
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/gateway/workspace-editor-path.js +9 -1
- package/dist/src/gateway/workspace-editor-path.js.map +1 -1
- package/dist/src/generated/bundled-image-generation-providers.d.ts +4 -2
- package/dist/src/generated/bundled-image-generation-providers.js +6 -4
- package/dist/src/generated/bundled-image-generation-providers.js.map +1 -1
- package/dist/src/goals/goal-service.d.ts +1 -1
- package/dist/src/goals/goal-service.js +2 -1
- package/dist/src/goals/goal-service.js.map +1 -1
- package/dist/src/goals/goal-store.d.ts +1 -1
- package/dist/src/goals/goal-store.js +12 -6
- package/dist/src/goals/goal-store.js.map +1 -1
- package/dist/src/goals/goal-workflow-judge.js +1 -1
- package/dist/src/goals/types.d.ts +3 -0
- package/dist/src/i18n/goals-bundle.js +1 -1
- package/dist/src/i18n/index.js +1 -1
- package/dist/src/i18n/share-tool-bundle.js +2 -2
- package/dist/src/media/paths.js +3 -4
- package/dist/src/media/paths.js.map +1 -1
- package/dist/src/notes/agent-context.js +2 -2
- package/dist/src/notes/service.js +1 -1
- package/dist/src/notes/service.js.map +1 -1
- package/dist/src/projects/automation-bind.d.ts +1 -0
- package/dist/src/projects/automation-bind.js +16 -0
- package/dist/src/projects/automation-bind.js.map +1 -0
- package/dist/src/projects/goal-bind.d.ts +4 -0
- package/dist/src/projects/goal-bind.js +40 -0
- package/dist/src/projects/goal-bind.js.map +1 -0
- package/dist/src/projects/index.d.ts +11 -0
- package/dist/src/projects/index.js +11 -0
- package/dist/src/projects/memory-bind.d.ts +1 -0
- package/dist/src/projects/memory-bind.js +16 -0
- package/dist/src/projects/memory-bind.js.map +1 -0
- package/dist/src/projects/project-agent.d.ts +10 -0
- package/dist/src/projects/project-agent.js +27 -0
- package/dist/src/projects/project-agent.js.map +1 -0
- package/dist/src/projects/project-loop.d.ts +58 -0
- package/dist/src/projects/project-loop.js +118 -0
- package/dist/src/projects/project-loop.js.map +1 -0
- package/dist/src/projects/project-service.d.ts +26 -0
- package/dist/src/projects/project-service.js +94 -0
- package/dist/src/projects/project-service.js.map +1 -0
- package/dist/src/projects/project-store.d.ts +31 -0
- package/dist/src/projects/project-store.js +193 -0
- package/dist/src/projects/project-store.js.map +1 -0
- package/dist/src/projects/session-bind.d.ts +5 -0
- package/dist/src/projects/session-bind.js +46 -0
- package/dist/src/projects/session-bind.js.map +1 -0
- package/dist/src/projects/types.d.ts +60 -0
- package/dist/src/projects/types.js +1 -0
- package/dist/src/projects/workflow-bind.d.ts +1 -0
- package/dist/src/projects/workflow-bind.js +16 -0
- package/dist/src/projects/workflow-bind.js.map +1 -0
- package/dist/src/projects/workspace.d.ts +5 -0
- package/dist/src/projects/workspace.js +25 -0
- package/dist/src/projects/workspace.js.map +1 -0
- package/dist/src/providers/domestic-presets.d.ts +615 -0
- package/dist/src/providers/domestic-presets.js +834 -0
- package/dist/src/providers/domestic-presets.js.map +1 -0
- package/dist/src/providers/env-keys.js +29 -5
- package/dist/src/providers/env-keys.js.map +1 -1
- package/dist/src/providers/extension-stream-bridge.js +1 -1
- package/dist/src/providers/extension-stream-bridge.js.map +1 -1
- package/dist/src/providers/index.d.ts +5 -5
- package/dist/src/providers/index.js +101 -21
- package/dist/src/providers/index.js.map +1 -1
- package/dist/src/providers/model-discovery.d.ts +17 -0
- package/dist/src/providers/model-discovery.js +61 -0
- package/dist/src/providers/model-discovery.js.map +1 -0
- package/dist/src/providers/model-registry.d.ts +1 -1
- package/dist/src/providers/model-registry.js +1 -1
- package/dist/src/providers/model-registry.js.map +1 -1
- package/dist/src/providers/presentation.js +185 -14
- package/dist/src/providers/presentation.js.map +1 -1
- package/dist/src/session/index.d.ts +1 -1
- package/dist/src/session/index.js +3 -3
- package/dist/src/session/session-title.js +1 -1
- package/dist/src/session/session-title.js.map +1 -1
- package/dist/src/session/session-workspace.d.ts +4 -2
- package/dist/src/session/session-workspace.js +10 -3
- package/dist/src/session/session-workspace.js.map +1 -1
- package/dist/src/session/types.d.ts +3 -0
- package/dist/src/session/types.js.map +1 -1
- package/dist/src/storage/sqlite/memory-records-repository.d.ts +3 -0
- package/dist/src/storage/sqlite/memory-records-repository.js +16 -5
- package/dist/src/storage/sqlite/memory-records-repository.js.map +1 -1
- package/dist/src/storage/sqlite/migrations/019_projects.sql +40 -0
- package/dist/src/storage/sqlite/migrations/020_project_default_agent.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/notes-repository.js +20 -4
- package/dist/src/storage/sqlite/notes-repository.js.map +1 -1
- package/dist/src/storage/sqlite/row-mappers.d.ts +2 -0
- package/dist/src/storage/sqlite/row-mappers.js +2 -0
- 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/session-repository.js +10 -5
- package/dist/src/storage/sqlite/session-repository.js.map +1 -1
- package/dist/src/storage/sqlite/transcript-repository.js +8 -0
- package/dist/src/storage/sqlite/transcript-repository.js.map +1 -1
- package/dist/src/tui/backends/embedded-backend.js +1 -1
- package/dist/src/tui/tui-commands.js +145 -0
- package/dist/src/tui/tui-commands.js.map +1 -1
- package/dist/src/tui/xopc-tui-keybindings.d.ts +1 -1
- package/dist/src/voice/tts/summarize.js +1 -1
- package/dist/src/voice/tts/summarize.js.map +1 -1
- package/dist/src/workflows/domain/run.d.ts +1 -0
- package/dist/src/workflows/domain/run.js.map +1 -1
- package/dist/src/workflows/draft/workflow-draft-service.js +1 -1
- package/dist/src/workflows/draft/workflow-draft-service.js.map +1 -1
- package/dist/src/workflows/index.js +1 -1
- package/dist/src/workflows/service/workflow-run-service.d.ts +1 -0
- package/dist/src/workflows/service/workflow-run-service.js +18 -4
- package/dist/src/workflows/service/workflow-run-service.js.map +1 -1
- package/dist/src/workflows/service/workflow-run-service.types.d.ts +2 -0
- package/dist/src/workflows/service/workflow-session-bridge.d.ts +1 -0
- package/dist/src/workflows/service/workflow-session-bridge.js +3 -0
- package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -1
- package/dist/src/workflows/store/run-index-store.d.ts +1 -0
- package/dist/src/workflows/store/run-index-store.js +13 -3
- package/dist/src/workflows/store/run-index-store.js.map +1 -1
- package/dist/src/workflows/store/run-store.d.ts +3 -1
- package/dist/src/workflows/store/run-store.js +5 -2
- package/dist/src/workflows/store/run-store.js.map +1 -1
- package/package.json +15 -6
- package/dist/gateway/static/root/assets/Combination-BzaXOLd9.js +0 -41
- package/dist/gateway/static/root/assets/agents-CFW_FS_V.js +0 -2
- package/dist/gateway/static/root/assets/apps-page-DT52OrbM.js +0 -1
- package/dist/gateway/static/root/assets/automation-suggestion-card-CtysjSoQ.js +0 -1
- package/dist/gateway/static/root/assets/automations-page-B2YvT3ES.js +0 -1
- package/dist/gateway/static/root/assets/browser-settings-page-BQEXPhDU.js +0 -8
- package/dist/gateway/static/root/assets/channels-settings-DRTutLlN.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-DneJVuge.js +0 -2
- package/dist/gateway/static/root/assets/dist-By6Rh2ee.js +0 -1
- package/dist/gateway/static/root/assets/dist-CkobR7mk.js +0 -1
- package/dist/gateway/static/root/assets/dist-DokQNVMQ.js +0 -1
- package/dist/gateway/static/root/assets/dreaming-settings-BEwWA1yf.js +0 -1
- package/dist/gateway/static/root/assets/extension-settings-page-BS2rx40e.js +0 -1
- package/dist/gateway/static/root/assets/gateway-settings-DAFI_T0W.js +0 -1
- package/dist/gateway/static/root/assets/goal-detail-page-DLuz4jC9.js +0 -1
- package/dist/gateway/static/root/assets/goals-page-DTAfv9Ft.js +0 -2
- package/dist/gateway/static/root/assets/goals-settings-CWN2iirQ.js +0 -1
- package/dist/gateway/static/root/assets/heartbeat-settings-CkkkHvOi.js +0 -1
- package/dist/gateway/static/root/assets/index-CnjzMw5i.js +0 -191
- package/dist/gateway/static/root/assets/index-E1QinYKp.css +0 -1
- package/dist/gateway/static/root/assets/logs-page-CDXDlS_W.js +0 -2
- package/dist/gateway/static/root/assets/messages-CISb1HLv.js +0 -3
- package/dist/gateway/static/root/assets/models-hub-panel-BTwxMIgZ.js +0 -2
- package/dist/gateway/static/root/assets/note-detail-page-BBfOeB0m.js +0 -2
- package/dist/gateway/static/root/assets/note-image-lightbox-4zntqpZq.js +0 -1
- package/dist/gateway/static/root/assets/note-time-hm6JO_Wi.js +0 -1
- package/dist/gateway/static/root/assets/notes-page-VocWOjoK.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-CXwjuD_Q.js +0 -1
- package/dist/gateway/static/root/assets/schedule-field-pRheF2CO.js +0 -1
- package/dist/gateway/static/root/assets/schema-form-D6PiPxfr.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-CpcVySQK.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-BVy_TawT.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-CZpNyCWn.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-layout-NxoW5Y57.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-MVHLLu_a.js +0 -1
- package/dist/gateway/static/root/assets/share-preview-page-B0suFCfj.js +0 -2
- package/dist/gateway/static/root/assets/shares-settings-C6DBbQGo.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-6hJmhwSn.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-Im1MA0Iw.js +0 -2
- package/dist/gateway/static/root/assets/user-profile-settings-panel-QAQWGelF.js +0 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-D-6XueTv.js +0 -1
- package/dist/gateway/static/root/assets/voice-player-store-CMC5NOJp.js +0 -1
- package/dist/gateway/static/root/assets/workflow-run-setup-panel-DVPllR4k.js +0 -3
- package/dist/gateway/static/root/assets/workflows-page-B94WISTW.js +0 -18
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { getSessionMetadata } from "../storage/sqlite/session-repository.js";
|
|
2
|
+
import "../storage/sqlite/index.js";
|
|
3
|
+
import { ProjectStore } from "./project-store.js";
|
|
4
|
+
import { bindGoalToProject, listProjectGoalIds, unbindGoalFromProject } from "./goal-bind.js";
|
|
5
|
+
import { bindSessionToProject, listProjectSessionKeys, unbindSessionFromProject } from "./session-bind.js";
|
|
6
|
+
//#region src/projects/project-service.ts
|
|
7
|
+
var ProjectService = class {
|
|
8
|
+
constructor(store = new ProjectStore()) {
|
|
9
|
+
this.store = store;
|
|
10
|
+
}
|
|
11
|
+
create(input) {
|
|
12
|
+
const slug = input.slug?.trim() || this.store.generateSlug(input.name);
|
|
13
|
+
return this.store.create({
|
|
14
|
+
...input,
|
|
15
|
+
slug
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
get(id) {
|
|
19
|
+
return this.store.get(id);
|
|
20
|
+
}
|
|
21
|
+
getBySlug(slug) {
|
|
22
|
+
return this.store.findBySlug(slug);
|
|
23
|
+
}
|
|
24
|
+
list(query) {
|
|
25
|
+
return this.store.list(query);
|
|
26
|
+
}
|
|
27
|
+
update(id, input) {
|
|
28
|
+
return this.store.update(id, input);
|
|
29
|
+
}
|
|
30
|
+
delete(id) {
|
|
31
|
+
this.store.delete(id);
|
|
32
|
+
}
|
|
33
|
+
getWithDetails(id) {
|
|
34
|
+
return this.store.getWithDetails(id);
|
|
35
|
+
}
|
|
36
|
+
attachSession(sessionKey, projectId) {
|
|
37
|
+
bindSessionToProject(sessionKey, projectId);
|
|
38
|
+
}
|
|
39
|
+
detachSession(sessionKey) {
|
|
40
|
+
unbindSessionFromProject(sessionKey);
|
|
41
|
+
}
|
|
42
|
+
listSessionKeys(projectId, limit, offset) {
|
|
43
|
+
return listProjectSessionKeys(projectId, limit, offset);
|
|
44
|
+
}
|
|
45
|
+
attachGoal(goalId, projectId) {
|
|
46
|
+
bindGoalToProject(goalId, projectId);
|
|
47
|
+
}
|
|
48
|
+
detachGoal(goalId) {
|
|
49
|
+
unbindGoalFromProject(goalId);
|
|
50
|
+
}
|
|
51
|
+
listGoalIds(projectId, limit, offset) {
|
|
52
|
+
return listProjectGoalIds(projectId, limit, offset);
|
|
53
|
+
}
|
|
54
|
+
suggestProjectsForSession(sessionKey) {
|
|
55
|
+
const session = getSessionMetadata(sessionKey);
|
|
56
|
+
if (!session) return [];
|
|
57
|
+
const projects = this.list({
|
|
58
|
+
status: "active",
|
|
59
|
+
limit: 500
|
|
60
|
+
}).items;
|
|
61
|
+
const haystack = [
|
|
62
|
+
session.key,
|
|
63
|
+
session.name,
|
|
64
|
+
session.routing?.agentId,
|
|
65
|
+
session.sourceChannel,
|
|
66
|
+
...session.tags ?? []
|
|
67
|
+
].filter(Boolean).join(" ").toLowerCase();
|
|
68
|
+
const suggestions = [];
|
|
69
|
+
for (const project of projects) {
|
|
70
|
+
let score = 0;
|
|
71
|
+
const reasons = [];
|
|
72
|
+
if (haystack.includes(project.slug.toLowerCase())) {
|
|
73
|
+
score += 10;
|
|
74
|
+
reasons.push("session metadata matches project slug");
|
|
75
|
+
}
|
|
76
|
+
for (const token of project.name.toLowerCase().split(/\s+/).filter((t) => t.length >= 3)) if (haystack.includes(token)) {
|
|
77
|
+
score += 3;
|
|
78
|
+
reasons.push(`matches ${token}`);
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
if (score > 0) suggestions.push({
|
|
82
|
+
projectId: project.id,
|
|
83
|
+
projectName: project.name,
|
|
84
|
+
score,
|
|
85
|
+
reason: reasons.join(", ")
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
return suggestions.sort((a, b) => b.score - a.score).slice(0, 5);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
//#endregion
|
|
92
|
+
export { ProjectService };
|
|
93
|
+
|
|
94
|
+
//# sourceMappingURL=project-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-service.js","names":[],"sources":["../../../src/projects/project-service.ts"],"sourcesContent":["import { getSessionMetadata } from '../storage/sqlite/index.js';\nimport { ProjectStore } from './project-store.js';\nimport { bindGoalToProject, listProjectGoalIds, unbindGoalFromProject } from './goal-bind.js';\nimport { bindSessionToProject, listProjectSessionKeys, unbindSessionFromProject } from './session-bind.js';\nimport type { CreateProjectInput, Project, ProjectListQuery, ProjectListResult, ProjectWithDetails, UpdateProjectInput } from './types.js';\n\nexport type ProjectSuggestion = {\n projectId: string;\n projectName: string;\n score: number;\n reason: string;\n};\n\nexport class ProjectService {\n constructor(private readonly store = new ProjectStore()) {}\n\n create(input: CreateProjectInput): Project {\n const slug = input.slug?.trim() || this.store.generateSlug(input.name);\n return this.store.create({ ...input, slug });\n }\n\n get(id: string): Project | null {\n return this.store.get(id);\n }\n\n getBySlug(slug: string): Project | null {\n return this.store.findBySlug(slug);\n }\n\n list(query?: ProjectListQuery): ProjectListResult {\n return this.store.list(query);\n }\n\n update(id: string, input: UpdateProjectInput): Project {\n return this.store.update(id, input);\n }\n\n delete(id: string): void {\n this.store.delete(id);\n }\n\n getWithDetails(id: string): ProjectWithDetails | null {\n return this.store.getWithDetails(id);\n }\n\n attachSession(sessionKey: string, projectId: string): void {\n bindSessionToProject(sessionKey, projectId);\n }\n\n detachSession(sessionKey: string): void {\n unbindSessionFromProject(sessionKey);\n }\n\n listSessionKeys(projectId: string, limit?: number, offset?: number): string[] {\n return listProjectSessionKeys(projectId, limit, offset);\n }\n\n attachGoal(goalId: string, projectId: string): void {\n bindGoalToProject(goalId, projectId);\n }\n\n detachGoal(goalId: string): void {\n unbindGoalFromProject(goalId);\n }\n\n listGoalIds(projectId: string, limit?: number, offset?: number): string[] {\n return listProjectGoalIds(projectId, limit, offset);\n }\n\n suggestProjectsForSession(sessionKey: string): ProjectSuggestion[] {\n const session = getSessionMetadata(sessionKey);\n if (!session) return [];\n const projects = this.list({ status: 'active', limit: 500 }).items;\n const haystack = [session.key, session.name, session.routing?.agentId, session.sourceChannel, ...(session.tags ?? [])]\n .filter(Boolean)\n .join(' ')\n .toLowerCase();\n const suggestions: ProjectSuggestion[] = [];\n for (const project of projects) {\n let score = 0;\n const reasons: string[] = [];\n if (haystack.includes(project.slug.toLowerCase())) {\n score += 10;\n reasons.push('session metadata matches project slug');\n }\n for (const token of project.name.toLowerCase().split(/\\s+/).filter((t) => t.length >= 3)) {\n if (haystack.includes(token)) {\n score += 3;\n reasons.push(`matches ${token}`);\n break;\n }\n }\n if (score > 0) {\n suggestions.push({ projectId: project.id, projectName: project.name, score, reason: reasons.join(', ') });\n }\n }\n return suggestions.sort((a, b) => b.score - a.score).slice(0, 5);\n }\n}\n"],"mappings":";;;;;;AAaA,IAAa,iBAAb,MAA4B;CAC1B,YAAY,QAAyB,IAAI,cAAc,EAAE;AAA5B,OAAA,QAAA;;CAE7B,OAAO,OAAoC;EACzC,MAAM,OAAO,MAAM,MAAM,MAAM,IAAI,KAAK,MAAM,aAAa,MAAM,KAAK;AACtE,SAAO,KAAK,MAAM,OAAO;GAAE,GAAG;GAAO;GAAM,CAAC;;CAG9C,IAAI,IAA4B;AAC9B,SAAO,KAAK,MAAM,IAAI,GAAG;;CAG3B,UAAU,MAA8B;AACtC,SAAO,KAAK,MAAM,WAAW,KAAK;;CAGpC,KAAK,OAA6C;AAChD,SAAO,KAAK,MAAM,KAAK,MAAM;;CAG/B,OAAO,IAAY,OAAoC;AACrD,SAAO,KAAK,MAAM,OAAO,IAAI,MAAM;;CAGrC,OAAO,IAAkB;AACvB,OAAK,MAAM,OAAO,GAAG;;CAGvB,eAAe,IAAuC;AACpD,SAAO,KAAK,MAAM,eAAe,GAAG;;CAGtC,cAAc,YAAoB,WAAyB;AACzD,uBAAqB,YAAY,UAAU;;CAG7C,cAAc,YAA0B;AACtC,2BAAyB,WAAW;;CAGtC,gBAAgB,WAAmB,OAAgB,QAA2B;AAC5E,SAAO,uBAAuB,WAAW,OAAO,OAAO;;CAGzD,WAAW,QAAgB,WAAyB;AAClD,oBAAkB,QAAQ,UAAU;;CAGtC,WAAW,QAAsB;AAC/B,wBAAsB,OAAO;;CAG/B,YAAY,WAAmB,OAAgB,QAA2B;AACxE,SAAO,mBAAmB,WAAW,OAAO,OAAO;;CAGrD,0BAA0B,YAAyC;EACjE,MAAM,UAAU,mBAAmB,WAAW;AAC9C,MAAI,CAAC,QAAS,QAAO,EAAE;EACvB,MAAM,WAAW,KAAK,KAAK;GAAE,QAAQ;GAAU,OAAO;GAAK,CAAC,CAAC;EAC7D,MAAM,WAAW;GAAC,QAAQ;GAAK,QAAQ;GAAM,QAAQ,SAAS;GAAS,QAAQ;GAAe,GAAI,QAAQ,QAAQ,EAAE;GAAE,CACnH,OAAO,QAAQ,CACf,KAAK,IAAI,CACT,aAAa;EAChB,MAAM,cAAmC,EAAE;AAC3C,OAAK,MAAM,WAAW,UAAU;GAC9B,IAAI,QAAQ;GACZ,MAAM,UAAoB,EAAE;AAC5B,OAAI,SAAS,SAAS,QAAQ,KAAK,aAAa,CAAC,EAAE;AACjD,aAAS;AACT,YAAQ,KAAK,wCAAwC;;AAEvD,QAAK,MAAM,SAAS,QAAQ,KAAK,aAAa,CAAC,MAAM,MAAM,CAAC,QAAQ,MAAM,EAAE,UAAU,EAAE,CACtF,KAAI,SAAS,SAAS,MAAM,EAAE;AAC5B,aAAS;AACT,YAAQ,KAAK,WAAW,QAAQ;AAChC;;AAGJ,OAAI,QAAQ,EACV,aAAY,KAAK;IAAE,WAAW,QAAQ;IAAI,aAAa,QAAQ;IAAM;IAAO,QAAQ,QAAQ,KAAK,KAAK;IAAE,CAAC;;AAG7G,SAAO,YAAY,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,GAAG,EAAE"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { CreateProjectInput, Project, ProjectListQuery, ProjectListResult, ProjectWithDetails, UpdateProjectInput } from './types.js';
|
|
2
|
+
export type ProjectRow = {
|
|
3
|
+
project_id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
slug: string;
|
|
6
|
+
description: string | null;
|
|
7
|
+
status: string;
|
|
8
|
+
default_agent_id: string | null;
|
|
9
|
+
workspace_root: string | null;
|
|
10
|
+
brief: string | null;
|
|
11
|
+
instructions: string | null;
|
|
12
|
+
created_at: number;
|
|
13
|
+
updated_at: number;
|
|
14
|
+
last_active_at: number | null;
|
|
15
|
+
};
|
|
16
|
+
export declare function slugifyProjectName(name: string): string;
|
|
17
|
+
export declare class ProjectStore {
|
|
18
|
+
create(input: CreateProjectInput): Project;
|
|
19
|
+
get(id: string): Project | null;
|
|
20
|
+
findBySlug(slug: string): Project | null;
|
|
21
|
+
list(query?: ProjectListQuery): ProjectListResult;
|
|
22
|
+
update(id: string, input: UpdateProjectInput): Project;
|
|
23
|
+
delete(id: string): void;
|
|
24
|
+
getSessionCount(id: string): number;
|
|
25
|
+
getGoalCount(id: string): number;
|
|
26
|
+
getActiveGoalCount(id: string): number;
|
|
27
|
+
getRecentSessions(id: string, limit?: number): ProjectWithDetails['recentSessions'];
|
|
28
|
+
getRecentWorkflowRuns(id: string, limit?: number): ProjectWithDetails['recentWorkflowRuns'];
|
|
29
|
+
getWithDetails(id: string): ProjectWithDetails | null;
|
|
30
|
+
generateSlug(name: string): string;
|
|
31
|
+
}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { getSqliteDatabase, runSqliteWriteTransaction } from "../storage/sqlite/transaction.js";
|
|
2
|
+
import { randomUUID } from "node:crypto";
|
|
3
|
+
//#region src/projects/project-store.ts
|
|
4
|
+
function trimOptional(value) {
|
|
5
|
+
if (value == null) return void 0;
|
|
6
|
+
return value.trim() || void 0;
|
|
7
|
+
}
|
|
8
|
+
function nullableText(value) {
|
|
9
|
+
if (value == null) return null;
|
|
10
|
+
return value.trim() || null;
|
|
11
|
+
}
|
|
12
|
+
function projectFromRow(row) {
|
|
13
|
+
return {
|
|
14
|
+
id: row.project_id,
|
|
15
|
+
name: row.name,
|
|
16
|
+
slug: row.slug,
|
|
17
|
+
description: row.description ?? void 0,
|
|
18
|
+
status: row.status,
|
|
19
|
+
defaultAgentId: row.default_agent_id ?? void 0,
|
|
20
|
+
workspaceRoot: row.workspace_root ?? void 0,
|
|
21
|
+
brief: row.brief ?? void 0,
|
|
22
|
+
instructions: row.instructions ?? void 0,
|
|
23
|
+
createdAt: row.created_at,
|
|
24
|
+
updatedAt: row.updated_at,
|
|
25
|
+
lastActiveAt: row.last_active_at ?? void 0
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function clampLimit(limit, fallback = 50) {
|
|
29
|
+
return Math.min(500, Math.max(1, Math.floor(limit ?? fallback)));
|
|
30
|
+
}
|
|
31
|
+
function normalizeName(name) {
|
|
32
|
+
const trimmed = name.trim();
|
|
33
|
+
if (!trimmed) throw new Error("Project name is required");
|
|
34
|
+
return trimmed;
|
|
35
|
+
}
|
|
36
|
+
function slugifyProjectName(name) {
|
|
37
|
+
return name.trim().toLowerCase().normalize("NFKD").replace(/[\u0300-\u036f]/g, "").replace(/[^\p{L}\p{N}]+/gu, "-").replace(/^-+|-+$/g, "").slice(0, 80) || `project-${Date.now()}`;
|
|
38
|
+
}
|
|
39
|
+
function projectSortColumn(sortBy) {
|
|
40
|
+
switch (sortBy) {
|
|
41
|
+
case "createdAt": return "created_at";
|
|
42
|
+
case "name": return "LOWER(name)";
|
|
43
|
+
default: return "updated_at";
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
var ProjectStore = class {
|
|
47
|
+
create(input) {
|
|
48
|
+
const now = Date.now();
|
|
49
|
+
const name = normalizeName(input.name);
|
|
50
|
+
const slug = input.slug?.trim() || slugifyProjectName(name);
|
|
51
|
+
const project = {
|
|
52
|
+
id: randomUUID(),
|
|
53
|
+
name,
|
|
54
|
+
slug,
|
|
55
|
+
description: trimOptional(input.description),
|
|
56
|
+
status: "active",
|
|
57
|
+
defaultAgentId: trimOptional(input.defaultAgentId),
|
|
58
|
+
workspaceRoot: trimOptional(input.workspaceRoot),
|
|
59
|
+
brief: trimOptional(input.brief),
|
|
60
|
+
instructions: trimOptional(input.instructions),
|
|
61
|
+
createdAt: now,
|
|
62
|
+
updatedAt: now,
|
|
63
|
+
lastActiveAt: now
|
|
64
|
+
};
|
|
65
|
+
runSqliteWriteTransaction((db) => {
|
|
66
|
+
db.prepare(`INSERT INTO projects (
|
|
67
|
+
project_id, name, slug, description, status, default_agent_id, workspace_root,
|
|
68
|
+
brief, instructions, created_at, updated_at, last_active_at
|
|
69
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(project.id, project.name, project.slug, project.description ?? null, project.status, project.defaultAgentId ?? null, project.workspaceRoot ?? null, project.brief ?? null, project.instructions ?? null, project.createdAt, project.updatedAt, project.lastActiveAt ?? null);
|
|
70
|
+
});
|
|
71
|
+
return project;
|
|
72
|
+
}
|
|
73
|
+
get(id) {
|
|
74
|
+
const row = getSqliteDatabase().prepare(`SELECT * FROM projects WHERE project_id = ?`).get(id);
|
|
75
|
+
return row ? projectFromRow(row) : null;
|
|
76
|
+
}
|
|
77
|
+
findBySlug(slug) {
|
|
78
|
+
const row = getSqliteDatabase().prepare(`SELECT * FROM projects WHERE slug = ?`).get(slug.trim());
|
|
79
|
+
return row ? projectFromRow(row) : null;
|
|
80
|
+
}
|
|
81
|
+
list(query = {}) {
|
|
82
|
+
const conditions = [];
|
|
83
|
+
const params = [];
|
|
84
|
+
if (query.status) {
|
|
85
|
+
const statuses = Array.isArray(query.status) ? query.status : [query.status];
|
|
86
|
+
conditions.push(`status IN (${statuses.map(() => "?").join(", ")})`);
|
|
87
|
+
params.push(...statuses);
|
|
88
|
+
}
|
|
89
|
+
if (query.search?.trim()) {
|
|
90
|
+
const like = `%${query.search.trim().toLowerCase()}%`;
|
|
91
|
+
conditions.push(`(LOWER(name) LIKE ? OR LOWER(slug) LIKE ? OR LOWER(COALESCE(description, '')) LIKE ?)`);
|
|
92
|
+
params.push(like, like, like);
|
|
93
|
+
}
|
|
94
|
+
const where = conditions.length ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
95
|
+
const limit = clampLimit(query.limit, 50);
|
|
96
|
+
const offset = Math.max(0, Math.floor(query.offset ?? 0));
|
|
97
|
+
const sortOrder = query.sortOrder === "asc" ? "ASC" : "DESC";
|
|
98
|
+
const sortColumn = projectSortColumn(query.sortBy);
|
|
99
|
+
const db = getSqliteDatabase();
|
|
100
|
+
const total = db.prepare(`SELECT COUNT(*) AS total FROM projects ${where}`).get(...params).total;
|
|
101
|
+
return {
|
|
102
|
+
items: db.prepare(`SELECT * FROM projects ${where} ORDER BY ${sortColumn} ${sortOrder} LIMIT ? OFFSET ?`).all(...params, limit, offset).map(projectFromRow),
|
|
103
|
+
total,
|
|
104
|
+
limit,
|
|
105
|
+
offset,
|
|
106
|
+
hasMore: offset + limit < total
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
update(id, input) {
|
|
110
|
+
const before = this.get(id);
|
|
111
|
+
if (!before) throw new Error(`Project not found: ${id}`);
|
|
112
|
+
const next = {
|
|
113
|
+
...before,
|
|
114
|
+
...input.name !== void 0 ? { name: normalizeName(input.name) } : {},
|
|
115
|
+
...input.description !== void 0 ? { description: nullableText(input.description) ?? void 0 } : {},
|
|
116
|
+
...input.status !== void 0 ? { status: input.status } : {},
|
|
117
|
+
...input.defaultAgentId !== void 0 ? { defaultAgentId: nullableText(input.defaultAgentId) ?? void 0 } : {},
|
|
118
|
+
...input.workspaceRoot !== void 0 ? { workspaceRoot: nullableText(input.workspaceRoot) ?? void 0 } : {},
|
|
119
|
+
...input.brief !== void 0 ? { brief: nullableText(input.brief) ?? void 0 } : {},
|
|
120
|
+
...input.instructions !== void 0 ? { instructions: nullableText(input.instructions) ?? void 0 } : {},
|
|
121
|
+
updatedAt: Date.now()
|
|
122
|
+
};
|
|
123
|
+
runSqliteWriteTransaction((db) => {
|
|
124
|
+
db.prepare(`UPDATE projects SET
|
|
125
|
+
name = ?, description = ?, status = ?, default_agent_id = ?, workspace_root = ?, brief = ?, instructions = ?, updated_at = ?
|
|
126
|
+
WHERE project_id = ?`).run(next.name, next.description ?? null, next.status, next.defaultAgentId ?? null, next.workspaceRoot ?? null, next.brief ?? null, next.instructions ?? null, next.updatedAt, id);
|
|
127
|
+
});
|
|
128
|
+
return this.get(id);
|
|
129
|
+
}
|
|
130
|
+
delete(id) {
|
|
131
|
+
runSqliteWriteTransaction((db) => {
|
|
132
|
+
db.prepare(`UPDATE sessions SET project_id = NULL WHERE project_id = ?`).run(id);
|
|
133
|
+
db.prepare(`UPDATE goals SET project_id = NULL WHERE project_id = ?`).run(id);
|
|
134
|
+
db.prepare(`UPDATE workflow_runs SET project_id = NULL WHERE project_id = ?`).run(id);
|
|
135
|
+
db.prepare(`UPDATE automations SET project_id = NULL WHERE project_id = ?`).run(id);
|
|
136
|
+
db.prepare(`UPDATE memory_records SET project_id = NULL WHERE project_id = ?`).run(id);
|
|
137
|
+
db.prepare(`DELETE FROM projects WHERE project_id = ?`).run(id);
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
getSessionCount(id) {
|
|
141
|
+
return getSqliteDatabase().prepare(`SELECT COUNT(*) AS total FROM sessions WHERE project_id = ? AND hidden_from_session_list = 0`).get(id).total;
|
|
142
|
+
}
|
|
143
|
+
getGoalCount(id) {
|
|
144
|
+
return getSqliteDatabase().prepare(`SELECT COUNT(*) AS total FROM goals WHERE project_id = ?`).get(id).total;
|
|
145
|
+
}
|
|
146
|
+
getActiveGoalCount(id) {
|
|
147
|
+
return getSqliteDatabase().prepare(`SELECT COUNT(*) AS total FROM goals WHERE project_id = ? AND status IN ('active', 'paused', 'blocked', 'needs_input')`).get(id).total;
|
|
148
|
+
}
|
|
149
|
+
getRecentSessions(id, limit = 5) {
|
|
150
|
+
return getSqliteDatabase().prepare(`SELECT session_key, name, updated_at, agent_id FROM sessions
|
|
151
|
+
WHERE project_id = ? AND hidden_from_session_list = 0 ORDER BY updated_at DESC LIMIT ?`).all(id, clampLimit(limit, 5)).map((row) => ({
|
|
152
|
+
key: row.session_key,
|
|
153
|
+
name: row.name ?? void 0,
|
|
154
|
+
updatedAt: new Date(row.updated_at).toISOString(),
|
|
155
|
+
agentId: row.agent_id
|
|
156
|
+
}));
|
|
157
|
+
}
|
|
158
|
+
getRecentWorkflowRuns(id, limit = 5) {
|
|
159
|
+
return getSqliteDatabase().prepare(`SELECT run_id, definition_id, status, created_at_ms FROM workflow_runs
|
|
160
|
+
WHERE project_id = ? ORDER BY created_at_ms DESC LIMIT ?`).all(id, clampLimit(limit, 5)).map((row) => ({
|
|
161
|
+
runId: row.run_id,
|
|
162
|
+
definitionId: row.definition_id,
|
|
163
|
+
status: row.status,
|
|
164
|
+
createdAt: row.created_at_ms
|
|
165
|
+
}));
|
|
166
|
+
}
|
|
167
|
+
getWithDetails(id) {
|
|
168
|
+
const project = this.get(id);
|
|
169
|
+
if (!project) return null;
|
|
170
|
+
return {
|
|
171
|
+
...project,
|
|
172
|
+
sessionCount: this.getSessionCount(id),
|
|
173
|
+
goalCount: this.getGoalCount(id),
|
|
174
|
+
activeGoalCount: this.getActiveGoalCount(id),
|
|
175
|
+
recentSessions: this.getRecentSessions(id),
|
|
176
|
+
recentWorkflowRuns: this.getRecentWorkflowRuns(id)
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
generateSlug(name) {
|
|
180
|
+
const base = slugifyProjectName(name);
|
|
181
|
+
let candidate = base;
|
|
182
|
+
let counter = 2;
|
|
183
|
+
while (this.findBySlug(candidate)) {
|
|
184
|
+
candidate = `${base}-${counter}`;
|
|
185
|
+
counter += 1;
|
|
186
|
+
}
|
|
187
|
+
return candidate;
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
//#endregion
|
|
191
|
+
export { ProjectStore, slugifyProjectName };
|
|
192
|
+
|
|
193
|
+
//# sourceMappingURL=project-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-store.js","names":[],"sources":["../../../src/projects/project-store.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport { getSqliteDatabase, runSqliteWriteTransaction } from '../storage/sqlite/transaction.js';\nimport type {\n CreateProjectInput,\n Project,\n ProjectListQuery,\n ProjectListResult,\n ProjectStatus,\n ProjectWithDetails,\n UpdateProjectInput,\n} from './types.js';\n\nexport type ProjectRow = {\n project_id: string;\n name: string;\n slug: string;\n description: string | null;\n status: string;\n default_agent_id: string | null;\n workspace_root: string | null;\n brief: string | null;\n instructions: string | null;\n created_at: number;\n updated_at: number;\n last_active_at: number | null;\n};\n\nfunction trimOptional(value: string | null | undefined): string | undefined {\n if (value == null) return undefined;\n const trimmed = value.trim();\n return trimmed || undefined;\n}\n\nfunction nullableText(value: string | null | undefined): string | null {\n if (value == null) return null;\n const trimmed = value.trim();\n return trimmed || null;\n}\n\nfunction projectFromRow(row: ProjectRow): Project {\n return {\n id: row.project_id,\n name: row.name,\n slug: row.slug,\n description: row.description ?? undefined,\n status: row.status as ProjectStatus,\n defaultAgentId: row.default_agent_id ?? undefined,\n workspaceRoot: row.workspace_root ?? undefined,\n brief: row.brief ?? undefined,\n instructions: row.instructions ?? undefined,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n lastActiveAt: row.last_active_at ?? undefined,\n };\n}\n\nfunction clampLimit(limit: number | undefined, fallback = 50): number {\n return Math.min(500, Math.max(1, Math.floor(limit ?? fallback)));\n}\n\nfunction normalizeName(name: string): string {\n const trimmed = name.trim();\n if (!trimmed) throw new Error('Project name is required');\n return trimmed;\n}\n\nexport function slugifyProjectName(name: string): string {\n const slug = name\n .trim()\n .toLowerCase()\n .normalize('NFKD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[^\\p{L}\\p{N}]+/gu, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 80);\n return slug || `project-${Date.now()}`;\n}\n\nfunction projectSortColumn(sortBy: ProjectListQuery['sortBy']): string {\n switch (sortBy) {\n case 'createdAt':\n return 'created_at';\n case 'name':\n return 'LOWER(name)';\n case 'updatedAt':\n default:\n return 'updated_at';\n }\n}\n\nexport class ProjectStore {\n create(input: CreateProjectInput): Project {\n const now = Date.now();\n const name = normalizeName(input.name);\n const slug = input.slug?.trim() || slugifyProjectName(name);\n const project: Project = {\n id: randomUUID(),\n name,\n slug,\n description: trimOptional(input.description),\n status: 'active',\n defaultAgentId: trimOptional(input.defaultAgentId),\n workspaceRoot: trimOptional(input.workspaceRoot),\n brief: trimOptional(input.brief),\n instructions: trimOptional(input.instructions),\n createdAt: now,\n updatedAt: now,\n lastActiveAt: now,\n };\n\n runSqliteWriteTransaction((db) => {\n db.prepare(\n `INSERT INTO projects (\n project_id, name, slug, description, status, default_agent_id, workspace_root,\n brief, instructions, created_at, updated_at, last_active_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n ).run(\n project.id,\n project.name,\n project.slug,\n project.description ?? null,\n project.status,\n project.defaultAgentId ?? null,\n project.workspaceRoot ?? null,\n project.brief ?? null,\n project.instructions ?? null,\n project.createdAt,\n project.updatedAt,\n project.lastActiveAt ?? null,\n );\n });\n return project;\n }\n\n get(id: string): Project | null {\n const row = getSqliteDatabase()\n .prepare(`SELECT * FROM projects WHERE project_id = ?`)\n .get(id) as ProjectRow | undefined;\n return row ? projectFromRow(row) : null;\n }\n\n findBySlug(slug: string): Project | null {\n const row = getSqliteDatabase()\n .prepare(`SELECT * FROM projects WHERE slug = ?`)\n .get(slug.trim()) as ProjectRow | undefined;\n return row ? projectFromRow(row) : null;\n }\n\n list(query: ProjectListQuery = {}): ProjectListResult {\n const conditions: string[] = [];\n const params: Array<string | number> = [];\n if (query.status) {\n const statuses = Array.isArray(query.status) ? query.status : [query.status];\n conditions.push(`status IN (${statuses.map(() => '?').join(', ')})`);\n params.push(...statuses);\n }\n if (query.search?.trim()) {\n const like = `%${query.search.trim().toLowerCase()}%`;\n conditions.push(`(LOWER(name) LIKE ? OR LOWER(slug) LIKE ? OR LOWER(COALESCE(description, '')) LIKE ?)`);\n params.push(like, like, like);\n }\n const where = conditions.length ? `WHERE ${conditions.join(' AND ')}` : '';\n const limit = clampLimit(query.limit, 50);\n const offset = Math.max(0, Math.floor(query.offset ?? 0));\n const sortOrder = query.sortOrder === 'asc' ? 'ASC' : 'DESC';\n const sortColumn = projectSortColumn(query.sortBy);\n const db = getSqliteDatabase();\n const total = (db.prepare(`SELECT COUNT(*) AS total FROM projects ${where}`).get(...params) as { total: number }).total;\n const rows = db\n .prepare(`SELECT * FROM projects ${where} ORDER BY ${sortColumn} ${sortOrder} LIMIT ? OFFSET ?`)\n .all(...params, limit, offset) as ProjectRow[];\n return { items: rows.map(projectFromRow), total, limit, offset, hasMore: offset + limit < total };\n }\n\n update(id: string, input: UpdateProjectInput): Project {\n const before = this.get(id);\n if (!before) throw new Error(`Project not found: ${id}`);\n const next = {\n ...before,\n ...(input.name !== undefined ? { name: normalizeName(input.name) } : {}),\n ...(input.description !== undefined ? { description: nullableText(input.description) ?? undefined } : {}),\n ...(input.status !== undefined ? { status: input.status } : {}),\n ...(input.defaultAgentId !== undefined ? { defaultAgentId: nullableText(input.defaultAgentId) ?? undefined } : {}),\n ...(input.workspaceRoot !== undefined ? { workspaceRoot: nullableText(input.workspaceRoot) ?? undefined } : {}),\n ...(input.brief !== undefined ? { brief: nullableText(input.brief) ?? undefined } : {}),\n ...(input.instructions !== undefined ? { instructions: nullableText(input.instructions) ?? undefined } : {}),\n updatedAt: Date.now(),\n } satisfies Project;\n\n runSqliteWriteTransaction((db) => {\n db.prepare(\n `UPDATE projects SET\n name = ?, description = ?, status = ?, default_agent_id = ?, workspace_root = ?, brief = ?, instructions = ?, updated_at = ?\n WHERE project_id = ?`,\n ).run(\n next.name,\n next.description ?? null,\n next.status,\n next.defaultAgentId ?? null,\n next.workspaceRoot ?? null,\n next.brief ?? null,\n next.instructions ?? null,\n next.updatedAt,\n id,\n );\n });\n return this.get(id)!;\n }\n\n delete(id: string): void {\n runSqliteWriteTransaction((db) => {\n db.prepare(`UPDATE sessions SET project_id = NULL WHERE project_id = ?`).run(id);\n db.prepare(`UPDATE goals SET project_id = NULL WHERE project_id = ?`).run(id);\n db.prepare(`UPDATE workflow_runs SET project_id = NULL WHERE project_id = ?`).run(id);\n db.prepare(`UPDATE automations SET project_id = NULL WHERE project_id = ?`).run(id);\n db.prepare(`UPDATE memory_records SET project_id = NULL WHERE project_id = ?`).run(id);\n db.prepare(`DELETE FROM projects WHERE project_id = ?`).run(id);\n });\n }\n\n getSessionCount(id: string): number {\n return (getSqliteDatabase()\n .prepare(`SELECT COUNT(*) AS total FROM sessions WHERE project_id = ? AND hidden_from_session_list = 0`)\n .get(id) as { total: number }).total;\n }\n\n getGoalCount(id: string): number {\n return (getSqliteDatabase().prepare(`SELECT COUNT(*) AS total FROM goals WHERE project_id = ?`).get(id) as { total: number }).total;\n }\n\n getActiveGoalCount(id: string): number {\n return (getSqliteDatabase()\n .prepare(`SELECT COUNT(*) AS total FROM goals WHERE project_id = ? AND status IN ('active', 'paused', 'blocked', 'needs_input')`)\n .get(id) as { total: number }).total;\n }\n\n getRecentSessions(id: string, limit = 5): ProjectWithDetails['recentSessions'] {\n const rows = getSqliteDatabase()\n .prepare(\n `SELECT session_key, name, updated_at, agent_id FROM sessions\n WHERE project_id = ? AND hidden_from_session_list = 0 ORDER BY updated_at DESC LIMIT ?`,\n )\n .all(id, clampLimit(limit, 5)) as Array<{ session_key: string; name: string | null; updated_at: number; agent_id: string }>;\n return rows.map((row) => ({\n key: row.session_key,\n name: row.name ?? undefined,\n updatedAt: new Date(row.updated_at).toISOString(),\n agentId: row.agent_id,\n }));\n }\n\n getRecentWorkflowRuns(id: string, limit = 5): ProjectWithDetails['recentWorkflowRuns'] {\n const rows = getSqliteDatabase()\n .prepare(\n `SELECT run_id, definition_id, status, created_at_ms FROM workflow_runs\n WHERE project_id = ? ORDER BY created_at_ms DESC LIMIT ?`,\n )\n .all(id, clampLimit(limit, 5)) as Array<{ run_id: string; definition_id: string; status: string; created_at_ms: number }>;\n return rows.map((row) => ({ runId: row.run_id, definitionId: row.definition_id, status: row.status, createdAt: row.created_at_ms }));\n }\n\n getWithDetails(id: string): ProjectWithDetails | null {\n const project = this.get(id);\n if (!project) return null;\n return {\n ...project,\n sessionCount: this.getSessionCount(id),\n goalCount: this.getGoalCount(id),\n activeGoalCount: this.getActiveGoalCount(id),\n recentSessions: this.getRecentSessions(id),\n recentWorkflowRuns: this.getRecentWorkflowRuns(id),\n };\n }\n\n generateSlug(name: string): string {\n const base = slugifyProjectName(name);\n let candidate = base;\n let counter = 2;\n while (this.findBySlug(candidate)) {\n candidate = `${base}-${counter}`;\n counter += 1;\n }\n return candidate;\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function bindSessionToProject(sessionKey: string, projectId: string): void;
|
|
2
|
+
export declare function unbindSessionFromProject(sessionKey: string): void;
|
|
3
|
+
export declare function listProjectSessionKeys(projectId: string, limit?: number, offset?: number): string[];
|
|
4
|
+
export declare function bindSessionsToProject(sessionKeys: string[], projectId: string): void;
|
|
5
|
+
export declare function moveSessionToProject(sessionKey: string, targetProjectId: string): void;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { getSqliteDatabase, runSqliteWriteTransaction } from "../storage/sqlite/transaction.js";
|
|
2
|
+
//#region src/projects/session-bind.ts
|
|
3
|
+
function projectExists(projectId) {
|
|
4
|
+
return Boolean(getSqliteDatabase().prepare(`SELECT 1 FROM projects WHERE project_id = ?`).get(projectId));
|
|
5
|
+
}
|
|
6
|
+
function assertProjectExists(projectId) {
|
|
7
|
+
if (!projectExists(projectId)) throw new Error(`Project not found: ${projectId}`);
|
|
8
|
+
}
|
|
9
|
+
function assertSessionExists(sessionKey) {
|
|
10
|
+
if (!getSqliteDatabase().prepare(`SELECT 1 FROM sessions WHERE session_key = ?`).get(sessionKey)) throw new Error(`Session not found: ${sessionKey}`);
|
|
11
|
+
}
|
|
12
|
+
function bindSessionToProject(sessionKey, projectId) {
|
|
13
|
+
assertProjectExists(projectId);
|
|
14
|
+
assertSessionExists(sessionKey);
|
|
15
|
+
runSqliteWriteTransaction((db) => {
|
|
16
|
+
const now = Date.now();
|
|
17
|
+
db.prepare(`UPDATE sessions SET project_id = ?, updated_at = ? WHERE session_key = ?`).run(projectId, now, sessionKey);
|
|
18
|
+
db.prepare(`UPDATE projects SET last_active_at = ?, updated_at = ? WHERE project_id = ?`).run(now, now, projectId);
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
function unbindSessionFromProject(sessionKey) {
|
|
22
|
+
assertSessionExists(sessionKey);
|
|
23
|
+
runSqliteWriteTransaction((db) => {
|
|
24
|
+
db.prepare(`UPDATE sessions SET project_id = NULL, updated_at = ? WHERE session_key = ?`).run(Date.now(), sessionKey);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
function listProjectSessionKeys(projectId, limit = 100, offset = 0) {
|
|
28
|
+
assertProjectExists(projectId);
|
|
29
|
+
return getSqliteDatabase().prepare(`SELECT session_key FROM sessions WHERE project_id = ? ORDER BY updated_at DESC LIMIT ? OFFSET ?`).all(projectId, Math.min(500, Math.max(1, Math.floor(limit))), Math.max(0, Math.floor(offset))).map((row) => row.session_key);
|
|
30
|
+
}
|
|
31
|
+
function bindSessionsToProject(sessionKeys, projectId) {
|
|
32
|
+
assertProjectExists(projectId);
|
|
33
|
+
runSqliteWriteTransaction((db) => {
|
|
34
|
+
const now = Date.now();
|
|
35
|
+
const stmt = db.prepare(`UPDATE sessions SET project_id = ?, updated_at = ? WHERE session_key = ?`);
|
|
36
|
+
for (const key of sessionKeys) stmt.run(projectId, now, key);
|
|
37
|
+
db.prepare(`UPDATE projects SET last_active_at = ?, updated_at = ? WHERE project_id = ?`).run(now, now, projectId);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function moveSessionToProject(sessionKey, targetProjectId) {
|
|
41
|
+
bindSessionToProject(sessionKey, targetProjectId);
|
|
42
|
+
}
|
|
43
|
+
//#endregion
|
|
44
|
+
export { bindSessionToProject, bindSessionsToProject, listProjectSessionKeys, moveSessionToProject, unbindSessionFromProject };
|
|
45
|
+
|
|
46
|
+
//# sourceMappingURL=session-bind.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-bind.js","names":[],"sources":["../../../src/projects/session-bind.ts"],"sourcesContent":["import { getSqliteDatabase, runSqliteWriteTransaction } from '../storage/sqlite/transaction.js';\n\nfunction projectExists(projectId: string): boolean {\n return Boolean(getSqliteDatabase().prepare(`SELECT 1 FROM projects WHERE project_id = ?`).get(projectId));\n}\n\nfunction assertProjectExists(projectId: string): void {\n if (!projectExists(projectId)) {\n throw new Error(`Project not found: ${projectId}`);\n }\n}\n\nfunction assertSessionExists(sessionKey: string): void {\n const row = getSqliteDatabase().prepare(`SELECT 1 FROM sessions WHERE session_key = ?`).get(sessionKey);\n if (!row) throw new Error(`Session not found: ${sessionKey}`);\n}\n\nexport function bindSessionToProject(sessionKey: string, projectId: string): void {\n assertProjectExists(projectId);\n assertSessionExists(sessionKey);\n runSqliteWriteTransaction((db) => {\n const now = Date.now();\n db.prepare(`UPDATE sessions SET project_id = ?, updated_at = ? WHERE session_key = ?`).run(projectId, now, sessionKey);\n db.prepare(`UPDATE projects SET last_active_at = ?, updated_at = ? WHERE project_id = ?`).run(now, now, projectId);\n });\n}\n\nexport function unbindSessionFromProject(sessionKey: string): void {\n assertSessionExists(sessionKey);\n runSqliteWriteTransaction((db) => {\n db.prepare(`UPDATE sessions SET project_id = NULL, updated_at = ? WHERE session_key = ?`).run(Date.now(), sessionKey);\n });\n}\n\nexport function listProjectSessionKeys(projectId: string, limit = 100, offset = 0): string[] {\n assertProjectExists(projectId);\n const rows = getSqliteDatabase()\n .prepare(`SELECT session_key FROM sessions WHERE project_id = ? ORDER BY updated_at DESC LIMIT ? OFFSET ?`)\n .all(projectId, Math.min(500, Math.max(1, Math.floor(limit))), Math.max(0, Math.floor(offset))) as Array<{ session_key: string }>;\n return rows.map((row) => row.session_key);\n}\n\nexport function bindSessionsToProject(sessionKeys: string[], projectId: string): void {\n assertProjectExists(projectId);\n runSqliteWriteTransaction((db) => {\n const now = Date.now();\n const stmt = db.prepare(`UPDATE sessions SET project_id = ?, updated_at = ? WHERE session_key = ?`);\n for (const key of sessionKeys) {\n stmt.run(projectId, now, key);\n }\n db.prepare(`UPDATE projects SET last_active_at = ?, updated_at = ? WHERE project_id = ?`).run(now, now, projectId);\n });\n}\n\nexport function moveSessionToProject(sessionKey: string, targetProjectId: string): void {\n bindSessionToProject(sessionKey, targetProjectId);\n}\n"],"mappings":";;AAEA,SAAS,cAAc,WAA4B;AACjD,QAAO,QAAQ,mBAAmB,CAAC,QAAQ,8CAA8C,CAAC,IAAI,UAAU,CAAC;;AAG3G,SAAS,oBAAoB,WAAyB;AACpD,KAAI,CAAC,cAAc,UAAU,CAC3B,OAAM,IAAI,MAAM,sBAAsB,YAAY;;AAItD,SAAS,oBAAoB,YAA0B;AAErD,KAAI,CADQ,mBAAmB,CAAC,QAAQ,+CAA+C,CAAC,IAAI,WACpF,CAAE,OAAM,IAAI,MAAM,sBAAsB,aAAa;;AAG/D,SAAgB,qBAAqB,YAAoB,WAAyB;AAChF,qBAAoB,UAAU;AAC9B,qBAAoB,WAAW;AAC/B,4BAA2B,OAAO;EAChC,MAAM,MAAM,KAAK,KAAK;AACtB,KAAG,QAAQ,2EAA2E,CAAC,IAAI,WAAW,KAAK,WAAW;AACtH,KAAG,QAAQ,8EAA8E,CAAC,IAAI,KAAK,KAAK,UAAU;GAClH;;AAGJ,SAAgB,yBAAyB,YAA0B;AACjE,qBAAoB,WAAW;AAC/B,4BAA2B,OAAO;AAChC,KAAG,QAAQ,8EAA8E,CAAC,IAAI,KAAK,KAAK,EAAE,WAAW;GACrH;;AAGJ,SAAgB,uBAAuB,WAAmB,QAAQ,KAAK,SAAS,GAAa;AAC3F,qBAAoB,UAAU;AAI9B,QAHa,mBAAmB,CAC7B,QAAQ,kGAAkG,CAC1G,IAAI,WAAW,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM,MAAM,CAAC,CAAC,EAAE,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,CAAC,CACrF,CAAC,KAAK,QAAQ,IAAI,YAAY;;AAG3C,SAAgB,sBAAsB,aAAuB,WAAyB;AACpF,qBAAoB,UAAU;AAC9B,4BAA2B,OAAO;EAChC,MAAM,MAAM,KAAK,KAAK;EACtB,MAAM,OAAO,GAAG,QAAQ,2EAA2E;AACnG,OAAK,MAAM,OAAO,YAChB,MAAK,IAAI,WAAW,KAAK,IAAI;AAE/B,KAAG,QAAQ,8EAA8E,CAAC,IAAI,KAAK,KAAK,UAAU;GAClH;;AAGJ,SAAgB,qBAAqB,YAAoB,iBAA+B;AACtF,sBAAqB,YAAY,gBAAgB"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { PaginatedResult } from '../session/types.js';
|
|
2
|
+
export type ProjectStatus = 'active' | 'paused' | 'archived';
|
|
3
|
+
export interface Project {
|
|
4
|
+
id: string;
|
|
5
|
+
name: string;
|
|
6
|
+
slug: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
status: ProjectStatus;
|
|
9
|
+
defaultAgentId?: string;
|
|
10
|
+
workspaceRoot?: string;
|
|
11
|
+
brief?: string;
|
|
12
|
+
instructions?: string;
|
|
13
|
+
createdAt: number;
|
|
14
|
+
updatedAt: number;
|
|
15
|
+
lastActiveAt?: number;
|
|
16
|
+
}
|
|
17
|
+
export interface ProjectWithDetails extends Project {
|
|
18
|
+
sessionCount: number;
|
|
19
|
+
goalCount: number;
|
|
20
|
+
activeGoalCount: number;
|
|
21
|
+
recentSessions: Array<{
|
|
22
|
+
key: string;
|
|
23
|
+
name?: string;
|
|
24
|
+
updatedAt: string;
|
|
25
|
+
agentId: string;
|
|
26
|
+
}>;
|
|
27
|
+
recentWorkflowRuns: Array<{
|
|
28
|
+
runId: string;
|
|
29
|
+
definitionId: string;
|
|
30
|
+
status: string;
|
|
31
|
+
createdAt: number;
|
|
32
|
+
}>;
|
|
33
|
+
}
|
|
34
|
+
export interface ProjectListQuery {
|
|
35
|
+
status?: ProjectStatus | ProjectStatus[];
|
|
36
|
+
search?: string;
|
|
37
|
+
sortBy?: 'updatedAt' | 'createdAt' | 'name';
|
|
38
|
+
sortOrder?: 'asc' | 'desc';
|
|
39
|
+
limit?: number;
|
|
40
|
+
offset?: number;
|
|
41
|
+
}
|
|
42
|
+
export interface CreateProjectInput {
|
|
43
|
+
name: string;
|
|
44
|
+
slug?: string;
|
|
45
|
+
description?: string;
|
|
46
|
+
defaultAgentId?: string;
|
|
47
|
+
workspaceRoot?: string;
|
|
48
|
+
brief?: string;
|
|
49
|
+
instructions?: string;
|
|
50
|
+
}
|
|
51
|
+
export interface UpdateProjectInput {
|
|
52
|
+
name?: string;
|
|
53
|
+
description?: string | null;
|
|
54
|
+
defaultAgentId?: string | null;
|
|
55
|
+
status?: ProjectStatus;
|
|
56
|
+
workspaceRoot?: string | null;
|
|
57
|
+
brief?: string | null;
|
|
58
|
+
instructions?: string | null;
|
|
59
|
+
}
|
|
60
|
+
export type ProjectListResult = PaginatedResult<Project>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function bindWorkflowRunToProject(runId: string, projectId: string): void;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { getSqliteDatabase, runSqliteWriteTransaction } from "../storage/sqlite/transaction.js";
|
|
2
|
+
//#region src/projects/workflow-bind.ts
|
|
3
|
+
function bindWorkflowRunToProject(runId, projectId) {
|
|
4
|
+
const db = getSqliteDatabase();
|
|
5
|
+
if (!db.prepare(`SELECT 1 FROM projects WHERE project_id = ?`).get(projectId)) throw new Error(`Project not found: ${projectId}`);
|
|
6
|
+
if (!db.prepare(`SELECT 1 FROM workflow_runs WHERE run_id = ?`).get(runId)) throw new Error(`Workflow run not found: ${runId}`);
|
|
7
|
+
runSqliteWriteTransaction((tx) => {
|
|
8
|
+
const now = Date.now();
|
|
9
|
+
tx.prepare(`UPDATE workflow_runs SET project_id = ? WHERE run_id = ?`).run(projectId, runId);
|
|
10
|
+
tx.prepare(`UPDATE projects SET last_active_at = ?, updated_at = ? WHERE project_id = ?`).run(now, now, projectId);
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
export { bindWorkflowRunToProject };
|
|
15
|
+
|
|
16
|
+
//# sourceMappingURL=workflow-bind.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-bind.js","names":[],"sources":["../../../src/projects/workflow-bind.ts"],"sourcesContent":["import { getSqliteDatabase, runSqliteWriteTransaction } from '../storage/sqlite/transaction.js';\n\nexport function bindWorkflowRunToProject(runId: string, projectId: string): void {\n const db = getSqliteDatabase();\n if (!db.prepare(`SELECT 1 FROM projects WHERE project_id = ?`).get(projectId)) throw new Error(`Project not found: ${projectId}`);\n if (!db.prepare(`SELECT 1 FROM workflow_runs WHERE run_id = ?`).get(runId)) throw new Error(`Workflow run not found: ${runId}`);\n runSqliteWriteTransaction((tx) => {\n const now = Date.now();\n tx.prepare(`UPDATE workflow_runs SET project_id = ? WHERE run_id = ?`).run(projectId, runId);\n tx.prepare(`UPDATE projects SET last_active_at = ?, updated_at = ? WHERE project_id = ?`).run(now, now, projectId);\n });\n}\n"],"mappings":";;AAEA,SAAgB,yBAAyB,OAAe,WAAyB;CAC/E,MAAM,KAAK,mBAAmB;AAC9B,KAAI,CAAC,GAAG,QAAQ,8CAA8C,CAAC,IAAI,UAAU,CAAE,OAAM,IAAI,MAAM,sBAAsB,YAAY;AACjI,KAAI,CAAC,GAAG,QAAQ,+CAA+C,CAAC,IAAI,MAAM,CAAE,OAAM,IAAI,MAAM,2BAA2B,QAAQ;AAC/H,4BAA2B,OAAO;EAChC,MAAM,MAAM,KAAK,KAAK;AACtB,KAAG,QAAQ,2DAA2D,CAAC,IAAI,WAAW,MAAM;AAC5F,KAAG,QAAQ,8EAA8E,CAAC,IAAI,KAAK,KAAK,UAAU;GAClH"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Config } from '../config/schema.js';
|
|
2
|
+
import type { Project } from './types.js';
|
|
3
|
+
export declare function resolveProjectWorkspacePath(config: Config, sessionKey: string, project: Project | null): string;
|
|
4
|
+
export declare function getProjectForSession(sessionKey: string): Project | null;
|
|
5
|
+
export declare function getProjectWorkspacePathForSession(sessionKey: string): string | null;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { resolveEffectiveAgentProfileForSession } from "../config/agent-profile.js";
|
|
2
|
+
import { isXopcDatabaseOpen } from "../storage/sqlite/connection.js";
|
|
3
|
+
import { getSessionMetadata } from "../storage/sqlite/session-repository.js";
|
|
4
|
+
import "../storage/sqlite/index.js";
|
|
5
|
+
import { projectWorkspacePath } from "../session/session-workspace.js";
|
|
6
|
+
import { ProjectStore } from "./project-store.js";
|
|
7
|
+
//#region src/projects/workspace.ts
|
|
8
|
+
function resolveProjectWorkspacePath(config, sessionKey, project) {
|
|
9
|
+
const projectWorkspace = projectWorkspacePath(project);
|
|
10
|
+
if (projectWorkspace) return projectWorkspace;
|
|
11
|
+
return resolveEffectiveAgentProfileForSession(config, sessionKey).resolvedWorkspacePath;
|
|
12
|
+
}
|
|
13
|
+
function getProjectForSession(sessionKey) {
|
|
14
|
+
if (!isXopcDatabaseOpen()) return null;
|
|
15
|
+
const projectId = getSessionMetadata(sessionKey)?.projectId;
|
|
16
|
+
if (!projectId) return null;
|
|
17
|
+
return new ProjectStore().get(projectId);
|
|
18
|
+
}
|
|
19
|
+
function getProjectWorkspacePathForSession(sessionKey) {
|
|
20
|
+
return projectWorkspacePath(getProjectForSession(sessionKey));
|
|
21
|
+
}
|
|
22
|
+
//#endregion
|
|
23
|
+
export { getProjectForSession, getProjectWorkspacePathForSession, resolveProjectWorkspacePath };
|
|
24
|
+
|
|
25
|
+
//# sourceMappingURL=workspace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace.js","names":[],"sources":["../../../src/projects/workspace.ts"],"sourcesContent":["import { resolveEffectiveAgentProfileForSession } from '../config/agent-profile.js';\nimport type { Config } from '../config/schema.js';\nimport {\n getSessionMetadata,\n isXopcDatabaseOpen,\n} from '../storage/sqlite/index.js';\nimport { projectWorkspacePath } from '../session/session-workspace.js';\nimport { ProjectStore } from './project-store.js';\nimport type { Project } from './types.js';\n\nexport function resolveProjectWorkspacePath(\n config: Config,\n sessionKey: string,\n project: Project | null,\n): string {\n const projectWorkspace = projectWorkspacePath(project);\n if (projectWorkspace) {\n return projectWorkspace;\n }\n return resolveEffectiveAgentProfileForSession(config, sessionKey).resolvedWorkspacePath;\n}\n\nexport function getProjectForSession(sessionKey: string): Project | null {\n if (!isXopcDatabaseOpen()) {\n return null;\n }\n const projectId = getSessionMetadata(sessionKey)?.projectId;\n if (!projectId) {\n return null;\n }\n return new ProjectStore().get(projectId);\n}\n\nexport function getProjectWorkspacePathForSession(sessionKey: string): string | null {\n return projectWorkspacePath(getProjectForSession(sessionKey));\n}\n"],"mappings":";;;;;;;AAUA,SAAgB,4BACd,QACA,YACA,SACQ;CACR,MAAM,mBAAmB,qBAAqB,QAAQ;AACtD,KAAI,iBACF,QAAO;AAET,QAAO,uCAAuC,QAAQ,WAAW,CAAC;;AAGpE,SAAgB,qBAAqB,YAAoC;AACvE,KAAI,CAAC,oBAAoB,CACvB,QAAO;CAET,MAAM,YAAY,mBAAmB,WAAW,EAAE;AAClD,KAAI,CAAC,UACH,QAAO;AAET,QAAO,IAAI,cAAc,CAAC,IAAI,UAAU;;AAG1C,SAAgB,kCAAkC,YAAmC;AACnF,QAAO,qBAAqB,qBAAqB,WAAW,CAAC"}
|