compound-workflow 1.6.9 → 1.6.10

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.6.9",
3
+ "version": "1.6.10",
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.6.9",
3
+ "version": "1.6.10",
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.6.9",
3
+ "version": "1.6.10",
4
4
  "description": "Clarify → plan → execute → verify → capture. One Install action for Cursor, Claude, and OpenCode.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -449,23 +449,25 @@ function cursorDetected() {
449
449
  }
450
450
 
451
451
  function applyCursorRegistration(targetRoot, dryRun, noRegisterCursor, forceRegister, isSelfInstall) {
452
- if (dryRun) return;
453
-
454
452
  const claudePluginsDir = path.join(os.homedir(), ".claude", "plugins");
455
453
  const installedPath = path.join(claudePluginsDir, "installed_plugins.json");
456
454
  const settingsPath = path.join(os.homedir(), ".claude", "settings.json");
457
455
 
458
- // installPath must point to the package root so Claude Code resolves
459
- // commands/agents/skills paths in .claude-plugin/plugin.json relative to it.
460
- const pluginInstallPath = isSelfInstall
461
- ? realpathSafe(PACKAGE_ROOT)
462
- : realpathSafe(path.join(targetRoot, "node_modules", "compound-workflow"));
456
+ const pluginVersion = (() => {
457
+ try {
458
+ const pkgPath = path.join(PACKAGE_ROOT, "package.json");
459
+ return JSON.parse(fs.readFileSync(pkgPath, "utf8")).version || "0.0.0";
460
+ } catch {
461
+ return "0.0.0";
462
+ }
463
+ })();
463
464
 
464
- const pluginDescriptor = {
465
- pluginId: "compound-workflow@local",
466
- scope: "user",
467
- installPath: pluginInstallPath,
468
- };
465
+ // For self-install (dev), use the package root with user scope.
466
+ // For consumer projects, use the project root with project scope so each
467
+ // project gets its own entry and installs don't overwrite each other.
468
+ const targetRootReal = realpathSafe(isSelfInstall ? PACKAGE_ROOT : targetRoot);
469
+ const pluginId = "compound-workflow@local";
470
+ const scope = isSelfInstall ? "user" : "project";
469
471
 
470
472
  let installed = {};
471
473
  if (fs.existsSync(installedPath)) {
@@ -476,7 +478,38 @@ function applyCursorRegistration(targetRoot, dryRun, noRegisterCursor, forceRegi
476
478
  }
477
479
  }
478
480
  const plugins = ensureObject(installed.plugins);
479
- plugins[pluginDescriptor.pluginId] = [{ scope: pluginDescriptor.scope || "user", installPath: pluginDescriptor.installPath }];
481
+ const existingEntries = Array.isArray(plugins[pluginId]) ? plugins[pluginId] : [];
482
+
483
+ // Remove legacy scope:"user" entries when switching to project-scope
484
+ const cleanedEntries = scope === "project"
485
+ ? existingEntries.filter((e) => e.scope !== "user")
486
+ : existingEntries;
487
+
488
+ // Prune stale entries whose installPath no longer has a plugin manifest on disk
489
+ const pruned = cleanedEntries.filter((e) => {
490
+ const manifest = path.join(e.installPath || "", ".claude-plugin", "plugin.json");
491
+ return fs.existsSync(manifest);
492
+ });
493
+
494
+ // Find existing entry for this project (or user-scope entry for self-install)
495
+ const matchIndex = pruned.findIndex((e) =>
496
+ scope === "user" ? e.scope === "user" : e.scope === "project" && e.projectPath === targetRootReal
497
+ );
498
+
499
+ const existingEntry = matchIndex >= 0 ? pruned[matchIndex] : {};
500
+ const now = new Date().toISOString();
501
+ const newEntry = {
502
+ scope,
503
+ ...(scope === "project" ? { projectPath: targetRootReal } : {}),
504
+ installPath: targetRootReal,
505
+ version: pluginVersion,
506
+ installedAt: existingEntry.installedAt || now,
507
+ lastUpdated: now,
508
+ };
509
+
510
+ plugins[pluginId] = matchIndex >= 0
511
+ ? pruned.map((e, i) => (i === matchIndex ? newEntry : e))
512
+ : [...pruned, newEntry];
480
513
  installed.plugins = plugins;
481
514
 
482
515
  let settings = {};
@@ -487,13 +520,33 @@ function applyCursorRegistration(targetRoot, dryRun, noRegisterCursor, forceRegi
487
520
  settings = {};
488
521
  }
489
522
  }
523
+ // User-level settings (backward compat)
490
524
  settings.enabledPlugins = ensureObject(settings.enabledPlugins);
491
- settings.enabledPlugins[pluginDescriptor.pluginId] = true;
525
+ settings.enabledPlugins[pluginId] = true;
526
+
527
+ if (dryRun) {
528
+ console.log("[dry-run] Would register Claude plugin:", JSON.stringify(newEntry, null, 2));
529
+ return;
530
+ }
492
531
 
493
532
  fs.mkdirSync(claudePluginsDir, { recursive: true });
494
533
  fs.mkdirSync(path.dirname(settingsPath), { recursive: true });
495
534
  fs.writeFileSync(installedPath, JSON.stringify(installed, null, 2) + "\n", "utf8");
496
535
  fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf8");
536
+
537
+ // Project-level settings required for scope:"project" to activate
538
+ if (!isSelfInstall) {
539
+ const projectSettingsPath = path.join(targetRoot, ".claude", "settings.json");
540
+ let projectSettings = {};
541
+ if (fs.existsSync(projectSettingsPath)) {
542
+ try { projectSettings = readJsonMaybe(projectSettingsPath) ?? {}; } catch { projectSettings = {}; }
543
+ }
544
+ projectSettings.enabledPlugins = ensureObject(projectSettings.enabledPlugins);
545
+ projectSettings.enabledPlugins[pluginId] = true;
546
+ fs.mkdirSync(path.join(targetRoot, ".claude"), { recursive: true });
547
+ fs.writeFileSync(projectSettingsPath, JSON.stringify(projectSettings, null, 2) + "\n", "utf8");
548
+ }
549
+
497
550
  console.log("Registered compound-workflow with Claude Code. Restart Claude Code; enable 'Include third-party Plugins, Skills, and other configs' in Settings if needed.");
498
551
 
499
552
  if (noRegisterCursor && !forceRegister) return;