diffing 0.16.0 → 0.16.1
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/dist/cli.mjs +2 -2
- package/dist/client/assets/{angular-html-JZN5kc0L.js → angular-html-ByeJB0rh.js} +1 -1
- package/dist/client/assets/{angular-ts-CJtfwtPm.js → angular-ts-CiwZGajG.js} +1 -1
- package/dist/client/assets/{apl-BW-LdBEV.js → apl-C8k5a5fk.js} +1 -1
- package/dist/client/assets/{arc-CxBp7uj_.js → arc-B8VMoqVr.js} +1 -1
- package/dist/client/assets/{architectureDiagram-3BPJPVTR-DWRcM6V_.js → architectureDiagram-3BPJPVTR-C-ng2xNL.js} +1 -1
- package/dist/client/assets/{astro-gYWZxO_0.js → astro-BE-h-qpp.js} +1 -1
- package/dist/client/assets/{blade-Dhwn6-nM.js → blade-D-0BV1wW.js} +1 -1
- package/dist/client/assets/{blockDiagram-GPEHLZMM-C5RclE5o.js → blockDiagram-GPEHLZMM-DyAQuONU.js} +1 -1
- package/dist/client/assets/{c-DStVJ8gV.js → c-Dg_Gx29H.js} +1 -1
- package/dist/client/assets/{c4Diagram-AAUBKEIU-BGUA_e0K.js → c4Diagram-AAUBKEIU-k5uKTHvm.js} +1 -1
- package/dist/client/assets/channel-DsuXeLi4.js +1 -0
- package/dist/client/assets/{chunk-2J33WTMH-B7n4bw-R.js → chunk-2J33WTMH-Dod_VwYj.js} +1 -1
- package/dist/client/assets/{chunk-3OPIFGDE-w01g5zoV.js → chunk-3OPIFGDE-B8HMjry-.js} +1 -1
- package/dist/client/assets/{chunk-4BX2VUAB-DxqZfswb.js → chunk-4BX2VUAB-TvkJVIZw.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-CbDClk6A.js → chunk-55IACEB6-BsXuKAKc.js} +1 -1
- package/dist/client/assets/{chunk-5ZQYHXKU-CnsO6rSw.js → chunk-5ZQYHXKU-BI1cj2cZ.js} +1 -1
- package/dist/client/assets/{chunk-727SXJPM-BtcRYmEV.js → chunk-727SXJPM-yWQ27Wk0.js} +1 -1
- package/dist/client/assets/{chunk-AQP2D5EJ-CGhb3Sth.js → chunk-AQP2D5EJ-B2BBCtTr.js} +1 -1
- package/dist/client/assets/{chunk-BSJP7CBP-DeuRDOb1.js → chunk-BSJP7CBP-CXXvPXhK.js} +1 -1
- package/dist/client/assets/{chunk-CSCIHK7Q-B9E4vQNj.js → chunk-CSCIHK7Q-jYiloqyi.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-Bq9LG2aQ.js → chunk-FMBD7UC4-DZzqIT32.js} +1 -1
- package/dist/client/assets/{chunk-KSCS5N6A-BVlK-NC4.js → chunk-KSCS5N6A-krdCf8iG.js} +1 -1
- package/dist/client/assets/{chunk-L5ZTLDWV-DcdQquQQ.js → chunk-L5ZTLDWV-0uuTmeZV.js} +1 -1
- package/dist/client/assets/{chunk-LZXEDZCA-D3hLMWf5.js → chunk-LZXEDZCA-BBfUgD06.js} +2 -2
- package/dist/client/assets/{chunk-ND2GUHAM-0nxCj3q_.js → chunk-ND2GUHAM-jkir4ZKE.js} +1 -1
- package/dist/client/assets/{chunk-NZK2D7GU-C_Wkgas6.js → chunk-NZK2D7GU-DMWZNibJ.js} +1 -1
- package/dist/client/assets/{chunk-O5CBEL6O-BjWUWCBx.js → chunk-O5CBEL6O-B1e1HGaX.js} +1 -1
- package/dist/client/assets/chunk-QZHKN3VN-D5b3mBJ2.js +1 -0
- package/dist/client/assets/chunk-WU5MYG2G-C1Pa4Y04.js +1 -0
- package/dist/client/assets/{chunk-XPW4576I-BoIL-UAf.js → chunk-XPW4576I-AvbCAUav.js} +1 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-DCnVfYt-.js +1 -0
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-BPa1Jkt-.js +1 -0
- package/dist/client/assets/{cobol-BhFBbthm.js → cobol-DQnGB_GV.js} +1 -1
- package/dist/client/assets/{coffee-CIJ9uq8T.js → coffee-CDV5a89x.js} +1 -1
- package/dist/client/assets/{cose-bilkent-S5V4N54A-CbiOjhru.js → cose-bilkent-S5V4N54A-t-mDNRF2.js} +1 -1
- package/dist/client/assets/{cpp-DtSSrq00.js → cpp-8G6b-siI.js} +1 -1
- package/dist/client/assets/{crystal-CukkuPMH.js → crystal-CGYCC6FM.js} +1 -1
- package/dist/client/assets/{css-B1khiVXh.js → css-nez4R8_Z.js} +1 -1
- package/dist/client/assets/{dagre-BM42HDAG-DV-L1RXR.js → dagre-BM42HDAG--azesYIg.js} +1 -1
- package/dist/client/assets/{diagram-2AECGRRQ-BIS3Tcy4.js → diagram-2AECGRRQ-4WJ7nKhA.js} +1 -1
- package/dist/client/assets/{diagram-5GNKFQAL-BT7ScWHB.js → diagram-5GNKFQAL-C7ZGhLXn.js} +1 -1
- package/dist/client/assets/{diagram-KO2AKTUF-DhEvzqhQ.js → diagram-KO2AKTUF-BobK_rbl.js} +1 -1
- package/dist/client/assets/{diagram-LMA3HP47-DIh9QR2k.js → diagram-LMA3HP47-BOc-OkIS.js} +1 -1
- package/dist/client/assets/{diagram-OG6HWLK6-V6xtTYuU.js → diagram-OG6HWLK6-BEtLgm86.js} +1 -1
- package/dist/client/assets/{dist--CAI-jgr.js → dist-DPuBwToc.js} +1 -1
- package/dist/client/assets/{edge-CuCj0fvA.js → edge-Z5RMbJQv.js} +1 -1
- package/dist/client/assets/{edit-BMeAI0Sj.js → edit-CFxbgVPV.js} +1 -1
- package/dist/client/assets/{elixir-CakheKmu.js → elixir-d3C79FQc.js} +1 -1
- package/dist/client/assets/{elm-C1NdUKtL.js → elm-CDAf6Uyn.js} +1 -1
- package/dist/client/assets/{erDiagram-TEJ5UH35-DLJ0CCH3.js → erDiagram-TEJ5UH35-D-pR2GY9.js} +1 -1
- package/dist/client/assets/{erb-CetH6rlA.js → erb-CTJk9FKH.js} +1 -1
- package/dist/client/assets/{flowDiagram-I6XJVG4X-aIYTauNq.js → flowDiagram-I6XJVG4X-BwMCy2QV.js} +1 -1
- package/dist/client/assets/{ganttDiagram-6RSMTGT7-DRQE_4dV.js → ganttDiagram-6RSMTGT7-BI1WLJDi.js} +1 -1
- package/dist/client/assets/{git-rebase-sKnthHnf.js → git-rebase-Dr0-MVoW.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-PVQCEYII-DbSrYZsG.js → gitGraphDiagram-PVQCEYII-CUfW0k1f.js} +1 -1
- package/dist/client/assets/{glimmer-js-Bt7nvyGa.js → glimmer-js-CXhLhyW-.js} +1 -1
- package/dist/client/assets/{glimmer-ts-YO9zmz82.js → glimmer-ts-BFAFT-VD.js} +1 -1
- package/dist/client/assets/{glsl-DsvRozYb.js → glsl-D7yanhgY.js} +1 -1
- package/dist/client/assets/{graphql-sXzHf_gb.js → graphql-CpoDxrok.js} +1 -1
- package/dist/client/assets/{hack-C3UDBYU5.js → hack-BL5fmC4q.js} +1 -1
- package/dist/client/assets/{haml-Bfx2v9ts.js → haml-ClAE6RVM.js} +1 -1
- package/dist/client/assets/{handlebars-D7y9m08n.js → handlebars-nHw91uOv.js} +1 -1
- package/dist/client/assets/{html-LJt8Nrzd.js → html-BIiOKqgG.js} +1 -1
- package/dist/client/assets/{html-derivative-GRYtRNx6.js → html-derivative-D1nPnuOK.js} +1 -1
- package/dist/client/assets/{http-CFcGSNWA.js → http-B_QcRZjt.js} +1 -1
- package/dist/client/assets/{hurl-EaOExxlv.js → hurl-CZE0DsD3.js} +1 -1
- package/dist/client/assets/{index-DIOUI027.js → index-Erqhm7rW.js} +7 -7
- package/dist/client/assets/{infoDiagram-5YYISTIA-CT2k1ZKR.js → infoDiagram-5YYISTIA-w2M_OHua.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-D9ZWerXw.js → ishikawaDiagram-YF4QCWOH-CW_l9PGx.js} +1 -1
- package/dist/client/assets/{java-QdNEgqNn.js → java-CXTqX09w.js} +1 -1
- package/dist/client/assets/{javascript-C0TUIalv.js → javascript-9z9ABBep.js} +1 -1
- package/dist/client/assets/{jinja-CHXCs943.js → jinja-Cluf_5Bk.js} +1 -1
- package/dist/client/assets/{jison-Cu1JVrPL.js → jison-CqCEUtc4.js} +1 -1
- package/dist/client/assets/{journeyDiagram-JHISSGLW-CS0prGm3.js → journeyDiagram-JHISSGLW-D-YwusBa.js} +1 -1
- package/dist/client/assets/{json-DbuC832p.js → json-BMq_bPP8.js} +1 -1
- package/dist/client/assets/{jsx-D2ojEfVP.js → jsx-Djij59b9.js} +1 -1
- package/dist/client/assets/{julia-DBG4gf9M.js → julia-DybzCMnh.js} +1 -1
- package/dist/client/assets/{just-cnG6iJYR.js → just-4ChcAr9-.js} +1 -1
- package/dist/client/assets/{kanban-definition-UN3LZRKU-B5_nyCCN.js → kanban-definition-UN3LZRKU-Brvoukmm.js} +1 -1
- package/dist/client/assets/{latex-C-t8YHXx.js → latex-CS2TtFXG.js} +1 -1
- package/dist/client/assets/{line-PhY2p9yO.js → line-CqxM-stA.js} +1 -1
- package/dist/client/assets/{linear-DZfj4bbh.js → linear-C7T82059.js} +1 -1
- package/dist/client/assets/{liquid-BXKFGxIR.js → liquid-84AtYenm.js} +1 -1
- package/dist/client/assets/{lua-BNuqYfRm.js → lua-DJzFx3Cf.js} +1 -1
- package/dist/client/assets/{marko-DSC8kwzM.js → marko-BLw9BV9E.js} +1 -1
- package/dist/client/assets/{mdc-BwB9Dj6D.js → mdc-BjZejN3b.js} +1 -1
- package/dist/client/assets/{mermaid-parser.core-BrVg46EN.js → mermaid-parser.core-BdiEBAsd.js} +1 -1
- package/dist/client/assets/{mermaid.core-Bnf5T6PT.js → mermaid.core-BsnKhnrM.js} +3 -3
- package/dist/client/assets/{mindmap-definition-RKZ34NQL-CAomoDK8.js → mindmap-definition-RKZ34NQL-CBaIFnbc.js} +1 -1
- package/dist/client/assets/{nginx-BrQvZxpD.js → nginx-DuamCwvX.js} +1 -1
- package/dist/client/assets/{nim-tVYcrqi1.js → nim-Bt8c9-ge.js} +1 -1
- package/dist/client/assets/{perl-B-60oGLc.js → perl-D52AfmwC.js} +1 -1
- package/dist/client/assets/{php-DJJABwVz.js → php-BBMlJg0_.js} +1 -1
- package/dist/client/assets/{pieDiagram-4H26LBE5-BOtZhQH4.js → pieDiagram-4H26LBE5-BlmPajcA.js} +1 -1
- package/dist/client/assets/{pug-KJGvmNqp.js → pug-DFHmDqEE.js} +1 -1
- package/dist/client/assets/{qml-6M7QCkVi.js → qml-C0333o-g.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-W4KKPZXB-Pcpz6-BU.js → quadrantDiagram-W4KKPZXB-Bqlm_zZk.js} +1 -1
- package/dist/client/assets/{r-CJX_7SfZ.js → r-DZFmvIgR.js} +1 -1
- package/dist/client/assets/{razor-DYZH4-tY.js → razor-BIGLkWzR.js} +1 -1
- package/dist/client/assets/{regexp-DWtQcg88.js → regexp-BW6jpgf9.js} +1 -1
- package/dist/client/assets/{requirementDiagram-4Y6WPE33-Cruba0r2.js → requirementDiagram-4Y6WPE33-B1PrtUeD.js} +1 -1
- package/dist/client/assets/{review-export-DUMpiyN2.js → review-export-BlgD3bdw.js} +1 -1
- package/dist/client/assets/{rst-idvXY1TW.js → rst-Cj51ZJaa.js} +1 -1
- package/dist/client/assets/{ruby-CBUdU1Jx.js → ruby-lMhGjwpf.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-5OEKKPKP-DpLjNHX_.js → sankeyDiagram-5OEKKPKP-D2HtUNVF.js} +1 -1
- package/dist/client/assets/{sas-CD7-yPwf.js → sas-BWSQku7l.js} +1 -1
- package/dist/client/assets/{scss-CcmN3LNf.js → scss-CdRPuhLN.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-3UESZ5HK-Dxvk3OQI.js → sequenceDiagram-3UESZ5HK-D9SQy0XI.js} +1 -1
- package/dist/client/assets/{shellscript-BxkDFxdN.js → shellscript-DOfOBXcj.js} +1 -1
- package/dist/client/assets/{shellsession-Bz5EKpQO.js → shellsession-7XAOCVni.js} +1 -1
- package/dist/client/assets/{soy-DMVQQ2W2.js → soy-DDnzVRIw.js} +1 -1
- package/dist/client/assets/{sql-B-oK6O9W.js → sql-Ba34agKe.js} +1 -1
- package/dist/client/assets/{src-BNoZKBH3.js → src-BO-qT_v_.js} +1 -1
- package/dist/client/assets/{stata-CUZrRD4_.js → stata-BQlYGHQU.js} +1 -1
- package/dist/client/assets/{stateDiagram-AJRCARHV-DcGkjwzF.js → stateDiagram-AJRCARHV-7IEYjFRo.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-DP6swlL9.js +1 -0
- package/dist/client/assets/{surrealql-TyxgDynf.js → surrealql-BET1l7SW.js} +1 -1
- package/dist/client/assets/{svelte-nYNHcaCO.js → svelte-Bd7ZOeQI.js} +1 -1
- package/dist/client/assets/{templ-DfKxw_Rl.js → templ-BYvRQdOw.js} +1 -1
- package/dist/client/assets/{tex-CNwID2CI.js → tex-CT8DpKxX.js} +1 -1
- package/dist/client/assets/{timeline-definition-PNZ67QCA-CluiloeV.js → timeline-definition-PNZ67QCA-CurQYWmi.js} +1 -1
- package/dist/client/assets/{ts-tags-DgUARkAi.js → ts-tags-D4iPPwau.js} +1 -1
- package/dist/client/assets/{tsx-2yb3iicd.js → tsx-Dgk_Aw-B.js} +1 -1
- package/dist/client/assets/{twig-l1ft8ReI.js → twig-abRNWeh3.js} +1 -1
- package/dist/client/assets/{typescript-BZqXFlL1.js → typescript-BgR1JqdC.js} +1 -1
- package/dist/client/assets/{vennDiagram-CIIHVFJN-DHRoQg07.js → vennDiagram-CIIHVFJN-DbrRBL5S.js} +1 -1
- package/dist/client/assets/{vue-BgXkMZZj.js → vue-DSkhKq4Q.js} +1 -1
- package/dist/client/assets/{vue-html-Byxl7Gyw.js → vue-html-J0jWoD9X.js} +1 -1
- package/dist/client/assets/{vue-vine-Bzpp44S9.js → vue-vine-BgX5MC8-.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-YWT4CUSO-DQ_ujF1q.js → wardleyDiagram-YWT4CUSO-DIFXQsoP.js} +1 -1
- package/dist/client/assets/{xml-CpwLtzxK.js → xml-Ca53xGLB.js} +1 -1
- package/dist/client/assets/{xsl-VlCQyM4_.js → xsl-CNnXclYV.js} +1 -1
- package/dist/client/assets/{xychartDiagram-2RQKCTM6-DjG2u0Gz.js → xychartDiagram-2RQKCTM6-CmfInPqa.js} +1 -1
- package/dist/client/assets/{yaml-BypQObHK.js → yaml-CjjyUhfg.js} +1 -1
- package/dist/client/index.html +1 -1
- package/dist/{mcp-C9HpAFs0.mjs → mcp-BgrRjzn3.mjs} +1 -1
- package/dist/native/tui-darwin-arm64/diffing-tui +0 -0
- package/dist/native/tui-darwin-x64/diffing-tui +0 -0
- package/dist/native/tui-linux-arm64-gnu/diffing-tui +0 -0
- package/dist/native/tui-linux-arm64-musl/diffing-tui +0 -0
- package/dist/native/tui-linux-x64-gnu/diffing-tui +0 -0
- package/dist/native/tui-linux-x64-musl/diffing-tui +0 -0
- package/dist/native/tui-win32-x64-msvc/diffing-tui.exe +0 -0
- package/dist/{server-BmQqrWy4.mjs → server-Ct9QuV1l.mjs} +23 -0
- package/extensions/pi/index.ts +282 -86
- package/extensions/pi/pi-modules.d.ts +70 -0
- package/extensions/pi/tsconfig.json +14 -0
- package/package.json +1 -1
- package/dist/client/assets/channel-BqKSU-HY.js +0 -1
- package/dist/client/assets/chunk-QZHKN3VN-BE1tL2Nx.js +0 -1
- package/dist/client/assets/chunk-WU5MYG2G-DP73Gify.js +0 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK--5lgckcu.js +0 -1
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-CCQu7EQ7.js +0 -1
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-DVv3yrP9.js +0 -1
package/extensions/pi/index.ts
CHANGED
|
@@ -11,17 +11,28 @@
|
|
|
11
11
|
* `[Skill conflicts]` banner appears when pi runs inside the diffing repo.
|
|
12
12
|
*
|
|
13
13
|
* All tool executions spawn the `diffing` CLI in the consumer repo (ctx.cwd).
|
|
14
|
-
* Install: `pi install
|
|
14
|
+
* Install: `pi install npm:diffing` (published on npm),
|
|
15
|
+
* `pi install git:github.com/ahmedragab20/diffing`, or symlink this
|
|
15
16
|
* directory into `~/.pi/agent/extensions/diffing`.
|
|
16
17
|
*/
|
|
17
18
|
|
|
18
19
|
import { spawn } from "node:child_process";
|
|
19
|
-
import {
|
|
20
|
+
import {
|
|
21
|
+
existsSync,
|
|
22
|
+
lstatSync,
|
|
23
|
+
readFileSync,
|
|
24
|
+
realpathSync,
|
|
25
|
+
rmSync,
|
|
26
|
+
symlinkSync,
|
|
27
|
+
} from "node:fs";
|
|
20
28
|
import { homedir } from "node:os";
|
|
21
29
|
import { dirname, join, resolve } from "node:path";
|
|
22
30
|
import { fileURLToPath } from "node:url";
|
|
23
31
|
import { StringEnum } from "@earendil-works/pi-ai";
|
|
24
|
-
import type {
|
|
32
|
+
import type {
|
|
33
|
+
ExtensionAPI,
|
|
34
|
+
ExtensionContext,
|
|
35
|
+
} from "@earendil-works/pi-coding-agent";
|
|
25
36
|
import { Type } from "typebox";
|
|
26
37
|
|
|
27
38
|
// ────────────────────────────────────────────────────────────────────────────
|
|
@@ -134,12 +145,12 @@ function describe(result: RunResult, command: string): string {
|
|
|
134
145
|
return out || "(no output)";
|
|
135
146
|
}
|
|
136
147
|
const err = result.stderr.trim();
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
148
|
+
let hint = "";
|
|
149
|
+
if (result.exitCode === 127) {
|
|
150
|
+
hint = `\n\n\`diffing\` was not found on PATH (ran: diffing ${command}). Install it with \`npm i -g diffing\` or run \`diffing setup\`.`;
|
|
151
|
+
} else if (result.exitCode === 3) {
|
|
152
|
+
hint = `\n\nNo diffing server is running for this repo (ran: diffing ${command}). Start one with \`diffing\` (or the diffing_start_review tool).`;
|
|
153
|
+
}
|
|
143
154
|
return err ? `${err}${hint}` : `exit code ${result.exitCode}${hint}`;
|
|
144
155
|
}
|
|
145
156
|
|
|
@@ -179,7 +190,10 @@ async function refreshStatus(ctx: ExtensionContext): Promise<void> {
|
|
|
179
190
|
const sessions = await activeSessions(ctx.cwd);
|
|
180
191
|
const active = sessions.find((s) => s.active) ?? sessions[0];
|
|
181
192
|
if (active) {
|
|
182
|
-
ctx.ui.setStatus(
|
|
193
|
+
ctx.ui.setStatus(
|
|
194
|
+
"diffing",
|
|
195
|
+
`diffing: ${active.mode ?? "session"} — ${active.url ?? ""}`,
|
|
196
|
+
);
|
|
183
197
|
} else {
|
|
184
198
|
ctx.ui.setStatus("diffing", "diffing: no server");
|
|
185
199
|
}
|
|
@@ -209,7 +223,9 @@ function findGitRepoRoot(startDir: string): string | null {
|
|
|
209
223
|
|
|
210
224
|
function isDiffingRoot(dir: string): boolean {
|
|
211
225
|
try {
|
|
212
|
-
const pkg = JSON.parse(
|
|
226
|
+
const pkg = JSON.parse(
|
|
227
|
+
readFileSync(join(dir, "package.json"), "utf-8"),
|
|
228
|
+
) as { name?: string };
|
|
213
229
|
if (pkg.name !== "diffing") return false;
|
|
214
230
|
return existsSync(join(dir, SKILLS_REL));
|
|
215
231
|
} catch {
|
|
@@ -262,7 +278,11 @@ function selfHealSkillLinks(canonical: string): void {
|
|
|
262
278
|
|
|
263
279
|
function spawnDetachedReview(cwd: string, args: string[]): void {
|
|
264
280
|
try {
|
|
265
|
-
const child = spawn("diffing", args, {
|
|
281
|
+
const child = spawn("diffing", args, {
|
|
282
|
+
cwd,
|
|
283
|
+
stdio: "ignore",
|
|
284
|
+
detached: true,
|
|
285
|
+
});
|
|
266
286
|
child.unref();
|
|
267
287
|
} catch {
|
|
268
288
|
// surfaced by the URL poll below
|
|
@@ -279,7 +299,12 @@ async function ensureReviewUrl(
|
|
|
279
299
|
const existing = await diffingUrl(cwd);
|
|
280
300
|
if (existing && reuse) return { url: existing, reused: true };
|
|
281
301
|
if (existing && !reuse) return { url: existing, reused: true };
|
|
282
|
-
spawnDetachedReview(cwd, [
|
|
302
|
+
spawnDetachedReview(cwd, [
|
|
303
|
+
"--web",
|
|
304
|
+
"--no-open",
|
|
305
|
+
"--skip-setup",
|
|
306
|
+
...extraArgs,
|
|
307
|
+
]);
|
|
283
308
|
const deadline = Date.now() + REVIEW_START_TIMEOUT_MS;
|
|
284
309
|
for (;;) {
|
|
285
310
|
if (signal?.aborted) break;
|
|
@@ -366,20 +391,33 @@ export default function (pi: ExtensionAPI) {
|
|
|
366
391
|
}),
|
|
367
392
|
),
|
|
368
393
|
reuse: Type.Optional(
|
|
369
|
-
Type.Boolean({
|
|
394
|
+
Type.Boolean({
|
|
395
|
+
description:
|
|
396
|
+
"Reuse the active session if one is running. Default: true.",
|
|
397
|
+
default: true,
|
|
398
|
+
}),
|
|
370
399
|
),
|
|
371
400
|
}),
|
|
372
401
|
async execute(_id, params, signal, _onUpdate, ctx) {
|
|
373
402
|
try {
|
|
374
403
|
const extra = params.prRef ? ["--gh-pr", params.prRef] : [];
|
|
375
|
-
const { url, reused } = await ensureReviewUrl(
|
|
404
|
+
const { url, reused } = await ensureReviewUrl(
|
|
405
|
+
ctx.cwd,
|
|
406
|
+
extra,
|
|
407
|
+
params.reuse ?? true,
|
|
408
|
+
signal,
|
|
409
|
+
);
|
|
376
410
|
await refreshStatus(ctx);
|
|
411
|
+
return textResult(`Review ${reused ? "reused" : "started"}: ${url}`, {
|
|
412
|
+
url,
|
|
413
|
+
reused,
|
|
414
|
+
mode: params.prRef ? "gh-pr" : "web",
|
|
415
|
+
});
|
|
416
|
+
} catch (error) {
|
|
377
417
|
return textResult(
|
|
378
|
-
|
|
379
|
-
{
|
|
418
|
+
error instanceof Error ? error.message : String(error),
|
|
419
|
+
{ started: false },
|
|
380
420
|
);
|
|
381
|
-
} catch (error) {
|
|
382
|
-
return textResult(error instanceof Error ? error.message : String(error), { started: false });
|
|
383
421
|
}
|
|
384
422
|
},
|
|
385
423
|
});
|
|
@@ -391,9 +429,17 @@ export default function (pi: ExtensionAPI) {
|
|
|
391
429
|
"Snapshot the current review comments as XML (or JSON). Use --open to see only unresolved threads. Parse the returned XML to act on feedback.",
|
|
392
430
|
parameters: Type.Object({
|
|
393
431
|
open: Type.Optional(
|
|
394
|
-
Type.Boolean({
|
|
432
|
+
Type.Boolean({
|
|
433
|
+
description:
|
|
434
|
+
"Only include open (unresolved) comment threads. Default: true.",
|
|
435
|
+
default: true,
|
|
436
|
+
}),
|
|
437
|
+
),
|
|
438
|
+
format: Type.Optional(
|
|
439
|
+
StringEnum(["xml", "json", "md"] as const, {
|
|
440
|
+
description: "Output format. Default: xml.",
|
|
441
|
+
}),
|
|
395
442
|
),
|
|
396
|
-
format: Type.Optional(StringEnum(["xml", "json", "md"] as const, { description: "Output format. Default: xml." })),
|
|
397
443
|
}),
|
|
398
444
|
async execute(_id, params, _signal, _onUpdate, ctx) {
|
|
399
445
|
const args = ["comments"];
|
|
@@ -411,16 +457,33 @@ export default function (pi: ExtensionAPI) {
|
|
|
411
457
|
pi.registerTool({
|
|
412
458
|
name: "diffing_reply",
|
|
413
459
|
label: "Diffing Reply",
|
|
414
|
-
description:
|
|
460
|
+
description:
|
|
461
|
+
"Append a reply to an existing comment thread by id. Answers questions; does not resolve.",
|
|
415
462
|
parameters: Type.Object({
|
|
416
|
-
commentId: Type.String({
|
|
463
|
+
commentId: Type.String({
|
|
464
|
+
description: "UUID of the comment thread to reply to.",
|
|
465
|
+
}),
|
|
417
466
|
body: Type.String({ description: "Markdown reply body." }),
|
|
418
|
-
model: Type.Optional(
|
|
467
|
+
model: Type.Optional(
|
|
468
|
+
Type.String({
|
|
469
|
+
description: "Model name to attribute. Defaults to the active model.",
|
|
470
|
+
}),
|
|
471
|
+
),
|
|
419
472
|
}),
|
|
420
473
|
async execute(_id, params, _signal, _onUpdate, ctx) {
|
|
421
|
-
const result = await runDiffing(
|
|
422
|
-
|
|
423
|
-
|
|
474
|
+
const result = await runDiffing(
|
|
475
|
+
[
|
|
476
|
+
"reply",
|
|
477
|
+
params.commentId,
|
|
478
|
+
"-",
|
|
479
|
+
"--model",
|
|
480
|
+
modelName(ctx, params.model),
|
|
481
|
+
],
|
|
482
|
+
ctx.cwd,
|
|
483
|
+
{
|
|
484
|
+
stdin: params.body,
|
|
485
|
+
},
|
|
486
|
+
);
|
|
424
487
|
return textResult(describe(result, `diffing reply ${params.commentId}`), {
|
|
425
488
|
exitCode: result.exitCode,
|
|
426
489
|
stderr: result.stderr.trim() || undefined,
|
|
@@ -431,14 +494,20 @@ export default function (pi: ExtensionAPI) {
|
|
|
431
494
|
pi.registerTool({
|
|
432
495
|
name: "diffing_resolve",
|
|
433
496
|
label: "Diffing Resolve",
|
|
434
|
-
description:
|
|
435
|
-
|
|
497
|
+
description:
|
|
498
|
+
"Mark a review comment thread resolved. Use after addressing a change request.",
|
|
499
|
+
parameters: Type.Object({
|
|
500
|
+
commentId: Type.String({ description: "UUID of the comment thread." }),
|
|
501
|
+
}),
|
|
436
502
|
async execute(_id, params, _signal, _onUpdate, ctx) {
|
|
437
503
|
const result = await runDiffing(["resolve", params.commentId], ctx.cwd);
|
|
438
|
-
return textResult(
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
504
|
+
return textResult(
|
|
505
|
+
describe(result, `diffing resolve ${params.commentId}`),
|
|
506
|
+
{
|
|
507
|
+
exitCode: result.exitCode,
|
|
508
|
+
stderr: result.stderr.trim() || undefined,
|
|
509
|
+
},
|
|
510
|
+
);
|
|
442
511
|
},
|
|
443
512
|
});
|
|
444
513
|
|
|
@@ -446,13 +515,18 @@ export default function (pi: ExtensionAPI) {
|
|
|
446
515
|
name: "diffing_unresolve",
|
|
447
516
|
label: "Diffing Unresolve",
|
|
448
517
|
description: "Re-open a previously resolved comment thread.",
|
|
449
|
-
parameters: Type.Object({
|
|
518
|
+
parameters: Type.Object({
|
|
519
|
+
commentId: Type.String({ description: "UUID of the comment thread." }),
|
|
520
|
+
}),
|
|
450
521
|
async execute(_id, params, _signal, _onUpdate, ctx) {
|
|
451
522
|
const result = await runDiffing(["unresolve", params.commentId], ctx.cwd);
|
|
452
|
-
return textResult(
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
523
|
+
return textResult(
|
|
524
|
+
describe(result, `diffing unresolve ${params.commentId}`),
|
|
525
|
+
{
|
|
526
|
+
exitCode: result.exitCode,
|
|
527
|
+
stderr: result.stderr.trim() || undefined,
|
|
528
|
+
},
|
|
529
|
+
);
|
|
456
530
|
},
|
|
457
531
|
});
|
|
458
532
|
|
|
@@ -462,18 +536,35 @@ export default function (pi: ExtensionAPI) {
|
|
|
462
536
|
description:
|
|
463
537
|
"Post a live progress toast to the review UI so the human sees status while work is underway. Safe to call frequently.",
|
|
464
538
|
parameters: Type.Object({
|
|
465
|
-
message: Type.String({
|
|
466
|
-
|
|
467
|
-
|
|
539
|
+
message: Type.String({
|
|
540
|
+
description: "Progress message, e.g. 'Addressing L42…'.",
|
|
541
|
+
}),
|
|
542
|
+
pct: Type.Optional(
|
|
543
|
+
Type.Number({ description: "Optional 0-100 completion percent." }),
|
|
544
|
+
),
|
|
545
|
+
model: Type.Optional(
|
|
546
|
+
Type.String({
|
|
547
|
+
description: "Model name to attribute. Defaults to the active model.",
|
|
548
|
+
}),
|
|
549
|
+
),
|
|
468
550
|
}),
|
|
469
551
|
async execute(_id, params, _signal, _onUpdate, ctx) {
|
|
470
|
-
const args = [
|
|
552
|
+
const args = [
|
|
553
|
+
"progress",
|
|
554
|
+
"--message",
|
|
555
|
+
params.message,
|
|
556
|
+
"--model",
|
|
557
|
+
modelName(ctx, params.model),
|
|
558
|
+
];
|
|
471
559
|
if (params.pct !== undefined) args.push("--pct", String(params.pct));
|
|
472
560
|
const result = await runDiffing(args, ctx.cwd);
|
|
473
|
-
return textResult(
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
561
|
+
return textResult(
|
|
562
|
+
describe(result, `diffing progress --message "${params.message}"`),
|
|
563
|
+
{
|
|
564
|
+
exitCode: result.exitCode,
|
|
565
|
+
stderr: result.stderr.trim() || undefined,
|
|
566
|
+
},
|
|
567
|
+
);
|
|
477
568
|
},
|
|
478
569
|
});
|
|
479
570
|
|
|
@@ -484,12 +575,19 @@ export default function (pi: ExtensionAPI) {
|
|
|
484
575
|
"Synchronously wait (long-poll) until the human releases the review ('Send to agent'), then return the comments XML. Exit code 2 (or a timeout) is an expected park signal — do not silent-loop; resume once the human says the review is ready.",
|
|
485
576
|
parameters: Type.Object({
|
|
486
577
|
timeout: Type.Optional(
|
|
487
|
-
Type.Number({
|
|
578
|
+
Type.Number({
|
|
579
|
+
description: "Max seconds to block. Default: 60 (park beyond that).",
|
|
580
|
+
default: 60,
|
|
581
|
+
}),
|
|
488
582
|
),
|
|
489
583
|
}),
|
|
490
584
|
async execute(_id, params, signal, _onUpdate, ctx) {
|
|
491
585
|
const timeout = Math.min(Math.max(params.timeout ?? 60, 1), 600);
|
|
492
|
-
const result = await runDiffing(
|
|
586
|
+
const result = await runDiffing(
|
|
587
|
+
["await-review", "-t", String(timeout)],
|
|
588
|
+
ctx.cwd,
|
|
589
|
+
{ signal },
|
|
590
|
+
);
|
|
493
591
|
const parked = result.exitCode === 2;
|
|
494
592
|
if (parked) {
|
|
495
593
|
return textResult(
|
|
@@ -512,26 +610,52 @@ export default function (pi: ExtensionAPI) {
|
|
|
512
610
|
"Submit (or resubmit) a markdown plan for human review. Pass the plan as file (path) or body (inline text). Returns the plan id and review URL. Default handoff is async: share the URL, end the turn, act on the verdict when the human decides.",
|
|
513
611
|
parameters: Type.Object({
|
|
514
612
|
file: Type.Optional(
|
|
515
|
-
Type.String({
|
|
613
|
+
Type.String({
|
|
614
|
+
description:
|
|
615
|
+
"Path to the plan markdown file. Use the body parameter instead to submit inline text.",
|
|
616
|
+
}),
|
|
617
|
+
),
|
|
618
|
+
body: Type.Optional(
|
|
619
|
+
Type.String({ description: "Inline plan markdown body." }),
|
|
620
|
+
),
|
|
621
|
+
title: Type.Optional(
|
|
622
|
+
Type.String({
|
|
623
|
+
description: "Display title. Defaults to the plan's first heading.",
|
|
624
|
+
}),
|
|
516
625
|
),
|
|
517
|
-
body: Type.Optional(Type.String({ description: "Inline plan markdown body." })),
|
|
518
|
-
title: Type.Optional(Type.String({ description: "Display title. Defaults to the plan's first heading." })),
|
|
519
626
|
planId: Type.Optional(
|
|
520
|
-
Type.String({
|
|
627
|
+
Type.String({
|
|
628
|
+
description:
|
|
629
|
+
"Resubmit a revised body for an existing plan id (bumps version, resets verdict).",
|
|
630
|
+
}),
|
|
631
|
+
),
|
|
632
|
+
model: Type.Optional(
|
|
633
|
+
Type.String({
|
|
634
|
+
description: "Authoring model. Defaults to the active model.",
|
|
635
|
+
}),
|
|
521
636
|
),
|
|
522
|
-
model: Type.Optional(Type.String({ description: "Authoring model. Defaults to the active model." })),
|
|
523
637
|
}),
|
|
524
638
|
async execute(_id, params, signal, _onUpdate, ctx) {
|
|
525
639
|
let stdin: string | undefined;
|
|
526
640
|
let fileArg = params.file;
|
|
527
641
|
if (!fileArg) {
|
|
528
642
|
if (!params.body) {
|
|
529
|
-
return textResult(
|
|
643
|
+
return textResult(
|
|
644
|
+
"Provide either file (path) or body (inline plan markdown).",
|
|
645
|
+
{ submitted: false },
|
|
646
|
+
);
|
|
530
647
|
}
|
|
531
648
|
fileArg = "-";
|
|
532
649
|
stdin = params.body;
|
|
533
650
|
}
|
|
534
|
-
const args = [
|
|
651
|
+
const args = [
|
|
652
|
+
"plan",
|
|
653
|
+
"submit",
|
|
654
|
+
fileArg,
|
|
655
|
+
"--save-source",
|
|
656
|
+
"--model",
|
|
657
|
+
modelName(ctx, params.model),
|
|
658
|
+
];
|
|
535
659
|
if (params.title) args.push("--title", params.title);
|
|
536
660
|
if (params.planId) args.push("--id", params.planId);
|
|
537
661
|
const result = await runDiffing(args, ctx.cwd, { signal, stdin });
|
|
@@ -559,12 +683,19 @@ export default function (pi: ExtensionAPI) {
|
|
|
559
683
|
"Synchronously wait until the human decides on the submitted plan, then return the <plan-review> XML with the verdict. Exit code 2 is an expected park signal — do not silent-loop.",
|
|
560
684
|
parameters: Type.Object({
|
|
561
685
|
timeout: Type.Optional(
|
|
562
|
-
Type.Number({
|
|
686
|
+
Type.Number({
|
|
687
|
+
description: "Max seconds to block. Default: 60 (park beyond that).",
|
|
688
|
+
default: 60,
|
|
689
|
+
}),
|
|
563
690
|
),
|
|
564
691
|
}),
|
|
565
692
|
async execute(_id, params, signal, _onUpdate, ctx) {
|
|
566
693
|
const timeout = Math.min(Math.max(params.timeout ?? 60, 1), 600);
|
|
567
|
-
const result = await runDiffing(
|
|
694
|
+
const result = await runDiffing(
|
|
695
|
+
["plan", "await", "-t", String(timeout)],
|
|
696
|
+
ctx.cwd,
|
|
697
|
+
{ signal },
|
|
698
|
+
);
|
|
568
699
|
if (result.exitCode === 2) {
|
|
569
700
|
return textResult(
|
|
570
701
|
`No plan verdict within ${timeout}s (park). Share the plan URL and end your turn; run diffing_plan_await again when the human says the verdict is ready.`,
|
|
@@ -582,9 +713,12 @@ export default function (pi: ExtensionAPI) {
|
|
|
582
713
|
pi.registerTool({
|
|
583
714
|
name: "diffing_plan_list",
|
|
584
715
|
label: "Diffing Plan List",
|
|
585
|
-
description:
|
|
716
|
+
description:
|
|
717
|
+
"List submitted plans for the current repo (id, decision, version, open comments, title).",
|
|
586
718
|
parameters: Type.Object({
|
|
587
|
-
json: Type.Optional(
|
|
719
|
+
json: Type.Optional(
|
|
720
|
+
Type.Boolean({ description: "Emit raw JSON instead of the table." }),
|
|
721
|
+
),
|
|
588
722
|
}),
|
|
589
723
|
async execute(_id, params, _signal, _onUpdate, ctx) {
|
|
590
724
|
const args = ["plan", "list"];
|
|
@@ -600,10 +734,15 @@ export default function (pi: ExtensionAPI) {
|
|
|
600
734
|
pi.registerTool({
|
|
601
735
|
name: "diffing_plan_show",
|
|
602
736
|
label: "Diffing Plan Show",
|
|
603
|
-
description:
|
|
737
|
+
description:
|
|
738
|
+
"Show a single plan as <plan-review> XML (or raw JSON) including the verdict and open comments.",
|
|
604
739
|
parameters: Type.Object({
|
|
605
|
-
planId: Type.Optional(
|
|
606
|
-
|
|
740
|
+
planId: Type.Optional(
|
|
741
|
+
Type.String({ description: "Plan id. Omit for the latest plan." }),
|
|
742
|
+
),
|
|
743
|
+
json: Type.Optional(
|
|
744
|
+
Type.Boolean({ description: "Emit raw JSON instead of XML." }),
|
|
745
|
+
),
|
|
607
746
|
}),
|
|
608
747
|
async execute(_id, params, _signal, _onUpdate, ctx) {
|
|
609
748
|
const args = ["plan", "show"];
|
|
@@ -620,22 +759,37 @@ export default function (pi: ExtensionAPI) {
|
|
|
620
759
|
pi.registerTool({
|
|
621
760
|
name: "diffing_plan_reply",
|
|
622
761
|
label: "Diffing Plan Reply",
|
|
623
|
-
description:
|
|
762
|
+
description:
|
|
763
|
+
"Reply to an inline plan comment (the owning plan is resolved automatically).",
|
|
624
764
|
parameters: Type.Object({
|
|
625
765
|
commentId: Type.String({ description: "UUID of the plan comment." }),
|
|
626
766
|
body: Type.String({ description: "Markdown reply body." }),
|
|
627
|
-
model: Type.Optional(
|
|
767
|
+
model: Type.Optional(
|
|
768
|
+
Type.String({
|
|
769
|
+
description: "Model name to attribute. Defaults to the active model.",
|
|
770
|
+
}),
|
|
771
|
+
),
|
|
628
772
|
}),
|
|
629
773
|
async execute(_id, params, _signal, _onUpdate, ctx) {
|
|
630
774
|
const result = await runDiffing(
|
|
631
|
-
[
|
|
775
|
+
[
|
|
776
|
+
"plan",
|
|
777
|
+
"reply",
|
|
778
|
+
params.commentId,
|
|
779
|
+
"-",
|
|
780
|
+
"--model",
|
|
781
|
+
modelName(ctx, params.model),
|
|
782
|
+
],
|
|
632
783
|
ctx.cwd,
|
|
633
784
|
{ stdin: params.body },
|
|
634
785
|
);
|
|
635
|
-
return textResult(
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
786
|
+
return textResult(
|
|
787
|
+
describe(result, `diffing plan reply ${params.commentId}`),
|
|
788
|
+
{
|
|
789
|
+
exitCode: result.exitCode,
|
|
790
|
+
stderr: result.stderr.trim() || undefined,
|
|
791
|
+
},
|
|
792
|
+
);
|
|
639
793
|
},
|
|
640
794
|
});
|
|
641
795
|
|
|
@@ -643,25 +797,36 @@ export default function (pi: ExtensionAPI) {
|
|
|
643
797
|
name: "diffing_plan_resolve",
|
|
644
798
|
label: "Diffing Plan Resolve",
|
|
645
799
|
description: "Mark a plan comment resolved.",
|
|
646
|
-
parameters: Type.Object({
|
|
800
|
+
parameters: Type.Object({
|
|
801
|
+
commentId: Type.String({ description: "UUID of the plan comment." }),
|
|
802
|
+
}),
|
|
647
803
|
async execute(_id, params, _signal, _onUpdate, ctx) {
|
|
648
|
-
const result = await runDiffing(
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
804
|
+
const result = await runDiffing(
|
|
805
|
+
["plan", "resolve", params.commentId],
|
|
806
|
+
ctx.cwd,
|
|
807
|
+
);
|
|
808
|
+
return textResult(
|
|
809
|
+
describe(result, `diffing plan resolve ${params.commentId}`),
|
|
810
|
+
{
|
|
811
|
+
exitCode: result.exitCode,
|
|
812
|
+
stderr: result.stderr.trim() || undefined,
|
|
813
|
+
},
|
|
814
|
+
);
|
|
653
815
|
},
|
|
654
816
|
});
|
|
655
817
|
|
|
656
818
|
pi.registerTool({
|
|
657
819
|
name: "diffing_url",
|
|
658
820
|
label: "Diffing URL",
|
|
659
|
-
description:
|
|
821
|
+
description:
|
|
822
|
+
"Print the base URL of the active diffing review server for this repo, or report that none is running.",
|
|
660
823
|
parameters: Type.Object({}),
|
|
661
824
|
async execute(_id, _params, _signal, _onUpdate, ctx) {
|
|
662
825
|
const url = await diffingUrl(ctx.cwd);
|
|
663
826
|
return textResult(
|
|
664
|
-
url
|
|
827
|
+
url
|
|
828
|
+
? url
|
|
829
|
+
: "No diffing server running for this repo. Start one with diffing_start_review or `/diffing`.",
|
|
665
830
|
{ url },
|
|
666
831
|
);
|
|
667
832
|
},
|
|
@@ -673,9 +838,19 @@ export default function (pi: ExtensionAPI) {
|
|
|
673
838
|
description:
|
|
674
839
|
"List, select, or stop live diffing review sessions for this repo. use: retarget agent commands to a session id prefix. stop: graceful shutdown of a session.",
|
|
675
840
|
parameters: Type.Object({
|
|
676
|
-
action: Type.Optional(
|
|
677
|
-
|
|
678
|
-
|
|
841
|
+
action: Type.Optional(
|
|
842
|
+
StringEnum(["list", "use", "stop"] as const, {
|
|
843
|
+
description: "Action. Default: list.",
|
|
844
|
+
}),
|
|
845
|
+
),
|
|
846
|
+
value: Type.Optional(
|
|
847
|
+
Type.String({
|
|
848
|
+
description: "Session id prefix (for use/stop), or 'active'/'all'.",
|
|
849
|
+
}),
|
|
850
|
+
),
|
|
851
|
+
json: Type.Optional(
|
|
852
|
+
Type.Boolean({ description: "Emit JSON for list. Default: false." }),
|
|
853
|
+
),
|
|
679
854
|
}),
|
|
680
855
|
async execute(_id, params, _signal, _onUpdate, ctx) {
|
|
681
856
|
const action = params.action ?? "list";
|
|
@@ -700,7 +875,11 @@ export default function (pi: ExtensionAPI) {
|
|
|
700
875
|
description:
|
|
701
876
|
"Probe the active GitHub PR review session: PR identity, head/base SHAs, patch size, and conversation/draft counts. Fails cleanly when no PR session is active.",
|
|
702
877
|
parameters: Type.Object({
|
|
703
|
-
json: Type.Optional(
|
|
878
|
+
json: Type.Optional(
|
|
879
|
+
Type.Boolean({
|
|
880
|
+
description: "Emit raw JSON instead of human-readable output.",
|
|
881
|
+
}),
|
|
882
|
+
),
|
|
704
883
|
}),
|
|
705
884
|
async execute(_id, params, _signal, _onUpdate, ctx) {
|
|
706
885
|
const args = ["gh", "overview"];
|
|
@@ -719,15 +898,29 @@ export default function (pi: ExtensionAPI) {
|
|
|
719
898
|
description:
|
|
720
899
|
"Escape hatch: run any documented `diffing` agent subcommand with raw arguments. Examples: ['inspect','summary'], ['comment','edit',id,'--body','...'], ['gh','threads','--unresolved'], ['gh','reviews'], ['plan','versions',id], ['doctor'], ['mode']. Returns stdout + exit code; exit 3 means no server.",
|
|
721
900
|
parameters: Type.Object({
|
|
722
|
-
args: Type.Array(
|
|
723
|
-
|
|
901
|
+
args: Type.Array(
|
|
902
|
+
Type.String({
|
|
903
|
+
description: "Subcommand and arguments, e.g. ['inspect','summary'].",
|
|
904
|
+
}),
|
|
905
|
+
),
|
|
906
|
+
stdin: Type.Optional(
|
|
907
|
+
Type.String({
|
|
908
|
+
description:
|
|
909
|
+
"Optional text to pipe to the command's stdin (e.g. reply bodies).",
|
|
910
|
+
}),
|
|
911
|
+
),
|
|
724
912
|
}),
|
|
725
913
|
async execute(_id, params, signal, _onUpdate, ctx) {
|
|
726
914
|
const args = params.args;
|
|
727
915
|
if (!Array.isArray(args) || args.length === 0) {
|
|
728
|
-
return textResult("Provide at least one subcommand argument.", {
|
|
916
|
+
return textResult("Provide at least one subcommand argument.", {
|
|
917
|
+
ran: false,
|
|
918
|
+
});
|
|
729
919
|
}
|
|
730
|
-
const result = await runDiffing(args, ctx.cwd, {
|
|
920
|
+
const result = await runDiffing(args, ctx.cwd, {
|
|
921
|
+
signal,
|
|
922
|
+
stdin: params.stdin,
|
|
923
|
+
});
|
|
731
924
|
return textResult(describe(result, `diffing ${args.join(" ")}`), {
|
|
732
925
|
exitCode: result.exitCode,
|
|
733
926
|
stderr: result.stderr.trim() || undefined,
|
|
@@ -747,7 +940,10 @@ export default function (pi: ExtensionAPI) {
|
|
|
747
940
|
await refreshStatus(ctx);
|
|
748
941
|
ctx.ui.notify(`diffing review: ${url}`, "info");
|
|
749
942
|
} catch (error) {
|
|
750
|
-
ctx.ui.notify(
|
|
943
|
+
ctx.ui.notify(
|
|
944
|
+
error instanceof Error ? error.message : String(error),
|
|
945
|
+
"error",
|
|
946
|
+
);
|
|
751
947
|
}
|
|
752
948
|
},
|
|
753
949
|
});
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ambient declarations for pi-bundled modules.
|
|
3
|
+
*
|
|
4
|
+
* The pi harness provides `@earendil-works/pi-ai`, `@earendil-works/pi-coding-agent`
|
|
5
|
+
* and `typebox` at extension load time — they are intentionally NOT installed in
|
|
6
|
+
* this repository (keeps the product lockfile free of the pi runtime tree). These
|
|
7
|
+
* declarations let the extension typecheck standalone for editors/LSP; the
|
|
8
|
+
* authoritative types are the real packages resolved by pi at runtime.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
declare module "@earendil-works/pi-ai" {
|
|
12
|
+
export function StringEnum<T extends readonly string[]>(
|
|
13
|
+
values: T,
|
|
14
|
+
options?: { description?: string; default?: T[number] },
|
|
15
|
+
): { type: "string"; enum: T; description?: string; default?: T[number] };
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
declare module "@earendil-works/pi-coding-agent" {
|
|
19
|
+
export interface ExtensionContext {
|
|
20
|
+
cwd: string;
|
|
21
|
+
hasUI: boolean;
|
|
22
|
+
model?: { id: string; provider?: string };
|
|
23
|
+
ui: {
|
|
24
|
+
setStatus(id: string, text: string): void;
|
|
25
|
+
notify(
|
|
26
|
+
text: string,
|
|
27
|
+
level?: "info" | "error" | "success" | "warning",
|
|
28
|
+
): void;
|
|
29
|
+
setWidget?(id: string, lines: string[]): void;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface ToolResult {
|
|
34
|
+
content: { type: "text"; text: string }[];
|
|
35
|
+
details: Record<string, unknown>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface ToolDefinition {
|
|
39
|
+
name: string;
|
|
40
|
+
label?: string;
|
|
41
|
+
description: string;
|
|
42
|
+
parameters: any;
|
|
43
|
+
execute(
|
|
44
|
+
toolCallId: string,
|
|
45
|
+
params: any,
|
|
46
|
+
signal: AbortSignal | undefined,
|
|
47
|
+
onUpdate: any,
|
|
48
|
+
ctx: ExtensionContext,
|
|
49
|
+
): Promise<ToolResult> | ToolResult;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface ExtensionAPI {
|
|
53
|
+
on(
|
|
54
|
+
event: string,
|
|
55
|
+
handler: (event: any, ctx: ExtensionContext) => any,
|
|
56
|
+
): void;
|
|
57
|
+
registerTool(definition: ToolDefinition): void;
|
|
58
|
+
registerCommand(
|
|
59
|
+
name: string,
|
|
60
|
+
definition: {
|
|
61
|
+
description?: string;
|
|
62
|
+
handler: (args: string | undefined, ctx: ExtensionContext) => any;
|
|
63
|
+
},
|
|
64
|
+
): void;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
declare module "typebox" {
|
|
69
|
+
export const Type: any;
|
|
70
|
+
}
|