wind-agent-cli 1.37.2 → 1.38.0
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/LICENSE +718 -718
- package/README.md +17 -2
- package/dist/api-docs.html +901 -901
- package/dist/assets/{CodeEditor-B2Wf7Fg0.js → CodeEditor-FvgsnJ7J.js} +6 -6
- package/dist/assets/FileTree-NLULrBDi.js +1 -0
- package/dist/assets/GitPanel-51KUBbEW.js +4 -0
- package/dist/assets/{MarkdownPreview-C0tqYnVu.js → MarkdownPreview-PEEWVWeS.js} +17 -27
- package/dist/assets/Shell-BEx66cW_.js +76 -0
- package/dist/assets/Shell-DrlLKa8f.css +1 -0
- package/dist/assets/StandaloneShell-BkuUCPZP.js +1 -0
- package/dist/assets/TaskMasterPanel-DfQG80SF.js +2 -0
- package/dist/assets/abnfDiagram-N423BO3Z-Cc0ul87U.js +1 -0
- package/dist/assets/arc-BAuugHw_.js +1 -0
- package/dist/assets/architectureDiagram-T3A2C74G-DA3G7QZD.js +36 -0
- package/dist/assets/{blockDiagram-VBNYF7ZC-DpaEf3mv.js → blockDiagram-VBNYF7ZC-tJ12IJs3.js} +4 -4
- package/dist/assets/c4Diagram-5PPSVZJV-5BTMCXL4.js +10 -0
- package/dist/assets/channel-BGDgNNQz.js +1 -0
- package/dist/assets/{chunk-2GRJ4B5K-DoSdNo8u.js → chunk-2GRJ4B5K-BPaI06Ou.js} +1 -1
- package/dist/assets/{chunk-2Q5K7J3B-CE7I3uMn.js → chunk-2Q5K7J3B-HV4zmsEe.js} +1 -1
- package/dist/assets/chunk-5RXB4S5H-BAwutJoU.js +231 -0
- package/dist/assets/{chunk-5VM5RSS4-B55XgqHZ.js → chunk-5VM5RSS4-B9QAJPrv.js} +1 -1
- package/dist/assets/{chunk-6Q2QTUOP-BS1KpefW.js → chunk-6Q2QTUOP-BOIW8bzI.js} +1 -1
- package/dist/assets/chunk-GF5L2VYU-DD13o00-.js +206 -0
- package/dist/assets/{chunk-JWPE2WC7-DOtkNhMm.js → chunk-JWPE2WC7-CFBm23VK.js} +1 -1
- package/dist/assets/{chunk-KBJHAD2P-BXLjviqM.js → chunk-KBJHAD2P-C0i0v8Op.js} +1 -1
- package/dist/assets/{chunk-RYQCIY6F-C50fjNNz.js → chunk-RYQCIY6F-DfeK0taV.js} +1 -1
- package/dist/assets/{chunk-XXDRQBXY-QBYqCkb7.js → chunk-XXDRQBXY-BKWvf-QE.js} +1 -1
- package/dist/assets/classDiagram-JCYQIIEL-C2SNM4oy.js +1 -0
- package/dist/assets/classDiagram-v2-OCEON4UE-C2SNM4oy.js +1 -0
- package/dist/assets/cose-bilkent-JH36ORCC-CBE8oM7L.js +1 -0
- package/dist/assets/{cynefin-VYW2F7L2-DnJa_OlQ.js → cynefin-VYW2F7L2-DziGp35A.js} +11 -23
- package/dist/assets/cynefinDiagram-MW4NZA55-CNvtHl39.js +62 -0
- package/dist/assets/cytoscape.esm-yzknjiTM.js +321 -0
- package/dist/assets/dagre-VZM6K2ZE-Bz9lsU7m.js +4 -0
- package/dist/assets/{diagram-7IWD3JNH-pFzs9HEu.js → diagram-7IWD3JNH-CV7D3VSd.js} +5 -5
- package/dist/assets/{diagram-B4RE2ZJO-CcehQC7x.js → diagram-B4RE2ZJO-Dj4EjDNC.js} +2 -2
- package/dist/assets/diagram-LBJQPF4R-wJ6FHvf-.js +24 -0
- package/dist/assets/diagram-Q27KOJAE-DMFYMhOB.js +24 -0
- package/dist/assets/diagram-UB23O5K3-DeBSbWAI.js +41 -0
- package/dist/assets/ebnfDiagram-BXEA7PRR-2NnJSGhT.js +1 -0
- package/dist/assets/erDiagram-JOGREHBK-DrSlg8hr.js +85 -0
- package/dist/assets/feature-chat-CvOCyaLe.js +88 -0
- package/dist/assets/feature-workspace-CAB6bgPy.js +39 -0
- package/dist/assets/{flowDiagram-UKHOOZJN-CJV8fQPR.js → flowDiagram-UKHOOZJN-C0pejU6W.js} +4 -4
- package/dist/assets/ganttDiagram-PKOTCBZU-BM0VCUUz.js +292 -0
- package/dist/assets/gitGraphDiagram-DS77QQ5N-SbLG0c5_.js +106 -0
- package/dist/assets/graph-DOmOIIwC.js +1 -0
- package/dist/assets/{index-GFhXZyl2.js → index-BflGfU1C.js} +3 -3
- package/dist/assets/index-Btkf0_rU.js +1 -0
- package/dist/assets/index-Cr5MbHuj.css +1 -0
- package/dist/assets/index-Gqazqfs3.js +1 -0
- package/dist/assets/index-nyrkoQK6.js +35 -0
- package/dist/assets/infoDiagram-6WML65LV-Cf5DSa66.js +2 -0
- package/dist/assets/ishikawaDiagram-WSZJBQD7-DwyFutKy.js +70 -0
- package/dist/assets/journeyDiagram-NVQOT4AX-Df0FRhLo.js +139 -0
- package/dist/assets/{kanban-definition-27J2QSJJ-B3iL0ztJ.js → kanban-definition-27J2QSJJ-HmpbjrZz.js} +6 -6
- package/dist/assets/{layout-D6BstSzF.js → layout-D-LzfAck.js} +1 -1
- package/dist/assets/{linear-Cwe9dEKA.js → linear-DOM01LBe.js} +1 -1
- package/dist/assets/map-DxJ2ADlA.js +1 -0
- package/dist/assets/mermaid.core-C2Ma-_S6.js +306 -0
- package/dist/assets/{mindmap-definition-FAOFIHXS-BgfBYMzr.js → mindmap-definition-FAOFIHXS-B4GOIn76.js} +4 -4
- package/dist/assets/pegDiagram-VL7TDLO6-BHur7aH2.js +1 -0
- package/dist/assets/{pieDiagram-7S7Q4E2Y-DeSrxc4I.js → pieDiagram-7S7Q4E2Y-Cw0UELLV.js} +2 -2
- package/dist/assets/quadrantDiagram-CIZ2JOQS-CB2BrX3g.js +7 -0
- package/dist/assets/railroadDiagram-AXF67PYL-DPYZYmLX.js +1 -0
- package/dist/assets/requirementDiagram-LRYGKXZP-DSX4IJ1n.js +84 -0
- package/dist/assets/sankeyDiagram-W5VNT64P-TenC3ZQo.js +40 -0
- package/dist/assets/sequenceDiagram-SI44F4Z6-DltGsf3F.js +162 -0
- package/dist/assets/sizeCapture-X5ZJPWSS-D7llwbJZ.js +1 -0
- package/dist/assets/stateDiagram-OKZ733FA-C-hAvbnY.js +1 -0
- package/dist/assets/stateDiagram-v2-UEYNNEHI-DaYSFcRQ.js +1 -0
- package/dist/assets/swimlanes-SLNWSIFB-DWD30fv6.js +2 -0
- package/dist/assets/swimlanesDiagram-ULZ7WXOC-LTkF2T6t.js +8 -0
- package/dist/assets/timeline-definition-Z64GVDOM-quWmimSE.js +120 -0
- package/dist/assets/vendor-data-DsEZeNPr.js +4 -0
- package/dist/assets/vendor-i18n-B6HjLCnN.js +1 -0
- package/dist/assets/vendor-markdown-DkITEES2.js +298 -0
- package/dist/assets/vendor-react-C2GTiUCy.js +10 -0
- package/dist/assets/vendor-ui-CAUHSABu.js +49 -0
- package/dist/assets/vennDiagram-T6HMQDX7-aUQcm8h5.js +34 -0
- package/dist/assets/{wardleyDiagram-T6FBY63Y-BNCpsFZV.js → wardleyDiagram-T6FBY63Y-BZ0bwsFQ.js} +2 -2
- package/dist/assets/workbox-window.prod.es5-BBnX5xw4.js +2 -0
- package/dist/assets/xychartDiagram-ELKLHX3M-DOVzAq63.js +7 -0
- package/dist/clear-cache.html +85 -85
- package/dist/convert-icons.md +52 -52
- package/dist/favicon.png +0 -0
- package/dist/favicon.svg +8 -8
- package/dist/generate-icons.js +48 -48
- package/dist/icons/codex-white.svg +3 -3
- package/dist/icons/codex.svg +3 -3
- package/dist/icons/cursor-white.svg +11 -11
- package/dist/icons/icon-128x128.png +0 -0
- package/dist/icons/icon-128x128.svg +11 -11
- package/dist/icons/icon-144x144.png +0 -0
- package/dist/icons/icon-144x144.svg +11 -11
- package/dist/icons/icon-152x152.png +0 -0
- package/dist/icons/icon-152x152.svg +11 -11
- package/dist/icons/icon-180x180.png +0 -0
- package/dist/icons/icon-192x192.png +0 -0
- package/dist/icons/icon-192x192.svg +11 -11
- package/dist/icons/icon-384x384.png +0 -0
- package/dist/icons/icon-384x384.svg +11 -11
- package/dist/icons/icon-512x512.png +0 -0
- package/dist/icons/icon-512x512.svg +11 -11
- package/dist/icons/icon-72x72.png +0 -0
- package/dist/icons/icon-72x72.svg +11 -11
- package/dist/icons/icon-96x96.png +0 -0
- package/dist/icons/icon-96x96.svg +11 -11
- package/dist/icons/icon-maskable-192x192.png +0 -0
- package/dist/icons/icon-maskable-512x512.png +0 -0
- package/dist/icons/icon-template.svg +11 -11
- package/dist/icons/new-icon.png +0 -0
- package/dist/index.html +48 -58
- package/dist/logo-128.png +0 -0
- package/dist/logo-256.png +0 -0
- package/dist/logo.svg +17 -17
- package/dist/manifest.webmanifest +1 -0
- package/dist/push-sw.js +48 -0
- package/dist/screenshots/setup-screen-mobile.png +0 -0
- package/dist/screenshots/setup-screen.png +0 -0
- package/dist/sw.js +1 -124
- package/dist/workbox-ae5c0bb2.js +1 -0
- package/dist-server/server/index.js +1 -1
- package/dist-server/server/index.js.map +1 -1
- package/dist-server/server/load-env.js +4 -2
- package/dist-server/server/load-env.js.map +1 -1
- package/dist-server/server/modules/agent/agent.routes.js +1 -1
- package/dist-server/server/modules/agent/agent.routes.js.map +1 -1
- package/dist-server/server/modules/browser-use/browser-use.service.js +1 -1
- package/dist-server/server/modules/browser-use/browser-use.service.js.map +1 -1
- package/dist-server/server/modules/cli/cli.service.js +37 -37
- package/dist-server/server/modules/cli/cli.service.js.map +1 -1
- package/dist-server/server/modules/cli/sandbox.service.js +43 -43
- package/dist-server/server/modules/cli/sandbox.service.js.map +1 -1
- package/dist-server/server/modules/cli/tests/cli-environment-bootstrap.test.js +74 -74
- package/dist-server/server/modules/commands/commands.routes.js +25 -25
- package/dist-server/server/modules/commands/commands.routes.js.map +1 -1
- package/dist-server/server/modules/commands/tests/commands.test.js +1 -1
- package/dist-server/server/modules/commands/tests/commands.test.js.map +1 -1
- package/dist-server/server/modules/database/connection.js +1 -1
- package/dist-server/server/modules/database/connection.js.map +1 -1
- package/dist-server/server/modules/database/migrations.js +190 -190
- package/dist-server/server/modules/database/repositories/api-keys.js +3 -3
- package/dist-server/server/modules/database/repositories/github-tokens.js +2 -2
- package/dist-server/server/modules/database/repositories/notification-channel-endpoints.js +28 -28
- package/dist-server/server/modules/database/repositories/notification-preferences.js +4 -4
- package/dist-server/server/modules/database/repositories/projects.db.js +61 -61
- package/dist-server/server/modules/database/repositories/provider-models.js +35 -35
- package/dist-server/server/modules/database/repositories/push-subscriptions.js +5 -5
- package/dist-server/server/modules/database/repositories/scan-state.db.js +5 -5
- package/dist-server/server/modules/database/repositories/sessions.db.js +93 -93
- package/dist-server/server/modules/database/schema.js +177 -177
- package/dist-server/server/modules/database/tests/projects.db.integration.test.js +3 -2
- package/dist-server/server/modules/database/tests/projects.db.integration.test.js.map +1 -1
- package/dist-server/server/modules/database/tests/provider-models.db.integration.test.js +6 -6
- package/dist-server/server/modules/database/tests/sessions-provider-mapping.test.js +4 -3
- package/dist-server/server/modules/database/tests/sessions-provider-mapping.test.js.map +1 -1
- package/dist-server/server/modules/database/tests/sessions.db.integration.test.js +2 -1
- package/dist-server/server/modules/database/tests/sessions.db.integration.test.js.map +1 -1
- package/dist-server/server/modules/git/git.routes.js +17 -17
- package/dist-server/server/modules/notifications/services/notification-orchestrator.service.js +1 -1
- package/dist-server/server/modules/notifications/services/notification-orchestrator.service.js.map +1 -1
- package/dist-server/server/modules/notifications/vapid-keys.service.js +1 -1
- package/dist-server/server/modules/notifications/vapid-keys.service.js.map +1 -1
- package/dist-server/server/modules/projects/tests/project-management.service.test.js +2 -1
- package/dist-server/server/modules/projects/tests/project-management.service.test.js.map +1 -1
- package/dist-server/server/modules/providers/list/codex/codex-app-server.client.js +2 -2
- package/dist-server/server/modules/providers/list/codex/codex-app-server.client.js.map +1 -1
- package/dist-server/server/modules/providers/list/codex/codex-models.provider.js +1 -1
- package/dist-server/server/modules/providers/list/codex/codex-models.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/cursor/cursor-models.provider.js +1 -1
- package/dist-server/server/modules/providers/list/cursor/cursor-models.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/cursor/cursor-session-synchronizer.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/opencode/opencode-models.provider.js +13 -13
- package/dist-server/server/modules/providers/list/opencode/opencode-runtime.provider.js +9 -9
- package/dist-server/server/modules/providers/list/opencode/opencode-runtime.provider.test.js +17 -17
- package/dist-server/server/modules/providers/list/opencode/opencode-session-synchronizer.provider.js +25 -25
- package/dist-server/server/modules/providers/list/opencode/opencode-sessions.provider.js +27 -27
- package/dist-server/server/modules/providers/services/provider-token-usage.service.js +9 -9
- package/dist-server/server/modules/providers/services/sessions.service.js +1 -1
- package/dist-server/server/modules/providers/tests/claude-auth.test.js +8 -0
- package/dist-server/server/modules/providers/tests/claude-auth.test.js.map +1 -1
- package/dist-server/server/modules/providers/tests/codex-sessions.test.js +1 -1
- package/dist-server/server/modules/providers/tests/codex-sessions.test.js.map +1 -1
- package/dist-server/server/modules/providers/tests/mcp.test.js +3 -3
- package/dist-server/server/modules/providers/tests/opencode-sessions.test.js +98 -98
- package/dist-server/server/modules/providers/tests/opencode-sessions.test.js.map +1 -1
- package/dist-server/server/modules/providers/tests/provider-token-usage.service.test.js +18 -18
- package/dist-server/server/modules/providers/tests/provider.routes.test.js +1 -1
- package/dist-server/server/modules/providers/tests/provider.routes.test.js.map +1 -1
- package/dist-server/server/modules/system/system.service.js +1 -1
- package/dist-server/server/modules/system/system.service.js.map +1 -1
- package/dist-server/server/modules/system/tests/system.service.test.js +1 -1
- package/dist-server/server/modules/system/tests/system.service.test.js.map +1 -1
- package/dist-server/server/modules/taskmaster/taskmaster.routes.js +423 -422
- package/dist-server/server/modules/taskmaster/taskmaster.routes.js.map +1 -1
- package/dist-server/server/modules/websocket/services/shell-websocket.service.js +1 -1
- package/dist-server/server/modules/websocket/services/shell-websocket.service.js.map +1 -1
- package/dist-server/server/modules/worktrees/services/worktree-list.service.js +1 -1
- package/dist-server/server/modules/worktrees/services/worktree-open.service.js +1 -1
- package/dist-server/server/modules/worktrees/services/worktree-remove.service.js +1 -1
- package/electron/cloud.js +260 -260
- package/electron/desktopNotifications.js +378 -378
- package/electron/desktopWindow.js +766 -766
- package/electron/launcher/index.html +14 -14
- package/electron/launcher/launcher.css +801 -801
- package/electron/launcher/launcher.js +687 -687
- package/electron/localServer.js +549 -549
- package/electron/main.js +944 -944
- package/electron/preload.cjs +60 -60
- package/electron/scripts/generate-macos-icon.js +62 -62
- package/electron/serverInstaller.js +277 -277
- package/electron/tabs.js +87 -87
- package/electron/viewHost.js +331 -331
- package/package.json +262 -247
- package/public/api-docs.html +901 -901
- package/scripts/build-client.mjs +30 -0
- package/scripts/fix-node-pty.js +67 -67
- package/scripts/generate-pwa-icons.ps1 +33 -0
- package/scripts/promote-dist-server.mjs +50 -50
- package/scripts/release/build-server-bundle.js +176 -176
- package/scripts/release/prepare-desktop-app.js +152 -152
- package/scripts/verify-pwa-build.mjs +37 -0
- package/server/index.ts +399 -399
- package/server/load-env.ts +49 -47
- package/server/modules/agent/agent.module.ts +52 -52
- package/server/modules/agent/agent.routes.ts +1287 -1287
- package/server/modules/agent/index.ts +2 -2
- package/server/modules/agent/tests/agent.routes.test.ts +205 -205
- package/server/modules/assets/assets.routes.ts +150 -150
- package/server/modules/assets/index.ts +3 -3
- package/server/modules/assets/services/image-assets.service.ts +127 -127
- package/server/modules/assets/tests/image-assets.service.test.ts +74 -74
- package/server/modules/auth/auth.middleware.ts +163 -163
- package/server/modules/auth/auth.module.ts +38 -38
- package/server/modules/auth/auth.routes.ts +57 -57
- package/server/modules/auth/auth.service.ts +155 -155
- package/server/modules/auth/index.ts +9 -9
- package/server/modules/auth/tests/auth.service.test.ts +95 -95
- package/server/modules/browser-use/browser-use-mcp.routes.ts +120 -120
- package/server/modules/browser-use/browser-use-mcp.ts +386 -386
- package/server/modules/browser-use/browser-use-runtime.ts +10 -10
- package/server/modules/browser-use/browser-use.routes.ts +96 -96
- package/server/modules/browser-use/browser-use.service.ts +836 -836
- package/server/modules/browser-use/index.ts +11 -11
- package/server/modules/browser-use/tests/browser-use.service.test.ts +10 -10
- package/server/modules/cli/cli.module.ts +93 -93
- package/server/modules/cli/cli.service.ts +248 -248
- package/server/modules/cli/cli.ts +19 -19
- package/server/modules/cli/index.ts +2 -2
- package/server/modules/cli/sandbox.service.ts +398 -398
- package/server/modules/cli/tests/cli-environment-bootstrap.test.ts +186 -186
- package/server/modules/cli/tests/cli.service.test.ts +86 -86
- package/server/modules/cli/tests/sandbox.service.test.ts +58 -58
- package/server/modules/commands/commands.module.ts +22 -22
- package/server/modules/commands/commands.routes.ts +587 -587
- package/server/modules/commands/index.ts +2 -2
- package/server/modules/commands/tests/commands.test.ts +110 -110
- package/server/modules/database/connection.ts +144 -143
- package/server/modules/database/index.ts +17 -17
- package/server/modules/database/init-db.ts +17 -17
- package/server/modules/database/migrations.ts +515 -515
- package/server/modules/database/repositories/api-keys.ts +119 -119
- package/server/modules/database/repositories/app-config.ts +53 -53
- package/server/modules/database/repositories/credentials.ts +106 -106
- package/server/modules/database/repositories/github-tokens.ts +100 -100
- package/server/modules/database/repositories/notification-channel-endpoints.ts +153 -153
- package/server/modules/database/repositories/notification-preferences.ts +117 -117
- package/server/modules/database/repositories/projects.db.ts +196 -196
- package/server/modules/database/repositories/provider-models.ts +168 -168
- package/server/modules/database/repositories/push-subscriptions.ts +80 -80
- package/server/modules/database/repositories/scan-state.db.ts +42 -42
- package/server/modules/database/repositories/sessions.db.ts +524 -524
- package/server/modules/database/repositories/users.ts +140 -140
- package/server/modules/database/repositories/vapid-keys.ts +57 -57
- package/server/modules/database/schema.ts +210 -210
- package/server/modules/database/tests/projects.db.integration.test.ts +73 -72
- package/server/modules/database/tests/provider-models.db.integration.test.ts +125 -125
- package/server/modules/database/tests/sessions-provider-mapping.test.ts +110 -109
- package/server/modules/database/tests/sessions.db.integration.test.ts +117 -116
- package/server/modules/file-tree/file-tree.module.ts +116 -116
- package/server/modules/file-tree/file-tree.routes.ts +258 -258
- package/server/modules/file-tree/file-tree.service.ts +675 -675
- package/server/modules/file-tree/index.ts +2 -2
- package/server/modules/file-tree/tests/file-tree.routes.test.ts +157 -157
- package/server/modules/file-tree/tests/file-tree.service.test.ts +371 -371
- package/server/modules/git/git-branch.service.ts +43 -43
- package/server/modules/git/git-parsing.service.ts +66 -66
- package/server/modules/git/git.module.ts +22 -22
- package/server/modules/git/git.routes.ts +1596 -1596
- package/server/modules/git/index.ts +2 -2
- package/server/modules/git/tests/git-branch.service.test.ts +60 -60
- package/server/modules/git/tests/git-init.routes.test.ts +132 -132
- package/server/modules/git/tests/git.test.ts +106 -106
- package/server/modules/notifications/index.ts +24 -24
- package/server/modules/notifications/notifications.routes.ts +127 -127
- package/server/modules/notifications/services/desktop-notification-clients.service.ts +124 -124
- package/server/modules/notifications/services/notification-orchestrator.service.js +310 -310
- package/server/modules/notifications/tests/notification-orchestrator.integration.test.ts +55 -55
- package/server/modules/notifications/vapid-keys.service.ts +38 -38
- package/server/modules/notifications/websocket/desktop-notifications-websocket.service.ts +109 -109
- package/server/modules/plugins/index.ts +9 -9
- package/server/modules/plugins/plugin-process.service.ts +217 -217
- package/server/modules/plugins/plugin-registry.service.ts +459 -459
- package/server/modules/plugins/plugins.module.ts +33 -33
- package/server/modules/plugins/plugins.routes.ts +66 -66
- package/server/modules/plugins/plugins.service.ts +147 -147
- package/server/modules/plugins/tests/plugins.service.test.ts +32 -32
- package/server/modules/projects/index.ts +11 -11
- package/server/modules/projects/projects.routes.ts +273 -273
- package/server/modules/projects/services/project-clone.service.ts +323 -323
- package/server/modules/projects/services/project-delete.service.ts +90 -90
- package/server/modules/projects/services/project-management.service.ts +144 -144
- package/server/modules/projects/services/project-star.service.ts +78 -78
- package/server/modules/projects/services/projects-has-taskmaster.service.ts +248 -248
- package/server/modules/projects/services/projects-with-sessions-fetch.service.ts +314 -314
- package/server/modules/projects/tests/project-clone.service.test.ts +183 -183
- package/server/modules/projects/tests/project-management.service.test.ts +118 -117
- package/server/modules/projects/tests/project-star.service.test.ts +123 -123
- package/server/modules/projects/tests/projects-has-taskmaster.service.test.ts +105 -105
- package/server/modules/providers/README.md +380 -380
- package/server/modules/providers/index.ts +10 -10
- package/server/modules/providers/list/claude/claude-auth.provider.ts +160 -160
- package/server/modules/providers/list/claude/claude-mcp.provider.ts +135 -135
- package/server/modules/providers/list/claude/claude-models.provider.ts +294 -294
- package/server/modules/providers/list/claude/claude-runtime.provider.js +1068 -1068
- package/server/modules/providers/list/claude/claude-session-synchronizer.provider.ts +203 -203
- package/server/modules/providers/list/claude/claude-sessions.provider.ts +684 -684
- package/server/modules/providers/list/claude/claude-skills.provider.ts +265 -265
- package/server/modules/providers/list/claude/claude.provider.ts +30 -30
- package/server/modules/providers/list/codex/codex-app-server.client.ts +2 -2
- package/server/modules/providers/list/codex/codex-auth.provider.ts +100 -100
- package/server/modules/providers/list/codex/codex-mcp.provider.ts +135 -135
- package/server/modules/providers/list/codex/codex-models.provider.ts +123 -123
- package/server/modules/providers/list/codex/codex-runtime.provider.js +533 -533
- package/server/modules/providers/list/codex/codex-session-synchronizer.provider.ts +203 -203
- package/server/modules/providers/list/codex/codex-sessions.provider.ts +938 -938
- package/server/modules/providers/list/codex/codex-skills.provider.ts +73 -73
- package/server/modules/providers/list/codex/codex.provider.ts +28 -28
- package/server/modules/providers/list/cursor/cursor-auth.provider.ts +143 -143
- package/server/modules/providers/list/cursor/cursor-mcp.provider.ts +108 -108
- package/server/modules/providers/list/cursor/cursor-models.provider.ts +119 -119
- package/server/modules/providers/list/cursor/cursor-runtime.provider.js +385 -385
- package/server/modules/providers/list/cursor/cursor-session-synchronizer.provider.ts +158 -159
- package/server/modules/providers/list/cursor/cursor-sessions.provider.ts +654 -654
- package/server/modules/providers/list/cursor/cursor-skills.provider.ts +39 -39
- package/server/modules/providers/list/cursor/cursor.provider.ts +30 -30
- package/server/modules/providers/list/opencode/opencode-auth.provider.ts +110 -110
- package/server/modules/providers/list/opencode/opencode-mcp.provider.ts +228 -228
- package/server/modules/providers/list/opencode/opencode-models.provider.ts +203 -203
- package/server/modules/providers/list/opencode/opencode-runtime.provider.js +434 -434
- package/server/modules/providers/list/opencode/opencode-runtime.provider.test.js +261 -261
- package/server/modules/providers/list/opencode/opencode-session-synchronizer.provider.ts +179 -179
- package/server/modules/providers/list/opencode/opencode-sessions.provider.ts +500 -500
- package/server/modules/providers/list/opencode/opencode-skills.provider.ts +78 -78
- package/server/modules/providers/list/opencode/opencode.provider.ts +30 -30
- package/server/modules/providers/provider.registry.ts +36 -36
- package/server/modules/providers/provider.routes.ts +877 -877
- package/server/modules/providers/services/mcp.service.ts +109 -109
- package/server/modules/providers/services/provider-auth.service.ts +26 -26
- package/server/modules/providers/services/provider-capabilities.service.ts +97 -97
- package/server/modules/providers/services/provider-models.service.ts +401 -401
- package/server/modules/providers/services/provider-runtime.service.ts +108 -108
- package/server/modules/providers/services/provider-token-usage.service.ts +357 -357
- package/server/modules/providers/services/session-conversations-search.service.ts +1321 -1321
- package/server/modules/providers/services/session-synchronizer.service.ts +74 -74
- package/server/modules/providers/services/sessions-watcher.service.ts +247 -247
- package/server/modules/providers/services/sessions.service.ts +471 -471
- package/server/modules/providers/services/skills.service.ts +39 -39
- package/server/modules/providers/shared/base/abstract.provider.ts +32 -32
- package/server/modules/providers/shared/mcp/mcp.provider.ts +151 -151
- package/server/modules/providers/shared/skills/skills.provider.ts +287 -287
- package/server/modules/providers/tests/claude-auth.test.ts +157 -150
- package/server/modules/providers/tests/claude-sessions.test.ts +61 -61
- package/server/modules/providers/tests/codex-sessions.test.ts +231 -231
- package/server/modules/providers/tests/mcp.test.ts +349 -349
- package/server/modules/providers/tests/opencode-models.test.ts +41 -41
- package/server/modules/providers/tests/opencode-sessions.test.ts +522 -522
- package/server/modules/providers/tests/provider-attachment-history.test.ts +247 -247
- package/server/modules/providers/tests/provider-models.service.test.ts +353 -353
- package/server/modules/providers/tests/provider-runtime.service.test.ts +138 -138
- package/server/modules/providers/tests/provider-token-usage.service.test.ts +186 -186
- package/server/modules/providers/tests/provider.routes.test.ts +244 -244
- package/server/modules/providers/tests/sessions-details.test.ts +73 -73
- package/server/modules/providers/tests/sessions.service.test.ts +127 -127
- package/server/modules/providers/tests/skills.test.ts +692 -692
- package/server/modules/settings/index.ts +2 -2
- package/server/modules/settings/settings.module.ts +50 -50
- package/server/modules/settings/settings.routes.ts +51 -51
- package/server/modules/settings/settings.service.ts +186 -186
- package/server/modules/settings/tests/settings.service.test.ts +54 -54
- package/server/modules/system/index.ts +2 -2
- package/server/modules/system/system.module.ts +62 -62
- package/server/modules/system/system.routes.ts +21 -21
- package/server/modules/system/system.service.ts +76 -76
- package/server/modules/system/tests/system.service.test.ts +118 -118
- package/server/modules/taskmaster/index.ts +2 -2
- package/server/modules/taskmaster/taskmaster.module.ts +24 -24
- package/server/modules/taskmaster/taskmaster.routes.ts +1483 -1482
- package/server/modules/taskmaster/taskmaster.service.ts +132 -132
- package/server/modules/taskmaster/tests/taskmaster.routes.test.ts +144 -144
- package/server/modules/taskmaster/tests/taskmaster.service.test.ts +97 -97
- package/server/modules/user/index.ts +2 -2
- package/server/modules/user/tests/user.service.test.ts +61 -61
- package/server/modules/user/user.module.ts +58 -58
- package/server/modules/user/user.routes.ts +50 -50
- package/server/modules/user/user.service.ts +85 -85
- package/server/modules/voice/index.ts +2 -2
- package/server/modules/voice/tests/voice.service.test.ts +98 -98
- package/server/modules/voice/voice.module.ts +47 -47
- package/server/modules/voice/voice.routes.ts +113 -113
- package/server/modules/voice/voice.service.ts +192 -192
- package/server/modules/websocket/README.md +273 -273
- package/server/modules/websocket/index.ts +3 -3
- package/server/modules/websocket/services/chat-run-registry.service.ts +343 -343
- package/server/modules/websocket/services/chat-session-writer.service.ts +145 -145
- package/server/modules/websocket/services/chat-websocket.service.ts +425 -425
- package/server/modules/websocket/services/plugin-websocket-proxy.service.ts +65 -65
- package/server/modules/websocket/services/shell-websocket.service.ts +503 -503
- package/server/modules/websocket/services/websocket-auth.service.ts +59 -59
- package/server/modules/websocket/services/websocket-server.service.ts +124 -124
- package/server/modules/websocket/services/websocket-state.service.ts +16 -16
- package/server/modules/websocket/services/websocket-writer.service.ts +38 -38
- package/server/modules/websocket/tests/chat-attachment-filter.test.ts +59 -59
- package/server/modules/websocket/tests/chat-run-registry.test.ts +282 -282
- package/server/modules/websocket/tests/shell-websocket.service.test.ts +100 -100
- package/server/modules/websocket/tests/websocket-heartbeat.service.test.ts +78 -78
- package/server/modules/worktrees/index.ts +2 -2
- package/server/modules/worktrees/services/worktree-create-and-open.service.ts +53 -53
- package/server/modules/worktrees/services/worktree-create.service.ts +104 -104
- package/server/modules/worktrees/services/worktree-git.service.ts +207 -207
- package/server/modules/worktrees/services/worktree-list.service.ts +143 -143
- package/server/modules/worktrees/services/worktree-merge.service.ts +157 -157
- package/server/modules/worktrees/services/worktree-open.service.ts +85 -85
- package/server/modules/worktrees/services/worktree-remove.service.ts +88 -88
- package/server/modules/worktrees/tests/worktree-create-and-open.service.test.ts +68 -68
- package/server/modules/worktrees/tests/worktree-create.service.test.ts +142 -142
- package/server/modules/worktrees/tests/worktree-git.service.test.ts +84 -84
- package/server/modules/worktrees/tests/worktree-list.service.test.ts +45 -45
- package/server/modules/worktrees/tests/worktree-merge.service.test.ts +213 -213
- package/server/modules/worktrees/tests/worktree-open.service.test.ts +122 -122
- package/server/modules/worktrees/tests/worktree-remove.service.test.ts +227 -227
- package/server/modules/worktrees/tests/worktrees.routes.test.ts +199 -199
- package/server/modules/worktrees/worktrees.module.ts +113 -113
- package/server/modules/worktrees/worktrees.routes.ts +116 -116
- package/server/shared/claude-cli-path.ts +139 -139
- package/server/shared/frontmatter.ts +18 -18
- package/server/shared/image-attachments.ts +435 -435
- package/server/shared/interfaces.ts +179 -179
- package/server/shared/tests/claude-cli-path.test.ts +61 -61
- package/server/shared/tests/image-attachments.test.ts +353 -353
- package/server/shared/tests/slice-tail-page.test.ts +42 -42
- package/server/shared/types.ts +1228 -1228
- package/server/shared/utils.ts +1161 -1161
- package/server/tsconfig.json +40 -40
- package/shared/networkHosts.js +22 -22
- package/dist/assets/FileTree-N2IkkHlv.js +0 -127
- package/dist/assets/GitPanel-DZCeuFZ2.js +0 -29
- package/dist/assets/PluginTabContent-Bnuf-fb8.js +0 -1
- package/dist/assets/Shell-BfFnMZ-f.js +0 -81
- package/dist/assets/Shell-qxJ8_QYu.css +0 -32
- package/dist/assets/StandaloneShell-QmyYwNAl.js +0 -1
- package/dist/assets/TaskMasterPanel-fMsmvN9L.js +0 -32
- package/dist/assets/abnfDiagram-N423BO3Z-DjPU7HLs.js +0 -1
- package/dist/assets/arc-Pdq6Tvr3.js +0 -1
- package/dist/assets/architectureDiagram-T3A2C74G-D0JnT0Vh.js +0 -36
- package/dist/assets/c4Diagram-5PPSVZJV-MpqlPGFi.js +0 -10
- package/dist/assets/channel-Bm0ZLE4z.js +0 -1
- package/dist/assets/chunk-5RXB4S5H-B4UQ8snD.js +0 -231
- package/dist/assets/chunk-GF5L2VYU-DkEPedJP.js +0 -206
- package/dist/assets/classDiagram-JCYQIIEL-DqEOcNxw.js +0 -1
- package/dist/assets/classDiagram-v2-OCEON4UE-DqEOcNxw.js +0 -1
- package/dist/assets/code-xml-VK1YfShP.js +0 -6
- package/dist/assets/cose-bilkent-JH36ORCC-DrVTo1Nh.js +0 -1
- package/dist/assets/cynefinDiagram-MW4NZA55-CCxBjw9E.js +0 -62
- package/dist/assets/cytoscape.esm-C10L9Icf.js +0 -331
- package/dist/assets/dagre-VZM6K2ZE-C_GvE4lu.js +0 -4
- package/dist/assets/diagram-LBJQPF4R-hfKcrrxe.js +0 -24
- package/dist/assets/diagram-Q27KOJAE-C1semJfK.js +0 -24
- package/dist/assets/diagram-UB23O5K3-57hvXQXO.js +0 -41
- package/dist/assets/ebnfDiagram-BXEA7PRR-9KIAlAVw.js +0 -1
- package/dist/assets/erDiagram-JOGREHBK-B7OzJ767.js +0 -85
- package/dist/assets/ganttDiagram-PKOTCBZU-CbMNWWQu.js +0 -292
- package/dist/assets/gitGraphDiagram-DS77QQ5N-I_vZ5waO.js +0 -106
- package/dist/assets/graph-Cx-EqisW.js +0 -1
- package/dist/assets/index-DFnVoqpx.js +0 -1174
- package/dist/assets/index-DlSeAkw_.js +0 -11
- package/dist/assets/index-ZHwIojzi.js +0 -1
- package/dist/assets/index-t1w8KNxn.css +0 -1
- package/dist/assets/infoDiagram-6WML65LV-Dh20Tsbq.js +0 -2
- package/dist/assets/ishikawaDiagram-WSZJBQD7-DH2Sm3ko.js +0 -70
- package/dist/assets/journeyDiagram-NVQOT4AX-BNFQqlVu.js +0 -139
- package/dist/assets/map-CV9uif0g.js +0 -1
- package/dist/assets/mermaid.core-BYRQSshi.js +0 -312
- package/dist/assets/pegDiagram-VL7TDLO6-CNYpECr8.js +0 -1
- package/dist/assets/quadrantDiagram-CIZ2JOQS-BXVVQsa6.js +0 -7
- package/dist/assets/railroadDiagram-AXF67PYL-JTroIW8F.js +0 -1
- package/dist/assets/requirementDiagram-LRYGKXZP-C1Z_inLz.js +0 -84
- package/dist/assets/sankeyDiagram-W5VNT64P-DCJgKFUk.js +0 -40
- package/dist/assets/sequenceDiagram-SI44F4Z6-D8Wrx5Vc.js +0 -162
- package/dist/assets/sizeCapture-X5ZJPWSS-CXqD68vD.js +0 -1
- package/dist/assets/stateDiagram-OKZ733FA-CF0Ekqjo.js +0 -1
- package/dist/assets/stateDiagram-v2-UEYNNEHI-DARLpEFJ.js +0 -1
- package/dist/assets/swimlanes-SLNWSIFB-DVIax_k4.js +0 -2
- package/dist/assets/swimlanesDiagram-ULZ7WXOC-CrgDgaY8.js +0 -8
- package/dist/assets/timeline-definition-Z64GVDOM-DSqk3ApG.js +0 -120
- package/dist/assets/vendor-react-whEHfigN.js +0 -59
- package/dist/assets/vennDiagram-T6HMQDX7-DNbTqyG5.js +0 -34
- package/dist/assets/xychartDiagram-ELKLHX3M-XsVZphHr.js +0 -7
- package/dist/manifest.json +0 -61
package/server/shared/types.ts
CHANGED
|
@@ -1,298 +1,298 @@
|
|
|
1
|
-
import type { IncomingMessage } from 'node:http';
|
|
2
|
-
import type { Readable } from 'node:stream';
|
|
3
|
-
|
|
4
|
-
//----------------- HTTP RESPONSE SHAPES ------------
|
|
5
|
-
/**
|
|
6
|
-
* Canonical success envelope used by backend APIs that return a structured payload.
|
|
7
|
-
*
|
|
8
|
-
* Use this for route handlers that need a stable `success/data` shape so frontend
|
|
9
|
-
* consumers can parse responses consistently across endpoints.
|
|
10
|
-
*/
|
|
11
|
-
export type ApiSuccessShape<TData = unknown> = {
|
|
12
|
-
success: true;
|
|
13
|
-
data: TData;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Generic plain-object record used when parsing loosely typed JSON payloads.
|
|
18
|
-
*
|
|
19
|
-
* Use this only after runtime shape checks, not as a replacement for validated
|
|
20
|
-
* domain models.
|
|
21
|
-
*/
|
|
22
|
-
export type AnyRecord = Record<string, any>;
|
|
23
|
-
|
|
24
|
-
// ---------------------------
|
|
25
|
-
//----------------- WEBSOCKET TRANSPORT TYPES ------------
|
|
26
|
-
/**
|
|
27
|
-
* Minimal websocket client contract used by backend broadcaster services.
|
|
28
|
-
*
|
|
29
|
-
* Any transport object added to `connectedClients` must implement these two
|
|
30
|
-
* members so shared services can safely send JSON strings and check whether the
|
|
31
|
-
* socket is still open before broadcasting.
|
|
32
|
-
*/
|
|
33
|
-
export type RealtimeClientConnection = {
|
|
34
|
-
readyState: number;
|
|
35
|
-
send(data: string): void;
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Authenticated user payload attached to websocket upgrade requests.
|
|
40
|
-
*
|
|
41
|
-
* Platform and OSS auth flows currently use either `id` or `userId`; both are
|
|
42
|
-
* represented here so websocket handlers can resolve a stable writer user id.
|
|
43
|
-
*/
|
|
44
|
-
export type AuthenticatedWebSocketUser = {
|
|
45
|
-
id?: string | number;
|
|
46
|
-
userId?: string | number;
|
|
47
|
-
username?: string;
|
|
48
|
-
[key: string]: unknown;
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* HTTP upgrade request shape after websocket authentication succeeds.
|
|
53
|
-
*
|
|
54
|
-
* `verifyClient` populates `request.user` with the authenticated payload, and
|
|
55
|
-
* downstream websocket handlers rely on this extended request type.
|
|
56
|
-
*/
|
|
57
|
-
export type AuthenticatedWebSocketRequest = IncomingMessage & {
|
|
58
|
-
user?: AuthenticatedWebSocketUser;
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
// ---------------------------
|
|
62
|
-
//----------------- PROVIDER MESSAGE MODEL ------------
|
|
63
|
-
/**
|
|
64
|
-
* Providers supported by the unified server runtime.
|
|
65
|
-
*
|
|
66
|
-
* Use this as the source of truth whenever a function or payload needs to identify
|
|
67
|
-
* a specific LLM integration.
|
|
68
|
-
*/
|
|
69
|
-
export type LLMProvider = 'claude' | 'codex' | 'cursor' | 'opencode';
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* One selectable model row in a provider model catalog.
|
|
73
|
-
*/
|
|
74
|
-
export type ProviderModelOption = {
|
|
75
|
-
value: string;
|
|
76
|
-
label: string;
|
|
77
|
-
description?: string;
|
|
78
|
-
/** Stable SQLite row id used only by model-management actions. */
|
|
79
|
-
recordId?: number;
|
|
80
|
-
/** True for user-created rows; false for immutable
|
|
81
|
-
isCustom?: boolean;
|
|
82
|
-
effort?: {
|
|
83
|
-
default?: string;
|
|
84
|
-
values: {
|
|
85
|
-
value: string;
|
|
86
|
-
description?: string;
|
|
87
|
-
}[];
|
|
88
|
-
};
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Provider model catalog returned by `GET /api/providers/:provider/models`.
|
|
93
|
-
*/
|
|
94
|
-
export type ProviderModelsDefinition = {
|
|
95
|
-
OPTIONS: ProviderModelOption[];
|
|
96
|
-
DEFAULT: string;
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* One persisted custom-model row in the provider model library.
|
|
101
|
-
*
|
|
102
|
-
* Provider modules use this shape at the database boundary. Predefined models
|
|
103
|
-
* never use this type because they remain source-controlled in provider
|
|
104
|
-
* adapters. `modelId` is sent to the provider runtime, while `model` is the
|
|
105
|
-
* user-supplied display name shown in pickers.
|
|
106
|
-
*/
|
|
107
|
-
export type CustomProviderModelRecord = {
|
|
108
|
-
recordId: number;
|
|
109
|
-
provider: LLMProvider;
|
|
110
|
-
modelId: string;
|
|
111
|
-
model: string;
|
|
112
|
-
sortOrder: number;
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* User-editable values accepted when creating or changing a custom model.
|
|
117
|
-
*
|
|
118
|
-
* `id` must be the exact provider-facing model identifier and cannot contain
|
|
119
|
-
* whitespace. `model` is a concise display name. The provider is supplied by
|
|
120
|
-
* the route path so a row can never be moved across providers accidentally.
|
|
121
|
-
*/
|
|
122
|
-
export type CustomProviderModelInput = {
|
|
123
|
-
id: string;
|
|
124
|
-
model: string;
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
// ---------------------------
|
|
128
|
-
//----------------- PROVIDER ACTIVE MODEL TYPES ------------
|
|
129
|
-
/**
|
|
130
|
-
* Provider-neutral result for the model that is actively driving a session or
|
|
131
|
-
* provider runtime at the time of lookup.
|
|
132
|
-
*
|
|
133
|
-
* `model` must always be populated. Provider adapters should use the
|
|
134
|
-
* provider-specific lookup method requested by the caller, and only fall back
|
|
135
|
-
* to the provider catalog `DEFAULT` value when the active model cannot be read.
|
|
136
|
-
*/
|
|
137
|
-
export type ProviderCurrentActiveModel = {
|
|
138
|
-
model: string;
|
|
139
|
-
};
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Where a resolved session model came from.
|
|
143
|
-
*
|
|
144
|
-
* `session` means the app has recorded a model for this session (the user
|
|
145
|
-
* picked one, or the session has been sent on at least once) and that value is
|
|
146
|
-
* authoritative. `provider` means the session predates any app-recorded model
|
|
147
|
-
* and the value was read back from the provider's own session state — the case
|
|
148
|
-
* for sessions started directly in a provider CLI. `default` means neither was
|
|
149
|
-
* available and the catalog default is standing in.
|
|
150
|
-
*
|
|
151
|
-
* Routes surface this so the frontend can tell a real selection apart from a
|
|
152
|
-
* placeholder without re-deriving the precedence chain.
|
|
153
|
-
*/
|
|
154
|
-
export type ProviderSessionModelSource = 'session' | 'provider' | 'default';
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* The model one session runs with, its persisted reasoning effort when one has
|
|
158
|
-
* been recorded, and where the model answer came from.
|
|
159
|
-
*
|
|
160
|
-
* Returned by `providerModelsService.resolveSessionModel` and used by the
|
|
161
|
-
* `/models`, `/cost` and `/status` commands, the active-model route, and the
|
|
162
|
-
* composer's model picker so every surface agrees on one answer.
|
|
163
|
-
*/
|
|
164
|
-
export type ProviderSessionModel = {
|
|
165
|
-
provider: LLMProvider;
|
|
166
|
-
sessionId: string | null;
|
|
167
|
-
model: string;
|
|
168
|
-
/** NULL means this session has not recorded an effort choice yet. */
|
|
169
|
-
effort: string | null;
|
|
170
|
-
source: ProviderSessionModelSource;
|
|
171
|
-
};
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* Message/event variants emitted by provider adapters and normalized transports.
|
|
175
|
-
*
|
|
176
|
-
* Keep this union in sync with event kinds produced by provider session adapters.
|
|
177
|
-
*/
|
|
178
|
-
export type MessageKind =
|
|
179
|
-
| 'text'
|
|
180
|
-
| 'tool_use'
|
|
181
|
-
| 'tool_result'
|
|
182
|
-
| 'thinking'
|
|
183
|
-
| 'stream_delta'
|
|
184
|
-
| 'stream_end'
|
|
185
|
-
| 'error'
|
|
186
|
-
| 'complete'
|
|
187
|
-
| 'status'
|
|
188
|
-
| 'permission_request'
|
|
189
|
-
| 'permission_cancelled'
|
|
190
|
-
| 'session_created'
|
|
191
|
-
| 'interactive_prompt'
|
|
192
|
-
| 'task_notification';
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Event kinds added by the chat gateway layer on top of provider message kinds.
|
|
196
|
-
*
|
|
197
|
-
* These are app-level realtime events (subscription acks, sidebar deltas,
|
|
198
|
-
* project loading progress, protocol failures) that are not produced by any
|
|
199
|
-
* provider adapter. Together with `MessageKind` they form the complete set of
|
|
200
|
-
* `kind` values a websocket client can receive, so the frontend only ever
|
|
201
|
-
* needs one kind-based switch.
|
|
202
|
-
*/
|
|
203
|
-
export type GatewayEventKind =
|
|
204
|
-
| 'chat_subscribed'
|
|
205
|
-
| 'session_upserted'
|
|
206
|
-
| 'loading_progress'
|
|
207
|
-
| 'protocol_error';
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* Complete set of `kind` values emitted to websocket clients.
|
|
211
|
-
*
|
|
212
|
-
* Every server-to-client websocket frame carries a `kind` from this union.
|
|
213
|
-
* Provider runtimes emit `MessageKind` values; gateway services emit
|
|
214
|
-
* `GatewayEventKind` values.
|
|
215
|
-
*/
|
|
216
|
-
export type ServerEventKind = MessageKind | GatewayEventKind;
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* Provider-neutral message envelope used in REST responses and realtime channels.
|
|
220
|
-
*
|
|
221
|
-
* Every provider-specific message must be converted into this shape before being
|
|
222
|
-
* emitted outside provider-specific modules.
|
|
223
|
-
*/
|
|
224
|
-
export type NormalizedMessage = {
|
|
225
|
-
id: string;
|
|
226
|
-
sessionId: string;
|
|
227
|
-
timestamp: string;
|
|
228
|
-
provider: LLMProvider;
|
|
229
|
-
kind: MessageKind;
|
|
230
|
-
/**
|
|
231
|
-
* Monotonic per-run sequence number assigned by the chat run registry when a
|
|
232
|
-
* live event is forwarded to the websocket. History messages loaded over
|
|
233
|
-
* REST do not carry it. Clients use it with `chat.subscribe` to replay only
|
|
234
|
-
* the live events they missed across websocket reconnects.
|
|
235
|
-
*/
|
|
236
|
-
seq?: number;
|
|
237
|
-
role?: 'user' | 'assistant';
|
|
238
|
-
content?: string;
|
|
239
|
-
/**
|
|
240
|
-
* Optional display-oriented metadata used by providers that need to expose
|
|
241
|
-
* richer transcript artifacts without introducing a brand-new message kind.
|
|
242
|
-
*
|
|
243
|
-
* Current Claude usage:
|
|
244
|
-
* - local slash commands expose parsed command fields
|
|
245
|
-
* - compact summaries are flagged so the UI can treat them differently later
|
|
246
|
-
*/
|
|
247
|
-
displayText?: string;
|
|
248
|
-
commandName?: string;
|
|
249
|
-
commandMessage?: string;
|
|
250
|
-
commandArgs?: string;
|
|
251
|
-
isLocalCommand?: boolean;
|
|
252
|
-
isLocalCommandStdout?: boolean;
|
|
253
|
-
isCompactSummary?: boolean;
|
|
254
|
-
images?: unknown;
|
|
255
|
-
/** Non-image files attached to a user turn after provider history normalization. */
|
|
256
|
-
files?: unknown;
|
|
257
|
-
toolName?: string;
|
|
258
|
-
toolInput?: unknown;
|
|
259
|
-
toolId?: string;
|
|
260
|
-
toolResult?: {
|
|
261
|
-
content?: string;
|
|
262
|
-
isError?: boolean;
|
|
263
|
-
toolUseResult?: unknown;
|
|
264
|
-
};
|
|
265
|
-
isError?: boolean;
|
|
266
|
-
text?: string;
|
|
267
|
-
tokens?: number;
|
|
268
|
-
canInterrupt?: boolean;
|
|
269
|
-
requestId?: string;
|
|
270
|
-
input?: unknown;
|
|
271
|
-
context?: unknown;
|
|
272
|
-
reason?: string;
|
|
273
|
-
newSessionId?: string;
|
|
274
|
-
status?: string;
|
|
275
|
-
summary?: string;
|
|
276
|
-
tokenBudget?: unknown;
|
|
277
|
-
subagentTools?: unknown;
|
|
278
|
-
toolUseResult?: unknown;
|
|
279
|
-
sequence?: number;
|
|
280
|
-
rowid?: number;
|
|
281
|
-
[key: string]: unknown;
|
|
282
|
-
};
|
|
283
|
-
|
|
284
|
-
/**
|
|
285
|
-
* Output gateway shared by WebSocket and SSE provider runs.
|
|
286
|
-
*
|
|
287
|
-
* Runtime adapters only depend on this structural surface, which keeps them
|
|
288
|
-
* independent from the transport that ultimately delivers normalized events.
|
|
289
|
-
*/
|
|
1
|
+
import type { IncomingMessage } from 'node:http';
|
|
2
|
+
import type { Readable } from 'node:stream';
|
|
3
|
+
|
|
4
|
+
//----------------- HTTP RESPONSE SHAPES ------------
|
|
5
|
+
/**
|
|
6
|
+
* Canonical success envelope used by backend APIs that return a structured payload.
|
|
7
|
+
*
|
|
8
|
+
* Use this for route handlers that need a stable `success/data` shape so frontend
|
|
9
|
+
* consumers can parse responses consistently across endpoints.
|
|
10
|
+
*/
|
|
11
|
+
export type ApiSuccessShape<TData = unknown> = {
|
|
12
|
+
success: true;
|
|
13
|
+
data: TData;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Generic plain-object record used when parsing loosely typed JSON payloads.
|
|
18
|
+
*
|
|
19
|
+
* Use this only after runtime shape checks, not as a replacement for validated
|
|
20
|
+
* domain models.
|
|
21
|
+
*/
|
|
22
|
+
export type AnyRecord = Record<string, any>;
|
|
23
|
+
|
|
24
|
+
// ---------------------------
|
|
25
|
+
//----------------- WEBSOCKET TRANSPORT TYPES ------------
|
|
26
|
+
/**
|
|
27
|
+
* Minimal websocket client contract used by backend broadcaster services.
|
|
28
|
+
*
|
|
29
|
+
* Any transport object added to `connectedClients` must implement these two
|
|
30
|
+
* members so shared services can safely send JSON strings and check whether the
|
|
31
|
+
* socket is still open before broadcasting.
|
|
32
|
+
*/
|
|
33
|
+
export type RealtimeClientConnection = {
|
|
34
|
+
readyState: number;
|
|
35
|
+
send(data: string): void;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Authenticated user payload attached to websocket upgrade requests.
|
|
40
|
+
*
|
|
41
|
+
* Platform and OSS auth flows currently use either `id` or `userId`; both are
|
|
42
|
+
* represented here so websocket handlers can resolve a stable writer user id.
|
|
43
|
+
*/
|
|
44
|
+
export type AuthenticatedWebSocketUser = {
|
|
45
|
+
id?: string | number;
|
|
46
|
+
userId?: string | number;
|
|
47
|
+
username?: string;
|
|
48
|
+
[key: string]: unknown;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* HTTP upgrade request shape after websocket authentication succeeds.
|
|
53
|
+
*
|
|
54
|
+
* `verifyClient` populates `request.user` with the authenticated payload, and
|
|
55
|
+
* downstream websocket handlers rely on this extended request type.
|
|
56
|
+
*/
|
|
57
|
+
export type AuthenticatedWebSocketRequest = IncomingMessage & {
|
|
58
|
+
user?: AuthenticatedWebSocketUser;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// ---------------------------
|
|
62
|
+
//----------------- PROVIDER MESSAGE MODEL ------------
|
|
63
|
+
/**
|
|
64
|
+
* Providers supported by the unified server runtime.
|
|
65
|
+
*
|
|
66
|
+
* Use this as the source of truth whenever a function or payload needs to identify
|
|
67
|
+
* a specific LLM integration.
|
|
68
|
+
*/
|
|
69
|
+
export type LLMProvider = 'claude' | 'codex' | 'cursor' | 'opencode';
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* One selectable model row in a provider model catalog.
|
|
73
|
+
*/
|
|
74
|
+
export type ProviderModelOption = {
|
|
75
|
+
value: string;
|
|
76
|
+
label: string;
|
|
77
|
+
description?: string;
|
|
78
|
+
/** Stable SQLite row id used only by model-management actions. */
|
|
79
|
+
recordId?: number;
|
|
80
|
+
/** True for user-created rows; false for immutable WindCli defaults. */
|
|
81
|
+
isCustom?: boolean;
|
|
82
|
+
effort?: {
|
|
83
|
+
default?: string;
|
|
84
|
+
values: {
|
|
85
|
+
value: string;
|
|
86
|
+
description?: string;
|
|
87
|
+
}[];
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Provider model catalog returned by `GET /api/providers/:provider/models`.
|
|
93
|
+
*/
|
|
94
|
+
export type ProviderModelsDefinition = {
|
|
95
|
+
OPTIONS: ProviderModelOption[];
|
|
96
|
+
DEFAULT: string;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* One persisted custom-model row in the provider model library.
|
|
101
|
+
*
|
|
102
|
+
* Provider modules use this shape at the database boundary. Predefined models
|
|
103
|
+
* never use this type because they remain source-controlled in provider
|
|
104
|
+
* adapters. `modelId` is sent to the provider runtime, while `model` is the
|
|
105
|
+
* user-supplied display name shown in pickers.
|
|
106
|
+
*/
|
|
107
|
+
export type CustomProviderModelRecord = {
|
|
108
|
+
recordId: number;
|
|
109
|
+
provider: LLMProvider;
|
|
110
|
+
modelId: string;
|
|
111
|
+
model: string;
|
|
112
|
+
sortOrder: number;
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* User-editable values accepted when creating or changing a custom model.
|
|
117
|
+
*
|
|
118
|
+
* `id` must be the exact provider-facing model identifier and cannot contain
|
|
119
|
+
* whitespace. `model` is a concise display name. The provider is supplied by
|
|
120
|
+
* the route path so a row can never be moved across providers accidentally.
|
|
121
|
+
*/
|
|
122
|
+
export type CustomProviderModelInput = {
|
|
123
|
+
id: string;
|
|
124
|
+
model: string;
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
// ---------------------------
|
|
128
|
+
//----------------- PROVIDER ACTIVE MODEL TYPES ------------
|
|
129
|
+
/**
|
|
130
|
+
* Provider-neutral result for the model that is actively driving a session or
|
|
131
|
+
* provider runtime at the time of lookup.
|
|
132
|
+
*
|
|
133
|
+
* `model` must always be populated. Provider adapters should use the
|
|
134
|
+
* provider-specific lookup method requested by the caller, and only fall back
|
|
135
|
+
* to the provider catalog `DEFAULT` value when the active model cannot be read.
|
|
136
|
+
*/
|
|
137
|
+
export type ProviderCurrentActiveModel = {
|
|
138
|
+
model: string;
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Where a resolved session model came from.
|
|
143
|
+
*
|
|
144
|
+
* `session` means the app has recorded a model for this session (the user
|
|
145
|
+
* picked one, or the session has been sent on at least once) and that value is
|
|
146
|
+
* authoritative. `provider` means the session predates any app-recorded model
|
|
147
|
+
* and the value was read back from the provider's own session state — the case
|
|
148
|
+
* for sessions started directly in a provider CLI. `default` means neither was
|
|
149
|
+
* available and the catalog default is standing in.
|
|
150
|
+
*
|
|
151
|
+
* Routes surface this so the frontend can tell a real selection apart from a
|
|
152
|
+
* placeholder without re-deriving the precedence chain.
|
|
153
|
+
*/
|
|
154
|
+
export type ProviderSessionModelSource = 'session' | 'provider' | 'default';
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* The model one session runs with, its persisted reasoning effort when one has
|
|
158
|
+
* been recorded, and where the model answer came from.
|
|
159
|
+
*
|
|
160
|
+
* Returned by `providerModelsService.resolveSessionModel` and used by the
|
|
161
|
+
* `/models`, `/cost` and `/status` commands, the active-model route, and the
|
|
162
|
+
* composer's model picker so every surface agrees on one answer.
|
|
163
|
+
*/
|
|
164
|
+
export type ProviderSessionModel = {
|
|
165
|
+
provider: LLMProvider;
|
|
166
|
+
sessionId: string | null;
|
|
167
|
+
model: string;
|
|
168
|
+
/** NULL means this session has not recorded an effort choice yet. */
|
|
169
|
+
effort: string | null;
|
|
170
|
+
source: ProviderSessionModelSource;
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Message/event variants emitted by provider adapters and normalized transports.
|
|
175
|
+
*
|
|
176
|
+
* Keep this union in sync with event kinds produced by provider session adapters.
|
|
177
|
+
*/
|
|
178
|
+
export type MessageKind =
|
|
179
|
+
| 'text'
|
|
180
|
+
| 'tool_use'
|
|
181
|
+
| 'tool_result'
|
|
182
|
+
| 'thinking'
|
|
183
|
+
| 'stream_delta'
|
|
184
|
+
| 'stream_end'
|
|
185
|
+
| 'error'
|
|
186
|
+
| 'complete'
|
|
187
|
+
| 'status'
|
|
188
|
+
| 'permission_request'
|
|
189
|
+
| 'permission_cancelled'
|
|
190
|
+
| 'session_created'
|
|
191
|
+
| 'interactive_prompt'
|
|
192
|
+
| 'task_notification';
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Event kinds added by the chat gateway layer on top of provider message kinds.
|
|
196
|
+
*
|
|
197
|
+
* These are app-level realtime events (subscription acks, sidebar deltas,
|
|
198
|
+
* project loading progress, protocol failures) that are not produced by any
|
|
199
|
+
* provider adapter. Together with `MessageKind` they form the complete set of
|
|
200
|
+
* `kind` values a websocket client can receive, so the frontend only ever
|
|
201
|
+
* needs one kind-based switch.
|
|
202
|
+
*/
|
|
203
|
+
export type GatewayEventKind =
|
|
204
|
+
| 'chat_subscribed'
|
|
205
|
+
| 'session_upserted'
|
|
206
|
+
| 'loading_progress'
|
|
207
|
+
| 'protocol_error';
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Complete set of `kind` values emitted to websocket clients.
|
|
211
|
+
*
|
|
212
|
+
* Every server-to-client websocket frame carries a `kind` from this union.
|
|
213
|
+
* Provider runtimes emit `MessageKind` values; gateway services emit
|
|
214
|
+
* `GatewayEventKind` values.
|
|
215
|
+
*/
|
|
216
|
+
export type ServerEventKind = MessageKind | GatewayEventKind;
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Provider-neutral message envelope used in REST responses and realtime channels.
|
|
220
|
+
*
|
|
221
|
+
* Every provider-specific message must be converted into this shape before being
|
|
222
|
+
* emitted outside provider-specific modules.
|
|
223
|
+
*/
|
|
224
|
+
export type NormalizedMessage = {
|
|
225
|
+
id: string;
|
|
226
|
+
sessionId: string;
|
|
227
|
+
timestamp: string;
|
|
228
|
+
provider: LLMProvider;
|
|
229
|
+
kind: MessageKind;
|
|
230
|
+
/**
|
|
231
|
+
* Monotonic per-run sequence number assigned by the chat run registry when a
|
|
232
|
+
* live event is forwarded to the websocket. History messages loaded over
|
|
233
|
+
* REST do not carry it. Clients use it with `chat.subscribe` to replay only
|
|
234
|
+
* the live events they missed across websocket reconnects.
|
|
235
|
+
*/
|
|
236
|
+
seq?: number;
|
|
237
|
+
role?: 'user' | 'assistant';
|
|
238
|
+
content?: string;
|
|
239
|
+
/**
|
|
240
|
+
* Optional display-oriented metadata used by providers that need to expose
|
|
241
|
+
* richer transcript artifacts without introducing a brand-new message kind.
|
|
242
|
+
*
|
|
243
|
+
* Current Claude usage:
|
|
244
|
+
* - local slash commands expose parsed command fields
|
|
245
|
+
* - compact summaries are flagged so the UI can treat them differently later
|
|
246
|
+
*/
|
|
247
|
+
displayText?: string;
|
|
248
|
+
commandName?: string;
|
|
249
|
+
commandMessage?: string;
|
|
250
|
+
commandArgs?: string;
|
|
251
|
+
isLocalCommand?: boolean;
|
|
252
|
+
isLocalCommandStdout?: boolean;
|
|
253
|
+
isCompactSummary?: boolean;
|
|
254
|
+
images?: unknown;
|
|
255
|
+
/** Non-image files attached to a user turn after provider history normalization. */
|
|
256
|
+
files?: unknown;
|
|
257
|
+
toolName?: string;
|
|
258
|
+
toolInput?: unknown;
|
|
259
|
+
toolId?: string;
|
|
260
|
+
toolResult?: {
|
|
261
|
+
content?: string;
|
|
262
|
+
isError?: boolean;
|
|
263
|
+
toolUseResult?: unknown;
|
|
264
|
+
};
|
|
265
|
+
isError?: boolean;
|
|
266
|
+
text?: string;
|
|
267
|
+
tokens?: number;
|
|
268
|
+
canInterrupt?: boolean;
|
|
269
|
+
requestId?: string;
|
|
270
|
+
input?: unknown;
|
|
271
|
+
context?: unknown;
|
|
272
|
+
reason?: string;
|
|
273
|
+
newSessionId?: string;
|
|
274
|
+
status?: string;
|
|
275
|
+
summary?: string;
|
|
276
|
+
tokenBudget?: unknown;
|
|
277
|
+
subagentTools?: unknown;
|
|
278
|
+
toolUseResult?: unknown;
|
|
279
|
+
sequence?: number;
|
|
280
|
+
rowid?: number;
|
|
281
|
+
[key: string]: unknown;
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Output gateway shared by WebSocket and SSE provider runs.
|
|
286
|
+
*
|
|
287
|
+
* Runtime adapters only depend on this structural surface, which keeps them
|
|
288
|
+
* independent from the transport that ultimately delivers normalized events.
|
|
289
|
+
*/
|
|
290
290
|
export type ProviderRuntimeWriter = {
|
|
291
|
-
send(data: unknown): void;
|
|
292
|
-
setSessionId?(sessionId: string): void;
|
|
293
|
-
userId?: string | number | null;
|
|
294
|
-
isWebSocketWriter?: boolean;
|
|
295
|
-
isSSEStreamWriter?: boolean;
|
|
291
|
+
send(data: unknown): void;
|
|
292
|
+
setSessionId?(sessionId: string): void;
|
|
293
|
+
userId?: string | number | null;
|
|
294
|
+
isWebSocketWriter?: boolean;
|
|
295
|
+
isSSEStreamWriter?: boolean;
|
|
296
296
|
};
|
|
297
297
|
|
|
298
298
|
//----------------- CODEX APP-SERVER PROTOCOL EVENTS ------------
|
|
@@ -302,7 +302,7 @@ export type ProviderRuntimeWriter = {
|
|
|
302
302
|
*
|
|
303
303
|
* The Codex JSON-RPC client emits this shape to its runtime adapter. Method and
|
|
304
304
|
* parameter validation stays in the adapter because the protocol can add new
|
|
305
|
-
* notification variants independently of
|
|
305
|
+
* notification variants independently of WindCli releases.
|
|
306
306
|
*/
|
|
307
307
|
export type CodexAppServerNotification = {
|
|
308
308
|
method: string;
|
|
@@ -313,7 +313,7 @@ export type CodexAppServerNotification = {
|
|
|
313
313
|
* Server-initiated Codex JSON-RPC request that may require a UI response.
|
|
314
314
|
*
|
|
315
315
|
* The Codex client forwards approval-capable requests to the runtime while it
|
|
316
|
-
* rejects request methods that
|
|
316
|
+
* rejects request methods that WindCli does not implement.
|
|
317
317
|
*/
|
|
318
318
|
export type CodexAppServerRequest = {
|
|
319
319
|
id: number;
|
|
@@ -334,935 +334,935 @@ export type CodexAppServerExit = {
|
|
|
334
334
|
// ---------------------------
|
|
335
335
|
|
|
336
336
|
export type ProviderPermissionDecision = {
|
|
337
|
-
allow: boolean;
|
|
338
|
-
updatedInput?: unknown;
|
|
339
|
-
message?: string;
|
|
340
|
-
rememberEntry?: unknown;
|
|
341
|
-
};
|
|
342
|
-
|
|
343
|
-
export type ProviderRuntimePermissionGateway = {
|
|
344
|
-
resolve(requestId: string, decision: ProviderPermissionDecision): void;
|
|
345
|
-
listPending(sessionId: string): unknown[];
|
|
346
|
-
};
|
|
347
|
-
|
|
348
|
-
/**
|
|
349
|
-
* Provider-scoped application capabilities supplied to a runtime for one run.
|
|
350
|
-
*
|
|
351
|
-
* Keeping these lookups outside concrete SDK/CLI adapters prevents the
|
|
352
|
-
* adapters from importing services that resolve back through providerRegistry.
|
|
353
|
-
*/
|
|
354
|
-
export type ProviderRuntimeContext = {
|
|
355
|
-
resolveProviderSessionId(sessionId: string | null | undefined): string | null;
|
|
356
|
-
resolveResumeModel(
|
|
357
|
-
sessionId: string | undefined,
|
|
358
|
-
requestedModel?: string | null,
|
|
359
|
-
): Promise<string | undefined>;
|
|
360
|
-
getProviderModels(): Promise<ProviderModelsDefinition>;
|
|
361
|
-
normalizeMessage(raw: unknown, sessionId: string | null): NormalizedMessage[];
|
|
362
|
-
isProviderInstalled(): Promise<boolean>;
|
|
363
|
-
};
|
|
364
|
-
|
|
365
|
-
export type ProviderRunFunction = (
|
|
366
|
-
command: string,
|
|
367
|
-
options: AnyRecord,
|
|
368
|
-
writer: ProviderRuntimeWriter,
|
|
369
|
-
) => Promise<unknown>;
|
|
370
|
-
|
|
371
|
-
/**
|
|
372
|
-
* Shared options used to fetch historical provider messages.
|
|
373
|
-
*
|
|
374
|
-
* Consumers should pass provider-specific lookup hints (`projectPath`) only
|
|
375
|
-
* when the selected provider requires them.
|
|
376
|
-
*
|
|
377
|
-
* `providerSessionId` is the provider-native session id from the sessions
|
|
378
|
-
* index (transcript file name / provider database key). Provider adapters
|
|
379
|
-
* must use it — never the app-facing session id they were called with — when
|
|
380
|
-
* matching transcript rows on disk, because app-created sessions use an
|
|
381
|
-
* app-allocated id that the provider has never seen.
|
|
382
|
-
*/
|
|
383
|
-
export type FetchHistoryOptions = {
|
|
384
|
-
projectPath?: string;
|
|
385
|
-
limit?: number | null;
|
|
386
|
-
offset?: number;
|
|
387
|
-
providerSessionId?: string;
|
|
388
|
-
};
|
|
389
|
-
|
|
390
|
-
/**
|
|
391
|
-
* Standardized response payload returned from provider history readers.
|
|
392
|
-
*
|
|
393
|
-
* Use this as the contract for APIs that return paginated conversation history.
|
|
394
|
-
*/
|
|
395
|
-
export type FetchHistoryResult = {
|
|
396
|
-
messages: NormalizedMessage[];
|
|
397
|
-
total: number;
|
|
398
|
-
hasMore: boolean;
|
|
399
|
-
offset: number;
|
|
400
|
-
limit: number | null;
|
|
401
|
-
tokenUsage?: unknown;
|
|
402
|
-
};
|
|
403
|
-
|
|
404
|
-
// ---------------------------
|
|
405
|
-
//----------------- PROVIDER SKILL TYPES ------------
|
|
406
|
-
/**
|
|
407
|
-
* Scope where a provider skill definition was discovered.
|
|
408
|
-
*
|
|
409
|
-
* Provider skill adapters should use this to describe the origin of each
|
|
410
|
-
* skill markdown file without leaking provider-specific folder names into route
|
|
411
|
-
* contracts. `repo` is used for Codex repository lookup locations, while
|
|
412
|
-
* `project` is used for providers that treat workspace-local skills as project
|
|
413
|
-
* scoped.
|
|
414
|
-
*/
|
|
415
|
-
export type ProviderSkillScope = 'user' | 'project' | 'plugin' | 'repo' | 'admin' | 'system';
|
|
416
|
-
|
|
417
|
-
/**
|
|
418
|
-
* Shared input accepted by provider skill listing operations.
|
|
419
|
-
*
|
|
420
|
-
* Routes pass `workspacePath` when a caller wants project/repository skills for
|
|
421
|
-
* a specific folder. Providers should fall back to the backend process cwd when
|
|
422
|
-
* this option is omitted.
|
|
423
|
-
*/
|
|
424
|
-
export type ProviderSkillListOptions = {
|
|
425
|
-
workspacePath?: string;
|
|
426
|
-
};
|
|
427
|
-
|
|
428
|
-
/**
|
|
429
|
-
* One supporting file bundled with an uploaded provider skill.
|
|
430
|
-
*
|
|
431
|
-
* `relativePath` is resolved below the installed skill directory and must never
|
|
432
|
-
* be absolute or contain traversal segments. Text files may use `utf8`; binary
|
|
433
|
-
* scripts and assets should use `base64` so JSON transport does not corrupt
|
|
434
|
-
* their bytes.
|
|
435
|
-
*/
|
|
436
|
-
export type ProviderSkillCreateFile = {
|
|
437
|
-
relativePath: string;
|
|
438
|
-
content: string;
|
|
439
|
-
encoding: 'utf8' | 'base64';
|
|
440
|
-
};
|
|
441
|
-
|
|
442
|
-
/**
|
|
443
|
-
* One skill markdown payload submitted for provider-managed installation.
|
|
444
|
-
*
|
|
445
|
-
* `content` is the raw markdown body that will be written to `SKILL.md`.
|
|
446
|
-
* `directoryName` lets callers control the target folder name explicitly when
|
|
447
|
-
* they want stable filesystem paths that differ from the markdown front matter
|
|
448
|
-
* `name` field. `fileName` is optional upload metadata used only as a final
|
|
449
|
-
* fallback when no directory name or front matter name is present. `files`
|
|
450
|
-
* carries scripts, references, and other files from a complete skill folder.
|
|
451
|
-
*/
|
|
452
|
-
export type ProviderSkillCreateEntry = {
|
|
453
|
-
content: string;
|
|
454
|
-
directoryName?: string;
|
|
455
|
-
fileName?: string;
|
|
456
|
-
files?: ProviderSkillCreateFile[];
|
|
457
|
-
};
|
|
458
|
-
|
|
459
|
-
/**
|
|
460
|
-
* Shared input accepted by provider skill creation operations.
|
|
461
|
-
*
|
|
462
|
-
* The service layer batches multiple skill definitions in one request. Each
|
|
463
|
-
* entry can contain only markdown or a complete skill folder.
|
|
464
|
-
*/
|
|
465
|
-
export type ProviderSkillCreateInput = {
|
|
466
|
-
entries: ProviderSkillCreateEntry[];
|
|
467
|
-
};
|
|
468
|
-
|
|
469
|
-
export type ProviderSkillRemoveInput = {
|
|
470
|
-
directoryName: string;
|
|
471
|
-
};
|
|
472
|
-
|
|
473
|
-
/**
|
|
474
|
-
* Normalized skill record returned by provider skill adapters.
|
|
475
|
-
*
|
|
476
|
-
* The `command` value is the exact invocation text the selected provider expects
|
|
477
|
-
* for this skill. Claude plugin skills use a namespaced command such as
|
|
478
|
-
* `/plugin-name:skill-name`, while Codex skills use the `$skill-name` form.
|
|
479
|
-
* `sourcePath` points to the skill markdown file that produced the record so
|
|
480
|
-
* callers can distinguish duplicate skill names across scopes.
|
|
481
|
-
*/
|
|
482
|
-
export type ProviderSkill = {
|
|
483
|
-
provider: LLMProvider;
|
|
484
|
-
name: string;
|
|
485
|
-
description: string;
|
|
486
|
-
command: string;
|
|
487
|
-
scope: ProviderSkillScope;
|
|
488
|
-
sourcePath: string;
|
|
489
|
-
pluginName?: string;
|
|
490
|
-
pluginId?: string;
|
|
491
|
-
};
|
|
492
|
-
|
|
493
|
-
/**
|
|
494
|
-
* Internal source descriptor consumed by shared provider skill discovery logic.
|
|
495
|
-
*
|
|
496
|
-
* Concrete provider adapters build these records from their native lookup rules.
|
|
497
|
-
* The shared skills provider then scans `rootDir` for child skill markdown files
|
|
498
|
-
* and uses `commandForSkill` or `commandPrefix` to produce the provider-specific
|
|
499
|
-
* invocation command. Set `recursive` only when a provider stores skills under
|
|
500
|
-
* arbitrary nested folders below the source root.
|
|
501
|
-
*/
|
|
502
|
-
export type ProviderSkillSource = {
|
|
503
|
-
scope: ProviderSkillScope;
|
|
504
|
-
rootDir: string;
|
|
505
|
-
recursive?: boolean;
|
|
506
|
-
commandPrefix?: '/' | '$';
|
|
507
|
-
commandForSkill?: (skillName: string) => string;
|
|
508
|
-
pluginName?: string;
|
|
509
|
-
pluginId?: string;
|
|
510
|
-
};
|
|
511
|
-
|
|
512
|
-
// ---------------------------
|
|
513
|
-
//----------------- SHARED ERROR TYPES ------------
|
|
514
|
-
/**
|
|
515
|
-
* Optional metadata used when constructing application-level errors.
|
|
516
|
-
*
|
|
517
|
-
* `statusCode` should reflect the HTTP response status, while `code` identifies
|
|
518
|
-
* the stable machine-readable error category.
|
|
519
|
-
*/
|
|
520
|
-
export type AppErrorOptions = {
|
|
521
|
-
code?: string;
|
|
522
|
-
statusCode?: number;
|
|
523
|
-
details?: unknown;
|
|
524
|
-
};
|
|
525
|
-
|
|
526
|
-
// ---------------------------
|
|
527
|
-
//----------------- MCP TYPES ------------
|
|
528
|
-
/**
|
|
529
|
-
* Scope where an MCP server definition is stored and resolved.
|
|
530
|
-
*
|
|
531
|
-
* `user` is global for a user account, `local` is provider-local, and `project`
|
|
532
|
-
* is tied to a specific project path.
|
|
533
|
-
*/
|
|
534
|
-
export type McpScope = 'user' | 'local' | 'project';
|
|
535
|
-
|
|
536
|
-
/**
|
|
537
|
-
* Transport protocol used by an MCP server definition.
|
|
538
|
-
*/
|
|
539
|
-
export type McpTransport = 'stdio' | 'http' | 'sse';
|
|
540
|
-
|
|
541
|
-
/**
|
|
542
|
-
* Normalized MCP server model exposed to frontend and route handlers.
|
|
543
|
-
*
|
|
544
|
-
* Provider adapters should map provider-native config to this structure before
|
|
545
|
-
* returning results.
|
|
546
|
-
*/
|
|
547
|
-
export type ProviderMcpServer = {
|
|
548
|
-
provider: LLMProvider;
|
|
549
|
-
name: string;
|
|
550
|
-
scope: McpScope;
|
|
551
|
-
transport: McpTransport;
|
|
552
|
-
command?: string;
|
|
553
|
-
args?: string[];
|
|
554
|
-
env?: Record<string, string>;
|
|
555
|
-
cwd?: string;
|
|
556
|
-
url?: string;
|
|
557
|
-
headers?: Record<string, string>;
|
|
558
|
-
envVars?: string[];
|
|
559
|
-
bearerTokenEnvVar?: string;
|
|
560
|
-
envHttpHeaders?: Record<string, string>;
|
|
561
|
-
};
|
|
562
|
-
|
|
563
|
-
/**
|
|
564
|
-
* Payload for create/update MCP server operations.
|
|
565
|
-
*
|
|
566
|
-
* Routes and services should accept this type, validate it, and then persist it
|
|
567
|
-
* through provider-specific MCP repositories.
|
|
568
|
-
*/
|
|
569
|
-
export type UpsertProviderMcpServerInput = {
|
|
570
|
-
name: string;
|
|
571
|
-
scope?: McpScope;
|
|
572
|
-
transport: McpTransport;
|
|
573
|
-
workspacePath?: string;
|
|
574
|
-
command?: string;
|
|
575
|
-
args?: string[];
|
|
576
|
-
env?: Record<string, string>;
|
|
577
|
-
cwd?: string;
|
|
578
|
-
url?: string;
|
|
579
|
-
headers?: Record<string, string>;
|
|
580
|
-
envVars?: string[];
|
|
581
|
-
bearerTokenEnvVar?: string;
|
|
582
|
-
envHttpHeaders?: Record<string, string>;
|
|
583
|
-
};
|
|
584
|
-
|
|
585
|
-
// ---------------------------
|
|
586
|
-
//----------------- PROVIDER AUTH TYPES ------------
|
|
587
|
-
/**
|
|
588
|
-
* Authentication status result returned by provider health checks.
|
|
589
|
-
*
|
|
590
|
-
* This shape is consumed by settings/status endpoints to report installation and
|
|
591
|
-
* credential state for each provider.
|
|
592
|
-
*/
|
|
593
|
-
export type ProviderAuthStatus = {
|
|
594
|
-
installed: boolean;
|
|
595
|
-
provider: LLMProvider;
|
|
596
|
-
authenticated: boolean;
|
|
597
|
-
email: string | null;
|
|
598
|
-
method: string | null;
|
|
599
|
-
error?: string;
|
|
600
|
-
};
|
|
601
|
-
|
|
602
|
-
// ---------------------------
|
|
603
|
-
//----------------- SHARED DATABASE CREDENTIAL TYPES ------------
|
|
604
|
-
/**
|
|
605
|
-
* Safe credential view returned by credential listing APIs.
|
|
606
|
-
*
|
|
607
|
-
* This intentionally excludes the raw credential secret while still exposing
|
|
608
|
-
* metadata needed for UI rendering and management operations.
|
|
609
|
-
*/
|
|
610
|
-
export type CredentialPublicRow = {
|
|
611
|
-
id: number;
|
|
612
|
-
credential_name: string;
|
|
613
|
-
credential_type: string;
|
|
614
|
-
description: string | null;
|
|
615
|
-
created_at: string;
|
|
616
|
-
is_active: number;
|
|
617
|
-
};
|
|
618
|
-
|
|
619
|
-
/**
|
|
620
|
-
* Result returned after creating a credential record.
|
|
621
|
-
*
|
|
622
|
-
* Use this return shape when callers need the created id and display metadata,
|
|
623
|
-
* but must never receive the stored secret value.
|
|
624
|
-
*/
|
|
625
|
-
export type CreateCredentialResult = {
|
|
626
|
-
id: number | bigint;
|
|
627
|
-
credentialName: string;
|
|
628
|
-
credentialType: string;
|
|
629
|
-
};
|
|
630
|
-
|
|
631
|
-
// ---------------------------
|
|
632
|
-
//----------------- PROJECT PERSISTENCE TYPES ------------
|
|
633
|
-
/**
|
|
634
|
-
* Canonical project row shape returned by the projects repository.
|
|
635
|
-
*
|
|
636
|
-
* Use this type whenever backend services need to pass around one database
|
|
637
|
-
* project record without leaking raw SQL row typing across modules.
|
|
638
|
-
*/
|
|
639
|
-
export type ProjectRepositoryRow = {
|
|
640
|
-
project_id: string;
|
|
641
|
-
project_path: string;
|
|
642
|
-
custom_project_name: string | null;
|
|
643
|
-
isStarred: number;
|
|
644
|
-
isArchived: number;
|
|
645
|
-
};
|
|
646
|
-
|
|
647
|
-
/**
|
|
648
|
-
* Result category returned by `projectsDb.createProjectPath`.
|
|
649
|
-
*
|
|
650
|
-
* `created` means a fresh row was inserted, `reactivated_archived` means an
|
|
651
|
-
* existing archived path was accepted and updated, and `active_conflict` means
|
|
652
|
-
* an already-active path blocked project creation.
|
|
653
|
-
*/
|
|
654
|
-
export type CreateProjectPathOutcome =
|
|
655
|
-
| 'created'
|
|
656
|
-
| 'reactivated_archived'
|
|
657
|
-
| 'active_conflict';
|
|
658
|
-
|
|
659
|
-
/**
|
|
660
|
-
* Structured result returned by project-path upsert operations.
|
|
661
|
-
*
|
|
662
|
-
* Services should use this result to decide whether a request succeeded,
|
|
663
|
-
* should return a conflict, or needs follow-up retrieval of row metadata.
|
|
664
|
-
*/
|
|
665
|
-
export type CreateProjectPathResult = {
|
|
666
|
-
outcome: CreateProjectPathOutcome;
|
|
667
|
-
project: ProjectRepositoryRow | null;
|
|
668
|
-
};
|
|
669
|
-
|
|
670
|
-
/**
|
|
671
|
-
* Validation result for user-supplied workspace/project paths.
|
|
672
|
-
*
|
|
673
|
-
* `resolvedPath` is present only when validation succeeds. `error` is present
|
|
674
|
-
* only when validation fails and is suitable for user-facing diagnostics.
|
|
675
|
-
*/
|
|
676
|
-
export type WorkspacePathValidationResult = {
|
|
677
|
-
valid: boolean;
|
|
678
|
-
resolvedPath?: string;
|
|
679
|
-
error?: string;
|
|
680
|
-
};
|
|
681
|
-
|
|
682
|
-
// ---------------------------
|
|
683
|
-
//----------------- GIT WORKTREE MANAGEMENT ------------
|
|
684
|
-
/**
|
|
685
|
-
* Captured output of one completed `git` invocation.
|
|
686
|
-
*
|
|
687
|
-
* Returned by `GitCommandRunner` implementations so worktree services can read
|
|
688
|
-
* both streams without caring about process plumbing.
|
|
689
|
-
*/
|
|
690
|
-
export type GitCommandResult = {
|
|
691
|
-
stdout: string;
|
|
692
|
-
stderr: string;
|
|
693
|
-
};
|
|
694
|
-
|
|
695
|
-
/**
|
|
696
|
-
* Executes `git <args>` inside `cwd` and resolves with the captured output.
|
|
697
|
-
*
|
|
698
|
-
* All worktree services receive their git access through this contract so
|
|
699
|
-
* tests can inject a fake runner instead of spawning real processes. The
|
|
700
|
-
* promise must reject (with `stderr` attached when available) on a non-zero
|
|
701
|
-
* exit code.
|
|
702
|
-
*/
|
|
703
|
-
export type GitCommandRunner = (args: string[], cwd: string) => Promise<GitCommandResult>;
|
|
704
|
-
|
|
705
|
-
/**
|
|
706
|
-
* One entry parsed from `git worktree list --porcelain`.
|
|
707
|
-
*
|
|
708
|
-
* This is the raw repository-level view (path/HEAD/branch/flags) before any
|
|
709
|
-
* enrichment with project links or ahead/behind counts. `branch` is null for
|
|
710
|
-
* detached-HEAD worktrees.
|
|
711
|
-
*/
|
|
712
|
-
export type WorktreePorcelainEntry = {
|
|
713
|
-
path: string;
|
|
714
|
-
headSha: string | null;
|
|
715
|
-
branch: string | null;
|
|
716
|
-
isDetached: boolean;
|
|
717
|
-
isLocked: boolean;
|
|
718
|
-
isPrunable: boolean;
|
|
719
|
-
};
|
|
720
|
-
|
|
721
|
-
/**
|
|
722
|
-
* Fully enriched worktree row served to the UI.
|
|
723
|
-
*
|
|
724
|
-
* Extends the porcelain entry with everything the Worktrees panel renders:
|
|
725
|
-
* dirty-file count, ahead/behind relative to the base branch (the branch
|
|
726
|
-
* checked out in the main worktree), last-commit metadata, and the
|
|
727
|
-
* project row linked to the worktree directory (if one was registered).
|
|
728
|
-
*/
|
|
729
|
-
export type WorktreeDescriptor = {
|
|
730
|
-
path: string;
|
|
731
|
-
branch: string | null;
|
|
732
|
-
headSha: string | null;
|
|
733
|
-
isMain: boolean;
|
|
734
|
-
isCurrent: boolean;
|
|
735
|
-
isLocked: boolean;
|
|
736
|
-
isDetached: boolean;
|
|
737
|
-
changedFileCount: number;
|
|
738
|
-
ahead: number;
|
|
739
|
-
behind: number;
|
|
740
|
-
lastCommitSubject: string | null;
|
|
741
|
-
lastCommitDate: string | null;
|
|
742
|
-
linkedProjectId: string | null;
|
|
743
|
-
linkedProjectArchived: boolean;
|
|
744
|
-
};
|
|
745
|
-
|
|
746
|
-
/**
|
|
747
|
-
* Response payload of `GET /api/worktrees`.
|
|
748
|
-
*
|
|
749
|
-
* `baseBranch` is the branch checked out in the main worktree — the merge
|
|
750
|
-
* target offered by the UI. `worktrees` always lists the main worktree first.
|
|
751
|
-
*/
|
|
752
|
-
export type WorktreeListResult = {
|
|
753
|
-
repositoryRoot: string;
|
|
754
|
-
baseBranch: string | null;
|
|
755
|
-
worktrees: WorktreeDescriptor[];
|
|
756
|
-
};
|
|
757
|
-
|
|
758
|
-
// ---------------------------
|
|
759
|
-
//----------------- WORKTREE SERVICE INPUTS AND RESULTS ------------
|
|
760
|
-
/**
|
|
761
|
-
* Input accepted by the worktree-listing workflow.
|
|
762
|
-
*
|
|
763
|
-
* `projectPath` may point at the main checkout or any linked worktree. The
|
|
764
|
-
* service uses Git to resolve the complete repository-level worktree list.
|
|
765
|
-
*/
|
|
766
|
-
export type ListWorktreesInput = {
|
|
767
|
-
projectPath: string;
|
|
768
|
-
};
|
|
769
|
-
|
|
770
|
-
/**
|
|
771
|
-
* Input accepted when creating a linked Git worktree.
|
|
772
|
-
*
|
|
773
|
-
* `branch` is checked out when it already exists, otherwise it is created from
|
|
774
|
-
* `baseBranch`. When `baseBranch` is omitted, the main worktree branch is used.
|
|
775
|
-
*/
|
|
776
|
-
export type CreateWorktreeInput = {
|
|
777
|
-
projectPath: string;
|
|
778
|
-
branch: string;
|
|
779
|
-
baseBranch?: string | null;
|
|
780
|
-
};
|
|
781
|
-
|
|
782
|
-
/**
|
|
783
|
-
* Result of successfully creating a linked Git worktree.
|
|
784
|
-
*
|
|
785
|
-
* `createdBranch` distinguishes a new branch from an existing branch checkout,
|
|
786
|
-
* allowing API clients to accurately describe what Git changed.
|
|
787
|
-
*/
|
|
788
|
-
export type CreateWorktreeResult = {
|
|
789
|
-
worktreePath: string;
|
|
790
|
-
branch: string;
|
|
791
|
-
createdBranch: boolean;
|
|
792
|
-
};
|
|
793
|
-
|
|
794
|
-
/**
|
|
795
|
-
* Result of atomically creating and registering a worktree for project use.
|
|
796
|
-
*
|
|
797
|
-
* The Worktrees application service compensates the Git creation if project
|
|
798
|
-
* registration fails, so routes only receive this shape after both steps pass.
|
|
799
|
-
*/
|
|
800
|
-
export type CreateAndOpenWorktreeResult = CreateWorktreeResult & {
|
|
801
|
-
project: WorktreeProjectView;
|
|
802
|
-
};
|
|
803
|
-
|
|
804
|
-
/**
|
|
805
|
-
* Input accepted when registering an existing worktree as a
|
|
806
|
-
*
|
|
807
|
-
* The service verifies that `worktreePath` belongs to the repository containing
|
|
808
|
-
* `projectPath` before it creates or restores any project record.
|
|
809
|
-
*/
|
|
810
|
-
export type OpenWorktreeInput = {
|
|
811
|
-
projectPath: string;
|
|
812
|
-
worktreePath: string;
|
|
813
|
-
};
|
|
814
|
-
|
|
815
|
-
/**
|
|
816
|
-
* Project view returned after a worktree is opened in
|
|
817
|
-
*
|
|
818
|
-
* This deliberately mirrors the project-selection payload used by the Projects
|
|
819
|
-
* module so the frontend can switch to the worktree without another lookup.
|
|
820
|
-
*/
|
|
821
|
-
export type WorktreeProjectView = {
|
|
822
|
-
projectId: string;
|
|
823
|
-
path: string;
|
|
824
|
-
fullPath: string;
|
|
825
|
-
displayName: string;
|
|
826
|
-
isStarred: boolean;
|
|
827
|
-
sessions: [];
|
|
828
|
-
sessionMeta: { hasMore: false; total: 0 };
|
|
829
|
-
};
|
|
830
|
-
|
|
831
|
-
/**
|
|
832
|
-
* Input accepted when removing a linked Git worktree.
|
|
833
|
-
*
|
|
834
|
-
* `force` permits removal with local changes. `deleteBranch` requests
|
|
835
|
-
* best-effort branch cleanup after the worktree directory is removed.
|
|
836
|
-
*/
|
|
837
|
-
export type RemoveWorktreeInput = {
|
|
838
|
-
projectPath: string;
|
|
839
|
-
worktreePath: string;
|
|
840
|
-
force?: boolean;
|
|
841
|
-
deleteBranch?: boolean;
|
|
842
|
-
};
|
|
843
|
-
|
|
844
|
-
/**
|
|
845
|
-
* Result of removing a linked Git worktree.
|
|
846
|
-
*
|
|
847
|
-
* `archivalError` reports best-effort project archival failure after Git has
|
|
848
|
-
* already removed the worktree, allowing callers to represent partial success.
|
|
849
|
-
*/
|
|
850
|
-
export type RemoveWorktreeResult = {
|
|
851
|
-
removedPath: string;
|
|
852
|
-
branch: string | null;
|
|
853
|
-
branchDeleted: boolean;
|
|
854
|
-
archivedProjectId: string | null;
|
|
855
|
-
archivalError: string | null;
|
|
856
|
-
};
|
|
857
|
-
|
|
858
|
-
/**
|
|
859
|
-
* Input accepted when merging a linked worktree into the main worktree branch.
|
|
860
|
-
*
|
|
861
|
-
* The service verifies both worktrees are clean, supports squash and regular
|
|
862
|
-
* merges, and may remove the source worktree after a successful merge.
|
|
863
|
-
*/
|
|
864
|
-
export type MergeWorktreeInput = {
|
|
865
|
-
projectPath: string;
|
|
866
|
-
worktreePath: string;
|
|
867
|
-
squash?: boolean;
|
|
868
|
-
message?: string | null;
|
|
869
|
-
removeAfterMerge?: boolean;
|
|
870
|
-
};
|
|
871
|
-
|
|
872
|
-
/**
|
|
873
|
-
* Result of a completed worktree merge.
|
|
874
|
-
*
|
|
875
|
-
* `removedWorktree` is populated only when post-merge removal succeeds.
|
|
876
|
-
* `cleanupError` reports failed optional removal without misrepresenting the
|
|
877
|
-
* already-completed merge as a failure.
|
|
878
|
-
*/
|
|
879
|
-
export type MergeWorktreeResult = {
|
|
880
|
-
mergedBranch: string;
|
|
881
|
-
targetBranch: string;
|
|
882
|
-
squash: boolean;
|
|
883
|
-
removedWorktree: RemoveWorktreeResult | null;
|
|
884
|
-
cleanupError: string | null;
|
|
885
|
-
};
|
|
886
|
-
|
|
887
|
-
// ---------------------------
|
|
888
|
-
//----------------- WORKTREE MODULE DEPENDENCY CONTRACTS ------------
|
|
889
|
-
/**
|
|
890
|
-
* Filesystem capability required by the Worktrees module.
|
|
891
|
-
*
|
|
892
|
-
* Production wiring checks the real filesystem; unit tests provide a small
|
|
893
|
-
* deterministic fake so worktree creation never touches developer directories.
|
|
894
|
-
*/
|
|
895
|
-
export type WorktreeFileSystem = {
|
|
896
|
-
pathExists(candidatePath: string): Promise<boolean>;
|
|
897
|
-
};
|
|
898
|
-
|
|
899
|
-
/**
|
|
900
|
-
* Project-management boundary consumed by Worktrees workflows.
|
|
901
|
-
*
|
|
902
|
-
* The Worktrees module uses this contract instead of importing Database or
|
|
903
|
-
* Projects internals. Production adapters delegate through those modules'
|
|
904
|
-
* `index.ts` barrels, while unit tests supply in-memory functions.
|
|
905
|
-
*/
|
|
906
|
-
export type WorktreeProjectGateway = {
|
|
907
|
-
getProjectPathById(projectId: string): string | null;
|
|
908
|
-
getProjectByPath(projectPath: string): ProjectRepositoryRow | null;
|
|
909
|
-
createProject(input: {
|
|
910
|
-
projectPath: string;
|
|
911
|
-
customName: string;
|
|
912
|
-
}): Promise<{
|
|
913
|
-
outcome: 'created' | 'reactivated_archived';
|
|
914
|
-
project: { projectId: string };
|
|
915
|
-
}>;
|
|
916
|
-
restoreProject(projectId: string): void | Promise<void>;
|
|
917
|
-
archiveProject(projectId: string): void | Promise<void>;
|
|
918
|
-
};
|
|
919
|
-
|
|
920
|
-
/**
|
|
921
|
-
* Complete application-service surface used by the Worktrees HTTP router.
|
|
922
|
-
*
|
|
923
|
-
* Routes parse transport values and call these functions; they do not import
|
|
924
|
-
* repositories, filesystem adapters, Git runners, or individual service files.
|
|
925
|
-
*/
|
|
926
|
-
export type WorktreeServices = {
|
|
927
|
-
resolveProjectPath(projectId: string): string;
|
|
928
|
-
list(input: ListWorktreesInput): Promise<WorktreeListResult>;
|
|
929
|
-
create(input: CreateWorktreeInput): Promise<CreateWorktreeResult>;
|
|
930
|
-
createAndOpen(input: CreateWorktreeInput): Promise<CreateAndOpenWorktreeResult>;
|
|
931
|
-
open(input: OpenWorktreeInput): Promise<WorktreeProjectView>;
|
|
932
|
-
merge(input: MergeWorktreeInput): Promise<MergeWorktreeResult>;
|
|
933
|
-
remove(input: RemoveWorktreeInput): Promise<RemoveWorktreeResult>;
|
|
934
|
-
};
|
|
935
|
-
|
|
936
|
-
// ---------------------------
|
|
937
|
-
//----------------- FILE TREE MODULE CONTRACTS ------------
|
|
938
|
-
/**
|
|
939
|
-
* One filesystem item returned by the File Tree API.
|
|
940
|
-
*
|
|
941
|
-
* The service populates metadata without following symlinks and recursively
|
|
942
|
-
* attaches `children` only while the requested depth permits traversal. The
|
|
943
|
-
* frontend uses the absolute `path` as the stable identifier for editor and
|
|
944
|
-
* file-operation requests.
|
|
945
|
-
*/
|
|
946
|
-
export type FileTreeNode = {
|
|
947
|
-
name: string;
|
|
948
|
-
path: string;
|
|
949
|
-
type: 'file' | 'directory';
|
|
950
|
-
size: number;
|
|
951
|
-
modified: string | null;
|
|
952
|
-
permissions: string;
|
|
953
|
-
permissionsRwx: string;
|
|
954
|
-
isSymlink?: boolean;
|
|
955
|
-
children?: FileTreeNode[];
|
|
956
|
-
};
|
|
957
|
-
|
|
958
|
-
/**
|
|
959
|
-
* Minimal directory-entry shape required during File Tree traversal.
|
|
960
|
-
*
|
|
961
|
-
* Production adapts Node `Dirent` objects to this structural contract. Tests
|
|
962
|
-
* provide small handwritten entries and therefore never read real directories.
|
|
963
|
-
*/
|
|
964
|
-
export type FileTreeDirectoryEntry = {
|
|
965
|
-
name: string;
|
|
966
|
-
isDirectory(): boolean;
|
|
967
|
-
};
|
|
968
|
-
|
|
969
|
-
/**
|
|
970
|
-
* Minimal file-stat shape used for tree metadata and delete decisions.
|
|
971
|
-
*
|
|
972
|
-
* The numeric mode is converted to octal and rwx strings for the UI. `lstat`
|
|
973
|
-
* supplies symlink state while `stat` is used when deciding file versus folder
|
|
974
|
-
* deletion behavior.
|
|
975
|
-
*/
|
|
976
|
-
export type FileTreeStats = {
|
|
977
|
-
size: number;
|
|
978
|
-
mtime: Date;
|
|
979
|
-
mode: number;
|
|
980
|
-
isDirectory(): boolean;
|
|
981
|
-
isSymbolicLink(): boolean;
|
|
982
|
-
};
|
|
983
|
-
|
|
984
|
-
/**
|
|
985
|
-
* Complete filesystem capability injected into File Tree services.
|
|
986
|
-
*
|
|
987
|
-
* The production composition root delegates these operations to Node's fs
|
|
988
|
-
* APIs. Unit tests provide deterministic path-keyed fakes so service tests
|
|
989
|
-
* cannot inspect, write, rename, or delete developer files.
|
|
990
|
-
*/
|
|
991
|
-
export type FileTreeFileSystem = {
|
|
992
|
-
access(candidatePath: string): Promise<void>;
|
|
993
|
-
stat(candidatePath: string): Promise<FileTreeStats>;
|
|
994
|
-
lstat(candidatePath: string): Promise<FileTreeStats>;
|
|
995
|
-
// Streamed rather than returned as an array so a directory with millions of
|
|
996
|
-
// children is abandoned at the entry limit instead of being materialized.
|
|
997
|
-
openDirectory(directoryPath: string): AsyncIterable<FileTreeDirectoryEntry>;
|
|
998
|
-
realpath(candidatePath: string): Promise<string>;
|
|
999
|
-
readTextFile(filePath: string): Promise<string>;
|
|
1000
|
-
writeTextFile(filePath: string, content: string): Promise<void>;
|
|
1001
|
-
makeDirectory(directoryPath: string, recursive: boolean): Promise<void>;
|
|
1002
|
-
rename(oldPath: string, newPath: string): Promise<void>;
|
|
1003
|
-
removeDirectory(directoryPath: string): Promise<void>;
|
|
1004
|
-
unlink(filePath: string): Promise<void>;
|
|
1005
|
-
copyFile(sourcePath: string, destinationPath: string): Promise<void>;
|
|
1006
|
-
createReadStream(filePath: string): Readable;
|
|
1007
|
-
};
|
|
1008
|
-
|
|
1009
|
-
/**
|
|
1010
|
-
* Project lookup boundary consumed by File Tree workflows.
|
|
1011
|
-
*
|
|
1012
|
-
* File Tree services resolve DB-assigned project ids through this contract and
|
|
1013
|
-
* never import the Database module or its repositories directly.
|
|
1014
|
-
*/
|
|
1015
|
-
export type FileTreeProjectGateway = {
|
|
1016
|
-
getProjectPathById(projectId: string): string | null | Promise<string | null>;
|
|
1017
|
-
};
|
|
1018
|
-
|
|
1019
|
-
/**
|
|
1020
|
-
* Workspace validation boundary used by filesystem browsing and folder creation.
|
|
1021
|
-
*
|
|
1022
|
-
* The injected validator enforces the configured workspace root and resolves
|
|
1023
|
-
* symlinks before the File Tree service exposes or mutates paths.
|
|
1024
|
-
*/
|
|
1025
|
-
export type FileTreeWorkspaceGateway = {
|
|
1026
|
-
rootPath: string;
|
|
1027
|
-
validatePath(candidatePath: string): Promise<WorkspacePathValidationResult>;
|
|
1028
|
-
};
|
|
1029
|
-
|
|
1030
|
-
/**
|
|
1031
|
-
* Uploaded-file record passed from the Multer transport adapter into the File
|
|
1032
|
-
* Tree service.
|
|
1033
|
-
*
|
|
1034
|
-
* Transport-specific field names are normalized so upload workflows do not
|
|
1035
|
-
* depend on Express or Multer types.
|
|
1036
|
-
*/
|
|
1037
|
-
export type FileTreeUploadedFile = {
|
|
1038
|
-
originalName: string;
|
|
1039
|
-
temporaryPath: string;
|
|
1040
|
-
size: number;
|
|
1041
|
-
mimeType: string;
|
|
1042
|
-
};
|
|
1043
|
-
|
|
1044
|
-
/**
|
|
1045
|
-
* Logger boundary for expected File Tree diagnostics.
|
|
1046
|
-
*
|
|
1047
|
-
* Production delegates to the server console. Unit tests use no-op or captured
|
|
1048
|
-
* loggers and never patch the global console singleton.
|
|
1049
|
-
*/
|
|
1050
|
-
export type FileTreeLogger = {
|
|
1051
|
-
error(message: string, error?: unknown): void;
|
|
1052
|
-
};
|
|
1053
|
-
|
|
1054
|
-
/**
|
|
1055
|
-
* Required production dependencies for the File Tree application service.
|
|
1056
|
-
*
|
|
1057
|
-
* Filesystem, project lookup, workspace policy, MIME detection, concurrency,
|
|
1058
|
-
* and logging are all explicit so service construction has no hidden process,
|
|
1059
|
-
* repository, or machine-wide defaults.
|
|
1060
|
-
*/
|
|
1061
|
-
export type FileTreeServiceDependencies = {
|
|
1062
|
-
fileSystem: FileTreeFileSystem;
|
|
1063
|
-
projects: FileTreeProjectGateway;
|
|
1064
|
-
workspace: FileTreeWorkspaceGateway;
|
|
1065
|
-
resolveMimeType(filePath: string): string;
|
|
1066
|
-
fileSystemConcurrency: number;
|
|
1067
|
-
logger: FileTreeLogger;
|
|
1068
|
-
};
|
|
1069
|
-
|
|
1070
|
-
/**
|
|
1071
|
-
* Complete File Tree application-service surface consumed by HTTP routes.
|
|
1072
|
-
*
|
|
1073
|
-
* Routes parse transport inputs and call these methods; they never resolve
|
|
1074
|
-
* project repositories, validate filesystem ownership, or perform filesystem
|
|
1075
|
-
* mutations themselves.
|
|
1076
|
-
*/
|
|
1077
|
-
export type FileTreeServices = {
|
|
1078
|
-
browseWorkspace(inputPath: string | null): Promise<{
|
|
1079
|
-
path: string;
|
|
1080
|
-
suggestions: Array<{ path: string; name: string; type: 'directory' }>;
|
|
1081
|
-
}>;
|
|
1082
|
-
createWorkspaceFolder(folderPath: string): Promise<{ success: true; path: string }>;
|
|
1083
|
-
readTextFile(projectId: string, filePath: string): Promise<{ content: string; path: string }>;
|
|
1084
|
-
openFile(projectId: string, filePath: string): Promise<{ contentType: string; stream: Readable }>;
|
|
1085
|
-
saveTextFile(projectId: string, filePath: string, content: string): Promise<{
|
|
1086
|
-
success: true;
|
|
1087
|
-
path: string;
|
|
1088
|
-
message: string;
|
|
1089
|
-
}>;
|
|
1090
|
-
listProjectFiles(
|
|
1091
|
-
projectId: string,
|
|
1092
|
-
options?: { respectGitignore: boolean },
|
|
1093
|
-
): Promise<FileTreeNode[]>;
|
|
1094
|
-
createEntry(input: {
|
|
1095
|
-
projectId: string;
|
|
1096
|
-
parentPath: string;
|
|
1097
|
-
type: 'file' | 'directory';
|
|
1098
|
-
name: string;
|
|
1099
|
-
}): Promise<{ success: true; path: string; name: string; type: 'file' | 'directory'; message: string }>;
|
|
1100
|
-
renameEntry(input: { projectId: string; oldPath: string; newName: string }): Promise<{
|
|
1101
|
-
success: true;
|
|
1102
|
-
oldPath: string;
|
|
1103
|
-
newPath: string;
|
|
1104
|
-
newName: string;
|
|
1105
|
-
message: string;
|
|
1106
|
-
}>;
|
|
1107
|
-
deleteEntry(input: { projectId: string; targetPath: string }): Promise<{
|
|
1108
|
-
success: true;
|
|
1109
|
-
path: string;
|
|
1110
|
-
type: 'file' | 'directory';
|
|
1111
|
-
message: string;
|
|
1112
|
-
}>;
|
|
1113
|
-
storeUploadedFiles(input: {
|
|
1114
|
-
projectId: string;
|
|
1115
|
-
targetPath: string;
|
|
1116
|
-
relativePaths: string[];
|
|
1117
|
-
requestedFileCount: number;
|
|
1118
|
-
files: FileTreeUploadedFile[];
|
|
1119
|
-
}): Promise<{
|
|
1120
|
-
success: true;
|
|
1121
|
-
files: Array<{ name: string; path: string; size: number; mimeType: string }>;
|
|
1122
|
-
uploadedCount: number;
|
|
1123
|
-
requestedFileCount: number;
|
|
1124
|
-
targetPath: string;
|
|
1125
|
-
message: string;
|
|
1126
|
-
}>;
|
|
1127
|
-
};
|
|
1128
|
-
|
|
1129
|
-
// ---------------------------
|
|
1130
|
-
//----------------- VOICE MODULE CONTRACTS ------------
|
|
1131
|
-
/**
|
|
1132
|
-
* Per-request voice settings parsed from authenticated HTTP headers.
|
|
1133
|
-
*
|
|
1134
|
-
* The Voice routes create this value from the optional `x-voice-*` headers and
|
|
1135
|
-
* pass it to the Voice service. Empty values mean "use the server-configured
|
|
1136
|
-
* default"; the backend base URL is intentionally absent because clients must
|
|
1137
|
-
* never control the server's outbound destination.
|
|
1138
|
-
*/
|
|
1139
|
-
export type VoiceRequestOverrides = {
|
|
1140
|
-
apiKey?: string;
|
|
1141
|
-
sttModel?: string;
|
|
1142
|
-
ttsModel?: string;
|
|
1143
|
-
ttsVoice?: string;
|
|
1144
|
-
ttsFormat?: string;
|
|
1145
|
-
};
|
|
1146
|
-
|
|
1147
|
-
/**
|
|
1148
|
-
* Uploaded audio accepted by the Voice transcription service.
|
|
1149
|
-
*
|
|
1150
|
-
* Routes translate Multer's transport-specific file object into this minimal
|
|
1151
|
-
* shape so the service does not depend on Express or Multer types.
|
|
1152
|
-
*/
|
|
1153
|
-
export type VoiceAudioUpload = {
|
|
1154
|
-
bytes: Buffer;
|
|
1155
|
-
mimeType: string;
|
|
1156
|
-
fileName: string;
|
|
1157
|
-
};
|
|
1158
|
-
|
|
1159
|
-
/**
|
|
1160
|
-
* Successful speech payload returned by the Voice service.
|
|
1161
|
-
*
|
|
1162
|
-
* The route copies `contentType` to the client response and pipes `body`
|
|
1163
|
-
* without buffering the complete synthesized audio in application memory.
|
|
1164
|
-
*/
|
|
1165
|
-
export type VoiceSpeechPayload = {
|
|
1166
|
-
contentType: string;
|
|
1167
|
-
body: ReadableStream<Uint8Array> | null;
|
|
1168
|
-
};
|
|
1169
|
-
|
|
1170
|
-
/**
|
|
1171
|
-
* Explicit service result used by Voice routes instead of transport-aware
|
|
1172
|
-
* exceptions.
|
|
1173
|
-
*
|
|
1174
|
-
* Services return `ok: false` with the exact client status/message for expected
|
|
1175
|
-
* backend, validation, and timeout failures. Routes only translate the result
|
|
1176
|
-
* into HTTP output, while unexpected programming errors still reject normally.
|
|
1177
|
-
*/
|
|
1178
|
-
export type VoiceServiceResult<TValue> =
|
|
1179
|
-
| { ok: true; value: TValue }
|
|
1180
|
-
| { ok: false; status: number; error: string };
|
|
1181
|
-
|
|
1182
|
-
/**
|
|
1183
|
-
* Complete application-service surface consumed by the Voice HTTP router.
|
|
1184
|
-
*
|
|
1185
|
-
* The composition root supplies a concrete implementation with environment
|
|
1186
|
-
* configuration and an injected outbound HTTP adapter. Unit tests use the same
|
|
1187
|
-
* contract with handwritten fetch fakes and never patch global state.
|
|
1188
|
-
*/
|
|
1189
|
-
export type VoiceService = {
|
|
1190
|
-
getHealth(): { configured: boolean };
|
|
1191
|
-
transcribe(input: {
|
|
1192
|
-
audio: VoiceAudioUpload;
|
|
1193
|
-
overrides: VoiceRequestOverrides;
|
|
1194
|
-
}): Promise<VoiceServiceResult<{ text: string }>>;
|
|
1195
|
-
synthesizeSpeech(input: {
|
|
1196
|
-
text: string;
|
|
1197
|
-
overrides: VoiceRequestOverrides;
|
|
1198
|
-
}): Promise<VoiceServiceResult<VoiceSpeechPayload>>;
|
|
1199
|
-
};
|
|
1200
|
-
|
|
1201
|
-
// ---------------------------
|
|
1202
|
-
//----------------- CLI MODULE CONTRACTS ------------
|
|
1203
|
-
/**
|
|
1204
|
-
* Output boundary used by the CLI and Sandbox services.
|
|
1205
|
-
*
|
|
1206
|
-
* Production wiring delegates to the real console. Unit tests collect these
|
|
1207
|
-
* calls in arrays, which keeps command assertions deterministic and avoids
|
|
1208
|
-
* monkey-patching the global console singleton.
|
|
1209
|
-
*/
|
|
1210
|
-
export type CliOutput = {
|
|
1211
|
-
log(message?: string): void;
|
|
1212
|
-
error(message?: string): void;
|
|
1213
|
-
};
|
|
1214
|
-
|
|
1215
|
-
/**
|
|
1216
|
-
* Minimal synchronous filesystem surface shared by CLI status reporting and
|
|
1217
|
-
* sandbox workspace validation.
|
|
1218
|
-
*
|
|
1219
|
-
* The production composition root adapts Node's filesystem module. Tests supply
|
|
1220
|
-
* path-keyed fakes, so service tests never inspect or modify the real machine.
|
|
1221
|
-
*/
|
|
1222
|
-
export type CliFileSystem = {
|
|
1223
|
-
pathExists(filePath: string): boolean;
|
|
1224
|
-
getFileStats(filePath: string): { size: number; modifiedAt: Date };
|
|
1225
|
-
};
|
|
1226
|
-
|
|
1227
|
-
/**
|
|
1228
|
-
* Mutable environment view owned by the CLI application.
|
|
1229
|
-
*
|
|
1230
|
-
* CLI options update this object before the server starts. Production passes
|
|
1231
|
-
* `process.env`; tests pass a plain record to verify option precedence without
|
|
1232
|
-
* changing process-wide environment state.
|
|
1233
|
-
*/
|
|
1234
|
-
export type CliEnvironment = Record<string, string | undefined>;
|
|
1235
|
-
|
|
1236
|
-
/**
|
|
1237
|
-
* Package metadata displayed by CLI help, status, version, and update commands.
|
|
1238
|
-
*
|
|
1239
|
-
* The composition root reads this once from the application package file and
|
|
1240
|
-
* injects only the fields the service needs.
|
|
1241
|
-
*/
|
|
1242
|
-
export type CliPackageMetadata = {
|
|
1243
|
-
version: string;
|
|
1244
|
-
homepage?: string;
|
|
1245
|
-
bugsUrl?: string;
|
|
1246
|
-
};
|
|
1247
|
-
|
|
1248
|
-
/**
|
|
1249
|
-
* Executable CLI application returned by the CLI composition root.
|
|
1250
|
-
*
|
|
1251
|
-
* The thin executable entrypoint passes `process.argv` arguments to `run` and
|
|
1252
|
-
* copies the returned code to `process.exitCode`. Tests invoke the same method
|
|
1253
|
-
* directly with isolated dependencies.
|
|
1254
|
-
*/
|
|
1255
|
-
export type CliApplication = {
|
|
1256
|
-
run(argumentsList: string[]): Promise<number>;
|
|
1257
|
-
};
|
|
1258
|
-
|
|
1259
|
-
/**
|
|
1260
|
-
* Sandbox command service consumed by the top-level CLI command dispatcher.
|
|
1261
|
-
*
|
|
1262
|
-
* Keeping this behind one required dependency lets CLI tests use a tiny fake,
|
|
1263
|
-
* while focused Sandbox tests exercise subprocess and filesystem behavior with
|
|
1264
|
-
* their own handwritten adapters.
|
|
1265
|
-
*/
|
|
1266
|
-
export type SandboxCommandService = {
|
|
1267
|
-
execute(argumentsList: string[]): Promise<number>;
|
|
1268
|
-
};
|
|
337
|
+
allow: boolean;
|
|
338
|
+
updatedInput?: unknown;
|
|
339
|
+
message?: string;
|
|
340
|
+
rememberEntry?: unknown;
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
export type ProviderRuntimePermissionGateway = {
|
|
344
|
+
resolve(requestId: string, decision: ProviderPermissionDecision): void;
|
|
345
|
+
listPending(sessionId: string): unknown[];
|
|
346
|
+
};
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Provider-scoped application capabilities supplied to a runtime for one run.
|
|
350
|
+
*
|
|
351
|
+
* Keeping these lookups outside concrete SDK/CLI adapters prevents the
|
|
352
|
+
* adapters from importing services that resolve back through providerRegistry.
|
|
353
|
+
*/
|
|
354
|
+
export type ProviderRuntimeContext = {
|
|
355
|
+
resolveProviderSessionId(sessionId: string | null | undefined): string | null;
|
|
356
|
+
resolveResumeModel(
|
|
357
|
+
sessionId: string | undefined,
|
|
358
|
+
requestedModel?: string | null,
|
|
359
|
+
): Promise<string | undefined>;
|
|
360
|
+
getProviderModels(): Promise<ProviderModelsDefinition>;
|
|
361
|
+
normalizeMessage(raw: unknown, sessionId: string | null): NormalizedMessage[];
|
|
362
|
+
isProviderInstalled(): Promise<boolean>;
|
|
363
|
+
};
|
|
364
|
+
|
|
365
|
+
export type ProviderRunFunction = (
|
|
366
|
+
command: string,
|
|
367
|
+
options: AnyRecord,
|
|
368
|
+
writer: ProviderRuntimeWriter,
|
|
369
|
+
) => Promise<unknown>;
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Shared options used to fetch historical provider messages.
|
|
373
|
+
*
|
|
374
|
+
* Consumers should pass provider-specific lookup hints (`projectPath`) only
|
|
375
|
+
* when the selected provider requires them.
|
|
376
|
+
*
|
|
377
|
+
* `providerSessionId` is the provider-native session id from the sessions
|
|
378
|
+
* index (transcript file name / provider database key). Provider adapters
|
|
379
|
+
* must use it — never the app-facing session id they were called with — when
|
|
380
|
+
* matching transcript rows on disk, because app-created sessions use an
|
|
381
|
+
* app-allocated id that the provider has never seen.
|
|
382
|
+
*/
|
|
383
|
+
export type FetchHistoryOptions = {
|
|
384
|
+
projectPath?: string;
|
|
385
|
+
limit?: number | null;
|
|
386
|
+
offset?: number;
|
|
387
|
+
providerSessionId?: string;
|
|
388
|
+
};
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* Standardized response payload returned from provider history readers.
|
|
392
|
+
*
|
|
393
|
+
* Use this as the contract for APIs that return paginated conversation history.
|
|
394
|
+
*/
|
|
395
|
+
export type FetchHistoryResult = {
|
|
396
|
+
messages: NormalizedMessage[];
|
|
397
|
+
total: number;
|
|
398
|
+
hasMore: boolean;
|
|
399
|
+
offset: number;
|
|
400
|
+
limit: number | null;
|
|
401
|
+
tokenUsage?: unknown;
|
|
402
|
+
};
|
|
403
|
+
|
|
404
|
+
// ---------------------------
|
|
405
|
+
//----------------- PROVIDER SKILL TYPES ------------
|
|
406
|
+
/**
|
|
407
|
+
* Scope where a provider skill definition was discovered.
|
|
408
|
+
*
|
|
409
|
+
* Provider skill adapters should use this to describe the origin of each
|
|
410
|
+
* skill markdown file without leaking provider-specific folder names into route
|
|
411
|
+
* contracts. `repo` is used for Codex repository lookup locations, while
|
|
412
|
+
* `project` is used for providers that treat workspace-local skills as project
|
|
413
|
+
* scoped.
|
|
414
|
+
*/
|
|
415
|
+
export type ProviderSkillScope = 'user' | 'project' | 'plugin' | 'repo' | 'admin' | 'system';
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Shared input accepted by provider skill listing operations.
|
|
419
|
+
*
|
|
420
|
+
* Routes pass `workspacePath` when a caller wants project/repository skills for
|
|
421
|
+
* a specific folder. Providers should fall back to the backend process cwd when
|
|
422
|
+
* this option is omitted.
|
|
423
|
+
*/
|
|
424
|
+
export type ProviderSkillListOptions = {
|
|
425
|
+
workspacePath?: string;
|
|
426
|
+
};
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* One supporting file bundled with an uploaded provider skill.
|
|
430
|
+
*
|
|
431
|
+
* `relativePath` is resolved below the installed skill directory and must never
|
|
432
|
+
* be absolute or contain traversal segments. Text files may use `utf8`; binary
|
|
433
|
+
* scripts and assets should use `base64` so JSON transport does not corrupt
|
|
434
|
+
* their bytes.
|
|
435
|
+
*/
|
|
436
|
+
export type ProviderSkillCreateFile = {
|
|
437
|
+
relativePath: string;
|
|
438
|
+
content: string;
|
|
439
|
+
encoding: 'utf8' | 'base64';
|
|
440
|
+
};
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* One skill markdown payload submitted for provider-managed installation.
|
|
444
|
+
*
|
|
445
|
+
* `content` is the raw markdown body that will be written to `SKILL.md`.
|
|
446
|
+
* `directoryName` lets callers control the target folder name explicitly when
|
|
447
|
+
* they want stable filesystem paths that differ from the markdown front matter
|
|
448
|
+
* `name` field. `fileName` is optional upload metadata used only as a final
|
|
449
|
+
* fallback when no directory name or front matter name is present. `files`
|
|
450
|
+
* carries scripts, references, and other files from a complete skill folder.
|
|
451
|
+
*/
|
|
452
|
+
export type ProviderSkillCreateEntry = {
|
|
453
|
+
content: string;
|
|
454
|
+
directoryName?: string;
|
|
455
|
+
fileName?: string;
|
|
456
|
+
files?: ProviderSkillCreateFile[];
|
|
457
|
+
};
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* Shared input accepted by provider skill creation operations.
|
|
461
|
+
*
|
|
462
|
+
* The service layer batches multiple skill definitions in one request. Each
|
|
463
|
+
* entry can contain only markdown or a complete skill folder.
|
|
464
|
+
*/
|
|
465
|
+
export type ProviderSkillCreateInput = {
|
|
466
|
+
entries: ProviderSkillCreateEntry[];
|
|
467
|
+
};
|
|
468
|
+
|
|
469
|
+
export type ProviderSkillRemoveInput = {
|
|
470
|
+
directoryName: string;
|
|
471
|
+
};
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* Normalized skill record returned by provider skill adapters.
|
|
475
|
+
*
|
|
476
|
+
* The `command` value is the exact invocation text the selected provider expects
|
|
477
|
+
* for this skill. Claude plugin skills use a namespaced command such as
|
|
478
|
+
* `/plugin-name:skill-name`, while Codex skills use the `$skill-name` form.
|
|
479
|
+
* `sourcePath` points to the skill markdown file that produced the record so
|
|
480
|
+
* callers can distinguish duplicate skill names across scopes.
|
|
481
|
+
*/
|
|
482
|
+
export type ProviderSkill = {
|
|
483
|
+
provider: LLMProvider;
|
|
484
|
+
name: string;
|
|
485
|
+
description: string;
|
|
486
|
+
command: string;
|
|
487
|
+
scope: ProviderSkillScope;
|
|
488
|
+
sourcePath: string;
|
|
489
|
+
pluginName?: string;
|
|
490
|
+
pluginId?: string;
|
|
491
|
+
};
|
|
492
|
+
|
|
493
|
+
/**
|
|
494
|
+
* Internal source descriptor consumed by shared provider skill discovery logic.
|
|
495
|
+
*
|
|
496
|
+
* Concrete provider adapters build these records from their native lookup rules.
|
|
497
|
+
* The shared skills provider then scans `rootDir` for child skill markdown files
|
|
498
|
+
* and uses `commandForSkill` or `commandPrefix` to produce the provider-specific
|
|
499
|
+
* invocation command. Set `recursive` only when a provider stores skills under
|
|
500
|
+
* arbitrary nested folders below the source root.
|
|
501
|
+
*/
|
|
502
|
+
export type ProviderSkillSource = {
|
|
503
|
+
scope: ProviderSkillScope;
|
|
504
|
+
rootDir: string;
|
|
505
|
+
recursive?: boolean;
|
|
506
|
+
commandPrefix?: '/' | '$';
|
|
507
|
+
commandForSkill?: (skillName: string) => string;
|
|
508
|
+
pluginName?: string;
|
|
509
|
+
pluginId?: string;
|
|
510
|
+
};
|
|
511
|
+
|
|
512
|
+
// ---------------------------
|
|
513
|
+
//----------------- SHARED ERROR TYPES ------------
|
|
514
|
+
/**
|
|
515
|
+
* Optional metadata used when constructing application-level errors.
|
|
516
|
+
*
|
|
517
|
+
* `statusCode` should reflect the HTTP response status, while `code` identifies
|
|
518
|
+
* the stable machine-readable error category.
|
|
519
|
+
*/
|
|
520
|
+
export type AppErrorOptions = {
|
|
521
|
+
code?: string;
|
|
522
|
+
statusCode?: number;
|
|
523
|
+
details?: unknown;
|
|
524
|
+
};
|
|
525
|
+
|
|
526
|
+
// ---------------------------
|
|
527
|
+
//----------------- MCP TYPES ------------
|
|
528
|
+
/**
|
|
529
|
+
* Scope where an MCP server definition is stored and resolved.
|
|
530
|
+
*
|
|
531
|
+
* `user` is global for a user account, `local` is provider-local, and `project`
|
|
532
|
+
* is tied to a specific project path.
|
|
533
|
+
*/
|
|
534
|
+
export type McpScope = 'user' | 'local' | 'project';
|
|
535
|
+
|
|
536
|
+
/**
|
|
537
|
+
* Transport protocol used by an MCP server definition.
|
|
538
|
+
*/
|
|
539
|
+
export type McpTransport = 'stdio' | 'http' | 'sse';
|
|
540
|
+
|
|
541
|
+
/**
|
|
542
|
+
* Normalized MCP server model exposed to frontend and route handlers.
|
|
543
|
+
*
|
|
544
|
+
* Provider adapters should map provider-native config to this structure before
|
|
545
|
+
* returning results.
|
|
546
|
+
*/
|
|
547
|
+
export type ProviderMcpServer = {
|
|
548
|
+
provider: LLMProvider;
|
|
549
|
+
name: string;
|
|
550
|
+
scope: McpScope;
|
|
551
|
+
transport: McpTransport;
|
|
552
|
+
command?: string;
|
|
553
|
+
args?: string[];
|
|
554
|
+
env?: Record<string, string>;
|
|
555
|
+
cwd?: string;
|
|
556
|
+
url?: string;
|
|
557
|
+
headers?: Record<string, string>;
|
|
558
|
+
envVars?: string[];
|
|
559
|
+
bearerTokenEnvVar?: string;
|
|
560
|
+
envHttpHeaders?: Record<string, string>;
|
|
561
|
+
};
|
|
562
|
+
|
|
563
|
+
/**
|
|
564
|
+
* Payload for create/update MCP server operations.
|
|
565
|
+
*
|
|
566
|
+
* Routes and services should accept this type, validate it, and then persist it
|
|
567
|
+
* through provider-specific MCP repositories.
|
|
568
|
+
*/
|
|
569
|
+
export type UpsertProviderMcpServerInput = {
|
|
570
|
+
name: string;
|
|
571
|
+
scope?: McpScope;
|
|
572
|
+
transport: McpTransport;
|
|
573
|
+
workspacePath?: string;
|
|
574
|
+
command?: string;
|
|
575
|
+
args?: string[];
|
|
576
|
+
env?: Record<string, string>;
|
|
577
|
+
cwd?: string;
|
|
578
|
+
url?: string;
|
|
579
|
+
headers?: Record<string, string>;
|
|
580
|
+
envVars?: string[];
|
|
581
|
+
bearerTokenEnvVar?: string;
|
|
582
|
+
envHttpHeaders?: Record<string, string>;
|
|
583
|
+
};
|
|
584
|
+
|
|
585
|
+
// ---------------------------
|
|
586
|
+
//----------------- PROVIDER AUTH TYPES ------------
|
|
587
|
+
/**
|
|
588
|
+
* Authentication status result returned by provider health checks.
|
|
589
|
+
*
|
|
590
|
+
* This shape is consumed by settings/status endpoints to report installation and
|
|
591
|
+
* credential state for each provider.
|
|
592
|
+
*/
|
|
593
|
+
export type ProviderAuthStatus = {
|
|
594
|
+
installed: boolean;
|
|
595
|
+
provider: LLMProvider;
|
|
596
|
+
authenticated: boolean;
|
|
597
|
+
email: string | null;
|
|
598
|
+
method: string | null;
|
|
599
|
+
error?: string;
|
|
600
|
+
};
|
|
601
|
+
|
|
602
|
+
// ---------------------------
|
|
603
|
+
//----------------- SHARED DATABASE CREDENTIAL TYPES ------------
|
|
604
|
+
/**
|
|
605
|
+
* Safe credential view returned by credential listing APIs.
|
|
606
|
+
*
|
|
607
|
+
* This intentionally excludes the raw credential secret while still exposing
|
|
608
|
+
* metadata needed for UI rendering and management operations.
|
|
609
|
+
*/
|
|
610
|
+
export type CredentialPublicRow = {
|
|
611
|
+
id: number;
|
|
612
|
+
credential_name: string;
|
|
613
|
+
credential_type: string;
|
|
614
|
+
description: string | null;
|
|
615
|
+
created_at: string;
|
|
616
|
+
is_active: number;
|
|
617
|
+
};
|
|
618
|
+
|
|
619
|
+
/**
|
|
620
|
+
* Result returned after creating a credential record.
|
|
621
|
+
*
|
|
622
|
+
* Use this return shape when callers need the created id and display metadata,
|
|
623
|
+
* but must never receive the stored secret value.
|
|
624
|
+
*/
|
|
625
|
+
export type CreateCredentialResult = {
|
|
626
|
+
id: number | bigint;
|
|
627
|
+
credentialName: string;
|
|
628
|
+
credentialType: string;
|
|
629
|
+
};
|
|
630
|
+
|
|
631
|
+
// ---------------------------
|
|
632
|
+
//----------------- PROJECT PERSISTENCE TYPES ------------
|
|
633
|
+
/**
|
|
634
|
+
* Canonical project row shape returned by the projects repository.
|
|
635
|
+
*
|
|
636
|
+
* Use this type whenever backend services need to pass around one database
|
|
637
|
+
* project record without leaking raw SQL row typing across modules.
|
|
638
|
+
*/
|
|
639
|
+
export type ProjectRepositoryRow = {
|
|
640
|
+
project_id: string;
|
|
641
|
+
project_path: string;
|
|
642
|
+
custom_project_name: string | null;
|
|
643
|
+
isStarred: number;
|
|
644
|
+
isArchived: number;
|
|
645
|
+
};
|
|
646
|
+
|
|
647
|
+
/**
|
|
648
|
+
* Result category returned by `projectsDb.createProjectPath`.
|
|
649
|
+
*
|
|
650
|
+
* `created` means a fresh row was inserted, `reactivated_archived` means an
|
|
651
|
+
* existing archived path was accepted and updated, and `active_conflict` means
|
|
652
|
+
* an already-active path blocked project creation.
|
|
653
|
+
*/
|
|
654
|
+
export type CreateProjectPathOutcome =
|
|
655
|
+
| 'created'
|
|
656
|
+
| 'reactivated_archived'
|
|
657
|
+
| 'active_conflict';
|
|
658
|
+
|
|
659
|
+
/**
|
|
660
|
+
* Structured result returned by project-path upsert operations.
|
|
661
|
+
*
|
|
662
|
+
* Services should use this result to decide whether a request succeeded,
|
|
663
|
+
* should return a conflict, or needs follow-up retrieval of row metadata.
|
|
664
|
+
*/
|
|
665
|
+
export type CreateProjectPathResult = {
|
|
666
|
+
outcome: CreateProjectPathOutcome;
|
|
667
|
+
project: ProjectRepositoryRow | null;
|
|
668
|
+
};
|
|
669
|
+
|
|
670
|
+
/**
|
|
671
|
+
* Validation result for user-supplied workspace/project paths.
|
|
672
|
+
*
|
|
673
|
+
* `resolvedPath` is present only when validation succeeds. `error` is present
|
|
674
|
+
* only when validation fails and is suitable for user-facing diagnostics.
|
|
675
|
+
*/
|
|
676
|
+
export type WorkspacePathValidationResult = {
|
|
677
|
+
valid: boolean;
|
|
678
|
+
resolvedPath?: string;
|
|
679
|
+
error?: string;
|
|
680
|
+
};
|
|
681
|
+
|
|
682
|
+
// ---------------------------
|
|
683
|
+
//----------------- GIT WORKTREE MANAGEMENT ------------
|
|
684
|
+
/**
|
|
685
|
+
* Captured output of one completed `git` invocation.
|
|
686
|
+
*
|
|
687
|
+
* Returned by `GitCommandRunner` implementations so worktree services can read
|
|
688
|
+
* both streams without caring about process plumbing.
|
|
689
|
+
*/
|
|
690
|
+
export type GitCommandResult = {
|
|
691
|
+
stdout: string;
|
|
692
|
+
stderr: string;
|
|
693
|
+
};
|
|
694
|
+
|
|
695
|
+
/**
|
|
696
|
+
* Executes `git <args>` inside `cwd` and resolves with the captured output.
|
|
697
|
+
*
|
|
698
|
+
* All worktree services receive their git access through this contract so
|
|
699
|
+
* tests can inject a fake runner instead of spawning real processes. The
|
|
700
|
+
* promise must reject (with `stderr` attached when available) on a non-zero
|
|
701
|
+
* exit code.
|
|
702
|
+
*/
|
|
703
|
+
export type GitCommandRunner = (args: string[], cwd: string) => Promise<GitCommandResult>;
|
|
704
|
+
|
|
705
|
+
/**
|
|
706
|
+
* One entry parsed from `git worktree list --porcelain`.
|
|
707
|
+
*
|
|
708
|
+
* This is the raw repository-level view (path/HEAD/branch/flags) before any
|
|
709
|
+
* enrichment with project links or ahead/behind counts. `branch` is null for
|
|
710
|
+
* detached-HEAD worktrees.
|
|
711
|
+
*/
|
|
712
|
+
export type WorktreePorcelainEntry = {
|
|
713
|
+
path: string;
|
|
714
|
+
headSha: string | null;
|
|
715
|
+
branch: string | null;
|
|
716
|
+
isDetached: boolean;
|
|
717
|
+
isLocked: boolean;
|
|
718
|
+
isPrunable: boolean;
|
|
719
|
+
};
|
|
720
|
+
|
|
721
|
+
/**
|
|
722
|
+
* Fully enriched worktree row served to the UI.
|
|
723
|
+
*
|
|
724
|
+
* Extends the porcelain entry with everything the Worktrees panel renders:
|
|
725
|
+
* dirty-file count, ahead/behind relative to the base branch (the branch
|
|
726
|
+
* checked out in the main worktree), last-commit metadata, and the WindCli
|
|
727
|
+
* project row linked to the worktree directory (if one was registered).
|
|
728
|
+
*/
|
|
729
|
+
export type WorktreeDescriptor = {
|
|
730
|
+
path: string;
|
|
731
|
+
branch: string | null;
|
|
732
|
+
headSha: string | null;
|
|
733
|
+
isMain: boolean;
|
|
734
|
+
isCurrent: boolean;
|
|
735
|
+
isLocked: boolean;
|
|
736
|
+
isDetached: boolean;
|
|
737
|
+
changedFileCount: number;
|
|
738
|
+
ahead: number;
|
|
739
|
+
behind: number;
|
|
740
|
+
lastCommitSubject: string | null;
|
|
741
|
+
lastCommitDate: string | null;
|
|
742
|
+
linkedProjectId: string | null;
|
|
743
|
+
linkedProjectArchived: boolean;
|
|
744
|
+
};
|
|
745
|
+
|
|
746
|
+
/**
|
|
747
|
+
* Response payload of `GET /api/worktrees`.
|
|
748
|
+
*
|
|
749
|
+
* `baseBranch` is the branch checked out in the main worktree — the merge
|
|
750
|
+
* target offered by the UI. `worktrees` always lists the main worktree first.
|
|
751
|
+
*/
|
|
752
|
+
export type WorktreeListResult = {
|
|
753
|
+
repositoryRoot: string;
|
|
754
|
+
baseBranch: string | null;
|
|
755
|
+
worktrees: WorktreeDescriptor[];
|
|
756
|
+
};
|
|
757
|
+
|
|
758
|
+
// ---------------------------
|
|
759
|
+
//----------------- WORKTREE SERVICE INPUTS AND RESULTS ------------
|
|
760
|
+
/**
|
|
761
|
+
* Input accepted by the worktree-listing workflow.
|
|
762
|
+
*
|
|
763
|
+
* `projectPath` may point at the main checkout or any linked worktree. The
|
|
764
|
+
* service uses Git to resolve the complete repository-level worktree list.
|
|
765
|
+
*/
|
|
766
|
+
export type ListWorktreesInput = {
|
|
767
|
+
projectPath: string;
|
|
768
|
+
};
|
|
769
|
+
|
|
770
|
+
/**
|
|
771
|
+
* Input accepted when creating a linked Git worktree.
|
|
772
|
+
*
|
|
773
|
+
* `branch` is checked out when it already exists, otherwise it is created from
|
|
774
|
+
* `baseBranch`. When `baseBranch` is omitted, the main worktree branch is used.
|
|
775
|
+
*/
|
|
776
|
+
export type CreateWorktreeInput = {
|
|
777
|
+
projectPath: string;
|
|
778
|
+
branch: string;
|
|
779
|
+
baseBranch?: string | null;
|
|
780
|
+
};
|
|
781
|
+
|
|
782
|
+
/**
|
|
783
|
+
* Result of successfully creating a linked Git worktree.
|
|
784
|
+
*
|
|
785
|
+
* `createdBranch` distinguishes a new branch from an existing branch checkout,
|
|
786
|
+
* allowing API clients to accurately describe what Git changed.
|
|
787
|
+
*/
|
|
788
|
+
export type CreateWorktreeResult = {
|
|
789
|
+
worktreePath: string;
|
|
790
|
+
branch: string;
|
|
791
|
+
createdBranch: boolean;
|
|
792
|
+
};
|
|
793
|
+
|
|
794
|
+
/**
|
|
795
|
+
* Result of atomically creating and registering a worktree for project use.
|
|
796
|
+
*
|
|
797
|
+
* The Worktrees application service compensates the Git creation if project
|
|
798
|
+
* registration fails, so routes only receive this shape after both steps pass.
|
|
799
|
+
*/
|
|
800
|
+
export type CreateAndOpenWorktreeResult = CreateWorktreeResult & {
|
|
801
|
+
project: WorktreeProjectView;
|
|
802
|
+
};
|
|
803
|
+
|
|
804
|
+
/**
|
|
805
|
+
* Input accepted when registering an existing worktree as a WindCli project.
|
|
806
|
+
*
|
|
807
|
+
* The service verifies that `worktreePath` belongs to the repository containing
|
|
808
|
+
* `projectPath` before it creates or restores any project record.
|
|
809
|
+
*/
|
|
810
|
+
export type OpenWorktreeInput = {
|
|
811
|
+
projectPath: string;
|
|
812
|
+
worktreePath: string;
|
|
813
|
+
};
|
|
814
|
+
|
|
815
|
+
/**
|
|
816
|
+
* Project view returned after a worktree is opened in WindCli.
|
|
817
|
+
*
|
|
818
|
+
* This deliberately mirrors the project-selection payload used by the Projects
|
|
819
|
+
* module so the frontend can switch to the worktree without another lookup.
|
|
820
|
+
*/
|
|
821
|
+
export type WorktreeProjectView = {
|
|
822
|
+
projectId: string;
|
|
823
|
+
path: string;
|
|
824
|
+
fullPath: string;
|
|
825
|
+
displayName: string;
|
|
826
|
+
isStarred: boolean;
|
|
827
|
+
sessions: [];
|
|
828
|
+
sessionMeta: { hasMore: false; total: 0 };
|
|
829
|
+
};
|
|
830
|
+
|
|
831
|
+
/**
|
|
832
|
+
* Input accepted when removing a linked Git worktree.
|
|
833
|
+
*
|
|
834
|
+
* `force` permits removal with local changes. `deleteBranch` requests
|
|
835
|
+
* best-effort branch cleanup after the worktree directory is removed.
|
|
836
|
+
*/
|
|
837
|
+
export type RemoveWorktreeInput = {
|
|
838
|
+
projectPath: string;
|
|
839
|
+
worktreePath: string;
|
|
840
|
+
force?: boolean;
|
|
841
|
+
deleteBranch?: boolean;
|
|
842
|
+
};
|
|
843
|
+
|
|
844
|
+
/**
|
|
845
|
+
* Result of removing a linked Git worktree.
|
|
846
|
+
*
|
|
847
|
+
* `archivalError` reports best-effort project archival failure after Git has
|
|
848
|
+
* already removed the worktree, allowing callers to represent partial success.
|
|
849
|
+
*/
|
|
850
|
+
export type RemoveWorktreeResult = {
|
|
851
|
+
removedPath: string;
|
|
852
|
+
branch: string | null;
|
|
853
|
+
branchDeleted: boolean;
|
|
854
|
+
archivedProjectId: string | null;
|
|
855
|
+
archivalError: string | null;
|
|
856
|
+
};
|
|
857
|
+
|
|
858
|
+
/**
|
|
859
|
+
* Input accepted when merging a linked worktree into the main worktree branch.
|
|
860
|
+
*
|
|
861
|
+
* The service verifies both worktrees are clean, supports squash and regular
|
|
862
|
+
* merges, and may remove the source worktree after a successful merge.
|
|
863
|
+
*/
|
|
864
|
+
export type MergeWorktreeInput = {
|
|
865
|
+
projectPath: string;
|
|
866
|
+
worktreePath: string;
|
|
867
|
+
squash?: boolean;
|
|
868
|
+
message?: string | null;
|
|
869
|
+
removeAfterMerge?: boolean;
|
|
870
|
+
};
|
|
871
|
+
|
|
872
|
+
/**
|
|
873
|
+
* Result of a completed worktree merge.
|
|
874
|
+
*
|
|
875
|
+
* `removedWorktree` is populated only when post-merge removal succeeds.
|
|
876
|
+
* `cleanupError` reports failed optional removal without misrepresenting the
|
|
877
|
+
* already-completed merge as a failure.
|
|
878
|
+
*/
|
|
879
|
+
export type MergeWorktreeResult = {
|
|
880
|
+
mergedBranch: string;
|
|
881
|
+
targetBranch: string;
|
|
882
|
+
squash: boolean;
|
|
883
|
+
removedWorktree: RemoveWorktreeResult | null;
|
|
884
|
+
cleanupError: string | null;
|
|
885
|
+
};
|
|
886
|
+
|
|
887
|
+
// ---------------------------
|
|
888
|
+
//----------------- WORKTREE MODULE DEPENDENCY CONTRACTS ------------
|
|
889
|
+
/**
|
|
890
|
+
* Filesystem capability required by the Worktrees module.
|
|
891
|
+
*
|
|
892
|
+
* Production wiring checks the real filesystem; unit tests provide a small
|
|
893
|
+
* deterministic fake so worktree creation never touches developer directories.
|
|
894
|
+
*/
|
|
895
|
+
export type WorktreeFileSystem = {
|
|
896
|
+
pathExists(candidatePath: string): Promise<boolean>;
|
|
897
|
+
};
|
|
898
|
+
|
|
899
|
+
/**
|
|
900
|
+
* Project-management boundary consumed by Worktrees workflows.
|
|
901
|
+
*
|
|
902
|
+
* The Worktrees module uses this contract instead of importing Database or
|
|
903
|
+
* Projects internals. Production adapters delegate through those modules'
|
|
904
|
+
* `index.ts` barrels, while unit tests supply in-memory functions.
|
|
905
|
+
*/
|
|
906
|
+
export type WorktreeProjectGateway = {
|
|
907
|
+
getProjectPathById(projectId: string): string | null;
|
|
908
|
+
getProjectByPath(projectPath: string): ProjectRepositoryRow | null;
|
|
909
|
+
createProject(input: {
|
|
910
|
+
projectPath: string;
|
|
911
|
+
customName: string;
|
|
912
|
+
}): Promise<{
|
|
913
|
+
outcome: 'created' | 'reactivated_archived';
|
|
914
|
+
project: { projectId: string };
|
|
915
|
+
}>;
|
|
916
|
+
restoreProject(projectId: string): void | Promise<void>;
|
|
917
|
+
archiveProject(projectId: string): void | Promise<void>;
|
|
918
|
+
};
|
|
919
|
+
|
|
920
|
+
/**
|
|
921
|
+
* Complete application-service surface used by the Worktrees HTTP router.
|
|
922
|
+
*
|
|
923
|
+
* Routes parse transport values and call these functions; they do not import
|
|
924
|
+
* repositories, filesystem adapters, Git runners, or individual service files.
|
|
925
|
+
*/
|
|
926
|
+
export type WorktreeServices = {
|
|
927
|
+
resolveProjectPath(projectId: string): string;
|
|
928
|
+
list(input: ListWorktreesInput): Promise<WorktreeListResult>;
|
|
929
|
+
create(input: CreateWorktreeInput): Promise<CreateWorktreeResult>;
|
|
930
|
+
createAndOpen(input: CreateWorktreeInput): Promise<CreateAndOpenWorktreeResult>;
|
|
931
|
+
open(input: OpenWorktreeInput): Promise<WorktreeProjectView>;
|
|
932
|
+
merge(input: MergeWorktreeInput): Promise<MergeWorktreeResult>;
|
|
933
|
+
remove(input: RemoveWorktreeInput): Promise<RemoveWorktreeResult>;
|
|
934
|
+
};
|
|
935
|
+
|
|
936
|
+
// ---------------------------
|
|
937
|
+
//----------------- FILE TREE MODULE CONTRACTS ------------
|
|
938
|
+
/**
|
|
939
|
+
* One filesystem item returned by the File Tree API.
|
|
940
|
+
*
|
|
941
|
+
* The service populates metadata without following symlinks and recursively
|
|
942
|
+
* attaches `children` only while the requested depth permits traversal. The
|
|
943
|
+
* frontend uses the absolute `path` as the stable identifier for editor and
|
|
944
|
+
* file-operation requests.
|
|
945
|
+
*/
|
|
946
|
+
export type FileTreeNode = {
|
|
947
|
+
name: string;
|
|
948
|
+
path: string;
|
|
949
|
+
type: 'file' | 'directory';
|
|
950
|
+
size: number;
|
|
951
|
+
modified: string | null;
|
|
952
|
+
permissions: string;
|
|
953
|
+
permissionsRwx: string;
|
|
954
|
+
isSymlink?: boolean;
|
|
955
|
+
children?: FileTreeNode[];
|
|
956
|
+
};
|
|
957
|
+
|
|
958
|
+
/**
|
|
959
|
+
* Minimal directory-entry shape required during File Tree traversal.
|
|
960
|
+
*
|
|
961
|
+
* Production adapts Node `Dirent` objects to this structural contract. Tests
|
|
962
|
+
* provide small handwritten entries and therefore never read real directories.
|
|
963
|
+
*/
|
|
964
|
+
export type FileTreeDirectoryEntry = {
|
|
965
|
+
name: string;
|
|
966
|
+
isDirectory(): boolean;
|
|
967
|
+
};
|
|
968
|
+
|
|
969
|
+
/**
|
|
970
|
+
* Minimal file-stat shape used for tree metadata and delete decisions.
|
|
971
|
+
*
|
|
972
|
+
* The numeric mode is converted to octal and rwx strings for the UI. `lstat`
|
|
973
|
+
* supplies symlink state while `stat` is used when deciding file versus folder
|
|
974
|
+
* deletion behavior.
|
|
975
|
+
*/
|
|
976
|
+
export type FileTreeStats = {
|
|
977
|
+
size: number;
|
|
978
|
+
mtime: Date;
|
|
979
|
+
mode: number;
|
|
980
|
+
isDirectory(): boolean;
|
|
981
|
+
isSymbolicLink(): boolean;
|
|
982
|
+
};
|
|
983
|
+
|
|
984
|
+
/**
|
|
985
|
+
* Complete filesystem capability injected into File Tree services.
|
|
986
|
+
*
|
|
987
|
+
* The production composition root delegates these operations to Node's fs
|
|
988
|
+
* APIs. Unit tests provide deterministic path-keyed fakes so service tests
|
|
989
|
+
* cannot inspect, write, rename, or delete developer files.
|
|
990
|
+
*/
|
|
991
|
+
export type FileTreeFileSystem = {
|
|
992
|
+
access(candidatePath: string): Promise<void>;
|
|
993
|
+
stat(candidatePath: string): Promise<FileTreeStats>;
|
|
994
|
+
lstat(candidatePath: string): Promise<FileTreeStats>;
|
|
995
|
+
// Streamed rather than returned as an array so a directory with millions of
|
|
996
|
+
// children is abandoned at the entry limit instead of being materialized.
|
|
997
|
+
openDirectory(directoryPath: string): AsyncIterable<FileTreeDirectoryEntry>;
|
|
998
|
+
realpath(candidatePath: string): Promise<string>;
|
|
999
|
+
readTextFile(filePath: string): Promise<string>;
|
|
1000
|
+
writeTextFile(filePath: string, content: string): Promise<void>;
|
|
1001
|
+
makeDirectory(directoryPath: string, recursive: boolean): Promise<void>;
|
|
1002
|
+
rename(oldPath: string, newPath: string): Promise<void>;
|
|
1003
|
+
removeDirectory(directoryPath: string): Promise<void>;
|
|
1004
|
+
unlink(filePath: string): Promise<void>;
|
|
1005
|
+
copyFile(sourcePath: string, destinationPath: string): Promise<void>;
|
|
1006
|
+
createReadStream(filePath: string): Readable;
|
|
1007
|
+
};
|
|
1008
|
+
|
|
1009
|
+
/**
|
|
1010
|
+
* Project lookup boundary consumed by File Tree workflows.
|
|
1011
|
+
*
|
|
1012
|
+
* File Tree services resolve DB-assigned project ids through this contract and
|
|
1013
|
+
* never import the Database module or its repositories directly.
|
|
1014
|
+
*/
|
|
1015
|
+
export type FileTreeProjectGateway = {
|
|
1016
|
+
getProjectPathById(projectId: string): string | null | Promise<string | null>;
|
|
1017
|
+
};
|
|
1018
|
+
|
|
1019
|
+
/**
|
|
1020
|
+
* Workspace validation boundary used by filesystem browsing and folder creation.
|
|
1021
|
+
*
|
|
1022
|
+
* The injected validator enforces the configured workspace root and resolves
|
|
1023
|
+
* symlinks before the File Tree service exposes or mutates paths.
|
|
1024
|
+
*/
|
|
1025
|
+
export type FileTreeWorkspaceGateway = {
|
|
1026
|
+
rootPath: string;
|
|
1027
|
+
validatePath(candidatePath: string): Promise<WorkspacePathValidationResult>;
|
|
1028
|
+
};
|
|
1029
|
+
|
|
1030
|
+
/**
|
|
1031
|
+
* Uploaded-file record passed from the Multer transport adapter into the File
|
|
1032
|
+
* Tree service.
|
|
1033
|
+
*
|
|
1034
|
+
* Transport-specific field names are normalized so upload workflows do not
|
|
1035
|
+
* depend on Express or Multer types.
|
|
1036
|
+
*/
|
|
1037
|
+
export type FileTreeUploadedFile = {
|
|
1038
|
+
originalName: string;
|
|
1039
|
+
temporaryPath: string;
|
|
1040
|
+
size: number;
|
|
1041
|
+
mimeType: string;
|
|
1042
|
+
};
|
|
1043
|
+
|
|
1044
|
+
/**
|
|
1045
|
+
* Logger boundary for expected File Tree diagnostics.
|
|
1046
|
+
*
|
|
1047
|
+
* Production delegates to the server console. Unit tests use no-op or captured
|
|
1048
|
+
* loggers and never patch the global console singleton.
|
|
1049
|
+
*/
|
|
1050
|
+
export type FileTreeLogger = {
|
|
1051
|
+
error(message: string, error?: unknown): void;
|
|
1052
|
+
};
|
|
1053
|
+
|
|
1054
|
+
/**
|
|
1055
|
+
* Required production dependencies for the File Tree application service.
|
|
1056
|
+
*
|
|
1057
|
+
* Filesystem, project lookup, workspace policy, MIME detection, concurrency,
|
|
1058
|
+
* and logging are all explicit so service construction has no hidden process,
|
|
1059
|
+
* repository, or machine-wide defaults.
|
|
1060
|
+
*/
|
|
1061
|
+
export type FileTreeServiceDependencies = {
|
|
1062
|
+
fileSystem: FileTreeFileSystem;
|
|
1063
|
+
projects: FileTreeProjectGateway;
|
|
1064
|
+
workspace: FileTreeWorkspaceGateway;
|
|
1065
|
+
resolveMimeType(filePath: string): string;
|
|
1066
|
+
fileSystemConcurrency: number;
|
|
1067
|
+
logger: FileTreeLogger;
|
|
1068
|
+
};
|
|
1069
|
+
|
|
1070
|
+
/**
|
|
1071
|
+
* Complete File Tree application-service surface consumed by HTTP routes.
|
|
1072
|
+
*
|
|
1073
|
+
* Routes parse transport inputs and call these methods; they never resolve
|
|
1074
|
+
* project repositories, validate filesystem ownership, or perform filesystem
|
|
1075
|
+
* mutations themselves.
|
|
1076
|
+
*/
|
|
1077
|
+
export type FileTreeServices = {
|
|
1078
|
+
browseWorkspace(inputPath: string | null): Promise<{
|
|
1079
|
+
path: string;
|
|
1080
|
+
suggestions: Array<{ path: string; name: string; type: 'directory' }>;
|
|
1081
|
+
}>;
|
|
1082
|
+
createWorkspaceFolder(folderPath: string): Promise<{ success: true; path: string }>;
|
|
1083
|
+
readTextFile(projectId: string, filePath: string): Promise<{ content: string; path: string }>;
|
|
1084
|
+
openFile(projectId: string, filePath: string): Promise<{ contentType: string; stream: Readable }>;
|
|
1085
|
+
saveTextFile(projectId: string, filePath: string, content: string): Promise<{
|
|
1086
|
+
success: true;
|
|
1087
|
+
path: string;
|
|
1088
|
+
message: string;
|
|
1089
|
+
}>;
|
|
1090
|
+
listProjectFiles(
|
|
1091
|
+
projectId: string,
|
|
1092
|
+
options?: { respectGitignore: boolean },
|
|
1093
|
+
): Promise<FileTreeNode[]>;
|
|
1094
|
+
createEntry(input: {
|
|
1095
|
+
projectId: string;
|
|
1096
|
+
parentPath: string;
|
|
1097
|
+
type: 'file' | 'directory';
|
|
1098
|
+
name: string;
|
|
1099
|
+
}): Promise<{ success: true; path: string; name: string; type: 'file' | 'directory'; message: string }>;
|
|
1100
|
+
renameEntry(input: { projectId: string; oldPath: string; newName: string }): Promise<{
|
|
1101
|
+
success: true;
|
|
1102
|
+
oldPath: string;
|
|
1103
|
+
newPath: string;
|
|
1104
|
+
newName: string;
|
|
1105
|
+
message: string;
|
|
1106
|
+
}>;
|
|
1107
|
+
deleteEntry(input: { projectId: string; targetPath: string }): Promise<{
|
|
1108
|
+
success: true;
|
|
1109
|
+
path: string;
|
|
1110
|
+
type: 'file' | 'directory';
|
|
1111
|
+
message: string;
|
|
1112
|
+
}>;
|
|
1113
|
+
storeUploadedFiles(input: {
|
|
1114
|
+
projectId: string;
|
|
1115
|
+
targetPath: string;
|
|
1116
|
+
relativePaths: string[];
|
|
1117
|
+
requestedFileCount: number;
|
|
1118
|
+
files: FileTreeUploadedFile[];
|
|
1119
|
+
}): Promise<{
|
|
1120
|
+
success: true;
|
|
1121
|
+
files: Array<{ name: string; path: string; size: number; mimeType: string }>;
|
|
1122
|
+
uploadedCount: number;
|
|
1123
|
+
requestedFileCount: number;
|
|
1124
|
+
targetPath: string;
|
|
1125
|
+
message: string;
|
|
1126
|
+
}>;
|
|
1127
|
+
};
|
|
1128
|
+
|
|
1129
|
+
// ---------------------------
|
|
1130
|
+
//----------------- VOICE MODULE CONTRACTS ------------
|
|
1131
|
+
/**
|
|
1132
|
+
* Per-request voice settings parsed from authenticated HTTP headers.
|
|
1133
|
+
*
|
|
1134
|
+
* The Voice routes create this value from the optional `x-voice-*` headers and
|
|
1135
|
+
* pass it to the Voice service. Empty values mean "use the server-configured
|
|
1136
|
+
* default"; the backend base URL is intentionally absent because clients must
|
|
1137
|
+
* never control the server's outbound destination.
|
|
1138
|
+
*/
|
|
1139
|
+
export type VoiceRequestOverrides = {
|
|
1140
|
+
apiKey?: string;
|
|
1141
|
+
sttModel?: string;
|
|
1142
|
+
ttsModel?: string;
|
|
1143
|
+
ttsVoice?: string;
|
|
1144
|
+
ttsFormat?: string;
|
|
1145
|
+
};
|
|
1146
|
+
|
|
1147
|
+
/**
|
|
1148
|
+
* Uploaded audio accepted by the Voice transcription service.
|
|
1149
|
+
*
|
|
1150
|
+
* Routes translate Multer's transport-specific file object into this minimal
|
|
1151
|
+
* shape so the service does not depend on Express or Multer types.
|
|
1152
|
+
*/
|
|
1153
|
+
export type VoiceAudioUpload = {
|
|
1154
|
+
bytes: Buffer;
|
|
1155
|
+
mimeType: string;
|
|
1156
|
+
fileName: string;
|
|
1157
|
+
};
|
|
1158
|
+
|
|
1159
|
+
/**
|
|
1160
|
+
* Successful speech payload returned by the Voice service.
|
|
1161
|
+
*
|
|
1162
|
+
* The route copies `contentType` to the client response and pipes `body`
|
|
1163
|
+
* without buffering the complete synthesized audio in application memory.
|
|
1164
|
+
*/
|
|
1165
|
+
export type VoiceSpeechPayload = {
|
|
1166
|
+
contentType: string;
|
|
1167
|
+
body: ReadableStream<Uint8Array> | null;
|
|
1168
|
+
};
|
|
1169
|
+
|
|
1170
|
+
/**
|
|
1171
|
+
* Explicit service result used by Voice routes instead of transport-aware
|
|
1172
|
+
* exceptions.
|
|
1173
|
+
*
|
|
1174
|
+
* Services return `ok: false` with the exact client status/message for expected
|
|
1175
|
+
* backend, validation, and timeout failures. Routes only translate the result
|
|
1176
|
+
* into HTTP output, while unexpected programming errors still reject normally.
|
|
1177
|
+
*/
|
|
1178
|
+
export type VoiceServiceResult<TValue> =
|
|
1179
|
+
| { ok: true; value: TValue }
|
|
1180
|
+
| { ok: false; status: number; error: string };
|
|
1181
|
+
|
|
1182
|
+
/**
|
|
1183
|
+
* Complete application-service surface consumed by the Voice HTTP router.
|
|
1184
|
+
*
|
|
1185
|
+
* The composition root supplies a concrete implementation with environment
|
|
1186
|
+
* configuration and an injected outbound HTTP adapter. Unit tests use the same
|
|
1187
|
+
* contract with handwritten fetch fakes and never patch global state.
|
|
1188
|
+
*/
|
|
1189
|
+
export type VoiceService = {
|
|
1190
|
+
getHealth(): { configured: boolean };
|
|
1191
|
+
transcribe(input: {
|
|
1192
|
+
audio: VoiceAudioUpload;
|
|
1193
|
+
overrides: VoiceRequestOverrides;
|
|
1194
|
+
}): Promise<VoiceServiceResult<{ text: string }>>;
|
|
1195
|
+
synthesizeSpeech(input: {
|
|
1196
|
+
text: string;
|
|
1197
|
+
overrides: VoiceRequestOverrides;
|
|
1198
|
+
}): Promise<VoiceServiceResult<VoiceSpeechPayload>>;
|
|
1199
|
+
};
|
|
1200
|
+
|
|
1201
|
+
// ---------------------------
|
|
1202
|
+
//----------------- CLI MODULE CONTRACTS ------------
|
|
1203
|
+
/**
|
|
1204
|
+
* Output boundary used by the CLI and Sandbox services.
|
|
1205
|
+
*
|
|
1206
|
+
* Production wiring delegates to the real console. Unit tests collect these
|
|
1207
|
+
* calls in arrays, which keeps command assertions deterministic and avoids
|
|
1208
|
+
* monkey-patching the global console singleton.
|
|
1209
|
+
*/
|
|
1210
|
+
export type CliOutput = {
|
|
1211
|
+
log(message?: string): void;
|
|
1212
|
+
error(message?: string): void;
|
|
1213
|
+
};
|
|
1214
|
+
|
|
1215
|
+
/**
|
|
1216
|
+
* Minimal synchronous filesystem surface shared by CLI status reporting and
|
|
1217
|
+
* sandbox workspace validation.
|
|
1218
|
+
*
|
|
1219
|
+
* The production composition root adapts Node's filesystem module. Tests supply
|
|
1220
|
+
* path-keyed fakes, so service tests never inspect or modify the real machine.
|
|
1221
|
+
*/
|
|
1222
|
+
export type CliFileSystem = {
|
|
1223
|
+
pathExists(filePath: string): boolean;
|
|
1224
|
+
getFileStats(filePath: string): { size: number; modifiedAt: Date };
|
|
1225
|
+
};
|
|
1226
|
+
|
|
1227
|
+
/**
|
|
1228
|
+
* Mutable environment view owned by the CLI application.
|
|
1229
|
+
*
|
|
1230
|
+
* CLI options update this object before the server starts. Production passes
|
|
1231
|
+
* `process.env`; tests pass a plain record to verify option precedence without
|
|
1232
|
+
* changing process-wide environment state.
|
|
1233
|
+
*/
|
|
1234
|
+
export type CliEnvironment = Record<string, string | undefined>;
|
|
1235
|
+
|
|
1236
|
+
/**
|
|
1237
|
+
* Package metadata displayed by CLI help, status, version, and update commands.
|
|
1238
|
+
*
|
|
1239
|
+
* The composition root reads this once from the application package file and
|
|
1240
|
+
* injects only the fields the service needs.
|
|
1241
|
+
*/
|
|
1242
|
+
export type CliPackageMetadata = {
|
|
1243
|
+
version: string;
|
|
1244
|
+
homepage?: string;
|
|
1245
|
+
bugsUrl?: string;
|
|
1246
|
+
};
|
|
1247
|
+
|
|
1248
|
+
/**
|
|
1249
|
+
* Executable CLI application returned by the CLI composition root.
|
|
1250
|
+
*
|
|
1251
|
+
* The thin executable entrypoint passes `process.argv` arguments to `run` and
|
|
1252
|
+
* copies the returned code to `process.exitCode`. Tests invoke the same method
|
|
1253
|
+
* directly with isolated dependencies.
|
|
1254
|
+
*/
|
|
1255
|
+
export type CliApplication = {
|
|
1256
|
+
run(argumentsList: string[]): Promise<number>;
|
|
1257
|
+
};
|
|
1258
|
+
|
|
1259
|
+
/**
|
|
1260
|
+
* Sandbox command service consumed by the top-level CLI command dispatcher.
|
|
1261
|
+
*
|
|
1262
|
+
* Keeping this behind one required dependency lets CLI tests use a tiny fake,
|
|
1263
|
+
* while focused Sandbox tests exercise subprocess and filesystem behavior with
|
|
1264
|
+
* their own handwritten adapters.
|
|
1265
|
+
*/
|
|
1266
|
+
export type SandboxCommandService = {
|
|
1267
|
+
execute(argumentsList: string[]): Promise<number>;
|
|
1268
|
+
};
|