handyman-harness 3.0.0 → 3.1.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.
@@ -31,10 +31,10 @@ request before you start.
31
31
  # - The green gate (./init.sh | bash tests/run_tests.sh) is ALWAYS the last Acceptance bullet.
32
32
  # - Choose an archetype: [Research] leaves a plan in docs/ ; [Implementation] changes code + tests.
33
33
  # - Fill the CORE always; delete the OPTIONAL sections that do not apply (no placeholders).
34
- # - Only name, title, description, and acceptance become the feature_list.json entry (via node dist/feature.js add);
34
+ # - Only name, title, description, and acceptance become the feature_list.json entry (via npx handyman-harness@3 feature add);
35
35
  # Verification, Considerations, Tools, and Post-feature are guidance for the leader and the human.
36
36
  # - Tools: skills come from discovery.skills and agents from discovery.agents (harness.config.json);
37
- # verify both are installed with node dist/tools_discovery.js check. See references/discovery.md.
37
+ # verify both are installed with npx handyman-harness@3 tools_discovery check. See references/discovery.md.
38
38
 
39
39
  ## ───── CORE (fill always) ─────
40
40
 
@@ -58,7 +58,7 @@ request before you start.
58
58
 
59
59
  ## Tools
60
60
  - skills: <handyman, ...>
61
- - agents (optional): <implementer, reviewer, explorer> # from discovery.agents; verify with node dist/tools_discovery.js check
61
+ - agents (optional): <implementer, reviewer, explorer> # from discovery.agents; verify with npx handyman-harness@3 tools_discovery check
62
62
 
63
63
  ## ───── OPTIONAL (fill only if it applies; otherwise delete the section) ─────
64
64
 
@@ -69,7 +69,7 @@ request before you start.
69
69
  ## Verification (extension)
70
70
  - Functional check: <which request/action and the expected result>
71
71
  - Description trigger (skill-authoring only): if this change edits the skill's `description`,
72
- re-measure the trigger with `node dist/evals.js measure` and refresh `evals/.last-measured`
72
+ re-measure the trigger with `npx handyman-harness@3 evals measure` and refresh `evals/.last-measured`
73
73
  (the size cap alone does not prove it still triggers — see references/evals.md).
74
74
 
75
75
  ## Considerations
@@ -101,7 +101,7 @@ Two requests grounded in this repo's own history — one per archetype.
101
101
 
102
102
  ## Context
103
103
  Several harness mutations (backlog entries, current.md, history.md) are done by hand
104
- with no deterministic script, unlike feature_list.json (covered by node dist/feature.js). Map
104
+ with no deterministic script, unlike feature_list.json (covered by npx handyman-harness@3 feature). Map
105
105
  the gap before building anything.
106
106
 
107
107
  ## Scope
@@ -130,22 +130,22 @@ the gap before building anything.
130
130
 
131
131
  ## Context
132
132
  backlog/ entries (impl_/review_/explore_) are written by hand with per-type
133
- frontmatter; there is no generator, unlike node dist/feature.js for state. Implements Plan A of
133
+ frontmatter; there is no generator, unlike npx handyman-harness@3 feature for state. Implements Plan A of
134
134
  docs/analisis-acciones-deterministas-por-capa.md.
135
135
 
136
136
  ## Scope
137
137
  - Includes: src/backlog.ts, assets/backlog-*.template.md, references (anatomy/templates/workflow), tests/test_backlog.sh
138
138
 
139
139
  ## Acceptance criteria (observable and testable)
140
- - node dist/backlog.js impl <feature> creates impl_<feature>.md with implementer frontmatter
141
- - node dist/backlog.js review <feature> [--status approved|changes_requested] creates a coherent review_<feature>.md
140
+ - npx handyman-harness@3 backlog impl <feature> creates impl_<feature>.md with implementer frontmatter
141
+ - npx handyman-harness@3 backlog review <feature> [--status approved|changes_requested] creates a coherent review_<feature>.md
142
142
  - it never overwrites an existing entry (idempotent)
143
143
  - tests/test_backlog.sh covers each subcommand and is wired into run_tests.sh
144
144
  - bash tests/run_tests.sh passes
145
145
 
146
146
  ## Verification
147
147
  - Gate that must stay green: ./init.sh
148
- - Functional check: run node dist/backlog.js impl demo_feature and see the file with correct frontmatter
148
+ - Functional check: run npx handyman-harness@3 backlog impl demo_feature and see the file with correct frontmatter
149
149
 
150
150
  ## Considerations
151
151
  - ponytail: the smallest change that satisfies the Acceptance
@@ -183,7 +183,7 @@ run_test() {
183
183
  # --- Advisory checks (non-blocking) -----------------------------------------
184
184
  # A harness with no version stamp predates harness versioning; flag it so the
185
185
  # user can seal and update it. A sealed harness stays silent here - explicit
186
- # drift detection is node dist/upgrade_harness.js --check. Never changes EXIT_CODE.
186
+ # drift detection is npx handyman-harness@3 upgrade_harness --check. Never changes EXIT_CODE.
187
187
  check_harness_version() {
188
188
  ver=""
189
189
  if [ -f "$PROJECT_ROOT/harness.config.json" ]; then
@@ -194,7 +194,7 @@ check_harness_version() {
194
194
  fi
195
195
  if [ -z "$ver" ]; then
196
196
  echo "NOTE: harness has no version stamp - created before harness versioning." >&2
197
- echo " run node dist/upgrade_harness.js --check (or re-scaffold) to seal and update it." >&2
197
+ echo " run npx handyman-harness@3 upgrade_harness --check (or re-scaffold) to seal and update it." >&2
198
198
  fi
199
199
  }
200
200
 
@@ -259,14 +259,14 @@ check_evals() {
259
259
  count="$(_json "$eval_set" len 2>/dev/null)"
260
260
  if [ "${count:-0}" -eq 0 ]; then
261
261
  echo "NOTE: evals/trigger-eval.json has no labeled queries - the description trigger is unmeasured." >&2
262
- echo " add positive and negative queries, then run node dist/evals.js measure (see references/evals.md)." >&2
262
+ echo " add positive and negative queries, then run npx handyman-harness@3 evals measure (see references/evals.md)." >&2
263
263
  return 0
264
264
  fi
265
265
  marker="$PROJECT_ROOT/evals/.last-measured"
266
266
  desc="$PROJECT_ROOT/SKILL.md"
267
267
  if [ -f "$desc" ] && { [ ! -f "$marker" ] || [ "$desc" -nt "$marker" ]; }; then
268
268
  echo "NOTE: SKILL.md changed since the last trigger measurement (or it was never measured)." >&2
269
- echo " re-run node dist/evals.js measure and refresh evals/.last-measured (see references/evals.md)." >&2
269
+ echo " re-run npx handyman-harness@3 evals measure and refresh evals/.last-measured (see references/evals.md)." >&2
270
270
  fi
271
271
  }
272
272
 
@@ -11,7 +11,7 @@ tags: [handyman/sprint]
11
11
 
12
12
  > Closed work period. Every section except the two marked manual is derived at
13
13
  > close time from `feature_list.json`, `progress/history.md`, and `backlog/`
14
- > frontmatter by `node dist/sprint.js close`; regenerate rather than hand-edit.
14
+ > frontmatter by `npx handyman-harness@3 sprint close`; regenerate rather than hand-edit.
15
15
 
16
16
  ## Identity
17
17
 
package/dist/cli.js CHANGED
@@ -25,6 +25,7 @@ verbs:
25
25
  ${list}
26
26
 
27
27
  Each verb accepts --help for its own options.
28
+ handyman --version prints the toolchain version.
28
29
  `;
29
30
  }
30
31
  var [verb, ...rest] = process.argv.slice(2);
@@ -32,6 +33,15 @@ if (!verb || verb === "--help" || verb === "-h") {
32
33
  process.stdout.write(usage());
33
34
  process.exit(verb ? 0 : 2);
34
35
  }
36
+ if (verb === "--version" || verb === "-v") {
37
+ const { readFileSync } = await import("node:fs");
38
+ const pkg = JSON.parse(
39
+ readFileSync(new URL("../package.json", import.meta.url), "utf8")
40
+ );
41
+ process.stdout.write(`${pkg.version}
42
+ `);
43
+ process.exit(0);
44
+ }
35
45
  if (!VERBS.includes(verb)) {
36
46
  process.stderr.write(`error: unknown verb '${verb}'
37
47
 
package/dist/toolbox.js CHANGED
@@ -8038,6 +8038,7 @@ import { basename as basename2, dirname, join as join8, resolve as resolve6 } fr
8038
8038
  import { fileURLToPath as fileURLToPath2 } from "node:url";
8039
8039
  var ASSETS = fileURLToPath2(new URL("../assets", import.meta.url));
8040
8040
  var SKILL_MD = fileURLToPath2(new URL("../SKILL.md", import.meta.url));
8041
+ var PKG_JSON = fileURLToPath2(new URL("../package.json", import.meta.url));
8041
8042
  var MIGRATIONS = [
8042
8043
  {
8043
8044
  version: "1.6.0",
@@ -8149,14 +8150,19 @@ function truthyString(value) {
8149
8150
  return null;
8150
8151
  }
8151
8152
  function currentSkillVersion() {
8152
- let text;
8153
8153
  try {
8154
- text = readTextUniversal(SKILL_MD);
8154
+ const match = /^\s+version:\s*(.+)$/m.exec(readTextUniversal(SKILL_MD));
8155
+ if (match) {
8156
+ return match[1].trim();
8157
+ }
8158
+ } catch {
8159
+ }
8160
+ try {
8161
+ const version = JSON.parse(readTextUniversal(PKG_JSON)).version;
8162
+ return typeof version === "string" ? version : "";
8155
8163
  } catch {
8156
8164
  return "";
8157
8165
  }
8158
- const match = /^\s+version:\s*(.+)$/m.exec(text);
8159
- return match ? match[1].trim() : "";
8160
8166
  }
8161
8167
  function readInstalledVersion(root, workspace) {
8162
8168
  const configPath = join8(root, "harness.config.json");
@@ -8190,6 +8190,7 @@ import { basename as basename2, dirname as dirname2, join as join10, resolve as
8190
8190
  import { fileURLToPath as fileURLToPath2 } from "node:url";
8191
8191
  var ASSETS = fileURLToPath2(new URL("../assets", import.meta.url));
8192
8192
  var SKILL_MD = fileURLToPath2(new URL("../SKILL.md", import.meta.url));
8193
+ var PKG_JSON = fileURLToPath2(new URL("../package.json", import.meta.url));
8193
8194
  var MIGRATIONS = [
8194
8195
  {
8195
8196
  version: "1.6.0",
@@ -8301,14 +8302,19 @@ function truthyString(value) {
8301
8302
  return null;
8302
8303
  }
8303
8304
  function currentSkillVersion() {
8304
- let text;
8305
8305
  try {
8306
- text = readTextUniversal(SKILL_MD);
8306
+ const match = /^\s+version:\s*(.+)$/m.exec(readTextUniversal(SKILL_MD));
8307
+ if (match) {
8308
+ return match[1].trim();
8309
+ }
8310
+ } catch {
8311
+ }
8312
+ try {
8313
+ const version = JSON.parse(readTextUniversal(PKG_JSON)).version;
8314
+ return typeof version === "string" ? version : "";
8307
8315
  } catch {
8308
8316
  return "";
8309
8317
  }
8310
- const match = /^\s+version:\s*(.+)$/m.exec(text);
8311
- return match ? match[1].trim() : "";
8312
8318
  }
8313
8319
  function readInstalledVersion(root, workspace) {
8314
8320
  const configPath = join10(root, "harness.config.json");
@@ -6910,6 +6910,7 @@ function resolveWorkspace(root) {
6910
6910
  // src/upgrade_harness.ts
6911
6911
  var ASSETS = fileURLToPath2(new URL("../assets", import.meta.url));
6912
6912
  var SKILL_MD = fileURLToPath2(new URL("../SKILL.md", import.meta.url));
6913
+ var PKG_JSON = fileURLToPath2(new URL("../package.json", import.meta.url));
6913
6914
  var MIGRATIONS = [
6914
6915
  {
6915
6916
  version: "1.6.0",
@@ -7021,14 +7022,19 @@ function truthyString(value) {
7021
7022
  return null;
7022
7023
  }
7023
7024
  function currentSkillVersion() {
7024
- let text;
7025
7025
  try {
7026
- text = readTextUniversal(SKILL_MD);
7026
+ const match = /^\s+version:\s*(.+)$/m.exec(readTextUniversal(SKILL_MD));
7027
+ if (match) {
7028
+ return match[1].trim();
7029
+ }
7030
+ } catch {
7031
+ }
7032
+ try {
7033
+ const version = JSON.parse(readTextUniversal(PKG_JSON)).version;
7034
+ return typeof version === "string" ? version : "";
7027
7035
  } catch {
7028
7036
  return "";
7029
7037
  }
7030
- const match = /^\s+version:\s*(.+)$/m.exec(text);
7031
- return match ? match[1].trim() : "";
7032
7038
  }
7033
7039
  function readInstalledVersion(root, workspace) {
7034
7040
  const configPath = join2(root, "harness.config.json");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "handyman-harness",
3
- "version": "3.0.0",
3
+ "version": "3.1.0",
4
4
  "description": "Handyman agent-harness toolchain (TypeScript/Node).",
5
5
  "author": "Rodrigo Mardones",
6
6
  "license": "MIT",