@songsid/agend 2.1.0-beta.7 → 2.1.0-beta.9

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.
@@ -122,8 +122,9 @@ node -e "let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{t
122
122
  }
123
123
  }
124
124
  getReadyPattern() {
125
- // Startup/header: Gemini shortcut text. Daily idle statusline: "◔ 42%".
126
- return /\? for shortcuts|Gemini|◔\s*\d+%/m;
125
+ // Startup/header: Gemini shortcut text. Daily prompts observed in the TUI
126
+ // are either "◔ 42%" or a standalone ">" line between separators.
127
+ return /\? for shortcuts|Gemini|◔\s*\d+%|^>\s*$/m;
127
128
  }
128
129
  getContextUsage() {
129
130
  return null;
@@ -1 +1 @@
1
- {"version":3,"file":"antigravity.js","sourceRoot":"","sources":["../../src/backend/antigravity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAChG,OAAO,EAAiF,iBAAiB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC7I,OAAO,EAAE,gBAAgB,EAAgB,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,OAAO,kBAAkB;IAIT;IAHX,UAAU,GAAG,KAAK,CAAC;IACpB,UAAU,CAAS;IAE3B,YAAoB,WAAmB;QAAnB,gBAAW,GAAX,WAAW,CAAQ;QACrC,IAAI,CAAC,UAAU,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC;IAED,YAAY,CAAC,MAAwB;QACnC,IAAI,GAAG,GAAG,GAAG,IAAI,CAAC,UAAU,iCAAiC,CAAC;QAC9D,IAAI,CAAC,MAAM,CAAC,UAAU;YAAE,GAAG,IAAI,aAAa,CAAC;QAC7C,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YACjB,IAAI,iBAAiB,CAAC,aAAa,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;gBACnD,0EAA0E;gBAC1E,sDAAsD;gBACtD,GAAG,IAAI,YAAY,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,sBAAsB,EAAE,EAAE,CAAC,EAAE,CAAC;YACxE,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CAAC,kBAAkB,MAAM,CAAC,KAAK,kFAAkF,CAAC,CAAC;YACjI,CAAC;QACH,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED;;;OAGG;IACH,uBAAuB,CAAC,gBAAwB,EAAE,YAAqB;QACrE,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;QACvB,MAAM,GAAG,GAAG,gBAAgB,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,gBAAgB,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC;QAC7G,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;QAClE,IAAI,CAAC,SAAS;YAAE,OAAO,gBAAgB,CAAC;QAExC,MAAM,IAAI,GAAG,YAAY,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,WAAW,CAAC;QACpE,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,EAAE,kBAAkB,EAAE,IAAI,CAAC,CAAC;QACzD,SAAS,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5C,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,WAAW,CAAC,MAAwB;QAClC,8FAA8F;QAC9F,MAAM,GAAG,GAAG,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC;QACvF,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QACvC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE1C,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;YACxB,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;YAChD,gBAAgB,CAAC,UAAU,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC;QACzE,CAAC;QAED,IAAI,CAAC,gBAAgB,EAAE,CAAC;IAC1B,CAAC;IAED;;;;;;;;OAQG;IACK,gBAAgB;QACtB,IAAI,CAAC;YACH,uEAAuE;YACvE,oEAAoE;YACpE,0EAA0E;YAC1E,yEAAyE;YACzE,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,EAAE,mBAAmB,CAAC,CAAC;YAC7D,MAAM,MAAM,GAAG;;;CAGpB,CAAC;YACI,IAAI,CAAC;gBACH,SAAS,CAAC,YAAY,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC/C,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;gBACnD,SAAS,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CAAE,4CAA4C;YAC7E,CAAC;YAAC,MAAM,CAAC,CAAC,+DAA+D,CAAC,CAAC;YAE3E,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,iBAAiB,CAAC,CAAC;YAC7D,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;YACnD,IAAI,QAAQ,GAA4B,EAAE,CAAC;YAC3C,IAAI,CAAC;gBAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,qCAAqC,CAAC,CAAC;YACzH,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;gBAAE,QAAQ,GAAG,EAAE,CAAC;YAChG,MAAM,UAAU,GAAG,CAAC,QAAQ,CAAC,UAAU,IAAI,OAAO,QAAQ,CAAC,UAAU,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;gBACxH,CAAC,CAAC,QAAQ,CAAC,UAAqC;gBAChD,CAAC,CAAC,EAAE,CAAC;YAEP,IAAI,OAAO,GAAG,KAAK,CAAC;YACpB,IAAI,UAAU,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;gBAAC,UAAU,CAAC,OAAO,GAAG,IAAI,CAAC;gBAAC,OAAO,GAAG,IAAI,CAAC;YAAC,CAAC;YAC/E,oEAAoE;YACpE,MAAM,cAAc,GAAG,OAAO,UAAU,CAAC,OAAO,KAAK,QAAQ,IAAI,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC;YAClG,IAAI,CAAC,cAAc,IAAI,UAAU,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;gBAAC,UAAU,CAAC,OAAO,GAAG,UAAU,CAAC;gBAAC,OAAO,GAAG,IAAI,CAAC;YAAC,CAAC;YAE9G,IAAI,CAAC,OAAO;gBAAE,OAAO,CAAE,oDAAoD;YAC3E,QAAQ,CAAC,UAAU,GAAG,UAAU,CAAC;YACjC,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACvC,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QACxE,CAAC;QAAC,MAAM,CAAC,CAAC,2DAA2D,CAAC,CAAC;IACzE,CAAC;IAED,OAAO,CAAC,MAAwB;QAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,kBAAkB,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC;QACrE,IAAI,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACpB,IAAI,CAAC;gBAAC,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;IAED,eAAe;QACb,wEAAwE;QACxE,OAAO,mCAAmC,CAAC;IAC7C,CAAC;IAED,eAAe;QACb,OAAO,IAAI,CAAC;IACd,CAAC;IAED,YAAY;QACV,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;YAC/C,OAAO,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC;QACjD,CAAC;QAAC,MAAM,CAAC;YAAC,OAAO,IAAI,CAAC;QAAC,CAAC;IAC1B,CAAC;IAED,cAAc,KAAa,OAAO,OAAO,CAAC,CAAC,CAAC;IAE5C,8EAA8E;IAC9E,+DAA+D;IAC/D,iBAAiB,KAAa,OAAO,QAAQ,CAAC,CAAC,CAAC;IAEhD,2EAA2E;IAC3E,8EAA8E;IAC9E,YAAY,KAAa,OAAO,QAAQ,CAAC,CAAC,CAAC;IAE3C,gBAAgB;QACd,OAAO;YACL,EAAE,OAAO,EAAE,2BAA2B,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAAiB,EAAE;YACrG,EAAE,OAAO,EAAE,wCAAwC,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,sBAAsB,EAAE;SAC9H,CAAC;IACJ,CAAC;IAED,iBAAiB;QACf,OAAO;YACL,EAAE,OAAO,EAAE,oCAAoC,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,qBAAqB,EAAE;SACvG,CAAC;IACJ,CAAC;IAED,iBAAiB;QACf,OAAO,EAAE,CAAC;IACZ,CAAC;CACF"}
1
+ {"version":3,"file":"antigravity.js","sourceRoot":"","sources":["../../src/backend/antigravity.ts"],"names":[],"mappings":"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"}
@@ -18,6 +18,8 @@ export declare class ContextGuardian extends EventEmitter {
18
18
  private logger;
19
19
  private statusFilePath;
20
20
  private consecutiveReadFailures;
21
+ private watching;
22
+ private readonly onStatusFileChange;
21
23
  constructor(_config: GuardianConfig, logger: Logger, statusFilePath: string);
22
24
  startWatching(): void;
23
25
  private readAndCheck;
@@ -16,6 +16,8 @@ export class ContextGuardian extends EventEmitter {
16
16
  logger;
17
17
  statusFilePath;
18
18
  consecutiveReadFailures = 0;
19
+ watching = false;
20
+ onStatusFileChange = () => this.readAndCheck();
19
21
  constructor(_config, logger, statusFilePath) {
20
22
  super();
21
23
  this._config = _config;
@@ -23,8 +25,11 @@ export class ContextGuardian extends EventEmitter {
23
25
  this.statusFilePath = statusFilePath;
24
26
  }
25
27
  startWatching() {
28
+ if (this.watching)
29
+ return;
30
+ this.watching = true;
26
31
  this.logger.debug({ path: this.statusFilePath }, "Watching status line file");
27
- watchFile(this.statusFilePath, { interval: 2000 }, () => this.readAndCheck());
32
+ watchFile(this.statusFilePath, { interval: 2000 }, this.onStatusFileChange);
28
33
  }
29
34
  readAndCheck() {
30
35
  try {
@@ -67,7 +72,10 @@ export class ContextGuardian extends EventEmitter {
67
72
  }
68
73
  }
69
74
  stop() {
70
- unwatchFile(this.statusFilePath);
75
+ if (!this.watching)
76
+ return;
77
+ unwatchFile(this.statusFilePath, this.onStatusFileChange);
78
+ this.watching = false;
71
79
  }
72
80
  }
73
81
  //# sourceMappingURL=context-guardian.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"context-guardian.js","sourceRoot":"","sources":["../src/context-guardian.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"context-guardian.js","sourceRoot":"","sources":["../src/context-guardian.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { Daemon } from "./daemon.js";
2
+ import { createLogger } from "./logger.js";
2
3
  const args = process.argv.slice(2);
3
4
  function getArg(name) {
4
5
  const idx = args.indexOf(name);
@@ -15,7 +16,7 @@ catch (err) {
15
16
  process.exit(1);
16
17
  }
17
18
  const topicMode = args.includes("--topic-mode");
18
- const daemon = new Daemon(name, config, instanceDir, topicMode);
19
+ const daemon = new Daemon(name, config, instanceDir, topicMode, undefined, undefined, createLogger(config.log_level));
19
20
  daemon.start().catch((err) => {
20
21
  console.error("Daemon failed:", err);
21
22
  process.exit(1);
@@ -1 +1 @@
1
- {"version":3,"file":"daemon-entry.js","sourceRoot":"","sources":["../src/daemon-entry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAGrC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEnC,SAAS,MAAM,CAAC,IAAY;IAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACzC,CAAC;AAED,MAAM,IAAI,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;AAClC,MAAM,WAAW,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAC7C,IAAI,MAAsB,CAAC;AAC3B,IAAI,CAAC;IACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;AAC1C,CAAC;AAAC,OAAO,GAAG,EAAE,CAAC;IACb,OAAO,CAAC,KAAK,CAAC,kCAAmC,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;IAC1E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;AAChD,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;AAEhE,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IAC3B,OAAO,CAAC,KAAK,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;IAC1B,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;IACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC;AACF,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAChC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC"}
1
+ {"version":3,"file":"daemon-entry.js","sourceRoot":"","sources":["../src/daemon-entry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEnC,SAAS,MAAM,CAAC,IAAY;IAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACzC,CAAC;AAED,MAAM,IAAI,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;AAClC,MAAM,WAAW,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAC7C,IAAI,MAAsB,CAAC;AAC3B,IAAI,CAAC;IACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;AAC1C,CAAC;AAAC,OAAO,GAAG,EAAE,CAAC;IACb,OAAO,CAAC,KAAK,CAAC,kCAAmC,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;IAC1E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;AAChD,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;AAEtH,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IAC3B,OAAO,CAAC,KAAK,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;IAC1B,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;IACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC;AACF,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAChC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC"}
package/dist/daemon.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { EventEmitter } from "node:events";
2
2
  import type { InstanceConfig, RotationSnapshot } from "./types.js";
3
+ import type { Logger } from "./logger.js";
3
4
  import { MessageBus } from "./channel/message-bus.js";
4
5
  import type { CliBackend, InstanceState, InstanceStateSnapshot } from "./backend/types.js";
5
6
  import { HangDetector } from "./hang-detector.js";
@@ -38,6 +39,20 @@ export declare class PaneStateMachine {
38
39
  observe(pane: string, now?: number): InstanceStateSnapshot;
39
40
  snapshot(now?: number): InstanceStateSnapshot;
40
41
  }
42
+ /** Tracks whether an inbound arrived after the most recent confirmed idle prompt. */
43
+ export declare class PendingWorkTracker {
44
+ private lastInboundAt;
45
+ private lastIdleAt;
46
+ private sequence;
47
+ private lastInboundOrder;
48
+ private lastIdleOrder;
49
+ constructor(now?: number);
50
+ recordInbound(now?: number): void;
51
+ recordIdle(now?: number): void;
52
+ hasPendingWork(): boolean;
53
+ }
54
+ /** Redact likely credentials and control sequences before pane text reaches logs. */
55
+ export declare function sanitizePaneTail(pane: string, lineCount?: number): string[];
41
56
  export declare class Daemon extends EventEmitter {
42
57
  private name;
43
58
  private config;
@@ -81,6 +96,7 @@ export declare class Daemon extends EventEmitter {
81
96
  private hangDetector;
82
97
  private instanceState;
83
98
  private instanceStateMachine;
99
+ private pendingWork;
84
100
  private instanceStateMonitorTimer;
85
101
  private statePollInFlight;
86
102
  private autoPauseController;
@@ -99,6 +115,8 @@ export declare class Daemon extends EventEmitter {
99
115
  private lastBuiltInstructions;
100
116
  private pasteQueueDepth;
101
117
  private errorMonitorTimer;
118
+ /** Prevent in-flight monitor callbacks from re-arming after a pause. */
119
+ private runtimeMonitorsFrozen;
102
120
  private errorWaitingForRecovery;
103
121
  private errorDetectedAt;
104
122
  /** Whether this instance is in an abnormal error state (auto-pause is normal). */
@@ -114,7 +132,7 @@ export declare class Daemon extends EventEmitter {
114
132
  private static ERROR_COOLDOWN_MS;
115
133
  private lastErrorCount;
116
134
  private lastDetectedErrorType;
117
- constructor(name: string, config: InstanceConfig, instanceDir: string, topicMode?: boolean, backend?: CliBackend | undefined, controlClient?: TmuxControlClient | undefined);
135
+ constructor(name: string, config: InstanceConfig, instanceDir: string, topicMode?: boolean, backend?: CliBackend | undefined, controlClient?: TmuxControlClient | undefined, rootLogger?: Logger);
118
136
  start(): Promise<void>;
119
137
  private startHealthCheck;
120
138
  /**
@@ -142,6 +160,11 @@ export declare class Daemon extends EventEmitter {
142
160
  /** Respawn the CLI in the preserved window and block until its prompt is ready. */
143
161
  wake(timeoutMs?: number): Promise<void>;
144
162
  private startInstanceStateMonitor;
163
+ private handleStuckTransition;
164
+ /** Stop every runtime poller/watcher while preserving IPC and daemon state. */
165
+ private freezeRuntimeMonitors;
166
+ /** Restore the same monitor objects after wake without adding event listeners. */
167
+ private resumeRuntimeMonitors;
145
168
  getMessageBus(): MessageBus;
146
169
  private summarizeTool;
147
170
  private addToolStatus;
package/dist/daemon.js CHANGED
@@ -3,7 +3,6 @@ import { mkdirSync, writeFileSync, readFileSync, existsSync, unlinkSync, rmSync,
3
3
  import { fileURLToPath } from "node:url";
4
4
  import { createHash, randomBytes } from "node:crypto";
5
5
  import { EventEmitter } from "node:events";
6
- import { createLogger } from "./logger.js";
7
6
  import { TmuxManager } from "./tmux-manager.js";
8
7
  import { TranscriptMonitor } from "./transcript-monitor.js";
9
8
  import { ContextGuardian } from "./context-guardian.js";
@@ -115,6 +114,55 @@ export class PaneStateMachine {
115
114
  };
116
115
  }
117
116
  }
117
+ /** Tracks whether an inbound arrived after the most recent confirmed idle prompt. */
118
+ export class PendingWorkTracker {
119
+ lastInboundAt = 0;
120
+ lastIdleAt;
121
+ sequence = 0;
122
+ lastInboundOrder = 0;
123
+ lastIdleOrder = 0;
124
+ constructor(now = Date.now()) {
125
+ this.lastIdleAt = now;
126
+ }
127
+ recordInbound(now = Date.now()) {
128
+ this.lastInboundAt = now;
129
+ this.lastInboundOrder = ++this.sequence;
130
+ }
131
+ recordIdle(now = Date.now()) {
132
+ // An async pane poll can finish after a newer inbound. Do not let its stale
133
+ // observation clear work which had not arrived when the pane was captured.
134
+ if (now < this.lastInboundAt)
135
+ return;
136
+ this.lastIdleAt = now;
137
+ this.lastIdleOrder = ++this.sequence;
138
+ }
139
+ hasPendingWork() {
140
+ return this.lastInboundOrder > this.lastIdleOrder;
141
+ }
142
+ }
143
+ /** Redact likely credentials and control sequences before pane text reaches logs. */
144
+ export function sanitizePaneTail(pane, lineCount = 5) {
145
+ const secretAssignment = /\b(token|secret|password|passwd|api[_-]?key|authorization)\b\s*[:=]\s*\S+/gi;
146
+ const bearer = /\bBearer\s+\S+/gi;
147
+ const knownToken = /\b(?:sk-[A-Za-z0-9_-]+|ghp_[A-Za-z0-9]+|github_pat_[A-Za-z0-9_]+|AKIA[A-Z0-9]{16})\b/g;
148
+ const jwt = /\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\b/g;
149
+ const opaqueSecret = /\b[A-Za-z0-9_+/=-]{32,}\b/g;
150
+ const lines = pane
151
+ .replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, "")
152
+ .split(/\r?\n/);
153
+ while (lines.length > 0 && /^\s*$/.test(lines[lines.length - 1]))
154
+ lines.pop();
155
+ return lines
156
+ .slice(-lineCount)
157
+ .map(line => line
158
+ .replace(bearer, "Bearer [REDACTED]")
159
+ .replace(secretAssignment, "$1=[REDACTED]")
160
+ .replace(knownToken, "[REDACTED]")
161
+ .replace(jwt, "[REDACTED]")
162
+ .replace(opaqueSecret, "[REDACTED]")
163
+ .replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, "")
164
+ .slice(0, 200));
165
+ }
118
166
  export class Daemon extends EventEmitter {
119
167
  name;
120
168
  config;
@@ -164,6 +212,7 @@ export class Daemon extends EventEmitter {
164
212
  hangDetector = null;
165
213
  instanceState = "idle";
166
214
  instanceStateMachine = null;
215
+ pendingWork = new PendingWorkTracker();
167
216
  instanceStateMonitorTimer = null;
168
217
  statePollInFlight = false;
169
218
  autoPauseController;
@@ -189,6 +238,8 @@ export class Daemon extends EventEmitter {
189
238
  pasteQueueDepth = 0;
190
239
  // PTY error pattern monitoring
191
240
  errorMonitorTimer = null;
241
+ /** Prevent in-flight monitor callbacks from re-arming after a pause. */
242
+ runtimeMonitorsFrozen = false;
192
243
  errorWaitingForRecovery = false; // true = error detected, waiting for ready pattern
193
244
  errorDetectedAt = 0;
194
245
  /** Whether this instance is in an abnormal error state (auto-pause is normal). */
@@ -215,7 +266,7 @@ export class Daemon extends EventEmitter {
215
266
  // still registers as new (prevents the old hash-dedup's permanent suppression).
216
267
  lastErrorCount = new Map();
217
268
  lastDetectedErrorType = null;
218
- constructor(name, config, instanceDir, topicMode = false, backend, controlClient) {
269
+ constructor(name, config, instanceDir, topicMode = false, backend, controlClient, rootLogger) {
219
270
  super();
220
271
  this.name = name;
221
272
  this.config = config;
@@ -223,7 +274,9 @@ export class Daemon extends EventEmitter {
223
274
  this.topicMode = topicMode;
224
275
  this.backend = backend;
225
276
  this.controlClient = controlClient;
226
- this.logger = createLogger(config.log_level);
277
+ if (!rootLogger)
278
+ throw new Error("Daemon requires a shared root logger");
279
+ this.logger = rootLogger.child({ instance: name }, { level: config.log_level });
227
280
  this.tmuxSessionName = getTmuxSession();
228
281
  this.messageBus = new MessageBus();
229
282
  this.messageBus.setLogger(this.logger);
@@ -521,11 +574,18 @@ export class Daemon extends EventEmitter {
521
574
  this.logger.info(`${this.name} ready`);
522
575
  }
523
576
  startHealthCheck() {
577
+ if (this.runtimeMonitorsFrozen || this.healthCheckTimer)
578
+ return;
524
579
  const { max_retries, backoff, reset_after } = this.config.restart_policy;
525
580
  if (max_retries <= 0)
526
581
  return; // restart disabled
527
582
  const scheduleNext = () => {
583
+ if (this.runtimeMonitorsFrozen || this.healthCheckTimer)
584
+ return;
528
585
  this.healthCheckTimer = setTimeout(async () => {
586
+ this.healthCheckTimer = null;
587
+ if (this.runtimeMonitorsFrozen)
588
+ return;
529
589
  // Instance directory removed externally (e.g. `rm -rf ~/.agend/instances/<name>`).
530
590
  // Stop the loop permanently — otherwise every tick triggers a respawn, whose
531
591
  // writeRotationSnapshot fails with ENOENT and gets caught as "Failed to respawn",
@@ -776,6 +836,8 @@ export class Daemon extends EventEmitter {
776
836
  * (ready pattern visible), it goes back to monitoring for new errors.
777
837
  */
778
838
  startErrorMonitor() {
839
+ if (this.runtimeMonitorsFrozen || this.errorMonitorTimer)
840
+ return;
779
841
  const patterns = this.backend?.getErrorPatterns?.() ?? [];
780
842
  const dialogs = this.backend?.getRuntimeDialogs?.() ?? [];
781
843
  if (!patterns.length && !dialogs.length)
@@ -895,26 +957,13 @@ export class Daemon extends EventEmitter {
895
957
  }
896
958
  async stop() {
897
959
  this.logger.info("Stopping daemon instance");
898
- if (this.healthCheckTimer) {
899
- clearTimeout(this.healthCheckTimer);
900
- this.healthCheckTimer = null;
901
- }
902
- if (this.errorMonitorTimer) {
903
- clearInterval(this.errorMonitorTimer);
904
- this.errorMonitorTimer = null;
905
- }
906
- if (this.instanceStateMonitorTimer) {
907
- clearInterval(this.instanceStateMonitorTimer);
908
- this.instanceStateMonitorTimer = null;
909
- }
960
+ this.freezeRuntimeMonitors();
910
961
  if (this.toolStatusDebounce) {
911
962
  clearTimeout(this.toolStatusDebounce);
912
963
  this.toolStatusDebounce = null;
913
964
  }
914
965
  this.pendingIpcRequests.clear();
915
966
  this.hangDetector?.stop();
916
- this.transcriptMonitor?.stop();
917
- this.guardian?.stop();
918
967
  if (this.adapter)
919
968
  await this.adapter.stop();
920
969
  // Notify MCP servers of graceful shutdown (prevents reconnect attempts)
@@ -1007,6 +1056,7 @@ export class Daemon extends EventEmitter {
1007
1056
  }
1008
1057
  this.pauseWakeState = "pausing";
1009
1058
  this.healthCheckPaused = true;
1059
+ this.freezeRuntimeMonitors();
1010
1060
  const transition = (async () => {
1011
1061
  try {
1012
1062
  this.saveSessionId();
@@ -1053,6 +1103,7 @@ export class Daemon extends EventEmitter {
1053
1103
  this.pauseWakeState = "active";
1054
1104
  this.healthCheckPaused = false;
1055
1105
  this.pauseRequested = false;
1106
+ this.resumeRuntimeMonitors();
1056
1107
  throw err;
1057
1108
  }
1058
1109
  })();
@@ -1105,6 +1156,7 @@ export class Daemon extends EventEmitter {
1105
1156
  }
1106
1157
  catch { }
1107
1158
  this.transcriptMonitor?.resetOffset();
1159
+ this.resumeRuntimeMonitors();
1108
1160
  this.logger.info("Instance auto-woke");
1109
1161
  this.ipcServer?.broadcast({
1110
1162
  type: "instance_state", instanceName: this.name, state: this.instanceState, pausedAt: null,
@@ -1124,7 +1176,7 @@ export class Daemon extends EventEmitter {
1124
1176
  }
1125
1177
  }
1126
1178
  startInstanceStateMonitor() {
1127
- if (!this.tmux || !this.backend || this.instanceStateMonitorTimer)
1179
+ if (this.runtimeMonitorsFrozen || !this.tmux || !this.backend || this.instanceStateMonitorTimer)
1128
1180
  return;
1129
1181
  const rawConfig = this.config.hang_detector;
1130
1182
  const timeoutMinutes = rawConfig?.timeout_minutes;
@@ -1134,7 +1186,8 @@ export class Daemon extends EventEmitter {
1134
1186
  const pollIntervalMs = typeof rawConfig?.poll_interval_ms === "number" && rawConfig.poll_interval_ms > 0
1135
1187
  ? rawConfig.poll_interval_ms
1136
1188
  : DEFAULT_STATE_POLL_INTERVAL_MS;
1137
- this.instanceStateMachine = new PaneStateMachine(this.backend.getReadyPattern(), stuckTimeoutMs);
1189
+ const readyPattern = this.backend.getReadyPattern();
1190
+ this.instanceStateMachine = new PaneStateMachine(readyPattern, stuckTimeoutMs);
1138
1191
  const poll = async () => {
1139
1192
  if (!this.tmux || this.spawning || this.statePollInFlight)
1140
1193
  return;
@@ -1147,6 +1200,11 @@ export class Daemon extends EventEmitter {
1147
1200
  const previous = this.instanceState;
1148
1201
  const snapshot = this.instanceStateMachine.observe(pane);
1149
1202
  this.instanceState = snapshot.state;
1203
+ // Only a transition back to idle completes pending work. Repeated idle
1204
+ // polls between enqueue and paste must not clear a newly-recorded inbound.
1205
+ if (snapshot.state === "idle" && previous !== "idle") {
1206
+ this.pendingWork.recordIdle(snapshot.observedAt);
1207
+ }
1150
1208
  if (snapshot.state !== previous) {
1151
1209
  this.logger.info({
1152
1210
  previousState: previous,
@@ -1158,7 +1216,7 @@ export class Daemon extends EventEmitter {
1158
1216
  // Emit exactly once per transition into stuck. Further notifications
1159
1217
  // require observable progress (working) or a ready prompt (idle) first.
1160
1218
  if (snapshot.state === "stuck") {
1161
- this.hangDetector?.emit("hang");
1219
+ this.handleStuckTransition(pane, snapshot, readyPattern);
1162
1220
  }
1163
1221
  }
1164
1222
  if (snapshot.state !== "idle")
@@ -1180,6 +1238,54 @@ export class Daemon extends EventEmitter {
1180
1238
  void poll();
1181
1239
  this.instanceStateMonitorTimer = setInterval(() => { void poll(); }, pollIntervalMs);
1182
1240
  }
1241
+ handleStuckTransition(pane, snapshot, readyPattern) {
1242
+ const deterministicReadyPattern = new RegExp(readyPattern.source, readyPattern.flags.replace(/[gy]/g, ""));
1243
+ const diagnostic = {
1244
+ backend: this.backend?.binaryName ?? this.config.backend ?? "unknown",
1245
+ paneTail: sanitizePaneTail(pane),
1246
+ readyPattern: readyPattern.toString(),
1247
+ readyMatched: deterministicReadyPattern.test(pane),
1248
+ unchangedForMs: snapshot.unchangedForMs,
1249
+ pendingWork: this.pendingWork.hasPendingWork(),
1250
+ };
1251
+ if (!diagnostic.pendingWork) {
1252
+ this.logger.debug(diagnostic, "Suppressing stuck notification without pending work");
1253
+ return;
1254
+ }
1255
+ this.logger.warn(diagnostic, "Instance pane stuck with pending work");
1256
+ this.hangDetector?.emit("hang", { unchangedForMs: snapshot.unchangedForMs });
1257
+ }
1258
+ /** Stop every runtime poller/watcher while preserving IPC and daemon state. */
1259
+ freezeRuntimeMonitors() {
1260
+ this.runtimeMonitorsFrozen = true;
1261
+ if (this.healthCheckTimer) {
1262
+ clearTimeout(this.healthCheckTimer);
1263
+ this.healthCheckTimer = null;
1264
+ }
1265
+ if (this.errorMonitorTimer) {
1266
+ clearInterval(this.errorMonitorTimer);
1267
+ this.errorMonitorTimer = null;
1268
+ }
1269
+ if (this.instanceStateMonitorTimer) {
1270
+ clearInterval(this.instanceStateMonitorTimer);
1271
+ this.instanceStateMonitorTimer = null;
1272
+ }
1273
+ this.transcriptMonitor?.stop();
1274
+ this.guardian?.stop();
1275
+ }
1276
+ /** Restore the same monitor objects after wake without adding event listeners. */
1277
+ resumeRuntimeMonitors() {
1278
+ if (!this.runtimeMonitorsFrozen)
1279
+ return;
1280
+ this.runtimeMonitorsFrozen = false;
1281
+ this.startHealthCheck();
1282
+ if (!this.config.lightweight) {
1283
+ this.transcriptMonitor?.startPolling();
1284
+ this.guardian?.startWatching();
1285
+ this.startErrorMonitor();
1286
+ }
1287
+ this.startInstanceStateMonitor();
1288
+ }
1183
1289
  getMessageBus() {
1184
1290
  return this.messageBus;
1185
1291
  }
@@ -1264,6 +1370,7 @@ export class Daemon extends EventEmitter {
1264
1370
  this.pendingInstructionsUpdate = undefined;
1265
1371
  }
1266
1372
  this.hangDetector?.recordInbound();
1373
+ this.pendingWork.recordInbound();
1267
1374
  // v3: record user messages for rotation snapshot
1268
1375
  this.recordRecentUserMessage(content, meta);
1269
1376
  // Format message with metadata prefix for the agent