@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.
Files changed (4) hide show
  1. package/README.md +8 -5
  2. package/dist/cli.js +1060 -833
  3. package/package.json +5 -6
  4. 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/auth.ts
190
- import { z as z6 } from "zod";
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 z7 } from "zod";
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 = z7.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");
276
- var RequestDocumentUploadUrlSchema = z7.object({
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: z7.enum(ALLOWED_DOCUMENT_MIME_TYPES, {
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: z7.number().int().positive().max(
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 = z7.enum([
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 = z7.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");
294
- var DocumentContentMdSchema = z7.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");
295
- var DocumentFileRefSchema = z7.object({
296
- fileKey: z7.string().min(1),
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: z7.enum(ALLOWED_DOCUMENT_MIME_TYPES)
269
+ mimeType: z6.enum(ALLOWED_DOCUMENT_MIME_TYPES)
299
270
  });
300
- var CreateDocumentSchema = z7.object({
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 = z7.object({
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 = z7.object({
291
+ var ListDocumentsQuerySchema = z6.object({
321
292
  kind: DocumentKindSchema.optional()
322
293
  });
323
294
 
324
- // ../shared/src/dto/milestone.ts
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 MilestoneNameSchema = z8.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");
327
- var MilestoneDescriptionSchema = z8.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");
328
- var MilestoneStatusSchema = z8.enum([MilestoneStatus.OPEN, MilestoneStatus.DONE]);
329
- var CreateMilestoneSchema = z8.object({
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: z8.coerce.date().optional(),
368
+ dueAt: z9.coerce.date().optional(),
333
369
  status: MilestoneStatusSchema.default(MilestoneStatus.OPEN)
334
370
  });
335
- var UpdateMilestoneSchema = z8.object({
371
+ var UpdateMilestoneSchema = z9.object({
336
372
  name: MilestoneNameSchema.optional(),
337
373
  description: MilestoneDescriptionSchema.nullable().optional(),
338
- dueAt: z8.coerce.date().nullable().optional(),
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 = z8.object({
344
- orderedIds: z8.array(z8.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")
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 z9 } from "zod";
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 = z9.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(
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 = 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(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");
363
- var CreateOrganizationSchema = z9.object({
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 = z9.object({
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 = z9.object({
374
- email: z9.email("\u041D\u0435\u043A\u043E\u0440\u0440\u0435\u043A\u0442\u043D\u044B\u0439 email"),
375
- orgRole: z9.enum([OrgRole.ADMIN, OrgRole.MEMBER]).default(OrgRole.MEMBER)
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 = z9.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");
379
- var AcceptInvitationSchema = z9.object({
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 = z9.object({
383
- type: z9.literal("member"),
418
+ var OrganizationMemberDTOSchema = z10.object({
419
+ type: z10.literal("member"),
384
420
  /** id записи Membership — тот же id принимает `DELETE .../members/:id`. */
385
- id: z9.string(),
386
- userId: z9.string(),
387
- name: z9.string().nullable(),
388
- email: z9.string().nullable(),
389
- image: z9.string().nullable(),
390
- orgRole: z9.enum([OrgRole.OWNER, OrgRole.ADMIN, OrgRole.MEMBER]),
391
- createdAt: z9.coerce.date()
392
- });
393
- var OrganizationInvitationDTOSchema = z9.object({
394
- type: z9.literal("invitation"),
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: z9.string(),
397
- email: z9.string(),
398
- orgRole: z9.enum([OrgRole.ADMIN, OrgRole.MEMBER]),
432
+ id: z10.string(),
433
+ email: z10.string(),
434
+ orgRole: z10.enum([OrgRole.ADMIN, OrgRole.MEMBER]),
399
435
  /** `expired` — вычисляется на сервере сравнением `expiresAt` с текущим временем. */
400
- status: z9.enum(["pending", "expired"]),
401
- invitedByName: z9.string().nullable(),
402
- expiresAt: z9.coerce.date(),
403
- createdAt: z9.coerce.date()
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 = z9.discriminatedUnion("type", [
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 z10 } from "zod";
412
- var ProfileNameSchema = z10.string().trim().min(1, "\u0423\u043A\u0430\u0436\u0438\u0442\u0435 \u0438\u043C\u044F").max(120);
413
- var UpdateProfileSchema = z10.object({
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 = z10.object({
417
- currentPassword: z10.string().min(1).max(200).optional(),
452
+ var ChangePasswordSchema = z11.object({
453
+ currentPassword: z11.string().min(1).max(200).optional(),
418
454
  newPassword: PasswordSchema
419
455
  });
420
- var RequestEmailChangeSchema = z10.object({
456
+ var RequestEmailChangeSchema = z11.object({
421
457
  newEmail: EmailSchema,
422
458
  /** Нужен, если у аккаунта есть пароль — см. `ChangePasswordSchema`. */
423
- currentPassword: z10.string().min(1).max(200).optional()
459
+ currentPassword: z11.string().min(1).max(200).optional()
424
460
  });
425
- var ConfirmEmailChangeSchema = z10.object({
426
- token: z10.string().min(1)
461
+ var ConfirmEmailChangeSchema = z11.object({
462
+ token: z11.string().min(1)
427
463
  });
428
- var UpdateAvatarSchema = z10.object({
429
- fileKey: z10.string().min(1).max(500)
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 = z10.object({
439
- fileName: z10.string().trim().min(1).max(200),
440
- mimeType: z10.enum(ALLOWED_AVATAR_MIME_TYPES),
441
- size: z10.number().int().positive().max(MAX_AVATAR_FILE_SIZE_BYTES)
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 = z10.object({
444
- provider: z10.string().trim().min(1).max(50)
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 z14 } from "zod";
484
+ import { z as z15 } from "zod";
449
485
 
450
486
  // ../shared/src/settings/project-settings.ts
451
- import { z as z13 } from "zod";
487
+ import { z as z14 } from "zod";
452
488
 
453
489
  // ../shared/src/dto/task-template.ts
454
- import { z as z12 } from "zod";
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 z11 } from "zod";
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 = z11.enum(taskTypeValues);
519
- var TaskStatusSchema = z11.enum(taskStatusValues);
520
- var TaskPrioritySchema = z11.enum(priorityValues);
521
- var TaskExecutorSchema = z11.enum(executorValues);
522
- var TaskTestResultSchema = z11.enum(testResultValues);
523
- var TaskTitleSchema = z11.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");
524
- var TaskDescriptionSchema = z11.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");
525
- var TaskLabelSchema = z11.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");
526
- var TaskLabelsSchema = z11.array(TaskLabelSchema).max(30, "\u041D\u0435 \u0431\u043E\u043B\u044C\u0448\u0435 30 \u043C\u0435\u0442\u043E\u043A");
527
- var TaskMetadataSchema = z11.record(z11.string(), z11.unknown());
528
- var TaskAcceptanceSchema = z11.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");
529
- var TaskEstimateMinSchema = z11.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);
530
- var TaskOrderSchema = z11.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");
531
- var TaskResultMdSchema = z11.string().max(5e4);
532
- var TaskResultLinkKindSchema = z11.enum(["pr", "commit", "url"]);
533
- var TaskResultLinkSchema = z11.object({
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: z11.string().url("\u041D\u0435\u043A\u043E\u0440\u0440\u0435\u043A\u0442\u043D\u044B\u0439 URL"),
536
- label: z11.string().max(200).optional()
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 = z11.array(TaskResultLinkSchema).max(50);
539
- var TaskLastErrorSchema = z11.string().max(5e3);
540
- var IdSchema = z11.string().min(1);
541
- var CreateTaskSchema = z11.object({
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: z11.string().min(1).max(60).optional(),
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: z11.coerce.date().optional(),
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 = z11.object({
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: z11.string().max(2e4).optional(),
612
+ statusComment: z12.string().max(2e4).optional(),
565
613
  priority: TaskPrioritySchema.optional(),
566
614
  executor: TaskExecutorSchema.optional(),
567
- roleKey: z11.string().min(1).max(60).nullable().optional(),
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: z11.coerce.date().nullable().optional(),
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 = z11.object({
587
- status: z11.string().max(500).optional(),
588
- role: z11.string().max(500).optional(),
589
- assignee: z11.string().max(500).optional(),
590
- milestone: z11.string().max(500).optional(),
591
- label: z11.string().max(500).optional(),
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: z11.string().max(100).optional(),
596
- type: z11.string().max(200).optional(),
597
- q: z11.string().trim().max(200).optional(),
598
- cursor: z11.string().max(4e3).optional(),
599
- limit: z11.coerce.number().int().min(1).max(TASK_LIST_MAX_LIMIT).default(TASK_LIST_DEFAULT_LIMIT)
600
- });
601
- var BulkTaskIdsSchema = z11.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");
602
- var BulkTaskActionSchema = z11.discriminatedUnion("action", [
603
- z11.object({
604
- action: z11.literal("status"),
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: z11.string().max(2e4).optional()
655
+ comment: z12.string().max(2e4).optional()
608
656
  }),
609
- z11.object({
610
- action: z11.literal("milestone"),
657
+ z12.object({
658
+ action: z12.literal("milestone"),
611
659
  taskIds: BulkTaskIdsSchema,
612
660
  milestoneId: IdSchema.nullable()
613
661
  }),
614
- z11.object({
615
- action: z11.literal("role"),
662
+ z12.object({
663
+ action: z12.literal("role"),
616
664
  taskIds: BulkTaskIdsSchema,
617
- roleKey: z11.string().min(1).max(60).nullable()
665
+ roleKey: z12.string().min(1).max(60).nullable()
618
666
  }),
619
- z11.object({
620
- action: z11.literal("delete"),
667
+ z12.object({
668
+ action: z12.literal("delete"),
621
669
  taskIds: BulkTaskIdsSchema
622
670
  })
623
671
  ]);
624
- var BulkTaskResultItemSchema = z11.object({
625
- taskId: z11.string(),
626
- ok: z11.boolean(),
627
- error: z11.object({ code: z11.string(), message: z11.string() }).optional()
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 = 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(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");
632
- var TaskTemplateSchema = z12.object({
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: z12.string().min(1),
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: z12.string().min(1).max(60).optional(),
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 = z12.array(TaskTemplateSchema).max(50, "\u041D\u0435 \u0431\u043E\u043B\u044C\u0448\u0435 50 \u0448\u0430\u0431\u043B\u043E\u043D\u043E\u0432");
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 = z13.enum(taskStatusValues2);
670
- var BoardSettingsSchema = z13.object({
671
- hiddenStatuses: z13.array(TaskStatusSchema2).default([]),
672
- mergedColumns: z13.array(z13.array(TaskStatusSchema2)).default([])
673
- });
674
- var NotificationSettingsSchema = z13.object({
675
- telegram: z13.boolean().default(false),
676
- email: z13.boolean().default(false)
677
- });
678
- var ProjectSettingsSchema = z13.object({
679
- autoAccept: z13.boolean().default(false),
680
- requireTests: z13.boolean().default(true),
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: z13.boolean().default(false),
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: z13.boolean().default(false),
762
+ reviewTaskOnPr: z14.boolean().default(false),
715
763
  /**
716
764
  * Ключ роли, на которую вешается задача ревью (`RoleDefinition.key`).
717
765
  * Пусто — задача заводится без роли и видна всей команде проекта.
718
766
  */
719
- reviewRoleKey: z13.string().trim().min(1).max(60).optional(),
720
- maxParallelTasksPerAgent: z13.number().int().positive().default(1),
721
- leaseTtlSec: z13.number().int().positive().default(120),
722
- taskTimeoutMin: z13.number().int().positive().default(90),
723
- contextResetAfterTasks: z13.number().int().positive().default(8),
724
- branchTemplate: z13.string().min(1).default("task/{key}-{slug}"),
725
- commitTemplate: z13.string().min(1).default("{key}: {title}"),
726
- stopPatternsOverride: z13.array(z13.string()).optional(),
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 = z14.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");
737
- var ProjectNameSchema = z14.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");
738
- var ProjectDescriptionSchema = z14.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");
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: z14.coerce.date().optional()
788
+ autonomousConfirmedAt: z15.coerce.date().optional()
741
789
  });
742
790
  var UpdateProjectSettingsSchema = ProjectSettingsRecordSchema.partial();
743
- var ProjectModeSchema = z14.enum([ProjectMode.AUTONOMOUS, ProjectMode.APPROVAL]);
744
- var ProjectStatusSchema = z14.enum([
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 = z14.enum([GitMode.DIRECT, GitMode.PR]);
750
- var ProjectDateSchema = z14.coerce.date();
751
- var NewProjectMilestoneSchema = z14.object({
752
- name: z14.string().trim().min(1, "\u0423\u043A\u0430\u0436\u0438\u0442\u0435 \u043D\u0430\u0437\u0432\u0430\u043D\u0438\u0435").max(200),
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 = z14.object({
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: z14.boolean().optional(),
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: z14.array(z14.string().min(1)).max(100).optional(),
771
- milestones: z14.array(NewProjectMilestoneSchema).max(50).optional()
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 = z14.object({
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: z14.boolean().optional()
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 z15 } from "zod";
795
- var RepositoryUrlSchema = z15.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(
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 = z15.string().trim().min(1).max(200);
803
- var PathHintSchema = z15.string().trim().max(300);
804
- var CreateRepositorySchema = z15.object({
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 = z15.object({
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 = z15.object({
865
+ var ConnectGithubRepositorySchema = z16.object({
818
866
  /** Идентификатор НАШЕЙ записи установки, а не номер установки в GitHub. */
819
- installationId: z15.string().min(1, "\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0430\u043A\u043A\u0430\u0443\u043D\u0442 GitHub"),
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: z15.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"),
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 z16 } from "zod";
843
- var RoleNameSchema = z16.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");
844
- var RoleColorSchema = z16.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");
845
- var CreateRoleSchema = z16.object({
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: z16.string().optional()
896
+ defaultTrustProfileId: z17.string().optional()
849
897
  });
850
- var UpdateRoleSchema = z16.object({
898
+ var UpdateRoleSchema = z17.object({
851
899
  name: RoleNameSchema.optional(),
852
900
  color: RoleColorSchema.optional(),
853
- defaultTrustProfileId: z16.string().nullable().optional()
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 z17 } from "zod";
860
- var SavedFilterNameSchema = 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(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");
861
- var SavedFilterQuerySchema = z17.object({
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: z17.array(TaskStatusSchema).max(11).default([]),
872
- roles: z17.array(z17.string().min(1)).max(50).default([]),
873
- assignees: z17.array(z17.string().min(1)).max(50).default([]),
874
- milestones: z17.array(z17.string().min(1)).max(50).default([]),
875
- labels: z17.array(TaskLabelSchema).max(30).default([]),
876
- priorities: z17.array(TaskPrioritySchema).max(4).default([]),
877
- types: z17.array(TaskTypeSchema).max(7).default([]),
878
- q: z17.string().trim().max(200).default("")
879
- });
880
- var CreateSavedFilterSchema = z17.object({
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 = z17.object({
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 z18 } from "zod";
893
- var TaskDependencyKindSchema = z18.enum([DepKind.BLOCKS, DepKind.RELATES]);
894
- var IdSchema2 = z18.string().min(1);
895
- var CreateTaskDependencySchema = z18.object({
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 = z18.object({
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 z19 } from "zod";
905
- var TaskEventKindSchema = z19.enum([
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 = z19.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");
917
- var CreateTaskEventSchema = z19.object({
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 = z19.object({ bodyMd: TaskCommentBodySchema });
921
- var TaskEditPayloadSchema = z19.object({
922
- fields: z19.record(z19.string(), z19.object({ from: z19.unknown(), to: z19.unknown() }))
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 = z19.object({
925
- from: z19.string().nullable(),
926
- to: z19.string().nullable()
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 = z19.object({
978
+ var ListTaskEventsQuerySchema = z20.object({
931
979
  /** CSV нескольких kind — как остальные CSV-фильтры задач (lib/tasks/filters.ts). */
932
- kind: z19.string().max(300).optional(),
933
- cursor: z19.string().max(4e3).optional(),
934
- limit: z19.coerce.number().int().min(1).max(TASK_EVENT_LIST_MAX_LIMIT).default(TASK_EVENT_LIST_DEFAULT_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 z20 } from "zod";
939
- var CommentSchema = z20.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");
940
- var TransitionTaskSchema = z20.object({
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 = z20.object({
992
+ var AcceptTaskSchema = z21.object({
945
993
  comment: CommentSchema.optional()
946
994
  });
947
- var ReturnTaskSchema = z20.object({
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 = z20.object({
998
+ var ReopenTaskSchema = z21.object({
951
999
  reason: CommentSchema.optional()
952
1000
  });
953
- var RequeueTaskSchema = z20.object({
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 z21 } from "zod";
959
- var CommentSchema2 = 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");
960
- var RestoreTaskSchema = z21.object({
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 = z21.object({
966
- cursor: z21.string().max(4e3).optional(),
967
- limit: z21.coerce.number().int().min(1).max(TASK_TRASH_LIST_MAX_LIMIT).default(TASK_TRASH_LIST_DEFAULT_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 z22 } from "zod";
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 = z22.enum(["allow", "approve", "deny"]);
1026
- var trustFilesModeSchema = z22.enum(["allow", "approve"]);
1027
- var trustRulesSchema = z22.object({
1028
- bash: z22.object({
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: z22.array(z22.string().min(1)),
1033
- allowPatterns: z22.array(z22.string().min(1)).optional()
1080
+ stopPatterns: z23.array(z23.string().min(1)),
1081
+ allowPatterns: z23.array(z23.string().min(1)).optional()
1034
1082
  }),
1035
- files: z22.object({
1083
+ files: z23.object({
1036
1084
  mode: trustFilesModeSchema,
1037
- protectedPaths: z22.array(z22.string().min(1))
1085
+ protectedPaths: z23.array(z23.string().min(1))
1038
1086
  }),
1039
- git: z22.object({
1040
- allowPushDefault: z22.boolean(),
1041
- allowForcePush: z22.boolean()
1087
+ git: z23.object({
1088
+ allowPushDefault: z23.boolean(),
1089
+ allowForcePush: z23.boolean()
1042
1090
  }),
1043
- network: z22.object({
1044
- allowSsh: z22.boolean(),
1045
- sshHostsAllow: z22.array(z22.string().min(1)).optional()
1091
+ network: z23.object({
1092
+ allowSsh: z23.boolean(),
1093
+ sshHostsAllow: z23.array(z23.string().min(1)).optional()
1046
1094
  }),
1047
- approvalTtlMin: z22.number().int().positive()
1048
- });
1049
- var agentSummarySchema = z22.object({
1050
- id: z22.string().min(1),
1051
- projectId: z22.string().min(1),
1052
- membershipId: z22.string().min(1),
1053
- name: z22.string().min(1),
1054
- roleKeys: z22.array(z22.string().min(1)),
1055
- status: z22.enum(agentStatusValues),
1056
- mode: z22.enum(agentModeValues),
1057
- lastSeenAt: z22.string().datetime().nullable(),
1058
- clientVersion: z22.string().nullable(),
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: z22.string().nullable().default(null),
1077
- currentTaskId: z22.string().nullable(),
1078
- tasksCompletedInSession: z22.number().int().nonnegative()
1079
- });
1080
- var agentCurrentTaskSummarySchema = z22.object({
1081
- id: z22.string().min(1),
1082
- number: z22.number().int().positive(),
1083
- title: z22.string().min(1),
1084
- status: z22.enum(taskStatusValues3)
1085
- });
1086
- var agentHelloPayloadSchema = z22.object({
1087
- clientVersion: z22.string().min(1),
1088
- cwd: z22.string().min(1),
1089
- os: z22.string().min(1),
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: z22.string().min(1).max(64).optional(),
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: z22.string().min(1).optional(),
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: z22.string().min(1).optional(),
1169
+ claudeVersion: z23.string().min(1).optional(),
1122
1170
  // Роли, которыми клиент СЕБЯ считает — информационно (лог/диагностика
1123
1171
  // рассинхрона), не авторизация: авторизующие `Agent.roleKeys` идут из
1124
1172
  // БД (заданы при создании агента, REST §12 ТЗ), этот payload их не
1125
1173
  // меняет. См. блок «ВОПРОСЫ» отчёта P2-03.
1126
- roleKeys: z22.array(z22.string().min(1)),
1127
- resumeToken: z22.string().min(1).optional()
1174
+ roleKeys: z23.array(z23.string().min(1)),
1175
+ resumeToken: z23.string().min(1).optional()
1128
1176
  });
1129
- var agentHelloAckSchema = z22.object({
1177
+ var agentHelloAckSchema = z23.object({
1130
1178
  agent: agentSummarySchema,
1131
1179
  trust: trustRulesSchema,
1132
1180
  currentTask: agentCurrentTaskSummarySchema.optional(),
1133
- mode: z22.enum(agentModeValues)
1181
+ mode: z23.enum(agentModeValues)
1134
1182
  });
1135
- var agentHeartbeatPayloadSchema = z22.object({
1136
- currentTaskId: z22.string().min(1).optional(),
1137
- resumeToken: z22.string().min(1).optional(),
1138
- status: z22.enum(agentStatusValues)
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 = z22.object({
1141
- ok: z22.boolean(),
1142
- leaseExpiresAt: z22.string().datetime().optional()
1188
+ var agentHeartbeatAckSchema = z23.object({
1189
+ ok: z23.boolean(),
1190
+ leaseExpiresAt: z23.string().datetime().optional()
1143
1191
  });
1144
- var agentModePayloadSchema = z22.object({
1145
- mode: z22.enum(agentModeValues)
1192
+ var agentModePayloadSchema = z23.object({
1193
+ mode: z23.enum(agentModeValues)
1146
1194
  });
1147
- var agentModeAckSchema = z22.object({
1148
- ok: z22.boolean(),
1149
- mode: z22.enum(agentModeValues).optional()
1195
+ var agentModeAckSchema = z23.object({
1196
+ ok: z23.boolean(),
1197
+ mode: z23.enum(agentModeValues).optional()
1150
1198
  });
1151
- var taskPayloadMilestoneSchema = z22.object({
1152
- name: z22.string().min(1),
1153
- dueAt: z22.string().datetime().nullable()
1199
+ var taskPayloadMilestoneSchema = z23.object({
1200
+ name: z23.string().min(1),
1201
+ dueAt: z23.string().datetime().nullable()
1154
1202
  });
1155
- var taskPayloadTaskSchema = z22.object({
1156
- id: z22.string().min(1),
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: z22.string().min(1),
1159
- title: z22.string().min(1),
1160
- descriptionMd: z22.string(),
1161
- type: z22.enum(taskTypeValues2),
1162
- priority: z22.enum(priorityValues2),
1163
- acceptance: z22.string(),
1164
- attempts: z22.number().int().nonnegative(),
1165
- reviewNotes: z22.string().optional(),
1166
- metadata: z22.record(z22.string(), z22.unknown()),
1167
- labels: z22.array(z22.string()),
1168
- milestone: taskPayloadMilestoneSchema.optional()
1169
- });
1170
- var taskPayloadRepoSchema = z22.object({
1171
- url: z22.string().min(1),
1172
- defaultBranch: z22.string().min(1),
1173
- pathHint: z22.string().nullable()
1174
- });
1175
- var taskPayloadProjectSchema = z22.object({
1176
- key: z22.string().min(1),
1177
- name: z22.string().min(1),
1178
- mode: z22.enum(projectModeValues),
1179
- gitMode: z22.enum(gitModeValues),
1180
- repos: z22.array(taskPayloadRepoSchema),
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: z22.string().min(1),
1246
+ branchName: z23.string().min(1),
1183
1247
  /** Префикс сообщения коммита, `ATL-42:`. */
1184
- commitPrefix: z22.string().min(1)
1248
+ commitPrefix: z23.string().min(1)
1185
1249
  });
1186
- var taskPayloadDependencySchema = z22.object({
1187
- key: z22.string().min(1),
1188
- title: z22.string().min(1),
1189
- status: z22.enum(taskStatusValues3),
1190
- resultMd: z22.string().optional(),
1191
- resultLinks: z22.array(z22.string()).optional()
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 = z22.object({
1194
- id: z22.string().min(1),
1195
- textMd: z22.string(),
1196
- answerMd: z22.string().optional()
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 = z22.object({
1199
- profileKey: z22.string().min(1),
1200
- summary: z22.string()
1262
+ var taskPayloadTrustSchema = z23.object({
1263
+ profileKey: z23.string().min(1),
1264
+ summary: z23.string()
1201
1265
  });
1202
- var taskPayloadLeaseSchema = z22.object({
1203
- resumeToken: z22.string().min(1),
1204
- expiresAt: z22.string().datetime()
1266
+ var taskPayloadLeaseSchema = z23.object({
1267
+ resumeToken: z23.string().min(1),
1268
+ expiresAt: z23.string().datetime()
1205
1269
  });
1206
- var taskPayloadSchema = z22.object({
1270
+ var taskPayloadSchema = z23.object({
1207
1271
  task: taskPayloadTaskSchema,
1208
1272
  project: taskPayloadProjectSchema,
1209
- dependencies: z22.array(taskPayloadDependencySchema),
1210
- openQuestions: z22.array(taskPayloadOpenQuestionSchema),
1273
+ dependencies: z23.array(taskPayloadDependencySchema),
1274
+ openQuestions: z23.array(taskPayloadOpenQuestionSchema),
1211
1275
  trust: taskPayloadTrustSchema,
1212
1276
  lease: taskPayloadLeaseSchema
1213
1277
  });
1214
- var taskClaimPayloadSchema = z22.object({
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: z22.number().int().min(0).max(600)
1221
- });
1222
- var taskClaimAckSchema = z22.union([taskPayloadSchema, z22.object({ empty: z22.literal(true) })]);
1223
- var taskStartPayloadSchema = z22.object({
1224
- taskId: z22.string().min(1),
1225
- resumeToken: z22.string().min(1)
1226
- });
1227
- var taskStartAckSchema = z22.object({ ok: z22.boolean() });
1228
- var taskProgressLevelSchema = z22.enum(["debug", "info", "warn", "error"]);
1229
- var taskProgressPayloadSchema = z22.object({
1230
- taskId: z22.string().min(1),
1231
- note: z22.string().min(1),
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 = z22.object({ ok: z22.boolean() });
1235
- var taskReleasePayloadSchema = z22.object({
1236
- taskId: z22.string().min(1),
1237
- reason: z22.string().min(1)
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 = z22.object({ ok: z22.boolean() });
1240
- var taskGetPayloadSchema = z22.object({
1241
- taskId: z22.string().min(1)
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 = z22.enum(["success", "partial", "failed"]);
1247
- var reportLinkSchema = z22.object({
1248
- kind: z22.enum(["commit", "pr", "doc", "other"]),
1249
- url: z22.string().min(1),
1250
- title: z22.string().optional()
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 = z22.object({
1253
- taskId: z22.string().min(1),
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: z22.string().min(1),
1324
+ resumeToken: z23.string().min(1),
1261
1325
  status: reportStatusSchema,
1262
- resultMd: z22.string().min(1),
1263
- links: z22.array(reportLinkSchema),
1264
- testResult: z22.enum(testResultValues2),
1265
- nextSteps: z22.string().optional()
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 = z22.object({
1268
- taskStatus: z22.enum(taskStatusValues3),
1331
+ var reportAckSchema = z23.object({
1332
+ taskStatus: z23.enum(taskStatusValues3),
1269
1333
  /** true, если этот ack — повтор уже принятой сдачи (идемпотентность). */
1270
- duplicate: z22.boolean().optional()
1334
+ duplicate: z23.boolean().optional()
1271
1335
  });
1272
- var contextIncludeSchema = z22.enum(["spec", "decisions", "documents", "related", "repo"]);
1273
- var contextGetPayloadSchema = z22.object({
1274
- taskId: z22.string().min(1).optional(),
1275
- include: z22.array(contextIncludeSchema).min(1)
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 = z22.object({
1341
+ var contextDocumentFileSchema = z23.object({
1278
1342
  /** Имя как у человека на диске: `Спецификация v2.pdf`. */
1279
- fileName: z22.string().min(1),
1343
+ fileName: z23.string().min(1),
1280
1344
  /** Временная ссылка на скачивание — агент читает файл сам. */
1281
- downloadUrl: z22.string().min(1),
1345
+ downloadUrl: z23.string().min(1),
1282
1346
  /** Сколько секунд ссылка живёт: успеть скачать, а не отложить на потом. */
1283
- expiresInSeconds: z22.number().int().positive()
1347
+ expiresInSeconds: z23.number().int().positive()
1284
1348
  });
1285
- var contextDocumentSchema = z22.object({
1286
- id: z22.string().min(1),
1287
- title: z22.string().min(1),
1288
- kind: z22.string().min(1),
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: z22.string(),
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 = z22.object({
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: z22.array(z22.string()).optional(),
1379
+ notes: z23.array(z23.string()).optional(),
1316
1380
  spec: contextDocumentSchema.nullable().optional(),
1317
- decisions: z22.array(contextDocumentSchema).optional(),
1381
+ decisions: z23.array(contextDocumentSchema).optional(),
1318
1382
  /** Все документы проекта — любого типа, включая спецификацию и решения. */
1319
- documents: z22.array(contextDocumentSchema).optional(),
1320
- related: z22.array(taskPayloadDependencySchema).optional(),
1321
- repo: z22.object({
1322
- repos: z22.array(taskPayloadRepoSchema),
1323
- branchName: z22.string().optional(),
1324
- commitPrefix: z22.string().optional()
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 = z22.object({
1328
- retryAfterSec: z22.number().int().positive().optional(),
1329
- taskId: z22.string().min(1).optional()
1391
+ var agentRateLimitedPayloadSchema = z23.object({
1392
+ retryAfterSec: z23.number().int().positive().optional(),
1393
+ taskId: z23.string().min(1).optional()
1330
1394
  });
1331
- var agentRateLimitedAckSchema = z22.object({
1332
- ok: z22.boolean(),
1395
+ var agentRateLimitedAckSchema = z23.object({
1396
+ ok: z23.boolean(),
1333
1397
  /** Когда задача вернётся в очередь (§9.4 ТЗ: «через 2 ч»). */
1334
- requeueAt: z22.string().datetime().optional()
1398
+ requeueAt: z23.string().datetime().optional()
1335
1399
  });
1336
- var projectStatePayloadSchema = z22.object({
1337
- projectId: z22.string().min(1),
1338
- paused: z22.boolean(),
1339
- mode: z22.enum(projectModeValues),
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: z22.string().optional()
1342
- });
1343
- var questionSummarySchema = z22.object({
1344
- id: z22.string().min(1),
1345
- taskId: z22.string().min(1).nullable(),
1346
- textMd: z22.string(),
1347
- options: z22.array(z22.string()),
1348
- blocking: z22.boolean(),
1349
- status: z22.enum(questionStatusValues),
1350
- answerMd: z22.string().nullable(),
1351
- answeredAt: z22.string().datetime().nullable(),
1352
- createdAt: z22.string().datetime()
1353
- });
1354
- var questionAskPayloadSchema = z22.object({
1355
- taskId: z22.string().min(1).optional(),
1356
- textMd: z22.string().min(1),
1357
- targetRole: z22.string().min(1).optional(),
1358
- targetMemberId: z22.string().min(1).optional(),
1359
- options: z22.array(z22.string().min(1)).optional(),
1360
- blocking: z22.boolean(),
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: z22.number().int().min(0).max(600).optional()
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 = z22.object({
1447
+ var questionAskAckSchema = z23.object({
1367
1448
  question: questionSummarySchema
1368
1449
  });
1369
- var questionWaitPayloadSchema = z22.object({
1370
- questionId: z22.string().min(1),
1371
- waitSec: z22.number().int().min(0).max(600)
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 = z22.object({
1454
+ var questionWaitAckSchema = z23.object({
1374
1455
  question: questionSummarySchema
1375
1456
  });
1376
- var taskCreatePayloadSchema = z22.object({
1377
- title: z22.string().min(1),
1378
- descriptionMd: z22.string(),
1379
- roleKey: z22.string().min(1).optional(),
1380
- assigneeId: z22.string().min(1).optional(),
1381
- type: z22.enum(taskTypeValues2),
1382
- priority: z22.enum(priorityValues2),
1383
- executor: z22.enum(executorValues2),
1384
- blocksCurrent: z22.boolean(),
1385
- acceptance: z22.string().optional(),
1386
- labels: z22.array(z22.string().min(1)).optional()
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 = z22.object({
1391
- id: z22.string().min(1),
1392
- key: z22.string().min(1),
1393
- title: z22.string().min(1),
1394
- type: z22.enum(taskTypeValues2),
1395
- status: z22.enum(taskStatusValues3),
1396
- priority: z22.enum(priorityValues2),
1397
- roleKey: z22.string().min(1).nullable(),
1398
- assigneeId: z22.string().min(1).nullable(),
1399
- labels: z22.array(z22.string()),
1400
- updatedAt: z22.string().datetime()
1401
- });
1402
- var taskCreateAckSchema = z22.object({
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: z22.enum(taskStatusValues3).optional()
1502
+ currentTaskStatus: z23.enum(taskStatusValues3).optional()
1406
1503
  });
1407
- var taskListPayloadSchema = z22.object({
1408
- status: z22.array(z22.enum(taskStatusValues3)).optional(),
1409
- roleKey: z22.string().min(1).optional(),
1504
+ var taskListPayloadSchema = z23.object({
1505
+ status: z23.array(z23.enum(taskStatusValues3)).optional(),
1506
+ roleKey: z23.string().min(1).optional(),
1410
1507
  /** Поиск по заголовку, без учёта регистра. */
1411
- query: z22.string().min(1).optional(),
1412
- limit: z22.number().int().min(1).max(100).optional()
1413
- });
1414
- var taskListAckSchema = z22.object({
1415
- tasks: z22.array(taskBriefSchema)
1416
- });
1417
- var taskUpdatePayloadSchema = z22.object({
1418
- taskId: z22.string().min(1),
1419
- patch: z22.object({
1420
- progressNote: z22.string().min(1).optional(),
1421
- labels: z22.array(z22.string().min(1)).optional(),
1422
- estimateMin: z22.number().int().positive().optional()
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 = z22.object({
1522
+ var taskUpdateAckSchema = z23.object({
1426
1523
  task: taskBriefSchema
1427
1524
  });
1428
- var modeSetPayloadSchema = z22.object({
1429
- mode: z22.enum(agentModeValues)
1525
+ var modeSetPayloadSchema = z23.object({
1526
+ mode: z23.enum(agentModeValues)
1430
1527
  });
1431
- var agentPausePayloadSchema = z22.object({
1432
- reason: z22.string().min(1)
1528
+ var agentPausePayloadSchema = z23.object({
1529
+ reason: z23.string().min(1)
1433
1530
  });
1434
1531
  var trustUpdatedPayloadSchema = trustRulesSchema;
1435
- var leaseLostPayloadSchema = z22.object({
1436
- taskId: z22.string().min(1),
1437
- reason: z22.string().min(1)
1438
- });
1439
- var taskUpdatedAgentPayloadSchema = z22.object({
1440
- taskId: z22.string().min(1),
1441
- patch: z22.record(z22.string(), z22.unknown()).optional()
1442
- });
1443
- var questionAnsweredPayloadSchema = z22.object({
1444
- questionId: z22.string().min(1),
1445
- answerMd: z22.string()
1446
- });
1447
- var approvalSummarySchema = z22.object({
1448
- id: z22.string().min(1),
1449
- taskId: z22.string().min(1),
1450
- kind: z22.enum(approvalKindValues),
1451
- summary: z22.string(),
1452
- status: z22.enum(approvalStatusValues),
1453
- expiresAt: z22.string().datetime(),
1454
- decidedAt: z22.string().datetime().nullable(),
1455
- createdAt: z22.string().datetime()
1456
- });
1457
- var approvalRequestPayloadSchema = z22.object({
1458
- taskId: z22.string().min(1),
1459
- kind: z22.enum(approvalKindValues),
1460
- summary: z22.string().min(1),
1461
- command: z22.string().min(1),
1462
- cwd: z22.string().min(1),
1463
- host: z22.string().min(1).optional(),
1464
- diff: z22.string().optional(),
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: z22.number().int().min(0).max(600).optional()
1563
+ waitSec: z23.number().int().min(0).max(600).optional()
1467
1564
  });
1468
- var approvalRequestAckSchema = z22.object({
1565
+ var approvalRequestAckSchema = z23.object({
1469
1566
  approval: approvalSummarySchema,
1470
1567
  /** Приходит только при `APPROVED` — одноразовый, привязан к команде и каталогу (§14.4 ТЗ). */
1471
- oneTimeToken: z22.string().min(1).optional()
1568
+ oneTimeToken: z23.string().min(1).optional()
1472
1569
  });
1473
- var approvalWaitPayloadSchema = z22.object({
1474
- approvalId: z22.string().min(1),
1475
- waitSec: z22.number().int().min(0).max(600)
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 = z22.object({
1479
- approvalId: z22.string().min(1),
1480
- status: z22.enum([ApprovalStatus.APPROVED, ApprovalStatus.REJECTED]),
1481
- oneTimeToken: z22.string().min(1).optional()
1482
- });
1483
- var agentPresenceUiPayloadSchema = z22.object({
1484
- projectId: z22.string().min(1),
1485
- agentId: z22.string().min(1),
1486
- status: z22.enum(agentStatusValues),
1487
- lastSeenAt: z22.string().datetime(),
1488
- currentTaskId: z22.string().nullable().optional()
1489
- });
1490
- var taskOpenPrPayloadSchema = z22.object({
1491
- taskId: z22.string().min(1),
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: z22.string().min(1),
1590
+ branchName: z23.string().min(1),
1494
1591
  /** Rebase на основную ветку не прошёл — PR помечается «conflicts» (§13.1 ТЗ). */
1495
- conflicted: z22.boolean().optional(),
1592
+ conflicted: z23.boolean().optional(),
1496
1593
  /** Только пути файлов, никогда содержимое (§18 ТЗ). */
1497
- conflictedFiles: z22.array(z22.string().min(1)).max(100).optional()
1594
+ conflictedFiles: z23.array(z23.string().min(1)).max(100).optional()
1498
1595
  });
1499
- var taskOpenPrAckSchema = z22.object({
1500
- url: z22.string().url(),
1501
- number: z22.number().int().positive(),
1596
+ var taskOpenPrAckSchema = z23.object({
1597
+ url: z23.string().url(),
1598
+ number: z23.number().int().positive(),
1502
1599
  /** `false` — PR уже существовал для этой ветки, повторно не создавали. */
1503
- created: z22.boolean()
1600
+ created: z23.boolean()
1504
1601
  });
1505
1602
 
1506
1603
  // ../shared/src/events/ticket.ts
1507
- import { z as z23 } from "zod";
1508
- var realtimeTicketPayloadSchema = z23.object({
1509
- sub: z23.string().min(1),
1510
- orgIds: z23.array(z23.string().min(1)),
1511
- projectIds: z23.array(z23.string().min(1)),
1512
- iat: z23.number().int().positive(),
1513
- exp: z23.number().int().positive(),
1514
- jti: z23.string().min(1)
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 = z23.object({
1517
- room: z23.string().min(1),
1518
- projectId: z23.string().min(1).optional()
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 z24 } from "zod";
1619
+ import { z as z25 } from "zod";
1523
1620
  var taskStatusValues4 = Object.values(TaskStatus);
1524
- var taskCreatedPayloadSchema = z24.object({
1525
- taskId: z24.string().min(1),
1526
- projectId: z24.string().min(1),
1527
- orgId: z24.string().min(1)
1528
- });
1529
- var taskUpdatedPayloadSchema = z24.object({
1530
- taskId: z24.string().min(1),
1531
- projectId: z24.string().min(1),
1532
- orgId: z24.string().min(1),
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: z24.record(z24.string(), z24.unknown()).optional()
1632
+ patch: z25.record(z25.string(), z25.unknown()).optional()
1536
1633
  });
1537
- var taskDeletedPayloadSchema = z24.object({
1538
- taskId: z24.string().min(1),
1539
- projectId: z24.string().min(1),
1540
- orgId: z24.string().min(1)
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 = z24.object({
1543
- taskId: z24.string().min(1),
1544
- projectId: z24.string().min(1),
1545
- orgId: z24.string().min(1),
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: z24.enum(taskStatusValues4),
1549
- order: z24.number()
1645
+ status: z25.enum(taskStatusValues4),
1646
+ order: z25.number()
1550
1647
  });
1551
- var notificationNewPayloadSchema = z24.object({
1552
- notificationId: z24.string().min(1),
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: z24.string().min(1),
1556
- kind: z24.string().min(1),
1557
- title: z24.string().min(1),
1558
- body: z24.string().optional(),
1559
- link: z24.string().optional()
1560
- });
1561
- var futurePlaceholderPayloadSchema = z24.object({
1562
- projectId: z24.string().min(1)
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 = z24.object({
1565
- questionId: z24.string().min(1),
1566
- projectId: z24.string().min(1),
1567
- orgId: z24.string().min(1),
1568
- taskId: z24.string().min(1).nullable().optional(),
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: z24.string().min(1).nullable().optional(),
1571
- targetMemberId: z24.string().min(1).nullable().optional(),
1572
- blocking: z24.boolean().optional()
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: z24.string().datetime().optional()
1672
+ publishedAt: z25.string().datetime().optional()
1576
1673
  };
1577
- var uiEventEnvelopeSchema = z24.discriminatedUnion("event", [
1578
- z24.object({
1579
- event: z24.literal("task:created"),
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
- z24.object({
1584
- event: z24.literal("task:updated"),
1680
+ z25.object({
1681
+ event: z25.literal("task:updated"),
1585
1682
  payload: taskUpdatedPayloadSchema,
1586
1683
  ...envelopeExtra
1587
1684
  }),
1588
- z24.object({
1589
- event: z24.literal("task:deleted"),
1685
+ z25.object({
1686
+ event: z25.literal("task:deleted"),
1590
1687
  payload: taskDeletedPayloadSchema,
1591
1688
  ...envelopeExtra
1592
1689
  }),
1593
- z24.object({ event: z24.literal("task:moved"), payload: taskMovedPayloadSchema, ...envelopeExtra }),
1594
- z24.object({
1595
- event: z24.literal("notification:new"),
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
- z24.object({
1603
- event: z24.literal("agent:presence"),
1699
+ z25.object({
1700
+ event: z25.literal("agent:presence"),
1604
1701
  payload: futurePlaceholderPayloadSchema,
1605
1702
  ...envelopeExtra
1606
1703
  }),
1607
- z24.object({
1608
- event: z24.literal("question:new"),
1704
+ z25.object({
1705
+ event: z25.literal("question:new"),
1609
1706
  payload: questionEventPayloadSchema,
1610
1707
  ...envelopeExtra
1611
1708
  }),
1612
- z24.object({
1613
- event: z24.literal("question:answered"),
1709
+ z25.object({
1710
+ event: z25.literal("question:answered"),
1614
1711
  payload: questionEventPayloadSchema,
1615
1712
  ...envelopeExtra
1616
1713
  }),
1617
- z24.object({
1618
- event: z24.literal("question:dismissed"),
1714
+ z25.object({
1715
+ event: z25.literal("question:dismissed"),
1619
1716
  payload: questionEventPayloadSchema,
1620
1717
  ...envelopeExtra
1621
1718
  }),
1622
- z24.object({
1623
- event: z24.literal("approval:requested"),
1719
+ z25.object({
1720
+ event: z25.literal("approval:requested"),
1624
1721
  payload: futurePlaceholderPayloadSchema,
1625
1722
  ...envelopeExtra
1626
1723
  }),
1627
- z24.object({
1628
- event: z24.literal("approval:decided"),
1724
+ z25.object({
1725
+ event: z25.literal("approval:decided"),
1629
1726
  payload: futurePlaceholderPayloadSchema,
1630
1727
  ...envelopeExtra
1631
1728
  }),
1632
- z24.object({
1633
- event: z24.literal("audit:appended"),
1729
+ z25.object({
1730
+ event: z25.literal("audit:appended"),
1634
1731
  payload: futurePlaceholderPayloadSchema,
1635
1732
  ...envelopeExtra
1636
1733
  }),
1637
- z24.object({
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: z24.literal("project:state"),
1645
- payload: z24.object({
1646
- projectId: z24.string().min(1),
1647
- paused: z24.boolean(),
1648
- mode: z24.string().min(1),
1649
- reason: z24.string().optional()
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 z25 } from "zod";
1668
- var ImportTargetStatusSchema = z25.enum([
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 = z25.string().trim().min(1).max(100);
1674
- var ImportTaskInputSchema = z25.object({
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: z25.string().trim().min(1).max(60).optional(),
1683
- milestoneId: z25.string().min(1).optional(),
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 = z25.object({
1691
- tasks: z25.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")
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 z26 } from "zod";
1696
- var OrgSettingsSchema = z26.object({}).passthrough();
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 z27 } from "zod";
2929
- var HookCommandEntrySchema = z27.object({
2930
- type: z27.literal("command"),
2931
- command: z27.string().min(1),
2932
- timeout: z27.number().int().positive().optional()
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 = z27.object({
2935
- matcher: z27.string().optional(),
2936
- hooks: z27.array(HookCommandEntrySchema)
3031
+ var HookMatcherGroupSchema = z28.object({
3032
+ matcher: z28.string().optional(),
3033
+ hooks: z28.array(HookCommandEntrySchema)
2937
3034
  }).passthrough();
2938
- var McpServerEntrySchema = z27.object({
2939
- command: z27.string().min(1),
2940
- args: z27.array(z27.string()).optional()
3035
+ var McpServerEntrySchema = z28.object({
3036
+ command: z28.string().min(1),
3037
+ args: z28.array(z28.string()).optional()
2941
3038
  }).passthrough();
2942
- var ClaudeSettingsSchema = z27.object({
2943
- mcpServers: z27.record(z27.string(), McpServerEntrySchema).optional(),
2944
- hooks: z27.record(z27.string(), z27.array(HookMatcherGroupSchema)).optional(),
2945
- env: z27.record(z27.string(), z27.string()).optional()
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 z28 } from "zod";
3147
+ import { z as z29 } from "zod";
3051
3148
  var STATE_SCHEMA_VERSION = 1;
3052
- var CurrentTaskSchema = z28.object({
3053
- taskId: z28.string().min(1),
3149
+ var CurrentTaskSchema = z29.object({
3150
+ taskId: z29.string().min(1),
3054
3151
  /** Человекочитаемый ключ вроде `REL-42` — для текста в хуках. Необязателен: на первых порах может быть неизвестен. */
3055
- taskKey: z28.string().min(1).optional(),
3056
- resumeToken: z28.string().min(1),
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: z28.string().min(1).optional(),
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: z28.enum([GitMode.DIRECT, GitMode.PR]).optional()
3085
- });
3086
- var TrustCacheSchema = z28.object({
3087
- profileKey: z28.string().min(1),
3088
- updatedAt: z28.string(),
3089
- rules: z28.object({
3090
- bash: z28.object({
3091
- mode: z28.enum(["allow", "approve", "deny"]),
3092
- stopPatterns: z28.array(z28.string()).default([]),
3093
- allowPatterns: z28.array(z28.string()).optional()
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: z28.object({
3096
- mode: z28.enum(["allow", "approve"]),
3097
- protectedPaths: z28.array(z28.string()).default([])
3192
+ files: z29.object({
3193
+ mode: z29.enum(["allow", "approve"]),
3194
+ protectedPaths: z29.array(z29.string()).default([])
3098
3195
  }).optional(),
3099
- git: z28.object({ allowPushDefault: z28.boolean(), allowForcePush: z28.boolean() }).optional(),
3100
- network: z28.object({ allowSsh: z28.boolean(), sshHostsAllow: z28.array(z28.string()).optional() }).optional(),
3101
- approvalTtlMin: z28.number().int().positive().optional()
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 = z28.object({
3105
- token: z28.string().min(1),
3106
- command: z28.string().min(1),
3107
- cwd: z28.string().min(1),
3108
- expiresAt: z28.string(),
3109
- createdAt: z28.string()
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 = z28.object({
3112
- command: z28.string().min(1),
3113
- cwd: z28.string().min(1),
3114
- createdAt: z28.string()
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 = z28.enum([AgentMode.AUTONOMOUS, AgentMode.MANUAL]);
3213
+ var AgentModeSchema = z29.enum([AgentMode.AUTONOMOUS, AgentMode.MANUAL]);
3117
3214
  var DEFAULT_CONTEXT_RESET_AFTER_TASKS = ProjectSettingsSchema.parse({}).contextResetAfterTasks;
3118
- var ClientStateSchema = z28.object({
3119
- version: z28.literal(STATE_SCHEMA_VERSION).default(STATE_SCHEMA_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: z28.number().int().nonnegative().default(0),
3220
+ tasksCompletedInSession: z29.number().int().nonnegative().default(0),
3124
3221
  /** Кэш `ProjectSettings.contextResetAfterTasks` (§7.2 ТЗ) — сколько задач подряд можно сдать, прежде чем `Stop`-хук попросит `/clear`. */
3125
- contextResetAfterTasks: z28.number().int().positive().default(DEFAULT_CONTEXT_RESET_AFTER_TASKS),
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: z28.string() }).nullable().default(null),
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: z28.record(z28.string(), ApprovedCommandSchema).default({}),
3228
+ approvedCommands: z29.record(z29.string(), ApprovedCommandSchema).default({}),
3132
3229
  /** Незавершённые запросы подтверждения, ключ — `approvalId`. См. `PendingApprovalSchema`. */
3133
- pendingApprovals: z28.record(z28.string(), PendingApprovalSchema).default({}),
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: z28.string().default(() => (/* @__PURE__ */ new Date()).toISOString())
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 z29 } from "zod";
3297
+ import { z as z30 } from "zod";
3188
3298
  var PROJECT_CONFIG_SCHEMA_VERSION = 1;
3189
- var ProjectConfigSchema = z29.object({
3190
- version: z29.literal(PROJECT_CONFIG_SCHEMA_VERSION).default(PROJECT_CONFIG_SCHEMA_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: z29.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"),
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: z29.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"),
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: z29.string().trim().min(1, "ID \u0430\u0433\u0435\u043D\u0442\u0430 \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u0435\u043D"),
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: z29.string().trim().min(1).optional(),
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: z29.enum(["isolated", "checkout"]).default("isolated")
3341
+ worktrees: z30.enum(["isolated", "checkout"]).default("isolated")
3232
3342
  });
3233
- var CredentialsEntrySchema = z29.object({
3234
- url: z29.string().trim().url(),
3235
- token: z29.string().min(1),
3236
- projectKey: z29.string().min(1),
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: z29.string()
3348
+ savedAt: z30.string()
3239
3349
  });
3240
3350
  var CREDENTIALS_SCHEMA_VERSION = 1;
3241
- var CredentialsFileSchema = z29.object({
3242
- version: z29.literal(CREDENTIALS_SCHEMA_VERSION).default(CREDENTIALS_SCHEMA_VERSION),
3243
- agents: z29.record(z29.string(), CredentialsEntrySchema).default({})
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 z30 } from "zod";
3325
- var McpServerEntrySchema2 = z30.object({
3326
- command: z30.string().min(1).optional(),
3327
- args: z30.array(z30.string()).optional()
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 = z30.object({
3330
- mcpServers: z30.record(z30.string(), McpServerEntrySchema2).optional()
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 z31 } from "zod";
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 = z31.object({
3523
- hooks: z31.record(z31.string(), z31.array(z31.object({}).passthrough())).optional()
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 z32 } from "zod";
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 = z32.object({ command: z32.string().min(1) }).passthrough();
3577
- var CursorHooksFileSchema = z32.object({
3578
- version: z32.number().optional(),
3579
- hooks: z32.record(z32.string(), z32.array(CursorHookEntrySchema)).optional()
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 = z32.object({
3582
- mcpServers: z32.record(z32.string(), z32.object({}).passthrough()).optional()
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 z33 } from "zod";
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 = z33.object({
3697
- $schema: z33.string().optional(),
3698
- mcp: z33.record(z33.string(), z33.object({}).passthrough()).optional()
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
- function sendAuditActions(actions, options = {}) {
3824
- const auditActions = actions.filter((action) => action.type === "audit:command");
3825
- if (auditActions.length === 0) return;
3826
- void dispatch(auditActions, options).catch(() => {
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("audit:command", action.payload);
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 z34 } from "zod";
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 = z34.object({ command: z34.string(), cwd: z34.string().optional() }).passthrough();
3872
- var CursorStopInputSchema = z34.object({ status: z34.string().optional(), loop_count: z34.number().optional() }).passthrough();
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 = z34.object({
3879
- directory: z34.string().optional(),
3880
- input: z34.object({ tool: z34.string().optional() }).passthrough().optional(),
3881
- output: z34.object({ args: z34.record(z34.string(), z34.unknown()).optional() }).passthrough().optional(),
3882
- event: z34.object({ type: z34.string().optional() }).passthrough().optional()
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.4.1",
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.ai",
4800
+ homepage: "https://quiel.app",
4676
4801
  repository: {
4677
4802
  type: "git",
4678
- url: "git+https://github.com/Quiel-AI/quiel-cli.git"
4803
+ url: "git+https://github.com/Quiel-App/quiel-cli.git"
4679
4804
  },
4680
4805
  bugs: {
4681
- url: "https://github.com/Quiel-AI/quiel-cli/issues"
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 z35 } from "zod";
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: z35.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)")
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 z36 } from "zod";
5823
+ import { z as z37 } from "zod";
5700
5824
  var submitWorkInputShape = {
5701
- branchName: z36.string().min(1).describe(
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: z36.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."),
5705
- commitPrefix: z36.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:".'),
5706
- taskKey: z36.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."),
5707
- taskTitle: z36.string().min(1).describe("\u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A \u0437\u0430\u0434\u0430\u0447\u0438 \u2014 \u0438\u0437 task.title."),
5708
- repoRoot: z36.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."),
5709
- testsPassed: z36.boolean().optional().describe(
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: z36.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.")
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 z37 } from "zod";
6186
- var PreCompactInputSchema = z37.object({
6187
- hook_event_name: z37.literal("PreCompact"),
6188
- session_id: z37.string(),
6189
- cwd: z37.string(),
6190
- trigger: z37.enum(["manual", "auto"]),
6191
- custom_instructions: z37.string().nullable()
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 z38 } from "zod";
6201
- var PreToolUseInputSchema = z38.object({
6202
- hook_event_name: z38.literal("PreToolUse"),
6203
- session_id: z38.string(),
6204
- cwd: z38.string(),
6205
- tool_name: z38.string(),
6206
- tool_input: z38.record(z38.string(), z38.unknown()),
6207
- tool_use_id: z38.string()
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 z42 } from "zod";
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 z39 } from "zod";
6356
- var SessionStartInputSchema = z39.object({
6357
- hook_event_name: z39.literal("SessionStart"),
6358
- session_id: z39.string(),
6359
- cwd: z39.string(),
6360
- source: z39.enum(["startup", "resume", "clear", "compact", "fork"]),
6361
- model: z39.string().optional()
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 z40 } from "zod";
6401
- var StopInputSchema = z40.object({
6402
- hook_event_name: z40.literal("Stop"),
6403
- session_id: z40.string(),
6404
- cwd: z40.string(),
6405
- stop_hook_active: z40.boolean(),
6406
- last_assistant_message: z40.string().optional()
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 z41 } from "zod";
6451
- var StopFailureErrorTypeSchema = z41.enum([
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 = z41.object({
6465
- hook_event_name: z41.literal("StopFailure"),
6466
- session_id: z41.string(),
6467
- cwd: z41.string(),
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: z41.unknown().optional(),
6470
- last_assistant_message: z41.string().optional()
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 = z42.discriminatedUnion("hook_event_name", [
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
- if (result.statePatch) {
6514
- writeState({ ...state, ...result.statePatch }, stateFilePath);
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) sendAuditActions(result.execution.serverActions);
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
- sendAuditActions(execution.serverActions);
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"