workflow-toolkit 1.0.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/.agents/skills/ponytail/SKILL.md +111 -0
- package/.agents/skills/ponytail-audit/SKILL.md +37 -0
- package/.agents/skills/ponytail-debt/SKILL.md +41 -0
- package/.agents/skills/ponytail-gain/SKILL.md +47 -0
- package/.agents/skills/ponytail-help/SKILL.md +70 -0
- package/.agents/skills/ponytail-review/SKILL.md +52 -0
- package/.agents/skills/prompt-review/SKILL.md +60 -0
- package/.agents/skills/wtk/SKILL.md +64 -0
- package/.agents/skills/wtk/references/artifacts.md +82 -0
- package/.agents/skills/wtk/references/evidence.md +68 -0
- package/.agents/skills/wtk/references/git.md +75 -0
- package/.agents/skills/wtk/references/test-contract.md +76 -0
- package/.agents/skills/wtk/references/validation.md +127 -0
- package/.agents/skills/wtk-config/SKILL.md +102 -0
- package/.agents/skills/wtk-config/assets/agents/claude/deep-reviewer.md +40 -0
- package/.agents/skills/wtk-config/assets/agents/claude/designer.md +57 -0
- package/.agents/skills/wtk-config/assets/agents/claude/explorer.md +41 -0
- package/.agents/skills/wtk-config/assets/agents/claude/implementer.md +57 -0
- package/.agents/skills/wtk-config/assets/agents/claude/planner.md +68 -0
- package/.agents/skills/wtk-config/assets/agents/claude/verifier.md +80 -0
- package/.agents/skills/wtk-config/assets/agents/codex/deep-reviewer.toml +41 -0
- package/.agents/skills/wtk-config/assets/agents/codex/designer.toml +55 -0
- package/.agents/skills/wtk-config/assets/agents/codex/explorer.toml +35 -0
- package/.agents/skills/wtk-config/assets/agents/codex/implementer.toml +52 -0
- package/.agents/skills/wtk-config/assets/agents/codex/planner.toml +66 -0
- package/.agents/skills/wtk-config/assets/agents/codex/verifier.toml +78 -0
- package/.agents/skills/wtk-config/assets/agents/cursor/deep-reviewer.md +38 -0
- package/.agents/skills/wtk-config/assets/agents/cursor/designer.md +55 -0
- package/.agents/skills/wtk-config/assets/agents/cursor/explorer.md +39 -0
- package/.agents/skills/wtk-config/assets/agents/cursor/implementer.md +55 -0
- package/.agents/skills/wtk-config/assets/agents/cursor/planner.md +66 -0
- package/.agents/skills/wtk-config/assets/agents/cursor/verifier.md +79 -0
- package/.agents/skills/wtk-config/scripts/ad-index.py +123 -0
- package/.agents/skills/wtk-config/scripts/repository_intelligence.py +671 -0
- package/.agents/skills/wtk-config/scripts/workflow_config.py +972 -0
- package/.agents/skills/wtk-deep-review/SKILL.md +164 -0
- package/.agents/skills/wtk-deep-review/assets/PROMPT.md +56 -0
- package/.agents/skills/wtk-deep-review/assets/REVIEW_UI.html +1340 -0
- package/.agents/skills/wtk-deep-review/assets/findings.schema.json +113 -0
- package/.agents/skills/wtk-deep-review/references/context-pack.md +88 -0
- package/.agents/skills/wtk-deep-review/references/orchestration.md +164 -0
- package/.agents/skills/wtk-deep-review/references/output-contracts.md +149 -0
- package/.agents/skills/wtk-deep-review/references/publish-github.md +83 -0
- package/.agents/skills/wtk-deep-review/references/state-and-learnings.md +64 -0
- package/.agents/skills/wtk-deep-review/references/subagent-runtimes.md +33 -0
- package/.agents/skills/wtk-deep-review/references/taxonomy.md +70 -0
- package/.agents/skills/wtk-deep-review/scripts/_common.py +371 -0
- package/.agents/skills/wtk-deep-review/scripts/build_jobs.py +561 -0
- package/.agents/skills/wtk-deep-review/scripts/build_knowledge.py +349 -0
- package/.agents/skills/wtk-deep-review/scripts/build_manifest.py +479 -0
- package/.agents/skills/wtk-deep-review/scripts/graft_context.py +160 -0
- package/.agents/skills/wtk-deep-review/scripts/graphify_context.py +75 -0
- package/.agents/skills/wtk-deep-review/scripts/merge_findings.py +313 -0
- package/.agents/skills/wtk-deep-review/scripts/render_html.py +240 -0
- package/.agents/skills/wtk-deep-review/scripts/render_review.py +282 -0
- package/.agents/skills/wtk-deep-review/scripts/run_jobs.py +436 -0
- package/.agents/skills/wtk-deep-review/scripts/token_metrics.py +369 -0
- package/.agents/skills/wtk-discover/SKILL.md +270 -0
- package/.agents/skills/wtk-discover/references/document-format.md +149 -0
- package/.agents/skills/wtk-implement/SKILL.md +95 -0
- package/.agents/skills/wtk-implement/references/checklist-format.md +116 -0
- package/.agents/skills/wtk-implement/references/screens.md +129 -0
- package/.agents/skills/wtk-implement/references/test-policy.md +152 -0
- package/.agents/skills/wtk-implement/references/verify.md +297 -0
- package/.agents/skills/wtk-knowledge-check/SKILL.md +16 -0
- package/.agents/skills/wtk-knowledge-check/scripts/check.ts +502 -0
- package/.agents/skills/wtk-knowledge-check/scripts/cli.ts +32 -0
- package/.agents/skills/wtk-knowledge-check/scripts/frontmatter.ts +44 -0
- package/.agents/skills/wtk-lean/.skill-meta.json +6 -0
- package/.agents/skills/wtk-lean/NOTICE.md +18 -0
- package/.agents/skills/wtk-lean/SKILL.md +137 -0
- package/.agents/skills/wtk-lean/references/build.md +168 -0
- package/.agents/skills/wtk-lean/references/checks.md +253 -0
- package/.agents/skills/wtk-lean/references/memory.md +156 -0
- package/.agents/skills/wtk-lean/references/plan.md +514 -0
- package/.agents/skills/wtk-lean/references/verify.md +336 -0
- package/.agents/skills/wtk-lean/scripts/check_commit.py +121 -0
- package/.agents/skills/wtk-lean/scripts/fixtures/checks.md +98 -0
- package/.agents/skills/wtk-lean/scripts/fixtures/plan.md +119 -0
- package/.agents/skills/wtk-lean/scripts/fixtures/verification.md +41 -0
- package/.agents/skills/wtk-lean/scripts/lessons.py +412 -0
- package/.agents/skills/wtk-lean/scripts/selftest.py +401 -0
- package/.agents/skills/wtk-lean/scripts/validate_checks.py +417 -0
- package/.agents/skills/wtk-lean/scripts/validate_plan.py +580 -0
- package/.agents/skills/wtk-lean/scripts/validate_verification.py +357 -0
- package/.agents/skills/wtk-plan/SKILL.md +102 -0
- package/.agents/skills/wtk-plan/references/document-format.md +222 -0
- package/.agents/skills/wtk-qa/SKILL.md +14 -0
- package/.agents/skills/wtk-qa-execute/SKILL.md +115 -0
- package/.agents/skills/wtk-qa-execute/references/fix-loop.md +23 -0
- package/.agents/skills/wtk-qa-execute/references/session-protocol.md +25 -0
- package/.agents/skills/wtk-qa-plan/SKILL.md +111 -0
- package/.agents/skills/wtk-qa-plan/references/profile.md +35 -0
- package/.agents/skills/wtk-ship/SKILL.md +49 -0
- package/.agents/skills/wtk-ship/remediation.py +170 -0
- package/.agents/skills/wtk-ship/scripts/close_feature.py +83 -0
- package/.agents/skills/wtk-ship/scripts/review_convergence.py +373 -0
- package/.wtk.toml.example +93 -0
- package/AGENTS.md +129 -0
- package/NOTICE.md +12 -0
- package/README.md +440 -0
- package/bin/wtk.js +25 -0
- package/docs/toolkit/README.md +56 -0
- package/docs/toolkit/decisions.md +61 -0
- package/docs/toolkit/guidelines/CONTEXT-BUDGET.md +64 -0
- package/docs/toolkit/guidelines/DX.md +67 -0
- package/docs/toolkit/guidelines/FRONTEND.md +73 -0
- package/docs/toolkit/guidelines/KNOWLEDGE-WIKI.md +128 -0
- package/docs/toolkit/guidelines/MODELING.md +134 -0
- package/docs/toolkit/guidelines/QA-EXECUTION.md +46 -0
- package/docs/toolkit/guidelines/QA-SCENARIOS.md +165 -0
- package/docs/toolkit/guidelines/REVIEW-ROUNDS.md +160 -0
- package/docs/toolkit/guidelines/SECURITY.md +160 -0
- package/docs/toolkit/guidelines/UI-UX.md +117 -0
- package/docs/toolkit/guidelines/WORKFLOW-MEMORY.md +73 -0
- package/docs/toolkit/guidelines.md +50 -0
- package/docs/toolkit/loop.md +77 -0
- package/docs/toolkit/purpose.md +51 -0
- package/docs/toolkit/repository-intelligence.md +53 -0
- package/docs/toolkit/reviews.md +77 -0
- package/knowledge/AGENTS.md +316 -0
- package/knowledge/raw/README.md +17 -0
- package/package.json +74 -0
- package/scripts/install_security_skills.py +816 -0
- package/scripts/installer/engine.js +254 -0
- package/scripts/installer/knowledge.js +28 -0
- package/scripts/installer/packets.js +77 -0
- package/scripts/installer/terminal.js +98 -0
- package/scripts/installer/transaction.js +75 -0
- package/skills-lock.json +92 -0
- package/templates/adoption/agents/core.md +23 -0
- package/templates/adoption/agents/quality.md +3 -0
- package/templates/adoption/knowledge/wiki/architecture/index.md +3 -0
- package/templates/adoption/knowledge/wiki/decisions/index.md +3 -0
- package/templates/adoption/knowledge/wiki/design/index.md +3 -0
- package/templates/adoption/knowledge/wiki/domain/index.md +3 -0
- package/templates/adoption/knowledge/wiki/index.md +3 -0
- package/templates/adoption/knowledge/wiki/log.md +3 -0
- package/templates/adoption/knowledge/wiki/open-questions/index.md +3 -0
- package/templates/adoption/knowledge/wiki/product/index.md +3 -0
- package/templates/adoption/knowledge/wiki/research/index.md +3 -0
- package/templates/adoption/product/AGENT-CONTEXT.md +25 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: planner
|
|
3
|
+
description: >-
|
|
4
|
+
Workflow Toolkit planner for discovery and approved Lean planning. Does not implement product code.
|
|
5
|
+
model: cursor-grok-4.6[effort=high]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
You are the **planner**. Discover unresolved choices, then prepare the approved Lean plan and
|
|
9
|
+
checks before dispatching one sequential builder. Do not implement product code.
|
|
10
|
+
|
|
11
|
+
## Load
|
|
12
|
+
|
|
13
|
+
- Skill `wtk-lean` for integrated feature planning; use `wtk-discover` or `wtk-plan` only when
|
|
14
|
+
the user's entry is explicitly modular
|
|
15
|
+
- Approved source and the feature's `plan.md` / `checks.md` when present
|
|
16
|
+
- `uiux.md`, approved source/export, and `docs/toolkit/guidelines/UI-UX.md` when a screen or visual reference is in scope
|
|
17
|
+
- `.agents/skills/wtk/references/test-contract.md` — derive each check's proof at its owning layer
|
|
18
|
+
- `.specs/AD-INDEX.md`; an AD body with `rg -A 20 '^### AD-NNN' .specs/STATE.md`
|
|
19
|
+
- `docs/toolkit/guidelines/SECURITY.md` heading `## 2. At Specify — declare the surfaces` if the spec touches a surface
|
|
20
|
+
- `docs/toolkit/guidelines/MODELING.md` if modeling a domain or boundary
|
|
21
|
+
- `docs/toolkit/guidelines/FRONTEND.md` — only the heading the slice disputes, never the whole file
|
|
22
|
+
|
|
23
|
+
## Do not load
|
|
24
|
+
|
|
25
|
+
Skill `wtk-implement`, all of `.specs/STATE.md`, all of `FRONTEND.md`, the Execute transcript.
|
|
26
|
+
|
|
27
|
+
## Deliver
|
|
28
|
+
|
|
29
|
+
For integrated Lean, deliver `plan.md` and `checks.md`; direct modular entries retain their
|
|
30
|
+
`.design/`, `.tasks/`, and `.checks/` artifacts. A slice is observable and whole; one builder
|
|
31
|
+
works sequentially within the declared context budget.
|
|
32
|
+
|
|
33
|
+
Closing packet for the builder: cited ACs, the current Lean slice from `checks.md` (or the
|
|
34
|
+
modular task payload), proof selectors, and one neighboring context when needed.
|
|
35
|
+
|
|
36
|
+
A search or trace: spawn `explorer`. Do not search the product tree for that.
|
|
37
|
+
|
|
38
|
+
## Repository intelligence
|
|
39
|
+
|
|
40
|
+
- For a named module/domain boundary, responsibility transfer, shared abstraction, central flow, or unresolved architectural risk, have Explorer query fresh Graphify before freezing the plan.
|
|
41
|
+
- Do not duplicate code discovery; use returned architectural pointers and let Explorer route unknown implementation locations to Graft.
|
|
42
|
+
|
|
43
|
+
## Classification and routing
|
|
44
|
+
|
|
45
|
+
Before dispatching any phase or gate, state: `Classification: <tier>`; `Facts: <bounded surface,
|
|
46
|
+
behavior, blast radius, and contradictory evidence>`; `Validation: <cheapest discriminating layer>`.
|
|
47
|
+
Use this vocabulary as intent guidance, confirmed by repository evidence:
|
|
48
|
+
|
|
49
|
+
- `cross-feature change` → at least Medium feature; map every affected product promise.
|
|
50
|
+
- `feature` → at least Small feature; size upward as needed.
|
|
51
|
+
- `direct correction` / `UI-only correction` → direct correction only when one bounded surface,
|
|
52
|
+
existing component/reference, preserved behavior, and no unresolved or listed risk surface hold.
|
|
53
|
+
- `issue`, `bug`, `refactor`, `small change`, and `UI change` → neutral; infer from the outcome.
|
|
54
|
+
|
|
55
|
+
For a qualifying UI-only correction, run inspect → implement → one targeted integration check → one
|
|
56
|
+
atomic commit. Do not dispatch spec/tasks, Verifier, QA, deep review, repeated validation, or full
|
|
57
|
+
e2e. Do not retest shadcn/TanStack internals. UI presence or a missing selector is not escalation.
|
|
58
|
+
If named repository evidence contradicts the fast path, name it before escalating; file count alone
|
|
59
|
+
does not reclassify.
|
|
60
|
+
Examples: CRM banner → existing shadcn toast and existing table → TanStack/shadcn data table stay
|
|
61
|
+
direct corrections when trigger, message, and table semantics are unchanged.
|
|
62
|
+
|
|
63
|
+
## Product context
|
|
64
|
+
|
|
65
|
+
Read `docs/product/AGENT-CONTEXT.md` before work. Follow its role/task route, load only cited paths
|
|
66
|
+
or headings, and name missing required context as a gap.
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: verifier
|
|
3
|
+
description: >-
|
|
4
|
+
Fresh independent proof session for a complete feature's technical, QA Plan, or QA Execute phase. Author ≠ verifier. Writes checkout-local verification.md.
|
|
5
|
+
model: cursor-grok-4.6[effort=medium]
|
|
6
|
+
is_background: true
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
You are the **verifier**. You did not write this code. Receive a fresh role packet,
|
|
10
|
+
exclude author and operator context, re-derive coverage evidence-or-zero, and keep
|
|
11
|
+
every artifact in the active checkout.
|
|
12
|
+
|
|
13
|
+
## Packet (this only)
|
|
14
|
+
|
|
15
|
+
- `phase`: exactly one of `technical`, `wtk-qa-plan`, or `wtk-qa-execute`.
|
|
16
|
+
- Feature `plan.md` and `checks.md` (criteria and proofs = source of truth).
|
|
17
|
+
- Complete feature branch diff / commit range.
|
|
18
|
+
- Tests in scope.
|
|
19
|
+
- Assigned evidence named by the packet.
|
|
20
|
+
- Skill `wtk-lean`, the phase procedure.
|
|
21
|
+
- `.agents/skills/wtk/references/test-contract.md` only if a case looks hollow or uses the wrong layer.
|
|
22
|
+
- `docs/toolkit/guidelines/UI-UX.md` and the pointed `uiux.md` row when a visual AC is in scope.
|
|
23
|
+
|
|
24
|
+
## Do not load
|
|
25
|
+
|
|
26
|
+
The Implementer's transcript, the operator handoff, all of `.specs/STATE.md`, and how
|
|
27
|
+
the author thought.
|
|
28
|
+
|
|
29
|
+
## Independence and tree boundary
|
|
30
|
+
|
|
31
|
+
- This is a fresh session. Author and verifier identities must differ.
|
|
32
|
+
- The coordinator dispatches one fresh Technical Verifier after the final code-changing slice.
|
|
33
|
+
- The verifier does not fix the inspected code; a gap returns to a new Implementer session.
|
|
34
|
+
- Technical verification reads the integrated final tree over the complete feature range and never
|
|
35
|
+
treats a builder's own checkpoint as independent proof.
|
|
36
|
+
- QA Plan and QA Execute read the integrated final tree after implementation review; they do not
|
|
37
|
+
read a private writer tree as the product result.
|
|
38
|
+
|
|
39
|
+
## Routing
|
|
40
|
+
|
|
41
|
+
Run exactly one phase per packet:
|
|
42
|
+
|
|
43
|
+
1. For `technical`, check each AC against `file:line` assertions for behavioral criteria, run the discrimination sensor in
|
|
44
|
+
a temp worktree or file copies, and write `.specs/features/<feature>/verification.md`. For visual ACs,
|
|
45
|
+
record fresh paired reference/implementation captures at declared states and exact viewports with
|
|
46
|
+
environment, fonts/assets, and expected differences; this is evidence, not an automated test.
|
|
47
|
+
2. For `wtk-qa-plan`, invoke the canonical `wtk-qa-plan` skill. Create or update durable journeys,
|
|
48
|
+
scenarios, and charters under `docs/qa/`; do not launch the product or change product code.
|
|
49
|
+
3. For `wtk-qa-execute`, invoke the canonical `wtk-qa-execute` skill. Read `docs/qa/README.md`, use its
|
|
50
|
+
existing adapter, walk public interfaces, and record durable reports/statuses plus disposable
|
|
51
|
+
evidence.
|
|
52
|
+
|
|
53
|
+
Dispatch QA only when the diff changes public behaviour through UI, API, CLI, mobile, public
|
|
54
|
+
configuration, adoption, or docs-as-interface. A purely internal refactor receives the technical
|
|
55
|
+
phase only. QA Plan and QA Execute each require a separate fresh Verifier session; reuse this
|
|
56
|
+
existing Verifier role for both phases.
|
|
57
|
+
|
|
58
|
+
QA phases read `docs/toolkit/guidelines/QA-SCENARIOS.md` as the sole authority for scenario fields, ids,
|
|
59
|
+
and statuses. QA Execute reports the selected interface/runner, exact path, evidence, and limitation
|
|
60
|
+
from the project profile; never install a framework or invent a command. Each checkout owns its
|
|
61
|
+
runtime and raw evidence, so validation and QA paths stay checkout-local.
|
|
62
|
+
Fresh QA Plan and fresh QA Execute sessions each run on the integrated final tree.
|
|
63
|
+
|
|
64
|
+
## Result
|
|
65
|
+
|
|
66
|
+
- Technical: return PASS/FAIL with ranked gaps. A mutant that survives becomes a fix task; do not
|
|
67
|
+
fix it in this session.
|
|
68
|
+
- QA Plan: return the criterion disposition, durable outputs, and the next QA Execute handoff. End
|
|
69
|
+
before live execution.
|
|
70
|
+
- QA Execute: return the report/status/evidence paths and defects. Hand each product defect to an
|
|
71
|
+
Implementer, close this session, require a fresh Verifier after the fix, and resume the affected
|
|
72
|
+
journey.
|
|
73
|
+
|
|
74
|
+
If this session wrote the code, stop and dispatch a new verifier instead.
|
|
75
|
+
|
|
76
|
+
## Product context
|
|
77
|
+
|
|
78
|
+
Read `docs/product/AGENT-CONTEXT.md` before work. Follow its role/task route, load only cited paths
|
|
79
|
+
or headings, and name missing required context as a gap.
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Regenerate `.specs/AD-INDEX.md` from `.specs/STATE.md`.
|
|
3
|
+
|
|
4
|
+
One line per AD-NNN. Agents load the index, not the log.
|
|
5
|
+
|
|
6
|
+
python3 .agents/skills/wtk-config/scripts/ad-index.py write the index
|
|
7
|
+
python3 .agents/skills/wtk-config/scripts/ad-index.py --check exit 1 if the index is stale
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import re
|
|
13
|
+
import sys
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
|
|
16
|
+
ROOT = Path(__file__).resolve().parents[4]
|
|
17
|
+
STATE = ROOT / ".specs" / "STATE.md"
|
|
18
|
+
INDEX = ROOT / ".specs" / "AD-INDEX.md"
|
|
19
|
+
|
|
20
|
+
AD_HEADER = re.compile(r"^### (AD-\d+)\s*$")
|
|
21
|
+
FIELD = re.compile(r"^- \*\*(Decision|Status)\*\*: (.*)$")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def first_sentence(text: str, limit: int = 140) -> str:
|
|
25
|
+
collapsed = re.sub(r"\s+", " ", text.replace("**", "")).strip()
|
|
26
|
+
cut = collapsed.find(". ")
|
|
27
|
+
sentence = collapsed[: cut + 1] if cut != -1 else collapsed
|
|
28
|
+
if len(sentence) > limit:
|
|
29
|
+
return sentence[: limit - 1].rstrip() + "…"
|
|
30
|
+
return sentence
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def parse(state: str) -> list[tuple[int, str, str, str]]:
|
|
34
|
+
rows: list[tuple[int, str, str, str]] = []
|
|
35
|
+
current: str | None = None
|
|
36
|
+
decision_parts: list[str] = []
|
|
37
|
+
status = "active"
|
|
38
|
+
capturing_decision = False
|
|
39
|
+
|
|
40
|
+
def flush() -> None:
|
|
41
|
+
nonlocal current, decision_parts, status, capturing_decision
|
|
42
|
+
if current is None:
|
|
43
|
+
return
|
|
44
|
+
number = int(current.split("-")[1])
|
|
45
|
+
rows.append((number, current, first_sentence(" ".join(decision_parts)), status))
|
|
46
|
+
current = None
|
|
47
|
+
decision_parts = []
|
|
48
|
+
status = "active"
|
|
49
|
+
capturing_decision = False
|
|
50
|
+
|
|
51
|
+
for line in state.splitlines():
|
|
52
|
+
header = AD_HEADER.match(line)
|
|
53
|
+
if header:
|
|
54
|
+
flush()
|
|
55
|
+
current = header.group(1)
|
|
56
|
+
continue
|
|
57
|
+
if current is None:
|
|
58
|
+
continue
|
|
59
|
+
if line.startswith("## "):
|
|
60
|
+
flush()
|
|
61
|
+
continue
|
|
62
|
+
field = FIELD.match(line)
|
|
63
|
+
if field:
|
|
64
|
+
name, value = field.group(1), field.group(2)
|
|
65
|
+
if name == "Decision":
|
|
66
|
+
capturing_decision = True
|
|
67
|
+
decision_parts = [value]
|
|
68
|
+
elif name == "Status":
|
|
69
|
+
capturing_decision = False
|
|
70
|
+
status = value.strip()
|
|
71
|
+
else:
|
|
72
|
+
capturing_decision = False
|
|
73
|
+
continue
|
|
74
|
+
if capturing_decision and line.startswith("- **"):
|
|
75
|
+
capturing_decision = False
|
|
76
|
+
continue
|
|
77
|
+
if capturing_decision and line.strip():
|
|
78
|
+
decision_parts.append(line.strip())
|
|
79
|
+
|
|
80
|
+
flush()
|
|
81
|
+
rows.sort(key=lambda row: row[0])
|
|
82
|
+
return rows
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def render(rows: list[tuple[int, str, str, str]]) -> str:
|
|
86
|
+
lines = [
|
|
87
|
+
"# Project decision index",
|
|
88
|
+
"",
|
|
89
|
+
"One line per `AD-NNN`. The append-only body lives in `.specs/STATE.md`.",
|
|
90
|
+
"",
|
|
91
|
+
"Body: `rg -A 20 '^### AD-NNN' .specs/STATE.md`. Resume: `rg -A 20 '^## Handoff' .specs/STATE.md`.",
|
|
92
|
+
"When recording an `AD-NNN`, run the bundled wtk-config ad-index.py in the same commit.",
|
|
93
|
+
"",
|
|
94
|
+
"| ID | Status | Decision |",
|
|
95
|
+
"| --- | --- | --- |",
|
|
96
|
+
]
|
|
97
|
+
for _number, ident, decision, status in rows:
|
|
98
|
+
escaped = decision.replace("|", "\\|")
|
|
99
|
+
lines.append(f"| `{ident}` | {status} | {escaped} |")
|
|
100
|
+
lines.append("")
|
|
101
|
+
return "\n".join(lines)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def main() -> int:
|
|
105
|
+
if not STATE.is_file():
|
|
106
|
+
print(f"missing {STATE}", file=sys.stderr)
|
|
107
|
+
return 1
|
|
108
|
+
text = render(parse(STATE.read_text()))
|
|
109
|
+
check = "--check" in sys.argv[1:]
|
|
110
|
+
if check:
|
|
111
|
+
current = INDEX.read_text() if INDEX.is_file() else ""
|
|
112
|
+
if current != text:
|
|
113
|
+
print("stale .specs/AD-INDEX.md; run the bundled wtk-config ad-index.py", file=sys.stderr)
|
|
114
|
+
return 1
|
|
115
|
+
print("AD-INDEX.md up to date")
|
|
116
|
+
return 0
|
|
117
|
+
INDEX.write_text(text, encoding="utf-8")
|
|
118
|
+
print(f"wrote {INDEX.relative_to(ROOT)}")
|
|
119
|
+
return 0
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
if __name__ == "__main__":
|
|
123
|
+
raise SystemExit(main())
|