crewly 1.20.152 → 1.20.153
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.
- package/config/roles/orchestrator/prompt.md +7 -0
- package/config/roles/team-leader/prompt.md +6 -0
- package/config/sops/developer/git-workflow.md +1 -0
- package/dist/backend/backend/src/constants.d.ts +92 -0
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +92 -0
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/worktree-janitor/worktree-janitor.routes.d.ts +29 -0
- package/dist/backend/backend/src/controllers/worktree-janitor/worktree-janitor.routes.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/worktree-janitor/worktree-janitor.routes.js +63 -0
- package/dist/backend/backend/src/controllers/worktree-janitor/worktree-janitor.routes.js.map +1 -0
- package/dist/backend/backend/src/index.d.ts +7 -0
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +114 -2
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/routes/api.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/routes/api.routes.js +3 -0
- package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/decision-rights.module.d.ts +18 -3
- package/dist/backend/backend/src/services/ai/prompt-modules/decision-rights.module.d.ts.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/decision-rights.module.js +28 -4
- package/dist/backend/backend/src/services/ai/prompt-modules/decision-rights.module.js.map +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-sync.types.d.ts +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-sync.types.d.ts.map +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-sync.types.js +1 -0
- package/dist/backend/backend/src/services/cloud/cloud-sync.types.js.map +1 -1
- package/dist/backend/backend/src/services/cloud/waiting-actions-inbound.service.d.ts +128 -0
- package/dist/backend/backend/src/services/cloud/waiting-actions-inbound.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/cloud/waiting-actions-inbound.service.js +279 -0
- package/dist/backend/backend/src/services/cloud/waiting-actions-inbound.service.js.map +1 -0
- package/dist/backend/backend/src/services/cloud/waiting-items-sync.service.d.ts +122 -0
- package/dist/backend/backend/src/services/cloud/waiting-items-sync.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/cloud/waiting-items-sync.service.js +261 -0
- package/dist/backend/backend/src/services/cloud/waiting-items-sync.service.js.map +1 -0
- package/dist/backend/backend/src/services/cloud/waiting-items.contract.d.ts +101 -0
- package/dist/backend/backend/src/services/cloud/waiting-items.contract.d.ts.map +1 -0
- package/dist/backend/backend/src/services/cloud/waiting-items.contract.js +113 -0
- package/dist/backend/backend/src/services/cloud/waiting-items.contract.js.map +1 -0
- package/dist/backend/backend/src/services/slack/slack-initializer.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-initializer.js +2 -1
- package/dist/backend/backend/src/services/slack/slack-initializer.js.map +1 -1
- package/dist/backend/backend/src/services/v3/request.service.d.ts +19 -0
- package/dist/backend/backend/src/services/v3/request.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/request.service.js +36 -0
- package/dist/backend/backend/src/services/v3/request.service.js.map +1 -1
- package/dist/backend/backend/src/services/worktree/worktree-janitor.git.d.ts +131 -0
- package/dist/backend/backend/src/services/worktree/worktree-janitor.git.d.ts.map +1 -0
- package/dist/backend/backend/src/services/worktree/worktree-janitor.git.js +238 -0
- package/dist/backend/backend/src/services/worktree/worktree-janitor.git.js.map +1 -0
- package/dist/backend/backend/src/services/worktree/worktree-janitor.service.d.ts +241 -0
- package/dist/backend/backend/src/services/worktree/worktree-janitor.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/worktree/worktree-janitor.service.js +504 -0
- package/dist/backend/backend/src/services/worktree/worktree-janitor.service.js.map +1 -0
- package/dist/backend/build-info.json +2 -2
- package/dist/cli/backend/src/constants.d.ts +92 -0
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +92 -0
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/services/ai/prompt-modules/decision-rights.module.d.ts +18 -3
- package/dist/cli/backend/src/services/ai/prompt-modules/decision-rights.module.d.ts.map +1 -1
- package/dist/cli/backend/src/services/ai/prompt-modules/decision-rights.module.js +28 -4
- package/dist/cli/backend/src/services/ai/prompt-modules/decision-rights.module.js.map +1 -1
- package/dist/cli/backend/src/services/cloud/cloud-sync.types.d.ts +1 -1
- package/dist/cli/backend/src/services/cloud/cloud-sync.types.d.ts.map +1 -1
- package/dist/cli/backend/src/services/cloud/cloud-sync.types.js +1 -0
- package/dist/cli/backend/src/services/cloud/cloud-sync.types.js.map +1 -1
- package/dist/cli/backend/src/services/v3/request.service.d.ts +19 -0
- package/dist/cli/backend/src/services/v3/request.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/v3/request.service.js +36 -0
- package/dist/cli/backend/src/services/v3/request.service.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WaitingItemsSyncService — keeps Crewly Cloud's "Waiting on you" list in
|
|
3
|
+
* step with this machine (specs/unified-conversations-cloud-store.md §F,
|
|
4
|
+
* Phase 5).
|
|
5
|
+
*
|
|
6
|
+
* "Waiting on you" = tickets in 待验收 (board column `to_review`): work an
|
|
7
|
+
* agent handed back for the owner's OK. The column is derived, not stored,
|
|
8
|
+
* so this service recomputes the set and uploads a text snapshot
|
|
9
|
+
* (`POST /api/cloud/conversations/waiting/ingest`, `full: true`) whenever it
|
|
10
|
+
* changed:
|
|
11
|
+
*
|
|
12
|
+
* - on a Request write (RequestService.onChange), gathered for 2 s;
|
|
13
|
+
* - on a 30 s check (a WorkItem finishing can move a ticket into 待验收
|
|
14
|
+
* without touching its Request file) — uploads only when the set differs
|
|
15
|
+
* from what Cloud last took;
|
|
16
|
+
* - every 5 minutes regardless (a full resync: Cloud refreshes the items'
|
|
17
|
+
* `syncedAt`, so the portal knows the machine is alive, and drops anything
|
|
18
|
+
* this machine no longer has);
|
|
19
|
+
* - after an accept / send-back from the portal was carried out.
|
|
20
|
+
*
|
|
21
|
+
* Every upload is the whole set, so a ticket that left 待验收 disappears in
|
|
22
|
+
* Cloud with the next upload. Uses the machine's own Cloud token (same as
|
|
23
|
+
* the conversation uploader); signed out = nothing is sent. The conversation
|
|
24
|
+
* sync kill switch (`CREWLY_CONVERSATION_SYNC=0`) turns this off too.
|
|
25
|
+
*
|
|
26
|
+
* @module services/cloud/waiting-items-sync.service
|
|
27
|
+
*/
|
|
28
|
+
import { WAITING_SYNC_CONSTANTS } from '../../constants.js';
|
|
29
|
+
import { LoggerService } from '../core/logger.service.js';
|
|
30
|
+
import { accountIdOfToken, isConversationSyncDisabled } from './conversation-cloud-sync.service.js';
|
|
31
|
+
import { INSTANCE_ID_PATTERN } from './conversation-ingest.contract.js';
|
|
32
|
+
import { toWaitingIngestItem } from './waiting-items.contract.js';
|
|
33
|
+
const C = WAITING_SYNC_CONSTANTS;
|
|
34
|
+
/** Uploads the machine's "waiting on you" set to Crewly Cloud. */
|
|
35
|
+
export class WaitingItemsSyncService {
|
|
36
|
+
deps;
|
|
37
|
+
logger;
|
|
38
|
+
fetchImpl;
|
|
39
|
+
now;
|
|
40
|
+
setTimer;
|
|
41
|
+
clearTimer;
|
|
42
|
+
started = false;
|
|
43
|
+
running = null;
|
|
44
|
+
rerun = false;
|
|
45
|
+
checkTimer = null;
|
|
46
|
+
debounceTimer = null;
|
|
47
|
+
unsubscribe = null;
|
|
48
|
+
/** Snapshot Cloud last took (items + capabilities), per account. */
|
|
49
|
+
lastKey = null;
|
|
50
|
+
lastAccount = null;
|
|
51
|
+
lastFullAt = 0;
|
|
52
|
+
failures = 0;
|
|
53
|
+
pausedUntil = 0;
|
|
54
|
+
pauseLogged = false;
|
|
55
|
+
constructor(deps) {
|
|
56
|
+
this.deps = deps;
|
|
57
|
+
this.logger = deps.logger ?? LoggerService.getInstance().createComponentLogger('WaitingItemsSync');
|
|
58
|
+
this.fetchImpl = deps.fetchImpl ?? ((input, init) => fetch(input, init));
|
|
59
|
+
this.now = deps.now ?? Date.now;
|
|
60
|
+
this.setTimer = deps.setTimeout ?? ((fn, ms) => setTimeout(fn, ms));
|
|
61
|
+
this.clearTimer = deps.clearTimeout ?? ((h) => clearTimeout(h));
|
|
62
|
+
}
|
|
63
|
+
/** Start watching tickets and the periodic check. Idempotent; never throws. */
|
|
64
|
+
start() {
|
|
65
|
+
if (this.started)
|
|
66
|
+
return;
|
|
67
|
+
this.started = true;
|
|
68
|
+
try {
|
|
69
|
+
this.unsubscribe = this.deps.onTicketChange?.(() => this.requestSync()) ?? null;
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
this.unsubscribe = null;
|
|
73
|
+
}
|
|
74
|
+
this.scheduleCheck(0);
|
|
75
|
+
}
|
|
76
|
+
/** Stop timers and the ticket subscription. */
|
|
77
|
+
stop() {
|
|
78
|
+
this.started = false;
|
|
79
|
+
if (this.checkTimer)
|
|
80
|
+
this.clearTimer(this.checkTimer);
|
|
81
|
+
if (this.debounceTimer)
|
|
82
|
+
this.clearTimer(this.debounceTimer);
|
|
83
|
+
this.checkTimer = null;
|
|
84
|
+
this.debounceTimer = null;
|
|
85
|
+
try {
|
|
86
|
+
this.unsubscribe?.();
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
// ignore
|
|
90
|
+
}
|
|
91
|
+
this.unsubscribe = null;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Upload soon (after the 2 s gather) — a ticket changed, or an action from
|
|
95
|
+
* the portal was carried out.
|
|
96
|
+
*/
|
|
97
|
+
requestSync() {
|
|
98
|
+
if (!this.started || this.debounceTimer)
|
|
99
|
+
return;
|
|
100
|
+
this.debounceTimer = this.setTimer(() => {
|
|
101
|
+
this.debounceTimer = null;
|
|
102
|
+
void this.syncNow();
|
|
103
|
+
}, C.DEBOUNCE_MS);
|
|
104
|
+
}
|
|
105
|
+
/** Keep the periodic check going. */
|
|
106
|
+
scheduleCheck(delayMs = C.CHECK_INTERVAL_MS) {
|
|
107
|
+
if (!this.started)
|
|
108
|
+
return;
|
|
109
|
+
this.checkTimer = this.setTimer(() => {
|
|
110
|
+
this.checkTimer = null;
|
|
111
|
+
void this.syncNow().finally(() => this.scheduleCheck());
|
|
112
|
+
}, delayMs);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Recompute the set and upload it when it changed (or a full resync is
|
|
116
|
+
* due). One upload at a time; a call during one runs again after it.
|
|
117
|
+
* Never throws.
|
|
118
|
+
*
|
|
119
|
+
* @param force - Upload even when nothing changed
|
|
120
|
+
* @returns What happened
|
|
121
|
+
*/
|
|
122
|
+
async syncNow(force = false) {
|
|
123
|
+
if (this.running) {
|
|
124
|
+
this.rerun = true;
|
|
125
|
+
return this.running;
|
|
126
|
+
}
|
|
127
|
+
this.running = (async () => {
|
|
128
|
+
let outcome = 'skipped';
|
|
129
|
+
try {
|
|
130
|
+
do {
|
|
131
|
+
this.rerun = false;
|
|
132
|
+
outcome = await this.pass(force);
|
|
133
|
+
} while (this.rerun);
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
this.logger.warn('Waiting items sync failed', { error: error instanceof Error ? error.message : String(error) });
|
|
137
|
+
outcome = 'failed';
|
|
138
|
+
}
|
|
139
|
+
return outcome;
|
|
140
|
+
})();
|
|
141
|
+
try {
|
|
142
|
+
return await this.running;
|
|
143
|
+
}
|
|
144
|
+
finally {
|
|
145
|
+
this.running = null;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
async pass(force) {
|
|
149
|
+
if (isConversationSyncDisabled(this.deps.env ?? process.env))
|
|
150
|
+
return 'skipped';
|
|
151
|
+
const token = this.deps.cloud.getToken();
|
|
152
|
+
const base = this.deps.cloud.getCloudUrl();
|
|
153
|
+
if (!token || !base)
|
|
154
|
+
return 'skipped';
|
|
155
|
+
if (this.now() < this.pausedUntil)
|
|
156
|
+
return 'paused';
|
|
157
|
+
const account = accountIdOfToken(token);
|
|
158
|
+
if (account !== this.lastAccount) {
|
|
159
|
+
// New sign-in or another account: the first upload is a full one.
|
|
160
|
+
this.lastAccount = account;
|
|
161
|
+
this.lastKey = null;
|
|
162
|
+
this.lastFullAt = 0;
|
|
163
|
+
}
|
|
164
|
+
const { instanceId, deviceName } = await this.deps.identity();
|
|
165
|
+
if (!INSTANCE_ID_PATTERN.test(instanceId))
|
|
166
|
+
return 'skipped';
|
|
167
|
+
const rows = await this.deps.listWaiting();
|
|
168
|
+
const names = await this.deps.agentNames?.().catch(() => new Map());
|
|
169
|
+
const items = rows
|
|
170
|
+
.filter((r) => r.column === 'to_review')
|
|
171
|
+
.map((r) => toWaitingIngestItem(r, (s) => names?.get(s)))
|
|
172
|
+
.sort((a, b) => a.ticketId.localeCompare(b.ticketId));
|
|
173
|
+
let capabilities = [];
|
|
174
|
+
try {
|
|
175
|
+
capabilities = this.deps.capabilities?.() ?? [];
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
capabilities = [];
|
|
179
|
+
}
|
|
180
|
+
const key = JSON.stringify([items, capabilities, deviceName ?? null]);
|
|
181
|
+
const fullDue = this.now() - this.lastFullAt >= C.FULL_SYNC_INTERVAL_MS;
|
|
182
|
+
if (!force && !fullDue && key === this.lastKey)
|
|
183
|
+
return 'unchanged';
|
|
184
|
+
const version = (await this.deps.crewlyVersion?.().catch(() => undefined)) ?? undefined;
|
|
185
|
+
const body = {
|
|
186
|
+
instanceId,
|
|
187
|
+
...(deviceName ? { deviceName } : {}),
|
|
188
|
+
...(version ? { crewlyVersion: version } : {}),
|
|
189
|
+
full: true,
|
|
190
|
+
items,
|
|
191
|
+
capabilities,
|
|
192
|
+
};
|
|
193
|
+
return this.upload(base, token, body, key);
|
|
194
|
+
}
|
|
195
|
+
/** POST the snapshot and book the outcome. */
|
|
196
|
+
async upload(base, token, body, key) {
|
|
197
|
+
const url = `${base.replace(/\/$/, '')}${C.INGEST_PATH}`;
|
|
198
|
+
let status = 0;
|
|
199
|
+
let code = null;
|
|
200
|
+
try {
|
|
201
|
+
const response = await this.fetchImpl(url, {
|
|
202
|
+
method: 'POST',
|
|
203
|
+
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
|
204
|
+
body: JSON.stringify(body),
|
|
205
|
+
signal: AbortSignal.timeout(C.REQUEST_TIMEOUT_MS),
|
|
206
|
+
});
|
|
207
|
+
status = response.status;
|
|
208
|
+
if (response.ok) {
|
|
209
|
+
this.lastKey = key;
|
|
210
|
+
this.lastFullAt = this.now();
|
|
211
|
+
this.failures = 0;
|
|
212
|
+
if (this.pauseLogged) {
|
|
213
|
+
this.pauseLogged = false;
|
|
214
|
+
this.logger.info('Crewly Cloud is taking "waiting on you" updates again');
|
|
215
|
+
}
|
|
216
|
+
this.logger.debug('Waiting items uploaded', { count: body.items.length });
|
|
217
|
+
return 'uploaded';
|
|
218
|
+
}
|
|
219
|
+
const parsed = (await response.json().catch(() => null));
|
|
220
|
+
code = typeof parsed?.code === 'string' ? parsed.code : null;
|
|
221
|
+
}
|
|
222
|
+
catch (error) {
|
|
223
|
+
code = error instanceof Error ? error.message : String(error);
|
|
224
|
+
}
|
|
225
|
+
if (status === 404 || status === 400 || status === 503 || (status === 403 && code === 'sync_disabled')) {
|
|
226
|
+
// Not deployed yet, refused, key missing or switched off: check again in an hour.
|
|
227
|
+
this.pausedUntil = this.now() + C.UNAVAILABLE_RETRY_MS;
|
|
228
|
+
if (!this.pauseLogged) {
|
|
229
|
+
this.pauseLogged = true;
|
|
230
|
+
this.logger.info('Crewly Cloud is not taking "waiting on you" updates right now; checking again in an hour', { status, code });
|
|
231
|
+
}
|
|
232
|
+
return 'paused';
|
|
233
|
+
}
|
|
234
|
+
if (status === 401)
|
|
235
|
+
void this.deps.cloud.tryRefreshToken?.().catch(() => false);
|
|
236
|
+
this.failures += 1;
|
|
237
|
+
const delay = Math.min(C.BACKOFF_INITIAL_MS * 2 ** (this.failures - 1), C.BACKOFF_MAX_MS);
|
|
238
|
+
this.pausedUntil = this.now() + delay;
|
|
239
|
+
if (this.failures === 1)
|
|
240
|
+
this.logger.warn('Waiting items upload failed; will retry', { status, code, retryInMs: delay });
|
|
241
|
+
return 'failed';
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
let instance = null;
|
|
245
|
+
/**
|
|
246
|
+
* Install the process-wide instance (composition root).
|
|
247
|
+
*
|
|
248
|
+
* @param service - The service, or null
|
|
249
|
+
*/
|
|
250
|
+
export function setWaitingItemsSyncService(service) {
|
|
251
|
+
instance = service;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* The process-wide instance, or null before wiring.
|
|
255
|
+
*
|
|
256
|
+
* @returns The service or null
|
|
257
|
+
*/
|
|
258
|
+
export function getWaitingItemsSyncService() {
|
|
259
|
+
return instance;
|
|
260
|
+
}
|
|
261
|
+
//# sourceMappingURL=waiting-items-sync.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"waiting-items-sync.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/cloud/waiting-items-sync.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "Waiting on you" wire contract, machine side — mirrors
|
|
3
|
+
* `AUTH:conversations/waiting.contract.ts` (crewly-services). Change them
|
|
4
|
+
* together.
|
|
5
|
+
*
|
|
6
|
+
* POST /api/cloud/conversations/waiting/ingest machine snapshot of its 待验收 tickets
|
|
7
|
+
* GET /api/cloud/conversations/waiting/actions/:actionId?instanceId= fetch a pushed action
|
|
8
|
+
* POST /api/cloud/conversations/waiting/actions/:actionId/result report what happened
|
|
9
|
+
* relay `waiting_action` {v, actionId, itemId, instanceId, ticketId} Cloud → machine (ids only)
|
|
10
|
+
*
|
|
11
|
+
* Pure (no I/O).
|
|
12
|
+
*
|
|
13
|
+
* @module services/cloud/waiting-items.contract
|
|
14
|
+
*/
|
|
15
|
+
import type { TicketListItem } from '../v3/ticket-intake.service.js';
|
|
16
|
+
/** One ticket in 待验收 as the machine uploads it (text only). */
|
|
17
|
+
export interface WaitingIngestItem {
|
|
18
|
+
/** Request id (stable). */
|
|
19
|
+
ticketId: string;
|
|
20
|
+
/** `TKT-12` */
|
|
21
|
+
tkt?: string;
|
|
22
|
+
title: string;
|
|
23
|
+
/** Start of the agent's answer. */
|
|
24
|
+
excerpt?: string;
|
|
25
|
+
/** Agent that answered (local session name). */
|
|
26
|
+
agentSession?: string;
|
|
27
|
+
agentName?: string;
|
|
28
|
+
/** When it went to 待验收 (ISO). */
|
|
29
|
+
since: string;
|
|
30
|
+
/** When silence accepts it (ISO), or null. */
|
|
31
|
+
autoAcceptAt: string | null;
|
|
32
|
+
rejectCount: number;
|
|
33
|
+
/** Ticket's last change (ISO). */
|
|
34
|
+
updatedAt: string;
|
|
35
|
+
}
|
|
36
|
+
/** `POST /waiting/ingest` body. */
|
|
37
|
+
export interface WaitingIngestRequest {
|
|
38
|
+
instanceId: string;
|
|
39
|
+
deviceName?: string;
|
|
40
|
+
crewlyVersion?: string;
|
|
41
|
+
/** True = `items` is the whole set; Cloud removes this machine's other items. */
|
|
42
|
+
full: boolean;
|
|
43
|
+
items: WaitingIngestItem[];
|
|
44
|
+
/** Tickets that left 待验收 (delta uploads). */
|
|
45
|
+
removed?: string[];
|
|
46
|
+
capabilities?: string[];
|
|
47
|
+
}
|
|
48
|
+
/** `data` of a `waiting_action` relay push. */
|
|
49
|
+
export interface WaitingActionRelayData {
|
|
50
|
+
v: 1;
|
|
51
|
+
actionId: string;
|
|
52
|
+
itemId: string;
|
|
53
|
+
instanceId: string;
|
|
54
|
+
ticketId: string;
|
|
55
|
+
}
|
|
56
|
+
/** What the owner asked for. */
|
|
57
|
+
export type WaitingActionKind = 'accept' | 'send_back';
|
|
58
|
+
/** `GET /waiting/actions/:actionId?instanceId=` → `data`. */
|
|
59
|
+
export interface WaitingActionFetchResponse {
|
|
60
|
+
actionId: string;
|
|
61
|
+
itemId: string;
|
|
62
|
+
instanceId: string;
|
|
63
|
+
ticketId: string;
|
|
64
|
+
kind: WaitingActionKind;
|
|
65
|
+
/** With `send_back`: what still needs fixing. */
|
|
66
|
+
reason?: string;
|
|
67
|
+
state: 'queued' | 'sent' | 'failed';
|
|
68
|
+
}
|
|
69
|
+
/** `POST /waiting/actions/:actionId/result` body. */
|
|
70
|
+
export interface WaitingActionResultRequest {
|
|
71
|
+
instanceId: string;
|
|
72
|
+
ok: boolean;
|
|
73
|
+
/** Refusal code from the ticket service (`not_in_review`, `open_work`, …). */
|
|
74
|
+
code?: string;
|
|
75
|
+
/** Owner-readable reason when not ok. */
|
|
76
|
+
error?: string;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Validate the `data` of a `waiting_action` push. Never throws.
|
|
80
|
+
*
|
|
81
|
+
* @param raw - `IncomingMessage.payload`
|
|
82
|
+
* @returns The push, or null when it is not one
|
|
83
|
+
*/
|
|
84
|
+
export declare function parseWaitingActionRelayData(raw: unknown): WaitingActionRelayData | null;
|
|
85
|
+
/**
|
|
86
|
+
* Validate Cloud's answer to the action fetch. Never throws.
|
|
87
|
+
*
|
|
88
|
+
* @param raw - Parsed JSON body (`{success, data}`)
|
|
89
|
+
* @returns The action, or null when the body is not usable
|
|
90
|
+
*/
|
|
91
|
+
export declare function parseWaitingActionFetchResponse(raw: unknown): WaitingActionFetchResponse | null;
|
|
92
|
+
/**
|
|
93
|
+
* Shape one board row in 待验收 for Cloud. Ticket mechanics stay internal
|
|
94
|
+
* (the portal shows the title, the agent's words and who said them).
|
|
95
|
+
*
|
|
96
|
+
* @param row - Board row (`column === 'to_review'`)
|
|
97
|
+
* @param nameOf - Display name of an agent session, when known
|
|
98
|
+
* @returns The upload item
|
|
99
|
+
*/
|
|
100
|
+
export declare function toWaitingIngestItem(row: TicketListItem, nameOf?: (session: string) => string | undefined): WaitingIngestItem;
|
|
101
|
+
//# sourceMappingURL=waiting-items.contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"waiting-items.contract.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/cloud/waiting-items.contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAErE,+DAA+D;AAC/D,MAAM,WAAW,iBAAiB;IAChC,2BAA2B;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,mCAAmC;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gDAAgD;IAChD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,8CAA8C;IAC9C,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,kCAAkC;IAClC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,mCAAmC;AACnC,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iFAAiF;IACjF,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC3B,6CAA6C;IAC7C,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,+CAA+C;AAC/C,MAAM,WAAW,sBAAsB;IACrC,CAAC,EAAE,CAAC,CAAC;IACL,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,gCAAgC;AAChC,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,WAAW,CAAC;AAEvD,6DAA6D;AAC7D,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,iBAAiB,CAAC;IACxB,iDAAiD;IACjD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;CACrC;AAED,qDAAqD;AACrD,MAAM,WAAW,0BAA0B;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,OAAO,CAAC;IACZ,8EAA8E;IAC9E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAuBD;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,GAAG,EAAE,OAAO,GAAG,sBAAsB,GAAG,IAAI,CAKvF;AAED;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAAC,GAAG,EAAE,OAAO,GAAG,0BAA0B,GAAG,IAAI,CAgB/F;AAcD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,GAAG,iBAAiB,CAgB5H"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "Waiting on you" wire contract, machine side — mirrors
|
|
3
|
+
* `AUTH:conversations/waiting.contract.ts` (crewly-services). Change them
|
|
4
|
+
* together.
|
|
5
|
+
*
|
|
6
|
+
* POST /api/cloud/conversations/waiting/ingest machine snapshot of its 待验收 tickets
|
|
7
|
+
* GET /api/cloud/conversations/waiting/actions/:actionId?instanceId= fetch a pushed action
|
|
8
|
+
* POST /api/cloud/conversations/waiting/actions/:actionId/result report what happened
|
|
9
|
+
* relay `waiting_action` {v, actionId, itemId, instanceId, ticketId} Cloud → machine (ids only)
|
|
10
|
+
*
|
|
11
|
+
* Pure (no I/O).
|
|
12
|
+
*
|
|
13
|
+
* @module services/cloud/waiting-items.contract
|
|
14
|
+
*/
|
|
15
|
+
import { WAITING_SYNC_CONSTANTS } from '../../constants.js';
|
|
16
|
+
/**
|
|
17
|
+
* Whether a value is a plain object.
|
|
18
|
+
*
|
|
19
|
+
* @param value - Anything
|
|
20
|
+
* @returns True for a non-array object
|
|
21
|
+
*/
|
|
22
|
+
function isRecord(value) {
|
|
23
|
+
return !!value && typeof value === 'object' && !Array.isArray(value);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Whether a value is a non-empty string of at most `max` characters.
|
|
27
|
+
*
|
|
28
|
+
* @param value - Anything
|
|
29
|
+
* @param max - Longest accepted length
|
|
30
|
+
* @returns True when usable as an id
|
|
31
|
+
*/
|
|
32
|
+
function nonEmpty(value, max = 128) {
|
|
33
|
+
return typeof value === 'string' && value.length > 0 && value.length <= max;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Validate the `data` of a `waiting_action` push. Never throws.
|
|
37
|
+
*
|
|
38
|
+
* @param raw - `IncomingMessage.payload`
|
|
39
|
+
* @returns The push, or null when it is not one
|
|
40
|
+
*/
|
|
41
|
+
export function parseWaitingActionRelayData(raw) {
|
|
42
|
+
if (!isRecord(raw))
|
|
43
|
+
return null;
|
|
44
|
+
const { actionId, itemId, instanceId, ticketId } = raw;
|
|
45
|
+
if (!nonEmpty(actionId) || !nonEmpty(itemId, 64) || !nonEmpty(instanceId) || !nonEmpty(ticketId))
|
|
46
|
+
return null;
|
|
47
|
+
return { v: 1, actionId, itemId, instanceId, ticketId };
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Validate Cloud's answer to the action fetch. Never throws.
|
|
51
|
+
*
|
|
52
|
+
* @param raw - Parsed JSON body (`{success, data}`)
|
|
53
|
+
* @returns The action, or null when the body is not usable
|
|
54
|
+
*/
|
|
55
|
+
export function parseWaitingActionFetchResponse(raw) {
|
|
56
|
+
const data = isRecord(raw) && isRecord(raw['data']) ? raw['data'] : null;
|
|
57
|
+
if (!data)
|
|
58
|
+
return null;
|
|
59
|
+
const { actionId, itemId, instanceId, ticketId, kind, reason, state } = data;
|
|
60
|
+
if (!nonEmpty(actionId) || !nonEmpty(itemId, 64) || !nonEmpty(instanceId) || !nonEmpty(ticketId))
|
|
61
|
+
return null;
|
|
62
|
+
if (kind !== 'accept' && kind !== 'send_back')
|
|
63
|
+
return null;
|
|
64
|
+
if (kind === 'send_back' && (typeof reason !== 'string' || reason.trim().length === 0))
|
|
65
|
+
return null;
|
|
66
|
+
return {
|
|
67
|
+
actionId,
|
|
68
|
+
itemId,
|
|
69
|
+
instanceId,
|
|
70
|
+
ticketId,
|
|
71
|
+
kind,
|
|
72
|
+
...(kind === 'send_back' ? { reason: reason.trim() } : {}),
|
|
73
|
+
state: state === 'queued' || state === 'failed' ? state : 'sent',
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Cut text to `max` characters on a character boundary.
|
|
78
|
+
*
|
|
79
|
+
* @param text - Text
|
|
80
|
+
* @param max - Longest length
|
|
81
|
+
* @returns The text, shortened with an ellipsis when needed
|
|
82
|
+
*/
|
|
83
|
+
function cut(text, max) {
|
|
84
|
+
if (text.length <= max)
|
|
85
|
+
return text;
|
|
86
|
+
return `${Array.from(text).slice(0, max - 1).join('')}…`;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Shape one board row in 待验收 for Cloud. Ticket mechanics stay internal
|
|
90
|
+
* (the portal shows the title, the agent's words and who said them).
|
|
91
|
+
*
|
|
92
|
+
* @param row - Board row (`column === 'to_review'`)
|
|
93
|
+
* @param nameOf - Display name of an agent session, when known
|
|
94
|
+
* @returns The upload item
|
|
95
|
+
*/
|
|
96
|
+
export function toWaitingIngestItem(row, nameOf) {
|
|
97
|
+
const agentSession = row.reply?.by ?? row.assignee ?? undefined;
|
|
98
|
+
const agentName = agentSession ? nameOf?.(agentSession) : undefined;
|
|
99
|
+
const excerpt = (row.reply?.excerpt ?? row.description ?? '').trim();
|
|
100
|
+
return {
|
|
101
|
+
ticketId: row.id,
|
|
102
|
+
...(row.tkt ? { tkt: row.tkt } : {}),
|
|
103
|
+
title: cut(row.title.trim() || row.tkt || row.id, WAITING_SYNC_CONSTANTS.MAX_TITLE_CHARS),
|
|
104
|
+
...(excerpt ? { excerpt: cut(excerpt, WAITING_SYNC_CONSTANTS.MAX_EXCERPT_CHARS) } : {}),
|
|
105
|
+
...(agentSession ? { agentSession } : {}),
|
|
106
|
+
...(agentName ? { agentName } : {}),
|
|
107
|
+
since: row.submittedAt ?? row.updatedAt,
|
|
108
|
+
autoAcceptAt: row.autoAcceptAt,
|
|
109
|
+
rejectCount: row.rejectCount,
|
|
110
|
+
updatedAt: row.updatedAt,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=waiting-items.contract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"waiting-items.contract.js","sourceRoot":"","sources":["../../../../../../backend/src/services/cloud/waiting-items.contract.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slack-initializer.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/slack/slack-initializer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,EACL,uBAAuB,EAGxB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,4BAA4B,EAG7B,MAAM,sCAAsC,CAAC;AAE9C,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,sCAAsC,CAAC;
|
|
1
|
+
{"version":3,"file":"slack-initializer.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/slack/slack-initializer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,EACL,uBAAuB,EAGxB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,4BAA4B,EAG7B,MAAM,sCAAsC,CAAC;AAE9C,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,sCAAsC,CAAC;AAI9C,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAI3E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAsCjF,4DAA4D;AAC5D,MAAM,MAAM,WAAW,GAAG,eAAe,CAAC;AAE1C,6CAA6C;AAC7C,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,WAAW,CAAC;IACpB;;;OAGG;IACH,QAAQ,CAAC,EAAE;QAAE,MAAM,EAAE,WAAW,CAAC;QAAC,MAAM,EAAE,WAAW,CAAA;KAAE,CAAC;CACzD;AAyDD,qEAAqE;AACrE;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,KAAK,CAAC;IAAE,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,GACzE;IAAE,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAWvD;AAmBD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,2CAA2C;IAC3C,SAAS,EAAE,OAAO,CAAC;IACnB,uCAAuC;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAM3C;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,WAAW,GAAG,IAAI,CAiB1D;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAqBlE;AAED;;;;GAIG;AACH,wBAAsB,6BAA6B,IAAI,OAAO,CAAC,uBAAuB,CAAC,CAsBtF;AAED,2CAA2C;AAC3C,MAAM,WAAW,qBAAqB;IACpC,wEAAwE;IACxE,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;IAC1B,+CAA+C;IAC/C,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;IAC1B,0EAA0E;IAC1E,SAAS,EAAE,WAAW,GAAG,IAAI,CAAC;CAC/B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,qBAAqB,GAAG,mBAAmB,GAAG,IAAI,CAW/F;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAmC9E;AAYD;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAS1F;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,WAAW,GAAG,IAAI,CAEzD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,GAAG,IAAI,CAErE;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,0EAA0E;IAC1E,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;CAC3C;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,2BAA2B,CAC/C,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,eAAe,CAAC,CA0B1B;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,IAAI,CAAC,mBAAmB,EAAE,QAAQ,GAAG,QAAQ,CAAC,EACxD,OAAO,CAAC,EAAE,gBAAgB,EAC1B,MAAM,SAAY,GACjB,OAAO,CAAC,eAAe,CAAC,CAmD1B;AAoCD;;;;;GAKG;AACH,wBAAsB,2BAA2B,IAAI,OAAO,CAAC,4BAA4B,CAAC,CAuBzF;AAED;;;;GAIG;AACH,wBAAsB,0BAA0B,IAAI,OAAO,CAAC,4BAA4B,GAAG,IAAI,CAAC,CAW/F;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAS3D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,4BAA4B,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAyDjG;AAED;;;;;;GAMG;AACH,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC,CAkB7D;AAED,4CAA4C;AAC5C,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,iEAAiE;IACjE,YAAY,EAAE,WAAW,GAAG,IAAI,CAAC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yFAAyF;IACzF,IAAI,CAAC,EAAE,eAAe,GAAG,oBAAoB,GAAG,gBAAgB,CAAC;CAClE;AAED;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAqD7F;AAED;;GAEG;AACH,wBAAgB,0BAA0B,IAAI,IAAI,CAWjD;AA4BD,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC,CA+K5D;AAED;;;;GAIG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAanD"}
|
|
@@ -15,6 +15,7 @@ import { getSlackAgentIdentityService } from './slack-agent-identity.service.js'
|
|
|
15
15
|
import { loadSlackSourcePreference, saveSlackSourcePreference, } from './slack-source-preference.service.js';
|
|
16
16
|
import { getSlackTeamChannelService } from './slack-team-channel.service.js';
|
|
17
17
|
import { cloudTalkCapabilities } from '../cloud/cloud-talk-inbound.service.js';
|
|
18
|
+
import { waitingActionCapabilities } from '../cloud/waiting-actions-inbound.service.js';
|
|
18
19
|
import { SLACK_CLOUD_CONSTANTS, CREWLY_CONSTANTS, SLACK_AGENT_DM_CONSTANTS, SLACK_TYPING_CONSTANTS } from '../../constants.js';
|
|
19
20
|
import * as path from 'path';
|
|
20
21
|
import { getCrewlyHomePath } from '../core/crewly-home.utils.js';
|
|
@@ -514,7 +515,7 @@ export async function ensureSlackInstanceRegistry() {
|
|
|
514
515
|
getTeamChannels: () => getSlackTeamChannelService(),
|
|
515
516
|
getBoundWorkspaceId: () => getSlackCloudConfigService()?.getConfig()?.workspace.slackTeamId || null,
|
|
516
517
|
isAgentAwake: (agentSession) => sessionBackendExists(agentSession),
|
|
517
|
-
capabilities: () => cloudTalkCapabilities(),
|
|
518
|
+
capabilities: () => [...cloudTalkCapabilities(), ...waitingActionCapabilities()],
|
|
518
519
|
});
|
|
519
520
|
setSlackInstanceRegistryService(registry);
|
|
520
521
|
}
|