@auroraflow/code 0.0.15 → 0.0.17

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 CHANGED
@@ -16,8 +16,7 @@ lib/ current MVP support modules
16
16
 
17
17
  ## Install
18
18
 
19
- Installing `@auroraflow/code` as a global npm package attempts to install/update the
20
- official Claude Code and Codex global commands:
19
+ Install `@auroraflow/code` as a global npm package:
21
20
 
22
21
  ```bash
23
22
  npm install -g @auroraflow/code
@@ -26,12 +25,18 @@ npm install -g @auroraflow/code
26
25
  Aurora does not export `claude` or `codex` bins. The standalone `claude` and
27
26
  `codex` commands remain the official clients and keep their official behavior.
28
27
  Aurora only wraps them through `aurora-claude` and `aurora-codex`.
28
+ Aurora does not auto-install official clients during package installation; this
29
+ keeps `npm install -g @auroraflow/code` fast and avoids hiding npm/network
30
+ failures inside postinstall.
29
31
 
30
32
  To install or update the official clients explicitly:
31
33
 
32
34
  ```bash
33
35
  aurora install-clients
34
36
  aurora update-clients
37
+ aurora install codex
38
+ aurora install claude
39
+ aurora install all
35
40
  ```
36
41
 
37
42
  ## Commands
@@ -43,6 +48,8 @@ node bin/aurora.js
43
48
  node bin/aurora.js init
44
49
  node bin/aurora.js claude
45
50
  node bin/aurora.js codex
51
+ node bin/aurora.js install codex
52
+ node bin/aurora.js install claude
46
53
  node bin/aurora.js install-clients
47
54
  node bin/aurora.js update-clients
48
55
  node bin/aurora.js status
@@ -50,6 +57,8 @@ node bin/aurora.js status
50
57
 
51
58
  Running `aurora` without a subcommand opens an interactive client selector. Use
52
59
  Up/Down (or `j`/`k`) and Enter to launch Claude or Codex through Aurora.
60
+ If the selected official client is missing, Aurora prompts to install that
61
+ specific client before launch.
53
62
 
54
63
  The launcher stores shared local state under `~/.aurora` and starts a local
55
64
  sidecar at `127.0.0.1:17878`. Official clients talk to the sidecar; the sidecar
@@ -1,4 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import { runAuroraClaude } from "../packages/cli/src/index.js";
3
3
 
4
- await runAuroraClaude(process.argv.slice(2));
4
+ try {
5
+ await runAuroraClaude(process.argv.slice(2));
6
+ } catch (error) {
7
+ console.error(`Aurora Claude error: ${error?.message || error}`);
8
+ process.exit(1);
9
+ }
@@ -1,4 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import { runAuroraCodex } from "../packages/cli/src/index.js";
3
3
 
4
- await runAuroraCodex(process.argv.slice(2));
4
+ try {
5
+ await runAuroraCodex(process.argv.slice(2));
6
+ } catch (error) {
7
+ console.error(`Aurora Codex error: ${error?.message || error}`);
8
+ process.exit(1);
9
+ }
@@ -1,13 +1,16 @@
1
1
  #!/usr/bin/env node
2
2
  import { installOfficialClients, isGlobalNpmLifecycle, officialClientStatuses } from "../packages/clients/src/index.js";
3
3
 
4
- if (!process.env.AURORA_SKIP_OFFICIAL_CLIENT_INSTALL && isGlobalNpmLifecycle()) {
4
+ if (process.env.AURORA_INSTALL_OFFICIAL_CLIENTS === "1" && isGlobalNpmLifecycle()) {
5
5
  try {
6
6
  await installOfficialClients();
7
7
  } catch (error) {
8
8
  console.error(`[aurora-code] official client install failed: ${error.message}`);
9
9
  console.error("[aurora-code] run `aurora install-clients` after installation.");
10
10
  }
11
+ } else if (isGlobalNpmLifecycle()) {
12
+ console.error("[aurora-code] installed Aurora launcher. Official Claude/Codex clients are not auto-installed.");
13
+ console.error("[aurora-code] run `aurora install-clients`, or install only what you need: `npm install -g @openai/codex@latest`.");
11
14
  }
12
15
 
13
16
  const statuses = officialClientStatuses();
package/bin/aurora.js CHANGED
@@ -1,4 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import { runAuroraCLI } from "../packages/cli/src/index.js";
3
3
 
4
- await runAuroraCLI(process.argv.slice(2));
4
+ try {
5
+ await runAuroraCLI(process.argv.slice(2));
6
+ } catch (error) {
7
+ console.error(`Aurora error: ${error?.message || error}`);
8
+ process.exit(1);
9
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@auroraflow/code",
3
- "version": "0.0.15",
3
+ "version": "0.0.17",
4
4
  "type": "module",
5
5
  "description": "Aurora launcher and sidecar for official Codex and Claude Code clients.",
6
6
  "repository": {
@@ -1,7 +1,7 @@
1
1
  import { ensureLayout, readAccount, readState, writeAccount, writeState } from "../../state/src/index.js";
2
- import { officialClientStatuses, runClient, updateOfficialClients } from "../../clients/src/index.js";
2
+ import { installOfficialClient, officialClientStatus, officialClientStatuses, runClient, updateOfficialClients } from "../../clients/src/index.js";
3
3
  import { ensureSidecarRunning, installSidecarService, sidecarServiceStatus, uninstallSidecarService } from "../../service/src/index.js";
4
- import { chooseClient, promptFields } from "../../../lib/prompt.js";
4
+ import { chooseClient, promptChoice, promptFields } from "../../../lib/prompt.js";
5
5
 
6
6
  export async function runAuroraCLI(argv = process.argv.slice(2)) {
7
7
  await ensureLayout();
@@ -28,6 +28,9 @@ export async function runAuroraCLI(argv = process.argv.slice(2)) {
28
28
  officialClients: officialClientStatuses()
29
29
  }, null, 2));
30
30
  return;
31
+ case "install":
32
+ await installCommand(rest);
33
+ return;
31
34
  case "install-clients":
32
35
  case "install-official-clients":
33
36
  case "update-clients":
@@ -70,6 +73,26 @@ async function sidecarCommand(args) {
70
73
  }
71
74
  }
72
75
 
76
+ async function installCommand(args) {
77
+ const target = args[0] ?? "";
78
+ switch (target) {
79
+ case "codex":
80
+ case "claude":
81
+ await installOfficialClient(target);
82
+ console.log(JSON.stringify({ officialClients: officialClientStatuses() }, null, 2));
83
+ return;
84
+ case "all":
85
+ case "clients":
86
+ case "official-clients":
87
+ await updateOfficialClients();
88
+ console.log(JSON.stringify({ officialClients: officialClientStatuses() }, null, 2));
89
+ return;
90
+ default:
91
+ console.error("Usage: aurora install [codex|claude|all]");
92
+ process.exit(1);
93
+ }
94
+ }
95
+
73
96
  export async function runAuroraClaude(argv = process.argv.slice(2)) {
74
97
  await ensureLayout();
75
98
  await runClient("claude", argv);
@@ -86,9 +109,23 @@ async function startInteractive(args) {
86
109
  await init();
87
110
  }
88
111
  const client = await chooseClient();
112
+ await ensureOfficialClientForInteractive(client);
89
113
  await runClient(client, args);
90
114
  }
91
115
 
116
+ async function ensureOfficialClientForInteractive(client) {
117
+ const status = officialClientStatus(client);
118
+ if (status?.installed) return;
119
+ const action = await promptChoice(`${status?.name ?? client} is not installed`, [
120
+ { label: `Install ${status?.name ?? client} now`, value: "install" },
121
+ { label: "Exit", value: "exit" }
122
+ ]);
123
+ if (action !== "install") {
124
+ throw new Error(`${status?.name ?? client} is required. Run: aurora install ${client}`);
125
+ }
126
+ await installOfficialClient(client);
127
+ }
128
+
92
129
  async function init() {
93
130
  const existing = await readState();
94
131
  const account = await readAccount();
@@ -164,6 +201,9 @@ function usage(exitCode) {
164
201
  aurora init
165
202
  aurora claude [args...]
166
203
  aurora codex [args...]
204
+ aurora install codex
205
+ aurora install claude
206
+ aurora install all
167
207
  aurora install-clients
168
208
  aurora update-clients
169
209
  aurora status
@@ -8,6 +8,7 @@ import { ensureSidecarRunning } from "../../service/src/index.js";
8
8
 
9
9
  const here = dirname(fileURLToPath(import.meta.url));
10
10
  const packageRoot = resolve(here, "..", "..", "..");
11
+ const CODEX_MODEL_CATALOG_TIMEOUT_MS = 30000;
11
12
 
12
13
  const OFFICIAL_CLIENTS = {
13
14
  claude: {
@@ -24,10 +25,10 @@ const OFFICIAL_CLIENTS = {
24
25
 
25
26
  export async function createClientLaunchSpec(client, args = []) {
26
27
  const command = officialClientBin(client);
27
- const sidecar = await ensureSidecarRunning();
28
28
  const state = await readState();
29
29
  const model = selectedModelAlias(state);
30
30
  const key = selectedKey(state);
31
+ const sidecar = await ensureSidecarRunning();
31
32
  if (client === "claude") {
32
33
  const env = {
33
34
  ...process.env,
@@ -83,8 +84,15 @@ export async function updateOfficialClients() {
83
84
  }
84
85
 
85
86
  export async function installOfficialClients() {
87
+ await installOfficialClient("claude");
88
+ await installOfficialClient("codex");
89
+ }
90
+
91
+ export async function installOfficialClient(client) {
92
+ const spec = OFFICIAL_CLIENTS[client];
93
+ if (!spec) throw new Error(`unknown official client: ${client}`);
86
94
  const npm = npmCommandSpec();
87
- const args = ["install", "-g", "@anthropic-ai/claude-code@latest", "@openai/codex@latest"];
95
+ const args = ["install", "-g", `${spec.packageName}@latest`];
88
96
  await spawnAndWait(npm.command, [...npm.args, ...args], { ...process.env });
89
97
  }
90
98
 
@@ -92,12 +100,16 @@ export function isGlobalNpmLifecycle() {
92
100
  return process.env.npm_config_global === "true" || process.env.npm_config_location === "global";
93
101
  }
94
102
 
103
+ export function officialClientStatus(client) {
104
+ return officialClientStatuses().find(status => status.id === client) ?? null;
105
+ }
106
+
95
107
  function officialClientBin(client) {
96
108
  const spec = OFFICIAL_CLIENTS[client];
97
109
  if (!spec) throw new Error(`unknown official client: ${client}`);
98
110
  const bin = resolveOfficialClientBin(spec.binName);
99
111
  if (!bin) {
100
- throw new Error(`${spec.name} is not installed. Run: aurora install-clients`);
112
+ throw new Error(`${spec.name} is not installed. Run: aurora install ${client}`);
101
113
  }
102
114
  return bin;
103
115
  }
@@ -171,13 +183,18 @@ stream_idle_timeout_ms = 300000
171
183
 
172
184
  async function writeCodexModelCatalog(sidecar, modelCatalogPath) {
173
185
  const clientVersion = "0.137.0";
174
- const response = await fetch(
175
- `${sidecar.baseURL}/v1/models?client_version=${encodeURIComponent(clientVersion)}`,
176
- {
177
- headers: { authorization: `Bearer ${sidecar.token}` },
178
- signal: AbortSignal.timeout(5000)
179
- }
180
- );
186
+ let response;
187
+ try {
188
+ response = await fetch(
189
+ `${sidecar.baseURL}/v1/models?client_version=${encodeURIComponent(clientVersion)}`,
190
+ {
191
+ headers: { authorization: `Bearer ${sidecar.token}` },
192
+ signal: AbortSignal.timeout(CODEX_MODEL_CATALOG_TIMEOUT_MS)
193
+ }
194
+ );
195
+ } catch (error) {
196
+ throw new Error(`Aurora Codex model catalog request timed out after ${CODEX_MODEL_CATALOG_TIMEOUT_MS / 1000}s. Check Aurora Desktop key/model selection and network to Aurora Gateway. (${error?.message || error})`);
197
+ }
181
198
  if (!response.ok) {
182
199
  throw new Error(`Aurora Codex model catalog request failed with HTTP ${response.status}`);
183
200
  }
@@ -48,6 +48,7 @@ export async function ensureSidecarIdentity() {
48
48
  }
49
49
 
50
50
  export async function startSidecar(options = {}) {
51
+ installSidecarProcessGuards();
51
52
  const tokenOverride = options.token || readArg("--token") || process.env.AURORA_SIDECAR_TOKEN;
52
53
  const portOverride = options.port || readArg("--port") || process.env.AURORA_SIDECAR_PORT;
53
54
  const identity = await ensureSidecarIdentity();
@@ -134,18 +135,22 @@ async function pingLocalSidecar(port, token) {
134
135
  }
135
136
  }
136
137
 
137
- // The sidecar is a long-lived local proxy that Claude Code / Codex depend on
138
- // for every request. A single bad request (e.g. a mid-stream upstream drop)
139
- // must NOT kill the process: an orphaned sidecar with no live supervisor never
140
- // comes back, leaving the client stuck on ConnectionRefused. Log and keep
141
- // serving; the HTTP server stays healthy for the next request.
142
- process.on("uncaughtException", error => {
143
- console.error(`Aurora sidecar uncaught exception: ${error?.stack || error?.message || error}`);
144
- });
138
+ function installSidecarProcessGuards() {
139
+ if (process.__auroraSidecarProcessGuardsInstalled) return;
140
+ process.__auroraSidecarProcessGuardsInstalled = true;
141
+ // The sidecar is a long-lived local proxy that Claude Code / Codex depend on
142
+ // for every request. A single bad request (e.g. a mid-stream upstream drop)
143
+ // must NOT kill the process: an orphaned sidecar with no live supervisor never
144
+ // comes back, leaving the client stuck on ConnectionRefused. Log and keep
145
+ // serving; the HTTP server stays healthy for the next request.
146
+ process.on("uncaughtException", error => {
147
+ console.error(`Aurora sidecar uncaught exception: ${error?.stack || error?.message || error}`);
148
+ });
145
149
 
146
- process.on("unhandledRejection", reason => {
147
- console.error(`Aurora sidecar unhandled rejection: ${reason?.stack || reason?.message || reason}`);
148
- });
150
+ process.on("unhandledRejection", reason => {
151
+ console.error(`Aurora sidecar unhandled rejection: ${reason?.stack || reason?.message || reason}`);
152
+ });
153
+ }
149
154
 
150
155
  async function handle(request, response, token) {
151
156
  if (!isAuthorized(request, token)) {