@ulpi/cli 0.1.5 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +143 -214
- package/dist/{auth-PN7TMQHV-2W4ICG64.js → auth-FWM7MM4Q-VZC3U2XZ.js} +1 -1
- package/dist/{auth-BFFBUJUC.js → auth-HDK7ECJL.js} +2 -1
- package/dist/{chunk-RJIRWQJD.js → chunk-3BCW6ABU.js} +402 -142
- package/dist/{chunk-L3PWNHSA.js → chunk-3WB5CXH4.js} +180 -5
- package/dist/{chunk-K4OVPFY2.js → chunk-4UCJIAOU.js} +2 -2
- package/dist/chunk-4XTHZVDS.js +109 -0
- package/dist/chunk-4ZPOZULQ.js +6522 -0
- package/dist/{chunk-SIAQVRKG.js → chunk-5MI5GIXM.js} +48 -2
- package/dist/{chunk-KLEASXUR.js → chunk-6ZL6NXMV.js} +1 -1
- package/dist/{chunk-AV5RB3N2.js → chunk-76D3BYJD.js} +48 -0
- package/dist/{chunk-DOIKS6C5.js → chunk-AWOSRA5F.js} +1 -1
- package/dist/{chunk-UCMT5OKP.js → chunk-BFEKZZHM.js} +274 -57
- package/dist/chunk-C7CLUQI6.js +1286 -0
- package/dist/{chunk-ELTGWMDE.js → chunk-E3B5NROU.js} +7 -7
- package/dist/chunk-EJ7TW77N.js +1418 -0
- package/dist/{chunk-P2RESJRN.js → chunk-EWLYVXQ4.js} +2 -2
- package/dist/{chunk-6OURRFP7.js → chunk-IV6MWETF.js} +383 -168
- package/dist/chunk-IZPJHSPX.js +1478 -0
- package/dist/chunk-JLHNLM3C.js +228 -0
- package/dist/chunk-PO4NUZUU.js +147 -0
- package/dist/chunk-S6ANCSYO.js +1271 -0
- package/dist/chunk-SEU7WWNQ.js +1251 -0
- package/dist/chunk-SNQ7NAIS.js +453 -0
- package/dist/{ulpi-RMMCUAGP-EWYUE7RU.js → chunk-TSLDGT5O.js} +73 -35
- package/dist/{chunk-EIWYSP3A.js → chunk-UXHCHOWQ.js} +83 -62
- package/dist/chunk-WED4LM5N.js +322 -0
- package/dist/chunk-WVOZE25N.js +6757 -0
- package/dist/{chunk-5SCG7UYM.js → chunk-XKF4DPUM.js} +7 -7
- package/dist/{chunk-74WVVWJ4.js → chunk-YOKL7RB5.js} +184 -15
- package/dist/chunk-Z53CAR7G.js +298 -0
- package/dist/{ci-JQ56YIKC.js → ci-COZRTPGQ.js} +124 -26
- package/dist/cloud-2F3NLVHN.js +274 -0
- package/dist/{codemap-HMYBXJL2.js → codemap-XNGMAF3F.js} +37 -37
- package/dist/codex-MB5YTMRT.js +132 -0
- package/dist/{config-YYWEN7U2.js → config-OOELBYTH.js} +1 -1
- package/dist/dist-2BJYR5EI.js +59 -0
- package/dist/dist-3EIQTZHT.js +1380 -0
- package/dist/{dist-WAMAQVPK.js → dist-4U5L2X2C.js} +2 -2
- package/dist/{dist-4XTJ6HLM.js → dist-54KAMNLO.js} +16 -15
- package/dist/dist-6M4MZWZW.js +58 -0
- package/dist/dist-6X576SU2.js +27 -0
- package/dist/dist-7QOEYLFX.js +103 -0
- package/dist/dist-AYBGHEDY.js +2541 -0
- package/dist/dist-EK45QNEM.js +45 -0
- package/dist/{dist-U7ZIJMZD.js → dist-FKFEJRPX.js} +16 -15
- package/dist/dist-GTEJUBBT.js +66 -0
- package/dist/dist-HA74OKJZ.js +40 -0
- package/dist/{dist-XG2GG5SD.js → dist-HU5RZAON.js} +14 -2
- package/dist/dist-IYE3OBRB.js +374 -0
- package/dist/{dist-7WLLPWWB.js → dist-JLU26AB6.js} +12 -9
- package/dist/{dist-6G7JC2RA.js → dist-KUCI6JFE.js} +49 -9
- package/dist/dist-NUEMFZFL.js +33 -0
- package/dist/{dist-GWGTAHNM.js → dist-NUXMDXZ3.js} +31 -3
- package/dist/{dist-5R4RYNQO.js → dist-YCNWHSLN.js} +15 -5
- package/dist/{dist-6MFVWIFF.js → dist-YFFG2ZD6.js} +9 -16
- package/dist/dist-ZG4OKCSR.js +15 -0
- package/dist/doctor-FKYSIHER.js +345 -0
- package/dist/{export-import-4A5MWLIA.js → export-import-JFQH4KSJ.js} +1 -1
- package/dist/{history-RNUWO4JZ.js → history-UMGQNQQ7.js} +7 -7
- package/dist/{hooks-installer-K2JXEBNN.js → hooks-installer-YEYTYA6Q.js} +2 -2
- package/dist/index.js +398 -622
- package/dist/{init-NQWFZPKO.js → init-TJYW5ROZ.js} +78 -12
- package/dist/job-HIDMAFW2.js +376 -0
- package/dist/jobs.memory-PLMMSFHB-VBECCTHN.js +33 -0
- package/dist/kiro-VMUHDFGK.js +153 -0
- package/dist/{launchd-OYXUAVW6.js → launchd-U3MSWBRH.js} +9 -17
- package/dist/mcp-PDUD7SGP.js +249 -0
- package/dist/mcp-installer-PQU3XOGO.js +259 -0
- package/dist/mcp-setup-OA7IB3H3.js +263 -0
- package/dist/{memory-D6ZFFCI2.js → memory-ZNAEAK3B.js} +17 -17
- package/dist/{ollama-3XCUZMZT-FYKHW4TZ.js → ollama-3XCUZMZT-4JMH6B7P.js} +1 -1
- package/dist/{openai-E7G2YAHU-IG33BFYF.js → openai-E7G2YAHU-T3HMBPH7.js} +2 -2
- package/dist/portal-JYWVHXDU.js +210 -0
- package/dist/prd-Q4J5NVAR.js +408 -0
- package/dist/repos-WWZXNN3P.js +271 -0
- package/dist/review-integration-RQE4KMAV.js +14 -0
- package/dist/{rules-3OFGWHP4.js → rules-Y4VSOY5Y.js} +3 -3
- package/dist/run-VPNXEIBY.js +687 -0
- package/dist/server-COL4AXKU-P7S7NNF6.js +11 -0
- package/dist/server-U7PQ6FTS-MG4MJPTS.js +20 -0
- package/dist/{skills-GY2CTPWN.js → skills-QEYU2N27.js} +4 -2
- package/dist/start-IJKY5RVT.js +303 -0
- package/dist/{status-SE43TIFJ.js → status-BHQYYGAL.js} +2 -2
- package/dist/{templates-O2XDKB5R.js → templates-CBRUJ66V.js} +6 -5
- package/dist/tui-DP7736EX.js +61 -0
- package/dist/ulpi-5EN6JCAS-LFE3WSL4.js +10 -0
- package/dist/{uninstall-KWGSGZTI.js → uninstall-BX6FOV77.js} +3 -3
- package/dist/{update-QYZA4D23.js → update-AQKTHFVQ.js} +3 -3
- package/dist/{version-checker-MVB74DEX.js → version-checker-5L5PUOEX.js} +2 -2
- package/package.json +13 -4
- package/dist/chunk-26LLDX2T.js +0 -553
- package/dist/chunk-DDRLI6JU.js +0 -331
- package/dist/chunk-IFATANHR.js +0 -453
- package/dist/chunk-JWUUVXIV.js +0 -13694
- package/dist/chunk-LD52XG3X.js +0 -4273
- package/dist/chunk-MIAQVCFW.js +0 -39
- package/dist/chunk-YYZOFYS6.js +0 -415
- package/dist/dist-XD4YI27T.js +0 -26
- package/dist/mcp-installer-TOYDP77X.js +0 -124
- package/dist/projects-COUJP4ZC.js +0 -271
- package/dist/review-KMGP2S25.js +0 -152
- package/dist/server-USLHY6GH-F4JSXCWA.js +0 -18
- package/dist/server-X5P6WH2M-ULZF5WHZ.js +0 -11
- package/dist/ui-4SM2SUI6.js +0 -167
- package/dist/ui.html +0 -698
- /package/dist/skills/{ulpi-generate-guardian → ulpi-generate-guards}/SKILL.md +0 -0
- /package/dist/skills/{ulpi-generate-guardian → ulpi-generate-guards}/references/framework-rules.md +0 -0
- /package/dist/skills/{ulpi-generate-guardian → ulpi-generate-guards}/references/language-rules.md +0 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getKiroStatus,
|
|
3
|
+
installKiroHooks,
|
|
4
|
+
installKiroSkills,
|
|
5
|
+
uninstallKiro
|
|
6
|
+
} from "./chunk-WED4LM5N.js";
|
|
7
|
+
import "./chunk-IZPJHSPX.js";
|
|
8
|
+
import {
|
|
9
|
+
convertClaudeAgentsToKiro,
|
|
10
|
+
convertClaudeSkillsToKiro
|
|
11
|
+
} from "./chunk-SNQ7NAIS.js";
|
|
12
|
+
import "./chunk-4ZPOZULQ.js";
|
|
13
|
+
import "./chunk-5MI5GIXM.js";
|
|
14
|
+
import "./chunk-C7CLUQI6.js";
|
|
15
|
+
import "./chunk-YOKL7RB5.js";
|
|
16
|
+
import "./chunk-KIKPIH6N.js";
|
|
17
|
+
import "./chunk-4VNS5WPM.js";
|
|
18
|
+
|
|
19
|
+
// src/commands/kiro.ts
|
|
20
|
+
import chalk from "chalk";
|
|
21
|
+
function runKiro(args, projectDir) {
|
|
22
|
+
const subcommand = args[0];
|
|
23
|
+
switch (subcommand) {
|
|
24
|
+
case "install":
|
|
25
|
+
return handleInstall(args.slice(1), projectDir);
|
|
26
|
+
case "convert":
|
|
27
|
+
return handleConvert(args.slice(1), projectDir);
|
|
28
|
+
case "uninstall":
|
|
29
|
+
return handleUninstall(projectDir);
|
|
30
|
+
case "status":
|
|
31
|
+
return handleStatus(projectDir);
|
|
32
|
+
default:
|
|
33
|
+
printUsage();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function handleInstall(args, projectDir) {
|
|
37
|
+
const mode = args.includes("--patch-default") ? "default" : "agent";
|
|
38
|
+
const skipConvert = args.includes("--no-convert");
|
|
39
|
+
console.log(chalk.bold("\nInstalling ULPI for Kiro CLI\n"));
|
|
40
|
+
const { file, agent } = installKiroHooks(mode);
|
|
41
|
+
console.log(chalk.green(`\u2713 Agent config: ${agent}`));
|
|
42
|
+
console.log(chalk.dim(` ${file}`));
|
|
43
|
+
const skillCount = installKiroSkills(projectDir);
|
|
44
|
+
if (skillCount > 0) {
|
|
45
|
+
console.log(chalk.green(`\u2713 Installed ${skillCount} bundled skill(s) to .kiro/skills/`));
|
|
46
|
+
} else {
|
|
47
|
+
console.log(chalk.dim(" Bundled skills already installed"));
|
|
48
|
+
}
|
|
49
|
+
if (!skipConvert) {
|
|
50
|
+
const converted = convertClaudeSkillsToKiro(projectDir);
|
|
51
|
+
if (converted > 0) {
|
|
52
|
+
console.log(chalk.green(`\u2713 Converted ${converted} Claude Code skill(s) to .kiro/skills/`));
|
|
53
|
+
} else {
|
|
54
|
+
console.log(chalk.dim(" No new Claude Code skills to convert"));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (!skipConvert) {
|
|
58
|
+
const agentCount = convertClaudeAgentsToKiro(projectDir);
|
|
59
|
+
if (agentCount > 0) {
|
|
60
|
+
console.log(chalk.green(`\u2713 Converted ${agentCount} Claude Code agent(s) to .kiro/agents/`));
|
|
61
|
+
} else {
|
|
62
|
+
console.log(chalk.dim(" No new Claude Code agents to convert"));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
console.log();
|
|
66
|
+
if (mode === "agent") {
|
|
67
|
+
console.log(chalk.cyan("Start Kiro with the ULPI agent:"));
|
|
68
|
+
console.log(chalk.dim(" kiro-cli --agent ulpi-governance"));
|
|
69
|
+
} else {
|
|
70
|
+
console.log(chalk.cyan("ULPI hooks added to default Kiro agent."));
|
|
71
|
+
console.log(chalk.dim(" kiro-cli"));
|
|
72
|
+
}
|
|
73
|
+
console.log();
|
|
74
|
+
}
|
|
75
|
+
function handleConvert(args, projectDir) {
|
|
76
|
+
const skipAgents = args.includes("--no-agents");
|
|
77
|
+
const skipSkills = args.includes("--no-skills");
|
|
78
|
+
console.log(chalk.bold("\nConverting Claude Code assets to Kiro format\n"));
|
|
79
|
+
if (!skipSkills) {
|
|
80
|
+
const skillCount = convertClaudeSkillsToKiro(projectDir);
|
|
81
|
+
if (skillCount > 0) {
|
|
82
|
+
console.log(chalk.green(`\u2713 Converted ${skillCount} Claude Code skill(s) to .kiro/skills/`));
|
|
83
|
+
} else {
|
|
84
|
+
console.log(chalk.dim(" No new Claude Code skills to convert"));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (!skipAgents) {
|
|
88
|
+
const agentCount = convertClaudeAgentsToKiro(projectDir);
|
|
89
|
+
if (agentCount > 0) {
|
|
90
|
+
console.log(chalk.green(`\u2713 Converted ${agentCount} Claude Code agent(s) to .kiro/agents/`));
|
|
91
|
+
} else {
|
|
92
|
+
console.log(chalk.dim(" No new Claude Code agents to convert"));
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
console.log();
|
|
96
|
+
}
|
|
97
|
+
function handleUninstall(projectDir) {
|
|
98
|
+
console.log(chalk.bold("\nUninstalling ULPI from Kiro CLI\n"));
|
|
99
|
+
const { agentRemoved, skillsRemoved, agentsRemoved } = uninstallKiro(projectDir);
|
|
100
|
+
if (agentRemoved) {
|
|
101
|
+
console.log(chalk.green("\u2713 Removed ulpi-governance agent config"));
|
|
102
|
+
} else {
|
|
103
|
+
console.log(chalk.dim(" Agent config not found"));
|
|
104
|
+
}
|
|
105
|
+
if (skillsRemoved > 0) {
|
|
106
|
+
console.log(chalk.green(`\u2713 Removed ${skillsRemoved} skill(s) from .kiro/skills/`));
|
|
107
|
+
} else {
|
|
108
|
+
console.log(chalk.dim(" No ULPI skills found"));
|
|
109
|
+
}
|
|
110
|
+
if (agentsRemoved > 0) {
|
|
111
|
+
console.log(chalk.green(`\u2713 Removed ${agentsRemoved} converted agent(s) from .kiro/agents/`));
|
|
112
|
+
} else {
|
|
113
|
+
console.log(chalk.dim(" No converted agents found"));
|
|
114
|
+
}
|
|
115
|
+
console.log();
|
|
116
|
+
}
|
|
117
|
+
function handleStatus(projectDir) {
|
|
118
|
+
const status = getKiroStatus(projectDir);
|
|
119
|
+
console.log(chalk.bold("\nKiro CLI Integration Status\n"));
|
|
120
|
+
console.log(` Agent: ${status.agentInstalled ? chalk.green("installed") : chalk.dim("not installed")}`);
|
|
121
|
+
if (status.agentInstalled) {
|
|
122
|
+
console.log(chalk.dim(` ${status.agentPath}`));
|
|
123
|
+
}
|
|
124
|
+
const bundledLabel = status.skillCount > 0 ? chalk.green(`${status.skillCount} bundled`) : chalk.dim("0 bundled");
|
|
125
|
+
const convertedLabel = status.convertedSkillCount > 0 ? chalk.green(`${status.convertedSkillCount} converted`) : chalk.dim("0 converted");
|
|
126
|
+
console.log(` Skills: ${bundledLabel}, ${convertedLabel}`);
|
|
127
|
+
const agentsLabel = status.convertedAgentCount > 0 ? chalk.green(`${status.convertedAgentCount} converted`) : chalk.dim("0 converted");
|
|
128
|
+
console.log(` Agents: ${agentsLabel}`);
|
|
129
|
+
console.log(` MCP: ${status.mcpConfigured ? chalk.green("configured") : chalk.dim("not configured")}`);
|
|
130
|
+
console.log();
|
|
131
|
+
}
|
|
132
|
+
function printUsage() {
|
|
133
|
+
console.log(`
|
|
134
|
+
Usage: ulpi kiro <subcommand> [options]
|
|
135
|
+
|
|
136
|
+
Subcommands:
|
|
137
|
+
install Install ULPI hooks, skills, agent config, and convert Claude Code skills + agents
|
|
138
|
+
convert Convert Claude Code skills and agents to Kiro format (no hooks)
|
|
139
|
+
uninstall Remove ULPI agent config, skills, and converted agents
|
|
140
|
+
status Show Kiro integration status
|
|
141
|
+
|
|
142
|
+
Install options:
|
|
143
|
+
--patch-default Patch the default Kiro agent instead of creating ulpi-governance
|
|
144
|
+
--no-convert Skip converting Claude Code skills and agents
|
|
145
|
+
|
|
146
|
+
Convert options:
|
|
147
|
+
--no-agents Skip agent conversion
|
|
148
|
+
--no-skills Skip skill conversion
|
|
149
|
+
`.trim());
|
|
150
|
+
}
|
|
151
|
+
export {
|
|
152
|
+
runKiro
|
|
153
|
+
};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import "./chunk-
|
|
1
|
+
import "./chunk-XKF4DPUM.js";
|
|
2
2
|
import {
|
|
3
3
|
LAUNCHD_LABEL,
|
|
4
4
|
LOGS_DIR,
|
|
5
5
|
getApiPort,
|
|
6
6
|
getBinaryPath
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-C7CLUQI6.js";
|
|
8
8
|
import "./chunk-4VNS5WPM.js";
|
|
9
9
|
|
|
10
10
|
// src/launchd.ts
|
|
@@ -30,23 +30,15 @@ function needsLegacyMigration() {
|
|
|
30
30
|
function generatePlist(options = {}) {
|
|
31
31
|
const port = options.port ?? getApiPort();
|
|
32
32
|
const binary = getBinaryPath();
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const resolved = execFileSync("which", [p], { encoding: "utf-8", timeout: 3e3 }).trim();
|
|
40
|
-
if (resolved) parts[i] = resolved;
|
|
41
|
-
else parts[i] = p;
|
|
42
|
-
} catch {
|
|
43
|
-
parts[i] = p;
|
|
44
|
-
}
|
|
45
|
-
} else {
|
|
46
|
-
parts[i] = p;
|
|
33
|
+
let resolvedBinary = binary;
|
|
34
|
+
if (!binary.startsWith("/")) {
|
|
35
|
+
try {
|
|
36
|
+
const resolved = execFileSync("which", [binary], { encoding: "utf-8", timeout: 3e3 }).trim();
|
|
37
|
+
if (resolved) resolvedBinary = resolved;
|
|
38
|
+
} catch {
|
|
47
39
|
}
|
|
48
40
|
}
|
|
49
|
-
const programArgs =
|
|
41
|
+
const programArgs = ` <string>${escapeXml(resolvedBinary)}</string>`;
|
|
50
42
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
51
43
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
52
44
|
<plist version="1.0">
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import "./chunk-4VNS5WPM.js";
|
|
2
|
+
|
|
3
|
+
// src/commands/mcp.ts
|
|
4
|
+
import chalk from "chalk";
|
|
5
|
+
async function runMcp(args, projectDir) {
|
|
6
|
+
const sub = args[0];
|
|
7
|
+
switch (sub) {
|
|
8
|
+
case "gateway":
|
|
9
|
+
return runGateway(projectDir);
|
|
10
|
+
case "list":
|
|
11
|
+
return runList();
|
|
12
|
+
case "add":
|
|
13
|
+
return runAdd(args.slice(1));
|
|
14
|
+
case "remove":
|
|
15
|
+
return runRemove(args.slice(1));
|
|
16
|
+
case "enable":
|
|
17
|
+
return runEnable(args.slice(1), projectDir);
|
|
18
|
+
case "disable":
|
|
19
|
+
return runDisable(args.slice(1), projectDir);
|
|
20
|
+
case "status":
|
|
21
|
+
return runStatus(projectDir);
|
|
22
|
+
case "catalog":
|
|
23
|
+
return runCatalogList(args.slice(1));
|
|
24
|
+
case "cloud-connect":
|
|
25
|
+
return runCloudConnect(projectDir);
|
|
26
|
+
default:
|
|
27
|
+
printUsage();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function printUsage() {
|
|
31
|
+
console.log(`
|
|
32
|
+
Usage: ulpi mcp <subcommand>
|
|
33
|
+
|
|
34
|
+
Gateway:
|
|
35
|
+
gateway Start the MCP gateway (stdio, blocks until closed)
|
|
36
|
+
|
|
37
|
+
Library:
|
|
38
|
+
list List global MCP library entries
|
|
39
|
+
add <name> Add MCP to library (--from-catalog to use bundled definition)
|
|
40
|
+
remove <name> Remove MCP from library
|
|
41
|
+
|
|
42
|
+
Per-Repo:
|
|
43
|
+
enable <name> Enable MCP for current repo
|
|
44
|
+
disable <name> Disable MCP for current repo
|
|
45
|
+
status Show enabled MCPs for current repo
|
|
46
|
+
|
|
47
|
+
Catalog:
|
|
48
|
+
catalog [--search=<q>] List available catalog entries
|
|
49
|
+
|
|
50
|
+
Cloud:
|
|
51
|
+
cloud-connect Configure .mcp.json to connect to Cloud MCP Gateway
|
|
52
|
+
`.trim());
|
|
53
|
+
}
|
|
54
|
+
async function runGateway(projectDir) {
|
|
55
|
+
const { startGateway } = await import("./dist-IYE3OBRB.js");
|
|
56
|
+
await startGateway({ projectDir });
|
|
57
|
+
}
|
|
58
|
+
async function runList() {
|
|
59
|
+
const { listLibrary } = await import("./dist-EK45QNEM.js");
|
|
60
|
+
const entries = listLibrary();
|
|
61
|
+
if (entries.length === 0) {
|
|
62
|
+
console.log(chalk.dim("No MCPs in library. Run 'ulpi mcp add <name> --from-catalog' to add one."));
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
console.log(chalk.bold(`MCP Library (${entries.length} entries)
|
|
66
|
+
`));
|
|
67
|
+
for (const entry of entries) {
|
|
68
|
+
const name = chalk.cyan(entry.name);
|
|
69
|
+
const display = entry.display_name ? ` (${entry.display_name})` : "";
|
|
70
|
+
const cat = chalk.dim(`[${entry.category}]`);
|
|
71
|
+
const desc = entry.description ? chalk.dim(` \u2014 ${entry.description}`) : "";
|
|
72
|
+
console.log(` ${name}${display} ${cat}${desc}`);
|
|
73
|
+
console.log(` ${chalk.dim(`${entry.command} ${entry.args.join(" ")}`)}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async function runAdd(args) {
|
|
77
|
+
const name = args.find((a) => !a.startsWith("-"));
|
|
78
|
+
const fromCatalog = args.includes("--from-catalog");
|
|
79
|
+
if (!name) {
|
|
80
|
+
console.error(chalk.red("Usage: ulpi mcp add <name> [--from-catalog]"));
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (!/^[a-z0-9][a-z0-9_-]*$/.test(name) || name.length > 128) {
|
|
84
|
+
console.error(chalk.red("Name must be lowercase alphanumeric with hyphens/underscores, max 128 chars."));
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const { addToLibrary, getLibraryEntry } = await import("./dist-EK45QNEM.js");
|
|
88
|
+
if (getLibraryEntry(name)) {
|
|
89
|
+
console.log(chalk.yellow(`MCP "${name}" already exists in library. Use 'ulpi mcp remove ${name}' first.`));
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const projectDir = process.cwd();
|
|
93
|
+
if (fromCatalog) {
|
|
94
|
+
const { getCatalogEntry, enableMcp } = await import("./dist-EK45QNEM.js");
|
|
95
|
+
const entry = getCatalogEntry(name);
|
|
96
|
+
if (!entry) {
|
|
97
|
+
console.error(chalk.red(`"${name}" not found in catalog. Run 'ulpi mcp catalog' to see available entries.`));
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
addToLibrary(name, {
|
|
101
|
+
name: entry.name,
|
|
102
|
+
display_name: entry.display_name,
|
|
103
|
+
description: entry.description,
|
|
104
|
+
command: entry.command,
|
|
105
|
+
args: entry.args,
|
|
106
|
+
transport: entry.transport,
|
|
107
|
+
category: entry.category,
|
|
108
|
+
config_schema: entry.config_schema,
|
|
109
|
+
tags: entry.tags,
|
|
110
|
+
source: "catalog"
|
|
111
|
+
});
|
|
112
|
+
enableMcp(projectDir, name);
|
|
113
|
+
console.log(chalk.green(`Added "${name}" to library and enabled for this repo.`));
|
|
114
|
+
} else {
|
|
115
|
+
const commandIdx = args.indexOf("--command");
|
|
116
|
+
const command = commandIdx !== -1 ? args[commandIdx + 1] : void 0;
|
|
117
|
+
if (!command) {
|
|
118
|
+
console.error(chalk.red("For manual add, provide --command: ulpi mcp add <name> --command npx --args '-y,@scope/pkg'"));
|
|
119
|
+
console.error(chalk.dim("Or use --from-catalog to add from the bundled catalog."));
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const argsIdx = args.indexOf("--args");
|
|
123
|
+
const mcpArgs = argsIdx !== -1 ? args[argsIdx + 1]?.split(",") ?? [] : [];
|
|
124
|
+
const { enableMcp: enableManual } = await import("./dist-EK45QNEM.js");
|
|
125
|
+
addToLibrary(name, {
|
|
126
|
+
name,
|
|
127
|
+
command,
|
|
128
|
+
args: mcpArgs,
|
|
129
|
+
transport: "stdio",
|
|
130
|
+
category: "custom",
|
|
131
|
+
tags: [],
|
|
132
|
+
source: "manual"
|
|
133
|
+
});
|
|
134
|
+
enableManual(projectDir, name);
|
|
135
|
+
console.log(chalk.green(`Added "${name}" to library and enabled for this repo.`));
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
async function runRemove(args) {
|
|
139
|
+
const name = args[0];
|
|
140
|
+
if (!name) {
|
|
141
|
+
console.error(chalk.red("Usage: ulpi mcp remove <name>"));
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const { removeFromLibrary, disableMcp } = await import("./dist-EK45QNEM.js");
|
|
145
|
+
const removed = removeFromLibrary(name);
|
|
146
|
+
if (removed) {
|
|
147
|
+
disableMcp(process.cwd(), name);
|
|
148
|
+
console.log(chalk.green(`Removed "${name}" from library and disabled for this repo.`));
|
|
149
|
+
} else {
|
|
150
|
+
console.log(chalk.yellow(`"${name}" not found in library.`));
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
async function runEnable(args, projectDir) {
|
|
154
|
+
const name = args[0];
|
|
155
|
+
if (!name) {
|
|
156
|
+
console.error(chalk.red("Usage: ulpi mcp enable <name>"));
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
const { getLibraryEntry, enableMcp } = await import("./dist-EK45QNEM.js");
|
|
160
|
+
if (!getLibraryEntry(name)) {
|
|
161
|
+
console.error(chalk.red(`"${name}" not in library. Run 'ulpi mcp add ${name} --from-catalog' first.`));
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
const config = {};
|
|
165
|
+
for (let i = 1; i < args.length; i++) {
|
|
166
|
+
if (args[i]?.includes("=")) {
|
|
167
|
+
const [key, ...rest] = args[i].split("=");
|
|
168
|
+
if (key) config[key] = rest.join("=");
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
enableMcp(projectDir, name, Object.keys(config).length > 0 ? config : void 0);
|
|
172
|
+
console.log(chalk.green(`Enabled "${name}" for this repo.`));
|
|
173
|
+
if (Object.keys(config).length > 0) {
|
|
174
|
+
console.log(chalk.dim(` Config: ${Object.entries(config).map(([k, v]) => `${k}=${v}`).join(", ")}`));
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
async function runDisable(args, projectDir) {
|
|
178
|
+
const name = args[0];
|
|
179
|
+
if (!name) {
|
|
180
|
+
console.error(chalk.red("Usage: ulpi mcp disable <name>"));
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
const { disableMcp } = await import("./dist-EK45QNEM.js");
|
|
184
|
+
const disabled = disableMcp(projectDir, name);
|
|
185
|
+
if (disabled) {
|
|
186
|
+
console.log(chalk.green(`Disabled "${name}" for this repo.`));
|
|
187
|
+
} else {
|
|
188
|
+
console.log(chalk.yellow(`"${name}" not enabled for this repo.`));
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
async function runStatus(projectDir) {
|
|
192
|
+
const { listActivations, getLibraryEntry } = await import("./dist-EK45QNEM.js");
|
|
193
|
+
const activations = listActivations(projectDir);
|
|
194
|
+
if (activations.length === 0) {
|
|
195
|
+
console.log(chalk.dim("No MCPs configured for this repo. Run 'ulpi mcp enable <name>' to add one."));
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
console.log(chalk.bold(`MCPs for this repo (${activations.length})
|
|
199
|
+
`));
|
|
200
|
+
for (const { name, activation } of activations) {
|
|
201
|
+
const status = activation.enabled ? chalk.green("ON") : chalk.red("OFF");
|
|
202
|
+
const def = getLibraryEntry(name);
|
|
203
|
+
const display = def?.display_name ? ` (${def.display_name})` : "";
|
|
204
|
+
const missing = !def ? chalk.yellow(" [not in library]") : "";
|
|
205
|
+
console.log(` ${status} ${chalk.cyan(name)}${display}${missing}`);
|
|
206
|
+
const configEntries = Object.entries(activation.config);
|
|
207
|
+
if (configEntries.length > 0) {
|
|
208
|
+
for (const [key, value] of configEntries) {
|
|
209
|
+
const displayValue = typeof value === "string" && value.startsWith("env:") ? chalk.dim(value) : chalk.dim(String(value));
|
|
210
|
+
console.log(` ${chalk.dim(key)} = ${displayValue}`);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
async function runCatalogList(args) {
|
|
216
|
+
const searchFlag = args.find((a) => a.startsWith("--search="));
|
|
217
|
+
const query = searchFlag ? searchFlag.slice("--search=".length) : void 0;
|
|
218
|
+
const { loadCatalog, searchCatalog } = await import("./dist-EK45QNEM.js");
|
|
219
|
+
const entries = query ? searchCatalog(query) : loadCatalog();
|
|
220
|
+
if (entries.length === 0) {
|
|
221
|
+
console.log(chalk.dim(query ? `No catalog entries matching "${query}".` : "Catalog is empty."));
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
console.log(chalk.bold(`MCP Catalog (${entries.length} entries)${query ? ` \u2014 search: "${query}"` : ""}
|
|
225
|
+
`));
|
|
226
|
+
const byCategory = /* @__PURE__ */ new Map();
|
|
227
|
+
for (const entry of entries) {
|
|
228
|
+
const cat = entry.category ?? "custom";
|
|
229
|
+
if (!byCategory.has(cat)) byCategory.set(cat, []);
|
|
230
|
+
byCategory.get(cat).push(entry);
|
|
231
|
+
}
|
|
232
|
+
for (const [category, items] of byCategory) {
|
|
233
|
+
console.log(chalk.bold(` ${category.charAt(0).toUpperCase() + category.slice(1)}`));
|
|
234
|
+
for (const item of items) {
|
|
235
|
+
const name = chalk.cyan(item.name);
|
|
236
|
+
const desc = item.description ? chalk.dim(` \u2014 ${item.description}`) : "";
|
|
237
|
+
console.log(` ${name}${desc}`);
|
|
238
|
+
}
|
|
239
|
+
console.log("");
|
|
240
|
+
}
|
|
241
|
+
console.log(chalk.dim(`Add to library: ulpi mcp add <name> --from-catalog`));
|
|
242
|
+
}
|
|
243
|
+
async function runCloudConnect(projectDir) {
|
|
244
|
+
const { runCloud } = await import("./cloud-2F3NLVHN.js");
|
|
245
|
+
await runCloud(["connect"], projectDir);
|
|
246
|
+
}
|
|
247
|
+
export {
|
|
248
|
+
runMcp
|
|
249
|
+
};
|