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.
- package/dist/{chunk-MDR73QT2.js → chunk-COGKNJJB.js} +2 -2
- package/dist/{chunk-NJQ2JFGF.js → chunk-H2E7QMF4.js} +2 -2
- package/dist/{chunk-7QPZN27I.js → chunk-IY3Z54UK.js} +143 -117
- package/dist/chunk-IY3Z54UK.js.map +1 -0
- package/dist/{chunk-MIHOPQP4.js → chunk-RDID5P4K.js} +2 -2
- package/dist/{chunk-GY3SK66Y.js → chunk-THDBKJAV.js} +3 -3
- package/dist/cli.js +68 -30
- package/dist/cli.js.map +1 -1
- package/dist/commands/memory/server.js +3 -3
- package/dist/{context-XTPBYGKW.js → context-BCTOCTZD.js} +5 -5
- package/dist/{install-MQDN7TLA.js → install-L23C4YWJ.js} +9 -5
- package/dist/install-L23C4YWJ.js.map +1 -0
- package/dist/{pull-ELZGXQPJ.js → pull-5KYLJ6TH.js} +7 -7
- package/dist/{push-HJXEC7XC.js → push-UOVLT5HO.js} +7 -7
- package/dist/{require-deps-3B3NWAEP.js → require-deps-T2QOGQQ3.js} +3 -3
- package/dist/{stats-S3GNMUDF.js → stats-GL7P24U7.js} +6 -6
- package/dist/{sync-clean-XNMLP3FZ.js → sync-clean-7RNYS7EH.js} +3 -3
- package/dist/{sync-status-4AGU776A.js → sync-status-ULZCMBQJ.js} +7 -7
- package/dist/{tui-CGXGXU5U.js → tui-UGBWF2WT.js} +4 -4
- package/package.json +1 -1
- package/dist/chunk-7QPZN27I.js.map +0 -1
- package/dist/install-MQDN7TLA.js.map +0 -1
- /package/dist/{chunk-MDR73QT2.js.map → chunk-COGKNJJB.js.map} +0 -0
- /package/dist/{chunk-NJQ2JFGF.js.map → chunk-H2E7QMF4.js.map} +0 -0
- /package/dist/{chunk-MIHOPQP4.js.map → chunk-RDID5P4K.js.map} +0 -0
- /package/dist/{chunk-GY3SK66Y.js.map → chunk-THDBKJAV.js.map} +0 -0
- /package/dist/{context-XTPBYGKW.js.map → context-BCTOCTZD.js.map} +0 -0
- /package/dist/{pull-ELZGXQPJ.js.map → pull-5KYLJ6TH.js.map} +0 -0
- /package/dist/{push-HJXEC7XC.js.map → push-UOVLT5HO.js.map} +0 -0
- /package/dist/{require-deps-3B3NWAEP.js.map → require-deps-T2QOGQQ3.js.map} +0 -0
- /package/dist/{stats-S3GNMUDF.js.map → stats-GL7P24U7.js.map} +0 -0
- /package/dist/{sync-clean-XNMLP3FZ.js.map → sync-clean-7RNYS7EH.js.map} +0 -0
- /package/dist/{sync-status-4AGU776A.js.map → sync-status-ULZCMBQJ.js.map} +0 -0
- /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-
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
|
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
|
|
105
|
-
import { join as
|
|
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
|
|
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(
|
|
121
|
-
fileExists(
|
|
122
|
-
readFileOrNull(
|
|
123
|
-
fileExists(
|
|
124
|
-
fileExists(
|
|
125
|
-
fileExists(
|
|
126
|
-
readJsonOrNull(
|
|
127
|
-
fileExists(
|
|
128
|
-
fileExists(
|
|
129
|
-
fileExists(
|
|
130
|
-
fileExists(
|
|
131
|
-
fileExists(
|
|
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(
|
|
213
|
-
fileExists(
|
|
214
|
-
fileExists(
|
|
215
|
-
fileExists(
|
|
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
|
|
633
|
-
import { join as
|
|
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 =
|
|
760
|
+
const mcpJsonPath = join2(root, ".mcp.json");
|
|
781
761
|
try {
|
|
782
|
-
const mcpJson = JSON.parse(await
|
|
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" ?
|
|
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 =
|
|
978
|
+
const ignorePath = join3(root, ".claudeignore");
|
|
994
979
|
let content;
|
|
995
980
|
try {
|
|
996
|
-
content = await
|
|
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
|
|
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 ??
|
|
992
|
+
const claudeMdPath = targetPath ?? join3(root, "CLAUDE.md");
|
|
1008
993
|
let existing;
|
|
1009
994
|
try {
|
|
1010
|
-
existing = await
|
|
995
|
+
existing = await readFile3(claudeMdPath, "utf-8");
|
|
1011
996
|
} catch {
|
|
1012
997
|
if (!targetPath) return false;
|
|
1013
|
-
await
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
1071
|
-
await
|
|
1072
|
-
|
|
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 =
|
|
1070
|
+
const conventionsPath = join3(root, ".claude", "rules", "conventions.md");
|
|
1086
1071
|
let content;
|
|
1087
1072
|
try {
|
|
1088
|
-
content = await
|
|
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
|
|
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 =
|
|
1099
|
-
const skillPath =
|
|
1100
|
-
const globalPath =
|
|
1101
|
-
const legacyProject =
|
|
1102
|
-
const legacyGlobal =
|
|
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
|
|
1105
|
-
await
|
|
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 =
|
|
1111
|
-
const globalPath =
|
|
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
|
|
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-
|
|
1266
|
+
//# sourceMappingURL=chunk-IY3Z54UK.js.map
|