@kilospark/nairo 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/dist/api.d.ts +16 -0
  2. package/dist/api.d.ts.map +1 -0
  3. package/dist/api.js +102 -0
  4. package/dist/api.js.map +1 -0
  5. package/dist/auth-browser.d.ts +5 -0
  6. package/dist/auth-browser.d.ts.map +1 -0
  7. package/dist/auth-browser.js +217 -0
  8. package/dist/auth-browser.js.map +1 -0
  9. package/dist/commands/bootstrap.d.ts +5 -0
  10. package/dist/commands/bootstrap.d.ts.map +1 -0
  11. package/dist/commands/bootstrap.js +363 -0
  12. package/dist/commands/bootstrap.js.map +1 -0
  13. package/dist/commands/delete.d.ts +4 -0
  14. package/dist/commands/delete.d.ts.map +1 -0
  15. package/dist/commands/delete.js +64 -0
  16. package/dist/commands/delete.js.map +1 -0
  17. package/dist/commands/export.d.ts +4 -0
  18. package/dist/commands/export.d.ts.map +1 -0
  19. package/dist/commands/export.js +25 -0
  20. package/dist/commands/export.js.map +1 -0
  21. package/dist/commands/hook.d.ts +4 -0
  22. package/dist/commands/hook.d.ts.map +1 -0
  23. package/dist/commands/hook.js +242 -0
  24. package/dist/commands/hook.js.map +1 -0
  25. package/dist/commands/import.d.ts +2 -0
  26. package/dist/commands/import.d.ts.map +1 -0
  27. package/dist/commands/import.js +210 -0
  28. package/dist/commands/import.js.map +1 -0
  29. package/dist/commands/install.d.ts +9 -0
  30. package/dist/commands/install.d.ts.map +1 -0
  31. package/dist/commands/install.js +282 -0
  32. package/dist/commands/install.js.map +1 -0
  33. package/dist/commands/list.d.ts +5 -0
  34. package/dist/commands/list.d.ts.map +1 -0
  35. package/dist/commands/list.js +90 -0
  36. package/dist/commands/list.js.map +1 -0
  37. package/dist/commands/login.d.ts +2 -0
  38. package/dist/commands/login.d.ts.map +1 -0
  39. package/dist/commands/login.js +24 -0
  40. package/dist/commands/login.js.map +1 -0
  41. package/dist/commands/search.d.ts +4 -0
  42. package/dist/commands/search.d.ts.map +1 -0
  43. package/dist/commands/search.js +42 -0
  44. package/dist/commands/search.js.map +1 -0
  45. package/dist/commands/signup.d.ts +2 -0
  46. package/dist/commands/signup.d.ts.map +1 -0
  47. package/dist/commands/signup.js +6 -0
  48. package/dist/commands/signup.js.map +1 -0
  49. package/dist/config.d.ts +10 -0
  50. package/dist/config.d.ts.map +1 -0
  51. package/dist/config.js +35 -0
  52. package/dist/config.js.map +1 -0
  53. package/dist/index.d.ts +3 -0
  54. package/dist/index.d.ts.map +1 -0
  55. package/dist/index.js +93 -0
  56. package/dist/index.js.map +1 -0
  57. package/dist/prompt.d.ts +10 -0
  58. package/dist/prompt.d.ts.map +1 -0
  59. package/dist/prompt.js +37 -0
  60. package/dist/prompt.js.map +1 -0
  61. package/dist/tools/configure.d.ts +9 -0
  62. package/dist/tools/configure.d.ts.map +1 -0
  63. package/dist/tools/configure.js +326 -0
  64. package/dist/tools/configure.js.map +1 -0
  65. package/dist/tools/detect.d.ts +7 -0
  66. package/dist/tools/detect.d.ts.map +1 -0
  67. package/dist/tools/detect.js +125 -0
  68. package/dist/tools/detect.js.map +1 -0
  69. package/package.json +24 -0
package/dist/index.js ADDED
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire } from "node:module";
3
+ import { Command } from "commander";
4
+ import { loginCommand } from "./commands/login.js";
5
+ import { signupCommand } from "./commands/signup.js";
6
+ import { installCommand } from "./commands/install.js";
7
+ import { bootstrapCommand } from "./commands/bootstrap.js";
8
+ import { listCommand } from "./commands/list.js";
9
+ import { searchCommand } from "./commands/search.js";
10
+ import { deleteCommand } from "./commands/delete.js";
11
+ import { exportCommand } from "./commands/export.js";
12
+ import { importCommand } from "./commands/import.js";
13
+ import { hookPostToolUse, hookSessionStart, hookSessionEnd } from "./commands/hook.js";
14
+ const require = createRequire(import.meta.url);
15
+ const pkg = require("../package.json");
16
+ const program = new Command();
17
+ program
18
+ .name("nairo")
19
+ .description("Nairo CLI — memory layer for AI coding agents")
20
+ .version(pkg.version);
21
+ program
22
+ .command("login")
23
+ .description("Configure CLI with an API key")
24
+ .action(loginCommand);
25
+ program
26
+ .command("signup")
27
+ .description("Alias for login (API-key setup)")
28
+ .action(signupCommand);
29
+ program
30
+ .command("install")
31
+ .description("Set up Nairo MCP for your AI coding tools")
32
+ .option("--api-url <url>", "Nairo API URL")
33
+ .option("--api-key <key>", "Nairo API key")
34
+ .option("--browser-auth", "Force browser sign-in and refresh API key")
35
+ .option("--dry-run", "Preview detected tools and config targets without writing files")
36
+ .action((options) => installCommand(options));
37
+ program.action(() => {
38
+ installCommand().catch((error) => {
39
+ const message = error instanceof Error ? error.message : String(error);
40
+ console.error(`Install failed: ${message}`);
41
+ process.exit(1);
42
+ });
43
+ });
44
+ program
45
+ .command("bootstrap")
46
+ .description("Extract memory events from project files")
47
+ .option("-p, --project <name>", "Project name")
48
+ .option("-y, --yes", "Accept all extracted events without interactive review")
49
+ .action((options) => bootstrapCommand(options));
50
+ program
51
+ .command("list")
52
+ .description("List memory events")
53
+ .option("-p, --project <id>", "Project ID")
54
+ .option("-t, --type <type>", "Filter by event type")
55
+ .action((options) => listCommand(options));
56
+ program
57
+ .command("search")
58
+ .description("Search memory events")
59
+ .argument("<query>", "Search query")
60
+ .option("-p, --project <id>", "Project ID")
61
+ .action((query, options) => searchCommand(query, options));
62
+ program
63
+ .command("delete")
64
+ .description("Delete a memory event")
65
+ .argument("[eventId]", "Event ID to delete")
66
+ .option("-a, --all", "Delete all events")
67
+ .action((eventId, options) => deleteCommand(eventId, options));
68
+ program
69
+ .command("export")
70
+ .description("Export all data as JSON")
71
+ .option("-o, --output <file>", "Output file path")
72
+ .action((options) => exportCommand(options));
73
+ program
74
+ .command("import")
75
+ .description("Import local conversation source references as pending memory")
76
+ .action(importCommand);
77
+ const hook = program
78
+ .command("hook")
79
+ .description("Claude Code hook handlers (used internally)");
80
+ hook
81
+ .command("post-tool-use")
82
+ .description("Handle PostToolUse hook event")
83
+ .action(hookPostToolUse);
84
+ hook
85
+ .command("session-start")
86
+ .description("Handle SessionStart hook event")
87
+ .action(hookSessionStart);
88
+ hook
89
+ .command("session-end")
90
+ .description("Handle SessionEnd hook event")
91
+ .action(hookSessionEnd);
92
+ program.parse();
93
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Prompt the user for input via readline.
3
+ */
4
+ export declare function prompt(question: string): Promise<string>;
5
+ /**
6
+ * Prompt for a password (input is hidden).
7
+ * Uses a muted output stream so typed characters are not echoed.
8
+ */
9
+ export declare function promptPassword(question: string): Promise<string>;
10
+ //# sourceMappingURL=prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../src/prompt.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAYxD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAiBhE"}
package/dist/prompt.js ADDED
@@ -0,0 +1,37 @@
1
+ import { createInterface } from "node:readline";
2
+ /**
3
+ * Prompt the user for input via readline.
4
+ */
5
+ export function prompt(question) {
6
+ const rl = createInterface({
7
+ input: process.stdin,
8
+ output: process.stdout,
9
+ });
10
+ return new Promise((resolve) => {
11
+ rl.question(question, (answer) => {
12
+ rl.close();
13
+ resolve(answer.trim());
14
+ });
15
+ });
16
+ }
17
+ /**
18
+ * Prompt for a password (input is hidden).
19
+ * Uses a muted output stream so typed characters are not echoed.
20
+ */
21
+ export function promptPassword(question) {
22
+ return new Promise((resolve) => {
23
+ // Write the question before muting
24
+ process.stdout.write(question);
25
+ const rl = createInterface({
26
+ input: process.stdin,
27
+ output: process.stdout,
28
+ terminal: false,
29
+ });
30
+ rl.on("line", (line) => {
31
+ rl.close();
32
+ process.stdout.write("\n");
33
+ resolve(line.trim());
34
+ });
35
+ });
36
+ }
37
+ //# sourceMappingURL=prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../src/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD;;GAEG;AACH,MAAM,UAAU,MAAM,CAAC,QAAgB;IACrC,MAAM,EAAE,GAAG,eAAe,CAAC;QACzB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAC,CAAC;IAEH,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,EAAE;YAC/B,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,mCAAmC;QACnC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAE/B,MAAM,EAAE,GAAG,eAAe,CAAC;YACzB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,QAAQ,EAAE,KAAK;SAChB,CAAC,CAAC;QAEH,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACrB,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC3B,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACvB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { DetectedTool } from "./detect.js";
2
+ export declare function hasNairoMcpConfig(tool: DetectedTool, apiUrl?: string): boolean;
3
+ /**
4
+ * Configure a detected tool's MCP config to include Nairo.
5
+ */
6
+ export declare function configureTool(tool: DetectedTool, apiKey: string, apiUrl: string, options?: {
7
+ dryRun?: boolean;
8
+ }): void;
9
+ //# sourceMappingURL=configure.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configure.d.ts","sourceRoot":"","sources":["../../src/tools/configure.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAoIhD,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,YAAY,EAClB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAoET;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,YAAY,EAClB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GACjC,IAAI,CA0KN"}
@@ -0,0 +1,326 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, } from "node:fs";
2
+ import { dirname } from "node:path";
3
+ import { spawnSync } from "node:child_process";
4
+ import { homedir } from "node:os";
5
+ import { join } from "node:path";
6
+ /**
7
+ * Read a JSON file safely, returning an empty object if it doesn't exist or is invalid.
8
+ */
9
+ function readJsonFile(filePath) {
10
+ try {
11
+ if (!existsSync(filePath)) {
12
+ return {};
13
+ }
14
+ const raw = readFileSync(filePath, "utf-8");
15
+ return JSON.parse(raw);
16
+ }
17
+ catch {
18
+ return {};
19
+ }
20
+ }
21
+ /**
22
+ * Write a JSON file, creating parent directories if needed.
23
+ */
24
+ function writeJsonFile(filePath, data) {
25
+ const dir = dirname(filePath);
26
+ if (!existsSync(dir)) {
27
+ mkdirSync(dir, { recursive: true });
28
+ }
29
+ writeFileSync(filePath, JSON.stringify(data, null, 2) + "\n", "utf-8");
30
+ }
31
+ function shellRcPath() {
32
+ const home = homedir();
33
+ const shell = process.env.SHELL || "";
34
+ if (shell.endsWith("zsh"))
35
+ return join(home, ".zshrc");
36
+ if (shell.endsWith("bash"))
37
+ return join(home, ".bashrc");
38
+ if (shell.endsWith("fish"))
39
+ return join(home, ".config", "fish", "config.fish");
40
+ return join(home, ".zshrc");
41
+ }
42
+ function persistCodexApiKey(apiKey) {
43
+ const rcPath = shellRcPath();
44
+ if (!rcPath)
45
+ return;
46
+ const dir = dirname(rcPath);
47
+ if (!existsSync(dir)) {
48
+ mkdirSync(dir, { recursive: true });
49
+ }
50
+ const start = "# >>> nairo codex >>>";
51
+ const end = "# <<< nairo codex <<<";
52
+ const shell = process.env.SHELL || "";
53
+ const exportLine = shell.endsWith("fish")
54
+ ? `set -gx NAIRO_API_KEY "${apiKey}"`
55
+ : `export NAIRO_API_KEY="${apiKey}"`;
56
+ const block = `${start}\n${exportLine}\n${end}`;
57
+ let current = "";
58
+ if (existsSync(rcPath)) {
59
+ current = readFileSync(rcPath, "utf-8");
60
+ }
61
+ const pattern = new RegExp(`${start.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}[\\s\\S]*?${end.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}`, "m");
62
+ if (pattern.test(current)) {
63
+ current = current.replace(pattern, block);
64
+ }
65
+ else {
66
+ current = `${current.trimEnd()}\n\n${block}\n`;
67
+ }
68
+ writeFileSync(rcPath, current, "utf-8");
69
+ // macOS GUI apps (and terminal sessions spawned by launchd) won't always
70
+ // inherit shell rc exports. Set launchd env so Codex can resolve the token.
71
+ if (process.platform === "darwin") {
72
+ spawnSync("launchctl", ["setenv", "NAIRO_API_KEY", apiKey], {
73
+ stdio: "ignore",
74
+ });
75
+ }
76
+ }
77
+ function setCodexNairoHttpHeader(configPath, apiKey) {
78
+ const headerLine = `http_headers = { Authorization = "Bearer ${apiKey}" }`;
79
+ const sectionHeader = "[mcp_servers.nairo]";
80
+ let raw = "";
81
+ if (existsSync(configPath)) {
82
+ raw = readFileSync(configPath, "utf-8");
83
+ }
84
+ const lines = raw.length > 0 ? raw.split("\n") : [];
85
+ const start = lines.findIndex((line) => line.trim() === sectionHeader);
86
+ if (start === -1) {
87
+ const suffix = raw.endsWith("\n") || raw.length === 0 ? "" : "\n";
88
+ const block = `${suffix}${sectionHeader}\n${headerLine}\n`;
89
+ writeFileSync(configPath, raw + block, "utf-8");
90
+ return;
91
+ }
92
+ let end = lines.length;
93
+ for (let i = start + 1; i < lines.length; i++) {
94
+ if (lines[i].startsWith("[") && lines[i].endsWith("]")) {
95
+ end = i;
96
+ break;
97
+ }
98
+ }
99
+ const before = lines.slice(0, start + 1);
100
+ const body = lines
101
+ .slice(start + 1, end)
102
+ .filter((line) => !line.trim().startsWith("bearer_token_env_var"))
103
+ .filter((line) => !line.trim().startsWith("http_headers"));
104
+ const after = lines.slice(end);
105
+ const next = [...before, ...body, headerLine, ...after].join("\n");
106
+ writeFileSync(configPath, next, "utf-8");
107
+ }
108
+ /**
109
+ * Build the MCP server entry for Nairo.
110
+ */
111
+ function nairoMcpEntry(apiUrl, apiKey) {
112
+ const baseUrl = apiUrl.replace(/\/+$/, "");
113
+ return {
114
+ url: `${baseUrl}/api/mcp`,
115
+ headers: { Authorization: `Bearer ${apiKey}` },
116
+ };
117
+ }
118
+ export function hasNairoMcpConfig(tool, apiUrl) {
119
+ const expectedUrl = apiUrl
120
+ ? `${apiUrl.replace(/\/+$/, "")}/api/mcp`
121
+ : null;
122
+ // Codex config is TOML; a pragmatic detection is enough here.
123
+ if (tool.name === "Codex") {
124
+ if (!existsSync(tool.configPath))
125
+ return false;
126
+ try {
127
+ const raw = readFileSync(tool.configPath, "utf-8");
128
+ if (!raw.includes("nairo"))
129
+ return false;
130
+ return expectedUrl ? raw.includes(expectedUrl) : true;
131
+ }
132
+ catch {
133
+ return false;
134
+ }
135
+ }
136
+ if (!existsSync(tool.configPath))
137
+ return false;
138
+ const config = readJsonFile(tool.configPath);
139
+ const candidates = [];
140
+ const mcpServers = config.mcpServers;
141
+ if (mcpServers?.nairo)
142
+ candidates.push(mcpServers.nairo);
143
+ const mcpDotServers = config["mcp.servers"];
144
+ if (mcpDotServers?.nairo)
145
+ candidates.push(mcpDotServers.nairo);
146
+ const contextServers = config.context_servers;
147
+ if (contextServers?.nairo)
148
+ candidates.push(contextServers.nairo);
149
+ const experimental = config.experimental;
150
+ const continueServers = experimental?.modelContextProtocolServers;
151
+ if (Array.isArray(continueServers)) {
152
+ for (const server of continueServers) {
153
+ const transport = server.transport;
154
+ if (transport?.url && String(transport.url).includes("/api/mcp")) {
155
+ candidates.push(server);
156
+ }
157
+ }
158
+ }
159
+ for (const candidate of candidates) {
160
+ const obj = candidate;
161
+ const directUrl = typeof obj.url === "string"
162
+ ? obj.url
163
+ : typeof obj.settings?.url ===
164
+ "string"
165
+ ? String(obj.settings.url)
166
+ : typeof obj.transport?.url ===
167
+ "string"
168
+ ? String(obj.transport.url)
169
+ : null;
170
+ if (!directUrl)
171
+ continue;
172
+ if (!directUrl.includes("/api/mcp"))
173
+ continue;
174
+ if (expectedUrl && directUrl !== expectedUrl)
175
+ continue;
176
+ return true;
177
+ }
178
+ return false;
179
+ }
180
+ /**
181
+ * Configure a detected tool's MCP config to include Nairo.
182
+ */
183
+ export function configureTool(tool, apiKey, apiUrl, options = {}) {
184
+ const entry = nairoMcpEntry(apiUrl, apiKey);
185
+ const dryRun = options.dryRun === true;
186
+ if (dryRun) {
187
+ return;
188
+ }
189
+ switch (tool.name) {
190
+ case "Claude Code": {
191
+ const config = readJsonFile(tool.configPath);
192
+ const mcpServers = config.mcpServers ?? {};
193
+ mcpServers.nairo = {
194
+ type: "http",
195
+ ...entry,
196
+ };
197
+ config.mcpServers = mcpServers;
198
+ writeJsonFile(tool.configPath, config);
199
+ break;
200
+ }
201
+ case "Cursor": {
202
+ const config = readJsonFile(tool.configPath);
203
+ const mcpServers = config.mcpServers ?? {};
204
+ mcpServers.nairo = entry;
205
+ config.mcpServers = mcpServers;
206
+ writeJsonFile(tool.configPath, config);
207
+ break;
208
+ }
209
+ case "VS Code (Copilot)": {
210
+ const config = readJsonFile(tool.configPath);
211
+ const mcpServers = config["mcp.servers"] ?? {};
212
+ mcpServers.nairo = {
213
+ type: "sse",
214
+ ...entry,
215
+ };
216
+ config["mcp.servers"] = mcpServers;
217
+ writeJsonFile(tool.configPath, config);
218
+ break;
219
+ }
220
+ case "Windsurf": {
221
+ const config = readJsonFile(tool.configPath);
222
+ const mcpServers = config.mcpServers ?? {};
223
+ mcpServers.nairo = entry;
224
+ config.mcpServers = mcpServers;
225
+ writeJsonFile(tool.configPath, config);
226
+ break;
227
+ }
228
+ case "Opencode": {
229
+ const config = readJsonFile(tool.configPath);
230
+ const mcpServers = config.mcpServers ?? {};
231
+ mcpServers.nairo = entry;
232
+ config.mcpServers = mcpServers;
233
+ writeJsonFile(tool.configPath, config);
234
+ break;
235
+ }
236
+ case "Codex": {
237
+ const baseUrl = apiUrl.replace(/\/+$/, "");
238
+ const codexEnv = { ...process.env, NAIRO_API_KEY: apiKey };
239
+ // Persist for future Codex launches; no manual "source" file flow.
240
+ persistCodexApiKey(apiKey);
241
+ // Ignore remove failures (server may not exist yet).
242
+ spawnSync("codex", ["mcp", "remove", "nairo"], {
243
+ env: codexEnv,
244
+ stdio: "ignore",
245
+ });
246
+ const add = spawnSync("codex", [
247
+ "mcp",
248
+ "add",
249
+ "nairo",
250
+ "--url",
251
+ `${baseUrl}/api/mcp`,
252
+ "--bearer-token-env-var",
253
+ "NAIRO_API_KEY",
254
+ ], { env: codexEnv, encoding: "utf-8" });
255
+ if (add.error) {
256
+ throw add.error;
257
+ }
258
+ if (add.status !== 0) {
259
+ throw new Error(add.stderr?.trim() || "codex mcp add failed");
260
+ }
261
+ // Avoid env propagation pitfalls by pinning header auth in Codex config.
262
+ setCodexNairoHttpHeader(tool.configPath, apiKey);
263
+ break;
264
+ }
265
+ case "Gemini": {
266
+ const config = readJsonFile(tool.configPath);
267
+ const mcpServers = config.mcpServers ?? {};
268
+ mcpServers.nairo = entry;
269
+ config.mcpServers = mcpServers;
270
+ writeJsonFile(tool.configPath, config);
271
+ break;
272
+ }
273
+ case "Droid": {
274
+ const config = readJsonFile(tool.configPath);
275
+ const mcpServers = config.mcpServers ?? {};
276
+ mcpServers.nairo = entry;
277
+ config.mcpServers = mcpServers;
278
+ writeJsonFile(tool.configPath, config);
279
+ break;
280
+ }
281
+ case "Zed": {
282
+ const config = readJsonFile(tool.configPath);
283
+ const contextServers = config.context_servers ?? {};
284
+ contextServers.nairo = {
285
+ settings: entry,
286
+ };
287
+ config.context_servers = contextServers;
288
+ writeJsonFile(tool.configPath, config);
289
+ break;
290
+ }
291
+ case "Continue": {
292
+ const config = readJsonFile(tool.configPath);
293
+ const experimental = config.experimental ?? {};
294
+ const servers = experimental.modelContextProtocolServers ?? [];
295
+ // Remove existing nairo entry if present (matching by URL)
296
+ const mcpUrl = `${apiUrl.replace(/\/+$/, "")}/api/mcp`;
297
+ const filtered = servers.filter((s) => {
298
+ const transport = s.transport;
299
+ return transport?.url !== mcpUrl;
300
+ });
301
+ // Add Nairo server entry
302
+ filtered.push({
303
+ transport: {
304
+ type: "sse",
305
+ url: mcpUrl,
306
+ },
307
+ headers: { Authorization: `Bearer ${apiKey}` },
308
+ });
309
+ experimental.modelContextProtocolServers = filtered;
310
+ config.experimental = experimental;
311
+ writeJsonFile(tool.configPath, config);
312
+ break;
313
+ }
314
+ case "Cline": {
315
+ const config = readJsonFile(tool.configPath);
316
+ const mcpServers = config.mcpServers ?? {};
317
+ mcpServers.nairo = entry;
318
+ config.mcpServers = mcpServers;
319
+ writeJsonFile(tool.configPath, config);
320
+ break;
321
+ }
322
+ default:
323
+ console.log(` [skip] Unknown tool: ${tool.name}`);
324
+ }
325
+ }
326
+ //# sourceMappingURL=configure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configure.js","sourceRoot":"","sources":["../../src/tools/configure.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export interface DetectedTool {
2
+ name: string;
3
+ configPath: string;
4
+ detected: boolean;
5
+ }
6
+ export declare function detectTools(): DetectedTool[];
7
+ //# sourceMappingURL=detect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../../src/tools/detect.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,WAAW,IAAI,YAAY,EAAE,CAyL5C"}
@@ -0,0 +1,125 @@
1
+ import { existsSync } from "node:fs";
2
+ import { homedir, platform } from "node:os";
3
+ import { join } from "node:path";
4
+ export function detectTools() {
5
+ const home = homedir();
6
+ const os = platform();
7
+ const tools = [
8
+ {
9
+ name: "Claude Code",
10
+ configPath: join(home, ".claude.json"),
11
+ detected: false,
12
+ },
13
+ {
14
+ name: "Cursor",
15
+ configPath: join(home, ".cursor", "mcp.json"),
16
+ detected: false,
17
+ },
18
+ {
19
+ name: "VS Code (Copilot)",
20
+ configPath: os === "darwin"
21
+ ? join(home, "Library", "Application Support", "Code", "User", "settings.json")
22
+ : os === "win32"
23
+ ? join(home, "AppData", "Roaming", "Code", "User", "settings.json")
24
+ : join(home, ".config", "Code", "User", "settings.json"),
25
+ detected: false,
26
+ },
27
+ {
28
+ name: "Windsurf",
29
+ configPath: join(home, ".codeium", "windsurf", "mcp_config.json"),
30
+ detected: false,
31
+ },
32
+ {
33
+ name: "Opencode",
34
+ configPath: join(home, ".config", "opencode", "config.json"),
35
+ detected: false,
36
+ },
37
+ {
38
+ name: "Codex",
39
+ configPath: join(home, ".codex", "config.toml"),
40
+ detected: false,
41
+ },
42
+ {
43
+ name: "Gemini",
44
+ configPath: join(home, ".gemini", "antigravity", "mcp_config.json"),
45
+ detected: false,
46
+ },
47
+ {
48
+ name: "Droid",
49
+ configPath: join(home, ".config", "droid", "config.json"),
50
+ detected: false,
51
+ },
52
+ {
53
+ name: "Zed",
54
+ configPath: join(home, ".config", "zed", "settings.json"),
55
+ detected: false,
56
+ },
57
+ {
58
+ name: "Continue",
59
+ configPath: join(home, ".continue", "config.json"),
60
+ detected: false,
61
+ },
62
+ {
63
+ name: "Cline",
64
+ configPath: os === "darwin"
65
+ ? join(home, ".vscode", "globalStorage", "saoudrizwan.claude-dev", "settings", "cline_mcp_settings.json")
66
+ : os === "win32"
67
+ ? join(home, ".vscode", "globalStorage", "saoudrizwan.claude-dev", "settings", "cline_mcp_settings.json")
68
+ : join(home, ".vscode", "globalStorage", "saoudrizwan.claude-dev", "settings", "cline_mcp_settings.json"),
69
+ detected: false,
70
+ },
71
+ ];
72
+ for (const tool of tools) {
73
+ if (tool.name === "Opencode") {
74
+ const opencodeConfigDir = join(home, ".config", "opencode");
75
+ const opencodeLocalBin = join(home, ".opencode", "bin", "opencode");
76
+ const opencodeXdgBin = join(home, ".local", "share", "opencode", "bin", "opencode");
77
+ tool.detected =
78
+ existsSync(tool.configPath) ||
79
+ existsSync(opencodeConfigDir) ||
80
+ existsSync(opencodeLocalBin) ||
81
+ existsSync(opencodeXdgBin);
82
+ continue;
83
+ }
84
+ if (tool.name === "Gemini") {
85
+ const geminiDir = join(home, ".gemini");
86
+ const geminiAntigravityDir = join(home, ".gemini", "antigravity");
87
+ const geminiLocalBin = join(home, ".gemini", "bin", "gemini");
88
+ const geminiXdgBin = join(home, ".local", "share", "gemini", "bin", "gemini");
89
+ tool.detected =
90
+ existsSync(tool.configPath) ||
91
+ existsSync(geminiDir) ||
92
+ existsSync(geminiAntigravityDir) ||
93
+ existsSync(geminiLocalBin) ||
94
+ existsSync(geminiXdgBin);
95
+ continue;
96
+ }
97
+ if (tool.name === "Codex") {
98
+ const codexDir = join(home, ".codex");
99
+ const codexLocalBin = join(home, ".local", "bin", "codex");
100
+ const codexXdgBin = join(home, ".local", "share", "codex", "bin", "codex");
101
+ tool.detected =
102
+ existsSync(tool.configPath) ||
103
+ existsSync(codexDir) ||
104
+ existsSync(codexLocalBin) ||
105
+ existsSync(codexXdgBin);
106
+ continue;
107
+ }
108
+ if (tool.name === "Droid") {
109
+ const droidConfigDir = join(home, ".config", "droid");
110
+ const droidAltConfig = join(home, ".droid", "config.json");
111
+ const droidLocalBin = join(home, ".droid", "bin", "droid");
112
+ const droidXdgBin = join(home, ".local", "share", "droid", "bin", "droid");
113
+ tool.detected =
114
+ existsSync(tool.configPath) ||
115
+ existsSync(droidConfigDir) ||
116
+ existsSync(droidAltConfig) ||
117
+ existsSync(droidLocalBin) ||
118
+ existsSync(droidXdgBin);
119
+ continue;
120
+ }
121
+ tool.detected = existsSync(tool.configPath);
122
+ }
123
+ return tools;
124
+ }
125
+ //# sourceMappingURL=detect.js.map