@uzysjung/agent-harness 26.171.0 → 26.172.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/dist/index.js CHANGED
@@ -101,7 +101,7 @@ import {
101
101
  targetsInclude,
102
102
  upsertHarnessImport,
103
103
  writeInstallLog
104
- } from "./chunk-U4X4Z333.js";
104
+ } from "./chunk-T2HBTG32.js";
105
105
 
106
106
  // node_modules/sisteransi/src/index.js
107
107
  var require_src = __commonJS({
@@ -4190,6 +4190,9 @@ function ownersOf(path) {
4190
4190
  )
4191
4191
  );
4192
4192
  }
4193
+ function bundlePath(path) {
4194
+ return path.startsWith(".agents/skills/") ? `${SKILLS_DIR}${path.slice(".agents/skills/".length)}` : path;
4195
+ }
4193
4196
  function isRecordedTrackTarget(log, path) {
4194
4197
  return recordedTrackTargets(log)(path);
4195
4198
  }
@@ -4790,7 +4793,7 @@ function legacyGitignoreSeed(text, render, previous) {
4790
4793
 
4791
4794
  // src/installer.ts
4792
4795
  init_esm_shims();
4793
- import { chmodSync as chmodSync3, existsSync as existsSync22, readdirSync as readdirSync5, readFileSync as readFileSync22, writeFileSync as writeFileSync8 } from "fs";
4796
+ import { chmodSync as chmodSync3, existsSync as existsSync22, readdirSync as readdirSync5, readFileSync as readFileSync23, writeFileSync as writeFileSync8 } from "fs";
4794
4797
  import { basename as basename4, join as join31, relative as relative5, resolve, sep as sep6 } from "path";
4795
4798
 
4796
4799
  // src/anchor-seed.ts
@@ -6381,7 +6384,7 @@ function runCliTransforms(params) {
6381
6384
 
6382
6385
  // src/displaced.ts
6383
6386
  init_esm_shims();
6384
- import { lstatSync as lstatSync3, mkdirSync as mkdirSync5, renameSync } from "fs";
6387
+ import { lstatSync as lstatSync3, mkdirSync as mkdirSync5, readFileSync as readFileSync17, renameSync } from "fs";
6385
6388
  import { dirname as dirname5, join as join23 } from "path";
6386
6389
  function exists(abs) {
6387
6390
  try {
@@ -6391,13 +6394,23 @@ function exists(abs) {
6391
6394
  return false;
6392
6395
  }
6393
6396
  }
6397
+ function isLegacyDisplaced(log, projectDir, f) {
6398
+ if (f.change !== "displaced") return false;
6399
+ let original;
6400
+ try {
6401
+ original = readFileSync17(join23(projectDir, f.notes[0] ?? f.path), "utf8");
6402
+ } catch {
6403
+ return false;
6404
+ }
6405
+ return isLegacyHarnessFile(f.path, hashContent(original)) && !isRecordedTrackTarget(log, bundlePath(f.path));
6406
+ }
6394
6407
  function restoreDisplaced(log, projectDir, opts) {
6395
6408
  const out = [];
6396
6409
  for (const f of log.rootFiles ?? []) {
6397
6410
  if (f.change !== "displaced" || !opts.has(f.path)) continue;
6398
6411
  const slot = join23(projectDir, f.path);
6399
6412
  if (outsideProjectTarget(projectDir, slot) !== null) continue;
6400
- const backup = f.notes[0] ?? null;
6413
+ const backup = isLegacyDisplaced(log, projectDir, f) ? null : f.notes[0] ?? null;
6401
6414
  const d2 = judgeDisplaced({
6402
6415
  backup,
6403
6416
  backupExists: backup !== null && exists(join23(projectDir, backup)),
@@ -6466,7 +6479,7 @@ import {
6466
6479
  constants as fsConstants,
6467
6480
  mkdirSync as mkdirSync6,
6468
6481
  readdirSync as readdirSync3,
6469
- readFileSync as readFileSync17,
6482
+ readFileSync as readFileSync18,
6470
6483
  renameSync as renameSync2,
6471
6484
  rmdirSync,
6472
6485
  rmSync as rmSync3
@@ -6484,7 +6497,7 @@ function snapshotSkillRoots(projectDir) {
6484
6497
  for (const rel of listFilesRecursive(join25(projectDir, root))) {
6485
6498
  const path = `${root}/${rel}`;
6486
6499
  try {
6487
- out.set(path, hashContent(readFileSync17(join25(projectDir, path), "utf8")));
6500
+ out.set(path, hashContent(readFileSync18(join25(projectDir, path), "utf8")));
6488
6501
  } catch {
6489
6502
  }
6490
6503
  }
@@ -6781,7 +6794,7 @@ function slotFilesToKeep(projectDir, hold) {
6781
6794
  continue;
6782
6795
  const abs = join25(projectDir, path);
6783
6796
  try {
6784
- if (recordedSha !== void 0 && hashContent(readFileSync17(abs, "utf8")) === recordedSha)
6797
+ if (recordedSha !== void 0 && hashContent(readFileSync18(abs, "utf8")) === recordedSha)
6785
6798
  continue;
6786
6799
  accessSync(abs, fsConstants.R_OK);
6787
6800
  } catch {
@@ -6795,12 +6808,12 @@ function slotFilesToKeep(projectDir, hold) {
6795
6808
  function settleAside(projectDir, f, restore) {
6796
6809
  let now = null;
6797
6810
  try {
6798
- now = readFileSync17(f.abs);
6811
+ now = readFileSync18(f.abs);
6799
6812
  } catch (e2) {
6800
6813
  const code = e2.code;
6801
6814
  if (code !== "ENOENT" && code !== "ENOTDIR") throw e2;
6802
6815
  }
6803
- if (restore || (now === null ? !f.recorded : now.equals(readFileSync17(f.aside)))) {
6816
+ if (restore || (now === null ? !f.recorded : now.equals(readFileSync18(f.aside)))) {
6804
6817
  mkdirSync6(dirname6(f.abs), { recursive: true });
6805
6818
  renameSync2(f.aside, f.abs);
6806
6819
  return "back";
@@ -6935,7 +6948,7 @@ function detectVersion(method, spawn, scope, projectDir) {
6935
6948
  case "npm": {
6936
6949
  const pkgJson = scope === "global" ? detectGlobalNpmPackageJsonPath(method.pkg, spawn) : join25(projectDir, "node_modules", method.pkg, "package.json");
6937
6950
  if (!pkgJson || !existsSync19(pkgJson)) return void 0;
6938
- const parsed = JSON.parse(readFileSync17(pkgJson, "utf8"));
6951
+ const parsed = JSON.parse(readFileSync18(pkgJson, "utf8"));
6939
6952
  return parsed.version;
6940
6953
  }
6941
6954
  default:
@@ -6949,7 +6962,7 @@ function detectPluginVersion(pluginId, scope, projectDir) {
6949
6962
  const claudeScope = scope === "global" ? "user" : "project";
6950
6963
  const path = join25(homedir2(), ".claude/plugins/installed_plugins.json");
6951
6964
  if (!existsSync19(path)) return void 0;
6952
- const data = JSON.parse(readFileSync17(path, "utf8"));
6965
+ const data = JSON.parse(readFileSync18(path, "utf8"));
6953
6966
  const entries = data.plugins?.[pluginId] ?? [];
6954
6967
  const matches = entries.filter(
6955
6968
  (e2) => claudeScope === "user" ? e2.scope === "user" : e2.scope === "project" && e2.projectPath === projectDir
@@ -6981,7 +6994,7 @@ function getNpmGlobalRoot(spawn) {
6981
6994
 
6982
6995
  // src/key-ids.ts
6983
6996
  init_esm_shims();
6984
- import { readFileSync as readFileSync18 } from "fs";
6997
+ import { readFileSync as readFileSync19 } from "fs";
6985
6998
  import { join as join26 } from "path";
6986
6999
  function renderedKeyIds(harnessRoot, input, clis) {
6987
7000
  const out = /* @__PURE__ */ new Set();
@@ -7005,7 +7018,7 @@ function renderedKeyIds(harnessRoot, input, clis) {
7005
7018
  for (const name of Object.keys(mcp.mcpServers)) add(".mcp.json", `mcpServers.${name}`);
7006
7019
  for (const key of gitignoreRender().keys()) add(".gitignore", key);
7007
7020
  if (clis.includes("claude")) {
7008
- const template = readFileSync18(join26(harnessRoot, "templates/settings.json"), "utf8");
7021
+ const template = readFileSync19(join26(harnessRoot, "templates/settings.json"), "utf8");
7009
7022
  for (const key of renderSettingsPortion(template, () => true).keys()) {
7010
7023
  add(".claude/settings.json", key);
7011
7024
  }
@@ -7069,7 +7082,7 @@ function refreshLinkedSkillBodies(params) {
7069
7082
 
7070
7083
  // src/out-of-track.ts
7071
7084
  init_esm_shims();
7072
- import { lstatSync as lstatSync4, readFileSync as readFileSync19, rmSync as rmSync4 } from "fs";
7085
+ import { lstatSync as lstatSync4, readFileSync as readFileSync20, rmSync as rmSync4 } from "fs";
7073
7086
  import { join as join28 } from "path";
7074
7087
  var AGENTS_RULE = /^\.agents\/rules\/([^/]+)\.md$/;
7075
7088
  var ANCHOR_RULE = "uzys-harness";
@@ -7099,7 +7112,7 @@ function reclaimOutOfTrack(args) {
7099
7112
  out.bringBack[f.path] = tracksBringing(name);
7100
7113
  continue;
7101
7114
  }
7102
- const disk = stat === void 0 ? null : readFileSync19(abs, "utf8");
7115
+ const disk = stat === void 0 ? null : readFileSync20(abs, "utf8");
7103
7116
  const verdict = judge({
7104
7117
  op: "remove",
7105
7118
  kind: "harness",
@@ -7131,7 +7144,7 @@ function tracksBringing(rule) {
7131
7144
 
7132
7145
  // src/state.ts
7133
7146
  init_esm_shims();
7134
- import { existsSync as existsSync20, readFileSync as readFileSync20 } from "fs";
7147
+ import { existsSync as existsSync20, readFileSync as readFileSync21 } from "fs";
7135
7148
  import { join as join29 } from "path";
7136
7149
  var META_FILE = ".claude/.installed-tracks";
7137
7150
  var LEGACY_ANCHOR_FILE = ".claude/CLAUDE.md";
@@ -7160,7 +7173,7 @@ function tracksFromLog(tracks) {
7160
7173
  }
7161
7174
  function collectTraces(projectDir) {
7162
7175
  const at5 = (rel) => join29(projectDir, rel);
7163
- const contains = (rel, needle) => existsSync20(at5(rel)) && readFileSync20(at5(rel), "utf8").includes(needle);
7176
+ const contains = (rel, needle) => existsSync20(at5(rel)) && readFileSync21(at5(rel), "utf8").includes(needle);
7164
7177
  const traces = [];
7165
7178
  if (existsSync20(at5(META_FILE)))
7166
7179
  traces.push({ path: META_FILE, tracks: readMetafile(at5(META_FILE)) });
@@ -7175,7 +7188,7 @@ function collectTraces(projectDir) {
7175
7188
  }
7176
7189
  function readMetafile(path) {
7177
7190
  const seen = /* @__PURE__ */ new Set();
7178
- for (const word of readFileSync20(path, "utf8").split(/\s+/)) {
7191
+ for (const word of readFileSync21(path, "utf8").split(/\s+/)) {
7179
7192
  if (isTrack(word)) seen.add(word);
7180
7193
  }
7181
7194
  return [...seen].sort();
@@ -7220,7 +7233,7 @@ import {
7220
7233
  copyFileSync,
7221
7234
  existsSync as existsSync21,
7222
7235
  readdirSync as readdirSync4,
7223
- readFileSync as readFileSync21,
7236
+ readFileSync as readFileSync22,
7224
7237
  rmdirSync as rmdirSync2,
7225
7238
  statSync as statSync4,
7226
7239
  unlinkSync as unlinkSync2,
@@ -7541,7 +7554,7 @@ function retiredFeaturesPart(projectDir, f) {
7541
7554
  }
7542
7555
  function legacyHookOnDisk(projectDir, rel) {
7543
7556
  try {
7544
- return hasLegacyHarnessHook(readFileSync21(join30(projectDir, rel), "utf8"));
7557
+ return hasLegacyHarnessHook(readFileSync22(join30(projectDir, rel), "utf8"));
7545
7558
  } catch {
7546
7559
  return false;
7547
7560
  }
@@ -7573,7 +7586,7 @@ function writeUpdateSharedFiles(args) {
7573
7586
  const manifest = buildManifest(spec);
7574
7587
  writeSettingsShared(
7575
7588
  writer,
7576
- readFileSync21(settingsSource, "utf8"),
7589
+ readFileSync22(settingsSource, "utf8"),
7577
7590
  projectDir,
7578
7591
  log,
7579
7592
  (script) => {
@@ -7817,7 +7830,7 @@ function pruneSkillExtras(projectDir, templatesDir, ids, outside, recordOf, now)
7817
7830
  const targetFile = join30(targetSkill, rel);
7818
7831
  if (outside.skip(targetFile)) continue;
7819
7832
  const rec = recordOf(`.claude/skills/${id}/${rel}`);
7820
- if (rec.state !== "sha" || hashContent(readFileSync21(targetFile, "utf8")) !== rec.sha256) {
7833
+ if (rec.state !== "sha" || hashContent(readFileSync22(targetFile, "utf8")) !== rec.sha256) {
7821
7834
  backupFile(targetFile, now);
7822
7835
  backedUp.push(`${id}/${rel}`);
7823
7836
  }
@@ -7924,8 +7937,8 @@ function syncHarnessAnchor(projectDir, templatesDir, report, outside, now = /* @
7924
7937
  if (outside.skip(anchor)) return;
7925
7938
  const existed = existsSync21(anchor);
7926
7939
  if (existed) {
7927
- const current = readFileSync21(anchor, "utf8");
7928
- if (current !== readFileSync21(templateMd, "utf8")) {
7940
+ const current = readFileSync22(anchor, "utf8");
7941
+ if (current !== readFileSync22(templateMd, "utf8")) {
7929
7942
  const recorded2 = readInstallLog(projectDir)?.templates.rootClaudeMd;
7930
7943
  const owned = recorded2?.path === HARNESS_ANCHOR_FILE && hashContent(current) === recorded2.sha256;
7931
7944
  if (!owned) {
@@ -7948,7 +7961,7 @@ function syncHarnessAnchor(projectDir, templatesDir, report, outside, now = /* @
7948
7961
  function upsertRootImport(projectDir, outside) {
7949
7962
  const target = join30(projectDir, "CLAUDE.md");
7950
7963
  if (outside.skip(target)) return false;
7951
- const existing = existsSync21(target) ? readFileSync21(target, "utf8") : null;
7964
+ const existing = existsSync21(target) ? readFileSync22(target, "utf8") : null;
7952
7965
  const next = upsertHarnessImport(existing, {
7953
7966
  projectName: basename3(projectDir),
7954
7967
  tracks: installedTracks(projectDir),
@@ -7976,7 +7989,7 @@ function recordAnchorBaseline(projectDir, anchor) {
7976
7989
  ...log.templates,
7977
7990
  rootClaudeMd: {
7978
7991
  path: HARNESS_ANCHOR_FILE,
7979
- sha256: hashContent(readFileSync21(anchor, "utf8"))
7992
+ sha256: hashContent(readFileSync22(anchor, "utf8"))
7980
7993
  }
7981
7994
  }
7982
7995
  };
@@ -8264,7 +8277,7 @@ function pruneOrphans(target, source, ext, ctx, now) {
8264
8277
  const targetFile = join30(target, file);
8265
8278
  const rec = ctx.recordOf(`.claude/${ctx.prefix}/${file}`);
8266
8279
  try {
8267
- const disk = readFileSync21(targetFile, "utf8");
8280
+ const disk = readFileSync22(targetFile, "utf8");
8268
8281
  const { verdict } = judge({ op: "remove", kind: "harness", rec, disk, next: null });
8269
8282
  if (verdict === "leave" || ctx.outside.skip(targetFile)) continue;
8270
8283
  if (verdict === "backup+remove") backupFile(targetFile, now);
@@ -8330,7 +8343,7 @@ function runInstall(ctx) {
8330
8343
  const settingsPath = join31(projectDir, ".claude", "settings.json");
8331
8344
  if (existsSync22(settingsPath)) {
8332
8345
  try {
8333
- JSON.parse(readFileSync22(settingsPath, "utf8"));
8346
+ JSON.parse(readFileSync23(settingsPath, "utf8"));
8334
8347
  } catch {
8335
8348
  throw new Error(
8336
8349
  `${relative5(process.cwd(), settingsPath)} is not valid JSON \u2014 left untouched, so no hooks were wired. Fix or delete that file, then run the install again`
@@ -8649,7 +8662,7 @@ function pendingKeyExcludes(projectDir, keyExclude, touched) {
8649
8662
  if (path === null || done.has(path) || !existsSync22(join31(projectDir, path))) return [];
8650
8663
  const name = adapterFor(path);
8651
8664
  const keys = [...excludedKeys(path, [id])];
8652
- const present2 = name === null ? null : ADAPTERS[name].read(readFileSync22(join31(projectDir, path), "utf8"), keys, projectDir);
8665
+ const present2 = name === null ? null : ADAPTERS[name].read(readFileSync23(join31(projectDir, path), "utf8"), keys, projectDir);
8653
8666
  return present2 !== null && present2.size === 0 ? [] : [{ id, path }];
8654
8667
  });
8655
8668
  }
@@ -8810,7 +8823,7 @@ function installClaudeBaseline(manifestSpec, projectDir, templatesDir, baselineE
8810
8823
  function writeSettingsPortion(writer, source, projectDir, previousLog, hookInstalled) {
8811
8824
  return writeSettingsShared(
8812
8825
  writer,
8813
- readFileSync22(source, "utf8"),
8826
+ readFileSync23(source, "utf8"),
8814
8827
  projectDir,
8815
8828
  previousLog,
8816
8829
  hookInstalled
@@ -9096,7 +9109,7 @@ function accumulateCategory(cats, entry) {
9096
9109
  function writeRootClaudeMd(projectDir, tracks, continuousSkills, harnessRoot, writer) {
9097
9110
  const target = join31(projectDir, "CLAUDE.md");
9098
9111
  if (writer.skipOutside(target)) return null;
9099
- const existing = existsSync22(target) ? readFileSync22(target, "utf-8") : null;
9112
+ const existing = existsSync22(target) ? readFileSync23(target, "utf-8") : null;
9100
9113
  const seeded = existing === null ? seedRootClaudeProjectContext(projectDir, harnessRoot) : null;
9101
9114
  const content = upsertHarnessImport(existing, {
9102
9115
  projectName: basename4(projectDir),
@@ -9130,7 +9143,7 @@ function listHookFiles(hookDir) {
9130
9143
  // src/commands/install-render.ts
9131
9144
  init_esm_shims();
9132
9145
  import { homedir as homedir3 } from "os";
9133
- import { existsSync as existsSync24, readdirSync as readdirSync6, readFileSync as readFileSync24 } from "fs";
9146
+ import { existsSync as existsSync24, readdirSync as readdirSync6, readFileSync as readFileSync25 } from "fs";
9134
9147
  import { join as join33, relative as relative6 } from "path";
9135
9148
 
9136
9149
  // src/preset-recommend.ts
@@ -9167,7 +9180,7 @@ function groupAssetsByCategory(assetIds) {
9167
9180
 
9168
9181
  // src/resident-entries.ts
9169
9182
  init_esm_shims();
9170
- import { existsSync as existsSync23, readFileSync as readFileSync23 } from "fs";
9183
+ import { existsSync as existsSync23, readFileSync as readFileSync24 } from "fs";
9171
9184
  import { basename as basename5, join as join32 } from "path";
9172
9185
  function residentEntries(spec) {
9173
9186
  const skillThere = (id) => INTERNAL_BUNDLED_SKILL_IDS.includes(id) && [".claude/skills", ".agents/skills"].some((d2) => existsSync23(join32(spec.projectDir, d2, id)));
@@ -9208,7 +9221,7 @@ function plannedClaudeContext(spec) {
9208
9221
  if (!spec.cli.includes("claude")) return void 0;
9209
9222
  const root = resolveBundleRoot();
9210
9223
  const rootClaude = join32(spec.projectDir, "CLAUDE.md");
9211
- const existing = existsSync23(rootClaude) ? readFileSync23(rootClaude, "utf-8") : null;
9224
+ const existing = existsSync23(rootClaude) ? readFileSync24(rootClaude, "utf-8") : null;
9212
9225
  const seeded = existing === null ? seedRootClaudeProjectContext(spec.projectDir, root) : null;
9213
9226
  if (existing === null && seeded === null) return void 0;
9214
9227
  const manifestSpec = buildManifestSpec(spec);
@@ -9374,7 +9387,7 @@ function renderUpdateSummary(log, spec, report) {
9374
9387
  log(
9375
9388
  infoRow(
9376
9389
  "NEXT",
9377
- unmeasured === backups.length ? 'nothing to re-apply unless you remember editing one of them \u2014 then ask audit-harness-fit: "update \uBC31\uC5C5\uBCF8\uC758 \uB0B4 \uD3B8\uC9D1\uC744 \uC0C8 \uD310\uC5D0 \uB2E4\uC2DC \uC5B9\uC5B4\uC918"' : 'to re-apply your edits on the new version, ask audit-harness-fit: "update \uBC31\uC5C5\uBCF8\uC758 \uB0B4 \uD3B8\uC9D1\uC744 \uC0C8 \uD310\uC5D0 \uB2E4\uC2DC \uC5B9\uC5B4\uC918"'
9390
+ unmeasured === backups.length ? 'nothing to carry over unless you remember editing one of them \u2014 then ask audit-harness-fit: "update \uBC31\uC5C5\uBCF8\uC758 \uB0B4 \uD3B8\uC9D1\uC744 \uB0B4 \uD30C\uC77C\uB85C \uC62E\uACA8\uC918"' : 'backups are not loaded \u2014 to keep your edits across updates, ask audit-harness-fit: "update \uBC31\uC5C5\uBCF8\uC758 \uB0B4 \uD3B8\uC9D1\uC744 \uB0B4 \uD30C\uC77C\uB85C \uC62E\uACA8\uC918" (update replaces harness files every time, so edits put back inside them return as backups)'
9378
9391
  )
9379
9392
  );
9380
9393
  }
@@ -9671,7 +9684,7 @@ function renderFinalSummary(log, spec, report, fromWizard) {
9671
9684
  const home = process.env.CODEX_HOME ?? join33(homedir3(), ".codex");
9672
9685
  const configPath = join33(home, "config.toml");
9673
9686
  if (!existsSync24(configPath)) return false;
9674
- return hasTrustEntry(readFileSync24(configPath, "utf8"), spec.projectDir);
9687
+ return hasTrustEntry(readFileSync25(configPath, "utf8"), spec.projectDir);
9675
9688
  } catch {
9676
9689
  return false;
9677
9690
  }
@@ -9712,7 +9725,7 @@ function renderFinalSummary(log, spec, report, fromWizard) {
9712
9725
  }
9713
9726
  function hasFillPrompt(path) {
9714
9727
  try {
9715
- return readFileSync24(path, "utf8").includes("<!-- FILL:");
9728
+ return readFileSync25(path, "utf8").includes("<!-- FILL:");
9716
9729
  } catch {
9717
9730
  return false;
9718
9731
  }
@@ -10848,7 +10861,7 @@ function registerInstallCommand(cli) {
10848
10861
 
10849
10862
  // src/commands/list.ts
10850
10863
  init_esm_shims();
10851
- import { existsSync as existsSync25, readFileSync as readFileSync25 } from "fs";
10864
+ import { existsSync as existsSync25, readFileSync as readFileSync26 } from "fs";
10852
10865
  import { join as join34, resolve as resolve3 } from "path";
10853
10866
  function listAction(options = {}, deps = {}) {
10854
10867
  const log = deps.log ?? console.log;
@@ -10953,7 +10966,7 @@ function formatHarnessFileRows(log, projectDir) {
10953
10966
  const rootMd = log.templates.rootClaudeMd;
10954
10967
  if (rootMd) {
10955
10968
  const path = join34(projectDir, rootMd.path);
10956
- const modified = existsSync25(path) && hashContent(readFileSync25(path, "utf8")) !== rootMd.sha256;
10969
+ const modified = existsSync25(path) && hashContent(readFileSync26(path, "utf8")) !== rootMd.sha256;
10957
10970
  rows2.push(
10958
10971
  modified ? ` ${c.dim(rootMd.path)} ${c.yellow("(\uC218\uC815\uB428 \u2014 uninstall \uC2DC \uBCF4\uC874)")}` : ` ${c.dim(rootMd.path)}`
10959
10972
  );
@@ -10990,7 +11003,7 @@ import {
10990
11003
  constants as fsConstants2,
10991
11004
  lstatSync as lstatSync5,
10992
11005
  readdirSync as readdirSync7,
10993
- readFileSync as readFileSync26,
11006
+ readFileSync as readFileSync27,
10994
11007
  readlinkSync,
10995
11008
  realpathSync as realpathSync3,
10996
11009
  rmdirSync as rmdirSync3,
@@ -12087,7 +12100,8 @@ var TRACK_LABELS = {
12087
12100
  "csr-supabase": "csr-supabase \u2014 Vite + React + Supabase",
12088
12101
  "csr-fastify": "csr-fastify \u2014 Vite + React + Fastify",
12089
12102
  "csr-fastapi": "csr-fastapi \u2014 Vite + React + FastAPI",
12090
- "ssr-htmx": "ssr-htmx \u2014 htmx + FastAPI",
12103
+ "ssr-htmx": "ssr-htmx \u2014 htmx + FastAPI (Python) + daisyUI",
12104
+ "ssr-htmx-fastify": "ssr-htmx-fastify \u2014 htmx + Fastify (Node) + daisyUI",
12091
12105
  "ssr-nextjs": "ssr-nextjs \u2014 Next.js (App Router)",
12092
12106
  data: "data \u2014 Python data / DuckDB / PySide6",
12093
12107
  executive: "executive \u2014 proposals / DD / pitch (no agent-skills)",
@@ -13182,7 +13196,7 @@ function agentsMdRerenderSet(target, remaining, log, projectDir) {
13182
13196
  }
13183
13197
  function readTextOrEmpty(abs) {
13184
13198
  try {
13185
- return readFileSync26(abs, "utf8");
13199
+ return readFileSync27(abs, "utf8");
13186
13200
  } catch {
13187
13201
  return "";
13188
13202
  }
@@ -13323,7 +13337,7 @@ function remnantFor(path, log, harnessRoot, projectDir, wiringGone = []) {
13323
13337
  const gone = (k2) => wiringGone.includes(`hooks/${k2.split("#")[1] ?? ""}`);
13324
13338
  return (disk) => {
13325
13339
  try {
13326
- const template = readFileSync26(join35(harnessRoot, "templates", "settings.json"), "utf8");
13340
+ const template = readFileSync27(join35(harnessRoot, "templates", "settings.json"), "utf8");
13327
13341
  const render = renderSettingsPortion(template, () => true);
13328
13342
  return [...legacySettingsSeed(disk, render, projectDir, { edited: true }).keys()].filter(
13329
13343
  (k2) => !k2.endsWith("{}") && !gone(k2)
@@ -13646,7 +13660,7 @@ function templateNext(harnessRoot, log, path) {
13646
13660
  if (helper === void 0 && !path.startsWith(CLAUDE_DIR3)) return null;
13647
13661
  try {
13648
13662
  const source = helper ?? path.slice(CLAUDE_DIR3.length);
13649
- return readFileSync26(join35(harnessRoot, "templates", source), "utf8");
13663
+ return readFileSync27(join35(harnessRoot, "templates", source), "utf8");
13650
13664
  } catch {
13651
13665
  return null;
13652
13666
  }
@@ -13690,13 +13704,13 @@ function removeRecordedFile(path, ctx) {
13690
13704
  return;
13691
13705
  }
13692
13706
  if (st2.isSymbolicLink()) effective = real;
13693
- disk = readFileSync26(effective, "utf8");
13707
+ disk = readFileSync27(effective, "utf8");
13694
13708
  } catch {
13695
13709
  out.unjudged.push(path);
13696
13710
  return;
13697
13711
  }
13698
13712
  const rec = recorded(log, path, { isTarget: ctx.isTarget });
13699
- const legacy = rec.state !== "sha" && isLegacyHarnessFile(path, hashContent(disk)) && (rec.state === "no-sha" || mayReclaimLegacy(log, path));
13713
+ const legacy = rec.state !== "sha" && isLegacyHarnessFile(path, hashContent(disk)) && (rec.state === "no-sha" || mayReclaimLegacy(log, projectDir, path));
13700
13714
  const inBundle = legacy && ctx.isTarget(bundlePath(path));
13701
13715
  const verdict = judge({
13702
13716
  op: "remove",
@@ -13726,14 +13740,13 @@ function legacyFileCandidates() {
13726
13740
  (p2) => p2.startsWith(SKILLS_DIR3) ? [p2, `.agents/skills/${p2.slice(SKILLS_DIR3.length)}`] : [p2]
13727
13741
  );
13728
13742
  }
13729
- function bundlePath(path) {
13730
- return path.startsWith(".agents/skills/") ? `${SKILLS_DIR3}${path.slice(".agents/skills/".length)}` : path;
13731
- }
13732
- function mayReclaimLegacy(log, path) {
13743
+ function mayReclaimLegacy(log, projectDir, path) {
13733
13744
  const clis = installedClis(log);
13734
13745
  if (!ownersOf(path).some((c3) => clis.includes(c3))) return false;
13735
13746
  if (isExcludedPath(bundlePath(path), excludedIds(log))) return false;
13736
- return !(log.rootFiles ?? []).some((f) => f.path === path && f.change === "displaced");
13747
+ return !(log.rootFiles ?? []).some(
13748
+ (f) => f.path === path && f.change === "displaced" && !isLegacyDisplaced(log, projectDir, f)
13749
+ );
13737
13750
  }
13738
13751
  function removeLegacyHookWiring(log, projectDir, scope, io, removed) {
13739
13752
  if (!scope.has(SETTINGS_TARGET) || !installedClis(log).includes("claude")) return [];
@@ -13816,7 +13829,7 @@ function removeHarnessMadeShared(path, sha, projectDir, io, out, pruneFrom) {
13816
13829
  return true;
13817
13830
  }
13818
13831
  if (lstatSync5(abs).isSymbolicLink()) effective = real;
13819
- current = readFileSync26(effective, "utf8");
13832
+ current = readFileSync27(effective, "utf8");
13820
13833
  } catch {
13821
13834
  out.unjudged.push(path);
13822
13835
  return true;
@@ -14079,7 +14092,7 @@ function removeAnchor(log, projectDir, io) {
14079
14092
  if (outside !== null) return { removed: false, lines: outsideLines([outside], log) };
14080
14093
  let disk;
14081
14094
  try {
14082
- disk = readFileSync26(abs, "utf8");
14095
+ disk = readFileSync27(abs, "utf8");
14083
14096
  } catch {
14084
14097
  return {
14085
14098
  removed: false,
@@ -14124,7 +14137,7 @@ function removeAnchor(log, projectDir, io) {
14124
14137
  var AGENTS_MD2 = "AGENTS.md";
14125
14138
  function readAgentsMdTemplate(harnessRoot) {
14126
14139
  try {
14127
- return readFileSync26(join35(harnessRoot, AGENTS_MD_TEMPLATE), "utf8");
14140
+ return readFileSync27(join35(harnessRoot, AGENTS_MD_TEMPLATE), "utf8");
14128
14141
  } catch {
14129
14142
  return null;
14130
14143
  }
@@ -14157,7 +14170,7 @@ function removeUnrecordedLegacyAgentsMd(path, projectDir, io, out, pruneFrom) {
14157
14170
  const real = realpathSync3(abs);
14158
14171
  if (!statSync5(real).isFile()) return false;
14159
14172
  if (lstatSync5(abs).isSymbolicLink()) effective = real;
14160
- current = readFileSync26(effective, "utf8");
14173
+ current = readFileSync27(effective, "utf8");
14161
14174
  } catch {
14162
14175
  return false;
14163
14176
  }
@@ -14219,7 +14232,7 @@ function removeToolFiles(files, projectDir, rm) {
14219
14232
  continue;
14220
14233
  }
14221
14234
  try {
14222
- if (hashContent(readFileSync26(abs, "utf8")) !== sha256) {
14235
+ if (hashContent(readFileSync27(abs, "utf8")) !== sha256) {
14223
14236
  const backup = backupFile(abs);
14224
14237
  notes.push(`backed up ${path} \u2192 ${relative7(projectDir, backup)} (changed since install)`);
14225
14238
  }
@@ -14267,7 +14280,7 @@ function readRootClaudeMd(projectDir) {
14267
14280
  const path = join35(projectDir, "CLAUDE.md");
14268
14281
  if (!existsSync26(path)) return null;
14269
14282
  try {
14270
- return readFileSync26(path, "utf8");
14283
+ return readFileSync27(path, "utf8");
14271
14284
  } catch {
14272
14285
  return null;
14273
14286
  }