@holt-os/holt 0.14.1 → 0.14.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.
Files changed (3) hide show
  1. package/README.md +51 -13
  2. package/dist/cli.js +532 -194
  3. package/package.json +2 -1
package/dist/cli.js CHANGED
@@ -2220,9 +2220,9 @@ Default brain? [${chosen.join("/")}] (${defPick}): `) ?? "").trim();
2220
2220
  }
2221
2221
 
2222
2222
  // src/commands/launch.ts
2223
- import { readFileSync as readFileSync12, writeFileSync as writeFileSync11, existsSync as existsSync11, mkdirSync as mkdirSync10, copyFileSync as copyFileSync2 } from "fs";
2224
- import { homedir as homedir6 } from "os";
2225
- import { join as join12, dirname as dirname5 } from "path";
2223
+ import { readFileSync as readFileSync13, writeFileSync as writeFileSync12, existsSync as existsSync12, mkdirSync as mkdirSync11, copyFileSync as copyFileSync2 } from "fs";
2224
+ import { homedir as homedir7 } from "os";
2225
+ import { join as join13, dirname as dirname6 } from "path";
2226
2226
 
2227
2227
  // src/scheduler.ts
2228
2228
  import { homedir as homedir3 } from "os";
@@ -2363,11 +2363,340 @@ function ensureLogsDir() {
2363
2363
  mkdirSync7(logsDir(), { recursive: true });
2364
2364
  }
2365
2365
 
2366
+ // src/skillcompiler.ts
2367
+ import {
2368
+ readFileSync as readFileSync10,
2369
+ writeFileSync as writeFileSync8,
2370
+ existsSync as existsSync8,
2371
+ mkdirSync as mkdirSync8,
2372
+ readdirSync as readdirSync2,
2373
+ statSync as statSync3,
2374
+ rmSync as rmSync4,
2375
+ cpSync
2376
+ } from "fs";
2377
+ import { join as join9, dirname as dirname3 } from "path";
2378
+ import { homedir as homedir4 } from "os";
2379
+ import { createHash as createHash2 } from "crypto";
2380
+ var MARKER = "holt-managed skill";
2381
+ var CODEX_PREFIX = "holt-";
2382
+ function manifestPath(ws = workspace()) {
2383
+ return join9(wsHoltDir(ws), "skill-commands.json");
2384
+ }
2385
+ function emptyManifest() {
2386
+ return { version: 1, brains: {} };
2387
+ }
2388
+ function readManifest(ws = workspace()) {
2389
+ const p = manifestPath(ws);
2390
+ if (!existsSync8(p)) return emptyManifest();
2391
+ try {
2392
+ const parsed = JSON.parse(readFileSync10(p, "utf8"));
2393
+ const brains = parsed.brains && typeof parsed.brains === "object" ? parsed.brains : {};
2394
+ return { version: 1, brains };
2395
+ } catch {
2396
+ return emptyManifest();
2397
+ }
2398
+ }
2399
+ function writeManifest(m, ws = workspace()) {
2400
+ mkdirSync8(wsHoltDir(ws), { recursive: true });
2401
+ writeFileSync8(manifestPath(ws), JSON.stringify(m, null, 2) + "\n", "utf8");
2402
+ }
2403
+ function hashString(s) {
2404
+ return createHash2("sha256").update(s).digest("hex");
2405
+ }
2406
+ function hashDir(dir) {
2407
+ const h = createHash2("sha256");
2408
+ const walk = (rel) => {
2409
+ const abs = join9(dir, rel);
2410
+ let entries;
2411
+ try {
2412
+ entries = readdirSync2(abs).sort();
2413
+ } catch {
2414
+ return;
2415
+ }
2416
+ for (const name of entries) {
2417
+ const childRel = rel ? join9(rel, name) : name;
2418
+ const childAbs = join9(dir, childRel);
2419
+ let st;
2420
+ try {
2421
+ st = statSync3(childAbs);
2422
+ } catch {
2423
+ continue;
2424
+ }
2425
+ if (st.isDirectory()) {
2426
+ h.update("D:" + childRel + "\n");
2427
+ walk(childRel);
2428
+ } else {
2429
+ h.update("F:" + childRel + "\n");
2430
+ try {
2431
+ h.update(readFileSync10(childAbs));
2432
+ } catch {
2433
+ }
2434
+ }
2435
+ }
2436
+ };
2437
+ walk("");
2438
+ return h.digest("hex");
2439
+ }
2440
+ function readSkillSource(skill) {
2441
+ const file = join9(skill.dir, "SKILL.md");
2442
+ let raw = "";
2443
+ try {
2444
+ raw = readFileSync10(file, "utf8");
2445
+ } catch {
2446
+ return null;
2447
+ }
2448
+ const { data, body } = parseFrontmatter(raw);
2449
+ const description = (data.description || skill.description || "").trim();
2450
+ return { name: skill.name, description, body: body.trim() };
2451
+ }
2452
+ function tomlBasicString(s) {
2453
+ return s.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, " ").trim();
2454
+ }
2455
+ function tomlMultiline(s) {
2456
+ return s.replace(/\\/g, "\\\\").replace(/"""/g, '\\"\\"\\"');
2457
+ }
2458
+ function renderGeminiToml(src) {
2459
+ const instructions = src.body || src.description;
2460
+ if (!instructions.trim()) return null;
2461
+ const prompt = [
2462
+ instructions,
2463
+ "",
2464
+ "Apply the skill above to this request:",
2465
+ "{{args}}"
2466
+ ].join("\n");
2467
+ const lines = [
2468
+ `# ${MARKER}: ${src.name}`,
2469
+ "# Generated by Holt from a SKILL.md. Edit the skill, not this file: Holt",
2470
+ '# will overwrite it on the next launch. Delete via "holt skill remove".'
2471
+ ];
2472
+ if (src.description) lines.push(`description = "${tomlBasicString(src.description)}"`);
2473
+ lines.push('prompt = """');
2474
+ lines.push(tomlMultiline(prompt));
2475
+ lines.push('"""');
2476
+ return lines.join("\n") + "\n";
2477
+ }
2478
+ function renderCodexPrompt(src) {
2479
+ const instructions = src.body || src.description;
2480
+ if (!instructions.trim()) return null;
2481
+ const front = ["---"];
2482
+ if (src.description) front.push(`description: ${src.description.replace(/\n/g, " ").trim()}`);
2483
+ front.push("argument-hint: [request]");
2484
+ front.push("---");
2485
+ const parts = [
2486
+ front.join("\n"),
2487
+ "",
2488
+ `<!-- ${MARKER}: ${src.name} (generated by Holt from a SKILL.md; do not edit) -->`,
2489
+ "",
2490
+ instructions,
2491
+ "",
2492
+ "Apply the skill above to this request:",
2493
+ "",
2494
+ "$ARGUMENTS",
2495
+ ""
2496
+ ];
2497
+ return parts.join("\n");
2498
+ }
2499
+ function claudeSkillsDir(ws) {
2500
+ return join9(ws, ".claude", "skills");
2501
+ }
2502
+ function geminiCommandsDir(ws) {
2503
+ return join9(ws, ".gemini", "commands");
2504
+ }
2505
+ function codexPromptsDir() {
2506
+ return join9(homedir4(), ".codex", "prompts");
2507
+ }
2508
+ function fileIsOurs(path) {
2509
+ try {
2510
+ return readFileSync10(path, "utf8").includes(MARKER);
2511
+ } catch {
2512
+ return false;
2513
+ }
2514
+ }
2515
+ function emptyResult() {
2516
+ return { written: [], skippedExisting: [], skippedUnexpressible: [], removed: [] };
2517
+ }
2518
+ function priorEntry(m, brain, path) {
2519
+ return (m.brains[brain] || []).find((e) => e.path === path);
2520
+ }
2521
+ function compileForBrain(brain, ws = workspace()) {
2522
+ const res = emptyResult();
2523
+ const manifest = readManifest(ws);
2524
+ const prior = manifest.brains[brain] || [];
2525
+ const nextEntries = [];
2526
+ let skills;
2527
+ try {
2528
+ skills = listSkills();
2529
+ } catch {
2530
+ return res;
2531
+ }
2532
+ const enabledNames = new Set(skills.map((s) => s.name));
2533
+ for (const skill of skills) {
2534
+ try {
2535
+ if (brain === "claude") {
2536
+ compileClaude(skill, ws, manifest, res, nextEntries);
2537
+ } else if (brain === "gemini") {
2538
+ compileGemini(skill, ws, manifest, res, nextEntries);
2539
+ } else {
2540
+ compileCodex(skill, manifest, res, nextEntries);
2541
+ }
2542
+ } catch {
2543
+ res.skippedUnexpressible.push(skill.name);
2544
+ }
2545
+ }
2546
+ for (const e of prior) {
2547
+ if (enabledNames.has(e.skill) && nextEntries.some((n) => n.path === e.path)) continue;
2548
+ if (removeArtifact(e.path)) res.removed.push(e.path);
2549
+ }
2550
+ manifest.brains[brain] = nextEntries;
2551
+ try {
2552
+ writeManifest(manifest, ws);
2553
+ } catch {
2554
+ }
2555
+ return res;
2556
+ }
2557
+ function compileClaude(skill, ws, manifest, res, next) {
2558
+ const dest = join9(claudeSkillsDir(ws), skill.name);
2559
+ const known = priorEntry(manifest, "claude", dest);
2560
+ if (existsSync8(dest) && !known) {
2561
+ res.skippedExisting.push(dest);
2562
+ return;
2563
+ }
2564
+ const srcHash = hashDir(skill.dir);
2565
+ if (known && known.hash === srcHash && existsSync8(dest)) {
2566
+ next.push(known);
2567
+ return;
2568
+ }
2569
+ if (existsSync8(dest)) rmSync4(dest, { recursive: true, force: true });
2570
+ mkdirSync8(dirname3(dest), { recursive: true });
2571
+ cpSync(skill.dir, dest, { recursive: true });
2572
+ next.push({ skill: skill.name, path: dest, hash: hashDir(dest) });
2573
+ res.written.push(dest);
2574
+ }
2575
+ function compileGemini(skill, ws, manifest, res, next) {
2576
+ const src = readSkillSource(skill);
2577
+ if (!src) {
2578
+ res.skippedUnexpressible.push(skill.name);
2579
+ return;
2580
+ }
2581
+ const content = renderGeminiToml(src);
2582
+ if (content === null) {
2583
+ res.skippedUnexpressible.push(skill.name);
2584
+ return;
2585
+ }
2586
+ const dest = join9(geminiCommandsDir(ws), `${skill.name}.toml`);
2587
+ writeTextArtifact("gemini", skill.name, dest, content, manifest, res, next);
2588
+ }
2589
+ function compileCodex(skill, manifest, res, next) {
2590
+ const src = readSkillSource(skill);
2591
+ if (!src) {
2592
+ res.skippedUnexpressible.push(skill.name);
2593
+ return;
2594
+ }
2595
+ const content = renderCodexPrompt(src);
2596
+ if (content === null) {
2597
+ res.skippedUnexpressible.push(skill.name);
2598
+ return;
2599
+ }
2600
+ const dest = join9(codexPromptsDir(), `${CODEX_PREFIX}${skill.name}.md`);
2601
+ writeTextArtifact("codex", skill.name, dest, content, manifest, res, next);
2602
+ }
2603
+ function writeTextArtifact(brain, skillName, dest, content, manifest, res, next) {
2604
+ const known = priorEntry(manifest, brain, dest);
2605
+ if (existsSync8(dest) && !known && !fileIsOurs(dest)) {
2606
+ res.skippedExisting.push(dest);
2607
+ return;
2608
+ }
2609
+ const hash = hashString(content);
2610
+ if (existsSync8(dest)) {
2611
+ let cur = "";
2612
+ try {
2613
+ cur = readFileSync10(dest, "utf8");
2614
+ } catch {
2615
+ cur = "";
2616
+ }
2617
+ if (hashString(cur) === hash) {
2618
+ next.push({ skill: skillName, path: dest, hash });
2619
+ return;
2620
+ }
2621
+ }
2622
+ mkdirSync8(dirname3(dest), { recursive: true });
2623
+ writeFileSync8(dest, content, "utf8");
2624
+ next.push({ skill: skillName, path: dest, hash });
2625
+ res.written.push(dest);
2626
+ }
2627
+ function removeArtifact(path) {
2628
+ try {
2629
+ if (!existsSync8(path)) return false;
2630
+ rmSync4(path, { recursive: true, force: true });
2631
+ return true;
2632
+ } catch {
2633
+ return false;
2634
+ }
2635
+ }
2636
+ function syncSkillCommands(brain, ws = workspace()) {
2637
+ let res;
2638
+ try {
2639
+ res = compileForBrain(brain, ws);
2640
+ } catch {
2641
+ return;
2642
+ }
2643
+ reportQuiet(brain, res);
2644
+ }
2645
+ function syncAllBrains(enabled, ws = workspace()) {
2646
+ for (const brain of enabled) {
2647
+ try {
2648
+ const res = compileForBrain(brain, ws);
2649
+ reportQuiet(brain, res);
2650
+ } catch {
2651
+ }
2652
+ }
2653
+ }
2654
+ function removeSkillArtifacts(skillName, ws = workspace()) {
2655
+ const manifest = readManifest(ws);
2656
+ let removed = 0;
2657
+ for (const brain of Object.keys(manifest.brains)) {
2658
+ const entries = manifest.brains[brain] || [];
2659
+ const keep = [];
2660
+ for (const e of entries) {
2661
+ if (e.skill === skillName) {
2662
+ if (removeArtifact(e.path)) removed++;
2663
+ } else {
2664
+ keep.push(e);
2665
+ }
2666
+ }
2667
+ manifest.brains[brain] = keep;
2668
+ }
2669
+ try {
2670
+ writeManifest(manifest, ws);
2671
+ } catch {
2672
+ }
2673
+ return removed;
2674
+ }
2675
+ var BRAIN_LABEL = {
2676
+ claude: "Claude Code",
2677
+ gemini: "Gemini CLI",
2678
+ codex: "Codex"
2679
+ };
2680
+ function reportQuiet(brain, res) {
2681
+ const changed = res.written.length + res.removed.length;
2682
+ if (changed === 0 && res.skippedExisting.length === 0) return;
2683
+ const label = BRAIN_LABEL[brain];
2684
+ const parts = [];
2685
+ if (res.written.length) parts.push(`${res.written.length} synced`);
2686
+ if (res.removed.length) parts.push(`${res.removed.length} removed`);
2687
+ if (parts.length) {
2688
+ console.log(c.dim(` Skills as ${label} commands: ${parts.join(", ")}.`));
2689
+ }
2690
+ for (const p of res.skippedExisting) {
2691
+ console.log(c.dim(` Skipped ${p} (already exists and not written by Holt).`));
2692
+ }
2693
+ }
2694
+
2366
2695
  // src/commands/hook.ts
2367
- import { readFileSync as readFileSync11, writeFileSync as writeFileSync9, existsSync as existsSync9, mkdirSync as mkdirSync9, copyFileSync, realpathSync as realpathSync2, appendFileSync as appendFileSync2, statSync as statSync4 } from "fs";
2696
+ import { readFileSync as readFileSync12, writeFileSync as writeFileSync10, existsSync as existsSync10, mkdirSync as mkdirSync10, copyFileSync, realpathSync as realpathSync2, appendFileSync as appendFileSync2, statSync as statSync5 } from "fs";
2368
2697
  import { spawnSync as spawnSync3 } from "child_process";
2369
- import { join as join10, dirname as dirname3 } from "path";
2370
- import { homedir as homedir4 } from "os";
2698
+ import { join as join11, dirname as dirname4 } from "path";
2699
+ import { homedir as homedir5 } from "os";
2371
2700
 
2372
2701
  // src/facts.ts
2373
2702
  var MIN_EXCHANGES_FOR_EXTRACTION = 3;
@@ -2483,15 +2812,15 @@ async function extractAndSaveFacts(active, cfg, history, session) {
2483
2812
 
2484
2813
  // src/wiki.ts
2485
2814
  import {
2486
- readFileSync as readFileSync10,
2487
- writeFileSync as writeFileSync8,
2488
- existsSync as existsSync8,
2489
- mkdirSync as mkdirSync8,
2490
- rmSync as rmSync4,
2491
- readdirSync as readdirSync2,
2492
- statSync as statSync3
2815
+ readFileSync as readFileSync11,
2816
+ writeFileSync as writeFileSync9,
2817
+ existsSync as existsSync9,
2818
+ mkdirSync as mkdirSync9,
2819
+ rmSync as rmSync5,
2820
+ readdirSync as readdirSync3,
2821
+ statSync as statSync4
2493
2822
  } from "fs";
2494
- import { join as join9 } from "path";
2823
+ import { join as join10 } from "path";
2495
2824
  import { totalmem } from "os";
2496
2825
 
2497
2826
  // src/localmodel.ts
@@ -2546,28 +2875,28 @@ function pullHint(model) {
2546
2875
 
2547
2876
  // src/wiki.ts
2548
2877
  function wikiDir() {
2549
- return join9(wsHoltDir(), "wiki");
2878
+ return join10(wsHoltDir(), "wiki");
2550
2879
  }
2551
2880
  function wikiStatePath() {
2552
- return join9(wikiDir(), ".state.json");
2881
+ return join10(wikiDir(), ".state.json");
2553
2882
  }
2554
2883
  function wikiIndexPath() {
2555
- return join9(wikiDir(), "index.md");
2884
+ return join10(wikiDir(), "index.md");
2556
2885
  }
2557
2886
  function pagePath(slug) {
2558
- return join9(wikiDir(), `${slug}.md`);
2887
+ return join10(wikiDir(), `${slug}.md`);
2559
2888
  }
2560
2889
  function loadState() {
2561
2890
  try {
2562
- const s = JSON.parse(readFileSync10(wikiStatePath(), "utf8"));
2891
+ const s = JSON.parse(readFileSync11(wikiStatePath(), "utf8"));
2563
2892
  return { lastSyncTs: typeof s.lastSyncTs === "number" ? s.lastSyncTs : 0, updatedAt: s.updatedAt ?? 0 };
2564
2893
  } catch {
2565
2894
  return { lastSyncTs: 0, updatedAt: 0 };
2566
2895
  }
2567
2896
  }
2568
2897
  function saveState(s) {
2569
- mkdirSync8(wikiDir(), { recursive: true });
2570
- writeFileSync8(wikiStatePath(), JSON.stringify(s, null, 2) + "\n", "utf8");
2898
+ mkdirSync9(wikiDir(), { recursive: true });
2899
+ writeFileSync9(wikiStatePath(), JSON.stringify(s, null, 2) + "\n", "utf8");
2571
2900
  }
2572
2901
  function saveSyncMarker(ts) {
2573
2902
  saveState({ lastSyncTs: ts, updatedAt: Date.now() });
@@ -2577,19 +2906,19 @@ function isPageFile(name) {
2577
2906
  }
2578
2907
  function listPageSlugs() {
2579
2908
  const dir = wikiDir();
2580
- if (!existsSync8(dir)) return [];
2909
+ if (!existsSync9(dir)) return [];
2581
2910
  try {
2582
- return readdirSync2(dir).filter(isPageFile).map((f) => f.slice(0, -3)).sort();
2911
+ return readdirSync3(dir).filter(isPageFile).map((f) => f.slice(0, -3)).sort();
2583
2912
  } catch {
2584
2913
  return [];
2585
2914
  }
2586
2915
  }
2587
2916
  function readPage(slug) {
2588
2917
  const p = pagePath(slug);
2589
- if (!existsSync8(p)) return null;
2918
+ if (!existsSync9(p)) return null;
2590
2919
  let raw = "";
2591
2920
  try {
2592
- raw = readFileSync10(p, "utf8");
2921
+ raw = readFileSync11(p, "utf8");
2593
2922
  } catch {
2594
2923
  return null;
2595
2924
  }
@@ -2631,8 +2960,8 @@ function renderPage(pg) {
2631
2960
  return fm;
2632
2961
  }
2633
2962
  function writePage(pg) {
2634
- mkdirSync8(wikiDir(), { recursive: true });
2635
- writeFileSync8(pagePath(pg.slug), renderPage(pg), "utf8");
2963
+ mkdirSync9(wikiDir(), { recursive: true });
2964
+ writeFileSync9(pagePath(pg.slug), renderPage(pg), "utf8");
2636
2965
  }
2637
2966
  var WIKILINK_RE = /\[\[([^\]]+)\]\]/g;
2638
2967
  function extractLinks(body) {
@@ -2909,8 +3238,8 @@ function renderIndex(pages) {
2909
3238
  return lines.join("\n");
2910
3239
  }
2911
3240
  function writeIndex(pages) {
2912
- mkdirSync8(wikiDir(), { recursive: true });
2913
- writeFileSync8(wikiIndexPath(), renderIndex(pages), "utf8");
3241
+ mkdirSync9(wikiDir(), { recursive: true });
3242
+ writeFileSync9(wikiIndexPath(), renderIndex(pages), "utf8");
2914
3243
  }
2915
3244
  var WIKI_SESSION = "wiki";
2916
3245
  function wikiRowId(slug) {
@@ -2925,9 +3254,9 @@ async function indexPagesForRecall(pages) {
2925
3254
  if (pages.length === 0) return;
2926
3255
  const slugs = new Set(pages.map((p) => sanitizeName(p.slug).slice(0, 24)));
2927
3256
  const kept = dropWikiRows(slugs);
2928
- mkdirSync8(join9(wsHoltDir(), "memory"), { recursive: true });
2929
- writeFileSync8(
2930
- join9(wsHoltDir(), "memory", "turns.jsonl"),
3257
+ mkdirSync9(join10(wsHoltDir(), "memory"), { recursive: true });
3258
+ writeFileSync9(
3259
+ join10(wsHoltDir(), "memory", "turns.jsonl"),
2931
3260
  kept.map((t) => JSON.stringify(t)).join("\n") + (kept.length ? "\n" : ""),
2932
3261
  "utf8"
2933
3262
  );
@@ -2949,9 +3278,9 @@ ${pg.body}`.slice(0, 4e3);
2949
3278
  function clearWikiRecallRows() {
2950
3279
  try {
2951
3280
  const kept = loadTurns().filter((t) => t.session !== WIKI_SESSION);
2952
- mkdirSync8(join9(wsHoltDir(), "memory"), { recursive: true });
2953
- writeFileSync8(
2954
- join9(wsHoltDir(), "memory", "turns.jsonl"),
3281
+ mkdirSync9(join10(wsHoltDir(), "memory"), { recursive: true });
3282
+ writeFileSync9(
3283
+ join10(wsHoltDir(), "memory", "turns.jsonl"),
2955
3284
  kept.map((t) => JSON.stringify(t)).join("\n") + (kept.length ? "\n" : ""),
2956
3285
  "utf8"
2957
3286
  );
@@ -2959,14 +3288,14 @@ function clearWikiRecallRows() {
2959
3288
  }
2960
3289
  }
2961
3290
  function wipeWiki() {
2962
- if (existsSync8(wikiDir())) rmSync4(wikiDir(), { recursive: true, force: true });
3291
+ if (existsSync9(wikiDir())) rmSync5(wikiDir(), { recursive: true, force: true });
2963
3292
  }
2964
3293
  function wikiStats() {
2965
3294
  const slugs = listPageSlugs();
2966
3295
  let bytes = 0;
2967
3296
  for (const slug of slugs) {
2968
3297
  try {
2969
- bytes += statSync3(pagePath(slug)).size;
3298
+ bytes += statSync4(pagePath(slug)).size;
2970
3299
  } catch {
2971
3300
  }
2972
3301
  }
@@ -3005,26 +3334,26 @@ var HOOK_CMD = {
3005
3334
  capture: "holt hook capture"
3006
3335
  };
3007
3336
  function globalSettingsPath() {
3008
- return join10(homedir4(), ".claude", "settings.json");
3337
+ return join11(homedir5(), ".claude", "settings.json");
3009
3338
  }
3010
3339
  function projectSettingsPath() {
3011
- return join10(process.cwd(), ".claude", "settings.json");
3340
+ return join11(process.cwd(), ".claude", "settings.json");
3012
3341
  }
3013
3342
  function readSettings(path) {
3014
- if (!existsSync9(path)) return {};
3343
+ if (!existsSync10(path)) return {};
3015
3344
  try {
3016
- const parsed = JSON.parse(readFileSync11(path, "utf8"));
3345
+ const parsed = JSON.parse(readFileSync12(path, "utf8"));
3017
3346
  return parsed && typeof parsed === "object" ? parsed : {};
3018
3347
  } catch {
3019
3348
  throw new Error(`could not parse ${path} (not valid JSON) - leaving it untouched`);
3020
3349
  }
3021
3350
  }
3022
3351
  function writeSettings(path, settings) {
3023
- mkdirSync9(dirname3(path), { recursive: true });
3024
- writeFileSync9(path, JSON.stringify(settings, null, 2) + "\n", "utf8");
3352
+ mkdirSync10(dirname4(path), { recursive: true });
3353
+ writeFileSync10(path, JSON.stringify(settings, null, 2) + "\n", "utf8");
3025
3354
  }
3026
3355
  function backup(path) {
3027
- if (!existsSync9(path)) return null;
3356
+ if (!existsSync10(path)) return null;
3028
3357
  const dest = `${path}.holt-bak`;
3029
3358
  try {
3030
3359
  copyFileSync(path, dest);
@@ -3114,7 +3443,7 @@ function remove(rest) {
3114
3443
  const paths = project ? [projectSettingsPath()] : [globalSettingsPath(), projectSettingsPath()];
3115
3444
  let touchedAny = false;
3116
3445
  for (const path of paths) {
3117
- if (!existsSync9(path)) continue;
3446
+ if (!existsSync10(path)) continue;
3118
3447
  let settings;
3119
3448
  try {
3120
3449
  settings = readSettings(path);
@@ -3144,7 +3473,7 @@ function status(rest) {
3144
3473
  ];
3145
3474
  console.log(c.accent(" Holt ambient hooks"));
3146
3475
  for (const e of entries) {
3147
- if (!existsSync9(e.path)) {
3476
+ if (!existsSync10(e.path)) {
3148
3477
  console.log(c.dim(` ${e.label.padEnd(8)} ${e.path} (no settings file)`));
3149
3478
  continue;
3150
3479
  }
@@ -3194,7 +3523,7 @@ function parseHookInput(raw) {
3194
3523
  }
3195
3524
  }
3196
3525
  function enterFolder(cwd) {
3197
- if (!cwd || !existsSync9(cwd)) return null;
3526
+ if (!cwd || !existsSync10(cwd)) return null;
3198
3527
  try {
3199
3528
  const real = realpathSync2(cwd);
3200
3529
  process.chdir(real);
@@ -3205,13 +3534,13 @@ function enterFolder(cwd) {
3205
3534
  }
3206
3535
  function guardTrusted(real) {
3207
3536
  if (!isTrusted(real)) return false;
3208
- if (!existsSync9(memDir())) return false;
3537
+ if (!existsSync10(memDir())) return false;
3209
3538
  return true;
3210
3539
  }
3211
3540
  function hookLog(msg) {
3212
3541
  try {
3213
- mkdirSync9(GLOBAL_DIR, { recursive: true });
3214
- appendFileSync2(join10(GLOBAL_DIR, "hooks.log"), `${(/* @__PURE__ */ new Date()).toISOString()} ${msg}
3542
+ mkdirSync10(GLOBAL_DIR, { recursive: true });
3543
+ appendFileSync2(join11(GLOBAL_DIR, "hooks.log"), `${(/* @__PURE__ */ new Date()).toISOString()} ${msg}
3215
3544
  `, "utf8");
3216
3545
  } catch {
3217
3546
  }
@@ -3219,18 +3548,18 @@ function hookLog(msg) {
3219
3548
  function fileBytes(path) {
3220
3549
  if (!path) return 0;
3221
3550
  try {
3222
- return statSync4(path).size;
3551
+ return statSync5(path).size;
3223
3552
  } catch {
3224
3553
  return 0;
3225
3554
  }
3226
3555
  }
3227
3556
  var THROTTLE_MIN_NEW_EXCHANGES = 2;
3228
3557
  function hookStatePath() {
3229
- return join10(GLOBAL_DIR, "hook-state.json");
3558
+ return join11(GLOBAL_DIR, "hook-state.json");
3230
3559
  }
3231
3560
  function readHookState() {
3232
3561
  try {
3233
- const parsed = JSON.parse(readFileSync11(hookStatePath(), "utf8"));
3562
+ const parsed = JSON.parse(readFileSync12(hookStatePath(), "utf8"));
3234
3563
  if (!parsed || typeof parsed !== "object") return {};
3235
3564
  return parsed;
3236
3565
  } catch {
@@ -3243,10 +3572,10 @@ function lastProcessedExchanges(state, sessionId) {
3243
3572
  }
3244
3573
  function saveHookState(sessionId, exchanges) {
3245
3574
  try {
3246
- mkdirSync9(GLOBAL_DIR, { recursive: true });
3575
+ mkdirSync10(GLOBAL_DIR, { recursive: true });
3247
3576
  const state = readHookState();
3248
3577
  state[sessionId] = { lastExchanges: exchanges };
3249
- writeFileSync9(hookStatePath(), JSON.stringify(state, null, 2) + "\n", "utf8");
3578
+ writeFileSync10(hookStatePath(), JSON.stringify(state, null, 2) + "\n", "utf8");
3250
3579
  } catch {
3251
3580
  }
3252
3581
  }
@@ -3320,7 +3649,7 @@ function readTranscript(path) {
3320
3649
  const out = [];
3321
3650
  let raw;
3322
3651
  try {
3323
- raw = readFileSync11(path, "utf8");
3652
+ raw = readFileSync12(path, "utf8");
3324
3653
  } catch {
3325
3654
  return out;
3326
3655
  }
@@ -3348,28 +3677,28 @@ function readTranscript(path) {
3348
3677
  return out;
3349
3678
  }
3350
3679
  function resolveCommandPath(command) {
3351
- if (command.startsWith("/") && existsSync9(command)) return command;
3680
+ if (command.startsWith("/") && existsSync10(command)) return command;
3352
3681
  try {
3353
3682
  const shell = process.env.SHELL || "/bin/sh";
3354
3683
  const res = spawnSync3(shell, ["-lc", "command -v " + command], { encoding: "utf8" });
3355
3684
  if (res.status === 0) {
3356
3685
  const p = (res.stdout || "").trim().split("\n")[0]?.trim();
3357
- if (p && p.startsWith("/") && existsSync9(p)) return p;
3686
+ if (p && p.startsWith("/") && existsSync10(p)) return p;
3358
3687
  }
3359
3688
  } catch {
3360
3689
  }
3361
- const home = homedir4();
3690
+ const home = homedir5();
3362
3691
  const dirs = [
3363
- join10(home, ".local", "bin"),
3692
+ join11(home, ".local", "bin"),
3364
3693
  "/opt/homebrew/bin",
3365
3694
  "/usr/local/bin",
3366
- join10(home, ".npm-global", "bin"),
3695
+ join11(home, ".npm-global", "bin"),
3367
3696
  "/usr/bin",
3368
3697
  "/bin"
3369
3698
  ];
3370
3699
  for (const dir of dirs) {
3371
- const candidate = join10(dir, command);
3372
- if (existsSync9(candidate)) return candidate;
3700
+ const candidate = join11(dir, command);
3701
+ if (existsSync10(candidate)) return candidate;
3373
3702
  }
3374
3703
  return null;
3375
3704
  }
@@ -3443,7 +3772,7 @@ async function capture() {
3443
3772
  let bytes = 0;
3444
3773
  let lines = 0;
3445
3774
  try {
3446
- const rawT = readFileSync11(data.transcript_path, "utf8");
3775
+ const rawT = readFileSync12(data.transcript_path, "utf8");
3447
3776
  bytes = Buffer.byteLength(rawT, "utf8");
3448
3777
  lines = countLines(rawT);
3449
3778
  } catch {
@@ -3541,8 +3870,8 @@ async function hook(sub, rest = []) {
3541
3870
  import { randomUUID as randomUUID4 } from "crypto";
3542
3871
 
3543
3872
  // src/output.ts
3544
- import { writeFileSync as writeFileSync10 } from "fs";
3545
- import { join as join11, isAbsolute } from "path";
3873
+ import { writeFileSync as writeFileSync11 } from "fs";
3874
+ import { join as join12, isAbsolute } from "path";
3546
3875
  function escapeHtml(s) {
3547
3876
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
3548
3877
  }
@@ -3682,8 +4011,8 @@ function saveReply(reply, format, name) {
3682
4011
  throw new Error('name must be a plain file name in this folder (no "/", "\\", or "..").');
3683
4012
  }
3684
4013
  if (!/\.[a-z0-9]+$/i.test(base)) base += ext;
3685
- const path = join11(process.cwd(), base);
3686
- writeFileSync10(path, renderReply(reply, format), "utf8");
4014
+ const path = join12(process.cwd(), base);
4015
+ writeFileSync11(path, renderReply(reply, format), "utf8");
3687
4016
  return path;
3688
4017
  }
3689
4018
 
@@ -3711,12 +4040,12 @@ async function login(which) {
3711
4040
  }
3712
4041
 
3713
4042
  // src/access.ts
3714
- import { existsSync as existsSync10, realpathSync as realpathSync3, statSync as statSync5 } from "fs";
3715
- import { homedir as homedir5 } from "os";
3716
- import { dirname as dirname4, isAbsolute as isAbsolute2, resolve as resolve2, sep } from "path";
4043
+ import { existsSync as existsSync11, realpathSync as realpathSync3, statSync as statSync6 } from "fs";
4044
+ import { homedir as homedir6 } from "os";
4045
+ import { dirname as dirname5, isAbsolute as isAbsolute2, resolve as resolve2, sep } from "path";
3717
4046
  function expandHome(p) {
3718
- if (p === "~") return homedir5();
3719
- if (p.startsWith("~/")) return resolve2(homedir5(), p.slice(2));
4047
+ if (p === "~") return homedir6();
4048
+ if (p.startsWith("~/")) return resolve2(homedir6(), p.slice(2));
3720
4049
  return p;
3721
4050
  }
3722
4051
  function isInside(child, parent) {
@@ -3727,7 +4056,7 @@ function isInside(child, parent) {
3727
4056
  function resolveExisting(token) {
3728
4057
  const expanded = expandHome(token);
3729
4058
  const abs = isAbsolute2(expanded) ? expanded : resolve2(process.cwd(), expanded);
3730
- if (!existsSync10(abs)) return null;
4059
+ if (!existsSync11(abs)) return null;
3731
4060
  try {
3732
4061
  return realpathSync3(abs);
3733
4062
  } catch {
@@ -3736,9 +4065,9 @@ function resolveExisting(token) {
3736
4065
  }
3737
4066
  function containingDir(absPath) {
3738
4067
  try {
3739
- return statSync5(absPath).isDirectory() ? absPath : dirname4(absPath);
4068
+ return statSync6(absPath).isDirectory() ? absPath : dirname5(absPath);
3740
4069
  } catch {
3741
- return dirname4(absPath);
4070
+ return dirname5(absPath);
3742
4071
  }
3743
4072
  }
3744
4073
  function resolveGrantDir(token) {
@@ -4166,13 +4495,13 @@ var CONTEXT_MARKER = "<!-- holt-managed identity -->";
4166
4495
  function brandContextFile(id) {
4167
4496
  const name = CONTEXT_FILE[id];
4168
4497
  if (!name) return null;
4169
- const path = join12(workspace(), name);
4498
+ const path = join13(workspace(), name);
4170
4499
  try {
4171
- if (existsSync11(path)) {
4172
- const cur = readFileSync12(path, "utf8");
4500
+ if (existsSync12(path)) {
4501
+ const cur = readFileSync13(path, "utf8");
4173
4502
  if (!cur.includes(CONTEXT_MARKER)) return null;
4174
4503
  }
4175
- writeFileSync11(path, `${CONTEXT_MARKER}
4504
+ writeFileSync12(path, `${CONTEXT_MARKER}
4176
4505
  # Holt
4177
4506
 
4178
4507
  ${HOLT_IDENTITY}
@@ -4183,11 +4512,11 @@ ${HOLT_IDENTITY}
4183
4512
  }
4184
4513
  }
4185
4514
  function brandStatusLine() {
4186
- const path = join12(workspace(), ".claude", "settings.json");
4515
+ const path = join13(workspace(), ".claude", "settings.json");
4187
4516
  let settings = {};
4188
4517
  try {
4189
- if (existsSync11(path)) {
4190
- const parsed = JSON.parse(readFileSync12(path, "utf8"));
4518
+ if (existsSync12(path)) {
4519
+ const parsed = JSON.parse(readFileSync13(path, "utf8"));
4191
4520
  if (parsed && typeof parsed === "object") settings = parsed;
4192
4521
  }
4193
4522
  } catch {
@@ -4195,13 +4524,13 @@ function brandStatusLine() {
4195
4524
  }
4196
4525
  if (settings.statusLine) return false;
4197
4526
  try {
4198
- if (existsSync11(path)) copyFileSync2(path, `${path}.holt-bak`);
4527
+ if (existsSync12(path)) copyFileSync2(path, `${path}.holt-bak`);
4199
4528
  settings.statusLine = {
4200
4529
  type: "command",
4201
4530
  command: `${resolveHoltPath()} statusline`
4202
4531
  };
4203
- mkdirSync10(dirname5(path), { recursive: true });
4204
- writeFileSync11(path, JSON.stringify(settings, null, 2) + "\n", "utf8");
4532
+ mkdirSync11(dirname6(path), { recursive: true });
4533
+ writeFileSync12(path, JSON.stringify(settings, null, 2) + "\n", "utf8");
4205
4534
  return true;
4206
4535
  } catch {
4207
4536
  return false;
@@ -4223,7 +4552,7 @@ function resolveTarget(cfg) {
4223
4552
  async function ensureSetup() {
4224
4553
  const ws = workspace();
4225
4554
  if (!isTrusted(ws)) trustDir(ws);
4226
- mkdirSync10(memDir(), { recursive: true });
4555
+ mkdirSync11(memDir(), { recursive: true });
4227
4556
  if (!hooksAlreadyInstalled()) {
4228
4557
  try {
4229
4558
  await hook("install", []);
@@ -4233,8 +4562,8 @@ async function ensureSetup() {
4233
4562
  }
4234
4563
  function hooksAlreadyInstalled() {
4235
4564
  try {
4236
- const p = join12(homedir6(), ".claude", "settings.json");
4237
- return existsSync11(p) && readFileSync12(p, "utf8").includes("holt hook");
4565
+ const p = join13(homedir7(), ".claude", "settings.json");
4566
+ return existsSync12(p) && readFileSync13(p, "utf8").includes("holt hook");
4238
4567
  } catch {
4239
4568
  return false;
4240
4569
  }
@@ -4283,6 +4612,7 @@ async function launch() {
4283
4612
  if (ctx) console.log(c.dim(` Holt identity: ${ctx}`));
4284
4613
  }
4285
4614
  if (target.id === "claude") brandStatusLine();
4615
+ syncSkillCommands(target.id);
4286
4616
  const interactive = INTERACTIVE_ARGS[target.id];
4287
4617
  const args = [...interactive, ...flags];
4288
4618
  console.log(c.dim(' Starting your Holt session. Type "exit" to leave.\n'));
@@ -4291,7 +4621,7 @@ async function launch() {
4291
4621
  }
4292
4622
 
4293
4623
  // src/commands/memory.ts
4294
- import { existsSync as existsSync12, readFileSync as readFileSync13 } from "fs";
4624
+ import { existsSync as existsSync13, readFileSync as readFileSync14 } from "fs";
4295
4625
  import { basename } from "path";
4296
4626
  async function memoryCmd(sub, rest = []) {
4297
4627
  const { ask, close } = createReader();
@@ -4339,12 +4669,12 @@ async function memoryCmd(sub, rest = []) {
4339
4669
  return;
4340
4670
  }
4341
4671
  if (action === "facts") {
4342
- if (!existsSync12(factsMdPath())) {
4672
+ if (!existsSync13(factsMdPath())) {
4343
4673
  console.log(c.dim("\n No facts distilled yet. They form when you end a chat session.\n"));
4344
4674
  close();
4345
4675
  return;
4346
4676
  }
4347
- const body = readFileSync13(factsMdPath(), "utf8").trim();
4677
+ const body = readFileSync14(factsMdPath(), "utf8").trim();
4348
4678
  console.log("\n" + body + "\n");
4349
4679
  close();
4350
4680
  return;
@@ -4458,8 +4788,8 @@ function globalCmd(act, rest) {
4458
4788
  }
4459
4789
 
4460
4790
  // src/commands/wiki.ts
4461
- import { existsSync as existsSync13, readFileSync as readFileSync14 } from "fs";
4462
- import { join as join13 } from "path";
4791
+ import { existsSync as existsSync14, readFileSync as readFileSync15 } from "fs";
4792
+ import { join as join14 } from "path";
4463
4793
  import { spawn as spawn3 } from "child_process";
4464
4794
  function titleToSlug(title) {
4465
4795
  return proposeSlug(title);
@@ -4652,7 +4982,7 @@ function listCmd() {
4652
4982
  for (const slug of slugs) {
4653
4983
  const pg = readPage(slug);
4654
4984
  if (!pg) continue;
4655
- const size = existsSync13(join13(wikiDir(), slug + ".md")) ? (readFileSync14(join13(wikiDir(), slug + ".md"), "utf8").length / 1024).toFixed(1) : "0.0";
4985
+ const size = existsSync14(join14(wikiDir(), slug + ".md")) ? (readFileSync15(join14(wikiDir(), slug + ".md"), "utf8").length / 1024).toFixed(1) : "0.0";
4656
4986
  console.log(` ${c.cyan(pg.title.padEnd(28).slice(0, 28))} ${c.dim(pg.updated || " ")} ${size} KB`);
4657
4987
  }
4658
4988
  console.log("");
@@ -4670,7 +5000,7 @@ function showCmd(name) {
4670
5000
  `));
4671
5001
  return;
4672
5002
  }
4673
- const raw = readFileSync14(join13(wikiDir(), slug + ".md"), "utf8");
5003
+ const raw = readFileSync15(join14(wikiDir(), slug + ".md"), "utf8");
4674
5004
  console.log("\n" + raw.trim() + "\n");
4675
5005
  }
4676
5006
  async function statusCmd(cfg) {
@@ -4740,8 +5070,8 @@ function setupCmd(cfg) {
4740
5070
  `));
4741
5071
  }
4742
5072
  function openCmd() {
4743
- const target = existsSync13(wikiIndexPath()) ? wikiIndexPath() : wikiDir();
4744
- if (!existsSync13(target)) {
5073
+ const target = existsSync14(wikiIndexPath()) ? wikiIndexPath() : wikiDir();
5074
+ if (!existsSync14(target)) {
4745
5075
  console.log(c.dim('\n No wiki yet. Run "holt wiki sync" first.\n'));
4746
5076
  return;
4747
5077
  }
@@ -4828,29 +5158,29 @@ async function wikiCmd(sub, rest = []) {
4828
5158
 
4829
5159
  // src/commands/skill.ts
4830
5160
  import {
4831
- mkdirSync as mkdirSync12,
4832
- writeFileSync as writeFileSync13,
4833
- readFileSync as readFileSync16,
4834
- existsSync as existsSync15,
4835
- readdirSync as readdirSync3,
4836
- statSync as statSync7,
4837
- rmSync as rmSync5,
4838
- cpSync,
5161
+ mkdirSync as mkdirSync13,
5162
+ writeFileSync as writeFileSync14,
5163
+ readFileSync as readFileSync17,
5164
+ existsSync as existsSync16,
5165
+ readdirSync as readdirSync4,
5166
+ statSync as statSync8,
5167
+ rmSync as rmSync6,
5168
+ cpSync as cpSync2,
4839
5169
  mkdtempSync
4840
5170
  } from "fs";
4841
- import { join as join15, resolve as resolve4, sep as sep2, isAbsolute as isAbsolute4 } from "path";
5171
+ import { join as join16, resolve as resolve4, sep as sep2, isAbsolute as isAbsolute4 } from "path";
4842
5172
  import { tmpdir } from "os";
4843
5173
  import { spawnSync as spawnSync4 } from "child_process";
4844
5174
 
4845
5175
  // src/registry.ts
4846
- import { readFileSync as readFileSync15, writeFileSync as writeFileSync12, existsSync as existsSync14, mkdirSync as mkdirSync11, statSync as statSync6 } from "fs";
4847
- import { join as join14, isAbsolute as isAbsolute3, resolve as resolve3 } from "path";
5176
+ import { readFileSync as readFileSync16, writeFileSync as writeFileSync13, existsSync as existsSync15, mkdirSync as mkdirSync12, statSync as statSync7 } from "fs";
5177
+ import { join as join15, isAbsolute as isAbsolute3, resolve as resolve3 } from "path";
4848
5178
  import { pathToFileURL, fileURLToPath as fileURLToPath2 } from "url";
4849
5179
  var DEFAULT_REGISTRY_URL = "https://raw.githubusercontent.com/holt-os/registry/main/registry.json";
4850
5180
  var REGISTRY_REPO_URL = "https://github.com/holt-os/registry";
4851
5181
  var CACHE_TTL_MS = 60 * 60 * 1e3;
4852
5182
  function registryCachePath() {
4853
- return join14(GLOBAL_DIR, "registry-cache.json");
5183
+ return join15(GLOBAL_DIR, "registry-cache.json");
4854
5184
  }
4855
5185
  function registryUrl() {
4856
5186
  const env = (process.env.HOLT_REGISTRY_URL || "").trim();
@@ -4889,8 +5219,8 @@ function parseRegistry(text) {
4889
5219
  function readCache() {
4890
5220
  try {
4891
5221
  const path = registryCachePath();
4892
- if (!existsSync14(path)) return null;
4893
- const raw = JSON.parse(readFileSync15(path, "utf8"));
5222
+ if (!existsSync15(path)) return null;
5223
+ const raw = JSON.parse(readFileSync16(path, "utf8"));
4894
5224
  if (!raw || typeof raw.fetchedAt !== "number" || typeof raw.url !== "string") return null;
4895
5225
  const registry = coerceRegistry(raw.registry);
4896
5226
  if (!registry) return null;
@@ -4901,9 +5231,9 @@ function readCache() {
4901
5231
  }
4902
5232
  function writeCache(url, registry) {
4903
5233
  try {
4904
- mkdirSync11(GLOBAL_DIR, { recursive: true });
5234
+ mkdirSync12(GLOBAL_DIR, { recursive: true });
4905
5235
  const body = { fetchedAt: Date.now(), url, registry };
4906
- writeFileSync12(registryCachePath(), JSON.stringify(body, null, 2) + "\n", "utf8");
5236
+ writeFileSync13(registryCachePath(), JSON.stringify(body, null, 2) + "\n", "utf8");
4907
5237
  } catch {
4908
5238
  }
4909
5239
  }
@@ -4921,10 +5251,10 @@ function localPathFor(loc) {
4921
5251
  var UNREACHABLE_MSG = "no registry reachable; set HOLT_REGISTRY_URL or the community registry is not live yet";
4922
5252
  function loadLocal(path) {
4923
5253
  try {
4924
- if (!existsSync14(path)) {
5254
+ if (!existsSync15(path)) {
4925
5255
  return { registry: null, fromCache: false, error: UNREACHABLE_MSG };
4926
5256
  }
4927
- const registry = parseRegistry(readFileSync15(path, "utf8"));
5257
+ const registry = parseRegistry(readFileSync16(path, "utf8"));
4928
5258
  if (!registry) {
4929
5259
  return { registry: null, fromCache: false, error: "registry file is not valid JSON" };
4930
5260
  }
@@ -4993,6 +5323,12 @@ function buildPublishEntry(input) {
4993
5323
  }
4994
5324
 
4995
5325
  // src/commands/skill.ts
5326
+ function enabledBrains() {
5327
+ const cfg = loadConfig();
5328
+ if (!cfg) return [...BRAIN_IDS];
5329
+ const on2 = BRAIN_IDS.filter((b) => cfg.brains[b].enabled);
5330
+ return on2.length ? on2 : [...BRAIN_IDS];
5331
+ }
4996
5332
  function usage() {
4997
5333
  console.log(c.dim([
4998
5334
  "",
@@ -5053,12 +5389,12 @@ function resolveSubpathDir(fetched, subpath) {
5053
5389
  return target;
5054
5390
  }
5055
5391
  function findSkillDir(root) {
5056
- if (existsSync15(join15(root, "SKILL.md"))) return root;
5392
+ if (existsSync16(join16(root, "SKILL.md"))) return root;
5057
5393
  let subs = [];
5058
5394
  try {
5059
- subs = readdirSync3(root).filter((f) => {
5395
+ subs = readdirSync4(root).filter((f) => {
5060
5396
  try {
5061
- return statSync7(join15(root, f)).isDirectory();
5397
+ return statSync8(join16(root, f)).isDirectory();
5062
5398
  } catch {
5063
5399
  return false;
5064
5400
  }
@@ -5066,8 +5402,8 @@ function findSkillDir(root) {
5066
5402
  } catch {
5067
5403
  return null;
5068
5404
  }
5069
- const withSkill = subs.filter((f) => existsSync15(join15(root, f, "SKILL.md")));
5070
- if (withSkill.length === 1) return join15(root, withSkill[0]);
5405
+ const withSkill = subs.filter((f) => existsSync16(join16(root, f, "SKILL.md")));
5406
+ if (withSkill.length === 1) return join16(root, withSkill[0]);
5071
5407
  return null;
5072
5408
  }
5073
5409
  function cmdList() {
@@ -5108,7 +5444,7 @@ function cmdShow(name) {
5108
5444
  const { skill, body } = loaded;
5109
5445
  console.log("\n" + c.accent(skill.name) + c.dim(` (${skill.scope})`));
5110
5446
  if (skill.description) console.log(" " + skill.description);
5111
- console.log(c.dim(" " + join15(skill.dir, "SKILL.md")));
5447
+ console.log(c.dim(" " + join16(skill.dir, "SKILL.md")));
5112
5448
  console.log("");
5113
5449
  console.log(c.dim(body));
5114
5450
  console.log("");
@@ -5120,19 +5456,19 @@ function cmdCreate(name, global) {
5120
5456
  return;
5121
5457
  }
5122
5458
  const scope = global ? "global" : "workspace";
5123
- const dir = join15(skillsRoot(scope), clean);
5124
- if (existsSync15(dir)) {
5459
+ const dir = join16(skillsRoot(scope), clean);
5460
+ if (existsSync16(dir)) {
5125
5461
  console.error(c.red(`
5126
5462
  A ${scope} skill named "${clean}" already exists.`));
5127
5463
  console.error(c.dim(" " + dir + "\n"));
5128
5464
  process.exitCode = 1;
5129
5465
  return;
5130
5466
  }
5131
- mkdirSync12(dir, { recursive: true });
5132
- writeFileSync13(join15(dir, "SKILL.md"), SKILL_TEMPLATE(clean), "utf8");
5467
+ mkdirSync13(dir, { recursive: true });
5468
+ writeFileSync14(join16(dir, "SKILL.md"), SKILL_TEMPLATE(clean), "utf8");
5133
5469
  console.log(c.green(`
5134
5470
  Created ${scope} skill "${clean}".`));
5135
- console.log(c.dim(" " + join15(dir, "SKILL.md")));
5471
+ console.log(c.dim(" " + join16(dir, "SKILL.md")));
5136
5472
  console.log(c.dim(' Edit it, then run it in chat with "/skill ' + clean + '".\n'));
5137
5473
  }
5138
5474
  function installFromSource(source, scope) {
@@ -5141,7 +5477,7 @@ function installFromSource(source, scope) {
5141
5477
  let tempDir = "";
5142
5478
  try {
5143
5479
  if (isGitUrl(base)) {
5144
- tempDir = mkdtempSync(join15(tmpdir(), "holt-skill-"));
5480
+ tempDir = mkdtempSync(join16(tmpdir(), "holt-skill-"));
5145
5481
  console.log(c.dim(`
5146
5482
  Cloning ${base} ...`));
5147
5483
  const res = spawnSync4("git", ["clone", "--depth", "1", base, tempDir], { stdio: "ignore" });
@@ -5153,7 +5489,7 @@ function installFromSource(source, scope) {
5153
5489
  fetched = tempDir;
5154
5490
  } else {
5155
5491
  fetched = resolve4(base);
5156
- if (!existsSync15(fetched)) {
5492
+ if (!existsSync16(fetched)) {
5157
5493
  console.error(c.red(`
5158
5494
  No such path: ${fetched}
5159
5495
  `));
@@ -5171,7 +5507,7 @@ function installFromSource(source, scope) {
5171
5507
  process.exitCode = 1;
5172
5508
  return false;
5173
5509
  }
5174
- if (!existsSync15(target) || !statSync7(target).isDirectory()) {
5510
+ if (!existsSync16(target) || !statSync8(target).isDirectory()) {
5175
5511
  console.error(c.red(`
5176
5512
  Subpath "${subpath}" does not exist in the source.
5177
5513
  `));
@@ -5191,7 +5527,7 @@ function installFromSource(source, scope) {
5191
5527
  }
5192
5528
  let skillName = "";
5193
5529
  try {
5194
- const { data } = parseFrontmatter(readFileSync16(join15(skillDir, "SKILL.md"), "utf8"));
5530
+ const { data } = parseFrontmatter(readFileSync17(join16(skillDir, "SKILL.md"), "utf8"));
5195
5531
  skillName = sanitizeName(data.name || "");
5196
5532
  } catch {
5197
5533
  skillName = "";
@@ -5202,26 +5538,26 @@ function installFromSource(source, scope) {
5202
5538
  process.exitCode = 1;
5203
5539
  return false;
5204
5540
  }
5205
- const dest = join15(skillsRoot(scope), skillName);
5206
- if (existsSync15(dest)) {
5541
+ const dest = join16(skillsRoot(scope), skillName);
5542
+ if (existsSync16(dest)) {
5207
5543
  console.error(c.red(`
5208
5544
  A ${scope} skill named "${skillName}" already exists.`));
5209
5545
  console.error(c.dim(" " + dest + "\n"));
5210
5546
  process.exitCode = 1;
5211
5547
  return false;
5212
5548
  }
5213
- mkdirSync12(skillsRoot(scope), { recursive: true });
5214
- cpSync(skillDir, dest, { recursive: true });
5215
- const nestedGit = join15(dest, ".git");
5216
- if (existsSync15(nestedGit)) rmSync5(nestedGit, { recursive: true, force: true });
5549
+ mkdirSync13(skillsRoot(scope), { recursive: true });
5550
+ cpSync2(skillDir, dest, { recursive: true });
5551
+ const nestedGit = join16(dest, ".git");
5552
+ if (existsSync16(nestedGit)) rmSync6(nestedGit, { recursive: true, force: true });
5217
5553
  console.log(c.green(`
5218
5554
  Installed ${scope} skill "${skillName}".`));
5219
- console.log(c.dim(" " + join15(dest, "SKILL.md") + "\n"));
5555
+ console.log(c.dim(" " + join16(dest, "SKILL.md") + "\n"));
5220
5556
  return true;
5221
5557
  } finally {
5222
- if (tempDir && existsSync15(tempDir)) {
5558
+ if (tempDir && existsSync16(tempDir)) {
5223
5559
  try {
5224
- rmSync5(tempDir, { recursive: true, force: true });
5560
+ rmSync6(tempDir, { recursive: true, force: true });
5225
5561
  } catch {
5226
5562
  }
5227
5563
  }
@@ -5234,8 +5570,8 @@ async function cmdAdd(source, global, refresh) {
5234
5570
  }
5235
5571
  const scope = global ? "global" : "workspace";
5236
5572
  const { base } = splitSubpath(source);
5237
- if (isGitUrl(base) || existsSync15(resolve4(base))) {
5238
- installFromSource(source, scope);
5573
+ if (isGitUrl(base) || existsSync16(resolve4(base))) {
5574
+ if (installFromSource(source, scope)) syncAllBrains(enabledBrains());
5239
5575
  return;
5240
5576
  }
5241
5577
  const { registry, error } = await loadRegistry({ refresh });
@@ -5256,7 +5592,7 @@ async function cmdAdd(source, global, refresh) {
5256
5592
  }
5257
5593
  console.log(c.dim(`
5258
5594
  Resolved "${hit.name}" -> ${hit.source}`));
5259
- installFromSource(hit.source, scope);
5595
+ if (installFromSource(hit.source, scope)) syncAllBrains(enabledBrains());
5260
5596
  }
5261
5597
  async function cmdSearch(query, refresh) {
5262
5598
  const { registry, error, fromCache } = await loadRegistry({ refresh });
@@ -5306,7 +5642,7 @@ function cmdPublish(name) {
5306
5642
  }
5307
5643
  let raw = "";
5308
5644
  try {
5309
- raw = readFileSync16(join15(loaded.skill.dir, "SKILL.md"), "utf8");
5645
+ raw = readFileSync17(join16(loaded.skill.dir, "SKILL.md"), "utf8");
5310
5646
  } catch {
5311
5647
  console.error(c.red("\n Could not read the skill's SKILL.md.\n"));
5312
5648
  process.exitCode = 1;
@@ -5316,14 +5652,14 @@ function cmdPublish(name) {
5316
5652
  skillName = sanitizeName(data.name || loaded.skill.name);
5317
5653
  description = (data.description || loaded.skill.description || "").trim();
5318
5654
  } else {
5319
- const file = join15(process.cwd(), "SKILL.md");
5320
- if (!existsSync15(file)) {
5655
+ const file = join16(process.cwd(), "SKILL.md");
5656
+ if (!existsSync16(file)) {
5321
5657
  console.error(c.red("\n No SKILL.md in the current directory, and no skill name given."));
5322
5658
  console.error(c.dim(" Usage: holt skill publish [<name>]\n"));
5323
5659
  process.exitCode = 1;
5324
5660
  return;
5325
5661
  }
5326
- const { data } = parseFrontmatter(readFileSync16(file, "utf8"));
5662
+ const { data } = parseFrontmatter(readFileSync17(file, "utf8"));
5327
5663
  skillName = sanitizeName(data.name || process.cwd().split(/[\\/]/).pop() || "");
5328
5664
  description = (data.description || "").trim();
5329
5665
  sourceHint = process.cwd();
@@ -5359,11 +5695,11 @@ async function cmdRemove(name, ask) {
5359
5695
  console.log(c.dim("\n Usage: holt skill remove <name>\n"));
5360
5696
  return;
5361
5697
  }
5362
- const wsDir = join15(skillsRoot("workspace"), clean);
5363
- const globalDir = join15(skillsRoot("global"), clean);
5364
- const target = existsSync15(wsDir) ? wsDir : existsSync15(globalDir) ? globalDir : "";
5698
+ const wsDir = join16(skillsRoot("workspace"), clean);
5699
+ const globalDir = join16(skillsRoot("global"), clean);
5700
+ const target = existsSync16(wsDir) ? wsDir : existsSync16(globalDir) ? globalDir : "";
5365
5701
  if (!target) {
5366
- if (existsSync15(join15(skillsRoot("builtin"), clean))) {
5702
+ if (existsSync16(join16(skillsRoot("builtin"), clean))) {
5367
5703
  console.error(c.red(`
5368
5704
  "${clean}" is a built-in skill and cannot be removed; it ships inside Holt.`));
5369
5705
  console.error(c.dim(" Override it instead: create a workspace or global skill with the same name.\n"));
@@ -5380,7 +5716,9 @@ async function cmdRemove(name, ask) {
5380
5716
  const a = (await ask(`
5381
5717
  Delete ${scope} skill "${clean}"? [y/N] `) ?? "").trim().toLowerCase();
5382
5718
  if (a === "y" || a === "yes") {
5383
- rmSync5(target, { recursive: true, force: true });
5719
+ rmSync6(target, { recursive: true, force: true });
5720
+ removeSkillArtifacts(clean);
5721
+ syncAllBrains(enabledBrains());
5384
5722
  console.log(c.green(" Removed.\n"));
5385
5723
  } else {
5386
5724
  console.log(c.dim(" Kept.\n"));
@@ -5436,8 +5774,8 @@ async function skillCmd(sub, rest = []) {
5436
5774
  }
5437
5775
 
5438
5776
  // src/commands/graph.ts
5439
- import { writeFileSync as writeFileSync14, mkdirSync as mkdirSync13, existsSync as existsSync16 } from "fs";
5440
- import { join as join17, dirname as dirname7, resolve as resolve5 } from "path";
5777
+ import { writeFileSync as writeFileSync15, mkdirSync as mkdirSync14, existsSync as existsSync17 } from "fs";
5778
+ import { join as join18, dirname as dirname8, resolve as resolve5 } from "path";
5441
5779
  import { spawn as spawn4 } from "child_process";
5442
5780
 
5443
5781
  // src/communities.ts
@@ -6234,8 +6572,8 @@ function renderGraphHtml(graph2, meta) {
6234
6572
  }
6235
6573
 
6236
6574
  // src/ingest.ts
6237
- import { readdirSync as readdirSync4, readFileSync as readFileSync17, statSync as statSync8 } from "fs";
6238
- import { join as join16, relative, sep as sep3, extname, dirname as dirname6, basename as basename2 } from "path";
6575
+ import { readdirSync as readdirSync5, readFileSync as readFileSync18, statSync as statSync9 } from "fs";
6576
+ import { join as join17, relative, sep as sep3, extname, dirname as dirname7, basename as basename2 } from "path";
6239
6577
  var CODE_EXT = /* @__PURE__ */ new Set([
6240
6578
  "js",
6241
6579
  "jsx",
@@ -6297,7 +6635,7 @@ function ingestFolder(root, want = { code: true, docs: true }) {
6297
6635
  const dir = stack.pop();
6298
6636
  let entries;
6299
6637
  try {
6300
- entries = readdirSync4(dir).sort((a, b) => a.localeCompare(b));
6638
+ entries = readdirSync5(dir).sort((a, b) => a.localeCompare(b));
6301
6639
  } catch {
6302
6640
  skipped.unreadable++;
6303
6641
  continue;
@@ -6308,10 +6646,10 @@ function ingestFolder(root, want = { code: true, docs: true }) {
6308
6646
  skipped.hitFileCap = true;
6309
6647
  break;
6310
6648
  }
6311
- const full = join16(dir, name);
6649
+ const full = join17(dir, name);
6312
6650
  let st;
6313
6651
  try {
6314
- st = statSync8(full);
6652
+ st = statSync9(full);
6315
6653
  } catch {
6316
6654
  skipped.unreadable++;
6317
6655
  continue;
@@ -6341,7 +6679,7 @@ function ingestFolder(root, want = { code: true, docs: true }) {
6341
6679
  }
6342
6680
  let content;
6343
6681
  try {
6344
- content = readFileSync17(full, "utf8");
6682
+ content = readFileSync18(full, "utf8");
6345
6683
  } catch {
6346
6684
  skipped.unreadable++;
6347
6685
  continue;
@@ -6475,7 +6813,7 @@ function resolvePySpec(f, spec, byId) {
6475
6813
  return null;
6476
6814
  }
6477
6815
  function toPosixDir(id) {
6478
- const d = toPosix(dirname6(id));
6816
+ const d = toPosix(dirname7(id));
6479
6817
  return d === "" || d === "." ? "." : d;
6480
6818
  }
6481
6819
  var MD_LINK_RE = /\[[^\]]*\]\(([^)\s]+)(?:\s+["'][^"']*["'])?\)/g;
@@ -6647,7 +6985,7 @@ async function graph(args = []) {
6647
6985
  const ingestCode = opts.code;
6648
6986
  const ingestDocs = opts.docs;
6649
6987
  const turns = loadTurns();
6650
- const includeWiki = opts.wiki !== void 0 ? opts.wiki : existsSync16(wikiDir());
6988
+ const includeWiki = opts.wiki !== void 0 ? opts.wiki : existsSync17(wikiDir());
6651
6989
  const wikiPages = includeWiki ? wikiGraphPages() : [];
6652
6990
  let fileNodeCount = 0;
6653
6991
  let docNodeCount = 0;
@@ -6677,9 +7015,9 @@ async function graph(args = []) {
6677
7015
  if (codeGraph) assignCommunities(g);
6678
7016
  if (opts.report) {
6679
7017
  const md = renderReport(g, { workspace: workspace() });
6680
- const reportPath = opts.out ? resolve5(opts.out) : join17(workspace(), "GRAPH_REPORT.md");
6681
- mkdirSync13(dirname7(reportPath), { recursive: true });
6682
- writeFileSync14(reportPath, md, "utf8");
7018
+ const reportPath = opts.out ? resolve5(opts.out) : join18(workspace(), "GRAPH_REPORT.md");
7019
+ mkdirSync14(dirname8(reportPath), { recursive: true });
7020
+ writeFileSync15(reportPath, md, "utf8");
6683
7021
  const communities = new Set(g.nodes.map((n) => n.community ?? "0")).size;
6684
7022
  console.log("\n" + c.accent("Graph report written") + c.dim(" (this folder)"));
6685
7023
  console.log(` nodes ${g.nodes.length} (${fileNodeCount} files, ${docNodeCount} docs)`);
@@ -6699,9 +7037,9 @@ async function graph(args = []) {
6699
7037
  concepts: conceptCount,
6700
7038
  edges: g.edges.length
6701
7039
  });
6702
- const outPath = opts.out ? resolve5(opts.out) : join17(wsHoltDir(), "graph.html");
6703
- mkdirSync13(dirname7(outPath), { recursive: true });
6704
- writeFileSync14(outPath, html, "utf8");
7040
+ const outPath = opts.out ? resolve5(opts.out) : join18(wsHoltDir(), "graph.html");
7041
+ mkdirSync14(dirname8(outPath), { recursive: true });
7042
+ writeFileSync15(outPath, html, "utf8");
6705
7043
  console.log("\n" + c.accent("Memory graph built") + c.dim(" (this folder)"));
6706
7044
  const parts = [`${turns.length} turns`, `${conceptCount} concepts`];
6707
7045
  if (wikiCount) parts.push(`${wikiCount} wiki pages`);
@@ -6989,7 +7327,7 @@ function holtTools() {
6989
7327
  }
6990
7328
 
6991
7329
  // src/version.ts
6992
- var VERSION = "0.14.1";
7330
+ var VERSION = "0.14.3";
6993
7331
 
6994
7332
  // src/commands/mcp.ts
6995
7333
  function printSetup() {
@@ -7111,7 +7449,7 @@ async function statusline() {
7111
7449
  }
7112
7450
 
7113
7451
  // src/commands/run.ts
7114
- import { writeFileSync as writeFileSync15 } from "fs";
7452
+ import { writeFileSync as writeFileSync16 } from "fs";
7115
7453
  import { resolve as resolve6 } from "path";
7116
7454
  var USAGE3 = [
7117
7455
  " holt run <task> [options]",
@@ -7203,7 +7541,7 @@ async function run(args) {
7203
7541
  if (p.out) {
7204
7542
  const target = resolve6(process.cwd(), p.out);
7205
7543
  try {
7206
- writeFileSync15(target, result.text, "utf8");
7544
+ writeFileSync16(target, result.text, "utf8");
7207
7545
  process.stderr.write(c.dim(`saved to ${target}`) + "\n");
7208
7546
  } catch (e) {
7209
7547
  process.stderr.write(c.red(`Could not write ${target}: ${e.message}`) + "\n");
@@ -7214,8 +7552,8 @@ async function run(args) {
7214
7552
 
7215
7553
  // src/commands/schedule.ts
7216
7554
  import { spawnSync as spawnSync5 } from "child_process";
7217
- import { writeFileSync as writeFileSync16, mkdirSync as mkdirSync14, rmSync as rmSync6, existsSync as existsSync17 } from "fs";
7218
- import { dirname as dirname8 } from "path";
7555
+ import { writeFileSync as writeFileSync17, mkdirSync as mkdirSync15, rmSync as rmSync7, existsSync as existsSync18 } from "fs";
7556
+ import { dirname as dirname9 } from "path";
7219
7557
  function parseAdd(rest) {
7220
7558
  const positional = [];
7221
7559
  const opts = { notify: false };
@@ -7238,8 +7576,8 @@ function parseAdd(rest) {
7238
7576
  }
7239
7577
  function installDarwin(job, holtPath) {
7240
7578
  const path = plistPath(job.id);
7241
- mkdirSync14(dirname8(path), { recursive: true });
7242
- writeFileSync16(path, buildLaunchdPlist(job, holtPath), "utf8");
7579
+ mkdirSync15(dirname9(path), { recursive: true });
7580
+ writeFileSync17(path, buildLaunchdPlist(job, holtPath), "utf8");
7243
7581
  const res = spawnSync5("launchctl", ["load", "-w", path], { encoding: "utf8" });
7244
7582
  if (res.status === 0) {
7245
7583
  console.log(c.green(" Loaded into launchd."));
@@ -7327,10 +7665,10 @@ function listCmd2() {
7327
7665
  }
7328
7666
  function removeDarwin(id) {
7329
7667
  const path = plistPath(id);
7330
- if (existsSync17(path)) {
7668
+ if (existsSync18(path)) {
7331
7669
  spawnSync5("launchctl", ["unload", path], { encoding: "utf8" });
7332
7670
  try {
7333
- rmSync6(path);
7671
+ rmSync7(path);
7334
7672
  } catch {
7335
7673
  }
7336
7674
  }
@@ -7390,29 +7728,29 @@ async function schedule(sub, rest = []) {
7390
7728
 
7391
7729
  // src/commands/routine.ts
7392
7730
  import { spawnSync as spawnSync6 } from "child_process";
7393
- import { writeFileSync as writeFileSync18, mkdirSync as mkdirSync16, rmSync as rmSync7, existsSync as existsSync18 } from "fs";
7394
- import { dirname as dirname9, resolve as resolve7 } from "path";
7731
+ import { writeFileSync as writeFileSync19, mkdirSync as mkdirSync17, rmSync as rmSync8, existsSync as existsSync19 } from "fs";
7732
+ import { dirname as dirname10, resolve as resolve7 } from "path";
7395
7733
 
7396
7734
  // src/routines.ts
7397
- import { readFileSync as readFileSync18, writeFileSync as writeFileSync17, mkdirSync as mkdirSync15 } from "fs";
7398
- import { join as join18 } from "path";
7735
+ import { readFileSync as readFileSync19, writeFileSync as writeFileSync18, mkdirSync as mkdirSync16 } from "fs";
7736
+ import { join as join19 } from "path";
7399
7737
  function sanitizeRoutineName(name) {
7400
7738
  return (name || "").trim().toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "").replace(/-{2,}/g, "-");
7401
7739
  }
7402
7740
  function routinesPath() {
7403
- return join18(GLOBAL_DIR, "routines.json");
7741
+ return join19(GLOBAL_DIR, "routines.json");
7404
7742
  }
7405
7743
  function loadRoutines() {
7406
7744
  try {
7407
- const raw = JSON.parse(readFileSync18(routinesPath(), "utf8"));
7745
+ const raw = JSON.parse(readFileSync19(routinesPath(), "utf8"));
7408
7746
  return Array.isArray(raw) ? raw : [];
7409
7747
  } catch {
7410
7748
  return [];
7411
7749
  }
7412
7750
  }
7413
7751
  function saveRoutines(routines) {
7414
- mkdirSync15(GLOBAL_DIR, { recursive: true });
7415
- writeFileSync17(routinesPath(), JSON.stringify(routines, null, 2) + "\n", "utf8");
7752
+ mkdirSync16(GLOBAL_DIR, { recursive: true });
7753
+ writeFileSync18(routinesPath(), JSON.stringify(routines, null, 2) + "\n", "utf8");
7416
7754
  }
7417
7755
  function findRoutine(name) {
7418
7756
  const want = sanitizeRoutineName(name);
@@ -7472,8 +7810,8 @@ function routineJobId(name) {
7472
7810
  }
7473
7811
  function installDarwin2(job, holtPath) {
7474
7812
  const path = plistPath(job.id);
7475
- mkdirSync16(dirname9(path), { recursive: true });
7476
- writeFileSync18(path, buildLaunchdPlist(job, holtPath), "utf8");
7813
+ mkdirSync17(dirname10(path), { recursive: true });
7814
+ writeFileSync19(path, buildLaunchdPlist(job, holtPath), "utf8");
7477
7815
  const res = spawnSync6("launchctl", ["load", "-w", path], { encoding: "utf8" });
7478
7816
  if (res.status === 0) {
7479
7817
  console.log(c.green(" Loaded into launchd."));
@@ -7517,10 +7855,10 @@ function installSchedule(r) {
7517
7855
  }
7518
7856
  function removeScheduleDarwin(id) {
7519
7857
  const path = plistPath(id);
7520
- if (existsSync18(path)) {
7858
+ if (existsSync19(path)) {
7521
7859
  spawnSync6("launchctl", ["unload", path], { encoding: "utf8" });
7522
7860
  try {
7523
- rmSync7(path);
7861
+ rmSync8(path);
7524
7862
  } catch {
7525
7863
  }
7526
7864
  }
@@ -7713,7 +8051,7 @@ async function runCmd(rest) {
7713
8051
  if (outTarget) {
7714
8052
  const target = resolve7(routine2.workspace, outTarget);
7715
8053
  try {
7716
- writeFileSync18(target, result.text, "utf8");
8054
+ writeFileSync19(target, result.text, "utf8");
7717
8055
  if (!quiet) process.stderr.write(c.dim(`saved to ${target}`) + "\n");
7718
8056
  } catch (e) {
7719
8057
  process.stderr.write(c.red(`Could not write ${target}: ${e.message}`) + "\n");
@@ -7851,7 +8189,7 @@ async function routine(sub, rest = []) {
7851
8189
  }
7852
8190
 
7853
8191
  // src/commands/notify.ts
7854
- import { readFileSync as readFileSync19 } from "fs";
8192
+ import { readFileSync as readFileSync20 } from "fs";
7855
8193
  async function notify(args) {
7856
8194
  const nonFlag = args.filter((a) => a !== "-" && !a.startsWith("--"));
7857
8195
  const wantsStdin = args.includes("-") || !process.stdin.isTTY;
@@ -7884,7 +8222,7 @@ async function notify(args) {
7884
8222
  }
7885
8223
  function readStdin3() {
7886
8224
  try {
7887
- return readFileSync19(0, "utf8");
8225
+ return readFileSync20(0, "utf8");
7888
8226
  } catch {
7889
8227
  return "";
7890
8228
  }
@@ -8095,7 +8433,7 @@ async function doctor() {
8095
8433
  }
8096
8434
 
8097
8435
  // src/commands/write.ts
8098
- import { writeFileSync as writeFileSync19 } from "fs";
8436
+ import { writeFileSync as writeFileSync20 } from "fs";
8099
8437
  import { resolve as resolve8 } from "path";
8100
8438
 
8101
8439
  // src/antiai.ts
@@ -8276,7 +8614,7 @@ async function write(args) {
8276
8614
  if (p.out) {
8277
8615
  const target = resolve8(process.cwd(), p.out);
8278
8616
  try {
8279
- writeFileSync19(target, draft + "\n", "utf8");
8617
+ writeFileSync20(target, draft + "\n", "utf8");
8280
8618
  process.stderr.write(c.dim(`saved to ${target}`) + "\n");
8281
8619
  } catch (e) {
8282
8620
  process.stderr.write(c.red(`Could not write ${target}: ${e.message}`) + "\n");