@namzu/cli 36.6.0 → 37.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +156 -0
- package/dist/bin.js +1 -1
- package/dist/boot-narrative.d.ts.map +1 -1
- package/dist/chunks/{acp-VF7NQ6JH.js → acp-KTJZTVUR.js} +68 -60
- package/dist/chunks/acp-KTJZTVUR.js.map +6 -0
- package/dist/chunks/{activity-command-NKR6S6K6.js → activity-command-UMTER4IK.js} +13 -13
- package/dist/chunks/{add-26SZOQLU.js → add-AIDLR6U4.js} +23 -24
- package/dist/chunks/add-AIDLR6U4.js.map +6 -0
- package/dist/chunks/{agent-CHDTE6PN.js → agent-C7TDIJ67.js} +26 -23
- package/dist/chunks/agent-session-D4Z3TOX3.js +49 -0
- package/dist/chunks/{archive-LYS5QLIY.js → archive-FKUQ77FG.js} +8 -8
- package/dist/chunks/{bin-main-SXTF5LOX.js → bin-main-BLF3YOHJ.js} +7 -7
- package/dist/chunks/{browser-4VQULFC5.js → browser-7P2TABJG.js} +6 -6
- package/dist/chunks/{chat-AYQUXC4H.js → chat-YN6WWBI6.js} +20 -19
- package/dist/chunks/{chat-AYQUXC4H.js.map → chat-YN6WWBI6.js.map} +1 -1
- package/dist/chunks/{chunk-TUN5WPEN.js → chunk-23SR4YFL.js} +2 -2
- package/dist/chunks/{chunk-GGCPLAQF.js → chunk-2EDGH6Y3.js} +3 -3
- package/dist/chunks/{chunk-ODWFH233.js → chunk-2YPMHUI4.js} +2 -2
- package/dist/chunks/{chunk-7QVXN3FK.js → chunk-37A6M7P4.js} +4 -4
- package/dist/chunks/{chunk-DZEWXEUN.js → chunk-3NCL3Y53.js} +6 -6
- package/dist/chunks/{chunk-6XVYUSCD.js → chunk-3SGEHTJ4.js} +24 -16
- package/dist/chunks/{chunk-6XVYUSCD.js.map → chunk-3SGEHTJ4.js.map} +1 -1
- package/dist/chunks/{chunk-RPRM4YIC.js → chunk-45MA2WMX.js} +3 -3
- package/dist/chunks/{chunk-LFHTKWQ5.js → chunk-4GDOFBZF.js} +3 -3
- package/dist/chunks/chunk-5GOYK3IN.js +108 -0
- package/dist/chunks/chunk-5GOYK3IN.js.map +6 -0
- package/dist/chunks/{chunk-BVJQ5NVZ.js → chunk-5WDPVM7Q.js} +2 -2
- package/dist/chunks/{chunk-KWYQCOJA.js → chunk-6CQJH56B.js} +2 -2
- package/dist/chunks/{chunk-IKGTBMN2.js → chunk-6HDBRUB7.js} +1121 -142
- package/dist/chunks/chunk-6HDBRUB7.js.map +6 -0
- package/dist/chunks/{chunk-MIIWBGGM.js → chunk-74WE6T6M.js} +6 -6
- package/dist/chunks/{chunk-77VH3G4M.js → chunk-BUQ7VMBS.js} +6 -6
- package/dist/chunks/{chunk-QMDN7FIB.js → chunk-BV2SDA2D.js} +13 -6
- package/dist/chunks/chunk-BV2SDA2D.js.map +6 -0
- package/dist/chunks/{chunk-OTG2DGSA.js → chunk-D7FPVZDC.js} +2 -2
- package/dist/chunks/{chunk-SMUEQ5RA.js → chunk-DBBWIOQS.js} +3 -3
- package/dist/chunks/{chunk-P7NKAQ6I.js → chunk-DFU5KG3V.js} +4 -4
- package/dist/chunks/{chunk-TC55VVWF.js → chunk-EBFWNPMU.js} +11 -11
- package/dist/chunks/{chunk-X6SYXGAY.js → chunk-F2JKDYHA.js} +4 -4
- package/dist/chunks/{chunk-VE322URM.js → chunk-FKLDO6SF.js} +3 -3
- package/dist/chunks/{chunk-2JVVUMXC.js → chunk-FLUVTAXY.js} +6811 -1746
- package/dist/chunks/chunk-FLUVTAXY.js.map +6 -0
- package/dist/chunks/{chunk-2LBM3V3N.js → chunk-GR452YOE.js} +2 -2
- package/dist/chunks/{chunk-GZHWOIKT.js → chunk-HHKKHUJK.js} +2 -2
- package/dist/chunks/{chunk-ZU4YCZVG.js → chunk-HV4SSQ2Y.js} +3 -3
- package/dist/chunks/{chunk-2EUHQ3UU.js → chunk-HXFPEA6Z.js} +7 -2
- package/dist/chunks/chunk-HXFPEA6Z.js.map +6 -0
- package/dist/chunks/{chunk-5SVMKOEG.js → chunk-I3Q53U6H.js} +2 -2
- package/dist/chunks/{chunk-XQWG6PQN.js → chunk-I6XWCKKW.js} +39 -4
- package/dist/chunks/{chunk-XQWG6PQN.js.map → chunk-I6XWCKKW.js.map} +1 -1
- package/dist/chunks/{chunk-Z6GVIPO2.js → chunk-JH2O55TT.js} +4 -4
- package/dist/chunks/{chunk-AO3RYELY.js → chunk-KQM2NQ2W.js} +27 -12
- package/dist/chunks/chunk-KQM2NQ2W.js.map +6 -0
- package/dist/chunks/{chunk-DII3AAD5.js → chunk-KSFS3BI7.js} +2 -2
- package/dist/chunks/{chunk-G2DJRAN7.js → chunk-L7Q7QNNE.js} +3 -3
- package/dist/chunks/{chunk-5X6ADRCM.js → chunk-MVGNG67O.js} +2 -2
- package/dist/chunks/{chunk-YUIZ3I52.js → chunk-MYRLRBZG.js} +19 -3
- package/dist/chunks/chunk-MYRLRBZG.js.map +6 -0
- package/dist/chunks/{chunk-MMCTEOXA.js → chunk-NKERGDBZ.js} +2 -2
- package/dist/chunks/{chunk-BUORNM3L.js → chunk-OKB66ICJ.js} +23 -18
- package/dist/chunks/chunk-OKB66ICJ.js.map +6 -0
- package/dist/chunks/{chunk-UVAY5ESO.js → chunk-OVVIFOAR.js} +4 -4
- package/dist/chunks/{chunk-QQFWOGD2.js → chunk-QCJU5KFR.js} +6 -6
- package/dist/chunks/{chunk-PQOGAHD5.js → chunk-QU3LGVTZ.js} +5 -5
- package/dist/chunks/{chunk-ZNAE3DVS.js → chunk-QVMTUMTW.js} +89 -4
- package/dist/chunks/{chunk-ZNAE3DVS.js.map → chunk-QVMTUMTW.js.map} +2 -2
- package/dist/chunks/{chunk-ODSPUOYW.js → chunk-R23DP7S7.js} +17 -17
- package/dist/chunks/{chunk-EOPRQEHH.js → chunk-SEKX6IR5.js} +13 -13
- package/dist/chunks/{chunk-V6WLAAXC.js → chunk-UFZGVNFQ.js} +2 -2
- package/dist/chunks/{chunk-VU7JHAR6.js → chunk-WMOYTZXD.js} +19 -18
- package/dist/chunks/{chunk-VU7JHAR6.js.map → chunk-WMOYTZXD.js.map} +1 -1
- package/dist/chunks/{chunk-BN5A2MAB.js → chunk-WRGY7MRU.js} +80 -39
- package/dist/chunks/chunk-WRGY7MRU.js.map +6 -0
- package/dist/chunks/{chunk-PH72277Q.js → chunk-WWE4W2R6.js} +2 -2
- package/dist/chunks/{chunk-3Z24K6SK.js → chunk-X3ZBCYV6.js} +2 -2
- package/dist/chunks/{chunk-2NUNK4JI.js → chunk-XDAMUTVR.js} +4 -4
- package/dist/chunks/{chunk-WFAZLQ5N.js → chunk-XYXPAVPG.js} +4 -4
- package/dist/chunks/{chunk-3APO4D7I.js → chunk-Y3UE64PV.js} +3 -3
- package/dist/chunks/{chunk-4WM5CKTI.js → chunk-YCVR5E2Z.js} +182 -18
- package/dist/chunks/chunk-YCVR5E2Z.js.map +6 -0
- package/dist/chunks/{chunk-GKEBBQ3Z.js → chunk-ZKI3Z4VR.js} +5 -3
- package/dist/chunks/chunk-ZKI3Z4VR.js.map +6 -0
- package/dist/chunks/{chunk-AY6EUCML.js → chunk-ZRAALEF2.js} +2 -2
- package/dist/chunks/{chunk-HO4QVXVW.js → chunk-ZRJYG2F2.js} +2 -2
- package/dist/chunks/{cli-runtime-TQIXSGNJ.js → cli-runtime-74KKQHC7.js} +15 -11
- package/dist/chunks/cli-runtime-74KKQHC7.js.map +6 -0
- package/dist/chunks/{commands-YCYR4OO7.js → commands-2Q7KPVLW.js} +5 -5
- package/dist/chunks/{crash-report-3STEQBVJ.js → crash-report-KDVWQ2RR.js} +6 -6
- package/dist/chunks/{dist-ITGC4C5H.js → dist-25C2CYHP.js} +2 -2
- package/dist/chunks/{dist-G2ZZ3OAU.js → dist-4TGHKBRS.js} +2 -2
- package/dist/chunks/{dist-H4O3BALK.js → dist-674RS73L.js} +2 -2
- package/dist/chunks/{dist-Z33PLHVL.js → dist-OMRUSJ5R.js} +12 -2
- package/dist/chunks/{dist-Z33PLHVL.js.map → dist-OMRUSJ5R.js.map} +1 -1
- package/dist/chunks/{dist-XJYPRLMT.js → dist-Q523V5L2.js} +2 -2
- package/dist/chunks/{dist-FDUMWWP6.js → dist-UYD7IXG3.js} +2 -2
- package/dist/chunks/{dist-LCPSN2KU.js → dist-ZDSPMZ5S.js} +2 -2
- package/dist/chunks/{doctor-YCV7KO72.js → doctor-TFION64N.js} +7 -7
- package/dist/chunks/{drain-B6NE7ECX.js → drain-3W3A4KPX.js} +21 -16
- package/dist/chunks/drain-3W3A4KPX.js.map +6 -0
- package/dist/chunks/{eval-HKVQPXKR.js → eval-TCUVH3S3.js} +2 -2
- package/dist/chunks/{exec-MOJSMH4D.js → exec-EIELDRPM.js} +57 -105
- package/dist/chunks/exec-EIELDRPM.js.map +6 -0
- package/dist/chunks/{home-XWVKZPVH.js → home-FYDAEWNW.js} +3 -3
- package/dist/chunks/{host-queries-FZZJCBO7.js → host-queries-WFWM672O.js} +17 -17
- package/dist/chunks/{lifecycle-4R4ZRWRI.js → lifecycle-ALDBR656.js} +28 -29
- package/dist/chunks/{list-7V5HNSRV.js → list-Z4XOJJ7V.js} +21 -22
- package/dist/chunks/list-Z4XOJJ7V.js.map +6 -0
- package/dist/chunks/{login-MSFPVB2R.js → login-UZONOHHT.js} +9 -9
- package/dist/chunks/{logs-EGCWVNBU.js → logs-O3NGOQFC.js} +4 -4
- package/dist/chunks/{mcp-DWCVUDXK.js → mcp-YI6PL4TH.js} +23 -22
- package/dist/chunks/mcp-YI6PL4TH.js.map +6 -0
- package/dist/chunks/{message-command-K3GFQCZU.js → message-command-QEQJ25KR.js} +40 -39
- package/dist/chunks/message-command-QEQJ25KR.js.map +6 -0
- package/dist/chunks/{operator-tools-JRMP2OHZ.js → operator-tools-GKYGHHPM.js} +12 -12
- package/dist/chunks/{output-schema-XVJ3XUMN.js → output-schema-KXKCYDI4.js} +3 -3
- package/dist/chunks/{pal-Y5K4PJF7.js → pal-2EYYHPXC.js} +14 -14
- package/dist/chunks/{providers-MNU4KDEW.js → providers-JF5SWSTH.js} +6 -6
- package/dist/chunks/{resident-BI4VV6F4.js → resident-WHH7YQGZ.js} +29 -28
- package/dist/chunks/resident-WHH7YQGZ.js.map +6 -0
- package/dist/chunks/resume-WR4KOI7Q.js +21 -0
- package/dist/chunks/{resume-command-XBFDMRUK.js → resume-command-A3HKQSRH.js} +4 -4
- package/dist/chunks/{schedule-XEU5OSKW.js → schedule-QIJCYWIQ.js} +8 -8
- package/dist/chunks/{service-YOZ6GUL5.js → service-IXPGBY3F.js} +37 -38
- package/dist/chunks/service-IXPGBY3F.js.map +6 -0
- package/dist/chunks/session-step-ZZBENVGS.js +26 -0
- package/dist/chunks/{skills-ZKC4GGY6.js → skills-AGU7FTRG.js} +11 -11
- package/dist/chunks/{state-RV3YXV6V.js → state-MTHK7DUX.js} +2 -2
- package/dist/chunks/{store-PJQ65VLY.js → store-EWEKEKSG.js} +12 -8
- package/dist/chunks/{store-7X5FJMKH.js → store-LPOET7IK.js} +4 -4
- package/dist/chunks/{store-QLMY3B43.js → store-XPSGZANO.js} +6 -6
- package/dist/chunks/store-XPSGZANO.js.map +6 -0
- package/dist/chunks/{tui-FZJ37KG2.js → tui-YMBQLMGW.js} +2324 -827
- package/dist/chunks/tui-YMBQLMGW.js.map +6 -0
- package/dist/chunks/turndown.cjs-2NVZBL7F.js +17615 -0
- package/dist/chunks/turndown.cjs-2NVZBL7F.js.map +6 -0
- package/dist/chunks/{upgrade-KJRSVGA3.js → upgrade-3YOFSMAQ.js} +2 -2
- package/dist/chunks/{worktree-JLK5Z6DS.js → worktree-VPD2N53Y.js} +10 -10
- package/dist/cli-runtime.d.ts +1 -1
- package/dist/cli-runtime.d.ts.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/commands/acp.d.ts.map +1 -1
- package/dist/commands/desktop-host.d.ts.map +1 -1
- package/dist/commands/drain.d.ts.map +1 -1
- package/dist/commands/exec-json.d.ts.map +1 -1
- package/dist/commands/exec.d.ts.map +1 -1
- package/dist/commands/resume.d.ts +31 -0
- package/dist/commands/resume.d.ts.map +1 -1
- package/dist/config/debug.d.ts.map +1 -1
- package/dist/config/load.d.ts +21 -6
- package/dist/config/load.d.ts.map +1 -1
- package/dist/config/schema.d.ts +48 -4
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/context/doctrine.d.ts +9 -0
- package/dist/context/doctrine.d.ts.map +1 -1
- package/dist/context/runtime-message.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -15
- package/dist/integrations/notifications/idle.d.ts +48 -0
- package/dist/integrations/notifications/idle.d.ts.map +1 -0
- package/dist/integrations/notifications/terminal.d.ts +4 -0
- package/dist/integrations/notifications/terminal.d.ts.map +1 -1
- package/dist/integrations/providers/image-input.d.ts +22 -0
- package/dist/integrations/providers/image-input.d.ts.map +1 -0
- package/dist/integrations/resident/runner-worker.js +24 -24
- package/dist/integrations/resident/session-step.d.ts.map +1 -1
- package/dist/integrations/sessions/ai-title.d.ts +45 -0
- package/dist/integrations/sessions/ai-title.d.ts.map +1 -0
- package/dist/integrations/sessions/store.d.ts +16 -0
- package/dist/integrations/sessions/store.d.ts.map +1 -1
- package/dist/integrations/small-model/route.d.ts +44 -0
- package/dist/integrations/small-model/route.d.ts.map +1 -0
- package/dist/integrations/small-model/side-model.d.ts +89 -0
- package/dist/integrations/small-model/side-model.d.ts.map +1 -0
- package/dist/integrations/subagents/runtime.d.ts +6 -0
- package/dist/integrations/subagents/runtime.d.ts.map +1 -1
- package/dist/pals/agent-session.d.ts.map +1 -1
- package/dist/pals/chat.d.ts.map +1 -1
- package/dist/pals/review.d.ts.map +1 -1
- package/dist/permissions/local-settings.d.ts +57 -0
- package/dist/permissions/local-settings.d.ts.map +1 -0
- package/dist/permissions/rules.d.ts +32 -0
- package/dist/permissions/rules.d.ts.map +1 -1
- package/dist/permissions/session-allow.d.ts +71 -17
- package/dist/permissions/session-allow.d.ts.map +1 -1
- package/dist/plan/approval.d.ts +43 -0
- package/dist/plan/approval.d.ts.map +1 -0
- package/dist/plan/exit-plan-mode-tool.d.ts +24 -0
- package/dist/plan/exit-plan-mode-tool.d.ts.map +1 -0
- package/dist/plan/plan-file.d.ts +10 -0
- package/dist/plan/plan-file.d.ts.map +1 -0
- package/dist/reminders/frame.d.ts +20 -0
- package/dist/reminders/frame.d.ts.map +1 -0
- package/dist/reminders/index.d.ts +24 -0
- package/dist/reminders/index.d.ts.map +1 -0
- package/dist/reminders/plan-mode.d.ts +25 -0
- package/dist/reminders/plan-mode.d.ts.map +1 -0
- package/dist/reminders/task-nudge.d.ts +18 -0
- package/dist/reminders/task-nudge.d.ts.map +1 -0
- package/dist/schedule/fire/fire.d.ts.map +1 -1
- package/dist/tui/App.d.ts.map +1 -1
- package/dist/tui/Composer.d.ts.map +1 -1
- package/dist/tui/LiveActivity.d.ts.map +1 -1
- package/dist/tui/PermissionOverlay.d.ts +5 -1
- package/dist/tui/PermissionOverlay.d.ts.map +1 -1
- package/dist/tui/PlanApprovalOverlay.d.ts +32 -0
- package/dist/tui/PlanApprovalOverlay.d.ts.map +1 -0
- package/dist/tui/QuestionDialog.d.ts +22 -0
- package/dist/tui/QuestionDialog.d.ts.map +1 -0
- package/dist/tui/StatusBar.d.ts +16 -3
- package/dist/tui/StatusBar.d.ts.map +1 -1
- package/dist/tui/agent.d.ts +72 -8
- package/dist/tui/agent.d.ts.map +1 -1
- package/dist/tui/capability-notice.d.ts +1 -1
- package/dist/tui/capability-notice.d.ts.map +1 -1
- package/dist/tui/context-meter.d.ts +33 -0
- package/dist/tui/context-meter.d.ts.map +1 -0
- package/dist/tui/mentions.d.ts +9 -1
- package/dist/tui/mentions.d.ts.map +1 -1
- package/dist/tui/plain-interruption.d.ts +7 -4
- package/dist/tui/plain-interruption.d.ts.map +1 -1
- package/dist/tui/question-dialog.d.ts +34 -0
- package/dist/tui/question-dialog.d.ts.map +1 -0
- package/dist/tui/slashCommands.d.ts +4 -3
- package/dist/tui/slashCommands.d.ts.map +1 -1
- package/dist/tui/status-line/StatusLineRows.d.ts +11 -0
- package/dist/tui/status-line/StatusLineRows.d.ts.map +1 -0
- package/dist/tui/status-line/controller.d.ts +55 -0
- package/dist/tui/status-line/controller.d.ts.map +1 -0
- package/dist/tui/status-line/output.d.ts +18 -0
- package/dist/tui/status-line/output.d.ts.map +1 -0
- package/dist/tui/status-line/payload.d.ts +43 -0
- package/dist/tui/status-line/payload.d.ts.map +1 -0
- package/dist/tui/status-line/run-command.d.ts +24 -0
- package/dist/tui/status-line/run-command.d.ts.map +1 -0
- package/dist/tui/status-line/useStatusLine.d.ts +22 -0
- package/dist/tui/status-line/useStatusLine.d.ts.map +1 -0
- package/dist/tui/status-line/workspace-git.d.ts +17 -0
- package/dist/tui/status-line/workspace-git.d.ts.map +1 -0
- package/dist/tui/terminal-title.d.ts +33 -0
- package/dist/tui/terminal-title.d.ts.map +1 -0
- package/dist/tui/turn-interruption.d.ts.map +1 -1
- package/dist/tui/types.d.ts +12 -1
- package/dist/tui/types.d.ts.map +1 -1
- package/package.json +4 -4
- package/dist/chunks/acp-VF7NQ6JH.js.map +0 -6
- package/dist/chunks/add-26SZOQLU.js.map +0 -6
- package/dist/chunks/agent-session-F5XU36CE.js +0 -46
- package/dist/chunks/chunk-2EUHQ3UU.js.map +0 -6
- package/dist/chunks/chunk-2JVVUMXC.js.map +0 -6
- package/dist/chunks/chunk-4WM5CKTI.js.map +0 -6
- package/dist/chunks/chunk-AO3RYELY.js.map +0 -6
- package/dist/chunks/chunk-BN5A2MAB.js.map +0 -6
- package/dist/chunks/chunk-BUORNM3L.js.map +0 -6
- package/dist/chunks/chunk-GKEBBQ3Z.js.map +0 -6
- package/dist/chunks/chunk-IKGTBMN2.js.map +0 -6
- package/dist/chunks/chunk-QMDN7FIB.js.map +0 -6
- package/dist/chunks/chunk-UFPOA63T.js +0 -71
- package/dist/chunks/chunk-UFPOA63T.js.map +0 -6
- package/dist/chunks/chunk-YUIZ3I52.js.map +0 -6
- package/dist/chunks/cli-runtime-TQIXSGNJ.js.map +0 -6
- package/dist/chunks/drain-B6NE7ECX.js.map +0 -6
- package/dist/chunks/exec-MOJSMH4D.js.map +0 -6
- package/dist/chunks/list-7V5HNSRV.js.map +0 -6
- package/dist/chunks/mcp-DWCVUDXK.js.map +0 -6
- package/dist/chunks/message-command-K3GFQCZU.js.map +0 -6
- package/dist/chunks/resident-BI4VV6F4.js.map +0 -6
- package/dist/chunks/service-YOZ6GUL5.js.map +0 -6
- package/dist/chunks/session-step-RLSIZ3S2.js +0 -26
- package/dist/chunks/tui-FZJ37KG2.js.map +0 -6
- /package/dist/chunks/{activity-command-NKR6S6K6.js.map → activity-command-UMTER4IK.js.map} +0 -0
- /package/dist/chunks/{agent-CHDTE6PN.js.map → agent-C7TDIJ67.js.map} +0 -0
- /package/dist/chunks/{agent-session-F5XU36CE.js.map → agent-session-D4Z3TOX3.js.map} +0 -0
- /package/dist/chunks/{archive-LYS5QLIY.js.map → archive-FKUQ77FG.js.map} +0 -0
- /package/dist/chunks/{bin-main-SXTF5LOX.js.map → bin-main-BLF3YOHJ.js.map} +0 -0
- /package/dist/chunks/{browser-4VQULFC5.js.map → browser-7P2TABJG.js.map} +0 -0
- /package/dist/chunks/{chunk-TUN5WPEN.js.map → chunk-23SR4YFL.js.map} +0 -0
- /package/dist/chunks/{chunk-GGCPLAQF.js.map → chunk-2EDGH6Y3.js.map} +0 -0
- /package/dist/chunks/{chunk-ODWFH233.js.map → chunk-2YPMHUI4.js.map} +0 -0
- /package/dist/chunks/{chunk-7QVXN3FK.js.map → chunk-37A6M7P4.js.map} +0 -0
- /package/dist/chunks/{chunk-DZEWXEUN.js.map → chunk-3NCL3Y53.js.map} +0 -0
- /package/dist/chunks/{chunk-RPRM4YIC.js.map → chunk-45MA2WMX.js.map} +0 -0
- /package/dist/chunks/{chunk-LFHTKWQ5.js.map → chunk-4GDOFBZF.js.map} +0 -0
- /package/dist/chunks/{chunk-BVJQ5NVZ.js.map → chunk-5WDPVM7Q.js.map} +0 -0
- /package/dist/chunks/{chunk-KWYQCOJA.js.map → chunk-6CQJH56B.js.map} +0 -0
- /package/dist/chunks/{chunk-MIIWBGGM.js.map → chunk-74WE6T6M.js.map} +0 -0
- /package/dist/chunks/{chunk-77VH3G4M.js.map → chunk-BUQ7VMBS.js.map} +0 -0
- /package/dist/chunks/{chunk-OTG2DGSA.js.map → chunk-D7FPVZDC.js.map} +0 -0
- /package/dist/chunks/{chunk-SMUEQ5RA.js.map → chunk-DBBWIOQS.js.map} +0 -0
- /package/dist/chunks/{chunk-P7NKAQ6I.js.map → chunk-DFU5KG3V.js.map} +0 -0
- /package/dist/chunks/{chunk-TC55VVWF.js.map → chunk-EBFWNPMU.js.map} +0 -0
- /package/dist/chunks/{chunk-X6SYXGAY.js.map → chunk-F2JKDYHA.js.map} +0 -0
- /package/dist/chunks/{chunk-VE322URM.js.map → chunk-FKLDO6SF.js.map} +0 -0
- /package/dist/chunks/{chunk-2LBM3V3N.js.map → chunk-GR452YOE.js.map} +0 -0
- /package/dist/chunks/{chunk-GZHWOIKT.js.map → chunk-HHKKHUJK.js.map} +0 -0
- /package/dist/chunks/{chunk-ZU4YCZVG.js.map → chunk-HV4SSQ2Y.js.map} +0 -0
- /package/dist/chunks/{chunk-5SVMKOEG.js.map → chunk-I3Q53U6H.js.map} +0 -0
- /package/dist/chunks/{chunk-Z6GVIPO2.js.map → chunk-JH2O55TT.js.map} +0 -0
- /package/dist/chunks/{chunk-DII3AAD5.js.map → chunk-KSFS3BI7.js.map} +0 -0
- /package/dist/chunks/{chunk-G2DJRAN7.js.map → chunk-L7Q7QNNE.js.map} +0 -0
- /package/dist/chunks/{chunk-5X6ADRCM.js.map → chunk-MVGNG67O.js.map} +0 -0
- /package/dist/chunks/{chunk-MMCTEOXA.js.map → chunk-NKERGDBZ.js.map} +0 -0
- /package/dist/chunks/{chunk-UVAY5ESO.js.map → chunk-OVVIFOAR.js.map} +0 -0
- /package/dist/chunks/{chunk-QQFWOGD2.js.map → chunk-QCJU5KFR.js.map} +0 -0
- /package/dist/chunks/{chunk-PQOGAHD5.js.map → chunk-QU3LGVTZ.js.map} +0 -0
- /package/dist/chunks/{chunk-ODSPUOYW.js.map → chunk-R23DP7S7.js.map} +0 -0
- /package/dist/chunks/{chunk-EOPRQEHH.js.map → chunk-SEKX6IR5.js.map} +0 -0
- /package/dist/chunks/{chunk-V6WLAAXC.js.map → chunk-UFZGVNFQ.js.map} +0 -0
- /package/dist/chunks/{chunk-PH72277Q.js.map → chunk-WWE4W2R6.js.map} +0 -0
- /package/dist/chunks/{chunk-3Z24K6SK.js.map → chunk-X3ZBCYV6.js.map} +0 -0
- /package/dist/chunks/{chunk-2NUNK4JI.js.map → chunk-XDAMUTVR.js.map} +0 -0
- /package/dist/chunks/{chunk-WFAZLQ5N.js.map → chunk-XYXPAVPG.js.map} +0 -0
- /package/dist/chunks/{chunk-3APO4D7I.js.map → chunk-Y3UE64PV.js.map} +0 -0
- /package/dist/chunks/{chunk-AY6EUCML.js.map → chunk-ZRAALEF2.js.map} +0 -0
- /package/dist/chunks/{chunk-HO4QVXVW.js.map → chunk-ZRJYG2F2.js.map} +0 -0
- /package/dist/chunks/{commands-YCYR4OO7.js.map → commands-2Q7KPVLW.js.map} +0 -0
- /package/dist/chunks/{crash-report-3STEQBVJ.js.map → crash-report-KDVWQ2RR.js.map} +0 -0
- /package/dist/chunks/{dist-ITGC4C5H.js.map → dist-25C2CYHP.js.map} +0 -0
- /package/dist/chunks/{dist-G2ZZ3OAU.js.map → dist-4TGHKBRS.js.map} +0 -0
- /package/dist/chunks/{dist-H4O3BALK.js.map → dist-674RS73L.js.map} +0 -0
- /package/dist/chunks/{dist-XJYPRLMT.js.map → dist-Q523V5L2.js.map} +0 -0
- /package/dist/chunks/{dist-FDUMWWP6.js.map → dist-UYD7IXG3.js.map} +0 -0
- /package/dist/chunks/{dist-LCPSN2KU.js.map → dist-ZDSPMZ5S.js.map} +0 -0
- /package/dist/chunks/{doctor-YCV7KO72.js.map → doctor-TFION64N.js.map} +0 -0
- /package/dist/chunks/{eval-HKVQPXKR.js.map → eval-TCUVH3S3.js.map} +0 -0
- /package/dist/chunks/{home-XWVKZPVH.js.map → home-FYDAEWNW.js.map} +0 -0
- /package/dist/chunks/{host-queries-FZZJCBO7.js.map → host-queries-WFWM672O.js.map} +0 -0
- /package/dist/chunks/{lifecycle-4R4ZRWRI.js.map → lifecycle-ALDBR656.js.map} +0 -0
- /package/dist/chunks/{login-MSFPVB2R.js.map → login-UZONOHHT.js.map} +0 -0
- /package/dist/chunks/{logs-EGCWVNBU.js.map → logs-O3NGOQFC.js.map} +0 -0
- /package/dist/chunks/{operator-tools-JRMP2OHZ.js.map → operator-tools-GKYGHHPM.js.map} +0 -0
- /package/dist/chunks/{output-schema-XVJ3XUMN.js.map → output-schema-KXKCYDI4.js.map} +0 -0
- /package/dist/chunks/{pal-Y5K4PJF7.js.map → pal-2EYYHPXC.js.map} +0 -0
- /package/dist/chunks/{providers-MNU4KDEW.js.map → providers-JF5SWSTH.js.map} +0 -0
- /package/dist/chunks/{resume-command-XBFDMRUK.js.map → resume-WR4KOI7Q.js.map} +0 -0
- /package/dist/chunks/{session-step-RLSIZ3S2.js.map → resume-command-A3HKQSRH.js.map} +0 -0
- /package/dist/chunks/{schedule-XEU5OSKW.js.map → schedule-QIJCYWIQ.js.map} +0 -0
- /package/dist/chunks/{store-7X5FJMKH.js.map → session-step-ZZBENVGS.js.map} +0 -0
- /package/dist/chunks/{skills-ZKC4GGY6.js.map → skills-AGU7FTRG.js.map} +0 -0
- /package/dist/chunks/{state-RV3YXV6V.js.map → state-MTHK7DUX.js.map} +0 -0
- /package/dist/chunks/{store-PJQ65VLY.js.map → store-EWEKEKSG.js.map} +0 -0
- /package/dist/chunks/{store-QLMY3B43.js.map → store-LPOET7IK.js.map} +0 -0
- /package/dist/chunks/{upgrade-KJRSVGA3.js.map → upgrade-3YOFSMAQ.js.map} +0 -0
- /package/dist/chunks/{worktree-JLK5Z6DS.js.map → worktree-VPD2N53Y.js.map} +0 -0
|
@@ -2,16 +2,19 @@ import { createRequire as __namzuCreateRequire } from 'node:module';
|
|
|
2
2
|
const require = __namzuCreateRequire(import.meta.url);
|
|
3
3
|
import {
|
|
4
4
|
openManagedWorktrees
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-3NCL3Y53.js";
|
|
6
6
|
import {
|
|
7
7
|
createBrowserControl
|
|
8
8
|
} from "./chunk-WHODOMXA.js";
|
|
9
9
|
import {
|
|
10
10
|
connectMcpServers
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-JH2O55TT.js";
|
|
12
|
+
import {
|
|
13
|
+
openInBrowser
|
|
14
|
+
} from "./chunk-UFZGVNFQ.js";
|
|
12
15
|
import {
|
|
13
16
|
createSessionSkillCatalog
|
|
14
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-FKLDO6SF.js";
|
|
15
18
|
import {
|
|
16
19
|
SAVE_SKILL_TOOL_NAME,
|
|
17
20
|
WORKFLOW_TOOL_DESCRIPTION,
|
|
@@ -27,10 +30,7 @@ import {
|
|
|
27
30
|
viewFromJournal,
|
|
28
31
|
workflowOffered,
|
|
29
32
|
workflowRefusal
|
|
30
|
-
} from "./chunk-
|
|
31
|
-
import {
|
|
32
|
-
openInBrowser
|
|
33
|
-
} from "./chunk-V6WLAAXC.js";
|
|
33
|
+
} from "./chunk-4GDOFBZF.js";
|
|
34
34
|
import {
|
|
35
35
|
CredentialRefreshRejectedError,
|
|
36
36
|
CredentialWithdrawnError,
|
|
@@ -38,15 +38,16 @@ import {
|
|
|
38
38
|
ensureFreshStoredCodexCredential,
|
|
39
39
|
readSubscriptionCredential,
|
|
40
40
|
sameOAuthCredential
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-DFU5KG3V.js";
|
|
42
42
|
import {
|
|
43
43
|
debugRequested
|
|
44
44
|
} from "./chunk-GNBMKISG.js";
|
|
45
45
|
import {
|
|
46
|
+
LOCAL_CONFIG_FILE,
|
|
46
47
|
configuredPassthroughTools,
|
|
47
48
|
resolveToolResultScreens,
|
|
48
49
|
unmatchedPassthroughTools
|
|
49
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-YCVR5E2Z.js";
|
|
50
51
|
import {
|
|
51
52
|
formatSize,
|
|
52
53
|
homePath,
|
|
@@ -74,30 +75,20 @@ import {
|
|
|
74
75
|
requiresCredentialForModel,
|
|
75
76
|
resolveChainCapabilities,
|
|
76
77
|
unresolvedMembers
|
|
77
|
-
} from "./chunk-
|
|
78
|
+
} from "./chunk-SEKX6IR5.js";
|
|
78
79
|
import {
|
|
79
80
|
PROVIDER_REGISTRY,
|
|
80
81
|
missingCredentialMessage,
|
|
81
82
|
unsupportedProviderMessage
|
|
82
83
|
} from "./chunk-6LLJQ3KY.js";
|
|
83
|
-
import {
|
|
84
|
-
cliLogger
|
|
85
|
-
} from "./chunk-TUN5WPEN.js";
|
|
86
84
|
import {
|
|
87
85
|
isPermissionMode,
|
|
88
86
|
permissionModeLabel
|
|
89
|
-
} from "./chunk-
|
|
90
|
-
import {
|
|
91
|
-
probeCapabilities
|
|
92
|
-
} from "./chunk-OH6TB27S.js";
|
|
93
|
-
import {
|
|
94
|
-
activeZenCatalogue,
|
|
95
|
-
isOfferableModel
|
|
96
|
-
} from "./chunk-U3JIZFOS.js";
|
|
87
|
+
} from "./chunk-D7FPVZDC.js";
|
|
97
88
|
import {
|
|
98
89
|
conversationLogPath,
|
|
99
90
|
ensureSessionStarted
|
|
100
|
-
} from "./chunk-
|
|
91
|
+
} from "./chunk-I6XWCKKW.js";
|
|
101
92
|
import {
|
|
102
93
|
INSTRUCTIONS_FILENAME,
|
|
103
94
|
MAX_CHARS_PER_FILE,
|
|
@@ -107,16 +98,31 @@ import {
|
|
|
107
98
|
} from "./chunk-H6B6AROX.js";
|
|
108
99
|
import {
|
|
109
100
|
ensurePrivateStateDirectory
|
|
110
|
-
} from "./chunk-
|
|
101
|
+
} from "./chunk-HHKKHUJK.js";
|
|
102
|
+
import {
|
|
103
|
+
compilePermissions,
|
|
104
|
+
isPermissionEffect
|
|
105
|
+
} from "./chunk-QVMTUMTW.js";
|
|
106
|
+
import {
|
|
107
|
+
cliLogger
|
|
108
|
+
} from "./chunk-23SR4YFL.js";
|
|
109
|
+
import {
|
|
110
|
+
probeCapabilities
|
|
111
|
+
} from "./chunk-OH6TB27S.js";
|
|
112
|
+
import {
|
|
113
|
+
activeZenCatalogue,
|
|
114
|
+
isOfferableModel
|
|
115
|
+
} from "./chunk-U3JIZFOS.js";
|
|
111
116
|
import {
|
|
112
117
|
restrictToOwner
|
|
113
|
-
} from "./chunk-
|
|
118
|
+
} from "./chunk-ZRAALEF2.js";
|
|
114
119
|
import {
|
|
115
120
|
namzuHomePath
|
|
116
|
-
} from "./chunk-
|
|
121
|
+
} from "./chunk-WWE4W2R6.js";
|
|
117
122
|
import {
|
|
118
123
|
AgentManager,
|
|
119
124
|
AgentRegistry,
|
|
125
|
+
AuthorizationGate,
|
|
120
126
|
BOOT_EVENT_NAMES,
|
|
121
127
|
BackgroundJobRegistry,
|
|
122
128
|
CODING_AGENT_DELEGATION_DOCTRINE,
|
|
@@ -148,6 +154,7 @@ import {
|
|
|
148
154
|
MarkdownMemoryStore,
|
|
149
155
|
MemoryContentRejectedError,
|
|
150
156
|
MemoryNameConflictError,
|
|
157
|
+
NOOP_LOGGER,
|
|
151
158
|
PLAN_MODE_DOCTRINE,
|
|
152
159
|
PluginLifecycleManager,
|
|
153
160
|
PluginRegistry,
|
|
@@ -221,6 +228,7 @@ import {
|
|
|
221
228
|
isCompactionMessage,
|
|
222
229
|
isEntityId,
|
|
223
230
|
isProjectInstructionMessageSource,
|
|
231
|
+
isReminderMessage,
|
|
224
232
|
isReviewExempt,
|
|
225
233
|
isTerminalAgentTaskState,
|
|
226
234
|
isTerminalStatus,
|
|
@@ -228,8 +236,10 @@ import {
|
|
|
228
236
|
isTrustedReadOnly,
|
|
229
237
|
isTurnInProgressError,
|
|
230
238
|
isolationOf,
|
|
239
|
+
lexShellCommandLine,
|
|
231
240
|
mapTools,
|
|
232
241
|
mcpJsonSchemaToZod,
|
|
242
|
+
modelReadsImages,
|
|
233
243
|
openSessionTokenBudget,
|
|
234
244
|
parseWorkflowMeta,
|
|
235
245
|
query,
|
|
@@ -238,6 +248,7 @@ import {
|
|
|
238
248
|
refineEvidenceRecallTerms,
|
|
239
249
|
requireOpenProject,
|
|
240
250
|
resolveContextWindow,
|
|
251
|
+
resolveModelPricing,
|
|
241
252
|
resolveNamzuHome,
|
|
242
253
|
resolveWithinReal,
|
|
243
254
|
resumeSession,
|
|
@@ -252,7 +263,7 @@ import {
|
|
|
252
263
|
windowsShellNotice,
|
|
253
264
|
withProviderFallback,
|
|
254
265
|
wrapUntrusted
|
|
255
|
-
} from "./chunk-
|
|
266
|
+
} from "./chunk-FLUVTAXY.js";
|
|
256
267
|
import {
|
|
257
268
|
__name
|
|
258
269
|
} from "./chunk-76FLAFCG.js";
|
|
@@ -303,6 +314,46 @@ function createCurrentCredentialReader() {
|
|
|
303
314
|
}
|
|
304
315
|
__name(createCurrentCredentialReader, "createCurrentCredentialReader");
|
|
305
316
|
|
|
317
|
+
// src/integrations/providers/image-input.ts
|
|
318
|
+
var TextOnlyModels = class {
|
|
319
|
+
static {
|
|
320
|
+
__name(this, "TextOnlyModels");
|
|
321
|
+
}
|
|
322
|
+
known = /* @__PURE__ */ new Set();
|
|
323
|
+
key(providerId, model) {
|
|
324
|
+
return `${providerId}/${model}`;
|
|
325
|
+
}
|
|
326
|
+
add(providerId, model) {
|
|
327
|
+
this.known.add(this.key(providerId, model));
|
|
328
|
+
}
|
|
329
|
+
has(providerId, model) {
|
|
330
|
+
return this.known.has(this.key(providerId, model));
|
|
331
|
+
}
|
|
332
|
+
/** Whether a request for `model` through `provider` may carry images. */
|
|
333
|
+
reads(provider, model) {
|
|
334
|
+
return !this.has(provider.id, model) && modelReadsImages(provider, model);
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* `provider`, answering for what this conversation has learned. A proxy and
|
|
338
|
+
* not a copy, so every other member (private state, later-added methods)
|
|
339
|
+
* stays the provider's own.
|
|
340
|
+
*/
|
|
341
|
+
informing(provider) {
|
|
342
|
+
const prefix = `${provider.id}/`;
|
|
343
|
+
if (![...this.known].some((entry) => entry.startsWith(prefix))) return provider;
|
|
344
|
+
const known = this;
|
|
345
|
+
return new Proxy(provider, {
|
|
346
|
+
get(target, property) {
|
|
347
|
+
if (property === "supportsImageInputFor") {
|
|
348
|
+
return (model) => !known.has(target.id, model) && (target.supportsImageInputFor?.(model) ?? true);
|
|
349
|
+
}
|
|
350
|
+
const value = Reflect.get(target, property, target);
|
|
351
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
};
|
|
356
|
+
|
|
306
357
|
// src/integrations/web/open-url.ts
|
|
307
358
|
var OPEN_URL_TOOL_NAME = "open_url";
|
|
308
359
|
var inputSchema = {
|
|
@@ -367,10 +418,10 @@ var tail = Promise.resolve();
|
|
|
367
418
|
var nextStart = 0;
|
|
368
419
|
function cancelled(promise, signal) {
|
|
369
420
|
signal.throwIfAborted();
|
|
370
|
-
return new Promise((
|
|
421
|
+
return new Promise((resolve11, reject) => {
|
|
371
422
|
const abort = /* @__PURE__ */ __name(() => reject(signal.reason), "abort");
|
|
372
423
|
signal.addEventListener("abort", abort, { once: true });
|
|
373
|
-
promise.then(
|
|
424
|
+
promise.then(resolve11, reject).finally(() => signal.removeEventListener("abort", abort));
|
|
374
425
|
});
|
|
375
426
|
}
|
|
376
427
|
__name(cancelled, "cancelled");
|
|
@@ -411,8 +462,8 @@ async function searchExa(query2, limit, context) {
|
|
|
411
462
|
const deadline = Date.now() + DEADLINE_MS;
|
|
412
463
|
const previous = tail;
|
|
413
464
|
let release;
|
|
414
|
-
tail = new Promise((
|
|
415
|
-
release =
|
|
465
|
+
tail = new Promise((resolve11) => {
|
|
466
|
+
release = resolve11;
|
|
416
467
|
});
|
|
417
468
|
let acquired = false;
|
|
418
469
|
try {
|
|
@@ -929,7 +980,7 @@ __name(oneLine, "oneLine");
|
|
|
929
980
|
// src/tui/agent.ts
|
|
930
981
|
import { SubprocessComputerUseHost } from "@namzu/computer-use";
|
|
931
982
|
import { realpath as realpath4, stat as stat4 } from "node:fs/promises";
|
|
932
|
-
import { join as
|
|
983
|
+
import { join as join14, parse, resolve as resolve10 } from "node:path";
|
|
933
984
|
|
|
934
985
|
// src/checkpoints/store.ts
|
|
935
986
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
@@ -2334,6 +2385,11 @@ function createSessionDirectories(cwd, directories) {
|
|
|
2334
2385
|
}
|
|
2335
2386
|
__name(createSessionDirectories, "createSessionDirectories");
|
|
2336
2387
|
|
|
2388
|
+
// src/context/doctrine.ts
|
|
2389
|
+
var NAMZU_PLAN_FILE_DOCTRINE = `## Plan mode
|
|
2390
|
+
|
|
2391
|
+
You are in plan mode. Read, search and think; the only file you may change is the plan file named in the plan-mode reminder. Any other \`edit\`, \`write\` or shell command that changes state will be refused. Write the plan into the plan file, then call \`exit_plan_mode\` so the user can approve it; do not ask for approval in plain text. If the user sends you back with feedback, revise the plan file and call it again.`;
|
|
2392
|
+
|
|
2337
2393
|
// src/context/project-tracker.ts
|
|
2338
2394
|
import { realpathSync } from "node:fs";
|
|
2339
2395
|
import { dirname as dirname2, isAbsolute as isAbsolute3, join as join3, relative as relative3, resolve as resolve3, sep as sep2 } from "node:path";
|
|
@@ -3943,7 +3999,7 @@ async function searchConversationCore(sessions, sessionId, request, signal, acti
|
|
|
3943
3999
|
result.excludedToolResults = (result.excludedToolResults ?? 0) + page.excludedToolResults;
|
|
3944
4000
|
if (page.excludedSummaries)
|
|
3945
4001
|
result.excludedSummaries = (result.excludedSummaries ?? 0) + page.excludedSummaries;
|
|
3946
|
-
const
|
|
4002
|
+
const matches = page.matches.map(
|
|
3947
4003
|
(match) => ({
|
|
3948
4004
|
seq: match.seq,
|
|
3949
4005
|
recordedAt: match.recordedAt,
|
|
@@ -3958,11 +4014,11 @@ async function searchConversationCore(sessions, sessionId, request, signal, acti
|
|
|
3958
4014
|
...match.characterOffset === void 0 ? {} : { byteOffset: match.byteOffset }
|
|
3959
4015
|
})
|
|
3960
4016
|
);
|
|
3961
|
-
const bytes = Buffer.byteLength(JSON.stringify(
|
|
4017
|
+
const bytes = Buffer.byteLength(JSON.stringify(matches));
|
|
3962
4018
|
if (outputBytes + bytes > OUTPUT_BYTES)
|
|
3963
4019
|
throw new Error("Evidence exceeded its output allowance.");
|
|
3964
4020
|
outputBytes += bytes;
|
|
3965
|
-
result.matches.push(...
|
|
4021
|
+
result.matches.push(...matches);
|
|
3966
4022
|
result.unavailable += page.unavailable.length;
|
|
3967
4023
|
result.incomplete ||= page.incomplete || page.unavailable.length > 0;
|
|
3968
4024
|
state.omitted ||= page.incomplete || page.unavailable.length > 0;
|
|
@@ -4235,15 +4291,15 @@ function newScan(terms) {
|
|
|
4235
4291
|
return { terms, started: false };
|
|
4236
4292
|
}
|
|
4237
4293
|
__name(newScan, "newScan");
|
|
4238
|
-
function advanceScan(scans,
|
|
4239
|
-
|
|
4240
|
-
|
|
4294
|
+
function advanceScan(scans, scan2, nextCursor, excerpts, hasDerivedSummaries, canRefine) {
|
|
4295
|
+
scan2.started = true;
|
|
4296
|
+
scan2.cursor = nextCursor;
|
|
4241
4297
|
if (!canRefine || scans.length !== 1 || !nextCursor) return;
|
|
4242
4298
|
if (hasDerivedSummaries) {
|
|
4243
|
-
scans.push({ ...newScan(
|
|
4299
|
+
scans.push({ ...newScan(scan2.terms), excludeDerivedSummaries: true });
|
|
4244
4300
|
return;
|
|
4245
4301
|
}
|
|
4246
|
-
const focused = refineEvidenceRecallTerms(
|
|
4302
|
+
const focused = refineEvidenceRecallTerms(scan2.terms, excerpts);
|
|
4247
4303
|
if (focused) scans.push(newScan(focused));
|
|
4248
4304
|
}
|
|
4249
4305
|
__name(advanceScan, "advanceScan");
|
|
@@ -4268,8 +4324,8 @@ function createConversationEvidenceRecall(sessions, sessionId, assertOwner, reso
|
|
|
4268
4324
|
let excludedSummaries = 0;
|
|
4269
4325
|
const scans = [newScan(terms)];
|
|
4270
4326
|
for (let pages = 0; pages < RECALL_PAGES; pages++) {
|
|
4271
|
-
const
|
|
4272
|
-
if (!
|
|
4327
|
+
const scan2 = [...scans].reverse().find((s) => !s.started || s.cursor);
|
|
4328
|
+
if (!scan2) break;
|
|
4273
4329
|
signal.throwIfAborted();
|
|
4274
4330
|
const remaining = maxReadBytes - scannedBytes;
|
|
4275
4331
|
if (remaining < 1024 * 1024) {
|
|
@@ -4280,12 +4336,12 @@ function createConversationEvidenceRecall(sessions, sessionId, assertOwner, reso
|
|
|
4280
4336
|
sessions,
|
|
4281
4337
|
sessionId,
|
|
4282
4338
|
{
|
|
4283
|
-
terms:
|
|
4339
|
+
terms: scan2.terms,
|
|
4284
4340
|
matchMode: "token",
|
|
4285
4341
|
excludeSuccessfulTools: CONVERSATION_RETRIEVAL_TOOLS,
|
|
4286
|
-
excludeDerivedSummaries:
|
|
4342
|
+
excludeDerivedSummaries: scan2.excludeDerivedSummaries ?? false,
|
|
4287
4343
|
maxReadBytes: remaining,
|
|
4288
|
-
...
|
|
4344
|
+
...scan2.cursor ? { cursor: scan2.cursor } : {}
|
|
4289
4345
|
},
|
|
4290
4346
|
signal,
|
|
4291
4347
|
active
|
|
@@ -4316,7 +4372,7 @@ function createConversationEvidenceRecall(sessions, sessionId, assertOwner, reso
|
|
|
4316
4372
|
}
|
|
4317
4373
|
advanceScan(
|
|
4318
4374
|
scans,
|
|
4319
|
-
|
|
4375
|
+
scan2,
|
|
4320
4376
|
page.nextCursor,
|
|
4321
4377
|
page.matches.map((match) => match.text),
|
|
4322
4378
|
page.matches.some((match) => match.source === "compaction_shed:summary"),
|
|
@@ -4326,9 +4382,9 @@ function createConversationEvidenceRecall(sessions, sessionId, assertOwner, reso
|
|
|
4326
4382
|
}
|
|
4327
4383
|
assertOwner(turnId);
|
|
4328
4384
|
signal.throwIfAborted();
|
|
4329
|
-
const continuations = [...scans].reverse().filter((
|
|
4385
|
+
const continuations = [...scans].reverse().filter((scan2) => scan2.cursor !== void 0).map((scan2) => ({
|
|
4330
4386
|
toolName: "search_conversation",
|
|
4331
|
-
input: { cursor:
|
|
4387
|
+
input: { cursor: scan2.cursor }
|
|
4332
4388
|
}));
|
|
4333
4389
|
return {
|
|
4334
4390
|
candidates,
|
|
@@ -4433,6 +4489,150 @@ function createTaskContextStep(store, tenantId, now = Date.now) {
|
|
|
4433
4489
|
}
|
|
4434
4490
|
__name(createTaskContextStep, "createTaskContextStep");
|
|
4435
4491
|
|
|
4492
|
+
// src/integrations/small-model/route.ts
|
|
4493
|
+
function parseSmallModel(value, activeProviderId, isKnownProvider) {
|
|
4494
|
+
const slash = value.indexOf("/");
|
|
4495
|
+
if (slash > 0 && slash < value.length - 1) {
|
|
4496
|
+
const head = value.slice(0, slash);
|
|
4497
|
+
if (isKnownProvider(head)) return { providerId: head, model: value.slice(slash + 1) };
|
|
4498
|
+
}
|
|
4499
|
+
return { providerId: activeProviderId, model: value };
|
|
4500
|
+
}
|
|
4501
|
+
__name(parseSmallModel, "parseSmallModel");
|
|
4502
|
+
var NOT_A_CHAT_MODEL = /embed|moderat|whisper|transcri|tts|speech|image|dall-?e|realtime|audio/iu;
|
|
4503
|
+
function price(providerId, model) {
|
|
4504
|
+
if (model.inputPrice !== void 0 && model.outputPrice !== void 0) {
|
|
4505
|
+
return model.inputPrice + model.outputPrice;
|
|
4506
|
+
}
|
|
4507
|
+
const rates = resolveModelPricing(providerId, model.id);
|
|
4508
|
+
return rates === void 0 ? void 0 : rates.inputCostPer1M + rates.outputCostPer1M;
|
|
4509
|
+
}
|
|
4510
|
+
__name(price, "price");
|
|
4511
|
+
function cheapestTextModel(providerId, models, offerable = () => true) {
|
|
4512
|
+
let best;
|
|
4513
|
+
for (const model of models) {
|
|
4514
|
+
if (!model.supportsStreaming) continue;
|
|
4515
|
+
if (model.inputModalities !== void 0 && !model.inputModalities.includes("text")) continue;
|
|
4516
|
+
if (NOT_A_CHAT_MODEL.test(model.id)) continue;
|
|
4517
|
+
if (!offerable(model)) continue;
|
|
4518
|
+
const cost = price(providerId, model);
|
|
4519
|
+
if (cost === void 0) continue;
|
|
4520
|
+
if (best === void 0) {
|
|
4521
|
+
best = { model, cost };
|
|
4522
|
+
continue;
|
|
4523
|
+
}
|
|
4524
|
+
if (cost !== best.cost) {
|
|
4525
|
+
if (cost < best.cost) best = { model, cost };
|
|
4526
|
+
continue;
|
|
4527
|
+
}
|
|
4528
|
+
const window = model.contextWindow ?? 0;
|
|
4529
|
+
const bestWindow = best.model.contextWindow ?? 0;
|
|
4530
|
+
if (window > bestWindow || window === bestWindow && model.id.length < best.model.id.length) {
|
|
4531
|
+
best = { model, cost };
|
|
4532
|
+
}
|
|
4533
|
+
}
|
|
4534
|
+
return best?.model;
|
|
4535
|
+
}
|
|
4536
|
+
__name(cheapestTextModel, "cheapestTextModel");
|
|
4537
|
+
|
|
4538
|
+
// src/integrations/small-model/side-model.ts
|
|
4539
|
+
function estimateTokens(text) {
|
|
4540
|
+
return Math.ceil(text.length / 4);
|
|
4541
|
+
}
|
|
4542
|
+
__name(estimateTokens, "estimateTokens");
|
|
4543
|
+
function createSideModel(deps) {
|
|
4544
|
+
const routes = /* @__PURE__ */ new Map();
|
|
4545
|
+
const resolve11 = /* @__PURE__ */ __name(async (sessionId, signal) => {
|
|
4546
|
+
const active = deps.active();
|
|
4547
|
+
if (deps.configured !== void 0) {
|
|
4548
|
+
const target = parseSmallModel(deps.configured, active.providerId, deps.isKnownProvider);
|
|
4549
|
+
return { ...target, source: "configured" };
|
|
4550
|
+
}
|
|
4551
|
+
try {
|
|
4552
|
+
const provider = await deps.buildProvider(sessionId, active);
|
|
4553
|
+
if (provider.listModels === void 0) return { ...active, source: "main" };
|
|
4554
|
+
const listing = await runPickerProviderOperation(
|
|
4555
|
+
signal,
|
|
4556
|
+
(operationSignal) => provider.listModels(operationSignal)
|
|
4557
|
+
);
|
|
4558
|
+
const cheapest = cheapestTextModel(
|
|
4559
|
+
active.providerId,
|
|
4560
|
+
listing,
|
|
4561
|
+
(model) => deps.offerable ? deps.offerable(active.providerId, model) : true
|
|
4562
|
+
);
|
|
4563
|
+
if (cheapest !== void 0) {
|
|
4564
|
+
return {
|
|
4565
|
+
providerId: active.providerId,
|
|
4566
|
+
model: cheapest.id,
|
|
4567
|
+
source: "cheapest"
|
|
4568
|
+
};
|
|
4569
|
+
}
|
|
4570
|
+
} catch (error) {
|
|
4571
|
+
deps.debug?.("side model: listing failed, using the conversation model", error);
|
|
4572
|
+
}
|
|
4573
|
+
return { ...active, source: "main" };
|
|
4574
|
+
}, "resolve");
|
|
4575
|
+
const route = /* @__PURE__ */ __name((sessionId, signal) => {
|
|
4576
|
+
const active = deps.active();
|
|
4577
|
+
const key = `${active.providerId}
|
|
4578
|
+
${active.model}
|
|
4579
|
+
${deps.configured ?? ""}`;
|
|
4580
|
+
let pending = routes.get(key);
|
|
4581
|
+
if (pending === void 0) {
|
|
4582
|
+
pending = resolve11(sessionId, signal);
|
|
4583
|
+
routes.set(key, pending);
|
|
4584
|
+
void pending.then((value) => {
|
|
4585
|
+
if (signal.aborted && value.source === "main" && routes.get(key) === pending) {
|
|
4586
|
+
routes.delete(key);
|
|
4587
|
+
}
|
|
4588
|
+
});
|
|
4589
|
+
}
|
|
4590
|
+
return pending;
|
|
4591
|
+
}, "route");
|
|
4592
|
+
const ask = /* @__PURE__ */ __name(async (request) => {
|
|
4593
|
+
try {
|
|
4594
|
+
request.signal.throwIfAborted();
|
|
4595
|
+
const chosen = await route(request.sessionId, request.signal);
|
|
4596
|
+
const provider = await deps.buildProvider(request.sessionId, chosen);
|
|
4597
|
+
const estimatedPromptTokens = estimateTokens(request.instruction) + estimateTokens(request.body);
|
|
4598
|
+
const send = /* @__PURE__ */ __name(async () => {
|
|
4599
|
+
const response = await collectChatCompletion(
|
|
4600
|
+
provider.chatStream({
|
|
4601
|
+
model: chosen.model,
|
|
4602
|
+
messages: [createSystemMessage(request.instruction), createUserMessage(request.body)],
|
|
4603
|
+
maxTokens: request.maxTokens,
|
|
4604
|
+
signal: request.signal
|
|
4605
|
+
})
|
|
4606
|
+
);
|
|
4607
|
+
return { value: response.message.content ?? "", usage: response.usage };
|
|
4608
|
+
}, "send");
|
|
4609
|
+
if (request.timing === "in-turn") {
|
|
4610
|
+
const text = await deps.ledger.chargeNow({
|
|
4611
|
+
turnId: request.turnId,
|
|
4612
|
+
sessionId: request.sessionId,
|
|
4613
|
+
estimatedPromptTokens,
|
|
4614
|
+
signal: request.signal,
|
|
4615
|
+
request: send
|
|
4616
|
+
});
|
|
4617
|
+
return text?.trim() ? text : void 0;
|
|
4618
|
+
}
|
|
4619
|
+
const result = await send();
|
|
4620
|
+
void deps.ledger.chargeLater({
|
|
4621
|
+
turnId: request.turnId,
|
|
4622
|
+
sessionId: request.sessionId,
|
|
4623
|
+
estimatedPromptTokens,
|
|
4624
|
+
usage: result.usage
|
|
4625
|
+
});
|
|
4626
|
+
return result.value.trim() ? result.value : void 0;
|
|
4627
|
+
} catch (error) {
|
|
4628
|
+
deps.debug?.("side model: request failed", error);
|
|
4629
|
+
return void 0;
|
|
4630
|
+
}
|
|
4631
|
+
}, "ask");
|
|
4632
|
+
return { route, ask };
|
|
4633
|
+
}
|
|
4634
|
+
__name(createSideModel, "createSideModel");
|
|
4635
|
+
|
|
4436
4636
|
// src/integrations/state/retention.ts
|
|
4437
4637
|
var CLI_CHECKPOINT_RETENTION = 10;
|
|
4438
4638
|
|
|
@@ -6275,9 +6475,68 @@ async function createSubagentRuntime(input) {
|
|
|
6275
6475
|
throw error;
|
|
6276
6476
|
}
|
|
6277
6477
|
}, "gatewayForTurn");
|
|
6478
|
+
const queuedSideSpend = /* @__PURE__ */ new Map();
|
|
6479
|
+
const releasedTurns = /* @__PURE__ */ new Set();
|
|
6480
|
+
const countSideSpend = /* @__PURE__ */ __name(async (budget, spend) => {
|
|
6481
|
+
const controller = new AbortController();
|
|
6482
|
+
await chargeLabelRequest({
|
|
6483
|
+
budget,
|
|
6484
|
+
sessionId: spend.sessionId,
|
|
6485
|
+
estimatedPromptTokens: spend.estimatedPromptTokens,
|
|
6486
|
+
signal: controller.signal,
|
|
6487
|
+
request: /* @__PURE__ */ __name(async () => ({ value: true, usage: spend.usage }), "request")
|
|
6488
|
+
}).catch(() => void 0);
|
|
6489
|
+
}, "countSideSpend");
|
|
6490
|
+
const countQueuedSideSpend = /* @__PURE__ */ __name(async (turnId, pending) => {
|
|
6491
|
+
const queued = queuedSideSpend.get(turnId);
|
|
6492
|
+
if (queued === void 0) return;
|
|
6493
|
+
queuedSideSpend.delete(turnId);
|
|
6494
|
+
const runtime = await pending.catch(() => void 0);
|
|
6495
|
+
if (runtime === void 0) return;
|
|
6496
|
+
for (const spend of queued) await countSideSpend(runtime.budget, spend);
|
|
6497
|
+
}, "countQueuedSideSpend");
|
|
6498
|
+
const sideLedger = {
|
|
6499
|
+
async chargeNow(input2) {
|
|
6500
|
+
const turn = await parents.get(input2.turnId)?.catch(() => void 0);
|
|
6501
|
+
if (!turn || closed) return void 0;
|
|
6502
|
+
return chargeLabelRequest({
|
|
6503
|
+
budget: turn.budget,
|
|
6504
|
+
sessionId: input2.sessionId,
|
|
6505
|
+
estimatedPromptTokens: input2.estimatedPromptTokens,
|
|
6506
|
+
signal: input2.signal,
|
|
6507
|
+
request: input2.request
|
|
6508
|
+
});
|
|
6509
|
+
},
|
|
6510
|
+
async chargeLater(input2) {
|
|
6511
|
+
const spend = {
|
|
6512
|
+
sessionId: input2.sessionId,
|
|
6513
|
+
estimatedPromptTokens: input2.estimatedPromptTokens,
|
|
6514
|
+
usage: input2.usage
|
|
6515
|
+
};
|
|
6516
|
+
if (!releasedTurns.has(input2.turnId)) {
|
|
6517
|
+
const queue = queuedSideSpend.get(input2.turnId) ?? [];
|
|
6518
|
+
queue.push(spend);
|
|
6519
|
+
queuedSideSpend.set(input2.turnId, queue);
|
|
6520
|
+
return;
|
|
6521
|
+
}
|
|
6522
|
+
await openSessionTokenBudget({
|
|
6523
|
+
store: tokenBudgetStore,
|
|
6524
|
+
scope: { rootSessionId: input2.sessionId, rootTurnId: input2.turnId }
|
|
6525
|
+
}).then(
|
|
6526
|
+
(budget) => countSideSpend(budget, spend),
|
|
6527
|
+
() => void 0
|
|
6528
|
+
);
|
|
6529
|
+
}
|
|
6530
|
+
};
|
|
6278
6531
|
const releaseTurn = /* @__PURE__ */ __name(async (turnId) => {
|
|
6279
6532
|
const pending = parents.get(turnId);
|
|
6280
6533
|
if (!pending) return;
|
|
6534
|
+
await countQueuedSideSpend(turnId, pending);
|
|
6535
|
+
releasedTurns.add(turnId);
|
|
6536
|
+
if (releasedTurns.size > 256) {
|
|
6537
|
+
const oldest = releasedTurns.values().next().value;
|
|
6538
|
+
if (oldest !== void 0) releasedTurns.delete(oldest);
|
|
6539
|
+
}
|
|
6281
6540
|
parents.delete(turnId);
|
|
6282
6541
|
await pending.then(
|
|
6283
6542
|
(runtime) => runtime.close(),
|
|
@@ -7335,6 +7594,7 @@ ${JSON.stringify(launch.schema)}`;
|
|
|
7335
7594
|
gatewayForTurn,
|
|
7336
7595
|
completionInboxForTurn,
|
|
7337
7596
|
releaseTurn,
|
|
7597
|
+
sideLedger,
|
|
7338
7598
|
agentTool,
|
|
7339
7599
|
waitForTaskTool,
|
|
7340
7600
|
agentTaskListTool,
|
|
@@ -7732,11 +7992,11 @@ var WorkflowRunRegistry = class {
|
|
|
7732
7992
|
whenIdle(signal) {
|
|
7733
7993
|
const going = /* @__PURE__ */ __name(() => [...this.runs.values()].some((run2) => !run2.finalized), "going");
|
|
7734
7994
|
if (!going() || signal?.aborted) return Promise.resolve();
|
|
7735
|
-
return new Promise((
|
|
7995
|
+
return new Promise((resolve11) => {
|
|
7736
7996
|
const done = /* @__PURE__ */ __name(() => {
|
|
7737
7997
|
off();
|
|
7738
7998
|
signal?.removeEventListener("abort", done);
|
|
7739
|
-
|
|
7999
|
+
resolve11();
|
|
7740
8000
|
}, "done");
|
|
7741
8001
|
const off = this.subscribe(() => {
|
|
7742
8002
|
if (!going()) done();
|
|
@@ -7933,8 +8193,8 @@ function createWorkflowHost(options) {
|
|
|
7933
8193
|
let launching = true;
|
|
7934
8194
|
let settleLaunch = /* @__PURE__ */ __name(() => {
|
|
7935
8195
|
}, "settleLaunch");
|
|
7936
|
-
const launch = new Promise((
|
|
7937
|
-
settleLaunch =
|
|
8196
|
+
const launch = new Promise((resolve11) => {
|
|
8197
|
+
settleLaunch = resolve11;
|
|
7938
8198
|
});
|
|
7939
8199
|
const detach = /* @__PURE__ */ __name(() => {
|
|
7940
8200
|
if (!launching) return;
|
|
@@ -8743,28 +9003,249 @@ function createLiveModeControl(options) {
|
|
|
8743
9003
|
}
|
|
8744
9004
|
__name(createLiveModeControl, "createLiveModeControl");
|
|
8745
9005
|
|
|
9006
|
+
// src/permissions/local-settings.ts
|
|
9007
|
+
import { execFile as execFile3 } from "node:child_process";
|
|
9008
|
+
import { existsSync, readFileSync, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
9009
|
+
import { appendFile as appendFile3, mkdir as mkdir5, readFile as readFile5, writeFile as writeFile3 } from "node:fs/promises";
|
|
9010
|
+
import { homedir } from "node:os";
|
|
9011
|
+
import { dirname as dirname3, isAbsolute as isAbsolute6, join as join13, resolve as resolve8 } from "node:path";
|
|
9012
|
+
function localConfigPath(cwd) {
|
|
9013
|
+
return resolve8(cwd, LOCAL_CONFIG_FILE);
|
|
9014
|
+
}
|
|
9015
|
+
__name(localConfigPath, "localConfigPath");
|
|
9016
|
+
function isRecord2(value) {
|
|
9017
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
9018
|
+
}
|
|
9019
|
+
__name(isRecord2, "isRecord");
|
|
9020
|
+
function addAllowRules(permissions, additions) {
|
|
9021
|
+
const out = { ...permissions };
|
|
9022
|
+
for (const [tool, wanted] of Object.entries(additions)) {
|
|
9023
|
+
const existing = out[tool];
|
|
9024
|
+
if (existing === void 0) {
|
|
9025
|
+
out[tool] = wanted;
|
|
9026
|
+
continue;
|
|
9027
|
+
}
|
|
9028
|
+
if (isPermissionEffect(existing)) continue;
|
|
9029
|
+
if (!isRecord2(existing)) continue;
|
|
9030
|
+
if (isPermissionEffect(wanted)) {
|
|
9031
|
+
continue;
|
|
9032
|
+
}
|
|
9033
|
+
const table = { ...existing };
|
|
9034
|
+
for (const [pattern, effect] of Object.entries(wanted)) {
|
|
9035
|
+
if (table[pattern] === void 0) table[pattern] = effect;
|
|
9036
|
+
}
|
|
9037
|
+
out[tool] = table;
|
|
9038
|
+
}
|
|
9039
|
+
return out;
|
|
9040
|
+
}
|
|
9041
|
+
__name(addAllowRules, "addAllowRules");
|
|
9042
|
+
function writeLocalAllows(cwd, additions) {
|
|
9043
|
+
const path = localConfigPath(cwd);
|
|
9044
|
+
let document = {};
|
|
9045
|
+
if (existsSync(path)) {
|
|
9046
|
+
let parsed;
|
|
9047
|
+
try {
|
|
9048
|
+
parsed = JSON.parse(readFileSync(path, "utf-8"));
|
|
9049
|
+
} catch (cause) {
|
|
9050
|
+
return {
|
|
9051
|
+
path,
|
|
9052
|
+
error: `${LOCAL_CONFIG_FILE} is not valid JSON (${cause instanceof Error ? cause.message : String(cause)})`
|
|
9053
|
+
};
|
|
9054
|
+
}
|
|
9055
|
+
if (!isRecord2(parsed)) return { path, error: `${LOCAL_CONFIG_FILE} is not a JSON object` };
|
|
9056
|
+
document = parsed;
|
|
9057
|
+
}
|
|
9058
|
+
const permissions = isRecord2(document.permissions) ? document.permissions : {};
|
|
9059
|
+
if (document.permissions !== void 0 && !isRecord2(document.permissions)) {
|
|
9060
|
+
return { path, error: `${LOCAL_CONFIG_FILE} has a permissions value that is not a table` };
|
|
9061
|
+
}
|
|
9062
|
+
document = { ...document, permissions: addAllowRules(permissions, additions) };
|
|
9063
|
+
try {
|
|
9064
|
+
const staging = `${path}.${process.pid}.tmp`;
|
|
9065
|
+
writeFileSync2(staging, `${JSON.stringify(document, null, " ")}
|
|
9066
|
+
`, { mode: 384 });
|
|
9067
|
+
renameSync2(staging, path);
|
|
9068
|
+
} catch (cause) {
|
|
9069
|
+
return { path, error: cause instanceof Error ? cause.message : String(cause) };
|
|
9070
|
+
}
|
|
9071
|
+
return { path };
|
|
9072
|
+
}
|
|
9073
|
+
__name(writeLocalAllows, "writeLocalAllows");
|
|
9074
|
+
function git2(args, cwd, env) {
|
|
9075
|
+
return new Promise((done) => {
|
|
9076
|
+
execFile3(
|
|
9077
|
+
"git",
|
|
9078
|
+
[...args],
|
|
9079
|
+
{ cwd, env, timeout: 15e3, windowsHide: true },
|
|
9080
|
+
(error, stdout) => {
|
|
9081
|
+
const code = error === null ? 0 : typeof error.code === "number" ? error.code : 1;
|
|
9082
|
+
done({ code, stdout: String(stdout ?? "") });
|
|
9083
|
+
}
|
|
9084
|
+
);
|
|
9085
|
+
});
|
|
9086
|
+
}
|
|
9087
|
+
__name(git2, "git");
|
|
9088
|
+
function globalIgnorePath(configured, env) {
|
|
9089
|
+
const home = env.HOME ?? env.USERPROFILE ?? homedir();
|
|
9090
|
+
const value = configured.trim();
|
|
9091
|
+
if (value === "~" || value.startsWith("~/")) return join13(home, value.slice(2));
|
|
9092
|
+
if (value !== "" && isAbsolute6(value)) return value;
|
|
9093
|
+
const xdg = env.XDG_CONFIG_HOME;
|
|
9094
|
+
if (xdg && isAbsolute6(xdg)) return join13(xdg, "git", "ignore");
|
|
9095
|
+
return join13(home, ".config", "git", "ignore");
|
|
9096
|
+
}
|
|
9097
|
+
__name(globalIgnorePath, "globalIgnorePath");
|
|
9098
|
+
async function ensureLocalConfigIgnored(cwd, env = process.env) {
|
|
9099
|
+
try {
|
|
9100
|
+
const inside = await git2(["rev-parse", "--is-inside-work-tree"], cwd, env);
|
|
9101
|
+
if (inside.code !== 0 || inside.stdout.trim() !== "true") return { state: "not-a-repository" };
|
|
9102
|
+
const ignored = /* @__PURE__ */ __name(async () => (await git2(["check-ignore", "--", LOCAL_CONFIG_FILE], cwd, env)).code === 0, "ignored");
|
|
9103
|
+
if (await ignored()) return { state: "ignored", written: false };
|
|
9104
|
+
const configured = await git2(["config", "--global", "--get", "core.excludesfile"], cwd, env);
|
|
9105
|
+
const file = globalIgnorePath(configured.code === 0 ? configured.stdout : "", env);
|
|
9106
|
+
const line = `**/${LOCAL_CONFIG_FILE}`;
|
|
9107
|
+
await mkdir5(dirname3(file), { recursive: true });
|
|
9108
|
+
let existing = "";
|
|
9109
|
+
try {
|
|
9110
|
+
existing = await readFile5(file, "utf-8");
|
|
9111
|
+
} catch {
|
|
9112
|
+
}
|
|
9113
|
+
const why = /* @__PURE__ */ __name(async () => (await git2(["ls-files", "--error-unmatch", "--", LOCAL_CONFIG_FILE], cwd, env)).code === 0 ? "tracked" : "not-read", "why");
|
|
9114
|
+
if (existing.includes(line)) {
|
|
9115
|
+
const reason = await why();
|
|
9116
|
+
return { state: reason, reason: `${line} is in ${file} but git does not ignore the file` };
|
|
9117
|
+
}
|
|
9118
|
+
if (existing === "") await writeFile3(file, `${line}
|
|
9119
|
+
`, "utf-8");
|
|
9120
|
+
else await appendFile3(file, `${existing.endsWith("\n") ? "" : "\n"}${line}
|
|
9121
|
+
`, "utf-8");
|
|
9122
|
+
if (!await ignored()) {
|
|
9123
|
+
const reason = await why();
|
|
9124
|
+
return { state: reason, reason: `wrote ${line} to ${file} but git still does not ignore it` };
|
|
9125
|
+
}
|
|
9126
|
+
return { state: "ignored", written: true };
|
|
9127
|
+
} catch (cause) {
|
|
9128
|
+
return { state: "failed", reason: cause instanceof Error ? cause.message : String(cause) };
|
|
9129
|
+
}
|
|
9130
|
+
}
|
|
9131
|
+
__name(ensureLocalConfigIgnored, "ensureLocalConfigIgnored");
|
|
9132
|
+
function logIgnoreOutcome(outcome) {
|
|
9133
|
+
if (outcome.state === "ignored" || outcome.state === "not-a-repository") return;
|
|
9134
|
+
cliLogger().warn("The local config may be tracked by git", {
|
|
9135
|
+
"namzu.config.local.state": outcome.state,
|
|
9136
|
+
"namzu.config.local.reason": outcome.reason
|
|
9137
|
+
});
|
|
9138
|
+
}
|
|
9139
|
+
__name(logIgnoreOutcome, "logIgnoreOutcome");
|
|
9140
|
+
|
|
8746
9141
|
// src/permissions/session-allow.ts
|
|
8747
9142
|
var WEB_FETCH_TOOL = "web_fetch";
|
|
8748
9143
|
var MAX_LABEL_COMMAND = 60;
|
|
8749
|
-
|
|
9144
|
+
var MAX_RULES_PER_ANSWER = 5;
|
|
9145
|
+
function isRecord3(value) {
|
|
8750
9146
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8751
9147
|
}
|
|
8752
|
-
__name(
|
|
9148
|
+
__name(isRecord3, "isRecord");
|
|
8753
9149
|
function alwaysAsked(call) {
|
|
8754
9150
|
return call.escalation !== void 0 || call.requiresApproval === true || call.authorization?.explicitReview === true || call.isDestructive === true;
|
|
8755
9151
|
}
|
|
8756
9152
|
__name(alwaysAsked, "alwaysAsked");
|
|
8757
|
-
|
|
9153
|
+
var NO_PREFIX_PROGRAMS = /* @__PURE__ */ new Set([
|
|
9154
|
+
"sh",
|
|
9155
|
+
"bash",
|
|
9156
|
+
"zsh",
|
|
9157
|
+
"fish",
|
|
9158
|
+
"csh",
|
|
9159
|
+
"tcsh",
|
|
9160
|
+
"ksh",
|
|
9161
|
+
"dash",
|
|
9162
|
+
"cmd",
|
|
9163
|
+
"powershell",
|
|
9164
|
+
"pwsh",
|
|
9165
|
+
"env",
|
|
9166
|
+
"xargs",
|
|
9167
|
+
"command",
|
|
9168
|
+
"builtin",
|
|
9169
|
+
"noglob",
|
|
9170
|
+
"nice",
|
|
9171
|
+
"stdbuf",
|
|
9172
|
+
"nohup",
|
|
9173
|
+
"timeout",
|
|
9174
|
+
"time",
|
|
9175
|
+
"watch",
|
|
9176
|
+
"ionice",
|
|
9177
|
+
"chrt",
|
|
9178
|
+
"setsid",
|
|
9179
|
+
"taskset",
|
|
9180
|
+
"strace",
|
|
9181
|
+
"ltrace",
|
|
9182
|
+
"script",
|
|
9183
|
+
"flock",
|
|
9184
|
+
"unshare",
|
|
9185
|
+
"nsenter",
|
|
9186
|
+
"sudo",
|
|
9187
|
+
"doas",
|
|
9188
|
+
"pkexec",
|
|
9189
|
+
"su",
|
|
9190
|
+
"runuser"
|
|
9191
|
+
]);
|
|
9192
|
+
var SUBCOMMAND = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;
|
|
9193
|
+
var ASSIGNMENT = /^[A-Za-z_]\w*=/;
|
|
9194
|
+
var PLAIN_PROGRAM = /^[\w./+@:-]+$/;
|
|
9195
|
+
var NOT_EXACT = /[\n\r;&|<>`$()*?{}\\]/;
|
|
9196
|
+
function programName(word) {
|
|
9197
|
+
return word.slice(word.lastIndexOf("/") + 1);
|
|
9198
|
+
}
|
|
9199
|
+
__name(programName, "programName");
|
|
9200
|
+
function twoWordPrefix(command) {
|
|
9201
|
+
const words = command.trim().split(/\s+/).filter(Boolean);
|
|
9202
|
+
const [program, subcommand] = words;
|
|
9203
|
+
if (words.length < 2 || program === void 0 || subcommand === void 0) return void 0;
|
|
9204
|
+
if (ASSIGNMENT.test(program)) return void 0;
|
|
9205
|
+
if (!PLAIN_PROGRAM.test(program) || NO_PREFIX_PROGRAMS.has(programName(program))) return void 0;
|
|
9206
|
+
if (!SUBCOMMAND.test(subcommand)) return void 0;
|
|
9207
|
+
return `${program} ${subcommand}`;
|
|
9208
|
+
}
|
|
9209
|
+
__name(twoWordPrefix, "twoWordPrefix");
|
|
9210
|
+
function allowForCommand(tool, command) {
|
|
9211
|
+
if (NOT_EXACT.test(command)) return void 0;
|
|
9212
|
+
const prefix = programName(command.split(/\s+/)[0] ?? "") === "cd" ? void 0 : twoWordPrefix(command);
|
|
9213
|
+
if (prefix !== void 0) return { kind: "prefix", tool, prefix };
|
|
9214
|
+
return { kind: "command", tool, command };
|
|
9215
|
+
}
|
|
9216
|
+
__name(allowForCommand, "allowForCommand");
|
|
9217
|
+
function plainCommands(line) {
|
|
9218
|
+
const lexed = lexShellCommandLine(line, { dialect: "bash" });
|
|
9219
|
+
if (!lexed.complete || lexed.opaque || lexed.commands.length === 0) return void 0;
|
|
9220
|
+
if (lexed.redirections.length > 0 || lexed.compoundWords.length > 0) return void 0;
|
|
9221
|
+
const out = [];
|
|
9222
|
+
for (const command of lexed.commands) {
|
|
9223
|
+
if (command.origin !== "line" || command.redirections.length > 0) return void 0;
|
|
9224
|
+
const text = command.text.trim();
|
|
9225
|
+
if (text === "") return void 0;
|
|
9226
|
+
out.push(text);
|
|
9227
|
+
}
|
|
9228
|
+
return out;
|
|
9229
|
+
}
|
|
9230
|
+
__name(plainCommands, "plainCommands");
|
|
9231
|
+
function allowsFor(call, commands) {
|
|
8758
9232
|
if (alwaysAsked(call)) return void 0;
|
|
8759
|
-
const input =
|
|
9233
|
+
const input = isRecord3(call.input) ? call.input : void 0;
|
|
8760
9234
|
const commandArgument = commands.get(call.name);
|
|
8761
9235
|
if (commandArgument !== void 0) {
|
|
8762
9236
|
const line = input?.[commandArgument];
|
|
8763
9237
|
if (typeof line !== "string") return void 0;
|
|
8764
|
-
const command = line.trim();
|
|
8765
|
-
if (command === "" || /[\n\r;&|<>`$()*?{}\\]/.test(command)) return void 0;
|
|
8766
9238
|
if (input?.dangerously_disable_sandbox === true) return void 0;
|
|
8767
|
-
|
|
9239
|
+
if (line.trim() === "" || /[\n\r]/.test(line.trim())) return void 0;
|
|
9240
|
+
const parts = plainCommands(line);
|
|
9241
|
+
if (parts === void 0) return void 0;
|
|
9242
|
+
const out = [];
|
|
9243
|
+
for (const part of parts) {
|
|
9244
|
+
const allow = allowForCommand(call.name, part);
|
|
9245
|
+
if (allow === void 0) return void 0;
|
|
9246
|
+
if (!out.some((existing) => sameAllow(existing, allow))) out.push(allow);
|
|
9247
|
+
}
|
|
9248
|
+
return out.length > 0 && out.length <= MAX_RULES_PER_ANSWER ? out : void 0;
|
|
8768
9249
|
}
|
|
8769
9250
|
if (call.name === WEB_FETCH_TOOL) {
|
|
8770
9251
|
const url = input?.url;
|
|
@@ -8772,29 +9253,32 @@ function allowFor(call, commands) {
|
|
|
8772
9253
|
try {
|
|
8773
9254
|
const host = new URL(url).hostname;
|
|
8774
9255
|
if (host === "" || host.includes("*")) return void 0;
|
|
8775
|
-
return { kind: "host", tool: call.name, host };
|
|
9256
|
+
return [{ kind: "host", tool: call.name, host }];
|
|
8776
9257
|
} catch {
|
|
8777
9258
|
return void 0;
|
|
8778
9259
|
}
|
|
8779
9260
|
}
|
|
8780
|
-
if (call.name.startsWith("mcp__")) return { kind: "tool", tool: call.name };
|
|
9261
|
+
if (call.name.startsWith("mcp__")) return [{ kind: "tool", tool: call.name }];
|
|
8781
9262
|
return void 0;
|
|
8782
9263
|
}
|
|
8783
|
-
__name(
|
|
9264
|
+
__name(allowsFor, "allowsFor");
|
|
8784
9265
|
function allowsForBatch(calls, commands) {
|
|
8785
9266
|
if (calls.length === 0) return void 0;
|
|
8786
9267
|
const out = [];
|
|
8787
9268
|
for (const call of calls) {
|
|
8788
|
-
const
|
|
8789
|
-
if (!
|
|
8790
|
-
|
|
9269
|
+
const allows = allowsFor(call, commands);
|
|
9270
|
+
if (!allows) return void 0;
|
|
9271
|
+
for (const allow of allows) {
|
|
9272
|
+
if (!out.some((existing) => sameAllow(existing, allow))) out.push(allow);
|
|
9273
|
+
}
|
|
8791
9274
|
}
|
|
8792
|
-
return out;
|
|
9275
|
+
return out.length <= MAX_RULES_PER_ANSWER ? out : void 0;
|
|
8793
9276
|
}
|
|
8794
9277
|
__name(allowsForBatch, "allowsForBatch");
|
|
8795
9278
|
function sameAllow(a, b) {
|
|
8796
9279
|
if (a.kind !== b.kind || a.tool !== b.tool) return false;
|
|
8797
9280
|
if (a.kind === "command" && b.kind === "command") return a.command === b.command;
|
|
9281
|
+
if (a.kind === "prefix" && b.kind === "prefix") return a.prefix === b.prefix;
|
|
8798
9282
|
if (a.kind === "host" && b.kind === "host") return a.host === b.host;
|
|
8799
9283
|
return true;
|
|
8800
9284
|
}
|
|
@@ -8808,6 +9292,8 @@ function describeAllows(allows) {
|
|
|
8808
9292
|
switch (allow.kind) {
|
|
8809
9293
|
case "command":
|
|
8810
9294
|
return `${shorten(allow.command)} commands`;
|
|
9295
|
+
case "prefix":
|
|
9296
|
+
return `${shorten(allow.prefix)} * commands`;
|
|
8811
9297
|
case "host":
|
|
8812
9298
|
return allow.host;
|
|
8813
9299
|
case "tool":
|
|
@@ -8817,47 +9303,237 @@ function describeAllows(allows) {
|
|
|
8817
9303
|
return parts.length <= 1 ? parts[0] ?? "" : `${parts.slice(0, -1).join(", ")} and ${parts.at(-1)}`;
|
|
8818
9304
|
}
|
|
8819
9305
|
__name(describeAllows, "describeAllows");
|
|
8820
|
-
function
|
|
8821
|
-
|
|
8822
|
-
|
|
8823
|
-
|
|
8824
|
-
|
|
8825
|
-
|
|
8826
|
-
|
|
8827
|
-
|
|
8828
|
-
|
|
8829
|
-
|
|
8830
|
-
|
|
8831
|
-
|
|
8832
|
-
|
|
8833
|
-
|
|
8834
|
-
|
|
8835
|
-
|
|
8836
|
-
|
|
8837
|
-
|
|
8838
|
-
|
|
9306
|
+
function permissionsForAllows(allows) {
|
|
9307
|
+
const table = {};
|
|
9308
|
+
const pattern = /* @__PURE__ */ __name((tool, glob) => {
|
|
9309
|
+
const existing = table[tool];
|
|
9310
|
+
const patterns = typeof existing === "object" ? existing : {};
|
|
9311
|
+
patterns[glob] = "allow";
|
|
9312
|
+
table[tool] = patterns;
|
|
9313
|
+
}, "pattern");
|
|
9314
|
+
for (const allow of allows) {
|
|
9315
|
+
switch (allow.kind) {
|
|
9316
|
+
case "command":
|
|
9317
|
+
pattern(allow.tool, allow.command);
|
|
9318
|
+
break;
|
|
9319
|
+
case "prefix":
|
|
9320
|
+
pattern(allow.tool, `${allow.prefix} *`);
|
|
9321
|
+
break;
|
|
9322
|
+
case "host":
|
|
9323
|
+
pattern(allow.tool, `http://${allow.host}/*`);
|
|
9324
|
+
pattern(allow.tool, `https://${allow.host}/*`);
|
|
9325
|
+
break;
|
|
9326
|
+
case "tool":
|
|
9327
|
+
table[allow.tool] = "allow";
|
|
9328
|
+
break;
|
|
8839
9329
|
}
|
|
8840
9330
|
}
|
|
9331
|
+
return table;
|
|
8841
9332
|
}
|
|
8842
|
-
__name(
|
|
8843
|
-
function createSessionAllows(
|
|
9333
|
+
__name(permissionsForAllows, "permissionsForAllows");
|
|
9334
|
+
function createSessionAllows(_commands, options = {}) {
|
|
8844
9335
|
const entries = [];
|
|
9336
|
+
let gate;
|
|
9337
|
+
const rebuild = /* @__PURE__ */ __name(() => {
|
|
9338
|
+
const { rules } = compilePermissions(permissionsForAllows(entries));
|
|
9339
|
+
gate = rules.length === 0 ? void 0 : new AuthorizationGate(
|
|
9340
|
+
{
|
|
9341
|
+
enabled: true,
|
|
9342
|
+
rules: [...rules],
|
|
9343
|
+
allowReadOnlyTools: false,
|
|
9344
|
+
denyDangerousPatterns: false,
|
|
9345
|
+
logDecisions: false
|
|
9346
|
+
},
|
|
9347
|
+
NOOP_LOGGER
|
|
9348
|
+
);
|
|
9349
|
+
}, "rebuild");
|
|
9350
|
+
const allowed = /* @__PURE__ */ __name((call) => {
|
|
9351
|
+
if (isRecord3(call.toolInput) && call.toolInput.dangerously_disable_sandbox === true)
|
|
9352
|
+
return false;
|
|
9353
|
+
const result = gate?.evaluate(call);
|
|
9354
|
+
return result !== void 0 && result.matchedRule !== null && result.decision === "allow";
|
|
9355
|
+
}, "allowed");
|
|
8845
9356
|
return {
|
|
8846
9357
|
add(allows) {
|
|
8847
|
-
|
|
8848
|
-
|
|
9358
|
+
const fresh = allows.filter(
|
|
9359
|
+
(allow) => !entries.some((existing) => sameAllow(existing, allow))
|
|
9360
|
+
);
|
|
9361
|
+
entries.push(...fresh);
|
|
9362
|
+
if (fresh.length > 0) rebuild();
|
|
9363
|
+
const cwd = typeof options.cwd === "function" ? options.cwd() : options.cwd;
|
|
9364
|
+
if (cwd === void 0) return void 0;
|
|
9365
|
+
const write = (options.persist ?? writeLocalAllows)(cwd, permissionsForAllows(allows));
|
|
9366
|
+
if (write.error !== void 0) {
|
|
9367
|
+
cliLogger().warn("Could not save a remembered answer", {
|
|
9368
|
+
"namzu.config.local.path": write.path,
|
|
9369
|
+
"namzu.config.local.error": write.error
|
|
9370
|
+
});
|
|
9371
|
+
return `Could not save this answer to ${LOCAL_CONFIG_FILE}: ${write.error}. It holds for this session only.`;
|
|
8849
9372
|
}
|
|
9373
|
+
void (options.keepIgnored ?? ensureLocalConfigIgnored)(cwd).then(logIgnoreOutcome);
|
|
9374
|
+
return void 0;
|
|
8850
9375
|
},
|
|
8851
9376
|
list: /* @__PURE__ */ __name(() => [...entries], "list"),
|
|
8852
9377
|
rule: {
|
|
8853
9378
|
type: "predicate",
|
|
8854
|
-
description: "allowed
|
|
8855
|
-
decide: /* @__PURE__ */ __name((call) =>
|
|
9379
|
+
description: "allowed by an answer at a prompt",
|
|
9380
|
+
decide: /* @__PURE__ */ __name((call) => allowed(call) ? "allow" : null, "decide")
|
|
8856
9381
|
}
|
|
8857
9382
|
};
|
|
8858
9383
|
}
|
|
8859
9384
|
__name(createSessionAllows, "createSessionAllows");
|
|
8860
9385
|
|
|
9386
|
+
// src/plan/approval.ts
|
|
9387
|
+
var KEEP_PLANNING_PLACEHOLDER = "Tell namzu what to change";
|
|
9388
|
+
function planApprovalRows(bypassAvailable) {
|
|
9389
|
+
return [
|
|
9390
|
+
bypassAvailable ? {
|
|
9391
|
+
id: "approve-auto",
|
|
9392
|
+
label: "Yes, and approve every tool without asking",
|
|
9393
|
+
mode: "auto"
|
|
9394
|
+
} : {
|
|
9395
|
+
id: "approve-accept-edits",
|
|
9396
|
+
label: "Yes, and auto-approve edits",
|
|
9397
|
+
mode: "accept-edits"
|
|
9398
|
+
},
|
|
9399
|
+
{
|
|
9400
|
+
id: "approve-ask",
|
|
9401
|
+
label: "Yes, and ask before each edit",
|
|
9402
|
+
mode: "prompt"
|
|
9403
|
+
},
|
|
9404
|
+
{ id: "keep-planning", label: "No, keep planning" }
|
|
9405
|
+
];
|
|
9406
|
+
}
|
|
9407
|
+
__name(planApprovalRows, "planApprovalRows");
|
|
9408
|
+
var EXIT_PLAN_MODE_TOOL_NAME = "exit_plan_mode";
|
|
9409
|
+
|
|
9410
|
+
// src/plan/plan-file.ts
|
|
9411
|
+
import { readFile as readFile6 } from "node:fs/promises";
|
|
9412
|
+
import { isAbsolute as isAbsolute7, resolve as resolve9 } from "node:path";
|
|
9413
|
+
var WRITERS = /* @__PURE__ */ new Set(["write", "edit"]);
|
|
9414
|
+
function isPlanFileWrite(planPath, cwd) {
|
|
9415
|
+
const target = resolve9(planPath);
|
|
9416
|
+
return (call) => {
|
|
9417
|
+
if (!WRITERS.has(call.name)) return false;
|
|
9418
|
+
const input = call.input;
|
|
9419
|
+
if (input === null || typeof input !== "object") return false;
|
|
9420
|
+
const path = input.path;
|
|
9421
|
+
if (typeof path !== "string" || path.length === 0 || path.includes("\0")) return false;
|
|
9422
|
+
return resolve9(isAbsolute7(path) ? path : resolve9(cwd, path)) === target;
|
|
9423
|
+
};
|
|
9424
|
+
}
|
|
9425
|
+
__name(isPlanFileWrite, "isPlanFileWrite");
|
|
9426
|
+
async function readPlan(planPath) {
|
|
9427
|
+
try {
|
|
9428
|
+
const text = await readFile6(planPath, "utf8");
|
|
9429
|
+
return text.trim().length > 0 ? text : void 0;
|
|
9430
|
+
} catch {
|
|
9431
|
+
return void 0;
|
|
9432
|
+
}
|
|
9433
|
+
}
|
|
9434
|
+
__name(readPlan, "readPlan");
|
|
9435
|
+
|
|
9436
|
+
// src/plan/exit-plan-mode-tool.ts
|
|
9437
|
+
function approvedPlanText(plan, planPath, answer) {
|
|
9438
|
+
return [
|
|
9439
|
+
`The user approved your plan and moved this session to "${permissionModeLabel(answer.mode)}". You can start the work now; if a task list fits it, open one first.`,
|
|
9440
|
+
"",
|
|
9441
|
+
`The plan is saved at ${planPath} if you need to refer back to it.`,
|
|
9442
|
+
...answer.feedback ? ["", `The user added: ${answer.feedback}`] : [],
|
|
9443
|
+
"",
|
|
9444
|
+
"## Approved plan",
|
|
9445
|
+
plan
|
|
9446
|
+
].join("\n");
|
|
9447
|
+
}
|
|
9448
|
+
__name(approvedPlanText, "approvedPlanText");
|
|
9449
|
+
function buildExitPlanModeTool(host) {
|
|
9450
|
+
return defineTool({
|
|
9451
|
+
name: EXIT_PLAN_MODE_TOOL_NAME,
|
|
9452
|
+
description: "Present the finished plan for the user to approve and leave plan mode. Write the plan to the plan file first; this tool reads it from there and takes no arguments. The user picks how to continue (auto-approve edits, or ask before each edit) or sends you back to planning with feedback. Call it only while in plan mode, only when the plan is ready, and never ask for approval of a plan any other way.",
|
|
9453
|
+
inputSchema: mcpJsonSchemaToZod({
|
|
9454
|
+
type: "object",
|
|
9455
|
+
properties: {},
|
|
9456
|
+
additionalProperties: false
|
|
9457
|
+
}),
|
|
9458
|
+
category: "custom",
|
|
9459
|
+
permissions: [],
|
|
9460
|
+
// Asks the person, changes nothing itself: the mode switch is theirs.
|
|
9461
|
+
readOnly: true,
|
|
9462
|
+
destructive: false,
|
|
9463
|
+
concurrencySafe: false,
|
|
9464
|
+
// A person reads a whole plan before answering.
|
|
9465
|
+
timeoutMs: 30 * 6e4,
|
|
9466
|
+
presentCall: /* @__PURE__ */ __name(() => ({
|
|
9467
|
+
kind: "generic",
|
|
9468
|
+
label: "Present plan for approval",
|
|
9469
|
+
presentation: "activity"
|
|
9470
|
+
}), "presentCall"),
|
|
9471
|
+
// The transcript already shows the approved plan (the host writes it when the
|
|
9472
|
+
// person approves); the tool's own result is for the model.
|
|
9473
|
+
presentResult: /* @__PURE__ */ __name((_input, result) => {
|
|
9474
|
+
if (result.success)
|
|
9475
|
+
return {
|
|
9476
|
+
kind: "generic",
|
|
9477
|
+
label: "Plan approved",
|
|
9478
|
+
visibility: "hidden"
|
|
9479
|
+
};
|
|
9480
|
+
const outcome = result.data?.outcome;
|
|
9481
|
+
return outcome === "keep-planning" ? { kind: "generic", label: "Kept planning", outcome: "cancelled" } : void 0;
|
|
9482
|
+
}, "presentResult"),
|
|
9483
|
+
async execute(_input, context) {
|
|
9484
|
+
context.abortSignal?.throwIfAborted();
|
|
9485
|
+
if (host.mode() !== "plan") {
|
|
9486
|
+
return {
|
|
9487
|
+
success: false,
|
|
9488
|
+
output: "",
|
|
9489
|
+
error: "You are not in plan mode, so there is no plan to put up for approval. If your plan was already approved, carry on with the work."
|
|
9490
|
+
};
|
|
9491
|
+
}
|
|
9492
|
+
const planPath = host.planPath();
|
|
9493
|
+
const plan = await readPlan(planPath);
|
|
9494
|
+
if (plan === void 0) {
|
|
9495
|
+
return {
|
|
9496
|
+
success: false,
|
|
9497
|
+
output: "",
|
|
9498
|
+
error: `There is no plan to approve: ${planPath} is missing or empty. Write the plan to that file first, then call ${EXIT_PLAN_MODE_TOOL_NAME}.`
|
|
9499
|
+
};
|
|
9500
|
+
}
|
|
9501
|
+
const ask = host.approval();
|
|
9502
|
+
if (!ask) {
|
|
9503
|
+
return {
|
|
9504
|
+
success: false,
|
|
9505
|
+
output: "",
|
|
9506
|
+
error: "Nobody can approve a plan in this session, and you cannot leave plan mode yourself. End your reply with the plan and tell the user to switch the permission mode when they want it carried out."
|
|
9507
|
+
};
|
|
9508
|
+
}
|
|
9509
|
+
let answer;
|
|
9510
|
+
try {
|
|
9511
|
+
answer = await ask(
|
|
9512
|
+
{ plan, planPath, bypassAvailable: host.bypassAvailable() },
|
|
9513
|
+
context.abortSignal
|
|
9514
|
+
);
|
|
9515
|
+
} catch {
|
|
9516
|
+
answer = { kind: "keep-planning" };
|
|
9517
|
+
}
|
|
9518
|
+
context.abortSignal?.throwIfAborted();
|
|
9519
|
+
if (answer.kind === "approve") {
|
|
9520
|
+
return {
|
|
9521
|
+
success: true,
|
|
9522
|
+
output: approvedPlanText(plan, planPath, answer),
|
|
9523
|
+
data: { outcome: "approved", mode: answer.mode }
|
|
9524
|
+
};
|
|
9525
|
+
}
|
|
9526
|
+
return {
|
|
9527
|
+
success: false,
|
|
9528
|
+
output: "",
|
|
9529
|
+
error: answer.feedback ? `The user did not approve the plan and wants you to keep planning. What they said: ${answer.feedback}` : "The user did not approve the plan yet and has not said what to change. Stay in plan mode and ask what they want different, or refine the plan.",
|
|
9530
|
+
data: { outcome: "keep-planning" }
|
|
9531
|
+
};
|
|
9532
|
+
}
|
|
9533
|
+
});
|
|
9534
|
+
}
|
|
9535
|
+
__name(buildExitPlanModeTool, "buildExitPlanModeTool");
|
|
9536
|
+
|
|
8861
9537
|
// src/provider-retry.ts
|
|
8862
9538
|
var TERMINAL_PROVIDER_RETRY = {
|
|
8863
9539
|
maxRetries: 10,
|
|
@@ -8872,6 +9548,175 @@ function terminalProviderRetry(restartableOutput) {
|
|
|
8872
9548
|
}
|
|
8873
9549
|
__name(terminalProviderRetry, "terminalProviderRetry");
|
|
8874
9550
|
|
|
9551
|
+
// src/reminders/index.ts
|
|
9552
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
9553
|
+
|
|
9554
|
+
// src/reminders/frame.ts
|
|
9555
|
+
var TAG = /^<system-reminder kind="([a-z-]+)"(?: form="([a-z]+)")?>/;
|
|
9556
|
+
function frameReminder(kind, text, form) {
|
|
9557
|
+
const open3 = form ? `<system-reminder kind="${kind}" form="${form}">` : `<system-reminder kind="${kind}">`;
|
|
9558
|
+
return `${open3}
|
|
9559
|
+
${text.trim()}
|
|
9560
|
+
</system-reminder>`;
|
|
9561
|
+
}
|
|
9562
|
+
__name(frameReminder, "frameReminder");
|
|
9563
|
+
function reminderKindOf(message2) {
|
|
9564
|
+
if (!isReminderMessage(message2) || typeof message2.content !== "string") return void 0;
|
|
9565
|
+
const kind = TAG.exec(message2.content)?.[1];
|
|
9566
|
+
return kind === "plan-mode" || kind === "plan-reentry" || kind === "plan-exit" || kind === "task-nudge" ? kind : void 0;
|
|
9567
|
+
}
|
|
9568
|
+
__name(reminderKindOf, "reminderKindOf");
|
|
9569
|
+
function isOperatorTurn(message2) {
|
|
9570
|
+
if (message2.role !== "user") return false;
|
|
9571
|
+
const source = message2.source;
|
|
9572
|
+
return source === void 0 || source.type === "goal-round" || source.type === "runtime-context" && source.kind === "steering";
|
|
9573
|
+
}
|
|
9574
|
+
__name(isOperatorTurn, "isOperatorTurn");
|
|
9575
|
+
|
|
9576
|
+
// src/reminders/plan-mode.ts
|
|
9577
|
+
var PLAN_REMINDER_EVERY_N_TURNS = 5;
|
|
9578
|
+
var PLAN_REMINDER_FULL_EVERY_N = 5;
|
|
9579
|
+
function scan(messages) {
|
|
9580
|
+
let turns = 0;
|
|
9581
|
+
let hasReminder = false;
|
|
9582
|
+
let sent = 0;
|
|
9583
|
+
let hasExited = false;
|
|
9584
|
+
let inStretch = true;
|
|
9585
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
9586
|
+
const message2 = messages[i];
|
|
9587
|
+
const kind = reminderKindOf(message2);
|
|
9588
|
+
if (kind === "plan-exit") {
|
|
9589
|
+
hasExited = true;
|
|
9590
|
+
if (!hasReminder) inStretch = false;
|
|
9591
|
+
break;
|
|
9592
|
+
}
|
|
9593
|
+
if (kind === "plan-mode" || kind === "plan-reentry") {
|
|
9594
|
+
if (inStretch) hasReminder = true;
|
|
9595
|
+
if (kind === "plan-mode") sent++;
|
|
9596
|
+
continue;
|
|
9597
|
+
}
|
|
9598
|
+
if (!hasReminder && isOperatorTurn(message2)) turns++;
|
|
9599
|
+
}
|
|
9600
|
+
return { turnsSinceReminder: turns, hasReminder, sent, hasExited };
|
|
9601
|
+
}
|
|
9602
|
+
__name(scan, "scan");
|
|
9603
|
+
function fullText(input) {
|
|
9604
|
+
const file = input.planExists ? `A plan already exists at ${input.planPath}. Read it, then revise it in place with the edit tool.` : `No plan exists yet. Create it at ${input.planPath} with the write tool.`;
|
|
9605
|
+
const ending = input.canAsk ? "Your turn ends in exactly one of two ways: you ask the user a question with ask_user_question to settle something you cannot decide yourself, or you call exit_plan_mode once the plan file is ready for approval." : "Your turn ends by calling exit_plan_mode once the plan file is ready for approval.";
|
|
9606
|
+
return `Plan mode is on. Change nothing except the plan file: no edits, no commands that change state, no commits. This overrides every other instruction you have.
|
|
9607
|
+
|
|
9608
|
+
${file} It is the only file you may write; build the plan up in it as you learn.
|
|
9609
|
+
|
|
9610
|
+
How to plan:
|
|
9611
|
+
1. Understand the request. Read the code it touches and look for existing functions and patterns to reuse before proposing new ones. For wide questions, send read-only explore agents; one is usually enough.
|
|
9612
|
+
2. Decide on one approach. Weigh alternatives briefly and keep only the one you recommend.
|
|
9613
|
+
3. Write the plan file: why the change is needed, the recommended approach, the files to change, what existing code it reuses, and how to verify the result end to end.
|
|
9614
|
+
4. Finish. ${ending} Never ask for approval in plain text ("does this look right?"); exit_plan_mode is how the user is asked.`;
|
|
9615
|
+
}
|
|
9616
|
+
__name(fullText, "fullText");
|
|
9617
|
+
function sparseText(input) {
|
|
9618
|
+
return `Plan mode is still on (full rules above). Only ${input.planPath} may be written. End the turn by ${input.canAsk ? "asking the user a question or " : ""}calling exit_plan_mode.`;
|
|
9619
|
+
}
|
|
9620
|
+
__name(sparseText, "sparseText");
|
|
9621
|
+
function reentryText(input) {
|
|
9622
|
+
return `You are back in plan mode after leaving it earlier. A plan from that session is at ${input.planPath}. Before planning anything new, read it and compare it with the current request: if this is a different task, start over and overwrite it; if it continues the same task, revise it and drop what no longer applies. Edit the plan file one way or the other before you call exit_plan_mode.`;
|
|
9623
|
+
}
|
|
9624
|
+
__name(reentryText, "reentryText");
|
|
9625
|
+
function exitText(input) {
|
|
9626
|
+
return `You have left plan mode. You can edit files and run tools again.${input.planExists ? ` The plan is at ${input.planPath} if you need to refer to it.` : ""}`;
|
|
9627
|
+
}
|
|
9628
|
+
__name(exitText, "exitText");
|
|
9629
|
+
function planModeReminders(input) {
|
|
9630
|
+
const stretch = scan(input.messages);
|
|
9631
|
+
if (input.mode !== "plan") {
|
|
9632
|
+
return stretch.hasReminder ? [frameReminder("plan-exit", exitText(input))] : [];
|
|
9633
|
+
}
|
|
9634
|
+
if (stretch.hasReminder && stretch.turnsSinceReminder < PLAN_REMINDER_EVERY_N_TURNS) return [];
|
|
9635
|
+
const full = (stretch.sent + 1) % PLAN_REMINDER_FULL_EVERY_N === 1;
|
|
9636
|
+
const out = [
|
|
9637
|
+
frameReminder(
|
|
9638
|
+
"plan-mode",
|
|
9639
|
+
full ? fullText(input) : sparseText(input),
|
|
9640
|
+
full ? "full" : "sparse"
|
|
9641
|
+
)
|
|
9642
|
+
];
|
|
9643
|
+
if (!stretch.hasReminder && stretch.hasExited && input.planExists) {
|
|
9644
|
+
out.push(frameReminder("plan-reentry", reentryText(input)));
|
|
9645
|
+
}
|
|
9646
|
+
return out;
|
|
9647
|
+
}
|
|
9648
|
+
__name(planModeReminders, "planModeReminders");
|
|
9649
|
+
|
|
9650
|
+
// src/reminders/task-nudge.ts
|
|
9651
|
+
var TASK_NUDGE_AFTER_TURNS = 10;
|
|
9652
|
+
var TASK_NUDGE_EVERY_TURNS = 10;
|
|
9653
|
+
var TASK_TOOLS = /* @__PURE__ */ new Set(["task_create", "task_update"]);
|
|
9654
|
+
function taskNudgeCounts(messages) {
|
|
9655
|
+
let sinceTaskTool = 0;
|
|
9656
|
+
let sinceNudge = 0;
|
|
9657
|
+
let sawTool = false;
|
|
9658
|
+
let sawNudge = false;
|
|
9659
|
+
for (let i = messages.length - 1; i >= 0 && !(sawTool && sawNudge); i--) {
|
|
9660
|
+
const message2 = messages[i];
|
|
9661
|
+
if (message2.role === "assistant") {
|
|
9662
|
+
if (!sawTool && message2.toolCalls?.some((call) => TASK_TOOLS.has(call.function.name))) {
|
|
9663
|
+
sawTool = true;
|
|
9664
|
+
}
|
|
9665
|
+
if (!sawTool) sinceTaskTool++;
|
|
9666
|
+
if (!sawNudge) sinceNudge++;
|
|
9667
|
+
} else if (!sawNudge && reminderKindOf(message2) === "task-nudge") {
|
|
9668
|
+
sawNudge = true;
|
|
9669
|
+
}
|
|
9670
|
+
}
|
|
9671
|
+
return { sinceTaskTool, sinceNudge };
|
|
9672
|
+
}
|
|
9673
|
+
__name(taskNudgeCounts, "taskNudgeCounts");
|
|
9674
|
+
function listText(tasks) {
|
|
9675
|
+
return tasks.map((task) => `#${task.id}. [${task.status}] ${task.subject}`).join("\n");
|
|
9676
|
+
}
|
|
9677
|
+
__name(listText, "listText");
|
|
9678
|
+
function taskNudge(messages, tasks) {
|
|
9679
|
+
if (messages.length === 0) return [];
|
|
9680
|
+
const { sinceTaskTool, sinceNudge } = taskNudgeCounts(messages);
|
|
9681
|
+
if (sinceTaskTool < TASK_NUDGE_AFTER_TURNS || sinceNudge < TASK_NUDGE_EVERY_TURNS) return [];
|
|
9682
|
+
const head = "You have not used the task tools for a while. If this work has steps worth tracking, add them with task_create and keep their status current with task_update (in_progress when you start one, completed when it is done); if the list has gone stale, tidy it. Only do so if it fits the work; otherwise ignore this note.";
|
|
9683
|
+
return [
|
|
9684
|
+
frameReminder(
|
|
9685
|
+
"task-nudge",
|
|
9686
|
+
tasks.length > 0 ? `${head}
|
|
9687
|
+
|
|
9688
|
+
The task list now:
|
|
9689
|
+
${listText(tasks)}` : head
|
|
9690
|
+
)
|
|
9691
|
+
];
|
|
9692
|
+
}
|
|
9693
|
+
__name(taskNudge, "taskNudge");
|
|
9694
|
+
|
|
9695
|
+
// src/reminders/index.ts
|
|
9696
|
+
function createCliReminderSource(options) {
|
|
9697
|
+
return async ({ messages }) => {
|
|
9698
|
+
const out = [];
|
|
9699
|
+
if (options.planPath) {
|
|
9700
|
+
const planPath = options.planPath();
|
|
9701
|
+
out.push(
|
|
9702
|
+
...planModeReminders({
|
|
9703
|
+
messages,
|
|
9704
|
+
mode: options.mode(),
|
|
9705
|
+
planPath,
|
|
9706
|
+
planExists: (options.planExists ?? existsSync2)(planPath),
|
|
9707
|
+
canAsk: options.canAsk === true
|
|
9708
|
+
})
|
|
9709
|
+
);
|
|
9710
|
+
}
|
|
9711
|
+
if (options.tasks) {
|
|
9712
|
+
const nudge = taskNudge(messages, []);
|
|
9713
|
+
if (nudge.length > 0) out.push(...taskNudge(messages, await options.tasks()));
|
|
9714
|
+
}
|
|
9715
|
+
return out;
|
|
9716
|
+
};
|
|
9717
|
+
}
|
|
9718
|
+
__name(createCliReminderSource, "createCliReminderSource");
|
|
9719
|
+
|
|
8875
9720
|
// src/skills/directory.ts
|
|
8876
9721
|
function createSkillDirectoryResolver(options) {
|
|
8877
9722
|
return async (skill, context) => {
|
|
@@ -9021,24 +9866,24 @@ async function resolveModelSwitch(request, options) {
|
|
|
9021
9866
|
listed.set(detected.entry.id, listing);
|
|
9022
9867
|
return listing.kind === "ok" && listing.models.some((candidate) => candidate.id === model);
|
|
9023
9868
|
}, "inspect");
|
|
9024
|
-
const
|
|
9869
|
+
const resolve11 = /* @__PURE__ */ __name((detected) => ({
|
|
9025
9870
|
kind: "resolved",
|
|
9026
9871
|
selection: { id: detected.entry.id, model }
|
|
9027
9872
|
}), "resolve");
|
|
9028
9873
|
const first = selected ?? usable.find(({ entry }) => entry.id === options.currentProvider);
|
|
9029
|
-
if (first && await inspect(first)) return
|
|
9874
|
+
if (first && await inspect(first)) return resolve11(first);
|
|
9030
9875
|
const candidates = selected ? [selected] : usable;
|
|
9031
|
-
const
|
|
9876
|
+
const matches = selected ? [] : (await Promise.all(
|
|
9032
9877
|
candidates.filter((candidate) => candidate !== first).map(async (candidate) => await inspect(candidate) ? candidate : void 0)
|
|
9033
9878
|
)).filter((candidate) => candidate !== void 0);
|
|
9034
9879
|
signal?.throwIfAborted();
|
|
9035
|
-
const uniqueMatch =
|
|
9036
|
-
if (uniqueMatch) return
|
|
9037
|
-
if (
|
|
9880
|
+
const uniqueMatch = matches.length === 1 ? matches[0] : void 0;
|
|
9881
|
+
if (uniqueMatch) return resolve11(uniqueMatch);
|
|
9882
|
+
if (matches.length > 1) {
|
|
9038
9883
|
return {
|
|
9039
9884
|
kind: "rejected",
|
|
9040
|
-
reason: `Model "${model}" is available from multiple providers. Specify one: ${
|
|
9041
|
-
choices:
|
|
9885
|
+
reason: `Model "${model}" is available from multiple providers. Specify one: ${matches.map(({ entry }) => entry.id).join(", ")}.`,
|
|
9886
|
+
choices: matches.map(({ entry }) => ({ provider: entry.id, model }))
|
|
9042
9887
|
};
|
|
9043
9888
|
}
|
|
9044
9889
|
const choices = candidates.flatMap((candidate) => {
|
|
@@ -9109,6 +9954,8 @@ function createCliToolPresenter(registry) {
|
|
|
9109
9954
|
__name(createCliToolPresenter, "createCliToolPresenter");
|
|
9110
9955
|
|
|
9111
9956
|
// src/tui/agent.ts
|
|
9957
|
+
var WEB_FETCH_MAX_BYTES = 10 * 1024 * 1024;
|
|
9958
|
+
var WEB_EXTRACT_MAX_TOKENS = 8192;
|
|
9112
9959
|
async function observeWithSignal(operation, signal) {
|
|
9113
9960
|
signal.throwIfAborted();
|
|
9114
9961
|
let rejectAbort = /* @__PURE__ */ __name(() => {
|
|
@@ -9187,8 +10034,8 @@ var SessionOperationOwner = class {
|
|
|
9187
10034
|
})()[Symbol.asyncIterator]();
|
|
9188
10035
|
let settled = false;
|
|
9189
10036
|
let settle;
|
|
9190
|
-
const settlement = new Promise((
|
|
9191
|
-
settle =
|
|
10037
|
+
const settlement = new Promise((resolve11) => {
|
|
10038
|
+
settle = resolve11;
|
|
9192
10039
|
});
|
|
9193
10040
|
let operationTail = Promise.resolve();
|
|
9194
10041
|
let returnStarted = false;
|
|
@@ -9457,14 +10304,14 @@ function clipRequestContext(prompt, limit, kind) {
|
|
|
9457
10304
|
__name(clipRequestContext, "clipRequestContext");
|
|
9458
10305
|
async function createAgentSession(prefs, detected, options = {}) {
|
|
9459
10306
|
if (options.palEnvironment) {
|
|
9460
|
-
const { createPalAgentSession } = await import("./agent-session-
|
|
10307
|
+
const { createPalAgentSession } = await import("./agent-session-D4Z3TOX3.js");
|
|
9461
10308
|
return createPalAgentSession(prefs, detected, options);
|
|
9462
10309
|
}
|
|
9463
|
-
const { palAtWorkspace } = await import("./store-
|
|
10310
|
+
const { palAtWorkspace } = await import("./store-XPSGZANO.js");
|
|
9464
10311
|
if (palAtWorkspace(options.cwd ?? process.cwd()))
|
|
9465
10312
|
throw new Error("This Pal requires its owned virtual computer. Open it with namzu pal chat.");
|
|
9466
10313
|
const commandArguments = builtinCommandArguments();
|
|
9467
|
-
const sessionAllows = createSessionAllows(commandArguments);
|
|
10314
|
+
const sessionAllows = createSessionAllows(commandArguments, { cwd: /* @__PURE__ */ __name(() => cwd, "cwd") });
|
|
9468
10315
|
const sessionRules = [...options.rules ?? [], sessionAllows.rule];
|
|
9469
10316
|
const fileObservations = /* @__PURE__ */ new Map();
|
|
9470
10317
|
const observationsFor = /* @__PURE__ */ __name((id, prior) => {
|
|
@@ -9494,7 +10341,7 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
9494
10341
|
}
|
|
9495
10342
|
return seeded;
|
|
9496
10343
|
}, "observationsFor");
|
|
9497
|
-
const requestedCwd =
|
|
10344
|
+
const requestedCwd = resolve10(options.cwd ?? process.cwd());
|
|
9498
10345
|
let cwd;
|
|
9499
10346
|
try {
|
|
9500
10347
|
const entry2 = await stat4(requestedCwd);
|
|
@@ -9526,13 +10373,13 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
9526
10373
|
paths = options.conversationSessions.paths;
|
|
9527
10374
|
projectId = options.conversationSessions.projectId;
|
|
9528
10375
|
} else {
|
|
9529
|
-
const home =
|
|
10376
|
+
const home = resolve10(options.stateRoot ?? resolveNamzuHome());
|
|
9530
10377
|
ensurePrivateStateDirectory(home, "projects");
|
|
9531
10378
|
const project = await ensureProject({ home, cwd: cliProjectRoot(cwd) });
|
|
9532
10379
|
paths = new SessionPaths({ home, slug: project.slug });
|
|
9533
10380
|
projectId = project.projectId;
|
|
9534
10381
|
}
|
|
9535
|
-
ensurePrivateStateDirectory(
|
|
10382
|
+
ensurePrivateStateDirectory(resolve10(paths.projectDir(), ".."), paths.slug);
|
|
9536
10383
|
ensurePrivateStateDirectory(paths.projectDir(), "memory");
|
|
9537
10384
|
} catch (error) {
|
|
9538
10385
|
return emptySession(
|
|
@@ -9801,8 +10648,8 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
9801
10648
|
const ownedJobs = jobRegistry ? bindOwner(jobRegistry, jobOwner) : void 0;
|
|
9802
10649
|
const directories = [];
|
|
9803
10650
|
for (const dir of options.additionalDirectories ?? []) {
|
|
9804
|
-
const absolute =
|
|
9805
|
-
if (absolute !==
|
|
10651
|
+
const absolute = resolve10(cwd, dir);
|
|
10652
|
+
if (absolute !== resolve10(cwd) && !directories.includes(absolute)) directories.push(absolute);
|
|
9806
10653
|
}
|
|
9807
10654
|
const sessionDirectories = createSessionDirectories(cwd, directories);
|
|
9808
10655
|
const checkpoints = new FileCheckpointStore(
|
|
@@ -9866,6 +10713,8 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
9866
10713
|
let computerUseHost;
|
|
9867
10714
|
let computerUseTool;
|
|
9868
10715
|
let computerUseError;
|
|
10716
|
+
const textOnlyModels = new TextOnlyModels();
|
|
10717
|
+
let turnReadsImages = textOnlyModels.reads(provider, model);
|
|
9869
10718
|
const computerUseProviderRefusal = options.enableComputerUse === true && computerUsePackage?.state === "present" ? computerUseUnavailableReason(provider) : void 0;
|
|
9870
10719
|
if (computerUseProviderRefusal !== void 0) {
|
|
9871
10720
|
toolsets.push(
|
|
@@ -9886,7 +10735,7 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
9886
10735
|
toolsets.push(
|
|
9887
10736
|
readyWhen(
|
|
9888
10737
|
toolset("computer-use", [computerUseTool]),
|
|
9889
|
-
() => computerUseHasControl(candidate.capabilities)
|
|
10738
|
+
() => turnReadsImages && computerUseHasControl(candidate.capabilities)
|
|
9890
10739
|
)
|
|
9891
10740
|
);
|
|
9892
10741
|
computerUseHost = candidate;
|
|
@@ -10002,7 +10851,26 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
10002
10851
|
webSearchTool = createWebSearchTool();
|
|
10003
10852
|
toolsets.push(toolset("web-search", [webSearchTool]));
|
|
10004
10853
|
}
|
|
10005
|
-
|
|
10854
|
+
let sideModel;
|
|
10855
|
+
const webCapability = options.web?.fetch ? {
|
|
10856
|
+
// A page may be ten mebibytes, as in the reference; the guard's own
|
|
10857
|
+
// default is two.
|
|
10858
|
+
fetch: new GuardedFetchProvider({ maxBytes: WEB_FETCH_MAX_BYTES }),
|
|
10859
|
+
// The answer to a prompt about a page comes from the small model. It is
|
|
10860
|
+
// read at call time: the model exists once the delegation runtime does,
|
|
10861
|
+
// and a page fetched without one is returned as markdown instead.
|
|
10862
|
+
extract: {
|
|
10863
|
+
extract: /* @__PURE__ */ __name(async (request) => sideModel?.ask({
|
|
10864
|
+
sessionId: request.sessionId,
|
|
10865
|
+
turnId: request.turnId,
|
|
10866
|
+
instruction: request.instruction,
|
|
10867
|
+
body: request.body,
|
|
10868
|
+
maxTokens: WEB_EXTRACT_MAX_TOKENS,
|
|
10869
|
+
signal: request.signal ?? new AbortController().signal,
|
|
10870
|
+
timing: "in-turn"
|
|
10871
|
+
}), "extract")
|
|
10872
|
+
}
|
|
10873
|
+
} : void 0;
|
|
10006
10874
|
if (webCapability) toolsets.push(toolset("web-fetch", [WebFetchTool]));
|
|
10007
10875
|
const delegationScopes = /* @__PURE__ */ new Map();
|
|
10008
10876
|
const delegationLimits = /* @__PURE__ */ new Map();
|
|
@@ -10086,6 +10954,18 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
10086
10954
|
)
|
|
10087
10955
|
] : [], "savedAgentsSteps");
|
|
10088
10956
|
const directChildReports = /* @__PURE__ */ new Set();
|
|
10957
|
+
const providerForModel = /* @__PURE__ */ __name(async (invokingSessionId, providerId, selectedModel) => {
|
|
10958
|
+
if (!invokingSessionId && (providerId === "zen" || providerId === "zen-go"))
|
|
10959
|
+
throw new Error("A delegated provider requires its invoking conversation.");
|
|
10960
|
+
await ensureRegistered(providerId);
|
|
10961
|
+
const credential = await currentCredentialFor(providerId);
|
|
10962
|
+
return constructProvider(
|
|
10963
|
+
providerId,
|
|
10964
|
+
providerId === primary.id && credential ? { ...credential, apiKey: currentToken ?? credential.apiKey } : credential,
|
|
10965
|
+
selectedModel,
|
|
10966
|
+
{ sessionId: invokingSessionId }
|
|
10967
|
+
);
|
|
10968
|
+
}, "providerForModel");
|
|
10089
10969
|
let subagentRuntime;
|
|
10090
10970
|
let allowedAgentIds = [];
|
|
10091
10971
|
try {
|
|
@@ -10200,28 +11080,19 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
10200
11080
|
}
|
|
10201
11081
|
})
|
|
10202
11082
|
);
|
|
10203
|
-
const
|
|
11083
|
+
const matches = catalogues.flat();
|
|
10204
11084
|
return JSON.stringify({
|
|
10205
|
-
models:
|
|
10206
|
-
omitted: Math.max(0,
|
|
11085
|
+
models: matches.slice(0, 40),
|
|
11086
|
+
omitted: Math.max(0, matches.length - 40),
|
|
10207
11087
|
guidance: "Use exact IDs. Omitted capability fields are unknown, not unsupported. Narrow query when results are omitted."
|
|
10208
11088
|
});
|
|
10209
11089
|
}, "listModels"),
|
|
10210
11090
|
buildProvider: /* @__PURE__ */ __name(async (invokingSessionId, selection) => {
|
|
10211
11091
|
const providerId = selection ? selection.provider : turnRouteTarget?.provider ?? primary.id;
|
|
10212
11092
|
const selectedModel = selection?.model ?? turnRouteTarget?.model ?? model;
|
|
10213
|
-
|
|
10214
|
-
throw new Error("A delegated provider requires its invoking conversation.");
|
|
10215
|
-
await ensureRegistered(providerId);
|
|
10216
|
-
const credential = await currentCredentialFor(providerId);
|
|
10217
|
-
const childProvider = constructProvider(
|
|
10218
|
-
providerId,
|
|
10219
|
-
providerId === primary.id && credential ? { ...credential, apiKey: currentToken ?? credential.apiKey } : credential,
|
|
10220
|
-
selectedModel,
|
|
10221
|
-
{ sessionId: invokingSessionId }
|
|
10222
|
-
);
|
|
11093
|
+
const childProvider = await providerForModel(invokingSessionId, providerId, selectedModel);
|
|
10223
11094
|
if (selection?.effort) await prepareDelegatedEffort(childProvider, selectedModel);
|
|
10224
|
-
return childProvider;
|
|
11095
|
+
return textOnlyModels.informing(childProvider);
|
|
10225
11096
|
}, "buildProvider"),
|
|
10226
11097
|
configureWebSearch: /* @__PURE__ */ __name((childProvider, childModel, toolsets2) => {
|
|
10227
11098
|
if (webSearch.mode === "off") return void 0;
|
|
@@ -10242,6 +11113,21 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
10242
11113
|
authorizationGate: gateFor(sessionRules)
|
|
10243
11114
|
});
|
|
10244
11115
|
subagentRuntime = sub;
|
|
11116
|
+
sideModel = createSideModel({
|
|
11117
|
+
active: /* @__PURE__ */ __name(() => ({
|
|
11118
|
+
providerId: turnRouteTarget?.provider ?? primary.id,
|
|
11119
|
+
model: turnRouteTarget?.model ?? model
|
|
11120
|
+
}), "active"),
|
|
11121
|
+
configured: options.smallModel,
|
|
11122
|
+
isKnownProvider: /* @__PURE__ */ __name((id) => findDetected(detected, id) != null, "isKnownProvider"),
|
|
11123
|
+
buildProvider: /* @__PURE__ */ __name((sessionId, target) => providerForModel(sessionId, target.providerId, target.model), "buildProvider"),
|
|
11124
|
+
offerable: /* @__PURE__ */ __name((providerId, listed) => {
|
|
11125
|
+
const found = findDetected(detected, providerId);
|
|
11126
|
+
return found != null && canSelectModel(found.entry, found.apiKey, listed.id) && isOfferableModel(providerId, listed.id);
|
|
11127
|
+
}, "offerable"),
|
|
11128
|
+
ledger: sub.sideLedger,
|
|
11129
|
+
debug: /* @__PURE__ */ __name((message2, error) => cliLogger().debug(message2, exceptionAttributes(error)), "debug")
|
|
11130
|
+
});
|
|
10245
11131
|
const agentToolsets = [toolset("agents", [sub.agentTool, sub.waitForTaskTool])];
|
|
10246
11132
|
if (sub.modelCatalogueTool)
|
|
10247
11133
|
agentToolsets.push(toolset("agents:model-catalogue", [sub.modelCatalogueTool]));
|
|
@@ -10260,7 +11146,7 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
10260
11146
|
runsDirectory: /* @__PURE__ */ __name((turnId) => {
|
|
10261
11147
|
if (options.ephemeral) return void 0;
|
|
10262
11148
|
const owner = delegationScopes.get(turnId) ?? scope;
|
|
10263
|
-
return
|
|
11149
|
+
return join14(paths.sessionDir({ sessionId: owner.sessionId }), "runs");
|
|
10264
11150
|
}, "runsDirectory"),
|
|
10265
11151
|
refusal: /* @__PURE__ */ __name((turnId) => {
|
|
10266
11152
|
const auth = delegatedWorkflowAuth.get(turnId);
|
|
@@ -10343,6 +11229,7 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
10343
11229
|
);
|
|
10344
11230
|
}
|
|
10345
11231
|
subagentRuntime = void 0;
|
|
11232
|
+
sideModel = void 0;
|
|
10346
11233
|
cliLogger().warn("sub-agent runtime unavailable this session", exceptionAttributes(err));
|
|
10347
11234
|
}
|
|
10348
11235
|
const modelSwitchHandlers = /* @__PURE__ */ new Map();
|
|
@@ -10375,6 +11262,13 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
10375
11262
|
action: "answer_question",
|
|
10376
11263
|
selectedOptionIds: [...answer.selectedOptionIds],
|
|
10377
11264
|
...answer.freeText !== void 0 ? { freeText: answer.freeText } : {},
|
|
11265
|
+
...answer.answers ? {
|
|
11266
|
+
answers: answer.answers.map((entry2) => ({
|
|
11267
|
+
questionId: entry2.questionId,
|
|
11268
|
+
selectedOptionIds: [...entry2.selectedOptionIds],
|
|
11269
|
+
...entry2.freeText !== void 0 ? { freeText: entry2.freeText } : {}
|
|
11270
|
+
}))
|
|
11271
|
+
} : {},
|
|
10378
11272
|
questionId: request.question.questionId
|
|
10379
11273
|
};
|
|
10380
11274
|
case "abort":
|
|
@@ -10387,13 +11281,26 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
10387
11281
|
toolset("ask-user-question", [buildAskUserQuestionTool({ resumeHandler: parkQuestion })])
|
|
10388
11282
|
);
|
|
10389
11283
|
}
|
|
11284
|
+
let currentPlanHost;
|
|
11285
|
+
if (options.planApproval && !options.ephemeral) {
|
|
11286
|
+
toolsets.push(
|
|
11287
|
+
toolset("plan-mode", [
|
|
11288
|
+
buildExitPlanModeTool({
|
|
11289
|
+
mode: /* @__PURE__ */ __name(() => currentPlanHost?.mode() ?? "prompt", "mode"),
|
|
11290
|
+
planPath: /* @__PURE__ */ __name(() => currentPlanHost?.planPath ?? paths.planFile({ sessionId: scope.sessionId }), "planPath"),
|
|
11291
|
+
bypassAvailable: /* @__PURE__ */ __name(() => currentPlanHost?.bypassAvailable() ?? false, "bypassAvailable"),
|
|
11292
|
+
approval: /* @__PURE__ */ __name(() => currentPlanHost?.approval, "approval")
|
|
11293
|
+
})
|
|
11294
|
+
])
|
|
11295
|
+
);
|
|
11296
|
+
}
|
|
10390
11297
|
if (options.extraTools && options.extraTools.length > 0) {
|
|
10391
11298
|
toolsets.push(toolset("extra", options.extraTools));
|
|
10392
11299
|
}
|
|
10393
11300
|
if (options.openUrl) toolsets.push(toolset("open-url", [createOpenUrlTool()]));
|
|
10394
11301
|
const decisionTool = maybeCreateDecisionTool(options.decision, process.env);
|
|
10395
11302
|
if (decisionTool) toolsets.push(toolset("decide", [decisionTool]));
|
|
10396
|
-
const operatorPals = await import("./operator-tools-
|
|
11303
|
+
const operatorPals = await import("./operator-tools-GKYGHHPM.js");
|
|
10397
11304
|
toolsets.push(
|
|
10398
11305
|
readyWhen(
|
|
10399
11306
|
toolset(
|
|
@@ -10712,7 +11619,8 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
10712
11619
|
(input) => subagentRuntime?.launchesReadOnlyAgent(input) === true
|
|
10713
11620
|
),
|
|
10714
11621
|
{ unattendedSandboxEscape },
|
|
10715
|
-
screenPolicyFor(() => liveManager())
|
|
11622
|
+
screenPolicyFor(() => liveManager()),
|
|
11623
|
+
options.planApproval && !options.ephemeral ? isPlanFileWrite(paths.planFile({ sessionId: entry2.sessionId }), cwd) : void 0
|
|
10716
11624
|
), "handlerFor")
|
|
10717
11625
|
});
|
|
10718
11626
|
const resumeHandler = modeControl.handler;
|
|
@@ -10905,8 +11813,8 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
10905
11813
|
if (mapped) yield mapped;
|
|
10906
11814
|
}
|
|
10907
11815
|
if (settled) break;
|
|
10908
|
-
await new Promise((
|
|
10909
|
-
wake =
|
|
11816
|
+
await new Promise((resolve11) => {
|
|
11817
|
+
wake = resolve11;
|
|
10910
11818
|
});
|
|
10911
11819
|
wake = void 0;
|
|
10912
11820
|
}
|
|
@@ -10929,7 +11837,9 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
10929
11837
|
return lastAutoRoute;
|
|
10930
11838
|
},
|
|
10931
11839
|
get imageAttachmentsSupported() {
|
|
10932
|
-
|
|
11840
|
+
const current = providerForSession(scope.sessionId);
|
|
11841
|
+
if (options.routing) return current.capabilities?.supportsVision;
|
|
11842
|
+
return textOnlyModels.reads(current, model) ? current.capabilities?.supportsVision : false;
|
|
10933
11843
|
},
|
|
10934
11844
|
get documentAttachmentsSupported() {
|
|
10935
11845
|
return providerForSession(scope.sessionId).capabilities?.supportsDocuments;
|
|
@@ -10941,7 +11851,7 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
10941
11851
|
return reasoningEffortDefault;
|
|
10942
11852
|
},
|
|
10943
11853
|
...reasoningSettled ? { reasoningSettled } : {},
|
|
10944
|
-
compact: /* @__PURE__ */ __name((messages) => operations.promise(void 0, async (signal) => {
|
|
11854
|
+
compact: /* @__PURE__ */ __name((messages, instructions) => operations.promise(void 0, async (signal) => {
|
|
10945
11855
|
const sessionId = scope.sessionId;
|
|
10946
11856
|
const sessions = options.conversationSessions;
|
|
10947
11857
|
await prepareProviderCredential(signal);
|
|
@@ -10949,7 +11859,8 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
10949
11859
|
config: compactionConfigFor(options.compaction),
|
|
10950
11860
|
provider: providerForSession(sessionId),
|
|
10951
11861
|
model,
|
|
10952
|
-
signal
|
|
11862
|
+
signal,
|
|
11863
|
+
...instructions ? { instructions } : {}
|
|
10953
11864
|
};
|
|
10954
11865
|
if (sessions && !options.ephemeral) {
|
|
10955
11866
|
if (sessions.projectId !== scope.projectId || sessions.tenantId !== scope.tenantId)
|
|
@@ -11010,7 +11921,7 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
11010
11921
|
const live = host.registry.list();
|
|
11011
11922
|
const known = new Set(live.map((view) => view.runId));
|
|
11012
11923
|
const saved = options.ephemeral ? [] : await listWorkflowRuns(
|
|
11013
|
-
|
|
11924
|
+
join14(paths.sessionDir({ sessionId: scope.sessionId }), "runs")
|
|
11014
11925
|
).catch(() => []);
|
|
11015
11926
|
return [
|
|
11016
11927
|
...[...live].sort((a, b) => b.startedAt - a.startedAt),
|
|
@@ -11025,6 +11936,7 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
11025
11936
|
reset: /* @__PURE__ */ __name(() => host.registry.reset(), "reset")
|
|
11026
11937
|
}))(workflowHost)
|
|
11027
11938
|
} : {},
|
|
11939
|
+
...sideModel ? { sideModel } : {},
|
|
11028
11940
|
...subagentRuntime ? {
|
|
11029
11941
|
subagents: subagentRuntime.activity,
|
|
11030
11942
|
onSubagentReport: /* @__PURE__ */ __name((listener) => {
|
|
@@ -11219,6 +12131,13 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
11219
12131
|
errorKind: null,
|
|
11220
12132
|
// Reads the same object the handler mutates, at call time.
|
|
11221
12133
|
allowForSession: /* @__PURE__ */ __name((allows) => sessionAllows.add(allows), "allowForSession"),
|
|
12134
|
+
notifyHooks: /* @__PURE__ */ __name((info) => {
|
|
12135
|
+
if (!sessionPlugins) return;
|
|
12136
|
+
void sessionPlugins.manager.executeHooks("notification", {
|
|
12137
|
+
sessionId: scope.sessionId,
|
|
12138
|
+
notification: info
|
|
12139
|
+
}).catch(() => []);
|
|
12140
|
+
}, "notifyHooks"),
|
|
11222
12141
|
commandArguments,
|
|
11223
12142
|
setPermissionMode: /* @__PURE__ */ __name(async (mode, reason) => {
|
|
11224
12143
|
await Promise.all(
|
|
@@ -11239,6 +12158,8 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
11239
12158
|
let runManager = manager;
|
|
11240
12159
|
lastSendInteractive = opts?.onPermission !== void 0;
|
|
11241
12160
|
const turnScope = { ...scope };
|
|
12161
|
+
const planPath = options.planApproval && !options.ephemeral ? paths.planFile({ sessionId: turnScope.sessionId }) : void 0;
|
|
12162
|
+
const planModeWrite = planPath ? isPlanFileWrite(planPath, cwd) : void 0;
|
|
11242
12163
|
const initialMode = opts?.permissionMode ?? options.permissionMode ?? (opts?.onPermission || opts?.reviewHold ? "prompt" : "auto");
|
|
11243
12164
|
const modeControl = createLiveModeControl({
|
|
11244
12165
|
initial: initialMode,
|
|
@@ -11264,7 +12185,8 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
11264
12185
|
(input) => subagentRuntime?.launchesReadOnlyAgent(input) === true
|
|
11265
12186
|
),
|
|
11266
12187
|
{ unattendedSandboxEscape },
|
|
11267
|
-
screenPolicyFor(() => runManager)
|
|
12188
|
+
screenPolicyFor(() => runManager),
|
|
12189
|
+
planModeWrite
|
|
11268
12190
|
), "handlerFor")
|
|
11269
12191
|
});
|
|
11270
12192
|
const resumeHandler = modeControl.handler;
|
|
@@ -11301,6 +12223,8 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
11301
12223
|
const autoRoute = await autoRouteFor(messages, turnScope.sessionId, signal);
|
|
11302
12224
|
const turnWebSearch = autoRoute ? routedWebSearch(autoRoute) : nativeWebSearch;
|
|
11303
12225
|
const turnSkills = await turnSkillsFor(autoRoute?.model ?? model);
|
|
12226
|
+
const turnProvider = autoRoute?.provider ?? providerForSession(turnScope.sessionId);
|
|
12227
|
+
turnReadsImages = textOnlyModels.reads(turnProvider, autoRoute?.model ?? model);
|
|
11304
12228
|
const curatedMemory = readMemory(void 0, cwd);
|
|
11305
12229
|
for (const notice of formatMemoryDiagnostics(curatedMemory)) {
|
|
11306
12230
|
yield { kind: "context", text: notice, shed: false };
|
|
@@ -11315,6 +12239,12 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
11315
12239
|
}
|
|
11316
12240
|
const curatedMemoryPrompt = composeMemoryPrompt(curatedMemory);
|
|
11317
12241
|
currentOnQuestion = opts?.onQuestion;
|
|
12242
|
+
currentPlanHost = planPath ? {
|
|
12243
|
+
mode: /* @__PURE__ */ __name(() => modeControl.current(), "mode"),
|
|
12244
|
+
planPath,
|
|
12245
|
+
approval: opts?.onPlanExit,
|
|
12246
|
+
bypassAvailable: opts?.bypassAvailable ?? (() => false)
|
|
12247
|
+
} : void 0;
|
|
11318
12248
|
const [environmentFacts, turnSnapshot] = await Promise.all([
|
|
11319
12249
|
readEnvironmentFacts(cwd),
|
|
11320
12250
|
readTurnSnapshot(cwd)
|
|
@@ -11432,7 +12362,7 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
11432
12362
|
// Present only while the turn runs under `plan`. A mode change
|
|
11433
12363
|
// is rare, so the cached prefix it re-keys is a price paid once
|
|
11434
12364
|
// per switch rather than once per turn.
|
|
11435
|
-
!residentContext && opts?.permissionMode === "plan" ? PLAN_MODE_DOCTRINE : void 0,
|
|
12365
|
+
!residentContext && opts?.permissionMode === "plan" ? planPath ? NAMZU_PLAN_FILE_DOCTRINE : PLAN_MODE_DOCTRINE : void 0,
|
|
11436
12366
|
residentContext ? void 0 : environmentPrompt,
|
|
11437
12367
|
residentContext ? void 0 : opts?.extraSystem,
|
|
11438
12368
|
residentContext ? void 0 : opts?.systemNote,
|
|
@@ -11453,6 +12383,14 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
11453
12383
|
}
|
|
11454
12384
|
claimTurn(turnId);
|
|
11455
12385
|
const turnTaskStore = selectTaskStore(turnScope);
|
|
12386
|
+
const reminderSource = options.reminders ? createCliReminderSource({
|
|
12387
|
+
mode: /* @__PURE__ */ __name(() => modeControl.current(), "mode"),
|
|
12388
|
+
...planPath ? {
|
|
12389
|
+
planPath: /* @__PURE__ */ __name(() => planPath, "planPath"),
|
|
12390
|
+
canAsk: Boolean(options.askUser && subagentRuntime)
|
|
12391
|
+
} : {},
|
|
12392
|
+
tasks: /* @__PURE__ */ __name(() => turnTaskStore.list({ sessionId: turnScope.sessionId }), "tasks")
|
|
12393
|
+
}) : void 0;
|
|
11456
12394
|
let ephemeralLog;
|
|
11457
12395
|
if (options.ephemeral) {
|
|
11458
12396
|
ephemeralLog = new InMemorySessionLog({
|
|
@@ -11477,7 +12415,7 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
11477
12415
|
}
|
|
11478
12416
|
try {
|
|
11479
12417
|
for await (const event of runTurn({
|
|
11480
|
-
provider:
|
|
12418
|
+
provider: textOnlyModels.informing(turnProvider),
|
|
11481
12419
|
fileReadTracker: await observationsFor(turnScope.sessionId, messages),
|
|
11482
12420
|
compactionConfig: compactionConfigFor(options.compaction),
|
|
11483
12421
|
retainedToolPreviewChars: options.conversationSessions ? options.compaction?.retainedToolPreviewChars ?? 4e3 : void 0,
|
|
@@ -11494,7 +12432,10 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
11494
12432
|
// is a fallback that fails for the reason the fallback exists to
|
|
11495
12433
|
// survive. Building a driver is a client object, not a request.
|
|
11496
12434
|
// A routed turn has no fallback chain, like a pinned resume.
|
|
11497
|
-
fallbackProviders: autoRoute ? [] : fallbackPlan.build(currentToken, turnScope.sessionId)
|
|
12435
|
+
fallbackProviders: autoRoute ? [] : fallbackPlan.build(currentToken, turnScope.sessionId).map((member) => ({
|
|
12436
|
+
...member,
|
|
12437
|
+
provider: textOnlyModels.informing(member.provider)
|
|
12438
|
+
})),
|
|
11498
12439
|
model: autoRoute?.model ?? model,
|
|
11499
12440
|
toolsets: runToolsets,
|
|
11500
12441
|
...screensConfig !== void 0 ? { toolResultGuardrails: screensConfig } : {},
|
|
@@ -11535,6 +12476,7 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
11535
12476
|
...memoryContextSteps(curatedMemoryPrompt, storedMemory.prompt)
|
|
11536
12477
|
],
|
|
11537
12478
|
taskStore: turnTaskStore,
|
|
12479
|
+
...reminderSource ? { reminders: reminderSource } : {},
|
|
11538
12480
|
systemPrompt,
|
|
11539
12481
|
messages,
|
|
11540
12482
|
projectInstructionContext: projectInstructions.createTurnContext(),
|
|
@@ -11555,7 +12497,12 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
11555
12497
|
task_update: options.toolLoading === "deferred" ? "deferred" : "active",
|
|
11556
12498
|
task_list: options.toolLoading === "deferred" ? "deferred" : "active"
|
|
11557
12499
|
},
|
|
11558
|
-
onSessionEvent:
|
|
12500
|
+
onSessionEvent: /* @__PURE__ */ __name((event2) => {
|
|
12501
|
+
if (event2.type === "capability_warning" && event2.contentSource === "history" && event2.model !== void 0) {
|
|
12502
|
+
textOnlyModels.add(event2.providerId, event2.model);
|
|
12503
|
+
}
|
|
12504
|
+
options.onSessionEvent?.(event2);
|
|
12505
|
+
}, "onSessionEvent"),
|
|
11559
12506
|
...sandbox.provider ? { sandboxProvider: sandbox.provider } : {},
|
|
11560
12507
|
...options.sandbox?.teardownTimeoutMs !== void 0 ? {
|
|
11561
12508
|
sandboxTeardownTimeoutMs: options.sandbox.teardownTimeoutMs
|
|
@@ -11975,13 +12922,17 @@ function gateFor(rules) {
|
|
|
11975
12922
|
return { ...VERIFICATION_GATE, rules: [...rules ?? []] };
|
|
11976
12923
|
}
|
|
11977
12924
|
__name(gateFor, "gateFor");
|
|
12925
|
+
var MAX_OUTPUT_CONTINUATIONS = 3;
|
|
11978
12926
|
var COMPACTION_CONFIG = {
|
|
11979
12927
|
strategy: "salience",
|
|
12928
|
+
// Give up on compaction that keeps failing or keeps refilling, and say so
|
|
12929
|
+
// once. The kernel leaves this off, so the CLI asks.
|
|
12930
|
+
circuitBreaker: true,
|
|
11980
12931
|
// On, and this is the CLI making a choice rather than taking a default.
|
|
11981
12932
|
// A session's transcript is the only record of what was compacted away;
|
|
11982
12933
|
// the size trade this costs is the operator's to see and turn off.
|
|
11983
12934
|
recordShedHistory: true,
|
|
11984
|
-
triggerThreshold
|
|
12935
|
+
// No `triggerThreshold`: the kernel derives it from the model's window.
|
|
11985
12936
|
resetThreshold: 0.4,
|
|
11986
12937
|
keepRecentMessages: 6,
|
|
11987
12938
|
// Reclaim from stale tool output before summarizing. A CLI session is
|
|
@@ -12049,6 +13000,7 @@ async function* runTurn({
|
|
|
12049
13000
|
onApprovalPolicy,
|
|
12050
13001
|
reviewAllowedCalls,
|
|
12051
13002
|
taskStore,
|
|
13003
|
+
reminders,
|
|
12052
13004
|
systemPrompt,
|
|
12053
13005
|
messages,
|
|
12054
13006
|
projectInstructionContext,
|
|
@@ -12073,6 +13025,7 @@ async function* runTurn({
|
|
|
12073
13025
|
const readsOnly = declaredReadOnly(turnManager);
|
|
12074
13026
|
try {
|
|
12075
13027
|
const events = query({
|
|
13028
|
+
maxOutputContinuations: MAX_OUTPUT_CONTINUATIONS,
|
|
12076
13029
|
...retainedToolPreviewChars !== void 0 ? { retainedToolPreviewChars } : {},
|
|
12077
13030
|
...fileReadTracker ? { fileReadTracker } : {},
|
|
12078
13031
|
...structuredOutput ? { structuredOutput } : {},
|
|
@@ -12133,6 +13086,7 @@ async function* runTurn({
|
|
|
12133
13086
|
...systemPrompt ? { systemPrompt } : {},
|
|
12134
13087
|
projectInstructionContext,
|
|
12135
13088
|
messages: [...messages],
|
|
13089
|
+
...reminders ? { reminders } : {},
|
|
12136
13090
|
...opts?.inboundMessages ? { inboundMessages: opts.inboundMessages } : {},
|
|
12137
13091
|
...opts?.waitForInbound ? { waitForInbound: opts.waitForInbound } : {},
|
|
12138
13092
|
...opts?.durableInbound ? { durableInbound: opts.durableInbound } : {},
|
|
@@ -12206,12 +13160,13 @@ async function* runTurn({
|
|
|
12206
13160
|
}
|
|
12207
13161
|
}
|
|
12208
13162
|
__name(runTurn, "runTurn");
|
|
12209
|
-
function makeResumeHandler(approval, onPermission, mode = onPermission ? "prompt" : "auto", exempt = () => false, escapePolicy = {}, screen) {
|
|
13163
|
+
function makeResumeHandler(approval, onPermission, mode = onPermission ? "prompt" : "auto", exempt = () => false, escapePolicy = {}, screen, planModeWrite) {
|
|
12210
13164
|
return createReviewHandler({
|
|
12211
13165
|
mode,
|
|
12212
13166
|
prompt: onPermission,
|
|
12213
13167
|
exempt,
|
|
12214
13168
|
remembered: approval,
|
|
13169
|
+
...planModeWrite ? { planModeWrite } : {},
|
|
12215
13170
|
...screen ? { screenConsent: screen.consent, capturesScreen: screen.capturesScreen } : {},
|
|
12216
13171
|
// Refused unless the operator wrote `sandbox.allowUnattendedEscape`: a
|
|
12217
13172
|
// session with nobody to ask has nobody to consent to leaving the
|
|
@@ -12270,7 +13225,9 @@ function withRuntimeMountedTools(manager) {
|
|
|
12270
13225
|
__name(withRuntimeMountedTools, "withRuntimeMountedTools");
|
|
12271
13226
|
function reviewExemptionFor(mode, manager, launchesReadOnlyAgent) {
|
|
12272
13227
|
const exemptLookup = withRuntimeMountedTools(manager);
|
|
12273
|
-
return (name, input) => isPromptExempt(exemptLookup, name, input) ||
|
|
13228
|
+
return (name, input) => isPromptExempt(exemptLookup, name, input) || // Presenting a plan asks the person on its own screen and changes nothing;
|
|
13229
|
+
// `plan` is the one mode it is for. Outside it the tool refuses by itself.
|
|
13230
|
+
name === EXIT_PLAN_MODE_TOOL_NAME && manager.has(EXIT_PLAN_MODE_TOOL_NAME) || mode !== "strict" && name === AGENT_LAUNCH_TOOL && launchesReadOnlyAgent(input) || mode !== "strict" && mode !== "plan" && confirmsItself(name, input) || mode !== "strict" && mode !== "plan" && name === SAVE_SKILL_TOOL_NAME && manager.has(SAVE_SKILL_TOOL_NAME);
|
|
12274
13231
|
}
|
|
12275
13232
|
__name(reviewExemptionFor, "reviewExemptionFor");
|
|
12276
13233
|
function confirmsItself(name, input) {
|
|
@@ -12335,6 +13292,21 @@ function toAgentEvent(event, presenter, readsOnly) {
|
|
|
12335
13292
|
...event.messageId ? { messageId: event.messageId } : {},
|
|
12336
13293
|
...event.turnId ? { turnId: event.turnId } : {}
|
|
12337
13294
|
};
|
|
13295
|
+
case "plugin_hook_completed": {
|
|
13296
|
+
const result = event.result;
|
|
13297
|
+
if ((result.action === "continue" || result.action === "skip") && result.halt) {
|
|
13298
|
+
return {
|
|
13299
|
+
kind: "hook-notice",
|
|
13300
|
+
text: `A hook stopped this turn: ${result.halt.reason}`
|
|
13301
|
+
};
|
|
13302
|
+
}
|
|
13303
|
+
if ((result.action === "continue" || result.action === "skip") && result.notice) {
|
|
13304
|
+
return { kind: "hook-notice", text: `A hook says: ${result.notice}` };
|
|
13305
|
+
}
|
|
13306
|
+
return null;
|
|
13307
|
+
}
|
|
13308
|
+
case "plugin_hook_executing":
|
|
13309
|
+
return event.statusMessage ? { kind: "hook-status", text: event.statusMessage } : null;
|
|
12338
13310
|
case "reasoning_started":
|
|
12339
13311
|
return { kind: "reasoning", text: "" };
|
|
12340
13312
|
case "reasoning_delta":
|
|
@@ -12560,6 +13532,7 @@ function toAgentEvent(event, presenter, readsOnly) {
|
|
|
12560
13532
|
reclaimedTokens: event.reclaimedTokens
|
|
12561
13533
|
};
|
|
12562
13534
|
case "compaction_failed":
|
|
13535
|
+
if (event.cause === "breaker_open") return null;
|
|
12563
13536
|
return {
|
|
12564
13537
|
kind: "context",
|
|
12565
13538
|
text: describeCompactionFailure(event),
|
|
@@ -12585,6 +13558,10 @@ function describeCompactionFailure(event) {
|
|
|
12585
13558
|
return `context could not be reduced further \u2014 nothing left to shed. ${held}; later passes will answer the same`;
|
|
12586
13559
|
case "split_tool_pair":
|
|
12587
13560
|
return `context not compacted \u2014 the reducer produced a history splitting a tool call from its result, so it was refused. ${held}; this is a bug in the reducer`;
|
|
13561
|
+
case "breaker_open":
|
|
13562
|
+
return "automatic compaction paused for this reply after repeated attempts that shed nothing";
|
|
13563
|
+
case "refilling":
|
|
13564
|
+
return event.error ?? "The context filled up again right after being compacted, three times in a row. A file being read or a tool output is probably too large for the context window. Try reading it in smaller parts.";
|
|
12588
13565
|
}
|
|
12589
13566
|
}
|
|
12590
13567
|
__name(describeCompactionFailure, "describeCompactionFailure");
|
|
@@ -12882,6 +13859,8 @@ export {
|
|
|
12882
13859
|
renderStoredMemorySection,
|
|
12883
13860
|
allowsForBatch,
|
|
12884
13861
|
describeAllows,
|
|
13862
|
+
KEEP_PLANNING_PLACEHOLDER,
|
|
13863
|
+
planApprovalRows,
|
|
12885
13864
|
assistantTranscriptTexts,
|
|
12886
13865
|
projectTurnConversation,
|
|
12887
13866
|
resolveModelSwitch,
|
|
@@ -12911,4 +13890,4 @@ export {
|
|
|
12911
13890
|
RESULT_SUMMARY_WHOLE_MAX,
|
|
12912
13891
|
resultSummaryLine
|
|
12913
13892
|
};
|
|
12914
|
-
//# sourceMappingURL=chunk-
|
|
13893
|
+
//# sourceMappingURL=chunk-6HDBRUB7.js.map
|