@skyf0xx/hedgehog 6.2.4 → 6.2.6
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 +12 -0
- package/README.zh-CN.md +12 -0
- package/bin/cli.mjs +24 -6
- package/package.json +1 -1
- package/src/agents/planner.md +14 -0
- package/src/db/plan.mjs +5 -5
- package/src/db/worktree.mjs +27 -0
- package/src/hosts/capabilities.mjs +1 -0
- package/src/hosts/gemini/gemini-extension.json +1 -1
- package/src/registry/cores.json +9 -0
- package/src/registry/index.mjs +6 -5
- package/src/skills/hedgehog-planning-intake/SKILL.md +7 -4
package/README.md
CHANGED
|
@@ -192,6 +192,18 @@ Bundle
|
|
|
192
192
|
Join
|
|
193
193
|
```
|
|
194
194
|
|
|
195
|
+
### Copywriting
|
|
196
|
+
|
|
197
|
+
Copy is drafted and revised against a mechanical gate instead of prompting alone:
|
|
198
|
+
|
|
199
|
+
``` text
|
|
200
|
+
Brief
|
|
201
|
+
↓
|
|
202
|
+
Draft ⇄ zod validation()
|
|
203
|
+
↓ pass
|
|
204
|
+
Ship
|
|
205
|
+
```
|
|
206
|
+
|
|
195
207
|
### Anything else
|
|
196
208
|
|
|
197
209
|
A CLI, a library, a browser extension, a data pipeline, etc. gets its build order.
|
package/README.zh-CN.md
CHANGED
package/bin/cli.mjs
CHANGED
|
@@ -21,7 +21,7 @@ import { spawn, execFileSync } from 'node:child_process';
|
|
|
21
21
|
import { dbInit, DB_PATH, dbAbsPath, openDb, openDbAt } from '../src/db/init.mjs';
|
|
22
22
|
import { loadCore, lintCore, isModuleAxis } from '../src/db/core.mjs';
|
|
23
23
|
import { planTasks, CORE_INTENT_ID } from '../src/db/plan.mjs';
|
|
24
|
-
import { addIntent, INTENTS_DIR } from '../src/db/intent.mjs';
|
|
24
|
+
import { addIntent, INTENTS_DIR, intentFilePath } from '../src/db/intent.mjs';
|
|
25
25
|
import {
|
|
26
26
|
nextTask,
|
|
27
27
|
formatNext,
|
|
@@ -595,9 +595,13 @@ ${bold('Usage')}
|
|
|
595
595
|
npx @skyf0xx/hedgehog abandon <intent-id> --reason "<why>"
|
|
596
596
|
drop an intent that will never finish: records why,
|
|
597
597
|
resets its tasks to planned on trunk, removes its
|
|
598
|
-
worktree and branch
|
|
598
|
+
worktree and branch — the id stays taken; to change
|
|
599
|
+
an abandoned intent, edit its .hedgehog/intents/<id>.json
|
|
600
|
+
by hand and run 'hedgehog plan', not 'intent add' again
|
|
599
601
|
npx @skyf0xx/hedgehog intent add [flags] add an intent (rules/requirements/dependencies)
|
|
600
|
-
npx @skyf0xx/hedgehog intent add --file <path> add an intent from a JSON file
|
|
602
|
+
npx @skyf0xx/hedgehog intent add --file <path> add an intent from a JSON file — fails on an id already
|
|
603
|
+
in the build graph, including one reset by 'hedgehog
|
|
604
|
+
abandon' (still 'planned', not removed); see 'abandon' above
|
|
601
605
|
npx @skyf0xx/hedgehog next print the task packet for one ready task
|
|
602
606
|
npx @skyf0xx/hedgehog show <task-id> print the task packet for any task, at any status
|
|
603
607
|
npx @skyf0xx/hedgehog claim --owner <owner> [--count <n>] atomically claim up to n ready tasks
|
|
@@ -1555,7 +1559,11 @@ async function planCommand(args = []) {
|
|
|
1555
1559
|
}
|
|
1556
1560
|
|
|
1557
1561
|
for (const { intentId, branch, path } of worktreesCreated) {
|
|
1558
|
-
console.log(
|
|
1562
|
+
console.log(
|
|
1563
|
+
` ${green('worktree')} ${bold(intentId)} ${dim(`${branch} → ${path}`)}\n` +
|
|
1564
|
+
` ${dim(`compiling here, not onto trunk, because every intent ${intentId} depends_on is already complete —`)}\n` +
|
|
1565
|
+
` ${dim(`see \`hedgehog merge ${intentId}\`/\`hedgehog abandon ${intentId}\` to close it out later`)}`,
|
|
1566
|
+
);
|
|
1559
1567
|
}
|
|
1560
1568
|
|
|
1561
1569
|
// Compiles the new worktree's own graph from inside it — a plain
|
|
@@ -1728,8 +1736,15 @@ async function intentCommand(args) {
|
|
|
1728
1736
|
try {
|
|
1729
1737
|
intent = await addIntent(db, record);
|
|
1730
1738
|
} catch (err) {
|
|
1739
|
+
const idTaken = /UNIQUE constraint failed: intents\.id/.test(err.message);
|
|
1731
1740
|
console.error(
|
|
1732
|
-
`${red('Failed to add intent:')} ${err.message}\n\
|
|
1741
|
+
`${red('Failed to add intent:')} ${err.message}\n\n` +
|
|
1742
|
+
(idTaken
|
|
1743
|
+
? `${bold(record.id)} already exists in the build graph — this includes an intent \`hedgehog abandon\`\n` +
|
|
1744
|
+
`reset to 'planned' rather than removed. To change it, edit ${intentFilePath(record.id)}\n` +
|
|
1745
|
+
`by hand and run \`hedgehog plan\` to recompile; don't run \`intent add\` again for this id.\n\n`
|
|
1746
|
+
: '') +
|
|
1747
|
+
`Usage: hedgehog intent add --id <id> --goal <goal> --outcome <outcome> [--rule <r>]... [--depends-on <id>]...\n or: hedgehog intent add --file <path.json>\n`,
|
|
1733
1748
|
);
|
|
1734
1749
|
process.exitCode = 1;
|
|
1735
1750
|
return;
|
|
@@ -3705,7 +3720,10 @@ async function abandonCommand(args) {
|
|
|
3705
3720
|
console.log(
|
|
3706
3721
|
`\n${bold('Abandoned.')} ${dim(`${id} is reset to planned on trunk. Commit ${ABANDONED_DIR}/${id.toLowerCase()}.json —`)}\n` +
|
|
3707
3722
|
`${dim('the build graph is derived and gitignored, and an uncommitted abandonment')}\n` +
|
|
3708
|
-
`${dim('is reverted by the next `hedgehog db rebuild`.')}\n
|
|
3723
|
+
`${dim('is reverted by the next `hedgehog db rebuild`.')}\n\n` +
|
|
3724
|
+
`${dim(`${bold(id)} still exists in the build graph at 'planned' — do not run \`hedgehog intent add\` for`)}\n` +
|
|
3725
|
+
`${dim(`this id again (it will fail: the id is already taken). To change the intent, edit`)}\n` +
|
|
3726
|
+
`${dim(`${intentFilePath(id)} by hand and run \`hedgehog plan\` to recompile it.`)}\n`,
|
|
3709
3727
|
);
|
|
3710
3728
|
}
|
|
3711
3729
|
|
package/package.json
CHANGED
package/src/agents/planner.md
CHANGED
|
@@ -259,6 +259,20 @@ the first-run shape; on re-entry, run `hedgehog-planning-intake`'s
|
|
|
259
259
|
owns `.hedgehog/chain/00-brief.md` and this core's own Confirm & Lock
|
|
260
260
|
stage; `.hedgehog/BMAD/` is written by the shared Phase 0 in
|
|
261
261
|
`hedgehog-planning-intake`.
|
|
262
|
+
- **`copywriting`** → open `hedgehog-copywriting-loop`'s planning-intake
|
|
263
|
+
section and follow it: it opens with `hedgehog-planning-intake`'s
|
|
264
|
+
Phase 0 (the same vendored BMAD shelf `full-stack-app` runs, in full,
|
|
265
|
+
archived to `.hedgehog/BMAD/` — the same skill, not a separate copy of
|
|
266
|
+
its steps), then does its own mining into a draft brief (what's being
|
|
267
|
+
written, the audience, the register), the copywriting counterpart to
|
|
268
|
+
`hedgehog-planning-intake`'s Phase 1 (domain modules and an Add-ons
|
|
269
|
+
decision on full-stack-app). The mined draft is shown back at this
|
|
270
|
+
core's own Confirm & Lock stage, pre-filled from BMAD's output, for
|
|
271
|
+
the user to accept or correct. State the same BMAD attribution as
|
|
272
|
+
full-stack-app before that Phase 0 begins. `hedgehog-copywriting-loop`
|
|
273
|
+
owns `.hedgehog/copy/00-brief.md` and this core's own Confirm & Lock
|
|
274
|
+
stage; `.hedgehog/BMAD/` is written by the shared Phase 0 in
|
|
275
|
+
`hedgehog-planning-intake`.
|
|
262
276
|
- **`deepseek-harness`** → no BMAD shelf runs on this core, and none of
|
|
263
277
|
`hedgehog-planning-intake` applies. Intake is mechanical, owned
|
|
264
278
|
entirely by `hedgehog-dsh-loop`'s own Planning intake section: confirm
|
package/src/db/plan.mjs
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
//
|
|
6
6
|
// full-stack-app and pwa-app: one task per layer per intent (an intent is
|
|
7
7
|
// a domain module — see the core definition's `{module}` placeholder).
|
|
8
|
-
// landing-page, deepseek-harness, and authored (whether
|
|
9
|
-
// scratch or adopted onto an existing repo): one task per
|
|
10
|
-
// module axis. All are the same operation — walk a core
|
|
11
|
-
// chain once per intent — because a linear chain is
|
|
12
|
-
// the layer graph (spec: MVP scope item 5).
|
|
8
|
+
// landing-page, copywriting, deepseek-harness, and authored (whether
|
|
9
|
+
// designed from scratch or adopted onto an existing repo): one task per
|
|
10
|
+
// phase/layer, no module axis. All are the same operation — walk a core
|
|
11
|
+
// definition's layer chain once per intent — because a linear chain is
|
|
12
|
+
// the degenerate case of the layer graph (spec: MVP scope item 5).
|
|
13
13
|
//
|
|
14
14
|
// Layer cardinality: a layer marked `once: true` in the core definition
|
|
15
15
|
// opts out of that per-intent multiplication and compiles a single task
|
package/src/db/worktree.mjs
CHANGED
|
@@ -431,6 +431,26 @@ function resetIntentTasksToPlanned(db, intentId) {
|
|
|
431
431
|
.all(intentId);
|
|
432
432
|
}
|
|
433
433
|
|
|
434
|
+
// Deletes every `intent_dependencies` row naming `intentId` on either
|
|
435
|
+
// side. An abandoned intent is reset to `planned` with no compiled tasks
|
|
436
|
+
// on trunk, so a `depends_on` edge pointing at it (something else declared
|
|
437
|
+
// as depending on it) or away from it (its own declared dependency) is
|
|
438
|
+
// both stale the moment abandonment lands: `eligibleIntents` (this file)
|
|
439
|
+
// reads that table directly to decide worktree eligibility, and a row
|
|
440
|
+
// surviving abandonment lets an unrelated intent read as "its dependency
|
|
441
|
+
// is satisfied" against an intent that no longer has any real status to
|
|
442
|
+
// satisfy anything with, or lets this intent re-read as eligible against a
|
|
443
|
+
// dependency it no longer declares. Re-adding the same id later
|
|
444
|
+
// (`hedgehog intent add --file` with a JSON that still declares the
|
|
445
|
+
// dependency) recreates the row from that file, same as any first-time
|
|
446
|
+
// add — this only clears what abandonment made stale, not what a future
|
|
447
|
+
// add might legitimately restate.
|
|
448
|
+
function clearIntentDependencies(db, intentId) {
|
|
449
|
+
db.prepare(
|
|
450
|
+
'DELETE FROM intent_dependencies WHERE intent_id = ? OR depends_on_intent_id = ?',
|
|
451
|
+
).run(intentId, intentId);
|
|
452
|
+
}
|
|
453
|
+
|
|
434
454
|
// Resets every task of `intentId` to `planned` on whichever DB `db` is
|
|
435
455
|
// open against (trunk, by the CLI's own contract — see abandonCommand),
|
|
436
456
|
// clears any lease, and reopens the intent itself to `planned` so a later
|
|
@@ -440,6 +460,11 @@ function resetIntentTasksToPlanned(db, intentId) {
|
|
|
440
460
|
// tasks that don't exist yet). Mirrors reconcile.mjs#applyReconciliation's
|
|
441
461
|
// shape: the committed file is written first, this is applied second.
|
|
442
462
|
//
|
|
463
|
+
// Also clears every `intent_dependencies` row naming this intent, on
|
|
464
|
+
// either side (clearIntentDependencies, above) — an abandoned intent's own
|
|
465
|
+
// declared dependency and any other intent's dependency on it are both
|
|
466
|
+
// stale the instant it resets to `planned` with no shipped work.
|
|
467
|
+
//
|
|
443
468
|
// Refuses an intent already `complete` (merged, real shipped work) —
|
|
444
469
|
// same reasoning as reconcile.mjs#confirmReconciliation refusing an
|
|
445
470
|
// already-complete task: applyAbandonment resets tasks to 'planned'
|
|
@@ -458,6 +483,7 @@ export function applyAbandonment(db, intentId) {
|
|
|
458
483
|
);
|
|
459
484
|
}
|
|
460
485
|
const resetTasks = resetIntentTasksToPlanned(db, intentId);
|
|
486
|
+
clearIntentDependencies(db, intentId);
|
|
461
487
|
|
|
462
488
|
if (intent) {
|
|
463
489
|
db.prepare("UPDATE intents SET status = 'planned' WHERE id = ?").run(intentId);
|
|
@@ -501,6 +527,7 @@ export function replayAbandonments(db, abandonments) {
|
|
|
501
527
|
}
|
|
502
528
|
setPlanned.run(intentId);
|
|
503
529
|
resetIntentTasksToPlanned(db, intentId);
|
|
530
|
+
clearIntentDependencies(db, intentId);
|
|
504
531
|
replayed.push({ intentId, reason: record.reason });
|
|
505
532
|
}
|
|
506
533
|
return { replayed, orphaned };
|
package/src/registry/cores.json
CHANGED
|
@@ -51,6 +51,15 @@
|
|
|
51
51
|
"language": "typescript",
|
|
52
52
|
"repository": "https://github.com/skyf0xx/hedgehog-core-adopted",
|
|
53
53
|
"selects_when": "The description is about bringing Hedgehog's discipline to a codebase that already exists, rather than building something new — the repo already has real source files, or the user says so explicitly: \"adopt this repo\", \"add Hedgehog to my existing project\", \"I want scope/verify enforcement on my changes here\". Not chosen by matching a `when` paragraph the way a shipped core is: hedgehog-adopt reads the repo read-only, proposes a linear-chain .hedgehog/core.yaml whose verify commands are the repo's own, and writes only .hedgehog/ — never a workspace, never a stack migration. This is the core most often confused with authored: adopted brings discipline to an existing repo, while authored designs and scaffolds a workspace from scratch for something being built new — route here only when the work is landing on a codebase that already exists."
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"name": "copywriting",
|
|
57
|
+
"flag": "--copywriting",
|
|
58
|
+
"package": "@skyf0xx/hedgehog-core-copywriting",
|
|
59
|
+
"version": "^0.1.1",
|
|
60
|
+
"language": "typescript",
|
|
61
|
+
"repository": "https://github.com/skyf0xx/hedgehog-core-copywriting",
|
|
62
|
+
"selects_when": "The description asks for a piece of writing or prose to be written or fixed as its own deliverable — marketing copy, a product announcement, UI microcopy strings, docs prose, an email, a pitch, an article, an essay, a blog post, or any other standalone written piece — with no page, app, or other artifact being built around it. Concrete signals: \"write an article about X\", \"write copy for X\", \"help me write a blog post\", \"make this sound less like AI\", \"fix this copy\", \"improve this writing\", \"draft a product announcement\", a request to run text through an AI-tell or humanizer check. Not just marketing/product framing — any standalone prose request qualifies, articles and essays included. The core drafts against `checkCopy()`, a real script running deterministic AI-tell and prose-quality checks (banned vocabulary, passive voice, readability score, sentence-length variance), not an agent's own self-review — a piece of writing ships because the script exited 0. This is the core most often confused with landing-page: landing-page's own copy skill still owns copy that's part of a full page build (headline, hero, section copy sequenced through that core's Chain Method); route here only when the writing is the entire ask, not one stage of a larger build."
|
|
54
63
|
}
|
|
55
64
|
]
|
|
56
65
|
}
|
package/src/registry/index.mjs
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
// Core package registry. One entry per Hedgehog core — full-stack-app,
|
|
2
|
-
// pwa-app, landing-page, deepseek-harness, and authored —
|
|
3
|
-
// package that ships its agents, skills, and (for the
|
|
4
|
-
// plus the CLI flag `hedgehog init` accepts for it
|
|
5
|
-
// reads aloud in Phase 0 to choose one. A fixed
|
|
6
|
-
// discovered by name or flag rather than
|
|
2
|
+
// pwa-app, landing-page, copywriting, deepseek-harness, and authored —
|
|
3
|
+
// naming the npm package that ships its agents, skills, and (for the
|
|
4
|
+
// first five) scaffold, plus the CLI flag `hedgehog init` accepts for it
|
|
5
|
+
// and the prose `planner` reads aloud in Phase 0 to choose one. A fixed
|
|
6
|
+
// table, one entry per core, discovered by name or flag rather than
|
|
7
|
+
// convention.
|
|
7
8
|
//
|
|
8
9
|
// `authored` carries no flag — it is never selected off a fixed list at
|
|
9
10
|
// install time. hedgehog-core-design chooses it during planning (from-scratch
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: hedgehog-planning-intake
|
|
3
|
-
description: Use on any core for first-run planning intake — Phase 0 runs the vendored BMAD-METHOD planning shelf, shared by every core, and Phase 1 (mining `04-prd.md` into intent records plus the Add-ons/sync-and-remote-entities decision) is full-stack-app's and pwa-app's shared procedure — identical mechanics, a different decision at step 5/8. Phase 0 also defines compressed intake, the path a user's explicit "just build it" choice takes on full-stack-app, pwa-app, and authored cores: one batched round of questions in place of the shelf, writing the same archive at the same path so Phase 1, `ux-planner`, and the Re-entry pass all keep their documented source. Also use for the Re-entry pass, which mines new scope into additional intents without re-running the shelf, on any core with a module axis to add an intent to (full-stack-app, pwa-app, authored) — landing-page has none, so its own new-scope path runs through `hedgehog-landing-loop`'s Correction Protocol instead. Invoked by the `planner` agent, which decides the path; don't run standalone. landing-page runs this skill's Phase 0 on first run, then mines the same archive through `hedgehog-landing-loop`'s own planning-intake section, that core's counterpart to this skill's Phase 1. An authored core runs this skill's Phase 0, then `hedgehog-core-design`, then this skill's Phase 1 mining against the designed layer sequence. A brownfield adoption (`hedgehog-adopt`) never runs this skill's shelf at all — the drivers BMAD elicits are already settled facts of a repo that already exists.
|
|
3
|
+
description: Use on any core for first-run planning intake — Phase 0 runs the vendored BMAD-METHOD planning shelf, shared by every core, and Phase 1 (mining `04-prd.md` into intent records plus the Add-ons/sync-and-remote-entities decision) is full-stack-app's and pwa-app's shared procedure — identical mechanics, a different decision at step 5/8. Phase 0 also defines compressed intake, the path a user's explicit "just build it" choice takes on full-stack-app, pwa-app, and authored cores: one batched round of questions in place of the shelf, writing the same archive at the same path so Phase 1, `ux-planner`, and the Re-entry pass all keep their documented source. Also use for the Re-entry pass, which mines new scope into additional intents without re-running the shelf, on any core with a module axis to add an intent to (full-stack-app, pwa-app, authored) — landing-page has none, so its own new-scope path runs through `hedgehog-landing-loop`'s Correction Protocol instead. Invoked by the `planner` agent, which decides the path; don't run standalone. landing-page runs this skill's Phase 0 on first run, then mines the same archive through `hedgehog-landing-loop`'s own planning-intake section, that core's counterpart to this skill's Phase 1. copywriting runs this skill's Phase 0 the same way, then mines the same archive through `hedgehog-copywriting-loop`'s own planning-intake section into a what/audience/register brief — no module axis, so its own new-scope path runs through that loop's Correction Protocol rather than the Re-entry pass below. An authored core runs this skill's Phase 0, then `hedgehog-core-design`, then this skill's Phase 1 mining against the designed layer sequence. A brownfield adoption (`hedgehog-adopt`) never runs this skill's shelf at all — the drivers BMAD elicits are already settled facts of a repo that already exists.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Hedgehog Planning Intake
|
|
@@ -11,12 +11,15 @@ every core) and mining its output. On full-stack-app and pwa-app that
|
|
|
11
11
|
mining is this skill's own Phase 1, into intent records written via
|
|
12
12
|
`hedgehog intent
|
|
13
13
|
add`; on landing-page it's `hedgehog-landing-loop`'s planning-intake
|
|
14
|
-
section, into a subject/audience/job statement
|
|
14
|
+
section, into a subject/audience/job statement; on copywriting it's
|
|
15
|
+
`hedgehog-copywriting-loop`'s planning-intake section, into a
|
|
16
|
+
what/audience/register brief. This is the mechanics
|
|
15
17
|
`planner` calls once its Phase 0 core-selection check has picked a core —
|
|
16
18
|
the interpretive judgment (which Feature becomes which intent, Confirm &
|
|
17
19
|
Lock either way) belongs to `planner`; this skill (Phase 0, and Phase 1 on
|
|
18
|
-
full-stack-app and pwa-app)
|
|
19
|
-
|
|
20
|
+
full-stack-app and pwa-app), `hedgehog-landing-loop` (landing-page's own
|
|
21
|
+
mining), and `hedgehog-copywriting-loop` (copywriting's own mining) are
|
|
22
|
+
the fixed procedures that judgment runs inside.
|
|
20
23
|
|
|
21
24
|
That shelf run is a **first run**, once per project. When new scope
|
|
22
25
|
enters play later on a core with a module axis (full-stack-app, pwa-app,
|