wind-agent-cli 1.38.3 → 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.
- package/README.md +8 -1
- package/dist/api-docs.html +4 -3
- package/dist/assets/{CodeEditor-C9qFO6L8.js → CodeEditor-C8eMIGen.js} +1 -1
- package/dist/assets/{FileTree-0yJEzBi9.js → FileTree-D52nAPO4.js} +1 -1
- package/dist/assets/{GitPanel-BhbG7yVZ.js → GitPanel-DgeKbZsW.js} +1 -1
- package/dist/assets/{MarkdownPreview-C7pAt3xI.js → MarkdownPreview-B00VQTx6.js} +1 -1
- package/dist/assets/{Shell-CrjXAW4f.js → Shell-twzi9t5B.js} +7 -7
- package/dist/assets/{StandaloneShell-J5BR1g26.js → StandaloneShell-DH_GBJMj.js} +1 -1
- package/dist/assets/{TaskMasterPanel-B2wpEHWP.js → TaskMasterPanel-BY-pMPMl.js} +2 -2
- package/dist/assets/{abnfDiagram-N423BO3Z-DztbjsU0.js → abnfDiagram-N423BO3Z-BwBdstkH.js} +1 -1
- package/dist/assets/{arc-DRGumrCP.js → arc-C0IOpbFP.js} +1 -1
- package/dist/assets/{architectureDiagram-T3A2C74G-DnsczqwM.js → architectureDiagram-T3A2C74G-C-Wkj_AY.js} +1 -1
- package/dist/assets/{blockDiagram-VBNYF7ZC-CPsS5qw5.js → blockDiagram-VBNYF7ZC-_sXAZKku.js} +1 -1
- package/dist/assets/{c4Diagram-5PPSVZJV-DyjwDxYL.js → c4Diagram-5PPSVZJV-C0DUsZv8.js} +1 -1
- package/dist/assets/channel-B6xiB58V.js +1 -0
- package/dist/assets/{chunk-2GRJ4B5K-C794q4RK.js → chunk-2GRJ4B5K-D2TFB_6A.js} +1 -1
- package/dist/assets/{chunk-2Q5K7J3B-BfK76GMF.js → chunk-2Q5K7J3B-B_co_2bI.js} +1 -1
- package/dist/assets/{chunk-5RXB4S5H-Dmwk_KHT.js → chunk-5RXB4S5H-BcUSLq4H.js} +1 -1
- package/dist/assets/{chunk-5VM5RSS4-DOeUnsxL.js → chunk-5VM5RSS4-0mQFBKSp.js} +1 -1
- package/dist/assets/{chunk-6Q2QTUOP-BrjdaybI.js → chunk-6Q2QTUOP-BAkqmW1M.js} +1 -1
- package/dist/assets/{chunk-GF5L2VYU-DCjoLr5D.js → chunk-GF5L2VYU-Cyz0Xl7f.js} +1 -1
- package/dist/assets/{chunk-JWPE2WC7-TEJEfxQK.js → chunk-JWPE2WC7-DYO47aT-.js} +1 -1
- package/dist/assets/{chunk-KBJHAD2P-tbXW-dpx.js → chunk-KBJHAD2P-DvXEzV8J.js} +1 -1
- package/dist/assets/{chunk-RYQCIY6F-CX4Zsite.js → chunk-RYQCIY6F-Beut8dYt.js} +1 -1
- package/dist/assets/{chunk-XXDRQBXY-DVJXNcFN.js → chunk-XXDRQBXY-DLIy1GFl.js} +1 -1
- package/dist/assets/classDiagram-JCYQIIEL-C7xIPTll.js +1 -0
- package/dist/assets/classDiagram-v2-OCEON4UE-C7xIPTll.js +1 -0
- package/dist/assets/{cose-bilkent-JH36ORCC-DLpXc-vJ.js → cose-bilkent-JH36ORCC-DynbO4dj.js} +1 -1
- package/dist/assets/{cynefin-VYW2F7L2-toFyL_eT.js → cynefin-VYW2F7L2-CYTJsH3o.js} +1 -1
- package/dist/assets/{cynefinDiagram-MW4NZA55-7KnX5nu-.js → cynefinDiagram-MW4NZA55-ftj-lAeE.js} +1 -1
- package/dist/assets/{dagre-VZM6K2ZE-C-QOFsDs.js → dagre-VZM6K2ZE-C1kSFboe.js} +1 -1
- package/dist/assets/{diagram-7IWD3JNH-26OmKaGK.js → diagram-7IWD3JNH-CqXHTFrY.js} +1 -1
- package/dist/assets/{diagram-B4RE2ZJO-0o9kK2uO.js → diagram-B4RE2ZJO-B84n3Zko.js} +1 -1
- package/dist/assets/{diagram-LBJQPF4R-CAgMu3zd.js → diagram-LBJQPF4R-B710SefS.js} +1 -1
- package/dist/assets/{diagram-Q27KOJAE-B0W-AePB.js → diagram-Q27KOJAE-CmVPl9pq.js} +1 -1
- package/dist/assets/{diagram-UB23O5K3-66AXZ7Mk.js → diagram-UB23O5K3-LozbeaFL.js} +1 -1
- package/dist/assets/{ebnfDiagram-BXEA7PRR-JlixVrAW.js → ebnfDiagram-BXEA7PRR-B321UBUA.js} +1 -1
- package/dist/assets/{erDiagram-JOGREHBK-ZxzuRr4f.js → erDiagram-JOGREHBK-CTbw676k.js} +1 -1
- package/dist/assets/feature-chat-pY0kOrz2.js +88 -0
- package/dist/assets/feature-workspace-FLomYkPq.js +39 -0
- package/dist/assets/{flowDiagram-UKHOOZJN-u67vU32D.js → flowDiagram-UKHOOZJN-BWVKTWlw.js} +1 -1
- package/dist/assets/{ganttDiagram-PKOTCBZU-Crl9IPqX.js → ganttDiagram-PKOTCBZU-BAj9eeeX.js} +1 -1
- package/dist/assets/{gitGraphDiagram-DS77QQ5N-B2rTRd1W.js → gitGraphDiagram-DS77QQ5N-DcVMRU7N.js} +1 -1
- package/dist/assets/{index-YP8FmBZO.js → index-BYFstHFT.js} +1 -1
- package/dist/assets/index-BbBSplOU.js +35 -0
- package/dist/assets/{index-CPP7a6gU.js → index-BrWTp075.js} +1 -1
- package/dist/assets/index-CHukVVB2.css +1 -0
- package/dist/assets/{index-BTFkWJZe.js → index-k9M0VaFg.js} +1 -1
- package/dist/assets/{infoDiagram-6WML65LV-o9ZSr_ud.js → infoDiagram-6WML65LV-V6wz33B4.js} +1 -1
- package/dist/assets/{ishikawaDiagram-WSZJBQD7-DnrbX4Ui.js → ishikawaDiagram-WSZJBQD7-Dd-WNPyK.js} +1 -1
- package/dist/assets/{journeyDiagram-NVQOT4AX-CSfWpt5R.js → journeyDiagram-NVQOT4AX-D9VCuCeA.js} +1 -1
- package/dist/assets/{kanban-definition-27J2QSJJ-dj3PZxCQ.js → kanban-definition-27J2QSJJ-CUtwDOl-.js} +1 -1
- package/dist/assets/{linear-DieERJn8.js → linear-D_XGf1jO.js} +1 -1
- package/dist/assets/{mermaid.core-cq_VDJvZ.js → mermaid.core-DOnsXioB.js} +4 -4
- package/dist/assets/{mindmap-definition-FAOFIHXS-CHQ8W4LE.js → mindmap-definition-FAOFIHXS-DAYNL5ZV.js} +1 -1
- package/dist/assets/{pegDiagram-VL7TDLO6-CR2rMB3e.js → pegDiagram-VL7TDLO6-B5FX3-E6.js} +1 -1
- package/dist/assets/{pieDiagram-7S7Q4E2Y-Cs4NOlmu.js → pieDiagram-7S7Q4E2Y-EbnDBVd0.js} +1 -1
- package/dist/assets/{quadrantDiagram-CIZ2JOQS-CdHqIaj5.js → quadrantDiagram-CIZ2JOQS-C1koOtwT.js} +1 -1
- package/dist/assets/{railroadDiagram-AXF67PYL-BNPU0Q8Z.js → railroadDiagram-AXF67PYL-D52xmshj.js} +1 -1
- package/dist/assets/{requirementDiagram-LRYGKXZP-DwDQoirA.js → requirementDiagram-LRYGKXZP-B7VbfNnW.js} +1 -1
- package/dist/assets/{sankeyDiagram-W5VNT64P-DSDSpLjf.js → sankeyDiagram-W5VNT64P-CeRG1vHN.js} +1 -1
- package/dist/assets/{sequenceDiagram-SI44F4Z6-zfhext7x.js → sequenceDiagram-SI44F4Z6-CfKHnmSE.js} +1 -1
- package/dist/assets/{sizeCapture-X5ZJPWSS-C56q6k2T.js → sizeCapture-X5ZJPWSS-DJTzyd0S.js} +1 -1
- package/dist/assets/{stateDiagram-OKZ733FA-D2lhrHPg.js → stateDiagram-OKZ733FA-DN0c7IYD.js} +1 -1
- package/dist/assets/stateDiagram-v2-UEYNNEHI-DbihlVOQ.js +1 -0
- package/dist/assets/{swimlanes-SLNWSIFB-D1HyP0oO.js → swimlanes-SLNWSIFB-CaaJpBDA.js} +2 -2
- package/dist/assets/swimlanesDiagram-ULZ7WXOC-BBRevuGP.js +8 -0
- package/dist/assets/{timeline-definition-Z64GVDOM-R1zaf6JI.js → timeline-definition-Z64GVDOM-CrzHN7d2.js} +1 -1
- package/dist/assets/{vennDiagram-T6HMQDX7-BwlaSNYk.js → vennDiagram-T6HMQDX7-BTldHIjo.js} +1 -1
- package/dist/assets/{wardleyDiagram-T6FBY63Y-Dd9-WAib.js → wardleyDiagram-T6FBY63Y-D9Y50OsZ.js} +1 -1
- package/dist/assets/{xychartDiagram-ELKLHX3M-BVn4eBvu.js → xychartDiagram-ELKLHX3M-DjxSJ3aF.js} +1 -1
- package/dist/favicon.png +0 -0
- package/dist/icons/icon-128x128.png +0 -0
- package/dist/icons/icon-144x144.png +0 -0
- package/dist/icons/icon-152x152.png +0 -0
- package/dist/icons/icon-180x180.png +0 -0
- package/dist/icons/icon-192x192.png +0 -0
- package/dist/icons/icon-384x384.png +0 -0
- package/dist/icons/icon-512x512.png +0 -0
- package/dist/icons/icon-72x72.png +0 -0
- package/dist/icons/icon-96x96.png +0 -0
- package/dist/icons/icon-maskable-192x192.png +0 -0
- package/dist/icons/icon-maskable-512x512.png +0 -0
- package/dist/icons/new.png +0 -0
- package/dist/index.html +4 -4
- package/dist/logo-128.png +0 -0
- package/dist/logo-256.png +0 -0
- package/dist/sw.js +1 -1
- package/dist-server/server/index.js +2 -0
- package/dist-server/server/index.js.map +1 -1
- package/dist-server/server/modules/agent/agent.routes.js +14 -2
- package/dist-server/server/modules/agent/agent.routes.js.map +1 -1
- package/dist-server/server/modules/agent/tests/agent.routes.test.js +1 -0
- package/dist-server/server/modules/agent/tests/agent.routes.test.js.map +1 -1
- package/dist-server/server/modules/commands/commands.routes.js +2 -1
- package/dist-server/server/modules/commands/commands.routes.js.map +1 -1
- package/dist-server/server/modules/database/migrations.js +43 -0
- package/dist-server/server/modules/database/migrations.js.map +1 -1
- package/dist-server/server/modules/database/tests/projects.db.integration.test.js +24 -1
- package/dist-server/server/modules/database/tests/projects.db.integration.test.js.map +1 -1
- package/dist-server/server/modules/notifications/services/notification-orchestrator.service.js +2 -0
- package/dist-server/server/modules/notifications/services/notification-orchestrator.service.js.map +1 -1
- package/dist-server/server/modules/providers/list/opencode/opencode-session-synchronizer.provider.js +10 -1
- package/dist-server/server/modules/providers/list/opencode/opencode-session-synchronizer.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/pi/index.js +5 -0
- package/dist-server/server/modules/providers/list/pi/index.js.map +1 -0
- package/dist-server/server/modules/providers/list/pi/pi-auth.provider.js +55 -0
- package/dist-server/server/modules/providers/list/pi/pi-auth.provider.js.map +1 -0
- package/dist-server/server/modules/providers/list/pi/pi-mcp.provider.js +23 -0
- package/dist-server/server/modules/providers/list/pi/pi-mcp.provider.js.map +1 -0
- package/dist-server/server/modules/providers/list/pi/pi-models.provider.js +99 -0
- package/dist-server/server/modules/providers/list/pi/pi-models.provider.js.map +1 -0
- package/dist-server/server/modules/providers/list/pi/pi-runtime.provider.js +262 -0
- package/dist-server/server/modules/providers/list/pi/pi-runtime.provider.js.map +1 -0
- package/dist-server/server/modules/providers/list/pi/pi-session-synchronizer.provider.js +136 -0
- package/dist-server/server/modules/providers/list/pi/pi-session-synchronizer.provider.js.map +1 -0
- package/dist-server/server/modules/providers/list/pi/pi-sessions.provider.js +225 -0
- package/dist-server/server/modules/providers/list/pi/pi-sessions.provider.js.map +1 -0
- package/dist-server/server/modules/providers/list/pi/pi-skills.provider.js +31 -0
- package/dist-server/server/modules/providers/list/pi/pi-skills.provider.js.map +1 -0
- package/dist-server/server/modules/providers/list/pi/pi.provider.js +22 -0
- package/dist-server/server/modules/providers/list/pi/pi.provider.js.map +1 -0
- package/dist-server/server/modules/providers/provider.registry.js +2 -0
- package/dist-server/server/modules/providers/provider.registry.js.map +1 -1
- package/dist-server/server/modules/providers/provider.routes.js +2 -1
- package/dist-server/server/modules/providers/provider.routes.js.map +1 -1
- package/dist-server/server/modules/providers/services/provider-capabilities.service.js +26 -0
- package/dist-server/server/modules/providers/services/provider-capabilities.service.js.map +1 -1
- package/dist-server/server/modules/providers/services/session-synchronizer.service.js +1 -0
- package/dist-server/server/modules/providers/services/session-synchronizer.service.js.map +1 -1
- package/dist-server/server/modules/providers/services/sessions-watcher.service.js +5 -0
- package/dist-server/server/modules/providers/services/sessions-watcher.service.js.map +1 -1
- package/dist-server/server/modules/providers/tests/mcp.test.js +4 -2
- package/dist-server/server/modules/providers/tests/mcp.test.js.map +1 -1
- package/dist-server/server/modules/providers/tests/opencode-sessions.test.js +56 -5
- package/dist-server/server/modules/providers/tests/opencode-sessions.test.js.map +1 -1
- package/dist-server/server/modules/providers/tests/pi-provider.test.js +244 -0
- package/dist-server/server/modules/providers/tests/pi-provider.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/provider-runtime.service.test.js +9 -0
- package/dist-server/server/modules/providers/tests/provider-runtime.service.test.js.map +1 -1
- package/dist-server/server/shared/utils.js +19 -0
- package/dist-server/server/shared/utils.js.map +1 -1
- package/package.json +1 -1
- package/public/api-docs.html +4 -3
- package/scripts/generate-pwa-icons.ps1 +1 -1
- package/server/index.ts +2 -0
- package/server/modules/agent/agent.module.ts +1 -1
- package/server/modules/agent/agent.routes.ts +15 -2
- package/server/modules/agent/tests/agent.routes.test.ts +1 -0
- package/server/modules/commands/commands.routes.ts +2 -1
- package/server/modules/database/migrations.ts +52 -0
- package/server/modules/database/tests/projects.db.integration.test.ts +28 -1
- package/server/modules/notifications/services/notification-orchestrator.service.js +2 -0
- package/server/modules/providers/README.md +5 -1
- package/server/modules/providers/list/opencode/opencode-session-synchronizer.provider.ts +18 -0
- package/server/modules/providers/list/pi/index.ts +4 -0
- package/server/modules/providers/list/pi/pi-auth.provider.ts +58 -0
- package/server/modules/providers/list/pi/pi-mcp.provider.ts +33 -0
- package/server/modules/providers/list/pi/pi-models.provider.ts +114 -0
- package/server/modules/providers/list/pi/pi-runtime.provider.ts +271 -0
- package/server/modules/providers/list/pi/pi-session-synchronizer.provider.ts +134 -0
- package/server/modules/providers/list/pi/pi-sessions.provider.ts +206 -0
- package/server/modules/providers/list/pi/pi-skills.provider.ts +37 -0
- package/server/modules/providers/list/pi/pi.provider.ts +33 -0
- package/server/modules/providers/provider.registry.ts +2 -0
- package/server/modules/providers/provider.routes.ts +1 -0
- package/server/modules/providers/services/provider-capabilities.service.ts +32 -0
- package/server/modules/providers/services/session-synchronizer.service.ts +1 -0
- package/server/modules/providers/services/sessions-watcher.service.ts +5 -0
- package/server/modules/providers/tests/mcp.test.ts +4 -2
- package/server/modules/providers/tests/opencode-sessions.test.ts +81 -6
- package/server/modules/providers/tests/pi-provider.test.ts +244 -0
- package/server/modules/providers/tests/provider-runtime.service.test.ts +10 -0
- package/server/shared/types.ts +1 -1
- package/server/shared/utils.ts +23 -0
- package/dist/assets/channel-Dj-iU3BT.js +0 -1
- package/dist/assets/classDiagram-JCYQIIEL-euwGMP6E.js +0 -1
- package/dist/assets/classDiagram-v2-OCEON4UE-euwGMP6E.js +0 -1
- package/dist/assets/feature-chat-CNYDDkFQ.js +0 -88
- package/dist/assets/feature-workspace-BMlv7Ust.js +0 -39
- package/dist/assets/index-Cr5MbHuj.css +0 -1
- package/dist/assets/index-uINlYqXe.js +0 -35
- package/dist/assets/stateDiagram-v2-UEYNNEHI-C3wzBtFn.js +0 -1
- package/dist/assets/swimlanesDiagram-ULZ7WXOC-Dts8yQMu.js +0 -8
- 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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"}
|