@namzu/cli 36.5.0 → 37.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +159 -0
- package/dist/bin.js +1 -1
- package/dist/boot-narrative.d.ts.map +1 -1
- package/dist/chunks/{acp-QQHLC6HY.js → acp-NJUDAWEV.js} +54 -49
- package/dist/chunks/acp-NJUDAWEV.js.map +6 -0
- package/dist/chunks/{activity-command-7A2NGBRO.js → activity-command-YUENOVUC.js} +13 -13
- package/dist/chunks/{add-VK7JVGYN.js → add-3F3PRHZ5.js} +23 -24
- package/dist/chunks/add-3F3PRHZ5.js.map +6 -0
- package/dist/chunks/{agent-IYFZOSN7.js → agent-KYILQUOP.js} +26 -23
- package/dist/chunks/agent-session-2YMHOAKF.js +49 -0
- package/dist/chunks/{archive-7A5RLRRZ.js → archive-VXAYIALI.js} +8 -8
- package/dist/chunks/{bin-main-QWTSTI5W.js → bin-main-7CCZXZ53.js} +7 -7
- package/dist/chunks/{browser-Z4JR5SV4.js → browser-LAZRYCOJ.js} +6 -6
- package/dist/chunks/{chat-452HRD23.js → chat-RI2TEONK.js} +20 -19
- package/dist/chunks/{chat-452HRD23.js.map → chat-RI2TEONK.js.map} +1 -1
- package/dist/chunks/{chunk-DQNJEGUV.js → chunk-2IWFTP44.js} +2 -2
- package/dist/chunks/{chunk-R5QMJRF7.js → chunk-2K4A2MVQ.js} +4 -4
- package/dist/chunks/{chunk-HNX3JZWU.js → chunk-2KSXZBZK.js} +29 -6
- package/dist/chunks/{chunk-HNX3JZWU.js.map → chunk-2KSXZBZK.js.map} +1 -1
- package/dist/chunks/{chunk-KJLJVK4Y.js → chunk-34CCZWJM.js} +6 -6
- package/dist/chunks/{chunk-IFBWLO7J.js → chunk-3M5GHYIX.js} +4 -4
- package/dist/chunks/{chunk-R5OZ6DCD.js → chunk-3RGJ3AC7.js} +2 -2
- package/dist/chunks/{chunk-2IWLDZNE.js → chunk-4DDYSIB2.js} +4 -2
- package/dist/chunks/chunk-4DDYSIB2.js.map +6 -0
- package/dist/chunks/{chunk-P6AM76US.js → chunk-4JQ2VCTQ.js} +6 -6
- package/dist/chunks/{chunk-BQYV3WGF.js → chunk-5GUMVF2I.js} +2 -2
- package/dist/chunks/{chunk-E2OJSRDE.js → chunk-5J3T7DNL.js} +5208 -1146
- package/dist/chunks/chunk-5J3T7DNL.js.map +6 -0
- package/dist/chunks/{chunk-DSODVSO7.js → chunk-5RTONMXP.js} +11 -11
- package/dist/chunks/{chunk-7RP7HIBA.js → chunk-5Y2HRYPF.js} +2 -2
- package/dist/chunks/{chunk-QLB4KNQA.js → chunk-6V3D6JMG.js} +2 -2
- package/dist/chunks/{chunk-HBWHJCNO.js → chunk-7BXRAEQU.js} +23 -18
- package/dist/chunks/chunk-7BXRAEQU.js.map +6 -0
- package/dist/chunks/{chunk-KGKBG3U7.js → chunk-AHKD4XSH.js} +3 -3
- package/dist/chunks/{chunk-6G3TX6QD.js → chunk-BPGADECQ.js} +3 -3
- package/dist/chunks/{chunk-WBR7JG42.js → chunk-BXJ7G5XN.js} +1085 -141
- package/dist/chunks/chunk-BXJ7G5XN.js.map +6 -0
- package/dist/chunks/{chunk-KI7GP25X.js → chunk-DEYX6OXI.js} +3 -3
- package/dist/chunks/{chunk-3N54T4H4.js → chunk-DFLYRMHP.js} +2 -2
- package/dist/chunks/{chunk-AJLZB6G6.js → chunk-EHEEEVWJ.js} +3 -3
- package/dist/chunks/{chunk-FPMRK6W6.js → chunk-EIMWVYBK.js} +3 -3
- package/dist/chunks/{chunk-QB6CLDHT.js → chunk-EV57ARS2.js} +23 -9
- package/dist/chunks/chunk-EV57ARS2.js.map +6 -0
- package/dist/chunks/{chunk-QXUJNVPO.js → chunk-I7GFMQGF.js} +2 -2
- package/dist/chunks/{chunk-PDSZNG3C.js → chunk-IOGROWMG.js} +3 -3
- package/dist/chunks/{chunk-PGEDH5H5.js → chunk-JAPAPPNH.js} +89 -4
- package/dist/chunks/{chunk-PGEDH5H5.js.map → chunk-JAPAPPNH.js.map} +2 -2
- package/dist/chunks/{chunk-QQ2TBG2P.js → chunk-K7ADP5FF.js} +6 -6
- package/dist/chunks/{chunk-5TIOW3QX.js → chunk-KF7KR67Z.js} +17 -17
- package/dist/chunks/{chunk-7TW2GZ5D.js → chunk-KXRBZ2IT.js} +80 -39
- package/dist/chunks/chunk-KXRBZ2IT.js.map +6 -0
- package/dist/chunks/{chunk-XMN2OSBG.js → chunk-LSMOWOWC.js} +57 -4
- package/dist/chunks/{chunk-XMN2OSBG.js.map → chunk-LSMOWOWC.js.map} +1 -1
- package/dist/chunks/{chunk-4BBUZZDS.js → chunk-MK4U26GZ.js} +2 -2
- package/dist/chunks/{chunk-J7GTTLAZ.js → chunk-MR34S4AM.js} +4 -4
- package/dist/chunks/{chunk-LNBO3KD2.js → chunk-NADDUQSP.js} +182 -18
- package/dist/chunks/chunk-NADDUQSP.js.map +6 -0
- package/dist/chunks/{chunk-WEVDA4IS.js → chunk-NQGVXNXO.js} +6 -6
- package/dist/chunks/{chunk-OQHSD4WX.js → chunk-O3XQA4ZZ.js} +4 -4
- package/dist/chunks/{chunk-7IKMMZ7R.js → chunk-OEI64DLJ.js} +2 -2
- package/dist/chunks/{chunk-CAOXGCUA.js → chunk-PGPL6KIS.js} +3 -3
- package/dist/chunks/{chunk-TC7HMH6P.js → chunk-PSZ6GS75.js} +2 -2
- package/dist/chunks/{chunk-QNHDYR4J.js → chunk-PXLJT6YH.js} +13 -13
- package/dist/chunks/{chunk-AM6K4LK2.js → chunk-QEWQONLW.js} +2 -2
- package/dist/chunks/{chunk-3I5CIWA6.js → chunk-QXSIBEFU.js} +3 -3
- package/dist/chunks/{chunk-GELWAUNY.js → chunk-SDHJ2YUN.js} +7 -3
- package/dist/chunks/chunk-SDHJ2YUN.js.map +6 -0
- package/dist/chunks/{chunk-GKVDZZN6.js → chunk-SJW2UYTK.js} +2 -2
- package/dist/chunks/{chunk-6YVH6LAU.js → chunk-STHNLNY5.js} +4 -4
- package/dist/chunks/{chunk-7NGZ5XGK.js → chunk-T5D5HHTY.js} +24 -16
- package/dist/chunks/{chunk-7NGZ5XGK.js.map → chunk-T5D5HHTY.js.map} +1 -1
- package/dist/chunks/{chunk-OF6QIV42.js → chunk-TCXO5WZX.js} +2 -2
- package/dist/chunks/{chunk-ZBWLULPM.js → chunk-UMVFXQYE.js} +4 -4
- package/dist/chunks/{chunk-KR2AARGO.js → chunk-UY74BJBW.js} +2 -2
- package/dist/chunks/{chunk-HUTSLFLA.js → chunk-VA63RY7U.js} +4 -4
- package/dist/chunks/{chunk-KX2JZX4Q.js → chunk-VHEMDWNA.js} +19 -18
- package/dist/chunks/{chunk-KX2JZX4Q.js.map → chunk-VHEMDWNA.js.map} +1 -1
- package/dist/chunks/chunk-VNGFBD26.js +108 -0
- package/dist/chunks/chunk-VNGFBD26.js.map +6 -0
- package/dist/chunks/{chunk-OIGLY4EG.js → chunk-W5PML5BG.js} +2 -2
- package/dist/chunks/{chunk-KRUTBAWS.js → chunk-XAFTUVN7.js} +5 -5
- package/dist/chunks/{chunk-2Y3V7YTY.js → chunk-YJVLERBF.js} +2 -2
- package/dist/chunks/{chunk-EZ26PYSK.js → chunk-YQHHGBOR.js} +5 -3
- package/dist/chunks/chunk-YQHHGBOR.js.map +6 -0
- package/dist/chunks/{cli-runtime-KHQJO3WG.js → cli-runtime-KH73NP4C.js} +15 -11
- package/dist/chunks/cli-runtime-KH73NP4C.js.map +6 -0
- package/dist/chunks/{commands-GOFR6DU5.js → commands-IMV24FMR.js} +5 -5
- package/dist/chunks/{crash-report-BEZJS4TE.js → crash-report-VQBUHKGL.js} +6 -6
- package/dist/chunks/{dist-ZIZ457D5.js → dist-7Y7RRIE5.js} +4 -2
- package/dist/chunks/{dist-ZIZ457D5.js.map → dist-7Y7RRIE5.js.map} +1 -1
- package/dist/chunks/{dist-TFSA6QEB.js → dist-CQLUZMPF.js} +2 -2
- package/dist/chunks/{dist-2PTH7PME.js → dist-E6HO2DY4.js} +4 -3
- package/dist/chunks/{dist-2PTH7PME.js.map → dist-E6HO2DY4.js.map} +1 -1
- package/dist/chunks/{dist-GR6IFO7M.js → dist-EZYJPZFW.js} +3 -2
- package/dist/chunks/{dist-GR6IFO7M.js.map → dist-EZYJPZFW.js.map} +1 -1
- package/dist/chunks/{dist-AVGYNTRY.js → dist-LNY6YOW7.js} +2 -2
- package/dist/chunks/{dist-OLFVZDAR.js → dist-WAEUJUZL.js} +5 -2
- package/dist/chunks/dist-WAEUJUZL.js.map +6 -0
- package/dist/chunks/{dist-B3WFU7LE.js → dist-ZNBV3COW.js} +4 -3
- package/dist/chunks/{dist-B3WFU7LE.js.map → dist-ZNBV3COW.js.map} +1 -1
- package/dist/chunks/{doctor-Y366MZD7.js → doctor-DEG3FKDC.js} +7 -7
- package/dist/chunks/{drain-CQELENIA.js → drain-NPWQOBUJ.js} +21 -16
- package/dist/chunks/drain-NPWQOBUJ.js.map +6 -0
- package/dist/chunks/{eval-IUIKSMIP.js → eval-GI6JQAOX.js} +2 -2
- package/dist/chunks/{exec-CUF3USRR.js → exec-RP67LSL5.js} +57 -105
- package/dist/chunks/exec-RP67LSL5.js.map +6 -0
- package/dist/chunks/{home-OZK7SYKC.js → home-7EKRNFWG.js} +3 -3
- package/dist/chunks/{host-queries-OZ3GTNQB.js → host-queries-YN42AIUD.js} +17 -17
- package/dist/chunks/{lifecycle-EDPBG4CF.js → lifecycle-T7GDJRCI.js} +28 -29
- package/dist/chunks/{list-OKA3E7GI.js → list-FQZJ3GDF.js} +21 -22
- package/dist/chunks/list-FQZJ3GDF.js.map +6 -0
- package/dist/chunks/{login-NMPAF4D4.js → login-NO23T6HC.js} +9 -9
- package/dist/chunks/{logs-BLEDKYPA.js → logs-LJVTOGXE.js} +4 -4
- package/dist/chunks/{mcp-SO43UZSA.js → mcp-NBWL73J5.js} +23 -22
- package/dist/chunks/mcp-NBWL73J5.js.map +6 -0
- package/dist/chunks/{message-command-4CG7SPQA.js → message-command-YIURBF2Q.js} +40 -39
- package/dist/chunks/message-command-YIURBF2Q.js.map +6 -0
- package/dist/chunks/{operator-tools-BRBJUOP5.js → operator-tools-MQXMUQLG.js} +12 -12
- package/dist/chunks/{output-schema-Q74INRDV.js → output-schema-2BCRDYWG.js} +3 -3
- package/dist/chunks/{pal-Q4LLIL3Z.js → pal-PTOFIOCI.js} +14 -14
- package/dist/chunks/{providers-L4SRCWQ5.js → providers-YRNXCZW5.js} +6 -6
- package/dist/chunks/{resident-KROFLWQD.js → resident-QI33LA6J.js} +29 -28
- package/dist/chunks/resident-QI33LA6J.js.map +6 -0
- package/dist/chunks/resume-3R5VLEIS.js +21 -0
- package/dist/chunks/{resume-command-433WHYYJ.js → resume-command-7SGSPKXV.js} +4 -4
- package/dist/chunks/{schedule-YTD3NQTH.js → schedule-YOMKA5IF.js} +8 -8
- package/dist/chunks/{service-X2BXZORB.js → service-A4YKUMRI.js} +37 -38
- package/dist/chunks/service-A4YKUMRI.js.map +6 -0
- package/dist/chunks/session-step-N5EWWZ4K.js +26 -0
- package/dist/chunks/{skills-6U4GTACH.js → skills-BARULYB3.js} +11 -11
- package/dist/chunks/{state-JKH362WC.js → state-ZD6WF2PZ.js} +2 -2
- package/dist/chunks/{store-LMUDVSKO.js → store-HEOMPNER.js} +4 -4
- package/dist/chunks/{store-T6ITZS2N.js → store-RD7EX5RD.js} +14 -8
- package/dist/chunks/{store-ULDTJXKN.js → store-YWZ6SY2M.js} +6 -6
- package/dist/chunks/store-YWZ6SY2M.js.map +6 -0
- package/dist/chunks/{tui-T5O5A7F3.js → tui-JLOFXK7O.js} +2373 -828
- package/dist/chunks/tui-JLOFXK7O.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-FUJFUSY5.js → upgrade-FLMI5ZYW.js} +2 -2
- package/dist/chunks/{worktree-KJYHKRHL.js → worktree-GUWRR5KY.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/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 +26 -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/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/provider-retry.d.ts +21 -0
- package/dist/provider-retry.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 +5 -4
- 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 +84 -8
- package/dist/tui/agent.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 +19 -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 +12 -12
- package/dist/chunks/acp-QQHLC6HY.js.map +0 -6
- package/dist/chunks/add-VK7JVGYN.js.map +0 -6
- package/dist/chunks/agent-session-FXZ4RXQH.js +0 -46
- package/dist/chunks/chunk-2IWLDZNE.js.map +0 -6
- package/dist/chunks/chunk-7TW2GZ5D.js.map +0 -6
- package/dist/chunks/chunk-E2OJSRDE.js.map +0 -6
- package/dist/chunks/chunk-EZ26PYSK.js.map +0 -6
- package/dist/chunks/chunk-GELWAUNY.js.map +0 -6
- package/dist/chunks/chunk-HBWHJCNO.js.map +0 -6
- package/dist/chunks/chunk-LNBO3KD2.js.map +0 -6
- package/dist/chunks/chunk-QB6CLDHT.js.map +0 -6
- package/dist/chunks/chunk-WBR7JG42.js.map +0 -6
- package/dist/chunks/chunk-ZHWB7GXV.js +0 -71
- package/dist/chunks/chunk-ZHWB7GXV.js.map +0 -6
- package/dist/chunks/cli-runtime-KHQJO3WG.js.map +0 -6
- package/dist/chunks/dist-OLFVZDAR.js.map +0 -6
- package/dist/chunks/drain-CQELENIA.js.map +0 -6
- package/dist/chunks/exec-CUF3USRR.js.map +0 -6
- package/dist/chunks/list-OKA3E7GI.js.map +0 -6
- package/dist/chunks/mcp-SO43UZSA.js.map +0 -6
- package/dist/chunks/message-command-4CG7SPQA.js.map +0 -6
- package/dist/chunks/resident-KROFLWQD.js.map +0 -6
- package/dist/chunks/service-X2BXZORB.js.map +0 -6
- package/dist/chunks/session-step-NTNPJVXZ.js +0 -26
- package/dist/chunks/tui-T5O5A7F3.js.map +0 -6
- /package/dist/chunks/{activity-command-7A2NGBRO.js.map → activity-command-YUENOVUC.js.map} +0 -0
- /package/dist/chunks/{agent-IYFZOSN7.js.map → agent-KYILQUOP.js.map} +0 -0
- /package/dist/chunks/{agent-session-FXZ4RXQH.js.map → agent-session-2YMHOAKF.js.map} +0 -0
- /package/dist/chunks/{archive-7A5RLRRZ.js.map → archive-VXAYIALI.js.map} +0 -0
- /package/dist/chunks/{bin-main-QWTSTI5W.js.map → bin-main-7CCZXZ53.js.map} +0 -0
- /package/dist/chunks/{browser-Z4JR5SV4.js.map → browser-LAZRYCOJ.js.map} +0 -0
- /package/dist/chunks/{chunk-DQNJEGUV.js.map → chunk-2IWFTP44.js.map} +0 -0
- /package/dist/chunks/{chunk-R5QMJRF7.js.map → chunk-2K4A2MVQ.js.map} +0 -0
- /package/dist/chunks/{chunk-KJLJVK4Y.js.map → chunk-34CCZWJM.js.map} +0 -0
- /package/dist/chunks/{chunk-IFBWLO7J.js.map → chunk-3M5GHYIX.js.map} +0 -0
- /package/dist/chunks/{chunk-R5OZ6DCD.js.map → chunk-3RGJ3AC7.js.map} +0 -0
- /package/dist/chunks/{chunk-P6AM76US.js.map → chunk-4JQ2VCTQ.js.map} +0 -0
- /package/dist/chunks/{chunk-BQYV3WGF.js.map → chunk-5GUMVF2I.js.map} +0 -0
- /package/dist/chunks/{chunk-DSODVSO7.js.map → chunk-5RTONMXP.js.map} +0 -0
- /package/dist/chunks/{chunk-7RP7HIBA.js.map → chunk-5Y2HRYPF.js.map} +0 -0
- /package/dist/chunks/{chunk-QLB4KNQA.js.map → chunk-6V3D6JMG.js.map} +0 -0
- /package/dist/chunks/{chunk-KGKBG3U7.js.map → chunk-AHKD4XSH.js.map} +0 -0
- /package/dist/chunks/{chunk-6G3TX6QD.js.map → chunk-BPGADECQ.js.map} +0 -0
- /package/dist/chunks/{chunk-KI7GP25X.js.map → chunk-DEYX6OXI.js.map} +0 -0
- /package/dist/chunks/{chunk-3N54T4H4.js.map → chunk-DFLYRMHP.js.map} +0 -0
- /package/dist/chunks/{chunk-AJLZB6G6.js.map → chunk-EHEEEVWJ.js.map} +0 -0
- /package/dist/chunks/{chunk-FPMRK6W6.js.map → chunk-EIMWVYBK.js.map} +0 -0
- /package/dist/chunks/{chunk-QXUJNVPO.js.map → chunk-I7GFMQGF.js.map} +0 -0
- /package/dist/chunks/{chunk-PDSZNG3C.js.map → chunk-IOGROWMG.js.map} +0 -0
- /package/dist/chunks/{chunk-QQ2TBG2P.js.map → chunk-K7ADP5FF.js.map} +0 -0
- /package/dist/chunks/{chunk-5TIOW3QX.js.map → chunk-KF7KR67Z.js.map} +0 -0
- /package/dist/chunks/{chunk-4BBUZZDS.js.map → chunk-MK4U26GZ.js.map} +0 -0
- /package/dist/chunks/{chunk-J7GTTLAZ.js.map → chunk-MR34S4AM.js.map} +0 -0
- /package/dist/chunks/{chunk-WEVDA4IS.js.map → chunk-NQGVXNXO.js.map} +0 -0
- /package/dist/chunks/{chunk-OQHSD4WX.js.map → chunk-O3XQA4ZZ.js.map} +0 -0
- /package/dist/chunks/{chunk-7IKMMZ7R.js.map → chunk-OEI64DLJ.js.map} +0 -0
- /package/dist/chunks/{chunk-CAOXGCUA.js.map → chunk-PGPL6KIS.js.map} +0 -0
- /package/dist/chunks/{chunk-TC7HMH6P.js.map → chunk-PSZ6GS75.js.map} +0 -0
- /package/dist/chunks/{chunk-QNHDYR4J.js.map → chunk-PXLJT6YH.js.map} +0 -0
- /package/dist/chunks/{chunk-AM6K4LK2.js.map → chunk-QEWQONLW.js.map} +0 -0
- /package/dist/chunks/{chunk-3I5CIWA6.js.map → chunk-QXSIBEFU.js.map} +0 -0
- /package/dist/chunks/{chunk-GKVDZZN6.js.map → chunk-SJW2UYTK.js.map} +0 -0
- /package/dist/chunks/{chunk-6YVH6LAU.js.map → chunk-STHNLNY5.js.map} +0 -0
- /package/dist/chunks/{chunk-OF6QIV42.js.map → chunk-TCXO5WZX.js.map} +0 -0
- /package/dist/chunks/{chunk-ZBWLULPM.js.map → chunk-UMVFXQYE.js.map} +0 -0
- /package/dist/chunks/{chunk-KR2AARGO.js.map → chunk-UY74BJBW.js.map} +0 -0
- /package/dist/chunks/{chunk-HUTSLFLA.js.map → chunk-VA63RY7U.js.map} +0 -0
- /package/dist/chunks/{chunk-OIGLY4EG.js.map → chunk-W5PML5BG.js.map} +0 -0
- /package/dist/chunks/{chunk-KRUTBAWS.js.map → chunk-XAFTUVN7.js.map} +0 -0
- /package/dist/chunks/{chunk-2Y3V7YTY.js.map → chunk-YJVLERBF.js.map} +0 -0
- /package/dist/chunks/{commands-GOFR6DU5.js.map → commands-IMV24FMR.js.map} +0 -0
- /package/dist/chunks/{crash-report-BEZJS4TE.js.map → crash-report-VQBUHKGL.js.map} +0 -0
- /package/dist/chunks/{dist-TFSA6QEB.js.map → dist-CQLUZMPF.js.map} +0 -0
- /package/dist/chunks/{dist-AVGYNTRY.js.map → dist-LNY6YOW7.js.map} +0 -0
- /package/dist/chunks/{doctor-Y366MZD7.js.map → doctor-DEG3FKDC.js.map} +0 -0
- /package/dist/chunks/{eval-IUIKSMIP.js.map → eval-GI6JQAOX.js.map} +0 -0
- /package/dist/chunks/{home-OZK7SYKC.js.map → home-7EKRNFWG.js.map} +0 -0
- /package/dist/chunks/{host-queries-OZ3GTNQB.js.map → host-queries-YN42AIUD.js.map} +0 -0
- /package/dist/chunks/{lifecycle-EDPBG4CF.js.map → lifecycle-T7GDJRCI.js.map} +0 -0
- /package/dist/chunks/{login-NMPAF4D4.js.map → login-NO23T6HC.js.map} +0 -0
- /package/dist/chunks/{logs-BLEDKYPA.js.map → logs-LJVTOGXE.js.map} +0 -0
- /package/dist/chunks/{operator-tools-BRBJUOP5.js.map → operator-tools-MQXMUQLG.js.map} +0 -0
- /package/dist/chunks/{output-schema-Q74INRDV.js.map → output-schema-2BCRDYWG.js.map} +0 -0
- /package/dist/chunks/{pal-Q4LLIL3Z.js.map → pal-PTOFIOCI.js.map} +0 -0
- /package/dist/chunks/{providers-L4SRCWQ5.js.map → providers-YRNXCZW5.js.map} +0 -0
- /package/dist/chunks/{resume-command-433WHYYJ.js.map → resume-3R5VLEIS.js.map} +0 -0
- /package/dist/chunks/{session-step-NTNPJVXZ.js.map → resume-command-7SGSPKXV.js.map} +0 -0
- /package/dist/chunks/{schedule-YTD3NQTH.js.map → schedule-YOMKA5IF.js.map} +0 -0
- /package/dist/chunks/{store-LMUDVSKO.js.map → session-step-N5EWWZ4K.js.map} +0 -0
- /package/dist/chunks/{skills-6U4GTACH.js.map → skills-BARULYB3.js.map} +0 -0
- /package/dist/chunks/{state-JKH362WC.js.map → state-ZD6WF2PZ.js.map} +0 -0
- /package/dist/chunks/{store-T6ITZS2N.js.map → store-HEOMPNER.js.map} +0 -0
- /package/dist/chunks/{store-ULDTJXKN.js.map → store-RD7EX5RD.js.map} +0 -0
- /package/dist/chunks/{upgrade-FUJFUSY5.js.map → upgrade-FLMI5ZYW.js.map} +0 -0
- /package/dist/chunks/{worktree-KJYHKRHL.js.map → worktree-GUWRR5KY.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-4JQ2VCTQ.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-2K4A2MVQ.js";
|
|
12
|
+
import {
|
|
13
|
+
openInBrowser
|
|
14
|
+
} from "./chunk-2IWFTP44.js";
|
|
12
15
|
import {
|
|
13
16
|
createSessionSkillCatalog
|
|
14
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-BPGADECQ.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-DQNJEGUV.js";
|
|
33
|
+
} from "./chunk-PGPL6KIS.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-UMVFXQYE.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-NADDUQSP.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-PXLJT6YH.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-GKVDZZN6.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-6V3D6JMG.js";
|
|
97
88
|
import {
|
|
98
89
|
conversationLogPath,
|
|
99
90
|
ensureSessionStarted
|
|
100
|
-
} from "./chunk-
|
|
91
|
+
} from "./chunk-LSMOWOWC.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-5GUMVF2I.js";
|
|
102
|
+
import {
|
|
103
|
+
compilePermissions,
|
|
104
|
+
isPermissionEffect
|
|
105
|
+
} from "./chunk-JAPAPPNH.js";
|
|
106
|
+
import {
|
|
107
|
+
cliLogger
|
|
108
|
+
} from "./chunk-SJW2UYTK.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-3RGJ3AC7.js";
|
|
114
119
|
import {
|
|
115
120
|
namzuHomePath
|
|
116
|
-
} from "./chunk-
|
|
121
|
+
} from "./chunk-5Y2HRYPF.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,6 +236,7 @@ import {
|
|
|
228
236
|
isTrustedReadOnly,
|
|
229
237
|
isTurnInProgressError,
|
|
230
238
|
isolationOf,
|
|
239
|
+
lexShellCommandLine,
|
|
231
240
|
mapTools,
|
|
232
241
|
mcpJsonSchemaToZod,
|
|
233
242
|
openSessionTokenBudget,
|
|
@@ -238,6 +247,7 @@ import {
|
|
|
238
247
|
refineEvidenceRecallTerms,
|
|
239
248
|
requireOpenProject,
|
|
240
249
|
resolveContextWindow,
|
|
250
|
+
resolveModelPricing,
|
|
241
251
|
resolveNamzuHome,
|
|
242
252
|
resolveWithinReal,
|
|
243
253
|
resumeSession,
|
|
@@ -252,7 +262,7 @@ import {
|
|
|
252
262
|
windowsShellNotice,
|
|
253
263
|
withProviderFallback,
|
|
254
264
|
wrapUntrusted
|
|
255
|
-
} from "./chunk-
|
|
265
|
+
} from "./chunk-5J3T7DNL.js";
|
|
256
266
|
import {
|
|
257
267
|
__name
|
|
258
268
|
} from "./chunk-76FLAFCG.js";
|
|
@@ -367,10 +377,10 @@ var tail = Promise.resolve();
|
|
|
367
377
|
var nextStart = 0;
|
|
368
378
|
function cancelled(promise, signal) {
|
|
369
379
|
signal.throwIfAborted();
|
|
370
|
-
return new Promise((
|
|
380
|
+
return new Promise((resolve11, reject) => {
|
|
371
381
|
const abort = /* @__PURE__ */ __name(() => reject(signal.reason), "abort");
|
|
372
382
|
signal.addEventListener("abort", abort, { once: true });
|
|
373
|
-
promise.then(
|
|
383
|
+
promise.then(resolve11, reject).finally(() => signal.removeEventListener("abort", abort));
|
|
374
384
|
});
|
|
375
385
|
}
|
|
376
386
|
__name(cancelled, "cancelled");
|
|
@@ -411,8 +421,8 @@ async function searchExa(query2, limit, context) {
|
|
|
411
421
|
const deadline = Date.now() + DEADLINE_MS;
|
|
412
422
|
const previous = tail;
|
|
413
423
|
let release;
|
|
414
|
-
tail = new Promise((
|
|
415
|
-
release =
|
|
424
|
+
tail = new Promise((resolve11) => {
|
|
425
|
+
release = resolve11;
|
|
416
426
|
});
|
|
417
427
|
let acquired = false;
|
|
418
428
|
try {
|
|
@@ -929,7 +939,7 @@ __name(oneLine, "oneLine");
|
|
|
929
939
|
// src/tui/agent.ts
|
|
930
940
|
import { SubprocessComputerUseHost } from "@namzu/computer-use";
|
|
931
941
|
import { realpath as realpath4, stat as stat4 } from "node:fs/promises";
|
|
932
|
-
import { join as
|
|
942
|
+
import { join as join14, parse, resolve as resolve10 } from "node:path";
|
|
933
943
|
|
|
934
944
|
// src/checkpoints/store.ts
|
|
935
945
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
@@ -2334,6 +2344,11 @@ function createSessionDirectories(cwd, directories) {
|
|
|
2334
2344
|
}
|
|
2335
2345
|
__name(createSessionDirectories, "createSessionDirectories");
|
|
2336
2346
|
|
|
2347
|
+
// src/context/doctrine.ts
|
|
2348
|
+
var NAMZU_PLAN_FILE_DOCTRINE = `## Plan mode
|
|
2349
|
+
|
|
2350
|
+
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.`;
|
|
2351
|
+
|
|
2337
2352
|
// src/context/project-tracker.ts
|
|
2338
2353
|
import { realpathSync } from "node:fs";
|
|
2339
2354
|
import { dirname as dirname2, isAbsolute as isAbsolute3, join as join3, relative as relative3, resolve as resolve3, sep as sep2 } from "node:path";
|
|
@@ -3943,7 +3958,7 @@ async function searchConversationCore(sessions, sessionId, request, signal, acti
|
|
|
3943
3958
|
result.excludedToolResults = (result.excludedToolResults ?? 0) + page.excludedToolResults;
|
|
3944
3959
|
if (page.excludedSummaries)
|
|
3945
3960
|
result.excludedSummaries = (result.excludedSummaries ?? 0) + page.excludedSummaries;
|
|
3946
|
-
const
|
|
3961
|
+
const matches = page.matches.map(
|
|
3947
3962
|
(match) => ({
|
|
3948
3963
|
seq: match.seq,
|
|
3949
3964
|
recordedAt: match.recordedAt,
|
|
@@ -3958,11 +3973,11 @@ async function searchConversationCore(sessions, sessionId, request, signal, acti
|
|
|
3958
3973
|
...match.characterOffset === void 0 ? {} : { byteOffset: match.byteOffset }
|
|
3959
3974
|
})
|
|
3960
3975
|
);
|
|
3961
|
-
const bytes = Buffer.byteLength(JSON.stringify(
|
|
3976
|
+
const bytes = Buffer.byteLength(JSON.stringify(matches));
|
|
3962
3977
|
if (outputBytes + bytes > OUTPUT_BYTES)
|
|
3963
3978
|
throw new Error("Evidence exceeded its output allowance.");
|
|
3964
3979
|
outputBytes += bytes;
|
|
3965
|
-
result.matches.push(...
|
|
3980
|
+
result.matches.push(...matches);
|
|
3966
3981
|
result.unavailable += page.unavailable.length;
|
|
3967
3982
|
result.incomplete ||= page.incomplete || page.unavailable.length > 0;
|
|
3968
3983
|
state.omitted ||= page.incomplete || page.unavailable.length > 0;
|
|
@@ -4235,15 +4250,15 @@ function newScan(terms) {
|
|
|
4235
4250
|
return { terms, started: false };
|
|
4236
4251
|
}
|
|
4237
4252
|
__name(newScan, "newScan");
|
|
4238
|
-
function advanceScan(scans,
|
|
4239
|
-
|
|
4240
|
-
|
|
4253
|
+
function advanceScan(scans, scan2, nextCursor, excerpts, hasDerivedSummaries, canRefine) {
|
|
4254
|
+
scan2.started = true;
|
|
4255
|
+
scan2.cursor = nextCursor;
|
|
4241
4256
|
if (!canRefine || scans.length !== 1 || !nextCursor) return;
|
|
4242
4257
|
if (hasDerivedSummaries) {
|
|
4243
|
-
scans.push({ ...newScan(
|
|
4258
|
+
scans.push({ ...newScan(scan2.terms), excludeDerivedSummaries: true });
|
|
4244
4259
|
return;
|
|
4245
4260
|
}
|
|
4246
|
-
const focused = refineEvidenceRecallTerms(
|
|
4261
|
+
const focused = refineEvidenceRecallTerms(scan2.terms, excerpts);
|
|
4247
4262
|
if (focused) scans.push(newScan(focused));
|
|
4248
4263
|
}
|
|
4249
4264
|
__name(advanceScan, "advanceScan");
|
|
@@ -4268,8 +4283,8 @@ function createConversationEvidenceRecall(sessions, sessionId, assertOwner, reso
|
|
|
4268
4283
|
let excludedSummaries = 0;
|
|
4269
4284
|
const scans = [newScan(terms)];
|
|
4270
4285
|
for (let pages = 0; pages < RECALL_PAGES; pages++) {
|
|
4271
|
-
const
|
|
4272
|
-
if (!
|
|
4286
|
+
const scan2 = [...scans].reverse().find((s) => !s.started || s.cursor);
|
|
4287
|
+
if (!scan2) break;
|
|
4273
4288
|
signal.throwIfAborted();
|
|
4274
4289
|
const remaining = maxReadBytes - scannedBytes;
|
|
4275
4290
|
if (remaining < 1024 * 1024) {
|
|
@@ -4280,12 +4295,12 @@ function createConversationEvidenceRecall(sessions, sessionId, assertOwner, reso
|
|
|
4280
4295
|
sessions,
|
|
4281
4296
|
sessionId,
|
|
4282
4297
|
{
|
|
4283
|
-
terms:
|
|
4298
|
+
terms: scan2.terms,
|
|
4284
4299
|
matchMode: "token",
|
|
4285
4300
|
excludeSuccessfulTools: CONVERSATION_RETRIEVAL_TOOLS,
|
|
4286
|
-
excludeDerivedSummaries:
|
|
4301
|
+
excludeDerivedSummaries: scan2.excludeDerivedSummaries ?? false,
|
|
4287
4302
|
maxReadBytes: remaining,
|
|
4288
|
-
...
|
|
4303
|
+
...scan2.cursor ? { cursor: scan2.cursor } : {}
|
|
4289
4304
|
},
|
|
4290
4305
|
signal,
|
|
4291
4306
|
active
|
|
@@ -4316,7 +4331,7 @@ function createConversationEvidenceRecall(sessions, sessionId, assertOwner, reso
|
|
|
4316
4331
|
}
|
|
4317
4332
|
advanceScan(
|
|
4318
4333
|
scans,
|
|
4319
|
-
|
|
4334
|
+
scan2,
|
|
4320
4335
|
page.nextCursor,
|
|
4321
4336
|
page.matches.map((match) => match.text),
|
|
4322
4337
|
page.matches.some((match) => match.source === "compaction_shed:summary"),
|
|
@@ -4326,9 +4341,9 @@ function createConversationEvidenceRecall(sessions, sessionId, assertOwner, reso
|
|
|
4326
4341
|
}
|
|
4327
4342
|
assertOwner(turnId);
|
|
4328
4343
|
signal.throwIfAborted();
|
|
4329
|
-
const continuations = [...scans].reverse().filter((
|
|
4344
|
+
const continuations = [...scans].reverse().filter((scan2) => scan2.cursor !== void 0).map((scan2) => ({
|
|
4330
4345
|
toolName: "search_conversation",
|
|
4331
|
-
input: { cursor:
|
|
4346
|
+
input: { cursor: scan2.cursor }
|
|
4332
4347
|
}));
|
|
4333
4348
|
return {
|
|
4334
4349
|
candidates,
|
|
@@ -4433,6 +4448,150 @@ function createTaskContextStep(store, tenantId, now = Date.now) {
|
|
|
4433
4448
|
}
|
|
4434
4449
|
__name(createTaskContextStep, "createTaskContextStep");
|
|
4435
4450
|
|
|
4451
|
+
// src/integrations/small-model/route.ts
|
|
4452
|
+
function parseSmallModel(value, activeProviderId, isKnownProvider) {
|
|
4453
|
+
const slash = value.indexOf("/");
|
|
4454
|
+
if (slash > 0 && slash < value.length - 1) {
|
|
4455
|
+
const head = value.slice(0, slash);
|
|
4456
|
+
if (isKnownProvider(head)) return { providerId: head, model: value.slice(slash + 1) };
|
|
4457
|
+
}
|
|
4458
|
+
return { providerId: activeProviderId, model: value };
|
|
4459
|
+
}
|
|
4460
|
+
__name(parseSmallModel, "parseSmallModel");
|
|
4461
|
+
var NOT_A_CHAT_MODEL = /embed|moderat|whisper|transcri|tts|speech|image|dall-?e|realtime|audio/iu;
|
|
4462
|
+
function price(providerId, model) {
|
|
4463
|
+
if (model.inputPrice !== void 0 && model.outputPrice !== void 0) {
|
|
4464
|
+
return model.inputPrice + model.outputPrice;
|
|
4465
|
+
}
|
|
4466
|
+
const rates = resolveModelPricing(providerId, model.id);
|
|
4467
|
+
return rates === void 0 ? void 0 : rates.inputCostPer1M + rates.outputCostPer1M;
|
|
4468
|
+
}
|
|
4469
|
+
__name(price, "price");
|
|
4470
|
+
function cheapestTextModel(providerId, models, offerable = () => true) {
|
|
4471
|
+
let best;
|
|
4472
|
+
for (const model of models) {
|
|
4473
|
+
if (!model.supportsStreaming) continue;
|
|
4474
|
+
if (model.inputModalities !== void 0 && !model.inputModalities.includes("text")) continue;
|
|
4475
|
+
if (NOT_A_CHAT_MODEL.test(model.id)) continue;
|
|
4476
|
+
if (!offerable(model)) continue;
|
|
4477
|
+
const cost = price(providerId, model);
|
|
4478
|
+
if (cost === void 0) continue;
|
|
4479
|
+
if (best === void 0) {
|
|
4480
|
+
best = { model, cost };
|
|
4481
|
+
continue;
|
|
4482
|
+
}
|
|
4483
|
+
if (cost !== best.cost) {
|
|
4484
|
+
if (cost < best.cost) best = { model, cost };
|
|
4485
|
+
continue;
|
|
4486
|
+
}
|
|
4487
|
+
const window = model.contextWindow ?? 0;
|
|
4488
|
+
const bestWindow = best.model.contextWindow ?? 0;
|
|
4489
|
+
if (window > bestWindow || window === bestWindow && model.id.length < best.model.id.length) {
|
|
4490
|
+
best = { model, cost };
|
|
4491
|
+
}
|
|
4492
|
+
}
|
|
4493
|
+
return best?.model;
|
|
4494
|
+
}
|
|
4495
|
+
__name(cheapestTextModel, "cheapestTextModel");
|
|
4496
|
+
|
|
4497
|
+
// src/integrations/small-model/side-model.ts
|
|
4498
|
+
function estimateTokens(text) {
|
|
4499
|
+
return Math.ceil(text.length / 4);
|
|
4500
|
+
}
|
|
4501
|
+
__name(estimateTokens, "estimateTokens");
|
|
4502
|
+
function createSideModel(deps) {
|
|
4503
|
+
const routes = /* @__PURE__ */ new Map();
|
|
4504
|
+
const resolve11 = /* @__PURE__ */ __name(async (sessionId, signal) => {
|
|
4505
|
+
const active = deps.active();
|
|
4506
|
+
if (deps.configured !== void 0) {
|
|
4507
|
+
const target = parseSmallModel(deps.configured, active.providerId, deps.isKnownProvider);
|
|
4508
|
+
return { ...target, source: "configured" };
|
|
4509
|
+
}
|
|
4510
|
+
try {
|
|
4511
|
+
const provider = await deps.buildProvider(sessionId, active);
|
|
4512
|
+
if (provider.listModels === void 0) return { ...active, source: "main" };
|
|
4513
|
+
const listing = await runPickerProviderOperation(
|
|
4514
|
+
signal,
|
|
4515
|
+
(operationSignal) => provider.listModels(operationSignal)
|
|
4516
|
+
);
|
|
4517
|
+
const cheapest = cheapestTextModel(
|
|
4518
|
+
active.providerId,
|
|
4519
|
+
listing,
|
|
4520
|
+
(model) => deps.offerable ? deps.offerable(active.providerId, model) : true
|
|
4521
|
+
);
|
|
4522
|
+
if (cheapest !== void 0) {
|
|
4523
|
+
return {
|
|
4524
|
+
providerId: active.providerId,
|
|
4525
|
+
model: cheapest.id,
|
|
4526
|
+
source: "cheapest"
|
|
4527
|
+
};
|
|
4528
|
+
}
|
|
4529
|
+
} catch (error) {
|
|
4530
|
+
deps.debug?.("side model: listing failed, using the conversation model", error);
|
|
4531
|
+
}
|
|
4532
|
+
return { ...active, source: "main" };
|
|
4533
|
+
}, "resolve");
|
|
4534
|
+
const route = /* @__PURE__ */ __name((sessionId, signal) => {
|
|
4535
|
+
const active = deps.active();
|
|
4536
|
+
const key = `${active.providerId}
|
|
4537
|
+
${active.model}
|
|
4538
|
+
${deps.configured ?? ""}`;
|
|
4539
|
+
let pending = routes.get(key);
|
|
4540
|
+
if (pending === void 0) {
|
|
4541
|
+
pending = resolve11(sessionId, signal);
|
|
4542
|
+
routes.set(key, pending);
|
|
4543
|
+
void pending.then((value) => {
|
|
4544
|
+
if (signal.aborted && value.source === "main" && routes.get(key) === pending) {
|
|
4545
|
+
routes.delete(key);
|
|
4546
|
+
}
|
|
4547
|
+
});
|
|
4548
|
+
}
|
|
4549
|
+
return pending;
|
|
4550
|
+
}, "route");
|
|
4551
|
+
const ask = /* @__PURE__ */ __name(async (request) => {
|
|
4552
|
+
try {
|
|
4553
|
+
request.signal.throwIfAborted();
|
|
4554
|
+
const chosen = await route(request.sessionId, request.signal);
|
|
4555
|
+
const provider = await deps.buildProvider(request.sessionId, chosen);
|
|
4556
|
+
const estimatedPromptTokens = estimateTokens(request.instruction) + estimateTokens(request.body);
|
|
4557
|
+
const send = /* @__PURE__ */ __name(async () => {
|
|
4558
|
+
const response = await collectChatCompletion(
|
|
4559
|
+
provider.chatStream({
|
|
4560
|
+
model: chosen.model,
|
|
4561
|
+
messages: [createSystemMessage(request.instruction), createUserMessage(request.body)],
|
|
4562
|
+
maxTokens: request.maxTokens,
|
|
4563
|
+
signal: request.signal
|
|
4564
|
+
})
|
|
4565
|
+
);
|
|
4566
|
+
return { value: response.message.content ?? "", usage: response.usage };
|
|
4567
|
+
}, "send");
|
|
4568
|
+
if (request.timing === "in-turn") {
|
|
4569
|
+
const text = await deps.ledger.chargeNow({
|
|
4570
|
+
turnId: request.turnId,
|
|
4571
|
+
sessionId: request.sessionId,
|
|
4572
|
+
estimatedPromptTokens,
|
|
4573
|
+
signal: request.signal,
|
|
4574
|
+
request: send
|
|
4575
|
+
});
|
|
4576
|
+
return text?.trim() ? text : void 0;
|
|
4577
|
+
}
|
|
4578
|
+
const result = await send();
|
|
4579
|
+
void deps.ledger.chargeLater({
|
|
4580
|
+
turnId: request.turnId,
|
|
4581
|
+
sessionId: request.sessionId,
|
|
4582
|
+
estimatedPromptTokens,
|
|
4583
|
+
usage: result.usage
|
|
4584
|
+
});
|
|
4585
|
+
return result.value.trim() ? result.value : void 0;
|
|
4586
|
+
} catch (error) {
|
|
4587
|
+
deps.debug?.("side model: request failed", error);
|
|
4588
|
+
return void 0;
|
|
4589
|
+
}
|
|
4590
|
+
}, "ask");
|
|
4591
|
+
return { route, ask };
|
|
4592
|
+
}
|
|
4593
|
+
__name(createSideModel, "createSideModel");
|
|
4594
|
+
|
|
4436
4595
|
// src/integrations/state/retention.ts
|
|
4437
4596
|
var CLI_CHECKPOINT_RETENTION = 10;
|
|
4438
4597
|
|
|
@@ -6275,9 +6434,68 @@ async function createSubagentRuntime(input) {
|
|
|
6275
6434
|
throw error;
|
|
6276
6435
|
}
|
|
6277
6436
|
}, "gatewayForTurn");
|
|
6437
|
+
const queuedSideSpend = /* @__PURE__ */ new Map();
|
|
6438
|
+
const releasedTurns = /* @__PURE__ */ new Set();
|
|
6439
|
+
const countSideSpend = /* @__PURE__ */ __name(async (budget, spend) => {
|
|
6440
|
+
const controller = new AbortController();
|
|
6441
|
+
await chargeLabelRequest({
|
|
6442
|
+
budget,
|
|
6443
|
+
sessionId: spend.sessionId,
|
|
6444
|
+
estimatedPromptTokens: spend.estimatedPromptTokens,
|
|
6445
|
+
signal: controller.signal,
|
|
6446
|
+
request: /* @__PURE__ */ __name(async () => ({ value: true, usage: spend.usage }), "request")
|
|
6447
|
+
}).catch(() => void 0);
|
|
6448
|
+
}, "countSideSpend");
|
|
6449
|
+
const countQueuedSideSpend = /* @__PURE__ */ __name(async (turnId, pending) => {
|
|
6450
|
+
const queued = queuedSideSpend.get(turnId);
|
|
6451
|
+
if (queued === void 0) return;
|
|
6452
|
+
queuedSideSpend.delete(turnId);
|
|
6453
|
+
const runtime = await pending.catch(() => void 0);
|
|
6454
|
+
if (runtime === void 0) return;
|
|
6455
|
+
for (const spend of queued) await countSideSpend(runtime.budget, spend);
|
|
6456
|
+
}, "countQueuedSideSpend");
|
|
6457
|
+
const sideLedger = {
|
|
6458
|
+
async chargeNow(input2) {
|
|
6459
|
+
const turn = await parents.get(input2.turnId)?.catch(() => void 0);
|
|
6460
|
+
if (!turn || closed) return void 0;
|
|
6461
|
+
return chargeLabelRequest({
|
|
6462
|
+
budget: turn.budget,
|
|
6463
|
+
sessionId: input2.sessionId,
|
|
6464
|
+
estimatedPromptTokens: input2.estimatedPromptTokens,
|
|
6465
|
+
signal: input2.signal,
|
|
6466
|
+
request: input2.request
|
|
6467
|
+
});
|
|
6468
|
+
},
|
|
6469
|
+
async chargeLater(input2) {
|
|
6470
|
+
const spend = {
|
|
6471
|
+
sessionId: input2.sessionId,
|
|
6472
|
+
estimatedPromptTokens: input2.estimatedPromptTokens,
|
|
6473
|
+
usage: input2.usage
|
|
6474
|
+
};
|
|
6475
|
+
if (!releasedTurns.has(input2.turnId)) {
|
|
6476
|
+
const queue = queuedSideSpend.get(input2.turnId) ?? [];
|
|
6477
|
+
queue.push(spend);
|
|
6478
|
+
queuedSideSpend.set(input2.turnId, queue);
|
|
6479
|
+
return;
|
|
6480
|
+
}
|
|
6481
|
+
await openSessionTokenBudget({
|
|
6482
|
+
store: tokenBudgetStore,
|
|
6483
|
+
scope: { rootSessionId: input2.sessionId, rootTurnId: input2.turnId }
|
|
6484
|
+
}).then(
|
|
6485
|
+
(budget) => countSideSpend(budget, spend),
|
|
6486
|
+
() => void 0
|
|
6487
|
+
);
|
|
6488
|
+
}
|
|
6489
|
+
};
|
|
6278
6490
|
const releaseTurn = /* @__PURE__ */ __name(async (turnId) => {
|
|
6279
6491
|
const pending = parents.get(turnId);
|
|
6280
6492
|
if (!pending) return;
|
|
6493
|
+
await countQueuedSideSpend(turnId, pending);
|
|
6494
|
+
releasedTurns.add(turnId);
|
|
6495
|
+
if (releasedTurns.size > 256) {
|
|
6496
|
+
const oldest = releasedTurns.values().next().value;
|
|
6497
|
+
if (oldest !== void 0) releasedTurns.delete(oldest);
|
|
6498
|
+
}
|
|
6281
6499
|
parents.delete(turnId);
|
|
6282
6500
|
await pending.then(
|
|
6283
6501
|
(runtime) => runtime.close(),
|
|
@@ -7335,6 +7553,7 @@ ${JSON.stringify(launch.schema)}`;
|
|
|
7335
7553
|
gatewayForTurn,
|
|
7336
7554
|
completionInboxForTurn,
|
|
7337
7555
|
releaseTurn,
|
|
7556
|
+
sideLedger,
|
|
7338
7557
|
agentTool,
|
|
7339
7558
|
waitForTaskTool,
|
|
7340
7559
|
agentTaskListTool,
|
|
@@ -7732,11 +7951,11 @@ var WorkflowRunRegistry = class {
|
|
|
7732
7951
|
whenIdle(signal) {
|
|
7733
7952
|
const going = /* @__PURE__ */ __name(() => [...this.runs.values()].some((run2) => !run2.finalized), "going");
|
|
7734
7953
|
if (!going() || signal?.aborted) return Promise.resolve();
|
|
7735
|
-
return new Promise((
|
|
7954
|
+
return new Promise((resolve11) => {
|
|
7736
7955
|
const done = /* @__PURE__ */ __name(() => {
|
|
7737
7956
|
off();
|
|
7738
7957
|
signal?.removeEventListener("abort", done);
|
|
7739
|
-
|
|
7958
|
+
resolve11();
|
|
7740
7959
|
}, "done");
|
|
7741
7960
|
const off = this.subscribe(() => {
|
|
7742
7961
|
if (!going()) done();
|
|
@@ -7933,8 +8152,8 @@ function createWorkflowHost(options) {
|
|
|
7933
8152
|
let launching = true;
|
|
7934
8153
|
let settleLaunch = /* @__PURE__ */ __name(() => {
|
|
7935
8154
|
}, "settleLaunch");
|
|
7936
|
-
const launch = new Promise((
|
|
7937
|
-
settleLaunch =
|
|
8155
|
+
const launch = new Promise((resolve11) => {
|
|
8156
|
+
settleLaunch = resolve11;
|
|
7938
8157
|
});
|
|
7939
8158
|
const detach = /* @__PURE__ */ __name(() => {
|
|
7940
8159
|
if (!launching) return;
|
|
@@ -8743,28 +8962,249 @@ function createLiveModeControl(options) {
|
|
|
8743
8962
|
}
|
|
8744
8963
|
__name(createLiveModeControl, "createLiveModeControl");
|
|
8745
8964
|
|
|
8965
|
+
// src/permissions/local-settings.ts
|
|
8966
|
+
import { execFile as execFile3 } from "node:child_process";
|
|
8967
|
+
import { existsSync, readFileSync, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
8968
|
+
import { appendFile as appendFile3, mkdir as mkdir5, readFile as readFile5, writeFile as writeFile3 } from "node:fs/promises";
|
|
8969
|
+
import { homedir } from "node:os";
|
|
8970
|
+
import { dirname as dirname3, isAbsolute as isAbsolute6, join as join13, resolve as resolve8 } from "node:path";
|
|
8971
|
+
function localConfigPath(cwd) {
|
|
8972
|
+
return resolve8(cwd, LOCAL_CONFIG_FILE);
|
|
8973
|
+
}
|
|
8974
|
+
__name(localConfigPath, "localConfigPath");
|
|
8975
|
+
function isRecord2(value) {
|
|
8976
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8977
|
+
}
|
|
8978
|
+
__name(isRecord2, "isRecord");
|
|
8979
|
+
function addAllowRules(permissions, additions) {
|
|
8980
|
+
const out = { ...permissions };
|
|
8981
|
+
for (const [tool, wanted] of Object.entries(additions)) {
|
|
8982
|
+
const existing = out[tool];
|
|
8983
|
+
if (existing === void 0) {
|
|
8984
|
+
out[tool] = wanted;
|
|
8985
|
+
continue;
|
|
8986
|
+
}
|
|
8987
|
+
if (isPermissionEffect(existing)) continue;
|
|
8988
|
+
if (!isRecord2(existing)) continue;
|
|
8989
|
+
if (isPermissionEffect(wanted)) {
|
|
8990
|
+
continue;
|
|
8991
|
+
}
|
|
8992
|
+
const table = { ...existing };
|
|
8993
|
+
for (const [pattern, effect] of Object.entries(wanted)) {
|
|
8994
|
+
if (table[pattern] === void 0) table[pattern] = effect;
|
|
8995
|
+
}
|
|
8996
|
+
out[tool] = table;
|
|
8997
|
+
}
|
|
8998
|
+
return out;
|
|
8999
|
+
}
|
|
9000
|
+
__name(addAllowRules, "addAllowRules");
|
|
9001
|
+
function writeLocalAllows(cwd, additions) {
|
|
9002
|
+
const path = localConfigPath(cwd);
|
|
9003
|
+
let document = {};
|
|
9004
|
+
if (existsSync(path)) {
|
|
9005
|
+
let parsed;
|
|
9006
|
+
try {
|
|
9007
|
+
parsed = JSON.parse(readFileSync(path, "utf-8"));
|
|
9008
|
+
} catch (cause) {
|
|
9009
|
+
return {
|
|
9010
|
+
path,
|
|
9011
|
+
error: `${LOCAL_CONFIG_FILE} is not valid JSON (${cause instanceof Error ? cause.message : String(cause)})`
|
|
9012
|
+
};
|
|
9013
|
+
}
|
|
9014
|
+
if (!isRecord2(parsed)) return { path, error: `${LOCAL_CONFIG_FILE} is not a JSON object` };
|
|
9015
|
+
document = parsed;
|
|
9016
|
+
}
|
|
9017
|
+
const permissions = isRecord2(document.permissions) ? document.permissions : {};
|
|
9018
|
+
if (document.permissions !== void 0 && !isRecord2(document.permissions)) {
|
|
9019
|
+
return { path, error: `${LOCAL_CONFIG_FILE} has a permissions value that is not a table` };
|
|
9020
|
+
}
|
|
9021
|
+
document = { ...document, permissions: addAllowRules(permissions, additions) };
|
|
9022
|
+
try {
|
|
9023
|
+
const staging = `${path}.${process.pid}.tmp`;
|
|
9024
|
+
writeFileSync2(staging, `${JSON.stringify(document, null, " ")}
|
|
9025
|
+
`, { mode: 384 });
|
|
9026
|
+
renameSync2(staging, path);
|
|
9027
|
+
} catch (cause) {
|
|
9028
|
+
return { path, error: cause instanceof Error ? cause.message : String(cause) };
|
|
9029
|
+
}
|
|
9030
|
+
return { path };
|
|
9031
|
+
}
|
|
9032
|
+
__name(writeLocalAllows, "writeLocalAllows");
|
|
9033
|
+
function git2(args, cwd, env) {
|
|
9034
|
+
return new Promise((done) => {
|
|
9035
|
+
execFile3(
|
|
9036
|
+
"git",
|
|
9037
|
+
[...args],
|
|
9038
|
+
{ cwd, env, timeout: 15e3, windowsHide: true },
|
|
9039
|
+
(error, stdout) => {
|
|
9040
|
+
const code = error === null ? 0 : typeof error.code === "number" ? error.code : 1;
|
|
9041
|
+
done({ code, stdout: String(stdout ?? "") });
|
|
9042
|
+
}
|
|
9043
|
+
);
|
|
9044
|
+
});
|
|
9045
|
+
}
|
|
9046
|
+
__name(git2, "git");
|
|
9047
|
+
function globalIgnorePath(configured, env) {
|
|
9048
|
+
const home = env.HOME ?? env.USERPROFILE ?? homedir();
|
|
9049
|
+
const value = configured.trim();
|
|
9050
|
+
if (value === "~" || value.startsWith("~/")) return join13(home, value.slice(2));
|
|
9051
|
+
if (value !== "" && isAbsolute6(value)) return value;
|
|
9052
|
+
const xdg = env.XDG_CONFIG_HOME;
|
|
9053
|
+
if (xdg && isAbsolute6(xdg)) return join13(xdg, "git", "ignore");
|
|
9054
|
+
return join13(home, ".config", "git", "ignore");
|
|
9055
|
+
}
|
|
9056
|
+
__name(globalIgnorePath, "globalIgnorePath");
|
|
9057
|
+
async function ensureLocalConfigIgnored(cwd, env = process.env) {
|
|
9058
|
+
try {
|
|
9059
|
+
const inside = await git2(["rev-parse", "--is-inside-work-tree"], cwd, env);
|
|
9060
|
+
if (inside.code !== 0 || inside.stdout.trim() !== "true") return { state: "not-a-repository" };
|
|
9061
|
+
const ignored = /* @__PURE__ */ __name(async () => (await git2(["check-ignore", "--", LOCAL_CONFIG_FILE], cwd, env)).code === 0, "ignored");
|
|
9062
|
+
if (await ignored()) return { state: "ignored", written: false };
|
|
9063
|
+
const configured = await git2(["config", "--global", "--get", "core.excludesfile"], cwd, env);
|
|
9064
|
+
const file = globalIgnorePath(configured.code === 0 ? configured.stdout : "", env);
|
|
9065
|
+
const line = `**/${LOCAL_CONFIG_FILE}`;
|
|
9066
|
+
await mkdir5(dirname3(file), { recursive: true });
|
|
9067
|
+
let existing = "";
|
|
9068
|
+
try {
|
|
9069
|
+
existing = await readFile5(file, "utf-8");
|
|
9070
|
+
} catch {
|
|
9071
|
+
}
|
|
9072
|
+
const why = /* @__PURE__ */ __name(async () => (await git2(["ls-files", "--error-unmatch", "--", LOCAL_CONFIG_FILE], cwd, env)).code === 0 ? "tracked" : "not-read", "why");
|
|
9073
|
+
if (existing.includes(line)) {
|
|
9074
|
+
const reason = await why();
|
|
9075
|
+
return { state: reason, reason: `${line} is in ${file} but git does not ignore the file` };
|
|
9076
|
+
}
|
|
9077
|
+
if (existing === "") await writeFile3(file, `${line}
|
|
9078
|
+
`, "utf-8");
|
|
9079
|
+
else await appendFile3(file, `${existing.endsWith("\n") ? "" : "\n"}${line}
|
|
9080
|
+
`, "utf-8");
|
|
9081
|
+
if (!await ignored()) {
|
|
9082
|
+
const reason = await why();
|
|
9083
|
+
return { state: reason, reason: `wrote ${line} to ${file} but git still does not ignore it` };
|
|
9084
|
+
}
|
|
9085
|
+
return { state: "ignored", written: true };
|
|
9086
|
+
} catch (cause) {
|
|
9087
|
+
return { state: "failed", reason: cause instanceof Error ? cause.message : String(cause) };
|
|
9088
|
+
}
|
|
9089
|
+
}
|
|
9090
|
+
__name(ensureLocalConfigIgnored, "ensureLocalConfigIgnored");
|
|
9091
|
+
function logIgnoreOutcome(outcome) {
|
|
9092
|
+
if (outcome.state === "ignored" || outcome.state === "not-a-repository") return;
|
|
9093
|
+
cliLogger().warn("The local config may be tracked by git", {
|
|
9094
|
+
"namzu.config.local.state": outcome.state,
|
|
9095
|
+
"namzu.config.local.reason": outcome.reason
|
|
9096
|
+
});
|
|
9097
|
+
}
|
|
9098
|
+
__name(logIgnoreOutcome, "logIgnoreOutcome");
|
|
9099
|
+
|
|
8746
9100
|
// src/permissions/session-allow.ts
|
|
8747
9101
|
var WEB_FETCH_TOOL = "web_fetch";
|
|
8748
9102
|
var MAX_LABEL_COMMAND = 60;
|
|
8749
|
-
|
|
9103
|
+
var MAX_RULES_PER_ANSWER = 5;
|
|
9104
|
+
function isRecord3(value) {
|
|
8750
9105
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8751
9106
|
}
|
|
8752
|
-
__name(
|
|
9107
|
+
__name(isRecord3, "isRecord");
|
|
8753
9108
|
function alwaysAsked(call) {
|
|
8754
9109
|
return call.escalation !== void 0 || call.requiresApproval === true || call.authorization?.explicitReview === true || call.isDestructive === true;
|
|
8755
9110
|
}
|
|
8756
9111
|
__name(alwaysAsked, "alwaysAsked");
|
|
8757
|
-
|
|
9112
|
+
var NO_PREFIX_PROGRAMS = /* @__PURE__ */ new Set([
|
|
9113
|
+
"sh",
|
|
9114
|
+
"bash",
|
|
9115
|
+
"zsh",
|
|
9116
|
+
"fish",
|
|
9117
|
+
"csh",
|
|
9118
|
+
"tcsh",
|
|
9119
|
+
"ksh",
|
|
9120
|
+
"dash",
|
|
9121
|
+
"cmd",
|
|
9122
|
+
"powershell",
|
|
9123
|
+
"pwsh",
|
|
9124
|
+
"env",
|
|
9125
|
+
"xargs",
|
|
9126
|
+
"command",
|
|
9127
|
+
"builtin",
|
|
9128
|
+
"noglob",
|
|
9129
|
+
"nice",
|
|
9130
|
+
"stdbuf",
|
|
9131
|
+
"nohup",
|
|
9132
|
+
"timeout",
|
|
9133
|
+
"time",
|
|
9134
|
+
"watch",
|
|
9135
|
+
"ionice",
|
|
9136
|
+
"chrt",
|
|
9137
|
+
"setsid",
|
|
9138
|
+
"taskset",
|
|
9139
|
+
"strace",
|
|
9140
|
+
"ltrace",
|
|
9141
|
+
"script",
|
|
9142
|
+
"flock",
|
|
9143
|
+
"unshare",
|
|
9144
|
+
"nsenter",
|
|
9145
|
+
"sudo",
|
|
9146
|
+
"doas",
|
|
9147
|
+
"pkexec",
|
|
9148
|
+
"su",
|
|
9149
|
+
"runuser"
|
|
9150
|
+
]);
|
|
9151
|
+
var SUBCOMMAND = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;
|
|
9152
|
+
var ASSIGNMENT = /^[A-Za-z_]\w*=/;
|
|
9153
|
+
var PLAIN_PROGRAM = /^[\w./+@:-]+$/;
|
|
9154
|
+
var NOT_EXACT = /[\n\r;&|<>`$()*?{}\\]/;
|
|
9155
|
+
function programName(word) {
|
|
9156
|
+
return word.slice(word.lastIndexOf("/") + 1);
|
|
9157
|
+
}
|
|
9158
|
+
__name(programName, "programName");
|
|
9159
|
+
function twoWordPrefix(command) {
|
|
9160
|
+
const words = command.trim().split(/\s+/).filter(Boolean);
|
|
9161
|
+
const [program, subcommand] = words;
|
|
9162
|
+
if (words.length < 2 || program === void 0 || subcommand === void 0) return void 0;
|
|
9163
|
+
if (ASSIGNMENT.test(program)) return void 0;
|
|
9164
|
+
if (!PLAIN_PROGRAM.test(program) || NO_PREFIX_PROGRAMS.has(programName(program))) return void 0;
|
|
9165
|
+
if (!SUBCOMMAND.test(subcommand)) return void 0;
|
|
9166
|
+
return `${program} ${subcommand}`;
|
|
9167
|
+
}
|
|
9168
|
+
__name(twoWordPrefix, "twoWordPrefix");
|
|
9169
|
+
function allowForCommand(tool, command) {
|
|
9170
|
+
if (NOT_EXACT.test(command)) return void 0;
|
|
9171
|
+
const prefix = programName(command.split(/\s+/)[0] ?? "") === "cd" ? void 0 : twoWordPrefix(command);
|
|
9172
|
+
if (prefix !== void 0) return { kind: "prefix", tool, prefix };
|
|
9173
|
+
return { kind: "command", tool, command };
|
|
9174
|
+
}
|
|
9175
|
+
__name(allowForCommand, "allowForCommand");
|
|
9176
|
+
function plainCommands(line) {
|
|
9177
|
+
const lexed = lexShellCommandLine(line, { dialect: "bash" });
|
|
9178
|
+
if (!lexed.complete || lexed.opaque || lexed.commands.length === 0) return void 0;
|
|
9179
|
+
if (lexed.redirections.length > 0 || lexed.compoundWords.length > 0) return void 0;
|
|
9180
|
+
const out = [];
|
|
9181
|
+
for (const command of lexed.commands) {
|
|
9182
|
+
if (command.origin !== "line" || command.redirections.length > 0) return void 0;
|
|
9183
|
+
const text = command.text.trim();
|
|
9184
|
+
if (text === "") return void 0;
|
|
9185
|
+
out.push(text);
|
|
9186
|
+
}
|
|
9187
|
+
return out;
|
|
9188
|
+
}
|
|
9189
|
+
__name(plainCommands, "plainCommands");
|
|
9190
|
+
function allowsFor(call, commands) {
|
|
8758
9191
|
if (alwaysAsked(call)) return void 0;
|
|
8759
|
-
const input =
|
|
9192
|
+
const input = isRecord3(call.input) ? call.input : void 0;
|
|
8760
9193
|
const commandArgument = commands.get(call.name);
|
|
8761
9194
|
if (commandArgument !== void 0) {
|
|
8762
9195
|
const line = input?.[commandArgument];
|
|
8763
9196
|
if (typeof line !== "string") return void 0;
|
|
8764
|
-
const command = line.trim();
|
|
8765
|
-
if (command === "" || /[\n\r;&|<>`$()*?{}\\]/.test(command)) return void 0;
|
|
8766
9197
|
if (input?.dangerously_disable_sandbox === true) return void 0;
|
|
8767
|
-
|
|
9198
|
+
if (line.trim() === "" || /[\n\r]/.test(line.trim())) return void 0;
|
|
9199
|
+
const parts = plainCommands(line);
|
|
9200
|
+
if (parts === void 0) return void 0;
|
|
9201
|
+
const out = [];
|
|
9202
|
+
for (const part of parts) {
|
|
9203
|
+
const allow = allowForCommand(call.name, part);
|
|
9204
|
+
if (allow === void 0) return void 0;
|
|
9205
|
+
if (!out.some((existing) => sameAllow(existing, allow))) out.push(allow);
|
|
9206
|
+
}
|
|
9207
|
+
return out.length > 0 && out.length <= MAX_RULES_PER_ANSWER ? out : void 0;
|
|
8768
9208
|
}
|
|
8769
9209
|
if (call.name === WEB_FETCH_TOOL) {
|
|
8770
9210
|
const url = input?.url;
|
|
@@ -8772,29 +9212,32 @@ function allowFor(call, commands) {
|
|
|
8772
9212
|
try {
|
|
8773
9213
|
const host = new URL(url).hostname;
|
|
8774
9214
|
if (host === "" || host.includes("*")) return void 0;
|
|
8775
|
-
return { kind: "host", tool: call.name, host };
|
|
9215
|
+
return [{ kind: "host", tool: call.name, host }];
|
|
8776
9216
|
} catch {
|
|
8777
9217
|
return void 0;
|
|
8778
9218
|
}
|
|
8779
9219
|
}
|
|
8780
|
-
if (call.name.startsWith("mcp__")) return { kind: "tool", tool: call.name };
|
|
9220
|
+
if (call.name.startsWith("mcp__")) return [{ kind: "tool", tool: call.name }];
|
|
8781
9221
|
return void 0;
|
|
8782
9222
|
}
|
|
8783
|
-
__name(
|
|
9223
|
+
__name(allowsFor, "allowsFor");
|
|
8784
9224
|
function allowsForBatch(calls, commands) {
|
|
8785
9225
|
if (calls.length === 0) return void 0;
|
|
8786
9226
|
const out = [];
|
|
8787
9227
|
for (const call of calls) {
|
|
8788
|
-
const
|
|
8789
|
-
if (!
|
|
8790
|
-
|
|
9228
|
+
const allows = allowsFor(call, commands);
|
|
9229
|
+
if (!allows) return void 0;
|
|
9230
|
+
for (const allow of allows) {
|
|
9231
|
+
if (!out.some((existing) => sameAllow(existing, allow))) out.push(allow);
|
|
9232
|
+
}
|
|
8791
9233
|
}
|
|
8792
|
-
return out;
|
|
9234
|
+
return out.length <= MAX_RULES_PER_ANSWER ? out : void 0;
|
|
8793
9235
|
}
|
|
8794
9236
|
__name(allowsForBatch, "allowsForBatch");
|
|
8795
9237
|
function sameAllow(a, b) {
|
|
8796
9238
|
if (a.kind !== b.kind || a.tool !== b.tool) return false;
|
|
8797
9239
|
if (a.kind === "command" && b.kind === "command") return a.command === b.command;
|
|
9240
|
+
if (a.kind === "prefix" && b.kind === "prefix") return a.prefix === b.prefix;
|
|
8798
9241
|
if (a.kind === "host" && b.kind === "host") return a.host === b.host;
|
|
8799
9242
|
return true;
|
|
8800
9243
|
}
|
|
@@ -8808,6 +9251,8 @@ function describeAllows(allows) {
|
|
|
8808
9251
|
switch (allow.kind) {
|
|
8809
9252
|
case "command":
|
|
8810
9253
|
return `${shorten(allow.command)} commands`;
|
|
9254
|
+
case "prefix":
|
|
9255
|
+
return `${shorten(allow.prefix)} * commands`;
|
|
8811
9256
|
case "host":
|
|
8812
9257
|
return allow.host;
|
|
8813
9258
|
case "tool":
|
|
@@ -8817,47 +9262,420 @@ function describeAllows(allows) {
|
|
|
8817
9262
|
return parts.length <= 1 ? parts[0] ?? "" : `${parts.slice(0, -1).join(", ")} and ${parts.at(-1)}`;
|
|
8818
9263
|
}
|
|
8819
9264
|
__name(describeAllows, "describeAllows");
|
|
8820
|
-
function
|
|
8821
|
-
|
|
8822
|
-
|
|
8823
|
-
|
|
8824
|
-
|
|
8825
|
-
|
|
8826
|
-
|
|
8827
|
-
|
|
8828
|
-
|
|
8829
|
-
|
|
8830
|
-
|
|
8831
|
-
|
|
8832
|
-
|
|
8833
|
-
|
|
8834
|
-
|
|
8835
|
-
|
|
8836
|
-
|
|
8837
|
-
|
|
8838
|
-
|
|
9265
|
+
function permissionsForAllows(allows) {
|
|
9266
|
+
const table = {};
|
|
9267
|
+
const pattern = /* @__PURE__ */ __name((tool, glob) => {
|
|
9268
|
+
const existing = table[tool];
|
|
9269
|
+
const patterns = typeof existing === "object" ? existing : {};
|
|
9270
|
+
patterns[glob] = "allow";
|
|
9271
|
+
table[tool] = patterns;
|
|
9272
|
+
}, "pattern");
|
|
9273
|
+
for (const allow of allows) {
|
|
9274
|
+
switch (allow.kind) {
|
|
9275
|
+
case "command":
|
|
9276
|
+
pattern(allow.tool, allow.command);
|
|
9277
|
+
break;
|
|
9278
|
+
case "prefix":
|
|
9279
|
+
pattern(allow.tool, `${allow.prefix} *`);
|
|
9280
|
+
break;
|
|
9281
|
+
case "host":
|
|
9282
|
+
pattern(allow.tool, `http://${allow.host}/*`);
|
|
9283
|
+
pattern(allow.tool, `https://${allow.host}/*`);
|
|
9284
|
+
break;
|
|
9285
|
+
case "tool":
|
|
9286
|
+
table[allow.tool] = "allow";
|
|
9287
|
+
break;
|
|
8839
9288
|
}
|
|
8840
9289
|
}
|
|
9290
|
+
return table;
|
|
8841
9291
|
}
|
|
8842
|
-
__name(
|
|
8843
|
-
function createSessionAllows(
|
|
9292
|
+
__name(permissionsForAllows, "permissionsForAllows");
|
|
9293
|
+
function createSessionAllows(_commands, options = {}) {
|
|
8844
9294
|
const entries = [];
|
|
9295
|
+
let gate;
|
|
9296
|
+
const rebuild = /* @__PURE__ */ __name(() => {
|
|
9297
|
+
const { rules } = compilePermissions(permissionsForAllows(entries));
|
|
9298
|
+
gate = rules.length === 0 ? void 0 : new AuthorizationGate(
|
|
9299
|
+
{
|
|
9300
|
+
enabled: true,
|
|
9301
|
+
rules: [...rules],
|
|
9302
|
+
allowReadOnlyTools: false,
|
|
9303
|
+
denyDangerousPatterns: false,
|
|
9304
|
+
logDecisions: false
|
|
9305
|
+
},
|
|
9306
|
+
NOOP_LOGGER
|
|
9307
|
+
);
|
|
9308
|
+
}, "rebuild");
|
|
9309
|
+
const allowed = /* @__PURE__ */ __name((call) => {
|
|
9310
|
+
if (isRecord3(call.toolInput) && call.toolInput.dangerously_disable_sandbox === true)
|
|
9311
|
+
return false;
|
|
9312
|
+
const result = gate?.evaluate(call);
|
|
9313
|
+
return result !== void 0 && result.matchedRule !== null && result.decision === "allow";
|
|
9314
|
+
}, "allowed");
|
|
8845
9315
|
return {
|
|
8846
9316
|
add(allows) {
|
|
8847
|
-
|
|
8848
|
-
|
|
9317
|
+
const fresh = allows.filter(
|
|
9318
|
+
(allow) => !entries.some((existing) => sameAllow(existing, allow))
|
|
9319
|
+
);
|
|
9320
|
+
entries.push(...fresh);
|
|
9321
|
+
if (fresh.length > 0) rebuild();
|
|
9322
|
+
const cwd = typeof options.cwd === "function" ? options.cwd() : options.cwd;
|
|
9323
|
+
if (cwd === void 0) return void 0;
|
|
9324
|
+
const write = (options.persist ?? writeLocalAllows)(cwd, permissionsForAllows(allows));
|
|
9325
|
+
if (write.error !== void 0) {
|
|
9326
|
+
cliLogger().warn("Could not save a remembered answer", {
|
|
9327
|
+
"namzu.config.local.path": write.path,
|
|
9328
|
+
"namzu.config.local.error": write.error
|
|
9329
|
+
});
|
|
9330
|
+
return `Could not save this answer to ${LOCAL_CONFIG_FILE}: ${write.error}. It holds for this session only.`;
|
|
8849
9331
|
}
|
|
9332
|
+
void (options.keepIgnored ?? ensureLocalConfigIgnored)(cwd).then(logIgnoreOutcome);
|
|
9333
|
+
return void 0;
|
|
8850
9334
|
},
|
|
8851
9335
|
list: /* @__PURE__ */ __name(() => [...entries], "list"),
|
|
8852
9336
|
rule: {
|
|
8853
9337
|
type: "predicate",
|
|
8854
|
-
description: "allowed
|
|
8855
|
-
decide: /* @__PURE__ */ __name((call) =>
|
|
9338
|
+
description: "allowed by an answer at a prompt",
|
|
9339
|
+
decide: /* @__PURE__ */ __name((call) => allowed(call) ? "allow" : null, "decide")
|
|
8856
9340
|
}
|
|
8857
9341
|
};
|
|
8858
9342
|
}
|
|
8859
9343
|
__name(createSessionAllows, "createSessionAllows");
|
|
8860
9344
|
|
|
9345
|
+
// src/plan/approval.ts
|
|
9346
|
+
var KEEP_PLANNING_PLACEHOLDER = "Tell namzu what to change";
|
|
9347
|
+
function planApprovalRows(bypassAvailable) {
|
|
9348
|
+
return [
|
|
9349
|
+
bypassAvailable ? {
|
|
9350
|
+
id: "approve-auto",
|
|
9351
|
+
label: "Yes, and approve every tool without asking",
|
|
9352
|
+
mode: "auto"
|
|
9353
|
+
} : {
|
|
9354
|
+
id: "approve-accept-edits",
|
|
9355
|
+
label: "Yes, and auto-approve edits",
|
|
9356
|
+
mode: "accept-edits"
|
|
9357
|
+
},
|
|
9358
|
+
{
|
|
9359
|
+
id: "approve-ask",
|
|
9360
|
+
label: "Yes, and ask before each edit",
|
|
9361
|
+
mode: "prompt"
|
|
9362
|
+
},
|
|
9363
|
+
{ id: "keep-planning", label: "No, keep planning" }
|
|
9364
|
+
];
|
|
9365
|
+
}
|
|
9366
|
+
__name(planApprovalRows, "planApprovalRows");
|
|
9367
|
+
var EXIT_PLAN_MODE_TOOL_NAME = "exit_plan_mode";
|
|
9368
|
+
|
|
9369
|
+
// src/plan/plan-file.ts
|
|
9370
|
+
import { readFile as readFile6 } from "node:fs/promises";
|
|
9371
|
+
import { isAbsolute as isAbsolute7, resolve as resolve9 } from "node:path";
|
|
9372
|
+
var WRITERS = /* @__PURE__ */ new Set(["write", "edit"]);
|
|
9373
|
+
function isPlanFileWrite(planPath, cwd) {
|
|
9374
|
+
const target = resolve9(planPath);
|
|
9375
|
+
return (call) => {
|
|
9376
|
+
if (!WRITERS.has(call.name)) return false;
|
|
9377
|
+
const input = call.input;
|
|
9378
|
+
if (input === null || typeof input !== "object") return false;
|
|
9379
|
+
const path = input.path;
|
|
9380
|
+
if (typeof path !== "string" || path.length === 0 || path.includes("\0")) return false;
|
|
9381
|
+
return resolve9(isAbsolute7(path) ? path : resolve9(cwd, path)) === target;
|
|
9382
|
+
};
|
|
9383
|
+
}
|
|
9384
|
+
__name(isPlanFileWrite, "isPlanFileWrite");
|
|
9385
|
+
async function readPlan(planPath) {
|
|
9386
|
+
try {
|
|
9387
|
+
const text = await readFile6(planPath, "utf8");
|
|
9388
|
+
return text.trim().length > 0 ? text : void 0;
|
|
9389
|
+
} catch {
|
|
9390
|
+
return void 0;
|
|
9391
|
+
}
|
|
9392
|
+
}
|
|
9393
|
+
__name(readPlan, "readPlan");
|
|
9394
|
+
|
|
9395
|
+
// src/plan/exit-plan-mode-tool.ts
|
|
9396
|
+
function approvedPlanText(plan, planPath, answer) {
|
|
9397
|
+
return [
|
|
9398
|
+
`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.`,
|
|
9399
|
+
"",
|
|
9400
|
+
`The plan is saved at ${planPath} if you need to refer back to it.`,
|
|
9401
|
+
...answer.feedback ? ["", `The user added: ${answer.feedback}`] : [],
|
|
9402
|
+
"",
|
|
9403
|
+
"## Approved plan",
|
|
9404
|
+
plan
|
|
9405
|
+
].join("\n");
|
|
9406
|
+
}
|
|
9407
|
+
__name(approvedPlanText, "approvedPlanText");
|
|
9408
|
+
function buildExitPlanModeTool(host) {
|
|
9409
|
+
return defineTool({
|
|
9410
|
+
name: EXIT_PLAN_MODE_TOOL_NAME,
|
|
9411
|
+
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.",
|
|
9412
|
+
inputSchema: mcpJsonSchemaToZod({
|
|
9413
|
+
type: "object",
|
|
9414
|
+
properties: {},
|
|
9415
|
+
additionalProperties: false
|
|
9416
|
+
}),
|
|
9417
|
+
category: "custom",
|
|
9418
|
+
permissions: [],
|
|
9419
|
+
// Asks the person, changes nothing itself: the mode switch is theirs.
|
|
9420
|
+
readOnly: true,
|
|
9421
|
+
destructive: false,
|
|
9422
|
+
concurrencySafe: false,
|
|
9423
|
+
// A person reads a whole plan before answering.
|
|
9424
|
+
timeoutMs: 30 * 6e4,
|
|
9425
|
+
presentCall: /* @__PURE__ */ __name(() => ({
|
|
9426
|
+
kind: "generic",
|
|
9427
|
+
label: "Present plan for approval",
|
|
9428
|
+
presentation: "activity"
|
|
9429
|
+
}), "presentCall"),
|
|
9430
|
+
// The transcript already shows the approved plan (the host writes it when the
|
|
9431
|
+
// person approves); the tool's own result is for the model.
|
|
9432
|
+
presentResult: /* @__PURE__ */ __name((_input, result) => {
|
|
9433
|
+
if (result.success)
|
|
9434
|
+
return {
|
|
9435
|
+
kind: "generic",
|
|
9436
|
+
label: "Plan approved",
|
|
9437
|
+
visibility: "hidden"
|
|
9438
|
+
};
|
|
9439
|
+
const outcome = result.data?.outcome;
|
|
9440
|
+
return outcome === "keep-planning" ? { kind: "generic", label: "Kept planning", outcome: "cancelled" } : void 0;
|
|
9441
|
+
}, "presentResult"),
|
|
9442
|
+
async execute(_input, context) {
|
|
9443
|
+
context.abortSignal?.throwIfAborted();
|
|
9444
|
+
if (host.mode() !== "plan") {
|
|
9445
|
+
return {
|
|
9446
|
+
success: false,
|
|
9447
|
+
output: "",
|
|
9448
|
+
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."
|
|
9449
|
+
};
|
|
9450
|
+
}
|
|
9451
|
+
const planPath = host.planPath();
|
|
9452
|
+
const plan = await readPlan(planPath);
|
|
9453
|
+
if (plan === void 0) {
|
|
9454
|
+
return {
|
|
9455
|
+
success: false,
|
|
9456
|
+
output: "",
|
|
9457
|
+
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}.`
|
|
9458
|
+
};
|
|
9459
|
+
}
|
|
9460
|
+
const ask = host.approval();
|
|
9461
|
+
if (!ask) {
|
|
9462
|
+
return {
|
|
9463
|
+
success: false,
|
|
9464
|
+
output: "",
|
|
9465
|
+
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."
|
|
9466
|
+
};
|
|
9467
|
+
}
|
|
9468
|
+
let answer;
|
|
9469
|
+
try {
|
|
9470
|
+
answer = await ask(
|
|
9471
|
+
{ plan, planPath, bypassAvailable: host.bypassAvailable() },
|
|
9472
|
+
context.abortSignal
|
|
9473
|
+
);
|
|
9474
|
+
} catch {
|
|
9475
|
+
answer = { kind: "keep-planning" };
|
|
9476
|
+
}
|
|
9477
|
+
context.abortSignal?.throwIfAborted();
|
|
9478
|
+
if (answer.kind === "approve") {
|
|
9479
|
+
return {
|
|
9480
|
+
success: true,
|
|
9481
|
+
output: approvedPlanText(plan, planPath, answer),
|
|
9482
|
+
data: { outcome: "approved", mode: answer.mode }
|
|
9483
|
+
};
|
|
9484
|
+
}
|
|
9485
|
+
return {
|
|
9486
|
+
success: false,
|
|
9487
|
+
output: "",
|
|
9488
|
+
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.",
|
|
9489
|
+
data: { outcome: "keep-planning" }
|
|
9490
|
+
};
|
|
9491
|
+
}
|
|
9492
|
+
});
|
|
9493
|
+
}
|
|
9494
|
+
__name(buildExitPlanModeTool, "buildExitPlanModeTool");
|
|
9495
|
+
|
|
9496
|
+
// src/provider-retry.ts
|
|
9497
|
+
var TERMINAL_PROVIDER_RETRY = {
|
|
9498
|
+
maxRetries: 10,
|
|
9499
|
+
initialDelayMs: 500,
|
|
9500
|
+
maxDelayMs: 32e3,
|
|
9501
|
+
maxRetryAfterMs: 6e4,
|
|
9502
|
+
jitter: "proportional",
|
|
9503
|
+
retryAfter: "floor"
|
|
9504
|
+
};
|
|
9505
|
+
function terminalProviderRetry(restartableOutput) {
|
|
9506
|
+
return restartableOutput ? { ...TERMINAL_PROVIDER_RETRY, retryMidStream: true } : TERMINAL_PROVIDER_RETRY;
|
|
9507
|
+
}
|
|
9508
|
+
__name(terminalProviderRetry, "terminalProviderRetry");
|
|
9509
|
+
|
|
9510
|
+
// src/reminders/index.ts
|
|
9511
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
9512
|
+
|
|
9513
|
+
// src/reminders/frame.ts
|
|
9514
|
+
var TAG = /^<system-reminder kind="([a-z-]+)"(?: form="([a-z]+)")?>/;
|
|
9515
|
+
function frameReminder(kind, text, form) {
|
|
9516
|
+
const open3 = form ? `<system-reminder kind="${kind}" form="${form}">` : `<system-reminder kind="${kind}">`;
|
|
9517
|
+
return `${open3}
|
|
9518
|
+
${text.trim()}
|
|
9519
|
+
</system-reminder>`;
|
|
9520
|
+
}
|
|
9521
|
+
__name(frameReminder, "frameReminder");
|
|
9522
|
+
function reminderKindOf(message2) {
|
|
9523
|
+
if (!isReminderMessage(message2) || typeof message2.content !== "string") return void 0;
|
|
9524
|
+
const kind = TAG.exec(message2.content)?.[1];
|
|
9525
|
+
return kind === "plan-mode" || kind === "plan-reentry" || kind === "plan-exit" || kind === "task-nudge" ? kind : void 0;
|
|
9526
|
+
}
|
|
9527
|
+
__name(reminderKindOf, "reminderKindOf");
|
|
9528
|
+
function isOperatorTurn(message2) {
|
|
9529
|
+
if (message2.role !== "user") return false;
|
|
9530
|
+
const source = message2.source;
|
|
9531
|
+
return source === void 0 || source.type === "goal-round" || source.type === "runtime-context" && source.kind === "steering";
|
|
9532
|
+
}
|
|
9533
|
+
__name(isOperatorTurn, "isOperatorTurn");
|
|
9534
|
+
|
|
9535
|
+
// src/reminders/plan-mode.ts
|
|
9536
|
+
var PLAN_REMINDER_EVERY_N_TURNS = 5;
|
|
9537
|
+
var PLAN_REMINDER_FULL_EVERY_N = 5;
|
|
9538
|
+
function scan(messages) {
|
|
9539
|
+
let turns = 0;
|
|
9540
|
+
let hasReminder = false;
|
|
9541
|
+
let sent = 0;
|
|
9542
|
+
let hasExited = false;
|
|
9543
|
+
let inStretch = true;
|
|
9544
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
9545
|
+
const message2 = messages[i];
|
|
9546
|
+
const kind = reminderKindOf(message2);
|
|
9547
|
+
if (kind === "plan-exit") {
|
|
9548
|
+
hasExited = true;
|
|
9549
|
+
if (!hasReminder) inStretch = false;
|
|
9550
|
+
break;
|
|
9551
|
+
}
|
|
9552
|
+
if (kind === "plan-mode" || kind === "plan-reentry") {
|
|
9553
|
+
if (inStretch) hasReminder = true;
|
|
9554
|
+
if (kind === "plan-mode") sent++;
|
|
9555
|
+
continue;
|
|
9556
|
+
}
|
|
9557
|
+
if (!hasReminder && isOperatorTurn(message2)) turns++;
|
|
9558
|
+
}
|
|
9559
|
+
return { turnsSinceReminder: turns, hasReminder, sent, hasExited };
|
|
9560
|
+
}
|
|
9561
|
+
__name(scan, "scan");
|
|
9562
|
+
function fullText(input) {
|
|
9563
|
+
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.`;
|
|
9564
|
+
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.";
|
|
9565
|
+
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.
|
|
9566
|
+
|
|
9567
|
+
${file} It is the only file you may write; build the plan up in it as you learn.
|
|
9568
|
+
|
|
9569
|
+
How to plan:
|
|
9570
|
+
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.
|
|
9571
|
+
2. Decide on one approach. Weigh alternatives briefly and keep only the one you recommend.
|
|
9572
|
+
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.
|
|
9573
|
+
4. Finish. ${ending} Never ask for approval in plain text ("does this look right?"); exit_plan_mode is how the user is asked.`;
|
|
9574
|
+
}
|
|
9575
|
+
__name(fullText, "fullText");
|
|
9576
|
+
function sparseText(input) {
|
|
9577
|
+
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.`;
|
|
9578
|
+
}
|
|
9579
|
+
__name(sparseText, "sparseText");
|
|
9580
|
+
function reentryText(input) {
|
|
9581
|
+
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.`;
|
|
9582
|
+
}
|
|
9583
|
+
__name(reentryText, "reentryText");
|
|
9584
|
+
function exitText(input) {
|
|
9585
|
+
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.` : ""}`;
|
|
9586
|
+
}
|
|
9587
|
+
__name(exitText, "exitText");
|
|
9588
|
+
function planModeReminders(input) {
|
|
9589
|
+
const stretch = scan(input.messages);
|
|
9590
|
+
if (input.mode !== "plan") {
|
|
9591
|
+
return stretch.hasReminder ? [frameReminder("plan-exit", exitText(input))] : [];
|
|
9592
|
+
}
|
|
9593
|
+
if (stretch.hasReminder && stretch.turnsSinceReminder < PLAN_REMINDER_EVERY_N_TURNS) return [];
|
|
9594
|
+
const full = (stretch.sent + 1) % PLAN_REMINDER_FULL_EVERY_N === 1;
|
|
9595
|
+
const out = [
|
|
9596
|
+
frameReminder(
|
|
9597
|
+
"plan-mode",
|
|
9598
|
+
full ? fullText(input) : sparseText(input),
|
|
9599
|
+
full ? "full" : "sparse"
|
|
9600
|
+
)
|
|
9601
|
+
];
|
|
9602
|
+
if (!stretch.hasReminder && stretch.hasExited && input.planExists) {
|
|
9603
|
+
out.push(frameReminder("plan-reentry", reentryText(input)));
|
|
9604
|
+
}
|
|
9605
|
+
return out;
|
|
9606
|
+
}
|
|
9607
|
+
__name(planModeReminders, "planModeReminders");
|
|
9608
|
+
|
|
9609
|
+
// src/reminders/task-nudge.ts
|
|
9610
|
+
var TASK_NUDGE_AFTER_TURNS = 10;
|
|
9611
|
+
var TASK_NUDGE_EVERY_TURNS = 10;
|
|
9612
|
+
var TASK_TOOLS = /* @__PURE__ */ new Set(["task_create", "task_update"]);
|
|
9613
|
+
function taskNudgeCounts(messages) {
|
|
9614
|
+
let sinceTaskTool = 0;
|
|
9615
|
+
let sinceNudge = 0;
|
|
9616
|
+
let sawTool = false;
|
|
9617
|
+
let sawNudge = false;
|
|
9618
|
+
for (let i = messages.length - 1; i >= 0 && !(sawTool && sawNudge); i--) {
|
|
9619
|
+
const message2 = messages[i];
|
|
9620
|
+
if (message2.role === "assistant") {
|
|
9621
|
+
if (!sawTool && message2.toolCalls?.some((call) => TASK_TOOLS.has(call.function.name))) {
|
|
9622
|
+
sawTool = true;
|
|
9623
|
+
}
|
|
9624
|
+
if (!sawTool) sinceTaskTool++;
|
|
9625
|
+
if (!sawNudge) sinceNudge++;
|
|
9626
|
+
} else if (!sawNudge && reminderKindOf(message2) === "task-nudge") {
|
|
9627
|
+
sawNudge = true;
|
|
9628
|
+
}
|
|
9629
|
+
}
|
|
9630
|
+
return { sinceTaskTool, sinceNudge };
|
|
9631
|
+
}
|
|
9632
|
+
__name(taskNudgeCounts, "taskNudgeCounts");
|
|
9633
|
+
function listText(tasks) {
|
|
9634
|
+
return tasks.map((task) => `#${task.id}. [${task.status}] ${task.subject}`).join("\n");
|
|
9635
|
+
}
|
|
9636
|
+
__name(listText, "listText");
|
|
9637
|
+
function taskNudge(messages, tasks) {
|
|
9638
|
+
if (messages.length === 0) return [];
|
|
9639
|
+
const { sinceTaskTool, sinceNudge } = taskNudgeCounts(messages);
|
|
9640
|
+
if (sinceTaskTool < TASK_NUDGE_AFTER_TURNS || sinceNudge < TASK_NUDGE_EVERY_TURNS) return [];
|
|
9641
|
+
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.";
|
|
9642
|
+
return [
|
|
9643
|
+
frameReminder(
|
|
9644
|
+
"task-nudge",
|
|
9645
|
+
tasks.length > 0 ? `${head}
|
|
9646
|
+
|
|
9647
|
+
The task list now:
|
|
9648
|
+
${listText(tasks)}` : head
|
|
9649
|
+
)
|
|
9650
|
+
];
|
|
9651
|
+
}
|
|
9652
|
+
__name(taskNudge, "taskNudge");
|
|
9653
|
+
|
|
9654
|
+
// src/reminders/index.ts
|
|
9655
|
+
function createCliReminderSource(options) {
|
|
9656
|
+
return async ({ messages }) => {
|
|
9657
|
+
const out = [];
|
|
9658
|
+
if (options.planPath) {
|
|
9659
|
+
const planPath = options.planPath();
|
|
9660
|
+
out.push(
|
|
9661
|
+
...planModeReminders({
|
|
9662
|
+
messages,
|
|
9663
|
+
mode: options.mode(),
|
|
9664
|
+
planPath,
|
|
9665
|
+
planExists: (options.planExists ?? existsSync2)(planPath),
|
|
9666
|
+
canAsk: options.canAsk === true
|
|
9667
|
+
})
|
|
9668
|
+
);
|
|
9669
|
+
}
|
|
9670
|
+
if (options.tasks) {
|
|
9671
|
+
const nudge = taskNudge(messages, []);
|
|
9672
|
+
if (nudge.length > 0) out.push(...taskNudge(messages, await options.tasks()));
|
|
9673
|
+
}
|
|
9674
|
+
return out;
|
|
9675
|
+
};
|
|
9676
|
+
}
|
|
9677
|
+
__name(createCliReminderSource, "createCliReminderSource");
|
|
9678
|
+
|
|
8861
9679
|
// src/skills/directory.ts
|
|
8862
9680
|
function createSkillDirectoryResolver(options) {
|
|
8863
9681
|
return async (skill, context) => {
|
|
@@ -9007,24 +9825,24 @@ async function resolveModelSwitch(request, options) {
|
|
|
9007
9825
|
listed.set(detected.entry.id, listing);
|
|
9008
9826
|
return listing.kind === "ok" && listing.models.some((candidate) => candidate.id === model);
|
|
9009
9827
|
}, "inspect");
|
|
9010
|
-
const
|
|
9828
|
+
const resolve11 = /* @__PURE__ */ __name((detected) => ({
|
|
9011
9829
|
kind: "resolved",
|
|
9012
9830
|
selection: { id: detected.entry.id, model }
|
|
9013
9831
|
}), "resolve");
|
|
9014
9832
|
const first = selected ?? usable.find(({ entry }) => entry.id === options.currentProvider);
|
|
9015
|
-
if (first && await inspect(first)) return
|
|
9833
|
+
if (first && await inspect(first)) return resolve11(first);
|
|
9016
9834
|
const candidates = selected ? [selected] : usable;
|
|
9017
|
-
const
|
|
9835
|
+
const matches = selected ? [] : (await Promise.all(
|
|
9018
9836
|
candidates.filter((candidate) => candidate !== first).map(async (candidate) => await inspect(candidate) ? candidate : void 0)
|
|
9019
9837
|
)).filter((candidate) => candidate !== void 0);
|
|
9020
9838
|
signal?.throwIfAborted();
|
|
9021
|
-
const uniqueMatch =
|
|
9022
|
-
if (uniqueMatch) return
|
|
9023
|
-
if (
|
|
9839
|
+
const uniqueMatch = matches.length === 1 ? matches[0] : void 0;
|
|
9840
|
+
if (uniqueMatch) return resolve11(uniqueMatch);
|
|
9841
|
+
if (matches.length > 1) {
|
|
9024
9842
|
return {
|
|
9025
9843
|
kind: "rejected",
|
|
9026
|
-
reason: `Model "${model}" is available from multiple providers. Specify one: ${
|
|
9027
|
-
choices:
|
|
9844
|
+
reason: `Model "${model}" is available from multiple providers. Specify one: ${matches.map(({ entry }) => entry.id).join(", ")}.`,
|
|
9845
|
+
choices: matches.map(({ entry }) => ({ provider: entry.id, model }))
|
|
9028
9846
|
};
|
|
9029
9847
|
}
|
|
9030
9848
|
const choices = candidates.flatMap((candidate) => {
|
|
@@ -9095,6 +9913,8 @@ function createCliToolPresenter(registry) {
|
|
|
9095
9913
|
__name(createCliToolPresenter, "createCliToolPresenter");
|
|
9096
9914
|
|
|
9097
9915
|
// src/tui/agent.ts
|
|
9916
|
+
var WEB_FETCH_MAX_BYTES = 10 * 1024 * 1024;
|
|
9917
|
+
var WEB_EXTRACT_MAX_TOKENS = 8192;
|
|
9098
9918
|
async function observeWithSignal(operation, signal) {
|
|
9099
9919
|
signal.throwIfAborted();
|
|
9100
9920
|
let rejectAbort = /* @__PURE__ */ __name(() => {
|
|
@@ -9173,8 +9993,8 @@ var SessionOperationOwner = class {
|
|
|
9173
9993
|
})()[Symbol.asyncIterator]();
|
|
9174
9994
|
let settled = false;
|
|
9175
9995
|
let settle;
|
|
9176
|
-
const settlement = new Promise((
|
|
9177
|
-
settle =
|
|
9996
|
+
const settlement = new Promise((resolve11) => {
|
|
9997
|
+
settle = resolve11;
|
|
9178
9998
|
});
|
|
9179
9999
|
let operationTail = Promise.resolve();
|
|
9180
10000
|
let returnStarted = false;
|
|
@@ -9443,14 +10263,14 @@ function clipRequestContext(prompt, limit, kind) {
|
|
|
9443
10263
|
__name(clipRequestContext, "clipRequestContext");
|
|
9444
10264
|
async function createAgentSession(prefs, detected, options = {}) {
|
|
9445
10265
|
if (options.palEnvironment) {
|
|
9446
|
-
const { createPalAgentSession } = await import("./agent-session-
|
|
10266
|
+
const { createPalAgentSession } = await import("./agent-session-2YMHOAKF.js");
|
|
9447
10267
|
return createPalAgentSession(prefs, detected, options);
|
|
9448
10268
|
}
|
|
9449
|
-
const { palAtWorkspace } = await import("./store-
|
|
10269
|
+
const { palAtWorkspace } = await import("./store-YWZ6SY2M.js");
|
|
9450
10270
|
if (palAtWorkspace(options.cwd ?? process.cwd()))
|
|
9451
10271
|
throw new Error("This Pal requires its owned virtual computer. Open it with namzu pal chat.");
|
|
9452
10272
|
const commandArguments = builtinCommandArguments();
|
|
9453
|
-
const sessionAllows = createSessionAllows(commandArguments);
|
|
10273
|
+
const sessionAllows = createSessionAllows(commandArguments, { cwd: /* @__PURE__ */ __name(() => cwd, "cwd") });
|
|
9454
10274
|
const sessionRules = [...options.rules ?? [], sessionAllows.rule];
|
|
9455
10275
|
const fileObservations = /* @__PURE__ */ new Map();
|
|
9456
10276
|
const observationsFor = /* @__PURE__ */ __name((id, prior) => {
|
|
@@ -9480,7 +10300,7 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
9480
10300
|
}
|
|
9481
10301
|
return seeded;
|
|
9482
10302
|
}, "observationsFor");
|
|
9483
|
-
const requestedCwd =
|
|
10303
|
+
const requestedCwd = resolve10(options.cwd ?? process.cwd());
|
|
9484
10304
|
let cwd;
|
|
9485
10305
|
try {
|
|
9486
10306
|
const entry2 = await stat4(requestedCwd);
|
|
@@ -9512,13 +10332,13 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
9512
10332
|
paths = options.conversationSessions.paths;
|
|
9513
10333
|
projectId = options.conversationSessions.projectId;
|
|
9514
10334
|
} else {
|
|
9515
|
-
const home =
|
|
10335
|
+
const home = resolve10(options.stateRoot ?? resolveNamzuHome());
|
|
9516
10336
|
ensurePrivateStateDirectory(home, "projects");
|
|
9517
10337
|
const project = await ensureProject({ home, cwd: cliProjectRoot(cwd) });
|
|
9518
10338
|
paths = new SessionPaths({ home, slug: project.slug });
|
|
9519
10339
|
projectId = project.projectId;
|
|
9520
10340
|
}
|
|
9521
|
-
ensurePrivateStateDirectory(
|
|
10341
|
+
ensurePrivateStateDirectory(resolve10(paths.projectDir(), ".."), paths.slug);
|
|
9522
10342
|
ensurePrivateStateDirectory(paths.projectDir(), "memory");
|
|
9523
10343
|
} catch (error) {
|
|
9524
10344
|
return emptySession(
|
|
@@ -9787,8 +10607,8 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
9787
10607
|
const ownedJobs = jobRegistry ? bindOwner(jobRegistry, jobOwner) : void 0;
|
|
9788
10608
|
const directories = [];
|
|
9789
10609
|
for (const dir of options.additionalDirectories ?? []) {
|
|
9790
|
-
const absolute =
|
|
9791
|
-
if (absolute !==
|
|
10610
|
+
const absolute = resolve10(cwd, dir);
|
|
10611
|
+
if (absolute !== resolve10(cwd) && !directories.includes(absolute)) directories.push(absolute);
|
|
9792
10612
|
}
|
|
9793
10613
|
const sessionDirectories = createSessionDirectories(cwd, directories);
|
|
9794
10614
|
const checkpoints = new FileCheckpointStore(
|
|
@@ -9988,7 +10808,26 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
9988
10808
|
webSearchTool = createWebSearchTool();
|
|
9989
10809
|
toolsets.push(toolset("web-search", [webSearchTool]));
|
|
9990
10810
|
}
|
|
9991
|
-
|
|
10811
|
+
let sideModel;
|
|
10812
|
+
const webCapability = options.web?.fetch ? {
|
|
10813
|
+
// A page may be ten mebibytes, as in the reference; the guard's own
|
|
10814
|
+
// default is two.
|
|
10815
|
+
fetch: new GuardedFetchProvider({ maxBytes: WEB_FETCH_MAX_BYTES }),
|
|
10816
|
+
// The answer to a prompt about a page comes from the small model. It is
|
|
10817
|
+
// read at call time: the model exists once the delegation runtime does,
|
|
10818
|
+
// and a page fetched without one is returned as markdown instead.
|
|
10819
|
+
extract: {
|
|
10820
|
+
extract: /* @__PURE__ */ __name(async (request) => sideModel?.ask({
|
|
10821
|
+
sessionId: request.sessionId,
|
|
10822
|
+
turnId: request.turnId,
|
|
10823
|
+
instruction: request.instruction,
|
|
10824
|
+
body: request.body,
|
|
10825
|
+
maxTokens: WEB_EXTRACT_MAX_TOKENS,
|
|
10826
|
+
signal: request.signal ?? new AbortController().signal,
|
|
10827
|
+
timing: "in-turn"
|
|
10828
|
+
}), "extract")
|
|
10829
|
+
}
|
|
10830
|
+
} : void 0;
|
|
9992
10831
|
if (webCapability) toolsets.push(toolset("web-fetch", [WebFetchTool]));
|
|
9993
10832
|
const delegationScopes = /* @__PURE__ */ new Map();
|
|
9994
10833
|
const delegationLimits = /* @__PURE__ */ new Map();
|
|
@@ -10072,6 +10911,18 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
10072
10911
|
)
|
|
10073
10912
|
] : [], "savedAgentsSteps");
|
|
10074
10913
|
const directChildReports = /* @__PURE__ */ new Set();
|
|
10914
|
+
const providerForModel = /* @__PURE__ */ __name(async (invokingSessionId, providerId, selectedModel) => {
|
|
10915
|
+
if (!invokingSessionId && (providerId === "zen" || providerId === "zen-go"))
|
|
10916
|
+
throw new Error("A delegated provider requires its invoking conversation.");
|
|
10917
|
+
await ensureRegistered(providerId);
|
|
10918
|
+
const credential = await currentCredentialFor(providerId);
|
|
10919
|
+
return constructProvider(
|
|
10920
|
+
providerId,
|
|
10921
|
+
providerId === primary.id && credential ? { ...credential, apiKey: currentToken ?? credential.apiKey } : credential,
|
|
10922
|
+
selectedModel,
|
|
10923
|
+
{ sessionId: invokingSessionId }
|
|
10924
|
+
);
|
|
10925
|
+
}, "providerForModel");
|
|
10075
10926
|
let subagentRuntime;
|
|
10076
10927
|
let allowedAgentIds = [];
|
|
10077
10928
|
try {
|
|
@@ -10186,26 +11037,17 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
10186
11037
|
}
|
|
10187
11038
|
})
|
|
10188
11039
|
);
|
|
10189
|
-
const
|
|
11040
|
+
const matches = catalogues.flat();
|
|
10190
11041
|
return JSON.stringify({
|
|
10191
|
-
models:
|
|
10192
|
-
omitted: Math.max(0,
|
|
11042
|
+
models: matches.slice(0, 40),
|
|
11043
|
+
omitted: Math.max(0, matches.length - 40),
|
|
10193
11044
|
guidance: "Use exact IDs. Omitted capability fields are unknown, not unsupported. Narrow query when results are omitted."
|
|
10194
11045
|
});
|
|
10195
11046
|
}, "listModels"),
|
|
10196
11047
|
buildProvider: /* @__PURE__ */ __name(async (invokingSessionId, selection) => {
|
|
10197
11048
|
const providerId = selection ? selection.provider : turnRouteTarget?.provider ?? primary.id;
|
|
10198
11049
|
const selectedModel = selection?.model ?? turnRouteTarget?.model ?? model;
|
|
10199
|
-
|
|
10200
|
-
throw new Error("A delegated provider requires its invoking conversation.");
|
|
10201
|
-
await ensureRegistered(providerId);
|
|
10202
|
-
const credential = await currentCredentialFor(providerId);
|
|
10203
|
-
const childProvider = constructProvider(
|
|
10204
|
-
providerId,
|
|
10205
|
-
providerId === primary.id && credential ? { ...credential, apiKey: currentToken ?? credential.apiKey } : credential,
|
|
10206
|
-
selectedModel,
|
|
10207
|
-
{ sessionId: invokingSessionId }
|
|
10208
|
-
);
|
|
11050
|
+
const childProvider = await providerForModel(invokingSessionId, providerId, selectedModel);
|
|
10209
11051
|
if (selection?.effort) await prepareDelegatedEffort(childProvider, selectedModel);
|
|
10210
11052
|
return childProvider;
|
|
10211
11053
|
}, "buildProvider"),
|
|
@@ -10228,6 +11070,21 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
10228
11070
|
authorizationGate: gateFor(sessionRules)
|
|
10229
11071
|
});
|
|
10230
11072
|
subagentRuntime = sub;
|
|
11073
|
+
sideModel = createSideModel({
|
|
11074
|
+
active: /* @__PURE__ */ __name(() => ({
|
|
11075
|
+
providerId: turnRouteTarget?.provider ?? primary.id,
|
|
11076
|
+
model: turnRouteTarget?.model ?? model
|
|
11077
|
+
}), "active"),
|
|
11078
|
+
configured: options.smallModel,
|
|
11079
|
+
isKnownProvider: /* @__PURE__ */ __name((id) => findDetected(detected, id) != null, "isKnownProvider"),
|
|
11080
|
+
buildProvider: /* @__PURE__ */ __name((sessionId, target) => providerForModel(sessionId, target.providerId, target.model), "buildProvider"),
|
|
11081
|
+
offerable: /* @__PURE__ */ __name((providerId, listed) => {
|
|
11082
|
+
const found = findDetected(detected, providerId);
|
|
11083
|
+
return found != null && canSelectModel(found.entry, found.apiKey, listed.id) && isOfferableModel(providerId, listed.id);
|
|
11084
|
+
}, "offerable"),
|
|
11085
|
+
ledger: sub.sideLedger,
|
|
11086
|
+
debug: /* @__PURE__ */ __name((message2, error) => cliLogger().debug(message2, exceptionAttributes(error)), "debug")
|
|
11087
|
+
});
|
|
10231
11088
|
const agentToolsets = [toolset("agents", [sub.agentTool, sub.waitForTaskTool])];
|
|
10232
11089
|
if (sub.modelCatalogueTool)
|
|
10233
11090
|
agentToolsets.push(toolset("agents:model-catalogue", [sub.modelCatalogueTool]));
|
|
@@ -10246,7 +11103,7 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
10246
11103
|
runsDirectory: /* @__PURE__ */ __name((turnId) => {
|
|
10247
11104
|
if (options.ephemeral) return void 0;
|
|
10248
11105
|
const owner = delegationScopes.get(turnId) ?? scope;
|
|
10249
|
-
return
|
|
11106
|
+
return join14(paths.sessionDir({ sessionId: owner.sessionId }), "runs");
|
|
10250
11107
|
}, "runsDirectory"),
|
|
10251
11108
|
refusal: /* @__PURE__ */ __name((turnId) => {
|
|
10252
11109
|
const auth = delegatedWorkflowAuth.get(turnId);
|
|
@@ -10329,6 +11186,7 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
10329
11186
|
);
|
|
10330
11187
|
}
|
|
10331
11188
|
subagentRuntime = void 0;
|
|
11189
|
+
sideModel = void 0;
|
|
10332
11190
|
cliLogger().warn("sub-agent runtime unavailable this session", exceptionAttributes(err));
|
|
10333
11191
|
}
|
|
10334
11192
|
const modelSwitchHandlers = /* @__PURE__ */ new Map();
|
|
@@ -10361,6 +11219,13 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
10361
11219
|
action: "answer_question",
|
|
10362
11220
|
selectedOptionIds: [...answer.selectedOptionIds],
|
|
10363
11221
|
...answer.freeText !== void 0 ? { freeText: answer.freeText } : {},
|
|
11222
|
+
...answer.answers ? {
|
|
11223
|
+
answers: answer.answers.map((entry2) => ({
|
|
11224
|
+
questionId: entry2.questionId,
|
|
11225
|
+
selectedOptionIds: [...entry2.selectedOptionIds],
|
|
11226
|
+
...entry2.freeText !== void 0 ? { freeText: entry2.freeText } : {}
|
|
11227
|
+
}))
|
|
11228
|
+
} : {},
|
|
10364
11229
|
questionId: request.question.questionId
|
|
10365
11230
|
};
|
|
10366
11231
|
case "abort":
|
|
@@ -10373,13 +11238,26 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
10373
11238
|
toolset("ask-user-question", [buildAskUserQuestionTool({ resumeHandler: parkQuestion })])
|
|
10374
11239
|
);
|
|
10375
11240
|
}
|
|
11241
|
+
let currentPlanHost;
|
|
11242
|
+
if (options.planApproval && !options.ephemeral) {
|
|
11243
|
+
toolsets.push(
|
|
11244
|
+
toolset("plan-mode", [
|
|
11245
|
+
buildExitPlanModeTool({
|
|
11246
|
+
mode: /* @__PURE__ */ __name(() => currentPlanHost?.mode() ?? "prompt", "mode"),
|
|
11247
|
+
planPath: /* @__PURE__ */ __name(() => currentPlanHost?.planPath ?? paths.planFile({ sessionId: scope.sessionId }), "planPath"),
|
|
11248
|
+
bypassAvailable: /* @__PURE__ */ __name(() => currentPlanHost?.bypassAvailable() ?? false, "bypassAvailable"),
|
|
11249
|
+
approval: /* @__PURE__ */ __name(() => currentPlanHost?.approval, "approval")
|
|
11250
|
+
})
|
|
11251
|
+
])
|
|
11252
|
+
);
|
|
11253
|
+
}
|
|
10376
11254
|
if (options.extraTools && options.extraTools.length > 0) {
|
|
10377
11255
|
toolsets.push(toolset("extra", options.extraTools));
|
|
10378
11256
|
}
|
|
10379
11257
|
if (options.openUrl) toolsets.push(toolset("open-url", [createOpenUrlTool()]));
|
|
10380
11258
|
const decisionTool = maybeCreateDecisionTool(options.decision, process.env);
|
|
10381
11259
|
if (decisionTool) toolsets.push(toolset("decide", [decisionTool]));
|
|
10382
|
-
const operatorPals = await import("./operator-tools-
|
|
11260
|
+
const operatorPals = await import("./operator-tools-MQXMUQLG.js");
|
|
10383
11261
|
toolsets.push(
|
|
10384
11262
|
readyWhen(
|
|
10385
11263
|
toolset(
|
|
@@ -10698,7 +11576,8 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
10698
11576
|
(input) => subagentRuntime?.launchesReadOnlyAgent(input) === true
|
|
10699
11577
|
),
|
|
10700
11578
|
{ unattendedSandboxEscape },
|
|
10701
|
-
screenPolicyFor(() => liveManager())
|
|
11579
|
+
screenPolicyFor(() => liveManager()),
|
|
11580
|
+
options.planApproval && !options.ephemeral ? isPlanFileWrite(paths.planFile({ sessionId: entry2.sessionId }), cwd) : void 0
|
|
10702
11581
|
), "handlerFor")
|
|
10703
11582
|
});
|
|
10704
11583
|
const resumeHandler = modeControl.handler;
|
|
@@ -10891,8 +11770,8 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
10891
11770
|
if (mapped) yield mapped;
|
|
10892
11771
|
}
|
|
10893
11772
|
if (settled) break;
|
|
10894
|
-
await new Promise((
|
|
10895
|
-
wake =
|
|
11773
|
+
await new Promise((resolve11) => {
|
|
11774
|
+
wake = resolve11;
|
|
10896
11775
|
});
|
|
10897
11776
|
wake = void 0;
|
|
10898
11777
|
}
|
|
@@ -10927,7 +11806,7 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
10927
11806
|
return reasoningEffortDefault;
|
|
10928
11807
|
},
|
|
10929
11808
|
...reasoningSettled ? { reasoningSettled } : {},
|
|
10930
|
-
compact: /* @__PURE__ */ __name((messages) => operations.promise(void 0, async (signal) => {
|
|
11809
|
+
compact: /* @__PURE__ */ __name((messages, instructions) => operations.promise(void 0, async (signal) => {
|
|
10931
11810
|
const sessionId = scope.sessionId;
|
|
10932
11811
|
const sessions = options.conversationSessions;
|
|
10933
11812
|
await prepareProviderCredential(signal);
|
|
@@ -10935,7 +11814,8 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
10935
11814
|
config: compactionConfigFor(options.compaction),
|
|
10936
11815
|
provider: providerForSession(sessionId),
|
|
10937
11816
|
model,
|
|
10938
|
-
signal
|
|
11817
|
+
signal,
|
|
11818
|
+
...instructions ? { instructions } : {}
|
|
10939
11819
|
};
|
|
10940
11820
|
if (sessions && !options.ephemeral) {
|
|
10941
11821
|
if (sessions.projectId !== scope.projectId || sessions.tenantId !== scope.tenantId)
|
|
@@ -10996,7 +11876,7 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
10996
11876
|
const live = host.registry.list();
|
|
10997
11877
|
const known = new Set(live.map((view) => view.runId));
|
|
10998
11878
|
const saved = options.ephemeral ? [] : await listWorkflowRuns(
|
|
10999
|
-
|
|
11879
|
+
join14(paths.sessionDir({ sessionId: scope.sessionId }), "runs")
|
|
11000
11880
|
).catch(() => []);
|
|
11001
11881
|
return [
|
|
11002
11882
|
...[...live].sort((a, b) => b.startedAt - a.startedAt),
|
|
@@ -11011,6 +11891,7 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
11011
11891
|
reset: /* @__PURE__ */ __name(() => host.registry.reset(), "reset")
|
|
11012
11892
|
}))(workflowHost)
|
|
11013
11893
|
} : {},
|
|
11894
|
+
...sideModel ? { sideModel } : {},
|
|
11014
11895
|
...subagentRuntime ? {
|
|
11015
11896
|
subagents: subagentRuntime.activity,
|
|
11016
11897
|
onSubagentReport: /* @__PURE__ */ __name((listener) => {
|
|
@@ -11205,6 +12086,13 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
11205
12086
|
errorKind: null,
|
|
11206
12087
|
// Reads the same object the handler mutates, at call time.
|
|
11207
12088
|
allowForSession: /* @__PURE__ */ __name((allows) => sessionAllows.add(allows), "allowForSession"),
|
|
12089
|
+
notifyHooks: /* @__PURE__ */ __name((info) => {
|
|
12090
|
+
if (!sessionPlugins) return;
|
|
12091
|
+
void sessionPlugins.manager.executeHooks("notification", {
|
|
12092
|
+
sessionId: scope.sessionId,
|
|
12093
|
+
notification: info
|
|
12094
|
+
}).catch(() => []);
|
|
12095
|
+
}, "notifyHooks"),
|
|
11208
12096
|
commandArguments,
|
|
11209
12097
|
setPermissionMode: /* @__PURE__ */ __name(async (mode, reason) => {
|
|
11210
12098
|
await Promise.all(
|
|
@@ -11225,6 +12113,8 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
11225
12113
|
let runManager = manager;
|
|
11226
12114
|
lastSendInteractive = opts?.onPermission !== void 0;
|
|
11227
12115
|
const turnScope = { ...scope };
|
|
12116
|
+
const planPath = options.planApproval && !options.ephemeral ? paths.planFile({ sessionId: turnScope.sessionId }) : void 0;
|
|
12117
|
+
const planModeWrite = planPath ? isPlanFileWrite(planPath, cwd) : void 0;
|
|
11228
12118
|
const initialMode = opts?.permissionMode ?? options.permissionMode ?? (opts?.onPermission || opts?.reviewHold ? "prompt" : "auto");
|
|
11229
12119
|
const modeControl = createLiveModeControl({
|
|
11230
12120
|
initial: initialMode,
|
|
@@ -11250,7 +12140,8 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
11250
12140
|
(input) => subagentRuntime?.launchesReadOnlyAgent(input) === true
|
|
11251
12141
|
),
|
|
11252
12142
|
{ unattendedSandboxEscape },
|
|
11253
|
-
screenPolicyFor(() => runManager)
|
|
12143
|
+
screenPolicyFor(() => runManager),
|
|
12144
|
+
planModeWrite
|
|
11254
12145
|
), "handlerFor")
|
|
11255
12146
|
});
|
|
11256
12147
|
const resumeHandler = modeControl.handler;
|
|
@@ -11301,6 +12192,12 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
11301
12192
|
}
|
|
11302
12193
|
const curatedMemoryPrompt = composeMemoryPrompt(curatedMemory);
|
|
11303
12194
|
currentOnQuestion = opts?.onQuestion;
|
|
12195
|
+
currentPlanHost = planPath ? {
|
|
12196
|
+
mode: /* @__PURE__ */ __name(() => modeControl.current(), "mode"),
|
|
12197
|
+
planPath,
|
|
12198
|
+
approval: opts?.onPlanExit,
|
|
12199
|
+
bypassAvailable: opts?.bypassAvailable ?? (() => false)
|
|
12200
|
+
} : void 0;
|
|
11304
12201
|
const [environmentFacts, turnSnapshot] = await Promise.all([
|
|
11305
12202
|
readEnvironmentFacts(cwd),
|
|
11306
12203
|
readTurnSnapshot(cwd)
|
|
@@ -11418,7 +12315,7 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
11418
12315
|
// Present only while the turn runs under `plan`. A mode change
|
|
11419
12316
|
// is rare, so the cached prefix it re-keys is a price paid once
|
|
11420
12317
|
// per switch rather than once per turn.
|
|
11421
|
-
!residentContext && opts?.permissionMode === "plan" ? PLAN_MODE_DOCTRINE : void 0,
|
|
12318
|
+
!residentContext && opts?.permissionMode === "plan" ? planPath ? NAMZU_PLAN_FILE_DOCTRINE : PLAN_MODE_DOCTRINE : void 0,
|
|
11422
12319
|
residentContext ? void 0 : environmentPrompt,
|
|
11423
12320
|
residentContext ? void 0 : opts?.extraSystem,
|
|
11424
12321
|
residentContext ? void 0 : opts?.systemNote,
|
|
@@ -11439,6 +12336,14 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
11439
12336
|
}
|
|
11440
12337
|
claimTurn(turnId);
|
|
11441
12338
|
const turnTaskStore = selectTaskStore(turnScope);
|
|
12339
|
+
const reminderSource = options.reminders ? createCliReminderSource({
|
|
12340
|
+
mode: /* @__PURE__ */ __name(() => modeControl.current(), "mode"),
|
|
12341
|
+
...planPath ? {
|
|
12342
|
+
planPath: /* @__PURE__ */ __name(() => planPath, "planPath"),
|
|
12343
|
+
canAsk: Boolean(options.askUser && subagentRuntime)
|
|
12344
|
+
} : {},
|
|
12345
|
+
tasks: /* @__PURE__ */ __name(() => turnTaskStore.list({ sessionId: turnScope.sessionId }), "tasks")
|
|
12346
|
+
}) : void 0;
|
|
11442
12347
|
let ephemeralLog;
|
|
11443
12348
|
if (options.ephemeral) {
|
|
11444
12349
|
ephemeralLog = new InMemorySessionLog({
|
|
@@ -11521,6 +12426,7 @@ async function createAgentSession(prefs, detected, options = {}) {
|
|
|
11521
12426
|
...memoryContextSteps(curatedMemoryPrompt, storedMemory.prompt)
|
|
11522
12427
|
],
|
|
11523
12428
|
taskStore: turnTaskStore,
|
|
12429
|
+
...reminderSource ? { reminders: reminderSource } : {},
|
|
11524
12430
|
systemPrompt,
|
|
11525
12431
|
messages,
|
|
11526
12432
|
projectInstructionContext: projectInstructions.createTurnContext(),
|
|
@@ -11663,7 +12569,10 @@ function constructProvider(id, det, model, context = {}) {
|
|
|
11663
12569
|
type: "openai",
|
|
11664
12570
|
apiKey: det?.apiKey ?? "",
|
|
11665
12571
|
baseURL: det?.baseUrl,
|
|
11666
|
-
model
|
|
12572
|
+
model,
|
|
12573
|
+
// The kernel retries, counts and shows each try; the vendor SDK must not
|
|
12574
|
+
// try again silently underneath.
|
|
12575
|
+
maxRetries: 0
|
|
11667
12576
|
});
|
|
11668
12577
|
return provider;
|
|
11669
12578
|
}
|
|
@@ -11678,7 +12587,8 @@ function constructProvider(id, det, model, context = {}) {
|
|
|
11678
12587
|
accessToken: det.apiKey ?? "",
|
|
11679
12588
|
accountId: det.codex.accountId,
|
|
11680
12589
|
baseURL: det.baseUrl,
|
|
11681
|
-
model
|
|
12590
|
+
model,
|
|
12591
|
+
maxRetries: 0
|
|
11682
12592
|
});
|
|
11683
12593
|
return provider;
|
|
11684
12594
|
}
|
|
@@ -11698,7 +12608,8 @@ function constructProvider(id, det, model, context = {}) {
|
|
|
11698
12608
|
type: "deepseek",
|
|
11699
12609
|
apiKey: det?.apiKey ?? "",
|
|
11700
12610
|
baseURL: det?.baseUrl,
|
|
11701
|
-
model
|
|
12611
|
+
model,
|
|
12612
|
+
maxRetries: 0
|
|
11702
12613
|
});
|
|
11703
12614
|
return provider;
|
|
11704
12615
|
}
|
|
@@ -11956,13 +12867,17 @@ function gateFor(rules) {
|
|
|
11956
12867
|
return { ...VERIFICATION_GATE, rules: [...rules ?? []] };
|
|
11957
12868
|
}
|
|
11958
12869
|
__name(gateFor, "gateFor");
|
|
12870
|
+
var MAX_OUTPUT_CONTINUATIONS = 3;
|
|
11959
12871
|
var COMPACTION_CONFIG = {
|
|
11960
12872
|
strategy: "salience",
|
|
12873
|
+
// Give up on compaction that keeps failing or keeps refilling, and say so
|
|
12874
|
+
// once. The kernel leaves this off, so the CLI asks.
|
|
12875
|
+
circuitBreaker: true,
|
|
11961
12876
|
// On, and this is the CLI making a choice rather than taking a default.
|
|
11962
12877
|
// A session's transcript is the only record of what was compacted away;
|
|
11963
12878
|
// the size trade this costs is the operator's to see and turn off.
|
|
11964
12879
|
recordShedHistory: true,
|
|
11965
|
-
triggerThreshold
|
|
12880
|
+
// No `triggerThreshold`: the kernel derives it from the model's window.
|
|
11966
12881
|
resetThreshold: 0.4,
|
|
11967
12882
|
keepRecentMessages: 6,
|
|
11968
12883
|
// Reclaim from stale tool output before summarizing. A CLI session is
|
|
@@ -12030,6 +12945,7 @@ async function* runTurn({
|
|
|
12030
12945
|
onApprovalPolicy,
|
|
12031
12946
|
reviewAllowedCalls,
|
|
12032
12947
|
taskStore,
|
|
12948
|
+
reminders,
|
|
12033
12949
|
systemPrompt,
|
|
12034
12950
|
messages,
|
|
12035
12951
|
projectInstructionContext,
|
|
@@ -12054,6 +12970,7 @@ async function* runTurn({
|
|
|
12054
12970
|
const readsOnly = declaredReadOnly(turnManager);
|
|
12055
12971
|
try {
|
|
12056
12972
|
const events = query({
|
|
12973
|
+
maxOutputContinuations: MAX_OUTPUT_CONTINUATIONS,
|
|
12057
12974
|
...retainedToolPreviewChars !== void 0 ? { retainedToolPreviewChars } : {},
|
|
12058
12975
|
...fileReadTracker ? { fileReadTracker } : {},
|
|
12059
12976
|
...structuredOutput ? { structuredOutput } : {},
|
|
@@ -12064,6 +12981,7 @@ async function* runTurn({
|
|
|
12064
12981
|
turnId,
|
|
12065
12982
|
...opts?.origin ? { origin: opts.origin } : {},
|
|
12066
12983
|
...opts?.abandonInterrupted ? { abandonInterrupted: true } : {},
|
|
12984
|
+
retry: terminalProviderRetry(opts?.restartableOutput === true),
|
|
12067
12985
|
// Omitted rather than empty when there is no tail. `query` treats the
|
|
12068
12986
|
// two the same, but an absent option reads as "this turn has no chain"
|
|
12069
12987
|
// where `[]` reads as "this turn has a chain with nothing in it".
|
|
@@ -12113,6 +13031,7 @@ async function* runTurn({
|
|
|
12113
13031
|
...systemPrompt ? { systemPrompt } : {},
|
|
12114
13032
|
projectInstructionContext,
|
|
12115
13033
|
messages: [...messages],
|
|
13034
|
+
...reminders ? { reminders } : {},
|
|
12116
13035
|
...opts?.inboundMessages ? { inboundMessages: opts.inboundMessages } : {},
|
|
12117
13036
|
...opts?.waitForInbound ? { waitForInbound: opts.waitForInbound } : {},
|
|
12118
13037
|
...opts?.durableInbound ? { durableInbound: opts.durableInbound } : {},
|
|
@@ -12168,7 +13087,7 @@ async function* runTurn({
|
|
|
12168
13087
|
if (isTurnInProgressError(err)) {
|
|
12169
13088
|
yield {
|
|
12170
13089
|
kind: "error",
|
|
12171
|
-
message: `This conversation already has a ${err.state} turn
|
|
13090
|
+
message: `This conversation already has a ${err.state} turn. ${err.state === "running" ? "Wait for it to finish." : "Resume it with /resume, or close it with /abandon."}`,
|
|
12172
13091
|
turnInProgress: {
|
|
12173
13092
|
sessionId: String(err.sessionId),
|
|
12174
13093
|
activeTurnId: String(err.activeTurnId),
|
|
@@ -12186,12 +13105,13 @@ async function* runTurn({
|
|
|
12186
13105
|
}
|
|
12187
13106
|
}
|
|
12188
13107
|
__name(runTurn, "runTurn");
|
|
12189
|
-
function makeResumeHandler(approval, onPermission, mode = onPermission ? "prompt" : "auto", exempt = () => false, escapePolicy = {}, screen) {
|
|
13108
|
+
function makeResumeHandler(approval, onPermission, mode = onPermission ? "prompt" : "auto", exempt = () => false, escapePolicy = {}, screen, planModeWrite) {
|
|
12190
13109
|
return createReviewHandler({
|
|
12191
13110
|
mode,
|
|
12192
13111
|
prompt: onPermission,
|
|
12193
13112
|
exempt,
|
|
12194
13113
|
remembered: approval,
|
|
13114
|
+
...planModeWrite ? { planModeWrite } : {},
|
|
12195
13115
|
...screen ? { screenConsent: screen.consent, capturesScreen: screen.capturesScreen } : {},
|
|
12196
13116
|
// Refused unless the operator wrote `sandbox.allowUnattendedEscape`: a
|
|
12197
13117
|
// session with nobody to ask has nobody to consent to leaving the
|
|
@@ -12250,7 +13170,9 @@ function withRuntimeMountedTools(manager) {
|
|
|
12250
13170
|
__name(withRuntimeMountedTools, "withRuntimeMountedTools");
|
|
12251
13171
|
function reviewExemptionFor(mode, manager, launchesReadOnlyAgent) {
|
|
12252
13172
|
const exemptLookup = withRuntimeMountedTools(manager);
|
|
12253
|
-
return (name, input) => isPromptExempt(exemptLookup, name, input) ||
|
|
13173
|
+
return (name, input) => isPromptExempt(exemptLookup, name, input) || // Presenting a plan asks the person on its own screen and changes nothing;
|
|
13174
|
+
// `plan` is the one mode it is for. Outside it the tool refuses by itself.
|
|
13175
|
+
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);
|
|
12254
13176
|
}
|
|
12255
13177
|
__name(reviewExemptionFor, "reviewExemptionFor");
|
|
12256
13178
|
function confirmsItself(name, input) {
|
|
@@ -12315,6 +13237,21 @@ function toAgentEvent(event, presenter, readsOnly) {
|
|
|
12315
13237
|
...event.messageId ? { messageId: event.messageId } : {},
|
|
12316
13238
|
...event.turnId ? { turnId: event.turnId } : {}
|
|
12317
13239
|
};
|
|
13240
|
+
case "plugin_hook_completed": {
|
|
13241
|
+
const result = event.result;
|
|
13242
|
+
if ((result.action === "continue" || result.action === "skip") && result.halt) {
|
|
13243
|
+
return {
|
|
13244
|
+
kind: "hook-notice",
|
|
13245
|
+
text: `A hook stopped this turn: ${result.halt.reason}`
|
|
13246
|
+
};
|
|
13247
|
+
}
|
|
13248
|
+
if ((result.action === "continue" || result.action === "skip") && result.notice) {
|
|
13249
|
+
return { kind: "hook-notice", text: `A hook says: ${result.notice}` };
|
|
13250
|
+
}
|
|
13251
|
+
return null;
|
|
13252
|
+
}
|
|
13253
|
+
case "plugin_hook_executing":
|
|
13254
|
+
return event.statusMessage ? { kind: "hook-status", text: event.statusMessage } : null;
|
|
12318
13255
|
case "reasoning_started":
|
|
12319
13256
|
return { kind: "reasoning", text: "" };
|
|
12320
13257
|
case "reasoning_delta":
|
|
@@ -12364,7 +13301,8 @@ function toAgentEvent(event, presenter, readsOnly) {
|
|
|
12364
13301
|
attempt: event.attempt,
|
|
12365
13302
|
maxRetries: event.maxRetries,
|
|
12366
13303
|
code: event.code,
|
|
12367
|
-
...event.status !== void 0 ? { status: event.status } : {}
|
|
13304
|
+
...event.status !== void 0 ? { status: event.status } : {},
|
|
13305
|
+
...event.restart ? { restart: true } : {}
|
|
12368
13306
|
};
|
|
12369
13307
|
case "tool_progress":
|
|
12370
13308
|
return {
|
|
@@ -12564,6 +13502,10 @@ function describeCompactionFailure(event) {
|
|
|
12564
13502
|
return `context could not be reduced further \u2014 nothing left to shed. ${held}; later passes will answer the same`;
|
|
12565
13503
|
case "split_tool_pair":
|
|
12566
13504
|
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`;
|
|
13505
|
+
case "breaker_open":
|
|
13506
|
+
return event.error ?? "Automatic compaction stopped after three failed attempts. Run /compact yourself, or start fresh with /clear.";
|
|
13507
|
+
case "refilling":
|
|
13508
|
+
return event.error ?? "The context filled up again right after being compacted, three times in a row. Read big files in smaller parts, or start fresh with /clear.";
|
|
12567
13509
|
}
|
|
12568
13510
|
}
|
|
12569
13511
|
__name(describeCompactionFailure, "describeCompactionFailure");
|
|
@@ -12861,6 +13803,8 @@ export {
|
|
|
12861
13803
|
renderStoredMemorySection,
|
|
12862
13804
|
allowsForBatch,
|
|
12863
13805
|
describeAllows,
|
|
13806
|
+
KEEP_PLANNING_PLACEHOLDER,
|
|
13807
|
+
planApprovalRows,
|
|
12864
13808
|
assistantTranscriptTexts,
|
|
12865
13809
|
projectTurnConversation,
|
|
12866
13810
|
resolveModelSwitch,
|
|
@@ -12890,4 +13834,4 @@ export {
|
|
|
12890
13834
|
RESULT_SUMMARY_WHOLE_MAX,
|
|
12891
13835
|
resultSummaryLine
|
|
12892
13836
|
};
|
|
12893
|
-
//# sourceMappingURL=chunk-
|
|
13837
|
+
//# sourceMappingURL=chunk-BXJ7G5XN.js.map
|