crewly 1.20.168 → 1.20.170

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 (152) hide show
  1. package/config/constants.ts +4 -0
  2. package/config/skills/_common/lib.sh +5 -0
  3. package/config/skills/agent/core/reply/SKILL.md +71 -0
  4. package/config/skills/agent/core/reply/execute.sh +81 -0
  5. package/config/skills/agent/core/reply/execute.test.sh +87 -0
  6. package/dist/backend/backend/src/constants.d.ts +101 -0
  7. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  8. package/dist/backend/backend/src/constants.js +105 -0
  9. package/dist/backend/backend/src/constants.js.map +1 -1
  10. package/dist/backend/backend/src/controllers/chat/agent-reply.controller.d.ts +36 -0
  11. package/dist/backend/backend/src/controllers/chat/agent-reply.controller.d.ts.map +1 -0
  12. package/dist/backend/backend/src/controllers/chat/agent-reply.controller.js +182 -0
  13. package/dist/backend/backend/src/controllers/chat/agent-reply.controller.js.map +1 -0
  14. package/dist/backend/backend/src/controllers/chat/chat.controller.d.ts +30 -0
  15. package/dist/backend/backend/src/controllers/chat/chat.controller.d.ts.map +1 -1
  16. package/dist/backend/backend/src/controllers/chat/chat.controller.js +171 -0
  17. package/dist/backend/backend/src/controllers/chat/chat.controller.js.map +1 -1
  18. package/dist/backend/backend/src/controllers/chat/chat.routes.d.ts.map +1 -1
  19. package/dist/backend/backend/src/controllers/chat/chat.routes.js +4 -0
  20. package/dist/backend/backend/src/controllers/chat/chat.routes.js.map +1 -1
  21. package/dist/backend/backend/src/controllers/slack/slack.controller.d.ts +55 -0
  22. package/dist/backend/backend/src/controllers/slack/slack.controller.d.ts.map +1 -1
  23. package/dist/backend/backend/src/controllers/slack/slack.controller.js +1 -1
  24. package/dist/backend/backend/src/controllers/slack/slack.controller.js.map +1 -1
  25. package/dist/backend/backend/src/index.d.ts +10 -0
  26. package/dist/backend/backend/src/index.d.ts.map +1 -1
  27. package/dist/backend/backend/src/index.js +119 -1
  28. package/dist/backend/backend/src/index.js.map +1 -1
  29. package/dist/backend/backend/src/middleware/agent-origin.middleware.d.ts +45 -0
  30. package/dist/backend/backend/src/middleware/agent-origin.middleware.d.ts.map +1 -0
  31. package/dist/backend/backend/src/middleware/agent-origin.middleware.js +148 -0
  32. package/dist/backend/backend/src/middleware/agent-origin.middleware.js.map +1 -0
  33. package/dist/backend/backend/src/routes/modules/system.routes.d.ts.map +1 -1
  34. package/dist/backend/backend/src/routes/modules/system.routes.js +6 -0
  35. package/dist/backend/backend/src/routes/modules/system.routes.js.map +1 -1
  36. package/dist/backend/backend/src/services/agent/agent-process-origin.service.d.ts +86 -0
  37. package/dist/backend/backend/src/services/agent/agent-process-origin.service.d.ts.map +1 -0
  38. package/dist/backend/backend/src/services/agent/agent-process-origin.service.js +114 -0
  39. package/dist/backend/backend/src/services/agent/agent-process-origin.service.js.map +1 -0
  40. package/dist/backend/backend/src/services/agent/codex-daemon.utils.d.ts +56 -0
  41. package/dist/backend/backend/src/services/agent/codex-daemon.utils.d.ts.map +1 -0
  42. package/dist/backend/backend/src/services/agent/codex-daemon.utils.js +100 -0
  43. package/dist/backend/backend/src/services/agent/codex-daemon.utils.js.map +1 -0
  44. package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.d.ts +15 -0
  45. package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.d.ts.map +1 -1
  46. package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.js +27 -0
  47. package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.js.map +1 -1
  48. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +18 -0
  49. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -1
  50. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +48 -3
  51. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -1
  52. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.d.ts +271 -0
  53. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.d.ts.map +1 -0
  54. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.js +605 -0
  55. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.js.map +1 -0
  56. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.d.ts +179 -0
  57. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.d.ts.map +1 -0
  58. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.js +327 -0
  59. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.js.map +1 -0
  60. package/dist/backend/backend/src/services/orc/agent-reply-target.d.ts +95 -0
  61. package/dist/backend/backend/src/services/orc/agent-reply-target.d.ts.map +1 -0
  62. package/dist/backend/backend/src/services/orc/agent-reply-target.js +85 -0
  63. package/dist/backend/backend/src/services/orc/agent-reply-target.js.map +1 -0
  64. package/dist/backend/backend/src/services/orc/orc-reply-route.service.d.ts +20 -0
  65. package/dist/backend/backend/src/services/orc/orc-reply-route.service.d.ts.map +1 -1
  66. package/dist/backend/backend/src/services/orc/orc-reply-route.service.js +34 -1
  67. package/dist/backend/backend/src/services/orc/orc-reply-route.service.js.map +1 -1
  68. package/dist/backend/backend/src/services/slack/slack-initializer.d.ts.map +1 -1
  69. package/dist/backend/backend/src/services/slack/slack-initializer.js +5 -0
  70. package/dist/backend/backend/src/services/slack/slack-initializer.js.map +1 -1
  71. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts +13 -0
  72. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts.map +1 -1
  73. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js +40 -0
  74. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
  75. package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
  76. package/dist/backend/backend/src/services/slack/slack-team-channel.service.js +2 -0
  77. package/dist/backend/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
  78. package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.d.ts +33 -0
  79. package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.d.ts.map +1 -1
  80. package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.js +68 -0
  81. package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.js.map +1 -1
  82. package/dist/backend/backend/src/services/slack/slack.service.d.ts +16 -0
  83. package/dist/backend/backend/src/services/slack/slack.service.d.ts.map +1 -1
  84. package/dist/backend/backend/src/services/slack/slack.service.js +22 -5
  85. package/dist/backend/backend/src/services/slack/slack.service.js.map +1 -1
  86. package/dist/backend/backend/src/services/system/auto-update.service.d.ts +15 -5
  87. package/dist/backend/backend/src/services/system/auto-update.service.d.ts.map +1 -1
  88. package/dist/backend/backend/src/services/system/auto-update.service.js +26 -21
  89. package/dist/backend/backend/src/services/system/auto-update.service.js.map +1 -1
  90. package/dist/backend/backend/src/services/system/auto-update.utils.d.ts +51 -0
  91. package/dist/backend/backend/src/services/system/auto-update.utils.d.ts.map +1 -1
  92. package/dist/backend/backend/src/services/system/auto-update.utils.js +103 -0
  93. package/dist/backend/backend/src/services/system/auto-update.utils.js.map +1 -1
  94. package/dist/backend/backend/src/types/slack.types.d.ts +6 -0
  95. package/dist/backend/backend/src/types/slack.types.d.ts.map +1 -1
  96. package/dist/backend/backend/src/types/slack.types.js.map +1 -1
  97. package/dist/backend/build-info.json +2 -2
  98. package/dist/backend/config/constants.d.ts +4 -0
  99. package/dist/backend/config/constants.d.ts.map +1 -1
  100. package/dist/backend/config/constants.js +4 -0
  101. package/dist/backend/config/constants.js.map +1 -1
  102. package/dist/cli/backend/src/constants.d.ts +101 -0
  103. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  104. package/dist/cli/backend/src/constants.js +105 -0
  105. package/dist/cli/backend/src/constants.js.map +1 -1
  106. package/dist/cli/backend/src/services/agent/codex-daemon.utils.d.ts +56 -0
  107. package/dist/cli/backend/src/services/agent/codex-daemon.utils.d.ts.map +1 -0
  108. package/dist/cli/backend/src/services/agent/codex-daemon.utils.js +100 -0
  109. package/dist/cli/backend/src/services/agent/codex-daemon.utils.js.map +1 -0
  110. package/dist/cli/backend/src/services/agent/runtime-agent.service.abstract.d.ts +15 -0
  111. package/dist/cli/backend/src/services/agent/runtime-agent.service.abstract.d.ts.map +1 -1
  112. package/dist/cli/backend/src/services/agent/runtime-agent.service.abstract.js +27 -0
  113. package/dist/cli/backend/src/services/agent/runtime-agent.service.abstract.js.map +1 -1
  114. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +18 -0
  115. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -1
  116. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +48 -3
  117. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -1
  118. package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.d.ts +271 -0
  119. package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.d.ts.map +1 -0
  120. package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.js +605 -0
  121. package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.js.map +1 -0
  122. package/dist/cli/backend/src/services/orc/orc-reply-route.service.d.ts +20 -0
  123. package/dist/cli/backend/src/services/orc/orc-reply-route.service.d.ts.map +1 -1
  124. package/dist/cli/backend/src/services/orc/orc-reply-route.service.js +34 -1
  125. package/dist/cli/backend/src/services/orc/orc-reply-route.service.js.map +1 -1
  126. package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.d.ts +13 -0
  127. package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.d.ts.map +1 -1
  128. package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.js +40 -0
  129. package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
  130. package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
  131. package/dist/cli/backend/src/services/slack/slack-team-channel.service.js +2 -0
  132. package/dist/cli/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
  133. package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.d.ts +33 -0
  134. package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.d.ts.map +1 -1
  135. package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.js +68 -0
  136. package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.js.map +1 -1
  137. package/dist/cli/backend/src/services/slack/slack.service.d.ts +16 -0
  138. package/dist/cli/backend/src/services/slack/slack.service.d.ts.map +1 -1
  139. package/dist/cli/backend/src/services/slack/slack.service.js +22 -5
  140. package/dist/cli/backend/src/services/slack/slack.service.js.map +1 -1
  141. package/dist/cli/backend/src/services/system/auto-update.utils.d.ts +51 -0
  142. package/dist/cli/backend/src/services/system/auto-update.utils.d.ts.map +1 -1
  143. package/dist/cli/backend/src/services/system/auto-update.utils.js +103 -0
  144. package/dist/cli/backend/src/services/system/auto-update.utils.js.map +1 -1
  145. package/dist/cli/backend/src/types/slack.types.d.ts +6 -0
  146. package/dist/cli/backend/src/types/slack.types.d.ts.map +1 -1
  147. package/dist/cli/backend/src/types/slack.types.js.map +1 -1
  148. package/dist/cli/config/constants.d.ts +4 -0
  149. package/dist/cli/config/constants.d.ts.map +1 -1
  150. package/dist/cli/config/constants.js +4 -0
  151. package/dist/cli/config/constants.js.map +1 -1
  152. package/package.json +1 -1
@@ -0,0 +1,179 @@
1
+ /**
2
+ * Wiring for the unanswered-owner-message watchdog: turns deliveries into
3
+ * tracked entries, turns what the owner can see into "answered", and
4
+ * implements the nudge and the note on top of the real transports.
5
+ *
6
+ * Kept apart from the service so the timeline logic stays transport-free and
7
+ * the transport glue stays small and testable with plain fakes.
8
+ *
9
+ * @module services/messaging/owner-message-watchdog.wiring
10
+ * @see specs/2026-09-30-owner-message-guarantee.md
11
+ */
12
+ import type { ChatChannelDTO, ChatMessageDTO } from '../chat-v2/types.js';
13
+ import type { DispatchMessageResult } from '../chat-v2/chat-v2.dispatcher.service.js';
14
+ import { OwnerMessageWatchdogService, type LoginHint, type NudgeOutcome, type OwnerMessageEntry, type OwnerMessageTrackInput } from './owner-message-watchdog.service.js';
15
+ /**
16
+ * Whether a chat-v2 user turn was written by the owner: not by an agent (here
17
+ * or on another machine), and — for a Slack row, when the owner is known — by
18
+ * the owner's Slack user.
19
+ *
20
+ * @param message - The turn
21
+ * @param ownerSlackUserId - The workspace owner's Slack user id, when known
22
+ * @returns True for the owner's message
23
+ */
24
+ export declare function isOwnerChatTurn(message: Pick<ChatMessageDTO, 'senderType' | 'metadata'>, ownerSlackUserId: string | null | undefined): boolean;
25
+ /**
26
+ * Build the entry for a chat-v2 dispatch that reached at least one agent.
27
+ *
28
+ * Responsible agent: the first recipient that had to answer; with nobody
29
+ * required (an un-addressed room message the awake agents were only told
30
+ * about), the room lead when it got the message, else the first non-
31
+ * orchestrator recipient. An orchestrator that was only woken to route a
32
+ * private room's message is never made responsible: its hand-off re-dispatches
33
+ * the message, and that dispatch is tracked under the same key.
34
+ *
35
+ * @param channel - Channel the message was recorded in
36
+ * @param message - The owner's turn
37
+ * @param result - Dispatch outcome
38
+ * @param ctx - Owner id and the room lead, when known
39
+ * @returns Track input, or null when nothing should be tracked
40
+ */
41
+ export declare function trackInputFromDispatch(channel: Pick<ChatChannelDTO, 'id' | 'type' | 'agentSession'>, message: ChatMessageDTO, result: DispatchMessageResult, ctx?: {
42
+ ownerSlackUserId?: string | null;
43
+ leader?: string | null;
44
+ }): OwnerMessageTrackInput | null;
45
+ /**
46
+ * Login hint for a runtime waiting on a sign-in ("reply 重新登录 claude").
47
+ *
48
+ * @param runtimeType - The runtime type recorded with the login request, if any
49
+ * @returns The hint
50
+ */
51
+ export declare function loginHintFor(runtimeType: string | null | undefined): LoginHint;
52
+ /**
53
+ * The reminder delivered to the responsible agent. Carries the same routing
54
+ * header a normal delivery does, so the agent's `reply` goes back to the
55
+ * owner's conversation (and thread).
56
+ *
57
+ * @param entry - The unanswered message
58
+ * @param waitedMinutes - How long it has waited
59
+ * @param opts - `withHeader: false` when the transport adds its own `[CHAT:…]` header (the orchestrator's queue)
60
+ * @returns The text to deliver
61
+ */
62
+ export declare function buildNudgeMessage(entry: OwnerMessageEntry, waitedMinutes: number, opts?: {
63
+ withHeader?: boolean;
64
+ }): string;
65
+ /** What the wiring needs from the rest of the backend. */
66
+ export interface OwnerWatchdogWiringDeps {
67
+ crewlyHome: string;
68
+ /** PTY / in-process delivery (sub-agents) */
69
+ sendToAgent: (session: string, text: string) => Promise<{
70
+ success: boolean;
71
+ error?: string;
72
+ }>;
73
+ /** Whether the agent's runtime session exists */
74
+ sessionExists: (session: string) => boolean;
75
+ /** User-initiated activation (same path as the dispatcher's activate-on-send) */
76
+ activate: (session: string) => Promise<{
77
+ success: boolean;
78
+ error?: string;
79
+ }>;
80
+ /** Orchestrator delivery (its message queue) */
81
+ enqueueForOrchestrator: (input: {
82
+ content: string;
83
+ conversationId: string;
84
+ source: string;
85
+ sourceMetadata?: Record<string, unknown>;
86
+ }) => void;
87
+ isBusy: (session: string) => boolean;
88
+ /** Pending sign-in record for the session, if any */
89
+ loginRequired: (session: string) => {
90
+ runtimeType?: string | null;
91
+ } | null | undefined;
92
+ displayNameOf?: (session: string) => string;
93
+ /** Slack posting (null while Slack is not wired) */
94
+ slack: () => {
95
+ isConnected(): boolean;
96
+ sendMessage(m: {
97
+ channelId: string;
98
+ text: string;
99
+ threadTs?: string;
100
+ botToken?: string;
101
+ notAnAnswer?: boolean;
102
+ skipChatV2Mirror?: boolean;
103
+ }): Promise<string>;
104
+ } | null;
105
+ /** Whether a placeholder shows in a Slack thread */
106
+ owesThread: (slackChannelId: string, threadTs: string) => boolean;
107
+ /** Bot token of the agent whose own app owns this Slack DM (the master bot cannot post there) */
108
+ agentDmBotToken: (slackChannelId: string) => string | undefined;
109
+ /** An agent's own bot token, when installed */
110
+ botTokenOf: (session: string) => string | undefined;
111
+ /** Record a system note in a chat-v2 channel; false when it could not be recorded */
112
+ recordChatNote: (chatChannelId: string, threadId: string | undefined, text: string) => boolean;
113
+ /** Tell the reply router which chat thread a nudge is about */
114
+ noteOriginThread?: (session: string, chatChannelId: string, threadId: string | undefined) => void;
115
+ }
116
+ /** chat-v2 metadata flag on the watchdog's own chat notes (never taken as an answer). */
117
+ export declare const OWNER_WATCHDOG_NOTE_METADATA_KEY = "ownerWatchdogNote";
118
+ /**
119
+ * Re-deliver an unanswered message to its responsible agent.
120
+ *
121
+ * @param deps - Wiring deps
122
+ * @param entry - The message
123
+ * @param waited - Minutes waited
124
+ * @returns Sent, or blocked with the reason
125
+ */
126
+ export declare function nudgeAgent(deps: OwnerWatchdogWiringDeps, entry: OwnerMessageEntry, waited: number): Promise<NudgeOutcome>;
127
+ /**
128
+ * Post the note where the owner wrote: the Slack thread (Crewly's master bot;
129
+ * in an agent-owned DM the agent's bot, the only one that can post there), or
130
+ * a system turn in the chat channel.
131
+ *
132
+ * @param deps - Wiring deps
133
+ * @param entry - The message
134
+ * @param text - The note
135
+ * @returns True when posted
136
+ */
137
+ export declare function postOwnerNote(deps: OwnerWatchdogWiringDeps, entry: OwnerMessageEntry, text: string): Promise<boolean>;
138
+ /**
139
+ * Build the watchdog on the real transports and expose it as the singleton.
140
+ *
141
+ * @param deps - Wiring deps
142
+ * @returns The started watchdog
143
+ */
144
+ export declare function createOwnerMessageWatchdog(deps: OwnerWatchdogWiringDeps): OwnerMessageWatchdogService;
145
+ /**
146
+ * Feed a chat-v2 turn to the watchdog: an agent turn in a watched chat
147
+ * channel is the answer (an interim one is a visible "working on it").
148
+ *
149
+ * @param service - The watchdog
150
+ * @param dto - The recorded turn
151
+ */
152
+ export declare function onChatTurn(service: Pick<OwnerMessageWatchdogService, 'noteChatAnswer'>, dto: ChatMessageDTO): void;
153
+ /**
154
+ * Feed a Slack post made through this machine's SlackService.
155
+ *
156
+ * @param service - The watchdog
157
+ * @param post - Channel, thread and whether it was flagged as not an answer
158
+ */
159
+ export declare function onSlackOutbound(service: Pick<OwnerMessageWatchdogService, 'noteSlackAnswer'>, post: {
160
+ channelId: string;
161
+ threadTs?: string;
162
+ notAnAnswer?: boolean;
163
+ kind?: string;
164
+ }): void;
165
+ /**
166
+ * Feed an inbound Slack message: a colleague agent (any machine) posting in
167
+ * a watched thread answered it.
168
+ *
169
+ * @param service - The watchdog
170
+ * @param message - Inbound message fields
171
+ */
172
+ export declare function onSlackInbound(service: Pick<OwnerMessageWatchdogService, 'noteSlackAnswer'>, message: {
173
+ channelId: string;
174
+ threadTs?: string;
175
+ authorAgentSession?: string;
176
+ }): void;
177
+ /** Log once when wiring is skipped (kept here so index.ts stays thin). */
178
+ export declare function logWiringSkipped(reason: string): void;
179
+ //# sourceMappingURL=owner-message-watchdog.wiring.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"owner-message-watchdog.wiring.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/messaging/owner-message-watchdog.wiring.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,327 @@
1
+ /**
2
+ * Wiring for the unanswered-owner-message watchdog: turns deliveries into
3
+ * tracked entries, turns what the owner can see into "answered", and
4
+ * implements the nudge and the note on top of the real transports.
5
+ *
6
+ * Kept apart from the service so the timeline logic stays transport-free and
7
+ * the transport glue stays small and testable with plain fakes.
8
+ *
9
+ * @module services/messaging/owner-message-watchdog.wiring
10
+ * @see specs/2026-09-30-owner-message-guarantee.md
11
+ */
12
+ import * as path from 'path';
13
+ import { AGENT_REPLY_CONSTANTS, MESSAGE_SOURCES, ORCHESTRATOR_SESSION_NAME, OWNER_EVIDENCE_METADATA, OWNER_MESSAGE_WATCHDOG_CONSTANTS as C, SLACK_TYPING_CONSTANTS, } from '../../constants.js';
14
+ import { LoggerService } from '../core/logger.service.js';
15
+ import { slackThreadTag } from '../slack/slack-thread-key.js';
16
+ import { OwnerMessageWatchdogService, setOwnerMessageWatchdog, } from './owner-message-watchdog.service.js';
17
+ const logger = LoggerService.getInstance().createComponentLogger('OwnerMessageWatchdogWiring');
18
+ // ---------------------------------------------------------------------------
19
+ // Delivery → tracked entry
20
+ // ---------------------------------------------------------------------------
21
+ /**
22
+ * Whether a chat-v2 user turn was written by the owner: not by an agent (here
23
+ * or on another machine), and — for a Slack row, when the owner is known — by
24
+ * the owner's Slack user.
25
+ *
26
+ * @param message - The turn
27
+ * @param ownerSlackUserId - The workspace owner's Slack user id, when known
28
+ * @returns True for the owner's message
29
+ */
30
+ export function isOwnerChatTurn(message, ownerSlackUserId) {
31
+ if (message.senderType !== 'user')
32
+ return false;
33
+ const meta = message.metadata ?? {};
34
+ if (meta[OWNER_EVIDENCE_METADATA.AUTHOR_AGENT_SESSION] || meta[OWNER_EVIDENCE_METADATA.REMOTE_AGENT_SESSION])
35
+ return false;
36
+ const source = typeof meta.source === 'string' ? meta.source : '';
37
+ if (OWNER_EVIDENCE_METADATA.AGENT_REPLY_SOURCES.includes(source))
38
+ return false;
39
+ if (source === 'slack') {
40
+ const slackUserId = typeof meta.slackUserId === 'string' ? meta.slackUserId : '';
41
+ if (!slackUserId)
42
+ return false;
43
+ return !ownerSlackUserId || slackUserId === ownerSlackUserId;
44
+ }
45
+ return true;
46
+ }
47
+ /**
48
+ * Build the entry for a chat-v2 dispatch that reached at least one agent.
49
+ *
50
+ * Responsible agent: the first recipient that had to answer; with nobody
51
+ * required (an un-addressed room message the awake agents were only told
52
+ * about), the room lead when it got the message, else the first non-
53
+ * orchestrator recipient. An orchestrator that was only woken to route a
54
+ * private room's message is never made responsible: its hand-off re-dispatches
55
+ * the message, and that dispatch is tracked under the same key.
56
+ *
57
+ * @param channel - Channel the message was recorded in
58
+ * @param message - The owner's turn
59
+ * @param result - Dispatch outcome
60
+ * @param ctx - Owner id and the room lead, when known
61
+ * @returns Track input, or null when nothing should be tracked
62
+ */
63
+ export function trackInputFromDispatch(channel, message, result, ctx = {}) {
64
+ if (!result.dispatched)
65
+ return null;
66
+ if (!isOwnerChatTurn(message, ctx.ownerSlackUserId))
67
+ return null;
68
+ let recipients = [];
69
+ let required = [];
70
+ if (result.strategy === 'dm') {
71
+ if (channel.agentSession)
72
+ recipients = required = [channel.agentSession];
73
+ }
74
+ else if (result.strategy === 'huddle-broadcast') {
75
+ const got = (result.huddleOutcomes ?? []).filter((o) => o.dispatched);
76
+ recipients = got.map((o) => o.sessionName);
77
+ required = got.filter((o) => o.responseMode === 'required').map((o) => o.sessionName);
78
+ }
79
+ else if (result.strategy === 'channel-mentions') {
80
+ recipients = required = (result.mentionOutcomes ?? []).filter((o) => o.dispatched).map((o) => o.target.sessionName);
81
+ }
82
+ if (recipients.length === 0)
83
+ return null;
84
+ let responsible = required[0];
85
+ if (!responsible) {
86
+ const nonOrc = recipients.filter((s) => s !== ORCHESTRATOR_SESSION_NAME);
87
+ responsible = ctx.leader && nonOrc.includes(ctx.leader) ? ctx.leader : nonOrc[0];
88
+ }
89
+ if (!responsible)
90
+ return null;
91
+ const meta = message.metadata ?? {};
92
+ const isHuddle = channel.type !== 'dm';
93
+ // When the owner wrote it: the timeline starts there, and an answer that
94
+ // beat this call (a fast agent while a colleague cold-starts) still counts.
95
+ const receivedAt = typeof message.createdAt === 'number' && message.createdAt > 0 ? { receivedAt: message.createdAt } : {};
96
+ const chatThreadId = isHuddle ? message.threadId ?? message.id : undefined;
97
+ const slackChannelId = meta.source === 'slack' && typeof meta.slackChannelId === 'string' ? meta.slackChannelId : undefined;
98
+ if (slackChannelId) {
99
+ const sourceTs = typeof meta.slackTs === 'string' ? meta.slackTs : undefined;
100
+ const threadTs = typeof meta.slackThreadTs === 'string' ? meta.slackThreadTs : sourceTs;
101
+ return {
102
+ surface: 'slack',
103
+ slackChannelId,
104
+ ...(threadTs ? { threadTs } : {}),
105
+ ...(sourceTs ? { sourceTs } : {}),
106
+ chatChannelId: channel.id,
107
+ ...(chatThreadId ? { chatThreadId } : {}),
108
+ messageId: message.id,
109
+ responsible,
110
+ recipients,
111
+ required: required.length > 0,
112
+ text: message.content ?? '',
113
+ ...receivedAt,
114
+ };
115
+ }
116
+ return {
117
+ surface: 'chat',
118
+ chatChannelId: channel.id,
119
+ ...(chatThreadId ? { chatThreadId } : {}),
120
+ messageId: message.id,
121
+ responsible,
122
+ recipients,
123
+ required: required.length > 0,
124
+ text: message.content ?? '',
125
+ ...receivedAt,
126
+ };
127
+ }
128
+ /**
129
+ * Login hint for a runtime waiting on a sign-in ("reply 重新登录 claude").
130
+ *
131
+ * @param runtimeType - The runtime type recorded with the login request, if any
132
+ * @returns The hint
133
+ */
134
+ export function loginHintFor(runtimeType) {
135
+ const rt = (runtimeType ?? '').toLowerCase();
136
+ if (rt.includes('codex'))
137
+ return { runtime: 'Codex', runtimeCmd: 'codex' };
138
+ if (rt.includes('gemini') || rt.includes('antigravity'))
139
+ return { runtime: 'Gemini', runtimeCmd: 'gemini' };
140
+ return { runtime: 'Claude', runtimeCmd: 'claude' };
141
+ }
142
+ /**
143
+ * The reminder delivered to the responsible agent. Carries the same routing
144
+ * header a normal delivery does, so the agent's `reply` goes back to the
145
+ * owner's conversation (and thread).
146
+ *
147
+ * @param entry - The unanswered message
148
+ * @param waitedMinutes - How long it has waited
149
+ * @param opts - `withHeader: false` when the transport adds its own `[CHAT:…]` header (the orchestrator's queue)
150
+ * @returns The text to deliver
151
+ */
152
+ export function buildNudgeMessage(entry, waitedMinutes, opts = {}) {
153
+ const identity = /^[A-Za-z0-9._-]+$/.test(entry.responsible) ? `CREWLY_SESSION_NAME=${entry.responsible} ` : '';
154
+ const replyCmd = `${identity}bash ${AGENT_REPLY_CONSTANTS.SKILL_PATH} "<你的回复>"`;
155
+ const noneCmd = `${identity}bash ${AGENT_REPLY_CONSTANTS.SKILL_PATH} --none`;
156
+ const withHeader = opts.withHeader ?? true;
157
+ const head = withHeader && entry.chatChannelId ? `[CHAT:${entry.chatChannelId}] <owner@reminder>` : null;
158
+ const threadTag = entry.surface === 'slack' && entry.slackChannelId && (entry.threadTs ?? entry.sourceTs)
159
+ ? slackThreadTag(entry.slackChannelId, (entry.threadTs ?? entry.sourceTs))
160
+ : null;
161
+ return [
162
+ ...(head ? [head] : []),
163
+ ...(threadTag ? [threadTag] : []),
164
+ '',
165
+ C.NUDGE_TEXT.replace('{waited}', String(waitedMinutes)).replace('{replyCmd}', replyCmd).replace('{noneCmd}', noneCmd),
166
+ '',
167
+ `owner 的原话: ${entry.preview}`,
168
+ ].join('\n');
169
+ }
170
+ /** chat-v2 metadata flag on the watchdog's own chat notes (never taken as an answer). */
171
+ export const OWNER_WATCHDOG_NOTE_METADATA_KEY = 'ownerWatchdogNote';
172
+ /**
173
+ * Re-deliver an unanswered message to its responsible agent.
174
+ *
175
+ * @param deps - Wiring deps
176
+ * @param entry - The message
177
+ * @param waited - Minutes waited
178
+ * @returns Sent, or blocked with the reason
179
+ */
180
+ export async function nudgeAgent(deps, entry, waited) {
181
+ const session = entry.responsible;
182
+ if (session === ORCHESTRATOR_SESSION_NAME) {
183
+ const text = buildNudgeMessage(entry, waited, { withHeader: false });
184
+ if (!entry.chatChannelId)
185
+ return { outcome: 'blocked', reason: 'error', detail: 'no conversation to re-deliver to' };
186
+ try {
187
+ deps.enqueueForOrchestrator({
188
+ content: text,
189
+ conversationId: entry.chatChannelId,
190
+ source: entry.surface === 'slack' ? MESSAGE_SOURCES.SLACK : MESSAGE_SOURCES.WEB_CHAT,
191
+ ...(entry.surface === 'slack' && entry.slackChannelId
192
+ ? { sourceMetadata: { channelId: entry.slackChannelId, threadTs: entry.threadTs ?? entry.sourceTs } }
193
+ : {}),
194
+ });
195
+ return { outcome: 'sent' };
196
+ }
197
+ catch (err) {
198
+ return { outcome: 'blocked', reason: 'error', detail: err instanceof Error ? err.message : String(err) };
199
+ }
200
+ }
201
+ const text = buildNudgeMessage(entry, waited);
202
+ let woke = false;
203
+ if (!deps.sessionExists(session)) {
204
+ const res = await deps.activate(session).catch((err) => ({ success: false, error: err instanceof Error ? err.message : String(err) }));
205
+ if (!res.success)
206
+ return { outcome: 'blocked', reason: 'asleep', detail: res.error ?? 'activation failed' };
207
+ woke = true;
208
+ }
209
+ let result = await deps.sendToAgent(session, text).catch((err) => ({ success: false, error: err instanceof Error ? err.message : String(err) }));
210
+ if (!result.success && !woke && !deps.sessionExists(session)) {
211
+ const res = await deps.activate(session).catch((err) => ({ success: false, error: err instanceof Error ? err.message : String(err) }));
212
+ if (!res.success)
213
+ return { outcome: 'blocked', reason: 'asleep', detail: res.error ?? 'activation failed' };
214
+ result = await deps.sendToAgent(session, text).catch((err) => ({ success: false, error: err instanceof Error ? err.message : String(err) }));
215
+ }
216
+ if (!result.success)
217
+ return { outcome: 'blocked', reason: 'error', detail: result.error ?? 'delivery failed' };
218
+ if (entry.chatChannelId)
219
+ deps.noteOriginThread?.(session, entry.chatChannelId, entry.chatThreadId);
220
+ return { outcome: 'sent' };
221
+ }
222
+ /**
223
+ * Post the note where the owner wrote: the Slack thread (Crewly's master bot;
224
+ * in an agent-owned DM the agent's bot, the only one that can post there), or
225
+ * a system turn in the chat channel.
226
+ *
227
+ * @param deps - Wiring deps
228
+ * @param entry - The message
229
+ * @param text - The note
230
+ * @returns True when posted
231
+ */
232
+ export async function postOwnerNote(deps, entry, text) {
233
+ if (entry.surface === 'chat') {
234
+ if (!entry.chatChannelId)
235
+ return false;
236
+ return deps.recordChatNote(entry.chatChannelId, entry.chatThreadId, text);
237
+ }
238
+ const slack = deps.slack();
239
+ if (!slack?.isConnected() || !entry.slackChannelId)
240
+ return false;
241
+ const threadTs = entry.threadTs ?? entry.sourceTs;
242
+ const base = { channelId: entry.slackChannelId, text, ...(threadTs ? { threadTs } : {}), notAnAnswer: true, skipChatV2Mirror: true };
243
+ const dmToken = deps.agentDmBotToken(entry.slackChannelId);
244
+ try {
245
+ await slack.sendMessage(dmToken ? { ...base, botToken: dmToken } : base);
246
+ return true;
247
+ }
248
+ catch (err) {
249
+ const fallback = !dmToken ? deps.botTokenOf(entry.responsible) : undefined;
250
+ if (!fallback)
251
+ throw err;
252
+ await slack.sendMessage({ ...base, botToken: fallback });
253
+ return true;
254
+ }
255
+ }
256
+ /**
257
+ * Build the watchdog on the real transports and expose it as the singleton.
258
+ *
259
+ * @param deps - Wiring deps
260
+ * @returns The started watchdog
261
+ */
262
+ export function createOwnerMessageWatchdog(deps) {
263
+ const service = new OwnerMessageWatchdogService({
264
+ isBusy: deps.isBusy,
265
+ hasVisiblePlaceholder: (entry) => {
266
+ const threadTs = entry.threadTs ?? entry.sourceTs;
267
+ return !!entry.slackChannelId && !!threadTs && deps.owesThread(entry.slackChannelId, threadTs);
268
+ },
269
+ nudge: (entry, waited) => nudgeAgent(deps, entry, waited),
270
+ postNote: (entry, text) => postOwnerNote(deps, entry, text),
271
+ loginRequired: (session) => {
272
+ const info = deps.loginRequired(session);
273
+ return info ? loginHintFor(info.runtimeType) : null;
274
+ },
275
+ ...(deps.displayNameOf ? { displayNameOf: deps.displayNameOf } : {}),
276
+ storePath: path.join(deps.crewlyHome, C.STORE_FILENAME),
277
+ });
278
+ setOwnerMessageWatchdog(service);
279
+ service.start();
280
+ return service;
281
+ }
282
+ // ---------------------------------------------------------------------------
283
+ // Answer signals
284
+ // ---------------------------------------------------------------------------
285
+ /**
286
+ * Feed a chat-v2 turn to the watchdog: an agent turn in a watched chat
287
+ * channel is the answer (an interim one is a visible "working on it").
288
+ *
289
+ * @param service - The watchdog
290
+ * @param dto - The recorded turn
291
+ */
292
+ export function onChatTurn(service, dto) {
293
+ if (dto.senderType !== 'agent')
294
+ return;
295
+ if (dto.metadata?.[OWNER_WATCHDOG_NOTE_METADATA_KEY])
296
+ return;
297
+ const interim = dto.metadata?.[SLACK_TYPING_CONSTANTS.INTERIM_METADATA_KEY] === true;
298
+ service.noteChatAnswer(dto.channelId, dto.threadId ?? null, interim);
299
+ }
300
+ /**
301
+ * Feed a Slack post made through this machine's SlackService.
302
+ *
303
+ * @param service - The watchdog
304
+ * @param post - Channel, thread and whether it was flagged as not an answer
305
+ */
306
+ export function onSlackOutbound(service, post) {
307
+ if (post.notAnAnswer)
308
+ return;
309
+ service.noteSlackAnswer(post.channelId, post.threadTs, post.kind ?? 'post');
310
+ }
311
+ /**
312
+ * Feed an inbound Slack message: a colleague agent (any machine) posting in
313
+ * a watched thread answered it.
314
+ *
315
+ * @param service - The watchdog
316
+ * @param message - Inbound message fields
317
+ */
318
+ export function onSlackInbound(service, message) {
319
+ if (!message.authorAgentSession || !message.threadTs)
320
+ return;
321
+ service.noteSlackAnswer(message.channelId, message.threadTs, `agent ${message.authorAgentSession} posted`);
322
+ }
323
+ /** Log once when wiring is skipped (kept here so index.ts stays thin). */
324
+ export function logWiringSkipped(reason) {
325
+ logger.warn('Owner message watchdog not started', { reason });
326
+ }
327
+ //# sourceMappingURL=owner-message-watchdog.wiring.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"owner-message-watchdog.wiring.js","sourceRoot":"","sources":["../../../../../../backend/src/services/messaging/owner-message-watchdog.wiring.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Where an agent's `reply` goes — decided by the harness from the delivery
3
+ * the agent is answering, not by the agent picking the right tool and ids.
4
+ *
5
+ * Agents had to choose between reply-channel / reply-chat / reply-slack /
6
+ * report-status and pass the right ids; Codex agents in particular got this
7
+ * wrong and the owner's answer went to the orchestrator as "status" or into
8
+ * the wrong conversation. `reply "<text>"` names nothing: the answer goes to
9
+ * the turn origin recorded when the owner's message was delivered
10
+ * (`OrcReplyRouteService`). Explicit ids that are the agent's own still win.
11
+ *
12
+ * @module services/orc/agent-reply-target
13
+ * @see specs/2026-09-30-owner-message-guarantee.md §B
14
+ */
15
+ import type { TurnOrigin } from './orc-reply-route.service.js';
16
+ /** The decision. */
17
+ export type AgentReplyPlan =
18
+ /** A report-status line: to the orchestrator, exactly like report-status. */
19
+ {
20
+ kind: 'status';
21
+ }
22
+ /** No answer needed: close what the agent was asked, post nothing. */
23
+ | {
24
+ kind: 'none';
25
+ origin?: TurnOrigin;
26
+ }
27
+ /** Post as the agent into a chat-v2 conversation (DM / room / huddle), in `thread` when set. */
28
+ | {
29
+ kind: 'post';
30
+ conversationId: string;
31
+ thread?: string;
32
+ via: 'explicit' | 'origin';
33
+ reason: string;
34
+ }
35
+ /** The orchestrator answering a Slack thread it was asked in through the master bot. */
36
+ | {
37
+ kind: 'orc-slack';
38
+ channelId: string;
39
+ threadTs?: string;
40
+ reason: string;
41
+ }
42
+ /** The orchestrator answering in a chat conversation (its own reply routing applies). */
43
+ | {
44
+ kind: 'orc-chat';
45
+ conversationId?: string;
46
+ reason: string;
47
+ }
48
+ /** Nothing to answer into. */
49
+ | {
50
+ kind: 'no-target';
51
+ reason: string;
52
+ };
53
+ /** Inputs of {@link planAgentReply}. */
54
+ export interface AgentReplyRequest {
55
+ /** Replying session (X-Agent-Session) */
56
+ session: string;
57
+ /** Whether it is the orchestrator */
58
+ isOrchestrator: boolean;
59
+ /** Reply text ('' with `none`) */
60
+ content: string;
61
+ /** `reply --none`: no answer needed */
62
+ none?: boolean;
63
+ /** Ids the agent passed, if any (may be missing, legacy or wrong) */
64
+ requested?: {
65
+ conversationId?: string;
66
+ thread?: string;
67
+ };
68
+ /** The recorded turn origin */
69
+ origin?: TurnOrigin;
70
+ /** Whether `conversationId` is one this agent may answer in (its DM, a room it is in) */
71
+ ownsConversation: (conversationId: string) => boolean;
72
+ }
73
+ /**
74
+ * Whether text is a report-status line for the orchestrator.
75
+ *
76
+ * @param content - Reply text
77
+ * @returns True for `[DONE]`, `[WORKING]`, … at the start
78
+ */
79
+ export declare function isStatusReport(content: string): boolean;
80
+ /**
81
+ * The thread an origin's answer belongs in: the Slack thread key when the
82
+ * message came from Slack, else the chat-v2 thread.
83
+ *
84
+ * @param origin - Turn origin
85
+ * @returns Thread reference, or undefined
86
+ */
87
+ export declare function originThread(origin: TurnOrigin | undefined): string | undefined;
88
+ /**
89
+ * Decide where a reply goes.
90
+ *
91
+ * @param req - Who is replying, what, the ids it passed and its turn origin
92
+ * @returns The plan
93
+ */
94
+ export declare function planAgentReply(req: AgentReplyRequest): AgentReplyPlan;
95
+ //# sourceMappingURL=agent-reply-target.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-reply-target.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/orc/agent-reply-target.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAE/D,oBAAoB;AACpB,MAAM,MAAM,cAAc;AACxB,6EAA6E;AAC3E;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE;AACpB,sEAAsE;GACpE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,UAAU,CAAA;CAAE;AACvC,gGAAgG;GAC9F;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,UAAU,GAAG,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE;AACvG,wFAAwF;GACtF;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE;AAC7E,yFAAyF;GACvF;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE;AAC/D,8BAA8B;GAC5B;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1C,wCAAwC;AACxC,MAAM,WAAW,iBAAiB;IAChC,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,qCAAqC;IACrC,cAAc,EAAE,OAAO,CAAC;IACxB,kCAAkC;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,qEAAqE;IACrE,SAAS,CAAC,EAAE;QAAE,cAAc,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACzD,+BAA+B;IAC/B,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,yFAAyF;IACzF,gBAAgB,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,OAAO,CAAC;CACvD;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAE/E;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,iBAAiB,GAAG,cAAc,CA2CrE"}