project-logbook 1.1.0 → 1.3.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 (209) hide show
  1. package/README.md +5 -0
  2. package/dist/commands/build.js +7 -4
  3. package/dist/commands/build.js.map +1 -1
  4. package/dist/commands/log.js +2 -0
  5. package/dist/commands/log.js.map +1 -1
  6. package/dist/commands/new-helpers.d.ts +25 -0
  7. package/dist/commands/new-helpers.js +106 -0
  8. package/dist/commands/new-helpers.js.map +1 -0
  9. package/dist/commands/new.js +91 -92
  10. package/dist/commands/new.js.map +1 -1
  11. package/dist/commands/release.js +2 -0
  12. package/dist/commands/release.js.map +1 -1
  13. package/dist/commands/start.d.ts +1 -1
  14. package/dist/commands/start.js +154 -42
  15. package/dist/commands/start.js.map +1 -1
  16. package/dist/commands/status.js +3 -0
  17. package/dist/commands/status.js.map +1 -1
  18. package/dist/commands/watch.d.ts +15 -0
  19. package/dist/commands/watch.js +153 -0
  20. package/dist/commands/watch.js.map +1 -0
  21. package/dist/index.js +8 -1
  22. package/dist/index.js.map +1 -1
  23. package/dist/lib/autolink.d.ts +5 -0
  24. package/dist/lib/autolink.js +36 -2
  25. package/dist/lib/autolink.js.map +1 -1
  26. package/dist/lib/build-helpers.d.ts +12 -3
  27. package/dist/lib/build-helpers.js +70 -65
  28. package/dist/lib/build-helpers.js.map +1 -1
  29. package/dist/lib/build-steps.js +2 -1
  30. package/dist/lib/build-steps.js.map +1 -1
  31. package/dist/lib/config.d.ts +8 -0
  32. package/dist/lib/config.js +7 -0
  33. package/dist/lib/config.js.map +1 -1
  34. package/dist/lib/custom-card-renderer.js +2 -1
  35. package/dist/lib/custom-card-renderer.js.map +1 -1
  36. package/dist/lib/entry-href.d.ts +7 -0
  37. package/dist/lib/entry-href.js +8 -0
  38. package/dist/lib/entry-href.js.map +1 -0
  39. package/dist/lib/markdown-processors.d.ts +6 -2
  40. package/dist/lib/markdown-processors.js +9 -7
  41. package/dist/lib/markdown-processors.js.map +1 -1
  42. package/dist/lib/post-template.js +3 -3
  43. package/dist/lib/post-template.js.map +1 -1
  44. package/dist/lib/template-helpers.js +3 -2
  45. package/dist/lib/template-helpers.js.map +1 -1
  46. package/dist/lib/template-types.d.ts +2 -0
  47. package/dist/lib/templates.js +5 -3
  48. package/dist/lib/templates.js.map +1 -1
  49. package/dist/linters/jira-prefix.js +32 -16
  50. package/dist/linters/jira-prefix.js.map +1 -1
  51. package/dist/templates/CONTRIBUTING.md +35 -3
  52. package/dist/templates/about-watch.md +29 -0
  53. package/dist/templates/adr.md +34 -0
  54. package/dist/templates/hub.css +677 -0
  55. package/dist/templates/hub.js +628 -0
  56. package/dist/templates/index.md +5 -4
  57. package/dist/templates/steer.txt +14 -1
  58. package/dist/utils/id.d.ts +1 -1
  59. package/dist/utils/id.js +4 -1
  60. package/dist/utils/id.js.map +1 -1
  61. package/dist/utils/prompt.d.ts +6 -0
  62. package/dist/utils/prompt.js +59 -0
  63. package/dist/utils/prompt.js.map +1 -0
  64. package/dist/watch/collector.d.ts +14 -0
  65. package/dist/watch/collector.js +33 -0
  66. package/dist/watch/collector.js.map +1 -0
  67. package/dist/watch/collectors/acli.d.ts +15 -0
  68. package/dist/watch/collectors/acli.js +197 -0
  69. package/dist/watch/collectors/acli.js.map +1 -0
  70. package/dist/watch/collectors/entries.d.ts +9 -0
  71. package/dist/watch/collectors/entries.js +90 -0
  72. package/dist/watch/collectors/entries.js.map +1 -0
  73. package/dist/watch/collectors/git.d.ts +12 -0
  74. package/dist/watch/collectors/git.js +58 -0
  75. package/dist/watch/collectors/git.js.map +1 -0
  76. package/dist/watch/collectors/glab.d.ts +10 -0
  77. package/dist/watch/collectors/glab.js +184 -0
  78. package/dist/watch/collectors/glab.js.map +1 -0
  79. package/dist/watch/collectors/index.d.ts +10 -0
  80. package/dist/watch/collectors/index.js +21 -0
  81. package/dist/watch/collectors/index.js.map +1 -0
  82. package/dist/watch/collectors/jira.d.ts +3 -0
  83. package/dist/watch/collectors/jira.js +110 -0
  84. package/dist/watch/collectors/jira.js.map +1 -0
  85. package/dist/watch/collectors/type-guards.d.ts +17 -0
  86. package/dist/watch/collectors/type-guards.js +35 -0
  87. package/dist/watch/collectors/type-guards.js.map +1 -0
  88. package/dist/watch/collectors/types.d.ts +37 -0
  89. package/dist/watch/collectors/types.js +9 -0
  90. package/dist/watch/collectors/types.js.map +1 -0
  91. package/dist/watch/dashboard-html.d.ts +11 -0
  92. package/dist/watch/dashboard-html.js +73 -0
  93. package/dist/watch/dashboard-html.js.map +1 -0
  94. package/dist/watch/dashboard-script.d.ts +12 -0
  95. package/dist/watch/dashboard-script.js +20 -0
  96. package/dist/watch/dashboard-script.js.map +1 -0
  97. package/dist/watch/dashboard-styles.d.ts +12 -0
  98. package/dist/watch/dashboard-styles.js +20 -0
  99. package/dist/watch/dashboard-styles.js.map +1 -0
  100. package/dist/watch/dashboard.d.ts +12 -0
  101. package/dist/watch/dashboard.js +50 -0
  102. package/dist/watch/dashboard.js.map +1 -0
  103. package/dist/watch/git-utils.d.ts +30 -0
  104. package/dist/watch/git-utils.js +101 -0
  105. package/dist/watch/git-utils.js.map +1 -0
  106. package/dist/watch/hub-state.d.ts +37 -0
  107. package/dist/watch/hub-state.js +55 -0
  108. package/dist/watch/hub-state.js.map +1 -0
  109. package/dist/watch/hub.d.ts +2 -0
  110. package/dist/watch/hub.js +219 -0
  111. package/dist/watch/hub.js.map +1 -0
  112. package/dist/watch/log-utils.d.ts +13 -0
  113. package/dist/watch/log-utils.js +24 -0
  114. package/dist/watch/log-utils.js.map +1 -0
  115. package/dist/watch/notify.d.ts +18 -0
  116. package/dist/watch/notify.js +45 -0
  117. package/dist/watch/notify.js.map +1 -0
  118. package/dist/watch/state.d.ts +34 -0
  119. package/dist/watch/state.js +36 -0
  120. package/dist/watch/state.js.map +1 -0
  121. package/dist/watch/strategies/behind-default.d.ts +5 -0
  122. package/dist/watch/strategies/behind-default.js +21 -0
  123. package/dist/watch/strategies/behind-default.js.map +1 -0
  124. package/dist/watch/strategies/idle.d.ts +5 -0
  125. package/dist/watch/strategies/idle.js +21 -0
  126. package/dist/watch/strategies/idle.js.map +1 -0
  127. package/dist/watch/strategies/in-progress.d.ts +5 -0
  128. package/dist/watch/strategies/in-progress.js +21 -0
  129. package/dist/watch/strategies/in-progress.js.map +1 -0
  130. package/dist/watch/strategies/index.d.ts +34 -0
  131. package/dist/watch/strategies/index.js +148 -0
  132. package/dist/watch/strategies/index.js.map +1 -0
  133. package/dist/watch/strategies/jira-not-in-review.d.ts +2 -0
  134. package/dist/watch/strategies/jira-not-in-review.js +29 -0
  135. package/dist/watch/strategies/jira-not-in-review.js.map +1 -0
  136. package/dist/watch/strategies/jira-still-open.d.ts +2 -0
  137. package/dist/watch/strategies/jira-still-open.js +31 -0
  138. package/dist/watch/strategies/jira-still-open.js.map +1 -0
  139. package/dist/watch/strategies/mr-approval-optional.d.ts +5 -0
  140. package/dist/watch/strategies/mr-approval-optional.js +21 -0
  141. package/dist/watch/strategies/mr-approval-optional.js.map +1 -0
  142. package/dist/watch/strategies/mr-approved.d.ts +5 -0
  143. package/dist/watch/strategies/mr-approved.js +21 -0
  144. package/dist/watch/strategies/mr-approved.js.map +1 -0
  145. package/dist/watch/strategies/mr-conflicts.d.ts +5 -0
  146. package/dist/watch/strategies/mr-conflicts.js +21 -0
  147. package/dist/watch/strategies/mr-conflicts.js.map +1 -0
  148. package/dist/watch/strategies/mr-draft.d.ts +5 -0
  149. package/dist/watch/strategies/mr-draft.js +21 -0
  150. package/dist/watch/strategies/mr-draft.js.map +1 -0
  151. package/dist/watch/strategies/mr-open-comments.d.ts +5 -0
  152. package/dist/watch/strategies/mr-open-comments.js +21 -0
  153. package/dist/watch/strategies/mr-open-comments.js.map +1 -0
  154. package/dist/watch/strategies/narrative-missing.d.ts +5 -0
  155. package/dist/watch/strategies/narrative-missing.js +21 -0
  156. package/dist/watch/strategies/narrative-missing.js.map +1 -0
  157. package/dist/watch/strategies/no-mr.d.ts +5 -0
  158. package/dist/watch/strategies/no-mr.js +21 -0
  159. package/dist/watch/strategies/no-mr.js.map +1 -0
  160. package/dist/watch/strategies/pipeline-failed.d.ts +5 -0
  161. package/dist/watch/strategies/pipeline-failed.js +21 -0
  162. package/dist/watch/strategies/pipeline-failed.js.map +1 -0
  163. package/dist/watch/strategies/pipeline-running.d.ts +5 -0
  164. package/dist/watch/strategies/pipeline-running.js +21 -0
  165. package/dist/watch/strategies/pipeline-running.js.map +1 -0
  166. package/dist/watch/strategies/ready-for-release.d.ts +7 -0
  167. package/dist/watch/strategies/ready-for-release.js +35 -0
  168. package/dist/watch/strategies/ready-for-release.js.map +1 -0
  169. package/dist/watch/strategies/ready-to-commit.d.ts +5 -0
  170. package/dist/watch/strategies/ready-to-commit.js +21 -0
  171. package/dist/watch/strategies/ready-to-commit.js.map +1 -0
  172. package/dist/watch/strategies/ready-to-push.d.ts +5 -0
  173. package/dist/watch/strategies/ready-to-push.js +21 -0
  174. package/dist/watch/strategies/ready-to-push.js.map +1 -0
  175. package/dist/watch/strategies/released.d.ts +6 -0
  176. package/dist/watch/strategies/released.js +21 -0
  177. package/dist/watch/strategies/released.js.map +1 -0
  178. package/dist/watch/strategies/squash-merged.d.ts +6 -0
  179. package/dist/watch/strategies/squash-merged.js +21 -0
  180. package/dist/watch/strategies/squash-merged.js.map +1 -0
  181. package/dist/watch/strategies/types.d.ts +31 -0
  182. package/dist/watch/strategies/types.js +12 -0
  183. package/dist/watch/strategies/types.js.map +1 -0
  184. package/dist/watch/strategies/unstaged-changes.d.ts +5 -0
  185. package/dist/watch/strategies/unstaged-changes.js +21 -0
  186. package/dist/watch/strategies/unstaged-changes.js.map +1 -0
  187. package/dist/watch/strategies/wrong-branch.d.ts +6 -0
  188. package/dist/watch/strategies/wrong-branch.js +26 -0
  189. package/dist/watch/strategies/wrong-branch.js.map +1 -0
  190. package/dist/watch/types.d.ts +190 -0
  191. package/dist/watch/types.js +25 -0
  192. package/dist/watch/types.js.map +1 -0
  193. package/dist/watch/watcher-fs.d.ts +39 -0
  194. package/dist/watch/watcher-fs.js +105 -0
  195. package/dist/watch/watcher-fs.js.map +1 -0
  196. package/dist/watch/watcher-http.d.ts +19 -0
  197. package/dist/watch/watcher-http.js +47 -0
  198. package/dist/watch/watcher-http.js.map +1 -0
  199. package/dist/watch/watcher.d.ts +4 -0
  200. package/dist/watch/watcher.js +174 -0
  201. package/dist/watch/watcher.js.map +1 -0
  202. package/package.json +3 -2
  203. package/src/templates/CONTRIBUTING.md +35 -3
  204. package/src/templates/about-watch.md +29 -0
  205. package/src/templates/adr.md +34 -0
  206. package/src/templates/hub.css +677 -0
  207. package/src/templates/hub.js +628 -0
  208. package/src/templates/index.md +5 -4
  209. package/src/templates/steer.txt +14 -1
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Shared watcher state for logbook watch.
3
+ *
4
+ * This is the single source of truth that collectors write to and strategies
5
+ * read from. Each field is optional — a collector populates its subset, and
6
+ * strategies handle missing data gracefully (undefined = not available).
7
+ *
8
+ * The state is mutable. Collectors update it in-place on their own schedule.
9
+ * After any collector runs, strategies are re-evaluated against the current
10
+ * snapshot.
11
+ */
12
+ import type { GitLabMr, JiraIssue, WatcherMetrics } from './types.js';
13
+ /**
14
+ * The mutable watcher state. Extends WatcherMetrics with fields for future
15
+ * collectors (glab, acli, etc.).
16
+ */
17
+ export interface WatcherState extends WatcherMetrics {
18
+ /** MR title if one exists. */
19
+ mrTitle?: string;
20
+ /** All open MRs for the project (for GitLab tab). */
21
+ glabOpenMrs?: GitLabMr[];
22
+ /** Jira ticket assignee. */
23
+ jiraAssignee?: string;
24
+ /** All Jira issues assigned to the current user (for Jira tab). */
25
+ jiraAssignedIssues?: JiraIssue[];
26
+ /** ISO timestamp of last successful GitLab collector run. */
27
+ glabLastUpdated?: string;
28
+ /** ISO timestamp of last successful Jira collector run. */
29
+ jiraLastUpdated?: string;
30
+ }
31
+ /**
32
+ * Create a fresh empty state with safe defaults.
33
+ */
34
+ export declare function createEmptyState(): WatcherState;
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Shared watcher state for logbook watch.
3
+ *
4
+ * This is the single source of truth that collectors write to and strategies
5
+ * read from. Each field is optional — a collector populates its subset, and
6
+ * strategies handle missing data gracefully (undefined = not available).
7
+ *
8
+ * The state is mutable. Collectors update it in-place on their own schedule.
9
+ * After any collector runs, strategies are re-evaluated against the current
10
+ * snapshot.
11
+ */
12
+ /**
13
+ * Create a fresh empty state with safe defaults.
14
+ */
15
+ export function createEmptyState() {
16
+ return {
17
+ branch: undefined,
18
+ defaultBranch: 'main',
19
+ hasActiveTicket: false,
20
+ activeTicketId: undefined,
21
+ activeTicketSlug: undefined,
22
+ latestLog: undefined,
23
+ latestLogTimestamp: undefined,
24
+ isDirty: false,
25
+ stagedFiles: 0,
26
+ unstagedFiles: 0,
27
+ isAheadOfRemote: false,
28
+ hasNarrativePlaceholders: false,
29
+ isReleased: false,
30
+ hasLockfile: false,
31
+ isSquashMerged: false,
32
+ commitsBehindDefault: 0,
33
+ lastActivityTimestamp: new Date().toISOString(),
34
+ };
35
+ }
36
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/watch/state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AA4BH;;GAEG;AACH,MAAM,UAAU,gBAAgB;IAC9B,OAAO;QACL,MAAM,EAAE,SAAS;QACjB,aAAa,EAAE,MAAM;QACrB,eAAe,EAAE,KAAK;QACtB,cAAc,EAAE,SAAS;QACzB,gBAAgB,EAAE,SAAS;QAC3B,SAAS,EAAE,SAAS;QACpB,kBAAkB,EAAE,SAAS;QAC7B,OAAO,EAAE,KAAK;QACd,WAAW,EAAE,CAAC;QACd,aAAa,EAAE,CAAC;QAChB,eAAe,EAAE,KAAK;QACtB,wBAAwB,EAAE,KAAK;QAC/B,UAAU,EAAE,KAAK;QACjB,WAAW,EAAE,KAAK;QAClB,cAAc,EAAE,KAAK;QACrB,oBAAoB,EAAE,CAAC;QACvB,qBAAqB,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KAChD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { StatusStrategy } from './types.js';
2
+ /**
3
+ * Behind Default — the current branch is behind the default branch.
4
+ */
5
+ export declare const behindDefaultCheck: StatusStrategy;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Behind Default — the current branch is behind the default branch.
3
+ */
4
+ export const behindDefaultCheck = {
5
+ id: 'behind-default',
6
+ source: 'Git',
7
+ description: 'The current branch is behind the default branch. Consider rebasing or merging.',
8
+ blockedBy: ['squash-merged', 'released'],
9
+ check(metrics) {
10
+ if (metrics.commitsBehindDefault > 0) {
11
+ return {
12
+ id: 'behind-default',
13
+ label: 'Behind Default',
14
+ severity: 'warning',
15
+ detail: `${metrics.commitsBehindDefault} commit${metrics.commitsBehindDefault !== 1 ? 's' : ''} behind ${metrics.defaultBranch}`,
16
+ };
17
+ }
18
+ return null;
19
+ },
20
+ };
21
+ //# sourceMappingURL=behind-default.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"behind-default.js","sourceRoot":"","sources":["../../../src/watch/strategies/behind-default.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAmB;IAChD,EAAE,EAAE,gBAAgB;IACpB,MAAM,EAAE,KAAK;IACb,WAAW,EAAE,gFAAgF;IAC7F,SAAS,EAAE,CAAC,eAAe,EAAE,UAAU,CAAC;IACxC,KAAK,CAAC,OAAO;QACX,IAAI,OAAO,CAAC,oBAAoB,GAAG,CAAC,EAAE,CAAC;YACrC,OAAO;gBACL,EAAE,EAAE,gBAAgB;gBACpB,KAAK,EAAE,gBAAgB;gBACvB,QAAQ,EAAE,SAAS;gBACnB,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,UAAU,OAAO,CAAC,oBAAoB,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,WAAW,OAAO,CAAC,aAAa,EAAE;aACjI,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { StatusStrategy } from './types.js';
2
+ /**
3
+ * Idle — no active ticket and no dirty state.
4
+ */
5
+ export declare const idleCheck: StatusStrategy;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Idle — no active ticket and no dirty state.
3
+ */
4
+ export const idleCheck = {
5
+ id: 'idle',
6
+ source: 'LOGBOOK',
7
+ description: 'No active ticket and no uncommitted changes.',
8
+ blockedBy: ['squash-merged', 'released'],
9
+ check(metrics) {
10
+ if (!metrics.hasActiveTicket && !metrics.isDirty) {
11
+ return {
12
+ id: 'idle',
13
+ label: 'Idle',
14
+ severity: 'info',
15
+ detail: 'No active ticket. All clean.',
16
+ };
17
+ }
18
+ return null;
19
+ },
20
+ };
21
+ //# sourceMappingURL=idle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"idle.js","sourceRoot":"","sources":["../../../src/watch/strategies/idle.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,CAAC,MAAM,SAAS,GAAmB;IACvC,EAAE,EAAE,MAAM;IACV,MAAM,EAAE,SAAS;IACjB,WAAW,EAAE,8CAA8C;IAC3D,SAAS,EAAE,CAAC,eAAe,EAAE,UAAU,CAAC;IACxC,KAAK,CAAC,OAAO;QACX,IAAI,CAAC,OAAO,CAAC,eAAe,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YACjD,OAAO;gBACL,EAAE,EAAE,MAAM;gBACV,KAAK,EAAE,MAAM;gBACb,QAAQ,EAAE,MAAM;gBAChB,MAAM,EAAE,8BAA8B;aACvC,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { StatusStrategy } from './types.js';
2
+ /**
3
+ * In Progress — an active ticket is present but no other blocking state.
4
+ */
5
+ export declare const inProgressCheck: StatusStrategy;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * In Progress — an active ticket is present but no other blocking state.
3
+ */
4
+ export const inProgressCheck = {
5
+ id: 'in-progress',
6
+ source: 'LOGBOOK',
7
+ description: 'An active ticket is present and work is in progress.',
8
+ blockedBy: ['squash-merged', 'released'],
9
+ check(metrics) {
10
+ if (metrics.hasActiveTicket) {
11
+ return {
12
+ id: 'in-progress',
13
+ label: 'In Progress',
14
+ severity: 'info',
15
+ detail: `Working on ${metrics.activeTicketId ?? metrics.activeTicketSlug ?? 'unknown'}`,
16
+ };
17
+ }
18
+ return null;
19
+ },
20
+ };
21
+ //# sourceMappingURL=in-progress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"in-progress.js","sourceRoot":"","sources":["../../../src/watch/strategies/in-progress.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAmB;IAC7C,EAAE,EAAE,aAAa;IACjB,MAAM,EAAE,SAAS;IACjB,WAAW,EAAE,sDAAsD;IACnE,SAAS,EAAE,CAAC,eAAe,EAAE,UAAU,CAAC;IACxC,KAAK,CAAC,OAAO;QACX,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;YAC5B,OAAO;gBACL,EAAE,EAAE,aAAa;gBACjB,KAAK,EAAE,aAAa;gBACpB,QAAQ,EAAE,MAAM;gBAChB,MAAM,EAAE,cAAc,OAAO,CAAC,cAAc,IAAI,OAAO,CAAC,gBAAgB,IAAI,SAAS,EAAE;aACxF,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Strategy registry and evaluator for logbook watch.
3
+ *
4
+ * Strategies are evaluated in declared order. The `blockedBy` mechanism
5
+ * suppresses a strategy if any of its listed blocker IDs are already active.
6
+ */
7
+ import type { StatusResult, StatusSeverity, WatcherMetrics } from '../types.js';
8
+ import type { StrategySource } from './types.js';
9
+ /**
10
+ * Evaluate all strategies against the given metrics.
11
+ *
12
+ * Strategies are evaluated in order. If a strategy declares `blockedBy` IDs
13
+ * and any of those are already in the results, that strategy is suppressed.
14
+ *
15
+ * @param metrics - The collected watcher metrics.
16
+ * @returns All applicable, non-blocked status results.
17
+ */
18
+ export declare function evaluateStatuses(metrics: WatcherMetrics): StatusResult[];
19
+ /** Static metadata for a strategy (used by the Help tab API). */
20
+ interface StrategyMeta {
21
+ id: string;
22
+ label: string;
23
+ severity: StatusSeverity;
24
+ source: StrategySource;
25
+ description: string;
26
+ blockedBy: string[];
27
+ }
28
+ /**
29
+ * Get static metadata for all registered strategies (for Help tab API).
30
+ *
31
+ * @returns Array of strategy metadata objects sorted by source then severity.
32
+ */
33
+ export declare function getStrategyMetadata(): StrategyMeta[];
34
+ export {};
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Strategy registry and evaluator for logbook watch.
3
+ *
4
+ * Strategies are evaluated in declared order. The `blockedBy` mechanism
5
+ * suppresses a strategy if any of its listed blocker IDs are already active.
6
+ */
7
+ import { releasedCheck } from './released.js';
8
+ import { squashMergedCheck } from './squash-merged.js';
9
+ import { idleCheck } from './idle.js';
10
+ import { inProgressCheck } from './in-progress.js';
11
+ import { unstagedChangesCheck } from './unstaged-changes.js';
12
+ import { readyToCommitCheck } from './ready-to-commit.js';
13
+ import { readyToPushCheck } from './ready-to-push.js';
14
+ import { narrativeMissingCheck } from './narrative-missing.js';
15
+ import { readyForReleaseCheck } from './ready-for-release.js';
16
+ import { mrDraftCheck } from './mr-draft.js';
17
+ import { mrOpenCommentsCheck } from './mr-open-comments.js';
18
+ import { mrApprovedCheck } from './mr-approved.js';
19
+ import { mrApprovalOptionalCheck } from './mr-approval-optional.js';
20
+ import { pipelineFailedCheck } from './pipeline-failed.js';
21
+ import { pipelineRunningCheck } from './pipeline-running.js';
22
+ import { noMrCheck } from './no-mr.js';
23
+ import { wrongBranchCheck } from './wrong-branch.js';
24
+ import { behindDefaultCheck } from './behind-default.js';
25
+ import { mrConflictsCheck } from './mr-conflicts.js';
26
+ import { jiraStillOpenCheck } from './jira-still-open.js';
27
+ import { jiraNotInReviewCheck } from './jira-not-in-review.js';
28
+ /** All registered strategies, evaluated in this order. */
29
+ const ALL_STRATEGIES = [
30
+ squashMergedCheck,
31
+ releasedCheck,
32
+ idleCheck,
33
+ inProgressCheck,
34
+ wrongBranchCheck,
35
+ behindDefaultCheck,
36
+ unstagedChangesCheck,
37
+ readyToCommitCheck,
38
+ readyToPushCheck,
39
+ pipelineFailedCheck,
40
+ pipelineRunningCheck,
41
+ mrDraftCheck,
42
+ mrConflictsCheck,
43
+ mrOpenCommentsCheck,
44
+ mrApprovedCheck,
45
+ mrApprovalOptionalCheck,
46
+ noMrCheck,
47
+ jiraStillOpenCheck,
48
+ jiraNotInReviewCheck,
49
+ narrativeMissingCheck,
50
+ readyForReleaseCheck,
51
+ ];
52
+ /**
53
+ * Evaluate all strategies against the given metrics.
54
+ *
55
+ * Strategies are evaluated in order. If a strategy declares `blockedBy` IDs
56
+ * and any of those are already in the results, that strategy is suppressed.
57
+ *
58
+ * @param metrics - The collected watcher metrics.
59
+ * @returns All applicable, non-blocked status results.
60
+ */
61
+ export function evaluateStatuses(metrics) {
62
+ const results = [];
63
+ const activeIds = new Set();
64
+ for (const strategy of ALL_STRATEGIES) {
65
+ if (strategy.blockedBy?.some((id) => activeIds.has(id)))
66
+ continue;
67
+ const result = strategy.check(metrics);
68
+ if (result) {
69
+ results.push(result);
70
+ activeIds.add(result.id);
71
+ }
72
+ }
73
+ return results;
74
+ }
75
+ /** Strategy ID → label/severity mapping (derived from known outputs). */
76
+ const STRATEGY_META = [
77
+ { id: 'squash-merged', label: 'Squash Merged', severity: 'success' },
78
+ { id: 'released', label: 'Released', severity: 'success' },
79
+ { id: 'idle', label: 'Idle', severity: 'info' },
80
+ { id: 'in-progress', label: 'In Progress', severity: 'info' },
81
+ { id: 'wrong-branch', label: 'Not on Ticket Branch', severity: 'warning' },
82
+ { id: 'behind-default', label: 'Behind Default', severity: 'warning' },
83
+ { id: 'unstaged-changes', label: 'Unstaged Changes', severity: 'warning' },
84
+ { id: 'ready-to-commit', label: 'Ready to Commit', severity: 'warning' },
85
+ { id: 'ready-to-push', label: 'Ready to Push', severity: 'warning' },
86
+ { id: 'pipeline-failed', label: 'Pipeline Failed', severity: 'warning' },
87
+ { id: 'pipeline-running', label: 'Pipeline Running', severity: 'info' },
88
+ { id: 'mr-draft', label: 'MR Draft', severity: 'info' },
89
+ { id: 'mr-conflicts', label: 'MR Conflicts', severity: 'warning' },
90
+ { id: 'mr-open-comments', label: 'MR Open Comments', severity: 'warning' },
91
+ { id: 'mr-approved', label: 'MR Approved', severity: 'success' },
92
+ {
93
+ id: 'mr-approval-optional',
94
+ label: 'MR Open (Approval Optional)',
95
+ severity: 'info',
96
+ },
97
+ { id: 'no-mr', label: 'No MR', severity: 'info' },
98
+ { id: 'jira-still-open', label: 'Jira Still Open', severity: 'warning' },
99
+ {
100
+ id: 'jira-not-in-review',
101
+ label: 'Jira Not In Review',
102
+ severity: 'warning',
103
+ },
104
+ {
105
+ id: 'narrative-missing',
106
+ label: 'Narrative Missing',
107
+ severity: 'warning',
108
+ },
109
+ {
110
+ id: 'ready-for-release',
111
+ label: 'Ready for Release',
112
+ severity: 'success',
113
+ },
114
+ ];
115
+ /**
116
+ * Get static metadata for all registered strategies (for Help tab API).
117
+ *
118
+ * @returns Array of strategy metadata objects sorted by source then severity.
119
+ */
120
+ export function getStrategyMetadata() {
121
+ const sourceOrder = {
122
+ LOGBOOK: 0,
123
+ Git: 1,
124
+ GitLab: 2,
125
+ Jira: 3,
126
+ };
127
+ const severityOrder = {
128
+ warning: 0,
129
+ info: 1,
130
+ success: 2,
131
+ };
132
+ const meta = ALL_STRATEGIES.map((strategy, i) => ({
133
+ id: STRATEGY_META[i].id,
134
+ label: STRATEGY_META[i].label,
135
+ severity: STRATEGY_META[i].severity,
136
+ source: strategy.source ?? 'LOGBOOK',
137
+ description: strategy.description ?? '',
138
+ blockedBy: strategy.blockedBy ?? [],
139
+ }));
140
+ meta.sort((a, b) => {
141
+ const srcDiff = sourceOrder[a.source] - sourceOrder[b.source];
142
+ if (srcDiff !== 0)
143
+ return srcDiff;
144
+ return severityOrder[a.severity] - severityOrder[b.severity];
145
+ });
146
+ return meta;
147
+ }
148
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/watch/strategies/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { StatusStrategy } from './types.js';
2
+ export declare const jiraNotInReviewCheck: StatusStrategy;
@@ -0,0 +1,29 @@
1
+ export const jiraNotInReviewCheck = {
2
+ id: 'jira-not-in-review',
3
+ source: 'Jira',
4
+ description: 'Jira ticket is not in Review despite an open MR.',
5
+ blockedBy: ['squash-merged', 'released'],
6
+ check(metrics) {
7
+ if (metrics.jiraStatus &&
8
+ !isReviewStatus(metrics.jiraStatus) &&
9
+ !isDoneStatus(metrics.jiraStatus) &&
10
+ (metrics.mrStatus === 'open' || metrics.mrStatus === 'approval-optional' || metrics.mrStatus === 'draft')) {
11
+ return {
12
+ id: 'jira-not-in-review',
13
+ label: 'Jira Not In Review',
14
+ severity: 'warning',
15
+ detail: `Jira status: ${metrics.jiraStatus}`,
16
+ };
17
+ }
18
+ return null;
19
+ },
20
+ };
21
+ const REVIEW_STATUSES = new Set(['in review', 'review', 'reviewing', 'in review / qa']);
22
+ const DONE_STATUSES = new Set(['done', 'closed', 'resolved', 'completed']);
23
+ function isReviewStatus(status) {
24
+ return REVIEW_STATUSES.has(status.toLowerCase());
25
+ }
26
+ function isDoneStatus(status) {
27
+ return DONE_STATUSES.has(status.toLowerCase());
28
+ }
29
+ //# sourceMappingURL=jira-not-in-review.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jira-not-in-review.js","sourceRoot":"","sources":["../../../src/watch/strategies/jira-not-in-review.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,oBAAoB,GAAmB;IAClD,EAAE,EAAE,oBAAoB;IACxB,MAAM,EAAE,MAAM;IACd,WAAW,EAAE,kDAAkD;IAC/D,SAAS,EAAE,CAAC,eAAe,EAAE,UAAU,CAAC;IACxC,KAAK,CAAC,OAAO;QACX,IACE,OAAO,CAAC,UAAU;YAClB,CAAC,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC;YACnC,CAAC,YAAY,CAAC,OAAO,CAAC,UAAU,CAAC;YACjC,CAAC,OAAO,CAAC,QAAQ,KAAK,MAAM,IAAI,OAAO,CAAC,QAAQ,KAAK,mBAAmB,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,EACzG,CAAC;YACD,OAAO;gBACL,EAAE,EAAE,oBAAoB;gBACxB,KAAK,EAAE,oBAAoB;gBAC3B,QAAQ,EAAE,SAAS;gBACnB,MAAM,EAAE,gBAAgB,OAAO,CAAC,UAAU,EAAE;aAC7C,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAC;AAEF,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,gBAAgB,CAAC,CAAC,CAAC;AACxF,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC;AAE3E,SAAS,cAAc,CAAC,MAAc;IACpC,OAAO,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;AACnD,CAAC;AACD,SAAS,YAAY,CAAC,MAAc;IAClC,OAAO,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;AACjD,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { StatusStrategy } from './types.js';
2
+ export declare const jiraStillOpenCheck: StatusStrategy;
@@ -0,0 +1,31 @@
1
+ export const jiraStillOpenCheck = {
2
+ id: 'jira-still-open',
3
+ source: 'Jira',
4
+ description: 'The linked Jira ticket is in an unstarted status (To Do, Open, etc.).',
5
+ blockedBy: ['squash-merged', 'released'],
6
+ check(metrics) {
7
+ if (metrics.jiraStatus && isUnstartedStatus(metrics.jiraStatus)) {
8
+ return {
9
+ id: 'jira-still-open',
10
+ label: 'Jira Still Open',
11
+ severity: 'warning',
12
+ detail: `Status: ${metrics.jiraStatus}`,
13
+ };
14
+ }
15
+ return null;
16
+ },
17
+ };
18
+ const UNSTARTED_STATUSES = new Set([
19
+ 'to do',
20
+ 'open',
21
+ 'new',
22
+ 'backlog',
23
+ 'selected for development',
24
+ 'ready',
25
+ 'groomed',
26
+ 'refinement',
27
+ ]);
28
+ function isUnstartedStatus(status) {
29
+ return UNSTARTED_STATUSES.has(status.toLowerCase());
30
+ }
31
+ //# sourceMappingURL=jira-still-open.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jira-still-open.js","sourceRoot":"","sources":["../../../src/watch/strategies/jira-still-open.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,kBAAkB,GAAmB;IAChD,EAAE,EAAE,iBAAiB;IACrB,MAAM,EAAE,MAAM;IACd,WAAW,EAAE,uEAAuE;IACpF,SAAS,EAAE,CAAC,eAAe,EAAE,UAAU,CAAC;IACxC,KAAK,CAAC,OAAO;QACX,IAAI,OAAO,CAAC,UAAU,IAAI,iBAAiB,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;YAChE,OAAO;gBACL,EAAE,EAAE,iBAAiB;gBACrB,KAAK,EAAE,iBAAiB;gBACxB,QAAQ,EAAE,SAAS;gBACnB,MAAM,EAAE,WAAW,OAAO,CAAC,UAAU,EAAE;aACxC,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAC;AAEF,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC;IACjC,OAAO;IACP,MAAM;IACN,KAAK;IACL,SAAS;IACT,0BAA0B;IAC1B,OAAO;IACP,SAAS;IACT,YAAY;CACb,CAAC,CAAC;AAEH,SAAS,iBAAiB,CAAC,MAAc;IACvC,OAAO,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;AACtD,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { StatusStrategy } from './types.js';
2
+ /**
3
+ * MR Approval Optional — the merge request is open but no approvals are required.
4
+ */
5
+ export declare const mrApprovalOptionalCheck: StatusStrategy;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * MR Approval Optional — the merge request is open but no approvals are required.
3
+ */
4
+ export const mrApprovalOptionalCheck = {
5
+ id: 'mr-approval-optional',
6
+ source: 'GitLab',
7
+ description: 'The merge request is open but no approvals are required.',
8
+ blockedBy: ['squash-merged', 'released'],
9
+ check(metrics) {
10
+ if (metrics.mrStatus === 'approval-optional') {
11
+ return {
12
+ id: 'mr-approval-optional',
13
+ label: 'MR Open (Approval Optional)',
14
+ severity: 'info',
15
+ detail: 'No approvals required for this MR.',
16
+ };
17
+ }
18
+ return null;
19
+ },
20
+ };
21
+ //# sourceMappingURL=mr-approval-optional.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mr-approval-optional.js","sourceRoot":"","sources":["../../../src/watch/strategies/mr-approval-optional.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAmB;IACrD,EAAE,EAAE,sBAAsB;IAC1B,MAAM,EAAE,QAAQ;IAChB,WAAW,EAAE,0DAA0D;IACvE,SAAS,EAAE,CAAC,eAAe,EAAE,UAAU,CAAC;IACxC,KAAK,CAAC,OAAO;QACX,IAAI,OAAO,CAAC,QAAQ,KAAK,mBAAmB,EAAE,CAAC;YAC7C,OAAO;gBACL,EAAE,EAAE,sBAAsB;gBAC1B,KAAK,EAAE,6BAA6B;gBACpC,QAAQ,EAAE,MAAM;gBAChB,MAAM,EAAE,oCAAoC;aAC7C,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { StatusStrategy } from './types.js';
2
+ /**
3
+ * MR Approved — the merge request has been approved by sufficient reviewers.
4
+ */
5
+ export declare const mrApprovedCheck: StatusStrategy;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * MR Approved — the merge request has been approved by sufficient reviewers.
3
+ */
4
+ export const mrApprovedCheck = {
5
+ id: 'mr-approved',
6
+ source: 'GitLab',
7
+ description: 'The merge request has received sufficient approvals.',
8
+ blockedBy: ['squash-merged', 'released'],
9
+ check(metrics) {
10
+ if (metrics.mrStatus === 'approved') {
11
+ return {
12
+ id: 'mr-approved',
13
+ label: 'MR Approved',
14
+ severity: 'success',
15
+ detail: 'Merge request is approved.',
16
+ };
17
+ }
18
+ return null;
19
+ },
20
+ };
21
+ //# sourceMappingURL=mr-approved.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mr-approved.js","sourceRoot":"","sources":["../../../src/watch/strategies/mr-approved.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAmB;IAC7C,EAAE,EAAE,aAAa;IACjB,MAAM,EAAE,QAAQ;IAChB,WAAW,EAAE,sDAAsD;IACnE,SAAS,EAAE,CAAC,eAAe,EAAE,UAAU,CAAC;IACxC,KAAK,CAAC,OAAO;QACX,IAAI,OAAO,CAAC,QAAQ,KAAK,UAAU,EAAE,CAAC;YACpC,OAAO;gBACL,EAAE,EAAE,aAAa;gBACjB,KAAK,EAAE,aAAa;gBACpB,QAAQ,EAAE,SAAS;gBACnB,MAAM,EAAE,4BAA4B;aACrC,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { StatusStrategy } from './types.js';
2
+ /**
3
+ * MR Conflicts — the merge request has merge conflicts with the target branch.
4
+ */
5
+ export declare const mrConflictsCheck: StatusStrategy;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * MR Conflicts — the merge request has merge conflicts with the target branch.
3
+ */
4
+ export const mrConflictsCheck = {
5
+ id: 'mr-conflicts',
6
+ source: 'GitLab',
7
+ description: 'The merge request has merge conflicts with the target branch.',
8
+ blockedBy: ['squash-merged', 'released'],
9
+ check(metrics) {
10
+ if (metrics.mrHasConflicts) {
11
+ return {
12
+ id: 'mr-conflicts',
13
+ label: 'MR Conflicts',
14
+ severity: 'warning',
15
+ detail: 'Merge request has conflicts.',
16
+ };
17
+ }
18
+ return null;
19
+ },
20
+ };
21
+ //# sourceMappingURL=mr-conflicts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mr-conflicts.js","sourceRoot":"","sources":["../../../src/watch/strategies/mr-conflicts.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAmB;IAC9C,EAAE,EAAE,cAAc;IAClB,MAAM,EAAE,QAAQ;IAChB,WAAW,EAAE,+DAA+D;IAC5E,SAAS,EAAE,CAAC,eAAe,EAAE,UAAU,CAAC;IACxC,KAAK,CAAC,OAAO;QACX,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;YAC3B,OAAO;gBACL,EAAE,EAAE,cAAc;gBAClB,KAAK,EAAE,cAAc;gBACrB,QAAQ,EAAE,SAAS;gBACnB,MAAM,EAAE,8BAA8B;aACvC,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { StatusStrategy } from './types.js';
2
+ /**
3
+ * MR Draft — the merge request for the current branch is in draft state.
4
+ */
5
+ export declare const mrDraftCheck: StatusStrategy;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * MR Draft — the merge request for the current branch is in draft state.
3
+ */
4
+ export const mrDraftCheck = {
5
+ id: 'mr-draft',
6
+ source: 'GitLab',
7
+ description: 'The merge request for this branch is in draft state.',
8
+ blockedBy: ['squash-merged', 'released'],
9
+ check(metrics) {
10
+ if (metrics.mrStatus === 'draft') {
11
+ return {
12
+ id: 'mr-draft',
13
+ label: 'MR Draft',
14
+ severity: 'info',
15
+ detail: 'Merge request is in draft state.',
16
+ };
17
+ }
18
+ return null;
19
+ },
20
+ };
21
+ //# sourceMappingURL=mr-draft.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mr-draft.js","sourceRoot":"","sources":["../../../src/watch/strategies/mr-draft.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAmB;IAC1C,EAAE,EAAE,UAAU;IACd,MAAM,EAAE,QAAQ;IAChB,WAAW,EAAE,sDAAsD;IACnE,SAAS,EAAE,CAAC,eAAe,EAAE,UAAU,CAAC;IACxC,KAAK,CAAC,OAAO;QACX,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;YACjC,OAAO;gBACL,EAAE,EAAE,UAAU;gBACd,KAAK,EAAE,UAAU;gBACjB,QAAQ,EAAE,MAAM;gBAChB,MAAM,EAAE,kCAAkC;aAC3C,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { StatusStrategy } from './types.js';
2
+ /**
3
+ * MR Open Comments — the merge request has unresolved discussion threads.
4
+ */
5
+ export declare const mrOpenCommentsCheck: StatusStrategy;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * MR Open Comments — the merge request has unresolved discussion threads.
3
+ */
4
+ export const mrOpenCommentsCheck = {
5
+ id: 'mr-open-comments',
6
+ source: 'GitLab',
7
+ description: 'The merge request has unresolved discussion threads.',
8
+ blockedBy: ['squash-merged', 'released'],
9
+ check(metrics) {
10
+ if (metrics.mrOpenThreads !== undefined && metrics.mrOpenThreads > 0) {
11
+ return {
12
+ id: 'mr-open-comments',
13
+ label: 'MR Open Comments',
14
+ severity: 'warning',
15
+ detail: `${metrics.mrOpenThreads} unresolved thread${metrics.mrOpenThreads !== 1 ? 's' : ''}`,
16
+ };
17
+ }
18
+ return null;
19
+ },
20
+ };
21
+ //# sourceMappingURL=mr-open-comments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mr-open-comments.js","sourceRoot":"","sources":["../../../src/watch/strategies/mr-open-comments.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAmB;IACjD,EAAE,EAAE,kBAAkB;IACtB,MAAM,EAAE,QAAQ;IAChB,WAAW,EAAE,sDAAsD;IACnE,SAAS,EAAE,CAAC,eAAe,EAAE,UAAU,CAAC;IACxC,KAAK,CAAC,OAAO;QACX,IAAI,OAAO,CAAC,aAAa,KAAK,SAAS,IAAI,OAAO,CAAC,aAAa,GAAG,CAAC,EAAE,CAAC;YACrE,OAAO;gBACL,EAAE,EAAE,kBAAkB;gBACtB,KAAK,EAAE,kBAAkB;gBACzB,QAAQ,EAAE,SAAS;gBACnB,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,qBAAqB,OAAO,CAAC,aAAa,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;aAC9F,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { StatusStrategy } from './types.js';
2
+ /**
3
+ * Narrative Missing — the active ticket's index.md still has unfilled placeholders.
4
+ */
5
+ export declare const narrativeMissingCheck: StatusStrategy;