codebyplan 1.13.34 → 1.13.35

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.
Files changed (2) hide show
  1. package/dist/cli.js +72 -16
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -14,7 +14,7 @@ var VERSION, PACKAGE_NAME;
14
14
  var init_version = __esm({
15
15
  "src/lib/version.ts"() {
16
16
  "use strict";
17
- VERSION = "1.13.34";
17
+ VERSION = "1.13.35";
18
18
  PACKAGE_NAME = "codebyplan";
19
19
  }
20
20
  });
@@ -1606,22 +1606,16 @@ function mergeEnabledPluginsIntoSettings(settings, plugins) {
1606
1606
  }
1607
1607
  return settings;
1608
1608
  }
1609
- function stripOwnedHooksFromSettings(settings) {
1609
+ function collapseEmptyHookBlocks(settings) {
1610
1610
  if (!settings.hooks) {
1611
- return settings;
1611
+ return;
1612
1612
  }
1613
1613
  for (const event of Object.keys(settings.hooks)) {
1614
1614
  const eventBlocks = settings.hooks[event];
1615
1615
  if (!eventBlocks) {
1616
1616
  continue;
1617
1617
  }
1618
- const survivingBlocks = [];
1619
- for (const block of eventBlocks) {
1620
- block.hooks = block.hooks.filter((e) => e._owner !== OWNER);
1621
- if (block.hooks.length > 0) {
1622
- survivingBlocks.push(block);
1623
- }
1624
- }
1618
+ const survivingBlocks = eventBlocks.filter((b) => b.hooks.length > 0);
1625
1619
  if (survivingBlocks.length > 0) {
1626
1620
  settings.hooks[event] = survivingBlocks;
1627
1621
  } else {
@@ -1631,6 +1625,54 @@ function stripOwnedHooksFromSettings(settings) {
1631
1625
  if (Object.keys(settings.hooks).length === 0) {
1632
1626
  delete settings.hooks;
1633
1627
  }
1628
+ }
1629
+ function stripOwnedHooksFromSettings(settings) {
1630
+ if (!settings.hooks) {
1631
+ return settings;
1632
+ }
1633
+ for (const event of Object.keys(settings.hooks)) {
1634
+ const eventBlocks = settings.hooks[event];
1635
+ if (!eventBlocks) {
1636
+ continue;
1637
+ }
1638
+ for (const block of eventBlocks) {
1639
+ block.hooks = block.hooks.filter((e) => e._owner !== OWNER);
1640
+ }
1641
+ }
1642
+ collapseEmptyHookBlocks(settings);
1643
+ return settings;
1644
+ }
1645
+ function pruneMissingManagedHooks(settings, hooksJson, onPruned) {
1646
+ if (!settings.hooks) {
1647
+ return settings;
1648
+ }
1649
+ const liveIdsByEvent = /* @__PURE__ */ new Map();
1650
+ for (const [event, matchers] of Object.entries(hooksJson.hooks)) {
1651
+ const ids = /* @__PURE__ */ new Set();
1652
+ for (const block of matchers) {
1653
+ for (const cmd of block.hooks) {
1654
+ ids.add(extractHookId(cmd.command));
1655
+ }
1656
+ }
1657
+ liveIdsByEvent.set(event, ids);
1658
+ }
1659
+ for (const event of Object.keys(settings.hooks)) {
1660
+ const eventBlocks = settings.hooks[event];
1661
+ if (!eventBlocks) {
1662
+ continue;
1663
+ }
1664
+ const liveIds = liveIdsByEvent.get(event) ?? /* @__PURE__ */ new Set();
1665
+ for (const block of eventBlocks) {
1666
+ block.hooks = block.hooks.filter((e) => {
1667
+ const shouldPrune = e._owner === OWNER && e._hook_id !== void 0 && !liveIds.has(e._hook_id);
1668
+ if (shouldPrune && onPruned) {
1669
+ onPruned(e._hook_id);
1670
+ }
1671
+ return !shouldPrune;
1672
+ });
1673
+ }
1674
+ }
1675
+ collapseEmptyHookBlocks(settings);
1634
1676
  return settings;
1635
1677
  }
1636
1678
  var OWNER, PLACEHOLDER_RE, REPLACEMENT, SCALAR_BASE_KEYS, DEPRECATED_BASE_KEYS;
@@ -2558,9 +2600,9 @@ async function runLspFull(projectPath, opts = {}) {
2558
2600
  ` Detected LSP servers: ${servers.map((s) => s.plugin).join(", ")}
2559
2601
  `
2560
2602
  );
2561
- const settingsPath = join10(projectPath, ".claude", "settings.json");
2603
+ const settingsLocalPath = join10(projectPath, ".claude", "settings.local.json");
2562
2604
  let settings = {};
2563
- const existingSettingsRaw = await readJsonFile(settingsPath);
2605
+ const existingSettingsRaw = await readJsonFile(settingsLocalPath);
2564
2606
  if (existingSettingsRaw) {
2565
2607
  settings = existingSettingsRaw;
2566
2608
  }
@@ -2569,15 +2611,15 @@ async function runLspFull(projectPath, opts = {}) {
2569
2611
  servers.map((s) => s.plugin)
2570
2612
  );
2571
2613
  if (dryRun) {
2572
- console.log(` [dry-run] would update ${settingsPath}`);
2614
+ console.log(` [dry-run] would update ${settingsLocalPath}`);
2573
2615
  } else {
2574
2616
  await mkdir4(join10(projectPath, ".claude"), { recursive: true });
2575
2617
  await writeFile6(
2576
- settingsPath,
2618
+ settingsLocalPath,
2577
2619
  JSON.stringify(settings, null, 2) + "\n",
2578
2620
  "utf-8"
2579
2621
  );
2580
- console.log(` Updated ${settingsPath}`);
2622
+ console.log(` Updated ${settingsLocalPath}`);
2581
2623
  }
2582
2624
  const lspJsonPath = join10(projectPath, ".codebyplan", "lsp.json");
2583
2625
  const lspJsonContent = {
@@ -2648,7 +2690,7 @@ async function runLspFull(projectPath, opts = {}) {
2648
2690
  ` Enabled plugins: ${pluginNames.length > 0 ? pluginNames.join(", ") : "none"}`
2649
2691
  );
2650
2692
  console.log(
2651
- ` (settings.json key format: <plugin>@claude-plugins-official)`
2693
+ ` (settings.local.json key format: <plugin>@claude-plugins-official)`
2652
2694
  );
2653
2695
  if (autoInstalled.length > 0) {
2654
2696
  console.log(
@@ -2811,6 +2853,13 @@ async function runInstall(opts, deps = {}) {
2811
2853
  fs3.readFileSync(hooksJsonPath, "utf8")
2812
2854
  );
2813
2855
  mergeHooksIntoSettings(existingSettings, hooksJson);
2856
+ pruneMissingManagedHooks(
2857
+ existingSettings,
2858
+ hooksJson,
2859
+ opts.verbose ? (id) => console.log(
2860
+ `${opts.dryRun ? "[dry-run] would prune" : "pruned"} removed managed hook: ${id}`
2861
+ ) : void 0
2862
+ );
2814
2863
  }
2815
2864
  if (!opts.dryRun) {
2816
2865
  fs3.mkdirSync(path4.dirname(settingsPath), { recursive: true });
@@ -8806,6 +8855,13 @@ async function runUpdate(opts, deps = {}) {
8806
8855
  fs7.readFileSync(hooksJsonPath, "utf8")
8807
8856
  );
8808
8857
  mergeHooksIntoSettings(existingSettings, hooksJson);
8858
+ pruneMissingManagedHooks(
8859
+ existingSettings,
8860
+ hooksJson,
8861
+ opts.verbose ? (id) => console.log(
8862
+ `${opts.dryRun ? "[dry-run] would prune" : "pruned"} removed managed hook: ${id}`
8863
+ ) : void 0
8864
+ );
8809
8865
  }
8810
8866
  if (!opts.dryRun) {
8811
8867
  fs7.mkdirSync(path8.dirname(settingsPath), { recursive: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codebyplan",
3
- "version": "1.13.34",
3
+ "version": "1.13.35",
4
4
  "description": "CLI for CodeByPlan — AI-powered development planning and tracking",
5
5
  "type": "module",
6
6
  "bin": {