@davidbalzan/groundwork 0.3.1
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/LICENSE +21 -0
- package/README.md +323 -0
- package/docs/DECISIONS.md +170 -0
- package/package.json +38 -0
- package/payload/doc-templates/COMMANDS.md +419 -0
- package/payload/doc-templates/DECISIONS.md +168 -0
- package/payload/doc-templates/FACTS.md +43 -0
- package/payload/doc-templates/GROUNDWORK_METHODOLOGY.md +1300 -0
- package/payload/doc-templates/STACK_MAP.md +90 -0
- package/payload/doc-templates/WORKSTREAMS.md +79 -0
- package/payload/doc-templates/_INDEX.md +54 -0
- package/payload/doc-templates/phases/README.md +36 -0
- package/payload/doc-templates/phases/templates/README.md +63 -0
- package/payload/doc-templates/phases/templates/TASK_TEMPLATE.md +302 -0
- package/payload/doc-templates/phases/templates/task_template_prompt.md +229 -0
- package/payload/doc-templates/templates/ARCHITECTURE_GUIDE_TEMPLATE.md +250 -0
- package/payload/doc-templates/templates/DESIGN_SYSTEM_TEMPLATE.md +336 -0
- package/payload/doc-templates/templates/DONE_TEMPLATE.md +21 -0
- package/payload/doc-templates/templates/PHASES_README_TEMPLATE.md +144 -0
- package/payload/doc-templates/templates/PHASE_README_TEMPLATE.md +142 -0
- package/payload/doc-templates/templates/PRD_TEMPLATE.md +348 -0
- package/payload/doc-templates/templates/PRODUCTION_ROADMAP_TEMPLATE.md +168 -0
- package/payload/doc-templates/templates/QUEUE_TEMPLATE.md +17 -0
- package/payload/doc-templates/templates/TECH_STACK_TEMPLATE.md +199 -0
- package/payload/scripts/check-task.mjs +98 -0
- package/payload/scripts/check-versions.mjs +113 -0
- package/payload/scripts/phase-status.mjs +69 -0
- package/payload/scripts/set-fact.mjs +86 -0
- package/payload/skills/add-data-layer/SKILL.md +129 -0
- package/payload/skills/check-task/SKILL.md +35 -0
- package/payload/skills/check-versions/SKILL.md +47 -0
- package/payload/skills/create-prd/SKILL.md +90 -0
- package/payload/skills/domain-model/SKILL.md +90 -0
- package/payload/skills/kickstart/SKILL.md +157 -0
- package/payload/skills/log-decision/SKILL.md +65 -0
- package/payload/skills/next/SKILL.md +65 -0
- package/payload/skills/plan-phase/SKILL.md +108 -0
- package/payload/skills/remember/SKILL.md +77 -0
- package/payload/skills/start-session/SKILL.md +52 -0
- package/payload/skills/update-workstreams/SKILL.md +60 -0
- package/src/cli.mjs +115 -0
- package/src/commands/add.mjs +39 -0
- package/src/commands/artifacts.mjs +24 -0
- package/src/commands/doctor.mjs +292 -0
- package/src/commands/init.mjs +147 -0
- package/src/commands/knowledge.mjs +148 -0
- package/src/commands/list.mjs +61 -0
- package/src/commands/status.mjs +96 -0
- package/src/commands/update.mjs +128 -0
- package/src/lib/adr-tripwire.mjs +171 -0
- package/src/lib/artifacts.mjs +124 -0
- package/src/lib/config.mjs +43 -0
- package/src/lib/fs.mjs +46 -0
- package/src/lib/log.mjs +22 -0
- package/src/lib/paths.mjs +36 -0
- package/src/lib/progress.mjs +26 -0
- package/src/lib/skills.mjs +42 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: next
|
|
3
|
+
description: Figure out where the project is in the Groundwork flow and recommend the next step. Use when the user asks "what's next", "where are we", "what should I do now", or seems unsure which Groundwork skill to run.
|
|
4
|
+
argument-hint: "[optional: area to focus on]"
|
|
5
|
+
allowed-tools: Read, Glob, Grep
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Next - Groundwork Flow Guide
|
|
9
|
+
|
|
10
|
+
Act as the project's flow coach. Inspect the current state, tell the user exactly where
|
|
11
|
+
they are in the Groundwork lifecycle, and recommend the single best next action (with a
|
|
12
|
+
short why). This skill never edits files — it orients and points.
|
|
13
|
+
|
|
14
|
+
## How to assess (read these, in order)
|
|
15
|
+
|
|
16
|
+
1. `docs/TECH_STACK.md` / `docs/PRODUCTION_ROADMAP.md` — do the project docs exist yet?
|
|
17
|
+
2. `docs/STACK_MAP.md` — are versions pinned and recently audited (`Last audited` date)?
|
|
18
|
+
3. `docs/PRD.md` (or `docs/PRD_*.md`) — is there a PRD?
|
|
19
|
+
4. `docs/phases/phase*/PHASE*_TASKS.md` — do task files exist, and how many checkboxes
|
|
20
|
+
are open vs done? (For exact counts, suggest `groundwork status` or
|
|
21
|
+
`docs/.groundwork/scripts/phase-status.mjs`.)
|
|
22
|
+
5. `docs/WORKSTREAMS.md` — any active streams in flight?
|
|
23
|
+
6. `docs/QUEUE.md` (or legacy `docs/BACKLOG.md`) — what is the next unblocked `- [ ]` item in `## Queue`?
|
|
24
|
+
7. `docs/DECISIONS.md` — recent or pending ADRs.
|
|
25
|
+
|
|
26
|
+
## Decision tree
|
|
27
|
+
|
|
28
|
+
Pick the FIRST matching state and recommend its action:
|
|
29
|
+
|
|
30
|
+
| State detected | Recommend |
|
|
31
|
+
| -------------- | --------- |
|
|
32
|
+
| No `PRD.md` (and no project docs) | `/create-prd "<idea>"` — **first step**: define the product before scaffolding |
|
|
33
|
+
| PRD exists, but no `TECH_STACK.md` / `PRODUCTION_ROADMAP.md` | `/kickstart` — scaffold the project docs **from the PRD** |
|
|
34
|
+
| Designing and terminology is fuzzy/conflicting, or no `CONTEXT.md` yet | `/domain-model` — pin the ubiquitous language (+ bounded contexts) |
|
|
35
|
+
| Docs exist, a `package.json` is present, `STACK_MAP` never audited or stale | `/check-versions` — pin to latest stable before building |
|
|
36
|
+
| Roadmap exists but no `PHASE*_TASKS.md` | `/plan-phase 1 "<name>"` — break the first phase into tasks |
|
|
37
|
+
| Task file has open `- [ ]` items, no active stream | `/start-session`, then work the next task; `/check-task <id>` as you finish |
|
|
38
|
+
| Work in progress | `/update-workstreams` to record state; `/log-decision` for any new choices |
|
|
39
|
+
| All tasks in current phase done | `groundwork status` to confirm, then `/plan-phase N+1` for the next phase |
|
|
40
|
+
| A reusable cross-project lesson surfaced, knowledge repo configured | `/remember` it (or `/remember --adr` if it's a real decision with trade-offs) |
|
|
41
|
+
| A lesson surfaced but no knowledge repo set (no `$GROUNDWORK_KNOWLEDGE` and no `~/.config/groundwork/config.json`) | `groundwork knowledge init` first, then `/remember` |
|
|
42
|
+
| A project-specific decision was made | `/log-decision` (writes this project's `docs/DECISIONS.md`) |
|
|
43
|
+
| A feature now needs persistence and there's no DB | `/add-data-layer` |
|
|
44
|
+
|
|
45
|
+
If several apply, choose the one earliest in the flow that is incomplete — finishing the
|
|
46
|
+
foundation beats jumping ahead.
|
|
47
|
+
|
|
48
|
+
## Output format
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
## Where you are
|
|
52
|
+
<one or two sentences: current phase/task, what's done, what's open>
|
|
53
|
+
|
|
54
|
+
## Recommended next step
|
|
55
|
+
**`/<skill> <args>`** — <why this, now>
|
|
56
|
+
|
|
57
|
+
## Also worth doing
|
|
58
|
+
- <secondary suggestion, if any>
|
|
59
|
+
- <blocker to clear, if any>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Keep it short and decisive — one clear recommendation, not a menu. If the user passed
|
|
63
|
+
`$ARGUMENTS`, bias the recommendation toward that area.
|
|
64
|
+
|
|
65
|
+
Focus area (optional): $ARGUMENTS
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: plan-phase
|
|
3
|
+
description: Generate a new phase task document using the project template
|
|
4
|
+
argument-hint: "<phase number> <phase name>"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Plan Phase - Task Document Generator
|
|
8
|
+
|
|
9
|
+
Generate a comprehensive phase task document following the Groundwork methodology.
|
|
10
|
+
|
|
11
|
+
## Obsidian Format (Required)
|
|
12
|
+
|
|
13
|
+
Both generated files start with YAML frontmatter and use `[[wikilinks]]` (to
|
|
14
|
+
`[[PRODUCTION_ROADMAP]]`, `[[ARCHITECTURE_GUIDE]]`, `[[TECH_STACK]]`, `[[DECISIONS]]`,
|
|
15
|
+
`[[WORKSTREAMS]]`, sibling phases). Frontmatter:
|
|
16
|
+
|
|
17
|
+
```yaml
|
|
18
|
+
# docs/phases/phaseN/README.md
|
|
19
|
+
---
|
|
20
|
+
title: "Phase N: [Name]"
|
|
21
|
+
tags: [groundwork/phase]
|
|
22
|
+
aliases: ["Phase N"]
|
|
23
|
+
---
|
|
24
|
+
# docs/phases/phaseN/PHASEN_TASKS.md
|
|
25
|
+
---
|
|
26
|
+
title: "Phase N Tasks"
|
|
27
|
+
tags: [groundwork/phase, groundwork/tasks]
|
|
28
|
+
aliases: ["Phase N Tasks"]
|
|
29
|
+
---
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Base the README on `docs/templates/PHASE_README_TEMPLATE.md` and the tasks file on
|
|
33
|
+
`docs/phases/templates/TASK_TEMPLATE.md` (both already have frontmatter — keep it, update titles).
|
|
34
|
+
|
|
35
|
+
## Instructions
|
|
36
|
+
|
|
37
|
+
Follow the 6-stage approach from `docs/phases/templates/task_template_prompt.md`:
|
|
38
|
+
|
|
39
|
+
1. **Discovery & scope** — read existing phase docs; review PRODUCTION_ROADMAP.md objectives.
|
|
40
|
+
2. **Technical analysis** — explore relevant code + patterns; check ARCHITECTURE_GUIDE.md
|
|
41
|
+
(constraints) and TECH_STACK.md. Read `docs/CONTEXT.md` (if present) and use its
|
|
42
|
+
canonical terms for task names, types, and APIs; if the phase introduces/sharpens
|
|
43
|
+
domain terms, run `/domain-model`.
|
|
44
|
+
3. **Impact & risk** — phase dependencies, risks + mitigations, blockers.
|
|
45
|
+
4. **Component inventory** — components to create/modify, mapped to packages; shared types.
|
|
46
|
+
5. **Task planning** — 4–6 major tasks, each 3–7 sub-steps, priorities
|
|
47
|
+
(CRITICAL/HIGH/MEDIUM/LOW), inter-task dependencies.
|
|
48
|
+
6. **Success criteria** — functional, technical, and quality criteria.
|
|
49
|
+
7. **Confidence report** — end the tasks file with a short `## Low-confidence decisions`
|
|
50
|
+
list: the choices in this plan you are least sure about and why (naming, boundaries,
|
|
51
|
+
library picks, ordering). Cheap to fix now, expensive after code exists.
|
|
52
|
+
|
|
53
|
+
## Task format
|
|
54
|
+
|
|
55
|
+
```markdown
|
|
56
|
+
### Task N: [Task Name]
|
|
57
|
+
|
|
58
|
+
**Priority**: [CRITICAL/HIGH/MEDIUM/LOW]
|
|
59
|
+
**Package**: [client/server/shared]
|
|
60
|
+
**Dependencies**: [Task numbers or "None"]
|
|
61
|
+
|
|
62
|
+
#### Sub-tasks
|
|
63
|
+
- [ ] N.1 [First sub-task]
|
|
64
|
+
- [ ] N.2 [Second sub-task]
|
|
65
|
+
|
|
66
|
+
#### Deliverables
|
|
67
|
+
- [What this task produces]
|
|
68
|
+
|
|
69
|
+
#### Interfaces / contracts (if the task introduces or changes any)
|
|
70
|
+
```ts
|
|
71
|
+
// signatures only — types, function/method signatures, endpoint shapes, table columns.
|
|
72
|
+
// No bodies. This is the level a reviewer can skim before code exists.
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
#### Rollback Plan (if high-risk)
|
|
76
|
+
- [How to revert if needed]
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Output
|
|
80
|
+
|
|
81
|
+
1. Generate `docs/phases/phaseN/README.md` (overview) and `PHASEN_TASKS.md` (detailed tasks).
|
|
82
|
+
2. Update PRODUCTION_ROADMAP.md to include the new phase.
|
|
83
|
+
3. Update `docs/QUEUE.md` (see below).
|
|
84
|
+
4. Summarize what was created.
|
|
85
|
+
|
|
86
|
+
## QUEUE.md Integration
|
|
87
|
+
|
|
88
|
+
After generating the tasks file, update `docs/QUEUE.md` — the inbound queue that bridges
|
|
89
|
+
Groundwork phase planning and whoever executes (you solo, or a coordinator's live multi-agent
|
|
90
|
+
dispatch). Completions land in `docs/DONE.md`, which this skill never writes.
|
|
91
|
+
|
|
92
|
+
```markdown
|
|
93
|
+
# QUEUE — <project>
|
|
94
|
+
|
|
95
|
+
## Queue
|
|
96
|
+
- [ ] (P1) Phase N: [Phase Name] — see [[phases/phaseN/PHASEN_TASKS]] for full breakdown · acceptance: all Phase N success criteria met
|
|
97
|
+
- [ ] (P2) <ad-hoc task added by David>
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Rules:
|
|
101
|
+
- **One Queue item per phase** — reference the PHASEN_TASKS file, don't inline sub-tasks; the executor reads the linked file for the full contract.
|
|
102
|
+
- **Priority mapping**: CRITICAL → P1, HIGH → P2, MEDIUM/LOW → P3. Default new phases to P1 unless the roadmap says otherwise.
|
|
103
|
+
- **If `docs/QUEUE.md` doesn't exist**, create it from `docs/templates/QUEUE_TEMPLATE.md`; if it exists, append to `## Queue` — never overwrite or reorder existing items (David owns this file).
|
|
104
|
+
- **Ad-hoc tasks** live alongside phase items in the Queue — don't remove or reorder them.
|
|
105
|
+
- **Never touch `docs/DONE.md`** — executor-only, append-only.
|
|
106
|
+
- **Legacy layout:** if the project still has a `docs/BACKLOG.md` with a `## Queue` section, append there instead and suggest migrating to the QUEUE/DONE split.
|
|
107
|
+
|
|
108
|
+
Phase to plan: $ARGUMENTS
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: remember
|
|
3
|
+
description: Capture a cross-project lesson in the central git knowledge repo — a quick dated note by default, or a formal ADR when it's a real decision with trade-offs (use --adr). Use when the user says "remember that…" or a reusable lesson/decision surfaces worth keeping beyond this project.
|
|
4
|
+
argument-hint: "[--adr] [tag:] <lesson>"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Remember - Capture a Lesson (central, git-level)
|
|
8
|
+
|
|
9
|
+
Persist cross-project lessons to the **central knowledge repo** so they live at git level
|
|
10
|
+
(shared across projects, machines, and the swarm). Two modes:
|
|
11
|
+
|
|
12
|
+
- **note** (default) — a quick dated one-liner in `notes/lessons.md`.
|
|
13
|
+
- **ADR** (`--adr`, or when the lesson is a real decision) — a formal record in
|
|
14
|
+
`adr/NNNN-*.md` with rationale and trade-offs, indexed in `INDEX.md`.
|
|
15
|
+
|
|
16
|
+
Use the ADR mode **only when** the lesson is *hard to reverse*, *surprising without
|
|
17
|
+
context*, and *a real trade-off*. Otherwise a note is enough.
|
|
18
|
+
|
|
19
|
+
## Resolve the knowledge repo (per-user — never hardcode)
|
|
20
|
+
|
|
21
|
+
Order: `$GROUNDWORK_KNOWLEDGE` → `knowledgeRepo` in
|
|
22
|
+
`${XDG_CONFIG_HOME:-$HOME/.config}/groundwork/config.json` → else stop and tell the user to
|
|
23
|
+
run `groundwork knowledge init` (or `link <dir>`).
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
KB="$GROUNDWORK_KNOWLEDGE"
|
|
27
|
+
[ -z "$KB" ] && KB=$(groundwork knowledge path 2>/dev/null | head -1)
|
|
28
|
+
[ -z "$KB" ] && { echo "No knowledge repo configured — run: groundwork knowledge init"; exit 1; }
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Always `git -C "$KB" pull --rebase --autostash 2>/dev/null || true` before writing (the
|
|
32
|
+
swarm/other machines push here too), and commit + push after.
|
|
33
|
+
|
|
34
|
+
## Note mode (default)
|
|
35
|
+
|
|
36
|
+
1. Parse `$ARGUMENTS` into an optional `tag:` prefix (lowercase, e.g. `tooling:`) + the lesson; infer a tag if none.
|
|
37
|
+
2. Resolve `$KB`. Pull.
|
|
38
|
+
3. Append to `$KB/notes/lessons.md` (create with `# Lessons` if absent), today's date:
|
|
39
|
+
```markdown
|
|
40
|
+
- [YYYY-MM-DD] (tag) <lesson> · src: <project/repo, if relevant>
|
|
41
|
+
```
|
|
42
|
+
4. `git add notes/lessons.md && git commit -m "note: <summary>" && git push 2>/dev/null || true`.
|
|
43
|
+
5. Confirm. If it reads like a real decision, offer to upgrade it with `--adr`.
|
|
44
|
+
|
|
45
|
+
## ADR mode (`--adr`)
|
|
46
|
+
|
|
47
|
+
1. Resolve `$KB`. Pull.
|
|
48
|
+
2. Gather (briefly, from `$ARGUMENTS` + conversation): **Context**, **Decision**,
|
|
49
|
+
**Consequences** (positive + negative), **Alternatives considered**.
|
|
50
|
+
3. Next number: scan `$KB/adr/` for the highest `NNNN`, increment, zero-pad to 4 digits.
|
|
51
|
+
4. Write `$KB/adr/NNNN-kebab-title.md`:
|
|
52
|
+
```markdown
|
|
53
|
+
# ADR-NNNN: <Title>
|
|
54
|
+
|
|
55
|
+
**Status**: Accepted
|
|
56
|
+
**Date**: YYYY-MM-DD
|
|
57
|
+
**Tags**: <comma-separated>
|
|
58
|
+
**Origin**: <project/repo, if relevant>
|
|
59
|
+
|
|
60
|
+
## Context
|
|
61
|
+
## Decision
|
|
62
|
+
## Consequences
|
|
63
|
+
**Positive**
|
|
64
|
+
**Negative**
|
|
65
|
+
## Alternatives Considered
|
|
66
|
+
```
|
|
67
|
+
5. Add a row to `$KB/INDEX.md` (ID, linked title, tags, date).
|
|
68
|
+
6. `git add adr/ INDEX.md && git commit -m "adr: NNNN <title>" && git push 2>/dev/null || true`.
|
|
69
|
+
7. If promoting an existing note, append `→ ADR-NNNN` to it in `notes/lessons.md`. Confirm and show the ADR.
|
|
70
|
+
|
|
71
|
+
## Scope
|
|
72
|
+
|
|
73
|
+
Cross-project lessons/decisions belong here. **Project-specific** decisions stay in that
|
|
74
|
+
project's `docs/DECISIONS.md` via `/log-decision`. Tool-agnostic by design — just git +
|
|
75
|
+
markdown, so any agent or human shares the repo.
|
|
76
|
+
|
|
77
|
+
## Lesson to capture: $ARGUMENTS
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: start-session
|
|
3
|
+
description: Load project context from Groundwork docs at the start of a session
|
|
4
|
+
argument-hint: "[optional: specific area to focus on]"
|
|
5
|
+
allowed-tools: Read, Glob, Grep
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Start Session - Groundwork Context Loader
|
|
9
|
+
|
|
10
|
+
Load context from the Groundwork docs to understand current project state, then summarize.
|
|
11
|
+
|
|
12
|
+
## Instructions
|
|
13
|
+
|
|
14
|
+
Read, in order (skip any that are absent):
|
|
15
|
+
|
|
16
|
+
1. **`docs/PRODUCTION_ROADMAP.md`** — the "Current Status" section is the primary entry point.
|
|
17
|
+
2. **`docs/WORKSTREAMS.md`** — live state of parallel streams (what's in flight now).
|
|
18
|
+
3. **Active phase** `docs/phases/phaseN/README.md` + `PHASEN_TASKS.md` — goals + task breakdown.
|
|
19
|
+
4. **`docs/DECISIONS.md`** — recent/relevant ADRs.
|
|
20
|
+
5. **`docs/CONTEXT.md`** — the ubiquitous language; use its canonical terms.
|
|
21
|
+
6. **`docs/QUEUE.md`** (or legacy `docs/BACKLOG.md`) — next unblocked Queue item + ad-hoc tasks.
|
|
22
|
+
7. **Summarize** (see format). `docs/ARTIFACTS.md` maps where everything lives if unsure.
|
|
23
|
+
|
|
24
|
+
## Output Format
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
## Session Context
|
|
28
|
+
**Active Phase**: Phase N - [Name]
|
|
29
|
+
**Current Task**: [description] **Status**: [In Progress / Blocked / …]
|
|
30
|
+
|
|
31
|
+
### Recent Progress
|
|
32
|
+
- [what was completed]
|
|
33
|
+
|
|
34
|
+
### Recent Decisions
|
|
35
|
+
- ADR-XXX: [Title] — [impact on current work]
|
|
36
|
+
|
|
37
|
+
### Blockers
|
|
38
|
+
- [blocking items]
|
|
39
|
+
|
|
40
|
+
### Next Backlog Item
|
|
41
|
+
- (P?) [next unblocked Queue item, or "No backlog found"]
|
|
42
|
+
|
|
43
|
+
### Suggested Next Steps
|
|
44
|
+
1. … 2. …
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
If `$ARGUMENTS` is given, focus the summary on that area.
|
|
48
|
+
|
|
49
|
+
## Decision relevance
|
|
50
|
+
|
|
51
|
+
Surface ADRs from the last 30 days, any related to the current phase, any "Proposed" ones
|
|
52
|
+
awaiting confirmation, and any that constrain the current task.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: update-workstreams
|
|
3
|
+
description: Update docs/WORKSTREAMS.md with the live state of parallel work streams
|
|
4
|
+
argument-hint: "[stream id or summary of progress]"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Update Workstreams - Live Parallel-Work Recorder
|
|
8
|
+
|
|
9
|
+
Update `docs/WORKSTREAMS.md` to reflect the live state of every parallel stream of work —
|
|
10
|
+
a table of **active streams**, not a single focus (the swarm-native replacement for
|
|
11
|
+
"current focus"). It is the live counterpart to `[[QUEUE]]`:
|
|
12
|
+
|
|
13
|
+
- **`QUEUE.md`** = the *inbound* queue (what to pick up next). Owned by the human + `/plan-phase`.
|
|
14
|
+
- **`WORKSTREAMS.md`** = the *live* state (what's in flight). Written by whoever's working,
|
|
15
|
+
including an external coordinator that pulls from QUEUE and opens a stream here. See
|
|
16
|
+
`[[GROUNDWORK_METHODOLOGY#multi-agent-seam]]`.
|
|
17
|
+
- **`DONE.md`** = the *completion log* (append-only, written by the executor).
|
|
18
|
+
|
|
19
|
+
Working alone is just the one-row case — the model scales solo → fleet unchanged.
|
|
20
|
+
|
|
21
|
+
Preserve the file's frontmatter; use `[[wikilinks]]` (`[[DECISIONS#adr-005|ADR-005]]`, `[[QUEUE]]`).
|
|
22
|
+
|
|
23
|
+
**Write only the core; preserve coordinator extensions.** Under a multi-agent coordinator,
|
|
24
|
+
`WORKSTREAMS.md` may carry coordinator-only sections after the `<!-- coordinator extensions -->`
|
|
25
|
+
fence (Open PRs, Cutover Gates, Needs David, Risks, Rooms, Decisions Recorded). You edit
|
|
26
|
+
**only** `## Active Streams` and `## Recently Closed`; copy everything from that fence onward
|
|
27
|
+
through **verbatim** on every rewrite — never edit or drop it. Within Active Streams, touch
|
|
28
|
+
only the row(s) you own, and if another agent may be writing, re-read immediately before
|
|
29
|
+
writing (read-before-write) so you don't clobber a concurrent row.
|
|
30
|
+
|
|
31
|
+
## Instructions
|
|
32
|
+
|
|
33
|
+
1. Read `docs/WORKSTREAMS.md`.
|
|
34
|
+
2. From `$ARGUMENTS`/context: new stream → add a row; progress → update its Status / Last
|
|
35
|
+
note; finished → move the row to `## Recently Closed` with an outcome.
|
|
36
|
+
3. Keep one row per active stream; update the `Last Updated` timestamp; confirm the result.
|
|
37
|
+
|
|
38
|
+
Write grammar is **`workstreams.v1`**: the 6-col Active Streams table below. Do not write a
|
|
39
|
+
5-col Lanes table (`Lane | Owner | State | Current slice | Next GO`) — that shape is
|
|
40
|
+
parse-only.
|
|
41
|
+
|
|
42
|
+
## Format
|
|
43
|
+
|
|
44
|
+
```markdown
|
|
45
|
+
## Active Streams
|
|
46
|
+
|
|
47
|
+
| Stream | Owner / Agent | Branch · Worktree | Status | Blocker | Last note |
|
|
48
|
+
| ----------------- | ------------- | ---------------------------- | -------------- | ------- | ------------------------------- |
|
|
49
|
+
| Phase 2 · Auth | agent-api | `feat/phase2-auth` · wt-auth | 🚧 In Progress | None | JWT done, RBAC next |
|
|
50
|
+
| Phase 3 · Search | — | — | ⏳ Queued | Phase 2 | pulled from [[QUEUE]] |
|
|
51
|
+
|
|
52
|
+
## Recently Closed
|
|
53
|
+
- ✅ Phase 1 · Foundation — agent-api · `feat/phase1` · merged YYYY-MM-DD
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Guidelines: status = 🚧 In Progress · 🔍 In Review · ⏳ Queued · ⛔ Blocked · ✅ Done. Record
|
|
57
|
+
branch + worktree so any agent can resume the exact context. `Blocker` names the dependency
|
|
58
|
+
(another stream, a decision, a person), not just "yes". Dates `YYYY-MM-DD`.
|
|
59
|
+
|
|
60
|
+
Progress to record: $ARGUMENTS
|
package/src/cli.mjs
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { init } from "./commands/init.mjs";
|
|
4
|
+
import { update } from "./commands/update.mjs";
|
|
5
|
+
import { add } from "./commands/add.mjs";
|
|
6
|
+
import { list } from "./commands/list.mjs";
|
|
7
|
+
import { status } from "./commands/status.mjs";
|
|
8
|
+
import { knowledge } from "./commands/knowledge.mjs";
|
|
9
|
+
import { artifacts } from "./commands/artifacts.mjs";
|
|
10
|
+
import { doctor } from "./commands/doctor.mjs";
|
|
11
|
+
import { log, bold, cyan, dim } from "./lib/log.mjs";
|
|
12
|
+
|
|
13
|
+
const argv = process.argv.slice(2);
|
|
14
|
+
|
|
15
|
+
/** Split flags (--foo) from positional args. */
|
|
16
|
+
function parse(args) {
|
|
17
|
+
const flags = {};
|
|
18
|
+
const pos = [];
|
|
19
|
+
for (const a of args) {
|
|
20
|
+
if (a.startsWith("--")) flags[a.slice(2)] = true;
|
|
21
|
+
else pos.push(a);
|
|
22
|
+
}
|
|
23
|
+
return { flags, pos };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function version() {
|
|
27
|
+
const pkg = JSON.parse(
|
|
28
|
+
readFileSync(new URL("../package.json", import.meta.url), "utf8")
|
|
29
|
+
);
|
|
30
|
+
console.log(pkg.version);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function help() {
|
|
34
|
+
console.log(
|
|
35
|
+
[
|
|
36
|
+
bold("groundwork") + dim(" — bolt the Groundwork AI workflow onto any repo"),
|
|
37
|
+
"",
|
|
38
|
+
bold("Usage:") + " groundwork <command> [dir] [flags]",
|
|
39
|
+
"",
|
|
40
|
+
bold("Commands:"),
|
|
41
|
+
` ${cyan("init")} [dir] Install skills + IDE mirrors + docs into a repo (default: .)`,
|
|
42
|
+
` ${cyan("update")} [dir] Upgrade skills + scripts in place (keeps your docs); ${dim("--all")} adds new skills, ${dim("--docs")} refreshes generic reference docs`,
|
|
43
|
+
` ${cyan("add")} <skill> [dir] Add one optional skill (e.g. add-data-layer)`,
|
|
44
|
+
` ${cyan("list")} [dir] List available skills and install state`,
|
|
45
|
+
` ${cyan("status")} [dir] Show live workstreams, next backlog item, phase progress`,
|
|
46
|
+
` ${cyan("doctor")} [dir] Flag doc↔reality drift (orphan links, stale phases/versions)`,
|
|
47
|
+
` ${cyan("knowledge")} <cmd> Central ADR/lessons repo (init | link | sync [--push] | path)`,
|
|
48
|
+
` ${cyan("artifacts")} [dir] Regenerate docs/ARTIFACTS.md from the manifest`,
|
|
49
|
+
` ${cyan("help")} Show this help`,
|
|
50
|
+
` ${cyan("version")} Print version`,
|
|
51
|
+
"",
|
|
52
|
+
bold("Flags:"),
|
|
53
|
+
` --minimal init only the core 5 skills`,
|
|
54
|
+
` --force overwrite files that already exist`,
|
|
55
|
+
` --json machine-readable output (doctor / status / list)`,
|
|
56
|
+
"",
|
|
57
|
+
bold("Examples:"),
|
|
58
|
+
dim(" npx github:davidbalzan/groundwork init"),
|
|
59
|
+
dim(" groundwork init . --minimal"),
|
|
60
|
+
dim(" groundwork add data-layer"),
|
|
61
|
+
dim(" groundwork status"),
|
|
62
|
+
].join("\n")
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const [cmd, ...rest] = argv;
|
|
67
|
+
const { flags, pos } = parse(rest);
|
|
68
|
+
|
|
69
|
+
try {
|
|
70
|
+
switch (cmd) {
|
|
71
|
+
case "init":
|
|
72
|
+
init(pos[0], flags);
|
|
73
|
+
break;
|
|
74
|
+
case "update":
|
|
75
|
+
update(pos[0], flags);
|
|
76
|
+
break;
|
|
77
|
+
case "add":
|
|
78
|
+
add(pos[0], pos[1]);
|
|
79
|
+
break;
|
|
80
|
+
case "list":
|
|
81
|
+
list(pos[0], flags);
|
|
82
|
+
break;
|
|
83
|
+
case "status":
|
|
84
|
+
status(pos[0], flags);
|
|
85
|
+
break;
|
|
86
|
+
case "knowledge":
|
|
87
|
+
knowledge(pos[0], pos[1], flags);
|
|
88
|
+
break;
|
|
89
|
+
case "artifacts":
|
|
90
|
+
artifacts(pos[0]);
|
|
91
|
+
break;
|
|
92
|
+
case "doctor":
|
|
93
|
+
doctor(pos[0], flags);
|
|
94
|
+
break;
|
|
95
|
+
case "version":
|
|
96
|
+
case "--version":
|
|
97
|
+
case "-v":
|
|
98
|
+
version();
|
|
99
|
+
break;
|
|
100
|
+
case "help":
|
|
101
|
+
case "--help":
|
|
102
|
+
case "-h":
|
|
103
|
+
case undefined:
|
|
104
|
+
help();
|
|
105
|
+
break;
|
|
106
|
+
default:
|
|
107
|
+
log.err(`Unknown command: ${cmd}`);
|
|
108
|
+
help();
|
|
109
|
+
process.exitCode = 1;
|
|
110
|
+
}
|
|
111
|
+
} catch (err) {
|
|
112
|
+
log.err(err.message);
|
|
113
|
+
if (process.env.DEBUG) console.error(err);
|
|
114
|
+
process.exitCode = 1;
|
|
115
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { PAYLOAD_SKILLS, TARGET } from "../lib/paths.mjs";
|
|
3
|
+
import { copyFileSafe, exists } from "../lib/fs.mjs";
|
|
4
|
+
import { loadSkills, mirrorFiles } from "../lib/skills.mjs";
|
|
5
|
+
import fs from "node:fs";
|
|
6
|
+
import { log, cyan } from "../lib/log.mjs";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Add a single optional skill (e.g. after a `--minimal` install, or to pull in
|
|
10
|
+
* `add-data-layer`). Copies the SKILL.md and regenerates that skill's mirrors.
|
|
11
|
+
*/
|
|
12
|
+
export function add(skillName, targetDir) {
|
|
13
|
+
const root = path.resolve(targetDir || ".");
|
|
14
|
+
if (!skillName) {
|
|
15
|
+
log.err("Usage: groundwork add <skill-name> (see `groundwork list`)");
|
|
16
|
+
process.exitCode = 1;
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
const src = path.join(PAYLOAD_SKILLS, skillName, "SKILL.md");
|
|
20
|
+
if (!exists(src)) {
|
|
21
|
+
log.err(`Unknown skill "${skillName}". Run \`groundwork list\`.`);
|
|
22
|
+
process.exitCode = 1;
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
copyFileSafe(src, path.join(root, TARGET.skills, skillName, "SKILL.md"), {
|
|
27
|
+
force: true,
|
|
28
|
+
});
|
|
29
|
+
const [skill] = loadSkills([skillName]);
|
|
30
|
+
for (const f of mirrorFiles([skill], {
|
|
31
|
+
cursorDir: path.join(root, TARGET.cursor),
|
|
32
|
+
vscodeDir: path.join(root, TARGET.vscode),
|
|
33
|
+
})) {
|
|
34
|
+
fs.mkdirSync(path.dirname(f.rel), { recursive: true });
|
|
35
|
+
fs.writeFileSync(f.rel, f.content);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
log.ok(`Added skill ${cyan("/" + skillName)} (+ Cursor/VS Code mirrors).`);
|
|
39
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { TARGET } from "../lib/paths.mjs";
|
|
3
|
+
import { writeText, exists } from "../lib/fs.mjs";
|
|
4
|
+
import { renderArtifactsDoc } from "../lib/artifacts.mjs";
|
|
5
|
+
import { log, cyan } from "../lib/log.mjs";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Regenerate docs/ARTIFACTS.md in a target project from the single-source manifest.
|
|
9
|
+
* (init/update call writeArtifacts directly; this is the manual on-demand entry point.)
|
|
10
|
+
*/
|
|
11
|
+
export function artifacts(targetDir) {
|
|
12
|
+
const root = path.resolve(targetDir || ".");
|
|
13
|
+
if (!exists(path.join(root, TARGET.docs))) {
|
|
14
|
+
log.warn("No docs/ here. Run `groundwork init` first.");
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
writeArtifacts(root);
|
|
18
|
+
log.ok(`Regenerated ${cyan("docs/ARTIFACTS.md")} from the manifest.`);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** Write docs/ARTIFACTS.md from the manifest. Shared by init/update. */
|
|
22
|
+
export function writeArtifacts(root) {
|
|
23
|
+
writeText(path.join(root, TARGET.docs, "ARTIFACTS.md"), renderArtifactsDoc());
|
|
24
|
+
}
|