@davidorex/pi-workflows 0.2.0 → 0.3.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 +7 -4
- package/README.md +12 -2
- package/agents/architecture-designer.agent.yaml +58 -0
- package/agents/architecture-inferrer.agent.yaml +60 -0
- package/agents/gap-identifier.agent.yaml +66 -0
- package/agents/handoff-writer.agent.yaml +64 -0
- package/agents/plan-creator.agent.yaml +63 -0
- package/agents/project-definer.agent.yaml +53 -0
- package/agents/project-inferrer.agent.yaml +63 -0
- package/agents/requirements-gatherer.agent.yaml +58 -0
- package/dist/agent-spec.d.ts +27 -0
- package/dist/agent-spec.d.ts.map +1 -0
- package/dist/agent-spec.js +112 -0
- package/dist/agent-spec.js.map +1 -0
- package/dist/checkpoint.d.ts +50 -0
- package/dist/checkpoint.d.ts.map +1 -0
- package/dist/checkpoint.js +109 -0
- package/dist/checkpoint.js.map +1 -0
- package/dist/completion.d.ts +18 -0
- package/dist/completion.d.ts.map +1 -0
- package/dist/completion.js +58 -0
- package/dist/completion.js.map +1 -0
- package/dist/dag.d.ts +56 -0
- package/dist/dag.d.ts.map +1 -0
- package/dist/dag.js +172 -0
- package/dist/dag.js.map +1 -0
- package/dist/dispatch.d.ts +35 -0
- package/dist/dispatch.d.ts.map +1 -0
- package/dist/dispatch.js +311 -0
- package/dist/dispatch.js.map +1 -0
- package/dist/expression.d.ts +64 -0
- package/dist/expression.d.ts.map +1 -0
- package/dist/expression.js +294 -0
- package/dist/expression.js.map +1 -0
- package/dist/format.d.ts +19 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +42 -0
- package/dist/format.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +675 -0
- package/dist/index.js.map +1 -0
- package/dist/output.d.ts +12 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +59 -0
- package/dist/output.js.map +1 -0
- package/dist/state.d.ts +66 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +227 -0
- package/dist/state.js.map +1 -0
- package/dist/step-agent.d.ts +35 -0
- package/dist/step-agent.d.ts.map +1 -0
- package/dist/step-agent.js +156 -0
- package/dist/step-agent.js.map +1 -0
- package/dist/step-command.d.ts +21 -0
- package/dist/step-command.d.ts.map +1 -0
- package/dist/step-command.js +150 -0
- package/dist/step-command.js.map +1 -0
- package/dist/step-foreach.d.ts +33 -0
- package/dist/step-foreach.d.ts.map +1 -0
- package/dist/step-foreach.js +112 -0
- package/dist/step-foreach.js.map +1 -0
- package/dist/step-gate.d.ts +18 -0
- package/dist/step-gate.d.ts.map +1 -0
- package/dist/step-gate.js +137 -0
- package/dist/step-gate.js.map +1 -0
- package/dist/step-loop.d.ts +32 -0
- package/dist/step-loop.d.ts.map +1 -0
- package/dist/step-loop.js +278 -0
- package/dist/step-loop.js.map +1 -0
- package/dist/step-monitor.d.ts +56 -0
- package/dist/step-monitor.d.ts.map +1 -0
- package/dist/step-monitor.js +317 -0
- package/dist/step-monitor.js.map +1 -0
- package/dist/step-parallel.d.ts +43 -0
- package/dist/step-parallel.d.ts.map +1 -0
- package/dist/step-parallel.js +122 -0
- package/dist/step-parallel.js.map +1 -0
- package/{src/step-pause.ts → dist/step-pause.d.ts} +3 -13
- package/dist/step-pause.d.ts.map +1 -0
- package/dist/step-pause.js +22 -0
- package/dist/step-pause.js.map +1 -0
- package/dist/step-shared.d.ts +57 -0
- package/dist/step-shared.d.ts.map +1 -0
- package/dist/step-shared.js +125 -0
- package/dist/step-shared.js.map +1 -0
- package/dist/step-transform.d.ts +11 -0
- package/dist/step-transform.d.ts.map +1 -0
- package/dist/step-transform.js +41 -0
- package/dist/step-transform.js.map +1 -0
- package/dist/template.d.ts +51 -0
- package/dist/template.d.ts.map +1 -0
- package/{src/template.ts → dist/template.js} +32 -38
- package/dist/template.js.map +1 -0
- package/dist/test-helpers.d.ts +17 -0
- package/dist/test-helpers.d.ts.map +1 -0
- package/dist/test-helpers.js +46 -0
- package/dist/test-helpers.js.map +1 -0
- package/dist/tui.d.ts +47 -0
- package/dist/tui.d.ts.map +1 -0
- package/dist/tui.js +143 -0
- package/dist/tui.js.map +1 -0
- package/dist/types.d.ts +164 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/workflow-discovery.d.ts +23 -0
- package/dist/workflow-discovery.d.ts.map +1 -0
- package/dist/workflow-discovery.js +103 -0
- package/dist/workflow-discovery.js.map +1 -0
- package/dist/workflow-executor.d.ts +50 -0
- package/dist/workflow-executor.d.ts.map +1 -0
- package/dist/workflow-executor.js +726 -0
- package/dist/workflow-executor.js.map +1 -0
- package/dist/workflow-sdk.d.ts +44 -0
- package/dist/workflow-sdk.d.ts.map +1 -0
- package/dist/workflow-sdk.js +438 -0
- package/dist/workflow-sdk.js.map +1 -0
- package/dist/workflow-spec.d.ts +33 -0
- package/dist/workflow-spec.d.ts.map +1 -0
- package/dist/workflow-spec.js +464 -0
- package/dist/workflow-spec.js.map +1 -0
- package/dist/workflows-dir.d.ts +3 -0
- package/dist/workflows-dir.d.ts.map +1 -0
- package/{src/workflows-dir.ts → dist/workflows-dir.js} +1 -0
- package/dist/workflows-dir.js.map +1 -0
- package/package.json +53 -38
- package/schemas/decomposition-specs.schema.json +48 -48
- package/schemas/execution-results.schema.json +48 -48
- package/schemas/investigation-findings.schema.json +43 -43
- package/schemas/pattern-analysis.schema.json +41 -41
- package/schemas/phase.schema.json +48 -0
- package/schemas/plan-breakdown.schema.json +20 -20
- package/schemas/quality-analysis.schema.json +33 -33
- package/schemas/research-findings.schema.json +42 -42
- package/schemas/structure-analysis.schema.json +40 -40
- package/schemas/synthesis.schema.json +31 -31
- package/schemas/verifier-output.schema.json +94 -94
- package/skill-narrative.md +84 -0
- package/skills/pi-workflows/SKILL.md +247 -0
- package/templates/architecture-designer/task.md +117 -0
- package/templates/architecture-inferrer/task.md +61 -0
- package/templates/gap-identifier/task.md +103 -0
- package/templates/handoff-writer/task.md +91 -0
- package/templates/plan-creator/task.md +143 -0
- package/templates/project-definer/task.md +67 -0
- package/templates/project-inferrer/task.md +56 -0
- package/templates/requirements-gatherer/task.md +90 -0
- package/workflows/analyze-existing-project.workflow.yaml +74 -0
- package/workflows/create-handoff.workflow.yaml +58 -0
- package/workflows/create-phase.workflow.yaml +1 -1
- package/workflows/do-gap.workflow.yaml +4 -4
- package/workflows/fix-audit.workflow.yaml +1 -1
- package/workflows/gap-to-phase.workflow.yaml +1 -1
- package/workflows/init-new-project.workflow.yaml +55 -0
- package/workflows/plan-from-requirements.workflow.yaml +51 -0
- package/workflows/self-implement.workflow.yaml +3 -3
- package/workflows/typed-analysis.workflow.yaml +4 -4
- package/src/agent-spec.test.ts +0 -289
- package/src/agent-spec.ts +0 -122
- package/src/block-validation.test.ts +0 -350
- package/src/checkpoint.test.ts +0 -237
- package/src/checkpoint.ts +0 -140
- package/src/completion.test.ts +0 -143
- package/src/completion.ts +0 -68
- package/src/dag.test.ts +0 -350
- package/src/dag.ts +0 -219
- package/src/dispatch.test.ts +0 -475
- package/src/dispatch.ts +0 -353
- package/src/expression.test.ts +0 -353
- package/src/expression.ts +0 -332
- package/src/format.test.ts +0 -80
- package/src/format.ts +0 -41
- package/src/graduated-failure.test.ts +0 -556
- package/src/index.test.ts +0 -114
- package/src/index.ts +0 -516
- package/src/loop.test.ts +0 -551
- package/src/output.test.ts +0 -213
- package/src/output.ts +0 -70
- package/src/parallel-integration.test.ts +0 -175
- package/src/resume.test.ts +0 -192
- package/src/state.test.ts +0 -192
- package/src/state.ts +0 -254
- package/src/step-agent.test.ts +0 -327
- package/src/step-agent.ts +0 -178
- package/src/step-command.test.ts +0 -330
- package/src/step-command.ts +0 -132
- package/src/step-foreach.test.ts +0 -647
- package/src/step-foreach.ts +0 -148
- package/src/step-gate.test.ts +0 -185
- package/src/step-gate.ts +0 -116
- package/src/step-loop.test.ts +0 -626
- package/src/step-loop.ts +0 -323
- package/src/step-parallel.test.ts +0 -475
- package/src/step-parallel.ts +0 -168
- package/src/step-pause.test.ts +0 -30
- package/src/step-shared.test.ts +0 -355
- package/src/step-shared.ts +0 -157
- package/src/step-transform.test.ts +0 -155
- package/src/step-transform.ts +0 -47
- package/src/template-integration.test.ts +0 -72
- package/src/template.test.ts +0 -162
- package/src/test-helpers.ts +0 -51
- package/src/tui.test.ts +0 -355
- package/src/tui.ts +0 -182
- package/src/types.ts +0 -195
- package/src/verifier-schema.test.ts +0 -226
- package/src/workflow-discovery.test.ts +0 -105
- package/src/workflow-discovery.ts +0 -114
- package/src/workflow-executor.test.ts +0 -1532
- package/src/workflow-executor.ts +0 -810
- package/src/workflow-sdk.test.ts +0 -238
- package/src/workflow-sdk.ts +0 -262
- package/src/workflow-spec.test.ts +0 -576
- package/src/workflow-spec.ts +0 -471
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
## Project Identity
|
|
2
|
+
|
|
3
|
+
**Name:** {{ project.name }}
|
|
4
|
+
**Description:** {{ project.description }}
|
|
5
|
+
**Core Value:** {{ project.core_value }}
|
|
6
|
+
**Status:** {{ project.status }}
|
|
7
|
+
{% if project.stack %}
|
|
8
|
+
|
|
9
|
+
### Stack
|
|
10
|
+
{% for item in project.stack %}
|
|
11
|
+
- {{ item }}
|
|
12
|
+
{% endfor %}
|
|
13
|
+
{% endif %}
|
|
14
|
+
|
|
15
|
+
## Requirements Summary
|
|
16
|
+
|
|
17
|
+
{% for req in requirements.requirements %}
|
|
18
|
+
{% if req.priority == "must" %}
|
|
19
|
+
- **{{ req.id }}** [must/{{ req.type }}]: {{ req.description }}
|
|
20
|
+
{% endif %}
|
|
21
|
+
{% endfor %}
|
|
22
|
+
{% for req in requirements.requirements %}
|
|
23
|
+
{% if req.priority == "should" %}
|
|
24
|
+
- **{{ req.id }}** [should/{{ req.type }}]: {{ req.description }}
|
|
25
|
+
{% endif %}
|
|
26
|
+
{% endfor %}
|
|
27
|
+
{% for req in requirements.requirements %}
|
|
28
|
+
{% if req.priority == "could" %}
|
|
29
|
+
- **{{ req.id }}** [could/{{ req.type }}]: {{ req.description }}
|
|
30
|
+
{% endif %}
|
|
31
|
+
{% endfor %}
|
|
32
|
+
|
|
33
|
+
## Architecture
|
|
34
|
+
|
|
35
|
+
**Overview:** {{ architecture.overview }}
|
|
36
|
+
|
|
37
|
+
### Modules
|
|
38
|
+
{% for module in architecture.modules %}
|
|
39
|
+
- **{{ module.name }}** (`{{ module.file }}`): {{ module.responsibility }}{% if module.dependencies %} [depends: {{ module.dependencies | join(", ") }}]{% endif %}
|
|
40
|
+
{% endfor %}
|
|
41
|
+
|
|
42
|
+
### Patterns
|
|
43
|
+
{% for pattern in architecture.patterns %}
|
|
44
|
+
- **{{ pattern.name }}**: {{ pattern.description }} (used in: {{ pattern.used_in | join(", ") }})
|
|
45
|
+
{% endfor %}
|
|
46
|
+
|
|
47
|
+
### Boundaries
|
|
48
|
+
{% for boundary in architecture.boundaries %}
|
|
49
|
+
- {{ boundary }}
|
|
50
|
+
{% endfor %}
|
|
51
|
+
|
|
52
|
+
{% if existing_files %}
|
|
53
|
+
## Existing Project Files
|
|
54
|
+
|
|
55
|
+
The project directory already contains these files:
|
|
56
|
+
{% for file in existing_files %}
|
|
57
|
+
- {{ file }}
|
|
58
|
+
{% endfor %}
|
|
59
|
+
|
|
60
|
+
Account for existing structure — do not plan to recreate files that already exist unless they need modification.
|
|
61
|
+
{% endif %}
|
|
62
|
+
|
|
63
|
+
## Instructions
|
|
64
|
+
|
|
65
|
+
Create implementation phases and tasks that build this project incrementally. The plan should take the project from its current state ({{ project.status }}) to a working system that satisfies all "must" requirements and addresses "should" requirements.
|
|
66
|
+
|
|
67
|
+
### Phase guidelines
|
|
68
|
+
|
|
69
|
+
1. **Phase 1** — Foundation: project structure, core module scaffolding, configuration, initial tests
|
|
70
|
+
2. **Phase 2+** — Layer functionality in priority order: "must" requirements first, then "should"
|
|
71
|
+
3. **Final phase** — Integration, documentation, and verification
|
|
72
|
+
4. Each phase should represent a meaningful milestone — the project is more capable after each phase
|
|
73
|
+
5. A phase with more than 8-10 tasks is likely too large — split it
|
|
74
|
+
|
|
75
|
+
### For each phase, provide:
|
|
76
|
+
|
|
77
|
+
- **number** — sequential starting at 1
|
|
78
|
+
- **name** — short descriptive name
|
|
79
|
+
- **intent** — what this phase accomplishes and why it comes at this point
|
|
80
|
+
- **goal** — what is true after this phase that was not true before
|
|
81
|
+
- **status** — `"planned"`
|
|
82
|
+
- **success_criteria** — array of `{ criterion, verify_method }` (verify_method: "command", "inspect", or "test")
|
|
83
|
+
- **dependencies** — array of phase numbers this depends on (empty for phase 1)
|
|
84
|
+
- **inputs** — what this phase needs from prior phases or external sources
|
|
85
|
+
- **outputs** — what this phase produces for later phases or users
|
|
86
|
+
|
|
87
|
+
### For each task, provide:
|
|
88
|
+
|
|
89
|
+
- **id** — unique, formatted as T-001, T-002, etc.
|
|
90
|
+
- **description** — clear statement of what to do
|
|
91
|
+
- **status** — `"planned"`
|
|
92
|
+
- **phase** — phase number this belongs to
|
|
93
|
+
- **files** — array of file paths this task creates or modifies
|
|
94
|
+
- **acceptance_criteria** — array of specific, verifiable statements
|
|
95
|
+
- **depends_on** — array of task IDs this depends on (empty if none)
|
|
96
|
+
- **notes** — optional: any implementation guidance or caveats
|
|
97
|
+
|
|
98
|
+
### Task sizing
|
|
99
|
+
|
|
100
|
+
- Each task should be completable by one agent in one context window
|
|
101
|
+
- A task touching more than 3-5 files likely needs splitting
|
|
102
|
+
- A task with more than 5 acceptance criteria may be doing too much
|
|
103
|
+
- Group related changes: schema + implementation + test = one task when files are few
|
|
104
|
+
|
|
105
|
+
### Traceability
|
|
106
|
+
|
|
107
|
+
- Every "must" requirement should be addressed by at least one task
|
|
108
|
+
- Every task's files should map to at least one architecture module
|
|
109
|
+
- Note requirement IDs in task descriptions or notes where the mapping is clear
|
|
110
|
+
|
|
111
|
+
### Output format
|
|
112
|
+
|
|
113
|
+
Produce a single JSON object with two arrays:
|
|
114
|
+
|
|
115
|
+
```json
|
|
116
|
+
{
|
|
117
|
+
"phases": [
|
|
118
|
+
{
|
|
119
|
+
"number": 1,
|
|
120
|
+
"name": "string",
|
|
121
|
+
"intent": "string",
|
|
122
|
+
"goal": "string",
|
|
123
|
+
"status": "planned",
|
|
124
|
+
"success_criteria": [{ "criterion": "string", "verify_method": "command" }],
|
|
125
|
+
"dependencies": [],
|
|
126
|
+
"inputs": ["string"],
|
|
127
|
+
"outputs": ["string"]
|
|
128
|
+
}
|
|
129
|
+
],
|
|
130
|
+
"tasks": [
|
|
131
|
+
{
|
|
132
|
+
"id": "T-001",
|
|
133
|
+
"description": "string",
|
|
134
|
+
"status": "planned",
|
|
135
|
+
"phase": 1,
|
|
136
|
+
"files": ["src/file.ts"],
|
|
137
|
+
"acceptance_criteria": ["string"],
|
|
138
|
+
"depends_on": [],
|
|
139
|
+
"notes": "optional string"
|
|
140
|
+
}
|
|
141
|
+
]
|
|
142
|
+
}
|
|
143
|
+
```
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
## Vision Statement
|
|
2
|
+
|
|
3
|
+
{{ vision }}
|
|
4
|
+
|
|
5
|
+
{% if context %}
|
|
6
|
+
## Additional Context
|
|
7
|
+
|
|
8
|
+
{{ context }}
|
|
9
|
+
{% endif %}
|
|
10
|
+
|
|
11
|
+
## Instructions
|
|
12
|
+
|
|
13
|
+
Produce a structured project identity from the vision statement above. Extract, infer, or derive each field — do not leave gaps where the vision provides signal.
|
|
14
|
+
|
|
15
|
+
### Fields to produce
|
|
16
|
+
|
|
17
|
+
1. **name** — short, lowercase-hyphenated project identifier
|
|
18
|
+
2. **description** — 1-3 sentences capturing what the project does and why it matters
|
|
19
|
+
3. **core_value** — one sentence a stakeholder outside the project could understand
|
|
20
|
+
4. **target_users** — array of user roles or personas who benefit
|
|
21
|
+
5. **constraints** — array of `{ type, description }` objects reflecting real limitations from the vision
|
|
22
|
+
- type examples: "technical", "organizational", "timeline", "budget", "regulatory", "compatibility"
|
|
23
|
+
6. **scope_boundaries** — `{ in: [...], out: [...] }` capturing what is and is not in scope
|
|
24
|
+
- `out` is especially important: document what a reader might assume is in scope but is not
|
|
25
|
+
7. **goals** — array of `{ id, description, success_criteria: [...] }` objects
|
|
26
|
+
- IDs: G-001, G-002, etc.
|
|
27
|
+
- success_criteria: measurable or verifiable statements (not aspirational)
|
|
28
|
+
8. **status** — set to `"inception"`
|
|
29
|
+
|
|
30
|
+
{% if stack %}
|
|
31
|
+
### Stack
|
|
32
|
+
|
|
33
|
+
The following technology stack has been specified:
|
|
34
|
+
|
|
35
|
+
{% for item in stack %}
|
|
36
|
+
- {{ item }}
|
|
37
|
+
{% endfor %}
|
|
38
|
+
|
|
39
|
+
Include these in the output `stack` array.
|
|
40
|
+
{% endif %}
|
|
41
|
+
|
|
42
|
+
{% if repository %}
|
|
43
|
+
### Repository
|
|
44
|
+
|
|
45
|
+
Repository: {{ repository }}
|
|
46
|
+
|
|
47
|
+
Include this in the output `repository` field.
|
|
48
|
+
{% endif %}
|
|
49
|
+
|
|
50
|
+
### Output format
|
|
51
|
+
|
|
52
|
+
Produce a single JSON object. Every required field must be present. The object should conform to the project block schema:
|
|
53
|
+
|
|
54
|
+
```json
|
|
55
|
+
{
|
|
56
|
+
"name": "string (required)",
|
|
57
|
+
"description": "string (required)",
|
|
58
|
+
"core_value": "string (required)",
|
|
59
|
+
"target_users": ["string"],
|
|
60
|
+
"constraints": [{ "type": "string", "description": "string" }],
|
|
61
|
+
"scope_boundaries": { "in": ["string"], "out": ["string"] },
|
|
62
|
+
"goals": [{ "id": "G-001", "description": "string", "success_criteria": ["string"] }],
|
|
63
|
+
"status": "inception",
|
|
64
|
+
"repository": "string (if provided)",
|
|
65
|
+
"stack": ["string (if provided)"]
|
|
66
|
+
}
|
|
67
|
+
```
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
Infer the project identity for the project at `{{ path }}`.
|
|
2
|
+
|
|
3
|
+
## Codebase Analysis
|
|
4
|
+
|
|
5
|
+
{% if analysis.files is defined %}
|
|
6
|
+
### Files ({{ analysis.files | length }} total)
|
|
7
|
+
{% for file in analysis.files | batch(20) | first %}
|
|
8
|
+
- `{{ file.path }}` ({{ file.language | default("unknown") }})
|
|
9
|
+
{% endfor %}
|
|
10
|
+
{% if analysis.files | length > 20 %}
|
|
11
|
+
... and {{ analysis.files | length - 20 }} more files
|
|
12
|
+
{% endif %}
|
|
13
|
+
{% endif %}
|
|
14
|
+
|
|
15
|
+
{% if analysis.entryPoints is defined %}
|
|
16
|
+
### Entry Points
|
|
17
|
+
{% for ep in analysis.entryPoints %}
|
|
18
|
+
- `{{ ep }}`
|
|
19
|
+
{% endfor %}
|
|
20
|
+
{% endif %}
|
|
21
|
+
|
|
22
|
+
## Instructions
|
|
23
|
+
|
|
24
|
+
Read project metadata and documentation to determine the project's identity. Start with:
|
|
25
|
+
- README.md (or equivalent)
|
|
26
|
+
- Package manifest (package.json, Cargo.toml, pyproject.toml, go.mod, etc.)
|
|
27
|
+
- CLAUDE.md or similar project instructions if present
|
|
28
|
+
- CI/CD configuration if present
|
|
29
|
+
|
|
30
|
+
Produce a project identity block:
|
|
31
|
+
|
|
32
|
+
1. **name** — the project's canonical name (from package manifest, not directory name)
|
|
33
|
+
2. **description** — concise summary of what the project does (2-3 sentences max)
|
|
34
|
+
3. **core_value** — single sentence: why does this project exist? What value does it provide?
|
|
35
|
+
4. **target_users** — who uses this? (e.g., "TypeScript developers", "DevOps engineers", "data scientists")
|
|
36
|
+
5. **constraints** — each with `type` and `description`:
|
|
37
|
+
- Runtime constraints (Node.js version, browser support, etc.)
|
|
38
|
+
- Language constraints (TypeScript strict mode, ESM-only, etc.)
|
|
39
|
+
- Compatibility constraints (API stability, backward compat, etc.)
|
|
40
|
+
6. **scope_boundaries**:
|
|
41
|
+
- `in`: what the project explicitly does
|
|
42
|
+
- `out`: what the project explicitly does not do (deferred or excluded)
|
|
43
|
+
7. **goals** — each with `id`, `description`, and optional `success_criteria` array
|
|
44
|
+
- Only include goals evidenced by the codebase (README roadmap, issues, TODO markers)
|
|
45
|
+
8. **status** — one of: inception, planning, development, maintenance, complete
|
|
46
|
+
- Infer from: version maturity, commit recency, test coverage, presence of CI
|
|
47
|
+
9. **repository** — repository URL if discoverable from package manifest or git remote
|
|
48
|
+
10. **stack** — primary technology choices only (language, framework, key libraries — not every dependency)
|
|
49
|
+
|
|
50
|
+
## Required Output Schema
|
|
51
|
+
|
|
52
|
+
You MUST produce JSON conforming exactly to this schema. Every required field must be present.
|
|
53
|
+
|
|
54
|
+
```json
|
|
55
|
+
{{ output_schema }}
|
|
56
|
+
```
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
## Project Identity
|
|
2
|
+
|
|
3
|
+
**Name:** {{ project.name }}
|
|
4
|
+
**Description:** {{ project.description }}
|
|
5
|
+
**Core Value:** {{ project.core_value }}
|
|
6
|
+
|
|
7
|
+
### Target Users
|
|
8
|
+
{% for user in project.target_users %}
|
|
9
|
+
- {{ user }}
|
|
10
|
+
{% endfor %}
|
|
11
|
+
|
|
12
|
+
### Constraints
|
|
13
|
+
{% for constraint in project.constraints %}
|
|
14
|
+
- [{{ constraint.type }}] {{ constraint.description }}
|
|
15
|
+
{% endfor %}
|
|
16
|
+
|
|
17
|
+
### Scope Boundaries
|
|
18
|
+
|
|
19
|
+
**In scope:**
|
|
20
|
+
{% for item in project.scope_boundaries.in %}
|
|
21
|
+
- {{ item }}
|
|
22
|
+
{% endfor %}
|
|
23
|
+
|
|
24
|
+
**Out of scope:**
|
|
25
|
+
{% for item in project.scope_boundaries.out %}
|
|
26
|
+
- {{ item }}
|
|
27
|
+
{% endfor %}
|
|
28
|
+
|
|
29
|
+
### Goals
|
|
30
|
+
{% for goal in project.goals %}
|
|
31
|
+
- **{{ goal.id }}**: {{ goal.description }}
|
|
32
|
+
{% for criterion in goal.success_criteria %}- {{ criterion }}
|
|
33
|
+
{% endfor %}
|
|
34
|
+
{% endfor %}
|
|
35
|
+
|
|
36
|
+
{% if vision %}
|
|
37
|
+
## Original Vision
|
|
38
|
+
|
|
39
|
+
{{ vision }}
|
|
40
|
+
{% endif %}
|
|
41
|
+
|
|
42
|
+
## Instructions
|
|
43
|
+
|
|
44
|
+
Derive requirements from the project identity above. Produce a comprehensive but proportionate set of requirements covering what the system must do (functional), quality attributes it must exhibit (non-functional), hard limits it must respect (constraint), and external connections it must support (integration).
|
|
45
|
+
|
|
46
|
+
### For each requirement, provide:
|
|
47
|
+
|
|
48
|
+
1. **id** — unique, formatted as REQ-001, REQ-002, etc.
|
|
49
|
+
2. **description** — clear statement of what is required
|
|
50
|
+
3. **type** — one of: `functional`, `non-functional`, `constraint`, `integration`
|
|
51
|
+
4. **status** — set to `"proposed"` for all
|
|
52
|
+
5. **priority** — MoSCoW: `must`, `should`, `could`, `wont`
|
|
53
|
+
6. **acceptance_criteria** — array of specific, verifiable statements
|
|
54
|
+
7. **source** — set to `"agent"` for all
|
|
55
|
+
8. **depends_on** — array of other requirement IDs this depends on (empty array if none)
|
|
56
|
+
|
|
57
|
+
### Priority guidance
|
|
58
|
+
|
|
59
|
+
- **must**: the project fails without this — directly tied to core_value and essential goals
|
|
60
|
+
- **should**: important for target users but the project could ship a minimal version without it
|
|
61
|
+
- **could**: enhances the experience but is clearly secondary
|
|
62
|
+
- **wont**: explicitly excluded — derive these from scope_boundaries.out
|
|
63
|
+
|
|
64
|
+
### Coverage expectations
|
|
65
|
+
|
|
66
|
+
- Every goal should map to at least one "must" requirement
|
|
67
|
+
- Every constraint should appear as a "constraint" type requirement
|
|
68
|
+
- Include at least one non-functional requirement for each quality attribute the project implies (performance, security, usability, reliability, etc. — only those that are relevant)
|
|
69
|
+
- Include "wont" requirements for major items in scope_boundaries.out
|
|
70
|
+
|
|
71
|
+
### Output format
|
|
72
|
+
|
|
73
|
+
Produce a single JSON object with a `requirements` array:
|
|
74
|
+
|
|
75
|
+
```json
|
|
76
|
+
{
|
|
77
|
+
"requirements": [
|
|
78
|
+
{
|
|
79
|
+
"id": "REQ-001",
|
|
80
|
+
"description": "string",
|
|
81
|
+
"type": "functional",
|
|
82
|
+
"status": "proposed",
|
|
83
|
+
"priority": "must",
|
|
84
|
+
"acceptance_criteria": ["string"],
|
|
85
|
+
"source": "agent",
|
|
86
|
+
"depends_on": []
|
|
87
|
+
}
|
|
88
|
+
]
|
|
89
|
+
}
|
|
90
|
+
```
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
name: analyze-existing-project
|
|
2
|
+
description: Analyze an existing codebase, infer architecture and conventions, identify gaps, create planning state
|
|
3
|
+
version: "1"
|
|
4
|
+
|
|
5
|
+
input:
|
|
6
|
+
type: object
|
|
7
|
+
properties:
|
|
8
|
+
path:
|
|
9
|
+
type: string
|
|
10
|
+
description: Path to analyze (defaults to current directory)
|
|
11
|
+
|
|
12
|
+
steps:
|
|
13
|
+
explore:
|
|
14
|
+
agent: code-explorer
|
|
15
|
+
input:
|
|
16
|
+
path: ${{ input.path }}
|
|
17
|
+
|
|
18
|
+
# These two analyze concurrently — no mutual dependencies, both depend only on explore
|
|
19
|
+
analyze-structure:
|
|
20
|
+
agent: structure-analyzer
|
|
21
|
+
input:
|
|
22
|
+
exploration: ${{ steps.explore.textOutput }}
|
|
23
|
+
path: ${{ input.path }}
|
|
24
|
+
output:
|
|
25
|
+
format: json
|
|
26
|
+
|
|
27
|
+
analyze-patterns:
|
|
28
|
+
agent: pattern-analyzer
|
|
29
|
+
input:
|
|
30
|
+
exploration: ${{ steps.explore.textOutput }}
|
|
31
|
+
path: ${{ input.path }}
|
|
32
|
+
output:
|
|
33
|
+
format: json
|
|
34
|
+
|
|
35
|
+
infer-architecture:
|
|
36
|
+
agent: architecture-inferrer
|
|
37
|
+
input:
|
|
38
|
+
analysis:
|
|
39
|
+
structure: ${{ steps.analyze-structure.output }}
|
|
40
|
+
patterns: ${{ steps.analyze-patterns.output }}
|
|
41
|
+
path: ${{ input.path }}
|
|
42
|
+
output:
|
|
43
|
+
format: json
|
|
44
|
+
|
|
45
|
+
infer-project:
|
|
46
|
+
agent: project-inferrer
|
|
47
|
+
input:
|
|
48
|
+
analysis:
|
|
49
|
+
structure: ${{ steps.analyze-structure.output }}
|
|
50
|
+
patterns: ${{ steps.analyze-patterns.output }}
|
|
51
|
+
path: ${{ input.path }}
|
|
52
|
+
output:
|
|
53
|
+
format: json
|
|
54
|
+
|
|
55
|
+
identify-gaps:
|
|
56
|
+
agent: gap-identifier
|
|
57
|
+
input:
|
|
58
|
+
analysis:
|
|
59
|
+
structure: ${{ steps.analyze-structure.output }}
|
|
60
|
+
patterns: ${{ steps.analyze-patterns.output }}
|
|
61
|
+
architecture: ${{ steps.infer-architecture.output }}
|
|
62
|
+
path: ${{ input.path }}
|
|
63
|
+
output:
|
|
64
|
+
format: json
|
|
65
|
+
|
|
66
|
+
completion:
|
|
67
|
+
template: |
|
|
68
|
+
Existing project analyzed.
|
|
69
|
+
|
|
70
|
+
**Project:** ${{ steps.infer-project.output.name }} — ${{ steps.infer-project.output.core_value }}
|
|
71
|
+
**Architecture:** ${{ steps.infer-architecture.output.modules | length }} modules, ${{ steps.infer-architecture.output.patterns | length }} patterns
|
|
72
|
+
**Gaps:** ${{ steps.identify-gaps.output.gaps | length }} identified
|
|
73
|
+
|
|
74
|
+
Use `/project status` to see the full state. Use `/project validate` to check cross-block references.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
name: create-handoff
|
|
2
|
+
description: Capture current work context for session resume
|
|
3
|
+
version: "1"
|
|
4
|
+
|
|
5
|
+
steps:
|
|
6
|
+
load-state:
|
|
7
|
+
command: |
|
|
8
|
+
node -e "
|
|
9
|
+
const fs = require('fs');
|
|
10
|
+
const path = require('path');
|
|
11
|
+
const projectDir = '.project';
|
|
12
|
+
const state = {};
|
|
13
|
+
|
|
14
|
+
// Read project identity
|
|
15
|
+
try { state.project = JSON.parse(fs.readFileSync(path.join(projectDir, 'project.json'), 'utf-8')); } catch {}
|
|
16
|
+
|
|
17
|
+
// Read phase files
|
|
18
|
+
try {
|
|
19
|
+
const phasesDir = path.join(projectDir, 'phases');
|
|
20
|
+
state.phases = fs.readdirSync(phasesDir).filter(f => f.endsWith('.json')).map(f => {
|
|
21
|
+
try { return JSON.parse(fs.readFileSync(path.join(phasesDir, f), 'utf-8')); } catch { return null; }
|
|
22
|
+
}).filter(Boolean);
|
|
23
|
+
} catch { state.phases = []; }
|
|
24
|
+
|
|
25
|
+
// Read block summaries
|
|
26
|
+
try {
|
|
27
|
+
state.gaps = JSON.parse(fs.readFileSync(path.join(projectDir, 'gaps.json'), 'utf-8'));
|
|
28
|
+
} catch {}
|
|
29
|
+
try {
|
|
30
|
+
state.decisions = JSON.parse(fs.readFileSync(path.join(projectDir, 'decisions.json'), 'utf-8'));
|
|
31
|
+
} catch {}
|
|
32
|
+
try {
|
|
33
|
+
state.tasks = JSON.parse(fs.readFileSync(path.join(projectDir, 'tasks.json'), 'utf-8'));
|
|
34
|
+
} catch {}
|
|
35
|
+
|
|
36
|
+
// Recent git activity
|
|
37
|
+
try {
|
|
38
|
+
const { execSync } = require('child_process');
|
|
39
|
+
state.recent_commits = execSync('git log --oneline -10', { encoding: 'utf-8' }).trim().split('\n');
|
|
40
|
+
state.changed_files = execSync('git diff --name-only HEAD~3 2>/dev/null || echo \"\"', { encoding: 'utf-8' }).trim().split('\n').filter(Boolean);
|
|
41
|
+
} catch { state.recent_commits = []; state.changed_files = []; }
|
|
42
|
+
|
|
43
|
+
console.log(JSON.stringify(state));
|
|
44
|
+
"
|
|
45
|
+
output:
|
|
46
|
+
format: json
|
|
47
|
+
|
|
48
|
+
capture:
|
|
49
|
+
agent: handoff-writer
|
|
50
|
+
input:
|
|
51
|
+
project_state: ${{ steps.load-state.output }}
|
|
52
|
+
path: "."
|
|
53
|
+
output:
|
|
54
|
+
format: json
|
|
55
|
+
|
|
56
|
+
completion:
|
|
57
|
+
message: |
|
|
58
|
+
Handoff captured to .project/handoff.json. Resume context is available for the next session.
|
|
@@ -37,7 +37,7 @@ steps:
|
|
|
37
37
|
gap: "${{ steps.load.output.gap }}"
|
|
38
38
|
output:
|
|
39
39
|
format: json
|
|
40
|
-
schema: schemas/investigation-findings.schema.json
|
|
40
|
+
schema: ../schemas/investigation-findings.schema.json
|
|
41
41
|
|
|
42
42
|
research:
|
|
43
43
|
when: "${{ steps.investigate.output.needs_research }}"
|
|
@@ -47,7 +47,7 @@ steps:
|
|
|
47
47
|
research_questions: "${{ steps.investigate.output.research_questions }}"
|
|
48
48
|
output:
|
|
49
49
|
format: json
|
|
50
|
-
schema: schemas/research-findings.schema.json
|
|
50
|
+
schema: ../schemas/research-findings.schema.json
|
|
51
51
|
|
|
52
52
|
decompose:
|
|
53
53
|
agent: decomposer
|
|
@@ -57,7 +57,7 @@ steps:
|
|
|
57
57
|
research: "${{ steps.research.output }}"
|
|
58
58
|
output:
|
|
59
59
|
format: json
|
|
60
|
-
schema: schemas/decomposition-specs.schema.json
|
|
60
|
+
schema: ../schemas/decomposition-specs.schema.json
|
|
61
61
|
|
|
62
62
|
implement:
|
|
63
63
|
forEach: "${{ steps.decompose.output.specs }}"
|
|
@@ -72,7 +72,7 @@ steps:
|
|
|
72
72
|
onExhausted: fail
|
|
73
73
|
output:
|
|
74
74
|
format: json
|
|
75
|
-
schema: schemas/execution-results.schema.json
|
|
75
|
+
schema: ../schemas/execution-results.schema.json
|
|
76
76
|
|
|
77
77
|
verify:
|
|
78
78
|
command: |
|
|
@@ -87,7 +87,7 @@ steps:
|
|
|
87
87
|
conformance_reference: "${{ steps.load.output.conformance_reference }}"
|
|
88
88
|
output:
|
|
89
89
|
format: json
|
|
90
|
-
schema: schemas/execution-results.schema.json
|
|
90
|
+
schema: ../schemas/execution-results.schema.json
|
|
91
91
|
path: .project/fix-audit-results.json
|
|
92
92
|
|
|
93
93
|
route-results:
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
name: init-new-project
|
|
2
|
+
description: Bootstrap a new project from vision through requirements to initial plan
|
|
3
|
+
version: "1"
|
|
4
|
+
|
|
5
|
+
input:
|
|
6
|
+
type: object
|
|
7
|
+
required: [vision]
|
|
8
|
+
properties:
|
|
9
|
+
vision:
|
|
10
|
+
type: string
|
|
11
|
+
description: What the project aims to achieve, who it's for, and why it matters
|
|
12
|
+
|
|
13
|
+
steps:
|
|
14
|
+
define-identity:
|
|
15
|
+
agent: project-definer
|
|
16
|
+
input:
|
|
17
|
+
vision: ${{ input.vision }}
|
|
18
|
+
output:
|
|
19
|
+
format: json
|
|
20
|
+
|
|
21
|
+
gather-requirements:
|
|
22
|
+
agent: requirements-gatherer
|
|
23
|
+
input:
|
|
24
|
+
project: ${{ steps.define-identity.output }}
|
|
25
|
+
vision: ${{ input.vision }}
|
|
26
|
+
output:
|
|
27
|
+
format: json
|
|
28
|
+
|
|
29
|
+
design-architecture:
|
|
30
|
+
agent: architecture-designer
|
|
31
|
+
input:
|
|
32
|
+
project: ${{ steps.define-identity.output }}
|
|
33
|
+
requirements: ${{ steps.gather-requirements.output }}
|
|
34
|
+
output:
|
|
35
|
+
format: json
|
|
36
|
+
|
|
37
|
+
create-plan:
|
|
38
|
+
agent: plan-creator
|
|
39
|
+
input:
|
|
40
|
+
project: ${{ steps.define-identity.output }}
|
|
41
|
+
requirements: ${{ steps.gather-requirements.output }}
|
|
42
|
+
architecture: ${{ steps.design-architecture.output }}
|
|
43
|
+
output:
|
|
44
|
+
format: json
|
|
45
|
+
|
|
46
|
+
completion:
|
|
47
|
+
template: |
|
|
48
|
+
Project initialized from vision.
|
|
49
|
+
|
|
50
|
+
**Identity:** ${{ steps.define-identity.output.name }} — ${{ steps.define-identity.output.core_value }}
|
|
51
|
+
**Requirements:** ${{ steps.gather-requirements.output.requirements | length }} captured
|
|
52
|
+
**Architecture:** ${{ steps.design-architecture.output.modules | length }} modules
|
|
53
|
+
**Plan:** phases and tasks created
|
|
54
|
+
|
|
55
|
+
Use `/project status` to see the full state. Use `/project validate` to check cross-block references.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
name: plan-from-requirements
|
|
2
|
+
description: Decompose accepted requirements into phases and tasks
|
|
3
|
+
version: "1"
|
|
4
|
+
|
|
5
|
+
steps:
|
|
6
|
+
load-context:
|
|
7
|
+
command: |
|
|
8
|
+
node -e "
|
|
9
|
+
const fs = require('fs');
|
|
10
|
+
const path = require('path');
|
|
11
|
+
const projectDir = '.project';
|
|
12
|
+
const context = {};
|
|
13
|
+
|
|
14
|
+
// Read requirements
|
|
15
|
+
try { context.requirements = JSON.parse(fs.readFileSync(path.join(projectDir, 'requirements.json'), 'utf-8')); } catch { context.requirements = { requirements: [] }; }
|
|
16
|
+
|
|
17
|
+
// Read architecture
|
|
18
|
+
try { context.architecture = JSON.parse(fs.readFileSync(path.join(projectDir, 'architecture.json'), 'utf-8')); } catch { context.architecture = null; }
|
|
19
|
+
|
|
20
|
+
// Read project identity
|
|
21
|
+
try { context.project = JSON.parse(fs.readFileSync(path.join(projectDir, 'project.json'), 'utf-8')); } catch { context.project = null; }
|
|
22
|
+
|
|
23
|
+
// Read existing phases
|
|
24
|
+
try {
|
|
25
|
+
const phasesDir = path.join(projectDir, 'phases');
|
|
26
|
+
context.existing_phases = fs.readdirSync(phasesDir).filter(f => f.endsWith('.json')).map(f => {
|
|
27
|
+
try { return JSON.parse(fs.readFileSync(path.join(phasesDir, f), 'utf-8')); } catch { return null; }
|
|
28
|
+
}).filter(Boolean);
|
|
29
|
+
} catch { context.existing_phases = []; }
|
|
30
|
+
|
|
31
|
+
console.log(JSON.stringify(context));
|
|
32
|
+
"
|
|
33
|
+
output:
|
|
34
|
+
format: json
|
|
35
|
+
|
|
36
|
+
create-plan:
|
|
37
|
+
agent: plan-creator
|
|
38
|
+
input:
|
|
39
|
+
project: ${{ steps.load-context.output.project }}
|
|
40
|
+
requirements: ${{ steps.load-context.output.requirements }}
|
|
41
|
+
architecture: ${{ steps.load-context.output.architecture }}
|
|
42
|
+
existing_phases: ${{ steps.load-context.output.existing_phases }}
|
|
43
|
+
output:
|
|
44
|
+
format: json
|
|
45
|
+
|
|
46
|
+
completion:
|
|
47
|
+
template: |
|
|
48
|
+
Plan created from requirements.
|
|
49
|
+
|
|
50
|
+
Use `/project status` to see the phase and task breakdown.
|
|
51
|
+
Use `/project validate` to check cross-block references.
|
|
@@ -25,7 +25,7 @@ steps:
|
|
|
25
25
|
conventions: "${{ input.conventions }}"
|
|
26
26
|
output:
|
|
27
27
|
format: json
|
|
28
|
-
schema: schemas/plan-breakdown.schema.json
|
|
28
|
+
schema: ../schemas/plan-breakdown.schema.json
|
|
29
29
|
|
|
30
30
|
implement:
|
|
31
31
|
forEach: "${{ steps.plan.output.plans }}"
|
|
@@ -37,7 +37,7 @@ steps:
|
|
|
37
37
|
conventions: "${{ input.conventions }}"
|
|
38
38
|
output:
|
|
39
39
|
format: json
|
|
40
|
-
schema: schemas/execution-results.schema.json
|
|
40
|
+
schema: ../schemas/execution-results.schema.json
|
|
41
41
|
|
|
42
42
|
verify:
|
|
43
43
|
agent: verifier
|
|
@@ -46,7 +46,7 @@ steps:
|
|
|
46
46
|
step_output: "${{ steps.implement.output }}"
|
|
47
47
|
output:
|
|
48
48
|
format: json
|
|
49
|
-
schema: schemas/verifier-output.schema.json
|
|
49
|
+
schema: ../schemas/verifier-output.schema.json
|
|
50
50
|
|
|
51
51
|
check:
|
|
52
52
|
gate:
|