crewly 1.20.300 → 1.20.302

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 (100) hide show
  1. package/config/skills/agent/core/publish-app/SKILL.md +10 -1
  2. package/config/skills/agent/core/receive-file/SKILL.md +4 -0
  3. package/config/skills/agent/core/request-file/SKILL.md +74 -0
  4. package/config/skills/agent/core/request-file/execute.sh +89 -0
  5. package/config/skills/agent/core/request-file/execute.test.sh +77 -0
  6. package/config/skills/agent/core/slack-file/SKILL.md +1 -1
  7. package/dist/backend/backend/src/constants.d.ts +13 -4
  8. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  9. package/dist/backend/backend/src/constants.js +18 -6
  10. package/dist/backend/backend/src/constants.js.map +1 -1
  11. package/dist/backend/backend/src/controllers/apps/apps.controller.d.ts +9 -0
  12. package/dist/backend/backend/src/controllers/apps/apps.controller.d.ts.map +1 -1
  13. package/dist/backend/backend/src/controllers/apps/apps.controller.js +21 -0
  14. package/dist/backend/backend/src/controllers/apps/apps.controller.js.map +1 -1
  15. package/dist/backend/backend/src/controllers/apps/apps.routes.d.ts +2 -0
  16. package/dist/backend/backend/src/controllers/apps/apps.routes.d.ts.map +1 -1
  17. package/dist/backend/backend/src/controllers/apps/apps.routes.js +7 -1
  18. package/dist/backend/backend/src/controllers/apps/apps.routes.js.map +1 -1
  19. package/dist/backend/backend/src/index.d.ts.map +1 -1
  20. package/dist/backend/backend/src/index.js +20 -1
  21. package/dist/backend/backend/src/index.js.map +1 -1
  22. package/dist/backend/backend/src/services/agent/follow-through.service.d.ts +33 -0
  23. package/dist/backend/backend/src/services/agent/follow-through.service.d.ts.map +1 -1
  24. package/dist/backend/backend/src/services/agent/follow-through.service.js +80 -7
  25. package/dist/backend/backend/src/services/agent/follow-through.service.js.map +1 -1
  26. package/dist/backend/backend/src/services/agent/follow-through.wiring.d.ts +34 -0
  27. package/dist/backend/backend/src/services/agent/follow-through.wiring.d.ts.map +1 -1
  28. package/dist/backend/backend/src/services/agent/follow-through.wiring.js +109 -4
  29. package/dist/backend/backend/src/services/agent/follow-through.wiring.js.map +1 -1
  30. package/dist/backend/backend/src/services/agent/idle-detection.service.d.ts +9 -0
  31. package/dist/backend/backend/src/services/agent/idle-detection.service.d.ts.map +1 -1
  32. package/dist/backend/backend/src/services/agent/idle-detection.service.js +24 -1
  33. package/dist/backend/backend/src/services/agent/idle-detection.service.js.map +1 -1
  34. package/dist/backend/backend/src/services/agent/idle-work-guard.d.ts +12 -1
  35. package/dist/backend/backend/src/services/agent/idle-work-guard.d.ts.map +1 -1
  36. package/dist/backend/backend/src/services/agent/idle-work-guard.js +11 -1
  37. package/dist/backend/backend/src/services/agent/idle-work-guard.js.map +1 -1
  38. package/dist/backend/backend/src/services/agent/stated-intent.d.ts +2 -2
  39. package/dist/backend/backend/src/services/agent/stated-intent.d.ts.map +1 -1
  40. package/dist/backend/backend/src/services/agent/stated-intent.js +17 -7
  41. package/dist/backend/backend/src/services/agent/stated-intent.js.map +1 -1
  42. package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts.map +1 -1
  43. package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js +1 -0
  44. package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js.map +1 -1
  45. package/dist/backend/backend/src/services/apps/apps.wiring.d.ts.map +1 -1
  46. package/dist/backend/backend/src/services/apps/apps.wiring.js +14 -0
  47. package/dist/backend/backend/src/services/apps/apps.wiring.js.map +1 -1
  48. package/dist/backend/backend/src/services/apps/file-request-watch.service.d.ts +88 -0
  49. package/dist/backend/backend/src/services/apps/file-request-watch.service.d.ts.map +1 -0
  50. package/dist/backend/backend/src/services/apps/file-request-watch.service.js +170 -0
  51. package/dist/backend/backend/src/services/apps/file-request-watch.service.js.map +1 -0
  52. package/dist/backend/backend/src/services/messaging/deferred-start-retry.d.ts +2 -0
  53. package/dist/backend/backend/src/services/messaging/deferred-start-retry.d.ts.map +1 -1
  54. package/dist/backend/backend/src/services/messaging/deferred-start-retry.js +1 -1
  55. package/dist/backend/backend/src/services/messaging/deferred-start-retry.js.map +1 -1
  56. package/dist/backend/backend/src/services/messaging/owner-thread-sentinel.service.d.ts +16 -0
  57. package/dist/backend/backend/src/services/messaging/owner-thread-sentinel.service.d.ts.map +1 -1
  58. package/dist/backend/backend/src/services/messaging/owner-thread-sentinel.service.js +38 -0
  59. package/dist/backend/backend/src/services/messaging/owner-thread-sentinel.service.js.map +1 -1
  60. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts.map +1 -1
  61. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js +51 -33
  62. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
  63. package/dist/backend/backend/src/types/slack.types.d.ts +8 -0
  64. package/dist/backend/backend/src/types/slack.types.d.ts.map +1 -1
  65. package/dist/backend/backend/src/types/slack.types.js.map +1 -1
  66. package/dist/backend/build-info.json +2 -2
  67. package/dist/cli/backend/src/constants.d.ts +13 -4
  68. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  69. package/dist/cli/backend/src/constants.js +18 -6
  70. package/dist/cli/backend/src/constants.js.map +1 -1
  71. package/dist/cli/backend/src/services/agent/follow-through.service.d.ts +33 -0
  72. package/dist/cli/backend/src/services/agent/follow-through.service.d.ts.map +1 -1
  73. package/dist/cli/backend/src/services/agent/follow-through.service.js +80 -7
  74. package/dist/cli/backend/src/services/agent/follow-through.service.js.map +1 -1
  75. package/dist/cli/backend/src/services/agent/stated-intent.d.ts +2 -2
  76. package/dist/cli/backend/src/services/agent/stated-intent.d.ts.map +1 -1
  77. package/dist/cli/backend/src/services/agent/stated-intent.js +17 -7
  78. package/dist/cli/backend/src/services/agent/stated-intent.js.map +1 -1
  79. package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts.map +1 -1
  80. package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.js +1 -0
  81. package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.js.map +1 -1
  82. package/dist/cli/backend/src/services/messaging/owner-thread-sentinel.service.d.ts +16 -0
  83. package/dist/cli/backend/src/services/messaging/owner-thread-sentinel.service.d.ts.map +1 -1
  84. package/dist/cli/backend/src/services/messaging/owner-thread-sentinel.service.js +38 -0
  85. package/dist/cli/backend/src/services/messaging/owner-thread-sentinel.service.js.map +1 -1
  86. package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.d.ts.map +1 -1
  87. package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.js +51 -33
  88. package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
  89. package/dist/cli/backend/src/services/worktree/low-disk-guard.d.ts +109 -0
  90. package/dist/cli/backend/src/services/worktree/low-disk-guard.d.ts.map +1 -0
  91. package/dist/cli/backend/src/services/worktree/low-disk-guard.js +148 -0
  92. package/dist/cli/backend/src/services/worktree/low-disk-guard.js.map +1 -0
  93. package/dist/cli/backend/src/services/worktree/worktree-janitor.git.d.ts +224 -0
  94. package/dist/cli/backend/src/services/worktree/worktree-janitor.git.d.ts.map +1 -0
  95. package/dist/cli/backend/src/services/worktree/worktree-janitor.git.js +449 -0
  96. package/dist/cli/backend/src/services/worktree/worktree-janitor.git.js.map +1 -0
  97. package/dist/cli/backend/src/types/slack.types.d.ts +8 -0
  98. package/dist/cli/backend/src/types/slack.types.d.ts.map +1 -1
  99. package/dist/cli/backend/src/types/slack.types.js.map +1 -1
  100. package/package.json +1 -1
@@ -27,6 +27,18 @@ export declare const FOLLOW_THROUGH_CONSTANTS: {
27
27
  readonly OUTPUT_WORK_MS: 45000;
28
28
  /** After a runtime restart the first tool call is the harness's own register-self */
29
29
  readonly TOOLS_AFTER_RESTART: 2;
30
+ /**
31
+ * Tool calls after the statement that count as having started. One is not
32
+ * enough: the reply itself is followed by housekeeping (status mark,
33
+ * memory write) that is not the promised work (Pia, 2026-10-11).
34
+ */
35
+ readonly TOOLS_TO_COUNT: 3;
36
+ /** A statement this old whose agent is quiet is checked without waiting for a turn-end event */
37
+ readonly SWEEP_AFTER_MS: 60000;
38
+ /** How often open statements are swept */
39
+ readonly SWEEP_INTERVAL_MS: 20000;
40
+ /** Quiet for this long = the agent is not mid-turn */
41
+ readonly QUIET_MS: 15000;
30
42
  };
31
43
  /** What the guard needs from the rest of the backend. */
32
44
  export interface FollowThroughDeps {
@@ -44,6 +56,12 @@ export interface FollowThroughDeps {
44
56
  waitingOnOwner?: (session: string) => Promise<boolean>;
45
57
  /** Owner-stopped or team-paused agents are never nudged */
46
58
  isHeldBack?: (session: string) => boolean;
59
+ /** The agent produced no output for {@link FOLLOW_THROUGH_CONSTANTS.QUIET_MS} (sweep only) */
60
+ isQuiet?: (session: string) => boolean;
61
+ /** Make the statement a durable WorkItem for the agent; returns its id */
62
+ commit?: (session: string, sentence: string, at: number) => Promise<string | null>;
63
+ /** The statement was answered: close its WorkItem */
64
+ settle?: (workItemId: string) => Promise<void>;
47
65
  now?: () => number;
48
66
  }
49
67
  /** What a turn end did. */
@@ -103,7 +121,15 @@ export declare class AgentFollowThroughService {
103
121
  takeIntent(agent: string): {
104
122
  sentence: string;
105
123
  at: number;
124
+ workItemId?: string;
106
125
  } | null;
126
+ /**
127
+ * Age of the agent's open stated intent.
128
+ *
129
+ * @param agent - Session
130
+ * @returns Milliseconds, or null when none is open
131
+ */
132
+ intentAgeMs(agent: string): number | null;
107
133
  /**
108
134
  * The agent's turn ended: nudge it once when it stated an intent that
109
135
  * nothing followed. Never throws.
@@ -112,6 +138,13 @@ export declare class AgentFollowThroughService {
112
138
  * @returns What happened
113
139
  */
114
140
  onTurnEnd(agent: string): Promise<TurnEndOutcome>;
141
+ /**
142
+ * Check statements whose agent went quiet without a turn-end event reaching
143
+ * us (the post can land after the turn-end settle ran). Called on a timer.
144
+ *
145
+ * @returns Agents nudged
146
+ */
147
+ sweep(): Promise<string[]>;
115
148
  /** Whether the agent did anything after the statement. */
116
149
  private followed;
117
150
  }
@@ -1 +1 @@
1
- {"version":3,"file":"follow-through.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/agent/follow-through.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"follow-through.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/agent/follow-through.service.ts"],"names":[],"mappings":"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"}
@@ -30,15 +30,28 @@ export const FOLLOW_THROUGH_CONSTANTS = {
30
30
  OUTPUT_WORK_MS: 45_000,
31
31
  /** After a runtime restart the first tool call is the harness's own register-self */
32
32
  TOOLS_AFTER_RESTART: 2,
33
+ /**
34
+ * Tool calls after the statement that count as having started. One is not
35
+ * enough: the reply itself is followed by housekeeping (status mark,
36
+ * memory write) that is not the promised work (Pia, 2026-10-11).
37
+ */
38
+ TOOLS_TO_COUNT: 3,
39
+ /** A statement this old whose agent is quiet is checked without waiting for a turn-end event */
40
+ SWEEP_AFTER_MS: 60_000,
41
+ /** How often open statements are swept */
42
+ SWEEP_INTERVAL_MS: 20_000,
43
+ /** Quiet for this long = the agent is not mid-turn */
44
+ QUIET_MS: 15_000,
33
45
  };
34
46
  /**
35
47
  * @param sentence - What the agent said
36
48
  * @returns The nudge text (harness text, English)
37
49
  */
38
50
  export function followThroughNudge(sentence) {
39
- return (`[FOLLOW-THROUGH] You told the owner you would do this now: "${sentence}". ` +
40
- 'Your turn ended without starting it. Start it now, in this turn; ' +
41
- "don't reply again until there's a result or a real blocker.");
51
+ return (`[FOLLOW-THROUGH] You told the owner you're starting this now: "${sentence}". ` +
52
+ 'Your turn ended without starting it. Start it now, in this turn. ' +
53
+ 'If you were waiting on an answer, proceed with the default you stated; a question with a default is not a reason to wait. ' +
54
+ "Don't reply again until there's a result or a real blocker.");
42
55
  }
43
56
  /**
44
57
  * Tracks the last stated intent per agent and nudges once when a turn ends
@@ -69,11 +82,42 @@ export class AgentFollowThroughService {
69
82
  return;
70
83
  const at = input.at ?? this.now();
71
84
  const found = detectStatedIntent(input.text);
85
+ const prior = this.statements.get(input.agent);
72
86
  if (found) {
73
- this.statements.set(input.agent, { at, sentence: found.sentence, nudged: false });
87
+ const stmt = {
88
+ at,
89
+ sentence: found.sentence,
90
+ nudged: false,
91
+ ...(prior?.workItemId ? { workItemId: prior.workItemId } : {}),
92
+ ...(prior?.committing ? { committing: true } : {}),
93
+ };
94
+ this.statements.set(input.agent, stmt);
95
+ // Durable: the promise becomes a WorkItem for the agent (the answer goes to the
96
+ // owner's thread), so a stop or restart does not lose it.
97
+ if (!stmt.workItemId && !stmt.committing && this.deps.commit) {
98
+ stmt.committing = true;
99
+ const agent = input.agent;
100
+ void this.deps.commit(agent, found.sentence, at).then((id) => {
101
+ // The statement may have been replaced meanwhile: attach to the live one.
102
+ const live = this.statements.get(agent);
103
+ if (id && live) {
104
+ live.workItemId = id;
105
+ live.committing = false;
106
+ }
107
+ else if (id) {
108
+ void this.deps.settle?.(id).catch(() => undefined);
109
+ }
110
+ }, () => {
111
+ const live = this.statements.get(agent);
112
+ if (live)
113
+ live.committing = false;
114
+ });
115
+ }
74
116
  return;
75
117
  }
76
118
  this.statements.delete(input.agent);
119
+ if (prior?.workItemId && !input.interim)
120
+ void this.deps.settle?.(prior.workItemId).catch(() => undefined);
77
121
  if (!input.interim)
78
122
  this.lastReplyAt.set(input.agent, at);
79
123
  }
@@ -109,7 +153,17 @@ export class AgentFollowThroughService {
109
153
  if (!s)
110
154
  return null;
111
155
  this.statements.delete(agent);
112
- return { sentence: s.sentence, at: s.at };
156
+ return { sentence: s.sentence, at: s.at, ...(s.workItemId ? { workItemId: s.workItemId } : {}) };
157
+ }
158
+ /**
159
+ * Age of the agent's open stated intent.
160
+ *
161
+ * @param agent - Session
162
+ * @returns Milliseconds, or null when none is open
163
+ */
164
+ intentAgeMs(agent) {
165
+ const s = this.statements.get(agent);
166
+ return s ? this.now() - s.at : null;
113
167
  }
114
168
  /**
115
169
  * The agent's turn ended: nudge it once when it stated an intent that
@@ -141,10 +195,10 @@ export class AgentFollowThroughService {
141
195
  if (this.deps.isHeldBack?.(agent))
142
196
  return 'held';
143
197
  // One nudge per statement; one per agent per cooldown, whatever it says next.
144
- s.nudged = true;
145
198
  const last = this.lastNudgeAt.get(agent);
146
199
  if (last !== undefined && now - last < FOLLOW_THROUGH_CONSTANTS.NUDGE_COOLDOWN_MS)
147
200
  return 'cooldown';
201
+ s.nudged = true;
148
202
  const ok = await this.deps.nudgeAgent(agent, followThroughNudge(s.sentence)).catch(() => false);
149
203
  this.logger.info('Stated intent without action — agent nudged', { agent, sentence: s.sentence, delivered: ok });
150
204
  if (!ok)
@@ -157,12 +211,31 @@ export class AgentFollowThroughService {
157
211
  return 'none';
158
212
  }
159
213
  }
214
+ /**
215
+ * Check statements whose agent went quiet without a turn-end event reaching
216
+ * us (the post can land after the turn-end settle ran). Called on a timer.
217
+ *
218
+ * @returns Agents nudged
219
+ */
220
+ async sweep() {
221
+ const out = [];
222
+ const now = this.now();
223
+ for (const [agent, s] of [...this.statements]) {
224
+ if (s.nudged || now - s.at < FOLLOW_THROUGH_CONSTANTS.SWEEP_AFTER_MS)
225
+ continue;
226
+ if (this.deps.isQuiet && !this.deps.isQuiet(agent))
227
+ continue;
228
+ if ((await this.onTurnEnd(agent)) === 'nudged')
229
+ out.push(agent);
230
+ }
231
+ return out;
232
+ }
160
233
  /** Whether the agent did anything after the statement. */
161
234
  followed(agent, s) {
162
235
  const tools = this.deps.toolStartsSince(agent, s.at);
163
236
  if (tools !== null) {
164
237
  const restarted = (this.deps.runtimeStartedAt?.(agent) ?? 0) > s.at;
165
- return tools >= (restarted ? FOLLOW_THROUGH_CONSTANTS.TOOLS_AFTER_RESTART : 1);
238
+ return tools >= FOLLOW_THROUGH_CONSTANTS.TOOLS_TO_COUNT + (restarted ? FOLLOW_THROUGH_CONSTANTS.TOOLS_AFTER_RESTART : 0);
166
239
  }
167
240
  const span = this.deps.outputSpanSince?.(agent, s.at);
168
241
  // No hooks and no output reading: cannot tell, so do not nag.
@@ -1 +1 @@
1
- {"version":3,"file":"follow-through.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/agent/follow-through.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAwB,MAAM,2BAA2B,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,qBAAqB;AACrB,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACvC,oFAAoF;IACpF,UAAU,EAAE,EAAE,GAAG,MAAM;IACvB,wEAAwE;IACxE,OAAO,EAAE,EAAE,GAAG,MAAM;IACpB,wEAAwE;IACxE,iBAAiB,EAAE,EAAE,GAAG,MAAM;IAC9B,6FAA6F;IAC7F,cAAc,EAAE,MAAM;IACtB,qFAAqF;IACrF,mBAAmB,EAAE,CAAC;CACb,CAAC;AA+BX;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAAgB;IAClD,OAAO,CACN,+DAA+D,QAAQ,KAAK;QAC5E,mEAAmE;QACnE,6DAA6D,CAC7D,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,yBAAyB;IAOR;IANZ,UAAU,GAAG,IAAI,GAAG,EAAqB,CAAC;IAC1C,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;IACxC,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;IACxC,MAAM,CAAkB;IAEzC,uCAAuC;IACvC,YAA6B,IAAuB;QAAvB,SAAI,GAAJ,IAAI,CAAmB;QACnD,IAAI,CAAC,MAAM,GAAG,aAAa,CAAC,WAAW,EAAE,CAAC,qBAAqB,CAAC,eAAe,CAAC,CAAC;IAClF,CAAC;IAEO,GAAG;QACV,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;IACrD,CAAC;IAED;;;;;OAKG;IACH,aAAa,CAAC,KAAsE;QACnF,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,KAAK,yBAAyB;YAAE,OAAO;QACtE,MAAM,EAAE,GAAG,KAAK,CAAC,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;QAClC,MAAM,KAAK,GAAG,kBAAkB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7C,IAAI,KAAK,EAAE,CAAC;YACX,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;YAClF,OAAO;QACR,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK,CAAC,OAAO;YAAE,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED;;;;;;OAMG;IACH,eAAe,CAAC,KAAa;QAC5B,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;IAED;;;;;;OAMG;IACH,WAAW,CAAC,KAAa;QACxB,MAAM,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACrC,OAAO,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,EAAE,IAAI,wBAAwB,CAAC,OAAO,CAAC;IACrE,CAAC;IAED;;;;;OAKG;IACH,UAAU,CAAC,KAAa;QACvB,MAAM,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QACpB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC9B,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;IAC3C,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,SAAS,CAAC,KAAa;QAC5B,IAAI,CAAC;YACJ,MAAM,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACrC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM;gBAAE,OAAO,MAAM,CAAC;YAClC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,IAAI,GAAG,GAAG,CAAC,CAAC,EAAE,GAAG,wBAAwB,CAAC,UAAU,EAAE,CAAC;gBACtD,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC9B,OAAO,OAAO,CAAC;YAChB,CAAC;YACD,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC;gBAC7B,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC9B,OAAO,QAAQ,CAAC;YACjB,CAAC;YACD,IAAI,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;gBACxE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC9B,OAAO,YAAY,CAAC;YACrB,CAAC;YACD,IAAI,MAAM,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC;gBAAE,OAAO,SAAS,CAAC;YACjF,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC;gBAAE,OAAO,MAAM,CAAC;YACjD,8EAA8E;YAC9E,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC;YAChB,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACzC,IAAI,IAAI,KAAK,SAAS,IAAI,GAAG,GAAG,IAAI,GAAG,wBAAwB,CAAC,iBAAiB;gBAAE,OAAO,UAAU,CAAC;YACrG,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC;YAChG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,6CAA6C,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC;YAChH,IAAI,CAAC,EAAE;gBAAE,OAAO,eAAe,CAAC;YAChC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YACjC,OAAO,QAAQ,CAAC;QACjB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,yCAAyC,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACjI,OAAO,MAAM,CAAC;QACf,CAAC;IACF,CAAC;IAED,0DAA0D;IAClD,QAAQ,CAAC,KAAa,EAAE,CAAY;QAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;QACrD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACpB,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACpE,OAAO,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,wBAAwB,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAChF,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;QACtD,8DAA8D;QAC9D,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC;QACrD,OAAO,IAAI,IAAI,wBAAwB,CAAC,cAAc,CAAC;IACxD,CAAC;CACD;AAED,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,IAAI,QAAQ,GAAqC,IAAI,CAAC;AAEtD,4EAA4E;AAC5E,MAAM,UAAU,gBAAgB;IAC/B,OAAO,QAAQ,CAAC;AACjB,CAAC;AAED,yDAAyD;AACzD,MAAM,UAAU,gBAAgB,CAAC,OAAyC;IACzE,QAAQ,GAAG,OAAO,CAAC;AACpB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,+BAA+B,CAAC,KAAyD;IACxG,IAAI,CAAC;QACJ,QAAQ,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACR,iBAAiB;IAClB,CAAC;AACF,CAAC"}
1
+ {"version":3,"file":"follow-through.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/agent/follow-through.service.ts"],"names":[],"mappings":"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"}
@@ -36,6 +36,30 @@ export interface FollowThroughWiringDeps {
36
36
  * @returns The guard, or null when switched off
37
37
  */
38
38
  export declare function createFollowThrough(deps: FollowThroughWiringDeps): AgentFollowThroughService | null;
39
+ /** Metadata marker on WorkItems made for a stated intent. */
40
+ export declare const STATED_INTENT_MARKER = "stated-intent";
41
+ /**
42
+ * Make "I'm starting X now" a WorkItem for the agent, so it survives a stop or
43
+ * restart. Created with the agent as creator, so the answer goes to the owner
44
+ * thread the agent is in (the pool stamps the origin). One open item per agent.
45
+ *
46
+ * @param session - The agent
47
+ * @param sentence - What it said
48
+ * @returns The WorkItem id, or null when none could be made
49
+ */
50
+ export declare function commitStatedIntent(session: string, sentence: string): Promise<string | null>;
51
+ /**
52
+ * @param sentence - What the agent told the owner
53
+ * @returns The brief put on the promise's WorkItem (harness text)
54
+ */
55
+ export declare function stateIntentBrief(sentence: string): string;
56
+ /**
57
+ * The promise was answered: close its WorkItem (queued ones are cancelled,
58
+ * started ones completed). Never throws.
59
+ *
60
+ * @param workItemId - The promise's WorkItem
61
+ */
62
+ export declare function settleStatedIntent(workItemId: string): Promise<void>;
39
63
  /**
40
64
  * End of an agent's turn: nudge a stated intent nothing followed, give an
41
65
  * unanswered owner ticket a WorkItem, then (the caller) submit answered
@@ -51,6 +75,16 @@ export declare function idleWorkGuardDeps(): IdleWorkGuardDeps;
51
75
  export declare function idlePendingWorkCheck(): (session: string) => Promise<string | null>;
52
76
  /** Seams of the work release on the real services. */
53
77
  export declare function releaseWorkDeps(): ReleaseWorkDeps;
78
+ /**
79
+ * After an agent that owes work was stopped for memory: build the reminder it
80
+ * gets when it is brought back, from the WorkItems queued for it. Null when
81
+ * nothing is queued for it.
82
+ *
83
+ * @param items - Pool items
84
+ * @param session - The stopped agent
85
+ * @returns Reminder text, or null
86
+ */
87
+ export declare function owedWorkReminder(items: readonly WorkItem[], session: string): string | null;
54
88
  /**
55
89
  * Release what a stopping agent holds (idle stop under pressure, emergency stop).
56
90
  *
@@ -1 +1 @@
1
- {"version":3,"file":"follow-through.wiring.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/agent/follow-through.wiring.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,mCAAmC,CAAC;AAYlF,OAAO,EAAE,yBAAyB,EAAsC,MAAM,6BAA6B,CAAC;AAC5G,OAAO,EAAkC,KAAK,iBAAiB,EAAE,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAIpH;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAOlG;AAED,uDAAuD;AACvD,MAAM,WAAW,uBAAuB;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CAC9E;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,uBAAuB,GAAG,yBAAyB,GAAG,IAAI,CAqBnG;AAID;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqBxE;AAED,yDAAyD;AACzD,wBAAgB,iBAAiB,IAAI,iBAAiB,CAOrD;AAED,gEAAgE;AAChE,wBAAgB,oBAAoB,IAAI,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAElF;AAED,sDAAsD;AACtD,wBAAgB,eAAe,IAAI,eAAe,CAsBjD;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAElF"}
1
+ {"version":3,"file":"follow-through.wiring.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/agent/follow-through.wiring.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAA+C,KAAK,QAAQ,EAAE,MAAM,mCAAmC,CAAC;AAY/G,OAAO,EAAE,yBAAyB,EAAgE,MAAM,6BAA6B,CAAC;AACtI,OAAO,EAAkC,KAAK,iBAAiB,EAAE,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAIpH;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAYlG;AAED,uDAAuD;AACvD,MAAM,WAAW,uBAAuB;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CAC9E;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,uBAAuB,GAAG,yBAAyB,GAAG,IAAI,CA8BnG;AAID,6DAA6D;AAC7D,eAAO,MAAM,oBAAoB,kBAAkB,CAAC;AAEpD;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAgBlG;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAKzD;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAO1E;AAID;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqBxE;AAED,yDAAyD;AACzD,wBAAgB,iBAAiB,IAAI,iBAAiB,CAWrD;AAED,gEAAgE;AAChE,wBAAgB,oBAAoB,IAAI,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAElF;AAED,sDAAsD;AACtD,wBAAgB,eAAe,IAAI,eAAe,CAsCjD;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQ3F;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAElF"}
@@ -7,7 +7,7 @@
7
7
  * @see specs/2026-10-10-agent-follow-through.md
8
8
  */
9
9
  import { PROJECT_TICKET_CONSTANTS } from '../../constants.js';
10
- import { createWorkItem } from '../../types/v2/work-item.types.js';
10
+ import { createWorkItem, TERMINAL_WORK_ITEM_STATUSES } from '../../types/v2/work-item.types.js';
11
11
  import { LoggerService } from '../core/logger.service.js';
12
12
  import { RequestService } from '../v3/request.service.js';
13
13
  import { getTicketReviewService } from '../v3/ticket-review.service.js';
@@ -19,7 +19,7 @@ import { AgentTurnStateService } from '../monitoring/agent-turn-state.js';
19
19
  import { isOwnerStopped } from './owner-stopped.registry.js';
20
20
  import { pausedTeamOfSession } from '../team/team-pause.registry.js';
21
21
  import { PtyActivityTrackerService } from './pty-activity-tracker.service.js';
22
- import { AgentFollowThroughService, getFollowThrough, setFollowThrough } from './follow-through.service.js';
22
+ import { AgentFollowThroughService, FOLLOW_THROUGH_CONSTANTS, getFollowThrough, setFollowThrough } from './follow-through.service.js';
23
23
  import { holdReasonFor, releaseHeldWork } from './idle-work-guard.js';
24
24
  const logger = LoggerService.getInstance().createComponentLogger('FollowThroughWiring');
25
25
  /**
@@ -36,9 +36,14 @@ export function handedOffSince(items, session, since) {
36
36
  return items.some((wi) => {
37
37
  if (Date.parse(wi.createdAt) < since)
38
38
  return false;
39
- if (wi.target === session)
40
- return true;
41
39
  const m = (wi.metadata ?? {});
40
+ if (wi.target === session) {
41
+ // An item the harness queued for the agent (the promise's own WorkItem,
42
+ // a ticket's) is not the agent starting: it waits until the agent does.
43
+ const waiting = wi.status === 'queued' || wi.status === 'proposed' || wi.status === 'scheduled' || wi.status === 'blocked';
44
+ if (!(waiting && typeof m['harnessCreated'] === 'string'))
45
+ return true;
46
+ }
42
47
  return m['delegatedBy'] === session || m['createdBy'] === session || m[PROJECT_TICKET_CONSTANTS.DELEGATION_CALLER_METADATA_KEY] === session;
43
48
  });
44
49
  }
@@ -69,10 +74,71 @@ export function createFollowThrough(deps) {
69
74
  return open.length > 0;
70
75
  },
71
76
  isHeldBack: (session) => isOwnerStopped(session) || !!pausedTeamOfSession(session),
77
+ isQuiet: (session) => !tracker.hasActivity(session) || tracker.getIdleTimeMs(session) >= FOLLOW_THROUGH_CONSTANTS.QUIET_MS,
78
+ commit: (session, sentence) => commitStatedIntent(session, sentence),
79
+ settle: (workItemId) => settleStatedIntent(workItemId),
72
80
  });
73
81
  setFollowThrough(service);
82
+ // A post can land after the turn-end settle ran: sweep quiet agents too.
83
+ if (sweepTimer)
84
+ clearInterval(sweepTimer);
85
+ sweepTimer = setInterval(() => {
86
+ void service.sweep().catch(() => undefined);
87
+ }, FOLLOW_THROUGH_CONSTANTS.SWEEP_INTERVAL_MS);
88
+ sweepTimer.unref?.();
74
89
  return service;
75
90
  }
91
+ let sweepTimer = null;
92
+ /** Metadata marker on WorkItems made for a stated intent. */
93
+ export const STATED_INTENT_MARKER = 'stated-intent';
94
+ /**
95
+ * Make "I'm starting X now" a WorkItem for the agent, so it survives a stop or
96
+ * restart. Created with the agent as creator, so the answer goes to the owner
97
+ * thread the agent is in (the pool stamps the origin). One open item per agent.
98
+ *
99
+ * @param session - The agent
100
+ * @param sentence - What it said
101
+ * @returns The WorkItem id, or null when none could be made
102
+ */
103
+ export async function commitStatedIntent(session, sentence) {
104
+ const pool = TaskPoolService.getInstance();
105
+ const open = (await pool.getAllItems()).find((wi) => wi.target === session && wi.metadata?.['harnessCreated'] === STATED_INTENT_MARKER && !TERMINAL_WORK_ITEM_STATUSES.has(wi.status));
106
+ if (open)
107
+ return open.id;
108
+ const wi = createWorkItem({
109
+ type: 'delegate',
110
+ owner: 'agent',
111
+ target: session,
112
+ title: `Follow through: ${sentence.slice(0, 70)}`,
113
+ description: stateIntentBrief(sentence),
114
+ metadata: { harnessCreated: STATED_INTENT_MARKER },
115
+ });
116
+ await pool.addToPool(wi, { creatorSession: session });
117
+ return wi.id;
118
+ }
119
+ /**
120
+ * @param sentence - What the agent told the owner
121
+ * @returns The brief put on the promise's WorkItem (harness text)
122
+ */
123
+ export function stateIntentBrief(sentence) {
124
+ return (`You told the owner: "${sentence}". Do it now, and reply in the owner's thread when there is a result or a real blocker. ` +
125
+ 'If you asked a question and stated a default, go ahead with the default.');
126
+ }
127
+ /**
128
+ * The promise was answered: close its WorkItem (queued ones are cancelled,
129
+ * started ones completed). Never throws.
130
+ *
131
+ * @param workItemId - The promise's WorkItem
132
+ */
133
+ export async function settleStatedIntent(workItemId) {
134
+ const pool = TaskPoolService.getInstance();
135
+ try {
136
+ await pool.cancelQueued(workItemId, 'answered by the agent', { cancelledBy: 'system' });
137
+ }
138
+ catch {
139
+ await pool.completeSimpleItem(workItemId, 'system').catch(() => undefined);
140
+ }
141
+ }
76
142
  const settling = new Set();
77
143
  /**
78
144
  * End of an agent's turn: nudge a stated intent nothing followed, give an
@@ -115,6 +181,10 @@ export function idleWorkGuardDeps() {
115
181
  listTickets: () => RequestService.getInstance().listAll(),
116
182
  owesOwner: (session) => getOwnerThreadSentinel()?.owesOwner(session) ?? false,
117
183
  holdsIntent: (session) => getFollowThrough()?.holdsIntent(session) ?? false,
184
+ owedAgeMs: (session) => {
185
+ const ages = [getOwnerThreadSentinel()?.owedAgeMs(session) ?? null, getFollowThrough()?.intentAgeMs(session) ?? null].filter((a) => a !== null);
186
+ return ages.length > 0 ? Math.min(...ages) : null;
187
+ },
118
188
  };
119
189
  }
120
190
  /** The idle check's pending-work check on the real services. */
@@ -131,6 +201,9 @@ export function releaseWorkDeps() {
131
201
  const intent = getFollowThrough()?.takeIntent(session);
132
202
  if (!intent)
133
203
  return null;
204
+ // Already a WorkItem since the statement: nothing more to park.
205
+ if (intent.workItemId)
206
+ return intent.workItemId;
134
207
  const wi = createWorkItem({
135
208
  type: 'delegate',
136
209
  owner: 'system',
@@ -143,8 +216,40 @@ export function releaseWorkDeps() {
143
216
  await pool.addToPool(wi, { creatorSession: session });
144
217
  return wi.id;
145
218
  },
219
+ parkPromise: async (session) => {
220
+ const text = getOwnerThreadSentinel()?.promiseText(session);
221
+ if (!text)
222
+ return null;
223
+ const wi = createWorkItem({
224
+ type: 'delegate',
225
+ owner: 'system',
226
+ target: session,
227
+ title: `Follow through: ${text.slice(0, 70)}`,
228
+ description: `You promised the owner: "${text}". Crewly stopped you (memory) before you delivered. Deliver it; reply in the owner's thread with the result or a real blocker.`,
229
+ metadata: { harnessCreated: 'owner-promise' },
230
+ });
231
+ await pool.addToPool(wi, { creatorSession: session });
232
+ return wi.id;
233
+ },
146
234
  };
147
235
  }
236
+ /**
237
+ * After an agent that owes work was stopped for memory: build the reminder it
238
+ * gets when it is brought back, from the WorkItems queued for it. Null when
239
+ * nothing is queued for it.
240
+ *
241
+ * @param items - Pool items
242
+ * @param session - The stopped agent
243
+ * @returns Reminder text, or null
244
+ */
245
+ export function owedWorkReminder(items, session) {
246
+ const queued = items.filter((wi) => wi.target === session && wi.status === 'queued');
247
+ if (queued.length === 0)
248
+ return null;
249
+ const lines = queued.slice(0, 5).map((wi) => `- ${wi.title}`);
250
+ return ('[FOLLOW-THROUGH] You were stopped to free memory while you still owed the owner this. It is still yours; start it now and reply in the owner thread with the result:\n' +
251
+ lines.join('\n'));
252
+ }
148
253
  /**
149
254
  * Release what a stopping agent holds (idle stop under pressure, emergency stop).
150
255
  *
@@ -1 +1 @@
1
- {"version":3,"file":"follow-through.wiring.js","sourceRoot":"","sources":["../../../../../../backend/src/services/agent/follow-through.wiring.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"follow-through.wiring.js","sourceRoot":"","sources":["../../../../../../backend/src/services/agent/follow-through.wiring.ts"],"names":[],"mappings":"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"}
@@ -42,6 +42,7 @@ export declare class IdleDetectionService {
42
42
  private agentRegistrationService;
43
43
  private pendingWorkCheck;
44
44
  private workReleaser;
45
+ private owedStopHook;
45
46
  private isChecking;
46
47
  private lastTickStartedAt;
47
48
  private lastTickCompletedAt;
@@ -147,7 +148,15 @@ export declare class IdleDetectionService {
147
148
  * @param sessionName - Agent session
148
149
  * @returns A reason, or null when nothing holds it or the check fails
149
150
  */
151
+ /**
152
+ * Inject what happens after an agent that still owed work was stopped for
153
+ * memory: it is brought back when a slot frees (the work is already queued).
154
+ *
155
+ * @param hook - Called once per such stop, or null
156
+ */
157
+ setOwedStopHook(hook: ((sessionName: string) => void) | null): void;
150
158
  private holdReason;
159
+ private runOwedStopHook;
151
160
  /** Put the work a stopping agent holds back in the queue (best-effort). */
152
161
  private releaseWork;
153
162
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"idle-detection.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/agent/idle-detection.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAaH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAChF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAKxE;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,EAAE,WAAW,CAAC,cAAc,CAA0E,CAAC;AAEzI;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,GAAG,MAAM,GAAG,IAAI,CAAC,CAAC;AAEzF;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAElF;;;;;;;GAOG;AACH,qBAAa,oBAAoB;IAChC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAqC;IAC5D,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,KAAK,CAA+C;IAC5D,OAAO,CAAC,wBAAwB,CAAyC;IACzE,OAAO,CAAC,gBAAgB,CAAiC;IACzD,OAAO,CAAC,YAAY,CAA6B;IAIjD,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,iBAAiB,CAAuB;IAChD,OAAO,CAAC,mBAAmB,CAAuB;IAClD,OAAO,CAAC,kBAAkB,CAAuB;IACjD,OAAO,CAAC,uBAAuB,CAAK;IACpC,OAAO,CAAC,gBAAgB,CAAK;IAE7B,OAAO;IAIP;;;;OAIG;IACH,2BAA2B,CAAC,OAAO,EAAE,wBAAwB,GAAG,IAAI;IAIpE;;;;;OAKG;IACH,mBAAmB,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,GAAG,IAAI;IAIzD;;;;;OAKG;IACH,eAAe,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI,GAAG,IAAI;IAIpD;;;;OAIG;IACH,MAAM,CAAC,WAAW,IAAI,oBAAoB;IAO1C;;OAEG;IACH,MAAM,CAAC,aAAa,IAAI,IAAI;IAO5B;;OAEG;IACH,KAAK,IAAI,IAAI;IAeb;;;;;;;;;;OAUG;IACH,OAAO,CAAC,OAAO;IA2Ef;;;;;OAKG;IACH,QAAQ,IAAI;QACX,SAAS,EAAE,OAAO,CAAC;QACnB,UAAU,EAAE,OAAO,CAAC;QACpB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;QACjC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;QACnC,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;QAClC,uBAAuB,EAAE,MAAM,CAAC;QAChC,gBAAgB,EAAE,MAAM,CAAC;KACzB;IAYD;;OAEG;IACH,IAAI,IAAI,IAAI;IAQZ;;;;OAIG;IACH,SAAS,IAAI,OAAO;IAIpB,4CAA4C;IAC5C,WAAW,EAAE,MAAM;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,gBAAgB,CAAC,EAAE,OAAO,CAAC;KAC3B,CAAkB;IAEnB;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IAIrB;;;;OAIG;IACG,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAoOnC;;;;;OAKG;YACW,UAAU;IAWxB,2EAA2E;YAC7D,WAAW;IAQzB;;;;;;;;OAQG;YACW,kBAAkB;IAehC;;;;;;;;OAQG;IACG,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC;CAyE5C"}
1
+ {"version":3,"file":"idle-detection.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/agent/idle-detection.service.ts"],"names":[],"mappings":"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"}
@@ -43,6 +43,7 @@ export class IdleDetectionService {
43
43
  agentRegistrationService = null;
44
44
  pendingWorkCheck = null;
45
45
  workReleaser = null;
46
+ owedStopHook = null;
46
47
  // Observability: surfaces silent hangs that previously caused the
47
48
  // loop to "stop" for hours with no log evidence (2026-05-14 incident).
48
49
  isChecking = false;
@@ -390,7 +391,9 @@ export class IdleDetectionService {
390
391
  // pressure mode, where memory wins; then the work is put back
391
392
  // in the queue first so the next start redelivers it.
392
393
  const held = await this.holdReason(member.sessionName);
393
- if (held && !pressure) {
394
+ // A promise made to the owner minutes ago is spared even under
395
+ // pressure; only the emergency stop overrides it.
396
+ if (held === 'fresh_promise' || (held && !pressure)) {
394
397
  this.logger.info('Agent idle but has queued work, keeping alive', {
395
398
  sessionName: member.sessionName,
396
399
  role: member.role,
@@ -418,6 +421,8 @@ export class IdleDetectionService {
418
421
  await this.agentRegistrationService.terminateAgentSession(member.sessionName, member.role);
419
422
  await StorageService.getInstance().updateAgentStatus(member.sessionName, CREWLY_CONSTANTS.AGENT_STATUSES.INACTIVE, 'idle_exit');
420
423
  reportOwnerThreadBlocking(member.sessionName, { kind: 'stopped', why: 'idle' });
424
+ if (held)
425
+ this.runOwedStopHook(member.sessionName);
421
426
  }
422
427
  catch (err) {
423
428
  this.logger.error('Failed to stop idle agent', {
@@ -454,6 +459,15 @@ export class IdleDetectionService {
454
459
  * @param sessionName - Agent session
455
460
  * @returns A reason, or null when nothing holds it or the check fails
456
461
  */
462
+ /**
463
+ * Inject what happens after an agent that still owed work was stopped for
464
+ * memory: it is brought back when a slot frees (the work is already queued).
465
+ *
466
+ * @param hook - Called once per such stop, or null
467
+ */
468
+ setOwedStopHook(hook) {
469
+ this.owedStopHook = hook;
470
+ }
457
471
  async holdReason(sessionName) {
458
472
  if (!this.pendingWorkCheck)
459
473
  return null;
@@ -467,6 +481,14 @@ export class IdleDetectionService {
467
481
  return null;
468
482
  }
469
483
  }
484
+ runOwedStopHook(sessionName) {
485
+ try {
486
+ this.owedStopHook?.(sessionName);
487
+ }
488
+ catch {
489
+ /* best-effort */
490
+ }
491
+ }
470
492
  /** Put the work a stopping agent holds back in the queue (best-effort). */
471
493
  async releaseWork(sessionName, why) {
472
494
  try {
@@ -557,6 +579,7 @@ export class IdleDetectionService {
557
579
  PtyActivityTrackerService.getInstance().clearSession(member.sessionName);
558
580
  await StorageService.getInstance().updateAgentStatus(member.sessionName, CREWLY_CONSTANTS.AGENT_STATUSES.INACTIVE, 'idle_exit_pressure');
559
581
  reportOwnerThreadBlocking(member.sessionName, { kind: 'stopped', why: 'pressure' });
582
+ this.runOwedStopHook(member.sessionName);
560
583
  stoppedCount++;
561
584
  }
562
585
  catch (err) {