@aylith/inspekt-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 (37) hide show
  1. package/dist/chunk-HD6ANKAP.js +20 -0
  2. package/dist/chunk-HD6ANKAP.js.map +1 -0
  3. package/dist/cli.cjs +451 -0
  4. package/dist/cli.cjs.map +1 -0
  5. package/dist/cli.d.ts +3 -0
  6. package/dist/cli.d.ts.map +1 -0
  7. package/dist/cli.js +419 -0
  8. package/dist/cli.js.map +1 -0
  9. package/dist/index.cjs +55 -0
  10. package/dist/index.cjs.map +1 -0
  11. package/dist/index.d.ts +9 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +9 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/setup/detect.d.ts +11 -0
  16. package/dist/setup/detect.d.ts.map +1 -0
  17. package/dist/setup/index.d.ts +23 -0
  18. package/dist/setup/index.d.ts.map +1 -0
  19. package/dist/setup/token.d.ts +13 -0
  20. package/dist/setup/token.d.ts.map +1 -0
  21. package/dist/setup/types.d.ts +17 -0
  22. package/dist/setup/types.d.ts.map +1 -0
  23. package/dist/setup/writers/antigravity.d.ts +6 -0
  24. package/dist/setup/writers/antigravity.d.ts.map +1 -0
  25. package/dist/setup/writers/claude-code.d.ts +8 -0
  26. package/dist/setup/writers/claude-code.d.ts.map +1 -0
  27. package/dist/setup/writers/codex.d.ts +6 -0
  28. package/dist/setup/writers/codex.d.ts.map +1 -0
  29. package/dist/setup/writers/cursor.d.ts +6 -0
  30. package/dist/setup/writers/cursor.d.ts.map +1 -0
  31. package/dist/setup/writers/gemini-cli.d.ts +6 -0
  32. package/dist/setup/writers/gemini-cli.d.ts.map +1 -0
  33. package/dist/setup/writers/json-writer.d.ts +18 -0
  34. package/dist/setup/writers/json-writer.d.ts.map +1 -0
  35. package/dist/setup/writers/mcp-entry.d.ts +8 -0
  36. package/dist/setup/writers/mcp-entry.d.ts.map +1 -0
  37. package/package.json +46 -0
package/dist/cli.js ADDED
@@ -0,0 +1,419 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ openInEditor
4
+ } from "./chunk-HD6ANKAP.js";
5
+
6
+ // src/setup/index.ts
7
+ import os2 from "os";
8
+
9
+ // src/setup/detect.ts
10
+ import { existsSync } from "fs";
11
+ import path from "path";
12
+ import os from "os";
13
+ var AGENTS = [
14
+ {
15
+ id: "claude-code",
16
+ label: "Claude Code",
17
+ configPath: (home) => process.platform === "win32" ? path.join(process.env["APPDATA"] ?? path.join(home, "AppData", "Roaming"), "Claude", "claude_desktop_config.json") : path.join(home, ".config", "claude", "mcp.json")
18
+ },
19
+ {
20
+ id: "cursor",
21
+ label: "Cursor",
22
+ configPath: (home) => process.platform === "darwin" ? path.join(home, "Library", "Application Support", "Cursor", "User", "settings.json") : process.platform === "win32" ? path.join(process.env["APPDATA"] ?? path.join(home, "AppData", "Roaming"), "Cursor", "User", "settings.json") : path.join(home, ".config", "Cursor", "User", "settings.json")
23
+ },
24
+ {
25
+ id: "codex",
26
+ label: "OpenAI Codex",
27
+ configPath: (home) => path.join(home, ".codex", "config.toml")
28
+ },
29
+ {
30
+ id: "gemini-cli",
31
+ label: "Gemini CLI",
32
+ configPath: (home) => path.join(home, ".gemini", "settings.json")
33
+ },
34
+ {
35
+ id: "antigravity",
36
+ label: "Antigravity",
37
+ configPath: (home) => process.platform === "darwin" ? path.join(home, "Library", "Application Support", "Antigravity", "User", "settings.json") : process.platform === "win32" ? path.join(process.env["APPDATA"] ?? path.join(home, "AppData", "Roaming"), "Antigravity", "User", "settings.json") : path.join(home, ".config", "Antigravity", "User", "settings.json")
38
+ }
39
+ ];
40
+ function detectAgents(home = os.homedir()) {
41
+ return AGENTS.map((a) => {
42
+ const p = a.configPath(home);
43
+ return {
44
+ id: a.id,
45
+ label: a.label,
46
+ configPath: p,
47
+ installed: existsSync(p)
48
+ };
49
+ });
50
+ }
51
+ function descriptorFor(id) {
52
+ return AGENTS.find((a) => a.id === id);
53
+ }
54
+
55
+ // src/setup/token.ts
56
+ import { promises as fs, existsSync as existsSync2, mkdirSync } from "fs";
57
+ import path2 from "path";
58
+ import { randomBytes } from "crypto";
59
+ function configPath(home) {
60
+ return path2.join(home, ".inspekt", "config.json");
61
+ }
62
+ function handshakePath(home) {
63
+ return path2.join(home, ".inspekt", "extension-handshake.json");
64
+ }
65
+ function defaultQueuePath(home) {
66
+ return path2.join(home, ".inspekt", "queue.jsonl");
67
+ }
68
+ function generateToken() {
69
+ return randomBytes(32).toString("hex");
70
+ }
71
+ async function loadOrCreateConfig(home) {
72
+ const p = configPath(home);
73
+ const dir = path2.dirname(p);
74
+ if (!existsSync2(dir)) mkdirSync(dir, { recursive: true });
75
+ if (existsSync2(p)) {
76
+ try {
77
+ const raw = await fs.readFile(p, "utf8");
78
+ const parsed = JSON.parse(raw);
79
+ if (parsed.token) {
80
+ return {
81
+ token: parsed.token,
82
+ host: parsed.host ?? "127.0.0.1",
83
+ port: parsed.port ?? 5678,
84
+ queuePath: parsed.queuePath ?? defaultQueuePath(home)
85
+ };
86
+ }
87
+ } catch {
88
+ }
89
+ }
90
+ const config = {
91
+ token: generateToken(),
92
+ host: "127.0.0.1",
93
+ port: 5678,
94
+ queuePath: defaultQueuePath(home)
95
+ };
96
+ await fs.writeFile(p, JSON.stringify(config, null, 2) + "\n", "utf8");
97
+ return config;
98
+ }
99
+ async function writeHandshake(home, config) {
100
+ const data = {
101
+ token: config.token,
102
+ agentEndpoint: `http://${config.host}:${config.port}`
103
+ };
104
+ await fs.writeFile(handshakePath(home), JSON.stringify(data, null, 2) + "\n", "utf8");
105
+ }
106
+
107
+ // src/setup/writers/claude-code.ts
108
+ import { promises as fs3, existsSync as existsSync4, mkdirSync as mkdirSync3 } from "fs";
109
+ import path4 from "path";
110
+
111
+ // src/setup/writers/mcp-entry.ts
112
+ function buildMcpEntry(config) {
113
+ return {
114
+ command: "npx",
115
+ args: ["-y", "@aylith/inspekt-mcp"],
116
+ env: {
117
+ INSPEKT_TOKEN: config.token,
118
+ INSPEKT_QUEUE_PATH: config.queuePath
119
+ }
120
+ };
121
+ }
122
+
123
+ // src/setup/writers/json-writer.ts
124
+ import { promises as fs2, existsSync as existsSync3, mkdirSync as mkdirSync2 } from "fs";
125
+ import path3 from "path";
126
+ async function writeMcpEntryToJsonConfig(configPath2, entry, options) {
127
+ const serverName = options.serverName ?? "inspekt";
128
+ const indent = options.indent ?? 2;
129
+ const dir = path3.dirname(configPath2);
130
+ if (!existsSync3(dir)) mkdirSync2(dir, { recursive: true });
131
+ let root = {};
132
+ if (existsSync3(configPath2)) {
133
+ const raw = await fs2.readFile(configPath2, "utf8");
134
+ if (raw.trim().length > 0) {
135
+ try {
136
+ root = JSON.parse(raw);
137
+ } catch (err) {
138
+ throw new Error(`Failed to parse ${configPath2}: ${err.message}`);
139
+ }
140
+ }
141
+ }
142
+ let cursor = root;
143
+ for (const key of options.mcpServersPath) {
144
+ const next = cursor[key];
145
+ if (next === void 0 || next === null) {
146
+ const fresh = {};
147
+ cursor[key] = fresh;
148
+ cursor = fresh;
149
+ } else if (typeof next === "object" && !Array.isArray(next)) {
150
+ cursor = next;
151
+ } else {
152
+ throw new Error(
153
+ `Unexpected non-object value at ${options.mcpServersPath.join(".")} in ${configPath2}`
154
+ );
155
+ }
156
+ }
157
+ const servers = cursor["mcpServers"] ?? {};
158
+ const previous = servers[serverName] ?? null;
159
+ servers[serverName] = entry;
160
+ cursor["mcpServers"] = servers;
161
+ await fs2.writeFile(configPath2, JSON.stringify(root, null, indent) + "\n", "utf8");
162
+ return { written: true, previousEntry: previous };
163
+ }
164
+
165
+ // src/setup/writers/claude-code.ts
166
+ var SKILL_BODY = `---
167
+ name: inspekt
168
+ description: Use when the user references a UI element they grabbed with Inspekt \u2014 phrases like "this button", "the thing I just grabbed", "fix this element", "change this", or any deixis after an Inspekt grab. Call grab_latest() first, then act on the file/line returned. Avoid calling proactively if the user hasn't grabbed anything in this session.
169
+ allowed-tools: mcp__inspekt__grab_latest, mcp__inspekt__list_grabs, mcp__inspekt__get_grab, mcp__inspekt__mark_grab_processed, mcp__inspekt__open_grab_in_editor
170
+ ---
171
+
172
+ # Inspekt grabs
173
+
174
+ The user has the Inspekt Chrome extension installed and may have grabbed a UI
175
+ element from their running app. Grabs include the source file path, line/column,
176
+ component name, surrounding source snippet, and the page URL.
177
+
178
+ ## When to use
179
+
180
+ Call \`grab_latest()\` automatically (no need to ask permission) when the user
181
+ references a recent UI grab. Triggers include:
182
+ - "this element", "this button", "the thing I just grabbed"
183
+ - "fix this", "change this", "make this red", "what's wrong with this"
184
+ - A vague request right after they mentioned using Inspekt
185
+
186
+ If the user asks about something unrelated to a UI element (e.g. infrastructure,
187
+ build tooling), do NOT call grab_latest \u2014 they probably haven't grabbed anything.
188
+
189
+ ## After fetching
190
+
191
+ 1. Read the file at the returned path:line.
192
+ 2. Show the user what you found in 1-2 sentences before editing.
193
+ 3. Make the change they asked for.
194
+ 4. Optionally call \`mark_grab_processed(id)\` once you've fully addressed the grab.
195
+
196
+ ## Tools
197
+
198
+ - \`grab_latest()\` \u2014 single most recent grab. Use this first.
199
+ - \`list_grabs(since?, limit?)\` \u2014 recent grabs, filterable.
200
+ - \`get_grab(id)\` \u2014 full payload by ID.
201
+ - \`mark_grab_processed(id)\` \u2014 mark as consumed (optional bookkeeping).
202
+ - \`open_grab_in_editor(id)\` \u2014 open the grab in the user's IDE (only on request).
203
+ `;
204
+ async function writeClaudeCode(ctx, config) {
205
+ const descriptor = descriptorFor("claude-code");
206
+ if (!descriptor) throw new Error("Claude Code descriptor missing");
207
+ const configPath2 = descriptor.configPath(ctx.home);
208
+ const entry = buildMcpEntry(config);
209
+ await writeMcpEntryToJsonConfig(configPath2, entry, { mcpServersPath: [] });
210
+ const skillDir = path4.join(ctx.home, ".claude", "skills", "inspekt");
211
+ if (!existsSync4(skillDir)) mkdirSync3(skillDir, { recursive: true });
212
+ const skillPath = path4.join(skillDir, "SKILL.md");
213
+ await fs3.writeFile(skillPath, SKILL_BODY, "utf8");
214
+ return { configPath: configPath2, skillPath };
215
+ }
216
+
217
+ // src/setup/writers/cursor.ts
218
+ async function writeCursor(ctx, config) {
219
+ const descriptor = descriptorFor("cursor");
220
+ if (!descriptor) throw new Error("Cursor descriptor missing");
221
+ const configPath2 = descriptor.configPath(ctx.home);
222
+ const entry = buildMcpEntry(config);
223
+ await writeMcpEntryToJsonConfig(configPath2, entry, { mcpServersPath: [] });
224
+ return { configPath: configPath2 };
225
+ }
226
+
227
+ // src/setup/writers/codex.ts
228
+ import { promises as fs4, existsSync as existsSync5, mkdirSync as mkdirSync4 } from "fs";
229
+ import path5 from "path";
230
+ var BLOCK_START = "# >>> inspekt managed mcp entry \u2014 do not edit between markers >>>";
231
+ var BLOCK_END = "# <<< inspekt managed mcp entry <<<";
232
+ function buildBlock(config) {
233
+ const entry = buildMcpEntry(config);
234
+ const argsArr = entry.args.map((a) => `"${a}"`).join(", ");
235
+ return [
236
+ BLOCK_START,
237
+ "[mcp_servers.inspekt]",
238
+ `command = "${entry.command}"`,
239
+ `args = [${argsArr}]`,
240
+ "",
241
+ "[mcp_servers.inspekt.env]",
242
+ `INSPEKT_TOKEN = "${entry.env["INSPEKT_TOKEN"]}"`,
243
+ `INSPEKT_QUEUE_PATH = "${entry.env["INSPEKT_QUEUE_PATH"]}"`,
244
+ BLOCK_END
245
+ ].join("\n");
246
+ }
247
+ async function writeCodex(ctx, config) {
248
+ const descriptor = descriptorFor("codex");
249
+ if (!descriptor) throw new Error("Codex descriptor missing");
250
+ const configPath2 = descriptor.configPath(ctx.home);
251
+ const dir = path5.dirname(configPath2);
252
+ if (!existsSync5(dir)) mkdirSync4(dir, { recursive: true });
253
+ const existing = existsSync5(configPath2) ? await fs4.readFile(configPath2, "utf8") : "";
254
+ const block = buildBlock(config);
255
+ const startIdx = existing.indexOf(BLOCK_START);
256
+ const endIdx = existing.indexOf(BLOCK_END);
257
+ let next;
258
+ if (startIdx !== -1 && endIdx !== -1 && endIdx > startIdx) {
259
+ next = existing.slice(0, startIdx) + block + existing.slice(endIdx + BLOCK_END.length);
260
+ } else {
261
+ next = existing.trim().length > 0 ? `${existing.trimEnd()}
262
+
263
+ ${block}
264
+ ` : `${block}
265
+ `;
266
+ }
267
+ await fs4.writeFile(configPath2, next, "utf8");
268
+ return { configPath: configPath2 };
269
+ }
270
+
271
+ // src/setup/writers/gemini-cli.ts
272
+ async function writeGeminiCli(ctx, config) {
273
+ const descriptor = descriptorFor("gemini-cli");
274
+ if (!descriptor) throw new Error("Gemini CLI descriptor missing");
275
+ const configPath2 = descriptor.configPath(ctx.home);
276
+ const entry = buildMcpEntry(config);
277
+ await writeMcpEntryToJsonConfig(configPath2, entry, { mcpServersPath: [] });
278
+ return { configPath: configPath2 };
279
+ }
280
+
281
+ // src/setup/writers/antigravity.ts
282
+ async function writeAntigravity(ctx, config) {
283
+ const descriptor = descriptorFor("antigravity");
284
+ if (!descriptor) throw new Error("Antigravity descriptor missing");
285
+ const configPath2 = descriptor.configPath(ctx.home);
286
+ const entry = buildMcpEntry(config);
287
+ await writeMcpEntryToJsonConfig(configPath2, entry, { mcpServersPath: [] });
288
+ return { configPath: configPath2 };
289
+ }
290
+
291
+ // src/setup/index.ts
292
+ async function runSetup(opts = {}) {
293
+ const home = opts.home ?? os2.homedir();
294
+ const config = await loadOrCreateConfig(home);
295
+ await writeHandshake(home, config);
296
+ const detected = detectAgents(home);
297
+ const requested = opts.agents ? detected.filter((a) => opts.agents.includes(a.id)) : detected.filter((a) => a.installed);
298
+ const ctx = {
299
+ home,
300
+ token: config.token,
301
+ daemonUrl: `http://${config.host}:${config.port}`
302
+ };
303
+ const written = [];
304
+ const skipped = [];
305
+ for (const agent of requested) {
306
+ try {
307
+ let p;
308
+ switch (agent.id) {
309
+ case "claude-code": {
310
+ const r = await writeClaudeCode(ctx, config);
311
+ p = r.configPath;
312
+ if (!opts.quiet) console.log(` \u2713 Claude Code \u2192 ${r.configPath}`);
313
+ if (!opts.quiet) console.log(` skill \u2192 ${r.skillPath}`);
314
+ break;
315
+ }
316
+ case "cursor": {
317
+ const r = await writeCursor(ctx, config);
318
+ p = r.configPath;
319
+ if (!opts.quiet) console.log(` \u2713 Cursor \u2192 ${r.configPath}`);
320
+ break;
321
+ }
322
+ case "codex": {
323
+ const r = await writeCodex(ctx, config);
324
+ p = r.configPath;
325
+ if (!opts.quiet) console.log(` \u2713 OpenAI Codex \u2192 ${r.configPath}`);
326
+ break;
327
+ }
328
+ case "gemini-cli": {
329
+ const r = await writeGeminiCli(ctx, config);
330
+ p = r.configPath;
331
+ if (!opts.quiet) console.log(` \u2713 Gemini CLI \u2192 ${r.configPath}`);
332
+ break;
333
+ }
334
+ case "antigravity": {
335
+ const r = await writeAntigravity(ctx, config);
336
+ p = r.configPath;
337
+ if (!opts.quiet) console.log(` \u2713 Antigravity \u2192 ${r.configPath}`);
338
+ break;
339
+ }
340
+ }
341
+ written.push({ id: agent.id, path: p });
342
+ } catch (err) {
343
+ skipped.push({ id: agent.id, reason: err.message });
344
+ if (!opts.quiet) console.log(` \u2717 ${agent.label}: ${err.message}`);
345
+ }
346
+ }
347
+ if (!opts.quiet) {
348
+ console.log("");
349
+ console.log(`Token written to ${ctx.home}/.inspekt/config.json`);
350
+ console.log("Handshake file at ~/.inspekt/extension-handshake.json \u2014 the Chrome");
351
+ console.log("extension will pick up the token from there on next launch.");
352
+ console.log("");
353
+ console.log("Next: start the daemon with `inspekt-daemon` (or let it auto-start on");
354
+ console.log("the first grab from the extension).");
355
+ }
356
+ return {
357
+ token: config.token,
358
+ configPath: `${ctx.home}/.inspekt/config.json`,
359
+ agentsWritten: written,
360
+ agentsSkipped: skipped
361
+ };
362
+ }
363
+
364
+ // src/cli.ts
365
+ var args = process.argv.slice(2);
366
+ var sub = args[0];
367
+ function printHelp() {
368
+ console.log(`Usage:`);
369
+ console.log(` inspekt setup [--agents <list>] Register Inspekt with your installed agents`);
370
+ console.log(` inspekt open <file>[:<line>[:<col>]] [--editor <editor>]`);
371
+ console.log(` inspekt <file>[:<line>[:<col>]] [--editor <editor>] (shorthand for 'open')`);
372
+ console.log(``);
373
+ console.log(`Examples:`);
374
+ console.log(` inspekt setup`);
375
+ console.log(` inspekt setup --agents claude-code,cursor`);
376
+ console.log(` inspekt src/App.tsx:42`);
377
+ console.log(` inspekt src/App.tsx:42:3 --editor cursor`);
378
+ }
379
+ if (!sub || sub === "--help" || sub === "-h" || sub === "help") {
380
+ printHelp();
381
+ process.exit(0);
382
+ }
383
+ if (sub === "setup") {
384
+ const agentsIdx = args.indexOf("--agents");
385
+ const agents = agentsIdx !== -1 && args[agentsIdx + 1] ? args[agentsIdx + 1].split(",") : void 0;
386
+ void runSetup({ agents }).catch((err) => {
387
+ console.error("[inspekt setup]", err);
388
+ process.exit(1);
389
+ });
390
+ } else {
391
+ const filePart = sub === "open" ? args[1] : sub;
392
+ if (!filePart) {
393
+ printHelp();
394
+ process.exit(1);
395
+ }
396
+ const restStart = sub === "open" ? 2 : 1;
397
+ let editor;
398
+ const editorIdx = args.indexOf("--editor", restStart);
399
+ const editorIdxShort = args.indexOf("-e", restStart);
400
+ const idx = editorIdx !== -1 ? editorIdx : editorIdxShort;
401
+ if (idx !== -1 && args[idx + 1]) {
402
+ editor = args[idx + 1];
403
+ }
404
+ const parts = filePart.split(":");
405
+ let file;
406
+ let line;
407
+ let column;
408
+ if (/^[A-Z]$/i.test(parts[0] ?? "") && (parts[1] ?? "").includes("\\")) {
409
+ file = `${parts[0]}:${parts[1]}`;
410
+ line = parts[2] ? parseInt(parts[2], 10) : void 0;
411
+ column = parts[3] ? parseInt(parts[3], 10) : void 0;
412
+ } else {
413
+ file = parts[0];
414
+ line = parts[1] ? parseInt(parts[1], 10) : void 0;
415
+ column = parts[2] ? parseInt(parts[2], 10) : void 0;
416
+ }
417
+ openInEditor({ file, line, column, editor });
418
+ }
419
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/setup/index.ts","../src/setup/detect.ts","../src/setup/token.ts","../src/setup/writers/claude-code.ts","../src/setup/writers/mcp-entry.ts","../src/setup/writers/json-writer.ts","../src/setup/writers/cursor.ts","../src/setup/writers/codex.ts","../src/setup/writers/gemini-cli.ts","../src/setup/writers/antigravity.ts","../src/cli.ts"],"sourcesContent":["// `inspekt setup` — interactive (and non-interactive) registration of Inspekt\n// with the user's installed agents. Generates an auth token, writes it to\n// ~/.inspekt/config.json + ~/.inspekt/extension-handshake.json (read by the\n// Chrome extension on first launch), and adds the inspekt MCP entry to each\n// chosen agent's config file.\n\nimport os from 'node:os';\nimport { detectAgents } from './detect.js';\nimport { loadOrCreateConfig, writeHandshake } from './token.js';\nimport { writeClaudeCode } from './writers/claude-code.js';\nimport { writeCursor } from './writers/cursor.js';\nimport { writeCodex } from './writers/codex.js';\nimport { writeGeminiCli } from './writers/gemini-cli.js';\nimport { writeAntigravity } from './writers/antigravity.js';\nimport type { AgentId, SetupContext } from './types.js';\n\nexport interface RunSetupOptions {\n /** Restrict registration to this subset. If omitted, register all detected agents. */\n agents?: string[];\n /** Override home (for tests). */\n home?: string;\n /** When true, suppresses interactive output and only logs paths written. */\n quiet?: boolean;\n}\n\nexport interface SetupResult {\n token: string;\n configPath: string;\n agentsWritten: { id: AgentId; path: string }[];\n agentsSkipped: { id: AgentId; reason: string }[];\n}\n\nexport async function runSetup(opts: RunSetupOptions = {}): Promise<SetupResult> {\n const home = opts.home ?? os.homedir();\n const config = await loadOrCreateConfig(home);\n await writeHandshake(home, config);\n\n const detected = detectAgents(home);\n const requested = opts.agents\n ? detected.filter((a) => opts.agents!.includes(a.id))\n : detected.filter((a) => a.installed);\n\n const ctx: SetupContext = {\n home,\n token: config.token,\n daemonUrl: `http://${config.host}:${config.port}`,\n };\n\n const written: SetupResult['agentsWritten'] = [];\n const skipped: SetupResult['agentsSkipped'] = [];\n\n for (const agent of requested) {\n try {\n let p: string;\n switch (agent.id) {\n case 'claude-code': {\n const r = await writeClaudeCode(ctx, config);\n p = r.configPath;\n if (!opts.quiet) console.log(` ✓ Claude Code → ${r.configPath}`);\n if (!opts.quiet) console.log(` skill → ${r.skillPath}`);\n break;\n }\n case 'cursor': {\n const r = await writeCursor(ctx, config);\n p = r.configPath;\n if (!opts.quiet) console.log(` ✓ Cursor → ${r.configPath}`);\n break;\n }\n case 'codex': {\n const r = await writeCodex(ctx, config);\n p = r.configPath;\n if (!opts.quiet) console.log(` ✓ OpenAI Codex → ${r.configPath}`);\n break;\n }\n case 'gemini-cli': {\n const r = await writeGeminiCli(ctx, config);\n p = r.configPath;\n if (!opts.quiet) console.log(` ✓ Gemini CLI → ${r.configPath}`);\n break;\n }\n case 'antigravity': {\n const r = await writeAntigravity(ctx, config);\n p = r.configPath;\n if (!opts.quiet) console.log(` ✓ Antigravity → ${r.configPath}`);\n break;\n }\n }\n written.push({ id: agent.id, path: p! });\n } catch (err) {\n skipped.push({ id: agent.id, reason: (err as Error).message });\n if (!opts.quiet) console.log(` ✗ ${agent.label}: ${(err as Error).message}`);\n }\n }\n\n // Friendly summary.\n if (!opts.quiet) {\n console.log('');\n console.log(`Token written to ${ctx.home}/.inspekt/config.json`);\n console.log('Handshake file at ~/.inspekt/extension-handshake.json — the Chrome');\n console.log('extension will pick up the token from there on next launch.');\n console.log('');\n console.log('Next: start the daemon with `inspekt-daemon` (or let it auto-start on');\n console.log('the first grab from the extension).');\n }\n\n return {\n token: config.token,\n configPath: `${ctx.home}/.inspekt/config.json`,\n agentsWritten: written,\n agentsSkipped: skipped,\n };\n}\n","// Detect installed agents by looking for their canonical config files.\n// Returns a uniform DetectedAgent[] regardless of platform — caller decides\n// which ones to register Inspekt with.\n\nimport { existsSync } from 'node:fs';\nimport path from 'node:path';\nimport os from 'node:os';\nimport type { AgentId, DetectedAgent } from './types.js';\n\nexport interface AgentDescriptor {\n id: AgentId;\n label: string;\n /** Returns the canonical MCP config path for this agent on this platform. */\n configPath: (home: string) => string;\n}\n\nexport const AGENTS: AgentDescriptor[] = [\n {\n id: 'claude-code',\n label: 'Claude Code',\n configPath: (home) =>\n process.platform === 'win32'\n ? path.join(process.env['APPDATA'] ?? path.join(home, 'AppData', 'Roaming'), 'Claude', 'claude_desktop_config.json')\n : path.join(home, '.config', 'claude', 'mcp.json'),\n },\n {\n id: 'cursor',\n label: 'Cursor',\n configPath: (home) =>\n process.platform === 'darwin'\n ? path.join(home, 'Library', 'Application Support', 'Cursor', 'User', 'settings.json')\n : process.platform === 'win32'\n ? path.join(process.env['APPDATA'] ?? path.join(home, 'AppData', 'Roaming'), 'Cursor', 'User', 'settings.json')\n : path.join(home, '.config', 'Cursor', 'User', 'settings.json'),\n },\n {\n id: 'codex',\n label: 'OpenAI Codex',\n configPath: (home) => path.join(home, '.codex', 'config.toml'),\n },\n {\n id: 'gemini-cli',\n label: 'Gemini CLI',\n configPath: (home) => path.join(home, '.gemini', 'settings.json'),\n },\n {\n id: 'antigravity',\n label: 'Antigravity',\n configPath: (home) =>\n process.platform === 'darwin'\n ? path.join(home, 'Library', 'Application Support', 'Antigravity', 'User', 'settings.json')\n : process.platform === 'win32'\n ? path.join(process.env['APPDATA'] ?? path.join(home, 'AppData', 'Roaming'), 'Antigravity', 'User', 'settings.json')\n : path.join(home, '.config', 'Antigravity', 'User', 'settings.json'),\n },\n];\n\nexport function detectAgents(home: string = os.homedir()): DetectedAgent[] {\n return AGENTS.map((a) => {\n const p = a.configPath(home);\n return {\n id: a.id,\n label: a.label,\n configPath: p,\n installed: existsSync(p),\n };\n });\n}\n\nexport function descriptorFor(id: AgentId): AgentDescriptor | undefined {\n return AGENTS.find((a) => a.id === id);\n}\n","// Token + ~/.inspekt/config.json management. The token is a 256-bit random\n// hex string written to ~/.inspekt/config.json and replayed into every agent's\n// MCP server config (so the daemon can authenticate requests). The Chrome\n// extension reads the same value from chrome.storage.sync (set by an\n// extension-handshake file at ~/.inspekt/extension-handshake.json).\n\nimport { promises as fs, existsSync, mkdirSync } from 'node:fs';\nimport path from 'node:path';\nimport { randomBytes } from 'node:crypto';\n\nexport interface InspektConfig {\n token: string;\n host: string;\n port: number;\n queuePath: string;\n}\n\nexport function configPath(home: string): string {\n return path.join(home, '.inspekt', 'config.json');\n}\n\nexport function handshakePath(home: string): string {\n return path.join(home, '.inspekt', 'extension-handshake.json');\n}\n\nexport function defaultQueuePath(home: string): string {\n return path.join(home, '.inspekt', 'queue.jsonl');\n}\n\nexport function generateToken(): string {\n return randomBytes(32).toString('hex');\n}\n\nexport async function loadOrCreateConfig(home: string): Promise<InspektConfig> {\n const p = configPath(home);\n const dir = path.dirname(p);\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n\n if (existsSync(p)) {\n try {\n const raw = await fs.readFile(p, 'utf8');\n const parsed = JSON.parse(raw) as Partial<InspektConfig>;\n if (parsed.token) {\n return {\n token: parsed.token,\n host: parsed.host ?? '127.0.0.1',\n port: parsed.port ?? 5678,\n queuePath: parsed.queuePath ?? defaultQueuePath(home),\n };\n }\n } catch {\n // Fall through and rewrite.\n }\n }\n\n const config: InspektConfig = {\n token: generateToken(),\n host: '127.0.0.1',\n port: 5678,\n queuePath: defaultQueuePath(home),\n };\n await fs.writeFile(p, JSON.stringify(config, null, 2) + '\\n', 'utf8');\n return config;\n}\n\nexport async function writeHandshake(home: string, config: InspektConfig): Promise<void> {\n // Small JSON the Chrome extension polls on first launch (when its\n // chrome.storage.sync token is empty) to discover the daemon address +\n // token. The extension deletes this file once it's stored the values.\n const data = {\n token: config.token,\n agentEndpoint: `http://${config.host}:${config.port}`,\n };\n await fs.writeFile(handshakePath(home), JSON.stringify(data, null, 2) + '\\n', 'utf8');\n}\n","// Claude Code MCP entry writer. Drops the inspekt server into the user's\n// MCP config (linux/macOS: ~/.config/claude/mcp.json; Windows:\n// %APPDATA%/Claude/claude_desktop_config.json) and a SKILL.md into\n// ~/.claude/skills/inspekt/ describing trigger conditions.\n\nimport { promises as fs, existsSync, mkdirSync } from 'node:fs';\nimport path from 'node:path';\nimport { buildMcpEntry } from './mcp-entry.js';\nimport { writeMcpEntryToJsonConfig } from './json-writer.js';\nimport { descriptorFor } from '../detect.js';\nimport type { InspektConfig } from '../token.js';\nimport type { SetupContext } from '../types.js';\n\nconst SKILL_BODY = `---\nname: inspekt\ndescription: Use when the user references a UI element they grabbed with Inspekt — phrases like \"this button\", \"the thing I just grabbed\", \"fix this element\", \"change this\", or any deixis after an Inspekt grab. Call grab_latest() first, then act on the file/line returned. Avoid calling proactively if the user hasn't grabbed anything in this session.\nallowed-tools: mcp__inspekt__grab_latest, mcp__inspekt__list_grabs, mcp__inspekt__get_grab, mcp__inspekt__mark_grab_processed, mcp__inspekt__open_grab_in_editor\n---\n\n# Inspekt grabs\n\nThe user has the Inspekt Chrome extension installed and may have grabbed a UI\nelement from their running app. Grabs include the source file path, line/column,\ncomponent name, surrounding source snippet, and the page URL.\n\n## When to use\n\nCall \\`grab_latest()\\` automatically (no need to ask permission) when the user\nreferences a recent UI grab. Triggers include:\n- \"this element\", \"this button\", \"the thing I just grabbed\"\n- \"fix this\", \"change this\", \"make this red\", \"what's wrong with this\"\n- A vague request right after they mentioned using Inspekt\n\nIf the user asks about something unrelated to a UI element (e.g. infrastructure,\nbuild tooling), do NOT call grab_latest — they probably haven't grabbed anything.\n\n## After fetching\n\n1. Read the file at the returned path:line.\n2. Show the user what you found in 1-2 sentences before editing.\n3. Make the change they asked for.\n4. Optionally call \\`mark_grab_processed(id)\\` once you've fully addressed the grab.\n\n## Tools\n\n- \\`grab_latest()\\` — single most recent grab. Use this first.\n- \\`list_grabs(since?, limit?)\\` — recent grabs, filterable.\n- \\`get_grab(id)\\` — full payload by ID.\n- \\`mark_grab_processed(id)\\` — mark as consumed (optional bookkeeping).\n- \\`open_grab_in_editor(id)\\` — open the grab in the user's IDE (only on request).\n`;\n\nexport interface ClaudeCodeWriteResult {\n configPath: string;\n skillPath: string;\n}\n\nexport async function writeClaudeCode(\n ctx: SetupContext,\n config: InspektConfig,\n): Promise<ClaudeCodeWriteResult> {\n const descriptor = descriptorFor('claude-code');\n if (!descriptor) throw new Error('Claude Code descriptor missing');\n const configPath = descriptor.configPath(ctx.home);\n const entry = buildMcpEntry(config);\n\n // Top-level mcpServers map.\n await writeMcpEntryToJsonConfig(configPath, entry, { mcpServersPath: [] });\n\n // Skill file — drop one in the personal skills dir so the inspector heuristic\n // there picks it up.\n const skillDir = path.join(ctx.home, '.claude', 'skills', 'inspekt');\n if (!existsSync(skillDir)) mkdirSync(skillDir, { recursive: true });\n const skillPath = path.join(skillDir, 'SKILL.md');\n await fs.writeFile(skillPath, SKILL_BODY, 'utf8');\n\n return { configPath, skillPath };\n}\n","// Shared MCP-server entry shape that we write into every agent's config.\n// Claude Code, Cursor, Codex, Gemini CLI, and Antigravity all use a\n// `mcpServers` map keyed by server name. The exact path inside their JSON\n// config differs; the per-agent writer is responsible for placing this block\n// in the right place.\n\nimport type { InspektConfig } from '../token.js';\n\nexport interface McpEntry {\n command: string;\n args: string[];\n env: Record<string, string>;\n}\n\nexport function buildMcpEntry(config: InspektConfig): McpEntry {\n return {\n command: 'npx',\n args: ['-y', '@aylith/inspekt-mcp'],\n env: {\n INSPEKT_TOKEN: config.token,\n INSPEKT_QUEUE_PATH: config.queuePath,\n },\n };\n}\n","// Idempotent JSON writer for agent config files.\n//\n// Each agent's config is a JSON file with a top-level `mcpServers` map (or a\n// nested path). We merge our entry in without disturbing other keys, preserve\n// the existing key order via JSON.parse roundtrip, and write back with the\n// same indentation.\n\nimport { promises as fs, existsSync, mkdirSync } from 'node:fs';\nimport path from 'node:path';\nimport type { McpEntry } from './mcp-entry.js';\n\nexport interface JsonMergeOptions {\n /**\n * Path inside the JSON config where the mcpServers map lives. Empty array\n * means the root has `mcpServers` directly; otherwise we walk into the\n * given keys, creating objects as needed.\n */\n mcpServersPath: string[];\n /** Server name to use inside mcpServers (default 'inspekt'). */\n serverName?: string;\n /** Indent for re-serialization (default 2 spaces). */\n indent?: number;\n}\n\nexport async function writeMcpEntryToJsonConfig(\n configPath: string,\n entry: McpEntry,\n options: JsonMergeOptions,\n): Promise<{ written: boolean; previousEntry: McpEntry | null }> {\n const serverName = options.serverName ?? 'inspekt';\n const indent = options.indent ?? 2;\n\n const dir = path.dirname(configPath);\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n\n let root: Record<string, unknown> = {};\n if (existsSync(configPath)) {\n const raw = await fs.readFile(configPath, 'utf8');\n if (raw.trim().length > 0) {\n try {\n root = JSON.parse(raw) as Record<string, unknown>;\n } catch (err) {\n throw new Error(`Failed to parse ${configPath}: ${(err as Error).message}`);\n }\n }\n }\n\n // Walk into nested path, creating intermediate objects.\n let cursor: Record<string, unknown> = root;\n for (const key of options.mcpServersPath) {\n const next = cursor[key];\n if (next === undefined || next === null) {\n const fresh: Record<string, unknown> = {};\n cursor[key] = fresh;\n cursor = fresh;\n } else if (typeof next === 'object' && !Array.isArray(next)) {\n cursor = next as Record<string, unknown>;\n } else {\n throw new Error(\n `Unexpected non-object value at ${options.mcpServersPath.join('.')} in ${configPath}`,\n );\n }\n }\n\n // mcpServers map lives one level deeper than our path.\n const servers = (cursor['mcpServers'] as Record<string, McpEntry> | undefined) ?? {};\n const previous = servers[serverName] ?? null;\n servers[serverName] = entry;\n cursor['mcpServers'] = servers;\n\n await fs.writeFile(configPath, JSON.stringify(root, null, indent) + '\\n', 'utf8');\n return { written: true, previousEntry: previous };\n}\n","// Cursor MCP entry writer. Cursor 0.45+ supports MCP servers; the entry\n// lives at the top-level `mcpServers` key in\n// ~/Library/Application Support/Cursor/User/settings.json (and platform\n// equivalents). We merge alongside existing user settings.\n\nimport { buildMcpEntry } from './mcp-entry.js';\nimport { writeMcpEntryToJsonConfig } from './json-writer.js';\nimport { descriptorFor } from '../detect.js';\nimport type { InspektConfig } from '../token.js';\nimport type { SetupContext } from '../types.js';\n\nexport async function writeCursor(\n ctx: SetupContext,\n config: InspektConfig,\n): Promise<{ configPath: string }> {\n const descriptor = descriptorFor('cursor');\n if (!descriptor) throw new Error('Cursor descriptor missing');\n const configPath = descriptor.configPath(ctx.home);\n const entry = buildMcpEntry(config);\n await writeMcpEntryToJsonConfig(configPath, entry, { mcpServersPath: [] });\n return { configPath };\n}\n","// OpenAI Codex CLI uses ~/.codex/config.toml. The MCP-server block has a\n// fixed TOML shape:\n//\n// [mcp_servers.inspekt]\n// command = \"npx\"\n// args = [\"-y\", \"@aylith/inspekt-mcp\"]\n// [mcp_servers.inspekt.env]\n// INSPEKT_TOKEN = \"...\"\n//\n// We don't want to drag a TOML parser in just for this — we instead detect\n// an existing `[mcp_servers.inspekt]` section and rewrite it idempotently\n// with a simple string-level edit. Other agents' configs (JSON) get proper\n// parsing.\n\nimport { promises as fs, existsSync, mkdirSync } from 'node:fs';\nimport path from 'node:path';\nimport { descriptorFor } from '../detect.js';\nimport { buildMcpEntry } from './mcp-entry.js';\nimport type { InspektConfig } from '../token.js';\nimport type { SetupContext } from '../types.js';\n\nconst BLOCK_START = '# >>> inspekt managed mcp entry — do not edit between markers >>>';\nconst BLOCK_END = '# <<< inspekt managed mcp entry <<<';\n\nfunction buildBlock(config: InspektConfig): string {\n const entry = buildMcpEntry(config);\n const argsArr = entry.args.map((a) => `\"${a}\"`).join(', ');\n return [\n BLOCK_START,\n '[mcp_servers.inspekt]',\n `command = \"${entry.command}\"`,\n `args = [${argsArr}]`,\n '',\n '[mcp_servers.inspekt.env]',\n `INSPEKT_TOKEN = \"${entry.env['INSPEKT_TOKEN']}\"`,\n `INSPEKT_QUEUE_PATH = \"${entry.env['INSPEKT_QUEUE_PATH']}\"`,\n BLOCK_END,\n ].join('\\n');\n}\n\nexport async function writeCodex(\n ctx: SetupContext,\n config: InspektConfig,\n): Promise<{ configPath: string }> {\n const descriptor = descriptorFor('codex');\n if (!descriptor) throw new Error('Codex descriptor missing');\n const configPath = descriptor.configPath(ctx.home);\n const dir = path.dirname(configPath);\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n\n const existing = existsSync(configPath) ? await fs.readFile(configPath, 'utf8') : '';\n const block = buildBlock(config);\n\n const startIdx = existing.indexOf(BLOCK_START);\n const endIdx = existing.indexOf(BLOCK_END);\n let next: string;\n if (startIdx !== -1 && endIdx !== -1 && endIdx > startIdx) {\n next = existing.slice(0, startIdx) + block + existing.slice(endIdx + BLOCK_END.length);\n } else {\n next = existing.trim().length > 0 ? `${existing.trimEnd()}\\n\\n${block}\\n` : `${block}\\n`;\n }\n\n await fs.writeFile(configPath, next, 'utf8');\n return { configPath };\n}\n","// Gemini CLI MCP entry writer. Gemini's settings.json lives at\n// ~/.gemini/settings.json with a top-level `mcpServers` key.\n\nimport { buildMcpEntry } from './mcp-entry.js';\nimport { writeMcpEntryToJsonConfig } from './json-writer.js';\nimport { descriptorFor } from '../detect.js';\nimport type { InspektConfig } from '../token.js';\nimport type { SetupContext } from '../types.js';\n\nexport async function writeGeminiCli(\n ctx: SetupContext,\n config: InspektConfig,\n): Promise<{ configPath: string }> {\n const descriptor = descriptorFor('gemini-cli');\n if (!descriptor) throw new Error('Gemini CLI descriptor missing');\n const configPath = descriptor.configPath(ctx.home);\n const entry = buildMcpEntry(config);\n await writeMcpEntryToJsonConfig(configPath, entry, { mcpServersPath: [] });\n return { configPath };\n}\n","// Antigravity is Code-OSS based, so it follows the VS Code-style settings.json\n// convention for MCP servers (under a top-level `mcpServers` key).\n\nimport { buildMcpEntry } from './mcp-entry.js';\nimport { writeMcpEntryToJsonConfig } from './json-writer.js';\nimport { descriptorFor } from '../detect.js';\nimport type { InspektConfig } from '../token.js';\nimport type { SetupContext } from '../types.js';\n\nexport async function writeAntigravity(\n ctx: SetupContext,\n config: InspektConfig,\n): Promise<{ configPath: string }> {\n const descriptor = descriptorFor('antigravity');\n if (!descriptor) throw new Error('Antigravity descriptor missing');\n const configPath = descriptor.configPath(ctx.home);\n const entry = buildMcpEntry(config);\n await writeMcpEntryToJsonConfig(configPath, entry, { mcpServersPath: [] });\n return { configPath };\n}\n","#!/usr/bin/env node\nimport { openInEditor } from './index.js';\nimport { runSetup } from './setup/index.js';\n\nconst args = process.argv.slice(2);\nconst sub = args[0];\n\nfunction printHelp(): void {\n console.log(`Usage:`);\n console.log(` inspekt setup [--agents <list>] Register Inspekt with your installed agents`);\n console.log(` inspekt open <file>[:<line>[:<col>]] [--editor <editor>]`);\n console.log(` inspekt <file>[:<line>[:<col>]] [--editor <editor>] (shorthand for 'open')`);\n console.log(``);\n console.log(`Examples:`);\n console.log(` inspekt setup`);\n console.log(` inspekt setup --agents claude-code,cursor`);\n console.log(` inspekt src/App.tsx:42`);\n console.log(` inspekt src/App.tsx:42:3 --editor cursor`);\n}\n\nif (!sub || sub === '--help' || sub === '-h' || sub === 'help') {\n printHelp();\n process.exit(0);\n}\n\nif (sub === 'setup') {\n const agentsIdx = args.indexOf('--agents');\n const agents = agentsIdx !== -1 && args[agentsIdx + 1] ? args[agentsIdx + 1]!.split(',') : undefined;\n void runSetup({ agents }).catch((err) => {\n console.error('[inspekt setup]', err);\n process.exit(1);\n });\n} else {\n // `inspekt open <file>` or shorthand `inspekt <file>`.\n const filePart = sub === 'open' ? args[1] : sub;\n if (!filePart) {\n printHelp();\n process.exit(1);\n }\n const restStart = sub === 'open' ? 2 : 1;\n let editor: string | undefined;\n const editorIdx = args.indexOf('--editor', restStart);\n const editorIdxShort = args.indexOf('-e', restStart);\n const idx = editorIdx !== -1 ? editorIdx : editorIdxShort;\n if (idx !== -1 && args[idx + 1]) {\n editor = args[idx + 1];\n }\n\n // Parse file:line:column (with Windows-path awareness)\n const parts = filePart.split(':');\n let file: string;\n let line: number | undefined;\n let column: number | undefined;\n if (/^[A-Z]$/i.test(parts[0] ?? '') && (parts[1] ?? '').includes('\\\\')) {\n file = `${parts[0]}:${parts[1]}`;\n line = parts[2] ? parseInt(parts[2], 10) : undefined;\n column = parts[3] ? parseInt(parts[3], 10) : undefined;\n } else {\n file = parts[0]!;\n line = parts[1] ? parseInt(parts[1], 10) : undefined;\n column = parts[2] ? parseInt(parts[2], 10) : undefined;\n }\n\n openInEditor({ file, line, column, editor });\n}\n"],"mappings":"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","names":["os","existsSync","path","fs","existsSync","mkdirSync","path","fs","existsSync","mkdirSync","path","configPath","configPath","path","existsSync","mkdirSync","fs","configPath","fs","existsSync","mkdirSync","path","configPath","path","existsSync","mkdirSync","fs","configPath","configPath","os"]}
package/dist/index.cjs ADDED
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ openInEditor: () => openInEditor,
34
+ resolveEditor: () => resolveEditor
35
+ });
36
+ module.exports = __toCommonJS(index_exports);
37
+ var import_launch_editor = __toESM(require("launch-editor"), 1);
38
+ function openInEditor(options) {
39
+ const { file, line, column, editor } = options;
40
+ let target = file;
41
+ if (line) {
42
+ target += `:${line}`;
43
+ if (column) target += `:${column}`;
44
+ }
45
+ (0, import_launch_editor.default)(target, editor ?? process.env["INSPEKT_EDITOR"] ?? "code");
46
+ }
47
+ function resolveEditor(editor) {
48
+ return editor ?? process.env["INSPEKT_EDITOR"] ?? "code";
49
+ }
50
+ // Annotate the CommonJS export names for ESM import in node:
51
+ 0 && (module.exports = {
52
+ openInEditor,
53
+ resolveEditor
54
+ });
55
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import launchEditor from 'launch-editor';\n\nexport interface OpenFileOptions {\n file: string;\n line?: number;\n column?: number;\n editor?: string;\n}\n\nexport function openInEditor(options: OpenFileOptions): void {\n const { file, line, column, editor } = options;\n let target = file;\n if (line) {\n target += `:${line}`;\n if (column) target += `:${column}`;\n }\n\n launchEditor(target, editor ?? process.env['INSPEKT_EDITOR'] ?? 'code');\n}\n\nexport function resolveEditor(editor?: string): string {\n return editor ?? process.env['INSPEKT_EDITOR'] ?? 'code';\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,2BAAyB;AASlB,SAAS,aAAa,SAAgC;AAC3D,QAAM,EAAE,MAAM,MAAM,QAAQ,OAAO,IAAI;AACvC,MAAI,SAAS;AACb,MAAI,MAAM;AACR,cAAU,IAAI,IAAI;AAClB,QAAI,OAAQ,WAAU,IAAI,MAAM;AAAA,EAClC;AAEA,2BAAAA,SAAa,QAAQ,UAAU,QAAQ,IAAI,gBAAgB,KAAK,MAAM;AACxE;AAEO,SAAS,cAAc,QAAyB;AACrD,SAAO,UAAU,QAAQ,IAAI,gBAAgB,KAAK;AACpD;","names":["launchEditor"]}
@@ -0,0 +1,9 @@
1
+ export interface OpenFileOptions {
2
+ file: string;
3
+ line?: number;
4
+ column?: number;
5
+ editor?: string;
6
+ }
7
+ export declare function openInEditor(options: OpenFileOptions): void;
8
+ export declare function resolveEditor(editor?: string): string;
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI,CAS3D;AAED,wBAAgB,aAAa,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAErD"}
package/dist/index.js ADDED
@@ -0,0 +1,9 @@
1
+ import {
2
+ openInEditor,
3
+ resolveEditor
4
+ } from "./chunk-HD6ANKAP.js";
5
+ export {
6
+ openInEditor,
7
+ resolveEditor
8
+ };
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,11 @@
1
+ import type { AgentId, DetectedAgent } from './types.js';
2
+ export interface AgentDescriptor {
3
+ id: AgentId;
4
+ label: string;
5
+ /** Returns the canonical MCP config path for this agent on this platform. */
6
+ configPath: (home: string) => string;
7
+ }
8
+ export declare const AGENTS: AgentDescriptor[];
9
+ export declare function detectAgents(home?: string): DetectedAgent[];
10
+ export declare function descriptorFor(id: AgentId): AgentDescriptor | undefined;
11
+ //# sourceMappingURL=detect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../../src/setup/detect.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEzD,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,6EAA6E;IAC7E,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CACtC;AAED,eAAO,MAAM,MAAM,EAAE,eAAe,EAuCnC,CAAC;AAEF,wBAAgB,YAAY,CAAC,IAAI,GAAE,MAAqB,GAAG,aAAa,EAAE,CAUzE;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,OAAO,GAAG,eAAe,GAAG,SAAS,CAEtE"}
@@ -0,0 +1,23 @@
1
+ import type { AgentId } from './types.js';
2
+ export interface RunSetupOptions {
3
+ /** Restrict registration to this subset. If omitted, register all detected agents. */
4
+ agents?: string[];
5
+ /** Override home (for tests). */
6
+ home?: string;
7
+ /** When true, suppresses interactive output and only logs paths written. */
8
+ quiet?: boolean;
9
+ }
10
+ export interface SetupResult {
11
+ token: string;
12
+ configPath: string;
13
+ agentsWritten: {
14
+ id: AgentId;
15
+ path: string;
16
+ }[];
17
+ agentsSkipped: {
18
+ id: AgentId;
19
+ reason: string;
20
+ }[];
21
+ }
22
+ export declare function runSetup(opts?: RunSetupOptions): Promise<SetupResult>;
23
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/setup/index.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,OAAO,EAAgB,MAAM,YAAY,CAAC;AAExD,MAAM,WAAW,eAAe;IAC9B,sFAAsF;IACtF,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,iCAAiC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4EAA4E;IAC5E,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC/C,aAAa,EAAE;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAClD;AAED,wBAAsB,QAAQ,CAAC,IAAI,GAAE,eAAoB,GAAG,OAAO,CAAC,WAAW,CAAC,CA+E/E"}
@@ -0,0 +1,13 @@
1
+ export interface InspektConfig {
2
+ token: string;
3
+ host: string;
4
+ port: number;
5
+ queuePath: string;
6
+ }
7
+ export declare function configPath(home: string): string;
8
+ export declare function handshakePath(home: string): string;
9
+ export declare function defaultQueuePath(home: string): string;
10
+ export declare function generateToken(): string;
11
+ export declare function loadOrCreateConfig(home: string): Promise<InspektConfig>;
12
+ export declare function writeHandshake(home: string, config: InspektConfig): Promise<void>;
13
+ //# sourceMappingURL=token.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../src/setup/token.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CA8B7E;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CASvF"}