@uzysjung/agent-harness 26.130.0 → 26.131.1

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/README.md CHANGED
@@ -45,6 +45,7 @@ What it installed is recorded, so you can review it and take it back out:
45
45
 
46
46
  ```bash
47
47
  npx -y @uzysjung/agent-harness list # what this project got
48
+ npx -y @uzysjung/agent-harness update # refresh it to the current release
48
49
  npx -y @uzysjung/agent-harness uninstall # pick what to remove
49
50
  ```
50
51
 
package/dist/index.js CHANGED
@@ -712,7 +712,7 @@ var cac = (name = "") => new CAC(name);
712
712
  // package.json
713
713
  var package_default = {
714
714
  name: "@uzysjung/agent-harness",
715
- version: "26.130.0",
715
+ version: "26.131.1",
716
716
  description: "Curate vetted AI-coding skills & plugins by your tech stack \u2014 install only what you need, across Claude Code, Codex, OpenCode & Antigravity",
717
717
  type: "module",
718
718
  publishConfig: {
@@ -2152,6 +2152,14 @@ import {
2152
2152
  writeFileSync as writeFileSync8
2153
2153
  } from "fs";
2154
2154
  import { dirname as dirname4, join as join10 } from "path";
2155
+ function buildUpdateSpec(projectDir, tracks) {
2156
+ return {
2157
+ tracks: [...tracks],
2158
+ options: DEFAULT_OPTIONS,
2159
+ cli: ["claude"],
2160
+ projectDir
2161
+ };
2162
+ }
2155
2163
  function runUpdateMode(projectDir, templatesDir) {
2156
2164
  const claudeDir = join10(projectDir, ".claude");
2157
2165
  const report = {
@@ -4948,6 +4956,90 @@ async function dispatchUninstall(options) {
4948
4956
  uninstallAction(picked.options);
4949
4957
  }
4950
4958
 
4959
+ // src/commands/update.ts
4960
+ init_esm_shims();
4961
+ import { resolve as resolve5 } from "path";
4962
+
4963
+ // src/state.ts
4964
+ init_esm_shims();
4965
+ import { existsSync as existsSync15, readFileSync as readFileSync14 } from "fs";
4966
+ import { join as join14 } from "path";
4967
+ var META_FILE = ".claude/.installed-tracks";
4968
+ var LEGACY_SIGNATURES = [
4969
+ { rule: "htmx.md", track: "ssr-htmx" },
4970
+ { rule: "nextjs.md", track: "ssr-nextjs" },
4971
+ { rule: "data-analysis.md", track: "data" },
4972
+ { rule: "pyside6.md", track: "data" },
4973
+ { rule: "cli-development.md", track: "tooling" }
4974
+ ];
4975
+ function detectInstallState(projectDir) {
4976
+ const claudeDir = join14(projectDir, ".claude");
4977
+ const hasClaudeDir = existsSync15(claudeDir);
4978
+ if (!hasClaudeDir) {
4979
+ return { state: "new", tracks: [], source: "none", hasClaudeDir: false };
4980
+ }
4981
+ const metaPath = join14(projectDir, META_FILE);
4982
+ if (existsSync15(metaPath)) {
4983
+ const tracks2 = readMetafile(metaPath);
4984
+ return { state: "existing", tracks: tracks2, source: "metafile", hasClaudeDir: true };
4985
+ }
4986
+ const tracks = inferFromLegacySignatures(projectDir);
4987
+ return { state: "existing", tracks, source: "legacy", hasClaudeDir: true };
4988
+ }
4989
+ function readMetafile(path) {
4990
+ const raw = readFileSync14(path, "utf8");
4991
+ const seen = /* @__PURE__ */ new Set();
4992
+ for (const line of raw.split(/\s+/)) {
4993
+ const trimmed = line.trim();
4994
+ if (isTrack(trimmed)) {
4995
+ seen.add(trimmed);
4996
+ }
4997
+ }
4998
+ return [...seen].sort();
4999
+ }
5000
+ function inferFromLegacySignatures(projectDir) {
5001
+ const rulesDir = join14(projectDir, ".claude/rules");
5002
+ if (!existsSync15(rulesDir)) {
5003
+ return [];
5004
+ }
5005
+ const found = /* @__PURE__ */ new Set();
5006
+ for (const sig of LEGACY_SIGNATURES) {
5007
+ if (existsSync15(join14(rulesDir, sig.rule))) {
5008
+ found.add(sig.track);
5009
+ }
5010
+ }
5011
+ return [...found].sort();
5012
+ }
5013
+
5014
+ // src/commands/update.ts
5015
+ function updateAction(options = {}, deps = {}) {
5016
+ const log = deps.log ?? console.log;
5017
+ const err = deps.err ?? console.error;
5018
+ const exit = deps.exit ?? ((code) => process.exit(code));
5019
+ const detect = deps.detect ?? detectInstallState;
5020
+ const execute = deps.execute ?? executeSpec;
5021
+ const projectDir = resolve5(options.projectDir ?? process.cwd());
5022
+ const state = detect(projectDir);
5023
+ if (!state.hasClaudeDir) {
5024
+ err(status.failure(c.red(`No harness install found at ${projectDir}/.claude`)));
5025
+ err(c.dim(" Run `agent-harness install --track <name>` first."));
5026
+ exit(1);
5027
+ return;
5028
+ }
5029
+ log(c.dim(`Updating policy files in ${projectDir}/.claude`));
5030
+ execute(buildUpdateSpec(projectDir, state.tracks), { log, err, exit, mode: "update" });
5031
+ }
5032
+ function registerUpdateCommand(cli2) {
5033
+ cli2.command(
5034
+ "update",
5035
+ "Refresh installed policy files (rules / agents / commands / hooks / skills)"
5036
+ ).option("--project-dir <path>", "[Project] Target project directory", {
5037
+ default: process.cwd()
5038
+ }).action((options) => {
5039
+ updateAction(options);
5040
+ });
5041
+ }
5042
+
4951
5043
  // src/interactive.ts
4952
5044
  init_esm_shims();
4953
5045
 
@@ -5264,57 +5356,6 @@ Proceed?`,
5264
5356
  }
5265
5357
  };
5266
5358
 
5267
- // src/state.ts
5268
- init_esm_shims();
5269
- import { existsSync as existsSync15, readFileSync as readFileSync14 } from "fs";
5270
- import { join as join14 } from "path";
5271
- var META_FILE = ".claude/.installed-tracks";
5272
- var LEGACY_SIGNATURES = [
5273
- { rule: "htmx.md", track: "ssr-htmx" },
5274
- { rule: "nextjs.md", track: "ssr-nextjs" },
5275
- { rule: "data-analysis.md", track: "data" },
5276
- { rule: "pyside6.md", track: "data" },
5277
- { rule: "cli-development.md", track: "tooling" }
5278
- ];
5279
- function detectInstallState(projectDir) {
5280
- const claudeDir = join14(projectDir, ".claude");
5281
- const hasClaudeDir = existsSync15(claudeDir);
5282
- if (!hasClaudeDir) {
5283
- return { state: "new", tracks: [], source: "none", hasClaudeDir: false };
5284
- }
5285
- const metaPath = join14(projectDir, META_FILE);
5286
- if (existsSync15(metaPath)) {
5287
- const tracks2 = readMetafile(metaPath);
5288
- return { state: "existing", tracks: tracks2, source: "metafile", hasClaudeDir: true };
5289
- }
5290
- const tracks = inferFromLegacySignatures(projectDir);
5291
- return { state: "existing", tracks, source: "legacy", hasClaudeDir: true };
5292
- }
5293
- function readMetafile(path) {
5294
- const raw = readFileSync14(path, "utf8");
5295
- const seen = /* @__PURE__ */ new Set();
5296
- for (const line of raw.split(/\s+/)) {
5297
- const trimmed = line.trim();
5298
- if (isTrack(trimmed)) {
5299
- seen.add(trimmed);
5300
- }
5301
- }
5302
- return [...seen].sort();
5303
- }
5304
- function inferFromLegacySignatures(projectDir) {
5305
- const rulesDir = join14(projectDir, ".claude/rules");
5306
- if (!existsSync15(rulesDir)) {
5307
- return [];
5308
- }
5309
- const found = /* @__PURE__ */ new Set();
5310
- for (const sig of LEGACY_SIGNATURES) {
5311
- if (existsSync15(join14(rulesDir, sig.rule))) {
5312
- found.add(sig.track);
5313
- }
5314
- }
5315
- return [...found].sort();
5316
- }
5317
-
5318
5359
  // src/interactive.ts
5319
5360
  function splitInstallTargets(targets) {
5320
5361
  const optionKeys = [];
@@ -5381,29 +5422,17 @@ async function runInteractive(projectDir, deps = {}) {
5381
5422
  }
5382
5423
  if (action === "update") {
5383
5424
  mode = "update";
5384
- const summary = formatSummary({
5385
- tracks: state.tracks,
5386
- options: toOptionFlags([]),
5387
- cli: ["claude"],
5388
- projectDir
5389
- });
5390
- const confirmed = await prompts.confirmInstall(`UPDATE policy files only:
5391
- ${summary}`);
5425
+ const spec = buildUpdateSpec(projectDir, state.tracks);
5426
+ const confirmed = await prompts.confirmInstall(
5427
+ `UPDATE policy files only:
5428
+ ${formatSummary(spec)}`
5429
+ );
5392
5430
  if (!confirmed) {
5393
5431
  prompts.outro("Cancelled.");
5394
5432
  return { ok: false, reason: "cancelled" };
5395
5433
  }
5396
5434
  prompts.outro("Running update mode...");
5397
- return {
5398
- ok: true,
5399
- mode: "update",
5400
- spec: {
5401
- tracks: state.tracks,
5402
- options: toOptionFlags([]),
5403
- cli: ["claude"],
5404
- projectDir
5405
- }
5406
- };
5435
+ return { ok: true, mode: "update", spec };
5407
5436
  }
5408
5437
  if (action === "add") {
5409
5438
  mode = "add";
@@ -5588,6 +5617,7 @@ function buildCli() {
5588
5617
  cli2.help();
5589
5618
  cli2.version(VERSION);
5590
5619
  registerInstallCommand(cli2);
5620
+ registerUpdateCommand(cli2);
5591
5621
  registerListCommand(cli2);
5592
5622
  registerUninstallCommand(cli2);
5593
5623
  cli2.command("", "Interactive installer (state detection + prompts)").action(() => defaultAction());