@drisp/cli 0.5.24 → 0.5.26

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.
@@ -8,7 +8,7 @@ import {
8
8
  installWorkflowPlugins,
9
9
  resolveWorkflow,
10
10
  writeGlobalConfig
11
- } from "./chunk-7UUPLAP4.js";
11
+ } from "./chunk-73V7GXV6.js";
12
12
 
13
13
  // src/setup/steps/WorkflowInstallWizard.tsx
14
14
  import { useState, useEffect, useCallback, useRef } from "react";
@@ -92,4 +92,4 @@ function WorkflowInstallWizard({ source, onDone }) {
92
92
  export {
93
93
  WorkflowInstallWizard as default
94
94
  };
95
- //# sourceMappingURL=WorkflowInstallWizard-IMU47QWB.js.map
95
+ //# sourceMappingURL=WorkflowInstallWizard-5FENJHBW.js.map
@@ -3,10 +3,11 @@ import {
3
3
  loadOrCreateToken,
4
4
  requireTokenForBind,
5
5
  timingSafeTokenEqual
6
- } from "./chunk-7GEQJQMR.js";
6
+ } from "./chunk-4NX4WFPB.js";
7
7
  import {
8
8
  CHANNEL_REQUEST_ID_REGEX,
9
9
  createUdsServerTransport,
10
+ createWsServerTransport,
10
11
  generateChannelRequestId,
11
12
  isLoopbackHost,
12
13
  isValidChannelRequestId,
@@ -14,13 +15,12 @@ import {
14
15
  refreshDashboardAccessToken,
15
16
  resolveGatewayPaths,
16
17
  resolveListenSpec,
17
- traceGatewayFrame,
18
18
  trackGatewayRuntimeExpired,
19
19
  trackGatewayRuntimeRebind,
20
20
  trackGatewayTransportConnect,
21
21
  trackGatewayTransportDisconnect,
22
22
  writeGatewayTrace
23
- } from "./chunk-YU2WMPRC.js";
23
+ } from "./chunk-3U37HT4T.js";
24
24
 
25
25
  // src/gateway/daemon.ts
26
26
  import fs4 from "fs";
@@ -2441,7 +2441,7 @@ var cachedVersion = null;
2441
2441
  function readVersion() {
2442
2442
  if (cachedVersion !== null) return cachedVersion;
2443
2443
  try {
2444
- const injected = "0.5.24";
2444
+ const injected = "0.5.26";
2445
2445
  if (typeof injected === "string" && injected.length > 0) {
2446
2446
  cachedVersion = injected;
2447
2447
  return cachedVersion;
@@ -3464,6 +3464,33 @@ var DispatchPipeline = class {
3464
3464
  }
3465
3465
  };
3466
3466
 
3467
+ // src/gateway/listenerPlan.ts
3468
+ function planListener(spec, token) {
3469
+ requireTokenForBind(spec, token);
3470
+ if (spec.kind === "uds") {
3471
+ return {
3472
+ transport: { kind: "uds", socketPath: spec.socketPath },
3473
+ warnings: []
3474
+ };
3475
+ }
3476
+ const warnings = [];
3477
+ if (spec.insecure && !spec.tls && !isLoopbackHost(spec.host)) {
3478
+ warnings.push(
3479
+ `athena-gateway: WARNING --insecure is set on a non-loopback bind (${spec.host}:${spec.port}); token travels in plaintext. Use only behind TLS-terminating reverse proxy or Tailscale/WireGuard tunnel.`
3480
+ );
3481
+ }
3482
+ return {
3483
+ transport: {
3484
+ kind: "tcp",
3485
+ host: spec.host,
3486
+ port: spec.port,
3487
+ allowNonLoopback: spec.insecure || Boolean(spec.tls),
3488
+ ...spec.tls ? { tls: spec.tls } : {}
3489
+ },
3490
+ warnings
3491
+ };
3492
+ }
3493
+
3467
3494
  // src/gateway/lock.ts
3468
3495
  import fs2 from "fs";
3469
3496
  import path2 from "path";
@@ -3824,221 +3851,19 @@ function openGatewayState(dbPath) {
3824
3851
  return db;
3825
3852
  }
3826
3853
 
3827
- // src/gateway/transport/tlsWs.ts
3828
- import { WebSocketServer } from "ws";
3829
- import { createServer as createHttpsServer } from "https";
3830
- import { readFileSync as readFileSync3 } from "fs";
3831
- function createWsServerTransport(opts) {
3832
- if (!opts.allowNonLoopback && !isLoopbackHost(opts.host)) {
3833
- throw new Error(`gateway: refusing non-loopback bind without --insecure`);
3834
- }
3835
- let endpoint = null;
3836
- const scheme = opts.tls ? "wss" : "ws";
3837
- const rateLimit = createConnectRateLimiter(opts.rateLimitPerMin ?? 10);
3838
- return {
3839
- kind: "ws",
3840
- endpoint: () => {
3841
- if (!endpoint) {
3842
- throw new Error("gateway: WS transport has not started listening");
3843
- }
3844
- return endpoint;
3845
- },
3846
- listen: (onConnection) => new Promise((resolve, reject) => {
3847
- const verifyClient = (info) => rateLimit.allow(info.req.socket.remoteAddress ?? "unknown");
3848
- const { wss, httpsServer } = createWss({
3849
- host: opts.host,
3850
- port: opts.port,
3851
- tls: opts.tls,
3852
- verifyClient
3853
- });
3854
- const onError = (err) => reject(err);
3855
- wss.once("error", onError);
3856
- if (httpsServer) httpsServer.once("error", onError);
3857
- const onListening = () => {
3858
- wss.off("error", onError);
3859
- if (httpsServer) httpsServer.off("error", onError);
3860
- const addr = httpsServer ? httpsServer.address() : wss.address();
3861
- if (typeof addr === "string" || addr === null) {
3862
- wss.close();
3863
- httpsServer?.close();
3864
- reject(
3865
- new Error("gateway: WS listener did not expose TCP address")
3866
- );
3867
- return;
3868
- }
3869
- endpoint = {
3870
- host: opts.host,
3871
- port: addr.port,
3872
- url: `${scheme}://${opts.host}:${addr.port}`
3873
- };
3874
- resolve({
3875
- close: () => new Promise((closeResolve) => {
3876
- for (const client of wss.clients) client.terminate();
3877
- wss.close(() => {
3878
- if (httpsServer) httpsServer.close(() => closeResolve());
3879
- else closeResolve();
3880
- });
3881
- })
3882
- });
3883
- };
3884
- if (httpsServer) httpsServer.once("listening", onListening);
3885
- else wss.once("listening", onListening);
3886
- const pingIntervalMs = opts.pingIntervalMs ?? 15e3;
3887
- const pongTimeoutMs = opts.pongTimeoutMs ?? 3e4;
3888
- wss.on("connection", (ws) => {
3889
- attachHeartbeat(ws, pingIntervalMs, pongTimeoutMs);
3890
- onConnection(createWsConnection(ws, `${scheme}:${opts.host}`));
3891
- });
3892
- })
3893
- };
3894
- }
3895
- function loadTlsOptions(tls) {
3896
- return {
3897
- cert: readFileSync3(tls.certPath),
3898
- key: readFileSync3(tls.keyPath)
3899
- };
3900
- }
3901
- function createWss(input) {
3902
- if (input.tls) {
3903
- const httpsServer = createHttpsServer(loadTlsOptions(input.tls));
3904
- httpsServer.listen({ host: input.host, port: input.port });
3905
- return {
3906
- wss: new WebSocketServer({
3907
- server: httpsServer,
3908
- verifyClient: input.verifyClient
3909
- }),
3910
- httpsServer
3911
- };
3912
- }
3913
- return {
3914
- wss: new WebSocketServer({
3915
- host: input.host,
3916
- port: input.port,
3917
- verifyClient: input.verifyClient
3918
- }),
3919
- httpsServer: null
3920
- };
3921
- }
3922
- function createConnectRateLimiter(maxPerMin) {
3923
- if (maxPerMin <= 0) return { allow: () => true };
3924
- const buckets = /* @__PURE__ */ new Map();
3925
- let pruneCountdown = 256;
3926
- const prune = (cutoff) => {
3927
- for (const [ip, arr] of buckets) {
3928
- const fresh = arr.filter((t) => t > cutoff);
3929
- if (fresh.length === 0) buckets.delete(ip);
3930
- else if (fresh.length !== arr.length) buckets.set(ip, fresh);
3931
- }
3932
- };
3933
- return {
3934
- allow(ip) {
3935
- const now = Date.now();
3936
- const cutoff = now - 6e4;
3937
- pruneCountdown -= 1;
3938
- if (pruneCountdown <= 0) {
3939
- prune(cutoff);
3940
- pruneCountdown = 256;
3941
- }
3942
- const recent = (buckets.get(ip) ?? []).filter((t) => t > cutoff);
3943
- if (recent.length >= maxPerMin) {
3944
- buckets.set(ip, recent);
3945
- return false;
3946
- }
3947
- recent.push(now);
3948
- buckets.set(ip, recent);
3949
- return true;
3950
- }
3951
- };
3952
- }
3953
- function attachHeartbeat(ws, pingIntervalMs, pongTimeoutMs) {
3954
- if (pingIntervalMs <= 0) return;
3955
- let pongTimer = null;
3956
- const clearPongTimer = () => {
3957
- if (pongTimer) {
3958
- clearTimeout(pongTimer);
3959
- pongTimer = null;
3960
- }
3961
- };
3962
- ws.on("pong", clearPongTimer);
3963
- const interval = setInterval(() => {
3964
- if (ws.readyState !== ws.OPEN) return;
3965
- try {
3966
- ws.ping();
3967
- } catch {
3968
- return;
3969
- }
3970
- if (!pongTimer) {
3971
- pongTimer = setTimeout(() => ws.terminate(), pongTimeoutMs);
3972
- }
3973
- }, pingIntervalMs);
3974
- const stop = () => {
3975
- clearInterval(interval);
3976
- clearPongTimer();
3977
- };
3978
- ws.on("close", stop);
3979
- ws.on("error", stop);
3980
- }
3981
- function createWsConnection(ws, peer) {
3982
- const frameHandlers = /* @__PURE__ */ new Set();
3983
- const closeHandlers = /* @__PURE__ */ new Set();
3984
- const errorHandlers = /* @__PURE__ */ new Set();
3985
- ws.on("message", (data) => {
3986
- let parsed;
3987
- try {
3988
- parsed = JSON.parse(data.toString());
3989
- } catch {
3990
- ws.close();
3991
- return;
3992
- }
3993
- traceGatewayFrame("ws", peer, "in", parsed);
3994
- for (const handler of frameHandlers) handler(parsed);
3995
- });
3996
- ws.on("error", (err) => {
3997
- for (const handler of errorHandlers) handler(err);
3998
- });
3999
- ws.on("close", () => {
4000
- for (const handler of closeHandlers) handler();
4001
- });
4002
- return {
4003
- kind: "ws",
4004
- peer,
4005
- send: (frame) => {
4006
- if (ws.readyState !== ws.OPEN) return;
4007
- traceGatewayFrame("ws", peer, "out", frame);
4008
- ws.send(JSON.stringify(frame));
4009
- },
4010
- close: () => ws.close(),
4011
- onFrame: (cb) => {
4012
- frameHandlers.add(cb);
4013
- return () => frameHandlers.delete(cb);
4014
- },
4015
- onClose: (cb) => {
4016
- closeHandlers.add(cb);
4017
- return () => closeHandlers.delete(cb);
4018
- },
4019
- onError: (cb) => {
4020
- errorHandlers.add(cb);
4021
- return () => errorHandlers.delete(cb);
4022
- }
4023
- };
4024
- }
4025
-
4026
3854
  // src/gateway/daemon.ts
4027
- function buildListenerStatus(spec, resolvedPort) {
4028
- if (spec.kind === "uds") {
4029
- return { kind: "uds", socketPath: spec.socketPath };
3855
+ function describeToStatus(desc, spec) {
3856
+ if (desc.kind === "uds") {
3857
+ return { kind: "uds", socketPath: desc.socketPath };
4030
3858
  }
4031
- const port = resolvedPort ?? spec.port;
4032
- const tls = Boolean(spec.tls);
4033
- const scheme = tls ? "wss" : "ws";
4034
3859
  return {
4035
3860
  kind: "tcp",
4036
- host: spec.host,
4037
- port,
4038
- url: `${scheme}://${spec.host}:${port}`,
4039
- tls,
4040
- insecure: spec.insecure,
4041
- loopback: isLoopbackHost(spec.host)
3861
+ host: desc.host,
3862
+ port: desc.port,
3863
+ url: desc.url,
3864
+ tls: desc.tls,
3865
+ insecure: spec.kind === "tcp" ? spec.insecure : false,
3866
+ loopback: isLoopbackHost(desc.host)
4042
3867
  };
4043
3868
  }
4044
3869
  async function startDaemon(opts) {
@@ -4057,7 +3882,7 @@ async function startDaemon(opts) {
4057
3882
  const lock = acquireLock(paths.lockPath);
4058
3883
  const token = loadOrCreateToken(paths.tokenPath);
4059
3884
  const listenSpec = opts.listenSpec ?? resolveListenSpec({ paths });
4060
- requireTokenForBind(listenSpec, token);
3885
+ const listenerPlan = planListener(listenSpec, token);
4061
3886
  const listenerHints = {
4062
3887
  transport: listenSpec.kind === "tcp" ? "ws" : "uds",
4063
3888
  tls: listenSpec.kind === "tcp" && Boolean(listenSpec.tls),
@@ -4109,29 +3934,31 @@ async function startDaemon(opts) {
4109
3934
  logRegistrations: !opts.silent
4110
3935
  });
4111
3936
  }
3937
+ let transport;
4112
3938
  const handler = createDispatcher({
4113
3939
  startedAt,
4114
3940
  pipeline,
4115
3941
  channelManager,
4116
3942
  relayCoordinator,
4117
- getListener: () => listenerStatus ?? buildListenerStatus(listenSpec, null),
3943
+ getListener: () => listenerStatus ?? describeToStatus(transport.describe(), listenSpec),
4118
3944
  reloadChannels
4119
3945
  });
4120
3946
  let server;
4121
3947
  let listener;
4122
3948
  try {
4123
- const transport = listenSpec.kind === "tcp" ? createWsServerTransport({
4124
- host: listenSpec.host,
4125
- port: listenSpec.port,
4126
- allowNonLoopback: listenSpec.insecure || Boolean(listenSpec.tls),
4127
- ...listenSpec.tls ? { tls: listenSpec.tls } : {}
4128
- }) : void 0;
3949
+ const tcpPlan = listenerPlan.transport.kind === "tcp" ? listenerPlan.transport : null;
3950
+ transport = tcpPlan ? createWsServerTransport({
3951
+ host: tcpPlan.host,
3952
+ port: tcpPlan.port,
3953
+ allowNonLoopback: tcpPlan.allowNonLoopback,
3954
+ ...tcpPlan.tls ? { tls: tcpPlan.tls } : {}
3955
+ }) : createUdsServerTransport({ socketPath: paths.socketPath });
4129
3956
  server = await startControlServer({
4130
3957
  socketPath: paths.socketPath,
4131
3958
  token,
4132
3959
  startedAt,
4133
3960
  handler,
4134
- ...transport !== void 0 ? { transport } : {},
3961
+ transport,
4135
3962
  onConnect: (ctx) => {
4136
3963
  connectionOpenedAt.set(ctx.connectionId, Date.now());
4137
3964
  trackGatewayTransportConnect({
@@ -4152,19 +3979,14 @@ async function startDaemon(opts) {
4152
3979
  pipeline.notifyConnectionClosed(ctx.connectionId);
4153
3980
  }
4154
3981
  });
4155
- if (listenSpec.kind === "tcp") {
4156
- const endpoint = transport.endpoint();
4157
- listener = {
4158
- kind: "tcp",
4159
- host: endpoint.host,
4160
- port: endpoint.port,
4161
- url: endpoint.url
4162
- };
4163
- listenerStatus = buildListenerStatus(listenSpec, endpoint.port);
4164
- } else {
4165
- listener = { kind: "uds", socketPath: listenSpec.socketPath };
4166
- listenerStatus = buildListenerStatus(listenSpec, null);
4167
- }
3982
+ const description = transport.describe();
3983
+ listenerStatus = describeToStatus(description, listenSpec);
3984
+ listener = description.kind === "uds" ? { kind: "uds", socketPath: description.socketPath } : {
3985
+ kind: "tcp",
3986
+ host: description.host,
3987
+ port: description.port,
3988
+ url: description.url
3989
+ };
4168
3990
  } catch (err) {
4169
3991
  lock.release();
4170
3992
  throw err;
@@ -4174,11 +3996,8 @@ async function startDaemon(opts) {
4174
3996
  process.stdout.write(`athena-gateway: ok pid=${pid} ${target}
4175
3997
  `);
4176
3998
  }
4177
- if (listenSpec.kind === "tcp" && listenSpec.insecure && !listenSpec.tls && !isLoopbackHost(listenSpec.host)) {
4178
- process.stderr.write(
4179
- `athena-gateway: WARNING --insecure is set on a non-loopback bind (${listenSpec.host}:${listenSpec.port}); token travels in plaintext. Use only behind TLS-terminating reverse proxy or Tailscale/WireGuard tunnel.
4180
- `
4181
- );
3999
+ for (const warning of listenerPlan.warnings) {
4000
+ process.stderr.write(warning + "\n");
4182
4001
  }
4183
4002
  let stopping = false;
4184
4003
  const stop = async () => {