@kernlang/cli 3.2.3 → 3.3.5
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/cli.js +28 -16
- package/dist/cli.js.map +1 -1
- package/dist/commands/apply.d.ts +14 -0
- package/dist/commands/apply.js +167 -0
- package/dist/commands/apply.js.map +1 -0
- package/dist/commands/compile.js +57 -9
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/gaps.d.ts +1 -0
- package/dist/commands/gaps.js +178 -0
- package/dist/commands/gaps.js.map +1 -0
- package/dist/commands/migrate-class-body.d.ts +50 -0
- package/dist/commands/migrate-class-body.js +453 -0
- package/dist/commands/migrate-class-body.js.map +1 -0
- package/dist/commands/migrate.d.ts +80 -0
- package/dist/commands/migrate.js +586 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/review.d.ts +9 -0
- package/dist/commands/review.js +294 -28
- package/dist/commands/review.js.map +1 -1
- package/dist/commands/transpile.js +9 -2
- package/dist/commands/transpile.js.map +1 -1
- package/dist/remote-repo.d.ts +21 -0
- package/dist/remote-repo.js +167 -0
- package/dist/remote-repo.js.map +1 -0
- package/dist/review-baseline.d.ts +27 -0
- package/dist/review-baseline.js +120 -0
- package/dist/review-baseline.js.map +1 -0
- package/dist/shared.d.ts +23 -2
- package/dist/shared.js +175 -8
- package/dist/shared.js.map +1 -1
- package/package.json +14 -13
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { readCoverageGaps } from '@kernlang/core';
|
|
2
|
+
import { existsSync, readdirSync, readFileSync, statSync } from 'fs';
|
|
3
|
+
import { extname, join, relative, resolve } from 'path';
|
|
4
|
+
import { withOptionalRemoteRepo } from '../remote-repo.js';
|
|
5
|
+
import { hasFlag, parseFlagOrNext } from '../shared.js';
|
|
6
|
+
/** Display order — most actionable first. Keeps the report scanable. */
|
|
7
|
+
const CATEGORY_ORDER = [
|
|
8
|
+
'migratable',
|
|
9
|
+
'blocked-by-parser',
|
|
10
|
+
'blocked-by-codegen',
|
|
11
|
+
'needs-new-node',
|
|
12
|
+
'detected',
|
|
13
|
+
];
|
|
14
|
+
const CATEGORY_HINTS = {
|
|
15
|
+
migratable: 'run `kern migrate <name>` to auto-rewrite',
|
|
16
|
+
'blocked-by-parser': 'parser cannot read this yet — file a parser issue',
|
|
17
|
+
'blocked-by-codegen': 'parses but no codegen path — file a codegen issue',
|
|
18
|
+
'needs-new-node': 'no IR node models this — proposal needed',
|
|
19
|
+
detected: 'feature observed; no migration or schema change available yet',
|
|
20
|
+
};
|
|
21
|
+
const SCAN_EXTENSIONS = new Set(['.kern', '.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs']);
|
|
22
|
+
const SKIP_DIRS = new Set([
|
|
23
|
+
'node_modules',
|
|
24
|
+
'dist',
|
|
25
|
+
'build',
|
|
26
|
+
'.git',
|
|
27
|
+
'.kern-gaps',
|
|
28
|
+
'coverage',
|
|
29
|
+
'.next',
|
|
30
|
+
'.turbo',
|
|
31
|
+
'.vercel',
|
|
32
|
+
'generated',
|
|
33
|
+
]);
|
|
34
|
+
const KERN_GAP_PATTERN = /\/\/\s*KERN-GAP:\s*(.+?)\s*$/;
|
|
35
|
+
function walkSources(root, files) {
|
|
36
|
+
let entries;
|
|
37
|
+
try {
|
|
38
|
+
entries = readdirSync(root);
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
for (const entry of entries) {
|
|
44
|
+
if (SKIP_DIRS.has(entry))
|
|
45
|
+
continue;
|
|
46
|
+
const full = join(root, entry);
|
|
47
|
+
let stat;
|
|
48
|
+
try {
|
|
49
|
+
stat = statSync(full);
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
if (stat.isDirectory()) {
|
|
55
|
+
walkSources(full, files);
|
|
56
|
+
}
|
|
57
|
+
else if (stat.isFile() && SCAN_EXTENSIONS.has(extname(entry))) {
|
|
58
|
+
files.push(full);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function scanFileForGaps(file) {
|
|
63
|
+
let content;
|
|
64
|
+
try {
|
|
65
|
+
content = readFileSync(file, 'utf-8');
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return [];
|
|
69
|
+
}
|
|
70
|
+
const out = [];
|
|
71
|
+
const lines = content.split('\n');
|
|
72
|
+
for (let i = 0; i < lines.length; i++) {
|
|
73
|
+
const match = lines[i].match(KERN_GAP_PATTERN);
|
|
74
|
+
if (match) {
|
|
75
|
+
out.push({ file, line: i + 1, message: match[1] });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return out;
|
|
79
|
+
}
|
|
80
|
+
function collectGapsReport(rootDir, gapDir) {
|
|
81
|
+
const files = [];
|
|
82
|
+
walkSources(rootDir, files);
|
|
83
|
+
const sourceGaps = [];
|
|
84
|
+
for (const file of files) {
|
|
85
|
+
sourceGaps.push(...scanFileForGaps(file));
|
|
86
|
+
}
|
|
87
|
+
const coverageGaps = existsSync(gapDir) ? readCoverageGaps(gapDir) : [];
|
|
88
|
+
return { scannedFiles: files.length, sourceGaps, coverageGaps };
|
|
89
|
+
}
|
|
90
|
+
function printHumanReport(report, rootDir, verbose) {
|
|
91
|
+
const total = report.sourceGaps.length + report.coverageGaps.length;
|
|
92
|
+
process.stdout.write(`kern gaps — scanned ${report.scannedFiles} files in ${relative(process.cwd(), rootDir) || '.'}\n`);
|
|
93
|
+
if (total === 0) {
|
|
94
|
+
process.stdout.write('No gaps found.\n');
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
if (report.sourceGaps.length > 0) {
|
|
98
|
+
process.stdout.write(`\nKERN-GAP comments (${report.sourceGaps.length}):\n`);
|
|
99
|
+
const grouped = new Map();
|
|
100
|
+
for (const gap of report.sourceGaps) {
|
|
101
|
+
const rel = relative(rootDir, gap.file) || gap.file;
|
|
102
|
+
if (!grouped.has(rel))
|
|
103
|
+
grouped.set(rel, []);
|
|
104
|
+
grouped.get(rel)?.push(gap);
|
|
105
|
+
}
|
|
106
|
+
const sorted = [...grouped.entries()].sort(([a], [b]) => a.localeCompare(b));
|
|
107
|
+
for (const [file, gaps] of sorted) {
|
|
108
|
+
process.stdout.write(` ${file}\n`);
|
|
109
|
+
for (const gap of gaps) {
|
|
110
|
+
process.stdout.write(` ${gap.line}: ${gap.message}\n`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (report.coverageGaps.length > 0) {
|
|
115
|
+
process.stdout.write(`\nCompiler coverage gaps (${report.coverageGaps.length}):\n`);
|
|
116
|
+
// Group by category; missing category (older .kern-gaps JSONs) counts as `detected`.
|
|
117
|
+
const byCategory = new Map();
|
|
118
|
+
for (const gap of report.coverageGaps) {
|
|
119
|
+
const category = gap.category ?? 'detected';
|
|
120
|
+
if (!byCategory.has(category))
|
|
121
|
+
byCategory.set(category, []);
|
|
122
|
+
byCategory.get(category).push(gap);
|
|
123
|
+
}
|
|
124
|
+
for (const category of CATEGORY_ORDER) {
|
|
125
|
+
const gaps = byCategory.get(category);
|
|
126
|
+
if (!gaps || gaps.length === 0)
|
|
127
|
+
continue;
|
|
128
|
+
const migrationNames = new Set();
|
|
129
|
+
for (const g of gaps)
|
|
130
|
+
if (g.migration)
|
|
131
|
+
migrationNames.add(g.migration);
|
|
132
|
+
const hint = CATEGORY_HINTS[category];
|
|
133
|
+
const migrationSuffix = category === 'migratable' && migrationNames.size > 0
|
|
134
|
+
? ` — ${[...migrationNames]
|
|
135
|
+
.sort()
|
|
136
|
+
.map((m) => `kern migrate ${m}`)
|
|
137
|
+
.join(', ')}`
|
|
138
|
+
: '';
|
|
139
|
+
process.stdout.write(` ${category} (${gaps.length}): ${hint}${migrationSuffix}\n`);
|
|
140
|
+
}
|
|
141
|
+
if (!verbose) {
|
|
142
|
+
process.stdout.write('\n (run with --verbose for per-file detail)\n');
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
process.stdout.write('\n Detail:\n');
|
|
146
|
+
for (const category of CATEGORY_ORDER) {
|
|
147
|
+
const gaps = byCategory.get(category);
|
|
148
|
+
if (!gaps || gaps.length === 0)
|
|
149
|
+
continue;
|
|
150
|
+
for (const gap of gaps) {
|
|
151
|
+
const rel = relative(rootDir, gap.file) || gap.file;
|
|
152
|
+
const migration = gap.migration ? ` migration=${gap.migration}` : '';
|
|
153
|
+
const parent = gap.parentType ? ` parent=${gap.parentType}` : '';
|
|
154
|
+
process.stdout.write(` [${category}] ${rel}:${gap.line} handler ${gap.handlerLength}ch${parent}${migration} @ ${gap.timestamp}\n`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
process.stdout.write(`\nTotal: ${total} gaps across ${report.scannedFiles} scanned files.\n`);
|
|
160
|
+
}
|
|
161
|
+
async function runGapsLocal(args, remoteContext) {
|
|
162
|
+
const rootDir = resolve(parseFlagOrNext(args, '--root') ?? remoteContext?.rootDir ?? process.cwd());
|
|
163
|
+
const gapDir = resolve(parseFlagOrNext(args, '--gap-dir') ?? join(rootDir, '.kern-gaps'));
|
|
164
|
+
const json = hasFlag(args, '--json');
|
|
165
|
+
const verbose = hasFlag(args, '--verbose', '-v');
|
|
166
|
+
const report = collectGapsReport(rootDir, gapDir);
|
|
167
|
+
if (json) {
|
|
168
|
+
process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
printHumanReport(report, rootDir, verbose);
|
|
172
|
+
}
|
|
173
|
+
export async function runGaps(args) {
|
|
174
|
+
await withOptionalRemoteRepo(args, { commandName: 'gaps' }, async (remoteContext) => {
|
|
175
|
+
await runGapsLocal(args, remoteContext);
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=gaps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gaps.js","sourceRoot":"","sources":["../../src/commands/gaps.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `kern migrate class-body` — convert handler-escaped class expressions to
|
|
3
|
+
* first-class `class` nodes.
|
|
4
|
+
*
|
|
5
|
+
* Detects this shape:
|
|
6
|
+
*
|
|
7
|
+
* const name=AudioRecorder type=(any|object|unknown) [export=true]
|
|
8
|
+
* handler <<<
|
|
9
|
+
* class AudioRecorder [extends X] [implements Y] {
|
|
10
|
+
* private fd: T = init;
|
|
11
|
+
* ...
|
|
12
|
+
* constructor(...) { ... }
|
|
13
|
+
* foo(...) { ... }
|
|
14
|
+
* }
|
|
15
|
+
* >>>
|
|
16
|
+
*
|
|
17
|
+
* and rewrites it to a proper:
|
|
18
|
+
*
|
|
19
|
+
* class name=AudioRecorder [export=true] [extends=X] [implements=Y]
|
|
20
|
+
* field name=fd type=T private=true default={{ init }}
|
|
21
|
+
* constructor params="..."
|
|
22
|
+
* handler <<< ... >>>
|
|
23
|
+
* method name=foo params="..." returns=T
|
|
24
|
+
* handler <<< ... >>>
|
|
25
|
+
*
|
|
26
|
+
* This is NOT byte-equivalent: the original emits
|
|
27
|
+
* `export const X: any = class X { ... };` (class expression bound to const)
|
|
28
|
+
* whereas the rewrite emits
|
|
29
|
+
* `export class X { ... }` (class declaration)
|
|
30
|
+
*
|
|
31
|
+
* The two are behaviourally compatible at the call sites we care about
|
|
32
|
+
* (constructor, methods, imports) but differ in hoisting and in the
|
|
33
|
+
* value of `typeof X`. We only migrate when the original annotation was the
|
|
34
|
+
* throwaway `any`/`object`/`unknown` — i.e. no existing code relied on the
|
|
35
|
+
* type of the const, because the const had no useful type to begin with.
|
|
36
|
+
*/
|
|
37
|
+
export interface ClassBodyHit {
|
|
38
|
+
headerLine: number;
|
|
39
|
+
literal: string;
|
|
40
|
+
valueAttr: string;
|
|
41
|
+
}
|
|
42
|
+
export interface ClassBodyResult {
|
|
43
|
+
hits: ClassBodyHit[];
|
|
44
|
+
output: string;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Main entry: walk .kern source text, rewrite every
|
|
48
|
+
* `const ... handler <<< class X {...} >>>` block to a `class` node.
|
|
49
|
+
*/
|
|
50
|
+
export declare function rewriteClassBodies(source: string): ClassBodyResult;
|