vinta-ai-workflows 0.1.7
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 +830 -0
- package/LICENSE +21 -0
- package/README.md +547 -0
- package/package.json +27 -0
- package/schemas/README.md +84 -0
- package/schemas/mcp-preflight-cache.v1.schema.json +50 -0
- package/schemas/prs-context-comments.v1.schema.json +51 -0
- package/schemas/prs-context-frontmatter.v1.schema.json +77 -0
- package/schemas/sub-agent.v1.schema.json +105 -0
- package/schemas/vinta-ai-workflows-config.v1.schema.json +283 -0
- package/skills/vinta-analyze-codebase/SKILL.md +325 -0
- package/skills/vinta-bootstrap-ai-tools/SKILL.md +375 -0
- package/skills/vinta-bootstrap-ai-tools/resources/stacks/README.md +50 -0
- package/skills/vinta-bootstrap-ai-tools/resources/stacks/django/notes.md +52 -0
- package/skills/vinta-bootstrap-ai-tools/resources/stacks/medplum/notes.md +45 -0
- package/skills/vinta-bootstrap-ai-tools/resources/stacks/nextjs-app-router/notes.md +35 -0
- package/skills/vinta-bootstrap-ai-tools/resources/stacks/python-package/notes.md +31 -0
- package/skills/vinta-bootstrap-ai-tools/resources/stacks/typescript-monorepo/notes.md +32 -0
- package/skills/vinta-derive-skills/SKILL.md +200 -0
- package/skills/vinta-derive-skills/resources/amend-plan-template.md +355 -0
- package/skills/vinta-derive-skills/resources/foundation-skills/add-one-off-script/SKILL.md +292 -0
- package/skills/vinta-derive-skills/resources/foundation-skills/add-one-off-script/resources/one_off_script_base.py +602 -0
- package/skills/vinta-derive-skills/resources/foundation-skills/add-one-off-script/resources/one_off_script_base.ts +624 -0
- package/skills/vinta-derive-skills/resources/foundation-skills/create-qa-use-cases/SKILL.md +232 -0
- package/skills/vinta-derive-skills/resources/foundation-skills/create-spec/SKILL.md +235 -0
- package/skills/vinta-derive-skills/resources/foundation-skills/open-pr-from-context/SKILL.md +78 -0
- package/skills/vinta-derive-skills/resources/foundation-skills/open-pr-from-context/scripts/open-pr.sh +357 -0
- package/skills/vinta-derive-skills/resources/foundation-skills/plan-feature/SKILL.md +418 -0
- package/skills/vinta-derive-skills/resources/implement-plan-template.md +375 -0
- package/skills/vinta-derive-skills/resources/prs-context-template.md +91 -0
- package/skills/vinta-derive-skills/resources/systematic-debugging-mcp-tools.md +125 -0
- package/skills/vinta-derive-skills/resources/systematic-debugging-template.md +167 -0
- package/skills/vinta-derive-subagents/SKILL.md +192 -0
- package/skills/vinta-install-ai-tools-setup/SKILL.md +138 -0
- package/skills/vinta-install-ai-tools-setup/resources/setup-ai-tools.mjs +392 -0
- package/skills/vinta-migrate-plans-specs/SKILL.md +229 -0
- package/skills/vinta-sync-ai-tools/SKILL.md +184 -0
- package/skills/vinta-update-project-skills/SKILL.md +178 -0
- package/skills/vinta-write-agents-md/SKILL.md +192 -0
- package/vinta-ai-workflows.mjs +316 -0
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: systematic-debugging
|
|
3
|
+
description: Use when debugging any defect, test failure, regression, performance issue, or unexpected behavior in {{PROJECT_NAME}} ({{STACK_SUMMARY}}). Enforces a root-cause-first investigation flow before any code change is proposed. Pulls evidence from the project's observability MCP tools ({{OBSERVABILITY_MCP_LIST}}) before forming a hypothesis. Cites the project's real test, lint, and type-check commands so reproduction steps are concrete.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Systematic debugging
|
|
7
|
+
|
|
8
|
+
Random fixes mask root causes and grow new bugs on top of old ones. This skill drives debugging through four ordered phases. Each phase has an exit gate; you may not advance until the gate is satisfied.
|
|
9
|
+
|
|
10
|
+
## Iron law
|
|
11
|
+
|
|
12
|
+
> **No code change until the root cause is identified and named.**
|
|
13
|
+
|
|
14
|
+
A change that makes the symptom go away without an explanation of *why the symptom existed* is a guess, not a fix. Guesses do not ship.
|
|
15
|
+
|
|
16
|
+
## When to invoke
|
|
17
|
+
|
|
18
|
+
- Test failure (red unit, scoped, or e2e suite).
|
|
19
|
+
- Production incident or alert page.
|
|
20
|
+
- Unexpected behaviour reported by a user, QA, or another engineer.
|
|
21
|
+
- Performance regression (latency / throughput / memory).
|
|
22
|
+
- Build, type-check, lint, or deploy failure that is not obviously a typo.
|
|
23
|
+
- A previous fix did not work and you are tempted to "try one more thing".
|
|
24
|
+
|
|
25
|
+
The pressure to skip this skill is highest exactly when it is most needed. Treat "we don't have time for the process" as a signal to slow down, not speed up.
|
|
26
|
+
|
|
27
|
+
## Phase 0 — Observability sweep (MCP servers)
|
|
28
|
+
|
|
29
|
+
Before reading code, pull the evidence the platform already has. The project lists these observability MCP servers as available: **{{OBSERVABILITY_MCP_LIST}}**.
|
|
30
|
+
|
|
31
|
+
### Local-only escape hatch (per-run opt-out)
|
|
32
|
+
|
|
33
|
+
If the user passes `local-only` to this skill (e.g. `/systematic-debugging local-only — flaky test in test_foo.py`), or if the bug is obviously local — a unit test that has never run in CI, a build error on an unpushed branch, a typo — skip the entire MCP preflight + categories block. Open the Phase 0 evidence note with the line *"local-only debug at user request — no platform evidence consulted"* and continue to Phase 1. This bypass does **not** touch the cache.
|
|
34
|
+
|
|
35
|
+
If the user did not opt out, run the cached preflight below.
|
|
36
|
+
|
|
37
|
+
### Preflight — cached, with hard-stop on failure
|
|
38
|
+
|
|
39
|
+
State lives at `.vinta-ai-workflows/cache.yaml` (gitignored, schema [`mcp-preflight-cache.v1`](../../../../schemas/mcp-preflight-cache.v1.schema.json)). The cache has no TTL — `ok` entries stay valid until something proves them wrong. A failed MCP call later in this session flips the offending server to `dirty`, forcing a fresh preflight on the next debug run.
|
|
40
|
+
|
|
41
|
+
For every server in `{{OBSERVABILITY_MCP_LIST}}`:
|
|
42
|
+
|
|
43
|
+
1. **Read** the cache entry for the server.
|
|
44
|
+
2. **Cache hit (`status: ok`)** → log one line `cache hit: <server> (<tools_count> tools, verified <relative-time> ago)` and skip to "Discover the right calls" below for this server. No tool listing, no extra calls.
|
|
45
|
+
3. **Cache miss / `dirty` / `missing` / `auth-error` / `unreachable`** → run a fresh preflight:
|
|
46
|
+
- Check that an MCP server with that identifier is connected. If not, **stop and tell the user verbatim**: *"systematic-debugging requires the `<name>` MCP server, but it is not connected in this session. Connect it, run with `local-only`, or remove it from `skills.systematic-debugging.observability_mcp_servers` in `.vinta-ai-workflows.yaml`."* Write `status: missing`, `error_message: "not connected"` to the cache and stop.
|
|
47
|
+
- Confirm at least one tool from that server can be invoked. Auth error / expired token / missing API key → same hard-stop, with the upstream error message quoted verbatim. Cache as `status: auth-error`, `error_message: "<verbatim>"`.
|
|
48
|
+
- On success: write `status: ok`, `verified_at: <now>`, `tools_count: <n>` to the cache.
|
|
49
|
+
4. Do **not** silently fall back to a different server, to local logs, or to "investigate without observability". A configured-but-broken server is a configuration bug; surface it. The user can choose to re-run with `local-only` once they see the failure.
|
|
50
|
+
|
|
51
|
+
If `{{OBSERVABILITY_MCP_LIST}}` is `none configured`, the cache is irrelevant — skip the preflight and use the no-tools fallback rendered below. Warn once if the bug appears production-only: *"This bug looks production-only and no observability MCP server is configured. Re-run with `local-only` to silence this warning, or wire up an observability MCP server first."*
|
|
52
|
+
|
|
53
|
+
### Mid-session invalidation (mark dirty)
|
|
54
|
+
|
|
55
|
+
Any later MCP call that fails with auth, connection, or transport error → patch the cache entry: `status: dirty`, `verified_at: <now>`, `error_message: "<verbatim>"`, optionally `marked_dirty_during: "<phase / plan / session id>"`. Continue the debug session using whatever evidence is already collected; do not re-preflight inside the same session. The next debug run will see `dirty` and re-preflight just that server.
|
|
56
|
+
|
|
57
|
+
A successful tool call against a server that's currently marked anything other than `ok` is allowed to flip it back to `ok` — the server clearly recovered.
|
|
58
|
+
|
|
59
|
+
### Refresh the cache manually
|
|
60
|
+
|
|
61
|
+
- Force re-preflight everywhere: delete `.vinta-ai-workflows/cache.yaml`.
|
|
62
|
+
- Force re-preflight one server: edit the entry's `status` to `dirty` (or any non-ok value).
|
|
63
|
+
- Forget a server entirely: remove it from `skills.systematic-debugging.observability_mcp_servers` in `.vinta-ai-workflows.yaml` — the cache entry then becomes inert (no preflight, no warnings).
|
|
64
|
+
|
|
65
|
+
### Discover the right calls at runtime
|
|
66
|
+
|
|
67
|
+
**Do not assume tool names from training data — they go stale.** For each cache-hit server (and each server that just passed a fresh preflight), list the tools it exposes, then map them to the evidence categories below by reading their descriptions and parameter names. If a server claims to cover a category but no listed tool matches, ask the user before falling back to "no evidence available".
|
|
68
|
+
|
|
69
|
+
{{OBSERVABILITY_MCP_BLOCK}}
|
|
70
|
+
|
|
71
|
+
**Do not skip this phase because the bug "looks local".** A failing unit test on your machine and a 500 in production at the same hour is one incident, not two. The observability sweep is what reveals that.
|
|
72
|
+
|
|
73
|
+
## Phase 1 — Root cause investigation
|
|
74
|
+
|
|
75
|
+
Goal: state the cause in one sentence with a citation (file:line, log line, or trace span).
|
|
76
|
+
|
|
77
|
+
1. **Read the error completely.** Stack trace from bottom to top. Note every frame in our code — skip framework noise on the first pass, return to it only if our frames don't explain it.
|
|
78
|
+
2. **Reproduce locally.**
|
|
79
|
+
- Unit / integration: `{{TEST_CMD}}`{{SCOPED_TEST_NOTE}}
|
|
80
|
+
- Single failing test in isolation: `{{NEW_TEST_CMD_PATTERN}}`
|
|
81
|
+
- Type / build gate: `{{BUILD_CMD}}`{{TYPECHECK_NOTE}}
|
|
82
|
+
- Lint: `{{LINT_CMD}}`
|
|
83
|
+
{{E2E_BLOCK}}
|
|
84
|
+
If you cannot reproduce, gather more evidence (Phase 0 logs, traces, user repro steps). Do not propose a fix against a bug you cannot trigger.
|
|
85
|
+
3. **Bisect recent changes.** `git log --oneline {{DEFAULT_BRANCH}}..HEAD` plus `git log -p` on the suspect file. Check the deploy timeline from Phase 0 against commits.
|
|
86
|
+
4. **Trace data flow at component boundaries.** For every layer the bad value crosses (request → handler → service → store → response), log the value entering and the value leaving. Find the layer where the value changes shape unexpectedly. That layer holds the bug.
|
|
87
|
+
5. **Trace backward from the failure.** If the error is "got `undefined`", the question is not "why did this consumer crash" but "who produced `undefined` and why was that allowed to propagate".
|
|
88
|
+
|
|
89
|
+
Exit gate: write the cause as a single sentence — *"`OrderService.applyDiscount` returns `null` when the cart has zero items because the early-return at orders.ts:142 predates the empty-cart feature, and the caller at checkout.ts:88 forgot to handle null."* Vague causes ("something with discounts") fail this gate.
|
|
90
|
+
|
|
91
|
+
## Phase 2 — Pattern analysis
|
|
92
|
+
|
|
93
|
+
Goal: confirm the root cause by comparing against working code.
|
|
94
|
+
|
|
95
|
+
1. Find a sibling code path that does the *same kind of thing* and works. (Another service method, another handler, another reducer.)
|
|
96
|
+
2. Diff the working path against the broken one. Note every difference, even ones that "couldn't matter".
|
|
97
|
+
3. If the bug is in a library / framework integration, read the upstream reference implementation or docs end-to-end before continuing. Skim is not allowed.
|
|
98
|
+
4. List dependencies the broken path silently relies on (env var, feature flag, migration, cache warm-up). Verify each one is present in the failing environment.
|
|
99
|
+
|
|
100
|
+
Exit gate: you can name what the broken path is missing or doing differently, and show the working path as proof.
|
|
101
|
+
|
|
102
|
+
## Phase 3 — Hypothesis & test
|
|
103
|
+
|
|
104
|
+
Goal: a single hypothesis, a single failing test, no speculative changes.
|
|
105
|
+
|
|
106
|
+
1. State the hypothesis: *"If I change X to Y, the bug stops because Z."*
|
|
107
|
+
2. Write the failing test FIRST.
|
|
108
|
+
- New test file: `{{NEW_TEST_CMD_PATTERN}}`
|
|
109
|
+
- Scoped suite: `{{SCOPED_TEST_PATTERN}}`
|
|
110
|
+
- The test must fail today for the same reason production fails. A test that fails for a different reason is a different bug.
|
|
111
|
+
3. Make the smallest possible change. One variable. No drive-by refactors. No "while I'm here".
|
|
112
|
+
4. Re-run the failing test. Did it go green? Re-run the scoped suite — did anything else go red?
|
|
113
|
+
5. If the test stays red, do **not** stack a second change on top. Return to Phase 1 with the new evidence (the test plus what it shows) and re-state the cause.
|
|
114
|
+
|
|
115
|
+
Exit gate: one new test, red before the change, green after, no other test newly red.
|
|
116
|
+
|
|
117
|
+
## Phase 4 — Implementation & verification
|
|
118
|
+
|
|
119
|
+
Goal: ship the fix at the right level of abstraction with the right safety net.
|
|
120
|
+
|
|
121
|
+
1. **Fix at the source, not the symptom.** If null leaks from a producer, fix the producer. Defensive null-checks at the consumer are an additional layer (see "defense in depth" below), not a replacement for the source fix.
|
|
122
|
+
2. **Defense in depth where the cost is low.** Validation at the boundary, an assertion in the producer, a typed return that forbids the bad shape — pick the layer the codebase already invests in. Don't sprinkle.
|
|
123
|
+
3. **Run the full local gate before pushing.**
|
|
124
|
+
- `{{LINT_CMD}}`
|
|
125
|
+
- `{{BUILD_CMD}}`
|
|
126
|
+
- `{{TEST_CMD}}`{{SCOPED_TEST_NOTE}}
|
|
127
|
+
{{E2E_OUTER_GATE_LINE}}
|
|
128
|
+
4. **Verify on the observability side after deploy.** The error fingerprint from Phase 0 should stop firing. If the platform supports it, mark the issue resolved in the source MCP tool so a regression re-opens it instead of creating a duplicate.
|
|
129
|
+
5. **Document if the fix is non-obvious.** A comment is justified only when the *why* would surprise the next reader — a hidden invariant, a workaround for a known upstream bug, a constraint not visible from the call site. Don't narrate the change.
|
|
130
|
+
|
|
131
|
+
## Stop conditions — count your attempts
|
|
132
|
+
|
|
133
|
+
If you reach **three failed fix attempts** on the same bug, the architecture is suspect, not the next line you were about to change. Stop and escalate:
|
|
134
|
+
|
|
135
|
+
- Re-read the original report. Has the symptom drifted as you patched things?
|
|
136
|
+
- Are the three attempts each fixing a different file? That is a sign the contract between layers is wrong, not any single layer.
|
|
137
|
+
- Bring a second engineer (human or another agent) to walk Phase 1 from scratch. Don't hand them your hypothesis — hand them the symptom.
|
|
138
|
+
|
|
139
|
+
A fourth attempt without architectural review is how week-long debugging sessions start.
|
|
140
|
+
|
|
141
|
+
## Red flags — return to Phase 1 immediately
|
|
142
|
+
|
|
143
|
+
You catch yourself thinking or typing any of:
|
|
144
|
+
|
|
145
|
+
- "Quick fix now, investigate later."
|
|
146
|
+
- "Let me try changing X and see if it works."
|
|
147
|
+
- "It's probably the cache / the build / a flaky test."
|
|
148
|
+
- "I don't fully understand this but this might work."
|
|
149
|
+
- "I'll add a try/catch around it."
|
|
150
|
+
- "I'll skip writing the test, the manual repro is enough."
|
|
151
|
+
- "Let me bundle this fix with the cleanup I was going to do anyway."
|
|
152
|
+
|
|
153
|
+
These are not debugging — they are guessing with extra steps. Stop and re-enter Phase 1.
|
|
154
|
+
|
|
155
|
+
## Reusable skills the orchestrator should chain
|
|
156
|
+
|
|
157
|
+
When this skill runs inside [implement-plan](../implement-plan/SKILL.md) (the inner / outer test loop), the implementer agent invokes systematic-debugging on every red gate and reports the Phase-1 cause in its report. The orchestrator never overrides the Iron Law — a phase that can't name the cause is not allowed to land.
|
|
158
|
+
|
|
159
|
+
For new test scaffolding, defer to the project's test conventions captured in [AGENTS.md](../../AGENTS.md). For env / config issues uncovered in Phase 0, route to the project's `add-env-var` skill if shipped (`{{PROJECT_SKILLS_LIST}}`).
|
|
160
|
+
|
|
161
|
+
## Verification checklist (apply before claiming a bug fixed)
|
|
162
|
+
|
|
163
|
+
1. Phase 0 evidence stored or linked in the PR description (trace id / issue link / dashboard URL).
|
|
164
|
+
2. Root cause stated in one sentence in the PR description.
|
|
165
|
+
3. New failing-then-passing test cited by file:line.
|
|
166
|
+
4. Full local gate green: `{{LINT_CMD}}` + `{{BUILD_CMD}}` + `{{TEST_CMD}}`{{E2E_OUTER_GATE_CHECKLIST}}.
|
|
167
|
+
5. Observability source updated post-deploy (issue resolved / alert acknowledged) so a recurrence pages instead of silently re-opening.
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: vinta-derive-subagents
|
|
3
|
+
description: Author `ai-tools/agents/*.yaml` for the target project. Always emits the foundation trio (`implementer`, `reviewer`, `fixer`); adds stack-specific specialists (e.g. `deploy-author` for Medplum, `migration-author` for Django) when the inventory from [vinta-analyze-codebase](../vinta-analyze-codebase/SKILL.md) matches a stack template under [bootstrap-ai-tools/resources/stacks/](../vinta-bootstrap-ai-tools/resources/stacks/). Each YAML follows the schema documented in `ai-tools/agents/README.md` so the setup script can generate per-vendor copies.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Derive sub-agents
|
|
7
|
+
|
|
8
|
+
Author the canonical YAML sources for the target project's sub-agents. Setup script reads these later and emits per-vendor variants (Claude `.md`, Cursor `.md`, Copilot `.agent.md`, Codex `.toml`).
|
|
9
|
+
|
|
10
|
+
## Output
|
|
11
|
+
|
|
12
|
+
`ai-tools/agents/<name>.yaml` — one per sub-agent. Plus `ai-tools/agents/README.md` (schema doc) if not already present (copy from the bootstrap-defining repo).
|
|
13
|
+
|
|
14
|
+
## Inputs
|
|
15
|
+
|
|
16
|
+
1. Inventory from [vinta-analyze-codebase](../vinta-analyze-codebase/SKILL.md), specifically `existing_ai_artifacts.agents` — every sub-agent file already in the repo with its name, description, classification (`foundation-shape` / `stack-specialist` / `project-custom`).
|
|
17
|
+
2. AGENTS.md content from [vinta-write-agents-md](../vinta-write-agents-md/SKILL.md) (so agent prompts can reference real conventions).
|
|
18
|
+
3. Step 0 interview decisions from [vinta-bootstrap-ai-tools](../vinta-bootstrap-ai-tools/SKILL.md) — including the [Existing AI artifacts](../vinta-bootstrap-ai-tools/SKILL.md#e-existing-ai-artifacts-per-artifact-disposition) **per-agent disposition** (migrate / keep / drop / replace).
|
|
19
|
+
4. Stack templates under [bootstrap-ai-tools/resources/stacks/<stack>/agents/](../vinta-bootstrap-ai-tools/resources/stacks/) for matched stacks.
|
|
20
|
+
|
|
21
|
+
## Reconcile against existing agents (do this FIRST)
|
|
22
|
+
|
|
23
|
+
Before drafting any new YAML, walk through every entry in `existing_ai_artifacts.agents` and apply the disposition the user picked in the bootstrap interview's [Existing AI artifacts](../vinta-bootstrap-ai-tools/SKILL.md#e-existing-ai-artifacts-per-artifact-disposition) group:
|
|
24
|
+
|
|
25
|
+
- **Migrate to `ai-tools/agents/<name>.yaml`** — convert vendor format → canonical YAML. Preserve `name` + `description` + body. Map vendor-specific fields:
|
|
26
|
+
- Claude `tools:` (CSV string) → YAML `claude-tools:` or `overrides.claude.tools` (let `setup-ai-tools.mjs` derive defaults from `access`).
|
|
27
|
+
- Cursor `readonly: true|false` → `access: read-only | read-write`.
|
|
28
|
+
- Codex `sandbox_mode` → `access` mapping (`read-only` → `read-only`, `workspace-write` → `read-write`); preserve other Codex-only fields under `overrides.codex`.
|
|
29
|
+
- Copilot `tools:` array → `overrides.copilot.tools`.
|
|
30
|
+
- Move the body content into the canonical YAML `body:` literal block.
|
|
31
|
+
- **Keep in current vendor path, don't touch** — don't emit a canonical YAML for it. AGENTS.md may reference it; `setup-ai-tools.mjs` won't manage it.
|
|
32
|
+
- **Drop** — log the removal; don't emit anything.
|
|
33
|
+
- **Replace with Vinta foundation version** (foundation-shape only — `implementer` / `reviewer` / `fixer`) — discard the existing body, emit the canonical foundation trio body below.
|
|
34
|
+
|
|
35
|
+
For the foundation trio: only emit a fresh canonical version when none exists OR the user said `Replace`. If the user said `Migrate` or `Keep` for an existing `implementer.yaml`, **do not overwrite**.
|
|
36
|
+
|
|
37
|
+
After this reconciliation, continue with the foundation trio + stack specialists for any name still missing.
|
|
38
|
+
|
|
39
|
+
## Foundation trio (always emit)
|
|
40
|
+
|
|
41
|
+
Every project gets these three. Bodies are project-tailored; structure is stable.
|
|
42
|
+
|
|
43
|
+
### `implementer.yaml`
|
|
44
|
+
|
|
45
|
+
Default coder for one phase of an `ai-plans/` plan. Reads AGENTS.md + plan body, executes Changes/Tests/Acceptance, runs inner loop + outer gate, reports back. Never branches, pushes, or opens PRs (orchestrator owns git remotes). Never adds AI co-author trailers (when policy forbids).
|
|
46
|
+
|
|
47
|
+
YAML shape — full contract at [`schemas/sub-agent.v1.schema.json`](../../schemas/sub-agent.v1.schema.json). Required fields: `schema_version`, `name`, `description`, `access`, `body`. Authoring tip: prepend `# yaml-language-server: $schema=./node_modules/vinta-ai-workflows/schemas/sub-agent.v1.schema.json` for IDE validation.
|
|
48
|
+
|
|
49
|
+
```yaml
|
|
50
|
+
# yaml-language-server: $schema=./node_modules/vinta-ai-workflows/schemas/sub-agent.v1.schema.json
|
|
51
|
+
schema_version: 1
|
|
52
|
+
name: implementer
|
|
53
|
+
description: |
|
|
54
|
+
One-line role. Followed by stack/conventions referenced (React + TS + Medplum, or Django + DRF, etc).
|
|
55
|
+
Conditions for use, outputs, what it never does.
|
|
56
|
+
access: read-write
|
|
57
|
+
body: |
|
|
58
|
+
# Implementer
|
|
59
|
+
|
|
60
|
+
Sections (adapt to project):
|
|
61
|
+
- Before writing (read AGENTS.md, plan body, neighbor code).
|
|
62
|
+
- Conventions (pulled from AGENTS.md — code style, separation of concerns, tenancy, framework rules).
|
|
63
|
+
- Loop (inner: lint → scoped tests → typecheck/build; outer: full build + full tests + e2e for UI).
|
|
64
|
+
- Report shape.
|
|
65
|
+
- Will not (branch, push, PR, co-author trailer, skip outer gate, ...).
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
The body **must reference real commands** for this project (`pnpm test:patient`, `make all-tests`, `pytest tests/integration/`, etc — pulled from `inventory.commands`). Don't generic-ify.
|
|
69
|
+
|
|
70
|
+
### `reviewer.yaml`
|
|
71
|
+
|
|
72
|
+
Adversarial reviewer. Reads phase body + diff + AGENTS.md + relevant SKILL.md. Outputs BLOCKER / SHOULD-FIX / NIT findings with file:line. Read-only — `access: read-only`.
|
|
73
|
+
|
|
74
|
+
YAML shape:
|
|
75
|
+
```yaml
|
|
76
|
+
name: reviewer
|
|
77
|
+
description: |
|
|
78
|
+
Adversarial code reviewer for one phase of an ai-plans/ implementation.
|
|
79
|
+
Read-only by design. Outputs severity-tagged findings; orchestrator dispatches a fixer.
|
|
80
|
+
access: read-only
|
|
81
|
+
body: |
|
|
82
|
+
# Reviewer
|
|
83
|
+
|
|
84
|
+
Sections:
|
|
85
|
+
- Read in order (phase body, the plan's **Goals + Non-goals** + **Guiding Decisions** sections, AGENTS.md, reusable SKILL.md, full diff, tracking).
|
|
86
|
+
- Look for (plan compliance, convention violations, bugs, test gaps, deploy risks, security, scope creep, commit hygiene).
|
|
87
|
+
- Report shape (BLOCKER/SHOULD-FIX/NIT with file:line + suggested fix).
|
|
88
|
+
- Severity guidance.
|
|
89
|
+
- Will not (edit, re-run tests "to be sure", suggest architectural changes, be polite).
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
"Look for" sweeps must be **project-specific**. Pull violations classes from AGENTS.md + stack templates. Examples:
|
|
93
|
+
- Medplum project: missing `meta.account`, bare Subscription criteria, hard-coded env-prefixed bot names, AccessPolicy compartment gaps, writable PractitionerRole, missing notification `tenant` field.
|
|
94
|
+
- Django project: missing `tenant_id` filter, loop+save instead of bulk_create, lock-heavy migration on hot table, missing `db_default` on non-null new column.
|
|
95
|
+
|
|
96
|
+
### `fixer.yaml`
|
|
97
|
+
|
|
98
|
+
Applies one finding from the reviewer (or one named test failure). Smallest correct change. Re-runs inner + outer gate. Reports.
|
|
99
|
+
|
|
100
|
+
YAML shape:
|
|
101
|
+
```yaml
|
|
102
|
+
name: fixer
|
|
103
|
+
description: |
|
|
104
|
+
Applies a narrowly-scoped fix to one reviewer finding or one named failure.
|
|
105
|
+
Like the implementer: never branches, pushes, or opens PRs. Never adds AI co-author trailers.
|
|
106
|
+
access: read-write
|
|
107
|
+
body: |
|
|
108
|
+
# Fixer
|
|
109
|
+
|
|
110
|
+
Sections:
|
|
111
|
+
- Task shapes (reviewer finding verbatim, or test/gate failure).
|
|
112
|
+
- Loop (read surrounding, narrowest change, inner loop, outer gate).
|
|
113
|
+
- Report (changes, did NOT touch, out-of-scope spotted, notes).
|
|
114
|
+
- Will not (silence tests, downgrade asserts, scope expansion, ...).
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Stack-specific specialists (user-supplied)
|
|
118
|
+
|
|
119
|
+
[bootstrap-ai-tools/resources/stacks/<stack>/notes.md](../vinta-bootstrap-ai-tools/resources/stacks/) describes **detection signals + agent categories typically needed** for each stack — NOT ready-made agent YAML. The team's specific agent library lives wherever they keep it.
|
|
120
|
+
|
|
121
|
+
For each stack the inventory matched, surface to the user:
|
|
122
|
+
|
|
123
|
+
> Detected stack `<X>`. Notes for this stack list these agent categories: A, B, C. Do you have existing agent templates for any of these? If yes, point me at the path / URL. If no, we'll record them as known gaps.
|
|
124
|
+
|
|
125
|
+
Use `AskUserQuestion`-style prompts:
|
|
126
|
+
- *"Do you have an agent template for `<category>` (e.g. `deploy-author` for Medplum, `migration-author` for Django)?"* → `Yes — at this path/URL`, `No — record as gap`, `Skip for now`.
|
|
127
|
+
|
|
128
|
+
When the user provides a path:
|
|
129
|
+
1. Read the source agent YAML (or `.md` if the user's library uses Claude-style markdown — convert to the YAML schema documented above before saving).
|
|
130
|
+
2. Replace placeholder paths / app names / command names with the target project's specifics, using the placeholder list from [resources/stacks/<stack>/notes.md](../vinta-bootstrap-ai-tools/resources/stacks/).
|
|
131
|
+
3. Drop sections that don't apply (e.g. if the Django project doesn't use `psqlextra`, strip partitioned-table guidance from a `migration-author` template).
|
|
132
|
+
4. Write to `ai-tools/agents/<name>.yaml`.
|
|
133
|
+
|
|
134
|
+
When the user has no template:
|
|
135
|
+
- Record the agent category in the run's TODO list. Output as part of the orchestrator's final summary.
|
|
136
|
+
- The user can run `vinta-derive-subagents` standalone later — pointing at the [resources/stacks/<stack>/notes.md](../vinta-bootstrap-ai-tools/resources/stacks/) for the agent's role description — and draft the YAML from scratch using the schema above.
|
|
137
|
+
|
|
138
|
+
If multiple stacks match, ask per-stack independently. The user may have templates for one stack but not another.
|
|
139
|
+
|
|
140
|
+
The orchestrator does **not** ship pre-baked Medplum / Django / etc agent content. Agent bodies are project- and team-specific; one shared template doesn't fit every team's conventions or chosen vendor (the same logical role looks different in Claude Code vs Cursor vs Codex frontmatter).
|
|
141
|
+
|
|
142
|
+
## Schema (recap from `ai-tools/agents/README.md`)
|
|
143
|
+
|
|
144
|
+
```yaml
|
|
145
|
+
name: <kebab-case> # required, matches filename stem
|
|
146
|
+
description: <text> # required; folded or literal block OK
|
|
147
|
+
access: read-only | read-write # required; drives vendor defaults
|
|
148
|
+
claude-tools: <comma list> # optional convenience; overrides claude default
|
|
149
|
+
overrides: # optional per-vendor
|
|
150
|
+
claude: { tools: ... }
|
|
151
|
+
cursor: { model, readonly, is_background }
|
|
152
|
+
copilot: { tools: [...], model, user-invocable, disable-model-invocation }
|
|
153
|
+
codex: { sandbox_mode, model, model_reasoning_effort }
|
|
154
|
+
body: | # required, markdown content as YAML literal block
|
|
155
|
+
...
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
The setup script ([vinta-install-ai-tools-setup](../vinta-install-ai-tools-setup/SKILL.md)) reads these and emits per-vendor copies. **Don't edit the per-vendor files** — edits get overwritten on the next setup run.
|
|
159
|
+
|
|
160
|
+
## Rules
|
|
161
|
+
|
|
162
|
+
- **Bodies cite real commands.** No `pnpm test:foo` if `package.json` has no `test:foo` script. No `make all-tests` if there's no Makefile. Pull from `inventory.commands`.
|
|
163
|
+
- **Bodies cite real conventions.** AGENTS.md is the source — repeat key load-bearing rules so the agent has them inline (don't expect agents to always re-fetch AGENTS.md mid-prompt).
|
|
164
|
+
- **`access` matches reality.** Reviewer is `read-only`. Implementer / fixer / deploy-author / migration-author are `read-write` (they need to edit code).
|
|
165
|
+
- **No PR creation by any agent.** Per Step 0 interview policy. The "Will not" section in every agent body must say so explicitly.
|
|
166
|
+
- **No AI co-author trailers in commits.** Per Step 0 interview policy. Repeat in every read-write agent body.
|
|
167
|
+
- **Stack templates are starting points.** Customize aggressively to the target project; don't ship copy-pasted Vinta AI Workflow-specific paths.
|
|
168
|
+
- **No `§N` shorthand in any agent body, prompt, or "look for" list.** Reference plan or spec sections by their full name (`Goals + Non-goals`, `Guiding Decisions`, `Data Model Changes`, `Phased Rollout`, etc.). `§N` references are unreadable for humans and shift when section numbering changes.
|
|
169
|
+
|
|
170
|
+
## Adding a new agent later
|
|
171
|
+
|
|
172
|
+
1. Create `ai-tools/agents/<new-name>.yaml`.
|
|
173
|
+
2. Run `pnpm setup:ai-tools` (or `node ai-tools/scripts/setup-ai-tools.mjs`) to materialize per-vendor copies.
|
|
174
|
+
3. Commit YAML + generated vendor files.
|
|
175
|
+
|
|
176
|
+
If the new agent applies to a stack that other projects share, contribute it back to [bootstrap-ai-tools/resources/stacks/<stack>/agents/](../vinta-bootstrap-ai-tools/resources/stacks/) so the next bootstrap picks it up.
|
|
177
|
+
|
|
178
|
+
## Pitfalls
|
|
179
|
+
|
|
180
|
+
- **Generic agent bodies that say nothing project-specific.** A body that reads "follow conventions, run tests, report back" is useless. Bodies must name files, commands, conventions, and the "violations to look for" specific to this project.
|
|
181
|
+
- **Splitting work between implementer and a stack specialist when there's no real division.** A pure TypeScript monorepo doesn't need a `deploy-author` — Vercel handles deploys automatically. Don't add specialists for ceremony.
|
|
182
|
+
- **Forgetting to delete unused stack-template sections.** Templates are written for the maximal case (e.g. `migration-author` covers `psqlextra` partitioning + HStore + view migrations). Strip what your project doesn't use.
|
|
183
|
+
- **Duplicating AGENTS.md content verbatim into every agent body.** Repeat the load-bearing rules; don't replay the whole document.
|
|
184
|
+
|
|
185
|
+
## Verification
|
|
186
|
+
|
|
187
|
+
After writing all YAMLs:
|
|
188
|
+
|
|
189
|
+
1. `node -e "require('yaml').parse(require('fs').readFileSync('ai-tools/agents/<name>.yaml', 'utf8'))"` for each — confirms valid YAML.
|
|
190
|
+
2. `node ai-tools/scripts/setup-ai-tools.mjs` — runs cleanly, generates vendor copies.
|
|
191
|
+
3. Open each generated vendor file (Claude / Cursor / Copilot / Codex), spot-check that body content + frontmatter look right.
|
|
192
|
+
4. Read each YAML body end-to-end: does it tell the agent what to do in this project? Specific commands? Specific conventions? Specific violations to flag?
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: vinta-install-ai-tools-setup
|
|
3
|
+
description: Install the multi-vendor `setup-ai-tools.mjs` script in the target project, wire up a `pnpm setup:ai-tools` (or equivalent) script alias, ensure the YAML parser dependency is present, then run the script to generate per-vendor AGENTS.md / skill / sub-agent files. Final step of [vinta-bootstrap-ai-tools](../vinta-bootstrap-ai-tools/SKILL.md). Idempotent — safe to re-run after editing canonical sources.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Install ai-tools setup
|
|
7
|
+
|
|
8
|
+
The setup script reads `ai-tools/AGENTS.md`, `ai-tools/skills/`, and `ai-tools/agents/*.yaml` (canonical sources) and emits per-vendor copies + symlinks. This skill installs the script + its package wiring + runs it for the first time.
|
|
9
|
+
|
|
10
|
+
## Output
|
|
11
|
+
|
|
12
|
+
- `ai-tools/scripts/setup-ai-tools.mjs` — copied from this skill's [resources/setup-ai-tools.mjs](resources/setup-ai-tools.mjs).
|
|
13
|
+
- `package.json` (or equivalent) gains a `setup:ai-tools` script alias.
|
|
14
|
+
- `yaml` (npm) added as a devDependency.
|
|
15
|
+
- Vendor symlinks + generated files materialized.
|
|
16
|
+
|
|
17
|
+
## Inputs
|
|
18
|
+
|
|
19
|
+
- `ai-tools/AGENTS.md` (from [vinta-write-agents-md](../vinta-write-agents-md/SKILL.md))
|
|
20
|
+
- `ai-tools/agents/*.yaml` (from [vinta-derive-subagents](../vinta-derive-subagents/SKILL.md))
|
|
21
|
+
- `ai-tools/skills/<name>/SKILL.md` (from [vinta-derive-skills](../vinta-derive-skills/SKILL.md))
|
|
22
|
+
- Step 0 vendor selection from the [vinta-bootstrap-ai-tools](../vinta-bootstrap-ai-tools/SKILL.md#a-scope) **Scope → Vendor coverage** answer.
|
|
23
|
+
|
|
24
|
+
## Steps
|
|
25
|
+
|
|
26
|
+
### 1. Prerequisite check
|
|
27
|
+
|
|
28
|
+
`ai-tools/AGENTS.md` exists. `ai-tools/agents/*.yaml` has at least the foundation trio (`implementer`, `reviewer`, `fixer`). `ai-tools/skills/` is non-empty.
|
|
29
|
+
|
|
30
|
+
If any are missing → stop. Route the user back to the relevant sub-skill ([vinta-write-agents-md](../vinta-write-agents-md/SKILL.md), [vinta-derive-subagents](../vinta-derive-subagents/SKILL.md), [vinta-derive-skills](../vinta-derive-skills/SKILL.md)).
|
|
31
|
+
|
|
32
|
+
### 2. Copy the setup script
|
|
33
|
+
|
|
34
|
+
Copy [resources/setup-ai-tools.mjs](resources/setup-ai-tools.mjs) (bundled with this skill) into the target repo at `ai-tools/scripts/setup-ai-tools.mjs`. Make it executable: `chmod +x ai-tools/scripts/setup-ai-tools.mjs`.
|
|
35
|
+
|
|
36
|
+
The script is self-contained — no project-specific edits required. It reads vendor agent paths + skill paths relative to the repo root.
|
|
37
|
+
|
|
38
|
+
### 3. Add the package script
|
|
39
|
+
|
|
40
|
+
For Node/TS projects: add `"setup:ai-tools": "node ai-tools/scripts/setup-ai-tools.mjs"` to root `package.json:scripts`.
|
|
41
|
+
|
|
42
|
+
For Python / Go / Rust / etc projects: there's no `package.json`, but Node is still required to run the script. Add a Makefile target / Justfile recipe / shell alias instead:
|
|
43
|
+
|
|
44
|
+
```makefile
|
|
45
|
+
setup-ai-tools:
|
|
46
|
+
@node ai-tools/scripts/setup-ai-tools.mjs
|
|
47
|
+
.PHONY: setup-ai-tools
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Or a `bin/setup-ai-tools` shell wrapper. Document the invocation in the project README + AGENTS.md.
|
|
51
|
+
|
|
52
|
+
### 4. Add the YAML parser dependency
|
|
53
|
+
|
|
54
|
+
The script imports `yaml` (npm). Add to devDependencies:
|
|
55
|
+
|
|
56
|
+
- pnpm: `pnpm add -D -w yaml` (root of workspace) or `pnpm add -D yaml` (single package).
|
|
57
|
+
- npm: `npm install --save-dev yaml`.
|
|
58
|
+
- yarn: `yarn add -D yaml`.
|
|
59
|
+
|
|
60
|
+
For projects without a Node toolchain (pure Python / Go / Rust / etc): the agent must still install `yaml` somewhere `node` can find it. Two options:
|
|
61
|
+
- (a) Add a minimal `package.json` at the repo root with just `{"devDependencies": {"yaml": "^2.8.0"}}` and run `npm install` in CI / dev setup.
|
|
62
|
+
- (b) Bundle `yaml` as a vendored copy under `ai-tools/scripts/node_modules/yaml/` (heavier, but no Node ecosystem footprint elsewhere).
|
|
63
|
+
|
|
64
|
+
Default to (a). Confirm with the user.
|
|
65
|
+
|
|
66
|
+
### 5. Configure vendor selection (optional)
|
|
67
|
+
|
|
68
|
+
If the user only wants a subset of vendors (per the Step 0 **Scope → Vendor coverage** answer), pass `--only` on the first run:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
node ai-tools/scripts/setup-ai-tools.mjs --only claude-code,cursor
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Or wire the alias to default to the subset:
|
|
75
|
+
|
|
76
|
+
```json
|
|
77
|
+
"setup:ai-tools": "node ai-tools/scripts/setup-ai-tools.mjs --only claude-code,cursor"
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
If the user wants all four vendors (default), no `--only` flag needed.
|
|
81
|
+
|
|
82
|
+
### 6. Run the script
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
pnpm setup:ai-tools
|
|
86
|
+
# or: node ai-tools/scripts/setup-ai-tools.mjs
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Expected output: list of symlinks ensured, list of generated per-vendor files, list of agents with their access class. No errors.
|
|
90
|
+
|
|
91
|
+
### 7. Verify each selected vendor
|
|
92
|
+
|
|
93
|
+
For each vendor in the user's selection:
|
|
94
|
+
|
|
95
|
+
- **Claude Code**: `ls .claude/agents/` lists every agent's `.md`. `ls .claude/skills/` (or `ls -L`) lists every skill dir. `cat AGENTS.md` resolves to the canonical content.
|
|
96
|
+
- **Cursor**: `ls .cursor/agents/` + `ls .cursor/skills/`. Open Cursor and check that the agent + skill panels surface them.
|
|
97
|
+
- **VS Code Copilot**: `ls .github/agents/` lists `*.agent.md`. `ls .github/skills/` lists skill dirs. `cat .github/copilot-instructions.md` resolves to the canonical AGENTS.md.
|
|
98
|
+
- **Codex**: `ls .codex/agents/` lists `*.toml`. Each TOML opens cleanly + has `name` / `description` / `sandbox_mode` / `developer_instructions` fields.
|
|
99
|
+
|
|
100
|
+
Any mismatches → re-run the script. If still wrong → inspect the script's output for warnings (it warns when a target path exists as a non-symlink real file).
|
|
101
|
+
|
|
102
|
+
### 8. Commit
|
|
103
|
+
|
|
104
|
+
Stage:
|
|
105
|
+
- `ai-tools/` (canonical sources + script)
|
|
106
|
+
- `package.json` (script alias + yaml dep)
|
|
107
|
+
- `pnpm-lock.yaml` / `package-lock.json` / `yarn.lock` (after install)
|
|
108
|
+
- `AGENTS.md` (root symlink)
|
|
109
|
+
- `.claude/`, `.cursor/`, `.github/agents/`, `.github/skills/`, `.github/copilot-instructions.md`, `.codex/agents/`, `.agents/skills/` — whichever vendors selected
|
|
110
|
+
|
|
111
|
+
Commit message style matches the project's convention captured during the bootstrap interview's **Project conventions** group. Default: `Bootstrap ai-tools layout (AGENTS.md, skills, sub-agents, vendor wiring)`.
|
|
112
|
+
|
|
113
|
+
## What gets re-run vs left alone
|
|
114
|
+
|
|
115
|
+
The setup script is **selective by vendor** but **destructive within a vendor**:
|
|
116
|
+
|
|
117
|
+
- For vendors in `--only` (or all four by default): the script `rm -rf` the target dir and regenerates. Hand-edits to per-vendor files are lost.
|
|
118
|
+
- For vendors NOT in `--only`: the script leaves their files untouched.
|
|
119
|
+
|
|
120
|
+
**Always edit the canonical sources** (`ai-tools/agents/*.yaml`, `ai-tools/skills/`, `ai-tools/AGENTS.md`). Generated vendor files are derived; they get overwritten on the next run.
|
|
121
|
+
|
|
122
|
+
## Pitfalls
|
|
123
|
+
|
|
124
|
+
- **Skipping the prerequisite check.** Running the script on an empty `ai-tools/` produces empty output — no error, but no useful files either. Always confirm canonical sources exist first.
|
|
125
|
+
- **Hand-editing a generated vendor file.** The auto-generated header at the top of every output points at the YAML / canonical source. Edit there, re-run the script.
|
|
126
|
+
- **Adding `yaml` to dependencies (not devDependencies).** Setup is dev-time only. Putting `yaml` in production deps inflates bundles.
|
|
127
|
+
- **Forgetting to commit the symlinks.** Most VCS handle symlinks fine, but verify your repo's setup. `git config core.symlinks true` (default on macOS / Linux). Windows: enable Developer Mode or use `core.symlinks = true` and admin shell.
|
|
128
|
+
- **Using `--only` without communicating to the team.** A teammate runs `pnpm setup:ai-tools` on their machine and wipes the vendors you didn't include. Document the selection in AGENTS.md or the script alias.
|
|
129
|
+
|
|
130
|
+
## Verification
|
|
131
|
+
|
|
132
|
+
Final smoke test:
|
|
133
|
+
|
|
134
|
+
1. `pnpm setup:ai-tools` runs cleanly, no errors.
|
|
135
|
+
2. Spot-check one agent file in each selected vendor — content matches the canonical YAML.
|
|
136
|
+
3. Spot-check one skill — the skill description shows up in the vendor's UI (Claude `/help`, Cursor agent panel, Copilot chat slash menu, Codex slash menu).
|
|
137
|
+
4. Edit `ai-tools/AGENTS.md` (add a comment line). Confirm the change appears in `cat AGENTS.md` (root symlink) + each selected vendor's instruction-file path.
|
|
138
|
+
5. Edit `ai-tools/agents/implementer.yaml` (e.g. tweak description). Re-run setup. Confirm changes propagate to all selected vendor agent files.
|