@codyswann/lisa 1.83.0 → 1.84.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/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/configs/vitest/base.d.ts +6 -0
- package/dist/configs/vitest/base.d.ts.map +1 -1
- package/dist/configs/vitest/base.js +11 -0
- package/dist/configs/vitest/base.js.map +1 -1
- package/dist/configs/vitest/cdk.d.ts +2 -2
- package/dist/configs/vitest/cdk.d.ts.map +1 -1
- package/dist/configs/vitest/cdk.js +3 -2
- package/dist/configs/vitest/cdk.js.map +1 -1
- package/dist/configs/vitest/nestjs.d.ts +2 -2
- package/dist/configs/vitest/nestjs.d.ts.map +1 -1
- package/dist/configs/vitest/nestjs.js +3 -2
- package/dist/configs/vitest/nestjs.js.map +1 -1
- package/dist/configs/vitest/typescript.d.ts +2 -2
- package/dist/configs/vitest/typescript.d.ts.map +1 -1
- package/dist/configs/vitest/typescript.js +3 -3
- package/dist/configs/vitest/typescript.js.map +1 -1
- package/dist/core/config.d.ts +2 -0
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +2 -0
- package/dist/core/config.js.map +1 -1
- package/dist/core/lisa.d.ts +28 -0
- package/dist/core/lisa.d.ts.map +1 -1
- package/dist/core/lisa.js +99 -28
- package/dist/core/lisa.js.map +1 -1
- package/dist/migrations/ensure-lisa-postinstall.d.ts +28 -0
- package/dist/migrations/ensure-lisa-postinstall.d.ts.map +1 -0
- package/dist/migrations/ensure-lisa-postinstall.js +115 -0
- package/dist/migrations/ensure-lisa-postinstall.js.map +1 -0
- package/dist/migrations/ensure-tsconfig-local-includes.d.ts +56 -0
- package/dist/migrations/ensure-tsconfig-local-includes.d.ts.map +1 -0
- package/dist/migrations/ensure-tsconfig-local-includes.js +178 -0
- package/dist/migrations/ensure-tsconfig-local-includes.js.map +1 -0
- package/dist/migrations/index.d.ts +38 -0
- package/dist/migrations/index.d.ts.map +1 -0
- package/dist/migrations/index.js +65 -0
- package/dist/migrations/index.js.map +1 -0
- package/dist/migrations/migration.interface.d.ts +56 -0
- package/dist/migrations/migration.interface.d.ts.map +1 -0
- package/dist/migrations/migration.interface.js +2 -0
- package/dist/migrations/migration.interface.js.map +1 -0
- package/package.json +1 -1
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/typescript/copy-overwrite/audit.ignore.config.json +22 -47
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Migration, MigrationContext, MigrationResult } from "./migration.interface.js";
|
|
2
|
+
/**
|
|
3
|
+
* Migration: ensure Node-based projects chain Lisa into their postinstall script.
|
|
4
|
+
*
|
|
5
|
+
* Any TypeScript/Node project (expo, nestjs, cdk, npm-package, plain typescript) with a
|
|
6
|
+
* custom postinstall (`patch-package && ...`) that never invokes Lisa will not apply
|
|
7
|
+
* template updates automatically on `bun install` / `npm install`. Evidence: frontend-v2
|
|
8
|
+
* (expo) and propswap/frontend (typescript-only) both needed this chained invocation.
|
|
9
|
+
* This migration prepends the standard Lisa invocation so template updates apply
|
|
10
|
+
* automatically on install. Rails-only projects are skipped (no Node postinstall).
|
|
11
|
+
*/
|
|
12
|
+
export declare class EnsureLisaPostinstallMigration implements Migration {
|
|
13
|
+
readonly name = "ensure-lisa-postinstall";
|
|
14
|
+
readonly description = "Ensure Node-based projects run Lisa in their postinstall script";
|
|
15
|
+
/**
|
|
16
|
+
* Check whether this migration should run on the project
|
|
17
|
+
* @param ctx - Migration context
|
|
18
|
+
* @returns True when a Node project is missing the Lisa invocation in postinstall
|
|
19
|
+
*/
|
|
20
|
+
applies(ctx: MigrationContext): Promise<boolean>;
|
|
21
|
+
/**
|
|
22
|
+
* Apply the migration, prepending the Lisa invocation to the project's postinstall
|
|
23
|
+
* @param ctx - Migration context
|
|
24
|
+
* @returns Result describing the action taken
|
|
25
|
+
*/
|
|
26
|
+
apply(ctx: MigrationContext): Promise<MigrationResult>;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=ensure-lisa-postinstall.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ensure-lisa-postinstall.d.ts","sourceRoot":"","sources":["../../src/migrations/ensure-lisa-postinstall.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,SAAS,EACT,gBAAgB,EAChB,eAAe,EAChB,MAAM,0BAA0B,CAAC;AA6DlC;;;;;;;;;GASG;AACH,qBAAa,8BAA+B,YAAW,SAAS;IAC9D,QAAQ,CAAC,IAAI,6BAA6B;IAC1C,QAAQ,CAAC,WAAW,qEACgD;IAEpE;;;;OAIG;IACG,OAAO,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;IAetD;;;;OAIG;IACG,KAAK,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;CAqC7D"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import * as path from "node:path";
|
|
2
|
+
import { readJsonOrNull, writeJson } from "../utils/json-utils.js";
|
|
3
|
+
const PACKAGE_JSON = "package.json";
|
|
4
|
+
const LISA_INVOCATION = "node node_modules/@codyswann/lisa/dist/index.js --yes --skip-git-check . 2>/dev/null || true";
|
|
5
|
+
const LISA_MARKER = "node_modules/@codyswann/lisa/dist/index.js";
|
|
6
|
+
/**
|
|
7
|
+
* Project types that do not use Node.js postinstall hooks (e.g. Rails).
|
|
8
|
+
* Projects detected as only these types are skipped by this migration.
|
|
9
|
+
*/
|
|
10
|
+
const NON_NODE_TYPES = ["rails"];
|
|
11
|
+
/**
|
|
12
|
+
* Read package.json, returning null if missing
|
|
13
|
+
* @param projectDir - Project directory containing package.json
|
|
14
|
+
* @returns Parsed package.json or null when absent/invalid
|
|
15
|
+
*/
|
|
16
|
+
async function readPackageJson(projectDir) {
|
|
17
|
+
return readJsonOrNull(path.join(projectDir, PACKAGE_JSON));
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Compose the new postinstall, prepending the Lisa invocation to any existing command
|
|
21
|
+
* @param existing - Existing postinstall script (may be undefined)
|
|
22
|
+
* @returns The composed postinstall script
|
|
23
|
+
*/
|
|
24
|
+
function composePostinstall(existing) {
|
|
25
|
+
const trimmed = existing?.trim();
|
|
26
|
+
if (!trimmed) {
|
|
27
|
+
return LISA_INVOCATION;
|
|
28
|
+
}
|
|
29
|
+
return `${LISA_INVOCATION} && ${trimmed}`;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Determine whether the detected types indicate a Node.js project that should
|
|
33
|
+
* run Lisa via postinstall. Rails-only projects are excluded; any Node stack
|
|
34
|
+
* (typescript, expo, nestjs, cdk, npm-package) qualifies.
|
|
35
|
+
* @param detectedTypes - Detected project types for the destination
|
|
36
|
+
* @returns True when at least one detected type uses Node postinstall hooks
|
|
37
|
+
*/
|
|
38
|
+
function hasNodePostinstallType(detectedTypes) {
|
|
39
|
+
if (detectedTypes.length === 0) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
return detectedTypes.some(type => !NON_NODE_TYPES.includes(type));
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Migration: ensure Node-based projects chain Lisa into their postinstall script.
|
|
46
|
+
*
|
|
47
|
+
* Any TypeScript/Node project (expo, nestjs, cdk, npm-package, plain typescript) with a
|
|
48
|
+
* custom postinstall (`patch-package && ...`) that never invokes Lisa will not apply
|
|
49
|
+
* template updates automatically on `bun install` / `npm install`. Evidence: frontend-v2
|
|
50
|
+
* (expo) and propswap/frontend (typescript-only) both needed this chained invocation.
|
|
51
|
+
* This migration prepends the standard Lisa invocation so template updates apply
|
|
52
|
+
* automatically on install. Rails-only projects are skipped (no Node postinstall).
|
|
53
|
+
*/
|
|
54
|
+
export class EnsureLisaPostinstallMigration {
|
|
55
|
+
name = "ensure-lisa-postinstall";
|
|
56
|
+
description = "Ensure Node-based projects run Lisa in their postinstall script";
|
|
57
|
+
/**
|
|
58
|
+
* Check whether this migration should run on the project
|
|
59
|
+
* @param ctx - Migration context
|
|
60
|
+
* @returns True when a Node project is missing the Lisa invocation in postinstall
|
|
61
|
+
*/
|
|
62
|
+
async applies(ctx) {
|
|
63
|
+
if (!hasNodePostinstallType(ctx.detectedTypes)) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
const pkg = await readPackageJson(ctx.projectDir);
|
|
67
|
+
if (!pkg) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
const postinstall = pkg.scripts?.postinstall;
|
|
71
|
+
if (postinstall && postinstall.includes(LISA_MARKER)) {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Apply the migration, prepending the Lisa invocation to the project's postinstall
|
|
78
|
+
* @param ctx - Migration context
|
|
79
|
+
* @returns Result describing the action taken
|
|
80
|
+
*/
|
|
81
|
+
async apply(ctx) {
|
|
82
|
+
const pkgPath = path.join(ctx.projectDir, PACKAGE_JSON);
|
|
83
|
+
const pkg = await readPackageJson(ctx.projectDir);
|
|
84
|
+
if (!pkg) {
|
|
85
|
+
return { name: this.name, action: "noop" };
|
|
86
|
+
}
|
|
87
|
+
const currentScripts = pkg.scripts ?? {};
|
|
88
|
+
const newPostinstall = composePostinstall(currentScripts.postinstall);
|
|
89
|
+
const nextPkg = {
|
|
90
|
+
...pkg,
|
|
91
|
+
scripts: { ...currentScripts, postinstall: newPostinstall },
|
|
92
|
+
};
|
|
93
|
+
const message = currentScripts.postinstall
|
|
94
|
+
? `Chained Lisa into existing postinstall: ${newPostinstall}`
|
|
95
|
+
: `Set postinstall to Lisa invocation: ${newPostinstall}`;
|
|
96
|
+
if (ctx.dryRun) {
|
|
97
|
+
ctx.logger.dry(`Would update package.json scripts.postinstall`);
|
|
98
|
+
return {
|
|
99
|
+
name: this.name,
|
|
100
|
+
action: "applied",
|
|
101
|
+
changedFiles: [PACKAGE_JSON],
|
|
102
|
+
message,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
await writeJson(pkgPath, nextPkg);
|
|
106
|
+
ctx.logger.success(message);
|
|
107
|
+
return {
|
|
108
|
+
name: this.name,
|
|
109
|
+
action: "applied",
|
|
110
|
+
changedFiles: [PACKAGE_JSON],
|
|
111
|
+
message,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=ensure-lisa-postinstall.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ensure-lisa-postinstall.js","sourceRoot":"","sources":["../../src/migrations/ensure-lisa-postinstall.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { Migration, MigrationContext, MigrationResult } from "./migration.interface.js";
|
|
2
|
+
/**
|
|
3
|
+
* Migration: backfill missing include/exclude in existing tsconfig.local.json files.
|
|
4
|
+
*
|
|
5
|
+
* Before PR #373, include/exclude lived in tsconfig.json. After they moved to
|
|
6
|
+
* tsconfig.local.json (create-only), existing projects kept their include-less local
|
|
7
|
+
* tsconfig and typecheck began compiling tests, worktrees, etc. This migration injects
|
|
8
|
+
* the canonical defaults for any key that is missing without touching existing values.
|
|
9
|
+
*
|
|
10
|
+
* Additionally, this migration preserves a project's narrower include/exclude from
|
|
11
|
+
* the pre-strategy tsconfig.json when the stack template's include/exclude would
|
|
12
|
+
* widen tsc scope. Evidence: thumbwar-backend's tsconfig.json pinned `include: ["src/**\/*"]`
|
|
13
|
+
* but after Lisa overwrote tsconfig.json the stack template's include was used,
|
|
14
|
+
* pulling `vitest.*.ts` into typecheck scope.
|
|
15
|
+
*/
|
|
16
|
+
export declare class EnsureTsconfigLocalIncludesMigration implements Migration {
|
|
17
|
+
readonly name = "ensure-tsconfig-local-includes";
|
|
18
|
+
readonly description = "Backfill include/exclude in tsconfig.local.json for projects upgraded past PR #373";
|
|
19
|
+
private snapshotInclude;
|
|
20
|
+
private snapshotExclude;
|
|
21
|
+
/**
|
|
22
|
+
* Snapshot the project's pre-strategy tsconfig.json include/exclude so we can
|
|
23
|
+
* preserve narrower scopes when the copy-overwrite strategy replaces tsconfig.json.
|
|
24
|
+
* @param ctx - Migration context
|
|
25
|
+
*/
|
|
26
|
+
beforeStrategies(ctx: MigrationContext): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Check whether this migration should run on the project
|
|
29
|
+
* @param ctx - Migration context
|
|
30
|
+
* @returns True when tsconfig.local.json exists but is missing include or exclude
|
|
31
|
+
*/
|
|
32
|
+
applies(ctx: MigrationContext): Promise<boolean>;
|
|
33
|
+
/**
|
|
34
|
+
* Apply the migration, injecting any missing include/exclude keys
|
|
35
|
+
* @param ctx - Migration context
|
|
36
|
+
* @returns Result describing the action taken
|
|
37
|
+
*/
|
|
38
|
+
apply(ctx: MigrationContext): Promise<MigrationResult>;
|
|
39
|
+
/**
|
|
40
|
+
* Prefer the project's pre-strategy tsconfig.json include when it is narrower
|
|
41
|
+
* than the stack template's include. "Narrower" means the snapshot is a strict
|
|
42
|
+
* subset of the template or differs in content at all — we preserve project intent.
|
|
43
|
+
* Falls back to the stack template include when no snapshot exists.
|
|
44
|
+
* @param templateInclude - Stack template include to fall back to
|
|
45
|
+
* @returns The preserved or template include
|
|
46
|
+
*/
|
|
47
|
+
private chooseInclude;
|
|
48
|
+
/**
|
|
49
|
+
* Prefer the project's pre-strategy tsconfig.json exclude when one existed.
|
|
50
|
+
* Falls back to the stack template exclude when no snapshot exists.
|
|
51
|
+
* @param templateExclude - Stack template exclude to fall back to
|
|
52
|
+
* @returns The preserved or template exclude
|
|
53
|
+
*/
|
|
54
|
+
private chooseExclude;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=ensure-tsconfig-local-includes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ensure-tsconfig-local-includes.d.ts","sourceRoot":"","sources":["../../src/migrations/ensure-tsconfig-local-includes.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,SAAS,EACT,gBAAgB,EAChB,eAAe,EAChB,MAAM,0BAA0B,CAAC;AA+ElC;;;;;;;;;;;;;GAaG;AACH,qBAAa,oCAAqC,YAAW,SAAS;IACpE,QAAQ,CAAC,IAAI,oCAAoC;IACjD,QAAQ,CAAC,WAAW,wFACmE;IAEvF,OAAO,CAAC,eAAe,CAAgC;IACvD,OAAO,CAAC,eAAe,CAAgC;IAEvD;;;;OAIG;IACG,gBAAgB,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAY5D;;;;OAIG;IACG,OAAO,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;IAStD;;;;OAIG;IACG,KAAK,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;IAoD5D;;;;;;;OAOG;IACH,OAAO,CAAC,aAAa;IAOrB;;;;;OAKG;IACH,OAAO,CAAC,aAAa;CAMtB"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import * as path from "node:path";
|
|
2
|
+
import * as fse from "fs-extra";
|
|
3
|
+
import { readJsonOrNull, writeJson } from "../utils/json-utils.js";
|
|
4
|
+
const TSCONFIG_LOCAL = "tsconfig.local.json";
|
|
5
|
+
const TSCONFIG_ROOT = "tsconfig.json";
|
|
6
|
+
/**
|
|
7
|
+
* Preferred order of project types for sourcing include/exclude defaults.
|
|
8
|
+
* The first type in detectedTypes matching this list is used.
|
|
9
|
+
*/
|
|
10
|
+
const TEMPLATE_PRIORITY = [
|
|
11
|
+
"expo",
|
|
12
|
+
"cdk",
|
|
13
|
+
"nestjs",
|
|
14
|
+
"npm-package",
|
|
15
|
+
"typescript",
|
|
16
|
+
];
|
|
17
|
+
/**
|
|
18
|
+
* Fallback defaults when the template file cannot be read (matches typescript/create-only)
|
|
19
|
+
*/
|
|
20
|
+
const FALLBACK_DEFAULTS = {
|
|
21
|
+
include: ["src/**/*"],
|
|
22
|
+
exclude: ["node_modules", ".build", "dist", "**/*.test.ts", "**/*.spec.ts"],
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Return the template project type to read defaults from, or null if none applies
|
|
26
|
+
* @param detectedTypes - Detected project types for the destination project
|
|
27
|
+
* @returns The highest-priority matching project type, or null when none match
|
|
28
|
+
*/
|
|
29
|
+
function pickTemplateType(detectedTypes) {
|
|
30
|
+
for (const type of TEMPLATE_PRIORITY) {
|
|
31
|
+
if (detectedTypes.includes(type)) {
|
|
32
|
+
return type;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Load include/exclude defaults from a Lisa template tsconfig.local.json
|
|
39
|
+
* @param lisaDir - Lisa installation directory
|
|
40
|
+
* @param type - Project type whose template to read
|
|
41
|
+
* @returns The template's include/exclude, or the fallback defaults when absent
|
|
42
|
+
*/
|
|
43
|
+
async function loadTemplateDefaults(lisaDir, type) {
|
|
44
|
+
const templatePath = path.join(lisaDir, type, "create-only", TSCONFIG_LOCAL);
|
|
45
|
+
const template = await readJsonOrNull(templatePath);
|
|
46
|
+
if (!template) {
|
|
47
|
+
return FALLBACK_DEFAULTS;
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
include: template.include ?? FALLBACK_DEFAULTS.include,
|
|
51
|
+
exclude: template.exclude ?? FALLBACK_DEFAULTS.exclude,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Migration: backfill missing include/exclude in existing tsconfig.local.json files.
|
|
56
|
+
*
|
|
57
|
+
* Before PR #373, include/exclude lived in tsconfig.json. After they moved to
|
|
58
|
+
* tsconfig.local.json (create-only), existing projects kept their include-less local
|
|
59
|
+
* tsconfig and typecheck began compiling tests, worktrees, etc. This migration injects
|
|
60
|
+
* the canonical defaults for any key that is missing without touching existing values.
|
|
61
|
+
*
|
|
62
|
+
* Additionally, this migration preserves a project's narrower include/exclude from
|
|
63
|
+
* the pre-strategy tsconfig.json when the stack template's include/exclude would
|
|
64
|
+
* widen tsc scope. Evidence: thumbwar-backend's tsconfig.json pinned `include: ["src/**\/*"]`
|
|
65
|
+
* but after Lisa overwrote tsconfig.json the stack template's include was used,
|
|
66
|
+
* pulling `vitest.*.ts` into typecheck scope.
|
|
67
|
+
*/
|
|
68
|
+
export class EnsureTsconfigLocalIncludesMigration {
|
|
69
|
+
name = "ensure-tsconfig-local-includes";
|
|
70
|
+
description = "Backfill include/exclude in tsconfig.local.json for projects upgraded past PR #373";
|
|
71
|
+
snapshotInclude;
|
|
72
|
+
snapshotExclude;
|
|
73
|
+
/**
|
|
74
|
+
* Snapshot the project's pre-strategy tsconfig.json include/exclude so we can
|
|
75
|
+
* preserve narrower scopes when the copy-overwrite strategy replaces tsconfig.json.
|
|
76
|
+
* @param ctx - Migration context
|
|
77
|
+
*/
|
|
78
|
+
async beforeStrategies(ctx) {
|
|
79
|
+
const rootPath = path.join(ctx.projectDir, TSCONFIG_ROOT);
|
|
80
|
+
const existing = await readJsonOrNull(rootPath);
|
|
81
|
+
if (!existing) {
|
|
82
|
+
this.snapshotInclude = undefined;
|
|
83
|
+
this.snapshotExclude = undefined;
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
this.snapshotInclude = existing.include;
|
|
87
|
+
this.snapshotExclude = existing.exclude;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Check whether this migration should run on the project
|
|
91
|
+
* @param ctx - Migration context
|
|
92
|
+
* @returns True when tsconfig.local.json exists but is missing include or exclude
|
|
93
|
+
*/
|
|
94
|
+
async applies(ctx) {
|
|
95
|
+
const tsconfigLocalPath = path.join(ctx.projectDir, TSCONFIG_LOCAL);
|
|
96
|
+
const existing = await readJsonOrNull(tsconfigLocalPath);
|
|
97
|
+
if (!existing) {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
return existing.include === undefined || existing.exclude === undefined;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Apply the migration, injecting any missing include/exclude keys
|
|
104
|
+
* @param ctx - Migration context
|
|
105
|
+
* @returns Result describing the action taken
|
|
106
|
+
*/
|
|
107
|
+
async apply(ctx) {
|
|
108
|
+
const tsconfigLocalPath = path.join(ctx.projectDir, TSCONFIG_LOCAL);
|
|
109
|
+
const existing = await readJsonOrNull(tsconfigLocalPath);
|
|
110
|
+
if (!existing) {
|
|
111
|
+
return { name: this.name, action: "noop" };
|
|
112
|
+
}
|
|
113
|
+
const templateType = pickTemplateType(ctx.detectedTypes);
|
|
114
|
+
const defaults = templateType
|
|
115
|
+
? await loadTemplateDefaults(ctx.lisaDir, templateType)
|
|
116
|
+
: FALLBACK_DEFAULTS;
|
|
117
|
+
const chosenInclude = this.chooseInclude(defaults.include);
|
|
118
|
+
const chosenExclude = this.chooseExclude(defaults.exclude);
|
|
119
|
+
const patched = {
|
|
120
|
+
...existing,
|
|
121
|
+
...(existing.include === undefined ? { include: chosenInclude } : {}),
|
|
122
|
+
...(existing.exclude === undefined ? { exclude: chosenExclude } : {}),
|
|
123
|
+
};
|
|
124
|
+
const missing = [
|
|
125
|
+
...(existing.include === undefined ? ["include"] : []),
|
|
126
|
+
...(existing.exclude === undefined ? ["exclude"] : []),
|
|
127
|
+
];
|
|
128
|
+
if (missing.length === 0) {
|
|
129
|
+
return { name: this.name, action: "noop" };
|
|
130
|
+
}
|
|
131
|
+
const message = `Injected ${missing.join(", ")} into tsconfig.local.json`;
|
|
132
|
+
if (ctx.dryRun) {
|
|
133
|
+
ctx.logger.dry(`Would update tsconfig.local.json: ${missing.join(", ")}`);
|
|
134
|
+
return {
|
|
135
|
+
name: this.name,
|
|
136
|
+
action: "applied",
|
|
137
|
+
changedFiles: [TSCONFIG_LOCAL],
|
|
138
|
+
message,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
await fse.ensureDir(path.dirname(tsconfigLocalPath));
|
|
142
|
+
await writeJson(tsconfigLocalPath, patched);
|
|
143
|
+
ctx.logger.success(message);
|
|
144
|
+
return {
|
|
145
|
+
name: this.name,
|
|
146
|
+
action: "applied",
|
|
147
|
+
changedFiles: [TSCONFIG_LOCAL],
|
|
148
|
+
message,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Prefer the project's pre-strategy tsconfig.json include when it is narrower
|
|
153
|
+
* than the stack template's include. "Narrower" means the snapshot is a strict
|
|
154
|
+
* subset of the template or differs in content at all — we preserve project intent.
|
|
155
|
+
* Falls back to the stack template include when no snapshot exists.
|
|
156
|
+
* @param templateInclude - Stack template include to fall back to
|
|
157
|
+
* @returns The preserved or template include
|
|
158
|
+
*/
|
|
159
|
+
chooseInclude(templateInclude) {
|
|
160
|
+
if (this.snapshotInclude === undefined) {
|
|
161
|
+
return templateInclude;
|
|
162
|
+
}
|
|
163
|
+
return this.snapshotInclude;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Prefer the project's pre-strategy tsconfig.json exclude when one existed.
|
|
167
|
+
* Falls back to the stack template exclude when no snapshot exists.
|
|
168
|
+
* @param templateExclude - Stack template exclude to fall back to
|
|
169
|
+
* @returns The preserved or template exclude
|
|
170
|
+
*/
|
|
171
|
+
chooseExclude(templateExclude) {
|
|
172
|
+
if (this.snapshotExclude === undefined) {
|
|
173
|
+
return templateExclude;
|
|
174
|
+
}
|
|
175
|
+
return this.snapshotExclude;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=ensure-tsconfig-local-includes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ensure-tsconfig-local-includes.js","sourceRoot":"","sources":["../../src/migrations/ensure-tsconfig-local-includes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Migration, MigrationContext, MigrationResult } from "./migration.interface.js";
|
|
2
|
+
export type { Migration, MigrationAction, MigrationContext, MigrationResult, } from "./migration.interface.js";
|
|
3
|
+
export { EnsureLisaPostinstallMigration } from "./ensure-lisa-postinstall.js";
|
|
4
|
+
export { EnsureTsconfigLocalIncludesMigration } from "./ensure-tsconfig-local-includes.js";
|
|
5
|
+
/**
|
|
6
|
+
* Registry that runs applicable migrations against a destination project
|
|
7
|
+
*/
|
|
8
|
+
export declare class MigrationRegistry {
|
|
9
|
+
private readonly migrations;
|
|
10
|
+
/**
|
|
11
|
+
* Initialize registry with provided or default migrations
|
|
12
|
+
* @param migrations - Optional array of migrations (uses defaults if omitted)
|
|
13
|
+
*/
|
|
14
|
+
constructor(migrations?: readonly Migration[]);
|
|
15
|
+
/**
|
|
16
|
+
* Get all registered migrations
|
|
17
|
+
* @returns All migrations in registration order
|
|
18
|
+
*/
|
|
19
|
+
getAll(): readonly Migration[];
|
|
20
|
+
/**
|
|
21
|
+
* Invoke the optional `beforeStrategies` hook on every registered migration.
|
|
22
|
+
* Used to snapshot project state that strategies will subsequently overwrite.
|
|
23
|
+
* @param ctx - Migration context
|
|
24
|
+
*/
|
|
25
|
+
runBeforeStrategies(ctx: MigrationContext): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Run every migration whose `applies` returns true
|
|
28
|
+
* @param ctx - Migration context
|
|
29
|
+
* @returns Aggregated results from every registered migration
|
|
30
|
+
*/
|
|
31
|
+
runAll(ctx: MigrationContext): Promise<readonly MigrationResult[]>;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Create the default migration registry
|
|
35
|
+
* @returns New MigrationRegistry with all default migrations registered
|
|
36
|
+
*/
|
|
37
|
+
export declare function createMigrationRegistry(): MigrationRegistry;
|
|
38
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,SAAS,EACT,gBAAgB,EAChB,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAElC,YAAY,EACV,SAAS,EACT,eAAe,EACf,gBAAgB,EAChB,eAAe,GAChB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,8BAA8B,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,EAAE,oCAAoC,EAAE,MAAM,qCAAqC,CAAC;AAE3F;;GAEG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAuB;IAElD;;;OAGG;gBACS,UAAU,CAAC,EAAE,SAAS,SAAS,EAAE;IAO7C;;;OAGG;IACH,MAAM,IAAI,SAAS,SAAS,EAAE;IAI9B;;;;OAIG;IACG,mBAAmB,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ/D;;;;OAIG;IACG,MAAM,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,SAAS,eAAe,EAAE,CAAC;CAazE;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,IAAI,iBAAiB,CAE3D"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { EnsureLisaPostinstallMigration } from "./ensure-lisa-postinstall.js";
|
|
2
|
+
import { EnsureTsconfigLocalIncludesMigration } from "./ensure-tsconfig-local-includes.js";
|
|
3
|
+
export { EnsureLisaPostinstallMigration } from "./ensure-lisa-postinstall.js";
|
|
4
|
+
export { EnsureTsconfigLocalIncludesMigration } from "./ensure-tsconfig-local-includes.js";
|
|
5
|
+
/**
|
|
6
|
+
* Registry that runs applicable migrations against a destination project
|
|
7
|
+
*/
|
|
8
|
+
export class MigrationRegistry {
|
|
9
|
+
migrations;
|
|
10
|
+
/**
|
|
11
|
+
* Initialize registry with provided or default migrations
|
|
12
|
+
* @param migrations - Optional array of migrations (uses defaults if omitted)
|
|
13
|
+
*/
|
|
14
|
+
constructor(migrations) {
|
|
15
|
+
this.migrations = migrations ?? [
|
|
16
|
+
new EnsureTsconfigLocalIncludesMigration(),
|
|
17
|
+
new EnsureLisaPostinstallMigration(),
|
|
18
|
+
];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Get all registered migrations
|
|
22
|
+
* @returns All migrations in registration order
|
|
23
|
+
*/
|
|
24
|
+
getAll() {
|
|
25
|
+
return this.migrations;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Invoke the optional `beforeStrategies` hook on every registered migration.
|
|
29
|
+
* Used to snapshot project state that strategies will subsequently overwrite.
|
|
30
|
+
* @param ctx - Migration context
|
|
31
|
+
*/
|
|
32
|
+
async runBeforeStrategies(ctx) {
|
|
33
|
+
for (const migration of this.migrations) {
|
|
34
|
+
if (migration.beforeStrategies) {
|
|
35
|
+
await migration.beforeStrategies(ctx);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Run every migration whose `applies` returns true
|
|
41
|
+
* @param ctx - Migration context
|
|
42
|
+
* @returns Aggregated results from every registered migration
|
|
43
|
+
*/
|
|
44
|
+
async runAll(ctx) {
|
|
45
|
+
const results = [];
|
|
46
|
+
for (const migration of this.migrations) {
|
|
47
|
+
const shouldRun = await migration.applies(ctx);
|
|
48
|
+
if (!shouldRun) {
|
|
49
|
+
results.push({ name: migration.name, action: "skipped" });
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
const result = await migration.apply(ctx);
|
|
53
|
+
results.push(result);
|
|
54
|
+
}
|
|
55
|
+
return results;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Create the default migration registry
|
|
60
|
+
* @returns New MigrationRegistry with all default migrations registered
|
|
61
|
+
*/
|
|
62
|
+
export function createMigrationRegistry() {
|
|
63
|
+
return new MigrationRegistry();
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,EAAE,oCAAoC,EAAE,MAAM,qCAAqC,CAAC;AAa3F,OAAO,EAAE,8BAA8B,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,EAAE,oCAAoC,EAAE,MAAM,qCAAqC,CAAC;AAE3F;;GAEG;AACH,MAAM,OAAO,iBAAiB;IACX,UAAU,CAAuB;IAElD;;;OAGG;IACH,YAAY,UAAiC;QAC3C,IAAI,CAAC,UAAU,GAAG,UAAU,IAAI;YAC9B,IAAI,oCAAoC,EAAE;YAC1C,IAAI,8BAA8B,EAAE;SACrC,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,MAAM;QACJ,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,mBAAmB,CAAC,GAAqB;QAC7C,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACxC,IAAI,SAAS,CAAC,gBAAgB,EAAE,CAAC;gBAC/B,MAAM,SAAS,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC;YACxC,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,MAAM,CAAC,GAAqB;QAChC,MAAM,OAAO,GAAsB,EAAE,CAAC;QACtC,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACxC,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAC/C,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;gBAC1D,SAAS;YACX,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC1C,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvB,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB;IACrC,OAAO,IAAI,iBAAiB,EAAE,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { ProjectType } from "../core/config.js";
|
|
2
|
+
import type { ILogger } from "../logging/index.js";
|
|
3
|
+
/**
|
|
4
|
+
* Action performed by a migration run
|
|
5
|
+
*/
|
|
6
|
+
export type MigrationAction = "applied" | "skipped" | "noop";
|
|
7
|
+
/**
|
|
8
|
+
* Context passed to migrations at runtime
|
|
9
|
+
*/
|
|
10
|
+
export interface MigrationContext {
|
|
11
|
+
/** Destination project directory */
|
|
12
|
+
readonly projectDir: string;
|
|
13
|
+
/** Lisa installation directory (where templates live) */
|
|
14
|
+
readonly lisaDir: string;
|
|
15
|
+
/** Project types detected for the destination project */
|
|
16
|
+
readonly detectedTypes: readonly ProjectType[];
|
|
17
|
+
/** If true, describe what would change without modifying files */
|
|
18
|
+
readonly dryRun: boolean;
|
|
19
|
+
/** Logger for user-facing output */
|
|
20
|
+
readonly logger: ILogger;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Result of running a migration
|
|
24
|
+
*/
|
|
25
|
+
export interface MigrationResult {
|
|
26
|
+
readonly name: string;
|
|
27
|
+
readonly action: MigrationAction;
|
|
28
|
+
readonly changedFiles?: readonly string[];
|
|
29
|
+
readonly message?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* One-time idempotent transform applied to an existing project
|
|
33
|
+
*/
|
|
34
|
+
export interface Migration {
|
|
35
|
+
readonly name: string;
|
|
36
|
+
readonly description: string;
|
|
37
|
+
/**
|
|
38
|
+
* Optional pre-strategy hook. Runs before the copy/deletion strategies so
|
|
39
|
+
* the migration can snapshot files that will subsequently be overwritten.
|
|
40
|
+
* Implementations must be idempotent and side-effect free beyond updating
|
|
41
|
+
* their own in-memory state.
|
|
42
|
+
* @param ctx Migration context
|
|
43
|
+
*/
|
|
44
|
+
beforeStrategies?(ctx: MigrationContext): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Whether this migration should run on this project.
|
|
47
|
+
* @param ctx Migration context
|
|
48
|
+
*/
|
|
49
|
+
applies(ctx: MigrationContext): Promise<boolean>;
|
|
50
|
+
/**
|
|
51
|
+
* Apply the migration. Must be idempotent.
|
|
52
|
+
* @param ctx Migration context
|
|
53
|
+
*/
|
|
54
|
+
apply(ctx: MigrationContext): Promise<MigrationResult>;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=migration.interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration.interface.d.ts","sourceRoot":"","sources":["../../src/migrations/migration.interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAEnD;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;AAE7D;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,oCAAoC;IACpC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAE5B,yDAAyD;IACzD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,yDAAyD;IACzD,QAAQ,CAAC,aAAa,EAAE,SAAS,WAAW,EAAE,CAAC;IAE/C,kEAAkE;IAClE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAEzB,oCAAoC;IACpC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAE7B;;;;;;OAMG;IACH,gBAAgB,CAAC,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAExD;;;OAGG;IACH,OAAO,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEjD;;;OAGG;IACH,KAAK,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CACxD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration.interface.js","sourceRoot":"","sources":["../../src/migrations/migration.interface.ts"],"names":[],"mappings":""}
|
package/package.json
CHANGED
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
"lodash": ">=4.18.1"
|
|
77
77
|
},
|
|
78
78
|
"name": "@codyswann/lisa",
|
|
79
|
-
"version": "1.
|
|
79
|
+
"version": "1.84.0",
|
|
80
80
|
"description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
|
|
81
81
|
"main": "dist/index.js",
|
|
82
82
|
"exports": {
|