mu-agent 0.2.2 → 0.2.3

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.
@@ -269,21 +269,20 @@
269
269
  "fa-IR": "پیام‌های حین کار"
270
270
  },
271
271
  "summary": {
272
- "zh": "任务进行中你又发来一句话:判断是要立刻打断,还是等这一步做完再处理。默认是影子模式:判定只记录,消息按你按的键投递,不用等判定。",
273
- "en": "For a message that arrives while the agent is working: interrupt now, or handle it after the current step. In shadow by default: the verdict is only logged, and the key you pressed decides what happens to the message, without waiting for the verdict.",
274
- "zh-TW": "代理工作時你又傳來一則訊息:判斷是要立刻打斷,還是等這一步做完再處理。預設為影子模式:判定只記錄下來,訊息照你按的鍵送出,不等判定。",
275
- "ja-JP": "エージェントの作業中に届いたメッセージについて、すぐに中断するか、現在のステップが終わってから対応するかを判定します。既定ではシャドーモードです。判定は記録するだけで、メッセージは判定を待たずに、押したキーのとおりに届けます。",
276
- "ko-KR": "에이전트가 작업하는 중에 메시지가 도착하면, 지금 바로 작업을 중단할지 현재 단계를 마친 뒤 처리할지 판정합니다. 기본값은 섀도 모드입니다. 판정은 기록만 하고, 메시지는 판정을 기다리지 않고 누른 키대로 전달됩니다.",
277
- "de-DE": "Eine Nachricht, die eintrifft, während der Agent arbeitet: sofort unterbrechen oder nach dem aktuellen Schritt bearbeiten. Standardmäßig im Schattenmodus: Das Urteil wird nur aufgezeichnet, und die Nachricht wird so zugestellt, wie es die gedrückte Taste vorgibt, ohne auf das Urteil zu warten.",
278
- "fr-FR": "Un message arrive pendant que l’agent travaille : interrompre tout de suite, ou le traiter après l’étape en cours. En mode fantôme par défaut : le jugement est seulement enregistré, et le message suit la touche sur laquelle vous avez appuyé, sans attendre le jugement.",
279
- "es-ES": "Un mensaje que llega mientras el agente trabaja: interrumpir ahora o atenderlo al terminar el paso actual. En modo sombra de forma predeterminada: el veredicto solo se registra y el mensaje se entrega según la tecla que pulsaste, sin esperarlo.",
280
- "pt-BR": "Uma mensagem que chega enquanto o agente trabalha: interromper agora ou tratá-la depois da etapa atual. No modo sombra por padrão: o veredito só é registrado, e a mensagem segue a tecla que você apertou, sem esperar por ele.",
281
- "ru-RU": "Сообщение, пришедшее во время работы агента: прервать работу сразу или обработать его после текущего шага. По умолчанию в теневом режиме: решение только записывается, а сообщение доставляется так, как велит нажатая клавиша, не дожидаясь решения.",
282
- "uk-UA": "Повідомлення, що надходить, поки агент працює: перервати роботу зараз чи обробити його після поточного кроку. Типово в тіньовому режимі: рішення лише записується, а повідомлення доставляється відповідно до натиснутої клавіші, не чекаючи на рішення.",
283
- "tr-TR": "Ajan çalışırken gelen bir mesaj: iş hemen kesilsin mi, yoksa mesaj mevcut adımdan sonra mı ele alınsın? Varsayılan olarak gölge modunda: karar yalnızca kaydedilir ve mesaj, kararı beklemeden bastığınız tuşa göre iletilir.",
284
- "fa-IR": "پیامی که هنگام کار عامل می‌رسد: همین حالا کار را قطع کند، یا پس از گام فعلی به آن بپردازد. به‌طور پیش‌فرض در حالت سایه است: نتیجهٔ داوری فقط ثبت می‌شود و پیام، بی‌آنکه منتظر آن بماند، طبق کلیدی که زده‌اید تحویل داده می‌شود."
285
- },
286
- "defaultMode": "shadow"
272
+ "zh": "任务进行中你又发来一句话:判断是在下一步就带进工作,还是等这一轮做完再处理。判定最多等 1.5 秒;没有判定时,消息按你发送的方式送达。",
273
+ "en": "For a message you send while the agent is working: bring it into the work at the next step, or hold it until the run is done. mu waits up to 1.5 seconds for the verdict; without one, the message goes as you sent it.",
274
+ "zh-TW": "任務進行中你又傳來一則訊息:判斷是在下一步就帶進工作,還是等這一輪做完再處理。判定最多等 1.5 秒;沒有判定時,訊息照你傳送的方式送達。",
275
+ "ja-JP": "エージェントの作業中に送ったメッセージを、次のステップで作業に取り込むか、実行が終わるまで待たせるかを判定します。判定は最大 1.5 秒待ち、判定がなければメッセージは送ったとおりに届きます。",
276
+ "ko-KR": "에이전트가 작업하는 중에 보낸 메시지를 다음 단계에서 작업에 반영할지, 실행이 끝날 때까지 기다리게 할지 판정합니다. 판정은 최대 1.5초 기다리며, 판정이 없으면 메시지는 보낸 그대로 전달됩니다.",
277
+ "de-DE": "Eine Nachricht, die Sie senden, während der Agent arbeitet: beim nächsten Schritt in die Arbeit aufnehmen oder zurückhalten, bis der Lauf fertig ist. mu wartet bis zu 1,5 Sekunden auf das Urteil; ohne Urteil wird die Nachricht so zugestellt, wie Sie sie gesendet haben.",
278
+ "fr-FR": "Un message envoyé pendant que l’agent travaille : l’intégrer au travail dès l’étape suivante, ou le garder jusqu’à la fin de l’exécution. mu attend le jugement jusqu’à 1,5 seconde ; sans jugement, le message part tel que vous l’avez envoyé.",
279
+ "es-ES": "Un mensaje que envías mientras el agente trabaja: incorporarlo al trabajo en el siguiente paso o guardarlo hasta que termine la ejecución. mu espera el veredicto hasta 1,5 segundos; sin veredicto, el mensaje se entrega tal como lo enviaste.",
280
+ "pt-BR": "Uma mensagem que você envia enquanto o agente trabalha: levá-la ao trabalho na próxima etapa ou guardá-la até a execução terminar. O mu espera o veredito por até 1,5 segundo; sem ele, a mensagem segue como você a enviou.",
281
+ "ru-RU": "Сообщение, отправленное во время работы агента: включить его в работу на следующем шаге или придержать до конца запуска. mu ждёт решения до 1,5 секунды; без решения сообщение доставляется так, как вы его отправили.",
282
+ "uk-UA": "Повідомлення, надіслане під час роботи агента: долучити його до роботи на наступному кроці чи притримати до кінця запуску. mu чекає на рішення до 1,5 секунди; без рішення повідомлення доставляється так, як ви його надіслали.",
283
+ "tr-TR": "Ajan çalışırken gönderdiğiniz bir mesaj: bir sonraki adımda işe katılsın mı, yoksa çalışma bitene kadar beklesin mi? mu karar için en fazla 1,5 saniye bekler; karar gelmezse mesaj gönderdiğiniz gibi iletilir.",
284
+ "fa-IR": "پیامی که هنگام کار عامل می‌فرستید: در گام بعدی وارد کار شود، یا تا پایان اجرا نگه داشته شود. mu حداکثر 1.5 ثانیه منتظر نتیجهٔ داوری می‌ماند؛ اگر نتیجه‌ای نرسد، پیام همان‌طور که فرستاده‌اید تحویل داده می‌شود."
285
+ }
287
286
  },
288
287
  {
289
288
  "id": "skills.disclosure",
@@ -11,7 +11,7 @@ var pi_host_modules_exports = {};
11
11
  __export(pi_host_modules_exports, {
12
12
  VIRTUAL_MODULES: () => VIRTUAL_MODULES
13
13
  });
14
- import { VIRTUAL_MODULES } from "../../dist/bundle/chunks/virtual-modules-U6MRV5BC.js";
14
+ import { VIRTUAL_MODULES } from "../../dist/bundle/chunks/virtual-modules-6BAN7L2H.js";
15
15
  var init_pi_host_modules = __esm({
16
16
  "pi-host-modules:pi-host-modules"() {
17
17
  "use strict";
@@ -5,7 +5,7 @@ import {
5
5
  CLOUD_CODE_ENDPOINT,
6
6
  antigravityUserAgent,
7
7
  require_pi_ai
8
- } from "./chunk-6XRUK3PM.js";
8
+ } from "./chunk-JZ4X4HQO.js";
9
9
  import {
10
10
  __commonJS,
11
11
  __require,
package/judge/mu/index.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  init_pi_host_modules,
10
10
  pi_host_modules_exports,
11
11
  require_pi_ai
12
- } from "./chunk-6XRUK3PM.js";
12
+ } from "./chunk-JZ4X4HQO.js";
13
13
  import {
14
14
  __commonJS,
15
15
  __require,
@@ -27501,8 +27501,9 @@ var DEFAULT_CONFIG = {
27501
27501
  "capability.disclosure": "off",
27502
27502
  // Its rules deliver what matters; in single-prompt runs a "next_turn" verdict never reached anyone.
27503
27503
  "notify.routing": "shadow",
27504
- // About a second on every mid-run message, and no verdict has changed anything yet.
27505
- "input.interjection": "shadow",
27504
+ // input.interjection follows the default: mu, not the key that sent it, decides when a message sent mid-run
27505
+ // reaches the work. A message waits for its verdict for at most 1.5 s (`features.interjection.waitMs`), and goes
27506
+ // as sent without one. A built-in "active" here would keep it acting under a default of shadow.
27506
27507
  // Its steers were mostly wrong where it flagged anything at all, so it only records until it is reworked.
27507
27508
  "turn.drift": "shadow"
27508
27509
  },
@@ -37492,8 +37493,7 @@ var helpZh = () => `mu ${VERSIONS.mu} \xB7 \u5148\u5224\u65AD\u518D\u52A8\u624B\
37492
37493
  /import-chat [\u6587\u4EF6]\uFF1A\u628A\u8FD9\u4E2A\u9879\u76EE\u5728 Claude Code\u3001Codex \u6216 ZCode \u91CC\u7684\u5BF9\u8BDD\u5BFC\u5165\u8FDB\u6765\uFF0C\u63A5\u7740\u5728\u8FD9\u91CC\u804A
37493
37494
 
37494
37495
  \u5224\u65AD\u5C42
37495
- \u4F60\u7684\u6BCF\u6761\u6D88\u606F\u90FD\u5148\u4EA4\u7ED9\u5224\u5B9A\u5668\u8BFB\uFF1A\u8BFB\u7684\u65F6\u5019\u6D88\u606F\u505C\u5728\u8F93\u5165\u6846\u4E0A\u65B9\uFF08\u6309 esc \u53EF\u8DF3\u8FC7\u7B49\u5F85\uFF09\uFF0C
37496
- \u5224\u5B9A\u7ED3\u679C\u7559\u5728\u5BF9\u8BDD\u91CC\u8FD9\u6761\u6D88\u606F\u4E0B\u9762\u3002${(0, import_pi_coding_agent5.keyText)("app.tools.expand")} \u53EF\u4EE5\u770B\u6BCF\u4E2A\u5224\u5B9A\u80CC\u540E\u7684\u5168\u90E8\u56DE\u7B54\u3002
37496
+ \u6309 esc \u4E0D\u7B49\u5224\u5B9A\u5668\u8BFB\u5B8C\u6D88\u606F\uFF1B${(0, import_pi_coding_agent5.keyText)("app.tools.expand")} \u53EF\u4EE5\u770B\u6BCF\u4E2A\u5224\u5B9A\u80CC\u540E\u7684\u5168\u90E8\u56DE\u7B54\u3002
37497
37497
  /mu judge <\u5224\u5B9A\u5668>\uFF1A\u7531\u54EA\u4E9B\u6A21\u578B\u6765\u5224\u5B9A\u3001\u6309\u4EC0\u4E48\u987A\u5E8F\uFF0C\u6BD4\u5982 laya | laya,jev | jev-opencode-free | clm | classifier:<\u63D0\u4F9B\u5546>/<\u6A21\u578B> | llm:<\u63D0\u4F9B\u5546>/<\u6A21\u578B>
37498
37498
  /mu route <\u5224\u5B9A\u70B9> <\u5224\u5B9A\u5668|default>\uFF1A\u8BA9\u67D0\u4E00\u4E2A\u5224\u5B9A\u70B9\u7528\u81EA\u5DF1\u7684\u5224\u5B9A\u5668\uFF0C\u6BD4\u5982 browser.step llm:openai/gpt-5.6-luna
37499
37499
  /mu mode <\u5224\u5B9A\u70B9|default> <off|shadow|active>\uFF1Aoff \u5173\u95ED\uFF0Cshadow \u5F71\u5B50\uFF08\u53EA\u8BB0\u5F55\uFF0C\u4E0D\u8D77\u4F5C\u7528\uFF09\uFF0Cactive \u751F\u6548
@@ -37551,7 +37551,7 @@ var helpSectionsEn = () => [
37551
37551
  },
37552
37552
  {
37553
37553
  title: "Judgment kernel",
37554
- intro: `The judge reads every message first. While it reads, your message waits above the editor (esc skips the wait); the verdict then appears under your message. ${(0, import_pi_coding_agent5.keyText)("app.tools.expand")} shows the full answers behind a verdict.`,
37554
+ intro: `esc skips the wait for the judge's reading of a message; ${(0, import_pi_coding_agent5.keyText)("app.tools.expand")} shows the full answers behind a verdict.`,
37555
37555
  rows: [
37556
37556
  [
37557
37557
  "/mu judge <judges>",
@@ -40565,7 +40565,7 @@ var geminiCliOAuth = googleOAuth(GEMINI_CLI_LOGIN);
40565
40565
  var antigravityOAuth = googleOAuth(ANTIGRAVITY_LOGIN);
40566
40566
 
40567
40567
  // packages/kyrn-judge/src/google-login/providers.ts
40568
- var cloudCode = () => (0, import_pi_ai2.lazyApi)(() => import("./cloud-code-XR7SZMJC.js"));
40568
+ var cloudCode = () => (0, import_pi_ai2.lazyApi)(() => import("./cloud-code-PDKLWJEG.js"));
40569
40569
  var FREE = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
40570
40570
  var NOT_CHAT = /image|live|computer-use|customtools|latest|deep-research|tts|embedding/;
40571
40571
  function geminiCliModels() {
@@ -48650,29 +48650,47 @@ function registerInterjection(runtime) {
48650
48650
  const options = runtime.options("interjection", { enabled: true, waitMs: 1500 });
48651
48651
  if (!options.enabled) return;
48652
48652
  const { pi } = runtime;
48653
+ let previous = Promise.resolve();
48654
+ const otherWay = async (event, sent) => {
48655
+ if (event.images?.length) return void 0;
48656
+ const goal = runtime.taskFrame()?.goal;
48657
+ if (!goal) return void 0;
48658
+ const input = {
48659
+ userMessage: clip(event.text, 400),
48660
+ goal,
48661
+ currentAction: clip(runtime.lastAssistantText, 300)
48662
+ };
48663
+ if (runtime.mode(inputInterjection.id) !== "active") {
48664
+ void runtime.engine.decide(inputInterjection, input).catch(() => {
48665
+ });
48666
+ return void 0;
48667
+ }
48668
+ const decision = await within(runtime.engine.decide(inputInterjection, input), options.waitMs);
48669
+ if (!decision || decision.source !== "judge") return void 0;
48670
+ if (decision.outcome === "keep" || decision.outcome === sent) return void 0;
48671
+ return decision.outcome;
48672
+ };
48653
48673
  pi.on(
48654
48674
  "input",
48655
48675
  failOpen(async (event, ctx) => {
48656
48676
  runtime.touch(ctx);
48657
- if (event.source === "extension" || !event.streamingBehavior || !event.text.trim()) return void 0;
48658
- if (event.images?.length) return void 0;
48659
- const goal = runtime.taskFrame()?.goal;
48660
- if (!goal) return void 0;
48661
- const input = {
48662
- userMessage: clip(event.text, 400),
48663
- goal,
48664
- currentAction: clip(runtime.lastAssistantText, 300)
48677
+ const sent = event.streamingBehavior;
48678
+ if (event.source === "extension" || !sent || !event.text.trim()) return void 0;
48679
+ const earlier = previous;
48680
+ let release = () => {
48665
48681
  };
48666
- if (runtime.mode(inputInterjection.id) !== "active") {
48667
- void runtime.engine.decide(inputInterjection, input).catch(() => {
48668
- });
48669
- return void 0;
48682
+ previous = new Promise((resolve15) => {
48683
+ release = () => setTimeout(resolve15, 0);
48684
+ });
48685
+ try {
48686
+ const other = await otherWay(event, sent).catch(() => void 0);
48687
+ await earlier;
48688
+ if (!other || ctx.isIdle()) return void 0;
48689
+ pi.sendUserMessage(event.text, { deliverAs: other, expandPromptTemplates: true });
48690
+ return { action: "handled" };
48691
+ } finally {
48692
+ release();
48670
48693
  }
48671
- const decision = await within(runtime.engine.decide(inputInterjection, input), options.waitMs);
48672
- if (!decision || decision.source !== "judge") return void 0;
48673
- if (decision.outcome === "keep" || decision.outcome === event.streamingBehavior) return void 0;
48674
- pi.sendUserMessage(event.text, { deliverAs: decision.outcome });
48675
- return { action: "handled" };
48676
48694
  })
48677
48695
  );
48678
48696
  }
@@ -129,7 +129,6 @@ const BUILT_IN_MODES = {
129
129
  "swarm.patch": "off",
130
130
  "capability.disclosure": "off",
131
131
  "notify.routing": "shadow",
132
- "input.interjection": "shadow",
133
132
  "turn.drift": "shadow",
134
133
  };
135
134
  // Whether any decision point asks a judge (DecisionEngine.asksJudge). With none, nothing is sent to one, and the rows
@@ -20,8 +20,6 @@ if (args.includes("--help") || args.includes("-h")) {
20
20
  " mu ledger verdicts from the 5 most recent sessions",
21
21
  " mu ledger <n> from the n most recent",
22
22
  " mu ledger --json one JSON object per verdict, for scripts",
23
- "",
24
- "It reads the session files mu keeps on this machine; nothing is sent anywhere.",
25
23
  ].join("\n"),
26
24
  );
27
25
  process.exit(0);
package/kyrn/bin/mu.mjs CHANGED
@@ -100,10 +100,10 @@ export function usage(platform) {
100
100
  ' mu "prompt" start a session with this prompt',
101
101
  ' mu -p "prompt" run one prompt, print the answer and exit',
102
102
  " mu -c | -r continue the last session | pick a session to resume",
103
- " mu setup connect a model (paste an API key or pick a service) and choose a judge",
104
- " (see mu setup --help for scripting, reading a key from stdin and the supported services)",
103
+ " mu setup connect a model (paste an API key or pick a service) and choose a judge (mu setup --help)",
105
104
  " mu judge mude install install mude 1.0, mu's own decision model for coding, and make it the judge on this Mac (Apple silicon, 1.8 GB)",
106
105
  " enable | disable | start | stop | status | uninstall (mu judge mude help)",
106
+ " mu judge model <cmd> other decision models from Hugging Face: add <link> | list | use | remove (mu judge model help)",
107
107
  " mu judge <cmd> manage the local judge, Laya (macOS on Apple silicon): setup | start | stop | status | run",
108
108
  " mu ledger [n] [--json] print the judge's verdicts from the last n sessions",
109
109
  " mu import <file>... import Claude Code, Codex and ZCode conversations; --list shows them (mu import --help)",
@@ -116,8 +116,6 @@ export function usage(platform) {
116
116
  "",
117
117
  "Everything else goes to pi unchanged: mu --help also shows pi's options,",
118
118
  "and mu install|remove|update|list|config manage pi packages.",
119
- "",
120
- "Formerly KYRN: the kyrn commands still work.",
121
119
  ].join("\n");
122
120
  }
123
121
 
@@ -465,6 +463,37 @@ export function wantsMude({ env, agentDir, platform, readFile }) {
465
463
  return false;
466
464
  }
467
465
 
466
+ /**
467
+ * The decision model added from Hugging Face (mu judge model add) that the configuration asks for, when mude isn't the
468
+ * one: the first judge in MU_JUDGE, `tiers` or a route that has a record in <mu home>/local-judge/models. Its server is
469
+ * then started when a session starts, as mude's is.
470
+ */
471
+ export function wantedModel({ env, agentDir, muDir, platform, readFile, exists }) {
472
+ const path = pathFor(platform);
473
+ const added = (name) => /^[a-z0-9][a-z0-9._-]*$/.test(name) && exists(path.join(muDir, "local-judge", "models", name, "model.json"));
474
+ const judges = muEnv("JUDGE", env);
475
+ if (judges) return judges.split(",").map((judge) => judge.trim()).find(added);
476
+ for (const name of ["mu.json", "kyrn.json"]) {
477
+ let config;
478
+ try {
479
+ config = JSON.parse(readFile(path.join(agentDir, name)));
480
+ } catch (error) {
481
+ if (error instanceof SyntaxError) return undefined;
482
+ continue;
483
+ }
484
+ const names = [config?.tiers, ...Object.values(config?.routes ?? {})].flatMap((tiers) => (Array.isArray(tiers) ? tiers : []));
485
+ return names.find((judge) => typeof judge === "string" && added(judge));
486
+ }
487
+ return undefined;
488
+ }
489
+
490
+ /** What starts the server of the decision model the configuration asks for: `mu judge mude start`, or a model's. */
491
+ export function localModelStart({ env, agentDir, muDir, platform, readFile, exists }) {
492
+ if (wantsMude({ env, agentDir, platform, readFile })) return ["start", "--no-wait"];
493
+ const model = wantedModel({ env, agentDir, muDir, platform, readFile, exists });
494
+ return model ? ["model", "start", model, "--no-wait"] : undefined;
495
+ }
496
+
468
497
  export function localJudgeSupport({ platform, env, wsl = false }) {
469
498
  if (platform === "darwin") return { runs: true };
470
499
  const url = muEnv("LOCAL_JUDGE_URL", env);
@@ -605,11 +634,12 @@ export function planLaunch({
605
634
  }
606
635
  }
607
636
 
608
- // mude's server, when the configuration asks for it: started without waiting, so a session never waits for the
609
- // model to load (what mude cannot answer yet goes to the judges behind it). Only a Mac runs it.
637
+ // mude's server, or an added model's, when the configuration asks for it: started without waiting, so a session
638
+ // never waits for the model to load (what it cannot answer yet goes to the judges behind it). Only a Mac runs it.
610
639
  let startMude;
611
- if (execPath && platform === "darwin" && wantsMude({ env: childEnv, agentDir, platform, readFile: fs.readFile })) {
612
- const mude = planMude({ platform, env: childEnv, argv: ["start", "--no-wait"], root, home, execPath, fs, stripsTypes });
640
+ const local = execPath && platform === "darwin" ? localModelStart({ env: childEnv, agentDir, muDir, platform, readFile: fs.readFile, exists: fs.exists }) : undefined;
641
+ if (local) {
642
+ const mude = planMude({ platform, env: childEnv, argv: local, root, home, execPath, fs, stripsTypes });
613
643
  if (!mude.error) startMude = { command: mude.command, args: mude.args, env: mude.env };
614
644
  }
615
645
 
@@ -647,8 +677,9 @@ export function planHost({ platform, env, argv, root, home, fs, wsl = false, str
647
677
  // mude's server is started by a Node of the host's: `nodePath` with `nodeEnv` (Electron's own binary with
648
678
  // ELECTRON_RUN_AS_NODE=1 in the desktop app). Without one, the host leaves it to the app.
649
679
  let startMude;
650
- if (nodePath && platform === "darwin" && wantsMude({ env: launch.env, agentDir: launch.agentDir, platform, readFile: fs.readFile })) {
651
- const mude = planMude({ platform, env: { ...launch.env, ...nodeEnv }, argv: ["start", "--no-wait"], root, home, execPath: nodePath, fs, stripsTypes });
680
+ const local = nodePath && platform === "darwin" ? localModelStart({ env: launch.env, agentDir: launch.agentDir, muDir: launch.muDir, platform, readFile: fs.readFile, exists: fs.exists }) : undefined;
681
+ if (local) {
682
+ const mude = planMude({ platform, env: { ...launch.env, ...nodeEnv }, argv: local, root, home, execPath: nodePath, fs, stripsTypes });
652
683
  if (!mude.error) startMude = { command: mude.command, args: mude.args, env: mude.env };
653
684
  }
654
685
  const common = {
@@ -714,8 +745,9 @@ export function prepareLaunch({ plan, platform, root, bin, err }) {
714
745
  }
715
746
 
716
747
  /**
717
- * mude's server, started in the background (`mu judge mude start --no-wait`): nothing waits for it, and it outlives this
718
- * process, shared by every mu session like Laya. When mude is not installed it does nothing (the doctor says so).
748
+ * mude's server, or an added model's, started in the background (`mu judge mude start --no-wait`): nothing waits for
749
+ * it, and it outlives this process, shared by every mu session like Laya. When it is not installed it does nothing (the
750
+ * doctor says so).
719
751
  */
720
752
  function startMudeServer(plan) {
721
753
  if (!plan.startMude) return;
@@ -774,9 +806,10 @@ export const LINK_USAGE = [
774
806
  export const AUTH_USAGE = [
775
807
  "mu's sign-in, which the desktop app runs (JSON lines on stdout):",
776
808
  " mu auth status",
777
- " mu auth login <provider>",
809
+ " mu auth login <provider> [--paste]",
778
810
  " mu auth logout <provider>",
779
- "In a terminal, /login inside mu signs in the same way.",
811
+ "In a terminal, /login inside mu signs in the same way. With --paste, the sign-in takes the address the browser",
812
+ "ends on as pasted instead of listening for it: for when another program (the Codex CLI) holds the callback port.",
780
813
  "",
781
814
  "pi's auth commands:",
782
815
  ].join("\n");
@@ -1609,11 +1642,12 @@ export async function main(argv = process.argv.slice(2)) {
1609
1642
  },
1610
1643
  });
1611
1644
  }
1612
- if (command === "judge" && rest[0] === "mude") {
1645
+ // `mu judge model …` runs in the same file as `mu judge mude …`, as `model …`.
1646
+ if (command === "judge" && (rest[0] === "mude" || rest[0] === "model")) {
1613
1647
  const plan = planMude({
1614
1648
  platform,
1615
1649
  env,
1616
- argv: rest.slice(1),
1650
+ argv: rest[0] === "model" ? rest : rest.slice(1),
1617
1651
  root,
1618
1652
  home,
1619
1653
  execPath: process.execPath,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mu-agent",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "mu: a coding agent that hands its routine decisions to a small, fast judge model, so the main model can keep its attention on the work. Built on pi.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -42,6 +42,6 @@
42
42
  "muBuild": {
43
43
  "pi": "1.3.0",
44
44
  "judge": "0.1.0",
45
- "commit": "21f3c2a84"
45
+ "commit": "d9f6ebc2c"
46
46
  }
47
47
  }
@@ -1,2 +0,0 @@
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-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};