@mu-crew/mu 3.11.2 → 3.11.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.
- package/AGENTS.md +2 -1
- package/dist/{chunk-2FJK6OOZ.js → chunk-3L5KO3PX.js} +3 -3
- package/dist/{chunk-JYZUNPPO.js → chunk-F7ZBF6I7.js} +24 -22
- package/dist/chunk-F7ZBF6I7.js.map +1 -0
- package/dist/{chunk-4PACTXAB.js → chunk-L2ABBTYG.js} +1 -1
- package/dist/chunk-L2ABBTYG.js.map +1 -0
- package/dist/{chunk-DXKJY3NT.js → chunk-LEORAGKV.js} +3 -3
- package/dist/{chunk-WYBOR4FX.js → chunk-R2SVBZAB.js} +20 -4
- package/dist/chunk-R2SVBZAB.js.map +1 -0
- package/dist/{cli-GRAPF5VC.js → cli-GJIO7GWD.js} +9 -8
- package/dist/cli-GJIO7GWD.js.map +1 -0
- package/dist/cli.js +2 -2
- package/dist/extension/mu-pi.js +122 -32
- package/dist/extension/mu-pi.js.map +1 -1
- package/dist/index.js +4 -4
- package/dist/{tui-DGDEH4JX.js → tui-WHCLVCYE.js} +5 -5
- package/dist/tui-sync-worker.js +2 -2
- package/docs/architecture/control-socket.md +1 -1
- package/docs/guide/delegate.md +7 -0
- package/docs/reference/env.md +1 -0
- package/docs/reference/naming.md +7 -0
- package/package.json +1 -1
- package/dist/chunk-4PACTXAB.js.map +0 -1
- package/dist/chunk-JYZUNPPO.js.map +0 -1
- package/dist/chunk-WYBOR4FX.js.map +0 -1
- package/dist/cli-GRAPF5VC.js.map +0 -1
- /package/dist/{chunk-2FJK6OOZ.js.map → chunk-3L5KO3PX.js.map} +0 -0
- /package/dist/{chunk-DXKJY3NT.js.map → chunk-LEORAGKV.js.map} +0 -0
- /package/dist/{tui-DGDEH4JX.js.map → tui-WHCLVCYE.js.map} +0 -0
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
defaultStateDir
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-L2ABBTYG.js";
|
|
5
5
|
import "./chunk-PZ5AY32C.js";
|
|
6
6
|
|
|
7
7
|
// src/main.ts
|
|
@@ -47,6 +47,6 @@ function enableCompileCacheIn(dir, enable = nodeEnable ?? null) {
|
|
|
47
47
|
|
|
48
48
|
// src/main.ts
|
|
49
49
|
enableCompileCacheIn(join(defaultStateDir(), "compile-cache"));
|
|
50
|
-
var { runCli } = await import("./cli-
|
|
50
|
+
var { runCli } = await import("./cli-GJIO7GWD.js");
|
|
51
51
|
await runCli(process.argv);
|
|
52
52
|
//# sourceMappingURL=cli.js.map
|
package/dist/extension/mu-pi.js
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
chmodSync,
|
|
4
4
|
existsSync as existsSync3,
|
|
5
5
|
linkSync,
|
|
6
|
-
mkdirSync,
|
|
6
|
+
mkdirSync as mkdirSync2,
|
|
7
7
|
readdirSync,
|
|
8
8
|
readFileSync as readFileSync2,
|
|
9
9
|
realpathSync,
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
statSync as statSync2
|
|
12
12
|
} from "fs";
|
|
13
13
|
import { connect, createServer } from "net";
|
|
14
|
-
import { dirname, join as
|
|
14
|
+
import { dirname, join as join4 } from "path";
|
|
15
15
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
16
16
|
|
|
17
17
|
// src/ctl/protocol.ts
|
|
@@ -44,9 +44,19 @@ var LineDecoder = class {
|
|
|
44
44
|
|
|
45
45
|
// extension/delegate.ts
|
|
46
46
|
import { execFile } from "child_process";
|
|
47
|
-
import { existsSync, statSync } from "fs";
|
|
48
|
-
import { delimiter, join } from "path";
|
|
47
|
+
import { existsSync, mkdirSync, statSync, writeFileSync } from "fs";
|
|
48
|
+
import { delimiter, join as join2 } from "path";
|
|
49
49
|
import { fileURLToPath } from "url";
|
|
50
|
+
|
|
51
|
+
// src/state-dir.ts
|
|
52
|
+
import { homedir } from "os";
|
|
53
|
+
import { isAbsolute, join } from "path";
|
|
54
|
+
function defaultCacheDir() {
|
|
55
|
+
const xdg = process.env.XDG_CACHE_HOME;
|
|
56
|
+
return join(xdg !== void 0 && isAbsolute(xdg) ? xdg : join(homedir(), ".cache"), "mu");
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// extension/delegate.ts
|
|
50
60
|
var DELEGATE_TOOL = "mu_delegate";
|
|
51
61
|
var DELEGATE_CANCEL_TOOL = "mu_delegate_cancel";
|
|
52
62
|
var DELEGATE_MESSAGE_TYPE = "mu-delegate";
|
|
@@ -84,7 +94,7 @@ function isDir(p) {
|
|
|
84
94
|
}
|
|
85
95
|
}
|
|
86
96
|
function onPath(bin, env) {
|
|
87
|
-
return (env.PATH ?? "").split(delimiter).some((d) => d !== "" && existsSync(
|
|
97
|
+
return (env.PATH ?? "").split(delimiter).some((d) => d !== "" && existsSync(join2(d, bin)));
|
|
88
98
|
}
|
|
89
99
|
function defaultRunner() {
|
|
90
100
|
let cli;
|
|
@@ -154,6 +164,29 @@ ${agent.lastText ?? ""}`;
|
|
|
154
164
|
return `${who}: mu agent wait gave no result. ${fate}${ws}${tailBlock}`;
|
|
155
165
|
}
|
|
156
166
|
}
|
|
167
|
+
function droppedAnswersDir() {
|
|
168
|
+
return join2(defaultCacheDir(), "delegate-answers");
|
|
169
|
+
}
|
|
170
|
+
function droppedNote(dropped) {
|
|
171
|
+
const n = dropped.length;
|
|
172
|
+
const lines = dropped.map((d) => {
|
|
173
|
+
const how = [
|
|
174
|
+
d.outcome ?? "no result",
|
|
175
|
+
d.elapsedMs !== void 0 ? formatElapsed(d.elapsedMs) : void 0
|
|
176
|
+
].filter((x) => x !== void 0).join(", ");
|
|
177
|
+
const where = [
|
|
178
|
+
d.copy ? `answer: ${d.copy}` : void 0,
|
|
179
|
+
d.sessionFile ? `session: ${d.sessionFile}` : void 0
|
|
180
|
+
].filter((x) => x !== void 0);
|
|
181
|
+
if (where.length === 0) where.push(`read: mu agent read ${d.name} -n 50 -w ${W}`);
|
|
182
|
+
return `- ${W}/${d.name} (${how}) ${where.join(" \xB7 ")}`;
|
|
183
|
+
});
|
|
184
|
+
return [
|
|
185
|
+
`The interrupt dropped ${n} delegate answer${n === 1 ? "" : "s"} before ${n === 1 ? "it" : "they"} arrived:`,
|
|
186
|
+
...lines,
|
|
187
|
+
"The answer file holds the message that would have arrived; in a session file the answer is the last assistant message."
|
|
188
|
+
].join("\n");
|
|
189
|
+
}
|
|
157
190
|
var RECORD_NOTE_MAX = 4e3;
|
|
158
191
|
var RECORD_FALLBACK_TAIL = 1500;
|
|
159
192
|
var VERDICT_LINE = /^[\s>*_`-]*VERDICT:/;
|
|
@@ -227,6 +260,23 @@ function registerDelegate(pi, run = defaultRunner()) {
|
|
|
227
260
|
const track = (ctx) => {
|
|
228
261
|
if (ctx?.hasUI !== false && ctx?.ui) ui = ctx.ui;
|
|
229
262
|
};
|
|
263
|
+
const markQueued = (delivery) => {
|
|
264
|
+
const a = arriving.get(delivery);
|
|
265
|
+
if (a) a.queued = true;
|
|
266
|
+
};
|
|
267
|
+
const saveCopy = (name, content) => {
|
|
268
|
+
try {
|
|
269
|
+
const dir = droppedAnswersDir();
|
|
270
|
+
mkdirSync(dir, { recursive: true });
|
|
271
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
272
|
+
const path = join2(dir, `${stamp}_${name}.md`);
|
|
273
|
+
writeFileSync(path, `${content}
|
|
274
|
+
`);
|
|
275
|
+
return path;
|
|
276
|
+
} catch {
|
|
277
|
+
return void 0;
|
|
278
|
+
}
|
|
279
|
+
};
|
|
230
280
|
const forget = (name) => {
|
|
231
281
|
inflight.delete(name);
|
|
232
282
|
drain();
|
|
@@ -371,12 +421,21 @@ function registerDelegate(pi, run = defaultRunner()) {
|
|
|
371
421
|
recordNote(record.label, name, outcome, agent?.lastText, extras.elapsedMs ?? 0)
|
|
372
422
|
) : void 0;
|
|
373
423
|
const message = delegateMessage(name, agent, pane, { ...extras, ...tail ? { tail } : {} });
|
|
424
|
+
const content = recorded ? `${message}
|
|
425
|
+
|
|
426
|
+
${recorded}` : message;
|
|
427
|
+
const a = arriving.get(delivery);
|
|
428
|
+
if (a)
|
|
429
|
+
Object.assign(a, {
|
|
430
|
+
content,
|
|
431
|
+
...outcome ? { outcome } : {},
|
|
432
|
+
...extras.elapsedMs !== void 0 ? { elapsedMs: extras.elapsedMs } : {},
|
|
433
|
+
...agent?.sessionFile ? { sessionFile: agent.sessionFile } : {}
|
|
434
|
+
});
|
|
374
435
|
await pi.sendMessage(
|
|
375
436
|
{
|
|
376
437
|
customType: DELEGATE_MESSAGE_TYPE,
|
|
377
|
-
content
|
|
378
|
-
|
|
379
|
-
${recorded}` : message,
|
|
438
|
+
content,
|
|
380
439
|
display: true,
|
|
381
440
|
details: {
|
|
382
441
|
name,
|
|
@@ -451,7 +510,7 @@ ${task}` : task,
|
|
|
451
510
|
);
|
|
452
511
|
const settle = async (r) => {
|
|
453
512
|
const delivery = ++deliverySeq;
|
|
454
|
-
arriving.set(delivery, false);
|
|
513
|
+
arriving.set(delivery, { queued: false, name });
|
|
455
514
|
forget(name);
|
|
456
515
|
try {
|
|
457
516
|
await deliver(
|
|
@@ -468,22 +527,28 @@ ${task}` : task,
|
|
|
468
527
|
delivery,
|
|
469
528
|
entry.record
|
|
470
529
|
);
|
|
471
|
-
|
|
530
|
+
markQueued(delivery);
|
|
472
531
|
} catch (e) {
|
|
532
|
+
const content = `Delegate ${W}/${name} settled, but delivering its answer failed: ${e instanceof Error ? e.message : String(e)}. Read it with: mu agent read ${name} -n 50 -w ${W}`;
|
|
533
|
+
const a = arriving.get(delivery);
|
|
534
|
+
if (a) a.content = content;
|
|
473
535
|
await Promise.resolve(
|
|
474
536
|
pi.sendMessage(
|
|
475
537
|
{
|
|
476
538
|
customType: DELEGATE_MESSAGE_TYPE,
|
|
477
|
-
content
|
|
539
|
+
content,
|
|
478
540
|
display: true,
|
|
479
541
|
details: { name, workstream: W, outcome: null, closed: false, delivery }
|
|
480
542
|
},
|
|
481
543
|
{ deliverAs: "followUp", triggerTurn: true }
|
|
482
544
|
)
|
|
483
|
-
).
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
545
|
+
).then(
|
|
546
|
+
() => markQueued(delivery),
|
|
547
|
+
() => {
|
|
548
|
+
arriving.delete(delivery);
|
|
549
|
+
showStatus();
|
|
550
|
+
}
|
|
551
|
+
);
|
|
487
552
|
}
|
|
488
553
|
};
|
|
489
554
|
void waiting.then(async (r) => {
|
|
@@ -686,13 +751,32 @@ ${task}` : task,
|
|
|
686
751
|
});
|
|
687
752
|
pi.on("agent_settled", (e) => {
|
|
688
753
|
if (e.aborted !== true) return;
|
|
689
|
-
|
|
690
|
-
for (const [id,
|
|
691
|
-
if (queued)
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
754
|
+
const dropped = [];
|
|
755
|
+
for (const [id, a] of arriving) {
|
|
756
|
+
if (!a.queued) continue;
|
|
757
|
+
arriving.delete(id);
|
|
758
|
+
dropped.push({
|
|
759
|
+
name: a.name,
|
|
760
|
+
...a.outcome ? { outcome: a.outcome } : {},
|
|
761
|
+
...a.elapsedMs !== void 0 ? { elapsedMs: a.elapsedMs } : {},
|
|
762
|
+
...a.sessionFile ? { sessionFile: a.sessionFile } : {},
|
|
763
|
+
...a.content ? { copy: saveCopy(a.name, a.content) } : {}
|
|
764
|
+
});
|
|
765
|
+
}
|
|
766
|
+
if (dropped.length === 0) return;
|
|
767
|
+
showStatus();
|
|
768
|
+
void Promise.resolve(
|
|
769
|
+
pi.sendMessage(
|
|
770
|
+
{
|
|
771
|
+
customType: DELEGATE_MESSAGE_TYPE,
|
|
772
|
+
content: droppedNote(dropped),
|
|
773
|
+
display: true,
|
|
774
|
+
details: { dropped }
|
|
775
|
+
},
|
|
776
|
+
{ triggerTurn: false }
|
|
777
|
+
)
|
|
778
|
+
).catch(() => {
|
|
779
|
+
});
|
|
696
780
|
});
|
|
697
781
|
pi.on("session_shutdown", (_e, ctx) => {
|
|
698
782
|
if (arriving.size > 0) {
|
|
@@ -722,7 +806,7 @@ ${task}` : task,
|
|
|
722
806
|
|
|
723
807
|
// extension/nudge.ts
|
|
724
808
|
import { existsSync as existsSync2, readFileSync } from "fs";
|
|
725
|
-
import { join as
|
|
809
|
+
import { join as join3 } from "path";
|
|
726
810
|
var NUDGE_MESSAGE_TYPE = "mu-keep-driving";
|
|
727
811
|
var NUDGE_LOG_KIND = "nudge";
|
|
728
812
|
var CLOSE_NUDGE_MESSAGE_TYPE = "mu-close-task";
|
|
@@ -746,7 +830,7 @@ function keepDrivingRule(skillMd) {
|
|
|
746
830
|
}
|
|
747
831
|
function readSkill() {
|
|
748
832
|
for (const up of ["..", "../.."]) {
|
|
749
|
-
const p =
|
|
833
|
+
const p = join3(import.meta.dirname ?? "", up, "skills", "mu", "SKILL.md");
|
|
750
834
|
if (existsSync2(p)) return readFileSync(p, "utf8");
|
|
751
835
|
}
|
|
752
836
|
return void 0;
|
|
@@ -1147,7 +1231,7 @@ function registerRefuteNudge(pi, run = defaultRunner(), nested = notNested) {
|
|
|
1147
1231
|
}
|
|
1148
1232
|
|
|
1149
1233
|
// extension/mu-pi.ts
|
|
1150
|
-
var EXT_VERSION = true ? "3.11.
|
|
1234
|
+
var EXT_VERSION = true ? "3.11.3" : void 0;
|
|
1151
1235
|
var FRESH_COMMAND = "mu-fresh";
|
|
1152
1236
|
var FRESH_TIMEOUT_MS = 3e4;
|
|
1153
1237
|
function commandName(name) {
|
|
@@ -1167,7 +1251,7 @@ function detectPiVersion() {
|
|
|
1167
1251
|
if (!entry) return void 0;
|
|
1168
1252
|
let dir = dirname(realpathSync(entry));
|
|
1169
1253
|
for (let i = 0; i < 6; i++) {
|
|
1170
|
-
const pkgPath =
|
|
1254
|
+
const pkgPath = join4(dir, "package.json");
|
|
1171
1255
|
if (existsSync3(pkgPath)) {
|
|
1172
1256
|
const pkg = JSON.parse(readFileSync2(pkgPath, "utf8"));
|
|
1173
1257
|
if (typeof pkg === "object" && pkg !== null) {
|
|
@@ -1273,8 +1357,8 @@ function promptsDir(from = import.meta.url) {
|
|
|
1273
1357
|
return void 0;
|
|
1274
1358
|
}
|
|
1275
1359
|
for (const up of ["..", "../.."]) {
|
|
1276
|
-
const d =
|
|
1277
|
-
if (existsSync3(
|
|
1360
|
+
const d = join4(here, up, "prompts");
|
|
1361
|
+
if (existsSync3(join4(d, "ultrathink.md"))) return d;
|
|
1278
1362
|
}
|
|
1279
1363
|
return void 0;
|
|
1280
1364
|
}
|
|
@@ -1282,7 +1366,7 @@ function registerPrompts(pi) {
|
|
|
1282
1366
|
pi.on("resources_discover", () => {
|
|
1283
1367
|
const d = promptsDir();
|
|
1284
1368
|
if (!d) return {};
|
|
1285
|
-
const paths = readdirSync(d).filter((f) => f.endsWith(".md")).sort().map((f) =>
|
|
1369
|
+
const paths = readdirSync(d).filter((f) => f.endsWith(".md")).sort().map((f) => join4(d, f));
|
|
1286
1370
|
return { promptPaths: paths };
|
|
1287
1371
|
});
|
|
1288
1372
|
}
|
|
@@ -1353,6 +1437,11 @@ function serveCtl(pi) {
|
|
|
1353
1437
|
g.endText = void 0;
|
|
1354
1438
|
g.lastError = g.endError;
|
|
1355
1439
|
g.endError = void 0;
|
|
1440
|
+
try {
|
|
1441
|
+
g.sessionFile = c.sessionManager?.getSessionFile();
|
|
1442
|
+
} catch {
|
|
1443
|
+
g.sessionFile = void 0;
|
|
1444
|
+
}
|
|
1356
1445
|
for (const w of [...g.waiters]) w();
|
|
1357
1446
|
});
|
|
1358
1447
|
pi.registerCommand(FRESH_COMMAND, {
|
|
@@ -1512,7 +1601,8 @@ function serveCtl(pi) {
|
|
|
1512
1601
|
}
|
|
1513
1602
|
const settledRun = () => ({
|
|
1514
1603
|
lastText: g.lastText,
|
|
1515
|
-
...g.lastError !== void 0 ? { lastError: g.lastError } : {}
|
|
1604
|
+
...g.lastError !== void 0 ? { lastError: g.lastError } : {},
|
|
1605
|
+
...g.sessionFile !== void 0 ? { sessionFile: g.sessionFile } : {}
|
|
1516
1606
|
});
|
|
1517
1607
|
function wait(afterRuns, timeoutMs, conn) {
|
|
1518
1608
|
if (afterRuns !== void 0 && g.runs > afterRuns && g.state === "idle") {
|
|
@@ -1570,7 +1660,7 @@ function serveCtl(pi) {
|
|
|
1570
1660
|
});
|
|
1571
1661
|
}
|
|
1572
1662
|
async function bind() {
|
|
1573
|
-
|
|
1663
|
+
mkdirSync2(dirname(sockPath), { recursive: true, mode: 448 });
|
|
1574
1664
|
if (await socketIsLive(sockPath)) {
|
|
1575
1665
|
g.nested = true;
|
|
1576
1666
|
process.stderr.write(
|
|
@@ -1580,7 +1670,7 @@ function serveCtl(pi) {
|
|
|
1580
1670
|
return;
|
|
1581
1671
|
}
|
|
1582
1672
|
rmSync(sockPath, { force: true });
|
|
1583
|
-
const tmp =
|
|
1673
|
+
const tmp = join4(dirname(sockPath), `.${process.pid.toString(36)}${(++bindSeq).toString(36)}`);
|
|
1584
1674
|
rmSync(tmp, { force: true });
|
|
1585
1675
|
const s = createServer(onConnection);
|
|
1586
1676
|
await new Promise((resolve, reject) => {
|