project-logbook 1.2.0 → 1.4.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 (226) hide show
  1. package/README.md +2 -0
  2. package/dist/commands/answer.d.ts +1 -0
  3. package/dist/commands/answer.js +41 -0
  4. package/dist/commands/answer.js.map +1 -0
  5. package/dist/commands/answers.d.ts +6 -0
  6. package/dist/commands/answers.js +37 -0
  7. package/dist/commands/answers.js.map +1 -0
  8. package/dist/commands/ask.d.ts +1 -0
  9. package/dist/commands/ask.js +30 -0
  10. package/dist/commands/ask.js.map +1 -0
  11. package/dist/commands/build.js +25 -6
  12. package/dist/commands/build.js.map +1 -1
  13. package/dist/commands/deprecate-qna.d.ts +1 -0
  14. package/dist/commands/deprecate-qna.js +33 -0
  15. package/dist/commands/deprecate-qna.js.map +1 -0
  16. package/dist/commands/log.js +2 -0
  17. package/dist/commands/log.js.map +1 -1
  18. package/dist/commands/new-helpers.d.ts +0 -1
  19. package/dist/commands/new-helpers.js +6 -3
  20. package/dist/commands/new-helpers.js.map +1 -1
  21. package/dist/commands/release.js +2 -0
  22. package/dist/commands/release.js.map +1 -1
  23. package/dist/commands/start.js +90 -21
  24. package/dist/commands/start.js.map +1 -1
  25. package/dist/commands/status.js +6 -0
  26. package/dist/commands/status.js.map +1 -1
  27. package/dist/commands/unanswered.d.ts +1 -0
  28. package/dist/commands/unanswered.js +25 -0
  29. package/dist/commands/unanswered.js.map +1 -0
  30. package/dist/commands/watch.d.ts +15 -0
  31. package/dist/commands/watch.js +153 -0
  32. package/dist/commands/watch.js.map +1 -0
  33. package/dist/index.js +44 -0
  34. package/dist/index.js.map +1 -1
  35. package/dist/lib/autolink.d.ts +5 -0
  36. package/dist/lib/autolink.js +36 -2
  37. package/dist/lib/autolink.js.map +1 -1
  38. package/dist/lib/build-helpers.d.ts +10 -1
  39. package/dist/lib/build-helpers.js +27 -4
  40. package/dist/lib/build-helpers.js.map +1 -1
  41. package/dist/lib/build-steps.js +2 -1
  42. package/dist/lib/build-steps.js.map +1 -1
  43. package/dist/lib/config.d.ts +16 -0
  44. package/dist/lib/config.js +17 -0
  45. package/dist/lib/config.js.map +1 -1
  46. package/dist/lib/custom-card-renderer.js +2 -1
  47. package/dist/lib/custom-card-renderer.js.map +1 -1
  48. package/dist/lib/entry-href.d.ts +7 -0
  49. package/dist/lib/entry-href.js +8 -0
  50. package/dist/lib/entry-href.js.map +1 -0
  51. package/dist/lib/markdown-processors.d.ts +2 -1
  52. package/dist/lib/post-template.js +3 -3
  53. package/dist/lib/post-template.js.map +1 -1
  54. package/dist/lib/template-helpers.d.ts +2 -1
  55. package/dist/lib/template-helpers.js +32 -2
  56. package/dist/lib/template-helpers.js.map +1 -1
  57. package/dist/lib/template-types.d.ts +14 -0
  58. package/dist/lib/templates.js +14 -4
  59. package/dist/lib/templates.js.map +1 -1
  60. package/dist/linters/index.js +2 -0
  61. package/dist/linters/index.js.map +1 -1
  62. package/dist/linters/jira-prefix.js +32 -16
  63. package/dist/linters/jira-prefix.js.map +1 -1
  64. package/dist/linters/qna.d.ts +3 -0
  65. package/dist/linters/qna.js +120 -0
  66. package/dist/linters/qna.js.map +1 -0
  67. package/dist/templates/about-watch.md +29 -0
  68. package/dist/templates/hub.css +677 -0
  69. package/dist/templates/hub.js +743 -0
  70. package/dist/templates/qna.md +11 -0
  71. package/dist/templates/steer.txt +2 -0
  72. package/dist/templates/styles.css +53 -0
  73. package/dist/utils/id.d.ts +1 -1
  74. package/dist/utils/id.js +4 -1
  75. package/dist/utils/id.js.map +1 -1
  76. package/dist/utils/qna.d.ts +46 -0
  77. package/dist/utils/qna.js +157 -0
  78. package/dist/utils/qna.js.map +1 -0
  79. package/dist/watch/__tests__/git-utils.test.d.ts +1 -0
  80. package/dist/watch/__tests__/git-utils.test.js +17 -0
  81. package/dist/watch/__tests__/git-utils.test.js.map +1 -0
  82. package/dist/watch/collector.d.ts +14 -0
  83. package/dist/watch/collector.js +33 -0
  84. package/dist/watch/collector.js.map +1 -0
  85. package/dist/watch/collectors/acli.d.ts +15 -0
  86. package/dist/watch/collectors/acli.js +197 -0
  87. package/dist/watch/collectors/acli.js.map +1 -0
  88. package/dist/watch/collectors/entries.d.ts +9 -0
  89. package/dist/watch/collectors/entries.js +90 -0
  90. package/dist/watch/collectors/entries.js.map +1 -0
  91. package/dist/watch/collectors/git.d.ts +12 -0
  92. package/dist/watch/collectors/git.js +58 -0
  93. package/dist/watch/collectors/git.js.map +1 -0
  94. package/dist/watch/collectors/glab.d.ts +10 -0
  95. package/dist/watch/collectors/glab.js +273 -0
  96. package/dist/watch/collectors/glab.js.map +1 -0
  97. package/dist/watch/collectors/index.d.ts +10 -0
  98. package/dist/watch/collectors/index.js +21 -0
  99. package/dist/watch/collectors/index.js.map +1 -0
  100. package/dist/watch/collectors/jira.d.ts +3 -0
  101. package/dist/watch/collectors/jira.js +111 -0
  102. package/dist/watch/collectors/jira.js.map +1 -0
  103. package/dist/watch/collectors/type-guards.d.ts +17 -0
  104. package/dist/watch/collectors/type-guards.js +35 -0
  105. package/dist/watch/collectors/type-guards.js.map +1 -0
  106. package/dist/watch/collectors/types.d.ts +37 -0
  107. package/dist/watch/collectors/types.js +9 -0
  108. package/dist/watch/collectors/types.js.map +1 -0
  109. package/dist/watch/dashboard-html.d.ts +11 -0
  110. package/dist/watch/dashboard-html.js +81 -0
  111. package/dist/watch/dashboard-html.js.map +1 -0
  112. package/dist/watch/dashboard-script.d.ts +12 -0
  113. package/dist/watch/dashboard-script.js +20 -0
  114. package/dist/watch/dashboard-script.js.map +1 -0
  115. package/dist/watch/dashboard-styles.d.ts +12 -0
  116. package/dist/watch/dashboard-styles.js +20 -0
  117. package/dist/watch/dashboard-styles.js.map +1 -0
  118. package/dist/watch/dashboard.d.ts +12 -0
  119. package/dist/watch/dashboard.js +50 -0
  120. package/dist/watch/dashboard.js.map +1 -0
  121. package/dist/watch/git-utils.d.ts +36 -0
  122. package/dist/watch/git-utils.js +117 -0
  123. package/dist/watch/git-utils.js.map +1 -0
  124. package/dist/watch/hub-state.d.ts +39 -0
  125. package/dist/watch/hub-state.js +57 -0
  126. package/dist/watch/hub-state.js.map +1 -0
  127. package/dist/watch/hub.d.ts +2 -0
  128. package/dist/watch/hub.js +252 -0
  129. package/dist/watch/hub.js.map +1 -0
  130. package/dist/watch/log-utils.d.ts +13 -0
  131. package/dist/watch/log-utils.js +24 -0
  132. package/dist/watch/log-utils.js.map +1 -0
  133. package/dist/watch/notify.d.ts +18 -0
  134. package/dist/watch/notify.js +45 -0
  135. package/dist/watch/notify.js.map +1 -0
  136. package/dist/watch/state.d.ts +38 -0
  137. package/dist/watch/state.js +36 -0
  138. package/dist/watch/state.js.map +1 -0
  139. package/dist/watch/strategies/behind-default.d.ts +5 -0
  140. package/dist/watch/strategies/behind-default.js +21 -0
  141. package/dist/watch/strategies/behind-default.js.map +1 -0
  142. package/dist/watch/strategies/idle.d.ts +5 -0
  143. package/dist/watch/strategies/idle.js +21 -0
  144. package/dist/watch/strategies/idle.js.map +1 -0
  145. package/dist/watch/strategies/in-progress.d.ts +5 -0
  146. package/dist/watch/strategies/in-progress.js +21 -0
  147. package/dist/watch/strategies/in-progress.js.map +1 -0
  148. package/dist/watch/strategies/index.d.ts +34 -0
  149. package/dist/watch/strategies/index.js +148 -0
  150. package/dist/watch/strategies/index.js.map +1 -0
  151. package/dist/watch/strategies/jira-not-in-review.d.ts +2 -0
  152. package/dist/watch/strategies/jira-not-in-review.js +29 -0
  153. package/dist/watch/strategies/jira-not-in-review.js.map +1 -0
  154. package/dist/watch/strategies/jira-still-open.d.ts +2 -0
  155. package/dist/watch/strategies/jira-still-open.js +31 -0
  156. package/dist/watch/strategies/jira-still-open.js.map +1 -0
  157. package/dist/watch/strategies/mr-approval-optional.d.ts +5 -0
  158. package/dist/watch/strategies/mr-approval-optional.js +21 -0
  159. package/dist/watch/strategies/mr-approval-optional.js.map +1 -0
  160. package/dist/watch/strategies/mr-approved.d.ts +5 -0
  161. package/dist/watch/strategies/mr-approved.js +21 -0
  162. package/dist/watch/strategies/mr-approved.js.map +1 -0
  163. package/dist/watch/strategies/mr-conflicts.d.ts +5 -0
  164. package/dist/watch/strategies/mr-conflicts.js +21 -0
  165. package/dist/watch/strategies/mr-conflicts.js.map +1 -0
  166. package/dist/watch/strategies/mr-draft.d.ts +5 -0
  167. package/dist/watch/strategies/mr-draft.js +21 -0
  168. package/dist/watch/strategies/mr-draft.js.map +1 -0
  169. package/dist/watch/strategies/mr-open-comments.d.ts +5 -0
  170. package/dist/watch/strategies/mr-open-comments.js +21 -0
  171. package/dist/watch/strategies/mr-open-comments.js.map +1 -0
  172. package/dist/watch/strategies/narrative-missing.d.ts +5 -0
  173. package/dist/watch/strategies/narrative-missing.js +21 -0
  174. package/dist/watch/strategies/narrative-missing.js.map +1 -0
  175. package/dist/watch/strategies/no-mr.d.ts +5 -0
  176. package/dist/watch/strategies/no-mr.js +21 -0
  177. package/dist/watch/strategies/no-mr.js.map +1 -0
  178. package/dist/watch/strategies/pipeline-failed.d.ts +5 -0
  179. package/dist/watch/strategies/pipeline-failed.js +21 -0
  180. package/dist/watch/strategies/pipeline-failed.js.map +1 -0
  181. package/dist/watch/strategies/pipeline-running.d.ts +5 -0
  182. package/dist/watch/strategies/pipeline-running.js +21 -0
  183. package/dist/watch/strategies/pipeline-running.js.map +1 -0
  184. package/dist/watch/strategies/ready-for-release.d.ts +7 -0
  185. package/dist/watch/strategies/ready-for-release.js +35 -0
  186. package/dist/watch/strategies/ready-for-release.js.map +1 -0
  187. package/dist/watch/strategies/ready-to-commit.d.ts +5 -0
  188. package/dist/watch/strategies/ready-to-commit.js +21 -0
  189. package/dist/watch/strategies/ready-to-commit.js.map +1 -0
  190. package/dist/watch/strategies/ready-to-push.d.ts +5 -0
  191. package/dist/watch/strategies/ready-to-push.js +21 -0
  192. package/dist/watch/strategies/ready-to-push.js.map +1 -0
  193. package/dist/watch/strategies/released.d.ts +6 -0
  194. package/dist/watch/strategies/released.js +21 -0
  195. package/dist/watch/strategies/released.js.map +1 -0
  196. package/dist/watch/strategies/squash-merged.d.ts +6 -0
  197. package/dist/watch/strategies/squash-merged.js +21 -0
  198. package/dist/watch/strategies/squash-merged.js.map +1 -0
  199. package/dist/watch/strategies/types.d.ts +31 -0
  200. package/dist/watch/strategies/types.js +12 -0
  201. package/dist/watch/strategies/types.js.map +1 -0
  202. package/dist/watch/strategies/unstaged-changes.d.ts +5 -0
  203. package/dist/watch/strategies/unstaged-changes.js +21 -0
  204. package/dist/watch/strategies/unstaged-changes.js.map +1 -0
  205. package/dist/watch/strategies/wrong-branch.d.ts +6 -0
  206. package/dist/watch/strategies/wrong-branch.js +26 -0
  207. package/dist/watch/strategies/wrong-branch.js.map +1 -0
  208. package/dist/watch/types.d.ts +211 -0
  209. package/dist/watch/types.js +25 -0
  210. package/dist/watch/types.js.map +1 -0
  211. package/dist/watch/watcher-fs.d.ts +39 -0
  212. package/dist/watch/watcher-fs.js +105 -0
  213. package/dist/watch/watcher-fs.js.map +1 -0
  214. package/dist/watch/watcher-http.d.ts +19 -0
  215. package/dist/watch/watcher-http.js +47 -0
  216. package/dist/watch/watcher-http.js.map +1 -0
  217. package/dist/watch/watcher.d.ts +4 -0
  218. package/dist/watch/watcher.js +185 -0
  219. package/dist/watch/watcher.js.map +1 -0
  220. package/package.json +8 -2
  221. package/src/templates/about-watch.md +29 -0
  222. package/src/templates/hub.css +677 -0
  223. package/src/templates/hub.js +743 -0
  224. package/src/templates/qna.md +11 -0
  225. package/src/templates/steer.txt +2 -0
  226. package/src/templates/styles.css +53 -0
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Logbook entries collector for logbook watch.
3
+ *
4
+ * Reads the active lockfile, checks for narrative placeholders, and detects
5
+ * released entries. Runs on file-system events (instant feedback when the
6
+ * lockfile or entry files change).
7
+ */
8
+ import { existsSync, readFileSync } from 'node:fs';
9
+ import matter from 'gray-matter';
10
+ import { getConfig, GITLAB_PREFIX, getLogbookDirPath } from '../../lib/config.js';
11
+ import { getEntryFilePaths } from '../../lib/entry-paths.js';
12
+ import { getLastLogEntry } from '../log-utils.js';
13
+ import { resolveActiveTicketId, readActiveTicketSlug } from '../git-utils.js';
14
+ /** Check if the YAML frontmatter has any unfilled template placeholders. */
15
+ function hasPlaceholders(raw) {
16
+ try {
17
+ const parsed = matter(raw);
18
+ const data = parsed.data ?? {};
19
+ const placeholders = ['[PROMPTER]', '[HARNESS]', '[LLM]', '[WRITE_SUMMARY_HERE]'];
20
+ for (const val of Object.values(data)) {
21
+ if (typeof val === 'string' && placeholders.includes(val))
22
+ return true;
23
+ }
24
+ return false;
25
+ }
26
+ catch {
27
+ return false;
28
+ }
29
+ }
30
+ /** Check if dateEnd is set (i.e., entry is released). */
31
+ function isReleased(raw) {
32
+ try {
33
+ const parsed = matter(raw);
34
+ const dateEnd = parsed.data?.dateEnd;
35
+ if (!dateEnd)
36
+ return false;
37
+ const val = String(dateEnd).trim();
38
+ return val !== '' && val !== '[DATE_END]';
39
+ }
40
+ catch {
41
+ return false;
42
+ }
43
+ }
44
+ export const entriesCollector = {
45
+ name: 'entries',
46
+ schedule: { type: 'fs', patterns: ['**/log.md', '**/index.md', '**/ticket.md', '.logbook-active'] },
47
+ async available(_cwd) {
48
+ return true;
49
+ },
50
+ async collect(cwd, state) {
51
+ const config = getConfig(cwd);
52
+ const entriesDir = getLogbookDirPath(config, cwd);
53
+ const slug = readActiveTicketSlug(cwd);
54
+ if (slug) {
55
+ state.hasActiveTicket = true;
56
+ state.hasLockfile = true;
57
+ state.activeTicketSlug = slug;
58
+ state.activeTicketId = resolveActiveTicketId(cwd, state.branch, config.jiraPrefix, GITLAB_PREFIX);
59
+ const { log: logPath } = getEntryFilePaths(entriesDir, slug);
60
+ const logEntry = getLastLogEntry(logPath);
61
+ if (logEntry) {
62
+ state.latestLog = logEntry.message;
63
+ state.latestLogTimestamp = logEntry.timestamp;
64
+ state.lastActivityTimestamp = logEntry.timestamp;
65
+ }
66
+ const { index: indexPath } = getEntryFilePaths(entriesDir, slug);
67
+ if (existsSync(indexPath)) {
68
+ const raw = readFileSync(indexPath, 'utf8');
69
+ state.hasNarrativePlaceholders = hasPlaceholders(raw);
70
+ state.isReleased = isReleased(raw);
71
+ }
72
+ else {
73
+ state.hasNarrativePlaceholders = true;
74
+ state.isReleased = false;
75
+ }
76
+ }
77
+ else {
78
+ state.hasActiveTicket = false;
79
+ state.hasLockfile = false;
80
+ state.activeTicketSlug = undefined;
81
+ state.latestLog = undefined;
82
+ state.latestLogTimestamp = undefined;
83
+ state.hasNarrativePlaceholders = false;
84
+ state.isReleased = false;
85
+ state.activeTicketId = resolveActiveTicketId(cwd, state.branch, config.jiraPrefix, GITLAB_PREFIX);
86
+ state.hasActiveTicket = !!state.activeTicketId;
87
+ }
88
+ },
89
+ };
90
+ //# sourceMappingURL=entries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entries.js","sourceRoot":"","sources":["../../../src/watch/collectors/entries.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Git collector for logbook watch.
3
+ *
4
+ * Collects branch information, dirty state, and ahead/behind counts. Runs on
5
+ * file-system events (instant feedback when files change) and on interval
6
+ * (to catch remote state changes).
7
+ *
8
+ * Uses shared git-utils helpers to avoid duplication with the detail
9
+ * collector and other collectors.
10
+ */
11
+ import type { Collector } from './types.js';
12
+ export declare const gitCollector: Collector;
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Git collector for logbook watch.
3
+ *
4
+ * Collects branch information, dirty state, and ahead/behind counts. Runs on
5
+ * file-system events (instant feedback when files change) and on interval
6
+ * (to catch remote state changes).
7
+ *
8
+ * Uses shared git-utils helpers to avoid duplication with the detail
9
+ * collector and other collectors.
10
+ */
11
+ import { getCurrentBranch, getDefaultBranch } from '../../lib/git-helpers.js';
12
+ import { parseGitStatus, commitsAheadOfRemote, commitsVsDefault } from '../git-utils.js';
13
+ /** Check if a git repo exists at cwd. */
14
+ async function isGitRepo(cwd) {
15
+ try {
16
+ const { execSync } = await import('node:child_process');
17
+ execSync('git rev-parse --git-dir', {
18
+ cwd,
19
+ stdio: ['ignore', 'pipe', 'ignore'],
20
+ });
21
+ return true;
22
+ }
23
+ catch {
24
+ return false;
25
+ }
26
+ }
27
+ export const gitCollector = {
28
+ name: 'git',
29
+ schedule: { type: 'fs', patterns: ['**/*'] },
30
+ async available(cwd) {
31
+ return isGitRepo(cwd);
32
+ },
33
+ async collect(cwd, state) {
34
+ const branch = getCurrentBranch(cwd);
35
+ state.branch = branch;
36
+ const defaultBranch = getDefaultBranch(cwd);
37
+ state.defaultBranch = defaultBranch;
38
+ if (branch) {
39
+ const { staged, unstaged } = parseGitStatus(cwd);
40
+ state.stagedFiles = staged;
41
+ state.unstagedFiles = unstaged;
42
+ state.isDirty = staged > 0 || unstaged > 0;
43
+ state.isAheadOfRemote = commitsAheadOfRemote(cwd) > 0;
44
+ state.commitsBehindDefault = commitsVsDefault(cwd, defaultBranch);
45
+ }
46
+ else {
47
+ state.stagedFiles = 0;
48
+ state.unstagedFiles = 0;
49
+ state.isDirty = false;
50
+ state.isAheadOfRemote = false;
51
+ state.commitsBehindDefault = 0;
52
+ }
53
+ if (!state.lastActivityTimestamp) {
54
+ state.lastActivityTimestamp = new Date().toISOString();
55
+ }
56
+ },
57
+ };
58
+ //# sourceMappingURL=git.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../../../src/watch/collectors/git.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAG9E,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEzF,yCAAyC;AACzC,KAAK,UAAU,SAAS,CAAC,GAAW;IAClC,IAAI,CAAC;QACH,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;QACxD,QAAQ,CAAC,yBAAyB,EAAE;YAClC,GAAG;YACH,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;SACpC,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,YAAY,GAAc;IACrC,IAAI,EAAE,KAAK;IAEX,QAAQ,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,MAAM,CAAC,EAAE;IAE5C,KAAK,CAAC,SAAS,CAAC,GAAW;QACzB,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,GAAW,EAAE,KAAmB;QAC5C,MAAM,MAAM,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;QACrC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;QAEtB,MAAM,aAAa,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;QAC5C,KAAK,CAAC,aAAa,GAAG,aAAa,CAAC;QAEpC,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;YACjD,KAAK,CAAC,WAAW,GAAG,MAAM,CAAC;YAC3B,KAAK,CAAC,aAAa,GAAG,QAAQ,CAAC;YAC/B,KAAK,CAAC,OAAO,GAAG,MAAM,GAAG,CAAC,IAAI,QAAQ,GAAG,CAAC,CAAC;YAE3C,KAAK,CAAC,eAAe,GAAG,oBAAoB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACtD,KAAK,CAAC,oBAAoB,GAAG,gBAAgB,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;QACpE,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,WAAW,GAAG,CAAC,CAAC;YACtB,KAAK,CAAC,aAAa,GAAG,CAAC,CAAC;YACxB,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC;YACtB,KAAK,CAAC,eAAe,GAAG,KAAK,CAAC;YAC9B,KAAK,CAAC,oBAAoB,GAAG,CAAC,CAAC;QACjC,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,qBAAqB,EAAE,CAAC;YACjC,KAAK,CAAC,qBAAqB,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACzD,CAAC;IACH,CAAC;CACF,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * GitLab collector for logbook watch.
3
+ *
4
+ * Uses the `glab` CLI to query merge requests and pipeline status for the
5
+ * current branch. Runs on interval (30s) since it calls an external API.
6
+ *
7
+ * Falls back gracefully when `glab` is not installed or not authenticated.
8
+ */
9
+ import type { Collector } from './types.js';
10
+ export declare const glabCollector: Collector;
@@ -0,0 +1,273 @@
1
+ /* eslint-disable max-lines */
2
+ /**
3
+ * GitLab collector for logbook watch.
4
+ *
5
+ * Uses the `glab` CLI to query merge requests and pipeline status for the
6
+ * current branch. Runs on interval (30s) since it calls an external API.
7
+ *
8
+ * Falls back gracefully when `glab` is not installed or not authenticated.
9
+ */
10
+ import { execSync } from 'node:child_process';
11
+ import { getCurrentBranch } from '../../lib/git-helpers.js';
12
+ import { getDefaultBranch } from '../../lib/git-helpers.js';
13
+ import { logTime } from '../watcher-http.js';
14
+ import { parsePipelineStatus } from './type-guards.js';
15
+ /** Debug log with the same timestamp prefix as the watcher. */
16
+ function dbg(msg) {
17
+ console.log(`[${logTime()}] [glab] ${msg}`);
18
+ }
19
+ /** Check if glab CLI is available and authenticated. */
20
+ async function isGlabAvailable() {
21
+ try {
22
+ execSync('glab --version', {
23
+ stdio: ['ignore', 'pipe', 'ignore'],
24
+ });
25
+ // Check auth status — "glab auth status" exits 0 when logged in.
26
+ execSync('glab auth status', {
27
+ stdio: ['ignore', 'pipe', 'ignore'],
28
+ });
29
+ return true;
30
+ }
31
+ catch {
32
+ return false;
33
+ }
34
+ }
35
+ /** Format an execSync error, preferring stderr for a real glab message. */
36
+ function formatGitError(err) {
37
+ if (!err || typeof err !== 'object')
38
+ return String(err);
39
+ if ('stderr' in err && typeof err.stderr === 'object' && err.stderr !== null) {
40
+ const line = String(err.stderr);
41
+ if (line.trim())
42
+ return line.trim();
43
+ }
44
+ if ('message' in err && typeof err.message === 'string') {
45
+ return err.message;
46
+ }
47
+ return String(err);
48
+ }
49
+ /** Resolve the git remote origin that glab will use to pick the project. */
50
+ function getRemoteUrl(cwd) {
51
+ try {
52
+ return execSync('git remote get-url origin', {
53
+ encoding: 'utf8',
54
+ cwd,
55
+ stdio: ['ignore', 'pipe', 'ignore'],
56
+ }).trim();
57
+ }
58
+ catch {
59
+ return '(no origin remote) ';
60
+ }
61
+ }
62
+ /** Fetch open MRs from glab. Returns null on command failure (caller keeps last known state). */
63
+ function fetchMrs(cwd) {
64
+ try {
65
+ // `glab mr list` has no --state flag on this version; open is the default.
66
+ const output = execSync('glab mr list --output json --per-page 100', {
67
+ encoding: 'utf8',
68
+ cwd,
69
+ stdio: ['ignore', 'pipe', 'ignore'],
70
+ }).trim();
71
+ if (!output)
72
+ return [];
73
+ const items = JSON.parse(output);
74
+ return items;
75
+ }
76
+ catch (err) {
77
+ dbg(`mr list failed: ${formatGitError(err)}`);
78
+ return null;
79
+ }
80
+ }
81
+ /** Fetch pipeline status for the current branch. */
82
+ function fetchPipelineStatus(cwd, branch) {
83
+ try {
84
+ const output = execSync(`glab ci status --branch "${branch}" --output json`, {
85
+ encoding: 'utf8',
86
+ cwd,
87
+ stdio: ['ignore', 'pipe', 'ignore'],
88
+ }).trim();
89
+ if (!output)
90
+ return 'none';
91
+ const parsed = JSON.parse(output);
92
+ return parsePipelineStatus(parsed.status);
93
+ }
94
+ catch {
95
+ return 'none';
96
+ }
97
+ }
98
+ /** Check if branch has recent running/failed pipelines via glab pipeline list. */
99
+ function hasRecentPipeline(cwd, branch, status) {
100
+ try {
101
+ const output = execSync(`glab pipeline list --branch "${branch}" --output json --per-page 5`, {
102
+ encoding: 'utf8',
103
+ cwd,
104
+ stdio: ['ignore', 'pipe', 'ignore'],
105
+ }).trim();
106
+ if (!output)
107
+ return false;
108
+ const pipelines = JSON.parse(output);
109
+ return pipelines.some((p) => p.status === status);
110
+ }
111
+ catch {
112
+ return false;
113
+ }
114
+ }
115
+ /** Fetch open work items (issues) for the current project from glab. Null on failure. */
116
+ function fetchWorkItems(cwd) {
117
+ try {
118
+ // open is the default state; --per-page lifts the default 30-item cap.
119
+ const output = execSync('glab issue list --output json --per-page 100', {
120
+ encoding: 'utf8',
121
+ cwd,
122
+ stdio: ['ignore', 'pipe', 'ignore'],
123
+ }).trim();
124
+ if (!output) {
125
+ dbg('issue list returned empty output');
126
+ return [];
127
+ }
128
+ const items = JSON.parse(output);
129
+ return items.map((it) => {
130
+ const url = it.web_url ?? '';
131
+ const projectUrl = url.replace(/\/-\/(?:issues|work_items)\/\d+$/, '');
132
+ return {
133
+ iid: it.iid,
134
+ title: it.title,
135
+ status: it.state,
136
+ url,
137
+ projectUrl,
138
+ projectName: projectUrl.split('/').pop() ?? '',
139
+ updated: it.updated_at ?? '',
140
+ };
141
+ });
142
+ }
143
+ catch (err) {
144
+ dbg(`issue list failed: ${formatGitError(err)}`);
145
+ return null;
146
+ }
147
+ }
148
+ /** Determine MR status from a glab MR item. */
149
+ function determineMrStatus(mr, _branch) {
150
+ if (mr.state === 'merged')
151
+ return 'merged';
152
+ if (mr.state === 'closed')
153
+ return 'none';
154
+ // Draft check (GitLab 14+)
155
+ if (mr.draft === true)
156
+ return 'draft';
157
+ // Conflicts detection
158
+ if (mr.conflicts)
159
+ return 'open';
160
+ // Approval-based status
161
+ const approvalsLeft = mr.approvals_left ?? 0;
162
+ const approvalsRequired = mr.approvals_required ?? 0;
163
+ const changesRequested = (mr.reviewers ?? []).some((r) => r.state === 'CHANGED');
164
+ if (approvalsRequired > 0 && approvalsLeft === 0 && !changesRequested) {
165
+ return 'approved';
166
+ }
167
+ if (approvalsRequired === 0) {
168
+ return 'approval-optional';
169
+ }
170
+ if (changesRequested) {
171
+ return 'changes-requested';
172
+ }
173
+ // Open comments detection
174
+ if (mr.merge_status === 'cannot_be_merged') {
175
+ return 'open';
176
+ }
177
+ return 'open';
178
+ }
179
+ export const glabCollector = {
180
+ name: 'glab',
181
+ schedule: { type: 'interval', ms: 30_000 },
182
+ async available(_cwd) {
183
+ return isGlabAvailable();
184
+ },
185
+ async collect(cwd, state) {
186
+ const branch = getCurrentBranch(cwd);
187
+ if (!branch)
188
+ return;
189
+ const remote = getRemoteUrl(cwd);
190
+ dbg(`project remote: ${remote} (branch '${branch}')`);
191
+ try {
192
+ // All open MRs for the project (drives the GitLab tab).
193
+ const allMrs = fetchMrs(cwd);
194
+ if (allMrs === null) {
195
+ // Fetch failed (transient/API) — keep last known MR state instead of wiping it.
196
+ dbg('mr list unavailable — preserving last known MR state');
197
+ return;
198
+ }
199
+ dbg(`fetched ${allMrs.length} open MR(s) for the project`);
200
+ state.glabLastUpdated = new Date().toISOString();
201
+ // Branch-specific card status uses open MRs for the current branch.
202
+ const mrs = allMrs.filter((mr) => mr.source_branch === branch).sort((a, b) => b.iid - a.iid);
203
+ dbg(`${mrs.length} MR(s) for current branch`);
204
+ if (mrs.length === 0) {
205
+ state.mrStatus = 'none';
206
+ state.mrUrl = undefined;
207
+ state.mrTitle = undefined;
208
+ state.mrOpenThreads = undefined;
209
+ state.mrHasConflicts = undefined;
210
+ state.pipelineStatus = 'none';
211
+ }
212
+ else {
213
+ const mr = mrs[0];
214
+ // Check pipeline status via mr head_pipeline first, fall back to ci status
215
+ if (mr.head_pipeline) {
216
+ state.pipelineStatus = parsePipelineStatus(mr.head_pipeline.status);
217
+ }
218
+ else {
219
+ state.pipelineStatus = fetchPipelineStatus(cwd, branch);
220
+ }
221
+ // Fallback: check for recent running/failed pipelines if head_pipeline is stale
222
+ if (state.pipelineStatus === 'none' || state.pipelineStatus === 'passed') {
223
+ const defaultBranch = getDefaultBranch(cwd);
224
+ if (branch !== defaultBranch) {
225
+ if (hasRecentPipeline(cwd, branch, 'running')) {
226
+ state.pipelineStatus = 'running';
227
+ }
228
+ else if (hasRecentPipeline(cwd, branch, 'failed')) {
229
+ state.pipelineStatus = 'failed';
230
+ }
231
+ }
232
+ }
233
+ state.mrStatus = determineMrStatus(mr, branch);
234
+ state.mrUrl = mr.web_url;
235
+ state.mrTitle = mr.title;
236
+ state.mrHasConflicts = mr.conflicts;
237
+ // Count open threads (note_count - resolved)
238
+ state.mrOpenThreads = 0;
239
+ }
240
+ dbg(`branch mrStatus='${state.mrStatus ?? 'none'}' mrUrl=${state.mrUrl ?? '(none)'}`);
241
+ // Build full MR list for the GitLab tab (ALL MRs for the project).
242
+ const projectUrl = allMrs[0]?.web_url ? allMrs[0].web_url.replace(/\/-\/merge_requests\/\d+$/, '') : '';
243
+ state.glabOpenMrs = allMrs.map((item) => ({
244
+ iid: item.iid,
245
+ title: item.title,
246
+ status: item.state,
247
+ comments: 0,
248
+ url: item.web_url,
249
+ sourceBranch: item.source_branch,
250
+ projectUrl: projectUrl ? projectUrl : item.web_url.replace(/\/-\/merge_requests\/\d+$/, ''),
251
+ projectName: projectUrl
252
+ .split('/')
253
+ .pop()
254
+ ?.replace(/\.git$/, '') ?? '',
255
+ }));
256
+ dbg(`glabOpenMrs has ${state.glabOpenMrs.length} entry/entries`);
257
+ // Open work items (issues) for the current project.
258
+ const workItems = fetchWorkItems(cwd);
259
+ if (workItems === null) {
260
+ dbg('work item list unavailable — preserving last known work item state');
261
+ }
262
+ else {
263
+ state.glabWorkItems = workItems;
264
+ state.glabWorkItemsLastUpdated = new Date().toISOString();
265
+ dbg(`glabWorkItems has ${workItems.length} entry/entries`);
266
+ }
267
+ }
268
+ catch (err) {
269
+ dbg(`collect failed: ${err instanceof Error ? err.message : String(err)}`);
270
+ }
271
+ },
272
+ };
273
+ //# sourceMappingURL=glab.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glab.js","sourceRoot":"","sources":["../../../src/watch/collectors/glab.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Collector registry for logbook watch.
3
+ *
4
+ * Exports all available collectors. The watcher runner checks `available()`
5
+ * for each and only activates those whose prerequisites are met.
6
+ */
7
+ import type { Collector } from './types.js';
8
+ /** All registered collectors. */
9
+ /** acli takes priority over jira when both are available — order matters. */
10
+ export declare const ALL_COLLECTORS: Collector[];
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Collector registry for logbook watch.
3
+ *
4
+ * Exports all available collectors. The watcher runner checks `available()`
5
+ * for each and only activates those whose prerequisites are met.
6
+ */
7
+ import { gitCollector } from './git.js';
8
+ import { entriesCollector } from './entries.js';
9
+ import { glabCollector } from './glab.js';
10
+ import { acliCollector } from './acli.js';
11
+ import { jiraCollector } from './jira.js';
12
+ /** All registered collectors. */
13
+ /** acli takes priority over jira when both are available — order matters. */
14
+ export const ALL_COLLECTORS = [
15
+ gitCollector,
16
+ entriesCollector,
17
+ glabCollector,
18
+ acliCollector,
19
+ jiraCollector,
20
+ ];
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/watch/collectors/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C,iCAAiC;AACjC,6EAA6E;AAC7E,MAAM,CAAC,MAAM,cAAc,GAAgB;IACzC,YAAY;IACZ,gBAAgB;IAChB,aAAa;IACb,aAAa;IACb,aAAa;CACd,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** HTTP Jira collector — fallback when acli is not available. */
2
+ import type { Collector } from './types.js';
3
+ export declare const jiraCollector: Collector;
@@ -0,0 +1,111 @@
1
+ /** HTTP Jira collector — fallback when acli is not available. */
2
+ import { request } from 'node:https';
3
+ import { execSync } from 'node:child_process';
4
+ import { getConfig, GITLAB_PREFIX } from '../../lib/config.js';
5
+ import { getCurrentBranch } from '../../lib/git-helpers.js';
6
+ import { extractTicketFromBranch } from '../git-utils.js';
7
+ import { isJiraIssue } from './type-guards.js';
8
+ function buildAssignedJql(accountId) {
9
+ return `assignee = "${accountId}" AND resolution = Unresolved ORDER BY updated DESC`;
10
+ }
11
+ function httpGet(url, token, timeout = 5000) {
12
+ return new Promise((resolve) => {
13
+ const req = request(url, { method: 'GET', headers: { Authorization: `Bearer ${token}`, Accept: 'application/json' }, timeout }, (res) => {
14
+ const chunks = [];
15
+ res.on('data', (chunk) => chunks.push(chunk));
16
+ res.on('end', () => {
17
+ if (res.statusCode !== 200) {
18
+ resolve(null);
19
+ return;
20
+ }
21
+ try {
22
+ const parsed = JSON.parse(Buffer.concat(chunks).toString('utf8'));
23
+ resolve(parsed);
24
+ }
25
+ catch {
26
+ resolve(null);
27
+ }
28
+ });
29
+ });
30
+ req.on('error', () => resolve(null));
31
+ req.on('timeout', () => {
32
+ req.destroy();
33
+ resolve(null);
34
+ });
35
+ req.end();
36
+ });
37
+ }
38
+ function fetchMyself(baseUrl, token) {
39
+ return httpGet(new URL('/rest/api/3/myself', baseUrl), token, 5000);
40
+ }
41
+ function searchIssues(baseUrl, token, jql) {
42
+ const url = new URL('/rest/api/3/search', baseUrl);
43
+ url.searchParams.set('jql', jql);
44
+ url.searchParams.set('fields', 'summary,status,updated,assignee');
45
+ url.searchParams.set('maxResults', '50');
46
+ return httpGet(url, token, 10_000).then((body) => {
47
+ const issues = (body?.issues ?? []).filter(isJiraIssue);
48
+ return issues;
49
+ });
50
+ }
51
+ function fetchIssue(baseUrl, token, issueKey) {
52
+ const url = new URL(`/rest/api/3/issue/${issueKey}`, baseUrl);
53
+ url.searchParams.set('fields', 'summary,status,updated,assignee');
54
+ return httpGet(url, token, 5000).then((body) => (body && isJiraIssue(body) ? body : null));
55
+ }
56
+ function getJiraToken() {
57
+ return process.env.JIRA_API_TOKEN;
58
+ }
59
+ export const jiraCollector = {
60
+ name: 'jira',
61
+ schedule: { type: 'interval', ms: 60_000 },
62
+ async available(_cwd) {
63
+ if (!getJiraToken())
64
+ return false;
65
+ try {
66
+ execSync('which acli', { stdio: ['ignore', 'pipe', 'ignore'] });
67
+ return false;
68
+ }
69
+ catch {
70
+ return true;
71
+ }
72
+ },
73
+ async collect(cwd, state) {
74
+ try {
75
+ const config = getConfig(cwd);
76
+ const baseUrl = config.jiraBaseUrl;
77
+ const token = getJiraToken();
78
+ if (!baseUrl || !token) {
79
+ state.jiraStatus = undefined;
80
+ state.jiraAssignedIssues = [];
81
+ state.jiraLastUpdated = new Date().toISOString();
82
+ return;
83
+ }
84
+ const myself = await fetchMyself(baseUrl, token);
85
+ if (!myself) {
86
+ state.jiraAssignedIssues = [];
87
+ state.jiraLastUpdated = new Date().toISOString();
88
+ return;
89
+ }
90
+ const rawIssues = await searchIssues(baseUrl, token, buildAssignedJql(myself.accountId));
91
+ state.jiraAssignedIssues = rawIssues.map((issue) => ({
92
+ key: issue.key,
93
+ summary: issue.fields.summary,
94
+ status: issue.fields.status.name,
95
+ url: `${baseUrl}/browse/${issue.key}`,
96
+ jiraBaseUrl: baseUrl,
97
+ updated: issue.fields.updated,
98
+ }));
99
+ const branch = getCurrentBranch(cwd);
100
+ const ticketKey = state.activeTicketId ??
101
+ (branch ? extractTicketFromBranch(branch, config.jiraPrefix, GITLAB_PREFIX) : undefined);
102
+ if (ticketKey) {
103
+ const issue = await fetchIssue(baseUrl, token, ticketKey);
104
+ state.jiraStatus = issue?.fields.status.name;
105
+ }
106
+ state.jiraLastUpdated = new Date().toISOString();
107
+ }
108
+ catch { }
109
+ },
110
+ };
111
+ //# sourceMappingURL=jira.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jira.js","sourceRoot":"","sources":["../../../src/watch/collectors/jira.ts"],"names":[],"mappings":"AAAA,iEAAiE;AAEjE,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAG1D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAkB/C,SAAS,gBAAgB,CAAC,SAAiB;IACzC,OAAO,eAAe,SAAS,qDAAqD,CAAC;AACvF,CAAC;AAED,SAAS,OAAO,CAAI,GAAQ,EAAE,KAAa,EAAE,OAAO,GAAG,IAAI;IACzD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,GAAG,GAAG,OAAO,CACjB,GAAG,EACH,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE,EAAE,OAAO,EAAE,EACrG,CAAC,GAAG,EAAE,EAAE;YACN,MAAM,MAAM,GAAa,EAAE,CAAC;YAC5B,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YACtD,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;gBACjB,IAAI,GAAG,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;oBAC3B,OAAO,CAAC,IAAI,CAAC,CAAC;oBACd,OAAO;gBACT,CAAC;gBACD,IAAI,CAAC;oBACH,MAAM,MAAM,GAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;oBACrE,OAAO,CAAC,MAAM,CAAC,CAAC;gBAClB,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO,CAAC,IAAI,CAAC,CAAC;gBAChB,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CACF,CAAC;QACF,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QACrC,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;YACrB,GAAG,CAAC,OAAO,EAAE,CAAC;YACd,OAAO,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC,CAAC,CAAC;QACH,GAAG,CAAC,GAAG,EAAE,CAAC;IACZ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,WAAW,CAAC,OAAe,EAAE,KAAa;IACjD,OAAO,OAAO,CAAC,IAAI,GAAG,CAAC,oBAAoB,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;AACtE,CAAC;AAED,SAAS,YAAY,CAAC,OAAe,EAAE,KAAa,EAAE,GAAW;IAC/D,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,oBAAoB,EAAE,OAAO,CAAC,CAAC;IACnD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACjC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,iCAAiC,CAAC,CAAC;IAClE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;IACzC,OAAO,OAAO,CAAqB,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;QACnE,MAAM,MAAM,GAAmB,CAAC,IAAI,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACxE,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,UAAU,CAAC,OAAe,EAAE,KAAa,EAAE,QAAgB;IAClE,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,qBAAqB,QAAQ,EAAE,EAAE,OAAO,CAAC,CAAC;IAC9D,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,iCAAiC,CAAC,CAAC;IAClE,OAAO,OAAO,CAAe,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAC3G,CAAC;AAED,SAAS,YAAY;IACnB,OAAO,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;AACpC,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAc;IACtC,IAAI,EAAE,MAAM;IACZ,QAAQ,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,EAAE;IAC1C,KAAK,CAAC,SAAS,CAAC,IAAY;QAC1B,IAAI,CAAC,YAAY,EAAE;YAAE,OAAO,KAAK,CAAC;QAClC,IAAI,CAAC;YACH,QAAQ,CAAC,YAAY,EAAE,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;YAChE,OAAO,KAAK,CAAC;QACf,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,KAAK,CAAC,OAAO,CAAC,GAAW,EAAE,KAAmB;QAC5C,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;YAC9B,MAAM,OAAO,GAAG,MAAM,CAAC,WAAW,CAAC;YACnC,MAAM,KAAK,GAAG,YAAY,EAAE,CAAC;YAC7B,IAAI,CAAC,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC;gBACvB,KAAK,CAAC,UAAU,GAAG,SAAS,CAAC;gBAC7B,KAAK,CAAC,kBAAkB,GAAG,EAAE,CAAC;gBAC9B,KAAK,CAAC,eAAe,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;gBACjD,OAAO;YACT,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YACjD,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,KAAK,CAAC,kBAAkB,GAAG,EAAE,CAAC;gBAC9B,KAAK,CAAC,eAAe,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;gBACjD,OAAO;YACT,CAAC;YACD,MAAM,SAAS,GAAG,MAAM,YAAY,CAAC,OAAO,EAAE,KAAK,EAAE,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;YACzF,KAAK,CAAC,kBAAkB,GAAG,SAAS,CAAC,GAAG,CACtC,CAAC,KAAK,EAAa,EAAE,CAAC,CAAC;gBACrB,GAAG,EAAE,KAAK,CAAC,GAAG;gBACd,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO;gBAC7B,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI;gBAChC,GAAG,EAAE,GAAG,OAAO,WAAW,KAAK,CAAC,GAAG,EAAE;gBACrC,WAAW,EAAE,OAAO;gBACpB,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO;aAC9B,CAAC,CACH,CAAC;YACF,MAAM,MAAM,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;YACrC,MAAM,SAAS,GACb,KAAK,CAAC,cAAc;gBACpB,CAAC,MAAM,CAAC,CAAC,CAAC,uBAAuB,CAAC,MAAM,EAAE,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;YAC3F,IAAI,SAAS,EAAE,CAAC;gBACd,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;gBAC1D,KAAK,CAAC,UAAU,GAAG,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;YAC/C,CAAC;YACD,KAAK,CAAC,eAAe,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACnD,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC;CACF,CAAC"}
@@ -0,0 +1,17 @@
1
+ /** Type guards for GitLab and Jira API response types. */
2
+ interface JiraIssueRaw {
3
+ key: string;
4
+ fields: {
5
+ summary: string;
6
+ status: {
7
+ name: string;
8
+ };
9
+ updated: string;
10
+ assignee: {
11
+ displayName: string;
12
+ } | null;
13
+ };
14
+ }
15
+ export declare function isJiraIssue(value: unknown): value is JiraIssueRaw;
16
+ export declare function parsePipelineStatus(status: string): 'running' | 'passed' | 'failed' | 'pending' | 'canceled' | 'none';
17
+ export {};