@ulpi/cli 0.1.4 → 0.1.6

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 (112) hide show
  1. package/LICENSE +21 -0
  2. package/dist/{auth-PN7TMQHV-2W4ICG64.js → auth-FWM7MM4Q-VZC3U2XZ.js} +1 -1
  3. package/dist/{auth-ECQ3IB4E.js → auth-HDK7ECJL.js} +2 -1
  4. package/dist/{chunk-3SBPZRB5.js → chunk-3BCW6ABU.js} +402 -142
  5. package/dist/{chunk-JGBXM5NC.js → chunk-3WB5CXH4.js} +180 -5
  6. package/dist/{chunk-2HEE5OKX.js → chunk-4UCJIAOU.js} +2 -2
  7. package/dist/chunk-4XTHZVDS.js +109 -0
  8. package/dist/chunk-4ZPOZULQ.js +6522 -0
  9. package/dist/{chunk-SIAQVRKG.js → chunk-5MI5GIXM.js} +48 -2
  10. package/dist/{chunk-KLEASXUR.js → chunk-6ZL6NXMV.js} +1 -1
  11. package/dist/chunk-76D3BYJD.js +221 -0
  12. package/dist/{chunk-ZLYRPD7I.js → chunk-AWOSRA5F.js} +1 -1
  13. package/dist/{chunk-PDR55ZNW.js → chunk-BFEKZZHM.js} +274 -57
  14. package/dist/chunk-C7CLUQI6.js +1286 -0
  15. package/dist/{chunk-7AL4DOEJ.js → chunk-E3B5NROU.js} +7 -7
  16. package/dist/chunk-EJ7TW77N.js +1418 -0
  17. package/dist/{chunk-5J6NLQUN.js → chunk-IV6MWETF.js} +383 -168
  18. package/dist/chunk-IZPJHSPX.js +1478 -0
  19. package/dist/chunk-JLHNLM3C.js +228 -0
  20. package/dist/{chunk-BZL5H4YQ.js → chunk-KYYI23AQ.js} +2 -2
  21. package/dist/{chunk-2CLNOKPA.js → chunk-RSFJ6QSR.js} +18 -0
  22. package/dist/chunk-S6ANCSYO.js +1271 -0
  23. package/dist/chunk-SEU7WWNQ.js +1251 -0
  24. package/dist/chunk-SNQ7NAIS.js +453 -0
  25. package/dist/{ulpi-RMMCUAGP-JCJ273T6.js → chunk-TSLDGT5O.js} +73 -35
  26. package/dist/{chunk-SPOI23SB.js → chunk-UXHCHOWQ.js} +83 -62
  27. package/dist/chunk-V2H5D6Y3.js +146 -0
  28. package/dist/{chunk-QJ5GSMEC.js → chunk-VVEDXI7E.js} +2 -1
  29. package/dist/chunk-VXH5Y4FO.js +6761 -0
  30. package/dist/chunk-WED4LM5N.js +322 -0
  31. package/dist/{chunk-74WVVWJ4.js → chunk-YOKL7RB5.js} +184 -15
  32. package/dist/chunk-Z53CAR7G.js +298 -0
  33. package/dist/ci-X3U2W4HC.js +854 -0
  34. package/dist/cloud-2F3NLVHN.js +274 -0
  35. package/dist/{codemap-RKSD4MIE.js → codemap-XNGMAF3F.js} +37 -37
  36. package/dist/codex-MB5YTMRT.js +132 -0
  37. package/dist/{config-EGAXXCGL.js → config-OOELBYTH.js} +1 -1
  38. package/dist/dist-2BJYR5EI.js +59 -0
  39. package/dist/dist-2K7IEVTA.js +43 -0
  40. package/dist/dist-3EIQTZHT.js +1380 -0
  41. package/dist/{dist-YA2BWZB2.js → dist-4U5L2X2C.js} +2 -2
  42. package/dist/{dist-UKMCJBB2.js → dist-54KAMNLO.js} +16 -15
  43. package/dist/dist-6M4MZWZW.js +58 -0
  44. package/dist/dist-6X576SU2.js +27 -0
  45. package/dist/dist-7QOEYLFX.js +103 -0
  46. package/dist/dist-AYBGHEDY.js +2541 -0
  47. package/dist/dist-EK45QNEM.js +45 -0
  48. package/dist/{dist-CS2VKNYS.js → dist-FKFEJRPX.js} +16 -15
  49. package/dist/dist-GTEJUBBT.js +66 -0
  50. package/dist/dist-HA74OKJZ.js +40 -0
  51. package/dist/dist-HU5RZAON.js +48 -0
  52. package/dist/dist-IYE3OBRB.js +374 -0
  53. package/dist/{dist-GJYT2OQV.js → dist-JLU26AB6.js} +12 -9
  54. package/dist/{dist-6G7JC2RA.js → dist-KUCI6JFE.js} +49 -9
  55. package/dist/dist-NUEMFZFL.js +33 -0
  56. package/dist/{dist-RKOGLK7R.js → dist-NUXMDXZ3.js} +31 -3
  57. package/dist/{dist-QAU3LGJN.js → dist-YCNWHSLN.js} +15 -5
  58. package/dist/{dist-CB5D5LMO.js → dist-YFFG2ZD6.js} +9 -16
  59. package/dist/dist-ZG4OKCSR.js +15 -0
  60. package/dist/doctor-SI4LLLDZ.js +345 -0
  61. package/dist/{export-import-4A5MWLIA.js → export-import-JFQH4KSJ.js} +1 -1
  62. package/dist/{history-3MOBX4MA.js → history-5NE46ZAH.js} +7 -7
  63. package/dist/hooks-installer-UN5JZLDQ.js +19 -0
  64. package/dist/index.js +395 -619
  65. package/dist/{init-6CH4HV5T.js → init-5FK3VKRT.js} +79 -13
  66. package/dist/job-HIDMAFW2.js +376 -0
  67. package/dist/jobs.memory-PLMMSFHB-VBECCTHN.js +33 -0
  68. package/dist/kiro-VMUHDFGK.js +153 -0
  69. package/dist/{launchd-LF2QMSKZ.js → launchd-6AWT54HR.js} +9 -17
  70. package/dist/mcp-PDUD7SGP.js +249 -0
  71. package/dist/mcp-installer-PQU3XOGO.js +259 -0
  72. package/dist/mcp-setup-OA7IB3H3.js +263 -0
  73. package/dist/{memory-Y6OZTXJ2.js → memory-ZNAEAK3B.js} +17 -17
  74. package/dist/{ollama-3XCUZMZT-FYKHW4TZ.js → ollama-3XCUZMZT-4JMH6B7P.js} +1 -1
  75. package/dist/{openai-E7G2YAHU-UYY4ZWON.js → openai-E7G2YAHU-T3HMBPH7.js} +2 -2
  76. package/dist/portal-JYWVHXDU.js +210 -0
  77. package/dist/prd-Q4J5NVAR.js +408 -0
  78. package/dist/repos-WWZXNN3P.js +271 -0
  79. package/dist/review-integration-5WHEJU2A.js +14 -0
  80. package/dist/{rules-E427DKYJ.js → rules-Y4VSOY5Y.js} +3 -3
  81. package/dist/run-VPNXEIBY.js +687 -0
  82. package/dist/server-COL4AXKU-P7S7NNF6.js +11 -0
  83. package/dist/server-KKSETHDV-XSSLEENT.js +20 -0
  84. package/dist/{skills-CX73O3IV.js → skills-QEYU2N27.js} +4 -2
  85. package/dist/start-JYOEL7AJ.js +303 -0
  86. package/dist/{status-4DFHDJMN.js → status-BHQYYGAL.js} +2 -2
  87. package/dist/{templates-U7T6MARD.js → templates-CBRUJ66V.js} +4 -3
  88. package/dist/tui-DP7736EX.js +61 -0
  89. package/dist/ulpi-5EN6JCAS-LFE3WSL4.js +10 -0
  90. package/dist/{uninstall-6SW35IK4.js → uninstall-ICUV6DDV.js} +3 -3
  91. package/dist/{update-M6IBJNYP.js → update-7ZMAYRBH.js} +3 -3
  92. package/dist/{version-checker-Q6YTYAGP.js → version-checker-4ZFMZA7Y.js} +2 -2
  93. package/package.json +39 -31
  94. package/dist/chunk-2MZER6ND.js +0 -415
  95. package/dist/chunk-2VYFVYJL.js +0 -4273
  96. package/dist/chunk-6OCEY7JY.js +0 -422
  97. package/dist/chunk-7LXY5UVC.js +0 -330
  98. package/dist/chunk-B55DDP24.js +0 -136
  99. package/dist/chunk-JWUUVXIV.js +0 -13694
  100. package/dist/chunk-MIAQVCFW.js +0 -39
  101. package/dist/chunk-YM2HV4IA.js +0 -505
  102. package/dist/ci-STSL2LSP.js +0 -370
  103. package/dist/mcp-installer-NQCGKQ23.js +0 -124
  104. package/dist/projects-ATHDD3D6.js +0 -271
  105. package/dist/review-ADUPV3PN.js +0 -152
  106. package/dist/server-USLHY6GH-AEOJC5ST.js +0 -18
  107. package/dist/server-X5P6WH2M-7K2RY34N.js +0 -11
  108. package/dist/skills/ulpi-generate-guardian/SKILL.md +0 -750
  109. package/dist/skills/ulpi-generate-guardian/references/framework-rules.md +0 -849
  110. package/dist/skills/ulpi-generate-guardian/references/language-rules.md +0 -591
  111. package/dist/ui-OWXZ3YSR.js +0 -167
  112. package/dist/ui.html +0 -698
@@ -0,0 +1,259 @@
1
+ import {
2
+ getBinaryPath
3
+ } from "./chunk-C7CLUQI6.js";
4
+ import "./chunk-4VNS5WPM.js";
5
+
6
+ // src/mcp-installer.ts
7
+ import * as fs from "fs";
8
+ import * as path from "path";
9
+ import { execFileSync } from "child_process";
10
+ function mcpJsonPath(projectDir) {
11
+ return path.join(projectDir, ".mcp.json");
12
+ }
13
+ function readMcpJson(projectDir) {
14
+ const filePath = mcpJsonPath(projectDir);
15
+ if (fs.existsSync(filePath)) {
16
+ try {
17
+ const data = JSON.parse(fs.readFileSync(filePath, "utf-8"));
18
+ return { mcpServers: data.mcpServers ?? {} };
19
+ } catch {
20
+ }
21
+ }
22
+ return { mcpServers: {} };
23
+ }
24
+ function writeMcpJson(projectDir, mcpServers) {
25
+ const filePath = mcpJsonPath(projectDir);
26
+ fs.writeFileSync(filePath, JSON.stringify({ mcpServers }, null, 2) + "\n", "utf-8");
27
+ }
28
+ function buildMcpEntry(subcommandArgs, description) {
29
+ return { command: getBinaryPath(), args: subcommandArgs, description };
30
+ }
31
+ function installMcpServer(projectDir) {
32
+ const { mcpServers } = readMcpJson(projectDir);
33
+ if (mcpServers["codemap"]) {
34
+ return { installed: false, message: "CodeMap MCP server already registered" };
35
+ }
36
+ mcpServers["codemap"] = buildMcpEntry(["codemap", "serve"], "Semantic code search (hybrid vector + BM25), symbol lookup, file summaries, dependency graph analysis (PageRank, cycles, coupling). Use search_code for concept-based queries, search_symbols to find functions/types by name.");
37
+ writeMcpJson(projectDir, mcpServers);
38
+ return { installed: true, message: "CodeMap MCP server registered in .mcp.json" };
39
+ }
40
+ function uninstallMcpServer(projectDir) {
41
+ const filePath = mcpJsonPath(projectDir);
42
+ if (!fs.existsSync(filePath)) return;
43
+ try {
44
+ const { mcpServers } = readMcpJson(projectDir);
45
+ if (mcpServers["codemap"]) {
46
+ delete mcpServers["codemap"];
47
+ writeMcpJson(projectDir, mcpServers);
48
+ }
49
+ } catch {
50
+ }
51
+ }
52
+ function isMcpServerInstalled(projectDir) {
53
+ const { mcpServers } = readMcpJson(projectDir);
54
+ return !!mcpServers["codemap"];
55
+ }
56
+ function installMemoryMcpServer(projectDir) {
57
+ const { mcpServers } = readMcpJson(projectDir);
58
+ if (mcpServers["memory"]) {
59
+ return { installed: false, message: "Memory MCP server already registered" };
60
+ }
61
+ mcpServers["memory"] = buildMcpEntry(["memory", "serve"], "Persistent agent memory across sessions. Search past decisions, patterns, and learnings. Save new memories, browse timeline, get session context, and manage retention.");
62
+ writeMcpJson(projectDir, mcpServers);
63
+ return { installed: true, message: "Memory MCP server registered in .mcp.json" };
64
+ }
65
+ function uninstallMemoryMcpServer(projectDir) {
66
+ const filePath = mcpJsonPath(projectDir);
67
+ if (!fs.existsSync(filePath)) return;
68
+ try {
69
+ const { mcpServers } = readMcpJson(projectDir);
70
+ if (mcpServers["memory"]) {
71
+ delete mcpServers["memory"];
72
+ writeMcpJson(projectDir, mcpServers);
73
+ }
74
+ } catch {
75
+ }
76
+ }
77
+ function isMemoryMcpServerInstalled(projectDir) {
78
+ const { mcpServers } = readMcpJson(projectDir);
79
+ return !!mcpServers["memory"];
80
+ }
81
+ function installGatewayMcpServer(projectDir) {
82
+ const { mcpServers } = readMcpJson(projectDir);
83
+ if (mcpServers["tools"]) {
84
+ return { installed: false, message: "MCP Gateway server already registered" };
85
+ }
86
+ mcpServers["tools"] = buildMcpEntry(["mcp", "gateway"], "MCP gateway proxy \u2014 aggregates tools from third-party MCP servers (databases, APIs, services) enabled for this project. Tool names are prefixed with the server name (e.g. postgres__query, stripe__list_customers).");
87
+ writeMcpJson(projectDir, mcpServers);
88
+ return { installed: true, message: "MCP Gateway server registered in .mcp.json" };
89
+ }
90
+ function isCommandAvailable(command) {
91
+ try {
92
+ execFileSync("which", [command], { encoding: "utf-8", timeout: 5e3 });
93
+ return true;
94
+ } catch {
95
+ return false;
96
+ }
97
+ }
98
+ function getProjectMcpEntries() {
99
+ const binary = getBinaryPath();
100
+ return {
101
+ codemap: { command: binary, args: ["codemap", "serve"] },
102
+ memory: { command: binary, args: ["memory", "serve"] },
103
+ gateway: { command: binary, args: ["mcp", "gateway"] }
104
+ };
105
+ }
106
+ function readJsonConfig(filePath) {
107
+ if (fs.existsSync(filePath)) {
108
+ try {
109
+ return JSON.parse(fs.readFileSync(filePath, "utf-8"));
110
+ } catch {
111
+ }
112
+ }
113
+ return {};
114
+ }
115
+ function writeJsonConfig(filePath, config) {
116
+ const dir = path.dirname(filePath);
117
+ if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
118
+ fs.writeFileSync(filePath, JSON.stringify(config, null, 2) + "\n", "utf-8");
119
+ }
120
+ function writeCodexProjectMcp(projectDir) {
121
+ const filePath = path.join(projectDir, ".codex", "config.toml");
122
+ const entries = getProjectMcpEntries();
123
+ const added = [];
124
+ let content = "";
125
+ if (fs.existsSync(filePath)) {
126
+ content = fs.readFileSync(filePath, "utf-8");
127
+ }
128
+ const servers = {
129
+ "ulpi-codemap": entries.codemap,
130
+ "ulpi-memory": entries.memory,
131
+ "tools": entries.gateway
132
+ };
133
+ for (const [name, entry] of Object.entries(servers)) {
134
+ const sectionHeader = `[mcp_servers.${name}]`;
135
+ if (content.includes(sectionHeader)) continue;
136
+ const argsToml = entry.args.map((a) => `"${a}"`).join(", ");
137
+ content += `
138
+ ${sectionHeader}
139
+ command = "${entry.command}"
140
+ args = [${argsToml}]
141
+ `;
142
+ added.push(name);
143
+ }
144
+ if (added.length === 0) return null;
145
+ const dir = path.dirname(filePath);
146
+ if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
147
+ fs.writeFileSync(filePath, content, "utf-8");
148
+ return { cli: "Codex", file: ".codex/config.toml", servers: added };
149
+ }
150
+ function writeKiroProjectMcp(projectDir) {
151
+ const filePath = path.join(projectDir, ".kiro", "settings", "mcp.json");
152
+ const entries = getProjectMcpEntries();
153
+ const added = [];
154
+ const config = readJsonConfig(filePath);
155
+ const mcpServers = config.mcpServers ?? {};
156
+ const servers = {
157
+ "ulpi-codemap": entries.codemap,
158
+ "ulpi-memory": entries.memory,
159
+ "tools": entries.gateway
160
+ };
161
+ for (const [name, entry] of Object.entries(servers)) {
162
+ if (mcpServers[name]) continue;
163
+ mcpServers[name] = { command: entry.command, args: entry.args, transportType: "stdio" };
164
+ added.push(name);
165
+ }
166
+ if (added.length === 0) return null;
167
+ config.mcpServers = mcpServers;
168
+ writeJsonConfig(filePath, config);
169
+ return { cli: "Kiro", file: ".kiro/settings/mcp.json", servers: added };
170
+ }
171
+ function writeGeminiProjectMcp(projectDir) {
172
+ const filePath = path.join(projectDir, ".gemini", "settings.json");
173
+ const entries = getProjectMcpEntries();
174
+ const added = [];
175
+ const config = readJsonConfig(filePath);
176
+ const mcpServers = config.mcpServers ?? {};
177
+ const servers = {
178
+ "ulpi-codemap": entries.codemap,
179
+ "ulpi-memory": entries.memory,
180
+ "tools": entries.gateway
181
+ };
182
+ for (const [name, entry] of Object.entries(servers)) {
183
+ if (mcpServers[name]) continue;
184
+ mcpServers[name] = { command: entry.command, args: entry.args };
185
+ added.push(name);
186
+ }
187
+ if (added.length === 0) return null;
188
+ config.mcpServers = mcpServers;
189
+ writeJsonConfig(filePath, config);
190
+ return { cli: "Gemini", file: ".gemini/settings.json", servers: added };
191
+ }
192
+ function writeOpenCodeProjectMcp(projectDir) {
193
+ const filePath = path.join(projectDir, "opencode.json");
194
+ const entries = getProjectMcpEntries();
195
+ const added = [];
196
+ const config = readJsonConfig(filePath);
197
+ const mcp = config.mcp ?? {};
198
+ const servers = {
199
+ "ulpi-codemap": entries.codemap,
200
+ "ulpi-memory": entries.memory,
201
+ "tools": entries.gateway
202
+ };
203
+ for (const [name, entry] of Object.entries(servers)) {
204
+ if (mcp[name]) continue;
205
+ mcp[name] = { command: [entry.command, ...entry.args], type: "local" };
206
+ added.push(name);
207
+ }
208
+ if (added.length === 0) return null;
209
+ config.mcp = mcp;
210
+ writeJsonConfig(filePath, config);
211
+ return { cli: "OpenCode", file: "opencode.json", servers: added };
212
+ }
213
+ function writeDroidProjectMcp(projectDir) {
214
+ const filePath = path.join(projectDir, ".factory", "mcp.json");
215
+ const entries = getProjectMcpEntries();
216
+ const added = [];
217
+ const config = readJsonConfig(filePath);
218
+ const mcpServers = config.mcpServers ?? {};
219
+ const servers = {
220
+ "ulpi-codemap": entries.codemap,
221
+ "ulpi-memory": entries.memory,
222
+ "tools": entries.gateway
223
+ };
224
+ for (const [name, entry] of Object.entries(servers)) {
225
+ if (mcpServers[name]) continue;
226
+ mcpServers[name] = { command: entry.command, args: entry.args, type: "stdio" };
227
+ added.push(name);
228
+ }
229
+ if (added.length === 0) return null;
230
+ config.mcpServers = mcpServers;
231
+ writeJsonConfig(filePath, config);
232
+ return { cli: "Droid", file: ".factory/mcp.json", servers: added };
233
+ }
234
+ function installMcpForAllClis(projectDir) {
235
+ const results = [];
236
+ const clis = [
237
+ { binary: "codex", writer: writeCodexProjectMcp },
238
+ { binary: "kiro", writer: writeKiroProjectMcp },
239
+ { binary: "gemini", writer: writeGeminiProjectMcp },
240
+ { binary: "opencode", writer: writeOpenCodeProjectMcp },
241
+ { binary: "droid", writer: writeDroidProjectMcp }
242
+ ];
243
+ for (const { binary, writer } of clis) {
244
+ if (!isCommandAvailable(binary)) continue;
245
+ const result = writer(projectDir);
246
+ if (result) results.push(result);
247
+ }
248
+ return results;
249
+ }
250
+ export {
251
+ installGatewayMcpServer,
252
+ installMcpForAllClis,
253
+ installMcpServer,
254
+ installMemoryMcpServer,
255
+ isMcpServerInstalled,
256
+ isMemoryMcpServerInstalled,
257
+ uninstallMcpServer,
258
+ uninstallMemoryMcpServer
259
+ };
@@ -0,0 +1,263 @@
1
+ import "./chunk-4VNS5WPM.js";
2
+
3
+ // src/commands/mcp-setup.ts
4
+ import * as fs from "fs";
5
+ import * as path from "path";
6
+ import * as os from "os";
7
+ import { execFileSync } from "child_process";
8
+ import chalk from "chalk";
9
+ function isCommandAvailable(command) {
10
+ try {
11
+ execFileSync("which", [command], { encoding: "utf-8", timeout: 5e3 });
12
+ return true;
13
+ } catch {
14
+ return false;
15
+ }
16
+ }
17
+ function detectAgents() {
18
+ const agents = [];
19
+ const home = os.homedir();
20
+ if (isCommandAvailable("claude")) {
21
+ agents.push({
22
+ name: "Claude Code",
23
+ binary: "claude",
24
+ configPath: path.join(home, ".claude", "settings.json"),
25
+ format: "json"
26
+ });
27
+ }
28
+ if (isCommandAvailable("opencode")) {
29
+ const xdgConfig = process.env.XDG_CONFIG_HOME ?? path.join(home, ".config");
30
+ const opencodePath = path.join(xdgConfig, "opencode", "config.json");
31
+ agents.push({
32
+ name: "OpenCode",
33
+ binary: "opencode",
34
+ configPath: opencodePath,
35
+ format: "json"
36
+ });
37
+ }
38
+ if (isCommandAvailable("gemini")) {
39
+ const xdgConfig = process.env.XDG_CONFIG_HOME ?? path.join(home, ".config");
40
+ agents.push({
41
+ name: "Gemini CLI",
42
+ binary: "gemini",
43
+ configPath: path.join(xdgConfig, "gemini", "settings.json"),
44
+ format: "json"
45
+ });
46
+ }
47
+ if (isCommandAvailable("codex")) {
48
+ agents.push({
49
+ name: "Codex",
50
+ binary: "codex",
51
+ configPath: path.join(home, ".codex", "config.json"),
52
+ format: "json"
53
+ });
54
+ }
55
+ if (isCommandAvailable("kiro")) {
56
+ agents.push({
57
+ name: "Kiro",
58
+ binary: "kiro",
59
+ configPath: path.join(home, ".kiro", "settings", "mcp.json"),
60
+ format: "json-nested"
61
+ });
62
+ }
63
+ if (isCommandAvailable("droid")) {
64
+ const xdgConfig = process.env.XDG_CONFIG_HOME ?? path.join(home, ".config");
65
+ agents.push({
66
+ name: "Droid",
67
+ binary: "droid",
68
+ configPath: path.join(xdgConfig, "droid", "mcp.json"),
69
+ format: "json"
70
+ });
71
+ }
72
+ return agents;
73
+ }
74
+ function buildMcpEntries() {
75
+ return {
76
+ codemap: {
77
+ command: "ulpi",
78
+ args: ["codemap", "serve"]
79
+ },
80
+ memory: {
81
+ command: "ulpi",
82
+ args: ["memory", "serve"]
83
+ },
84
+ gateway: {
85
+ command: "ulpi",
86
+ args: ["mcp", "gateway"]
87
+ }
88
+ };
89
+ }
90
+ function writeJsonMcpConfig(configPath, agentName) {
91
+ const entries = [];
92
+ const mcpEntries = buildMcpEntries();
93
+ let config = {};
94
+ if (fs.existsSync(configPath)) {
95
+ try {
96
+ config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
97
+ } catch {
98
+ }
99
+ }
100
+ const mcpServers = config.mcpServers ?? {};
101
+ let changed = false;
102
+ if (!mcpServers["ulpi-codemap"]) {
103
+ mcpServers["ulpi-codemap"] = mcpEntries.codemap;
104
+ entries.push("ulpi-codemap");
105
+ changed = true;
106
+ }
107
+ if (!mcpServers["ulpi-memory"]) {
108
+ mcpServers["ulpi-memory"] = mcpEntries.memory;
109
+ entries.push("ulpi-memory");
110
+ changed = true;
111
+ }
112
+ if (!mcpServers["tools"]) {
113
+ mcpServers["tools"] = mcpEntries.gateway;
114
+ entries.push("tools");
115
+ changed = true;
116
+ }
117
+ if (changed) {
118
+ config.mcpServers = mcpServers;
119
+ const dir = path.dirname(configPath);
120
+ if (!fs.existsSync(dir)) {
121
+ fs.mkdirSync(dir, { recursive: true });
122
+ }
123
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
124
+ }
125
+ return { written: changed, entries };
126
+ }
127
+ function writeKiroMcpConfig(configPath) {
128
+ const entries = [];
129
+ const mcpEntries = buildMcpEntries();
130
+ let config = {};
131
+ if (fs.existsSync(configPath)) {
132
+ try {
133
+ config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
134
+ } catch {
135
+ }
136
+ }
137
+ const mcpServers = config.mcpServers ?? {};
138
+ let changed = false;
139
+ if (!mcpServers["ulpi-codemap"]) {
140
+ mcpServers["ulpi-codemap"] = {
141
+ command: mcpEntries.codemap.command,
142
+ args: mcpEntries.codemap.args,
143
+ transportType: "stdio"
144
+ };
145
+ entries.push("ulpi-codemap");
146
+ changed = true;
147
+ }
148
+ if (!mcpServers["ulpi-memory"]) {
149
+ mcpServers["ulpi-memory"] = {
150
+ command: mcpEntries.memory.command,
151
+ args: mcpEntries.memory.args,
152
+ transportType: "stdio"
153
+ };
154
+ entries.push("ulpi-memory");
155
+ changed = true;
156
+ }
157
+ if (!mcpServers["tools"]) {
158
+ mcpServers["tools"] = {
159
+ command: mcpEntries.gateway.command,
160
+ args: mcpEntries.gateway.args,
161
+ transportType: "stdio"
162
+ };
163
+ entries.push("tools");
164
+ changed = true;
165
+ }
166
+ if (changed) {
167
+ config.mcpServers = mcpServers;
168
+ const dir = path.dirname(configPath);
169
+ if (!fs.existsSync(dir)) {
170
+ fs.mkdirSync(dir, { recursive: true });
171
+ }
172
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
173
+ }
174
+ return { written: changed, entries };
175
+ }
176
+ function suggestAdditionalMcpServers(projectDir) {
177
+ const suggestions = [];
178
+ suggestions.push(
179
+ `${chalk.cyan("context7")} - Library documentation lookup (npx -y @upstash/context7-mcp@latest)`
180
+ );
181
+ const claudeSettingsPath = path.join(projectDir, ".claude", "settings.local.json");
182
+ if (fs.existsSync(claudeSettingsPath)) {
183
+ try {
184
+ const settings = JSON.parse(fs.readFileSync(claudeSettingsPath, "utf-8"));
185
+ const mcpServers = settings.mcpServers;
186
+ if (mcpServers) {
187
+ const projectServers = Object.keys(mcpServers).filter(
188
+ (k) => !k.startsWith("ulpi-") && k !== "codemap" && k !== "memory"
189
+ );
190
+ if (projectServers.length > 0) {
191
+ suggestions.push(
192
+ `${chalk.dim("Project MCP servers detected:")} ${projectServers.join(", ")}`
193
+ );
194
+ }
195
+ }
196
+ } catch {
197
+ }
198
+ }
199
+ if (suggestions.length > 0) {
200
+ console.log(chalk.bold("\nSuggested additional MCP servers:"));
201
+ for (const suggestion of suggestions) {
202
+ console.log(` ${suggestion}`);
203
+ }
204
+ }
205
+ }
206
+ async function runMcpSetup(projectDir) {
207
+ console.log(chalk.bold("\nULPI MCP Setup\n"));
208
+ const agents = detectAgents();
209
+ if (agents.length === 0) {
210
+ console.log(chalk.yellow("No supported agent CLIs detected on PATH."));
211
+ console.log(chalk.dim("\nSupported agents: claude, opencode, gemini, codex, kiro, droid"));
212
+ console.log(chalk.dim("Install one and run this command again."));
213
+ return;
214
+ }
215
+ console.log(`Detected ${chalk.cyan(String(agents.length))} agent CLI(s):
216
+ `);
217
+ let totalWritten = 0;
218
+ let totalSkipped = 0;
219
+ for (const agent of agents) {
220
+ console.log(` ${chalk.bold(agent.name)} (${chalk.dim(agent.binary)})`);
221
+ console.log(` Config: ${chalk.dim(agent.configPath)}`);
222
+ let result;
223
+ if (agent.format === "json-nested") {
224
+ result = writeKiroMcpConfig(agent.configPath);
225
+ } else {
226
+ result = writeJsonMcpConfig(agent.configPath, agent.name);
227
+ }
228
+ if (result.written) {
229
+ console.log(
230
+ ` ${chalk.green("Added:")} ${result.entries.join(", ")}`
231
+ );
232
+ totalWritten += result.entries.length;
233
+ } else {
234
+ console.log(` ${chalk.dim("Already configured")}`);
235
+ totalSkipped++;
236
+ }
237
+ console.log("");
238
+ }
239
+ if (totalWritten > 0) {
240
+ console.log(
241
+ chalk.green(`Registered ${totalWritten} MCP server(s) across ${agents.length} agent(s).`)
242
+ );
243
+ } else if (totalSkipped > 0) {
244
+ console.log(chalk.dim("All agents already have ULPI MCP servers configured."));
245
+ }
246
+ try {
247
+ const { installMcpForAllClis } = await import("./mcp-installer-PQU3XOGO.js");
248
+ const cliResults = installMcpForAllClis(projectDir);
249
+ if (cliResults.length > 0) {
250
+ console.log(chalk.bold("Project-level MCP configs:\n"));
251
+ for (const result of cliResults) {
252
+ console.log(` ${chalk.green("\u2713")} ${result.cli} \u2014 ${result.file} (${result.servers.join(", ")})`);
253
+ }
254
+ console.log("");
255
+ }
256
+ } catch {
257
+ }
258
+ suggestAdditionalMcpServers(projectDir);
259
+ console.log("");
260
+ }
261
+ export {
262
+ runMcpSetup
263
+ };
@@ -50,8 +50,8 @@ Subcommands:
50
50
  }
51
51
  async function initSubcommand(projectDir) {
52
52
  console.log(chalk.bold("\nAgent Memory -- Initialize\n"));
53
- const { isMemoryInitialized, saveMemoryConfig, DEFAULT_MEMORY_CONFIG } = await import("./dist-GJYT2OQV.js");
54
- const { projectMemoryDir } = await import("./dist-RKOGLK7R.js");
53
+ const { isMemoryInitialized, saveMemoryConfig, DEFAULT_MEMORY_CONFIG } = await import("./dist-JLU26AB6.js");
54
+ const { projectMemoryDir } = await import("./dist-NUXMDXZ3.js");
55
55
  const fs = await import("fs");
56
56
  if (isMemoryInitialized(projectDir)) {
57
57
  console.log(chalk.yellow("Memory is already initialized for this project."));
@@ -67,7 +67,7 @@ async function initSubcommand(projectDir) {
67
67
  console.log(chalk.dim(` Capture mode: ${config.captureMode}`));
68
68
  console.log(chalk.dim(` Classifier: ${config.classifier.enabled ? "enabled" : "disabled"}`));
69
69
  console.log(chalk.dim(` Surface: ${config.surfaceOnStart ? `on start (limit ${config.surfaceLimit})` : "disabled"}`));
70
- const { installMemoryMcpServer } = await import("./mcp-installer-NQCGKQ23.js");
70
+ const { installMemoryMcpServer } = await import("./mcp-installer-PQU3XOGO.js");
71
71
  const mcp = installMemoryMcpServer(projectDir);
72
72
  if (mcp.installed) {
73
73
  console.log(chalk.green("\u2713 MCP server registered"));
@@ -104,7 +104,7 @@ async function searchSubcommand(args, projectDir) {
104
104
  const ora = (await import("ora")).default;
105
105
  const spinner = ora("Searching memories...").start();
106
106
  try {
107
- const { searchMemory, isMemoryInitialized } = await import("./dist-GJYT2OQV.js");
107
+ const { searchMemory, isMemoryInitialized } = await import("./dist-JLU26AB6.js");
108
108
  if (!isMemoryInitialized(projectDir)) {
109
109
  spinner.fail("Memory not initialized");
110
110
  console.log(chalk.dim("Run 'ulpi memory init' first."));
@@ -170,7 +170,7 @@ async function rememberSubcommand(args, projectDir) {
170
170
  console.log(chalk.dim('\nExample: ulpi memory remember "Always run tests before committing" --type PREFERENCE --importance high'));
171
171
  return;
172
172
  }
173
- const { isMemoryInitialized } = await import("./dist-GJYT2OQV.js");
173
+ const { isMemoryInitialized } = await import("./dist-JLU26AB6.js");
174
174
  if (!isMemoryInitialized(projectDir)) {
175
175
  console.log(chalk.red("Error: Memory not initialized. Run 'ulpi memory init' first."));
176
176
  return;
@@ -190,7 +190,7 @@ async function rememberSubcommand(args, projectDir) {
190
190
  const ora = (await import("ora")).default;
191
191
  const spinner = ora("Storing memory...").start();
192
192
  try {
193
- const { generateMemoryId, rememberMemory } = await import("./dist-GJYT2OQV.js");
193
+ const { generateMemoryId, rememberMemory } = await import("./dist-JLU26AB6.js");
194
194
  const now = (/* @__PURE__ */ new Date()).toISOString();
195
195
  const entry = {
196
196
  id: generateMemoryId(memType, text),
@@ -216,7 +216,7 @@ async function rememberSubcommand(args, projectDir) {
216
216
  }
217
217
  }
218
218
  async function statusSubcommand(projectDir) {
219
- const { isMemoryInitialized, getMemoryStats, isMemoryEnabled, loadMemoryConfig } = await import("./dist-GJYT2OQV.js");
219
+ const { isMemoryInitialized, getMemoryStats, isMemoryEnabled, loadMemoryConfig } = await import("./dist-JLU26AB6.js");
220
220
  console.log(chalk.bold("\nAgent Memory Status\n"));
221
221
  if (!isMemoryInitialized(projectDir)) {
222
222
  console.log(chalk.yellow(" Not initialized"));
@@ -257,7 +257,7 @@ async function statusSubcommand(projectDir) {
257
257
  }
258
258
  async function exportSubcommand(projectDir) {
259
259
  console.log(chalk.bold("\nAgent Memory -- Export\n"));
260
- const { isMemoryInitialized, exportMemories } = await import("./dist-GJYT2OQV.js");
260
+ const { isMemoryInitialized, exportMemories } = await import("./dist-JLU26AB6.js");
261
261
  if (!isMemoryInitialized(projectDir)) {
262
262
  console.log(chalk.red("Error: Memory not initialized. Run 'ulpi memory init' first."));
263
263
  return;
@@ -277,7 +277,7 @@ async function exportSubcommand(projectDir) {
277
277
  }
278
278
  async function importSubcommand(projectDir) {
279
279
  console.log(chalk.bold("\nAgent Memory -- Import\n"));
280
- const { importMemories } = await import("./dist-GJYT2OQV.js");
280
+ const { importMemories } = await import("./dist-JLU26AB6.js");
281
281
  try {
282
282
  const result = await importMemories(projectDir);
283
283
  if (!result.success) {
@@ -295,18 +295,18 @@ async function importSubcommand(projectDir) {
295
295
  }
296
296
  }
297
297
  async function serveSubcommand(projectDir) {
298
- const { isMemoryInitialized } = await import("./dist-GJYT2OQV.js");
298
+ const { isMemoryInitialized } = await import("./dist-JLU26AB6.js");
299
299
  if (!isMemoryInitialized(projectDir)) {
300
300
  console.error(chalk.red("Error: Memory not initialized. Run 'ulpi memory init' first."));
301
301
  process.exit(1);
302
302
  }
303
303
  console.error(chalk.dim("[memory-mcp] Starting MCP server..."));
304
304
  console.error(chalk.dim(`[memory-mcp] Project: ${projectDir}`));
305
- const { startMemoryMcpServer } = await import("./dist-CS2VKNYS.js");
305
+ const { startMemoryMcpServer } = await import("./dist-FKFEJRPX.js");
306
306
  await startMemoryMcpServer({ projectDir });
307
307
  }
308
308
  async function classifySubcommand(args, projectDir) {
309
- const { isMemoryInitialized, listCapturedSessions, classifySession, loadWatermark, writeClassifyBatchProgress, clearClassifyBatchProgress } = await import("./dist-GJYT2OQV.js");
309
+ const { isMemoryInitialized, listCapturedSessions, classifySession, loadWatermark, writeClassifyBatchProgress, clearClassifyBatchProgress } = await import("./dist-JLU26AB6.js");
310
310
  if (!isMemoryInitialized(projectDir)) {
311
311
  console.log(chalk.red("Error: Memory not initialized. Run 'ulpi memory init' first."));
312
312
  return;
@@ -341,7 +341,7 @@ async function classifySubcommand(args, projectDir) {
341
341
  }
342
342
  if (doExport) {
343
343
  try {
344
- const { exportMemories } = await import("./dist-GJYT2OQV.js");
344
+ const { exportMemories } = await import("./dist-JLU26AB6.js");
345
345
  await exportMemories(projectDir);
346
346
  } catch {
347
347
  }
@@ -351,7 +351,7 @@ async function classifySubcommand(args, projectDir) {
351
351
  await classifySingleSession(projectDir, sessionId, classifySession);
352
352
  if (doExport) {
353
353
  try {
354
- const { exportMemories } = await import("./dist-GJYT2OQV.js");
354
+ const { exportMemories } = await import("./dist-JLU26AB6.js");
355
355
  const result = await exportMemories(projectDir);
356
356
  console.log(chalk.green(`\u2713 Exported ${result.memoriesExported} memories to ${result.branchName}`));
357
357
  } catch (err) {
@@ -526,7 +526,7 @@ Agent Memory -- Classify Session
526
526
  }
527
527
  }
528
528
  async function enableSubcommand(projectDir) {
529
- const { loadMemoryConfig, saveMemoryConfig, isMemoryInitialized } = await import("./dist-GJYT2OQV.js");
529
+ const { loadMemoryConfig, saveMemoryConfig, isMemoryInitialized } = await import("./dist-JLU26AB6.js");
530
530
  if (!isMemoryInitialized(projectDir)) {
531
531
  console.log(chalk.red("Error: Memory not initialized. Run 'ulpi memory init' first."));
532
532
  return;
@@ -537,7 +537,7 @@ async function enableSubcommand(projectDir) {
537
537
  console.log(chalk.green("\u2713 Memory capture enabled"));
538
538
  }
539
539
  async function disableSubcommand(projectDir) {
540
- const { loadMemoryConfig, saveMemoryConfig, isMemoryInitialized } = await import("./dist-GJYT2OQV.js");
540
+ const { loadMemoryConfig, saveMemoryConfig, isMemoryInitialized } = await import("./dist-JLU26AB6.js");
541
541
  if (!isMemoryInitialized(projectDir)) {
542
542
  console.log(chalk.red("Error: Memory not initialized. Run 'ulpi memory init' first."));
543
543
  return;
@@ -548,7 +548,7 @@ async function disableSubcommand(projectDir) {
548
548
  console.log(chalk.yellow("\u2713 Memory capture disabled"));
549
549
  }
550
550
  async function reindexSubcommand(projectDir) {
551
- const { isMemoryInitialized, reindexMemories } = await import("./dist-GJYT2OQV.js");
551
+ const { isMemoryInitialized, reindexMemories } = await import("./dist-JLU26AB6.js");
552
552
  if (!isMemoryInitialized(projectDir)) {
553
553
  console.log(chalk.red("Error: Memory not initialized. Run 'ulpi memory init' first."));
554
554
  return;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  OllamaEmbedder
3
- } from "./chunk-KLEASXUR.js";
3
+ } from "./chunk-6ZL6NXMV.js";
4
4
  import "./chunk-4VNS5WPM.js";
5
5
  export {
6
6
  OllamaEmbedder
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  OpenAIEmbedder
3
- } from "./chunk-2HEE5OKX.js";
4
- import "./chunk-7LXY5UVC.js";
3
+ } from "./chunk-4UCJIAOU.js";
4
+ import "./chunk-C7CLUQI6.js";
5
5
  import "./chunk-4VNS5WPM.js";
6
6
  export {
7
7
  OpenAIEmbedder