@kernlang/codemod 3.3.4
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 +678 -0
- package/dist/adapter-registry.d.ts +12 -0
- package/dist/adapter-registry.js +21 -0
- package/dist/adapter-registry.js.map +1 -0
- package/dist/adapters/index.d.ts +2 -0
- package/dist/adapters/index.js +5 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/zustand-store.d.ts +14 -0
- package/dist/adapters/zustand-store.js +261 -0
- package/dist/adapters/zustand-store.js.map +1 -0
- package/dist/apply-files.d.ts +19 -0
- package/dist/apply-files.js +60 -0
- package/dist/apply-files.js.map +1 -0
- package/dist/apply.d.ts +37 -0
- package/dist/apply.js +275 -0
- package/dist/apply.js.map +1 -0
- package/dist/audit.d.ts +10 -0
- package/dist/audit.js +26 -0
- package/dist/audit.js.map +1 -0
- package/dist/diagnostics.d.ts +36 -0
- package/dist/diagnostics.js +117 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/format.d.ts +13 -0
- package/dist/format.js +30 -0
- package/dist/format.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/project.d.ts +16 -0
- package/dist/project.js +47 -0
- package/dist/project.js.map +1 -0
- package/dist/template-loader.d.ts +15 -0
- package/dist/template-loader.js +55 -0
- package/dist/template-loader.js.map +1 -0
- package/dist/types.d.ts +86 -0
- package/dist/types.js +11 -0
- package/dist/types.js.map +1 -0
- package/package.json +39 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template loader — lazy-registers built-in KERN templates from @kernlang/core's
|
|
3
|
+
* TEMPLATE_CATALOG so expandTemplateNode can find them.
|
|
4
|
+
*
|
|
5
|
+
* Uses defaultRuntime's template registry. Idempotent: calling ensureTemplate()
|
|
6
|
+
* for the same templateName twice only registers it once.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Ensure the named template is registered. Searches TEMPLATE_CATALOG, parses
|
|
10
|
+
* the first matching template source, and registers it with defaultRuntime.
|
|
11
|
+
*
|
|
12
|
+
* Returns true if the template is available (either newly registered or already
|
|
13
|
+
* was), false if it wasn't found in the catalog.
|
|
14
|
+
*/
|
|
15
|
+
export declare function ensureTemplate(templateName: string): boolean;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template loader — lazy-registers built-in KERN templates from @kernlang/core's
|
|
3
|
+
* TEMPLATE_CATALOG so expandTemplateNode can find them.
|
|
4
|
+
*
|
|
5
|
+
* Uses defaultRuntime's template registry. Idempotent: calling ensureTemplate()
|
|
6
|
+
* for the same templateName twice only registers it once.
|
|
7
|
+
*/
|
|
8
|
+
import { defaultRuntime, parse, registerTemplate, TEMPLATE_CATALOG } from '@kernlang/core';
|
|
9
|
+
const registered = new Set();
|
|
10
|
+
function findTemplateNode(source, templateName) {
|
|
11
|
+
let ast;
|
|
12
|
+
try {
|
|
13
|
+
ast = parse(source);
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
// A single catalog template failing to parse must not abort lookup for
|
|
17
|
+
// every other template.
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
if (ast.type === 'template' && ast.props?.name === templateName)
|
|
21
|
+
return ast;
|
|
22
|
+
for (const child of ast.children || []) {
|
|
23
|
+
if (child.type === 'template' && child.props?.name === templateName)
|
|
24
|
+
return child;
|
|
25
|
+
}
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Ensure the named template is registered. Searches TEMPLATE_CATALOG, parses
|
|
30
|
+
* the first matching template source, and registers it with defaultRuntime.
|
|
31
|
+
*
|
|
32
|
+
* Returns true if the template is available (either newly registered or already
|
|
33
|
+
* was), false if it wasn't found in the catalog.
|
|
34
|
+
*/
|
|
35
|
+
export function ensureTemplate(templateName) {
|
|
36
|
+
if (registered.has(templateName))
|
|
37
|
+
return true;
|
|
38
|
+
// If someone else already registered it, trust that.
|
|
39
|
+
if (defaultRuntime.templateRegistry.has(templateName)) {
|
|
40
|
+
registered.add(templateName);
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
for (const entry of TEMPLATE_CATALOG) {
|
|
44
|
+
for (const source of Object.values(entry.templates)) {
|
|
45
|
+
const node = findTemplateNode(source, templateName);
|
|
46
|
+
if (node) {
|
|
47
|
+
registerTemplate(node);
|
|
48
|
+
registered.add(templateName);
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=template-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-loader.js","sourceRoot":"","sources":["../src/template-loader.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,cAAc,EAAe,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAExG,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;AAErC,SAAS,gBAAgB,CAAC,MAAc,EAAE,YAAoB;IAC5D,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IACtB,CAAC;IAAC,MAAM,CAAC;QACP,uEAAuE;QACvE,wBAAwB;QACxB,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,GAAG,CAAC,IAAI,KAAK,UAAU,IAAI,GAAG,CAAC,KAAK,EAAE,IAAI,KAAK,YAAY;QAAE,OAAO,GAAG,CAAC;IAC5E,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC;QACvC,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,KAAK,CAAC,KAAK,EAAE,IAAI,KAAK,YAAY;YAAE,OAAO,KAAK,CAAC;IACpF,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,YAAoB;IACjD,IAAI,UAAU,CAAC,GAAG,CAAC,YAAY,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9C,qDAAqD;IACrD,IAAI,cAAc,CAAC,gBAAgB,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;QACtD,UAAU,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,gBAAgB,EAAE,CAAC;QACrC,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;YACpD,MAAM,IAAI,GAAG,gBAAgB,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;YACpD,IAAI,IAAI,EAAE,CAAC;gBACT,gBAAgB,CAAC,IAAI,CAAC,CAAC;gBACvB,UAAU,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;gBAC7B,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for @kernlang/codemod.
|
|
3
|
+
*
|
|
4
|
+
* TemplateMatch from @kernlang/review is treated as a candidate signal only.
|
|
5
|
+
* Each TemplateAdapter re-derives the exact AST span, extracts CHILDREN from
|
|
6
|
+
* the user's interior, and returns a RewritePlan. The orchestrator applies
|
|
7
|
+
* the plan, then gates the write behind reparse, re-detect, and a two-stage
|
|
8
|
+
* diagnostics check.
|
|
9
|
+
*/
|
|
10
|
+
import type { TemplateMatch } from '@kernlang/review';
|
|
11
|
+
import type { SourceFile } from 'ts-morph';
|
|
12
|
+
/** Exact replacement span in the source file, anchored by an adapter. */
|
|
13
|
+
export interface ResolvedRegion {
|
|
14
|
+
/** Character offset start (inclusive) */
|
|
15
|
+
start: number;
|
|
16
|
+
/** Character offset end (exclusive) */
|
|
17
|
+
end: number;
|
|
18
|
+
/** Human-readable description used in audit/logging (e.g. "VariableStatement at L12") */
|
|
19
|
+
label: string;
|
|
20
|
+
}
|
|
21
|
+
/** Result of extracting the user's interior into CHILDREN lines. */
|
|
22
|
+
export type ExtractResult = {
|
|
23
|
+
ok: true;
|
|
24
|
+
children: string[];
|
|
25
|
+
} | {
|
|
26
|
+
ok: false;
|
|
27
|
+
reason: string;
|
|
28
|
+
};
|
|
29
|
+
/** Result of resolving the replacement region. */
|
|
30
|
+
export type ResolveResult = {
|
|
31
|
+
ok: true;
|
|
32
|
+
region: ResolvedRegion;
|
|
33
|
+
} | {
|
|
34
|
+
ok: false;
|
|
35
|
+
reason: string;
|
|
36
|
+
};
|
|
37
|
+
/** A template adapter owns one templateName's rewrite semantics end-to-end. */
|
|
38
|
+
export interface TemplateAdapter {
|
|
39
|
+
/** Matches TemplateMatch.templateName (e.g. 'zustand-store') */
|
|
40
|
+
readonly templateName: string;
|
|
41
|
+
/** Re-derive the real rewrite span from the candidate match. */
|
|
42
|
+
resolveRegion(sourceFile: SourceFile, match: TemplateMatch): ResolveResult;
|
|
43
|
+
/** Extract the user interior as KERN child lines to be injected as {{CHILDREN}}. */
|
|
44
|
+
extractChildren(sourceFile: SourceFile, region: ResolvedRegion, match: TemplateMatch): ExtractResult;
|
|
45
|
+
}
|
|
46
|
+
export interface ApplyOptions {
|
|
47
|
+
/** Actually write to disk. Default false (dry-run). */
|
|
48
|
+
write?: boolean;
|
|
49
|
+
/** Minimum confidence percentage to consider (0-100). Default 80. */
|
|
50
|
+
minConfidence?: number;
|
|
51
|
+
/** Restrict to a single template name. */
|
|
52
|
+
templateName?: string;
|
|
53
|
+
/** Path to write audit JSONL. Default .kern/codemod-audit.jsonl under cwd. */
|
|
54
|
+
auditPath?: string;
|
|
55
|
+
/** Override cwd (affects tsconfig lookup + audit path). */
|
|
56
|
+
cwd?: string;
|
|
57
|
+
}
|
|
58
|
+
export type ApplyDecision = 'applied' | 'dry-run' | 'skipped' | 'rejected';
|
|
59
|
+
export interface ApplyResult {
|
|
60
|
+
filePath: string;
|
|
61
|
+
templateName: string;
|
|
62
|
+
confidencePct: number;
|
|
63
|
+
decision: ApplyDecision;
|
|
64
|
+
reason?: string;
|
|
65
|
+
/** Span that was replaced (character offsets). Present when adapter resolved. */
|
|
66
|
+
replacedSpan?: {
|
|
67
|
+
start: number;
|
|
68
|
+
end: number;
|
|
69
|
+
};
|
|
70
|
+
/** Unified diff between original and transformed text (present for applied/dry-run). */
|
|
71
|
+
diff?: string;
|
|
72
|
+
/** True when transformed text parsed cleanly. */
|
|
73
|
+
parseOk?: boolean;
|
|
74
|
+
/** True when post-transform re-detection no longer finds the original match. */
|
|
75
|
+
reDetectOk?: boolean;
|
|
76
|
+
/** New tsc diagnostics introduced by this edit (empty = safe). */
|
|
77
|
+
newDiagnostics?: string[];
|
|
78
|
+
tsTokens?: number;
|
|
79
|
+
kernTokens?: number;
|
|
80
|
+
/** ISO-8601 */
|
|
81
|
+
timestamp: string;
|
|
82
|
+
}
|
|
83
|
+
export type AuditEntry = ApplyResult & {
|
|
84
|
+
/** Schema version for forward compatibility */
|
|
85
|
+
schema: 1;
|
|
86
|
+
};
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for @kernlang/codemod.
|
|
3
|
+
*
|
|
4
|
+
* TemplateMatch from @kernlang/review is treated as a candidate signal only.
|
|
5
|
+
* Each TemplateAdapter re-derives the exact AST span, extracts CHILDREN from
|
|
6
|
+
* the user's interior, and returns a RewritePlan. The orchestrator applies
|
|
7
|
+
* the plan, then gates the write behind reparse, re-detect, and a two-stage
|
|
8
|
+
* diagnostics check.
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kernlang/codemod",
|
|
3
|
+
"version": "3.3.4",
|
|
4
|
+
"description": "Kern Codemod — apply kern-review TemplateMatch results to rewrite TS into KERN-template-backed TS",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"default": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"keywords": [
|
|
18
|
+
"kern",
|
|
19
|
+
"codemod",
|
|
20
|
+
"refactor",
|
|
21
|
+
"typescript",
|
|
22
|
+
"ai"
|
|
23
|
+
],
|
|
24
|
+
"license": "AGPL-3.0",
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "https://github.com/KERNlang/kern",
|
|
28
|
+
"directory": "packages/codemod"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"ts-morph": "^28.0.0",
|
|
32
|
+
"@kernlang/core": "3.3.4",
|
|
33
|
+
"@kernlang/review": "3.3.4"
|
|
34
|
+
},
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "tsc -b",
|
|
37
|
+
"test": "node --experimental-vm-modules ../../node_modules/jest/bin/jest.js --config jest.config.js"
|
|
38
|
+
}
|
|
39
|
+
}
|