@inteeka/task-cli 0.2.20 → 0.2.22

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/cli.js CHANGED
@@ -3232,6 +3232,15 @@ async function jsonRequest(url, init) {
3232
3232
  return { ok: true, status: res.statusCode, data: env?.data ?? body, nonce: nonceStr };
3233
3233
  }
3234
3234
  const errBody = body;
3235
+ if (res.statusCode === 401 || res.statusCode === 403) {
3236
+ const reqId = errBody?.error?.request_id ?? "";
3237
+ const code = errBody?.error?.code ?? `HTTP_${res.statusCode}`;
3238
+ const msg = errBody?.error?.message ?? "(no message)";
3239
+ process.stderr.write(
3240
+ `[scan/api] ${res.statusCode} on ${url} \u2014 code=${code} request_id=${reqId} message=${msg}
3241
+ `
3242
+ );
3243
+ }
3235
3244
  return {
3236
3245
  ok: false,
3237
3246
  status: res.statusCode,
@@ -3239,18 +3248,48 @@ async function jsonRequest(url, init) {
3239
3248
  message: errBody?.error?.message ?? `Request failed with status ${res.statusCode}`
3240
3249
  };
3241
3250
  }
3251
+ var FRESH_CRED_CACHE_MS = 5e3;
3242
3252
  var AutopilotApi = class {
3243
- creds;
3253
+ /**
3254
+ * @deprecated retained only to satisfy the constructor signature for
3255
+ * callers passing an initial snapshot. NEVER read this in any method —
3256
+ * always go through `getFreshCreds()` so an on-disk rotation triggered
3257
+ * by the listener heartbeat or another CLI process during a long-running
3258
+ * scan is observed before the next user-bearer call.
3259
+ */
3260
+ initialCreds;
3261
+ cachedCreds = null;
3262
+ cachedAt = 0;
3244
3263
  constructor(opts) {
3245
- this.creds = opts.creds;
3264
+ this.initialCreds = opts.creds;
3265
+ this.cachedCreds = opts.creds;
3266
+ this.cachedAt = Date.now();
3246
3267
  this.apiUrl = opts.apiUrl;
3247
3268
  }
3248
3269
  apiUrl;
3270
+ /**
3271
+ * Returns a credentials object that's been re-read from disk (and
3272
+ * refreshed via the file-locked HTTP path if expired) within the last
3273
+ * FRESH_CRED_CACHE_MS. Replaces the previous "cached at construction
3274
+ * time" model which produced UNAUTHORIZED 401s mid-scan when the
3275
+ * listener heartbeat rotated the on-disk pair under us.
3276
+ */
3277
+ async getFreshCreds() {
3278
+ if (this.cachedCreds && Date.now() - this.cachedAt < FRESH_CRED_CACHE_MS) {
3279
+ return this.cachedCreds;
3280
+ }
3281
+ const onDisk = await readCredentials();
3282
+ const base = onDisk ?? this.cachedCreds ?? this.initialCreds;
3283
+ const fresh = await ensureFreshAccessToken(base);
3284
+ this.cachedCreds = fresh;
3285
+ this.cachedAt = Date.now();
3286
+ return fresh;
3287
+ }
3249
3288
  async userHeaders() {
3250
- this.creds = await ensureFreshAccessToken(this.creds);
3289
+ const creds = await this.getFreshCreds();
3251
3290
  return {
3252
3291
  "Content-Type": "application/json",
3253
- Authorization: `Bearer ${this.creds.access_token}`,
3292
+ Authorization: `Bearer ${creds.access_token}`,
3254
3293
  "User-Agent": "task-cli/scan"
3255
3294
  };
3256
3295
  }
@@ -3842,6 +3881,7 @@ ${c.bold(`${project.organisation_slug}/${project.project_slug}`)} ${c.dim(`(${pr
3842
3881
  let fatal = null;
3843
3882
  try {
3844
3883
  while (!args.isInterrupted()) {
3884
+ if (agg.submitted >= maxSubmits) break;
3845
3885
  let prepared;
3846
3886
  try {
3847
3887
  prepared = await api.prepare(skillToken, batchSize, randomUUID2());
@@ -3894,6 +3934,7 @@ ${c.bold(`${project.organisation_slug}/${project.project_slug}`)} ${c.dim(`(${pr
3894
3934
  spinner?.succeed(`#${ticket.sequence_number} ready`);
3895
3935
  }
3896
3936
  inFlight.delete(ticket.ticket_id);
3937
+ if (agg.submitted >= maxSubmits) break;
3897
3938
  } catch (err) {
3898
3939
  agg.failed += 1;
3899
3940
  spinner?.fail(`#${ticket.sequence_number} ${err.message.slice(0, 200)}`);
@@ -5617,7 +5658,7 @@ function checkBinary(name, command) {
5617
5658
  }
5618
5659
 
5619
5660
  // src/commands/version.ts
5620
- var CLI_VERSION = true ? "0.2.20" : "0.0.0-dev";
5661
+ var CLI_VERSION = true ? "0.2.22" : "0.0.0-dev";
5621
5662
  function registerVersion(program2) {
5622
5663
  program2.command("version").description("Print the CLI version").action(() => {
5623
5664
  process.stdout.write(CLI_VERSION + "\n");