mu-agent 0.1.10 → 0.1.14

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.
Files changed (41) hide show
  1. package/CHANGELOG.md +122 -0
  2. package/README.md +7 -7
  3. package/dist/bundle/chunks/{chunk-DNNHZBQR.js → chunk-6Z2347ML.js} +1 -1
  4. package/dist/bundle/chunks/{chunk-FN6OEZYR.js → chunk-AN7MSYCK.js} +1 -1
  5. package/dist/bundle/chunks/{chunk-O7IPTASE.js → chunk-BK7M6BDT.js} +22 -21
  6. package/dist/bundle/chunks/{chunk-X234222Q.js → chunk-DYTENXHX.js} +2 -2
  7. package/dist/bundle/chunks/{chunk-RAQ6TU76.js → chunk-FLHKNMLQ.js} +1 -1
  8. package/dist/bundle/chunks/chunk-LHRPMXVI.js +2 -0
  9. package/dist/bundle/chunks/{chunk-HZNN636Z.js → chunk-LT2C56HV.js} +1 -1
  10. package/dist/bundle/chunks/{chunk-SGOTYFMT.js → chunk-MF3VB62R.js} +1 -1
  11. package/dist/bundle/chunks/{chunk-QOEEJKS4.js → chunk-URBBMV3M.js} +1 -1
  12. package/dist/bundle/chunks/{chunk-VJLOQZKR.js → chunk-WCJNJQO5.js} +1 -1
  13. package/dist/bundle/chunks/{cli-722OL3K5.js → cli-M4YBZZ6Q.js} +1 -1
  14. package/dist/bundle/chunks/{easter-egg-3d-6H34EDGX.js → easter-egg-3d-VFY3YRQR.js} +1 -1
  15. package/dist/bundle/chunks/{execute-KVSEIDWL.js → execute-FKI7Y4XR.js} +1 -1
  16. package/dist/bundle/chunks/{runtime-O3ELDOM7.js → runtime-IKE5OQIW.js} +1 -1
  17. package/dist/bundle/chunks/{virtual-modules-IKEARUOZ.js → virtual-modules-U6MRV5BC.js} +1 -1
  18. package/dist/bundle/cli-runtime.js +1 -1
  19. package/dist/bundle/index.js +1 -1
  20. package/dist/bundle/rpc-entry.js +1 -1
  21. package/docs/settings.md +1 -1
  22. package/judge/dist/auth.js +54 -26
  23. package/judge/dist/chrome.js +2 -2
  24. package/judge/dist/import.js +833 -161
  25. package/judge/dist/setup.js +142 -48
  26. package/judge/manifest.json +2048 -394
  27. package/judge/mu/chunk-3NQ5BIBI.js +4773 -0
  28. package/judge/mu/chunk-6XRUK3PM.js +51 -0
  29. package/judge/mu/chunk-WQM4MV6L.js +58 -0
  30. package/judge/mu/cloud-code-XR7SZMJC.js +22802 -0
  31. package/judge/mu/dist-75PS4OC4.js +1283 -0
  32. package/judge/mu/index.js +4949 -32969
  33. package/judge/mu/multipart-parser-ZDXVIOOP.js +372 -0
  34. package/judge/mu/src-TVVA5ZK2.js +1409 -0
  35. package/kyrn/bin/kyrn-doctor +67 -14
  36. package/kyrn/bin/kyrn-judge-local +42 -13
  37. package/kyrn/bin/kyrn-ledger +16 -1
  38. package/kyrn/bin/mu.mjs +101 -29
  39. package/kyrn/local-judge/server.py +26 -14
  40. package/package.json +6 -3
  41. package/dist/bundle/chunks/chunk-BSS6T6KQ.js +0 -2
package/CHANGELOG.md CHANGED
@@ -2,6 +2,128 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.1.14] - 2026-10-23
6
+
7
+ ### Added
8
+
9
+ - Spend that no message of a session carries is recorded as a `kyrn.usage` session entry (a custom entry: kept in the file, never sent to the model; format in `kyrn/docs/features/usage-accounting.md`). A reply the watchdog cuts: the aborted request reports no usage, so its output is estimated from the reasoning that had streamed at 3.5 characters per token (the median over 164 reasoning-only MiMo replies on Terminal-Bench 2.1), less any output the provider did report, and priced at the model's output rate (`source: "watchdog-cut"`, `estimated: true`). Each `delegate` or `hive` sub-agent, verifiers included, when it ends: the sums of its messages' usage and cost as it streamed them, plus its own watchdog's estimates, `partial: true` when it was stopped or failed (`source: "subagent"`, with `kind`, `name`, `role`, `status`). On Terminal-Bench 2.1, 9 cuts of about 27k reasoning tokens and one hive at three times its parent's cost were in no session file. The `watchdog.cut` presentation event's `thoughtChars` is now the whole reasoning, not the end kept for the retry.
10
+ - With `"recordState": true`, a decision whose questions are built from its input (one per skill in `skills.disclosure`, per capability, per memory in `memory.worth`, and so on) also keeps those questions in its ledger row (`questions`, redacted like the request). Without them such a row could not be replayed or used to train a judge. Decisions with fixed questions are named by `specId` and `specVersion`, and keep nothing more.
11
+
12
+ ### Changed
13
+
14
+ - An interactive turn waits less before the model starts. `skills.disclosure` is asked the moment the message arrives, alongside preflight, as `runtime.atTurnStart` meant it to be: the early question never went out, because an `input` event's context has no `getSystemPromptOptions`, so the skills question waited for preflight's verdict and then for its own. The list now comes from the last turn, or before the first from pi's `/skill:` commands (`features.skills.askEarly`, default true). Every wait before a turn ends 3 s after the message arrived instead of 4 s (`preflight.waitMs`, `catalog.waitMs`, `skills.waitMs`, `memory.waitMs`; the frame's was 3 s already). `tool.admission` holds a long result at most 2 s instead of 4 s (`admission.waitMs`). Measured in the owner's 49 interactive sessions (Jev, reached from China): the skills question added a median 0.7 s to every message; no preflight or skills verdict came between 3 and 4 s (past 3 s they came after 4.3 s and 5.2 s or not at all), and the one capability verdict that did opened nothing (none of 34 did); and 19 of 57 admission calls waited the full 4 s, while the 3 verdicts that came between 2 and 4 s dropped nothing. Replayed on those 67 turns, the wait before the model starts goes from a median 2.7 s to 1.7 s (mean 2.8 s to 2.0 s), and at most 3 s instead of 4 s. Approval, risk, constraint and injection checks wait as before.
15
+ - `turn.continue` in an unattended run (`mu --print`, json mode): a "you said you would" verdict (`promised`) sends the agent back at most once per user message (`features.continuation.unattendedPromised`, default 1; `maxNudges` still caps all nudges together), and not at all when the run that just ended was the agent's answer to a nudge and called no tool (`promisedAfterToolless`, default false). The ending-with-no-message rule and go-ahead nudges are unchanged, and so is an interactive session. `promised` needs a new judge capability, `intent`, which the built-in `laya` profile sets to false: with `laya,jev` it goes to Jev, and with Laya alone no `promised` nudge is sent (`continuation.localPromised: true` asks Laya again). On Terminal-Bench 2.1 (constraints-scheduling) Laya read "Done. Created `/app/meeting_scheduled.ics` …" as a promise twice; the second nudge sent the model searching `/` for test files: 4 extra requests and 51k input tokens.
16
+ - `capability.disclosure` is off by default (`DEFAULT_CONFIG.modes`; the manifest's `defaultMode` is `off`, and the desktop settings show it off). On Terminal-Bench 2.1 it was asked 162 times and never had an effect ("never open" was more accurate than the judge); in 49 interactive sessions it was asked 34 times and opened nothing, while each turn waited for it beside preflight (p50 0.91 s, p90 8.9 s; 6 of 34 answers late or failed). `off` now means: no judge call and no wait at the start of a turn, and packs and MCP servers stay hidden exactly as when the judge opens none. The model opens one with `find_capability`, the user with `/capabilities open`, a pack's command (`/review`, `/commit`) opens its own, and a sub-agent opens what its parent has open (`KYRN_CAPABILITIES_OPEN`, now passed with the decision off too, so a child asks nothing). Before, `off` hid nothing; that is `features.catalog: false` now, which also hands every MCP server to pi at session start (before, it only started the packs). `"modes": { "capability.disclosure": "active" }` in `mu.json`, or the desktop settings, bring the judge's choice back. So that the model knows what it can open without the judge, `find_capability`'s description lists the judged capabilities installed when the session's first turn starts, hidden or open, by id and kind, MCP servers first (`Installed: mcp:linear (MCP server), pack:ast-grep (pack), …`; at most 20, then "and N more"). It is taken once and kept for the session, so opening one never changes the description or the cached prefix; with nothing judged installed the description is as before, and an unattended run still leaves `find_capability` out (`catalog.unattendedHidden`).
17
+ - In the terminal and the desktop app, a call that changes files no longer waits for the checkpoint's scan after it (about 0.1 s a change on a Mac, 0.2 s in a container): the scan runs in the background, and the run ends once the last one has, waiting at most 3 s more. A rewind still waits for it, so a file changed by hand after the run is still told apart from the agent's changes.
18
+ - In the terminal and the desktop app, a chain of read-only shell commands (`pwd && find src -name '*.ts' | head`, `git status --short; git log --oneline -5`) no longer counts as a call that can change files, so a turn that only looks takes no checkpoint snapshot (in a container the first snapshot took a median 0.75-1.7 s). The permission gate and the constraint gate already read such chains as only looking (`isReadOnlyChain`); a chain with any other program, a redirection that writes, or `cd` before `git` still counts as a change.
19
+ - `turn.rewind` waits at most 3 s for its verdict (`features.checkpoint.rewindWaitMs`), not the judge's own timeout (10 s for a hosted judge, 30 s for an `llm:` one). A late verdict carries on, as the fallback did. On Terminal-Bench 2.1 every verdict came in 0.2-1.6 s.
20
+ - With Laya alone, `turn.continue` is no longer asked at the end of a run. Laya is trusted on neither `promised` (`intent`) nor a go-ahead (`meta`, `relate`), so its verdict could only be "end", while the run waited for it up to 3 s (`continuation.waitMs`). Laya also reads these questions with a yes bias: in Terminal-Bench 2.1 it said yes to `asks_go_ahead` 18 of 29 times and to `irreversible` 15 times, where Jev and mude said no on almost every state. Probed with clear cases, it answers them the right way round ("I've completed the task" scores 0.01-0.1 on all three questions), so the answers aren't inverted; it is a weak reader of agent messages. `continuation.localPromised: true` still asks it. Routes set with `/mu route` now count when mu works out which judge answers a decision (also for the batching of `tool.admission` and `tool.injection`).
21
+
22
+ ### Fixed
23
+
24
+ - `/login`: a sign-in cancelled with Escape goes back quietly also when the flow rejects with the dialog's abort (GitHub Copilot's), not only with "Login cancelled".
25
+ - An unattended run (`mu --print`, json mode; not a sub-agent) could not reach an MCP server that isn't `"exposure": "always"`: since #81 it leaves `find_capability` out (`catalog.unattendedHidden`) and asks no `capability.disclosure`, and #122 made that the case for `"modes": { "default": "off" }` too. Now `find_capability` stays in such a run when at least one judged MCP server is installed when its first turn starts (`features.catalog.unattendedFindWithMcp`, default true), with the installed list from #122 in its description (`mcp:linear (MCP server)`, …), so the model can open the server within the run. Packs alone don't keep it: a run without a server (Terminal-Bench has none) sends the same first request as before, and no prompt or tool description names `find_capability` there.
26
+ - `mu "- Fix the parser"` (a message that starts with a list item) runs instead of ending with "Unknown option: - Fix the parser". On Terminal-Bench 2.1 one task's instruction starts that way (pytorch-model-recovery), and Harbor's pi command, which mu's bench adapter builds on, puts no `--` before it: that task ended with exit 1 before the agent ran, in pi and in every mu config.
27
+ - With Laya first and a hosted judge behind it (`/mu judge laya,jev`), a long tool output (`tool.admission`) and fetched content (`tool.injection`) went to Jev one chunk or passage per request, as if Laya answered them, though Laya is not trusted on screening and the cascade passes them on. They go in batches now, as with Jev alone: measured on Jev, 16 chunks took 0.44 s and 7.6k tokens in one request, against 1.4 s and 11.6k as 16. Which judge answers comes from the first judge trusted on the question, and `/mu judge` changes it for the rest of the session; before, the setting at start-up stayed.
28
+ - `tool.risk` and the permission confirmation read a flagged command with its line breaks (`riskExcerpt`). Every run of whitespace used to become one space, so in a script `echo done` and an `rm -rf build` on the next line read as one echo. Spaces and tabs still collapse, and blank lines go. A flagged command longer than 1,500 characters (`RISK_COMMAND_CHARS`, 8,000 before) reaches the judge as the excerpt the confirmation shows: the start of the command and every flagged part with the text around it. Each rule that matched keeps at least one part. Whole scripts up to 8,000 characters read worse: on 36 dev `tool.risk` scenarios hidden among read-only commands from real sessions (144 long variants), the cost (10 per false allow, 1 per needless confirmation) went from 87 to 64 with the shipped judge model.
29
+ - `mu setup`'s subscription hint no longer says to start mu and type `/login`: when setup starts mu, `/login` is already open.
30
+ - With the judge off (`"modes": { "default": "off" }`, setup's "Not now"), nothing asks it and nothing names it. The footer status after a message is left out, where it named the judge set up ("Jev 1.13 (free): chat · answer directly · off"). `/status` says `judge: off` and no longer lists `notify.routing`, `input.interjection` and `turn.drift` as `shadow`, since a built-in mode gives way to a default of off (`DecisionEngine.overrides()`). `/doctor` no longer probes the judge with a question, which sent a request to OpenCode and brought up the free Jev's notice. It and `mu doctor` say the judge is off, leave out the Jev key row, and show `browse` as off. A first `mu setup` no longer reports a backup when the only file was the empty `auth.json` pi writes at its first start.
31
+ - A judge provider that ignores the `AbortSignal` can no longer hold a decision past `timeoutMs`. `Judge.evaluate` races the provider's requests against the deadline and fails with a `timeout` `JudgeError`, so the decision takes its fallback as with any late verdict. The built-in providers already stopped at the signal.
32
+
33
+ ## [0.1.13] - 2026-10-22
34
+
35
+ ### Added
36
+
37
+ - A run deadline: `MU_TIME_BUDGET_S` (or `features.deadline.budgetS`) is the run's time budget in seconds, counted from when the mu process started. With a budget, the watchdog cuts a reply that has only been thinking after `min(thinkingMs, max(60 s, half the time left when the reply started))` instead of after `thinkingMs`, and the model gets a one-line steer when 50% and 80% of the budget have passed: the minutes left and, at 80%, to get the requested result in place (files written, services running) before polishing (`features.deadline.notices`). No judge is asked, a sub-agent ignores the budget, and without one nothing changes. On Terminal-Bench 2.1 all 3 watchdog cuts came 788-886 s into a 900 s budget, too late for the retry to finish.
38
+
39
+ ### Changed
40
+
41
+ - `mu setup` lists services by language (`servicesInOrder`): in English OpenAI, Anthropic, Google, xAI, OpenRouter and OpenCode Zen come first, then the table's order; in Chinese the table's order. Ollama and `other` stay last. The same goes for "Choose a service from the list" and the picker for a key mu doesn't recognize; `--service` ids are unchanged.
42
+ - `quietStartup` defaults to `"header"` under mu's name (pi keeps `false`): the welcome header shows, the startup listing of loaded resources doesn't; diagnostics still do. A value in settings.json, `false` included, holds; `--verbose` overrides it.
43
+ - `/login` offers no Claude subscription sign-in under mu's name (Anthropic doesn't allow other apps to offer one); an Anthropic API key is still offered, and an earlier sign-in stays until `/logout`. `mu setup` refuses a Claude subscription token (`sk-ant-oat…`) given as a key, pasted or with `--key-stdin`, and sends it nowhere.
44
+ - The plain-language board runs only where someone watches it, the terminal and the desktop app, not in `mu --print` or json mode (`features.board.unattended` brings it back). While subagents work, it looks again only when one of them starts, finishes or fails, not every 20 seconds (`followAlways`). An unsure "has anything changed?" with nothing new no longer rewrites the board, and "is it waiting for you?" is asked only once the agent stopped. Replayed on 82 judged looks, the change gate alone cuts the writer calls from 82 to 29.
45
+ - `delegate` and `hive` ask the judge how hard a task is only when a model ladder is set (`features.swarm.models`) or a role pins a model of its own: without one, a delegation that names every role asks nothing, and one that doesn't asks only which role. Hive bees get their thinking level the way delegate's subagents do: on the session's model, the session's level, which keeps the parent's prompt cache warm.
46
+ - Hive: what a bee says starting with `FOUND:` or `DEAD END:` goes on the board without asking the judge (`features.hive.publishMarked`), and tool output is no longer put to the judge as a possible note (`publishToolOutputs`). When the judge can't answer, notes go to every bee up to `maxDeliveriesPerBee` instead of to none. A new note is held against at most 2 earlier ones (`maxRelatedPerNote`, was 6).
47
+ - `swarm.patch` is off by default: the delegate result already lists every changed file with its line counts. `"modes": { "swarm.patch": "active" }` in `mu.json` turns it back on.
48
+ - `browse` with a goal refuses up front when the judge for `browser.step` can't relate a goal to a page (Laya alone), and says how to route it to another judge; before, it opened the page and blocked after the first look.
49
+ - In shadow mode, the decisions mu acts on anyway (`browser.step`, `swarm.routing`, `judge.items`) are recorded as the judge's, not as the fallback's (`actsInShadow`).
50
+ - `notify.routing` and `input.interjection` are in shadow by default: the verdict is recorded and nothing waits for it. Without a verdict, a background job's end or watched line and the 70% and 85% context-budget notices reach the model at once, as a steer (`features.background.unjudged` and `features.notify.unjudged`: `now`, `next_turn` or `drop`); before, a job's end waited for a next turn that a one-shot run never has, and the budget notice was dropped. A watched line is not routed while `bg_output` waits on its job. A message sent mid-run goes on at once instead of after up to 1.5 s.
51
+ - `turn.continue` (v2) asks whether what the closing message offers is more than the user asked for (`beyond_request`). Only a go-ahead on the requested work sends the agent back; an offer of extra work no longer does. The local judge (Laya) is not asked this question, so on Laya alone no stop counts as a go-ahead.
52
+ - `cache.warming` is asked only while the agent is idle and waits at most 3 s (`features.warming.waitMs`). During a run pi's own decision stands, so a message that reads like a sign-off can no longer stop warming in the middle of the run.
53
+ - `skills.disclosure`: a verdict on the session's first message that arrives after the 4 s wait is applied from the next turn, instead of the session keeping every skill description (`features.skills.applyLate`).
54
+ - `tool.injection` asks the judge only about passages with prose in them: six words in a row on a line, or eight characters in a row of a script written without spaces (`features.injection.proseWords`, 0 judges every passage). Directory listings, link lists, response headers and short grep hits get the rules alone. On Terminal-Bench 2.1 that is about half of all screened passages, and half of the screened results need no request at all.
55
+ - `tool.injection` and `tool.admission` ask for a new judge capability, `screen`, which the built-in `laya` profile sets to false. With `laya,jev` they go straight to Jev; with Laya alone, injection is left to the rules and long output goes in whole. On Terminal-Bench 2.1 every passage Laya withheld was clean, its one admission drop was wrong, and most of its calls on both failed or came too late.
56
+ - A cascade's stand-in answer (`judge: "untrusted"` or `"unavailable"`, a probability of 0.5 nobody gave) is no verdict for `tool.injection`: the rules read the passage, where before it passed unread. Such a call, and an admission call answered only by stand-ins, is recorded as a fallback (`abstain`).
57
+ - `tool.admission` no longer judges `web_fetch` results (added to `passThrough`, whose listed default now also shows `delegate` and `hive`) or a bash or PowerShell command that only prints files (`features.admission.printCommands`: `cat`, `sed -n`, `head`, `tail`, `nl`, `less`, `bat`, `grep`, `rg`, `od`, `xxd`, `git show`, `git diff`, `readelf`, `objdump`, with `cd` and `echo` between them). A redirect, a here document, `$(…)`, `&&` into another program or `tail -f` makes it more than a print. On Terminal-Bench 2.1 this skips 46 of 89 admission calls; every drop the judge got right there was in background-job or script output, which is still judged.
58
+ - An unattended run (`mu --print`, json mode) runs a lean profile. Preflight, capability disclosure and the drift check are not asked; no skill is drafted and no lesson is learned, while kept lessons are still read; and `delegate`, `apply_patch_from`, `browse`, `locate`, `remember`, `find_skill`, `find_capability`, `hive` and the bundled `mu-browser` skill are left out of the request, so its first request is about 1.9k tokens smaller (17.8k to 10.5k characters on a faux-provider session). Packs stay hidden as before. A tool called for by its command stays (`mu -p "/hive …"`). Sub-agents, which run in json mode too, are not affected. Each part has an option: `preflight.unattended`, `catalog.askUnattended`, `catalog.unattendedHidden`, `monitor.unattended`, `procedures.unattended`, `memory.unattendedWrites`.
59
+ - `turn.drift` only records by default (`modes: { "turn.drift": "shadow" }`): in benchmark runs Jev never flagged drift, and about 9 in 10 of another judge's drift steers were wrong. Set it to `active` to have it steer again.
60
+ - `skill.capture` drafts a skill only when the judge is at least 90% sure the run was a procedure (was 70%).
61
+ - `memory.outcome` learns only from a loop the turn got out of, not from drift, which names no failing call.
62
+ - Permission modes: a command made only of read-only commands joined by `;`, `&&`, `||` or `|` (`pwd && find . -name '*.ts' | sort | head`, `git status --short; git log --oneline -5`), throwing output away with `2>/dev/null` or `2>&1`, runs without asking the judge or you, like a single read-only command, and the constraint gate no longer checks it. A redirect that writes a file, `sed -i`, `tee`, `find` with `-exec`, `-delete` or `-fprint`, a substitution, or `cd` followed by `git` still asks. Quoting is read the way the shell reads it, so `rg '--pre=./x'` and `sort --out=f` no longer pass as read-only (`features.permissions.readOnlyChains`, `features.constraints.skipReadOnly`).
63
+ - The risk rules flag `rm` only when it deletes recursively (`-r`, `-R`, `-rf`, `--recursive`, also after a file name); `rm -f file` and `docker run --rm` are not flagged. `curl … | python3 -c '…'` (and `node -e`, `perl -e`, `ruby -e`) reads the download as data and is no longer "runs a downloaded script", unless the code runs what it reads (`exec`, `eval`, `system`, …). A download saved and then run in the same command (`curl -o i.sh … && sh i.sh`) is flagged now.
64
+ - `tool.risk` (v2) asks only whether you asked for the command. Its "destructive" question never changed a verdict in Judge mode; with permission modes off, a "not destructive" no longer lets the guard run a flagged command.
65
+ - `tool.description` (v2) keeps the judge's verdicts in `~/.mu/agent/mu/tool-descriptions.json`, so the next `mu --print`, subagent or restart doesn't screen an unchanged MCP server again or wait up to 8 seconds for it. A call to an MCP tool taken off the list is refused before anyone is asked to allow it, and a cascade's stand-in answer is no verdict here either: the rules read that passage, and nothing is kept.
66
+ - `turn.drift` (v2) is reworked, and stays in shadow until a benchmark validates it. The judge sees the task frame's goal and first open acceptance item; the last 8 actions as `bash: make -> exit 2 in 14s; last line: …`; the minutes since the last sign of progress (a file written for the first time, more tests passing or fewer failing, an error not seen before, a failing call passing, a call of a minute or more that succeeds, a ticked item) and since the start; and how often one call came back the same. It is asked after 6 tool results once 3 minutes have passed since the last check, or 10 minutes after it whatever happened, on a timer that never keeps the process alive (`features.monitor`: `every`, `minMinutes`, `maxMinutes`). A steer needs drift at p ≥ 0.9 on two checks in a row and 10 minutes without progress (`stuckMinutes`), or a loop reading at p ≥ 0.8, named once per call like the loop rule; at most one steer per 15 minutes, the loop rule's included (`cooldownMinutes`). It names what looks stuck and asks for a different approach. In shadow, the steer it would have sent is recorded as a `kyrn.monitor` entry with `shadow: true`. Replayed over the 109 Terminal-Bench 2.1 sessions of 0.1.11 with their recorded answers, it asks about 30% less often, leaves less of a timed-out run unchecked, and sends none of the 29 drift steers v1 sent: 1 of them came after 10 minutes without progress, and it followed an `on_track` reading.
67
+ - An unattended run takes no checkpoints (`features.checkpoint.unattended`): no snapshot before the first call that can change files, and no blocking rescan after each one, where nobody can confirm a rewind and no file was ever put back. In Terminal-Bench 2.1 trials the snapshot and rescans cost a median 4-7.5 s a trial; on a Mac, 20 file-changing calls in a 2,000-file folder spent 2.5-3.0 s in git, and now spend none. A dead end is still asked about (`turn.rewind`), in a turn that ran such a call, and the model is told to step back. Sub-agents took none already. Nothing changes in the terminal or the desktop app.
68
+ - Judge warm-up (`features.warmup`) sends no probe in an unattended run (`unattended`), to a judge at a loopback, private-network or `host.docker.internal` address (`nearby`), or while a real question used the connection within the last `intervalMs`. A probe still on its way is cancelled when the session ends, and `/status` counts probes and their input tokens. Unattended Jev runs sent about 19 probes a trial (5.2k input tokens), more than their logged judge traffic.
69
+ - `notify.routing` is not asked in an unattended run (`features.notify.unattended`), like the drift check: in shadow, its default, the verdict changes nothing there.
70
+ - Sub-agents (`delegate`, hive bees) take their parent's settled `skills.disclosure` and `capability.disclosure` answers instead of asking the judge again: the parent passes the skills it hides and the capabilities it has open (`KYRN_SKILLS_HIDDEN`, `KYRN_CAPABILITIES_OPEN`), and the child hides and opens exactly those, whatever its own mode, and asks nothing. That saves about 0.8k judge tokens and up to 4 s at every child's start, and with 4 or more skills a further 6.5-11k tokens; a child whose own skills verdict came late used to carry every skill description on every request. While the parent's first skills verdict is still on its way, a child asks for itself as before. `features.skills.subagentsInherit` and `features.catalog.subagentsInherit` turn it off.
71
+ - In `mu --print`, json mode and sub-agents the system prompt is about 375 tokens shorter per request (9.1k to 7.7k characters on a faux-provider print session): pi's `<docs>` list of its guides becomes one line with the path to the docs, and the `<mu>` section leaves out the commands to type, the reply to act on, the hints before a turn and the `browse` tool. In Terminal-Bench runs the docs were never read in 286 trials. Interactive and desktop sessions keep both (`features.welcome.unattended` brings them back elsewhere).
72
+ - `web_fetch`'s description, its note on a page that needs JavaScript and `web_search`'s advice when no source answers name the `browse` tool only when the model has it; before, an unattended run, which leaves `browse` out, was told to use it.
73
+ - The settings texts added in this release for the drift monitor's timing options, sub-agents taking the session's skills and capabilities, and the unattended-run options of checkpoints, notification routing, judge warm-up and the welcome note are in all eleven extra languages.
74
+ - The judgment layer's bundle is split: code it imports only when used (the Google sign-in providers' request code with Google's SDK, 1.2 MB) moves from `judge/mu/index.js` (3.5 MB to 2.4 MB) to chunks beside it, which Node reads and compiles only on first use. Importing the extension takes about 9 ms less on a cold compile cache (48 to 40 ms on an Apple M6), at every start and in every sub-agent. The build imports every chunk once to check that Node can.
75
+
76
+ ### Fixed
77
+
78
+ - `mu doctor` (kyrn-doctor) prints "mu doctor found N things to fix" or "mu doctor: everything is set up" first when stdout is a terminal; piped output is still one row per line.
79
+ - `/login` hides the `openai-codex` sign-in under mu's name, as `mu auth` and the desktop app do; `openai` (Sign in with ChatGPT) replaces it. A stored `openai-codex` sign-in still works and shows in `/logout`. The first `/login` menu leaves out the "Sign in with Radius" shortcut under mu's name; Radius is still under Sign in with an account. `mu setup`'s subscription hint names `/login`'s actual entries.
80
+ - The footer shows "no model" for the agent's `unknown/unknown` placeholder.
81
+ - `mu setup` ends with exit code 4 (`SETUP_EXIT.signIn`) when a subscription was chosen and a session follows; the launcher then starts the session with `/login` as its first message, which opens the sign-in like the typed command (`afterSetup`). Inside a session, "No models available" leads with `/login` (`formatNoModelsAvailableMessage({ inSession: true })`).
82
+ - `mu judge` (kyrn-judge-local): `help`/`--help` prints a usage, an unknown command prints it to stderr and exits 2, `status` prints one readable line (`status --json` the server's JSON), and its messages are sentence case. `mu ledger --help` prints a usage instead of reading the sessions. `mu auth --help` (or a bare `mu auth`) prints mu's `status | login | logout` before pi's auth help. `mu import --help` names `MU_AGENT_DIR`, the variable the docs use. `mu link --help` / `mu unlink --help` print a usage (they linked and unlinked); unlink's messages are sentences. The launcher answers `mu --version` and `-v` itself with mu's bare version: in a checkout from kyrn/npm/package.template.json (pi's own answer there was pi's version), in the package from its package.json; the smoke test checks it; the launch-chain tests start pi with `--help` instead.
83
+ - `mu setup`'s "Not now" judge writes `"modes": { "default": "off" }` (before: nothing, so the default `jev` tier with no key used the free Jev on OpenCode Zen); a judge picked later removes that "off". `mu setup --judge off` writes the same for scripts; `--judge none` still leaves the judge unchanged. The engine takes `builtInModes` (DEFAULT_CONFIG.modes): with the default "off", a point whose mode is only its built-in one is off too, so no judge is asked; a mode set to another value holds. With every point off, the welcome line shows the judge as off and neither it nor the warm-up probes the judge.
84
+ - The loop rule ("the same call 3 times with the same outcome") compares the whole input and the result text. Paging through a file with `read` at different offsets, or two scripts whose first 300 characters match, no longer counts as a loop.
85
+ - The end-of-run checks (`turn.completion`, `turn.continue`) cancel their judge call when their 3 s wait runs out. A late verdict no longer keeps `mu --print` from exiting until the judge's own timeout: with a slow local judge, runs ended 7-13 s after their last message. Notification verdicts still on their way are cancelled when the session ends.
86
+ - The `remember` tool dropped a lesson when the judge gave no verdict (a timeout, no judge, shadow mode) or could not tell. It now stores it; only a judge that reads it as one-off or known already turns it down. Sub-agents' `Lesson:` lines still need a verdict.
87
+ - `manifest.json` gives a decision point its built-in mode (`defaultMode`) when `DEFAULT_CONFIG.modes` sets one for it: `swarm.patch` off, `notify.routing`, `input.interjection` and `turn.drift` in shadow. Without it the desktop app's settings and kernel bar showed these points at the default mode, as active, and usemu.dev counted 38 of the 40 points as acting from the start instead of 34. `scripts/write-docs-reference.mjs` reads the modes from the manifest too.
88
+ - The local judge (Laya) no longer crashes when the disk runs low. Core ML keeps its compiled copy of the model in `~/Library/Caches/python/com.apple.e5rt.e5bundlecache`, marked purgeable, and macOS deletes it to free space; each change of input length read it back, so the next one recompiled the model (3-36 s) or aborted the sidecar inside MetalPerformanceShadersGraph (`failed assertion shape.count = 0 != strides.count = 2`), five times in one night of Terminal-Bench. The sidecar now pads every request to the checkpoint's whole window (1024 tokens), so after warm-up the length never changes: about 10 ms more a question at a steady length, and no more 0.4-1 s switches. `MU_LOCAL_JUDGE_MIN_LENGTH=256` brings the shorter buckets back. Warm-up skips the lengths no request can reach and no longer logs `warm-up for length 16 failed: StopIteration`.
89
+
90
+ ## [0.1.12] - 2026-10-22
91
+
92
+ ### Added
93
+
94
+ - A long-thinking watchdog: a reply that has only been thinking for 10 minutes, with no text and no tool call yet, is cut and asked again at the same reasoning effort, with the end of its reasoning so far and a request to act on it first. The retry is never cut. At most 3 cuts per message (`features.watchdog`: `thinkingMs`, `maxCuts`).
95
+ - `mu import` reads ZCode conversations too (`~/.zcode/cli/db/db.sqlite`), beside Claude Code and Codex, with rewinds, compactions, sub-agent threads and forks.
96
+ - Imported conversations keep their whole history: thinking (shown, never sent to the new model) and images, as well as messages and tool calls. A Claude Code conversation keeps the title Claude Code shows for it.
97
+ - Importing a conversation again brings over what's new in it, into the same conversation; if you also went on in mu, the new import is a conversation of its own. `mu import --list` marks conversations that changed since.
98
+
99
+ ### Changed
100
+
101
+ - The permission mode `jev` ("Jev approves") is now `judge` ("Judge mode"): `/permissions full | judge | ask`, `MU_PERMISSIONS=judge`. A saved `jev` falls back to the default, which is judge mode. The kernel's and the command line's messages say "the judge" where they meant mu's judge in general, and keep "Jev" for TypeSafe's hosted model.
102
+ - Background jobs started with `bg_start` keep running after an unattended run (`mu --print`, json mode) ends, so a server a task asked for is still up afterwards. Such jobs write to their log file instead of a pipe to mu. Interactive and desktop sessions still stop their jobs at the end (`features.background.keepOnExit`: `headless`, `always` or `never`).
103
+ - A failed model request is retried up to 8 times instead of 3 (`retry.maxRetries`). With the 60-second cap on each wait, a provider that stops answering for about four minutes no longer ends the run.
104
+
105
+ ### Fixed
106
+
107
+ - A run that ended on a reply with only thinking in it, no text and no tool call, stopped there without a word. mu now sends the agent back to the task, up to the same limit as its other nudges.
108
+ - A reply cut by the provider's content filter (`finish_reason: content_filter`) ended the run. It is now asked again, twice at most.
109
+ - A Claude Code conversation compacted more than once is imported whole; before, the import stopped at the latest compaction.
110
+ - An imported conversation goes on with mu's model, not the one Claude Code, Codex or ZCode answered with, so `mu` no longer warns that it can't restore that model.
111
+
112
+ ## [0.1.11] - 2026-10-21
113
+
114
+ ### Changed
115
+
116
+ - The package's keywords add `pi-coding-agent`, `mcp` and `prompt-injection`, so directories that index pi coding agents and MCP clients find it.
117
+ - English: a copy edit of what the command line and the kernel show, after `docs/writing-style.md`: "subagent" as one word, "canceled", "session" for what is allowed until the session ends ("Allow for this session"), and clearer wording in `mu setup`, `/browse`, the board's account and the settings' help. The `/browse` hint names `mu.json`, not `kyrn.json`. The Chinese text is unchanged.
118
+
119
+ ### Fixed
120
+
121
+ - With a Jev key (TypeSafe), the welcome screen and each verdict line name the judge `Jev`, not its model id `jev-latest`. A versioned Jev on OpenCode Zen shows as `Jev 1.13`.
122
+ - `/hive <question>` shows what you typed in the chat and as the conversation's title. The request to start a hive at once, written for the model in English, goes with it as a message only the model reads; before, it filled your message, also in a Chinese session. A `/hive` sent while a turn runs still sends the request as its message.
123
+ - The footer's line after each message reads like the verdict line, `Jev: multi-step task · full effort · 71 ms`, instead of `jev-latest active: multi_step_task -> heavy 71ms`. A verdict in shadow mode ends with `recorded only`.
124
+ - `planHost` names the script the command line runs pi with (`cli`: `dist/bundle/cli.js` in the package, `packages/coding-agent/src/cli.ts` in a checkout). The desktop app's host hands it to pi as `process.argv[1]`, so the sub-agents pi starts by running that script again (`hive`, `delegate`, the swarm) no longer fail with "The mu host needs a parent".
125
+ - With no model connected, `mu -p` and the other no-key errors now say to run `mu setup`, instead of pointing to `/login` (which only exists inside a session) and two files inside the package.
126
+
5
127
  ## [0.1.10] - 2026-10-21
6
128
 
7
129
  ### Changed
package/README.md CHANGED
@@ -13,7 +13,7 @@ mu
13
13
 
14
14
  You need Node.js 22.19 or newer. The package is `mu-agent`; the command is `mu`. It runs on macOS, Linux, Windows and WSL.
15
15
 
16
- `mu setup` connects a model from your shell. Paste an API key and mu detects the service from the key's format (DeepSeek, Qwen, Kimi, GLM, SiliconFlow, StepFun, OpenRouter, OpenCode Zen, OpenAI, Anthropic, Google Gemini, xAI), or pick Ollama or your own endpoint. It checks the key with one request, picks a starting model and sets up the judge. If no model is set up yet, the first `mu` run offers to start setup.
16
+ `mu setup` connects a model from your shell. Paste an API key and mu detects the service from the key's format (OpenAI, Anthropic, Google Gemini, xAI, OpenRouter, OpenCode Zen, DeepSeek, Qwen, Kimi, GLM, SiliconFlow, StepFun), or pick Ollama or your own endpoint. It checks the key with one request, picks a starting model and sets up the judge. To use a ChatGPT, Grok or Google subscription instead, choose it there and mu starts on `/login`. If no model is set up yet, the first `mu` run offers to start setup.
17
17
 
18
18
  Inside mu, `/login` signs in to a provider or a subscription and `/model` switches models. `/help` lists everything. `mu doctor` checks your setup from the shell.
19
19
 
@@ -23,19 +23,19 @@ mu is built on [pi](https://github.com/earendil-works/pi). It hands the small qu
23
23
 
24
24
  - **Every decision is visible.** Each decision point is `off`, `shadow` (asked and logged, but not acted on) or `active`. `/ledger` and `mu ledger` show the verdicts.
25
25
  - **Every decision has a fallback.** When the judge is unsure, slow or unreachable, a plain rule decides, or pi's default behavior runs. For approvals, the fallback is to ask you.
26
- - **And more:** a task frame that keeps your constraints in your own words, three permission modes (`/permissions`), goal mode (`/goal`), a plain-language progress board (`/board`), checkpoints and `/rewind`, subagents that edit in their own git worktrees (`delegate`), read-only hives of investigators (`hive`), a judge-driven browser (`browse`), and the rules, skills and MCP servers you already set up in Claude Code, Cursor and Codex.
26
+ - **And more:** a task frame that keeps your constraints in your own words, three permission modes (`/permissions`), goal mode (`/goal`), a plain-language progress board (`/board`), checkpoints and `/rewind`, subagents that edit in their own git worktrees (`delegate`), read-only hives of investigators (`hive`), a judge-driven browser (`browse`), and it picks up the rules, skills and MCP servers you already set up in Claude Code, Cursor and Codex.
27
27
 
28
28
  ## Choose a judge
29
29
 
30
- Out of the box, Jev 1.13 on OpenCode Zen answers for free (for a limited time) and needs no key. What it judges goes to OpenCode, which doesn't train on it, and mu reminds you of that once a day. To send nothing anywhere, start mu with `MU_JUDGE=off`, or use the local judge, Laya.
30
+ Out of the box, the judge is Jev 1.13, TypeSafe's hosted judge model, free on OpenCode Zen for a limited time and with no key needed. What it judges goes to OpenCode, which doesn't train on it, and mu reminds you of that once a day. To send nothing anywhere, run `mu setup --judge off` (or choose "Not now" when `mu setup` asks): no decision point asks a judge, and mu's features keep working on their rules. Or use the local judge, Laya.
31
31
 
32
- - **Jev** (hosted): set `TYPESAFE_API_KEY` (TypeSafe), `MU_JUDGE_OPENROUTER_API_KEY` (Jev on OpenRouter), `AI_GATEWAY_API_KEY` (Vercel AI Gateway), `OPENCODE_API_KEY` (OpenCode Zen) or `CLOUDFLARE_API_KEY` with `CLOUDFLARE_ACCOUNT_ID` (Cloudflare Workers AI) in your environment, or add it to `~/.mu/.env` as `KEY=value`. `mu setup` asks for a key and writes it there. mu reads that file as data and never prints it, and starts using the key automatically.
32
+ - **Jev** (hosted): set `TYPESAFE_API_KEY` (TypeSafe), `MU_JUDGE_OPENROUTER_API_KEY` (Jev on OpenRouter), `AI_GATEWAY_API_KEY` (Vercel AI Gateway), `OPENCODE_API_KEY` (OpenCode Zen) or `CLOUDFLARE_API_KEY` with `CLOUDFLARE_ACCOUNT_ID` (Cloudflare Workers AI) in your environment, or add it to `~/.mu/.env` as `KEY=value`. `mu setup` asks for a key and writes it there. mu reads that file as data, never prints it and starts using the key automatically.
33
33
  - **Another classifier** from pi's catalog: `/mu judge classifier:<provider>/<model>`, for example Cloudflare's Clef (`clef`, `clef-flash`) or a System One model on OpenRouter, with that provider's key.
34
34
  - **CLM** (self-hosted; its encoder needs a GPU): start `clm-serve` from [Contrastive-LM/CLM](https://github.com/Contrastive-LM/CLM), then run `/mu judge clm`. For a server on another machine, add `"judges": { "clm": { "type": "clm", "baseUrl": "http://<host>:8700" } }` to `~/.mu/agent/mu.json`. If the server was started with `CLM_API_KEY`, set the same value in `MU_JUDGE_CLM_API_KEY`. `mu doctor` checks the server.
35
35
  - **Laya** (local, macOS on Apple silicon): `mu judge setup` installs it into `~/.mu/local-judge`. It downloads about 930 MB, and only when you run that command.
36
36
  - **Any model you already use:** `/mu judge llm:<provider>/<model>`.
37
37
 
38
- 38 of the 40 decision points act on their verdicts from the start (`active`); `context.compact` and `output.drift` belong to features that are off until you turn them on. To only record what the judge would do, run `/mu mode default shadow`, or put `"modes": { "default": "shadow" }` in `~/.mu/agent/mu.json`.
38
+ 33 of the 40 decision points act on their verdicts from the start (`active`); `context.compact` and `output.drift` belong to features that are off until you turn them on, `capability.disclosure` and `swarm.patch` are `off`, and `notify.routing`, `input.interjection` and `turn.drift` are in `shadow`. To only record what the judge would do, run `/mu mode default shadow`, or put `"modes": { "default": "shadow" }` in `~/.mu/agent/mu.json`.
39
39
 
40
40
  ## Commands
41
41
 
@@ -47,7 +47,7 @@ mu -c | -r continue the last session | pick a session to resume
47
47
  mu setup connect a model and choose a judge (see mu setup --help for scripting and services)
48
48
  mu judge <cmd> manage the local judge, Laya (macOS on Apple silicon): setup | start | stop | status | run
49
49
  mu ledger [n] [--json] print the judge's verdicts from the last n sessions
50
- mu import --list | <file>... import Claude Code and Codex conversations (mu import --help)
50
+ mu import <file>... import Claude Code, Codex and ZCode conversations; --list shows them (mu import --help)
51
51
  mu doctor check the installation, the judges and the connections
52
52
  mu auth <cmd> sign-in helper for the desktop app: status | login | logout
53
53
  mu link | unlink put the mu command on your PATH | remove it
@@ -58,7 +58,7 @@ Everything else goes to pi unchanged: `mu --help` also shows pi's options. mu ke
58
58
 
59
59
  ## Themes
60
60
 
61
- In the terminal, mu starts in its own themes, `mu-dark` or `mu-light` to match your terminal, until you pick a theme in `/settings`. Choose `system` there to use your terminal's own palette.
61
+ In the terminal, mu uses its own themes, `mu-dark` or `mu-light` to match your terminal, until you pick a theme in `/settings`. Choose `system` there to use your terminal's own palette.
62
62
 
63
63
  ## Update and remove
64
64
 
@@ -1,4 +1,4 @@
1
1
  import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url);
2
- import{mcpNamespace,require_proper_lockfile,validateMcpServerConfig}from"./chunk-SGOTYFMT.js";import{CONFIG_DIR_NAME,canonicalizePath,resolvePath,stripBom}from"./chunk-BSS6T6KQ.js";import{__toESM}from"./chunk-JXWJOIH4.js";var import_proper_lockfile=__toESM(require_proper_lockfile(),1);import{existsSync,mkdirSync,readFileSync,writeFileSync}from"node:fs";import{homedir}from"node:os";import{dirname,join}from"node:path";var TRUST_REQUIRING_PROJECT_CONFIG_RESOURCES=["settings.json","mcp.json","extensions","skills","prompts","themes","SYSTEM.md","APPEND_SYSTEM.md"];function normalizeCwd(cwd){return canonicalizePath(resolvePath(cwd))}function findNearestTrustEntry(data,cwd){let currentDir=normalizeCwd(cwd);for(;;){let value=data[currentDir];if(value===!0||value===!1)return{path:currentDir,decision:value};let parentDir=dirname(currentDir);if(parentDir===currentDir)return null;currentDir=parentDir}}function getProjectTrustParentPath(cwd){let trustPath=normalizeCwd(cwd),parentDir=dirname(trustPath);return parentDir===trustPath?void 0:parentDir}function getProjectTrustOptions(cwd,options){let trustPath=normalizeCwd(cwd),trustOptions=[{label:"Trust",trusted:!0,updates:[{path:trustPath,decision:!0}],savedPath:trustPath}],parentPath=getProjectTrustParentPath(cwd);return parentPath!==void 0&&trustOptions.push({label:`Trust parent folder (${parentPath})`,trusted:!0,updates:[{path:parentPath,decision:!0},{path:trustPath,decision:null}],savedPath:parentPath}),options?.includeSessionOnly&&trustOptions.push({label:"Trust (this session only)",trusted:!0,updates:[]}),trustOptions.push({label:"Do not trust",trusted:!1,updates:[{path:trustPath,decision:!1}],savedPath:trustPath}),options?.includeSessionOnly&&trustOptions.push({label:"Do not trust (this session only)",trusted:!1,updates:[]}),trustOptions}function readTrustFile(path){if(!existsSync(path))return{};let parsed;try{parsed=JSON.parse(stripBom(readFileSync(path,"utf-8")))}catch(error){let message=error instanceof Error?error.message:String(error);throw new Error(`Failed to read trust store ${path}: ${message}`)}if(typeof parsed!="object"||parsed===null||Array.isArray(parsed))throw new Error(`Invalid trust store ${path}: expected an object`);let data={};for(let[key,value]of Object.entries(parsed)){if(value!==!0&&value!==!1&&value!==null)throw new Error(`Invalid trust store ${path}: value for ${JSON.stringify(key)} must be true, false, or null`);data[key]=value}return data}function writeTrustFile(path,data){let sorted={};for(let key of Object.keys(data).sort()){let value=data[key];(value===!0||value===!1||value===null)&&(sorted[key]=value)}mkdirSync(dirname(path),{recursive:!0}),writeFileSync(path,`${JSON.stringify(sorted,null,2)}
2
+ import{mcpNamespace,require_proper_lockfile,validateMcpServerConfig}from"./chunk-MF3VB62R.js";import{CONFIG_DIR_NAME,canonicalizePath,resolvePath,stripBom}from"./chunk-LHRPMXVI.js";import{__toESM}from"./chunk-JXWJOIH4.js";var import_proper_lockfile=__toESM(require_proper_lockfile(),1);import{existsSync,mkdirSync,readFileSync,writeFileSync}from"node:fs";import{homedir}from"node:os";import{dirname,join}from"node:path";var TRUST_REQUIRING_PROJECT_CONFIG_RESOURCES=["settings.json","mcp.json","extensions","skills","prompts","themes","SYSTEM.md","APPEND_SYSTEM.md"];function normalizeCwd(cwd){return canonicalizePath(resolvePath(cwd))}function findNearestTrustEntry(data,cwd){let currentDir=normalizeCwd(cwd);for(;;){let value=data[currentDir];if(value===!0||value===!1)return{path:currentDir,decision:value};let parentDir=dirname(currentDir);if(parentDir===currentDir)return null;currentDir=parentDir}}function getProjectTrustParentPath(cwd){let trustPath=normalizeCwd(cwd),parentDir=dirname(trustPath);return parentDir===trustPath?void 0:parentDir}function getProjectTrustOptions(cwd,options){let trustPath=normalizeCwd(cwd),trustOptions=[{label:"Trust",trusted:!0,updates:[{path:trustPath,decision:!0}],savedPath:trustPath}],parentPath=getProjectTrustParentPath(cwd);return parentPath!==void 0&&trustOptions.push({label:`Trust parent folder (${parentPath})`,trusted:!0,updates:[{path:parentPath,decision:!0},{path:trustPath,decision:null}],savedPath:parentPath}),options?.includeSessionOnly&&trustOptions.push({label:"Trust (this session only)",trusted:!0,updates:[]}),trustOptions.push({label:"Do not trust",trusted:!1,updates:[{path:trustPath,decision:!1}],savedPath:trustPath}),options?.includeSessionOnly&&trustOptions.push({label:"Do not trust (this session only)",trusted:!1,updates:[]}),trustOptions}function readTrustFile(path){if(!existsSync(path))return{};let parsed;try{parsed=JSON.parse(stripBom(readFileSync(path,"utf-8")))}catch(error){let message=error instanceof Error?error.message:String(error);throw new Error(`Failed to read trust store ${path}: ${message}`)}if(typeof parsed!="object"||parsed===null||Array.isArray(parsed))throw new Error(`Invalid trust store ${path}: expected an object`);let data={};for(let[key,value]of Object.entries(parsed)){if(value!==!0&&value!==!1&&value!==null)throw new Error(`Invalid trust store ${path}: value for ${JSON.stringify(key)} must be true, false, or null`);data[key]=value}return data}function writeTrustFile(path,data){let sorted={};for(let key of Object.keys(data).sort()){let value=data[key];(value===!0||value===!1||value===null)&&(sorted[key]=value)}mkdirSync(dirname(path),{recursive:!0}),writeFileSync(path,`${JSON.stringify(sorted,null,2)}
3
3
  `,"utf-8")}function acquireTrustLockSync(path){let trustDir=dirname(path);mkdirSync(trustDir,{recursive:!0});let maxAttempts=10,delayMs=20,lastError;for(let attempt=1;attempt<=maxAttempts;attempt++)try{return import_proper_lockfile.default.lockSync(trustDir,{realpath:!1,lockfilePath:`${path}.lock`})}catch(error){if((typeof error=="object"&&error!==null&&"code"in error?String(error.code):void 0)!=="ELOCKED"||attempt===maxAttempts)throw error;lastError=error;let start=Date.now();for(;Date.now()-start<delayMs;);}throw lastError instanceof Error?lastError:new Error("Failed to acquire trust store lock")}function withTrustFileLock(path,fn){let release=acquireTrustLockSync(path);try{return fn()}finally{release()}}function hasTrustRequiringProjectResources(cwd){let homeDir=canonicalizePath(resolvePath(process.env.HOME||homedir())),userAgentsSkillsDir=join(homeDir,".agents","skills"),currentDir=canonicalizePath(resolvePath(cwd)),configDir=join(currentDir,CONFIG_DIR_NAME);if(TRUST_REQUIRING_PROJECT_CONFIG_RESOURCES.some(entry=>existsSync(join(configDir,entry))))return!0;for(;;){let agentsSkillsDir=join(currentDir,".agents","skills");if(agentsSkillsDir!==userAgentsSkillsDir&&existsSync(agentsSkillsDir))return!0;let parentDir=dirname(currentDir);if(parentDir===currentDir)return!1;currentDir=parentDir}}var ProjectTrustStore=class{trustPath;constructor(agentDir){this.trustPath=join(resolvePath(agentDir),"trust.json")}get(cwd){return this.getEntry(cwd)?.decision??null}getEntry(cwd){return withTrustFileLock(this.trustPath,()=>{let data=readTrustFile(this.trustPath);return findNearestTrustEntry(data,cwd)})}set(cwd,decision){this.setMany([{path:cwd,decision}])}setMany(decisions){withTrustFileLock(this.trustPath,()=>{let data=readTrustFile(this.trustPath);for(let{path,decision}of decisions){let key=normalizeCwd(path);decision===null?delete data[key]:data[key]=decision}writeTrustFile(this.trustPath,data)})}};import{existsSync as existsSync2,mkdirSync as mkdirSync2,readFileSync as readFileSync2,writeFileSync as writeFileSync2}from"node:fs";import{dirname as dirname2,join as join2}from"node:path";var OVERRIDE_KEYS=["enabled","exposure","toolExposure"];function isOverride(value){return value.command===void 0&&value.url===void 0&&value.type===void 0}function isRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function readConfigFile(path,scope,state){let{servers,errors}=state;if(!existsSync2(path))return;let parsed;try{parsed=JSON.parse(readFileSync2(path,"utf8"))}catch(error){errors.push(`${path}: ${error instanceof Error?error.message:String(error)}`);return}if(!isRecord(parsed)||parsed.mcpServers!==void 0&&!isRecord(parsed.mcpServers)){errors.push(`${path}: expected an object with an "mcpServers" object`);return}typeof parsed.autoEnableCodemode=="boolean"?state.autoEnableCodemode=parsed.autoEnableCodemode:parsed.autoEnableCodemode!==void 0&&errors.push(`${path}: autoEnableCodemode must be a boolean`);for(let[name,value]of Object.entries(parsed.mcpServers??{})){if(scope==="project"&&isRecord(value)&&isOverride(value)){let base=servers.get(name),extra=Object.keys(value).filter(key=>!OVERRIDE_KEYS.includes(key));if(!base)errors.push(`${path}: server "${name}" needs "command" or "url", or a global server to override`);else if(extra.length>0)errors.push(`${path}: server "${name}": an override can only set ${OVERRIDE_KEYS.join(", ")}`);else{let config2=validateMcpServerConfig(name,{...base.config,...value});typeof config2=="string"?errors.push(`${path}: ${config2}`):servers.set(name,{...base,config:config2,override:path})}continue}let config=validateMcpServerConfig(name,value);if(typeof config=="string"){errors.push(`${path}: ${config}`);continue}let clash=[...servers.keys()].find(other=>other!==name&&mcpNamespace(other)===mcpNamespace(name));if(clash){errors.push(`${path}: server "${name}" conflicts with "${clash}"`);continue}if(scope==="project"&&"url"in config&&config.auth){errors.push(`${path}: server "${name}": auth is only allowed in the global mcp.json`);continue}servers.set(name,{name,config,source:path,scope})}}function loadMcpConfig(options){let state={servers:new Map,errors:[]};readConfigFile(join2(options.agentDir,"mcp.json"),"global",state);let projectConfig=options.projectTrusted?join2(options.cwd,CONFIG_DIR_NAME,"mcp.json"):void 0;return projectConfig&&readConfigFile(projectConfig,"project",state),{servers:[...state.servers.values()],...state.autoEnableCodemode===void 0?{}:{autoEnableCodemode:state.autoEnableCodemode},errors:state.errors,...projectConfig?{projectConfig}:{}}}function updateMcpServerConfig(path,name,patch,options={}){editMcpServers(path,(servers,parsed)=>{let server=servers?.[name];if(server===void 0&&options.override&&(server={},parsed.mcpServers={...servers,[name]:server}),!isRecord(server))throw new Error(`${path} does not define MCP server "${name}"`);let keepDefaults=isOverride(server);return patch.enabled!==void 0&&(patch.enabled&&!keepDefaults?delete server.enabled:server.enabled=patch.enabled),patch.exposure!==void 0&&(patch.exposure==="codemode"&&!keepDefaults?delete server.exposure:server.exposure=patch.exposure),!0})}function addMcpServerConfig(path,name,config){let replaced=!1;return editMcpServers(path,(servers,parsed)=>{let target=servers??{};return replaced=target[name]!==void 0,target[name]=config,parsed.mcpServers=target,!0}),replaced}function removeMcpServerConfig(path,name){if(!existsSync2(path))return!1;let removed=!1;return editMcpServers(path,servers=>!servers||servers[name]===void 0?!1:(delete servers[name],removed=!0,!0)),removed}function editMcpServers(path,edit){let text=existsSync2(path)?readFileSync2(path,"utf8"):void 0,parsed=text===void 0?{}:JSON.parse(text);if(!isRecord(parsed)||parsed.mcpServers!==void 0&&!isRecord(parsed.mcpServers))throw new Error(`${path}: expected an object with an "mcpServers" object`);let servers=isRecord(parsed.mcpServers)?parsed.mcpServers:void 0;if(!edit(servers,parsed))return;let indent=text&&/^([ \t]+)\S/m.exec(text)?.[1]||" ";mkdirSync2(dirname2(path),{recursive:!0}),writeFileSync2(path,`${JSON.stringify(parsed,null,indent)}
4
4
  `)}import{spawn}from"node:child_process";function openBrowser(target){let[cmd,args]=process.platform==="darwin"?["open",[target]]:process.platform==="win32"?["rundll32",["url.dll,FileProtocolHandler",target]]:["xdg-open",[target]];spawn(cmd,args,{stdio:"ignore",detached:!0}).on("error",()=>{}).unref()}export{getProjectTrustOptions,hasTrustRequiringProjectResources,ProjectTrustStore,loadMcpConfig,updateMcpServerConfig,addMcpServerConfig,removeMcpServerConfig,openBrowser};
@@ -1,2 +1,2 @@
1
1
  import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url);
2
- import{AgentSession,AgentSessionRuntime,AssistantMessageComponent,BashExecutionComponent,BorderedLoader,BranchSummaryMessageComponent,CURRENT_SESSION_VERSION,CompactionSummaryMessageComponent,CredentialSynchronizationError,CustomEditor,CustomMessageComponent,DEFAULT_COMPACTION_SETTINGS,DefaultPackageManager,DefaultResourceLoader,DynamicBorder,ExtensionEditorComponent,ExtensionInputComponent,ExtensionRunner,ExtensionSelectorComponent,FooterComponent,InteractiveMode,LoginDialogComponent,MCP_CONNECTION_EVENT,ModelRegistry,ModelRuntime,ModelSelectorComponent,OAuthSelectorComponent,RpcClient,SessionManager,SessionSelectorComponent,SettingsManager,SettingsSelectorComponent,SkillInvocationMessageComponent,ThinkingSelectorComponent,ToolExecutionComponent,TreeSelectorComponent,UserMessageComponent,UserMessageSelectorComponent,VIRTUAL_MODEL_STATE_ENTRY,applyHttpProxySettings,buildContextEntries,buildSessionContext,buildSessionProjection,calculateContextTokens,collectEntriesForBranchSummary,compact,configureHttpDispatcher,convertToLlm,convertToPng,copyToClipboard,createAgentSession,createAgentSessionFromServices,createAgentSessionRuntime,createAgentSessionServices,createBashTool,createBashToolDefinition,createCodemodeExtension,createCodingTools,createEditTool,createEditToolDefinition,createEventBus,createExtensionRuntime,createFindTool,createFindToolDefinition,createGrepTool,createGrepToolDefinition,createLocalBashOperations,createLocalPowerShellOperations,createLsTool,createLsToolDefinition,createMcpExtension,createPowerShellTool,createPowerShellToolDefinition,createReadOnlyTools,createReadTool,createReadToolDefinition,createSyntheticSourceInfo,createToolSearchExtension,createWriteTool,createWriteToolDefinition,defaultModelPerProvider,defineTool,detectSupportedImageMimeTypeFromFile,discoverAndLoadExtensions,estimateTokens,findCutPoint,findTurnStartIndex,formatDimensionNote,formatSkillsForPrompt,generateBranchSummary,generateDiffString,generateSummary,generateSummaryWithUsage,generateUnifiedPatch,getLastAssistantUsage,getLatestCompactionEntry,isBashToolResult,isEditToolResult,isFindToolResult,isGrepToolResult,isLsToolResult,isPowerShellToolResult,isReadToolResult,isToolCallEventType,isWriteToolResult,loadProjectContextFiles,loadSkills,loadSkillsFromDir,main,migrateSessionEntries,parseArgs,parseFrontmatter,parseSessionEntries,parseSkillBlock,prepareBranchEntries,renderDiff,resizeImage,resolveCliModel,resolveModelScopeWithDiagnostics,runPrintMode,runRpcMode,serializeConversation,sessionEntryToContextMessages,setupCli,shouldCompact,stdioRpcTransport,stripFrontmatter,withFileMutationQueue,wrapRegisteredTool,wrapRegisteredTools}from"./chunk-O7IPTASE.js";import{DEFAULT_MAX_BYTES,DEFAULT_MAX_LINES,formatReadLineRange,formatSize,truncateHead,truncateLine,truncateTail,truncateToVisualLines}from"./chunk-X234222Q.js";import{ArminComponent}from"./chunk-RAQ6TU76.js";import{Container,SelectList,Theme,getAvailableThemes,getLanguageFromPath,getMarkdownTheme,getSelectListTheme,getSettingsListTheme,highlightCode,initTheme,keyHint,keyText,rawKeyHint}from"./chunk-HZNN636Z.js";import{ProjectTrustStore,hasTrustRequiringProjectResources,loadMcpConfig}from"./chunk-DNNHZBQR.js";import{readStoredCredential}from"./chunk-SGOTYFMT.js";import{getPowerShellConfig,getShellConfig}from"./chunk-QOEEJKS4.js";import{CONFIG_DIR_NAME,VERSION,getAgentDir,getDocsPath,getExamplesPath,getPackageDir,getReadmePath}from"./chunk-BSS6T6KQ.js";import{__export}from"./chunk-JXWJOIH4.js";var dist_exports={};__export(dist_exports,{AgentSession:()=>AgentSession,AgentSessionRuntime:()=>AgentSessionRuntime,ArminComponent:()=>ArminComponent,AssistantMessageComponent:()=>AssistantMessageComponent,BashExecutionComponent:()=>BashExecutionComponent,BorderedLoader:()=>BorderedLoader,BranchSummaryMessageComponent:()=>BranchSummaryMessageComponent,CONFIG_DIR_NAME:()=>CONFIG_DIR_NAME,CURRENT_SESSION_VERSION:()=>CURRENT_SESSION_VERSION,CompactionSummaryMessageComponent:()=>CompactionSummaryMessageComponent,CredentialSynchronizationError:()=>CredentialSynchronizationError,CustomEditor:()=>CustomEditor,CustomMessageComponent:()=>CustomMessageComponent,DEFAULT_COMPACTION_SETTINGS:()=>DEFAULT_COMPACTION_SETTINGS,DEFAULT_MAX_BYTES:()=>DEFAULT_MAX_BYTES,DEFAULT_MAX_LINES:()=>DEFAULT_MAX_LINES,DefaultPackageManager:()=>DefaultPackageManager,DefaultResourceLoader:()=>DefaultResourceLoader,DynamicBorder:()=>DynamicBorder,ExtensionEditorComponent:()=>ExtensionEditorComponent,ExtensionInputComponent:()=>ExtensionInputComponent,ExtensionRunner:()=>ExtensionRunner,ExtensionSelectorComponent:()=>ExtensionSelectorComponent,FooterComponent:()=>FooterComponent,InteractiveMode:()=>InteractiveMode,LoginDialogComponent:()=>LoginDialogComponent,MCP_CONNECTION_EVENT:()=>MCP_CONNECTION_EVENT,ModelRegistry:()=>ModelRegistry,ModelRuntime:()=>ModelRuntime,ModelSelectorComponent:()=>ModelSelectorComponent,OAuthSelectorComponent:()=>OAuthSelectorComponent,ProjectTrustStore:()=>ProjectTrustStore,RpcClient:()=>RpcClient,SessionManager:()=>SessionManager,SessionSelectorComponent:()=>SessionSelectorComponent,SettingsManager:()=>SettingsManager,SettingsSelectorComponent:()=>SettingsSelectorComponent,ShowImagesSelectorComponent:()=>ShowImagesSelectorComponent,SkillInvocationMessageComponent:()=>SkillInvocationMessageComponent,Theme:()=>Theme,ThemeSelectorComponent:()=>ThemeSelectorComponent,ThinkingSelectorComponent:()=>ThinkingSelectorComponent,ToolExecutionComponent:()=>ToolExecutionComponent,TreeSelectorComponent:()=>TreeSelectorComponent,UserMessageComponent:()=>UserMessageComponent,UserMessageSelectorComponent:()=>UserMessageSelectorComponent,VERSION:()=>VERSION,VIRTUAL_MODEL_STATE_ENTRY:()=>VIRTUAL_MODEL_STATE_ENTRY,applyHttpProxySettings:()=>applyHttpProxySettings,buildContextEntries:()=>buildContextEntries,buildSessionContext:()=>buildSessionContext,buildSessionProjection:()=>buildSessionProjection,calculateContextTokens:()=>calculateContextTokens,collectEntriesForBranchSummary:()=>collectEntriesForBranchSummary,compact:()=>compact,configureHttpDispatcher:()=>configureHttpDispatcher,convertToLlm:()=>convertToLlm,convertToPng:()=>convertToPng,copyToClipboard:()=>copyToClipboard,createAgentSession:()=>createAgentSession,createAgentSessionFromServices:()=>createAgentSessionFromServices,createAgentSessionRuntime:()=>createAgentSessionRuntime,createAgentSessionServices:()=>createAgentSessionServices,createBashTool:()=>createBashTool,createBashToolDefinition:()=>createBashToolDefinition,createCodemodeExtension:()=>createCodemodeExtension,createCodingTools:()=>createCodingTools,createEditTool:()=>createEditTool,createEditToolDefinition:()=>createEditToolDefinition,createEventBus:()=>createEventBus,createExtensionRuntime:()=>createExtensionRuntime,createFindTool:()=>createFindTool,createFindToolDefinition:()=>createFindToolDefinition,createGrepTool:()=>createGrepTool,createGrepToolDefinition:()=>createGrepToolDefinition,createLocalBashOperations:()=>createLocalBashOperations,createLocalPowerShellOperations:()=>createLocalPowerShellOperations,createLsTool:()=>createLsTool,createLsToolDefinition:()=>createLsToolDefinition,createMcpExtension:()=>createMcpExtension,createPowerShellTool:()=>createPowerShellTool,createPowerShellToolDefinition:()=>createPowerShellToolDefinition,createReadOnlyTools:()=>createReadOnlyTools,createReadTool:()=>createReadTool,createReadToolDefinition:()=>createReadToolDefinition,createSyntheticSourceInfo:()=>createSyntheticSourceInfo,createToolSearchExtension:()=>createToolSearchExtension,createWriteTool:()=>createWriteTool,createWriteToolDefinition:()=>createWriteToolDefinition,defaultModelPerProvider:()=>defaultModelPerProvider,defineTool:()=>defineTool,detectSupportedImageMimeTypeFromFile:()=>detectSupportedImageMimeTypeFromFile,discoverAndLoadExtensions:()=>discoverAndLoadExtensions,estimateTokens:()=>estimateTokens,findCutPoint:()=>findCutPoint,findTurnStartIndex:()=>findTurnStartIndex,formatDimensionNote:()=>formatDimensionNote,formatReadLineRange:()=>formatReadLineRange,formatSize:()=>formatSize,formatSkillsForPrompt:()=>formatSkillsForPrompt,generateBranchSummary:()=>generateBranchSummary,generateDiffString:()=>generateDiffString,generateSummary:()=>generateSummary,generateSummaryWithUsage:()=>generateSummaryWithUsage,generateUnifiedPatch:()=>generateUnifiedPatch,getAgentDir:()=>getAgentDir,getDocsPath:()=>getDocsPath,getExamplesPath:()=>getExamplesPath,getLanguageFromPath:()=>getLanguageFromPath,getLastAssistantUsage:()=>getLastAssistantUsage,getLatestCompactionEntry:()=>getLatestCompactionEntry,getMarkdownTheme:()=>getMarkdownTheme,getPackageDir:()=>getPackageDir,getPowerShellConfig:()=>getPowerShellConfig,getReadmePath:()=>getReadmePath,getSelectListTheme:()=>getSelectListTheme,getSettingsListTheme:()=>getSettingsListTheme,getShellConfig:()=>getShellConfig,hasTrustRequiringProjectResources:()=>hasTrustRequiringProjectResources,highlightCode:()=>highlightCode,initTheme:()=>initTheme,isBashToolResult:()=>isBashToolResult,isEditToolResult:()=>isEditToolResult,isFindToolResult:()=>isFindToolResult,isGrepToolResult:()=>isGrepToolResult,isLsToolResult:()=>isLsToolResult,isPowerShellToolResult:()=>isPowerShellToolResult,isReadToolResult:()=>isReadToolResult,isToolCallEventType:()=>isToolCallEventType,isWriteToolResult:()=>isWriteToolResult,keyHint:()=>keyHint,keyText:()=>keyText,loadMcpConfig:()=>loadMcpConfig,loadProjectContextFiles:()=>loadProjectContextFiles,loadSkills:()=>loadSkills,loadSkillsFromDir:()=>loadSkillsFromDir,main:()=>main,migrateSessionEntries:()=>migrateSessionEntries,parseArgs:()=>parseArgs,parseFrontmatter:()=>parseFrontmatter,parseSessionEntries:()=>parseSessionEntries,parseSkillBlock:()=>parseSkillBlock,prepareBranchEntries:()=>prepareBranchEntries,rawKeyHint:()=>rawKeyHint,readStoredCredential:()=>readStoredCredential,renderDiff:()=>renderDiff,resizeImage:()=>resizeImage,resolveCliModel:()=>resolveCliModel,resolveModelScopeWithDiagnostics:()=>resolveModelScopeWithDiagnostics,runPrintMode:()=>runPrintMode,runRpcMode:()=>runRpcMode,serializeConversation:()=>serializeConversation,sessionEntryToContextMessages:()=>sessionEntryToContextMessages,setupCli:()=>setupCli,shouldCompact:()=>shouldCompact,stdioRpcTransport:()=>stdioRpcTransport,stripFrontmatter:()=>stripFrontmatter,truncateHead:()=>truncateHead,truncateLine:()=>truncateLine,truncateTail:()=>truncateTail,truncateToVisualLines:()=>truncateToVisualLines,withFileMutationQueue:()=>withFileMutationQueue,wrapRegisteredTool:()=>wrapRegisteredTool,wrapRegisteredTools:()=>wrapRegisteredTools});var SHOW_IMAGES_SELECT_LIST_LAYOUT={minPrimaryColumnWidth:12,maxPrimaryColumnWidth:32},ShowImagesSelectorComponent=class extends Container{selectList;constructor(currentValue,onSelect,onCancel){super();let items=[{value:"yes",label:"Yes",description:"Show images inline in terminal"},{value:"no",label:"No",description:"Show text placeholder instead"}];this.addChild(new DynamicBorder),this.selectList=new SelectList(items,5,getSelectListTheme(),SHOW_IMAGES_SELECT_LIST_LAYOUT),this.selectList.setSelectedIndex(currentValue?0:1),this.selectList.onSelect=item=>{onSelect(item.value==="yes")},this.selectList.onCancel=()=>{onCancel()},this.addChild(this.selectList),this.addChild(new DynamicBorder)}getSelectList(){return this.selectList}};var THEME_SELECT_LIST_LAYOUT={minPrimaryColumnWidth:12,maxPrimaryColumnWidth:32},ThemeSelectorComponent=class extends Container{selectList;onPreview;constructor(currentTheme,onSelect,onCancel,onPreview){super(),this.onPreview=onPreview;let themes=getAvailableThemes(),themeItems=themes.map(name=>({value:name,label:name,description:name===currentTheme?"(current)":void 0}));this.addChild(new DynamicBorder),this.selectList=new SelectList(themeItems,10,getSelectListTheme(),THEME_SELECT_LIST_LAYOUT);let currentIndex=themes.indexOf(currentTheme);currentIndex!==-1&&this.selectList.setSelectedIndex(currentIndex),this.selectList.onSelect=item=>{onSelect(item.value)},this.selectList.onCancel=()=>{onCancel()},this.selectList.onSelectionChange=item=>{this.onPreview(item.value)},this.addChild(this.selectList),this.addChild(new DynamicBorder)}getSelectList(){return this.selectList}};export{ShowImagesSelectorComponent,ThemeSelectorComponent,dist_exports};
2
+ import{AgentSession,AgentSessionRuntime,AssistantMessageComponent,BashExecutionComponent,BorderedLoader,BranchSummaryMessageComponent,CURRENT_SESSION_VERSION,CompactionSummaryMessageComponent,CredentialSynchronizationError,CustomEditor,CustomMessageComponent,DEFAULT_COMPACTION_SETTINGS,DefaultPackageManager,DefaultResourceLoader,DynamicBorder,ExtensionEditorComponent,ExtensionInputComponent,ExtensionRunner,ExtensionSelectorComponent,FooterComponent,InteractiveMode,LoginDialogComponent,MCP_CONNECTION_EVENT,ModelRegistry,ModelRuntime,ModelSelectorComponent,OAuthSelectorComponent,RpcClient,SessionManager,SessionSelectorComponent,SettingsManager,SettingsSelectorComponent,SkillInvocationMessageComponent,ThinkingSelectorComponent,ToolExecutionComponent,TreeSelectorComponent,UserMessageComponent,UserMessageSelectorComponent,VIRTUAL_MODEL_STATE_ENTRY,applyHttpProxySettings,buildContextEntries,buildSessionContext,buildSessionProjection,calculateContextTokens,collectEntriesForBranchSummary,compact,configureHttpDispatcher,convertToLlm,convertToPng,copyToClipboard,createAgentSession,createAgentSessionFromServices,createAgentSessionRuntime,createAgentSessionServices,createBashTool,createBashToolDefinition,createCodemodeExtension,createCodingTools,createEditTool,createEditToolDefinition,createEventBus,createExtensionRuntime,createFindTool,createFindToolDefinition,createGrepTool,createGrepToolDefinition,createLocalBashOperations,createLocalPowerShellOperations,createLsTool,createLsToolDefinition,createMcpExtension,createPowerShellTool,createPowerShellToolDefinition,createReadOnlyTools,createReadTool,createReadToolDefinition,createSyntheticSourceInfo,createToolSearchExtension,createWriteTool,createWriteToolDefinition,defaultModelPerProvider,defineTool,detectSupportedImageMimeTypeFromFile,discoverAndLoadExtensions,estimateTokens,findCutPoint,findTurnStartIndex,formatDimensionNote,formatSkillsForPrompt,generateBranchSummary,generateDiffString,generateSummary,generateSummaryWithUsage,generateUnifiedPatch,getLastAssistantUsage,getLatestCompactionEntry,isBashToolResult,isEditToolResult,isFindToolResult,isGrepToolResult,isLsToolResult,isPowerShellToolResult,isReadToolResult,isToolCallEventType,isWriteToolResult,loadProjectContextFiles,loadSkills,loadSkillsFromDir,main,migrateSessionEntries,parseArgs,parseFrontmatter,parseSessionEntries,parseSkillBlock,prepareBranchEntries,renderDiff,resizeImage,resolveCliModel,resolveModelScopeWithDiagnostics,runPrintMode,runRpcMode,serializeConversation,sessionEntryToContextMessages,setupCli,shouldCompact,stdioRpcTransport,stripFrontmatter,withFileMutationQueue,wrapRegisteredTool,wrapRegisteredTools}from"./chunk-BK7M6BDT.js";import{DEFAULT_MAX_BYTES,DEFAULT_MAX_LINES,formatReadLineRange,formatSize,truncateHead,truncateLine,truncateTail,truncateToVisualLines}from"./chunk-DYTENXHX.js";import{ArminComponent}from"./chunk-FLHKNMLQ.js";import{Container,SelectList,Theme,getAvailableThemes,getLanguageFromPath,getMarkdownTheme,getSelectListTheme,getSettingsListTheme,highlightCode,initTheme,keyHint,keyText,rawKeyHint}from"./chunk-LT2C56HV.js";import{ProjectTrustStore,hasTrustRequiringProjectResources,loadMcpConfig}from"./chunk-6Z2347ML.js";import{readStoredCredential}from"./chunk-MF3VB62R.js";import{getPowerShellConfig,getShellConfig}from"./chunk-URBBMV3M.js";import{CONFIG_DIR_NAME,VERSION,getAgentDir,getDocsPath,getExamplesPath,getPackageDir,getReadmePath}from"./chunk-LHRPMXVI.js";import{__export}from"./chunk-JXWJOIH4.js";var dist_exports={};__export(dist_exports,{AgentSession:()=>AgentSession,AgentSessionRuntime:()=>AgentSessionRuntime,ArminComponent:()=>ArminComponent,AssistantMessageComponent:()=>AssistantMessageComponent,BashExecutionComponent:()=>BashExecutionComponent,BorderedLoader:()=>BorderedLoader,BranchSummaryMessageComponent:()=>BranchSummaryMessageComponent,CONFIG_DIR_NAME:()=>CONFIG_DIR_NAME,CURRENT_SESSION_VERSION:()=>CURRENT_SESSION_VERSION,CompactionSummaryMessageComponent:()=>CompactionSummaryMessageComponent,CredentialSynchronizationError:()=>CredentialSynchronizationError,CustomEditor:()=>CustomEditor,CustomMessageComponent:()=>CustomMessageComponent,DEFAULT_COMPACTION_SETTINGS:()=>DEFAULT_COMPACTION_SETTINGS,DEFAULT_MAX_BYTES:()=>DEFAULT_MAX_BYTES,DEFAULT_MAX_LINES:()=>DEFAULT_MAX_LINES,DefaultPackageManager:()=>DefaultPackageManager,DefaultResourceLoader:()=>DefaultResourceLoader,DynamicBorder:()=>DynamicBorder,ExtensionEditorComponent:()=>ExtensionEditorComponent,ExtensionInputComponent:()=>ExtensionInputComponent,ExtensionRunner:()=>ExtensionRunner,ExtensionSelectorComponent:()=>ExtensionSelectorComponent,FooterComponent:()=>FooterComponent,InteractiveMode:()=>InteractiveMode,LoginDialogComponent:()=>LoginDialogComponent,MCP_CONNECTION_EVENT:()=>MCP_CONNECTION_EVENT,ModelRegistry:()=>ModelRegistry,ModelRuntime:()=>ModelRuntime,ModelSelectorComponent:()=>ModelSelectorComponent,OAuthSelectorComponent:()=>OAuthSelectorComponent,ProjectTrustStore:()=>ProjectTrustStore,RpcClient:()=>RpcClient,SessionManager:()=>SessionManager,SessionSelectorComponent:()=>SessionSelectorComponent,SettingsManager:()=>SettingsManager,SettingsSelectorComponent:()=>SettingsSelectorComponent,ShowImagesSelectorComponent:()=>ShowImagesSelectorComponent,SkillInvocationMessageComponent:()=>SkillInvocationMessageComponent,Theme:()=>Theme,ThemeSelectorComponent:()=>ThemeSelectorComponent,ThinkingSelectorComponent:()=>ThinkingSelectorComponent,ToolExecutionComponent:()=>ToolExecutionComponent,TreeSelectorComponent:()=>TreeSelectorComponent,UserMessageComponent:()=>UserMessageComponent,UserMessageSelectorComponent:()=>UserMessageSelectorComponent,VERSION:()=>VERSION,VIRTUAL_MODEL_STATE_ENTRY:()=>VIRTUAL_MODEL_STATE_ENTRY,applyHttpProxySettings:()=>applyHttpProxySettings,buildContextEntries:()=>buildContextEntries,buildSessionContext:()=>buildSessionContext,buildSessionProjection:()=>buildSessionProjection,calculateContextTokens:()=>calculateContextTokens,collectEntriesForBranchSummary:()=>collectEntriesForBranchSummary,compact:()=>compact,configureHttpDispatcher:()=>configureHttpDispatcher,convertToLlm:()=>convertToLlm,convertToPng:()=>convertToPng,copyToClipboard:()=>copyToClipboard,createAgentSession:()=>createAgentSession,createAgentSessionFromServices:()=>createAgentSessionFromServices,createAgentSessionRuntime:()=>createAgentSessionRuntime,createAgentSessionServices:()=>createAgentSessionServices,createBashTool:()=>createBashTool,createBashToolDefinition:()=>createBashToolDefinition,createCodemodeExtension:()=>createCodemodeExtension,createCodingTools:()=>createCodingTools,createEditTool:()=>createEditTool,createEditToolDefinition:()=>createEditToolDefinition,createEventBus:()=>createEventBus,createExtensionRuntime:()=>createExtensionRuntime,createFindTool:()=>createFindTool,createFindToolDefinition:()=>createFindToolDefinition,createGrepTool:()=>createGrepTool,createGrepToolDefinition:()=>createGrepToolDefinition,createLocalBashOperations:()=>createLocalBashOperations,createLocalPowerShellOperations:()=>createLocalPowerShellOperations,createLsTool:()=>createLsTool,createLsToolDefinition:()=>createLsToolDefinition,createMcpExtension:()=>createMcpExtension,createPowerShellTool:()=>createPowerShellTool,createPowerShellToolDefinition:()=>createPowerShellToolDefinition,createReadOnlyTools:()=>createReadOnlyTools,createReadTool:()=>createReadTool,createReadToolDefinition:()=>createReadToolDefinition,createSyntheticSourceInfo:()=>createSyntheticSourceInfo,createToolSearchExtension:()=>createToolSearchExtension,createWriteTool:()=>createWriteTool,createWriteToolDefinition:()=>createWriteToolDefinition,defaultModelPerProvider:()=>defaultModelPerProvider,defineTool:()=>defineTool,detectSupportedImageMimeTypeFromFile:()=>detectSupportedImageMimeTypeFromFile,discoverAndLoadExtensions:()=>discoverAndLoadExtensions,estimateTokens:()=>estimateTokens,findCutPoint:()=>findCutPoint,findTurnStartIndex:()=>findTurnStartIndex,formatDimensionNote:()=>formatDimensionNote,formatReadLineRange:()=>formatReadLineRange,formatSize:()=>formatSize,formatSkillsForPrompt:()=>formatSkillsForPrompt,generateBranchSummary:()=>generateBranchSummary,generateDiffString:()=>generateDiffString,generateSummary:()=>generateSummary,generateSummaryWithUsage:()=>generateSummaryWithUsage,generateUnifiedPatch:()=>generateUnifiedPatch,getAgentDir:()=>getAgentDir,getDocsPath:()=>getDocsPath,getExamplesPath:()=>getExamplesPath,getLanguageFromPath:()=>getLanguageFromPath,getLastAssistantUsage:()=>getLastAssistantUsage,getLatestCompactionEntry:()=>getLatestCompactionEntry,getMarkdownTheme:()=>getMarkdownTheme,getPackageDir:()=>getPackageDir,getPowerShellConfig:()=>getPowerShellConfig,getReadmePath:()=>getReadmePath,getSelectListTheme:()=>getSelectListTheme,getSettingsListTheme:()=>getSettingsListTheme,getShellConfig:()=>getShellConfig,hasTrustRequiringProjectResources:()=>hasTrustRequiringProjectResources,highlightCode:()=>highlightCode,initTheme:()=>initTheme,isBashToolResult:()=>isBashToolResult,isEditToolResult:()=>isEditToolResult,isFindToolResult:()=>isFindToolResult,isGrepToolResult:()=>isGrepToolResult,isLsToolResult:()=>isLsToolResult,isPowerShellToolResult:()=>isPowerShellToolResult,isReadToolResult:()=>isReadToolResult,isToolCallEventType:()=>isToolCallEventType,isWriteToolResult:()=>isWriteToolResult,keyHint:()=>keyHint,keyText:()=>keyText,loadMcpConfig:()=>loadMcpConfig,loadProjectContextFiles:()=>loadProjectContextFiles,loadSkills:()=>loadSkills,loadSkillsFromDir:()=>loadSkillsFromDir,main:()=>main,migrateSessionEntries:()=>migrateSessionEntries,parseArgs:()=>parseArgs,parseFrontmatter:()=>parseFrontmatter,parseSessionEntries:()=>parseSessionEntries,parseSkillBlock:()=>parseSkillBlock,prepareBranchEntries:()=>prepareBranchEntries,rawKeyHint:()=>rawKeyHint,readStoredCredential:()=>readStoredCredential,renderDiff:()=>renderDiff,resizeImage:()=>resizeImage,resolveCliModel:()=>resolveCliModel,resolveModelScopeWithDiagnostics:()=>resolveModelScopeWithDiagnostics,runPrintMode:()=>runPrintMode,runRpcMode:()=>runRpcMode,serializeConversation:()=>serializeConversation,sessionEntryToContextMessages:()=>sessionEntryToContextMessages,setupCli:()=>setupCli,shouldCompact:()=>shouldCompact,stdioRpcTransport:()=>stdioRpcTransport,stripFrontmatter:()=>stripFrontmatter,truncateHead:()=>truncateHead,truncateLine:()=>truncateLine,truncateTail:()=>truncateTail,truncateToVisualLines:()=>truncateToVisualLines,withFileMutationQueue:()=>withFileMutationQueue,wrapRegisteredTool:()=>wrapRegisteredTool,wrapRegisteredTools:()=>wrapRegisteredTools});var SHOW_IMAGES_SELECT_LIST_LAYOUT={minPrimaryColumnWidth:12,maxPrimaryColumnWidth:32},ShowImagesSelectorComponent=class extends Container{selectList;constructor(currentValue,onSelect,onCancel){super();let items=[{value:"yes",label:"Yes",description:"Show images inline in terminal"},{value:"no",label:"No",description:"Show text placeholder instead"}];this.addChild(new DynamicBorder),this.selectList=new SelectList(items,5,getSelectListTheme(),SHOW_IMAGES_SELECT_LIST_LAYOUT),this.selectList.setSelectedIndex(currentValue?0:1),this.selectList.onSelect=item=>{onSelect(item.value==="yes")},this.selectList.onCancel=()=>{onCancel()},this.addChild(this.selectList),this.addChild(new DynamicBorder)}getSelectList(){return this.selectList}};var THEME_SELECT_LIST_LAYOUT={minPrimaryColumnWidth:12,maxPrimaryColumnWidth:32},ThemeSelectorComponent=class extends Container{selectList;onPreview;constructor(currentTheme,onSelect,onCancel,onPreview){super(),this.onPreview=onPreview;let themes=getAvailableThemes(),themeItems=themes.map(name=>({value:name,label:name,description:name===currentTheme?"(current)":void 0}));this.addChild(new DynamicBorder),this.selectList=new SelectList(themeItems,10,getSelectListTheme(),THEME_SELECT_LIST_LAYOUT);let currentIndex=themes.indexOf(currentTheme);currentIndex!==-1&&this.selectList.setSelectedIndex(currentIndex),this.selectList.onSelect=item=>{onSelect(item.value)},this.selectList.onCancel=()=>{onCancel()},this.selectList.onSelectionChange=item=>{this.onPreview(item.value)},this.addChild(this.selectList),this.addChild(new DynamicBorder)}getSelectList(){return this.selectList}};export{ShowImagesSelectorComponent,ThemeSelectorComponent,dist_exports};