@codeledger/cli 0.6.8 → 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.
- package/dist/commands/activate.d.ts.map +1 -1
- package/dist/commands/activate.js +94 -26
- package/dist/commands/activate.js.map +1 -1
- package/dist/commands/ci.d.ts +16 -0
- package/dist/commands/ci.d.ts.map +1 -0
- package/dist/commands/ci.js +323 -0
- package/dist/commands/ci.js.map +1 -0
- package/dist/commands/commit-msg.d.ts +58 -0
- package/dist/commands/commit-msg.d.ts.map +1 -0
- package/dist/commands/commit-msg.js +461 -0
- package/dist/commands/commit-msg.js.map +1 -0
- package/dist/commands/compare.d.ts.map +1 -1
- package/dist/commands/compare.js +8 -0
- package/dist/commands/compare.js.map +1 -1
- package/dist/commands/context.d.ts +17 -0
- package/dist/commands/context.d.ts.map +1 -0
- package/dist/commands/context.js +687 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +65 -0
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/enable.d.ts +7 -0
- package/dist/commands/enable.d.ts.map +1 -0
- package/dist/commands/enable.js +75 -0
- package/dist/commands/enable.js.map +1 -0
- package/dist/commands/features.d.ts +2 -0
- package/dist/commands/features.d.ts.map +1 -0
- package/dist/commands/features.js +182 -0
- package/dist/commands/features.js.map +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +22 -1
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/intent.d.ts +5 -3
- package/dist/commands/intent.d.ts.map +1 -1
- package/dist/commands/intent.js +135 -4
- package/dist/commands/intent.js.map +1 -1
- package/dist/commands/ledger.d.ts +14 -0
- package/dist/commands/ledger.d.ts.map +1 -0
- package/dist/commands/ledger.js +128 -0
- package/dist/commands/ledger.js.map +1 -0
- package/dist/commands/license.d.ts +45 -0
- package/dist/commands/license.d.ts.map +1 -0
- package/dist/commands/license.js +240 -0
- package/dist/commands/license.js.map +1 -0
- package/dist/commands/orchestrate.d.ts +12 -0
- package/dist/commands/orchestrate.d.ts.map +1 -0
- package/dist/commands/orchestrate.js +119 -0
- package/dist/commands/orchestrate.js.map +1 -0
- package/dist/commands/policy-simulate.d.ts +9 -0
- package/dist/commands/policy-simulate.d.ts.map +1 -0
- package/dist/commands/policy-simulate.js +46 -0
- package/dist/commands/policy-simulate.js.map +1 -0
- package/dist/commands/pr-summary.d.ts +59 -0
- package/dist/commands/pr-summary.d.ts.map +1 -0
- package/dist/commands/pr-summary.js +524 -0
- package/dist/commands/pr-summary.js.map +1 -0
- package/dist/commands/provenance.d.ts +10 -0
- package/dist/commands/provenance.d.ts.map +1 -0
- package/dist/commands/provenance.js +87 -0
- package/dist/commands/provenance.js.map +1 -0
- package/dist/commands/replay.d.ts +2 -0
- package/dist/commands/replay.d.ts.map +1 -0
- package/dist/commands/replay.js +181 -0
- package/dist/commands/replay.js.map +1 -0
- package/dist/commands/serve.d.ts +3 -0
- package/dist/commands/serve.d.ts.map +1 -1
- package/dist/commands/serve.js +73 -1
- package/dist/commands/serve.js.map +1 -1
- package/dist/commands/session-cleanup.js +1 -0
- package/dist/commands/session-cleanup.js.map +1 -1
- package/dist/commands/session-summary.d.ts.map +1 -1
- package/dist/commands/session-summary.js +180 -3
- package/dist/commands/session-summary.js.map +1 -1
- package/dist/commands/setup-ci.d.ts +17 -1
- package/dist/commands/setup-ci.d.ts.map +1 -1
- package/dist/commands/setup-ci.js +202 -51
- package/dist/commands/setup-ci.js.map +1 -1
- package/dist/commands/share.js +1 -1
- package/dist/commands/share.js.map +1 -1
- package/dist/commands/stats.d.ts +8 -0
- package/dist/commands/stats.d.ts.map +1 -0
- package/dist/commands/stats.js +164 -0
- package/dist/commands/stats.js.map +1 -0
- package/dist/commands/team-ledger.d.ts +11 -0
- package/dist/commands/team-ledger.d.ts.map +1 -0
- package/dist/commands/team-ledger.js +74 -0
- package/dist/commands/team-ledger.js.map +1 -0
- package/dist/commands/team-metrics.d.ts +8 -0
- package/dist/commands/team-metrics.d.ts.map +1 -0
- package/dist/commands/team-metrics.js +57 -0
- package/dist/commands/team-metrics.js.map +1 -0
- package/dist/commands/upgrade.d.ts +6 -0
- package/dist/commands/upgrade.d.ts.map +1 -0
- package/dist/commands/upgrade.js +39 -0
- package/dist/commands/upgrade.js.map +1 -0
- package/dist/commands/verify.d.ts.map +1 -1
- package/dist/commands/verify.js +35 -3
- package/dist/commands/verify.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +256 -36
- package/dist/index.js.map +1 -1
- package/dist/intent/extractor.d.ts +15 -0
- package/dist/intent/extractor.d.ts.map +1 -0
- package/dist/intent/extractor.js +149 -0
- package/dist/intent/extractor.js.map +1 -0
- package/dist/intent/fetcher.d.ts +33 -0
- package/dist/intent/fetcher.d.ts.map +1 -0
- package/dist/intent/fetcher.js +364 -0
- package/dist/intent/fetcher.js.map +1 -0
- package/dist/intent/loader.d.ts +26 -0
- package/dist/intent/loader.d.ts.map +1 -0
- package/dist/intent/loader.js +80 -0
- package/dist/intent/loader.js.map +1 -0
- package/dist/intent/types.d.ts +33 -0
- package/dist/intent/types.d.ts.map +1 -0
- package/dist/intent/types.js +9 -0
- package/dist/intent/types.js.map +1 -0
- package/dist/project-config.d.ts +38 -0
- package/dist/project-config.d.ts.map +1 -0
- package/dist/project-config.js +206 -0
- package/dist/project-config.js.map +1 -0
- package/dist/review-intelligence/detectors/architecture-graph.d.ts +18 -0
- package/dist/review-intelligence/detectors/architecture-graph.d.ts.map +1 -0
- package/dist/review-intelligence/detectors/architecture-graph.js +73 -0
- package/dist/review-intelligence/detectors/architecture-graph.js.map +1 -0
- package/dist/review-intelligence/detectors/pack-rules.d.ts +16 -0
- package/dist/review-intelligence/detectors/pack-rules.d.ts.map +1 -0
- package/dist/review-intelligence/detectors/pack-rules.js +107 -0
- package/dist/review-intelligence/detectors/pack-rules.js.map +1 -0
- package/dist/review-intelligence/fixes/index.d.ts +18 -0
- package/dist/review-intelligence/fixes/index.d.ts.map +1 -1
- package/dist/review-intelligence/fixes/index.js +198 -9
- package/dist/review-intelligence/fixes/index.js.map +1 -1
- package/dist/review-intelligence/index.d.ts +4 -1
- package/dist/review-intelligence/index.d.ts.map +1 -1
- package/dist/review-intelligence/index.js +20 -3
- package/dist/review-intelligence/index.js.map +1 -1
- package/dist/review-intelligence/invariants.d.ts +15 -0
- package/dist/review-intelligence/invariants.d.ts.map +1 -1
- package/dist/review-intelligence/invariants.js +36 -5
- package/dist/review-intelligence/invariants.js.map +1 -1
- package/dist/review-intelligence/types.d.ts +16 -12
- package/dist/review-intelligence/types.d.ts.map +1 -1
- package/dist/review-intelligence/types.js +9 -1
- package/dist/review-intelligence/types.js.map +1 -1
- package/dist/templates/claude-md.d.ts.map +1 -1
- package/dist/templates/claude-md.js +32 -127
- package/dist/templates/claude-md.js.map +1 -1
- package/dist/templates/config.js +4 -4
- package/dist/templates/config.js.map +1 -1
- package/dist/templates/hooks.d.ts +3 -1
- package/dist/templates/hooks.d.ts.map +1 -1
- package/dist/templates/hooks.js +101 -2
- package/dist/templates/hooks.js.map +1 -1
- package/package.json +11 -10
- package/LICENSE +0 -27
|
@@ -0,0 +1,524 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* codeledger pr-summary — Generate a structured PR summary from branch changes.
|
|
3
|
+
*
|
|
4
|
+
* Architecture:
|
|
5
|
+
* 1. collectPRContext() — gather diff vs base, commits, branch name
|
|
6
|
+
* 2. analyzePRChanges() — classify changes, detect risks, group by subsystem
|
|
7
|
+
* 3. renderPRSummary() — build markdown or JSON PR summary
|
|
8
|
+
*
|
|
9
|
+
* Flags:
|
|
10
|
+
* --base <branch> Base branch (default: main)
|
|
11
|
+
* --issue <ID> Issue identifier for intent context
|
|
12
|
+
* --intent-file <path> Path to pre-extracted intent JSON
|
|
13
|
+
* --format markdown|json Output format (default: markdown)
|
|
14
|
+
* --write <file> Write output to file instead of stdout
|
|
15
|
+
* --title-only Output only the PR title
|
|
16
|
+
* --body-only Output only the PR body (no title)
|
|
17
|
+
*/
|
|
18
|
+
import { execSync } from 'node:child_process';
|
|
19
|
+
import { writeFileSync } from 'node:fs';
|
|
20
|
+
import { loadIntent } from '../intent/loader.js';
|
|
21
|
+
import { loadProjectConfig } from '../project-config.js';
|
|
22
|
+
// ── 1. PR Context Collection ─────────────────────────────────────────────────
|
|
23
|
+
export function collectPRContext(cwd, baseBranch) {
|
|
24
|
+
let branchName = '';
|
|
25
|
+
try {
|
|
26
|
+
branchName = execSync('git rev-parse --abbrev-ref HEAD', { cwd, encoding: 'utf-8' }).trim();
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
// Detached HEAD — use empty
|
|
30
|
+
}
|
|
31
|
+
// Get merge base to diff against
|
|
32
|
+
let mergeBase;
|
|
33
|
+
try {
|
|
34
|
+
mergeBase = execSync(`git merge-base ${baseBranch} HEAD`, { cwd, encoding: 'utf-8' }).trim();
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// No merge base found — try diffing directly
|
|
38
|
+
mergeBase = baseBranch;
|
|
39
|
+
}
|
|
40
|
+
let diff;
|
|
41
|
+
try {
|
|
42
|
+
diff = execSync(`git diff ${mergeBase}...HEAD`, {
|
|
43
|
+
cwd,
|
|
44
|
+
encoding: 'utf-8',
|
|
45
|
+
maxBuffer: 20 * 1024 * 1024,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
console.error(`Failed to compute diff against ${baseBranch}. Is it a valid branch?`);
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
if (!diff.trim()) {
|
|
53
|
+
console.error(`No changes found between ${baseBranch} and HEAD.`);
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
let filesChanged;
|
|
57
|
+
try {
|
|
58
|
+
const nameOnly = execSync(`git diff --name-only ${mergeBase}...HEAD`, { cwd, encoding: 'utf-8' });
|
|
59
|
+
filesChanged = nameOnly.trim().split('\n').filter(Boolean);
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
filesChanged = [];
|
|
63
|
+
}
|
|
64
|
+
let commits;
|
|
65
|
+
try {
|
|
66
|
+
const log = execSync(`git log --oneline ${mergeBase}..HEAD`, { cwd, encoding: 'utf-8' });
|
|
67
|
+
commits = log.trim().split('\n').filter(Boolean).map((line) => {
|
|
68
|
+
const spaceIdx = line.indexOf(' ');
|
|
69
|
+
return {
|
|
70
|
+
hash: line.slice(0, spaceIdx),
|
|
71
|
+
subject: line.slice(spaceIdx + 1),
|
|
72
|
+
};
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
commits = [];
|
|
77
|
+
}
|
|
78
|
+
let additions = 0;
|
|
79
|
+
let deletions = 0;
|
|
80
|
+
try {
|
|
81
|
+
const stat = execSync(`git diff --shortstat ${mergeBase}...HEAD`, { cwd, encoding: 'utf-8' });
|
|
82
|
+
const addMatch = stat.match(/(\d+) insertion/);
|
|
83
|
+
const delMatch = stat.match(/(\d+) deletion/);
|
|
84
|
+
if (addMatch)
|
|
85
|
+
additions = parseInt(addMatch[1], 10);
|
|
86
|
+
if (delMatch)
|
|
87
|
+
deletions = parseInt(delMatch[1], 10);
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
// Non-fatal
|
|
91
|
+
}
|
|
92
|
+
return { diff, filesChanged, commits, branchName, baseBranch, additions, deletions };
|
|
93
|
+
}
|
|
94
|
+
// ── 2. PR Analysis ───────────────────────────────────────────────────────────
|
|
95
|
+
export function analyzePRChanges(ctx, intent) {
|
|
96
|
+
const { filesChanged, commits, diff, branchName } = ctx;
|
|
97
|
+
// Group files by subsystem
|
|
98
|
+
const groups = groupFilesBySubsystem(filesChanged);
|
|
99
|
+
// Classify the overall change type from commits
|
|
100
|
+
const changeType = inferChangeType(commits, filesChanged, diff);
|
|
101
|
+
// Generate title
|
|
102
|
+
const title = generateTitle(changeType, branchName, commits, intent);
|
|
103
|
+
// Generate summary
|
|
104
|
+
const summary = generateSummary(changeType, filesChanged, commits, intent);
|
|
105
|
+
// Build key changes from file groups
|
|
106
|
+
const keyChanges = buildKeyChanges(groups, diff);
|
|
107
|
+
// Detect risks
|
|
108
|
+
const risks = detectRisks(filesChanged, diff, ctx);
|
|
109
|
+
// Infer testing notes
|
|
110
|
+
const testingNotes = inferTestingNotes(filesChanged, diff);
|
|
111
|
+
// Business impact (only if intent is available)
|
|
112
|
+
const businessImpact = intent
|
|
113
|
+
? `This change addresses: ${intent.goal}`
|
|
114
|
+
: null;
|
|
115
|
+
// Why this change exists (from intent or commits)
|
|
116
|
+
const whyThisChange = inferWhyThisChange(intent, commits, branchName);
|
|
117
|
+
// Subsystems
|
|
118
|
+
const subsystemsTouched = [...groups.keys()];
|
|
119
|
+
// Suggested reviewer focus
|
|
120
|
+
const reviewerFocus = inferReviewerFocus(filesChanged, risks, groups, diff);
|
|
121
|
+
return {
|
|
122
|
+
title,
|
|
123
|
+
summary,
|
|
124
|
+
whyThisChange,
|
|
125
|
+
keyChanges,
|
|
126
|
+
risks,
|
|
127
|
+
testingNotes,
|
|
128
|
+
businessImpact,
|
|
129
|
+
subsystemsTouched,
|
|
130
|
+
reviewerFocus,
|
|
131
|
+
stats: {
|
|
132
|
+
filesChanged: filesChanged.length,
|
|
133
|
+
additions: ctx.additions,
|
|
134
|
+
deletions: ctx.deletions,
|
|
135
|
+
commits: commits.length,
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
function groupFilesBySubsystem(files) {
|
|
140
|
+
const groups = new Map();
|
|
141
|
+
for (const f of files) {
|
|
142
|
+
const parts = f.split('/');
|
|
143
|
+
let subsystem;
|
|
144
|
+
if (parts[0] === 'packages' && parts.length >= 2) {
|
|
145
|
+
subsystem = parts[1];
|
|
146
|
+
}
|
|
147
|
+
else if (parts[0] === 'src' && parts.length >= 2) {
|
|
148
|
+
subsystem = parts[1];
|
|
149
|
+
}
|
|
150
|
+
else if (parts[0] === 'tests' || parts[0] === 'test') {
|
|
151
|
+
subsystem = 'tests';
|
|
152
|
+
}
|
|
153
|
+
else if (parts[0] === 'docs' || parts[0] === 'doc') {
|
|
154
|
+
subsystem = 'docs';
|
|
155
|
+
}
|
|
156
|
+
else if (parts[0] === '.github') {
|
|
157
|
+
subsystem = 'ci';
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
subsystem = parts[0] ?? 'root';
|
|
161
|
+
}
|
|
162
|
+
const group = groups.get(subsystem);
|
|
163
|
+
if (group) {
|
|
164
|
+
group.push(f);
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
groups.set(subsystem, [f]);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return groups;
|
|
171
|
+
}
|
|
172
|
+
function inferChangeType(commits, files, diff) {
|
|
173
|
+
// Check commit subjects for conventional commit prefixes
|
|
174
|
+
const prefixCounts = new Map();
|
|
175
|
+
for (const c of commits) {
|
|
176
|
+
const match = c.subject.match(/^(feat|fix|refactor|perf|test|docs|chore|build|ci)\b/);
|
|
177
|
+
if (match) {
|
|
178
|
+
const prefix = match[1];
|
|
179
|
+
prefixCounts.set(prefix, (prefixCounts.get(prefix) ?? 0) + 1);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
if (prefixCounts.size > 0) {
|
|
183
|
+
// Return the most common prefix
|
|
184
|
+
let maxPrefix = 'feat';
|
|
185
|
+
let maxCount = 0;
|
|
186
|
+
for (const [prefix, count] of prefixCounts) {
|
|
187
|
+
if (count > maxCount) {
|
|
188
|
+
maxPrefix = prefix;
|
|
189
|
+
maxCount = count;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return maxPrefix;
|
|
193
|
+
}
|
|
194
|
+
// Fall back to file-pattern analysis
|
|
195
|
+
const allTest = files.length > 0 && files.every((f) => /\.test\.|\.spec\.|__tests__/.test(f));
|
|
196
|
+
if (allTest)
|
|
197
|
+
return 'test';
|
|
198
|
+
const allDocs = files.length > 0 && files.every((f) => /\.md$|\.txt$|\.rst$/.test(f));
|
|
199
|
+
if (allDocs)
|
|
200
|
+
return 'docs';
|
|
201
|
+
if (/^new file mode/m.test(diff))
|
|
202
|
+
return 'feat';
|
|
203
|
+
return 'feat';
|
|
204
|
+
}
|
|
205
|
+
function generateTitle(changeType, branchName, commits, intent) {
|
|
206
|
+
// If intent has a title, use it
|
|
207
|
+
if (intent) {
|
|
208
|
+
const prefix = changeType === 'feat' ? '' : `${changeType}: `;
|
|
209
|
+
const title = `${prefix}${intent.title}`;
|
|
210
|
+
return title.length <= 70 ? title : title.slice(0, 67) + '...';
|
|
211
|
+
}
|
|
212
|
+
// If there's only one commit, use its subject
|
|
213
|
+
if (commits.length === 1) {
|
|
214
|
+
return commits[0].subject;
|
|
215
|
+
}
|
|
216
|
+
// Extract scope from branch name
|
|
217
|
+
const branchMatch = branchName.match(/^(?:feat|fix|refactor|chore)\/(.+)/);
|
|
218
|
+
if (branchMatch) {
|
|
219
|
+
const desc = branchMatch[1].replace(/[-_]/g, ' ');
|
|
220
|
+
return desc.length <= 70 ? desc : desc.slice(0, 67) + '...';
|
|
221
|
+
}
|
|
222
|
+
// Fall back to first commit
|
|
223
|
+
if (commits.length > 0) {
|
|
224
|
+
return commits[0].subject;
|
|
225
|
+
}
|
|
226
|
+
return `${changeType}: update codebase`;
|
|
227
|
+
}
|
|
228
|
+
function generateSummary(changeType, files, commits, intent) {
|
|
229
|
+
const parts = [];
|
|
230
|
+
if (intent) {
|
|
231
|
+
parts.push(`This PR addresses: ${intent.goal}`);
|
|
232
|
+
}
|
|
233
|
+
const fileCount = files.length;
|
|
234
|
+
const commitCount = commits.length;
|
|
235
|
+
if (commitCount === 1) {
|
|
236
|
+
parts.push(`Single commit ${changeType} touching ${fileCount} file${fileCount === 1 ? '' : 's'}.`);
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
parts.push(`${commitCount} commits across ${fileCount} file${fileCount === 1 ? '' : 's'}.`);
|
|
240
|
+
}
|
|
241
|
+
if (intent && intent.acceptance_criteria.length > 0) {
|
|
242
|
+
parts.push(`Acceptance criteria: ${intent.acceptance_criteria.length} item${intent.acceptance_criteria.length === 1 ? '' : 's'} defined.`);
|
|
243
|
+
}
|
|
244
|
+
return parts.join(' ');
|
|
245
|
+
}
|
|
246
|
+
function buildKeyChanges(groups, diff) {
|
|
247
|
+
const changes = [];
|
|
248
|
+
for (const [subsystem, files] of groups) {
|
|
249
|
+
const items = [];
|
|
250
|
+
// Extract structural changes from the diff for these files
|
|
251
|
+
for (const f of files.slice(0, 5)) {
|
|
252
|
+
const filename = f.split('/').pop() ?? f;
|
|
253
|
+
// Check if it's a new file
|
|
254
|
+
const newFilePattern = new RegExp(`diff --git a/${f.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')} b/.*\\nnew file mode`);
|
|
255
|
+
if (newFilePattern.test(diff)) {
|
|
256
|
+
items.push(`Add ${filename}`);
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
items.push(`Update ${filename}`);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
if (files.length > 5) {
|
|
263
|
+
items.push(`... and ${files.length - 5} more files`);
|
|
264
|
+
}
|
|
265
|
+
changes.push({ category: subsystem, items });
|
|
266
|
+
}
|
|
267
|
+
return changes;
|
|
268
|
+
}
|
|
269
|
+
function detectRisks(files, diff, ctx) {
|
|
270
|
+
const risks = [];
|
|
271
|
+
// Large PR
|
|
272
|
+
if (files.length > 30) {
|
|
273
|
+
risks.push(`Large PR: ${files.length} files changed — consider splitting`);
|
|
274
|
+
}
|
|
275
|
+
// Large diff
|
|
276
|
+
if (ctx.additions + ctx.deletions > 1000) {
|
|
277
|
+
risks.push(`Significant code change: +${ctx.additions}/-${ctx.deletions} lines`);
|
|
278
|
+
}
|
|
279
|
+
// Migration files
|
|
280
|
+
if (files.some((f) => /migration|migrate/i.test(f))) {
|
|
281
|
+
risks.push('Contains database migration — verify rollback strategy');
|
|
282
|
+
}
|
|
283
|
+
// Config/env changes
|
|
284
|
+
if (files.some((f) => /\.env|config\.|secrets/i.test(f))) {
|
|
285
|
+
risks.push('Configuration or environment changes detected');
|
|
286
|
+
}
|
|
287
|
+
// Dependency changes
|
|
288
|
+
if (files.some((f) => /package\.json$|pnpm-lock|yarn\.lock|Cargo\.lock/i.test(f))) {
|
|
289
|
+
risks.push('Dependency changes — review for supply chain impact');
|
|
290
|
+
}
|
|
291
|
+
// Security-sensitive patterns
|
|
292
|
+
if (/password|secret|token|api[_-]?key|credential/i.test(diff)) {
|
|
293
|
+
risks.push('Potential security-sensitive content in diff — review carefully');
|
|
294
|
+
}
|
|
295
|
+
return risks;
|
|
296
|
+
}
|
|
297
|
+
function inferTestingNotes(files, diff) {
|
|
298
|
+
const notes = [];
|
|
299
|
+
const testFiles = files.filter((f) => /\.test\.|\.spec\.|__tests__/.test(f));
|
|
300
|
+
if (testFiles.length > 0) {
|
|
301
|
+
notes.push(`${testFiles.length} test file${testFiles.length === 1 ? '' : 's'} added/updated`);
|
|
302
|
+
}
|
|
303
|
+
else if (files.some((f) => /\.ts$|\.js$|\.py$|\.go$|\.rs$/.test(f))) {
|
|
304
|
+
notes.push('No test files changed — verify test coverage');
|
|
305
|
+
}
|
|
306
|
+
// Check for test additions in diff
|
|
307
|
+
const testAdds = [...diff.matchAll(/^\+.*(?:describe|it|test)\s*\(/gm)].length;
|
|
308
|
+
if (testAdds > 0) {
|
|
309
|
+
notes.push(`${testAdds} new test case${testAdds === 1 ? '' : 's'} detected`);
|
|
310
|
+
}
|
|
311
|
+
return notes;
|
|
312
|
+
}
|
|
313
|
+
function inferWhyThisChange(intent, commits, branchName) {
|
|
314
|
+
// Priority 1: intent goal provides explicit "why"
|
|
315
|
+
if (intent?.goal) {
|
|
316
|
+
return intent.goal;
|
|
317
|
+
}
|
|
318
|
+
// Priority 2: extract from commit messages — look for "because", "so that", "to "
|
|
319
|
+
for (const c of commits) {
|
|
320
|
+
const lower = c.subject.toLowerCase();
|
|
321
|
+
// Conventional commit subjects with meaningful context
|
|
322
|
+
const match = lower.match(/(?:fix|feat|refactor|chore|docs|test)(?:\([^)]*\))?:\s*(.+)/);
|
|
323
|
+
if (match?.[1]) {
|
|
324
|
+
return match[1].charAt(0).toUpperCase() + match[1].slice(1);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
// Priority 3: infer from branch name
|
|
328
|
+
const branchMatch = branchName.match(/^(?:feat|fix|chore|refactor|hotfix)\/(.+)/);
|
|
329
|
+
if (branchMatch?.[1]) {
|
|
330
|
+
return branchMatch[1].replace(/[-_]/g, ' ').replace(/^\w/, (c) => c.toUpperCase());
|
|
331
|
+
}
|
|
332
|
+
return null;
|
|
333
|
+
}
|
|
334
|
+
function inferReviewerFocus(files, risks, groups, diff) {
|
|
335
|
+
const focus = [];
|
|
336
|
+
// High-risk files get focus
|
|
337
|
+
const riskFiles = files.filter((f) => /auth|security|crypto|migration|payment|billing|permission/i.test(f));
|
|
338
|
+
if (riskFiles.length > 0) {
|
|
339
|
+
focus.push(`Security-sensitive files: ${riskFiles.slice(0, 3).join(', ')}`);
|
|
340
|
+
}
|
|
341
|
+
// API surface changes
|
|
342
|
+
const apiFiles = files.filter((f) => /(?:route|controller|handler|endpoint|api)\./i.test(f) ||
|
|
343
|
+
/\/api\//i.test(f));
|
|
344
|
+
if (apiFiles.length > 0) {
|
|
345
|
+
focus.push(`API surface changes in ${apiFiles.length} file${apiFiles.length === 1 ? '' : 's'}`);
|
|
346
|
+
}
|
|
347
|
+
// Config/infra changes
|
|
348
|
+
if (risks.some((r) => /configuration|environment/i.test(r))) {
|
|
349
|
+
focus.push('Configuration changes — verify environment compatibility');
|
|
350
|
+
}
|
|
351
|
+
// Large subsystems touched
|
|
352
|
+
for (const [subsystem, subsystemFiles] of groups) {
|
|
353
|
+
if (subsystemFiles.length >= 5) {
|
|
354
|
+
focus.push(`Heavy changes in ${subsystem} (${subsystemFiles.length} files)`);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
// Deletion-heavy changes
|
|
358
|
+
if (/^-[^-]/gm.test(diff)) {
|
|
359
|
+
const deletions = [...diff.matchAll(/^-[^-]/gm)].length;
|
|
360
|
+
const additions = [...diff.matchAll(/^\+[^+]/gm)].length;
|
|
361
|
+
if (deletions > additions * 2 && deletions > 20) {
|
|
362
|
+
focus.push('Significant code removal — verify nothing critical was deleted');
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
return focus;
|
|
366
|
+
}
|
|
367
|
+
// ── 3. Rendering ─────────────────────────────────────────────────────────────
|
|
368
|
+
export function renderPRMarkdown(analysis, intent, sections) {
|
|
369
|
+
const lines = [];
|
|
370
|
+
// Default section order matches the product spec
|
|
371
|
+
const activeSections = sections ?? [
|
|
372
|
+
'summary', 'why', 'business_impact', 'key_changes',
|
|
373
|
+
'subsystems_touched', 'risk_signals', 'reviewer_focus', 'testing', 'stats',
|
|
374
|
+
];
|
|
375
|
+
for (const section of activeSections) {
|
|
376
|
+
switch (section) {
|
|
377
|
+
case 'summary':
|
|
378
|
+
lines.push('## Summary');
|
|
379
|
+
lines.push('');
|
|
380
|
+
lines.push(analysis.summary);
|
|
381
|
+
lines.push('');
|
|
382
|
+
break;
|
|
383
|
+
case 'why':
|
|
384
|
+
if (analysis.whyThisChange) {
|
|
385
|
+
lines.push('## Why This Change');
|
|
386
|
+
lines.push('');
|
|
387
|
+
lines.push(analysis.whyThisChange);
|
|
388
|
+
lines.push('');
|
|
389
|
+
}
|
|
390
|
+
break;
|
|
391
|
+
case 'business_impact':
|
|
392
|
+
if (analysis.businessImpact) {
|
|
393
|
+
lines.push('## Business Impact');
|
|
394
|
+
lines.push('');
|
|
395
|
+
lines.push(analysis.businessImpact);
|
|
396
|
+
if (intent && intent.acceptance_criteria.length > 0) {
|
|
397
|
+
lines.push('');
|
|
398
|
+
lines.push('**Acceptance Criteria:**');
|
|
399
|
+
for (const ac of intent.acceptance_criteria) {
|
|
400
|
+
lines.push(`- [ ] ${ac}`);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
lines.push('');
|
|
404
|
+
}
|
|
405
|
+
break;
|
|
406
|
+
case 'key_changes':
|
|
407
|
+
lines.push('## Key Changes');
|
|
408
|
+
lines.push('');
|
|
409
|
+
for (const group of analysis.keyChanges) {
|
|
410
|
+
lines.push(`### ${group.category}`);
|
|
411
|
+
for (const item of group.items) {
|
|
412
|
+
lines.push(`- ${item}`);
|
|
413
|
+
}
|
|
414
|
+
lines.push('');
|
|
415
|
+
}
|
|
416
|
+
break;
|
|
417
|
+
case 'subsystems_touched':
|
|
418
|
+
if (analysis.subsystemsTouched.length > 0) {
|
|
419
|
+
lines.push('## Key Subsystems Touched');
|
|
420
|
+
lines.push('');
|
|
421
|
+
for (const sub of analysis.subsystemsTouched) {
|
|
422
|
+
lines.push(`- \`${sub}\``);
|
|
423
|
+
}
|
|
424
|
+
lines.push('');
|
|
425
|
+
}
|
|
426
|
+
break;
|
|
427
|
+
case 'risk_signals':
|
|
428
|
+
if (analysis.risks.length > 0) {
|
|
429
|
+
lines.push('## Risk Signals');
|
|
430
|
+
lines.push('');
|
|
431
|
+
for (const risk of analysis.risks) {
|
|
432
|
+
lines.push(`- ⚠️ ${risk}`);
|
|
433
|
+
}
|
|
434
|
+
lines.push('');
|
|
435
|
+
}
|
|
436
|
+
break;
|
|
437
|
+
case 'verify_findings':
|
|
438
|
+
// Emit a sentinel marker that the GitHub workflow replaces with actual verify output.
|
|
439
|
+
// When used outside the workflow (e.g., CLI), this marker is invisible in rendered markdown.
|
|
440
|
+
lines.push('<!-- codeledger:verify-findings-placeholder -->');
|
|
441
|
+
lines.push('');
|
|
442
|
+
break;
|
|
443
|
+
case 'reviewer_focus':
|
|
444
|
+
if (analysis.reviewerFocus.length > 0) {
|
|
445
|
+
lines.push('## Suggested Reviewer Focus');
|
|
446
|
+
lines.push('');
|
|
447
|
+
for (const item of analysis.reviewerFocus) {
|
|
448
|
+
lines.push(`- ${item}`);
|
|
449
|
+
}
|
|
450
|
+
lines.push('');
|
|
451
|
+
}
|
|
452
|
+
break;
|
|
453
|
+
case 'testing':
|
|
454
|
+
if (analysis.testingNotes.length > 0) {
|
|
455
|
+
lines.push('## Testing');
|
|
456
|
+
lines.push('');
|
|
457
|
+
for (const note of analysis.testingNotes) {
|
|
458
|
+
lines.push(`- ${note}`);
|
|
459
|
+
}
|
|
460
|
+
lines.push('');
|
|
461
|
+
}
|
|
462
|
+
break;
|
|
463
|
+
case 'stats':
|
|
464
|
+
lines.push('## Stats');
|
|
465
|
+
lines.push('');
|
|
466
|
+
lines.push(`- **Files changed:** ${analysis.stats.filesChanged}`);
|
|
467
|
+
lines.push(`- **Additions:** +${analysis.stats.additions}`);
|
|
468
|
+
lines.push(`- **Deletions:** -${analysis.stats.deletions}`);
|
|
469
|
+
lines.push(`- **Commits:** ${analysis.stats.commits}`);
|
|
470
|
+
lines.push('');
|
|
471
|
+
break;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
return lines.join('\n');
|
|
475
|
+
}
|
|
476
|
+
export function renderPRJSON(analysis) {
|
|
477
|
+
return JSON.stringify(analysis, null, 2);
|
|
478
|
+
}
|
|
479
|
+
// ── Main command ─────────────────────────────────────────────────────────────
|
|
480
|
+
export async function runPRSummary(cwd, flags) {
|
|
481
|
+
// CLI flags override .codeledger.yml defaults
|
|
482
|
+
const projectCfg = loadProjectConfig(cwd);
|
|
483
|
+
const baseBranch = flags['base'] ?? projectCfg.pr.base_branch;
|
|
484
|
+
// 1. Collect PR context
|
|
485
|
+
const ctx = collectPRContext(cwd, baseBranch);
|
|
486
|
+
// 2. Load intent (optional — from flag, file, or branch inference)
|
|
487
|
+
const intent = await loadIntent({
|
|
488
|
+
issue: flags['issue'],
|
|
489
|
+
intentFile: flags['intent-file'],
|
|
490
|
+
trackerPrefix: projectCfg.intent.tracker_prefix || undefined,
|
|
491
|
+
});
|
|
492
|
+
// 3. Analyze changes
|
|
493
|
+
const analysis = analyzePRChanges(ctx, intent);
|
|
494
|
+
// 4. Render output
|
|
495
|
+
const format = flags['format'] ?? 'markdown';
|
|
496
|
+
let output;
|
|
497
|
+
// Resolve section list from config (if not JSON)
|
|
498
|
+
const sections = projectCfg.pr.sections.length > 0 ? projectCfg.pr.sections : undefined;
|
|
499
|
+
if (flags['title-only'] === 'true') {
|
|
500
|
+
output = analysis.title;
|
|
501
|
+
}
|
|
502
|
+
else if (flags['body-only'] === 'true') {
|
|
503
|
+
output = format === 'json'
|
|
504
|
+
? renderPRJSON(analysis)
|
|
505
|
+
: renderPRMarkdown(analysis, intent, sections);
|
|
506
|
+
}
|
|
507
|
+
else {
|
|
508
|
+
if (format === 'json') {
|
|
509
|
+
output = renderPRJSON(analysis);
|
|
510
|
+
}
|
|
511
|
+
else {
|
|
512
|
+
output = `# ${analysis.title}\n\n${renderPRMarkdown(analysis, intent, sections)}`;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
// 5. Write to file or stdout
|
|
516
|
+
if (flags['write']) {
|
|
517
|
+
writeFileSync(flags['write'], output + '\n', 'utf-8');
|
|
518
|
+
console.log(`PR summary written to ${flags['write']}`);
|
|
519
|
+
}
|
|
520
|
+
else {
|
|
521
|
+
console.log(output);
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
//# sourceMappingURL=pr-summary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pr-summary.js","sourceRoot":"","sources":["../../src/commands/pr-summary.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `codeledger provenance [trace|export]`
|
|
3
|
+
*
|
|
4
|
+
* Context Provenance Graph (Enterprise) — full causal traceability.
|
|
5
|
+
* Subcommands:
|
|
6
|
+
* trace — Trace causal chain for a task: Task → Context → Files → Edits → Outcome
|
|
7
|
+
* export — Export full provenance graph as JSON
|
|
8
|
+
*/
|
|
9
|
+
export declare function runProvenance(cwd: string, flags: Record<string, string>): Promise<void>;
|
|
10
|
+
//# sourceMappingURL=provenance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provenance.d.ts","sourceRoot":"","sources":["../../src/commands/provenance.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,wBAAsB,aAAa,CACjC,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC5B,OAAO,CAAC,IAAI,CAAC,CAyEf"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `codeledger provenance [trace|export]`
|
|
3
|
+
*
|
|
4
|
+
* Context Provenance Graph (Enterprise) — full causal traceability.
|
|
5
|
+
* Subcommands:
|
|
6
|
+
* trace — Trace causal chain for a task: Task → Context → Files → Edits → Outcome
|
|
7
|
+
* export — Export full provenance graph as JSON
|
|
8
|
+
*/
|
|
9
|
+
import { existsSync } from 'node:fs';
|
|
10
|
+
import { join } from 'node:path';
|
|
11
|
+
import { traceTask, exportGraph } from '@codeledger/engine';
|
|
12
|
+
export async function runProvenance(cwd, flags) {
|
|
13
|
+
const sub = flags['_sub'] ?? 'trace';
|
|
14
|
+
const configPath = join(cwd, '.codeledger', 'config.json');
|
|
15
|
+
if (!existsSync(configPath)) {
|
|
16
|
+
console.error('No .codeledger/config.json found. Run "codeledger init" first.');
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
switch (sub) {
|
|
20
|
+
case 'trace': {
|
|
21
|
+
const taskId = flags['task'];
|
|
22
|
+
if (!taskId) {
|
|
23
|
+
console.error('--task is required. Usage: codeledger provenance trace --task "<task-id>"');
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
const trace = traceTask(cwd, taskId);
|
|
27
|
+
if (!trace) {
|
|
28
|
+
console.error(`No provenance found for task: ${taskId}`);
|
|
29
|
+
console.log('Hint: Provenance is recorded during activate/verify cycles.');
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
if (flags['json'] === 'true') {
|
|
33
|
+
console.log(JSON.stringify(trace, null, 2));
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
console.log('\n🔗 Provenance Trace\n');
|
|
37
|
+
console.log(` Task: ${trace.taskLabel}`);
|
|
38
|
+
console.log(` Outcome: ${trace.outcome}`);
|
|
39
|
+
console.log(` Chain (${trace.chain.length} nodes):\n`);
|
|
40
|
+
for (const node of trace.chain) {
|
|
41
|
+
const date = new Date(node.timestamp).toISOString().slice(0, 19);
|
|
42
|
+
const icon = kindIcon(node.kind);
|
|
43
|
+
console.log(` ${icon} [${node.kind}] ${node.label} (${date})`);
|
|
44
|
+
}
|
|
45
|
+
console.log();
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
case 'export': {
|
|
49
|
+
const graph = exportGraph(cwd);
|
|
50
|
+
if (graph.nodes.length === 0) {
|
|
51
|
+
console.log('Provenance graph is empty.');
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (flags['json'] === 'true') {
|
|
55
|
+
console.log(JSON.stringify(graph, null, 2));
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
console.log(`\n📊 Provenance Graph: ${graph.nodes.length} nodes, ${graph.edges.length} edges\n`);
|
|
59
|
+
const byKind = new Map();
|
|
60
|
+
for (const n of graph.nodes) {
|
|
61
|
+
byKind.set(n.kind, (byKind.get(n.kind) ?? 0) + 1);
|
|
62
|
+
}
|
|
63
|
+
for (const [kind, count] of byKind) {
|
|
64
|
+
console.log(` ${kindIcon(kind)} ${kind}: ${count}`);
|
|
65
|
+
}
|
|
66
|
+
console.log();
|
|
67
|
+
}
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
default:
|
|
71
|
+
console.error(`Unknown subcommand: ${sub}. Use: trace, export`);
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function kindIcon(kind) {
|
|
76
|
+
switch (kind) {
|
|
77
|
+
case 'task': return '🎯';
|
|
78
|
+
case 'intent': return '📝';
|
|
79
|
+
case 'bundle': return '📦';
|
|
80
|
+
case 'file': return '📄';
|
|
81
|
+
case 'edit': return '✏️';
|
|
82
|
+
case 'commit': return '💾';
|
|
83
|
+
case 'outcome': return '✅';
|
|
84
|
+
default: return '•';
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=provenance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provenance.js","sourceRoot":"","sources":["../../src/commands/provenance.ts"],"names":[],"mappings":"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"}
|