compound-workflow 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/.claude-plugin/marketplace.json +11 -0
  2. package/.claude-plugin/plugin.json +12 -0
  3. package/.cursor-plugin/plugin.json +12 -0
  4. package/README.md +155 -0
  5. package/package.json +22 -0
  6. package/scripts/install-cli.mjs +313 -0
  7. package/scripts/sync-into-repo.sh +103 -0
  8. package/src/.agents/agents/research/best-practices-researcher.md +132 -0
  9. package/src/.agents/agents/research/framework-docs-researcher.md +134 -0
  10. package/src/.agents/agents/research/git-history-analyzer.md +62 -0
  11. package/src/.agents/agents/research/learnings-researcher.md +288 -0
  12. package/src/.agents/agents/research/repo-research-analyst.md +146 -0
  13. package/src/.agents/agents/review/agent-native-reviewer.md +299 -0
  14. package/src/.agents/agents/workflow/bug-reproduction-validator.md +87 -0
  15. package/src/.agents/agents/workflow/lint.md +20 -0
  16. package/src/.agents/agents/workflow/spec-flow-analyzer.md +149 -0
  17. package/src/.agents/commands/assess.md +60 -0
  18. package/src/.agents/commands/install.md +53 -0
  19. package/src/.agents/commands/metrics.md +59 -0
  20. package/src/.agents/commands/setup.md +9 -0
  21. package/src/.agents/commands/sync.md +9 -0
  22. package/src/.agents/commands/test-browser.md +393 -0
  23. package/src/.agents/commands/workflow/brainstorm.md +252 -0
  24. package/src/.agents/commands/workflow/compound.md +142 -0
  25. package/src/.agents/commands/workflow/plan.md +737 -0
  26. package/src/.agents/commands/workflow/review-v2.md +148 -0
  27. package/src/.agents/commands/workflow/review.md +110 -0
  28. package/src/.agents/commands/workflow/triage.md +54 -0
  29. package/src/.agents/commands/workflow/work.md +439 -0
  30. package/src/.agents/references/README.md +12 -0
  31. package/src/.agents/references/standards/README.md +9 -0
  32. package/src/.agents/scripts/self-check.mjs +227 -0
  33. package/src/.agents/scripts/sync-opencode.mjs +355 -0
  34. package/src/.agents/skills/agent-browser/SKILL.md +223 -0
  35. package/src/.agents/skills/audit-traceability/SKILL.md +260 -0
  36. package/src/.agents/skills/brainstorming/SKILL.md +250 -0
  37. package/src/.agents/skills/compound-docs/SKILL.md +533 -0
  38. package/src/.agents/skills/compound-docs/assets/critical-pattern-template.md +34 -0
  39. package/src/.agents/skills/compound-docs/assets/resolution-template.md +97 -0
  40. package/src/.agents/skills/compound-docs/references/yaml-schema.md +87 -0
  41. package/src/.agents/skills/compound-docs/schema.project.yaml +18 -0
  42. package/src/.agents/skills/compound-docs/schema.yaml +119 -0
  43. package/src/.agents/skills/data-foundations/SKILL.md +185 -0
  44. package/src/.agents/skills/document-review/SKILL.md +108 -0
  45. package/src/.agents/skills/file-todos/SKILL.md +177 -0
  46. package/src/.agents/skills/file-todos/assets/todo-template.md +106 -0
  47. package/src/.agents/skills/financial-workflow-integrity/SKILL.md +423 -0
  48. package/src/.agents/skills/git-worktree/SKILL.md +268 -0
  49. package/src/.agents/skills/pii-protection-prisma/SKILL.md +629 -0
  50. package/src/.agents/skills/process-metrics/SKILL.md +46 -0
  51. package/src/.agents/skills/process-metrics/assets/daily-template.md +37 -0
  52. package/src/.agents/skills/process-metrics/assets/monthly-template.md +21 -0
  53. package/src/.agents/skills/process-metrics/assets/weekly-template.md +25 -0
  54. package/src/.agents/skills/technical-review/SKILL.md +83 -0
  55. package/src/AGENTS.md +213 -0
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "compound-workflow",
3
+ "owner": { "name": "Compound Workflow" },
4
+ "plugins": [
5
+ {
6
+ "name": "compound-workflow",
7
+ "source": ".",
8
+ "description": "Clarify → plan → execute → verify → capture workflow. Commands, skills, and agents for structured development."
9
+ }
10
+ ]
11
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "compound-workflow",
3
+ "version": "0.1.0",
4
+ "description": "Clarify → plan → execute → verify → capture workflow: commands, skills, and agents for Claude Code",
5
+ "author": { "name": "Compound Workflow" },
6
+ "keywords": ["workflow", "planning", "agents", "skills", "commands"],
7
+ "license": "MIT",
8
+ "repository": "https://github.com/your-org/compound-workflow",
9
+ "commands": "./src/.agents/commands",
10
+ "agents": "./src/.agents/agents",
11
+ "skills": "./src/.agents/skills"
12
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "compound-workflow",
3
+ "version": "0.1.0",
4
+ "description": "Clarify → plan → execute → verify → capture workflow: commands, skills, and agents for Cursor, Claude, and OpenCode",
5
+ "author": { "name": "Compound Workflow" },
6
+ "keywords": ["workflow", "cursor", "claude", "opencode", "agents", "planning"],
7
+ "license": "MIT",
8
+ "repository": { "type": "git", "url": "https://github.com/your-org/compound-workflow" },
9
+ "skills": "src/.agents/skills",
10
+ "agents": "src/.agents/agents",
11
+ "commands": "src/.agents/commands"
12
+ }
package/README.md ADDED
@@ -0,0 +1,155 @@
1
+ # Compound Workflow (.agents)
2
+
3
+ A portable, command-first workflow: **clarify → plan → execute → verify → capture**. Commands are the public API; skills and agents are composable internals.
4
+
5
+ It reduces delivery failures from **unclear intent**, **weak verification**, and **lost context**. Use it when you want structured cycles without ad-hoc tooling.
6
+
7
+ *This template and README are continually refined during development.*
8
+
9
+ Inspired by [Compound Engineering](https://every.to/guides/compound-engineering) (Every) — the AI-native philosophy that each unit of work should compound into the next.
10
+
11
+ Runtime assets live in `src/.agents/` and `src/AGENTS.md`. **Cursor/Claude:** load via plugin. **OpenCode:** install the npm package and run Install once.
12
+
13
+ ---
14
+
15
+ ## Get started
16
+
17
+ **One action:** In your project (with compound-workflow as a dependency), run **Install**—either the `/install` command in Cursor/Claude or:
18
+
19
+ ```bash
20
+ npm install compound-workflow
21
+ npx compound-workflow install
22
+ ```
23
+
24
+ Optional: `--dry-run` (preview), `--root /path/to/project`, `--no-config` (skip Repo Config Block reminder).
25
+
26
+ Install writes `opencode.json` (OpenCode loads from the package), merges `AGENTS.md` (preserves your Repo Config Block), creates standard dirs, and reminds you to set the Repo Config Block in `AGENTS.md` if needed. No copy; Cursor/Claude use the plugin; OpenCode reads from `node_modules/compound-workflow`.
27
+
28
+ **Cursor / Claude:** Add the compound-workflow plugin (from this repo or marketplace). Then in any repo you can run `/install` or use the CLI above.
29
+
30
+ **Legacy (clone inside repo):** If you cloned this repo inside a host repo and need to copy files without npm, use `./scripts/sync-into-repo.sh` (copy only; does not update opencode.json). Prefer the npm + Install flow above.
31
+
32
+ To update to a new release, see [Updating compound-workflow](#updating-compound-workflow).
33
+
34
+ ---
35
+
36
+ ## Updating compound-workflow
37
+
38
+ - **Cursor / Claude (plugin):** Update via the editor’s plugin/marketplace (check for updates or reinstall). If installed from repo, pull latest and reload the plugin. No per-project step; the plugin loads commands/skills from its installed source.
39
+ - **OpenCode / npm:** Run `npm update compound-workflow` (or bump the version in `package.json` and `npm install`), then run **Install** again: `/install` or `npx compound-workflow install`. This refreshes `opencode.json`, merges the latest `AGENTS.md` template, and ensures dirs exist; Repo Config Block is preserved.
40
+
41
+ ---
42
+
43
+ ## Workflow at a glance
44
+
45
+ Clarify what to build → plan how (fidelity + confidence) → execute via todos → triage and review → capture learnings → log and assess.
46
+
47
+ ```mermaid
48
+ flowchart LR
49
+ A[brainstorm] --> B[plan] --> C[work] --> D[triage] --> E[review] --> F[compound] --> G[metrics]
50
+ ```
51
+
52
+ ---
53
+
54
+ ## Step-by-step: intent and commands
55
+
56
+ | Step | Intent | Command | Output / note |
57
+ |------|--------|---------|---------------|
58
+ | Clarify what to build | Dialogue only; no code | `/workflow:brainstorm [topic]` | `docs/brainstorms/` |
59
+ | Define how (fidelity + confidence) | Plan only; no code | `/workflow:plan [description or brainstorm path]` | `docs/plans/` |
60
+ | Execute | File-based todos; risk-tier testing; no auto-ship | `/workflow:work <plan-path>` | `todos/` |
61
+ | Ready the queue | Priority and dependencies for pending todos | `/workflow:triage` | — |
62
+ | Validate quality | Evidence-based review; no fixes by default | `/workflow:review [PR, branch, or current]` | pass / pass-with-notes / fail |
63
+ | Capture learnings | One solution doc for future use | `/workflow:compound [context]` | `docs/solutions/` |
64
+ | Log and improve | Session log + optional aggregate review | `/metrics` + `/assess weekly 7` (or monthly) | `docs/metrics/daily/`, weekly/monthly |
65
+
66
+ #### 1. Clarify (brainstorm)
67
+
68
+ **Intent:** Dialogue only; no code. **Command:** `/workflow:brainstorm [topic]`. **Output:** `docs/brainstorms/`.
69
+
70
+ #### 2. Define how (plan)
71
+
72
+ **Intent:** Plan only; no code; fidelity + confidence. **Command:** `/workflow:plan [description or brainstorm path]`. **Output:** `docs/plans/`.
73
+
74
+ #### 3. Execute (work)
75
+
76
+ **Intent:** File-based todos; risk-tier testing; no auto-ship. **Command:** `/workflow:work <plan-path>`. **Output:** `todos/`.
77
+
78
+ #### 4. Ready the queue (triage)
79
+
80
+ **Intent:** Priority and dependencies for pending todos. **Command:** `/workflow:triage`. **Output:** —.
81
+
82
+ #### 5. Validate quality (review)
83
+
84
+ **Intent:** Evidence-based review; no fixes by default. **Command:** `/workflow:review [PR|branch|current]`. **Output:** pass / pass-with-notes / fail.
85
+
86
+ #### 6. Capture learnings (compound)
87
+
88
+ **Intent:** One solution doc for future use. **Command:** `/workflow:compound [context]`. **Output:** `docs/solutions/`.
89
+
90
+ #### 7. Log and improve
91
+
92
+ **Intent:** Session log + optional aggregate review. **Command:** `/metrics` + `/assess weekly 7` (or monthly). **Output:** `docs/metrics/daily/`, weekly/monthly.
93
+
94
+ **Optional QA:** **`/test-browser [PR|branch|current]`** — Browser validation on affected pages via **agent-browser CLI only** (not MCP). Install: `npm install -g agent-browser` then `agent-browser install`. See [src/.agents/commands/test-browser.md](src/.agents/commands/test-browser.md).
95
+
96
+ ---
97
+
98
+ ## Command reference
99
+
100
+ **Onboarding:** `/install` — one action: writes opencode.json, merges AGENTS.md, creates dirs, preserves Repo Config Block. Run `npx compound-workflow install` in the project (requires `npm install compound-workflow`). Re-run after `npm update compound-workflow` to refresh config; see [Updating compound-workflow](#updating-compound-workflow).
101
+
102
+ **Core workflow:** See [Step-by-step](#step-by-step-intent-and-commands) above.
103
+
104
+ **QA:** `/test-browser [PR|branch|current]` — browser checks on affected routes (agent-browser CLI only).
105
+
106
+ **Improvement:** `/metrics [plan|todo|pr|solution|label]` — log session to `docs/metrics/daily/` and assess. `/assess [daily|weekly|monthly] [count]` — aggregate metrics and optional summary files.
107
+
108
+ **Experimental:** `/workflow:review-v2 [PR|branch|current]` — interactive snippet review; output-only (no GitHub publish).
109
+
110
+ Full detail: [src/AGENTS.md](src/AGENTS.md), [src/.agents/commands/](src/.agents/commands/).
111
+
112
+ ---
113
+
114
+ ## Artifacts
115
+
116
+ - **Brainstorms:** `docs/brainstorms/YYYY-MM-DD-<topic>-brainstorm.md`
117
+ - **Plans:** `docs/plans/YYYY-MM-DD-<type>-<slug>-plan.md`
118
+ - **Todos:** `todos/{id}-{status}-{priority}-{slug}.md`
119
+ - **Solutions:** `docs/solutions/<category>/YYYY-MM-DD-<module-slug>-<symptom-slug>.md`
120
+ - **Metrics:** `docs/metrics/daily/YYYY-MM-DD.md`, `docs/metrics/weekly/YYYY-WW.md`, `docs/metrics/monthly/YYYY-MM.md`
121
+
122
+ ---
123
+
124
+ ## How it works (internals)
125
+
126
+ Commands are the public API. Skills and agents are invoked by commands; you don’t call them directly.
127
+
128
+ - **Workflow skills:** `brainstorming`, `file-todos`, `compound-docs`, `document-review`, `technical-review`, `git-worktree`, `agent-browser`, `process-metrics`.
129
+ - **Guardrail standards:** `data-foundations`, `pii-protection-prisma`, `financial-workflow-integrity`, `audit-traceability` — applied when work touches multi-tenant data, PII, money, or audit.
130
+ - **Agents:** Used by plan, review, and work for research, lint, and validation (e.g. `repo-research-analyst`, `learnings-researcher`, `git-history-analyzer`, `agent-native-reviewer`).
131
+
132
+ Full “when to use what” and reference standards: [src/AGENTS.md](src/AGENTS.md).
133
+
134
+ ---
135
+
136
+ ## Guardrails
137
+
138
+ - **No auto-ship:** `/workflow:work` and `/workflow:review` do not commit, push, or create PRs by default.
139
+
140
+ - **Brainstorm and plan do not write code.** Output is documents only.
141
+
142
+ - Add a separate shipping command if you want automated commit/PR and quality gates.
143
+
144
+ ---
145
+
146
+ ## Configuration and optional bits
147
+
148
+ **Repo configuration:** Commands read a **Repo Config Block** (YAML) in `AGENTS.md` for `default_branch`, `dev_server_url`, `test_command`, etc. Run **`/install`** once; then edit `AGENTS.md` to set the Repo Config Block.
149
+
150
+ **agent-browser:** `/test-browser` uses the agent-browser CLI only. Install: `npm install -g agent-browser` then `agent-browser install`. See [src/.agents/commands/test-browser.md](src/.agents/commands/test-browser.md).
151
+
152
+ **Source of truth**
153
+
154
+ - Workflows and commands: [src/.agents/](src/.agents/)
155
+ - Principles and skill index: [src/AGENTS.md](src/AGENTS.md)
package/package.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "compound-workflow",
3
+ "version": "0.1.1",
4
+ "description": "Clarify → plan → execute → verify → capture. One Install action for Cursor, Claude, and OpenCode.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/your-org/compound-workflow.git"
9
+ },
10
+ "bin": {
11
+ "compound-workflow": "scripts/install-cli.mjs"
12
+ },
13
+ "files": [
14
+ "src",
15
+ "scripts",
16
+ ".cursor-plugin",
17
+ ".claude-plugin"
18
+ ],
19
+ "engines": {
20
+ "node": ">=18"
21
+ }
22
+ }
@@ -0,0 +1,313 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * compound-workflow install
4
+ * One action: opencode.json (load from package) + AGENTS.md merge + dirs + Repo Config Block.
5
+ * Run from project: npx compound-workflow install [--root <dir>] [--dry-run] [--no-config]
6
+ */
7
+ import fs from "node:fs";
8
+ import path from "node:path";
9
+ import { fileURLToPath } from "node:url";
10
+
11
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
12
+
13
+ function usage(exitCode = 0) {
14
+ const msg = `
15
+ Usage:
16
+ npx compound-workflow install [--root <projectDir>] [--dry-run] [--no-config]
17
+
18
+ One action: writes opencode.json (loads from package), merges AGENTS.md, creates dirs,
19
+ and prompts for Repo Config Block (unless --no-config).
20
+
21
+ --root <dir> Project directory (default: cwd)
22
+ --dry-run Print planned changes only
23
+ --no-config Skip Repo Config Block prompt (only write opencode.json + AGENTS.md + dirs)
24
+ `;
25
+ (exitCode === 0 ? console.log : console.error)(msg.trimStart());
26
+ process.exit(exitCode);
27
+ }
28
+
29
+ function parseArgs(argv) {
30
+ const out = { root: process.cwd(), dryRun: false, noConfig: false };
31
+ for (let i = 2; i < argv.length; i++) {
32
+ const a = argv[i];
33
+ if (a === "--dry-run") out.dryRun = true;
34
+ else if (a === "--no-config") out.noConfig = true;
35
+ else if (a === "--root") {
36
+ const v = argv[i + 1];
37
+ if (!v) usage(1);
38
+ out.root = v;
39
+ i++;
40
+ } else if (a === "-h" || a === "--help") usage(0);
41
+ else if (a && a !== "install" && !a.startsWith("-")) usage(1);
42
+ }
43
+ return out;
44
+ }
45
+
46
+ function realpathSafe(p) {
47
+ try {
48
+ return fs.realpathSync(p);
49
+ } catch {
50
+ return path.resolve(p);
51
+ }
52
+ }
53
+
54
+ const packageRoot = realpathSafe(path.join(__dirname, ".."));
55
+ const packageAgents = path.join(packageRoot, "src", ".agents");
56
+ const PKG_PREFIX = "node_modules/compound-workflow";
57
+
58
+ function walkFiles(dirAbs, predicate) {
59
+ const out = [];
60
+ const stack = [dirAbs];
61
+ while (stack.length) {
62
+ const cur = stack.pop();
63
+ let entries;
64
+ try {
65
+ entries = fs.readdirSync(cur, { withFileTypes: true });
66
+ } catch {
67
+ continue;
68
+ }
69
+ for (const e of entries) {
70
+ const p = path.join(cur, e.name);
71
+ if (e.isDirectory()) stack.push(p);
72
+ else if (e.isFile() && predicate(p)) out.push(p);
73
+ }
74
+ }
75
+ out.sort();
76
+ return out;
77
+ }
78
+
79
+ function parseFrontmatter(md) {
80
+ if (!md.startsWith("---\n") && !md.startsWith("---\r\n")) return {};
81
+ const end = md.indexOf("\n---", 4);
82
+ if (end === -1) return {};
83
+ const block = md.slice(4, end + 1);
84
+ const out = {};
85
+ for (const line of block.split(/\r?\n/)) {
86
+ const m = line.match(/^([A-Za-z0-9_-]+):\s*(.*)\s*$/);
87
+ if (!m) continue;
88
+ let v = (m[2] ?? "").replace(/^"(.*)"$/, "$1").replace(/^'(.*)'$/, "$1");
89
+ out[m[1]] = v;
90
+ }
91
+ return out;
92
+ }
93
+
94
+ function discoverCommands(agentsRoot) {
95
+ const commandsDir = path.join(agentsRoot, "commands");
96
+ const files = walkFiles(commandsDir, (p) => p.endsWith(".md"));
97
+ const map = new Map();
98
+ for (const fileAbs of files) {
99
+ const rel = path.relative(packageRoot, fileAbs).replaceAll(path.sep, "/");
100
+ const md = fs.readFileSync(fileAbs, "utf8");
101
+ const fm = parseFrontmatter(md);
102
+ const id = (fm.invocation || fm.name || path.basename(fileAbs, ".md")).trim();
103
+ const description = (fm.description || id).trim();
104
+ if (!id) continue;
105
+ const pkgRel = `${PKG_PREFIX}/${rel}`;
106
+ map.set(id, { id, rel: pkgRel, description });
107
+ }
108
+ return map;
109
+ }
110
+
111
+ function discoverAgents(agentsRoot) {
112
+ const agentsDir = path.join(agentsRoot, "agents");
113
+ const files = walkFiles(agentsDir, (p) => p.endsWith(".md"));
114
+ const map = new Map();
115
+ for (const fileAbs of files) {
116
+ const rel = path.relative(packageRoot, fileAbs).replaceAll(path.sep, "/");
117
+ const md = fs.readFileSync(fileAbs, "utf8");
118
+ const fm = parseFrontmatter(md);
119
+ const id = (fm.name || path.basename(fileAbs, ".md")).trim();
120
+ const description = (fm.description || id).trim();
121
+ if (!id) continue;
122
+ const pkgRel = `${PKG_PREFIX}/${rel}`;
123
+ map.set(id, { id, rel: pkgRel, description });
124
+ }
125
+ return map;
126
+ }
127
+
128
+ function ensureObject(v) {
129
+ return v && typeof v === "object" && !Array.isArray(v) ? v : {};
130
+ }
131
+
132
+ function stripJsonc(input) {
133
+ let out = "";
134
+ let i = 0;
135
+ let inStr = false,
136
+ strQuote = "",
137
+ escape = false;
138
+ while (i < input.length) {
139
+ const c = input[i];
140
+ const n = input[i + 1];
141
+ if (inStr) {
142
+ out += c;
143
+ if (escape) escape = false;
144
+ else if (c === "\\") escape = true;
145
+ else if (c === strQuote) inStr = false;
146
+ i++;
147
+ continue;
148
+ }
149
+ if (c === '"' || c === "'") {
150
+ inStr = true;
151
+ strQuote = c;
152
+ out += c;
153
+ i++;
154
+ continue;
155
+ }
156
+ if (c === "/" && n === "/") {
157
+ while (i < input.length && input[i] !== "\n") i++;
158
+ continue;
159
+ }
160
+ if (c === "/" && n === "*") {
161
+ i += 2;
162
+ while (i < input.length && !(input[i] === "*" && input[i + 1] === "/")) i++;
163
+ i += 2;
164
+ continue;
165
+ }
166
+ out += c;
167
+ i++;
168
+ }
169
+ return out;
170
+ }
171
+
172
+ function readJsonMaybe(fileAbs) {
173
+ if (!fs.existsSync(fileAbs)) return null;
174
+ const raw = fs.readFileSync(fileAbs, "utf8");
175
+ return JSON.parse(stripJsonc(raw));
176
+ }
177
+
178
+ function writeOpenCodeJson(targetRoot, dryRun) {
179
+ const opencodeAbs = path.join(targetRoot, "opencode.json");
180
+ const existing = readJsonMaybe(opencodeAbs) ?? {};
181
+ const next = structuredClone(existing);
182
+
183
+ next.$schema = next.$schema || "https://opencode.ai/config.json";
184
+ next.skills = ensureObject(next.skills);
185
+ const skillsPath = `${PKG_PREFIX}/src/.agents/skills`;
186
+ if (!Array.isArray(next.skills.paths)) next.skills.paths = [];
187
+ if (!next.skills.paths.includes(skillsPath)) next.skills.paths.unshift(skillsPath);
188
+ next.command = ensureObject(next.command);
189
+ next.agent = ensureObject(next.agent);
190
+
191
+ const commands = discoverCommands(packageAgents);
192
+ const agents = discoverAgents(packageAgents);
193
+
194
+ for (const [id, cmd] of commands) {
195
+ next.command[id] = {
196
+ ...ensureObject(next.command[id]),
197
+ description: cmd.description,
198
+ agent: "build",
199
+ template: `@AGENTS.md\n@${cmd.rel}\nArguments: $ARGUMENTS\n`,
200
+ };
201
+ }
202
+ for (const [id, ag] of agents) {
203
+ next.agent[id] = {
204
+ ...ensureObject(next.agent[id]),
205
+ description: ag.description,
206
+ mode: "subagent",
207
+ prompt: `{file:${ag.rel}}`,
208
+ permission: { ...ensureObject(next.agent[id]?.permission), edit: "deny" },
209
+ };
210
+ }
211
+
212
+ const out = JSON.stringify(next, null, 2) + "\n";
213
+ if (dryRun) {
214
+ console.log("[dry-run] Would write opencode.json:", opencodeAbs);
215
+ return;
216
+ }
217
+ fs.writeFileSync(opencodeAbs, out, "utf8");
218
+ console.log("Wrote:", opencodeAbs);
219
+ }
220
+
221
+ function extractRepoConfigBlock(md) {
222
+ const match = md.match(/(### Repo Config Block[^\n]*\n)?\s*```yaml\n([\s\S]*?)```/);
223
+ if (!match) return { block: null, rest: md };
224
+ const full = match[0];
225
+ const block = match[2].trim();
226
+ const rest = md.replace(full, "").replace(/\n{3,}/g, "\n\n").trim();
227
+ return { block, rest };
228
+ }
229
+
230
+ function mergeAgentsMd(templateMd, existingMd) {
231
+ const { block: existingBlock, rest: existingRest } = existingMd
232
+ ? extractRepoConfigBlock(existingMd)
233
+ : { block: null, rest: "" };
234
+ const { block: _tplBlock, rest: templateRest } = extractRepoConfigBlock(templateMd);
235
+ let out = templateRest;
236
+ if (existingBlock) {
237
+ const repoSection =
238
+ "### Repo Config Block (Optional)\n\n```yaml\n" + existingBlock + "\n```\n";
239
+ if (!out.includes("### Repo Config Block")) {
240
+ out = out.replace("## Repo Configuration (Optional)", "## Repo Configuration (Optional)\n\n" + repoSection);
241
+ } else {
242
+ out = out.replace(/### Repo Config Block[^\n]*\n\s*```yaml\n[\s\S]*?```/, repoSection);
243
+ }
244
+ }
245
+ return out;
246
+ }
247
+
248
+ function writeAgentsMd(targetRoot, dryRun) {
249
+ const templatePath = path.join(packageRoot, "src", "AGENTS.md");
250
+ const targetPath = path.join(targetRoot, "AGENTS.md");
251
+ const templateMd = fs.readFileSync(templatePath, "utf8");
252
+ const existingMd = fs.existsSync(targetPath) ? fs.readFileSync(targetPath, "utf8") : null;
253
+ const merged = mergeAgentsMd(templateMd, existingMd);
254
+ if (dryRun) {
255
+ console.log("[dry-run] Would write AGENTS.md:", targetPath);
256
+ return merged;
257
+ }
258
+ fs.writeFileSync(targetPath, merged, "utf8");
259
+ console.log("Wrote:", targetPath);
260
+ return merged;
261
+ }
262
+
263
+ const DIRS = [
264
+ "docs/brainstorms",
265
+ "docs/plans",
266
+ "docs/solutions",
267
+ "docs/metrics/daily",
268
+ "docs/metrics/weekly",
269
+ "docs/metrics/monthly",
270
+ "todos",
271
+ ];
272
+
273
+ function ensureDirs(targetRoot, dryRun) {
274
+ for (const d of DIRS) {
275
+ const abs = path.join(targetRoot, d);
276
+ if (dryRun && !fs.existsSync(abs)) console.log("[dry-run] Would create:", d);
277
+ else if (!fs.existsSync(abs)) {
278
+ fs.mkdirSync(abs, { recursive: true });
279
+ console.log("Created:", d);
280
+ }
281
+ }
282
+ }
283
+
284
+ function main() {
285
+ const args = parseArgs(process.argv);
286
+ const targetRoot = realpathSafe(args.root);
287
+
288
+ if (!fs.existsSync(packageAgents)) {
289
+ console.error("Error: package agents dir not found:", packageAgents);
290
+ process.exit(2);
291
+ }
292
+
293
+ const pkgInTarget = path.join(targetRoot, "node_modules", "compound-workflow");
294
+ if (!fs.existsSync(pkgInTarget) && !args.dryRun) {
295
+ console.error("Error: compound-workflow not found in project. Run: npm install compound-workflow");
296
+ process.exit(2);
297
+ }
298
+
299
+ console.log("Target root:", targetRoot);
300
+ console.log("Package root:", packageRoot);
301
+
302
+ writeOpenCodeJson(targetRoot, args.dryRun);
303
+ writeAgentsMd(targetRoot, args.dryRun);
304
+ ensureDirs(targetRoot, args.dryRun);
305
+
306
+ if (!args.noConfig && !args.dryRun && process.stdin.isTTY) {
307
+ console.log("\nRepo Config: edit AGENTS.md to set default_branch, test_command, lint_command, dev_server_url.");
308
+ }
309
+
310
+ console.log("\nDone. Run opencode debug config to verify.");
311
+ }
312
+
313
+ main();
@@ -0,0 +1,103 @@
1
+ #!/usr/bin/env bash
2
+ # LEGACY: Prefer "npm install compound-workflow" + "npx compound-workflow install" in the project.
3
+ # Copy src/.agents and src/AGENTS.md from this compound-workflow repo into a host repo.
4
+ # Does not update opencode.json; run Install (npx compound-workflow install) in the project for that.
5
+ set -e
6
+ CLONE_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
7
+ DRY_RUN=0
8
+ FORCE=0
9
+ TARGET=""
10
+
11
+ usage() {
12
+ cat <<'EOF'
13
+ Usage:
14
+ ./scripts/sync-into-repo.sh [--dry-run] [--force] [target_dir]
15
+
16
+ Copies:
17
+ - src/.agents -> <target_dir>/.agents
18
+ - src/AGENTS.md -> <target_dir>/AGENTS.md (only if missing)
19
+
20
+ Notes:
21
+ - Replaces <target_dir>/.agents (prevents .agents/.agents nesting)
22
+ - Prints absolute paths before writing
23
+ - Refuses non-git targets unless --force
24
+ EOF
25
+ }
26
+
27
+ while [[ $# -gt 0 ]]; do
28
+ case "$1" in
29
+ --dry-run)
30
+ DRY_RUN=1
31
+ shift
32
+ ;;
33
+ --force)
34
+ FORCE=1
35
+ shift
36
+ ;;
37
+ -h|--help)
38
+ usage
39
+ exit 0
40
+ ;;
41
+ *)
42
+ if [[ -z "$TARGET" ]]; then
43
+ TARGET="$1"
44
+ shift
45
+ else
46
+ echo "Error: unexpected argument: $1" >&2
47
+ usage >&2
48
+ exit 1
49
+ fi
50
+ ;;
51
+ esac
52
+ done
53
+
54
+ TARGET="${TARGET:-$(dirname "$CLONE_ROOT")}"
55
+ if [[ ! -d "$CLONE_ROOT/src/.agents" || ! -f "$CLONE_ROOT/src/AGENTS.md" ]]; then
56
+ echo "Error: $CLONE_ROOT is not a compound-workflow clone (missing src/.agents or src/AGENTS.md)" >&2
57
+ exit 1
58
+ fi
59
+ if [[ ! -d "$TARGET" ]]; then
60
+ echo "Error: target is not a directory: $TARGET" >&2
61
+ exit 1
62
+ fi
63
+ TARGET_ABS="$(cd "$TARGET" && pwd)"
64
+ # Host marker validation (escape hatch: --force)
65
+ if [[ "$FORCE" -ne 1 && ! -d "$TARGET_ABS/.git" ]]; then
66
+ echo "Error: target does not look like a git repo (missing .git): $TARGET_ABS" >&2
67
+ echo "Hint: pass --force if you really want to sync into a non-git directory." >&2
68
+ exit 1
69
+ fi
70
+ # Refuse obvious template targets (escape hatch: --force)
71
+ if [[ "$FORCE" -ne 1 && -d "$TARGET_ABS/src/.agents" && -f "$TARGET_ABS/src/AGENTS.md" ]]; then
72
+ echo "Error: target looks like a compound-workflow template repo (has src/.agents + src/AGENTS.md): $TARGET_ABS" >&2
73
+ echo "Refusing to sync into a template repo. Pass --force to override." >&2
74
+ exit 1
75
+ fi
76
+ # Avoid copying into our own src
77
+ if [[ "$TARGET_ABS" == "$(cd "$CLONE_ROOT/src" 2>/dev/null && pwd)" ]] || [[ "$TARGET_ABS" == "$CLONE_ROOT/src" ]]; then
78
+ echo "Error: target must not be the clone's src directory" >&2
79
+ exit 1
80
+ fi
81
+ echo "Resolved target: $TARGET_ABS"
82
+ echo "Planned writes:"
83
+ echo " - $TARGET_ABS/.agents (replace)"
84
+ if [[ ! -f "$TARGET_ABS/AGENTS.md" ]]; then
85
+ echo " - $TARGET_ABS/AGENTS.md (create)"
86
+ else
87
+ echo " - $TARGET_ABS/AGENTS.md (skip; already exists)"
88
+ fi
89
+
90
+ if [[ "$DRY_RUN" -eq 1 ]]; then
91
+ echo "Dry-run: no changes made."
92
+ exit 0
93
+ fi
94
+
95
+ echo "Copying into $TARGET_ABS ..."
96
+ rm -rf "$TARGET_ABS/.agents"
97
+ cp -R "$CLONE_ROOT/src/.agents" "$TARGET_ABS/.agents"
98
+ if [[ ! -f "$TARGET_ABS/AGENTS.md" ]]; then
99
+ cp "$CLONE_ROOT/src/AGENTS.md" "$TARGET_ABS/AGENTS.md"
100
+ else
101
+ echo "AGENTS.md already exists; skipped copy. Run Install (npx compound-workflow install) in the project to merge template with host AGENTS.md."
102
+ fi
103
+ echo "Done. Run Install in the project (npx compound-workflow install) to configure opencode.json and AGENTS.md, or run /install in Cursor."