wind-agent-cli 1.37.2 → 1.37.3
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 +1 -1
- package/dist/api-docs.html +901 -901
- package/dist/assets/{CodeEditor-B2Wf7Fg0.js → CodeEditor-BqmxpZ_D.js} +1 -1
- package/dist/assets/{FileTree-N2IkkHlv.js → FileTree-DLE7Ioai.js} +1 -1
- package/dist/assets/{GitPanel-DZCeuFZ2.js → GitPanel-f8RMRa8D.js} +1 -1
- package/dist/assets/{MarkdownPreview-C0tqYnVu.js → MarkdownPreview-93h_1tJa.js} +1 -1
- package/dist/assets/{PluginTabContent-Bnuf-fb8.js → PluginTabContent-DU1jjkXP.js} +1 -1
- package/dist/assets/{Shell-BfFnMZ-f.js → Shell-CN_2MRIM.js} +1 -1
- package/dist/assets/{StandaloneShell-QmyYwNAl.js → StandaloneShell-D0avS8UE.js} +1 -1
- package/dist/assets/{TaskMasterPanel-fMsmvN9L.js → TaskMasterPanel-Cpf1Q5Ph.js} +3 -3
- package/dist/assets/{abnfDiagram-N423BO3Z-DjPU7HLs.js → abnfDiagram-N423BO3Z-p3aJIm4T.js} +1 -1
- package/dist/assets/{arc-Pdq6Tvr3.js → arc-CTeud6Fl.js} +1 -1
- package/dist/assets/{architectureDiagram-T3A2C74G-D0JnT0Vh.js → architectureDiagram-T3A2C74G-CG7kRCJU.js} +1 -1
- package/dist/assets/{blockDiagram-VBNYF7ZC-DpaEf3mv.js → blockDiagram-VBNYF7ZC-oSjQ1SgE.js} +1 -1
- package/dist/assets/{c4Diagram-5PPSVZJV-MpqlPGFi.js → c4Diagram-5PPSVZJV-RkzF0DJV.js} +1 -1
- package/dist/assets/channel-BfQbarn9.js +1 -0
- package/dist/assets/{chunk-2GRJ4B5K-DoSdNo8u.js → chunk-2GRJ4B5K-B07uZ07O.js} +1 -1
- package/dist/assets/{chunk-2Q5K7J3B-CE7I3uMn.js → chunk-2Q5K7J3B-DNSfO7xS.js} +1 -1
- package/dist/assets/{chunk-5RXB4S5H-B4UQ8snD.js → chunk-5RXB4S5H-BTeYcgyb.js} +1 -1
- package/dist/assets/{chunk-5VM5RSS4-B55XgqHZ.js → chunk-5VM5RSS4-B7vZV0zC.js} +1 -1
- package/dist/assets/{chunk-6Q2QTUOP-BS1KpefW.js → chunk-6Q2QTUOP-DuS_xUGG.js} +1 -1
- package/dist/assets/{chunk-GF5L2VYU-DkEPedJP.js → chunk-GF5L2VYU-CKLZ3iVD.js} +1 -1
- package/dist/assets/{chunk-JWPE2WC7-DOtkNhMm.js → chunk-JWPE2WC7-DD2hcXvs.js} +1 -1
- package/dist/assets/{chunk-KBJHAD2P-BXLjviqM.js → chunk-KBJHAD2P-Cz-l38qp.js} +1 -1
- package/dist/assets/{chunk-RYQCIY6F-C50fjNNz.js → chunk-RYQCIY6F-DGFIU1YM.js} +1 -1
- package/dist/assets/{chunk-XXDRQBXY-QBYqCkb7.js → chunk-XXDRQBXY-CmfzoYFl.js} +1 -1
- package/dist/assets/classDiagram-JCYQIIEL-Bpfe3kq7.js +1 -0
- package/dist/assets/classDiagram-v2-OCEON4UE-Bpfe3kq7.js +1 -0
- package/dist/assets/{code-xml-VK1YfShP.js → code-xml-CLpHzEOP.js} +1 -1
- package/dist/assets/{cose-bilkent-JH36ORCC-DrVTo1Nh.js → cose-bilkent-JH36ORCC-DlFcLXCB.js} +1 -1
- package/dist/assets/{cynefin-VYW2F7L2-DnJa_OlQ.js → cynefin-VYW2F7L2-P1HecReO.js} +1 -1
- package/dist/assets/{cynefinDiagram-MW4NZA55-CCxBjw9E.js → cynefinDiagram-MW4NZA55-COgduz5P.js} +1 -1
- package/dist/assets/{dagre-VZM6K2ZE-C_GvE4lu.js → dagre-VZM6K2ZE-Bbb-siGp.js} +1 -1
- package/dist/assets/{diagram-7IWD3JNH-pFzs9HEu.js → diagram-7IWD3JNH-9CWGFMYR.js} +1 -1
- package/dist/assets/{diagram-B4RE2ZJO-CcehQC7x.js → diagram-B4RE2ZJO-TWK59T6V.js} +1 -1
- package/dist/assets/{diagram-LBJQPF4R-hfKcrrxe.js → diagram-LBJQPF4R-ErMC9yaa.js} +1 -1
- package/dist/assets/{diagram-Q27KOJAE-C1semJfK.js → diagram-Q27KOJAE-Dt_-C7hV.js} +1 -1
- package/dist/assets/{diagram-UB23O5K3-57hvXQXO.js → diagram-UB23O5K3-BJ1DnRAF.js} +1 -1
- package/dist/assets/{ebnfDiagram-BXEA7PRR-9KIAlAVw.js → ebnfDiagram-BXEA7PRR-CE1YaQ9s.js} +1 -1
- package/dist/assets/{erDiagram-JOGREHBK-B7OzJ767.js → erDiagram-JOGREHBK-Bqk7N9aY.js} +1 -1
- package/dist/assets/{flowDiagram-UKHOOZJN-CJV8fQPR.js → flowDiagram-UKHOOZJN-DEr2II5V.js} +1 -1
- package/dist/assets/{ganttDiagram-PKOTCBZU-CbMNWWQu.js → ganttDiagram-PKOTCBZU-CWYAUeYN.js} +1 -1
- package/dist/assets/{gitGraphDiagram-DS77QQ5N-I_vZ5waO.js → gitGraphDiagram-DS77QQ5N-tdEcEIM6.js} +1 -1
- package/dist/assets/{index-ZHwIojzi.js → index-B-sTfSZq.js} +1 -1
- package/dist/assets/{index-GFhXZyl2.js → index-BSe3UiFA.js} +1 -1
- package/dist/assets/{index-DFnVoqpx.js → index-B_FDMWar.js} +5 -5
- package/dist/assets/{index-DlSeAkw_.js → index-CWJtg2pR.js} +1 -1
- package/dist/assets/{infoDiagram-6WML65LV-Dh20Tsbq.js → infoDiagram-6WML65LV-A3IqRUnO.js} +1 -1
- package/dist/assets/{ishikawaDiagram-WSZJBQD7-DH2Sm3ko.js → ishikawaDiagram-WSZJBQD7-B2uL6bkK.js} +1 -1
- package/dist/assets/{journeyDiagram-NVQOT4AX-BNFQqlVu.js → journeyDiagram-NVQOT4AX-D9JB-hRW.js} +1 -1
- package/dist/assets/{kanban-definition-27J2QSJJ-B3iL0ztJ.js → kanban-definition-27J2QSJJ-DmlgiV7K.js} +1 -1
- package/dist/assets/{linear-Cwe9dEKA.js → linear-Ct_eoJQk.js} +1 -1
- package/dist/assets/{mermaid.core-BYRQSshi.js → mermaid.core-CQ698HNn.js} +5 -5
- package/dist/assets/{mindmap-definition-FAOFIHXS-BgfBYMzr.js → mindmap-definition-FAOFIHXS-DGtMgQhf.js} +1 -1
- package/dist/assets/{pegDiagram-VL7TDLO6-CNYpECr8.js → pegDiagram-VL7TDLO6-CO6vP4n9.js} +1 -1
- package/dist/assets/{pieDiagram-7S7Q4E2Y-DeSrxc4I.js → pieDiagram-7S7Q4E2Y-DMkt_Zfr.js} +1 -1
- package/dist/assets/{quadrantDiagram-CIZ2JOQS-BXVVQsa6.js → quadrantDiagram-CIZ2JOQS-DgNxRz6t.js} +1 -1
- package/dist/assets/{railroadDiagram-AXF67PYL-JTroIW8F.js → railroadDiagram-AXF67PYL-DKz9UqA9.js} +1 -1
- package/dist/assets/{requirementDiagram-LRYGKXZP-C1Z_inLz.js → requirementDiagram-LRYGKXZP-L84XyGgV.js} +1 -1
- package/dist/assets/{sankeyDiagram-W5VNT64P-DCJgKFUk.js → sankeyDiagram-W5VNT64P-CQqWbJ3j.js} +1 -1
- package/dist/assets/{sequenceDiagram-SI44F4Z6-D8Wrx5Vc.js → sequenceDiagram-SI44F4Z6--tnzS2tb.js} +1 -1
- package/dist/assets/{sizeCapture-X5ZJPWSS-CXqD68vD.js → sizeCapture-X5ZJPWSS-DujwEOtm.js} +1 -1
- package/dist/assets/{stateDiagram-OKZ733FA-CF0Ekqjo.js → stateDiagram-OKZ733FA-BK3TcZY2.js} +1 -1
- package/dist/assets/stateDiagram-v2-UEYNNEHI-_medyomK.js +1 -0
- package/dist/assets/{swimlanes-SLNWSIFB-DVIax_k4.js → swimlanes-SLNWSIFB-naX-Uv1B.js} +2 -2
- package/dist/assets/swimlanesDiagram-ULZ7WXOC-DstIv3TC.js +8 -0
- package/dist/assets/{timeline-definition-Z64GVDOM-DSqk3ApG.js → timeline-definition-Z64GVDOM-C-vP_ddU.js} +1 -1
- package/dist/assets/{vennDiagram-T6HMQDX7-DNbTqyG5.js → vennDiagram-T6HMQDX7-DN-I7o-7.js} +1 -1
- package/dist/assets/{wardleyDiagram-T6FBY63Y-BNCpsFZV.js → wardleyDiagram-T6FBY63Y-Db9dsaXv.js} +1 -1
- package/dist/assets/{xychartDiagram-ELKLHX3M-XsVZphHr.js → xychartDiagram-ELKLHX3M-DE6OxW_p.js} +1 -1
- package/dist/clear-cache.html +85 -85
- package/dist/convert-icons.md +52 -52
- 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.svg +11 -11
- package/dist/icons/icon-144x144.svg +11 -11
- package/dist/icons/icon-152x152.svg +11 -11
- package/dist/icons/icon-192x192.svg +11 -11
- package/dist/icons/icon-384x384.svg +11 -11
- package/dist/icons/icon-512x512.svg +11 -11
- package/dist/icons/icon-72x72.svg +11 -11
- package/dist/icons/icon-96x96.svg +11 -11
- package/dist/icons/icon-template.svg +11 -11
- package/dist/index.html +56 -56
- package/dist/logo.svg +17 -17
- package/dist/manifest.json +60 -60
- package/dist/sw.js +124 -124
- package/dist-server/server/modules/cli/cli.service.js +36 -36
- package/dist-server/server/modules/cli/sandbox.service.js +38 -38
- package/dist-server/server/modules/cli/tests/cli-environment-bootstrap.test.js +74 -74
- package/dist-server/server/modules/commands/commands.routes.js +24 -24
- 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 +92 -92
- package/dist-server/server/modules/database/schema.js +177 -177
- package/dist-server/server/modules/database/tests/provider-models.db.integration.test.js +6 -6
- package/dist-server/server/modules/git/git.routes.js +17 -17
- package/dist-server/server/modules/providers/list/opencode/opencode-models.provider.js +12 -12
- 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/tests/mcp.test.js +3 -3
- package/dist-server/server/modules/providers/tests/opencode-sessions.test.js +96 -96
- package/dist-server/server/modules/providers/tests/provider-token-usage.service.test.js +18 -18
- package/dist-server/server/modules/taskmaster/taskmaster.routes.js +419 -419
- 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 +250 -247
- package/public/api-docs.html +901 -901
- package/scripts/fix-node-pty.js +67 -67
- 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/server/index.ts +399 -399
- package/server/load-env.ts +47 -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 +586 -586
- package/server/modules/commands/index.ts +2 -2
- package/server/modules/commands/tests/commands.test.ts +109 -109
- package/server/modules/database/connection.ts +143 -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 +72 -72
- package/server/modules/database/tests/provider-models.db.integration.test.ts +125 -125
- package/server/modules/database/tests/sessions-provider-mapping.test.ts +109 -109
- package/server/modules/database/tests/sessions.db.integration.test.ts +116 -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 +117 -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-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 +159 -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 +150 -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 +1482 -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 +502 -502
- 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 +1226 -1226
- package/server/shared/utils.ts +1161 -1161
- package/server/tsconfig.json +40 -40
- package/shared/networkHosts.js +22 -22
- package/dist/assets/channel-Bm0ZLE4z.js +0 -1
- package/dist/assets/classDiagram-JCYQIIEL-DqEOcNxw.js +0 -1
- package/dist/assets/classDiagram-v2-OCEON4UE-DqEOcNxw.js +0 -1
- package/dist/assets/stateDiagram-v2-UEYNNEHI-DARLpEFJ.js +0 -1
- package/dist/assets/swimlanesDiagram-ULZ7WXOC-CrgDgaY8.js +0 -8
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
import os from 'node:os';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { promises as fsPromises } from 'node:fs';
|
|
4
|
-
|
|
5
|
-
import chokidar, { type FSWatcher } from 'chokidar';
|
|
6
|
-
|
|
7
|
-
import { projectsDb, sessionsDb } from '@/modules/database/index.js';
|
|
8
|
-
import { sessionSynchronizerService } from '@/modules/providers/services/session-synchronizer.service.js';
|
|
9
|
-
import { WS_OPEN_STATE, connectedClients } from '@/modules/websocket/index.js';
|
|
10
|
-
import type { LLMProvider } from '@/shared/types.js';
|
|
1
|
+
import os from 'node:os';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { promises as fsPromises } from 'node:fs';
|
|
4
|
+
|
|
5
|
+
import chokidar, { type FSWatcher } from 'chokidar';
|
|
6
|
+
|
|
7
|
+
import { projectsDb, sessionsDb } from '@/modules/database/index.js';
|
|
8
|
+
import { sessionSynchronizerService } from '@/modules/providers/services/session-synchronizer.service.js';
|
|
9
|
+
import { WS_OPEN_STATE, connectedClients } from '@/modules/websocket/index.js';
|
|
10
|
+
import type { LLMProvider } from '@/shared/types.js';
|
|
11
11
|
import { generateDisplayName } from '@/modules/projects/index.js';
|
|
12
12
|
import { SessionWatchScheduler } from '@/modules/providers/services/session-watch-scheduler.js';
|
|
13
13
|
|
|
14
14
|
const PROVIDER_WATCH_PATHS: Array<{ provider: LLMProvider; rootPath: string }> = [
|
|
15
|
-
{
|
|
16
|
-
provider: 'claude',
|
|
17
|
-
rootPath: path.join(os.homedir(), '.claude', 'projects'),
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
provider: 'cursor',
|
|
21
|
-
rootPath: path.join(os.homedir(), '.cursor', 'projects'),
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
provider: 'codex',
|
|
25
|
-
rootPath: path.join(os.homedir(), '.codex', 'sessions'),
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
provider: 'opencode',
|
|
29
|
-
rootPath: path.join(os.homedir(), '.local', 'share', 'opencode'),
|
|
30
|
-
},
|
|
31
|
-
];
|
|
32
|
-
|
|
15
|
+
{
|
|
16
|
+
provider: 'claude',
|
|
17
|
+
rootPath: path.join(os.homedir(), '.claude', 'projects'),
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
provider: 'cursor',
|
|
21
|
+
rootPath: path.join(os.homedir(), '.cursor', 'projects'),
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
provider: 'codex',
|
|
25
|
+
rootPath: path.join(os.homedir(), '.codex', 'sessions'),
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
provider: 'opencode',
|
|
29
|
+
rootPath: path.join(os.homedir(), '.local', 'share', 'opencode'),
|
|
30
|
+
},
|
|
31
|
+
];
|
|
32
|
+
|
|
33
33
|
const WATCHER_IGNORED_DIRECTORY_NAMES = new Set([
|
|
34
34
|
'node_modules',
|
|
35
35
|
'.git',
|
|
@@ -38,188 +38,188 @@ const WATCHER_IGNORED_DIRECTORY_NAMES = new Set([
|
|
|
38
38
|
'subagents',
|
|
39
39
|
'tool-results',
|
|
40
40
|
]);
|
|
41
|
-
|
|
42
|
-
const PROJECTS_UPDATE_DEBOUNCE_MS = 500;
|
|
43
|
-
const PROJECTS_UPDATE_MAX_WAIT_MS = 2_000;
|
|
44
|
-
|
|
41
|
+
|
|
42
|
+
const PROJECTS_UPDATE_DEBOUNCE_MS = 500;
|
|
43
|
+
const PROJECTS_UPDATE_MAX_WAIT_MS = 2_000;
|
|
44
|
+
|
|
45
45
|
const watchers: FSWatcher[] = [];
|
|
46
46
|
let watchScheduler: SessionWatchScheduler | null = null;
|
|
47
|
-
|
|
48
|
-
type PendingWatcherUpdate = {
|
|
49
|
-
providers: Set<LLMProvider>;
|
|
47
|
+
|
|
48
|
+
type PendingWatcherUpdate = {
|
|
49
|
+
providers: Set<LLMProvider>;
|
|
50
50
|
changeTypes: Set<'add' | 'change'>;
|
|
51
|
-
/**
|
|
52
|
-
* Provider-native session ids reported by the synchronizers. They are
|
|
53
|
-
* translated back to app-facing session rows at flush time, because the
|
|
54
|
-
* transcript file names on disk only ever contain provider ids.
|
|
55
|
-
*/
|
|
56
|
-
updatedSessionIds: Set<string>;
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
let pendingWatcherUpdate: PendingWatcherUpdate | null = null;
|
|
60
|
-
let pendingWatcherUpdateStartedAt: number | null = null;
|
|
61
|
-
let pendingWatcherFlushTimer: ReturnType<typeof setTimeout> | null = null;
|
|
62
|
-
let watcherRefreshInFlight = false;
|
|
63
|
-
let watcherRescheduleAfterRefresh = false;
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Filters watcher events to provider-specific session artifact file types.
|
|
67
|
-
*/
|
|
68
|
-
function isWatcherTargetFile(provider: LLMProvider, filePath: string): boolean {
|
|
69
|
-
if (provider === 'opencode') {
|
|
70
|
-
return path.basename(filePath) === 'opencode.db';
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
return filePath.endsWith('.jsonl');
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function clearPendingWatcherFlushTimer(): void {
|
|
77
|
-
if (pendingWatcherFlushTimer) {
|
|
78
|
-
clearTimeout(pendingWatcherFlushTimer);
|
|
79
|
-
pendingWatcherFlushTimer = null;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function schedulePendingWatcherFlush(): void {
|
|
84
|
-
if (!pendingWatcherUpdate) {
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const now = Date.now();
|
|
89
|
-
if (pendingWatcherUpdateStartedAt === null) {
|
|
90
|
-
pendingWatcherUpdateStartedAt = now;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
const elapsed = now - pendingWatcherUpdateStartedAt;
|
|
94
|
-
const remainingMaxWait = Math.max(0, PROJECTS_UPDATE_MAX_WAIT_MS - elapsed);
|
|
95
|
-
const delay = Math.min(PROJECTS_UPDATE_DEBOUNCE_MS, remainingMaxWait);
|
|
96
|
-
|
|
97
|
-
clearPendingWatcherFlushTimer();
|
|
98
|
-
pendingWatcherFlushTimer = setTimeout(() => {
|
|
99
|
-
void flushPendingWatcherUpdate();
|
|
100
|
-
}, delay);
|
|
101
|
-
}
|
|
102
|
-
|
|
51
|
+
/**
|
|
52
|
+
* Provider-native session ids reported by the synchronizers. They are
|
|
53
|
+
* translated back to app-facing session rows at flush time, because the
|
|
54
|
+
* transcript file names on disk only ever contain provider ids.
|
|
55
|
+
*/
|
|
56
|
+
updatedSessionIds: Set<string>;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
let pendingWatcherUpdate: PendingWatcherUpdate | null = null;
|
|
60
|
+
let pendingWatcherUpdateStartedAt: number | null = null;
|
|
61
|
+
let pendingWatcherFlushTimer: ReturnType<typeof setTimeout> | null = null;
|
|
62
|
+
let watcherRefreshInFlight = false;
|
|
63
|
+
let watcherRescheduleAfterRefresh = false;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Filters watcher events to provider-specific session artifact file types.
|
|
67
|
+
*/
|
|
68
|
+
function isWatcherTargetFile(provider: LLMProvider, filePath: string): boolean {
|
|
69
|
+
if (provider === 'opencode') {
|
|
70
|
+
return path.basename(filePath) === 'opencode.db';
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return filePath.endsWith('.jsonl');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function clearPendingWatcherFlushTimer(): void {
|
|
77
|
+
if (pendingWatcherFlushTimer) {
|
|
78
|
+
clearTimeout(pendingWatcherFlushTimer);
|
|
79
|
+
pendingWatcherFlushTimer = null;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function schedulePendingWatcherFlush(): void {
|
|
84
|
+
if (!pendingWatcherUpdate) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const now = Date.now();
|
|
89
|
+
if (pendingWatcherUpdateStartedAt === null) {
|
|
90
|
+
pendingWatcherUpdateStartedAt = now;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const elapsed = now - pendingWatcherUpdateStartedAt;
|
|
94
|
+
const remainingMaxWait = Math.max(0, PROJECTS_UPDATE_MAX_WAIT_MS - elapsed);
|
|
95
|
+
const delay = Math.min(PROJECTS_UPDATE_DEBOUNCE_MS, remainingMaxWait);
|
|
96
|
+
|
|
97
|
+
clearPendingWatcherFlushTimer();
|
|
98
|
+
pendingWatcherFlushTimer = setTimeout(() => {
|
|
99
|
+
void flushPendingWatcherUpdate();
|
|
100
|
+
}, delay);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
103
|
function queuePendingWatcherUpdate(
|
|
104
104
|
eventType: 'add' | 'change',
|
|
105
|
-
provider: LLMProvider,
|
|
106
|
-
updatedSessionId: string | null
|
|
107
|
-
): void {
|
|
108
|
-
if (!pendingWatcherUpdate) {
|
|
109
|
-
pendingWatcherUpdate = {
|
|
110
|
-
providers: new Set<LLMProvider>(),
|
|
105
|
+
provider: LLMProvider,
|
|
106
|
+
updatedSessionId: string | null
|
|
107
|
+
): void {
|
|
108
|
+
if (!pendingWatcherUpdate) {
|
|
109
|
+
pendingWatcherUpdate = {
|
|
110
|
+
providers: new Set<LLMProvider>(),
|
|
111
111
|
changeTypes: new Set<'add' | 'change'>(),
|
|
112
|
-
updatedSessionIds: new Set<string>(),
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
pendingWatcherUpdate.providers.add(provider);
|
|
117
|
-
pendingWatcherUpdate.changeTypes.add(eventType);
|
|
118
|
-
if (updatedSessionId) {
|
|
119
|
-
pendingWatcherUpdate.updatedSessionIds.add(updatedSessionId);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
schedulePendingWatcherFlush();
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Builds one `session_upserted` delta event for a provider-native session id.
|
|
127
|
-
*
|
|
128
|
-
* The event carries everything a sidebar needs to upsert the session in place
|
|
129
|
-
* (session summary plus owning-project metadata), so clients never need a full
|
|
130
|
-
* project-list refetch when a transcript file changes on disk. Returns `null`
|
|
131
|
-
* when the id cannot be resolved to an indexed session row.
|
|
132
|
-
*/
|
|
133
|
-
async function buildSessionUpsertedEvent(updatedProviderSessionId: string): Promise<string | null> {
|
|
134
|
-
const row = sessionsDb.getSessionByProviderSessionId(updatedProviderSessionId)
|
|
135
|
-
?? sessionsDb.getSessionById(updatedProviderSessionId);
|
|
136
|
-
if (!row || row.isArchived) {
|
|
137
|
-
return null;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
const projectPath = row.project_path;
|
|
141
|
-
const project = projectPath ? projectsDb.getProjectPath(projectPath) : null;
|
|
142
|
-
const displayName = project?.custom_project_name?.trim()
|
|
143
|
-
? project.custom_project_name
|
|
144
|
-
: await generateDisplayName(path.basename(projectPath ?? '') || (projectPath ?? ''), projectPath);
|
|
145
|
-
|
|
146
|
-
return JSON.stringify({
|
|
147
|
-
kind: 'session_upserted',
|
|
148
|
-
sessionId: row.session_id,
|
|
149
|
-
provider: row.provider,
|
|
150
|
-
session: {
|
|
151
|
-
id: row.session_id,
|
|
152
|
-
summary: row.custom_name || '',
|
|
153
|
-
messageCount: 0,
|
|
154
|
-
lastActivity: row.updated_at ?? row.created_at ?? new Date().toISOString(),
|
|
155
|
-
},
|
|
156
|
-
project: project
|
|
157
|
-
? {
|
|
158
|
-
projectId: project.project_id,
|
|
159
|
-
path: project.project_path,
|
|
160
|
-
fullPath: project.project_path,
|
|
161
|
-
displayName,
|
|
162
|
-
isStarred: Boolean(project.isStarred),
|
|
163
|
-
}
|
|
164
|
-
: null,
|
|
165
|
-
timestamp: new Date().toISOString(),
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
async function flushPendingWatcherUpdate(): Promise<void> {
|
|
170
|
-
clearPendingWatcherFlushTimer();
|
|
171
|
-
|
|
172
|
-
if (!pendingWatcherUpdate) {
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
if (watcherRefreshInFlight) {
|
|
177
|
-
watcherRescheduleAfterRefresh = true;
|
|
178
|
-
return;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
const queuedUpdate = pendingWatcherUpdate;
|
|
182
|
-
pendingWatcherUpdate = null;
|
|
183
|
-
pendingWatcherUpdateStartedAt = null;
|
|
184
|
-
watcherRefreshInFlight = true;
|
|
185
|
-
|
|
186
|
-
try {
|
|
187
|
-
// Per-session deltas instead of full project snapshots: an upsert of one
|
|
188
|
-
// session can never clobber unrelated client state, so the frontend needs
|
|
189
|
-
// no "suppress updates while a run is active" protection logic.
|
|
190
|
-
const events: string[] = [];
|
|
191
|
-
for (const updatedSessionId of queuedUpdate.updatedSessionIds) {
|
|
192
|
-
const event = await buildSessionUpsertedEvent(updatedSessionId);
|
|
193
|
-
if (event) {
|
|
194
|
-
events.push(event);
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
if (events.length > 0) {
|
|
199
|
-
connectedClients.forEach(client => {
|
|
200
|
-
if (client.readyState === WS_OPEN_STATE) {
|
|
201
|
-
for (const event of events) {
|
|
202
|
-
client.send(event);
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
} catch (error) {
|
|
208
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
209
|
-
console.error('Session watcher refresh failed while broadcasting session_upserted', { error: message });
|
|
210
|
-
} finally {
|
|
211
|
-
watcherRefreshInFlight = false;
|
|
212
|
-
|
|
213
|
-
if (pendingWatcherUpdate || watcherRescheduleAfterRefresh) {
|
|
214
|
-
watcherRescheduleAfterRefresh = false;
|
|
215
|
-
schedulePendingWatcherFlush();
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* Handles file watcher updates and triggers provider file-level synchronization.
|
|
222
|
-
*/
|
|
112
|
+
updatedSessionIds: new Set<string>(),
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
pendingWatcherUpdate.providers.add(provider);
|
|
117
|
+
pendingWatcherUpdate.changeTypes.add(eventType);
|
|
118
|
+
if (updatedSessionId) {
|
|
119
|
+
pendingWatcherUpdate.updatedSessionIds.add(updatedSessionId);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
schedulePendingWatcherFlush();
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Builds one `session_upserted` delta event for a provider-native session id.
|
|
127
|
+
*
|
|
128
|
+
* The event carries everything a sidebar needs to upsert the session in place
|
|
129
|
+
* (session summary plus owning-project metadata), so clients never need a full
|
|
130
|
+
* project-list refetch when a transcript file changes on disk. Returns `null`
|
|
131
|
+
* when the id cannot be resolved to an indexed session row.
|
|
132
|
+
*/
|
|
133
|
+
async function buildSessionUpsertedEvent(updatedProviderSessionId: string): Promise<string | null> {
|
|
134
|
+
const row = sessionsDb.getSessionByProviderSessionId(updatedProviderSessionId)
|
|
135
|
+
?? sessionsDb.getSessionById(updatedProviderSessionId);
|
|
136
|
+
if (!row || row.isArchived) {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const projectPath = row.project_path;
|
|
141
|
+
const project = projectPath ? projectsDb.getProjectPath(projectPath) : null;
|
|
142
|
+
const displayName = project?.custom_project_name?.trim()
|
|
143
|
+
? project.custom_project_name
|
|
144
|
+
: await generateDisplayName(path.basename(projectPath ?? '') || (projectPath ?? ''), projectPath);
|
|
145
|
+
|
|
146
|
+
return JSON.stringify({
|
|
147
|
+
kind: 'session_upserted',
|
|
148
|
+
sessionId: row.session_id,
|
|
149
|
+
provider: row.provider,
|
|
150
|
+
session: {
|
|
151
|
+
id: row.session_id,
|
|
152
|
+
summary: row.custom_name || '',
|
|
153
|
+
messageCount: 0,
|
|
154
|
+
lastActivity: row.updated_at ?? row.created_at ?? new Date().toISOString(),
|
|
155
|
+
},
|
|
156
|
+
project: project
|
|
157
|
+
? {
|
|
158
|
+
projectId: project.project_id,
|
|
159
|
+
path: project.project_path,
|
|
160
|
+
fullPath: project.project_path,
|
|
161
|
+
displayName,
|
|
162
|
+
isStarred: Boolean(project.isStarred),
|
|
163
|
+
}
|
|
164
|
+
: null,
|
|
165
|
+
timestamp: new Date().toISOString(),
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
async function flushPendingWatcherUpdate(): Promise<void> {
|
|
170
|
+
clearPendingWatcherFlushTimer();
|
|
171
|
+
|
|
172
|
+
if (!pendingWatcherUpdate) {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (watcherRefreshInFlight) {
|
|
177
|
+
watcherRescheduleAfterRefresh = true;
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const queuedUpdate = pendingWatcherUpdate;
|
|
182
|
+
pendingWatcherUpdate = null;
|
|
183
|
+
pendingWatcherUpdateStartedAt = null;
|
|
184
|
+
watcherRefreshInFlight = true;
|
|
185
|
+
|
|
186
|
+
try {
|
|
187
|
+
// Per-session deltas instead of full project snapshots: an upsert of one
|
|
188
|
+
// session can never clobber unrelated client state, so the frontend needs
|
|
189
|
+
// no "suppress updates while a run is active" protection logic.
|
|
190
|
+
const events: string[] = [];
|
|
191
|
+
for (const updatedSessionId of queuedUpdate.updatedSessionIds) {
|
|
192
|
+
const event = await buildSessionUpsertedEvent(updatedSessionId);
|
|
193
|
+
if (event) {
|
|
194
|
+
events.push(event);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (events.length > 0) {
|
|
199
|
+
connectedClients.forEach(client => {
|
|
200
|
+
if (client.readyState === WS_OPEN_STATE) {
|
|
201
|
+
for (const event of events) {
|
|
202
|
+
client.send(event);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
} catch (error) {
|
|
208
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
209
|
+
console.error('Session watcher refresh failed while broadcasting session_upserted', { error: message });
|
|
210
|
+
} finally {
|
|
211
|
+
watcherRefreshInFlight = false;
|
|
212
|
+
|
|
213
|
+
if (pendingWatcherUpdate || watcherRescheduleAfterRefresh) {
|
|
214
|
+
watcherRescheduleAfterRefresh = false;
|
|
215
|
+
schedulePendingWatcherFlush();
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Handles file watcher updates and triggers provider file-level synchronization.
|
|
222
|
+
*/
|
|
223
223
|
function containsIgnoredDirectory(candidatePath: string, rootPath: string): boolean {
|
|
224
224
|
const relativePath = path.relative(rootPath, candidatePath);
|
|
225
225
|
return relativePath
|
|
@@ -279,24 +279,24 @@ function createWatchScheduler(): SessionWatchScheduler {
|
|
|
279
279
|
},
|
|
280
280
|
});
|
|
281
281
|
}
|
|
282
|
-
|
|
283
|
-
/**
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
284
|
* Used by the server bootstrap in `server/index.ts` to start provider
|
|
285
285
|
* filesystem watchers after the application services are ready.
|
|
286
|
-
*/
|
|
286
|
+
*/
|
|
287
287
|
export async function initializeSessionsWatcher(): Promise<void> {
|
|
288
288
|
if (watchers.length > 0 || watchScheduler) {
|
|
289
289
|
return;
|
|
290
290
|
}
|
|
291
291
|
|
|
292
292
|
console.log('Setting up session watchers');
|
|
293
|
-
|
|
294
|
-
const initialSync = await sessionSynchronizerService.synchronizeSessions();
|
|
295
|
-
console.log('Initial session synchronization complete', {
|
|
296
|
-
processedByProvider: initialSync.processedByProvider,
|
|
297
|
-
failures: initialSync.failures,
|
|
298
|
-
});
|
|
299
|
-
|
|
293
|
+
|
|
294
|
+
const initialSync = await sessionSynchronizerService.synchronizeSessions();
|
|
295
|
+
console.log('Initial session synchronization complete', {
|
|
296
|
+
processedByProvider: initialSync.processedByProvider,
|
|
297
|
+
failures: initialSync.failures,
|
|
298
|
+
});
|
|
299
|
+
|
|
300
300
|
watchScheduler = createWatchScheduler();
|
|
301
301
|
|
|
302
302
|
for (const { provider, rootPath } of PROVIDER_WATCH_PATHS) {
|
|
@@ -332,26 +332,26 @@ export async function initializeSessionsWatcher(): Promise<void> {
|
|
|
332
332
|
watchedDirectoryCount,
|
|
333
333
|
});
|
|
334
334
|
})
|
|
335
|
-
.on('error', (error: unknown) => {
|
|
336
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
337
|
-
console.error(`Session watcher error for provider "${provider}"`, { error: message });
|
|
338
|
-
});
|
|
339
|
-
|
|
340
|
-
watchers.push(watcher);
|
|
341
|
-
} catch (error) {
|
|
342
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
343
|
-
console.error(`Failed to initialize session watcher for provider "${provider}"`, {
|
|
344
|
-
rootPath,
|
|
345
|
-
error: message,
|
|
346
|
-
});
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
/**
|
|
335
|
+
.on('error', (error: unknown) => {
|
|
336
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
337
|
+
console.error(`Session watcher error for provider "${provider}"`, { error: message });
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
watchers.push(watcher);
|
|
341
|
+
} catch (error) {
|
|
342
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
343
|
+
console.error(`Failed to initialize session watcher for provider "${provider}"`, {
|
|
344
|
+
rootPath,
|
|
345
|
+
error: message,
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
352
|
* Used by the shutdown path in `server/index.ts` to drain scheduler work and
|
|
353
353
|
* close every provider filesystem watcher before process exit.
|
|
354
|
-
*/
|
|
354
|
+
*/
|
|
355
355
|
export async function closeSessionsWatcher(): Promise<void> {
|
|
356
356
|
clearPendingWatcherFlushTimer();
|
|
357
357
|
|
|
@@ -360,18 +360,18 @@ export async function closeSessionsWatcher(): Promise<void> {
|
|
|
360
360
|
await scheduler?.close();
|
|
361
361
|
|
|
362
362
|
await Promise.all(
|
|
363
|
-
watchers.map(async (watcher) => {
|
|
364
|
-
try {
|
|
365
|
-
await watcher.close();
|
|
366
|
-
} catch (error) {
|
|
367
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
368
|
-
console.error('Failed to close session watcher', { error: message });
|
|
369
|
-
}
|
|
370
|
-
})
|
|
371
|
-
);
|
|
372
|
-
watchers.length = 0;
|
|
373
|
-
pendingWatcherUpdate = null;
|
|
374
|
-
pendingWatcherUpdateStartedAt = null;
|
|
375
|
-
watcherRefreshInFlight = false;
|
|
376
|
-
watcherRescheduleAfterRefresh = false;
|
|
377
|
-
}
|
|
363
|
+
watchers.map(async (watcher) => {
|
|
364
|
+
try {
|
|
365
|
+
await watcher.close();
|
|
366
|
+
} catch (error) {
|
|
367
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
368
|
+
console.error('Failed to close session watcher', { error: message });
|
|
369
|
+
}
|
|
370
|
+
})
|
|
371
|
+
);
|
|
372
|
+
watchers.length = 0;
|
|
373
|
+
pendingWatcherUpdate = null;
|
|
374
|
+
pendingWatcherUpdateStartedAt = null;
|
|
375
|
+
watcherRefreshInFlight = false;
|
|
376
|
+
watcherRescheduleAfterRefresh = false;
|
|
377
|
+
}
|