@drisp/cli 0.4.5 → 0.5.0
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/dist/{WorkflowInstallWizard-2MC5A7W4.js → WorkflowInstallWizard-X754ND4V.js} +2 -2
- package/dist/athena-gateway.js +5 -3888
- package/dist/chunk-2OJ3GGIP.js +104 -0
- package/dist/{chunk-5VK2ZMVV.js → chunk-A54HGVML.js} +96 -95
- package/dist/{chunk-4CRZXLIP.js → chunk-BTY7MYYT.js} +135 -135
- package/dist/{chunk-PJUDHH4R.js → chunk-K53YMYTG.js} +1049 -812
- package/dist/chunk-MRAM6EYI.js +76 -0
- package/dist/chunk-SHLHZL5F.js +4124 -0
- package/dist/chunk-ZVOGOZNT.js +395 -0
- package/dist/cli.js +1131 -888
- package/dist/dashboard-daemon.js +9 -107
- package/dist/supervisor.js +692 -0
- package/package.json +1 -1
- package/dist/chunk-M44KEGM7.js +0 -173
|
@@ -1,16 +1,133 @@
|
|
|
1
|
-
// src/
|
|
1
|
+
// src/infra/config/dashboardClient.ts
|
|
2
|
+
import crypto from "crypto";
|
|
3
|
+
import fs from "fs";
|
|
2
4
|
import os from "os";
|
|
3
5
|
import path from "path";
|
|
6
|
+
function dashboardClientConfigPath(env = process.env) {
|
|
7
|
+
const home = env["HOME"] ?? os.homedir();
|
|
8
|
+
return path.join(home, ".config", "athena", "dashboard.json");
|
|
9
|
+
}
|
|
10
|
+
function normalizeDashboardUrl(input) {
|
|
11
|
+
let parsed;
|
|
12
|
+
try {
|
|
13
|
+
parsed = new URL(input);
|
|
14
|
+
} catch {
|
|
15
|
+
throw new Error("dashboard url must be a valid URL");
|
|
16
|
+
}
|
|
17
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
18
|
+
throw new Error("dashboard url must use http:// or https://");
|
|
19
|
+
}
|
|
20
|
+
return parsed.origin;
|
|
21
|
+
}
|
|
22
|
+
function readDashboardClientConfig(env = process.env) {
|
|
23
|
+
const configPath = dashboardClientConfigPath(env);
|
|
24
|
+
let raw;
|
|
25
|
+
try {
|
|
26
|
+
raw = fs.readFileSync(configPath, "utf-8");
|
|
27
|
+
} catch (err) {
|
|
28
|
+
if (err.code === "ENOENT") return null;
|
|
29
|
+
throw err;
|
|
30
|
+
}
|
|
31
|
+
let parsed;
|
|
32
|
+
try {
|
|
33
|
+
parsed = JSON.parse(raw);
|
|
34
|
+
} catch (err) {
|
|
35
|
+
throw new Error(
|
|
36
|
+
`dashboard client config ${configPath} is invalid JSON: ${err instanceof Error ? err.message : String(err)}`
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
try {
|
|
40
|
+
return parseDashboardClientConfig(parsed);
|
|
41
|
+
} catch (err) {
|
|
42
|
+
throw new Error(
|
|
43
|
+
`dashboard client config ${configPath} is invalid: ${err instanceof Error ? err.message : String(err)}`
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function writeDashboardClientConfig(config, env = process.env) {
|
|
48
|
+
const validated = parseDashboardClientConfig(config);
|
|
49
|
+
const configPath = dashboardClientConfigPath(env);
|
|
50
|
+
const dir = path.dirname(configPath);
|
|
51
|
+
fs.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
52
|
+
const tmpPath = `${configPath}.${process.pid}.${crypto.randomBytes(4).toString("hex")}.tmp`;
|
|
53
|
+
const fd = fs.openSync(tmpPath, "w", 384);
|
|
54
|
+
try {
|
|
55
|
+
fs.writeSync(fd, JSON.stringify(validated, null, 2) + "\n");
|
|
56
|
+
fs.fsyncSync(fd);
|
|
57
|
+
} finally {
|
|
58
|
+
fs.closeSync(fd);
|
|
59
|
+
}
|
|
60
|
+
try {
|
|
61
|
+
fs.renameSync(tmpPath, configPath);
|
|
62
|
+
} catch (err) {
|
|
63
|
+
try {
|
|
64
|
+
fs.unlinkSync(tmpPath);
|
|
65
|
+
} catch {
|
|
66
|
+
}
|
|
67
|
+
throw err;
|
|
68
|
+
}
|
|
69
|
+
if (process.platform !== "win32") {
|
|
70
|
+
try {
|
|
71
|
+
fs.chmodSync(dir, 448);
|
|
72
|
+
fs.chmodSync(configPath, 384);
|
|
73
|
+
} catch {
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function removeDashboardClientConfig(env = process.env) {
|
|
78
|
+
const configPath = dashboardClientConfigPath(env);
|
|
79
|
+
try {
|
|
80
|
+
fs.unlinkSync(configPath);
|
|
81
|
+
} catch (err) {
|
|
82
|
+
if (err.code !== "ENOENT") throw err;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function parseDashboardClientConfig(raw) {
|
|
86
|
+
if (typeof raw !== "object" || raw === null) {
|
|
87
|
+
throw new Error("dashboard config root must be an object");
|
|
88
|
+
}
|
|
89
|
+
const obj = raw;
|
|
90
|
+
const stringFields = [
|
|
91
|
+
"dashboardUrl",
|
|
92
|
+
"instanceId",
|
|
93
|
+
"refreshToken",
|
|
94
|
+
"fingerprint"
|
|
95
|
+
];
|
|
96
|
+
for (const key of stringFields) {
|
|
97
|
+
const value = obj[key];
|
|
98
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
99
|
+
throw new Error(`${key} must be a non-empty string`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (typeof obj["pairedAt"] !== "number") {
|
|
103
|
+
throw new Error("pairedAt must be a number");
|
|
104
|
+
}
|
|
105
|
+
if (obj["lastRefreshAt"] !== void 0 && typeof obj["lastRefreshAt"] !== "number") {
|
|
106
|
+
throw new Error("lastRefreshAt must be a number");
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
dashboardUrl: obj["dashboardUrl"],
|
|
110
|
+
instanceId: obj["instanceId"],
|
|
111
|
+
refreshToken: obj["refreshToken"],
|
|
112
|
+
fingerprint: obj["fingerprint"],
|
|
113
|
+
pairedAt: obj["pairedAt"],
|
|
114
|
+
...obj["lastRefreshAt"] !== void 0 ? { lastRefreshAt: obj["lastRefreshAt"] } : {}
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// src/gateway/paths.ts
|
|
119
|
+
import os2 from "os";
|
|
120
|
+
import path2 from "path";
|
|
4
121
|
var SUN_PATH_MAX = 104;
|
|
5
122
|
function resolveGatewayPaths(env = process.env) {
|
|
6
|
-
const home = env["HOME"] ??
|
|
123
|
+
const home = env["HOME"] ?? os2.homedir();
|
|
7
124
|
const xdg = env["XDG_RUNTIME_DIR"]?.trim();
|
|
8
|
-
const runDir = xdg && xdg.length > 0 ?
|
|
9
|
-
const configDir =
|
|
10
|
-
const socketPath =
|
|
11
|
-
const lockPath =
|
|
12
|
-
const tokenPath =
|
|
13
|
-
const statePath =
|
|
125
|
+
const runDir = xdg && xdg.length > 0 ? path2.join(xdg, "athena") : path2.join(home, ".config", "athena", "run");
|
|
126
|
+
const configDir = path2.join(home, ".config", "athena", "gateway");
|
|
127
|
+
const socketPath = path2.join(runDir, "gateway.sock");
|
|
128
|
+
const lockPath = path2.join(runDir, "gateway.lock");
|
|
129
|
+
const tokenPath = path2.join(configDir, "token");
|
|
130
|
+
const statePath = path2.join(configDir, "state.db");
|
|
14
131
|
if (Buffer.byteLength(socketPath, "utf-8") > SUN_PATH_MAX) {
|
|
15
132
|
throw new Error(
|
|
16
133
|
`Gateway socket path exceeds ${SUN_PATH_MAX} bytes (sun_path limit): ${socketPath}. Set XDG_RUNTIME_DIR to a shorter path or relocate $HOME.`
|
|
@@ -117,10 +234,10 @@ async function shutdownTelemetry() {
|
|
|
117
234
|
}
|
|
118
235
|
|
|
119
236
|
// src/infra/telemetry/events.ts
|
|
120
|
-
import
|
|
237
|
+
import os3 from "os";
|
|
121
238
|
function systemProps() {
|
|
122
239
|
return {
|
|
123
|
-
os: `${
|
|
240
|
+
os: `${os3.platform()}-${os3.arch()}`,
|
|
124
241
|
nodeVersion: process.version
|
|
125
242
|
};
|
|
126
243
|
}
|
|
@@ -134,7 +251,7 @@ function trackSessionEnded(props) {
|
|
|
134
251
|
capture("session.ended", props);
|
|
135
252
|
}
|
|
136
253
|
function sanitizeStackTrace(stack) {
|
|
137
|
-
const home =
|
|
254
|
+
const home = os3.homedir();
|
|
138
255
|
return stack.replaceAll(home, "~");
|
|
139
256
|
}
|
|
140
257
|
function trackError(props) {
|
|
@@ -170,7 +287,7 @@ function trackClaudeStartupFailed(props) {
|
|
|
170
287
|
const resolvedBinary = props.failureStage === "exit_nonzero" || props.failureStage === "startup_timeout" || classifiedReason !== "binary_not_found";
|
|
171
288
|
capture("claude.startup_failed", {
|
|
172
289
|
harness: props.harness,
|
|
173
|
-
platform: `${
|
|
290
|
+
platform: `${os3.platform()}-${os3.arch()}`,
|
|
174
291
|
failure_stage: props.failureStage,
|
|
175
292
|
resolved_binary: resolvedBinary,
|
|
176
293
|
exit_code: props.exitCode,
|
|
@@ -196,123 +313,6 @@ function trackSetupCompleted(props) {
|
|
|
196
313
|
capture("setup.completed", props);
|
|
197
314
|
}
|
|
198
315
|
|
|
199
|
-
// src/infra/config/dashboardClient.ts
|
|
200
|
-
import crypto from "crypto";
|
|
201
|
-
import fs from "fs";
|
|
202
|
-
import os3 from "os";
|
|
203
|
-
import path2 from "path";
|
|
204
|
-
function dashboardClientConfigPath(env = process.env) {
|
|
205
|
-
const home = env["HOME"] ?? os3.homedir();
|
|
206
|
-
return path2.join(home, ".config", "athena", "dashboard.json");
|
|
207
|
-
}
|
|
208
|
-
function normalizeDashboardUrl(input) {
|
|
209
|
-
let parsed;
|
|
210
|
-
try {
|
|
211
|
-
parsed = new URL(input);
|
|
212
|
-
} catch {
|
|
213
|
-
throw new Error("dashboard url must be a valid URL");
|
|
214
|
-
}
|
|
215
|
-
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
216
|
-
throw new Error("dashboard url must use http:// or https://");
|
|
217
|
-
}
|
|
218
|
-
return parsed.origin;
|
|
219
|
-
}
|
|
220
|
-
function readDashboardClientConfig(env = process.env) {
|
|
221
|
-
const configPath = dashboardClientConfigPath(env);
|
|
222
|
-
let raw;
|
|
223
|
-
try {
|
|
224
|
-
raw = fs.readFileSync(configPath, "utf-8");
|
|
225
|
-
} catch (err) {
|
|
226
|
-
if (err.code === "ENOENT") return null;
|
|
227
|
-
throw err;
|
|
228
|
-
}
|
|
229
|
-
let parsed;
|
|
230
|
-
try {
|
|
231
|
-
parsed = JSON.parse(raw);
|
|
232
|
-
} catch (err) {
|
|
233
|
-
throw new Error(
|
|
234
|
-
`dashboard client config ${configPath} is invalid JSON: ${err instanceof Error ? err.message : String(err)}`
|
|
235
|
-
);
|
|
236
|
-
}
|
|
237
|
-
try {
|
|
238
|
-
return parseDashboardClientConfig(parsed);
|
|
239
|
-
} catch (err) {
|
|
240
|
-
throw new Error(
|
|
241
|
-
`dashboard client config ${configPath} is invalid: ${err instanceof Error ? err.message : String(err)}`
|
|
242
|
-
);
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
function writeDashboardClientConfig(config, env = process.env) {
|
|
246
|
-
const validated = parseDashboardClientConfig(config);
|
|
247
|
-
const configPath = dashboardClientConfigPath(env);
|
|
248
|
-
const dir = path2.dirname(configPath);
|
|
249
|
-
fs.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
250
|
-
const tmpPath = `${configPath}.${process.pid}.${crypto.randomBytes(4).toString("hex")}.tmp`;
|
|
251
|
-
const fd = fs.openSync(tmpPath, "w", 384);
|
|
252
|
-
try {
|
|
253
|
-
fs.writeSync(fd, JSON.stringify(validated, null, 2) + "\n");
|
|
254
|
-
fs.fsyncSync(fd);
|
|
255
|
-
} finally {
|
|
256
|
-
fs.closeSync(fd);
|
|
257
|
-
}
|
|
258
|
-
try {
|
|
259
|
-
fs.renameSync(tmpPath, configPath);
|
|
260
|
-
} catch (err) {
|
|
261
|
-
try {
|
|
262
|
-
fs.unlinkSync(tmpPath);
|
|
263
|
-
} catch {
|
|
264
|
-
}
|
|
265
|
-
throw err;
|
|
266
|
-
}
|
|
267
|
-
if (process.platform !== "win32") {
|
|
268
|
-
try {
|
|
269
|
-
fs.chmodSync(dir, 448);
|
|
270
|
-
fs.chmodSync(configPath, 384);
|
|
271
|
-
} catch {
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
function removeDashboardClientConfig(env = process.env) {
|
|
276
|
-
const configPath = dashboardClientConfigPath(env);
|
|
277
|
-
try {
|
|
278
|
-
fs.unlinkSync(configPath);
|
|
279
|
-
} catch (err) {
|
|
280
|
-
if (err.code !== "ENOENT") throw err;
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
function parseDashboardClientConfig(raw) {
|
|
284
|
-
if (typeof raw !== "object" || raw === null) {
|
|
285
|
-
throw new Error("dashboard config root must be an object");
|
|
286
|
-
}
|
|
287
|
-
const obj = raw;
|
|
288
|
-
const stringFields = [
|
|
289
|
-
"dashboardUrl",
|
|
290
|
-
"instanceId",
|
|
291
|
-
"refreshToken",
|
|
292
|
-
"fingerprint"
|
|
293
|
-
];
|
|
294
|
-
for (const key of stringFields) {
|
|
295
|
-
const value = obj[key];
|
|
296
|
-
if (typeof value !== "string" || value.length === 0) {
|
|
297
|
-
throw new Error(`${key} must be a non-empty string`);
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
if (typeof obj["pairedAt"] !== "number") {
|
|
301
|
-
throw new Error("pairedAt must be a number");
|
|
302
|
-
}
|
|
303
|
-
if (obj["lastRefreshAt"] !== void 0 && typeof obj["lastRefreshAt"] !== "number") {
|
|
304
|
-
throw new Error("lastRefreshAt must be a number");
|
|
305
|
-
}
|
|
306
|
-
return {
|
|
307
|
-
dashboardUrl: obj["dashboardUrl"],
|
|
308
|
-
instanceId: obj["instanceId"],
|
|
309
|
-
refreshToken: obj["refreshToken"],
|
|
310
|
-
fingerprint: obj["fingerprint"],
|
|
311
|
-
pairedAt: obj["pairedAt"],
|
|
312
|
-
...obj["lastRefreshAt"] !== void 0 ? { lastRefreshAt: obj["lastRefreshAt"] } : {}
|
|
313
|
-
};
|
|
314
|
-
}
|
|
315
|
-
|
|
316
316
|
// src/infra/config/dashboardAuth.ts
|
|
317
317
|
import fs2 from "fs";
|
|
318
318
|
var DEFAULT_LOCK_TIMEOUT_MS = 3e4;
|
|
@@ -739,6 +739,11 @@ function isValidChannelRequestId(value) {
|
|
|
739
739
|
|
|
740
740
|
export {
|
|
741
741
|
writeGatewayTrace,
|
|
742
|
+
dashboardClientConfigPath,
|
|
743
|
+
normalizeDashboardUrl,
|
|
744
|
+
readDashboardClientConfig,
|
|
745
|
+
writeDashboardClientConfig,
|
|
746
|
+
removeDashboardClientConfig,
|
|
742
747
|
TransportUnreachableError,
|
|
743
748
|
traceGatewayFrame,
|
|
744
749
|
createUdsServerTransport,
|
|
@@ -765,11 +770,6 @@ export {
|
|
|
765
770
|
trackGatewayRuntimeRebind,
|
|
766
771
|
trackGatewayRuntimeExpired,
|
|
767
772
|
trackSetupCompleted,
|
|
768
|
-
dashboardClientConfigPath,
|
|
769
|
-
normalizeDashboardUrl,
|
|
770
|
-
readDashboardClientConfig,
|
|
771
|
-
writeDashboardClientConfig,
|
|
772
|
-
removeDashboardClientConfig,
|
|
773
773
|
refreshDashboardAccessToken
|
|
774
774
|
};
|
|
775
|
-
//# sourceMappingURL=chunk-
|
|
775
|
+
//# sourceMappingURL=chunk-BTY7MYYT.js.map
|