agentpack-cli 0.1.0

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 (61) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +174 -0
  3. package/SECURITY.md +44 -0
  4. package/assets/agentpack-logo.jpg +0 -0
  5. package/dist/src/agentpack.d.ts +2 -0
  6. package/dist/src/agentpack.js +8 -0
  7. package/dist/src/agentpack.js.map +1 -0
  8. package/dist/src/cli/index.d.ts +3 -0
  9. package/dist/src/cli/index.js +412 -0
  10. package/dist/src/cli/index.js.map +1 -0
  11. package/dist/src/core/budget.d.ts +14 -0
  12. package/dist/src/core/budget.js +56 -0
  13. package/dist/src/core/budget.js.map +1 -0
  14. package/dist/src/core/checkpoints.d.ts +24 -0
  15. package/dist/src/core/checkpoints.js +93 -0
  16. package/dist/src/core/checkpoints.js.map +1 -0
  17. package/dist/src/core/doctor.d.ts +4 -0
  18. package/dist/src/core/doctor.js +304 -0
  19. package/dist/src/core/doctor.js.map +1 -0
  20. package/dist/src/core/git.d.ts +2 -0
  21. package/dist/src/core/git.js +34 -0
  22. package/dist/src/core/git.js.map +1 -0
  23. package/dist/src/core/hash.d.ts +5 -0
  24. package/dist/src/core/hash.js +29 -0
  25. package/dist/src/core/hash.js.map +1 -0
  26. package/dist/src/core/ids.d.ts +1 -0
  27. package/dist/src/core/ids.js +7 -0
  28. package/dist/src/core/ids.js.map +1 -0
  29. package/dist/src/core/presets.d.ts +12 -0
  30. package/dist/src/core/presets.js +24 -0
  31. package/dist/src/core/presets.js.map +1 -0
  32. package/dist/src/core/redaction.d.ts +4 -0
  33. package/dist/src/core/redaction.js +18 -0
  34. package/dist/src/core/redaction.js.map +1 -0
  35. package/dist/src/core/resume.d.ts +13 -0
  36. package/dist/src/core/resume.js +398 -0
  37. package/dist/src/core/resume.js.map +1 -0
  38. package/dist/src/core/store.d.ts +20 -0
  39. package/dist/src/core/store.js +240 -0
  40. package/dist/src/core/store.js.map +1 -0
  41. package/dist/src/core/types.d.ts +43 -0
  42. package/dist/src/core/types.js +2 -0
  43. package/dist/src/core/types.js.map +1 -0
  44. package/dist/src/integrations/install.d.ts +5 -0
  45. package/dist/src/integrations/install.js +361 -0
  46. package/dist/src/integrations/install.js.map +1 -0
  47. package/dist/src/mcp/server.d.ts +9 -0
  48. package/dist/src/mcp/server.js +347 -0
  49. package/dist/src/mcp/server.js.map +1 -0
  50. package/dist/src/operations.d.ts +29 -0
  51. package/dist/src/operations.js +199 -0
  52. package/dist/src/operations.js.map +1 -0
  53. package/docs/DOGFOOD.md +72 -0
  54. package/docs/INTEGRATIONS.md +183 -0
  55. package/docs/MCP.md +83 -0
  56. package/docs/MVP.md +97 -0
  57. package/docs/ROADMAP.md +129 -0
  58. package/docs/SETUP.md +56 -0
  59. package/docs/agentpack-flow.md +63 -0
  60. package/package.json +55 -0
  61. package/scripts/mcp-smoke.mjs +197 -0
@@ -0,0 +1,240 @@
1
+ import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync } from "node:fs";
2
+ import path from "node:path";
3
+ import { createId } from "./ids.js";
4
+ export const PACK_DIR = ".agentpack";
5
+ export const SCHEMA_VERSION = 1;
6
+ export const AGENTPACK_IGNORE_PATTERNS = [
7
+ `${PACK_DIR}/`,
8
+ ".codex",
9
+ ".claude",
10
+ ".mcp.json",
11
+ "AGENTS.md",
12
+ "CLAUDE.md"
13
+ ];
14
+ const LOCK_TIMEOUT_MS = 10_000;
15
+ const STALE_LOCK_MS = 5 * 60_000;
16
+ const heldLocks = new Set();
17
+ const sleepBuffer = new SharedArrayBuffer(4);
18
+ const sleepArray = new Int32Array(sleepBuffer);
19
+ export function findPackRoot(startDir) {
20
+ let current = path.resolve(startDir);
21
+ while (true) {
22
+ if (existsSync(path.join(current, PACK_DIR))) {
23
+ return current;
24
+ }
25
+ const parent = path.dirname(current);
26
+ if (parent === current) {
27
+ return null;
28
+ }
29
+ current = parent;
30
+ }
31
+ }
32
+ export function requirePackRoot(startDir) {
33
+ const root = findPackRoot(startDir);
34
+ if (!root) {
35
+ throw new Error("No .agentpack directory found. Run `agentpack init` first.");
36
+ }
37
+ return root;
38
+ }
39
+ export function initPack(root) {
40
+ const packPath = path.join(root, PACK_DIR);
41
+ const now = new Date().toISOString();
42
+ mkdirSync(packPath, { recursive: true });
43
+ for (const dir of ["checkpoints", "evidence", "instructions", "exports", "cache"]) {
44
+ mkdirSync(path.join(packPath, dir), { recursive: true });
45
+ }
46
+ writeJsonIfMissing(path.join(packPath, "config.json"), {
47
+ schemaVersion: SCHEMA_VERSION,
48
+ projectName: path.basename(root),
49
+ redactions: [
50
+ "OPENAI_API_KEY",
51
+ "ANTHROPIC_API_KEY",
52
+ "GITHUB_TOKEN",
53
+ "NPM_TOKEN"
54
+ ],
55
+ defaultBudget: 4000,
56
+ includeGitDiff: true
57
+ });
58
+ writeJsonIfMissing(path.join(packPath, "state.json"), {
59
+ schemaVersion: SCHEMA_VERSION,
60
+ goal: null,
61
+ currentStatus: "Initialized Agentpack.",
62
+ nextActions: [],
63
+ currentCheckpoint: null,
64
+ createdAt: now,
65
+ updatedAt: now
66
+ });
67
+ writeJsonIfMissing(path.join(packPath, "sources.json"), {
68
+ schemaVersion: SCHEMA_VERSION,
69
+ sources: []
70
+ });
71
+ if (!existsSync(path.join(packPath, "events.jsonl"))) {
72
+ writeFileSync(path.join(packPath, "events.jsonl"), "", "utf8");
73
+ }
74
+ ensurePackIgnored(root);
75
+ return packPath;
76
+ }
77
+ export function ensurePackIgnored(root) {
78
+ const gitignorePath = path.join(root, ".gitignore");
79
+ const existing = existsSync(gitignorePath) ? readFileSync(gitignorePath, "utf8") : "";
80
+ const lines = existing.split(/\r?\n/).map((line) => line.trim());
81
+ const missing = AGENTPACK_IGNORE_PATTERNS.filter((pattern) => !hasIgnorePattern(lines, pattern));
82
+ if (!missing.length) {
83
+ return;
84
+ }
85
+ const prefix = existing && !existing.endsWith("\n") ? "\n" : "";
86
+ writeFileSync(gitignorePath, `${existing}${prefix}${missing.join("\n")}\n`, "utf8");
87
+ }
88
+ function hasIgnorePattern(lines, pattern) {
89
+ const normalized = pattern.endsWith("/") ? pattern.slice(0, -1) : pattern;
90
+ return lines.some((line) => {
91
+ const normalizedLine = line.endsWith("/") ? line.slice(0, -1) : line;
92
+ return normalizedLine === normalized;
93
+ });
94
+ }
95
+ export function getPackPath(root, ...parts) {
96
+ return path.join(root, PACK_DIR, ...parts);
97
+ }
98
+ export function readJson(filePath, fallback) {
99
+ if (!existsSync(filePath)) {
100
+ return fallback;
101
+ }
102
+ return JSON.parse(readFileSync(filePath, "utf8"));
103
+ }
104
+ export function writeJson(filePath, value) {
105
+ writeTextFileAtomic(filePath, `${JSON.stringify(value, null, 2)}\n`);
106
+ }
107
+ export function writeJsonIfMissing(filePath, value) {
108
+ if (!existsSync(filePath)) {
109
+ writeJson(filePath, value);
110
+ }
111
+ }
112
+ export function readState(root) {
113
+ const state = readJson(getPackPath(root, "state.json"), null);
114
+ if (!state) {
115
+ throw new Error("Agentpack state.json is missing. Run `agentpack init` again.");
116
+ }
117
+ return state;
118
+ }
119
+ export function writeState(root, state) {
120
+ withPackWriteLock(root, () => {
121
+ writeJson(getPackPath(root, "state.json"), {
122
+ ...state,
123
+ updatedAt: new Date().toISOString()
124
+ });
125
+ });
126
+ }
127
+ export function readSources(root) {
128
+ return readJson(getPackPath(root, "sources.json"), { schemaVersion: SCHEMA_VERSION, sources: [] });
129
+ }
130
+ export function writeSources(root, sources) {
131
+ withPackWriteLock(root, () => {
132
+ writeJson(getPackPath(root, "sources.json"), sources);
133
+ });
134
+ }
135
+ export function appendEvent(root, type, payload = {}) {
136
+ const event = {
137
+ id: createId("evt"),
138
+ ts: new Date().toISOString(),
139
+ type,
140
+ ...payload
141
+ };
142
+ withPackWriteLock(root, () => {
143
+ writeFileSync(getPackPath(root, "events.jsonl"), `${JSON.stringify(event)}\n`, {
144
+ encoding: "utf8",
145
+ flag: "a"
146
+ });
147
+ });
148
+ return event;
149
+ }
150
+ export function readEvents(root) {
151
+ const content = readFileSync(getPackPath(root, "events.jsonl"), "utf8");
152
+ return content
153
+ .split("\n")
154
+ .filter(Boolean)
155
+ .map((line) => JSON.parse(line));
156
+ }
157
+ export function listCheckpoints(root) {
158
+ const checkpointsPath = getPackPath(root, "checkpoints");
159
+ if (!existsSync(checkpointsPath)) {
160
+ return [];
161
+ }
162
+ return readdirSync(checkpointsPath, { withFileTypes: true })
163
+ .filter((entry) => entry.isDirectory())
164
+ .map((entry) => entry.name)
165
+ .sort();
166
+ }
167
+ export function withPackWriteLock(root, fn) {
168
+ const lockPath = getPackPath(root, ".lock");
169
+ if (heldLocks.has(lockPath)) {
170
+ return fn();
171
+ }
172
+ acquireLock(lockPath);
173
+ heldLocks.add(lockPath);
174
+ try {
175
+ return fn();
176
+ }
177
+ finally {
178
+ heldLocks.delete(lockPath);
179
+ releaseLock(lockPath);
180
+ }
181
+ }
182
+ function writeTextFileAtomic(filePath, content) {
183
+ const dir = path.dirname(filePath);
184
+ const tempPath = path.join(dir, `.${path.basename(filePath)}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`);
185
+ try {
186
+ writeFileSync(tempPath, content, "utf8");
187
+ renameSync(tempPath, filePath);
188
+ }
189
+ catch (error) {
190
+ try {
191
+ unlinkSync(tempPath);
192
+ }
193
+ catch {
194
+ // Best effort cleanup; preserve the original write error.
195
+ }
196
+ throw error;
197
+ }
198
+ }
199
+ function acquireLock(lockPath) {
200
+ const startedAt = Date.now();
201
+ while (true) {
202
+ try {
203
+ mkdirSync(lockPath, { mode: 0o700 });
204
+ return;
205
+ }
206
+ catch (error) {
207
+ if (!isErrnoException(error) || error.code !== "EEXIST") {
208
+ throw error;
209
+ }
210
+ removeStaleLock(lockPath);
211
+ if (Date.now() - startedAt > LOCK_TIMEOUT_MS) {
212
+ throw new Error(`Timed out waiting for Agentpack state lock: ${lockPath}`);
213
+ }
214
+ sleepSync(25);
215
+ }
216
+ }
217
+ }
218
+ function releaseLock(lockPath) {
219
+ rmSync(lockPath, { recursive: true, force: true });
220
+ }
221
+ function removeStaleLock(lockPath) {
222
+ try {
223
+ const ageMs = Date.now() - statSync(lockPath).mtimeMs;
224
+ if (ageMs > STALE_LOCK_MS) {
225
+ rmSync(lockPath, { recursive: true, force: true });
226
+ }
227
+ }
228
+ catch (error) {
229
+ if (!isErrnoException(error) || error.code !== "ENOENT") {
230
+ throw error;
231
+ }
232
+ }
233
+ }
234
+ function sleepSync(ms) {
235
+ Atomics.wait(sleepArray, 0, 0, ms);
236
+ }
237
+ function isErrnoException(error) {
238
+ return error instanceof Error && "code" in error;
239
+ }
240
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/core/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ export interface AgentpackConfig {
2
+ schemaVersion: number;
3
+ projectName: string;
4
+ redactions: string[];
5
+ defaultBudget: number;
6
+ includeGitDiff: boolean;
7
+ }
8
+ export interface AgentpackState {
9
+ schemaVersion: number;
10
+ goal: string | null;
11
+ currentStatus: string;
12
+ nextActions: string[];
13
+ currentCheckpoint: string | null;
14
+ createdAt: string;
15
+ updatedAt: string;
16
+ }
17
+ export interface SourceRecord {
18
+ path: string;
19
+ hash: string;
20
+ size: number;
21
+ mtimeMs: number;
22
+ recordedAt: string;
23
+ summary: string;
24
+ snippet: string;
25
+ }
26
+ export interface SourcesFile {
27
+ schemaVersion: number;
28
+ sources: SourceRecord[];
29
+ }
30
+ export interface AgentpackEvent {
31
+ id: string;
32
+ ts: string;
33
+ type: string;
34
+ [key: string]: unknown;
35
+ }
36
+ export interface GitInfo {
37
+ available: boolean;
38
+ topLevel?: string;
39
+ branch: string | null;
40
+ head: string | null;
41
+ status: string;
42
+ diff: string;
43
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/core/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,5 @@
1
+ interface InstallOptions {
2
+ dryRun?: boolean;
3
+ }
4
+ export declare function installIntegration(root: string, targetValue: string, options?: InstallOptions): string;
5
+ export {};
@@ -0,0 +1,361 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
+ import path from "node:path";
3
+ import { getPackPath, readJson } from "../core/store.js";
4
+ const INSTALL_TARGETS = ["codex", "claude", "claude-desktop", "cursor"];
5
+ const INSTRUCTIONS = `# Agentpack
6
+
7
+ Use Agentpack as the task-state ledger for this repo.
8
+ Agentpack is not an activity logger; do not record every thought, file read, or edit.
9
+
10
+ At the start of a task:
11
+ - call \`load_context\` with a small preset first
12
+ - call \`source_status\` before re-reading previously inspected files
13
+
14
+ During work:
15
+ - call \`record_source\` after inspecting an important file, with a concise conclusion
16
+ - call \`record_decision\` for durable technical/product decisions
17
+ - call \`record_dead_end\` when an approach failed and should not be repeated
18
+ - call \`attach_evidence\` for useful test output, command output, or verification notes
19
+
20
+ Default cadence:
21
+ - start with Agentpack context
22
+ - work locally without recording every micro-step
23
+ - record durable findings and evidence before a checkpoint
24
+ - use full safe mode for risky or release-like changes
25
+
26
+ Before re-reading an unchanged source file, prefer the recorded source conclusion unless the task requires fresh inspection.
27
+
28
+ After meaningful progress, call \`checkpoint\` with:
29
+ - summary
30
+ - current status
31
+ - next actions
32
+ `;
33
+ export function installIntegration(root, targetValue, options = {}) {
34
+ const target = parseTarget(targetValue);
35
+ const dryRun = options.dryRun !== false;
36
+ const plan = buildInstallPlan(root, target);
37
+ const statuses = plan.files.map((file) => ({
38
+ file,
39
+ status: fileStatus(file.filePath, file.content)
40
+ }));
41
+ if (!dryRun) {
42
+ applyPlan(plan);
43
+ }
44
+ return formatInstallResult(root, plan, statuses, dryRun);
45
+ }
46
+ function buildInstallPlan(root, target) {
47
+ mkdirSync(getPackPath(root, "instructions"), { recursive: true });
48
+ const serverName = mcpServerName(root);
49
+ if (target === "codex") {
50
+ const codexSnippetPath = getPackPath(root, "instructions", "codex-mcp.example.toml");
51
+ return {
52
+ target,
53
+ files: [
54
+ writeFilePlan(root, ".agentpack/instructions/codex.md", "Write Codex-specific Agentpack workflow instructions.", INSTRUCTIONS),
55
+ managedBlockPlan(root, "AGENTS.md", "Add or update the Agentpack block in AGENTS.md.", INSTRUCTIONS),
56
+ tomlTablePlan(root, ".codex/config.toml", "Add the Agentpack MCP server to project-local Codex config.", `mcp_servers.${serverName}`, codexMcpTomlTable(serverName), "mcp_servers.agentpack"),
57
+ writeFilePlan(root, ".agentpack/instructions/codex-mcp.example.toml", "Write a Codex MCP config snippet for manual review.", codexTomlSnippet(serverName))
58
+ ],
59
+ notes: [
60
+ "No global Codex config is modified.",
61
+ `Codex should use the project-local .codex/config.toml entry named ${serverName} for this repo.`,
62
+ "Remove any old ~/.codex/config.toml agentpack server that hard-codes --root or cwd to another project.",
63
+ `For manual review, see ${relativePath(root, codexSnippetPath)}.`
64
+ ]
65
+ };
66
+ }
67
+ if (target === "claude") {
68
+ return {
69
+ target,
70
+ files: [
71
+ writeFilePlan(root, ".agentpack/instructions/claude.md", "Write Claude-specific Agentpack workflow instructions.", INSTRUCTIONS),
72
+ managedBlockPlan(root, "CLAUDE.md", "Add or update the Agentpack block in CLAUDE.md.", INSTRUCTIONS),
73
+ jsonMergePlan(root, ".mcp.json", "Add the Agentpack MCP server to project .mcp.json.", serverName, claudeMcpServer())
74
+ ],
75
+ notes: [
76
+ "Only project-local files are modified.",
77
+ `The Claude Code MCP server key is ${serverName} to avoid cross-repo name collisions.`,
78
+ "Claude Code prompts before using project-scoped MCP servers from .mcp.json."
79
+ ]
80
+ };
81
+ }
82
+ if (target === "claude-desktop") {
83
+ const desktopSnippetPath = getPackPath(root, "instructions", "claude-desktop-mcp.example.json");
84
+ return {
85
+ target,
86
+ files: [
87
+ writeFilePlan(root, ".agentpack/instructions/claude-desktop.md", "Write Claude Desktop-specific Agentpack setup notes.", claudeDesktopInstructions(root, desktopSnippetPath)),
88
+ writeFilePlan(root, ".agentpack/instructions/claude-desktop-mcp.example.json", "Write a Claude Desktop MCP config snippet for manual review.", claudeDesktopJsonSnippet(root, serverName))
89
+ ],
90
+ notes: [
91
+ "No Claude Desktop global config is modified.",
92
+ "Claude Desktop does not read project .mcp.json or CLAUDE.md.",
93
+ `To enable local MCP in Claude Desktop manually, review ${relativePath(root, desktopSnippetPath)} and merge it into ~/Library/Application Support/Claude/claude_desktop_config.json on macOS.`
94
+ ]
95
+ };
96
+ }
97
+ return {
98
+ target,
99
+ files: [
100
+ writeFilePlan(root, ".agentpack/instructions/cursor.md", "Write Cursor-specific Agentpack workflow instructions.", INSTRUCTIONS),
101
+ writeFilePlan(root, ".cursor/rules/agentpack.mdc", "Write a Cursor project rule for Agentpack.", INSTRUCTIONS),
102
+ jsonMergePlan(root, ".cursor/mcp.json", "Add the Agentpack MCP server to Cursor project MCP config.", serverName, cursorMcpServer())
103
+ ],
104
+ notes: [
105
+ "Only project-local files are modified.",
106
+ "Cursor reads project-specific MCP servers from .cursor/mcp.json."
107
+ ]
108
+ };
109
+ }
110
+ function applyPlan(plan) {
111
+ for (const file of plan.files) {
112
+ mkdirSync(path.dirname(file.filePath), { recursive: true });
113
+ if (existsSync(file.filePath) && readFileSync(file.filePath, "utf8") === file.content) {
114
+ continue;
115
+ }
116
+ writeFileSync(file.filePath, file.content, "utf8");
117
+ }
118
+ }
119
+ function formatInstallResult(root, plan, statuses, dryRun) {
120
+ const lines = [
121
+ dryRun
122
+ ? `Agentpack ${plan.target} install plan (dry run)`
123
+ : `Installed Agentpack ${plan.target} integration`,
124
+ dryRun ? "No files were changed." : "Files written:",
125
+ "",
126
+ ...statuses.map(({ file, status }) => `- ${status.toUpperCase()} ${relativePath(root, file.filePath)}: ${file.description}`),
127
+ "",
128
+ "Notes:",
129
+ ...plan.notes.map((note) => `- ${note}`)
130
+ ];
131
+ if (dryRun) {
132
+ lines.push("", "To apply:", ` agentpack install ${plan.target} --write`);
133
+ }
134
+ return lines.join("\n");
135
+ }
136
+ function writeFilePlan(root, relativeFilePath, description, content) {
137
+ return {
138
+ filePath: path.join(root, relativeFilePath),
139
+ description,
140
+ content: ensureTrailingNewline(content)
141
+ };
142
+ }
143
+ function managedBlockPlan(root, relativeFilePath, description, block) {
144
+ const filePath = path.join(root, relativeFilePath);
145
+ const existing = existsSync(filePath) ? readFileSync(filePath, "utf8") : "";
146
+ return {
147
+ filePath,
148
+ description,
149
+ content: upsertManagedBlock(existing, block)
150
+ };
151
+ }
152
+ function jsonMergePlan(root, relativeFilePath, description, serverName, server) {
153
+ const filePath = path.join(root, relativeFilePath);
154
+ const existing = readJson(filePath, {});
155
+ const mcpServers = isRecord(existing.mcpServers) ? existing.mcpServers : {};
156
+ const nextMcpServers = {
157
+ ...mcpServers,
158
+ [serverName]: server
159
+ };
160
+ if (serverName !== "agentpack" && JSON.stringify(mcpServers.agentpack) === JSON.stringify(server)) {
161
+ delete nextMcpServers.agentpack;
162
+ }
163
+ const next = {
164
+ ...existing,
165
+ mcpServers: nextMcpServers
166
+ };
167
+ return {
168
+ filePath,
169
+ description,
170
+ content: `${JSON.stringify(next, null, 2)}\n`
171
+ };
172
+ }
173
+ function tomlTablePlan(root, relativeFilePath, description, tableName, tableBody, legacyTableName) {
174
+ const filePath = path.join(root, relativeFilePath);
175
+ const existing = existsSync(filePath) ? readFileSync(filePath, "utf8") : "";
176
+ const withoutLegacy = legacyTableName && legacyTableName !== tableName
177
+ ? removeTomlTable(existing, legacyTableName)
178
+ : existing;
179
+ return {
180
+ filePath,
181
+ description,
182
+ content: upsertTomlTable(withoutLegacy, tableName, tableBody)
183
+ };
184
+ }
185
+ function upsertManagedBlock(existing, block) {
186
+ const marker = "<!-- agentpack:start -->";
187
+ const endMarker = "<!-- agentpack:end -->";
188
+ const wrapped = `${marker}\n${block.trim()}\n${endMarker}\n`;
189
+ if (existing.includes(marker)) {
190
+ return existing.replace(new RegExp(`${escapeRegExp(marker)}[\\s\\S]*?${escapeRegExp(endMarker)}\\n?`), wrapped);
191
+ }
192
+ return `${existing.trimEnd()}\n\n${wrapped}`.trimStart();
193
+ }
194
+ function upsertTomlTable(existing, tableName, tableBody) {
195
+ const tableHeader = `[${tableName}]`;
196
+ const lines = existing.split(/\r?\n/);
197
+ const start = lines.findIndex((line) => line.trim() === tableHeader);
198
+ const bodyLines = tableBody.trimEnd().split("\n");
199
+ if (start === -1) {
200
+ const prefix = existing.trimEnd();
201
+ return ensureTrailingNewline(prefix ? `${prefix}\n\n${tableBody}` : tableBody);
202
+ }
203
+ let end = start + 1;
204
+ const nestedPrefix = `[${tableName}.`;
205
+ while (end < lines.length) {
206
+ const trimmed = (lines[end] || "").trim();
207
+ if (trimmed.startsWith("[") && trimmed.endsWith("]") && !trimmed.startsWith(nestedPrefix)) {
208
+ break;
209
+ }
210
+ end += 1;
211
+ }
212
+ lines.splice(start, end - start, ...bodyLines);
213
+ return ensureTrailingNewline(lines.join("\n").trimEnd());
214
+ }
215
+ function removeTomlTable(existing, tableName) {
216
+ const tableHeader = `[${tableName}]`;
217
+ const lines = existing.split(/\r?\n/);
218
+ const start = lines.findIndex((line) => line.trim() === tableHeader);
219
+ if (start === -1) {
220
+ return existing;
221
+ }
222
+ let end = start + 1;
223
+ const nestedPrefix = `[${tableName}.`;
224
+ while (end < lines.length) {
225
+ const trimmed = (lines[end] || "").trim();
226
+ if (trimmed.startsWith("[") && trimmed.endsWith("]") && !trimmed.startsWith(nestedPrefix)) {
227
+ break;
228
+ }
229
+ end += 1;
230
+ }
231
+ lines.splice(start, end - start);
232
+ return ensureTrailingNewline(lines.join("\n").trimEnd());
233
+ }
234
+ function codexTomlSnippet(serverName) {
235
+ return [
236
+ "# Add this to the repo's .codex/config.toml after reviewing it.",
237
+ "# Do not put a project-specific --root or cwd in ~/.codex/config.toml.",
238
+ "# A hard-coded global root makes Agentpack read the wrong repo.",
239
+ codexMcpTomlTable(serverName),
240
+ ""
241
+ ].join("\n");
242
+ }
243
+ function codexMcpTomlTable(serverName) {
244
+ return [
245
+ `[mcp_servers.${serverName}]`,
246
+ "command = \"agentpack\"",
247
+ "args = [\"mcp\"]",
248
+ "startup_timeout_sec = 10",
249
+ "tool_timeout_sec = 60",
250
+ ""
251
+ ].join("\n");
252
+ }
253
+ function claudeMcpServer() {
254
+ return {
255
+ type: "stdio",
256
+ command: "agentpack",
257
+ args: ["mcp"]
258
+ };
259
+ }
260
+ function claudeDesktopMcpServer(root) {
261
+ return {
262
+ command: "agentpack",
263
+ args: ["mcp", "--root", root],
264
+ env: {
265
+ AGENTPACK_ROOT: root
266
+ }
267
+ };
268
+ }
269
+ function claudeDesktopJsonSnippet(root, serverName) {
270
+ return JSON.stringify({
271
+ mcpServers: {
272
+ [serverName]: claudeDesktopMcpServer(root)
273
+ }
274
+ }, null, 2);
275
+ }
276
+ function claudeDesktopInstructions(root, snippetPath) {
277
+ return [
278
+ "# Agentpack for Claude Desktop",
279
+ "",
280
+ "Claude Desktop does not read project-local `.mcp.json` or `CLAUDE.md`.",
281
+ "Use Claude Code's `.mcp.json` for Claude Code only.",
282
+ "",
283
+ "For Claude Desktop local MCP, prefer Desktop Extensions/MCP bundles when Agentpack ships one.",
284
+ "Until then, review the generated JSON snippet and merge it into your Claude Desktop config manually.",
285
+ "Do not copy the generated snippet over the Desktop config file; that can delete existing MCP servers.",
286
+ "",
287
+ "macOS config path:",
288
+ "",
289
+ "```text",
290
+ "~/Library/Application Support/Claude/claude_desktop_config.json",
291
+ "```",
292
+ "",
293
+ "Generated snippet:",
294
+ "",
295
+ "```text",
296
+ relativePath(root, snippetPath),
297
+ "```",
298
+ "",
299
+ "Safe manual flow:",
300
+ "",
301
+ "```bash",
302
+ "agentpack install claude-desktop --write",
303
+ "cat .agentpack/instructions/claude-desktop-mcp.example.json",
304
+ "mkdir -p \"$HOME/Library/Application Support/Claude\"",
305
+ "open -e \"$HOME/Library/Application Support/Claude/claude_desktop_config.json\"",
306
+ "```",
307
+ "",
308
+ "If the config file does not exist yet, create it with the generated snippet content.",
309
+ "If it already exists, merge only the `mcpServers.agentpack` entry into the existing JSON.",
310
+ "",
311
+ "After editing the Claude Desktop config, restart Claude Desktop.",
312
+ "",
313
+ "If Claude Desktop cannot find `agentpack`, replace the `command` value with an absolute executable path.",
314
+ "Keep both the `--root` argument and `AGENTPACK_ROOT` env value pointed at the project whose `.agentpack/` state you want Claude Desktop to use.",
315
+ "When switching Claude Desktop to another repo, update both the global `mcpServers.agentpack.args` `--root` value and `mcpServers.agentpack.env.AGENTPACK_ROOT`, then restart Claude Desktop."
316
+ ].join("\n");
317
+ }
318
+ function cursorMcpServer() {
319
+ return {
320
+ type: "stdio",
321
+ command: "agentpack",
322
+ args: ["mcp", "--root", "${workspaceFolder}"]
323
+ };
324
+ }
325
+ function mcpServerName(root) {
326
+ const projectName = path.basename(root);
327
+ const slug = projectName
328
+ .toLowerCase()
329
+ .replace(/[^a-z0-9_-]+/g, "-")
330
+ .replace(/^-+|-+$/g, "")
331
+ .replace(/-{2,}/g, "-");
332
+ if (!slug || slug === "agentpack") {
333
+ return "agentpack";
334
+ }
335
+ return `agentpack-${slug}`;
336
+ }
337
+ function parseTarget(target) {
338
+ if (INSTALL_TARGETS.includes(target)) {
339
+ return target;
340
+ }
341
+ throw new Error(`Unknown install target: ${target}`);
342
+ }
343
+ function fileStatus(filePath, content) {
344
+ if (!existsSync(filePath)) {
345
+ return "create";
346
+ }
347
+ return readFileSync(filePath, "utf8") === content ? "unchanged" : "update";
348
+ }
349
+ function relativePath(root, filePath) {
350
+ return path.relative(root, filePath) || ".";
351
+ }
352
+ function ensureTrailingNewline(value) {
353
+ return value.endsWith("\n") ? value : `${value}\n`;
354
+ }
355
+ function isRecord(value) {
356
+ return value !== null && typeof value === "object" && !Array.isArray(value);
357
+ }
358
+ function escapeRegExp(value) {
359
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
360
+ }
361
+ //# sourceMappingURL=install.js.map