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,203 +1,203 @@
|
|
|
1
|
-
import os from 'node:os';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { readFile } from 'node:fs/promises';
|
|
4
|
-
|
|
5
|
-
import { sessionsDb } from '@/modules/database/index.js';
|
|
6
|
-
import {
|
|
7
|
-
buildLookupMap,
|
|
8
|
-
extractFirstValidJsonlData,
|
|
9
|
-
findFilesRecursivelyCreatedAfter,
|
|
10
|
-
normalizeSessionName,
|
|
11
|
-
readFileTimestamps,
|
|
12
|
-
} from '@/shared/utils.js';
|
|
13
|
-
import type { IProviderSessionSynchronizer } from '@/shared/interfaces.js';
|
|
14
|
-
|
|
15
|
-
type ParsedSession = {
|
|
16
|
-
sessionId: string;
|
|
17
|
-
projectPath: string;
|
|
18
|
-
sessionName?: string;
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Session indexer for Claude transcript artifacts.
|
|
23
|
-
*/
|
|
24
|
-
export class ClaudeSessionSynchronizer implements IProviderSessionSynchronizer {
|
|
25
|
-
private readonly provider = 'claude' as const;
|
|
26
|
-
private readonly claudeHome = path.join(os.homedir(), '.claude');
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Returns true when a JSONL file is a subagent transcript or tool result
|
|
30
|
-
* rather than a top-level session.
|
|
31
|
-
*
|
|
32
|
-
* Claude stores subagent transcripts under a `subagents/` directory and
|
|
33
|
-
* tool results under a `tool-results/` directory, e.g.
|
|
34
|
-
* `~/.claude/projects/<encoded-cwd>/<session-id>/subagents/agent-<id>.jsonl`.
|
|
35
|
-
* Those files repeat the parent session's `sessionId`, so indexing them as
|
|
36
|
-
* standalone sessions overwrites the parent row's `jsonl_path` and corrupts
|
|
37
|
-
* the main session record. The recursive scan in `synchronize()` reaches
|
|
38
|
-
* them, so both entry points must skip them.
|
|
39
|
-
*/
|
|
40
|
-
private isSubagentTranscript(filePath: string): boolean {
|
|
41
|
-
const pathParts = path.normalize(filePath).split(path.sep);
|
|
42
|
-
return pathParts.includes('subagents') || pathParts.includes('tool-results');
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Scans ~/.claude/projects and upserts discovered sessions into DB.
|
|
47
|
-
*/
|
|
48
|
-
async synchronize(since?: Date): Promise<number> {
|
|
49
|
-
const nameMap = await buildLookupMap(path.join(this.claudeHome, 'history.jsonl'), 'sessionId', 'display');
|
|
50
|
-
const files = await findFilesRecursivelyCreatedAfter(
|
|
51
|
-
path.join(this.claudeHome, 'projects'),
|
|
52
|
-
'.jsonl',
|
|
53
|
-
since ?? null
|
|
54
|
-
);
|
|
55
|
-
|
|
56
|
-
let processed = 0;
|
|
57
|
-
for (const filePath of files) {
|
|
58
|
-
if (this.isSubagentTranscript(filePath)) {
|
|
59
|
-
continue;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const parsed = await this.processSessionFile(filePath, nameMap);
|
|
63
|
-
if (!parsed) {
|
|
64
|
-
continue;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const timestamps = await readFileTimestamps(filePath);
|
|
68
|
-
sessionsDb.createSession(
|
|
69
|
-
parsed.sessionId,
|
|
70
|
-
this.provider,
|
|
71
|
-
parsed.projectPath,
|
|
72
|
-
parsed.sessionName,
|
|
73
|
-
timestamps.createdAt,
|
|
74
|
-
timestamps.updatedAt,
|
|
75
|
-
filePath
|
|
76
|
-
);
|
|
77
|
-
processed += 1;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
return processed;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Parses and upserts one Claude session JSONL file.
|
|
85
|
-
*/
|
|
86
|
-
async synchronizeFile(filePath: string): Promise<string | null> {
|
|
87
|
-
if (!filePath.endsWith('.jsonl')) {
|
|
88
|
-
return null;
|
|
89
|
-
}
|
|
90
|
-
if (this.isSubagentTranscript(filePath)) {
|
|
91
|
-
return null;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
const nameMap = await buildLookupMap(path.join(this.claudeHome, 'history.jsonl'), 'sessionId', 'display');
|
|
95
|
-
const parsed = await this.processSessionFile(filePath, nameMap);
|
|
96
|
-
if (!parsed) {
|
|
97
|
-
return null;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
const timestamps = await readFileTimestamps(filePath);
|
|
101
|
-
return sessionsDb.createSession(
|
|
102
|
-
parsed.sessionId,
|
|
103
|
-
this.provider,
|
|
104
|
-
parsed.projectPath,
|
|
105
|
-
parsed.sessionName,
|
|
106
|
-
timestamps.createdAt,
|
|
107
|
-
timestamps.updatedAt,
|
|
108
|
-
filePath
|
|
109
|
-
);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Extracts session metadata from one Claude JSONL session file.
|
|
114
|
-
*/
|
|
115
|
-
private async processSessionFile(
|
|
116
|
-
filePath: string,
|
|
117
|
-
nameMap: Map<string, string>
|
|
118
|
-
): Promise<ParsedSession | null> {
|
|
119
|
-
const parsed = await extractFirstValidJsonlData(filePath, (rawData) => {
|
|
120
|
-
const data = rawData as Record<string, unknown>;
|
|
121
|
-
const sessionId = typeof data.sessionId === 'string' ? data.sessionId : undefined;
|
|
122
|
-
const projectPath = typeof data.cwd === 'string' ? data.cwd : undefined;
|
|
123
|
-
|
|
124
|
-
if (!sessionId || !projectPath) {
|
|
125
|
-
return null;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
return {
|
|
129
|
-
sessionId,
|
|
130
|
-
projectPath,
|
|
131
|
-
};
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
if (!parsed) {
|
|
135
|
-
return null;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// App-created sessions are keyed by an app id, so disk-discovered provider
|
|
139
|
-
// ids must be resolved through the provider-id mapping first.
|
|
140
|
-
const existingSession = sessionsDb.getSessionByProviderSessionId(parsed.sessionId)
|
|
141
|
-
?? sessionsDb.getSessionById(parsed.sessionId);
|
|
142
|
-
const existingSessionName = existingSession?.custom_name;
|
|
143
|
-
if (existingSessionName && existingSessionName !== 'Untitled Claude Session') {
|
|
144
|
-
return {
|
|
145
|
-
...parsed,
|
|
146
|
-
sessionName: normalizeSessionName(existingSessionName, 'Untitled Claude Session'),
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
let sessionName = nameMap.get(parsed.sessionId);
|
|
151
|
-
if (!sessionName) {
|
|
152
|
-
sessionName = await this.extractSessionAiTitleFromEnd(filePath, parsed.sessionId);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
return {
|
|
156
|
-
...parsed,
|
|
157
|
-
sessionName: normalizeSessionName(sessionName, 'Untitled Claude Session'),
|
|
158
|
-
};
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
private async extractSessionAiTitleFromEnd(
|
|
162
|
-
filePath: string,
|
|
163
|
-
sessionId: string
|
|
164
|
-
): Promise<string | undefined> {
|
|
165
|
-
try {
|
|
166
|
-
const content = await readFile(filePath, 'utf8');
|
|
167
|
-
const lines = content.split(/\r?\n/);
|
|
168
|
-
|
|
169
|
-
for (let index = lines.length - 1; index >= 0; index -= 1) {
|
|
170
|
-
const line = lines[index]?.trim();
|
|
171
|
-
if (!line) {
|
|
172
|
-
continue;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
let parsed: unknown;
|
|
176
|
-
try {
|
|
177
|
-
parsed = JSON.parse(line);
|
|
178
|
-
} catch {
|
|
179
|
-
continue;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
const data = parsed as Record<string, unknown>;
|
|
183
|
-
const eventType = typeof data.type === 'string' ? data.type : undefined;
|
|
184
|
-
const eventSessionId = typeof data.sessionId === 'string' ? data.sessionId : undefined;
|
|
185
|
-
const aiTitle = typeof data.aiTitle === 'string' ? data.aiTitle : undefined;
|
|
186
|
-
const lastPrompt = typeof data.lastPrompt === 'string' ? data.lastPrompt : undefined;
|
|
187
|
-
const claudeRenamedTitle = typeof data.customTitle === 'string' ? data.customTitle : undefined;
|
|
188
|
-
|
|
189
|
-
if (
|
|
190
|
-
(eventType === 'ai-title' && eventSessionId === sessionId && aiTitle?.trim()) ||
|
|
191
|
-
(eventType === 'last-prompt' && eventSessionId === sessionId && lastPrompt?.trim()) ||
|
|
192
|
-
(eventType === "custom-title" && eventSessionId === sessionId && claudeRenamedTitle?.trim())
|
|
193
|
-
) {
|
|
194
|
-
return aiTitle || lastPrompt || claudeRenamedTitle;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
} catch {
|
|
198
|
-
// Ignore missing/unreadable files so sync can continue.
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
return undefined;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
1
|
+
import os from 'node:os';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { readFile } from 'node:fs/promises';
|
|
4
|
+
|
|
5
|
+
import { sessionsDb } from '@/modules/database/index.js';
|
|
6
|
+
import {
|
|
7
|
+
buildLookupMap,
|
|
8
|
+
extractFirstValidJsonlData,
|
|
9
|
+
findFilesRecursivelyCreatedAfter,
|
|
10
|
+
normalizeSessionName,
|
|
11
|
+
readFileTimestamps,
|
|
12
|
+
} from '@/shared/utils.js';
|
|
13
|
+
import type { IProviderSessionSynchronizer } from '@/shared/interfaces.js';
|
|
14
|
+
|
|
15
|
+
type ParsedSession = {
|
|
16
|
+
sessionId: string;
|
|
17
|
+
projectPath: string;
|
|
18
|
+
sessionName?: string;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Session indexer for Claude transcript artifacts.
|
|
23
|
+
*/
|
|
24
|
+
export class ClaudeSessionSynchronizer implements IProviderSessionSynchronizer {
|
|
25
|
+
private readonly provider = 'claude' as const;
|
|
26
|
+
private readonly claudeHome = path.join(os.homedir(), '.claude');
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Returns true when a JSONL file is a subagent transcript or tool result
|
|
30
|
+
* rather than a top-level session.
|
|
31
|
+
*
|
|
32
|
+
* Claude stores subagent transcripts under a `subagents/` directory and
|
|
33
|
+
* tool results under a `tool-results/` directory, e.g.
|
|
34
|
+
* `~/.claude/projects/<encoded-cwd>/<session-id>/subagents/agent-<id>.jsonl`.
|
|
35
|
+
* Those files repeat the parent session's `sessionId`, so indexing them as
|
|
36
|
+
* standalone sessions overwrites the parent row's `jsonl_path` and corrupts
|
|
37
|
+
* the main session record. The recursive scan in `synchronize()` reaches
|
|
38
|
+
* them, so both entry points must skip them.
|
|
39
|
+
*/
|
|
40
|
+
private isSubagentTranscript(filePath: string): boolean {
|
|
41
|
+
const pathParts = path.normalize(filePath).split(path.sep);
|
|
42
|
+
return pathParts.includes('subagents') || pathParts.includes('tool-results');
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Scans ~/.claude/projects and upserts discovered sessions into DB.
|
|
47
|
+
*/
|
|
48
|
+
async synchronize(since?: Date): Promise<number> {
|
|
49
|
+
const nameMap = await buildLookupMap(path.join(this.claudeHome, 'history.jsonl'), 'sessionId', 'display');
|
|
50
|
+
const files = await findFilesRecursivelyCreatedAfter(
|
|
51
|
+
path.join(this.claudeHome, 'projects'),
|
|
52
|
+
'.jsonl',
|
|
53
|
+
since ?? null
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
let processed = 0;
|
|
57
|
+
for (const filePath of files) {
|
|
58
|
+
if (this.isSubagentTranscript(filePath)) {
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const parsed = await this.processSessionFile(filePath, nameMap);
|
|
63
|
+
if (!parsed) {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const timestamps = await readFileTimestamps(filePath);
|
|
68
|
+
sessionsDb.createSession(
|
|
69
|
+
parsed.sessionId,
|
|
70
|
+
this.provider,
|
|
71
|
+
parsed.projectPath,
|
|
72
|
+
parsed.sessionName,
|
|
73
|
+
timestamps.createdAt,
|
|
74
|
+
timestamps.updatedAt,
|
|
75
|
+
filePath
|
|
76
|
+
);
|
|
77
|
+
processed += 1;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return processed;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Parses and upserts one Claude session JSONL file.
|
|
85
|
+
*/
|
|
86
|
+
async synchronizeFile(filePath: string): Promise<string | null> {
|
|
87
|
+
if (!filePath.endsWith('.jsonl')) {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
if (this.isSubagentTranscript(filePath)) {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const nameMap = await buildLookupMap(path.join(this.claudeHome, 'history.jsonl'), 'sessionId', 'display');
|
|
95
|
+
const parsed = await this.processSessionFile(filePath, nameMap);
|
|
96
|
+
if (!parsed) {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const timestamps = await readFileTimestamps(filePath);
|
|
101
|
+
return sessionsDb.createSession(
|
|
102
|
+
parsed.sessionId,
|
|
103
|
+
this.provider,
|
|
104
|
+
parsed.projectPath,
|
|
105
|
+
parsed.sessionName,
|
|
106
|
+
timestamps.createdAt,
|
|
107
|
+
timestamps.updatedAt,
|
|
108
|
+
filePath
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Extracts session metadata from one Claude JSONL session file.
|
|
114
|
+
*/
|
|
115
|
+
private async processSessionFile(
|
|
116
|
+
filePath: string,
|
|
117
|
+
nameMap: Map<string, string>
|
|
118
|
+
): Promise<ParsedSession | null> {
|
|
119
|
+
const parsed = await extractFirstValidJsonlData(filePath, (rawData) => {
|
|
120
|
+
const data = rawData as Record<string, unknown>;
|
|
121
|
+
const sessionId = typeof data.sessionId === 'string' ? data.sessionId : undefined;
|
|
122
|
+
const projectPath = typeof data.cwd === 'string' ? data.cwd : undefined;
|
|
123
|
+
|
|
124
|
+
if (!sessionId || !projectPath) {
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return {
|
|
129
|
+
sessionId,
|
|
130
|
+
projectPath,
|
|
131
|
+
};
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
if (!parsed) {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// App-created sessions are keyed by an app id, so disk-discovered provider
|
|
139
|
+
// ids must be resolved through the provider-id mapping first.
|
|
140
|
+
const existingSession = sessionsDb.getSessionByProviderSessionId(parsed.sessionId)
|
|
141
|
+
?? sessionsDb.getSessionById(parsed.sessionId);
|
|
142
|
+
const existingSessionName = existingSession?.custom_name;
|
|
143
|
+
if (existingSessionName && existingSessionName !== 'Untitled Claude Session') {
|
|
144
|
+
return {
|
|
145
|
+
...parsed,
|
|
146
|
+
sessionName: normalizeSessionName(existingSessionName, 'Untitled Claude Session'),
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
let sessionName = nameMap.get(parsed.sessionId);
|
|
151
|
+
if (!sessionName) {
|
|
152
|
+
sessionName = await this.extractSessionAiTitleFromEnd(filePath, parsed.sessionId);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return {
|
|
156
|
+
...parsed,
|
|
157
|
+
sessionName: normalizeSessionName(sessionName, 'Untitled Claude Session'),
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
private async extractSessionAiTitleFromEnd(
|
|
162
|
+
filePath: string,
|
|
163
|
+
sessionId: string
|
|
164
|
+
): Promise<string | undefined> {
|
|
165
|
+
try {
|
|
166
|
+
const content = await readFile(filePath, 'utf8');
|
|
167
|
+
const lines = content.split(/\r?\n/);
|
|
168
|
+
|
|
169
|
+
for (let index = lines.length - 1; index >= 0; index -= 1) {
|
|
170
|
+
const line = lines[index]?.trim();
|
|
171
|
+
if (!line) {
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
let parsed: unknown;
|
|
176
|
+
try {
|
|
177
|
+
parsed = JSON.parse(line);
|
|
178
|
+
} catch {
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const data = parsed as Record<string, unknown>;
|
|
183
|
+
const eventType = typeof data.type === 'string' ? data.type : undefined;
|
|
184
|
+
const eventSessionId = typeof data.sessionId === 'string' ? data.sessionId : undefined;
|
|
185
|
+
const aiTitle = typeof data.aiTitle === 'string' ? data.aiTitle : undefined;
|
|
186
|
+
const lastPrompt = typeof data.lastPrompt === 'string' ? data.lastPrompt : undefined;
|
|
187
|
+
const claudeRenamedTitle = typeof data.customTitle === 'string' ? data.customTitle : undefined;
|
|
188
|
+
|
|
189
|
+
if (
|
|
190
|
+
(eventType === 'ai-title' && eventSessionId === sessionId && aiTitle?.trim()) ||
|
|
191
|
+
(eventType === 'last-prompt' && eventSessionId === sessionId && lastPrompt?.trim()) ||
|
|
192
|
+
(eventType === "custom-title" && eventSessionId === sessionId && claudeRenamedTitle?.trim())
|
|
193
|
+
) {
|
|
194
|
+
return aiTitle || lastPrompt || claudeRenamedTitle;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
} catch {
|
|
198
|
+
// Ignore missing/unreadable files so sync can continue.
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
return undefined;
|
|
202
|
+
}
|
|
203
|
+
}
|