compound-workflow 1.7.1 → 1.7.3

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.7.1",
3
+ "version": "1.7.3",
4
4
  "description": "Clarify -> plan -> execute -> verify -> capture workflow for Cursor",
5
5
  "author": {
6
6
  "name": "Compound Workflow"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "compound-workflow",
3
- "version": "1.7.1",
3
+ "version": "1.7.3",
4
4
  "description": "Clarify → plan → execute → verify → capture. One Install action for Cursor, Claude, and OpenCode.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -34,7 +34,7 @@ When Cursor is detected (~/.cursor), registers the plugin so skills/commands app
34
34
  --root <dir> Project directory (default: cwd)
35
35
  --dry-run Print planned changes only
36
36
  --no-config Skip Repo Config Block reminder
37
- --no-register-cursor Do not register plugin with Cursor (skip apply to ~/.claude/)
37
+ --no-register-cursor Do not register plugin with Cursor
38
38
  --register-cursor Force registration with Cursor even if ~/.cursor not found
39
39
  `;
40
40
  (exitCode === 0 ? console.log : console.error)(msg.trimStart());
@@ -42,14 +42,13 @@ When Cursor is detected (~/.cursor), registers the plugin so skills/commands app
42
42
  }
43
43
 
44
44
  function parseArgs(argv) {
45
- const out = { root: process.cwd(), dryRun: false, noConfig: false, noRegisterCursor: false, registerCursor: false, verify: false };
45
+ const out = { root: process.cwd(), dryRun: false, noConfig: false, noRegisterCursor: false, registerCursor: false };
46
46
  for (let i = 2; i < argv.length; i++) {
47
47
  const arg = argv[i];
48
48
  if (arg === "--dry-run") out.dryRun = true;
49
49
  else if (arg === "--no-config") out.noConfig = true;
50
50
  else if (arg === "--no-register-cursor") out.noRegisterCursor = true;
51
51
  else if (arg === "--register-cursor") out.registerCursor = true;
52
- else if (arg === "--verify") out.verify = true;
53
52
  else if (arg === "--root") {
54
53
  const value = argv[i + 1];
55
54
  if (!value) usage(1);
@@ -342,7 +341,8 @@ function writePluginManifests(targetRoot, dryRun, isSelfInstall) {
342
341
  const claudeManifest = readJsonMaybe(claudeSrc);
343
342
  if (!cursorManifest || !claudeManifest) return;
344
343
 
345
- // Cursor supports full manifest with commands/agents/skills path overrides.
344
+ // All Cursor paths point directly at the package source — no symlink indirection.
345
+ // This ensures frontmatter (descriptions) is parsed correctly by Cursor for all components.
346
346
  const cursorOut = {
347
347
  ...cursorManifest,
348
348
  commands: `${pathsBase}/commands`,
@@ -426,411 +426,24 @@ function writePluginManifests(targetRoot, dryRun, isSelfInstall) {
426
426
  console.log("Wrote: .cursor-plugin/plugin.json, .claude-plugin/plugin.json, .cursor-plugin/registration.json" + (isSelfInstall ? "" : ", .claude-plugin/marketplace.json"));
427
427
  }
428
428
 
429
- /**
430
- * Cursor discovers skills only from .agents/skills, .cursor/skills, ~/.cursor/skills.
431
- * Populate .cursor/skills/ with symlinks to the package skills so Cursor finds them.
432
- */
433
- function syncCursorSkills(targetRoot, dryRun, isSelfInstall) {
434
- const packageSkillsAbs = isSelfInstall
435
- ? path.join(PACKAGE_ROOT, "src", ".agents", "skills")
436
- : path.join(targetRoot, "node_modules", "compound-workflow", "src", ".agents", "skills");
437
- if (!fs.existsSync(packageSkillsAbs)) return;
438
-
439
- const cursorSkillsDir = path.join(targetRoot, ".cursor", "skills");
440
- let entries;
441
- try {
442
- entries = fs.readdirSync(packageSkillsAbs, { withFileTypes: true });
443
- } catch {
444
- return;
445
- }
446
-
447
- const skillDirs = entries.filter((e) => e.isDirectory() && fs.existsSync(path.join(packageSkillsAbs, e.name, "SKILL.md"))).map((e) => e.name);
448
- if (skillDirs.length === 0) return;
449
-
450
- if (dryRun) {
451
- console.log("[dry-run] Would symlink", skillDirs.length, "skills into .cursor/skills/");
452
- return;
453
- }
454
-
455
- fs.mkdirSync(cursorSkillsDir, { recursive: true });
456
- const packageSkillsReal = realpathSafe(packageSkillsAbs);
457
- const skillSet = new Set(skillDirs);
458
-
459
- // Prune: remove symlinks that point at our package but are no longer in the package
460
- try {
461
- for (const entry of fs.readdirSync(cursorSkillsDir, { withFileTypes: true })) {
462
- if (!entry.isSymbolicLink()) continue;
463
- const linkPath = path.join(cursorSkillsDir, entry.name);
464
- try {
465
- const resolved = realpathSafe(linkPath);
466
- if (!resolved.startsWith(packageSkillsReal + path.sep) && resolved !== packageSkillsReal) continue;
467
- const base = path.basename(resolved);
468
- if (skillSet.has(base)) continue;
469
- fs.rmSync(linkPath);
470
- } catch {
471
- /* ignore broken symlinks or permission errors */
472
- }
473
- }
474
- } catch {
475
- /* .cursor/skills not readable */
476
- }
477
-
478
- for (const name of skillDirs) {
479
- const linkPath = path.join(cursorSkillsDir, name);
480
- const targetPath = path.join(packageSkillsAbs, name);
481
- try {
482
- if (fs.existsSync(linkPath)) {
483
- const stat = fs.lstatSync(linkPath);
484
- if (!stat.isSymbolicLink()) continue;
485
- try {
486
- if (realpathSafe(linkPath) !== realpathSafe(targetPath)) continue;
487
- } catch {
488
- continue;
489
- }
490
- fs.rmSync(linkPath);
491
- }
492
- fs.symlinkSync(targetPath, linkPath, "dir");
493
- } catch (err) {
494
- if (err.code === "EPERM" && process.platform === "win32") {
495
- try {
496
- fs.symlinkSync(targetPath, linkPath, "junction");
497
- } catch {
498
- console.warn("[cursor] Could not symlink skill", name, err.message);
499
- }
500
- } else {
501
- console.warn("[cursor] Could not symlink skill", name, err.message);
502
- }
503
- }
504
- }
505
- console.log("Synced", skillDirs.length, "skills to .cursor/skills/");
506
- }
507
-
508
- /**
509
- * Cursor discovers commands from .cursor/commands.
510
- * Populate .cursor/commands/ with symlinks to the package commands so Cursor finds them.
511
- */
512
- function syncCursorCommands(targetRoot, dryRun, isSelfInstall) {
513
- const packageCommandsAbs = isSelfInstall
514
- ? path.join(PACKAGE_ROOT, "src", ".agents", "commands")
515
- : path.join(targetRoot, "node_modules", "compound-workflow", "src", ".agents", "commands");
516
- if (!fs.existsSync(packageCommandsAbs)) return;
517
-
518
- const cursorCommandsDir = path.join(targetRoot, ".cursor", "commands");
519
- let entries;
520
- try {
521
- entries = fs.readdirSync(packageCommandsAbs, { withFileTypes: true });
522
- } catch {
523
- return;
524
- }
525
-
526
- // Filter .md files that are commands
527
- const commandFiles = entries.filter((e) => e.isFile() && e.name.endsWith(".md")).map((e) => e.name);
528
- if (commandFiles.length === 0) return;
529
-
530
- if (dryRun) {
531
- console.log("[dry-run] Would symlink", commandFiles.length, "commands into .cursor/commands/");
532
- return;
533
- }
534
-
535
- fs.mkdirSync(cursorCommandsDir, { recursive: true });
536
- const packageCommandsReal = realpathSafe(packageCommandsAbs);
537
- const commandSet = new Set(commandFiles);
538
-
539
- // Prune: remove symlinks that point at our package but are no longer in the package
540
- try {
541
- for (const entry of fs.readdirSync(cursorCommandsDir, { withFileTypes: true })) {
542
- if (!entry.isSymbolicLink()) continue;
543
- const linkPath = path.join(cursorCommandsDir, entry.name);
544
- try {
545
- const resolved = realpathSafe(linkPath);
546
- if (!resolved.startsWith(packageCommandsReal + path.sep) && resolved !== packageCommandsReal) continue;
547
- const base = path.basename(resolved);
548
- if (commandSet.has(base)) continue;
549
- fs.rmSync(linkPath);
550
- } catch {
551
- /* ignore broken symlinks or permission errors */
552
- }
553
- }
554
- } catch {
555
- /* .cursor/commands not readable */
556
- }
557
-
558
- for (const name of commandFiles) {
559
- const linkPath = path.join(cursorCommandsDir, name);
560
- const targetPath = path.join(packageCommandsAbs, name);
561
- try {
562
- if (fs.existsSync(linkPath)) {
563
- const stat = fs.lstatSync(linkPath);
564
- if (!stat.isSymbolicLink()) continue;
565
- try {
566
- if (realpathSafe(linkPath) !== realpathSafe(targetPath)) continue;
567
- } catch {
568
- continue;
569
- }
570
- fs.rmSync(linkPath);
571
- }
572
- fs.symlinkSync(targetPath, linkPath, "file");
573
- } catch (err) {
574
- console.warn("[cursor] Could not symlink command", name, err.message);
575
- }
576
- }
577
- console.log("Synced", commandFiles.length, "commands to .cursor/commands/");
578
- }
579
-
580
- /**
581
- * Cursor discovers agents from .cursor/agents.
582
- * Populate .cursor/agents/ with symlinks to the package agents so Cursor finds them.
583
- * Preserves subdirectory structure (research/, workflow/, review/).
584
- */
585
- function syncCursorAgents(targetRoot, dryRun, isSelfInstall) {
586
- const packageAgentsAbs = isSelfInstall
587
- ? path.join(PACKAGE_ROOT, "src", ".agents", "agents")
588
- : path.join(targetRoot, "node_modules", "compound-workflow", "src", ".agents", "agents");
589
- if (!fs.existsSync(packageAgentsAbs)) return;
590
-
591
- const cursorAgentsDir = path.join(targetRoot, ".cursor", "agents");
592
-
593
- // Get all agent files from manifest (these include subdir paths like "research/repo-research-analyst.md")
594
- const agentRels = GENERATED_MANIFEST.agents.map((a) => a.rel);
595
- if (agentRels.length === 0) return;
596
-
597
- if (dryRun) {
598
- console.log("[dry-run] Would symlink", agentRels.length, "agents into .cursor/agents/");
599
- return;
600
- }
601
-
602
- fs.mkdirSync(cursorAgentsDir, { recursive: true });
603
- const packageAgentsReal = realpathSafe(packageAgentsAbs);
604
- const agentSet = new Set(agentRels);
605
-
606
- // Build set of valid subdirectories to preserve structure
607
- const validSubdirs = new Set();
608
- for (const rel of agentRels) {
609
- const subdir = path.dirname(rel);
610
- if (subdir !== ".") validSubdirs.add(subdir);
611
- }
612
429
 
613
- // Prune: remove symlinks that point at our package but are no longer in the manifest
614
- try {
615
- for (const entry of fs.readdirSync(cursorAgentsDir, { withFileTypes: true })) {
616
- if (entry.isDirectory()) {
617
- // Check if this subdir is still valid
618
- if (!validSubdirs.has(entry.name)) {
619
- // Remove the entire stale subdirectory
620
- fs.rmSync(path.join(cursorAgentsDir, entry.name), { recursive: true, force: true });
621
- continue;
622
- }
623
- // Prune stale symlinks within valid subdirectories
624
- const subdirPath = path.join(cursorAgentsDir, entry.name);
625
- for (const subEntry of fs.readdirSync(subdirPath, { withFileTypes: true })) {
626
- if (!subEntry.isSymbolicLink()) continue;
627
- const linkPath = path.join(subdirPath, subEntry.name);
628
- try {
629
- const resolved = realpathSafe(linkPath);
630
- if (!resolved.startsWith(packageAgentsReal + path.sep) && resolved !== packageAgentsReal) continue;
631
- const relFromPackage = path.relative(packageAgentsAbs, resolved);
632
- if (agentSet.has(relFromPackage)) continue;
633
- fs.rmSync(linkPath);
634
- } catch {
635
- /* ignore broken symlinks */
636
- }
637
- }
638
- } else if (entry.isSymbolicLink()) {
639
- // Handle flat symlinks (if any were created at root level)
640
- const linkPath = path.join(cursorAgentsDir, entry.name);
641
- try {
642
- const resolved = realpathSafe(linkPath);
643
- if (!resolved.startsWith(packageAgentsReal + path.sep) && resolved !== packageAgentsReal) continue;
644
- const relFromPackage = path.relative(packageAgentsAbs, resolved);
645
- if (agentSet.has(relFromPackage)) continue;
646
- fs.rmSync(linkPath);
647
- } catch {
648
- /* ignore broken symlinks */
649
- }
650
- }
651
- }
652
- } catch {
653
- /* .cursor/agents not readable */
654
- }
655
-
656
- // Create symlinks preserving subdirectory structure
657
- for (const rel of agentRels) {
658
- const targetPath = path.join(packageAgentsAbs, rel);
659
- const linkPath = path.join(cursorAgentsDir, rel);
660
-
661
- // Ensure subdirectory exists
662
- const subdir = path.dirname(rel);
663
- if (subdir !== ".") {
664
- fs.mkdirSync(path.join(cursorAgentsDir, subdir), { recursive: true });
665
- }
666
-
667
- try {
668
- if (fs.existsSync(linkPath)) {
669
- const stat = fs.lstatSync(linkPath);
670
- if (!stat.isSymbolicLink()) continue;
671
- try {
672
- if (realpathSafe(linkPath) !== realpathSafe(targetPath)) continue;
673
- } catch {
674
- continue;
675
- }
676
- fs.rmSync(linkPath);
677
- }
678
- fs.symlinkSync(targetPath, linkPath, "file");
679
- } catch (err) {
680
- console.warn("[cursor] Could not symlink agent", rel, err.message);
681
- }
682
- }
683
- console.log("Synced", agentRels.length, "agents to .cursor/agents/");
684
- }
685
430
 
686
431
  function cursorDetected() {
687
432
  return fs.existsSync(path.join(os.homedir(), ".cursor"));
688
433
  }
689
434
 
690
- /**
691
- * Verifies plugin integrity by checking all symlinks in .cursor/ directories
692
- * match the expected state from GENERATED_MANIFEST.
693
- * Returns { ok: boolean, issues: string[] }
694
- */
695
- function verifyPluginIntegrity(targetRoot, isSelfInstall) {
696
- const issues = [];
697
- const packageRoot = isSelfInstall
698
- ? PACKAGE_ROOT
699
- : path.join(targetRoot, "node_modules", "compound-workflow");
700
-
701
- // Verify skills
702
- const cursorSkillsDir = path.join(targetRoot, ".cursor", "skills");
703
- const packageSkillsDir = path.join(packageRoot, "src", ".agents", "skills");
704
- if (fs.existsSync(packageSkillsDir)) {
705
- const expectedSkills = new Set(
706
- fs.readdirSync(packageSkillsDir, { withFileTypes: true })
707
- .filter((e) => e.isDirectory() && fs.existsSync(path.join(packageSkillsDir, e.name, "SKILL.md")))
708
- .map((e) => e.name)
709
- );
710
- if (fs.existsSync(cursorSkillsDir)) {
711
- const actualSkills = fs.readdirSync(cursorSkillsDir, { withFileTypes: true })
712
- .filter((e) => e.isSymbolicLink())
713
- .map((e) => e.name);
714
- for (const skill of expectedSkills) {
715
- if (!actualSkills.includes(skill)) {
716
- issues.push(`Missing skill symlink: .cursor/skills/${skill}`);
717
- }
718
- }
719
- for (const skill of actualSkills) {
720
- if (!expectedSkills.has(skill)) {
721
- issues.push(`Stale skill symlink: .cursor/skills/${skill}`);
722
- }
723
- }
724
- } else if (expectedSkills.size > 0) {
725
- issues.push(`Missing .cursor/skills/ directory (${expectedSkills.size} expected)`);
726
- }
727
- }
728
-
729
- // Verify commands
730
- const cursorCommandsDir = path.join(targetRoot, ".cursor", "commands");
731
- const packageCommandsDir = path.join(packageRoot, "src", ".agents", "commands");
732
- if (fs.existsSync(packageCommandsDir)) {
733
- const expectedCommands = new Set(
734
- fs.readdirSync(packageCommandsDir, { withFileTypes: true })
735
- .filter((e) => e.isFile() && e.name.endsWith(".md"))
736
- .map((e) => e.name)
737
- );
738
- if (fs.existsSync(cursorCommandsDir)) {
739
- const actualCommands = fs.readdirSync(cursorCommandsDir, { withFileTypes: true })
740
- .filter((e) => e.isSymbolicLink())
741
- .map((e) => e.name);
742
- for (const cmd of expectedCommands) {
743
- if (!actualCommands.includes(cmd)) {
744
- issues.push(`Missing command symlink: .cursor/commands/${cmd}`);
745
- }
746
- }
747
- for (const cmd of actualCommands) {
748
- if (!expectedCommands.has(cmd)) {
749
- issues.push(`Stale command symlink: .cursor/commands/${cmd}`);
750
- }
751
- }
752
- } else if (expectedCommands.size > 0) {
753
- issues.push(`Missing .cursor/commands/ directory (${expectedCommands.size} expected)`);
754
- }
755
- }
756
-
757
- // Verify agents
758
- const cursorAgentsDir = path.join(targetRoot, ".cursor", "agents");
759
- const packageAgentsDir = path.join(packageRoot, "src", ".agents", "agents");
760
- if (fs.existsSync(packageAgentsDir)) {
761
- // Recursively get all .md files from package agents dir
762
- const expectedAgents = [];
763
- function collectAgents(dir, prefix = "") {
764
- for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
765
- const relPath = prefix ? `${prefix}/${entry.name}` : entry.name;
766
- if (entry.isDirectory()) {
767
- collectAgents(path.join(dir, entry.name), relPath);
768
- } else if (entry.isFile() && entry.name.endsWith(".md")) {
769
- expectedAgents.push(relPath);
770
- }
771
- }
772
- }
773
- collectAgents(packageAgentsDir);
774
- const expectedSet = new Set(expectedAgents);
775
-
776
- if (fs.existsSync(cursorAgentsDir)) {
777
- const actualAgents = [];
778
- function collectActualAgents(dir, prefix = "") {
779
- for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
780
- const relPath = prefix ? `${prefix}/${entry.name}` : entry.name;
781
- if (entry.isDirectory()) {
782
- collectActualAgents(path.join(dir, entry.name), relPath);
783
- } else if (entry.isSymbolicLink()) {
784
- actualAgents.push(relPath);
785
- }
786
- }
787
- }
788
- collectActualAgents(cursorAgentsDir);
789
- const actualSet = new Set(actualAgents);
790
-
791
- for (const agent of expectedAgents) {
792
- if (!actualSet.has(agent)) {
793
- issues.push(`Missing agent symlink: .cursor/agents/${agent}`);
794
- }
795
- }
796
- for (const agent of actualAgents) {
797
- if (!expectedSet.has(agent)) {
798
- issues.push(`Stale agent symlink: .cursor/agents/${agent}`);
799
- }
800
- }
801
- } else if (expectedAgents.length > 0) {
802
- issues.push(`Missing .cursor/agents/ directory (${expectedAgents.length} expected)`);
803
- }
804
- }
805
-
806
- return { ok: issues.length === 0, issues };
807
- }
808
435
 
809
436
  function applyCursorRegistration(targetRoot, dryRun, noRegisterCursor, forceRegister, isSelfInstall) {
810
- const claudePluginsDir = path.join(os.homedir(), ".claude", "plugins");
811
- const installedPath = path.join(claudePluginsDir, "installed_plugins.json");
812
- const settingsPath = path.join(os.homedir(), ".claude", "settings.json");
813
-
814
- const pluginVersion = (() => {
815
- try {
816
- const pkgPath = path.join(PACKAGE_ROOT, "package.json");
817
- return JSON.parse(fs.readFileSync(pkgPath, "utf8")).version || "0.0.0";
818
- } catch {
819
- return "0.0.0";
820
- }
821
- })();
822
-
823
437
  const projectRoot = isSelfInstall ? PACKAGE_ROOT : targetRoot;
824
- const pluginId = "compound-workflow@local";
438
+ const pluginId = "compound-workflow@compound-workflow-local";
825
439
 
826
440
  if (dryRun) {
827
441
  console.log("[dry-run] Would register Claude plugin (project-scoped) at:", projectRoot);
828
442
  return;
829
443
  }
830
444
 
831
- // Registration is always project-scoped: write only to <project>/.claude/settings.json.
832
- // Claude Code manages ~/.claude/plugins/installed_plugins.json itself via marketplace flow;
833
- // writing to user-level files causes "unregistered local marketplace" errors on startup.
445
+ // Registration is strictly project-scoped: write only to <project>/.claude/settings.json.
446
+ // Never touch ~/.claude — Claude Code manages user-level plugin state itself.
834
447
  const projectSettingsPath = path.join(projectRoot, ".claude", "settings.json");
835
448
  let projectSettings = {};
836
449
  if (fs.existsSync(projectSettingsPath)) {
@@ -844,31 +457,11 @@ function applyCursorRegistration(targetRoot, dryRun, noRegisterCursor, forceRegi
844
457
  }
845
458
  projectSettings.extraKnownMarketplaces = ensureObject(projectSettings.extraKnownMarketplaces);
846
459
  projectSettings.extraKnownMarketplaces["compound-workflow-local"] = {
847
- source: { source: "file", path: ".claude-plugin/marketplace.json" },
460
+ source: { source: "file", path: "." },
848
461
  };
849
462
  fs.mkdirSync(path.join(projectRoot, ".claude"), { recursive: true });
850
463
  fs.writeFileSync(projectSettingsPath, JSON.stringify(projectSettings, null, 2) + "\n", "utf8");
851
464
 
852
- // Clean up any stale user-level enabledPlugins entries left by previous install versions.
853
- // These cause "unregistered local marketplace" errors on every Claude Code startup.
854
- if (fs.existsSync(settingsPath)) {
855
- try {
856
- let userSettings = readJsonMaybe(settingsPath) ?? {};
857
- const staleIds = ["compound-workflow@local", "compound-workflow@compound-workflow-local"];
858
- let changed = false;
859
- for (const id of staleIds) {
860
- if (userSettings?.enabledPlugins?.[id] !== undefined) {
861
- delete userSettings.enabledPlugins[id];
862
- changed = true;
863
- }
864
- }
865
- if (changed) {
866
- fs.writeFileSync(settingsPath, JSON.stringify(userSettings, null, 2) + "\n", "utf8");
867
- console.log("Cleaned up stale compound-workflow entries from ~/.claude/settings.json");
868
- }
869
- } catch { /* ignore */ }
870
- }
871
-
872
465
  console.log("Registered compound-workflow with Claude Code (project-scoped).");
873
466
  if (!isSelfInstall) {
874
467
  console.log(" Claude Code 2.1+: open /plugin, go to Discover; install 'compound-workflow' from marketplace 'compound-workflow-local', or run: claude --plugin-dir ./node_modules/compound-workflow");
@@ -908,31 +501,6 @@ function main() {
908
501
  const args = parseArgs(process.argv);
909
502
  const targetRoot = realpathSafe(args.root);
910
503
 
911
- // Handle verification mode early (no manifest needed)
912
- if (args.verify) {
913
- console.log("Verifying plugin integrity...");
914
- const isSelfInstall = realpathSafe(targetRoot) === realpathSafe(PACKAGE_ROOT);
915
- // Try to read manifest for accurate verification, but continue without it
916
- try {
917
- GENERATED_MANIFEST = readGeneratedManifest();
918
- } catch {
919
- console.warn("Warning: Could not read generated manifest, using filesystem scan only");
920
- GENERATED_MANIFEST = { commands: [], agents: [] };
921
- }
922
- const result = verifyPluginIntegrity(targetRoot, isSelfInstall);
923
- if (result.ok) {
924
- console.log("Plugin integrity: OK (all symlinks present and valid)");
925
- process.exit(0);
926
- } else {
927
- console.error("Plugin integrity issues found:");
928
- for (const issue of result.issues) {
929
- console.error(` - ${issue}`);
930
- }
931
- console.error("\nRun 'npx compound-workflow install' to fix.");
932
- process.exit(1);
933
- }
934
- }
935
-
936
504
  const genScript = path.join(PACKAGE_ROOT, "scripts", "generate-platform-artifacts.mjs");
937
505
  if (fs.existsSync(genScript)) {
938
506
  console.log("[compound-workflow] Regenerating manifest from package source...");
@@ -975,9 +543,6 @@ function main() {
975
543
 
976
544
  writeOpenCodeJson(targetRoot, args.dryRun, isSelfInstall);
977
545
  writePluginManifests(targetRoot, args.dryRun, isSelfInstall);
978
- syncCursorSkills(targetRoot, args.dryRun, isSelfInstall);
979
- syncCursorCommands(targetRoot, args.dryRun, isSelfInstall);
980
- syncCursorAgents(targetRoot, args.dryRun, isSelfInstall);
981
546
  applyCursorRegistration(targetRoot, args.dryRun, args.noRegisterCursor, args.registerCursor, isSelfInstall);
982
547
  reportOpenCodeIntegration(targetRoot, args.dryRun);
983
548
  writeAgentsMd(targetRoot, args.dryRun);
@@ -6,7 +6,7 @@ argument-hint: "[PR number, branch name, or 'current' for current branch]"
6
6
 
7
7
  # Browser Test Command
8
8
 
9
- <command_purpose>Run end-to-end browser tests on pages affected by a PR or branch changes using agent-browser CLI.</command_purpose>
9
+ Run end-to-end browser tests on pages affected by a PR or branch changes using agent-browser CLI.
10
10
 
11
11
  ## CRITICAL: Use agent-browser CLI Only
12
12
 
@@ -7,8 +7,9 @@ argument-hint: "[feature idea or problem to explore]"
7
7
 
8
8
  # Brainstorm a Feature or Improvement
9
9
 
10
- **Note: The current year is 2026.** Use this when dating brainstorm
11
- documents.
10
+ Explore requirements and approaches through collaborative dialogue before planning implementation.
11
+
12
+ **Note: The current year is 2026.** Use this when dating brainstorm documents.
12
13
 
13
14
  Brainstorming helps answer **WHAT** to build through collaborative
14
15
  dialogue. It precedes `/workflow:plan`, which answers **HOW** to build
@@ -7,6 +7,8 @@ argument-hint: "[feature description, bug report, improvement idea, or brainstor
7
7
 
8
8
  # Create a plan for a new feature or bug fix
9
9
 
10
+ Transform feature descriptions into well-structured project plans using an explicit fidelity and confidence model.
11
+
10
12
  ## Introduction
11
13
 
12
14
  **Note: The current year is 2026.** Use this when dating plans and searching for recent documentation.