@mu-crew/mu 3.11.2 → 3.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/AGENTS.md CHANGED
@@ -221,7 +221,8 @@ documenting" is not a reason.
221
221
  - No render layer beyond `cli-table3` + `picocolors`, except `ink`
222
222
  inside `src/cli/tui/`. Never a second TUI stack.
223
223
  - Don't bundle pi. It is an optional peer dependency.
224
- - Write files only under `~/.local/state/mu/` or the repo.
224
+ - Write files only under `~/.local/state/mu/`, `~/.cache/mu/`, or the
225
+ repo. The cache dir holds only files mu can lose at any time.
225
226
 
226
227
  ## When you're done
227
228
 
@@ -21,10 +21,10 @@ import {
21
21
  withCaptureSuppressed,
22
22
  withFileLock,
23
23
  withOpContext
24
- } from "./chunk-WYBOR4FX.js";
24
+ } from "./chunk-R2SVBZAB.js";
25
25
  import {
26
26
  defaultStateDir
27
- } from "./chunk-4PACTXAB.js";
27
+ } from "./chunk-L2ABBTYG.js";
28
28
  import {
29
29
  __export
30
30
  } from "./chunk-PZ5AY32C.js";
@@ -1814,12 +1814,12 @@ function superscriptDigit(n) {
1814
1814
  import { dirname as dirname6 } from "path";
1815
1815
 
1816
1816
  // src/agent-state.ts
1817
- import { accessSync, constants, existsSync as existsSync9 } from "fs";
1817
+ import { accessSync, constants, existsSync as existsSync10 } from "fs";
1818
1818
  import { homedir as homedir2 } from "os";
1819
1819
  import { delimiter, join as join8 } from "path";
1820
1820
 
1821
1821
  // src/agents/transport.ts
1822
- import { existsSync as existsSync8 } from "fs";
1822
+ import { existsSync as existsSync9 } from "fs";
1823
1823
  import { dirname as dirname5 } from "path";
1824
1824
 
1825
1825
  // src/ctl/client.ts
@@ -1995,7 +1995,7 @@ function remoteCtlSocketPath(workstream, agent, uid) {
1995
1995
 
1996
1996
  // src/agents/spawn.ts
1997
1997
  import { execFile as execFile2 } from "child_process";
1998
- import { mkdirSync, rmSync as rmSync4 } from "fs";
1998
+ import { existsSync as existsSync8, mkdirSync, rmSync as rmSync4 } from "fs";
1999
1999
  import { basename, dirname as dirname4 } from "path";
2000
2000
  import { setTimeout as delay } from "timers/promises";
2001
2001
  import { promisify as promisify2 } from "util";
@@ -4084,7 +4084,8 @@ async function checkCommandResolvable(command) {
4084
4084
  var NEXT_FREE_ATTEMPTS = 32;
4085
4085
  var NEXT_FREE_LOOKUPS = 1e3;
4086
4086
  function nextFreeAgentName(db, name, workstream) {
4087
- if (getAgent(db, name, workstream) === void 0) return name;
4087
+ const free = (n) => getAgent(db, n, workstream) === void 0 && !existsSync8(workspacePath(workstream, n));
4088
+ if (free(name)) return name;
4088
4089
  const m = /^(.*)-(\d+)$/.exec(name);
4089
4090
  const [stem, first] = m ? [m[1] ?? "", BigInt(m[2] ?? "1")] : [name, 1n];
4090
4091
  for (let i = 1n; i <= BigInt(NEXT_FREE_LOOKUPS); i++) {
@@ -4093,7 +4094,7 @@ function nextFreeAgentName(db, name, workstream) {
4093
4094
  if (!isValidAgentName(candidate)) {
4094
4095
  throw new AgentNameExhaustedError(name, `no valid name left (tried ${candidate})`);
4095
4096
  }
4096
- if (getAgent(db, candidate, workstream) === void 0) return candidate;
4097
+ if (free(candidate)) return candidate;
4097
4098
  }
4098
4099
  throw new AgentNameExhaustedError(name, `the next ${NEXT_FREE_LOOKUPS} names are taken`);
4099
4100
  }
@@ -4926,7 +4927,7 @@ function agentCtlSocket(db, agent) {
4926
4927
  return ctlSocketPath(agent.workstreamName, agent.name, dirname5(db.name));
4927
4928
  }
4928
4929
  function expectsCtl(agent, sock = ctlSocketPath(agent.workstreamName, agent.name)) {
4929
- return speaksMuCtl(agent.cli, resolveCliCommand(agent.cli)) || existsSync8(sock);
4930
+ return speaksMuCtl(agent.cli, resolveCliCommand(agent.cli)) || existsSync9(sock);
4930
4931
  }
4931
4932
  function chooseTransport(agent, sock) {
4932
4933
  return expectsCtl(agent, sock) ? "ctl" : "mux";
@@ -5026,7 +5027,8 @@ async function sendViaTransport(agent, text, opts) {
5026
5027
  transport,
5027
5028
  ...reply.state !== void 0 ? { state: reply.state } : {},
5028
5029
  ...reply.runs !== void 0 ? { runs: reply.runs } : {},
5029
- ...reply.since !== void 0 ? { since: reply.since } : {}
5030
+ ...reply.since !== void 0 ? { since: reply.since } : {},
5031
+ ...reply.sessionFile !== void 0 ? { sessionFile: reply.sessionFile } : {}
5030
5032
  };
5031
5033
  }
5032
5034
  async function runSessionCommand(agent, sock, cmd, force) {
@@ -5086,7 +5088,7 @@ function murmurOnPath() {
5086
5088
  }
5087
5089
  function murmurExtensionLinked() {
5088
5090
  const piDir = process.env.PI_CODING_AGENT_DIR ?? join8(homedir2(), ".pi", "agent");
5089
- return existsSync9(join8(piDir, "extensions", "murmur.ts"));
5091
+ return existsSync10(join8(piDir, "extensions", "murmur.ts"));
5090
5092
  }
5091
5093
  function murmurAvailable() {
5092
5094
  return murmurOnPath() && murmurExtensionLinked();
@@ -7322,6 +7324,7 @@ async function waitForAgents(db, input, opts) {
7322
7324
  st.fired = true;
7323
7325
  if (snap.lastText !== void 0) st.lastText = snap.lastText;
7324
7326
  if (snap.lastError !== void 0) st.lastError = snap.lastError;
7327
+ if (snap.sessionFile !== void 0) st.sessionFile = snap.sessionFile;
7325
7328
  }
7326
7329
  wake();
7327
7330
  },
@@ -7810,7 +7813,7 @@ function formatTreeNodeLabel(t, statusFn, opts = {}) {
7810
7813
  }
7811
7814
 
7812
7815
  // src/rebuild.ts
7813
- import { existsSync as existsSync10, mkdirSync as mkdirSync2, rmSync as rmSync5, statSync as statSync2 } from "fs";
7816
+ import { existsSync as existsSync11, mkdirSync as mkdirSync2, rmSync as rmSync5, statSync as statSync2 } from "fs";
7814
7817
  import { dirname as dirname7 } from "path";
7815
7818
  var RebuildTargetExistsError = class extends Error {
7816
7819
  constructor(path) {
@@ -7868,10 +7871,10 @@ function rebuildInto(source, opts) {
7868
7871
  (row) => row.name === "main"
7869
7872
  )?.file;
7870
7873
  if (sourceFile !== void 0 && sourceFile.length > 0) {
7871
- const sameFile = sourceFile === targetPath || existsSync10(targetPath) && existsSync10(sourceFile) && sameInode(sourceFile, targetPath);
7874
+ const sameFile = sourceFile === targetPath || existsSync11(targetPath) && existsSync11(sourceFile) && sameInode(sourceFile, targetPath);
7872
7875
  if (sameFile) throw new RebuildTargetIsSourceError(targetPath);
7873
7876
  }
7874
- if (existsSync10(targetPath) && opts.force !== true) {
7877
+ if (existsSync11(targetPath) && opts.force !== true) {
7875
7878
  throw new RebuildTargetExistsError(targetPath);
7876
7879
  }
7877
7880
  mkdirSync2(dirname7(targetPath), { recursive: true });
@@ -8231,7 +8234,7 @@ var DriftDetectedError = class extends Error {
8231
8234
  };
8232
8235
 
8233
8236
  // src/fleet-hazards.ts
8234
- import { existsSync as existsSync11, statfsSync } from "fs";
8237
+ import { existsSync as existsSync12, statfsSync } from "fs";
8235
8238
  import { resolve as resolve3, sep } from "path";
8236
8239
  var HazardFailError = class extends Error {
8237
8240
  constructor(failedRows) {
@@ -8311,7 +8314,7 @@ function classifyFsType(magic, platform = process.platform) {
8311
8314
  function probeFilesystem(path) {
8312
8315
  try {
8313
8316
  let probeTarget = resolve3(path);
8314
- while (!existsSync11(probeTarget)) {
8317
+ while (!existsSync12(probeTarget)) {
8315
8318
  const parent = resolve3(probeTarget, "..");
8316
8319
  if (parent === probeTarget) break;
8317
8320
  probeTarget = parent;
@@ -8411,7 +8414,7 @@ function checkFleetHazards(db, opts = { dbPath: "" }) {
8411
8414
 
8412
8415
  // src/link.ts
8413
8416
  import {
8414
- existsSync as existsSync12,
8417
+ existsSync as existsSync13,
8415
8418
  lstatSync,
8416
8419
  mkdirSync as mkdirSync3,
8417
8420
  readFileSync as readFileSync2,
@@ -8480,12 +8483,12 @@ export default extension;
8480
8483
  function linkPi(opts) {
8481
8484
  const path = extensionPath(opts);
8482
8485
  const entry = extensionEntry();
8483
- if (!existsSync12(entry)) {
8486
+ if (!existsSync13(entry)) {
8484
8487
  throw new Error(`mu pi extension not built: ${entry} is missing (run npm run build)`);
8485
8488
  }
8486
8489
  if (lstatOrUndefined(path)?.isSymbolicLink() === true) {
8487
8490
  const current = resolve4(dirname8(path), readlinkSync(path));
8488
- if (existsSync12(current) && opts?.force !== true) {
8491
+ if (existsSync13(current) && opts?.force !== true) {
8489
8492
  throw new LinkConflictError(path, "foreign-symlink", current);
8490
8493
  }
8491
8494
  rmSync7(path);
@@ -8508,7 +8511,7 @@ function linkSkill(opts) {
8508
8511
  if (!st.isSymbolicLink()) throw new LinkConflictError(path, "not-a-symlink");
8509
8512
  const current = resolve4(dirname8(path), readlinkSync(path));
8510
8513
  if (current === target) return { path, target };
8511
- if (existsSync12(current) && opts?.force !== true) {
8514
+ if (existsSync13(current) && opts?.force !== true) {
8512
8515
  throw new LinkConflictError(path, "foreign-symlink", current);
8513
8516
  }
8514
8517
  previous = current;
@@ -8538,7 +8541,7 @@ function inspectExtension(path) {
8538
8541
  if (!spec) return { path, state: "dangling" };
8539
8542
  const raw = JSON.parse(spec);
8540
8543
  const target = raw.startsWith("file:") ? fileURLToPath(raw) : raw;
8541
- return { path, state: existsSync12(target) ? "ok" : "dangling", target };
8544
+ return { path, state: existsSync13(target) ? "ok" : "dangling", target };
8542
8545
  }
8543
8546
  function inspectSkill(path) {
8544
8547
  const st = lstatOrUndefined(path);
@@ -8568,7 +8571,7 @@ function inspectLinks(opts) {
8568
8571
  }
8569
8572
 
8570
8573
  // src/doctor-summary.ts
8571
- import { accessSync as accessSync2, constants as constants2, existsSync as existsSync13, readFileSync as readFileSync3, realpathSync as realpathSync2 } from "fs";
8574
+ import { accessSync as accessSync2, constants as constants2, existsSync as existsSync14, readFileSync as readFileSync3, realpathSync as realpathSync2 } from "fs";
8572
8575
  import { delimiter as delimiter2, dirname as dirname9, join as join11, parse } from "path";
8573
8576
  import { fileURLToPath as fileURLToPath2 } from "url";
8574
8577
  function loadDoctorSummary(db, snapshot2, agentStateSource = "murmur") {
@@ -8734,7 +8737,7 @@ function murmurVersion(executable) {
8734
8737
  const root = parse(dir).root;
8735
8738
  while (dir !== root) {
8736
8739
  const packagePath = join11(dir, "package.json");
8737
- if (existsSync13(packagePath)) {
8740
+ if (existsSync14(packagePath)) {
8738
8741
  try {
8739
8742
  const pkg = JSON.parse(readFileSync3(packagePath, "utf8"));
8740
8743
  if (typeof pkg === "object" && pkg !== null && "name" in pkg && pkg.name === "@mu-crew/murmur" && "version" in pkg && typeof pkg.version === "string") {
@@ -9925,4 +9928,4 @@ export {
9925
9928
  agentStateHistogram,
9926
9929
  summarizeOwnedTasks
9927
9930
  };
9928
- //# sourceMappingURL=chunk-JYZUNPPO.js.map
9931
+ //# sourceMappingURL=chunk-IRPTNVJC.js.map