@dezycro-ai/agent-plugin 2.0.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/.claude-plugin/plugin.json +7 -0
- package/LICENSE +18 -0
- package/PERSONAS.md +309 -0
- package/README.md +125 -0
- package/bin/resolve-auth.js +112 -0
- package/dist/hooks/lib/authoring.d.ts +118 -0
- package/dist/hooks/lib/authoring.js +277 -0
- package/dist/hooks/lib/config.d.ts +28 -0
- package/dist/hooks/lib/config.js +175 -0
- package/dist/hooks/lib/controller-match.d.ts +16 -0
- package/dist/hooks/lib/controller-match.js +96 -0
- package/dist/hooks/lib/coverage.d.ts +17 -0
- package/dist/hooks/lib/coverage.js +66 -0
- package/dist/hooks/lib/hashing.d.ts +8 -0
- package/dist/hooks/lib/hashing.js +49 -0
- package/dist/hooks/lib/logging.d.ts +13 -0
- package/dist/hooks/lib/logging.js +72 -0
- package/dist/hooks/lib/publish-spec.d.ts +17 -0
- package/dist/hooks/lib/publish-spec.js +64 -0
- package/dist/hooks/lib/quality-gate.d.ts +67 -0
- package/dist/hooks/lib/quality-gate.js +187 -0
- package/dist/hooks/lib/router.d.ts +32 -0
- package/dist/hooks/lib/router.js +717 -0
- package/dist/hooks/lib/state.d.ts +34 -0
- package/dist/hooks/lib/state.js +238 -0
- package/dist/hooks/lib/undo.d.ts +11 -0
- package/dist/hooks/lib/undo.js +71 -0
- package/dist/hooks/lib/verify.d.ts +28 -0
- package/dist/hooks/lib/verify.js +94 -0
- package/dist/hooks/lib/workbook.d.ts +21 -0
- package/dist/hooks/lib/workbook.js +77 -0
- package/dist/hooks/types.d.ts +249 -0
- package/dist/hooks/types.js +14 -0
- package/hooks/companion-runner +108 -0
- package/hooks/hooks.json +74 -0
- package/install.js +84 -0
- package/package.json +50 -0
- package/prompts/existing-work-ranker.md +47 -0
- package/prompts/prd-drafter.md +53 -0
- package/prompts/prd-question.md +66 -0
- package/prompts/trd-context-gate.md +57 -0
- package/prompts/trd-discovery.md +71 -0
- package/prompts/trd-drafter.md +63 -0
- package/prompts/trd-question.md +61 -0
- package/prompts/trd-reviewer.md +74 -0
- package/prompts/workbook-sweep.md +89 -0
- package/setup.js +35 -0
- package/skills/author/SKILL.md +285 -0
- package/skills/import-features/SKILL.md +428 -0
- package/skills/init/SKILL.md +133 -0
- package/skills/publish-spec/SKILL.md +101 -0
- package/skills/status/SKILL.md +76 -0
- package/skills/sync/SKILL.md +76 -0
- package/skills/verify/SKILL.md +248 -0
- package/skills/work/SKILL.md +201 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: status
|
|
3
|
+
description: Show a compact workbook summary for the active feature — journeys, tasks, issues, and latest verification results. Requires an active feature (run /dezycro:work first).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Dezycro Feature Status
|
|
7
|
+
|
|
8
|
+
You are displaying a compact workbook summary for the active Dezycro feature.
|
|
9
|
+
|
|
10
|
+
## Step 1: Read Active Feature
|
|
11
|
+
|
|
12
|
+
Read `.dezycro/active-feature.json` using the Read tool. If the file does not exist, tell the user:
|
|
13
|
+
|
|
14
|
+
> No active feature. Run `/dezycro:work <feature-name>` first to select a feature.
|
|
15
|
+
|
|
16
|
+
Then stop.
|
|
17
|
+
|
|
18
|
+
Extract `featureId` and `featureName`.
|
|
19
|
+
|
|
20
|
+
## Step 2: Read Config
|
|
21
|
+
|
|
22
|
+
Read `.dezycro/config.json` to get `workspaceId`.
|
|
23
|
+
|
|
24
|
+
## Step 3: Fetch Workbook
|
|
25
|
+
|
|
26
|
+
Call `get_workbook(workspaceId, featureId)`.
|
|
27
|
+
|
|
28
|
+
## Step 4: Fetch Coverage Report
|
|
29
|
+
|
|
30
|
+
Call `get_coverage_report(workspaceId, featureId)`. Treat a `null` `report` (no run yet) as gate-clear and skip the coverage line — otherwise compute:
|
|
31
|
+
- **bound**: `boundButNotExecutable.length + executableButNotObserved.length` (ops bound to a JEP but not yet observed)
|
|
32
|
+
- **inconclusive**: `observedButInconclusive.length`
|
|
33
|
+
- **failed**: `decisiveFailures.length`
|
|
34
|
+
- **scope**: `executionContexts.join(",")` (typically `API`)
|
|
35
|
+
|
|
36
|
+
## Step 5: Render Summary
|
|
37
|
+
|
|
38
|
+
From the workbook response, compute:
|
|
39
|
+
- **Journeys**: count by status (PASSING, FAILING, PENDING, SKIPPED) — only count `enforced` journeys for the X/Y ratio
|
|
40
|
+
- **Tasks**: count by status (CONFIRMED, PUSHED, DONE, IN_PROGRESS, PENDING) — show confirmation progress: "X/Y confirmed"
|
|
41
|
+
- **Issues**: count OPEN issues, group by severity
|
|
42
|
+
- **Latest verify**: timestamp of most recent entry in `verifierRuns`, and its pass/total count
|
|
43
|
+
|
|
44
|
+
Display:
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
Feature: <featureName> (<lifecycle status>)
|
|
48
|
+
Journeys: X/Y passing, Z failing, W pending
|
|
49
|
+
Tasks: N total — A confirmed, B pushed, C done, D in progress, E pending
|
|
50
|
+
Issues: M open (severities)
|
|
51
|
+
Verify: last run <relative time> — X/Y
|
|
52
|
+
Coverage: A bound · B inconclusive · C failed · scope=<scope>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
If the coverage report was null (no run processed yet), drop the `Coverage:` line entirely. If `lifecycleBlocking` is `true`, append ` ⛔ blocks VERIFIED` to the coverage line.
|
|
56
|
+
|
|
57
|
+
If there are **OPEN HIGH issues**, list each:
|
|
58
|
+
```
|
|
59
|
+
HIGH issues:
|
|
60
|
+
- <summary>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
If there are **FAILING journeys**, list each:
|
|
64
|
+
```
|
|
65
|
+
Failing journeys:
|
|
66
|
+
JOURNEY-X: <description>
|
|
67
|
+
JOURNEY-Y: <description>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
If there are **IN_PROGRESS tasks**, list each:
|
|
71
|
+
```
|
|
72
|
+
In-progress tasks:
|
|
73
|
+
- <title>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Keep the output compact. No extra explanations unless the user asks follow-up questions.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sync
|
|
3
|
+
description: Sync your current work to the Dezycro workbook — creates tasks, records decisions, links commits, and flags issues. Run periodically during development to keep the workbook current.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Sync Agent Context
|
|
7
|
+
|
|
8
|
+
You are reviewing what work has been done on the active feature and updating the Dezycro workbook to reflect it.
|
|
9
|
+
|
|
10
|
+
## Step 1: Read Active Feature
|
|
11
|
+
|
|
12
|
+
Read `.dezycro/active-feature.json` and `.dezycro/config.json`. If no active feature, tell the user to run `/dezycro:work` first.
|
|
13
|
+
|
|
14
|
+
## Step 2: Get Current Workbook State
|
|
15
|
+
|
|
16
|
+
Call `get_workbook(workspaceId, featureId)` to see what's already tracked.
|
|
17
|
+
|
|
18
|
+
## Step 3: Review Recent Work
|
|
19
|
+
|
|
20
|
+
Look at what has happened since the feature was loaded:
|
|
21
|
+
|
|
22
|
+
1. **Git commits**: Run `git log --oneline --since="<selectedAt from active-feature.json>"` to see commits made during this session.
|
|
23
|
+
|
|
24
|
+
2. **Files changed**: Run `git diff --name-only HEAD~5` (or since the feature was loaded) to understand what areas were touched.
|
|
25
|
+
|
|
26
|
+
3. **Current conversation context**: Review what you've been working on in this session — decisions made, problems encountered, assumptions relied on.
|
|
27
|
+
|
|
28
|
+
## Step 4: Update Workbook
|
|
29
|
+
|
|
30
|
+
For each item identified, use the appropriate MCP tool:
|
|
31
|
+
|
|
32
|
+
### Tasks
|
|
33
|
+
- For each distinct unit of work completed or in progress, check if a matching task exists in the workbook.
|
|
34
|
+
- If not, call `create_task(workspaceId, featureId, title, journeyRefs, intentRefs, notes)` to create it.
|
|
35
|
+
- If a task exists and its status changed (e.g., you finished implementing it), call `update_task(workspaceId, featureId, taskId, status)`.
|
|
36
|
+
- Link tasks to the required journeys they cover (`journeyRefs`).
|
|
37
|
+
|
|
38
|
+
### Decisions
|
|
39
|
+
- For any architectural or design decision made during the session, call `add_decision(workspaceId, featureId, summary, reason, journeyRefs)`.
|
|
40
|
+
- Include the rationale — this is the audit trail for why code was written a certain way.
|
|
41
|
+
|
|
42
|
+
### Issues
|
|
43
|
+
- For any issue that blocked progress or required a workaround, call `add_issue(workspaceId, featureId, summary, severity, intentRefs)`.
|
|
44
|
+
- Use HIGH for things that prevent journey completion, MEDIUM for workarounds, LOW for minor friction.
|
|
45
|
+
|
|
46
|
+
### Assumptions
|
|
47
|
+
- For any assumption made that hasn't been validated, call `add_assumption(workspaceId, featureId, summary)`.
|
|
48
|
+
|
|
49
|
+
### Artifacts
|
|
50
|
+
- For meaningful commits, call `link_artifact(workspaceId, featureId, artifactType="COMMIT", ref=<commit SHA>, linkedIds=<task IDs>)`.
|
|
51
|
+
- For PRs, call `link_artifact(workspaceId, featureId, artifactType="PR", ref=<PR URL>)`.
|
|
52
|
+
|
|
53
|
+
## Step 5: Display Summary
|
|
54
|
+
|
|
55
|
+
Show what was synced:
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
Workbook synced for "<featureName>"
|
|
59
|
+
|
|
60
|
+
Tasks: X created, Y updated
|
|
61
|
+
Decisions: N recorded
|
|
62
|
+
Issues: M flagged
|
|
63
|
+
Artifacts: P linked
|
|
64
|
+
|
|
65
|
+
Current state:
|
|
66
|
+
Journeys: A/B passing
|
|
67
|
+
Tasks: C done, D in progress, E pending
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Guidelines
|
|
71
|
+
|
|
72
|
+
- Don't create duplicate tasks — check existing tasks before creating new ones.
|
|
73
|
+
- Be specific in task titles — "Implement login endpoint" not "Work on feature".
|
|
74
|
+
- Always include `journeyRefs` when the work covers a specific required journey.
|
|
75
|
+
- Record decisions even if they seem obvious — the workbook is for humans reviewing later.
|
|
76
|
+
- Don't over-sync — only record meaningful work, not every small edit.
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: verify
|
|
3
|
+
description: Pull the latest verifier binary, run it against the local (or remote) environment, and upload results to the workbook. Requires an active feature (run /dezycro:work first). Accepts optional --env argument to select environment.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Run Dezycro Verification
|
|
7
|
+
|
|
8
|
+
You are pulling the verifier binary for the active feature, running it against the configured environment, and uploading results.
|
|
9
|
+
|
|
10
|
+
## Step 0: Check for Pending Spec Publish (Pillar 2)
|
|
11
|
+
|
|
12
|
+
Before running verify, check whether Companion's controller-edit tracker recorded any controller-path edits since the last spec publish. The PostToolUse hook flips `needsSpecPublish=true` whenever an Edit/Write/MultiEdit touches a file matching `companion.autoVerify.controllerPaths` (TRD §5.2).
|
|
13
|
+
|
|
14
|
+
Run:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
companion-runner state --get
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
(If the binary isn't on PATH, fall back to `node ${CLAUDE_PLUGIN_ROOT}/hooks/companion-runner state --get`.)
|
|
21
|
+
|
|
22
|
+
Parse the JSON. If `needsSpecPublish === true` AND `controllerEditsSinceLastPublish` is non-empty:
|
|
23
|
+
|
|
24
|
+
1. Print the announcement verbatim (replacing `<list>` with the paths from `controllerEditsSinceLastPublish[*].path`, comma-separated):
|
|
25
|
+
|
|
26
|
+
> Controllers changed since last published spec: \<list\>. Publishing spec before verify.
|
|
27
|
+
|
|
28
|
+
2. Invoke `/dezycro:publish-spec` programmatically before continuing.
|
|
29
|
+
|
|
30
|
+
3. Poll the feature's `verifyPending` flag every 5 seconds (call `get_workbook(workspaceId, featureId)` and read the feature record) until it clears or 5 minutes elapse — this matches the verifier compile SLA.
|
|
31
|
+
|
|
32
|
+
4. After publish-spec returns control, clear the flags so the same edits don't re-trigger on the next verify:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
companion-runner state --patch='{"needsSpecPublish": false, "controllerEditsSinceLastPublish": []}'
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Note the `=` after `--patch` — the argv parser requires the `=` form (space-separated form is reserved for the `--route` flag).
|
|
39
|
+
|
|
40
|
+
5. Continue to Step 1.
|
|
41
|
+
|
|
42
|
+
If `needsSpecPublish` is false (or `companion-state.json` is missing), continue to Step 1 immediately. If the `companion-runner` binary isn't installed (Companion V1 repos), skip Step 0 entirely.
|
|
43
|
+
|
|
44
|
+
## Step 1: Read Active Feature
|
|
45
|
+
|
|
46
|
+
Read `.dezycro/active-feature.json` using the Read tool. If the file does not exist, tell the user:
|
|
47
|
+
|
|
48
|
+
> No active feature. Run `/dezycro:work <feature-name>` first to select a feature.
|
|
49
|
+
|
|
50
|
+
Then stop.
|
|
51
|
+
|
|
52
|
+
Extract `featureId` and `featureName`.
|
|
53
|
+
|
|
54
|
+
## Step 2: Read Config
|
|
55
|
+
|
|
56
|
+
Read `.dezycro/config.json` using the Read tool. Extract `workspaceId` and `environments`.
|
|
57
|
+
|
|
58
|
+
Parse the command arguments (`$ARGUMENTS`) for `--env <name>`. If provided, use that environment. Otherwise, find the environment with `"default": true`. If no default, use the first environment.
|
|
59
|
+
|
|
60
|
+
Extract from the selected environment:
|
|
61
|
+
- `setup` (optional) — command to start the environment
|
|
62
|
+
- `apiUrl` (required) — base URL for the verifier
|
|
63
|
+
- `healthCheck` (optional) — command to check if environment is ready
|
|
64
|
+
- `teardown` (optional) — command to stop the environment
|
|
65
|
+
|
|
66
|
+
## Step 3: Environment Setup
|
|
67
|
+
|
|
68
|
+
If the selected environment has a `setup` command:
|
|
69
|
+
|
|
70
|
+
1. Run the setup command via Bash tool.
|
|
71
|
+
2. If there's a `healthCheck` command, poll it:
|
|
72
|
+
- Run the health check command via Bash.
|
|
73
|
+
- If it fails (non-zero exit), wait 2 seconds and retry.
|
|
74
|
+
- Retry up to 15 times (30 seconds total).
|
|
75
|
+
- If still failing after 15 retries, tell the user:
|
|
76
|
+
> Environment health check failed after 30 seconds. Check your setup command and health check endpoint.
|
|
77
|
+
> Setup: `<setup command>`
|
|
78
|
+
> Health check: `<healthCheck command>`
|
|
79
|
+
- Then stop.
|
|
80
|
+
|
|
81
|
+
If no `setup` command, skip this step. If there's a `healthCheck` but no `setup`, still run the health check.
|
|
82
|
+
|
|
83
|
+
## Step 4: Pull Verifier Binary
|
|
84
|
+
|
|
85
|
+
1. Detect the platform by running via Bash:
|
|
86
|
+
```bash
|
|
87
|
+
echo "$(uname -s | tr '[:upper:]' '[:lower:]')/$(uname -m | sed 's/x86_64/amd64/' | sed 's/aarch64/arm64/')"
|
|
88
|
+
```
|
|
89
|
+
This gives you the platform string like `darwin/arm64` or `linux/amd64`.
|
|
90
|
+
|
|
91
|
+
2. Call `pull_verifier(featureId, platform)` via MCP (using the `pull_verifier` tool with `featureId` and `platform` parameters).
|
|
92
|
+
|
|
93
|
+
3. If the tool returns an error indicating no binary exists:
|
|
94
|
+
- Check generation status by calling `generation_status(workspaceId, featureId)` via MCP.
|
|
95
|
+
- If generation is **in progress** (status is not IDLE/COMPLETE/FAILED):
|
|
96
|
+
- Tell the user: "JEP generation in progress — waiting for binary..."
|
|
97
|
+
- Poll `generation_status` every 15 seconds, up to 20 times (5 minutes).
|
|
98
|
+
- Show a brief status update every poll: "Still generating... (<status>)"
|
|
99
|
+
- Once status is COMPLETE, retry `pull_verifier`.
|
|
100
|
+
- If status is FAILED or timeout reached, tell the user:
|
|
101
|
+
> JEP generation failed or timed out. Check the generation logs or run `/dezycro:publish-spec` to retry.
|
|
102
|
+
- Then stop.
|
|
103
|
+
- If generation is **IDLE** (never started):
|
|
104
|
+
- Tell the user:
|
|
105
|
+
> No verifier binary available. The feature needs an API spec first.
|
|
106
|
+
> Run `/dezycro:publish-spec` to upload your spec and trigger JEP generation.
|
|
107
|
+
- Then stop.
|
|
108
|
+
|
|
109
|
+
4. From the response, extract `downloadUrl`, `contentHash`, and any CLI usage hints.
|
|
110
|
+
|
|
111
|
+
5. Check if the binary is already cached:
|
|
112
|
+
```bash
|
|
113
|
+
ls .dezycro/bin/<contentHash>/dezycro-verify 2>/dev/null && echo "cached" || echo "not-cached"
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
6. If not cached, download and cache it:
|
|
117
|
+
```bash
|
|
118
|
+
mkdir -p .dezycro/bin/<contentHash>
|
|
119
|
+
curl -fSL -o .dezycro/bin/<contentHash>/dezycro-verify "<downloadUrl>"
|
|
120
|
+
chmod +x .dezycro/bin/<contentHash>/dezycro-verify
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Step 5: Load Auth Personas (from `.dezycro/auth.local.json`)
|
|
124
|
+
|
|
125
|
+
The generated verifier expects each persona's auth config to be present as an environment variable whose name is declared in `.dezycro/auth.local.json` (`personas.<name>.envVar`, e.g. `AUTH_ADMIN1`). Without these, every authenticated request fails and the run looks broken for the wrong reason. Full schema in `PERSONAS.md` in the claude-plugin (`!file:` / `!env:` / `!cmd:` secret backends, `${VAR}` placeholders, auth types: `bearer`/`basic`/`header`/`http_endpoint`/`js`/`none`).
|
|
126
|
+
|
|
127
|
+
Use `dezycro-resolve-auth` — it reads `.dezycro/auth.local.json`, resolves secrets, substitutes `${…}` placeholders, and emits `export KEY='value'` lines that must be consumed via `eval` (so the shell strips the quotes before the binary sees the value — `env $(…)` does NOT work here and will produce `invalid character '\''` JSON parse errors):
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
eval "$(dezycro-resolve-auth)"
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
If the binary isn't on PATH (plugin not installed globally), fall back to invoking the script directly from the repo's claude-plugin dir:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
eval "$(node claude-plugin/bin/resolve-auth.js)"
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Do not hand-roll the exports from `.github/workflows/ci.yml` — `auth.local.json` is the source of truth and will drift if you do.
|
|
140
|
+
|
|
141
|
+
If `.dezycro/auth.local.json` does not exist, the script prints a stderr warning and emits nothing — `eval` of empty input is a no-op, which is the right behavior (dev/prod runs may inject credentials another way, or the user may have already exported them). Per-persona secret failures are stderr warnings only, so a missing `!file:` secret for one persona will NOT block unrelated personas.
|
|
142
|
+
|
|
143
|
+
## Step 6: Run Verifier
|
|
144
|
+
|
|
145
|
+
Run the verifier binary via Bash, in the same shell invocation as the `eval` from Step 5 so the exports carry over:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
eval "$(dezycro-resolve-auth)"
|
|
149
|
+
.dezycro/bin/<contentHash>/dezycro-verify run --all --base-url <apiUrl> --json
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Capture the full stdout output. The verifier outputs JSON with path results.
|
|
153
|
+
|
|
154
|
+
If the binary fails to execute (non-zero exit with no JSON output), show stderr and suggest:
|
|
155
|
+
> Verifier binary failed to execute. Try:
|
|
156
|
+
> - `./dezycro-verify doctor` to check connectivity
|
|
157
|
+
> - Verify your API is running at `<apiUrl>`
|
|
158
|
+
> - Check that the binary matches your platform
|
|
159
|
+
> - Confirm the expected `AUTH_*` env vars from `.dezycro/auth.local.json` are set
|
|
160
|
+
|
|
161
|
+
## Step 7: Upload Results
|
|
162
|
+
|
|
163
|
+
Take the JSON output from Step 6 and call `record_verifier_run` via MCP:
|
|
164
|
+
- `workspaceId`: from config
|
|
165
|
+
- `featureId`: from active feature
|
|
166
|
+
- `results`: the full JSON output as a string
|
|
167
|
+
- `specHash`, `flowVersion`, `jepVersion`: extract from the verifier JSON output's metadata section if present, otherwise omit
|
|
168
|
+
|
|
169
|
+
This automatically updates journey statuses in the workbook and may trigger lifecycle transitions (IN_PROGRESS -> VERIFIED if all enforced journeys pass and all journey-linked tasks are PUSHED).
|
|
170
|
+
|
|
171
|
+
## Step 8: Display Results
|
|
172
|
+
|
|
173
|
+
Parse the JSON output and display a summary:
|
|
174
|
+
|
|
175
|
+
```
|
|
176
|
+
Verification Results: X/Y passed
|
|
177
|
+
|
|
178
|
+
PASSING:
|
|
179
|
+
JOURNEY-1: <description>
|
|
180
|
+
JOURNEY-2: <description>
|
|
181
|
+
|
|
182
|
+
FAILING:
|
|
183
|
+
JOURNEY-3: <description>
|
|
184
|
+
-> <HTTP method> <endpoint> returned <actual status> (expected <expected status>)
|
|
185
|
+
-> Intent: "<intent reference>"
|
|
186
|
+
|
|
187
|
+
SKIPPED:
|
|
188
|
+
JOURNEY-8: <description> (not enforced)
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Step 9: Surface Coverage Gaps
|
|
192
|
+
|
|
193
|
+
The verifier run also feeds the coverage projection. Call `get_coverage_report(workspaceId, featureId)` once the upload from Step 7 has settled. If the response carries a `null` report, skip this step — the projection materializes asynchronously and may not be ready on the first call.
|
|
194
|
+
|
|
195
|
+
If the report is present, take the top 3 entries (in this priority order) from `decisiveFailures` first, then `observedButInconclusive` to fill the remaining slots, and surface them with action hints derived from `verdict`:
|
|
196
|
+
|
|
197
|
+
| Verdict | Action hint |
|
|
198
|
+
|--------------------------------------|--------------------------------------------------------------------------------------|
|
|
199
|
+
| `FAIL_DECISIVE_ROUTE_MISSING` | Endpoint not implemented — implement it or remove from the spec |
|
|
200
|
+
| `FAIL_DECISIVE_CONTRACT` | Response shape does not match the spec — fix the endpoint or update the spec |
|
|
201
|
+
| `FAIL_DECISIVE_PERSISTENCE` | State did not persist — investigate the write path |
|
|
202
|
+
| `INCONCLUSIVE_AUTH_REQUIRED` | Supply an auth fixture in `.dezycro/auth.local.json` for the persona that owns it |
|
|
203
|
+
| `INCONCLUSIVE_SETUP_REQUIRED` | Required setup state is missing — supply prerequisites (parent resource, fixture) |
|
|
204
|
+
| `INCONCLUSIVE_INPUT_CONSTRAINT` | Input did not satisfy a constraint — supply a valid fixture for the parameter |
|
|
205
|
+
|
|
206
|
+
Display:
|
|
207
|
+
|
|
208
|
+
```
|
|
209
|
+
Coverage gaps (top 3):
|
|
210
|
+
- <operationId> [<verdict>] -> <action hint>
|
|
211
|
+
- <operationId> [<verdict>] -> <action hint>
|
|
212
|
+
- <operationId> [<verdict>] -> <action hint>
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
If the report has zero entries in both buckets, print `Coverage: clear ✓` instead. If `lifecycleBlocking` is `true`, prepend a one-line note: `⛔ Coverage gate blocks VERIFIED until the entries below are addressed.`
|
|
216
|
+
|
|
217
|
+
## Step 9b: Update Companion State (Pillar 4)
|
|
218
|
+
|
|
219
|
+
Tell Companion the verify completed and snapshot the coverage counts so the Stop-hook delta and pre-PUSH nudge can compare against the next run (TRD §5.4.1). Extract three counts from the `get_coverage_report` response from Step 9:
|
|
220
|
+
|
|
221
|
+
- `uncoveredPaths` — count of paths with no covering journey
|
|
222
|
+
- `endpointsNotInSpec` — count of observed endpoints absent from the spec
|
|
223
|
+
- `staleBaselines` — count of baselines older than `staleBaselineDays` (default 14)
|
|
224
|
+
|
|
225
|
+
If the report was null/missing, set all three to 0. Then run:
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
companion-runner state --patch='{"lastVerifyCompletionTs":"<iso-8601-now>","coverageSnapshot":{"uncoveredPaths":<n>,"endpointsNotInSpec":<n>,"staleBaselines":<n>}}'
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
(Fall back to `node ${CLAUDE_PLUGIN_ROOT}/hooks/companion-runner state --patch=…` if the binary isn't on PATH. Skip the entire step if the binary isn't installed — V1 repos.)
|
|
232
|
+
|
|
233
|
+
This is a fire-and-forget bookkeeping step. If the patch returns a lock-contention error, do not retry — the next verify will overwrite.
|
|
234
|
+
|
|
235
|
+
## Step 10: Teardown (Optional)
|
|
236
|
+
|
|
237
|
+
If the selected environment has a `teardown` command, ask the user:
|
|
238
|
+
|
|
239
|
+
> Want to tear down the environment? (`<teardown command>`)
|
|
240
|
+
|
|
241
|
+
If yes, run it via Bash.
|
|
242
|
+
|
|
243
|
+
## Next Steps
|
|
244
|
+
|
|
245
|
+
Based on results:
|
|
246
|
+
- **All journeys passing**: "All journeys passing! The feature may auto-transition to VERIFIED."
|
|
247
|
+
- **Some failures**: "Fix the failing journeys and run `/dezycro:verify` again. Focus on: <list top 2-3 failing journeys>."
|
|
248
|
+
- **No journeys passing**: "No journeys passing yet. Review the failing assertions and start implementing the feature endpoints."
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: work
|
|
3
|
+
description: Start or resume working on a Dezycro feature — gates on PRD/TRD/graph approval, interactively helps pick a feature when none is given, and binds the session to the workbook as the source of truth. Use when starting a coding session. Accepts an optional feature name or UUID as argument.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Start/Resume Feature Work
|
|
7
|
+
|
|
8
|
+
You are loading a Dezycro feature's full context so the developer can start (or resume) working on it. **The workbook is the source of truth** — local files (`.dezycro/active-feature.json`) are only a session pointer; every meaningful state change goes through MCP workbook tools.
|
|
9
|
+
|
|
10
|
+
## Hard Rules — Read Before Anything Else
|
|
11
|
+
|
|
12
|
+
1. **No approved graph → no work.** A feature with `lifecycleStatus == "DRAFT"` has no approved flow graph, which means no journeys, no JEP, no agent context. **Refuse to start a coding session on it.** Walk the user to the webapp to approve the graph instead. (Lifecycle: `DRAFT` → `APPROVED` happens automatically when the flow graph is approved.)
|
|
13
|
+
2. **No PRD or TRD → no work.** Even if the feature is `APPROVED`, both PRD and TRD documents must exist and be at `status == "COMPLETE"`. Without finalized docs, the agent context is incomplete and you will hallucinate.
|
|
14
|
+
3. **Workbook is canonical.** Every issue you find, every decision you make, every task you complete during this session is persisted to the workbook via MCP tools (`add_issue`, `add_decision`, `add_assumption`, `update_task`, `update_issue`). **Do not** keep findings in scratch files or "I'll remember it" memory — it does not survive the session and the PM cannot see it.
|
|
15
|
+
4. **Lifecycle states allowed for coding:** `APPROVED`, `IN_PROGRESS`, `VERIFIED`. Refuse: `DRAFT`, `SHIPPED`, `ABANDONED` (offer to reopen with the user's confirmation for `ABANDONED`/`SHIPPED`, but do not just dive in).
|
|
16
|
+
|
|
17
|
+
## Step 1: Read Config
|
|
18
|
+
|
|
19
|
+
Read `.dezycro/config.json` from the repository root using the Read tool. If the file does not exist, tell the user:
|
|
20
|
+
|
|
21
|
+
> No `.dezycro/config.json` found. Run `/dezycro:init` first to set up this repository.
|
|
22
|
+
|
|
23
|
+
Then stop.
|
|
24
|
+
|
|
25
|
+
Extract `workspaceId` and `projectId` from the config.
|
|
26
|
+
|
|
27
|
+
## Step 2: Resolve Feature
|
|
28
|
+
|
|
29
|
+
The user may provide a feature name or UUID as the command argument: `$ARGUMENTS`
|
|
30
|
+
|
|
31
|
+
### 2a. If `$ARGUMENTS` is a UUID
|
|
32
|
+
|
|
33
|
+
(Matches pattern `[0-9a-f]{8}-[0-9a-f]{4}-...`.) Use it directly as `featureId`. You will need to fetch its full record later to read `lifecycleStatus`, `name`, and `breadcrumb` — do that by calling `search_features(workspaceId, projectId, query=<the UUID's first 8 chars>)` and matching by `id`, OR by skipping ahead to the lifecycle check via `get_workbook` and `list_feature_documents` and accepting that you'll surface the name from those.
|
|
34
|
+
|
|
35
|
+
### 2b. If `$ARGUMENTS` is a non-empty string (feature name / substring)
|
|
36
|
+
|
|
37
|
+
Call `search_features(workspaceId, projectId, query=$ARGUMENTS)`.
|
|
38
|
+
|
|
39
|
+
- **Exactly one match**: use it.
|
|
40
|
+
- **Multiple matches**: use `AskUserQuestion` with up to 4 options. Label each `<featureName> — <breadcrumb path> · <lifecycleStatus>`. If more than 4 matches, show the 4 most recently updated and add a 5th catch-all "None of these — refine the search" option that re-prompts for a new query.
|
|
41
|
+
- **No matches**: tell the user "No features matched `<query>`. Run `/dezycro:work` with no argument to browse." Then stop.
|
|
42
|
+
|
|
43
|
+
### 2c. If `$ARGUMENTS` is empty — interactive picker
|
|
44
|
+
|
|
45
|
+
This is the path most demos and resumed sessions hit. **Do not** dump a flat list of every feature — that's noisy. Help the user navigate.
|
|
46
|
+
|
|
47
|
+
1. **Call `list_features(workspaceId, projectId)`** (omit `parentDirectoryId` to get the project root). The response has:
|
|
48
|
+
- `directories[]` with `id`, `name`, `namePath`, `updateTimestamp`
|
|
49
|
+
- `features[]` with `id`, `name`, `lifecycleStatus`, `updateTimestamp`, `breadcrumb`, `documentSummaries`
|
|
50
|
+
|
|
51
|
+
2. **Sort `directories[]` by `updateTimestamp` descending** and take the top 5.
|
|
52
|
+
|
|
53
|
+
3. **Sort root-level `features[]` by `updateTimestamp` descending** and take the top 3 — these are likely active work too.
|
|
54
|
+
|
|
55
|
+
4. **Use `AskUserQuestion`** with a single question titled "Where do you want to work?" and options built from the sorted lists. Aim for ≤4 options total (the tool's max). Prioritize in this order:
|
|
56
|
+
- The 2 most recently updated directories (label: `📁 <namePath> — updated <relative time>`)
|
|
57
|
+
- The most recently updated root-level feature, if any (label: `📄 <name> · <lifecycleStatus>`)
|
|
58
|
+
- One "🔍 Search by name" option (description: "Type a feature name to search across the whole project")
|
|
59
|
+
- Always include "📂 Browse from root" as a fallback if you have to drop options to stay ≤4
|
|
60
|
+
|
|
61
|
+
The user can always pick "Other" to type a custom answer (e.g., a path like `Backend/Auth/Login` or a folder name).
|
|
62
|
+
|
|
63
|
+
5. **Handle the response:**
|
|
64
|
+
- **Folder option** → call `list_features(workspaceId, projectId, parentDirectoryId=<folder.id>)`. Show its directories + features the same way (recently updated first). Recurse until the user picks a feature. Always include a "⬅ Go back" option once you're below the root.
|
|
65
|
+
- **Root feature option** → use that feature directly.
|
|
66
|
+
- **Search option** → ask the user for a query, then call `search_features` and resume at 2b.
|
|
67
|
+
- **"Other" / custom text** → treat as a search query (run `search_features`).
|
|
68
|
+
|
|
69
|
+
Store the resolved `featureId`, `featureName`, and `lifecycleStatus`.
|
|
70
|
+
|
|
71
|
+
## Step 3: Lifecycle Gate (HARD STOP if ungated)
|
|
72
|
+
|
|
73
|
+
You now have a candidate feature. **Before loading anything else**, validate it's workable:
|
|
74
|
+
|
|
75
|
+
1. If you don't yet have `lifecycleStatus` (e.g. user passed a raw UUID), call `get_workbook(workspaceId, featureId)` and read the feature's status via the parent lookup, OR call `search_features` with a fragment to recover it. The cheapest path: just call `list_feature_documents(workspaceId, featureId)` and `get_workbook(...)` next — both return enough metadata to fail-fast.
|
|
76
|
+
|
|
77
|
+
2. **Check `lifecycleStatus`:**
|
|
78
|
+
- `DRAFT` → **REFUSE**. Print:
|
|
79
|
+
> ⛔ Feature **<name>** is in `DRAFT` — the flow graph hasn't been approved yet, so there's no agent context, no journeys, and no JEP. I won't start a coding session on it.
|
|
80
|
+
>
|
|
81
|
+
> **What to do:** open the feature in the webapp, review the flow graph, and approve it. Once approved, the workbook initializes automatically and `/dezycro:work` will load it.
|
|
82
|
+
|
|
83
|
+
Then stop. Do NOT write `.dezycro/active-feature.json`.
|
|
84
|
+
- `SHIPPED` → **REFUSE**. Print:
|
|
85
|
+
> ⛔ Feature **<name>** is `SHIPPED`. There's nothing to do here. If you need to extend it, create a new feature or ask the PM to reopen this one.
|
|
86
|
+
|
|
87
|
+
Then stop.
|
|
88
|
+
- `ABANDONED` → **REFUSE by default**. Print:
|
|
89
|
+
> ⛔ Feature **<name>** is `ABANDONED`. If this was a mistake, reopen it in the webapp first. I won't start a coding session on an abandoned feature without that step.
|
|
90
|
+
|
|
91
|
+
Then stop.
|
|
92
|
+
- `APPROVED`, `IN_PROGRESS`, `VERIFIED` → continue to step 4.
|
|
93
|
+
|
|
94
|
+
3. **Check documents** — call `list_feature_documents(workspaceId, featureId)`. You need:
|
|
95
|
+
- At least one document with `type == "PRD"` and `status == "COMPLETE"`.
|
|
96
|
+
- At least one document with `type == "TRD"` and `status == "COMPLETE"`.
|
|
97
|
+
|
|
98
|
+
If either is missing or still `DRAFT` / `IN_PROGRESS`, **REFUSE**:
|
|
99
|
+
> ⛔ Feature **<name>** is `<lifecycleStatus>` but its documents aren't finalized:
|
|
100
|
+
> - PRD: <status or "missing">
|
|
101
|
+
> - TRD: <status or "missing">
|
|
102
|
+
>
|
|
103
|
+
> Without a finalized PRD and TRD, the agent context is incomplete and I will hallucinate. Finish the docs in the webapp first.
|
|
104
|
+
|
|
105
|
+
Then stop. Do NOT write `.dezycro/active-feature.json`.
|
|
106
|
+
|
|
107
|
+
## Step 4: Load Workbook
|
|
108
|
+
|
|
109
|
+
Call `get_workbook(workspaceId, featureId)`.
|
|
110
|
+
|
|
111
|
+
From the response, extract:
|
|
112
|
+
- `status` — the workbook/feature lifecycle status (NOT_STARTED / ACTIVE / COMPLETE)
|
|
113
|
+
- `journeys` — list with `journeyId`, `description`, `status` (PENDING/PASSING/FAILING/SKIPPED), `enforced`
|
|
114
|
+
- `tasks` — list with `id`, `title`, `status` (PENDING/IN_PROGRESS/DONE/PUSHED/CONFIRMED)
|
|
115
|
+
- `issues` — list with `summary`, `severity`, `status` (OPEN/RESOLVED/PUSHED/CLOSED)
|
|
116
|
+
- `verifierRuns` — list, take the most recent one for timestamp and results
|
|
117
|
+
|
|
118
|
+
## Step 5: Load Documents
|
|
119
|
+
|
|
120
|
+
Call `list_feature_documents(workspaceId, featureId)` to get document IDs (you already have the list from Step 3 — reuse it).
|
|
121
|
+
|
|
122
|
+
For each finalized document (PRD and TRD):
|
|
123
|
+
- Call `get_document(workspaceId, featureId, docId)`.
|
|
124
|
+
- Note the word count of the content.
|
|
125
|
+
|
|
126
|
+
Read both the PRD and TRD content — you will need this context to help the developer.
|
|
127
|
+
|
|
128
|
+
## Step 6: Write Active Feature (session pointer only)
|
|
129
|
+
|
|
130
|
+
Write `.dezycro/active-feature.json` using the Write tool:
|
|
131
|
+
|
|
132
|
+
```json
|
|
133
|
+
{
|
|
134
|
+
"featureId": "<resolved featureId>",
|
|
135
|
+
"featureName": "<resolved featureName>",
|
|
136
|
+
"selectedAt": "<current ISO 8601 timestamp>"
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Create the `.dezycro/` directory first if it doesn't exist: `mkdir -p .dezycro`
|
|
141
|
+
|
|
142
|
+
**This file is a pointer, not state.** It tells `/dezycro:status` and `/dezycro:verify` which feature is active. Any actual work — tasks, issues, decisions — lives in the workbook.
|
|
143
|
+
|
|
144
|
+
## Step 7: Display Summary
|
|
145
|
+
|
|
146
|
+
Present the feature context to the user in this format:
|
|
147
|
+
|
|
148
|
+
```
|
|
149
|
+
Feature: <featureName> (<lifecycleStatus>)
|
|
150
|
+
Path: <breadcrumb joined with " / ">
|
|
151
|
+
|
|
152
|
+
Journeys: X/Y passing, Z failing, W pending
|
|
153
|
+
Tasks: N total — A confirmed, B pushed, C done, D in progress, E pending
|
|
154
|
+
Issues: M open (list severities)
|
|
155
|
+
Verify: <timestamp or "never"> — X/Y journeys
|
|
156
|
+
|
|
157
|
+
PRD loaded (N words) | TRD loaded (M words)
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
If there are **failing journeys**, list them:
|
|
161
|
+
```
|
|
162
|
+
Failing journeys:
|
|
163
|
+
JOURNEY-X: <description> — FAILING
|
|
164
|
+
JOURNEY-Y: <description> — FAILING
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
If there are **open HIGH issues**, list them:
|
|
168
|
+
```
|
|
169
|
+
Open HIGH issues:
|
|
170
|
+
- <summary>
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
If there are **in-progress tasks**, list them:
|
|
174
|
+
```
|
|
175
|
+
In-progress tasks:
|
|
176
|
+
- <title>
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Step 8: Operating Rules (Show Once, Then Enforce)
|
|
180
|
+
|
|
181
|
+
After the summary, print this reminder verbatim so the developer sees what the agent will and won't do during the session:
|
|
182
|
+
|
|
183
|
+
> **Workbook is the source of truth for this session.**
|
|
184
|
+
> - I will record every issue I find via `add_issue` — not in chat-only or scratch files.
|
|
185
|
+
> - I will record every decision (e.g. "we chose JWT over session cookies") via `add_decision`.
|
|
186
|
+
> - I will record assumptions I'm making (e.g. "assuming all timestamps are UTC") via `add_assumption`.
|
|
187
|
+
> - I will update task status via `update_task` as I complete work — not local checkboxes.
|
|
188
|
+
> - When you tell me an issue is fixed, I will call `update_issue` to mark it RESOLVED.
|
|
189
|
+
> - Before declaring a journey done, I will run `/dezycro:verify` and let the verifier confirm.
|
|
190
|
+
>
|
|
191
|
+
> If you want me to skip the workbook for something quick (e.g. a one-off question), say so explicitly. Otherwise I will default to writing through.
|
|
192
|
+
|
|
193
|
+
## Ready
|
|
194
|
+
|
|
195
|
+
The developer now has full context. Offer:
|
|
196
|
+
|
|
197
|
+
> Ready to work on "<featureName>". What would you like to do?
|
|
198
|
+
> - Pick a failing journey or open issue to tackle
|
|
199
|
+
> - Start implementing an in-progress task
|
|
200
|
+
> - Run `/dezycro:verify` to test current state
|
|
201
|
+
> - Run `/dezycro:status` for a quick status check
|