ndrstnd 0.1.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/LICENSE +201 -0
- package/README.md +56 -0
- package/dist/server/agent.d.ts +51 -0
- package/dist/server/agent.js +77 -0
- package/dist/server/agent.js.map +1 -0
- package/dist/server/analysis-core.d.ts +93 -0
- package/dist/server/analysis-core.js +442 -0
- package/dist/server/analysis-core.js.map +1 -0
- package/dist/server/analyze.d.ts +55 -0
- package/dist/server/analyze.js +72 -0
- package/dist/server/analyze.js.map +1 -0
- package/dist/server/artifact.d.ts +8 -0
- package/dist/server/artifact.js +43 -0
- package/dist/server/artifact.js.map +1 -0
- package/dist/server/claude.d.ts +29 -0
- package/dist/server/claude.js +243 -0
- package/dist/server/claude.js.map +1 -0
- package/dist/server/cli-support.d.ts +7 -0
- package/dist/server/cli-support.js +13 -0
- package/dist/server/cli-support.js.map +1 -0
- package/dist/server/cli.d.ts +2 -0
- package/dist/server/cli.js +276 -0
- package/dist/server/cli.js.map +1 -0
- package/dist/server/codex.d.ts +34 -0
- package/dist/server/codex.js +256 -0
- package/dist/server/codex.js.map +1 -0
- package/dist/server/conversation.d.ts +9 -0
- package/dist/server/conversation.js +57 -0
- package/dist/server/conversation.js.map +1 -0
- package/dist/server/evidence-ordering.d.ts +13 -0
- package/dist/server/evidence-ordering.js +143 -0
- package/dist/server/evidence-ordering.js.map +1 -0
- package/dist/server/git-model.d.ts +15 -0
- package/dist/server/git-model.js +156 -0
- package/dist/server/git-model.js.map +1 -0
- package/dist/server/git.d.ts +29 -0
- package/dist/server/git.js +124 -0
- package/dist/server/git.js.map +1 -0
- package/dist/server/http.d.ts +14 -0
- package/dist/server/http.js +139 -0
- package/dist/server/http.js.map +1 -0
- package/dist/server/preview-fixture.d.ts +1 -0
- package/dist/server/preview-fixture.js +23 -0
- package/dist/server/preview-fixture.js.map +1 -0
- package/dist/server/review-presentation.d.ts +3 -0
- package/dist/server/review-presentation.js +14 -0
- package/dist/server/review-presentation.js.map +1 -0
- package/dist/server/skill.d.ts +14 -0
- package/dist/server/skill.js +94 -0
- package/dist/server/skill.js.map +1 -0
- package/dist/server/store.d.ts +36 -0
- package/dist/server/store.js +134 -0
- package/dist/server/store.js.map +1 -0
- package/dist/server/version.d.ts +2 -0
- package/dist/server/version.js +13 -0
- package/dist/server/version.js.map +1 -0
- package/dist/shared/analysis-schema.d.ts +325 -0
- package/dist/shared/analysis-schema.js +50 -0
- package/dist/shared/analysis-schema.js.map +1 -0
- package/dist/shared/domain.d.ts +33 -0
- package/dist/shared/domain.js +2 -0
- package/dist/shared/domain.js.map +1 -0
- package/dist/web/evidence-model.d.ts +36 -0
- package/dist/web/evidence-model.js +134 -0
- package/dist/web/evidence-model.js.map +1 -0
- package/dist/web/frozen-review-data.d.ts +3 -0
- package/dist/web/frozen-review-data.js +202 -0
- package/dist/web/frozen-review-data.js.map +1 -0
- package/dist/web/language.d.ts +4 -0
- package/dist/web/language.js +14 -0
- package/dist/web/language.js.map +1 -0
- package/dist/web/page.d.ts +10 -0
- package/dist/web/page.js +1038 -0
- package/dist/web/page.js.map +1 -0
- package/dist/web/review-data.d.ts +20 -0
- package/dist/web/review-data.js +2 -0
- package/dist/web/review-data.js.map +1 -0
- package/dist/web/test-plan-model.d.ts +27 -0
- package/dist/web/test-plan-model.js +89 -0
- package/dist/web/test-plan-model.js.map +1 -0
- package/package.json +47 -0
- package/src/skill-assets/ndrstnd/SKILL.md +22 -0
- package/src/skill-assets/ndrstnd/agents/openai.yaml +4 -0
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
import { AnalysisDocumentSchema } from "../shared/analysis-schema.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { deriveEvidenceOrder } from "./evidence-ordering.js";
|
|
4
|
+
export function parseAnalysisDocument(value, input, options) {
|
|
5
|
+
const document = parseWireAnalysisDocument(value);
|
|
6
|
+
const duplicateChapterIds = duplicated(document.chapters.map((chapter) => chapter.id));
|
|
7
|
+
if (duplicateChapterIds.length > 0)
|
|
8
|
+
throw new Error(`Analysis chapter ids are duplicated: ${duplicateChapterIds.join(", ")}. Give every chapter in c a unique id.`);
|
|
9
|
+
const duplicateStepIds = duplicated(document.steps.map((step) => step.id));
|
|
10
|
+
if (duplicateStepIds.length > 0)
|
|
11
|
+
throw new Error(`Analysis step ids are duplicated: ${duplicateStepIds.join(", ")}. Give every step in t a unique id.`);
|
|
12
|
+
const classified = [
|
|
13
|
+
...document.chapters.flatMap((chapter) => chapter.evidenceIds),
|
|
14
|
+
...document.omittedGroups.flatMap((group) => group.evidenceIds),
|
|
15
|
+
...document.unclassifiedEvidenceIds,
|
|
16
|
+
];
|
|
17
|
+
const duplicateEvidence = duplicated(classified);
|
|
18
|
+
if (duplicateEvidence.length > 0)
|
|
19
|
+
throw new Error(`Analysis evidence was classified more than once: ${duplicateEvidence.join(", ")}. Each evidence ID must appear exactly once across c, o, and u.`);
|
|
20
|
+
const knownEvidence = new Set(input.hunks.map((hunk) => hunk.id));
|
|
21
|
+
const referenced = new Set(classified);
|
|
22
|
+
for (const id of referenced)
|
|
23
|
+
if (!knownEvidence.has(id))
|
|
24
|
+
throw new Error(`Analysis referenced unknown evidence: ${id}. Use only hunk IDs listed in the review input manifest.`);
|
|
25
|
+
const meaningfulEvidence = input.hunks
|
|
26
|
+
.filter((hunk) => input.files.find((file) => file.id === hunk.fileId)?.signal === "meaningful")
|
|
27
|
+
.map((hunk) => hunk.id);
|
|
28
|
+
const missing = meaningfulEvidence.filter((id) => !referenced.has(id));
|
|
29
|
+
if (missing.length > 0)
|
|
30
|
+
throw new Error(`Analysis did not account for meaningful evidence: ${missing.join(", ")}. Add each missing ID to a chapter (c), an omitted group (o), or unclassified (u).`);
|
|
31
|
+
const grouped = new Set();
|
|
32
|
+
for (const chapter of document.chapters)
|
|
33
|
+
for (const id of chapter.evidenceIds)
|
|
34
|
+
grouped.add(id);
|
|
35
|
+
for (const group of document.omittedGroups)
|
|
36
|
+
for (const id of group.evidenceIds)
|
|
37
|
+
grouped.add(id);
|
|
38
|
+
const strayLowSignal = input.hunks
|
|
39
|
+
.filter((hunk) => input.files.find((file) => file.id === hunk.fileId)?.signal === "low-signal")
|
|
40
|
+
.map((hunk) => hunk.id)
|
|
41
|
+
.filter((id) => !grouped.has(id));
|
|
42
|
+
if (strayLowSignal.length > 0)
|
|
43
|
+
throw new Error(`Low-signal evidence was left ungrouped: ${strayLowSignal.join(", ")}. Add each ID to an omitted group in o with a short reason (for example lockfile churn or generated output); u is only for meaningful evidence that defies classification.`);
|
|
44
|
+
validateStepPlan(document, input, meaningfulEvidence);
|
|
45
|
+
validateFocus(document, input, options?.focus ?? "require");
|
|
46
|
+
validateProseDepth(document);
|
|
47
|
+
return document;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* "require" rejects missing or invalid focus so the repair loop demands it;
|
|
51
|
+
* "salvage" (the final attempt) keeps whatever focus is valid and lets the
|
|
52
|
+
* renderer fall back to heuristics, so a review never fails over focus alone.
|
|
53
|
+
*/
|
|
54
|
+
function validateFocus(document, input, mode) {
|
|
55
|
+
const hunksById = new Map(input.hunks.map((hunk) => [hunk.id, hunk]));
|
|
56
|
+
const focus = document.focus ?? {};
|
|
57
|
+
const valid = {};
|
|
58
|
+
for (const [evidenceId, ranges] of Object.entries(focus)) {
|
|
59
|
+
const hunk = hunksById.get(evidenceId);
|
|
60
|
+
if (hunk === undefined) {
|
|
61
|
+
if (mode === "require")
|
|
62
|
+
throw new Error(`Focus referenced unknown evidence: ${evidenceId}. Use only hunk IDs listed in the review input manifest.`);
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
const newLines = hunk.lines.flatMap((line) => (line.newLine === undefined ? [] : [line.newLine]));
|
|
66
|
+
const span = newLines.length === 0 ? "none" : `${Math.min(...newLines)}-${Math.max(...newLines)}`;
|
|
67
|
+
const validRanges = ranges.filter((range) => {
|
|
68
|
+
if (range.start > range.end) {
|
|
69
|
+
if (mode === "require")
|
|
70
|
+
throw new Error(`Focus range for ${evidenceId} is inverted: [${range.start},${range.end}]. Give [startLine,endLine] with startLine <= endLine.`);
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
if (!newLines.some((line) => line >= range.start && line <= range.end)) {
|
|
74
|
+
if (mode === "require")
|
|
75
|
+
throw new Error(`Focus range [${range.start},${range.end}] for ${evidenceId} selects no lines of that hunk; its new-file lines span ${span}. Use new-file line numbers from the patch.`);
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
return true;
|
|
79
|
+
});
|
|
80
|
+
if (validRanges.length > 0)
|
|
81
|
+
valid[evidenceId] = validRanges;
|
|
82
|
+
}
|
|
83
|
+
if (mode === "salvage") {
|
|
84
|
+
document.focus = valid;
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const missingFocus = document.chapters
|
|
88
|
+
.flatMap((chapter) => chapter.evidenceIds)
|
|
89
|
+
.filter((id) => focus[id] === undefined)
|
|
90
|
+
.filter((id) => (hunksById.get(id)?.lines ?? []).some((line) => line.newLine !== undefined));
|
|
91
|
+
if (missingFocus.length > 0)
|
|
92
|
+
throw new Error(`Focus is missing for chapter evidence: ${[...new Set(missingFocus)].join(", ")}. Add each ID to f with 1-3 [startLine,endLine] new-file line ranges covering the lines a reviewer must read first.`);
|
|
93
|
+
}
|
|
94
|
+
export const PROSE_WORD_RANGES = {
|
|
95
|
+
summary: { min: 35, max: 75 },
|
|
96
|
+
synopsis: { min: 20, max: 55 },
|
|
97
|
+
beforeAfter: { min: 8, max: 40 },
|
|
98
|
+
goal: { min: 12, max: 40 },
|
|
99
|
+
youNowHave: { min: 12, max: 40 },
|
|
100
|
+
};
|
|
101
|
+
function duplicated(values) {
|
|
102
|
+
const seen = new Set();
|
|
103
|
+
const dupes = new Set();
|
|
104
|
+
for (const value of values) {
|
|
105
|
+
if (seen.has(value))
|
|
106
|
+
dupes.add(value);
|
|
107
|
+
seen.add(value);
|
|
108
|
+
}
|
|
109
|
+
return [...dupes];
|
|
110
|
+
}
|
|
111
|
+
function wordCount(text) {
|
|
112
|
+
const trimmed = text.trim();
|
|
113
|
+
return trimmed === "" ? 0 : trimmed.split(/\s+/).length;
|
|
114
|
+
}
|
|
115
|
+
function proseIssue(label, text, range) {
|
|
116
|
+
const words = wordCount(text);
|
|
117
|
+
if (words < range.min)
|
|
118
|
+
return `${label} is ${words} words but must be ${range.min}-${range.max}: expand it with the concrete mechanisms, symbols, and consequences involved, not filler.`;
|
|
119
|
+
if (words > range.max)
|
|
120
|
+
return `${label} is ${words} words but must be ${range.min}-${range.max}: cut it down to the load-bearing facts.`;
|
|
121
|
+
return undefined;
|
|
122
|
+
}
|
|
123
|
+
function validateProseDepth(document) {
|
|
124
|
+
const issues = [proseIssue("The summary", document.summary, PROSE_WORD_RANGES.summary)];
|
|
125
|
+
for (const chapter of document.chapters) {
|
|
126
|
+
issues.push(proseIssue(`Chapter ${chapter.id} synopsis`, chapter.synopsis, PROSE_WORD_RANGES.synopsis));
|
|
127
|
+
if (chapter.before !== undefined)
|
|
128
|
+
issues.push(proseIssue(`Chapter ${chapter.id} before`, chapter.before, PROSE_WORD_RANGES.beforeAfter));
|
|
129
|
+
if (chapter.after !== undefined)
|
|
130
|
+
issues.push(proseIssue(`Chapter ${chapter.id} after`, chapter.after, PROSE_WORD_RANGES.beforeAfter));
|
|
131
|
+
}
|
|
132
|
+
for (const step of document.steps) {
|
|
133
|
+
issues.push(proseIssue(`Step ${step.id} goal`, step.goal, PROSE_WORD_RANGES.goal));
|
|
134
|
+
issues.push(proseIssue(`Step ${step.id} youNowHave`, step.youNowHave, PROSE_WORD_RANGES.youNowHave));
|
|
135
|
+
}
|
|
136
|
+
const found = issues.filter((issue) => issue !== undefined);
|
|
137
|
+
if (found.length > 0)
|
|
138
|
+
throw new Error(`Analysis prose depth is out of range; fix every field listed and keep all other fields unchanged. ${found.join(" ")}`);
|
|
139
|
+
}
|
|
140
|
+
function validateStepPlan(document, input, meaningfulEvidence) {
|
|
141
|
+
const knownChapters = new Set(document.chapters.map((chapter) => chapter.id));
|
|
142
|
+
const knownSteps = new Set(document.steps.map((step) => step.id));
|
|
143
|
+
for (const step of document.steps) {
|
|
144
|
+
for (const chapterId of step.advancesChapterIds) {
|
|
145
|
+
if (!knownChapters.has(chapterId))
|
|
146
|
+
throw new Error(`Analysis step ${step.id} advances unknown chapter: ${chapterId}. Every advancesChapterIds entry must match a chapter id declared in c.`);
|
|
147
|
+
}
|
|
148
|
+
for (const dependency of step.dependsOn) {
|
|
149
|
+
if (!knownSteps.has(dependency))
|
|
150
|
+
throw new Error(`Analysis step ${step.id} depends on unknown step: ${dependency}. dependsOn may only reference ids of other steps in t.`);
|
|
151
|
+
}
|
|
152
|
+
for (const targetStep of Object.values(step.forwardRefs)) {
|
|
153
|
+
if (!knownSteps.has(targetStep))
|
|
154
|
+
throw new Error(`Analysis step ${step.id} forward references unknown step: ${targetStep}. Each forwardRefs value must be the id of the step that introduces the symbol.`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
const stepEvidence = new Map();
|
|
158
|
+
for (const step of document.steps) {
|
|
159
|
+
for (const evidenceId of step.evidenceIds) {
|
|
160
|
+
if (stepEvidence.has(evidenceId))
|
|
161
|
+
throw new Error(`Analysis step evidence was duplicated: ${evidenceId}. Each evidence ID must appear in exactly one step; keep it in the step where the change is introduced.`);
|
|
162
|
+
stepEvidence.set(evidenceId, step.id);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
const missing = meaningfulEvidence.filter((id) => !stepEvidence.has(id));
|
|
166
|
+
if (missing.length > 0)
|
|
167
|
+
throw new Error(`Analysis steps did not account for meaningful evidence: ${missing.join(", ")}. Assign each missing ID to exactly one step in t.`);
|
|
168
|
+
const extra = [...stepEvidence.keys()].filter((id) => !meaningfulEvidence.includes(id));
|
|
169
|
+
if (extra.length > 0)
|
|
170
|
+
throw new Error(`Analysis steps referenced non-meaningful evidence: ${extra.join(", ")}. Steps may only contain meaningful evidence IDs; low-signal evidence belongs in omitted groups.`);
|
|
171
|
+
const stepIndex = new Map(document.steps.map((step, index) => [step.id, index]));
|
|
172
|
+
const stepByEvidence = new Map([...stepEvidence.entries()].map(([evidenceId, stepId]) => [evidenceId, document.steps.find((step) => step.id === stepId)]));
|
|
173
|
+
// Only define-before-use is a hard invariant; layer and test constraints stay
|
|
174
|
+
// suggestions because a good step plan may interleave tests with their subject.
|
|
175
|
+
for (const constraint of deriveEvidenceOrder(input.hunks, input.files).constraints) {
|
|
176
|
+
if (constraint.reason !== "symbol" || constraint.symbol === undefined)
|
|
177
|
+
continue;
|
|
178
|
+
const before = stepByEvidence.get(constraint.beforeEvidenceId);
|
|
179
|
+
const after = stepByEvidence.get(constraint.afterEvidenceId);
|
|
180
|
+
if (before === undefined || after === undefined || before.id === after.id)
|
|
181
|
+
continue;
|
|
182
|
+
if ((stepIndex.get(before.id) ?? 0) < (stepIndex.get(after.id) ?? 0))
|
|
183
|
+
continue;
|
|
184
|
+
if (after.forwardRefs[constraint.symbol] !== before.id) {
|
|
185
|
+
throw new Error(`Analysis step order violates symbol ${constraint.symbol}: ${before.id} must come before ${after.id}. Reorder the steps, or declare forwardRefs {"${constraint.symbol}":"${before.id}"} on ${after.id} if the forward use is intentional.`);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
export function analysisPrompt(input, conversation) {
|
|
190
|
+
const reviewInput = buildPromptReviewInput(input, conversation);
|
|
191
|
+
return `You are ndrstnd, a comprehension assistant. Explain a branch without critiquing it or proposing changes. Prioritize the implementation story and behavior changes. Return compact minified JSON only with this shape: {s,c:[[id,title,kind,synopsis,before|null,after|null,confidence,attention,riskCategories,evidenceIds]],t:[[id,title,goal,youNowHave,[[concern,resolvedByStepId|null]],dependsOn,forwardRefs,advancesChapterIds,evidenceIds]],o:[[title,reason,evidenceIds]],u:[evidenceId],f:{evidenceId:[[startLine,endLine]]},x:[[command,outcome,summary,source]]}. Allowed kind values are exactly feature, decision, behavior, non_functional, risk, test, other. Confidence is high, medium, or low. Attention is low, contained, elevated, high, or critical. Risk categories are formatting, refactor, behavior, performance, security. Use only listed evidence IDs. Every meaningful evidence ID must appear exactly once in c, o, or u, and exactly once in t. Group every low-signal evidence ID into an omitted group in o with a concise reason such as lockfile churn or generated output; u is a last resort for evidence that truly cannot be classified. f drives the Evidence zoom excerpts: for every evidence ID used in c, list 1-3 [startLine,endLine] ranges of new-file line numbers marking the exact lines a reviewer must read first - the load-bearing statements, not whole hunks, imports, or boilerplate. Each range must fall inside that hunk's new-file lines; inspect the patch to choose them precisely. x reports test or build runs that were actually observed: when the conversation or repository shows a command and its result, add [command,outcome,summary,source] with outcome passed, failed, mixed, or unknown and source conversation or repository. Omit x entirely when no run was observed - never invent execution evidence.
|
|
192
|
+
|
|
193
|
+
Prose depth is validated and out-of-range fields are rejected, so hit these word counts: summary ${PROSE_WORD_RANGES.summary.min}-${PROSE_WORD_RANGES.summary.max} words; each synopsis ${PROSE_WORD_RANGES.synopsis.min}-${PROSE_WORD_RANGES.synopsis.max} words across two or three sentences explaining what changed, how it works, and why it matters; before and after ${PROSE_WORD_RANGES.beforeAfter.min}-${PROSE_WORD_RANGES.beforeAfter.max} words each describing concrete observable behavior; each step goal ${PROSE_WORD_RANGES.goal.min}-${PROSE_WORD_RANGES.goal.max} words stating the intent and mechanism; each youNowHave ${PROSE_WORD_RANGES.youNowHave.min}-${PROSE_WORD_RANGES.youNowHave.max} words stating the capability that now exists. Titles stay under 10 words. Name the actual functions, types, and files involved. Never answer with a single vague sentence, and never pad - every sentence must add information a reviewer can act on.
|
|
194
|
+
|
|
195
|
+
Timeline steps are a rational reconstruction of how to build this branch. They are not commit chronology, file order, or the Story chapters repeated. Each step must be one capability increment; explain its intent in goal, its postcondition in youNowHave, intentionally postponed concerns in deferred, earlier step ids in dependsOn, unavoidable forward symbol uses in forwardRefs as {"Symbol":"later-step-id"}, the Story chapters it advances, and its evidence IDs. The manifest's construction.defineBeforeUse entries are hard ordering rules: each symbol must be defined in the same or an earlier step than its use, or the using step must declare it in forwardRefs. construction.suggestedEvidenceOrder is one valid linearization you may regroup into steps.
|
|
196
|
+
|
|
197
|
+
When the review input includes conversation, it is the dialogue between the user and the coding agent that produced this branch. Treat it as primary evidence of intent: explain why changes were made, which alternatives were considered or rejected, and which incidents, requirements, or downstream consumers motivated them, weaving those stated reasons into the summary, chapter synopses, before/after, step goals, and deferred concerns instead of guessing intent from the code alone. Attribute reasons faithfully - never invent motives the conversation does not support, and never copy credentials or secrets from it. When conversation is absent, ground every claim in the diff and repository alone.
|
|
198
|
+
|
|
199
|
+
You are running in the reviewed repository with a read-only sandbox. The review input below is a compact manifest. Hunks that carry a patch field include their complete diff text inline - never re-fetch those with git. For hunks without inline patch text, or when you need surrounding code, use the file paths, hunk IDs, line anchors, and suggested git commands to inspect only what you still need for a high-quality comprehension story. Prefer grouping related evidence IDs by behavior or decision instead of mirroring path order.
|
|
200
|
+
|
|
201
|
+
Review input:
|
|
202
|
+
${JSON.stringify(reviewInput)}`;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Inline patch text spares the analysis agent a git round trip per hunk, the dominant cost
|
|
206
|
+
* on small and medium branches, where every inspection command is a full model
|
|
207
|
+
* turn. The budget keeps huge branches on reference-first inspection so the
|
|
208
|
+
* prompt stays bounded.
|
|
209
|
+
*/
|
|
210
|
+
export const INLINE_PATCH_BUDGET = 40_000;
|
|
211
|
+
export function buildPromptReviewInput(input, conversation) {
|
|
212
|
+
const filesById = new Map(input.files.map((file) => [file.id, file]));
|
|
213
|
+
const hunksByFile = new Map();
|
|
214
|
+
let inlinePatchBudget = INLINE_PATCH_BUDGET;
|
|
215
|
+
for (const hunk of input.hunks) {
|
|
216
|
+
const file = filesById.get(hunk.fileId);
|
|
217
|
+
let patch;
|
|
218
|
+
if (file?.signal === "meaningful" && !file.binary && hunk.lines.length > 0) {
|
|
219
|
+
const text = hunkPatchText(hunk);
|
|
220
|
+
if (text.length <= inlinePatchBudget) {
|
|
221
|
+
inlinePatchBudget -= text.length;
|
|
222
|
+
patch = text;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
const compact = compactHunk(hunk, file?.path, patch);
|
|
226
|
+
const list = hunksByFile.get(hunk.fileId) ?? [];
|
|
227
|
+
list.push(compact);
|
|
228
|
+
hunksByFile.set(hunk.fileId, list);
|
|
229
|
+
}
|
|
230
|
+
const evidenceOrder = deriveEvidenceOrder(input.hunks, input.files);
|
|
231
|
+
return {
|
|
232
|
+
target: input.targetRef,
|
|
233
|
+
base: input.baseRef,
|
|
234
|
+
mergeBase: input.mergeBase,
|
|
235
|
+
inspection: {
|
|
236
|
+
workingDirectory: input.repoPath,
|
|
237
|
+
summaryCommand: `git diff --stat --find-renames --find-copies ${diffRange(input)}`,
|
|
238
|
+
patchCommand: `git diff --no-ext-diff --unified=80 --find-renames --find-copies ${diffRange(input)} -- <path>`,
|
|
239
|
+
currentFileCommand: "sed -n '<start>,<end>p' <path>",
|
|
240
|
+
note: "Hunks with a patch field carry their complete diff inline; run the patch command only for hunks without one or when surrounding code matters. For untracked working-tree files, inspect the current file directly and use the manifest hunk anchors as evidence IDs.",
|
|
241
|
+
},
|
|
242
|
+
files: input.files.map((file) => ({
|
|
243
|
+
id: file.id,
|
|
244
|
+
path: file.path,
|
|
245
|
+
previousPath: file.previousPath,
|
|
246
|
+
status: file.status,
|
|
247
|
+
binary: file.binary,
|
|
248
|
+
signal: file.signal,
|
|
249
|
+
signalReason: file.signalReason,
|
|
250
|
+
hunks: hunksByFile.get(file.id) ?? [],
|
|
251
|
+
})),
|
|
252
|
+
construction: {
|
|
253
|
+
suggestedEvidenceOrder: evidenceOrder.orderedEvidenceIds,
|
|
254
|
+
defineBeforeUse: evidenceOrder.constraints
|
|
255
|
+
.filter((constraint) => constraint.reason === "symbol")
|
|
256
|
+
.map((constraint) => ({ symbol: constraint.symbol, definedIn: constraint.beforeEvidenceId, usedIn: constraint.afterEvidenceId })),
|
|
257
|
+
},
|
|
258
|
+
conversation: compactConversation(conversation),
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
const KindSchema = z.enum(["feature", "decision", "behavior", "non_functional", "risk", "test", "other"]);
|
|
262
|
+
const ConfidenceSchema = z.enum(["high", "medium", "low"]);
|
|
263
|
+
const CompactRiskCategorySchema = z.enum(["formatting", "refactor", "behavior", "performance", "security"]);
|
|
264
|
+
const CompactChapterSchema = z.tuple([
|
|
265
|
+
z.string().min(1).max(80),
|
|
266
|
+
z.string().min(1).max(120),
|
|
267
|
+
KindSchema,
|
|
268
|
+
z.string().min(1).max(420),
|
|
269
|
+
z.string().max(300).nullable(),
|
|
270
|
+
z.string().max(300).nullable(),
|
|
271
|
+
ConfidenceSchema,
|
|
272
|
+
z.enum(["low", "contained", "elevated", "high", "critical"]),
|
|
273
|
+
z.array(CompactRiskCategorySchema),
|
|
274
|
+
z.array(z.string().min(1)).min(1),
|
|
275
|
+
]);
|
|
276
|
+
const CompactStepSchema = z.tuple([
|
|
277
|
+
z.string().min(1).max(80),
|
|
278
|
+
z.string().min(1).max(120),
|
|
279
|
+
z.string().min(1).max(320),
|
|
280
|
+
z.string().min(1).max(320),
|
|
281
|
+
z.array(z.tuple([z.string().min(1).max(220), z.string().min(1).max(80).nullable()])),
|
|
282
|
+
z.array(z.string().min(1).max(80)),
|
|
283
|
+
z.record(z.string().min(1), z.string().min(1).max(80)),
|
|
284
|
+
z.array(z.string().min(1).max(80)).min(1),
|
|
285
|
+
z.array(z.string().min(1)).min(1),
|
|
286
|
+
]);
|
|
287
|
+
const CompactAnalysisDocumentSchema = z.object({
|
|
288
|
+
s: z.string().min(1).max(560),
|
|
289
|
+
c: z.array(CompactChapterSchema),
|
|
290
|
+
t: z.array(CompactStepSchema),
|
|
291
|
+
o: z.array(z.tuple([z.string().min(1).max(120), z.string().min(1).max(220), z.array(z.string().min(1)).min(1)])),
|
|
292
|
+
u: z.array(z.string().min(1)),
|
|
293
|
+
f: z.record(z.string().min(1), z.array(z.tuple([z.number().int().min(1), z.number().int().min(1)])).min(1).max(5)).optional(),
|
|
294
|
+
x: z.array(z.tuple([z.string().min(1).max(200), z.enum(["passed", "failed", "mixed", "unknown"]), z.string().min(1).max(300), z.enum(["conversation", "repository"])])).max(5).optional(),
|
|
295
|
+
});
|
|
296
|
+
function parseWireAnalysisDocument(value) {
|
|
297
|
+
const full = AnalysisDocumentSchema.safeParse(value);
|
|
298
|
+
if (full.success)
|
|
299
|
+
return full.data;
|
|
300
|
+
const compactResult = CompactAnalysisDocumentSchema.safeParse(value);
|
|
301
|
+
if (!compactResult.success) {
|
|
302
|
+
// Repair turns quote this message; reporting the schema the document was aiming for keeps those turns productive.
|
|
303
|
+
const fullShaped = value !== null && typeof value === "object" && ("summary" in value || "chapters" in value);
|
|
304
|
+
const [shape, error] = fullShaped ? ["full", full.error] : ["compact", compactResult.error];
|
|
305
|
+
throw new Error(`Analysis document did not match the ${shape} shape: ${error.issues.slice(0, 8).map((issue) => `${issue.path.join(".") || "document"}: ${issue.message}`).join("; ")}`);
|
|
306
|
+
}
|
|
307
|
+
const compact = compactResult.data;
|
|
308
|
+
return AnalysisDocumentSchema.parse({
|
|
309
|
+
summary: compact.s,
|
|
310
|
+
chapters: compact.c.map((chapter) => ({
|
|
311
|
+
id: chapter[0],
|
|
312
|
+
title: chapter[1],
|
|
313
|
+
kind: chapter[2],
|
|
314
|
+
synopsis: chapter[3],
|
|
315
|
+
before: chapter[4] ?? undefined,
|
|
316
|
+
after: chapter[5] ?? undefined,
|
|
317
|
+
confidence: chapter[6],
|
|
318
|
+
attention: chapter[7],
|
|
319
|
+
riskCategories: chapter[8],
|
|
320
|
+
evidenceIds: chapter[9],
|
|
321
|
+
})),
|
|
322
|
+
steps: compact.t.map((step) => ({
|
|
323
|
+
id: step[0],
|
|
324
|
+
title: step[1],
|
|
325
|
+
goal: step[2],
|
|
326
|
+
youNowHave: step[3],
|
|
327
|
+
deferred: step[4].map((item) => ({ concern: item[0], resolvedByStepId: item[1] ?? undefined })),
|
|
328
|
+
dependsOn: step[5],
|
|
329
|
+
forwardRefs: step[6],
|
|
330
|
+
advancesChapterIds: step[7],
|
|
331
|
+
evidenceIds: step[8],
|
|
332
|
+
})),
|
|
333
|
+
omittedGroups: compact.o.map((group) => ({ title: group[0], reason: group[1], evidenceIds: group[2] })),
|
|
334
|
+
unclassifiedEvidenceIds: compact.u,
|
|
335
|
+
focus: compact.f === undefined ? undefined : Object.fromEntries(Object.entries(compact.f).map(([evidenceId, ranges]) => [evidenceId, ranges.map(([start, end]) => ({ start, end }))])),
|
|
336
|
+
testExecution: compact.x === undefined ? undefined : compact.x.map(([command, outcome, summary, source]) => ({ command, outcome, summary, source })),
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
function hunkPatchText(hunk) {
|
|
340
|
+
const markers = { context: " ", addition: "+", deletion: "-" };
|
|
341
|
+
const oldCount = hunk.lines.filter((line) => line.kind !== "addition").length;
|
|
342
|
+
const newCount = hunk.lines.filter((line) => line.kind !== "deletion").length;
|
|
343
|
+
return [`@@ -${hunk.oldStart},${oldCount} +${hunk.newStart},${newCount} @@`, ...hunk.lines.map((line) => `${markers[line.kind]}${line.content}`)].join("\n");
|
|
344
|
+
}
|
|
345
|
+
function compactHunk(hunk, path, patch) {
|
|
346
|
+
const additions = hunk.lines.filter((line) => line.kind === "addition");
|
|
347
|
+
const deletions = hunk.lines.filter((line) => line.kind === "deletion");
|
|
348
|
+
const context = hunk.lines.length - additions.length - deletions.length;
|
|
349
|
+
// Samples only anchor hunk IDs to recognizable content; the agent reads the inline
|
|
350
|
+
// patch or inspects the real one for detail, so two short previews per hunk are enough.
|
|
351
|
+
const sampleLines = deletions.length > 0 && additions.length > 0 ? [deletions[0], additions[0]] : [...deletions, ...additions].slice(0, 2);
|
|
352
|
+
const changedLineSamples = sampleLines.map((line) => ({
|
|
353
|
+
kind: line.kind,
|
|
354
|
+
oldLine: line.oldLine,
|
|
355
|
+
newLine: line.newLine,
|
|
356
|
+
preview: line.content.trim().slice(0, 100),
|
|
357
|
+
}));
|
|
358
|
+
return {
|
|
359
|
+
id: hunk.id,
|
|
360
|
+
fileId: hunk.fileId,
|
|
361
|
+
path,
|
|
362
|
+
oldStart: hunk.oldStart,
|
|
363
|
+
newStart: hunk.newStart,
|
|
364
|
+
lineCount: hunk.lines.length,
|
|
365
|
+
additions: additions.length,
|
|
366
|
+
deletions: deletions.length,
|
|
367
|
+
context,
|
|
368
|
+
patch,
|
|
369
|
+
changedLineSamples,
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
function compactConversation(conversation) {
|
|
373
|
+
if (conversation === undefined)
|
|
374
|
+
return undefined;
|
|
375
|
+
const messages = conversation.messages.slice(-16).map((message) => ({
|
|
376
|
+
role: message.role,
|
|
377
|
+
timestamp: message.timestamp,
|
|
378
|
+
excerpt: compactText(message.text, 1_500),
|
|
379
|
+
}));
|
|
380
|
+
return {
|
|
381
|
+
source: conversation.source,
|
|
382
|
+
messageCount: conversation.messages.length,
|
|
383
|
+
excerptedMessages: messages,
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
function compactText(text, limit) {
|
|
387
|
+
const normalized = text.replace(/\s+/g, " ").trim();
|
|
388
|
+
if (normalized.length <= limit)
|
|
389
|
+
return normalized;
|
|
390
|
+
const head = normalized.slice(0, Math.floor(limit * 0.7)).trimEnd();
|
|
391
|
+
const tail = normalized.slice(-Math.floor(limit * 0.25)).trimStart();
|
|
392
|
+
return `${head} ... ${tail}`;
|
|
393
|
+
}
|
|
394
|
+
function diffRange(input) {
|
|
395
|
+
if (input.includesWorkingTree)
|
|
396
|
+
return input.mergeBase;
|
|
397
|
+
return `${input.mergeBase} ${input.targetRef}`;
|
|
398
|
+
}
|
|
399
|
+
export function extractJson(text) {
|
|
400
|
+
// Agents sometimes narrate around the document, including other fenced snippets;
|
|
401
|
+
// take the first fence that holds an object, then fall back to the first balanced
|
|
402
|
+
// object in the raw text before giving up.
|
|
403
|
+
for (const match of text.matchAll(/```(?:json)?\s*([\s\S]*?)```/g)) {
|
|
404
|
+
const block = (match[1] ?? "").trim();
|
|
405
|
+
if (block.startsWith("{"))
|
|
406
|
+
return balancedJsonObject(block) ?? block;
|
|
407
|
+
}
|
|
408
|
+
const start = text.indexOf("{");
|
|
409
|
+
if (start === -1)
|
|
410
|
+
return text.trim();
|
|
411
|
+
const candidate = text.slice(start);
|
|
412
|
+
return balancedJsonObject(candidate) ?? candidate.trim();
|
|
413
|
+
}
|
|
414
|
+
/** Cuts the candidate at the brace closing its leading object, ignoring braces inside JSON strings, so trailing narration never corrupts the parse. */
|
|
415
|
+
function balancedJsonObject(candidate) {
|
|
416
|
+
let depth = 0;
|
|
417
|
+
let inString = false;
|
|
418
|
+
let escaped = false;
|
|
419
|
+
for (let index = 0; index < candidate.length; index += 1) {
|
|
420
|
+
const character = candidate[index];
|
|
421
|
+
if (inString) {
|
|
422
|
+
if (escaped)
|
|
423
|
+
escaped = false;
|
|
424
|
+
else if (character === "\\")
|
|
425
|
+
escaped = true;
|
|
426
|
+
else if (character === "\"")
|
|
427
|
+
inString = false;
|
|
428
|
+
continue;
|
|
429
|
+
}
|
|
430
|
+
if (character === "\"")
|
|
431
|
+
inString = true;
|
|
432
|
+
else if (character === "{")
|
|
433
|
+
depth += 1;
|
|
434
|
+
else if (character === "}") {
|
|
435
|
+
depth -= 1;
|
|
436
|
+
if (depth === 0)
|
|
437
|
+
return candidate.slice(0, index + 1);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
return undefined;
|
|
441
|
+
}
|
|
442
|
+
//# sourceMappingURL=analysis-core.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analysis-core.js","sourceRoot":"","sources":["../../src/server/analysis-core.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { CollectedReviewInput } from "./git.js";
|
|
2
|
+
import type { ConversationContext } from "./conversation.js";
|
|
3
|
+
import type { ReviewAgent, TurnActivity } from "./agent.js";
|
|
4
|
+
export { analysisPrompt, buildPromptReviewInput, parseAnalysisDocument } from "./analysis-core.js";
|
|
5
|
+
export interface AnalysisProgress {
|
|
6
|
+
onActivity?: (activity: TurnActivity) => void;
|
|
7
|
+
onRepair?: (attempt: number, attempts: number, problem: string) => void;
|
|
8
|
+
}
|
|
9
|
+
export declare function analyzeWithAgent(agent: ReviewAgent, input: CollectedReviewInput, conversation?: ConversationContext, progress?: AnalysisProgress): Promise<{
|
|
10
|
+
summary: string;
|
|
11
|
+
chapters: {
|
|
12
|
+
id: string;
|
|
13
|
+
title: string;
|
|
14
|
+
kind: "behavior" | "feature" | "decision" | "non_functional" | "risk" | "test" | "other";
|
|
15
|
+
synopsis: string;
|
|
16
|
+
confidence: "low" | "high" | "medium";
|
|
17
|
+
attention: "low" | "contained" | "elevated" | "high" | "critical";
|
|
18
|
+
riskCategories: ("formatting" | "refactor" | "behavior" | "performance" | "security")[];
|
|
19
|
+
evidenceIds: string[];
|
|
20
|
+
before?: string | undefined;
|
|
21
|
+
after?: string | undefined;
|
|
22
|
+
}[];
|
|
23
|
+
steps: {
|
|
24
|
+
id: string;
|
|
25
|
+
title: string;
|
|
26
|
+
evidenceIds: string[];
|
|
27
|
+
goal: string;
|
|
28
|
+
youNowHave: string;
|
|
29
|
+
deferred: {
|
|
30
|
+
concern: string;
|
|
31
|
+
resolvedByStepId?: string | undefined;
|
|
32
|
+
}[];
|
|
33
|
+
dependsOn: string[];
|
|
34
|
+
forwardRefs: Record<string, string>;
|
|
35
|
+
advancesChapterIds: string[];
|
|
36
|
+
}[];
|
|
37
|
+
omittedGroups: {
|
|
38
|
+
reason: string;
|
|
39
|
+
title: string;
|
|
40
|
+
evidenceIds: string[];
|
|
41
|
+
}[];
|
|
42
|
+
unclassifiedEvidenceIds: string[];
|
|
43
|
+
focus?: Record<string, {
|
|
44
|
+
end: number;
|
|
45
|
+
start: number;
|
|
46
|
+
}[]> | undefined;
|
|
47
|
+
testExecution?: {
|
|
48
|
+
command: string;
|
|
49
|
+
outcome: "unknown" | "passed" | "failed" | "mixed";
|
|
50
|
+
summary: string;
|
|
51
|
+
source: "conversation" | "repository";
|
|
52
|
+
}[] | undefined;
|
|
53
|
+
}>;
|
|
54
|
+
/** One reviewer-facing liveness line, printed on an interval so a long quiet analysis is never mistaken for a hang. */
|
|
55
|
+
export declare function formatAnalysisHeartbeat(agentName: string, elapsedMs: number, activity: TurnActivity | undefined, sinceActivityMs?: number): string;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { analysisPrompt, extractJson, parseAnalysisDocument } from "./analysis-core.js";
|
|
2
|
+
export { analysisPrompt, buildPromptReviewInput, parseAnalysisDocument } from "./analysis-core.js";
|
|
3
|
+
const REPAIR_ATTEMPTS = 2;
|
|
4
|
+
export async function analyzeWithAgent(agent, input, conversation, progress) {
|
|
5
|
+
const prompt = analysisPrompt(input, conversation);
|
|
6
|
+
return withFreshClientRetry(agent, async (client) => {
|
|
7
|
+
const thread = await client.startTextThread(input.repoPath);
|
|
8
|
+
try {
|
|
9
|
+
let response = await thread.send(prompt, progress?.onActivity);
|
|
10
|
+
let lastError = "";
|
|
11
|
+
for (let attempt = 0; attempt <= REPAIR_ATTEMPTS; attempt += 1) {
|
|
12
|
+
try {
|
|
13
|
+
return parseAnalysisDocument(JSON.parse(extractJson(response)), input, { focus: attempt === REPAIR_ATTEMPTS ? "salvage" : "require" });
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
lastError = error instanceof Error ? error.message : String(error);
|
|
17
|
+
if (attempt === REPAIR_ATTEMPTS)
|
|
18
|
+
break;
|
|
19
|
+
progress?.onRepair?.(attempt + 1, REPAIR_ATTEMPTS, lastError);
|
|
20
|
+
response = await thread.send(`Your prior response failed validation: ${lastError} Return only the corrected JSON document, with every other field kept as it was.`, progress?.onActivity);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
throw new Error(`${agent.name} produced an analysis that still failed validation after ${REPAIR_ATTEMPTS} repair turns: ${lastError}`);
|
|
24
|
+
}
|
|
25
|
+
finally {
|
|
26
|
+
await thread.close();
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
/** One reviewer-facing liveness line, printed on an interval so a long quiet analysis is never mistaken for a hang. */
|
|
31
|
+
export function formatAnalysisHeartbeat(agentName, elapsedMs, activity, sinceActivityMs) {
|
|
32
|
+
if (activity === undefined)
|
|
33
|
+
return `still analyzing (${formatDuration(elapsedMs)}): waiting for the first ${agentName} event`;
|
|
34
|
+
const draft = activity.draftCharacters > 0 ? `; ${formatCount(activity.draftCharacters)} draft characters` : "";
|
|
35
|
+
const stale = sinceActivityMs !== undefined && sinceActivityMs >= 60_000 ? `; no new ${agentName} events for ${formatDuration(sinceActivityMs)}` : "";
|
|
36
|
+
return `still analyzing (${formatDuration(elapsedMs)}): ${activity.label}${draft}${stale}`;
|
|
37
|
+
}
|
|
38
|
+
function formatDuration(milliseconds) {
|
|
39
|
+
const seconds = Math.max(0, Math.round(milliseconds / 1_000));
|
|
40
|
+
if (seconds < 60)
|
|
41
|
+
return `${seconds}s`;
|
|
42
|
+
return `${Math.floor(seconds / 60)}m${String(seconds % 60).padStart(2, "0")}s`;
|
|
43
|
+
}
|
|
44
|
+
function formatCount(count) {
|
|
45
|
+
return count < 1_000 ? String(count) : `${(count / 1_000).toFixed(1)}k`;
|
|
46
|
+
}
|
|
47
|
+
const TRANSIENT_AGENT_FAILURE = /stalled|timed out|exited with status|app-server closed|could not run|not running/i;
|
|
48
|
+
async function withFreshClientRetry(agent, run) {
|
|
49
|
+
const attempt = async () => {
|
|
50
|
+
const client = agent.createClient();
|
|
51
|
+
try {
|
|
52
|
+
return await run(client);
|
|
53
|
+
}
|
|
54
|
+
finally {
|
|
55
|
+
client.close();
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
try {
|
|
59
|
+
return await attempt();
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
if (!TRANSIENT_AGENT_FAILURE.test(error instanceof Error ? error.message : String(error)))
|
|
63
|
+
throw error;
|
|
64
|
+
try {
|
|
65
|
+
return await attempt();
|
|
66
|
+
}
|
|
67
|
+
catch (retryError) {
|
|
68
|
+
throw new Error(`${retryError instanceof Error ? retryError.message : String(retryError)} (already retried once with a fresh ${agent.name} client)`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=analyze.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyze.js","sourceRoot":"","sources":["../../src/server/analyze.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { AnalysisRevision, StoredReviewSession } from "./store.js";
|
|
2
|
+
export interface ArtifactOptions {
|
|
3
|
+
directory?: string;
|
|
4
|
+
now?: Date;
|
|
5
|
+
}
|
|
6
|
+
export declare function writeReviewArtifact(session: StoredReviewSession, revision: AnalysisRevision, options?: ArtifactOptions): Promise<string>;
|
|
7
|
+
export declare function cleanupArtifacts(directory?: string, now?: Date): Promise<void>;
|
|
8
|
+
export declare function defaultArtifactDirectory(): string;
|