@auroraflow/code 0.0.20 → 0.0.21
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 +4 -0
- package/package.json +1 -1
- package/packages/cli/src/index.js +27 -9
- package/packages/clients/src/index.js +124 -1
package/README.md
CHANGED
|
@@ -40,6 +40,7 @@ aurora install all
|
|
|
40
40
|
aurora repair codex
|
|
41
41
|
aurora repair claude
|
|
42
42
|
aurora doctor
|
|
43
|
+
aurora doctor --json
|
|
43
44
|
```
|
|
44
45
|
|
|
45
46
|
## Commands
|
|
@@ -55,6 +56,7 @@ node bin/aurora.js install codex
|
|
|
55
56
|
node bin/aurora.js install claude
|
|
56
57
|
node bin/aurora.js repair codex
|
|
57
58
|
node bin/aurora.js doctor
|
|
59
|
+
node bin/aurora.js doctor --json
|
|
58
60
|
node bin/aurora.js install-clients
|
|
59
61
|
node bin/aurora.js update-clients
|
|
60
62
|
node bin/aurora.js status
|
|
@@ -66,6 +68,8 @@ If the selected official client is missing, Aurora prompts to install that
|
|
|
66
68
|
specific client before launch.
|
|
67
69
|
If the package exists but its command is not usable, Aurora reports a broken
|
|
68
70
|
client state and prompts to repair instead of calling it "not installed".
|
|
71
|
+
`aurora doctor` prints a human-readable health summary, including npm, disk
|
|
72
|
+
space on Windows, and repair commands for missing or broken clients.
|
|
69
73
|
|
|
70
74
|
The launcher stores shared local state under `~/.aurora` and starts a local
|
|
71
75
|
sidecar at `127.0.0.1:17878`. Official clients talk to the sidecar; the sidecar
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ensureLayout, readAccount, readState, writeAccount, writeState } from "../../state/src/index.js";
|
|
2
|
-
import { installOfficialClient, officialClientStatus, officialClientStatuses, repairOfficialClient, runClient, updateOfficialClients } from "../../clients/src/index.js";
|
|
2
|
+
import { installOfficialClient, officialClientStatus, officialClientStatuses, officialClientsDoctor, repairOfficialClient, runClient, updateOfficialClients } from "../../clients/src/index.js";
|
|
3
3
|
import { ensureSidecarRunning, installSidecarService, sidecarServiceStatus, uninstallSidecarService } from "../../service/src/index.js";
|
|
4
4
|
import { chooseClient, promptChoice, promptFields } from "../../../lib/prompt.js";
|
|
5
5
|
|
|
@@ -29,7 +29,7 @@ export async function runAuroraCLI(argv = process.argv.slice(2)) {
|
|
|
29
29
|
}, null, 2));
|
|
30
30
|
return;
|
|
31
31
|
case "doctor":
|
|
32
|
-
await doctorCommand();
|
|
32
|
+
await doctorCommand(rest);
|
|
33
33
|
return;
|
|
34
34
|
case "install":
|
|
35
35
|
await installCommand(rest);
|
|
@@ -120,18 +120,35 @@ async function repairCommand(args) {
|
|
|
120
120
|
}
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
-
async function doctorCommand() {
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
123
|
+
async function doctorCommand(args = []) {
|
|
124
|
+
const report = officialClientsDoctor();
|
|
125
|
+
if (args.includes("--json")) {
|
|
126
|
+
console.log(JSON.stringify(report, null, 2));
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
console.log("Aurora doctor\n");
|
|
130
|
+
console.log(`Platform: ${report.platform}`);
|
|
131
|
+
console.log(`npm: ${report.npm.ok ? `ok (${report.npm.version})` : `problem (${report.npm.error || "unknown"})`}`);
|
|
132
|
+
if (report.disk.checked) {
|
|
133
|
+
console.log(`Disk ${report.disk.drive}: ${report.disk.availableMB ?? "unknown"} MB free`);
|
|
134
|
+
}
|
|
135
|
+
console.log("");
|
|
136
|
+
for (const status of report.officialClients) {
|
|
137
|
+
console.log(`${status.name}: ${status.state}${status.version ? ` (${status.version})` : ""}`);
|
|
138
|
+
if (status.bin) console.log(` command: ${status.bin}`);
|
|
139
|
+
if (status.packagePath) console.log(` package: ${status.packagePath}`);
|
|
140
|
+
if (status.problem) console.log(` problem: ${status.problem}`);
|
|
141
|
+
if (status.state === "missing") console.log(` fix: aurora install ${status.id}`);
|
|
127
142
|
if (status.state === "broken") {
|
|
128
|
-
console.
|
|
129
|
-
console.error(`Repair: aurora repair ${status.id}`);
|
|
143
|
+
console.log(` fix: aurora repair ${status.id}`);
|
|
130
144
|
if (process.platform === "win32") {
|
|
131
|
-
console.
|
|
145
|
+
console.log(` if locked: taskkill /F /IM ${status.id === "claude" ? "claude.exe" : "codex.exe"}`);
|
|
132
146
|
}
|
|
133
147
|
}
|
|
134
148
|
}
|
|
149
|
+
if (report.disk.checked && report.disk.availableBytes != null && report.disk.availableBytes < 512 * 1024 * 1024) {
|
|
150
|
+
console.log("\nWarning: low disk space can break npm install/repair. Free space and run: npm cache clean --force");
|
|
151
|
+
}
|
|
135
152
|
}
|
|
136
153
|
|
|
137
154
|
export async function runAuroraClaude(argv = process.argv.slice(2)) {
|
|
@@ -258,6 +275,7 @@ function usage(exitCode) {
|
|
|
258
275
|
aurora repair codex
|
|
259
276
|
aurora repair claude
|
|
260
277
|
aurora doctor
|
|
278
|
+
aurora doctor --json
|
|
261
279
|
aurora install-clients
|
|
262
280
|
aurora update-clients
|
|
263
281
|
aurora status
|
|
@@ -97,12 +97,18 @@ export async function installOfficialClients() {
|
|
|
97
97
|
export async function installOfficialClient(client, options = {}) {
|
|
98
98
|
const spec = OFFICIAL_CLIENTS[client];
|
|
99
99
|
if (!spec) throw new Error(`unknown official client: ${client}`);
|
|
100
|
+
const preflight = officialClientPreflight(client);
|
|
101
|
+
if (!preflight.ok) throw new Error(formatOfficialClientPreflightError(spec, preflight));
|
|
100
102
|
const npm = npmCommandSpec();
|
|
101
103
|
const args = ["install", "-g"];
|
|
102
104
|
if (options.repair) args.push("--force");
|
|
103
105
|
args.push(`${spec.packageName}@latest`);
|
|
104
106
|
console.error(`[aurora] ${options.repair ? "repairing" : "installing"} ${spec.name}: ${npm.command} ${[...npm.args, ...args].join(" ")}`);
|
|
105
|
-
|
|
107
|
+
try {
|
|
108
|
+
await spawnAndWait(npm.command, [...npm.args, ...args], { ...process.env });
|
|
109
|
+
} catch (error) {
|
|
110
|
+
throw new Error(formatOfficialClientInstallError(spec, client, error));
|
|
111
|
+
}
|
|
106
112
|
}
|
|
107
113
|
|
|
108
114
|
export async function repairOfficialClient(client) {
|
|
@@ -117,6 +123,16 @@ export function officialClientStatus(client) {
|
|
|
117
123
|
return officialClientStatuses().find(status => status.id === client) ?? null;
|
|
118
124
|
}
|
|
119
125
|
|
|
126
|
+
export function officialClientsDoctor() {
|
|
127
|
+
return {
|
|
128
|
+
platform: process.platform,
|
|
129
|
+
npm: npmDoctor(),
|
|
130
|
+
disk: diskDoctor(),
|
|
131
|
+
processHints: processHints(),
|
|
132
|
+
officialClients: officialClientStatuses()
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
120
136
|
function officialClientBin(client) {
|
|
121
137
|
const spec = OFFICIAL_CLIENTS[client];
|
|
122
138
|
if (!spec) throw new Error(`unknown official client: ${client}`);
|
|
@@ -179,6 +195,113 @@ function officialClientProblem(state, bin, packagePath) {
|
|
|
179
195
|
return "unknown";
|
|
180
196
|
}
|
|
181
197
|
|
|
198
|
+
function officialClientPreflight(client) {
|
|
199
|
+
const disk = diskDoctor();
|
|
200
|
+
if (disk.availableBytes != null && disk.availableBytes < 512 * 1024 * 1024) {
|
|
201
|
+
return { ok: false, reason: "low_disk_space", disk };
|
|
202
|
+
}
|
|
203
|
+
const processes = processHints();
|
|
204
|
+
const locked = processes.find(item => item.client === client && item.running);
|
|
205
|
+
if (locked) return { ok: false, reason: "client_process_running", process: locked };
|
|
206
|
+
return { ok: true, disk, processes };
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
function npmDoctor() {
|
|
210
|
+
try {
|
|
211
|
+
const npm = npmCommandSpec();
|
|
212
|
+
const result = spawnSyncCompat(npm.command, [...npm.args, "--version"]);
|
|
213
|
+
return {
|
|
214
|
+
command: npm.command,
|
|
215
|
+
args: npm.args,
|
|
216
|
+
ok: result.status === 0,
|
|
217
|
+
version: String(result.stdout || result.stderr || "").trim() || null
|
|
218
|
+
};
|
|
219
|
+
} catch (error) {
|
|
220
|
+
return { ok: false, error: error?.message || String(error) };
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function diskDoctor() {
|
|
225
|
+
if (process.platform !== "win32") return { checked: false, reason: "not_windows" };
|
|
226
|
+
try {
|
|
227
|
+
const drive = (process.env.APPDATA || process.cwd()).slice(0, 2);
|
|
228
|
+
const result = spawnSync("powershell.exe", [
|
|
229
|
+
"-NoProfile",
|
|
230
|
+
"-Command",
|
|
231
|
+
`(Get-PSDrive -Name ${JSON.stringify(drive.charAt(0))}).Free`
|
|
232
|
+
], { encoding: "utf8" });
|
|
233
|
+
const availableBytes = Number(String(result.stdout || "").trim());
|
|
234
|
+
return {
|
|
235
|
+
checked: true,
|
|
236
|
+
drive,
|
|
237
|
+
availableBytes: Number.isFinite(availableBytes) ? availableBytes : null,
|
|
238
|
+
availableMB: Number.isFinite(availableBytes) ? Math.floor(availableBytes / 1024 / 1024) : null
|
|
239
|
+
};
|
|
240
|
+
} catch (error) {
|
|
241
|
+
return { checked: false, error: error?.message || String(error) };
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function processHints() {
|
|
246
|
+
if (process.platform !== "win32") return [];
|
|
247
|
+
return [
|
|
248
|
+
{ client: "claude", image: "claude.exe", running: isWindowsProcessRunning("claude.exe") },
|
|
249
|
+
{ client: "codex", image: "codex.exe", running: isWindowsProcessRunning("codex.exe") },
|
|
250
|
+
{ client: "codex", image: "node.exe", running: false, note: "Codex may run through node.exe depending on npm package version." }
|
|
251
|
+
];
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function isWindowsProcessRunning(image) {
|
|
255
|
+
try {
|
|
256
|
+
const result = spawnSync("tasklist", ["/FI", `IMAGENAME eq ${image}`], { encoding: "utf8" });
|
|
257
|
+
return String(result.stdout || "").toLowerCase().includes(image.toLowerCase());
|
|
258
|
+
} catch {
|
|
259
|
+
return false;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
function formatOfficialClientPreflightError(spec, preflight) {
|
|
264
|
+
if (preflight.reason === "low_disk_space") {
|
|
265
|
+
return `${spec.name} repair/install blocked: low disk space on ${preflight.disk.drive} (${preflight.disk.availableMB} MB free). Free at least 512 MB, run npm cache clean --force, then retry.`;
|
|
266
|
+
}
|
|
267
|
+
if (preflight.reason === "client_process_running") {
|
|
268
|
+
return `${spec.name} repair/install blocked: ${preflight.process.image} is running. Close ${spec.name} or run: taskkill /F /IM ${preflight.process.image}`;
|
|
269
|
+
}
|
|
270
|
+
return `${spec.name} repair/install preflight failed: ${preflight.reason}`;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
function formatOfficialClientInstallError(spec, client, error) {
|
|
274
|
+
const message = error?.message || String(error);
|
|
275
|
+
const suggestions = officialClientFailureSuggestions(client, message);
|
|
276
|
+
return [`${spec.name} install/repair failed: ${message}`, ...suggestions].join("\n");
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function officialClientFailureSuggestions(client, message) {
|
|
280
|
+
const text = String(message);
|
|
281
|
+
const image = client === "claude" ? "claude.exe" : "codex.exe";
|
|
282
|
+
if (/ENOSPC|no space left/i.test(text)) {
|
|
283
|
+
return [
|
|
284
|
+
"Detected cause: disk is full.",
|
|
285
|
+
"Fix: free disk space, then run: npm cache clean --force",
|
|
286
|
+
`Retry: aurora repair ${client}`
|
|
287
|
+
];
|
|
288
|
+
}
|
|
289
|
+
if (/EBUSY|EPERM|resource busy|operation not permitted/i.test(text)) {
|
|
290
|
+
return [
|
|
291
|
+
"Detected cause: files are locked by a running process or antivirus.",
|
|
292
|
+
process.platform === "win32" ? `Fix: close the client, then run: taskkill /F /IM ${image}` : "Fix: close the running client process.",
|
|
293
|
+
`Retry: aurora repair ${client}`
|
|
294
|
+
];
|
|
295
|
+
}
|
|
296
|
+
if (/ENOENT|not found/i.test(text)) {
|
|
297
|
+
return [
|
|
298
|
+
"Detected cause: npm or a required command was not found.",
|
|
299
|
+
"Fix: reinstall Node.js/npm or add npm to PATH, then retry."
|
|
300
|
+
];
|
|
301
|
+
}
|
|
302
|
+
return [`Run diagnostics: aurora doctor`, `Retry after fixing the reported issue: aurora repair ${client}`];
|
|
303
|
+
}
|
|
304
|
+
|
|
182
305
|
function readOfficialClientVersion(bin) {
|
|
183
306
|
if (!bin) return null;
|
|
184
307
|
try {
|