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.
- package/assets/feature-request.template.md +9 -9
- package/assets/init.template.sh +4 -4
- package/assets/sprint.template.md +1 -1
- package/dist/cli.js +10 -0
- package/dist/toolbox.js +10 -4
- package/dist/toolbox_state.js +10 -4
- package/dist/upgrade_harness.js +10 -4
- package/package.json +1 -1
|
@@ -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
|
|
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
|
|
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
|
|
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 `
|
|
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
|
|
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
|
|
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
|
-
-
|
|
141
|
-
-
|
|
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
|
|
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
|
package/assets/init.template.sh
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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 `
|
|
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
|
-
|
|
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");
|
package/dist/toolbox_state.js
CHANGED
|
@@ -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
|
-
|
|
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");
|
package/dist/upgrade_harness.js
CHANGED
|
@@ -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
|
-
|
|
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");
|