@codeledger/cli 0.6.8 → 0.6.9

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 (83) hide show
  1. package/dist/commands/activate.d.ts.map +1 -1
  2. package/dist/commands/activate.js +16 -1
  3. package/dist/commands/activate.js.map +1 -1
  4. package/dist/commands/commit-msg.d.ts +58 -0
  5. package/dist/commands/commit-msg.d.ts.map +1 -0
  6. package/dist/commands/commit-msg.js +461 -0
  7. package/dist/commands/commit-msg.js.map +1 -0
  8. package/dist/commands/init.d.ts.map +1 -1
  9. package/dist/commands/init.js +14 -0
  10. package/dist/commands/init.js.map +1 -1
  11. package/dist/commands/intent.d.ts +3 -1
  12. package/dist/commands/intent.d.ts.map +1 -1
  13. package/dist/commands/intent.js +68 -2
  14. package/dist/commands/intent.js.map +1 -1
  15. package/dist/commands/pr-summary.d.ts +59 -0
  16. package/dist/commands/pr-summary.d.ts.map +1 -0
  17. package/dist/commands/pr-summary.js +524 -0
  18. package/dist/commands/pr-summary.js.map +1 -0
  19. package/dist/commands/session-cleanup.js +1 -0
  20. package/dist/commands/session-cleanup.js.map +1 -1
  21. package/dist/commands/session-summary.d.ts.map +1 -1
  22. package/dist/commands/session-summary.js +135 -3
  23. package/dist/commands/session-summary.js.map +1 -1
  24. package/dist/commands/setup-ci.d.ts.map +1 -1
  25. package/dist/commands/setup-ci.js +12 -0
  26. package/dist/commands/setup-ci.js.map +1 -1
  27. package/dist/commands/verify.d.ts.map +1 -1
  28. package/dist/commands/verify.js +35 -3
  29. package/dist/commands/verify.js.map +1 -1
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +45 -1
  32. package/dist/index.js.map +1 -1
  33. package/dist/intent/extractor.d.ts +15 -0
  34. package/dist/intent/extractor.d.ts.map +1 -0
  35. package/dist/intent/extractor.js +149 -0
  36. package/dist/intent/extractor.js.map +1 -0
  37. package/dist/intent/fetcher.d.ts +33 -0
  38. package/dist/intent/fetcher.d.ts.map +1 -0
  39. package/dist/intent/fetcher.js +364 -0
  40. package/dist/intent/fetcher.js.map +1 -0
  41. package/dist/intent/loader.d.ts +26 -0
  42. package/dist/intent/loader.d.ts.map +1 -0
  43. package/dist/intent/loader.js +80 -0
  44. package/dist/intent/loader.js.map +1 -0
  45. package/dist/intent/types.d.ts +33 -0
  46. package/dist/intent/types.d.ts.map +1 -0
  47. package/dist/intent/types.js +9 -0
  48. package/dist/intent/types.js.map +1 -0
  49. package/dist/project-config.d.ts +38 -0
  50. package/dist/project-config.d.ts.map +1 -0
  51. package/dist/project-config.js +206 -0
  52. package/dist/project-config.js.map +1 -0
  53. package/dist/review-intelligence/detectors/architecture-graph.d.ts +18 -0
  54. package/dist/review-intelligence/detectors/architecture-graph.d.ts.map +1 -0
  55. package/dist/review-intelligence/detectors/architecture-graph.js +73 -0
  56. package/dist/review-intelligence/detectors/architecture-graph.js.map +1 -0
  57. package/dist/review-intelligence/detectors/pack-rules.d.ts +16 -0
  58. package/dist/review-intelligence/detectors/pack-rules.d.ts.map +1 -0
  59. package/dist/review-intelligence/detectors/pack-rules.js +107 -0
  60. package/dist/review-intelligence/detectors/pack-rules.js.map +1 -0
  61. package/dist/review-intelligence/fixes/index.d.ts +18 -0
  62. package/dist/review-intelligence/fixes/index.d.ts.map +1 -1
  63. package/dist/review-intelligence/fixes/index.js +198 -9
  64. package/dist/review-intelligence/fixes/index.js.map +1 -1
  65. package/dist/review-intelligence/index.d.ts +4 -1
  66. package/dist/review-intelligence/index.d.ts.map +1 -1
  67. package/dist/review-intelligence/index.js +20 -3
  68. package/dist/review-intelligence/index.js.map +1 -1
  69. package/dist/review-intelligence/invariants.d.ts +15 -0
  70. package/dist/review-intelligence/invariants.d.ts.map +1 -1
  71. package/dist/review-intelligence/invariants.js +36 -5
  72. package/dist/review-intelligence/invariants.js.map +1 -1
  73. package/dist/review-intelligence/types.d.ts +16 -12
  74. package/dist/review-intelligence/types.d.ts.map +1 -1
  75. package/dist/review-intelligence/types.js +9 -1
  76. package/dist/review-intelligence/types.js.map +1 -1
  77. package/dist/templates/claude-md.d.ts.map +1 -1
  78. package/dist/templates/claude-md.js +23 -128
  79. package/dist/templates/claude-md.js.map +1 -1
  80. package/dist/templates/hooks.d.ts.map +1 -1
  81. package/dist/templates/hooks.js +39 -0
  82. package/dist/templates/hooks.js.map +1 -1
  83. package/package.json +9 -9
@@ -0,0 +1,364 @@
1
+ /**
2
+ * Issue fetcher — retrieves issue data from external trackers.
3
+ *
4
+ * Supported providers:
5
+ * - GitHub Issues: "owner/repo#123" or "#123" (infer from git remote)
6
+ * - Linear: "PREFIX-123" (requires LINEAR_API_KEY)
7
+ * - Jira: "PROJ-123" with JIRA_BASE_URL set (requires JIRA_API_TOKEN + JIRA_USER_EMAIL)
8
+ *
9
+ * Requires no API keys for public GitHub repos. For private repos,
10
+ * set GITHUB_TOKEN in the environment.
11
+ */
12
+ import { execSync } from 'node:child_process';
13
+ /**
14
+ * Detect issue source and fetch raw data.
15
+ * Provider detection priority: GitHub full → GitHub short → Linear/Jira (PREFIX-123)
16
+ */
17
+ export async function fetchIssue(issueId) {
18
+ // GitHub: owner/repo#123
19
+ const ghFullMatch = issueId.match(/^([^/]+\/[^#]+)#(\d+)$/);
20
+ if (ghFullMatch) {
21
+ return fetchGitHubIssue(ghFullMatch[1], ghFullMatch[2]);
22
+ }
23
+ // GitHub shorthand: #123 (infer repo from git remote)
24
+ const ghShortMatch = issueId.match(/^#?(\d+)$/);
25
+ if (ghShortMatch) {
26
+ const repo = inferGitHubRepo();
27
+ if (repo) {
28
+ return fetchGitHubIssue(repo, ghShortMatch[1]);
29
+ }
30
+ console.error(`Cannot infer GitHub repo for issue ${issueId}. Use "owner/repo#${ghShortMatch[1]}" format.`);
31
+ return null;
32
+ }
33
+ // PREFIX-123 pattern: detect Linear vs Jira based on env vars
34
+ const prefixMatch = issueId.match(/^([A-Z]+)-(\d+)$/);
35
+ if (prefixMatch) {
36
+ // If JIRA_BASE_URL is set, treat as Jira
37
+ if (process.env['JIRA_BASE_URL']) {
38
+ return fetchJiraIssue(issueId);
39
+ }
40
+ // Otherwise treat as Linear (default for PREFIX-123 format)
41
+ return fetchLinearIssue(issueId);
42
+ }
43
+ console.error(`Unrecognized issue format: "${issueId}". Supported: owner/repo#123, #123, PREFIX-123`);
44
+ return null;
45
+ }
46
+ async function fetchGitHubIssue(repo, number) {
47
+ const url = `https://api.github.com/repos/${repo}/issues/${number}`;
48
+ const token = process.env['GITHUB_TOKEN'] || process.env['GH_TOKEN'];
49
+ const headers = {
50
+ 'Accept': 'application/vnd.github.v3+json',
51
+ 'User-Agent': 'codeledger-cli',
52
+ };
53
+ if (token) {
54
+ headers['Authorization'] = `Bearer ${token}`;
55
+ }
56
+ try {
57
+ const res = await fetch(url, { headers });
58
+ if (!res.ok) {
59
+ if (res.status === 404) {
60
+ console.error(`Issue not found: ${repo}#${number}`);
61
+ }
62
+ else if (res.status === 403) {
63
+ console.error(`GitHub API rate limit or auth error. Set GITHUB_TOKEN for private repos.`);
64
+ }
65
+ else {
66
+ console.error(`GitHub API error ${res.status}: ${res.statusText}`);
67
+ }
68
+ return null;
69
+ }
70
+ const data = await res.json();
71
+ return {
72
+ title: data.title,
73
+ body: data.body ?? '',
74
+ labels: data.labels.map((l) => l.name),
75
+ state: data.state,
76
+ assignee: data.assignee?.login,
77
+ url: data.html_url,
78
+ };
79
+ }
80
+ catch (err) {
81
+ console.error(`Failed to fetch GitHub issue: ${err instanceof Error ? err.message : String(err)}`);
82
+ return null;
83
+ }
84
+ }
85
+ // ── Linear Provider ──────────────────────────────────────────────────────────
86
+ async function fetchLinearIssue(issueId) {
87
+ const token = process.env['LINEAR_API_KEY'];
88
+ if (!token) {
89
+ console.error(`Linear API key required. Set LINEAR_API_KEY in your environment.\n` +
90
+ ` export LINEAR_API_KEY=lin_api_...\n` +
91
+ `Or save issue data manually:\n` +
92
+ ` codeledger intent from-issue ${issueId} --format json > intent.json\n` +
93
+ ` Then use: --intent-file intent.json`);
94
+ return null;
95
+ }
96
+ const query = `
97
+ query IssueByIdentifier($id: String!) {
98
+ issue(id: $id) {
99
+ title
100
+ description
101
+ state { name }
102
+ assignee { name }
103
+ labels { nodes { name } }
104
+ url
105
+ }
106
+ }
107
+ `;
108
+ try {
109
+ const res = await fetch('https://api.linear.app/graphql', {
110
+ method: 'POST',
111
+ headers: {
112
+ 'Content-Type': 'application/json',
113
+ 'Authorization': token,
114
+ },
115
+ body: JSON.stringify({ query, variables: { id: issueId } }),
116
+ });
117
+ if (!res.ok) {
118
+ if (res.status === 401) {
119
+ console.error('Linear API authentication failed. Check LINEAR_API_KEY.');
120
+ }
121
+ else {
122
+ console.error(`Linear API error ${res.status}: ${res.statusText}`);
123
+ }
124
+ return null;
125
+ }
126
+ const json = await res.json();
127
+ if (json.errors && json.errors.length > 0) {
128
+ console.error(`Linear API error: ${json.errors[0].message}`);
129
+ return null;
130
+ }
131
+ const issue = json.data?.issue;
132
+ if (!issue) {
133
+ console.error(`Linear issue not found: ${issueId}`);
134
+ return null;
135
+ }
136
+ return {
137
+ title: issue.title,
138
+ body: issue.description ?? '',
139
+ labels: issue.labels.nodes.map((l) => l.name),
140
+ state: issue.state?.name,
141
+ assignee: issue.assignee?.name,
142
+ url: issue.url,
143
+ };
144
+ }
145
+ catch (err) {
146
+ console.error(`Failed to fetch Linear issue: ${err instanceof Error ? err.message : String(err)}`);
147
+ return null;
148
+ }
149
+ }
150
+ // ── Jira Provider ────────────────────────────────────────────────────────────
151
+ async function fetchJiraIssue(issueId) {
152
+ const baseUrl = process.env['JIRA_BASE_URL'];
153
+ if (!baseUrl) {
154
+ console.error(`Jira base URL required. Set JIRA_BASE_URL in your environment.\n` +
155
+ ` export JIRA_BASE_URL=https://your-org.atlassian.net`);
156
+ return null;
157
+ }
158
+ const token = process.env['JIRA_API_TOKEN'];
159
+ const email = process.env['JIRA_USER_EMAIL'];
160
+ if (!token || !email) {
161
+ console.error(`Jira API credentials required. Set both JIRA_API_TOKEN and JIRA_USER_EMAIL.\n` +
162
+ ` export JIRA_API_TOKEN=...\n` +
163
+ ` export JIRA_USER_EMAIL=you@company.com\n` +
164
+ `Or save issue data manually:\n` +
165
+ ` codeledger intent from-issue ${issueId} --format json > intent.json\n` +
166
+ ` Then use: --intent-file intent.json`);
167
+ return null;
168
+ }
169
+ const url = `${baseUrl.replace(/\/$/, '')}/rest/api/3/issue/${issueId}`;
170
+ const auth = Buffer.from(`${email}:${token}`).toString('base64');
171
+ try {
172
+ const res = await fetch(url, {
173
+ headers: {
174
+ 'Accept': 'application/json',
175
+ 'Authorization': `Basic ${auth}`,
176
+ },
177
+ });
178
+ if (!res.ok) {
179
+ if (res.status === 404) {
180
+ console.error(`Jira issue not found: ${issueId}`);
181
+ }
182
+ else if (res.status === 401) {
183
+ console.error('Jira API authentication failed. Check JIRA_API_TOKEN and JIRA_USER_EMAIL.');
184
+ }
185
+ else {
186
+ console.error(`Jira API error ${res.status}: ${res.statusText}`);
187
+ }
188
+ return null;
189
+ }
190
+ const data = await res.json();
191
+ // Jira v3 API uses ADF (Atlassian Document Format) for description.
192
+ // Extract plain text from top-level paragraphs.
193
+ const body = extractJiraDescription(data.fields.description);
194
+ return {
195
+ title: data.fields.summary,
196
+ body,
197
+ labels: data.fields.labels,
198
+ state: data.fields.status?.name,
199
+ assignee: data.fields.assignee?.displayName,
200
+ url: `${baseUrl.replace(/\/$/, '')}/browse/${data.key}`,
201
+ };
202
+ }
203
+ catch (err) {
204
+ console.error(`Failed to fetch Jira issue: ${err instanceof Error ? err.message : String(err)}`);
205
+ return null;
206
+ }
207
+ }
208
+ /**
209
+ * Extract plain text from a Jira ADF description or plain string.
210
+ * Handles both v2 (plain string) and v3 (ADF JSON) description formats.
211
+ *
212
+ * Supported ADF node types:
213
+ * - paragraph → joined text
214
+ * - heading → "# text" (with level)
215
+ * - bulletList / orderedList → "- item" / "1. item"
216
+ * - codeBlock → fenced code block
217
+ * - blockquote → "> text"
218
+ * - table → pipe-separated rows
219
+ * - panel → text with panel type prefix
220
+ * - text, hardBreak, mention, emoji, inlineCard (inline nodes)
221
+ */
222
+ export function extractJiraDescription(description) {
223
+ if (typeof description === 'string')
224
+ return description;
225
+ if (!description || typeof description !== 'object')
226
+ return '';
227
+ const doc = description;
228
+ if (!Array.isArray(doc.content))
229
+ return '';
230
+ return extractAdfBlocks(doc.content).join('\n');
231
+ }
232
+ /** Recursively extract text from an array of ADF block nodes. */
233
+ function extractAdfBlocks(blocks) {
234
+ const lines = [];
235
+ for (const block of blocks) {
236
+ switch (block.type) {
237
+ case 'paragraph':
238
+ lines.push(extractInlineText(block.content));
239
+ break;
240
+ case 'heading': {
241
+ const level = block.attrs?.['level'] ?? 2;
242
+ const prefix = '#'.repeat(Math.min(level, 6));
243
+ lines.push(`${prefix} ${extractInlineText(block.content)}`);
244
+ break;
245
+ }
246
+ case 'bulletList':
247
+ if (block.content) {
248
+ for (const item of block.content) {
249
+ if (item.type === 'listItem' && item.content) {
250
+ const itemText = extractAdfBlocks(item.content).join(' ');
251
+ lines.push(`- ${itemText}`);
252
+ }
253
+ }
254
+ }
255
+ break;
256
+ case 'orderedList':
257
+ if (block.content) {
258
+ let idx = 1;
259
+ for (const item of block.content) {
260
+ if (item.type === 'listItem' && item.content) {
261
+ const itemText = extractAdfBlocks(item.content).join(' ');
262
+ lines.push(`${idx}. ${itemText}`);
263
+ idx++;
264
+ }
265
+ }
266
+ }
267
+ break;
268
+ case 'codeBlock': {
269
+ const lang = block.attrs?.['language'] ?? '';
270
+ lines.push(`\`\`\`${lang}`);
271
+ lines.push(extractInlineText(block.content));
272
+ lines.push('```');
273
+ break;
274
+ }
275
+ case 'blockquote':
276
+ if (block.content) {
277
+ for (const inner of extractAdfBlocks(block.content)) {
278
+ lines.push(`> ${inner}`);
279
+ }
280
+ }
281
+ break;
282
+ case 'table':
283
+ if (block.content) {
284
+ for (const row of block.content) {
285
+ if ((row.type === 'tableRow' || row.type === 'tableHeader') && row.content) {
286
+ const cells = row.content.map((cell) => cell.content ? extractAdfBlocks(cell.content).join(' ') : '');
287
+ lines.push(`| ${cells.join(' | ')} |`);
288
+ }
289
+ }
290
+ }
291
+ break;
292
+ case 'panel':
293
+ if (block.content) {
294
+ const panelType = block.attrs?.['panelType'] ?? 'info';
295
+ lines.push(`[${panelType.toUpperCase()}]`);
296
+ lines.push(...extractAdfBlocks(block.content));
297
+ }
298
+ break;
299
+ case 'rule':
300
+ lines.push('---');
301
+ break;
302
+ default:
303
+ // Unknown block type — try to extract inline text as fallback
304
+ if (block.content) {
305
+ const text = extractInlineText(block.content);
306
+ if (text)
307
+ lines.push(text);
308
+ }
309
+ break;
310
+ }
311
+ }
312
+ return lines;
313
+ }
314
+ /** Extract plain text from an array of ADF inline nodes. */
315
+ function extractInlineText(nodes) {
316
+ if (!nodes)
317
+ return '';
318
+ const parts = [];
319
+ for (const node of nodes) {
320
+ switch (node.type) {
321
+ case 'text':
322
+ if (typeof node.text === 'string')
323
+ parts.push(node.text);
324
+ break;
325
+ case 'hardBreak':
326
+ parts.push('\n');
327
+ break;
328
+ case 'mention':
329
+ parts.push(`@${node.attrs?.['text'] ?? 'user'}`);
330
+ break;
331
+ case 'emoji':
332
+ parts.push(node.attrs?.['shortName'] ?? '');
333
+ break;
334
+ case 'inlineCard':
335
+ parts.push(node.attrs?.['url'] ?? '');
336
+ break;
337
+ default:
338
+ // Unknown inline — try text field
339
+ if (typeof node.text === 'string')
340
+ parts.push(node.text);
341
+ break;
342
+ }
343
+ }
344
+ return parts.join('');
345
+ }
346
+ // ── Repo Inference ───────────────────────────────────────────────────────────
347
+ function inferGitHubRepo() {
348
+ try {
349
+ const remote = execSync('git remote get-url origin', { encoding: 'utf-8', timeout: 5000 }).trim();
350
+ // SSH: git@github.com:owner/repo.git
351
+ const sshMatch = remote.match(/github\.com[:/]([^/]+\/[^.]+?)(?:\.git)?$/);
352
+ if (sshMatch)
353
+ return sshMatch[1];
354
+ // HTTPS: https://github.com/owner/repo.git
355
+ const httpsMatch = remote.match(/github\.com\/([^/]+\/[^.]+?)(?:\.git)?$/);
356
+ if (httpsMatch)
357
+ return httpsMatch[1];
358
+ return null;
359
+ }
360
+ catch {
361
+ return null;
362
+ }
363
+ }
364
+ //# sourceMappingURL=fetcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetcher.js","sourceRoot":"","sources":["../../src/intent/fetcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Intent loader — resolves an IssueIntent from:
3
+ * 1. --intent-file <path> (pre-extracted JSON)
4
+ * 2. --issue <ID> (fetch from tracker, extract intent)
5
+ * 3. branch name inference (via tracker_prefix config)
6
+ * 4. (none) (returns null — diff-only inference)
7
+ */
8
+ import type { IssueIntent } from './types.js';
9
+ export interface IntentSource {
10
+ issue?: string;
11
+ intentFile?: string;
12
+ trackerPrefix?: string;
13
+ }
14
+ /**
15
+ * Infer an issue ID from a branch name using a tracker prefix.
16
+ * E.g., branch "feat/LINEAR-123-add-search" with prefix "LINEAR" → "LINEAR-123"
17
+ *
18
+ * When branchName is omitted, reads current branch from git.
19
+ */
20
+ export declare function inferIssueFromBranch(trackerPrefix: string, branchName?: string): string | null;
21
+ /**
22
+ * Load intent from the best available source.
23
+ * Returns null if no intent source is provided.
24
+ */
25
+ export declare function loadIntent(source: IntentSource): Promise<IssueIntent | null>;
26
+ //# sourceMappingURL=loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/intent/loader.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAI9C,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAmB9F;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAuClF"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Intent loader — resolves an IssueIntent from:
3
+ * 1. --intent-file <path> (pre-extracted JSON)
4
+ * 2. --issue <ID> (fetch from tracker, extract intent)
5
+ * 3. branch name inference (via tracker_prefix config)
6
+ * 4. (none) (returns null — diff-only inference)
7
+ */
8
+ import { readFileSync, existsSync } from 'node:fs';
9
+ import { execSync } from 'node:child_process';
10
+ import { fetchIssue } from './fetcher.js';
11
+ import { extractIntent } from './extractor.js';
12
+ /**
13
+ * Infer an issue ID from a branch name using a tracker prefix.
14
+ * E.g., branch "feat/LINEAR-123-add-search" with prefix "LINEAR" → "LINEAR-123"
15
+ *
16
+ * When branchName is omitted, reads current branch from git.
17
+ */
18
+ export function inferIssueFromBranch(trackerPrefix, branchName) {
19
+ if (!trackerPrefix)
20
+ return null;
21
+ let branch = branchName;
22
+ if (!branch) {
23
+ try {
24
+ branch = execSync('git rev-parse --abbrev-ref HEAD', {
25
+ encoding: 'utf-8',
26
+ timeout: 5000,
27
+ }).trim();
28
+ }
29
+ catch {
30
+ return null;
31
+ }
32
+ }
33
+ // Match PREFIX-123 anywhere in the branch name
34
+ const pattern = new RegExp(`(${trackerPrefix}-\\d+)`, 'i');
35
+ const match = branch.match(pattern);
36
+ return match?.[1] ?? null;
37
+ }
38
+ /**
39
+ * Load intent from the best available source.
40
+ * Returns null if no intent source is provided.
41
+ */
42
+ export async function loadIntent(source) {
43
+ // Priority 1: pre-extracted file
44
+ if (source.intentFile) {
45
+ if (!existsSync(source.intentFile)) {
46
+ console.error(`Intent file not found: ${source.intentFile}`);
47
+ process.exit(1);
48
+ }
49
+ try {
50
+ const content = readFileSync(source.intentFile, 'utf-8');
51
+ return JSON.parse(content);
52
+ }
53
+ catch {
54
+ console.error(`Failed to parse intent file: ${source.intentFile}`);
55
+ process.exit(1);
56
+ }
57
+ }
58
+ // Priority 2: explicit issue ID
59
+ if (source.issue) {
60
+ const raw = await fetchIssue(source.issue);
61
+ if (!raw) {
62
+ console.error(`Could not fetch issue: ${source.issue}`);
63
+ return null;
64
+ }
65
+ return extractIntent(source.issue, raw);
66
+ }
67
+ // Priority 3: infer from branch name using tracker prefix
68
+ if (source.trackerPrefix) {
69
+ const inferred = inferIssueFromBranch(source.trackerPrefix);
70
+ if (inferred) {
71
+ const raw = await fetchIssue(inferred);
72
+ if (raw) {
73
+ return extractIntent(inferred, raw);
74
+ }
75
+ // Inference found a match but fetch failed — not fatal, fall through
76
+ }
77
+ }
78
+ return null;
79
+ }
80
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/intent/loader.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAQ/C;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,aAAqB,EAAE,UAAmB;IAC7E,IAAI,CAAC,aAAa;QAAE,OAAO,IAAI,CAAC;IAEhC,IAAI,MAAM,GAAG,UAAU,CAAC;IACxB,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,IAAI,CAAC;YACH,MAAM,GAAG,QAAQ,CAAC,iCAAiC,EAAE;gBACnD,QAAQ,EAAE,OAAO;gBACjB,OAAO,EAAE,IAAI;aACd,CAAC,CAAC,IAAI,EAAE,CAAC;QACZ,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,+CAA+C;IAC/C,MAAM,OAAO,GAAG,IAAI,MAAM,CAAC,IAAI,aAAa,QAAQ,EAAE,GAAG,CAAC,CAAC;IAC3D,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACpC,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AAC5B,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAoB;IACnD,iCAAiC;IACjC,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACtB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;YACnC,OAAO,CAAC,KAAK,CAAC,0BAA0B,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;YAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;YACzD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAgB,CAAC;QAC5C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,KAAK,CAAC,gCAAgC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;YACnE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAED,gCAAgC;IAChC,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC3C,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,CAAC,KAAK,CAAC,0BAA0B,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;YACxD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,aAAa,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC1C,CAAC;IAED,0DAA0D;IAC1D,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,oBAAoB,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;QAC5D,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAC;YACvC,IAAI,GAAG,EAAE,CAAC;gBACR,OAAO,aAAa,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;YACtC,CAAC;YACD,qEAAqE;QACvE,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Shared intent types for issue-driven context.
3
+ *
4
+ * An IssueIntent represents structured data extracted from an external
5
+ * issue tracker (Linear, Jira, GitHub Issues, etc.) that enriches
6
+ * commit messages, PR summaries, and other downstream outputs.
7
+ */
8
+ export interface IssueIntent {
9
+ /** Issue title */
10
+ title: string;
11
+ /** Inferred high-level goal */
12
+ goal: string;
13
+ /** Constraints extracted from the issue (if detectable) */
14
+ constraints: string[];
15
+ /** Acceptance criteria (if present in the issue body) */
16
+ acceptance_criteria: string[];
17
+ /** Source issue identifier (e.g., LINEAR-123, JIRA-456) */
18
+ source_id: string;
19
+ /** Source system (e.g., 'github', 'linear', 'jira', 'manual') */
20
+ source_system: string;
21
+ /** Raw issue body (for reference) */
22
+ raw: string;
23
+ }
24
+ /** Minimal issue data fetched from a tracker API */
25
+ export interface RawIssueData {
26
+ title: string;
27
+ body: string;
28
+ labels?: string[];
29
+ state?: string;
30
+ assignee?: string;
31
+ url?: string;
32
+ }
33
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/intent/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,WAAW;IAC1B,kBAAkB;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,yDAAyD;IACzD,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,2DAA2D;IAC3D,SAAS,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,aAAa,EAAE,MAAM,CAAC;IACtB,qCAAqC;IACrC,GAAG,EAAE,MAAM,CAAC;CACb;AAED,oDAAoD;AACpD,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Shared intent types for issue-driven context.
3
+ *
4
+ * An IssueIntent represents structured data extracted from an external
5
+ * issue tracker (Linear, Jira, GitHub Issues, etc.) that enriches
6
+ * commit messages, PR summaries, and other downstream outputs.
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/intent/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Project-level configuration loader for .codeledger.yml
3
+ *
4
+ * Reads optional project config from repo root (.codeledger.yml) that controls
5
+ * commit-msg, pr-summary, and PR review bot defaults. This is separate from
6
+ * the core .codeledger/config.json which handles scoring, selection, and harness.
7
+ *
8
+ * Uses a minimal YAML parser (no dependency) — supports only the flat/nested
9
+ * key-value structure documented in sample.codeledger.yml.
10
+ */
11
+ export interface ProjectConfig {
12
+ pr: {
13
+ base_branch: string;
14
+ comment_enabled: boolean;
15
+ sections: string[];
16
+ };
17
+ verify: {
18
+ mode: 'observe' | 'warn' | 'block';
19
+ severity_threshold: string;
20
+ review_intelligence: {
21
+ enabled: boolean;
22
+ invariants: Record<string, boolean>;
23
+ };
24
+ };
25
+ commit_msg: {
26
+ signature: boolean;
27
+ format: 'full' | 'minimal';
28
+ };
29
+ intent: {
30
+ tracker_prefix: string;
31
+ };
32
+ }
33
+ /**
34
+ * Load project config from .codeledger.yml in the given directory.
35
+ * Returns defaults if the file doesn't exist or fails to parse.
36
+ */
37
+ export declare function loadProjectConfig(cwd: string): ProjectConfig;
38
+ //# sourceMappingURL=project-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-config.d.ts","sourceRoot":"","sources":["../src/project-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE;QACF,WAAW,EAAE,MAAM,CAAC;QACpB,eAAe,EAAE,OAAO,CAAC;QACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;KACpB,CAAC;IACF,MAAM,EAAE;QACN,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;QACnC,kBAAkB,EAAE,MAAM,CAAC;QAC3B,mBAAmB,EAAE;YACnB,OAAO,EAAE,OAAO,CAAC;YACjB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;SACrC,CAAC;KACH,CAAC;IACF,UAAU,EAAE;QACV,SAAS,EAAE,OAAO,CAAC;QACnB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;KAC5B,CAAC;IACF,MAAM,EAAE;QACN,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;CACH;AAmID;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAe5D"}