@songsid/agend 2.1.8-beta.5 → 2.1.8-beta.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.
Files changed (41) hide show
  1. package/dist/backend/codex-session-lookup.d.ts +16 -0
  2. package/dist/backend/codex-session-lookup.js +76 -2
  3. package/dist/backend/codex-session-lookup.js.map +1 -1
  4. package/dist/backend/codex.js +10 -1
  5. package/dist/backend/codex.js.map +1 -1
  6. package/dist/backend/credential-profile.d.ts +9 -0
  7. package/dist/backend/credential-profile.js +20 -0
  8. package/dist/backend/credential-profile.js.map +1 -1
  9. package/dist/backend/muse.d.ts +6 -0
  10. package/dist/backend/muse.js +7 -1
  11. package/dist/backend/muse.js.map +1 -1
  12. package/dist/cli.js +91 -46
  13. package/dist/cli.js.map +1 -1
  14. package/dist/config.d.ts +1 -0
  15. package/dist/config.js +1 -1
  16. package/dist/config.js.map +1 -1
  17. package/dist/daemon.d.ts +16 -1
  18. package/dist/daemon.js +40 -2
  19. package/dist/daemon.js.map +1 -1
  20. package/dist/fleet-manager.d.ts +2 -0
  21. package/dist/fleet-manager.js +7 -2
  22. package/dist/fleet-manager.js.map +1 -1
  23. package/dist/forged-envelope-scan.d.ts +160 -0
  24. package/dist/forged-envelope-scan.js +312 -0
  25. package/dist/forged-envelope-scan.js.map +1 -0
  26. package/dist/instance-lifecycle.d.ts +3 -1
  27. package/dist/instance-lifecycle.js +16 -5
  28. package/dist/instance-lifecycle.js.map +1 -1
  29. package/dist/locale.js +10 -2
  30. package/dist/locale.js.map +1 -1
  31. package/dist/ls-rows.d.ts +17 -0
  32. package/dist/ls-rows.js +73 -0
  33. package/dist/ls-rows.js.map +1 -1
  34. package/dist/paths.js +4 -2
  35. package/dist/paths.js.map +1 -1
  36. package/dist/topic-commands.js +23 -19
  37. package/dist/topic-commands.js.map +1 -1
  38. package/dist/transcript-sources.d.ts +30 -0
  39. package/dist/transcript-sources.js +78 -0
  40. package/dist/transcript-sources.js.map +1 -1
  41. package/package.json +1 -1
package/dist/daemon.d.ts CHANGED
@@ -517,6 +517,16 @@ export declare class Daemon extends EventEmitter {
517
517
  * would silently no-op exactly when we most need to stop feeding the CLI.
518
518
  */
519
519
  private pausePending;
520
+ /**
521
+ * #1044: pause on the idle edge only if the auth error is still on screen.
522
+ * Set when nothing could vouch for the hit — the backend has no token-free
523
+ * auth check (muse), or it could not answer. A real expired session prints
524
+ * its failure at the end of the turn it broke, so it is still at the bottom
525
+ * when that turn ends; a phrase the pattern caught mid-turn has scrolled on
526
+ * by then. Recovery cannot decide this: an expired session is back at its
527
+ * prompt after every failed turn, which is what "recovered" means.
528
+ */
529
+ private pauseReconfirmAuth;
520
530
  /**
521
531
  * An auth failure was detected and nothing has resolved it yet.
522
532
  *
@@ -935,7 +945,12 @@ export declare class Daemon extends EventEmitter {
935
945
  * failures: pause() alone no-ops while the CLI is busy/stuck, which is the
936
946
  * usual state when the error surfaces. Cleared by a successful pause or wake.
937
947
  */
938
- requestPauseWhenIdle(): void;
948
+ requestPauseWhenIdle(opts?: {
949
+ reconfirmAuth?: boolean;
950
+ }): void;
951
+ /** The backend's own auth-error pattern, within the pane's last rows. */
952
+ private authErrorAtPaneBottom;
953
+ private static readonly AUTH_RECONFIRM_ROWS;
939
954
  pause(): Promise<void>;
940
955
  /** Respawn the CLI in the preserved window and block until its prompt is ready. */
941
956
  wake(timeoutMs?: number): Promise<void>;
package/dist/daemon.js CHANGED
@@ -1065,6 +1065,16 @@ export class Daemon extends EventEmitter {
1065
1065
  * would silently no-op exactly when we most need to stop feeding the CLI.
1066
1066
  */
1067
1067
  pausePending = false;
1068
+ /**
1069
+ * #1044: pause on the idle edge only if the auth error is still on screen.
1070
+ * Set when nothing could vouch for the hit — the backend has no token-free
1071
+ * auth check (muse), or it could not answer. A real expired session prints
1072
+ * its failure at the end of the turn it broke, so it is still at the bottom
1073
+ * when that turn ends; a phrase the pattern caught mid-turn has scrolled on
1074
+ * by then. Recovery cannot decide this: an expired session is back at its
1075
+ * prompt after every failed turn, which is what "recovered" means.
1076
+ */
1077
+ pauseReconfirmAuth = false;
1068
1078
  /**
1069
1079
  * An auth failure was detected and nothing has resolved it yet.
1070
1080
  *
@@ -3190,11 +3200,28 @@ export class Daemon extends EventEmitter {
3190
3200
  * failures: pause() alone no-ops while the CLI is busy/stuck, which is the
3191
3201
  * usual state when the error surfaces. Cleared by a successful pause or wake.
3192
3202
  */
3193
- requestPauseWhenIdle() {
3203
+ requestPauseWhenIdle(opts = {}) {
3194
3204
  if (this.pauseWakeState === "paused")
3195
3205
  return;
3206
+ const reconfirm = opts.reconfirmAuth === true;
3207
+ // A pause already pending unconditionally stays unconditional.
3208
+ this.pauseReconfirmAuth = this.pausePending ? this.pauseReconfirmAuth && reconfirm : reconfirm;
3196
3209
  this.pausePending = true;
3197
- }
3210
+ // A conditional request is the only pause path it has (#1044): decide on
3211
+ // the current pane now instead of at the next state sweep, so a pane that
3212
+ // is already idle is not left open to a delivery in the meantime.
3213
+ if (reconfirm)
3214
+ void this.captureAndEvaluateInstanceState("deferred_pause");
3215
+ }
3216
+ /** The backend's own auth-error pattern, within the pane's last rows. */
3217
+ authErrorAtPaneBottom(pane) {
3218
+ const rows = pane.replace(/\r/g, "").split("\n").filter(r => r.trim() !== "");
3219
+ const bottom = rows.slice(-Daemon.AUTH_RECONFIRM_ROWS).join("\n");
3220
+ return (this.backend?.getErrorPatterns?.() ?? [])
3221
+ .filter(ep => ep.type === "auth_error")
3222
+ .some(ep => new RegExp(ep.pattern.source, ep.pattern.flags.replace("g", "")).test(bottom));
3223
+ }
3224
+ static AUTH_RECONFIRM_ROWS = 15;
3198
3225
  async pause() {
3199
3226
  if (this.pauseWakeState === "paused")
3200
3227
  return;
@@ -3277,6 +3304,7 @@ export class Daemon extends EventEmitter {
3277
3304
  // An explicit wake (e.g. after the user re-logs in) cancels a deferred
3278
3305
  // auth pause — otherwise the instance would pause again the moment it idles.
3279
3306
  this.pausePending = false;
3307
+ this.pauseReconfirmAuth = false;
3280
3308
  this.authFailureUnresolved = false;
3281
3309
  this.loginScreenReported = false;
3282
3310
  this.fatalStartupReported = false;
@@ -3404,6 +3432,16 @@ export class Daemon extends EventEmitter {
3404
3432
  // live, kept its warm slot, and re-raised a hang alert on every scan.
3405
3433
  if (this.pausePending && (snapshot.state === "idle" || snapshot.state === "stuck") && this.pasteQueueDepth === 0) {
3406
3434
  this.pausePending = false;
3435
+ const reconfirm = this.pauseReconfirmAuth;
3436
+ this.pauseReconfirmAuth = false;
3437
+ // An unreadable pane keeps the pause: when in doubt, stop feeding a CLI
3438
+ // that may be unable to answer (42512a46).
3439
+ if (reconfirm && pane !== undefined && !this.authErrorAtPaneBottom(pane)) {
3440
+ this.authFailureUnresolved = false;
3441
+ this.logger.warn({ state: snapshot.state }, "Deferred auth pause dropped: the auth-error text is no longer at the bottom of the pane at the end of the turn, "
3442
+ + "and this backend has no auth check to confirm it (likely conversation text)");
3443
+ return;
3444
+ }
3407
3445
  this.pauseAllowStuck = snapshot.state === "stuck";
3408
3446
  this.emit("auto_pause_requested", { name: this.name, idleSince: snapshot.stateChangedAt });
3409
3447
  return;