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.
Files changed (40) hide show
  1. package/CHANGELOG.md +830 -0
  2. package/LICENSE +21 -0
  3. package/README.md +547 -0
  4. package/package.json +27 -0
  5. package/schemas/README.md +84 -0
  6. package/schemas/mcp-preflight-cache.v1.schema.json +50 -0
  7. package/schemas/prs-context-comments.v1.schema.json +51 -0
  8. package/schemas/prs-context-frontmatter.v1.schema.json +77 -0
  9. package/schemas/sub-agent.v1.schema.json +105 -0
  10. package/schemas/vinta-ai-workflows-config.v1.schema.json +283 -0
  11. package/skills/vinta-analyze-codebase/SKILL.md +325 -0
  12. package/skills/vinta-bootstrap-ai-tools/SKILL.md +375 -0
  13. package/skills/vinta-bootstrap-ai-tools/resources/stacks/README.md +50 -0
  14. package/skills/vinta-bootstrap-ai-tools/resources/stacks/django/notes.md +52 -0
  15. package/skills/vinta-bootstrap-ai-tools/resources/stacks/medplum/notes.md +45 -0
  16. package/skills/vinta-bootstrap-ai-tools/resources/stacks/nextjs-app-router/notes.md +35 -0
  17. package/skills/vinta-bootstrap-ai-tools/resources/stacks/python-package/notes.md +31 -0
  18. package/skills/vinta-bootstrap-ai-tools/resources/stacks/typescript-monorepo/notes.md +32 -0
  19. package/skills/vinta-derive-skills/SKILL.md +200 -0
  20. package/skills/vinta-derive-skills/resources/amend-plan-template.md +355 -0
  21. package/skills/vinta-derive-skills/resources/foundation-skills/add-one-off-script/SKILL.md +292 -0
  22. package/skills/vinta-derive-skills/resources/foundation-skills/add-one-off-script/resources/one_off_script_base.py +602 -0
  23. package/skills/vinta-derive-skills/resources/foundation-skills/add-one-off-script/resources/one_off_script_base.ts +624 -0
  24. package/skills/vinta-derive-skills/resources/foundation-skills/create-qa-use-cases/SKILL.md +232 -0
  25. package/skills/vinta-derive-skills/resources/foundation-skills/create-spec/SKILL.md +235 -0
  26. package/skills/vinta-derive-skills/resources/foundation-skills/open-pr-from-context/SKILL.md +78 -0
  27. package/skills/vinta-derive-skills/resources/foundation-skills/open-pr-from-context/scripts/open-pr.sh +357 -0
  28. package/skills/vinta-derive-skills/resources/foundation-skills/plan-feature/SKILL.md +418 -0
  29. package/skills/vinta-derive-skills/resources/implement-plan-template.md +375 -0
  30. package/skills/vinta-derive-skills/resources/prs-context-template.md +91 -0
  31. package/skills/vinta-derive-skills/resources/systematic-debugging-mcp-tools.md +125 -0
  32. package/skills/vinta-derive-skills/resources/systematic-debugging-template.md +167 -0
  33. package/skills/vinta-derive-subagents/SKILL.md +192 -0
  34. package/skills/vinta-install-ai-tools-setup/SKILL.md +138 -0
  35. package/skills/vinta-install-ai-tools-setup/resources/setup-ai-tools.mjs +392 -0
  36. package/skills/vinta-migrate-plans-specs/SKILL.md +229 -0
  37. package/skills/vinta-sync-ai-tools/SKILL.md +184 -0
  38. package/skills/vinta-update-project-skills/SKILL.md +178 -0
  39. package/skills/vinta-write-agents-md/SKILL.md +192 -0
  40. package/vinta-ai-workflows.mjs +316 -0
@@ -0,0 +1,375 @@
1
+ ---
2
+ name: vinta-bootstrap-ai-tools
3
+ description: Bootstrap a project's AI-tooling layout (`ai-tools/AGENTS.md`, `ai-tools/skills/`, `ai-tools/agents/*.yaml`) plus the multi-vendor setup script that wires the canonical sources into Claude Code, Cursor, Codex, and VS Code Copilot. Project-agnostic — adapts to whatever stack it finds. Detects langs, frameworks, build tools, deploy paths, multi-tenancy patterns, and CI conventions, interviews the user for the gaps, then drafts AGENTS.md, the foundation sub-agents (implementer / reviewer / fixer), and a starter set of project-specific skills. Stack-specific skill + agent templates (Medplum, Django, …) live as resources and get copied when the detected stack matches. Use when invoked in a fresh repo that doesn't yet have an `ai-tools/` directory, or to refresh an existing one. Orchestrates several sub-skills — see "Sub-skill flow" below.
4
+ ---
5
+
6
+ # Bootstrap AI tools
7
+
8
+ This skill produces, in the target repo:
9
+
10
+ - `ai-tools/AGENTS.md` — universal project conventions read by Claude Code, Cursor, Codex, Copilot.
11
+ - `ai-tools/skills/<name>/SKILL.md` — domain-specific skills (always: foundation set + stack-matched copies).
12
+ - `ai-tools/agents/<name>.yaml` — vendor-agnostic sub-agent definitions; the setup script materializes per-vendor copies.
13
+ - `ai-tools/scripts/setup-ai-tools.mjs` + a `pnpm setup:ai-tools` (or equivalent) script alias.
14
+ - All vendor symlinks + generated agent files (Claude markdown, Cursor markdown, Copilot `.agent.md`, Codex TOML).
15
+
16
+ Project-agnostic. Adapts to whatever the analysis finds. Stack-specific skill + agent templates (Medplum, Django, ...) live under [`resources/stacks/`](resources/stacks/) and get copied when the detected stack signals match.
17
+
18
+ ## Sub-skill flow
19
+
20
+ This orchestrator runs six sub-skills in order. Each is its own SKILL.md so it can be invoked standalone (e.g. to refresh just AGENTS.md without redoing analysis from scratch).
21
+
22
+ 1. [vinta-analyze-codebase](../vinta-analyze-codebase/SKILL.md) — walk the repo, build a structured inventory: languages, frameworks, build tools, test frameworks, deploy targets, monorepo shape, env model, multi-tenancy patterns, CI providers. Outputs an in-memory inventory the rest of the flow consumes.
23
+ 2. [vinta-write-agents-md](../vinta-write-agents-md/SKILL.md) — synthesize `ai-tools/AGENTS.md` from the inventory + a focused interview for what the analysis can't see.
24
+ 3. [vinta-derive-subagents](../vinta-derive-subagents/SKILL.md) — author `ai-tools/agents/*.yaml`. Always emits the foundation trio (`implementer`, `reviewer`, `fixer`); adds stack-specific specialists when the user supplies a template for a matched stack.
25
+ 4. [vinta-derive-skills](../vinta-derive-skills/SKILL.md) — author `ai-tools/skills/*/SKILL.md`. Always copies the project-agnostic foundation set (`plan-feature`, `create-spec`, `create-qa-use-cases`) verbatim from its bundled resources. Generates `implement-plan` from a parameterized template using project specifics. Asks the user whether the optional `add-e2e-test` and `add-env-var` skills are needed. Asks for stack-specific templates per matched stack.
26
+ 5. [vinta-install-ai-tools-setup](../vinta-install-ai-tools-setup/SKILL.md) — copy the canonical `setup-ai-tools.mjs` into `ai-tools/scripts/`, wire the package script alias, run setup, verify all vendor paths resolve.
27
+ 6. [vinta-migrate-plans-specs](../vinta-migrate-plans-specs/SKILL.md) — find any pre-existing implementation plans / feature specs scattered across the repo (`docs/`, `specs/`, `plans/`, root markdown, etc.) and propose moving them to the canonical layout `ai-plans/YYYY-MM-DD-{FEATURE_NAME}_{PLAN|SPEC}.md`. Read-only by default; every rename is gated on per-file user approval. Skipped automatically when the analysis finds no candidates.
28
+
29
+ Each sub-skill returns a short status report. Don't run the next sub-skill until the previous finished cleanly. If a sub-skill fails or surfaces ambiguity, surface that to the user and resolve before continuing.
30
+
31
+ ### Sibling skill — `create-qa-use-cases`
32
+
33
+ [create-qa-use-cases](../create-qa-use-cases/SKILL.md) lives alongside the five sub-skills above but is **not** dispatched by the orchestrator at bootstrap time. It serves two distinct purposes:
34
+
35
+ - **Foundation skill that ships to the target**. [vinta-derive-skills](../vinta-derive-skills/SKILL.md) copies the same SKILL.md (bundled at `derive-skills/resources/foundation-skills/create-qa-use-cases/SKILL.md`) into the target's `ai-tools/skills/create-qa-use-cases/`.
36
+ - **Sub-skill of `plan-feature` at runtime in the target**. When `plan-feature` runs in the target project and detects no `QA_USE_CASES.md`, it invokes `create-qa-use-cases` to bootstrap the doc from the active feature's spec + plan.
37
+
38
+ The bootstrap orchestrator doesn't need to invoke it directly. It just needs to make sure derive-skills ships it as part of the foundation set.
39
+
40
+ ## When to use
41
+
42
+ - Repo has no `ai-tools/` directory and the user wants to introduce Vinta's setup.
43
+ - Repo has a partial setup and the user wants to refresh / extend it. (This orchestrator is idempotent in spirit — sub-skills read what's there before writing.)
44
+ - Forking the Vinta conventions into a new project.
45
+
46
+ If the repo already has `ai-tools/AGENTS.md`, **do not overwrite** without explicit confirmation. The orchestrator's first interview question covers this.
47
+
48
+ ## Interview (Step 0 — before any sub-skill runs)
49
+
50
+ Use `AskUserQuestion` for finite-choice questions; iterate plain prose for open-ended ones. Same convention as [plan-feature](../plan-feature/SKILL.md) and [create-spec](../create-spec/SKILL.md).
51
+
52
+ ### A. Scope
53
+
54
+ 1. **Existing setup?** `ai-tools/` already present → confirm: refresh in place, or stop and route to specific sub-skill (e.g. just re-run install-ai-tools-setup). `AskUserQuestion` options: `Fresh bootstrap`, `Refresh in place`, `Stop, run a specific sub-skill instead`.
55
+ 2. **Which sub-skills to run?** Default = all six in order. `AskUserQuestion` options: `All six`, `Skip analyze-codebase (use prior inventory)`, `Skip derive-skills (foundation only)`, `Skip migrate-plans-specs (no prior planning docs)`, `Custom selection (ask me)`.
56
+ 3. **Vendor coverage.** Which AI tools does the team use? `AskUserQuestion` multi-select: `Claude Code`, `Cursor`, `VS Code Copilot`, `Codex`. Maps to the setup script's `--only` flag at the install step.
57
+
58
+ ### B. Stack detection
59
+
60
+ Don't ask yet — let `vinta-analyze-codebase` do its scan first, then echo back what it found and ask "anything I missed?". The interview for stack details lives inside each sub-skill where the question is most relevant.
61
+
62
+ ### C. Project conventions worth surfacing early
63
+
64
+ These bleed across sub-skills, so capture once now:
65
+
66
+ 1. **Source of truth for code style** — Biome, Prettier, ruff, black, gofmt, etc. (`AskUserQuestion` with the common options + `Other (I'll list)`).
67
+ 2. **Test framework(s)** — Vitest, Jest, pytest, Go test, etc. Multi-select.
68
+ 3. **Code host** — GitHub, GitLab, Bitbucket, other. Drives the `implement-plan` template's PR-creation block.
69
+ 4. **PR creation policy** — agents open PRs, or only push branches and humans open PRs?
70
+ 5. **Co-author trailer policy** — repo allows AI co-author trailers in commits, or strictly human-only?
71
+ 6. **Deploy targets** — Vercel, AWS, Kubernetes, Heroku, custom, none.
72
+
73
+ ### D. Optional foundation skills
74
+
75
+ Four skills are part of the foundation set but aren't always needed. Ask explicitly:
76
+
77
+ 1. **`add-e2e-test`** — does the project have e2e tests (Playwright / Cypress / similar) or plan to add them? `AskUserQuestion` options: `Yes — already has them`, `Yes — planning to add`, `No — skip`. If yes, [vinta-derive-skills](../vinta-derive-skills/SKILL.md)'s **Optional — ask the user** bucket follows up to ask whether the user has a template or wants to draft from scratch.
78
+ 2. **`add-env-var`** — does the project have a non-trivial env-var propagation flow (multiple files / build configs / CI updates per new var) or a single `.env` file is enough? `AskUserQuestion` options: `Yes — non-trivial flow`, `No — single .env is enough`. Skip if `No`.
79
+ 3. **`systematic-debugging`** — should agents follow a root-cause-first debugging flow that mandates pulling evidence from the project's observability MCP servers before proposing any fix? `AskUserQuestion` options: `Yes — enable`, `No — skip`. Recommend enabling whenever any observability MCP server is wired up — the skill bakes the project's real test / lint / build commands into the rendered checklist and instructs the agent to discover available calls on those servers at runtime (so it stays correct even as MCP servers add or rename tools).
80
+ 4. **`add-one-off-script`** — does the project ever need one-off operational scripts (backfills, cleanups, ad-hoc data fixes) that mutate production data outside the regular migration / ETL / cron path? `AskUserQuestion` options: `Yes — enable`, `No — skip`. Recommend `Yes` for any project with a relational DB or large user dataset; the bundled `BaseOneOffScript` template enforces the safety contract (dry-run by default, idempotent re-runs, batched DB ops, streamed reads, segmented CSV backups capped at 1M cells per file with one set of files per affected table, interruption-safe signal handlers, console + filesystem + S3 logs that survive an interruption). Skip for read-only projects or projects whose only writes go through a migration tool.
81
+
82
+ **Follow-up only when `add-one-off-script` = Yes.** Three short questions land in `skills.add-one-off-script` of `.vinta-ai-workflows.yaml`:
83
+ - **Scripts dir.** Default `scripts/one_off`. Override for monorepos that nest scripts under a service / package dir. Free-form string.
84
+ - **Primary language.** `AskUserQuestion`: `Python`, `TypeScript`. Auto-pick from `inventory.frameworks` when one language clearly dominates; ask only when polyglot. Drives which `BaseOneOffScript` template gets staged at `<scripts_dir>/_base.{py,ts}`.
85
+ - **S3 bucket + prefix.** Open prose. Empty bucket disables S3 upload (filesystem copy stays authoritative). The skill also reads the `ONE_OFF_S3_BUCKET` / `ONE_OFF_S3_PREFIX` env vars at runtime, so leaving the config blank is fine if the team prefers env-only.
86
+
87
+ **Follow-up only when `systematic-debugging` = Yes — observability MCP server inventory.** Open prose, not multi-select. Ask the user to name every MCP server already wired up that exposes observability data, in whatever shorthand the team uses (`sentry`, `datadog`, `our-internal-traces`, `grafana-prod`, etc.). The intent is not to pick from a fixed catalogue — that goes stale fast — but to give the systematic-debugging agent a starter list of servers to introspect at Phase 0. Cross-check the answers against any MCP servers actually configured in the project's AI tooling (`.mcp.json`, `~/.claude/mcp_servers.json`, `.codex/mcp.json`, etc.) — if a server is configured but the user didn't mention it, ask whether it carries observability data. The selection lands in `skills.systematic-debugging.observability_mcp_servers` of `.vinta-ai-workflows.yaml` (free-form string array). Empty array is allowed but warn the user that Phase 0 collapses to "local logs only" and production-only bugs without telemetry become a guess factory. The agent will discover specific tool names + categories (error tracking, traces, logs, metrics, alerts, deploys, dashboards) from the live MCP tool list at runtime — see [vinta-derive-skills/resources/systematic-debugging-mcp-tools.md](../vinta-derive-skills/resources/systematic-debugging-mcp-tools.md) for the evidence categories baked into the rendered SKILL.md.
88
+
89
+ **Cache scaffolding.** Preflight state lives at `.vinta-ai-workflows/cache.yaml` ([`mcp-preflight-cache.v1`](../../schemas/mcp-preflight-cache.v1.schema.json)). The bootstrap orchestrator must:
90
+
91
+ - Add `.vinta-ai-workflows/` to `.gitignore` if not already present (the cache is per-developer-machine state — never committed). [vinta-install-ai-tools-setup](../vinta-install-ai-tools-setup/SKILL.md) handles the gitignore patch alongside the existing `.vinta-ai-workflows/prs-context/` entry.
92
+ - Do **not** seed the cache file at bootstrap. The first debug run preflights all configured servers and writes the file then. An empty / missing `.vinta-ai-workflows/cache.yaml` is a valid initial state.
93
+ - Mention to the user how to refresh: delete the file to re-preflight everything, or edit one entry's `status` to `dirty` to refresh that one server. Token rotated → cache will catch the auth error on the next call and flip the entry to `dirty` automatically.
94
+
95
+ If the user answers "No" to any of the four, that skill won't ship. If the user answers "Yes" to `add-e2e-test` / `add-env-var` but doesn't have a template, derive-skills drafts one via interview. `systematic-debugging` is always template-rendered — no per-project drafting interview, just the MCP-server inventory above. `add-one-off-script` is copied verbatim from [vinta-derive-skills/resources/foundation-skills/add-one-off-script/](../vinta-derive-skills/resources/foundation-skills/add-one-off-script/) — its body is project-agnostic; the per-project variability lives in the `skills.add-one-off-script.*` config block above and in env vars consumed at runtime.
96
+
97
+ ### E. Existing AI artifacts (per-artifact disposition)
98
+
99
+ [vinta-analyze-codebase](../vinta-analyze-codebase/SKILL.md#11-existing-ai-tooling-artifacts)'s **Existing AI-tooling artifacts** scan produces an inventory of **every** AI-tooling artifact already in the repo: instruction docs (AGENTS.md / CLAUDE.md / .cursorrules / .github/copilot-instructions.md / ...), skills under `.claude/skills/`, `.cursor/skills/`, `.codex/skills/`, `.github/skills/`, `.agents/skills/`, `ai-tools/skills/`, and sub-agent files under `.claude/agents/`, `.cursor/agents/`, `.codex/agents/`, `.github/agents/`, `ai-tools/agents/`.
100
+
101
+ **Don't skip this step even when the inventory is short.** Three skill files in `.cursor/skills/` from a teammate's experiment are exactly the artifacts that get clobbered if the orchestrator forgets they exist.
102
+
103
+ For each artifact, read it (frontmatter + body), then ask the user via `AskUserQuestion`:
104
+
105
+ - **Instruction docs** (`AGENTS.md`, `CLAUDE.md`, etc.):
106
+ - `Merge into new ai-tools/AGENTS.md` — `vinta-write-agents-md` folds existing content into the canonical sections, preserving anything still accurate.
107
+ - `Keep as-is, link from ai-tools/AGENTS.md` — leave the file in place, reference it.
108
+ - `Replace from scratch` — discard existing, draft fresh from inventory + interview.
109
+
110
+ - **Skills** (each under any vendor `skills/` dir):
111
+ - `Migrate to ai-tools/skills/<name>/` — move into the canonical layout; `setup-ai-tools.mjs` will re-link to the chosen vendors. Vendor-prefixed dir (`vinta-*`) is left alone — installed by the `vinta-ai-workflows` CLI.
112
+ - `Keep in current vendor path, don't touch` — leaves it where it is. AGENTS.md may reference it; downstream skill setup won't manage it.
113
+ - `Drop` — delete (rare; usually the user wants to migrate).
114
+
115
+ Foundation-shape skills (name matches `plan-feature`, `create-spec`, `create-qa-use-cases`, `implement-plan`, `add-e2e-test`, `add-env-var`, `add-one-off-script`) get an extra option: `Replace with Vinta foundation version` — overwrites with the canonical foundation content, preserving the user's name. Useful when the existing version is stale.
116
+
117
+ - **Sub-agents** (each under any vendor `agents/` dir):
118
+ - `Migrate to ai-tools/agents/<name>.yaml` — converts vendor-specific format → canonical YAML; `setup-ai-tools.mjs` re-emits per-vendor copies.
119
+ - `Keep in current vendor path, don't touch` — leaves it where it is.
120
+ - `Drop`.
121
+
122
+ Foundation-shape (`implementer`, `reviewer`, `fixer`) gets the `Replace with Vinta foundation version` option as well.
123
+
124
+ Surface decisions per artifact, **not** as a single batch. The user might want to migrate one custom skill but keep two others where they are.
125
+
126
+ ### F. Design system doc (`DESIGN.md`)
127
+
128
+ Scan the repo root for `DESIGN.md` (case-insensitive). Per [Design.md with Cursor](https://designmd.app/blog/design-md-with-cursor/), this file holds the project's design system (colors, typography, spacing, components) in a Markdown format AI agents can consume before generating UI. **Never overwrite or rewrite an existing `DESIGN.md`** — the team owns its contents.
129
+
130
+ If present, ask via `AskUserQuestion`:
131
+
132
+ - `Keep and wire into AI tooling` (recommended) — leave file untouched at repo root; reference it from `ai-tools/AGENTS.md`; when `cursor` is in **Scope → Vendor coverage**, write `.cursor/rules/design.mdc` (Cursor Project Rules, Option A from the linked blog post) so Cursor auto-loads it before generating UI files.
133
+ - `Keep as-is, don't reference` — leave the file alone; no AGENTS.md mention, no Cursor rule.
134
+ - `Drop` — delete (rare; confirm twice before removing).
135
+
136
+ If absent, no prompt — don't fabricate a `DESIGN.md`. Record the gap so [vinta-write-agents-md](../vinta-write-agents-md/SKILL.md) can mention it as a TODO if the user wants design-system guidance.
137
+
138
+ The disposition lands in `project.design_md` of `.vinta-ai-workflows.yaml` (free-form string: `wired | kept-unreferenced | absent`). [vinta-write-agents-md](../vinta-write-agents-md/SKILL.md) reads it when `wired` and inserts a "Design system" section pointing at `DESIGN.md`. [vinta-install-ai-tools-setup](../vinta-install-ai-tools-setup/SKILL.md) reads it when `wired` + `cursor` ∈ `vendors` and writes `.cursor/rules/design.mdc` with this exact body:
139
+
140
+ ```markdown
141
+ ---
142
+ description: Design system rules — read DESIGN.md before generating UI
143
+ globs: ["**/*.tsx", "**/*.jsx", "**/*.vue", "**/*.svelte", "**/*.astro", "**/*.css"]
144
+ ---
145
+
146
+ Before generating any visual component, read the DESIGN.md file at the project root.
147
+
148
+ Rules:
149
+ - Use ONLY the colors defined in DESIGN.md
150
+ - Follow the typographic scale exactly
151
+ - Apply spacing values from the Spacing section
152
+ - Follow component patterns from the Components section
153
+ - Never violate the Do's and Don'ts section
154
+ - When in doubt, reference DESIGN.md — do not invent new values
155
+ ```
156
+
157
+ Globs may need tuning for the project's actual UI file extensions (Svelte-only projects, RN `.tsx`, etc.). Ask the user once if the analysis surfaced a UI framework not covered by the default glob list; otherwise ship the defaults.
158
+
159
+ After Step 0: read back the captured decisions (including every per-artifact disposition), confirm via `AskUserQuestion` (`Looks good`, `Some corrections (I'll list)`, `Stop, rethink`).
160
+
161
+ The dispositions become inputs to:
162
+
163
+ - `vinta-write-agents-md` — knows whether to merge / link / replace.
164
+ - `vinta-derive-subagents` — knows which agents to migrate vs leave; doesn't redrop a foundation file the user said `Replace`.
165
+ - `vinta-derive-skills` — same logic for skills. Doesn't ship a foundation version the user said `Keep` for.
166
+
167
+ ## Step 0.5 — Write `.vinta-ai-workflows.yaml` (single source of truth)
168
+
169
+ Captured interview state lands in **one** YAML file at the repo root: `.vinta-ai-workflows.yaml`. Schema: [`schemas/vinta-ai-workflows-config.v1.schema.json`](../../schemas/vinta-ai-workflows-config.v1.schema.json) (`schema_version: 1`).
170
+
171
+ This file is the **only** source of truth for project-wide settings. Every downstream sub-skill (4 → 6 below) reads from it instead of receiving values via in-conversation state. Every meta-skill ([vinta-sync-ai-tools](../vinta-sync-ai-tools/SKILL.md), [vinta-update-project-skills](../vinta-update-project-skills/SKILL.md)) reads + rewrites it.
172
+
173
+ Write the file now (before any sub-skill runs). Populate from the interview groups **Scope**, **Stack detection**, **Project conventions**, **Optional foundation skills**, and **Existing AI artifacts**:
174
+
175
+ ```yaml
176
+ # yaml-language-server: $schema=./node_modules/vinta-ai-workflows/schemas/vinta-ai-workflows-config.v1.schema.json
177
+
178
+ schema_version: 1
179
+ vinta_ai_workflows_version: <pkg version detected at install time>
180
+ last_synced_at: <ISO 8601 now>
181
+
182
+ project:
183
+ name: <from inventory>
184
+ default_branch: <from inventory>
185
+ code_host: <github | gitlab | bitbucket | self-hosted>
186
+ stack_summary: <inventory.frameworks one-liner>
187
+ ai_plans_dir: <ai-plans | apps/<service>/ai-plans | ...>
188
+ pr_template_paths: <inventory.existing_ai_artifacts.pr_templates[].path> # empty array if none found
189
+ design_md: <Step 0.F → wired | kept-unreferenced | absent>
190
+
191
+ commands:
192
+ lint: <Project conventions → Source of truth for code style>
193
+ format: <derived>
194
+ build: <derived>
195
+ test_unit: <Project conventions → Test framework(s)>
196
+ test_unit_scoped: <derived from monorepo shape>
197
+ test_unit_new_pattern: <derived>
198
+ e2e: <only when foundation_skills.add-e2e-test = enabled>
199
+
200
+ policies:
201
+ pr_creation: <Project conventions → PR creation policy>
202
+ ai_coauthor: <Project conventions → Co-author trailer policy>
203
+ commit_style: <conventional | imperative | other>
204
+ stage_pattern: <derived>
205
+ anti_git_add_all_reason: <derived>
206
+
207
+ vendors: <Scope → Vendor coverage list>
208
+
209
+ foundation_skills:
210
+ plan-feature: enabled
211
+ create-spec: enabled
212
+ create-qa-use-cases: enabled
213
+ implement-plan: enabled
214
+ amend-plan: enabled
215
+ open-pr-from-context: enabled
216
+ add-e2e-test: <Optional foundation skills → add-e2e-test answer → enabled | disabled>
217
+ add-env-var: <Optional foundation skills → add-env-var answer → enabled | disabled>
218
+ systematic-debugging: <Optional foundation skills → systematic-debugging answer → enabled | disabled>
219
+ add-one-off-script: <Optional foundation skills → add-one-off-script answer → enabled | disabled>
220
+
221
+ foundation_agents:
222
+ implementer: enabled
223
+ reviewer: enabled
224
+ fixer: enabled
225
+
226
+ stacks: <Stack detection → matched stacks>
227
+ stack_specialist_agents: <empty unless user supplied templates>
228
+
229
+ run_options:
230
+ implement-plan:
231
+ pause_between_phases: false
232
+ generate_inline_comments: false
233
+ amend-plan:
234
+ blast_radius_signal_threshold: 2
235
+
236
+ skills:
237
+ # Only emit this block when foundation_skills.systematic-debugging = enabled.
238
+ systematic-debugging:
239
+ observability_mcp_servers: <systematic-debugging follow-up — free-form array of MCP server identifiers, e.g. [sentry, datadog, our-internal-traces]>
240
+
241
+ # Only emit this block when foundation_skills.add-one-off-script = enabled.
242
+ add-one-off-script:
243
+ scripts_dir: <add-one-off-script follow-up — default `scripts/one_off`>
244
+ language: <add-one-off-script follow-up — `python` | `typescript`>
245
+ log_dir: .vinta-ai-workflows/one-off-runs
246
+ default_batch_size: 500
247
+ csv_max_cells: 1000000
248
+ s3_bucket: <add-one-off-script follow-up — empty disables S3 upload>
249
+ s3_prefix: one-off-runs/
250
+ ```
251
+
252
+ Validate the file against the schema before writing — if any required field is unresolved, route back to the relevant interview question. Don't write a partial config.
253
+
254
+ Existing-project case: `.vinta-ai-workflows.yaml` already present → that's a re-bootstrap. Show the existing config, ask via `AskUserQuestion`: `Keep existing config and refresh sub-skills only`, `Re-interview and overwrite`, `Stop`. The `Refresh sub-skills only` path is the common case for older projects whose config was written by an earlier `vinta-bootstrap-ai-tools`.
255
+
256
+ ## Stack templates — detection only, content is user-supplied
257
+
258
+ [`resources/stacks/<stack>/notes.md`](resources/stacks/) defines **detection signals** + lists the **categories of skills + sub-agents that typically belong** to each stack. **It does NOT ship ready-made skill / agent content.** The team's specific skill library lives wherever the team keeps it (a shared repo, a personal `~/skills/` dir, a published package, a private gist) — the bootstrap orchestrator asks the user to point at it when a stack matches.
259
+
260
+ | Stack | Detected by | What the notes.md describes |
261
+ |---|---|---|
262
+ | Medplum | `@medplum/*` deps + `bots/` dir + tenant compartmenting signals | bot skills, AccessPolicy skill, deploy-author agent |
263
+ | Django + Postgres | `manage.py` + Django dep + `migrations/` dirs (multi-tenant signals optional) | model + migration skills, migration-author agent |
264
+ | TypeScript monorepo | `turbo.json` / `pnpm-workspace.yaml` + `apps/`+`lib/` layout | env-var + shared-package skills (foundation only) |
265
+ | Python package | `pyproject.toml` without Django; `src/<pkg>/` layout | module + CLI + release skills as applicable |
266
+ | Next.js App Router | `next.config.*` + `app/` dir | route, server-action, caching, middleware, route-handler skills |
267
+
268
+ For each matched stack, the orchestrator (via [vinta-derive-skills](../vinta-derive-skills/SKILL.md) and [vinta-derive-subagents](../vinta-derive-subagents/SKILL.md)):
269
+
270
+ 1. Reads `<stack>/notes.md`.
271
+ 2. Surfaces the match: *"Detected stack X. Notes say teams typically maintain skills for: A, B, C. Do you have existing templates for any?"*
272
+ 3. If the user has templates → ask for paths (filesystem path, Git URL, package name on disk, etc) and copy + adapt them into the target's `ai-tools/`.
273
+ 4. If not → record as a known gap. The user can run `vinta-derive-skills` standalone later to draft them from scratch using the canonical structure.
274
+
275
+ If multiple stacks match (common — TypeScript monorepo + Medplum, or Django + Python-package), the orchestrator handles each; the user can supply templates for any subset.
276
+
277
+ ### Adding a new stack
278
+
279
+ 1. `mkdir resources/stacks/<stack-name>`.
280
+ 2. Write `notes.md` with detection signals + skill / agent categories + placeholders to ask about.
281
+ 3. Update the **Frameworks (from dependencies)** scan in [vinta-analyze-codebase](../vinta-analyze-codebase/SKILL.md#3-frameworks-from-dependencies) if a new dep / signal needs to be detected.
282
+ 4. Update the table above.
283
+
284
+ No skill / agent content lives in `resources/stacks/<stack>/`. That's by design — those are project- and team-specific.
285
+
286
+ ## Outputs
287
+
288
+ After Step 0.5 + all six sub-skills run, the target repo has:
289
+
290
+ ```
291
+ .vinta-ai-workflows.yaml ← single source of truth (Step 0.5)
292
+ schema: schemas/vinta-ai-workflows-config.v1.schema.json
293
+ .vinta-ai-workflows/ ← gitignored local state (only when systematic-debugging enabled)
294
+ └── cache.yaml ← MCP preflight cache, schema: mcp-preflight-cache.v1.schema.json
295
+ ai-tools/
296
+ ├── AGENTS.md
297
+ ├── skills/
298
+ │ ├── plan-feature/SKILL.md ← always (copied verbatim from derive-skills resources)
299
+ │ ├── create-spec/SKILL.md ← always (copied verbatim)
300
+ │ ├── create-qa-use-cases/SKILL.md ← always (copied verbatim)
301
+ │ ├── implement-plan/SKILL.md ← always (generated from template, project-specific)
302
+ │ ├── amend-plan/SKILL.md ← always (generated from template, project-specific)
303
+ │ ├── add-e2e-test/SKILL.md ← optional — only if user opts in
304
+ │ ├── add-env-var/SKILL.md ← optional — only if user opts in
305
+ │ ├── systematic-debugging/SKILL.md ← optional — only if user opts in (template-rendered)
306
+ │ ├── add-one-off-script/ ← optional — only if user opts in (verbatim copy + bundled BaseOneOffScript + LocalRuntime templates)
307
+ │ │ ├── SKILL.md
308
+ │ │ └── resources/
309
+ │ │ ├── one_off_script_base.py
310
+ │ │ └── one_off_script_base.ts
311
+ │ ├── run-one-off-script-django/ ← optional sister skill — only when stack matches + user supplies template (authors Jupyter notebook / mgmt command runner + JupyterRuntime / DjangoMgmtRuntime adapter in the per-script folder)
312
+ │ ├── run-one-off-script-medplum/ ← optional sister skill — only when stack matches + user supplies template (authors Medplum bot + MedplumBotRuntime adapter in the per-script folder)
313
+ │ └── <stack-specific skills>/SKILL.md ← only if user supplied templates
314
+ ├── agents/
315
+ │ ├── implementer.yaml ← always (foundation)
316
+ │ ├── reviewer.yaml ← always (foundation)
317
+ │ ├── fixer.yaml ← always (foundation)
318
+ │ ├── README.md ← schema doc
319
+ │ └── <stack-specific>.yaml ← only if user supplied templates
320
+ └── scripts/
321
+ └── setup-ai-tools.mjs ← copied from install-ai-tools-setup resources
322
+
323
+ DESIGN.md ← preserved at repo root if pre-existing (never overwritten)
324
+ .cursor/rules/design.mdc ← only when DESIGN.md exists, user opted Wire it in,
325
+ and `cursor` ∈ vendors (Cursor Project Rules, Option A
326
+ from https://designmd.app/blog/design-md-with-cursor/)
327
+
328
+ ai-plans/ ← created by migrate-plans-specs (step 6)
329
+ ├── YYYY-MM-DD-FEATURE_NAME_SPEC.md ← migrated from docs/, specs/, root, etc.
330
+ └── YYYY-MM-DD-FEATURE_NAME_PLAN.md ← future docs land here too (foundation
331
+ skills `create-spec` + `plan-feature`
332
+ write to this layout)
333
+ ```
334
+
335
+ Plus the symlinks + per-vendor generated files, set up by the install step.
336
+
337
+ Foundation skills break into three buckets — see [vinta-derive-skills](../vinta-derive-skills/SKILL.md) for the full mechanics:
338
+
339
+ - **Always copy verbatim**: `plan-feature`, `create-spec`, `create-qa-use-cases`. Bundled with the bootstrap skill set; project-agnostic enough to ship as-is (with light path scrubs).
340
+ - **Always generate**: `implement-plan`, `amend-plan`. Bodies have too much project-specific content (test commands, branch convention, PR + co-author policy, agent dispatch) — generated from parameterized templates using interview answers + inventory.
341
+ - **Optional, ask first**: `add-e2e-test`, `add-env-var`, `systematic-debugging`, `add-one-off-script`. Skipped by default; orchestrator asks via `AskUserQuestion` whether the project has the relevant flow at all. `add-e2e-test` / `add-env-var`: if yes + user has a template → copy + adapt; if yes + no template → draft from scratch via interview; if no → don't ship. `systematic-debugging`: if yes → render the bundled template plus the per-tool MCP catalogue blocks for the observability tools selected in its follow-up; if no → don't ship. `add-one-off-script`: if yes → copy the bundled SKILL.md verbatim plus the language-specific `BaseOneOffScript` template (`one_off_script_base.py` / `one_off_script_base.ts`) chosen via its follow-up; if no → don't ship.
342
+
343
+ Stack-specific skills + agents land in the target only when the user provides templates for them. If they don't have templates yet, the orchestrator records the detected stacks + skill categories as a TODO list the user can address later via [vinta-derive-skills](../vinta-derive-skills/SKILL.md) / [vinta-derive-subagents](../vinta-derive-subagents/SKILL.md) standalone runs.
344
+
345
+ ## Rules
346
+
347
+ - **Read before write.** Always check what's in the target repo first. Don't clobber existing AGENTS.md / skills / agents without an explicit confirmation in Step 0.
348
+ - **Stack templates are starting points, not finals.** Each copied skill / agent must be reviewed against the actual project (interview the user about specifics) and edited where the template's assumptions don't fit.
349
+ - **Don't fabricate conventions.** If `vinta-analyze-codebase` doesn't find a thing, ask the user. Don't write "Use bulk_create instead of loop+save" into AGENTS.md just because Django was detected — confirm the team actually follows it.
350
+ - **Foundation skills are universal.** Every project gets `add-env-var`, `add-e2e-test`, `plan-feature`, `implement-plan`, `create-spec`, `create-qa-use-cases`. The bodies need light per-project edits (test commands, branch conventions) — `vinta-derive-skills` handles that.
351
+ - **Foundation agents are universal.** `implementer` / `reviewer` / `fixer` always. Stack specialists (`deploy-author` for Medplum, `migration-author` for Django) only when the stack matches.
352
+ - **Don't run install-ai-tools-setup until AGENTS.md + agents YAMLs + skills exist.** The setup script reads these files; running it on an empty `ai-tools/` produces nothing useful.
353
+ - **Multi-vendor coverage matches the user's selection.** The install step's `--only` flag is set from the Step 0 **Scope → Vendor coverage** answer.
354
+ - **`DESIGN.md` is sacrosanct.** If the repo already has one, never overwrite, rewrite, or "clean up" its contents. Only ever read it to verify shape, and only ever write the sibling `.cursor/rules/design.mdc` pointer when the user opts in + `cursor` is a selected vendor.
355
+
356
+ ## Pitfalls
357
+
358
+ - **Bootstrapping a project that already has its own conventions.** The user's existing AGENTS.md / CONTRIBUTING.md / `.cursorrules` is gospel. Treat as input to `vinta-write-agents-md`, not noise to overwrite.
359
+ - **Detecting Django without verifying multi-tenancy.** Many Django projects are single-tenant; emitting `tenant_id` rules into AGENTS.md is wrong for them. Stack templates are starting points — interview before assuming.
360
+ - **Stack templates pulling source-repo-specific paths.** Templates are written to be project-agnostic (no `apps/<service>` hard-coding) but they may slip. Review each copied SKILL.md / agent.yaml for hard-coded paths from the source repo.
361
+ - **Skipping the interview because "the analysis is enough".** It isn't. Conventions humans hold but don't commit (PR review tone, deploy approvals, who-owns-what) only surface in conversation.
362
+ - **Forgetting to commit the canonical sources.** Generated vendor files are noisy in PRs. `vinta-derive-subagents` writes YAML; `vinta-install-ai-tools-setup` runs the script that produces vendor copies. Commit both — don't gitignore the vendor outputs unless the team agrees.
363
+
364
+ ## Verification
365
+
366
+ After all sub-skills finish:
367
+
368
+ 1. `ls -la ai-tools/` — confirm AGENTS.md, skills/, agents/, scripts/ all exist.
369
+ 2. `node ai-tools/scripts/setup-ai-tools.mjs` — runs cleanly, no errors.
370
+ 3. Each selected vendor's directory has the expected files: `.claude/agents/*.md`, `.cursor/agents/*.md`, `.github/agents/*.agent.md`, `.codex/agents/*.toml`.
371
+ 4. Spot-check one skill, one agent: open SKILL.md / `<agent>.yaml` and confirm content describes THIS project (not a copy-pasted template with `<placeholder>` strings).
372
+ 5. If the project uses Claude Code: in a new session, ask Claude to invoke one of the project-specific skills. Confirm it loads + the body looks right.
373
+ 6. If [vinta-migrate-plans-specs](../vinta-migrate-plans-specs/SKILL.md) ran: `ls ai-plans/` lists the migrated docs in canonical `YYYY-MM-DD-{FEATURE_NAME}_{PLAN|SPEC}.md` form. `git status` shows the renames staged (or already committed). No plan/spec markdown left orphaned in `docs/`, `specs/`, or repo root unless the user explicitly skipped them.
374
+
375
+ End the run with a one-paragraph summary: what was created, what was skipped (per `--only`), what manual edits the user should review.
@@ -0,0 +1,50 @@
1
+ # Stack templates
2
+
3
+ Each subdirectory here defines a **stack** — a set of detection signals + a description of what kinds of skills + sub-agents typically belong to that stack. The bootstrap flow uses these to:
4
+
5
+ 1. Detect (via [vinta-analyze-codebase](../../../vinta-analyze-codebase/SKILL.md)) which stacks the target project matches.
6
+ 2. Ask the user "I detected stack X; do you have skill / sub-agent templates for it? Point me at them" — bootstrap doesn't ship pre-baked content.
7
+ 3. Copy + adapt the user-provided templates into the target's `ai-tools/skills/` and `ai-tools/agents/`.
8
+
9
+ This keeps the bootstrap skill **infrastructure only**. Specific skill content (e.g. "how to add a Medplum bot") lives wherever the user keeps their personal / team skill library, not here.
10
+
11
+ ## Layout per stack
12
+
13
+ ```
14
+ <stack-name>/
15
+ └── notes.md # detection signals + typical skill/agent categories for this stack
16
+ ```
17
+
18
+ That's it. No `skills/` or `agents/` subdirs with content — those would be project-specific by nature, and the bootstrap orchestrator can't ship "the right" Medplum / Django / etc skill for every team.
19
+
20
+ ## How the orchestrator uses these
21
+
22
+ For each stack whose detection signals match the target's analyze-codebase inventory:
23
+
24
+ 1. Read `<stack>/notes.md`.
25
+ 2. Surface the match to the user: *"This project looks like a Medplum stack. The notes say teams typically maintain skills for: bot creation, AccessPolicy management, notification dispatch. Do you have existing templates for any of these?"*
26
+ 3. If yes → ask for paths (filesystem, Git URL, gist, etc). Copy + adapt into target's `ai-tools/`.
27
+ 4. If no → record as a known gap. The user can run [vinta-derive-skills](../../../vinta-derive-skills/SKILL.md) standalone later to draft them from scratch.
28
+
29
+ ## Adding a new stack
30
+
31
+ 1. `mkdir resources/stacks/<stack-name>`.
32
+ 2. Write `notes.md` with:
33
+ - **Detection signals** (what tells you this stack matches).
34
+ - **Skill categories typically needed** (just names + one-liners — no full SKILL.md content).
35
+ - **Agent categories typically needed** (same).
36
+ - **Common placeholders** the orchestrator should ask the user about (paths, command names, env-var names).
37
+ 3. Update the **Frameworks (from dependencies)** scan in [vinta-analyze-codebase](../../../vinta-analyze-codebase/SKILL.md#3-frameworks-from-dependencies) if a new dep / signal-file table row is needed.
38
+ 4. Update [vinta-bootstrap-ai-tools](../../SKILL.md) "Stack templates" table.
39
+
40
+ ## Existing stacks
41
+
42
+ | Stack | Detection notes |
43
+ |---|---|
44
+ | [medplum/](medplum/) | FHIR R4 backend, bot deploy, AccessPolicy model |
45
+ | [django/](django/) | Django + Postgres, multi-tenant if `tenant_id` columns / partitioning |
46
+ | [typescript-monorepo/](typescript-monorepo/) | Turbo / pnpm workspaces, `apps/` + `lib/` layout |
47
+ | [python-package/](python-package/) | `pyproject.toml` non-Django, `src/<pkg>/` layout |
48
+ | [nextjs-app-router/](nextjs-app-router/) | Next.js App Router, `app/` directory |
49
+
50
+ Add stacks as the team encounters new ones. Each is one notes.md file.
@@ -0,0 +1,52 @@
1
+ # Django + Postgres stack
2
+
3
+ ## Detection signals
4
+
5
+ Repo matches when:
6
+
7
+ - `pyproject.toml` (or `requirements*.txt`) lists `django` (any version).
8
+ - `manage.py` exists at root or in a `<project>/` subdir.
9
+ - At least one `<app>/migrations/` directory is present.
10
+
11
+ Multi-tenancy variant signals (any one triggers the multi-tenant flavor of skill prompts):
12
+
13
+ - `psqlextra` or `django-postgres-extra` in deps → likely LIST partitioning by tenant key.
14
+ - `tenant_id` (or `organization_id`, `account_id`) `UUIDField` / `ForeignKey` on hot-table models.
15
+ - A custom `Manager` / `QuerySet` with `for_tenant(...)` / `filter_tenant(...)` methods.
16
+ - Middleware that injects `request.tenant`.
17
+
18
+ If no multi-tenancy signals → single-tenant Django; the team's templates may still apply, just without the per-tenant filter rules.
19
+
20
+ ## Skill categories typically needed
21
+
22
+ - **Add-model** — base class, custom QuerySet + Manager (`from_queryset`), `db_table` explicit, `__all__` exports, admin registration, tenant column + index if multi-tenant, tests.
23
+ - **Add-migration** — naming, dependencies, `db_default` for non-null new columns, hot-table operations (CONCURRENTLY indexes, avoiding rewrites), `psqlextra` partitioned tables, view-version migrations (`vw_*`), HStore extensions, deferred constraints, the reverse path.
24
+ - **Create-postgres-view** (if the project uses versioned `vw_*` / `mv_*` views via a schema framework) — versioned SQL files, `MigrationSchemaView`, `Schema.Apply(N)` pattern.
25
+ - **Create-postgres-function** (if the project ships custom `CREATE FUNCTION` / aggregates) — versioned function migrations.
26
+ - **Create-data-import / create-data-export** — async import/export commands feeding integrations.
27
+ - **GraphQL-public-query** (if the project uses Strawberry or Graphene) — public-API mutation/query patterns.
28
+ - **REST-endpoint** (if the project uses Django REST Framework or django-ninja) - REST API endpoint patterns.
29
+ - **Run-one-off-script-django** — sister to the universal `add-one-off-script` foundation skill. Authors the *runner* artefact in the per-script folder (Jupyter notebook in `notebooks/` is the typical Vinta default; a thin `BaseCommand` under `<app>/management/commands/<name>.py` is the alternative for headless / cron / CI invocation) and ships the matching `Runtime` adapter at `<scripts_dir>/_runtime_django.py` (`JupyterRuntime` and/or `DjangoMgmtRuntime`). Adapter responsibilities: hook `BaseCommand.handle()` into `BaseOneOffScript.execute()`; respect `python manage.py <name> --apply` / `--resume` / `--status` / `--restore` flags; load Django settings + DB connection before the engine starts iterating; for the Jupyter variant, swap signal handlers for kernel-interrupt and skip the PID-file lease (notebook = single instance by construction). README in the per-script folder spells out `python manage.py shell < script.py`, `jupyter lab notebooks/<name>/runner.ipynb`, and `python manage.py <name> --apply` as the three legitimate entry points.
30
+
31
+ ## Agent categories typically needed
32
+
33
+ - **Migration-author** — specialist for high-stakes Django migrations (partitioned tables, view bumps, lock-aware ops on hot tables, deferred constraints, HStore). Treats every operation as a forward contract; audits the reverse path explicitly.
34
+
35
+ ## Placeholders the orchestrator should ask about
36
+
37
+ - Apps directory (e.g. `apps/`, `<project>/app/core/`, `<project>/`)
38
+ - Test directory layout (`tests/unit/`, `tests/integration/`, in-app `tests/`)
39
+ - Test command (`pytest`, `make all-tests`, `python manage.py test`)
40
+ - Lint command (`pre-commit run --files <changed>`, `ruff check`, `make lint`)
41
+ - Type check command (`mypy app/`, `make typecheck`, none)
42
+ - Tenant column name (`tenant_id`, `organization_id`, `account_id`)
43
+ - Hot tables list (the high-traffic models that need migration safety)
44
+ - Migration command (`make migrations`, `python manage.py makemigrations`, `poetry run python manage.py makemigrations`)
45
+ - One-off script invocation surface (Jupyter notebook in `notebooks/<name>/`, Django management command, both) — drives the `run-one-off-script-django` skill's runner artefact + which `Runtime` adapter ships
46
+ - Notebook directory path (`notebooks/`, `<project>/notebooks/`) — only when Jupyter is selected as a runner surface
47
+
48
+ ## When this stack doesn't apply cleanly
49
+
50
+ - Django REST framework but no DB (read-only API on top of an external service) → most of these skills don't apply.
51
+ - Single-tenant Django → apply but drop tenant-filter rules.
52
+ - Async-first (`asgi.py`, `django-channels`) → templates may need additional async-handling sections.
@@ -0,0 +1,45 @@
1
+ # Medplum stack
2
+
3
+ ## Detection signals
4
+
5
+ The target project matches this stack when **all** of these are true:
6
+
7
+ - `package.json` (any workspace) lists `@medplum/core`, `@medplum/fhirtypes`, or `@medplum/react` in dependencies.
8
+ - A `bots/` directory exists somewhere (typically `apps/<app>/bots/` or `packages/bots/`).
9
+ - Per-env tenant-Organization signals (any of):
10
+ - `meta.account` references in code that creates FHIR resources.
11
+ - `withTenantScope(...)` helper calls (if project is multi-tenants)
12
+ - `_compartment=Organization/<id>` in Subscription criteria (if project is multi-tenants).
13
+
14
+ If only the SDK is in dependencies but no `bots/` directory and no tenant compartmenting → **don't apply** this stack. The project is consuming the Medplum API, not running on Medplum the way an opinionated bot-driven setup does.
15
+
16
+ ## Skill categories typically needed
17
+
18
+ Names are conventional — the team's existing templates may use different naming. Surface these to the user as "do you have something like this?" prompts.
19
+
20
+ - **Add-bot** — handler/service split, BOTS registry entry, Subscription criteria + interaction extension, tenant scoping (`meta.account`), tests with `MockClient`.
21
+ - **Manage-access-policy** — AccessPolicy bundle JSON anatomy, tenant compartment pattern, `npx medplum post` reseed, RBAC two-layer relationship (server-side AccessPolicy + client-side permission gates).
22
+ - **Add-notification** (if vintasend or similar): registry entry, per-channel templates, context-generator/resolver map, dispatch helpers, tenant field on every create.
23
+ - **Run-one-off-script-medplum** — sister to the universal `add-one-off-script` foundation skill. Authors a Medplum bot at `<bots_dir>/one_off_<YYYY_MM_DD>_<name>/handler.ts` that imports the `BaseOneOffScript` subclass from the per-script folder and invokes `script.execute()` from inside the bot, plus the matching `MedplumBotRuntime` adapter at `<scripts_dir>/_runtime_medplum.ts`. Adapter responsibilities: lease becomes a no-op (Medplum guarantees single bot instance); `install_stop_handler` listens for the bot's cancellation token; `log` writes to `bot.log()`; CSV backup chunks + `run.log` upload to Medplum `Binary` resources (no FS in a bot) — restore reads them back via the FHIR API. Subscription criteria + BOTS registry entry are added by the same skill; tenant scoping (`meta.account`) on every created Binary follows the project's standard pattern.
24
+
25
+ ## Agent categories typically needed
26
+
27
+ - **Deploy-author** — specialist for deploy-affecting changes: AccessPolicy reseed via `npx medplum post`, bot deploy with Subscriptions, notification template compile-and-seed, env-var propagation across Vite / Turbo / CI.
28
+
29
+ ## Placeholders the orchestrator should ask about
30
+
31
+ When the user provides their existing templates, the orchestrator should substitute these per the target project:
32
+
33
+ - Bot directory path (e.g. `apps/<service>/bots/`)
34
+ - AccessPolicy JSON directory (e.g. `apps/<service>/data/`)
35
+ - Bot deploy command (e.g. `pnpm bots:deploy`)
36
+ - Tenant helper module path (e.g. `apps/<service>/bots/utils/tenant.ts`)
37
+ - Project naming (`Organization` vs `Project`, `org` vs `team`, etc)
38
+ - One-off script invocation surface — bot vs Medplum CLI script — drives the `run-one-off-script-medplum` skill's runner artefact + `Runtime` adapter shape
39
+
40
+ If the team's template library uses different terminology, follow theirs.
41
+
42
+ ## When this stack doesn't apply cleanly
43
+
44
+ - Project uses Medplum SDK only (no bots, no AccessPolicy bundles, no tenant compartmenting) → skip.
45
+ - Project has bots but uses a different deploy model (e.g. Lambda-based instead of Medplum-managed) → likely a different stack template; consider adding one.
@@ -0,0 +1,35 @@
1
+ # Next.js App Router stack
2
+
3
+ ## Detection signals
4
+
5
+ - `package.json` lists `next` (any version with App Router support — 13.4+).
6
+ - `app/` directory at repo root or app-package root.
7
+ - `next.config.{js,ts,mjs}` exists.
8
+
9
+ If the project uses Pages Router only (`pages/` directory, no `app/`) → either skip this stack or add a separate `nextjs-pages` stack.
10
+
11
+ ## Skill categories typically needed
12
+
13
+ - **Add-route** — Server Component vs Client Component decision, layout/page/loading/error file conventions, route group conventions, server-action wiring.
14
+ - **Add-server-action** — `'use server'` directive placement, form submission patterns, revalidation strategy, error handling.
15
+ - **Manage-caching** — `unstable_cache`, `revalidatePath`, `revalidateTag`, `cache: 'force-cache' | 'no-store'`, dynamic vs static segments. Cache Components if Next.js 16+.
16
+ - **Add-middleware-rule** — `middleware.ts` (or `proxy.ts` in Next.js 16+), matcher patterns, response rewrites/redirects, header/cookie manipulation.
17
+ - **Add-route-handler** (API endpoint) — `app/api/<route>/route.ts`, method exports, request validation, response shaping.
18
+
19
+ ## Agent categories typically needed
20
+
21
+ None specific — foundation trio covers most Next.js work. A `cache-author` specialist could be useful if the project has complex caching invariants.
22
+
23
+ ## Placeholders the orchestrator should ask about
24
+
25
+ - Next.js version (drives Cache Components / `proxy.ts` vs `middleware.ts` / Server Actions stability decisions)
26
+ - Deploy target (Vercel, self-hosted, container, edge)
27
+ - Auth library (Clerk, NextAuth, Auth0, Descope, custom)
28
+ - Data layer (Prisma, Drizzle, raw SQL, REST/GraphQL client to external API)
29
+ - Component library (shadcn/ui, Mantine, Chakra, custom)
30
+ - Styling (Tailwind, CSS Modules, styled-components, vanilla-extract)
31
+
32
+ ## When this stack doesn't apply
33
+
34
+ - Next.js Pages Router only → use a separate stack template.
35
+ - Next.js used purely as a static-site generator (`output: 'export'`) → most server-side skills don't apply.
@@ -0,0 +1,31 @@
1
+ # Python package stack
2
+
3
+ ## Detection signals
4
+
5
+ - `pyproject.toml` at root with `[project]` or `[tool.poetry]` (or `[tool.hatch]`, `[tool.uv]`, etc).
6
+ - `src/<pkg>/` or `<pkg>/` layout (no Django).
7
+ - `manage.py` absent (rules out Django — that's a separate stack).
8
+
9
+ ## Skill categories typically needed
10
+
11
+ - **Add-module** (sometimes) — when the team has conventions for new modules: file layout, `__all__` exports, entry-point registration in `pyproject.toml`, test file pairing.
12
+ - **Add-cli-command** (if the package ships a CLI via `[project.scripts]` or click/typer) — register entry point, argument schema, test pattern.
13
+ - **Release-package** (if PyPI publishing is part of the flow) — versioning, changelog, `python -m build`, `twine upload` (or trusted publisher), tag conventions.
14
+
15
+ ## Agent categories typically needed
16
+
17
+ None specific — foundation trio is enough for most Python packages.
18
+
19
+ ## Placeholders the orchestrator should ask about
20
+
21
+ - Package manager (`poetry`, `uv`, `pip + pip-tools`, `hatch`, plain `pip`)
22
+ - Source layout (`src/<pkg>/` vs flat `<pkg>/`)
23
+ - Test runner (`pytest`, `unittest`)
24
+ - Lint+format (`ruff`, `black`, `pylint`, `flake8`)
25
+ - Type check (`mypy`, `pyright`, none)
26
+ - Distribution target (PyPI, internal index, GitHub Releases, none)
27
+
28
+ ## When this stack doesn't apply
29
+
30
+ - Library + Django co-exist → use `django/` stack (which handles the migration + multi-tenant pieces).
31
+ - Pure scripting collection without packaging → foundation is sufficient.