wind-agent-cli 1.38.2 → 1.39.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.
Files changed (185) hide show
  1. package/README.md +8 -1
  2. package/dist/api-docs.html +4 -3
  3. package/dist/assets/{CodeEditor-C6BtLdoC.js → CodeEditor-C8eMIGen.js} +1 -1
  4. package/dist/assets/{FileTree-CGxNFZda.js → FileTree-D52nAPO4.js} +1 -1
  5. package/dist/assets/{GitPanel-BV-IAyEC.js → GitPanel-DgeKbZsW.js} +1 -1
  6. package/dist/assets/{MarkdownPreview-DVoEzpoc.js → MarkdownPreview-B00VQTx6.js} +1 -1
  7. package/dist/assets/{Shell-CUTO-THd.js → Shell-twzi9t5B.js} +7 -7
  8. package/dist/assets/{StandaloneShell-BKM1qxUc.js → StandaloneShell-DH_GBJMj.js} +1 -1
  9. package/dist/assets/{TaskMasterPanel-DDDCVF6M.js → TaskMasterPanel-BY-pMPMl.js} +2 -2
  10. package/dist/assets/{abnfDiagram-N423BO3Z-Crubtav6.js → abnfDiagram-N423BO3Z-BwBdstkH.js} +1 -1
  11. package/dist/assets/{arc-h9xb7EWA.js → arc-C0IOpbFP.js} +1 -1
  12. package/dist/assets/{architectureDiagram-T3A2C74G-BmMQp4MC.js → architectureDiagram-T3A2C74G-C-Wkj_AY.js} +1 -1
  13. package/dist/assets/{blockDiagram-VBNYF7ZC-BtD-zDnJ.js → blockDiagram-VBNYF7ZC-_sXAZKku.js} +1 -1
  14. package/dist/assets/{c4Diagram-5PPSVZJV-D18s6J-v.js → c4Diagram-5PPSVZJV-C0DUsZv8.js} +1 -1
  15. package/dist/assets/channel-B6xiB58V.js +1 -0
  16. package/dist/assets/{chunk-2GRJ4B5K-BHIcCvB_.js → chunk-2GRJ4B5K-D2TFB_6A.js} +1 -1
  17. package/dist/assets/{chunk-2Q5K7J3B-DcX4AeRe.js → chunk-2Q5K7J3B-B_co_2bI.js} +1 -1
  18. package/dist/assets/{chunk-5RXB4S5H-CZwYDv9K.js → chunk-5RXB4S5H-BcUSLq4H.js} +1 -1
  19. package/dist/assets/{chunk-5VM5RSS4-CR-F7R13.js → chunk-5VM5RSS4-0mQFBKSp.js} +1 -1
  20. package/dist/assets/{chunk-6Q2QTUOP-BPP216SB.js → chunk-6Q2QTUOP-BAkqmW1M.js} +1 -1
  21. package/dist/assets/{chunk-GF5L2VYU-CcFeSmHe.js → chunk-GF5L2VYU-Cyz0Xl7f.js} +1 -1
  22. package/dist/assets/{chunk-JWPE2WC7-C5T_9-OI.js → chunk-JWPE2WC7-DYO47aT-.js} +1 -1
  23. package/dist/assets/{chunk-KBJHAD2P-g5eR5X5h.js → chunk-KBJHAD2P-DvXEzV8J.js} +1 -1
  24. package/dist/assets/{chunk-RYQCIY6F-76WBDsoZ.js → chunk-RYQCIY6F-Beut8dYt.js} +1 -1
  25. package/dist/assets/{chunk-XXDRQBXY-DGuy3LLn.js → chunk-XXDRQBXY-DLIy1GFl.js} +1 -1
  26. package/dist/assets/classDiagram-JCYQIIEL-C7xIPTll.js +1 -0
  27. package/dist/assets/classDiagram-v2-OCEON4UE-C7xIPTll.js +1 -0
  28. package/dist/assets/{cose-bilkent-JH36ORCC-Cg4R1M0H.js → cose-bilkent-JH36ORCC-DynbO4dj.js} +1 -1
  29. package/dist/assets/{cynefin-VYW2F7L2-Cbmals-o.js → cynefin-VYW2F7L2-CYTJsH3o.js} +1 -1
  30. package/dist/assets/{cynefinDiagram-MW4NZA55-CI79hpHc.js → cynefinDiagram-MW4NZA55-ftj-lAeE.js} +1 -1
  31. package/dist/assets/{dagre-VZM6K2ZE-r3Uz8Fhv.js → dagre-VZM6K2ZE-C1kSFboe.js} +1 -1
  32. package/dist/assets/{diagram-7IWD3JNH-ClRIkmQw.js → diagram-7IWD3JNH-CqXHTFrY.js} +1 -1
  33. package/dist/assets/{diagram-B4RE2ZJO-C71qkNlS.js → diagram-B4RE2ZJO-B84n3Zko.js} +1 -1
  34. package/dist/assets/{diagram-LBJQPF4R-CC7ShhCC.js → diagram-LBJQPF4R-B710SefS.js} +1 -1
  35. package/dist/assets/{diagram-Q27KOJAE-DPHL4vnP.js → diagram-Q27KOJAE-CmVPl9pq.js} +1 -1
  36. package/dist/assets/{diagram-UB23O5K3-CP_My5E9.js → diagram-UB23O5K3-LozbeaFL.js} +1 -1
  37. package/dist/assets/{ebnfDiagram-BXEA7PRR-BQe4AU9Z.js → ebnfDiagram-BXEA7PRR-B321UBUA.js} +1 -1
  38. package/dist/assets/{erDiagram-JOGREHBK-CFidQ-d5.js → erDiagram-JOGREHBK-CTbw676k.js} +1 -1
  39. package/dist/assets/feature-chat-pY0kOrz2.js +88 -0
  40. package/dist/assets/feature-workspace-FLomYkPq.js +39 -0
  41. package/dist/assets/{flowDiagram-UKHOOZJN-X5fPFxbp.js → flowDiagram-UKHOOZJN-BWVKTWlw.js} +1 -1
  42. package/dist/assets/{ganttDiagram-PKOTCBZU-CILFHjP8.js → ganttDiagram-PKOTCBZU-BAj9eeeX.js} +1 -1
  43. package/dist/assets/{gitGraphDiagram-DS77QQ5N-DCQCtC_g.js → gitGraphDiagram-DS77QQ5N-DcVMRU7N.js} +1 -1
  44. package/dist/assets/{index-cNARKAN2.js → index-BYFstHFT.js} +1 -1
  45. package/dist/assets/index-BbBSplOU.js +35 -0
  46. package/dist/assets/{index-D0vbG70l.js → index-BrWTp075.js} +1 -1
  47. package/dist/assets/index-CHukVVB2.css +1 -0
  48. package/dist/assets/{index-Bo9nFrtn.js → index-k9M0VaFg.js} +1 -1
  49. package/dist/assets/{infoDiagram-6WML65LV-Da145n1G.js → infoDiagram-6WML65LV-V6wz33B4.js} +1 -1
  50. package/dist/assets/{ishikawaDiagram-WSZJBQD7-DGUP61eq.js → ishikawaDiagram-WSZJBQD7-Dd-WNPyK.js} +1 -1
  51. package/dist/assets/{journeyDiagram-NVQOT4AX-BqfnKWDJ.js → journeyDiagram-NVQOT4AX-D9VCuCeA.js} +1 -1
  52. package/dist/assets/{kanban-definition-27J2QSJJ-US6pQfNy.js → kanban-definition-27J2QSJJ-CUtwDOl-.js} +1 -1
  53. package/dist/assets/{linear-d91wK5kZ.js → linear-D_XGf1jO.js} +1 -1
  54. package/dist/assets/{mermaid.core-BsWqrIaW.js → mermaid.core-DOnsXioB.js} +4 -4
  55. package/dist/assets/{mindmap-definition-FAOFIHXS-CXWD2UbS.js → mindmap-definition-FAOFIHXS-DAYNL5ZV.js} +1 -1
  56. package/dist/assets/{pegDiagram-VL7TDLO6-BVzfDR-8.js → pegDiagram-VL7TDLO6-B5FX3-E6.js} +1 -1
  57. package/dist/assets/{pieDiagram-7S7Q4E2Y-PNpHZnJ9.js → pieDiagram-7S7Q4E2Y-EbnDBVd0.js} +1 -1
  58. package/dist/assets/{quadrantDiagram-CIZ2JOQS-DxCI4i3K.js → quadrantDiagram-CIZ2JOQS-C1koOtwT.js} +1 -1
  59. package/dist/assets/{railroadDiagram-AXF67PYL-BYkvo3om.js → railroadDiagram-AXF67PYL-D52xmshj.js} +1 -1
  60. package/dist/assets/{requirementDiagram-LRYGKXZP-LUtvOYtV.js → requirementDiagram-LRYGKXZP-B7VbfNnW.js} +1 -1
  61. package/dist/assets/{sankeyDiagram-W5VNT64P-CVyI8YeM.js → sankeyDiagram-W5VNT64P-CeRG1vHN.js} +1 -1
  62. package/dist/assets/{sequenceDiagram-SI44F4Z6-1vuRFolM.js → sequenceDiagram-SI44F4Z6-CfKHnmSE.js} +1 -1
  63. package/dist/assets/{sizeCapture-X5ZJPWSS-o4oVZXe8.js → sizeCapture-X5ZJPWSS-DJTzyd0S.js} +1 -1
  64. package/dist/assets/{stateDiagram-OKZ733FA-WedLIlXF.js → stateDiagram-OKZ733FA-DN0c7IYD.js} +1 -1
  65. package/dist/assets/stateDiagram-v2-UEYNNEHI-DbihlVOQ.js +1 -0
  66. package/dist/assets/{swimlanes-SLNWSIFB-CpeXuk67.js → swimlanes-SLNWSIFB-CaaJpBDA.js} +2 -2
  67. package/dist/assets/swimlanesDiagram-ULZ7WXOC-BBRevuGP.js +8 -0
  68. package/dist/assets/{timeline-definition-Z64GVDOM-DFcPWe47.js → timeline-definition-Z64GVDOM-CrzHN7d2.js} +1 -1
  69. package/dist/assets/{vennDiagram-T6HMQDX7-BH8C1C49.js → vennDiagram-T6HMQDX7-BTldHIjo.js} +1 -1
  70. package/dist/assets/{wardleyDiagram-T6FBY63Y-K1Ew0uit.js → wardleyDiagram-T6FBY63Y-D9Y50OsZ.js} +1 -1
  71. package/dist/assets/{xychartDiagram-ELKLHX3M-CQHlqWY2.js → xychartDiagram-ELKLHX3M-DjxSJ3aF.js} +1 -1
  72. package/dist/favicon.png +0 -0
  73. package/dist/icons/icon-128x128.png +0 -0
  74. package/dist/icons/icon-144x144.png +0 -0
  75. package/dist/icons/icon-152x152.png +0 -0
  76. package/dist/icons/icon-180x180.png +0 -0
  77. package/dist/icons/icon-192x192.png +0 -0
  78. package/dist/icons/icon-384x384.png +0 -0
  79. package/dist/icons/icon-512x512.png +0 -0
  80. package/dist/icons/icon-72x72.png +0 -0
  81. package/dist/icons/icon-96x96.png +0 -0
  82. package/dist/icons/icon-maskable-192x192.png +0 -0
  83. package/dist/icons/icon-maskable-512x512.png +0 -0
  84. package/dist/icons/new.png +0 -0
  85. package/dist/index.html +4 -4
  86. package/dist/logo-128.png +0 -0
  87. package/dist/logo-256.png +0 -0
  88. package/dist/sw.js +1 -1
  89. package/dist-server/server/index.js +2 -0
  90. package/dist-server/server/index.js.map +1 -1
  91. package/dist-server/server/modules/agent/agent.routes.js +14 -2
  92. package/dist-server/server/modules/agent/agent.routes.js.map +1 -1
  93. package/dist-server/server/modules/agent/tests/agent.routes.test.js +1 -0
  94. package/dist-server/server/modules/agent/tests/agent.routes.test.js.map +1 -1
  95. package/dist-server/server/modules/commands/commands.routes.js +2 -1
  96. package/dist-server/server/modules/commands/commands.routes.js.map +1 -1
  97. package/dist-server/server/modules/database/migrations.js +43 -0
  98. package/dist-server/server/modules/database/migrations.js.map +1 -1
  99. package/dist-server/server/modules/database/tests/projects.db.integration.test.js +24 -1
  100. package/dist-server/server/modules/database/tests/projects.db.integration.test.js.map +1 -1
  101. package/dist-server/server/modules/notifications/services/notification-orchestrator.service.js +2 -0
  102. package/dist-server/server/modules/notifications/services/notification-orchestrator.service.js.map +1 -1
  103. package/dist-server/server/modules/providers/list/opencode/opencode-session-synchronizer.provider.js +10 -1
  104. package/dist-server/server/modules/providers/list/opencode/opencode-session-synchronizer.provider.js.map +1 -1
  105. package/dist-server/server/modules/providers/list/pi/index.js +5 -0
  106. package/dist-server/server/modules/providers/list/pi/index.js.map +1 -0
  107. package/dist-server/server/modules/providers/list/pi/pi-auth.provider.js +55 -0
  108. package/dist-server/server/modules/providers/list/pi/pi-auth.provider.js.map +1 -0
  109. package/dist-server/server/modules/providers/list/pi/pi-mcp.provider.js +23 -0
  110. package/dist-server/server/modules/providers/list/pi/pi-mcp.provider.js.map +1 -0
  111. package/dist-server/server/modules/providers/list/pi/pi-models.provider.js +99 -0
  112. package/dist-server/server/modules/providers/list/pi/pi-models.provider.js.map +1 -0
  113. package/dist-server/server/modules/providers/list/pi/pi-runtime.provider.js +262 -0
  114. package/dist-server/server/modules/providers/list/pi/pi-runtime.provider.js.map +1 -0
  115. package/dist-server/server/modules/providers/list/pi/pi-session-synchronizer.provider.js +136 -0
  116. package/dist-server/server/modules/providers/list/pi/pi-session-synchronizer.provider.js.map +1 -0
  117. package/dist-server/server/modules/providers/list/pi/pi-sessions.provider.js +225 -0
  118. package/dist-server/server/modules/providers/list/pi/pi-sessions.provider.js.map +1 -0
  119. package/dist-server/server/modules/providers/list/pi/pi-skills.provider.js +31 -0
  120. package/dist-server/server/modules/providers/list/pi/pi-skills.provider.js.map +1 -0
  121. package/dist-server/server/modules/providers/list/pi/pi.provider.js +22 -0
  122. package/dist-server/server/modules/providers/list/pi/pi.provider.js.map +1 -0
  123. package/dist-server/server/modules/providers/provider.registry.js +2 -0
  124. package/dist-server/server/modules/providers/provider.registry.js.map +1 -1
  125. package/dist-server/server/modules/providers/provider.routes.js +2 -1
  126. package/dist-server/server/modules/providers/provider.routes.js.map +1 -1
  127. package/dist-server/server/modules/providers/services/provider-capabilities.service.js +26 -0
  128. package/dist-server/server/modules/providers/services/provider-capabilities.service.js.map +1 -1
  129. package/dist-server/server/modules/providers/services/session-synchronizer.service.js +1 -0
  130. package/dist-server/server/modules/providers/services/session-synchronizer.service.js.map +1 -1
  131. package/dist-server/server/modules/providers/services/sessions-watcher.service.js +5 -0
  132. package/dist-server/server/modules/providers/services/sessions-watcher.service.js.map +1 -1
  133. package/dist-server/server/modules/providers/tests/mcp.test.js +4 -2
  134. package/dist-server/server/modules/providers/tests/mcp.test.js.map +1 -1
  135. package/dist-server/server/modules/providers/tests/opencode-sessions.test.js +56 -5
  136. package/dist-server/server/modules/providers/tests/opencode-sessions.test.js.map +1 -1
  137. package/dist-server/server/modules/providers/tests/pi-provider.test.js +244 -0
  138. package/dist-server/server/modules/providers/tests/pi-provider.test.js.map +1 -0
  139. package/dist-server/server/modules/providers/tests/provider-runtime.service.test.js +9 -0
  140. package/dist-server/server/modules/providers/tests/provider-runtime.service.test.js.map +1 -1
  141. package/dist-server/server/shared/utils.js +19 -0
  142. package/dist-server/server/shared/utils.js.map +1 -1
  143. package/package.json +1 -1
  144. package/public/api-docs.html +4 -3
  145. package/scripts/generate-pwa-icons.ps1 +1 -1
  146. package/server/index.ts +2 -0
  147. package/server/modules/agent/agent.module.ts +1 -1
  148. package/server/modules/agent/agent.routes.ts +15 -2
  149. package/server/modules/agent/tests/agent.routes.test.ts +1 -0
  150. package/server/modules/commands/commands.routes.ts +2 -1
  151. package/server/modules/database/migrations.ts +52 -0
  152. package/server/modules/database/tests/projects.db.integration.test.ts +28 -1
  153. package/server/modules/notifications/services/notification-orchestrator.service.js +2 -0
  154. package/server/modules/providers/README.md +5 -1
  155. package/server/modules/providers/list/opencode/opencode-session-synchronizer.provider.ts +18 -0
  156. package/server/modules/providers/list/pi/index.ts +4 -0
  157. package/server/modules/providers/list/pi/pi-auth.provider.ts +58 -0
  158. package/server/modules/providers/list/pi/pi-mcp.provider.ts +33 -0
  159. package/server/modules/providers/list/pi/pi-models.provider.ts +114 -0
  160. package/server/modules/providers/list/pi/pi-runtime.provider.ts +271 -0
  161. package/server/modules/providers/list/pi/pi-session-synchronizer.provider.ts +134 -0
  162. package/server/modules/providers/list/pi/pi-sessions.provider.ts +206 -0
  163. package/server/modules/providers/list/pi/pi-skills.provider.ts +37 -0
  164. package/server/modules/providers/list/pi/pi.provider.ts +33 -0
  165. package/server/modules/providers/provider.registry.ts +2 -0
  166. package/server/modules/providers/provider.routes.ts +1 -0
  167. package/server/modules/providers/services/provider-capabilities.service.ts +32 -0
  168. package/server/modules/providers/services/session-synchronizer.service.ts +1 -0
  169. package/server/modules/providers/services/sessions-watcher.service.ts +5 -0
  170. package/server/modules/providers/tests/mcp.test.ts +4 -2
  171. package/server/modules/providers/tests/opencode-sessions.test.ts +81 -6
  172. package/server/modules/providers/tests/pi-provider.test.ts +244 -0
  173. package/server/modules/providers/tests/provider-runtime.service.test.ts +10 -0
  174. package/server/shared/types.ts +1 -1
  175. package/server/shared/utils.ts +23 -0
  176. package/dist/assets/channel-CuR3zGvy.js +0 -1
  177. package/dist/assets/classDiagram-JCYQIIEL-BWpl-4NG.js +0 -1
  178. package/dist/assets/classDiagram-v2-OCEON4UE-BWpl-4NG.js +0 -1
  179. package/dist/assets/feature-chat-CHKsDTs-.js +0 -88
  180. package/dist/assets/feature-workspace-BodovOw6.js +0 -39
  181. package/dist/assets/index-Bn37f1jp.js +0 -35
  182. package/dist/assets/index-Cr5MbHuj.css +0 -1
  183. package/dist/assets/stateDiagram-v2-UEYNNEHI-BqzvLVVB.js +0 -1
  184. package/dist/assets/swimlanesDiagram-ULZ7WXOC-CeI6fByR.js +0 -8
  185. package/dist/icons/new-icon.png +0 -0
@@ -0,0 +1,55 @@
1
+ import { parsePiModelsTable, runPiCommand } from './pi-models.provider.js';
2
+ const MINIMUM_VERSION = [0, 84, 2];
3
+ const isSupportedVersion = (output) => {
4
+ const match = output.match(/(\d+)\.(\d+)\.(\d+)/);
5
+ if (!match)
6
+ return false;
7
+ const version = match.slice(1).map(Number);
8
+ for (let index = 0; index < MINIMUM_VERSION.length; index += 1) {
9
+ if (version[index] > MINIMUM_VERSION[index])
10
+ return true;
11
+ if (version[index] < MINIMUM_VERSION[index])
12
+ return false;
13
+ }
14
+ return true;
15
+ };
16
+ /** Reports Pi CLI/version readiness and whether model discovery finds usable credentials. */
17
+ export class PiProviderAuth {
18
+ async getStatus() {
19
+ const version = runPiCommand(['--version']);
20
+ const installed = version.status === 0 && !version.error;
21
+ if (!installed) {
22
+ return {
23
+ installed: false,
24
+ provider: 'pi',
25
+ authenticated: false,
26
+ email: null,
27
+ method: null,
28
+ error: 'Pi CLI is not installed. Install @earendil-works/pi-coding-agent >= 0.84.2.',
29
+ };
30
+ }
31
+ if (!isSupportedVersion(`${version.stdout}\n${version.stderr}`)) {
32
+ return {
33
+ installed: false,
34
+ provider: 'pi',
35
+ authenticated: false,
36
+ email: null,
37
+ method: null,
38
+ error: 'Pi CLI 0.84.2 or newer is required.',
39
+ };
40
+ }
41
+ const models = runPiCommand(['--list-models']);
42
+ const authenticated = models.status === 0 && parsePiModelsTable(models.stdout).length > 0;
43
+ return {
44
+ installed: true,
45
+ provider: 'pi',
46
+ authenticated,
47
+ email: authenticated ? 'Pi model credentials' : null,
48
+ method: authenticated ? 'pi_cli' : null,
49
+ error: authenticated
50
+ ? undefined
51
+ : 'No authenticated Pi models. Run pi and use /login, or configure a provider API key.',
52
+ };
53
+ }
54
+ }
55
+ //# sourceMappingURL=pi-auth.provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pi-auth.provider.js","sourceRoot":"","sources":["../../../../../../server/modules/providers/list/pi/pi-auth.provider.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE3E,MAAM,eAAe,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAU,CAAC;AAE5C,MAAM,kBAAkB,GAAG,CAAC,MAAc,EAAW,EAAE;IACrD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;IAClD,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACzB,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC3C,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,eAAe,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QAC/D,IAAI,OAAO,CAAC,KAAK,CAAC,GAAG,eAAe,CAAC,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QACzD,IAAI,OAAO,CAAC,KAAK,CAAC,GAAG,eAAe,CAAC,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;IAC5D,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF,6FAA6F;AAC7F,MAAM,OAAO,cAAc;IACzB,KAAK,CAAC,SAAS;QACb,MAAM,OAAO,GAAG,YAAY,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;QAC5C,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QACzD,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO;gBACL,SAAS,EAAE,KAAK;gBAChB,QAAQ,EAAE,IAAI;gBACd,aAAa,EAAE,KAAK;gBACpB,KAAK,EAAE,IAAI;gBACX,MAAM,EAAE,IAAI;gBACZ,KAAK,EAAE,6EAA6E;aACrF,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,kBAAkB,CAAC,GAAG,OAAO,CAAC,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC;YAChE,OAAO;gBACL,SAAS,EAAE,KAAK;gBAChB,QAAQ,EAAE,IAAI;gBACd,aAAa,EAAE,KAAK;gBACpB,KAAK,EAAE,IAAI;gBACX,MAAM,EAAE,IAAI;gBACZ,KAAK,EAAE,qCAAqC;aAC7C,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,YAAY,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC;QAC/C,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,kBAAkB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;QAC1F,OAAO;YACL,SAAS,EAAE,IAAI;YACf,QAAQ,EAAE,IAAI;YACd,aAAa;YACb,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,IAAI;YACpD,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI;YACvC,KAAK,EAAE,aAAa;gBAClB,CAAC,CAAC,SAAS;gBACX,CAAC,CAAC,qFAAqF;SAC1F,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,23 @@
1
+ import { AppError } from '../../../../shared/utils.js';
2
+ const unsupported = () => {
3
+ throw new AppError('Pi does not provide native MCP configuration.', {
4
+ code: 'MCP_NOT_SUPPORTED',
5
+ statusCode: 400,
6
+ });
7
+ };
8
+ /** Explicit no-op MCP facet required by the provider contract. */
9
+ export class PiMcpProvider {
10
+ async listServers() {
11
+ return { user: [], local: [], project: [] };
12
+ }
13
+ async listServersForScope() {
14
+ return [];
15
+ }
16
+ async upsertServer(_input) {
17
+ return unsupported();
18
+ }
19
+ async removeServer(_input) {
20
+ return unsupported();
21
+ }
22
+ }
23
+ //# sourceMappingURL=pi-mcp.provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pi-mcp.provider.js","sourceRoot":"","sources":["../../../../../../server/modules/providers/list/pi/pi-mcp.provider.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,MAAM,WAAW,GAAG,GAAU,EAAE;IAC9B,MAAM,IAAI,QAAQ,CAAC,+CAA+C,EAAE;QAClE,IAAI,EAAE,mBAAmB;QACzB,UAAU,EAAE,GAAG;KAChB,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,kEAAkE;AAClE,MAAM,OAAO,aAAa;IACxB,KAAK,CAAC,WAAW;QACf,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,mBAAmB;QACvB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,MAAoC;QACrD,OAAO,WAAW,EAAE,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,MAIlB;QACC,OAAO,WAAW,EAAE,CAAC;IACvB,CAAC;CACF"}
@@ -0,0 +1,99 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import os from 'node:os';
3
+ import path from 'node:path';
4
+ import spawn from 'cross-spawn';
5
+ import { readObjectRecord, readOptionalString } from '../../../../shared/utils.js';
6
+ const THINKING_LEVELS = ['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'];
7
+ /** Used by Pi auth and model facets so both execute the CLI without a shell. */
8
+ export function runPiCommand(args) {
9
+ const result = spawn.sync('pi', args, {
10
+ encoding: 'utf8',
11
+ timeout: 10_000,
12
+ windowsHide: true,
13
+ });
14
+ return {
15
+ status: result.status,
16
+ stdout: String(result.stdout ?? ''),
17
+ stderr: String(result.stderr ?? ''),
18
+ error: result.error,
19
+ };
20
+ }
21
+ const normalizeHeader = (value) => value.toLowerCase().replace(/[^a-z]/g, '');
22
+ /** Parses Pi's fixed-column `--list-models` table; exported for focused provider tests. */
23
+ export function parsePiModelsTable(output) {
24
+ const lines = output.split(/\r?\n/).filter((line) => line.trim());
25
+ const headerIndex = lines.findIndex((line) => /provider/i.test(line) && /model/i.test(line));
26
+ if (headerIndex < 0)
27
+ return [];
28
+ const header = lines[headerIndex];
29
+ const matches = [...header.matchAll(/\S+/g)];
30
+ const columns = matches.map((match, index) => ({
31
+ name: normalizeHeader(match[0]),
32
+ start: match.index ?? 0,
33
+ end: matches[index + 1]?.index ?? Number.POSITIVE_INFINITY,
34
+ }));
35
+ const providerColumn = columns.find((column) => column.name === 'provider');
36
+ const modelColumn = columns.find((column) => column.name === 'model' || column.name === 'modelid');
37
+ const thinkingColumn = columns.find((column) => column.name === 'thinking');
38
+ const imageColumn = columns.find((column) => column.name === 'images' || column.name === 'image');
39
+ if (!providerColumn || !modelColumn)
40
+ return [];
41
+ const readColumn = (line, column) => (line.slice(column.start, Number.isFinite(column.end) ? column.end : undefined).trim());
42
+ return lines.slice(headerIndex + 1).flatMap((line) => {
43
+ if (/^-+$/.test(line.replace(/\s/g, '')))
44
+ return [];
45
+ const provider = readColumn(line, providerColumn);
46
+ const model = readColumn(line, modelColumn);
47
+ if (!provider || !model)
48
+ return [];
49
+ const value = `${provider}/${model}`;
50
+ const supportsThinking = thinkingColumn
51
+ ? /^(yes|true|supported)$/i.test(readColumn(line, thinkingColumn))
52
+ : false;
53
+ const supportsImages = imageColumn
54
+ ? /^(yes|true|supported)$/i.test(readColumn(line, imageColumn))
55
+ : false;
56
+ return [{
57
+ value,
58
+ label: model,
59
+ description: `${provider}${supportsImages ? ' · Images' : ''}`,
60
+ ...(supportsThinking ? {
61
+ effort: {
62
+ default: 'medium',
63
+ values: THINKING_LEVELS.map((level) => ({ value: level })),
64
+ },
65
+ } : {}),
66
+ }];
67
+ });
68
+ }
69
+ async function readPiDefaultModel() {
70
+ try {
71
+ const settings = readObjectRecord(JSON.parse(await readFile(path.join(os.homedir(), '.pi', 'agent', 'settings.json'), 'utf8')));
72
+ const provider = readOptionalString(settings?.defaultProvider);
73
+ const model = readOptionalString(settings?.defaultModel);
74
+ return provider && model ? `${provider}/${model}` : null;
75
+ }
76
+ catch {
77
+ return null;
78
+ }
79
+ }
80
+ /** Dynamic Pi catalog adapter. Discovery is intentionally uncached because auth changes alter the list. */
81
+ export class PiProviderModels {
82
+ async getSupportedModels() {
83
+ const result = runPiCommand(['--list-models']);
84
+ const options = result.status === 0 && !result.error ? parsePiModelsTable(result.stdout) : [];
85
+ const configuredDefault = await readPiDefaultModel();
86
+ const fallback = options[0]?.value ?? configuredDefault ?? '';
87
+ return {
88
+ OPTIONS: options,
89
+ DEFAULT: configuredDefault && options.some((option) => option.value === configuredDefault)
90
+ ? configuredDefault
91
+ : fallback,
92
+ };
93
+ }
94
+ async getCurrentActiveModel() {
95
+ const models = await this.getSupportedModels();
96
+ return { model: models.DEFAULT };
97
+ }
98
+ }
99
+ //# sourceMappingURL=pi-models.provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pi-models.provider.js","sourceRoot":"","sources":["../../../../../../server/modules/providers/list/pi/pi-models.provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,262 @@
1
+ import { existsSync, promises as fs } from 'node:fs';
2
+ import path from 'node:path';
3
+ import spawn from 'cross-spawn';
4
+ import { appendFilesInputTag, isAllowedImageSourcePath, normalizeImageDescriptors, resolveImageAbsolutePath, resolveImageMediaType, } from '../../../../shared/image-attachments.js';
5
+ import { createCompleteMessage, createNormalizedMessage, findTopmostGitRoot } from '../../../../shared/utils.js';
6
+ const activePiProcesses = new Map();
7
+ const ABORT_GRACE_MS = 500;
8
+ const formatError = (value) => value instanceof Error ? value.message : String(value);
9
+ async function buildPiImages(images, cwd) {
10
+ const result = [];
11
+ for (const descriptor of normalizeImageDescriptors(images)) {
12
+ const mimeType = resolveImageMediaType(descriptor);
13
+ const resolvedPath = resolveImageAbsolutePath(cwd, descriptor.path);
14
+ if (!mimeType?.startsWith('image/') || !isAllowedImageSourcePath(resolvedPath, cwd))
15
+ continue;
16
+ try {
17
+ const canonicalPath = await fs.realpath(resolvedPath);
18
+ if (!isAllowedImageSourcePath(canonicalPath, cwd))
19
+ continue;
20
+ result.push({
21
+ type: 'image',
22
+ data: (await fs.readFile(canonicalPath)).toString('base64'),
23
+ mimeType,
24
+ });
25
+ }
26
+ catch (error) {
27
+ console.warn(`[Pi] Unable to attach image ${descriptor.path}: ${formatError(error)}`);
28
+ }
29
+ }
30
+ return result;
31
+ }
32
+ async function collectProjectSkillArgs(cwd) {
33
+ const skillDirs = [path.join(cwd, '.pi', 'skills')];
34
+ const repoRoot = await findTopmostGitRoot(cwd);
35
+ let current = path.resolve(cwd);
36
+ while (true) {
37
+ skillDirs.push(path.join(current, '.agents', 'skills'));
38
+ if (!repoRoot || current === path.resolve(repoRoot))
39
+ break;
40
+ const parent = path.dirname(current);
41
+ if (parent === current)
42
+ break;
43
+ current = parent;
44
+ }
45
+ return skillDirs.filter(existsSync).flatMap((directory) => ['--skill', directory]);
46
+ }
47
+ const readTokenBudget = (event) => {
48
+ const messages = Array.isArray(event.messages) ? event.messages : [];
49
+ let input = 0;
50
+ let output = 0;
51
+ let cacheRead = 0;
52
+ let cacheWrite = 0;
53
+ for (const message of messages) {
54
+ if (!message || typeof message !== 'object')
55
+ continue;
56
+ const usage = message.usage;
57
+ if (!usage || typeof usage !== 'object')
58
+ continue;
59
+ const record = usage;
60
+ input += Number(record.input ?? 0);
61
+ output += Number(record.output ?? 0);
62
+ cacheRead += Number(record.cacheRead ?? 0);
63
+ cacheWrite += Number(record.cacheWrite ?? 0);
64
+ }
65
+ const used = input + output + cacheRead + cacheWrite;
66
+ return used > 0 ? {
67
+ used,
68
+ inputTokens: input + cacheRead,
69
+ outputTokens: output,
70
+ breakdown: { input: input + cacheRead, output },
71
+ } : null;
72
+ };
73
+ /** Starts one isolated Pi RPC process for a single chat.send operation. */
74
+ export async function runPi(command, options, writer, context) {
75
+ const sessionId = typeof options.sessionId === 'string' && options.sessionId.trim()
76
+ ? options.sessionId.trim()
77
+ : crypto.randomUUID();
78
+ const workingDir = typeof options.cwd === 'string' && options.cwd.trim()
79
+ ? options.cwd
80
+ : typeof options.projectPath === 'string' && options.projectPath.trim()
81
+ ? options.projectPath
82
+ : process.cwd();
83
+ const providerSessionId = context.resolveProviderSessionId(sessionId);
84
+ const resolvedModel = await context.resolveResumeModel(sessionId, typeof options.model === 'string' ? options.model : undefined);
85
+ const args = ['--mode', 'rpc', '--no-approve'];
86
+ if (providerSessionId)
87
+ args.push('--session', providerSessionId);
88
+ else
89
+ args.push('--session-id', sessionId);
90
+ if (resolvedModel) {
91
+ const slash = resolvedModel.indexOf('/');
92
+ if (slash > 0)
93
+ args.push('--provider', resolvedModel.slice(0, slash));
94
+ args.push('--model', resolvedModel);
95
+ }
96
+ if (typeof options.effort === 'string' && options.effort !== 'default') {
97
+ args.push('--thinking', options.effort);
98
+ }
99
+ args.push(...await collectProjectSkillArgs(workingDir));
100
+ const images = await buildPiImages(options.images, workingDir);
101
+ const prompt = appendFilesInputTag(command?.trim() ?? '', options.files);
102
+ await new Promise((resolve, reject) => {
103
+ let child;
104
+ let stdoutBuffer = '';
105
+ let stderr = '';
106
+ let terminalSent = false;
107
+ let settled = false;
108
+ let agentEnded = false;
109
+ let protocolError = null;
110
+ const cleanup = () => {
111
+ if (activePiProcesses.get(sessionId) === child)
112
+ activePiProcesses.delete(sessionId);
113
+ };
114
+ const settle = (exitCode, error) => {
115
+ if (settled)
116
+ return;
117
+ settled = true;
118
+ cleanup();
119
+ if (!terminalSent && !child.aborted) {
120
+ terminalSent = true;
121
+ writer.send(createCompleteMessage({ provider: 'pi', sessionId, exitCode }));
122
+ }
123
+ if (error)
124
+ reject(error);
125
+ else
126
+ resolve();
127
+ };
128
+ const emitError = (message) => writer.send(createNormalizedMessage({
129
+ kind: 'error', provider: 'pi', sessionId, content: message,
130
+ }));
131
+ const processLine = (line) => {
132
+ if (!line.trim())
133
+ return;
134
+ let event;
135
+ try {
136
+ event = JSON.parse(line);
137
+ }
138
+ catch {
139
+ protocolError = new Error('Pi RPC returned invalid JSONL output.');
140
+ emitError(protocolError.message);
141
+ child.stdin?.end();
142
+ setTimeout(() => { if (child.exitCode === null)
143
+ child.kill(); }, ABORT_GRACE_MS).unref();
144
+ return;
145
+ }
146
+ if (event.type === 'response' && event.success === false) {
147
+ protocolError = new Error(typeof event.error === 'string' ? event.error : 'Pi rejected the RPC request.');
148
+ emitError(protocolError.message);
149
+ child.stdin?.end();
150
+ setTimeout(() => { if (child.exitCode === null)
151
+ child.kill(); }, ABORT_GRACE_MS).unref();
152
+ return;
153
+ }
154
+ for (const message of context.normalizeMessage(event, sessionId))
155
+ writer.send(message);
156
+ if (event.type === 'agent_end' && event.willRetry !== true) {
157
+ agentEnded = true;
158
+ const tokenBudget = readTokenBudget(event);
159
+ if (tokenBudget)
160
+ writer.send(createNormalizedMessage({
161
+ kind: 'status', provider: 'pi', sessionId, text: 'token_budget', tokenBudget,
162
+ }));
163
+ if (!terminalSent) {
164
+ terminalSent = true;
165
+ writer.send(createCompleteMessage({ provider: 'pi', sessionId, exitCode: 0 }));
166
+ }
167
+ child.stdin?.end();
168
+ setTimeout(() => {
169
+ if (child.exitCode === null)
170
+ child.kill();
171
+ }, ABORT_GRACE_MS).unref();
172
+ }
173
+ };
174
+ try {
175
+ child = spawn('pi', args, {
176
+ cwd: workingDir,
177
+ stdio: ['pipe', 'pipe', 'pipe'],
178
+ env: process.env,
179
+ windowsHide: true,
180
+ });
181
+ }
182
+ catch (error) {
183
+ const wrapped = new Error(`Unable to start Pi CLI: ${formatError(error)}`);
184
+ emitError(wrapped.message);
185
+ reject(wrapped);
186
+ return;
187
+ }
188
+ activePiProcesses.set(sessionId, child);
189
+ writer.setSessionId?.(sessionId);
190
+ child.stdout?.on('data', (chunk) => {
191
+ stdoutBuffer += chunk.toString('utf8');
192
+ const lines = stdoutBuffer.split(/\r?\n/);
193
+ stdoutBuffer = lines.pop() ?? '';
194
+ for (const line of lines)
195
+ processLine(line);
196
+ });
197
+ child.stderr?.on('data', (chunk) => { stderr += chunk.toString('utf8'); });
198
+ child.on('error', (error) => {
199
+ const wrapped = new Error(`Pi CLI failed: ${error.message}`);
200
+ emitError(wrapped.message);
201
+ settle(1, wrapped);
202
+ });
203
+ child.on('close', (code) => {
204
+ if (stdoutBuffer.trim())
205
+ processLine(stdoutBuffer);
206
+ if (settled) {
207
+ cleanup();
208
+ return;
209
+ }
210
+ if (child.aborted) {
211
+ settle(0);
212
+ return;
213
+ }
214
+ if (agentEnded) {
215
+ settle(0);
216
+ return;
217
+ }
218
+ if (protocolError) {
219
+ settle(1, protocolError);
220
+ return;
221
+ }
222
+ const exitCode = code ?? 1;
223
+ if (exitCode !== 0) {
224
+ const message = stderr.trim() || `Pi CLI exited with code ${exitCode}.`;
225
+ emitError(message);
226
+ settle(exitCode, new Error(message));
227
+ }
228
+ else {
229
+ const error = new Error('Pi RPC exited before emitting agent_end.');
230
+ emitError(error.message);
231
+ settle(1, error);
232
+ }
233
+ });
234
+ child.stdin?.write(`${JSON.stringify({
235
+ id: `prompt-${sessionId}`,
236
+ type: 'prompt',
237
+ message: prompt,
238
+ ...(images.length > 0 ? { images } : {}),
239
+ })}\n`);
240
+ });
241
+ }
242
+ /** Sends Pi's RPC abort command, then force-terminates an unresponsive child. */
243
+ export function abortPiSession(sessionId) {
244
+ const child = activePiProcesses.get(sessionId);
245
+ if (!child)
246
+ return false;
247
+ child.aborted = true;
248
+ try {
249
+ child.stdin?.write(`${JSON.stringify({ id: `abort-${sessionId}`, type: 'abort' })}\n`);
250
+ }
251
+ catch {
252
+ child.kill();
253
+ }
254
+ setTimeout(() => {
255
+ if (child.exitCode === null)
256
+ child.kill();
257
+ }, ABORT_GRACE_MS).unref();
258
+ activePiProcesses.delete(sessionId);
259
+ return true;
260
+ }
261
+ export const piRuntime = { run: runPi, abort: abortPiSession };
262
+ //# sourceMappingURL=pi-runtime.provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pi-runtime.provider.js","sourceRoot":"","sources":["../../../../../../server/modules/providers/list/pi/pi-runtime.provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,136 @@
1
+ import fsSync from 'node:fs';
2
+ import { readdir, readFile, stat } from 'node:fs/promises';
3
+ import os from 'node:os';
4
+ import path from 'node:path';
5
+ import { sessionsDb } from '../../../../modules/database/index.js';
6
+ import { normalizeProviderTimestamp, normalizeSessionName, readObjectRecord, readOptionalString, } from '../../../../shared/utils.js';
7
+ const PI_SETTINGS_PATH = path.join(os.homedir(), '.pi', 'agent', 'settings.json');
8
+ const DEFAULT_PI_SESSION_DIR = path.join(os.homedir(), '.pi', 'agent', 'sessions');
9
+ const expandHome = (value) => {
10
+ if (value === '~')
11
+ return os.homedir();
12
+ if (value.startsWith(`~${path.sep}`) || value.startsWith('~/') || value.startsWith('~\\')) {
13
+ return path.join(os.homedir(), value.slice(2));
14
+ }
15
+ return path.isAbsolute(value) ? value : path.resolve(os.homedir(), value);
16
+ };
17
+ /** Resolves Pi's transcript root for the synchronizer and filesystem watcher. */
18
+ export function getPiSessionDirectory() {
19
+ const environmentDirectory = process.env.PI_CODING_AGENT_SESSION_DIR?.trim();
20
+ if (environmentDirectory)
21
+ return expandHome(environmentDirectory);
22
+ try {
23
+ const settings = readObjectRecord(JSON.parse(fsSync.readFileSync(PI_SETTINGS_PATH, 'utf8')));
24
+ const configured = readOptionalString(settings?.sessionDir);
25
+ if (configured)
26
+ return expandHome(configured);
27
+ }
28
+ catch {
29
+ // Missing or partially-written settings use Pi's standard session root.
30
+ }
31
+ return DEFAULT_PI_SESSION_DIR;
32
+ }
33
+ const listJsonlFiles = async (root) => {
34
+ const files = [];
35
+ const visit = async (directory) => {
36
+ let entries;
37
+ try {
38
+ entries = await readdir(directory, { withFileTypes: true });
39
+ }
40
+ catch {
41
+ return;
42
+ }
43
+ await Promise.all(entries.map(async (entry) => {
44
+ const entryPath = path.join(directory, entry.name);
45
+ if (entry.isDirectory())
46
+ await visit(entryPath);
47
+ else if (entry.isFile() && entry.name.endsWith('.jsonl'))
48
+ files.push(entryPath);
49
+ }));
50
+ };
51
+ await visit(root);
52
+ return files;
53
+ };
54
+ const firstUserText = (entries) => {
55
+ for (const entry of entries) {
56
+ if (entry.type !== 'message')
57
+ continue;
58
+ const message = readObjectRecord(entry.message);
59
+ if (message?.role !== 'user')
60
+ continue;
61
+ if (typeof message.content === 'string' && message.content.trim())
62
+ return message.content.trim();
63
+ if (Array.isArray(message.content)) {
64
+ const text = message.content.flatMap((part) => {
65
+ const block = readObjectRecord(part);
66
+ return block?.type === 'text' ? [readOptionalString(block.text) ?? ''] : [];
67
+ }).join('').trim();
68
+ if (text)
69
+ return text;
70
+ }
71
+ }
72
+ return undefined;
73
+ };
74
+ /** Indexes Pi's JSONL transcript tree into WindCli's stable sessions table. */
75
+ export class PiSessionSynchronizer {
76
+ async synchronize(since) {
77
+ const files = await listJsonlFiles(getPiSessionDirectory());
78
+ let processed = 0;
79
+ for (const filePath of files) {
80
+ if (since) {
81
+ try {
82
+ if ((await stat(filePath)).mtime < since)
83
+ continue;
84
+ }
85
+ catch {
86
+ continue;
87
+ }
88
+ }
89
+ if (await this.synchronizeFile(filePath))
90
+ processed += 1;
91
+ }
92
+ return processed;
93
+ }
94
+ async synchronizeFile(filePath) {
95
+ if (!filePath.endsWith('.jsonl'))
96
+ return null;
97
+ try {
98
+ const entries = (await readFile(filePath, 'utf8')).split(/\r?\n/).flatMap((line) => {
99
+ if (!line.trim())
100
+ return [];
101
+ try {
102
+ return [JSON.parse(line)];
103
+ }
104
+ catch {
105
+ return [];
106
+ }
107
+ });
108
+ const header = entries.find((entry) => entry.type === 'session');
109
+ const sessionId = readOptionalString(header?.id);
110
+ const projectPath = readOptionalString(header?.cwd);
111
+ if (!sessionId || !projectPath)
112
+ return null;
113
+ const sessionInfo = [...entries].reverse().find((entry) => entry.type === 'session_info');
114
+ const title = readOptionalString(sessionInfo?.name)
115
+ ?? readOptionalString(sessionInfo?.title)
116
+ ?? firstUserText(entries);
117
+ const fileStats = await stat(filePath);
118
+ const createdAt = normalizeProviderTimestamp(header?.timestamp ?? fileStats.birthtime);
119
+ const updatedAt = normalizeProviderTimestamp([...entries].reverse().find((entry) => readOptionalString(entry.timestamp))?.timestamp ?? fileStats.mtime);
120
+ const pending = sessionsDb.getSessionByProviderSessionId(sessionId)
121
+ ?? sessionsDb.getSessionById(sessionId)
122
+ ?? sessionsDb.findLatestPendingAppSession('pi', projectPath);
123
+ if (pending && !pending.provider_session_id) {
124
+ sessionsDb.assignProviderSessionId(pending.session_id, sessionId);
125
+ }
126
+ const existing = sessionsDb.getSessionByProviderSessionId(sessionId) ?? sessionsDb.getSessionById(sessionId);
127
+ const fallback = 'Untitled Pi Session';
128
+ return sessionsDb.createSession(sessionId, 'pi', projectPath, normalizeSessionName(existing?.custom_name || title, fallback), createdAt, updatedAt, filePath);
129
+ }
130
+ catch (error) {
131
+ console.warn(`[PiProvider] Failed to synchronize ${filePath}:`, error instanceof Error ? error.message : String(error));
132
+ return null;
133
+ }
134
+ }
135
+ }
136
+ //# sourceMappingURL=pi-session-synchronizer.provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pi-session-synchronizer.provider.js","sourceRoot":"","sources":["../../../../../../server/modules/providers/list/pi/pi-session-synchronizer.provider.ts"],"names":[],"mappings":"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"}