@quiel/cli 0.4.1 → 0.5.0
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/README.md +8 -5
- package/dist/cli.js +1060 -833
- package/package.json +5 -6
- package/README.ru.md +0 -137
package/dist/cli.js
CHANGED
|
@@ -186,40 +186,11 @@ var UpdateAgentSchema = z5.object({
|
|
|
186
186
|
message: "\u041D\u0443\u0436\u043D\u043E \u043F\u0435\u0440\u0435\u0434\u0430\u0442\u044C \u0445\u043E\u0442\u044F \u0431\u044B \u043E\u0434\u043D\u043E \u043F\u043E\u043B\u0435"
|
|
187
187
|
});
|
|
188
188
|
|
|
189
|
-
// ../shared/src/dto/
|
|
190
|
-
import { z as
|
|
191
|
-
var PASSWORD_MIN_LENGTH = 10;
|
|
192
|
-
var PASSWORD_MAX_LENGTH = 128;
|
|
193
|
-
var PasswordSchema = z6.string().min(PASSWORD_MIN_LENGTH, `\u041F\u0430\u0440\u043E\u043B\u044C \u043A\u043E\u0440\u043E\u0447\u0435 ${PASSWORD_MIN_LENGTH} \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432`).max(PASSWORD_MAX_LENGTH, `\u041F\u0430\u0440\u043E\u043B\u044C \u0434\u043B\u0438\u043D\u043D\u0435\u0435 ${PASSWORD_MAX_LENGTH} \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432`);
|
|
194
|
-
var EmailSchema = z6.string().trim().min(1, "\u0423\u043A\u0430\u0436\u0438\u0442\u0435 \u043F\u043E\u0447\u0442\u0443").email("\u041F\u043E\u0445\u043E\u0436\u0435, \u0432 \u0430\u0434\u0440\u0435\u0441\u0435 \u043E\u043F\u0435\u0447\u0430\u0442\u043A\u0430").toLowerCase();
|
|
195
|
-
var RegisterSchema = z6.object({
|
|
196
|
-
name: z6.string().trim().min(1, "\u0423\u043A\u0430\u0436\u0438\u0442\u0435 \u0438\u043C\u044F").max(120),
|
|
197
|
-
email: EmailSchema,
|
|
198
|
-
password: PasswordSchema
|
|
199
|
-
}).refine(
|
|
200
|
-
(value) => {
|
|
201
|
-
const localPart = value.email.split("@")[0] ?? "";
|
|
202
|
-
return localPart.length < 3 || !value.password.toLowerCase().includes(localPart);
|
|
203
|
-
},
|
|
204
|
-
{ message: "\u041F\u0430\u0440\u043E\u043B\u044C \u043D\u0435 \u0434\u043E\u043B\u0436\u0435\u043D \u043F\u043E\u0432\u0442\u043E\u0440\u044F\u0442\u044C \u0430\u0434\u0440\u0435\u0441 \u043F\u043E\u0447\u0442\u044B", path: ["password"] }
|
|
205
|
-
);
|
|
206
|
-
var LoginSchema = z6.object({
|
|
207
|
-
email: EmailSchema,
|
|
208
|
-
// На входе НЕ применяем правила длины: пароль мог быть задан раньше, по
|
|
209
|
-
// другим правилам, и «слишком короткий» на форме входа — это отказ в
|
|
210
|
-
// доступе законному владельцу, а заодно подсказка перебирающему, что
|
|
211
|
-
// проверять длину не нужно.
|
|
212
|
-
password: z6.string().min(1, "\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043F\u0430\u0440\u043E\u043B\u044C")
|
|
213
|
-
});
|
|
214
|
-
var ForgotPasswordSchema = z6.object({ email: EmailSchema });
|
|
215
|
-
var ResetPasswordSchema = z6.object({
|
|
216
|
-
token: z6.string().min(1),
|
|
217
|
-
password: PasswordSchema
|
|
218
|
-
});
|
|
219
|
-
var ResendVerificationSchema = z6.object({ email: EmailSchema });
|
|
189
|
+
// ../shared/src/dto/attachment.ts
|
|
190
|
+
import { z as z7 } from "zod";
|
|
220
191
|
|
|
221
192
|
// ../shared/src/dto/document.ts
|
|
222
|
-
import { z as
|
|
193
|
+
import { z as z6 } from "zod";
|
|
223
194
|
|
|
224
195
|
// ../shared/src/enums/project.ts
|
|
225
196
|
var ProjectStatus = {
|
|
@@ -272,32 +243,32 @@ var ALLOWED_DOCUMENT_MIME_TYPES = [
|
|
|
272
243
|
"image/webp"
|
|
273
244
|
];
|
|
274
245
|
var MAX_DOCUMENT_FILE_SIZE_BYTES = 20 * 1024 * 1024;
|
|
275
|
-
var DocumentFileNameSchema =
|
|
276
|
-
var RequestDocumentUploadUrlSchema =
|
|
246
|
+
var DocumentFileNameSchema = z6.string().trim().min(1, "\u0418\u043C\u044F \u0444\u0430\u0439\u043B\u0430 \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u043E").max(255, "\u0418\u043C\u044F \u0444\u0430\u0439\u043B\u0430 \u0434\u043E\u043B\u0436\u043D\u043E \u0431\u044B\u0442\u044C \u043D\u0435 \u0434\u043B\u0438\u043D\u043D\u0435\u0435 255 \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432");
|
|
247
|
+
var RequestDocumentUploadUrlSchema = z6.object({
|
|
277
248
|
fileName: DocumentFileNameSchema,
|
|
278
|
-
mimeType:
|
|
249
|
+
mimeType: z6.enum(ALLOWED_DOCUMENT_MIME_TYPES, {
|
|
279
250
|
message: `\u0422\u0438\u043F \u0444\u0430\u0439\u043B\u0430 \u043D\u0435 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044F. \u0420\u0430\u0437\u0440\u0435\u0448\u0435\u043D\u044B: ${ALLOWED_DOCUMENT_MIME_TYPES.join(", ")}`
|
|
280
251
|
}),
|
|
281
|
-
size:
|
|
252
|
+
size: z6.number().int().positive().max(
|
|
282
253
|
MAX_DOCUMENT_FILE_SIZE_BYTES,
|
|
283
254
|
`\u0424\u0430\u0439\u043B \u0431\u043E\u043B\u044C\u0448\u0435 ${MAX_DOCUMENT_FILE_SIZE_BYTES / (1024 * 1024)} \u041C\u0438\u0411`
|
|
284
255
|
)
|
|
285
256
|
});
|
|
286
|
-
var DocumentKindSchema =
|
|
257
|
+
var DocumentKindSchema = z6.enum([
|
|
287
258
|
DocumentKind.SPEC,
|
|
288
259
|
DocumentKind.PLAN,
|
|
289
260
|
DocumentKind.DATA,
|
|
290
261
|
DocumentKind.DECISION,
|
|
291
262
|
DocumentKind.OTHER
|
|
292
263
|
]);
|
|
293
|
-
var DocumentTitleSchema =
|
|
294
|
-
var DocumentContentMdSchema =
|
|
295
|
-
var DocumentFileRefSchema =
|
|
296
|
-
fileKey:
|
|
264
|
+
var DocumentTitleSchema = z6.string().trim().min(1, "\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u043E").max(200, "\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u0434\u043E\u043B\u0436\u043D\u043E \u0431\u044B\u0442\u044C \u043D\u0435 \u0434\u043B\u0438\u043D\u043D\u0435\u0435 200 \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432");
|
|
265
|
+
var DocumentContentMdSchema = z6.string().min(1, "\u0421\u043E\u0434\u0435\u0440\u0436\u0438\u043C\u043E\u0435 \u043D\u0435 \u043C\u043E\u0436\u0435\u0442 \u0431\u044B\u0442\u044C \u043F\u0443\u0441\u0442\u044B\u043C").max(5e5, "\u0422\u0435\u043A\u0441\u0442 \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C \u043D\u0435 \u0434\u043B\u0438\u043D\u043D\u0435\u0435 500 000 \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432");
|
|
266
|
+
var DocumentFileRefSchema = z6.object({
|
|
267
|
+
fileKey: z6.string().min(1),
|
|
297
268
|
fileName: DocumentFileNameSchema,
|
|
298
|
-
mimeType:
|
|
269
|
+
mimeType: z6.enum(ALLOWED_DOCUMENT_MIME_TYPES)
|
|
299
270
|
});
|
|
300
|
-
var CreateDocumentSchema =
|
|
271
|
+
var CreateDocumentSchema = z6.object({
|
|
301
272
|
kind: DocumentKindSchema,
|
|
302
273
|
title: DocumentTitleSchema,
|
|
303
274
|
contentMd: DocumentContentMdSchema.optional(),
|
|
@@ -306,7 +277,7 @@ var CreateDocumentSchema = z7.object({
|
|
|
306
277
|
message: "\u041D\u0443\u0436\u043D\u043E \u043F\u0435\u0440\u0435\u0434\u0430\u0442\u044C \u043B\u0438\u0431\u043E contentMd, \u043B\u0438\u0431\u043E file \u2014 \u043D\u0435 \u043E\u0431\u0430 \u0438 \u043D\u0435 \u043D\u0438 \u043E\u0434\u043D\u043E\u0433\u043E",
|
|
307
278
|
path: ["contentMd"]
|
|
308
279
|
});
|
|
309
|
-
var UpdateDocumentSchema =
|
|
280
|
+
var UpdateDocumentSchema = z6.object({
|
|
310
281
|
kind: DocumentKindSchema.optional(),
|
|
311
282
|
title: DocumentTitleSchema.optional(),
|
|
312
283
|
contentMd: DocumentContentMdSchema.optional(),
|
|
@@ -317,35 +288,100 @@ var UpdateDocumentSchema = z7.object({
|
|
|
317
288
|
message: "\u041D\u0435\u043B\u044C\u0437\u044F \u043E\u0434\u043D\u043E\u0432\u0440\u0435\u043C\u0435\u043D\u043D\u043E \u043F\u0435\u0440\u0435\u0434\u0430\u0442\u044C contentMd \u0438 file",
|
|
318
289
|
path: ["contentMd"]
|
|
319
290
|
});
|
|
320
|
-
var ListDocumentsQuerySchema =
|
|
291
|
+
var ListDocumentsQuerySchema = z6.object({
|
|
321
292
|
kind: DocumentKindSchema.optional()
|
|
322
293
|
});
|
|
323
294
|
|
|
324
|
-
// ../shared/src/dto/
|
|
295
|
+
// ../shared/src/dto/attachment.ts
|
|
296
|
+
var AttachmentFileKeySchema = z7.string().min(1, "\u041A\u043B\u044E\u0447 \u0444\u0430\u0439\u043B\u0430 \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u0435\u043D").max(1024, "\u0421\u043B\u0438\u0448\u043A\u043E\u043C \u0434\u043B\u0438\u043D\u043D\u044B\u0439 \u043A\u043B\u044E\u0447 \u0444\u0430\u0439\u043B\u0430").regex(/^attachments\//, "\u041A\u043B\u044E\u0447 \u0444\u0430\u0439\u043B\u0430 \u043D\u0435 \u0438\u0437 \u043A\u0430\u0442\u0430\u043B\u043E\u0433\u0430 \u0432\u043B\u043E\u0436\u0435\u043D\u0438\u0439");
|
|
297
|
+
var AttachmentInputSchema = z7.object({
|
|
298
|
+
fileKey: AttachmentFileKeySchema,
|
|
299
|
+
fileName: DocumentFileNameSchema,
|
|
300
|
+
mimeType: z7.enum(ALLOWED_DOCUMENT_MIME_TYPES, {
|
|
301
|
+
message: `\u0422\u0438\u043F \u0444\u0430\u0439\u043B\u0430 \u043D\u0435 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044F. \u0420\u0430\u0437\u0440\u0435\u0448\u0435\u043D\u044B: ${ALLOWED_DOCUMENT_MIME_TYPES.join(", ")}`
|
|
302
|
+
}),
|
|
303
|
+
size: z7.number().int().positive().max(MAX_DOCUMENT_FILE_SIZE_BYTES)
|
|
304
|
+
});
|
|
305
|
+
var MAX_ATTACHMENTS_PER_ITEM = 10;
|
|
306
|
+
var AttachmentListSchema = z7.array(AttachmentInputSchema).max(MAX_ATTACHMENTS_PER_ITEM, `\u041D\u0435 \u0431\u043E\u043B\u044C\u0448\u0435 ${MAX_ATTACHMENTS_PER_ITEM} \u0444\u0430\u0439\u043B\u043E\u0432`).refine(
|
|
307
|
+
(items) => new Set(items.map((item) => item.fileKey)).size === items.length,
|
|
308
|
+
"\u041E\u0434\u0438\u043D \u0438 \u0442\u043E\u0442 \u0436\u0435 \u0444\u0430\u0439\u043B \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D \u0434\u0432\u0430\u0436\u0434\u044B"
|
|
309
|
+
);
|
|
310
|
+
var attachmentSchema = z7.object({
|
|
311
|
+
id: z7.string(),
|
|
312
|
+
fileName: z7.string(),
|
|
313
|
+
mimeType: z7.string(),
|
|
314
|
+
size: z7.number().int().nonnegative(),
|
|
315
|
+
createdAt: z7.string(),
|
|
316
|
+
/**
|
|
317
|
+
* Временная ссылка на скачивание.
|
|
318
|
+
*
|
|
319
|
+
* ПУСТАЯ СТРОКА — РАБОЧИЙ СЛУЧАЙ, а не ошибка: хранилище может быть не
|
|
320
|
+
* настроено или отказать. Тогда и человек, и агент всё равно узнают,
|
|
321
|
+
* что файл ЕСТЬ, — а молчаливое «вложений нет» было бы хуже. Тот же
|
|
322
|
+
* приём, что у файлов документов (`dispatcher/context.ts`).
|
|
323
|
+
*/
|
|
324
|
+
downloadUrl: z7.string(),
|
|
325
|
+
expiresInSeconds: z7.number().int().positive()
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
// ../shared/src/dto/auth.ts
|
|
325
329
|
import { z as z8 } from "zod";
|
|
326
|
-
var
|
|
327
|
-
var
|
|
328
|
-
var
|
|
329
|
-
var
|
|
330
|
+
var PASSWORD_MIN_LENGTH = 10;
|
|
331
|
+
var PASSWORD_MAX_LENGTH = 128;
|
|
332
|
+
var PasswordSchema = z8.string().min(PASSWORD_MIN_LENGTH, `\u041F\u0430\u0440\u043E\u043B\u044C \u043A\u043E\u0440\u043E\u0447\u0435 ${PASSWORD_MIN_LENGTH} \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432`).max(PASSWORD_MAX_LENGTH, `\u041F\u0430\u0440\u043E\u043B\u044C \u0434\u043B\u0438\u043D\u043D\u0435\u0435 ${PASSWORD_MAX_LENGTH} \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432`);
|
|
333
|
+
var EmailSchema = z8.string().trim().min(1, "\u0423\u043A\u0430\u0436\u0438\u0442\u0435 \u043F\u043E\u0447\u0442\u0443").email("\u041F\u043E\u0445\u043E\u0436\u0435, \u0432 \u0430\u0434\u0440\u0435\u0441\u0435 \u043E\u043F\u0435\u0447\u0430\u0442\u043A\u0430").toLowerCase();
|
|
334
|
+
var RegisterSchema = z8.object({
|
|
335
|
+
name: z8.string().trim().min(1, "\u0423\u043A\u0430\u0436\u0438\u0442\u0435 \u0438\u043C\u044F").max(120),
|
|
336
|
+
email: EmailSchema,
|
|
337
|
+
password: PasswordSchema
|
|
338
|
+
}).refine(
|
|
339
|
+
(value) => {
|
|
340
|
+
const localPart = value.email.split("@")[0] ?? "";
|
|
341
|
+
return localPart.length < 3 || !value.password.toLowerCase().includes(localPart);
|
|
342
|
+
},
|
|
343
|
+
{ message: "\u041F\u0430\u0440\u043E\u043B\u044C \u043D\u0435 \u0434\u043E\u043B\u0436\u0435\u043D \u043F\u043E\u0432\u0442\u043E\u0440\u044F\u0442\u044C \u0430\u0434\u0440\u0435\u0441 \u043F\u043E\u0447\u0442\u044B", path: ["password"] }
|
|
344
|
+
);
|
|
345
|
+
var LoginSchema = z8.object({
|
|
346
|
+
email: EmailSchema,
|
|
347
|
+
// На входе НЕ применяем правила длины: пароль мог быть задан раньше, по
|
|
348
|
+
// другим правилам, и «слишком короткий» на форме входа — это отказ в
|
|
349
|
+
// доступе законному владельцу, а заодно подсказка перебирающему, что
|
|
350
|
+
// проверять длину не нужно.
|
|
351
|
+
password: z8.string().min(1, "\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043F\u0430\u0440\u043E\u043B\u044C")
|
|
352
|
+
});
|
|
353
|
+
var ForgotPasswordSchema = z8.object({ email: EmailSchema });
|
|
354
|
+
var ResetPasswordSchema = z8.object({
|
|
355
|
+
token: z8.string().min(1),
|
|
356
|
+
password: PasswordSchema
|
|
357
|
+
});
|
|
358
|
+
var ResendVerificationSchema = z8.object({ email: EmailSchema });
|
|
359
|
+
|
|
360
|
+
// ../shared/src/dto/milestone.ts
|
|
361
|
+
import { z as z9 } from "zod";
|
|
362
|
+
var MilestoneNameSchema = z9.string().trim().min(1, "\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u043E").max(150, "\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u0434\u043E\u043B\u0436\u043D\u043E \u0431\u044B\u0442\u044C \u043D\u0435 \u0434\u043B\u0438\u043D\u043D\u0435\u0435 150 \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432");
|
|
363
|
+
var MilestoneDescriptionSchema = z9.string().max(5e3, "\u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 \u0434\u043E\u043B\u0436\u043D\u043E \u0431\u044B\u0442\u044C \u043D\u0435 \u0434\u043B\u0438\u043D\u043D\u0435\u0435 5000 \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432");
|
|
364
|
+
var MilestoneStatusSchema = z9.enum([MilestoneStatus.OPEN, MilestoneStatus.DONE]);
|
|
365
|
+
var CreateMilestoneSchema = z9.object({
|
|
330
366
|
name: MilestoneNameSchema,
|
|
331
367
|
description: MilestoneDescriptionSchema.optional(),
|
|
332
|
-
dueAt:
|
|
368
|
+
dueAt: z9.coerce.date().optional(),
|
|
333
369
|
status: MilestoneStatusSchema.default(MilestoneStatus.OPEN)
|
|
334
370
|
});
|
|
335
|
-
var UpdateMilestoneSchema =
|
|
371
|
+
var UpdateMilestoneSchema = z9.object({
|
|
336
372
|
name: MilestoneNameSchema.optional(),
|
|
337
373
|
description: MilestoneDescriptionSchema.nullable().optional(),
|
|
338
|
-
dueAt:
|
|
374
|
+
dueAt: z9.coerce.date().nullable().optional(),
|
|
339
375
|
status: MilestoneStatusSchema.optional()
|
|
340
376
|
}).refine((data) => Object.keys(data).length > 0, {
|
|
341
377
|
message: "\u041D\u0443\u0436\u043D\u043E \u043F\u0435\u0440\u0435\u0434\u0430\u0442\u044C \u0445\u043E\u0442\u044F \u0431\u044B \u043E\u0434\u043D\u043E \u043F\u043E\u043B\u0435"
|
|
342
378
|
});
|
|
343
|
-
var ReorderMilestonesSchema =
|
|
344
|
-
orderedIds:
|
|
379
|
+
var ReorderMilestonesSchema = z9.object({
|
|
380
|
+
orderedIds: z9.array(z9.string().min(1)).min(1, "\u041D\u0443\u0436\u043D\u043E \u043F\u0435\u0440\u0435\u0434\u0430\u0442\u044C \u0445\u043E\u0442\u044F \u0431\u044B \u043E\u0434\u0438\u043D id")
|
|
345
381
|
});
|
|
346
382
|
|
|
347
383
|
// ../shared/src/dto/organization.ts
|
|
348
|
-
import { z as
|
|
384
|
+
import { z as z10 } from "zod";
|
|
349
385
|
|
|
350
386
|
// ../shared/src/enums/organization.ts
|
|
351
387
|
var OrgRole = {
|
|
@@ -355,78 +391,78 @@ var OrgRole = {
|
|
|
355
391
|
};
|
|
356
392
|
|
|
357
393
|
// ../shared/src/dto/organization.ts
|
|
358
|
-
var OrgSlugSchema =
|
|
394
|
+
var OrgSlugSchema = z10.string().min(2, "Slug \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C \u043D\u0435 \u043A\u043E\u0440\u043E\u0447\u0435 2 \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432").max(50, "Slug \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C \u043D\u0435 \u0434\u043B\u0438\u043D\u043D\u0435\u0435 50 \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432").regex(
|
|
359
395
|
/^[a-z0-9]+(-[a-z0-9]+)*$/,
|
|
360
396
|
"Slug: \u0441\u0442\u0440\u043E\u0447\u043D\u044B\u0435 \u043B\u0430\u0442\u0438\u043D\u0441\u043A\u0438\u0435 \u0431\u0443\u043A\u0432\u044B, \u0446\u0438\u0444\u0440\u044B \u0438 \u0434\u0435\u0444\u0438\u0441, \u0431\u0435\u0437 \u0434\u0435\u0444\u0438\u0441\u0430 \u043F\u043E \u043A\u0440\u0430\u044F\u043C"
|
|
361
397
|
);
|
|
362
|
-
var OrgNameSchema =
|
|
363
|
-
var CreateOrganizationSchema =
|
|
398
|
+
var OrgNameSchema = z10.string().trim().min(1, "\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u043E").max(100, "\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u0434\u043E\u043B\u0436\u043D\u043E \u0431\u044B\u0442\u044C \u043D\u0435 \u0434\u043B\u0438\u043D\u043D\u0435\u0435 100 \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432");
|
|
399
|
+
var CreateOrganizationSchema = z10.object({
|
|
364
400
|
name: OrgNameSchema,
|
|
365
401
|
slug: OrgSlugSchema.optional()
|
|
366
402
|
});
|
|
367
|
-
var UpdateOrganizationSchema =
|
|
403
|
+
var UpdateOrganizationSchema = z10.object({
|
|
368
404
|
name: OrgNameSchema.optional(),
|
|
369
405
|
slug: OrgSlugSchema.optional()
|
|
370
406
|
}).refine((data) => data.name !== void 0 || data.slug !== void 0, {
|
|
371
407
|
message: "\u041D\u0443\u0436\u043D\u043E \u043F\u0435\u0440\u0435\u0434\u0430\u0442\u044C \u0445\u043E\u0442\u044F \u0431\u044B \u043E\u0434\u043D\u043E \u043F\u043E\u043B\u0435 \u2014 name \u0438\u043B\u0438 slug"
|
|
372
408
|
});
|
|
373
|
-
var InviteMemberSchema =
|
|
374
|
-
email:
|
|
375
|
-
orgRole:
|
|
409
|
+
var InviteMemberSchema = z10.object({
|
|
410
|
+
email: z10.email("\u041D\u0435\u043A\u043E\u0440\u0440\u0435\u043A\u0442\u043D\u044B\u0439 email"),
|
|
411
|
+
orgRole: z10.enum([OrgRole.ADMIN, OrgRole.MEMBER]).default(OrgRole.MEMBER)
|
|
376
412
|
});
|
|
377
413
|
var INVITATION_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
378
|
-
var InvitationTokenSchema =
|
|
379
|
-
var AcceptInvitationSchema =
|
|
414
|
+
var InvitationTokenSchema = z10.string().min(16, "\u041D\u0435\u043A\u043E\u0440\u0440\u0435\u043A\u0442\u043D\u044B\u0439 \u0442\u043E\u043A\u0435\u043D \u043F\u0440\u0438\u0433\u043B\u0430\u0448\u0435\u043D\u0438\u044F");
|
|
415
|
+
var AcceptInvitationSchema = z10.object({
|
|
380
416
|
token: InvitationTokenSchema
|
|
381
417
|
});
|
|
382
|
-
var OrganizationMemberDTOSchema =
|
|
383
|
-
type:
|
|
418
|
+
var OrganizationMemberDTOSchema = z10.object({
|
|
419
|
+
type: z10.literal("member"),
|
|
384
420
|
/** id записи Membership — тот же id принимает `DELETE .../members/:id`. */
|
|
385
|
-
id:
|
|
386
|
-
userId:
|
|
387
|
-
name:
|
|
388
|
-
email:
|
|
389
|
-
image:
|
|
390
|
-
orgRole:
|
|
391
|
-
createdAt:
|
|
392
|
-
});
|
|
393
|
-
var OrganizationInvitationDTOSchema =
|
|
394
|
-
type:
|
|
421
|
+
id: z10.string(),
|
|
422
|
+
userId: z10.string(),
|
|
423
|
+
name: z10.string().nullable(),
|
|
424
|
+
email: z10.string().nullable(),
|
|
425
|
+
image: z10.string().nullable(),
|
|
426
|
+
orgRole: z10.enum([OrgRole.OWNER, OrgRole.ADMIN, OrgRole.MEMBER]),
|
|
427
|
+
createdAt: z10.coerce.date()
|
|
428
|
+
});
|
|
429
|
+
var OrganizationInvitationDTOSchema = z10.object({
|
|
430
|
+
type: z10.literal("invitation"),
|
|
395
431
|
/** id записи Invitation — тот же id принимает `DELETE .../members/:id`. */
|
|
396
|
-
id:
|
|
397
|
-
email:
|
|
398
|
-
orgRole:
|
|
432
|
+
id: z10.string(),
|
|
433
|
+
email: z10.string(),
|
|
434
|
+
orgRole: z10.enum([OrgRole.ADMIN, OrgRole.MEMBER]),
|
|
399
435
|
/** `expired` — вычисляется на сервере сравнением `expiresAt` с текущим временем. */
|
|
400
|
-
status:
|
|
401
|
-
invitedByName:
|
|
402
|
-
expiresAt:
|
|
403
|
-
createdAt:
|
|
436
|
+
status: z10.enum(["pending", "expired"]),
|
|
437
|
+
invitedByName: z10.string().nullable(),
|
|
438
|
+
expiresAt: z10.coerce.date(),
|
|
439
|
+
createdAt: z10.coerce.date()
|
|
404
440
|
});
|
|
405
|
-
var OrganizationMembersListItemSchema =
|
|
441
|
+
var OrganizationMembersListItemSchema = z10.discriminatedUnion("type", [
|
|
406
442
|
OrganizationMemberDTOSchema,
|
|
407
443
|
OrganizationInvitationDTOSchema
|
|
408
444
|
]);
|
|
409
445
|
|
|
410
446
|
// ../shared/src/dto/profile.ts
|
|
411
|
-
import { z as
|
|
412
|
-
var ProfileNameSchema =
|
|
413
|
-
var UpdateProfileSchema =
|
|
447
|
+
import { z as z11 } from "zod";
|
|
448
|
+
var ProfileNameSchema = z11.string().trim().min(1, "\u0423\u043A\u0430\u0436\u0438\u0442\u0435 \u0438\u043C\u044F").max(120);
|
|
449
|
+
var UpdateProfileSchema = z11.object({
|
|
414
450
|
name: ProfileNameSchema
|
|
415
451
|
});
|
|
416
|
-
var ChangePasswordSchema =
|
|
417
|
-
currentPassword:
|
|
452
|
+
var ChangePasswordSchema = z11.object({
|
|
453
|
+
currentPassword: z11.string().min(1).max(200).optional(),
|
|
418
454
|
newPassword: PasswordSchema
|
|
419
455
|
});
|
|
420
|
-
var RequestEmailChangeSchema =
|
|
456
|
+
var RequestEmailChangeSchema = z11.object({
|
|
421
457
|
newEmail: EmailSchema,
|
|
422
458
|
/** Нужен, если у аккаунта есть пароль — см. `ChangePasswordSchema`. */
|
|
423
|
-
currentPassword:
|
|
459
|
+
currentPassword: z11.string().min(1).max(200).optional()
|
|
424
460
|
});
|
|
425
|
-
var ConfirmEmailChangeSchema =
|
|
426
|
-
token:
|
|
461
|
+
var ConfirmEmailChangeSchema = z11.object({
|
|
462
|
+
token: z11.string().min(1)
|
|
427
463
|
});
|
|
428
|
-
var UpdateAvatarSchema =
|
|
429
|
-
fileKey:
|
|
464
|
+
var UpdateAvatarSchema = z11.object({
|
|
465
|
+
fileKey: z11.string().min(1).max(500)
|
|
430
466
|
});
|
|
431
467
|
var ALLOWED_AVATAR_MIME_TYPES = [
|
|
432
468
|
"image/jpeg",
|
|
@@ -435,23 +471,23 @@ var ALLOWED_AVATAR_MIME_TYPES = [
|
|
|
435
471
|
"image/gif"
|
|
436
472
|
];
|
|
437
473
|
var MAX_AVATAR_FILE_SIZE_BYTES = 2 * 1024 * 1024;
|
|
438
|
-
var RequestAvatarUploadUrlSchema =
|
|
439
|
-
fileName:
|
|
440
|
-
mimeType:
|
|
441
|
-
size:
|
|
474
|
+
var RequestAvatarUploadUrlSchema = z11.object({
|
|
475
|
+
fileName: z11.string().trim().min(1).max(200),
|
|
476
|
+
mimeType: z11.enum(ALLOWED_AVATAR_MIME_TYPES),
|
|
477
|
+
size: z11.number().int().positive().max(MAX_AVATAR_FILE_SIZE_BYTES)
|
|
442
478
|
});
|
|
443
|
-
var UnlinkAccountSchema =
|
|
444
|
-
provider:
|
|
479
|
+
var UnlinkAccountSchema = z11.object({
|
|
480
|
+
provider: z11.string().trim().min(1).max(50)
|
|
445
481
|
});
|
|
446
482
|
|
|
447
483
|
// ../shared/src/dto/project.ts
|
|
448
|
-
import { z as
|
|
484
|
+
import { z as z15 } from "zod";
|
|
449
485
|
|
|
450
486
|
// ../shared/src/settings/project-settings.ts
|
|
451
|
-
import { z as
|
|
487
|
+
import { z as z14 } from "zod";
|
|
452
488
|
|
|
453
489
|
// ../shared/src/dto/task-template.ts
|
|
454
|
-
import { z as
|
|
490
|
+
import { z as z13 } from "zod";
|
|
455
491
|
|
|
456
492
|
// ../shared/src/enums/task.ts
|
|
457
493
|
var TaskType = {
|
|
@@ -509,42 +545,42 @@ var EventKind = {
|
|
|
509
545
|
};
|
|
510
546
|
|
|
511
547
|
// ../shared/src/dto/task.ts
|
|
512
|
-
import { z as
|
|
548
|
+
import { z as z12 } from "zod";
|
|
513
549
|
var taskTypeValues = Object.values(TaskType);
|
|
514
550
|
var taskStatusValues = Object.values(TaskStatus);
|
|
515
551
|
var priorityValues = Object.values(Priority);
|
|
516
552
|
var executorValues = Object.values(Executor);
|
|
517
553
|
var testResultValues = Object.values(TestResult);
|
|
518
|
-
var TaskTypeSchema =
|
|
519
|
-
var TaskStatusSchema =
|
|
520
|
-
var TaskPrioritySchema =
|
|
521
|
-
var TaskExecutorSchema =
|
|
522
|
-
var TaskTestResultSchema =
|
|
523
|
-
var TaskTitleSchema =
|
|
524
|
-
var TaskDescriptionSchema =
|
|
525
|
-
var TaskLabelSchema =
|
|
526
|
-
var TaskLabelsSchema =
|
|
527
|
-
var TaskMetadataSchema =
|
|
528
|
-
var TaskAcceptanceSchema =
|
|
529
|
-
var TaskEstimateMinSchema =
|
|
530
|
-
var TaskOrderSchema =
|
|
531
|
-
var TaskResultMdSchema =
|
|
532
|
-
var TaskResultLinkKindSchema =
|
|
533
|
-
var TaskResultLinkSchema =
|
|
554
|
+
var TaskTypeSchema = z12.enum(taskTypeValues);
|
|
555
|
+
var TaskStatusSchema = z12.enum(taskStatusValues);
|
|
556
|
+
var TaskPrioritySchema = z12.enum(priorityValues);
|
|
557
|
+
var TaskExecutorSchema = z12.enum(executorValues);
|
|
558
|
+
var TaskTestResultSchema = z12.enum(testResultValues);
|
|
559
|
+
var TaskTitleSchema = z12.string().trim().min(1, "\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u043E").max(300, "\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u0434\u043E\u043B\u0436\u043D\u043E \u0431\u044B\u0442\u044C \u043D\u0435 \u0434\u043B\u0438\u043D\u043D\u0435\u0435 300 \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432");
|
|
560
|
+
var TaskDescriptionSchema = z12.string().max(5e4, "\u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 \u0434\u043E\u043B\u0436\u043D\u043E \u0431\u044B\u0442\u044C \u043D\u0435 \u0434\u043B\u0438\u043D\u043D\u0435\u0435 50000 \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432");
|
|
561
|
+
var TaskLabelSchema = z12.string().trim().min(1).max(40, "\u041C\u0435\u0442\u043A\u0430 \u0434\u043E\u043B\u0436\u043D\u0430 \u0431\u044B\u0442\u044C \u043D\u0435 \u0434\u043B\u0438\u043D\u043D\u0435\u0435 40 \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432");
|
|
562
|
+
var TaskLabelsSchema = z12.array(TaskLabelSchema).max(30, "\u041D\u0435 \u0431\u043E\u043B\u044C\u0448\u0435 30 \u043C\u0435\u0442\u043E\u043A");
|
|
563
|
+
var TaskMetadataSchema = z12.record(z12.string(), z12.unknown());
|
|
564
|
+
var TaskAcceptanceSchema = z12.string().max(2e4, "\u041A\u0440\u0438\u0442\u0435\u0440\u0438\u0438 \u043F\u0440\u0438\u0451\u043C\u043A\u0438 \u0434\u043E\u043B\u0436\u043D\u044B \u0431\u044B\u0442\u044C \u043D\u0435 \u0434\u043B\u0438\u043D\u043D\u0435\u0435 20000 \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432");
|
|
565
|
+
var TaskEstimateMinSchema = z12.number().int("\u041E\u0446\u0435\u043D\u043A\u0430 \u2014 \u0446\u0435\u043B\u043E\u0435 \u0447\u0438\u0441\u043B\u043E \u043C\u0438\u043D\u0443\u0442").positive("\u041E\u0446\u0435\u043D\u043A\u0430 \u0434\u043E\u043B\u0436\u043D\u0430 \u0431\u044B\u0442\u044C \u043F\u043E\u043B\u043E\u0436\u0438\u0442\u0435\u043B\u044C\u043D\u043E\u0439").max(1e5);
|
|
566
|
+
var TaskOrderSchema = z12.number().finite("order \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C \u043A\u043E\u043D\u0435\u0447\u043D\u044B\u043C \u0447\u0438\u0441\u043B\u043E\u043C");
|
|
567
|
+
var TaskResultMdSchema = z12.string().max(5e4);
|
|
568
|
+
var TaskResultLinkKindSchema = z12.enum(["pr", "commit", "url"]);
|
|
569
|
+
var TaskResultLinkSchema = z12.object({
|
|
534
570
|
kind: TaskResultLinkKindSchema,
|
|
535
|
-
url:
|
|
536
|
-
label:
|
|
571
|
+
url: z12.string().url("\u041D\u0435\u043A\u043E\u0440\u0440\u0435\u043A\u0442\u043D\u044B\u0439 URL"),
|
|
572
|
+
label: z12.string().max(200).optional()
|
|
537
573
|
});
|
|
538
|
-
var TaskResultLinksSchema =
|
|
539
|
-
var TaskLastErrorSchema =
|
|
540
|
-
var IdSchema =
|
|
541
|
-
var CreateTaskSchema =
|
|
574
|
+
var TaskResultLinksSchema = z12.array(TaskResultLinkSchema).max(50);
|
|
575
|
+
var TaskLastErrorSchema = z12.string().max(5e3);
|
|
576
|
+
var IdSchema = z12.string().min(1);
|
|
577
|
+
var CreateTaskSchema = z12.object({
|
|
542
578
|
title: TaskTitleSchema,
|
|
543
579
|
descriptionMd: TaskDescriptionSchema.default(""),
|
|
544
580
|
type: TaskTypeSchema.default(TaskType.FEATURE),
|
|
545
581
|
priority: TaskPrioritySchema.default(Priority.P2),
|
|
546
582
|
executor: TaskExecutorSchema.default(Executor.ANY),
|
|
547
|
-
roleKey:
|
|
583
|
+
roleKey: z12.string().min(1).max(60).optional(),
|
|
548
584
|
assigneeId: IdSchema.optional(),
|
|
549
585
|
milestoneId: IdSchema.optional(),
|
|
550
586
|
parentId: IdSchema.optional(),
|
|
@@ -552,19 +588,31 @@ var CreateTaskSchema = z11.object({
|
|
|
552
588
|
metadata: TaskMetadataSchema.default({}),
|
|
553
589
|
acceptance: TaskAcceptanceSchema.optional(),
|
|
554
590
|
estimateMin: TaskEstimateMinSchema.optional(),
|
|
555
|
-
dueAt:
|
|
591
|
+
dueAt: z12.coerce.date().optional(),
|
|
556
592
|
/** Позиция в колонке BACKLOG; если не передан — сервер ставит в конец (apps/web/src/lib/tasks/order.ts). */
|
|
557
|
-
order: TaskOrderSchema.optional()
|
|
593
|
+
order: TaskOrderSchema.optional(),
|
|
594
|
+
/**
|
|
595
|
+
* Файлы, приложенные человеком при постановке задачи (задача владельца
|
|
596
|
+
* 18.09.2026).
|
|
597
|
+
*
|
|
598
|
+
* Уже ЗАГРУЖЕННЫЕ: браузер кладёт их прямо в MinIO по подписанной
|
|
599
|
+
* ссылке, сюда приезжают только ключи. Сервер сверяет ключ с проектом и
|
|
600
|
+
* проверяет, что объект существует, — доверять клиенту здесь нельзя.
|
|
601
|
+
*
|
|
602
|
+
* Поле необязательное, и старый клиент, не знающий о нём, продолжает
|
|
603
|
+
* создавать задачи как раньше.
|
|
604
|
+
*/
|
|
605
|
+
attachments: AttachmentListSchema.default([])
|
|
558
606
|
});
|
|
559
|
-
var UpdateTaskSchema =
|
|
607
|
+
var UpdateTaskSchema = z12.object({
|
|
560
608
|
title: TaskTitleSchema.optional(),
|
|
561
609
|
descriptionMd: TaskDescriptionSchema.optional(),
|
|
562
610
|
type: TaskTypeSchema.optional(),
|
|
563
611
|
status: TaskStatusSchema.optional(),
|
|
564
|
-
statusComment:
|
|
612
|
+
statusComment: z12.string().max(2e4).optional(),
|
|
565
613
|
priority: TaskPrioritySchema.optional(),
|
|
566
614
|
executor: TaskExecutorSchema.optional(),
|
|
567
|
-
roleKey:
|
|
615
|
+
roleKey: z12.string().min(1).max(60).nullable().optional(),
|
|
568
616
|
assigneeId: IdSchema.nullable().optional(),
|
|
569
617
|
milestoneId: IdSchema.nullable().optional(),
|
|
570
618
|
parentId: IdSchema.nullable().optional(),
|
|
@@ -572,7 +620,7 @@ var UpdateTaskSchema = z11.object({
|
|
|
572
620
|
metadata: TaskMetadataSchema.optional(),
|
|
573
621
|
acceptance: TaskAcceptanceSchema.nullable().optional(),
|
|
574
622
|
estimateMin: TaskEstimateMinSchema.nullable().optional(),
|
|
575
|
-
dueAt:
|
|
623
|
+
dueAt: z12.coerce.date().nullable().optional(),
|
|
576
624
|
order: TaskOrderSchema.optional(),
|
|
577
625
|
resultMd: TaskResultMdSchema.nullable().optional(),
|
|
578
626
|
resultLinks: TaskResultLinksSchema.nullable().optional(),
|
|
@@ -583,55 +631,55 @@ var UpdateTaskSchema = z11.object({
|
|
|
583
631
|
});
|
|
584
632
|
var TASK_LIST_DEFAULT_LIMIT = 25;
|
|
585
633
|
var TASK_LIST_MAX_LIMIT = 100;
|
|
586
|
-
var TaskListQuerySchema =
|
|
587
|
-
status:
|
|
588
|
-
role:
|
|
589
|
-
assignee:
|
|
590
|
-
milestone:
|
|
591
|
-
label:
|
|
634
|
+
var TaskListQuerySchema = z12.object({
|
|
635
|
+
status: z12.string().max(500).optional(),
|
|
636
|
+
role: z12.string().max(500).optional(),
|
|
637
|
+
assignee: z12.string().max(500).optional(),
|
|
638
|
+
milestone: z12.string().max(500).optional(),
|
|
639
|
+
label: z12.string().max(500).optional(),
|
|
592
640
|
// §16.3 ТЗ перечисляет приоритет и тип среди фильтров доски и списка.
|
|
593
641
|
// Без них интерфейсу пришлось бы фильтровать уже загруженную страницу —
|
|
594
642
|
// на проекте крупнее одной страницы это даёт неверный результат.
|
|
595
|
-
priority:
|
|
596
|
-
type:
|
|
597
|
-
q:
|
|
598
|
-
cursor:
|
|
599
|
-
limit:
|
|
600
|
-
});
|
|
601
|
-
var BulkTaskIdsSchema =
|
|
602
|
-
var BulkTaskActionSchema =
|
|
603
|
-
|
|
604
|
-
action:
|
|
643
|
+
priority: z12.string().max(100).optional(),
|
|
644
|
+
type: z12.string().max(200).optional(),
|
|
645
|
+
q: z12.string().trim().max(200).optional(),
|
|
646
|
+
cursor: z12.string().max(4e3).optional(),
|
|
647
|
+
limit: z12.coerce.number().int().min(1).max(TASK_LIST_MAX_LIMIT).default(TASK_LIST_DEFAULT_LIMIT)
|
|
648
|
+
});
|
|
649
|
+
var BulkTaskIdsSchema = z12.array(IdSchema).min(1, "\u041D\u0443\u0436\u043D\u043E \u043F\u0435\u0440\u0435\u0434\u0430\u0442\u044C \u0445\u043E\u0442\u044F \u0431\u044B \u043E\u0434\u043D\u0443 \u0437\u0430\u0434\u0430\u0447\u0443").max(500, "\u041D\u0435 \u0431\u043E\u043B\u044C\u0448\u0435 500 \u0437\u0430\u0434\u0430\u0447 \u0437\u0430 \u043E\u0434\u0438\u043D \u0437\u0430\u043F\u0440\u043E\u0441");
|
|
650
|
+
var BulkTaskActionSchema = z12.discriminatedUnion("action", [
|
|
651
|
+
z12.object({
|
|
652
|
+
action: z12.literal("status"),
|
|
605
653
|
taskIds: BulkTaskIdsSchema,
|
|
606
654
|
status: TaskStatusSchema,
|
|
607
|
-
comment:
|
|
655
|
+
comment: z12.string().max(2e4).optional()
|
|
608
656
|
}),
|
|
609
|
-
|
|
610
|
-
action:
|
|
657
|
+
z12.object({
|
|
658
|
+
action: z12.literal("milestone"),
|
|
611
659
|
taskIds: BulkTaskIdsSchema,
|
|
612
660
|
milestoneId: IdSchema.nullable()
|
|
613
661
|
}),
|
|
614
|
-
|
|
615
|
-
action:
|
|
662
|
+
z12.object({
|
|
663
|
+
action: z12.literal("role"),
|
|
616
664
|
taskIds: BulkTaskIdsSchema,
|
|
617
|
-
roleKey:
|
|
665
|
+
roleKey: z12.string().min(1).max(60).nullable()
|
|
618
666
|
}),
|
|
619
|
-
|
|
620
|
-
action:
|
|
667
|
+
z12.object({
|
|
668
|
+
action: z12.literal("delete"),
|
|
621
669
|
taskIds: BulkTaskIdsSchema
|
|
622
670
|
})
|
|
623
671
|
]);
|
|
624
|
-
var BulkTaskResultItemSchema =
|
|
625
|
-
taskId:
|
|
626
|
-
ok:
|
|
627
|
-
error:
|
|
672
|
+
var BulkTaskResultItemSchema = z12.object({
|
|
673
|
+
taskId: z12.string(),
|
|
674
|
+
ok: z12.boolean(),
|
|
675
|
+
error: z12.object({ code: z12.string(), message: z12.string() }).optional()
|
|
628
676
|
});
|
|
629
677
|
|
|
630
678
|
// ../shared/src/dto/task-template.ts
|
|
631
|
-
var TaskTemplateNameSchema =
|
|
632
|
-
var TaskTemplateSchema =
|
|
679
|
+
var TaskTemplateNameSchema = z13.string().trim().min(1, "\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u043E").max(100, "\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u0434\u043E\u043B\u0436\u043D\u043E \u0431\u044B\u0442\u044C \u043D\u0435 \u0434\u043B\u0438\u043D\u043D\u0435\u0435 100 \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432");
|
|
680
|
+
var TaskTemplateSchema = z13.object({
|
|
633
681
|
/** Генерируется сервером при создании (`crypto.randomUUID()`), не вводится человеком. */
|
|
634
|
-
id:
|
|
682
|
+
id: z13.string().min(1),
|
|
635
683
|
/** Имя шаблона в списке выбора — НЕ заголовок будущей задачи (то поле — `title` ниже). */
|
|
636
684
|
name: TaskTemplateNameSchema,
|
|
637
685
|
type: TaskTypeSchema,
|
|
@@ -645,7 +693,7 @@ var TaskTemplateSchema = z12.object({
|
|
|
645
693
|
descriptionMd: TaskDescriptionSchema.default(""),
|
|
646
694
|
priority: TaskPrioritySchema.default(Priority.P2),
|
|
647
695
|
executor: TaskExecutorSchema.default(Executor.ANY),
|
|
648
|
-
roleKey:
|
|
696
|
+
roleKey: z13.string().min(1).max(60).optional(),
|
|
649
697
|
labels: TaskLabelsSchema.default([]),
|
|
650
698
|
acceptance: TaskAcceptanceSchema.optional(),
|
|
651
699
|
estimateMin: TaskEstimateMinSchema.optional()
|
|
@@ -661,23 +709,23 @@ var TaskTemplateSchema = z12.object({
|
|
|
661
709
|
// метаданные — редкий случай для многоразового шаблона, при
|
|
662
710
|
// необходимости человек добавит их на созданной задаче.
|
|
663
711
|
});
|
|
664
|
-
var TaskTemplatesSchema =
|
|
712
|
+
var TaskTemplatesSchema = z13.array(TaskTemplateSchema).max(50, "\u041D\u0435 \u0431\u043E\u043B\u044C\u0448\u0435 50 \u0448\u0430\u0431\u043B\u043E\u043D\u043E\u0432");
|
|
665
713
|
var TaskTemplateInputSchema = TaskTemplateSchema.omit({ id: true });
|
|
666
714
|
|
|
667
715
|
// ../shared/src/settings/project-settings.ts
|
|
668
716
|
var taskStatusValues2 = Object.values(TaskStatus);
|
|
669
|
-
var TaskStatusSchema2 =
|
|
670
|
-
var BoardSettingsSchema =
|
|
671
|
-
hiddenStatuses:
|
|
672
|
-
mergedColumns:
|
|
673
|
-
});
|
|
674
|
-
var NotificationSettingsSchema =
|
|
675
|
-
telegram:
|
|
676
|
-
email:
|
|
677
|
-
});
|
|
678
|
-
var ProjectSettingsSchema =
|
|
679
|
-
autoAccept:
|
|
680
|
-
requireTests:
|
|
717
|
+
var TaskStatusSchema2 = z14.enum(taskStatusValues2);
|
|
718
|
+
var BoardSettingsSchema = z14.object({
|
|
719
|
+
hiddenStatuses: z14.array(TaskStatusSchema2).default([]),
|
|
720
|
+
mergedColumns: z14.array(z14.array(TaskStatusSchema2)).default([])
|
|
721
|
+
});
|
|
722
|
+
var NotificationSettingsSchema = z14.object({
|
|
723
|
+
telegram: z14.boolean().default(false),
|
|
724
|
+
email: z14.boolean().default(false)
|
|
725
|
+
});
|
|
726
|
+
var ProjectSettingsSchema = z14.object({
|
|
727
|
+
autoAccept: z14.boolean().default(false),
|
|
728
|
+
requireTests: z14.boolean().default(true),
|
|
681
729
|
/**
|
|
682
730
|
* Не давать человеку принять задачу, пока проверки GitHub по последнему
|
|
683
731
|
* коммиту красные.
|
|
@@ -699,7 +747,7 @@ var ProjectSettingsSchema = z13.object({
|
|
|
699
747
|
* настройке — иначе получилось бы обещание, которого настройка не
|
|
700
748
|
* держит.
|
|
701
749
|
*/
|
|
702
|
-
requireGreenChecks:
|
|
750
|
+
requireGreenChecks: z14.boolean().default(false),
|
|
703
751
|
/**
|
|
704
752
|
* Заводить задачу на ревью, когда для задачи открывается pull request.
|
|
705
753
|
*
|
|
@@ -711,19 +759,19 @@ var ProjectSettingsSchema = z13.object({
|
|
|
711
759
|
* начать плодить задачи в уже работающих проектах — не то, чего от
|
|
712
760
|
* обновления ждут.
|
|
713
761
|
*/
|
|
714
|
-
reviewTaskOnPr:
|
|
762
|
+
reviewTaskOnPr: z14.boolean().default(false),
|
|
715
763
|
/**
|
|
716
764
|
* Ключ роли, на которую вешается задача ревью (`RoleDefinition.key`).
|
|
717
765
|
* Пусто — задача заводится без роли и видна всей команде проекта.
|
|
718
766
|
*/
|
|
719
|
-
reviewRoleKey:
|
|
720
|
-
maxParallelTasksPerAgent:
|
|
721
|
-
leaseTtlSec:
|
|
722
|
-
taskTimeoutMin:
|
|
723
|
-
contextResetAfterTasks:
|
|
724
|
-
branchTemplate:
|
|
725
|
-
commitTemplate:
|
|
726
|
-
stopPatternsOverride:
|
|
767
|
+
reviewRoleKey: z14.string().trim().min(1).max(60).optional(),
|
|
768
|
+
maxParallelTasksPerAgent: z14.number().int().positive().default(1),
|
|
769
|
+
leaseTtlSec: z14.number().int().positive().default(120),
|
|
770
|
+
taskTimeoutMin: z14.number().int().positive().default(90),
|
|
771
|
+
contextResetAfterTasks: z14.number().int().positive().default(8),
|
|
772
|
+
branchTemplate: z14.string().min(1).default("task/{key}-{slug}"),
|
|
773
|
+
commitTemplate: z14.string().min(1).default("{key}: {title}"),
|
|
774
|
+
stopPatternsOverride: z14.array(z14.string()).optional(),
|
|
727
775
|
notifications: NotificationSettingsSchema.default({ telegram: false, email: false }),
|
|
728
776
|
board: BoardSettingsSchema.default({ hiddenStatuses: [], mergedColumns: [] }),
|
|
729
777
|
// Шаблоны задач (§16.3 ТЗ: «Шаблоны задач по типу (настраиваются в
|
|
@@ -733,32 +781,32 @@ var ProjectSettingsSchema = z13.object({
|
|
|
733
781
|
});
|
|
734
782
|
|
|
735
783
|
// ../shared/src/dto/project.ts
|
|
736
|
-
var ProjectKeySchema =
|
|
737
|
-
var ProjectNameSchema =
|
|
738
|
-
var ProjectDescriptionSchema =
|
|
784
|
+
var ProjectKeySchema = z15.string().min(2, "\u041A\u043B\u044E\u0447 \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C \u043D\u0435 \u043A\u043E\u0440\u043E\u0447\u0435 2 \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432").max(8, "\u041A\u043B\u044E\u0447 \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C \u043D\u0435 \u0434\u043B\u0438\u043D\u043D\u0435\u0435 8 \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432").regex(/^[A-Z][A-Z0-9]*$/, "\u041A\u043B\u044E\u0447: \u0437\u0430\u0433\u043B\u0430\u0432\u043D\u044B\u0435 \u043B\u0430\u0442\u0438\u043D\u0441\u043A\u0438\u0435 \u0431\u0443\u043A\u0432\u044B \u0438 \u0446\u0438\u0444\u0440\u044B, \u043D\u0430\u0447\u0438\u043D\u0430\u0435\u0442\u0441\u044F \u0441 \u0431\u0443\u043A\u0432\u044B");
|
|
785
|
+
var ProjectNameSchema = z15.string().trim().min(1, "\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u043E").max(100, "\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u0434\u043E\u043B\u0436\u043D\u043E \u0431\u044B\u0442\u044C \u043D\u0435 \u0434\u043B\u0438\u043D\u043D\u0435\u0435 100 \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432");
|
|
786
|
+
var ProjectDescriptionSchema = z15.string().max(5e3, "\u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 \u0434\u043E\u043B\u0436\u043D\u043E \u0431\u044B\u0442\u044C \u043D\u0435 \u0434\u043B\u0438\u043D\u043D\u0435\u0435 5000 \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432");
|
|
739
787
|
var ProjectSettingsRecordSchema = ProjectSettingsSchema.extend({
|
|
740
|
-
autonomousConfirmedAt:
|
|
788
|
+
autonomousConfirmedAt: z15.coerce.date().optional()
|
|
741
789
|
});
|
|
742
790
|
var UpdateProjectSettingsSchema = ProjectSettingsRecordSchema.partial();
|
|
743
|
-
var ProjectModeSchema =
|
|
744
|
-
var ProjectStatusSchema =
|
|
791
|
+
var ProjectModeSchema = z15.enum([ProjectMode.AUTONOMOUS, ProjectMode.APPROVAL]);
|
|
792
|
+
var ProjectStatusSchema = z15.enum([
|
|
745
793
|
ProjectStatus.ACTIVE,
|
|
746
794
|
ProjectStatus.PAUSED,
|
|
747
795
|
ProjectStatus.ARCHIVED
|
|
748
796
|
]);
|
|
749
|
-
var GitModeSchema =
|
|
750
|
-
var ProjectDateSchema =
|
|
751
|
-
var NewProjectMilestoneSchema =
|
|
752
|
-
name:
|
|
797
|
+
var GitModeSchema = z15.enum([GitMode.DIRECT, GitMode.PR]);
|
|
798
|
+
var ProjectDateSchema = z15.coerce.date();
|
|
799
|
+
var NewProjectMilestoneSchema = z15.object({
|
|
800
|
+
name: z15.string().trim().min(1, "\u0423\u043A\u0430\u0436\u0438\u0442\u0435 \u043D\u0430\u0437\u0432\u0430\u043D\u0438\u0435").max(200),
|
|
753
801
|
dueAt: ProjectDateSchema.optional()
|
|
754
802
|
});
|
|
755
|
-
var CreateProjectSchema =
|
|
803
|
+
var CreateProjectSchema = z15.object({
|
|
756
804
|
name: ProjectNameSchema,
|
|
757
805
|
key: ProjectKeySchema.optional(),
|
|
758
806
|
description: ProjectDescriptionSchema.optional(),
|
|
759
807
|
mode: ProjectModeSchema.default(ProjectMode.APPROVAL),
|
|
760
808
|
gitMode: GitModeSchema.default(GitMode.DIRECT),
|
|
761
|
-
autonomousConfirmed:
|
|
809
|
+
autonomousConfirmed: z15.boolean().optional(),
|
|
762
810
|
startAt: ProjectDateSchema.optional(),
|
|
763
811
|
targetAt: ProjectDateSchema.optional(),
|
|
764
812
|
/**
|
|
@@ -767,15 +815,15 @@ var CreateProjectSchema = z14.object({
|
|
|
767
815
|
* второго запроса проект оставался бы без людей, и человек не понял
|
|
768
816
|
* бы, создался он или нет.
|
|
769
817
|
*/
|
|
770
|
-
memberIds:
|
|
771
|
-
milestones:
|
|
818
|
+
memberIds: z15.array(z15.string().min(1)).max(100).optional(),
|
|
819
|
+
milestones: z15.array(NewProjectMilestoneSchema).max(50).optional()
|
|
772
820
|
}).refine((data) => !data.startAt || !data.targetAt || data.startAt <= data.targetAt, {
|
|
773
821
|
// Срок раньше начала — почти всегда опечатка в одном из полей, и
|
|
774
822
|
// молча сохранённая, она потом показывается как «просрочен с первого дня».
|
|
775
823
|
message: "\u0414\u0430\u0442\u0430 \u0446\u0435\u043B\u0438 \u0440\u0430\u043D\u044C\u0448\u0435 \u0434\u0430\u0442\u044B \u043D\u0430\u0447\u0430\u043B\u0430",
|
|
776
824
|
path: ["targetAt"]
|
|
777
825
|
});
|
|
778
|
-
var UpdateProjectSchema =
|
|
826
|
+
var UpdateProjectSchema = z15.object({
|
|
779
827
|
name: ProjectNameSchema.optional(),
|
|
780
828
|
key: ProjectKeySchema.optional(),
|
|
781
829
|
description: ProjectDescriptionSchema.nullable().optional(),
|
|
@@ -785,28 +833,28 @@ var UpdateProjectSchema = z14.object({
|
|
|
785
833
|
startAt: ProjectDateSchema.nullable().optional(),
|
|
786
834
|
targetAt: ProjectDateSchema.nullable().optional(),
|
|
787
835
|
settings: UpdateProjectSettingsSchema.optional(),
|
|
788
|
-
autonomousConfirmed:
|
|
836
|
+
autonomousConfirmed: z15.boolean().optional()
|
|
789
837
|
}).refine((data) => Object.keys(data).length > 0, {
|
|
790
838
|
message: "\u041D\u0443\u0436\u043D\u043E \u043F\u0435\u0440\u0435\u0434\u0430\u0442\u044C \u0445\u043E\u0442\u044F \u0431\u044B \u043E\u0434\u043D\u043E \u043F\u043E\u043B\u0435"
|
|
791
839
|
});
|
|
792
840
|
|
|
793
841
|
// ../shared/src/dto/repository.ts
|
|
794
|
-
import { z as
|
|
795
|
-
var RepositoryUrlSchema =
|
|
842
|
+
import { z as z16 } from "zod";
|
|
843
|
+
var RepositoryUrlSchema = z16.string().trim().min(1, "\u0423\u043A\u0430\u0436\u0438\u0442\u0435 \u0430\u0434\u0440\u0435\u0441 \u0440\u0435\u043F\u043E\u0437\u0438\u0442\u043E\u0440\u0438\u044F").max(500).refine(
|
|
796
844
|
(value) => /^(https?:\/\/|ssh:\/\/|git@)/.test(value),
|
|
797
845
|
"\u0410\u0434\u0440\u0435\u0441 \u0434\u043E\u043B\u0436\u0435\u043D \u043D\u0430\u0447\u0438\u043D\u0430\u0442\u044C\u0441\u044F \u0441 https://, ssh:// \u0438\u043B\u0438 git@"
|
|
798
846
|
).refine(
|
|
799
847
|
(value) => inferGitProvider(value) !== GitProvider.GITHUB,
|
|
800
848
|
"\u0420\u0435\u043F\u043E\u0437\u0438\u0442\u043E\u0440\u0438\u0438 GitHub \u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0430\u044E\u0442\u0441\u044F \u0447\u0435\u0440\u0435\u0437 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0435 \u2014 \u0432\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0438\u0437 \u0441\u043F\u0438\u0441\u043A\u0430"
|
|
801
849
|
);
|
|
802
|
-
var DefaultBranchSchema =
|
|
803
|
-
var PathHintSchema =
|
|
804
|
-
var CreateRepositorySchema =
|
|
850
|
+
var DefaultBranchSchema = z16.string().trim().min(1).max(200);
|
|
851
|
+
var PathHintSchema = z16.string().trim().max(300);
|
|
852
|
+
var CreateRepositorySchema = z16.object({
|
|
805
853
|
url: RepositoryUrlSchema,
|
|
806
854
|
defaultBranch: DefaultBranchSchema.optional(),
|
|
807
855
|
pathHint: PathHintSchema.optional()
|
|
808
856
|
});
|
|
809
|
-
var UpdateRepositorySchema =
|
|
857
|
+
var UpdateRepositorySchema = z16.object({
|
|
810
858
|
url: RepositoryUrlSchema.optional(),
|
|
811
859
|
defaultBranch: DefaultBranchSchema.optional(),
|
|
812
860
|
// `null` — «убрать путь», отличается от «поле не прислали».
|
|
@@ -814,11 +862,11 @@ var UpdateRepositorySchema = z15.object({
|
|
|
814
862
|
}).refine((data) => Object.keys(data).length > 0, {
|
|
815
863
|
message: "\u041D\u0443\u0436\u043D\u043E \u043F\u0435\u0440\u0435\u0434\u0430\u0442\u044C \u0445\u043E\u0442\u044F \u0431\u044B \u043E\u0434\u043D\u043E \u043F\u043E\u043B\u0435"
|
|
816
864
|
});
|
|
817
|
-
var ConnectGithubRepositorySchema =
|
|
865
|
+
var ConnectGithubRepositorySchema = z16.object({
|
|
818
866
|
/** Идентификатор НАШЕЙ записи установки, а не номер установки в GitHub. */
|
|
819
|
-
installationId:
|
|
867
|
+
installationId: z16.string().min(1, "\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0430\u043A\u043A\u0430\u0443\u043D\u0442 GitHub"),
|
|
820
868
|
/** `owner/repo` — ровно в том виде, в каком его отдал GitHub. */
|
|
821
|
-
fullName:
|
|
869
|
+
fullName: z16.string().trim().min(3, "\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0440\u0435\u043F\u043E\u0437\u0438\u0442\u043E\u0440\u0438\u0439").max(300).regex(/^[^/\s]+\/[^/\s]+$/, "\u041E\u0436\u0438\u0434\u0430\u0435\u0442\u0441\u044F owner/repo"),
|
|
822
870
|
pathHint: PathHintSchema.optional()
|
|
823
871
|
});
|
|
824
872
|
function extractHost(url) {
|
|
@@ -839,26 +887,26 @@ function inferGitProvider(url) {
|
|
|
839
887
|
}
|
|
840
888
|
|
|
841
889
|
// ../shared/src/dto/role.ts
|
|
842
|
-
import { z as
|
|
843
|
-
var RoleNameSchema =
|
|
844
|
-
var RoleColorSchema =
|
|
845
|
-
var CreateRoleSchema =
|
|
890
|
+
import { z as z17 } from "zod";
|
|
891
|
+
var RoleNameSchema = z17.string().trim().min(1, "\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u043E").max(60, "\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u0434\u043E\u043B\u0436\u043D\u043E \u0431\u044B\u0442\u044C \u043D\u0435 \u0434\u043B\u0438\u043D\u043D\u0435\u0435 60 \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432");
|
|
892
|
+
var RoleColorSchema = z17.string().regex(/^#[0-9a-fA-F]{6}$/, "\u0426\u0432\u0435\u0442: hex-\u0444\u043E\u0440\u043C\u0430\u0442, \u043D\u0430\u043F\u0440\u0438\u043C\u0435\u0440 #3B82F6");
|
|
893
|
+
var CreateRoleSchema = z17.object({
|
|
846
894
|
name: RoleNameSchema,
|
|
847
895
|
color: RoleColorSchema,
|
|
848
|
-
defaultTrustProfileId:
|
|
896
|
+
defaultTrustProfileId: z17.string().optional()
|
|
849
897
|
});
|
|
850
|
-
var UpdateRoleSchema =
|
|
898
|
+
var UpdateRoleSchema = z17.object({
|
|
851
899
|
name: RoleNameSchema.optional(),
|
|
852
900
|
color: RoleColorSchema.optional(),
|
|
853
|
-
defaultTrustProfileId:
|
|
901
|
+
defaultTrustProfileId: z17.string().nullable().optional()
|
|
854
902
|
}).refine((data) => Object.keys(data).length > 0, {
|
|
855
903
|
message: "\u041D\u0443\u0436\u043D\u043E \u043F\u0435\u0440\u0435\u0434\u0430\u0442\u044C \u0445\u043E\u0442\u044F \u0431\u044B \u043E\u0434\u043D\u043E \u043F\u043E\u043B\u0435"
|
|
856
904
|
});
|
|
857
905
|
|
|
858
906
|
// ../shared/src/dto/saved-filter.ts
|
|
859
|
-
import { z as
|
|
860
|
-
var SavedFilterNameSchema =
|
|
861
|
-
var SavedFilterQuerySchema =
|
|
907
|
+
import { z as z18 } from "zod";
|
|
908
|
+
var SavedFilterNameSchema = z18.string().trim().min(1, "\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u043E").max(80, "\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 \u0434\u043E\u043B\u0436\u043D\u043E \u0431\u044B\u0442\u044C \u043D\u0435 \u0434\u043B\u0438\u043D\u043D\u0435\u0435 80 \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432");
|
|
909
|
+
var SavedFilterQuerySchema = z18.object({
|
|
862
910
|
/**
|
|
863
911
|
* Статусы задач. Появились позже остальных полей — 11 сентября 2026,
|
|
864
912
|
* когда список и доска стали двумя видами одной страницы: у списка
|
|
@@ -868,20 +916,20 @@ var SavedFilterQuerySchema = z17.object({
|
|
|
868
916
|
* до этого дня, поля не содержат вовсе, и без значения по умолчанию
|
|
869
917
|
* разбор ронял бы чужой сохранённый фильтр.
|
|
870
918
|
*/
|
|
871
|
-
statuses:
|
|
872
|
-
roles:
|
|
873
|
-
assignees:
|
|
874
|
-
milestones:
|
|
875
|
-
labels:
|
|
876
|
-
priorities:
|
|
877
|
-
types:
|
|
878
|
-
q:
|
|
879
|
-
});
|
|
880
|
-
var CreateSavedFilterSchema =
|
|
919
|
+
statuses: z18.array(TaskStatusSchema).max(11).default([]),
|
|
920
|
+
roles: z18.array(z18.string().min(1)).max(50).default([]),
|
|
921
|
+
assignees: z18.array(z18.string().min(1)).max(50).default([]),
|
|
922
|
+
milestones: z18.array(z18.string().min(1)).max(50).default([]),
|
|
923
|
+
labels: z18.array(TaskLabelSchema).max(30).default([]),
|
|
924
|
+
priorities: z18.array(TaskPrioritySchema).max(4).default([]),
|
|
925
|
+
types: z18.array(TaskTypeSchema).max(7).default([]),
|
|
926
|
+
q: z18.string().trim().max(200).default("")
|
|
927
|
+
});
|
|
928
|
+
var CreateSavedFilterSchema = z18.object({
|
|
881
929
|
name: SavedFilterNameSchema,
|
|
882
930
|
query: SavedFilterQuerySchema
|
|
883
931
|
});
|
|
884
|
-
var UpdateSavedFilterSchema =
|
|
932
|
+
var UpdateSavedFilterSchema = z18.object({
|
|
885
933
|
name: SavedFilterNameSchema.optional(),
|
|
886
934
|
query: SavedFilterQuerySchema.optional()
|
|
887
935
|
}).refine((data) => Object.keys(data).length > 0, {
|
|
@@ -889,20 +937,20 @@ var UpdateSavedFilterSchema = z17.object({
|
|
|
889
937
|
});
|
|
890
938
|
|
|
891
939
|
// ../shared/src/dto/task-dependency.ts
|
|
892
|
-
import { z as
|
|
893
|
-
var TaskDependencyKindSchema =
|
|
894
|
-
var IdSchema2 =
|
|
895
|
-
var CreateTaskDependencySchema =
|
|
940
|
+
import { z as z19 } from "zod";
|
|
941
|
+
var TaskDependencyKindSchema = z19.enum([DepKind.BLOCKS, DepKind.RELATES]);
|
|
942
|
+
var IdSchema2 = z19.string().min(1);
|
|
943
|
+
var CreateTaskDependencySchema = z19.object({
|
|
896
944
|
toId: IdSchema2,
|
|
897
945
|
kind: TaskDependencyKindSchema.default(DepKind.BLOCKS)
|
|
898
946
|
});
|
|
899
|
-
var DeleteTaskDependencySchema =
|
|
947
|
+
var DeleteTaskDependencySchema = z19.object({
|
|
900
948
|
toId: IdSchema2
|
|
901
949
|
});
|
|
902
950
|
|
|
903
951
|
// ../shared/src/dto/task-event.ts
|
|
904
|
-
import { z as
|
|
905
|
-
var TaskEventKindSchema =
|
|
952
|
+
import { z as z20 } from "zod";
|
|
953
|
+
var TaskEventKindSchema = z20.enum([
|
|
906
954
|
EventKind.COMMENT,
|
|
907
955
|
EventKind.STATUS,
|
|
908
956
|
EventKind.ASSIGN,
|
|
@@ -913,58 +961,58 @@ var TaskEventKindSchema = z19.enum([
|
|
|
913
961
|
EventKind.APPROVAL,
|
|
914
962
|
EventKind.SYSTEM
|
|
915
963
|
]);
|
|
916
|
-
var TaskCommentBodySchema =
|
|
917
|
-
var CreateTaskEventSchema =
|
|
964
|
+
var TaskCommentBodySchema = z20.string().trim().min(1, "\u041A\u043E\u043C\u043C\u0435\u043D\u0442\u0430\u0440\u0438\u0439 \u043D\u0435 \u043C\u043E\u0436\u0435\u0442 \u0431\u044B\u0442\u044C \u043F\u0443\u0441\u0442\u044B\u043C").max(2e4, "\u041A\u043E\u043C\u043C\u0435\u043D\u0442\u0430\u0440\u0438\u0439 \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C \u043D\u0435 \u0434\u043B\u0438\u043D\u043D\u0435\u0435 20000 \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432");
|
|
965
|
+
var CreateTaskEventSchema = z20.object({
|
|
918
966
|
bodyMd: TaskCommentBodySchema
|
|
919
967
|
});
|
|
920
|
-
var TaskCommentPayloadSchema =
|
|
921
|
-
var TaskEditPayloadSchema =
|
|
922
|
-
fields:
|
|
968
|
+
var TaskCommentPayloadSchema = z20.object({ bodyMd: TaskCommentBodySchema });
|
|
969
|
+
var TaskEditPayloadSchema = z20.object({
|
|
970
|
+
fields: z20.record(z20.string(), z20.object({ from: z20.unknown(), to: z20.unknown() }))
|
|
923
971
|
});
|
|
924
|
-
var TaskAssignPayloadSchema =
|
|
925
|
-
from:
|
|
926
|
-
to:
|
|
972
|
+
var TaskAssignPayloadSchema = z20.object({
|
|
973
|
+
from: z20.string().nullable(),
|
|
974
|
+
to: z20.string().nullable()
|
|
927
975
|
});
|
|
928
976
|
var TASK_EVENT_LIST_DEFAULT_LIMIT = 25;
|
|
929
977
|
var TASK_EVENT_LIST_MAX_LIMIT = 100;
|
|
930
|
-
var ListTaskEventsQuerySchema =
|
|
978
|
+
var ListTaskEventsQuerySchema = z20.object({
|
|
931
979
|
/** CSV нескольких kind — как остальные CSV-фильтры задач (lib/tasks/filters.ts). */
|
|
932
|
-
kind:
|
|
933
|
-
cursor:
|
|
934
|
-
limit:
|
|
980
|
+
kind: z20.string().max(300).optional(),
|
|
981
|
+
cursor: z20.string().max(4e3).optional(),
|
|
982
|
+
limit: z20.coerce.number().int().min(1).max(TASK_EVENT_LIST_MAX_LIMIT).default(TASK_EVENT_LIST_DEFAULT_LIMIT)
|
|
935
983
|
});
|
|
936
984
|
|
|
937
985
|
// ../shared/src/dto/task-transition.ts
|
|
938
|
-
import { z as
|
|
939
|
-
var CommentSchema =
|
|
940
|
-
var TransitionTaskSchema =
|
|
986
|
+
import { z as z21 } from "zod";
|
|
987
|
+
var CommentSchema = z21.string().max(2e4, "\u041A\u043E\u043C\u043C\u0435\u043D\u0442\u0430\u0440\u0438\u0439 \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C \u043D\u0435 \u0434\u043B\u0438\u043D\u043D\u0435\u0435 20000 \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432");
|
|
988
|
+
var TransitionTaskSchema = z21.object({
|
|
941
989
|
to: TaskStatusSchema,
|
|
942
990
|
comment: CommentSchema.optional()
|
|
943
991
|
});
|
|
944
|
-
var AcceptTaskSchema =
|
|
992
|
+
var AcceptTaskSchema = z21.object({
|
|
945
993
|
comment: CommentSchema.optional()
|
|
946
994
|
});
|
|
947
|
-
var ReturnTaskSchema =
|
|
995
|
+
var ReturnTaskSchema = z21.object({
|
|
948
996
|
comment: CommentSchema.min(1, "\u041A\u043E\u043C\u043C\u0435\u043D\u0442\u0430\u0440\u0438\u0439 \u0441 \u043F\u0440\u0430\u0432\u043A\u0430\u043C\u0438 \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u0435\u043D")
|
|
949
997
|
});
|
|
950
|
-
var ReopenTaskSchema =
|
|
998
|
+
var ReopenTaskSchema = z21.object({
|
|
951
999
|
reason: CommentSchema.optional()
|
|
952
1000
|
});
|
|
953
|
-
var RequeueTaskSchema =
|
|
1001
|
+
var RequeueTaskSchema = z21.object({
|
|
954
1002
|
reason: CommentSchema.optional()
|
|
955
1003
|
});
|
|
956
1004
|
|
|
957
1005
|
// ../shared/src/dto/trash.ts
|
|
958
|
-
import { z as
|
|
959
|
-
var CommentSchema2 =
|
|
960
|
-
var RestoreTaskSchema =
|
|
1006
|
+
import { z as z22 } from "zod";
|
|
1007
|
+
var CommentSchema2 = z22.string().max(2e4, "\u041A\u043E\u043C\u043C\u0435\u043D\u0442\u0430\u0440\u0438\u0439 \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C \u043D\u0435 \u0434\u043B\u0438\u043D\u043D\u0435\u0435 20000 \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432");
|
|
1008
|
+
var RestoreTaskSchema = z22.object({
|
|
961
1009
|
comment: CommentSchema2.optional()
|
|
962
1010
|
});
|
|
963
1011
|
var TASK_TRASH_LIST_DEFAULT_LIMIT = 25;
|
|
964
1012
|
var TASK_TRASH_LIST_MAX_LIMIT = 100;
|
|
965
|
-
var TaskTrashListQuerySchema =
|
|
966
|
-
cursor:
|
|
967
|
-
limit:
|
|
1013
|
+
var TaskTrashListQuerySchema = z22.object({
|
|
1014
|
+
cursor: z22.string().max(4e3).optional(),
|
|
1015
|
+
limit: z22.coerce.number().int().min(1).max(TASK_TRASH_LIST_MAX_LIMIT).default(TASK_TRASH_LIST_DEFAULT_LIMIT)
|
|
968
1016
|
});
|
|
969
1017
|
|
|
970
1018
|
// ../shared/src/enums/collaboration.ts
|
|
@@ -1009,7 +1057,7 @@ var FAILING_CHECK_CONCLUSIONS = [
|
|
|
1009
1057
|
];
|
|
1010
1058
|
|
|
1011
1059
|
// ../shared/src/events/agent-events.ts
|
|
1012
|
-
import { z as
|
|
1060
|
+
import { z as z23 } from "zod";
|
|
1013
1061
|
var agentStatusValues = Object.values(AgentStatus);
|
|
1014
1062
|
var agentModeValues = Object.values(AgentMode);
|
|
1015
1063
|
var taskStatusValues3 = Object.values(TaskStatus);
|
|
@@ -1022,40 +1070,40 @@ var gitModeValues = Object.values(GitMode);
|
|
|
1022
1070
|
var questionStatusValues = Object.values(QuestionStatus);
|
|
1023
1071
|
var approvalKindValues = Object.values(ApprovalKind);
|
|
1024
1072
|
var approvalStatusValues = Object.values(ApprovalStatus);
|
|
1025
|
-
var trustBashModeSchema =
|
|
1026
|
-
var trustFilesModeSchema =
|
|
1027
|
-
var trustRulesSchema =
|
|
1028
|
-
bash:
|
|
1073
|
+
var trustBashModeSchema = z23.enum(["allow", "approve", "deny"]);
|
|
1074
|
+
var trustFilesModeSchema = z23.enum(["allow", "approve"]);
|
|
1075
|
+
var trustRulesSchema = z23.object({
|
|
1076
|
+
bash: z23.object({
|
|
1029
1077
|
mode: trustBashModeSchema,
|
|
1030
1078
|
// Regex-строки (§14.3 ТЗ) — не z.instanceof(RegExp): TrustRules это Json,
|
|
1031
1079
|
// должен сериализоваться в БД/по сокету как обычные строки.
|
|
1032
|
-
stopPatterns:
|
|
1033
|
-
allowPatterns:
|
|
1080
|
+
stopPatterns: z23.array(z23.string().min(1)),
|
|
1081
|
+
allowPatterns: z23.array(z23.string().min(1)).optional()
|
|
1034
1082
|
}),
|
|
1035
|
-
files:
|
|
1083
|
+
files: z23.object({
|
|
1036
1084
|
mode: trustFilesModeSchema,
|
|
1037
|
-
protectedPaths:
|
|
1085
|
+
protectedPaths: z23.array(z23.string().min(1))
|
|
1038
1086
|
}),
|
|
1039
|
-
git:
|
|
1040
|
-
allowPushDefault:
|
|
1041
|
-
allowForcePush:
|
|
1087
|
+
git: z23.object({
|
|
1088
|
+
allowPushDefault: z23.boolean(),
|
|
1089
|
+
allowForcePush: z23.boolean()
|
|
1042
1090
|
}),
|
|
1043
|
-
network:
|
|
1044
|
-
allowSsh:
|
|
1045
|
-
sshHostsAllow:
|
|
1091
|
+
network: z23.object({
|
|
1092
|
+
allowSsh: z23.boolean(),
|
|
1093
|
+
sshHostsAllow: z23.array(z23.string().min(1)).optional()
|
|
1046
1094
|
}),
|
|
1047
|
-
approvalTtlMin:
|
|
1048
|
-
});
|
|
1049
|
-
var agentSummarySchema =
|
|
1050
|
-
id:
|
|
1051
|
-
projectId:
|
|
1052
|
-
membershipId:
|
|
1053
|
-
name:
|
|
1054
|
-
roleKeys:
|
|
1055
|
-
status:
|
|
1056
|
-
mode:
|
|
1057
|
-
lastSeenAt:
|
|
1058
|
-
clientVersion:
|
|
1095
|
+
approvalTtlMin: z23.number().int().positive()
|
|
1096
|
+
});
|
|
1097
|
+
var agentSummarySchema = z23.object({
|
|
1098
|
+
id: z23.string().min(1),
|
|
1099
|
+
projectId: z23.string().min(1),
|
|
1100
|
+
membershipId: z23.string().min(1),
|
|
1101
|
+
name: z23.string().min(1),
|
|
1102
|
+
roleKeys: z23.array(z23.string().min(1)),
|
|
1103
|
+
status: z23.enum(agentStatusValues),
|
|
1104
|
+
mode: z23.enum(agentModeValues),
|
|
1105
|
+
lastSeenAt: z23.string().datetime().nullable(),
|
|
1106
|
+
clientVersion: z23.string().nullable(),
|
|
1059
1107
|
/**
|
|
1060
1108
|
* Вид агентской программы — СТРОКА, а не `agentKindSchema`.
|
|
1061
1109
|
*
|
|
@@ -1073,20 +1121,20 @@ var agentSummarySchema = z22.object({
|
|
|
1073
1121
|
* Поймано тестом `cli/connect.test.ts`, который как раз отвечает
|
|
1074
1122
|
* ack-ом без этого поля.
|
|
1075
1123
|
*/
|
|
1076
|
-
kind:
|
|
1077
|
-
currentTaskId:
|
|
1078
|
-
tasksCompletedInSession:
|
|
1079
|
-
});
|
|
1080
|
-
var agentCurrentTaskSummarySchema =
|
|
1081
|
-
id:
|
|
1082
|
-
number:
|
|
1083
|
-
title:
|
|
1084
|
-
status:
|
|
1085
|
-
});
|
|
1086
|
-
var agentHelloPayloadSchema =
|
|
1087
|
-
clientVersion:
|
|
1088
|
-
cwd:
|
|
1089
|
-
os:
|
|
1124
|
+
kind: z23.string().nullable().default(null),
|
|
1125
|
+
currentTaskId: z23.string().nullable(),
|
|
1126
|
+
tasksCompletedInSession: z23.number().int().nonnegative()
|
|
1127
|
+
});
|
|
1128
|
+
var agentCurrentTaskSummarySchema = z23.object({
|
|
1129
|
+
id: z23.string().min(1),
|
|
1130
|
+
number: z23.number().int().positive(),
|
|
1131
|
+
title: z23.string().min(1),
|
|
1132
|
+
status: z23.enum(taskStatusValues3)
|
|
1133
|
+
});
|
|
1134
|
+
var agentHelloPayloadSchema = z23.object({
|
|
1135
|
+
clientVersion: z23.string().min(1),
|
|
1136
|
+
cwd: z23.string().min(1),
|
|
1137
|
+
os: z23.string().min(1),
|
|
1090
1138
|
/**
|
|
1091
1139
|
* Какую агентскую программу человек подключил (реестр `AGENT_KINDS`).
|
|
1092
1140
|
*
|
|
@@ -1103,13 +1151,13 @@ var agentHelloPayloadSchema = z22.object({
|
|
|
1103
1151
|
* терпимости — опечатка вида доедет до БД; там она видна как
|
|
1104
1152
|
* «неизвестный агент», и это несопоставимо дешевле.
|
|
1105
1153
|
*/
|
|
1106
|
-
agentKind:
|
|
1154
|
+
agentKind: z23.string().min(1).max(64).optional(),
|
|
1107
1155
|
/**
|
|
1108
1156
|
* Версия самой агентской программы: Claude Code, Codex, Cursor…
|
|
1109
1157
|
* `clientVersion` выше — версия НАШЕГО пакета `@quiel/cli`, это разные
|
|
1110
1158
|
* числа, и путать их дорого при разборе инцидента.
|
|
1111
1159
|
*/
|
|
1112
|
-
agentVersion:
|
|
1160
|
+
agentVersion: z23.string().min(1).optional(),
|
|
1113
1161
|
/**
|
|
1114
1162
|
* Прежнее имя `agentVersion`, когда вид агента был ровно один.
|
|
1115
1163
|
*
|
|
@@ -1118,176 +1166,192 @@ var agentHelloPayloadSchema = z22.object({
|
|
|
1118
1166
|
* неподнявшиеся клиенты отваливаются». Новый клиент шлёт его только
|
|
1119
1167
|
* для Claude Code — для Codex поле с таким именем было бы неправдой.
|
|
1120
1168
|
*/
|
|
1121
|
-
claudeVersion:
|
|
1169
|
+
claudeVersion: z23.string().min(1).optional(),
|
|
1122
1170
|
// Роли, которыми клиент СЕБЯ считает — информационно (лог/диагностика
|
|
1123
1171
|
// рассинхрона), не авторизация: авторизующие `Agent.roleKeys` идут из
|
|
1124
1172
|
// БД (заданы при создании агента, REST §12 ТЗ), этот payload их не
|
|
1125
1173
|
// меняет. См. блок «ВОПРОСЫ» отчёта P2-03.
|
|
1126
|
-
roleKeys:
|
|
1127
|
-
resumeToken:
|
|
1174
|
+
roleKeys: z23.array(z23.string().min(1)),
|
|
1175
|
+
resumeToken: z23.string().min(1).optional()
|
|
1128
1176
|
});
|
|
1129
|
-
var agentHelloAckSchema =
|
|
1177
|
+
var agentHelloAckSchema = z23.object({
|
|
1130
1178
|
agent: agentSummarySchema,
|
|
1131
1179
|
trust: trustRulesSchema,
|
|
1132
1180
|
currentTask: agentCurrentTaskSummarySchema.optional(),
|
|
1133
|
-
mode:
|
|
1181
|
+
mode: z23.enum(agentModeValues)
|
|
1134
1182
|
});
|
|
1135
|
-
var agentHeartbeatPayloadSchema =
|
|
1136
|
-
currentTaskId:
|
|
1137
|
-
resumeToken:
|
|
1138
|
-
status:
|
|
1183
|
+
var agentHeartbeatPayloadSchema = z23.object({
|
|
1184
|
+
currentTaskId: z23.string().min(1).optional(),
|
|
1185
|
+
resumeToken: z23.string().min(1).optional(),
|
|
1186
|
+
status: z23.enum(agentStatusValues)
|
|
1139
1187
|
});
|
|
1140
|
-
var agentHeartbeatAckSchema =
|
|
1141
|
-
ok:
|
|
1142
|
-
leaseExpiresAt:
|
|
1188
|
+
var agentHeartbeatAckSchema = z23.object({
|
|
1189
|
+
ok: z23.boolean(),
|
|
1190
|
+
leaseExpiresAt: z23.string().datetime().optional()
|
|
1143
1191
|
});
|
|
1144
|
-
var agentModePayloadSchema =
|
|
1145
|
-
mode:
|
|
1192
|
+
var agentModePayloadSchema = z23.object({
|
|
1193
|
+
mode: z23.enum(agentModeValues)
|
|
1146
1194
|
});
|
|
1147
|
-
var agentModeAckSchema =
|
|
1148
|
-
ok:
|
|
1149
|
-
mode:
|
|
1195
|
+
var agentModeAckSchema = z23.object({
|
|
1196
|
+
ok: z23.boolean(),
|
|
1197
|
+
mode: z23.enum(agentModeValues).optional()
|
|
1150
1198
|
});
|
|
1151
|
-
var taskPayloadMilestoneSchema =
|
|
1152
|
-
name:
|
|
1153
|
-
dueAt:
|
|
1199
|
+
var taskPayloadMilestoneSchema = z23.object({
|
|
1200
|
+
name: z23.string().min(1),
|
|
1201
|
+
dueAt: z23.string().datetime().nullable()
|
|
1154
1202
|
});
|
|
1155
|
-
var
|
|
1156
|
-
|
|
1203
|
+
var agentAttachmentSchema = z23.object({
|
|
1204
|
+
fileName: z23.string(),
|
|
1205
|
+
mimeType: z23.string(),
|
|
1206
|
+
size: z23.number().int().nonnegative(),
|
|
1207
|
+
downloadUrl: z23.string(),
|
|
1208
|
+
expiresInSeconds: z23.number().int().positive()
|
|
1209
|
+
});
|
|
1210
|
+
var taskPayloadTaskSchema = z23.object({
|
|
1211
|
+
id: z23.string().min(1),
|
|
1157
1212
|
/** Человекочитаемый ключ вида `ATL-42` (§7.5 ТЗ), НЕ то же, что `id`. */
|
|
1158
|
-
key:
|
|
1159
|
-
title:
|
|
1160
|
-
descriptionMd:
|
|
1161
|
-
type:
|
|
1162
|
-
priority:
|
|
1163
|
-
acceptance:
|
|
1164
|
-
attempts:
|
|
1165
|
-
reviewNotes:
|
|
1166
|
-
metadata:
|
|
1167
|
-
labels:
|
|
1168
|
-
milestone: taskPayloadMilestoneSchema.optional()
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1213
|
+
key: z23.string().min(1),
|
|
1214
|
+
title: z23.string().min(1),
|
|
1215
|
+
descriptionMd: z23.string(),
|
|
1216
|
+
type: z23.enum(taskTypeValues2),
|
|
1217
|
+
priority: z23.enum(priorityValues2),
|
|
1218
|
+
acceptance: z23.string(),
|
|
1219
|
+
attempts: z23.number().int().nonnegative(),
|
|
1220
|
+
reviewNotes: z23.string().optional(),
|
|
1221
|
+
metadata: z23.record(z23.string(), z23.unknown()),
|
|
1222
|
+
labels: z23.array(z23.string()),
|
|
1223
|
+
milestone: taskPayloadMilestoneSchema.optional(),
|
|
1224
|
+
/**
|
|
1225
|
+
* Файлы, приложенные человеком к задаче (задача владельца 18.09.2026).
|
|
1226
|
+
*
|
|
1227
|
+
* `default([])` НЕ УКРАШЕНИЕ: клиент 0.4.x про это поле не знает, а
|
|
1228
|
+
* сервер может оказаться новее его. Без умолчания старый клиент валил
|
|
1229
|
+
* бы разбор payload'а целиком — то есть переставал брать задачи из-за
|
|
1230
|
+
* поля, которое ему не нужно.
|
|
1231
|
+
*/
|
|
1232
|
+
attachments: z23.array(agentAttachmentSchema).default([])
|
|
1233
|
+
});
|
|
1234
|
+
var taskPayloadRepoSchema = z23.object({
|
|
1235
|
+
url: z23.string().min(1),
|
|
1236
|
+
defaultBranch: z23.string().min(1),
|
|
1237
|
+
pathHint: z23.string().nullable()
|
|
1238
|
+
});
|
|
1239
|
+
var taskPayloadProjectSchema = z23.object({
|
|
1240
|
+
key: z23.string().min(1),
|
|
1241
|
+
name: z23.string().min(1),
|
|
1242
|
+
mode: z23.enum(projectModeValues),
|
|
1243
|
+
gitMode: z23.enum(gitModeValues),
|
|
1244
|
+
repos: z23.array(taskPayloadRepoSchema),
|
|
1181
1245
|
/** Готовое имя ветки, `task/ATL-42-add-login` — считает сервер, не модель. */
|
|
1182
|
-
branchName:
|
|
1246
|
+
branchName: z23.string().min(1),
|
|
1183
1247
|
/** Префикс сообщения коммита, `ATL-42:`. */
|
|
1184
|
-
commitPrefix:
|
|
1248
|
+
commitPrefix: z23.string().min(1)
|
|
1185
1249
|
});
|
|
1186
|
-
var taskPayloadDependencySchema =
|
|
1187
|
-
key:
|
|
1188
|
-
title:
|
|
1189
|
-
status:
|
|
1190
|
-
resultMd:
|
|
1191
|
-
resultLinks:
|
|
1250
|
+
var taskPayloadDependencySchema = z23.object({
|
|
1251
|
+
key: z23.string().min(1),
|
|
1252
|
+
title: z23.string().min(1),
|
|
1253
|
+
status: z23.enum(taskStatusValues3),
|
|
1254
|
+
resultMd: z23.string().optional(),
|
|
1255
|
+
resultLinks: z23.array(z23.string()).optional()
|
|
1192
1256
|
});
|
|
1193
|
-
var taskPayloadOpenQuestionSchema =
|
|
1194
|
-
id:
|
|
1195
|
-
textMd:
|
|
1196
|
-
answerMd:
|
|
1257
|
+
var taskPayloadOpenQuestionSchema = z23.object({
|
|
1258
|
+
id: z23.string().min(1),
|
|
1259
|
+
textMd: z23.string(),
|
|
1260
|
+
answerMd: z23.string().optional()
|
|
1197
1261
|
});
|
|
1198
|
-
var taskPayloadTrustSchema =
|
|
1199
|
-
profileKey:
|
|
1200
|
-
summary:
|
|
1262
|
+
var taskPayloadTrustSchema = z23.object({
|
|
1263
|
+
profileKey: z23.string().min(1),
|
|
1264
|
+
summary: z23.string()
|
|
1201
1265
|
});
|
|
1202
|
-
var taskPayloadLeaseSchema =
|
|
1203
|
-
resumeToken:
|
|
1204
|
-
expiresAt:
|
|
1266
|
+
var taskPayloadLeaseSchema = z23.object({
|
|
1267
|
+
resumeToken: z23.string().min(1),
|
|
1268
|
+
expiresAt: z23.string().datetime()
|
|
1205
1269
|
});
|
|
1206
|
-
var taskPayloadSchema =
|
|
1270
|
+
var taskPayloadSchema = z23.object({
|
|
1207
1271
|
task: taskPayloadTaskSchema,
|
|
1208
1272
|
project: taskPayloadProjectSchema,
|
|
1209
|
-
dependencies:
|
|
1210
|
-
openQuestions:
|
|
1273
|
+
dependencies: z23.array(taskPayloadDependencySchema),
|
|
1274
|
+
openQuestions: z23.array(taskPayloadOpenQuestionSchema),
|
|
1211
1275
|
trust: taskPayloadTrustSchema,
|
|
1212
1276
|
lease: taskPayloadLeaseSchema
|
|
1213
1277
|
});
|
|
1214
|
-
var taskClaimPayloadSchema =
|
|
1278
|
+
var taskClaimPayloadSchema = z23.object({
|
|
1215
1279
|
/**
|
|
1216
1280
|
* Потолок 600 с — тот же, что §10.3 задаёт для `ask_human`
|
|
1217
1281
|
* («long-poll до 600 с»). Без верхней границы клиент может попросить
|
|
1218
1282
|
* сервер держать ack сутками, а это утечка обработчиков на сервере.
|
|
1219
1283
|
*/
|
|
1220
|
-
waitSec:
|
|
1221
|
-
});
|
|
1222
|
-
var taskClaimAckSchema =
|
|
1223
|
-
var taskStartPayloadSchema =
|
|
1224
|
-
taskId:
|
|
1225
|
-
resumeToken:
|
|
1226
|
-
});
|
|
1227
|
-
var taskStartAckSchema =
|
|
1228
|
-
var taskProgressLevelSchema =
|
|
1229
|
-
var taskProgressPayloadSchema =
|
|
1230
|
-
taskId:
|
|
1231
|
-
note:
|
|
1284
|
+
waitSec: z23.number().int().min(0).max(600)
|
|
1285
|
+
});
|
|
1286
|
+
var taskClaimAckSchema = z23.union([taskPayloadSchema, z23.object({ empty: z23.literal(true) })]);
|
|
1287
|
+
var taskStartPayloadSchema = z23.object({
|
|
1288
|
+
taskId: z23.string().min(1),
|
|
1289
|
+
resumeToken: z23.string().min(1)
|
|
1290
|
+
});
|
|
1291
|
+
var taskStartAckSchema = z23.object({ ok: z23.boolean() });
|
|
1292
|
+
var taskProgressLevelSchema = z23.enum(["debug", "info", "warn", "error"]);
|
|
1293
|
+
var taskProgressPayloadSchema = z23.object({
|
|
1294
|
+
taskId: z23.string().min(1),
|
|
1295
|
+
note: z23.string().min(1),
|
|
1232
1296
|
level: taskProgressLevelSchema.default("info")
|
|
1233
1297
|
});
|
|
1234
|
-
var taskProgressAckSchema =
|
|
1235
|
-
var taskReleasePayloadSchema =
|
|
1236
|
-
taskId:
|
|
1237
|
-
reason:
|
|
1298
|
+
var taskProgressAckSchema = z23.object({ ok: z23.boolean() });
|
|
1299
|
+
var taskReleasePayloadSchema = z23.object({
|
|
1300
|
+
taskId: z23.string().min(1),
|
|
1301
|
+
reason: z23.string().min(1)
|
|
1238
1302
|
});
|
|
1239
|
-
var taskReleaseAckSchema =
|
|
1240
|
-
var taskGetPayloadSchema =
|
|
1241
|
-
taskId:
|
|
1303
|
+
var taskReleaseAckSchema = z23.object({ ok: z23.boolean() });
|
|
1304
|
+
var taskGetPayloadSchema = z23.object({
|
|
1305
|
+
taskId: z23.string().min(1)
|
|
1242
1306
|
});
|
|
1243
1307
|
var taskGetAckSchema = taskPayloadSchema.omit({ lease: true }).extend({
|
|
1244
1308
|
lease: taskPayloadLeaseSchema.optional()
|
|
1245
1309
|
});
|
|
1246
|
-
var reportStatusSchema =
|
|
1247
|
-
var reportLinkSchema =
|
|
1248
|
-
kind:
|
|
1249
|
-
url:
|
|
1250
|
-
title:
|
|
1310
|
+
var reportStatusSchema = z23.enum(["success", "partial", "failed"]);
|
|
1311
|
+
var reportLinkSchema = z23.object({
|
|
1312
|
+
kind: z23.enum(["commit", "pr", "doc", "other"]),
|
|
1313
|
+
url: z23.string().min(1),
|
|
1314
|
+
title: z23.string().optional()
|
|
1251
1315
|
});
|
|
1252
|
-
var reportPayloadSchema =
|
|
1253
|
-
taskId:
|
|
1316
|
+
var reportPayloadSchema = z23.object({
|
|
1317
|
+
taskId: z23.string().min(1),
|
|
1254
1318
|
/**
|
|
1255
1319
|
* Ключ идемпотентности (P2-13): пара `taskId + resumeToken` однозначно
|
|
1256
1320
|
* определяет одну попытку сдачи. Повтор с тем же resumeToken обязан
|
|
1257
1321
|
* вернуть тот же `taskStatus`, а не сдать задачу дважды — модель
|
|
1258
1322
|
* ретраит вызов тула при обрыве связи, и это норма.
|
|
1259
1323
|
*/
|
|
1260
|
-
resumeToken:
|
|
1324
|
+
resumeToken: z23.string().min(1),
|
|
1261
1325
|
status: reportStatusSchema,
|
|
1262
|
-
resultMd:
|
|
1263
|
-
links:
|
|
1264
|
-
testResult:
|
|
1265
|
-
nextSteps:
|
|
1326
|
+
resultMd: z23.string().min(1),
|
|
1327
|
+
links: z23.array(reportLinkSchema),
|
|
1328
|
+
testResult: z23.enum(testResultValues2),
|
|
1329
|
+
nextSteps: z23.string().optional()
|
|
1266
1330
|
});
|
|
1267
|
-
var reportAckSchema =
|
|
1268
|
-
taskStatus:
|
|
1331
|
+
var reportAckSchema = z23.object({
|
|
1332
|
+
taskStatus: z23.enum(taskStatusValues3),
|
|
1269
1333
|
/** true, если этот ack — повтор уже принятой сдачи (идемпотентность). */
|
|
1270
|
-
duplicate:
|
|
1334
|
+
duplicate: z23.boolean().optional()
|
|
1271
1335
|
});
|
|
1272
|
-
var contextIncludeSchema =
|
|
1273
|
-
var contextGetPayloadSchema =
|
|
1274
|
-
taskId:
|
|
1275
|
-
include:
|
|
1336
|
+
var contextIncludeSchema = z23.enum(["spec", "decisions", "documents", "related", "repo"]);
|
|
1337
|
+
var contextGetPayloadSchema = z23.object({
|
|
1338
|
+
taskId: z23.string().min(1).optional(),
|
|
1339
|
+
include: z23.array(contextIncludeSchema).min(1)
|
|
1276
1340
|
});
|
|
1277
|
-
var contextDocumentFileSchema =
|
|
1341
|
+
var contextDocumentFileSchema = z23.object({
|
|
1278
1342
|
/** Имя как у человека на диске: `Спецификация v2.pdf`. */
|
|
1279
|
-
fileName:
|
|
1343
|
+
fileName: z23.string().min(1),
|
|
1280
1344
|
/** Временная ссылка на скачивание — агент читает файл сам. */
|
|
1281
|
-
downloadUrl:
|
|
1345
|
+
downloadUrl: z23.string().min(1),
|
|
1282
1346
|
/** Сколько секунд ссылка живёт: успеть скачать, а не отложить на потом. */
|
|
1283
|
-
expiresInSeconds:
|
|
1347
|
+
expiresInSeconds: z23.number().int().positive()
|
|
1284
1348
|
});
|
|
1285
|
-
var contextDocumentSchema =
|
|
1286
|
-
id:
|
|
1287
|
-
title:
|
|
1288
|
-
kind:
|
|
1349
|
+
var contextDocumentSchema = z23.object({
|
|
1350
|
+
id: z23.string().min(1),
|
|
1351
|
+
title: z23.string().min(1),
|
|
1352
|
+
kind: z23.string().min(1),
|
|
1289
1353
|
/** Текст документа. Пусто, если документ — файл: тогда заполнен `file`. */
|
|
1290
|
-
contentMd:
|
|
1354
|
+
contentMd: z23.string(),
|
|
1291
1355
|
/**
|
|
1292
1356
|
* Заполнен, если документ — файл.
|
|
1293
1357
|
*
|
|
@@ -1297,7 +1361,7 @@ var contextDocumentSchema = z22.object({
|
|
|
1297
1361
|
*/
|
|
1298
1362
|
file: contextDocumentFileSchema.nullable().optional()
|
|
1299
1363
|
});
|
|
1300
|
-
var contextPayloadSchema =
|
|
1364
|
+
var contextPayloadSchema = z23.object({
|
|
1301
1365
|
/**
|
|
1302
1366
|
* Замечания платформы к этому контексту — для агента, словами.
|
|
1303
1367
|
*
|
|
@@ -1312,341 +1376,374 @@ var contextPayloadSchema = z22.object({
|
|
|
1312
1376
|
* гаданию. Пустой ответ, который не объясняет свою пустоту, — та же
|
|
1313
1377
|
* молчаливая ошибка, что и пустая строка вместо файла.
|
|
1314
1378
|
*/
|
|
1315
|
-
notes:
|
|
1379
|
+
notes: z23.array(z23.string()).optional(),
|
|
1316
1380
|
spec: contextDocumentSchema.nullable().optional(),
|
|
1317
|
-
decisions:
|
|
1381
|
+
decisions: z23.array(contextDocumentSchema).optional(),
|
|
1318
1382
|
/** Все документы проекта — любого типа, включая спецификацию и решения. */
|
|
1319
|
-
documents:
|
|
1320
|
-
related:
|
|
1321
|
-
repo:
|
|
1322
|
-
repos:
|
|
1323
|
-
branchName:
|
|
1324
|
-
commitPrefix:
|
|
1383
|
+
documents: z23.array(contextDocumentSchema).optional(),
|
|
1384
|
+
related: z23.array(taskPayloadDependencySchema).optional(),
|
|
1385
|
+
repo: z23.object({
|
|
1386
|
+
repos: z23.array(taskPayloadRepoSchema),
|
|
1387
|
+
branchName: z23.string().optional(),
|
|
1388
|
+
commitPrefix: z23.string().optional()
|
|
1325
1389
|
}).optional()
|
|
1326
1390
|
});
|
|
1327
|
-
var agentRateLimitedPayloadSchema =
|
|
1328
|
-
retryAfterSec:
|
|
1329
|
-
taskId:
|
|
1391
|
+
var agentRateLimitedPayloadSchema = z23.object({
|
|
1392
|
+
retryAfterSec: z23.number().int().positive().optional(),
|
|
1393
|
+
taskId: z23.string().min(1).optional()
|
|
1330
1394
|
});
|
|
1331
|
-
var agentRateLimitedAckSchema =
|
|
1332
|
-
ok:
|
|
1395
|
+
var agentRateLimitedAckSchema = z23.object({
|
|
1396
|
+
ok: z23.boolean(),
|
|
1333
1397
|
/** Когда задача вернётся в очередь (§9.4 ТЗ: «через 2 ч»). */
|
|
1334
|
-
requeueAt:
|
|
1398
|
+
requeueAt: z23.string().datetime().optional()
|
|
1335
1399
|
});
|
|
1336
|
-
var projectStatePayloadSchema =
|
|
1337
|
-
projectId:
|
|
1338
|
-
paused:
|
|
1339
|
-
mode:
|
|
1400
|
+
var projectStatePayloadSchema = z23.object({
|
|
1401
|
+
projectId: z23.string().min(1),
|
|
1402
|
+
paused: z23.boolean(),
|
|
1403
|
+
mode: z23.enum(projectModeValues),
|
|
1340
1404
|
/** Причина паузы для модели; при `paused: false` не заполняется. */
|
|
1341
|
-
reason:
|
|
1342
|
-
});
|
|
1343
|
-
var questionSummarySchema =
|
|
1344
|
-
id:
|
|
1345
|
-
taskId:
|
|
1346
|
-
textMd:
|
|
1347
|
-
options:
|
|
1348
|
-
blocking:
|
|
1349
|
-
status:
|
|
1350
|
-
answerMd:
|
|
1351
|
-
answeredAt:
|
|
1352
|
-
createdAt:
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1405
|
+
reason: z23.string().optional()
|
|
1406
|
+
});
|
|
1407
|
+
var questionSummarySchema = z23.object({
|
|
1408
|
+
id: z23.string().min(1),
|
|
1409
|
+
taskId: z23.string().min(1).nullable(),
|
|
1410
|
+
textMd: z23.string(),
|
|
1411
|
+
options: z23.array(z23.string()),
|
|
1412
|
+
blocking: z23.boolean(),
|
|
1413
|
+
status: z23.enum(questionStatusValues),
|
|
1414
|
+
answerMd: z23.string().nullable(),
|
|
1415
|
+
answeredAt: z23.string().datetime().nullable(),
|
|
1416
|
+
createdAt: z23.string().datetime(),
|
|
1417
|
+
/**
|
|
1418
|
+
* Файлы, приложенные человеком К ОТВЕТУ (задача владельца 18.09.2026).
|
|
1419
|
+
*
|
|
1420
|
+
* Тот же вид, что у вложений задачи, и по той же причине ссылкой, а не
|
|
1421
|
+
* содержимым. `default([])` — чтобы клиент 0.4.x, не знающий поля, не
|
|
1422
|
+
* валил разбор ack'а целиком.
|
|
1423
|
+
*/
|
|
1424
|
+
attachments: z23.array(agentAttachmentSchema).default([])
|
|
1425
|
+
});
|
|
1426
|
+
var questionAskPayloadSchema = z23.object({
|
|
1427
|
+
taskId: z23.string().min(1).optional(),
|
|
1428
|
+
textMd: z23.string().min(1),
|
|
1429
|
+
targetRole: z23.string().min(1).optional(),
|
|
1430
|
+
targetMemberId: z23.string().min(1).optional(),
|
|
1431
|
+
options: z23.array(z23.string().min(1)).optional(),
|
|
1432
|
+
blocking: z23.boolean(),
|
|
1433
|
+
/**
|
|
1434
|
+
* Попросить человека приложить файл к ответу (задача владельца
|
|
1435
|
+
* 18.09.2026: «агент может попросить файлы»).
|
|
1436
|
+
*
|
|
1437
|
+
* ПРОСЬБА, А НЕ ТРЕБОВАНИЕ: форма ответа открывается сразу с выбором
|
|
1438
|
+
* файла, но ответить без вложений по-прежнему можно. Обязать человека
|
|
1439
|
+
* нельзя — он может и не иметь того файла, о котором речь.
|
|
1440
|
+
*/
|
|
1441
|
+
wantsFiles: z23.boolean().optional(),
|
|
1361
1442
|
/** Сколько ждать ответ в этом же вызове. 0 — не ждать, вернуть вопрос сразу. */
|
|
1362
|
-
waitSec:
|
|
1443
|
+
waitSec: z23.number().int().min(0).max(600).optional()
|
|
1363
1444
|
}).refine((v) => Boolean(v.targetRole) !== Boolean(v.targetMemberId), {
|
|
1364
1445
|
message: "\u041D\u0443\u0436\u0435\u043D \u0440\u043E\u0432\u043D\u043E \u043E\u0434\u0438\u043D \u0430\u0434\u0440\u0435\u0441\u0430\u0442: targetRole \u0418\u041B\u0418 targetMemberId"
|
|
1365
1446
|
});
|
|
1366
|
-
var questionAskAckSchema =
|
|
1447
|
+
var questionAskAckSchema = z23.object({
|
|
1367
1448
|
question: questionSummarySchema
|
|
1368
1449
|
});
|
|
1369
|
-
var questionWaitPayloadSchema =
|
|
1370
|
-
questionId:
|
|
1371
|
-
waitSec:
|
|
1450
|
+
var questionWaitPayloadSchema = z23.object({
|
|
1451
|
+
questionId: z23.string().min(1),
|
|
1452
|
+
waitSec: z23.number().int().min(0).max(600)
|
|
1372
1453
|
});
|
|
1373
|
-
var questionWaitAckSchema =
|
|
1454
|
+
var questionWaitAckSchema = z23.object({
|
|
1374
1455
|
question: questionSummarySchema
|
|
1375
1456
|
});
|
|
1376
|
-
var
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1457
|
+
var taskUsageEntrySchema = z23.object({
|
|
1458
|
+
/** Как модель назвал сам агент (`claude-opus-5`). Строка: список моделей меняется чаще схемы. */
|
|
1459
|
+
model: z23.string().min(1).max(200),
|
|
1460
|
+
/** Сколько обращений к модели дали эти числа. */
|
|
1461
|
+
requests: z23.number().int().nonnegative(),
|
|
1462
|
+
inputTokens: z23.number().int().nonnegative(),
|
|
1463
|
+
outputTokens: z23.number().int().nonnegative(),
|
|
1464
|
+
cacheReadTokens: z23.number().int().nonnegative(),
|
|
1465
|
+
cacheCreationTokens: z23.number().int().nonnegative()
|
|
1466
|
+
});
|
|
1467
|
+
var taskUsagePayloadSchema = z23.object({
|
|
1468
|
+
taskId: z23.string().min(1),
|
|
1469
|
+
/** Не больше десяти моделей за порцию — их у задачи одна-две, остальное признак ошибки. */
|
|
1470
|
+
entries: z23.array(taskUsageEntrySchema).min(1).max(10)
|
|
1471
|
+
});
|
|
1472
|
+
var taskUsageAckSchema = z23.object({ ok: z23.boolean() });
|
|
1473
|
+
var taskCreatePayloadSchema = z23.object({
|
|
1474
|
+
title: z23.string().min(1),
|
|
1475
|
+
descriptionMd: z23.string(),
|
|
1476
|
+
roleKey: z23.string().min(1).optional(),
|
|
1477
|
+
assigneeId: z23.string().min(1).optional(),
|
|
1478
|
+
type: z23.enum(taskTypeValues2),
|
|
1479
|
+
priority: z23.enum(priorityValues2),
|
|
1480
|
+
executor: z23.enum(executorValues2),
|
|
1481
|
+
blocksCurrent: z23.boolean(),
|
|
1482
|
+
acceptance: z23.string().optional(),
|
|
1483
|
+
labels: z23.array(z23.string().min(1)).optional()
|
|
1387
1484
|
}).refine((v) => Boolean(v.roleKey) !== Boolean(v.assigneeId), {
|
|
1388
1485
|
message: "\u041D\u0443\u0436\u0435\u043D \u0440\u043E\u0432\u043D\u043E \u043E\u0434\u0438\u043D \u0430\u0434\u0440\u0435\u0441\u0430\u0442: roleKey \u0418\u041B\u0418 assigneeId"
|
|
1389
1486
|
});
|
|
1390
|
-
var taskBriefSchema =
|
|
1391
|
-
id:
|
|
1392
|
-
key:
|
|
1393
|
-
title:
|
|
1394
|
-
type:
|
|
1395
|
-
status:
|
|
1396
|
-
priority:
|
|
1397
|
-
roleKey:
|
|
1398
|
-
assigneeId:
|
|
1399
|
-
labels:
|
|
1400
|
-
updatedAt:
|
|
1401
|
-
});
|
|
1402
|
-
var taskCreateAckSchema =
|
|
1487
|
+
var taskBriefSchema = z23.object({
|
|
1488
|
+
id: z23.string().min(1),
|
|
1489
|
+
key: z23.string().min(1),
|
|
1490
|
+
title: z23.string().min(1),
|
|
1491
|
+
type: z23.enum(taskTypeValues2),
|
|
1492
|
+
status: z23.enum(taskStatusValues3),
|
|
1493
|
+
priority: z23.enum(priorityValues2),
|
|
1494
|
+
roleKey: z23.string().min(1).nullable(),
|
|
1495
|
+
assigneeId: z23.string().min(1).nullable(),
|
|
1496
|
+
labels: z23.array(z23.string()),
|
|
1497
|
+
updatedAt: z23.string().datetime()
|
|
1498
|
+
});
|
|
1499
|
+
var taskCreateAckSchema = z23.object({
|
|
1403
1500
|
task: taskBriefSchema,
|
|
1404
1501
|
/** Во что ушла ТЕКУЩАЯ задача автора, если `blocksCurrent: true`. */
|
|
1405
|
-
currentTaskStatus:
|
|
1502
|
+
currentTaskStatus: z23.enum(taskStatusValues3).optional()
|
|
1406
1503
|
});
|
|
1407
|
-
var taskListPayloadSchema =
|
|
1408
|
-
status:
|
|
1409
|
-
roleKey:
|
|
1504
|
+
var taskListPayloadSchema = z23.object({
|
|
1505
|
+
status: z23.array(z23.enum(taskStatusValues3)).optional(),
|
|
1506
|
+
roleKey: z23.string().min(1).optional(),
|
|
1410
1507
|
/** Поиск по заголовку, без учёта регистра. */
|
|
1411
|
-
query:
|
|
1412
|
-
limit:
|
|
1413
|
-
});
|
|
1414
|
-
var taskListAckSchema =
|
|
1415
|
-
tasks:
|
|
1416
|
-
});
|
|
1417
|
-
var taskUpdatePayloadSchema =
|
|
1418
|
-
taskId:
|
|
1419
|
-
patch:
|
|
1420
|
-
progressNote:
|
|
1421
|
-
labels:
|
|
1422
|
-
estimateMin:
|
|
1508
|
+
query: z23.string().min(1).optional(),
|
|
1509
|
+
limit: z23.number().int().min(1).max(100).optional()
|
|
1510
|
+
});
|
|
1511
|
+
var taskListAckSchema = z23.object({
|
|
1512
|
+
tasks: z23.array(taskBriefSchema)
|
|
1513
|
+
});
|
|
1514
|
+
var taskUpdatePayloadSchema = z23.object({
|
|
1515
|
+
taskId: z23.string().min(1),
|
|
1516
|
+
patch: z23.object({
|
|
1517
|
+
progressNote: z23.string().min(1).optional(),
|
|
1518
|
+
labels: z23.array(z23.string().min(1)).optional(),
|
|
1519
|
+
estimateMin: z23.number().int().positive().optional()
|
|
1423
1520
|
}).refine((v) => Object.keys(v).length > 0, { message: "patch \u043D\u0435 \u043C\u043E\u0436\u0435\u0442 \u0431\u044B\u0442\u044C \u043F\u0443\u0441\u0442\u044B\u043C" })
|
|
1424
1521
|
});
|
|
1425
|
-
var taskUpdateAckSchema =
|
|
1522
|
+
var taskUpdateAckSchema = z23.object({
|
|
1426
1523
|
task: taskBriefSchema
|
|
1427
1524
|
});
|
|
1428
|
-
var modeSetPayloadSchema =
|
|
1429
|
-
mode:
|
|
1525
|
+
var modeSetPayloadSchema = z23.object({
|
|
1526
|
+
mode: z23.enum(agentModeValues)
|
|
1430
1527
|
});
|
|
1431
|
-
var agentPausePayloadSchema =
|
|
1432
|
-
reason:
|
|
1528
|
+
var agentPausePayloadSchema = z23.object({
|
|
1529
|
+
reason: z23.string().min(1)
|
|
1433
1530
|
});
|
|
1434
1531
|
var trustUpdatedPayloadSchema = trustRulesSchema;
|
|
1435
|
-
var leaseLostPayloadSchema =
|
|
1436
|
-
taskId:
|
|
1437
|
-
reason:
|
|
1438
|
-
});
|
|
1439
|
-
var taskUpdatedAgentPayloadSchema =
|
|
1440
|
-
taskId:
|
|
1441
|
-
patch:
|
|
1442
|
-
});
|
|
1443
|
-
var questionAnsweredPayloadSchema =
|
|
1444
|
-
questionId:
|
|
1445
|
-
answerMd:
|
|
1446
|
-
});
|
|
1447
|
-
var approvalSummarySchema =
|
|
1448
|
-
id:
|
|
1449
|
-
taskId:
|
|
1450
|
-
kind:
|
|
1451
|
-
summary:
|
|
1452
|
-
status:
|
|
1453
|
-
expiresAt:
|
|
1454
|
-
decidedAt:
|
|
1455
|
-
createdAt:
|
|
1456
|
-
});
|
|
1457
|
-
var approvalRequestPayloadSchema =
|
|
1458
|
-
taskId:
|
|
1459
|
-
kind:
|
|
1460
|
-
summary:
|
|
1461
|
-
command:
|
|
1462
|
-
cwd:
|
|
1463
|
-
host:
|
|
1464
|
-
diff:
|
|
1532
|
+
var leaseLostPayloadSchema = z23.object({
|
|
1533
|
+
taskId: z23.string().min(1),
|
|
1534
|
+
reason: z23.string().min(1)
|
|
1535
|
+
});
|
|
1536
|
+
var taskUpdatedAgentPayloadSchema = z23.object({
|
|
1537
|
+
taskId: z23.string().min(1),
|
|
1538
|
+
patch: z23.record(z23.string(), z23.unknown()).optional()
|
|
1539
|
+
});
|
|
1540
|
+
var questionAnsweredPayloadSchema = z23.object({
|
|
1541
|
+
questionId: z23.string().min(1),
|
|
1542
|
+
answerMd: z23.string()
|
|
1543
|
+
});
|
|
1544
|
+
var approvalSummarySchema = z23.object({
|
|
1545
|
+
id: z23.string().min(1),
|
|
1546
|
+
taskId: z23.string().min(1),
|
|
1547
|
+
kind: z23.enum(approvalKindValues),
|
|
1548
|
+
summary: z23.string(),
|
|
1549
|
+
status: z23.enum(approvalStatusValues),
|
|
1550
|
+
expiresAt: z23.string().datetime(),
|
|
1551
|
+
decidedAt: z23.string().datetime().nullable(),
|
|
1552
|
+
createdAt: z23.string().datetime()
|
|
1553
|
+
});
|
|
1554
|
+
var approvalRequestPayloadSchema = z23.object({
|
|
1555
|
+
taskId: z23.string().min(1),
|
|
1556
|
+
kind: z23.enum(approvalKindValues),
|
|
1557
|
+
summary: z23.string().min(1),
|
|
1558
|
+
command: z23.string().min(1),
|
|
1559
|
+
cwd: z23.string().min(1),
|
|
1560
|
+
host: z23.string().min(1).optional(),
|
|
1561
|
+
diff: z23.string().optional(),
|
|
1465
1562
|
/** Сколько ждать решения в этом же вызове; 0 — не ждать. Потолок — как у вопросов. */
|
|
1466
|
-
waitSec:
|
|
1563
|
+
waitSec: z23.number().int().min(0).max(600).optional()
|
|
1467
1564
|
});
|
|
1468
|
-
var approvalRequestAckSchema =
|
|
1565
|
+
var approvalRequestAckSchema = z23.object({
|
|
1469
1566
|
approval: approvalSummarySchema,
|
|
1470
1567
|
/** Приходит только при `APPROVED` — одноразовый, привязан к команде и каталогу (§14.4 ТЗ). */
|
|
1471
|
-
oneTimeToken:
|
|
1568
|
+
oneTimeToken: z23.string().min(1).optional()
|
|
1472
1569
|
});
|
|
1473
|
-
var approvalWaitPayloadSchema =
|
|
1474
|
-
approvalId:
|
|
1475
|
-
waitSec:
|
|
1570
|
+
var approvalWaitPayloadSchema = z23.object({
|
|
1571
|
+
approvalId: z23.string().min(1),
|
|
1572
|
+
waitSec: z23.number().int().min(0).max(600)
|
|
1476
1573
|
});
|
|
1477
1574
|
var approvalWaitAckSchema = approvalRequestAckSchema;
|
|
1478
|
-
var approvalDecidedPayloadSchema =
|
|
1479
|
-
approvalId:
|
|
1480
|
-
status:
|
|
1481
|
-
oneTimeToken:
|
|
1482
|
-
});
|
|
1483
|
-
var agentPresenceUiPayloadSchema =
|
|
1484
|
-
projectId:
|
|
1485
|
-
agentId:
|
|
1486
|
-
status:
|
|
1487
|
-
lastSeenAt:
|
|
1488
|
-
currentTaskId:
|
|
1489
|
-
});
|
|
1490
|
-
var taskOpenPrPayloadSchema =
|
|
1491
|
-
taskId:
|
|
1575
|
+
var approvalDecidedPayloadSchema = z23.object({
|
|
1576
|
+
approvalId: z23.string().min(1),
|
|
1577
|
+
status: z23.enum([ApprovalStatus.APPROVED, ApprovalStatus.REJECTED]),
|
|
1578
|
+
oneTimeToken: z23.string().min(1).optional()
|
|
1579
|
+
});
|
|
1580
|
+
var agentPresenceUiPayloadSchema = z23.object({
|
|
1581
|
+
projectId: z23.string().min(1),
|
|
1582
|
+
agentId: z23.string().min(1),
|
|
1583
|
+
status: z23.enum(agentStatusValues),
|
|
1584
|
+
lastSeenAt: z23.string().datetime(),
|
|
1585
|
+
currentTaskId: z23.string().nullable().optional()
|
|
1586
|
+
});
|
|
1587
|
+
var taskOpenPrPayloadSchema = z23.object({
|
|
1588
|
+
taskId: z23.string().min(1),
|
|
1492
1589
|
/** Ветка, которую клиент уже отправил на remote. */
|
|
1493
|
-
branchName:
|
|
1590
|
+
branchName: z23.string().min(1),
|
|
1494
1591
|
/** Rebase на основную ветку не прошёл — PR помечается «conflicts» (§13.1 ТЗ). */
|
|
1495
|
-
conflicted:
|
|
1592
|
+
conflicted: z23.boolean().optional(),
|
|
1496
1593
|
/** Только пути файлов, никогда содержимое (§18 ТЗ). */
|
|
1497
|
-
conflictedFiles:
|
|
1594
|
+
conflictedFiles: z23.array(z23.string().min(1)).max(100).optional()
|
|
1498
1595
|
});
|
|
1499
|
-
var taskOpenPrAckSchema =
|
|
1500
|
-
url:
|
|
1501
|
-
number:
|
|
1596
|
+
var taskOpenPrAckSchema = z23.object({
|
|
1597
|
+
url: z23.string().url(),
|
|
1598
|
+
number: z23.number().int().positive(),
|
|
1502
1599
|
/** `false` — PR уже существовал для этой ветки, повторно не создавали. */
|
|
1503
|
-
created:
|
|
1600
|
+
created: z23.boolean()
|
|
1504
1601
|
});
|
|
1505
1602
|
|
|
1506
1603
|
// ../shared/src/events/ticket.ts
|
|
1507
|
-
import { z as
|
|
1508
|
-
var realtimeTicketPayloadSchema =
|
|
1509
|
-
sub:
|
|
1510
|
-
orgIds:
|
|
1511
|
-
projectIds:
|
|
1512
|
-
iat:
|
|
1513
|
-
exp:
|
|
1514
|
-
jti:
|
|
1604
|
+
import { z as z24 } from "zod";
|
|
1605
|
+
var realtimeTicketPayloadSchema = z24.object({
|
|
1606
|
+
sub: z24.string().min(1),
|
|
1607
|
+
orgIds: z24.array(z24.string().min(1)),
|
|
1608
|
+
projectIds: z24.array(z24.string().min(1)),
|
|
1609
|
+
iat: z24.number().int().positive(),
|
|
1610
|
+
exp: z24.number().int().positive(),
|
|
1611
|
+
jti: z24.string().min(1)
|
|
1515
1612
|
});
|
|
1516
|
-
var roomJoinRequestSchema =
|
|
1517
|
-
room:
|
|
1518
|
-
projectId:
|
|
1613
|
+
var roomJoinRequestSchema = z24.object({
|
|
1614
|
+
room: z24.string().min(1),
|
|
1615
|
+
projectId: z24.string().min(1).optional()
|
|
1519
1616
|
});
|
|
1520
1617
|
|
|
1521
1618
|
// ../shared/src/events/ui-events.ts
|
|
1522
|
-
import { z as
|
|
1619
|
+
import { z as z25 } from "zod";
|
|
1523
1620
|
var taskStatusValues4 = Object.values(TaskStatus);
|
|
1524
|
-
var taskCreatedPayloadSchema =
|
|
1525
|
-
taskId:
|
|
1526
|
-
projectId:
|
|
1527
|
-
orgId:
|
|
1528
|
-
});
|
|
1529
|
-
var taskUpdatedPayloadSchema =
|
|
1530
|
-
taskId:
|
|
1531
|
-
projectId:
|
|
1532
|
-
orgId:
|
|
1621
|
+
var taskCreatedPayloadSchema = z25.object({
|
|
1622
|
+
taskId: z25.string().min(1),
|
|
1623
|
+
projectId: z25.string().min(1),
|
|
1624
|
+
orgId: z25.string().min(1)
|
|
1625
|
+
});
|
|
1626
|
+
var taskUpdatedPayloadSchema = z25.object({
|
|
1627
|
+
taskId: z25.string().min(1),
|
|
1628
|
+
projectId: z25.string().min(1),
|
|
1629
|
+
orgId: z25.string().min(1),
|
|
1533
1630
|
// Необязательный частичный diff — подсказка для оптимистичного мерджа на
|
|
1534
1631
|
// клиенте. Не гарантирует полноты: клиент обязан доверять только REST.
|
|
1535
|
-
patch:
|
|
1632
|
+
patch: z25.record(z25.string(), z25.unknown()).optional()
|
|
1536
1633
|
});
|
|
1537
|
-
var taskDeletedPayloadSchema =
|
|
1538
|
-
taskId:
|
|
1539
|
-
projectId:
|
|
1540
|
-
orgId:
|
|
1634
|
+
var taskDeletedPayloadSchema = z25.object({
|
|
1635
|
+
taskId: z25.string().min(1),
|
|
1636
|
+
projectId: z25.string().min(1),
|
|
1637
|
+
orgId: z25.string().min(1)
|
|
1541
1638
|
});
|
|
1542
|
-
var taskMovedPayloadSchema =
|
|
1543
|
-
taskId:
|
|
1544
|
-
projectId:
|
|
1545
|
-
orgId:
|
|
1639
|
+
var taskMovedPayloadSchema = z25.object({
|
|
1640
|
+
taskId: z25.string().min(1),
|
|
1641
|
+
projectId: z25.string().min(1),
|
|
1642
|
+
orgId: z25.string().min(1),
|
|
1546
1643
|
// Новый статус/позиция — нужны доске (P1-11) для немедленного
|
|
1547
1644
|
// перемещения карточки без ожидания REST-рефетча.
|
|
1548
|
-
status:
|
|
1549
|
-
order:
|
|
1645
|
+
status: z25.enum(taskStatusValues4),
|
|
1646
|
+
order: z25.number()
|
|
1550
1647
|
});
|
|
1551
|
-
var notificationNewPayloadSchema =
|
|
1552
|
-
notificationId:
|
|
1648
|
+
var notificationNewPayloadSchema = z25.object({
|
|
1649
|
+
notificationId: z25.string().min(1),
|
|
1553
1650
|
// userId, не membershipId: `apps/realtime` адресует личную комнату
|
|
1554
1651
|
// `user:{userId}` (см. rooms.ts) — так же, как ticket.sub.
|
|
1555
|
-
userId:
|
|
1556
|
-
kind:
|
|
1557
|
-
title:
|
|
1558
|
-
body:
|
|
1559
|
-
link:
|
|
1560
|
-
});
|
|
1561
|
-
var futurePlaceholderPayloadSchema =
|
|
1562
|
-
projectId:
|
|
1652
|
+
userId: z25.string().min(1),
|
|
1653
|
+
kind: z25.string().min(1),
|
|
1654
|
+
title: z25.string().min(1),
|
|
1655
|
+
body: z25.string().optional(),
|
|
1656
|
+
link: z25.string().optional()
|
|
1657
|
+
});
|
|
1658
|
+
var futurePlaceholderPayloadSchema = z25.object({
|
|
1659
|
+
projectId: z25.string().min(1)
|
|
1563
1660
|
}).loose();
|
|
1564
|
-
var questionEventPayloadSchema =
|
|
1565
|
-
questionId:
|
|
1566
|
-
projectId:
|
|
1567
|
-
orgId:
|
|
1568
|
-
taskId:
|
|
1661
|
+
var questionEventPayloadSchema = z25.object({
|
|
1662
|
+
questionId: z25.string().min(1),
|
|
1663
|
+
projectId: z25.string().min(1),
|
|
1664
|
+
orgId: z25.string().min(1),
|
|
1665
|
+
taskId: z25.string().min(1).nullable().optional(),
|
|
1569
1666
|
/** Кому адресован — роль или конкретный участник; для фильтра «мне» в UI. */
|
|
1570
|
-
targetRole:
|
|
1571
|
-
targetMemberId:
|
|
1572
|
-
blocking:
|
|
1667
|
+
targetRole: z25.string().min(1).nullable().optional(),
|
|
1668
|
+
targetMemberId: z25.string().min(1).nullable().optional(),
|
|
1669
|
+
blocking: z25.boolean().optional()
|
|
1573
1670
|
});
|
|
1574
1671
|
var envelopeExtra = {
|
|
1575
|
-
publishedAt:
|
|
1672
|
+
publishedAt: z25.string().datetime().optional()
|
|
1576
1673
|
};
|
|
1577
|
-
var uiEventEnvelopeSchema =
|
|
1578
|
-
|
|
1579
|
-
event:
|
|
1674
|
+
var uiEventEnvelopeSchema = z25.discriminatedUnion("event", [
|
|
1675
|
+
z25.object({
|
|
1676
|
+
event: z25.literal("task:created"),
|
|
1580
1677
|
payload: taskCreatedPayloadSchema,
|
|
1581
1678
|
...envelopeExtra
|
|
1582
1679
|
}),
|
|
1583
|
-
|
|
1584
|
-
event:
|
|
1680
|
+
z25.object({
|
|
1681
|
+
event: z25.literal("task:updated"),
|
|
1585
1682
|
payload: taskUpdatedPayloadSchema,
|
|
1586
1683
|
...envelopeExtra
|
|
1587
1684
|
}),
|
|
1588
|
-
|
|
1589
|
-
event:
|
|
1685
|
+
z25.object({
|
|
1686
|
+
event: z25.literal("task:deleted"),
|
|
1590
1687
|
payload: taskDeletedPayloadSchema,
|
|
1591
1688
|
...envelopeExtra
|
|
1592
1689
|
}),
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
event:
|
|
1690
|
+
z25.object({ event: z25.literal("task:moved"), payload: taskMovedPayloadSchema, ...envelopeExtra }),
|
|
1691
|
+
z25.object({
|
|
1692
|
+
event: z25.literal("notification:new"),
|
|
1596
1693
|
payload: notificationNewPayloadSchema,
|
|
1597
1694
|
...envelopeExtra
|
|
1598
1695
|
}),
|
|
1599
1696
|
// Заготовки под фазу 2+ (§11.3 ТЗ упоминает `question:*`/`approval:*` как
|
|
1600
1697
|
// группы, а не точные имена — ниже разумное предположение, подлежит
|
|
1601
1698
|
// уточнению, см. «ВОПРОСЫ» в отчёте P1-10).
|
|
1602
|
-
|
|
1603
|
-
event:
|
|
1699
|
+
z25.object({
|
|
1700
|
+
event: z25.literal("agent:presence"),
|
|
1604
1701
|
payload: futurePlaceholderPayloadSchema,
|
|
1605
1702
|
...envelopeExtra
|
|
1606
1703
|
}),
|
|
1607
|
-
|
|
1608
|
-
event:
|
|
1704
|
+
z25.object({
|
|
1705
|
+
event: z25.literal("question:new"),
|
|
1609
1706
|
payload: questionEventPayloadSchema,
|
|
1610
1707
|
...envelopeExtra
|
|
1611
1708
|
}),
|
|
1612
|
-
|
|
1613
|
-
event:
|
|
1709
|
+
z25.object({
|
|
1710
|
+
event: z25.literal("question:answered"),
|
|
1614
1711
|
payload: questionEventPayloadSchema,
|
|
1615
1712
|
...envelopeExtra
|
|
1616
1713
|
}),
|
|
1617
|
-
|
|
1618
|
-
event:
|
|
1714
|
+
z25.object({
|
|
1715
|
+
event: z25.literal("question:dismissed"),
|
|
1619
1716
|
payload: questionEventPayloadSchema,
|
|
1620
1717
|
...envelopeExtra
|
|
1621
1718
|
}),
|
|
1622
|
-
|
|
1623
|
-
event:
|
|
1719
|
+
z25.object({
|
|
1720
|
+
event: z25.literal("approval:requested"),
|
|
1624
1721
|
payload: futurePlaceholderPayloadSchema,
|
|
1625
1722
|
...envelopeExtra
|
|
1626
1723
|
}),
|
|
1627
|
-
|
|
1628
|
-
event:
|
|
1724
|
+
z25.object({
|
|
1725
|
+
event: z25.literal("approval:decided"),
|
|
1629
1726
|
payload: futurePlaceholderPayloadSchema,
|
|
1630
1727
|
...envelopeExtra
|
|
1631
1728
|
}),
|
|
1632
|
-
|
|
1633
|
-
event:
|
|
1729
|
+
z25.object({
|
|
1730
|
+
event: z25.literal("audit:appended"),
|
|
1634
1731
|
payload: futurePlaceholderPayloadSchema,
|
|
1635
1732
|
...envelopeExtra
|
|
1636
1733
|
}),
|
|
1637
|
-
|
|
1734
|
+
z25.object({
|
|
1638
1735
|
// Состояние проекта изменилось (OQ-30). Единственное событие этого
|
|
1639
1736
|
// канала, которое realtime рассылает НЕ только в `/ui`, но и агентам
|
|
1640
1737
|
// проекта: §17 ТЗ обещает «при PAUSED агентам шлётся agent:pause», а
|
|
1641
1738
|
// одностороннего agent:pause на рукопожатии для этого мало — снятие
|
|
1642
1739
|
// паузы до подключённого агента не доходит вовсе. Веб публикует одно
|
|
1643
1740
|
// событие, realtime разводит его по обоим namespace.
|
|
1644
|
-
event:
|
|
1645
|
-
payload:
|
|
1646
|
-
projectId:
|
|
1647
|
-
paused:
|
|
1648
|
-
mode:
|
|
1649
|
-
reason:
|
|
1741
|
+
event: z25.literal("project:state"),
|
|
1742
|
+
payload: z25.object({
|
|
1743
|
+
projectId: z25.string().min(1),
|
|
1744
|
+
paused: z25.boolean(),
|
|
1745
|
+
mode: z25.string().min(1),
|
|
1746
|
+
reason: z25.string().optional()
|
|
1650
1747
|
}),
|
|
1651
1748
|
...envelopeExtra
|
|
1652
1749
|
})
|
|
@@ -1664,14 +1761,14 @@ var PRIORITY_VALUES = new Set(Object.values(Priority));
|
|
|
1664
1761
|
var EXECUTOR_VALUES = new Set(Object.values(Executor));
|
|
1665
1762
|
|
|
1666
1763
|
// ../shared/src/import/types.ts
|
|
1667
|
-
import { z as
|
|
1668
|
-
var ImportTargetStatusSchema =
|
|
1764
|
+
import { z as z26 } from "zod";
|
|
1765
|
+
var ImportTargetStatusSchema = z26.enum([
|
|
1669
1766
|
TaskStatus.BACKLOG,
|
|
1670
1767
|
TaskStatus.READY,
|
|
1671
1768
|
TaskStatus.DONE
|
|
1672
1769
|
]);
|
|
1673
|
-
var ImportRowKeySchema =
|
|
1674
|
-
var ImportTaskInputSchema =
|
|
1770
|
+
var ImportRowKeySchema = z26.string().trim().min(1).max(100);
|
|
1771
|
+
var ImportTaskInputSchema = z26.object({
|
|
1675
1772
|
key: ImportRowKeySchema,
|
|
1676
1773
|
title: TaskTitleSchema,
|
|
1677
1774
|
descriptionMd: TaskDescriptionSchema.default(""),
|
|
@@ -1679,21 +1776,21 @@ var ImportTaskInputSchema = z25.object({
|
|
|
1679
1776
|
priority: TaskPrioritySchema.default(Priority.P2),
|
|
1680
1777
|
executor: TaskExecutorSchema.default(Executor.ANY),
|
|
1681
1778
|
status: ImportTargetStatusSchema.default(TaskStatus.BACKLOG),
|
|
1682
|
-
roleKey:
|
|
1683
|
-
milestoneId:
|
|
1779
|
+
roleKey: z26.string().trim().min(1).max(60).optional(),
|
|
1780
|
+
milestoneId: z26.string().min(1).optional(),
|
|
1684
1781
|
labels: TaskLabelsSchema.default([]),
|
|
1685
1782
|
metadata: TaskMetadataSchema.default({}),
|
|
1686
1783
|
acceptance: TaskAcceptanceSchema.optional(),
|
|
1687
1784
|
estimateMin: TaskEstimateMinSchema.optional(),
|
|
1688
1785
|
parentKey: ImportRowKeySchema.optional()
|
|
1689
1786
|
});
|
|
1690
|
-
var ImportTasksRequestSchema =
|
|
1691
|
-
tasks:
|
|
1787
|
+
var ImportTasksRequestSchema = z26.object({
|
|
1788
|
+
tasks: z26.array(ImportTaskInputSchema).min(1, "\u041D\u0443\u0436\u043D\u0430 \u0445\u043E\u0442\u044F \u0431\u044B \u043E\u0434\u043D\u0430 \u0437\u0430\u0434\u0430\u0447\u0430").max(500, "\u041D\u0435 \u0431\u043E\u043B\u044C\u0448\u0435 500 \u0437\u0430\u0434\u0430\u0447 \u0437\u0430 \u043E\u0434\u0438\u043D \u0438\u043C\u043F\u043E\u0440\u0442")
|
|
1692
1789
|
});
|
|
1693
1790
|
|
|
1694
1791
|
// ../shared/src/settings/org-settings.ts
|
|
1695
|
-
import { z as
|
|
1696
|
-
var OrgSettingsSchema =
|
|
1792
|
+
import { z as z27 } from "zod";
|
|
1793
|
+
var OrgSettingsSchema = z27.object({}).passthrough();
|
|
1697
1794
|
|
|
1698
1795
|
// ../shared/src/task-state.ts
|
|
1699
1796
|
var TASK_TRANSITIONS = [
|
|
@@ -2925,24 +3022,24 @@ function upsertClaudeMdSection(existingContent) {
|
|
|
2925
3022
|
// src/config/claude-settings.ts
|
|
2926
3023
|
import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
2927
3024
|
import { join as join2 } from "path";
|
|
2928
|
-
import { z as
|
|
2929
|
-
var HookCommandEntrySchema =
|
|
2930
|
-
type:
|
|
2931
|
-
command:
|
|
2932
|
-
timeout:
|
|
3025
|
+
import { z as z28 } from "zod";
|
|
3026
|
+
var HookCommandEntrySchema = z28.object({
|
|
3027
|
+
type: z28.literal("command"),
|
|
3028
|
+
command: z28.string().min(1),
|
|
3029
|
+
timeout: z28.number().int().positive().optional()
|
|
2933
3030
|
}).passthrough();
|
|
2934
|
-
var HookMatcherGroupSchema =
|
|
2935
|
-
matcher:
|
|
2936
|
-
hooks:
|
|
3031
|
+
var HookMatcherGroupSchema = z28.object({
|
|
3032
|
+
matcher: z28.string().optional(),
|
|
3033
|
+
hooks: z28.array(HookCommandEntrySchema)
|
|
2937
3034
|
}).passthrough();
|
|
2938
|
-
var McpServerEntrySchema =
|
|
2939
|
-
command:
|
|
2940
|
-
args:
|
|
3035
|
+
var McpServerEntrySchema = z28.object({
|
|
3036
|
+
command: z28.string().min(1),
|
|
3037
|
+
args: z28.array(z28.string()).optional()
|
|
2941
3038
|
}).passthrough();
|
|
2942
|
-
var ClaudeSettingsSchema =
|
|
2943
|
-
mcpServers:
|
|
2944
|
-
hooks:
|
|
2945
|
-
env:
|
|
3039
|
+
var ClaudeSettingsSchema = z28.object({
|
|
3040
|
+
mcpServers: z28.record(z28.string(), McpServerEntrySchema).optional(),
|
|
3041
|
+
hooks: z28.record(z28.string(), z28.array(HookMatcherGroupSchema)).optional(),
|
|
3042
|
+
env: z28.record(z28.string(), z28.string()).optional()
|
|
2946
3043
|
}).passthrough();
|
|
2947
3044
|
var CLAUDE_SETTINGS_RELATIVE_PATH = join2(".claude", "settings.json");
|
|
2948
3045
|
var CLI_BIN = "quiel";
|
|
@@ -3047,13 +3144,13 @@ function clearPendingApproval(state, approvalId) {
|
|
|
3047
3144
|
}
|
|
3048
3145
|
|
|
3049
3146
|
// src/state/schema.ts
|
|
3050
|
-
import { z as
|
|
3147
|
+
import { z as z29 } from "zod";
|
|
3051
3148
|
var STATE_SCHEMA_VERSION = 1;
|
|
3052
|
-
var CurrentTaskSchema =
|
|
3053
|
-
taskId:
|
|
3149
|
+
var CurrentTaskSchema = z29.object({
|
|
3150
|
+
taskId: z29.string().min(1),
|
|
3054
3151
|
/** Человекочитаемый ключ вроде `REL-42` — для текста в хуках. Необязателен: на первых порах может быть неизвестен. */
|
|
3055
|
-
taskKey:
|
|
3056
|
-
resumeToken:
|
|
3152
|
+
taskKey: z29.string().min(1).optional(),
|
|
3153
|
+
resumeToken: z29.string().min(1),
|
|
3057
3154
|
/**
|
|
3058
3155
|
* Каталог, в котором агент работает над этой задачей (`.claude/worktrees/…`).
|
|
3059
3156
|
*
|
|
@@ -3067,7 +3164,7 @@ var CurrentTaskSchema = z28.object({
|
|
|
3067
3164
|
* в чекауте), а у состояний, записанных прежними версиями клиента,
|
|
3068
3165
|
* поля просто нет.
|
|
3069
3166
|
*/
|
|
3070
|
-
worktreeDir:
|
|
3167
|
+
worktreeDir: z29.string().min(1).optional(),
|
|
3071
3168
|
/**
|
|
3072
3169
|
* Git-режим проекта (§13.1 ТЗ) — `DIRECT` или `PR`.
|
|
3073
3170
|
*
|
|
@@ -3081,58 +3178,71 @@ var CurrentTaskSchema = z28.object({
|
|
|
3081
3178
|
* Необязательно: состояния, записанные прежними версиями клиента, поля
|
|
3082
3179
|
* не имеют — тогда `submit_work` работает как раньше, в режиме DIRECT.
|
|
3083
3180
|
*/
|
|
3084
|
-
gitMode:
|
|
3085
|
-
});
|
|
3086
|
-
var TrustCacheSchema =
|
|
3087
|
-
profileKey:
|
|
3088
|
-
updatedAt:
|
|
3089
|
-
rules:
|
|
3090
|
-
bash:
|
|
3091
|
-
mode:
|
|
3092
|
-
stopPatterns:
|
|
3093
|
-
allowPatterns:
|
|
3181
|
+
gitMode: z29.enum([GitMode.DIRECT, GitMode.PR]).optional()
|
|
3182
|
+
});
|
|
3183
|
+
var TrustCacheSchema = z29.object({
|
|
3184
|
+
profileKey: z29.string().min(1),
|
|
3185
|
+
updatedAt: z29.string(),
|
|
3186
|
+
rules: z29.object({
|
|
3187
|
+
bash: z29.object({
|
|
3188
|
+
mode: z29.enum(["allow", "approve", "deny"]),
|
|
3189
|
+
stopPatterns: z29.array(z29.string()).default([]),
|
|
3190
|
+
allowPatterns: z29.array(z29.string()).optional()
|
|
3094
3191
|
}),
|
|
3095
|
-
files:
|
|
3096
|
-
mode:
|
|
3097
|
-
protectedPaths:
|
|
3192
|
+
files: z29.object({
|
|
3193
|
+
mode: z29.enum(["allow", "approve"]),
|
|
3194
|
+
protectedPaths: z29.array(z29.string()).default([])
|
|
3098
3195
|
}).optional(),
|
|
3099
|
-
git:
|
|
3100
|
-
network:
|
|
3101
|
-
approvalTtlMin:
|
|
3196
|
+
git: z29.object({ allowPushDefault: z29.boolean(), allowForcePush: z29.boolean() }).optional(),
|
|
3197
|
+
network: z29.object({ allowSsh: z29.boolean(), sshHostsAllow: z29.array(z29.string()).optional() }).optional(),
|
|
3198
|
+
approvalTtlMin: z29.number().int().positive().optional()
|
|
3102
3199
|
}).passthrough()
|
|
3103
3200
|
}).nullable();
|
|
3104
|
-
var ApprovedCommandSchema =
|
|
3105
|
-
token:
|
|
3106
|
-
command:
|
|
3107
|
-
cwd:
|
|
3108
|
-
expiresAt:
|
|
3109
|
-
createdAt:
|
|
3201
|
+
var ApprovedCommandSchema = z29.object({
|
|
3202
|
+
token: z29.string().min(1),
|
|
3203
|
+
command: z29.string().min(1),
|
|
3204
|
+
cwd: z29.string().min(1),
|
|
3205
|
+
expiresAt: z29.string(),
|
|
3206
|
+
createdAt: z29.string()
|
|
3110
3207
|
});
|
|
3111
|
-
var PendingApprovalSchema =
|
|
3112
|
-
command:
|
|
3113
|
-
cwd:
|
|
3114
|
-
createdAt:
|
|
3208
|
+
var PendingApprovalSchema = z29.object({
|
|
3209
|
+
command: z29.string().min(1),
|
|
3210
|
+
cwd: z29.string().min(1),
|
|
3211
|
+
createdAt: z29.string()
|
|
3115
3212
|
});
|
|
3116
|
-
var AgentModeSchema =
|
|
3213
|
+
var AgentModeSchema = z29.enum([AgentMode.AUTONOMOUS, AgentMode.MANUAL]);
|
|
3117
3214
|
var DEFAULT_CONTEXT_RESET_AFTER_TASKS = ProjectSettingsSchema.parse({}).contextResetAfterTasks;
|
|
3118
|
-
var ClientStateSchema =
|
|
3119
|
-
version:
|
|
3215
|
+
var ClientStateSchema = z29.object({
|
|
3216
|
+
version: z29.literal(STATE_SCHEMA_VERSION).default(STATE_SCHEMA_VERSION),
|
|
3120
3217
|
mode: AgentModeSchema.default(AgentMode.MANUAL),
|
|
3121
3218
|
currentTask: CurrentTaskSchema.nullable().default(null),
|
|
3122
3219
|
/** Счётчик сдач задач в текущей «сессии» (§10.4 ТЗ). Сбрасывается `SessionStart` при `source ∈ {startup, clear}` — см. src/hooks/session-start.ts. */
|
|
3123
|
-
tasksCompletedInSession:
|
|
3220
|
+
tasksCompletedInSession: z29.number().int().nonnegative().default(0),
|
|
3124
3221
|
/** Кэш `ProjectSettings.contextResetAfterTasks` (§7.2 ТЗ) — сколько задач подряд можно сдать, прежде чем `Stop`-хук попросит `/clear`. */
|
|
3125
|
-
contextResetAfterTasks:
|
|
3222
|
+
contextResetAfterTasks: z29.number().int().positive().default(DEFAULT_CONTEXT_RESET_AFTER_TASKS),
|
|
3126
3223
|
/** Кэш стоп-паттернов/правил доверия для `PreToolUse` фазы 4. */
|
|
3127
3224
|
trust: TrustCacheSchema.default(null),
|
|
3128
3225
|
/** Снимок задачи на момент последнего `PreCompact` — пишет src/hooks/pre-compact.ts, читает SessionStart(source="compact"), чтобы напомнить модели, чем она занималась. */
|
|
3129
|
-
lastPreCompact: CurrentTaskSchema.extend({ savedAt:
|
|
3226
|
+
lastPreCompact: CurrentTaskSchema.extend({ savedAt: z29.string() }).nullable().default(null),
|
|
3130
3227
|
/** Кэш одноразовых токенов подтверждения (§14.4 ТЗ), ключ — `hashCommandKey(command, cwd)`. Читает/жжёт `PreToolUse` (`hooks/pre-tool-use.ts`), пишут `request_approval`/`wait_approval` и пуш `approval:decided` (`socket/client.ts`). */
|
|
3131
|
-
approvedCommands:
|
|
3228
|
+
approvedCommands: z29.record(z29.string(), ApprovedCommandSchema).default({}),
|
|
3132
3229
|
/** Незавершённые запросы подтверждения, ключ — `approvalId`. См. `PendingApprovalSchema`. */
|
|
3133
|
-
pendingApprovals:
|
|
3230
|
+
pendingApprovals: z29.record(z29.string(), PendingApprovalSchema).default({}),
|
|
3231
|
+
/**
|
|
3232
|
+
* Сколько байтов транскрипта уже посчитано в расход токенов (вопрос
|
|
3233
|
+
* владельца 18.09.2026).
|
|
3234
|
+
*
|
|
3235
|
+
* Ключ — путь к файлу транскрипта: у сессии он свой, а `/clear` заводит
|
|
3236
|
+
* новый. Значение — смещение в БАЙТАХ, не в символах: кириллица в
|
|
3237
|
+
* транскрипте обычное дело.
|
|
3238
|
+
*
|
|
3239
|
+
* Без этого смещения каждый ход агента пересчитывал бы файл с начала, и
|
|
3240
|
+
* расход задачи рос бы квадратично — по числам это выглядело бы как
|
|
3241
|
+
* «агент потратил в сто раз больше», и проверить было бы нечем.
|
|
3242
|
+
*/
|
|
3243
|
+
usageOffsets: z29.record(z29.string(), z29.number().int().nonnegative()).default({}),
|
|
3134
3244
|
/** Штамп последней записи файла — выставляется в state/store.ts при каждом `writeState`. */
|
|
3135
|
-
updatedAt:
|
|
3245
|
+
updatedAt: z29.string().default(() => (/* @__PURE__ */ new Date()).toISOString())
|
|
3136
3246
|
});
|
|
3137
3247
|
function createDefaultState() {
|
|
3138
3248
|
return ClientStateSchema.parse({});
|
|
@@ -3184,18 +3294,18 @@ function updateState(patch, filePath = getStateFilePath()) {
|
|
|
3184
3294
|
}
|
|
3185
3295
|
|
|
3186
3296
|
// src/config/schema.ts
|
|
3187
|
-
import { z as
|
|
3297
|
+
import { z as z30 } from "zod";
|
|
3188
3298
|
var PROJECT_CONFIG_SCHEMA_VERSION = 1;
|
|
3189
|
-
var ProjectConfigSchema =
|
|
3190
|
-
version:
|
|
3299
|
+
var ProjectConfigSchema = z30.object({
|
|
3300
|
+
version: z30.literal(PROJECT_CONFIG_SCHEMA_VERSION).default(PROJECT_CONFIG_SCHEMA_VERSION),
|
|
3191
3301
|
/** URL платформы (§10.1 ТЗ), например `https://quiel.example.com`. */
|
|
3192
|
-
url:
|
|
3302
|
+
url: z30.string().trim().url("\u041D\u0443\u0436\u0435\u043D \u043F\u043E\u043B\u043D\u044B\u0439 URL, \u043D\u0430\u043F\u0440\u0438\u043C\u0435\u0440 https://quiel.example.com"),
|
|
3193
3303
|
/** Ключ проекта на платформе (OQ-11), например `REL`. */
|
|
3194
|
-
projectKey:
|
|
3304
|
+
projectKey: z30.string().trim().min(1, "\u041A\u043B\u044E\u0447 \u043F\u0440\u043E\u0435\u043A\u0442\u0430 \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u0435\u043D"),
|
|
3195
3305
|
/** Идентификатор агента — см. комментарий выше. */
|
|
3196
|
-
agentId:
|
|
3306
|
+
agentId: z30.string().trim().min(1, "ID \u0430\u0433\u0435\u043D\u0442\u0430 \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u0435\u043D"),
|
|
3197
3307
|
/** Человекочитаемое имя агента (§7.4 ТЗ: «odya-macbook») — необязательно, только для локального отображения. */
|
|
3198
|
-
agentName:
|
|
3308
|
+
agentName: z30.string().trim().min(1).optional(),
|
|
3199
3309
|
/** Роли, с которыми агент забирает задачи — подмножество ролей участника (§7.4 ТЗ). */
|
|
3200
3310
|
roleKeys: AgentRoleKeysSchema,
|
|
3201
3311
|
/**
|
|
@@ -3228,19 +3338,19 @@ var ProjectConfigSchema = z29.object({
|
|
|
3228
3338
|
* абсолютный путь вроде `/Users/odya/...` у коллеги на другой машине
|
|
3229
3339
|
* оказался бы битым. Режим переносим — это соглашение проекта.
|
|
3230
3340
|
*/
|
|
3231
|
-
worktrees:
|
|
3341
|
+
worktrees: z30.enum(["isolated", "checkout"]).default("isolated")
|
|
3232
3342
|
});
|
|
3233
|
-
var CredentialsEntrySchema =
|
|
3234
|
-
url:
|
|
3235
|
-
token:
|
|
3236
|
-
projectKey:
|
|
3343
|
+
var CredentialsEntrySchema = z30.object({
|
|
3344
|
+
url: z30.string().trim().url(),
|
|
3345
|
+
token: z30.string().min(1),
|
|
3346
|
+
projectKey: z30.string().min(1),
|
|
3237
3347
|
/** Когда записали — для диагностики (`quiel status`), не для логики. */
|
|
3238
|
-
savedAt:
|
|
3348
|
+
savedAt: z30.string()
|
|
3239
3349
|
});
|
|
3240
3350
|
var CREDENTIALS_SCHEMA_VERSION = 1;
|
|
3241
|
-
var CredentialsFileSchema =
|
|
3242
|
-
version:
|
|
3243
|
-
agents:
|
|
3351
|
+
var CredentialsFileSchema = z30.object({
|
|
3352
|
+
version: z30.literal(CREDENTIALS_SCHEMA_VERSION).default(CREDENTIALS_SCHEMA_VERSION),
|
|
3353
|
+
agents: z30.record(z30.string(), CredentialsEntrySchema).default({})
|
|
3244
3354
|
});
|
|
3245
3355
|
function createEmptyCredentialsFile() {
|
|
3246
3356
|
return CredentialsFileSchema.parse({});
|
|
@@ -3321,13 +3431,13 @@ function ensureWorktreesIgnored(dir) {
|
|
|
3321
3431
|
// src/config/mcp-json.ts
|
|
3322
3432
|
import { existsSync as existsSync6, readFileSync as readFileSync6, writeFileSync as writeFileSync6 } from "fs";
|
|
3323
3433
|
import { join as join6 } from "path";
|
|
3324
|
-
import { z as
|
|
3325
|
-
var McpServerEntrySchema2 =
|
|
3326
|
-
command:
|
|
3327
|
-
args:
|
|
3434
|
+
import { z as z31 } from "zod";
|
|
3435
|
+
var McpServerEntrySchema2 = z31.object({
|
|
3436
|
+
command: z31.string().min(1).optional(),
|
|
3437
|
+
args: z31.array(z31.string()).optional()
|
|
3328
3438
|
}).passthrough();
|
|
3329
|
-
var McpJsonSchema =
|
|
3330
|
-
mcpServers:
|
|
3439
|
+
var McpJsonSchema = z31.object({
|
|
3440
|
+
mcpServers: z31.record(z31.string(), McpServerEntrySchema2).optional()
|
|
3331
3441
|
}).passthrough();
|
|
3332
3442
|
var MCP_JSON_RELATIVE_PATH = ".mcp.json";
|
|
3333
3443
|
function mergeQuielMcpJson(existing) {
|
|
@@ -3516,11 +3626,11 @@ var claudeCodeInstaller = {
|
|
|
3516
3626
|
};
|
|
3517
3627
|
|
|
3518
3628
|
// src/agents/codex.ts
|
|
3519
|
-
import { z as
|
|
3629
|
+
import { z as z32 } from "zod";
|
|
3520
3630
|
var CODEX_HOOKS_PATH = ".codex/hooks.json";
|
|
3521
3631
|
var CODEX_CONFIG_PATH = ".codex/config.toml";
|
|
3522
|
-
var CodexHooksFileSchema =
|
|
3523
|
-
hooks:
|
|
3632
|
+
var CodexHooksFileSchema = z32.object({
|
|
3633
|
+
hooks: z32.record(z32.string(), z32.array(z32.object({}).passthrough())).optional()
|
|
3524
3634
|
}).passthrough();
|
|
3525
3635
|
function mcpServerTable() {
|
|
3526
3636
|
return [
|
|
@@ -3570,16 +3680,16 @@ var codexInstaller = {
|
|
|
3570
3680
|
};
|
|
3571
3681
|
|
|
3572
3682
|
// src/agents/cursor.ts
|
|
3573
|
-
import { z as
|
|
3683
|
+
import { z as z33 } from "zod";
|
|
3574
3684
|
var CURSOR_HOOKS_PATH = ".cursor/hooks.json";
|
|
3575
3685
|
var CURSOR_MCP_PATH = ".cursor/mcp.json";
|
|
3576
|
-
var CursorHookEntrySchema =
|
|
3577
|
-
var CursorHooksFileSchema =
|
|
3578
|
-
version:
|
|
3579
|
-
hooks:
|
|
3686
|
+
var CursorHookEntrySchema = z33.object({ command: z33.string().min(1) }).passthrough();
|
|
3687
|
+
var CursorHooksFileSchema = z33.object({
|
|
3688
|
+
version: z33.number().optional(),
|
|
3689
|
+
hooks: z33.record(z33.string(), z33.array(CursorHookEntrySchema)).optional()
|
|
3580
3690
|
}).passthrough();
|
|
3581
|
-
var CursorMcpFileSchema =
|
|
3582
|
-
mcpServers:
|
|
3691
|
+
var CursorMcpFileSchema = z33.object({
|
|
3692
|
+
mcpServers: z33.record(z33.string(), z33.object({}).passthrough()).optional()
|
|
3583
3693
|
}).passthrough();
|
|
3584
3694
|
var CURSOR_HOOKS = {
|
|
3585
3695
|
sessionStart: `${CLI_BIN} hook session-start --format cursor`,
|
|
@@ -3643,7 +3753,7 @@ var cursorInstaller = {
|
|
|
3643
3753
|
};
|
|
3644
3754
|
|
|
3645
3755
|
// src/agents/opencode.ts
|
|
3646
|
-
import { z as
|
|
3756
|
+
import { z as z34 } from "zod";
|
|
3647
3757
|
|
|
3648
3758
|
// src/agents/opencode-plugin.ts
|
|
3649
3759
|
var OPENCODE_PLUGIN_FILENAME = "quiel.js";
|
|
@@ -3693,9 +3803,9 @@ export const QuielPlugin = async ({ directory }) => {
|
|
|
3693
3803
|
// src/agents/opencode.ts
|
|
3694
3804
|
var OPENCODE_CONFIG_PATH = "opencode.json";
|
|
3695
3805
|
var OPENCODE_SCHEMA_URL = "https://opencode.ai/config.json";
|
|
3696
|
-
var OpencodeConfigSchema =
|
|
3697
|
-
$schema:
|
|
3698
|
-
mcp:
|
|
3806
|
+
var OpencodeConfigSchema = z34.object({
|
|
3807
|
+
$schema: z34.string().optional(),
|
|
3808
|
+
mcp: z34.record(z34.string(), z34.object({}).passthrough()).optional()
|
|
3699
3809
|
}).passthrough();
|
|
3700
3810
|
var opencodeInstaller = {
|
|
3701
3811
|
kind: AgentKind.OPENCODE,
|
|
@@ -3820,10 +3930,11 @@ var createSocket = (url, options) => io(url, {
|
|
|
3820
3930
|
// src/hooks/audit-sender.ts
|
|
3821
3931
|
var DEFAULT_CONNECT_TIMEOUT_MS = 3e3;
|
|
3822
3932
|
var DEFAULT_FLUSH_GRACE_MS = 150;
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
|
|
3933
|
+
var WIRE_EVENTS = /* @__PURE__ */ new Set(["audit:command", "task:usage"]);
|
|
3934
|
+
function sendHookActions(actions, options = {}) {
|
|
3935
|
+
const wireActions = actions.filter((action) => WIRE_EVENTS.has(action.type));
|
|
3936
|
+
if (wireActions.length === 0) return;
|
|
3937
|
+
void dispatch(wireActions, options).catch(() => {
|
|
3827
3938
|
});
|
|
3828
3939
|
}
|
|
3829
3940
|
async function dispatch(actions, options) {
|
|
@@ -3838,7 +3949,7 @@ async function dispatch(actions, options) {
|
|
|
3838
3949
|
});
|
|
3839
3950
|
try {
|
|
3840
3951
|
await connectOnce(socket, options.connectTimeoutMs ?? DEFAULT_CONNECT_TIMEOUT_MS);
|
|
3841
|
-
for (const action of actions) socket.emit(
|
|
3952
|
+
for (const action of actions) socket.emit(action.type, action.payload);
|
|
3842
3953
|
await sleep(options.flushGraceMs ?? DEFAULT_FLUSH_GRACE_MS);
|
|
3843
3954
|
} finally {
|
|
3844
3955
|
socket.disconnect();
|
|
@@ -3855,7 +3966,7 @@ function trimTrailingSlash(url) {
|
|
|
3855
3966
|
}
|
|
3856
3967
|
|
|
3857
3968
|
// src/hooks/format.ts
|
|
3858
|
-
import { z as
|
|
3969
|
+
import { z as z35 } from "zod";
|
|
3859
3970
|
var HOOK_FORMATS = ["claude", "cursor", "opencode"];
|
|
3860
3971
|
function asHookFormat(raw) {
|
|
3861
3972
|
const value = raw.trim().toLowerCase();
|
|
@@ -3868,18 +3979,18 @@ var CLAUDE_EVENT = {
|
|
|
3868
3979
|
"pre-tool-use": "PreToolUse",
|
|
3869
3980
|
"pre-compact": "PreCompact"
|
|
3870
3981
|
};
|
|
3871
|
-
var CursorShellInputSchema =
|
|
3872
|
-
var CursorStopInputSchema =
|
|
3982
|
+
var CursorShellInputSchema = z35.object({ command: z35.string(), cwd: z35.string().optional() }).passthrough();
|
|
3983
|
+
var CursorStopInputSchema = z35.object({ status: z35.string().optional(), loop_count: z35.number().optional() }).passthrough();
|
|
3873
3984
|
function cursorPermission(decision) {
|
|
3874
3985
|
if (decision === "deny") return "deny";
|
|
3875
3986
|
if (decision === "allow") return "allow";
|
|
3876
3987
|
return "ask";
|
|
3877
3988
|
}
|
|
3878
|
-
var OpencodePayloadSchema =
|
|
3879
|
-
directory:
|
|
3880
|
-
input:
|
|
3881
|
-
output:
|
|
3882
|
-
event:
|
|
3989
|
+
var OpencodePayloadSchema = z35.object({
|
|
3990
|
+
directory: z35.string().optional(),
|
|
3991
|
+
input: z35.object({ tool: z35.string().optional() }).passthrough().optional(),
|
|
3992
|
+
output: z35.object({ args: z35.record(z35.string(), z35.unknown()).optional() }).passthrough().optional(),
|
|
3993
|
+
event: z35.object({ type: z35.string().optional() }).passthrough().optional()
|
|
3883
3994
|
}).passthrough();
|
|
3884
3995
|
var OPENCODE_TOOLS = {
|
|
3885
3996
|
bash: { name: "Bash", arg: "command", field: "command" },
|
|
@@ -4581,6 +4692,9 @@ var askHumanInputShape = {
|
|
|
4581
4692
|
targetMemberId: questionAskPayloadSchema.shape.targetMemberId.describe(
|
|
4582
4693
|
"ID \u043A\u043E\u043D\u043A\u0440\u0435\u0442\u043D\u043E\u0433\u043E \u0443\u0447\u0430\u0441\u0442\u043D\u0438\u043A\u0430 \u043F\u0440\u043E\u0435\u043A\u0442\u0430 \u2014 \u0430\u0434\u0440\u0435\u0441\u0430\u0442 \u0432\u043E\u043F\u0440\u043E\u0441\u0430. \u041D\u0443\u0436\u0435\u043D \u0420\u041E\u0412\u041D\u041E \u041E\u0414\u0418\u041D \u0430\u0434\u0440\u0435\u0441\u0430\u0442: targetRole \u0418\u041B\u0418 targetMemberId, \u043D\u0435 \u043E\u0431\u0430 \u0441\u0440\u0430\u0437\u0443 \u0438 \u043D\u0435 \u043D\u0438 \u043E\u0434\u043D\u043E\u0433\u043E."
|
|
4583
4694
|
),
|
|
4695
|
+
wantsFiles: questionAskPayloadSchema.shape.wantsFiles.describe(
|
|
4696
|
+
"\u041F\u043E\u043F\u0440\u043E\u0441\u0438\u0442\u044C \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0430 \u043F\u0440\u0438\u043B\u043E\u0436\u0438\u0442\u044C \u0444\u0430\u0439\u043B \u043A \u043E\u0442\u0432\u0435\u0442\u0443 (\u0441\u043A\u0440\u0438\u043D\u0448\u043E\u0442, \u043B\u043E\u0433, \u0432\u044B\u0433\u0440\u0443\u0437\u043A\u0443). \u0424\u043E\u0440\u043C\u0430 \u043E\u0442\u0432\u0435\u0442\u0430 \u043E\u0442\u043A\u0440\u043E\u0435\u0442\u0441\u044F \u0441\u0440\u0430\u0437\u0443 \u0441 \u0432\u044B\u0431\u043E\u0440\u043E\u043C \u0444\u0430\u0439\u043B\u0430. \u042D\u0442\u043E \u041F\u0420\u041E\u0421\u042C\u0411\u0410, \u0430 \u043D\u0435 \u0442\u0440\u0435\u0431\u043E\u0432\u0430\u043D\u0438\u0435: \u0447\u0435\u043B\u043E\u0432\u0435\u043A \u0432\u043F\u0440\u0430\u0432\u0435 \u043E\u0442\u0432\u0435\u0442\u0438\u0442\u044C \u0431\u0435\u0437 \u0444\u0430\u0439\u043B\u043E\u0432, \u0438 \u0442\u043E\u0433\u0434\u0430 `attachments` \u0432 \u043E\u0442\u0432\u0435\u0442\u0435 \u0431\u0443\u0434\u0435\u0442 \u043F\u0443\u0441\u0442\u044B\u043C."
|
|
4697
|
+
),
|
|
4584
4698
|
options: questionAskPayloadSchema.shape.options.describe(
|
|
4585
4699
|
"\u0412\u0430\u0440\u0438\u0430\u043D\u0442\u044B \u043E\u0442\u0432\u0435\u0442\u0430 (\u043F\u043E\u043A\u0430\u0436\u0443\u0442\u0441\u044F \u043A\u043D\u043E\u043F\u043A\u0430\u043C\u0438 \u0432 UI/Telegram). \u041D\u0435 \u043F\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0439 \u2014 \u0447\u0435\u043B\u043E\u0432\u0435\u043A \u043E\u0442\u0432\u0435\u0442\u0438\u0442 \u0441\u0432\u043E\u0431\u043E\u0434\u043D\u044B\u043C \u0442\u0435\u043A\u0441\u0442\u043E\u043C."
|
|
4586
4700
|
),
|
|
@@ -4600,6 +4714,7 @@ async function askHumanHandler(args, runtime) {
|
|
|
4600
4714
|
...args.targetRole ? { targetRole: args.targetRole } : {},
|
|
4601
4715
|
...args.targetMemberId ? { targetMemberId: args.targetMemberId } : {},
|
|
4602
4716
|
...args.options && args.options.length > 0 ? { options: args.options } : {},
|
|
4717
|
+
...args.wantsFiles ? { wantsFiles: true } : {},
|
|
4603
4718
|
blocking: args.blocking,
|
|
4604
4719
|
waitSec
|
|
4605
4720
|
});
|
|
@@ -4656,10 +4771,20 @@ async function waitAnswerHandler(args, runtime) {
|
|
|
4656
4771
|
`\u0412\u043E\u043F\u0440\u043E\u0441 ${result.data.question.id} \u0432\u0441\u0451 \u0435\u0449\u0451 \u0431\u0435\u0437 \u043E\u0442\u0432\u0435\u0442\u0430 (\u0436\u0434\u0430\u043B ${waitSec} \u0441). \u0412\u044B\u0437\u043E\u0432\u0438 wait_answer \u0435\u0449\u0451 \u0440\u0430\u0437 \u0441 \u0442\u0435\u043C \u0436\u0435 questionId, \u043A\u043E\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u0443\u043C\u0435\u0441\u0442\u043D\u043E.`
|
|
4657
4772
|
);
|
|
4658
4773
|
}
|
|
4774
|
+
function describeAnswerAttachments(question) {
|
|
4775
|
+
if (question.attachments.length === 0) return "";
|
|
4776
|
+
const lines = question.attachments.map(
|
|
4777
|
+
(file) => file.downloadUrl ? `- ${file.fileName} (${file.mimeType}) \u2014 \u0441\u043A\u0430\u0447\u0430\u0439: ${file.downloadUrl}` : `- ${file.fileName} (${file.mimeType}) \u2014 \u0441\u0441\u044B\u043B\u043A\u0430 \u043D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u043D\u0430, \u0445\u0440\u0430\u043D\u0438\u043B\u0438\u0449\u0435 \u043D\u0435 \u043E\u0442\u0432\u0435\u0447\u0430\u0435\u0442`
|
|
4778
|
+
);
|
|
4779
|
+
return `
|
|
4780
|
+
|
|
4781
|
+
\u041A \u043E\u0442\u0432\u0435\u0442\u0443 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u044B \u0444\u0430\u0439\u043B\u044B (${question.attachments.length}). \u042D\u0442\u043E \u0447\u0430\u0441\u0442\u044C \u043E\u0442\u0432\u0435\u0442\u0430: \u0441\u043A\u0430\u0447\u0430\u0439 \u0438 \u043F\u0440\u043E\u0447\u0438\u0442\u0430\u0439 \u041A\u0410\u0416\u0414\u042B\u0419, \u0441\u0441\u044B\u043B\u043A\u0438 \u0436\u0438\u0432\u0443\u0442 ${question.attachments[0]?.expiresInSeconds ?? 300} \u0441 \u2014 \u043D\u0435 \u043E\u0442\u043A\u043B\u0430\u0434\u044B\u0432\u0430\u0439.
|
|
4782
|
+
` + lines.join("\n");
|
|
4783
|
+
}
|
|
4659
4784
|
function describeSettledQuestion(question) {
|
|
4660
4785
|
if (question.status === QuestionStatus.ANSWERED) {
|
|
4661
4786
|
return `\u0412\u043E\u043F\u0440\u043E\u0441 ${question.id} \u043F\u043E\u043B\u0443\u0447\u0438\u043B \u043E\u0442\u0432\u0435\u0442:
|
|
4662
|
-
${question.answerMd ?? ""}`;
|
|
4787
|
+
${question.answerMd ?? ""}${describeAnswerAttachments(question)}`;
|
|
4663
4788
|
}
|
|
4664
4789
|
if (question.status === QuestionStatus.DISMISSED) {
|
|
4665
4790
|
return `\u0412\u043E\u043F\u0440\u043E\u0441 ${question.id} \u043E\u0442\u043A\u043B\u043E\u043D\u0451\u043D (DISMISSED) \u2014 \u043E\u0442\u0432\u0435\u0442\u0430 \u043D\u0435 \u0431\u0443\u0434\u0435\u0442. \u0420\u0435\u0448\u0438, \u043A\u0430\u043A \u0434\u0435\u0439\u0441\u0442\u0432\u043E\u0432\u0430\u0442\u044C \u0434\u0430\u043B\u044C\u0448\u0435, \u0441\u0430\u043C, \u0438\u043B\u0438 \u0437\u0430\u0434\u0430\u0439 \u0432\u043E\u043F\u0440\u043E\u0441 \u0437\u0430\u043D\u043E\u0432\u043E.`;
|
|
@@ -4670,15 +4795,15 @@ ${question.answerMd ?? ""}`;
|
|
|
4670
4795
|
// package.json
|
|
4671
4796
|
var package_default = {
|
|
4672
4797
|
name: "@quiel/cli",
|
|
4673
|
-
version: "0.
|
|
4798
|
+
version: "0.5.0",
|
|
4674
4799
|
description: "CLI \u0438 MCP-\u0441\u0435\u0440\u0432\u0435\u0440 Quiel: \u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0430\u0435\u0442 \u0430\u0433\u0435\u043D\u0442\u0430 \u0443\u0447\u0430\u0441\u0442\u043D\u0438\u043A\u0430 (Claude Code, Codex, Cursor, OpenCode) \u043A \u043F\u043B\u0430\u0442\u0444\u043E\u0440\u043C\u0435",
|
|
4675
|
-
homepage: "https://quiel.
|
|
4800
|
+
homepage: "https://quiel.app",
|
|
4676
4801
|
repository: {
|
|
4677
4802
|
type: "git",
|
|
4678
|
-
url: "git+https://github.com/Quiel-
|
|
4803
|
+
url: "git+https://github.com/Quiel-App/quiel-cli.git"
|
|
4679
4804
|
},
|
|
4680
4805
|
bugs: {
|
|
4681
|
-
url: "https://github.com/Quiel-
|
|
4806
|
+
url: "https://github.com/Quiel-App/quiel-cli/issues"
|
|
4682
4807
|
},
|
|
4683
4808
|
keywords: [
|
|
4684
4809
|
"quiel",
|
|
@@ -4698,8 +4823,7 @@ var package_default = {
|
|
|
4698
4823
|
},
|
|
4699
4824
|
files: [
|
|
4700
4825
|
"dist",
|
|
4701
|
-
"README.md"
|
|
4702
|
-
"README.ru.md"
|
|
4826
|
+
"README.md"
|
|
4703
4827
|
],
|
|
4704
4828
|
engines: {
|
|
4705
4829
|
node: ">=22"
|
|
@@ -5640,7 +5764,7 @@ async function settleApproval(ack, commandCwd, runtime, waitSecUsed) {
|
|
|
5640
5764
|
}
|
|
5641
5765
|
|
|
5642
5766
|
// src/mcp/set-mode.ts
|
|
5643
|
-
import { z as
|
|
5767
|
+
import { z as z36 } from "zod";
|
|
5644
5768
|
|
|
5645
5769
|
// src/cli/mode.ts
|
|
5646
5770
|
function parseModeArg(raw) {
|
|
@@ -5681,7 +5805,7 @@ async function requestModeChange(modeArg, options = {}) {
|
|
|
5681
5805
|
|
|
5682
5806
|
// src/mcp/set-mode.ts
|
|
5683
5807
|
var setModeInputShape = {
|
|
5684
|
-
mode:
|
|
5808
|
+
mode: z36.enum(["auto", "manual"]).describe("auto \u2014 \u0432\u043A\u043B\u044E\u0447\u0438\u0442\u044C \u0430\u0432\u0442\u043E\u043D\u043E\u043C\u043D\u044B\u0439 \u0440\u0435\u0436\u0438\u043C \u0430\u0433\u0435\u043D\u0442\u0430, manual \u2014 \u0432\u044B\u043A\u043B\u044E\u0447\u0438\u0442\u044C (\xA710.2 \u0422\u0417)")
|
|
5685
5809
|
};
|
|
5686
5810
|
async function setModeHandler(args, runtime) {
|
|
5687
5811
|
const result = await requestModeChange(args.mode, {
|
|
@@ -5696,20 +5820,20 @@ async function setModeHandler(args, runtime) {
|
|
|
5696
5820
|
}
|
|
5697
5821
|
|
|
5698
5822
|
// src/mcp/submit-work.ts
|
|
5699
|
-
import { z as
|
|
5823
|
+
import { z as z37 } from "zod";
|
|
5700
5824
|
var submitWorkInputShape = {
|
|
5701
|
-
branchName:
|
|
5825
|
+
branchName: z37.string().min(1).describe(
|
|
5702
5826
|
"\u0418\u043C\u044F \u0432\u0435\u0442\u043A\u0438 \u0437\u0430\u0434\u0430\u0447\u0438 \u2014 \u0431\u0435\u0440\u0438 \u0440\u043E\u0432\u043D\u043E \u0438\u0437 project.branchName \u0432 TaskPayload, \u043A\u043E\u0442\u043E\u0440\u044B\u0439 \u0432\u0435\u0440\u043D\u0443\u043B next_task. \u041D\u0435 \u043F\u0440\u0438\u0434\u0443\u043C\u044B\u0432\u0430\u0439 \u0441\u0432\u043E\u0451."
|
|
5703
5827
|
),
|
|
5704
|
-
defaultBranch:
|
|
5705
|
-
commitPrefix:
|
|
5706
|
-
taskKey:
|
|
5707
|
-
taskTitle:
|
|
5708
|
-
repoRoot:
|
|
5709
|
-
testsPassed:
|
|
5828
|
+
defaultBranch: z37.string().min(1).describe("\u041E\u0441\u043D\u043E\u0432\u043D\u0430\u044F \u0432\u0435\u0442\u043A\u0430 \u0440\u0435\u043F\u043E\u0437\u0438\u0442\u043E\u0440\u0438\u044F \u2014 \u0438\u0437 project.repos[].defaultBranch."),
|
|
5829
|
+
commitPrefix: z37.string().min(1).describe('\u041F\u0440\u0435\u0444\u0438\u043A\u0441 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F \u043A\u043E\u043C\u043C\u0438\u0442\u0430 \u2014 \u0438\u0437 project.commitPrefix, \u043D\u0430\u043F\u0440\u0438\u043C\u0435\u0440 "ATL-42:".'),
|
|
5830
|
+
taskKey: z37.string().min(1).describe("\u041A\u043B\u044E\u0447 \u0437\u0430\u0434\u0430\u0447\u0438, \u043D\u0430\u043F\u0440\u0438\u043C\u0435\u0440 ATL-42 \u2014 \u0438\u0437 task.key."),
|
|
5831
|
+
taskTitle: z37.string().min(1).describe("\u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A \u0437\u0430\u0434\u0430\u0447\u0438 \u2014 \u0438\u0437 task.title."),
|
|
5832
|
+
repoRoot: z37.string().min(1).optional().describe("\u041A\u043E\u0440\u0435\u043D\u044C git-\u0440\u0435\u043F\u043E\u0437\u0438\u0442\u043E\u0440\u0438\u044F. \u041F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E \u2014 \u0440\u0430\u0431\u043E\u0447\u0438\u0439 \u043A\u0430\u0442\u0430\u043B\u043E\u0433 \u043F\u0440\u043E\u0435\u043A\u0442\u0430."),
|
|
5833
|
+
testsPassed: z37.boolean().optional().describe(
|
|
5710
5834
|
"\u041F\u0440\u043E\u0448\u043B\u0438 \u043B\u0438 \u0442\u0435\u0441\u0442\u044B. \u0415\u0441\u043B\u0438 \u043F\u0440\u043E\u0435\u043A\u0442 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0437\u0435\u043B\u0451\u043D\u044B\u0445 \u0442\u0435\u0441\u0442\u043E\u0432, \u0430 \u0437\u0434\u0435\u0441\u044C false \u2014 \u0441\u0434\u0430\u0447\u0430 \u043D\u0435 \u0441\u043E\u0441\u0442\u043E\u0438\u0442\u0441\u044F, \u0438 \u044D\u0442\u043E \u043F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u043E."
|
|
5711
5835
|
),
|
|
5712
|
-
requireTestsPassed:
|
|
5836
|
+
requireTestsPassed: z37.boolean().optional().describe("ProjectSettings.requireTests \u043F\u0440\u043E\u0435\u043A\u0442\u0430 \u2014 \u0438\u0437 \u043A\u043E\u043D\u0442\u0435\u043A\u0441\u0442\u0430 \u0437\u0430\u0434\u0430\u0447\u0438.")
|
|
5713
5837
|
};
|
|
5714
5838
|
async function submitWorkHandler(args, runtime) {
|
|
5715
5839
|
const state = readState(runtime.stateFilePath);
|
|
@@ -5944,6 +6068,7 @@ ${JSON.stringify(result.data.task, null, 2)}`
|
|
|
5944
6068
|
}
|
|
5945
6069
|
|
|
5946
6070
|
// src/mcp/register-tools.ts
|
|
6071
|
+
var ATTACHMENTS_HINT = "\u0412\u0410\u0416\u041D\u041E: \u0443 \u0437\u0430\u0434\u0430\u0447\u0438 \u043C\u043E\u0436\u0435\u0442 \u0431\u044B\u0442\u044C \u043F\u043E\u043B\u0435 `attachments` \u2014 \u0444\u0430\u0439\u043B\u044B, \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u043D\u044B\u0435 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u043E\u043C \u043A \u043F\u043E\u0441\u0442\u0430\u043D\u043E\u0432\u043A\u0435 (\u043C\u0430\u043A\u0435\u0442, \u043B\u043E\u0433, \u0432\u044B\u0433\u0440\u0443\u0437\u043A\u0430). \u042D\u0442\u043E \u0427\u0410\u0421\u0422\u042C \u0417\u0410\u0414\u0410\u041D\u0418\u042F, \u0430 \u043D\u0435 \u0443\u043A\u0440\u0430\u0448\u0435\u043D\u0438\u0435: \u0441\u043A\u0430\u0447\u0430\u0439 \u043A\u0430\u0436\u0434\u044B\u0439 \u043F\u043E `downloadUrl` \u0438 \u043F\u0440\u043E\u0447\u0438\u0442\u0430\u0439 \u041F\u0415\u0420\u0415\u0414 \u0440\u0430\u0431\u043E\u0442\u043E\u0439. \u0421\u0441\u044B\u043B\u043A\u0430 \u0436\u0438\u0432\u0451\u0442 `expiresInSeconds` \u0441\u0435\u043A\u0443\u043D\u0434 \u2014 \u0441\u043A\u0430\u0447\u0438\u0432\u0430\u0439 \u0441\u0440\u0430\u0437\u0443, \u0430 \u043D\u0435 \u043E\u0442\u043A\u043B\u0430\u0434\u044B\u0432\u0430\u0439. \u041F\u0443\u0441\u0442\u0430\u044F `downloadUrl` \u043E\u0437\u043D\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043E \u0445\u0440\u0430\u043D\u0438\u043B\u0438\u0449\u0435 \u043D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u043D\u043E: \u0442\u043E\u0433\u0434\u0430 \u0441\u043F\u0440\u043E\u0441\u0438 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0430 \u0447\u0435\u0440\u0435\u0437 `ask_human`, \u0430 \u043D\u0435 \u0440\u0430\u0431\u043E\u0442\u0430\u0439 \u0431\u0435\u0437 \u043C\u0430\u0442\u0435\u0440\u0438\u0430\u043B\u043E\u0432. \u041F\u0443\u0441\u0442\u043E\u0439 \u0441\u043F\u0438\u0441\u043E\u043A `attachments` \u2014 \u043D\u043E\u0440\u043C\u0430\u043B\u044C\u043D\u043E, \u0444\u0430\u0439\u043B\u043E\u0432 \u043F\u0440\u043E\u0441\u0442\u043E \u043D\u0435\u0442.";
|
|
5947
6072
|
function registerTools(server, runtime) {
|
|
5948
6073
|
server.registerTool(
|
|
5949
6074
|
"set_mode",
|
|
@@ -5958,7 +6083,7 @@ function registerTools(server, runtime) {
|
|
|
5958
6083
|
"next_task",
|
|
5959
6084
|
{
|
|
5960
6085
|
title: "\u0412\u0437\u044F\u0442\u044C \u0441\u043B\u0435\u0434\u0443\u044E\u0449\u0443\u044E \u0437\u0430\u0434\u0430\u0447\u0443",
|
|
5961
|
-
description: "\u0411\u043B\u043E\u043A\u0438\u0440\u0443\u044E\u0449\u0438\u0439 \u0432\u044B\u0437\u043E\u0432: \u0434\u043E\u0436\u0434\u0430\u0442\u044C\u0441\u044F \u0438 \u0437\u0430\u0431\u0440\u0430\u0442\u044C \u0441\u043B\u0435\u0434\u0443\u044E\u0449\u0443\u044E \u0437\u0430\u0434\u0430\u0447\u0443 \u0438\u0437 \u043E\u0447\u0435\u0440\u0435\u0434\u0438 \u0434\u0438\u0441\u043F\u0435\u0442\u0447\u0435\u0440\u0430 (\xA79.1, \xA710.3 \u0422\u0417). \u041F\u0440\u043E\u0434\u0432\u0438\u0433\u0430\u0435\u0442 \u0437\u0430\u0434\u0430\u0447\u0443 ASSIGNED \u2192 IN_PROGRESS. \u041F\u0443\u0441\u0442\u043E\u0439 \u043E\u0442\u0432\u0435\u0442 ({empty:true}) \u2014 \u043D\u043E\u0440\u043C\u0430\u043B\u044C\u043D\u044B\u0439 \u0438\u0441\u0445\u043E\u0434, \u0437\u0430\u0434\u0430\u0447 \u0432 \u043E\u0447\u0435\u0440\u0435\u0434\u0438 \u0441\u0435\u0439\u0447\u0430\u0441 \u043D\u0435\u0442, \u043D\u0435 \u043E\u0448\u0438\u0431\u043A\u0430.",
|
|
6086
|
+
description: "\u0411\u043B\u043E\u043A\u0438\u0440\u0443\u044E\u0449\u0438\u0439 \u0432\u044B\u0437\u043E\u0432: \u0434\u043E\u0436\u0434\u0430\u0442\u044C\u0441\u044F \u0438 \u0437\u0430\u0431\u0440\u0430\u0442\u044C \u0441\u043B\u0435\u0434\u0443\u044E\u0449\u0443\u044E \u0437\u0430\u0434\u0430\u0447\u0443 \u0438\u0437 \u043E\u0447\u0435\u0440\u0435\u0434\u0438 \u0434\u0438\u0441\u043F\u0435\u0442\u0447\u0435\u0440\u0430 (\xA79.1, \xA710.3 \u0422\u0417). \u041F\u0440\u043E\u0434\u0432\u0438\u0433\u0430\u0435\u0442 \u0437\u0430\u0434\u0430\u0447\u0443 ASSIGNED \u2192 IN_PROGRESS. \u041F\u0443\u0441\u0442\u043E\u0439 \u043E\u0442\u0432\u0435\u0442 ({empty:true}) \u2014 \u043D\u043E\u0440\u043C\u0430\u043B\u044C\u043D\u044B\u0439 \u0438\u0441\u0445\u043E\u0434, \u0437\u0430\u0434\u0430\u0447 \u0432 \u043E\u0447\u0435\u0440\u0435\u0434\u0438 \u0441\u0435\u0439\u0447\u0430\u0441 \u043D\u0435\u0442, \u043D\u0435 \u043E\u0448\u0438\u0431\u043A\u0430. " + ATTACHMENTS_HINT,
|
|
5962
6087
|
inputSchema: nextTaskInputShape
|
|
5963
6088
|
},
|
|
5964
6089
|
(args) => nextTaskHandler(args, runtime)
|
|
@@ -5967,7 +6092,7 @@ function registerTools(server, runtime) {
|
|
|
5967
6092
|
"get_task",
|
|
5968
6093
|
{
|
|
5969
6094
|
title: "\u041F\u0440\u043E\u0447\u0438\u0442\u0430\u0442\u044C \u0437\u0430\u0434\u0430\u0447\u0443",
|
|
5970
|
-
description: "\u0421\u0432\u0435\u0436\u0438\u0435 \u0434\u0430\u043D\u043D\u044B\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u043F\u043E id, \u0432\u043A\u043B\u044E\u0447\u0430\u044F \u043E\u0442\u0432\u0435\u0442\u044B \u043D\u0430 \u043E\u0442\u043A\u0440\u044B\u0442\u044B\u0435 \u0432\u043E\u043F\u0440\u043E\u0441\u044B (\xA710.3 \u0422\u0417).",
|
|
6095
|
+
description: "\u0421\u0432\u0435\u0436\u0438\u0435 \u0434\u0430\u043D\u043D\u044B\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u043F\u043E id, \u0432\u043A\u043B\u044E\u0447\u0430\u044F \u043E\u0442\u0432\u0435\u0442\u044B \u043D\u0430 \u043E\u0442\u043A\u0440\u044B\u0442\u044B\u0435 \u0432\u043E\u043F\u0440\u043E\u0441\u044B (\xA710.3 \u0422\u0417). " + ATTACHMENTS_HINT,
|
|
5971
6096
|
inputSchema: getTaskInputShape
|
|
5972
6097
|
},
|
|
5973
6098
|
(args) => getTaskHandler(args, runtime)
|
|
@@ -6182,13 +6307,13 @@ function formatConnectResult(result) {
|
|
|
6182
6307
|
}
|
|
6183
6308
|
|
|
6184
6309
|
// src/hooks/pre-compact.ts
|
|
6185
|
-
import { z as
|
|
6186
|
-
var PreCompactInputSchema =
|
|
6187
|
-
hook_event_name:
|
|
6188
|
-
session_id:
|
|
6189
|
-
cwd:
|
|
6190
|
-
trigger:
|
|
6191
|
-
custom_instructions:
|
|
6310
|
+
import { z as z38 } from "zod";
|
|
6311
|
+
var PreCompactInputSchema = z38.object({
|
|
6312
|
+
hook_event_name: z38.literal("PreCompact"),
|
|
6313
|
+
session_id: z38.string(),
|
|
6314
|
+
cwd: z38.string(),
|
|
6315
|
+
trigger: z38.enum(["manual", "auto"]),
|
|
6316
|
+
custom_instructions: z38.string().nullable()
|
|
6192
6317
|
}).passthrough();
|
|
6193
6318
|
function preCompactHook(_input, state, now = () => (/* @__PURE__ */ new Date()).toISOString()) {
|
|
6194
6319
|
const lastPreCompact = state.currentTask ? { ...state.currentTask, savedAt: now() } : null;
|
|
@@ -6197,14 +6322,14 @@ function preCompactHook(_input, state, now = () => (/* @__PURE__ */ new Date()).
|
|
|
6197
6322
|
|
|
6198
6323
|
// src/hooks/pre-tool-use.ts
|
|
6199
6324
|
import { isAbsolute as isAbsolute2, relative as relative2, resolve as resolve3 } from "path";
|
|
6200
|
-
import { z as
|
|
6201
|
-
var PreToolUseInputSchema =
|
|
6202
|
-
hook_event_name:
|
|
6203
|
-
session_id:
|
|
6204
|
-
cwd:
|
|
6205
|
-
tool_name:
|
|
6206
|
-
tool_input:
|
|
6207
|
-
tool_use_id:
|
|
6325
|
+
import { z as z39 } from "zod";
|
|
6326
|
+
var PreToolUseInputSchema = z39.object({
|
|
6327
|
+
hook_event_name: z39.literal("PreToolUse"),
|
|
6328
|
+
session_id: z39.string(),
|
|
6329
|
+
cwd: z39.string(),
|
|
6330
|
+
tool_name: z39.string(),
|
|
6331
|
+
tool_input: z39.record(z39.string(), z39.unknown()),
|
|
6332
|
+
tool_use_id: z39.string()
|
|
6208
6333
|
}).passthrough();
|
|
6209
6334
|
var NO_TRUST_CACHE_REASON = "\u041A\u044D\u0448 \u043F\u0440\u0430\u0432\u0438\u043B \u0434\u043E\u0432\u0435\u0440\u0438\u044F (TrustRules) \u043F\u0443\u0441\u0442 \u2014 \u043A\u043B\u0438\u0435\u043D\u0442 \u043D\u0438 \u0440\u0430\u0437\u0443 \u043D\u0435 \u043F\u043E\u043B\u0443\u0447\u0430\u043B \u0438\u0445 \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 (\u043D\u0435\u0442 agent:hello/trust:updated). \u041E\u043F\u0440\u0435\u0434\u0435\u043B\u0438\u0442\u044C \u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044E\u0449\u0438\u0439 \u043F\u0440\u043E\u0444\u0438\u043B\u044C (full/guarded/approve-all) \u0431\u0435\u0437 \u043D\u0435\u0433\u043E \u043D\u0435\u043B\u044C\u0437\u044F, \u043F\u043E\u044D\u0442\u043E\u043C\u0443 \u043F\u043E \u043F\u0440\u0430\u0432\u0438\u043B\u0443 \u043F\u0440\u043E\u0435\u043A\u0442\u0430 (fail-closed \u043F\u0440\u0438 \u043D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u043D\u043E\u0441\u0442\u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \xA710.4 \u0422\u0417) \u043A\u043E\u043C\u0430\u043D\u0434\u0430 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u044F. \u041F\u043E\u0434\u043D\u0438\u043C\u0438 \u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u0435: `quiel connect` (\u044D\u0442\u0430 \u043A\u043E\u043C\u0430\u043D\u0434\u0430 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043D\u0430 \u0438\u043C\u0435\u043D\u043D\u043E \u0434\u043B\u044F \u0442\u0430\u043A\u043E\u0433\u043E \u0441\u043B\u0443\u0447\u0430\u044F, \u0441\u043C. isBootstrapCommand) \u2014 \u043F\u043E\u0441\u043B\u0435 \u0440\u0443\u043A\u043E\u043F\u043E\u0436\u0430\u0442\u0438\u044F \u043F\u0440\u0430\u0432\u0438\u043B\u0430 \u043F\u0440\u0438\u0434\u0443\u0442, \u0438 \u043A\u043E\u043C\u0430\u043D\u0434\u044B \u043D\u0430\u0447\u043D\u0443\u0442 \u043F\u0440\u043E\u0445\u043E\u0434\u0438\u0442\u044C. \u0415\u0441\u043B\u0438 \u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u0435 \u0443\u0436\u0435 \u0435\u0441\u0442\u044C, \u0432\u044B\u0437\u043E\u0432\u0438 request_approval.";
|
|
6210
6335
|
var BOOTSTRAP_COMMAND_RE = /^quiel\s+(connect|status)\b/;
|
|
@@ -6349,16 +6474,100 @@ function handleFileWrite(input, state, now) {
|
|
|
6349
6474
|
}
|
|
6350
6475
|
|
|
6351
6476
|
// src/hooks/run.ts
|
|
6352
|
-
import { z as
|
|
6477
|
+
import { z as z43 } from "zod";
|
|
6478
|
+
|
|
6479
|
+
// src/usage/read.ts
|
|
6480
|
+
import { closeSync, openSync, readSync, statSync } from "fs";
|
|
6481
|
+
|
|
6482
|
+
// src/usage/transcript.ts
|
|
6483
|
+
function emptyUsageTotals() {
|
|
6484
|
+
return {
|
|
6485
|
+
requests: 0,
|
|
6486
|
+
inputTokens: 0,
|
|
6487
|
+
outputTokens: 0,
|
|
6488
|
+
cacheReadTokens: 0,
|
|
6489
|
+
cacheCreationTokens: 0
|
|
6490
|
+
};
|
|
6491
|
+
}
|
|
6492
|
+
function toCount(value) {
|
|
6493
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
|
|
6494
|
+
}
|
|
6495
|
+
function collectUsage(chunk) {
|
|
6496
|
+
const lastBreak = chunk.lastIndexOf("\n");
|
|
6497
|
+
if (lastBreak < 0) return { consumedBytes: 0, byModel: [] };
|
|
6498
|
+
const complete = chunk.slice(0, lastBreak + 1);
|
|
6499
|
+
const byModel = /* @__PURE__ */ new Map();
|
|
6500
|
+
for (const line of complete.split("\n")) {
|
|
6501
|
+
if (line.trim().length === 0) continue;
|
|
6502
|
+
let parsed;
|
|
6503
|
+
try {
|
|
6504
|
+
parsed = JSON.parse(line);
|
|
6505
|
+
} catch {
|
|
6506
|
+
continue;
|
|
6507
|
+
}
|
|
6508
|
+
const usage = parsed.message?.usage;
|
|
6509
|
+
if (!usage) continue;
|
|
6510
|
+
const model = typeof parsed.message?.model === "string" && parsed.message.model.length > 0 ? parsed.message.model : "unknown";
|
|
6511
|
+
const totals = byModel.get(model) ?? emptyUsageTotals();
|
|
6512
|
+
totals.requests += 1;
|
|
6513
|
+
totals.inputTokens += toCount(usage.input_tokens);
|
|
6514
|
+
totals.outputTokens += toCount(usage.output_tokens);
|
|
6515
|
+
totals.cacheReadTokens += toCount(usage.cache_read_input_tokens);
|
|
6516
|
+
totals.cacheCreationTokens += toCount(usage.cache_creation_input_tokens);
|
|
6517
|
+
byModel.set(model, totals);
|
|
6518
|
+
}
|
|
6519
|
+
return {
|
|
6520
|
+
// Байты, а не символы: смещение потом уходит в чтение файла, а
|
|
6521
|
+
// русские имена и эмодзи в транскрипте занимают больше одного байта.
|
|
6522
|
+
consumedBytes: Buffer.byteLength(complete, "utf8"),
|
|
6523
|
+
byModel: [...byModel].map(([model, totals]) => ({ model, ...totals }))
|
|
6524
|
+
};
|
|
6525
|
+
}
|
|
6526
|
+
function isUsageEmpty(byModel) {
|
|
6527
|
+
return byModel.every(
|
|
6528
|
+
(row) => row.inputTokens === 0 && row.outputTokens === 0 && row.cacheReadTokens === 0 && row.cacheCreationTokens === 0
|
|
6529
|
+
);
|
|
6530
|
+
}
|
|
6531
|
+
|
|
6532
|
+
// src/usage/read.ts
|
|
6533
|
+
function readNewUsage(transcriptPath, offset) {
|
|
6534
|
+
let size;
|
|
6535
|
+
try {
|
|
6536
|
+
size = statSync(transcriptPath).size;
|
|
6537
|
+
} catch {
|
|
6538
|
+
return { byModel: [], offset };
|
|
6539
|
+
}
|
|
6540
|
+
const from = size < offset ? 0 : offset;
|
|
6541
|
+
if (size <= from) return { byModel: [], offset: from };
|
|
6542
|
+
let chunk;
|
|
6543
|
+
let fd;
|
|
6544
|
+
try {
|
|
6545
|
+
fd = openSync(transcriptPath, "r");
|
|
6546
|
+
const buffer = Buffer.allocUnsafe(size - from);
|
|
6547
|
+
const read = readSync(fd, buffer, 0, buffer.length, from);
|
|
6548
|
+
chunk = buffer.subarray(0, read).toString("utf8");
|
|
6549
|
+
} catch {
|
|
6550
|
+
return { byModel: [], offset: from };
|
|
6551
|
+
} finally {
|
|
6552
|
+
if (fd !== void 0) {
|
|
6553
|
+
try {
|
|
6554
|
+
closeSync(fd);
|
|
6555
|
+
} catch {
|
|
6556
|
+
}
|
|
6557
|
+
}
|
|
6558
|
+
}
|
|
6559
|
+
const collected = collectUsage(chunk);
|
|
6560
|
+
return { byModel: collected.byModel, offset: from + collected.consumedBytes };
|
|
6561
|
+
}
|
|
6353
6562
|
|
|
6354
6563
|
// src/hooks/session-start.ts
|
|
6355
|
-
import { z as
|
|
6356
|
-
var SessionStartInputSchema =
|
|
6357
|
-
hook_event_name:
|
|
6358
|
-
session_id:
|
|
6359
|
-
cwd:
|
|
6360
|
-
source:
|
|
6361
|
-
model:
|
|
6564
|
+
import { z as z40 } from "zod";
|
|
6565
|
+
var SessionStartInputSchema = z40.object({
|
|
6566
|
+
hook_event_name: z40.literal("SessionStart"),
|
|
6567
|
+
session_id: z40.string(),
|
|
6568
|
+
cwd: z40.string(),
|
|
6569
|
+
source: z40.enum(["startup", "resume", "clear", "compact", "fork"]),
|
|
6570
|
+
model: z40.string().optional()
|
|
6362
6571
|
}).passthrough();
|
|
6363
6572
|
var SESSION_RESET_SOURCES = /* @__PURE__ */ new Set([
|
|
6364
6573
|
"startup",
|
|
@@ -6397,13 +6606,13 @@ function sessionStartHook(input, state) {
|
|
|
6397
6606
|
}
|
|
6398
6607
|
|
|
6399
6608
|
// src/hooks/stop.ts
|
|
6400
|
-
import { z as
|
|
6401
|
-
var StopInputSchema =
|
|
6402
|
-
hook_event_name:
|
|
6403
|
-
session_id:
|
|
6404
|
-
cwd:
|
|
6405
|
-
stop_hook_active:
|
|
6406
|
-
last_assistant_message:
|
|
6609
|
+
import { z as z41 } from "zod";
|
|
6610
|
+
var StopInputSchema = z41.object({
|
|
6611
|
+
hook_event_name: z41.literal("Stop"),
|
|
6612
|
+
session_id: z41.string(),
|
|
6613
|
+
cwd: z41.string(),
|
|
6614
|
+
stop_hook_active: z41.boolean(),
|
|
6615
|
+
last_assistant_message: z41.string().optional()
|
|
6407
6616
|
}).passthrough();
|
|
6408
6617
|
function taskLabel(state) {
|
|
6409
6618
|
if (!state.currentTask) return "";
|
|
@@ -6447,8 +6656,8 @@ function stopHook(input, state) {
|
|
|
6447
6656
|
}
|
|
6448
6657
|
|
|
6449
6658
|
// src/hooks/stop-failure.ts
|
|
6450
|
-
import { z as
|
|
6451
|
-
var StopFailureErrorTypeSchema =
|
|
6659
|
+
import { z as z42 } from "zod";
|
|
6660
|
+
var StopFailureErrorTypeSchema = z42.enum([
|
|
6452
6661
|
"rate_limit",
|
|
6453
6662
|
"overloaded",
|
|
6454
6663
|
"authentication_failed",
|
|
@@ -6461,13 +6670,13 @@ var StopFailureErrorTypeSchema = z41.enum([
|
|
|
6461
6670
|
"max_output_tokens",
|
|
6462
6671
|
"unknown"
|
|
6463
6672
|
]);
|
|
6464
|
-
var StopFailureInputSchema =
|
|
6465
|
-
hook_event_name:
|
|
6466
|
-
session_id:
|
|
6467
|
-
cwd:
|
|
6673
|
+
var StopFailureInputSchema = z42.object({
|
|
6674
|
+
hook_event_name: z42.literal("StopFailure"),
|
|
6675
|
+
session_id: z42.string(),
|
|
6676
|
+
cwd: z42.string(),
|
|
6468
6677
|
error: StopFailureErrorTypeSchema,
|
|
6469
|
-
error_details:
|
|
6470
|
-
last_assistant_message:
|
|
6678
|
+
error_details: z42.unknown().optional(),
|
|
6679
|
+
last_assistant_message: z42.string().optional()
|
|
6471
6680
|
}).passthrough();
|
|
6472
6681
|
function extractRetryAfterSec(errorDetails) {
|
|
6473
6682
|
if (typeof errorDetails === "number" && Number.isFinite(errorDetails) && errorDetails >= 0) {
|
|
@@ -6496,7 +6705,7 @@ function stopFailureHook(input, _state) {
|
|
|
6496
6705
|
}
|
|
6497
6706
|
|
|
6498
6707
|
// src/hooks/run.ts
|
|
6499
|
-
var HookInputSchema =
|
|
6708
|
+
var HookInputSchema = z43.discriminatedUnion("hook_event_name", [
|
|
6500
6709
|
SessionStartInputSchema,
|
|
6501
6710
|
StopInputSchema,
|
|
6502
6711
|
StopFailureInputSchema,
|
|
@@ -6510,13 +6719,31 @@ function runHook(rawInput, stateFilePath) {
|
|
|
6510
6719
|
}
|
|
6511
6720
|
const state = readState(stateFilePath);
|
|
6512
6721
|
const result = dispatch2(parsedInput.data, state);
|
|
6513
|
-
|
|
6514
|
-
|
|
6722
|
+
const usage = collectTaskUsage(parsedInput.data, state);
|
|
6723
|
+
if (result.statePatch || usage.statePatch) {
|
|
6724
|
+
writeState({ ...state, ...result.statePatch, ...usage.statePatch }, stateFilePath);
|
|
6515
6725
|
}
|
|
6516
6726
|
return {
|
|
6517
6727
|
stdout: JSON.stringify(result.output),
|
|
6518
6728
|
exitCode: 0,
|
|
6519
|
-
serverActions: result.serverActions ?? []
|
|
6729
|
+
serverActions: [...result.serverActions ?? [], ...usage.serverActions]
|
|
6730
|
+
};
|
|
6731
|
+
}
|
|
6732
|
+
function collectTaskUsage(input, state) {
|
|
6733
|
+
if (input.hook_event_name !== "Stop") return { serverActions: [] };
|
|
6734
|
+
const transcriptPath = input.transcript_path;
|
|
6735
|
+
if (typeof transcriptPath !== "string" || transcriptPath.length === 0) {
|
|
6736
|
+
return { serverActions: [] };
|
|
6737
|
+
}
|
|
6738
|
+
const before = state.usageOffsets[transcriptPath] ?? 0;
|
|
6739
|
+
const { byModel, offset } = readNewUsage(transcriptPath, before);
|
|
6740
|
+
if (offset === before) return { serverActions: [] };
|
|
6741
|
+
const statePatch = { usageOffsets: { ...state.usageOffsets, [transcriptPath]: offset } };
|
|
6742
|
+
const taskId = state.currentTask?.taskId;
|
|
6743
|
+
if (!taskId || isUsageEmpty(byModel)) return { statePatch, serverActions: [] };
|
|
6744
|
+
return {
|
|
6745
|
+
statePatch,
|
|
6746
|
+
serverActions: [{ type: "task:usage", payload: { taskId, entries: byModel } }]
|
|
6520
6747
|
};
|
|
6521
6748
|
}
|
|
6522
6749
|
function dispatch2(input, state) {
|
|
@@ -6980,14 +7207,14 @@ function createProgram() {
|
|
|
6980
7207
|
if (result.stderr.length > 0) process.stderr.write(`${result.stderr}
|
|
6981
7208
|
`);
|
|
6982
7209
|
process.exitCode = result.exitCode;
|
|
6983
|
-
if (result.execution)
|
|
7210
|
+
if (result.execution) sendHookActions(result.execution.serverActions);
|
|
6984
7211
|
return;
|
|
6985
7212
|
}
|
|
6986
7213
|
const execution = runCliHook(raw);
|
|
6987
7214
|
process.stdout.write(`${execution.stdout}
|
|
6988
7215
|
`);
|
|
6989
7216
|
process.exitCode = execution.exitCode;
|
|
6990
|
-
|
|
7217
|
+
sendHookActions(execution.serverActions);
|
|
6991
7218
|
});
|
|
6992
7219
|
program.command("mcp").description(
|
|
6993
7220
|
"\u0417\u0430\u043F\u0443\u0441\u0442\u0438\u0442\u044C MCP-\u0441\u0435\u0440\u0432\u0435\u0440 \u043F\u043E stdio: 15 \u0442\u0443\u043B\u043E\u0432 (\xA710.3 \u0422\u0417 \u0438 \u0434\u0430\u043B\u0435\u0435) \u043F\u043E\u0432\u0435\u0440\u0445 \u043F\u043E\u0441\u0442\u043E\u044F\u043D\u043D\u043E\u0433\u043E \u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u044F \u0441 \u043F\u043B\u0430\u0442\u0444\u043E\u0440\u043C\u043E\u0439"
|