mu-agent 0.2.5 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/README.md +1 -1
- package/judge/dist/mude.js +5 -4
- package/judge/dist/setup.js +3 -2
- package/judge/manifest.json +2 -2
- package/judge/mu/index.js +148 -86
- package/kyrn/bin/kyrn-doctor +5 -2
- package/kyrn/bin/mu.mjs +11 -7
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.2.6] - 2026-10-24
|
|
6
|
+
|
|
7
|
+
**0.2.6 shows the note that Laya was replaced when a person sends a message, keeps mude 1.0 local only when it's installed again, and stops `mu doctor` failing on a machine without Chrome.**
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- The `laya_removed` notice waits for a person. In 0.2.5 the desktop backend's health check of mu (a session that never gets a prompt) was the first session with a UI: it took Laya out of mu.json and got the notice about 3 s after the app started, so nobody saw it. mu.json still loses Laya at the first session start with a terminal or the desktop app, but the notice is now kept in `<agentDir>/mu/notices.json` (`layaRemoved: { judge, from }`) and said at the first message a person sends, in that session or a later one: `judge.notice`, then the line, and the entry is removed. pi's `input` event is that message; mu's own commands (`/goal`, `/permissions`, `/mu …`), which pi runs before it, and messages an extension sends don't count. A session that gets no message leaves the notice where it is, and `mu --print` and json mode still change nothing. `MU_JUDGE=laya` leaves the same notice at the start of each session that has it. The free Jev notice now writes its day beside other entries in notices.json instead of replacing the file. A mu.json that 0.2.5 already updated has no notice left to show.
|
|
12
|
+
- `mu judge mude install` without `--local-only` or `--with-fallback` keeps the current setting when mude 1.0 is already the judge (as `enable` does), instead of putting Jev back behind it.
|
|
13
|
+
- `mu judge model add`: a 401 without `HF_TOKEN` says the model doesn't exist or is private or gated, and to check the name, since Hugging Face answers both the same way.
|
|
14
|
+
- `mu doctor` and `/doctor` mark a missing Chrome, Chromium, Edge or Brave as optional (`--`) instead of something to fix, so `mu doctor` exits 0 when everything else is set up. `mu --help` lines fit in 100 columns.
|
|
15
|
+
|
|
5
16
|
## [0.2.5] - 2026-10-24
|
|
6
17
|
|
|
7
18
|
**0.2.5 removes Laya from mu's built-in judges. A configuration that still names it switches to mude 1.0 or Jev on its own.**
|
package/README.md
CHANGED
|
@@ -27,7 +27,7 @@ mu is built on [pi](https://github.com/earendil-works/pi). It hands the small qu
|
|
|
27
27
|
|
|
28
28
|
## Choose a judge
|
|
29
29
|
|
|
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
|
|
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 fall back to their own rules. Or, on a Mac with Apple silicon, use mude 1.0 with `--local-only`.
|
|
31
31
|
|
|
32
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.
|
package/judge/dist/mude.js
CHANGED
|
@@ -1071,7 +1071,7 @@ async function resolveModel(ref, options = {}) {
|
|
|
1071
1071
|
}
|
|
1072
1072
|
if (response.status === 401 || response.status === 403) {
|
|
1073
1073
|
throw new ModelError(
|
|
1074
|
-
|
|
1074
|
+
response.status === 401 && !options.token ? `Couldn't open ${ref.repo} on Hugging Face (401): it doesn't exist, or it's private or gated. Check the name; for a gated model, accept its terms on huggingface.co, set HF_TOKEN, then add it again` : `${ref.repo} is private or gated on Hugging Face (${response.status}). Accept its terms on huggingface.co, set HF_TOKEN, then add it again`,
|
|
1075
1075
|
"access"
|
|
1076
1076
|
);
|
|
1077
1077
|
}
|
|
@@ -1477,10 +1477,11 @@ function installLocalOnly(ctx, args) {
|
|
|
1477
1477
|
if (args.includes("--with-fallback")) return false;
|
|
1478
1478
|
try {
|
|
1479
1479
|
const value = JSON.parse(readFileSync7(ctx.paths.install, "utf8"));
|
|
1480
|
-
|
|
1480
|
+
if (typeof value === "object" && value !== null && "localOnly" in value) return value.localOnly === true;
|
|
1481
1481
|
} catch {
|
|
1482
|
-
return false;
|
|
1483
1482
|
}
|
|
1483
|
+
const current = judgeSetting(ctx.files, pkgOf(ctx).judge.name);
|
|
1484
|
+
return current.enabled && current.localOnly;
|
|
1484
1485
|
}
|
|
1485
1486
|
function startedAt(pid) {
|
|
1486
1487
|
try {
|
|
@@ -1961,7 +1962,7 @@ ${USAGE2}`, "usage");
|
|
|
1961
1962
|
else out = humanOut(write, tty, each2.pkg);
|
|
1962
1963
|
out.step(
|
|
1963
1964
|
"model",
|
|
1964
|
-
|
|
1965
|
+
`Adding ${record2.repo} @ ${record2.revision.slice(0, 7)} (${gb2(record2.bytes)} GB) as ${record2.id}. It runs its own server code (${SERVER_FILE}) on this Mac: add only models you trust.`
|
|
1965
1966
|
);
|
|
1966
1967
|
await install(each2, out, flags, mudePaths(home));
|
|
1967
1968
|
out.status(await status(each2));
|
package/judge/dist/setup.js
CHANGED
|
@@ -1439,10 +1439,11 @@ function installLocalOnly(ctx, args) {
|
|
|
1439
1439
|
if (args.includes("--with-fallback")) return false;
|
|
1440
1440
|
try {
|
|
1441
1441
|
const value = JSON.parse(readFileSync7(ctx.paths.install, "utf8"));
|
|
1442
|
-
|
|
1442
|
+
if (typeof value === "object" && value !== null && "localOnly" in value) return value.localOnly === true;
|
|
1443
1443
|
} catch {
|
|
1444
|
-
return false;
|
|
1445
1444
|
}
|
|
1445
|
+
const current = judgeSetting(ctx.files, pkgOf(ctx).judge.name);
|
|
1446
|
+
return current.enabled && current.localOnly;
|
|
1446
1447
|
}
|
|
1447
1448
|
function startedAt(pid) {
|
|
1448
1449
|
try {
|
package/judge/manifest.json
CHANGED
|
@@ -270,7 +270,7 @@
|
|
|
270
270
|
},
|
|
271
271
|
"summary": {
|
|
272
272
|
"zh": "任务进行中你又发来一句话:判断是在下一步就带进工作,还是等这一轮做完再处理。判定最多等 1.5 秒;没有判定时,消息按你发送的方式送达。",
|
|
273
|
-
"en": "For a message you send while the agent is working:
|
|
273
|
+
"en": "For a message you send while the agent is working: deliver it 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
274
|
"zh-TW": "任務進行中你又傳來一則訊息:判斷是在下一步就帶進工作,還是等這一輪做完再處理。判定最多等 1.5 秒;沒有判定時,訊息照你傳送的方式送達。",
|
|
275
275
|
"ja-JP": "エージェントの作業中に送ったメッセージを、次のステップで作業に取り込むか、実行が終わるまで待たせるかを判定します。判定は最大 1.5 秒待ち、判定がなければメッセージは送ったとおりに届きます。",
|
|
276
276
|
"ko-KR": "에이전트가 작업하는 중에 보낸 메시지를 다음 단계에서 작업에 반영할지, 실행이 끝날 때까지 기다리게 할지 판정합니다. 판정은 최대 1.5초 기다리며, 판정이 없으면 메시지는 보낸 그대로 전달됩니다.",
|
|
@@ -1381,7 +1381,7 @@
|
|
|
1381
1381
|
},
|
|
1382
1382
|
"summary": {
|
|
1383
1383
|
"zh": "上下文预算、后台命令结束等事件出现时,判断该现在告诉模型、稍后再说,还是不必说。默认是影子模式:判定只记录,事件按各自的规则投递,后台命令结束和上下文预算都是立刻告知。",
|
|
1384
|
-
"en": "For events such as the context budget or a background job's end: tell the model now, later or not at all. In shadow by default: the verdict is only logged, and each event is delivered by its own rule
|
|
1384
|
+
"en": "For events such as the context budget or a background job's end: tell the model now, later or not at all. In shadow by default: the verdict is only logged, and each event is delivered by its own rule (right away for a job's end and the context budget).",
|
|
1385
1385
|
"zh-TW": "上下文預算、背景工作結束這類事件出現時,判斷該現在告訴模型、晚點再說,還是不必說。預設為影子模式:判定只記錄下來,事件各按自己的規則送達;背景工作結束和上下文預算都是立刻告知。",
|
|
1386
1386
|
"ja-JP": "コンテキスト予算やバックグラウンドジョブの終了などのイベントを、モデルにすぐ伝えるか、後で伝えるか、伝えないかを判定します。既定ではシャドーモードです。判定は記録するだけで、各イベントはそれぞれのルールで届けます。ジョブの終了とコンテキスト予算の場合は、すぐに届けます。",
|
|
1387
1387
|
"ko-KR": "컨텍스트 예산이나 백그라운드 작업 종료 같은 이벤트를 모델에게 지금 알릴지, 나중에 알릴지, 알리지 않을지 정합니다. 기본값은 섀도 모드입니다. 판정은 기록만 하고 각 이벤트는 자체 규칙에 따라 전달되는데, 작업 종료와 컨텍스트 예산은 바로 알립니다.",
|
package/judge/mu/index.js
CHANGED
|
@@ -15046,7 +15046,7 @@ var require_snapshot_recorder = __commonJS({
|
|
|
15046
15046
|
"node_modules/undici/lib/mock/snapshot-recorder.js"(exports, module) {
|
|
15047
15047
|
"use strict";
|
|
15048
15048
|
var { writeFile: writeFile7, readFile: readFile6, mkdir: mkdir2 } = __require("node:fs/promises");
|
|
15049
|
-
var { dirname:
|
|
15049
|
+
var { dirname: dirname13, resolve: resolve15 } = __require("node:path");
|
|
15050
15050
|
var { setTimeout: setTimeout2, clearTimeout: clearTimeout2 } = __require("node:timers");
|
|
15051
15051
|
var { InvalidArgumentError, UndiciError } = require_errors();
|
|
15052
15052
|
var { hashId, isUrlExcludedFactory, normalizeHeaders, createHeaderFilters } = require_snapshot_utils();
|
|
@@ -15292,7 +15292,7 @@ var require_snapshot_recorder = __commonJS({
|
|
|
15292
15292
|
throw new InvalidArgumentError("Snapshot path is required");
|
|
15293
15293
|
}
|
|
15294
15294
|
const resolvedPath = resolve15(path);
|
|
15295
|
-
await mkdir2(
|
|
15295
|
+
await mkdir2(dirname13(resolvedPath), { recursive: true });
|
|
15296
15296
|
const data = Array.from(this.#snapshots.entries()).map(([hash, snapshot2]) => ({
|
|
15297
15297
|
hash,
|
|
15298
15298
|
snapshot: snapshot2
|
|
@@ -37933,7 +37933,7 @@ var helpSectionsEn = () => [
|
|
|
37933
37933
|
},
|
|
37934
37934
|
{
|
|
37935
37935
|
title: "Judgment kernel",
|
|
37936
|
-
intro: `
|
|
37936
|
+
intro: `While the judge reads a message, esc skips the wait; ${(0, import_pi_coding_agent5.keyText)("app.tools.expand")} shows the full answers behind a verdict.`,
|
|
37937
37937
|
rows: [
|
|
37938
37938
|
[
|
|
37939
37939
|
"/mu judge <judges>",
|
|
@@ -38235,7 +38235,12 @@ function registerCommands(runtime, roots) {
|
|
|
38235
38235
|
"decisions",
|
|
38236
38236
|
`default mode ${engine.getMode("*")}. Change it with /mu mode default <off|shadow|active>`
|
|
38237
38237
|
],
|
|
38238
|
-
|
|
38238
|
+
// Only mu's browser needs one: without it the rest of mu works.
|
|
38239
|
+
[
|
|
38240
|
+
chrome ? "ok " : "-- ",
|
|
38241
|
+
"browser",
|
|
38242
|
+
chrome ?? `optional, for mu's browser. ${browserAdvice(browserHost)}`
|
|
38243
|
+
],
|
|
38239
38244
|
[
|
|
38240
38245
|
"-- ",
|
|
38241
38246
|
"browse",
|
|
@@ -39940,9 +39945,30 @@ last update failed: ${lastFailure}` : text7, "info");
|
|
|
39940
39945
|
});
|
|
39941
39946
|
}
|
|
39942
39947
|
|
|
39948
|
+
// packages/kyrn-judge/src/extension/features/notices.ts
|
|
39949
|
+
import { readFileSync as readFileSync13 } from "node:fs";
|
|
39950
|
+
import { join as join23 } from "node:path";
|
|
39951
|
+
function noticesFile(agentDir) {
|
|
39952
|
+
return join23(agentDir, "mu", "notices.json");
|
|
39953
|
+
}
|
|
39954
|
+
function readNotices(file) {
|
|
39955
|
+
if (!file) return {};
|
|
39956
|
+
try {
|
|
39957
|
+
const value = JSON.parse(readFileSync13(file, "utf8"));
|
|
39958
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : {};
|
|
39959
|
+
} catch {
|
|
39960
|
+
return {};
|
|
39961
|
+
}
|
|
39962
|
+
}
|
|
39963
|
+
function writeNotice(file, key, value) {
|
|
39964
|
+
const notices = { ...readNotices(file), version: 1 };
|
|
39965
|
+
if (value === void 0) delete notices[key];
|
|
39966
|
+
else notices[key] = value;
|
|
39967
|
+
writeFileAtomic(file, `${JSON.stringify(notices, null, " ")}
|
|
39968
|
+
`);
|
|
39969
|
+
}
|
|
39970
|
+
|
|
39943
39971
|
// packages/kyrn-judge/src/extension/features/free-jev.ts
|
|
39944
|
-
import { mkdirSync as mkdirSync11, readFileSync as readFileSync13, writeFileSync as writeFileSync9 } from "node:fs";
|
|
39945
|
-
import { dirname as dirname5, join as join23 } from "node:path";
|
|
39946
39972
|
var ENDED = /* @__PURE__ */ new Map([
|
|
39947
39973
|
["auth", "paid"],
|
|
39948
39974
|
["payment_required", "paid"],
|
|
@@ -39953,25 +39979,18 @@ var today = () => {
|
|
|
39953
39979
|
return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}-${String(now.getDate()).padStart(2, "0")}`;
|
|
39954
39980
|
};
|
|
39955
39981
|
function saidOn(file) {
|
|
39956
|
-
|
|
39957
|
-
|
|
39958
|
-
const value = JSON.parse(readFileSync13(file, "utf8"));
|
|
39959
|
-
return typeof value.freeJev === "string" ? value.freeJev : void 0;
|
|
39960
|
-
} catch {
|
|
39961
|
-
return void 0;
|
|
39962
|
-
}
|
|
39982
|
+
const day = readNotices(file).freeJev;
|
|
39983
|
+
return typeof day === "string" ? day : void 0;
|
|
39963
39984
|
}
|
|
39964
39985
|
function markSaid(file, day) {
|
|
39965
39986
|
if (!file) return;
|
|
39966
39987
|
try {
|
|
39967
|
-
|
|
39968
|
-
writeFileSync9(file, `${JSON.stringify({ version: 1, freeJev: day }, null, " ")}
|
|
39969
|
-
`);
|
|
39988
|
+
writeNotice(file, "freeJev", day);
|
|
39970
39989
|
} catch {
|
|
39971
39990
|
}
|
|
39972
39991
|
}
|
|
39973
39992
|
function registerFreeJevNotice(runtime, roots) {
|
|
39974
|
-
const file = roots ?
|
|
39993
|
+
const file = roots ? noticesFile(roots.agentDir) : void 0;
|
|
39975
39994
|
let inUseSaid = false;
|
|
39976
39995
|
let endSaid = false;
|
|
39977
39996
|
const tell = (code, message, reason) => {
|
|
@@ -41407,7 +41426,7 @@ var hiveRelate = defineDecision({
|
|
|
41407
41426
|
});
|
|
41408
41427
|
|
|
41409
41428
|
// packages/kyrn-judge/src/hive/board.ts
|
|
41410
|
-
import { appendFileSync as appendFileSync3, closeSync as closeSync2, fstatSync, mkdirSync as
|
|
41429
|
+
import { appendFileSync as appendFileSync3, closeSync as closeSync2, fstatSync, mkdirSync as mkdirSync11, openSync as openSync2, readSync as readSync2 } from "node:fs";
|
|
41411
41430
|
import { join as join24 } from "node:path";
|
|
41412
41431
|
var BOARD = "board.jsonl";
|
|
41413
41432
|
var DELIVERIES = "deliveries.jsonl";
|
|
@@ -41450,7 +41469,7 @@ var Board = class {
|
|
|
41450
41469
|
offset = 0;
|
|
41451
41470
|
constructor(dir) {
|
|
41452
41471
|
this.dir = dir;
|
|
41453
|
-
|
|
41472
|
+
mkdirSync11(dir, { recursive: true });
|
|
41454
41473
|
}
|
|
41455
41474
|
post(note2) {
|
|
41456
41475
|
appendFileSync3(join24(this.dir, BOARD), `${JSON.stringify(note2)}
|
|
@@ -41643,7 +41662,7 @@ var swarmRouting = defineDecision({
|
|
|
41643
41662
|
|
|
41644
41663
|
// packages/kyrn-judge/src/swarm/patches.ts
|
|
41645
41664
|
import { randomBytes } from "node:crypto";
|
|
41646
|
-
import { mkdirSync as
|
|
41665
|
+
import { mkdirSync as mkdirSync12, readFileSync as readFileSync14, writeFileSync as writeFileSync9 } from "node:fs";
|
|
41647
41666
|
import { rm as rm2 } from "node:fs/promises";
|
|
41648
41667
|
import { join as join26 } from "node:path";
|
|
41649
41668
|
|
|
@@ -41651,7 +41670,7 @@ import { join as join26 } from "node:path";
|
|
|
41651
41670
|
import { spawn as spawn5 } from "node:child_process";
|
|
41652
41671
|
import { existsSync as existsSync11 } from "node:fs";
|
|
41653
41672
|
import { chmod, copyFile, lstat, mkdir, readdir, readFile, readlink, rm, symlink, writeFile } from "node:fs/promises";
|
|
41654
|
-
import { dirname as
|
|
41673
|
+
import { dirname as dirname5, join as join25 } from "node:path";
|
|
41655
41674
|
function gitArgs(args, platform = process.platform) {
|
|
41656
41675
|
return [
|
|
41657
41676
|
"-c",
|
|
@@ -41757,7 +41776,7 @@ async function copyUntracked(from, to, paths, maxBytes) {
|
|
|
41757
41776
|
if (path.endsWith("/")) continue;
|
|
41758
41777
|
try {
|
|
41759
41778
|
const stat = await lstat(join25(from, path));
|
|
41760
|
-
await mkdir(
|
|
41779
|
+
await mkdir(dirname5(join25(to, path)), { recursive: true });
|
|
41761
41780
|
if (stat.isSymbolicLink()) await symlink(await readlink(join25(from, path)), join25(to, path));
|
|
41762
41781
|
else if (!stat.isFile()) continue;
|
|
41763
41782
|
else if (stat.size > maxBytes) {
|
|
@@ -41895,8 +41914,8 @@ async function removeWorktree(run2, worktree) {
|
|
|
41895
41914
|
}
|
|
41896
41915
|
var markerPath = (dir) => `${dir}.json`;
|
|
41897
41916
|
async function writeMarker(marker) {
|
|
41898
|
-
await mkdir(
|
|
41899
|
-
await chmod(
|
|
41917
|
+
await mkdir(dirname5(marker.dir), { recursive: true });
|
|
41918
|
+
await chmod(dirname5(marker.dir), 448).catch(() => void 0);
|
|
41900
41919
|
await writeFile(markerPath(marker.dir), JSON.stringify(marker), { mode: 384 });
|
|
41901
41920
|
}
|
|
41902
41921
|
var RUN_DIR = /^kyrn-swarm-[\w-]+$/;
|
|
@@ -41947,7 +41966,7 @@ var PatchStore = class {
|
|
|
41947
41966
|
do
|
|
41948
41967
|
id = `p-${randomBytes(3).toString("hex")}`;
|
|
41949
41968
|
while (this.records.has(id));
|
|
41950
|
-
|
|
41969
|
+
mkdirSync12(dir, { recursive: true, mode: 448 });
|
|
41951
41970
|
const record4 = {
|
|
41952
41971
|
...details,
|
|
41953
41972
|
id,
|
|
@@ -41955,7 +41974,7 @@ var PatchStore = class {
|
|
|
41955
41974
|
createdAt: Date.now(),
|
|
41956
41975
|
status: "ready"
|
|
41957
41976
|
};
|
|
41958
|
-
|
|
41977
|
+
writeFileSync9(record4.path, patch, { mode: 384 });
|
|
41959
41978
|
this.records.set(id, record4);
|
|
41960
41979
|
this.persist(record4);
|
|
41961
41980
|
return record4;
|
|
@@ -41974,7 +41993,7 @@ var PatchStore = class {
|
|
|
41974
41993
|
}
|
|
41975
41994
|
persist(record4) {
|
|
41976
41995
|
try {
|
|
41977
|
-
|
|
41996
|
+
writeFileSync9(record4.path.replace(/\.patch$/, ".json"), JSON.stringify(record4, null, " "), { mode: 384 });
|
|
41978
41997
|
} catch {
|
|
41979
41998
|
}
|
|
41980
41999
|
}
|
|
@@ -42059,7 +42078,7 @@ async function applyPatch(run2, options) {
|
|
|
42059
42078
|
return { code: applied.code, stderr: applied.stderr, unmerged: [...new Set(paths)] };
|
|
42060
42079
|
};
|
|
42061
42080
|
try {
|
|
42062
|
-
|
|
42081
|
+
mkdirSync12(options.scratchDir, { recursive: true, mode: 448 });
|
|
42063
42082
|
const dry = await attempt(true);
|
|
42064
42083
|
if (dry.code !== 0 && dry.unmerged.length === 0) return { status: "failed", reasons: errorLines(dry.stderr) };
|
|
42065
42084
|
if (dry.unmerged.length > 0 && options.onConflict === "abort")
|
|
@@ -42241,7 +42260,7 @@ function swarmText(snapshot2, options) {
|
|
|
42241
42260
|
var import_typebox5 = __toESM(require_typebox(), 1);
|
|
42242
42261
|
import { rm as rm3 } from "node:fs/promises";
|
|
42243
42262
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
42244
|
-
import { basename as basename5, dirname as
|
|
42263
|
+
import { basename as basename5, dirname as dirname6, join as join27 } from "node:path";
|
|
42245
42264
|
|
|
42246
42265
|
// packages/kyrn-judge/src/decisions/swarm-patch.ts
|
|
42247
42266
|
var MAX_JUDGED_FILES = 12;
|
|
@@ -42538,7 +42557,7 @@ ${statLines(record4.summary, 200).join("\n")}`);
|
|
|
42538
42557
|
patchPath: record4.path,
|
|
42539
42558
|
files: record4.summary.files,
|
|
42540
42559
|
onConflict: params.conflicts ?? "abort",
|
|
42541
|
-
scratchDir: join27(
|
|
42560
|
+
scratchDir: join27(dirname6(record4.path), "scratch"),
|
|
42542
42561
|
signal
|
|
42543
42562
|
});
|
|
42544
42563
|
const details = { id: record4.id, result };
|
|
@@ -43194,7 +43213,7 @@ function registerSwarmCommand(runtime) {
|
|
|
43194
43213
|
}
|
|
43195
43214
|
|
|
43196
43215
|
// packages/kyrn-judge/src/extension/features/swarm-child.ts
|
|
43197
|
-
import { readFileSync as readFileSync15, renameSync as renameSync5, writeFileSync as
|
|
43216
|
+
import { readFileSync as readFileSync15, renameSync as renameSync5, writeFileSync as writeFileSync10 } from "node:fs";
|
|
43198
43217
|
var states = /* @__PURE__ */ new WeakMap();
|
|
43199
43218
|
function isWrappingUp(runtime) {
|
|
43200
43219
|
return states.get(runtime)?.wrapping === true;
|
|
@@ -43222,7 +43241,7 @@ function registerSwarmChild(runtime, path, frameOutPath2) {
|
|
|
43222
43241
|
const text7 = JSON.stringify(frameOut(frame));
|
|
43223
43242
|
if (text7 === saved) return void 0;
|
|
43224
43243
|
try {
|
|
43225
|
-
|
|
43244
|
+
writeFileSync10(`${frameOutPath2}.tmp`, text7);
|
|
43226
43245
|
renameSync5(`${frameOutPath2}.tmp`, frameOutPath2);
|
|
43227
43246
|
saved = text7;
|
|
43228
43247
|
} catch {
|
|
@@ -43926,7 +43945,7 @@ var import_pi_coding_agent9 = __toESM(require_pi_coding_agent(), 1);
|
|
|
43926
43945
|
var import_pi_tui4 = __toESM(require_pi_tui(), 1);
|
|
43927
43946
|
|
|
43928
43947
|
// packages/kyrn-judge/src/import/index.ts
|
|
43929
|
-
import { mkdirSync as
|
|
43948
|
+
import { mkdirSync as mkdirSync13, readdirSync as readdirSync6, readFileSync as readFileSync16, realpathSync as realpathSync2, renameSync as renameSync7, statSync as statSync11, writeFileSync as writeFileSync11 } from "node:fs";
|
|
43930
43949
|
import { homedir as homedir7 } from "node:os";
|
|
43931
43950
|
import { join as join32 } from "node:path";
|
|
43932
43951
|
|
|
@@ -45973,8 +45992,8 @@ function readChecks(store) {
|
|
|
45973
45992
|
function writeChecks(store, checks) {
|
|
45974
45993
|
const file = checksFile(store);
|
|
45975
45994
|
try {
|
|
45976
|
-
|
|
45977
|
-
|
|
45995
|
+
mkdirSync13(absolute(store.agentDir), { recursive: true });
|
|
45996
|
+
writeFileSync11(`${file}.tmp`, `${JSON.stringify(checks, null, 1)}
|
|
45978
45997
|
`, { mode: 384 });
|
|
45979
45998
|
renameSync7(`${file}.tmp`, file);
|
|
45980
45999
|
} catch {
|
|
@@ -46146,7 +46165,7 @@ async function importOne(path, options, imports, checks) {
|
|
|
46146
46165
|
}
|
|
46147
46166
|
if (earlier) converted = await read(tool, source, readOptions());
|
|
46148
46167
|
const dir = sessionDirFor(converted.cwd, options);
|
|
46149
|
-
|
|
46168
|
+
mkdirSync13(dir, { recursive: true });
|
|
46150
46169
|
const sessionFile = join32(dir, sessionFileName(converted.started, converted.sessionId));
|
|
46151
46170
|
writeSessionFile(sessionFile, converted.entries);
|
|
46152
46171
|
imports.push({
|
|
@@ -46355,7 +46374,7 @@ import { isAbsolute as isAbsolute4, join as join38, resolve as resolve7 } from "
|
|
|
46355
46374
|
|
|
46356
46375
|
// packages/kyrn-judge/src/inherit/files.ts
|
|
46357
46376
|
import { existsSync as existsSync13, readdirSync as readdirSync7, readFileSync as readFileSync17, realpathSync as realpathSync3, statSync as statSync12 } from "node:fs";
|
|
46358
|
-
import { dirname as
|
|
46377
|
+
import { dirname as dirname7, join as join33, resolve as resolve5 } from "node:path";
|
|
46359
46378
|
var MAX_FILE_BYTES = 2 * 1024 * 1024;
|
|
46360
46379
|
function projectChain(projectDir, home) {
|
|
46361
46380
|
const start = resolve5(projectDir);
|
|
@@ -46366,7 +46385,7 @@ function projectChain(projectDir, home) {
|
|
|
46366
46385
|
if (current === homeDir) break;
|
|
46367
46386
|
chain.push(current);
|
|
46368
46387
|
if (existsSync13(join33(current, ".git"))) return chain;
|
|
46369
|
-
const parent =
|
|
46388
|
+
const parent = dirname7(current);
|
|
46370
46389
|
if (parent === current) break;
|
|
46371
46390
|
current = parent;
|
|
46372
46391
|
}
|
|
@@ -46679,8 +46698,8 @@ function rulesForFile(rules, filePath) {
|
|
|
46679
46698
|
}
|
|
46680
46699
|
|
|
46681
46700
|
// packages/kyrn-judge/src/inherit/scan.ts
|
|
46682
|
-
import { mkdirSync as
|
|
46683
|
-
import { dirname as
|
|
46701
|
+
import { mkdirSync as mkdirSync14, readFileSync as readFileSync18, writeFileSync as writeFileSync12 } from "node:fs";
|
|
46702
|
+
import { dirname as dirname8, join as join37 } from "node:path";
|
|
46684
46703
|
|
|
46685
46704
|
// packages/kyrn-judge/src/inherit/mcp-config.ts
|
|
46686
46705
|
import { join as join35, resolve as resolve6 } from "node:path";
|
|
@@ -47368,8 +47387,8 @@ function readInheritState(agentDir) {
|
|
|
47368
47387
|
}
|
|
47369
47388
|
function writeInheritState(agentDir, state) {
|
|
47370
47389
|
const path = inheritStatePath(agentDir);
|
|
47371
|
-
|
|
47372
|
-
|
|
47390
|
+
mkdirSync14(dirname8(path), { recursive: true });
|
|
47391
|
+
writeFileSync12(path, `${JSON.stringify(state, null, " ")}
|
|
47373
47392
|
`);
|
|
47374
47393
|
}
|
|
47375
47394
|
|
|
@@ -47622,8 +47641,8 @@ function looksPoisoned(text7) {
|
|
|
47622
47641
|
// packages/kyrn-judge/src/extension/features/tool-descriptions.ts
|
|
47623
47642
|
var import_pi_coding_agent11 = __toESM(require_pi_coding_agent(), 1);
|
|
47624
47643
|
import { createHash as createHash6 } from "node:crypto";
|
|
47625
|
-
import { mkdirSync as
|
|
47626
|
-
import { dirname as
|
|
47644
|
+
import { mkdirSync as mkdirSync15, readFileSync as readFileSync19, renameSync as renameSync8, writeFileSync as writeFileSync13 } from "node:fs";
|
|
47645
|
+
import { dirname as dirname9, join as join39 } from "node:path";
|
|
47627
47646
|
var STORE_LIMIT = 2e3;
|
|
47628
47647
|
var VerdictStore = class {
|
|
47629
47648
|
file;
|
|
@@ -47658,9 +47677,9 @@ var VerdictStore = class {
|
|
|
47658
47677
|
const newest = [...all].sort(([, a], [, b]) => b.at - a.at).slice(0, STORE_LIMIT);
|
|
47659
47678
|
const flat4 = Object.fromEntries(newest.map(([key, entry]) => [key, { ...entry.verdict, at: entry.at }]));
|
|
47660
47679
|
try {
|
|
47661
|
-
|
|
47680
|
+
mkdirSync15(dirname9(this.file), { recursive: true });
|
|
47662
47681
|
const temp = `${this.file}.${process.pid}.tmp`;
|
|
47663
|
-
|
|
47682
|
+
writeFileSync13(temp, `${JSON.stringify({ version: 1, verdicts: flat4 })}
|
|
47664
47683
|
`, { mode: 384 });
|
|
47665
47684
|
renameSync8(temp, this.file);
|
|
47666
47685
|
} catch {
|
|
@@ -49214,15 +49233,19 @@ function registerJudgeItems(runtime) {
|
|
|
49214
49233
|
}
|
|
49215
49234
|
|
|
49216
49235
|
// packages/kyrn-judge/src/extension/features/laya.ts
|
|
49236
|
+
var PENDING_KEY = "layaRemoved";
|
|
49237
|
+
function layaNoticeOf(skipped, first) {
|
|
49238
|
+
return { judge: skipped.replacement ?? first, from: skipped.env && !skipped.file ? "MU_JUDGE" : "mu.json" };
|
|
49239
|
+
}
|
|
49217
49240
|
function judgeName(name) {
|
|
49218
49241
|
return name === "mude" ? "mude 1.0" : judgeDisplayName(name);
|
|
49219
49242
|
}
|
|
49220
|
-
function layaNotice(
|
|
49221
|
-
const name = judgeName(
|
|
49222
|
-
if (
|
|
49243
|
+
function layaNotice(notice) {
|
|
49244
|
+
const name = judgeName(notice.judge);
|
|
49245
|
+
if (notice.from === "MU_JUDGE") {
|
|
49223
49246
|
return say({
|
|
49224
49247
|
zh: `mu\uFF1A\u4E0D\u518D\u5185\u7F6E Laya\uFF0C\u6240\u4EE5\u8DF3\u8FC7\u4E86 MU_JUDGE \u91CC\u7684 laya\uFF0C\u5224\u5B9A\u5668\u73B0\u5728\u662F ${name}\u3002\u60F3\u7528\u522B\u7684\u51B3\u7B56\u6A21\u578B\uFF0C\u53EF\u4EE5\u4ECE Hugging Face \u6DFB\u52A0\uFF1Amu judge model add <\u94FE\u63A5>\uFF08\u6216\u5728\u684C\u9762\u7AEF\u300C\u8BBE\u7F6E \u2192 \u5224\u5B9A\u5668\u300D\u91CC\u6DFB\u52A0\uFF09\u3002`,
|
|
49225
|
-
en: `mu: Laya is no longer built in, so mu skips
|
|
49248
|
+
en: `mu: Laya is no longer built in, so mu skips laya in MU_JUDGE and your judge is now ${name}. To use another decision model, add it from Hugging Face: mu judge model add <link> (or Settings \u2192 Judges in the desktop app).`
|
|
49226
49249
|
});
|
|
49227
49250
|
}
|
|
49228
49251
|
return say({
|
|
@@ -49230,21 +49253,60 @@ function layaNotice(skipped, judge) {
|
|
|
49230
49253
|
en: `mu: Laya is no longer built in, so your judge is now ${name}. To use another decision model, add it from Hugging Face: mu judge model add <link> (or Settings \u2192 Judges in the desktop app).`
|
|
49231
49254
|
});
|
|
49232
49255
|
}
|
|
49256
|
+
function pendingLayaNotice(file) {
|
|
49257
|
+
const value = readNotices(file)[PENDING_KEY];
|
|
49258
|
+
if (typeof value !== "object" || value === null) return void 0;
|
|
49259
|
+
const { judge, from } = value;
|
|
49260
|
+
if (typeof judge !== "string" || !judge.trim()) return void 0;
|
|
49261
|
+
return { judge, from: from === "MU_JUDGE" ? "MU_JUDGE" : "mu.json" };
|
|
49262
|
+
}
|
|
49263
|
+
function holdNotice(file, notice) {
|
|
49264
|
+
try {
|
|
49265
|
+
if (notice.from === "MU_JUDGE" && pendingLayaNotice(file)?.from === "mu.json") return true;
|
|
49266
|
+
writeNotice(file, PENDING_KEY, notice);
|
|
49267
|
+
return true;
|
|
49268
|
+
} catch {
|
|
49269
|
+
return false;
|
|
49270
|
+
}
|
|
49271
|
+
}
|
|
49233
49272
|
function registerLayaNotice(runtime, skipped, roots, muHome2) {
|
|
49234
|
-
|
|
49235
|
-
|
|
49273
|
+
const file = roots ? noticesFile(roots.agentDir) : void 0;
|
|
49274
|
+
if (!skipped && !file) return;
|
|
49275
|
+
let held;
|
|
49276
|
+
let started = false;
|
|
49277
|
+
let asked = false;
|
|
49278
|
+
if (skipped) {
|
|
49279
|
+
runtime.pi.on("session_start", (_event, ctx) => {
|
|
49280
|
+
try {
|
|
49281
|
+
if (started || !ctx.hasUI) return;
|
|
49282
|
+
started = true;
|
|
49283
|
+
if (skipped.file && roots) {
|
|
49284
|
+
migrateConfigFile({ agentDir: roots.agentDir, muHome: muHome2, replacement: skipped.replacement });
|
|
49285
|
+
}
|
|
49286
|
+
const notice = layaNoticeOf(skipped, runtime.config.tiers[0] ?? "jev");
|
|
49287
|
+
if (!file || !holdNotice(file, notice)) held = notice;
|
|
49288
|
+
} catch {
|
|
49289
|
+
}
|
|
49290
|
+
});
|
|
49291
|
+
}
|
|
49292
|
+
runtime.pi.on("input", (event, ctx) => {
|
|
49236
49293
|
try {
|
|
49237
|
-
if (
|
|
49238
|
-
|
|
49239
|
-
|
|
49240
|
-
|
|
49241
|
-
|
|
49242
|
-
|
|
49243
|
-
|
|
49244
|
-
|
|
49245
|
-
|
|
49246
|
-
|
|
49247
|
-
|
|
49294
|
+
if (asked || !ctx.hasUI || event.source === "extension") return;
|
|
49295
|
+
if (!event.text.trim() && !event.images?.length) return;
|
|
49296
|
+
asked = true;
|
|
49297
|
+
const waiting = pendingLayaNotice(file);
|
|
49298
|
+
const notice = waiting ?? held;
|
|
49299
|
+
if (!notice) return;
|
|
49300
|
+
held = void 0;
|
|
49301
|
+
if (waiting && file) {
|
|
49302
|
+
try {
|
|
49303
|
+
writeNotice(file, PENDING_KEY, void 0);
|
|
49304
|
+
} catch {
|
|
49305
|
+
}
|
|
49306
|
+
}
|
|
49307
|
+
const message = layaNotice(notice);
|
|
49308
|
+
runtime.touch(ctx);
|
|
49309
|
+
runtime.present("judge.notice", { code: "laya_removed", judge: notice.judge, message });
|
|
49248
49310
|
ctx.ui.notify(message, "info");
|
|
49249
49311
|
} catch {
|
|
49250
49312
|
}
|
|
@@ -50967,7 +51029,7 @@ function capabilityId(serverName) {
|
|
|
50967
51029
|
|
|
50968
51030
|
// packages/kyrn-judge/src/mcp/store.ts
|
|
50969
51031
|
import { createHash as createHash7 } from "node:crypto";
|
|
50970
|
-
import { mkdirSync as
|
|
51032
|
+
import { mkdirSync as mkdirSync16, readFileSync as readFileSync21, renameSync as renameSync9, writeFileSync as writeFileSync14 } from "node:fs";
|
|
50971
51033
|
import { join as join41, resolve as resolve9 } from "node:path";
|
|
50972
51034
|
var DESCRIPTION_LENGTH2 = 200;
|
|
50973
51035
|
function sorted(map) {
|
|
@@ -50999,9 +51061,9 @@ function readJson(path, empty) {
|
|
|
50999
51061
|
function writeJson(path, value) {
|
|
51000
51062
|
if (!path) return;
|
|
51001
51063
|
try {
|
|
51002
|
-
|
|
51064
|
+
mkdirSync16(resolve9(path, ".."), { recursive: true });
|
|
51003
51065
|
const temporary = `${path}.${process.pid}.tmp`;
|
|
51004
|
-
|
|
51066
|
+
writeFileSync14(temporary, `${JSON.stringify(value, null, " ")}
|
|
51005
51067
|
`);
|
|
51006
51068
|
renameSync9(temporary, path);
|
|
51007
51069
|
} catch {
|
|
@@ -51664,8 +51726,8 @@ function turnDigest(turn) {
|
|
|
51664
51726
|
}
|
|
51665
51727
|
|
|
51666
51728
|
// packages/kyrn-judge/src/memory/store.ts
|
|
51667
|
-
import { appendFileSync as appendFileSync4, closeSync as closeSync5, fstatSync as fstatSync3, mkdirSync as
|
|
51668
|
-
import { dirname as
|
|
51729
|
+
import { appendFileSync as appendFileSync4, closeSync as closeSync5, fstatSync as fstatSync3, mkdirSync as mkdirSync17, openSync as openSync5, readFileSync as readFileSync22, readSync as readSync4 } from "node:fs";
|
|
51730
|
+
import { dirname as dirname10 } from "node:path";
|
|
51669
51731
|
var KINDS4 = ["correction", "preference", "pitfall", "workaround", "fact"];
|
|
51670
51732
|
var ORIGINS = ["user", "outcome", "model", "subagent", "command"];
|
|
51671
51733
|
var STATUSES = ["active", "retired", "superseded"];
|
|
@@ -51769,7 +51831,7 @@ function endsOpen(path) {
|
|
|
51769
51831
|
}
|
|
51770
51832
|
}
|
|
51771
51833
|
function writeLesson(path, line2) {
|
|
51772
|
-
|
|
51834
|
+
mkdirSync17(dirname10(path), { recursive: true });
|
|
51773
51835
|
appendFileSync4(path, `${endsOpen(path) ? "\n" : ""}${JSON.stringify(line2)}
|
|
51774
51836
|
`);
|
|
51775
51837
|
}
|
|
@@ -54155,7 +54217,7 @@ function report2(outcome) {
|
|
|
54155
54217
|
var import_typebox12 = __toESM(require_typebox(), 1);
|
|
54156
54218
|
import { realpathSync as realpathSync4 } from "node:fs";
|
|
54157
54219
|
import { readFile as readFile5, writeFile as writeFile6 } from "node:fs/promises";
|
|
54158
|
-
import { basename as basename13, dirname as
|
|
54220
|
+
import { basename as basename13, dirname as dirname11, isAbsolute as isAbsolute5, join as join46, relative as relative5 } from "node:path";
|
|
54159
54221
|
|
|
54160
54222
|
// packages/kyrn-judge/src/packs/conflicts.ts
|
|
54161
54223
|
import { mkdtemp as mkdtemp2, rm as rm5, writeFile as writeFile5 } from "node:fs/promises";
|
|
@@ -54292,7 +54354,7 @@ function real(path) {
|
|
|
54292
54354
|
try {
|
|
54293
54355
|
return realpathSync4.native(path);
|
|
54294
54356
|
} catch {
|
|
54295
|
-
const parent =
|
|
54357
|
+
const parent = dirname11(path);
|
|
54296
54358
|
return parent === path ? path : join46(real(parent), basename13(path));
|
|
54297
54359
|
}
|
|
54298
54360
|
}
|
|
@@ -55738,9 +55800,9 @@ var toolApproval = defineDecision({
|
|
|
55738
55800
|
});
|
|
55739
55801
|
|
|
55740
55802
|
// packages/kyrn-judge/src/permissions/modes.ts
|
|
55741
|
-
import { lstatSync as lstatSync2, mkdirSync as
|
|
55803
|
+
import { lstatSync as lstatSync2, mkdirSync as mkdirSync18, readFileSync as readFileSync23, readlinkSync, realpathSync as realpathSync5, renameSync as renameSync10, writeFileSync as writeFileSync15 } from "node:fs";
|
|
55742
55804
|
import { homedir as homedir10 } from "node:os";
|
|
55743
|
-
import { basename as basename14, dirname as
|
|
55805
|
+
import { basename as basename14, dirname as dirname12, isAbsolute as isAbsolute7, join as join47, relative as relative7, resolve as resolve12, sep as sep2 } from "node:path";
|
|
55744
55806
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
55745
55807
|
var PERMISSION_MODES = ["full", "judge", "ask"];
|
|
55746
55808
|
var MODE_TEXT = {
|
|
@@ -55828,11 +55890,11 @@ function realPath2(path, depth = 0) {
|
|
|
55828
55890
|
if (depth < 40) {
|
|
55829
55891
|
try {
|
|
55830
55892
|
if (lstatSync2(path).isSymbolicLink())
|
|
55831
|
-
return realPath2(resolve12(
|
|
55893
|
+
return realPath2(resolve12(dirname12(path), readlinkSync(path)), depth + 1);
|
|
55832
55894
|
} catch {
|
|
55833
55895
|
}
|
|
55834
55896
|
}
|
|
55835
|
-
const parent =
|
|
55897
|
+
const parent = dirname12(path);
|
|
55836
55898
|
return parent === path ? path : join47(realPath2(parent, depth + 1), basename14(path));
|
|
55837
55899
|
}
|
|
55838
55900
|
}
|
|
@@ -55973,9 +56035,9 @@ var PermissionDefaults = class {
|
|
|
55973
56035
|
this.memory = mode;
|
|
55974
56036
|
return;
|
|
55975
56037
|
}
|
|
55976
|
-
|
|
56038
|
+
mkdirSync18(join47(this.file, ".."), { recursive: true });
|
|
55977
56039
|
const temp = `${this.file}.${process.pid}.tmp`;
|
|
55978
|
-
|
|
56040
|
+
writeFileSync15(temp, `${JSON.stringify({ version: 1, mode }, null, " ")}
|
|
55979
56041
|
`, { mode: 384 });
|
|
55980
56042
|
renameSync10(temp, this.file);
|
|
55981
56043
|
}
|
|
@@ -56970,7 +57032,7 @@ var skillCapture = defineDecision({
|
|
|
56970
57032
|
});
|
|
56971
57033
|
|
|
56972
57034
|
// packages/kyrn-judge/src/memory/skill-drafts.ts
|
|
56973
|
-
import { existsSync as existsSync16, mkdirSync as
|
|
57035
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync19, readdirSync as readdirSync9, readFileSync as readFileSync24, rmSync as rmSync8, writeFileSync as writeFileSync16 } from "node:fs";
|
|
56974
57036
|
import { join as join49 } from "node:path";
|
|
56975
57037
|
var MAX_NAME = 64;
|
|
56976
57038
|
var MAX_DESCRIPTION = 300;
|
|
@@ -57035,9 +57097,9 @@ var SkillDrafts = class {
|
|
|
57035
57097
|
created: (/* @__PURE__ */ new Date()).toISOString()
|
|
57036
57098
|
};
|
|
57037
57099
|
const folder = join49(this.dir, name);
|
|
57038
|
-
|
|
57039
|
-
|
|
57040
|
-
|
|
57100
|
+
mkdirSync19(folder, { recursive: true });
|
|
57101
|
+
writeFileSync16(join49(folder, "SKILL.md"), markdown);
|
|
57102
|
+
writeFileSync16(join49(folder, "draft.json"), `${JSON.stringify(meta, null, " ")}
|
|
57041
57103
|
`);
|
|
57042
57104
|
return { ...meta, markdown };
|
|
57043
57105
|
}
|
|
@@ -57057,8 +57119,8 @@ var SkillDrafts = class {
|
|
|
57057
57119
|
const folder = join49(skillsDir, draft.name);
|
|
57058
57120
|
const path = join49(folder, "SKILL.md");
|
|
57059
57121
|
if (existsSync16(path)) return { error: "exists" };
|
|
57060
|
-
|
|
57061
|
-
|
|
57122
|
+
mkdirSync19(folder, { recursive: true });
|
|
57123
|
+
writeFileSync16(path, draft.markdown);
|
|
57062
57124
|
this.remove(draft.name);
|
|
57063
57125
|
return { path };
|
|
57064
57126
|
}
|
|
@@ -58031,7 +58093,7 @@ function registerWatchdog(runtime) {
|
|
|
58031
58093
|
import { join as join51 } from "node:path";
|
|
58032
58094
|
|
|
58033
58095
|
// packages/kyrn-judge/src/auth/exit.ts
|
|
58034
|
-
import { mkdirSync as
|
|
58096
|
+
import { mkdirSync as mkdirSync20, rmdirSync as rmdirSync2 } from "node:fs";
|
|
58035
58097
|
import { resolve as resolve14 } from "node:path";
|
|
58036
58098
|
import { setTimeout as sleep3 } from "node:timers/promises";
|
|
58037
58099
|
async function holdLocksUntilExit(files, {
|
|
@@ -58065,7 +58127,7 @@ function takeAll(locks) {
|
|
|
58065
58127
|
const taken = [];
|
|
58066
58128
|
for (const lock of locks) {
|
|
58067
58129
|
try {
|
|
58068
|
-
|
|
58130
|
+
mkdirSync20(lock);
|
|
58069
58131
|
taken.push(lock);
|
|
58070
58132
|
} catch (error) {
|
|
58071
58133
|
if (error.code !== "EEXIST") continue;
|
|
@@ -58144,7 +58206,7 @@ function registerKyrn(pi, options) {
|
|
|
58144
58206
|
registerWelcome(runtime);
|
|
58145
58207
|
const roots = options.roots ?? (options.config || options.provider ? void 0 : { home: homedir12(), agentDir: (0, import_pi_coding_agent17.getAgentDir)() });
|
|
58146
58208
|
runtime.stateDir = roots ? join52(roots.agentDir, "mu") : void 0;
|
|
58147
|
-
|
|
58209
|
+
registerLayaNotice(runtime, loaded.laya, roots, home);
|
|
58148
58210
|
if (loaded.disabled) {
|
|
58149
58211
|
if (!options.only || options.only.includes("permissions")) registerPermissions(runtime, roots);
|
|
58150
58212
|
registerCommands(runtime, roots);
|
package/kyrn/bin/kyrn-doctor
CHANGED
|
@@ -345,10 +345,13 @@ const { browserAdvice, findBrowser, thisBrowserHost } = await import(
|
|
|
345
345
|
const browserHost = thisBrowserHost();
|
|
346
346
|
const chrome = findBrowser(browserHost);
|
|
347
347
|
const [advice, ...moreAdvice] = chrome ? [] : browserAdvice(browserHost).split("\n");
|
|
348
|
+
// Only mu's browser needs one: without it the rest of mu works, so it is not something to fix.
|
|
348
349
|
row(
|
|
349
|
-
chrome ? "ok" : "
|
|
350
|
+
chrome ? "ok" : "--",
|
|
350
351
|
"browser",
|
|
351
|
-
chrome
|
|
352
|
+
chrome
|
|
353
|
+
? `${chrome.executable}${chrome.side === "windows" ? " (on the Windows side, reached over mirrored networking)" : ""}`
|
|
354
|
+
: `optional, for mu's browser. ${advice}`,
|
|
352
355
|
);
|
|
353
356
|
for (const line of moreAdvice) row("--", "", line);
|
|
354
357
|
const canRelate = (tier) =>
|
package/kyrn/bin/mu.mjs
CHANGED
|
@@ -101,12 +101,16 @@ export function usage(platform) {
|
|
|
101
101
|
' mu "prompt" start a session with this prompt',
|
|
102
102
|
' mu -p "prompt" run one prompt, print the answer and exit',
|
|
103
103
|
" mu -c | -r continue the last session | pick a session to resume",
|
|
104
|
-
" mu setup connect a model (paste an API key or pick a service) and choose
|
|
105
|
-
"
|
|
104
|
+
" mu setup connect a model (paste an API key or pick a service) and choose",
|
|
105
|
+
" a judge (mu setup --help)",
|
|
106
|
+
" mu judge mude install install mude 1.0, mu's own decision model for coding, and make it",
|
|
107
|
+
" the judge on this Mac (Apple silicon, 1.8 GB)",
|
|
106
108
|
" enable | disable | start | stop | status | uninstall (mu judge mude help)",
|
|
107
|
-
" mu judge model <cmd> other decision models from Hugging Face:
|
|
109
|
+
" mu judge model <cmd> other decision models from Hugging Face:",
|
|
110
|
+
" add <link> | list | use | remove (mu judge model help)",
|
|
108
111
|
" mu ledger [n] [--json] print the judge's verdicts from the last n sessions",
|
|
109
|
-
" mu import <file>... import Claude Code, Codex and ZCode conversations; --list shows
|
|
112
|
+
" mu import <file>... import Claude Code, Codex and ZCode conversations; --list shows",
|
|
113
|
+
" them (mu import --help)",
|
|
110
114
|
" mu doctor check the installation, the judges and the connections",
|
|
111
115
|
" mu auth <cmd> sign-in helper for the desktop app (JSON lines):",
|
|
112
116
|
" status | login <provider> | logout <provider>",
|
|
@@ -771,8 +775,8 @@ export const AUTH_USAGE = [
|
|
|
771
775
|
" mu auth status",
|
|
772
776
|
" mu auth login <provider> [--paste]",
|
|
773
777
|
" mu auth logout <provider>",
|
|
774
|
-
"In a terminal, /login inside mu signs in the same way. With --paste,
|
|
775
|
-
"
|
|
778
|
+
"In a terminal, /login inside mu signs in the same way. With --paste, you paste the address the browser ends on",
|
|
779
|
+
"instead of mu listening for it. Use it when another program, such as the Codex CLI, holds the callback port.",
|
|
776
780
|
"",
|
|
777
781
|
"pi's auth commands:",
|
|
778
782
|
].join("\n");
|
|
@@ -836,7 +840,7 @@ export function planJudge({ argv }) {
|
|
|
836
840
|
kind: "removed",
|
|
837
841
|
code: 1,
|
|
838
842
|
text: [
|
|
839
|
-
`mu judge ${command}
|
|
843
|
+
`mu judge ${command} used to manage Laya, which is no longer built into mu.`,
|
|
840
844
|
"For a decision model on this machine, install mude 1.0 (mu judge mude install), or add one from Hugging Face (mu judge model add <link>).",
|
|
841
845
|
].join("\n"),
|
|
842
846
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mu-agent",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.6",
|
|
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": "
|
|
45
|
+
"commit": "bd42ca6ba"
|
|
46
46
|
}
|
|
47
47
|
}
|