diffing 0.18.1 → 0.18.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{cli-agent-Cf6SAnH4.mjs → cli-agent-DV5ZhMX1.mjs} +209 -25
- package/dist/{cli-gh-2NEumKQB.mjs → cli-gh-0hY7pvwJ.mjs} +2 -2
- package/dist/cli.mjs +13 -12
- package/dist/client/assets/{angular-html-BV3gPi7L.js → angular-html-DgLkj6cM.js} +1 -1
- package/dist/client/assets/{angular-ts-DuuSfKJK.js → angular-ts-S7IdfqOh.js} +1 -1
- package/dist/client/assets/{apl-BMc69egk.js → apl-dC851k0e.js} +1 -1
- package/dist/client/assets/{arc-CEC1cz1S.js → arc-v8u_6qG_.js} +1 -1
- package/dist/client/assets/{architectureDiagram-3BPJPVTR-BmJ5OHgd.js → architectureDiagram-3BPJPVTR-CtfNNxPZ.js} +1 -1
- package/dist/client/assets/{astro-Bg_CYwmB.js → astro-DgnNzfoZ.js} +1 -1
- package/dist/client/assets/{blade-Mca0XoRC.js → blade-By7nZeyV.js} +1 -1
- package/dist/client/assets/{blockDiagram-GPEHLZMM--XrThRLW.js → blockDiagram-GPEHLZMM-cfmYosKW.js} +1 -1
- package/dist/client/assets/{c-B2Uqi6oI.js → c-C6I1CPq_.js} +1 -1
- package/dist/client/assets/{c4Diagram-AAUBKEIU-W8w5oiRi.js → c4Diagram-AAUBKEIU-L52oIoFq.js} +1 -1
- package/dist/client/assets/channel-B8Y5aSHX.js +1 -0
- package/dist/client/assets/{chunk-2J33WTMH-Bpr3MqKf.js → chunk-2J33WTMH-Dpy-98nI.js} +1 -1
- package/dist/client/assets/{chunk-3OPIFGDE-DdMV_3DM.js → chunk-3OPIFGDE-DsFmltuQ.js} +1 -1
- package/dist/client/assets/{chunk-4BX2VUAB-BkfeLLsz.js → chunk-4BX2VUAB-B1PXeD30.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-pCwXbxR0.js → chunk-55IACEB6-BkfaPY5R.js} +1 -1
- package/dist/client/assets/{chunk-5ZQYHXKU-BGFzCgvs.js → chunk-5ZQYHXKU-kHj4q0HC.js} +1 -1
- package/dist/client/assets/{chunk-727SXJPM-DU7oVWfJ.js → chunk-727SXJPM-DYndNEF7.js} +1 -1
- package/dist/client/assets/{chunk-AQP2D5EJ-DaVYG1qm.js → chunk-AQP2D5EJ-CGgu3cJd.js} +1 -1
- package/dist/client/assets/{chunk-BSJP7CBP-DAvnzgjY.js → chunk-BSJP7CBP-B85q9YnN.js} +1 -1
- package/dist/client/assets/{chunk-CSCIHK7Q-D6ZDvMsi.js → chunk-CSCIHK7Q-D4izdgab.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-BFDCYCqF.js → chunk-FMBD7UC4-CwH6kGrM.js} +1 -1
- package/dist/client/assets/{chunk-KSCS5N6A-BmD6XY52.js → chunk-KSCS5N6A-D6WNG6Qv.js} +1 -1
- package/dist/client/assets/{chunk-L5ZTLDWV-Dl9iUIBf.js → chunk-L5ZTLDWV-BFzgANjL.js} +1 -1
- package/dist/client/assets/{chunk-LZXEDZCA-rOOJDxdB.js → chunk-LZXEDZCA-CXVdeXQA.js} +2 -2
- package/dist/client/assets/{chunk-ND2GUHAM-DBDu-JeD.js → chunk-ND2GUHAM-nez7hw5f.js} +1 -1
- package/dist/client/assets/{chunk-NZK2D7GU-CRyk4F3R.js → chunk-NZK2D7GU-DQxrGm1r.js} +1 -1
- package/dist/client/assets/{chunk-O5CBEL6O-DcKB07iP.js → chunk-O5CBEL6O-BAYDbzO8.js} +1 -1
- package/dist/client/assets/chunk-QZHKN3VN-DPZNzASS.js +1 -0
- package/dist/client/assets/chunk-WU5MYG2G-DOKX6dPU.js +1 -0
- package/dist/client/assets/{chunk-XPW4576I-WuzWMSrp.js → chunk-XPW4576I-DdtioiQK.js} +1 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-CkitIGos.js +1 -0
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-BD7zcbFa.js +1 -0
- package/dist/client/assets/{cobol-oQ1i-YtO.js → cobol-DVRUz845.js} +1 -1
- package/dist/client/assets/{coffee-s9XlmHbB.js → coffee-ywp-ztcj.js} +1 -1
- package/dist/client/assets/{cose-bilkent-S5V4N54A-CymUm7fn.js → cose-bilkent-S5V4N54A-YAV-XlD-.js} +1 -1
- package/dist/client/assets/{cpp-D60LxTox.js → cpp-lGJg5yP8.js} +1 -1
- package/dist/client/assets/{crystal-CHrCczDb.js → crystal-C255DQNq.js} +1 -1
- package/dist/client/assets/{css-1PQO32Hw.js → css-D0fueLBG.js} +1 -1
- package/dist/client/assets/{dagre-BM42HDAG-DOHZc0tO.js → dagre-BM42HDAG-C-nRRJ_h.js} +1 -1
- package/dist/client/assets/{diagram-2AECGRRQ-D8O2cleS.js → diagram-2AECGRRQ-Cy08G2GT.js} +1 -1
- package/dist/client/assets/{diagram-5GNKFQAL-CO-Ej4UD.js → diagram-5GNKFQAL-B5KxlMfb.js} +1 -1
- package/dist/client/assets/{diagram-KO2AKTUF-DCUr4wzS.js → diagram-KO2AKTUF-BtlklsuV.js} +1 -1
- package/dist/client/assets/{diagram-LMA3HP47-D9HnA0Qg.js → diagram-LMA3HP47-DwJhvsVf.js} +1 -1
- package/dist/client/assets/{diagram-OG6HWLK6-BxAitO2n.js → diagram-OG6HWLK6-e6mkflzE.js} +1 -1
- package/dist/client/assets/{dist-N-ROBnkL.js → dist-8nkFH_K6.js} +1 -1
- package/dist/client/assets/{edge-Ck54Fn7y.js → edge-Cy4Xn6qQ.js} +1 -1
- package/dist/client/assets/{edit-B8RwtrDs.js → edit-C3wvBNC7.js} +1 -1
- package/dist/client/assets/{elixir-xXxdfsfU.js → elixir-CHz66mgQ.js} +1 -1
- package/dist/client/assets/{elm-g0vLRWbF.js → elm-CuSKJX5P.js} +1 -1
- package/dist/client/assets/{erDiagram-TEJ5UH35-1ZMg7g98.js → erDiagram-TEJ5UH35-U7lAAznz.js} +1 -1
- package/dist/client/assets/{erb-CGFnxOST.js → erb-BbtQ1hep.js} +1 -1
- package/dist/client/assets/{flowDiagram-I6XJVG4X-D5u9lhJ-.js → flowDiagram-I6XJVG4X-jIylSBs9.js} +1 -1
- package/dist/client/assets/{ganttDiagram-6RSMTGT7-BbVKEzs8.js → ganttDiagram-6RSMTGT7-DW3d8a36.js} +1 -1
- package/dist/client/assets/{git-rebase-B3s6bE5_.js → git-rebase-R-XkmJUY.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-PVQCEYII-sAottiiz.js → gitGraphDiagram-PVQCEYII-BHzkJu8s.js} +1 -1
- package/dist/client/assets/{glimmer-js-C2Xff18_.js → glimmer-js-C_yhese4.js} +1 -1
- package/dist/client/assets/{glimmer-ts-CRBS8ftd.js → glimmer-ts-DKD-Bn0M.js} +1 -1
- package/dist/client/assets/{glsl-aOY_t6dG.js → glsl-CJScdeHB.js} +1 -1
- package/dist/client/assets/{graphql-Cucpdpc6.js → graphql-BUP7lnbX.js} +1 -1
- package/dist/client/assets/{hack-Bw0KkVza.js → hack-Uu2tSM5_.js} +1 -1
- package/dist/client/assets/{haml-DnyaPoa2.js → haml-BKKDeeb3.js} +1 -1
- package/dist/client/assets/{handlebars-AedEof-m.js → handlebars-DXZJVvuj.js} +1 -1
- package/dist/client/assets/{html-Bu5h_Kgf.js → html-BNpfcyGi.js} +1 -1
- package/dist/client/assets/{html-derivative-CNiVLld1.js → html-derivative-D2Zj9RHU.js} +1 -1
- package/dist/client/assets/{http-B9-oOYPw.js → http-BDjsRgLN.js} +1 -1
- package/dist/client/assets/{hurl-Bo6NUnnd.js → hurl-D_YxHbnH.js} +1 -1
- package/dist/client/assets/{index-BkwV-g6J.js → index-CpN9wq1L.js} +142 -142
- package/dist/client/assets/{index-C73yr1tm.css → index-EoTRSuBL.css} +1 -1
- package/dist/client/assets/{infoDiagram-5YYISTIA-CfVELF4R.js → infoDiagram-5YYISTIA-oGpzG0Af.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-DztjIGfb.js → ishikawaDiagram-YF4QCWOH-066RGSaQ.js} +1 -1
- package/dist/client/assets/{java-JJ3dl_jz.js → java-DeOKsdfJ.js} +1 -1
- package/dist/client/assets/{javascript-QgUuQNTw.js → javascript-oM5JhL2b.js} +1 -1
- package/dist/client/assets/{jinja-GbeEm2-u.js → jinja-CpW87uSV.js} +1 -1
- package/dist/client/assets/{jison-BXZbHsO3.js → jison-Du6rTe9r.js} +1 -1
- package/dist/client/assets/{journeyDiagram-JHISSGLW-Lg8CkxeI.js → journeyDiagram-JHISSGLW-BB4Aymt4.js} +1 -1
- package/dist/client/assets/{json-D02YvQSa.js → json-Cl5vEJGM.js} +1 -1
- package/dist/client/assets/{jsx-eZde6NZS.js → jsx-D3lCkT_f.js} +1 -1
- package/dist/client/assets/{julia-CfcuUD-A.js → julia-P1bWdzXQ.js} +1 -1
- package/dist/client/assets/{just-hQr8WcQp.js → just-BQHIj4wn.js} +1 -1
- package/dist/client/assets/{kanban-definition-UN3LZRKU-BWIeZIf6.js → kanban-definition-UN3LZRKU-CveGMVSw.js} +1 -1
- package/dist/client/assets/{latex-BxffZwv_.js → latex-CzeBoguz.js} +1 -1
- package/dist/client/assets/{line-Cy1AFxf0.js → line-CjLRf0wl.js} +1 -1
- package/dist/client/assets/{linear-Kk5IbGHr.js → linear-GmrB0HMZ.js} +1 -1
- package/dist/client/assets/{liquid-BvKnpUyR.js → liquid-BNh96Tca.js} +1 -1
- package/dist/client/assets/{lua-Bcds2vY9.js → lua-CNQoqqQP.js} +1 -1
- package/dist/client/assets/{marko-CZJQLjYc.js → marko-C_xevFIb.js} +1 -1
- package/dist/client/assets/{mdc-BRigtixg.js → mdc-XPBTv6ak.js} +1 -1
- package/dist/client/assets/{mermaid-parser.core-Dh2uTVxt.js → mermaid-parser.core-HsXe3oD9.js} +1 -1
- package/dist/client/assets/{mermaid.core-CXIGVQ74.js → mermaid.core-BukRjtV2.js} +3 -3
- package/dist/client/assets/{mindmap-definition-RKZ34NQL-DQNQJuAB.js → mindmap-definition-RKZ34NQL-VTmEFYO4.js} +1 -1
- package/dist/client/assets/{nginx-BI3-LI9U.js → nginx-C6cZlyey.js} +1 -1
- package/dist/client/assets/{nim-PEd8ZOME.js → nim-Cd9xainG.js} +1 -1
- package/dist/client/assets/{perl-BPTGdP4p.js → perl-DUfKG3XX.js} +1 -1
- package/dist/client/assets/{php-C8BKL0yL.js → php-DqMFPxyM.js} +1 -1
- package/dist/client/assets/{pieDiagram-4H26LBE5-Dz7gE0t5.js → pieDiagram-4H26LBE5-Bwlobw-Z.js} +1 -1
- package/dist/client/assets/{pug-H5z9rtbz.js → pug-GUix1iYH.js} +1 -1
- package/dist/client/assets/{qml-EzSpo2aM.js → qml-CqF34de7.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-W4KKPZXB-pTnmYdEJ.js → quadrantDiagram-W4KKPZXB-CMujQAS2.js} +1 -1
- package/dist/client/assets/{r-VMeUwMIt.js → r-BxeiO8R8.js} +1 -1
- package/dist/client/assets/{razor-Ne05zcaj.js → razor-Cu8elnMU.js} +1 -1
- package/dist/client/assets/{regexp-i5_jUZAj.js → regexp-DxNPsA-x.js} +1 -1
- package/dist/client/assets/{requirementDiagram-4Y6WPE33-GVw3NOxE.js → requirementDiagram-4Y6WPE33-CrrnxwFz.js} +1 -1
- package/dist/client/assets/{review-export-B4TOUDUE.js → review-export-Bd6rUYIi.js} +1 -1
- package/dist/client/assets/{rst-BZWuei_6.js → rst-2Xzw7kAb.js} +1 -1
- package/dist/client/assets/{ruby-CApICFTD.js → ruby-tZt1Nxb8.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-5OEKKPKP-CwWzwmqj.js → sankeyDiagram-5OEKKPKP-ihur8vgn.js} +1 -1
- package/dist/client/assets/{sas-BzEPX6GL.js → sas-DjpUVtXs.js} +1 -1
- package/dist/client/assets/{scss-B6Ld2NRm.js → scss-CZffX3V1.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-3UESZ5HK-Bz_Q76Kt.js → sequenceDiagram-3UESZ5HK-Bg7fvZIu.js} +1 -1
- package/dist/client/assets/{shellscript-KmoqGVVu.js → shellscript-B7bmiOyR.js} +1 -1
- package/dist/client/assets/{shellsession-CsSh_KTo.js → shellsession-CS7D1mSi.js} +1 -1
- package/dist/client/assets/{soy-CLgOu1If.js → soy-B9Nii6ks.js} +1 -1
- package/dist/client/assets/{sql-BdCh56kU.js → sql-CzQPwj1z.js} +1 -1
- package/dist/client/assets/{src-D7QQkGEc.js → src-DNsvZq9f.js} +1 -1
- package/dist/client/assets/{stata-C3fo8EYS.js → stata-BjQgQlmT.js} +1 -1
- package/dist/client/assets/{stateDiagram-AJRCARHV-D0pZtzLu.js → stateDiagram-AJRCARHV-DsgTVCaj.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-CwRm1eh7.js +1 -0
- package/dist/client/assets/{surrealql-qzihsJw_.js → surrealql-D6DnLnn1.js} +1 -1
- package/dist/client/assets/{svelte-B4tbn_KI.js → svelte-DRgP3jXp.js} +1 -1
- package/dist/client/assets/{templ-Ddev3BvY.js → templ-Cwgx1vj-.js} +1 -1
- package/dist/client/assets/{tex-DJLtgNQ6.js → tex-RzUmM9ei.js} +1 -1
- package/dist/client/assets/{timeline-definition-PNZ67QCA-CWTWgYi0.js → timeline-definition-PNZ67QCA-rG2Mo1Zq.js} +1 -1
- package/dist/client/assets/{ts-tags-qqxigRtr.js → ts-tags-gdlLe8LD.js} +1 -1
- package/dist/client/assets/{tsx-Pkf9BaPv.js → tsx-C3y6O1l0.js} +1 -1
- package/dist/client/assets/{twig-BiScb10p.js → twig-DLMzUdS6.js} +1 -1
- package/dist/client/assets/{typescript-Bhy3UXig.js → typescript-T8PJwqaO.js} +1 -1
- package/dist/client/assets/{vennDiagram-CIIHVFJN-DwB89v9I.js → vennDiagram-CIIHVFJN-B-eDjTJG.js} +1 -1
- package/dist/client/assets/{vue-CANMWBRv.js → vue-BMIaruOV.js} +1 -1
- package/dist/client/assets/{vue-html-DtS6f62r.js → vue-html-D4e4SuHW.js} +1 -1
- package/dist/client/assets/{vue-vine-BpQ9kwSB.js → vue-vine-DU2nprLA.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-YWT4CUSO-DNwwPk4s.js → wardleyDiagram-YWT4CUSO-BkcHoefB.js} +1 -1
- package/dist/client/assets/{xml-CD5eIXsm.js → xml-DD7circ2.js} +1 -1
- package/dist/client/assets/{xsl-DGNZQAUu.js → xsl-Bu-TQ7Ag.js} +1 -1
- package/dist/client/assets/{xychartDiagram-2RQKCTM6-L7M4YSvw.js → xychartDiagram-2RQKCTM6-BGa1-yRO.js} +1 -1
- package/dist/client/assets/{yaml-Cm8mwIB7.js → yaml-C12ZIXNt.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/completions-C0ERX2wC.mjs +2 -0
- package/dist/design-system-types-QR9xS7o3.mjs +2 -0
- package/dist/design-system-types-uiP9W2uj.mjs +75 -0
- package/dist/{doctor-BxTaLqAF.mjs → doctor-Dg61wsBc.mjs} +6 -6
- package/dist/{doctor-BdDB6p27.mjs → doctor-Y8l1LEDM.mjs} +1 -1
- package/dist/{github-CToLsvPu.mjs → github-BtABlwOZ.mjs} +3 -3
- package/dist/{github--rpPZ3vK.mjs → github-BuBcy-co.mjs} +1 -1
- package/dist/{github-attachments-DEvAeo5P.mjs → github-attachments-Bwr25ItV.mjs} +1 -1
- package/dist/{mcp-DoNBucix.mjs → mcp-45VPdWIr.mjs} +136 -17
- package/dist/{mockup-format-D4Ln0WxJ.mjs → mockup-lint-BRjhxXSw.mjs} +160 -7
- 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/{review-export-DoST2oPt.mjs → review-export-BXCeRNjk.mjs} +1 -1
- package/dist/{server-BRQdb64n.mjs → server-CH-UPGFR.mjs} +1145 -127
- package/dist/{server-lock-CdaUNZyX.mjs → server-lock-ACw2cKDI.mjs} +22 -5
- package/dist/{session-conflict-BVgyyerQ.mjs → session-conflict-oUPEv3YT.mjs} +3 -3
- package/dist/{session-manager-CUqF8hkP.mjs → session-manager-C9KjVkzq.mjs} +2 -2
- package/dist/{session-url-B9FOnF3F.mjs → session-url-CyBpcLAH.mjs} +1 -1
- package/dist/{settings-DkPDB_hS.mjs → settings-DIa-3C8o.mjs} +1 -1
- package/dist/{setup-BwWZ9Fzq.mjs → setup-B6bOeWQl.mjs} +6 -6
- package/dist/{setup-first-run-i1o7DBki.mjs → setup-first-run-CAjtqBal.mjs} +2 -2
- package/dist/{setup-first-run-DyT0PlOZ.mjs → setup-first-run-DPXLAMqa.mjs} +1 -1
- package/extensions/pi/index.ts +128 -60
- package/extensions/pi/skill-heal.ts +73 -0
- package/extensions/pi/tsconfig.json +2 -1
- package/package.json +1 -1
- package/dist/client/assets/channel-C9URWRe4.js +0 -1
- package/dist/client/assets/chunk-QZHKN3VN-BBNO2-yv.js +0 -1
- package/dist/client/assets/chunk-WU5MYG2G-HP2Om5f9.js +0 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-BW_ZPHe7.js +0 -1
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-DOd628kk.js +0 -1
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-P0vTqsyH.js +0 -1
- package/dist/completions-CYa5usLb.mjs +0 -2
- /package/dist/{apply-suggestion-BsR_8FXW.mjs → apply-suggestion-tLsWREyb.mjs} +0 -0
- /package/dist/{comment-format-D4mCqr7T.mjs → comment-format-DS1wOWj_.mjs} +0 -0
- /package/dist/{completions-2aHVTmiJ.mjs → completions-ClqvbDYF.mjs} +0 -0
- /package/dist/{diff-fingerprint-BL5jNHnP.mjs → diff-fingerprint-PnC8Fs1-.mjs} +0 -0
- /package/dist/{find-tui-binary-DGspwyvd.mjs → find-tui-binary-DvADkBkP.mjs} +0 -0
- /package/dist/{handoff-DcShCxWJ.mjs → handoff-B85WLpcN.mjs} +0 -0
- /package/dist/{terminal-BroplOnw.mjs → terminal-Ce7OL1A-.mjs} +0 -0
- /package/dist/{tui-search-bridge-fFKqX4Fi.mjs → tui-search-bridge-N33QmB0q.mjs} +0 -0
- /package/dist/{update-check-ISaw61qS.mjs → update-check-D0yDl7sZ.mjs} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { f as getProjectStorageDir, h as getRepoRoot } from "./git-BGj31GX-.mjs";
|
|
2
2
|
import { spawnSync } from "node:child_process";
|
|
3
|
-
import { randomBytes, randomUUID } from "node:crypto";
|
|
3
|
+
import { randomBytes, randomUUID, timingSafeEqual } from "node:crypto";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { chmodSync, existsSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, rmdirSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
|
6
6
|
import { getCookie } from "hono/cookie";
|
|
@@ -12,7 +12,7 @@ import { getCookie } from "hono/cookie";
|
|
|
12
12
|
* is safe to bundle into the browser UI. Server-only helpers live in
|
|
13
13
|
* `server-auth.ts` and re-export these values for existing Node importers.
|
|
14
14
|
*/
|
|
15
|
-
/** Header, HttpOnly cookie, or
|
|
15
|
+
/** Header, HttpOnly cookie, or SSE query param carrying the per-session review API token. */
|
|
16
16
|
const SESSION_TOKEN_HEADER = "x-diffing-token";
|
|
17
17
|
const SESSION_TOKEN_QUERY = "token";
|
|
18
18
|
const SESSION_TOKEN_COOKIE = "diffing-token";
|
|
@@ -52,12 +52,29 @@ function isAllowedRequestHost(hostHeader, bindHost) {
|
|
|
52
52
|
if (!host) return true;
|
|
53
53
|
return isLoopbackHost(host);
|
|
54
54
|
}
|
|
55
|
-
|
|
55
|
+
/**
|
|
56
|
+
* Read the session token from the header or HttpOnly cookie.
|
|
57
|
+
*
|
|
58
|
+
* The query param is only honored when `allowQuery` is set, which is reserved
|
|
59
|
+
* for the SSE `/api/live` endpoint (`EventSource` cannot send headers). Tokens
|
|
60
|
+
* in URLs leak into history, referrers, and logs, so every other API route
|
|
61
|
+
* requires the header or cookie.
|
|
62
|
+
*/
|
|
63
|
+
function readSessionToken(c, opts) {
|
|
56
64
|
const header = c.req.header(SESSION_TOKEN_HEADER);
|
|
57
65
|
if (header) return header;
|
|
58
66
|
const cookie = getCookie(c, SESSION_TOKEN_COOKIE);
|
|
59
67
|
if (cookie) return cookie;
|
|
60
|
-
return c.req.query("token") || null;
|
|
68
|
+
if (opts?.allowQuery) return c.req.query("token") || null;
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
/** Constant-time comparison of a provided token against the expected session token. */
|
|
72
|
+
function tokenMatches(provided, expected) {
|
|
73
|
+
if (!provided) return false;
|
|
74
|
+
const providedBuf = Buffer.from(provided);
|
|
75
|
+
const expectedBuf = Buffer.from(expected);
|
|
76
|
+
if (providedBuf.length !== expectedBuf.length) return false;
|
|
77
|
+
return timingSafeEqual(providedBuf, expectedBuf);
|
|
61
78
|
}
|
|
62
79
|
/** `Set-Cookie` value for the review session token (loopback http — no Secure). */
|
|
63
80
|
function buildSessionTokenSetCookieValue(token) {
|
|
@@ -82,7 +99,7 @@ function createServerAuthMiddleware(config) {
|
|
|
82
99
|
}
|
|
83
100
|
if (!isAllowedRequestHost(c.req.header("host"), config.bindHost)) return c.json({ error: "request Host header is not allowed for this bind address" }, 403);
|
|
84
101
|
if (!config.insecureNoAuth && config.authToken) {
|
|
85
|
-
if (readSessionToken(c)
|
|
102
|
+
if (!tokenMatches(readSessionToken(c, { allowQuery: c.req.path === "/api/live" }), config.authToken)) return c.json({ error: "invalid or missing review session token" }, 401);
|
|
86
103
|
}
|
|
87
104
|
await next();
|
|
88
105
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { i as loadSettings } from "./settings-
|
|
2
|
-
import { l as removeServerSession, m as probeLockServerSync } from "./server-lock-
|
|
3
|
-
import { i as reviewSessionUrl } from "./session-url-
|
|
1
|
+
import { i as loadSettings } from "./settings-DIa-3C8o.mjs";
|
|
2
|
+
import { l as removeServerSession, m as probeLockServerSync } from "./server-lock-ACw2cKDI.mjs";
|
|
3
|
+
import { i as reviewSessionUrl } from "./session-url-CyBpcLAH.mjs";
|
|
4
4
|
//#region src/lib/session-conflict.ts
|
|
5
5
|
function sleepMs(ms) {
|
|
6
6
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as listServerLocks, d as sameServerSession, f as serverSessionId, n as activateServerLock, u as resolveActiveServerLock } from "./server-lock-
|
|
2
|
-
import { n as openExistingSession, r as stopLockOwner, t as existingSessionUrl } from "./session-conflict-
|
|
1
|
+
import { a as listServerLocks, d as sameServerSession, f as serverSessionId, n as activateServerLock, u as resolveActiveServerLock } from "./server-lock-ACw2cKDI.mjs";
|
|
2
|
+
import { n as openExistingSession, r as stopLockOwner, t as existingSessionUrl } from "./session-conflict-oUPEv3YT.mjs";
|
|
3
3
|
//#region src/lib/session-manager.ts
|
|
4
4
|
const EXIT_OK = 0;
|
|
5
5
|
const EXIT_NOT_FOUND = 4;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { S as SESSION_TOKEN_QUERY, y as isLoopbackHost } from "./server-lock-
|
|
1
|
+
import { S as SESSION_TOKEN_QUERY, y as isLoopbackHost } from "./server-lock-ACw2cKDI.mjs";
|
|
2
2
|
//#region src/lib/session-url.ts
|
|
3
3
|
/** Loopback-safe review URL for web / gh-pr locks; null for TUI or invalid ports. */
|
|
4
4
|
function reviewSessionBaseUrl(lock) {
|
|
@@ -85,4 +85,4 @@ function resetSetupCompleted() {
|
|
|
85
85
|
return saveSettings({ setupCompletedAt: null });
|
|
86
86
|
}
|
|
87
87
|
//#endregion
|
|
88
|
-
export { markSetupCompleted as a, loadSettings as i, formatModeLabel as n, resetSetupCompleted as o, isSetupCompleted as r, saveSettings as s, ensureConfigDir as t };
|
|
88
|
+
export { markSetupCompleted as a, writeJsonAtomically as c, loadSettings as i, formatModeLabel as n, resetSetupCompleted as o, isSetupCompleted as r, saveSettings as s, ensureConfigDir as t };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { S as isGitRepo, h as getRepoRoot } from "./git-BGj31GX-.mjs";
|
|
2
|
-
import { a as markSetupCompleted, i as loadSettings, n as formatModeLabel, o as resetSetupCompleted, r as isSetupCompleted, s as saveSettings, t as ensureConfigDir } from "./settings-
|
|
3
|
-
import { n as completionFor } from "./completions-
|
|
4
|
-
import { a as hintLine, c as stepHeader, i as dim, l as tone, n as box, o as isColorEnabled, r as copyBlock, s as rule, t as bold } from "./terminal-
|
|
5
|
-
import { n as runDoctor, t as formatDoctorReport } from "./doctor-
|
|
6
|
-
import { t as DOCS_GETTING_STARTED_URL } from "./setup-first-run-
|
|
2
|
+
import { a as markSetupCompleted, i as loadSettings, n as formatModeLabel, o as resetSetupCompleted, r as isSetupCompleted, s as saveSettings, t as ensureConfigDir } from "./settings-DIa-3C8o.mjs";
|
|
3
|
+
import { n as completionFor } from "./completions-ClqvbDYF.mjs";
|
|
4
|
+
import { a as hintLine, c as stepHeader, i as dim, l as tone, n as box, o as isColorEnabled, r as copyBlock, s as rule, t as bold } from "./terminal-Ce7OL1A-.mjs";
|
|
5
|
+
import { n as runDoctor, t as formatDoctorReport } from "./doctor-Dg61wsBc.mjs";
|
|
6
|
+
import { t as DOCS_GETTING_STARTED_URL } from "./setup-first-run-CAjtqBal.mjs";
|
|
7
7
|
import { execFileSync, spawn } from "node:child_process";
|
|
8
8
|
import { fileURLToPath } from "node:url";
|
|
9
9
|
import { dirname, join, resolve } from "node:path";
|
|
@@ -425,7 +425,7 @@ function printDoneChecklist(inGitRepo, cwd, color) {
|
|
|
425
425
|
], { color }));
|
|
426
426
|
}
|
|
427
427
|
async function handleFirstRunGate(options) {
|
|
428
|
-
const { shouldOfferFirstRunSetup, promptFirstRunSetup, DOCS_GETTING_STARTED_URL } = await import("./setup-first-run-
|
|
428
|
+
const { shouldOfferFirstRunSetup, promptFirstRunSetup, DOCS_GETTING_STARTED_URL } = await import("./setup-first-run-DPXLAMqa.mjs");
|
|
429
429
|
if (!shouldOfferFirstRunSetup({ skipSetup: options.skipSetup })) return;
|
|
430
430
|
while (true) {
|
|
431
431
|
const choice = await promptFirstRunSetup();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { r as isSetupCompleted } from "./settings-
|
|
2
|
-
import { a as hintLine, i as dim, n as box, o as isColorEnabled } from "./terminal-
|
|
1
|
+
import { r as isSetupCompleted } from "./settings-DIa-3C8o.mjs";
|
|
2
|
+
import { a as hintLine, i as dim, n as box, o as isColorEnabled } from "./terminal-Ce7OL1A-.mjs";
|
|
3
3
|
import { stdin, stdout } from "node:process";
|
|
4
4
|
import { createInterface } from "node:readline/promises";
|
|
5
5
|
//#region src/lib/setup-first-run.ts
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as shouldOfferFirstRunSetup, i as promptFirstRunSetup, t as DOCS_GETTING_STARTED_URL } from "./setup-first-run-
|
|
1
|
+
import { a as shouldOfferFirstRunSetup, i as promptFirstRunSetup, t as DOCS_GETTING_STARTED_URL } from "./setup-first-run-CAjtqBal.mjs";
|
|
2
2
|
export { DOCS_GETTING_STARTED_URL, promptFirstRunSetup, shouldOfferFirstRunSetup };
|
package/extensions/pi/index.ts
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Bridges the local-first diffing review loop into pi:
|
|
5
5
|
* - Structured LLM tools mirroring the diffing MCP surface (status, review
|
|
6
|
-
* start, comments, reply/resolve, plan loop, mockup loop,
|
|
7
|
-
* sessions, GH PR).
|
|
6
|
+
* start, comments, reply/resolve, plan loop, mockup loop, design system,
|
|
7
|
+
* progress, sessions, GH PR).
|
|
8
8
|
* - `/diffing` command to open/reuse the review UI for the current repo.
|
|
9
9
|
* - Footer status showing the active review session.
|
|
10
10
|
* - Skill self-heal: keeps `~/.agents/skills/diffing*` as symlinks to the
|
|
@@ -20,12 +20,9 @@
|
|
|
20
20
|
import { spawn } from "node:child_process";
|
|
21
21
|
import {
|
|
22
22
|
existsSync,
|
|
23
|
-
lstatSync,
|
|
24
23
|
mkdtempSync,
|
|
25
24
|
readFileSync,
|
|
26
|
-
realpathSync,
|
|
27
25
|
rmSync,
|
|
28
|
-
symlinkSync,
|
|
29
26
|
writeFileSync,
|
|
30
27
|
} from "node:fs";
|
|
31
28
|
import { homedir, tmpdir } from "node:os";
|
|
@@ -37,29 +34,19 @@ import type {
|
|
|
37
34
|
ExtensionContext,
|
|
38
35
|
} from "@earendil-works/pi-coding-agent";
|
|
39
36
|
import { Type } from "typebox";
|
|
37
|
+
import {
|
|
38
|
+
selfHealSkillLinks,
|
|
39
|
+
SKILLS_REL,
|
|
40
|
+
} from "./skill-heal.ts";
|
|
40
41
|
|
|
41
42
|
// ────────────────────────────────────────────────────────────────────────────
|
|
42
43
|
// Constants
|
|
43
44
|
// ────────────────────────────────────────────────────────────────────────────
|
|
44
45
|
|
|
45
|
-
const SKILL_NAMES = [
|
|
46
|
-
"diffing",
|
|
47
|
-
"diffing-finish-review",
|
|
48
|
-
"diffing-mockup-review",
|
|
49
|
-
"diffing-plan-review",
|
|
50
|
-
"diffing-pr-address",
|
|
51
|
-
"diffing-pr-read",
|
|
52
|
-
"diffing-release",
|
|
53
|
-
"diffing-review",
|
|
54
|
-
"diffing-start-review",
|
|
55
|
-
] as const;
|
|
56
|
-
|
|
57
46
|
const MAX_OUTPUT_BYTES = 48 * 1024;
|
|
58
47
|
const REVIEW_START_TIMEOUT_MS = 15_000;
|
|
59
48
|
const REVIEW_START_POLL_MS = 400;
|
|
60
49
|
|
|
61
|
-
const SKILLS_REL = join(".agents", "skills");
|
|
62
|
-
|
|
63
50
|
// ────────────────────────────────────────────────────────────────────────────
|
|
64
51
|
// CLI runner
|
|
65
52
|
// ────────────────────────────────────────────────────────────────────────────
|
|
@@ -247,35 +234,6 @@ function findCanonicalRoot(cwd: string): string | null {
|
|
|
247
234
|
return null;
|
|
248
235
|
}
|
|
249
236
|
|
|
250
|
-
/**
|
|
251
|
-
* Keep the `~/.agents/skills/diffing*` entries as symlinks to the canonical
|
|
252
|
-
* checkout's `.agents/skills`. pi dedupes skills by canonical realpath, so
|
|
253
|
-
* symlinked home entries merge silently with the repo's project skills and no
|
|
254
|
-
* `[Skill conflicts]` banner appears. Repairs stale real copies left behind by
|
|
255
|
-
* `diffing setup skills` / `npx skills add --copy`. Only touches the known
|
|
256
|
-
* names in SKILL_NAMES; never deletes anything else.
|
|
257
|
-
*/
|
|
258
|
-
function selfHealSkillLinks(canonical: string): void {
|
|
259
|
-
const homeSkills = join(homedir(), ".agents", "skills");
|
|
260
|
-
if (!existsSync(homeSkills)) return;
|
|
261
|
-
for (const name of SKILL_NAMES) {
|
|
262
|
-
const target = join(canonical, SKILLS_REL, name);
|
|
263
|
-
if (!existsSync(target)) continue;
|
|
264
|
-
const link = join(homeSkills, name);
|
|
265
|
-
try {
|
|
266
|
-
if (existsSync(link) || lstatSync(link)) {
|
|
267
|
-
if (lstatSync(link).isSymbolicLink()) {
|
|
268
|
-
const real = realpathSync(link);
|
|
269
|
-
if (real === realpathSync(target)) continue; // already correct
|
|
270
|
-
}
|
|
271
|
-
rmSync(link, { recursive: true, force: true });
|
|
272
|
-
}
|
|
273
|
-
symlinkSync(target, link, "dir");
|
|
274
|
-
} catch {
|
|
275
|
-
// best-effort; a failed heal must not break the session
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
237
|
|
|
280
238
|
// ────────────────────────────────────────────────────────────────────────────
|
|
281
239
|
// Detached review server start
|
|
@@ -339,7 +297,9 @@ export default function (pi: ExtensionAPI) {
|
|
|
339
297
|
// Keep the home skill links canonical for every session (idempotent).
|
|
340
298
|
pi.on("session_start", async (_event, ctx) => {
|
|
341
299
|
const canonical = findCanonicalRoot(ctx.cwd);
|
|
342
|
-
if (canonical)
|
|
300
|
+
if (canonical) {
|
|
301
|
+
selfHealSkillLinks(canonical, join(homedir(), ".agents", "skills"));
|
|
302
|
+
}
|
|
343
303
|
await refreshStatus(ctx);
|
|
344
304
|
});
|
|
345
305
|
|
|
@@ -824,7 +784,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
824
784
|
name: "diffing_mockup_submit",
|
|
825
785
|
label: "Diffing Mockup Submit",
|
|
826
786
|
description:
|
|
827
|
-
"Submit HTML mockup screen(s) for visual review.
|
|
787
|
+
"Submit HTML mockup screen(s) for visual review. HARD RULE — one state per screen: never tabs/accordions/toggles/modals/JS swaps. Pass html, a file/dir already under ~/.diffing/…/mockup-sources/, or screens [{id, html}]. Call diffing_design show first. Share the URL and park unless asked to wait. Resubmit with mockupId to bump the version. Fix any in-page-state or generic-style hints before parking.",
|
|
828
788
|
parameters: Type.Object({
|
|
829
789
|
html: Type.Optional(
|
|
830
790
|
Type.String({ description: "Single-screen HTML body." }),
|
|
@@ -853,6 +813,23 @@ export default function (pi: ExtensionAPI) {
|
|
|
853
813
|
),
|
|
854
814
|
model: Type.Optional(Type.String()),
|
|
855
815
|
source: Type.Optional(Type.String()),
|
|
816
|
+
mode: Type.Optional(
|
|
817
|
+
StringEnum(["fragment", "document"] as const, {
|
|
818
|
+
description:
|
|
819
|
+
"fragment = body contents wrapped by the published design-system shell. document = full HTML, no wrap. Default: server default.",
|
|
820
|
+
}),
|
|
821
|
+
),
|
|
822
|
+
designSystem: Type.Optional(
|
|
823
|
+
Type.String({
|
|
824
|
+
description:
|
|
825
|
+
"Design-system id to bind (default system if omitted).",
|
|
826
|
+
}),
|
|
827
|
+
),
|
|
828
|
+
planId: Type.Optional(
|
|
829
|
+
Type.String({
|
|
830
|
+
description: "Optional plan id this mockup illustrates.",
|
|
831
|
+
}),
|
|
832
|
+
),
|
|
856
833
|
}),
|
|
857
834
|
async execute(_id, params, _signal, _onUpdate, ctx) {
|
|
858
835
|
const args = ["mockup", "submit"];
|
|
@@ -895,6 +872,9 @@ export default function (pi: ExtensionAPI) {
|
|
|
895
872
|
if (params.mockupId) args.push("--id", params.mockupId);
|
|
896
873
|
if (params.model) args.push("--model", params.model);
|
|
897
874
|
if (params.source) args.push("--source", params.source);
|
|
875
|
+
if (params.mode) args.push("--mode", params.mode);
|
|
876
|
+
if (params.designSystem) args.push("--system", params.designSystem);
|
|
877
|
+
if (params.planId) args.push("--plan-id", params.planId);
|
|
898
878
|
try {
|
|
899
879
|
const result = await runDiffing(args, ctx.cwd, { stdin });
|
|
900
880
|
const stdout = result.stdout.trim();
|
|
@@ -1078,12 +1058,15 @@ export default function (pi: ExtensionAPI) {
|
|
|
1078
1058
|
name: "diffing_mockup_inspect",
|
|
1079
1059
|
label: "Diffing Mockup Inspect",
|
|
1080
1060
|
description:
|
|
1081
|
-
"Read compact, bounded mockup data without transferring screen HTML. view=summary (headline stats), comments (paged comment list), comment (one thread), screen (screen source). Filter by comment scope: status, screenId, viewport (desktop|tablet|mobile), version. context=none|anchor|source controls anchor detail. Prefer this over diffing_mockup_show.",
|
|
1061
|
+
"Read compact, bounded mockup data without transferring screen HTML. view=summary (headline stats), comments (paged comment list), comment (one thread), screen (screen source), preview (rendered preview metadata). Filter by comment scope: status, screenId, viewport (desktop|tablet|mobile), version. context=none|anchor|source controls anchor detail. Prefer this over diffing_mockup_show.",
|
|
1082
1062
|
parameters: Type.Object({
|
|
1083
|
-
view: StringEnum(
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1063
|
+
view: StringEnum(
|
|
1064
|
+
["summary", "comments", "comment", "screen", "preview"] as const,
|
|
1065
|
+
{
|
|
1066
|
+
description: "What to read. Default: summary.",
|
|
1067
|
+
default: "summary",
|
|
1068
|
+
},
|
|
1069
|
+
),
|
|
1087
1070
|
mockupId: Type.Optional(
|
|
1088
1071
|
Type.String({ description: "Mockup id. Default: latest." }),
|
|
1089
1072
|
),
|
|
@@ -1151,11 +1134,12 @@ export default function (pi: ExtensionAPI) {
|
|
|
1151
1134
|
name: "diffing_mockup_screen",
|
|
1152
1135
|
label: "Diffing Mockup Screen",
|
|
1153
1136
|
description:
|
|
1154
|
-
"One-screen revision of an HTML mockup. action=upsert adds/replaces a screen (html or file), remove deletes a screen, patch replaces the first exact occurrence of text with replacement. Every success bumps the mockup version; pass expectedVersion to guard racing edits (409 version-mismatch, nothing applied). For multi-screen revisions, resubmit via diffing_mockup_submit with the same mockupId.",
|
|
1137
|
+
"One-screen revision of an HTML mockup. action=upsert adds/replaces a screen (html or file), remove deletes a screen, patch replaces the first exact occurrence of text with replacement, replace-region replaces the inner HTML of the first [data-diffing=region] element (prefer this when the comment has a data-diffing target). Every success bumps the mockup version; pass expectedVersion to guard racing edits (409 version-mismatch, nothing applied). For multi-screen revisions, resubmit via diffing_mockup_submit with the same mockupId.",
|
|
1155
1138
|
parameters: Type.Object({
|
|
1156
|
-
action: StringEnum(
|
|
1157
|
-
|
|
1158
|
-
|
|
1139
|
+
action: StringEnum(
|
|
1140
|
+
["upsert", "remove", "patch", "replace-region"] as const,
|
|
1141
|
+
{ description: "Revision op." },
|
|
1142
|
+
),
|
|
1159
1143
|
mockupId: Type.String({ description: "Mockup id." }),
|
|
1160
1144
|
screenId: Type.String({ description: "Screen id." }),
|
|
1161
1145
|
html: Type.Optional(
|
|
@@ -1176,8 +1160,17 @@ export default function (pi: ExtensionAPI) {
|
|
|
1176
1160
|
description: "For patch: exact text to replace (first occurrence).",
|
|
1177
1161
|
}),
|
|
1178
1162
|
),
|
|
1163
|
+
region: Type.Optional(
|
|
1164
|
+
Type.String({
|
|
1165
|
+
description:
|
|
1166
|
+
"For replace-region: data-diffing attribute value of the block to replace.",
|
|
1167
|
+
}),
|
|
1168
|
+
),
|
|
1179
1169
|
replacement: Type.Optional(
|
|
1180
|
-
Type.String({
|
|
1170
|
+
Type.String({
|
|
1171
|
+
description:
|
|
1172
|
+
"For patch: replacement text. For replace-region: new inner HTML.",
|
|
1173
|
+
}),
|
|
1181
1174
|
),
|
|
1182
1175
|
expectedVersion: Type.Optional(
|
|
1183
1176
|
Type.Number({
|
|
@@ -1201,6 +1194,10 @@ export default function (pi: ExtensionAPI) {
|
|
|
1201
1194
|
stdin = params.html;
|
|
1202
1195
|
}
|
|
1203
1196
|
if (params.label) args.push("--label", params.label);
|
|
1197
|
+
} else if (params.action === "replace-region") {
|
|
1198
|
+
if (params.region) args.push("--region", params.region);
|
|
1199
|
+
if (params.replacement !== undefined)
|
|
1200
|
+
args.push("--replacement", params.replacement);
|
|
1204
1201
|
} else if (params.action === "patch") {
|
|
1205
1202
|
if (params.text !== undefined) args.push("--text", params.text);
|
|
1206
1203
|
if (params.replacement !== undefined)
|
|
@@ -1263,6 +1260,77 @@ export default function (pi: ExtensionAPI) {
|
|
|
1263
1260
|
},
|
|
1264
1261
|
});
|
|
1265
1262
|
|
|
1263
|
+
pi.registerTool({
|
|
1264
|
+
name: "diffing_mockup_handoff",
|
|
1265
|
+
label: "Diffing Mockup Handoff",
|
|
1266
|
+
description:
|
|
1267
|
+
"Compact implementation handoff after a mockup is approved: tokens, screens with intent, components used, leftover nits. Prefer this over dumping every screen's HTML. Call after decision=approved, before writing product UI.",
|
|
1268
|
+
parameters: Type.Object({
|
|
1269
|
+
mockupId: Type.Optional(
|
|
1270
|
+
Type.String({ description: "Mockup id. Default: latest." }),
|
|
1271
|
+
),
|
|
1272
|
+
json: Type.Optional(
|
|
1273
|
+
Type.Boolean({ description: "Emit raw JSON. Default: XML handoff." }),
|
|
1274
|
+
),
|
|
1275
|
+
}),
|
|
1276
|
+
async execute(_id, params, _signal, _onUpdate, ctx) {
|
|
1277
|
+
const args = ["mockup", "handoff"];
|
|
1278
|
+
if (params.mockupId) args.push(params.mockupId);
|
|
1279
|
+
if (params.json) args.push("--json");
|
|
1280
|
+
const result = await runDiffing(args, ctx.cwd);
|
|
1281
|
+
return textResult(describe(result, "diffing mockup handoff"), {
|
|
1282
|
+
exitCode: result.exitCode,
|
|
1283
|
+
stderr: result.stderr.trim() || undefined,
|
|
1284
|
+
});
|
|
1285
|
+
},
|
|
1286
|
+
});
|
|
1287
|
+
|
|
1288
|
+
pi.registerTool({
|
|
1289
|
+
name: "diffing_design",
|
|
1290
|
+
label: "Diffing Design System",
|
|
1291
|
+
description:
|
|
1292
|
+
"Per-repo design system used before authoring mockup HTML. show/list: read tokens, guidelines, components. extract: scan the consumer repo and write a draft (does not publish). propose: update the draft. publish: human action only — do not publish unless the human asked. Omit id for the default system.",
|
|
1293
|
+
parameters: Type.Object({
|
|
1294
|
+
action: StringEnum(
|
|
1295
|
+
["show", "list", "extract", "propose", "publish"] as const,
|
|
1296
|
+
{ description: "Design-system op. Default: show." },
|
|
1297
|
+
),
|
|
1298
|
+
id: Type.Optional(
|
|
1299
|
+
Type.String({ description: "System id. Default: default." }),
|
|
1300
|
+
),
|
|
1301
|
+
json: Type.Optional(
|
|
1302
|
+
Type.Boolean({ description: "Emit raw JSON. Default: false." }),
|
|
1303
|
+
),
|
|
1304
|
+
from: Type.Optional(
|
|
1305
|
+
StringEnum(["css", "text"] as const, {
|
|
1306
|
+
description: "For extract: scan source. Default: css.",
|
|
1307
|
+
}),
|
|
1308
|
+
),
|
|
1309
|
+
title: Type.Optional(
|
|
1310
|
+
Type.String({ description: "For extract/propose: system title." }),
|
|
1311
|
+
),
|
|
1312
|
+
guidelines: Type.Optional(
|
|
1313
|
+
Type.String({
|
|
1314
|
+
description: "For propose: markdown guidelines to write on the draft.",
|
|
1315
|
+
}),
|
|
1316
|
+
),
|
|
1317
|
+
}),
|
|
1318
|
+
async execute(_id, params, _signal, _onUpdate, ctx) {
|
|
1319
|
+
const action = params.action ?? "show";
|
|
1320
|
+
const args = ["design", action];
|
|
1321
|
+
if (params.id) args.push(params.id);
|
|
1322
|
+
if (params.json) args.push("--json");
|
|
1323
|
+
if (params.from) args.push("--from", params.from);
|
|
1324
|
+
if (params.title) args.push("--title", params.title);
|
|
1325
|
+
if (params.guidelines) args.push("--guidelines", params.guidelines);
|
|
1326
|
+
const result = await runDiffing(args, ctx.cwd);
|
|
1327
|
+
return textResult(describe(result, `diffing design ${action}`), {
|
|
1328
|
+
exitCode: result.exitCode,
|
|
1329
|
+
stderr: result.stderr.trim() || undefined,
|
|
1330
|
+
});
|
|
1331
|
+
},
|
|
1332
|
+
});
|
|
1333
|
+
|
|
1266
1334
|
pi.registerTool({
|
|
1267
1335
|
name: "diffing_url",
|
|
1268
1336
|
label: "Diffing URL",
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import {
|
|
2
|
+
existsSync,
|
|
3
|
+
lstatSync,
|
|
4
|
+
realpathSync,
|
|
5
|
+
rmSync,
|
|
6
|
+
symlinkSync,
|
|
7
|
+
} from "node:fs";
|
|
8
|
+
import { join } from "node:path";
|
|
9
|
+
|
|
10
|
+
export const DIFFING_SKILL_NAMES = [
|
|
11
|
+
"diffing",
|
|
12
|
+
"diffing-finish-review",
|
|
13
|
+
"diffing-mockup-author",
|
|
14
|
+
"diffing-mockup-review",
|
|
15
|
+
"diffing-plan-review",
|
|
16
|
+
"diffing-pr-address",
|
|
17
|
+
"diffing-pr-read",
|
|
18
|
+
"diffing-release",
|
|
19
|
+
"diffing-review",
|
|
20
|
+
"diffing-start-review",
|
|
21
|
+
] as const;
|
|
22
|
+
|
|
23
|
+
export const SKILLS_REL = join(".agents", "skills");
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Point `link` at `target`. Creates a missing link, repairs a stale/dangling
|
|
27
|
+
* one, and leaves a correct symlink alone. `existsSync` is false for both
|
|
28
|
+
* missing paths and dangling symlinks, so this uses `lstat` and treats ENOENT
|
|
29
|
+
* as "create".
|
|
30
|
+
*/
|
|
31
|
+
export function healSkillLink(
|
|
32
|
+
link: string,
|
|
33
|
+
target: string,
|
|
34
|
+
): "ok" | "created" | "repaired" {
|
|
35
|
+
if (!existsSync(target)) return "ok";
|
|
36
|
+
let st: ReturnType<typeof lstatSync> | null = null;
|
|
37
|
+
try {
|
|
38
|
+
st = lstatSync(link);
|
|
39
|
+
} catch {
|
|
40
|
+
st = null;
|
|
41
|
+
}
|
|
42
|
+
if (st) {
|
|
43
|
+
if (st.isSymbolicLink()) {
|
|
44
|
+
try {
|
|
45
|
+
if (realpathSync(link) === realpathSync(target)) return "ok";
|
|
46
|
+
} catch {
|
|
47
|
+
// dangling or unreadable — fall through and replace
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
rmSync(link, { recursive: true, force: true });
|
|
51
|
+
symlinkSync(target, link, "dir");
|
|
52
|
+
return "repaired";
|
|
53
|
+
}
|
|
54
|
+
symlinkSync(target, link, "dir");
|
|
55
|
+
return "created";
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Keep `~/.agents/skills/diffing*` as symlinks to the canonical checkout. */
|
|
59
|
+
export function selfHealSkillLinks(
|
|
60
|
+
canonical: string,
|
|
61
|
+
homeSkills: string,
|
|
62
|
+
): void {
|
|
63
|
+
if (!existsSync(homeSkills)) return;
|
|
64
|
+
for (const name of DIFFING_SKILL_NAMES) {
|
|
65
|
+
const target = join(canonical, SKILLS_REL, name);
|
|
66
|
+
if (!existsSync(target)) continue;
|
|
67
|
+
try {
|
|
68
|
+
healSkillLink(join(homeSkills, name), target);
|
|
69
|
+
} catch {
|
|
70
|
+
// best-effort; a failed heal must not break the session
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
"moduleResolution": "bundler",
|
|
6
6
|
"strict": true,
|
|
7
7
|
"noEmit": true,
|
|
8
|
+
"allowImportingTsExtensions": true,
|
|
8
9
|
"skipLibCheck": true,
|
|
9
10
|
"esModuleInterop": true,
|
|
10
11
|
"forceConsistentCasingInFileNames": true,
|
|
11
12
|
"types": ["node"]
|
|
12
13
|
},
|
|
13
|
-
"include": ["index.ts", "pi-modules.d.ts"]
|
|
14
|
+
"include": ["index.ts", "skill-heal.ts", "pi-modules.d.ts"]
|
|
14
15
|
}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{at as e,ot as t}from"./chunk-CSCIHK7Q-D6ZDvMsi.js";var n=(n,r)=>t.lang.round(e.parse(n)[r]);export{n as t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{h as e}from"./src-D7QQkGEc.js";var t=class{constructor(e){this.init=e,this.records=this.init()}static{e(this,`ImperativeState`)}reset(){this.records=this.init()}};export{t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{h as e,p as t}from"./src-D7QQkGEc.js";import{x as n}from"./chunk-CSCIHK7Q-D6ZDvMsi.js";var r=e(e=>{let{securityLevel:r}=n(),i=t(`body`);return r===`sandbox`&&(i=t((t(`#i${e}`).node()?.contentDocument??document).body)),i.select(`#${e}`)},`selectSvgElement`);export{r as t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{h as e}from"./src-D7QQkGEc.js";import"./chunk-CSCIHK7Q-D6ZDvMsi.js";import"./chunk-5ZQYHXKU-BGFzCgvs.js";import"./chunk-O5CBEL6O-DcKB07iP.js";import"./chunk-FMBD7UC4-BFDCYCqF.js";import"./chunk-BSJP7CBP-DAvnzgjY.js";import"./chunk-L5ZTLDWV-Dl9iUIBf.js";import"./chunk-ND2GUHAM-DBDu-JeD.js";import"./chunk-55IACEB6-pCwXbxR0.js";import"./chunk-2J33WTMH-Bpr3MqKf.js";import"./chunk-NZK2D7GU-CRyk4F3R.js";import"./chunk-3OPIFGDE-DdMV_3DM.js";import"./chunk-KSCS5N6A-BmD6XY52.js";import"./chunk-LZXEDZCA-rOOJDxdB.js";import{i as t,n,r,t as i}from"./chunk-727SXJPM-DU7oVWfJ.js";var a={parser:n,get db(){return new i},renderer:r,styles:t,init:e(e=>{e.class||={},e.class.arrowMarkerAbsolute=e.arrowMarkerAbsolute},`init`)};export{a as diagram};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{h as e}from"./src-D7QQkGEc.js";import"./chunk-CSCIHK7Q-D6ZDvMsi.js";import"./chunk-5ZQYHXKU-BGFzCgvs.js";import"./chunk-O5CBEL6O-DcKB07iP.js";import"./chunk-FMBD7UC4-BFDCYCqF.js";import"./chunk-BSJP7CBP-DAvnzgjY.js";import"./chunk-L5ZTLDWV-Dl9iUIBf.js";import"./chunk-ND2GUHAM-DBDu-JeD.js";import"./chunk-55IACEB6-pCwXbxR0.js";import"./chunk-2J33WTMH-Bpr3MqKf.js";import"./chunk-NZK2D7GU-CRyk4F3R.js";import"./chunk-3OPIFGDE-DdMV_3DM.js";import"./chunk-KSCS5N6A-BmD6XY52.js";import"./chunk-LZXEDZCA-rOOJDxdB.js";import{i as t,n,r,t as i}from"./chunk-727SXJPM-DU7oVWfJ.js";var a={parser:n,get db(){return new i},renderer:r,styles:t,init:e(e=>{e.class||={},e.class.arrowMarkerAbsolute=e.arrowMarkerAbsolute},`init`)};export{a as diagram};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{h as e}from"./src-D7QQkGEc.js";import"./chunk-CSCIHK7Q-D6ZDvMsi.js";import"./chunk-5ZQYHXKU-BGFzCgvs.js";import"./chunk-O5CBEL6O-DcKB07iP.js";import"./chunk-BSJP7CBP-DAvnzgjY.js";import"./chunk-L5ZTLDWV-Dl9iUIBf.js";import"./chunk-55IACEB6-pCwXbxR0.js";import"./chunk-2J33WTMH-Bpr3MqKf.js";import"./chunk-NZK2D7GU-CRyk4F3R.js";import"./chunk-3OPIFGDE-DdMV_3DM.js";import"./chunk-KSCS5N6A-BmD6XY52.js";import"./chunk-LZXEDZCA-rOOJDxdB.js";import{i as t,n,r,t as i}from"./chunk-AQP2D5EJ-DaVYG1qm.js";var a={parser:n,get db(){return new i(2)},renderer:r,styles:t,init:e(e=>{e.state||={},e.state.arrowMarkerAbsolute=e.arrowMarkerAbsolute},`init`)};export{a as diagram};
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|