@ulpi/cli 0.1.5 → 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.
- package/LICENSE +21 -0
- 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-6OURRFP7.js → chunk-IV6MWETF.js} +383 -168
- package/dist/chunk-IZPJHSPX.js +1478 -0
- package/dist/chunk-JLHNLM3C.js +228 -0
- package/dist/{chunk-P2RESJRN.js → chunk-KYYI23AQ.js} +2 -2
- 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-V2H5D6Y3.js +146 -0
- package/dist/{chunk-5SCG7UYM.js → chunk-VVEDXI7E.js} +1 -1
- package/dist/chunk-VXH5Y4FO.js +6761 -0
- package/dist/chunk-WED4LM5N.js +322 -0
- package/dist/{chunk-74WVVWJ4.js → chunk-YOKL7RB5.js} +184 -15
- package/dist/chunk-Z53CAR7G.js +298 -0
- package/dist/{ci-JQ56YIKC.js → ci-X3U2W4HC.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-SI4LLLDZ.js +345 -0
- package/dist/{export-import-4A5MWLIA.js → export-import-JFQH4KSJ.js} +1 -1
- package/dist/{history-RNUWO4JZ.js → history-5NE46ZAH.js} +7 -7
- package/dist/{hooks-installer-K2JXEBNN.js → hooks-installer-UN5JZLDQ.js} +2 -2
- package/dist/index.js +394 -618
- package/dist/{init-NQWFZPKO.js → init-5FK3VKRT.js} +76 -10
- 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-6AWT54HR.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-5WHEJU2A.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-KKSETHDV-XSSLEENT.js +20 -0
- package/dist/{skills-GY2CTPWN.js → skills-QEYU2N27.js} +4 -2
- package/dist/start-JYOEL7AJ.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-ICUV6DDV.js} +3 -3
- package/dist/{update-QYZA4D23.js → update-7ZMAYRBH.js} +3 -3
- package/dist/{version-checker-MVB74DEX.js → version-checker-4ZFMZA7Y.js} +2 -2
- package/package.json +39 -31
- 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/skills/ulpi-generate-guardian/SKILL.md +0 -750
- package/dist/skills/ulpi-generate-guardian/references/framework-rules.md +0 -849
- package/dist/skills/ulpi-generate-guardian/references/language-rules.md +0 -591
- package/dist/ui-4SM2SUI6.js +0 -167
- package/dist/ui.html +0 -698
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
import {
|
|
2
|
+
API_LOCK_FILE,
|
|
3
|
+
ULPI_GLOBAL_DIR,
|
|
4
|
+
loadUlpiSettings,
|
|
5
|
+
projectGuardsFile
|
|
6
|
+
} from "./chunk-C7CLUQI6.js";
|
|
7
|
+
import "./chunk-4VNS5WPM.js";
|
|
8
|
+
|
|
9
|
+
// src/commands/doctor.ts
|
|
10
|
+
import * as fs from "fs";
|
|
11
|
+
import * as path from "path";
|
|
12
|
+
import * as os from "os";
|
|
13
|
+
import { execFileSync } from "child_process";
|
|
14
|
+
import chalk from "chalk";
|
|
15
|
+
var PASS = chalk.green("\u2713");
|
|
16
|
+
var FAIL = chalk.red("\u2717");
|
|
17
|
+
var WARN = chalk.yellow("\u26A0");
|
|
18
|
+
var AGENTS = [
|
|
19
|
+
{
|
|
20
|
+
name: "Claude Code",
|
|
21
|
+
cliCommand: "claude",
|
|
22
|
+
tier: 1,
|
|
23
|
+
hookConfigPath: (dir) => path.join(dir, ".claude", "settings.local.json"),
|
|
24
|
+
mcpConfigPath: () => path.join(os.homedir(), ".claude", "settings.json")
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
name: "Gemini CLI",
|
|
28
|
+
cliCommand: "gemini",
|
|
29
|
+
tier: 1,
|
|
30
|
+
hookConfigPath: (dir) => path.join(dir, ".gemini", "settings.json"),
|
|
31
|
+
mcpConfigPath: () => {
|
|
32
|
+
const xdg = process.env.XDG_CONFIG_HOME ?? path.join(os.homedir(), ".config");
|
|
33
|
+
return path.join(xdg, "gemini", "settings.json");
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: "OpenCode",
|
|
38
|
+
cliCommand: "opencode",
|
|
39
|
+
tier: 1,
|
|
40
|
+
hookConfigPath: (dir) => path.join(dir, ".opencode", "config.json"),
|
|
41
|
+
mcpConfigPath: () => {
|
|
42
|
+
const xdg = process.env.XDG_CONFIG_HOME ?? path.join(os.homedir(), ".config");
|
|
43
|
+
return path.join(xdg, "opencode", "config.json");
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: "Codex",
|
|
48
|
+
cliCommand: "codex",
|
|
49
|
+
tier: 2,
|
|
50
|
+
hookConfigPath: () => null,
|
|
51
|
+
mcpConfigPath: () => path.join(os.homedir(), ".codex", "config.json")
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: "Kiro CLI",
|
|
55
|
+
cliCommand: "kiro",
|
|
56
|
+
tier: 2,
|
|
57
|
+
hookConfigPath: () => null,
|
|
58
|
+
mcpConfigPath: () => path.join(os.homedir(), ".kiro", "settings", "mcp.json")
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
name: "Factory Droid",
|
|
62
|
+
cliCommand: "droid",
|
|
63
|
+
tier: 3,
|
|
64
|
+
hookConfigPath: () => null,
|
|
65
|
+
mcpConfigPath: () => {
|
|
66
|
+
const xdg = process.env.XDG_CONFIG_HOME ?? path.join(os.homedir(), ".config");
|
|
67
|
+
return path.join(xdg, "droid", "mcp.json");
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
];
|
|
71
|
+
var passCount = 0;
|
|
72
|
+
var failCount = 0;
|
|
73
|
+
var warnCount = 0;
|
|
74
|
+
function pass(message) {
|
|
75
|
+
console.log(` ${PASS} ${message}`);
|
|
76
|
+
passCount++;
|
|
77
|
+
}
|
|
78
|
+
function fail(message) {
|
|
79
|
+
console.log(` ${FAIL} ${message}`);
|
|
80
|
+
failCount++;
|
|
81
|
+
}
|
|
82
|
+
function warn(message) {
|
|
83
|
+
console.log(` ${WARN} ${message}`);
|
|
84
|
+
warnCount++;
|
|
85
|
+
}
|
|
86
|
+
function section(title) {
|
|
87
|
+
console.log(`
|
|
88
|
+
${chalk.bold(title)}`);
|
|
89
|
+
}
|
|
90
|
+
function isCommandAvailable(command) {
|
|
91
|
+
try {
|
|
92
|
+
execFileSync("which", [command], { encoding: "utf-8", timeout: 5e3 });
|
|
93
|
+
try {
|
|
94
|
+
const version = execFileSync(command, ["--version"], {
|
|
95
|
+
encoding: "utf-8",
|
|
96
|
+
timeout: 1e4,
|
|
97
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
98
|
+
}).trim();
|
|
99
|
+
const match = version.match(/v?(\d+\.\d+\.\d+[^\s]*)/);
|
|
100
|
+
return { available: true, version: match?.[1] ?? version.split("\n")[0] };
|
|
101
|
+
} catch {
|
|
102
|
+
return { available: true };
|
|
103
|
+
}
|
|
104
|
+
} catch {
|
|
105
|
+
return { available: false };
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
function isApiServerRunning() {
|
|
109
|
+
try {
|
|
110
|
+
if (!fs.existsSync(API_LOCK_FILE)) return false;
|
|
111
|
+
const content = fs.readFileSync(API_LOCK_FILE, "utf-8");
|
|
112
|
+
const lock = JSON.parse(content);
|
|
113
|
+
if (lock.pid) {
|
|
114
|
+
try {
|
|
115
|
+
process.kill(lock.pid, 0);
|
|
116
|
+
return true;
|
|
117
|
+
} catch {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return false;
|
|
122
|
+
} catch {
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
function guardsYmlValid(projectDir) {
|
|
127
|
+
const guardsPath = projectGuardsFile(projectDir);
|
|
128
|
+
if (!fs.existsSync(guardsPath)) {
|
|
129
|
+
return { valid: false, error: "not found" };
|
|
130
|
+
}
|
|
131
|
+
try {
|
|
132
|
+
const content = fs.readFileSync(guardsPath, "utf-8");
|
|
133
|
+
if (!content.trim()) {
|
|
134
|
+
return { valid: false, error: "empty file" };
|
|
135
|
+
}
|
|
136
|
+
if (content.includes("project:") || content.includes("preconditions:") || content.includes("permissions:") || content.includes("postconditions:") || content.includes("pipelines:")) {
|
|
137
|
+
return { valid: true };
|
|
138
|
+
}
|
|
139
|
+
return { valid: false, error: "missing expected sections" };
|
|
140
|
+
} catch (err) {
|
|
141
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
142
|
+
return { valid: false, error: msg };
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
function checkMcpConfigured(configPath, serverName) {
|
|
146
|
+
try {
|
|
147
|
+
if (!fs.existsSync(configPath)) return false;
|
|
148
|
+
const config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
149
|
+
return !!config.mcpServers?.[serverName];
|
|
150
|
+
} catch {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
function checkHooksInstalled(configPath) {
|
|
155
|
+
if (!configPath) return false;
|
|
156
|
+
try {
|
|
157
|
+
if (!fs.existsSync(configPath)) return false;
|
|
158
|
+
const config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
159
|
+
return !!config.hooks && Object.keys(config.hooks).length > 0;
|
|
160
|
+
} catch {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
function checkCore(projectDir) {
|
|
165
|
+
section("Core");
|
|
166
|
+
try {
|
|
167
|
+
const version = "0.1.6";
|
|
168
|
+
pass(`ULPI CLI version: ${version}`);
|
|
169
|
+
} catch {
|
|
170
|
+
pass("ULPI CLI: installed");
|
|
171
|
+
}
|
|
172
|
+
const nodeVersion = process.version;
|
|
173
|
+
const major = parseInt(nodeVersion.slice(1), 10);
|
|
174
|
+
if (major >= 20) {
|
|
175
|
+
pass(`Node.js version: ${nodeVersion}`);
|
|
176
|
+
} else {
|
|
177
|
+
fail(`Node.js version: ${nodeVersion} (requires >= 20)`);
|
|
178
|
+
}
|
|
179
|
+
if (fs.existsSync(path.join(projectDir, ".ulpi"))) {
|
|
180
|
+
pass(`Project directory: ${projectDir}`);
|
|
181
|
+
} else {
|
|
182
|
+
warn(`Project directory: ${projectDir} (no .ulpi/ folder)`);
|
|
183
|
+
}
|
|
184
|
+
const guards = guardsYmlValid(projectDir);
|
|
185
|
+
if (guards.valid) {
|
|
186
|
+
pass(`Guards config: ${path.relative(projectDir, projectGuardsFile(projectDir))} (valid)`);
|
|
187
|
+
} else if (guards.error === "not found") {
|
|
188
|
+
fail("Guards config: not found (run: ulpi init)");
|
|
189
|
+
} else {
|
|
190
|
+
fail(`Guards config: invalid (${guards.error})`);
|
|
191
|
+
}
|
|
192
|
+
if (isApiServerRunning()) {
|
|
193
|
+
pass("API server: running");
|
|
194
|
+
} else {
|
|
195
|
+
fail("API server: not running (start with: ulpi ui)");
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
function checkAgentPlugins() {
|
|
199
|
+
section("Agent Plugins");
|
|
200
|
+
for (const agent of AGENTS) {
|
|
201
|
+
const detection = isCommandAvailable(agent.cliCommand);
|
|
202
|
+
if (detection.available) {
|
|
203
|
+
const versionStr = detection.version ? ` (${detection.version})` : "";
|
|
204
|
+
pass(`${agent.name}: installed${versionStr}`);
|
|
205
|
+
} else {
|
|
206
|
+
fail(`${agent.name}: not installed`);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
function checkMcpServers() {
|
|
211
|
+
section("MCP Servers");
|
|
212
|
+
const mcpServers = ["ulpi-codemap", "ulpi-memory"];
|
|
213
|
+
let checked = false;
|
|
214
|
+
for (const agent of AGENTS) {
|
|
215
|
+
const detection = isCommandAvailable(agent.cliCommand);
|
|
216
|
+
if (!detection.available) continue;
|
|
217
|
+
const configPath = agent.mcpConfigPath();
|
|
218
|
+
for (const serverName of mcpServers) {
|
|
219
|
+
const configured = checkMcpConfigured(configPath, serverName);
|
|
220
|
+
const displayName = serverName.replace("ulpi-", "");
|
|
221
|
+
if (configured) {
|
|
222
|
+
pass(`${displayName}-mcp: configured in ${agent.name}`);
|
|
223
|
+
} else {
|
|
224
|
+
fail(`${displayName}-mcp: not configured in ${agent.name}`);
|
|
225
|
+
}
|
|
226
|
+
checked = true;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
if (!checked) {
|
|
230
|
+
warn("No agent CLIs detected to check MCP configuration");
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
function checkIntelligenceLayer(projectDir) {
|
|
234
|
+
section("Intelligence Layer");
|
|
235
|
+
const projectSlug = path.basename(projectDir);
|
|
236
|
+
const codemapDir = path.join(ULPI_GLOBAL_DIR, "codemap", projectSlug);
|
|
237
|
+
if (fs.existsSync(codemapDir)) {
|
|
238
|
+
const lanceDir = path.join(codemapDir, "lance");
|
|
239
|
+
const hasVectorIndex = fs.existsSync(lanceDir);
|
|
240
|
+
const statusFile = path.join(codemapDir, "status.json");
|
|
241
|
+
if (fs.existsSync(statusFile)) {
|
|
242
|
+
try {
|
|
243
|
+
const status = JSON.parse(fs.readFileSync(statusFile, "utf-8"));
|
|
244
|
+
const details = [];
|
|
245
|
+
if (status.fileCount) details.push(`${status.fileCount} files`);
|
|
246
|
+
if (status.chunkCount) details.push(`${status.chunkCount} chunks`);
|
|
247
|
+
pass(`CodeMap index: ready${details.length ? ` (${details.join(", ")})` : ""}`);
|
|
248
|
+
} catch {
|
|
249
|
+
if (hasVectorIndex) {
|
|
250
|
+
pass("CodeMap index: ready");
|
|
251
|
+
} else {
|
|
252
|
+
fail("CodeMap index: not initialized (run: ulpi codemap init)");
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
} else if (hasVectorIndex) {
|
|
256
|
+
pass("CodeMap index: ready");
|
|
257
|
+
} else {
|
|
258
|
+
fail("CodeMap index: not initialized (run: ulpi codemap init)");
|
|
259
|
+
}
|
|
260
|
+
} else {
|
|
261
|
+
fail("CodeMap index: not initialized (run: ulpi codemap init)");
|
|
262
|
+
}
|
|
263
|
+
const memoryDir = path.join(ULPI_GLOBAL_DIR, "memory", projectSlug);
|
|
264
|
+
if (fs.existsSync(memoryDir)) {
|
|
265
|
+
const entriesDir = path.join(memoryDir, "entries");
|
|
266
|
+
let count = 0;
|
|
267
|
+
if (fs.existsSync(entriesDir)) {
|
|
268
|
+
try {
|
|
269
|
+
count = fs.readdirSync(entriesDir).filter((f) => f.endsWith(".json")).length;
|
|
270
|
+
} catch {
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
pass(`Memory store: ready (${count} memories)`);
|
|
274
|
+
} else {
|
|
275
|
+
fail("Memory store: not initialized (run: ulpi memory init)");
|
|
276
|
+
}
|
|
277
|
+
const depgraphPath = path.join(codemapDir, "depgraph.json");
|
|
278
|
+
if (fs.existsSync(depgraphPath)) {
|
|
279
|
+
pass("DepGraph: ready");
|
|
280
|
+
} else {
|
|
281
|
+
fail("DepGraph: not built (run: ulpi codemap init)");
|
|
282
|
+
}
|
|
283
|
+
try {
|
|
284
|
+
const settings = loadUlpiSettings();
|
|
285
|
+
const settingsRecord = settings;
|
|
286
|
+
const provider = settingsRecord.embedProvider;
|
|
287
|
+
const apiKeys = settingsRecord.apiKeys;
|
|
288
|
+
const hasKey = !!apiKeys?.embed || !!apiKeys?.openai;
|
|
289
|
+
if (provider === "ollama" || provider === "ulpi-cloud" || hasKey) {
|
|
290
|
+
pass(`Embeddings: ${provider ?? "configured"}`);
|
|
291
|
+
} else if (provider) {
|
|
292
|
+
pass(`Embeddings: ${provider}`);
|
|
293
|
+
} else {
|
|
294
|
+
warn("Embeddings: provider not configured (run: ulpi config set embedProvider)");
|
|
295
|
+
}
|
|
296
|
+
} catch {
|
|
297
|
+
warn("Embeddings: unable to check configuration");
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
function checkHookInstallation(projectDir) {
|
|
301
|
+
section("Hook Installation");
|
|
302
|
+
const hookAgents = AGENTS.filter((a) => a.tier === 1);
|
|
303
|
+
let checked = false;
|
|
304
|
+
for (const agent of hookAgents) {
|
|
305
|
+
const detection = isCommandAvailable(agent.cliCommand);
|
|
306
|
+
if (!detection.available) continue;
|
|
307
|
+
const configPath = agent.hookConfigPath(projectDir);
|
|
308
|
+
checked = true;
|
|
309
|
+
if (checkHooksInstalled(configPath)) {
|
|
310
|
+
const relPath = configPath ? path.relative(projectDir, configPath) : "unknown";
|
|
311
|
+
pass(`${agent.name} hooks: installed (${relPath})`);
|
|
312
|
+
} else {
|
|
313
|
+
fail(`${agent.name} hooks: not installed (run: ulpi init)`);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
if (!checked) {
|
|
317
|
+
warn("No Tier 1 agent CLIs detected to check hook installation");
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
function runDoctorCommand(args, projectDir) {
|
|
321
|
+
passCount = 0;
|
|
322
|
+
failCount = 0;
|
|
323
|
+
warnCount = 0;
|
|
324
|
+
console.log(`
|
|
325
|
+
${chalk.bold("ULPI System Health Check")}`);
|
|
326
|
+
console.log(` ${"========================"}`);
|
|
327
|
+
checkCore(projectDir);
|
|
328
|
+
checkAgentPlugins();
|
|
329
|
+
checkMcpServers();
|
|
330
|
+
checkIntelligenceLayer(projectDir);
|
|
331
|
+
checkHookInstallation(projectDir);
|
|
332
|
+
console.log("");
|
|
333
|
+
const parts = [];
|
|
334
|
+
if (passCount > 0) parts.push(chalk.green(`${passCount} passed`));
|
|
335
|
+
if (failCount > 0) parts.push(chalk.red(`${failCount} issues found`));
|
|
336
|
+
if (warnCount > 0) parts.push(chalk.yellow(`${warnCount} warnings`));
|
|
337
|
+
console.log(` Summary: ${parts.join(", ")}`);
|
|
338
|
+
console.log("");
|
|
339
|
+
if (failCount > 0) {
|
|
340
|
+
process.exit(1);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
export {
|
|
344
|
+
runDoctorCommand
|
|
345
|
+
};
|
|
@@ -19,13 +19,13 @@ import {
|
|
|
19
19
|
readTimeline,
|
|
20
20
|
updateEntryEnrichment,
|
|
21
21
|
writeHistoryEntry
|
|
22
|
-
} from "./chunk-
|
|
23
|
-
import "./chunk-
|
|
22
|
+
} from "./chunk-3WB5CXH4.js";
|
|
23
|
+
import "./chunk-SEU7WWNQ.js";
|
|
24
24
|
import {
|
|
25
25
|
DEFAULT_AI_MODEL,
|
|
26
26
|
REVIEWS_DIR,
|
|
27
27
|
getHistoryBranch
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-C7CLUQI6.js";
|
|
29
29
|
import "./chunk-4VNS5WPM.js";
|
|
30
30
|
|
|
31
31
|
// src/commands/history.ts
|
|
@@ -416,7 +416,7 @@ async function initSubcommand(projectDir) {
|
|
|
416
416
|
}
|
|
417
417
|
const projectName = path2.basename(projectDir);
|
|
418
418
|
try {
|
|
419
|
-
initHistoryBranch(projectDir, projectName, "0.1.
|
|
419
|
+
initHistoryBranch(projectDir, projectName, "0.1.6");
|
|
420
420
|
} catch (err) {
|
|
421
421
|
const message = err instanceof Error ? err.message : String(err);
|
|
422
422
|
console.log(chalk.red(`Error: ${message}`));
|
|
@@ -424,7 +424,7 @@ async function initSubcommand(projectDir) {
|
|
|
424
424
|
}
|
|
425
425
|
if (collectReviewPlans) {
|
|
426
426
|
try {
|
|
427
|
-
const { withWorktree, writeAndStage, commitInWorktree } = await import("./dist-
|
|
427
|
+
const { withWorktree, writeAndStage, commitInWorktree } = await import("./dist-YCNWHSLN.js");
|
|
428
428
|
const meta = readBranchMeta(projectDir);
|
|
429
429
|
if (meta) {
|
|
430
430
|
meta.config.collectReviewPlans = true;
|
|
@@ -447,8 +447,8 @@ async function initSubcommand(projectDir) {
|
|
|
447
447
|
);
|
|
448
448
|
if (installHooksAnswer.trim().toLowerCase() !== "n") {
|
|
449
449
|
try {
|
|
450
|
-
const { installGitHooks } = await import("./dist-
|
|
451
|
-
const { getBinaryPath } = await import("./dist-
|
|
450
|
+
const { installGitHooks } = await import("./dist-YCNWHSLN.js");
|
|
451
|
+
const { getBinaryPath } = await import("./dist-NUXMDXZ3.js");
|
|
452
452
|
const binaryPath = getBinaryPath();
|
|
453
453
|
const result = installGitHooks(projectDir, binaryPath);
|
|
454
454
|
if (result.installed.length > 0) {
|
|
@@ -4,10 +4,10 @@ import {
|
|
|
4
4
|
installHooks,
|
|
5
5
|
installLocalSkill,
|
|
6
6
|
uninstallHooks
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-VVEDXI7E.js";
|
|
8
8
|
import {
|
|
9
9
|
getBinaryPath
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-C7CLUQI6.js";
|
|
11
11
|
import "./chunk-4VNS5WPM.js";
|
|
12
12
|
export {
|
|
13
13
|
findSkillSource,
|