@jaybeeuu/agent-cortex 2.0.0 → 2.2.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/CHANGELOG.md +437 -0
- package/README.md +46 -15
- package/agents/README.md +22 -10
- package/agents/plan/agent.md +2 -2
- package/agents/ralph/agent.md +128 -91
- package/agents/ralph/claude/frontmatter.json +3 -3
- package/agents/ralph/claude/wake.md +46 -0
- package/agents/ralph/pi/{polling.md → wake.md} +35 -20
- package/agents/ralph-plan/agent.md +23 -11
- package/bin/agent-cortex.mjs +66 -4
- package/bin/installers/claude.mjs +262 -77
- package/bin/installers/pi.mjs +200 -24
- package/extensions/agent-guardrails/README.md +1 -1
- package/extensions/agent-guardrails/guardrails.ts +1 -1
- package/extensions/agent-guardrails/index.ts +1 -1
- package/extensions/agent-modes/discover.test.ts +2 -2
- package/extensions/output-style/README.md +58 -0
- package/extensions/output-style/index.ts +23 -0
- package/extensions/output-style/output-style.md +43 -0
- package/extensions/output-style/output-style.test.ts +50 -0
- package/extensions/output-style/output-style.ts +32 -0
- package/extensions/output-style/package.json +19 -0
- package/hooks/claude/scripts/notify.mjs +8 -1
- package/lib/cli.mjs +91 -2
- package/package.json +29 -4
- package/scripts/check-changeset.mjs +4 -0
- package/scripts/check-no-sync.mjs +5 -1
- package/scripts/check-skill-frontmatter.mjs +21 -0
- package/scripts/lib/compose-agent.mjs +69 -9
- package/scripts/lib/fs.mjs +10 -2
- package/scripts/lib/migrate.mjs +736 -0
- package/scripts/lib/release-gates.mjs +21 -1
- package/scripts/lib/skill-frontmatter.mjs +152 -0
- package/scripts/lib/skill-links.mjs +52 -0
- package/scripts/lib/verify-worker-tree.mjs +25 -0
- package/scripts/resolve-publish-command.mjs +4 -0
- package/skills/engineering/design-an-interface/SKILL.md +3 -3
- package/skills/engineering/grill-with-docs/SKILL.md +3 -5
- package/skills/engineering/improve-codebase-architecture/SKILL.md +5 -4
- package/skills/engineering/tdd/SKILL.md +5 -7
- package/skills/engineering/technical-direction/SKILL.md +5 -5
- package/skills/planning/classify-bead/REFERENCE.md +3 -3
- package/skills/planning/classify-bead/SKILL.md +14 -9
- package/skills/planning/classify-bead/scripts/classify-bead.mjs +5 -4
- package/skills/planning/create-task/REFERENCE.md +52 -3
- package/skills/planning/create-task/SKILL.md +70 -26
- package/skills/planning/create-task/scripts/{create-chores.ts → create-chores.mjs} +48 -23
- package/skills/planning/flesh-out-idea/REFERENCE.md +116 -0
- package/skills/planning/flesh-out-idea/SKILL.md +146 -0
- package/skills/planning/prd-to-tasks/REFERENCE.md +54 -5
- package/skills/planning/prd-to-tasks/SKILL.md +22 -16
- package/skills/planning/record-idea/FORMAT.md +66 -17
- package/skills/planning/record-idea/SKILL.md +48 -24
- package/skills/planning/request-refactor-plan/SKILL.md +4 -4
- package/skills/planning/spec-to-tickets/SKILL.md +5 -5
- package/skills/planning/write-a-prd/SKILL.md +8 -9
- package/skills/planning/write-a-ticket/SKILL.md +4 -6
- package/skills/productivity/bd-tool/SKILL.md +15 -10
- package/skills/productivity/grill-me/SKILL.md +5 -0
- package/skills/productivity/init-beads/SKILL.md +3 -3
- package/skills/productivity/migration/REFERENCE.md +227 -0
- package/skills/productivity/migration/SKILL.md +188 -0
- package/skills/productivity/validate-agent-dir/scripts/{validate-agent-dir.ts → validate-agent-dir.mjs} +49 -28
- package/skills/productivity/write-a-skill/SKILL.md +5 -5
- package/skills/review/maintain-agent-docs/SKILL.md +5 -7
- package/skills/review/refactor-skill/SKILL.md +4 -3
- package/skills/review/review-security/SKILL.md +3 -5
- package/skills/style/style-code/SKILL.md +5 -10
- package/skills/style/style-comms/SKILL.md +5 -7
- package/skills/style/style-documentation/SKILL.md +5 -6
- package/skills/style/style-tests/SKILL.md +5 -7
- package/skills/workflow/git-workflow/SKILL.md +28 -4
- package/skills/workflow/hitl-collab/SKILL.md +4 -6
- package/skills/workflow/plan/SKILL.md +41 -30
- package/skills/workflow/ralph/REFERENCE.md +209 -55
- package/skills/workflow/ralph/SKILL.md +89 -50
- package/skills/workflow/ralph/scripts/pending-gates.mjs +134 -0
- package/skills/workflow/run-pipeline-stage/SKILL.md +72 -71
- package/skills/workflow/run-pipeline-stage/playbooks/code.md +11 -0
- package/skills/workflow/run-pipeline-stage/playbooks/document.md +12 -0
- package/skills/workflow/run-pipeline-stage/playbooks/fix.md +12 -0
- package/skills/workflow/run-pipeline-stage/playbooks/review.md +11 -0
- package/skills/workflow/run-pipeline-stage/playbooks/verify.md +13 -0
- package/skills/workflow/run-pipeline-stage/prompts/stage-runner.md +73 -1
- package/token-map.README.md +9 -4
- package/token-map.json +13 -6
- package/.agents/skills/style-versioning/SKILL.md +0 -172
- package/.changeset/README.md +0 -8
- package/.changeset/config.json +0 -11
- package/.github/workflows/ci.yml +0 -302
- package/.junie/guidelines.md +0 -87
- package/.junie/mcp/mcp.json +0 -10
- package/AGENTS.md +0 -151
- package/agents/ralph/claude/polling.md +0 -31
- package/agents-native/ralph.md +0 -193
- package/docs/claude-hooks.md +0 -128
- package/docs/commit-signing.md +0 -231
- package/docs/ideas/auto-model-selection.md +0 -75
- package/docs/ideas/ban-content-assertion-tests.md +0 -75
- package/docs/ideas/bead-progress-notes-for-session-resumption.md +0 -75
- package/docs/ideas/classify-beads-via-deterministic-script-with-agent-fallback.md +0 -70
- package/docs/ideas/ctx-alias-version-and-update-commands.md +0 -65
- package/docs/ideas/ctx-feedback-command-for-capturing-ideas-from-any-machine.md +0 -67
- package/docs/ideas/dedicated-review-tests-skill.md +0 -71
- package/docs/ideas/deployment-beads-for-post-merge-pipelines.md +0 -36
- package/docs/ideas/design-and-delivery-as-separate-bead-trees/design-and-delivery-as-separate-bead-trees.md +0 -99
- package/docs/ideas/enable-signed-commit-enforcement-changesets-bot-commits-must-be-signed.md +0 -42
- package/docs/ideas/extension-manifests.md +0 -121
- package/docs/ideas/improve-pi-system-prompt.md +0 -37
- package/docs/ideas/map-every-cortex-tool-to-a-real-pi-equivalent.md +0 -95
- package/docs/ideas/model-selector.md +0 -40
- package/docs/ideas/pi-task-memory.md +0 -34
- package/docs/ideas/qa-extension.md +0 -43
- package/docs/ideas/record-idea-implementation-questions.md +0 -68
- package/docs/ideas/record-ideas-as-beads.md +0 -115
- package/docs/ideas/self-flushing-session.md +0 -72
- package/docs/ideas/state-in-beads-not-md.md +0 -69
- package/docs/ideas/subagent-visibility.md +0 -72
- package/docs/ideas/task-session-context.local.md +0 -95
- package/docs/ideas/task-session-context.md +0 -89
- package/docs/ideas/test-data-creation-helpers.md +0 -92
- package/docs/ideas/test-planning-stage-bead-in-feature-planning.md +0 -68
- package/docs/ideas/unified-ci-pipeline.md +0 -28
- package/docs/ideas/unify-the-ticket-and-task-decomposition-workflows.md +0 -71
- package/docs/ideas/worktree-housekeeping-for-closed-beads.md +0 -39
- package/docs/inspirations.md +0 -33
- package/docs/research/disable-model-invocation.md +0 -82
- package/docs/research/gas-city-research.md +0 -256
- package/docs/research/skill-design-research.md +0 -286
- package/docs/research/skill-improvements-analysis.md +0 -117
- package/docs/research/skill-patterns-research.md +0 -24
- package/docs/skills/skill-anatomy.md +0 -197
- package/docs/technical-direction/harness-config.md +0 -177
- package/docs/technical-direction/migration-execution-labels.md +0 -177
- package/docs/user-preferences.md +0 -17
- package/extensions/agent-guardrails/tsconfig.json +0 -12
- package/extensions/agent-modes/tsconfig.json +0 -12
- package/extensions/session-start/tsconfig.json +0 -12
- package/extensions/skill-stats/pnpm-lock.yaml +0 -329
- package/extensions/skill-stats/tsconfig.json +0 -12
- package/extensions/subagent/agents/planner.md +0 -37
- package/extensions/subagent/agents/reviewer.md +0 -35
- package/extensions/subagent/agents/scout.md +0 -50
- package/extensions/subagent/agents/worker.md +0 -24
- package/extensions/subagent/prompts/implement-and-review.md +0 -10
- package/extensions/subagent/prompts/implement.md +0 -10
- package/extensions/subagent/prompts/scout-and-plan.md +0 -9
- package/extensions/subagent/tsconfig.json +0 -12
- package/pi/keybindings.json +0 -3
- package/pi/settings.json +0 -34
- package/pnpm-workspace.yaml +0 -14
- package/skills/planning/create-task/scripts/package.json +0 -14
- package/skills/planning/create-task/scripts/pnpm-lock.yaml +0 -342
- package/skills/planning/create-task/scripts/tsconfig.json +0 -12
- package/skills/planning/record-idea/scripts/new-idea.sh +0 -89
- package/skills/productivity/validate-agent-dir/scripts/package.json +0 -15
- package/skills/productivity/validate-agent-dir/scripts/pnpm-lock.yaml +0 -329
- package/skills/productivity/validate-agent-dir/scripts/pnpm-workspace.yaml +0 -2
- package/skills/productivity/validate-agent-dir/scripts/tsconfig.json +0 -19
- package/skills/productivity/validate-agent-dir/scripts/validate-agent-dir.test.ts +0 -317
- package/skills/workflow/run-pipeline-stage/REFERENCE.md +0 -22
- package/skills/workflow/run-pipeline-stage/scripts/generate-progress.test.ts +0 -682
- package/skills/workflow/run-pipeline-stage/scripts/generate-progress.ts +0 -588
- package/skills/workflow/run-pipeline-stage/scripts/package.json +0 -15
- package/skills/workflow/run-pipeline-stage/scripts/pnpm-lock.yaml +0 -342
- package/skills/workflow/run-pipeline-stage/scripts/pnpm-workspace.yaml +0 -2
- package/skills/workflow/run-pipeline-stage/scripts/tsconfig.json +0 -12
- package/test/classify-bead.test.mjs +0 -277
- package/test/claude-installer.test.mjs +0 -308
- package/test/cli.test.mjs +0 -314
- package/test/create-chores.test.mjs +0 -85
- package/test/fake-bd.test.mjs +0 -72
- package/test/fs.test.mjs +0 -76
- package/test/helpers/fake-bd.mjs +0 -87
- package/test/helpers/fake-claude.mjs +0 -152
- package/test/helpers/fake-pi.mjs +0 -132
- package/test/installer.test.mjs +0 -664
- package/test/notify-hook.test.mjs +0 -63
- package/test/pi-installer.test.mjs +0 -785
- package/test/pi-register.test.mjs +0 -342
- package/test/pi-sweep.test.mjs +0 -619
- package/test/release-gates.test.mjs +0 -190
- package/test/verify-worker-tree.test.mjs +0 -120
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
##
|
|
1
|
+
## Wake mechanism (PI — blocking wait)
|
|
2
|
+
|
|
3
|
+
**Mechanism: a blocking wait — `wait_for_agents` blocks until at least one background worker finishes and returns its result inline, so the wait itself is the completion signal and no timer, sleep, or poll loop exists.**
|
|
4
|
+
|
|
5
|
+
### Spawn
|
|
2
6
|
|
|
3
7
|
RALPH HAS ONLY ONE WAY TO SPAWN SUBAGENTS: call the **`task`** tool (not bash, not any other tool).
|
|
4
8
|
|
|
@@ -10,7 +14,7 @@ Example:
|
|
|
10
14
|
```
|
|
11
15
|
Calling tool 'task' with arguments: { "prompt": "...", "cwd": ".agent-cortex/worktrees/abc-123" }
|
|
12
16
|
```
|
|
13
|
-
The response is a plain agent ID string (e.g. `agent-550e8400-e29b-41d4-a716-446655440000`). Store it in memory — you need it later to wait for the result.
|
|
17
|
+
The response is a plain agent ID string (e.g. `agent-550e8400-e29b-41d4-a716-446655440000`). Store it in memory and in `state.json` — you need it later to wait for the result.
|
|
14
18
|
|
|
15
19
|
**`wait_for_agents`** — Block until at least one background sub-agent completes. This is the primary way to get results back.
|
|
16
20
|
- `agentIds` (string[], required): The agent IDs returned by `task` to wait on.
|
|
@@ -31,25 +35,20 @@ Rules:
|
|
|
31
35
|
- ALWAYS set `cwd` to the feature worktree path when running stage chores.
|
|
32
36
|
- ALWAYS keep the returned `agentId` in memory to wait on it / read its result later.
|
|
33
37
|
|
|
34
|
-
|
|
38
|
+
### Completion arrival
|
|
35
39
|
|
|
36
|
-
|
|
40
|
+
A completion arrives **in the wait response**: `wait_for_agents` returns as soon as one worker finishes, carrying that worker's result inline, so you never go looking for it. Apply the shared completion handling in the **Event loop** section of agent.md (the result is included in the wait response, or re-read with `read_agent`; re-read state.json and branch on the entry's `kind` — `stage` parses the REPORT and confirms the worker closed its chore, `expand` confirms the parent now has `stage:*` chores and dispatches the ready `stage:code` — then check for newly ready beads and the shutdown check). An expansion worker is in the wait set but is never treated as a chore: it emits no REPORT and needs no close confirmation.
|
|
37
41
|
|
|
38
|
-
###
|
|
42
|
+
### Id tracking
|
|
39
43
|
|
|
40
|
-
|
|
41
|
-
- **Wait** — call `wait_for_agents` with the agent IDs of every in-flight chore (`timeout` defaults to 120s). The tool blocks until at least one finishes. For each completed agent:
|
|
42
|
-
1. Flush its log tail if it has new lines (see _Log polling_ below) to surface progress to chat.
|
|
43
|
-
2. Apply the shared completion handling in the **Event loop** section of agent.md (the result is included in the wait response, or re-read with `read_agent`; re-read state.json, parse the REPORT, close the chore, advance the parent, check for newly ready beads, run the shutdown check).
|
|
44
|
-
3. Drop the completed agent ID from the wait set.
|
|
45
|
-
- **Repeat** — dispatch replacements for completed chores (up to 5 in flight), add their new IDs to the wait set, and call `wait_for_agents` again with the remaining + new IDs.
|
|
46
|
-
- **Timeout / STILL RUNNING** — if the timeout elapses with agents still working, the tool returns those agents as STILL RUNNING (with `timed out` noted). Call `wait_for_agents` again with the same IDs — the still-running agents keep working; you never re-dispatch them. `read_agent` remains available to re-read a completed result at any time.
|
|
47
|
-
- **Abort** — if the user aborts, `wait_for_agents` returns immediately with what is known so far (no hang); do not re-issue the wait.
|
|
48
|
-
- **Stop** — when stopping completely (HITL Pause or Shutdown) there is no timer to kill on PI: just stop calling `wait_for_agents`. Never start background `sleep` timers for completion detection.
|
|
44
|
+
Initialize `.agent-cortex/ralph/state.json` as `{ "timerShellId": null, "inflight": [] }`. Only one handle matters here:
|
|
49
45
|
|
|
50
|
-
|
|
46
|
+
- **inflight[].agentId** — the ID `task` returned for that worker; it is the argument `wait_for_agents` takes, the identifier for a `read_agent` fallback, and the key the completion is correlated to its bead.
|
|
47
|
+
- **timerShellId** — stays `null` on PI forever: the blocking wait replaces a poll timer, so nothing is ever recorded there.
|
|
51
48
|
|
|
52
|
-
|
|
49
|
+
### Log flush
|
|
50
|
+
|
|
51
|
+
Flush new log lines as part of handling each wait result — that is when the loop wakes, and a worker's final lines arrive with the completion. Run this procedure each time `wait_for_agents` returns (or whenever a new agent is dispatched):
|
|
53
52
|
|
|
54
53
|
1. **Query in-flight beads**: read `inflight` from `state.json`. Each entry has a `parentId` and `logLine`.
|
|
55
54
|
2. For each in-flight entry, read new lines from its log file:
|
|
@@ -66,9 +65,25 @@ Run this procedure each time `wait_for_agents` returns (or whenever a new agent
|
|
|
66
65
|
- Update `logLine` in `state.json` for that entry.
|
|
67
66
|
4. If no entry had new lines, post nothing — do not spam the chat with empty polls.
|
|
68
67
|
|
|
69
|
-
|
|
68
|
+
### Wait loop lifecycle
|
|
69
|
+
|
|
70
|
+
- **Dispatch-and-wait** — during initialization, dispatch up to 5 AFK chore subagents with `task` (or an expansion worker for a chore-less AFK bead) and hold their agent IDs (recorded in `state.json`'s `inflight` list; expansion entries carry `kind: "expand"` and `choreId: null`).
|
|
71
|
+
- **Wait** — call `wait_for_agents` with the agent IDs of every in-flight agent, stage worker or expansion worker (`timeout` defaults to 120s). The tool blocks until at least one finishes. For each completed agent:
|
|
72
|
+
1. Flush its log tail if it has new lines (see _Log flush_ above) to surface progress to chat.
|
|
73
|
+
2. Apply the shared completion handling described under _Completion arrival_ above.
|
|
74
|
+
3. Drop the completed agent ID from the wait set.
|
|
75
|
+
- **Repeat** — dispatch replacements for completed work (up to 5 in flight), add their new IDs to the wait set, and call `wait_for_agents` again with the remaining + new IDs. A completed expansion leaves a slot to fill with its parent's newly ready `stage:code` chore.
|
|
76
|
+
- **Empty wait set** — never call `wait_for_agents` with an empty `agentIds` list. When handling a completion leaves `inflight` empty, run the event loop's final check (agent.md, _If nothing remains in flight_): a ready `stage:*` chore, or a ready, claimable chore-less AFK task bead (expand it first), is dispatchable — dispatch it and wait again. With nothing dispatchable, pending HITL gate beads mean **HITL Pause** and none mean **Shutdown**; either way stop calling `wait_for_agents` and act again only when the user re-prompts.
|
|
77
|
+
- **Timeout / STILL RUNNING** — if the timeout elapses with agents still working, the tool returns those agents as STILL RUNNING (with `timed out` noted). Call `wait_for_agents` again with the same IDs — the still-running agents keep working; you never re-dispatch them. `read_agent` remains available to re-read a completed result at any time.
|
|
78
|
+
- **Abort** — if the user aborts, `wait_for_agents` returns immediately with what is known so far (no hang); do not re-issue the wait.
|
|
79
|
+
|
|
80
|
+
### Stop
|
|
81
|
+
|
|
82
|
+
Nothing to kill: stopping means simply **stop calling `wait_for_agents`**. There is no timer, so there is no shellId to kill and nothing to unset — just do not issue another wait. Never start background `sleep` timers as a substitute for the wait, and never re-issue a wait once the HITL pause or shutdown condition has been met.
|
|
83
|
+
|
|
84
|
+
### Waiting constraints
|
|
70
85
|
|
|
71
|
-
- **Always** keep a `wait_for_agents` call outstanding while agents are in-flight —
|
|
86
|
+
- **Always** keep a `wait_for_agents` call outstanding while agents are in-flight — stage workers and expansion workers alike. Never let running agent work stall without a wait active.
|
|
72
87
|
- **Never** re-dispatch an agent that is merely STILL RUNNING — wait again on the same ID.
|
|
73
|
-
- **Never** start `sleep` / background timer loops for completion detection on PI — `wait_for_agents` replaces them
|
|
74
|
-
- **Never** post empty poll updates to chat — only surface new log content.
|
|
88
|
+
- **Never** start `sleep` / background timer loops for completion detection on PI — `wait_for_agents` replaces them, and there is nothing to kill on HITL Pause.
|
|
89
|
+
- **Never** post empty poll updates to chat — only surface new log content.
|
|
@@ -51,23 +51,35 @@ Update the top-level bead's `design` field with a high-level implementation plan
|
|
|
51
51
|
### 6. Decompose into tasks
|
|
52
52
|
For large workstreams (multiple distinct areas) invoke the **prd-to-tasks** skill. For a single self-contained task invoke **create-task**. Pass the full `bd prime` output and any relevant design context from the `design` field to each skill.
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
**Planning gate.** Each feature carries exactly one HITL planning bead — the design gate that keeps the feature's implementation children out of `bd ready` until a human confirms planning is sufficient. It is the bead `create-task` builds on its feature path: that skill's steps 5–6 are the authority for this shape, so when you delegate the feature to `create-task` the gate already exists and you must not create a second one.
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
Ownership is `--parent`; ordering is `bd dep add`. The planning bead is **owned by the feature** and **blocks every implementation child** of that feature. The feature never depends on its own gate — a container that waits on its own child is neither owner nor ordering.
|
|
57
|
+
|
|
58
|
+
Every planning bead description must be cold-start-ready so another person can pick it up without prior chat context. Include all of: (1) what is being built and why, (2) decisions already made, (3) open questions/risks, and (4) references (bead IDs, files, or docs) used during planning.
|
|
59
|
+
|
|
60
|
+
Both routes above create the gate for you, so this block is the shape to build by hand only when the feature already exists and `bd children <feature-id>` lists no `Plan:` child. Never run it beside a gate `create-task` already made: bead creation is not idempotent, so a second run leaves two design gates blocking the same children. The guard is check-then-act and therefore not atomic — two planners on one feature at the same instant could both pass it and create a gate each; that is acceptable because the only automated creation path goes through `create-task`, this agent runs as a single interactive HITL session, and a stray second planning bead carries no `lifecycle:feature-pr`, so ralph never pauses on it.
|
|
57
61
|
|
|
58
62
|
```bash
|
|
59
|
-
|
|
63
|
+
# Design gate: human-owned, owned by the feature, blocking every implementation child.
|
|
64
|
+
planning_id=$(bd create "Plan: <feature title>" --type task --priority <priority> \
|
|
65
|
+
-l execution:hitl --parent <feature-id> --no-inherit-labels \
|
|
66
|
+
--description "<planning context, decisions, open questions, and references>
|
|
60
67
|
|
|
61
68
|
## Acceptance Criteria
|
|
62
69
|
|
|
63
|
-
- [ ]
|
|
64
|
-
|
|
65
|
-
|
|
70
|
+
- [ ] The user confirms planning is sufficient for this feature." --validate --silent)
|
|
71
|
+
|
|
72
|
+
# Readiness gate: every implementation child waits on the design gate.
|
|
73
|
+
bd dep add <impl-task-id> <planning-bead-id>
|
|
66
74
|
```
|
|
67
75
|
|
|
68
|
-
|
|
76
|
+
`--no-inherit-labels` is not optional: `bd` copies a parent's labels at create time, so without it a gate under an `execution:afk` feature picks up `execution:afk` beside its own `execution:hitl` and stops routing as human work.
|
|
77
|
+
|
|
78
|
+
A planning bead is **not** a PR gate and carries no `lifecycle:` label. `create-chores.mjs` owns the `lifecycle:feature-pr` gate — owned by the implementation task, blocked by its `document` chore (the `create-task` skill's `REFERENCE.md` → PR gate bead); creating one here would put a second, differently-wired gate on the same bead. A standalone task bead needs no planning bead: `create-task` classifies it, and its human checkpoint is that PR gate.
|
|
79
|
+
|
|
80
|
+
Do not close planning gates in bulk. Only close a gate after the user explicitly confirms that exact feature is ready to implement; leave all unconfirmed gates open and blocking.
|
|
69
81
|
|
|
70
|
-
Before handing off, ensure every bead created in this step carries an `
|
|
82
|
+
Before handing off, ensure every bead created in this step carries an `execution:` label — check `bd label list <id>` yourself. Do not spawn `classify-bead` here: planning gates are labelled inline above and `create-task` classifies its beads internally. Only invoke it for a bead that genuinely lacks both the label and a `## Type` field. Then run `bd lint <id>` for every bead created in this step and fix any missing sections before handoff.
|
|
71
83
|
|
|
72
84
|
Tag every bead created in this step with `workflow:ralph`:
|
|
73
85
|
|
|
@@ -95,12 +107,12 @@ bead against the full backlog — a P3 feature that blocks others may need a hig
|
|
|
95
107
|
explicit priority than a standalone P4 feature.
|
|
96
108
|
|
|
97
109
|
### 7. Agree with the user
|
|
98
|
-
Present the bead list (IDs, titles, one-line rationale each) plus planning
|
|
110
|
+
Present the bead list (IDs, titles, one-line rationale each) plus the planning-gate status of each feature using `✅` (confirmed/closed) or `⏳` (awaiting confirmation/open). Ask the user to confirm or request changes before finishing.
|
|
99
111
|
|
|
100
|
-
If any planning
|
|
112
|
+
If any planning gate remains open, include an explicit warning that its implementation children are still blocked by it and cannot be handed off to ralph yet. Iterate until approved.
|
|
101
113
|
|
|
102
114
|
### 8. Hand off to ralph
|
|
103
|
-
Once approved, report: "Plan complete — `bd ready` will show the first tasks for ralph."
|
|
115
|
+
Once approved, report: "Plan complete — `bd ready -l execution:afk` will show the first tasks for ralph."
|
|
104
116
|
|
|
105
117
|
## Exploration sub-agent instructions
|
|
106
118
|
|
package/bin/agent-cortex.mjs
CHANGED
|
@@ -2,8 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
import { parseArgs, buildHelpText, validateHarness } from "../lib/cli.mjs";
|
|
4
4
|
import { join, dirname } from "node:path";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
import { readFile } from "node:fs/promises";
|
|
5
7
|
import { installPi, registerPi, sweepLegacyPiUserDirs } from "./installers/pi.mjs";
|
|
6
8
|
|
|
9
|
+
/** @typedef {import("./installers/pi.mjs").InstallPiResult} InstallPiResult */
|
|
10
|
+
/** @typedef {import("./installers/pi.mjs").RegisterPiResult} RegisterPiResult */
|
|
11
|
+
|
|
7
12
|
const argv = process.argv.slice(2);
|
|
8
13
|
const parsed = parseArgs(argv);
|
|
9
14
|
|
|
@@ -12,6 +17,41 @@ if (parsed.command === "help") {
|
|
|
12
17
|
process.exit(0);
|
|
13
18
|
}
|
|
14
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Read the version of the package this CLI ships in: `bin/` sits one level below
|
|
22
|
+
* the package root, in the repo checkout and in the published tarball alike.
|
|
23
|
+
* Resolved from this file's own location, never from the cwd or node_modules
|
|
24
|
+
* resolution, so an installed CLI reports the version it was installed at.
|
|
25
|
+
* Throws when that manifest is missing, unreadable, malformed, or has no version
|
|
26
|
+
* string, so a broken install never prints a bogus version with a success exit.
|
|
27
|
+
* @returns {Promise<string>}
|
|
28
|
+
*/
|
|
29
|
+
async function readPackageVersion() {
|
|
30
|
+
const manifestPath = join(dirname(fileURLToPath(import.meta.url)), "..", "package.json");
|
|
31
|
+
/** @type {unknown} */
|
|
32
|
+
let manifest;
|
|
33
|
+
try {
|
|
34
|
+
manifest = JSON.parse(await readFile(manifestPath, "utf-8"));
|
|
35
|
+
} catch (err) {
|
|
36
|
+
throw new Error(`Cannot read the package version from ${manifestPath}: ${/** @type {Error} */ (err).message}`);
|
|
37
|
+
}
|
|
38
|
+
const version = /** @type {{ version?: unknown }} */ (manifest).version;
|
|
39
|
+
if (typeof version !== "string" || version === "") {
|
|
40
|
+
throw new Error(`Cannot read the package version from ${manifestPath}: the manifest has no "version" string.`);
|
|
41
|
+
}
|
|
42
|
+
return version;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (parsed.command === "version") {
|
|
46
|
+
try {
|
|
47
|
+
process.stdout.write(`${await readPackageVersion()}\n`);
|
|
48
|
+
} catch (err) {
|
|
49
|
+
process.stderr.write(`${/** @type {Error} */ (err).message}\n`);
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
process.exit(0);
|
|
53
|
+
}
|
|
54
|
+
|
|
15
55
|
if (parsed.command === "unknown") {
|
|
16
56
|
process.stderr.write(`Unknown command: ${parsed.name}\nRun "agent-cortex --help" for usage.\n`);
|
|
17
57
|
process.exit(1);
|
|
@@ -66,7 +106,7 @@ if (parsed.command === "install") {
|
|
|
66
106
|
process.stdout.write(` → register it with pi: pi install ${result.output}\n`);
|
|
67
107
|
}
|
|
68
108
|
} catch (err) {
|
|
69
|
-
process.stderr.write(`Install failed: ${err.message}\n`);
|
|
109
|
+
process.stderr.write(`Install failed: ${/** @type {Error} */ (err).message}\n`);
|
|
70
110
|
process.exit(1);
|
|
71
111
|
}
|
|
72
112
|
process.exit(0);
|
|
@@ -99,8 +139,11 @@ if (parsed.command === "install") {
|
|
|
99
139
|
// keeps generating only (documented in --help).
|
|
100
140
|
if (parsed.output === undefined) {
|
|
101
141
|
await registerClaude({
|
|
102
|
-
|
|
103
|
-
|
|
142
|
+
// A default install always materialises the marketplace manifest; the
|
|
143
|
+
// generate-only form (--output) is the only path where it is null, and
|
|
144
|
+
// this branch is not that path.
|
|
145
|
+
root: /** @type {string} */ (result.marketplaceRoot),
|
|
146
|
+
manifest: /** @type {object} */ (result.marketplaceManifest),
|
|
104
147
|
pluginVersion: result.pluginVersion,
|
|
105
148
|
dryRun: parsed.dryRun ?? false,
|
|
106
149
|
requireRegister: parsed.requireRegister ?? false,
|
|
@@ -108,12 +151,13 @@ if (parsed.command === "install") {
|
|
|
108
151
|
}
|
|
109
152
|
process.exit(0);
|
|
110
153
|
} catch (err) {
|
|
111
|
-
process.stderr.write(`Install failed: ${err.message}\n`);
|
|
154
|
+
process.stderr.write(`Install failed: ${/** @type {Error} */ (err).message}\n`);
|
|
112
155
|
process.exit(1);
|
|
113
156
|
}
|
|
114
157
|
}
|
|
115
158
|
}
|
|
116
159
|
|
|
160
|
+
/** @param {{ removed: string[] }} result */
|
|
117
161
|
function printPiSweep({ removed }) {
|
|
118
162
|
if (removed.length === 0) return;
|
|
119
163
|
process.stdout.write(
|
|
@@ -124,6 +168,24 @@ function printPiSweep({ removed }) {
|
|
|
124
168
|
}
|
|
125
169
|
}
|
|
126
170
|
|
|
171
|
+
if (parsed.command === "migrate") {
|
|
172
|
+
if (parsed.optionError) {
|
|
173
|
+
process.stderr.write(`${parsed.optionError}\n`);
|
|
174
|
+
process.exit(1);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Loaded lazily: the migration registry is only needed on this path.
|
|
178
|
+
const { runMigrate } = await import("../scripts/lib/migrate.mjs");
|
|
179
|
+
try {
|
|
180
|
+
await runMigrate({ apply: parsed.apply ?? false, dir: parsed.dir });
|
|
181
|
+
} catch (err) {
|
|
182
|
+
process.stderr.write(`Migration failed: ${/** @type {Error} */ (err).message}\n`);
|
|
183
|
+
process.exit(1);
|
|
184
|
+
}
|
|
185
|
+
process.exit(0);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/** @param {InstallPiResult} result */
|
|
127
189
|
function printPiInstall(result) {
|
|
128
190
|
process.stdout.write(`Installing agent-cortex for "pi" harness…\n`);
|
|
129
191
|
process.stdout.write(` ✓ Staged pi package → ${result.output}\n`);
|