@bluewombat/manager-github 0.1.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 (155) hide show
  1. package/README.md +162 -0
  2. package/SPECS.md +126 -0
  3. package/dist/adapter/github/fetch-issue.d.ts +29 -0
  4. package/dist/adapter/github/fetch-issue.d.ts.map +1 -0
  5. package/dist/adapter/github/fetch-issue.js +34 -0
  6. package/dist/adapter/github/fetch-issue.js.map +1 -0
  7. package/dist/adapter/normalize/body.d.ts +24 -0
  8. package/dist/adapter/normalize/body.d.ts.map +1 -0
  9. package/dist/adapter/normalize/body.js +104 -0
  10. package/dist/adapter/normalize/body.js.map +1 -0
  11. package/dist/adapter/normalize/fingerprint.d.ts +8 -0
  12. package/dist/adapter/normalize/fingerprint.d.ts.map +1 -0
  13. package/dist/adapter/normalize/fingerprint.js +26 -0
  14. package/dist/adapter/normalize/fingerprint.js.map +1 -0
  15. package/dist/adapter/normalize/intent.d.ts +27 -0
  16. package/dist/adapter/normalize/intent.d.ts.map +1 -0
  17. package/dist/adapter/normalize/intent.js +57 -0
  18. package/dist/adapter/normalize/intent.js.map +1 -0
  19. package/dist/adapter/normalize/labels.d.ts +17 -0
  20. package/dist/adapter/normalize/labels.d.ts.map +1 -0
  21. package/dist/adapter/normalize/labels.js +43 -0
  22. package/dist/adapter/normalize/labels.js.map +1 -0
  23. package/dist/adapter/normalize/noise.d.ts +13 -0
  24. package/dist/adapter/normalize/noise.d.ts.map +1 -0
  25. package/dist/adapter/normalize/noise.js +28 -0
  26. package/dist/adapter/normalize/noise.js.map +1 -0
  27. package/dist/adapter/normalize/normalize.d.ts +22 -0
  28. package/dist/adapter/normalize/normalize.d.ts.map +1 -0
  29. package/dist/adapter/normalize/normalize.js +216 -0
  30. package/dist/adapter/normalize/normalize.js.map +1 -0
  31. package/dist/adapter/progress/emit.d.ts +3 -0
  32. package/dist/adapter/progress/emit.d.ts.map +1 -0
  33. package/dist/adapter/progress/emit.js +6 -0
  34. package/dist/adapter/progress/emit.js.map +1 -0
  35. package/dist/adapter/raw/parse-raw.d.ts +14 -0
  36. package/dist/adapter/raw/parse-raw.d.ts.map +1 -0
  37. package/dist/adapter/raw/parse-raw.js +47 -0
  38. package/dist/adapter/raw/parse-raw.js.map +1 -0
  39. package/dist/adapter/raw/unwrap.d.ts +12 -0
  40. package/dist/adapter/raw/unwrap.d.ts.map +1 -0
  41. package/dist/adapter/raw/unwrap.js +19 -0
  42. package/dist/adapter/raw/unwrap.js.map +1 -0
  43. package/dist/adapter/run/run-adapter.d.ts +28 -0
  44. package/dist/adapter/run/run-adapter.d.ts.map +1 -0
  45. package/dist/adapter/run/run-adapter.js +131 -0
  46. package/dist/adapter/run/run-adapter.js.map +1 -0
  47. package/dist/adapter/types.d.ts +69 -0
  48. package/dist/adapter/types.d.ts.map +1 -0
  49. package/dist/adapter/types.js +3 -0
  50. package/dist/adapter/types.js.map +1 -0
  51. package/dist/emitter/event/field-matrix.d.ts +29 -0
  52. package/dist/emitter/event/field-matrix.d.ts.map +1 -0
  53. package/dist/emitter/event/field-matrix.js +94 -0
  54. package/dist/emitter/event/field-matrix.js.map +1 -0
  55. package/dist/emitter/github/comments.d.ts +14 -0
  56. package/dist/emitter/github/comments.d.ts.map +1 -0
  57. package/dist/emitter/github/comments.js +69 -0
  58. package/dist/emitter/github/comments.js.map +1 -0
  59. package/dist/emitter/github/labels.d.ts +18 -0
  60. package/dist/emitter/github/labels.d.ts.map +1 -0
  61. package/dist/emitter/github/labels.js +81 -0
  62. package/dist/emitter/github/labels.js.map +1 -0
  63. package/dist/emitter/github/result.d.ts +19 -0
  64. package/dist/emitter/github/result.d.ts.map +1 -0
  65. package/dist/emitter/github/result.js +2 -0
  66. package/dist/emitter/github/result.js.map +1 -0
  67. package/dist/emitter/progress/emit.d.ts +3 -0
  68. package/dist/emitter/progress/emit.d.ts.map +1 -0
  69. package/dist/emitter/progress/emit.js +6 -0
  70. package/dist/emitter/progress/emit.js.map +1 -0
  71. package/dist/emitter/render/render-event.d.ts +20 -0
  72. package/dist/emitter/render/render-event.d.ts.map +1 -0
  73. package/dist/emitter/render/render-event.js +293 -0
  74. package/dist/emitter/render/render-event.js.map +1 -0
  75. package/dist/emitter/render/truncate.d.ts +9 -0
  76. package/dist/emitter/render/truncate.d.ts.map +1 -0
  77. package/dist/emitter/render/truncate.js +10 -0
  78. package/dist/emitter/render/truncate.js.map +1 -0
  79. package/dist/emitter/run/run-emitter.d.ts +27 -0
  80. package/dist/emitter/run/run-emitter.d.ts.map +1 -0
  81. package/dist/emitter/run/run-emitter.js +121 -0
  82. package/dist/emitter/run/run-emitter.js.map +1 -0
  83. package/dist/emitter/thread/marker.d.ts +15 -0
  84. package/dist/emitter/thread/marker.d.ts.map +1 -0
  85. package/dist/emitter/thread/marker.js +37 -0
  86. package/dist/emitter/thread/marker.js.map +1 -0
  87. package/dist/emitter/types.d.ts +64 -0
  88. package/dist/emitter/types.d.ts.map +1 -0
  89. package/dist/emitter/types.js +3 -0
  90. package/dist/emitter/types.js.map +1 -0
  91. package/dist/github/client.d.ts +63 -0
  92. package/dist/github/client.d.ts.map +1 -0
  93. package/dist/github/client.js +96 -0
  94. package/dist/github/client.js.map +1 -0
  95. package/dist/index.d.ts +55 -0
  96. package/dist/index.d.ts.map +1 -0
  97. package/dist/index.js +357 -0
  98. package/dist/index.js.map +1 -0
  99. package/dist/issue-number.d.ts +5 -0
  100. package/dist/issue-number.d.ts.map +1 -0
  101. package/dist/issue-number.js +32 -0
  102. package/dist/issue-number.js.map +1 -0
  103. package/dist/labels.d.ts +3 -0
  104. package/dist/labels.d.ts.map +1 -0
  105. package/dist/labels.js +24 -0
  106. package/dist/labels.js.map +1 -0
  107. package/dist/listener/delivery/run-hook.d.ts +8 -0
  108. package/dist/listener/delivery/run-hook.d.ts.map +1 -0
  109. package/dist/listener/delivery/run-hook.js +50 -0
  110. package/dist/listener/delivery/run-hook.js.map +1 -0
  111. package/dist/listener/github/list-issues.d.ts +30 -0
  112. package/dist/listener/github/list-issues.d.ts.map +1 -0
  113. package/dist/listener/github/list-issues.js +36 -0
  114. package/dist/listener/github/list-issues.js.map +1 -0
  115. package/dist/listener/progress/emit.d.ts +3 -0
  116. package/dist/listener/progress/emit.d.ts.map +1 -0
  117. package/dist/listener/progress/emit.js +6 -0
  118. package/dist/listener/progress/emit.js.map +1 -0
  119. package/dist/listener/run/run-listener.d.ts +35 -0
  120. package/dist/listener/run/run-listener.d.ts.map +1 -0
  121. package/dist/listener/run/run-listener.js +217 -0
  122. package/dist/listener/run/run-listener.js.map +1 -0
  123. package/dist/listener/source/select-events.d.ts +46 -0
  124. package/dist/listener/source/select-events.d.ts.map +1 -0
  125. package/dist/listener/source/select-events.js +102 -0
  126. package/dist/listener/source/select-events.js.map +1 -0
  127. package/dist/listener/types.d.ts +56 -0
  128. package/dist/listener/types.d.ts.map +1 -0
  129. package/dist/listener/types.js +3 -0
  130. package/dist/listener/types.js.map +1 -0
  131. package/dist/manager.d.ts +29 -0
  132. package/dist/manager.d.ts.map +1 -0
  133. package/dist/manager.js +256 -0
  134. package/dist/manager.js.map +1 -0
  135. package/dist/probe/probe-issue.d.ts +20 -0
  136. package/dist/probe/probe-issue.d.ts.map +1 -0
  137. package/dist/probe/probe-issue.js +45 -0
  138. package/dist/probe/probe-issue.js.map +1 -0
  139. package/dist/repo.d.ts +6 -0
  140. package/dist/repo.d.ts.map +1 -0
  141. package/dist/repo.js +14 -0
  142. package/dist/repo.js.map +1 -0
  143. package/dist/setup.d.ts +43 -0
  144. package/dist/setup.d.ts.map +1 -0
  145. package/dist/setup.js +281 -0
  146. package/dist/setup.js.map +1 -0
  147. package/dist/submission/submission.d.ts +44 -0
  148. package/dist/submission/submission.d.ts.map +1 -0
  149. package/dist/submission/submission.js +189 -0
  150. package/dist/submission/submission.js.map +1 -0
  151. package/dist/written-fingerprint.d.ts +7 -0
  152. package/dist/written-fingerprint.d.ts.map +1 -0
  153. package/dist/written-fingerprint.js +38 -0
  154. package/dist/written-fingerprint.js.map +1 -0
  155. package/package.json +51 -0
@@ -0,0 +1,17 @@
1
+ import type { Invalid } from "../types.js";
2
+ export type LabelsResult = {
3
+ ok: true;
4
+ names: string[];
5
+ } | {
6
+ ok: false;
7
+ invalid: Invalid;
8
+ };
9
+ /**
10
+ * The label names of an issue. GitHub writes them as objects; a caller building
11
+ * a raw intention by hand writes them as strings. Both are read.
12
+ */
13
+ export declare function readLabels(issue: Record<string, unknown>): LabelsResult;
14
+ /** What the labels carrying this prefix say, with the prefix removed. */
15
+ export declare function valuesWithPrefix(names: string[], prefix: string): string[];
16
+ export declare function hasLabel(names: string[], label: string): boolean;
17
+ //# sourceMappingURL=labels.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"labels.d.ts","sourceRoot":"","sources":["../../../src/adapter/normalize/labels.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,MAAM,YAAY,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC;AAE3F;;;GAGG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,YAAY,CAyBvE;AAMD,yEAAyE;AACzE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAK1E;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAEhE"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * The label names of an issue. GitHub writes them as objects; a caller building
3
+ * a raw intention by hand writes them as strings. Both are read.
4
+ */
5
+ export function readLabels(issue) {
6
+ const value = issue.labels;
7
+ if (value === undefined || value === null) {
8
+ return { ok: true, names: [] };
9
+ }
10
+ if (!Array.isArray(value)) {
11
+ return { ok: false, invalid: badLabels('Field "labels" is not an array.') };
12
+ }
13
+ const names = [];
14
+ for (const entry of value) {
15
+ if (typeof entry === "string") {
16
+ names.push(entry.trim());
17
+ continue;
18
+ }
19
+ if (entry !== null && typeof entry === "object" && !Array.isArray(entry)) {
20
+ const name = entry.name;
21
+ if (typeof name === "string") {
22
+ names.push(name.trim());
23
+ continue;
24
+ }
25
+ }
26
+ return { ok: false, invalid: badLabels('An entry of "labels" carries no name.') };
27
+ }
28
+ return { ok: true, names: names.filter((name) => name.length > 0) };
29
+ }
30
+ function badLabels(reason) {
31
+ return { code: "bad-field-type", reason };
32
+ }
33
+ /** What the labels carrying this prefix say, with the prefix removed. */
34
+ export function valuesWithPrefix(names, prefix) {
35
+ return names
36
+ .filter((name) => name.toLowerCase().startsWith(prefix.toLowerCase()))
37
+ .map((name) => name.slice(prefix.length).trim())
38
+ .filter((value) => value.length > 0);
39
+ }
40
+ export function hasLabel(names, label) {
41
+ return names.some((name) => name.toLowerCase() === label.toLowerCase());
42
+ }
43
+ //# sourceMappingURL=labels.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"labels.js","sourceRoot":"","sources":["../../../src/adapter/normalize/labels.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,KAA8B;IACvD,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC;IAC3B,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAC1C,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IACjC,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,CAAC,iCAAiC,CAAC,EAAE,CAAC;IAC9E,CAAC;IAED,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE,CAAC;QAC1B,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;YACzB,SAAS;QACX,CAAC;QACD,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACzE,MAAM,IAAI,GAAI,KAA4B,CAAC,IAAI,CAAC;YAChD,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC7B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;gBACxB,SAAS;YACX,CAAC;QACH,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,CAAC,uCAAuC,CAAC,EAAE,CAAC;IACpF,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC;AACtE,CAAC;AAED,SAAS,SAAS,CAAC,MAAc;IAC/B,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,CAAC;AAC5C,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,gBAAgB,CAAC,KAAe,EAAE,MAAc;IAC9D,OAAO,KAAK;SACT,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;SACrE,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;SAC/C,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,KAAe,EAAE,KAAa;IACrD,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;AAC1E,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * What the tracker put on an issue body that the human did not write.
3
+ * Pure: no clock, no request, no file.
4
+ *
5
+ * The body is the intention verbatim, and its fingerprint is what tells an
6
+ * edit from an echo. Two things GitHub itself puts there would otherwise pass
7
+ * for an edit: the comments an issue template leaves behind, and the boxes of
8
+ * a task list — a human ticking one is the most ordinary gesture on the page,
9
+ * and it is not a change of mind. Both leave; the words stay. Nothing here
10
+ * reads the words: no criteria, no headings, no meaning.
11
+ */
12
+ export declare function stripTrackerNoise(body: string): string;
13
+ //# sourceMappingURL=noise.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"noise.d.ts","sourceRoot":"","sources":["../../../src/adapter/normalize/noise.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAYtD"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * What the tracker put on an issue body that the human did not write.
3
+ * Pure: no clock, no request, no file.
4
+ *
5
+ * The body is the intention verbatim, and its fingerprint is what tells an
6
+ * edit from an echo. Two things GitHub itself puts there would otherwise pass
7
+ * for an edit: the comments an issue template leaves behind, and the boxes of
8
+ * a task list — a human ticking one is the most ordinary gesture on the page,
9
+ * and it is not a change of mind. Both leave; the words stay. Nothing here
10
+ * reads the words: no criteria, no headings, no meaning.
11
+ */
12
+ const HTML_COMMENT = /<!--[\s\S]*?-->/g;
13
+ /** A list item that opens with a box: the bullet and the words are kept, the box is not. */
14
+ const TASK_BOX = /^(\s*(?:[-*+]|\d+[.)])\s+)\[[ xX]\](?:\s+|$)/;
15
+ export function stripTrackerNoise(body) {
16
+ const lines = body
17
+ .replace(HTML_COMMENT, "")
18
+ .replace(/\r\n?/g, "\n")
19
+ .split("\n")
20
+ .map((line) => line.replace(TASK_BOX, "$1").trimEnd())
21
+ // A box with nothing after it was a line the human never filled in.
22
+ .filter((line) => !/^\s*(?:[-*+]|\d+[.)])$/.test(line));
23
+ return lines
24
+ .join("\n")
25
+ .replace(/\n{3,}/g, "\n\n")
26
+ .trim();
27
+ }
28
+ //# sourceMappingURL=noise.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"noise.js","sourceRoot":"","sources":["../../../src/adapter/normalize/noise.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,YAAY,GAAG,kBAAkB,CAAC;AACxC,4FAA4F;AAC5F,MAAM,QAAQ,GAAG,8CAA8C,CAAC;AAEhE,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,MAAM,KAAK,GAAG,IAAI;SACf,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC;SACzB,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC;SACvB,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;QACtD,oEAAoE;SACnE,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,wBAAwB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1D,OAAO,KAAK;SACT,IAAI,CAAC,IAAI,CAAC;SACV,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC;SAC1B,IAAI,EAAE,CAAC;AACZ,CAAC"}
@@ -0,0 +1,22 @@
1
+ import type { Unwrapped } from "../raw/unwrap.js";
2
+ import type { NormalizeResult, Repository } from "../types.js";
3
+ export type NormalizeOptions = {
4
+ manager: string;
5
+ repo: Repository;
6
+ defaultProject?: string;
7
+ defaultPriority: number;
8
+ projectLabelPrefix: string;
9
+ priorityLabelPrefix: string;
10
+ readyLabel: string;
11
+ normalizedAt: string;
12
+ };
13
+ /**
14
+ * Turn one issue into a FeatureStandard, or say why it cannot be one. Pure: no
15
+ * clock, no request, no file.
16
+ *
17
+ * Checks run in a fixed order — the pull-request refusal, then every recognised
18
+ * field's type, then the action, then the fields the intent requires, then the
19
+ * priority scale — so one raw intention always produces the same code.
20
+ */
21
+ export declare function normalize(raw: Unwrapped, options: NormalizeOptions): NormalizeResult;
22
+ //# sourceMappingURL=normalize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../../src/adapter/normalize/normalize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAA4B,eAAe,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAMzF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,UAAU,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAgGF;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,gBAAgB,GAAG,eAAe,CAmIpF"}
@@ -0,0 +1,216 @@
1
+ import { fingerprintOf } from "./fingerprint.js";
2
+ import { readIntent } from "./intent.js";
3
+ import { readLabels, valuesWithPrefix } from "./labels.js";
4
+ import { stripTrackerNoise } from "./noise.js";
5
+ const PRIORITY_NAMES = {
6
+ low: 25,
7
+ normal: 50,
8
+ high: 75,
9
+ urgent: 100,
10
+ };
11
+ function badType(field, value) {
12
+ return {
13
+ code: "bad-field-type",
14
+ reason: `Field "${field}" is ${describe(value)}, which this Block cannot read.`,
15
+ };
16
+ }
17
+ function describe(value) {
18
+ if (value === null) {
19
+ return "null";
20
+ }
21
+ if (Array.isArray(value)) {
22
+ return "an array";
23
+ }
24
+ return `a ${typeof value}`;
25
+ }
26
+ function readString(issue, field) {
27
+ const value = issue[field];
28
+ if (value === undefined || value === null) {
29
+ return { ok: true };
30
+ }
31
+ if (typeof value !== "string") {
32
+ return { ok: false, invalid: badType(field, value) };
33
+ }
34
+ const trimmed = value.trim();
35
+ return trimmed.length === 0 ? { ok: true } : { ok: true, value: trimmed };
36
+ }
37
+ /** The issue number, as GitHub writes it or as a caller typed it. */
38
+ function readNumber(issue) {
39
+ const value = issue.number;
40
+ if (value === undefined || value === null) {
41
+ return { ok: true };
42
+ }
43
+ if (typeof value === "number") {
44
+ if (!Number.isInteger(value) || value < 1) {
45
+ return { ok: false, invalid: badType("number", value) };
46
+ }
47
+ return { ok: true, value };
48
+ }
49
+ if (typeof value === "string" && /^\d+$/.test(value.trim())) {
50
+ return { ok: true, value: Number(value.trim()) };
51
+ }
52
+ return { ok: false, invalid: badType("number", value) };
53
+ }
54
+ function readPriority(values, prefix) {
55
+ if (values.length === 0) {
56
+ return { ok: true };
57
+ }
58
+ if (values.length > 1) {
59
+ return {
60
+ ok: false,
61
+ invalid: {
62
+ code: "bad-priority",
63
+ reason: `The issue carries ${values.length} "${prefix}" labels: ${values.join(", ")}.`,
64
+ },
65
+ };
66
+ }
67
+ const raw = values[0] ?? "";
68
+ const named = PRIORITY_NAMES[raw.toLowerCase()];
69
+ if (named !== undefined) {
70
+ return { ok: true, value: named };
71
+ }
72
+ if (/^\d+$/.test(raw)) {
73
+ const value = Number(raw);
74
+ if (value >= 0 && value <= 100) {
75
+ return { ok: true, value };
76
+ }
77
+ return {
78
+ ok: false,
79
+ invalid: { code: "bad-priority", reason: `Priority ${value} is outside the 0…100 scale.` },
80
+ };
81
+ }
82
+ return {
83
+ ok: false,
84
+ invalid: {
85
+ code: "bad-priority",
86
+ reason: `Priority "${raw}" is not one of low, normal, high, urgent, or 0…100.`,
87
+ },
88
+ };
89
+ }
90
+ /**
91
+ * Turn one issue into a FeatureStandard, or say why it cannot be one. Pure: no
92
+ * clock, no request, no file.
93
+ *
94
+ * Checks run in a fixed order — the pull-request refusal, then every recognised
95
+ * field's type, then the action, then the fields the intent requires, then the
96
+ * priority scale — so one raw intention always produces the same code.
97
+ */
98
+ export function normalize(raw, options) {
99
+ const { issue } = raw;
100
+ if (issue.pull_request !== undefined && issue.pull_request !== null) {
101
+ return {
102
+ ok: false,
103
+ invalid: {
104
+ code: "not-an-issue",
105
+ reason: "The raw intention is a pull request; only the issue tracker is read here.",
106
+ },
107
+ };
108
+ }
109
+ const number = readNumber(issue);
110
+ if (!number.ok) {
111
+ return { ok: false, invalid: number.invalid };
112
+ }
113
+ const title = readString(issue, "title");
114
+ if (!title.ok) {
115
+ return { ok: false, invalid: title.invalid };
116
+ }
117
+ const body = readString(issue, "body");
118
+ if (!body.ok) {
119
+ return { ok: false, invalid: body.invalid };
120
+ }
121
+ const state = readString(issue, "state");
122
+ if (!state.ok) {
123
+ return { ok: false, invalid: state.invalid };
124
+ }
125
+ const ref = readString(issue, "html_url");
126
+ if (!ref.ok) {
127
+ return { ok: false, invalid: ref.invalid };
128
+ }
129
+ const revision = readString(issue, "updated_at");
130
+ if (!revision.ok) {
131
+ return { ok: false, invalid: revision.invalid };
132
+ }
133
+ const labels = readLabels(issue);
134
+ if (!labels.ok) {
135
+ return { ok: false, invalid: labels.invalid };
136
+ }
137
+ const intent = readIntent({
138
+ action: raw.action,
139
+ state: state.value,
140
+ labels: labels.names,
141
+ readyLabel: options.readyLabel,
142
+ });
143
+ if (!intent.ok) {
144
+ return { ok: false, invalid: intent.invalid };
145
+ }
146
+ if (number.value === undefined) {
147
+ return {
148
+ ok: false,
149
+ invalid: { code: "missing-id", reason: 'The raw intention carries no issue "number".' },
150
+ };
151
+ }
152
+ const projects = valuesWithPrefix(labels.names, options.projectLabelPrefix);
153
+ if (projects.length > 1) {
154
+ return {
155
+ ok: false,
156
+ invalid: {
157
+ code: "ambiguous-project",
158
+ reason: `The issue carries ${projects.length} "${options.projectLabelPrefix}" labels: ${projects.join(", ")}.`,
159
+ },
160
+ };
161
+ }
162
+ const project = projects[0] ?? options.defaultProject;
163
+ if (project === undefined) {
164
+ return {
165
+ ok: false,
166
+ invalid: {
167
+ code: "missing-project",
168
+ reason: `No "${options.projectLabelPrefix}" label on the issue and no --default-project.`,
169
+ },
170
+ };
171
+ }
172
+ // The body as the human wrote it, less what the tracker put there: a
173
+ // template's comments and a task list's boxes are not an intention, and
174
+ // ticking a box must not read as an edit. A body that was only that falls
175
+ // back to the title, like no body at all.
176
+ const written = body.value === undefined ? undefined : stripTrackerNoise(body.value);
177
+ const intention = written === undefined || written.length === 0 ? title.value : written;
178
+ if (intent.intent === "upsert" && intention === undefined) {
179
+ return {
180
+ ok: false,
181
+ invalid: {
182
+ code: "missing-intention",
183
+ reason: 'An upsert needs a body or, failing that, a "title".',
184
+ },
185
+ };
186
+ }
187
+ const priority = readPriority(valuesWithPrefix(labels.names, options.priorityLabelPrefix), options.priorityLabelPrefix);
188
+ if (!priority.ok) {
189
+ return { ok: false, invalid: priority.invalid };
190
+ }
191
+ const source = {};
192
+ if (ref.value !== undefined) {
193
+ source.ref = ref.value;
194
+ }
195
+ if (revision.value !== undefined) {
196
+ source.revision = revision.value;
197
+ }
198
+ const externalId = `${options.repo.owner}/${options.repo.name}#${number.value}`;
199
+ // Built in the order the FeatureStandard documents, so stdout reads top-down.
200
+ const feature = {
201
+ key: `${options.manager}:${externalId}`,
202
+ manager: options.manager,
203
+ external_id: externalId,
204
+ intent: intent.intent,
205
+ project,
206
+ ...(title.value !== undefined ? { title: title.value } : {}),
207
+ ...(intention !== undefined ? { intention } : {}),
208
+ priority: priority.value ?? options.defaultPriority,
209
+ ...(Object.keys(source).length > 0 ? { source } : {}),
210
+ fingerprint: "",
211
+ normalized_at: options.normalizedAt,
212
+ };
213
+ feature.fingerprint = fingerprintOf(feature);
214
+ return { ok: true, feature };
215
+ }
216
+ //# sourceMappingURL=normalize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize.js","sourceRoot":"","sources":["../../../src/adapter/normalize/normalize.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export type ProgressWriter = (line: Record<string, unknown>) => void;
2
+ export declare function createStdoutProgressWriter(): ProgressWriter;
3
+ //# sourceMappingURL=emit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit.d.ts","sourceRoot":"","sources":["../../../src/adapter/progress/emit.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;AAErE,wBAAgB,0BAA0B,IAAI,cAAc,CAI3D"}
@@ -0,0 +1,6 @@
1
+ export function createStdoutProgressWriter() {
2
+ return (line) => {
3
+ process.stdout.write(`${JSON.stringify(line)}\n`);
4
+ };
5
+ }
6
+ //# sourceMappingURL=emit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit.js","sourceRoot":"","sources":["../../../src/adapter/progress/emit.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,0BAA0B;IACxC,OAAO,CAAC,IAAI,EAAE,EAAE;QACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpD,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { Invalid } from "../types.js";
2
+ export type ParseRawResult = {
3
+ ok: true;
4
+ object: Record<string, unknown>;
5
+ } | {
6
+ ok: false;
7
+ invalid: Invalid;
8
+ };
9
+ /**
10
+ * Structural checks on the raw intention: size, then JSON, then object.
11
+ * Nothing here looks at a field — that is normalization's job.
12
+ */
13
+ export declare function parseRaw(raw: string, maxRawBytes: number): ParseRawResult;
14
+ //# sourceMappingURL=parse-raw.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-raw.d.ts","sourceRoot":"","sources":["../../../src/adapter/raw/parse-raw.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,MAAM,cAAc,GACtB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAC7C;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC;AAEpC;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,cAAc,CAkCzE"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Structural checks on the raw intention: size, then JSON, then object.
3
+ * Nothing here looks at a field — that is normalization's job.
4
+ */
5
+ export function parseRaw(raw, maxRawBytes) {
6
+ const bytes = Buffer.byteLength(raw, "utf8");
7
+ if (bytes > maxRawBytes) {
8
+ return {
9
+ ok: false,
10
+ invalid: {
11
+ code: "raw-too-large",
12
+ reason: `The raw intention is ${bytes} bytes, over the ${maxRawBytes} allowed.`,
13
+ },
14
+ };
15
+ }
16
+ let parsed;
17
+ try {
18
+ parsed = JSON.parse(raw);
19
+ }
20
+ catch (error) {
21
+ const detail = error instanceof Error ? error.message : String(error);
22
+ return {
23
+ ok: false,
24
+ invalid: { code: "raw-not-json", reason: `The raw intention is not JSON: ${detail}` },
25
+ };
26
+ }
27
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
28
+ return {
29
+ ok: false,
30
+ invalid: {
31
+ code: "raw-not-object",
32
+ reason: `The raw intention parsed to ${describe(parsed)}, not an object.`,
33
+ },
34
+ };
35
+ }
36
+ return { ok: true, object: parsed };
37
+ }
38
+ function describe(value) {
39
+ if (value === null) {
40
+ return "null";
41
+ }
42
+ if (Array.isArray(value)) {
43
+ return "an array";
44
+ }
45
+ return `a ${typeof value}`;
46
+ }
47
+ //# sourceMappingURL=parse-raw.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-raw.js","sourceRoot":"","sources":["../../../src/adapter/raw/parse-raw.ts"],"names":[],"mappings":"AAMA;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,GAAW,EAAE,WAAmB;IACvD,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC7C,IAAI,KAAK,GAAG,WAAW,EAAE,CAAC;QACxB,OAAO;YACL,EAAE,EAAE,KAAK;YACT,OAAO,EAAE;gBACP,IAAI,EAAE,eAAe;gBACrB,MAAM,EAAE,wBAAwB,KAAK,oBAAoB,WAAW,WAAW;aAChF;SACF,CAAC;IACJ,CAAC;IAED,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,MAAM,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACtE,OAAO;YACL,EAAE,EAAE,KAAK;YACT,OAAO,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,kCAAkC,MAAM,EAAE,EAAE;SACtF,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3E,OAAO;YACL,EAAE,EAAE,KAAK;YACT,OAAO,EAAE;gBACP,IAAI,EAAE,gBAAgB;gBACtB,MAAM,EAAE,+BAA+B,QAAQ,CAAC,MAAM,CAAC,kBAAkB;aAC1E;SACF,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,MAAiC,EAAE,CAAC;AACjE,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,UAAU,CAAC;IACpB,CAAC;IACD,OAAO,KAAK,OAAO,KAAK,EAAE,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * A raw intention arrives in one of two shapes: the issue GitHub listed, or the
3
+ * envelope GitHub sends about an issue (`{ "action": …, "issue": { … } }`).
4
+ * Both are read, so a subscription and a webhook relay feed the same Block.
5
+ */
6
+ export type Unwrapped = {
7
+ issue: Record<string, unknown>;
8
+ /** What just happened to the issue; absent when the raw intention is a snapshot. */
9
+ action?: string;
10
+ };
11
+ export declare function unwrapIssue(raw: Record<string, unknown>): Unwrapped;
12
+ //# sourceMappingURL=unwrap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unwrap.d.ts","sourceRoot":"","sources":["../../../src/adapter/raw/unwrap.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,oFAAoF;IACpF,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAanE"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * A raw intention arrives in one of two shapes: the issue GitHub listed, or the
3
+ * envelope GitHub sends about an issue (`{ "action": …, "issue": { … } }`).
4
+ * Both are read, so a subscription and a webhook relay feed the same Block.
5
+ */
6
+ export function unwrapIssue(raw) {
7
+ const inner = raw.issue;
8
+ const issue = inner !== null && typeof inner === "object" && !Array.isArray(inner)
9
+ ? inner
10
+ : raw;
11
+ const action = raw.action;
12
+ return {
13
+ issue,
14
+ ...(typeof action === "string" && action.trim().length > 0
15
+ ? { action: action.trim().toLowerCase() }
16
+ : {}),
17
+ };
18
+ }
19
+ //# sourceMappingURL=unwrap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unwrap.js","sourceRoot":"","sources":["../../../src/adapter/raw/unwrap.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,MAAM,UAAU,WAAW,CAAC,GAA4B;IACtD,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;IACxB,MAAM,KAAK,GACT,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAClE,CAAC,CAAE,KAAiC;QACpC,CAAC,CAAC,GAAG,CAAC;IACV,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;IAC1B,OAAO;QACL,KAAK;QACL,GAAG,CAAC,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;YACxD,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE;YACzC,CAAC,CAAC,EAAE,CAAC;KACR,CAAC;AACJ,CAAC"}
@@ -0,0 +1,28 @@
1
+ import type { GithubClient } from "../../github/client.js";
2
+ import type { ProgressWriter } from "../progress/emit.js";
3
+ import type { FeatureStandard, Invalid, Invocation, RunOutcome } from "../types.js";
4
+ export type RunResult = {
5
+ outcome: RunOutcome;
6
+ feature?: FeatureStandard;
7
+ invalid?: Invalid;
8
+ detail?: string;
9
+ exitCode: number;
10
+ };
11
+ export type RunOptions = {
12
+ invocation: Invocation;
13
+ /** The raw intention; the CLI reads it from --raw or stdin. */
14
+ raw: string;
15
+ /** The authenticated channel a Fetch uses. Required only with `fetch`. */
16
+ github?: GithubClient;
17
+ write?: ProgressWriter;
18
+ now?: () => number;
19
+ interruptFlag?: {
20
+ interrupted: boolean;
21
+ };
22
+ };
23
+ export declare function invalidInvocationResult(write: ProgressWriter, reason: string): RunResult;
24
+ /**
25
+ * Run one FeatureAdapter invocation to a run outcome.
26
+ */
27
+ export declare function runAdapter(options: RunOptions): Promise<RunResult>;
28
+ //# sourceMappingURL=run-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-adapter.d.ts","sourceRoot":"","sources":["../../../src/adapter/run/run-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAG3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAG1D,OAAO,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEpF,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EAAE,UAAU,CAAC;IACpB,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,UAAU,EAAE,UAAU,CAAC;IACvB,+DAA+D;IAC/D,GAAG,EAAE,MAAM,CAAC;IACZ,0EAA0E;IAC1E,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE;QAAE,WAAW,EAAE,OAAO,CAAA;KAAE,CAAC;CAC1C,CAAC;AAiBF,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,CAOxF;AAcD;;GAEG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CAoGxE"}