compound-workflow 1.4.5 → 1.4.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/.claude-plugin/plugin.json +13 -4
- package/.cursor-plugin/plugin.json +20 -1
- package/README.md +20 -14
- package/package.json +4 -3
- package/scripts/generate-platform-artifacts.mjs +165 -0
- package/scripts/install-cli.mjs +160 -411
- package/src/.agents/commands/install.md +18 -30
- package/src/AGENTS.md +1 -1
- package/src/generated/opencode.managed.json +110 -0
- package/scripts/sync-into-repo.sh +0 -103
- package/src/.agents/commands/setup.md +0 -9
- package/src/.agents/commands/sync.md +0 -9
- package/src/.agents/commands/workflow/review-v2.md +0 -148
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "compound-workflow",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Clarify
|
|
5
|
-
"author": {
|
|
6
|
-
|
|
3
|
+
"version": "1.4.6",
|
|
4
|
+
"description": "Clarify -> plan -> execute -> verify -> capture workflow: commands, skills, and agents for Claude Code",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Compound Workflow"
|
|
7
|
+
},
|
|
8
|
+
"keywords": [
|
|
9
|
+
"workflow",
|
|
10
|
+
"planning",
|
|
11
|
+
"agents",
|
|
12
|
+
"skills",
|
|
13
|
+
"commands",
|
|
14
|
+
"claude"
|
|
15
|
+
],
|
|
7
16
|
"license": "MIT",
|
|
8
17
|
"repository": "https://github.com/cjerochim/compound-workflow",
|
|
9
18
|
"commands": "./src/.agents/commands",
|
|
@@ -1 +1,20 @@
|
|
|
1
|
-
{
|
|
1
|
+
{
|
|
2
|
+
"name": "compound-workflow",
|
|
3
|
+
"version": "1.4.6",
|
|
4
|
+
"description": "Clarify -> plan -> execute -> verify -> capture workflow for Cursor",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Compound Workflow"
|
|
7
|
+
},
|
|
8
|
+
"keywords": [
|
|
9
|
+
"workflow",
|
|
10
|
+
"cursor",
|
|
11
|
+
"agents",
|
|
12
|
+
"commands",
|
|
13
|
+
"skills"
|
|
14
|
+
],
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"repository": "https://github.com/cjerochim/compound-workflow",
|
|
17
|
+
"commands": "src/.agents/commands",
|
|
18
|
+
"agents": "src/.agents/agents",
|
|
19
|
+
"skills": "src/.agents/skills"
|
|
20
|
+
}
|
package/README.md
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Compound Workflow is a portable, command-first system for shipping software with less ambiguity and stronger verification.
|
|
4
4
|
It follows a simple cycle: **clarify -> plan -> execute -> verify -> capture**.
|
|
5
|
+
|
|
5
6
|
Use it when you want repeatable delivery without ad-hoc process drift.
|
|
6
7
|
|
|
7
8
|
Inspired by [Compound Engineering](https://every.to/guides/compound-engineering) (Every).
|
|
@@ -27,14 +28,19 @@ flowchart LR
|
|
|
27
28
|
npm install compound-workflow
|
|
28
29
|
```
|
|
29
30
|
|
|
30
|
-
`npm install` adds the package and automatically configures your repo (`AGENTS.md`, required directories, and
|
|
31
|
+
`npm install` adds the package and automatically configures your repo (`AGENTS.md`, required directories, and native OpenCode wiring).
|
|
31
32
|
If your package manager skips lifecycle scripts, run `npx compound-workflow install` manually.
|
|
32
33
|
|
|
33
34
|
Install configures:
|
|
34
35
|
|
|
35
36
|
- Workflow template content in `AGENTS.md`
|
|
36
37
|
- Standard workspace directories for plans/todos/docs
|
|
37
|
-
-
|
|
38
|
+
- `opencode.json` managed entries that reference `node_modules/compound-workflow/src/.agents/*`
|
|
39
|
+
|
|
40
|
+
## Breaking Change (2.0.0)
|
|
41
|
+
|
|
42
|
+
2.0.0 removes all legacy compatibility pathways (`/setup`, `/sync`, runtime mirror copies, and Cursor sync fallbacks).
|
|
43
|
+
See migration notes in [docs/migrations/2026-03-03-v2-native-cutover.md](docs/migrations/2026-03-03-v2-native-cutover.md).
|
|
38
44
|
|
|
39
45
|
## Critical Path
|
|
40
46
|
|
|
@@ -55,18 +61,18 @@ Optional:
|
|
|
55
61
|
|
|
56
62
|
Core flow: `/workflow:brainstorm` -> `/workflow:plan` -> `/workflow:work` -> `/workflow:review` -> `/workflow:compound` -> `/metrics` (optional `/assess` for rollups).
|
|
57
63
|
|
|
58
|
-
| Command
|
|
59
|
-
|
|
60
|
-
| `/install`
|
|
61
|
-
| `/workflow:brainstorm` | Clarify what to build through structured discussion
|
|
62
|
-
| `/workflow:plan`
|
|
63
|
-
| `/workflow:triage`
|
|
64
|
-
| `/workflow:work`
|
|
65
|
-
| `/workflow:review`
|
|
66
|
-
| `/workflow:compound`
|
|
67
|
-
| `/metrics`
|
|
68
|
-
| `/assess`
|
|
69
|
-
| `/test-browser`
|
|
64
|
+
| Command | Purpose | Related skills | Related agents |
|
|
65
|
+
| ---------------------- | ------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
66
|
+
| `/install` | Configure workflow files and runtime wiring in the repo | install CLI (no workflow skill routing) | none |
|
|
67
|
+
| `/workflow:brainstorm` | Clarify what to build through structured discussion | `brainstorming` (primary), `document-review` (optional refinement) | `repo-research-analyst` |
|
|
68
|
+
| `/workflow:plan` | Convert intent into an executable plan with fidelity/confidence | state-orchestration skill when needed (for example `xstate-actor-orchestration`) | `repo-research-analyst`, `learnings-researcher`, `best-practices-researcher`, `framework-docs-researcher`, `git-history-analyzer`, `spec-flow-analyzer`, `planning-technical-reviewer` |
|
|
69
|
+
| `/workflow:triage` | Manual queue curation for complex/multi-item backlogs (optional; `/workflow:work` runs triage automatically) | `file-todos` | none |
|
|
70
|
+
| `/workflow:work` | Execute plan/todos with quality gates and validation evidence | `git-worktree`, `file-todos`, `standards`, state-orchestration skill when needed | `repo-research-analyst`, `learnings-researcher`, `best-practices-researcher`, `framework-docs-researcher`, `git-history-analyzer` |
|
|
71
|
+
| `/workflow:review` | Perform independent quality review before completion | `git-worktree` (for non-current targets), `standards` | `learnings-researcher`, `lint`, `bug-reproduction-validator`, `git-history-analyzer`, `framework-docs-researcher`, `agent-native-reviewer` |
|
|
72
|
+
| `/workflow:compound` | Capture reusable implementation learnings in `docs/solutions/` | `compound-docs` (primary), `document-review` (optional) | `learnings-researcher`, `best-practices-researcher`, `framework-docs-researcher` |
|
|
73
|
+
| `/metrics` | Log session outcomes and improvement actions | `process-metrics`, `file-todos` (optional for follow-ups) | none |
|
|
74
|
+
| `/assess` | Aggregate metrics trends and propose process improvements | `file-todos` (for approved follow-up actions) | none |
|
|
75
|
+
| `/test-browser` | Validate affected routes with browser-level checks | `agent-browser`, `git-worktree` (optional branch isolation) | none |
|
|
70
76
|
|
|
71
77
|
Canonical command docs: [src/.agents/commands/](src/.agents/commands/)
|
|
72
78
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "compound-workflow",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.7",
|
|
4
4
|
"description": "Clarify → plan → execute → verify → capture. One Install action for Cursor, Claude, and OpenCode.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -14,11 +14,12 @@
|
|
|
14
14
|
"src",
|
|
15
15
|
"scripts",
|
|
16
16
|
".cursor-plugin",
|
|
17
|
-
".claude-plugin"
|
|
18
|
-
"skills"
|
|
17
|
+
".claude-plugin"
|
|
19
18
|
],
|
|
20
19
|
"scripts": {
|
|
21
20
|
"postinstall": "node scripts/postinstall.mjs",
|
|
21
|
+
"generate:artifacts": "node scripts/generate-platform-artifacts.mjs",
|
|
22
|
+
"check:artifacts": "node scripts/generate-platform-artifacts.mjs --check",
|
|
22
23
|
"check:pack-readme": "node scripts/check-pack-readme.mjs",
|
|
23
24
|
"test:install": "node --test tests/install-cli.test.mjs"
|
|
24
25
|
},
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
|
|
6
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const repoRoot = path.resolve(__dirname, "..");
|
|
8
|
+
const agentsRoot = path.join(repoRoot, "src", ".agents");
|
|
9
|
+
|
|
10
|
+
function walkFiles(dirAbs, predicate) {
|
|
11
|
+
const out = [];
|
|
12
|
+
const stack = [dirAbs];
|
|
13
|
+
while (stack.length) {
|
|
14
|
+
const cur = stack.pop();
|
|
15
|
+
let entries;
|
|
16
|
+
try {
|
|
17
|
+
entries = fs.readdirSync(cur, { withFileTypes: true });
|
|
18
|
+
} catch {
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
for (const e of entries) {
|
|
22
|
+
const p = path.join(cur, e.name);
|
|
23
|
+
if (e.isDirectory()) stack.push(p);
|
|
24
|
+
else if (e.isFile() && predicate(p)) out.push(p);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
out.sort();
|
|
28
|
+
return out;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function parseFrontmatter(md) {
|
|
32
|
+
if (!md.startsWith("---\n") && !md.startsWith("---\r\n")) return {};
|
|
33
|
+
const end = md.indexOf("\n---", 4);
|
|
34
|
+
if (end === -1) return {};
|
|
35
|
+
const block = md.slice(4, end + 1);
|
|
36
|
+
const out = {};
|
|
37
|
+
for (const line of block.split(/\r?\n/)) {
|
|
38
|
+
const match = line.match(/^([A-Za-z0-9_-]+):\s*(.*)\s*$/);
|
|
39
|
+
if (!match) continue;
|
|
40
|
+
out[match[1]] = (match[2] ?? "").replace(/^"(.*)"$/, "$1").replace(/^'(.*)'$/, "$1");
|
|
41
|
+
}
|
|
42
|
+
return out;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function discoverCommands() {
|
|
46
|
+
const commandsDir = path.join(agentsRoot, "commands");
|
|
47
|
+
const files = walkFiles(commandsDir, (p) => p.endsWith(".md"));
|
|
48
|
+
const commands = [];
|
|
49
|
+
|
|
50
|
+
for (const fileAbs of files) {
|
|
51
|
+
const relWithin = path.relative(commandsDir, fileAbs).replaceAll(path.sep, "/");
|
|
52
|
+
const frontmatter = parseFrontmatter(fs.readFileSync(fileAbs, "utf8"));
|
|
53
|
+
const id = (frontmatter.invocation || frontmatter.name || path.basename(fileAbs, ".md")).trim();
|
|
54
|
+
if (!id) continue;
|
|
55
|
+
commands.push({
|
|
56
|
+
id,
|
|
57
|
+
description: (frontmatter.description || id).trim(),
|
|
58
|
+
rel: relWithin,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return commands.sort((a, b) => a.id.localeCompare(b.id));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function discoverAgents() {
|
|
66
|
+
const agentDir = path.join(agentsRoot, "agents");
|
|
67
|
+
const files = walkFiles(agentDir, (p) => p.endsWith(".md"));
|
|
68
|
+
const agents = [];
|
|
69
|
+
|
|
70
|
+
for (const fileAbs of files) {
|
|
71
|
+
const relWithin = path.relative(agentDir, fileAbs).replaceAll(path.sep, "/");
|
|
72
|
+
const frontmatter = parseFrontmatter(fs.readFileSync(fileAbs, "utf8"));
|
|
73
|
+
const id = (frontmatter.name || path.basename(fileAbs, ".md")).trim();
|
|
74
|
+
if (!id) continue;
|
|
75
|
+
agents.push({
|
|
76
|
+
id,
|
|
77
|
+
description: (frontmatter.description || id).trim(),
|
|
78
|
+
rel: relWithin,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return agents.sort((a, b) => a.id.localeCompare(b.id));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function normalizeRepoUrl(repoValue) {
|
|
86
|
+
const raw = typeof repoValue === "string" ? repoValue : repoValue?.url;
|
|
87
|
+
if (typeof raw !== "string" || raw.trim().length === 0) return "";
|
|
88
|
+
return raw.replace(/^git\+/, "").replace(/\.git$/, "");
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function writeJson(absPath, value, checkOnly, changed) {
|
|
92
|
+
const next = JSON.stringify(value, null, 2) + "\n";
|
|
93
|
+
let prev = null;
|
|
94
|
+
if (fs.existsSync(absPath)) prev = fs.readFileSync(absPath, "utf8");
|
|
95
|
+
|
|
96
|
+
if (prev !== next) {
|
|
97
|
+
changed.push(absPath);
|
|
98
|
+
if (!checkOnly) {
|
|
99
|
+
fs.mkdirSync(path.dirname(absPath), { recursive: true });
|
|
100
|
+
fs.writeFileSync(absPath, next, "utf8");
|
|
101
|
+
console.log("Wrote:", path.relative(repoRoot, absPath));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function main() {
|
|
107
|
+
const checkOnly = process.argv.includes("--check");
|
|
108
|
+
|
|
109
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(repoRoot, "package.json"), "utf8"));
|
|
110
|
+
const repositoryUrl = normalizeRepoUrl(pkg.repository);
|
|
111
|
+
const commands = discoverCommands();
|
|
112
|
+
const agents = discoverAgents();
|
|
113
|
+
const changed = [];
|
|
114
|
+
|
|
115
|
+
const claudePlugin = {
|
|
116
|
+
name: pkg.name,
|
|
117
|
+
version: pkg.version,
|
|
118
|
+
description: "Clarify -> plan -> execute -> verify -> capture workflow: commands, skills, and agents for Claude Code",
|
|
119
|
+
author: { name: "Compound Workflow" },
|
|
120
|
+
keywords: ["workflow", "planning", "agents", "skills", "commands", "claude"],
|
|
121
|
+
license: pkg.license,
|
|
122
|
+
repository: repositoryUrl,
|
|
123
|
+
commands: "./src/.agents/commands",
|
|
124
|
+
agents: "./src/.agents/agents",
|
|
125
|
+
skills: "./src/.agents/skills",
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const cursorPlugin = {
|
|
129
|
+
name: pkg.name,
|
|
130
|
+
version: pkg.version,
|
|
131
|
+
description: "Clarify -> plan -> execute -> verify -> capture workflow for Cursor",
|
|
132
|
+
author: { name: "Compound Workflow" },
|
|
133
|
+
keywords: ["workflow", "cursor", "agents", "commands", "skills"],
|
|
134
|
+
license: pkg.license,
|
|
135
|
+
repository: repositoryUrl,
|
|
136
|
+
commands: "src/.agents/commands",
|
|
137
|
+
agents: "src/.agents/agents",
|
|
138
|
+
skills: "src/.agents/skills",
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
const openCodeManaged = {
|
|
142
|
+
$schema: "https://opencode.ai/config.json",
|
|
143
|
+
skillsPath: "node_modules/compound-workflow/src/.agents/skills",
|
|
144
|
+
commandRoot: "node_modules/compound-workflow/src/.agents/commands",
|
|
145
|
+
agentRoot: "node_modules/compound-workflow/src/.agents/agents",
|
|
146
|
+
commands,
|
|
147
|
+
agents,
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
writeJson(path.join(repoRoot, ".claude-plugin", "plugin.json"), claudePlugin, checkOnly, changed);
|
|
151
|
+
writeJson(path.join(repoRoot, ".cursor-plugin", "plugin.json"), cursorPlugin, checkOnly, changed);
|
|
152
|
+
writeJson(path.join(repoRoot, "src", "generated", "opencode.managed.json"), openCodeManaged, checkOnly, changed);
|
|
153
|
+
|
|
154
|
+
if (checkOnly && changed.length) {
|
|
155
|
+
console.error("Generated artifacts are stale:");
|
|
156
|
+
for (const abs of changed) console.error("-", path.relative(repoRoot, abs));
|
|
157
|
+
process.exit(1);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (!changed.length) {
|
|
161
|
+
console.log(checkOnly ? "Generated artifacts are up-to-date." : "No artifact updates required.");
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
main();
|