@ghx-dev/core 0.2.0 → 0.2.2

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 (161) hide show
  1. package/.claude-plugin/plugin.json +2 -2
  2. package/README.md +68 -224
  3. package/dist/cards/issue.assignees.add.yaml +1 -0
  4. package/dist/cards/issue.assignees.remove.yaml +1 -0
  5. package/dist/cards/issue.assignees.set.yaml +1 -0
  6. package/dist/cards/issue.close.yaml +1 -0
  7. package/dist/cards/issue.comments.create.yaml +1 -0
  8. package/dist/cards/issue.comments.list.yaml +1 -0
  9. package/dist/cards/issue.create.yaml +1 -0
  10. package/dist/cards/issue.delete.yaml +1 -0
  11. package/dist/cards/issue.labels.add.yaml +1 -0
  12. package/dist/cards/issue.labels.remove.yaml +1 -0
  13. package/dist/cards/issue.labels.set.yaml +1 -0
  14. package/dist/cards/issue.list.yaml +1 -0
  15. package/dist/cards/issue.milestone.clear.yaml +1 -0
  16. package/dist/cards/issue.milestone.set.yaml +1 -0
  17. package/dist/cards/issue.relations.blocked_by.add.yaml +1 -0
  18. package/dist/cards/issue.relations.blocked_by.remove.yaml +1 -0
  19. package/dist/cards/issue.relations.parent.remove.yaml +1 -0
  20. package/dist/cards/issue.relations.parent.set.yaml +1 -0
  21. package/dist/cards/issue.relations.prs.list.yaml +1 -0
  22. package/dist/cards/issue.relations.view.yaml +1 -0
  23. package/dist/cards/issue.reopen.yaml +1 -0
  24. package/dist/cards/issue.update.yaml +1 -0
  25. package/dist/cards/issue.view.yaml +1 -0
  26. package/dist/cards/pr.assignees.add.yaml +6 -2
  27. package/dist/cards/pr.assignees.remove.yaml +6 -2
  28. package/dist/cards/pr.branch.update.yaml +6 -2
  29. package/dist/cards/pr.create.yaml +7 -3
  30. package/dist/cards/pr.diff.files.yaml +1 -0
  31. package/dist/cards/pr.list.yaml +1 -0
  32. package/dist/cards/pr.merge.status.yaml +1 -0
  33. package/dist/cards/pr.merge.yaml +9 -3
  34. package/dist/cards/pr.reviews.list.yaml +1 -0
  35. package/dist/cards/pr.reviews.request.yaml +6 -3
  36. package/dist/cards/pr.reviews.submit.yaml +1 -0
  37. package/dist/cards/pr.threads.list.yaml +1 -0
  38. package/dist/cards/pr.threads.reply.yaml +1 -0
  39. package/dist/cards/pr.threads.resolve.yaml +1 -0
  40. package/dist/cards/pr.threads.unresolve.yaml +1 -0
  41. package/dist/cards/pr.update.yaml +7 -2
  42. package/dist/cards/pr.view.yaml +1 -0
  43. package/dist/cards/project_v2.fields.list.yaml +18 -2
  44. package/dist/cards/project_v2.items.field.update.yaml +8 -5
  45. package/dist/cards/project_v2.items.issue.add.yaml +9 -5
  46. package/dist/cards/project_v2.items.issue.remove.yaml +8 -5
  47. package/dist/cards/project_v2.items.list.yaml +8 -2
  48. package/dist/cards/project_v2.org.view.yaml +6 -2
  49. package/dist/cards/project_v2.user.view.yaml +6 -2
  50. package/dist/cards/release.list.yaml +8 -3
  51. package/dist/cards/release.view.yaml +8 -4
  52. package/dist/cards/repo.issue_types.list.yaml +7 -3
  53. package/dist/cards/repo.labels.list.yaml +7 -2
  54. package/dist/cards/repo.view.yaml +1 -0
  55. package/dist/chunk-7HUKYNI2.js +536 -0
  56. package/dist/chunk-7HUKYNI2.js.map +1 -0
  57. package/dist/{chunk-HEHONZTO.js → chunk-C2KRRSSX.js} +1 -1
  58. package/dist/chunk-C2KRRSSX.js.map +1 -0
  59. package/dist/chunk-GQO6BHJV.js +98 -0
  60. package/dist/chunk-GQO6BHJV.js.map +1 -0
  61. package/dist/chunk-H7CLZHRO.js +280 -0
  62. package/dist/chunk-H7CLZHRO.js.map +1 -0
  63. package/dist/chunk-NQ53ETYV.js +128 -0
  64. package/dist/chunk-NQ53ETYV.js.map +1 -0
  65. package/dist/{chunk-BIWBJA2F.js → chunk-OQWLEFAH.js} +220 -12
  66. package/dist/chunk-OQWLEFAH.js.map +1 -0
  67. package/dist/{chunk-Q7RCIK2C.js → chunk-Q2NW7DJE.js} +167 -62
  68. package/dist/chunk-Q2NW7DJE.js.map +1 -0
  69. package/dist/{pr-queries-UOEOXIJQ.js → chunk-QRHKAMRY.js} +11 -131
  70. package/dist/chunk-QRHKAMRY.js.map +1 -0
  71. package/dist/{chunk-3P3KHWFU.js → chunk-T3L2VDOS.js} +1080 -727
  72. package/dist/chunk-T3L2VDOS.js.map +1 -0
  73. package/dist/{issue-queries-GRA4MKPD.js → chunk-TGL33GEA.js} +7 -83
  74. package/dist/chunk-TGL33GEA.js.map +1 -0
  75. package/dist/chunk-ZGBVX2VG.js +32 -0
  76. package/dist/chunk-ZGBVX2VG.js.map +1 -0
  77. package/dist/cli/index.js +80 -15
  78. package/dist/cli/index.js.map +1 -1
  79. package/dist/core/registry/cards/issue.assignees.add.yaml +1 -0
  80. package/dist/core/registry/cards/issue.assignees.remove.yaml +1 -0
  81. package/dist/core/registry/cards/issue.assignees.set.yaml +1 -0
  82. package/dist/core/registry/cards/issue.close.yaml +1 -0
  83. package/dist/core/registry/cards/issue.comments.create.yaml +1 -0
  84. package/dist/core/registry/cards/issue.comments.list.yaml +1 -0
  85. package/dist/core/registry/cards/issue.create.yaml +1 -0
  86. package/dist/core/registry/cards/issue.delete.yaml +1 -0
  87. package/dist/core/registry/cards/issue.labels.add.yaml +1 -0
  88. package/dist/core/registry/cards/issue.labels.remove.yaml +1 -0
  89. package/dist/core/registry/cards/issue.labels.set.yaml +1 -0
  90. package/dist/core/registry/cards/issue.list.yaml +1 -0
  91. package/dist/core/registry/cards/issue.milestone.clear.yaml +1 -0
  92. package/dist/core/registry/cards/issue.milestone.set.yaml +1 -0
  93. package/dist/core/registry/cards/issue.relations.blocked_by.add.yaml +1 -0
  94. package/dist/core/registry/cards/issue.relations.blocked_by.remove.yaml +1 -0
  95. package/dist/core/registry/cards/issue.relations.parent.remove.yaml +1 -0
  96. package/dist/core/registry/cards/issue.relations.parent.set.yaml +1 -0
  97. package/dist/core/registry/cards/issue.relations.prs.list.yaml +1 -0
  98. package/dist/core/registry/cards/issue.relations.view.yaml +1 -0
  99. package/dist/core/registry/cards/issue.reopen.yaml +1 -0
  100. package/dist/core/registry/cards/issue.update.yaml +1 -0
  101. package/dist/core/registry/cards/issue.view.yaml +1 -0
  102. package/dist/core/registry/cards/pr.assignees.add.yaml +6 -2
  103. package/dist/core/registry/cards/pr.assignees.remove.yaml +6 -2
  104. package/dist/core/registry/cards/pr.branch.update.yaml +6 -2
  105. package/dist/core/registry/cards/pr.create.yaml +7 -3
  106. package/dist/core/registry/cards/pr.diff.files.yaml +1 -0
  107. package/dist/core/registry/cards/pr.list.yaml +1 -0
  108. package/dist/core/registry/cards/pr.merge.status.yaml +1 -0
  109. package/dist/core/registry/cards/pr.merge.yaml +9 -3
  110. package/dist/core/registry/cards/pr.reviews.list.yaml +1 -0
  111. package/dist/core/registry/cards/pr.reviews.request.yaml +6 -3
  112. package/dist/core/registry/cards/pr.reviews.submit.yaml +1 -0
  113. package/dist/core/registry/cards/pr.threads.list.yaml +1 -0
  114. package/dist/core/registry/cards/pr.threads.reply.yaml +1 -0
  115. package/dist/core/registry/cards/pr.threads.resolve.yaml +1 -0
  116. package/dist/core/registry/cards/pr.threads.unresolve.yaml +1 -0
  117. package/dist/core/registry/cards/pr.update.yaml +7 -2
  118. package/dist/core/registry/cards/pr.view.yaml +1 -0
  119. package/dist/core/registry/cards/project_v2.fields.list.yaml +18 -2
  120. package/dist/core/registry/cards/project_v2.items.field.update.yaml +8 -5
  121. package/dist/core/registry/cards/project_v2.items.issue.add.yaml +9 -5
  122. package/dist/core/registry/cards/project_v2.items.issue.remove.yaml +8 -5
  123. package/dist/core/registry/cards/project_v2.items.list.yaml +8 -2
  124. package/dist/core/registry/cards/project_v2.org.view.yaml +6 -2
  125. package/dist/core/registry/cards/project_v2.user.view.yaml +6 -2
  126. package/dist/core/registry/cards/release.list.yaml +8 -3
  127. package/dist/core/registry/cards/release.view.yaml +8 -4
  128. package/dist/core/registry/cards/repo.issue_types.list.yaml +7 -3
  129. package/dist/core/registry/cards/repo.labels.list.yaml +7 -2
  130. package/dist/core/registry/cards/repo.view.yaml +1 -0
  131. package/dist/index.d.ts +457 -0
  132. package/dist/index.js +12 -4
  133. package/dist/index.js.map +1 -1
  134. package/dist/{issue-mutations-FJNZW7L5.js → issue-mutations-DIWPF3JH.js} +98 -121
  135. package/dist/issue-mutations-DIWPF3JH.js.map +1 -0
  136. package/dist/issue-queries-YQL65J7X.js +93 -0
  137. package/dist/issue-queries-YQL65J7X.js.map +1 -0
  138. package/dist/{pr-mutations-UG67YOF5.js → pr-mutations-BVHDCAPR.js} +235 -95
  139. package/dist/pr-mutations-BVHDCAPR.js.map +1 -0
  140. package/dist/pr-queries-NUL2UZJB.js +143 -0
  141. package/dist/pr-queries-NUL2UZJB.js.map +1 -0
  142. package/dist/project-3ZSPVIOC.js +429 -0
  143. package/dist/project-3ZSPVIOC.js.map +1 -0
  144. package/dist/release-IQCWD655.js +57 -0
  145. package/dist/release-IQCWD655.js.map +1 -0
  146. package/dist/repo-JF47JAZG.js +82 -0
  147. package/dist/repo-JF47JAZG.js.map +1 -0
  148. package/package.json +9 -9
  149. package/skills/using-ghx/SKILL.md +78 -10
  150. package/dist/chunk-3P3KHWFU.js.map +0 -1
  151. package/dist/chunk-BIWBJA2F.js.map +0 -1
  152. package/dist/chunk-HEHONZTO.js.map +0 -1
  153. package/dist/chunk-Q7RCIK2C.js.map +0 -1
  154. package/dist/chunk-TDABI6C7.js +0 -167
  155. package/dist/chunk-TDABI6C7.js.map +0 -1
  156. package/dist/issue-mutations-FJNZW7L5.js.map +0 -1
  157. package/dist/issue-queries-GRA4MKPD.js.map +0 -1
  158. package/dist/pr-mutations-UG67YOF5.js.map +0 -1
  159. package/dist/pr-queries-UOEOXIJQ.js.map +0 -1
  160. package/dist/repo-JDUHFPZF.js +0 -66
  161. package/dist/repo-JDUHFPZF.js.map +0 -1
@@ -1,3 +1,22 @@
1
+ import {
2
+ AddProjectV2ItemDocument,
3
+ ProjectV2FieldsListOrgDocument,
4
+ ProjectV2ItemsListOrgDocument,
5
+ ProjectV2OrgViewDocument,
6
+ ProjectV2UserViewDocument,
7
+ RemoveProjectV2ItemDocument,
8
+ UpdateProjectV2ItemFieldDocument
9
+ } from "./chunk-H7CLZHRO.js";
10
+ import {
11
+ RepoIssueTypesListDocument,
12
+ RepoLabelsListDocument,
13
+ RepoViewDocument
14
+ } from "./chunk-NQ53ETYV.js";
15
+ import {
16
+ IssueCommentsListDocument,
17
+ IssueListDocument,
18
+ IssueViewDocument
19
+ } from "./chunk-TGL33GEA.js";
1
20
  import {
2
21
  IssueAssigneesAddDocument,
3
22
  IssueAssigneesLookupByNumberDocument,
@@ -8,31 +27,56 @@ import {
8
27
  IssueCloseDocument,
9
28
  IssueCommentCreateDocument,
10
29
  IssueCreateDocument,
11
- IssueCreateRepositoryIdDocument,
12
30
  IssueDeleteDocument,
13
31
  IssueLabelsAddDocument,
14
32
  IssueLabelsLookupByNumberDocument,
33
+ IssueLabelsRemoveDocument,
15
34
  IssueLabelsUpdateDocument,
35
+ IssueLinkedPrsListDocument,
16
36
  IssueMilestoneLookupByNumberDocument,
17
37
  IssueMilestoneSetDocument,
18
38
  IssueNodeIdLookupDocument,
19
39
  IssueParentLookupDocument,
20
40
  IssueParentRemoveDocument,
21
41
  IssueParentSetDocument,
42
+ IssueRelationsGetDocument,
22
43
  IssueReopenDocument,
23
44
  IssueUpdateDocument
24
- } from "./chunk-Q7RCIK2C.js";
45
+ } from "./chunk-Q2NW7DJE.js";
46
+ import {
47
+ PrDiffListFilesDocument,
48
+ PrListDocument,
49
+ PrMergeStatusDocument,
50
+ PrReviewsListDocument,
51
+ PrViewDocument
52
+ } from "./chunk-QRHKAMRY.js";
25
53
  import {
54
+ PrAssigneesAddDocument,
55
+ PrAssigneesRemoveDocument,
56
+ PrBranchUpdateDocument,
26
57
  PrCommentReplyDocument,
27
58
  PrCommentResolveDocument,
28
59
  PrCommentUnresolveDocument,
60
+ PrCommentsListDocument,
61
+ PrCreateDocument,
62
+ PrMergeDocument,
29
63
  PrNodeIdDocument,
30
- PrReviewSubmitDocument
31
- } from "./chunk-TDABI6C7.js";
64
+ PrReviewSubmitDocument,
65
+ PrReviewsRequestDocument,
66
+ PrUpdateDocument,
67
+ UserNodeIdDocument
68
+ } from "./chunk-7HUKYNI2.js";
69
+ import {
70
+ IssueCreateRepositoryIdDocument
71
+ } from "./chunk-ZGBVX2VG.js";
72
+ import {
73
+ ReleaseListDocument,
74
+ ReleaseViewDocument
75
+ } from "./chunk-GQO6BHJV.js";
32
76
  import {
33
77
  createGraphqlClient,
34
78
  createTokenTransport
35
- } from "./chunk-HEHONZTO.js";
79
+ } from "./chunk-C2KRRSSX.js";
36
80
 
37
81
  // src/core/execution/cli/safe-runner.ts
38
82
  import { spawn } from "child_process";
@@ -188,9 +232,10 @@ var operationCardSchema = {
188
232
  },
189
233
  graphql: {
190
234
  type: "object",
191
- required: ["operationName", "documentPath"],
235
+ required: ["operationName", "operationType", "documentPath"],
192
236
  properties: {
193
237
  operationName: { type: "string", minLength: 1 },
238
+ operationType: { enum: ["query", "mutation"] },
194
239
  documentPath: { type: "string", minLength: 1 },
195
240
  variables: { type: "object" },
196
241
  limits: {
@@ -616,111 +661,6 @@ var errorCodes = {
616
661
  Unknown: "UNKNOWN"
617
662
  };
618
663
 
619
- // src/core/errors/map-error.ts
620
- function toMessage(error) {
621
- if (error instanceof Error) {
622
- return error.message;
623
- }
624
- return String(error);
625
- }
626
- function mapErrorToCode(error) {
627
- const message = toMessage(error).toLowerCase();
628
- if (message.includes("rate limit") || /\b429\b/.test(message) || message.includes("too many requests")) {
629
- return errorCodes.RateLimit;
630
- }
631
- if (/\b(500|502|503|504)\b/.test(message)) {
632
- return errorCodes.Server;
633
- }
634
- if (message.includes("timeout")) {
635
- return errorCodes.Network;
636
- }
637
- if (message.includes("econn") || message.includes("enotfound") || message.includes("eai_again") || message.includes("network") || message.includes("connection reset")) {
638
- return errorCodes.Network;
639
- }
640
- if (message.includes("not found") || /\b404\b/.test(message)) {
641
- return errorCodes.NotFound;
642
- }
643
- if (message.includes("operation not available")) {
644
- return errorCodes.AdapterUnsupported;
645
- }
646
- if (message.includes("auth") || message.includes("forbidden") || message.includes("unauthorized")) {
647
- return errorCodes.Auth;
648
- }
649
- if (message.includes("validation") || message.includes("invalid") || message.includes("required") || message.includes("positive integer")) {
650
- return errorCodes.Validation;
651
- }
652
- return errorCodes.Unknown;
653
- }
654
-
655
- // src/core/execution/normalizer.ts
656
- function buildMeta(route, options) {
657
- const meta = {
658
- capability_id: options.capabilityId,
659
- route_used: route
660
- };
661
- if (options.reason !== void 0) {
662
- meta.reason = options.reason;
663
- }
664
- if (options.pagination !== void 0) {
665
- meta.pagination = options.pagination;
666
- }
667
- return meta;
668
- }
669
- function normalizeResult(data, route, options) {
670
- return {
671
- ok: true,
672
- data,
673
- meta: buildMeta(route, options)
674
- };
675
- }
676
- function normalizeError(error, route, options) {
677
- return {
678
- ok: false,
679
- error,
680
- meta: buildMeta(route, options)
681
- };
682
- }
683
-
684
- // src/core/registry/schema-validator.ts
685
- var validatorCache = /* @__PURE__ */ new WeakMap();
686
- function mapAjvErrors(errors) {
687
- if (!errors) {
688
- return [];
689
- }
690
- return errors.map((error) => ({
691
- instancePath: error.instancePath,
692
- message: error.message ?? "schema validation failed",
693
- keyword: error.keyword,
694
- params: error.params
695
- }));
696
- }
697
- function getValidator(schema) {
698
- const cached = validatorCache.get(schema);
699
- if (cached) {
700
- return cached;
701
- }
702
- const validator = ajv.compile(schema);
703
- validatorCache.set(schema, validator);
704
- return validator;
705
- }
706
- function validate(schema, payload) {
707
- const validator = getValidator(schema);
708
- const ok = validator(payload);
709
- if (ok) {
710
- return { ok: true };
711
- }
712
- return {
713
- ok: false,
714
- errors: mapAjvErrors(validator.errors)
715
- };
716
- }
717
- function validateInput(inputSchema, params) {
718
- return validate(inputSchema, params);
719
- }
720
- function validateOutput(outputSchema, data) {
721
- return validate(outputSchema, data);
722
- }
723
-
724
664
  // src/core/telemetry/log.ts
725
665
  import * as fs from "fs";
726
666
  import * as os from "os";
@@ -805,7 +745,7 @@ function createLogger(config) {
805
745
  }
806
746
  function write(level, msg, ctx) {
807
747
  if (levelIndex(level) < minIndex) return;
808
- const version = true ? "0.2.0" : "unknown";
748
+ const version = true ? "0.2.2" : "unknown";
809
749
  const entry = {
810
750
  ts: (/* @__PURE__ */ new Date()).toISOString(),
811
751
  pid: config.pid,
@@ -831,68 +771,291 @@ function createLogger(config) {
831
771
  }
832
772
  var logger = createLogger(createLoggerConfig());
833
773
 
834
- // src/core/execute/execute.ts
835
- function parsePredicateValue(raw) {
836
- const value = raw.trim();
837
- if (value === "true") {
838
- return true;
774
+ // src/core/errors/map-error.ts
775
+ function toMessage(error) {
776
+ if (error instanceof Error) {
777
+ return error.message;
839
778
  }
840
- if (value === "false") {
841
- return false;
779
+ return String(error);
780
+ }
781
+ function mapErrorToCode(error) {
782
+ const message = toMessage(error).toLowerCase();
783
+ if (message.includes("rate limit") || /\b429\b/.test(message) || message.includes("too many requests")) {
784
+ return errorCodes.RateLimit;
842
785
  }
843
- if (value === "null") {
844
- return null;
786
+ if (/\b(500|502|503|504)\b/.test(message)) {
787
+ return errorCodes.Server;
845
788
  }
846
- const numeric = Number(value);
847
- if (!Number.isNaN(numeric) && value.length > 0) {
848
- return numeric;
789
+ if (message.includes("timeout")) {
790
+ return errorCodes.Network;
849
791
  }
850
- return value.replace(/^['"]|['"]$/g, "");
851
- }
852
- function resolvePathValue(source, path2) {
853
- const segments = path2.split(".").filter((segment) => segment.length > 0);
854
- let current = source;
855
- for (const segment of segments) {
856
- if (typeof current !== "object" || current === null || Array.isArray(current)) {
857
- return void 0;
858
- }
859
- current = current[segment];
792
+ if (message.includes("econn") || message.includes("enotfound") || message.includes("eai_again") || message.includes("network") || message.includes("connection reset")) {
793
+ return errorCodes.Network;
860
794
  }
861
- return current;
795
+ if (message.includes("not found") || /\b404\b/.test(message)) {
796
+ return errorCodes.NotFound;
797
+ }
798
+ if (message.includes("operation not available")) {
799
+ return errorCodes.AdapterUnsupported;
800
+ }
801
+ if (message.includes("auth") || message.includes("forbidden") || message.includes("unauthorized")) {
802
+ return errorCodes.Auth;
803
+ }
804
+ if (message.includes("validation") || message.includes("invalid") || message.includes("required") || message.includes("positive integer")) {
805
+ return errorCodes.Validation;
806
+ }
807
+ return errorCodes.Unknown;
862
808
  }
863
- function evaluateSuitabilityPreferred(card, params, routingContext) {
864
- const rules = card.routing.suitability ?? [];
865
- for (const rule of rules) {
866
- const alwaysMatch = /^(cli|graphql|rest)$/i.exec(rule.predicate.trim());
867
- const alwaysRoute = alwaysMatch?.[1];
868
- if (rule.when === "always" && alwaysRoute) {
869
- return alwaysRoute.toLowerCase();
809
+
810
+ // src/core/routing/engine/assemble.ts
811
+ function isRetryableCode(code) {
812
+ return code === errorCodes.RateLimit || code === errorCodes.Network || code === errorCodes.Server;
813
+ }
814
+ function assembleChainResult(input) {
815
+ const {
816
+ steps,
817
+ requests,
818
+ mutationRawResult,
819
+ queryRawResult,
820
+ stepErrors,
821
+ cliResults,
822
+ cliStepCount,
823
+ batchStartMs
824
+ } = input;
825
+ const mutationStepIndices = new Set(
826
+ steps.filter((s) => s.route === "gql-mutation").map((s) => s.index)
827
+ );
828
+ const results = requests.map((req, stepIndex) => {
829
+ if (req === void 0) {
830
+ throw new Error(`invariant violated: request at index ${stepIndex} is undefined`);
870
831
  }
871
- const conditionalMatch = /^(cli|graphql|rest)\s+if\s+([a-zA-Z0-9_.]+)\s*(==|!=)\s*(.+)$/i.exec(
872
- rule.predicate.trim()
873
- );
874
- if (!conditionalMatch) {
875
- continue;
832
+ const cliResult = cliResults.get(stepIndex);
833
+ if (cliResult !== void 0) {
834
+ return cliResult.ok ? { task: req.task, ok: true, data: cliResult.data } : {
835
+ task: req.task,
836
+ ok: false,
837
+ error: cliResult.error ?? {
838
+ code: errorCodes.Unknown,
839
+ message: "CLI step failed",
840
+ retryable: false
841
+ }
842
+ };
876
843
  }
877
- const [, targetRouteRaw = "", rawPath = "", operator = "==", rawExpected = ""] = conditionalMatch;
878
- const targetRoute = targetRouteRaw.toLowerCase();
879
- const source = rule.when === "env" ? routingContext : params;
880
- const path2 = rawPath.startsWith("params.") || rawPath.startsWith("env.") ? rawPath.split(".").slice(1).join(".") : rawPath;
881
- const actual = resolvePathValue(source, path2);
882
- const expected = parsePredicateValue(rawExpected);
883
- const matches = operator === "==" ? actual === expected : actual !== expected;
884
- if (matches) {
885
- return targetRoute;
844
+ const alias = `step${stepIndex}`;
845
+ const stepError = stepErrors.get(alias);
846
+ if (stepError !== void 0) {
847
+ const code = mapErrorToCode(stepError);
848
+ return {
849
+ task: req.task,
850
+ ok: false,
851
+ error: {
852
+ code,
853
+ message: stepError,
854
+ retryable: isRetryableCode(code)
855
+ }
856
+ };
886
857
  }
887
- }
888
- return card.routing.preferred;
858
+ if (alias in mutationRawResult) {
859
+ return { task: req.task, ok: true };
860
+ }
861
+ if (alias in queryRawResult) {
862
+ return { task: req.task, ok: true, data: queryRawResult[alias] };
863
+ }
864
+ const missingMsg = mutationStepIndices.has(stepIndex) ? `missing mutation result for alias ${alias}` : `missing result for alias ${alias}`;
865
+ return {
866
+ task: req.task,
867
+ ok: false,
868
+ error: {
869
+ code: errorCodes.Unknown,
870
+ message: missingMsg,
871
+ retryable: false
872
+ }
873
+ };
874
+ });
875
+ const succeeded = results.filter((r) => r.ok).length;
876
+ const status = succeeded === results.length ? "success" : succeeded === 0 ? "failed" : "partial";
877
+ logger.info("execute_batch.complete", {
878
+ ok: status !== "failed",
879
+ status,
880
+ total: results.length,
881
+ succeeded,
882
+ failed: results.length - succeeded,
883
+ duration_ms: Date.now() - batchStartMs
884
+ });
885
+ const routeUsed = cliStepCount === requests.length ? "cli" : "graphql";
886
+ return {
887
+ status,
888
+ results,
889
+ meta: {
890
+ route_used: routeUsed,
891
+ total: results.length,
892
+ succeeded,
893
+ failed: results.length - succeeded
894
+ }
895
+ };
889
896
  }
890
- function routePlan(card, params, routingContext) {
891
- const preferred = evaluateSuitabilityPreferred(card, params, routingContext);
892
- const planned = /* @__PURE__ */ new Set([preferred, ...card.routing.fallbacks]);
893
- return [...planned];
897
+ function assembleResolutionFailure(requests, steps, phase1Error, cliResults) {
898
+ const cliStepCount = steps.filter((s) => s.route === "cli").length;
899
+ const results = requests.map((req, i) => {
900
+ if (req === void 0) {
901
+ throw new Error(`invariant violated: request at index ${i} is undefined`);
902
+ }
903
+ const cliResult = cliResults.get(i);
904
+ if (cliResult !== void 0) {
905
+ return cliResult.ok ? { task: req.task, ok: true, data: cliResult.data } : {
906
+ task: req.task,
907
+ ok: false,
908
+ error: cliResult.error ?? {
909
+ code: errorCodes.Unknown,
910
+ message: "CLI step failed",
911
+ retryable: false
912
+ }
913
+ };
914
+ }
915
+ return { task: req.task, ok: false, error: phase1Error };
916
+ });
917
+ const succeeded = results.filter((r) => r.ok).length;
918
+ const total = results.length;
919
+ const status = succeeded === total ? "success" : succeeded === 0 ? "failed" : "partial";
920
+ const routeUsed = cliStepCount === requests.length ? "cli" : "graphql";
921
+ return {
922
+ status,
923
+ results,
924
+ meta: { route_used: routeUsed, total, succeeded, failed: total - succeeded }
925
+ };
894
926
  }
895
- async function execute(options) {
927
+
928
+ // src/core/execution/normalizer.ts
929
+ function buildMeta(route, options) {
930
+ const meta = {
931
+ capability_id: options.capabilityId,
932
+ route_used: route
933
+ };
934
+ if (options.reason !== void 0) {
935
+ meta.reason = options.reason;
936
+ }
937
+ if (options.pagination !== void 0) {
938
+ meta.pagination = options.pagination;
939
+ }
940
+ return meta;
941
+ }
942
+ function normalizeResult(data, route, options) {
943
+ return {
944
+ ok: true,
945
+ data,
946
+ meta: buildMeta(route, options)
947
+ };
948
+ }
949
+ function normalizeError(error, route, options) {
950
+ return {
951
+ ok: false,
952
+ error,
953
+ meta: buildMeta(route, options)
954
+ };
955
+ }
956
+
957
+ // src/core/registry/schema-validator.ts
958
+ var validatorCache = /* @__PURE__ */ new WeakMap();
959
+ function mapAjvErrors(errors) {
960
+ if (!errors) {
961
+ return [];
962
+ }
963
+ return errors.map((error) => ({
964
+ instancePath: error.instancePath,
965
+ message: error.message ?? "schema validation failed",
966
+ keyword: error.keyword,
967
+ params: error.params
968
+ }));
969
+ }
970
+ function getValidator(schema) {
971
+ const cached = validatorCache.get(schema);
972
+ if (cached) {
973
+ return cached;
974
+ }
975
+ const validator = ajv.compile(schema);
976
+ validatorCache.set(schema, validator);
977
+ return validator;
978
+ }
979
+ function validate(schema, payload) {
980
+ const validator = getValidator(schema);
981
+ const ok = validator(payload);
982
+ if (ok) {
983
+ return { ok: true };
984
+ }
985
+ return {
986
+ ok: false,
987
+ errors: mapAjvErrors(validator.errors)
988
+ };
989
+ }
990
+ function validateInput(inputSchema, params) {
991
+ return validate(inputSchema, params);
992
+ }
993
+ function validateOutput(outputSchema, data) {
994
+ return validate(outputSchema, data);
995
+ }
996
+
997
+ // src/core/execute/execute.ts
998
+ function parsePredicateValue(raw) {
999
+ const value = raw.trim();
1000
+ if (value === "true") {
1001
+ return true;
1002
+ }
1003
+ if (value === "false") {
1004
+ return false;
1005
+ }
1006
+ if (value === "null") {
1007
+ return null;
1008
+ }
1009
+ const numeric = Number(value);
1010
+ if (!Number.isNaN(numeric) && value.length > 0) {
1011
+ return numeric;
1012
+ }
1013
+ return value.replace(/^['"]|['"]$/g, "");
1014
+ }
1015
+ function resolvePathValue(source, path2) {
1016
+ const segments = path2.split(".").filter((segment) => segment.length > 0);
1017
+ let current = source;
1018
+ for (const segment of segments) {
1019
+ if (typeof current !== "object" || current === null || Array.isArray(current)) {
1020
+ return void 0;
1021
+ }
1022
+ current = current[segment];
1023
+ }
1024
+ return current;
1025
+ }
1026
+ function evaluateSuitabilityPreferred(card, params, routingContext) {
1027
+ const rules = card.routing.suitability ?? [];
1028
+ for (const rule of rules) {
1029
+ const alwaysMatch = /^(cli|graphql|rest)$/i.exec(rule.predicate.trim());
1030
+ const alwaysRoute = alwaysMatch?.[1];
1031
+ if (rule.when === "always" && alwaysRoute) {
1032
+ return alwaysRoute.toLowerCase();
1033
+ }
1034
+ const conditionalMatch = /^(cli|graphql|rest)\s+if\s+([a-zA-Z0-9_.]+)\s*(==|!=)\s*(.+)$/i.exec(
1035
+ rule.predicate.trim()
1036
+ );
1037
+ if (!conditionalMatch) {
1038
+ continue;
1039
+ }
1040
+ const [, targetRouteRaw = "", rawPath = "", operator = "==", rawExpected = ""] = conditionalMatch;
1041
+ const targetRoute = targetRouteRaw.toLowerCase();
1042
+ const source = rule.when === "env" ? routingContext : params;
1043
+ const path2 = rawPath.startsWith("params.") || rawPath.startsWith("env.") ? rawPath.split(".").slice(1).join(".") : rawPath;
1044
+ const actual = resolvePathValue(source, path2);
1045
+ const expected = parsePredicateValue(rawExpected);
1046
+ const matches = operator === "==" ? actual === expected : actual !== expected;
1047
+ if (matches) {
1048
+ return targetRoute;
1049
+ }
1050
+ }
1051
+ return card.routing.preferred;
1052
+ }
1053
+ function routePlan(card, params, routingContext) {
1054
+ const preferred = evaluateSuitabilityPreferred(card, params, routingContext);
1055
+ const planned = /* @__PURE__ */ new Set([preferred, ...card.routing.fallbacks]);
1056
+ return [...planned];
1057
+ }
1058
+ async function execute(options) {
896
1059
  const inputValidation = validateInput(options.card.input_schema, options.params);
897
1060
  if (!inputValidation.ok) {
898
1061
  return normalizeError(
@@ -2135,6 +2298,7 @@ var handlePrMerge = async (runner, params, card) => {
2135
2298
  {
2136
2299
  prNumber: Number(params.prNumber),
2137
2300
  method: method === "squash" || method === "rebase" ? method : "merge",
2301
+ isMethodAssumed: params.method === void 0,
2138
2302
  queued: true,
2139
2303
  deleteBranch: params.deleteBranch === true
2140
2304
  },
@@ -2835,7 +2999,7 @@ var handleProjectV2ItemAddIssue = async (runner, params, _card) => {
2835
2999
  }
2836
3000
  const data = parseCliData(result.stdout);
2837
3001
  const root = typeof data === "object" && data !== null && !Array.isArray(data) ? data : {};
2838
- const normalized = { itemId: typeof root.id === "string" ? root.id : null, added: true };
3002
+ const normalized = { itemId: typeof root.id === "string" ? root.id : null, itemType: null };
2839
3003
  return normalizeResult(normalized, "cli", {
2840
3004
  capabilityId: "project_v2.items.issue.add",
2841
3005
  reason: "CARD_FALLBACK"
@@ -2925,7 +3089,7 @@ var handleProjectV2ItemFieldUpdate = async (runner, params, _card) => {
2925
3089
  { capabilityId: "project_v2.items.field.update", reason: "CARD_FALLBACK" }
2926
3090
  );
2927
3091
  }
2928
- const normalized = { itemId, updated: true };
3092
+ const normalized = { itemId };
2929
3093
  return normalizeResult(normalized, "cli", {
2930
3094
  capabilityId: "project_v2.items.field.update",
2931
3095
  reason: "CARD_FALLBACK"
@@ -2968,7 +3132,7 @@ var handleProjectV2ItemsIssueRemove = async (runner, params, _card) => {
2968
3132
  { capabilityId: "project_v2.items.issue.remove", reason: "CARD_FALLBACK" }
2969
3133
  );
2970
3134
  }
2971
- const normalized = { itemId, removed: true };
3135
+ const normalized = { deletedItemId: itemId };
2972
3136
  return normalizeResult(normalized, "cli", {
2973
3137
  capabilityId: "project_v2.items.issue.remove",
2974
3138
  reason: "CARD_FALLBACK"
@@ -4572,6 +4736,15 @@ var handlers7 = /* @__PURE__ */ new Map([
4572
4736
  return c.updateIssueLabels(p);
4573
4737
  }
4574
4738
  ],
4739
+ [
4740
+ "issue.labels.remove",
4741
+ (c, p) => {
4742
+ if (!c.removeIssueLabels) {
4743
+ throw new Error("removeIssueLabels operation not available");
4744
+ }
4745
+ return c.removeIssueLabels(p);
4746
+ }
4747
+ ],
4575
4748
  [
4576
4749
  "issue.assignees.set",
4577
4750
  (c, p) => {
@@ -4608,6 +4781,15 @@ var handlers7 = /* @__PURE__ */ new Map([
4608
4781
  return c.setIssueMilestone(p);
4609
4782
  }
4610
4783
  ],
4784
+ [
4785
+ "issue.milestone.clear",
4786
+ (c, p) => {
4787
+ if (!c.clearIssueMilestone) {
4788
+ throw new Error("clearIssueMilestone operation not available");
4789
+ }
4790
+ return c.clearIssueMilestone(p);
4791
+ }
4792
+ ],
4611
4793
  [
4612
4794
  "issue.comments.create",
4613
4795
  (c, p) => {
@@ -4709,6 +4891,80 @@ var handlers7 = /* @__PURE__ */ new Map([
4709
4891
  }
4710
4892
  return c.submitPrReview(p);
4711
4893
  }
4894
+ ],
4895
+ ["repo.labels.list", (c, p) => c.fetchRepoLabelsList(withDefaultFirst(p))],
4896
+ [
4897
+ "repo.issue_types.list",
4898
+ (c, p) => c.fetchRepoIssueTypesList(withDefaultFirst(p))
4899
+ ],
4900
+ // Release
4901
+ ["release.view", (c, p) => c.fetchReleaseView(p)],
4902
+ ["release.list", (c, p) => c.fetchReleaseList(withDefaultFirst(p))],
4903
+ // Project V2
4904
+ ["project_v2.org.view", (c, p) => c.fetchProjectV2OrgView(p)],
4905
+ ["project_v2.user.view", (c, p) => c.fetchProjectV2UserView(p)],
4906
+ [
4907
+ "project_v2.fields.list",
4908
+ (c, p) => c.fetchProjectV2FieldsList(withDefaultFirst(p))
4909
+ ],
4910
+ [
4911
+ "project_v2.items.list",
4912
+ (c, p) => c.fetchProjectV2ItemsList(withDefaultFirst(p))
4913
+ ],
4914
+ // PR mutations (Phase 2)
4915
+ [
4916
+ "pr.create",
4917
+ (c, p) => {
4918
+ const raw = p;
4919
+ return c.createPr({
4920
+ owner: raw.owner,
4921
+ name: raw.name,
4922
+ title: raw.title,
4923
+ headRefName: raw.head,
4924
+ baseRefName: raw.base,
4925
+ ...raw.body !== void 0 ? { body: raw.body } : {},
4926
+ ...raw.draft !== void 0 ? { draft: raw.draft } : {}
4927
+ });
4928
+ }
4929
+ ],
4930
+ ["pr.update", (c, p) => c.updatePr(p)],
4931
+ [
4932
+ "pr.merge",
4933
+ (c, p) => {
4934
+ const raw = p;
4935
+ const methodMap = {
4936
+ merge: "MERGE",
4937
+ squash: "SQUASH",
4938
+ rebase: "REBASE"
4939
+ };
4940
+ if (raw.method !== void 0 && typeof raw.method !== "string") {
4941
+ throw new Error(`method must be a string for pr.merge, got ${typeof raw.method}`);
4942
+ }
4943
+ const mergeMethod = raw.method !== void 0 ? methodMap[raw.method.toLowerCase()] : void 0;
4944
+ if (raw.method !== void 0 && !mergeMethod) {
4945
+ throw new Error(
4946
+ `Unsupported merge method "${raw.method}" for pr.merge. Expected one of: merge, squash, rebase.`
4947
+ );
4948
+ }
4949
+ return c.mergePr({
4950
+ owner: raw.owner,
4951
+ name: raw.name,
4952
+ prNumber: raw.prNumber,
4953
+ ...mergeMethod !== void 0 ? { mergeMethod } : {},
4954
+ ...raw.deleteBranch !== void 0 ? { deleteBranch: raw.deleteBranch } : {}
4955
+ });
4956
+ }
4957
+ ],
4958
+ ["pr.branch.update", (c, p) => c.updatePrBranch(p)],
4959
+ ["pr.assignees.add", (c, p) => c.addPrAssignees(p)],
4960
+ ["pr.assignees.remove", (c, p) => c.removePrAssignees(p)],
4961
+ ["pr.reviews.request", (c, p) => c.requestPrReviews(p)],
4962
+ // Project V2 mutations (Phase 2)
4963
+ ["project_v2.items.issue.add", (c, p) => c.addProjectV2Item(p)],
4964
+ ["project_v2.items.issue.remove", (c, p) => c.removeProjectV2Item(p)],
4965
+ [
4966
+ "project_v2.items.field.update",
4967
+ (c, p) => c.updateProjectV2ItemField(p)
4712
4968
  ]
4713
4969
  ]);
4714
4970
  function getGraphqlHandler(capabilityId) {
@@ -4797,81 +5053,263 @@ function preflightCheck(input) {
4797
5053
  // src/core/routing/policy.ts
4798
5054
  var routePreferenceOrder = ["cli", "graphql"];
4799
5055
 
4800
- // src/gql/batch.ts
4801
- function extractRootFieldName(query) {
4802
- const headerEnd = query.indexOf("{");
4803
- if (headerEnd === -1) return null;
4804
- const body = query.slice(headerEnd + 1);
4805
- const match = body.match(/^\s*(\w+)/);
4806
- return match?.[1] ?? null;
4807
- }
4808
- function buildBatchMutation(operations) {
4809
- if (operations.length === 0) {
4810
- throw new Error("buildBatchMutation requires at least one operation");
4811
- }
4812
- const allVarDeclarations = [];
4813
- const allSelections = [];
4814
- const mergedVariables = {};
4815
- const allFragments = /* @__PURE__ */ new Map();
4816
- for (const op of operations) {
4817
- const parsed = parseOperation(op.mutation);
4818
- for (const [name, text] of parsed.fragments) {
4819
- if (!allFragments.has(name)) {
4820
- allFragments.set(name, text);
4821
- }
4822
- }
4823
- for (const varDecl of parsed.variableDeclarations) {
4824
- allVarDeclarations.push(`$${op.alias}_${varDecl.name}: ${varDecl.type}`);
4825
- }
4826
- let body = parsed.body;
4827
- const sortedDeclarations = [...parsed.variableDeclarations].sort(
4828
- (a, b) => b.name.length - a.name.length
4829
- );
4830
- for (const varDecl of sortedDeclarations) {
4831
- body = body.replaceAll(
4832
- new RegExp(`\\$${escapeRegex(varDecl.name)}\\b`, "g"),
4833
- `$${op.alias}_${varDecl.name}`
4834
- );
4835
- }
4836
- const aliasedBody = body.replace(/^\s*(\w+)/, `${op.alias}: $1`);
4837
- allSelections.push(aliasedBody);
4838
- for (const [key, value] of Object.entries(op.variables)) {
4839
- mergedVariables[`${op.alias}_${key}`] = value;
4840
- }
5056
+ // src/core/routing/engine/cli-detect.ts
5057
+ var CLI_ENV_CACHE_TTL_MS = 3e4;
5058
+ var cliEnvironmentCache = /* @__PURE__ */ new WeakMap();
5059
+ var cliEnvironmentInFlight = /* @__PURE__ */ new WeakMap();
5060
+ var defaultCliRunner = createSafeCliCommandRunner();
5061
+ async function detectCliEnvironment(runner) {
5062
+ const version = await runner.run("gh", ["--version"], 1500).catch(() => null);
5063
+ if (!version || version.exitCode !== 0) {
5064
+ return { ghCliAvailable: false, ghAuthenticated: false };
4841
5065
  }
4842
- const fragmentBlock = allFragments.size > 0 ? "\n" + [...allFragments.values()].join("\n") : "";
4843
- const document = `mutation BatchComposite(${allVarDeclarations.join(", ")}) {
4844
- ${allSelections.join("\n")}
4845
- }${fragmentBlock}`;
4846
- return { document, variables: mergedVariables };
4847
- }
4848
- function escapeRegex(value) {
4849
- return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
5066
+ const auth = await runner.run("gh", ["auth", "status"], 2500).catch(() => null);
5067
+ return { ghCliAvailable: true, ghAuthenticated: auth?.exitCode === 0 };
4850
5068
  }
4851
- function parseOperation(document) {
4852
- const headerMatch = document.match(/(query|mutation)\s+\w+\s*\(([^)]*)\)/);
4853
- const variableDeclarations = [];
4854
- if (headerMatch && headerMatch[2]) {
4855
- const varString = headerMatch[2];
4856
- const varMatches = varString.matchAll(/\$(\w+)\s*:\s*([^,)]+)/g);
4857
- for (const match of varMatches) {
4858
- const name = match[1];
4859
- const type = match[2];
4860
- if (name && type) {
4861
- variableDeclarations.push({
4862
- name,
4863
- type: type.trim()
4864
- });
4865
- }
4866
- }
5069
+ async function detectCliEnvironmentCached(runner) {
5070
+ const now = Date.now();
5071
+ const cached = cliEnvironmentCache.get(runner);
5072
+ if (cached && cached.expiresAt > now) {
5073
+ return cached.value;
4867
5074
  }
4868
- const headerEnd = document.indexOf("{");
4869
- if (headerEnd === -1) {
4870
- throw new Error("Invalid mutation: no opening brace found");
5075
+ const inFlight = cliEnvironmentInFlight.get(runner);
5076
+ if (inFlight) {
5077
+ return inFlight;
4871
5078
  }
4872
- let depth = 0;
4873
- let bodyStart = -1;
4874
- let bodyEnd = -1;
5079
+ const probePromise = detectCliEnvironment(runner).then((value) => {
5080
+ cliEnvironmentCache.set(runner, {
5081
+ value,
5082
+ expiresAt: Date.now() + CLI_ENV_CACHE_TTL_MS
5083
+ });
5084
+ cliEnvironmentInFlight.delete(runner);
5085
+ return value;
5086
+ }).catch((error) => {
5087
+ cliEnvironmentInFlight.delete(runner);
5088
+ throw error;
5089
+ });
5090
+ cliEnvironmentInFlight.set(runner, probePromise);
5091
+ return probePromise;
5092
+ }
5093
+
5094
+ // src/core/routing/engine/single.ts
5095
+ var DEFAULT_REASON = "DEFAULT_POLICY";
5096
+ async function runSingleTask(task, input, deps) {
5097
+ const reason = deps.reason ?? DEFAULT_REASON;
5098
+ const card = getOperationCard(task);
5099
+ if (!card) {
5100
+ logger.error("execute.unsupported_task", { task });
5101
+ return normalizeError(
5102
+ {
5103
+ code: errorCodes.Validation,
5104
+ message: `Unsupported task: ${task}`,
5105
+ retryable: false
5106
+ },
5107
+ routePreferenceOrder[0],
5108
+ { capabilityId: task, reason }
5109
+ );
5110
+ }
5111
+ logger.debug("execute.start", { capability_id: task });
5112
+ const startMs = Date.now();
5113
+ const cliRunner = deps.cliRunner ?? defaultCliRunner;
5114
+ const result = await execute({
5115
+ card,
5116
+ params: input,
5117
+ routingContext: {
5118
+ ghCliAvailable: deps.ghCliAvailable,
5119
+ ghAuthenticated: deps.ghAuthenticated,
5120
+ githubTokenPresent: Boolean(deps.githubToken)
5121
+ },
5122
+ retry: {
5123
+ maxAttemptsPerRoute: 2
5124
+ },
5125
+ preflight: async (route) => {
5126
+ const preflightInput = { route };
5127
+ if (deps.githubToken !== void 0) {
5128
+ preflightInput.githubToken = deps.githubToken;
5129
+ }
5130
+ if (route === "cli") {
5131
+ if (deps.ghCliAvailable !== void 0) {
5132
+ preflightInput.ghCliAvailable = deps.ghCliAvailable;
5133
+ }
5134
+ if (deps.ghAuthenticated !== void 0) {
5135
+ preflightInput.ghAuthenticated = deps.ghAuthenticated;
5136
+ }
5137
+ if (preflightInput.ghCliAvailable === void 0 || preflightInput.ghAuthenticated === void 0) {
5138
+ if (deps.skipGhPreflight === true) {
5139
+ if (preflightInput.ghCliAvailable === void 0) {
5140
+ preflightInput.ghCliAvailable = true;
5141
+ }
5142
+ if (preflightInput.ghAuthenticated === void 0) {
5143
+ preflightInput.ghAuthenticated = true;
5144
+ }
5145
+ } else {
5146
+ const detected = await detectCliEnvironmentCached(cliRunner);
5147
+ if (preflightInput.ghCliAvailable === void 0) {
5148
+ preflightInput.ghCliAvailable = detected.ghCliAvailable;
5149
+ }
5150
+ if (preflightInput.ghAuthenticated === void 0) {
5151
+ preflightInput.ghAuthenticated = detected.ghAuthenticated;
5152
+ }
5153
+ }
5154
+ }
5155
+ }
5156
+ return preflightCheck(preflightInput);
5157
+ },
5158
+ routes: {
5159
+ graphql: async () => {
5160
+ return runGraphqlCapability(deps.githubClient, task, input);
5161
+ },
5162
+ cli: async () => {
5163
+ return runCliCapability(cliRunner, task, input, card);
5164
+ },
5165
+ rest: async () => normalizeError(
5166
+ {
5167
+ code: errorCodes.AdapterUnsupported,
5168
+ message: `Route 'rest' is not implemented for task '${task}'`,
5169
+ retryable: false,
5170
+ details: { route: "rest", task }
5171
+ },
5172
+ "rest",
5173
+ { capabilityId: task, reason }
5174
+ )
5175
+ }
5176
+ });
5177
+ logger.info("execute.complete", {
5178
+ capability_id: task,
5179
+ ok: result.ok,
5180
+ route_used: result.meta?.route_used ?? null,
5181
+ duration_ms: Date.now() - startMs,
5182
+ error_code: result.error?.code ?? null
5183
+ });
5184
+ return result;
5185
+ }
5186
+
5187
+ // src/core/routing/engine/cli-dispatch.ts
5188
+ function startCliSteps(steps, requests, deps) {
5189
+ return steps.filter((s) => s.route === "cli").map((step) => {
5190
+ const req = requests[step.index];
5191
+ if (req === void 0) {
5192
+ return Promise.resolve([
5193
+ step.index,
5194
+ {
5195
+ ok: false,
5196
+ error: { code: errorCodes.Unknown, message: "missing request", retryable: false },
5197
+ meta: { capability_id: step.card.capability_id, route_used: "cli" }
5198
+ }
5199
+ ]);
5200
+ }
5201
+ return runSingleTask(req.task, req.input, deps).then((result) => [step.index, result]).catch((err) => [
5202
+ step.index,
5203
+ {
5204
+ ok: false,
5205
+ error: {
5206
+ code: errorCodes.Unknown,
5207
+ message: err instanceof Error ? err.message : String(err),
5208
+ retryable: false
5209
+ },
5210
+ meta: { capability_id: req.task, route_used: "cli" }
5211
+ }
5212
+ ]);
5213
+ });
5214
+ }
5215
+ async function collectCliResults(cliPromises, cliSteps, requests) {
5216
+ const cliResults = /* @__PURE__ */ new Map();
5217
+ const outcomes = await Promise.allSettled(cliPromises);
5218
+ for (let j = 0; j < cliSteps.length; j += 1) {
5219
+ const step = cliSteps[j];
5220
+ const outcome = outcomes[j];
5221
+ if (step === void 0 || outcome === void 0) continue;
5222
+ if (outcome.status === "fulfilled") {
5223
+ const [resolvedIndex, result] = outcome.value;
5224
+ cliResults.set(resolvedIndex, result);
5225
+ } else {
5226
+ const msg = outcome.reason instanceof Error ? outcome.reason.message : String(outcome.reason);
5227
+ const req = requests[step.index];
5228
+ cliResults.set(step.index, {
5229
+ ok: false,
5230
+ error: { code: errorCodes.Unknown, message: msg, retryable: false },
5231
+ meta: { capability_id: req?.task ?? "unknown", route_used: "cli" }
5232
+ });
5233
+ }
5234
+ }
5235
+ return cliResults;
5236
+ }
5237
+
5238
+ // src/gql/batch.ts
5239
+ function extractRootFieldName(query) {
5240
+ const headerEnd = query.indexOf("{");
5241
+ if (headerEnd === -1) return null;
5242
+ const body = query.slice(headerEnd + 1);
5243
+ const match = body.match(/^\s*(\w+)/);
5244
+ return match?.[1] ?? null;
5245
+ }
5246
+ function buildBatchMutation(operations) {
5247
+ if (operations.length === 0) {
5248
+ throw new Error("buildBatchMutation requires at least one operation");
5249
+ }
5250
+ const allVarDeclarations = [];
5251
+ const allSelections = [];
5252
+ const mergedVariables = {};
5253
+ const allFragments = /* @__PURE__ */ new Map();
5254
+ for (const op of operations) {
5255
+ const parsed = parseOperation(op.mutation);
5256
+ for (const [name, text] of parsed.fragments) {
5257
+ if (!allFragments.has(name)) {
5258
+ allFragments.set(name, text);
5259
+ }
5260
+ }
5261
+ for (const varDecl of parsed.variableDeclarations) {
5262
+ allVarDeclarations.push(`$${op.alias}_${varDecl.name}: ${varDecl.type}`);
5263
+ }
5264
+ let body = parsed.body;
5265
+ const sortedDeclarations = [...parsed.variableDeclarations].sort(
5266
+ (a, b) => b.name.length - a.name.length
5267
+ );
5268
+ for (const varDecl of sortedDeclarations) {
5269
+ body = body.replaceAll(
5270
+ new RegExp(`\\$${escapeRegex(varDecl.name)}\\b`, "g"),
5271
+ `$${op.alias}_${varDecl.name}`
5272
+ );
5273
+ }
5274
+ const aliasedBody = body.replace(/^\s*(\w+)/, `${op.alias}: $1`);
5275
+ allSelections.push(aliasedBody);
5276
+ for (const [key, value] of Object.entries(op.variables)) {
5277
+ mergedVariables[`${op.alias}_${key}`] = value;
5278
+ }
5279
+ }
5280
+ const fragmentBlock = allFragments.size > 0 ? "\n" + [...allFragments.values()].join("\n") : "";
5281
+ const document = `mutation BatchComposite(${allVarDeclarations.join(", ")}) {
5282
+ ${allSelections.join("\n")}
5283
+ }${fragmentBlock}`;
5284
+ return { document, variables: mergedVariables };
5285
+ }
5286
+ function escapeRegex(value) {
5287
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
5288
+ }
5289
+ function parseOperation(document) {
5290
+ const headerMatch = document.match(/(query|mutation)\s+\w+\s*\(([^)]*)\)/);
5291
+ const variableDeclarations = [];
5292
+ if (headerMatch && headerMatch[2]) {
5293
+ const varString = headerMatch[2];
5294
+ const varMatches = varString.matchAll(/\$(\w+)\s*:\s*([^,)]+)/g);
5295
+ for (const match of varMatches) {
5296
+ const name = match[1];
5297
+ const type = match[2];
5298
+ if (name && type) {
5299
+ variableDeclarations.push({
5300
+ name,
5301
+ type: type.trim()
5302
+ });
5303
+ }
5304
+ }
5305
+ }
5306
+ const headerEnd = document.indexOf("{");
5307
+ if (headerEnd === -1) {
5308
+ throw new Error("Invalid mutation: no opening brace found");
5309
+ }
5310
+ let depth = 0;
5311
+ let bodyStart = -1;
5312
+ let bodyEnd = -1;
4875
5313
  for (let i = headerEnd; i < document.length; i++) {
4876
5314
  if (document[i] === "{") {
4877
5315
  if (depth === 0) bodyStart = i + 1;
@@ -4921,8 +5359,12 @@ function buildBatchQuery(operations) {
4921
5359
  const allVarDeclarations = [];
4922
5360
  const allSelections = [];
4923
5361
  const mergedVariables = {};
5362
+ const allFragments = /* @__PURE__ */ new Map();
4924
5363
  for (const op of operations) {
4925
5364
  const parsed = parseOperation(op.query);
5365
+ for (const [name, text] of parsed.fragments) {
5366
+ if (!allFragments.has(name)) allFragments.set(name, text);
5367
+ }
4926
5368
  for (const varDecl of parsed.variableDeclarations) {
4927
5369
  allVarDeclarations.push(`$${op.alias}_${varDecl.name}: ${varDecl.type}`);
4928
5370
  }
@@ -4943,9 +5385,10 @@ function buildBatchQuery(operations) {
4943
5385
  }
4944
5386
  }
4945
5387
  const varList = allVarDeclarations.length > 0 ? `(${allVarDeclarations.join(", ")})` : "";
5388
+ const fragmentBlock = allFragments.size > 0 ? "\n" + [...allFragments.values()].join("\n") : "";
4946
5389
  const document = `query BatchChain${varList} {
4947
5390
  ${allSelections.join("\n")}
4948
- }`;
5391
+ }${fragmentBlock}`;
4949
5392
  return { document, variables: mergedVariables };
4950
5393
  }
4951
5394
 
@@ -4993,26 +5436,6 @@ var IssueLabelsLookupDocument = `
4993
5436
  }
4994
5437
  `;
4995
5438
 
4996
- // src/gql/operations/issue-labels-remove.generated.ts
4997
- var IssueLabelsRemoveDocument = `
4998
- mutation IssueLabelsRemove($labelableId: ID!, $labelIds: [ID!]!) {
4999
- removeLabelsFromLabelable(
5000
- input: {labelableId: $labelableId, labelIds: $labelIds}
5001
- ) {
5002
- labelable {
5003
- ... on Issue {
5004
- id
5005
- labels(first: 50) {
5006
- nodes {
5007
- name
5008
- }
5009
- }
5010
- }
5011
- }
5012
- }
5013
- }
5014
- `;
5015
-
5016
5439
  // src/gql/operations/issue-milestone-lookup.generated.ts
5017
5440
  var IssueMilestoneLookupDocument = `
5018
5441
  query IssueMilestoneLookup($issueId: ID!, $milestoneNumber: Int!) {
@@ -5029,7 +5452,8 @@ var IssueMilestoneLookupDocument = `
5029
5452
  `;
5030
5453
 
5031
5454
  // src/gql/document-registry.ts
5032
- var LOOKUP_DOCUMENTS = {
5455
+ var DOCUMENTS = {
5456
+ // Resolution lookup queries (Phase 1)
5033
5457
  IssueAssigneesLookup: IssueAssigneesLookupDocument,
5034
5458
  IssueAssigneesLookupByNumber: IssueAssigneesLookupByNumberDocument,
5035
5459
  IssueCreateRepositoryId: IssueCreateRepositoryIdDocument,
@@ -5039,9 +5463,9 @@ var LOOKUP_DOCUMENTS = {
5039
5463
  IssueMilestoneLookupByNumber: IssueMilestoneLookupByNumberDocument,
5040
5464
  IssueNodeIdLookup: IssueNodeIdLookupDocument,
5041
5465
  IssueParentLookup: IssueParentLookupDocument,
5042
- PrNodeId: PrNodeIdDocument
5043
- };
5044
- var MUTATION_DOCUMENTS = {
5466
+ PrNodeId: PrNodeIdDocument,
5467
+ UserNodeId: UserNodeIdDocument,
5468
+ // Mutation documents
5045
5469
  IssueAssigneesAdd: IssueAssigneesAddDocument,
5046
5470
  IssueAssigneesRemove: IssueAssigneesRemoveDocument,
5047
5471
  IssueAssigneesUpdate: IssueAssigneesUpdateDocument,
@@ -5059,24 +5483,51 @@ var MUTATION_DOCUMENTS = {
5059
5483
  IssueParentSet: IssueParentSetDocument,
5060
5484
  IssueReopen: IssueReopenDocument,
5061
5485
  IssueUpdate: IssueUpdateDocument,
5486
+ PrAssigneesAdd: PrAssigneesAddDocument,
5487
+ PrAssigneesRemove: PrAssigneesRemoveDocument,
5488
+ PrBranchUpdate: PrBranchUpdateDocument,
5062
5489
  PrCommentReply: PrCommentReplyDocument,
5063
5490
  PrCommentResolve: PrCommentResolveDocument,
5064
5491
  PrCommentUnresolve: PrCommentUnresolveDocument,
5065
- PrReviewSubmit: PrReviewSubmitDocument
5492
+ PrCreate: PrCreateDocument,
5493
+ PrMerge: PrMergeDocument,
5494
+ PrReviewSubmit: PrReviewSubmitDocument,
5495
+ PrReviewsRequest: PrReviewsRequestDocument,
5496
+ PrUpdate: PrUpdateDocument,
5497
+ AddProjectV2Item: AddProjectV2ItemDocument,
5498
+ RemoveProjectV2Item: RemoveProjectV2ItemDocument,
5499
+ UpdateProjectV2ItemField: UpdateProjectV2ItemFieldDocument,
5500
+ // Query documents
5501
+ IssueView: IssueViewDocument,
5502
+ IssueList: IssueListDocument,
5503
+ IssueCommentsList: IssueCommentsListDocument,
5504
+ IssueRelationsGet: IssueRelationsGetDocument,
5505
+ IssueLinkedPrsList: IssueLinkedPrsListDocument,
5506
+ PrView: PrViewDocument,
5507
+ PrList: PrListDocument,
5508
+ PrDiffListFiles: PrDiffListFilesDocument,
5509
+ PrMergeStatus: PrMergeStatusDocument,
5510
+ PrCommentsList: PrCommentsListDocument,
5511
+ PrReviewsList: PrReviewsListDocument,
5512
+ RepoView: RepoViewDocument,
5513
+ RepoLabelsList: RepoLabelsListDocument,
5514
+ RepoIssueTypesList: RepoIssueTypesListDocument,
5515
+ ReleaseView: ReleaseViewDocument,
5516
+ ReleaseList: ReleaseListDocument,
5517
+ ProjectV2OrgView: ProjectV2OrgViewDocument,
5518
+ ProjectV2UserView: ProjectV2UserViewDocument,
5519
+ ProjectV2FieldsListOrg: ProjectV2FieldsListOrgDocument,
5520
+ ProjectV2ItemsListOrg: ProjectV2ItemsListOrgDocument
5066
5521
  };
5067
- function getLookupDocument(operationName) {
5068
- const doc = LOOKUP_DOCUMENTS[operationName];
5522
+ function getDocument(operationName) {
5523
+ const doc = DOCUMENTS[operationName];
5069
5524
  if (!doc) {
5070
- throw new Error(`No lookup document registered for operation: ${operationName}`);
5525
+ throw new Error(`No document registered for operation: ${operationName}`);
5071
5526
  }
5072
5527
  return doc;
5073
5528
  }
5074
- function getMutationDocument(operationName) {
5075
- const doc = MUTATION_DOCUMENTS[operationName];
5076
- if (!doc) {
5077
- throw new Error(`No mutation document registered for operation: ${operationName}`);
5078
- }
5079
- return doc;
5529
+ function getLookupDocument(operationName) {
5530
+ return getDocument(operationName);
5080
5531
  }
5081
5532
 
5082
5533
  // src/gql/resolve.ts
@@ -5150,8 +5601,8 @@ function applyInject(spec, lookupResult, input) {
5150
5601
  });
5151
5602
  return { [spec.target]: resolved };
5152
5603
  }
5153
- function buildMutationVars(mutationDoc, input, resolved) {
5154
- const headerMatch = mutationDoc.match(/(?:query|mutation)\s+\w+\s*\(([^)]*)\)/);
5604
+ function buildOperationVars(operationDoc, input, resolved) {
5605
+ const headerMatch = operationDoc.match(/(?:query|mutation)\s+\w+\s*\(([^)]*)\)/);
5155
5606
  const mutVarNames = /* @__PURE__ */ new Set();
5156
5607
  if (headerMatch?.[1]) {
5157
5608
  for (const match of headerMatch[1].matchAll(/\$(\w+)\s*:/g)) {
@@ -5172,211 +5623,131 @@ function buildMutationVars(mutationDoc, input, resolved) {
5172
5623
  return vars;
5173
5624
  }
5174
5625
 
5175
- // src/core/routing/engine.ts
5176
- var DEFAULT_REASON = "DEFAULT_POLICY";
5177
- var CLI_ENV_CACHE_TTL_MS = 3e4;
5178
- var cliEnvironmentCache = /* @__PURE__ */ new WeakMap();
5179
- var cliEnvironmentInFlight = /* @__PURE__ */ new WeakMap();
5180
- var defaultCliRunner = createSafeCliCommandRunner();
5181
- async function detectCliEnvironment(runner) {
5182
- try {
5183
- const version = await runner.run("gh", ["--version"], 1500);
5184
- if (version.exitCode !== 0) {
5185
- return {
5186
- ghCliAvailable: false,
5187
- ghAuthenticated: false
5188
- };
5626
+ // src/core/routing/engine/execute.ts
5627
+ async function runGqlExecutePhase(steps, requests, lookupResults, deps) {
5628
+ const mutationInputs = [];
5629
+ const queryInputs = [];
5630
+ const stepErrors = /* @__PURE__ */ new Map();
5631
+ const stepPreErrors = /* @__PURE__ */ new Map();
5632
+ for (const step of steps) {
5633
+ const { card, index, route } = step;
5634
+ const req = requests[index];
5635
+ if (req === void 0) continue;
5636
+ try {
5637
+ logger.debug("resolution.inject", { step: index, capability_id: req.task });
5638
+ const resolved = {};
5639
+ if (card.graphql?.resolution && lookupResults[index] !== void 0) {
5640
+ for (const spec of card.graphql.resolution.inject) {
5641
+ Object.assign(resolved, applyInject(spec, lookupResults[index], req.input));
5642
+ }
5643
+ }
5644
+ if (!card.graphql) {
5645
+ throw new Error(`Step ${index}: card has no graphql config for route '${route}'`);
5646
+ }
5647
+ const doc = getDocument(card.graphql.operationName);
5648
+ const vars = buildOperationVars(doc, req.input, resolved);
5649
+ if (route === "gql-mutation") {
5650
+ mutationInputs.push({
5651
+ alias: `step${index}`,
5652
+ mutation: doc,
5653
+ variables: vars,
5654
+ stepIndex: index
5655
+ });
5656
+ } else {
5657
+ queryInputs.push({
5658
+ alias: `step${index}`,
5659
+ query: doc,
5660
+ variables: vars,
5661
+ stepIndex: index
5662
+ });
5663
+ }
5664
+ } catch (err) {
5665
+ stepPreErrors.set(index, err instanceof Error ? err.message : String(err));
5189
5666
  }
5190
- const auth = await runner.run("gh", ["auth", "status"], 2500);
5191
- return {
5192
- ghCliAvailable: true,
5193
- ghAuthenticated: auth.exitCode === 0
5194
- };
5195
- } catch {
5196
- return {
5197
- ghCliAvailable: false,
5198
- ghAuthenticated: false
5199
- };
5200
5667
  }
5201
- }
5202
- async function detectCliEnvironmentCached(runner) {
5203
- const now = Date.now();
5204
- const cached = cliEnvironmentCache.get(runner);
5205
- if (cached && cached.expiresAt > now) {
5206
- return cached.value;
5207
- }
5208
- const inFlight = cliEnvironmentInFlight.get(runner);
5209
- if (inFlight) {
5210
- return inFlight;
5668
+ for (const [index, msg] of stepPreErrors) {
5669
+ stepErrors.set(`step${index}`, msg);
5211
5670
  }
5212
- const probePromise = detectCliEnvironment(runner).then((value) => {
5213
- cliEnvironmentCache.set(runner, {
5214
- value,
5215
- expiresAt: Date.now() + CLI_ENV_CACHE_TTL_MS
5216
- });
5217
- cliEnvironmentInFlight.delete(runner);
5218
- return value;
5219
- }).catch((error) => {
5220
- cliEnvironmentInFlight.delete(runner);
5221
- throw error;
5222
- });
5223
- cliEnvironmentInFlight.set(runner, probePromise);
5224
- return probePromise;
5225
- }
5226
- function isRetryableCode(code) {
5227
- return code === errorCodes.RateLimit || code === errorCodes.Network || code === errorCodes.Server;
5228
- }
5229
- async function executeTask(request, deps) {
5230
- const reason = deps.reason ?? DEFAULT_REASON;
5231
- const card = getOperationCard(request.task);
5232
- if (!card) {
5233
- logger.error("execute.unsupported_task", { task: request.task });
5234
- return normalizeError(
5235
- {
5236
- code: errorCodes.Validation,
5237
- message: `Unsupported task: ${request.task}`,
5238
- retryable: false
5239
- },
5240
- routePreferenceOrder[0],
5241
- { capabilityId: request.task, reason }
5242
- );
5243
- }
5244
- logger.debug("execute.start", { capability_id: request.task });
5245
- const startMs = Date.now();
5246
- const cliRunner = deps.cliRunner ?? defaultCliRunner;
5247
- const result = await execute({
5248
- card,
5249
- params: request.input,
5250
- routingContext: {
5251
- ghCliAvailable: deps.ghCliAvailable,
5252
- ghAuthenticated: deps.ghAuthenticated,
5253
- githubTokenPresent: Boolean(deps.githubToken)
5254
- },
5255
- retry: {
5256
- maxAttemptsPerRoute: 2
5257
- },
5258
- preflight: async (route) => {
5259
- const preflightInput = { route };
5260
- if (deps.githubToken !== void 0) {
5261
- preflightInput.githubToken = deps.githubToken;
5262
- }
5263
- if (route === "cli") {
5264
- if (deps.ghCliAvailable !== void 0) {
5265
- preflightInput.ghCliAvailable = deps.ghCliAvailable;
5266
- }
5267
- if (deps.ghAuthenticated !== void 0) {
5268
- preflightInput.ghAuthenticated = deps.ghAuthenticated;
5671
+ let mutationRawResult = {};
5672
+ const mutationPromise = mutationInputs.length > 0 ? (async () => {
5673
+ try {
5674
+ const { document, variables } = buildBatchMutation(
5675
+ mutationInputs.map(({ alias, mutation, variables: variables2 }) => ({
5676
+ alias,
5677
+ mutation,
5678
+ variables: variables2
5679
+ }))
5680
+ );
5681
+ logger.debug("mutation.batch_start", { count: mutationInputs.length });
5682
+ const rawResponse = await deps.githubClient.queryRaw(
5683
+ document,
5684
+ variables
5685
+ );
5686
+ if (rawResponse.errors?.length) {
5687
+ const attributedAliases = /* @__PURE__ */ new Set();
5688
+ for (const err of rawResponse.errors) {
5689
+ const alias = err.path?.[0];
5690
+ if (typeof alias === "string" && alias.startsWith("step")) {
5691
+ stepErrors.set(alias, err.message);
5692
+ attributedAliases.add(alias);
5693
+ }
5269
5694
  }
5270
- if (preflightInput.ghCliAvailable === void 0 || preflightInput.ghAuthenticated === void 0) {
5271
- if (deps.skipGhPreflight === true) {
5272
- if (preflightInput.ghCliAvailable === void 0) {
5273
- preflightInput.ghCliAvailable = true;
5274
- }
5275
- if (preflightInput.ghAuthenticated === void 0) {
5276
- preflightInput.ghAuthenticated = true;
5277
- }
5278
- } else {
5279
- const detected = await detectCliEnvironmentCached(cliRunner);
5280
- if (preflightInput.ghCliAvailable === void 0) {
5281
- preflightInput.ghCliAvailable = detected.ghCliAvailable;
5282
- }
5283
- if (preflightInput.ghAuthenticated === void 0) {
5284
- preflightInput.ghAuthenticated = detected.ghAuthenticated;
5695
+ if (attributedAliases.size === 0) {
5696
+ for (const { alias } of mutationInputs) {
5697
+ if (!stepErrors.has(alias)) {
5698
+ stepErrors.set(alias, rawResponse.errors[0]?.message ?? "GraphQL batch error");
5285
5699
  }
5286
5700
  }
5287
5701
  }
5288
5702
  }
5289
- return preflightCheck(preflightInput);
5290
- },
5291
- routes: {
5292
- graphql: async () => {
5293
- return runGraphqlCapability(
5294
- deps.githubClient,
5295
- request.task,
5296
- request.input
5297
- );
5298
- },
5299
- cli: async () => {
5300
- return runCliCapability(
5301
- cliRunner,
5302
- request.task,
5303
- request.input,
5304
- card
5305
- );
5306
- },
5307
- rest: async () => normalizeError(
5308
- {
5309
- code: errorCodes.AdapterUnsupported,
5310
- message: `Route 'rest' is not implemented for task '${request.task}'`,
5311
- retryable: false,
5312
- details: { route: "rest", task: request.task }
5313
- },
5314
- "rest",
5315
- { capabilityId: request.task, reason }
5316
- )
5317
- }
5318
- });
5319
- logger.info("execute.complete", {
5320
- capability_id: request.task,
5321
- ok: result.ok,
5322
- route_used: result.meta?.route_used ?? null,
5323
- duration_ms: Date.now() - startMs,
5324
- error_code: result.error?.code ?? null
5325
- });
5326
- return result;
5327
- }
5328
- async function executeTasks(requests, deps) {
5329
- logger.debug("execute_batch.start", { count: requests.length });
5330
- const batchStart = Date.now();
5331
- if (requests.length === 1) {
5332
- const [req] = requests;
5333
- if (req === void 0) {
5334
- logger.info("execute_batch.complete", {
5335
- ok: false,
5336
- status: "failed",
5337
- total: 0,
5338
- succeeded: 0,
5339
- failed: 0,
5340
- duration_ms: Date.now() - batchStart
5341
- });
5342
- return {
5343
- status: "failed",
5344
- results: [],
5345
- meta: { route_used: "graphql", total: 0, succeeded: 0, failed: 0 }
5346
- };
5347
- }
5348
- const result = await executeTask({ task: req.task, input: req.input }, deps);
5349
- const step = result.ok ? { task: req.task, ok: true, data: result.data } : {
5350
- task: req.task,
5351
- ok: false,
5352
- error: result.error || {
5353
- code: errorCodes.Unknown,
5354
- message: "Unknown error",
5355
- retryable: false
5703
+ mutationRawResult = rawResponse.data ?? {};
5704
+ logger.debug("mutation.batch_complete", { count: mutationInputs.length });
5705
+ } catch (err) {
5706
+ const code = mapErrorToCode(err);
5707
+ logger.error("mutation.batch_failed", { error_code: code });
5708
+ for (const { alias } of mutationInputs) {
5709
+ stepErrors.set(alias, err instanceof Error ? err.message : String(err));
5356
5710
  }
5357
- };
5358
- const succeeded1 = result.ok ? 1 : 0;
5359
- logger.info("execute_batch.complete", {
5360
- ok: result.ok,
5361
- status: result.ok ? "success" : "failed",
5362
- total: 1,
5363
- succeeded: succeeded1,
5364
- failed: 1 - succeeded1,
5365
- duration_ms: Date.now() - batchStart
5366
- });
5367
- return {
5368
- status: result.ok ? "success" : "failed",
5369
- results: [step],
5370
- meta: {
5371
- route_used: result.meta?.route_used ?? "graphql",
5372
- total: 1,
5373
- succeeded: succeeded1,
5374
- failed: 1 - succeeded1
5711
+ }
5712
+ })() : Promise.resolve();
5713
+ let queryRawResult = {};
5714
+ const queryPromise = queryInputs.length > 0 ? (async () => {
5715
+ try {
5716
+ const { document, variables } = buildBatchQuery(
5717
+ queryInputs.map(({ alias, query, variables: variables2 }) => ({
5718
+ alias,
5719
+ query,
5720
+ variables: variables2
5721
+ }))
5722
+ );
5723
+ logger.debug("query.batch_start", { count: queryInputs.length });
5724
+ const rawResult = await deps.githubClient.query(
5725
+ document,
5726
+ variables
5727
+ );
5728
+ queryRawResult = rawResult;
5729
+ logger.debug("query.batch_complete", { count: queryInputs.length });
5730
+ } catch (err) {
5731
+ const code = mapErrorToCode(err);
5732
+ logger.error("query.batch_failed", { error_code: code });
5733
+ for (const { alias } of queryInputs) {
5734
+ stepErrors.set(alias, err instanceof Error ? err.message : String(err));
5375
5735
  }
5376
- };
5377
- }
5736
+ }
5737
+ })() : Promise.resolve();
5738
+ await Promise.allSettled([mutationPromise, queryPromise]);
5739
+ return {
5740
+ mutationRawResult,
5741
+ queryRawResult,
5742
+ stepErrors
5743
+ };
5744
+ }
5745
+
5746
+ // src/core/routing/engine/preflight.ts
5747
+ function runPreflight(requests) {
5378
5748
  const preflightErrorByIndex = /* @__PURE__ */ new Map();
5379
5749
  const cards = [];
5750
+ const cardIsCliOnly = [];
5380
5751
  for (let i = 0; i < requests.length; i += 1) {
5381
5752
  const req = requests[i];
5382
5753
  if (req === void 0) continue;
@@ -5390,10 +5761,12 @@ async function executeTasks(requests, deps) {
5390
5761
  const details = inputValidation.errors.map((e) => `${e.instancePath || "root"}: ${e.message}`).join("; ");
5391
5762
  throw new Error(`Input validation failed: ${details}`);
5392
5763
  }
5393
- if (!card.graphql) {
5394
- throw new Error(`capability '${req.task}' has no GraphQL route and cannot be chained`);
5764
+ if (!card.graphql && !card.cli) {
5765
+ throw new Error(
5766
+ `capability '${req.task}' has no supported route (graphql or cli) and cannot be chained`
5767
+ );
5395
5768
  }
5396
- if (card.graphql.resolution) {
5769
+ if (card.graphql?.resolution) {
5397
5770
  const { lookup } = card.graphql.resolution;
5398
5771
  for (const [, inputField] of Object.entries(lookup.vars)) {
5399
5772
  if (req.input[inputField] === void 0) {
@@ -5404,6 +5777,7 @@ async function executeTasks(requests, deps) {
5404
5777
  }
5405
5778
  }
5406
5779
  cards.push(card);
5780
+ cardIsCliOnly.push(!card.graphql);
5407
5781
  } catch (err) {
5408
5782
  preflightErrorByIndex.set(i, {
5409
5783
  task: req.task,
@@ -5417,51 +5791,67 @@ async function executeTasks(requests, deps) {
5417
5791
  }
5418
5792
  }
5419
5793
  if (preflightErrorByIndex.size > 0) {
5420
- return {
5421
- status: "failed",
5422
- results: requests.map(
5423
- (req, i) => preflightErrorByIndex.get(i) ?? {
5424
- task: req.task,
5425
- ok: false,
5426
- error: {
5427
- code: errorCodes.Unknown,
5428
- message: "pre-flight failed",
5429
- retryable: false
5430
- }
5794
+ const results = requests.map(
5795
+ (req, i) => preflightErrorByIndex.get(i) ?? {
5796
+ task: req?.task ?? "unknown",
5797
+ ok: false,
5798
+ error: {
5799
+ code: errorCodes.Unknown,
5800
+ message: "pre-flight failed",
5801
+ retryable: false
5431
5802
  }
5432
- ),
5433
- meta: {
5434
- route_used: "graphql",
5435
- total: requests.length,
5436
- succeeded: 0,
5437
- failed: requests.length
5438
5803
  }
5439
- };
5440
- }
5441
- const lookupInputs = [];
5442
- const lookupResults = {};
5443
- function buildLookupVars(card, req) {
5444
- const vars = {};
5445
- if (card.graphql?.resolution) {
5446
- for (const [lookupVar, inputField] of Object.entries(card.graphql.resolution.lookup.vars)) {
5447
- vars[lookupVar] = req.input[inputField];
5448
- }
5449
- }
5450
- return vars;
5804
+ );
5805
+ const anyGqlCard = cardIsCliOnly.some((isCliOnly) => !isCliOnly);
5806
+ const routeUsed = !anyGqlCard && cards.length > 0 ? "cli" : "graphql";
5807
+ return { ok: false, results, routeUsed };
5451
5808
  }
5809
+ const steps = [];
5810
+ let cardIndex = 0;
5452
5811
  for (let i = 0; i < requests.length; i += 1) {
5453
- const card = cards[i];
5454
5812
  const req = requests[i];
5455
- if (card === void 0 || req === void 0) continue;
5813
+ const card = cards[cardIndex];
5814
+ if (req === void 0 || card === void 0) continue;
5815
+ cardIndex += 1;
5816
+ let route;
5817
+ if (!card.graphql) {
5818
+ route = "cli";
5819
+ } else if (card.graphql.operationType === "query") {
5820
+ route = "gql-query";
5821
+ } else {
5822
+ route = "gql-mutation";
5823
+ }
5824
+ steps.push({ route, card, index: i, request: req });
5825
+ }
5826
+ return { ok: true, steps, cards };
5827
+ }
5828
+
5829
+ // src/core/routing/engine/resolve.ts
5830
+ function buildLookupVars(card, input) {
5831
+ const vars = {};
5832
+ if (card.graphql?.resolution) {
5833
+ for (const [lookupVar, inputField] of Object.entries(card.graphql.resolution.lookup.vars)) {
5834
+ vars[lookupVar] = input[inputField];
5835
+ }
5836
+ }
5837
+ return vars;
5838
+ }
5839
+ async function runResolutionPhase(steps, requests, githubClient, resolutionCache) {
5840
+ const lookupResults = {};
5841
+ const lookupInputs = [];
5842
+ for (const step of steps) {
5843
+ const { card, index } = step;
5456
5844
  if (!card.graphql?.resolution) continue;
5457
- const lookupVars = buildLookupVars(card, req);
5458
- if (deps.resolutionCache) {
5845
+ const req = requests[index];
5846
+ if (req === void 0) continue;
5847
+ const lookupVars = buildLookupVars(card, req.input);
5848
+ if (resolutionCache) {
5459
5849
  const cacheKey = buildCacheKey(card.graphql.resolution.lookup.operationName, lookupVars);
5460
- const cached = deps.resolutionCache.get(cacheKey);
5850
+ const cached = resolutionCache.get(cacheKey);
5461
5851
  if (cached !== void 0) {
5462
- lookupResults[i] = cached;
5852
+ lookupResults[index] = cached;
5463
5853
  logger.debug("resolution.cache_hit", {
5464
- step: i,
5854
+ step: index,
5465
5855
  operation: card.graphql.resolution.lookup.operationName,
5466
5856
  key: cacheKey
5467
5857
  });
@@ -5469,237 +5859,176 @@ async function executeTasks(requests, deps) {
5469
5859
  }
5470
5860
  }
5471
5861
  logger.debug("resolution.lookup_scheduled", {
5472
- step: i,
5862
+ step: index,
5473
5863
  operation: card.graphql.resolution.lookup.operationName
5474
5864
  });
5475
5865
  lookupInputs.push({
5476
- alias: `step${i}`,
5866
+ alias: `step${index}`,
5477
5867
  query: getLookupDocument(card.graphql.resolution.lookup.operationName),
5478
5868
  variables: lookupVars,
5479
- stepIndex: i
5869
+ stepIndex: index
5480
5870
  });
5481
5871
  }
5482
- if (lookupInputs.length > 0) {
5483
- try {
5484
- const { document, variables } = buildBatchQuery(
5485
- lookupInputs.map(({ alias, query, variables: variables2 }) => ({
5486
- alias,
5487
- query,
5488
- variables: variables2
5489
- }))
5490
- );
5491
- logger.debug("query.batch_start", { count: lookupInputs.length });
5492
- const rawResult = await deps.githubClient.query(document, variables);
5493
- logger.debug("query.batch_complete", { count: lookupInputs.length });
5494
- for (const { alias, query, stepIndex } of lookupInputs) {
5495
- const rawValue = rawResult[alias];
5496
- const rootFieldName = extractRootFieldName(query);
5497
- const result = rootFieldName !== null ? { [rootFieldName]: rawValue } : rawValue;
5498
- lookupResults[stepIndex] = result;
5499
- logger.debug("resolution.step_resolved", { step: stepIndex, alias });
5500
- if (deps.resolutionCache && result !== void 0) {
5501
- const card = cards[stepIndex];
5502
- const req = requests[stepIndex];
5503
- if (card?.graphql?.resolution && req) {
5504
- const lookupVars = buildLookupVars(card, req);
5505
- deps.resolutionCache.set(
5506
- buildCacheKey(card.graphql.resolution.lookup.operationName, lookupVars),
5507
- result
5508
- );
5509
- logger.debug("resolution.cache_set", {
5510
- step: stepIndex,
5511
- operation: card.graphql.resolution.lookup.operationName
5512
- });
5513
- }
5514
- }
5515
- }
5516
- } catch (err) {
5517
- const errorMsg = err instanceof Error ? err.message : String(err);
5518
- const code = mapErrorToCode(err);
5519
- logger.error("resolution.lookup_failed", {
5520
- count: lookupInputs.length,
5521
- error_code: code,
5522
- message: errorMsg
5523
- });
5524
- return {
5525
- status: "failed",
5526
- results: requests.map((req) => ({
5527
- task: req.task,
5528
- ok: false,
5529
- error: {
5530
- code,
5531
- message: `Phase 1 (resolution) failed: ${errorMsg}`,
5532
- retryable: isRetryableCode(code)
5533
- }
5534
- })),
5535
- meta: {
5536
- route_used: "graphql",
5537
- total: requests.length,
5538
- succeeded: 0,
5539
- failed: requests.length
5540
- }
5541
- };
5542
- }
5872
+ if (lookupInputs.length === 0) {
5873
+ return lookupResults;
5543
5874
  }
5544
- const mutationInputs = [];
5545
- const stepPreResults = {};
5546
- for (let i = 0; i < requests.length; i += 1) {
5547
- const card = cards[i];
5548
- const req = requests[i];
5549
- if (card === void 0 || req === void 0) continue;
5550
- try {
5551
- logger.debug("resolution.inject", { step: i, capability_id: req.task });
5552
- const resolved = {};
5553
- if (card.graphql?.resolution && lookupResults[i] !== void 0) {
5554
- for (const spec of card.graphql.resolution.inject) {
5555
- Object.assign(resolved, applyInject(spec, lookupResults[i], req.input));
5556
- }
5557
- }
5558
- if (card.graphql === void 0) {
5559
- throw new Error("card.graphql is unexpectedly undefined");
5875
+ const { document, variables } = buildBatchQuery(
5876
+ lookupInputs.map(({ alias, query, variables: variables2 }) => ({
5877
+ alias,
5878
+ query,
5879
+ variables: variables2
5880
+ }))
5881
+ );
5882
+ logger.debug("query.batch_start", { count: lookupInputs.length });
5883
+ const rawResult = await githubClient.query(document, variables);
5884
+ logger.debug("query.batch_complete", { count: lookupInputs.length });
5885
+ for (const { alias, query, stepIndex } of lookupInputs) {
5886
+ const rawValue = rawResult[alias];
5887
+ if (rawValue === void 0) {
5888
+ logger.debug("resolution.step_missing", { step: stepIndex, alias });
5889
+ continue;
5890
+ }
5891
+ const rootFieldName = extractRootFieldName(query);
5892
+ const result = rootFieldName !== null ? { [rootFieldName]: rawValue } : rawValue;
5893
+ lookupResults[stepIndex] = result;
5894
+ logger.debug("resolution.step_resolved", { step: stepIndex, alias });
5895
+ if (resolutionCache) {
5896
+ const step = steps.find((s) => s.index === stepIndex);
5897
+ const req = requests[stepIndex];
5898
+ if (step?.card.graphql?.resolution && req) {
5899
+ const lookupVars = buildLookupVars(step.card, req.input);
5900
+ resolutionCache.set(
5901
+ buildCacheKey(step.card.graphql.resolution.lookup.operationName, lookupVars),
5902
+ result
5903
+ );
5904
+ logger.debug("resolution.cache_set", {
5905
+ step: stepIndex,
5906
+ operation: step.card.graphql.resolution.lookup.operationName
5907
+ });
5560
5908
  }
5561
- const mutDoc = getMutationDocument(card.graphql.operationName);
5562
- const mutVars = buildMutationVars(mutDoc, req.input, resolved);
5563
- mutationInputs.push({
5564
- alias: `step${i}`,
5565
- mutation: mutDoc,
5566
- variables: mutVars,
5567
- stepIndex: i
5568
- });
5569
- } catch (err) {
5570
- stepPreResults[i] = {
5571
- task: req.task,
5572
- ok: false,
5573
- error: {
5574
- code: mapErrorToCode(err),
5575
- message: err instanceof Error ? err.message : String(err),
5576
- retryable: false
5577
- }
5578
- };
5579
5909
  }
5580
5910
  }
5581
- let rawMutResult = {};
5582
- const stepErrors = /* @__PURE__ */ new Map();
5583
- if (mutationInputs.length > 0) {
5584
- try {
5585
- const { document, variables } = buildBatchMutation(
5586
- mutationInputs.map(({ alias, mutation, variables: variables2 }) => ({
5587
- alias,
5588
- mutation,
5589
- variables: variables2
5590
- }))
5591
- );
5592
- logger.debug("mutation.batch_start", { count: mutationInputs.length });
5593
- const rawResponse = await deps.githubClient.queryRaw(
5594
- document,
5595
- variables
5596
- );
5597
- if (rawResponse.errors?.length) {
5598
- for (const err of rawResponse.errors) {
5599
- const alias = err.path?.[0];
5600
- if (typeof alias === "string" && alias.startsWith("step")) {
5601
- stepErrors.set(alias, err.message);
5602
- }
5603
- }
5604
- if (stepErrors.size === 0) {
5605
- for (const { alias } of mutationInputs) {
5606
- stepErrors.set(alias, rawResponse.errors[0]?.message ?? "GraphQL batch error");
5607
- }
5608
- }
5609
- }
5610
- rawMutResult = rawResponse.data ?? {};
5611
- logger.debug("mutation.batch_complete", { count: mutationInputs.length });
5612
- } catch (err) {
5613
- const code = mapErrorToCode(err);
5614
- logger.error("mutation.batch_failed", { error_code: code });
5615
- for (const { stepIndex } of mutationInputs) {
5616
- const reqAtIndex = requests[stepIndex];
5617
- if (reqAtIndex !== void 0) {
5618
- stepPreResults[stepIndex] = {
5619
- task: reqAtIndex.task,
5620
- ok: false,
5621
- error: {
5622
- code,
5623
- message: err instanceof Error ? err.message : String(err),
5624
- retryable: isRetryableCode(code)
5625
- }
5626
- };
5627
- }
5911
+ return lookupResults;
5912
+ }
5913
+
5914
+ // src/core/routing/engine/batch.ts
5915
+ async function executeBatch(requests, deps) {
5916
+ const batchStartMs = Date.now();
5917
+ const preflight = runPreflight(requests);
5918
+ if (!preflight.ok) {
5919
+ return {
5920
+ status: "failed",
5921
+ results: preflight.results,
5922
+ meta: {
5923
+ route_used: preflight.routeUsed,
5924
+ total: requests.length,
5925
+ succeeded: 0,
5926
+ failed: requests.length
5628
5927
  }
5629
- }
5928
+ };
5630
5929
  }
5631
- const results = requests.map((req, stepIndex) => {
5632
- const preResult = stepPreResults[stepIndex];
5633
- if (preResult !== void 0) return preResult;
5634
- const mutInput = mutationInputs.find((m) => m.stepIndex === stepIndex);
5635
- if (mutInput === void 0) {
5636
- return {
5637
- task: req.task,
5638
- ok: false,
5639
- error: {
5640
- code: errorCodes.Unknown,
5641
- message: "step skipped",
5642
- retryable: false
5643
- }
5644
- };
5645
- }
5646
- const stepError = stepErrors.get(mutInput.alias);
5647
- if (stepError !== void 0) {
5648
- return {
5649
- task: req.task,
5650
- ok: false,
5651
- error: {
5652
- code: mapErrorToCode(stepError),
5653
- message: stepError,
5654
- retryable: false
5655
- }
5656
- };
5657
- }
5658
- if (rawMutResult == null || typeof rawMutResult !== "object") {
5659
- return {
5660
- task: req.task,
5661
- ok: false,
5662
- error: {
5663
- code: errorCodes.Unknown,
5664
- message: `unexpected mutation response shape for alias ${mutInput.alias}`,
5665
- retryable: false
5666
- }
5667
- };
5668
- }
5669
- if (!(mutInput.alias in rawMutResult)) {
5930
+ const { steps } = preflight;
5931
+ const cliSteps = steps.filter((s) => s.route === "cli");
5932
+ const gqlSteps = steps.filter((s) => s.route === "gql-query" || s.route === "gql-mutation");
5933
+ const cliStepCount = cliSteps.length;
5934
+ const cliPromises = startCliSteps(steps, requests, deps);
5935
+ let lookupResults = {};
5936
+ try {
5937
+ lookupResults = await runResolutionPhase(
5938
+ gqlSteps,
5939
+ requests,
5940
+ deps.githubClient,
5941
+ deps.resolutionCache
5942
+ );
5943
+ } catch (err) {
5944
+ const code = mapErrorToCode(err);
5945
+ const errorMsg = err instanceof Error ? err.message : String(err);
5946
+ logger.error("resolution.lookup_failed", {
5947
+ count: gqlSteps.length,
5948
+ error_code: code,
5949
+ message: errorMsg
5950
+ });
5951
+ const cliResults2 = await collectCliResults(cliPromises, cliSteps, requests);
5952
+ return assembleResolutionFailure(
5953
+ requests,
5954
+ steps,
5955
+ {
5956
+ code,
5957
+ message: `Phase 1 (resolution) failed: ${errorMsg}`,
5958
+ retryable: isRetryableCode(code)
5959
+ },
5960
+ cliResults2
5961
+ );
5962
+ }
5963
+ const { mutationRawResult, queryRawResult, stepErrors } = await runGqlExecutePhase(
5964
+ gqlSteps,
5965
+ requests,
5966
+ lookupResults,
5967
+ deps
5968
+ );
5969
+ const cliResults = await collectCliResults(cliPromises, cliSteps, requests);
5970
+ return assembleChainResult({
5971
+ steps,
5972
+ requests,
5973
+ mutationRawResult,
5974
+ queryRawResult,
5975
+ stepErrors,
5976
+ cliResults,
5977
+ cliStepCount,
5978
+ batchStartMs
5979
+ });
5980
+ }
5981
+
5982
+ // src/core/routing/engine/index.ts
5983
+ async function executeTask(request, deps) {
5984
+ return runSingleTask(request.task, request.input, deps);
5985
+ }
5986
+ async function executeTasks(requests, deps) {
5987
+ logger.debug("execute_batch.start", { count: requests.length });
5988
+ if (requests.length === 0) {
5989
+ return {
5990
+ status: "failed",
5991
+ results: [],
5992
+ meta: { route_used: "graphql", total: 0, succeeded: 0, failed: 0 }
5993
+ };
5994
+ }
5995
+ if (requests.length === 1) {
5996
+ const req = requests[0];
5997
+ if (req === void 0) {
5670
5998
  return {
5671
- task: req.task,
5672
- ok: false,
5673
- error: {
5674
- code: errorCodes.Unknown,
5675
- message: `missing mutation result for alias ${mutInput.alias}`,
5676
- retryable: false
5677
- }
5999
+ status: "failed",
6000
+ results: [],
6001
+ meta: { route_used: "graphql", total: 0, succeeded: 0, failed: 0 }
5678
6002
  };
5679
6003
  }
5680
- const data = rawMutResult[mutInput.alias];
5681
- return { task: req.task, ok: true, data };
5682
- });
5683
- const succeeded = results.filter((r) => r.ok).length;
5684
- const status = succeeded === results.length ? "success" : succeeded === 0 ? "failed" : "partial";
5685
- logger.info("execute_batch.complete", {
5686
- ok: status !== "failed",
5687
- status,
5688
- total: results.length,
5689
- succeeded,
5690
- failed: results.length - succeeded,
5691
- duration_ms: Date.now() - batchStart
5692
- });
5693
- return {
5694
- status,
5695
- results,
5696
- meta: {
5697
- route_used: "graphql",
5698
- total: results.length,
6004
+ const batchStartMs = Date.now();
6005
+ const result = await runSingleTask(req.task, req.input, deps);
6006
+ const step = result.ok ? { task: req.task, ok: true, data: result.data } : {
6007
+ task: req.task,
6008
+ ok: false,
6009
+ error: result.error ?? {
6010
+ code: errorCodes.Unknown,
6011
+ message: "Unknown error",
6012
+ retryable: false
6013
+ }
6014
+ };
6015
+ const succeeded = result.ok ? 1 : 0;
6016
+ const routeUsed = result.meta?.route_used ?? "graphql";
6017
+ logger.info("execute_batch.complete", {
6018
+ ok: result.ok,
6019
+ status: result.ok ? "success" : "failed",
6020
+ total: 1,
5699
6021
  succeeded,
5700
- failed: results.length - succeeded
5701
- }
5702
- };
6022
+ failed: 1 - succeeded,
6023
+ duration_ms: Date.now() - batchStartMs
6024
+ });
6025
+ return {
6026
+ status: result.ok ? "success" : "failed",
6027
+ results: [step],
6028
+ meta: { route_used: routeUsed, total: 1, succeeded, failed: 1 - succeeded }
6029
+ };
6030
+ }
6031
+ return executeBatch(requests, deps);
5703
6032
  }
5704
6033
 
5705
6034
  // src/gql/github-client.ts
@@ -5718,11 +6047,15 @@ function createGithubClient(transport) {
5718
6047
  let issueMutations;
5719
6048
  let prQueries;
5720
6049
  let prMutations;
5721
- const loadRepo = async () => repo ??= await import("./repo-JDUHFPZF.js");
5722
- const loadIssueQueries = async () => issueQueries ??= await import("./issue-queries-GRA4MKPD.js");
5723
- const loadIssueMutations = async () => issueMutations ??= await import("./issue-mutations-FJNZW7L5.js");
5724
- const loadPrQueries = async () => prQueries ??= await import("./pr-queries-UOEOXIJQ.js");
5725
- const loadPrMutations = async () => prMutations ??= await import("./pr-mutations-UG67YOF5.js");
6050
+ let release;
6051
+ let project;
6052
+ const loadRepo = async () => repo ??= await import("./repo-JF47JAZG.js");
6053
+ const loadIssueQueries = async () => issueQueries ??= await import("./issue-queries-YQL65J7X.js");
6054
+ const loadIssueMutations = async () => issueMutations ??= await import("./issue-mutations-DIWPF3JH.js");
6055
+ const loadPrQueries = async () => prQueries ??= await import("./pr-queries-NUL2UZJB.js");
6056
+ const loadPrMutations = async () => prMutations ??= await import("./pr-mutations-BVHDCAPR.js");
6057
+ const loadRelease = async () => release ??= await import("./release-IQCWD655.js");
6058
+ const loadProject = async () => project ??= await import("./project-3ZSPVIOC.js");
5726
6059
  return {
5727
6060
  query: (query, variables) => graphqlClient.query(query, variables),
5728
6061
  queryRaw: (query, variables) => graphqlClient.queryRaw(query, variables),
@@ -5737,10 +6070,12 @@ function createGithubClient(transport) {
5737
6070
  deleteIssue: async (input) => (await loadIssueMutations()).runIssueDelete(transport, input),
5738
6071
  updateIssueLabels: async (input) => (await loadIssueMutations()).runIssueLabelsUpdate(transport, input),
5739
6072
  addIssueLabels: async (input) => (await loadIssueMutations()).runIssueLabelsAdd(transport, input),
6073
+ removeIssueLabels: async (input) => (await loadIssueMutations()).runIssueLabelsRemove(transport, input),
5740
6074
  updateIssueAssignees: async (input) => (await loadIssueMutations()).runIssueAssigneesUpdate(transport, input),
5741
6075
  addIssueAssignees: async (input) => (await loadIssueMutations()).runIssueAssigneesAdd(transport, input),
5742
6076
  removeIssueAssignees: async (input) => (await loadIssueMutations()).runIssueAssigneesRemove(transport, input),
5743
6077
  setIssueMilestone: async (input) => (await loadIssueMutations()).runIssueMilestoneSet(transport, input),
6078
+ clearIssueMilestone: async (input) => (await loadIssueMutations()).runIssueMilestoneClear(transport, input),
5744
6079
  createIssueComment: async (input) => (await loadIssueMutations()).runIssueCommentCreate(transport, input),
5745
6080
  fetchIssueLinkedPrs: async (input) => (await loadIssueMutations()).runIssueLinkedPrsList(transport, input),
5746
6081
  fetchIssueRelations: async (input) => (await loadIssueMutations()).runIssueRelationsGet(transport, input),
@@ -5757,7 +6092,25 @@ function createGithubClient(transport) {
5757
6092
  replyToReviewThread: async (input) => (await loadPrMutations()).runReplyToReviewThread(transport, input),
5758
6093
  resolveReviewThread: async (input) => (await loadPrMutations()).runResolveReviewThread(transport, input),
5759
6094
  unresolveReviewThread: async (input) => (await loadPrMutations()).runUnresolveReviewThread(transport, input),
5760
- submitPrReview: async (input) => (await loadPrMutations()).runSubmitPrReview(transport, input)
6095
+ submitPrReview: async (input) => (await loadPrMutations()).runSubmitPrReview(transport, input),
6096
+ fetchRepoLabelsList: async (input) => (await loadRepo()).runRepoLabelsList(transport, input),
6097
+ fetchRepoIssueTypesList: async (input) => (await loadRepo()).runRepoIssueTypesList(transport, input),
6098
+ fetchReleaseView: async (input) => (await loadRelease()).runReleaseView(transport, input),
6099
+ fetchReleaseList: async (input) => (await loadRelease()).runReleaseList(transport, input),
6100
+ fetchProjectV2OrgView: async (input) => (await loadProject()).runProjectV2OrgView(transport, input),
6101
+ fetchProjectV2UserView: async (input) => (await loadProject()).runProjectV2UserView(transport, input),
6102
+ fetchProjectV2FieldsList: async (input) => (await loadProject()).runProjectV2FieldsList(transport, input),
6103
+ fetchProjectV2ItemsList: async (input) => (await loadProject()).runProjectV2ItemsList(transport, input),
6104
+ createPr: async (input) => (await loadPrMutations()).runPrCreate(transport, input),
6105
+ updatePr: async (input) => (await loadPrMutations()).runPrUpdate(transport, input),
6106
+ mergePr: async (input) => (await loadPrMutations()).runPrMerge(transport, input),
6107
+ updatePrBranch: async (input) => (await loadPrMutations()).runPrBranchUpdate(transport, input),
6108
+ addPrAssignees: async (input) => (await loadPrMutations()).runPrAssigneesAdd(transport, input),
6109
+ removePrAssignees: async (input) => (await loadPrMutations()).runPrAssigneesRemove(transport, input),
6110
+ requestPrReviews: async (input) => (await loadPrMutations()).runPrReviewsRequest(transport, input),
6111
+ addProjectV2Item: async (input) => (await loadProject()).runProjectV2ItemAdd(transport, input),
6112
+ removeProjectV2Item: async (input) => (await loadProject()).runProjectV2ItemRemove(transport, input),
6113
+ updateProjectV2ItemField: async (input) => (await loadProject()).runProjectV2ItemFieldUpdate(transport, input)
5761
6114
  };
5762
6115
  }
5763
6116
 
@@ -5776,4 +6129,4 @@ export {
5776
6129
  createGithubClientFromToken,
5777
6130
  createGithubClient
5778
6131
  };
5779
- //# sourceMappingURL=chunk-3P3KHWFU.js.map
6132
+ //# sourceMappingURL=chunk-T3L2VDOS.js.map