crewly 1.20.108 → 1.20.109
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/skills/agent/core/ticket-check/SKILL.md +62 -0
- package/config/skills/agent/core/ticket-check/execute.sh +71 -0
- package/config/skills/agent/core/ticket-check/execute.test.sh +69 -0
- package/dist/backend/backend/src/constants.d.ts +30 -0
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +30 -0
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/tickets/tickets.controller.d.ts +42 -0
- package/dist/backend/backend/src/controllers/tickets/tickets.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/tickets/tickets.controller.js +185 -0
- package/dist/backend/backend/src/controllers/tickets/tickets.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/tickets/tickets.routes.d.ts +7 -0
- package/dist/backend/backend/src/controllers/tickets/tickets.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/tickets/tickets.routes.js +16 -1
- package/dist/backend/backend/src/controllers/tickets/tickets.routes.js.map +1 -1
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +52 -1
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/services/cloud/mobile-api-relay.service.js +1 -1
- package/dist/backend/backend/src/services/cloud/mobile-api-relay.service.js.map +1 -1
- package/dist/backend/backend/src/services/reconciler/reconcile-rules.d.ts.map +1 -1
- package/dist/backend/backend/src/services/reconciler/reconcile-rules.js +6 -0
- package/dist/backend/backend/src/services/reconciler/reconcile-rules.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-agent-dm.service.js +2 -2
- package/dist/backend/backend/src/services/slack/slack-agent-dm.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.js +2 -2
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
- package/dist/backend/backend/src/services/v3/request-decompose.subscriber.d.ts +8 -0
- package/dist/backend/backend/src/services/v3/request-decompose.subscriber.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/request-decompose.subscriber.js +40 -0
- package/dist/backend/backend/src/services/v3/request-decompose.subscriber.js.map +1 -1
- package/dist/backend/backend/src/services/v3/request-sla.subscriber.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/request-sla.subscriber.js +9 -0
- package/dist/backend/backend/src/services/v3/request-sla.subscriber.js.map +1 -1
- package/dist/backend/backend/src/services/v3/request.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/request.service.js +28 -0
- package/dist/backend/backend/src/services/v3/request.service.js.map +1 -1
- package/dist/backend/backend/src/services/v3/ticket-channel-hooks.d.ts +17 -0
- package/dist/backend/backend/src/services/v3/ticket-channel-hooks.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/ticket-channel-hooks.js +52 -5
- package/dist/backend/backend/src/services/v3/ticket-channel-hooks.js.map +1 -1
- package/dist/backend/backend/src/services/v3/ticket-intake.service.d.ts +63 -1
- package/dist/backend/backend/src/services/v3/ticket-intake.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/ticket-intake.service.js +67 -1
- package/dist/backend/backend/src/services/v3/ticket-intake.service.js.map +1 -1
- package/dist/backend/backend/src/services/v3/ticket-review.service.d.ts +242 -0
- package/dist/backend/backend/src/services/v3/ticket-review.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/v3/ticket-review.service.js +456 -0
- package/dist/backend/backend/src/services/v3/ticket-review.service.js.map +1 -0
- package/dist/backend/backend/src/types/v2/index.d.ts +1 -1
- package/dist/backend/backend/src/types/v2/index.d.ts.map +1 -1
- package/dist/backend/backend/src/types/v2/index.js.map +1 -1
- package/dist/backend/backend/src/types/v2/request.types.d.ts +21 -1
- package/dist/backend/backend/src/types/v2/request.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/v2/request.types.js +3 -2
- package/dist/backend/backend/src/types/v2/request.types.js.map +1 -1
- package/dist/backend/backend/src/types/v2/ticket.types.d.ts +71 -1
- package/dist/backend/backend/src/types/v2/ticket.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/v2/ticket.types.js +40 -0
- package/dist/backend/backend/src/types/v2/ticket.types.js.map +1 -1
- package/dist/backend/build-info.json +2 -2
- package/dist/cli/backend/src/constants.d.ts +30 -0
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +30 -0
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-agent-dm.service.js +2 -2
- package/dist/cli/backend/src/services/slack/slack-agent-dm.service.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.js +2 -2
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
- package/dist/cli/backend/src/services/v3/request-sla.subscriber.d.ts.map +1 -1
- package/dist/cli/backend/src/services/v3/request-sla.subscriber.js +9 -0
- package/dist/cli/backend/src/services/v3/request-sla.subscriber.js.map +1 -1
- package/dist/cli/backend/src/services/v3/request.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/v3/request.service.js +28 -0
- package/dist/cli/backend/src/services/v3/request.service.js.map +1 -1
- package/dist/cli/backend/src/services/v3/ticket-channel-hooks.d.ts +17 -0
- package/dist/cli/backend/src/services/v3/ticket-channel-hooks.d.ts.map +1 -1
- package/dist/cli/backend/src/services/v3/ticket-channel-hooks.js +52 -5
- package/dist/cli/backend/src/services/v3/ticket-channel-hooks.js.map +1 -1
- package/dist/cli/backend/src/services/v3/ticket-intake.service.d.ts +63 -1
- package/dist/cli/backend/src/services/v3/ticket-intake.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/v3/ticket-intake.service.js +67 -1
- package/dist/cli/backend/src/services/v3/ticket-intake.service.js.map +1 -1
- package/dist/cli/backend/src/services/v3/ticket-review.service.d.ts +242 -0
- package/dist/cli/backend/src/services/v3/ticket-review.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/v3/ticket-review.service.js +456 -0
- package/dist/cli/backend/src/services/v3/ticket-review.service.js.map +1 -0
- package/dist/cli/backend/src/types/v2/index.d.ts +1 -1
- package/dist/cli/backend/src/types/v2/index.d.ts.map +1 -1
- package/dist/cli/backend/src/types/v2/index.js.map +1 -1
- package/dist/cli/backend/src/types/v2/request.types.d.ts +21 -1
- package/dist/cli/backend/src/types/v2/request.types.d.ts.map +1 -1
- package/dist/cli/backend/src/types/v2/request.types.js +3 -2
- package/dist/cli/backend/src/types/v2/request.types.js.map +1 -1
- package/dist/cli/backend/src/types/v2/ticket.types.d.ts +71 -1
- package/dist/cli/backend/src/types/v2/ticket.types.d.ts.map +1 -1
- package/dist/cli/backend/src/types/v2/ticket.types.js +40 -0
- package/dist/cli/backend/src/types/v2/ticket.types.js.map +1 -1
- package/frontend/dist/assets/{index-f7b99e81.js → index-07e338a9.js} +284 -284
- package/frontend/dist/assets/index-8327e63e.css +42 -0
- package/frontend/dist/index.html +2 -2
- package/package.json +1 -1
- package/frontend/dist/assets/index-413c5813.css +0 -42
|
@@ -5,12 +5,18 @@
|
|
|
5
5
|
* - GET /api/tickets?column=&q=&kind=&includeLegacy= — board-shaped list
|
|
6
6
|
* - GET /api/tickets/:tkt — one ticket by `TKT-123`, `123` or id
|
|
7
7
|
* - POST /api/tickets/:id/dismiss — the "不用记" action
|
|
8
|
+
* - POST /api/tickets/:id/verify — 验过了 (Phase 2)
|
|
9
|
+
* - POST /api/tickets/:id/reject { reason } — 打回 (Phase 2)
|
|
10
|
+
* - PUT /api/tickets/:id/acceptance { items } — replace acceptance list (Phase 2)
|
|
11
|
+
* - POST /api/tickets/:id/self-check { index, result, evidence } — agent self-check (Phase 2)
|
|
12
|
+
* - PATCH /api/tickets/:id { title, priority, kind, assignee } — board edits (Phase 2)
|
|
8
13
|
*
|
|
9
14
|
* @module controllers/tickets/tickets.controller
|
|
10
15
|
*/
|
|
11
16
|
import { getTicketIntakeService, } from '../../services/v3/ticket-intake.service.js';
|
|
12
17
|
import { isTicketBoardColumn, isTicketKind } from '../../types/v2/ticket.types.js';
|
|
13
18
|
import { readAgentSessionHeader } from '../../utils/agent-caller.utils.js';
|
|
19
|
+
import { getTicketReviewService, } from '../../services/v3/ticket-review.service.js';
|
|
14
20
|
/**
|
|
15
21
|
* The wired intake service, or a 503 when boot has not wired it.
|
|
16
22
|
*
|
|
@@ -132,4 +138,183 @@ export async function dismissTicket(req, res) {
|
|
|
132
138
|
res.status(500).json({ success: false, error: error.message });
|
|
133
139
|
}
|
|
134
140
|
}
|
|
141
|
+
// ---------------------------------------------------------------------------
|
|
142
|
+
// Phase 2 — review
|
|
143
|
+
// ---------------------------------------------------------------------------
|
|
144
|
+
/** HTTP status for each refusal. */
|
|
145
|
+
const REVIEW_REFUSAL_STATUS = {
|
|
146
|
+
not_found: 404,
|
|
147
|
+
invalid: 400,
|
|
148
|
+
not_in_review: 409,
|
|
149
|
+
already_done: 409,
|
|
150
|
+
cancelled: 409,
|
|
151
|
+
open_work: 409,
|
|
152
|
+
};
|
|
153
|
+
/** Human text for each refusal. */
|
|
154
|
+
const REVIEW_REFUSAL_TEXT = {
|
|
155
|
+
not_found: 'Ticket not found',
|
|
156
|
+
invalid: 'Invalid input',
|
|
157
|
+
not_in_review: 'Ticket is not waiting for review',
|
|
158
|
+
already_done: 'Ticket is already done',
|
|
159
|
+
cancelled: 'Ticket was cancelled',
|
|
160
|
+
open_work: 'Ticket still has open work items',
|
|
161
|
+
};
|
|
162
|
+
/**
|
|
163
|
+
* The wired review service, or a 503.
|
|
164
|
+
*
|
|
165
|
+
* @param res - Response to write the 503 to
|
|
166
|
+
* @returns The service, or null after responding
|
|
167
|
+
*/
|
|
168
|
+
function reviewOr503(res) {
|
|
169
|
+
const svc = getTicketReviewService();
|
|
170
|
+
if (!svc) {
|
|
171
|
+
res.status(503).json({ success: false, error: 'Ticket review is not ready' });
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
return svc;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Refuse a call made by an agent (owner-only actions).
|
|
178
|
+
*
|
|
179
|
+
* @param req - Express request
|
|
180
|
+
* @param res - Response
|
|
181
|
+
* @param what - What is owner-only (for the message)
|
|
182
|
+
* @returns True when refused
|
|
183
|
+
*/
|
|
184
|
+
function refuseAgent(req, res, what) {
|
|
185
|
+
if (!readAgentSessionHeader(req))
|
|
186
|
+
return false;
|
|
187
|
+
res.status(403).json({ success: false, error: `Only the owner can ${what}` });
|
|
188
|
+
return true;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Write a review action's result.
|
|
192
|
+
*
|
|
193
|
+
* @param res - Response
|
|
194
|
+
* @param result - The result
|
|
195
|
+
*/
|
|
196
|
+
function sendReviewResult(res, result) {
|
|
197
|
+
if (result.ok) {
|
|
198
|
+
res.json({ success: true, data: result.ticket });
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
res.status(REVIEW_REFUSAL_STATUS[result.reason]).json({
|
|
202
|
+
success: false,
|
|
203
|
+
error: REVIEW_REFUSAL_TEXT[result.reason],
|
|
204
|
+
code: result.reason,
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Run a review handler with the shared 503 / 500 handling.
|
|
209
|
+
*
|
|
210
|
+
* @param res - Response
|
|
211
|
+
* @param fn - The action
|
|
212
|
+
*/
|
|
213
|
+
async function runReview(res, fn) {
|
|
214
|
+
const svc = reviewOr503(res);
|
|
215
|
+
if (!svc)
|
|
216
|
+
return;
|
|
217
|
+
try {
|
|
218
|
+
sendReviewResult(res, await fn(svc));
|
|
219
|
+
}
|
|
220
|
+
catch (error) {
|
|
221
|
+
res.status(500).json({ success: false, error: error.message });
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* POST /api/tickets/:id/verify — 验过了. Owner only.
|
|
226
|
+
*
|
|
227
|
+
* @param req - Express request with `id` param
|
|
228
|
+
* @param res - `{ success, data: ticket }`, 403, 404 or 409
|
|
229
|
+
*/
|
|
230
|
+
export async function verifyTicket(req, res) {
|
|
231
|
+
if (refuseAgent(req, res, 'accept a ticket'))
|
|
232
|
+
return;
|
|
233
|
+
await runReview(res, (svc) => svc.verify(req.params.id ?? ''));
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* POST /api/tickets/:id/reject — 打回 with a required reason. Owner only.
|
|
237
|
+
* The reason becomes an acceptance criterion and a rework WorkItem is queued.
|
|
238
|
+
*
|
|
239
|
+
* @param req - Express request with `id` param and body `{ reason }`
|
|
240
|
+
* @param res - `{ success, data: ticket }`, 400, 403, 404 or 409
|
|
241
|
+
*/
|
|
242
|
+
export async function rejectTicket(req, res) {
|
|
243
|
+
if (refuseAgent(req, res, 'send a ticket back'))
|
|
244
|
+
return;
|
|
245
|
+
const reason = typeof req.body?.reason === 'string' ? req.body.reason.trim() : '';
|
|
246
|
+
if (!reason) {
|
|
247
|
+
res.status(400).json({ success: false, error: 'A reason is required', code: 'invalid' });
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
await runReview(res, (svc) => svc.reject(req.params.id ?? '', reason, 'board'));
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* PUT /api/tickets/:id/acceptance — replace the live acceptance list. Owner only.
|
|
254
|
+
*
|
|
255
|
+
* @param req - Express request with body `{ items: [{ text, check? }] }`
|
|
256
|
+
* @param res - `{ success, data: ticket }`, 400, 403 or 404
|
|
257
|
+
*/
|
|
258
|
+
export async function setTicketAcceptance(req, res) {
|
|
259
|
+
if (refuseAgent(req, res, 'edit acceptance criteria'))
|
|
260
|
+
return;
|
|
261
|
+
const raw = req.body?.items;
|
|
262
|
+
if (!Array.isArray(raw)) {
|
|
263
|
+
res.status(400).json({ success: false, error: '`items` must be an array', code: 'invalid' });
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
const items = [];
|
|
267
|
+
for (const entry of raw) {
|
|
268
|
+
const text = typeof entry === 'string' ? entry : entry?.text;
|
|
269
|
+
const check = typeof entry === 'object' && entry ? entry.check : undefined;
|
|
270
|
+
if (typeof text !== 'string') {
|
|
271
|
+
res.status(400).json({ success: false, error: 'Each item needs a `text`', code: 'invalid' });
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
items.push({ text, ...(check === 'auto' || check === 'judgment' ? { check } : {}) });
|
|
275
|
+
}
|
|
276
|
+
await runReview(res, (svc) => svc.setAcceptance(req.params.id ?? '', items));
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* POST /api/tickets/:id/self-check — an agent records its check of one
|
|
280
|
+
* criterion. Agents may call this.
|
|
281
|
+
*
|
|
282
|
+
* @param req - Express request with body `{ index, result: 'pass'|'fail', evidence? }`
|
|
283
|
+
* @param res - `{ success, data: ticket }`, 400 or 404
|
|
284
|
+
*/
|
|
285
|
+
export async function selfCheckTicket(req, res) {
|
|
286
|
+
const index = Number(req.body?.index);
|
|
287
|
+
const result = req.body?.result;
|
|
288
|
+
const evidence = typeof req.body?.evidence === 'string' ? req.body.evidence : undefined;
|
|
289
|
+
if (!Number.isInteger(index) || index < 0 || (result !== 'pass' && result !== 'fail')) {
|
|
290
|
+
res.status(400).json({ success: false, error: '`index` (>= 0) and `result` (pass|fail) are required', code: 'invalid' });
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
await runReview(res, (svc) => svc.selfCheck(req.params.id ?? '', index, result, evidence));
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* PATCH /api/tickets/:id — board edits (title, priority, kind, assignee). Owner only.
|
|
297
|
+
*
|
|
298
|
+
* @param req - Express request with a partial body
|
|
299
|
+
* @param res - `{ success, data: ticket }`, 400, 403 or 404
|
|
300
|
+
*/
|
|
301
|
+
export async function patchTicket(req, res) {
|
|
302
|
+
if (refuseAgent(req, res, 'edit a ticket'))
|
|
303
|
+
return;
|
|
304
|
+
const body = (req.body ?? {});
|
|
305
|
+
const patch = {};
|
|
306
|
+
if (typeof body.title === 'string')
|
|
307
|
+
patch.title = body.title;
|
|
308
|
+
if (typeof body.priority === 'string')
|
|
309
|
+
patch.priority = body.priority;
|
|
310
|
+
if (typeof body.kind === 'string')
|
|
311
|
+
patch.kind = body.kind;
|
|
312
|
+
if (typeof body.assignee === 'string' || body.assignee === null)
|
|
313
|
+
patch.assignee = body.assignee;
|
|
314
|
+
if (Object.keys(patch).length === 0) {
|
|
315
|
+
res.status(400).json({ success: false, error: 'Nothing to change', code: 'invalid' });
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
await runReview(res, (svc) => svc.patch(req.params.id ?? '', patch));
|
|
319
|
+
}
|
|
135
320
|
//# sourceMappingURL=tickets.controller.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tickets.controller.js","sourceRoot":"","sources":["../../../../../../backend/src/controllers/tickets/tickets.controller.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"tickets.controller.js","sourceRoot":"","sources":["../../../../../../backend/src/controllers/tickets/tickets.controller.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,13 @@ import { Router } from 'express';
|
|
|
11
11
|
* - GET / — board-shaped list
|
|
12
12
|
* - GET /:tkt — one ticket
|
|
13
13
|
* - POST /:id/dismiss — "不用记"
|
|
14
|
+
* - POST /:id/verify — 验过了
|
|
15
|
+
* - POST /:id/reject — 打回 { reason }
|
|
16
|
+
* - PUT /:id/acceptance — replace acceptance list
|
|
17
|
+
* - POST /:id/self-check — agent self-check of one criterion
|
|
18
|
+
* - PATCH /:id — title / priority / kind / assignee
|
|
19
|
+
* - POST /:id/acceptance, POST /:id/update — the same two, for the relay
|
|
20
|
+
* (portal / phone), which only carries GET and POST
|
|
14
21
|
*
|
|
15
22
|
* @returns Express router for /api/tickets
|
|
16
23
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tickets.routes.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/controllers/tickets/tickets.routes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"tickets.routes.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/controllers/tickets/tickets.routes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAYjC;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAc5C"}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @module controllers/tickets/tickets.routes
|
|
5
5
|
*/
|
|
6
6
|
import { Router } from 'express';
|
|
7
|
-
import { listTickets, getTicket, dismissTicket } from './tickets.controller.js';
|
|
7
|
+
import { listTickets, getTicket, dismissTicket, verifyTicket, rejectTicket, setTicketAcceptance, selfCheckTicket, patchTicket, } from './tickets.controller.js';
|
|
8
8
|
/**
|
|
9
9
|
* Create the tickets router.
|
|
10
10
|
*
|
|
@@ -12,6 +12,13 @@ import { listTickets, getTicket, dismissTicket } from './tickets.controller.js';
|
|
|
12
12
|
* - GET / — board-shaped list
|
|
13
13
|
* - GET /:tkt — one ticket
|
|
14
14
|
* - POST /:id/dismiss — "不用记"
|
|
15
|
+
* - POST /:id/verify — 验过了
|
|
16
|
+
* - POST /:id/reject — 打回 { reason }
|
|
17
|
+
* - PUT /:id/acceptance — replace acceptance list
|
|
18
|
+
* - POST /:id/self-check — agent self-check of one criterion
|
|
19
|
+
* - PATCH /:id — title / priority / kind / assignee
|
|
20
|
+
* - POST /:id/acceptance, POST /:id/update — the same two, for the relay
|
|
21
|
+
* (portal / phone), which only carries GET and POST
|
|
15
22
|
*
|
|
16
23
|
* @returns Express router for /api/tickets
|
|
17
24
|
*/
|
|
@@ -20,6 +27,14 @@ export function createTicketsRouter() {
|
|
|
20
27
|
router.get('/', listTickets);
|
|
21
28
|
router.get('/:tkt', getTicket);
|
|
22
29
|
router.post('/:id/dismiss', dismissTicket);
|
|
30
|
+
router.post('/:id/verify', verifyTicket);
|
|
31
|
+
router.post('/:id/reject', rejectTicket);
|
|
32
|
+
router.put('/:id/acceptance', setTicketAcceptance);
|
|
33
|
+
router.post('/:id/self-check', selfCheckTicket);
|
|
34
|
+
router.patch('/:id', patchTicket);
|
|
35
|
+
// POST twins: the relay (portal / phone) only carries GET and POST.
|
|
36
|
+
router.post('/:id/acceptance', setTicketAcceptance);
|
|
37
|
+
router.post('/:id/update', patchTicket);
|
|
23
38
|
return router;
|
|
24
39
|
}
|
|
25
40
|
//# sourceMappingURL=tickets.routes.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tickets.routes.js","sourceRoot":"","sources":["../../../../../../backend/src/controllers/tickets/tickets.routes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,
|
|
1
|
+
{"version":3,"file":"tickets.routes.js","sourceRoot":"","sources":["../../../../../../backend/src/controllers/tickets/tickets.routes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EACL,WAAW,EACX,SAAS,EACT,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,WAAW,GACZ,MAAM,yBAAyB,CAAC;AAEjC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,mBAAmB;IACjC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;IACxB,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IAC7B,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAC/B,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,aAAa,CAAC,CAAC;IAC3C,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;IACzC,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;IACzC,MAAM,CAAC,GAAG,CAAC,iBAAiB,EAAE,mBAAmB,CAAC,CAAC;IACnD,MAAM,CAAC,IAAI,CAAC,iBAAiB,EAAE,eAAe,CAAC,CAAC;IAChD,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAClC,oEAAoE;IACpE,MAAM,CAAC,IAAI,CAAC,iBAAiB,EAAE,mBAAmB,CAAC,CAAC;IACpD,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;IACxC,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../backend/src/index.ts"],"names":[],"mappings":";AA2CA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../backend/src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -58,11 +58,14 @@ import { setRequestServiceEventBus, RequestService } from './services/v3/request
|
|
|
58
58
|
import { getSlackService } from './services/slack/slack.service.js';
|
|
59
59
|
import { sendBootAnnouncement, isFirstBoot, markBooted } from './services/boot/boot-announce.service.js';
|
|
60
60
|
import { SubAgentMessageQueue } from './services/messaging/sub-agent-message-queue.service.js';
|
|
61
|
-
import { SUB_AGENT_QUEUE_CONSTANTS, CHAT_CONTEXT_CONSTANTS, SAFE_RESTART, PROCESS_EXIT_CODES, CLAUDE_STARTUP_CONSTANTS, WEB_CONSTANTS } from './constants.js';
|
|
61
|
+
import { SUB_AGENT_QUEUE_CONSTANTS, CHAT_CONTEXT_CONSTANTS, SAFE_RESTART, PROCESS_EXIT_CODES, CLAUDE_STARTUP_CONSTANTS, WEB_CONSTANTS, TICKET_CONSTANTS } from './constants.js';
|
|
62
62
|
import { PtyActivityTrackerService } from './services/agent/pty-activity-tracker.service.js';
|
|
63
63
|
import { InFlightTurnTracker } from './services/restart/in-flight-turn-tracker.service.js';
|
|
64
64
|
import { TicketIntakeService, setTicketIntakeService, resolveTicketIdForSession, } from './services/v3/ticket-intake.service.js';
|
|
65
65
|
import { createChatV2ReceiptSink } from './services/v3/ticket-channel-hooks.js';
|
|
66
|
+
import { TicketReviewService, setTicketReviewService, getTicketReviewService } from './services/v3/ticket-review.service.js';
|
|
67
|
+
import { activeAcceptance, formatTicketMarker, formatTicketNumber } from './types/v2/ticket.types.js';
|
|
68
|
+
import { createWorkItem, TERMINAL_WORK_ITEM_STATUSES } from './types/v2/work-item.types.js';
|
|
66
69
|
import { runPoolArchiveMigration } from './services/task-pool/pool-archive-migration.js';
|
|
67
70
|
import { createPtyTurnProbe } from './services/restart/turn-probe.js';
|
|
68
71
|
import { RestartDrainService, resolveRestartDrainMs } from './services/restart/restart-drain.service.js';
|
|
@@ -415,6 +418,45 @@ export class CrewlyServer {
|
|
|
415
418
|
}));
|
|
416
419
|
setTicketIntakeService(ticketIntake);
|
|
417
420
|
TaskPoolService.getInstance().setTicketResolver((sessionName) => resolveTicketIdForSession(InFlightTurnTracker.getInstance(), sessionName));
|
|
421
|
+
// Phase 2: answered → 待验收 → 验过了 / 打回 / silence accepts.
|
|
422
|
+
const ticketReview = new TicketReviewService({
|
|
423
|
+
requests: RequestService.getInstance(),
|
|
424
|
+
fallbackAgent: ORCHESTRATOR_SESSION_NAME,
|
|
425
|
+
openWorkItemCount: async (requestId) => (await TaskPoolService.getInstance().getAllItems()).filter((wi) => wi.requestId === requestId && !TERMINAL_WORK_ITEM_STATUSES.has(wi.status)).length,
|
|
426
|
+
createRework: async ({ ticket, reason, target }) => {
|
|
427
|
+
const tkt = formatTicketNumber(ticket.ticketNumber ?? 0);
|
|
428
|
+
const criteria = activeAcceptance(ticket.acceptance).map((a) => `- ${a.text}`).join('\n');
|
|
429
|
+
const wi = createWorkItem({
|
|
430
|
+
type: 'delegate',
|
|
431
|
+
owner: 'system',
|
|
432
|
+
target,
|
|
433
|
+
requestId: ticket.id,
|
|
434
|
+
title: TICKET_CONSTANTS.REVIEW.REWORK_TITLE(tkt),
|
|
435
|
+
description: `${formatTicketMarker(ticket)} The owner sent ${tkt} back: ${reason}\n\n` +
|
|
436
|
+
`Original ask: ${ticket.description}\n` +
|
|
437
|
+
(ticket.reply ? `Your last answer: ${ticket.reply.excerpt}\n` : '') +
|
|
438
|
+
(criteria ? `\nAcceptance criteria:\n${criteria}\n` : '') +
|
|
439
|
+
`\nFix it and answer in the ticket's conversation.`,
|
|
440
|
+
metadata: { ticketRework: true },
|
|
441
|
+
});
|
|
442
|
+
await TaskPoolService.getInstance().addToPool(wi);
|
|
443
|
+
return wi.id;
|
|
444
|
+
},
|
|
445
|
+
markReceiptDone: (ticket) => ticketIntake.markReceiptDone(ticket),
|
|
446
|
+
});
|
|
447
|
+
setTicketReviewService(ticketReview);
|
|
448
|
+
ticketIntake.setReviewHandler(ticketReview);
|
|
449
|
+
getChatV2Service().on('chat_message', (dto) => {
|
|
450
|
+
void ticketReview.onChatMessage(dto).catch(() => undefined);
|
|
451
|
+
});
|
|
452
|
+
const reviewSweep = setInterval(() => {
|
|
453
|
+
void ticketReview.sweep().catch((sweepErr) => {
|
|
454
|
+
this.logger.warn('Ticket review sweep failed', {
|
|
455
|
+
error: sweepErr instanceof Error ? sweepErr.message : String(sweepErr),
|
|
456
|
+
});
|
|
457
|
+
});
|
|
458
|
+
}, TICKET_CONSTANTS.REVIEW.SWEEP_INTERVAL_MS);
|
|
459
|
+
reviewSweep.unref?.();
|
|
418
460
|
}
|
|
419
461
|
catch (ticketBootErr) {
|
|
420
462
|
this.logger.error('Ticket intake boot failed — messages are still delivered, no tickets filed', {
|
|
@@ -913,6 +955,11 @@ export class CrewlyServer {
|
|
|
913
955
|
// was mid-answer and never got a reply; the message was still
|
|
914
956
|
// in the queue an hour later (2026-09-21, Ella).
|
|
915
957
|
setImmediate(() => void this.flushQueuedAgentMessages(event.sessionName));
|
|
958
|
+
// Ticket loop Phase 2: an agent that finished its turn has answered
|
|
959
|
+
// the tickets it replied in — submit them (待验收 or done).
|
|
960
|
+
void getTicketReviewService()
|
|
961
|
+
?.onAgentIdle(event.sessionName)
|
|
962
|
+
.catch(() => undefined);
|
|
916
963
|
// V3: Auto-close open Requests when the orchestrator goes idle
|
|
917
964
|
// Handles direct responses (no WorkItem delegation)
|
|
918
965
|
if (event.sessionName === ORCHESTRATOR_SESSION_NAME) {
|
|
@@ -3589,6 +3636,10 @@ export class CrewlyServer {
|
|
|
3589
3636
|
for (const req of all) {
|
|
3590
3637
|
if (req.status !== 'open')
|
|
3591
3638
|
continue;
|
|
3639
|
+
// Tickets matched to their chat turn close when their answer
|
|
3640
|
+
// settles (TicketReviewService), not on a timer.
|
|
3641
|
+
if (req.chatRef)
|
|
3642
|
+
continue;
|
|
3592
3643
|
const reqAge = Date.now() - new Date(req.createdAt).getTime();
|
|
3593
3644
|
if (reqAge > 10 * 60 * 1000)
|
|
3594
3645
|
continue; // older than 10 min — skip
|