@quiel/cli 0.1.0 → 0.2.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 (2) hide show
  1. package/dist/cli.js +1015 -653
  2. package/package.json +11 -2
package/dist/cli.js CHANGED
@@ -9,7 +9,7 @@ import { join } from "path";
9
9
  var QUIEL_CLAUDE_MD_HEADING = "## Quiel \u2014 \u0440\u0435\u0436\u0438\u043C \u0430\u0433\u0435\u043D\u0442\u0430";
10
10
  var SECTION_BODY = `\u041A\u043E\u0433\u0434\u0430 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C \u043F\u0440\u043E\u0441\u0438\u0442 \xAB\u0432\u043A\u043B\u044E\u0447\u0438\u0442\u044C \u0440\u0435\u0436\u0438\u043C \u0430\u0433\u0435\u043D\u0442\u0430\xBB, \u0432\u044B\u0437\u043E\u0432\u0438 \`set_mode(auto)\`, \u0437\u0430\u0442\u0435\u043C \`next_task\`.
11
11
  \u0414\u043B\u044F \u043A\u0430\u0436\u0434\u043E\u0439 \u0437\u0430\u0434\u0430\u0447\u0438:
12
- 1. \u0412\u044B\u0437\u043E\u0432\u0438 \`get_context\` \u0438 \u043F\u0440\u043E\u0447\u0438\u0442\u0430\u0439 \u0437\u0430\u0432\u0438\u0441\u0438\u043C\u043E\u0441\u0442\u0438/\u0432\u043E\u043F\u0440\u043E\u0441\u044B.
12
+ 1. \u0412\u044B\u0437\u043E\u0432\u0438 \`get_context\` \u0438 \u043F\u0440\u043E\u0447\u0438\u0442\u0430\u0439 \u0437\u0430\u0432\u0438\u0441\u0438\u043C\u043E\u0441\u0442\u0438/\u0432\u043E\u043F\u0440\u043E\u0441\u044B. \u0415\u0441\u043B\u0438 \u0443 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430 \u043F\u0443\u0441\u0442\u043E\u0439 \`contentMd\`, \u043D\u043E \u0437\u0430\u043F\u043E\u043B\u043D\u0435\u043D \`file\` \u2014 \u0441\u043F\u0435\u0446\u0438\u0444\u0438\u043A\u0430\u0446\u0438\u044F \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043D\u0430 \u0444\u0430\u0439\u043B\u043E\u043C: \u0441\u043A\u0430\u0447\u0430\u0439 \`file.downloadUrl\` \u0438 \u043F\u0440\u043E\u0447\u0438\u0442\u0430\u0439 \u0435\u0433\u043E.
13
13
  2. \`next_task\` \u043D\u0430\u0437\u044B\u0432\u0430\u0435\u0442 \u0440\u0430\u0431\u043E\u0447\u0438\u0439 \u043A\u0430\u0442\u0430\u043B\u043E\u0433 \u0437\u0430\u0434\u0430\u0447\u0438 \u2014 \u0432\u043E\u0439\u0434\u0438 \u0432 \u043D\u0435\u0433\u043E \u0447\u0435\u0440\u0435\u0437 \`EnterWorktree\` \u0438 \u0440\u0430\u0431\u043E\u0442\u0430\u0439 \u0442\u043E\u043B\u044C\u043A\u043E \u0442\u0430\u043C. \u0421\u0432\u043E\u0439 git worktree \u041D\u0415 \u0441\u043E\u0437\u0434\u0430\u0432\u0430\u0439: \u043E\u043D \u0443\u0436\u0435 \u0441\u043E\u0437\u0434\u0430\u043D \u043D\u0430 \u0432\u0435\u0442\u043A\u0435 \`project.branchName\`, \u0430 \u0432\u0442\u043E\u0440\u043E\u0439 \u0440\u0430\u0437\u043E\u0448\u0451\u043B\u0441\u044F \u0431\u044B \u0441 \u0442\u0435\u043C, \u043E\u0442\u043A\u0443\u0434\u0430 \`submit_work\` \u0431\u0435\u0440\u0451\u0442 \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F.
14
14
  3. \u0414\u0435\u043B\u0435\u0433\u0438\u0440\u0443\u0439 \u0432\u044B\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u0435 \u0441\u0443\u0431\u0430\u0433\u0435\u043D\u0442\u0443, \u043F\u0435\u0440\u0435\u0434\u0430\u0432 \u043F\u043E\u043B\u043D\u044B\u0439 TaskPayload. \u0421\u0430\u043C \u043D\u0435 \u043F\u0438\u0448\u0438 \u043A\u043E\u0434 \u0432 \u0433\u043B\u0430\u0432\u043D\u043E\u0439 \u0441\u0435\u0441\u0441\u0438\u0438.
15
15
  4. \u0415\u0441\u043B\u0438 \u0447\u0435\u0433\u043E-\u0442\u043E \u043D\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442 \u043E\u0442 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0430 \u2014 \`ask_human(blocking=true)\`. \u0415\u0441\u043B\u0438 \u043D\u0443\u0436\u043D\u0430 \u0440\u0430\u0431\u043E\u0442\u0430 \u0434\u0440\u0443\u0433\u043E\u0439 \u0440\u043E\u043B\u0438 \u2014 \`create_task\`.
@@ -267,6 +267,30 @@ var maskKeyValue = maskValueGroup(KEY_VALUE_RE);
267
267
  var maskFlagSpace = maskValueGroup(FLAG_SPACE_RE);
268
268
  var maskAuthHeader = maskValueGroup(AUTH_HEADER_RE);
269
269
 
270
+ // ../shared/src/docs/links.ts
271
+ var DocsPage = {
272
+ START: "start",
273
+ ACCESS: "access",
274
+ TASKS: "tasks",
275
+ AGENTS: "agents",
276
+ INTERACTION: "interaction",
277
+ SECURITY: "security",
278
+ GITHUB: "github",
279
+ SETTINGS: "settings",
280
+ REFERENCE: "reference"
281
+ };
282
+ var DOCS_PATHS = {
283
+ [DocsPage.START]: "/docs",
284
+ [DocsPage.ACCESS]: "/docs/access",
285
+ [DocsPage.TASKS]: "/docs/tasks",
286
+ [DocsPage.AGENTS]: "/docs/agents",
287
+ [DocsPage.INTERACTION]: "/docs/collaboration",
288
+ [DocsPage.SECURITY]: "/docs/security",
289
+ [DocsPage.GITHUB]: "/docs/github",
290
+ [DocsPage.SETTINGS]: "/docs/settings",
291
+ [DocsPage.REFERENCE]: "/docs/reference"
292
+ };
293
+
270
294
  // ../shared/src/dto/agent.ts
271
295
  import { z as z5 } from "zod";
272
296
 
@@ -363,6 +387,11 @@ var GitMode = {
363
387
  DIRECT: "DIRECT",
364
388
  PR: "PR"
365
389
  };
390
+ var GitProvider = {
391
+ GITHUB: "GITHUB",
392
+ GITLAB: "GITLAB",
393
+ GENERIC: "GENERIC"
394
+ };
366
395
  var DocumentKind = {
367
396
  SPEC: "SPEC",
368
397
  PLAN: "PLAN",
@@ -530,14 +559,51 @@ var OrganizationMembersListItemSchema = z9.discriminatedUnion("type", [
530
559
  OrganizationInvitationDTOSchema
531
560
  ]);
532
561
 
562
+ // ../shared/src/dto/profile.ts
563
+ import { z as z10 } from "zod";
564
+ var ProfileNameSchema = z10.string().trim().min(1, "\u0423\u043A\u0430\u0436\u0438\u0442\u0435 \u0438\u043C\u044F").max(120);
565
+ var UpdateProfileSchema = z10.object({
566
+ name: ProfileNameSchema
567
+ });
568
+ var ChangePasswordSchema = z10.object({
569
+ currentPassword: z10.string().min(1).max(200).optional(),
570
+ newPassword: PasswordSchema
571
+ });
572
+ var RequestEmailChangeSchema = z10.object({
573
+ newEmail: EmailSchema,
574
+ /** Нужен, если у аккаунта есть пароль — см. `ChangePasswordSchema`. */
575
+ currentPassword: z10.string().min(1).max(200).optional()
576
+ });
577
+ var ConfirmEmailChangeSchema = z10.object({
578
+ token: z10.string().min(1)
579
+ });
580
+ var UpdateAvatarSchema = z10.object({
581
+ fileKey: z10.string().min(1).max(500)
582
+ });
583
+ var ALLOWED_AVATAR_MIME_TYPES = [
584
+ "image/jpeg",
585
+ "image/png",
586
+ "image/webp",
587
+ "image/gif"
588
+ ];
589
+ var MAX_AVATAR_FILE_SIZE_BYTES = 2 * 1024 * 1024;
590
+ var RequestAvatarUploadUrlSchema = z10.object({
591
+ fileName: z10.string().trim().min(1).max(200),
592
+ mimeType: z10.enum(ALLOWED_AVATAR_MIME_TYPES),
593
+ size: z10.number().int().positive().max(MAX_AVATAR_FILE_SIZE_BYTES)
594
+ });
595
+ var UnlinkAccountSchema = z10.object({
596
+ provider: z10.string().trim().min(1).max(50)
597
+ });
598
+
533
599
  // ../shared/src/dto/project.ts
534
- import { z as z13 } from "zod";
600
+ import { z as z14 } from "zod";
535
601
 
536
602
  // ../shared/src/settings/project-settings.ts
537
- import { z as z12 } from "zod";
603
+ import { z as z13 } from "zod";
538
604
 
539
605
  // ../shared/src/dto/task-template.ts
540
- import { z as z11 } from "zod";
606
+ import { z as z12 } from "zod";
541
607
 
542
608
  // ../shared/src/enums/task.ts
543
609
  var TaskType = {
@@ -595,42 +661,42 @@ var EventKind = {
595
661
  };
596
662
 
597
663
  // ../shared/src/dto/task.ts
598
- import { z as z10 } from "zod";
664
+ import { z as z11 } from "zod";
599
665
  var taskTypeValues = Object.values(TaskType);
600
666
  var taskStatusValues = Object.values(TaskStatus);
601
667
  var priorityValues = Object.values(Priority);
602
668
  var executorValues = Object.values(Executor);
603
669
  var testResultValues = Object.values(TestResult);
604
- var TaskTypeSchema = z10.enum(taskTypeValues);
605
- var TaskStatusSchema = z10.enum(taskStatusValues);
606
- var TaskPrioritySchema = z10.enum(priorityValues);
607
- var TaskExecutorSchema = z10.enum(executorValues);
608
- var TaskTestResultSchema = z10.enum(testResultValues);
609
- var TaskTitleSchema = 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(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");
610
- var TaskDescriptionSchema = z10.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");
611
- var TaskLabelSchema = z10.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");
612
- var TaskLabelsSchema = z10.array(TaskLabelSchema).max(30, "\u041D\u0435 \u0431\u043E\u043B\u044C\u0448\u0435 30 \u043C\u0435\u0442\u043E\u043A");
613
- var TaskMetadataSchema = z10.record(z10.string(), z10.unknown());
614
- var TaskAcceptanceSchema = z10.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");
615
- var TaskEstimateMinSchema = z10.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);
616
- var TaskOrderSchema = z10.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");
617
- var TaskResultMdSchema = z10.string().max(5e4);
618
- var TaskResultLinkKindSchema = z10.enum(["pr", "commit", "url"]);
619
- var TaskResultLinkSchema = z10.object({
670
+ var TaskTypeSchema = z11.enum(taskTypeValues);
671
+ var TaskStatusSchema = z11.enum(taskStatusValues);
672
+ var TaskPrioritySchema = z11.enum(priorityValues);
673
+ var TaskExecutorSchema = z11.enum(executorValues);
674
+ var TaskTestResultSchema = z11.enum(testResultValues);
675
+ 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");
676
+ 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");
677
+ 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");
678
+ var TaskLabelsSchema = z11.array(TaskLabelSchema).max(30, "\u041D\u0435 \u0431\u043E\u043B\u044C\u0448\u0435 30 \u043C\u0435\u0442\u043E\u043A");
679
+ var TaskMetadataSchema = z11.record(z11.string(), z11.unknown());
680
+ 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");
681
+ 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);
682
+ 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");
683
+ var TaskResultMdSchema = z11.string().max(5e4);
684
+ var TaskResultLinkKindSchema = z11.enum(["pr", "commit", "url"]);
685
+ var TaskResultLinkSchema = z11.object({
620
686
  kind: TaskResultLinkKindSchema,
621
- url: z10.string().url("\u041D\u0435\u043A\u043E\u0440\u0440\u0435\u043A\u0442\u043D\u044B\u0439 URL"),
622
- label: z10.string().max(200).optional()
687
+ url: z11.string().url("\u041D\u0435\u043A\u043E\u0440\u0440\u0435\u043A\u0442\u043D\u044B\u0439 URL"),
688
+ label: z11.string().max(200).optional()
623
689
  });
624
- var TaskResultLinksSchema = z10.array(TaskResultLinkSchema).max(50);
625
- var TaskLastErrorSchema = z10.string().max(5e3);
626
- var IdSchema = z10.string().min(1);
627
- var CreateTaskSchema = z10.object({
690
+ var TaskResultLinksSchema = z11.array(TaskResultLinkSchema).max(50);
691
+ var TaskLastErrorSchema = z11.string().max(5e3);
692
+ var IdSchema = z11.string().min(1);
693
+ var CreateTaskSchema = z11.object({
628
694
  title: TaskTitleSchema,
629
695
  descriptionMd: TaskDescriptionSchema.default(""),
630
696
  type: TaskTypeSchema.default(TaskType.FEATURE),
631
697
  priority: TaskPrioritySchema.default(Priority.P2),
632
698
  executor: TaskExecutorSchema.default(Executor.ANY),
633
- roleKey: z10.string().min(1).max(60).optional(),
699
+ roleKey: z11.string().min(1).max(60).optional(),
634
700
  assigneeId: IdSchema.optional(),
635
701
  milestoneId: IdSchema.optional(),
636
702
  parentId: IdSchema.optional(),
@@ -638,19 +704,19 @@ var CreateTaskSchema = z10.object({
638
704
  metadata: TaskMetadataSchema.default({}),
639
705
  acceptance: TaskAcceptanceSchema.optional(),
640
706
  estimateMin: TaskEstimateMinSchema.optional(),
641
- dueAt: z10.coerce.date().optional(),
707
+ dueAt: z11.coerce.date().optional(),
642
708
  /** Позиция в колонке BACKLOG; если не передан — сервер ставит в конец (apps/web/src/lib/tasks/order.ts). */
643
709
  order: TaskOrderSchema.optional()
644
710
  });
645
- var UpdateTaskSchema = z10.object({
711
+ var UpdateTaskSchema = z11.object({
646
712
  title: TaskTitleSchema.optional(),
647
713
  descriptionMd: TaskDescriptionSchema.optional(),
648
714
  type: TaskTypeSchema.optional(),
649
715
  status: TaskStatusSchema.optional(),
650
- statusComment: z10.string().max(2e4).optional(),
716
+ statusComment: z11.string().max(2e4).optional(),
651
717
  priority: TaskPrioritySchema.optional(),
652
718
  executor: TaskExecutorSchema.optional(),
653
- roleKey: z10.string().min(1).max(60).nullable().optional(),
719
+ roleKey: z11.string().min(1).max(60).nullable().optional(),
654
720
  assigneeId: IdSchema.nullable().optional(),
655
721
  milestoneId: IdSchema.nullable().optional(),
656
722
  parentId: IdSchema.nullable().optional(),
@@ -658,7 +724,7 @@ var UpdateTaskSchema = z10.object({
658
724
  metadata: TaskMetadataSchema.optional(),
659
725
  acceptance: TaskAcceptanceSchema.nullable().optional(),
660
726
  estimateMin: TaskEstimateMinSchema.nullable().optional(),
661
- dueAt: z10.coerce.date().nullable().optional(),
727
+ dueAt: z11.coerce.date().nullable().optional(),
662
728
  order: TaskOrderSchema.optional(),
663
729
  resultMd: TaskResultMdSchema.nullable().optional(),
664
730
  resultLinks: TaskResultLinksSchema.nullable().optional(),
@@ -669,55 +735,55 @@ var UpdateTaskSchema = z10.object({
669
735
  });
670
736
  var TASK_LIST_DEFAULT_LIMIT = 25;
671
737
  var TASK_LIST_MAX_LIMIT = 100;
672
- var TaskListQuerySchema = z10.object({
673
- status: z10.string().max(500).optional(),
674
- role: z10.string().max(500).optional(),
675
- assignee: z10.string().max(500).optional(),
676
- milestone: z10.string().max(500).optional(),
677
- label: z10.string().max(500).optional(),
738
+ var TaskListQuerySchema = z11.object({
739
+ status: z11.string().max(500).optional(),
740
+ role: z11.string().max(500).optional(),
741
+ assignee: z11.string().max(500).optional(),
742
+ milestone: z11.string().max(500).optional(),
743
+ label: z11.string().max(500).optional(),
678
744
  // §16.3 ТЗ перечисляет приоритет и тип среди фильтров доски и списка.
679
745
  // Без них интерфейсу пришлось бы фильтровать уже загруженную страницу —
680
746
  // на проекте крупнее одной страницы это даёт неверный результат.
681
- priority: z10.string().max(100).optional(),
682
- type: z10.string().max(200).optional(),
683
- q: z10.string().trim().max(200).optional(),
684
- cursor: z10.string().max(4e3).optional(),
685
- limit: z10.coerce.number().int().min(1).max(TASK_LIST_MAX_LIMIT).default(TASK_LIST_DEFAULT_LIMIT)
686
- });
687
- var BulkTaskIdsSchema = z10.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");
688
- var BulkTaskActionSchema = z10.discriminatedUnion("action", [
689
- z10.object({
690
- action: z10.literal("status"),
747
+ priority: z11.string().max(100).optional(),
748
+ type: z11.string().max(200).optional(),
749
+ q: z11.string().trim().max(200).optional(),
750
+ cursor: z11.string().max(4e3).optional(),
751
+ limit: z11.coerce.number().int().min(1).max(TASK_LIST_MAX_LIMIT).default(TASK_LIST_DEFAULT_LIMIT)
752
+ });
753
+ 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");
754
+ var BulkTaskActionSchema = z11.discriminatedUnion("action", [
755
+ z11.object({
756
+ action: z11.literal("status"),
691
757
  taskIds: BulkTaskIdsSchema,
692
758
  status: TaskStatusSchema,
693
- comment: z10.string().max(2e4).optional()
759
+ comment: z11.string().max(2e4).optional()
694
760
  }),
695
- z10.object({
696
- action: z10.literal("milestone"),
761
+ z11.object({
762
+ action: z11.literal("milestone"),
697
763
  taskIds: BulkTaskIdsSchema,
698
764
  milestoneId: IdSchema.nullable()
699
765
  }),
700
- z10.object({
701
- action: z10.literal("role"),
766
+ z11.object({
767
+ action: z11.literal("role"),
702
768
  taskIds: BulkTaskIdsSchema,
703
- roleKey: z10.string().min(1).max(60).nullable()
769
+ roleKey: z11.string().min(1).max(60).nullable()
704
770
  }),
705
- z10.object({
706
- action: z10.literal("delete"),
771
+ z11.object({
772
+ action: z11.literal("delete"),
707
773
  taskIds: BulkTaskIdsSchema
708
774
  })
709
775
  ]);
710
- var BulkTaskResultItemSchema = z10.object({
711
- taskId: z10.string(),
712
- ok: z10.boolean(),
713
- error: z10.object({ code: z10.string(), message: z10.string() }).optional()
776
+ var BulkTaskResultItemSchema = z11.object({
777
+ taskId: z11.string(),
778
+ ok: z11.boolean(),
779
+ error: z11.object({ code: z11.string(), message: z11.string() }).optional()
714
780
  });
715
781
 
716
782
  // ../shared/src/dto/task-template.ts
717
- var TaskTemplateNameSchema = 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(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");
718
- var TaskTemplateSchema = z11.object({
783
+ 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");
784
+ var TaskTemplateSchema = z12.object({
719
785
  /** Генерируется сервером при создании (`crypto.randomUUID()`), не вводится человеком. */
720
- id: z11.string().min(1),
786
+ id: z12.string().min(1),
721
787
  /** Имя шаблона в списке выбора — НЕ заголовок будущей задачи (то поле — `title` ниже). */
722
788
  name: TaskTemplateNameSchema,
723
789
  type: TaskTypeSchema,
@@ -731,7 +797,7 @@ var TaskTemplateSchema = z11.object({
731
797
  descriptionMd: TaskDescriptionSchema.default(""),
732
798
  priority: TaskPrioritySchema.default(Priority.P2),
733
799
  executor: TaskExecutorSchema.default(Executor.ANY),
734
- roleKey: z11.string().min(1).max(60).optional(),
800
+ roleKey: z12.string().min(1).max(60).optional(),
735
801
  labels: TaskLabelsSchema.default([]),
736
802
  acceptance: TaskAcceptanceSchema.optional(),
737
803
  estimateMin: TaskEstimateMinSchema.optional()
@@ -747,30 +813,69 @@ var TaskTemplateSchema = z11.object({
747
813
  // метаданные — редкий случай для многоразового шаблона, при
748
814
  // необходимости человек добавит их на созданной задаче.
749
815
  });
750
- var TaskTemplatesSchema = z11.array(TaskTemplateSchema).max(50, "\u041D\u0435 \u0431\u043E\u043B\u044C\u0448\u0435 50 \u0448\u0430\u0431\u043B\u043E\u043D\u043E\u0432");
816
+ var TaskTemplatesSchema = z12.array(TaskTemplateSchema).max(50, "\u041D\u0435 \u0431\u043E\u043B\u044C\u0448\u0435 50 \u0448\u0430\u0431\u043B\u043E\u043D\u043E\u0432");
751
817
  var TaskTemplateInputSchema = TaskTemplateSchema.omit({ id: true });
752
818
 
753
819
  // ../shared/src/settings/project-settings.ts
754
820
  var taskStatusValues2 = Object.values(TaskStatus);
755
- var TaskStatusSchema2 = z12.enum(taskStatusValues2);
756
- var BoardSettingsSchema = z12.object({
757
- hiddenStatuses: z12.array(TaskStatusSchema2).default([]),
758
- mergedColumns: z12.array(z12.array(TaskStatusSchema2)).default([])
759
- });
760
- var NotificationSettingsSchema = z12.object({
761
- telegram: z12.boolean().default(false),
762
- email: z12.boolean().default(false)
763
- });
764
- var ProjectSettingsSchema = z12.object({
765
- autoAccept: z12.boolean().default(false),
766
- requireTests: z12.boolean().default(true),
767
- maxParallelTasksPerAgent: z12.number().int().positive().default(1),
768
- leaseTtlSec: z12.number().int().positive().default(120),
769
- taskTimeoutMin: z12.number().int().positive().default(90),
770
- contextResetAfterTasks: z12.number().int().positive().default(8),
771
- branchTemplate: z12.string().min(1).default("task/{key}-{slug}"),
772
- commitTemplate: z12.string().min(1).default("{key}: {title}"),
773
- stopPatternsOverride: z12.array(z12.string()).optional(),
821
+ var TaskStatusSchema2 = z13.enum(taskStatusValues2);
822
+ var BoardSettingsSchema = z13.object({
823
+ hiddenStatuses: z13.array(TaskStatusSchema2).default([]),
824
+ mergedColumns: z13.array(z13.array(TaskStatusSchema2)).default([])
825
+ });
826
+ var NotificationSettingsSchema = z13.object({
827
+ telegram: z13.boolean().default(false),
828
+ email: z13.boolean().default(false)
829
+ });
830
+ var ProjectSettingsSchema = z13.object({
831
+ autoAccept: z13.boolean().default(false),
832
+ requireTests: z13.boolean().default(true),
833
+ /**
834
+ * Не давать человеку принять задачу, пока проверки GitHub по последнему
835
+ * коммиту красные.
836
+ *
837
+ * В §7.2 ТЗ этого поля нет — добавлено по просьбе владельца 10 сентября
838
+ * 2026 («статус проверок → блокировка приёмки»). По духу это то же, что
839
+ * branch protection на стороне GitHub, только для приёмки задачи.
840
+ *
841
+ * **Дефолт `false`.** Включённым по умолчанию оно сломало бы уже
842
+ * работающие проекты: у проекта без подключённого GitHub проверок нет
843
+ * вовсе, и любая приёмка внезапно перестала бы проходить. §22.12 ТЗ
844
+ * велит выбирать более безопасный вариант — здесь безопаснее не менять
845
+ * поведение существующих проектов молча.
846
+ *
847
+ * **Касается только приёмки человеком.** Авто-приёмка по отчёту агента
848
+ * происходит раньше, чем проверки успевают запуститься, а авто-приёмка
849
+ * по merge означает, что GitHub слияние УЖЕ разрешил. Блокировать их
850
+ * значило бы навсегда подвесить задачи. Это записано и в подсказке к
851
+ * настройке — иначе получилось бы обещание, которого настройка не
852
+ * держит.
853
+ */
854
+ requireGreenChecks: z13.boolean().default(false),
855
+ /**
856
+ * Заводить задачу на ревью, когда для задачи открывается pull request.
857
+ *
858
+ * В §7.2 ТЗ этого поля нет — добавлено по просьбе владельца 10 сентября
859
+ * 2026. Без него открытый PR висит, пока кто-нибудь не заметит: платформа
860
+ * знает о нём, а в списке дел он не появляется.
861
+ *
862
+ * Дефолт `false` по той же причине, что у `requireGreenChecks`: молча
863
+ * начать плодить задачи в уже работающих проектах — не то, чего от
864
+ * обновления ждут.
865
+ */
866
+ reviewTaskOnPr: z13.boolean().default(false),
867
+ /**
868
+ * Ключ роли, на которую вешается задача ревью (`RoleDefinition.key`).
869
+ * Пусто — задача заводится без роли и видна всей команде проекта.
870
+ */
871
+ reviewRoleKey: z13.string().trim().min(1).max(60).optional(),
872
+ maxParallelTasksPerAgent: z13.number().int().positive().default(1),
873
+ leaseTtlSec: z13.number().int().positive().default(120),
874
+ taskTimeoutMin: z13.number().int().positive().default(90),
875
+ contextResetAfterTasks: z13.number().int().positive().default(8),
876
+ branchTemplate: z13.string().min(1).default("task/{key}-{slug}"),
877
+ commitTemplate: z13.string().min(1).default("{key}: {title}"),
878
+ stopPatternsOverride: z13.array(z13.string()).optional(),
774
879
  notifications: NotificationSettingsSchema.default({ telegram: false, email: false }),
775
880
  board: BoardSettingsSchema.default({ hiddenStatuses: [], mergedColumns: [] }),
776
881
  // Шаблоны задач (§16.3 ТЗ: «Шаблоны задач по типу (настраиваются в
@@ -780,55 +885,80 @@ var ProjectSettingsSchema = z12.object({
780
885
  });
781
886
 
782
887
  // ../shared/src/dto/project.ts
783
- var ProjectKeySchema = z13.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");
784
- var ProjectNameSchema = 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");
785
- var ProjectDescriptionSchema = z13.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");
888
+ 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");
889
+ 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");
890
+ 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");
786
891
  var ProjectSettingsRecordSchema = ProjectSettingsSchema.extend({
787
- autonomousConfirmedAt: z13.coerce.date().optional()
892
+ autonomousConfirmedAt: z14.coerce.date().optional()
788
893
  });
789
894
  var UpdateProjectSettingsSchema = ProjectSettingsRecordSchema.partial();
790
- var ProjectModeSchema = z13.enum([ProjectMode.AUTONOMOUS, ProjectMode.APPROVAL]);
791
- var ProjectStatusSchema = z13.enum([
895
+ var ProjectModeSchema = z14.enum([ProjectMode.AUTONOMOUS, ProjectMode.APPROVAL]);
896
+ var ProjectStatusSchema = z14.enum([
792
897
  ProjectStatus.ACTIVE,
793
898
  ProjectStatus.PAUSED,
794
899
  ProjectStatus.ARCHIVED
795
900
  ]);
796
- var GitModeSchema = z13.enum([GitMode.DIRECT, GitMode.PR]);
797
- var CreateProjectSchema = z13.object({
901
+ var GitModeSchema = z14.enum([GitMode.DIRECT, GitMode.PR]);
902
+ var ProjectDateSchema = z14.coerce.date();
903
+ var NewProjectMilestoneSchema = z14.object({
904
+ name: z14.string().trim().min(1, "\u0423\u043A\u0430\u0436\u0438\u0442\u0435 \u043D\u0430\u0437\u0432\u0430\u043D\u0438\u0435").max(200),
905
+ dueAt: ProjectDateSchema.optional()
906
+ });
907
+ var CreateProjectSchema = z14.object({
798
908
  name: ProjectNameSchema,
799
909
  key: ProjectKeySchema.optional(),
800
910
  description: ProjectDescriptionSchema.optional(),
801
911
  mode: ProjectModeSchema.default(ProjectMode.APPROVAL),
802
912
  gitMode: GitModeSchema.default(GitMode.DIRECT),
803
- autonomousConfirmed: z13.boolean().optional()
804
- });
805
- var UpdateProjectSchema = z13.object({
913
+ autonomousConfirmed: z14.boolean().optional(),
914
+ startAt: ProjectDateSchema.optional(),
915
+ targetAt: ProjectDateSchema.optional(),
916
+ /**
917
+ * Участники проекта — идентификаторы `Membership` в этой организации.
918
+ * Добавляются той же транзакцией, что и сам проект: иначе при сбое
919
+ * второго запроса проект оставался бы без людей, и человек не понял
920
+ * бы, создался он или нет.
921
+ */
922
+ memberIds: z14.array(z14.string().min(1)).max(100).optional(),
923
+ milestones: z14.array(NewProjectMilestoneSchema).max(50).optional()
924
+ }).refine((data) => !data.startAt || !data.targetAt || data.startAt <= data.targetAt, {
925
+ // Срок раньше начала — почти всегда опечатка в одном из полей, и
926
+ // молча сохранённая, она потом показывается как «просрочен с первого дня».
927
+ 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",
928
+ path: ["targetAt"]
929
+ });
930
+ var UpdateProjectSchema = z14.object({
806
931
  name: ProjectNameSchema.optional(),
807
932
  key: ProjectKeySchema.optional(),
808
933
  description: ProjectDescriptionSchema.nullable().optional(),
809
934
  status: ProjectStatusSchema.optional(),
810
935
  mode: ProjectModeSchema.optional(),
811
936
  gitMode: GitModeSchema.optional(),
937
+ startAt: ProjectDateSchema.nullable().optional(),
938
+ targetAt: ProjectDateSchema.nullable().optional(),
812
939
  settings: UpdateProjectSettingsSchema.optional(),
813
- autonomousConfirmed: z13.boolean().optional()
940
+ autonomousConfirmed: z14.boolean().optional()
814
941
  }).refine((data) => Object.keys(data).length > 0, {
815
942
  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
943
  });
817
944
 
818
945
  // ../shared/src/dto/repository.ts
819
- import { z as z14 } from "zod";
820
- var RepositoryUrlSchema = z14.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(
946
+ import { z as z15 } from "zod";
947
+ 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(
821
948
  (value) => /^(https?:\/\/|ssh:\/\/|git@)/.test(value),
822
949
  "\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@"
950
+ ).refine(
951
+ (value) => inferGitProvider(value) !== GitProvider.GITHUB,
952
+ "\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"
823
953
  );
824
- var DefaultBranchSchema = z14.string().trim().min(1).max(200);
825
- var PathHintSchema = z14.string().trim().max(300);
826
- var CreateRepositorySchema = z14.object({
954
+ var DefaultBranchSchema = z15.string().trim().min(1).max(200);
955
+ var PathHintSchema = z15.string().trim().max(300);
956
+ var CreateRepositorySchema = z15.object({
827
957
  url: RepositoryUrlSchema,
828
958
  defaultBranch: DefaultBranchSchema.optional(),
829
959
  pathHint: PathHintSchema.optional()
830
960
  });
831
- var UpdateRepositorySchema = z14.object({
961
+ var UpdateRepositorySchema = z15.object({
832
962
  url: RepositoryUrlSchema.optional(),
833
963
  defaultBranch: DefaultBranchSchema.optional(),
834
964
  // `null` — «убрать путь», отличается от «поле не прислали».
@@ -836,41 +966,74 @@ var UpdateRepositorySchema = z14.object({
836
966
  }).refine((data) => Object.keys(data).length > 0, {
837
967
  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"
838
968
  });
969
+ var ConnectGithubRepositorySchema = z15.object({
970
+ /** Идентификатор НАШЕЙ записи установки, а не номер установки в GitHub. */
971
+ installationId: z15.string().min(1, "\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0430\u043A\u043A\u0430\u0443\u043D\u0442 GitHub"),
972
+ /** `owner/repo` — ровно в том виде, в каком его отдал GitHub. */
973
+ 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"),
974
+ pathHint: PathHintSchema.optional()
975
+ });
976
+ function extractHost(url) {
977
+ const authority = /^[a-z][a-z0-9+.-]*:\/\/([^/\\?#]*)/i.exec(url)?.[1];
978
+ if (authority === void 0) return void 0;
979
+ const afterUserinfo = authority.slice(authority.lastIndexOf("@") + 1);
980
+ const host = afterUserinfo.replace(/:\d*$/, "");
981
+ return host.length > 0 ? host.toLowerCase() : void 0;
982
+ }
983
+ function inferGitProvider(url) {
984
+ const trimmed = url.trim();
985
+ const scpLike = /^git@([^:/]+):/.exec(trimmed);
986
+ const host = scpLike?.[1] ? scpLike[1].toLowerCase() : extractHost(trimmed);
987
+ if (!host) return GitProvider.GENERIC;
988
+ if (host === "github.com" || host.endsWith(".github.com")) return GitProvider.GITHUB;
989
+ if (host === "gitlab.com" || host.endsWith(".gitlab.com")) return GitProvider.GITLAB;
990
+ return GitProvider.GENERIC;
991
+ }
839
992
 
840
993
  // ../shared/src/dto/role.ts
841
- import { z as z15 } from "zod";
842
- var RoleNameSchema = 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(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");
843
- var RoleColorSchema = z15.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");
844
- var CreateRoleSchema = z15.object({
994
+ import { z as z16 } from "zod";
995
+ 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");
996
+ 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");
997
+ var CreateRoleSchema = z16.object({
845
998
  name: RoleNameSchema,
846
999
  color: RoleColorSchema,
847
- defaultTrustProfileId: z15.string().optional()
1000
+ defaultTrustProfileId: z16.string().optional()
848
1001
  });
849
- var UpdateRoleSchema = z15.object({
1002
+ var UpdateRoleSchema = z16.object({
850
1003
  name: RoleNameSchema.optional(),
851
1004
  color: RoleColorSchema.optional(),
852
- defaultTrustProfileId: z15.string().nullable().optional()
1005
+ defaultTrustProfileId: z16.string().nullable().optional()
853
1006
  }).refine((data) => Object.keys(data).length > 0, {
854
1007
  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"
855
1008
  });
856
1009
 
857
1010
  // ../shared/src/dto/saved-filter.ts
858
- import { z as z16 } from "zod";
859
- var SavedFilterNameSchema = 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(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");
860
- var SavedFilterQuerySchema = z16.object({
861
- roles: z16.array(z16.string().min(1)).max(50).default([]),
862
- assignees: z16.array(z16.string().min(1)).max(50).default([]),
863
- milestones: z16.array(z16.string().min(1)).max(50).default([]),
864
- labels: z16.array(TaskLabelSchema).max(30).default([]),
865
- priorities: z16.array(TaskPrioritySchema).max(4).default([]),
866
- types: z16.array(TaskTypeSchema).max(7).default([]),
867
- q: z16.string().trim().max(200).default("")
868
- });
869
- var CreateSavedFilterSchema = z16.object({
1011
+ import { z as z17 } from "zod";
1012
+ 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");
1013
+ var SavedFilterQuerySchema = z17.object({
1014
+ /**
1015
+ * Статусы задач. Появились позже остальных полей — 11 сентября 2026,
1016
+ * когда список и доска стали двумя видами одной страницы: у списка
1017
+ * фильтр по статусу был, у доски нет, и после объединения он общий.
1018
+ *
1019
+ * `.default([])` здесь обязателен, а не для красоты: записи, созданные
1020
+ * до этого дня, поля не содержат вовсе, и без значения по умолчанию
1021
+ * разбор ронял бы чужой сохранённый фильтр.
1022
+ */
1023
+ statuses: z17.array(TaskStatusSchema).max(11).default([]),
1024
+ roles: z17.array(z17.string().min(1)).max(50).default([]),
1025
+ assignees: z17.array(z17.string().min(1)).max(50).default([]),
1026
+ milestones: z17.array(z17.string().min(1)).max(50).default([]),
1027
+ labels: z17.array(TaskLabelSchema).max(30).default([]),
1028
+ priorities: z17.array(TaskPrioritySchema).max(4).default([]),
1029
+ types: z17.array(TaskTypeSchema).max(7).default([]),
1030
+ q: z17.string().trim().max(200).default("")
1031
+ });
1032
+ var CreateSavedFilterSchema = z17.object({
870
1033
  name: SavedFilterNameSchema,
871
1034
  query: SavedFilterQuerySchema
872
1035
  });
873
- var UpdateSavedFilterSchema = z16.object({
1036
+ var UpdateSavedFilterSchema = z17.object({
874
1037
  name: SavedFilterNameSchema.optional(),
875
1038
  query: SavedFilterQuerySchema.optional()
876
1039
  }).refine((data) => Object.keys(data).length > 0, {
@@ -878,20 +1041,20 @@ var UpdateSavedFilterSchema = z16.object({
878
1041
  });
879
1042
 
880
1043
  // ../shared/src/dto/task-dependency.ts
881
- import { z as z17 } from "zod";
882
- var TaskDependencyKindSchema = z17.enum([DepKind.BLOCKS, DepKind.RELATES]);
883
- var IdSchema2 = z17.string().min(1);
884
- var CreateTaskDependencySchema = z17.object({
1044
+ import { z as z18 } from "zod";
1045
+ var TaskDependencyKindSchema = z18.enum([DepKind.BLOCKS, DepKind.RELATES]);
1046
+ var IdSchema2 = z18.string().min(1);
1047
+ var CreateTaskDependencySchema = z18.object({
885
1048
  toId: IdSchema2,
886
1049
  kind: TaskDependencyKindSchema.default(DepKind.BLOCKS)
887
1050
  });
888
- var DeleteTaskDependencySchema = z17.object({
1051
+ var DeleteTaskDependencySchema = z18.object({
889
1052
  toId: IdSchema2
890
1053
  });
891
1054
 
892
1055
  // ../shared/src/dto/task-event.ts
893
- import { z as z18 } from "zod";
894
- var TaskEventKindSchema = z18.enum([
1056
+ import { z as z19 } from "zod";
1057
+ var TaskEventKindSchema = z19.enum([
895
1058
  EventKind.COMMENT,
896
1059
  EventKind.STATUS,
897
1060
  EventKind.ASSIGN,
@@ -902,58 +1065,58 @@ var TaskEventKindSchema = z18.enum([
902
1065
  EventKind.APPROVAL,
903
1066
  EventKind.SYSTEM
904
1067
  ]);
905
- var TaskCommentBodySchema = z18.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");
906
- var CreateTaskEventSchema = z18.object({
1068
+ 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");
1069
+ var CreateTaskEventSchema = z19.object({
907
1070
  bodyMd: TaskCommentBodySchema
908
1071
  });
909
- var TaskCommentPayloadSchema = z18.object({ bodyMd: TaskCommentBodySchema });
910
- var TaskEditPayloadSchema = z18.object({
911
- fields: z18.record(z18.string(), z18.object({ from: z18.unknown(), to: z18.unknown() }))
1072
+ var TaskCommentPayloadSchema = z19.object({ bodyMd: TaskCommentBodySchema });
1073
+ var TaskEditPayloadSchema = z19.object({
1074
+ fields: z19.record(z19.string(), z19.object({ from: z19.unknown(), to: z19.unknown() }))
912
1075
  });
913
- var TaskAssignPayloadSchema = z18.object({
914
- from: z18.string().nullable(),
915
- to: z18.string().nullable()
1076
+ var TaskAssignPayloadSchema = z19.object({
1077
+ from: z19.string().nullable(),
1078
+ to: z19.string().nullable()
916
1079
  });
917
1080
  var TASK_EVENT_LIST_DEFAULT_LIMIT = 25;
918
1081
  var TASK_EVENT_LIST_MAX_LIMIT = 100;
919
- var ListTaskEventsQuerySchema = z18.object({
1082
+ var ListTaskEventsQuerySchema = z19.object({
920
1083
  /** CSV нескольких kind — как остальные CSV-фильтры задач (lib/tasks/filters.ts). */
921
- kind: z18.string().max(300).optional(),
922
- cursor: z18.string().max(4e3).optional(),
923
- limit: z18.coerce.number().int().min(1).max(TASK_EVENT_LIST_MAX_LIMIT).default(TASK_EVENT_LIST_DEFAULT_LIMIT)
1084
+ kind: z19.string().max(300).optional(),
1085
+ cursor: z19.string().max(4e3).optional(),
1086
+ limit: z19.coerce.number().int().min(1).max(TASK_EVENT_LIST_MAX_LIMIT).default(TASK_EVENT_LIST_DEFAULT_LIMIT)
924
1087
  });
925
1088
 
926
1089
  // ../shared/src/dto/task-transition.ts
927
- import { z as z19 } from "zod";
928
- var CommentSchema = z19.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");
929
- var TransitionTaskSchema = z19.object({
1090
+ import { z as z20 } from "zod";
1091
+ 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");
1092
+ var TransitionTaskSchema = z20.object({
930
1093
  to: TaskStatusSchema,
931
1094
  comment: CommentSchema.optional()
932
1095
  });
933
- var AcceptTaskSchema = z19.object({
1096
+ var AcceptTaskSchema = z20.object({
934
1097
  comment: CommentSchema.optional()
935
1098
  });
936
- var ReturnTaskSchema = z19.object({
1099
+ var ReturnTaskSchema = z20.object({
937
1100
  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")
938
1101
  });
939
- var ReopenTaskSchema = z19.object({
1102
+ var ReopenTaskSchema = z20.object({
940
1103
  reason: CommentSchema.optional()
941
1104
  });
942
- var RequeueTaskSchema = z19.object({
1105
+ var RequeueTaskSchema = z20.object({
943
1106
  reason: CommentSchema.optional()
944
1107
  });
945
1108
 
946
1109
  // ../shared/src/dto/trash.ts
947
- import { z as z20 } from "zod";
948
- var CommentSchema2 = 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");
949
- var RestoreTaskSchema = z20.object({
1110
+ import { z as z21 } from "zod";
1111
+ 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");
1112
+ var RestoreTaskSchema = z21.object({
950
1113
  comment: CommentSchema2.optional()
951
1114
  });
952
1115
  var TASK_TRASH_LIST_DEFAULT_LIMIT = 25;
953
1116
  var TASK_TRASH_LIST_MAX_LIMIT = 100;
954
- var TaskTrashListQuerySchema = z20.object({
955
- cursor: z20.string().max(4e3).optional(),
956
- limit: z20.coerce.number().int().min(1).max(TASK_TRASH_LIST_MAX_LIMIT).default(TASK_TRASH_LIST_DEFAULT_LIMIT)
1117
+ var TaskTrashListQuerySchema = z21.object({
1118
+ cursor: z21.string().max(4e3).optional(),
1119
+ limit: z21.coerce.number().int().min(1).max(TASK_TRASH_LIST_MAX_LIMIT).default(TASK_TRASH_LIST_DEFAULT_LIMIT)
957
1120
  });
958
1121
 
959
1122
  // ../shared/src/enums/collaboration.ts
@@ -980,8 +1143,25 @@ var AuditDecision = {
980
1143
  ASKED: "ASKED"
981
1144
  };
982
1145
 
1146
+ // ../shared/src/enums/github.ts
1147
+ var CheckConclusion = {
1148
+ SUCCESS: "SUCCESS",
1149
+ FAILURE: "FAILURE",
1150
+ NEUTRAL: "NEUTRAL",
1151
+ CANCELLED: "CANCELLED",
1152
+ TIMED_OUT: "TIMED_OUT",
1153
+ ACTION_REQUIRED: "ACTION_REQUIRED",
1154
+ SKIPPED: "SKIPPED",
1155
+ STALE: "STALE"
1156
+ };
1157
+ var FAILING_CHECK_CONCLUSIONS = [
1158
+ CheckConclusion.FAILURE,
1159
+ CheckConclusion.TIMED_OUT,
1160
+ CheckConclusion.ACTION_REQUIRED
1161
+ ];
1162
+
983
1163
  // ../shared/src/events/agent-events.ts
984
- import { z as z21 } from "zod";
1164
+ import { z as z22 } from "zod";
985
1165
  var agentStatusValues = Object.values(AgentStatus);
986
1166
  var agentModeValues = Object.values(AgentMode);
987
1167
  var taskStatusValues3 = Object.values(TaskStatus);
@@ -994,552 +1174,590 @@ var gitModeValues = Object.values(GitMode);
994
1174
  var questionStatusValues = Object.values(QuestionStatus);
995
1175
  var approvalKindValues = Object.values(ApprovalKind);
996
1176
  var approvalStatusValues = Object.values(ApprovalStatus);
997
- var trustBashModeSchema = z21.enum(["allow", "approve", "deny"]);
998
- var trustFilesModeSchema = z21.enum(["allow", "approve"]);
999
- var trustRulesSchema = z21.object({
1000
- bash: z21.object({
1177
+ var trustBashModeSchema = z22.enum(["allow", "approve", "deny"]);
1178
+ var trustFilesModeSchema = z22.enum(["allow", "approve"]);
1179
+ var trustRulesSchema = z22.object({
1180
+ bash: z22.object({
1001
1181
  mode: trustBashModeSchema,
1002
1182
  // Regex-строки (§14.3 ТЗ) — не z.instanceof(RegExp): TrustRules это Json,
1003
1183
  // должен сериализоваться в БД/по сокету как обычные строки.
1004
- stopPatterns: z21.array(z21.string().min(1)),
1005
- allowPatterns: z21.array(z21.string().min(1)).optional()
1184
+ stopPatterns: z22.array(z22.string().min(1)),
1185
+ allowPatterns: z22.array(z22.string().min(1)).optional()
1006
1186
  }),
1007
- files: z21.object({
1187
+ files: z22.object({
1008
1188
  mode: trustFilesModeSchema,
1009
- protectedPaths: z21.array(z21.string().min(1))
1189
+ protectedPaths: z22.array(z22.string().min(1))
1010
1190
  }),
1011
- git: z21.object({
1012
- allowPushDefault: z21.boolean(),
1013
- allowForcePush: z21.boolean()
1191
+ git: z22.object({
1192
+ allowPushDefault: z22.boolean(),
1193
+ allowForcePush: z22.boolean()
1014
1194
  }),
1015
- network: z21.object({
1016
- allowSsh: z21.boolean(),
1017
- sshHostsAllow: z21.array(z21.string().min(1)).optional()
1195
+ network: z22.object({
1196
+ allowSsh: z22.boolean(),
1197
+ sshHostsAllow: z22.array(z22.string().min(1)).optional()
1018
1198
  }),
1019
- approvalTtlMin: z21.number().int().positive()
1020
- });
1021
- var agentSummarySchema = z21.object({
1022
- id: z21.string().min(1),
1023
- projectId: z21.string().min(1),
1024
- membershipId: z21.string().min(1),
1025
- name: z21.string().min(1),
1026
- roleKeys: z21.array(z21.string().min(1)),
1027
- status: z21.enum(agentStatusValues),
1028
- mode: z21.enum(agentModeValues),
1029
- lastSeenAt: z21.string().datetime().nullable(),
1030
- clientVersion: z21.string().nullable(),
1031
- currentTaskId: z21.string().nullable(),
1032
- tasksCompletedInSession: z21.number().int().nonnegative()
1033
- });
1034
- var agentCurrentTaskSummarySchema = z21.object({
1035
- id: z21.string().min(1),
1036
- number: z21.number().int().positive(),
1037
- title: z21.string().min(1),
1038
- status: z21.enum(taskStatusValues3)
1039
- });
1040
- var agentHelloPayloadSchema = z21.object({
1041
- clientVersion: z21.string().min(1),
1042
- cwd: z21.string().min(1),
1043
- os: z21.string().min(1),
1044
- claudeVersion: z21.string().min(1),
1199
+ approvalTtlMin: z22.number().int().positive()
1200
+ });
1201
+ var agentSummarySchema = z22.object({
1202
+ id: z22.string().min(1),
1203
+ projectId: z22.string().min(1),
1204
+ membershipId: z22.string().min(1),
1205
+ name: z22.string().min(1),
1206
+ roleKeys: z22.array(z22.string().min(1)),
1207
+ status: z22.enum(agentStatusValues),
1208
+ mode: z22.enum(agentModeValues),
1209
+ lastSeenAt: z22.string().datetime().nullable(),
1210
+ clientVersion: z22.string().nullable(),
1211
+ currentTaskId: z22.string().nullable(),
1212
+ tasksCompletedInSession: z22.number().int().nonnegative()
1213
+ });
1214
+ var agentCurrentTaskSummarySchema = z22.object({
1215
+ id: z22.string().min(1),
1216
+ number: z22.number().int().positive(),
1217
+ title: z22.string().min(1),
1218
+ status: z22.enum(taskStatusValues3)
1219
+ });
1220
+ var agentHelloPayloadSchema = z22.object({
1221
+ clientVersion: z22.string().min(1),
1222
+ cwd: z22.string().min(1),
1223
+ os: z22.string().min(1),
1224
+ claudeVersion: z22.string().min(1),
1045
1225
  // Роли, которыми клиент СЕБЯ считает — информационно (лог/диагностика
1046
1226
  // рассинхрона), не авторизация: авторизующие `Agent.roleKeys` идут из
1047
1227
  // БД (заданы при создании агента, REST §12 ТЗ), этот payload их не
1048
1228
  // меняет. См. блок «ВОПРОСЫ» отчёта P2-03.
1049
- roleKeys: z21.array(z21.string().min(1)),
1050
- resumeToken: z21.string().min(1).optional()
1229
+ roleKeys: z22.array(z22.string().min(1)),
1230
+ resumeToken: z22.string().min(1).optional()
1051
1231
  });
1052
- var agentHelloAckSchema = z21.object({
1232
+ var agentHelloAckSchema = z22.object({
1053
1233
  agent: agentSummarySchema,
1054
1234
  trust: trustRulesSchema,
1055
1235
  currentTask: agentCurrentTaskSummarySchema.optional(),
1056
- mode: z21.enum(agentModeValues)
1236
+ mode: z22.enum(agentModeValues)
1057
1237
  });
1058
- var agentHeartbeatPayloadSchema = z21.object({
1059
- currentTaskId: z21.string().min(1).optional(),
1060
- resumeToken: z21.string().min(1).optional(),
1061
- status: z21.enum(agentStatusValues)
1238
+ var agentHeartbeatPayloadSchema = z22.object({
1239
+ currentTaskId: z22.string().min(1).optional(),
1240
+ resumeToken: z22.string().min(1).optional(),
1241
+ status: z22.enum(agentStatusValues)
1062
1242
  });
1063
- var agentHeartbeatAckSchema = z21.object({
1064
- ok: z21.boolean(),
1065
- leaseExpiresAt: z21.string().datetime().optional()
1243
+ var agentHeartbeatAckSchema = z22.object({
1244
+ ok: z22.boolean(),
1245
+ leaseExpiresAt: z22.string().datetime().optional()
1066
1246
  });
1067
- var agentModePayloadSchema = z21.object({
1068
- mode: z21.enum(agentModeValues)
1247
+ var agentModePayloadSchema = z22.object({
1248
+ mode: z22.enum(agentModeValues)
1069
1249
  });
1070
- var agentModeAckSchema = z21.object({
1071
- ok: z21.boolean(),
1072
- mode: z21.enum(agentModeValues).optional()
1250
+ var agentModeAckSchema = z22.object({
1251
+ ok: z22.boolean(),
1252
+ mode: z22.enum(agentModeValues).optional()
1073
1253
  });
1074
- var taskPayloadMilestoneSchema = z21.object({
1075
- name: z21.string().min(1),
1076
- dueAt: z21.string().datetime().nullable()
1254
+ var taskPayloadMilestoneSchema = z22.object({
1255
+ name: z22.string().min(1),
1256
+ dueAt: z22.string().datetime().nullable()
1077
1257
  });
1078
- var taskPayloadTaskSchema = z21.object({
1079
- id: z21.string().min(1),
1258
+ var taskPayloadTaskSchema = z22.object({
1259
+ id: z22.string().min(1),
1080
1260
  /** Человекочитаемый ключ вида `ATL-42` (§7.5 ТЗ), НЕ то же, что `id`. */
1081
- key: z21.string().min(1),
1082
- title: z21.string().min(1),
1083
- descriptionMd: z21.string(),
1084
- type: z21.enum(taskTypeValues2),
1085
- priority: z21.enum(priorityValues2),
1086
- acceptance: z21.string(),
1087
- attempts: z21.number().int().nonnegative(),
1088
- reviewNotes: z21.string().optional(),
1089
- metadata: z21.record(z21.string(), z21.unknown()),
1090
- labels: z21.array(z21.string()),
1261
+ key: z22.string().min(1),
1262
+ title: z22.string().min(1),
1263
+ descriptionMd: z22.string(),
1264
+ type: z22.enum(taskTypeValues2),
1265
+ priority: z22.enum(priorityValues2),
1266
+ acceptance: z22.string(),
1267
+ attempts: z22.number().int().nonnegative(),
1268
+ reviewNotes: z22.string().optional(),
1269
+ metadata: z22.record(z22.string(), z22.unknown()),
1270
+ labels: z22.array(z22.string()),
1091
1271
  milestone: taskPayloadMilestoneSchema.optional()
1092
1272
  });
1093
- var taskPayloadRepoSchema = z21.object({
1094
- url: z21.string().min(1),
1095
- defaultBranch: z21.string().min(1),
1096
- pathHint: z21.string().nullable()
1097
- });
1098
- var taskPayloadProjectSchema = z21.object({
1099
- key: z21.string().min(1),
1100
- name: z21.string().min(1),
1101
- mode: z21.enum(projectModeValues),
1102
- gitMode: z21.enum(gitModeValues),
1103
- repos: z21.array(taskPayloadRepoSchema),
1273
+ var taskPayloadRepoSchema = z22.object({
1274
+ url: z22.string().min(1),
1275
+ defaultBranch: z22.string().min(1),
1276
+ pathHint: z22.string().nullable()
1277
+ });
1278
+ var taskPayloadProjectSchema = z22.object({
1279
+ key: z22.string().min(1),
1280
+ name: z22.string().min(1),
1281
+ mode: z22.enum(projectModeValues),
1282
+ gitMode: z22.enum(gitModeValues),
1283
+ repos: z22.array(taskPayloadRepoSchema),
1104
1284
  /** Готовое имя ветки, `task/ATL-42-add-login` — считает сервер, не модель. */
1105
- branchName: z21.string().min(1),
1285
+ branchName: z22.string().min(1),
1106
1286
  /** Префикс сообщения коммита, `ATL-42:`. */
1107
- commitPrefix: z21.string().min(1)
1287
+ commitPrefix: z22.string().min(1)
1108
1288
  });
1109
- var taskPayloadDependencySchema = z21.object({
1110
- key: z21.string().min(1),
1111
- title: z21.string().min(1),
1112
- status: z21.enum(taskStatusValues3),
1113
- resultMd: z21.string().optional(),
1114
- resultLinks: z21.array(z21.string()).optional()
1289
+ var taskPayloadDependencySchema = z22.object({
1290
+ key: z22.string().min(1),
1291
+ title: z22.string().min(1),
1292
+ status: z22.enum(taskStatusValues3),
1293
+ resultMd: z22.string().optional(),
1294
+ resultLinks: z22.array(z22.string()).optional()
1115
1295
  });
1116
- var taskPayloadOpenQuestionSchema = z21.object({
1117
- id: z21.string().min(1),
1118
- textMd: z21.string(),
1119
- answerMd: z21.string().optional()
1296
+ var taskPayloadOpenQuestionSchema = z22.object({
1297
+ id: z22.string().min(1),
1298
+ textMd: z22.string(),
1299
+ answerMd: z22.string().optional()
1120
1300
  });
1121
- var taskPayloadTrustSchema = z21.object({
1122
- profileKey: z21.string().min(1),
1123
- summary: z21.string()
1301
+ var taskPayloadTrustSchema = z22.object({
1302
+ profileKey: z22.string().min(1),
1303
+ summary: z22.string()
1124
1304
  });
1125
- var taskPayloadLeaseSchema = z21.object({
1126
- resumeToken: z21.string().min(1),
1127
- expiresAt: z21.string().datetime()
1305
+ var taskPayloadLeaseSchema = z22.object({
1306
+ resumeToken: z22.string().min(1),
1307
+ expiresAt: z22.string().datetime()
1128
1308
  });
1129
- var taskPayloadSchema = z21.object({
1309
+ var taskPayloadSchema = z22.object({
1130
1310
  task: taskPayloadTaskSchema,
1131
1311
  project: taskPayloadProjectSchema,
1132
- dependencies: z21.array(taskPayloadDependencySchema),
1133
- openQuestions: z21.array(taskPayloadOpenQuestionSchema),
1312
+ dependencies: z22.array(taskPayloadDependencySchema),
1313
+ openQuestions: z22.array(taskPayloadOpenQuestionSchema),
1134
1314
  trust: taskPayloadTrustSchema,
1135
1315
  lease: taskPayloadLeaseSchema
1136
1316
  });
1137
- var taskClaimPayloadSchema = z21.object({
1317
+ var taskClaimPayloadSchema = z22.object({
1138
1318
  /**
1139
1319
  * Потолок 600 с — тот же, что §10.3 задаёт для `ask_human`
1140
1320
  * («long-poll до 600 с»). Без верхней границы клиент может попросить
1141
1321
  * сервер держать ack сутками, а это утечка обработчиков на сервере.
1142
1322
  */
1143
- waitSec: z21.number().int().min(0).max(600)
1144
- });
1145
- var taskClaimAckSchema = z21.union([taskPayloadSchema, z21.object({ empty: z21.literal(true) })]);
1146
- var taskStartPayloadSchema = z21.object({
1147
- taskId: z21.string().min(1),
1148
- resumeToken: z21.string().min(1)
1149
- });
1150
- var taskStartAckSchema = z21.object({ ok: z21.boolean() });
1151
- var taskProgressLevelSchema = z21.enum(["debug", "info", "warn", "error"]);
1152
- var taskProgressPayloadSchema = z21.object({
1153
- taskId: z21.string().min(1),
1154
- note: z21.string().min(1),
1323
+ waitSec: z22.number().int().min(0).max(600)
1324
+ });
1325
+ var taskClaimAckSchema = z22.union([taskPayloadSchema, z22.object({ empty: z22.literal(true) })]);
1326
+ var taskStartPayloadSchema = z22.object({
1327
+ taskId: z22.string().min(1),
1328
+ resumeToken: z22.string().min(1)
1329
+ });
1330
+ var taskStartAckSchema = z22.object({ ok: z22.boolean() });
1331
+ var taskProgressLevelSchema = z22.enum(["debug", "info", "warn", "error"]);
1332
+ var taskProgressPayloadSchema = z22.object({
1333
+ taskId: z22.string().min(1),
1334
+ note: z22.string().min(1),
1155
1335
  level: taskProgressLevelSchema.default("info")
1156
1336
  });
1157
- var taskProgressAckSchema = z21.object({ ok: z21.boolean() });
1158
- var taskReleasePayloadSchema = z21.object({
1159
- taskId: z21.string().min(1),
1160
- reason: z21.string().min(1)
1337
+ var taskProgressAckSchema = z22.object({ ok: z22.boolean() });
1338
+ var taskReleasePayloadSchema = z22.object({
1339
+ taskId: z22.string().min(1),
1340
+ reason: z22.string().min(1)
1161
1341
  });
1162
- var taskReleaseAckSchema = z21.object({ ok: z21.boolean() });
1163
- var taskGetPayloadSchema = z21.object({
1164
- taskId: z21.string().min(1)
1342
+ var taskReleaseAckSchema = z22.object({ ok: z22.boolean() });
1343
+ var taskGetPayloadSchema = z22.object({
1344
+ taskId: z22.string().min(1)
1165
1345
  });
1166
1346
  var taskGetAckSchema = taskPayloadSchema.omit({ lease: true }).extend({
1167
1347
  lease: taskPayloadLeaseSchema.optional()
1168
1348
  });
1169
- var reportStatusSchema = z21.enum(["success", "partial", "failed"]);
1170
- var reportLinkSchema = z21.object({
1171
- kind: z21.enum(["commit", "pr", "doc", "other"]),
1172
- url: z21.string().min(1),
1173
- title: z21.string().optional()
1349
+ var reportStatusSchema = z22.enum(["success", "partial", "failed"]);
1350
+ var reportLinkSchema = z22.object({
1351
+ kind: z22.enum(["commit", "pr", "doc", "other"]),
1352
+ url: z22.string().min(1),
1353
+ title: z22.string().optional()
1174
1354
  });
1175
- var reportPayloadSchema = z21.object({
1176
- taskId: z21.string().min(1),
1355
+ var reportPayloadSchema = z22.object({
1356
+ taskId: z22.string().min(1),
1177
1357
  /**
1178
1358
  * Ключ идемпотентности (P2-13): пара `taskId + resumeToken` однозначно
1179
1359
  * определяет одну попытку сдачи. Повтор с тем же resumeToken обязан
1180
1360
  * вернуть тот же `taskStatus`, а не сдать задачу дважды — модель
1181
1361
  * ретраит вызов тула при обрыве связи, и это норма.
1182
1362
  */
1183
- resumeToken: z21.string().min(1),
1363
+ resumeToken: z22.string().min(1),
1184
1364
  status: reportStatusSchema,
1185
- resultMd: z21.string().min(1),
1186
- links: z21.array(reportLinkSchema),
1187
- testResult: z21.enum(testResultValues2),
1188
- nextSteps: z21.string().optional()
1365
+ resultMd: z22.string().min(1),
1366
+ links: z22.array(reportLinkSchema),
1367
+ testResult: z22.enum(testResultValues2),
1368
+ nextSteps: z22.string().optional()
1189
1369
  });
1190
- var reportAckSchema = z21.object({
1191
- taskStatus: z21.enum(taskStatusValues3),
1370
+ var reportAckSchema = z22.object({
1371
+ taskStatus: z22.enum(taskStatusValues3),
1192
1372
  /** true, если этот ack — повтор уже принятой сдачи (идемпотентность). */
1193
- duplicate: z21.boolean().optional()
1194
- });
1195
- var contextIncludeSchema = z21.enum(["spec", "decisions", "related", "repo"]);
1196
- var contextGetPayloadSchema = z21.object({
1197
- taskId: z21.string().min(1).optional(),
1198
- include: z21.array(contextIncludeSchema).min(1)
1199
- });
1200
- var contextDocumentSchema = z21.object({
1201
- id: z21.string().min(1),
1202
- title: z21.string().min(1),
1203
- kind: z21.string().min(1),
1204
- contentMd: z21.string()
1373
+ duplicate: z22.boolean().optional()
1374
+ });
1375
+ var contextIncludeSchema = z22.enum(["spec", "decisions", "related", "repo"]);
1376
+ var contextGetPayloadSchema = z22.object({
1377
+ taskId: z22.string().min(1).optional(),
1378
+ include: z22.array(contextIncludeSchema).min(1)
1379
+ });
1380
+ var contextDocumentFileSchema = z22.object({
1381
+ /** Имя как у человека на диске: `Спецификация v2.pdf`. */
1382
+ fileName: z22.string().min(1),
1383
+ /** Временная ссылка на скачивание — агент читает файл сам. */
1384
+ downloadUrl: z22.string().min(1),
1385
+ /** Сколько секунд ссылка живёт: успеть скачать, а не отложить на потом. */
1386
+ expiresInSeconds: z22.number().int().positive()
1387
+ });
1388
+ var contextDocumentSchema = z22.object({
1389
+ id: z22.string().min(1),
1390
+ title: z22.string().min(1),
1391
+ kind: z22.string().min(1),
1392
+ /** Текст документа. Пусто, если документ — файл: тогда заполнен `file`. */
1393
+ contentMd: z22.string(),
1394
+ /**
1395
+ * Заполнен, если документ — файл.
1396
+ *
1397
+ * `null` означает «текстовый документ», отсутствие ключа — «эта версия
1398
+ * платформы про файлы не знала». Различать важно: старый клиент не
1399
+ * должен принимать файловый документ за пустой.
1400
+ */
1401
+ file: contextDocumentFileSchema.nullable().optional()
1205
1402
  });
1206
- var contextPayloadSchema = z21.object({
1403
+ var contextPayloadSchema = z22.object({
1207
1404
  spec: contextDocumentSchema.nullable().optional(),
1208
- decisions: z21.array(contextDocumentSchema).optional(),
1209
- related: z21.array(taskPayloadDependencySchema).optional(),
1210
- repo: z21.object({
1211
- repos: z21.array(taskPayloadRepoSchema),
1212
- branchName: z21.string().optional(),
1213
- commitPrefix: z21.string().optional()
1405
+ decisions: z22.array(contextDocumentSchema).optional(),
1406
+ related: z22.array(taskPayloadDependencySchema).optional(),
1407
+ repo: z22.object({
1408
+ repos: z22.array(taskPayloadRepoSchema),
1409
+ branchName: z22.string().optional(),
1410
+ commitPrefix: z22.string().optional()
1214
1411
  }).optional()
1215
1412
  });
1216
- var agentRateLimitedPayloadSchema = z21.object({
1217
- retryAfterSec: z21.number().int().positive().optional(),
1218
- taskId: z21.string().min(1).optional()
1413
+ var agentRateLimitedPayloadSchema = z22.object({
1414
+ retryAfterSec: z22.number().int().positive().optional(),
1415
+ taskId: z22.string().min(1).optional()
1219
1416
  });
1220
- var agentRateLimitedAckSchema = z21.object({
1221
- ok: z21.boolean(),
1417
+ var agentRateLimitedAckSchema = z22.object({
1418
+ ok: z22.boolean(),
1222
1419
  /** Когда задача вернётся в очередь (§9.4 ТЗ: «через 2 ч»). */
1223
- requeueAt: z21.string().datetime().optional()
1420
+ requeueAt: z22.string().datetime().optional()
1224
1421
  });
1225
- var projectStatePayloadSchema = z21.object({
1226
- projectId: z21.string().min(1),
1227
- paused: z21.boolean(),
1228
- mode: z21.enum(projectModeValues),
1422
+ var projectStatePayloadSchema = z22.object({
1423
+ projectId: z22.string().min(1),
1424
+ paused: z22.boolean(),
1425
+ mode: z22.enum(projectModeValues),
1229
1426
  /** Причина паузы для модели; при `paused: false` не заполняется. */
1230
- reason: z21.string().optional()
1231
- });
1232
- var questionSummarySchema = z21.object({
1233
- id: z21.string().min(1),
1234
- taskId: z21.string().min(1).nullable(),
1235
- textMd: z21.string(),
1236
- options: z21.array(z21.string()),
1237
- blocking: z21.boolean(),
1238
- status: z21.enum(questionStatusValues),
1239
- answerMd: z21.string().nullable(),
1240
- answeredAt: z21.string().datetime().nullable(),
1241
- createdAt: z21.string().datetime()
1242
- });
1243
- var questionAskPayloadSchema = z21.object({
1244
- taskId: z21.string().min(1).optional(),
1245
- textMd: z21.string().min(1),
1246
- targetRole: z21.string().min(1).optional(),
1247
- targetMemberId: z21.string().min(1).optional(),
1248
- options: z21.array(z21.string().min(1)).optional(),
1249
- blocking: z21.boolean(),
1427
+ reason: z22.string().optional()
1428
+ });
1429
+ var questionSummarySchema = z22.object({
1430
+ id: z22.string().min(1),
1431
+ taskId: z22.string().min(1).nullable(),
1432
+ textMd: z22.string(),
1433
+ options: z22.array(z22.string()),
1434
+ blocking: z22.boolean(),
1435
+ status: z22.enum(questionStatusValues),
1436
+ answerMd: z22.string().nullable(),
1437
+ answeredAt: z22.string().datetime().nullable(),
1438
+ createdAt: z22.string().datetime()
1439
+ });
1440
+ var questionAskPayloadSchema = z22.object({
1441
+ taskId: z22.string().min(1).optional(),
1442
+ textMd: z22.string().min(1),
1443
+ targetRole: z22.string().min(1).optional(),
1444
+ targetMemberId: z22.string().min(1).optional(),
1445
+ options: z22.array(z22.string().min(1)).optional(),
1446
+ blocking: z22.boolean(),
1250
1447
  /** Сколько ждать ответ в этом же вызове. 0 — не ждать, вернуть вопрос сразу. */
1251
- waitSec: z21.number().int().min(0).max(600).optional()
1448
+ waitSec: z22.number().int().min(0).max(600).optional()
1252
1449
  }).refine((v) => Boolean(v.targetRole) !== Boolean(v.targetMemberId), {
1253
1450
  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"
1254
1451
  });
1255
- var questionAskAckSchema = z21.object({
1452
+ var questionAskAckSchema = z22.object({
1256
1453
  question: questionSummarySchema
1257
1454
  });
1258
- var questionWaitPayloadSchema = z21.object({
1259
- questionId: z21.string().min(1),
1260
- waitSec: z21.number().int().min(0).max(600)
1455
+ var questionWaitPayloadSchema = z22.object({
1456
+ questionId: z22.string().min(1),
1457
+ waitSec: z22.number().int().min(0).max(600)
1261
1458
  });
1262
- var questionWaitAckSchema = z21.object({
1459
+ var questionWaitAckSchema = z22.object({
1263
1460
  question: questionSummarySchema
1264
1461
  });
1265
- var taskCreatePayloadSchema = z21.object({
1266
- title: z21.string().min(1),
1267
- descriptionMd: z21.string(),
1268
- roleKey: z21.string().min(1).optional(),
1269
- assigneeId: z21.string().min(1).optional(),
1270
- type: z21.enum(taskTypeValues2),
1271
- priority: z21.enum(priorityValues2),
1272
- executor: z21.enum(executorValues2),
1273
- blocksCurrent: z21.boolean(),
1274
- acceptance: z21.string().optional(),
1275
- labels: z21.array(z21.string().min(1)).optional()
1462
+ var taskCreatePayloadSchema = z22.object({
1463
+ title: z22.string().min(1),
1464
+ descriptionMd: z22.string(),
1465
+ roleKey: z22.string().min(1).optional(),
1466
+ assigneeId: z22.string().min(1).optional(),
1467
+ type: z22.enum(taskTypeValues2),
1468
+ priority: z22.enum(priorityValues2),
1469
+ executor: z22.enum(executorValues2),
1470
+ blocksCurrent: z22.boolean(),
1471
+ acceptance: z22.string().optional(),
1472
+ labels: z22.array(z22.string().min(1)).optional()
1276
1473
  }).refine((v) => Boolean(v.roleKey) !== Boolean(v.assigneeId), {
1277
1474
  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"
1278
1475
  });
1279
- var taskBriefSchema = z21.object({
1280
- id: z21.string().min(1),
1281
- key: z21.string().min(1),
1282
- title: z21.string().min(1),
1283
- type: z21.enum(taskTypeValues2),
1284
- status: z21.enum(taskStatusValues3),
1285
- priority: z21.enum(priorityValues2),
1286
- roleKey: z21.string().min(1).nullable(),
1287
- assigneeId: z21.string().min(1).nullable(),
1288
- labels: z21.array(z21.string()),
1289
- updatedAt: z21.string().datetime()
1290
- });
1291
- var taskCreateAckSchema = z21.object({
1476
+ var taskBriefSchema = z22.object({
1477
+ id: z22.string().min(1),
1478
+ key: z22.string().min(1),
1479
+ title: z22.string().min(1),
1480
+ type: z22.enum(taskTypeValues2),
1481
+ status: z22.enum(taskStatusValues3),
1482
+ priority: z22.enum(priorityValues2),
1483
+ roleKey: z22.string().min(1).nullable(),
1484
+ assigneeId: z22.string().min(1).nullable(),
1485
+ labels: z22.array(z22.string()),
1486
+ updatedAt: z22.string().datetime()
1487
+ });
1488
+ var taskCreateAckSchema = z22.object({
1292
1489
  task: taskBriefSchema,
1293
1490
  /** Во что ушла ТЕКУЩАЯ задача автора, если `blocksCurrent: true`. */
1294
- currentTaskStatus: z21.enum(taskStatusValues3).optional()
1491
+ currentTaskStatus: z22.enum(taskStatusValues3).optional()
1295
1492
  });
1296
- var taskListPayloadSchema = z21.object({
1297
- status: z21.array(z21.enum(taskStatusValues3)).optional(),
1298
- roleKey: z21.string().min(1).optional(),
1493
+ var taskListPayloadSchema = z22.object({
1494
+ status: z22.array(z22.enum(taskStatusValues3)).optional(),
1495
+ roleKey: z22.string().min(1).optional(),
1299
1496
  /** Поиск по заголовку, без учёта регистра. */
1300
- query: z21.string().min(1).optional(),
1301
- limit: z21.number().int().min(1).max(100).optional()
1302
- });
1303
- var taskListAckSchema = z21.object({
1304
- tasks: z21.array(taskBriefSchema)
1305
- });
1306
- var taskUpdatePayloadSchema = z21.object({
1307
- taskId: z21.string().min(1),
1308
- patch: z21.object({
1309
- progressNote: z21.string().min(1).optional(),
1310
- labels: z21.array(z21.string().min(1)).optional(),
1311
- estimateMin: z21.number().int().positive().optional()
1497
+ query: z22.string().min(1).optional(),
1498
+ limit: z22.number().int().min(1).max(100).optional()
1499
+ });
1500
+ var taskListAckSchema = z22.object({
1501
+ tasks: z22.array(taskBriefSchema)
1502
+ });
1503
+ var taskUpdatePayloadSchema = z22.object({
1504
+ taskId: z22.string().min(1),
1505
+ patch: z22.object({
1506
+ progressNote: z22.string().min(1).optional(),
1507
+ labels: z22.array(z22.string().min(1)).optional(),
1508
+ estimateMin: z22.number().int().positive().optional()
1312
1509
  }).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" })
1313
1510
  });
1314
- var taskUpdateAckSchema = z21.object({
1511
+ var taskUpdateAckSchema = z22.object({
1315
1512
  task: taskBriefSchema
1316
1513
  });
1317
- var modeSetPayloadSchema = z21.object({
1318
- mode: z21.enum(agentModeValues)
1514
+ var modeSetPayloadSchema = z22.object({
1515
+ mode: z22.enum(agentModeValues)
1319
1516
  });
1320
- var agentPausePayloadSchema = z21.object({
1321
- reason: z21.string().min(1)
1517
+ var agentPausePayloadSchema = z22.object({
1518
+ reason: z22.string().min(1)
1322
1519
  });
1323
1520
  var trustUpdatedPayloadSchema = trustRulesSchema;
1324
- var leaseLostPayloadSchema = z21.object({
1325
- taskId: z21.string().min(1),
1326
- reason: z21.string().min(1)
1327
- });
1328
- var taskUpdatedAgentPayloadSchema = z21.object({
1329
- taskId: z21.string().min(1),
1330
- patch: z21.record(z21.string(), z21.unknown()).optional()
1331
- });
1332
- var questionAnsweredPayloadSchema = z21.object({
1333
- questionId: z21.string().min(1),
1334
- answerMd: z21.string()
1335
- });
1336
- var approvalSummarySchema = z21.object({
1337
- id: z21.string().min(1),
1338
- taskId: z21.string().min(1),
1339
- kind: z21.enum(approvalKindValues),
1340
- summary: z21.string(),
1341
- status: z21.enum(approvalStatusValues),
1342
- expiresAt: z21.string().datetime(),
1343
- decidedAt: z21.string().datetime().nullable(),
1344
- createdAt: z21.string().datetime()
1345
- });
1346
- var approvalRequestPayloadSchema = z21.object({
1347
- taskId: z21.string().min(1),
1348
- kind: z21.enum(approvalKindValues),
1349
- summary: z21.string().min(1),
1350
- command: z21.string().min(1),
1351
- cwd: z21.string().min(1),
1352
- host: z21.string().min(1).optional(),
1353
- diff: z21.string().optional(),
1521
+ var leaseLostPayloadSchema = z22.object({
1522
+ taskId: z22.string().min(1),
1523
+ reason: z22.string().min(1)
1524
+ });
1525
+ var taskUpdatedAgentPayloadSchema = z22.object({
1526
+ taskId: z22.string().min(1),
1527
+ patch: z22.record(z22.string(), z22.unknown()).optional()
1528
+ });
1529
+ var questionAnsweredPayloadSchema = z22.object({
1530
+ questionId: z22.string().min(1),
1531
+ answerMd: z22.string()
1532
+ });
1533
+ var approvalSummarySchema = z22.object({
1534
+ id: z22.string().min(1),
1535
+ taskId: z22.string().min(1),
1536
+ kind: z22.enum(approvalKindValues),
1537
+ summary: z22.string(),
1538
+ status: z22.enum(approvalStatusValues),
1539
+ expiresAt: z22.string().datetime(),
1540
+ decidedAt: z22.string().datetime().nullable(),
1541
+ createdAt: z22.string().datetime()
1542
+ });
1543
+ var approvalRequestPayloadSchema = z22.object({
1544
+ taskId: z22.string().min(1),
1545
+ kind: z22.enum(approvalKindValues),
1546
+ summary: z22.string().min(1),
1547
+ command: z22.string().min(1),
1548
+ cwd: z22.string().min(1),
1549
+ host: z22.string().min(1).optional(),
1550
+ diff: z22.string().optional(),
1354
1551
  /** Сколько ждать решения в этом же вызове; 0 — не ждать. Потолок — как у вопросов. */
1355
- waitSec: z21.number().int().min(0).max(600).optional()
1552
+ waitSec: z22.number().int().min(0).max(600).optional()
1356
1553
  });
1357
- var approvalRequestAckSchema = z21.object({
1554
+ var approvalRequestAckSchema = z22.object({
1358
1555
  approval: approvalSummarySchema,
1359
1556
  /** Приходит только при `APPROVED` — одноразовый, привязан к команде и каталогу (§14.4 ТЗ). */
1360
- oneTimeToken: z21.string().min(1).optional()
1557
+ oneTimeToken: z22.string().min(1).optional()
1361
1558
  });
1362
- var approvalWaitPayloadSchema = z21.object({
1363
- approvalId: z21.string().min(1),
1364
- waitSec: z21.number().int().min(0).max(600)
1559
+ var approvalWaitPayloadSchema = z22.object({
1560
+ approvalId: z22.string().min(1),
1561
+ waitSec: z22.number().int().min(0).max(600)
1365
1562
  });
1366
1563
  var approvalWaitAckSchema = approvalRequestAckSchema;
1367
- var approvalDecidedPayloadSchema = z21.object({
1368
- approvalId: z21.string().min(1),
1369
- status: z21.enum([ApprovalStatus.APPROVED, ApprovalStatus.REJECTED]),
1370
- oneTimeToken: z21.string().min(1).optional()
1371
- });
1372
- var agentPresenceUiPayloadSchema = z21.object({
1373
- projectId: z21.string().min(1),
1374
- agentId: z21.string().min(1),
1375
- status: z21.enum(agentStatusValues),
1376
- lastSeenAt: z21.string().datetime(),
1377
- currentTaskId: z21.string().nullable().optional()
1564
+ var approvalDecidedPayloadSchema = z22.object({
1565
+ approvalId: z22.string().min(1),
1566
+ status: z22.enum([ApprovalStatus.APPROVED, ApprovalStatus.REJECTED]),
1567
+ oneTimeToken: z22.string().min(1).optional()
1568
+ });
1569
+ var agentPresenceUiPayloadSchema = z22.object({
1570
+ projectId: z22.string().min(1),
1571
+ agentId: z22.string().min(1),
1572
+ status: z22.enum(agentStatusValues),
1573
+ lastSeenAt: z22.string().datetime(),
1574
+ currentTaskId: z22.string().nullable().optional()
1575
+ });
1576
+ var taskOpenPrPayloadSchema = z22.object({
1577
+ taskId: z22.string().min(1),
1578
+ /** Ветка, которую клиент уже отправил на remote. */
1579
+ branchName: z22.string().min(1),
1580
+ /** Rebase на основную ветку не прошёл — PR помечается «conflicts» (§13.1 ТЗ). */
1581
+ conflicted: z22.boolean().optional(),
1582
+ /** Только пути файлов, никогда содержимое (§18 ТЗ). */
1583
+ conflictedFiles: z22.array(z22.string().min(1)).max(100).optional()
1584
+ });
1585
+ var taskOpenPrAckSchema = z22.object({
1586
+ url: z22.string().url(),
1587
+ number: z22.number().int().positive(),
1588
+ /** `false` — PR уже существовал для этой ветки, повторно не создавали. */
1589
+ created: z22.boolean()
1378
1590
  });
1379
1591
 
1380
1592
  // ../shared/src/events/ticket.ts
1381
- import { z as z22 } from "zod";
1382
- var realtimeTicketPayloadSchema = z22.object({
1383
- sub: z22.string().min(1),
1384
- orgIds: z22.array(z22.string().min(1)),
1385
- projectIds: z22.array(z22.string().min(1)),
1386
- iat: z22.number().int().positive(),
1387
- exp: z22.number().int().positive(),
1388
- jti: z22.string().min(1)
1389
- });
1390
- var roomJoinRequestSchema = z22.object({
1391
- room: z22.string().min(1),
1392
- projectId: z22.string().min(1).optional()
1593
+ import { z as z23 } from "zod";
1594
+ var realtimeTicketPayloadSchema = z23.object({
1595
+ sub: z23.string().min(1),
1596
+ orgIds: z23.array(z23.string().min(1)),
1597
+ projectIds: z23.array(z23.string().min(1)),
1598
+ iat: z23.number().int().positive(),
1599
+ exp: z23.number().int().positive(),
1600
+ jti: z23.string().min(1)
1601
+ });
1602
+ var roomJoinRequestSchema = z23.object({
1603
+ room: z23.string().min(1),
1604
+ projectId: z23.string().min(1).optional()
1393
1605
  });
1394
1606
 
1395
1607
  // ../shared/src/events/ui-events.ts
1396
- import { z as z23 } from "zod";
1608
+ import { z as z24 } from "zod";
1397
1609
  var taskStatusValues4 = Object.values(TaskStatus);
1398
- var taskCreatedPayloadSchema = z23.object({
1399
- taskId: z23.string().min(1),
1400
- projectId: z23.string().min(1),
1401
- orgId: z23.string().min(1)
1402
- });
1403
- var taskUpdatedPayloadSchema = z23.object({
1404
- taskId: z23.string().min(1),
1405
- projectId: z23.string().min(1),
1406
- orgId: z23.string().min(1),
1610
+ var taskCreatedPayloadSchema = z24.object({
1611
+ taskId: z24.string().min(1),
1612
+ projectId: z24.string().min(1),
1613
+ orgId: z24.string().min(1)
1614
+ });
1615
+ var taskUpdatedPayloadSchema = z24.object({
1616
+ taskId: z24.string().min(1),
1617
+ projectId: z24.string().min(1),
1618
+ orgId: z24.string().min(1),
1407
1619
  // Необязательный частичный diff — подсказка для оптимистичного мерджа на
1408
1620
  // клиенте. Не гарантирует полноты: клиент обязан доверять только REST.
1409
- patch: z23.record(z23.string(), z23.unknown()).optional()
1621
+ patch: z24.record(z24.string(), z24.unknown()).optional()
1410
1622
  });
1411
- var taskDeletedPayloadSchema = z23.object({
1412
- taskId: z23.string().min(1),
1413
- projectId: z23.string().min(1),
1414
- orgId: z23.string().min(1)
1623
+ var taskDeletedPayloadSchema = z24.object({
1624
+ taskId: z24.string().min(1),
1625
+ projectId: z24.string().min(1),
1626
+ orgId: z24.string().min(1)
1415
1627
  });
1416
- var taskMovedPayloadSchema = z23.object({
1417
- taskId: z23.string().min(1),
1418
- projectId: z23.string().min(1),
1419
- orgId: z23.string().min(1),
1628
+ var taskMovedPayloadSchema = z24.object({
1629
+ taskId: z24.string().min(1),
1630
+ projectId: z24.string().min(1),
1631
+ orgId: z24.string().min(1),
1420
1632
  // Новый статус/позиция — нужны доске (P1-11) для немедленного
1421
1633
  // перемещения карточки без ожидания REST-рефетча.
1422
- status: z23.enum(taskStatusValues4),
1423
- order: z23.number()
1634
+ status: z24.enum(taskStatusValues4),
1635
+ order: z24.number()
1424
1636
  });
1425
- var notificationNewPayloadSchema = z23.object({
1426
- notificationId: z23.string().min(1),
1637
+ var notificationNewPayloadSchema = z24.object({
1638
+ notificationId: z24.string().min(1),
1427
1639
  // userId, не membershipId: `apps/realtime` адресует личную комнату
1428
1640
  // `user:{userId}` (см. rooms.ts) — так же, как ticket.sub.
1429
- userId: z23.string().min(1),
1430
- kind: z23.string().min(1),
1431
- title: z23.string().min(1),
1432
- body: z23.string().optional(),
1433
- link: z23.string().optional()
1434
- });
1435
- var futurePlaceholderPayloadSchema = z23.object({
1436
- projectId: z23.string().min(1)
1641
+ userId: z24.string().min(1),
1642
+ kind: z24.string().min(1),
1643
+ title: z24.string().min(1),
1644
+ body: z24.string().optional(),
1645
+ link: z24.string().optional()
1646
+ });
1647
+ var futurePlaceholderPayloadSchema = z24.object({
1648
+ projectId: z24.string().min(1)
1437
1649
  }).loose();
1438
- var questionEventPayloadSchema = z23.object({
1439
- questionId: z23.string().min(1),
1440
- projectId: z23.string().min(1),
1441
- orgId: z23.string().min(1),
1442
- taskId: z23.string().min(1).nullable().optional(),
1650
+ var questionEventPayloadSchema = z24.object({
1651
+ questionId: z24.string().min(1),
1652
+ projectId: z24.string().min(1),
1653
+ orgId: z24.string().min(1),
1654
+ taskId: z24.string().min(1).nullable().optional(),
1443
1655
  /** Кому адресован — роль или конкретный участник; для фильтра «мне» в UI. */
1444
- targetRole: z23.string().min(1).nullable().optional(),
1445
- targetMemberId: z23.string().min(1).nullable().optional(),
1446
- blocking: z23.boolean().optional()
1656
+ targetRole: z24.string().min(1).nullable().optional(),
1657
+ targetMemberId: z24.string().min(1).nullable().optional(),
1658
+ blocking: z24.boolean().optional()
1447
1659
  });
1448
1660
  var envelopeExtra = {
1449
- publishedAt: z23.string().datetime().optional()
1661
+ publishedAt: z24.string().datetime().optional()
1450
1662
  };
1451
- var uiEventEnvelopeSchema = z23.discriminatedUnion("event", [
1452
- z23.object({
1453
- event: z23.literal("task:created"),
1663
+ var uiEventEnvelopeSchema = z24.discriminatedUnion("event", [
1664
+ z24.object({
1665
+ event: z24.literal("task:created"),
1454
1666
  payload: taskCreatedPayloadSchema,
1455
1667
  ...envelopeExtra
1456
1668
  }),
1457
- z23.object({
1458
- event: z23.literal("task:updated"),
1669
+ z24.object({
1670
+ event: z24.literal("task:updated"),
1459
1671
  payload: taskUpdatedPayloadSchema,
1460
1672
  ...envelopeExtra
1461
1673
  }),
1462
- z23.object({
1463
- event: z23.literal("task:deleted"),
1674
+ z24.object({
1675
+ event: z24.literal("task:deleted"),
1464
1676
  payload: taskDeletedPayloadSchema,
1465
1677
  ...envelopeExtra
1466
1678
  }),
1467
- z23.object({ event: z23.literal("task:moved"), payload: taskMovedPayloadSchema, ...envelopeExtra }),
1468
- z23.object({
1469
- event: z23.literal("notification:new"),
1679
+ z24.object({ event: z24.literal("task:moved"), payload: taskMovedPayloadSchema, ...envelopeExtra }),
1680
+ z24.object({
1681
+ event: z24.literal("notification:new"),
1470
1682
  payload: notificationNewPayloadSchema,
1471
1683
  ...envelopeExtra
1472
1684
  }),
1473
1685
  // Заготовки под фазу 2+ (§11.3 ТЗ упоминает `question:*`/`approval:*` как
1474
1686
  // группы, а не точные имена — ниже разумное предположение, подлежит
1475
1687
  // уточнению, см. «ВОПРОСЫ» в отчёте P1-10).
1476
- z23.object({
1477
- event: z23.literal("agent:presence"),
1688
+ z24.object({
1689
+ event: z24.literal("agent:presence"),
1478
1690
  payload: futurePlaceholderPayloadSchema,
1479
1691
  ...envelopeExtra
1480
1692
  }),
1481
- z23.object({
1482
- event: z23.literal("question:new"),
1693
+ z24.object({
1694
+ event: z24.literal("question:new"),
1483
1695
  payload: questionEventPayloadSchema,
1484
1696
  ...envelopeExtra
1485
1697
  }),
1486
- z23.object({
1487
- event: z23.literal("question:answered"),
1698
+ z24.object({
1699
+ event: z24.literal("question:answered"),
1488
1700
  payload: questionEventPayloadSchema,
1489
1701
  ...envelopeExtra
1490
1702
  }),
1491
- z23.object({
1492
- event: z23.literal("question:dismissed"),
1703
+ z24.object({
1704
+ event: z24.literal("question:dismissed"),
1493
1705
  payload: questionEventPayloadSchema,
1494
1706
  ...envelopeExtra
1495
1707
  }),
1496
- z23.object({
1497
- event: z23.literal("approval:requested"),
1708
+ z24.object({
1709
+ event: z24.literal("approval:requested"),
1498
1710
  payload: futurePlaceholderPayloadSchema,
1499
1711
  ...envelopeExtra
1500
1712
  }),
1501
- z23.object({
1502
- event: z23.literal("approval:decided"),
1713
+ z24.object({
1714
+ event: z24.literal("approval:decided"),
1503
1715
  payload: futurePlaceholderPayloadSchema,
1504
1716
  ...envelopeExtra
1505
1717
  }),
1506
- z23.object({
1507
- event: z23.literal("audit:appended"),
1718
+ z24.object({
1719
+ event: z24.literal("audit:appended"),
1508
1720
  payload: futurePlaceholderPayloadSchema,
1509
1721
  ...envelopeExtra
1510
1722
  }),
1511
- z23.object({
1723
+ z24.object({
1512
1724
  // Состояние проекта изменилось (OQ-30). Единственное событие этого
1513
1725
  // канала, которое realtime рассылает НЕ только в `/ui`, но и агентам
1514
1726
  // проекта: §17 ТЗ обещает «при PAUSED агентам шлётся agent:pause», а
1515
1727
  // одностороннего agent:pause на рукопожатии для этого мало — снятие
1516
1728
  // паузы до подключённого агента не доходит вовсе. Веб публикует одно
1517
1729
  // событие, realtime разводит его по обоим namespace.
1518
- event: z23.literal("project:state"),
1519
- payload: z23.object({
1520
- projectId: z23.string().min(1),
1521
- paused: z23.boolean(),
1522
- mode: z23.string().min(1),
1523
- reason: z23.string().optional()
1730
+ event: z24.literal("project:state"),
1731
+ payload: z24.object({
1732
+ projectId: z24.string().min(1),
1733
+ paused: z24.boolean(),
1734
+ mode: z24.string().min(1),
1735
+ reason: z24.string().optional()
1524
1736
  }),
1525
1737
  ...envelopeExtra
1526
1738
  })
1527
1739
  ]);
1528
1740
 
1741
+ // ../shared/src/git/trailer.ts
1742
+ var TASK_TRAILER_NAME = "Quiel-Task";
1743
+ function buildTaskTrailer(taskKey) {
1744
+ return `${TASK_TRAILER_NAME}: ${taskKey}`;
1745
+ }
1746
+
1529
1747
  // ../shared/src/import/csv.ts
1530
1748
  var TASK_TYPE_VALUES = new Set(Object.values(TaskType));
1531
1749
  var PRIORITY_VALUES = new Set(Object.values(Priority));
1532
1750
  var EXECUTOR_VALUES = new Set(Object.values(Executor));
1533
1751
 
1534
1752
  // ../shared/src/import/types.ts
1535
- import { z as z24 } from "zod";
1536
- var ImportTargetStatusSchema = z24.enum([
1753
+ import { z as z25 } from "zod";
1754
+ var ImportTargetStatusSchema = z25.enum([
1537
1755
  TaskStatus.BACKLOG,
1538
1756
  TaskStatus.READY,
1539
1757
  TaskStatus.DONE
1540
1758
  ]);
1541
- var ImportRowKeySchema = z24.string().trim().min(1).max(100);
1542
- var ImportTaskInputSchema = z24.object({
1759
+ var ImportRowKeySchema = z25.string().trim().min(1).max(100);
1760
+ var ImportTaskInputSchema = z25.object({
1543
1761
  key: ImportRowKeySchema,
1544
1762
  title: TaskTitleSchema,
1545
1763
  descriptionMd: TaskDescriptionSchema.default(""),
@@ -1547,21 +1765,21 @@ var ImportTaskInputSchema = z24.object({
1547
1765
  priority: TaskPrioritySchema.default(Priority.P2),
1548
1766
  executor: TaskExecutorSchema.default(Executor.ANY),
1549
1767
  status: ImportTargetStatusSchema.default(TaskStatus.BACKLOG),
1550
- roleKey: z24.string().trim().min(1).max(60).optional(),
1551
- milestoneId: z24.string().min(1).optional(),
1768
+ roleKey: z25.string().trim().min(1).max(60).optional(),
1769
+ milestoneId: z25.string().min(1).optional(),
1552
1770
  labels: TaskLabelsSchema.default([]),
1553
1771
  metadata: TaskMetadataSchema.default({}),
1554
1772
  acceptance: TaskAcceptanceSchema.optional(),
1555
1773
  estimateMin: TaskEstimateMinSchema.optional(),
1556
1774
  parentKey: ImportRowKeySchema.optional()
1557
1775
  });
1558
- var ImportTasksRequestSchema = z24.object({
1559
- tasks: z24.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")
1776
+ var ImportTasksRequestSchema = z25.object({
1777
+ 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")
1560
1778
  });
1561
1779
 
1562
1780
  // ../shared/src/settings/org-settings.ts
1563
- import { z as z25 } from "zod";
1564
- var OrgSettingsSchema = z25.object({}).passthrough();
1781
+ import { z as z26 } from "zod";
1782
+ var OrgSettingsSchema = z26.object({}).passthrough();
1565
1783
 
1566
1784
  // ../shared/src/task-state.ts
1567
1785
  var TASK_TRANSITIONS = [
@@ -2740,13 +2958,13 @@ function evaluateFileAccess(relativePath, rules) {
2740
2958
  }
2741
2959
 
2742
2960
  // src/state/schema.ts
2743
- import { z as z26 } from "zod";
2961
+ import { z as z27 } from "zod";
2744
2962
  var STATE_SCHEMA_VERSION = 1;
2745
- var CurrentTaskSchema = z26.object({
2746
- taskId: z26.string().min(1),
2963
+ var CurrentTaskSchema = z27.object({
2964
+ taskId: z27.string().min(1),
2747
2965
  /** Человекочитаемый ключ вроде `REL-42` — для текста в хуках. Необязателен: на первых порах может быть неизвестен. */
2748
- taskKey: z26.string().min(1).optional(),
2749
- resumeToken: z26.string().min(1),
2966
+ taskKey: z27.string().min(1).optional(),
2967
+ resumeToken: z27.string().min(1),
2750
2968
  /**
2751
2969
  * Каталог, в котором агент работает над этой задачей (`.claude/worktrees/…`).
2752
2970
  *
@@ -2760,58 +2978,72 @@ var CurrentTaskSchema = z26.object({
2760
2978
  * в чекауте), а у состояний, записанных прежними версиями клиента,
2761
2979
  * поля просто нет.
2762
2980
  */
2763
- worktreeDir: z26.string().min(1).optional()
2764
- });
2765
- var TrustCacheSchema = z26.object({
2766
- profileKey: z26.string().min(1),
2767
- updatedAt: z26.string(),
2768
- rules: z26.object({
2769
- bash: z26.object({
2770
- mode: z26.enum(["allow", "approve", "deny"]),
2771
- stopPatterns: z26.array(z26.string()).default([]),
2772
- allowPatterns: z26.array(z26.string()).optional()
2981
+ worktreeDir: z27.string().min(1).optional(),
2982
+ /**
2983
+ * Git-режим проекта (§13.1 ТЗ) — `DIRECT` или `PR`.
2984
+ *
2985
+ * Хранится ЗДЕСЬ, а не спрашивается у модели аргументом тула, по той же
2986
+ * причине, по которой сервер сам считает `branchName`: это настройка
2987
+ * проекта, а не решение исполнителя. Приди она параметром — модель
2988
+ * могла бы (случайно или по «так быстрее») передать `DIRECT` там, где
2989
+ * проект требует ревью через PR, и работа уехала бы прямо в основную
2990
+ * ветку мимо человека.
2991
+ *
2992
+ * Необязательно: состояния, записанные прежними версиями клиента, поля
2993
+ * не имеют — тогда `submit_work` работает как раньше, в режиме DIRECT.
2994
+ */
2995
+ gitMode: z27.enum([GitMode.DIRECT, GitMode.PR]).optional()
2996
+ });
2997
+ var TrustCacheSchema = z27.object({
2998
+ profileKey: z27.string().min(1),
2999
+ updatedAt: z27.string(),
3000
+ rules: z27.object({
3001
+ bash: z27.object({
3002
+ mode: z27.enum(["allow", "approve", "deny"]),
3003
+ stopPatterns: z27.array(z27.string()).default([]),
3004
+ allowPatterns: z27.array(z27.string()).optional()
2773
3005
  }),
2774
- files: z26.object({
2775
- mode: z26.enum(["allow", "approve"]),
2776
- protectedPaths: z26.array(z26.string()).default([])
3006
+ files: z27.object({
3007
+ mode: z27.enum(["allow", "approve"]),
3008
+ protectedPaths: z27.array(z27.string()).default([])
2777
3009
  }).optional(),
2778
- git: z26.object({ allowPushDefault: z26.boolean(), allowForcePush: z26.boolean() }).optional(),
2779
- network: z26.object({ allowSsh: z26.boolean(), sshHostsAllow: z26.array(z26.string()).optional() }).optional(),
2780
- approvalTtlMin: z26.number().int().positive().optional()
3010
+ git: z27.object({ allowPushDefault: z27.boolean(), allowForcePush: z27.boolean() }).optional(),
3011
+ network: z27.object({ allowSsh: z27.boolean(), sshHostsAllow: z27.array(z27.string()).optional() }).optional(),
3012
+ approvalTtlMin: z27.number().int().positive().optional()
2781
3013
  }).passthrough()
2782
3014
  }).nullable();
2783
- var ApprovedCommandSchema = z26.object({
2784
- token: z26.string().min(1),
2785
- command: z26.string().min(1),
2786
- cwd: z26.string().min(1),
2787
- expiresAt: z26.string(),
2788
- createdAt: z26.string()
2789
- });
2790
- var PendingApprovalSchema = z26.object({
2791
- command: z26.string().min(1),
2792
- cwd: z26.string().min(1),
2793
- createdAt: z26.string()
2794
- });
2795
- var AgentModeSchema = z26.enum([AgentMode.AUTONOMOUS, AgentMode.MANUAL]);
3015
+ var ApprovedCommandSchema = z27.object({
3016
+ token: z27.string().min(1),
3017
+ command: z27.string().min(1),
3018
+ cwd: z27.string().min(1),
3019
+ expiresAt: z27.string(),
3020
+ createdAt: z27.string()
3021
+ });
3022
+ var PendingApprovalSchema = z27.object({
3023
+ command: z27.string().min(1),
3024
+ cwd: z27.string().min(1),
3025
+ createdAt: z27.string()
3026
+ });
3027
+ var AgentModeSchema = z27.enum([AgentMode.AUTONOMOUS, AgentMode.MANUAL]);
2796
3028
  var DEFAULT_CONTEXT_RESET_AFTER_TASKS = ProjectSettingsSchema.parse({}).contextResetAfterTasks;
2797
- var ClientStateSchema = z26.object({
2798
- version: z26.literal(STATE_SCHEMA_VERSION).default(STATE_SCHEMA_VERSION),
3029
+ var ClientStateSchema = z27.object({
3030
+ version: z27.literal(STATE_SCHEMA_VERSION).default(STATE_SCHEMA_VERSION),
2799
3031
  mode: AgentModeSchema.default(AgentMode.MANUAL),
2800
3032
  currentTask: CurrentTaskSchema.nullable().default(null),
2801
3033
  /** Счётчик сдач задач в текущей «сессии» (§10.4 ТЗ). Сбрасывается `SessionStart` при `source ∈ {startup, clear}` — см. src/hooks/session-start.ts. */
2802
- tasksCompletedInSession: z26.number().int().nonnegative().default(0),
3034
+ tasksCompletedInSession: z27.number().int().nonnegative().default(0),
2803
3035
  /** Кэш `ProjectSettings.contextResetAfterTasks` (§7.2 ТЗ) — сколько задач подряд можно сдать, прежде чем `Stop`-хук попросит `/clear`. */
2804
- contextResetAfterTasks: z26.number().int().positive().default(DEFAULT_CONTEXT_RESET_AFTER_TASKS),
3036
+ contextResetAfterTasks: z27.number().int().positive().default(DEFAULT_CONTEXT_RESET_AFTER_TASKS),
2805
3037
  /** Кэш стоп-паттернов/правил доверия для `PreToolUse` фазы 4. */
2806
3038
  trust: TrustCacheSchema.default(null),
2807
3039
  /** Снимок задачи на момент последнего `PreCompact` — пишет src/hooks/pre-compact.ts, читает SessionStart(source="compact"), чтобы напомнить модели, чем она занималась. */
2808
- lastPreCompact: CurrentTaskSchema.extend({ savedAt: z26.string() }).nullable().default(null),
3040
+ lastPreCompact: CurrentTaskSchema.extend({ savedAt: z27.string() }).nullable().default(null),
2809
3041
  /** Кэш одноразовых токенов подтверждения (§14.4 ТЗ), ключ — `hashCommandKey(command, cwd)`. Читает/жжёт `PreToolUse` (`hooks/pre-tool-use.ts`), пишут `request_approval`/`wait_approval` и пуш `approval:decided` (`socket/client.ts`). */
2810
- approvedCommands: z26.record(z26.string(), ApprovedCommandSchema).default({}),
3042
+ approvedCommands: z27.record(z27.string(), ApprovedCommandSchema).default({}),
2811
3043
  /** Незавершённые запросы подтверждения, ключ — `approvalId`. См. `PendingApprovalSchema`. */
2812
- pendingApprovals: z26.record(z26.string(), PendingApprovalSchema).default({}),
3044
+ pendingApprovals: z27.record(z27.string(), PendingApprovalSchema).default({}),
2813
3045
  /** Штамп последней записи файла — выставляется в state/store.ts при каждом `writeState`. */
2814
- updatedAt: z26.string().default(() => (/* @__PURE__ */ new Date()).toISOString())
3046
+ updatedAt: z27.string().default(() => (/* @__PURE__ */ new Date()).toISOString())
2815
3047
  });
2816
3048
  function createDefaultState() {
2817
3049
  return ClientStateSchema.parse({});
@@ -2863,18 +3095,18 @@ function updateState(patch, filePath = getStateFilePath()) {
2863
3095
  }
2864
3096
 
2865
3097
  // src/config/schema.ts
2866
- import { z as z27 } from "zod";
3098
+ import { z as z28 } from "zod";
2867
3099
  var PROJECT_CONFIG_SCHEMA_VERSION = 1;
2868
- var ProjectConfigSchema = z27.object({
2869
- version: z27.literal(PROJECT_CONFIG_SCHEMA_VERSION).default(PROJECT_CONFIG_SCHEMA_VERSION),
3100
+ var ProjectConfigSchema = z28.object({
3101
+ version: z28.literal(PROJECT_CONFIG_SCHEMA_VERSION).default(PROJECT_CONFIG_SCHEMA_VERSION),
2870
3102
  /** URL платформы (§10.1 ТЗ), например `https://quiel.example.com`. */
2871
- url: z27.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"),
3103
+ url: z28.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"),
2872
3104
  /** Ключ проекта на платформе (OQ-11), например `REL`. */
2873
- projectKey: z27.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"),
3105
+ projectKey: z28.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"),
2874
3106
  /** Идентификатор агента — см. комментарий выше. */
2875
- agentId: z27.string().trim().min(1, "ID \u0430\u0433\u0435\u043D\u0442\u0430 \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u0435\u043D"),
3107
+ agentId: z28.string().trim().min(1, "ID \u0430\u0433\u0435\u043D\u0442\u0430 \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u0435\u043D"),
2876
3108
  /** Человекочитаемое имя агента (§7.4 ТЗ: «odya-macbook») — необязательно, только для локального отображения. */
2877
- agentName: z27.string().trim().min(1).optional(),
3109
+ agentName: z28.string().trim().min(1).optional(),
2878
3110
  /** Роли, с которыми агент забирает задачи — подмножество ролей участника (§7.4 ТЗ). */
2879
3111
  roleKeys: AgentRoleKeysSchema,
2880
3112
  /**
@@ -2894,19 +3126,19 @@ var ProjectConfigSchema = z27.object({
2894
3126
  * абсолютный путь вроде `/Users/odya/...` у коллеги на другой машине
2895
3127
  * оказался бы битым. Режим переносим — это соглашение проекта.
2896
3128
  */
2897
- worktrees: z27.enum(["isolated", "checkout"]).default("isolated")
3129
+ worktrees: z28.enum(["isolated", "checkout"]).default("isolated")
2898
3130
  });
2899
- var CredentialsEntrySchema = z27.object({
2900
- url: z27.string().trim().url(),
2901
- token: z27.string().min(1),
2902
- projectKey: z27.string().min(1),
3131
+ var CredentialsEntrySchema = z28.object({
3132
+ url: z28.string().trim().url(),
3133
+ token: z28.string().min(1),
3134
+ projectKey: z28.string().min(1),
2903
3135
  /** Когда записали — для диагностики (`quiel status`), не для логики. */
2904
- savedAt: z27.string()
3136
+ savedAt: z28.string()
2905
3137
  });
2906
3138
  var CREDENTIALS_SCHEMA_VERSION = 1;
2907
- var CredentialsFileSchema = z27.object({
2908
- version: z27.literal(CREDENTIALS_SCHEMA_VERSION).default(CREDENTIALS_SCHEMA_VERSION),
2909
- agents: z27.record(z27.string(), CredentialsEntrySchema).default({})
3139
+ var CredentialsFileSchema = z28.object({
3140
+ version: z28.literal(CREDENTIALS_SCHEMA_VERSION).default(CREDENTIALS_SCHEMA_VERSION),
3141
+ agents: z28.record(z28.string(), CredentialsEntrySchema).default({})
2910
3142
  });
2911
3143
  function createEmptyCredentialsFile() {
2912
3144
  return CredentialsFileSchema.parse({});
@@ -2987,13 +3219,13 @@ function ensureWorktreesIgnored(dir) {
2987
3219
  // src/config/mcp-json.ts
2988
3220
  import { existsSync as existsSync6, readFileSync as readFileSync6, writeFileSync as writeFileSync6 } from "fs";
2989
3221
  import { join as join6 } from "path";
2990
- import { z as z28 } from "zod";
2991
- var McpServerEntrySchema2 = z28.object({
2992
- command: z28.string().min(1).optional(),
2993
- args: z28.array(z28.string()).optional()
3222
+ import { z as z29 } from "zod";
3223
+ var McpServerEntrySchema2 = z29.object({
3224
+ command: z29.string().min(1).optional(),
3225
+ args: z29.array(z29.string()).optional()
2994
3226
  }).passthrough();
2995
- var McpJsonSchema = z28.object({
2996
- mcpServers: z28.record(z28.string(), McpServerEntrySchema2).optional()
3227
+ var McpJsonSchema = z29.object({
3228
+ mcpServers: z29.record(z29.string(), McpServerEntrySchema2).optional()
2997
3229
  }).passthrough();
2998
3230
  var MCP_JSON_RELATIVE_PATH = ".mcp.json";
2999
3231
  function getMcpJsonPath(dir) {
@@ -3872,12 +4104,21 @@ ${question.answerMd ?? ""}`;
3872
4104
  // package.json
3873
4105
  var package_default = {
3874
4106
  name: "@quiel/cli",
3875
- version: "0.1.0",
3876
- description: "CLI \u0438 MCP-\u0441\u0435\u0440\u0432\u0435\u0440 quiel: \u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0430\u0435\u0442 Claude Code \u0443\u0447\u0430\u0441\u0442\u043D\u0438\u043A\u0430 \u043A \u043F\u043B\u0430\u0442\u0444\u043E\u0440\u043C\u0435",
4107
+ version: "0.2.0",
4108
+ description: "CLI \u0438 MCP-\u0441\u0435\u0440\u0432\u0435\u0440 Quiel: \u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0430\u0435\u0442 Claude Code \u0443\u0447\u0430\u0441\u0442\u043D\u0438\u043A\u0430 \u043A \u043F\u043B\u0430\u0442\u0444\u043E\u0440\u043C\u0435",
4109
+ homepage: "https://quiel.ai",
4110
+ keywords: [
4111
+ "quiel",
4112
+ "claude-code",
4113
+ "mcp",
4114
+ "mcp-server",
4115
+ "ai-agents",
4116
+ "task-tracker"
4117
+ ],
3877
4118
  license: "UNLICENSED",
3878
4119
  type: "module",
3879
4120
  bin: {
3880
- quiel: "./dist/cli.js"
4121
+ quiel: "dist/cli.js"
3881
4122
  },
3882
4123
  files: [
3883
4124
  "dist"
@@ -4130,7 +4371,7 @@ function buildCommitMessage(params) {
4130
4371
  const subject = `${params.commitPrefix} ${params.title}`.trim();
4131
4372
  return `${subject}
4132
4373
 
4133
- Quiel-Task: ${params.taskKey}
4374
+ ${buildTaskTrailer(params.taskKey)}
4134
4375
  `;
4135
4376
  }
4136
4377
  async function commitAll(params) {
@@ -4383,6 +4624,77 @@ async function submitDirectTask(params) {
4383
4624
  };
4384
4625
  }
4385
4626
 
4627
+ // src/git/submit-pr.ts
4628
+ async function pushTaskBranch(params) {
4629
+ const remote = params.remote ?? "origin";
4630
+ const branchCheck = requireValidBranchName(params.branchName, "\u0418\u043C\u044F \u0432\u0435\u0442\u043A\u0438 \u0437\u0430\u0434\u0430\u0447\u0438");
4631
+ if (!branchCheck.ok) return branchCheck;
4632
+ const ready = await assertReadyToPush(params);
4633
+ if (!ready.ok) return ready;
4634
+ const pushResult = await runGit(
4635
+ ["push", "--set-upstream", remote, `HEAD:refs/heads/${params.branchName}`],
4636
+ { cwd: params.worktreeDir }
4637
+ );
4638
+ if (!pushResult.ok) {
4639
+ return gitErr(
4640
+ describeGitFailure(`git push ${remote} HEAD:refs/heads/${params.branchName}`, pushResult)
4641
+ );
4642
+ }
4643
+ return gitOk({ pushedTo: `${remote}/${params.branchName}` });
4644
+ }
4645
+ async function submitPullRequestTask(params) {
4646
+ const remote = params.remote ?? "origin";
4647
+ let worktreeDir;
4648
+ if (params.worktreeDir) {
4649
+ worktreeDir = params.worktreeDir;
4650
+ } else {
4651
+ const worktree = await ensureWorktree({
4652
+ repoRoot: params.repoRoot,
4653
+ branchName: params.branchName,
4654
+ defaultBranch: params.defaultBranch,
4655
+ remote,
4656
+ worktreesRoot: params.worktreesRoot
4657
+ });
4658
+ if (!worktree.ok) return { status: "refused", message: worktree.message };
4659
+ worktreeDir = worktree.data.worktreeDir;
4660
+ }
4661
+ const commit = await commitAll({
4662
+ worktreeDir,
4663
+ commitPrefix: params.commitPrefix,
4664
+ title: params.taskTitle,
4665
+ taskKey: params.taskKey
4666
+ });
4667
+ if (!commit.ok) return { status: "refused", worktreeDir, message: commit.message };
4668
+ const rebase = await rebaseOntoDefault({
4669
+ worktreeDir,
4670
+ defaultBranch: params.defaultBranch,
4671
+ remote
4672
+ });
4673
+ if (!rebase.ok) return { status: "refused", worktreeDir, message: rebase.message };
4674
+ const conflicted = rebase.data.outcome === "conflict";
4675
+ const push = await pushTaskBranch({ worktreeDir, branchName: params.branchName, remote });
4676
+ if (!push.ok) return { status: "refused", worktreeDir, message: push.message };
4677
+ const sha = await getHeadSha(worktreeDir);
4678
+ let worktreeRemoved = false;
4679
+ if (params.removeWorktreeOnSuccess !== false) {
4680
+ const removed = await removeWorktree(params.repoRoot, worktreeDir);
4681
+ if (removed.ok) {
4682
+ await runGit(["branch", "-D", params.branchName], { cwd: params.repoRoot });
4683
+ worktreeRemoved = true;
4684
+ }
4685
+ }
4686
+ return {
4687
+ status: "pushed",
4688
+ worktreeDir,
4689
+ branchName: params.branchName,
4690
+ commitSha: sha.ok ? sha.data : null,
4691
+ pushedTo: push.data.pushedTo,
4692
+ conflicted,
4693
+ conflictedFiles: rebase.data.conflictedFiles,
4694
+ worktreeRemoved
4695
+ };
4696
+ }
4697
+
4386
4698
  // src/mcp/task-worktree.ts
4387
4699
  function planTaskWorktree(project, mode = "isolated") {
4388
4700
  if (mode === "checkout") {
@@ -4454,7 +4766,8 @@ async function nextTaskHandler(args, runtime) {
4454
4766
  currentTask: {
4455
4767
  taskId: task.task.id,
4456
4768
  taskKey: task.task.key,
4457
- resumeToken: task.lease.resumeToken
4769
+ resumeToken: task.lease.resumeToken,
4770
+ gitMode: task.project.gitMode
4458
4771
  }
4459
4772
  },
4460
4773
  stateFilePath
@@ -4476,6 +4789,7 @@ async function nextTaskHandler(args, runtime) {
4476
4789
  taskId: task.task.id,
4477
4790
  taskKey: task.task.key,
4478
4791
  resumeToken: task.lease.resumeToken,
4792
+ gitMode: task.project.gitMode,
4479
4793
  worktreeDir: worktree.data.worktreeDir
4480
4794
  }
4481
4795
  },
@@ -4738,7 +5052,7 @@ async function settleApproval(ack, commandCwd, runtime, waitSecUsed) {
4738
5052
  }
4739
5053
 
4740
5054
  // src/mcp/set-mode.ts
4741
- import { z as z29 } from "zod";
5055
+ import { z as z30 } from "zod";
4742
5056
 
4743
5057
  // src/cli/mode.ts
4744
5058
  function parseModeArg(raw) {
@@ -4779,7 +5093,7 @@ async function requestModeChange(modeArg, options = {}) {
4779
5093
 
4780
5094
  // src/mcp/set-mode.ts
4781
5095
  var setModeInputShape = {
4782
- mode: z29.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)")
5096
+ mode: z30.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)")
4783
5097
  };
4784
5098
  async function setModeHandler(args, runtime) {
4785
5099
  const result = await requestModeChange(args.mode, {
@@ -4794,20 +5108,20 @@ async function setModeHandler(args, runtime) {
4794
5108
  }
4795
5109
 
4796
5110
  // src/mcp/submit-work.ts
4797
- import { z as z30 } from "zod";
5111
+ import { z as z31 } from "zod";
4798
5112
  var submitWorkInputShape = {
4799
- branchName: z30.string().min(1).describe(
5113
+ branchName: z31.string().min(1).describe(
4800
5114
  "\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."
4801
5115
  ),
4802
- defaultBranch: z30.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."),
4803
- commitPrefix: z30.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:".'),
4804
- taskKey: z30.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."),
4805
- taskTitle: z30.string().min(1).describe("\u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A \u0437\u0430\u0434\u0430\u0447\u0438 \u2014 \u0438\u0437 task.title."),
4806
- repoRoot: z30.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."),
4807
- testsPassed: z30.boolean().optional().describe(
5116
+ defaultBranch: z31.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."),
5117
+ commitPrefix: z31.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:".'),
5118
+ taskKey: z31.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."),
5119
+ taskTitle: z31.string().min(1).describe("\u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A \u0437\u0430\u0434\u0430\u0447\u0438 \u2014 \u0438\u0437 task.title."),
5120
+ repoRoot: z31.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."),
5121
+ testsPassed: z31.boolean().optional().describe(
4808
5122
  "\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."
4809
5123
  ),
4810
- requireTestsPassed: z30.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.")
5124
+ requireTestsPassed: z31.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.")
4811
5125
  };
4812
5126
  async function submitWorkHandler(args, runtime) {
4813
5127
  const state = readState(runtime.stateFilePath);
@@ -4819,6 +5133,9 @@ async function submitWorkHandler(args, runtime) {
4819
5133
  );
4820
5134
  }
4821
5135
  }
5136
+ if (state.currentTask?.gitMode === GitMode.PR) {
5137
+ return submitViaPullRequest(args, runtime, state.currentTask);
5138
+ }
4822
5139
  const result = await submitDirectTask({
4823
5140
  repoRoot: args.repoRoot ?? runtime.cwd,
4824
5141
  ...state.currentTask?.worktreeDir ? { worktreeDir: state.currentTask.worktreeDir } : {},
@@ -4848,6 +5165,51 @@ async function submitWorkHandler(args, runtime) {
4848
5165
  \u041D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u043E\u0442\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u043E. \u0420\u0430\u0437\u0431\u0435\u0440\u0438\u0441\u044C \u0441 \u043F\u0440\u0438\u0447\u0438\u043D\u043E\u0439 \u0438\u043B\u0438 \u0432\u044B\u0437\u043E\u0432\u0438 report("partial"), \u0435\u0441\u043B\u0438 \u0441\u0430\u043C \u043D\u0435 \u043C\u043E\u0436\u0435\u0448\u044C.`
4849
5166
  );
4850
5167
  }
5168
+ async function submitViaPullRequest(args, runtime, currentTask) {
5169
+ const result = await submitPullRequestTask({
5170
+ repoRoot: args.repoRoot ?? runtime.cwd,
5171
+ ...currentTask.worktreeDir ? { worktreeDir: currentTask.worktreeDir } : {},
5172
+ branchName: args.branchName,
5173
+ defaultBranch: args.defaultBranch,
5174
+ taskKey: args.taskKey,
5175
+ taskTitle: args.taskTitle,
5176
+ commitPrefix: args.commitPrefix
5177
+ });
5178
+ if (result.status !== "pushed") {
5179
+ return errorResult(
5180
+ `${result.message}
5181
+
5182
+ \u041D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u043E\u0442\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u043E. \u0420\u0430\u0437\u0431\u0435\u0440\u0438\u0441\u044C \u0441 \u043F\u0440\u0438\u0447\u0438\u043D\u043E\u0439 \u0438\u043B\u0438 \u0432\u044B\u0437\u043E\u0432\u0438 report("partial"), \u0435\u0441\u043B\u0438 \u0441\u0430\u043C \u043D\u0435 \u043C\u043E\u0436\u0435\u0448\u044C.`
5183
+ );
5184
+ }
5185
+ const conflictNote = result.conflicted ? `
5186
+
5187
+ \u0412\u041D\u0418\u041C\u0410\u041D\u0418\u0415: rebase \u043D\u0430 ${args.defaultBranch} \u043A\u043E\u043D\u0444\u043B\u0438\u043A\u0442\u0443\u0435\u0442 (${result.conflictedFiles.join(", ")}). \u0412\u0435\u0442\u043A\u0430 \u043E\u0442\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0430 \u043A\u0430\u043A \u0435\u0441\u0442\u044C \u2014 \u0442\u0430\u043A \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0422\u0417 \u0434\u043B\u044F PR-\u0440\u0435\u0436\u0438\u043C\u0430. \u041A\u043E\u043D\u0444\u043B\u0438\u043A\u0442 \u0442\u044B \u041D\u0415 \u0440\u0435\u0448\u0430\u0435\u0448\u044C \u0441\u0430\u043C, PR \u0431\u0443\u0434\u0435\u0442 \u043F\u043E\u043C\u0435\u0447\u0435\u043D \xABconflicts\xBB, \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044F \u0447\u0435\u043B\u043E\u0432\u0435\u043A. \u0423\u043F\u043E\u043C\u044F\u043D\u0438 \u044D\u0442\u043E \u0432 report.` : "";
5188
+ const opened = await callServerOrError(
5189
+ runtime.client,
5190
+ "task:open_pr",
5191
+ taskOpenPrPayloadSchema.parse({
5192
+ taskId: currentTask.taskId,
5193
+ branchName: args.branchName,
5194
+ conflicted: result.conflicted,
5195
+ ...result.conflictedFiles.length > 0 ? { conflictedFiles: [...result.conflictedFiles] } : {}
5196
+ }),
5197
+ taskOpenPrAckSchema
5198
+ );
5199
+ if (!opened.ok) {
5200
+ return textResult(
5201
+ `\u0412\u0435\u0442\u043A\u0430 \u043E\u0442\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0430 \u0432 ${result.pushedTo}. \u041A\u043E\u043C\u043C\u0438\u0442: ${result.commitSha ?? "\u0431\u0435\u0437 \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u0439"}.` + conflictNote + `
5202
+
5203
+ \u041D\u043E PR \u043F\u043B\u0430\u0442\u0444\u043E\u0440\u043C\u0430 \u043D\u0435 \u043E\u0442\u043A\u0440\u044B\u043B\u0430: ${opened.message}. \u0420\u0430\u0431\u043E\u0442\u0430 \u041D\u0415 \u043F\u043E\u0442\u0435\u0440\u044F\u043D\u0430 \u2014 \u043E\u043D\u0430 \u0432 \u0432\u0435\u0442\u043A\u0435 "${args.branchName}" \u043D\u0430 remote. \u0412\u044B\u0437\u043E\u0432\u0438 report \u0441\u043E \u0441\u0441\u044B\u043B\u043A\u043E\u0439 \u043D\u0430 \u0432\u0435\u0442\u043A\u0443 \u0438 \u0443\u043F\u043E\u043C\u044F\u043D\u0438, \u0447\u0442\u043E PR \u043D\u0435 \u0441\u043E\u0437\u0434\u0430\u043D.`
5204
+ );
5205
+ }
5206
+ const createdNote = opened.data.created ? "PR \u0441\u043E\u0437\u0434\u0430\u043D" : "PR \u0434\u043B\u044F \u044D\u0442\u043E\u0439 \u0432\u0435\u0442\u043A\u0438 \u0443\u0436\u0435 \u0431\u044B\u043B \u043E\u0442\u043A\u0440\u044B\u0442";
5207
+ return textResult(
5208
+ `\u0412\u0435\u0442\u043A\u0430 \u043E\u0442\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0430 \u0432 ${result.pushedTo}. \u041A\u043E\u043C\u043C\u0438\u0442: ${result.commitSha ?? "\u0431\u0435\u0437 \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u0439"}. ${createdNote}: ${opened.data.url}` + conflictNote + `
5209
+
5210
+ \u0422\u0435\u043F\u0435\u0440\u044C \u0432\u044B\u0437\u043E\u0432\u0438 report \u0438 \u043F\u0435\u0440\u0435\u0434\u0430\u0439 \u0432 links \u0441\u0441\u044B\u043B\u043A\u0443 \u043D\u0430 PR (${opened.data.url}).`
5211
+ );
5212
+ }
4851
5213
 
4852
5214
  // src/mcp/tasks.ts
4853
5215
  var createTaskInputShape = {
@@ -5026,7 +5388,7 @@ function registerTools(server, runtime) {
5026
5388
  "get_context",
5027
5389
  {
5028
5390
  title: "\u041F\u043E\u043B\u0443\u0447\u0438\u0442\u044C \u043A\u043E\u043D\u0442\u0435\u043A\u0441\u0442 \u0437\u0430\u0434\u0430\u0447\u0438",
5029
- description: "\u0421\u043F\u0435\u0446\u0438\u0444\u0438\u043A\u0430\u0446\u0438\u044F \u043F\u0440\u043E\u0435\u043A\u0442\u0430, \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u044B-\u0440\u0435\u0448\u0435\u043D\u0438\u044F, \u0441\u0432\u044F\u0437\u0430\u043D\u043D\u044B\u0435/\u0437\u0430\u0432\u0438\u0441\u0438\u043C\u044B\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u0441 \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u0430\u043C\u0438, \u0441\u0441\u044B\u043B\u043A\u0438 \u043D\u0430 \u0440\u0435\u043F\u043E\u0437\u0438\u0442\u043E\u0440\u0438\u0439 \u0438 \u0432\u0435\u0442\u043A\u0443 (\xA710.3 \u0422\u0417).",
5391
+ description: "\u0421\u043F\u0435\u0446\u0438\u0444\u0438\u043A\u0430\u0446\u0438\u044F \u043F\u0440\u043E\u0435\u043A\u0442\u0430, \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u044B-\u0440\u0435\u0448\u0435\u043D\u0438\u044F, \u0441\u0432\u044F\u0437\u0430\u043D\u043D\u044B\u0435/\u0437\u0430\u0432\u0438\u0441\u0438\u043C\u044B\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u0441 \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u0430\u043C\u0438, \u0441\u0441\u044B\u043B\u043A\u0438 \u043D\u0430 \u0440\u0435\u043F\u043E\u0437\u0438\u0442\u043E\u0440\u0438\u0439 \u0438 \u0432\u0435\u0442\u043A\u0443 (\xA710.3 \u0422\u0417). \u0412\u0410\u0416\u041D\u041E: \u0443 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430 \u043C\u043E\u0436\u0435\u0442 \u043D\u0435 \u0431\u044B\u0442\u044C \u0442\u0435\u043A\u0441\u0442\u0430 \u2014 \u0442\u043E\u0433\u0434\u0430 \u0437\u0430\u043F\u043E\u043B\u043D\u0435\u043D\u043E \u043F\u043E\u043B\u0435 `file` (\u0441\u043F\u0435\u0446\u0438\u0444\u0438\u043A\u0430\u0446\u0438\u044F \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043D\u0430 \u0444\u0430\u0439\u043B\u043E\u043C, \u043D\u0430\u043F\u0440\u0438\u043C\u0435\u0440 PDF). \u0412 \u044D\u0442\u043E\u043C \u0441\u043B\u0443\u0447\u0430\u0435 \u0441\u043A\u0430\u0447\u0430\u0439 `file.downloadUrl` \u0438 \u043F\u0440\u043E\u0447\u0438\u0442\u0430\u0439 \u0444\u0430\u0439\u043B: \u043F\u0443\u0441\u0442\u043E\u0439 `contentMd` \u0440\u044F\u0434\u043E\u043C \u0441 \u043D\u0435\u043F\u0443\u0441\u0442\u044B\u043C `file` \u041D\u0415 \u043E\u0437\u043D\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043E \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430 \u043D\u0435\u0442. \u0421\u0441\u044B\u043B\u043A\u0430 \u0436\u0438\u0432\u0451\u0442 `file.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 \u0441\u043F\u0435\u0446\u0438\u0444\u0438\u043A\u0430\u0446\u0438\u0438.",
5030
5392
  inputSchema: getContextInputShape
5031
5393
  },
5032
5394
  (args) => getContextHandler(args, runtime)
@@ -5230,13 +5592,13 @@ function formatConnectResult(result) {
5230
5592
  }
5231
5593
 
5232
5594
  // src/hooks/pre-compact.ts
5233
- import { z as z31 } from "zod";
5234
- var PreCompactInputSchema = z31.object({
5235
- hook_event_name: z31.literal("PreCompact"),
5236
- session_id: z31.string(),
5237
- cwd: z31.string(),
5238
- trigger: z31.enum(["manual", "auto"]),
5239
- custom_instructions: z31.string().nullable()
5595
+ import { z as z32 } from "zod";
5596
+ var PreCompactInputSchema = z32.object({
5597
+ hook_event_name: z32.literal("PreCompact"),
5598
+ session_id: z32.string(),
5599
+ cwd: z32.string(),
5600
+ trigger: z32.enum(["manual", "auto"]),
5601
+ custom_instructions: z32.string().nullable()
5240
5602
  }).passthrough();
5241
5603
  function preCompactHook(_input, state, now = () => (/* @__PURE__ */ new Date()).toISOString()) {
5242
5604
  const lastPreCompact = state.currentTask ? { ...state.currentTask, savedAt: now() } : null;
@@ -5245,14 +5607,14 @@ function preCompactHook(_input, state, now = () => (/* @__PURE__ */ new Date()).
5245
5607
 
5246
5608
  // src/hooks/pre-tool-use.ts
5247
5609
  import { isAbsolute as isAbsolute2, relative as relative2, resolve as resolve3 } from "path";
5248
- import { z as z32 } from "zod";
5249
- var PreToolUseInputSchema = z32.object({
5250
- hook_event_name: z32.literal("PreToolUse"),
5251
- session_id: z32.string(),
5252
- cwd: z32.string(),
5253
- tool_name: z32.string(),
5254
- tool_input: z32.record(z32.string(), z32.unknown()),
5255
- tool_use_id: z32.string()
5610
+ import { z as z33 } from "zod";
5611
+ var PreToolUseInputSchema = z33.object({
5612
+ hook_event_name: z33.literal("PreToolUse"),
5613
+ session_id: z33.string(),
5614
+ cwd: z33.string(),
5615
+ tool_name: z33.string(),
5616
+ tool_input: z33.record(z33.string(), z33.unknown()),
5617
+ tool_use_id: z33.string()
5256
5618
  }).passthrough();
5257
5619
  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.";
5258
5620
  var BOOTSTRAP_COMMAND_RE = /^quiel\s+(connect|status)\b/;
@@ -5397,16 +5759,16 @@ function handleFileWrite(input, state, now) {
5397
5759
  }
5398
5760
 
5399
5761
  // src/hooks/run.ts
5400
- import { z as z36 } from "zod";
5762
+ import { z as z37 } from "zod";
5401
5763
 
5402
5764
  // src/hooks/session-start.ts
5403
- import { z as z33 } from "zod";
5404
- var SessionStartInputSchema = z33.object({
5405
- hook_event_name: z33.literal("SessionStart"),
5406
- session_id: z33.string(),
5407
- cwd: z33.string(),
5408
- source: z33.enum(["startup", "resume", "clear", "compact", "fork"]),
5409
- model: z33.string().optional()
5765
+ import { z as z34 } from "zod";
5766
+ var SessionStartInputSchema = z34.object({
5767
+ hook_event_name: z34.literal("SessionStart"),
5768
+ session_id: z34.string(),
5769
+ cwd: z34.string(),
5770
+ source: z34.enum(["startup", "resume", "clear", "compact", "fork"]),
5771
+ model: z34.string().optional()
5410
5772
  }).passthrough();
5411
5773
  var SESSION_RESET_SOURCES = /* @__PURE__ */ new Set([
5412
5774
  "startup",
@@ -5445,13 +5807,13 @@ function sessionStartHook(input, state) {
5445
5807
  }
5446
5808
 
5447
5809
  // src/hooks/stop.ts
5448
- import { z as z34 } from "zod";
5449
- var StopInputSchema = z34.object({
5450
- hook_event_name: z34.literal("Stop"),
5451
- session_id: z34.string(),
5452
- cwd: z34.string(),
5453
- stop_hook_active: z34.boolean(),
5454
- last_assistant_message: z34.string().optional()
5810
+ import { z as z35 } from "zod";
5811
+ var StopInputSchema = z35.object({
5812
+ hook_event_name: z35.literal("Stop"),
5813
+ session_id: z35.string(),
5814
+ cwd: z35.string(),
5815
+ stop_hook_active: z35.boolean(),
5816
+ last_assistant_message: z35.string().optional()
5455
5817
  }).passthrough();
5456
5818
  function taskLabel(state) {
5457
5819
  if (!state.currentTask) return "";
@@ -5495,8 +5857,8 @@ function stopHook(input, state) {
5495
5857
  }
5496
5858
 
5497
5859
  // src/hooks/stop-failure.ts
5498
- import { z as z35 } from "zod";
5499
- var StopFailureErrorTypeSchema = z35.enum([
5860
+ import { z as z36 } from "zod";
5861
+ var StopFailureErrorTypeSchema = z36.enum([
5500
5862
  "rate_limit",
5501
5863
  "overloaded",
5502
5864
  "authentication_failed",
@@ -5509,13 +5871,13 @@ var StopFailureErrorTypeSchema = z35.enum([
5509
5871
  "max_output_tokens",
5510
5872
  "unknown"
5511
5873
  ]);
5512
- var StopFailureInputSchema = z35.object({
5513
- hook_event_name: z35.literal("StopFailure"),
5514
- session_id: z35.string(),
5515
- cwd: z35.string(),
5874
+ var StopFailureInputSchema = z36.object({
5875
+ hook_event_name: z36.literal("StopFailure"),
5876
+ session_id: z36.string(),
5877
+ cwd: z36.string(),
5516
5878
  error: StopFailureErrorTypeSchema,
5517
- error_details: z35.unknown().optional(),
5518
- last_assistant_message: z35.string().optional()
5879
+ error_details: z36.unknown().optional(),
5880
+ last_assistant_message: z36.string().optional()
5519
5881
  }).passthrough();
5520
5882
  function extractRetryAfterSec(errorDetails) {
5521
5883
  if (typeof errorDetails === "number" && Number.isFinite(errorDetails) && errorDetails >= 0) {
@@ -5544,7 +5906,7 @@ function stopFailureHook(input, _state) {
5544
5906
  }
5545
5907
 
5546
5908
  // src/hooks/run.ts
5547
- var HookInputSchema = z36.discriminatedUnion("hook_event_name", [
5909
+ var HookInputSchema = z37.discriminatedUnion("hook_event_name", [
5548
5910
  SessionStartInputSchema,
5549
5911
  StopInputSchema,
5550
5912
  StopFailureInputSchema,