@drisp/cli 0.4.4 → 0.4.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.
@@ -1,16 +1,133 @@
1
- // src/gateway/paths.ts
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"] ?? os.homedir();
123
+ const home = env["HOME"] ?? os2.homedir();
7
124
  const xdg = env["XDG_RUNTIME_DIR"]?.trim();
8
- const runDir = xdg && xdg.length > 0 ? path.join(xdg, "athena") : path.join(home, ".config", "athena", "run");
9
- const configDir = path.join(home, ".config", "athena", "gateway");
10
- const socketPath = path.join(runDir, "gateway.sock");
11
- const lockPath = path.join(runDir, "gateway.lock");
12
- const tokenPath = path.join(configDir, "token");
13
- const statePath = path.join(configDir, "state.db");
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.`
@@ -53,7 +170,7 @@ function isLoopbackHost(host) {
53
170
 
54
171
  // src/infra/telemetry/client.ts
55
172
  import { PostHog } from "posthog-node";
56
- var POSTHOG_API_KEY = true ? "" : "";
173
+ var POSTHOG_API_KEY = true ? "phc_4UifMvZlZcJdgf3uDqzgEdIlQt98yAeUqVX5tobJcuD\n" : "";
57
174
  var POSTHOG_HOST = "https://us.i.posthog.com";
58
175
  var client = null;
59
176
  var deviceId = null;
@@ -117,10 +234,10 @@ async function shutdownTelemetry() {
117
234
  }
118
235
 
119
236
  // src/infra/telemetry/events.ts
120
- import os2 from "os";
237
+ import os3 from "os";
121
238
  function systemProps() {
122
239
  return {
123
- os: `${os2.platform()}-${os2.arch()}`,
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 = os2.homedir();
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: `${os2.platform()}-${os2.arch()}`,
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-4CRZXLIP.js.map
775
+ //# sourceMappingURL=chunk-WRHKXH5M.js.map