@linkedclaw/cli 0.1.0 → 0.1.1

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/bin.js CHANGED
@@ -3878,7 +3878,7 @@ function withTimeout(p, ms, code) {
3878
3878
  function escapeRegex(s) {
3879
3879
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
3880
3880
  }
3881
- var LinkedClawError, NetworkError, ApiError, ConfigError, HandlerError, CloudClient, RequesterFlows, TOOL_CALL_PATTERNS, SYSTEM_PATTERNS, DEFAULT_OUTPUT_PATTERNS, DEFAULT_STRIP_PATTERNS, DEFAULT_CLOUD_URL, DEFAULT_RELAY_URL, MessageType, RelayClient, nodeWsConnector, DEFAULT_INVOKE_TIMEOUT_MS, DEFAULT_SESSION_TURN_TIMEOUT_MS, DEFAULT_BROADCAST_OFFER_TIMEOUT_MS, DEFAULT_BROADCAST_EXECUTE_TIMEOUT_MS, BROADCAST_SUBMIT_MAX_RETRIES, BROADCAST_SUBMIT_BASE_MS, BROADCAST_SUBMIT_CAP_MS, ProviderRuntime, CORE_VERSION;
3881
+ var LinkedClawError, NetworkError, ApiError, ConfigError, HandlerError, CloudClient, RequesterFlows, TOOL_CALL_PATTERNS, SYSTEM_PATTERNS, DEFAULT_OUTPUT_PATTERNS, DEFAULT_STRIP_PATTERNS, DEFAULT_CLOUD_URL, DEFAULT_RELAY_URL, MessageType, DEFAULT_AUTH_FAILURE_CODES, RelayClient, nodeWsConnector, DEFAULT_INVOKE_TIMEOUT_MS, DEFAULT_SESSION_TURN_TIMEOUT_MS, DEFAULT_BROADCAST_OFFER_TIMEOUT_MS, DEFAULT_BROADCAST_EXECUTE_TIMEOUT_MS, BROADCAST_SUBMIT_MAX_RETRIES, BROADCAST_SUBMIT_BASE_MS, BROADCAST_SUBMIT_CAP_MS, ProviderRuntime, CORE_VERSION;
3882
3882
  var init_dist = __esm({
3883
3883
  "../core/dist/index.js"() {
3884
3884
  "use strict";
@@ -4144,6 +4144,10 @@ var init_dist = __esm({
4144
4144
  INVOKE: "invoke",
4145
4145
  INVOKE_RESULT: "invoke_result"
4146
4146
  };
4147
+ DEFAULT_AUTH_FAILURE_CODES = Object.freeze([
4148
+ 1008,
4149
+ ...Array.from({ length: 99 }, (_, i) => 4001 + i)
4150
+ ]);
4147
4151
  RelayClient = class extends EventEmitter {
4148
4152
  url;
4149
4153
  agentId;
@@ -4152,11 +4156,15 @@ var init_dist = __esm({
4152
4156
  heartbeatMs;
4153
4157
  reconnectBaseMs;
4154
4158
  reconnectMaxMs;
4159
+ authGraceMs;
4160
+ authFailureCloseCodes;
4155
4161
  connector;
4156
4162
  transport;
4157
4163
  heartbeatTimer;
4164
+ authGraceTimer;
4158
4165
  stopped = false;
4159
4166
  reconnectAttempt = 0;
4167
+ fatalState = null;
4160
4168
  constructor(opts) {
4161
4169
  super();
4162
4170
  this.url = opts.url;
@@ -4166,8 +4174,16 @@ var init_dist = __esm({
4166
4174
  this.heartbeatMs = opts.heartbeatMs ?? 3e4;
4167
4175
  this.reconnectBaseMs = opts.reconnectBaseMs ?? 1e3;
4168
4176
  this.reconnectMaxMs = opts.reconnectMaxMs ?? 3e4;
4177
+ this.authGraceMs = opts.authGraceMs ?? 5e3;
4178
+ this.authFailureCloseCodes = new Set(
4179
+ opts.authFailureCloseCodes ?? DEFAULT_AUTH_FAILURE_CODES
4180
+ );
4169
4181
  this.connector = opts.connector ?? nodeWsConnector;
4170
4182
  }
4183
+ /** Last detected permanent-auth-failure, or null when OK / still retrying. */
4184
+ getFatal() {
4185
+ return this.fatalState;
4186
+ }
4171
4187
  on(event, listener) {
4172
4188
  return super.on(event, listener);
4173
4189
  }
@@ -4183,13 +4199,15 @@ var init_dist = __esm({
4183
4199
  const { transport, ready } = await this.connector(this.url);
4184
4200
  this.transport = transport;
4185
4201
  transport.addMessageListener((data) => this.handleFrame(data));
4186
- transport.addCloseListener((code, reason) => this.handleClose(`close ${code}: ${reason}`));
4187
- transport.addErrorListener((err) => this.handleClose(`error: ${err.message}`));
4202
+ transport.addCloseListener(
4203
+ (code, reason) => this.handleClose(code, `close ${code}: ${reason}`)
4204
+ );
4205
+ transport.addErrorListener((err) => this.handleClose(null, `error: ${err.message}`));
4188
4206
  await ready;
4189
4207
  await this.sendIdentify();
4190
4208
  this.startHeartbeat();
4191
- this.reconnectAttempt = 0;
4192
4209
  this.emit("connected");
4210
+ this.startAuthGraceTimer();
4193
4211
  } catch (err) {
4194
4212
  throw new NetworkError(`relay connect failed: ${err.message}`, err);
4195
4213
  }
@@ -4201,6 +4219,7 @@ var init_dist = __esm({
4201
4219
  async stop() {
4202
4220
  this.stopped = true;
4203
4221
  this.stopHeartbeat();
4222
+ this.cancelAuthGraceTimer();
4204
4223
  if (this.transport) {
4205
4224
  try {
4206
4225
  await this.transport.close(1e3, "client_stop");
@@ -4248,11 +4267,39 @@ var init_dist = __esm({
4248
4267
  const evt = parseInbound(frame);
4249
4268
  if (evt) this.emit("event", evt);
4250
4269
  }
4251
- handleClose(reason) {
4270
+ handleClose(code, reason) {
4252
4271
  this.stopHeartbeat();
4272
+ this.cancelAuthGraceTimer();
4253
4273
  this.transport = void 0;
4254
4274
  this.emit("disconnected", reason);
4255
- if (!this.stopped) void this.scheduleReconnect();
4275
+ if (this.stopped) return;
4276
+ if (code !== null && this.authFailureCloseCodes.has(code)) {
4277
+ this.stopped = true;
4278
+ this.fatalState = { reason, code };
4279
+ this.emit("fatal", { reason, code });
4280
+ return;
4281
+ }
4282
+ void this.scheduleReconnect();
4283
+ }
4284
+ startAuthGraceTimer() {
4285
+ this.cancelAuthGraceTimer();
4286
+ if (this.authGraceMs <= 0) {
4287
+ this.reconnectAttempt = 0;
4288
+ return;
4289
+ }
4290
+ this.authGraceTimer = setTimeout(() => {
4291
+ this.authGraceTimer = void 0;
4292
+ if (this.transport) this.reconnectAttempt = 0;
4293
+ }, this.authGraceMs);
4294
+ if (typeof this.authGraceTimer.unref === "function") {
4295
+ this.authGraceTimer.unref();
4296
+ }
4297
+ }
4298
+ cancelAuthGraceTimer() {
4299
+ if (this.authGraceTimer) {
4300
+ clearTimeout(this.authGraceTimer);
4301
+ this.authGraceTimer = void 0;
4302
+ }
4256
4303
  }
4257
4304
  async scheduleReconnect() {
4258
4305
  this.reconnectAttempt += 1;
@@ -4320,6 +4367,7 @@ var init_dist = __esm({
4320
4367
  inFlightBroadcasts = /* @__PURE__ */ new Set();
4321
4368
  running = false;
4322
4369
  connected = false;
4370
+ fatal = null;
4323
4371
  constructor(deps) {
4324
4372
  this.cloud = deps.cloud;
4325
4373
  this.relay = deps.relay;
@@ -4331,10 +4379,18 @@ var init_dist = __esm({
4331
4379
  this.running = true;
4332
4380
  this.relay.on("connected", () => {
4333
4381
  this.connected = true;
4382
+ this.fatal = null;
4334
4383
  });
4335
4384
  this.relay.on("disconnected", () => {
4336
4385
  this.connected = false;
4337
4386
  });
4387
+ this.relay.on("fatal", (info) => {
4388
+ this.fatal = info;
4389
+ this.connected = false;
4390
+ console.error(
4391
+ `linkedclaw: relay rejected our credentials (code=${info.code ?? "?"}: ${info.reason}). Not retrying. Check apiKey/agentId and restart the plugin.`
4392
+ );
4393
+ });
4338
4394
  this.relay.on("event", (evt) => {
4339
4395
  void this.dispatch(evt);
4340
4396
  });
@@ -4351,7 +4407,8 @@ var init_dist = __esm({
4351
4407
  activeSessions: this.activeSessions.size,
4352
4408
  inFlightInvokes: this.inFlightInvokes.size,
4353
4409
  inFlightBroadcasts: this.inFlightBroadcasts.size,
4354
- ...this.config.agentId !== void 0 ? { agentId: this.config.agentId } : {}
4410
+ ...this.config.agentId !== void 0 ? { agentId: this.config.agentId } : {},
4411
+ ...this.fatal !== null ? { fatal: this.fatal } : {}
4355
4412
  };
4356
4413
  }
4357
4414
  // ────────── dispatch ──────────