compound-workflow 1.4.7 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/.cursor-plugin/plugin.json +4 -4
- package/package.json +3 -1
- package/scripts/check-pack-readme.mjs +16 -1
- package/scripts/check-version-parity.mjs +30 -0
- package/scripts/generate-platform-artifacts.mjs +3 -3
- package/scripts/install-cli.mjs +69 -31
- package/scripts/postinstall.mjs +4 -1
- package/src/.agents/commands/workflow/plan.md +2 -0
- package/src/.agents/commands/workflow/tech-review.md +28 -0
- package/src/.agents/skills/technical-review/SKILL.md +2 -3
- package/src/AGENTS.md +5 -4
- package/src/generated/opencode.managed.json +5 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "compound-workflow",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "Clarify -> plan -> execute -> verify -> capture workflow for Cursor",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Compound Workflow"
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
],
|
|
15
15
|
"license": "MIT",
|
|
16
16
|
"repository": "https://github.com/cjerochim/compound-workflow",
|
|
17
|
-
"commands": "src/.agents/commands",
|
|
18
|
-
"agents": "src/.agents/agents",
|
|
19
|
-
"skills": "src/.agents/skills"
|
|
17
|
+
"commands": "./src/.agents/commands",
|
|
18
|
+
"agents": "./src/.agents/agents",
|
|
19
|
+
"skills": "./src/.agents/skills"
|
|
20
20
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "compound-workflow",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "Clarify → plan → execute → verify → capture. One Install action for Cursor, Claude, and OpenCode.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"postinstall": "node scripts/postinstall.mjs",
|
|
21
21
|
"generate:artifacts": "node scripts/generate-platform-artifacts.mjs",
|
|
22
22
|
"check:artifacts": "node scripts/generate-platform-artifacts.mjs --check",
|
|
23
|
+
"check:version-parity": "node scripts/check-version-parity.mjs",
|
|
23
24
|
"check:pack-readme": "node scripts/check-pack-readme.mjs",
|
|
24
25
|
"test:install": "node --test tests/install-cli.test.mjs"
|
|
25
26
|
},
|
|
@@ -27,6 +28,7 @@
|
|
|
27
28
|
"node": ">=18"
|
|
28
29
|
},
|
|
29
30
|
"devDependencies": {
|
|
31
|
+
"@semantic-release/exec": "^6.0.0",
|
|
30
32
|
"@semantic-release/git": "^10.0.1",
|
|
31
33
|
"@semantic-release/npm": "^13.1.4",
|
|
32
34
|
"semantic-release": "^25.0.3"
|
|
@@ -31,6 +31,9 @@ try {
|
|
|
31
31
|
|
|
32
32
|
const files = Array.isArray(report) && report[0]?.files ? report[0].files : [];
|
|
33
33
|
const hasRootReadme = files.some((file) => /^readme(?:\.[^/]+)?$/i.test(file.path));
|
|
34
|
+
const hasGeneratedManifest = files.some((file) => file.path === "src/generated/opencode.managed.json");
|
|
35
|
+
const hasCursorPlugin = files.some((file) => file.path === ".cursor-plugin/plugin.json");
|
|
36
|
+
const hasClaudePlugin = files.some((file) => file.path === ".claude-plugin/plugin.json");
|
|
34
37
|
|
|
35
38
|
if (!hasRootReadme) {
|
|
36
39
|
console.error("Package guard failed: root README is missing from the packed tarball.");
|
|
@@ -38,4 +41,16 @@ if (!hasRootReadme) {
|
|
|
38
41
|
process.exit(1);
|
|
39
42
|
}
|
|
40
43
|
|
|
41
|
-
|
|
44
|
+
if (!hasGeneratedManifest) {
|
|
45
|
+
console.error("Package guard failed: src/generated/opencode.managed.json is missing from the packed tarball.");
|
|
46
|
+
console.error("Ensure 'src' is in package.json 'files' and the file is committed or generated before publish.");
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (!hasCursorPlugin || !hasClaudePlugin) {
|
|
51
|
+
console.error("Package guard failed: .cursor-plugin/plugin.json and .claude-plugin/plugin.json must be in the packed tarball.");
|
|
52
|
+
console.error("Ensure '.cursor-plugin' and '.claude-plugin' are in package.json 'files'.");
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
console.log("Package guard passed: root README, opencode.managed.json, and plugin manifests are present in npm pack output.");
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Exit 0 if package.json version matches .cursor-plugin/plugin.json and .claude-plugin/plugin.json.
|
|
4
|
+
* Used in CI to validate release artifact sync.
|
|
5
|
+
*/
|
|
6
|
+
import fs from "node:fs";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
import { fileURLToPath } from "node:url";
|
|
9
|
+
|
|
10
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
const root = path.resolve(__dirname, "..");
|
|
12
|
+
|
|
13
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(root, "package.json"), "utf8"));
|
|
14
|
+
const cursorPlugin = JSON.parse(
|
|
15
|
+
fs.readFileSync(path.join(root, ".cursor-plugin", "plugin.json"), "utf8")
|
|
16
|
+
);
|
|
17
|
+
const claudePlugin = JSON.parse(
|
|
18
|
+
fs.readFileSync(path.join(root, ".claude-plugin", "plugin.json"), "utf8")
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
const expected = pkg.version;
|
|
22
|
+
if (cursorPlugin.version !== expected || claudePlugin.version !== expected) {
|
|
23
|
+
console.error(
|
|
24
|
+
"Version mismatch: package.json=%s, .cursor-plugin/plugin.json=%s, .claude-plugin/plugin.json=%s",
|
|
25
|
+
expected,
|
|
26
|
+
cursorPlugin.version,
|
|
27
|
+
claudePlugin.version
|
|
28
|
+
);
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
@@ -133,9 +133,9 @@ function main() {
|
|
|
133
133
|
keywords: ["workflow", "cursor", "agents", "commands", "skills"],
|
|
134
134
|
license: pkg.license,
|
|
135
135
|
repository: repositoryUrl,
|
|
136
|
-
commands: "src/.agents/commands",
|
|
137
|
-
agents: "src/.agents/agents",
|
|
138
|
-
skills: "src/.agents/skills",
|
|
136
|
+
commands: "./src/.agents/commands",
|
|
137
|
+
agents: "./src/.agents/agents",
|
|
138
|
+
skills: "./src/.agents/skills",
|
|
139
139
|
};
|
|
140
140
|
|
|
141
141
|
const openCodeManaged = {
|
package/scripts/install-cli.mjs
CHANGED
|
@@ -137,19 +137,17 @@ function readGeneratedManifest() {
|
|
|
137
137
|
return manifest;
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
".agents/compound-workflow/commands",
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
PACKAGE_AGENT_ROOT,
|
|
152
|
-
];
|
|
140
|
+
let GENERATED_MANIFEST;
|
|
141
|
+
let PACKAGE_COMMAND_ROOT;
|
|
142
|
+
let PACKAGE_AGENT_ROOT;
|
|
143
|
+
let PACKAGE_SKILL_ROOT;
|
|
144
|
+
|
|
145
|
+
function getLegacyCommandRoots() {
|
|
146
|
+
return [".agents/compound-workflow/commands", PACKAGE_COMMAND_ROOT, "src/.agents/commands"];
|
|
147
|
+
}
|
|
148
|
+
function getLegacyAgentRoots() {
|
|
149
|
+
return [".agents/compound-workflow/agents", PACKAGE_AGENT_ROOT, "src/.agents/agents"];
|
|
150
|
+
}
|
|
153
151
|
|
|
154
152
|
function managedCommandPath(entry) {
|
|
155
153
|
const template = entry?.template;
|
|
@@ -167,14 +165,18 @@ function managedAgentPath(entry) {
|
|
|
167
165
|
}
|
|
168
166
|
|
|
169
167
|
function isManagedCommandPath(commandPath) {
|
|
170
|
-
return
|
|
168
|
+
return getLegacyCommandRoots().some((root) => commandPath.startsWith(`${root}/`));
|
|
171
169
|
}
|
|
172
170
|
|
|
173
171
|
function isManagedAgentPath(agentPath) {
|
|
174
|
-
return
|
|
172
|
+
return getLegacyAgentRoots().some((root) => agentPath.startsWith(`${root}/`));
|
|
175
173
|
}
|
|
176
174
|
|
|
177
|
-
function writeOpenCodeJson(targetRoot, dryRun) {
|
|
175
|
+
function writeOpenCodeJson(targetRoot, dryRun, isSelfInstall) {
|
|
176
|
+
const commandRoot = isSelfInstall ? "src/.agents/commands" : PACKAGE_COMMAND_ROOT;
|
|
177
|
+
const agentRoot = isSelfInstall ? "src/.agents/agents" : PACKAGE_AGENT_ROOT;
|
|
178
|
+
const skillRoot = isSelfInstall ? "src/.agents/skills" : PACKAGE_SKILL_ROOT;
|
|
179
|
+
|
|
178
180
|
const opencodeAbs = path.join(targetRoot, "opencode.json");
|
|
179
181
|
const existing = readJsonMaybe(opencodeAbs) ?? {};
|
|
180
182
|
const next = structuredClone(existing);
|
|
@@ -183,10 +185,9 @@ function writeOpenCodeJson(targetRoot, dryRun) {
|
|
|
183
185
|
next.skills = ensureObject(next.skills);
|
|
184
186
|
next.skills.paths = Array.isArray(next.skills.paths) ? next.skills.paths : [];
|
|
185
187
|
|
|
186
|
-
// Full cutover: remove old symlink-based managed path and use direct package skills path.
|
|
187
188
|
next.skills.paths = next.skills.paths.filter((p) => p !== ".agents/compound-workflow-skills");
|
|
188
|
-
if (!next.skills.paths.includes(
|
|
189
|
-
next.skills.paths.unshift(
|
|
189
|
+
if (!next.skills.paths.includes(skillRoot)) {
|
|
190
|
+
next.skills.paths.unshift(skillRoot);
|
|
190
191
|
}
|
|
191
192
|
|
|
192
193
|
next.command = ensureObject(next.command);
|
|
@@ -195,19 +196,17 @@ function writeOpenCodeJson(targetRoot, dryRun) {
|
|
|
195
196
|
const commands = GENERATED_MANIFEST.commands;
|
|
196
197
|
const agents = GENERATED_MANIFEST.agents;
|
|
197
198
|
|
|
198
|
-
// Upsert managed commands.
|
|
199
199
|
for (const command of commands) {
|
|
200
200
|
next.command[command.id] = {
|
|
201
201
|
...ensureObject(next.command[command.id]),
|
|
202
202
|
description: command.description,
|
|
203
203
|
agent: "build",
|
|
204
|
-
template: `@AGENTS.md\n@${
|
|
204
|
+
template: `@AGENTS.md\n@${commandRoot}/${command.rel}\nArguments: $ARGUMENTS\n`,
|
|
205
205
|
};
|
|
206
206
|
}
|
|
207
207
|
|
|
208
|
-
// Remove stale managed commands.
|
|
209
208
|
const managedCommandTargets = new Set(
|
|
210
|
-
commands.map((command) => `${
|
|
209
|
+
commands.map((command) => `${commandRoot}/${command.rel}`)
|
|
211
210
|
);
|
|
212
211
|
for (const [id, entry] of Object.entries(next.command)) {
|
|
213
212
|
const commandPath = managedCommandPath(entry);
|
|
@@ -215,20 +214,18 @@ function writeOpenCodeJson(targetRoot, dryRun) {
|
|
|
215
214
|
if (!managedCommandTargets.has(commandPath)) delete next.command[id];
|
|
216
215
|
}
|
|
217
216
|
|
|
218
|
-
// Upsert managed agents.
|
|
219
217
|
for (const agent of agents) {
|
|
220
218
|
next.agent[agent.id] = {
|
|
221
219
|
...ensureObject(next.agent[agent.id]),
|
|
222
220
|
description: agent.description,
|
|
223
221
|
mode: "subagent",
|
|
224
|
-
prompt: `{file:${
|
|
222
|
+
prompt: `{file:${agentRoot}/${agent.rel}}`,
|
|
225
223
|
permission: { ...ensureObject(next.agent[agent.id]?.permission), edit: "deny" },
|
|
226
224
|
};
|
|
227
225
|
}
|
|
228
226
|
|
|
229
|
-
// Remove stale managed agents.
|
|
230
227
|
const managedAgentTargets = new Set(
|
|
231
|
-
agents.map((agent) => `${
|
|
228
|
+
agents.map((agent) => `${agentRoot}/${agent.rel}`)
|
|
232
229
|
);
|
|
233
230
|
for (const [id, entry] of Object.entries(next.agent)) {
|
|
234
231
|
const agentPath = managedAgentPath(entry);
|
|
@@ -316,16 +313,45 @@ function ensureDirs(targetRoot, dryRun) {
|
|
|
316
313
|
}
|
|
317
314
|
}
|
|
318
315
|
|
|
316
|
+
function writePluginManifests(targetRoot, dryRun, isSelfInstall) {
|
|
317
|
+
const pathsBase = isSelfInstall ? "src/.agents" : "node_modules/compound-workflow/src/.agents";
|
|
318
|
+
const pathOverrides = {
|
|
319
|
+
commands: `${pathsBase}/commands`,
|
|
320
|
+
agents: `${pathsBase}/agents`,
|
|
321
|
+
skills: `${pathsBase}/skills`,
|
|
322
|
+
};
|
|
323
|
+
const cursorSrc = path.join(PACKAGE_ROOT, ".cursor-plugin", "plugin.json");
|
|
324
|
+
const claudeSrc = path.join(PACKAGE_ROOT, ".claude-plugin", "plugin.json");
|
|
325
|
+
const cursorManifest = readJsonMaybe(cursorSrc);
|
|
326
|
+
const claudeManifest = readJsonMaybe(claudeSrc);
|
|
327
|
+
if (!cursorManifest || !claudeManifest) return;
|
|
328
|
+
|
|
329
|
+
const cursorOut = { ...cursorManifest, ...pathOverrides };
|
|
330
|
+
const claudeOut = { ...claudeManifest, ...pathOverrides };
|
|
331
|
+
const cursorDir = path.join(targetRoot, ".cursor-plugin");
|
|
332
|
+
const claudeDir = path.join(targetRoot, ".claude-plugin");
|
|
333
|
+
|
|
334
|
+
if (dryRun) {
|
|
335
|
+
console.log("[dry-run] Would write .cursor-plugin/plugin.json and .claude-plugin/plugin.json");
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
fs.mkdirSync(cursorDir, { recursive: true });
|
|
339
|
+
fs.mkdirSync(claudeDir, { recursive: true });
|
|
340
|
+
fs.writeFileSync(path.join(cursorDir, "plugin.json"), JSON.stringify(cursorOut, null, 2) + "\n", "utf8");
|
|
341
|
+
fs.writeFileSync(path.join(claudeDir, "plugin.json"), JSON.stringify(claudeOut, null, 2) + "\n", "utf8");
|
|
342
|
+
console.log("Wrote: .cursor-plugin/plugin.json, .claude-plugin/plugin.json");
|
|
343
|
+
}
|
|
344
|
+
|
|
319
345
|
function reportOpenCodeIntegration(targetRoot, dryRun) {
|
|
320
346
|
if (dryRun) {
|
|
321
|
-
console.log("[dry-run] OpenCode integration check skipped.");
|
|
347
|
+
console.log("[dry-run] OpenCode integration check skipped (state would be updated by install).");
|
|
322
348
|
return;
|
|
323
349
|
}
|
|
324
350
|
|
|
325
351
|
const opencodeAbs = path.join(targetRoot, "opencode.json");
|
|
326
352
|
const opencode = readJsonMaybe(opencodeAbs) ?? {};
|
|
327
353
|
const skillPaths = Array.isArray(opencode?.skills?.paths) ? opencode.skills.paths : [];
|
|
328
|
-
const hasSkillPath = skillPaths.includes(PACKAGE_SKILL_ROOT);
|
|
354
|
+
const hasSkillPath = skillPaths.includes(PACKAGE_SKILL_ROOT) || skillPaths.includes("src/.agents/skills");
|
|
329
355
|
|
|
330
356
|
console.log(
|
|
331
357
|
"OpenCode integration:",
|
|
@@ -338,13 +364,24 @@ function main() {
|
|
|
338
364
|
const args = parseArgs(process.argv);
|
|
339
365
|
const targetRoot = realpathSafe(args.root);
|
|
340
366
|
|
|
367
|
+
try {
|
|
368
|
+
GENERATED_MANIFEST = readGeneratedManifest();
|
|
369
|
+
PACKAGE_COMMAND_ROOT = GENERATED_MANIFEST.commandRoot;
|
|
370
|
+
PACKAGE_AGENT_ROOT = GENERATED_MANIFEST.agentRoot;
|
|
371
|
+
PACKAGE_SKILL_ROOT = GENERATED_MANIFEST.skillsPath;
|
|
372
|
+
} catch (err) {
|
|
373
|
+
console.error("Error: OpenCode manifest not found. Run 'npm run generate:artifacts' in the package or reinstall compound-workflow.");
|
|
374
|
+
process.exit(2);
|
|
375
|
+
}
|
|
376
|
+
|
|
341
377
|
if (!fs.existsSync(PACKAGE_AGENTS_ROOT)) {
|
|
342
378
|
console.error("Error: package agents dir not found:", PACKAGE_AGENTS_ROOT);
|
|
343
379
|
process.exit(2);
|
|
344
380
|
}
|
|
345
381
|
|
|
382
|
+
const isSelfInstall = realpathSafe(targetRoot) === realpathSafe(PACKAGE_ROOT);
|
|
346
383
|
const pkgInTarget = path.join(targetRoot, "node_modules", "compound-workflow");
|
|
347
|
-
if (!fs.existsSync(pkgInTarget) && !args.dryRun) {
|
|
384
|
+
if (!isSelfInstall && !fs.existsSync(pkgInTarget) && !args.dryRun) {
|
|
348
385
|
console.error("Error: compound-workflow not found in project. Run: npm install compound-workflow");
|
|
349
386
|
process.exit(2);
|
|
350
387
|
}
|
|
@@ -353,7 +390,8 @@ function main() {
|
|
|
353
390
|
console.log("Package root:", PACKAGE_ROOT);
|
|
354
391
|
console.log("OpenCode CLI detected:", hasCommand("opencode") ? "yes" : "no");
|
|
355
392
|
|
|
356
|
-
writeOpenCodeJson(targetRoot, args.dryRun);
|
|
393
|
+
writeOpenCodeJson(targetRoot, args.dryRun, isSelfInstall);
|
|
394
|
+
writePluginManifests(targetRoot, args.dryRun, isSelfInstall);
|
|
357
395
|
reportOpenCodeIntegration(targetRoot, args.dryRun);
|
|
358
396
|
writeAgentsMd(targetRoot, args.dryRun);
|
|
359
397
|
ensureDirs(targetRoot, args.dryRun);
|
package/scripts/postinstall.mjs
CHANGED
|
@@ -38,7 +38,10 @@ function shouldSkip(targetRoot) {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
function run() {
|
|
41
|
-
|
|
41
|
+
let targetRoot = process.env.INIT_CWD ? path.resolve(process.env.INIT_CWD) : process.cwd();
|
|
42
|
+
if (!process.env.INIT_CWD) {
|
|
43
|
+
console.log("[compound-workflow] INIT_CWD not set; using process.cwd() as project root.");
|
|
44
|
+
}
|
|
42
45
|
const skipReason = shouldSkip(targetRoot);
|
|
43
46
|
if (skipReason) {
|
|
44
47
|
console.log(`[compound-workflow] postinstall skipped (${skipReason})`);
|
|
@@ -833,6 +833,8 @@ Write the complete plan file to `docs/plans/YYYY-MM-DD-<type>-<slug>-plan.md`. T
|
|
|
833
833
|
|
|
834
834
|
Confirm: "Plan written to docs/plans/[filename]"
|
|
835
835
|
|
|
836
|
+
**Auto technical review (when Fidelity is Medium or High):** After writing the plan file, if the declared **Fidelity is Medium or High**, automatically run technical review: run **Task planning-technical-reviewer(plan_path)** when the environment can run the Task, or load the `technical-review` skill so the subagent is used when available. Use the plan path just written. If Fidelity is Low, skip this step; the user can still choose "Technical review" from Post-Generation Options or call `/workflow:tech-review` later.
|
|
837
|
+
|
|
836
838
|
**Non-interactive mode:** When the invocation is non-interactive (e.g., `workflow:plan` run by automation, CI, or with an explicit non-interactive flag/convention), skip AskQuestion calls and do not present Post-Generation Options. For determinism, the repo should define the flag or convention (e.g., in `AGENTS.md` Repo Config Block or a documented env var). Still **declare** Fidelity, Confidence, Solution scope, Spike evaluation, Spikes needed, Research mode, and Open questions in the required announcement format before writing the plan. Use these defaults when user input is unavailable: fidelity = Medium, confidence = Medium, solution_scope = full_remediation, spike evaluation = not-required unless risky-work triggers are present, spikes needed = n/a when spike evaluation is not required, research mode = local + external for Medium/High risk topics else local only. Proceed directly to writing the plan file and then exit or return the plan path as output.
|
|
837
839
|
|
|
838
840
|
**Required in plan frontmatter:** Add these fields to the plan file:
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tech-review
|
|
3
|
+
invocation: workflow:tech-review
|
|
4
|
+
description: Run technical review on a plan (technical correctness before build). Optional plan path or latest in docs/plans/.
|
|
5
|
+
argument-hint: "[optional: plan path]"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# /workflow:tech-review
|
|
9
|
+
|
|
10
|
+
Run technical review on a feature approach or plan document. Checks technical alignment with architecture, code standards, and quality before build. Does not edit the plan; use `document-review` after technical review to apply agreed changes.
|
|
11
|
+
|
|
12
|
+
Contract precedence: if this command conflicts with other workflow docs, follow `docs/principles/workflow-baseline-principles.md`, then `src/AGENTS.md`, then this command.
|
|
13
|
+
|
|
14
|
+
## Inputs
|
|
15
|
+
|
|
16
|
+
- **Plan path (optional):** `$ARGUMENTS` — path to the plan file (e.g. `docs/plans/YYYY-MM-DD-<type>-<slug>-plan.md`).
|
|
17
|
+
- If not provided: use the plan from context, or discover the most recent plan in `docs/plans/` (e.g. by date prefix) or `docs/brainstorms/`.
|
|
18
|
+
|
|
19
|
+
## Execution
|
|
20
|
+
|
|
21
|
+
1. Resolve the plan document (from argument, context, or discovery).
|
|
22
|
+
2. Load the `technical-review` skill and run it on that plan. The skill runs **Task planning-technical-reviewer(plan_path)** when the environment can run the Task, then synthesizes the verdict and findings queue.
|
|
23
|
+
3. After technical review, if the user agrees to changes, recommend loading `document-review` to update the plan, then proceed to build when ready.
|
|
24
|
+
|
|
25
|
+
## Guardrails
|
|
26
|
+
|
|
27
|
+
- Do not modify the plan in this command; technical review is read-only. Apply changes via document-review or user edit.
|
|
28
|
+
- Do not create commits, push branches, or create pull requests.
|
|
@@ -23,9 +23,8 @@ Primary execution model: run an independent planning-phase pass first using `pla
|
|
|
23
23
|
|
|
24
24
|
## Step 1.5: Independent Fresh-Context Pass (Required)
|
|
25
25
|
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
- If the agent is not available, explicitly state: "planning-technical-reviewer unavailable; running direct technical review (degraded bias resistance)".
|
|
26
|
+
- Run **Task planning-technical-reviewer(plan_path)** when the environment can run the Task; treat its output as the independent pass and its blocking findings as pre-build blockers.
|
|
27
|
+
- If the Task cannot be run (e.g. no subagent/mcp_task support), explicitly state: "planning-technical-reviewer unavailable; running direct technical review (degraded bias resistance)" and perform the review in-context (load the planning-technical-reviewer agent doc and execute that review in this conversation), then synthesize the verdict.
|
|
29
28
|
|
|
30
29
|
## Step 1.6: Build Findings Queue (Required)
|
|
31
30
|
|
package/src/AGENTS.md
CHANGED
|
@@ -30,9 +30,10 @@ This `.agents` workspace is portable and command-first.
|
|
|
30
30
|
4. `/workflow:review` -> validate quality
|
|
31
31
|
5. `/workflow:compound` -> capture durable learnings
|
|
32
32
|
|
|
33
|
-
Optional manual
|
|
33
|
+
Optional manual steps:
|
|
34
34
|
|
|
35
35
|
- `/workflow:triage` -> explicitly curate/prioritize backlog items before execution when needed
|
|
36
|
+
- `/workflow:tech-review` -> run technical review on a plan (technical correctness before build); optional plan path
|
|
36
37
|
|
|
37
38
|
Continuous improvement:
|
|
38
39
|
|
|
@@ -43,9 +44,9 @@ Onboarding:
|
|
|
43
44
|
|
|
44
45
|
- `/install` -> one action: writes opencode.json, merges AGENTS.md, creates dirs, preserves Repo Config Block (run `npx compound-workflow install` in the project)
|
|
45
46
|
|
|
46
|
-
This workspace currently implements `brainstorm`, `plan`, `triage`, `work`, `review`, `compound`, and optional QA utilities.
|
|
47
|
+
This workspace currently implements `brainstorm`, `plan`, `triage`, `work`, `review`, `tech-review`, `compound`, and optional QA utilities.
|
|
47
48
|
|
|
48
|
-
Use the canonical command names (`/workflow:plan`, `/workflow:work`, `/workflow:review`, etc.). This template does not ship aliases.
|
|
49
|
+
Use the canonical command names (`/workflow:plan`, `/workflow:work`, `/workflow:review`, `/workflow:tech-review`, etc.). This template does not ship aliases.
|
|
49
50
|
|
|
50
51
|
## Contract Precedence
|
|
51
52
|
|
|
@@ -168,7 +169,7 @@ worktree_bootstrap_notes:
|
|
|
168
169
|
|
|
169
170
|
## Implemented Components (Current Scope)
|
|
170
171
|
|
|
171
|
-
- Commands: `workflow:brainstorm`, `workflow:plan`, `workflow:triage`, `workflow:work`, `workflow:review`, `workflow:compound` (under `.agents/commands/workflow/`), plus `test-browser`, `metrics`, `assess`, `install` (root commands)
|
|
172
|
+
- Commands: `workflow:brainstorm`, `workflow:plan`, `workflow:triage`, `workflow:work`, `workflow:review`, `workflow:tech-review`, `workflow:compound` (under `.agents/commands/workflow/`), plus `test-browser`, `metrics`, `assess`, `install` (root commands)
|
|
172
173
|
- Skills: `brainstorming`, `document-review`, `technical-review`, `compound-docs` (alias: `compound_doc`), `capture-skill`, `file-todos`, `agent-browser`, `git-worktree`, `process-metrics`, `react-ddd-mvc-frontend`, `xstate-actor-orchestration`, `standards`, `pii-protection-prisma`, `financial-workflow-integrity`, `audit-traceability`, `data-foundations`
|
|
173
174
|
- Agents:
|
|
174
175
|
- `repo-research-analyst`
|
|
@@ -44,6 +44,11 @@
|
|
|
44
44
|
"description": "Review a PR/branch/diff with structured findings. Does not implement fixes unless explicitly requested.",
|
|
45
45
|
"rel": "workflow/review.md"
|
|
46
46
|
},
|
|
47
|
+
{
|
|
48
|
+
"id": "workflow:tech-review",
|
|
49
|
+
"description": "Run technical review on a plan (technical correctness before build). Optional plan path or latest in docs/plans/.",
|
|
50
|
+
"rel": "workflow/tech-review.md"
|
|
51
|
+
},
|
|
47
52
|
{
|
|
48
53
|
"id": "workflow:triage",
|
|
49
54
|
"description": "Manual triage command to prioritize todo files into an executable ready queue (priority, dependencies, recommended action)",
|