@uzysjung/agent-harness 26.85.0 → 26.87.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
@@ -2,6 +2,7 @@
2
2
  import {
3
3
  CATEGORIES,
4
4
  CATEGORY_TITLES,
5
+ DEV_METHOD_SKILL_IDS,
5
6
  EXTERNAL_ASSETS,
6
7
  __commonJS,
7
8
  __toESM,
@@ -13,7 +14,7 @@ import {
13
14
  hasUiTrack,
14
15
  init_esm_shims,
15
16
  isAssetSelected
16
- } from "./chunk-SPZ63E7P.js";
17
+ } from "./chunk-QHYH6P32.js";
17
18
 
18
19
  // node_modules/sisteransi/src/index.js
19
20
  var require_src = __commonJS({
@@ -698,8 +699,8 @@ var cac = (name = "") => new CAC(name);
698
699
  // package.json
699
700
  var package_default = {
700
701
  name: "@uzysjung/agent-harness",
701
- version: "26.85.0",
702
- description: "Curate vetted AI-coding workflows by your tech stack \u2014 install only what you need, across Claude Code, Codex, OpenCode & Antigravity",
702
+ version: "26.87.0",
703
+ description: "Curate vetted AI-coding skills & plugins by your tech stack \u2014 install only what you need, across Claude Code, Codex, OpenCode & Antigravity",
703
704
  type: "module",
704
705
  publishConfig: {
705
706
  access: "public"
@@ -1016,6 +1017,33 @@ function renderSkill(params) {
1016
1017
  ""
1017
1018
  ].join("\n");
1018
1019
  }
1020
+ function renderBundledSkill(source) {
1021
+ const trimmed = source.trimEnd();
1022
+ const lines = trimmed.split(/\r?\n/);
1023
+ if (lines[0] !== "---") {
1024
+ return `${portBody(trimmed)}
1025
+ `;
1026
+ }
1027
+ let secondDelimAt = -1;
1028
+ for (let i = 1; i < lines.length; i++) {
1029
+ if (lines[i] === "---") {
1030
+ secondDelimAt = i;
1031
+ break;
1032
+ }
1033
+ }
1034
+ if (secondDelimAt < 0) {
1035
+ return `${portBody(trimmed)}
1036
+ `;
1037
+ }
1038
+ const frontmatter = lines.slice(0, secondDelimAt + 1).join("\n");
1039
+ const body = lines.slice(secondDelimAt + 1).join("\n");
1040
+ return `${frontmatter}
1041
+ ${portBody(body)}
1042
+ `;
1043
+ }
1044
+ function portBody(body) {
1045
+ return renameSlashes(body).replace(/CLAUDE_PROJECT_DIR/g, "CODEX_PROJECT_DIR").trimEnd();
1046
+ }
1019
1047
  function parseSource(source) {
1020
1048
  const lines = source.split(/\r?\n/);
1021
1049
  if (lines[0] === "---") {
@@ -1116,10 +1144,21 @@ function ensureProjectSkeleton(projectDir) {
1116
1144
  // src/antigravity/transform.ts
1117
1145
  var PHASES2 = ["spec", "plan", "build", "test", "review", "ship"];
1118
1146
  function runAntigravityTransform(params) {
1119
- const { harnessRoot, projectDir, withUzysHarness } = params;
1147
+ const { harnessRoot, projectDir, withUzysHarness, selectedInternalSkills = [] } = params;
1120
1148
  const rulesFile = writeRules(harnessRoot, projectDir);
1121
1149
  const skillFiles = [];
1122
1150
  const workflowFiles = [];
1151
+ for (const id of selectedInternalSkills) {
1152
+ const src = join3(harnessRoot, "templates/skills", id, "SKILL.md");
1153
+ if (!existsSync3(src)) {
1154
+ continue;
1155
+ }
1156
+ const skillDir = join3(projectDir, ".agents", "skills", id);
1157
+ ensureDir(skillDir);
1158
+ const target = join3(skillDir, "SKILL.md");
1159
+ writeFileSync2(target, renderBundledSkill(readFileSync3(src, "utf8")));
1160
+ skillFiles.push(target);
1161
+ }
1123
1162
  if (withUzysHarness) {
1124
1163
  for (const phase of PHASES2) {
1125
1164
  const skillDir = join3(projectDir, ".agents", "skills", `uzys-${phase}`);
@@ -1404,7 +1443,7 @@ var PHASES4 = ["spec", "plan", "build", "test", "review", "ship"];
1404
1443
  var HOOK_NAMES = ["session-start", "hito-counter", "gate-check"];
1405
1444
  var ENV_VAR_RENAME = /CLAUDE_PROJECT_DIR/g;
1406
1445
  function runCodexTransform(params) {
1407
- const { harnessRoot, projectDir, withUzysHarness = false } = params;
1446
+ const { harnessRoot, projectDir, withUzysHarness = false, selectedInternalSkills = [] } = params;
1408
1447
  const claudeMd = readRequired(join5(harnessRoot, "templates/CLAUDE.md"));
1409
1448
  const agentsTemplate = readRequired(join5(harnessRoot, "templates/codex/AGENTS.md.template"));
1410
1449
  const configTemplate = readRequired(join5(harnessRoot, "templates/codex/config.toml.template"));
@@ -1458,6 +1497,17 @@ function runCodexTransform(params) {
1458
1497
  skillFiles.push(target);
1459
1498
  }
1460
1499
  }
1500
+ for (const id of selectedInternalSkills) {
1501
+ const src = join5(harnessRoot, "templates/skills", id, "SKILL.md");
1502
+ if (!existsSync6(src)) {
1503
+ continue;
1504
+ }
1505
+ const skillDir = join5(projectDir, ".agents", "skills", id);
1506
+ ensureDir(skillDir);
1507
+ const target = join5(skillDir, "SKILL.md");
1508
+ writeFileSync5(target, renderBundledSkill(readFileSync6(src, "utf8")));
1509
+ skillFiles.push(target);
1510
+ }
1461
1511
  const promptFiles = [];
1462
1512
  if (withUzysHarness) {
1463
1513
  const promptDir = join5(projectDir, ".codex", "prompts");
@@ -2083,6 +2133,14 @@ function buildManifest(spec) {
2083
2133
  type: "dir",
2084
2134
  applies: onTracks("ssr-nextjs|full")
2085
2135
  });
2136
+ for (const sd of DEV_METHOD_SKILL_IDS) {
2137
+ m.push({
2138
+ source: `skills/${sd}`,
2139
+ target: `.claude/skills/${sd}`,
2140
+ type: "dir",
2141
+ applies: (s) => (s.selectedInternalSkills ?? []).includes(sd)
2142
+ });
2143
+ }
2086
2144
  for (const sd of PYTHON_SKILL_DIRS_ECC) {
2087
2145
  m.push({
2088
2146
  source: `skills/${sd}`,
@@ -2257,6 +2315,55 @@ function renderCommand(params) {
2257
2315
  ""
2258
2316
  ].join("\n");
2259
2317
  }
2318
+ function renderCommandFromSkill(source, id) {
2319
+ const { description, body } = parseSkillFrontmatter(source);
2320
+ const finalDescription = description || `${id} (dev-method skill, OpenCode command fallback)`;
2321
+ const escapedDesc = finalDescription.replace(/"/g, '\\"');
2322
+ const renamedBody = renameSlashes2(body).trimEnd();
2323
+ return ["---", `description: "${escapedDesc}"`, "agent: plan", "---", "", renamedBody, ""].join(
2324
+ "\n"
2325
+ );
2326
+ }
2327
+ function parseSkillFrontmatter(source) {
2328
+ const lines = source.split(/\r?\n/);
2329
+ if (lines[0] !== "---") {
2330
+ const firstLine = lines[0] ?? "";
2331
+ return { description: firstLine.trim(), body: lines.slice(1).join("\n") };
2332
+ }
2333
+ let secondDelimAt = -1;
2334
+ let description = "";
2335
+ for (let i = 1; i < lines.length; i++) {
2336
+ const line = lines[i] ?? "";
2337
+ if (line === "---") {
2338
+ secondDelimAt = i;
2339
+ break;
2340
+ }
2341
+ const inline = line.match(/^description:\s*(.+)$/);
2342
+ if (!inline) {
2343
+ continue;
2344
+ }
2345
+ const raw = (inline[1] ?? "").trim();
2346
+ if (raw === ">-" || raw === ">" || raw === "|" || raw === "|-") {
2347
+ const collected = [];
2348
+ for (let j3 = i + 1; j3 < lines.length; j3++) {
2349
+ const next = lines[j3] ?? "";
2350
+ if (next === "---") {
2351
+ break;
2352
+ }
2353
+ if (next.trim() === "" || /^\s/.test(next)) {
2354
+ collected.push(next.trim());
2355
+ } else {
2356
+ break;
2357
+ }
2358
+ }
2359
+ description = collected.join(" ").replace(/\s+/g, " ").trim();
2360
+ } else {
2361
+ description = stripQuotes2(raw);
2362
+ }
2363
+ }
2364
+ const body = secondDelimAt >= 0 ? lines.slice(secondDelimAt + 1).join("\n").replace(/^\n+/, "") : source;
2365
+ return { description, body };
2366
+ }
2260
2367
  function parseSource3(source) {
2261
2368
  const lines = source.split(/\r?\n/);
2262
2369
  if (lines[0] === "---") {
@@ -2310,7 +2417,7 @@ function parseTemplate(template) {
2310
2417
  // src/opencode/transform.ts
2311
2418
  var PHASES5 = ["spec", "plan", "build", "test", "review", "ship"];
2312
2419
  function runOpencodeTransform(params) {
2313
- const { harnessRoot, projectDir } = params;
2420
+ const { harnessRoot, projectDir, selectedInternalSkills = [] } = params;
2314
2421
  const claudeMd = readRequired2(join9(harnessRoot, "templates/CLAUDE.md"));
2315
2422
  const agentsTemplate = readRequired2(join9(harnessRoot, "templates/opencode/AGENTS.md.template"));
2316
2423
  const opencodeTemplate = readRequired2(
@@ -2345,6 +2452,15 @@ function runOpencodeTransform(params) {
2345
2452
  writeFileSync9(target, renderCommand({ source, phase }));
2346
2453
  commandFiles.push(target);
2347
2454
  }
2455
+ for (const id of selectedInternalSkills) {
2456
+ const src = join9(harnessRoot, "templates/skills", id, "SKILL.md");
2457
+ if (!existsSync11(src)) {
2458
+ continue;
2459
+ }
2460
+ const target = join9(cmdDir, `${id}.md`);
2461
+ writeFileSync9(target, renderCommandFromSkill(readFileSync11(src, "utf8"), id));
2462
+ commandFiles.push(target);
2463
+ }
2348
2464
  const pluginDir = join9(projectDir, ".opencode/plugins");
2349
2465
  ensureDir(pluginDir);
2350
2466
  const pluginPath = join9(pluginDir, "uzys-harness.ts");
@@ -2681,7 +2797,13 @@ function runInstall(ctx) {
2681
2797
  backup: backupPath,
2682
2798
  installedTracks: [...spec.tracks].sort(),
2683
2799
  mcpServers: Object.keys(mcpResult.mcpServers).sort(),
2684
- ...runCliTransforms(spec, harnessRoot, projectDir, manifestSpec.withUzysHarness),
2800
+ ...runCliTransforms(
2801
+ spec,
2802
+ harnessRoot,
2803
+ projectDir,
2804
+ manifestSpec.withUzysHarness,
2805
+ manifestSpec.selectedInternalSkills
2806
+ ),
2685
2807
  updateMode: null,
2686
2808
  mode,
2687
2809
  envFiles: writeEnvironmentFiles(projectDir, spec.tracks),
@@ -2739,7 +2861,10 @@ function buildManifestSpec(spec) {
2739
2861
  withUzysHarness: isAssetSelected("uzys-harness", selectionCtx),
2740
2862
  // v26.55.0 — withEcc gating (ADR-016). ECC cherry-pick (agents/skills/commands) 항목 토글.
2741
2863
  // withPrune 은 ecc-plugin 사용을 전제 (이전 applyOptionRules `withEcc ||= withPrune` 의미 보존).
2742
- withEcc: isAssetSelected("ecc-plugin", selectionCtx) || spec.options.withPrune
2864
+ withEcc: isAssetSelected("ecc-plugin", selectionCtx) || spec.options.withPrune,
2865
+ // v26.87.0 — dev-method skills (internal). has-dev-track 기본 + wizard uncheck /
2866
+ // `--without <id>` (forceExclude) 반영 — manifest copy 가 이 목록만 게이팅.
2867
+ selectedInternalSkills: DEV_METHOD_SKILL_IDS.filter((id) => isAssetSelected(id, selectionCtx))
2743
2868
  };
2744
2869
  }
2745
2870
  function emptyClaudeBaseline() {
@@ -2804,14 +2929,15 @@ function writeEnvironmentFiles(projectDir, tracks) {
2804
2929
  gitignoreNpxSkillsAdded: addGitignoreNpxSkillsAgents(projectDir)
2805
2930
  };
2806
2931
  }
2807
- function runCliTransforms(spec, harnessRoot, projectDir, uzysHarnessSelected) {
2932
+ function runCliTransforms(spec, harnessRoot, projectDir, uzysHarnessSelected, selectedInternalSkills) {
2808
2933
  let codex = null;
2809
2934
  let codexOptIn = null;
2810
2935
  if (spec.cli.includes("codex")) {
2811
2936
  codex = runCodexTransform({
2812
2937
  harnessRoot,
2813
2938
  projectDir,
2814
- withUzysHarness: uzysHarnessSelected
2939
+ withUzysHarness: uzysHarnessSelected,
2940
+ selectedInternalSkills
2815
2941
  });
2816
2942
  const installScope = spec.scope ?? "project";
2817
2943
  if (installScope === "global" && (spec.options.withCodexSkills || spec.options.withCodexTrust || spec.options.withCodexPrompts)) {
@@ -2826,7 +2952,7 @@ function runCliTransforms(spec, harnessRoot, projectDir, uzysHarnessSelected) {
2826
2952
  }
2827
2953
  let opencode = null;
2828
2954
  if (spec.cli.includes("opencode")) {
2829
- opencode = runOpencodeTransform({ harnessRoot, projectDir });
2955
+ opencode = runOpencodeTransform({ harnessRoot, projectDir, selectedInternalSkills });
2830
2956
  }
2831
2957
  let antigravity = null;
2832
2958
  let antigravityOptIn = null;
@@ -2834,7 +2960,8 @@ function runCliTransforms(spec, harnessRoot, projectDir, uzysHarnessSelected) {
2834
2960
  antigravity = runAntigravityTransform({
2835
2961
  harnessRoot,
2836
2962
  projectDir,
2837
- withUzysHarness: uzysHarnessSelected
2963
+ withUzysHarness: uzysHarnessSelected,
2964
+ selectedInternalSkills
2838
2965
  });
2839
2966
  const installScope = spec.scope ?? "project";
2840
2967
  if (installScope === "global" && spec.options.withAntigravityGlobal) {