claude-launchpad 1.8.0 → 1.8.1

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 (34) hide show
  1. package/dist/{chunk-MDR73QT2.js → chunk-COGKNJJB.js} +2 -2
  2. package/dist/{chunk-NJQ2JFGF.js → chunk-H2E7QMF4.js} +2 -2
  3. package/dist/{chunk-7QPZN27I.js → chunk-IY3Z54UK.js} +143 -117
  4. package/dist/chunk-IY3Z54UK.js.map +1 -0
  5. package/dist/{chunk-MIHOPQP4.js → chunk-RDID5P4K.js} +2 -2
  6. package/dist/{chunk-GY3SK66Y.js → chunk-THDBKJAV.js} +3 -3
  7. package/dist/cli.js +68 -30
  8. package/dist/cli.js.map +1 -1
  9. package/dist/commands/memory/server.js +3 -3
  10. package/dist/{context-XTPBYGKW.js → context-BCTOCTZD.js} +5 -5
  11. package/dist/{install-MQDN7TLA.js → install-L23C4YWJ.js} +9 -5
  12. package/dist/install-L23C4YWJ.js.map +1 -0
  13. package/dist/{pull-ELZGXQPJ.js → pull-5KYLJ6TH.js} +7 -7
  14. package/dist/{push-HJXEC7XC.js → push-UOVLT5HO.js} +7 -7
  15. package/dist/{require-deps-3B3NWAEP.js → require-deps-T2QOGQQ3.js} +3 -3
  16. package/dist/{stats-S3GNMUDF.js → stats-GL7P24U7.js} +6 -6
  17. package/dist/{sync-clean-XNMLP3FZ.js → sync-clean-7RNYS7EH.js} +3 -3
  18. package/dist/{sync-status-4AGU776A.js → sync-status-ULZCMBQJ.js} +7 -7
  19. package/dist/{tui-CGXGXU5U.js → tui-UGBWF2WT.js} +4 -4
  20. package/package.json +1 -1
  21. package/dist/chunk-7QPZN27I.js.map +0 -1
  22. package/dist/install-MQDN7TLA.js.map +0 -1
  23. /package/dist/{chunk-MDR73QT2.js.map → chunk-COGKNJJB.js.map} +0 -0
  24. /package/dist/{chunk-NJQ2JFGF.js.map → chunk-H2E7QMF4.js.map} +0 -0
  25. /package/dist/{chunk-MIHOPQP4.js.map → chunk-RDID5P4K.js.map} +0 -0
  26. /package/dist/{chunk-GY3SK66Y.js.map → chunk-THDBKJAV.js.map} +0 -0
  27. /package/dist/{context-XTPBYGKW.js.map → context-BCTOCTZD.js.map} +0 -0
  28. /package/dist/{pull-ELZGXQPJ.js.map → pull-5KYLJ6TH.js.map} +0 -0
  29. /package/dist/{push-HJXEC7XC.js.map → push-UOVLT5HO.js.map} +0 -0
  30. /package/dist/{require-deps-3B3NWAEP.js.map → require-deps-T2QOGQQ3.js.map} +0 -0
  31. /package/dist/{stats-S3GNMUDF.js.map → stats-GL7P24U7.js.map} +0 -0
  32. /package/dist/{sync-clean-XNMLP3FZ.js.map → sync-clean-7RNYS7EH.js.map} +0 -0
  33. /package/dist/{sync-status-4AGU776A.js.map → sync-status-ULZCMBQJ.js.map} +0 -0
  34. /package/dist/{tui-CGXGXU5U.js.map → tui-UGBWF2WT.js.map} +0 -0
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  log
4
- } from "./chunk-7QPZN27I.js";
4
+ } from "./chunk-IY3Z54UK.js";
5
5
 
6
6
  // src/commands/memory/utils/gist-transport.ts
7
7
  import { execSync } from "child_process";
@@ -205,4 +205,4 @@ export {
205
205
  deleteGistFile,
206
206
  updateGistFiles
207
207
  };
208
- //# sourceMappingURL=chunk-MDR73QT2.js.map
208
+ //# sourceMappingURL=chunk-COGKNJJB.js.map
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  log
4
- } from "./chunk-7QPZN27I.js";
4
+ } from "./chunk-IY3Z54UK.js";
5
5
 
6
6
  // src/commands/memory/utils/require-deps.ts
7
7
  import { createRequire } from "module";
@@ -44,4 +44,4 @@ export {
44
44
  cwdRequire,
45
45
  requireMemoryDeps
46
46
  };
47
- //# sourceMappingURL=chunk-NJQ2JFGF.js.map
47
+ //# sourceMappingURL=chunk-H2E7QMF4.js.map
@@ -32,77 +32,15 @@ async function readJsonOrNull(path) {
32
32
  }
33
33
 
34
34
  // src/lib/settings.ts
35
- import { readFile as readFile2, writeFile, mkdir } from "fs/promises";
36
- import { join } from "path";
37
- async function readSettingsJson(root) {
38
- const path = join(root, ".claude", "settings.json");
39
- try {
40
- const content = await readFile2(path, "utf-8");
41
- return JSON.parse(content);
42
- } catch {
43
- return {};
44
- }
45
- }
46
- async function writeSettingsJson(root, settings) {
47
- const dir = join(root, ".claude");
48
- await mkdir(dir, { recursive: true });
49
- await writeFile(join(dir, "settings.json"), JSON.stringify(settings, null, 2) + "\n");
50
- }
51
- async function readSettingsLocalJson(root) {
52
- const path = join(root, ".claude", "settings.local.json");
53
- try {
54
- const content = await readFile2(path, "utf-8");
55
- return JSON.parse(content);
56
- } catch {
57
- return {};
58
- }
59
- }
60
- async function writeSettingsLocalJson(root, settings) {
61
- const dir = join(root, ".claude");
62
- await mkdir(dir, { recursive: true });
63
- await writeFile(join(dir, "settings.local.json"), JSON.stringify(settings, null, 2) + "\n");
64
- }
65
-
66
- // src/lib/memory-placement.ts
67
- import { select } from "@inquirer/prompts";
68
- function hasMemoryPermissions(settings) {
69
- const permissions = settings.permissions;
70
- const allow = permissions?.allow ?? [];
71
- return allow.some((p) => p.includes("agentic-memory"));
72
- }
73
- async function getMemoryPlacement(root, skipPrompt = false) {
74
- const local = await readSettingsLocalJson(root);
75
- const persisted = local.memoryPlacement;
76
- if (persisted === "shared" || persisted === "local") {
77
- return persisted;
78
- }
79
- if (hasMemoryPermissions(local)) {
80
- await writeSettingsLocalJson(root, { ...local, memoryPlacement: "local" });
81
- return "local";
82
- }
83
- const shared = await readSettingsJson(root);
84
- if (hasMemoryPermissions(shared)) {
85
- await writeSettingsLocalJson(root, { ...local, memoryPlacement: "shared" });
86
- return "shared";
87
- }
88
- if (skipPrompt) return "shared";
89
- const choice = await select({
90
- message: "Where should memory config go?",
91
- choices: [
92
- { value: "shared", name: "Shared (team sees it) \u2014 CLAUDE.md + settings.json" },
93
- { value: "local", name: "Local (only you) \u2014 .claude/CLAUDE.md + settings.local.json" }
94
- ]
95
- });
96
- await writeSettingsLocalJson(root, { ...local, memoryPlacement: choice });
97
- return choice;
98
- }
35
+ import { readFile as readFile4, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
36
+ import { join as join4 } from "path";
99
37
 
100
38
  // src/lib/output.ts
101
39
  import chalk from "chalk";
102
40
 
103
41
  // src/commands/doctor/fixer.ts
104
- import { readFile as readFile4, writeFile as writeFile2, mkdir as mkdir2, access as access2 } from "fs/promises";
105
- import { join as join4 } from "path";
42
+ import { readFile as readFile3, writeFile, mkdir, access as access2 } from "fs/promises";
43
+ import { join as join3 } from "path";
106
44
  import { homedir } from "os";
107
45
 
108
46
  // src/lib/sections.ts
@@ -113,22 +51,22 @@ var OFF_LIMITS_CONTENT = "- Never hardcode secrets \u2014 use environment variab
113
51
  var SKILL_AUTHORING_CONTENT = 'When creating Claude Code skills (.claude/skills/*/SKILL.md):\n\n- Keep SKILL.md under 500 lines \u2014 move reference material to supporting files in the same directory\n- Front-load description (first 250 chars shown in listings) with TRIGGER when / DO NOT TRIGGER when clauses\n- Add allowed-tools in frontmatter to restrict tool access (e.g. Read, Glob, Grep for read-only skills)\n- Add argument-hint in frontmatter showing the expected input format (use $ARGUMENTS or $0, $1 for dynamic input)\n- Set disable-model-invocation: true for skills with side effects (deploy, send messages)\n- Structure as phases: Research, Plan, Execute, Verify with "Done when:" success criteria per phase\n- Handle edge cases and preconditions before execution';
114
52
 
115
53
  // src/lib/detect.ts
116
- import { join as join2, basename } from "path";
54
+ import { join, basename } from "path";
117
55
  async function detectProject(root) {
118
56
  const name = basename(root);
119
57
  const [pkgJson, goMod, pyProject, gemfile, cargo, pubspec, composerJson, pomXml, buildGradleGroovy, buildGradleKts, packageSwift, mixExs, csproj, lockfiles] = await Promise.all([
120
- readJsonOrNull(join2(root, "package.json")),
121
- fileExists(join2(root, "go.mod")),
122
- readFileOrNull(join2(root, "pyproject.toml")),
123
- fileExists(join2(root, "Gemfile")),
124
- fileExists(join2(root, "Cargo.toml")),
125
- fileExists(join2(root, "pubspec.yaml")),
126
- readJsonOrNull(join2(root, "composer.json")),
127
- fileExists(join2(root, "pom.xml")),
128
- fileExists(join2(root, "build.gradle")),
129
- fileExists(join2(root, "build.gradle.kts")),
130
- fileExists(join2(root, "Package.swift")),
131
- fileExists(join2(root, "mix.exs")),
58
+ readJsonOrNull(join(root, "package.json")),
59
+ fileExists(join(root, "go.mod")),
60
+ readFileOrNull(join(root, "pyproject.toml")),
61
+ fileExists(join(root, "Gemfile")),
62
+ fileExists(join(root, "Cargo.toml")),
63
+ fileExists(join(root, "pubspec.yaml")),
64
+ readJsonOrNull(join(root, "composer.json")),
65
+ fileExists(join(root, "pom.xml")),
66
+ fileExists(join(root, "build.gradle")),
67
+ fileExists(join(root, "build.gradle.kts")),
68
+ fileExists(join(root, "Package.swift")),
69
+ fileExists(join(root, "mix.exs")),
132
70
  globExists(root, "*.csproj"),
133
71
  detectLockfiles(root)
134
72
  ]);
@@ -209,10 +147,10 @@ function detectFramework(m) {
209
147
  }
210
148
  async function detectLockfiles(root) {
211
149
  const [pnpmLock, yarnLock, bunLock, npmLock] = await Promise.all([
212
- fileExists(join2(root, "pnpm-lock.yaml")),
213
- fileExists(join2(root, "yarn.lock")),
214
- fileExists(join2(root, "bun.lockb")),
215
- fileExists(join2(root, "package-lock.json"))
150
+ fileExists(join(root, "pnpm-lock.yaml")),
151
+ fileExists(join(root, "yarn.lock")),
152
+ fileExists(join(root, "bun.lockb")),
153
+ fileExists(join(root, "package-lock.json"))
216
154
  ]);
217
155
  return { pnpmLock, yarnLock, bunLock, npmLock };
218
156
  }
@@ -619,6 +557,40 @@ function generateEnhanceSkill() {
619
557
  ].join("\n");
620
558
  }
621
559
 
560
+ // src/lib/memory-placement.ts
561
+ import { select } from "@inquirer/prompts";
562
+ function hasMemoryPermissions(settings) {
563
+ const permissions = settings.permissions;
564
+ const allow = permissions?.allow ?? [];
565
+ return allow.some((p) => p.includes("agentic-memory"));
566
+ }
567
+ async function getMemoryPlacement(root, skipPrompt = false) {
568
+ const local = await readSettingsLocalJson(root) ?? {};
569
+ const persisted = local.memoryPlacement;
570
+ if (persisted === "shared" || persisted === "local") {
571
+ return persisted;
572
+ }
573
+ if (hasMemoryPermissions(local)) {
574
+ await writeSettingsLocalJson(root, { ...local, memoryPlacement: "local" });
575
+ return "local";
576
+ }
577
+ const shared = await readSettingsJson(root) ?? {};
578
+ if (hasMemoryPermissions(shared)) {
579
+ await writeSettingsLocalJson(root, { ...local, memoryPlacement: "shared" });
580
+ return "shared";
581
+ }
582
+ if (skipPrompt) return "shared";
583
+ const choice = await select({
584
+ message: "Where should memory config go?",
585
+ choices: [
586
+ { value: "shared", name: "Shared (team sees it) \u2014 CLAUDE.md + settings.json" },
587
+ { value: "local", name: "Local (only you) \u2014 .claude/CLAUDE.md + settings.local.json" }
588
+ ]
589
+ });
590
+ await writeSettingsLocalJson(root, { ...local, memoryPlacement: choice });
591
+ return choice;
592
+ }
593
+
622
594
  // src/lib/stub-marker.ts
623
595
  var LP_STUB_OPEN = "<!-- LP-STUB: ai-recommended -->";
624
596
  var LP_STUB_CLOSE = "<!-- /LP-STUB -->";
@@ -629,12 +601,13 @@ ${LP_STUB_CLOSE}`;
629
601
  }
630
602
 
631
603
  // src/commands/doctor/fixer-memory.ts
632
- import { readFile as readFile3 } from "fs/promises";
633
- import { join as join3 } from "path";
604
+ import { readFile as readFile2 } from "fs/promises";
605
+ import { join as join2 } from "path";
634
606
  async function addPlacementHook(root, placement, event, dedupKeyword, entry, prepend, successMsg) {
635
607
  const read = placement === "local" ? readSettingsLocalJson : readSettingsJson;
636
608
  const write = placement === "local" ? writeSettingsLocalJson : writeSettingsJson;
637
609
  const settings = await read(root);
610
+ if (settings === null) return false;
638
611
  const hooks = settings.hooks ?? {};
639
612
  const hookList = hooks[event] ?? [];
640
613
  const alreadyHas = hookList.some((g) => {
@@ -652,6 +625,7 @@ async function disableAutoMemory(root, placement) {
652
625
  const read = placement === "local" ? readSettingsLocalJson : readSettingsJson;
653
626
  const write = placement === "local" ? writeSettingsLocalJson : writeSettingsJson;
654
627
  const settings = await read(root);
628
+ if (settings === null) return false;
655
629
  if (settings.autoMemoryEnabled === false) return false;
656
630
  const updated = { ...settings, autoMemoryEnabled: false };
657
631
  await write(root, updated);
@@ -663,6 +637,7 @@ async function addMemoryToolPermissions(root, placement) {
663
637
  const read = placement === "local" ? readSettingsLocalJson : readSettingsJson;
664
638
  const write = placement === "local" ? writeSettingsLocalJson : writeSettingsJson;
665
639
  const settings = await read(root);
640
+ if (settings === null) return false;
666
641
  const permissions = settings.permissions ?? {};
667
642
  const allow = permissions.allow ?? [];
668
643
  const tools = [
@@ -701,6 +676,7 @@ async function upgradeStaleSessionEndPushHook(root) {
701
676
  const read = placement === "local" ? readSettingsLocalJson : readSettingsJson;
702
677
  const write = placement === "local" ? writeSettingsLocalJson : writeSettingsJson;
703
678
  const settings = await read(root);
679
+ if (settings === null) continue;
704
680
  const hooks = settings.hooks;
705
681
  const sessionEnd = hooks?.SessionEnd;
706
682
  if (!sessionEnd) continue;
@@ -727,6 +703,7 @@ async function upgradeStaleSessionEndPushHook(root) {
727
703
  }
728
704
  async function removeStaleStopHook(root) {
729
705
  const settings = await readSettingsJson(root);
706
+ if (settings === null) return false;
730
707
  const hooks = settings.hooks;
731
708
  if (!hooks?.Stop) return false;
732
709
  const stopHooks = hooks.Stop;
@@ -749,6 +726,7 @@ async function addMemoryToAllowedMcpServers(root) {
749
726
  const read = placement === "local" ? readSettingsLocalJson : readSettingsJson;
750
727
  const write = placement === "local" ? writeSettingsLocalJson : writeSettingsJson;
751
728
  const settings = await read(root);
729
+ if (settings === null) continue;
752
730
  const existing = settings.allowedMcpServers;
753
731
  if (!Array.isArray(existing)) continue;
754
732
  const list = existing;
@@ -769,17 +747,19 @@ async function addAllowedMcpServers(root, placement) {
769
747
  const read = placement === "local" ? readSettingsLocalJson : readSettingsJson;
770
748
  const write = placement === "local" ? writeSettingsLocalJson : writeSettingsJson;
771
749
  const settings = await read(root);
750
+ if (settings === null) return false;
772
751
  if (settings.allowedMcpServers) return false;
773
752
  const other = placement === "local" ? await readSettingsJson(root) : await readSettingsLocalJson(root);
753
+ if (other === null) return false;
774
754
  if (other.allowedMcpServers) return false;
775
755
  const serverNames = /* @__PURE__ */ new Set();
776
756
  const settingsServers = settings.mcpServers;
777
757
  if (settingsServers && typeof settingsServers === "object") {
778
758
  for (const name of Object.keys(settingsServers)) serverNames.add(name);
779
759
  }
780
- const mcpJsonPath = join3(root, ".mcp.json");
760
+ const mcpJsonPath = join2(root, ".mcp.json");
781
761
  try {
782
- const mcpJson = JSON.parse(await readFile3(mcpJsonPath, "utf-8"));
762
+ const mcpJson = JSON.parse(await readFile2(mcpJsonPath, "utf-8"));
783
763
  const mcpServers = mcpJson.mcpServers;
784
764
  if (mcpServers && typeof mcpServers === "object") {
785
765
  for (const name of Object.keys(mcpServers)) serverNames.add(name);
@@ -864,7 +844,7 @@ var FIX_TABLE = [
864
844
  { analyzer: "Memory", match: "SessionEnd push hook is not nohup-wrapped", fix: (root) => upgradeStaleSessionEndPushHook(root) },
865
845
  { analyzer: "Memory", match: "CLAUDE.md missing memory guidance", fix: (root, _det, placement) => {
866
846
  const content = "Use agentic-memory to persist knowledge across sessions:\n- Memories are automatically injected at session start\n- STORE IMMEDIATELY when: a dependency strategy changes, an architecture decision is made, a convention is established, a bug pattern is discovered, or a feature is killed/added\n- Use memory_search before memory_store to check for duplicates\n- NEVER store credentials, API keys, tokens, or secrets in memories";
867
- const target = placement === "local" ? join4(root, ".claude", "CLAUDE.md") : void 0;
847
+ const target = placement === "local" ? join3(root, ".claude", "CLAUDE.md") : void 0;
868
848
  return addClaudeMdSection(root, "## Memory", wrapStub(content), target);
869
849
  } }
870
850
  ];
@@ -881,6 +861,7 @@ async function tryFix(issue, root, detected, placement) {
881
861
  }
882
862
  async function addHook(root, event, dedupKeyword, entry, successMsg) {
883
863
  const settings = await readSettingsJson(root);
864
+ if (settings === null) return false;
884
865
  const hooks = settings.hooks ?? {};
885
866
  const hookList = hooks[event] ?? [];
886
867
  const alreadyHas = hookList.some((g) => {
@@ -954,6 +935,7 @@ async function addSessionStartHook(root) {
954
935
  }
955
936
  async function migrateAttribution(root) {
956
937
  const settings = await readSettingsJson(root);
938
+ if (settings === null) return false;
957
939
  if (settings.includeCoAuthoredBy === void 0) return false;
958
940
  const { includeCoAuthoredBy: _, ...rest } = settings;
959
941
  const updated = { ...rest, attribution: { commit: "", pr: "" } };
@@ -963,6 +945,7 @@ async function migrateAttribution(root) {
963
945
  }
964
946
  async function addCredentialDenyRules(root) {
965
947
  const settings = await readSettingsJson(root);
948
+ if (settings === null) return false;
966
949
  const permissions = settings.permissions ?? {};
967
950
  const deny = permissions.deny ?? [];
968
951
  const toAdd = ["Read(~/.ssh/*)", "Read(~/.aws/*)", "Read(~/.npmrc)"];
@@ -975,6 +958,7 @@ async function addCredentialDenyRules(root) {
975
958
  }
976
959
  async function addBypassDisable(root) {
977
960
  const settings = await readSettingsJson(root);
961
+ if (settings === null) return false;
978
962
  if (settings.disableBypassPermissionsMode === "disable") return false;
979
963
  const updated = { ...settings, disableBypassPermissionsMode: "disable" };
980
964
  await writeSettingsJson(root, updated);
@@ -983,6 +967,7 @@ async function addBypassDisable(root) {
983
967
  }
984
968
  async function removeSandboxSettings(root) {
985
969
  const settings = await readSettingsJson(root);
970
+ if (settings === null) return false;
986
971
  if (settings.sandbox === void 0) return false;
987
972
  const { sandbox: _sandbox, ...rest } = settings;
988
973
  await writeSettingsJson(root, rest);
@@ -990,27 +975,27 @@ async function removeSandboxSettings(root) {
990
975
  return true;
991
976
  }
992
977
  async function addEnvToClaudeignore(root) {
993
- const ignorePath = join4(root, ".claudeignore");
978
+ const ignorePath = join3(root, ".claudeignore");
994
979
  let content;
995
980
  try {
996
- content = await readFile4(ignorePath, "utf-8");
981
+ content = await readFile3(ignorePath, "utf-8");
997
982
  } catch {
998
983
  return false;
999
984
  }
1000
985
  const lines = content.split("\n").map((l) => l.trim());
1001
986
  if (lines.some((l) => l === ".env" || l === ".env.*" || l === ".env*")) return false;
1002
- await writeFile2(ignorePath, content.trimEnd() + "\n.env\n.env.*\n");
987
+ await writeFile(ignorePath, content.trimEnd() + "\n.env\n.env.*\n");
1003
988
  log.success("Added .env to .claudeignore");
1004
989
  return true;
1005
990
  }
1006
991
  async function addClaudeMdSection(root, heading, content, targetPath) {
1007
- const claudeMdPath = targetPath ?? join4(root, "CLAUDE.md");
992
+ const claudeMdPath = targetPath ?? join3(root, "CLAUDE.md");
1008
993
  let existing;
1009
994
  try {
1010
- existing = await readFile4(claudeMdPath, "utf-8");
995
+ existing = await readFile3(claudeMdPath, "utf-8");
1011
996
  } catch {
1012
997
  if (!targetPath) return false;
1013
- await mkdir2(join4(root, ".claude"), { recursive: true });
998
+ await mkdir(join3(root, ".claude"), { recursive: true });
1014
999
  existing = "# Local Claude Config\n";
1015
1000
  }
1016
1001
  if (existing.includes(heading)) return false;
@@ -1022,20 +1007,20 @@ ${content}
1022
1007
 
1023
1008
  `;
1024
1009
  const updated = existing.slice(0, insertAt) + section + existing.slice(insertAt);
1025
- await writeFile2(claudeMdPath, updated);
1010
+ await writeFile(claudeMdPath, updated);
1026
1011
  const label = targetPath ? ".claude/CLAUDE.md" : "CLAUDE.md";
1027
1012
  log.success(`Added "${heading}" section to ${label}`);
1028
1013
  return true;
1029
1014
  }
1030
1015
  async function createBacklogMd(root) {
1031
- const backlogPath = join4(root, "BACKLOG.md");
1016
+ const backlogPath = join3(root, "BACKLOG.md");
1032
1017
  try {
1033
1018
  await access2(backlogPath);
1034
1019
  return false;
1035
1020
  } catch {
1036
1021
  }
1037
1022
  const name = root.split("/").pop() ?? "Project";
1038
- await writeFile2(backlogPath, `# ${name} - Backlog
1023
+ await writeFile(backlogPath, `# ${name} - Backlog
1039
1024
 
1040
1025
  > Features discussed but deferred. Pick up when relevant.
1041
1026
  > Priority: P0 = next sprint, P1 = soon, P2 = when relevant.
@@ -1044,14 +1029,14 @@ async function createBacklogMd(root) {
1044
1029
  return true;
1045
1030
  }
1046
1031
  async function createClaudeignore(root, detected) {
1047
- const ignorePath = join4(root, ".claudeignore");
1032
+ const ignorePath = join3(root, ".claudeignore");
1048
1033
  try {
1049
1034
  await access2(ignorePath);
1050
1035
  return false;
1051
1036
  } catch {
1052
1037
  }
1053
1038
  const content = generateClaudeignore(detected);
1054
- await writeFile2(ignorePath, content);
1039
+ await writeFile(ignorePath, content);
1055
1040
  log.success("Generated .claudeignore with language-specific ignore patterns");
1056
1041
  return true;
1057
1042
  }
@@ -1061,15 +1046,15 @@ var SKILL_AUTHORING_SECTION = `
1061
1046
  ${SKILL_AUTHORING_CONTENT}
1062
1047
  `;
1063
1048
  async function createStarterRules(root) {
1064
- const rulesDir = join4(root, ".claude", "rules");
1049
+ const rulesDir = join3(root, ".claude", "rules");
1065
1050
  try {
1066
1051
  await access2(rulesDir);
1067
1052
  return false;
1068
1053
  } catch {
1069
1054
  }
1070
- await mkdir2(rulesDir, { recursive: true });
1071
- await writeFile2(
1072
- join4(rulesDir, "conventions.md"),
1055
+ await mkdir(rulesDir, { recursive: true });
1056
+ await writeFile(
1057
+ join3(rulesDir, "conventions.md"),
1073
1058
  `# Project Conventions
1074
1059
 
1075
1060
  - Use conventional commits (feat:, fix:, docs:, refactor:, test:, chore:)
@@ -1082,36 +1067,36 @@ ${SKILL_AUTHORING_SECTION}`
1082
1067
  return true;
1083
1068
  }
1084
1069
  async function addSkillAuthoringConventions(root) {
1085
- const conventionsPath = join4(root, ".claude", "rules", "conventions.md");
1070
+ const conventionsPath = join3(root, ".claude", "rules", "conventions.md");
1086
1071
  let content;
1087
1072
  try {
1088
- content = await readFile4(conventionsPath, "utf-8");
1073
+ content = await readFile3(conventionsPath, "utf-8");
1089
1074
  } catch {
1090
1075
  return false;
1091
1076
  }
1092
1077
  if (/^##\s+Skill\s+Authoring/im.test(content)) return false;
1093
- await writeFile2(conventionsPath, content.trimEnd() + "\n" + SKILL_AUTHORING_SECTION);
1078
+ await writeFile(conventionsPath, content.trimEnd() + "\n" + SKILL_AUTHORING_SECTION);
1094
1079
  log.success("Added Skill Authoring section to .claude/rules/conventions.md");
1095
1080
  return true;
1096
1081
  }
1097
1082
  async function createEnhanceSkill(root) {
1098
- const skillDir = join4(root, ".claude", "skills", "lp-enhance");
1099
- const skillPath = join4(skillDir, "SKILL.md");
1100
- const globalPath = join4(homedir(), ".claude", "skills", "lp-enhance", "SKILL.md");
1101
- const legacyProject = join4(root, ".claude", "commands", "lp-enhance.md");
1102
- const legacyGlobal = join4(homedir(), ".claude", "commands", "lp-enhance.md");
1083
+ const skillDir = join3(root, ".claude", "skills", "lp-enhance");
1084
+ const skillPath = join3(skillDir, "SKILL.md");
1085
+ const globalPath = join3(homedir(), ".claude", "skills", "lp-enhance", "SKILL.md");
1086
+ const legacyProject = join3(root, ".claude", "commands", "lp-enhance.md");
1087
+ const legacyGlobal = join3(homedir(), ".claude", "commands", "lp-enhance.md");
1103
1088
  if (await fileExists(skillPath) || await fileExists(globalPath) || await fileExists(legacyProject) || await fileExists(legacyGlobal)) return false;
1104
- await mkdir2(skillDir, { recursive: true });
1105
- await writeFile2(skillPath, generateEnhanceSkill());
1089
+ await mkdir(skillDir, { recursive: true });
1090
+ await writeFile(skillPath, generateEnhanceSkill());
1106
1091
  log.success("Generated /lp-enhance skill (.claude/skills/lp-enhance/)");
1107
1092
  return true;
1108
1093
  }
1109
1094
  async function updateEnhanceSkill(root) {
1110
- const projectPath = join4(root, ".claude", "skills", "lp-enhance", "SKILL.md");
1111
- const globalPath = join4(homedir(), ".claude", "skills", "lp-enhance", "SKILL.md");
1095
+ const projectPath = join3(root, ".claude", "skills", "lp-enhance", "SKILL.md");
1096
+ const globalPath = join3(homedir(), ".claude", "skills", "lp-enhance", "SKILL.md");
1112
1097
  const targetPath = await fileExists(projectPath) ? projectPath : await fileExists(globalPath) ? globalPath : null;
1113
1098
  if (!targetPath) return false;
1114
- await writeFile2(targetPath, generateEnhanceSkill());
1099
+ await writeFile(targetPath, generateEnhanceSkill());
1115
1100
  log.success("Updated /lp-enhance skill to latest version");
1116
1101
  return true;
1117
1102
  }
@@ -1140,10 +1125,16 @@ var colors = {
1140
1125
  return map[sev](` ${sev.toUpperCase()} `);
1141
1126
  }
1142
1127
  };
1128
+ var warnedKeys = /* @__PURE__ */ new Set();
1143
1129
  var log = {
1144
1130
  success: (msg) => console.log(` ${chalk.green("\u2713")} ${msg}`),
1145
1131
  error: (msg) => console.log(` ${chalk.red("\u2717")} ${msg}`),
1146
1132
  warn: (msg) => console.log(` ${chalk.yellow("!")} ${msg}`),
1133
+ warnOnce: (key, msg) => {
1134
+ if (warnedKeys.has(key)) return;
1135
+ warnedKeys.add(key);
1136
+ console.log(` ${chalk.yellow("!")} ${msg}`);
1137
+ },
1147
1138
  step: (msg) => console.log(` ${chalk.cyan("\u2192")} ${msg}`),
1148
1139
  info: (msg) => console.log(` ${chalk.dim("\xB7")} ${msg}`),
1149
1140
  blank: () => console.log()
@@ -1212,6 +1203,41 @@ function renderDoctorReport(results, options) {
1212
1203
  return { overallScore, actionableCount: actionable.length };
1213
1204
  }
1214
1205
 
1206
+ // src/lib/settings.ts
1207
+ async function readJsonFile(path) {
1208
+ let raw;
1209
+ try {
1210
+ raw = await readFile4(path, "utf-8");
1211
+ } catch (err) {
1212
+ const code = err.code;
1213
+ if (code === "ENOENT") return {};
1214
+ log.warnOnce(`read:${path}`, `Could not read ${path}: ${err.message}`);
1215
+ return null;
1216
+ }
1217
+ try {
1218
+ return JSON.parse(raw);
1219
+ } catch (err) {
1220
+ log.warnOnce(`parse:${path}`, `${path} is not valid JSON: ${err.message}. Treating as unreadable to avoid clobbering it.`);
1221
+ return null;
1222
+ }
1223
+ }
1224
+ async function readSettingsJson(root) {
1225
+ return readJsonFile(join4(root, ".claude", "settings.json"));
1226
+ }
1227
+ async function writeSettingsJson(root, settings) {
1228
+ const dir = join4(root, ".claude");
1229
+ await mkdir2(dir, { recursive: true });
1230
+ await writeFile2(join4(dir, "settings.json"), JSON.stringify(settings, null, 2) + "\n");
1231
+ }
1232
+ async function readSettingsLocalJson(root) {
1233
+ return readJsonFile(join4(root, ".claude", "settings.local.json"));
1234
+ }
1235
+ async function writeSettingsLocalJson(root, settings) {
1236
+ const dir = join4(root, ".claude");
1237
+ await mkdir2(dir, { recursive: true });
1238
+ await writeFile2(join4(dir, "settings.local.json"), JSON.stringify(settings, null, 2) + "\n");
1239
+ }
1240
+
1215
1241
  export {
1216
1242
  __export,
1217
1243
  SESSION_START_CONTENT,
@@ -1237,4 +1263,4 @@ export {
1237
1263
  printScoreCard,
1238
1264
  renderDoctorReport
1239
1265
  };
1240
- //# sourceMappingURL=chunk-7QPZN27I.js.map
1266
+ //# sourceMappingURL=chunk-IY3Z54UK.js.map