@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
|
@@ -1,271 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
getDefaultProject,
|
|
3
|
-
getProject,
|
|
4
|
-
listProjects,
|
|
5
|
-
loadProjectRegistry,
|
|
6
|
-
registerProject,
|
|
7
|
-
scanForProjects,
|
|
8
|
-
setDefaultProject,
|
|
9
|
-
unregisterProject
|
|
10
|
-
} from "./chunk-EIWYSP3A.js";
|
|
11
|
-
import {
|
|
12
|
-
JsonSessionStore
|
|
13
|
-
} from "./chunk-26LLDX2T.js";
|
|
14
|
-
import "./chunk-DDRLI6JU.js";
|
|
15
|
-
import "./chunk-4VNS5WPM.js";
|
|
16
|
-
|
|
17
|
-
// src/commands/projects.ts
|
|
18
|
-
import * as fs from "fs";
|
|
19
|
-
import * as path from "path";
|
|
20
|
-
import chalk from "chalk";
|
|
21
|
-
function runProjects(args) {
|
|
22
|
-
const subcommand = args[0];
|
|
23
|
-
switch (subcommand) {
|
|
24
|
-
case "list":
|
|
25
|
-
case "ls":
|
|
26
|
-
listProjectsCmd();
|
|
27
|
-
break;
|
|
28
|
-
case "add":
|
|
29
|
-
addProjectCmd(args[1]);
|
|
30
|
-
break;
|
|
31
|
-
case "remove":
|
|
32
|
-
case "rm":
|
|
33
|
-
removeProjectCmd(args[1]);
|
|
34
|
-
break;
|
|
35
|
-
case "default":
|
|
36
|
-
defaultProjectCmd(args[1]);
|
|
37
|
-
break;
|
|
38
|
-
case "scan":
|
|
39
|
-
scanProjectsCmd(args[1]);
|
|
40
|
-
break;
|
|
41
|
-
case "status":
|
|
42
|
-
statusCmd();
|
|
43
|
-
break;
|
|
44
|
-
default:
|
|
45
|
-
printUsage();
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
function printUsage() {
|
|
49
|
-
console.log(`
|
|
50
|
-
${chalk.bold("ULPI \u2014 Project Management")}
|
|
51
|
-
|
|
52
|
-
Usage: ulpi projects <command>
|
|
53
|
-
|
|
54
|
-
Commands:
|
|
55
|
-
list, ls List all registered projects
|
|
56
|
-
add <path> Register a project
|
|
57
|
-
remove, rm <id|path> Unregister a project
|
|
58
|
-
default [id|path] Get/set default project
|
|
59
|
-
scan [root-dir] Discover projects with .ulpi/
|
|
60
|
-
status Global health overview
|
|
61
|
-
|
|
62
|
-
Examples:
|
|
63
|
-
ulpi projects list
|
|
64
|
-
ulpi projects add /path/to/my-project
|
|
65
|
-
ulpi projects default my-webapp-id
|
|
66
|
-
ulpi projects scan ~/projects
|
|
67
|
-
`.trim());
|
|
68
|
-
}
|
|
69
|
-
function listProjectsCmd() {
|
|
70
|
-
const projects = listProjects();
|
|
71
|
-
const defaultProject = getDefaultProject();
|
|
72
|
-
if (projects.length === 0) {
|
|
73
|
-
console.log(chalk.yellow("\nNo projects registered."));
|
|
74
|
-
console.log("Run 'ulpi projects add <path>' to register a project.");
|
|
75
|
-
console.log("Or run 'ulpi init' in a project directory.\n");
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
console.log(chalk.bold(`
|
|
79
|
-
Projects (${projects.length} registered)
|
|
80
|
-
`));
|
|
81
|
-
for (const project of projects) {
|
|
82
|
-
const isDefault = defaultProject?.id === project.id;
|
|
83
|
-
const prefix = isDefault ? chalk.yellow("\u2605") : " ";
|
|
84
|
-
const name = chalk.bold(project.name);
|
|
85
|
-
const defaultLabel = isDefault ? chalk.dim(" (default)") : "";
|
|
86
|
-
console.log(` ${prefix} ${name}${defaultLabel}`);
|
|
87
|
-
console.log(chalk.dim(` ${project.path}`));
|
|
88
|
-
if (project.stack) {
|
|
89
|
-
const stackParts = [];
|
|
90
|
-
if (project.stack.runtime) stackParts.push(project.stack.runtime);
|
|
91
|
-
if (project.stack.framework) stackParts.push(project.stack.framework);
|
|
92
|
-
if (project.stack.packageManager) stackParts.push(project.stack.packageManager);
|
|
93
|
-
if (stackParts.length > 0) {
|
|
94
|
-
console.log(chalk.dim(` Stack: ${stackParts.join(" + ")}`));
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
const statusIcon = getStatusIcon(project);
|
|
98
|
-
const statusLabel = getStatusLabel(project);
|
|
99
|
-
console.log(` Status: ${statusIcon} ${statusLabel}`);
|
|
100
|
-
const lastAccessed = formatRelativeTime(project.lastAccessed);
|
|
101
|
-
console.log(chalk.dim(` Last accessed: ${lastAccessed}`));
|
|
102
|
-
console.log();
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
function addProjectCmd(projectPath) {
|
|
106
|
-
if (!projectPath) {
|
|
107
|
-
console.log(chalk.red("Error: Project path required."));
|
|
108
|
-
console.log("Usage: ulpi projects add <path>");
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
const absPath = path.resolve(projectPath);
|
|
112
|
-
if (!fs.existsSync(absPath)) {
|
|
113
|
-
console.log(chalk.red(`Error: Path does not exist: ${absPath}`));
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
if (!fs.statSync(absPath).isDirectory()) {
|
|
117
|
-
console.log(chalk.red(`Error: Path is not a directory: ${absPath}`));
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
120
|
-
const entry = registerProject(absPath);
|
|
121
|
-
console.log(chalk.green(`\u2713 Registered: ${entry.name}`));
|
|
122
|
-
console.log(chalk.dim(` ID: ${entry.id}`));
|
|
123
|
-
console.log(chalk.dim(` Path: ${entry.path}`));
|
|
124
|
-
console.log(chalk.dim(` Status: ${getStatusLabel(entry)}`));
|
|
125
|
-
}
|
|
126
|
-
function removeProjectCmd(idOrPath) {
|
|
127
|
-
if (!idOrPath) {
|
|
128
|
-
console.log(chalk.red("Error: Project ID or path required."));
|
|
129
|
-
console.log("Usage: ulpi projects remove <id|path>");
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
const project = getProject(idOrPath);
|
|
133
|
-
if (!project) {
|
|
134
|
-
console.log(chalk.red(`Error: Project not found: ${idOrPath}`));
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
const removed = unregisterProject(idOrPath);
|
|
138
|
-
if (removed) {
|
|
139
|
-
console.log(chalk.green(`\u2713 Unregistered: ${project.name}`));
|
|
140
|
-
} else {
|
|
141
|
-
console.log(chalk.red(`Error: Failed to unregister project.`));
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
function defaultProjectCmd(idOrPath) {
|
|
145
|
-
if (!idOrPath) {
|
|
146
|
-
const defaultProject = getDefaultProject();
|
|
147
|
-
if (defaultProject) {
|
|
148
|
-
console.log(`Default project: ${chalk.bold(defaultProject.name)}`);
|
|
149
|
-
console.log(chalk.dim(` ID: ${defaultProject.id}`));
|
|
150
|
-
console.log(chalk.dim(` Path: ${defaultProject.path}`));
|
|
151
|
-
} else {
|
|
152
|
-
console.log(chalk.yellow("No default project set."));
|
|
153
|
-
console.log("Use 'ulpi projects default <id|path>' to set one.");
|
|
154
|
-
}
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
157
|
-
if (idOrPath === "none" || idOrPath === "clear") {
|
|
158
|
-
setDefaultProject(void 0);
|
|
159
|
-
console.log(chalk.green("\u2713 Default project cleared."));
|
|
160
|
-
return;
|
|
161
|
-
}
|
|
162
|
-
const project = getProject(idOrPath);
|
|
163
|
-
if (!project) {
|
|
164
|
-
console.log(chalk.red(`Error: Project not found: ${idOrPath}`));
|
|
165
|
-
return;
|
|
166
|
-
}
|
|
167
|
-
const success = setDefaultProject(project.id);
|
|
168
|
-
if (success) {
|
|
169
|
-
console.log(chalk.green(`\u2713 Default project set to: ${project.name}`));
|
|
170
|
-
} else {
|
|
171
|
-
console.log(chalk.red("Error: Failed to set default project."));
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
function scanProjectsCmd(rootDir) {
|
|
175
|
-
const scanRoot = rootDir ? path.resolve(rootDir) : process.cwd();
|
|
176
|
-
if (!fs.existsSync(scanRoot)) {
|
|
177
|
-
console.log(chalk.red(`Error: Path does not exist: ${scanRoot}`));
|
|
178
|
-
return;
|
|
179
|
-
}
|
|
180
|
-
console.log(chalk.cyan(`Scanning for projects in: ${scanRoot}
|
|
181
|
-
`));
|
|
182
|
-
const found = scanForProjects(scanRoot);
|
|
183
|
-
if (found.length === 0) {
|
|
184
|
-
console.log(chalk.yellow("No projects with .ulpi/ found."));
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
|
-
console.log(`Found ${found.length} project(s):
|
|
188
|
-
`);
|
|
189
|
-
for (const projectPath of found) {
|
|
190
|
-
const existing = getProject(projectPath);
|
|
191
|
-
const status = existing ? chalk.dim("(already registered)") : "";
|
|
192
|
-
console.log(` ${chalk.green("\u2713")} ${projectPath} ${status}`);
|
|
193
|
-
if (!existing) {
|
|
194
|
-
registerProject(projectPath);
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
console.log(chalk.green(`
|
|
198
|
-
\u2713 All projects registered.`));
|
|
199
|
-
}
|
|
200
|
-
function statusCmd() {
|
|
201
|
-
const projects = listProjects();
|
|
202
|
-
const registry = loadProjectRegistry();
|
|
203
|
-
const store = new JsonSessionStore();
|
|
204
|
-
console.log(chalk.bold("\nULPI \u2014 Global Status\n"));
|
|
205
|
-
console.log(chalk.cyan("Summary"));
|
|
206
|
-
console.log(` Total projects: ${projects.length}`);
|
|
207
|
-
const configured = projects.filter((p) => p.configStatus === "configured").length;
|
|
208
|
-
const withHooks = projects.filter((p) => p.hooksInstalled).length;
|
|
209
|
-
console.log(` Configured: ${configured}`);
|
|
210
|
-
console.log(` Hooks installed: ${withHooks}`);
|
|
211
|
-
if (registry.defaultProject) {
|
|
212
|
-
const defaultProject = getProject(registry.defaultProject);
|
|
213
|
-
if (defaultProject) {
|
|
214
|
-
console.log(` Default: ${defaultProject.name}`);
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
const allSessions = store.list();
|
|
218
|
-
console.log(` Total sessions: ${allSessions.length}`);
|
|
219
|
-
console.log();
|
|
220
|
-
if (projects.length > 0) {
|
|
221
|
-
console.log(chalk.cyan("Projects"));
|
|
222
|
-
for (const project of projects) {
|
|
223
|
-
const statusIcon = getStatusIcon(project);
|
|
224
|
-
const isDefault = registry.defaultProject === project.id;
|
|
225
|
-
const defaultLabel = isDefault ? chalk.yellow(" \u2605") : "";
|
|
226
|
-
console.log(` ${statusIcon} ${project.name}${defaultLabel}`);
|
|
227
|
-
const projectSessions = store.listByProject(project.path);
|
|
228
|
-
if (projectSessions.length > 0) {
|
|
229
|
-
console.log(chalk.dim(` Sessions: ${projectSessions.length}`));
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
console.log();
|
|
234
|
-
}
|
|
235
|
-
function getStatusIcon(project) {
|
|
236
|
-
if (project.configStatus === "configured" && project.hooksInstalled) {
|
|
237
|
-
return chalk.green("\u2713");
|
|
238
|
-
}
|
|
239
|
-
if (project.configStatus === "configured" || project.hooksInstalled) {
|
|
240
|
-
return chalk.yellow("\u26A0");
|
|
241
|
-
}
|
|
242
|
-
return chalk.red("\u2717");
|
|
243
|
-
}
|
|
244
|
-
function getStatusLabel(project) {
|
|
245
|
-
if (project.configStatus === "configured" && project.hooksInstalled) {
|
|
246
|
-
return chalk.green("Configured");
|
|
247
|
-
}
|
|
248
|
-
if (project.configStatus === "configured" && !project.hooksInstalled) {
|
|
249
|
-
return chalk.yellow("Rules configured, hooks not installed");
|
|
250
|
-
}
|
|
251
|
-
if (project.configStatus !== "configured" && project.hooksInstalled) {
|
|
252
|
-
return chalk.yellow("Hooks installed, no rules");
|
|
253
|
-
}
|
|
254
|
-
return chalk.red("Not configured");
|
|
255
|
-
}
|
|
256
|
-
function formatRelativeTime(isoString) {
|
|
257
|
-
const date = new Date(isoString);
|
|
258
|
-
const now = /* @__PURE__ */ new Date();
|
|
259
|
-
const diffMs = now.getTime() - date.getTime();
|
|
260
|
-
const diffMins = Math.floor(diffMs / 6e4);
|
|
261
|
-
const diffHours = Math.floor(diffMins / 60);
|
|
262
|
-
const diffDays = Math.floor(diffHours / 24);
|
|
263
|
-
if (diffMins < 1) return "just now";
|
|
264
|
-
if (diffMins < 60) return `${diffMins} minute${diffMins === 1 ? "" : "s"} ago`;
|
|
265
|
-
if (diffHours < 24) return `${diffHours} hour${diffHours === 1 ? "" : "s"} ago`;
|
|
266
|
-
if (diffDays < 7) return `${diffDays} day${diffDays === 1 ? "" : "s"} ago`;
|
|
267
|
-
return date.toLocaleDateString();
|
|
268
|
-
}
|
|
269
|
-
export {
|
|
270
|
-
runProjects
|
|
271
|
-
};
|
package/dist/review-KMGP2S25.js
DELETED
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
listPlansWithMeta,
|
|
3
|
-
loadPlan
|
|
4
|
-
} from "./chunk-RJIRWQJD.js";
|
|
5
|
-
import {
|
|
6
|
-
loadRulesSync
|
|
7
|
-
} from "./chunk-SIAQVRKG.js";
|
|
8
|
-
import "./chunk-KIKPIH6N.js";
|
|
9
|
-
import {
|
|
10
|
-
REVIEWS_DIR,
|
|
11
|
-
loadUlpiSettings,
|
|
12
|
-
projectGuardsFile
|
|
13
|
-
} from "./chunk-DDRLI6JU.js";
|
|
14
|
-
import "./chunk-4VNS5WPM.js";
|
|
15
|
-
|
|
16
|
-
// src/commands/review.ts
|
|
17
|
-
import chalk from "chalk";
|
|
18
|
-
import * as fs from "fs";
|
|
19
|
-
import * as path from "path";
|
|
20
|
-
import { homedir } from "os";
|
|
21
|
-
async function runReview(args, projectDir) {
|
|
22
|
-
const subcommand = args[0];
|
|
23
|
-
switch (subcommand) {
|
|
24
|
-
case "list":
|
|
25
|
-
return listReviews(args.slice(1));
|
|
26
|
-
case "show":
|
|
27
|
-
return showReview(args.slice(1));
|
|
28
|
-
case "config":
|
|
29
|
-
return showConfig(projectDir);
|
|
30
|
-
case "migrate":
|
|
31
|
-
return migrateData();
|
|
32
|
-
default:
|
|
33
|
-
printUsage();
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
async function listReviews(args) {
|
|
37
|
-
const limitIdx = args.indexOf("--limit");
|
|
38
|
-
const limit = limitIdx !== -1 && args[limitIdx + 1] ? parseInt(args[limitIdx + 1], 10) : 20;
|
|
39
|
-
const plans = await listPlansWithMeta();
|
|
40
|
-
if (plans.length === 0) {
|
|
41
|
-
console.log(chalk.dim("No reviewed plans found."));
|
|
42
|
-
console.log(chalk.dim("Plans are stored in ~/.ulpi/reviews/"));
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
console.log(chalk.bold(`Reviewed Plans (${plans.length} total)
|
|
46
|
-
`));
|
|
47
|
-
const displayed = plans.slice(0, limit);
|
|
48
|
-
for (const plan of displayed) {
|
|
49
|
-
const statusIcon = plan.status === "approved" ? chalk.green("\u2713") : plan.status === "denied" ? chalk.red("\u2717") : chalk.yellow("\u25CB");
|
|
50
|
-
const date = new Date(plan.updatedAt).toLocaleDateString();
|
|
51
|
-
const versions = chalk.dim(`v${plan.versionCount}`);
|
|
52
|
-
console.log(` ${statusIcon} ${plan.title} ${versions} ${chalk.dim(date)}`);
|
|
53
|
-
console.log(chalk.dim(` slug: ${plan.slug}`));
|
|
54
|
-
}
|
|
55
|
-
if (plans.length > limit) {
|
|
56
|
-
console.log(chalk.dim(`
|
|
57
|
-
... and ${plans.length - limit} more. Use --limit to show more.`));
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
async function showReview(args) {
|
|
61
|
-
const slug = args[0];
|
|
62
|
-
if (!slug) {
|
|
63
|
-
console.error(chalk.red("Error: Please specify a plan slug."));
|
|
64
|
-
console.error("Usage: ulpi review show <slug>");
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
const plan = await loadPlan(slug);
|
|
68
|
-
if (!plan) {
|
|
69
|
-
console.error(chalk.red(`Plan not found: ${slug}`));
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
|
-
console.log(chalk.bold(plan.title));
|
|
73
|
-
console.log(chalk.dim(`Slug: ${plan.slug}`));
|
|
74
|
-
if (plan.projectPath) {
|
|
75
|
-
console.log(chalk.dim(`Project: ${plan.projectPath}`));
|
|
76
|
-
}
|
|
77
|
-
console.log();
|
|
78
|
-
console.log(chalk.bold("Versions:"));
|
|
79
|
-
for (const version of plan.versions) {
|
|
80
|
-
const decision = version.decision ? version.decision.behavior === "allow" ? chalk.green("approved") : chalk.red("denied") : chalk.yellow("pending");
|
|
81
|
-
const date = new Date(version.createdAt).toLocaleString();
|
|
82
|
-
const annotations = version.annotations.length;
|
|
83
|
-
const edits = version.inlineEdits.length;
|
|
84
|
-
console.log(` v${version.versionNumber} \u2014 ${decision} ${chalk.dim(date)}`);
|
|
85
|
-
if (annotations > 0 || edits > 0) {
|
|
86
|
-
console.log(chalk.dim(` ${annotations} annotation(s), ${edits} inline edit(s)`));
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
function showConfig(projectDir) {
|
|
91
|
-
const settings = loadUlpiSettings();
|
|
92
|
-
const review = settings.review;
|
|
93
|
-
console.log(chalk.bold("Review Configuration (effective)\n"));
|
|
94
|
-
console.log(` Enabled: ${formatBool(review.enabled)}`);
|
|
95
|
-
console.log(` Plan Review: ${formatBool(review.plan_review)}`);
|
|
96
|
-
console.log(` Code Review: ${formatBool(review.code_review)}`);
|
|
97
|
-
console.log(` Auto-open Browser: ${formatBool(review.auto_open_browser)}`);
|
|
98
|
-
const rules = loadRulesSync(projectGuardsFile(projectDir));
|
|
99
|
-
if (rules?.review) {
|
|
100
|
-
console.log(chalk.dim("\n Source: ~/.ulpi/settings.json + guards.yml review section"));
|
|
101
|
-
} else {
|
|
102
|
-
console.log(chalk.dim("\n Source: ~/.ulpi/settings.json (no review section in guards.yml)"));
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
function formatBool(val) {
|
|
106
|
-
return val ? chalk.green("yes") : chalk.red("no");
|
|
107
|
-
}
|
|
108
|
-
async function migrateData() {
|
|
109
|
-
const oldDir = path.join(homedir(), ".ulpi", "review", "plans");
|
|
110
|
-
const newDir = REVIEWS_DIR;
|
|
111
|
-
if (!fs.existsSync(oldDir)) {
|
|
112
|
-
console.log(chalk.dim("No legacy review data found at ~/.ulpi/review/plans/"));
|
|
113
|
-
return;
|
|
114
|
-
}
|
|
115
|
-
fs.mkdirSync(newDir, { recursive: true });
|
|
116
|
-
const entries = fs.readdirSync(oldDir, { withFileTypes: true });
|
|
117
|
-
const dirs = entries.filter((e) => e.isDirectory());
|
|
118
|
-
if (dirs.length === 0) {
|
|
119
|
-
console.log(chalk.dim("No plans to migrate."));
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
122
|
-
let migrated = 0;
|
|
123
|
-
for (const dir of dirs) {
|
|
124
|
-
const src = path.join(oldDir, dir.name);
|
|
125
|
-
const dst = path.join(newDir, dir.name);
|
|
126
|
-
if (fs.existsSync(dst)) {
|
|
127
|
-
console.log(chalk.dim(` Skipping ${dir.name} (already exists)`));
|
|
128
|
-
continue;
|
|
129
|
-
}
|
|
130
|
-
fs.cpSync(src, dst, { recursive: true });
|
|
131
|
-
migrated++;
|
|
132
|
-
console.log(chalk.green(` \u2713 Migrated: ${dir.name}`));
|
|
133
|
-
}
|
|
134
|
-
console.log(chalk.bold(`
|
|
135
|
-
Migrated ${migrated} plan(s) from ~/.ulpi/review/plans/ to ~/.ulpi/reviews/`));
|
|
136
|
-
}
|
|
137
|
-
function printUsage() {
|
|
138
|
-
console.log(`
|
|
139
|
-
Review \u2014 Plan and code review management
|
|
140
|
-
|
|
141
|
-
Usage: ulpi review <subcommand>
|
|
142
|
-
|
|
143
|
-
Subcommands:
|
|
144
|
-
list [--limit N] List reviewed plans
|
|
145
|
-
show <slug> Show plan details and version history
|
|
146
|
-
config Show review configuration
|
|
147
|
-
migrate Migrate data from ~/.ulpi/review/ to ~/.ulpi/reviews/
|
|
148
|
-
`.trim());
|
|
149
|
-
}
|
|
150
|
-
export {
|
|
151
|
-
runReview
|
|
152
|
-
};
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createApiServer
|
|
3
|
-
} from "./chunk-LD52XG3X.js";
|
|
4
|
-
import "./chunk-MIAQVCFW.js";
|
|
5
|
-
import "./chunk-YYZOFYS6.js";
|
|
6
|
-
import "./chunk-RJIRWQJD.js";
|
|
7
|
-
import "./chunk-EIWYSP3A.js";
|
|
8
|
-
import "./chunk-SIAQVRKG.js";
|
|
9
|
-
import "./chunk-IFATANHR.js";
|
|
10
|
-
import "./chunk-RSFJ6QSR.js";
|
|
11
|
-
import "./chunk-L3PWNHSA.js";
|
|
12
|
-
import "./chunk-26LLDX2T.js";
|
|
13
|
-
import "./chunk-KIKPIH6N.js";
|
|
14
|
-
import "./chunk-DDRLI6JU.js";
|
|
15
|
-
import "./chunk-4VNS5WPM.js";
|
|
16
|
-
export {
|
|
17
|
-
createApiServer
|
|
18
|
-
};
|
package/dist/ui-4SM2SUI6.js
DELETED
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createApiServer,
|
|
3
|
-
setUiServerPort
|
|
4
|
-
} from "./chunk-LD52XG3X.js";
|
|
5
|
-
import {
|
|
6
|
-
attachWebSocket
|
|
7
|
-
} from "./chunk-ELTGWMDE.js";
|
|
8
|
-
import {
|
|
9
|
-
generateApiSecret,
|
|
10
|
-
setApiSecret
|
|
11
|
-
} from "./chunk-MIAQVCFW.js";
|
|
12
|
-
import "./chunk-YYZOFYS6.js";
|
|
13
|
-
import "./chunk-RJIRWQJD.js";
|
|
14
|
-
import "./chunk-EIWYSP3A.js";
|
|
15
|
-
import "./chunk-SIAQVRKG.js";
|
|
16
|
-
import "./chunk-IFATANHR.js";
|
|
17
|
-
import "./chunk-RSFJ6QSR.js";
|
|
18
|
-
import "./chunk-L3PWNHSA.js";
|
|
19
|
-
import "./chunk-26LLDX2T.js";
|
|
20
|
-
import "./chunk-KIKPIH6N.js";
|
|
21
|
-
import {
|
|
22
|
-
API_LOCK_FILE,
|
|
23
|
-
getApiHost,
|
|
24
|
-
getApiPort
|
|
25
|
-
} from "./chunk-DDRLI6JU.js";
|
|
26
|
-
import "./chunk-4VNS5WPM.js";
|
|
27
|
-
|
|
28
|
-
// src/commands/ui.ts
|
|
29
|
-
import chalk from "chalk";
|
|
30
|
-
|
|
31
|
-
// ../api/dist/index.js
|
|
32
|
-
import * as fs from "fs";
|
|
33
|
-
import * as path from "path";
|
|
34
|
-
function writeApiLockFile(port, secret) {
|
|
35
|
-
try {
|
|
36
|
-
const dir = path.dirname(API_LOCK_FILE);
|
|
37
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
38
|
-
const lockData = { port, pid: process.pid, startedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
39
|
-
if (secret) lockData.secret = secret;
|
|
40
|
-
fs.writeFileSync(API_LOCK_FILE, JSON.stringify(lockData), { encoding: "utf-8", mode: 384 });
|
|
41
|
-
} catch {
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
function removeApiLockFile() {
|
|
45
|
-
try {
|
|
46
|
-
fs.unlinkSync(API_LOCK_FILE);
|
|
47
|
-
} catch {
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
async function main() {
|
|
51
|
-
const { getApiPort: getApiPort2, getApiHost: getApiHost2 } = await import("./dist-GWGTAHNM.js");
|
|
52
|
-
const { generateApiSecret: generateApiSecret2, setApiSecret: setApiSecret2 } = await import("./auth-PN7TMQHV-2W4ICG64.js");
|
|
53
|
-
const port = getApiPort2();
|
|
54
|
-
const host = getApiHost2();
|
|
55
|
-
const projectDir = process.argv[2] || process.cwd();
|
|
56
|
-
const secret = generateApiSecret2();
|
|
57
|
-
setApiSecret2(secret);
|
|
58
|
-
const { createApiServer: createApiServer2 } = await import("./server-USLHY6GH-F4JSXCWA.js");
|
|
59
|
-
const { attachWebSocket: attachWebSocket2 } = await import("./server-X5P6WH2M-ULZF5WHZ.js");
|
|
60
|
-
const server = createApiServer2(projectDir);
|
|
61
|
-
const wss = attachWebSocket2(server, projectDir);
|
|
62
|
-
const shutdown = () => {
|
|
63
|
-
console.log("\nShutting down ULPI API server...");
|
|
64
|
-
removeApiLockFile();
|
|
65
|
-
for (const client of wss.clients) {
|
|
66
|
-
client.close();
|
|
67
|
-
}
|
|
68
|
-
wss.close();
|
|
69
|
-
server.close(() => {
|
|
70
|
-
console.log("Server stopped.");
|
|
71
|
-
process.exit(0);
|
|
72
|
-
});
|
|
73
|
-
setTimeout(() => process.exit(0), 5e3).unref();
|
|
74
|
-
};
|
|
75
|
-
process.on("SIGTERM", shutdown);
|
|
76
|
-
process.on("SIGINT", shutdown);
|
|
77
|
-
server.listen(port, host, () => {
|
|
78
|
-
writeApiLockFile(port, secret);
|
|
79
|
-
console.log(`ULPI API server running at http://${host}:${port}`);
|
|
80
|
-
console.log(` WebSocket: ws://${host}:${port}/ws`);
|
|
81
|
-
console.log(` API: http://${host}:${port}/api/health`);
|
|
82
|
-
console.log(` Project: ${projectDir}`);
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
var isDirectRun = process.argv[1] && (process.argv[1].endsWith("index.js") || process.argv[1].endsWith("index.mjs"));
|
|
86
|
-
if (isDirectRun) {
|
|
87
|
-
main().catch((err) => {
|
|
88
|
-
console.error(
|
|
89
|
-
"Fatal:",
|
|
90
|
-
err instanceof Error ? err.message : String(err)
|
|
91
|
-
);
|
|
92
|
-
process.exit(1);
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// src/commands/ui.ts
|
|
97
|
-
async function runUI(args, projectDir) {
|
|
98
|
-
const portIndex = args.indexOf("--port");
|
|
99
|
-
let port = getApiPort();
|
|
100
|
-
if (portIndex !== -1 && args[portIndex + 1]) {
|
|
101
|
-
const parsed = parseInt(args[portIndex + 1], 10);
|
|
102
|
-
if (isNaN(parsed) || parsed < 1 || parsed > 65535) {
|
|
103
|
-
console.log(chalk.red("Invalid port number. Must be between 1 and 65535."));
|
|
104
|
-
process.exit(1);
|
|
105
|
-
}
|
|
106
|
-
port = parsed;
|
|
107
|
-
}
|
|
108
|
-
const host = getApiHost();
|
|
109
|
-
try {
|
|
110
|
-
const secret = generateApiSecret();
|
|
111
|
-
setApiSecret(secret);
|
|
112
|
-
setUiServerPort(port);
|
|
113
|
-
const server = createApiServer(projectDir);
|
|
114
|
-
const wss = attachWebSocket(server, projectDir);
|
|
115
|
-
const shutdown = () => {
|
|
116
|
-
console.log("\nShutting down ULPI server...");
|
|
117
|
-
removeApiLockFile();
|
|
118
|
-
for (const client of wss.clients) {
|
|
119
|
-
client.close();
|
|
120
|
-
}
|
|
121
|
-
wss.close();
|
|
122
|
-
server.close(() => {
|
|
123
|
-
console.log("Server stopped.");
|
|
124
|
-
process.exit(0);
|
|
125
|
-
});
|
|
126
|
-
setTimeout(() => process.exit(0), 5e3).unref();
|
|
127
|
-
};
|
|
128
|
-
process.on("SIGTERM", shutdown);
|
|
129
|
-
process.on("SIGINT", shutdown);
|
|
130
|
-
await new Promise((resolve, reject) => {
|
|
131
|
-
server.on("error", (err) => {
|
|
132
|
-
if (err.code === "EADDRINUSE") {
|
|
133
|
-
console.error(
|
|
134
|
-
`Port ${port} is already in use. Try a different port with --port.`
|
|
135
|
-
);
|
|
136
|
-
}
|
|
137
|
-
reject(err);
|
|
138
|
-
});
|
|
139
|
-
server.listen(port, host, () => {
|
|
140
|
-
writeApiLockFile(port, secret);
|
|
141
|
-
console.log(`
|
|
142
|
-
ULPI server running at:
|
|
143
|
-
`);
|
|
144
|
-
console.log(` http://${host}:${port}
|
|
145
|
-
`);
|
|
146
|
-
console.log(` WebSocket: ws://${host}:${port}/ws`);
|
|
147
|
-
console.log(` API: http://${host}:${port}/api/rules
|
|
148
|
-
`);
|
|
149
|
-
console.log(`Project dir: ${projectDir}
|
|
150
|
-
`);
|
|
151
|
-
console.log(`Press Ctrl+C to stop.
|
|
152
|
-
`);
|
|
153
|
-
resolve();
|
|
154
|
-
});
|
|
155
|
-
});
|
|
156
|
-
} catch (err) {
|
|
157
|
-
console.error(
|
|
158
|
-
chalk.red(
|
|
159
|
-
`Failed to start UI server: ${err instanceof Error ? err.message : String(err)}`
|
|
160
|
-
)
|
|
161
|
-
);
|
|
162
|
-
process.exit(1);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
export {
|
|
166
|
-
runUI
|
|
167
|
-
};
|