ci / build (push) Canceled after 0s
- shared/nextedit.ts: next-edit prompt format (region rewrite or NO_EDIT, Qwen spare special tokens) - shared/diagnostics.ts: TS errors near the cursor as context; symbols format 2 adds namespace imports - shared/prompt.ts: token healing (cut the half-typed word, force it via grammar), errors header section - daemon: model profiles carry contextFormat/errors/members/nextEdit; /v1/next-edit with edit-burst tracking; /v1/prewarm; /v1/debug/last; token healing on by default - extension: next-edit decorations (Tab apply / Esc dismiss), suggest on cursor move, prewarm on focus, Show Last Prompt, update check against releases, diagnostics in the edit recorder - models/README: training-data attribution; release script profiles for stage-d/stage-e - .gitea/workflows/ci.yml: build + test, publish release on vscode-v* tags (needs a runner + RELEASE_TOKEN) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J39imRDT8L7xYbWzsVWd8A
65 lines
2.6 KiB
TypeScript
65 lines
2.6 KiB
TypeScript
/**
|
|
* TypeScript errors near the cursor, as prompt context ("TS errors as context") and for verifying generated
|
|
* training data. Shared by the training pipeline and the daemon so the format is identical in both.
|
|
*
|
|
* Rendered as a pseudo-file in the repo header:
|
|
* <|file_sep|>{dir}/__errors__.txt
|
|
* TS2304 Cannot find name 'getU'. | const user = getU
|
|
*/
|
|
|
|
export interface Diagnostic {
|
|
/** 0-based line in the visible file. */
|
|
line: number
|
|
code: number
|
|
message: string
|
|
category: 'error' | 'warning'
|
|
}
|
|
|
|
/**
|
|
* Errors that are noise for completion: environment problems (unresolved modules or types when dependencies
|
|
* aren't installed) rather than mistakes in the code being written.
|
|
*/
|
|
export const IGNORED_CODES = new Set([
|
|
2307, // Cannot find module
|
|
7016, // Could not find a declaration file for module
|
|
2792, // Cannot find module. Did you mean to set moduleResolution…
|
|
7006, // Parameter implicitly has an 'any' type
|
|
7031, // Binding element implicitly has an 'any' type
|
|
2875, // JSX tag requires the module path … to exist
|
|
6133, // declared but never read (unused), noise while writing
|
|
6196, // declared but never used
|
|
])
|
|
|
|
export function relevantDiagnostics(diags: Diagnostic[], cursorLine: number, opts: { window?: number; max?: number } = {}): Diagnostic[] {
|
|
const window = opts.window ?? 20
|
|
const max = opts.max ?? 8
|
|
return diags
|
|
.filter(d => !IGNORED_CODES.has(d.code) && Math.abs(d.line - cursorLine) <= window)
|
|
.sort((a, b) => Math.abs(a.line - cursorLine) - Math.abs(b.line - cursorLine) || a.line - b.line)
|
|
.slice(0, max)
|
|
}
|
|
|
|
/** One line per diagnostic: code, message (first line), and the trimmed source line it points at. */
|
|
export function formatDiagnostics(diags: Diagnostic[], visible: string): string {
|
|
const lines = visible.split('\n')
|
|
return diags.map(d => {
|
|
const message = d.message.split('\n')[0].slice(0, 160)
|
|
const src = (lines[d.line] ?? '').trim().slice(0, 100)
|
|
return `TS${d.code} ${message} | ${src}`
|
|
}).join('\n')
|
|
}
|
|
|
|
/** Diagnostics present in `after` but not in `before`, matched by code + message (positions shift with edits). */
|
|
export function newDiagnostics(before: Diagnostic[], after: Diagnostic[]): Diagnostic[] {
|
|
const counts = new Map<string, number>()
|
|
for (const d of before) counts.set(`${d.code}:${d.message}`, (counts.get(`${d.code}:${d.message}`) ?? 0) + 1)
|
|
const out: Diagnostic[] = []
|
|
for (const d of after) {
|
|
const key = `${d.code}:${d.message}`
|
|
const n = counts.get(key) ?? 0
|
|
if (n > 0) counts.set(key, n - 1)
|
|
else if (!IGNORED_CODES.has(d.code)) out.push(d)
|
|
}
|
|
return out
|
|
}
|