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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "compound-workflow",
3
- "version": "1.4.6",
3
+ "version": "1.6.0",
4
4
  "description": "Clarify -> plan -> execute -> verify -> capture workflow: commands, skills, and agents for Claude Code",
5
5
  "author": {
6
6
  "name": "Compound Workflow"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "compound-workflow",
3
- "version": "1.4.6",
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.4.7",
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
- console.log("Package guard passed: root README is present in npm pack output.");
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 = {
@@ -137,19 +137,17 @@ function readGeneratedManifest() {
137
137
  return manifest;
138
138
  }
139
139
 
140
- const GENERATED_MANIFEST = readGeneratedManifest();
141
- const PACKAGE_COMMAND_ROOT = GENERATED_MANIFEST.commandRoot;
142
- const PACKAGE_AGENT_ROOT = GENERATED_MANIFEST.agentRoot;
143
- const PACKAGE_SKILL_ROOT = GENERATED_MANIFEST.skillsPath;
144
-
145
- const LEGACY_MANAGED_COMMAND_ROOTS = [
146
- ".agents/compound-workflow/commands",
147
- PACKAGE_COMMAND_ROOT,
148
- ];
149
- const LEGACY_MANAGED_AGENT_ROOTS = [
150
- ".agents/compound-workflow/agents",
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 LEGACY_MANAGED_COMMAND_ROOTS.some((root) => commandPath.startsWith(`${root}/`));
168
+ return getLegacyCommandRoots().some((root) => commandPath.startsWith(`${root}/`));
171
169
  }
172
170
 
173
171
  function isManagedAgentPath(agentPath) {
174
- return LEGACY_MANAGED_AGENT_ROOTS.some((root) => agentPath.startsWith(`${root}/`));
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(PACKAGE_SKILL_ROOT)) {
189
- next.skills.paths.unshift(PACKAGE_SKILL_ROOT);
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@${PACKAGE_COMMAND_ROOT}/${command.rel}\nArguments: $ARGUMENTS\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) => `${PACKAGE_COMMAND_ROOT}/${command.rel}`)
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:${PACKAGE_AGENT_ROOT}/${agent.rel}}`,
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) => `${PACKAGE_AGENT_ROOT}/${agent.rel}`)
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);
@@ -38,7 +38,10 @@ function shouldSkip(targetRoot) {
38
38
  }
39
39
 
40
40
  function run() {
41
- const targetRoot = process.env.INIT_CWD ? path.resolve(process.env.INIT_CWD) : "";
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
- - If `planning-technical-reviewer` exists under `.agents/agents/review/`, run it on the plan first.
27
- - Treat its blocking findings as pre-build blockers.
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 step:
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)",