chief-clancy 0.5.12 → 0.7.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 (102) hide show
  1. package/README.md +15 -8
  2. package/dist/bundle/clancy-afk.js +6 -2
  3. package/dist/bundle/clancy-once.js +71 -48
  4. package/dist/installer/hook-installer/hook-installer.d.ts +2 -0
  5. package/dist/installer/hook-installer/hook-installer.d.ts.map +1 -1
  6. package/dist/installer/hook-installer/hook-installer.js +36 -1
  7. package/dist/installer/hook-installer/hook-installer.js.map +1 -1
  8. package/dist/installer/install.js +16 -1
  9. package/dist/installer/install.js.map +1 -1
  10. package/dist/schemas/env.d.ts +36 -0
  11. package/dist/schemas/env.d.ts.map +1 -1
  12. package/dist/schemas/env.js +11 -0
  13. package/dist/schemas/env.js.map +1 -1
  14. package/dist/schemas/github-issues.d.ts +6 -0
  15. package/dist/schemas/github-issues.d.ts.map +1 -1
  16. package/dist/schemas/github-issues.js +3 -0
  17. package/dist/schemas/github-issues.js.map +1 -1
  18. package/dist/schemas/jira.d.ts +21 -0
  19. package/dist/schemas/jira.d.ts.map +1 -1
  20. package/dist/schemas/jira.js +18 -0
  21. package/dist/schemas/jira.js.map +1 -1
  22. package/dist/schemas/linear.d.ts +41 -0
  23. package/dist/schemas/linear.d.ts.map +1 -1
  24. package/dist/schemas/linear.js +34 -0
  25. package/dist/schemas/linear.js.map +1 -1
  26. package/dist/scripts/afk/afk.d.ts.map +1 -1
  27. package/dist/scripts/afk/afk.js +28 -0
  28. package/dist/scripts/afk/afk.js.map +1 -1
  29. package/dist/scripts/afk/report/report.d.ts +47 -0
  30. package/dist/scripts/afk/report/report.d.ts.map +1 -0
  31. package/dist/scripts/afk/report/report.js +194 -0
  32. package/dist/scripts/afk/report/report.js.map +1 -0
  33. package/dist/scripts/board/github/github.d.ts +33 -3
  34. package/dist/scripts/board/github/github.d.ts.map +1 -1
  35. package/dist/scripts/board/github/github.js +112 -27
  36. package/dist/scripts/board/github/github.js.map +1 -1
  37. package/dist/scripts/board/jira/jira.d.ts +36 -4
  38. package/dist/scripts/board/jira/jira.d.ts.map +1 -1
  39. package/dist/scripts/board/jira/jira.js +138 -65
  40. package/dist/scripts/board/jira/jira.js.map +1 -1
  41. package/dist/scripts/board/linear/linear.d.ts +32 -5
  42. package/dist/scripts/board/linear/linear.d.ts.map +1 -1
  43. package/dist/scripts/board/linear/linear.js +135 -17
  44. package/dist/scripts/board/linear/linear.js.map +1 -1
  45. package/dist/scripts/once/board-ops/board-ops.d.ts.map +1 -1
  46. package/dist/scripts/once/board-ops/board-ops.js +1 -1
  47. package/dist/scripts/once/board-ops/board-ops.js.map +1 -1
  48. package/dist/scripts/once/cost/cost.d.ts +10 -0
  49. package/dist/scripts/once/cost/cost.d.ts.map +1 -0
  50. package/dist/scripts/once/cost/cost.js +23 -0
  51. package/dist/scripts/once/cost/cost.js.map +1 -0
  52. package/dist/scripts/once/deliver/deliver.d.ts.map +1 -1
  53. package/dist/scripts/once/deliver/deliver.js +18 -1
  54. package/dist/scripts/once/deliver/deliver.js.map +1 -1
  55. package/dist/scripts/once/fetch-ticket/fetch-ticket.d.ts +19 -1
  56. package/dist/scripts/once/fetch-ticket/fetch-ticket.d.ts.map +1 -1
  57. package/dist/scripts/once/fetch-ticket/fetch-ticket.js +93 -29
  58. package/dist/scripts/once/fetch-ticket/fetch-ticket.js.map +1 -1
  59. package/dist/scripts/once/lock/lock.d.ts +17 -0
  60. package/dist/scripts/once/lock/lock.d.ts.map +1 -0
  61. package/dist/scripts/once/lock/lock.js +70 -0
  62. package/dist/scripts/once/lock/lock.js.map +1 -0
  63. package/dist/scripts/once/once.d.ts.map +1 -1
  64. package/dist/scripts/once/once.js +100 -4
  65. package/dist/scripts/once/once.js.map +1 -1
  66. package/dist/scripts/once/resume/resume.d.ts +24 -0
  67. package/dist/scripts/once/resume/resume.d.ts.map +1 -0
  68. package/dist/scripts/once/resume/resume.js +159 -0
  69. package/dist/scripts/once/resume/resume.js.map +1 -0
  70. package/dist/scripts/shared/format/format.d.ts.map +1 -1
  71. package/dist/scripts/shared/format/format.js +6 -1
  72. package/dist/scripts/shared/format/format.js.map +1 -1
  73. package/dist/scripts/shared/progress/progress.d.ts +18 -2
  74. package/dist/scripts/shared/progress/progress.d.ts.map +1 -1
  75. package/dist/scripts/shared/progress/progress.js +31 -4
  76. package/dist/scripts/shared/progress/progress.js.map +1 -1
  77. package/dist/scripts/shared/pull-request/pr-body/pr-body.d.ts +2 -1
  78. package/dist/scripts/shared/pull-request/pr-body/pr-body.d.ts.map +1 -1
  79. package/dist/scripts/shared/pull-request/pr-body/pr-body.js +10 -1
  80. package/dist/scripts/shared/pull-request/pr-body/pr-body.js.map +1 -1
  81. package/dist/types/remote.d.ts +1 -1
  82. package/dist/types/remote.d.ts.map +1 -1
  83. package/hooks/clancy-branch-guard.js +129 -0
  84. package/hooks/clancy-check-update.js +43 -0
  85. package/hooks/clancy-context-monitor.js +134 -46
  86. package/hooks/clancy-post-compact.js +53 -0
  87. package/hooks/package.json +3 -0
  88. package/package.json +3 -2
  89. package/src/agents/devils-advocate.md +53 -0
  90. package/src/agents/verification-gate.md +128 -0
  91. package/src/roles/planner/workflows/approve-plan.md +2 -2
  92. package/src/roles/reviewer/workflows/logs.md +9 -6
  93. package/src/roles/setup/commands/help.md +7 -0
  94. package/src/roles/setup/workflows/init.md +111 -6
  95. package/src/roles/setup/workflows/scaffold.md +57 -0
  96. package/src/roles/setup/workflows/settings.md +145 -0
  97. package/src/roles/setup/workflows/update.md +18 -0
  98. package/src/roles/strategist/commands/approve-brief.md +20 -0
  99. package/src/roles/strategist/commands/brief.md +27 -0
  100. package/src/roles/strategist/workflows/approve-brief.md +763 -0
  101. package/src/roles/strategist/workflows/brief.md +732 -0
  102. package/src/templates/CLAUDE.md +8 -1
@@ -11,7 +11,9 @@ import { dirname, join, resolve } from 'node:path';
11
11
  import { setTimeout as sleep } from 'node:timers/promises';
12
12
  import { fileURLToPath } from 'node:url';
13
13
  import { formatDuration } from '../../scripts/shared/format/format.js';
14
+ import { sendNotification } from '../../scripts/shared/notify/notify.js';
14
15
  import { bold, dim, green, red } from '../../utils/ansi/ansi.js';
16
+ import { generateSessionReport } from './report/report.js';
15
17
  /** Stop condition patterns matched against script output. */
16
18
  const STOP_PATTERNS = {
17
19
  noTickets: /No tickets found|No issues found|All done/,
@@ -75,6 +77,7 @@ export async function runAfkLoop(scriptDir, maxIterations = 5) {
75
77
  encoding: 'utf8',
76
78
  stdio: ['inherit', 'pipe', 'inherit'],
77
79
  cwd: process.cwd(),
80
+ env: { ...process.env, CLANCY_AFK_MODE: '1' },
78
81
  });
79
82
  const output = result.stdout ?? '';
80
83
  if (output) {
@@ -92,6 +95,7 @@ export async function runAfkLoop(scriptDir, maxIterations = 5) {
92
95
  console.log(dim(` Iteration ${i} took ${iterElapsed}`));
93
96
  console.log(`\n${condition.reason}`);
94
97
  console.log(dim(` Total: ${i} iteration${i > 1 ? 's' : ''} in ${totalElapsed}`));
98
+ generateAndSendReport(loopStart);
95
99
  return;
96
100
  }
97
101
  console.log(dim(` Iteration ${i} took ${iterElapsed}`));
@@ -106,6 +110,30 @@ export async function runAfkLoop(scriptDir, maxIterations = 5) {
106
110
  dim(` (${totalElapsed})`));
107
111
  console.log(dim(' "That\'s some good police work."'));
108
112
  console.log(dim(' Run clancy-afk again to continue.'));
113
+ generateAndSendReport(loopStart);
114
+ }
115
+ /**
116
+ * Generate a session report and optionally send a webhook notification.
117
+ */
118
+ function generateAndSendReport(loopStart) {
119
+ try {
120
+ const report = generateSessionReport(process.cwd(), loopStart, Date.now());
121
+ console.log('');
122
+ console.log(dim('─── Session Report ───'));
123
+ console.log(report);
124
+ const webhook = process.env.CLANCY_NOTIFY_WEBHOOK;
125
+ if (webhook) {
126
+ const lines = report.split('\n');
127
+ const summaryLines = lines.filter((l) => l.startsWith('- Tickets') || l.startsWith('- Total'));
128
+ const summary = `Clancy AFK: ${summaryLines.join('. ')}. Report: .clancy/session-report.md`;
129
+ sendNotification(webhook, summary).catch(() => {
130
+ // Best-effort — webhook failure shouldn't crash
131
+ });
132
+ }
133
+ }
134
+ catch {
135
+ // Best-effort — report generation failure shouldn't crash the loop
136
+ }
109
137
  }
110
138
  // Main guard — self-execute when run directly (e.g. node .clancy/clancy-afk.js)
111
139
  if (process.argv[1] &&
@@ -1 +1 @@
1
- {"version":3,"file":"afk.js","sourceRoot":"","sources":["../../../src/scripts/afk/afk.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"afk.js","sourceRoot":"","sources":["../../../src/scripts/afk/afk.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /** A parsed cost entry from costs.log. */
2
+ export type CostEntry = {
3
+ timestamp: string;
4
+ key: string;
5
+ duration: string;
6
+ tokens: string;
7
+ };
8
+ /** A ticket in the session report. */
9
+ export type SessionTicket = {
10
+ key: string;
11
+ summary: string;
12
+ status: string;
13
+ prNumber?: number;
14
+ duration?: string;
15
+ tokens?: string;
16
+ };
17
+ /**
18
+ * Parse costs.log and return entries with ISO timestamp >= the given threshold.
19
+ *
20
+ * Each line is expected to follow the format:
21
+ * `ISO-timestamp | KEY | Nmin | ~N tokens (estimated)`
22
+ *
23
+ * Lines that don't match are silently skipped.
24
+ *
25
+ * @param projectRoot - The project root directory.
26
+ * @param sinceMs - Only include entries with timestamp >= this value (ms since epoch).
27
+ * @returns Parsed cost entries from this session.
28
+ */
29
+ export declare function parseCostsLog(projectRoot: string, sinceMs: number): CostEntry[];
30
+ /**
31
+ * Convert a progress timestamp (`YYYY-MM-DD HH:MM`) to milliseconds since epoch.
32
+ *
33
+ * @param timestamp - The progress file timestamp string.
34
+ * @returns Milliseconds since epoch, or `NaN` if the timestamp is invalid.
35
+ */
36
+ export declare function progressTimestampToMs(timestamp: string): number;
37
+ /**
38
+ * Generate a session report from progress.txt and costs.log entries
39
+ * created during this AFK session.
40
+ *
41
+ * @param projectRoot - The project root directory.
42
+ * @param loopStartTime - When the AFK loop started (Date.now()).
43
+ * @param loopEndTime - When the AFK loop ended.
44
+ * @returns The report markdown string.
45
+ */
46
+ export declare function generateSessionReport(projectRoot: string, loopStartTime: number, loopEndTime: number): string;
47
+ //# sourceMappingURL=report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../../../src/scripts/afk/report/report.ts"],"names":[],"mappings":"AAeA,0CAA0C;AAC1C,MAAM,MAAM,SAAS,GAAG;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,sCAAsC;AACtC,MAAM,MAAM,aAAa,GAAG;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAC3B,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,SAAS,EAAE,CAiCb;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAK/D;AAcD;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,GAClB,MAAM,CA6HR"}
@@ -0,0 +1,194 @@
1
+ /**
2
+ * AFK session report generator.
3
+ *
4
+ * Reads progress.txt and costs.log entries created during the current
5
+ * AFK session and generates a markdown report at `.clancy/session-report.md`.
6
+ */
7
+ import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
8
+ import { join } from 'node:path';
9
+ import { formatDuration } from '../../../scripts/shared/format/format.js';
10
+ import { parseProgressFile, } from '../../../scripts/shared/progress/progress.js';
11
+ /**
12
+ * Parse costs.log and return entries with ISO timestamp >= the given threshold.
13
+ *
14
+ * Each line is expected to follow the format:
15
+ * `ISO-timestamp | KEY | Nmin | ~N tokens (estimated)`
16
+ *
17
+ * Lines that don't match are silently skipped.
18
+ *
19
+ * @param projectRoot - The project root directory.
20
+ * @param sinceMs - Only include entries with timestamp >= this value (ms since epoch).
21
+ * @returns Parsed cost entries from this session.
22
+ */
23
+ export function parseCostsLog(projectRoot, sinceMs) {
24
+ const filePath = join(projectRoot, '.clancy', 'costs.log');
25
+ let content;
26
+ try {
27
+ content = readFileSync(filePath, 'utf8');
28
+ }
29
+ catch {
30
+ return [];
31
+ }
32
+ const entries = [];
33
+ for (const line of content.split('\n')) {
34
+ const trimmed = line.trim();
35
+ if (!trimmed)
36
+ continue;
37
+ const parts = trimmed.split(' | ');
38
+ if (parts.length < 4)
39
+ continue;
40
+ const timestamp = parts[0];
41
+ const entryTime = new Date(timestamp).getTime();
42
+ if (Number.isNaN(entryTime) || entryTime < sinceMs)
43
+ continue;
44
+ entries.push({
45
+ timestamp,
46
+ key: parts[1],
47
+ duration: parts[2],
48
+ tokens: parts[3],
49
+ });
50
+ }
51
+ return entries;
52
+ }
53
+ /**
54
+ * Convert a progress timestamp (`YYYY-MM-DD HH:MM`) to milliseconds since epoch.
55
+ *
56
+ * @param timestamp - The progress file timestamp string.
57
+ * @returns Milliseconds since epoch, or `NaN` if the timestamp is invalid.
58
+ */
59
+ export function progressTimestampToMs(timestamp) {
60
+ // Progress timestamps are UTC: "YYYY-MM-DD HH:MM"
61
+ // Validate format before parsing to avoid JS Date quirks with garbage input
62
+ if (!/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/.test(timestamp))
63
+ return NaN;
64
+ return new Date(timestamp.replace(' ', 'T') + ':00Z').getTime();
65
+ }
66
+ /** Statuses that indicate a successfully completed ticket. */
67
+ const COMPLETED_STATUSES = new Set([
68
+ 'DONE',
69
+ 'PR_CREATED',
70
+ 'PUSHED',
71
+ 'EPIC_PR_CREATED',
72
+ 'RESUMED',
73
+ ]);
74
+ /** Statuses that indicate a failed/skipped ticket. */
75
+ const FAILED_STATUSES = new Set(['SKIPPED', 'PUSH_FAILED', 'TIME_LIMIT']);
76
+ /**
77
+ * Generate a session report from progress.txt and costs.log entries
78
+ * created during this AFK session.
79
+ *
80
+ * @param projectRoot - The project root directory.
81
+ * @param loopStartTime - When the AFK loop started (Date.now()).
82
+ * @param loopEndTime - When the AFK loop ended.
83
+ * @returns The report markdown string.
84
+ */
85
+ export function generateSessionReport(projectRoot, loopStartTime, loopEndTime) {
86
+ // 1. Read progress.txt, filter entries with timestamp >= loopStart
87
+ // Round loopStart down to the minute to match progress file precision (YYYY-MM-DD HH:MM)
88
+ const loopStartMinute = Math.floor(loopStartTime / 60000) * 60000;
89
+ const allProgress = parseProgressFile(projectRoot);
90
+ const sessionEntries = allProgress.filter((entry) => {
91
+ const entryMs = progressTimestampToMs(entry.timestamp);
92
+ return !Number.isNaN(entryMs) && entryMs >= loopStartMinute;
93
+ });
94
+ // 2. Read costs.log, filter entries with timestamp >= loopStart
95
+ const costEntries = parseCostsLog(projectRoot, loopStartTime);
96
+ // 3. Build a cost lookup by ticket key
97
+ const costByKey = new Map();
98
+ for (const cost of costEntries) {
99
+ costByKey.set(cost.key, cost);
100
+ }
101
+ // 4. Deduplicate progress entries — keep latest per key (for rework cycles)
102
+ const latestByKey = new Map();
103
+ for (const entry of sessionEntries) {
104
+ latestByKey.set(entry.key, entry);
105
+ }
106
+ // 5. Build session tickets
107
+ const tickets = [];
108
+ for (const entry of latestByKey.values()) {
109
+ const cost = costByKey.get(entry.key);
110
+ tickets.push({
111
+ key: entry.key,
112
+ summary: entry.summary,
113
+ status: entry.status,
114
+ ...(entry.prNumber != null && { prNumber: entry.prNumber }),
115
+ ...(cost && { duration: cost.duration, tokens: cost.tokens }),
116
+ });
117
+ }
118
+ // 6. Count completed vs failed
119
+ const completed = tickets.filter((t) => COMPLETED_STATUSES.has(t.status));
120
+ const failed = tickets.filter((t) => FAILED_STATUSES.has(t.status));
121
+ const totalDuration = formatDuration(loopEndTime - loopStartTime);
122
+ // 7. Calculate total estimated tokens
123
+ let totalTokens = 0;
124
+ for (const cost of costEntries) {
125
+ const match = cost.tokens.match(/~(\d[\d,]*)/);
126
+ if (match) {
127
+ totalTokens += parseInt(match[1].replace(/,/g, ''), 10);
128
+ }
129
+ }
130
+ // 8. Format the date
131
+ const date = new Date(loopStartTime);
132
+ const dateStr = `${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(2, '0')}-${String(date.getUTCDate()).padStart(2, '0')}`;
133
+ // 9. Generate markdown
134
+ const lines = [];
135
+ lines.push(`# AFK Session Report — ${dateStr}`);
136
+ lines.push('');
137
+ lines.push('## Summary');
138
+ lines.push(`- Tickets completed: ${completed.length}`);
139
+ lines.push(`- Tickets failed: ${failed.length}`);
140
+ lines.push(`- Total duration: ${totalDuration}`);
141
+ if (totalTokens > 0) {
142
+ lines.push(`- Estimated token usage: ${totalTokens.toLocaleString('en-US')}`);
143
+ }
144
+ lines.push('');
145
+ lines.push('## Tickets');
146
+ if (tickets.length === 0) {
147
+ lines.push('');
148
+ lines.push('No tickets were processed in this session.');
149
+ }
150
+ for (const ticket of tickets) {
151
+ const isCompleted = COMPLETED_STATUSES.has(ticket.status);
152
+ const icon = isCompleted ? '\u2713' : '\u2717';
153
+ lines.push('');
154
+ lines.push(`### ${icon} ${ticket.key} — ${ticket.summary}`);
155
+ if (ticket.duration) {
156
+ lines.push(`- Duration: ${ticket.duration}`);
157
+ }
158
+ if (ticket.tokens) {
159
+ lines.push(`- Tokens: ${ticket.tokens}`);
160
+ }
161
+ if (ticket.prNumber != null) {
162
+ lines.push(`- PR: #${ticket.prNumber}`);
163
+ }
164
+ lines.push(`- Status: ${ticket.status}`);
165
+ }
166
+ // 10. Next Steps
167
+ const prNumbers = tickets
168
+ .filter((t) => t.prNumber != null)
169
+ .map((t) => `#${t.prNumber}`);
170
+ const skippedKeys = failed.map((t) => t.key);
171
+ if (prNumbers.length > 0 || skippedKeys.length > 0) {
172
+ lines.push('');
173
+ lines.push('## Next Steps');
174
+ if (prNumbers.length > 0) {
175
+ lines.push(`- Review PRs ${prNumbers.join(', ')}`);
176
+ }
177
+ for (const key of skippedKeys) {
178
+ lines.push(`- ${key} needs manual intervention`);
179
+ }
180
+ }
181
+ lines.push('');
182
+ const report = lines.join('\n');
183
+ // 11. Write to .clancy/session-report.md (best-effort)
184
+ try {
185
+ const reportPath = join(projectRoot, '.clancy', 'session-report.md');
186
+ mkdirSync(join(projectRoot, '.clancy'), { recursive: true });
187
+ writeFileSync(reportPath, report, 'utf8');
188
+ }
189
+ catch {
190
+ // Best-effort — report is still returned for stdout
191
+ }
192
+ return report;
193
+ }
194
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../../../../src/scripts/afk/report/report.ts"],"names":[],"mappings":"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"}
@@ -45,16 +45,46 @@ export declare function resolveUsername(token: string, apiBase?: string): Promis
45
45
  export declare function fetchIssue(token: string, repo: string, label?: string, username?: string): Promise<(Ticket & {
46
46
  milestone?: string;
47
47
  }) | undefined>;
48
+ /** GitHub issue with optional milestone. */
49
+ export type GitHubTicket = Ticket & {
50
+ milestone?: string;
51
+ };
52
+ /**
53
+ * Fetch multiple candidate issues from GitHub Issues.
54
+ *
55
+ * @param token - The GitHub personal access token.
56
+ * @param repo - The repository in `owner/repo` format.
57
+ * @param label - Optional label to filter issues.
58
+ * @param username - The GitHub username for assignee filtering.
59
+ * @param excludeHitl - If `true`, excludes issues with the `clancy:hitl` label (client-side).
60
+ * @param limit - Maximum number of results to return (default: 5).
61
+ * @returns Array of fetched tickets (may be empty).
62
+ */
63
+ export declare function fetchIssues(token: string, repo: string, label?: string, username?: string, excludeHitl?: boolean, limit?: number): Promise<GitHubTicket[]>;
64
+ /**
65
+ * Check whether a GitHub issue is blocked by unresolved blockers.
66
+ *
67
+ * Parses the issue body for `Blocked by #N` lines and checks if any
68
+ * of those issues are still open.
69
+ *
70
+ * @param token - The GitHub personal access token.
71
+ * @param repo - The repository in `owner/repo` format.
72
+ * @param issueNumber - The issue number to check.
73
+ * @param body - The issue body text.
74
+ * @returns `true` if any blocker is unresolved, `false` otherwise.
75
+ */
76
+ export declare function fetchBlockerStatus(token: string, repo: string, issueNumber: number, body: string): Promise<boolean>;
48
77
  /** Result of checking children status for an epic/milestone. */
49
78
  export type ChildrenStatus = {
50
79
  total: number;
51
80
  incomplete: number;
52
81
  };
53
82
  /**
54
- * Fetch the children status of a GitHub parent issue.
83
+ * Fetch the children status of a GitHub parent issue (dual-mode).
55
84
  *
56
- * Searches for issues whose body contains `Parent: #{parentNumber}` and
57
- * counts total vs open. Used to determine if all children are done.
85
+ * Tries the `Epic: #{parentNumber}` text convention first. If no results,
86
+ * falls back to the native `Parent: #{parentNumber}` convention for
87
+ * backward compatibility with pre-v0.6.0 children.
58
88
  *
59
89
  * @param token - The GitHub personal access token.
60
90
  * @param repo - The repository in `owner/repo` format.
@@ -1 +1 @@
1
- {"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../../../src/scripts/board/github/github.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAY/C,4DAA4D;AAC5D,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAC9B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,UAAU,CAAC,CAWrB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,CAmCjB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,UAAU,CAC9B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,MAAM,EACd,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,CAAC,MAAM,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,SAAS,CAAC,CAyDxD;AAED,gEAAgE;AAChE,MAAM,MAAM,cAAc,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnE;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAkCrC;AAED;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAC9B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,OAAO,CAAC,CAoBlB"}
1
+ {"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../../../src/scripts/board/github/github.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAY/C,4DAA4D;AAC5D,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAC9B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,UAAU,CAAC,CAWrB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,CAmCjB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,UAAU,CAC9B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,MAAM,EACd,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,CAAC,MAAM,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,SAAS,CAAC,CAGxD;AAED,4CAA4C;AAC5C,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3D;;;;;;;;;;GAUG;AACH,wBAAsB,WAAW,CAC/B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,MAAM,EACd,QAAQ,CAAC,EAAE,MAAM,EACjB,WAAW,CAAC,EAAE,OAAO,EACrB,KAAK,SAAI,GACR,OAAO,CAAC,YAAY,EAAE,CAAC,CA6DzB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,OAAO,CAAC,CAoClB;AAED,gEAAgE;AAChE,MAAM,MAAM,cAAc,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnE;;;;;;;;;;;GAWG;AACH,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAsBrC;AA6CD;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAC9B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,OAAO,CAAC,CAoBlB"}
@@ -96,6 +96,21 @@ export async function resolveUsername(token, apiBase) {
96
96
  * @returns The fetched ticket with optional milestone, or `undefined` if none available.
97
97
  */
98
98
  export async function fetchIssue(token, repo, label, username) {
99
+ const results = await fetchIssues(token, repo, label, username, false, 1);
100
+ return results[0];
101
+ }
102
+ /**
103
+ * Fetch multiple candidate issues from GitHub Issues.
104
+ *
105
+ * @param token - The GitHub personal access token.
106
+ * @param repo - The repository in `owner/repo` format.
107
+ * @param label - Optional label to filter issues.
108
+ * @param username - The GitHub username for assignee filtering.
109
+ * @param excludeHitl - If `true`, excludes issues with the `clancy:hitl` label (client-side).
110
+ * @param limit - Maximum number of results to return (default: 5).
111
+ * @returns Array of fetched tickets (may be empty).
112
+ */
113
+ export async function fetchIssues(token, repo, label, username, excludeHitl, limit = 5) {
99
114
  let response;
100
115
  const params = new URLSearchParams({
101
116
  state: 'open',
@@ -111,11 +126,11 @@ export async function fetchIssue(token, repo, label, username) {
111
126
  }
112
127
  catch (err) {
113
128
  console.warn(`⚠ GitHub API request failed: ${err instanceof Error ? err.message : String(err)}`);
114
- return undefined;
129
+ return [];
115
130
  }
116
131
  if (!response.ok) {
117
132
  console.warn(`⚠ GitHub API returned HTTP ${response.status}`);
118
- return undefined;
133
+ return [];
119
134
  }
120
135
  let json;
121
136
  try {
@@ -123,31 +138,77 @@ export async function fetchIssue(token, repo, label, username) {
123
138
  }
124
139
  catch {
125
140
  console.warn('⚠ GitHub API returned invalid JSON');
126
- return undefined;
141
+ return [];
127
142
  }
128
143
  const parsed = githubIssuesResponseSchema.safeParse(json);
129
144
  if (!parsed.success) {
130
145
  console.warn(`⚠ Unexpected GitHub response shape: ${parsed.error.message}`);
131
- return undefined;
146
+ return [];
132
147
  }
133
148
  // Filter out pull requests
134
- const issues = parsed.data.filter((item) => !item.pull_request);
135
- if (!issues.length)
136
- return undefined;
137
- const issue = issues[0];
138
- return {
149
+ let issues = parsed.data.filter((item) => !item.pull_request);
150
+ // HITL/AFK filtering: exclude issues with clancy:hitl label
151
+ // GitHub Issues API doesn't support label exclusion natively, so filter client-side.
152
+ if (excludeHitl) {
153
+ issues = issues.filter((issue) => !issue.labels?.some((l) => l.name === 'clancy:hitl'));
154
+ }
155
+ return issues.slice(0, limit).map((issue) => ({
139
156
  key: `#${issue.number}`,
140
157
  title: issue.title,
141
158
  description: issue.body ?? '',
142
159
  provider: 'github',
143
160
  milestone: issue.milestone?.title,
144
- };
161
+ }));
162
+ }
163
+ /**
164
+ * Check whether a GitHub issue is blocked by unresolved blockers.
165
+ *
166
+ * Parses the issue body for `Blocked by #N` lines and checks if any
167
+ * of those issues are still open.
168
+ *
169
+ * @param token - The GitHub personal access token.
170
+ * @param repo - The repository in `owner/repo` format.
171
+ * @param issueNumber - The issue number to check.
172
+ * @param body - The issue body text.
173
+ * @returns `true` if any blocker is unresolved, `false` otherwise.
174
+ */
175
+ export async function fetchBlockerStatus(token, repo, issueNumber, body) {
176
+ if (!isValidRepo(repo))
177
+ return false;
178
+ // Parse "Blocked by #N" references from the body
179
+ const blockerPattern = /Blocked by #(\d+)/gi;
180
+ const blockerNumbers = new Set();
181
+ let match;
182
+ while ((match = blockerPattern.exec(body)) !== null) {
183
+ const num = parseInt(match[1], 10);
184
+ if (!Number.isNaN(num) && num !== issueNumber) {
185
+ blockerNumbers.add(num);
186
+ }
187
+ }
188
+ if (!blockerNumbers.size)
189
+ return false;
190
+ try {
191
+ for (const blockerNum of blockerNumbers) {
192
+ const response = await fetch(`${GITHUB_API}/repos/${repo}/issues/${blockerNum}`, { headers: githubHeaders(token) });
193
+ if (!response.ok)
194
+ continue;
195
+ const json = (await response.json());
196
+ // Short-circuit: one unresolved blocker is enough
197
+ if (json.state !== 'closed')
198
+ return true;
199
+ }
200
+ return false;
201
+ }
202
+ catch {
203
+ return false;
204
+ }
145
205
  }
146
206
  /**
147
- * Fetch the children status of a GitHub parent issue.
207
+ * Fetch the children status of a GitHub parent issue (dual-mode).
148
208
  *
149
- * Searches for issues whose body contains `Parent: #{parentNumber}` and
150
- * counts total vs open. Used to determine if all children are done.
209
+ * Tries the `Epic: #{parentNumber}` text convention first. If no results,
210
+ * falls back to the native `Parent: #{parentNumber}` convention for
211
+ * backward compatibility with pre-v0.6.0 children.
151
212
  *
152
213
  * @param token - The GitHub personal access token.
153
214
  * @param repo - The repository in `owner/repo` format.
@@ -158,25 +219,49 @@ export async function fetchChildrenStatus(token, repo, parentNumber) {
158
219
  if (!isValidRepo(repo))
159
220
  return undefined;
160
221
  try {
161
- // Fetch all issues (open + closed) and filter for parent reference
162
- const allParams = new URLSearchParams({
163
- state: 'all',
164
- per_page: '100',
165
- });
166
- const allResponse = await fetch(`${GITHUB_API}/repos/${repo}/issues?${allParams}`, { headers: githubHeaders(token) });
167
- if (!allResponse.ok)
168
- return undefined;
169
- const allIssues = (await allResponse.json());
170
- const parentRef = `Parent: #${parentNumber}`;
171
- const children = allIssues.filter((issue) => !issue.pull_request && issue.body && issue.body.includes(parentRef));
172
- const total = children.length;
173
- const incomplete = children.filter((c) => c.state === 'open').length;
174
- return { total, incomplete };
222
+ // Mode 1: Try Epic: text convention
223
+ const epicTextResult = await fetchChildrenByBodyRef(token, repo, `Epic: #${parentNumber}`);
224
+ if (epicTextResult && epicTextResult.total > 0)
225
+ return epicTextResult;
226
+ // Mode 2: Fall back to native Parent: convention
227
+ return await fetchChildrenByBodyRef(token, repo, `Parent: #${parentNumber}`);
175
228
  }
176
229
  catch {
177
230
  return undefined;
178
231
  }
179
232
  }
233
+ /**
234
+ * Fetch children status by searching for a body reference string.
235
+ *
236
+ * @param token - The GitHub personal access token.
237
+ * @param repo - The repository in `owner/repo` format.
238
+ * @param bodyRef - The body reference string to search for.
239
+ * @returns The children status, or `undefined` on failure.
240
+ */
241
+ async function fetchChildrenByBodyRef(token, repo, bodyRef) {
242
+ // Use GitHub Search API with total_count for accurate counts.
243
+ // Two queries: one for all children, one for open (incomplete) children.
244
+ const headers = githubHeaders(token);
245
+ const allQuery = `"${bodyRef}" repo:${repo} is:issue`;
246
+ const allParams = new URLSearchParams({ q: allQuery, per_page: '1' });
247
+ const allResponse = await fetch(`${GITHUB_API}/search/issues?${allParams}`, {
248
+ headers,
249
+ });
250
+ if (!allResponse.ok)
251
+ return undefined;
252
+ const allResult = (await allResponse.json());
253
+ const total = allResult.total_count ?? 0;
254
+ if (total === 0)
255
+ return { total: 0, incomplete: 0 };
256
+ const openQuery = `"${bodyRef}" repo:${repo} is:issue is:open`;
257
+ const openParams = new URLSearchParams({ q: openQuery, per_page: '1' });
258
+ const openResponse = await fetch(`${GITHUB_API}/search/issues?${openParams}`, { headers });
259
+ if (!openResponse.ok)
260
+ return { total, incomplete: total }; // assume all open on failure
261
+ const openResult = (await openResponse.json());
262
+ const incomplete = openResult.total_count ?? 0;
263
+ return { total, incomplete };
264
+ }
180
265
  /**
181
266
  * Close a GitHub issue.
182
267
  *
@@ -1 +1 @@
1
- {"version":3,"file":"github.js","sourceRoot":"","sources":["../../../../src/scripts/board/github/github.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,UAAU,CAAC;AAE7B,OAAO,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,EACL,UAAU,EACV,aAAa,EACb,YAAY,GACb,MAAM,+BAA+B,CAAC;AAIvC,2CAA2C;AAC3C,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;CAClB,CAAC,CAAC;AAEH,MAAM,iBAAiB,GAAG,oCAAoC,CAAC;AAE/D,qDAAqD;AACrD,IAAI,cAAkC,CAAC;AAEvC,4DAA4D;AAC5D,MAAM,UAAU,kBAAkB;IAChC,cAAc,GAAG,SAAS,CAAC;AAC7B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACtC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,KAAa,EACb,IAAY;IAEZ,OAAO,YAAY,CACjB,GAAG,UAAU,UAAU,IAAI,EAAE,EAC7B,aAAa,CAAC,KAAK,CAAC,EACpB;QACE,GAAG,EAAE,2CAA2C;QAChD,GAAG,EAAE,4BAA4B;QACjC,GAAG,EAAE,kBAAkB,IAAI,aAAa;KACzC,EACD,0CAA0C,CAC3C,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,KAAa,EACb,OAAgB;IAEhB,IAAI,cAAc;QAAE,OAAO,cAAc,CAAC;IAE1C,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,IAAI,UAAU,OAAO,EAAE;YAC5D,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC;SAC9B,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,GACR,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG;gBAChD,CAAC,CAAC,8FAA8F;gBAChG,CAAC,CAAC,EAAE,CAAC;YACT,OAAO,CAAC,IAAI,CACV,gCAAgC,QAAQ,CAAC,MAAM,0BAA0B,IAAI,EAAE,CAChF,CAAC;YACF,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,IAAI,GAAY,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC5C,MAAM,MAAM,GAAG,gBAAgB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAEhD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;YACnC,OAAO,cAAc,CAAC;QACxB,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,0DAA0D,CAAC,CAAC;IAC3E,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CACV,kCAAkC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,wBAAwB,CAC3G,CAAC;IACJ,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,KAAa,EACb,IAAY,EACZ,KAAc,EACd,QAAiB;IAEjB,IAAI,QAAkB,CAAC;IAEvB,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;QACjC,KAAK,EAAE,MAAM;QACb,QAAQ,EAAE,QAAQ,IAAI,KAAK;QAC3B,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;IAEH,IAAI,KAAK;QAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAEvC,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,UAAU,UAAU,IAAI,WAAW,MAAM,EAAE,EAAE;YACrE,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC;SAC9B,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CACV,gCAAgC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CACnF,CAAC;QACF,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,OAAO,CAAC,IAAI,CAAC,8BAA8B,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9D,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,IAAa,CAAC;IAElB,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;QACnD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,MAAM,GAAG,0BAA0B,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAE1D,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,CAAC,IAAI,CAAC,uCAAuC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAC5E,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,2BAA2B;IAC3B,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAEhE,IAAI,CAAC,MAAM,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IAErC,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IAExB,OAAO;QACL,GAAG,EAAE,IAAI,KAAK,CAAC,MAAM,EAAE;QACvB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,WAAW,EAAE,KAAK,CAAC,IAAI,IAAI,EAAE;QAC7B,QAAQ,EAAE,QAAQ;QAClB,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK;KAClC,CAAC;AACJ,CAAC;AAKD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,KAAa,EACb,IAAY,EACZ,YAAoB;IAEpB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IAEzC,IAAI,CAAC;QACH,mEAAmE;QACnE,MAAM,SAAS,GAAG,IAAI,eAAe,CAAC;YACpC,KAAK,EAAE,KAAK;YACZ,QAAQ,EAAE,KAAK;SAChB,CAAC,CAAC;QACH,MAAM,WAAW,GAAG,MAAM,KAAK,CAC7B,GAAG,UAAU,UAAU,IAAI,WAAW,SAAS,EAAE,EACjD,EAAE,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,CAClC,CAAC;QACF,IAAI,CAAC,WAAW,CAAC,EAAE;YAAE,OAAO,SAAS,CAAC;QAEtC,MAAM,SAAS,GAAG,CAAC,MAAM,WAAW,CAAC,IAAI,EAAE,CAIzC,CAAC;QAEH,MAAM,SAAS,GAAG,YAAY,YAAY,EAAE,CAAC;QAC7C,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,CAC/B,CAAC,KAAK,EAAE,EAAE,CACR,CAAC,KAAK,CAAC,YAAY,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CACtE,CAAC;QAEF,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC;QAC9B,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;QAErE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,KAAa,EACb,IAAY,EACZ,WAAmB;IAEnB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAErC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAC1B,GAAG,UAAU,UAAU,IAAI,WAAW,WAAW,EAAE,EACnD;YACE,MAAM,EAAE,OAAO;YACf,OAAO,EAAE;gBACP,GAAG,aAAa,CAAC,KAAK,CAAC;gBACvB,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;SAC1C,CACF,CAAC;QAEF,OAAO,QAAQ,CAAC,EAAE,CAAC;IACrB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"github.js","sourceRoot":"","sources":["../../../../src/scripts/board/github/github.ts"],"names":[],"mappings":"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"}