@deepseek-insight/dsi 0.8.4 → 0.9.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/.agents/skills/glass-dsi/SKILL.md +195 -0
- package/.agents/skills/glass-dsi/references/cdp-verification.md +132 -0
- package/.agents/skills/glass-dsi/scripts/_connect.mjs +81 -0
- package/.agents/skills/glass-dsi/scripts/glass-url.mjs +48 -0
- package/.agents/skills/glass-dsi/scripts/glass.mjs +84 -0
- package/.agents/skills/glass-url/SKILL.md +117 -0
- package/.agents/skills/glass-url/scripts/_args.mjs +49 -0
- package/.agents/skills/glass-url/scripts/_connect.mjs +99 -0
- package/.agents/skills/glass-url/scripts/glass-url.mjs +114 -0
- package/bin/dsi.mjs +23 -74
- package/bin/lib/zai-patch.mjs +115 -0
- package/build/client/_app/immutable/assets/0.Ch5VtsKp.css +2 -0
- package/build/client/_app/immutable/assets/2.D0QOh44D.css +1 -0
- package/build/client/_app/immutable/chunks/{DwcY-69G.js → 02Wfo2G3.js} +1 -1
- package/build/client/_app/immutable/chunks/0Tfhif1V.js +3 -0
- package/build/client/_app/immutable/chunks/{GKkjunMm.js → 0ruuBBbh.js} +2 -2
- package/build/client/_app/immutable/chunks/{DUCaFYlx.js → 4bHE1npv.js} +1 -1
- package/build/client/_app/immutable/chunks/{4cwyag_I.js → B4hDUAJl.js} +1 -1
- package/build/client/_app/immutable/chunks/{Cr2ck_ss.js → BIPXB-2I.js} +1 -1
- package/build/client/_app/immutable/chunks/{CeLBjOd9.js → BIgv-kQR.js} +1 -1
- package/build/client/_app/immutable/chunks/BK6k1nBs.js +1 -0
- package/build/client/_app/immutable/chunks/{SN3Efo-Q.js → BKwmKcDY.js} +1 -1
- package/build/client/_app/immutable/chunks/{CRFuOqJI.js → BORjuqef.js} +1 -1
- package/build/client/_app/immutable/chunks/{CH_bR_0j.js → BPmZB0-N.js} +1 -1
- package/build/client/_app/immutable/chunks/BROtno1Y.js +1 -0
- package/build/client/_app/immutable/chunks/{DEVxi5CK.js → BT5Iel00.js} +1 -1
- package/build/client/_app/immutable/chunks/{DdI16loP.js → BX3y_1Hh.js} +1 -1
- package/build/client/_app/immutable/chunks/{DuiFyTVb.js → Bea1gxLq.js} +1 -1
- package/build/client/_app/immutable/chunks/{D0uxHECr.js → BpkpgvVw.js} +1 -1
- package/build/client/_app/immutable/chunks/{CB55Rp7-.js → BreZS7EW.js} +1 -1
- package/build/client/_app/immutable/chunks/{BmDADyfH.js → BsS_byzk.js} +1 -1
- package/build/client/_app/immutable/chunks/{BWRXzjmQ.js → Bslg-dr5.js} +1 -1
- package/build/client/_app/immutable/chunks/{BkYT72a1.js → C-YczRN1.js} +1 -1
- package/build/client/_app/immutable/chunks/{DBKMIEwD.js → C2aW4lzo.js} +1 -1
- package/build/client/_app/immutable/chunks/{C4gs6zoI.js → C2qFXaz5.js} +1 -1
- package/build/client/_app/immutable/chunks/{BBd0nTHG.js → C5RyRpOh.js} +1 -1
- package/build/client/_app/immutable/chunks/{DJQr4efH.js → C5iHDVU_.js} +1 -1
- package/build/client/_app/immutable/chunks/{B4F5liKq.js → C7opVlLF.js} +1 -1
- package/build/client/_app/immutable/chunks/{DIxy2USu.js → CAuEkmZ4.js} +1 -1
- package/build/client/_app/immutable/chunks/{BO99LSSA.js → CIkiqgtA.js} +1 -1
- package/build/client/_app/immutable/chunks/{Bpd0I3U7.js → CJesWaZn.js} +1 -1
- package/build/client/_app/immutable/chunks/{at6PQqQ4.js → CRsoS5Y9.js} +1 -1
- package/build/client/_app/immutable/chunks/CTWtsoJD.js +6 -0
- package/build/client/_app/immutable/chunks/CWk5gmU2.js +1 -0
- package/build/client/_app/immutable/chunks/{lF8CNVOA.js → CXkrluSK.js} +1 -1
- package/build/client/_app/immutable/chunks/{DmRY6FWm.js → C_8kFZ_X.js} +4 -4
- package/build/client/_app/immutable/chunks/{D6KenyiF.js → Ch7hUoAH.js} +1 -1
- package/build/client/_app/immutable/chunks/{CnzmIbjr.js → ChmmHPdM.js} +1 -1
- package/build/client/_app/immutable/chunks/{DfUgh5E_.js → CjajmcJs.js} +1 -1
- package/build/client/_app/immutable/chunks/{q5PRaRZk.js → Ck6GS6Vb.js} +1 -1
- package/build/client/_app/immutable/chunks/{eFcFJ9Ld.js → ClGoDr_f.js} +1 -1
- package/build/client/_app/immutable/chunks/{BQC6O_RV.js → ClqGHlec.js} +1 -1
- package/build/client/_app/immutable/chunks/{zypfUZYM.js → CnW6hje6.js} +1 -1
- package/build/client/_app/immutable/chunks/{OW5Q7tGb.js → CpI6VYCH.js} +1 -1
- package/build/client/_app/immutable/chunks/{BXKc4uuX.js → CygwwaiE.js} +1 -1
- package/build/client/_app/immutable/chunks/{Bqwvv7Vf.js → CyhZtsZO.js} +35 -35
- package/build/client/_app/immutable/chunks/{BenkQ_4r.js → D-E2Noqq.js} +1 -1
- package/build/client/_app/immutable/chunks/{DuRZnRVw.js → D4Btzp_A.js} +1 -1
- package/build/client/_app/immutable/chunks/{CdaJvl_A.js → D4C3Jijv.js} +1 -1
- package/build/client/_app/immutable/chunks/D9jhmf3I.js +1 -0
- package/build/client/_app/immutable/chunks/{Cf0aMC4n.js → DCw0gAtv.js} +1 -1
- package/build/client/_app/immutable/chunks/{B6bTO8_7.js → DEW3KpiC.js} +1 -1
- package/build/client/_app/immutable/chunks/{O6xxeEm8.js → DYLFbKJe.js} +1 -1
- package/build/client/_app/immutable/chunks/{BsBBq-Qk.js → DYu7kgVa.js} +1 -1
- package/build/client/_app/immutable/chunks/Dfexc5qV.js +1 -0
- package/build/client/_app/immutable/chunks/{kzciT-3i.js → DhmUE8Ri.js} +1 -1
- package/build/client/_app/immutable/chunks/{DdJNsJBH.js → DjwX3rAC.js} +1 -1
- package/build/client/_app/immutable/chunks/{CajOZJDl.js → DlOfy8Sx.js} +1 -1
- package/build/client/_app/immutable/chunks/{CK5vhXvt.js → Do7Y1_MQ.js} +1 -1
- package/build/client/_app/immutable/chunks/{ap4GAVq-.js → Dq2XIb1m.js} +1 -1
- package/build/client/_app/immutable/chunks/{Czey8tDK.js → DuT_Qr5k.js} +1 -1
- package/build/client/_app/immutable/chunks/{4B6J_kM2.js → DyGggFea.js} +1 -1
- package/build/client/_app/immutable/chunks/{D0ChUnpi.js → Dym4i64U.js} +1 -1
- package/build/client/_app/immutable/chunks/FPsIAiN_.js +1 -0
- package/build/client/_app/immutable/chunks/{CevKuuic.js → GIczpP_D.js} +1 -1
- package/build/client/_app/immutable/chunks/{B2jrDnt8.js → LjOLSmU7.js} +1 -1
- package/build/client/_app/immutable/chunks/VtK73aN-.js +8 -0
- package/build/client/_app/immutable/chunks/{AcmOeh2U.js → ZqoQH_jm.js} +1 -1
- package/build/client/_app/immutable/chunks/{BlwWx85l.js → aXn6rE_7.js} +1 -1
- package/build/client/_app/immutable/chunks/{Czc4_W7v.js → dUOeoGwg.js} +1 -1
- package/build/client/_app/immutable/chunks/f50lp1rr.js +1 -0
- package/build/client/_app/immutable/chunks/{7FnrqGK9.js → lvLrv1cG.js} +1 -1
- package/build/client/_app/immutable/chunks/{CZoElI5B.js → pt3_jHwh.js} +1 -1
- package/build/client/_app/immutable/chunks/{Byu_teLA.js → q8irUX-p.js} +1 -1
- package/build/client/_app/immutable/chunks/{CnxoqrkQ.js → qmOgUo3c.js} +1 -1
- package/build/client/_app/immutable/chunks/vpNeypNM.js +1 -0
- package/build/client/_app/immutable/chunks/{DU8C5thd.js → xvTPLhcB.js} +1 -1
- package/build/client/_app/immutable/chunks/{DFBKiA2Z.js → zp7hrpsC.js} +1 -1
- package/build/client/_app/immutable/entry/app.D4oc_iez.js +2 -0
- package/build/client/_app/immutable/entry/start.Xkr2MCWg.js +1 -0
- package/build/client/_app/immutable/nodes/0.fsrqKU9i.js +1 -0
- package/build/client/_app/immutable/nodes/1.3F37GwcO.js +1 -0
- package/build/client/_app/immutable/nodes/2.DsWNNw0K.js +340 -0
- package/build/client/_app/version.json +1 -1
- package/build/handler.js +6 -6
- package/build/index.js +6 -6
- package/build/server/chunks/chunks/{app-config.svelte.js-BM4WbMFB.js → app-config.svelte.js-BXjvTmJu.js} +8 -3
- package/build/server/chunks/chunks/{config.js-vThvQeMn.js → config.js-r_jw_bQQ.js} +54 -2
- package/build/server/chunks/chunks/{db.js-DQm6CZ_r.js → db.js-f2PmBjyD.js} +2 -2
- package/build/server/chunks/chunks/{db2.js-DUhFxA3a.js → db2.js-DkwY64WO.js} +2 -2
- package/build/server/chunks/chunks/{dsh-connection.js-BgeraFA2.js → dsh-connection.js-BW07Aicl.js} +18 -10
- package/build/server/chunks/chunks/{dsh-events.js-BUkLR6ZV.js → dsh-events.js-BHf0lLZ5.js} +16 -3
- package/build/server/chunks/chunks/{git-probe.js-CLF37SRh.js → git-probe.js-CQqTV7XX.js} +3 -3
- package/build/server/chunks/chunks/{index-server.js-DmIEbDVz.js → index-server.js-CPkVoRxB.js} +2 -2
- package/build/server/chunks/chunks/{insight-config.js-Dp_2gB5J.js → insight-config.js-C5-Rhh5A.js} +19 -6
- package/build/server/chunks/chunks/{internal2.js-J3h-US64.js → internal2.js-DbC8VGqD.js} +4 -4
- package/build/server/chunks/chunks/ledger-stats.js-BWACyDPg.js +72 -0
- package/build/server/chunks/chunks/{registry.js-CZNJZ0C-.js → registry.js-CWnRQ4vx.js} +751 -53
- package/build/server/chunks/chunks/{registry2.js-D3Pr1Rv9.js → registry2.js-CFzpvj9c.js} +17 -1
- package/build/server/chunks/chunks/{server.js-B1bDXhHu.js → server.js-Dijo7DtV.js} +2 -2
- package/build/server/chunks/chunks/{settings-document.js-Gw1puaik.js → settings-document.js-DxKURfc_.js} +2 -2
- package/build/server/chunks/chunks/{state.js-8RBD56dL.js → state.js-DR4xiIVw.js} +5 -5
- package/build/server/chunks/chunks/{watcher.js-BVKnoQUw.js → watcher.js-DvlNn8X0.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/a2a/_id_/{_server.ts.js-BjzdVwdY.js → _server.ts.js-DItDXV23.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/a2a/{_server.ts.js-3kQCQuHT.js → _server.ts.js-Hor8QZb1.js} +8 -8
- package/build/server/chunks/entries/endpoints/api/a2a/register/{_server.ts.js-BUBTCLFn.js → _server.ts.js-CEvvsa8B.js} +8 -8
- package/build/server/chunks/entries/endpoints/api/browser/_id_/activate/{_server.ts.js-BdMJzENm.js → _server.ts.js-sXqf-okw.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/browser/_id_/close/{_server.ts.js-B5z9-N8Y.js → _server.ts.js-Byj9ApJh.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/browser/_id_/closetab/{_server.ts.js-CnZHun5r.js → _server.ts.js-DOIsrzvg.js} +16 -9
- package/build/server/chunks/entries/endpoints/api/browser/_id_/element/{_server.ts.js-C1oM2Ihf.js → _server.ts.js-Cq3gmRfE.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/browser/_id_/history/_server.ts.js-BGSLIV0t.js +61 -0
- package/build/server/chunks/entries/endpoints/api/browser/_id_/input/{_server.ts.js-DmbqGRMg.js → _server.ts.js-8slca75-.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/browser/_id_/mcp/{_server.ts.js-Cj80T1yH.js → _server.ts.js-CpbdTYds.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/browser/_id_/navigate/{_server.ts.js-6gi1UYTJ.js → _server.ts.js-Bls9LtLY.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/browser/_id_/opentab/{_server.ts.js-Bhx_J7ot.js → _server.ts.js-DqNi_iW_.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/browser/_id_/page/{_server.ts.js-DvQXNnX9.js → _server.ts.js-DuXWwo7i.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/browser/_id_/stream/{_server.ts.js-MflkVWUn.js → _server.ts.js-DXfqBDEw.js} +38 -9
- package/build/server/chunks/entries/endpoints/api/browser/_id_/tabs/{_server.ts.js-CoUSlLcP.js → _server.ts.js-Bgnl8lYs.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/browser/_id_/viewport/{_server.ts.js-DNk4EgjJ.js → _server.ts.js-FHmQVbrv.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/browser/_id_/zoom/_server.ts.js-BV4cBtSA.js +62 -0
- package/build/server/chunks/entries/endpoints/api/browser/{_server.ts.js-CECKap7O.js → _server.ts.js-4vgkwh7v.js} +9 -6
- package/build/server/chunks/entries/endpoints/api/config/{_server.ts.js-C8XDnDwe.js → _server.ts.js-C_9kwANR.js} +16 -6
- package/build/server/chunks/entries/endpoints/api/dsh/directory/{_server.ts.js-BFmWshpv.js → _server.ts.js-h1OTHcL4.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/jobs/{_server.ts.js-DATWy5mQ.js → _server.ts.js-B6nih9Sd.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/jobs/follow/{_server.ts.js-CugOD1Zd.js → _server.ts.js-Cf17SVmD.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/pick-directory/{_server.ts.js-DCupM4da.js → _server.ts.js-DjNwMbdS.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/presets/{_server.ts.js-Bh1btvr9.js → _server.ts.js-Cz5aaEhC.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/attachment/_server.ts.js-BFBy5O9Y.js +78 -0
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/cancel/{_server.ts.js-WI9yH2iG.js → _server.ts.js-CgEdCo3T.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/catalog/{_server.ts.js-bN9adUqz.js → _server.ts.js-Bo_aEnHh.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/changes/{_server.ts.js-Bxlm966G.js → _server.ts.js-Bd2G_GaH.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/command/{_server.ts.js-CM-raN_Q.js → _server.ts.js-DL64FyRw.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/events/{_server.ts.js-BzP30TXW.js → _server.ts.js-MhOGB66D.js} +7 -70
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/fork/{_server.ts.js-DvNkrTaY.js → _server.ts.js-MjPgXgGO.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/goal/{_server.ts.js-DXbCrefw.js → _server.ts.js-BUjDae5H.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/history/{_server.ts.js-B7YRQhuJ.js → _server.ts.js-dTKd7Hsv.js} +6 -6
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/models/{_server.ts.js-C_AEaLLJ.js → _server.ts.js-B82rvKoI.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/path/{_server.ts.js-Dj-pF5ik.js → _server.ts.js-Cqijsi-c.js} +4 -4
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/permission/{_server.ts.js-BX9FWJ6g.js → _server.ts.js-CL_vVv2p.js} +29 -6
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/prompt/{_server.ts.js-CQ2Bmtu4.js → _server.ts.js-WS4W9Ly4.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/rename/{_server.ts.js-Ha7xjnKW.js → _server.ts.js-B72KGRGh.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/respond/{_server.ts.js-BOg6llHk.js → _server.ts.js-DK5xb2b5.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/select-model/{_server.ts.js-DBqGALzZ.js → _server.ts.js-lhT87EQu.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/sessions/{_server.ts.js-CvA8WDDb.js → _server.ts.js-CMhfhbkN.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/subagents/_server.ts.js-BLvcFsg6.js +72 -0
- package/build/server/chunks/entries/endpoints/api/dsh/workspace-file/{_server.ts.js-BfjNH40j.js → _server.ts.js-D_rw2Uq6.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/workspace-tree/{_server.ts.js-De_qumyr.js → _server.ts.js-DfXpMMpw.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/workspaces/{_server.ts.js-tFpJJHCb.js → _server.ts.js-2mJCJVxk.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/workspaces/_workspaceId_/delete/{_server.ts.js-DVx5GGA_.js → _server.ts.js-BCx0Lzjf.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/workspaces/_workspaceId_/rename/{_server.ts.js-DuKT-aZp.js → _server.ts.js-DECaSjwp.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/prompts/_id_/{_server.ts.js-DsWFidFY.js → _server.ts.js-i_ciJzlb.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/prompts/{_server.ts.js-C6j0adQs.js → _server.ts.js-BO1pScn7.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/prompts/use/{_server.ts.js-BChAg4hm.js → _server.ts.js-Buhpf7WE.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/settings/{_server.ts.js-BPSHqbZN.js → _server.ts.js-DngUQzcT.js} +4 -4
- package/build/server/chunks/entries/endpoints/api/terminal/_id_/output/{_server.ts.js-BNBxebgG.js → _server.ts.js-DLETP4yQ.js} +2 -2
- package/build/server/chunks/entries/endpoints/api/terminal/_id_/reattach/{_server.ts.js-DDRJBGIr.js → _server.ts.js-uWl6oxPS.js} +2 -2
- package/build/server/chunks/entries/endpoints/api/terminal/_id_/send/{_server.ts.js-CA0vc_Cm.js → _server.ts.js-DYNmXaAd.js} +9 -2
- package/build/server/chunks/entries/endpoints/api/terminal/_id_/stream/{_server.ts.js-D6L8Gd_f.js → _server.ts.js-C5m3Ktho.js} +2 -2
- package/build/server/chunks/entries/endpoints/api/terminal/{_server.ts.js-D5CbUe5k.js → _server.ts.js-DoTNvcOa.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/workspace/file-write/{_server.ts.js-B-5YihUA.js → _server.ts.js-BzYOJSkI.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/workspace/git-events/{_server.ts.js-DT5jRZFE.js → _server.ts.js-xcNesei9.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/workspace/git-file-head/{_server.ts.js-DtW-utrd.js → _server.ts.js-DsJWYdxt.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/workspace/git-map/{_server.ts.js-8AIAo9jX.js → _server.ts.js-CNCku9BR.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/workspace/git-status/{_server.ts.js-CMw96vjY.js → _server.ts.js-nLsNjOxj.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/workspace/write-gate/{_server.ts.js-DKufa14_.js → _server.ts.js-urQk2-ds.js} +7 -7
- package/build/server/chunks/entries/{hooks.server.js-B-e4_ekh.js → hooks.server.js-CU2RE5vs.js} +3 -3
- package/build/server/chunks/entries/pages/{_error.svelte.js-DRPduJdP.js → _error.svelte.js-e018KpwE.js} +6 -6
- package/build/server/chunks/entries/pages/{_page.server.ts.js-7x6ZfGoB.js → _page.server.ts.js-BK3Y6eff.js} +3 -3
- package/build/server/chunks/entries/pages/{_page.svelte.js-Dek8Q1_v.js → _page.svelte.js-DQWBiRk1.js} +4185 -1734
- package/build/server/chunks/{handler-DUyvzXsb.js → handler-DsD7I1_u.js} +3 -3
- package/build/server/chunks/{index.js-BrP1SRzN.js → index.js-C_WAkwJs.js} +4 -4
- package/build/server/chunks/{manifest.js-C4z6aoYx.js → manifest.js-DUy52VaP.js} +85 -64
- package/build/server/chunks/nodes/{0.js-BuB3t8Br.js → 0.js-CuV3dXVD.js} +3 -3
- package/build/server/chunks/nodes/1.js-Dc5QC-NJ.js +9 -0
- package/build/server/chunks/nodes/{2.js-C-o9KF10.js → 2.js-PwcF4_kT.js} +10 -10
- package/package.json +2 -2
- package/skills/{dsi-kb-scenario → dsi-fc-scenario}/SKILL.md +11 -6
- package/template/.dsi/prompts.sqlite +0 -0
- package/template/.dsi/prompts.sqlite-shm +0 -0
- package/template/.dsi/prompts.sqlite-wal +0 -0
- package/template/.dsi/settings.yaml +7 -2
- package/build/client/_app/immutable/assets/0.cswkTiBk.css +0 -2
- package/build/client/_app/immutable/assets/2.BPprd30B.css +0 -1
- package/build/client/_app/immutable/chunks/BHDqH9nE.js +0 -1
- package/build/client/_app/immutable/chunks/C7Sg_49n.js +0 -1
- package/build/client/_app/immutable/chunks/CAneZX4t.js +0 -8
- package/build/client/_app/immutable/chunks/D-Rolhzs.js +0 -1
- package/build/client/_app/immutable/chunks/DQXo7qdJ.js +0 -1
- package/build/client/_app/immutable/chunks/DY0MQ1mO.js +0 -1
- package/build/client/_app/immutable/chunks/K3xyLTzZ.js +0 -1
- package/build/client/_app/immutable/chunks/NcOjFWr3.js +0 -6
- package/build/client/_app/immutable/chunks/cHj8EuyS.js +0 -3
- package/build/client/_app/immutable/chunks/o7DVZODA.js +0 -1
- package/build/client/_app/immutable/chunks/pdYhlwhf.js +0 -1
- package/build/client/_app/immutable/entry/app.DYNedUxy.js +0 -2
- package/build/client/_app/immutable/entry/start.BzyrBssE.js +0 -1
- package/build/client/_app/immutable/nodes/0.DQYP6BCS.js +0 -1
- package/build/client/_app/immutable/nodes/1.CHB5qqQ9.js +0 -1
- package/build/client/_app/immutable/nodes/2.C6No1310.js +0 -340
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/attachment/_server.ts.js-Cb8SBWVw.js +0 -46
- package/build/server/chunks/nodes/1.js-CW4V8ni8.js +0 -9
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* _args.mjs — pure helpers for glass-url.mjs (ADR-0045 Amendment 5, D9 + D10).
|
|
3
|
+
*
|
|
4
|
+
* Lives beside _connect.mjs so vitest can pin them without touching CDP
|
|
5
|
+
* (the driver connects at import; these never do). Exports are a contract:
|
|
6
|
+
* change them in the same edit that changes glass-url.mjs.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Title normalization: fold apostrophes, case, and punctuation runs.
|
|
11
|
+
* @param {string | undefined | null} s
|
|
12
|
+
* @returns {string}
|
|
13
|
+
*/
|
|
14
|
+
export const norm = (s) => (s || '').toLowerCase().replace(/[\u2019']/g, '').replace(/[^a-z0-9]+/g, ' ').trim();
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* D10 — the eval grammar is parsed, not positional.
|
|
18
|
+
* Inline mode: [substr?] src — the LAST arg is always the JS source.
|
|
19
|
+
* b64 mode: [b64payload, substr?] — the payload is consumed by the caller
|
|
20
|
+
* (it already stripped --b64), so anything LEFT is the substring.
|
|
21
|
+
* Returns an object with src and substr, undefined where absent.
|
|
22
|
+
* @param {string[]} rest
|
|
23
|
+
* @param {{ b64?: boolean } | undefined} [opts]
|
|
24
|
+
* @returns {{ src: string | undefined, substr: string | undefined }}
|
|
25
|
+
*/
|
|
26
|
+
export function parseEvalArgs(rest, opts) {
|
|
27
|
+
const b64 = !!(opts && opts.b64);
|
|
28
|
+
if (b64) {
|
|
29
|
+
return { src: rest[0], substr: rest.length > 1 ? rest[1] : undefined };
|
|
30
|
+
}
|
|
31
|
+
if (rest.length > 1) return { substr: rest[0], src: rest[1] };
|
|
32
|
+
return { src: rest[0], substr: undefined };
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* D9 — the play match consumes EVERY play term.
|
|
37
|
+
* True only when every whitespace-split term of play appears in the
|
|
38
|
+
* normalized title. An empty or absent play value means no filter (true) —
|
|
39
|
+
* the yt verb then takes the first result, unchanged behavior.
|
|
40
|
+
* @param {string} title
|
|
41
|
+
* @param {string | undefined | null} play
|
|
42
|
+
* @returns {boolean}
|
|
43
|
+
*/
|
|
44
|
+
export function matchAllTerms(title, play) {
|
|
45
|
+
const terms = (play || '').split(/\s+/).filter(Boolean);
|
|
46
|
+
if (!terms.length) return true;
|
|
47
|
+
const t = norm(title);
|
|
48
|
+
return terms.every((term) => t.includes(norm(term)));
|
|
49
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* _connect.mjs — shared glass connection for the glass-url / glass-dsi drivers.
|
|
4
|
+
*
|
|
5
|
+
* EXPORTS (do not guess — this header is the contract, keep it in sync):
|
|
6
|
+
* die(msg) — print a JSON error and exit 1.
|
|
7
|
+
* identityFrom(argv) — caller identity, first-wins: --owner-session
|
|
8
|
+
* flag > GLASS_OWNER_SESSION > DSH_SESSION_ID
|
|
9
|
+
* (the harness built-in is CONDITIONAL —
|
|
10
|
+
* dsh-shell-env index.js:89 injects it only
|
|
11
|
+
* when the execution carries an agent binding,
|
|
12
|
+
* RCA 2026-10-30 "the session id is gone" —
|
|
13
|
+
* so explicit beats inherited).
|
|
14
|
+
* pickSession(sessions, envId)
|
|
15
|
+
* — PURE D7 resolver (unit-tested): match the
|
|
16
|
+
* caller's identity to ownerSessionId. NEVER
|
|
17
|
+
* registry index (ADR-0045 amendment 3).
|
|
18
|
+
* Returns { session } | { session:null, error }.
|
|
19
|
+
* connect() — GET /api/browser (the ONLY source of truth,
|
|
20
|
+
* ADR-0030) → pickSession → CDP connect →
|
|
21
|
+
* { session, browser, ctx }. Dies LOUDLY on
|
|
22
|
+
* ambiguity; degraded single-session runs print
|
|
23
|
+
* a warning on stderr and proceed.
|
|
24
|
+
* pick(ctx, substr) — page whose URL contains substr; NEVER
|
|
25
|
+
* positional "newest" among foreign tabs (D2).
|
|
26
|
+
*/
|
|
27
|
+
import { chromium } from 'playwright-core';
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @typedef {Object} GlassSession
|
|
31
|
+
* @property {string} id
|
|
32
|
+
* @property {number} [port]
|
|
33
|
+
* @property {string|null} [ownerSessionId]
|
|
34
|
+
* @property {string} [createdAt]
|
|
35
|
+
* @typedef {Object} PickResult
|
|
36
|
+
* @property {GlassSession|null|undefined} session
|
|
37
|
+
* @property {boolean} [degraded]
|
|
38
|
+
* @property {string} [note]
|
|
39
|
+
* @property {string} [error]
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
const DSI = 'http://127.0.0.1:5175';
|
|
43
|
+
|
|
44
|
+
/** @param {string} msg @returns {never} */
|
|
45
|
+
export function die(msg) {
|
|
46
|
+
console.error(JSON.stringify({ error: msg, fallback: 'SKILL.md Step 1 — ask the OPERATOR to click the Browser chip IN THE RIGHT CONVERSATION, then catch the session via GET /api/browser. If DSH_SESSION_ID is absent from env, pass --owner-session <id> (the session id you already know from context).' }));
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** @param {string[]} argv @returns {string|undefined} */
|
|
51
|
+
export function identityFrom(argv) {
|
|
52
|
+
const flag = argv.indexOf('--owner-session');
|
|
53
|
+
if (flag !== -1 && argv[flag + 1]) return argv[flag + 1];
|
|
54
|
+
if (process.env.GLASS_OWNER_SESSION) return process.env.GLASS_OWNER_SESSION;
|
|
55
|
+
if (process.env.DSH_SESSION_ID) return process.env.DSH_SESSION_ID;
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** @param {GlassSession[]|null|undefined} sessions @param {string|undefined} envId @returns {PickResult} */
|
|
60
|
+
export function pickSession(sessions, envId) {
|
|
61
|
+
const list = sessions ?? [];
|
|
62
|
+
if (envId) {
|
|
63
|
+
const mine = list.filter((s) => (s.ownerSessionId ?? null) === envId);
|
|
64
|
+
if (mine.length === 1) return { session: mine[0], degraded: false };
|
|
65
|
+
if (mine.length > 1) {
|
|
66
|
+
const newest = [...mine].sort((a, b) => String(a.createdAt ?? '').localeCompare(String(b.createdAt ?? ''))).at(-1);
|
|
67
|
+
return { session: newest, degraded: false, note: 'multiple glasses owned by ' + envId + ' — newest wins' };
|
|
68
|
+
}
|
|
69
|
+
if (list.length === 1 && (list[0].ownerSessionId ?? null) === null) {
|
|
70
|
+
return { session: list[0], degraded: true, note: 'legacy session without ownerSessionId — degraded match' };
|
|
71
|
+
}
|
|
72
|
+
return { session: null, error: 'no glass owned by ' + envId + ' — your glass is dead or never summoned (click the Browser chip in THIS conversation); live glasses belong to other conversations and are untouchable (D7)' };
|
|
73
|
+
}
|
|
74
|
+
if (list.length === 1) {
|
|
75
|
+
return { session: list[0], degraded: true, note: 'no explicit identity in env — degraded single-session resolution' };
|
|
76
|
+
}
|
|
77
|
+
return { session: null, error: 'multiple live glasses and no explicit identity — pass --owner-session <id> (or GLASS_OWNER_SESSION) from the session id you already know; refusing to guess (D7)' };
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** @returns {Promise<{ session: GlassSession, browser: import('playwright-core').Browser, ctx: import('playwright-core').BrowserContext }>} */
|
|
81
|
+
export async function connect() {
|
|
82
|
+
let reg;
|
|
83
|
+
try {
|
|
84
|
+
reg = await (await fetch(DSI + '/api/browser')).json();
|
|
85
|
+
} catch {
|
|
86
|
+
die('DSI dev server not reachable on 5175 — floor not up (dsi dsh --sync --dev --playwright-mcp)');
|
|
87
|
+
}
|
|
88
|
+
const { session, degraded, note, error } = pickSession(reg.sessions, identityFrom(process.argv));
|
|
89
|
+
if (!session) die(error ?? 'no glass session resolved — operator must click the Browser chip');
|
|
90
|
+
if (degraded || note) console.error(JSON.stringify({ warn: note ?? 'degraded', sessionId: session.id }));
|
|
91
|
+
const browser = await chromium.connectOverCDP('http://127.0.0.1:' + session.port).catch(() => null);
|
|
92
|
+
if (!browser) die('CDP connect failed on port ' + session.port);
|
|
93
|
+
return { session, browser, ctx: browser.contexts()[0] };
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** @param {import('playwright-core').BrowserContext} ctx @param {string} substr @returns {import('playwright-core').Page|undefined} */
|
|
97
|
+
export function pick(ctx, substr) {
|
|
98
|
+
return ctx.pages().find((p) => p.url().includes(substr));
|
|
99
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* glass-url.mjs — the glass-url URL path (2026-10-29, hardened 2026-10-30,
|
|
4
|
+
* RCA "The Hardening That Missed the Token Burn").
|
|
5
|
+
*
|
|
6
|
+
* Drives NON-DSI surfaces (YouTube, docs, anything) on the operator's
|
|
7
|
+
* glass. Never touches the DSI tab. One command per intent:
|
|
8
|
+
*
|
|
9
|
+
* node …/glass-url.mjs yt <search terms…> --play "<title-substring>" [--shot f.png]
|
|
10
|
+
* search YouTube → normalized title match → open watch tab →
|
|
11
|
+
* unmute+play → gate twice (paused:false, rising t) → optional shot.
|
|
12
|
+
* Prints ONE JSON with every intermediate stage, then EXITS.
|
|
13
|
+
* node …/glass-url.mjs open <url>
|
|
14
|
+
* node …/glass-url.mjs pages
|
|
15
|
+
* node …/glass-url.mjs eval [url-substring] <js> # inline JS: LAST arg is the source
|
|
16
|
+
* node …/glass-url.mjs eval --b64 <base64-js> [url-substring]
|
|
17
|
+
* # base64 mode: quote-proof transport; anything left after the
|
|
18
|
+
* # payload IS the url-substring (parsed by shape — D10, _args.mjs).
|
|
19
|
+
* # yt --play consumes EVERY term (artist AND title) — D9.
|
|
20
|
+
* # A NO_MATCH / die is an ANSWER: report and stop (D11, SKILL.md).
|
|
21
|
+
* node …/glass-url.mjs shot [file.png] [url-substring]
|
|
22
|
+
*
|
|
23
|
+
* EXIT DISCIPLINE: this script always process.exit()s — a driver that
|
|
24
|
+
* played media once hung its caller for a full timeout (RCA trap 5).
|
|
25
|
+
*/
|
|
26
|
+
import { connect, die, pick } from './_connect.mjs';
|
|
27
|
+
import { norm, parseEvalArgs, matchAllTerms } from './_args.mjs';
|
|
28
|
+
|
|
29
|
+
const argv = process.argv.slice(2);
|
|
30
|
+
const { session, browser, ctx } = await connect();
|
|
31
|
+
const out = (v) => { console.log(JSON.stringify(v, null, 1)); return process.exit(0); };
|
|
32
|
+
|
|
33
|
+
// target tab: url-substring when given; else last http(s) page that is
|
|
34
|
+
// neither the glass placeholder nor :5175 (contract, not position — D2).
|
|
35
|
+
const target = (substr) => {
|
|
36
|
+
if (substr) {
|
|
37
|
+
const p = pick(ctx, substr);
|
|
38
|
+
if (!p) die('no tab matching "' + substr + '" — run: pages');
|
|
39
|
+
return p;
|
|
40
|
+
}
|
|
41
|
+
const pages = ctx.pages().filter((p) => p.url().startsWith('http') && !p.url().includes(':5175'));
|
|
42
|
+
if (!pages.length) die('no non-DSI tab to drive — run: glass-url.mjs open <url>');
|
|
43
|
+
return pages[pages.length - 1];
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// gate: read playback state; double-read proves time rises
|
|
47
|
+
const gate = async (page) => page.evaluate(() => { const v = document.querySelector('video'); if (!v) return { err: 'novideo' }; v.muted = false; try { v.play(); } catch {} return { t: Math.round(v.currentTime * 10) / 10, paused: v.paused }; });
|
|
48
|
+
|
|
49
|
+
const cmd = argv[0];
|
|
50
|
+
|
|
51
|
+
if (cmd === 'open') {
|
|
52
|
+
const url = argv[1];
|
|
53
|
+
if (!url) die('open needs a url');
|
|
54
|
+
const page = await ctx.newPage();
|
|
55
|
+
await page.goto(url, { waitUntil: 'domcontentloaded' }).catch((e) => die('goto failed: ' + e.message));
|
|
56
|
+
await page.waitForTimeout(1500); // let the SPA settle
|
|
57
|
+
await page.bringToFront(); // make the opened tab the active/visible one
|
|
58
|
+
out({ ok: true, sessionId: session.id, url: page.url(), title: await page.title() });
|
|
59
|
+
} else if (cmd === 'pages') {
|
|
60
|
+
out(await Promise.all(ctx.pages().map(async (p) => ({ url: p.url(), title: await p.title() }))));
|
|
61
|
+
} else if (cmd === 'eval') {
|
|
62
|
+
let rest = argv.slice(1);
|
|
63
|
+
let substr;
|
|
64
|
+
let src;
|
|
65
|
+
let b64 = false;
|
|
66
|
+
if (rest[0] === '--b64') { b64 = true; rest = rest.slice(1); } // payload stays in rest; parseEvalArgs takes it from here (D10)
|
|
67
|
+
const parsed = parseEvalArgs(rest, { b64 });
|
|
68
|
+
src = parsed.src; substr = parsed.substr;
|
|
69
|
+
if (b64 && src) src = Buffer.from(src, 'base64').toString('utf8');
|
|
70
|
+
if (!src) die('eval needs js (inline or --b64 <base64>)');
|
|
71
|
+
out(await target(substr).evaluate(async (s) => await eval(s), src));
|
|
72
|
+
} else if (cmd === 'shot') {
|
|
73
|
+
const file = argv[1] ?? 'tmp/glass-url-shot.png';
|
|
74
|
+
const substr = argv[2];
|
|
75
|
+
await target(substr).screenshot({ path: file });
|
|
76
|
+
out({ ok: true, file });
|
|
77
|
+
} else if (cmd === 'yt') {
|
|
78
|
+
const dash = argv.indexOf('--play');
|
|
79
|
+
const shotFlag = argv.indexOf('--shot');
|
|
80
|
+
const terms = argv.slice(1, dash === -1 ? (shotFlag === -1 ? argv.length : shotFlag) : dash).join(' ');
|
|
81
|
+
const matchSub = dash !== -1 ? argv[dash + 1] : null;
|
|
82
|
+
const shotFile = shotFlag !== -1 ? argv[shotFlag + 1] ?? 'tmp/glass-url-yt.png' : null;
|
|
83
|
+
if (!terms) die('yt needs search terms');
|
|
84
|
+
const stages = {};
|
|
85
|
+
const sp = await ctx.newPage();
|
|
86
|
+
await sp.goto('https://www.youtube.com/results?search_query=' + encodeURIComponent(terms), { waitUntil: 'domcontentloaded' });
|
|
87
|
+
await sp.waitForTimeout(3500);
|
|
88
|
+
const raw = await sp.evaluate(() => [...document.querySelectorAll('a#video-title')].slice(0, 25).map((a) => ({ t: a.title || a.textContent.trim(), h: a.href })));
|
|
89
|
+
stages.candidates = raw.length;
|
|
90
|
+
const hit = raw.find((r) => matchAllTerms(r.t, matchSub));
|
|
91
|
+
if (!hit) out({ ok: false, stage: 'match', play: matchSub, titles: raw.slice(0, 10).map((r) => r.t) }); // D9: a refusal is an answer
|
|
92
|
+
stages.matched = hit.t;
|
|
93
|
+
const wp = await ctx.newPage();
|
|
94
|
+
const watchUrl = 'https://www.youtube.com/watch?v=' + new URL(hit.h).searchParams.get('v');
|
|
95
|
+
await wp.goto(watchUrl, { waitUntil: 'domcontentloaded' });
|
|
96
|
+
await wp.waitForTimeout(6000);
|
|
97
|
+
await wp.bringToFront();
|
|
98
|
+
// gate loop: paused:false with RISING t on the last two reads. YouTube
|
|
99
|
+
// may restart the video once as settings settle (observed 2026-10-30:
|
|
100
|
+
// t 5.9 then 3.8) — re-read up to 3x instead of failing an honest play.
|
|
101
|
+
const reads = [await gate(wp)];
|
|
102
|
+
for (let i = 0; i < 2; i++) { await wp.waitForTimeout(4000); reads.push(await gate(wp)); }
|
|
103
|
+
stages.gates = reads;
|
|
104
|
+
const last = reads.slice(-2);
|
|
105
|
+
stages.passed = last.every((r) => r.paused === false && !r.err) && last[1].t > last[0].t;
|
|
106
|
+
if (shotFile) { await wp.screenshot({ path: shotFile }); stages.shot = shotFile; }
|
|
107
|
+
stages.watchUrl = wp.url();
|
|
108
|
+
await sp.close().catch(() => {});
|
|
109
|
+
out({ ok: stages.passed, sessionId: session.id, ...stages });
|
|
110
|
+
} else {
|
|
111
|
+
die('unknown command: ' + cmd + ' (see header usage)');
|
|
112
|
+
}
|
|
113
|
+
await browser.close().catch(() => {});
|
|
114
|
+
process.exit(0);
|
package/bin/dsi.mjs
CHANGED
|
@@ -5,8 +5,11 @@
|
|
|
5
5
|
// relative to this file, not the cwd, so a globally installed or npx-run
|
|
6
6
|
// package serves its own bundled build from any directory.
|
|
7
7
|
// `--zai` (on `dsi web` / `dsi dsh --sync`) bootstraps a fresh DSH install:
|
|
8
|
-
// it adds the ZAI provider and the default model
|
|
9
|
-
//
|
|
8
|
+
// it adds the ZAI provider and the default model as patch entries in the
|
|
9
|
+
// active profile's ~/.dsh/profiles/<profile>/cordis.patch.yml — the file the
|
|
10
|
+
// host composes entry config from (idempotent — existing entries win). The
|
|
11
|
+
// legacy flat ~/.dsh/settings.yaml is DSH's import-tombstoned past; the
|
|
12
|
+
// standalone `dsi zai` command was
|
|
10
13
|
// decommissioned — the flag does the same work before anything boots.
|
|
11
14
|
// `dsi dsh --token <token>` copies a dsh launch token into DSI's config
|
|
12
15
|
// ($DSI_CONFIG_PATH or ~/.dsi/settings.yaml, key dsh.authToken — the same
|
|
@@ -30,6 +33,7 @@ import { parse, stringify } from 'yaml';
|
|
|
30
33
|
import { mirrorSkills } from './lib/mirror-skills.mjs';
|
|
31
34
|
import { dshLauncherCmd, parsePluginArgs, takeoverFloorPorts, hostBounceDecision, floorUiPort, parseDevFloorPids, launchUrl, tokenFromSettings } from './lib/plugin-chain.mjs';
|
|
32
35
|
import { parseDevArg, devModeEnv, modeFromBoolean, resolveBounceMode, extractInspectArgs, parseInspectArgsFromEnv } from './lib/dev-mode.mjs';
|
|
36
|
+
import { addZaiProvider as addZaiPatch, zaiPatchPath } from './lib/zai-patch.mjs';
|
|
33
37
|
|
|
34
38
|
// Layman-facing help: wrapped near 76 columns, continuation lines indented,
|
|
35
39
|
// the recommended one-liner first. --zai is optional on purpose — no GLM
|
|
@@ -47,7 +51,8 @@ const USAGE = [
|
|
|
47
51
|
'',
|
|
48
52
|
' --sync sync the one-time launch token into ~/.dsi/settings.yaml,',
|
|
49
53
|
' then serve host + page as one pair',
|
|
50
|
-
' --zai bootstrap the GLM (Z.AI) provider into
|
|
54
|
+
' --zai bootstrap the GLM (Z.AI) provider into the active profile',
|
|
55
|
+
' ~/.dsh/profiles/<profile>/cordis.patch.yml',
|
|
51
56
|
' before anything boots. No GLM account? Skip it — drop this',
|
|
52
57
|
' flag and keep whatever provider you already configured:',
|
|
53
58
|
'',
|
|
@@ -122,37 +127,6 @@ const OV_PLUGIN = '@openviking/dsh-memory-plugin';
|
|
|
122
127
|
|
|
123
128
|
// ── dsi zai ────────────────────────────────────────────────────────────────
|
|
124
129
|
|
|
125
|
-
/** The ZAI provider block, byte-for-byte the fresh-install shape. */
|
|
126
|
-
const ZAI_PROVIDER = {
|
|
127
|
-
apiKeyEnv: 'ZAI_API_KEY',
|
|
128
|
-
api: 'openai-completions',
|
|
129
|
-
baseURL: 'https://api.z.ai/api/coding/paas/v4',
|
|
130
|
-
compat: { thinkingFormat: 'zai' },
|
|
131
|
-
models: [
|
|
132
|
-
{ id: 'glm-4.7' },
|
|
133
|
-
{ id: 'glm-5-turbo' },
|
|
134
|
-
{ id: 'glm-5.1' },
|
|
135
|
-
{ id: 'glm-5.2' },
|
|
136
|
-
{
|
|
137
|
-
id: 'glm-5.3',
|
|
138
|
-
name: 'GLM-5.3',
|
|
139
|
-
contextWindow: 1_000_000,
|
|
140
|
-
maxTokens: 131_072,
|
|
141
|
-
input: ['text']
|
|
142
|
-
},
|
|
143
|
-
{
|
|
144
|
-
id: 'glm-5.3-flash',
|
|
145
|
-
name: 'GLM-5.3-Flash',
|
|
146
|
-
contextWindow: 1_000_000,
|
|
147
|
-
maxTokens: 131_072,
|
|
148
|
-
input: ['text', 'image']
|
|
149
|
-
}
|
|
150
|
-
]
|
|
151
|
-
};
|
|
152
|
-
|
|
153
|
-
/** The default-model block a fresh ZAI install wants. */
|
|
154
|
-
const ZAI_DEFAULT_MODEL = { provider: 'zai', model: 'glm-5.3-flash' };
|
|
155
|
-
|
|
156
130
|
function isRecord(value) {
|
|
157
131
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
158
132
|
}
|
|
@@ -635,50 +609,25 @@ function readFloorEnv(pid) {
|
|
|
635
609
|
}
|
|
636
610
|
}
|
|
637
611
|
|
|
638
|
-
/** Add the ZAI provider and default model
|
|
639
|
-
*
|
|
640
|
-
*
|
|
641
|
-
* the
|
|
612
|
+
/** Add the ZAI provider and default model as patch entries in the active
|
|
613
|
+
* profile's cordis.patch.yml (bin/lib/zai-patch.mjs, ADR D7-D10). Existing
|
|
614
|
+
* entries always win — an already-configured profile is untouched. Exits 65
|
|
615
|
+
* when the patch file exists but is not a parseable patch array. */
|
|
642
616
|
function addZaiProvider() {
|
|
643
|
-
const
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
if (!isRecord(parsed)) throw new Error('not a YAML mapping');
|
|
651
|
-
doc = parsed;
|
|
652
|
-
} catch (error) {
|
|
653
|
-
console.error(`dsi zai: cannot parse ${settingsPath}: ${error?.message ?? error}`);
|
|
654
|
-
process.exit(65);
|
|
655
|
-
}
|
|
656
|
-
}
|
|
657
|
-
|
|
658
|
-
const added = [];
|
|
659
|
-
if (!isRecord(doc['llm-pi-ai']) || !isRecord(doc['llm-pi-ai'].providers)) {
|
|
660
|
-
doc['llm-pi-ai'] = { providers: {} };
|
|
661
|
-
}
|
|
662
|
-
if (!isRecord(doc['llm-pi-ai'].providers.zai)) {
|
|
663
|
-
doc['llm-pi-ai'].providers.zai = ZAI_PROVIDER;
|
|
664
|
-
added.push('llm-pi-ai.providers.zai');
|
|
665
|
-
}
|
|
666
|
-
if (doc['agent-default-model'] === undefined) {
|
|
667
|
-
doc['agent-default-model'] = ZAI_DEFAULT_MODEL;
|
|
668
|
-
added.push('agent-default-model');
|
|
617
|
+
const target = zaiPatchPath();
|
|
618
|
+
let result;
|
|
619
|
+
try {
|
|
620
|
+
result = addZaiPatch(target);
|
|
621
|
+
} catch (error) {
|
|
622
|
+
console.error(`dsi zai: ${error?.message ?? error}`);
|
|
623
|
+
process.exit(65);
|
|
669
624
|
}
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
console.log(`dsi zai: ${settingsPath} already has the ZAI provider — nothing to do`);
|
|
625
|
+
if (result.added.length === 0) {
|
|
626
|
+
console.log(`dsi zai: ${target} already has the ZAI provider — nothing to do`);
|
|
673
627
|
return;
|
|
674
628
|
}
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
const temp = `${settingsPath}.${process.pid}.tmp`;
|
|
678
|
-
writeFileSync(temp, stringify(doc), 'utf-8');
|
|
679
|
-
renameSync(temp, settingsPath);
|
|
680
|
-
for (const entry of added) console.log(`dsi zai: added ${entry}`);
|
|
681
|
-
console.log(`dsi zai: ${settingsPath} updated — set ZAI_API_KEY in the harness env, then restart dsh web`);
|
|
629
|
+
for (const entry of result.added) console.log(`dsi zai: added ${entry}`);
|
|
630
|
+
console.log(`dsi zai: ${target} updated — set ZAI_API_KEY in the harness env, then restart dsh web`);
|
|
682
631
|
}
|
|
683
632
|
|
|
684
633
|
/** Install the OpenViking memory plugin into the active dsh profile by
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
// The --zai bootstrap: add the GLM (Z.AI) provider and the default model to
|
|
2
|
+
// the ACTIVE dsh profile's Cordis patch file (~/.dsh/profiles/<profile>/
|
|
3
|
+
// cordis.patch.yml) — the file the host actually composes entry config from.
|
|
4
|
+
// The legacy flat ~/.dsh/settings.yaml was imported once and tombstoned as
|
|
5
|
+
// settings.yaml.imported by dsh-settings (ADR: The Packaged Insight 2026-09-11,
|
|
6
|
+
// amendment 2026-11-03, D7-D10), so writing it again only bought a re-import
|
|
7
|
+
// round-trip per boot. Idempotent — existing entries always win: only MISSING
|
|
8
|
+
// keys are added, the operator's other patch entries are never touched.
|
|
9
|
+
// Throws ZaiPatchError on an unparsable/non-array patch file; the bin wiring
|
|
10
|
+
// turns that into exit 65 (same fail-loud contract as before).
|
|
11
|
+
|
|
12
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
|
|
13
|
+
import { homedir } from 'node:os';
|
|
14
|
+
import path from 'node:path';
|
|
15
|
+
import { parse, stringify } from 'yaml';
|
|
16
|
+
|
|
17
|
+
export class ZaiPatchError extends Error {}
|
|
18
|
+
|
|
19
|
+
export const ZAI_PROVIDER = {
|
|
20
|
+
providers: {
|
|
21
|
+
zai: {
|
|
22
|
+
apiKeyEnv: 'ZAI_API_KEY',
|
|
23
|
+
api: 'openai-completions',
|
|
24
|
+
baseURL: 'https://api.z.ai/api/coding/paas/v4',
|
|
25
|
+
compat: { thinkingFormat: 'zai' },
|
|
26
|
+
models: [
|
|
27
|
+
{ id: 'glm-4.7' },
|
|
28
|
+
{ id: 'glm-5-turbo' },
|
|
29
|
+
{ id: 'glm-5.1' },
|
|
30
|
+
{ id: 'glm-5.2' },
|
|
31
|
+
{
|
|
32
|
+
id: 'glm-5.3',
|
|
33
|
+
name: 'GLM-5.3',
|
|
34
|
+
contextWindow: 1000000,
|
|
35
|
+
maxTokens: 131072,
|
|
36
|
+
input: ['text'],
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
id: 'glm-5.3-flash',
|
|
40
|
+
name: 'GLM-5.3-Flash',
|
|
41
|
+
contextWindow: 1000000,
|
|
42
|
+
maxTokens: 131072,
|
|
43
|
+
input: ['text', 'image'],
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export const ZAI_DEFAULT_MODEL = { provider: 'zai', model: 'glm-5.3-flash' };
|
|
51
|
+
|
|
52
|
+
const LLM_ENTRY_NAME = '@deepseek-ai/dsh-llm-pi-ai';
|
|
53
|
+
const MODEL_ENTRY_NAME = '@deepseek-ai/dsh-agent-default-model';
|
|
54
|
+
|
|
55
|
+
/** Resolve the patch file the bootstrap writes: DSH_PATCH_PATH override,
|
|
56
|
+
* else the active profile's cordis.patch.yml (DSH_PROFILE, default web). */
|
|
57
|
+
export function zaiPatchPath() {
|
|
58
|
+
if (process.env.DSH_PATCH_PATH !== undefined) return process.env.DSH_PATCH_PATH;
|
|
59
|
+
const profile = process.env.DSH_PROFILE ?? 'web';
|
|
60
|
+
return path.join(homedir(), '.dsh', 'profiles', profile, 'cordis.patch.yml');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function isRecord(value) {
|
|
64
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Add the ZAI provider and default model as patch entries when absent.
|
|
68
|
+
* Returns { added, path } — added lists the dotted keys newly written.
|
|
69
|
+
* @param {string | undefined} target explicit patch path (tests); default zaiPatchPath() */
|
|
70
|
+
export function addZaiProvider(target = zaiPatchPath()) {
|
|
71
|
+
let entries = [];
|
|
72
|
+
if (existsSync(target)) {
|
|
73
|
+
let parsed;
|
|
74
|
+
try {
|
|
75
|
+
parsed = parse(readFileSync(target, 'utf-8'));
|
|
76
|
+
} catch (error) {
|
|
77
|
+
throw new ZaiPatchError(`cannot parse ${target}: ${error?.message ?? error}`);
|
|
78
|
+
}
|
|
79
|
+
if (!Array.isArray(parsed) || parsed.some((row) => !isRecord(row))) {
|
|
80
|
+
throw new ZaiPatchError(`${target} is not a Cordis patch array of entries`);
|
|
81
|
+
}
|
|
82
|
+
entries = parsed;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const added = [];
|
|
86
|
+
|
|
87
|
+
// llm-pi-ai — create the entry when absent, merge zai when its provider map lacks it.
|
|
88
|
+
let llm = entries.find((row) => row.id === 'llm-pi-ai');
|
|
89
|
+
if (!isRecord(llm)) {
|
|
90
|
+
llm = { id: 'llm-pi-ai', name: LLM_ENTRY_NAME, config: {} };
|
|
91
|
+
entries.push(llm);
|
|
92
|
+
}
|
|
93
|
+
if (!isRecord(llm.config)) llm.config = {};
|
|
94
|
+
if (!isRecord(llm.config.providers)) llm.config.providers = {};
|
|
95
|
+
if (!isRecord(llm.config.providers.zai)) {
|
|
96
|
+
llm.config.providers.zai = ZAI_PROVIDER.providers.zai;
|
|
97
|
+
added.push('llm-pi-ai.providers.zai');
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// agent-default-model — the entry IS the setting; absent means unset.
|
|
101
|
+
if (!entries.some((row) => row.id === 'agent-default-model')) {
|
|
102
|
+
entries.push({ id: 'agent-default-model', name: MODEL_ENTRY_NAME, config: ZAI_DEFAULT_MODEL });
|
|
103
|
+
added.push('agent-default-model');
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (added.length === 0) {
|
|
107
|
+
return { added, path: target };
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
mkdirSync(path.dirname(target), { recursive: true });
|
|
111
|
+
const temp = `${target}.${process.pid}.tmp`;
|
|
112
|
+
writeFileSync(temp, stringify(entries), 'utf-8');
|
|
113
|
+
renameSync(temp, target);
|
|
114
|
+
return { added, path: target };
|
|
115
|
+
}
|