@bluewombat/manager-github 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bluewombat/manager-github",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "type": "module",
5
5
  "description": "GitHub Issues FeatureManager: issues in, comments and labels out; pull requests as Authority.",
6
6
  "keywords": [
@@ -43,9 +43,9 @@
43
43
  "build": "tsc -p tsconfig.build.json"
44
44
  },
45
45
  "dependencies": {
46
- "@bluewombat/manager-kit": "^0.1.0",
46
+ "@bluewombat/manager-kit": "^0.1.1",
47
47
  "@octokit/core": "^7.0.8",
48
48
  "@octokit/plugin-retry": "^8.1.1",
49
49
  "@octokit/plugin-throttling": "^11.0.5"
50
50
  }
51
- }
51
+ }
@@ -1,24 +0,0 @@
1
- /**
2
- * Reading an issue body. Pure: no clock, no request, no file.
3
- *
4
- * A body is free text a human wrote in a web form. Two shapes are recognised —
5
- * a task list, and an acceptance section — because those are the two shapes
6
- * GitHub itself renders as a checklist. Everything else stays intention text.
7
- */
8
- export type BodyParts = {
9
- /** The free text left once the criteria were taken out; absent when empty. */
10
- intention?: string;
11
- criteria: string[];
12
- };
13
- /** Comments an issue template left behind are not something a human wrote. */
14
- export declare function stripComments(body: string): string;
15
- /**
16
- * Split a body into the intention and its acceptance criteria.
17
- *
18
- * Task-list items win wherever they are: `- [ ] …` is the checklist GitHub
19
- * renders, and a human who wrote one meant it. Without any, a section titled
20
- * "acceptance criteria" (or "definition of done") is read instead, and the whole
21
- * section leaves the intention.
22
- */
23
- export declare function readBody(body: string): BodyParts;
24
- //# sourceMappingURL=body.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"body.d.ts","sourceRoot":"","sources":["../../../src/adapter/normalize/body.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,MAAM,MAAM,SAAS,GAAG;IACtB,8EAA8E;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB,CAAC;AAEF,8EAA8E;AAC9E,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AAcD;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAkChD"}
@@ -1,104 +0,0 @@
1
- /**
2
- * Reading an issue body. Pure: no clock, no request, no file.
3
- *
4
- * A body is free text a human wrote in a web form. Two shapes are recognised —
5
- * a task list, and an acceptance section — because those are the two shapes
6
- * GitHub itself renders as a checklist. Everything else stays intention text.
7
- */
8
- const TASK_ITEM = /^\s*[-*+]\s+\[[ xX]\]\s+(.*\S)\s*$/;
9
- const HEADING = /^\s{0,3}#{1,6}\s+(.*\S)\s*$/;
10
- const BULLET = /^\s*(?:[-*+]|\d+[.)])\s+(.*\S)\s*$/;
11
- /** Headings whose section is a list of criteria rather than intention text. */
12
- const CRITERIA_HEADINGS = new Set(["acceptance criteria", "definition of done"]);
13
- /** Comments an issue template left behind are not something a human wrote. */
14
- export function stripComments(body) {
15
- return body.replace(/<!--[\s\S]*?-->/g, "");
16
- }
17
- function headingTitle(line) {
18
- const matched = HEADING.exec(line);
19
- return matched?.[1] === undefined ? null : normalizeTitle(matched[1]);
20
- }
21
- function normalizeTitle(title) {
22
- return title
23
- .toLowerCase()
24
- .replace(/[^a-z0-9]+/g, " ")
25
- .trim();
26
- }
27
- /**
28
- * Split a body into the intention and its acceptance criteria.
29
- *
30
- * Task-list items win wherever they are: `- [ ] …` is the checklist GitHub
31
- * renders, and a human who wrote one meant it. Without any, a section titled
32
- * "acceptance criteria" (or "definition of done") is read instead, and the whole
33
- * section leaves the intention.
34
- */
35
- export function readBody(body) {
36
- const lines = stripComments(body).replace(/\r\n?/g, "\n").split("\n");
37
- const criteria = [];
38
- const kept = [];
39
- for (const line of lines) {
40
- const task = TASK_ITEM.exec(line);
41
- if (task?.[1] !== undefined) {
42
- criteria.push(task[1].trim());
43
- continue;
44
- }
45
- kept.push(line);
46
- }
47
- if (criteria.length > 0) {
48
- return parts(dropEmptiedCriteriaHeadings(kept), criteria);
49
- }
50
- const start = lines.findIndex((line) => {
51
- const title = headingTitle(line);
52
- return title !== null && CRITERIA_HEADINGS.has(title);
53
- });
54
- if (start === -1) {
55
- return parts(lines, []);
56
- }
57
- let end = start + 1;
58
- while (end < lines.length && headingTitle(lines[end] ?? "") === null) {
59
- const bullet = BULLET.exec(lines[end] ?? "");
60
- if (bullet?.[1] !== undefined) {
61
- criteria.push(bullet[1].trim());
62
- }
63
- end += 1;
64
- }
65
- return parts([...lines.slice(0, start), ...lines.slice(end)], criteria);
66
- }
67
- /**
68
- * Drop a criteria heading whose section the task list just emptied.
69
- *
70
- * `## Acceptance criteria` followed by `- [ ] …` items loses its items to the
71
- * task list above, and a bare heading with nothing under it would otherwise
72
- * travel on as intention text — into the Plan, and into the Builder's prompt.
73
- * A heading that still has prose under it stays: that prose is intention.
74
- */
75
- function dropEmptiedCriteriaHeadings(lines) {
76
- const out = [];
77
- for (let i = 0; i < lines.length; i++) {
78
- const title = headingTitle(lines[i] ?? "");
79
- if (title === null || !CRITERIA_HEADINGS.has(title)) {
80
- out.push(lines[i] ?? "");
81
- continue;
82
- }
83
- let end = i + 1;
84
- while (end < lines.length && headingTitle(lines[end] ?? "") === null) {
85
- end += 1;
86
- }
87
- if (lines.slice(i + 1, end).some((line) => line.trim().length > 0)) {
88
- out.push(...lines.slice(i, end));
89
- }
90
- i = end - 1;
91
- }
92
- return out;
93
- }
94
- function parts(kept, criteria) {
95
- const intention = kept
96
- .join("\n")
97
- .replace(/\n{3,}/g, "\n\n")
98
- .trim();
99
- return {
100
- ...(intention.length > 0 ? { intention } : {}),
101
- criteria: criteria.filter((entry) => entry.length > 0),
102
- };
103
- }
104
- //# sourceMappingURL=body.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"body.js","sourceRoot":"","sources":["../../../src/adapter/normalize/body.ts"],"names":[],"mappings":"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"}