@namzu/cli 35.0.0 → 36.1.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/CHANGELOG.md +764 -0
- package/README.md +160 -394
- package/assets/pal-blender-mcp.py +123 -0
- package/assets/pal-godot-mcp-pin.json +135 -0
- package/assets/pal-godot-mcp.cjs +418 -0
- package/dist/bin-main.d.ts +3 -0
- package/dist/bin-main.d.ts.map +1 -0
- package/dist/bin.d.ts +2 -1
- package/dist/bin.d.ts.map +1 -1
- package/dist/bin.js +85 -23
- package/dist/bin.js.map +6 -1
- package/dist/boot-narrative.d.ts +16 -0
- package/dist/boot-narrative.d.ts.map +1 -0
- package/dist/checkpoints/manifest.d.ts +107 -0
- package/dist/checkpoints/manifest.d.ts.map +1 -0
- package/dist/checkpoints/store.d.ts +280 -40
- package/dist/checkpoints/store.d.ts.map +1 -1
- package/dist/checkpoints/undo-plan.d.ts +83 -0
- package/dist/checkpoints/undo-plan.d.ts.map +1 -0
- package/dist/checkpoints/wrap.d.ts +4 -0
- package/dist/checkpoints/wrap.d.ts.map +1 -1
- package/dist/chunks/acp-5CWS2GLJ.js +13448 -0
- package/dist/chunks/acp-5CWS2GLJ.js.map +6 -0
- package/dist/chunks/activity-command-HK7YJTXV.js +262 -0
- package/dist/chunks/activity-command-HK7YJTXV.js.map +6 -0
- package/dist/chunks/add-ULH5DUNX.js +712 -0
- package/dist/chunks/add-ULH5DUNX.js.map +6 -0
- package/dist/chunks/agent-UEK2U3RE.js +87 -0
- package/dist/chunks/agent-UEK2U3RE.js.map +6 -0
- package/dist/chunks/agent-session-V7JRTODS.js +46 -0
- package/dist/chunks/agent-session-V7JRTODS.js.map +6 -0
- package/dist/chunks/archive-C4A3HPLF.js +84 -0
- package/dist/chunks/archive-C4A3HPLF.js.map +6 -0
- package/dist/chunks/bin-main-EEJHRDIC.js +126 -0
- package/dist/chunks/bin-main-EEJHRDIC.js.map +6 -0
- package/dist/chunks/browser-CRX4HM4C.js +31 -0
- package/dist/chunks/browser-CRX4HM4C.js.map +6 -0
- package/dist/chunks/chat-FVBATC4E.js +101 -0
- package/dist/chunks/chat-FVBATC4E.js.map +6 -0
- package/dist/chunks/chunk-2A37JQKY.js +1355 -0
- package/dist/chunks/chunk-2A37JQKY.js.map +6 -0
- package/dist/chunks/chunk-2NJ2XUXJ.js +283 -0
- package/dist/chunks/chunk-2NJ2XUXJ.js.map +6 -0
- package/dist/chunks/chunk-4HAE7PYX.js +74 -0
- package/dist/chunks/chunk-4HAE7PYX.js.map +6 -0
- package/dist/chunks/chunk-5GRV6P5C.js +69 -0
- package/dist/chunks/chunk-5GRV6P5C.js.map +6 -0
- package/dist/chunks/chunk-5PQVJBIO.js +168 -0
- package/dist/chunks/chunk-5PQVJBIO.js.map +6 -0
- package/dist/chunks/chunk-62I7HLAP.js +1142 -0
- package/dist/chunks/chunk-62I7HLAP.js.map +6 -0
- package/dist/chunks/chunk-63CGV3XY.js +161 -0
- package/dist/chunks/chunk-63CGV3XY.js.map +6 -0
- package/dist/chunks/chunk-6LLJQ3KY.js +225 -0
- package/dist/chunks/chunk-6LLJQ3KY.js.map +6 -0
- package/dist/chunks/chunk-6YG7D7U4.js +159 -0
- package/dist/chunks/chunk-6YG7D7U4.js.map +6 -0
- package/dist/chunks/chunk-76FLAFCG.js +51 -0
- package/dist/chunks/chunk-76FLAFCG.js.map +6 -0
- package/dist/chunks/chunk-7WJOQ6EA.js +106 -0
- package/dist/chunks/chunk-7WJOQ6EA.js.map +6 -0
- package/dist/chunks/chunk-A22MBIYU.js +42 -0
- package/dist/chunks/chunk-A22MBIYU.js.map +6 -0
- package/dist/chunks/chunk-A5DWGNGR.js +73 -0
- package/dist/chunks/chunk-A5DWGNGR.js.map +6 -0
- package/dist/chunks/chunk-A5UXODFL.js +76 -0
- package/dist/chunks/chunk-A5UXODFL.js.map +6 -0
- package/dist/chunks/chunk-AHIDYIRB.js +329 -0
- package/dist/chunks/chunk-AHIDYIRB.js.map +6 -0
- package/dist/chunks/chunk-AIY4PCDR.js +164 -0
- package/dist/chunks/chunk-AIY4PCDR.js.map +6 -0
- package/dist/chunks/chunk-AK2U3N2A.js +31 -0
- package/dist/chunks/chunk-AK2U3N2A.js.map +6 -0
- package/dist/chunks/chunk-AN7FO7NS.js +247 -0
- package/dist/chunks/chunk-AN7FO7NS.js.map +6 -0
- package/dist/chunks/chunk-AXIGFKJF.js +34 -0
- package/dist/chunks/chunk-AXIGFKJF.js.map +6 -0
- package/dist/chunks/chunk-C5WBEO3X.js +46 -0
- package/dist/chunks/chunk-C5WBEO3X.js.map +6 -0
- package/dist/chunks/chunk-C5XYHYMX.js +675 -0
- package/dist/chunks/chunk-C5XYHYMX.js.map +6 -0
- package/dist/chunks/chunk-CG65NUSJ.js +115 -0
- package/dist/chunks/chunk-CG65NUSJ.js.map +6 -0
- package/dist/chunks/chunk-CHIEVVQ2.js +32 -0
- package/dist/chunks/chunk-CHIEVVQ2.js.map +6 -0
- package/dist/chunks/chunk-E5VLANCO.js +101 -0
- package/dist/chunks/chunk-E5VLANCO.js.map +6 -0
- package/dist/chunks/chunk-EBOHVFOB.js +648 -0
- package/dist/chunks/chunk-EBOHVFOB.js.map +6 -0
- package/dist/chunks/chunk-EEDZOGV4.js +47 -0
- package/dist/chunks/chunk-EEDZOGV4.js.map +6 -0
- package/dist/chunks/chunk-EIYM6TY7.js +1479 -0
- package/dist/chunks/chunk-EIYM6TY7.js.map +6 -0
- package/dist/chunks/chunk-EWKJGHRO.js +82559 -0
- package/dist/chunks/chunk-EWKJGHRO.js.map +6 -0
- package/dist/chunks/chunk-EY7UNVER.js +311 -0
- package/dist/chunks/chunk-EY7UNVER.js.map +6 -0
- package/dist/chunks/chunk-FTMTO72X.js +95 -0
- package/dist/chunks/chunk-FTMTO72X.js.map +6 -0
- package/dist/chunks/chunk-FXS3AG6B.js +25326 -0
- package/dist/chunks/chunk-FXS3AG6B.js.map +6 -0
- package/dist/chunks/chunk-GIXSS6KW.js +2228 -0
- package/dist/chunks/chunk-GIXSS6KW.js.map +6 -0
- package/dist/chunks/chunk-GMCOZ3CU.js +245 -0
- package/dist/chunks/chunk-GMCOZ3CU.js.map +6 -0
- package/dist/chunks/chunk-GNBMKISG.js +19 -0
- package/dist/chunks/chunk-GNBMKISG.js.map +6 -0
- package/dist/chunks/chunk-GWQEMJFS.js +28 -0
- package/dist/chunks/chunk-GWQEMJFS.js.map +6 -0
- package/dist/chunks/chunk-H6B6AROX.js +151 -0
- package/dist/chunks/chunk-H6B6AROX.js.map +6 -0
- package/dist/chunks/chunk-HBBB2CAC.js +75 -0
- package/dist/chunks/chunk-HBBB2CAC.js.map +6 -0
- package/dist/chunks/chunk-HE7WUOX2.js +26 -0
- package/dist/chunks/chunk-HE7WUOX2.js.map +6 -0
- package/dist/chunks/chunk-HFJHHCTY.js +303 -0
- package/dist/chunks/chunk-HFJHHCTY.js.map +6 -0
- package/dist/chunks/chunk-HPMWYIBY.js +773 -0
- package/dist/chunks/chunk-HPMWYIBY.js.map +6 -0
- package/dist/chunks/chunk-HQM2WSQT.js +106 -0
- package/dist/chunks/chunk-HQM2WSQT.js.map +6 -0
- package/dist/chunks/chunk-ITZK4B66.js +787 -0
- package/dist/chunks/chunk-ITZK4B66.js.map +6 -0
- package/dist/chunks/chunk-J72CRUNX.js +154 -0
- package/dist/chunks/chunk-J72CRUNX.js.map +6 -0
- package/dist/chunks/chunk-JORONMD3.js +18 -0
- package/dist/chunks/chunk-JORONMD3.js.map +6 -0
- package/dist/chunks/chunk-JPPC4LJF.js +271 -0
- package/dist/chunks/chunk-JPPC4LJF.js.map +6 -0
- package/dist/chunks/chunk-JV3LONAU.js +76 -0
- package/dist/chunks/chunk-JV3LONAU.js.map +6 -0
- package/dist/chunks/chunk-K76WV7TN.js +71 -0
- package/dist/chunks/chunk-K76WV7TN.js.map +6 -0
- package/dist/chunks/chunk-KCWUQRZV.js +828 -0
- package/dist/chunks/chunk-KCWUQRZV.js.map +6 -0
- package/dist/chunks/chunk-KONYGNG6.js +7661 -0
- package/dist/chunks/chunk-KONYGNG6.js.map +6 -0
- package/dist/chunks/chunk-KU3W6IHV.js +109 -0
- package/dist/chunks/chunk-KU3W6IHV.js.map +6 -0
- package/dist/chunks/chunk-LQMHASKR.js +171 -0
- package/dist/chunks/chunk-LQMHASKR.js.map +6 -0
- package/dist/chunks/chunk-LXB3S4IC.js +19 -0
- package/dist/chunks/chunk-LXB3S4IC.js.map +6 -0
- package/dist/chunks/chunk-MZP6SH3M.js +3497 -0
- package/dist/chunks/chunk-MZP6SH3M.js.map +6 -0
- package/dist/chunks/chunk-N5IF64K3.js +1858 -0
- package/dist/chunks/chunk-N5IF64K3.js.map +6 -0
- package/dist/chunks/chunk-NADQQMMG.js +46 -0
- package/dist/chunks/chunk-NADQQMMG.js.map +6 -0
- package/dist/chunks/chunk-NQY5P2EB.js +20 -0
- package/dist/chunks/chunk-NQY5P2EB.js.map +6 -0
- package/dist/chunks/chunk-NUGPLXVK.js +228 -0
- package/dist/chunks/chunk-NUGPLXVK.js.map +6 -0
- package/dist/chunks/chunk-O7DBCVNY.js +110 -0
- package/dist/chunks/chunk-O7DBCVNY.js.map +6 -0
- package/dist/chunks/chunk-OEW7CJKK.js +140 -0
- package/dist/chunks/chunk-OEW7CJKK.js.map +6 -0
- package/dist/chunks/chunk-OH6TB27S.js +111 -0
- package/dist/chunks/chunk-OH6TB27S.js.map +6 -0
- package/dist/chunks/chunk-OLPOM3DR.js +127 -0
- package/dist/chunks/chunk-OLPOM3DR.js.map +6 -0
- package/dist/chunks/chunk-PYG7DZ2D.js +380 -0
- package/dist/chunks/chunk-PYG7DZ2D.js.map +6 -0
- package/dist/chunks/chunk-Q24K7536.js +661 -0
- package/dist/chunks/chunk-Q24K7536.js.map +6 -0
- package/dist/chunks/chunk-Q5YM2GCX.js +283 -0
- package/dist/chunks/chunk-Q5YM2GCX.js.map +6 -0
- package/dist/chunks/chunk-R7DCDBRN.js +106 -0
- package/dist/chunks/chunk-R7DCDBRN.js.map +6 -0
- package/dist/chunks/chunk-RC6X3ZY6.js +1439 -0
- package/dist/chunks/chunk-RC6X3ZY6.js.map +6 -0
- package/dist/chunks/chunk-SGS435PR.js +11111 -0
- package/dist/chunks/chunk-SGS435PR.js.map +6 -0
- package/dist/chunks/chunk-SKKWMMFP.js +474 -0
- package/dist/chunks/chunk-SKKWMMFP.js.map +6 -0
- package/dist/chunks/chunk-SRU3MDHZ.js +75 -0
- package/dist/chunks/chunk-SRU3MDHZ.js.map +6 -0
- package/dist/chunks/chunk-TBIX6JRE.js +24 -0
- package/dist/chunks/chunk-TBIX6JRE.js.map +6 -0
- package/dist/chunks/chunk-THNCQJ33.js +11265 -0
- package/dist/chunks/chunk-THNCQJ33.js.map +6 -0
- package/dist/chunks/chunk-THZXXVHM.js +2953 -0
- package/dist/chunks/chunk-THZXXVHM.js.map +6 -0
- package/dist/chunks/chunk-TIGWWAJI.js +765 -0
- package/dist/chunks/chunk-TIGWWAJI.js.map +6 -0
- package/dist/chunks/chunk-UDBEU2FR.js +97 -0
- package/dist/chunks/chunk-UDBEU2FR.js.map +6 -0
- package/dist/chunks/chunk-UOOQPODR.js +257 -0
- package/dist/chunks/chunk-UOOQPODR.js.map +6 -0
- package/dist/chunks/chunk-US5ZFPAU.js +400 -0
- package/dist/chunks/chunk-US5ZFPAU.js.map +6 -0
- package/dist/chunks/chunk-UWWGSDZ5.js +134 -0
- package/dist/chunks/chunk-UWWGSDZ5.js.map +6 -0
- package/dist/chunks/chunk-UXVYJWN5.js +1373 -0
- package/dist/chunks/chunk-UXVYJWN5.js.map +6 -0
- package/dist/chunks/chunk-V7TQR6AR.js +818 -0
- package/dist/chunks/chunk-V7TQR6AR.js.map +6 -0
- package/dist/chunks/chunk-VRL2WNQN.js +7534 -0
- package/dist/chunks/chunk-VRL2WNQN.js.map +6 -0
- package/dist/chunks/chunk-WATMFOHB.js +319 -0
- package/dist/chunks/chunk-WATMFOHB.js.map +6 -0
- package/dist/chunks/chunk-WHODOMXA.js +132 -0
- package/dist/chunks/chunk-WHODOMXA.js.map +6 -0
- package/dist/chunks/chunk-WM2JEUGV.js +207 -0
- package/dist/chunks/chunk-WM2JEUGV.js.map +6 -0
- package/dist/chunks/chunk-XEUQN4JC.js +54 -0
- package/dist/chunks/chunk-XEUQN4JC.js.map +6 -0
- package/dist/chunks/chunk-XHOD3RDN.js +517 -0
- package/dist/chunks/chunk-XHOD3RDN.js.map +6 -0
- package/dist/chunks/chunk-Y7B67G22.js +26 -0
- package/dist/chunks/chunk-Y7B67G22.js.map +6 -0
- package/dist/chunks/chunk-ZKEWE6K4.js +399 -0
- package/dist/chunks/chunk-ZKEWE6K4.js.map +6 -0
- package/dist/chunks/chunk-ZPR4IMRT.js +36 -0
- package/dist/chunks/chunk-ZPR4IMRT.js.map +6 -0
- package/dist/chunks/chunk-ZWA2JRJV.js +45 -0
- package/dist/chunks/chunk-ZWA2JRJV.js.map +6 -0
- package/dist/chunks/cli-runtime-7YAOEJGS.js +129 -0
- package/dist/chunks/cli-runtime-7YAOEJGS.js.map +6 -0
- package/dist/chunks/commands-QPVRB3RK.js +21 -0
- package/dist/chunks/commands-QPVRB3RK.js.map +6 -0
- package/dist/chunks/computer-GXDY4H35.js +493 -0
- package/dist/chunks/computer-GXDY4H35.js.map +6 -0
- package/dist/chunks/crash-report-S3BTEPYR.js +21 -0
- package/dist/chunks/crash-report-S3BTEPYR.js.map +6 -0
- package/dist/chunks/devtools-LBE4PAQN.js +3851 -0
- package/dist/chunks/devtools-LBE4PAQN.js.map +6 -0
- package/dist/chunks/dist-3GJFRS2X.js +520 -0
- package/dist/chunks/dist-3GJFRS2X.js.map +6 -0
- package/dist/chunks/dist-BFC7XUCT.js +555 -0
- package/dist/chunks/dist-BFC7XUCT.js.map +6 -0
- package/dist/chunks/dist-ERN5DRKK.js +1415 -0
- package/dist/chunks/dist-ERN5DRKK.js.map +6 -0
- package/dist/chunks/dist-EY3OJBQH.js +1339 -0
- package/dist/chunks/dist-EY3OJBQH.js.map +6 -0
- package/dist/chunks/dist-G42HPNIE.js +514 -0
- package/dist/chunks/dist-G42HPNIE.js.map +6 -0
- package/dist/chunks/dist-SKRHHPUR.js +1018 -0
- package/dist/chunks/dist-SKRHHPUR.js.map +6 -0
- package/dist/chunks/dist-Z47L7ZAJ.js +40654 -0
- package/dist/chunks/dist-Z47L7ZAJ.js.map +6 -0
- package/dist/chunks/doctor-IE3PLXZK.js +28 -0
- package/dist/chunks/doctor-IE3PLXZK.js.map +6 -0
- package/dist/chunks/drain-ESXUKOE6.js +471 -0
- package/dist/chunks/drain-ESXUKOE6.js.map +6 -0
- package/dist/chunks/endpoint-M2DDENPP.js +15 -0
- package/dist/chunks/endpoint-M2DDENPP.js.map +6 -0
- package/dist/chunks/eval-53UONRWR.js +187 -0
- package/dist/chunks/eval-53UONRWR.js.map +6 -0
- package/dist/chunks/exec-COV235L5.js +1284 -0
- package/dist/chunks/exec-COV235L5.js.map +6 -0
- package/dist/chunks/home-QS7RBP34.js +16 -0
- package/dist/chunks/home-QS7RBP34.js.map +6 -0
- package/dist/chunks/host-queries-LDEBHKBX.js +152 -0
- package/dist/chunks/host-queries-LDEBHKBX.js.map +6 -0
- package/dist/chunks/lib-KXZZJJG2.js +2657 -0
- package/dist/chunks/lib-KXZZJJG2.js.map +6 -0
- package/dist/chunks/lifecycle-6NF6NJNV.js +63 -0
- package/dist/chunks/lifecycle-6NF6NJNV.js.map +6 -0
- package/dist/chunks/list-DQZU7NEF.js +293 -0
- package/dist/chunks/list-DQZU7NEF.js.map +6 -0
- package/dist/chunks/login-IQGNP5XY.js +29 -0
- package/dist/chunks/login-IQGNP5XY.js.map +6 -0
- package/dist/chunks/logs-KSG7SFAB.js +116 -0
- package/dist/chunks/logs-KSG7SFAB.js.map +6 -0
- package/dist/chunks/mcp-WFXKXGNM.js +763 -0
- package/dist/chunks/mcp-WFXKXGNM.js.map +6 -0
- package/dist/chunks/message-command-O7ZH4I4C.js +170 -0
- package/dist/chunks/message-command-O7ZH4I4C.js.map +6 -0
- package/dist/chunks/node-QB2FA2ZB.js +916 -0
- package/dist/chunks/node-QB2FA2ZB.js.map +6 -0
- package/dist/chunks/operator-tools-LTPV3CH5.js +115 -0
- package/dist/chunks/operator-tools-LTPV3CH5.js.map +6 -0
- package/dist/chunks/output-schema-UM3P5AOR.js +11 -0
- package/dist/chunks/output-schema-UM3P5AOR.js.map +6 -0
- package/dist/chunks/pal-GBYJHBP3.js +200 -0
- package/dist/chunks/pal-GBYJHBP3.js.map +6 -0
- package/dist/chunks/paths-DXYFKIJU.js +10 -0
- package/dist/chunks/paths-DXYFKIJU.js.map +6 -0
- package/dist/chunks/pica-WNHDDIFX.js +1736 -0
- package/dist/chunks/pica-WNHDDIFX.js.map +6 -0
- package/dist/chunks/providers-J42J2PDA.js +160 -0
- package/dist/chunks/providers-J42J2PDA.js.map +6 -0
- package/dist/chunks/resident-7D6IM5LP.js +1314 -0
- package/dist/chunks/resident-7D6IM5LP.js.map +6 -0
- package/dist/chunks/resume-command-XZWGUXRK.js +22 -0
- package/dist/chunks/resume-command-XZWGUXRK.js.map +6 -0
- package/dist/chunks/schedule-JLIOF3MS.js +143 -0
- package/dist/chunks/schedule-JLIOF3MS.js.map +6 -0
- package/dist/chunks/serve-S7UWNIR3.js +21 -0
- package/dist/chunks/serve-S7UWNIR3.js.map +6 -0
- package/dist/chunks/service-YBU5VTKQ.js +1633 -0
- package/dist/chunks/service-YBU5VTKQ.js.map +6 -0
- package/dist/chunks/session-step-2HJSIJNN.js +26 -0
- package/dist/chunks/session-step-2HJSIJNN.js.map +6 -0
- package/dist/chunks/skills-HV2MOBEW.js +282 -0
- package/dist/chunks/skills-HV2MOBEW.js.map +6 -0
- package/dist/chunks/state-6HV3D3O4.js +717 -0
- package/dist/chunks/state-6HV3D3O4.js.map +6 -0
- package/dist/chunks/store-6J2MUGON.js +82 -0
- package/dist/chunks/store-6J2MUGON.js.map +6 -0
- package/dist/chunks/store-GDP2EW27.js +34 -0
- package/dist/chunks/store-GDP2EW27.js.map +6 -0
- package/dist/chunks/store-VXNKMMNW.js +42 -0
- package/dist/chunks/store-VXNKMMNW.js.map +6 -0
- package/dist/chunks/tui-DDWX2WYH.js +56903 -0
- package/dist/chunks/tui-DDWX2WYH.js.map +6 -0
- package/dist/chunks/upgrade-MC5JB7DK.js +315 -0
- package/dist/chunks/upgrade-MC5JB7DK.js.map +6 -0
- package/dist/chunks/webapi-6HUHZUAH.js +2715 -0
- package/dist/chunks/webapi-6HUHZUAH.js.map +6 -0
- package/dist/chunks/worktree-6YPRX6SU.js +116 -0
- package/dist/chunks/worktree-6YPRX6SU.js.map +6 -0
- package/dist/cli-runtime.d.ts +19 -0
- package/dist/cli-runtime.d.ts.map +1 -0
- package/dist/cli.d.ts +0 -15
- package/dist/cli.d.ts.map +1 -1
- package/dist/commands/acp-harness.d.ts +64 -0
- package/dist/commands/acp-harness.d.ts.map +1 -0
- package/dist/commands/acp-provider-retry.d.ts +27 -0
- package/dist/commands/acp-provider-retry.d.ts.map +1 -0
- package/dist/commands/acp.d.ts +134 -3
- package/dist/commands/acp.d.ts.map +1 -1
- package/dist/commands/computer.d.ts +3 -0
- package/dist/commands/computer.d.ts.map +1 -0
- package/dist/commands/desktop-host-changes.d.ts +65 -0
- package/dist/commands/desktop-host-changes.d.ts.map +1 -0
- package/dist/commands/desktop-host-header.d.ts +30 -0
- package/dist/commands/desktop-host-header.d.ts.map +1 -0
- package/dist/commands/desktop-host.d.ts +354 -0
- package/dist/commands/desktop-host.d.ts.map +1 -0
- package/dist/commands/desktop-model-catalogue.d.ts +25 -0
- package/dist/commands/desktop-model-catalogue.d.ts.map +1 -0
- package/dist/commands/effort-levels.d.ts +3 -0
- package/dist/commands/effort-levels.d.ts.map +1 -0
- package/dist/commands/exec-flags.d.ts +4 -0
- package/dist/commands/exec-flags.d.ts.map +1 -1
- package/dist/commands/exec.d.ts.map +1 -1
- package/dist/commands/lazy.d.ts +20 -0
- package/dist/commands/lazy.d.ts.map +1 -0
- package/dist/commands/manifest.d.ts +33 -0
- package/dist/commands/manifest.d.ts.map +1 -0
- package/dist/commands/pal.d.ts +5 -0
- package/dist/commands/pal.d.ts.map +1 -0
- package/dist/commands/permission-preview.d.ts +38 -0
- package/dist/commands/permission-preview.d.ts.map +1 -0
- package/dist/commands/registry.d.ts +10 -0
- package/dist/commands/registry.d.ts.map +1 -1
- package/dist/commands/serve.d.ts +1 -12
- package/dist/commands/serve.d.ts.map +1 -1
- package/dist/commands/stdin.d.ts.map +1 -1
- package/dist/commands/upgrade.d.ts +14 -0
- package/dist/commands/upgrade.d.ts.map +1 -1
- package/dist/compile-cache-enable.d.ts +2 -0
- package/dist/compile-cache-enable.d.ts.map +1 -0
- package/dist/compile-cache.d.ts +53 -0
- package/dist/compile-cache.d.ts.map +1 -0
- package/dist/computer/bundle.d.ts +18 -0
- package/dist/computer/bundle.d.ts.map +1 -0
- package/dist/computer/run.d.ts +26 -0
- package/dist/computer/run.d.ts.map +1 -0
- package/dist/computer/sentences.d.ts +30 -0
- package/dist/computer/sentences.d.ts.map +1 -0
- package/dist/config/load.d.ts +10 -1
- package/dist/config/load.d.ts.map +1 -1
- package/dist/context/capabilities.d.ts +25 -2
- package/dist/context/capabilities.d.ts.map +1 -1
- package/dist/context/runtime-message.d.ts.map +1 -1
- package/dist/crash-report.d.ts +22 -0
- package/dist/crash-report.d.ts.map +1 -0
- package/dist/debug-requested.d.ts +7 -0
- package/dist/debug-requested.d.ts.map +1 -0
- package/dist/doctor/checks/credentials.d.ts.map +1 -1
- package/dist/exit-codes.d.ts +9 -1
- package/dist/exit-codes.d.ts.map +1 -1
- package/dist/index.js +105 -17
- package/dist/index.js.map +6 -1
- package/dist/integrations/harness/claude-adapter.d.ts +20 -0
- package/dist/integrations/harness/claude-adapter.d.ts.map +1 -0
- package/dist/integrations/harness/claude-protocol.d.ts +67 -0
- package/dist/integrations/harness/claude-protocol.d.ts.map +1 -0
- package/dist/integrations/harness/codex-adapter.d.ts +80 -0
- package/dist/integrations/harness/codex-adapter.d.ts.map +1 -0
- package/dist/integrations/harness/codex-protocol.d.ts +22 -0
- package/dist/integrations/harness/codex-protocol.d.ts.map +1 -0
- package/dist/integrations/harness/model-cache.d.ts +16 -0
- package/dist/integrations/harness/model-cache.d.ts.map +1 -0
- package/dist/integrations/harness/native-executable.d.ts +8 -0
- package/dist/integrations/harness/native-executable.d.ts.map +1 -0
- package/dist/integrations/harness/process.d.ts +25 -0
- package/dist/integrations/harness/process.d.ts.map +1 -0
- package/dist/integrations/peers/runtime.d.ts +64 -0
- package/dist/integrations/peers/runtime.d.ts.map +1 -0
- package/dist/integrations/plugins/inventory.d.ts +27 -0
- package/dist/integrations/plugins/inventory.d.ts.map +1 -0
- package/dist/integrations/providers/composer-settings.d.ts +33 -0
- package/dist/integrations/providers/composer-settings.d.ts.map +1 -0
- package/dist/integrations/providers/connections.d.ts +37 -0
- package/dist/integrations/providers/connections.d.ts.map +1 -0
- package/dist/integrations/providers/credential-store.d.ts +35 -0
- package/dist/integrations/providers/credential-store.d.ts.map +1 -1
- package/dist/integrations/providers/discover.d.ts +27 -1
- package/dist/integrations/providers/discover.d.ts.map +1 -1
- package/dist/integrations/providers/index.d.ts +2 -2
- package/dist/integrations/providers/index.d.ts.map +1 -1
- package/dist/integrations/providers/picker-operation.d.ts +6 -0
- package/dist/integrations/providers/picker-operation.d.ts.map +1 -0
- package/dist/integrations/providers/setup.d.ts +16 -1
- package/dist/integrations/providers/setup.d.ts.map +1 -1
- package/dist/integrations/resident/runner-worker.js +190 -161
- package/dist/integrations/resident/runner-worker.js.map +6 -1
- package/dist/integrations/sessions/display-title.d.ts +8 -0
- package/dist/integrations/sessions/display-title.d.ts.map +1 -1
- package/dist/integrations/sessions/store.d.ts +23 -9
- package/dist/integrations/sessions/store.d.ts.map +1 -1
- package/dist/integrations/sessions/task-context.d.ts +1 -1
- package/dist/integrations/sessions/task-context.d.ts.map +1 -1
- package/dist/integrations/sessions/transcript-export.d.ts.map +1 -1
- package/dist/integrations/subagents/activity.d.ts +9 -6
- package/dist/integrations/subagents/activity.d.ts.map +1 -1
- package/dist/integrations/subagents/operator-journal.d.ts +20 -0
- package/dist/integrations/subagents/operator-journal.d.ts.map +1 -0
- package/dist/integrations/subagents/runtime.d.ts +11 -0
- package/dist/integrations/subagents/runtime.d.ts.map +1 -1
- package/dist/integrations/trust/store.d.ts +14 -0
- package/dist/integrations/trust/store.d.ts.map +1 -1
- package/dist/integrations/web/search.d.ts +1 -1
- package/dist/pals/actions.d.ts +57 -0
- package/dist/pals/actions.d.ts.map +1 -0
- package/dist/pals/activity-command.d.ts +3 -0
- package/dist/pals/activity-command.d.ts.map +1 -0
- package/dist/pals/activity.d.ts +18 -0
- package/dist/pals/activity.d.ts.map +1 -0
- package/dist/pals/agent-session.d.ts +19 -0
- package/dist/pals/agent-session.d.ts.map +1 -0
- package/dist/pals/channel-actions.d.ts +5 -0
- package/dist/pals/channel-actions.d.ts.map +1 -0
- package/dist/pals/channel-local.d.ts +7 -0
- package/dist/pals/channel-local.d.ts.map +1 -0
- package/dist/pals/channel.d.ts +20 -0
- package/dist/pals/channel.d.ts.map +1 -0
- package/dist/pals/chat.d.ts +6 -0
- package/dist/pals/chat.d.ts.map +1 -0
- package/dist/pals/communication.d.ts +47 -0
- package/dist/pals/communication.d.ts.map +1 -0
- package/dist/pals/conversations.d.ts +26 -0
- package/dist/pals/conversations.d.ts.map +1 -0
- package/dist/pals/desktop-communication.d.ts +111 -0
- package/dist/pals/desktop-communication.d.ts.map +1 -0
- package/dist/pals/dispatch.d.ts +13 -0
- package/dist/pals/dispatch.d.ts.map +1 -0
- package/dist/pals/environment.d.ts +103 -0
- package/dist/pals/environment.d.ts.map +1 -0
- package/dist/pals/guest-mcp-transport.d.ts +28 -0
- package/dist/pals/guest-mcp-transport.d.ts.map +1 -0
- package/dist/pals/guest-mcp.d.ts +22 -0
- package/dist/pals/guest-mcp.d.ts.map +1 -0
- package/dist/pals/inbox-start.d.ts +35 -0
- package/dist/pals/inbox-start.d.ts.map +1 -0
- package/dist/pals/message-command.d.ts +3 -0
- package/dist/pals/message-command.d.ts.map +1 -0
- package/dist/pals/operator-tools.d.ts +23 -0
- package/dist/pals/operator-tools.d.ts.map +1 -0
- package/dist/pals/public-transcript.d.ts +4 -0
- package/dist/pals/public-transcript.d.ts.map +1 -0
- package/dist/pals/review.d.ts +16 -0
- package/dist/pals/review.d.ts.map +1 -0
- package/dist/pals/store.d.ts +16 -0
- package/dist/pals/store.d.ts.map +1 -0
- package/dist/pals/tui-session.d.ts +11 -0
- package/dist/pals/tui-session.d.ts.map +1 -0
- package/dist/permissions/mode-names.d.ts +2 -0
- package/dist/permissions/mode-names.d.ts.map +1 -0
- package/dist/resume-invocation.d.ts +1 -1
- package/dist/resume-invocation.d.ts.map +1 -1
- package/dist/resume-shell.d.ts +8 -0
- package/dist/resume-shell.d.ts.map +1 -0
- package/dist/schedule/build.d.ts +12 -3
- package/dist/schedule/build.d.ts.map +1 -1
- package/dist/schedule/commands/add.d.ts +1 -1
- package/dist/schedule/commands/add.d.ts.map +1 -1
- package/dist/schedule/commands/lifecycle.d.ts.map +1 -1
- package/dist/schedule/commands/list.d.ts +3 -1
- package/dist/schedule/commands/list.d.ts.map +1 -1
- package/dist/schedule/daemon/daemon.d.ts +2 -0
- package/dist/schedule/daemon/daemon.d.ts.map +1 -1
- package/dist/schedule/delivery.d.ts +66 -0
- package/dist/schedule/delivery.d.ts.map +1 -0
- package/dist/schedule/fire/fire.d.ts +1 -1
- package/dist/schedule/fire/fire.d.ts.map +1 -1
- package/dist/schedule/fire/run-script.d.ts +2 -2
- package/dist/schedule/fire/run-script.d.ts.map +1 -1
- package/dist/schedule/fire/script-report.d.ts +31 -0
- package/dist/schedule/fire/script-report.d.ts.map +1 -0
- package/dist/schedule/floor.d.ts +1 -1
- package/dist/schedule/floor.d.ts.map +1 -1
- package/dist/schedule/folder.d.ts +6 -0
- package/dist/schedule/folder.d.ts.map +1 -1
- package/dist/schedule/resume-command.d.ts +3 -3
- package/dist/schedule/resume-command.d.ts.map +1 -1
- package/dist/schedule/store/history.d.ts.map +1 -1
- package/dist/schedule/store/jobs.d.ts +6 -6
- package/dist/schedule/store/jobs.d.ts.map +1 -1
- package/dist/schedule/store/script-state.d.ts +31 -0
- package/dist/schedule/store/script-state.d.ts.map +1 -0
- package/dist/schedule/store/state.d.ts +4 -2
- package/dist/schedule/store/state.d.ts.map +1 -1
- package/dist/schedule/types.d.ts +61 -16
- package/dist/schedule/types.d.ts.map +1 -1
- package/dist/skills/store.d.ts.map +1 -1
- package/dist/terminal/host.d.ts +22 -0
- package/dist/terminal/host.d.ts.map +1 -0
- package/dist/terminal/manager.d.ts +124 -0
- package/dist/terminal/manager.d.ts.map +1 -0
- package/dist/terminal/protocol.d.ts +162 -0
- package/dist/terminal/protocol.d.ts.map +1 -0
- package/dist/terminal/pty.d.ts +85 -0
- package/dist/terminal/pty.d.ts.map +1 -0
- package/dist/terminal/ring.d.ts +23 -0
- package/dist/terminal/ring.d.ts.map +1 -0
- package/dist/terminal/screen.d.ts +31 -0
- package/dist/terminal/screen.d.ts.map +1 -0
- package/dist/termination-state.d.ts +19 -0
- package/dist/termination-state.d.ts.map +1 -0
- package/dist/termination.d.ts +2 -9
- package/dist/termination.d.ts.map +1 -1
- package/dist/tui/AgentExplorer.d.ts +4 -1
- package/dist/tui/AgentExplorer.d.ts.map +1 -1
- package/dist/tui/App.d.ts.map +1 -1
- package/dist/tui/BackgroundJobsPanel.d.ts.map +1 -1
- package/dist/tui/BrandHeader.d.ts.map +1 -1
- package/dist/tui/ChildComposer.d.ts +22 -0
- package/dist/tui/ChildComposer.d.ts.map +1 -0
- package/dist/tui/ChoicePicker.d.ts.map +1 -1
- package/dist/tui/Composer.d.ts +21 -3
- package/dist/tui/Composer.d.ts.map +1 -1
- package/dist/tui/ComposerFrame.d.ts.map +1 -1
- package/dist/tui/CopyPicker.d.ts.map +1 -1
- package/dist/tui/EditPromptPicker.d.ts.map +1 -1
- package/dist/tui/EffortSlider.d.ts.map +1 -1
- package/dist/tui/LiveActivity.d.ts +7 -1
- package/dist/tui/LiveActivity.d.ts.map +1 -1
- package/dist/tui/Markdown.d.ts.map +1 -1
- package/dist/tui/PendingInputPanel.d.ts.map +1 -1
- package/dist/tui/PermissionOverlay.d.ts.map +1 -1
- package/dist/tui/Picker.d.ts.map +1 -1
- package/dist/tui/ProviderSetup.d.ts.map +1 -1
- package/dist/tui/ResumePicker.d.ts.map +1 -1
- package/dist/tui/SaveSkillOverlay.d.ts.map +1 -1
- package/dist/tui/ScheduleReviewOverlay.d.ts +1 -1
- package/dist/tui/ScheduleReviewOverlay.d.ts.map +1 -1
- package/dist/tui/StatusBar.d.ts +7 -1
- package/dist/tui/StatusBar.d.ts.map +1 -1
- package/dist/tui/StatusPanel.d.ts.map +1 -1
- package/dist/tui/TextPrompt.d.ts.map +1 -1
- package/dist/tui/ToolOutputViewer.d.ts.map +1 -1
- package/dist/tui/Transcript.d.ts +3 -0
- package/dist/tui/Transcript.d.ts.map +1 -1
- package/dist/tui/TranscriptScrollView.d.ts +23 -0
- package/dist/tui/TranscriptScrollView.d.ts.map +1 -0
- package/dist/tui/TrustPrompt.d.ts +8 -0
- package/dist/tui/TrustPrompt.d.ts.map +1 -1
- package/dist/tui/agent.d.ts +125 -3
- package/dist/tui/agent.d.ts.map +1 -1
- package/dist/tui/browser-notices.d.ts.map +1 -1
- package/dist/tui/capability-notice.d.ts +38 -0
- package/dist/tui/capability-notice.d.ts.map +1 -0
- package/dist/tui/console-input.d.ts +31 -0
- package/dist/tui/console-input.d.ts.map +1 -0
- package/dist/tui/conversation-evidence-view.d.ts.map +1 -1
- package/dist/tui/credential-entry.d.ts.map +1 -1
- package/dist/tui/exit-summary.d.ts +9 -1
- package/dist/tui/exit-summary.d.ts.map +1 -1
- package/dist/tui/external-editor.d.ts.map +1 -1
- package/dist/tui/index.d.ts.map +1 -1
- package/dist/tui/key-hints.d.ts +51 -0
- package/dist/tui/key-hints.d.ts.map +1 -0
- package/dist/tui/launch-settings.d.ts +34 -0
- package/dist/tui/launch-settings.d.ts.map +1 -0
- package/dist/tui/log-pane.d.ts.map +1 -1
- package/dist/tui/model-choices.d.ts +39 -1
- package/dist/tui/model-choices.d.ts.map +1 -1
- package/dist/tui/model-search.d.ts +4 -1
- package/dist/tui/model-search.d.ts.map +1 -1
- package/dist/tui/output-size-watch.d.ts +32 -0
- package/dist/tui/output-size-watch.d.ts.map +1 -0
- package/dist/tui/permission-review.d.ts.map +1 -1
- package/dist/tui/person-terms.d.ts +58 -0
- package/dist/tui/person-terms.d.ts.map +1 -0
- package/dist/tui/plain-failure.d.ts +27 -0
- package/dist/tui/plain-failure.d.ts.map +1 -0
- package/dist/tui/plain-interruption.d.ts +46 -0
- package/dist/tui/plain-interruption.d.ts.map +1 -0
- package/dist/tui/provider-list.d.ts.map +1 -1
- package/dist/tui/render-mode.d.ts +19 -0
- package/dist/tui/render-mode.d.ts.map +1 -0
- package/dist/tui/schedule/host-commands.d.ts +2 -9
- package/dist/tui/schedule/host-commands.d.ts.map +1 -1
- package/dist/tui/schedule/integration.d.ts +8 -0
- package/dist/tui/schedule/integration.d.ts.map +1 -1
- package/dist/tui/schedule/source-deliveries.d.ts +37 -0
- package/dist/tui/schedule/source-deliveries.d.ts.map +1 -0
- package/dist/tui/schedule/startup.d.ts.map +1 -1
- package/dist/tui/schedule/tool-host.d.ts +3 -1
- package/dist/tui/schedule/tool-host.d.ts.map +1 -1
- package/dist/tui/setup-text.d.ts +14 -0
- package/dist/tui/setup-text.d.ts.map +1 -0
- package/dist/tui/shell-escape.d.ts.map +1 -1
- package/dist/tui/skills/suggest-setting.d.ts.map +1 -1
- package/dist/tui/slashCommands.d.ts +4 -1
- package/dist/tui/slashCommands.d.ts.map +1 -1
- package/dist/tui/terminal-choice-text.d.ts +7 -0
- package/dist/tui/terminal-choice-text.d.ts.map +1 -1
- package/dist/tui/tidy-tool-output.d.ts +83 -0
- package/dist/tui/tidy-tool-output.d.ts.map +1 -0
- package/dist/tui/tool-presentation.d.ts +6 -0
- package/dist/tui/tool-presentation.d.ts.map +1 -0
- package/dist/tui/transcript-scroll.d.ts +73 -0
- package/dist/tui/transcript-scroll.d.ts.map +1 -0
- package/dist/tui/triggers/copy.d.ts.map +1 -1
- package/dist/tui/triggers/setting.d.ts.map +1 -1
- package/dist/tui/turn-interruption.d.ts +1 -1
- package/dist/tui/turn-interruption.d.ts.map +1 -1
- package/dist/tui/turn-limits-settings.d.ts +4 -4
- package/dist/tui/turn-limits-settings.d.ts.map +1 -1
- package/dist/tui/types.d.ts +10 -0
- package/dist/tui/types.d.ts.map +1 -1
- package/dist/tui/web-activity.d.ts +3 -2
- package/dist/tui/web-activity.d.ts.map +1 -1
- package/dist/tui/zen-free-refusal.d.ts +17 -0
- package/dist/tui/zen-free-refusal.d.ts.map +1 -0
- package/dist/usage-error.d.ts +15 -0
- package/dist/usage-error.d.ts.map +1 -0
- package/dist/warning-filter.d.ts +30 -0
- package/dist/warning-filter.d.ts.map +1 -0
- package/package.json +21 -10
- package/skills/schedule-task/SKILL.md +74 -20
- package/dist/browser/commands.js +0 -365
- package/dist/browser/commands.js.map +0 -1
- package/dist/browser/control.js +0 -140
- package/dist/browser/control.js.map +0 -1
- package/dist/browser/describe.js +0 -27
- package/dist/browser/describe.js.map +0 -1
- package/dist/checkpoints/store.js +0 -192
- package/dist/checkpoints/store.js.map +0 -1
- package/dist/checkpoints/wrap.js +0 -37
- package/dist/checkpoints/wrap.js.map +0 -1
- package/dist/cli.js +0 -602
- package/dist/cli.js.map +0 -1
- package/dist/commands/acp.js +0 -388
- package/dist/commands/acp.js.map +0 -1
- package/dist/commands/archive.js +0 -65
- package/dist/commands/archive.js.map +0 -1
- package/dist/commands/browser.js +0 -16
- package/dist/commands/browser.js.map +0 -1
- package/dist/commands/doctor.js +0 -267
- package/dist/commands/doctor.js.map +0 -1
- package/dist/commands/drain.js +0 -498
- package/dist/commands/drain.js.map +0 -1
- package/dist/commands/eval.js +0 -237
- package/dist/commands/eval.js.map +0 -1
- package/dist/commands/exec-flags.js +0 -334
- package/dist/commands/exec-flags.js.map +0 -1
- package/dist/commands/exec-json.js +0 -497
- package/dist/commands/exec-json.js.map +0 -1
- package/dist/commands/exec.js +0 -688
- package/dist/commands/exec.js.map +0 -1
- package/dist/commands/host-queries.js +0 -156
- package/dist/commands/host-queries.js.map +0 -1
- package/dist/commands/login.js +0 -315
- package/dist/commands/login.js.map +0 -1
- package/dist/commands/mcp-oauth-login.js +0 -213
- package/dist/commands/mcp-oauth-login.js.map +0 -1
- package/dist/commands/mcp.js +0 -461
- package/dist/commands/mcp.js.map +0 -1
- package/dist/commands/prior-messages.js +0 -329
- package/dist/commands/prior-messages.js.map +0 -1
- package/dist/commands/provider-wait.js +0 -65
- package/dist/commands/provider-wait.js.map +0 -1
- package/dist/commands/registry.js +0 -40
- package/dist/commands/registry.js.map +0 -1
- package/dist/commands/resident-flags.js +0 -193
- package/dist/commands/resident-flags.js.map +0 -1
- package/dist/commands/resident-learning.js +0 -293
- package/dist/commands/resident-learning.js.map +0 -1
- package/dist/commands/resident.js +0 -419
- package/dist/commands/resident.js.map +0 -1
- package/dist/commands/resume.js +0 -109
- package/dist/commands/resume.js.map +0 -1
- package/dist/commands/schedule.js +0 -131
- package/dist/commands/schedule.js.map +0 -1
- package/dist/commands/serve.js +0 -21
- package/dist/commands/serve.js.map +0 -1
- package/dist/commands/skills.js +0 -178
- package/dist/commands/skills.js.map +0 -1
- package/dist/commands/state.js +0 -110
- package/dist/commands/state.js.map +0 -1
- package/dist/commands/stdin.js +0 -69
- package/dist/commands/stdin.js.map +0 -1
- package/dist/commands/types.js +0 -2
- package/dist/commands/types.js.map +0 -1
- package/dist/commands/upgrade-progress.js +0 -54
- package/dist/commands/upgrade-progress.js.map +0 -1
- package/dist/commands/upgrade.js +0 -232
- package/dist/commands/upgrade.js.map +0 -1
- package/dist/commands/worktree.js +0 -86
- package/dist/commands/worktree.js.map +0 -1
- package/dist/config/composer-triggers.js +0 -80
- package/dist/config/composer-triggers.js.map +0 -1
- package/dist/config/debug.js +0 -126
- package/dist/config/debug.js.map +0 -1
- package/dist/config/load.js +0 -1208
- package/dist/config/load.js.map +0 -1
- package/dist/config/schema.js +0 -13
- package/dist/config/schema.js.map +0 -1
- package/dist/config/tool-result-screens.js +0 -104
- package/dist/config/tool-result-screens.js.map +0 -1
- package/dist/config/trusted-project-context.js +0 -28
- package/dist/config/trusted-project-context.js.map +0 -1
- package/dist/config/turn-guards.js +0 -46
- package/dist/config/turn-guards.js.map +0 -1
- package/dist/config/user-config.js +0 -118
- package/dist/config/user-config.js.map +0 -1
- package/dist/context/capabilities.js +0 -164
- package/dist/context/capabilities.js.map +0 -1
- package/dist/context/directories.js +0 -69
- package/dist/context/directories.js.map +0 -1
- package/dist/context/doctrine.js +0 -24
- package/dist/context/doctrine.js.map +0 -1
- package/dist/context/environment.js +0 -255
- package/dist/context/environment.js.map +0 -1
- package/dist/context/project-path.js +0 -16
- package/dist/context/project-path.js.map +0 -1
- package/dist/context/project-tracker.js +0 -217
- package/dist/context/project-tracker.js.map +0 -1
- package/dist/context/project.js +0 -256
- package/dist/context/project.js.map +0 -1
- package/dist/context/runtime-message.js +0 -30
- package/dist/context/runtime-message.js.map +0 -1
- package/dist/context/sandbox.js +0 -114
- package/dist/context/sandbox.js.map +0 -1
- package/dist/context/turn-snapshot.js +0 -122
- package/dist/context/turn-snapshot.js.map +0 -1
- package/dist/doctor/checks/browser.js +0 -63
- package/dist/doctor/checks/browser.js.map +0 -1
- package/dist/doctor/checks/chain.js +0 -211
- package/dist/doctor/checks/chain.js.map +0 -1
- package/dist/doctor/checks/credentials.js +0 -98
- package/dist/doctor/checks/credentials.js.map +0 -1
- package/dist/doctor/checks/index.js +0 -72
- package/dist/doctor/checks/index.js.map +0 -1
- package/dist/doctor/checks/invariants.js +0 -79
- package/dist/doctor/checks/invariants.js.map +0 -1
- package/dist/doctor/checks/logging.js +0 -69
- package/dist/doctor/checks/logging.js.map +0 -1
- package/dist/doctor/checks/providers.js +0 -30
- package/dist/doctor/checks/providers.js.map +0 -1
- package/dist/doctor/checks/runtime.js +0 -40
- package/dist/doctor/checks/runtime.js.map +0 -1
- package/dist/doctor/checks/sandbox.js +0 -76
- package/dist/doctor/checks/sandbox.js.map +0 -1
- package/dist/doctor/checks/scheduler.js +0 -74
- package/dist/doctor/checks/scheduler.js.map +0 -1
- package/dist/doctor/checks/session-export.js +0 -62
- package/dist/doctor/checks/session-export.js.map +0 -1
- package/dist/doctor/checks/telemetry.js +0 -58
- package/dist/doctor/checks/telemetry.js.map +0 -1
- package/dist/doctor/checks/vault.js +0 -67
- package/dist/doctor/checks/vault.js.map +0 -1
- package/dist/doctor/index.js +0 -3
- package/dist/doctor/index.js.map +0 -1
- package/dist/doctor/registry.js +0 -230
- package/dist/doctor/registry.js.map +0 -1
- package/dist/exit-codes.js +0 -62
- package/dist/exit-codes.js.map +0 -1
- package/dist/installation.js +0 -48
- package/dist/installation.js.map +0 -1
- package/dist/integrations/clipboard/image.js +0 -119
- package/dist/integrations/clipboard/image.js.map +0 -1
- package/dist/integrations/clipboard/text.js +0 -43
- package/dist/integrations/clipboard/text.js.map +0 -1
- package/dist/integrations/files/attachment-store.js +0 -86
- package/dist/integrations/files/attachment-store.js.map +0 -1
- package/dist/integrations/mcp/oauth-store.js +0 -549
- package/dist/integrations/mcp/oauth-store.js.map +0 -1
- package/dist/integrations/mcp/servers.js +0 -611
- package/dist/integrations/mcp/servers.js.map +0 -1
- package/dist/integrations/mcp/user-config.js +0 -92
- package/dist/integrations/mcp/user-config.js.map +0 -1
- package/dist/integrations/notifications/desktop/freedesktop.js +0 -33
- package/dist/integrations/notifications/desktop/freedesktop.js.map +0 -1
- package/dist/integrations/notifications/desktop/macos.js +0 -17
- package/dist/integrations/notifications/desktop/macos.js.map +0 -1
- package/dist/integrations/notifications/desktop/sanitize.js +0 -49
- package/dist/integrations/notifications/desktop/sanitize.js.map +0 -1
- package/dist/integrations/notifications/desktop/throttle.js +0 -39
- package/dist/integrations/notifications/desktop/throttle.js.map +0 -1
- package/dist/integrations/notifications/desktop/windows-toast.js +0 -56
- package/dist/integrations/notifications/desktop/windows-toast.js.map +0 -1
- package/dist/integrations/notifications/desktop.js +0 -199
- package/dist/integrations/notifications/desktop.js.map +0 -1
- package/dist/integrations/notifications/terminal.js +0 -46
- package/dist/integrations/notifications/terminal.js.map +0 -1
- package/dist/integrations/npm-invocation.js +0 -23
- package/dist/integrations/npm-invocation.js.map +0 -1
- package/dist/integrations/plugins/runtime.js +0 -189
- package/dist/integrations/plugins/runtime.js.map +0 -1
- package/dist/integrations/plugins/settings.js +0 -106
- package/dist/integrations/plugins/settings.js.map +0 -1
- package/dist/integrations/providers/access.js +0 -23
- package/dist/integrations/providers/access.js.map +0 -1
- package/dist/integrations/providers/chain-capabilities.js +0 -211
- package/dist/integrations/providers/chain-capabilities.js.map +0 -1
- package/dist/integrations/providers/codex-device-login.js +0 -195
- package/dist/integrations/providers/codex-device-login.js.map +0 -1
- package/dist/integrations/providers/codex-oauth.js +0 -95
- package/dist/integrations/providers/codex-oauth.js.map +0 -1
- package/dist/integrations/providers/credential-provider.js +0 -74
- package/dist/integrations/providers/credential-provider.js.map +0 -1
- package/dist/integrations/providers/credential-store.js +0 -657
- package/dist/integrations/providers/credential-store.js.map +0 -1
- package/dist/integrations/providers/current-credential.js +0 -45
- package/dist/integrations/providers/current-credential.js.map +0 -1
- package/dist/integrations/providers/discover.js +0 -313
- package/dist/integrations/providers/discover.js.map +0 -1
- package/dist/integrations/providers/gemini-credentials.js +0 -148
- package/dist/integrations/providers/gemini-credentials.js.map +0 -1
- package/dist/integrations/providers/harness-credentials.js +0 -344
- package/dist/integrations/providers/harness-credentials.js.map +0 -1
- package/dist/integrations/providers/identity.js +0 -64
- package/dist/integrations/providers/identity.js.map +0 -1
- package/dist/integrations/providers/index.js +0 -14
- package/dist/integrations/providers/index.js.map +0 -1
- package/dist/integrations/providers/keychain.js +0 -78
- package/dist/integrations/providers/keychain.js.map +0 -1
- package/dist/integrations/providers/model-reasoning.js +0 -51
- package/dist/integrations/providers/model-reasoning.js.map +0 -1
- package/dist/integrations/providers/oauth.js +0 -302
- package/dist/integrations/providers/oauth.js.map +0 -1
- package/dist/integrations/providers/preferences.js +0 -287
- package/dist/integrations/providers/preferences.js.map +0 -1
- package/dist/integrations/providers/register.js +0 -154
- package/dist/integrations/providers/register.js.map +0 -1
- package/dist/integrations/providers/registry.js +0 -289
- package/dist/integrations/providers/registry.js.map +0 -1
- package/dist/integrations/providers/setup.js +0 -158
- package/dist/integrations/providers/setup.js.map +0 -1
- package/dist/integrations/providers/subscription-login.js +0 -328
- package/dist/integrations/providers/subscription-login.js.map +0 -1
- package/dist/integrations/providers/zen-catalogue.js +0 -196
- package/dist/integrations/providers/zen-catalogue.js.map +0 -1
- package/dist/integrations/resident/foreground.js +0 -95
- package/dist/integrations/resident/foreground.js.map +0 -1
- package/dist/integrations/resident/inspection.js +0 -282
- package/dist/integrations/resident/inspection.js.map +0 -1
- package/dist/integrations/resident/learning-sources.js +0 -79
- package/dist/integrations/resident/learning-sources.js.map +0 -1
- package/dist/integrations/resident/learning-storage.js +0 -55
- package/dist/integrations/resident/learning-storage.js.map +0 -1
- package/dist/integrations/resident/lifecycle-errors.js +0 -15
- package/dist/integrations/resident/lifecycle-errors.js.map +0 -1
- package/dist/integrations/resident/owned-runner.js +0 -91
- package/dist/integrations/resident/owned-runner.js.map +0 -1
- package/dist/integrations/resident/runner-control.js +0 -238
- package/dist/integrations/resident/runner-control.js.map +0 -1
- package/dist/integrations/resident/runner-launch.js +0 -142
- package/dist/integrations/resident/runner-launch.js.map +0 -1
- package/dist/integrations/resident/runner-store.js +0 -284
- package/dist/integrations/resident/runner-store.js.map +0 -1
- package/dist/integrations/resident/session-log-reads.js +0 -125
- package/dist/integrations/resident/session-log-reads.js.map +0 -1
- package/dist/integrations/resident/session-step.js +0 -476
- package/dist/integrations/resident/session-step.js.map +0 -1
- package/dist/integrations/resident/storage.js +0 -183
- package/dist/integrations/resident/storage.js.map +0 -1
- package/dist/integrations/resident/tool-evidence.js +0 -123
- package/dist/integrations/resident/tool-evidence.js.map +0 -1
- package/dist/integrations/resident/verification.js +0 -109
- package/dist/integrations/resident/verification.js.map +0 -1
- package/dist/integrations/sessions/checkpoint-view.js +0 -48
- package/dist/integrations/sessions/checkpoint-view.js.map +0 -1
- package/dist/integrations/sessions/context-inventory.js +0 -44
- package/dist/integrations/sessions/context-inventory.js.map +0 -1
- package/dist/integrations/sessions/conversation-search.js +0 -572
- package/dist/integrations/sessions/conversation-search.js.map +0 -1
- package/dist/integrations/sessions/display-title.js +0 -5
- package/dist/integrations/sessions/display-title.js.map +0 -1
- package/dist/integrations/sessions/evidence-page-validation.js +0 -74
- package/dist/integrations/sessions/evidence-page-validation.js.map +0 -1
- package/dist/integrations/sessions/evidence-recall.js +0 -117
- package/dist/integrations/sessions/evidence-recall.js.map +0 -1
- package/dist/integrations/sessions/store.js +0 -780
- package/dist/integrations/sessions/store.js.map +0 -1
- package/dist/integrations/sessions/task-context.js +0 -96
- package/dist/integrations/sessions/task-context.js.map +0 -1
- package/dist/integrations/sessions/transcript-export.js +0 -342
- package/dist/integrations/sessions/transcript-export.js.map +0 -1
- package/dist/integrations/state/home.js +0 -17
- package/dist/integrations/state/home.js.map +0 -1
- package/dist/integrations/state/identity.js +0 -49
- package/dist/integrations/state/identity.js.map +0 -1
- package/dist/integrations/state/immutable-json.js +0 -38
- package/dist/integrations/state/immutable-json.js.map +0 -1
- package/dist/integrations/state/private-directory.js +0 -43
- package/dist/integrations/state/private-directory.js.map +0 -1
- package/dist/integrations/state/project.js +0 -13
- package/dist/integrations/state/project.js.map +0 -1
- package/dist/integrations/state/report.js +0 -626
- package/dist/integrations/state/report.js.map +0 -1
- package/dist/integrations/state/retention.js +0 -18
- package/dist/integrations/state/retention.js.map +0 -1
- package/dist/integrations/subagents/NamzuCliAgent.js +0 -9
- package/dist/integrations/subagents/NamzuCliAgent.js.map +0 -1
- package/dist/integrations/subagents/activity.js +0 -759
- package/dist/integrations/subagents/activity.js.map +0 -1
- package/dist/integrations/subagents/batches.js +0 -172
- package/dist/integrations/subagents/batches.js.map +0 -1
- package/dist/integrations/subagents/definitions.js +0 -26
- package/dist/integrations/subagents/definitions.js.map +0 -1
- package/dist/integrations/subagents/model-effort.js +0 -12
- package/dist/integrations/subagents/model-effort.js.map +0 -1
- package/dist/integrations/subagents/parent.js +0 -47
- package/dist/integrations/subagents/parent.js.map +0 -1
- package/dist/integrations/subagents/policy.js +0 -3
- package/dist/integrations/subagents/policy.js.map +0 -1
- package/dist/integrations/subagents/replay.js +0 -295
- package/dist/integrations/subagents/replay.js.map +0 -1
- package/dist/integrations/subagents/runtime.js +0 -1317
- package/dist/integrations/subagents/runtime.js.map +0 -1
- package/dist/integrations/subagents/saved-agents.js +0 -102
- package/dist/integrations/subagents/saved-agents.js.map +0 -1
- package/dist/integrations/subagents/slash.js +0 -45
- package/dist/integrations/subagents/slash.js.map +0 -1
- package/dist/integrations/subagents/worktree-driver.js +0 -72
- package/dist/integrations/subagents/worktree-driver.js.map +0 -1
- package/dist/integrations/telemetry/session-export.js +0 -119
- package/dist/integrations/telemetry/session-export.js.map +0 -1
- package/dist/integrations/trust/store.js +0 -73
- package/dist/integrations/trust/store.js.map +0 -1
- package/dist/integrations/updates.js +0 -115
- package/dist/integrations/updates.js.map +0 -1
- package/dist/integrations/web/exa-search.js +0 -154
- package/dist/integrations/web/exa-search.js.map +0 -1
- package/dist/integrations/web/open-url.js +0 -73
- package/dist/integrations/web/open-url.js.map +0 -1
- package/dist/integrations/web/search.js +0 -68
- package/dist/integrations/web/search.js.map +0 -1
- package/dist/integrations/worktrees/managed.js +0 -231
- package/dist/integrations/worktrees/managed.js.map +0 -1
- package/dist/logging.js +0 -115
- package/dist/logging.js.map +0 -1
- package/dist/memory/io.js +0 -177
- package/dist/memory/io.js.map +0 -1
- package/dist/memory/presentation.js +0 -76
- package/dist/memory/presentation.js.map +0 -1
- package/dist/memory/store.js +0 -180
- package/dist/memory/store.js.map +0 -1
- package/dist/memory/typed.js +0 -336
- package/dist/memory/typed.js.map +0 -1
- package/dist/output/formatter.js +0 -16
- package/dist/output/formatter.js.map +0 -1
- package/dist/output/index.js +0 -22
- package/dist/output/index.js.map +0 -1
- package/dist/output/json.js +0 -51
- package/dist/output/json.js.map +0 -1
- package/dist/output/text.js +0 -50
- package/dist/output/text.js.map +0 -1
- package/dist/output/yaml.js +0 -26
- package/dist/output/yaml.js.map +0 -1
- package/dist/output-schema.js +0 -18
- package/dist/output-schema.js.map +0 -1
- package/dist/permissions/browser-sites.js +0 -270
- package/dist/permissions/browser-sites.js.map +0 -1
- package/dist/permissions/canonical-project.js +0 -13
- package/dist/permissions/canonical-project.js.map +0 -1
- package/dist/permissions/checks.js +0 -128
- package/dist/permissions/checks.js.map +0 -1
- package/dist/permissions/headless-trust.js +0 -86
- package/dist/permissions/headless-trust.js.map +0 -1
- package/dist/permissions/live-mode.js +0 -62
- package/dist/permissions/live-mode.js.map +0 -1
- package/dist/permissions/mode.js +0 -65
- package/dist/permissions/mode.js.map +0 -1
- package/dist/permissions/rules.js +0 -358
- package/dist/permissions/rules.js.map +0 -1
- package/dist/release-notes.js +0 -64
- package/dist/release-notes.js.map +0 -1
- package/dist/resume-invocation.js +0 -24
- package/dist/resume-invocation.js.map +0 -1
- package/dist/schedule/build.js +0 -374
- package/dist/schedule/build.js.map +0 -1
- package/dist/schedule/changes.js +0 -78
- package/dist/schedule/changes.js.map +0 -1
- package/dist/schedule/commands/add.js +0 -603
- package/dist/schedule/commands/add.js.map +0 -1
- package/dist/schedule/commands/args.js +0 -80
- package/dist/schedule/commands/args.js.map +0 -1
- package/dist/schedule/commands/confirm-prompt.js +0 -21
- package/dist/schedule/commands/confirm-prompt.js.map +0 -1
- package/dist/schedule/commands/lifecycle.js +0 -586
- package/dist/schedule/commands/lifecycle.js.map +0 -1
- package/dist/schedule/commands/list.js +0 -260
- package/dist/schedule/commands/list.js.map +0 -1
- package/dist/schedule/commands/logs.js +0 -106
- package/dist/schedule/commands/logs.js.map +0 -1
- package/dist/schedule/commands/service.js +0 -458
- package/dist/schedule/commands/service.js.map +0 -1
- package/dist/schedule/daemon/daemon.js +0 -1265
- package/dist/schedule/daemon/daemon.js.map +0 -1
- package/dist/schedule/daemon/endpoint.js +0 -158
- package/dist/schedule/daemon/endpoint.js.map +0 -1
- package/dist/schedule/daemon/exit.js +0 -8
- package/dist/schedule/daemon/exit.js.map +0 -1
- package/dist/schedule/daemon/log.js +0 -53
- package/dist/schedule/daemon/log.js.map +0 -1
- package/dist/schedule/daemon/notify.js +0 -158
- package/dist/schedule/daemon/notify.js.map +0 -1
- package/dist/schedule/daemon/retention.js +0 -46
- package/dist/schedule/daemon/retention.js.map +0 -1
- package/dist/schedule/daemon/sessions.js +0 -52
- package/dist/schedule/daemon/sessions.js.map +0 -1
- package/dist/schedule/env.js +0 -106
- package/dist/schedule/env.js.map +0 -1
- package/dist/schedule/fire/browser-preflight.js +0 -73
- package/dist/schedule/fire/browser-preflight.js.map +0 -1
- package/dist/schedule/fire/calls.js +0 -114
- package/dist/schedule/fire/calls.js.map +0 -1
- package/dist/schedule/fire/fire.js +0 -681
- package/dist/schedule/fire/fire.js.map +0 -1
- package/dist/schedule/fire/result.js +0 -19
- package/dist/schedule/fire/result.js.map +0 -1
- package/dist/schedule/fire/run-script.js +0 -81
- package/dist/schedule/fire/run-script.js.map +0 -1
- package/dist/schedule/fire/unattended-note.js +0 -51
- package/dist/schedule/fire/unattended-note.js.map +0 -1
- package/dist/schedule/fire/wake-gate.js +0 -90
- package/dist/schedule/fire/wake-gate.js.map +0 -1
- package/dist/schedule/floor.js +0 -1561
- package/dist/schedule/floor.js.map +0 -1
- package/dist/schedule/folder.js +0 -84
- package/dist/schedule/folder.js.map +0 -1
- package/dist/schedule/paths.js +0 -53
- package/dist/schedule/paths.js.map +0 -1
- package/dist/schedule/policy.js +0 -414
- package/dist/schedule/policy.js.map +0 -1
- package/dist/schedule/resume-command.js +0 -72
- package/dist/schedule/resume-command.js.map +0 -1
- package/dist/schedule/script-check.js +0 -146
- package/dist/schedule/script-check.js.map +0 -1
- package/dist/schedule/script-shell.js +0 -5
- package/dist/schedule/script-shell.js.map +0 -1
- package/dist/schedule/service/detect.js +0 -29
- package/dist/schedule/service/detect.js.map +0 -1
- package/dist/schedule/service/index.js +0 -361
- package/dist/schedule/service/index.js.map +0 -1
- package/dist/schedule/service/launchd.js +0 -84
- package/dist/schedule/service/launchd.js.map +0 -1
- package/dist/schedule/service/manifest.js +0 -16
- package/dist/schedule/service/manifest.js.map +0 -1
- package/dist/schedule/service/names.js +0 -22
- package/dist/schedule/service/names.js.map +0 -1
- package/dist/schedule/service/quote.js +0 -64
- package/dist/schedule/service/quote.js.map +0 -1
- package/dist/schedule/service/runner.js +0 -31
- package/dist/schedule/service/runner.js.map +0 -1
- package/dist/schedule/service/systemd.js +0 -96
- package/dist/schedule/service/systemd.js.map +0 -1
- package/dist/schedule/service/windows-task.js +0 -199
- package/dist/schedule/service/windows-task.js.map +0 -1
- package/dist/schedule/service/wsl.js +0 -121
- package/dist/schedule/service/wsl.js.map +0 -1
- package/dist/schedule/store/atomic.js +0 -138
- package/dist/schedule/store/atomic.js.map +0 -1
- package/dist/schedule/store/claims.js +0 -57
- package/dist/schedule/store/claims.js.map +0 -1
- package/dist/schedule/store/digest.js +0 -139
- package/dist/schedule/store/digest.js.map +0 -1
- package/dist/schedule/store/history.js +0 -117
- package/dist/schedule/store/history.js.map +0 -1
- package/dist/schedule/store/jobs.js +0 -277
- package/dist/schedule/store/jobs.js.map +0 -1
- package/dist/schedule/store/state.js +0 -38
- package/dist/schedule/store/state.js.map +0 -1
- package/dist/schedule/types.js +0 -33
- package/dist/schedule/types.js.map +0 -1
- package/dist/schedule/visible-source.js +0 -59
- package/dist/schedule/visible-source.js.map +0 -1
- package/dist/skills/audit.js +0 -75
- package/dist/skills/audit.js.map +0 -1
- package/dist/skills/catalog.js +0 -226
- package/dist/skills/catalog.js.map +0 -1
- package/dist/skills/directory.js +0 -51
- package/dist/skills/directory.js.map +0 -1
- package/dist/skills/save.js +0 -344
- package/dist/skills/save.js.map +0 -1
- package/dist/skills/store.js +0 -351
- package/dist/skills/store.js.map +0 -1
- package/dist/termination.js +0 -143
- package/dist/termination.js.map +0 -1
- package/dist/test-support/toolset.js +0 -27
- package/dist/test-support/toolset.js.map +0 -1
- package/dist/tui/AgentExplorer.js +0 -789
- package/dist/tui/AgentExplorer.js.map +0 -1
- package/dist/tui/App.js +0 -8499
- package/dist/tui/App.js.map +0 -1
- package/dist/tui/BackgroundJobsPanel.js +0 -129
- package/dist/tui/BackgroundJobsPanel.js.map +0 -1
- package/dist/tui/BrandHeader.js +0 -14
- package/dist/tui/BrandHeader.js.map +0 -1
- package/dist/tui/Checklist.js +0 -90
- package/dist/tui/Checklist.js.map +0 -1
- package/dist/tui/ChoicePicker.js +0 -64
- package/dist/tui/ChoicePicker.js.map +0 -1
- package/dist/tui/Composer.js +0 -939
- package/dist/tui/Composer.js.map +0 -1
- package/dist/tui/ComposerFrame.js +0 -79
- package/dist/tui/ComposerFrame.js.map +0 -1
- package/dist/tui/CopyPicker.js +0 -19
- package/dist/tui/CopyPicker.js.map +0 -1
- package/dist/tui/EditPromptPicker.js +0 -17
- package/dist/tui/EditPromptPicker.js.map +0 -1
- package/dist/tui/EffortSlider.js +0 -134
- package/dist/tui/EffortSlider.js.map +0 -1
- package/dist/tui/LiveActivity.js +0 -89
- package/dist/tui/LiveActivity.js.map +0 -1
- package/dist/tui/Markdown.js +0 -137
- package/dist/tui/Markdown.js.map +0 -1
- package/dist/tui/PendingInputPanel.js +0 -108
- package/dist/tui/PendingInputPanel.js.map +0 -1
- package/dist/tui/PermissionOverlay.js +0 -278
- package/dist/tui/PermissionOverlay.js.map +0 -1
- package/dist/tui/Picker.js +0 -1310
- package/dist/tui/Picker.js.map +0 -1
- package/dist/tui/ProviderSetup.js +0 -125
- package/dist/tui/ProviderSetup.js.map +0 -1
- package/dist/tui/ResumePicker.js +0 -34
- package/dist/tui/ResumePicker.js.map +0 -1
- package/dist/tui/SaveSkillOverlay.js +0 -118
- package/dist/tui/SaveSkillOverlay.js.map +0 -1
- package/dist/tui/ScheduleReviewOverlay.js +0 -166
- package/dist/tui/ScheduleReviewOverlay.js.map +0 -1
- package/dist/tui/StatusBar.js +0 -182
- package/dist/tui/StatusBar.js.map +0 -1
- package/dist/tui/StatusPanel.js +0 -11
- package/dist/tui/StatusPanel.js.map +0 -1
- package/dist/tui/TaskList.js +0 -43
- package/dist/tui/TaskList.js.map +0 -1
- package/dist/tui/TextPrompt.js +0 -185
- package/dist/tui/TextPrompt.js.map +0 -1
- package/dist/tui/ToolOutputViewer.js +0 -39
- package/dist/tui/ToolOutputViewer.js.map +0 -1
- package/dist/tui/Transcript.js +0 -235
- package/dist/tui/Transcript.js.map +0 -1
- package/dist/tui/TrustPrompt.js +0 -13
- package/dist/tui/TrustPrompt.js.map +0 -1
- package/dist/tui/ViewportBound.js +0 -55
- package/dist/tui/ViewportBound.js.map +0 -1
- package/dist/tui/agent-transcript-rows.js +0 -115
- package/dist/tui/agent-transcript-rows.js.map +0 -1
- package/dist/tui/agent.js +0 -4301
- package/dist/tui/agent.js.map +0 -1
- package/dist/tui/browser-notices.js +0 -107
- package/dist/tui/browser-notices.js.map +0 -1
- package/dist/tui/choice-selection.js +0 -38
- package/dist/tui/choice-selection.js.map +0 -1
- package/dist/tui/compact-transcript.js +0 -46
- package/dist/tui/compact-transcript.js.map +0 -1
- package/dist/tui/consent-timing.js +0 -48
- package/dist/tui/consent-timing.js.map +0 -1
- package/dist/tui/conversation-evidence-view.js +0 -96
- package/dist/tui/conversation-evidence-view.js.map +0 -1
- package/dist/tui/conversation-history.js +0 -33
- package/dist/tui/conversation-history.js.map +0 -1
- package/dist/tui/copy-targets.js +0 -189
- package/dist/tui/copy-targets.js.map +0 -1
- package/dist/tui/credential-entry.js +0 -134
- package/dist/tui/credential-entry.js.map +0 -1
- package/dist/tui/edit-prompts.js +0 -35
- package/dist/tui/edit-prompts.js.map +0 -1
- package/dist/tui/exit-summary.js +0 -30
- package/dist/tui/exit-summary.js.map +0 -1
- package/dist/tui/external-editor.js +0 -169
- package/dist/tui/external-editor.js.map +0 -1
- package/dist/tui/hypermode.js +0 -58
- package/dist/tui/hypermode.js.map +0 -1
- package/dist/tui/index.js +0 -81
- package/dist/tui/index.js.map +0 -1
- package/dist/tui/live-window.js +0 -281
- package/dist/tui/live-window.js.map +0 -1
- package/dist/tui/log-pane.js +0 -100
- package/dist/tui/log-pane.js.map +0 -1
- package/dist/tui/login-prompt.js +0 -105
- package/dist/tui/login-prompt.js.map +0 -1
- package/dist/tui/logo.js +0 -9
- package/dist/tui/logo.js.map +0 -1
- package/dist/tui/markdown-block-cache.js +0 -76
- package/dist/tui/markdown-block-cache.js.map +0 -1
- package/dist/tui/markdown-table.js +0 -175
- package/dist/tui/markdown-table.js.map +0 -1
- package/dist/tui/markdown-wrap.js +0 -189
- package/dist/tui/markdown-wrap.js.map +0 -1
- package/dist/tui/markdownParser.js +0 -237
- package/dist/tui/markdownParser.js.map +0 -1
- package/dist/tui/mentions.js +0 -150
- package/dist/tui/mentions.js.map +0 -1
- package/dist/tui/model-catalogue-view.js +0 -75
- package/dist/tui/model-catalogue-view.js.map +0 -1
- package/dist/tui/model-choices.js +0 -157
- package/dist/tui/model-choices.js.map +0 -1
- package/dist/tui/model-search.js +0 -28
- package/dist/tui/model-search.js.map +0 -1
- package/dist/tui/model-selection-intent.js +0 -96
- package/dist/tui/model-selection-intent.js.map +0 -1
- package/dist/tui/model-switch-tool.js +0 -74
- package/dist/tui/model-switch-tool.js.map +0 -1
- package/dist/tui/model-switch.js +0 -106
- package/dist/tui/model-switch.js.map +0 -1
- package/dist/tui/notices.js +0 -27
- package/dist/tui/notices.js.map +0 -1
- package/dist/tui/open-browser.js +0 -147
- package/dist/tui/open-browser.js.map +0 -1
- package/dist/tui/permission-review.js +0 -858
- package/dist/tui/permission-review.js.map +0 -1
- package/dist/tui/plugin-view.js +0 -59
- package/dist/tui/plugin-view.js.map +0 -1
- package/dist/tui/provider-list.js +0 -327
- package/dist/tui/provider-list.js.map +0 -1
- package/dist/tui/provider-selection.js +0 -16
- package/dist/tui/provider-selection.js.map +0 -1
- package/dist/tui/schedule/host-commands.js +0 -428
- package/dist/tui/schedule/host-commands.js.map +0 -1
- package/dist/tui/schedule/integration.js +0 -150
- package/dist/tui/schedule/integration.js.map +0 -1
- package/dist/tui/schedule/loop-host.js +0 -153
- package/dist/tui/schedule/loop-host.js.map +0 -1
- package/dist/tui/schedule/resume.js +0 -333
- package/dist/tui/schedule/resume.js.map +0 -1
- package/dist/tui/schedule/startup.js +0 -121
- package/dist/tui/schedule/startup.js.map +0 -1
- package/dist/tui/schedule/tool-host.js +0 -619
- package/dist/tui/schedule/tool-host.js.map +0 -1
- package/dist/tui/selection-window.js +0 -37
- package/dist/tui/selection-window.js.map +0 -1
- package/dist/tui/shell-escape.js +0 -110
- package/dist/tui/shell-escape.js.map +0 -1
- package/dist/tui/skills/learning.js +0 -131
- package/dist/tui/skills/learning.js.map +0 -1
- package/dist/tui/skills/suggest-setting.js +0 -55
- package/dist/tui/skills/suggest-setting.js.map +0 -1
- package/dist/tui/skills/suggestion-ledger.js +0 -52
- package/dist/tui/skills/suggestion-ledger.js.map +0 -1
- package/dist/tui/slashCommands.js +0 -1588
- package/dist/tui/slashCommands.js.map +0 -1
- package/dist/tui/status-card.js +0 -30
- package/dist/tui/status-card.js.map +0 -1
- package/dist/tui/status-panel-layout.js +0 -42
- package/dist/tui/status-panel-layout.js.map +0 -1
- package/dist/tui/stream-blocks.js +0 -187
- package/dist/tui/stream-blocks.js.map +0 -1
- package/dist/tui/task-activity.js +0 -157
- package/dist/tui/task-activity.js.map +0 -1
- package/dist/tui/terminal-choice-text.js +0 -118
- package/dist/tui/terminal-choice-text.js.map +0 -1
- package/dist/tui/terminal-display.js +0 -65
- package/dist/tui/terminal-display.js.map +0 -1
- package/dist/tui/terminal-hyperlinks.js +0 -70
- package/dist/tui/terminal-hyperlinks.js.map +0 -1
- package/dist/tui/theme.js +0 -34
- package/dist/tui/theme.js.map +0 -1
- package/dist/tui/triggers/analyze.js +0 -221
- package/dist/tui/triggers/analyze.js.map +0 -1
- package/dist/tui/triggers/context-text.js +0 -44
- package/dist/tui/triggers/context-text.js.map +0 -1
- package/dist/tui/triggers/copy.js +0 -163
- package/dist/tui/triggers/copy.js.map +0 -1
- package/dist/tui/triggers/detect.js +0 -295
- package/dist/tui/triggers/detect.js.map +0 -1
- package/dist/tui/triggers/fold.js +0 -44
- package/dist/tui/triggers/fold.js.map +0 -1
- package/dist/tui/triggers/pattern.js +0 -243
- package/dist/tui/triggers/pattern.js.map +0 -1
- package/dist/tui/triggers/provenance.js +0 -98
- package/dist/tui/triggers/provenance.js.map +0 -1
- package/dist/tui/triggers/registry.js +0 -164
- package/dist/tui/triggers/registry.js.map +0 -1
- package/dist/tui/triggers/setting.js +0 -61
- package/dist/tui/triggers/setting.js.map +0 -1
- package/dist/tui/triggers/verbs.js +0 -140
- package/dist/tui/triggers/verbs.js.map +0 -1
- package/dist/tui/turn-interruption.js +0 -160
- package/dist/tui/turn-interruption.js.map +0 -1
- package/dist/tui/turn-limits-settings.js +0 -88
- package/dist/tui/turn-limits-settings.js.map +0 -1
- package/dist/tui/types.js +0 -7
- package/dist/tui/types.js.map +0 -1
- package/dist/tui/units.js +0 -20
- package/dist/tui/units.js.map +0 -1
- package/dist/tui/use-selection-index.js +0 -13
- package/dist/tui/use-selection-index.js.map +0 -1
- package/dist/tui/web-activity.js +0 -105
- package/dist/tui/web-activity.js.map +0 -1
- package/dist/tui/workspace-diff.js +0 -101
- package/dist/tui/workspace-diff.js.map +0 -1
- package/dist/tui/workspace-review.js +0 -67
- package/dist/tui/workspace-review.js.map +0 -1
- package/dist/user-commands/store.js +0 -235
- package/dist/user-commands/store.js.map +0 -1
- package/dist/version.js +0 -23
- package/dist/version.js.map +0 -1
package/dist/tui/Picker.js
DELETED
|
@@ -1,1310 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
/**
|
|
3
|
-
* First-run / re-pick provider selector.
|
|
4
|
-
*
|
|
5
|
-
* Renders the credentials the discoverer found (env / keychain / local
|
|
6
|
-
* probes) and lets the user pick a primary LLM provider for the TUI's own
|
|
7
|
-
* chat. Keyboard-only. The dispatch path that turns the selection into a
|
|
8
|
-
* live agent session lives in `agent.ts`.
|
|
9
|
-
*/
|
|
10
|
-
import { Box, Text, useInput, useWindowSize } from 'ink';
|
|
11
|
-
import { Fragment, useCallback, useEffect, useRef, useState } from 'react';
|
|
12
|
-
import { canSelectModel, hasApiCredential } from '../integrations/providers/access.js';
|
|
13
|
-
import { ALL_PROVIDER_IDS, PROVIDER_REGISTRY, signedInSubscriptionProviders, unsupportedProviderMessage, } from '../integrations/providers/index.js';
|
|
14
|
-
import { describeProviderModels, verifyCredential } from './agent.js';
|
|
15
|
-
import { classifyCredential, describeDisposition, keyLooksUsable, maskKey, sessionCredential, } from './credential-entry.js';
|
|
16
|
-
import { modelStep } from './model-choices.js';
|
|
17
|
-
import { filterModelChoices } from './model-search.js';
|
|
18
|
-
import { credentialNeed, initialProviderRow, pathProviderId, providerListRows, rowCredentialNeed, rowHasProvider, rowIndexOfProvider, rowIsUsable, rowNeedsChoice, typedCredentialEntry, } from './provider-list.js';
|
|
19
|
-
import { moveSelection, selectionWindow, } from './selection-window.js';
|
|
20
|
-
import { capChoiceLines, choiceDisplayWidth, eraseLastChoiceGrapheme, truncateChoiceText, wrapChoiceText, } from './terminal-choice-text.js';
|
|
21
|
-
import { terminalDisplayText } from './terminal-display.js';
|
|
22
|
-
import { theme } from './theme.js';
|
|
23
|
-
import { useSelectionIndex } from './use-selection-index.js';
|
|
24
|
-
/**
|
|
25
|
-
* Columns this screen's text area has, given the terminal's width.
|
|
26
|
-
*
|
|
27
|
-
* Derived rather than written down, because the number this replaces was a
|
|
28
|
-
* literal that counted two of the three things that take columns and forgot the
|
|
29
|
-
* third. In order:
|
|
30
|
-
*
|
|
31
|
-
* - `HOST_INSET_X` — the app draws every screen inside a box with one column
|
|
32
|
-
* of padding on each side (`App.tsx`'s root), so this picker's own box starts
|
|
33
|
-
* one column in and ends one column short of the terminal.
|
|
34
|
-
* - `BORDER_X` — this box's round border, one column per side.
|
|
35
|
-
* - `BOX_PADDING_X` — this box's `paddingX={1}`, one column per side.
|
|
36
|
-
*
|
|
37
|
-
* The old arithmetic was `columns - 4`: the border and the padding, minus the
|
|
38
|
-
* host's inset. At 60 columns that budgeted 56 columns of text for an area of
|
|
39
|
-
* 54 — measured from a 60-column capture, where the two borders sit at columns
|
|
40
|
-
* 1 and 58, leaving 56 between them and 54 inside the padding. Every row the
|
|
41
|
-
* screen measured as fitting therefore wrapped, and the text it wrapped was the
|
|
42
|
-
* row the cursor was on.
|
|
43
|
-
*/
|
|
44
|
-
const HOST_INSET_X = 2;
|
|
45
|
-
const BORDER_X = 2;
|
|
46
|
-
const BOX_PADDING_X = 2;
|
|
47
|
-
/** Columns a row of this screen's content may occupy. */
|
|
48
|
-
export function pickerContentWidth(columns) {
|
|
49
|
-
return Math.max(1, columns - HOST_INSET_X - BORDER_X - BOX_PADDING_X);
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Columns a row spends before its source: the marker, the number and the
|
|
53
|
-
* vendor's name, each written over its own width.
|
|
54
|
-
*
|
|
55
|
-
* Derived from the three, because 32 was written down here once and was the
|
|
56
|
-
* width of the BROKEN row — the one whose marker had lost the space beside it.
|
|
57
|
-
* A source measured against a row one column narrower than it is a source that
|
|
58
|
-
* wraps in the renderer after the screen has counted it as one line, which is
|
|
59
|
-
* the defect this whole window exists to prevent.
|
|
60
|
-
*/
|
|
61
|
-
const ROW_MARKER_WIDTH = 2;
|
|
62
|
-
const ROW_NUMBER_WIDTH = 3;
|
|
63
|
-
const ROW_LABEL_WIDTH = 28;
|
|
64
|
-
const ROW_PREFIX_WIDTH = ROW_MARKER_WIDTH + ROW_NUMBER_WIDTH + ROW_LABEL_WIDTH;
|
|
65
|
-
/** What a wrapped source line is indented by, so it lines up under the name. */
|
|
66
|
-
const ROW_INDENT = ' '.repeat(ROW_PREFIX_WIDTH);
|
|
67
|
-
/**
|
|
68
|
-
* Lines a row's source column may take before the rest is cut.
|
|
69
|
-
*
|
|
70
|
-
* Three is what a variable name needs at the width this was measured against
|
|
71
|
-
* (54 columns leaves 22 for the source, so `env · OPENROUTER_API_KEY` wraps to
|
|
72
|
-
* two). It is a cap rather than a measurement because a row's height is part of
|
|
73
|
-
* the box's height: without one, a forty-column terminal could make a single
|
|
74
|
-
* source a dozen lines and no window could keep the header on screen.
|
|
75
|
-
*/
|
|
76
|
-
const MAX_SOURCE_LINES = 3;
|
|
77
|
-
/** The words above the not-detected block, which the row window reserves lines for. */
|
|
78
|
-
const NOT_DETECTED_HEADING = 'Not detected — enter a credential to use these:';
|
|
79
|
-
/**
|
|
80
|
-
* The line above the box that is not the box's.
|
|
81
|
-
*
|
|
82
|
-
* Ink draws this screen below whatever the app has already written — the boot
|
|
83
|
-
* banner, on the turn that shows this picker first — and a terminal keeps the
|
|
84
|
-
* last `rows` lines of all of it. A box that fills the terminal exactly
|
|
85
|
-
* therefore loses its own top border, and under that border is the notice the
|
|
86
|
-
* screen exists to deliver.
|
|
87
|
-
*/
|
|
88
|
-
const TRANSCRIPT_LINE_ABOVE = 1;
|
|
89
|
-
/** The mark a row carries when it is the provider in force. */
|
|
90
|
-
const CURRENT_MARK = ' ← current';
|
|
91
|
-
/**
|
|
92
|
-
* Columns a row's source must keep before it shares its line with that mark.
|
|
93
|
-
*
|
|
94
|
-
* Twenty is the shortest this column can be and still be read: an environment
|
|
95
|
-
* variable name (`DEEPSEEK_API_KEY` is sixteen, with the word `needs` before it
|
|
96
|
-
* and the `←` mark is twelve columns of its own. Below twenty the mark moves
|
|
97
|
-
* down a line rather than cutting the answer in half.
|
|
98
|
-
*/
|
|
99
|
-
const MIN_SOURCE_COLUMNS = 20;
|
|
100
|
-
/** What `s` does, printed above the list on the screens that offer it. */
|
|
101
|
-
const SETUP_HINT = 's provider setup · check installations and access';
|
|
102
|
-
/**
|
|
103
|
-
* What the screen that found nothing says, and the reason it says it.
|
|
104
|
-
*
|
|
105
|
-
* Here rather than inline because the row window counts these lines before it
|
|
106
|
-
* draws a single row: they are the operator's only way off that screen, so they
|
|
107
|
-
* are reserved first and a row is drawn with what is left over.
|
|
108
|
-
*/
|
|
109
|
-
const EMPTY_SCREEN_INTRO = 'namzu scans these sources, in order, for an LLM credential:';
|
|
110
|
-
const EMPTY_SCREEN_HINTS = {
|
|
111
|
-
signIn: 'to sign in with a subscription — no API key, and namzu keeps it for next time.',
|
|
112
|
-
paste: 'to paste a credential now.',
|
|
113
|
-
durable: 'You can also set one of the env vars above (or start a local server) and restart.',
|
|
114
|
-
};
|
|
115
|
-
/** The sources the empty screen lists — the same set the summary line names. */
|
|
116
|
-
function emptyScreenSourceLines() {
|
|
117
|
-
return [
|
|
118
|
-
` · existing ${subscriptionProviders()
|
|
119
|
-
.map((entry) => entry.label)
|
|
120
|
-
.join(' and ')} sessions on this device`,
|
|
121
|
-
' · subscriptions signed in to from namzu (~/.namzu/credentials.json)',
|
|
122
|
-
' · env vars / API keys (optional alternatives: ANTHROPIC_API_KEY, OPENAI_API_KEY, …)',
|
|
123
|
-
' · local servers (Ollama localhost:11434, LM Studio localhost:1234)',
|
|
124
|
-
];
|
|
125
|
-
}
|
|
126
|
-
function subscriptionProviders() {
|
|
127
|
-
return ALL_PROVIDER_IDS.map((id) => PROVIDER_REGISTRY[id]).filter((entry) => entry.subscriptionLogin !== undefined);
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* The subscription screen offers two different operations and names both.
|
|
131
|
-
*
|
|
132
|
-
* A detected subscription session is already usable and must not be presented
|
|
133
|
-
* as a new OAuth flow. Conversely, a provider with no usable device session is
|
|
134
|
-
* still a valid new sign-in target. Keeping both rows means `/login` can switch
|
|
135
|
-
* to an owner CLI session without overwriting it, while still allowing a fresh
|
|
136
|
-
* Namzu-owned credential when the operator explicitly asks for one.
|
|
137
|
-
*/
|
|
138
|
-
function subscriptionChoices(detected) {
|
|
139
|
-
return [
|
|
140
|
-
...signedInSubscriptionProviders(detected).map((provider) => ({
|
|
141
|
-
kind: 'existing',
|
|
142
|
-
detected: provider,
|
|
143
|
-
})),
|
|
144
|
-
...subscriptionProviders().map((entry) => ({ kind: 'sign-in', entry })),
|
|
145
|
-
];
|
|
146
|
-
}
|
|
147
|
-
function signInChoiceIndex(choices, provider) {
|
|
148
|
-
return choices.findIndex((choice) => choice.kind === 'sign-in' && choice.entry.id === provider);
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
* The provider `k` opens entry for.
|
|
152
|
-
*
|
|
153
|
-
* The highlighted row's own provider whenever the vendor takes a typed
|
|
154
|
-
* credential. This screen used to answer the question from the registry
|
|
155
|
-
* instead: the saved provider if the picker was open because of one, and
|
|
156
|
-
* otherwise the first key-capable entry, which is a provider the operator may
|
|
157
|
-
* not have been looking at. A list you can move through is a list the key
|
|
158
|
-
* beside it has to follow.
|
|
159
|
-
*
|
|
160
|
-
* A row whose vendor takes none — a local server — falls through to the saved
|
|
161
|
-
* provider this picker was opened for: that route is why the notice above says
|
|
162
|
-
* `k`, and it must keep working when the cursor happens to sit on a row that
|
|
163
|
-
* cannot use it.
|
|
164
|
-
*
|
|
165
|
-
* Returns null when there is nothing here to enter a credential for, which the
|
|
166
|
-
* caller says out loud rather than presenting a field that leads nowhere.
|
|
167
|
-
*/
|
|
168
|
-
function keyEntryTarget(row, keyEntryFor) {
|
|
169
|
-
const onThisRow = typedCredentialEntry(row);
|
|
170
|
-
if (onThisRow)
|
|
171
|
-
return onThisRow;
|
|
172
|
-
if (keyEntryFor) {
|
|
173
|
-
const entry = PROVIDER_REGISTRY[keyEntryFor];
|
|
174
|
-
if (entry?.acceptsTypedCredential)
|
|
175
|
-
return entry;
|
|
176
|
-
}
|
|
177
|
-
return null;
|
|
178
|
-
}
|
|
179
|
-
export function Picker({ detected, currentProvider, selectionKind = 'provider-and-model', currentModel, initialView = 'providers', onSubmit, onCancel, onSetup, describeModels = describeProviderModels, onCredential, onLogin, onLoginComplete, verify = verifyCredential, keyEntryFor, notice, cancelExits = false, }) {
|
|
180
|
-
/**
|
|
181
|
-
* The one foreign operation still allowed to publish into this picker.
|
|
182
|
-
*
|
|
183
|
-
* A promise is not cancelled by unmounting the component that started it.
|
|
184
|
-
* The generation prevents a late result from writing state or invoking an
|
|
185
|
-
* external callback; the controller releases cooperative transports as soon
|
|
186
|
-
* as the operator changes their mind.
|
|
187
|
-
*/
|
|
188
|
-
const operationGenerationRef = useRef(0);
|
|
189
|
-
const operationRef = useRef(null);
|
|
190
|
-
const invalidateOperation = useCallback(() => {
|
|
191
|
-
operationGenerationRef.current += 1;
|
|
192
|
-
operationRef.current?.controller.abort(new Error('The picker operation was cancelled.'));
|
|
193
|
-
operationRef.current = null;
|
|
194
|
-
}, []);
|
|
195
|
-
const beginOperation = useCallback(() => {
|
|
196
|
-
invalidateOperation();
|
|
197
|
-
const operation = {
|
|
198
|
-
generation: operationGenerationRef.current,
|
|
199
|
-
controller: new AbortController(),
|
|
200
|
-
};
|
|
201
|
-
operationRef.current = operation;
|
|
202
|
-
return operation;
|
|
203
|
-
}, [invalidateOperation]);
|
|
204
|
-
const ownsOperation = useCallback((operation) => operationRef.current === operation &&
|
|
205
|
-
operationGenerationRef.current === operation.generation &&
|
|
206
|
-
!operation.controller.signal.aborted, []);
|
|
207
|
-
const finishOperation = useCallback((operation) => {
|
|
208
|
-
if (operationRef.current === operation)
|
|
209
|
-
operationRef.current = null;
|
|
210
|
-
}, []);
|
|
211
|
-
useEffect(() => invalidateOperation, [invalidateOperation]);
|
|
212
|
-
// The list this screen draws: what was detected, then every provider this
|
|
213
|
-
// build could construct if the operator supplied a credential.
|
|
214
|
-
//
|
|
215
|
-
// `detected` is still the discovery result and is still what the header
|
|
216
|
-
// counts, what the sign-in screen offers and what a submitted choice is
|
|
217
|
-
// built from. This is the screen, not the machine.
|
|
218
|
-
//
|
|
219
|
-
// The signed-in-subscription screen takes the detected rows alone: it asks
|
|
220
|
-
// which already-usable session to use, and a row that needs a key first
|
|
221
|
-
// makes that sentence false.
|
|
222
|
-
const rows = providerListRows(detected, selectionKind !== 'signed-in-subscription');
|
|
223
|
-
// Whether `k` is offered at all, read once so the hint below and the key
|
|
224
|
-
// handler cannot disagree about it. The handler adds the phase guards,
|
|
225
|
-
// because it runs on every screen this picker draws and this expression is
|
|
226
|
-
// computed only for the list.
|
|
227
|
-
const keyEntryOffered = onCredential !== undefined && selectionKind !== 'signed-in-subscription';
|
|
228
|
-
// The cursor is an index into whichever list the screen is drawing, and the
|
|
229
|
-
// sign-in screen draws `subscriptionChoices` while the provider list draws
|
|
230
|
-
// these rows, which is longer by however many providers can be set up from
|
|
231
|
-
// here. An index resolved against one and read against the other selects
|
|
232
|
-
// nothing at all, which is how `/login` came up with no row highlighted and
|
|
233
|
-
// an Enter that did nothing on the machine below: a saved preference naming
|
|
234
|
-
// a saved provider resolved to its row in the provider list, which is past the end
|
|
235
|
-
// of a three-row sign-in list.
|
|
236
|
-
const initialSelection = initialView === 'subscriptions' ? 0 : initialProviderRow(rows, currentProvider, keyEntryFor);
|
|
237
|
-
const { selection: cursor, selectionRef: cursorRef, setSelection: setCursor, } = useSelectionIndex(initialSelection);
|
|
238
|
-
// How wide this screen's text is, and how many lines its notice takes, both
|
|
239
|
-
// of which the row window is sized against — see the list below.
|
|
240
|
-
const terminal = useWindowSize();
|
|
241
|
-
const contentWidth = pickerContentWidth(terminal.columns ?? 80);
|
|
242
|
-
const noticeLines = notice ? wrapChoiceText(notice, contentWidth).length : 0;
|
|
243
|
-
const [errorHint, setErrorHint] = useState(null);
|
|
244
|
-
// The ref makes a pasted query followed immediately by Enter use the new
|
|
245
|
-
// filtered list, even before React has drawn another frame. Null keeps the
|
|
246
|
-
// existing provider and numeric shortcuts available outside search.
|
|
247
|
-
const [modelQuery, setModelQuery] = useState(null);
|
|
248
|
-
const modelQueryRef = useRef(null);
|
|
249
|
-
// `null` while choosing a provider. Once a provider is accepted this holds
|
|
250
|
-
// the model step, and `undefined` inside it means the listing is in flight.
|
|
251
|
-
const [modelPhase, setModelPhase] = useState(null);
|
|
252
|
-
const [loginPhase, setLoginPhase] = useState(initialView === 'subscriptions');
|
|
253
|
-
useEffect(() => {
|
|
254
|
-
setLoginPhase(initialView === 'subscriptions');
|
|
255
|
-
if (initialView !== 'models')
|
|
256
|
-
setModelPhase(null);
|
|
257
|
-
}, [initialView]);
|
|
258
|
-
const [loginEntry, setLoginEntry] = useState(null);
|
|
259
|
-
// Key entry. `value` is the secret and never leaves this component except as
|
|
260
|
-
// a mask or as the credential handed to `onCredential`.
|
|
261
|
-
//
|
|
262
|
-
// The provider is held as the ENTRY, not as an index into a filtered registry
|
|
263
|
-
// list. The index form could only ever address the first key-capable
|
|
264
|
-
// provider, because nothing on this screen changed it — so a credential typed
|
|
265
|
-
// for a saved provider would have been built for a different one.
|
|
266
|
-
const [keyEntry, setKeyEntry] = useState(null);
|
|
267
|
-
// The vendor whose ways in are being chosen, while that screen is up.
|
|
268
|
-
//
|
|
269
|
-
// Held as the vendor's id and resolved against `rows` on every render, not as
|
|
270
|
-
// a row object: `rows` is derived from the props on each render, and a stored
|
|
271
|
-
// row would be the list as it looked on the keystroke that opened this screen.
|
|
272
|
-
// The screen is only ever reached from a row, so the lookup cannot come back
|
|
273
|
-
// empty while it is up.
|
|
274
|
-
const [pathVendor, setPathVendor] = useState(null);
|
|
275
|
-
const pathRow = pathVendor === null ? null : (rows.find((row) => row.vendor === pathVendor) ?? null);
|
|
276
|
-
const openModels = useCallback((current, returnToProviders = true) => {
|
|
277
|
-
const operation = beginOperation();
|
|
278
|
-
modelQueryRef.current = null;
|
|
279
|
-
setModelQuery(null);
|
|
280
|
-
setModelPhase({ provider: current, step: undefined, returnToProviders });
|
|
281
|
-
setCursor(0);
|
|
282
|
-
const activeModel = currentProvider == null || currentProvider === current.entry.id
|
|
283
|
-
? (currentModel ?? undefined)
|
|
284
|
-
: undefined;
|
|
285
|
-
const showListing = (listing) => {
|
|
286
|
-
if (!ownsOperation(operation))
|
|
287
|
-
return;
|
|
288
|
-
finishOperation(operation);
|
|
289
|
-
const step = modelStep(current.entry.defaultModel, listing, activeModel, {
|
|
290
|
-
allowModel: (id) => canSelectModel(current.entry, current.apiKey, id),
|
|
291
|
-
});
|
|
292
|
-
const experimentalNotice = current.entry.id === 'zen' && !hasApiCredential(current.entry, current.apiKey)
|
|
293
|
-
? 'Zen free models are experimental. OpenCode installation is recommended; Namzu sends requests directly, and the gateway may refuse them.'
|
|
294
|
-
: null;
|
|
295
|
-
setModelPhase({
|
|
296
|
-
provider: current,
|
|
297
|
-
step: experimentalNotice
|
|
298
|
-
? { ...step, notice: [experimentalNotice, step.notice].filter(Boolean).join(' ') }
|
|
299
|
-
: step,
|
|
300
|
-
returnToProviders,
|
|
301
|
-
});
|
|
302
|
-
setCursor(step.initialIndex);
|
|
303
|
-
};
|
|
304
|
-
void describeModels(current.entry.id, current, operation.controller.signal)
|
|
305
|
-
.then(showListing)
|
|
306
|
-
.catch((error) => showListing({
|
|
307
|
-
kind: 'failed',
|
|
308
|
-
reason: error instanceof Error ? error.message : String(error),
|
|
309
|
-
}));
|
|
310
|
-
}, [
|
|
311
|
-
beginOperation,
|
|
312
|
-
currentModel,
|
|
313
|
-
currentProvider,
|
|
314
|
-
describeModels,
|
|
315
|
-
finishOperation,
|
|
316
|
-
ownsOperation,
|
|
317
|
-
setCursor,
|
|
318
|
-
]);
|
|
319
|
-
const initialModelsOpened = useRef(false);
|
|
320
|
-
useEffect(() => {
|
|
321
|
-
if (initialView !== 'models' || initialModelsOpened.current)
|
|
322
|
-
return;
|
|
323
|
-
initialModelsOpened.current = true;
|
|
324
|
-
const current = detected.find((provider) => provider.entry.id === currentProvider);
|
|
325
|
-
if (current?.entry.constructible)
|
|
326
|
-
openModels(current, false);
|
|
327
|
-
else
|
|
328
|
-
setErrorHint('The current provider is unavailable here. Choose another provider.');
|
|
329
|
-
}, [currentProvider, detected, initialView, openModels]);
|
|
330
|
-
const acceptKey = async () => {
|
|
331
|
-
const state = keyEntry;
|
|
332
|
-
if (!state)
|
|
333
|
-
return;
|
|
334
|
-
const { entry } = state;
|
|
335
|
-
const shape = keyLooksUsable(state.value);
|
|
336
|
-
if (!shape.ok) {
|
|
337
|
-
setKeyEntry({ ...state, status: 'typing', problem: shape.reason });
|
|
338
|
-
return;
|
|
339
|
-
}
|
|
340
|
-
setKeyEntry({ ...state, status: 'checking' });
|
|
341
|
-
const cred = sessionCredential(entry, state.value);
|
|
342
|
-
// Classified from the value the operator pasted, and read from the SAME
|
|
343
|
-
// function the session layer picks the wire header with, so the sentence
|
|
344
|
-
// on screen cannot disagree with the request that follows it.
|
|
345
|
-
const kind = classifyCredential(entry, state.value);
|
|
346
|
-
const operation = beginOperation();
|
|
347
|
-
let verification;
|
|
348
|
-
try {
|
|
349
|
-
verification = await verify(entry.id, cred, operation.controller.signal);
|
|
350
|
-
}
|
|
351
|
-
catch {
|
|
352
|
-
if (!ownsOperation(operation))
|
|
353
|
-
return;
|
|
354
|
-
finishOperation(operation);
|
|
355
|
-
setKeyEntry({
|
|
356
|
-
...state,
|
|
357
|
-
status: 'typing',
|
|
358
|
-
problem: 'The credential check failed before the provider answered. Nothing was stored.',
|
|
359
|
-
});
|
|
360
|
-
return;
|
|
361
|
-
}
|
|
362
|
-
if (!ownsOperation(operation))
|
|
363
|
-
return;
|
|
364
|
-
if (verification.kind === 'rejected') {
|
|
365
|
-
finishOperation(operation);
|
|
366
|
-
// Stays on the screen with the key intact so a one-character typo is
|
|
367
|
-
// fixable. The reason is the provider's, never the key.
|
|
368
|
-
setKeyEntry({
|
|
369
|
-
...state,
|
|
370
|
-
status: 'typing',
|
|
371
|
-
problem: describeDisposition(entry, verification, kind),
|
|
372
|
-
});
|
|
373
|
-
return;
|
|
374
|
-
}
|
|
375
|
-
// Keep this generation owned through App's session construction. Esc or
|
|
376
|
-
// another choice aborts it, so a late session cannot replace the newer one.
|
|
377
|
-
onCredential?.(cred, describeDisposition(entry, verification, kind), operation.controller.signal);
|
|
378
|
-
};
|
|
379
|
-
const acceptLogin = async () => {
|
|
380
|
-
const entry = loginEntry;
|
|
381
|
-
const operation = operationRef.current;
|
|
382
|
-
if (!entry || entry.status !== 'typing' || !operation || !onLoginComplete)
|
|
383
|
-
return;
|
|
384
|
-
if (entry.value.trim().length === 0) {
|
|
385
|
-
setLoginEntry({
|
|
386
|
-
...entry,
|
|
387
|
-
problem: 'Paste the authorization code or finished address first.',
|
|
388
|
-
});
|
|
389
|
-
return;
|
|
390
|
-
}
|
|
391
|
-
setLoginEntry({ ...entry, status: 'checking', problem: undefined });
|
|
392
|
-
try {
|
|
393
|
-
const disposition = await onLoginComplete(entry.value, operation.controller.signal);
|
|
394
|
-
if (!ownsOperation(operation))
|
|
395
|
-
return;
|
|
396
|
-
if (disposition === 'retry') {
|
|
397
|
-
setLoginEntry({
|
|
398
|
-
...entry,
|
|
399
|
-
status: 'typing',
|
|
400
|
-
problem: 'That value could not finish this sign-in. Check the address or code and try again.',
|
|
401
|
-
});
|
|
402
|
-
return;
|
|
403
|
-
}
|
|
404
|
-
finishOperation(operation);
|
|
405
|
-
setLoginEntry(null);
|
|
406
|
-
}
|
|
407
|
-
catch (error) {
|
|
408
|
-
if (!ownsOperation(operation))
|
|
409
|
-
return;
|
|
410
|
-
setLoginEntry({
|
|
411
|
-
...entry,
|
|
412
|
-
status: 'typing',
|
|
413
|
-
problem: `Could not finish sign-in: ${error instanceof Error ? error.message : String(error)}`,
|
|
414
|
-
});
|
|
415
|
-
}
|
|
416
|
-
};
|
|
417
|
-
/**
|
|
418
|
-
* Start a subscription sign-in for one provider.
|
|
419
|
-
*
|
|
420
|
-
* Written once and reached from two places — the sign-in screen's own Enter,
|
|
421
|
-
* and the sign-in path inside a vendor row — because two copies of this would
|
|
422
|
-
* be two places for the device-code wording, the operation's ownership and the
|
|
423
|
-
* failure sentence to drift apart. It is one operation either way, so an esc
|
|
424
|
-
* from either leaves nothing running behind the screen.
|
|
425
|
-
*/
|
|
426
|
-
const startSignIn = (entry) => {
|
|
427
|
-
if (!entry.subscriptionLogin)
|
|
428
|
-
return;
|
|
429
|
-
if (!onLogin) {
|
|
430
|
-
setErrorHint('Subscription sign-in is not available on this screen.');
|
|
431
|
-
return;
|
|
432
|
-
}
|
|
433
|
-
const operation = beginOperation();
|
|
434
|
-
setPathVendor(null);
|
|
435
|
-
setLoginEntry({ entry, value: '', status: 'starting' });
|
|
436
|
-
void onLogin(entry.id, operation.controller.signal)
|
|
437
|
-
.then((disposition) => {
|
|
438
|
-
if (!ownsOperation(operation))
|
|
439
|
-
return;
|
|
440
|
-
if (disposition === 'awaiting-input') {
|
|
441
|
-
setLoginEntry({
|
|
442
|
-
entry,
|
|
443
|
-
value: '',
|
|
444
|
-
status: 'typing',
|
|
445
|
-
});
|
|
446
|
-
return;
|
|
447
|
-
}
|
|
448
|
-
finishOperation(operation);
|
|
449
|
-
setLoginEntry(null);
|
|
450
|
-
})
|
|
451
|
-
.catch((error) => {
|
|
452
|
-
if (!ownsOperation(operation))
|
|
453
|
-
return;
|
|
454
|
-
finishOperation(operation);
|
|
455
|
-
setLoginEntry(null);
|
|
456
|
-
setErrorHint(`Could not start sign-in: ${error instanceof Error ? error.message : String(error)}`);
|
|
457
|
-
});
|
|
458
|
-
};
|
|
459
|
-
/**
|
|
460
|
-
* Follow one way in to the flow that already exists for it.
|
|
461
|
-
*
|
|
462
|
-
* The three arms are the three flows this screen already had; nothing here
|
|
463
|
-
* builds a credential. A detected path goes on to the model step exactly as
|
|
464
|
-
* Enter on a detected row always has. A credential path opens the paste field
|
|
465
|
-
* for its provider, so the value still travels `setKeyEntry` → `acceptKey` →
|
|
466
|
-
* the session credential. A sign-in path starts the operation `l` starts.
|
|
467
|
-
*/
|
|
468
|
-
const takePath = (path) => {
|
|
469
|
-
if (path.kind === 'detected') {
|
|
470
|
-
const current = path.detected;
|
|
471
|
-
if (selectionKind === 'signed-in-subscription') {
|
|
472
|
-
const operation = beginOperation();
|
|
473
|
-
onSubmit({ provider: current.entry.id }, operation.controller.signal);
|
|
474
|
-
return;
|
|
475
|
-
}
|
|
476
|
-
setPathVendor(null);
|
|
477
|
-
openModels(current);
|
|
478
|
-
return;
|
|
479
|
-
}
|
|
480
|
-
if (path.kind === 'credential') {
|
|
481
|
-
if (!onCredential) {
|
|
482
|
-
setErrorHint(`No credential can be entered for ${path.entry.label} on this screen.`);
|
|
483
|
-
return;
|
|
484
|
-
}
|
|
485
|
-
invalidateOperation();
|
|
486
|
-
setPathVendor(null);
|
|
487
|
-
setKeyEntry({ entry: path.entry, value: '', status: 'typing' });
|
|
488
|
-
return;
|
|
489
|
-
}
|
|
490
|
-
startSignIn(path.entry);
|
|
491
|
-
};
|
|
492
|
-
useInput((input, key) => {
|
|
493
|
-
if (loginEntry) {
|
|
494
|
-
if (key.escape) {
|
|
495
|
-
invalidateOperation();
|
|
496
|
-
setLoginEntry(null);
|
|
497
|
-
return;
|
|
498
|
-
}
|
|
499
|
-
if (loginEntry.status !== 'typing')
|
|
500
|
-
return;
|
|
501
|
-
if (key.return) {
|
|
502
|
-
void acceptLogin();
|
|
503
|
-
return;
|
|
504
|
-
}
|
|
505
|
-
if (key.backspace || key.delete) {
|
|
506
|
-
setLoginEntry((current) => current
|
|
507
|
-
? {
|
|
508
|
-
...current,
|
|
509
|
-
value: current.value.slice(0, -1),
|
|
510
|
-
problem: undefined,
|
|
511
|
-
}
|
|
512
|
-
: current);
|
|
513
|
-
return;
|
|
514
|
-
}
|
|
515
|
-
if (input && !key.ctrl && !key.meta) {
|
|
516
|
-
setLoginEntry((current) => current ? { ...current, value: current.value + input, problem: undefined } : current);
|
|
517
|
-
}
|
|
518
|
-
return;
|
|
519
|
-
}
|
|
520
|
-
// Key entry owns the keyboard while it is open: every printable character
|
|
521
|
-
// is part of a secret, so nothing here may fall through to a shortcut.
|
|
522
|
-
if (keyEntry) {
|
|
523
|
-
if (key.escape) {
|
|
524
|
-
invalidateOperation();
|
|
525
|
-
setKeyEntry(null);
|
|
526
|
-
return;
|
|
527
|
-
}
|
|
528
|
-
if (keyEntry.status === 'checking')
|
|
529
|
-
return;
|
|
530
|
-
if (key.return) {
|
|
531
|
-
void acceptKey();
|
|
532
|
-
return;
|
|
533
|
-
}
|
|
534
|
-
if (key.backspace || key.delete) {
|
|
535
|
-
setKeyEntry((k) => (k ? { ...k, value: k.value.slice(0, -1), status: 'typing' } : k));
|
|
536
|
-
return;
|
|
537
|
-
}
|
|
538
|
-
if (input && !key.ctrl && !key.meta) {
|
|
539
|
-
setKeyEntry((k) => (k ? { ...k, value: k.value + input, status: 'typing' } : k));
|
|
540
|
-
}
|
|
541
|
-
return;
|
|
542
|
-
}
|
|
543
|
-
// One vendor's ways in. Modal like the two screens above: while it is up it
|
|
544
|
-
// owns the keyboard, so `k`, `l` and `s` cannot act on a list that is not
|
|
545
|
-
// the one on screen. Escape returns to the row that opened it rather than
|
|
546
|
-
// to the top, because the cursor here is an index into this vendor's paths
|
|
547
|
-
// and would otherwise be read as a position in the list.
|
|
548
|
-
if (pathRow) {
|
|
549
|
-
if (key.escape) {
|
|
550
|
-
invalidateOperation();
|
|
551
|
-
setPathVendor(null);
|
|
552
|
-
setCursor(Math.max(0, rows.findIndex((row) => row.vendor === pathRow.vendor)));
|
|
553
|
-
return;
|
|
554
|
-
}
|
|
555
|
-
if (key.home || key.end || key.pageUp || key.pageDown) {
|
|
556
|
-
setCursor((current) => moveSelection(current, pathRow.paths.length, key.home ? 'first' : key.end ? 'last' : key.pageUp ? 'previous-page' : 'next-page'));
|
|
557
|
-
return;
|
|
558
|
-
}
|
|
559
|
-
if (key.upArrow) {
|
|
560
|
-
setCursor((current) => moveSelection(current, pathRow.paths.length, 'previous'));
|
|
561
|
-
return;
|
|
562
|
-
}
|
|
563
|
-
if (key.downArrow) {
|
|
564
|
-
setCursor((current) => moveSelection(current, pathRow.paths.length, 'next'));
|
|
565
|
-
return;
|
|
566
|
-
}
|
|
567
|
-
if (key.return) {
|
|
568
|
-
const chosen = pathRow.paths[cursorRef.current];
|
|
569
|
-
if (!chosen)
|
|
570
|
-
return;
|
|
571
|
-
takePath(chosen);
|
|
572
|
-
return;
|
|
573
|
-
}
|
|
574
|
-
const selected = Number.parseInt(input, 10);
|
|
575
|
-
if (Number.isFinite(selected) && selected >= 1 && selected <= pathRow.paths.length) {
|
|
576
|
-
setCursor(selected - 1);
|
|
577
|
-
}
|
|
578
|
-
return;
|
|
579
|
-
}
|
|
580
|
-
// `k` opens credential entry for the highlighted row — see
|
|
581
|
-
// `keyEntryTarget` for which provider that resolves to when the row takes
|
|
582
|
-
// no typed credential. The empty screen has always offered it (there,
|
|
583
|
-
// entering a credential is the only thing that can happen), and the
|
|
584
|
-
// populated one used to offer it only when `keyEntryFor` was set: someone
|
|
585
|
-
// with a working credential was not the person this was for. True then,
|
|
586
|
-
// and false for the operator this screen was opened for, who has a saved
|
|
587
|
-
// provider with no credential and a local server that happens to be
|
|
588
|
-
// running — they arrived at a list that named every provider except a way
|
|
589
|
-
// to fix the one they chose. The letter does not collide with anything:
|
|
590
|
-
// navigation is arrows and digits, and the model step owns its own keys.
|
|
591
|
-
//
|
|
592
|
-
// Two phases are guarded out. The model step types into search, so `k`
|
|
593
|
-
// there is a character and not a shortcut. The sign-in screen numbers its
|
|
594
|
-
// own choices, so the cursor indexes those rather than these rows, and a
|
|
595
|
-
// key read through it would name a provider nobody chose.
|
|
596
|
-
// `l` starts a Namzu-owned subscription sign-in from the general provider
|
|
597
|
-
// screen as well as the empty one. The already-signed-in choice deliberately
|
|
598
|
-
// omits it: external auth exists there, and a newly stored credential would
|
|
599
|
-
// lose to that external source on the required discovery re-read.
|
|
600
|
-
const loginTarget = keyEntryFor ? PROVIDER_REGISTRY[keyEntryFor] : undefined;
|
|
601
|
-
// Sign-in is an alternative to every provider source, including an API key
|
|
602
|
-
// or local server that discovery happened to find. Hiding `l` on a
|
|
603
|
-
// populated first-run list made those optional sources act like a decision
|
|
604
|
-
// the operator had already made. The model step remains model-only.
|
|
605
|
-
const canLogin = onLogin !== undefined && modelPhase === null && selectionKind !== 'signed-in-subscription';
|
|
606
|
-
if (canLogin && (input === 'l' || input === 'L')) {
|
|
607
|
-
invalidateOperation();
|
|
608
|
-
setLoginPhase(true);
|
|
609
|
-
const choices = subscriptionChoices(detected);
|
|
610
|
-
setCursor(loginTarget?.subscriptionLogin
|
|
611
|
-
? Math.max(0, signInChoiceIndex(choices, loginTarget.id))
|
|
612
|
-
: 0);
|
|
613
|
-
return;
|
|
614
|
-
}
|
|
615
|
-
if (!modelPhase && !loginPhase && input === 's' && onSetup) {
|
|
616
|
-
invalidateOperation();
|
|
617
|
-
onSetup();
|
|
618
|
-
return;
|
|
619
|
-
}
|
|
620
|
-
const highlighted = rows[cursorRef.current];
|
|
621
|
-
if (!loginPhase &&
|
|
622
|
-
modelPhase === null &&
|
|
623
|
-
keyEntryOffered &&
|
|
624
|
-
(input === 'k' || input === 'K')) {
|
|
625
|
-
const target = keyEntryTarget(highlighted, keyEntryFor);
|
|
626
|
-
if (target) {
|
|
627
|
-
invalidateOperation();
|
|
628
|
-
setKeyEntry({ entry: target, value: '', status: 'typing' });
|
|
629
|
-
}
|
|
630
|
-
else {
|
|
631
|
-
setErrorHint(highlighted
|
|
632
|
-
? `${highlighted.label} does not take a typed credential — choose a provider that does.`
|
|
633
|
-
: 'No provider here takes a typed credential.');
|
|
634
|
-
}
|
|
635
|
-
return;
|
|
636
|
-
}
|
|
637
|
-
if (modelPhase &&
|
|
638
|
-
(key.leftArrow || (modelQueryRef.current === null && (input === 'p' || input === 'P')))) {
|
|
639
|
-
invalidateOperation();
|
|
640
|
-
setCursor(Math.max(0, rowIndexOfProvider(rows, modelPhase.provider.entry.id)));
|
|
641
|
-
setModelPhase(null);
|
|
642
|
-
return;
|
|
643
|
-
}
|
|
644
|
-
if (key.escape) {
|
|
645
|
-
if (loginPhase) {
|
|
646
|
-
invalidateOperation();
|
|
647
|
-
setLoginPhase(false);
|
|
648
|
-
setCursor(0);
|
|
649
|
-
return;
|
|
650
|
-
}
|
|
651
|
-
// From the model step, back to the provider list rather than out of
|
|
652
|
-
// the picker: escape should undo one decision, not two.
|
|
653
|
-
if (modelPhase) {
|
|
654
|
-
invalidateOperation();
|
|
655
|
-
if (!modelPhase.returnToProviders) {
|
|
656
|
-
onCancel();
|
|
657
|
-
return;
|
|
658
|
-
}
|
|
659
|
-
setCursor(Math.max(0, rowIndexOfProvider(rows, modelPhase.provider.entry.id)));
|
|
660
|
-
setModelPhase(null);
|
|
661
|
-
return;
|
|
662
|
-
}
|
|
663
|
-
invalidateOperation();
|
|
664
|
-
onCancel();
|
|
665
|
-
return;
|
|
666
|
-
}
|
|
667
|
-
if (loginPhase) {
|
|
668
|
-
const choices = subscriptionChoices(detected);
|
|
669
|
-
if (key.home || key.end || key.pageUp || key.pageDown) {
|
|
670
|
-
setCursor((current) => moveSelection(current, choices.length, key.home ? 'first' : key.end ? 'last' : key.pageUp ? 'previous-page' : 'next-page'));
|
|
671
|
-
return;
|
|
672
|
-
}
|
|
673
|
-
if (key.upArrow) {
|
|
674
|
-
setCursor((current) => moveSelection(current, choices.length, 'previous'));
|
|
675
|
-
return;
|
|
676
|
-
}
|
|
677
|
-
if (key.downArrow) {
|
|
678
|
-
setCursor((current) => moveSelection(current, choices.length, 'next'));
|
|
679
|
-
return;
|
|
680
|
-
}
|
|
681
|
-
if (key.return) {
|
|
682
|
-
const chosen = choices[cursorRef.current];
|
|
683
|
-
if (!chosen)
|
|
684
|
-
return;
|
|
685
|
-
if (chosen.kind === 'existing') {
|
|
686
|
-
const operation = beginOperation();
|
|
687
|
-
onSubmit({ provider: chosen.detected.entry.id }, operation.controller.signal);
|
|
688
|
-
return;
|
|
689
|
-
}
|
|
690
|
-
startSignIn(chosen.entry);
|
|
691
|
-
return;
|
|
692
|
-
}
|
|
693
|
-
const selected = Number.parseInt(input, 10);
|
|
694
|
-
if (Number.isFinite(selected) && selected >= 1 && selected <= choices.length) {
|
|
695
|
-
setCursor(selected - 1);
|
|
696
|
-
}
|
|
697
|
-
return;
|
|
698
|
-
}
|
|
699
|
-
if (modelPhase) {
|
|
700
|
-
const step = modelPhase.step;
|
|
701
|
-
if (!step)
|
|
702
|
-
return; // still listing; ignore input rather than act on a stale list
|
|
703
|
-
const choices = filterModelChoices(step.choices, modelQueryRef.current ?? '');
|
|
704
|
-
const updateQuery = (next) => {
|
|
705
|
-
const selectedId = choices[cursorRef.current]?.id;
|
|
706
|
-
const filtered = filterModelChoices(step.choices, next ?? '');
|
|
707
|
-
modelQueryRef.current = next;
|
|
708
|
-
setModelQuery(next);
|
|
709
|
-
setCursor(Math.max(0, filtered.findIndex((choice) => choice.id === selectedId)));
|
|
710
|
-
setErrorHint(null);
|
|
711
|
-
};
|
|
712
|
-
if (key.home || key.end || key.pageUp || key.pageDown) {
|
|
713
|
-
setCursor((current) => moveSelection(current, choices.length, key.home ? 'first' : key.end ? 'last' : key.pageUp ? 'previous-page' : 'next-page'));
|
|
714
|
-
return;
|
|
715
|
-
}
|
|
716
|
-
if (key.upArrow) {
|
|
717
|
-
setCursor((current) => moveSelection(current, choices.length, 'previous'));
|
|
718
|
-
return;
|
|
719
|
-
}
|
|
720
|
-
if (key.downArrow) {
|
|
721
|
-
setCursor((current) => moveSelection(current, choices.length, 'next'));
|
|
722
|
-
return;
|
|
723
|
-
}
|
|
724
|
-
if (key.return) {
|
|
725
|
-
const chosen = choices[cursorRef.current];
|
|
726
|
-
if (!chosen) {
|
|
727
|
-
return;
|
|
728
|
-
}
|
|
729
|
-
const operation = beginOperation();
|
|
730
|
-
onSubmit({ provider: modelPhase.provider.entry.id, model: chosen.id }, operation.controller.signal);
|
|
731
|
-
return;
|
|
732
|
-
}
|
|
733
|
-
if (key.ctrl && input === 'u') {
|
|
734
|
-
updateQuery(null);
|
|
735
|
-
return;
|
|
736
|
-
}
|
|
737
|
-
if (key.ctrl || key.meta || key.rightArrow || key.tab)
|
|
738
|
-
return;
|
|
739
|
-
if (key.backspace || key.delete) {
|
|
740
|
-
const next = eraseLastChoiceGrapheme(modelQueryRef.current ?? '');
|
|
741
|
-
updateQuery(next || null);
|
|
742
|
-
return;
|
|
743
|
-
}
|
|
744
|
-
if (modelQueryRef.current === null && /^\d+$/.test(input)) {
|
|
745
|
-
const n = Number(input);
|
|
746
|
-
if (n >= 1 && n <= choices.length)
|
|
747
|
-
setCursor(n - 1);
|
|
748
|
-
return;
|
|
749
|
-
}
|
|
750
|
-
if (modelQueryRef.current === null && input === '/') {
|
|
751
|
-
updateQuery('');
|
|
752
|
-
return;
|
|
753
|
-
}
|
|
754
|
-
const text = input.replace(/\p{Cc}/gu, '');
|
|
755
|
-
if (text)
|
|
756
|
-
updateQuery(((modelQueryRef.current ?? '') + text).slice(0, 512));
|
|
757
|
-
return;
|
|
758
|
-
}
|
|
759
|
-
if (key.home || key.end || key.pageUp || key.pageDown) {
|
|
760
|
-
setCursor((current) => moveSelection(current, rows.length, key.home ? 'first' : key.end ? 'last' : key.pageUp ? 'previous-page' : 'next-page'));
|
|
761
|
-
return;
|
|
762
|
-
}
|
|
763
|
-
if (key.upArrow) {
|
|
764
|
-
setCursor((current) => moveSelection(current, rows.length, 'previous'));
|
|
765
|
-
return;
|
|
766
|
-
}
|
|
767
|
-
if (key.downArrow) {
|
|
768
|
-
setCursor((current) => moveSelection(current, rows.length, 'next'));
|
|
769
|
-
return;
|
|
770
|
-
}
|
|
771
|
-
if (key.return) {
|
|
772
|
-
const row = rows[cursorRef.current];
|
|
773
|
-
if (!row) {
|
|
774
|
-
setErrorHint('No provider available.');
|
|
775
|
-
return;
|
|
776
|
-
}
|
|
777
|
-
// Nothing on this row can be constructed, so there is no session to open
|
|
778
|
-
// and no catalogue to ask. The row stays visible on purpose — see the
|
|
779
|
-
// list below — so this is the only place that can decline it, and
|
|
780
|
-
// declining with the reason is the point: accepting would write the
|
|
781
|
-
// choice to preferences and hand the operator a session that refuses to
|
|
782
|
-
// start.
|
|
783
|
-
if (!rowIsUsable(row)) {
|
|
784
|
-
setErrorHint(unsupportedProviderMessage(row.detected[0]?.entry.id ?? row.vendor));
|
|
785
|
-
return;
|
|
786
|
-
}
|
|
787
|
-
// More than one provider behind this row: which of them the operator
|
|
788
|
-
// means is theirs to say. Skipping the question was the defect this
|
|
789
|
-
// screen was reported with — one row asked for a key while the session
|
|
790
|
-
// it could have used sat above it — so the row asks instead of picking.
|
|
791
|
-
if (rowNeedsChoice(row)) {
|
|
792
|
-
invalidateOperation();
|
|
793
|
-
setPathVendor(row.vendor);
|
|
794
|
-
setCursor(0);
|
|
795
|
-
return;
|
|
796
|
-
}
|
|
797
|
-
// One provider, so Enter means exactly what it has always meant: the
|
|
798
|
-
// detected session's models, or the field that takes the credential this
|
|
799
|
-
// row is missing. `takePath` is the same call the choice screen makes.
|
|
800
|
-
takePath(row.paths[0]);
|
|
801
|
-
return;
|
|
802
|
-
}
|
|
803
|
-
// Numeric quick-select, one keystroke per row and therefore the first nine.
|
|
804
|
-
// A tenth row would need two digits, and two digits cannot be told from
|
|
805
|
-
// two presses without a timer between them — a wait the screen would have
|
|
806
|
-
// to add to every `1` before it knew whether a `0` was coming. The list
|
|
807
|
-
// says so when it grows past nine rather than leaving the rest looking
|
|
808
|
-
// selectable and being unreachable.
|
|
809
|
-
const n = Number.parseInt(input, 10);
|
|
810
|
-
if (Number.isFinite(n) && n >= 1 && n <= Math.min(rows.length, 9)) {
|
|
811
|
-
setCursor(n - 1);
|
|
812
|
-
}
|
|
813
|
-
});
|
|
814
|
-
// Above every screen this picker draws, so the reason is on the same frame as
|
|
815
|
-
// the choice it is asking for. Whether the setup hint fits beside it is
|
|
816
|
-
// decided below, where the screen's line budget is; the screens that return
|
|
817
|
-
// early cannot be showing it in any case, so they ask for it unconditionally.
|
|
818
|
-
const buildNoticeBox = (withSetupHint) => notice || onSetup ? (_jsx(Box, { paddingBottom: 1, children: _jsxs(Box, { flexDirection: "column", children: [notice ? (_jsx(WrappedLines, { text: notice, width: contentWidth, color: theme.status.warn })) : null, onSetup && withSetupHint && !modelPhase && !loginPhase && !loginEntry && !keyEntry ? (_jsx(Text, { dimColor: true, children: SETUP_HINT })) : null] }) })) : null;
|
|
819
|
-
if (loginEntry) {
|
|
820
|
-
const waitsForDeviceApproval = loginEntry.entry.subscriptionLogin === 'device';
|
|
821
|
-
const painted = loginEntry.value
|
|
822
|
-
? `${'•'.repeat(Math.min(loginEntry.value.length, 32))}${loginEntry.value.length > 32 ? '…' : ''}`
|
|
823
|
-
: '(nothing pasted yet)';
|
|
824
|
-
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: theme.border.focus, paddingX: 1, children: [buildNoticeBox(true), _jsxs(Text, { color: theme.accent.system, bold: true, children: ["Complete ", loginEntry.entry.label, " sign-in"] }), waitsForDeviceApproval ? (_jsx(Text, { color: theme.text.muted, children: "Approve the device code shown above in your browser. esc cancels." })) : (_jsxs(_Fragment, { children: [_jsx(Text, { color: theme.text.muted, children: "Paste the authorization code, or the finished browser address, then press enter. esc cancels." }), _jsx(Box, { paddingTop: 1, children: _jsx(Text, { color: loginEntry.value ? theme.text.primary : theme.text.muted, children: painted }) })] })), _jsxs(Box, { paddingTop: 1, flexDirection: "column", children: [loginEntry.status === 'starting' ? (_jsx(Text, { color: theme.text.muted, children: waitsForDeviceApproval
|
|
825
|
-
? 'Waiting for browser approval…'
|
|
826
|
-
: 'Starting browser sign-in…' })) : loginEntry.status === 'checking' ? (_jsx(Text, { color: theme.text.muted, children: "Finishing sign-in\u2026" })) : null, loginEntry.problem ? _jsx(Text, { color: theme.status.warn, children: loginEntry.problem }) : null] })] }));
|
|
827
|
-
}
|
|
828
|
-
if (keyEntry) {
|
|
829
|
-
const { entry } = keyEntry;
|
|
830
|
-
// What the operator has typed SO FAR, classified live. It settles as they
|
|
831
|
-
// finish pasting, and it is the same question `acceptKey` asks — so the
|
|
832
|
-
// line below is a preview of the sentence they will get, not a second
|
|
833
|
-
// opinion about it.
|
|
834
|
-
const kind = classifyCredential(entry, keyEntry.value);
|
|
835
|
-
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: theme.border.focus, paddingX: 1, children: [buildNoticeBox(true), _jsxs(Box, { flexDirection: "column", paddingBottom: 1, children: [_jsxs(Text, { color: theme.accent.system, bold: true, children: ["Paste a credential for ", entry.label] }), _jsx(Text, { color: theme.text.muted, children: "An API key or a subscription token. Type or paste, then enter. esc cancels." })] }), _jsx(Text, { color: theme.text.primary, children: maskKey(keyEntry.value) || _jsx(Text, { color: theme.text.muted, children: "(nothing typed yet)" }) }), _jsxs(Box, { paddingTop: 1, flexDirection: "column", children: [keyEntry.status === 'checking' ? (_jsxs(Text, { color: theme.text.muted, children: ["Checking it with ", entry.label, "\u2026"] })) : (_jsx(Text, { color: theme.text.secondary, children: entry.id === 'google'
|
|
836
|
-
? 'Saved privately for future launches after Google starts. /logout gemini removes it.'
|
|
837
|
-
: 'Used for this session only — it is not written anywhere.' })), keyEntry.value.length > 0 && kind === 'subscription-token' ? (_jsx(Text, { color: theme.status.warn, children: "Reads as a subscription token \u2014 it expires in a few hours and namzu has no refresh data for a pasted one." })) : null, keyEntry.problem ? _jsx(Text, { color: theme.status.warn, children: keyEntry.problem }) : null] })] }));
|
|
838
|
-
}
|
|
839
|
-
if (modelPhase) {
|
|
840
|
-
return (_jsxs(Box, { flexDirection: "column", children: [buildNoticeBox(true), _jsx(ModelStepView, { providerLabel: modelPhase.provider.entry.label, otherProviders: detected
|
|
841
|
-
.filter((provider) => provider.entry.constructible && provider.entry.id !== modelPhase.provider.entry.id)
|
|
842
|
-
.map((provider) => provider.entry.label), step: modelPhase.step, query: modelQuery, currentModel: currentProvider == null || currentProvider === modelPhase.provider.entry.id
|
|
843
|
-
? currentModel
|
|
844
|
-
: undefined, cursor: cursor, errorHint: errorHint, returnToProviders: modelPhase.returnToProviders, sessionOnly: modelPhase.provider.source.kind === 'session' })] }));
|
|
845
|
-
}
|
|
846
|
-
// One vendor's ways in. Drawn only where the row's paths name more than one
|
|
847
|
-
// provider — every other row is answered by Enter as it always was — so this
|
|
848
|
-
// is the one screen this change adds, and it is reached one way.
|
|
849
|
-
if (pathRow) {
|
|
850
|
-
const experimentalZen = pathRow.paths.some((path) => path.kind === 'detected' &&
|
|
851
|
-
path.detected.entry.id === 'zen' &&
|
|
852
|
-
!hasApiCredential(path.detected.entry, path.detected.apiKey));
|
|
853
|
-
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: theme.border.focus, paddingX: 1, children: [buildNoticeBox(true), _jsxs(Text, { color: theme.accent.system, bold: true, children: ["Choose a way to use ", pathRow.label] }), _jsx(Text, { color: theme.text.muted, children: pathRow.detected.length > 0
|
|
854
|
-
? `${experimentalZen ? 'Available to try here' : 'Already usable here'} — ${rowSourceText(pathRow)}.`
|
|
855
|
-
: 'Nothing on this device is set up for it yet.' }), experimentalZen ? (_jsx(Text, { color: theme.status.warn, children: "OpenCode installation is recommended. Namzu sends requests directly; the gateway may refuse free models." })) : null, _jsx(Box, { flexDirection: "column", paddingTop: 1, children: pathRow.paths.map((path, index) => (_jsxs(Text, { color: index === cursor ? theme.text.primary : theme.text.muted, children: [index === cursor ? '❯' : ' ', " ", index + 1, ". ", describePath(path)] }, `${path.kind}-${pathProviderId(path)}`))) }), _jsxs(Box, { paddingTop: 1, flexDirection: "column", children: [_jsxs(Text, { color: theme.text.muted, children: ["\u2191\u2193 or 1-", pathRow.paths.length, " navigate \u00B7 enter use \u00B7 esc back"] }), errorHint ? _jsx(Text, { color: theme.status.warn, children: errorHint }) : null] })] }));
|
|
856
|
-
}
|
|
857
|
-
if (loginPhase) {
|
|
858
|
-
const choices = subscriptionChoices(detected);
|
|
859
|
-
const existingCount = choices.filter((choice) => choice.kind === 'existing').length;
|
|
860
|
-
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: theme.border.focus, paddingX: 1, children: [buildNoticeBox(true), _jsx(Text, { color: theme.accent.system, bold: true, children: "Choose a subscription session" }), _jsx(Text, { color: theme.text.muted, children: existingCount > 0
|
|
861
|
-
? 'Reuse a signed-in device session, or start a separate Namzu-owned sign-in.'
|
|
862
|
-
: 'No usable model session was found on this device. Start a new subscription sign-in.' }), _jsx(Box, { flexDirection: "column", paddingTop: 1, children: choices.map((choice, index) => (_jsxs(Text, { color: index === cursor ? theme.text.primary : theme.text.muted, children: [index === cursor ? '❯' : ' ', " ", index + 1, ".", ' ', choice.kind === 'existing'
|
|
863
|
-
? `Use existing ${choice.detected.entry.label} · ${describeSource(choice.detected)}`
|
|
864
|
-
: `Sign in to ${choice.entry.label} · ${choice.entry.subscriptionLogin === 'device' ? 'device code' : 'browser'}`] }, `${choice.kind}-${choice.kind === 'existing' ? choice.detected.entry.id : choice.entry.id}`))) }), _jsxs(Box, { paddingTop: 1, flexDirection: "column", children: [_jsxs(Text, { color: theme.text.muted, children: ["\u2191\u2193 or 1-", choices.length, " navigate \u00B7 enter use \u00B7 esc back"] }), errorHint ? _jsx(Text, { color: theme.status.warn, children: errorHint }) : null] })] }));
|
|
865
|
-
}
|
|
866
|
-
// Non-null exactly when `k` is live on this list and has somewhere to go —
|
|
867
|
-
// the same resolution the key handler performs, read from one place so the
|
|
868
|
-
// hint and the keyboard cannot drift apart. It follows the highlighted row,
|
|
869
|
-
// so the sentence changes as the cursor moves: a hint that kept naming the
|
|
870
|
-
// saved provider while `k` acted on another row would be the defect this
|
|
871
|
-
// screen's other messages are written to avoid.
|
|
872
|
-
const highlightedRow = rows[cursor];
|
|
873
|
-
const entryTarget = keyEntryOffered ? keyEntryTarget(highlightedRow, keyEntryFor) : null;
|
|
874
|
-
// The label is named only when `k` reaches past the highlighted row to the
|
|
875
|
-
// provider this screen was opened for. On the ordinary path the row under
|
|
876
|
-
// the cursor is the answer, and saying so again costs the line its tail: the
|
|
877
|
-
// footer is one row, and the sentence with a label in it wraps.
|
|
878
|
-
const namesAnotherRow = entryTarget !== null &&
|
|
879
|
-
(highlightedRow === undefined || !rowHasProvider(highlightedRow, entryTarget.id));
|
|
880
|
-
// The lines this screen spends on everything that is not a row, counted from
|
|
881
|
-
// the very words it is about to draw rather than estimated, then the rows get
|
|
882
|
-
// what is left.
|
|
883
|
-
//
|
|
884
|
-
// Two defects met here. The box used to be drawn at whatever height its rows
|
|
885
|
-
// needed, and on a 60x20 terminal it was taller than the terminal: Ink
|
|
886
|
-
// scrolled it, so the top border, the title, the count and the notice — the
|
|
887
|
-
// sentence telling the operator what to do about a missing credential — were
|
|
888
|
-
// above the top of the screen. And counting rows rather than lines was not
|
|
889
|
-
// enough either, because a row whose source column wraps is two lines: the
|
|
890
|
-
// count has to be the height the row actually draws, which is why the sources
|
|
891
|
-
// are wrapped here rather than by the renderer.
|
|
892
|
-
const oneLine = (text) => wrapChoiceText(text, contentWidth).length;
|
|
893
|
-
const emptyScreenFooter = `${onLogin ? 'l: sign in · ' : ''}↑↓ or 1-9 navigate · enter or k: enter a credential · ${cancelExits ? 'esc: exit namzu' : 'esc: exit picker'}`;
|
|
894
|
-
// Everything the screen draws that is not a row, in the order it is drawn:
|
|
895
|
-
// the box's two borders, the notice and its blank, the title, the blank and
|
|
896
|
-
// the intro, the sources, then the two or three ways off the screen with the
|
|
897
|
-
// blank each one sits under, the footer with its blank, the app's status bar
|
|
898
|
-
// underneath, and the line above the box that belongs to what the app has
|
|
899
|
-
// already written — Ink draws this box below that, and a terminal shows the
|
|
900
|
-
// last `rows` of it, so a box that fills the screen exactly loses its own top
|
|
901
|
-
// border to the transcript above it. Measured at 60x20, where the boot banner
|
|
902
|
-
// is two lines and the reserved line is what keeps the notice on screen.
|
|
903
|
-
const emptyScreenChromeRows = 2 +
|
|
904
|
-
(notice ? noticeLines : 0) +
|
|
905
|
-
(notice || onSetup ? 1 : 0) +
|
|
906
|
-
(onSetup ? oneLine(SETUP_HINT) : 0) +
|
|
907
|
-
1 +
|
|
908
|
-
1 +
|
|
909
|
-
oneLine(EMPTY_SCREEN_INTRO) +
|
|
910
|
-
emptyScreenSourceLines().reduce((rows, line) => rows + oneLine(line), 0) +
|
|
911
|
-
(onLogin ? 1 + oneLine(`Press l ${EMPTY_SCREEN_HINTS.signIn}`) : 0) +
|
|
912
|
-
1 +
|
|
913
|
-
oneLine(`Or press k ${EMPTY_SCREEN_HINTS.paste}`) +
|
|
914
|
-
1 +
|
|
915
|
-
oneLine(EMPTY_SCREEN_HINTS.durable) +
|
|
916
|
-
1 +
|
|
917
|
-
oneLine(emptyScreenFooter) +
|
|
918
|
-
1 +
|
|
919
|
-
TRANSCRIPT_LINE_ABOVE;
|
|
920
|
-
// The same, for the screen that found something: two borders, the notice and
|
|
921
|
-
// its blank, the title, the subtitle and the blank under the header, the
|
|
922
|
-
// heading above the not-detected block and the blank above that, the footer's
|
|
923
|
-
// blank and its line, and the status bar. The heading is reserved whenever
|
|
924
|
-
// the list has a not-detected block, even if the window does not reach it: a
|
|
925
|
-
// row too few visible is a scroll the arrows fix, and a line too many is the
|
|
926
|
-
// header scrolled away.
|
|
927
|
-
const listSubtitle = selectionKind === 'signed-in-subscription'
|
|
928
|
-
? `${detected.length} already usable · no API key required`
|
|
929
|
-
: `${detected.length} detected · device sessions / Namzu sign-ins / optional keys / local probes`;
|
|
930
|
-
const listFooter = `↑↓ or 1-9 navigate · enter ${selectionKind === 'signed-in-subscription' ? 'use' : 'accept'}${entryTarget
|
|
931
|
-
? ` · k enter a credential${namesAnotherRow ? ` for ${entryTarget.label}` : ''}`
|
|
932
|
-
: ''}${onLogin && selectionKind !== 'signed-in-subscription' ? ' · l create a Namzu sign-in' : ''} · ${cancelExits ? 'esc exit namzu' : 'esc cancel'}`;
|
|
933
|
-
// What the screen keeps, in the order it gives things up.
|
|
934
|
-
//
|
|
935
|
-
// Overflow cuts the TOP of the box, and the top is where the notice sits —
|
|
936
|
-
// the sentence that says why this screen is open and what to do about it.
|
|
937
|
-
// Everything below is ranked against that: the title and the rows are the
|
|
938
|
-
// screen, the footer is how it is left, and the two blocks that only describe
|
|
939
|
-
// the screen are what go when the terminal is too short to hold them all.
|
|
940
|
-
// `5 detected · device sessions / Namzu sign-ins / optional keys / local
|
|
941
|
-
// probes` is a summary of what is already listed beneath it, and
|
|
942
|
-
// `s provider setup` advertises a key that works from other screens too.
|
|
943
|
-
const headingRows = rows.some((row) => row.detected.length === 0) ? 1 + oneLine(NOT_DETECTED_HEADING) : 0;
|
|
944
|
-
// Everything above and below the rows except those two blocks.
|
|
945
|
-
const listCoreRows = 2 +
|
|
946
|
-
(notice ? noticeLines : 0) +
|
|
947
|
-
(notice || onSetup ? 1 : 0) +
|
|
948
|
-
1 +
|
|
949
|
-
headingRows +
|
|
950
|
-
1 +
|
|
951
|
-
oneLine(listFooter) +
|
|
952
|
-
1 +
|
|
953
|
-
TRANSCRIPT_LINE_ABOVE;
|
|
954
|
-
const subtitleRows = 1 + oneLine(listSubtitle);
|
|
955
|
-
const setupHintRows = onSetup ? oneLine(SETUP_HINT) : 0;
|
|
956
|
-
const screenRows = terminal.rows ?? 24;
|
|
957
|
-
// The row under the cursor is the one the window will not drop, so it is the
|
|
958
|
-
// height the gives-way tests are measured against — a row is one line only
|
|
959
|
-
// while its source column fits, and at 50 columns a variable name is three.
|
|
960
|
-
const cursorRow = rows[Math.max(0, Math.min(cursor, rows.length - 1))];
|
|
961
|
-
const mustKeep = cursorRow ? rowHeight(cursorRow, contentWidth, CURRENT_MARK) : 1;
|
|
962
|
-
const showSubtitle = screenRows - listCoreRows - setupHintRows - subtitleRows >= mustKeep;
|
|
963
|
-
const showSetupHint = screenRows - listCoreRows - (showSubtitle ? subtitleRows : 0) - setupHintRows >= mustKeep;
|
|
964
|
-
const listChromeRows = listCoreRows + (showSubtitle ? subtitleRows : 0) + (showSetupHint ? setupHintRows : 0);
|
|
965
|
-
const rowBudget = Math.max(1, screenRows - (detected.length === 0 ? emptyScreenChromeRows : listChromeRows));
|
|
966
|
-
const listWindow = rowWindow(rows, cursor, rowBudget, contentWidth);
|
|
967
|
-
if (detected.length === 0) {
|
|
968
|
-
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: theme.status.warn, paddingX: 1, children: [buildNoticeBox(showSetupHint), _jsx(Text, { color: theme.status.warn, bold: true, children: "No providers detected" }), _jsxs(Box, { paddingTop: 1, flexDirection: "column", children: [_jsx(WrappedLines, { text: EMPTY_SCREEN_INTRO, width: contentWidth, color: theme.text.primary }), emptyScreenSourceLines().map((line) => (_jsx(WrappedLines, { text: line, width: contentWidth, color: theme.text.muted }, line)))] }), onLogin ? (_jsx(Box, { paddingTop: 1, flexDirection: "column", children: _jsx(HintLines, { text: `Press l ${EMPTY_SCREEN_HINTS.signIn}`, keyLetter: "l", width: contentWidth, color: theme.text.primary }) })) : null, _jsx(Box, { paddingTop: 1, flexDirection: "column", children: _jsx(HintLines, { text: `Or press k ${EMPTY_SCREEN_HINTS.paste}`, keyLetter: "k", width: contentWidth, color: theme.text.primary }) }), _jsx(Box, { paddingTop: 1, children: _jsx(WrappedLines, { text: EMPTY_SCREEN_HINTS.durable, width: contentWidth, color: theme.text.secondary }) }), _jsx(ProviderSetupRows, { rows: rows, cursor: cursor, currentProvider: currentProvider, visible: listWindow, contentWidth: contentWidth }), _jsx(Box, { paddingTop: 1, children: _jsx(Text, { color: theme.text.muted, children: emptyScreenFooter }) })] }));
|
|
969
|
-
}
|
|
970
|
-
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: theme.border.focus, paddingX: 1, children: [buildNoticeBox(showSetupHint), _jsxs(Box, { flexDirection: "column", paddingBottom: 1, children: [_jsx(Text, { color: theme.accent.system, bold: true, children: selectionKind === 'signed-in-subscription'
|
|
971
|
-
? 'Choose a signed-in subscription'
|
|
972
|
-
: 'Choose a provider' }), showSubtitle ? (_jsx(WrappedLines, { text: listSubtitle, width: contentWidth, color: theme.text.muted })) : null] }), _jsx(ProviderSetupRows, { rows: rows, cursor: cursor, currentProvider: currentProvider, visible: listWindow, contentWidth: contentWidth }), _jsxs(Box, { flexDirection: "column", paddingTop: 1, children: [_jsx(WrappedLines, { text: listFooter, width: contentWidth, color: theme.text.muted }), rows.length > 9 ? (_jsx(Text, { color: theme.text.muted, children: "Rows past 9 are \u2191\u2193 only: two digits cannot be told from two presses." })) : null, errorHint ? _jsx(Text, { color: theme.status.warn, children: errorHint }) : null] })] }));
|
|
973
|
-
}
|
|
974
|
-
function ModelStepView({ providerLabel, otherProviders, step, query, currentModel, cursor, errorHint, returnToProviders, sessionOnly, }) {
|
|
975
|
-
const terminal = useWindowSize();
|
|
976
|
-
const columns = terminal.columns ?? 80;
|
|
977
|
-
// The same area the provider list measures against — see `pickerContentWidth`
|
|
978
|
-
// for the three deductions and what counting only two of them cost.
|
|
979
|
-
const width = pickerContentWidth(columns);
|
|
980
|
-
const choices = step ? filterModelChoices(step.choices, query ?? '') : [];
|
|
981
|
-
const noticeRows = step?.notice ? Math.ceil(choiceDisplayWidth(step.notice) / width) : 0;
|
|
982
|
-
const window = selectionWindow(choices, cursor, Math.max(1, Math.min(7, (terminal.rows ?? 24) - 7 - noticeRows)));
|
|
983
|
-
const hiddenAbove = window.start;
|
|
984
|
-
const hiddenBelow = choices.length - window.start - window.items.length;
|
|
985
|
-
const position = `${choices.length > 0 ? cursor + 1 : 0}/${choices.length}`;
|
|
986
|
-
const overflowHint = columns < 70
|
|
987
|
-
? `${hiddenAbove > 0 ? '↑' : ''}${hiddenBelow > 0 ? '↓' : ''}`
|
|
988
|
-
: [
|
|
989
|
-
hiddenAbove > 0 ? `↑${hiddenAbove} more` : '',
|
|
990
|
-
hiddenBelow > 0 ? `↓${hiddenBelow} more` : '',
|
|
991
|
-
]
|
|
992
|
-
.filter(Boolean)
|
|
993
|
-
.join(' · ');
|
|
994
|
-
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: theme.border.focus, paddingX: 1, children: [_jsxs(Box, { justifyContent: "space-between", children: [_jsxs(Box, { flexDirection: "column", flexGrow: 1, minWidth: 0, children: [_jsxs(Text, { color: theme.accent.system, bold: true, wrap: "truncate-end", children: ["Choose a model \u00B7 ", providerLabel] }), _jsx(Text, { color: theme.text.secondary, wrap: "truncate-end", children: columns < 70
|
|
995
|
-
? sessionOnly
|
|
996
|
-
? 'Applies to this session only.'
|
|
997
|
-
: 'Session and future launches.'
|
|
998
|
-
: sessionOnly
|
|
999
|
-
? 'Applies to this session only (temporary credential).'
|
|
1000
|
-
: 'Applies to this session and future launches.' })] }), step ? (_jsxs(Text, { color: theme.text.muted, children: [position, overflowHint ? `${columns < 70 ? '' : ' · '}${overflowHint}` : ''] })) : null] }), _jsxs(Box, { children: [_jsx(Box, { flexShrink: 0, children: _jsxs(Text, { color: theme.accent.system, children: [query === null ? 'p' : '←', " change provider"] }) }), otherProviders.length > 0 ? (_jsx(Box, { minWidth: 0, flexShrink: 1, children: _jsxs(Text, { color: theme.text.muted, wrap: "truncate-end", children: [' · ', otherProviders.slice(0, 2).map(terminalDisplayText).join(' / '), otherProviders.length > 2 ? ` / +${otherProviders.length - 2} more` : ''] }) })) : null] }), step === undefined ? (_jsxs(Text, { color: theme.text.muted, children: ["Asking ", providerLabel, " what it has\u2026"] })) : (_jsxs(_Fragment, { children: [_jsx(Text, { color: query === null ? theme.text.muted : theme.text.primary, children: truncateChoiceText(`Search: ${query ?? 'type or / to filter'}`, width) }), step.notice ? (_jsx(Text, { color: theme.status.warn, children: terminalDisplayText(step.notice) })) : null, _jsxs(Box, { flexDirection: "column", children: [choices.length === 0 ? (_jsx(Text, { color: theme.text.muted, children: step.choices.length === 0
|
|
1001
|
-
? 'No selectable models for this access path'
|
|
1002
|
-
: 'No matching models · Ctrl+U clears' })) : null, window.items.map((c, visibleIndex) => {
|
|
1003
|
-
const index = window.start + visibleIndex;
|
|
1004
|
-
const prefix = `${index === cursor ? '❯ ' : ' '}${index + 1}. `;
|
|
1005
|
-
const notes = columns < 70
|
|
1006
|
-
? [
|
|
1007
|
-
c.id === currentModel ? '(current)' : '',
|
|
1008
|
-
c.note?.includes('namzu default') ? '(default)' : '',
|
|
1009
|
-
c.note?.includes('image input') ? '(image)' : '',
|
|
1010
|
-
// Rebuilt from a fixed vocabulary, so a word
|
|
1011
|
-
// missing from it is DROPPED rather than
|
|
1012
|
-
// shortened — and a `(free)` that vanishes on a
|
|
1013
|
-
// narrow terminal is a marker the operator
|
|
1014
|
-
// cannot rely on. Listed here for the same
|
|
1015
|
-
// reason the other two are: the note is prose
|
|
1016
|
-
// the model step built, and this branch has to
|
|
1017
|
-
// know which of it still fits. `free` is read
|
|
1018
|
-
// off `c.note` rather than off the prices,
|
|
1019
|
-
// which the choice does not carry.
|
|
1020
|
-
c.note?.includes('free') ? '(free)' : '',
|
|
1021
|
-
]
|
|
1022
|
-
: [
|
|
1023
|
-
c.note,
|
|
1024
|
-
c.id === currentModel && !c.note?.includes('current') ? '(current)' : '',
|
|
1025
|
-
];
|
|
1026
|
-
const note = notes.filter(Boolean).join(' ');
|
|
1027
|
-
const labelWidth = width - choiceDisplayWidth(prefix) - choiceDisplayWidth(note) - 1;
|
|
1028
|
-
return (_jsxs(Text, { color: index === cursor ? theme.accent.system : theme.text.primary, children: [prefix, truncateChoiceText(c.label, labelWidth), note ? ` ${note}` : ''] }, c.id));
|
|
1029
|
-
})] })] })), _jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: theme.text.muted, children: columns < 70
|
|
1030
|
-
? `↑↓ · enter apply · esc ${returnToProviders ? 'back' : 'cancel'}`
|
|
1031
|
-
: `↑↓ · PgUp/PgDn · Home/End · enter apply · esc ${returnToProviders ? 'back' : 'cancel'}${query === null ? ' · digits select' : ' · Ctrl+U clears'}` }), errorHint ? _jsx(Text, { color: theme.status.warn, children: errorHint }) : null] })] }));
|
|
1032
|
-
}
|
|
1033
|
-
/**
|
|
1034
|
-
* The list, in the two blocks it is built as.
|
|
1035
|
-
*
|
|
1036
|
-
* Detected first and untouched: same rows, same order, same numbering, same
|
|
1037
|
-
* source column. The second block is appended below a heading rather than
|
|
1038
|
-
* merged into the first, because merging is the one thing that would move a row
|
|
1039
|
-
* the operator already knows the position of — and every row above this line is
|
|
1040
|
-
* one they may already be using.
|
|
1041
|
-
*
|
|
1042
|
-
* The appended rows carry no blank line between them. They are a work list
|
|
1043
|
-
* rather than a catalogue, and a machine with six of them would otherwise push
|
|
1044
|
-
* the box past a 24-row terminal and scroll the top of it — the detected rows —
|
|
1045
|
-
* out of sight. That argument is now the behaviour: `visible` is the slice that
|
|
1046
|
-
* fits, and when the whole list does not, the block boundary travels with the
|
|
1047
|
-
* window so the heading stays on screen wherever the operator has scrolled to.
|
|
1048
|
-
*
|
|
1049
|
-
* Grouping by vendor only shortened this list, and it shortened it by exactly
|
|
1050
|
-
* the duplicates: with one vendor drawn once instead of twice, nine
|
|
1051
|
-
* vendors is the most this screen can ever draw, and the digit shortcut's
|
|
1052
|
-
* nine-row limit is now a bound the list cannot pass rather than one it can
|
|
1053
|
-
* reach and overshoot. The sentence below still guards it, because a tenth
|
|
1054
|
-
* vendor in the registry would put the boundary back.
|
|
1055
|
-
*/
|
|
1056
|
-
function ProviderSetupRows({ rows, cursor, currentProvider, visible, contentWidth, }) {
|
|
1057
|
-
// The two blocks are contiguous by construction (`providerListRows` appends),
|
|
1058
|
-
// so one boundary splits them and every row's number is its position in the
|
|
1059
|
-
// whole list, whichever block it is drawn in. The boundary is a row's own
|
|
1060
|
-
// state now — whether this machine has anything for it — rather than which
|
|
1061
|
-
// arm of a union it is in.
|
|
1062
|
-
const firstUndetected = rows.findIndex((row) => row.detected.length === 0);
|
|
1063
|
-
return (_jsx(Box, { flexDirection: "column", children: visible.items.map((row, offset) => {
|
|
1064
|
-
const index = visible.start + offset;
|
|
1065
|
-
// The heading is drawn above the first not-detected row, or at the
|
|
1066
|
-
// top when the window has scrolled past that boundary — so the words
|
|
1067
|
-
// that explain the block below are never scrolled away from it.
|
|
1068
|
-
const heading = firstUndetected !== -1 &&
|
|
1069
|
-
(index === firstUndetected || (offset === 0 && index > firstUndetected)) ? (_jsx(Box, { marginTop: offset === 0 ? 0 : 1, children: _jsx(Text, { color: theme.text.muted, children: NOT_DETECTED_HEADING }) }, "heading")) : null;
|
|
1070
|
-
const detected = row.detected.length > 0;
|
|
1071
|
-
return (_jsxs(Fragment, { children: [heading, detected ? (_jsx(DetectedVendorRow, { row: row, index: index, selected: index === cursor, isCurrent: currentProvider != null && rowHasProvider(row, currentProvider), contentWidth: contentWidth })) : (_jsx(UnconfiguredVendorRow, { row: row, index: index, selected: index === cursor, isCurrent: currentProvider != null && rowHasProvider(row, currentProvider), contentWidth: contentWidth }))] }, row.vendor));
|
|
1072
|
-
}) }));
|
|
1073
|
-
}
|
|
1074
|
-
/**
|
|
1075
|
-
* A row for a vendor nothing on this machine can serve yet.
|
|
1076
|
-
*
|
|
1077
|
-
* Deliberately a separate component from `DetectedVendorRow` rather than one
|
|
1078
|
-
* component with two modes: the detected row's shape is what operators read
|
|
1079
|
-
* every day, and a shared body is a body where a change for the new rows moves
|
|
1080
|
-
* the old ones. The columns line up because both pad the label to the same
|
|
1081
|
-
* width; what differs is the third one, which says what is missing instead of
|
|
1082
|
-
* where the credential came from.
|
|
1083
|
-
*/
|
|
1084
|
-
function UnconfiguredVendorRow({ row, index, selected, isCurrent, contentWidth, }) {
|
|
1085
|
-
// The variable, not "not configured": it is the one thing the operator has
|
|
1086
|
-
// to act on, and it is what makes the credential durable. The colour marks
|
|
1087
|
-
// the work still to do on a screen that is otherwise all done.
|
|
1088
|
-
const mark = isCurrent ? CURRENT_MARK : '';
|
|
1089
|
-
const source = rowSourceLines(row, contentWidth, mark);
|
|
1090
|
-
const markInline = rowMarkPlacement(contentWidth, mark).inline;
|
|
1091
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(RowLine, { cursor: selected ? '›' : ' ', number: `${index + 1}.`, label: row.label, labelColor: selected ? theme.border.focus : theme.text.primary, labelBold: selected, numberColor: selected ? theme.border.focus : theme.text.muted, source: source[0] ?? '', sourceColor: theme.status.warn, currentMark: mark, markInline: markInline }), source.slice(1).map((line, at) => (
|
|
1092
|
-
// biome-ignore lint/suspicious/noArrayIndexKey: wrapped lines have no identity beyond their order.
|
|
1093
|
-
_jsx(Text, { color: theme.status.warn, children: `${ROW_INDENT}${line}` }, at))), mark !== '' && !markInline ? (_jsx(Text, { color: theme.accent.system, children: `${ROW_INDENT}${mark.trimStart()}` })) : null] }));
|
|
1094
|
-
}
|
|
1095
|
-
/**
|
|
1096
|
-
* One row's first line: marker, number, name and source.
|
|
1097
|
-
*
|
|
1098
|
-
* The segments are children of ONE `<Text>` rather than siblings in a `<Box>`,
|
|
1099
|
-
* and that is load-bearing rather than stylistic. A row that reaches the edge of
|
|
1100
|
-
* the box is compressed, and a compressed row loses the trailing whitespace of
|
|
1101
|
-
* the nodes it is built from — so the cursor row, which is one column wider
|
|
1102
|
-
* than every other row because of its marker, came out as `› 6.DeepSeek` while
|
|
1103
|
-
* the rows below kept their `6. `. Children of a text node are squashed into
|
|
1104
|
-
* one string before anything measures or wraps them, so the space between the
|
|
1105
|
-
* marker and the number is not trailing anything, and neither is the gap the
|
|
1106
|
-
* padded name leaves before the source.
|
|
1107
|
-
*/
|
|
1108
|
-
function RowLine({ cursor, number, label, labelColor, labelBold, numberColor, source, sourceColor, currentMark, markInline = true, dim = false, }) {
|
|
1109
|
-
return (_jsxs(Text, { children: [_jsx(Text, { color: numberColor, children: cursor }), " ", _jsx(Text, { color: numberColor, children: number }), ' ', _jsx(Text, { color: labelColor, bold: labelBold, dimColor: dim, children: label.padEnd(ROW_LABEL_WIDTH) }), _jsx(Text, { color: sourceColor, dimColor: dim, children: source }), currentMark && markInline ? (_jsx(Text, { color: theme.accent.system, children: currentMark })) : null] }));
|
|
1110
|
-
}
|
|
1111
|
-
/**
|
|
1112
|
-
* A row for a vendor something on this machine can already serve.
|
|
1113
|
-
*
|
|
1114
|
-
* What was found stays what is shown. A provider this build cannot construct is
|
|
1115
|
-
* still genuinely on the machine, and replacing "local · localhost:1234" with
|
|
1116
|
-
* the refusal would hide the discovery that makes the refusal make sense. The
|
|
1117
|
-
* reason goes in the source column, where the row says what namzu knows about
|
|
1118
|
-
* it.
|
|
1119
|
-
*
|
|
1120
|
-
* The row's name is the vendor's, which is the same word the operator used to
|
|
1121
|
-
* reach it — and the only place the two could differ is where one vendor is two
|
|
1122
|
-
* registry ids, which is the case this screen was changed for.
|
|
1123
|
-
*/
|
|
1124
|
-
function DetectedVendorRow({ row, index, selected, isCurrent, contentWidth, }) {
|
|
1125
|
-
const usable = rowIsUsable(row);
|
|
1126
|
-
const mark = isCurrent ? CURRENT_MARK : '';
|
|
1127
|
-
const source = rowSourceLines(row, contentWidth, mark);
|
|
1128
|
-
const markInline = rowMarkPlacement(contentWidth, mark).inline;
|
|
1129
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(RowLine, { cursor: selected ? '›' : ' ', number: `${index + 1}.`, label: row.label, labelColor: usable ? (selected ? theme.border.focus : theme.text.primary) : theme.text.muted, labelBold: usable && selected, numberColor: selected ? theme.border.focus : theme.text.muted, source: source[0] ?? '', sourceColor: usable ? theme.text.muted : theme.status.warn, currentMark: mark, markInline: markInline, dim: !usable }), source.slice(1).map((line, at) => (
|
|
1130
|
-
// biome-ignore lint/suspicious/noArrayIndexKey: wrapped lines have no identity beyond their order.
|
|
1131
|
-
_jsx(Text, { color: usable ? theme.text.muted : theme.status.warn, dimColor: !usable, children: `${ROW_INDENT}${line}` }, at))), mark !== '' && !markInline ? (_jsx(Text, { color: theme.accent.system, dimColor: !usable, children: `${ROW_INDENT}${mark.trimStart()}` })) : null] }));
|
|
1132
|
-
}
|
|
1133
|
-
/**
|
|
1134
|
-
* Text this screen wraps before the renderer sees it.
|
|
1135
|
-
*
|
|
1136
|
-
* Every sentence whose line count the box is sized against goes through here,
|
|
1137
|
-
* for two reasons that are the same reason. Ink's wrapping keeps the space it
|
|
1138
|
-
* broke at, so a sentence that ran onto a second line began it one column to
|
|
1139
|
-
* the right of the first — inside a box whose whole point is that its left edge
|
|
1140
|
-
* is straight. And a line count the screen reserved has to be the line count
|
|
1141
|
-
* the screen draws, which it is only if the screen is the one wrapping.
|
|
1142
|
-
*/
|
|
1143
|
-
function WrappedLines({ text, width, color, }) {
|
|
1144
|
-
return (_jsx(_Fragment, { children: wrapChoiceText(text, width).map((line, at) => (
|
|
1145
|
-
// biome-ignore lint/suspicious/noArrayIndexKey: wrapped lines have no identity beyond their order.
|
|
1146
|
-
_jsx(Text, { color: color, children: line || ' ' }, at))) }));
|
|
1147
|
-
}
|
|
1148
|
-
/**
|
|
1149
|
-
* The same, for a sentence that names a key the operator presses.
|
|
1150
|
-
*
|
|
1151
|
-
* The key is picked out in the accent colour wherever the wrap puts it, which
|
|
1152
|
-
* is why this splits the line it wrapped rather than the text it was given: a
|
|
1153
|
-
* span placed before wrapping is a span the wrap can move.
|
|
1154
|
-
*/
|
|
1155
|
-
function HintLines({ text, keyLetter, width, color, }) {
|
|
1156
|
-
return (_jsx(_Fragment, { children: wrapChoiceText(text, width).map((line, at) => {
|
|
1157
|
-
const words = line.split(' ');
|
|
1158
|
-
const key = words.indexOf(keyLetter);
|
|
1159
|
-
if (key < 0) {
|
|
1160
|
-
// biome-ignore lint/suspicious/noArrayIndexKey: wrapped lines have no identity beyond their order.
|
|
1161
|
-
return (_jsx(Text, { color: color, children: line }, at));
|
|
1162
|
-
}
|
|
1163
|
-
// biome-ignore lint/suspicious/noArrayIndexKey: wrapped lines have no identity beyond their order.
|
|
1164
|
-
return (_jsxs(Text, { color: color, children: [`${words.slice(0, key).join(' ')}${key > 0 ? ' ' : ''}`, _jsx(Text, { color: theme.accent.system, children: keyLetter }), key < words.length - 1 ? ` ${words.slice(key + 1).join(' ')}` : ''] }, at));
|
|
1165
|
-
}) }));
|
|
1166
|
-
}
|
|
1167
|
-
/**
|
|
1168
|
-
* A row's third column, wrapped to the columns the row has left for it.
|
|
1169
|
-
*
|
|
1170
|
-
* Wrapped here rather than by the renderer because a row's height is part of
|
|
1171
|
-
* the box's height, and the row window budgets in lines: Ink wrapping a row the
|
|
1172
|
-
* screen had measured as one line tall is exactly how the box grew past the
|
|
1173
|
-
* terminal and pushed its own header off the top. The count below draws the
|
|
1174
|
-
* same lines it measures, so the two cannot disagree.
|
|
1175
|
-
*/
|
|
1176
|
-
function rowSourceLines(row, contentWidth, currentMark = '') {
|
|
1177
|
-
const text = row.detected.length > 0 ? rowSourceText(row) : (rowCredentialNeed(row) ?? '');
|
|
1178
|
-
const available = Math.max(1, rowMarkPlacement(contentWidth, currentMark).sourceColumns);
|
|
1179
|
-
return capChoiceLines(wrapChoiceText(text, available), MAX_SOURCE_LINES, available);
|
|
1180
|
-
}
|
|
1181
|
-
/**
|
|
1182
|
-
* Where a row's `← current` mark goes at this width, and what it leaves the
|
|
1183
|
-
* source.
|
|
1184
|
-
*
|
|
1185
|
-
* Inline while the source keeps enough columns to be readable, and on a line of
|
|
1186
|
-
* its own when it does not. The mark is twelve columns, and at 60 columns
|
|
1187
|
-
* sharing the line with it left the source nine — which broke
|
|
1188
|
-
* `DEEPSEEK_API_KEY` across three lines to say what the operator already knew
|
|
1189
|
-
* from choosing this row.
|
|
1190
|
-
*/
|
|
1191
|
-
function rowMarkPlacement(contentWidth, currentMark) {
|
|
1192
|
-
const width = contentWidth - ROW_PREFIX_WIDTH;
|
|
1193
|
-
if (currentMark === '')
|
|
1194
|
-
return { inline: false, sourceColumns: width };
|
|
1195
|
-
const shares = width - choiceDisplayWidth(currentMark) >= MIN_SOURCE_COLUMNS;
|
|
1196
|
-
return {
|
|
1197
|
-
inline: shares,
|
|
1198
|
-
sourceColumns: Math.max(1, width - (shares ? choiceDisplayWidth(currentMark) : 0)),
|
|
1199
|
-
};
|
|
1200
|
-
}
|
|
1201
|
-
/**
|
|
1202
|
-
* The lines one row occupies at this width.
|
|
1203
|
-
*
|
|
1204
|
-
* A row that carries the mark on a line below its source is one line taller,
|
|
1205
|
-
* which is why the placement is decided by a function both the measurement and
|
|
1206
|
-
* the renderer call: a height the box did not reserve is the header scrolled off
|
|
1207
|
-
* the top of the terminal.
|
|
1208
|
-
*/
|
|
1209
|
-
function rowHeight(row, contentWidth, currentMark = '') {
|
|
1210
|
-
const lines = rowSourceLines(row, contentWidth, currentMark).length;
|
|
1211
|
-
const below = currentMark !== '' && !rowMarkPlacement(contentWidth, currentMark).inline;
|
|
1212
|
-
return below ? lines + 1 : lines;
|
|
1213
|
-
}
|
|
1214
|
-
/**
|
|
1215
|
-
* The rows that fit a line budget, with the row under the cursor among them.
|
|
1216
|
-
*
|
|
1217
|
-
* A window over ROWS and a budget in LINES, because a row is one line only
|
|
1218
|
-
* while its source column fits beside the label. The cursor's row is always
|
|
1219
|
-
* drawn whole — a cursor scrolled out of its own window is a screen the arrows
|
|
1220
|
-
* cannot explain — and the rows around it fill what is left, half the budget
|
|
1221
|
-
* above it when there is that much to show.
|
|
1222
|
-
*/
|
|
1223
|
-
function rowWindow(rows, cursor, budget, contentWidth) {
|
|
1224
|
-
if (rows.length === 0)
|
|
1225
|
-
return { start: 0, items: [] };
|
|
1226
|
-
// The row under the cursor is the marked one when a provider is in force, and
|
|
1227
|
-
// a marked row may be a line taller: see `rowHeight`.
|
|
1228
|
-
const marked = rows[Math.max(0, Math.min(cursor, rows.length - 1))];
|
|
1229
|
-
const heights = rows.map((row) => rowHeight(row, contentWidth, row === marked ? CURRENT_MARK : ''));
|
|
1230
|
-
const at = Math.max(0, Math.min(cursor, rows.length - 1));
|
|
1231
|
-
let start = at;
|
|
1232
|
-
let used = heights[at] ?? 1;
|
|
1233
|
-
const half = Math.max(1, Math.floor(budget / 2));
|
|
1234
|
-
while (start > 0 && used < half && used + (heights[start - 1] ?? 1) <= budget) {
|
|
1235
|
-
start -= 1;
|
|
1236
|
-
used += heights[start] ?? 1;
|
|
1237
|
-
}
|
|
1238
|
-
let end = at + 1;
|
|
1239
|
-
while (end < rows.length && used + (heights[end] ?? 1) <= budget) {
|
|
1240
|
-
used += heights[end] ?? 1;
|
|
1241
|
-
end += 1;
|
|
1242
|
-
}
|
|
1243
|
-
return { start, items: rows.slice(start, end) };
|
|
1244
|
-
}
|
|
1245
|
-
/**
|
|
1246
|
-
* What a detected row's third column says: where what it found came from.
|
|
1247
|
-
*
|
|
1248
|
-
* Every source is named, not the first one. A vendor reached two ways at once —
|
|
1249
|
-
* an exported key and a signed-in session — has two usable credentials, and
|
|
1250
|
-
* naming one of them would be the row choosing for an operator who has not
|
|
1251
|
-
* chosen anything yet. `+` joins them because the sources are joined by ` · `
|
|
1252
|
-
* internally, and a list of four items reads as four discoveries.
|
|
1253
|
-
*/
|
|
1254
|
-
function rowSourceText(row) {
|
|
1255
|
-
const text = row.detected.map(describeSource).join(' + ');
|
|
1256
|
-
return rowIsUsable(row) ? text : `${text} · unavailable in this build`;
|
|
1257
|
-
}
|
|
1258
|
-
/**
|
|
1259
|
-
* One way in, as the line that offers it.
|
|
1260
|
-
*
|
|
1261
|
-
* Each line borrows the wording of the screen it leads to — "Use existing …" is
|
|
1262
|
-
* the sign-in screen's phrase for a session already on the device, "Sign in to …
|
|
1263
|
-
* · device code" is its phrase for a new one, "a credential for …" is the paste
|
|
1264
|
-
* field's title — so the operator recognises where a line goes before pressing
|
|
1265
|
-
* enter on it.
|
|
1266
|
-
*/
|
|
1267
|
-
function describePath(path) {
|
|
1268
|
-
switch (path.kind) {
|
|
1269
|
-
case 'detected':
|
|
1270
|
-
return `Use existing ${path.detected.entry.label} · ${describeSource(path.detected)}`;
|
|
1271
|
-
case 'credential':
|
|
1272
|
-
return `Enter a credential for ${path.entry.label} · ${credentialNeed(path.entry)}`;
|
|
1273
|
-
case 'sign-in':
|
|
1274
|
-
return `Sign in to ${path.entry.label} · ${path.entry.subscriptionLogin === 'device' ? 'device code' : 'browser'}`;
|
|
1275
|
-
}
|
|
1276
|
-
}
|
|
1277
|
-
function describeSource(d) {
|
|
1278
|
-
switch (d.source.kind) {
|
|
1279
|
-
case 'env':
|
|
1280
|
-
if (d.entry.id === 'zen' && !hasApiCredential(d.entry, d.apiKey))
|
|
1281
|
-
return 'Zen free models · experimental; gateway may refuse';
|
|
1282
|
-
return `env · ${d.source.envName}`;
|
|
1283
|
-
case 'public':
|
|
1284
|
-
return 'Zen free models · experimental; gateway may refuse';
|
|
1285
|
-
case 'opencode-file':
|
|
1286
|
-
return 'OpenCode API key · this device';
|
|
1287
|
-
case 'probe':
|
|
1288
|
-
return `local · ${d.source.url.replace(/^https?:\/\//, '')}`;
|
|
1289
|
-
case 'keychain':
|
|
1290
|
-
return `keychain · ${d.source.service}`;
|
|
1291
|
-
case 'claude-file':
|
|
1292
|
-
return 'Claude session · this device';
|
|
1293
|
-
case 'gemini-file':
|
|
1294
|
-
return 'Gemini session · this device';
|
|
1295
|
-
case 'stored-gemini-key':
|
|
1296
|
-
return 'saved Gemini API key · this device';
|
|
1297
|
-
case 'codex-file':
|
|
1298
|
-
return 'Codex session · this device';
|
|
1299
|
-
case 'stored':
|
|
1300
|
-
// Named for what the operator DID, not for where the bytes live. They
|
|
1301
|
-
// signed in; the path is in `/doctor` for when it matters.
|
|
1302
|
-
return 'signed in · this machine';
|
|
1303
|
-
case 'session':
|
|
1304
|
-
// Named as temporary wherever it is listed. Someone scanning this
|
|
1305
|
-
// column should be able to see which credential disappears when they
|
|
1306
|
-
// close the terminal without having to remember typing it.
|
|
1307
|
-
return 'typed · this session only';
|
|
1308
|
-
}
|
|
1309
|
-
}
|
|
1310
|
-
//# sourceMappingURL=Picker.js.map
|