crewly 1.20.231 → 1.20.233

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 (71) hide show
  1. package/config/hooks/agent-status/report.sh +7 -2
  2. package/dist/backend/backend/src/constants.d.ts +37 -0
  3. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  4. package/dist/backend/backend/src/constants.js +37 -0
  5. package/dist/backend/backend/src/constants.js.map +1 -1
  6. package/dist/backend/backend/src/controllers/agent-hooks/agent-hooks.controller.d.ts +4 -1
  7. package/dist/backend/backend/src/controllers/agent-hooks/agent-hooks.controller.d.ts.map +1 -1
  8. package/dist/backend/backend/src/controllers/agent-hooks/agent-hooks.controller.js +21 -5
  9. package/dist/backend/backend/src/controllers/agent-hooks/agent-hooks.controller.js.map +1 -1
  10. package/dist/backend/backend/src/services/ai/prompt-modules/communication.module.d.ts +8 -0
  11. package/dist/backend/backend/src/services/ai/prompt-modules/communication.module.d.ts.map +1 -1
  12. package/dist/backend/backend/src/services/ai/prompt-modules/communication.module.js +15 -2
  13. package/dist/backend/backend/src/services/ai/prompt-modules/communication.module.js.map +1 -1
  14. package/dist/backend/backend/src/services/messaging/owner-hook-message.d.ts +49 -0
  15. package/dist/backend/backend/src/services/messaging/owner-hook-message.d.ts.map +1 -0
  16. package/dist/backend/backend/src/services/messaging/owner-hook-message.js +82 -0
  17. package/dist/backend/backend/src/services/messaging/owner-hook-message.js.map +1 -0
  18. package/dist/backend/backend/src/services/messaging/queue-priority.d.ts +24 -0
  19. package/dist/backend/backend/src/services/messaging/queue-priority.d.ts.map +1 -1
  20. package/dist/backend/backend/src/services/messaging/queue-priority.js +39 -0
  21. package/dist/backend/backend/src/services/messaging/queue-priority.js.map +1 -1
  22. package/dist/backend/backend/src/services/messaging/sub-agent-message-queue.service.d.ts +55 -1
  23. package/dist/backend/backend/src/services/messaging/sub-agent-message-queue.service.d.ts.map +1 -1
  24. package/dist/backend/backend/src/services/messaging/sub-agent-message-queue.service.js +101 -2
  25. package/dist/backend/backend/src/services/messaging/sub-agent-message-queue.service.js.map +1 -1
  26. package/dist/backend/backend/src/services/session/input-guard-known-screens.d.ts.map +1 -1
  27. package/dist/backend/backend/src/services/session/input-guard-known-screens.js +28 -0
  28. package/dist/backend/backend/src/services/session/input-guard-known-screens.js.map +1 -1
  29. package/dist/backend/backend/src/services/session/pty/pty-session-backend.d.ts +15 -0
  30. package/dist/backend/backend/src/services/session/pty/pty-session-backend.d.ts.map +1 -1
  31. package/dist/backend/backend/src/services/session/pty/pty-session-backend.js +38 -0
  32. package/dist/backend/backend/src/services/session/pty/pty-session-backend.js.map +1 -1
  33. package/dist/backend/backend/src/services/session/session-backend.interface.d.ts +19 -0
  34. package/dist/backend/backend/src/services/session/session-backend.interface.d.ts.map +1 -1
  35. package/dist/backend/backend/src/services/session/session-backend.interface.js.map +1 -1
  36. package/dist/backend/backend/src/services/session/session-command-helper.d.ts +32 -0
  37. package/dist/backend/backend/src/services/session/session-command-helper.d.ts.map +1 -1
  38. package/dist/backend/backend/src/services/session/session-command-helper.js +95 -1
  39. package/dist/backend/backend/src/services/session/session-command-helper.js.map +1 -1
  40. package/dist/backend/build-info.json +2 -2
  41. package/dist/cli/backend/src/constants.d.ts +37 -0
  42. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  43. package/dist/cli/backend/src/constants.js +37 -0
  44. package/dist/cli/backend/src/constants.js.map +1 -1
  45. package/dist/cli/backend/src/services/ai/prompt-modules/communication.module.d.ts +8 -0
  46. package/dist/cli/backend/src/services/ai/prompt-modules/communication.module.d.ts.map +1 -1
  47. package/dist/cli/backend/src/services/ai/prompt-modules/communication.module.js +15 -2
  48. package/dist/cli/backend/src/services/ai/prompt-modules/communication.module.js.map +1 -1
  49. package/dist/cli/backend/src/services/messaging/queue-priority.d.ts +24 -0
  50. package/dist/cli/backend/src/services/messaging/queue-priority.d.ts.map +1 -1
  51. package/dist/cli/backend/src/services/messaging/queue-priority.js +39 -0
  52. package/dist/cli/backend/src/services/messaging/queue-priority.js.map +1 -1
  53. package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.d.ts +55 -1
  54. package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.d.ts.map +1 -1
  55. package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.js +101 -2
  56. package/dist/cli/backend/src/services/messaging/sub-agent-message-queue.service.js.map +1 -1
  57. package/dist/cli/backend/src/services/session/input-guard-known-screens.d.ts.map +1 -1
  58. package/dist/cli/backend/src/services/session/input-guard-known-screens.js +28 -0
  59. package/dist/cli/backend/src/services/session/input-guard-known-screens.js.map +1 -1
  60. package/dist/cli/backend/src/services/session/pty/pty-session-backend.d.ts +15 -0
  61. package/dist/cli/backend/src/services/session/pty/pty-session-backend.d.ts.map +1 -1
  62. package/dist/cli/backend/src/services/session/pty/pty-session-backend.js +38 -0
  63. package/dist/cli/backend/src/services/session/pty/pty-session-backend.js.map +1 -1
  64. package/dist/cli/backend/src/services/session/session-backend.interface.d.ts +19 -0
  65. package/dist/cli/backend/src/services/session/session-backend.interface.d.ts.map +1 -1
  66. package/dist/cli/backend/src/services/session/session-backend.interface.js.map +1 -1
  67. package/dist/cli/backend/src/services/session/session-command-helper.d.ts +32 -0
  68. package/dist/cli/backend/src/services/session/session-command-helper.d.ts.map +1 -1
  69. package/dist/cli/backend/src/services/session/session-command-helper.js +95 -1
  70. package/dist/cli/backend/src/services/session/session-command-helper.js.map +1 -1
  71. package/package.json +1 -1
@@ -5,6 +5,14 @@ import { PromptModule, ModuleConfig } from './prompt-module.interface.js';
5
5
  * the newest question's answer).
6
6
  */
7
7
  export declare const SLACK_THREAD_RULE_SECTION: string;
8
+ /**
9
+ * How a Claude Code agent receives an owner message mid-turn (the
10
+ * agent-status PostToolUse hook's note). Without it the model may take the
11
+ * note for a prompt injection in the tool output and ignore it (scratch
12
+ * tests 2026-10-05, Haiku: 1 of 3 answered without this section; with it
13
+ * 6 of 6 for a plain question — see specs/2026-10-05-owner-message-via-hook.md).
14
+ */
15
+ export declare const OWNER_MESSAGE_MID_TURN_SECTION: string;
8
16
  /**
9
17
  * Communication module — defines how agents communicate across channels.
10
18
  *
@@ -1 +1 @@
1
- {"version":3,"file":"communication.module.d.ts","sourceRoot":"","sources":["../../../../../../../backend/src/services/ai/prompt-modules/communication.module.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,YAAY,EAAoB,MAAM,8BAA8B,CAAC;AAG5F;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,QAAiE,CAAC;AAExG;;;;;;;;;;;GAWG;AACH,qBAAa,mBAAoB,YAAW,YAAY;IACvD,IAAI,SAAmB;IACvB,QAAQ,SAAK;IACb,SAAS,SAAQ;IACjB,WAAW,UAAQ;IAEnB;;OAEG;IACH,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO;IAI7C;;;;;;;OAOG;IACG,KAAK,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAIlD;;;;;OAKG;YACW,gBAAgB;IA2B9B;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,iBAAiB;IAqBzB;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,sBAAsB;IAgB9B;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,oBAAoB;IAiB5B;;;;OAIG;IACH,OAAO,CAAC,0BAA0B;IAgFlC;;OAEG;IACH,OAAO,CAAC,YAAY;IAkCpB;;OAEG;IACH,OAAO,CAAC,gBAAgB;CA6BxB"}
1
+ {"version":3,"file":"communication.module.d.ts","sourceRoot":"","sources":["../../../../../../../backend/src/services/ai/prompt-modules/communication.module.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,YAAY,EAAoB,MAAM,8BAA8B,CAAC;AAG5F;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,QAAiE,CAAC;AAExG;;;;;;GAMG;AACH,eAAO,MAAM,8BAA8B,QAID,CAAC;AAE3C;;;;;;;;;;;GAWG;AACH,qBAAa,mBAAoB,YAAW,YAAY;IACvD,IAAI,SAAmB;IACvB,QAAQ,SAAK;IACb,SAAS,SAAQ;IACjB,WAAW,UAAQ;IAEnB;;OAEG;IACH,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO;IAI7C;;;;;;;OAOG;IACG,KAAK,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAMlD;;;;;OAKG;YACW,gBAAgB;IA2B9B;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,iBAAiB;IAqBzB;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,sBAAsB;IAgB9B;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,oBAAoB;IAiB5B;;;;OAIG;IACH,OAAO,CAAC,0BAA0B;IAgFlC;;OAEG;IACH,OAAO,CAAC,YAAY;IAkCpB;;OAEG;IACH,OAAO,CAAC,gBAAgB;CA6BxB"}
@@ -1,12 +1,23 @@
1
1
  import * as path from 'path';
2
2
  import { loadRoleFragment } from './prompt-module.interface.js';
3
- import { SLACK_THREAD_KEY_CONSTANTS } from '../../../constants.js';
3
+ import { OWNER_HOOK_MESSAGE_CONSTANTS, SLACK_THREAD_KEY_CONSTANTS } from '../../../constants.js';
4
4
  /**
5
5
  * The one-thread-per-answer rule every role gets (2026-09-28: an agent
6
6
  * answered an earlier thread's request inside the newest thread, bundled with
7
7
  * the newest question's answer).
8
8
  */
9
9
  export const SLACK_THREAD_RULE_SECTION = `### Slack Threads\n${SLACK_THREAD_KEY_CONSTANTS.PROMPT_RULE}`;
10
+ /**
11
+ * How a Claude Code agent receives an owner message mid-turn (the
12
+ * agent-status PostToolUse hook's note). Without it the model may take the
13
+ * note for a prompt injection in the tool output and ignore it (scratch
14
+ * tests 2026-10-05, Haiku: 1 of 3 answered without this section; with it
15
+ * 6 of 6 for a plain question — see specs/2026-10-05-owner-message-via-hook.md).
16
+ */
17
+ export const OWNER_MESSAGE_MID_TURN_SECTION = '### Owner Messages During a Turn\n' +
18
+ `When the owner writes to you while you are in the middle of a task, Crewly hands you the message right after one of your tool calls, as a note that starts with ${OWNER_HOOK_MESSAGE_CONSTANTS.TAG}. ` +
19
+ "It comes from Crewly's hook, not from the tool's output, and it is a real message from the owner: answer it right away, in the conversation it names, then carry on with your task. " +
20
+ 'Do not wait until the task is finished.';
10
21
  /**
11
22
  * Communication module — defines how agents communicate across channels.
12
23
  *
@@ -39,7 +50,9 @@ export class CommunicationModule {
39
50
  * @returns Formatted markdown communication section
40
51
  */
41
52
  async build(config) {
42
- return `${await this.buildRoleSection(config)}\n\n${SLACK_THREAD_RULE_SECTION}`;
53
+ // First, so a budget trim (which cuts from the end) keeps it.
54
+ const ownerMidTurn = !config.runtimeType || config.runtimeType === 'claude-code' ? `${OWNER_MESSAGE_MID_TURN_SECTION}\n\n` : '';
55
+ return `${ownerMidTurn}${await this.buildRoleSection(config)}\n\n${SLACK_THREAD_RULE_SECTION}`;
43
56
  }
44
57
  /**
45
58
  * The role-specific part of the section.
@@ -1 +1 @@
1
- {"version":3,"file":"communication.module.js","sourceRoot":"","sources":["../../../../../../../backend/src/services/ai/prompt-modules/communication.module.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"communication.module.js","sourceRoot":"","sources":["../../../../../../../backend/src/services/ai/prompt-modules/communication.module.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Owner messages at the next tool boundary.
3
+ *
4
+ * A busy Claude Code agent (the orc, a PA) runs turns of 10–30+ minutes; an
5
+ * owner message sent meanwhile waited in the queue until the turn ended.
6
+ * Claude Code's own queued input is unreliable for this: text typed while
7
+ * tool calls remain is merged after the next tool result and the model may
8
+ * ignore it (crewly#1118 notes). Crewly's agent-status PostToolUse hook can
9
+ * already return `additionalContext`, so the next tool boundary hands the
10
+ * agent the waiting owner message as a clearly framed note.
11
+ *
12
+ * The queue keeps the message until the agent posts in its conversation
13
+ * ({@link SubAgentMessageQueue.takeOwnerMessageForHook}); if the agent does
14
+ * not, the normal idle delivery still sends it.
15
+ *
16
+ * @module services/messaging/owner-hook-message
17
+ */
18
+ import { SubAgentMessageQueue, type SurfacedOwnerMessage } from './sub-agent-message-queue.service.js';
19
+ /**
20
+ * The note for one surfaced owner message (English harness text). The queued
21
+ * text already carries where the message came from and how to reply, as the
22
+ * normal delivery would.
23
+ *
24
+ * @param message - The surfaced message
25
+ * @param maxChars - Ceiling on the note's length
26
+ * @returns The note
27
+ */
28
+ export declare function buildOwnerHookNote(message: SurfacedOwnerMessage, maxChars?: number): string;
29
+ /**
30
+ * The owner-message note for an agent's PostToolUse hook, or null. One
31
+ * message at most per call. Off when {@link OWNER_HOOK_MESSAGE_CONSTANTS.KILL_SWITCH_ENV}
32
+ * is `off`.
33
+ *
34
+ * @param sessionName - The agent
35
+ * @param env - Environment (kill switch)
36
+ * @param queue - The message queue
37
+ * @returns The note, or null
38
+ */
39
+ export declare function ownerHookNoteFor(sessionName: string, env?: NodeJS.ProcessEnv, queue?: SubAgentMessageQueue): string | null;
40
+ /**
41
+ * Join the notes for one hook response, owner message first, within the
42
+ * size ceiling (a later note that does not fit is dropped, not cut).
43
+ *
44
+ * @param notes - Notes in priority order (nulls skipped)
45
+ * @param maxChars - Ceiling
46
+ * @returns The joined text, or null when there is none
47
+ */
48
+ export declare function joinHookNotes(notes: ReadonlyArray<string | null | undefined>, maxChars?: number): string | null;
49
+ //# sourceMappingURL=owner-hook-message.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"owner-hook-message.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/messaging/owner-hook-message.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,EAAE,oBAAoB,EAAE,KAAK,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AAEvG;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,oBAAoB,EAAE,QAAQ,GAAE,MAAuD,GAAG,MAAM,CAa3I;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC/B,WAAW,EAAE,MAAM,EACnB,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,KAAK,GAAE,oBAAyD,GAC9D,MAAM,GAAG,IAAI,CAKf;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,QAAQ,GAAE,MAAuD,GAAG,MAAM,GAAG,IAAI,CAY/J"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Owner messages at the next tool boundary.
3
+ *
4
+ * A busy Claude Code agent (the orc, a PA) runs turns of 10–30+ minutes; an
5
+ * owner message sent meanwhile waited in the queue until the turn ended.
6
+ * Claude Code's own queued input is unreliable for this: text typed while
7
+ * tool calls remain is merged after the next tool result and the model may
8
+ * ignore it (crewly#1118 notes). Crewly's agent-status PostToolUse hook can
9
+ * already return `additionalContext`, so the next tool boundary hands the
10
+ * agent the waiting owner message as a clearly framed note.
11
+ *
12
+ * The queue keeps the message until the agent posts in its conversation
13
+ * ({@link SubAgentMessageQueue.takeOwnerMessageForHook}); if the agent does
14
+ * not, the normal idle delivery still sends it.
15
+ *
16
+ * @module services/messaging/owner-hook-message
17
+ */
18
+ import { OWNER_HOOK_MESSAGE_CONSTANTS } from '../../constants.js';
19
+ import { SubAgentMessageQueue } from './sub-agent-message-queue.service.js';
20
+ /**
21
+ * The note for one surfaced owner message (English harness text). The queued
22
+ * text already carries where the message came from and how to reply, as the
23
+ * normal delivery would.
24
+ *
25
+ * @param message - The surfaced message
26
+ * @param maxChars - Ceiling on the note's length
27
+ * @returns The note
28
+ */
29
+ export function buildOwnerHookNote(message, maxChars = OWNER_HOOK_MESSAGE_CONSTANTS.MAX_CONTEXT_CHARS) {
30
+ const C = OWNER_HOOK_MESSAGE_CONSTANTS;
31
+ const head = message.surfaceCount > 1
32
+ ? `${C.TAG} Reminder: Crewly handed you this message from the owner a few minutes ago and you have not answered it yet. ` +
33
+ 'Answer it now, in the conversation it came from, before your next step of the current work; then carry on.'
34
+ : `${C.TAG} Crewly delivered this message from the owner while you were working. ` +
35
+ 'Answer it now, in the conversation it came from, before your next step of the current work; then carry on with that work.';
36
+ const sep = '\n\n';
37
+ const room = maxChars - head.length - sep.length;
38
+ const tail = '\n… (cut short here; read the full message in its conversation before you answer)';
39
+ const body = message.data.length <= room ? message.data : `${message.data.slice(0, Math.max(0, room - tail.length))}${tail}`;
40
+ return `${head}${sep}${body}`;
41
+ }
42
+ /**
43
+ * The owner-message note for an agent's PostToolUse hook, or null. One
44
+ * message at most per call. Off when {@link OWNER_HOOK_MESSAGE_CONSTANTS.KILL_SWITCH_ENV}
45
+ * is `off`.
46
+ *
47
+ * @param sessionName - The agent
48
+ * @param env - Environment (kill switch)
49
+ * @param queue - The message queue
50
+ * @returns The note, or null
51
+ */
52
+ export function ownerHookNoteFor(sessionName, env = process.env, queue = SubAgentMessageQueue.getInstance()) {
53
+ const C = OWNER_HOOK_MESSAGE_CONSTANTS;
54
+ if (env[C.KILL_SWITCH_ENV] === C.KILL_SWITCH_OFF_VALUE)
55
+ return null;
56
+ const message = queue.takeOwnerMessageForHook(sessionName);
57
+ return message ? buildOwnerHookNote(message) : null;
58
+ }
59
+ /**
60
+ * Join the notes for one hook response, owner message first, within the
61
+ * size ceiling (a later note that does not fit is dropped, not cut).
62
+ *
63
+ * @param notes - Notes in priority order (nulls skipped)
64
+ * @param maxChars - Ceiling
65
+ * @returns The joined text, or null when there is none
66
+ */
67
+ export function joinHookNotes(notes, maxChars = OWNER_HOOK_MESSAGE_CONSTANTS.MAX_CONTEXT_CHARS) {
68
+ let out = '';
69
+ for (const note of notes) {
70
+ if (!note)
71
+ continue;
72
+ const next = out ? `${out}\n\n${note}` : note;
73
+ if (next.length > maxChars) {
74
+ if (!out)
75
+ out = note.slice(0, maxChars);
76
+ continue;
77
+ }
78
+ out = next;
79
+ }
80
+ return out || null;
81
+ }
82
+ //# sourceMappingURL=owner-hook-message.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"owner-hook-message.js","sourceRoot":"","sources":["../../../../../../backend/src/services/messaging/owner-hook-message.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,4BAA4B,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAA6B,MAAM,sCAAsC,CAAC;AAEvG;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAA6B,EAAE,WAAmB,4BAA4B,CAAC,iBAAiB;IAClI,MAAM,CAAC,GAAG,4BAA4B,CAAC;IACvC,MAAM,IAAI,GACT,OAAO,CAAC,YAAY,GAAG,CAAC;QACvB,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,+GAA+G;YACxH,4GAA4G;QAC7G,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,wEAAwE;YACjF,2HAA2H,CAAC;IAC/H,MAAM,GAAG,GAAG,MAAM,CAAC;IACnB,MAAM,IAAI,GAAG,QAAQ,GAAG,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;IACjD,MAAM,IAAI,GAAG,mFAAmF,CAAC;IACjG,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC;IAC7H,OAAO,GAAG,IAAI,GAAG,GAAG,GAAG,IAAI,EAAE,CAAC;AAC/B,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAC/B,WAAmB,EACnB,MAAyB,OAAO,CAAC,GAAG,EACpC,QAA8B,oBAAoB,CAAC,WAAW,EAAE;IAEhE,MAAM,CAAC,GAAG,4BAA4B,CAAC;IACvC,IAAI,GAAG,CAAC,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,qBAAqB;QAAE,OAAO,IAAI,CAAC;IACpE,MAAM,OAAO,GAAG,KAAK,CAAC,uBAAuB,CAAC,WAAW,CAAC,CAAC;IAC3D,OAAO,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACrD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,KAA+C,EAAE,WAAmB,4BAA4B,CAAC,iBAAiB;IAC/I,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QAC9C,IAAI,IAAI,CAAC,MAAM,GAAG,QAAQ,EAAE,CAAC;YAC5B,IAAI,CAAC,GAAG;gBAAE,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;YACxC,SAAS;QACV,CAAC;QACD,GAAG,GAAG,IAAI,CAAC;IACZ,CAAC;IACD,OAAO,GAAG,IAAI,IAAI,CAAC;AACpB,CAAC"}
@@ -99,7 +99,31 @@ export declare class AgentPostLog {
99
99
  * @returns True when the agent spoke there after `since`
100
100
  */
101
101
  postedSince(session: string, where: QueueConversation, since: number): boolean;
102
+ /**
103
+ * Whether the agent answered in a conversation after it was explicitly
104
+ * shown a message from there (an owner message surfaced at a tool
105
+ * boundary). Unlike {@link postedSince}, a top-level DM counts: the agent
106
+ * was told to answer that message first, so its next top-level post there
107
+ * is taken as the answer (see {@link answersConversation}).
108
+ *
109
+ * @param session - The agent
110
+ * @param where - The message's conversation
111
+ * @param since - When the agent was shown it
112
+ * @returns True when the agent posted there after `since`
113
+ */
114
+ answeredSince(session: string, where: QueueConversation, since: number): boolean;
102
115
  }
116
+ /**
117
+ * Whether a post answers a message the agent was explicitly shown: the same
118
+ * thread when the message sits in a thread; otherwise a top-level post in the
119
+ * same chat channel (or Slack channel). A post in some other thread of the
120
+ * channel does not count.
121
+ *
122
+ * @param post - Where the agent posted
123
+ * @param message - Where the message's answer belongs
124
+ * @returns True on a match
125
+ */
126
+ export declare function answersConversation(post: QueueConversation, message: QueueConversation): boolean;
103
127
  /**
104
128
  * Whether a post landed in the conversation (and thread) a queued message belongs to.
105
129
  *
@@ -1 +1 @@
1
- {"version":3,"file":"queue-priority.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/messaging/queue-priority.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH,+CAA+C;AAC/C,MAAM,WAAW,iBAAiB;IACjC,kDAAkD;IAClD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qDAAqD;IACrD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yBAAyB;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,wBAAwB;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,6CAA6C;AAC7C,MAAM,WAAW,gBAAgB;IAChC,mGAAmG;IACnG,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,0IAA0I;IAC1I,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAC1B,yGAAyG;IACzG,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAeD;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAEtG;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAG5F;AAiBD;;;GAGG;AACH,qBAAa,YAAY;IACxB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA6B;IACpD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAkC;IAExD,oCAAoC;IACpC,MAAM,CAAC,WAAW,IAAI,YAAY;IAKlC,qBAAqB;IACrB,MAAM,CAAC,aAAa,IAAI,IAAI;IAI5B;;;;;;OAMG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,EAAE,EAAE,GAAE,MAAmB,GAAG,IAAI;IAS9E;;;;;;;;;OASG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO;CAK9E;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,EAAE,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAW5F;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAChC,GAAG,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,EAClJ,GAAG,GAAE,YAAyC,GAC5C,IAAI,CAWN"}
1
+ {"version":3,"file":"queue-priority.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/messaging/queue-priority.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH,+CAA+C;AAC/C,MAAM,WAAW,iBAAiB;IACjC,kDAAkD;IAClD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qDAAqD;IACrD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yBAAyB;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,wBAAwB;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,6CAA6C;AAC7C,MAAM,WAAW,gBAAgB;IAChC,mGAAmG;IACnG,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,0IAA0I;IAC1I,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAC1B,yGAAyG;IACzG,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAeD;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAEtG;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAG5F;AAiBD;;;GAGG;AACH,qBAAa,YAAY;IACxB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA6B;IACpD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAkC;IAExD,oCAAoC;IACpC,MAAM,CAAC,WAAW,IAAI,YAAY;IAKlC,qBAAqB;IACrB,MAAM,CAAC,aAAa,IAAI,IAAI;IAI5B;;;;;;OAMG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,EAAE,EAAE,GAAE,MAAmB,GAAG,IAAI;IAS9E;;;;;;;;;OASG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO;IAM9E;;;;;;;;;;;OAWG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO;CAKhF;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAMhG;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,EAAE,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAW5F;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAChC,GAAG,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,EAClJ,GAAG,GAAE,YAAyC,GAC5C,IAAI,CAWN"}
@@ -101,6 +101,45 @@ export class AgentPostLog {
101
101
  return false;
102
102
  return list.some((p) => p.at > since && sameConversation(p.where, where));
103
103
  }
104
+ /**
105
+ * Whether the agent answered in a conversation after it was explicitly
106
+ * shown a message from there (an owner message surfaced at a tool
107
+ * boundary). Unlike {@link postedSince}, a top-level DM counts: the agent
108
+ * was told to answer that message first, so its next top-level post there
109
+ * is taken as the answer (see {@link answersConversation}).
110
+ *
111
+ * @param session - The agent
112
+ * @param where - The message's conversation
113
+ * @param since - When the agent was shown it
114
+ * @returns True when the agent posted there after `since`
115
+ */
116
+ answeredSince(session, where, since) {
117
+ const list = this.posts.get(session);
118
+ if (!list)
119
+ return false;
120
+ return list.some((p) => p.at > since && answersConversation(p.where, where));
121
+ }
122
+ }
123
+ /**
124
+ * Whether a post answers a message the agent was explicitly shown: the same
125
+ * thread when the message sits in a thread; otherwise a top-level post in the
126
+ * same chat channel (or Slack channel). A post in some other thread of the
127
+ * channel does not count.
128
+ *
129
+ * @param post - Where the agent posted
130
+ * @param message - Where the message's answer belongs
131
+ * @returns True on a match
132
+ */
133
+ export function answersConversation(post, message) {
134
+ if (sameConversation(post, message))
135
+ return true;
136
+ if (message.chatThreadId || message.threadTs)
137
+ return false;
138
+ if (message.chatChannelId && post.chatChannelId === message.chatChannelId && !post.chatThreadId)
139
+ return true;
140
+ if (message.slackChannelId && post.slackChannelId === message.slackChannelId && !post.threadTs)
141
+ return true;
142
+ return false;
104
143
  }
105
144
  /**
106
145
  * Whether a post landed in the conversation (and thread) a queued message belongs to.
@@ -1 +1 @@
1
- {"version":3,"file":"queue-priority.js","sourceRoot":"","sources":["../../../../../../backend/src/services/messaging/queue-priority.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"queue-priority.js","sourceRoot":"","sources":["../../../../../../backend/src/services/messaging/queue-priority.ts"],"names":[],"mappings":"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"}
@@ -46,6 +46,23 @@ export interface QueuedAgentMessage {
46
46
  * by a newer one is dropped at flush time.
47
47
  */
48
48
  meta?: QueueMessageMeta;
49
+ /**
50
+ * When the owner message was last handed to the busy agent at a tool
51
+ * boundary ({@link SubAgentMessageQueue.takeOwnerMessageForHook}). It
52
+ * stays queued until the agent posts in its conversation after this.
53
+ */
54
+ surfacedAt?: number;
55
+ /** How many times it was handed over at a tool boundary */
56
+ surfaceCount?: number;
57
+ }
58
+ /** An owner message handed to a busy agent at a tool boundary. */
59
+ export interface SurfacedOwnerMessage {
60
+ /** The queued text (it already carries where and how to reply) */
61
+ data: string;
62
+ /** When it was queued */
63
+ queuedAt: number;
64
+ /** 1 the first time, 2 for the reminder */
65
+ surfaceCount: number;
49
66
  }
50
67
  /**
51
68
  * Owner messages first, each group in its existing order (stable).
@@ -54,8 +71,17 @@ export interface QueuedAgentMessage {
54
71
  * @returns The queue in delivery order
55
72
  */
56
73
  export declare function ownerFirst(list: QueuedAgentMessage[]): QueuedAgentMessage[];
74
+ /**
75
+ * The text an idle delivery writes: an owner message the agent was already
76
+ * shown at a tool boundary (and has not answered in its conversation) gets
77
+ * a one-line notice, so an agent that did answer elsewhere does not answer twice.
78
+ *
79
+ * @param m - Queued message
80
+ * @returns Text to deliver
81
+ */
82
+ export declare function withSurfacedNotice(m: QueuedAgentMessage): string;
57
83
  /** Why a queued message was dropped before delivery as no longer needed. */
58
- export type QueuePruneReason = 'answered-in-thread' | 'duplicate-owner-message' | 'superseded';
84
+ export type QueuePruneReason = 'answered-in-thread' | 'answered-after-surfacing' | 'duplicate-owner-message' | 'superseded';
59
85
  /** A hand-over prepared for a queued WorkItem brief (see {@link SubAgentMessageQueue.setHandOverPreparer}). */
60
86
  export interface QueuedHandOver {
61
87
  /** Text to write */
@@ -303,6 +329,34 @@ export declare class SubAgentMessageQueue {
303
329
  * @returns The messages still to deliver, in order
304
330
  */
305
331
  private pruneNoLongerNeeded;
332
+ /**
333
+ * Hand the next owner message waiting for a busy agent to its PostToolUse
334
+ * hook, so it reaches the agent at the next tool boundary instead of at
335
+ * the end of the turn. At most one per call.
336
+ *
337
+ * The message is NOT removed: it is marked surfaced (time and count) and
338
+ * stays queued until the agent posts in its conversation after that time
339
+ * (then it is dropped here or at the flush). Unanswered after
340
+ * {@link OWNER_HOOK_MESSAGE_CONSTANTS.RESURFACE_AFTER_MS} it is shown once
341
+ * more; after {@link OWNER_HOOK_MESSAGE_CONSTANTS.MAX_SURFACES} only the
342
+ * normal idle delivery remains. Nothing is lost; at worst it arrives twice.
343
+ *
344
+ * Only the owner's own messages (and the owner's decision answers) that
345
+ * name a conversation — not harness reminders, not other traffic.
346
+ *
347
+ * @param sessionName - The agent whose hook is asking
348
+ * @param now - Clock
349
+ * @returns The message to show, or null
350
+ */
351
+ takeOwnerMessageForHook(sessionName: string, now?: number): SurfacedOwnerMessage | null;
352
+ /**
353
+ * Whether a surfaced owner message was answered: the agent posted in its
354
+ * conversation after it was shown it.
355
+ *
356
+ * @param m - Queued message
357
+ * @returns True when it was answered
358
+ */
359
+ private answeredAfterSurfacing;
306
360
  /**
307
361
  * Whether the agent has already posted in the thread a queued message
308
362
  * belongs to, after it was queued — it was answered (the agent read the
@@ -1 +1 @@
1
- {"version":3,"file":"sub-agent-message-queue.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/messaging/sub-agent-message-queue.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sub-agent-message-queue.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/messaging/sub-agent-message-queue.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAQH,OAAO,EAAkC,KAAK,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5F;;GAEG;AACH,oDAAoD;AACpD,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,UAAU,GAAG,eAAe,CAAC;AAExE;;;;;;GAMG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,EAAE,EAAE,MAAM,EAAE,eAAe,KAAK,IAAI,CAAC;AAEtH,MAAM,WAAW,kBAAkB;IAClC,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,QAAQ,EAAE,MAAM,CAAC;IACjB,8BAA8B;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2DAA2D;IAC3D,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,kEAAkE;AAClE,MAAM,WAAW,oBAAoB;IACpC,kEAAkE;IAClE,IAAI,EAAE,MAAM,CAAC;IACb,yBAAyB;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,YAAY,EAAE,MAAM,CAAC;CACrB;AAYD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,kBAAkB,EAAE,GAAG,kBAAkB,EAAE,CAI3E;AAgBD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,kBAAkB,GAAG,MAAM,CAIhE;AAED,4EAA4E;AAC5E,MAAM,MAAM,gBAAgB,GAAG,oBAAoB,GAAG,0BAA0B,GAAG,yBAAyB,GAAG,YAAY,CAAC;AAE5H,+GAA+G;AAC/G,MAAM,WAAW,cAAc;IAC9B,oBAAoB;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,oCAAoC;IACpC,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,gCAAgC;IAChC,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,2FAA2F;IAC3F,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,oFAAoF;AACpF,MAAM,MAAM,sBAAsB,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;AAExH;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;AAElG;;;;;;;GAOG;AACH,qBAAa,oBAAoB;IAChC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAqC;IAC5D,OAAO,CAAC,eAAe,CAA2C;IAClE,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,gGAAgG;IAChG,OAAO,CAAC,aAAa,CAAuB;IAC5C,+EAA+E;IAC/E,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,UAAU,CAAkC;IACpD,+EAA+E;IAC/E,OAAO,CAAC,YAAY,CAAkC;IACtD,yEAAyE;IACzE,OAAO,CAAC,gBAAgB,CAAuC;IAC/D,kDAAkD;IAClD,OAAO,CAAC,iBAAiB,CAA8D;IACvF,uEAAuE;IACvE,OAAO,CAAC,eAAe,CAA8F;IAErH,OAAO;IAMP;;;;;;;OAOG;IACH,OAAO,CAAC,IAAI;IAyDZ;;;OAGG;IACH,OAAO,CAAC,IAAI;IAyBZ;;;;OAIG;IACH,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,oBAAoB;IAO5D;;OAEG;IACH,MAAM,CAAC,aAAa,IAAI,IAAI;IAI5B;;;;;;OAMG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO;IAIpD;;;;;;;;OAQG;IACH,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO;IAWlD;;;;;;OAMG;IACH,eAAe,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI,GAAG,IAAI;IAQzD;;;;;;OAMG;IACH,OAAO,CAAC,UAAU;IAYlB;;;;;;;;;OASG;IACH,oBAAoB,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,GAAG,IAAI;IAI3D;;;;;;;;OAQG;IACH,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAQ5D;;;;;OAKG;IACH,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,kBAAkB,EAAE;IAIxD;;;;;;;OAOG;IACH,oBAAoB,CAAC,QAAQ,EAAE,CAAC,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI;IAI1F,OAAO,CAAC,eAAe;IAQvB;;;;;OAKG;IACH,mBAAmB,CAAC,QAAQ,EAAE,sBAAsB,GAAG,IAAI,GAAG,IAAI;IAIlE;;;;;;OAMG;YACW,OAAO;IAarB;;;;;OAKG;IACG,UAAU,IAAI,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC;IAwBvE;;;;;;;;;;;;;;;;;;OAkBG;IACH,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,gBAAgB,CAAA;KAAO,GAAG,IAAI;IA+DlH;;;;;;OAMG;IACH,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,kBAAkB,EAAE;IAkBrD;;;;;;OAMG;IACH,OAAO,CAAC,cAAc;IAWtB;;;;;;;;;;;;;;;;;;OAkBG;IACG,KAAK,CACV,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,EACxF,KAAK,SAAI,GACP,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC;IAoHzF;;;;;;;;;;OAUG;IACH,OAAO,CAAC,mBAAmB;IAoC3B;;;;;;;;;;;;;;;;;;OAkBG;IACH,uBAAuB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,GAAE,MAAmB,GAAG,oBAAoB,GAAG,IAAI;IAmCnG;;;;;;OAMG;IACH,OAAO,CAAC,sBAAsB;IAK9B;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,gBAAgB;IAOxB,OAAO,CAAC,QAAQ;IAYhB;;;;;;;;OAQG;IACH,mBAAmB,IAAI,MAAM,EAAE;IAI/B;;;;;OAKG;IACH,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;IAKxC;;;;OAIG;IACH,KAAK,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAYhC;;;;;OAKG;IACH,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;IAKzC;;;;;OAKG;IACH,cAAc,IAAI,MAAM;CAKxB"}
@@ -12,7 +12,7 @@
12
12
  */
13
13
  import * as path from 'path';
14
14
  import { LoggerService } from '../core/logger.service.js';
15
- import { SUB_AGENT_QUEUE_CONSTANTS } from '../../constants.js';
15
+ import { OWNER_HOOK_MESSAGE_CONSTANTS, SUB_AGENT_QUEUE_CONSTANTS } from '../../constants.js';
16
16
  import { mkdirSync, existsSync } from 'fs';
17
17
  import { atomicWriteFileSync, quarantineCorruptFileSync, readJsonStoreSync, CorruptJsonFileError } from '../../utils/file-io.utils.js';
18
18
  import { getCrewlyHomePath } from '../core/crewly-home.utils.js';
@@ -38,6 +38,33 @@ export function ownerFirst(list) {
38
38
  return list;
39
39
  return [...owner, ...list.filter((m) => !isOwnerItem(m))];
40
40
  }
41
+ /**
42
+ * Whether a queued message may be handed to a busy agent at a tool boundary:
43
+ * written by the owner (not a harness reminder carrying the owner's words)
44
+ * and naming the conversation its answer belongs in — the evidence that it
45
+ * was answered is a post there.
46
+ *
47
+ * @param m - Queued message
48
+ * @returns True when it may be surfaced
49
+ */
50
+ function isSurfaceable(m) {
51
+ const where = m.meta?.where;
52
+ return isOwnerItem(m) && m.meta?.reminder !== true && !!where && !!(where.chatChannelId || where.slackChannelId);
53
+ }
54
+ /**
55
+ * The text an idle delivery writes: an owner message the agent was already
56
+ * shown at a tool boundary (and has not answered in its conversation) gets
57
+ * a one-line notice, so an agent that did answer elsewhere does not answer twice.
58
+ *
59
+ * @param m - Queued message
60
+ * @returns Text to deliver
61
+ */
62
+ export function withSurfacedNotice(m) {
63
+ if (m.surfacedAt === undefined)
64
+ return m.data;
65
+ const at = new Date(m.surfacedAt).toISOString();
66
+ return `[Crewly: this owner message was already shown to you during your last turn (at ${at}). If you already answered it, do not answer again.]\n${m.data}`;
67
+ }
41
68
  /**
42
69
  * Singleton service that holds pending messages per agent session.
43
70
  *
@@ -544,6 +571,11 @@ export class SubAgentMessageQueue {
544
571
  this.logPrune(sessionName, queued, 'answered-in-thread');
545
572
  continue;
546
573
  }
574
+ if (this.answeredAfterSurfacing(queued)) {
575
+ out.skippedStale += 1;
576
+ this.logPrune(sessionName, queued, 'answered-after-surfacing');
577
+ continue;
578
+ }
547
579
  if (await this.isStale(queued.data, sessionName)) {
548
580
  out.skippedStale += 1;
549
581
  continue;
@@ -565,7 +597,7 @@ export class SubAgentMessageQueue {
565
597
  });
566
598
  continue;
567
599
  }
568
- const sentText = handOver ? handOver.message : queued.data;
600
+ const sentText = handOver ? handOver.message : withSurfacedNotice(queued);
569
601
  const result = await send(sentText);
570
602
  if (handOver) {
571
603
  // Held again or failed: not delivered (the hand-over runs again next time).
@@ -671,6 +703,73 @@ export class SubAgentMessageQueue {
671
703
  this.save();
672
704
  return kept;
673
705
  }
706
+ /**
707
+ * Hand the next owner message waiting for a busy agent to its PostToolUse
708
+ * hook, so it reaches the agent at the next tool boundary instead of at
709
+ * the end of the turn. At most one per call.
710
+ *
711
+ * The message is NOT removed: it is marked surfaced (time and count) and
712
+ * stays queued until the agent posts in its conversation after that time
713
+ * (then it is dropped here or at the flush). Unanswered after
714
+ * {@link OWNER_HOOK_MESSAGE_CONSTANTS.RESURFACE_AFTER_MS} it is shown once
715
+ * more; after {@link OWNER_HOOK_MESSAGE_CONSTANTS.MAX_SURFACES} only the
716
+ * normal idle delivery remains. Nothing is lost; at worst it arrives twice.
717
+ *
718
+ * Only the owner's own messages (and the owner's decision answers) that
719
+ * name a conversation — not harness reminders, not other traffic.
720
+ *
721
+ * @param sessionName - The agent whose hook is asking
722
+ * @param now - Clock
723
+ * @returns The message to show, or null
724
+ */
725
+ takeOwnerMessageForHook(sessionName, now = Date.now()) {
726
+ const queue = this.pendingMessages.get(sessionName);
727
+ if (!queue || queue.length === 0)
728
+ return null;
729
+ const C = OWNER_HOOK_MESSAGE_CONSTANTS;
730
+ // Answered since it was shown: done with it.
731
+ const answered = queue.filter((m) => this.answeredAfterSurfacing(m));
732
+ if (answered.length > 0) {
733
+ for (const m of answered)
734
+ this.logPrune(sessionName, m, 'answered-after-surfacing');
735
+ const rest = queue.filter((m) => !answered.includes(m));
736
+ if (rest.length > 0)
737
+ this.pendingMessages.set(sessionName, rest);
738
+ else
739
+ this.pendingMessages.delete(sessionName);
740
+ }
741
+ const current = this.pendingMessages.get(sessionName) ?? [];
742
+ const next = current.find((m) => isSurfaceable(m) &&
743
+ (m.surfaceCount ?? 0) < C.MAX_SURFACES &&
744
+ (m.surfacedAt === undefined || now - m.surfacedAt >= C.RESURFACE_AFTER_MS));
745
+ if (!next) {
746
+ if (answered.length > 0)
747
+ this.save();
748
+ return null;
749
+ }
750
+ next.surfacedAt = now;
751
+ next.surfaceCount = (next.surfaceCount ?? 0) + 1;
752
+ this.save();
753
+ this.logger.info('Owner message handed to the busy agent at a tool boundary', {
754
+ sessionName,
755
+ surfaceCount: next.surfaceCount,
756
+ queuedAt: new Date(next.queuedAt).toISOString(),
757
+ ...(next.meta?.ref ? { ref: next.meta.ref } : {}),
758
+ });
759
+ return { data: next.data, queuedAt: next.queuedAt, surfaceCount: next.surfaceCount };
760
+ }
761
+ /**
762
+ * Whether a surfaced owner message was answered: the agent posted in its
763
+ * conversation after it was shown it.
764
+ *
765
+ * @param m - Queued message
766
+ * @returns True when it was answered
767
+ */
768
+ answeredAfterSurfacing(m) {
769
+ if (m.surfacedAt === undefined || !m.meta?.where)
770
+ return false;
771
+ return AgentPostLog.getInstance().answeredSince(m.sessionName, m.meta.where, m.surfacedAt);
772
+ }
674
773
  /**
675
774
  * Whether the agent has already posted in the thread a queued message
676
775
  * belongs to, after it was queued — it was answered (the agent read the