@marcomigozzi/trailhead 0.16.1 → 0.18.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/README.it.md +82 -25
- package/README.md +82 -25
- package/bin/base-preflight-docs.test.js +4 -1
- package/bin/bulk-cross-reference-docs.test.js +36 -0
- package/bin/capture-action.test.js +167 -0
- package/bin/capture-docs.test.js +32 -0
- package/bin/engine-route-docs.test.js +155 -0
- package/bin/facet-stamp-docs.test.js +79 -0
- package/bin/forced-mutation-docs.test.js +38 -0
- package/bin/grill-model-docs.test.js +155 -0
- package/bin/grilling-holistic-review-docs.test.js +7 -3
- package/bin/guard-axis-docs.test.js +69 -0
- package/bin/inbox-needs-info-docs.test.js +68 -0
- package/bin/lib/codex-projection.js +28 -19
- package/bin/lib/codex-projection.test.js +77 -20
- package/bin/lib/host-descriptor.js +1 -1
- package/bin/lib/host-descriptor.test.js +6 -0
- package/bin/needs-you-docs.test.js +9 -2
- package/bin/options-in-chat-docs.test.js +65 -0
- package/bin/pick-stress-test-docs.test.js +1 -1
- package/bin/pipeline-review-docs.test.js +118 -0
- package/bin/plan-review-budget-docs.test.js +63 -0
- package/bin/repo-target-docs.test.js +41 -0
- package/bin/report-status-docs.test.js +10 -2
- package/bin/seam-coverage-docs.test.js +46 -0
- package/bin/session-trust-docs.test.js +37 -0
- package/bin/standards-brief-docs.test.js +112 -0
- package/bin/surfaced-scope-docs.test.js +57 -0
- package/bin/test-once-docs.test.js +101 -0
- package/bin/test-run-docs.test.js +47 -0
- package/bin/trailhead.js +15 -8
- package/bin/trailhead.test.js +71 -17
- package/bin/unblock-docs.test.js +56 -0
- package/bin/yes-accepts-recommended-docs.test.js +54 -0
- package/package.json +1 -1
- package/plugins/trailhead/.claude-plugin/plugin.json +1 -1
- package/plugins/trailhead/agents/trailhead-code-review.md +2 -1
- package/plugins/trailhead/agents/trailhead-codebase-map.md +1 -1
- package/plugins/trailhead/agents/trailhead-grill.md +41 -0
- package/plugins/trailhead/agents/trailhead-plan.md +1 -1
- package/plugins/trailhead/agents/trailhead-verify.md +1 -0
- package/plugins/trailhead/hooks/lib/audit-walk.test.js +62 -0
- package/plugins/trailhead/hooks/lib/capture.test.js +439 -0
- package/plugins/trailhead/hooks/lib/checkout-find.test.js +195 -0
- package/plugins/trailhead/hooks/lib/checkout-in.test.js +83 -7
- package/plugins/trailhead/hooks/lib/dashboard.test.js +19 -0
- package/plugins/trailhead/hooks/lib/gh-auth-preflight.js +89 -0
- package/plugins/trailhead/hooks/lib/gh-auth-preflight.test.js +132 -0
- package/plugins/trailhead/hooks/lib/git-env-mod.test.js +55 -0
- package/plugins/trailhead/hooks/lib/git-env-spawn.test.js +73 -0
- package/plugins/trailhead/hooks/lib/git-env.test.js +51 -0
- package/plugins/trailhead/hooks/lib/global-config-dir.test.js +48 -0
- package/plugins/trailhead/hooks/lib/heredoc-mod.test.js +85 -0
- package/plugins/trailhead/hooks/lib/inbox-needs-info.test.js +179 -0
- package/plugins/trailhead/hooks/lib/inherit-session.js +17 -0
- package/plugins/trailhead/hooks/lib/issue-body.test.js +165 -0
- package/plugins/trailhead/hooks/lib/model-defaults-review.js +22 -1
- package/plugins/trailhead/hooks/lib/model-defaults-review.test.js +64 -1
- package/plugins/trailhead/hooks/lib/model-route.js +207 -0
- package/plugins/trailhead/hooks/lib/model-route.test.js +231 -0
- package/plugins/trailhead/hooks/lib/needs-you.test.js +45 -1
- package/plugins/trailhead/hooks/lib/plan-review-rounds.test.js +272 -0
- package/plugins/trailhead/hooks/lib/repo-target.test.js +256 -0
- package/plugins/trailhead/hooks/lib/report-status.test.js +56 -1
- package/plugins/trailhead/hooks/lib/statusline-git-env.test.js +47 -0
- package/plugins/trailhead/hooks/lib/test-run.test.js +757 -0
- package/plugins/trailhead/hooks/lib/trailhead-git-env.js +40 -0
- package/plugins/trailhead/hooks/mod/README.md +42 -17
- package/plugins/trailhead/hooks/mod/auto-run.ts +2 -1
- package/plugins/trailhead/hooks/mod/git-env.ts +31 -0
- package/plugins/trailhead/hooks/mod/heredoc.ts +79 -0
- package/plugins/trailhead/hooks/mod/map-pane-view.ts +3 -1
- package/plugins/trailhead/hooks/mod/map-pane.tsx +204 -49
- package/plugins/trailhead/hooks/mod/my-tickets.ts +76 -0
- package/plugins/trailhead/hooks/mod/repo-pin.ts +113 -9
- package/plugins/trailhead/hooks/mod/work-state-locate.ts +2 -1
- package/plugins/trailhead/hooks/trailhead-bash-guards.js +8 -8
- package/plugins/trailhead/hooks/trailhead-bash-guards.test.js +28 -14
- package/plugins/trailhead/hooks/trailhead-check-update.js +20 -2
- package/plugins/trailhead/hooks/trailhead-check-update.test.js +60 -0
- package/plugins/trailhead/hooks/trailhead-labels-guard.js +2 -2
- package/plugins/trailhead/hooks/trailhead-labels-guard.test.js +1 -1
- package/plugins/trailhead/hooks/trailhead-test-guard.js +232 -0
- package/plugins/trailhead/hooks/trailhead-test-guard.test.js +172 -0
- package/plugins/trailhead/skills/_shared/capture-core.md +123 -0
- package/plugins/trailhead/skills/_shared/choices.md +2 -2
- package/plugins/trailhead/skills/_shared/configuration-reference.md +30 -16
- package/plugins/trailhead/skills/_shared/configuration.md +1 -1
- package/plugins/trailhead/skills/_shared/load-first.md +2 -0
- package/plugins/trailhead/skills/_shared/session-handoff.md +1 -1
- package/plugins/trailhead/skills/_shared/substrate-commands.md +19 -6
- package/plugins/trailhead/skills/_shared/substrate.md +4 -3
- package/plugins/trailhead/skills/_shared/surfaced-scope.md +23 -0
- package/plugins/trailhead/skills/_shared/teamwork.md +11 -5
- package/plugins/trailhead/skills/_shared/techniques/acceptance-testing.md +1 -1
- package/plugins/trailhead/skills/_shared/techniques/code-review-pipeline.md +24 -0
- package/plugins/trailhead/skills/_shared/techniques/code-review.md +22 -6
- package/plugins/trailhead/skills/_shared/techniques/codebase-map.md +6 -3
- package/plugins/trailhead/skills/_shared/techniques/debug.md +5 -2
- package/plugins/trailhead/skills/_shared/techniques/grilling.md +28 -3
- package/plugins/trailhead/skills/_shared/techniques/plan-review.md +16 -4
- package/plugins/trailhead/skills/_shared/techniques/research.md +4 -1
- package/plugins/trailhead/skills/_shared/techniques/tdd.md +4 -2
- package/plugins/trailhead/skills/_shared/techniques/verify.md +5 -1
- package/plugins/trailhead/skills/_shared/techniques.md +8 -6
- package/plugins/trailhead/skills/trailhead-capture/SKILL.md +2 -4
- package/plugins/trailhead/skills/trailhead-capture/references/capture.md +29 -4
- package/plugins/trailhead/skills/trailhead-chart/SKILL.md +2 -2
- package/plugins/trailhead/skills/trailhead-chart/references/charting.md +5 -5
- package/plugins/trailhead/skills/trailhead-chart/references/inbox.md +11 -6
- package/plugins/trailhead/skills/trailhead-manage/references/auditing.md +18 -3
- package/plugins/trailhead/skills/trailhead-work/SKILL.md +12 -9
- package/plugins/trailhead/skills/trailhead-work/references/auto.md +3 -1
- package/plugins/trailhead/skills/trailhead-work/references/executor-brief.md +2 -0
- package/plugins/trailhead/skills/trailhead-work/references/ticket-engines.md +13 -13
- package/plugins/trailhead/templates/statusline-trailhead.sh +10 -3
- package/plugins/trailhead/templates/trailhead-audit-walk.js +56 -4
- package/plugins/trailhead/templates/trailhead-auto-merge.js +2 -1
- package/plugins/trailhead/templates/trailhead-auto-queue.js +2 -1
- package/plugins/trailhead/templates/trailhead-auto-slot.js +2 -1
- package/plugins/trailhead/templates/trailhead-base-preflight.js +10 -5
- package/plugins/trailhead/templates/trailhead-capture.js +419 -0
- package/plugins/trailhead/templates/trailhead-checkout-find.js +257 -0
- package/plugins/trailhead/templates/trailhead-checkout-in.js +78 -21
- package/plugins/trailhead/templates/trailhead-commit-msg-sync.js +2 -1
- package/plugins/trailhead/templates/trailhead-dashboard.js +15 -2
- package/plugins/trailhead/templates/trailhead-git-env.js +40 -0
- package/plugins/trailhead/templates/trailhead-inbox-needs-info.js +161 -0
- package/plugins/trailhead/templates/trailhead-isolation-answer.js +2 -1
- package/plugins/trailhead/templates/trailhead-isolation-copy.js +9 -4
- package/plugins/trailhead/templates/trailhead-issue-body.js +161 -12
- package/plugins/trailhead/templates/trailhead-merge-ticket.js +2 -1
- package/plugins/trailhead/templates/trailhead-needs-you.js +38 -4
- package/plugins/trailhead/templates/trailhead-plan-review-rounds.js +261 -7
- package/plugins/trailhead/templates/trailhead-repo-target.js +302 -0
- package/plugins/trailhead/templates/trailhead-report-status.js +57 -9
- package/plugins/trailhead/templates/trailhead-test-run.js +752 -0
- package/plugins/trailhead/templates/trailhead-uat-backfill.js +2 -1
- package/plugins/trailhead/templates/trailhead-uat-followup.js +2 -1
- package/plugins/trailhead/templates/trailhead-uat-setup.js +9 -4
- package/plugins/trailhead/templates/trailhead-unblock.js +2 -1
- package/plugins/trailhead/tests/auto-run-ui.test.ts +2 -1
- package/plugins/trailhead/tests/git-env.test.ts +20 -0
- package/plugins/trailhead/tests/map-pane-ui.test.ts +386 -50
- package/plugins/trailhead/tests/map-pane-view.test.ts +6 -0
- package/plugins/trailhead/tests/map-pane-write.test.ts +57 -1
- package/plugins/trailhead/tests/my-tickets.test.ts +66 -0
- package/plugins/trailhead/tests/repo-pin-late-repo.test.ts +3 -2
- package/plugins/trailhead/tests/repo-pin-relocate.test.ts +175 -0
- package/plugins/trailhead/tests/repo-pin.test.ts +20 -5
- package/plugins/trailhead/tests/unscrub.ts +8 -0
- package/plugins/trailhead/tests/work-state-prompt-hook.test.ts +3 -2
- package/plugins/trailhead/tests/work-state-worktree.test.ts +2 -1
- package/plugins/trailhead/types/index.d.ts +7 -0
|
@@ -3,20 +3,21 @@
|
|
|
3
3
|
// trailhead report status check (self-contained, ships in templates/ so it reaches
|
|
4
4
|
// every install channel). Checks the leading `status:` line of an engine-agent
|
|
5
5
|
// report (Code review, Goal-backward verification #250; executor, fix, plan, debug,
|
|
6
|
-
// research, codebase-map #249) before the engine branches on it, and returns the
|
|
6
|
+
// research, codebase-map #249; grill #323) before the engine branches on it, and returns the
|
|
7
7
|
// report's fields.
|
|
8
8
|
//
|
|
9
9
|
// CLI:
|
|
10
|
-
// node trailhead-report-status.js --technique <technique> [--file <path>]
|
|
10
|
+
// node trailhead-report-status.js --technique <technique> [--file <path> | --task-output <path>]
|
|
11
11
|
// <technique> is verify | code-review | executor | fix | plan | debug | research |
|
|
12
|
-
// codebase-map. Reads the report from --file,
|
|
12
|
+
// codebase-map | grill. Reads the report from --file, from the last assistant message
|
|
13
|
+
// of a background agent's task .output with --task-output, or from stdin when neither.
|
|
13
14
|
// Prints exactly one JSON line {"action","verdict","problem","report","fields","body"}:
|
|
14
15
|
// action accept | normalise | reask
|
|
15
16
|
// verdict the canonical token, or null on reask
|
|
16
17
|
// problem null | missing | unknown-token | conflicting | counts | fields (null iff not reask)
|
|
17
18
|
// report the original text on accept and reask; the normalised text on normalise
|
|
18
19
|
// fields label -> trimmed value for the report's fields (executor, fix, plan, debug,
|
|
19
|
-
// research, codebase-map); {} for verify and code-review; null on reask
|
|
20
|
+
// research, codebase-map, grill); {} for verify and code-review; null on reask
|
|
20
21
|
// body plan with `ready` only: the normalised report without its status line, the
|
|
21
22
|
// PLAN to post verbatim; null otherwise
|
|
22
23
|
// Exit 0 for all three actions; exit 2 on a usage error (missing or unknown
|
|
@@ -89,6 +90,19 @@ const CONTRACTS = Object.freeze({
|
|
|
89
90
|
Object.freeze({ when: frozen(['needs_input']), field: 'questions', rule: 'non-empty' }),
|
|
90
91
|
]),
|
|
91
92
|
}),
|
|
93
|
+
grilling: Object.freeze({
|
|
94
|
+
tokens: frozen(['question', 'review']),
|
|
95
|
+
required: frozen(['settled', 'frontier', 'amendments', 'conflicts']),
|
|
96
|
+
optional: frozen(['question', 'recommended', 'areas', 'facts']),
|
|
97
|
+
invariants: Object.freeze([
|
|
98
|
+
Object.freeze({ when: frozen(['question']), field: 'question', rule: 'non-empty' }),
|
|
99
|
+
Object.freeze({ when: frozen(['question']), field: 'recommended', rule: 'non-empty' }),
|
|
100
|
+
Object.freeze({ when: frozen(['question']), field: 'amendments', rule: 'none' }),
|
|
101
|
+
Object.freeze({ when: frozen(['question']), field: 'conflicts', rule: 'none' }),
|
|
102
|
+
Object.freeze({ when: frozen(['review']), field: 'frontier', rule: 'none' }),
|
|
103
|
+
Object.freeze({ when: frozen(['review']), field: 'question', rule: 'none' }),
|
|
104
|
+
]),
|
|
105
|
+
}),
|
|
92
106
|
});
|
|
93
107
|
|
|
94
108
|
// Technique -> field family.
|
|
@@ -99,6 +113,7 @@ const FAMILY_OF = Object.freeze({
|
|
|
99
113
|
research: 'investigating',
|
|
100
114
|
'codebase-map': 'investigating',
|
|
101
115
|
plan: 'plan',
|
|
116
|
+
grill: 'grilling',
|
|
102
117
|
});
|
|
103
118
|
|
|
104
119
|
// Technique -> its closed set of status tokens.
|
|
@@ -296,14 +311,38 @@ function checkReport(text, technique) {
|
|
|
296
311
|
return { action: 'normalise', verdict, problem: null, report: [...head, ...rest].join('\n'), fields, body };
|
|
297
312
|
}
|
|
298
313
|
|
|
314
|
+
// The report of a background agent, read from the host's task .output (JSONL, often a
|
|
315
|
+
// symlink to the subagent transcript): the text of the last assistant message that has
|
|
316
|
+
// any, its blocks joined in order. One message can span several lines sharing
|
|
317
|
+
// message.id; lines that are not JSON are skipped. null when there is no assistant text.
|
|
318
|
+
function reportFromTaskOutput(raw) {
|
|
319
|
+
const entries = raw.split('\n').flatMap((l) => {
|
|
320
|
+
if (!l.trim()) return [];
|
|
321
|
+
try { return [JSON.parse(l)]; } catch (_) { return []; }
|
|
322
|
+
});
|
|
323
|
+
const texts = (e) => {
|
|
324
|
+
const c = e && e.message && e.message.content;
|
|
325
|
+
if (typeof c === 'string') return [c];
|
|
326
|
+
return Array.isArray(c) ? c.filter((b) => b && b.type === 'text' && typeof b.text === 'string').map((b) => b.text) : [];
|
|
327
|
+
};
|
|
328
|
+
const assistant = entries.filter((e) => e && e.type === 'assistant' && e.message);
|
|
329
|
+
const last = [...assistant].reverse().find((e) => texts(e).length > 0);
|
|
330
|
+
if (!last) return null;
|
|
331
|
+
const id = last.message.id;
|
|
332
|
+
const parts = id === undefined ? texts(last) : assistant.filter((e) => e.message.id === id).flatMap(texts);
|
|
333
|
+
return parts.join('');
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
const VALUE_FLAGS = { '--technique': 'technique', '--file': 'file', '--task-output': 'taskOutput' };
|
|
337
|
+
|
|
299
338
|
function parseArgs(argv) {
|
|
300
|
-
const opts = { technique: null, file: null };
|
|
339
|
+
const opts = { technique: null, file: null, taskOutput: null };
|
|
301
340
|
for (let i = 0; i < argv.length; i++) {
|
|
302
341
|
const a = argv[i];
|
|
303
|
-
if (
|
|
342
|
+
if (Object.prototype.hasOwnProperty.call(VALUE_FLAGS, a)) {
|
|
304
343
|
const v = argv[i + 1];
|
|
305
344
|
if (v === undefined || v === '' || v.startsWith('--')) throw new Error(`${a} needs a value`);
|
|
306
|
-
opts[a
|
|
345
|
+
opts[VALUE_FLAGS[a]] = v;
|
|
307
346
|
i++;
|
|
308
347
|
} else {
|
|
309
348
|
throw new Error(`unknown argument: ${a}`);
|
|
@@ -311,9 +350,18 @@ function parseArgs(argv) {
|
|
|
311
350
|
}
|
|
312
351
|
if (!opts.technique) throw new Error(`--technique <${Object.keys(TOKENS).join('|')}> is required`);
|
|
313
352
|
if (!Object.prototype.hasOwnProperty.call(TOKENS, opts.technique)) throw new Error(`unknown technique: ${opts.technique}`);
|
|
353
|
+
if (opts.file !== null && opts.taskOutput !== null) throw new Error('--file and --task-output are mutually exclusive');
|
|
314
354
|
return opts;
|
|
315
355
|
}
|
|
316
356
|
|
|
357
|
+
function readReport(opts, readFile, readStdin) {
|
|
358
|
+
if (opts.file !== null) return readFile(opts.file);
|
|
359
|
+
if (opts.taskOutput === null) return readStdin();
|
|
360
|
+
const report = reportFromTaskOutput(readFile(opts.taskOutput));
|
|
361
|
+
if (report === null) throw new Error(`no assistant report in ${opts.taskOutput}`);
|
|
362
|
+
return report;
|
|
363
|
+
}
|
|
364
|
+
|
|
317
365
|
function main(argv, io = {}) {
|
|
318
366
|
const stdout = io.stdout || process.stdout;
|
|
319
367
|
const stderr = io.stderr || process.stderr;
|
|
@@ -322,7 +370,7 @@ function main(argv, io = {}) {
|
|
|
322
370
|
let result;
|
|
323
371
|
try {
|
|
324
372
|
const opts = parseArgs(argv);
|
|
325
|
-
const text = opts
|
|
373
|
+
const text = readReport(opts, readFile, readStdin);
|
|
326
374
|
result = checkReport(text, opts.technique);
|
|
327
375
|
} catch (e) {
|
|
328
376
|
stderr.write(`${JSON.stringify({ error: e.message })}\n`);
|
|
@@ -335,4 +383,4 @@ function main(argv, io = {}) {
|
|
|
335
383
|
// exitCode, not process.exit(): exiting at once truncates piped stdout at 64 KB.
|
|
336
384
|
if (require.main === module) process.exitCode = main(process.argv.slice(2));
|
|
337
385
|
|
|
338
|
-
module.exports = { checkReport, parseArgs, main, TOKENS, CONTRACTS, FAMILY_OF, VERIFY_CLASSES };
|
|
386
|
+
module.exports = { checkReport, reportFromTaskOutput, parseArgs, main, TOKENS, CONTRACTS, FAMILY_OF, VERIFY_CLASSES };
|