claude-launchpad 0.10.1-dev.4 → 0.10.1-dev.5
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/README.md +10 -8
- package/dist/{chunk-7YDBTED2.js → chunk-HVWGJSU5.js} +88 -21
- package/dist/chunk-HVWGJSU5.js.map +1 -0
- package/dist/cli.js +6 -6
- package/dist/cli.js.map +1 -1
- package/dist/commands/memory/server.js +1 -1
- package/dist/commands/memory/server.js.map +1 -1
- package/dist/pull-6WBOOER2.js +109 -0
- package/dist/pull-6WBOOER2.js.map +1 -0
- package/dist/push-XLL3FQ32.js +141 -0
- package/dist/push-XLL3FQ32.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-7YDBTED2.js.map +0 -1
- package/dist/pull-MPBJHZIP.js +0 -71
- package/dist/pull-MPBJHZIP.js.map +0 -1
- package/dist/push-GRCPUMV6.js +0 -114
- package/dist/push-GRCPUMV6.js.map +0 -1
package/README.md
CHANGED
|
@@ -193,7 +193,7 @@ Results save to `.claude/eval/` as structured markdown. Feed them back to Claude
|
|
|
193
193
|
|
|
194
194
|
## Memory
|
|
195
195
|
|
|
196
|
-
Optional persistent memory that replaces Claude Code's built-in flat-file
|
|
196
|
+
Optional persistent memory that replaces Claude Code's built-in flat-file system. Memories decay naturally, so stale knowledge fades and relevant context stays.
|
|
197
197
|
|
|
198
198
|
```bash
|
|
199
199
|
claude-launchpad memory
|
|
@@ -202,23 +202,25 @@ claude-launchpad memory
|
|
|
202
202
|
If memory is not installed, it runs interactive setup. If installed, it shows stats. Requires native deps first: `npm install better-sqlite3 sqlite-vec`.
|
|
203
203
|
|
|
204
204
|
**What it does:**
|
|
205
|
-
- **Smart session injection**
|
|
205
|
+
- **Smart session injection** loads the most relevant memories at session start
|
|
206
206
|
- **Stop hook** extracts facts from the conversation when you finish
|
|
207
207
|
- **Decay model** fades memories naturally (episodic: 60 days, semantic: 1 year, procedural: 2 years)
|
|
208
208
|
- **Self-tuning retrieval** promotes memories Claude searches for, demotes ones injected but never used
|
|
209
209
|
- **Project-scoped** with no cross-contamination between projects
|
|
210
210
|
- **TUI dashboard** (`--dashboard`) with vim navigation, filtering, and search
|
|
211
|
-
- **Cross-device sync**
|
|
211
|
+
- **Cross-device sync** pushes and pulls memories between machines via private GitHub Gist
|
|
212
212
|
|
|
213
|
-
Data stays in `~/.agentic-memory/memory.db`. Sync is opt-in
|
|
213
|
+
Data stays in `~/.agentic-memory/memory.db`. Sync is opt-in via `gh` CLI.
|
|
214
214
|
|
|
215
215
|
| Flag / Subcommand | What it does |
|
|
216
216
|
|---|---|
|
|
217
217
|
| `--dashboard` | Opens the interactive TUI dashboard |
|
|
218
|
-
| `push` | Push memories to a private GitHub Gist |
|
|
219
|
-
| `pull` | Pull memories from a private GitHub Gist |
|
|
220
|
-
| `push --
|
|
221
|
-
| `pull --
|
|
218
|
+
| `push` | Push current project's memories to a private GitHub Gist |
|
|
219
|
+
| `pull` | Pull current project's memories from a private GitHub Gist |
|
|
220
|
+
| `push --all` | Push all projects |
|
|
221
|
+
| `pull --all` | Pull all projects |
|
|
222
|
+
|
|
223
|
+
Sync stores one file per project inside a single private gist. Push/pull auto-detects the current project from your working directory. On a new device, the gist is auto-discovered from your GitHub account (no config to copy).
|
|
222
224
|
|
|
223
225
|
## Use in CI
|
|
224
226
|
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
SyncPayloadSchema
|
|
4
|
+
} from "./chunk-J5NT4JGE.js";
|
|
2
5
|
import {
|
|
3
6
|
DEFAULT_CONFIG,
|
|
4
7
|
resolveDataDir
|
|
@@ -10,11 +13,30 @@ import { readFileSync, writeFileSync, unlinkSync, mkdirSync } from "fs";
|
|
|
10
13
|
import { join, dirname } from "path";
|
|
11
14
|
import { tmpdir } from "os";
|
|
12
15
|
var EXEC_OPTS = { encoding: "utf-8", timeout: 3e4 };
|
|
13
|
-
var
|
|
16
|
+
var GIST_DESCRIPTION = "agentic-memory sync";
|
|
14
17
|
var SYNC_CONFIG_FILE = "sync-config.json";
|
|
15
18
|
function syncConfigPath() {
|
|
16
19
|
return join(resolveDataDir(DEFAULT_CONFIG.dataDir), SYNC_CONFIG_FILE);
|
|
17
20
|
}
|
|
21
|
+
function slugify(project) {
|
|
22
|
+
return project.replace(/[^a-zA-Z0-9._-]/g, "-");
|
|
23
|
+
}
|
|
24
|
+
function projectToFilename(project) {
|
|
25
|
+
if (!project) throw new Error("Project name cannot be empty");
|
|
26
|
+
return `memories-${slugify(project)}.json`;
|
|
27
|
+
}
|
|
28
|
+
function filenameToProject(filename) {
|
|
29
|
+
const match = filename.match(/^memories-(.+)\.json$/);
|
|
30
|
+
return match?.[1] ?? null;
|
|
31
|
+
}
|
|
32
|
+
function parsePayload(raw) {
|
|
33
|
+
if (!raw || raw === "null") return null;
|
|
34
|
+
try {
|
|
35
|
+
return SyncPayloadSchema.parse(JSON.parse(raw));
|
|
36
|
+
} catch {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
18
40
|
function assertGhAvailable() {
|
|
19
41
|
try {
|
|
20
42
|
execSync("gh --version", { ...EXEC_OPTS, stdio: "pipe" });
|
|
@@ -38,26 +60,50 @@ function loadSyncConfig() {
|
|
|
38
60
|
if (typeof parsed.gistId === "string" && parsed.gistId.length > 0) {
|
|
39
61
|
return { gistId: parsed.gistId };
|
|
40
62
|
}
|
|
41
|
-
return null;
|
|
42
63
|
} catch {
|
|
43
|
-
return null;
|
|
44
64
|
}
|
|
65
|
+
const discovered = discoverSyncGist();
|
|
66
|
+
if (discovered) {
|
|
67
|
+
saveSyncConfig({ gistId: discovered });
|
|
68
|
+
return { gistId: discovered };
|
|
69
|
+
}
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
function discoverSyncGist() {
|
|
73
|
+
try {
|
|
74
|
+
const output = execSync(
|
|
75
|
+
"gh gist list --limit 100",
|
|
76
|
+
{ ...EXEC_OPTS, stdio: ["pipe", "pipe", "pipe"] }
|
|
77
|
+
);
|
|
78
|
+
for (const line of output.split("\n")) {
|
|
79
|
+
const cols = line.split(" ");
|
|
80
|
+
if (cols[1]?.trim() === GIST_DESCRIPTION) {
|
|
81
|
+
const gistId = cols[0]?.trim();
|
|
82
|
+
if (gistId && /^[a-f0-9]+$/.test(gistId)) return gistId;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
} catch {
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
45
88
|
}
|
|
46
89
|
function saveSyncConfig(config) {
|
|
47
90
|
const filePath = syncConfigPath();
|
|
48
91
|
mkdirSync(dirname(filePath), { recursive: true });
|
|
49
92
|
writeFileSync(filePath, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
50
93
|
}
|
|
51
|
-
function createGist(
|
|
52
|
-
const
|
|
94
|
+
function createGist(filename, content) {
|
|
95
|
+
const safeFilename = slugify(filename.replace(/\.json$/, "")) + ".json";
|
|
96
|
+
const tmpFile = join(tmpdir(), safeFilename);
|
|
53
97
|
try {
|
|
54
|
-
writeFileSync(tmpFile,
|
|
98
|
+
writeFileSync(tmpFile, content, "utf-8");
|
|
55
99
|
const result = execSync(
|
|
56
|
-
`gh gist create "${tmpFile}" --desc "
|
|
100
|
+
`gh gist create "${tmpFile}" --desc "${GIST_DESCRIPTION}" --public=false`,
|
|
57
101
|
{ ...EXEC_OPTS, stdio: ["pipe", "pipe", "pipe"] }
|
|
58
102
|
).trim();
|
|
59
|
-
const gistId = result.split("/").pop() ?? "";
|
|
60
|
-
if (!gistId
|
|
103
|
+
const gistId = result.split("/").pop()?.trim() ?? "";
|
|
104
|
+
if (!gistId || !/^[a-f0-9]+$/.test(gistId)) {
|
|
105
|
+
throw new Error(`Failed to parse gist ID from: ${result}`);
|
|
106
|
+
}
|
|
61
107
|
saveSyncConfig({ gistId });
|
|
62
108
|
return gistId;
|
|
63
109
|
} finally {
|
|
@@ -67,22 +113,39 @@ function createGist(payload) {
|
|
|
67
113
|
}
|
|
68
114
|
}
|
|
69
115
|
}
|
|
70
|
-
function
|
|
116
|
+
function readGistFile(gistId, filename) {
|
|
71
117
|
try {
|
|
118
|
+
const escapedFilename = JSON.stringify(filename);
|
|
72
119
|
return execSync(
|
|
73
|
-
`gh
|
|
120
|
+
`gh api "/gists/${gistId}" --jq '.files[${escapedFilename}].content'`,
|
|
74
121
|
{ ...EXEC_OPTS, stdio: ["pipe", "pipe", "pipe"] }
|
|
75
|
-
);
|
|
122
|
+
).trimEnd();
|
|
76
123
|
} catch {
|
|
77
124
|
return null;
|
|
78
125
|
}
|
|
79
126
|
}
|
|
80
|
-
function
|
|
81
|
-
|
|
127
|
+
function listGistFiles(gistId) {
|
|
128
|
+
try {
|
|
129
|
+
const output = execSync(
|
|
130
|
+
`gh api "/gists/${gistId}" --jq '.files | keys[]'`,
|
|
131
|
+
{ ...EXEC_OPTS, stdio: ["pipe", "pipe", "pipe"] }
|
|
132
|
+
);
|
|
133
|
+
return output.trim().split("\n").filter(Boolean);
|
|
134
|
+
} catch {
|
|
135
|
+
return [];
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
function updateGistFiles(gistId, files) {
|
|
139
|
+
const payload = {
|
|
140
|
+
files: Object.fromEntries(
|
|
141
|
+
Object.entries(files).map(([name, content]) => [name, { content }])
|
|
142
|
+
)
|
|
143
|
+
};
|
|
144
|
+
const tmpFile = join(tmpdir(), `gist-patch-${Date.now()}.json`);
|
|
82
145
|
try {
|
|
83
|
-
writeFileSync(tmpFile, payload, "utf-8");
|
|
146
|
+
writeFileSync(tmpFile, JSON.stringify(payload), "utf-8");
|
|
84
147
|
execSync(
|
|
85
|
-
`gh
|
|
148
|
+
`gh api --method PATCH "/gists/${gistId}" --input "${tmpFile}"`,
|
|
86
149
|
{ ...EXEC_OPTS, stdio: ["pipe", "pipe", "pipe"] }
|
|
87
150
|
);
|
|
88
151
|
} finally {
|
|
@@ -112,11 +175,11 @@ function memoryToSyncRow(m) {
|
|
|
112
175
|
last_accessed: m.lastAccessed
|
|
113
176
|
};
|
|
114
177
|
}
|
|
115
|
-
function mergeFromRemote(memoryRepo, relationRepo, payload
|
|
178
|
+
function mergeFromRemote(memoryRepo, relationRepo, payload) {
|
|
116
179
|
let inserted = 0;
|
|
117
180
|
let updated = 0;
|
|
118
181
|
let relationsAdded = 0;
|
|
119
|
-
const memories =
|
|
182
|
+
const memories = payload.memories;
|
|
120
183
|
for (const remote of memories) {
|
|
121
184
|
const local = memoryRepo.getById(remote.id);
|
|
122
185
|
if (!local) {
|
|
@@ -143,12 +206,16 @@ function mergeFromRemote(memoryRepo, relationRepo, payload, project) {
|
|
|
143
206
|
}
|
|
144
207
|
|
|
145
208
|
export {
|
|
209
|
+
projectToFilename,
|
|
210
|
+
filenameToProject,
|
|
211
|
+
parsePayload,
|
|
146
212
|
assertGhAvailable,
|
|
147
213
|
loadSyncConfig,
|
|
148
214
|
createGist,
|
|
149
|
-
|
|
150
|
-
|
|
215
|
+
readGistFile,
|
|
216
|
+
listGistFiles,
|
|
217
|
+
updateGistFiles,
|
|
151
218
|
memoryToSyncRow,
|
|
152
219
|
mergeFromRemote
|
|
153
220
|
};
|
|
154
|
-
//# sourceMappingURL=chunk-
|
|
221
|
+
//# sourceMappingURL=chunk-HVWGJSU5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/memory/utils/gist-transport.ts","../src/commands/memory/utils/sync-merge.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport { readFileSync, writeFileSync, unlinkSync, mkdirSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { tmpdir } from 'node:os';\nimport { resolveDataDir, DEFAULT_CONFIG } from '../config.js';\nimport { SyncPayloadSchema } from '../types.js';\nimport type { SyncConfig, SyncPayload } from '../types.js';\n\nconst EXEC_OPTS = { encoding: 'utf-8' as const, timeout: 30_000 };\nconst GIST_DESCRIPTION = 'agentic-memory sync';\nconst SYNC_CONFIG_FILE = 'sync-config.json';\n\nfunction syncConfigPath(): string {\n return join(resolveDataDir(DEFAULT_CONFIG.dataDir), SYNC_CONFIG_FILE);\n}\n\nfunction slugify(project: string): string {\n return project.replace(/[^a-zA-Z0-9._-]/g, '-');\n}\n\nexport function projectToFilename(project: string): string {\n if (!project) throw new Error('Project name cannot be empty');\n return `memories-${slugify(project)}.json`;\n}\n\nexport function filenameToProject(filename: string): string | null {\n const match = filename.match(/^memories-(.+)\\.json$/);\n return match?.[1] ?? null;\n}\n\nexport function parsePayload(raw: string | null): SyncPayload | null {\n if (!raw || raw === 'null') return null;\n try { return SyncPayloadSchema.parse(JSON.parse(raw)); }\n catch { return null; }\n}\n\nexport function assertGhAvailable(): void {\n try {\n execSync('gh --version', { ...EXEC_OPTS, stdio: 'pipe' });\n } catch {\n throw new Error(\n 'Memory sync requires the GitHub CLI.\\n' +\n 'Install: https://cli.github.com/\\n' +\n 'Then run: gh auth login'\n );\n }\n try {\n execSync('gh auth status', { ...EXEC_OPTS, stdio: 'pipe' });\n } catch {\n throw new Error(\n 'gh is installed but not authenticated.\\n' +\n 'Run: gh auth login'\n );\n }\n}\n\nexport function loadSyncConfig(): SyncConfig | null {\n try {\n const raw = readFileSync(syncConfigPath(), 'utf-8');\n const parsed = JSON.parse(raw) as Record<string, unknown>;\n if (typeof parsed.gistId === 'string' && parsed.gistId.length > 0) {\n return { gistId: parsed.gistId };\n }\n } catch { /* no local config */ }\n\n const discovered = discoverSyncGist();\n if (discovered) {\n saveSyncConfig({ gistId: discovered });\n return { gistId: discovered };\n }\n return null;\n}\n\nfunction discoverSyncGist(): string | null {\n try {\n const output = execSync(\n 'gh gist list --limit 100',\n { ...EXEC_OPTS, stdio: ['pipe', 'pipe', 'pipe'] },\n );\n for (const line of output.split('\\n')) {\n const cols = line.split('\\t');\n if (cols[1]?.trim() === GIST_DESCRIPTION) {\n const gistId = cols[0]?.trim();\n if (gistId && /^[a-f0-9]+$/.test(gistId)) return gistId;\n }\n }\n } catch { /* gh list failed */ }\n return null;\n}\n\nexport function saveSyncConfig(config: SyncConfig): void {\n const filePath = syncConfigPath();\n mkdirSync(dirname(filePath), { recursive: true });\n writeFileSync(filePath, JSON.stringify(config, null, 2) + '\\n', 'utf-8');\n}\n\nexport function createGist(filename: string, content: string): string {\n const safeFilename = slugify(filename.replace(/\\.json$/, '')) + '.json';\n const tmpFile = join(tmpdir(), safeFilename);\n try {\n writeFileSync(tmpFile, content, 'utf-8');\n const result = execSync(\n `gh gist create \"${tmpFile}\" --desc \"${GIST_DESCRIPTION}\" --public=false`,\n { ...EXEC_OPTS, stdio: ['pipe', 'pipe', 'pipe'] },\n ).trim();\n const gistId = result.split('/').pop()?.trim() ?? '';\n if (!gistId || !/^[a-f0-9]+$/.test(gistId)) {\n throw new Error(`Failed to parse gist ID from: ${result}`);\n }\n saveSyncConfig({ gistId });\n return gistId;\n } finally {\n try { unlinkSync(tmpFile); } catch { /* ignore */ }\n }\n}\n\nexport function readGistFile(gistId: string, filename: string): string | null {\n try {\n const escapedFilename = JSON.stringify(filename);\n return execSync(\n `gh api \"/gists/${gistId}\" --jq '.files[${escapedFilename}].content'`,\n { ...EXEC_OPTS, stdio: ['pipe', 'pipe', 'pipe'] },\n ).trimEnd();\n } catch {\n return null;\n }\n}\n\nexport function listGistFiles(gistId: string): readonly string[] {\n try {\n const output = execSync(\n `gh api \"/gists/${gistId}\" --jq '.files | keys[]'`,\n { ...EXEC_OPTS, stdio: ['pipe', 'pipe', 'pipe'] },\n );\n return output.trim().split('\\n').filter(Boolean);\n } catch {\n return [];\n }\n}\n\nexport function updateGistFiles(\n gistId: string,\n files: Record<string, string>,\n): void {\n const payload = {\n files: Object.fromEntries(\n Object.entries(files).map(([name, content]) => [name, { content }]),\n ),\n };\n const tmpFile = join(tmpdir(), `gist-patch-${Date.now()}.json`);\n try {\n writeFileSync(tmpFile, JSON.stringify(payload), 'utf-8');\n execSync(\n `gh api --method PATCH \"/gists/${gistId}\" --input \"${tmpFile}\"`,\n { ...EXEC_OPTS, stdio: ['pipe', 'pipe', 'pipe'] },\n );\n } finally {\n try { unlinkSync(tmpFile); } catch { /* ignore */ }\n }\n}\n","import type { Memory, SyncPayload, SyncMemoryRow, MergeResult, RelationType } from '../types.js';\nimport type { MemoryRepo } from '../storage/memory-repo.js';\nimport type { RelationRepo } from '../storage/relation-repo.js';\n\nfunction memoryToSyncRow(m: Memory): SyncMemoryRow {\n return {\n id: m.id,\n type: m.type,\n title: m.title,\n content: m.content,\n context: m.context,\n source: m.source,\n project: m.project,\n tags: [...m.tags],\n importance: m.importance,\n access_count: m.accessCount,\n injection_count: m.injectionCount,\n created_at: m.createdAt,\n updated_at: m.updatedAt,\n last_accessed: m.lastAccessed,\n };\n}\n\nexport { memoryToSyncRow };\n\nexport function mergeFromRemote(\n memoryRepo: MemoryRepo,\n relationRepo: RelationRepo,\n payload: SyncPayload,\n): MergeResult {\n let inserted = 0;\n let updated = 0;\n let relationsAdded = 0;\n\n const memories = payload.memories;\n\n for (const remote of memories) {\n const local = memoryRepo.getById(remote.id);\n if (!local) {\n memoryRepo.upsertFromSync(remote);\n inserted++;\n } else if (remote.updated_at > local.updatedAt) {\n memoryRepo.upsertFromSync(remote);\n updated++;\n }\n }\n\n const localIds = new Set(memoryRepo.getAll().map((m) => m.id));\n const relations = payload.relations.filter(\n (r) => localIds.has(r.source_id) && localIds.has(r.target_id),\n );\n\n for (const rel of relations) {\n const added = relationRepo.create(\n rel.source_id,\n rel.target_id,\n rel.relation_type as RelationType,\n );\n if (added) relationsAdded++;\n }\n\n return { inserted, updated, relationsAdded };\n}\n"],"mappings":"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","names":[]}
|
package/dist/cli.js
CHANGED
|
@@ -1558,7 +1558,7 @@ var FIX_TABLE = [
|
|
|
1558
1558
|
{ analyzer: "Hooks", match: "SessionStart", fix: (root) => addSessionStartHook(root) },
|
|
1559
1559
|
{ analyzer: "Memory", match: "autoMemoryEnabled not disabled", fix: (root) => disableAutoMemory(root) },
|
|
1560
1560
|
{ analyzer: "Memory", match: "MCP tool permission", fix: (root) => addMemoryToolPermissions(root) },
|
|
1561
|
-
{ analyzer: "Memory", match: "CLAUDE.md missing memory guidance", fix: (root) => addClaudeMdSection(root, "## Memory", "Use agentic-memory to persist knowledge across sessions:\n- Memories are automatically injected at session start and extracted at session end\n- Save non-obvious decisions, gotchas, and deferred issues\n- Check memory for relevant context before starting work") }
|
|
1561
|
+
{ analyzer: "Memory", match: "CLAUDE.md missing memory guidance", fix: (root) => addClaudeMdSection(root, "## Memory", "Use agentic-memory to persist knowledge across sessions:\n- Memories are automatically injected at session start and extracted at session end\n- Save non-obvious decisions, gotchas, and deferred issues\n- NEVER store credentials, API keys, tokens, or secrets in memories\n- Check memory for relevant context before starting work") }
|
|
1562
1562
|
];
|
|
1563
1563
|
async function tryFix(issue, root, detected) {
|
|
1564
1564
|
const entry = FIX_TABLE.find(
|
|
@@ -2640,14 +2640,14 @@ function createMemoryCommand() {
|
|
|
2640
2640
|
{ hidden: true }
|
|
2641
2641
|
);
|
|
2642
2642
|
memory.addCommand(
|
|
2643
|
-
new Command4("push").description("Push memories to GitHub Gist").option("--
|
|
2644
|
-
const { runPush } = await import("./push-
|
|
2643
|
+
new Command4("push").description("Push current project's memories to GitHub Gist").option("--all", "Push all projects").option("-y, --yes", "Skip confirmation prompt").action(async (opts) => {
|
|
2644
|
+
const { runPush } = await import("./push-XLL3FQ32.js");
|
|
2645
2645
|
await runPush(opts);
|
|
2646
2646
|
})
|
|
2647
2647
|
);
|
|
2648
2648
|
memory.addCommand(
|
|
2649
|
-
new Command4("pull").description("Pull memories from GitHub Gist").option("--
|
|
2650
|
-
const { runPull } = await import("./pull-
|
|
2649
|
+
new Command4("pull").description("Pull current project's memories from GitHub Gist").option("--all", "Pull all projects").action(async (opts) => {
|
|
2650
|
+
const { runPull } = await import("./pull-6WBOOER2.js");
|
|
2651
2651
|
await runPull(opts);
|
|
2652
2652
|
})
|
|
2653
2653
|
);
|
|
@@ -2655,7 +2655,7 @@ function createMemoryCommand() {
|
|
|
2655
2655
|
}
|
|
2656
2656
|
|
|
2657
2657
|
// src/cli.ts
|
|
2658
|
-
var program = new Command5().name("claude-launchpad").description("CLI toolkit that makes Claude Code setups measurably good").version("0.10.1-dev.
|
|
2658
|
+
var program = new Command5().name("claude-launchpad").description("CLI toolkit that makes Claude Code setups measurably good").version("0.10.1-dev.5", "-v, --version").action(async () => {
|
|
2659
2659
|
const hasConfig = await fileExists(join11(process.cwd(), "CLAUDE.md")) || await fileExists(join11(process.cwd(), ".claude", "settings.json"));
|
|
2660
2660
|
if (hasConfig) {
|
|
2661
2661
|
await program.commands.find((c) => c.name() === "doctor")?.parseAsync([], { from: "user" });
|