@codyswann/lisa 2.171.0 → 2.171.1
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/codex/scripts/install-pkgs.sh +33 -11
- package/dist/utils/package-manager-detect.d.ts +66 -0
- package/dist/utils/package-manager-detect.d.ts.map +1 -0
- package/dist/utils/package-manager-detect.js +109 -0
- package/dist/utils/package-manager-detect.js.map +1 -0
- package/dist/utils/postinstall-trampoline.d.ts +3 -32
- package/dist/utils/postinstall-trampoline.d.ts.map +1 -1
- package/dist/utils/postinstall-trampoline.js +22 -65
- package/dist/utils/postinstall-trampoline.js.map +1 -1
- package/package.json +1 -1
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/hooks/install-pkgs.sh +34 -12
- package/plugins/lisa/skills/generate-claude-remote-build-script/SKILL.md +25 -3
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/skills/generate-claude-remote-build-script/SKILL.md +25 -3
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/hooks/install-pkgs.sh +34 -12
- package/plugins/lisa-copilot/skills/generate-claude-remote-build-script/SKILL.md +25 -3
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/hooks/install-pkgs.sh +34 -12
- package/plugins/lisa-cursor/skills/generate-claude-remote-build-script/SKILL.md +25 -3
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/src/base/hooks/install-pkgs.sh +34 -12
- package/plugins/src/base/skills/generate-claude-remote-build-script/SKILL.md +25 -3
- package/scripts/claude-remote-setup.sh +31 -3
- package/typescript/copy-contents/.husky/pre-push +8 -1
|
@@ -11,16 +11,38 @@ if [ -d "node_modules" ] || [ ! -f "package.json" ]; then
|
|
|
11
11
|
exit 0
|
|
12
12
|
fi
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
14
|
+
# Detect the package manager this project wants, honoring explicit opt-outs.
|
|
15
|
+
# Precedence: packageManager field > engines "please-use-<pm>" sentinel >
|
|
16
|
+
# lockfile presence (minus any PM the engines forbid) > npm default.
|
|
17
|
+
#
|
|
18
|
+
# This must NOT key on lockfile presence alone. An npm-only project
|
|
19
|
+
# (engines.bun = "please-use-npm", CI runs `npm ci`) that picks up a stray
|
|
20
|
+
# bun.lock would otherwise get `bun install`, re-create the bun.lock, and break
|
|
21
|
+
# — the SE-5221 regression. The engines/packageManager signals are
|
|
22
|
+
# authoritative; lockfiles are only a fallback and never override an opt-out.
|
|
23
|
+
detect_package_manager() {
|
|
24
|
+
_field="" _forced="" _forbidden=""
|
|
25
|
+
if [ -f package.json ] && command -v jq >/dev/null 2>&1; then
|
|
26
|
+
_field=$(jq -r '(.packageManager // "") | sub("@.*$";"")' package.json 2>/dev/null)
|
|
27
|
+
_forced=$(jq -r 'first((.engines // {})[] | strings | capture("please-use-(?<pm>bun|npm|yarn|pnpm)")?.pm) // ""' package.json 2>/dev/null)
|
|
28
|
+
_forbidden=$(jq -r '[(.engines // {}) | to_entries[] | select(((.value|strings) // "") | test("please-use|do-not-use";"i")) | .key] | join(" ")' package.json 2>/dev/null)
|
|
29
|
+
fi
|
|
30
|
+
case "$_field" in bun | npm | yarn | pnpm) printf '%s\n' "$_field"; return 0 ;; esac
|
|
31
|
+
case "$_forced" in bun | npm | yarn | pnpm) printf '%s\n' "$_forced"; return 0 ;; esac
|
|
32
|
+
_pm_allowed() { case " $_forbidden " in *" $1 "*) return 1 ;; *) return 0 ;; esac; }
|
|
33
|
+
if { [ -f bun.lockb ] || [ -f bun.lock ]; } && _pm_allowed bun; then printf 'bun\n'; return 0; fi
|
|
34
|
+
if [ -f pnpm-lock.yaml ] && _pm_allowed pnpm; then printf 'pnpm\n'; return 0; fi
|
|
35
|
+
if [ -f yarn.lock ] && _pm_allowed yarn; then printf 'yarn\n'; return 0; fi
|
|
36
|
+
if [ -f package-lock.json ] && _pm_allowed npm; then printf 'npm\n'; return 0; fi
|
|
37
|
+
printf 'npm\n'
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
PACKAGE_MANAGER="$(detect_package_manager)"
|
|
41
|
+
case "$PACKAGE_MANAGER" in
|
|
42
|
+
bun) command -v bun >/dev/null 2>&1 && bun install ;;
|
|
43
|
+
pnpm) command -v pnpm >/dev/null 2>&1 && pnpm install ;;
|
|
44
|
+
yarn) command -v yarn >/dev/null 2>&1 && yarn install ;;
|
|
45
|
+
*) command -v npm >/dev/null 2>&1 && npm install ;;
|
|
46
|
+
esac
|
|
25
47
|
|
|
26
48
|
exit 0
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Known package managers whose lockfiles must be regenerated when Lisa's apply
|
|
3
|
+
* mutates package.json (e.g., adds/updates resolutions or overrides entries).
|
|
4
|
+
*/
|
|
5
|
+
export type PackageManager = "bun" | "npm" | "pnpm" | "yarn";
|
|
6
|
+
/**
|
|
7
|
+
* Description of a package manager's lockfile file + the command Lisa should run
|
|
8
|
+
* to rebuild the lockfile without running install scripts.
|
|
9
|
+
*/
|
|
10
|
+
export interface LockfileRegenPlan {
|
|
11
|
+
readonly pm: PackageManager;
|
|
12
|
+
readonly lockfile: string;
|
|
13
|
+
/** Additional lockfile names for the same PM (e.g. bun.lockb for bun). */
|
|
14
|
+
readonly lockfileAlternatives?: readonly string[];
|
|
15
|
+
readonly command: string;
|
|
16
|
+
readonly args: readonly string[];
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Per-PM lockfile + regen command mapping. The regen commands are all
|
|
20
|
+
* "sync lockfile without running scripts" variants — we do NOT want to
|
|
21
|
+
* re-run lifecycle scripts (that would re-trigger the trampoline).
|
|
22
|
+
*
|
|
23
|
+
* bun: `bun install` is the canonical way to sync bun.lock after package.json
|
|
24
|
+
* changes. As of bun 1.x there is no `--lockfile-only` flag; `bun install`
|
|
25
|
+
* is already fast when node_modules is up-to-date and will simply update
|
|
26
|
+
* bun.lock to match package.json. We pass `--ignore-scripts` to avoid re-running
|
|
27
|
+
* the parent PM's lifecycle hooks (which triggered this trampoline to begin with).
|
|
28
|
+
*/
|
|
29
|
+
export declare const LOCKFILE_REGEN_PLANS: Readonly<Record<PackageManager, LockfileRegenPlan>>;
|
|
30
|
+
/**
|
|
31
|
+
* Read the set of package managers a project explicitly opts OUT of via its
|
|
32
|
+
* package.json `engines` field. The repo-wide convention is to pin an unwanted
|
|
33
|
+
* package manager to a sentinel string such as `"please-use-npm"` (e.g. an
|
|
34
|
+
* npm-only project sets `engines.bun = "please-use-npm"`). Such a manager must
|
|
35
|
+
* never have its lockfile regenerated — even if a stray lockfile for it is
|
|
36
|
+
* present — because doing so re-creates the stray lockfile via that manager's
|
|
37
|
+
* `install`. That is the SE-5221 regression: a stray `bun.lock` in an npm-only
|
|
38
|
+
* project kept alive by `bun install`, which then misroutes the pre-push hook's
|
|
39
|
+
* package-manager detection to the bun branch.
|
|
40
|
+
* @param projectDir - Absolute path to the project directory
|
|
41
|
+
* @returns Set of package managers the project forbids (possibly empty)
|
|
42
|
+
*/
|
|
43
|
+
export declare function enginesForbiddenManagers(projectDir: string): ReadonlySet<PackageManager>;
|
|
44
|
+
/**
|
|
45
|
+
* Detect which package managers the project uses based on lockfile presence,
|
|
46
|
+
* excluding any manager the project explicitly forbids via `engines`.
|
|
47
|
+
*
|
|
48
|
+
* A project may have more than one lockfile (the CDK dual-lockfile pattern
|
|
49
|
+
* keeps `bun.lock` for local dev while publishing `package-lock.json` for
|
|
50
|
+
* consumers), in which case every present lockfile must be regenerated so both
|
|
51
|
+
* stay in sync with package.json.
|
|
52
|
+
*
|
|
53
|
+
* Managers opted out via an `engines` sentinel (e.g. `bun = "please-use-npm"`)
|
|
54
|
+
* are dropped even when their lockfile is present, so the reconciliation never
|
|
55
|
+
* re-creates a stray lockfile the project deliberately disallows (SE-5221).
|
|
56
|
+
* @param projectDir - Absolute path to the project directory
|
|
57
|
+
* @returns Ordered list of detected package managers (possibly empty)
|
|
58
|
+
*/
|
|
59
|
+
export declare function detectPackageManagers(projectDir: string): readonly PackageManager[];
|
|
60
|
+
/**
|
|
61
|
+
* Get the regen plan (command/args/lockfile) for a given package manager.
|
|
62
|
+
* @param pm - Package manager to look up
|
|
63
|
+
* @returns Regen plan describing which command to spawn
|
|
64
|
+
*/
|
|
65
|
+
export declare function getLockfileRegenPlan(pm: PackageManager): LockfileRegenPlan;
|
|
66
|
+
//# sourceMappingURL=package-manager-detect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-manager-detect.d.ts","sourceRoot":"","sources":["../../src/utils/package-manager-detect.ts"],"names":[],"mappings":"AAWA;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;AAE7D;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,EAAE,cAAc,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,0EAA0E;IAC1E,QAAQ,CAAC,oBAAoB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;CAClC;AAKD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,oBAAoB,EAAE,QAAQ,CACzC,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,CA2BjC,CAAC;AAEX;;;;;;;;;;;;GAYG;AACH,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,MAAM,GACjB,WAAW,CAAC,cAAc,CAAC,CAmB7B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,MAAM,GACjB,SAAS,cAAc,EAAE,CAU3B;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,cAAc,GAAG,iBAAiB,CAE1E"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file package-manager-detect.ts
|
|
3
|
+
* @description Package-manager detection + lockfile-regen plans shared by the
|
|
4
|
+
* postinstall reconciliation trampoline. Split out from postinstall-trampoline
|
|
5
|
+
* so the detection surface (which manager a project actually uses, and which it
|
|
6
|
+
* explicitly forbids via `engines`) lives in one cohesive, well-tested module.
|
|
7
|
+
* @module utils
|
|
8
|
+
*/
|
|
9
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
10
|
+
import * as path from "node:path";
|
|
11
|
+
const INSTALL = "install";
|
|
12
|
+
const IGNORE_SCRIPTS = "--ignore-scripts";
|
|
13
|
+
/**
|
|
14
|
+
* Per-PM lockfile + regen command mapping. The regen commands are all
|
|
15
|
+
* "sync lockfile without running scripts" variants — we do NOT want to
|
|
16
|
+
* re-run lifecycle scripts (that would re-trigger the trampoline).
|
|
17
|
+
*
|
|
18
|
+
* bun: `bun install` is the canonical way to sync bun.lock after package.json
|
|
19
|
+
* changes. As of bun 1.x there is no `--lockfile-only` flag; `bun install`
|
|
20
|
+
* is already fast when node_modules is up-to-date and will simply update
|
|
21
|
+
* bun.lock to match package.json. We pass `--ignore-scripts` to avoid re-running
|
|
22
|
+
* the parent PM's lifecycle hooks (which triggered this trampoline to begin with).
|
|
23
|
+
*/
|
|
24
|
+
export const LOCKFILE_REGEN_PLANS = {
|
|
25
|
+
bun: {
|
|
26
|
+
pm: "bun",
|
|
27
|
+
lockfile: "bun.lock",
|
|
28
|
+
lockfileAlternatives: ["bun.lockb"],
|
|
29
|
+
command: "bun",
|
|
30
|
+
args: [INSTALL, IGNORE_SCRIPTS],
|
|
31
|
+
},
|
|
32
|
+
npm: {
|
|
33
|
+
pm: "npm",
|
|
34
|
+
lockfile: "package-lock.json",
|
|
35
|
+
command: "npm",
|
|
36
|
+
args: [INSTALL, "--package-lock-only", IGNORE_SCRIPTS],
|
|
37
|
+
},
|
|
38
|
+
pnpm: {
|
|
39
|
+
pm: "pnpm",
|
|
40
|
+
lockfile: "pnpm-lock.yaml",
|
|
41
|
+
command: "pnpm",
|
|
42
|
+
args: [INSTALL, "--lockfile-only", IGNORE_SCRIPTS],
|
|
43
|
+
},
|
|
44
|
+
yarn: {
|
|
45
|
+
pm: "yarn",
|
|
46
|
+
lockfile: "yarn.lock",
|
|
47
|
+
command: "yarn",
|
|
48
|
+
args: [INSTALL, "--mode", "update-lockfile"],
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Read the set of package managers a project explicitly opts OUT of via its
|
|
53
|
+
* package.json `engines` field. The repo-wide convention is to pin an unwanted
|
|
54
|
+
* package manager to a sentinel string such as `"please-use-npm"` (e.g. an
|
|
55
|
+
* npm-only project sets `engines.bun = "please-use-npm"`). Such a manager must
|
|
56
|
+
* never have its lockfile regenerated — even if a stray lockfile for it is
|
|
57
|
+
* present — because doing so re-creates the stray lockfile via that manager's
|
|
58
|
+
* `install`. That is the SE-5221 regression: a stray `bun.lock` in an npm-only
|
|
59
|
+
* project kept alive by `bun install`, which then misroutes the pre-push hook's
|
|
60
|
+
* package-manager detection to the bun branch.
|
|
61
|
+
* @param projectDir - Absolute path to the project directory
|
|
62
|
+
* @returns Set of package managers the project forbids (possibly empty)
|
|
63
|
+
*/
|
|
64
|
+
export function enginesForbiddenManagers(projectDir) {
|
|
65
|
+
try {
|
|
66
|
+
const pkg = JSON.parse(readFileSync(path.join(projectDir, "package.json"), "utf8"));
|
|
67
|
+
const engines = pkg.engines ?? {};
|
|
68
|
+
const managers = ["bun", "npm", "yarn", "pnpm"];
|
|
69
|
+
return new Set(managers.filter(pm => {
|
|
70
|
+
const value = engines[pm];
|
|
71
|
+
return (typeof value === "string" && /please-use|do-not-use/i.test(value));
|
|
72
|
+
}));
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// No package.json, or it is unreadable/invalid — nothing is forbidden.
|
|
76
|
+
return new Set();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Detect which package managers the project uses based on lockfile presence,
|
|
81
|
+
* excluding any manager the project explicitly forbids via `engines`.
|
|
82
|
+
*
|
|
83
|
+
* A project may have more than one lockfile (the CDK dual-lockfile pattern
|
|
84
|
+
* keeps `bun.lock` for local dev while publishing `package-lock.json` for
|
|
85
|
+
* consumers), in which case every present lockfile must be regenerated so both
|
|
86
|
+
* stay in sync with package.json.
|
|
87
|
+
*
|
|
88
|
+
* Managers opted out via an `engines` sentinel (e.g. `bun = "please-use-npm"`)
|
|
89
|
+
* are dropped even when their lockfile is present, so the reconciliation never
|
|
90
|
+
* re-creates a stray lockfile the project deliberately disallows (SE-5221).
|
|
91
|
+
* @param projectDir - Absolute path to the project directory
|
|
92
|
+
* @returns Ordered list of detected package managers (possibly empty)
|
|
93
|
+
*/
|
|
94
|
+
export function detectPackageManagers(projectDir) {
|
|
95
|
+
const forbidden = enginesForbiddenManagers(projectDir);
|
|
96
|
+
return Object.values(LOCKFILE_REGEN_PLANS)
|
|
97
|
+
.filter(plan => [plan.lockfile, ...(plan.lockfileAlternatives ?? [])].some(f => existsSync(path.join(projectDir, f))))
|
|
98
|
+
.map(plan => plan.pm)
|
|
99
|
+
.filter(pm => !forbidden.has(pm));
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Get the regen plan (command/args/lockfile) for a given package manager.
|
|
103
|
+
* @param pm - Package manager to look up
|
|
104
|
+
* @returns Regen plan describing which command to spawn
|
|
105
|
+
*/
|
|
106
|
+
export function getLockfileRegenPlan(pm) {
|
|
107
|
+
return LOCKFILE_REGEN_PLANS[pm];
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=package-manager-detect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-manager-detect.js","sourceRoot":"","sources":["../../src/utils/package-manager-detect.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,19 +1,7 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
*/
|
|
6
|
-
export type PackageManager = "bun" | "npm" | "pnpm" | "yarn";
|
|
7
|
-
/**
|
|
8
|
-
* Description of a package manager's lockfile file + the command Lisa should run
|
|
9
|
-
* to rebuild the lockfile without running install scripts.
|
|
10
|
-
*/
|
|
11
|
-
export interface LockfileRegenPlan {
|
|
12
|
-
readonly pm: PackageManager;
|
|
13
|
-
readonly lockfile: string;
|
|
14
|
-
readonly command: string;
|
|
15
|
-
readonly args: readonly string[];
|
|
16
|
-
}
|
|
2
|
+
import { type LockfileRegenPlan, type PackageManager, LOCKFILE_REGEN_PLANS, detectPackageManagers, enginesForbiddenManagers, getLockfileRegenPlan } from "./package-manager-detect.js";
|
|
3
|
+
export { LOCKFILE_REGEN_PLANS, detectPackageManagers, enginesForbiddenManagers, getLockfileRegenPlan, };
|
|
4
|
+
export type { LockfileRegenPlan, PackageManager };
|
|
17
5
|
/**
|
|
18
6
|
* Determine whether this Lisa invocation is running as a package-manager lifecycle
|
|
19
7
|
* script (postinstall, prepare, etc.). Works across npm, bun, yarn, and pnpm since
|
|
@@ -70,23 +58,6 @@ export declare function shouldSchedulePostinstallReconciliation(dryRun: boolean)
|
|
|
70
58
|
* @returns Absolute path to the Lisa dist directory
|
|
71
59
|
*/
|
|
72
60
|
export declare function getLisaDistDir(moduleUrl: string): string;
|
|
73
|
-
/**
|
|
74
|
-
* Detect which package managers the project uses based on lockfile presence.
|
|
75
|
-
*
|
|
76
|
-
* A project may have more than one lockfile (the CDK dual-lockfile pattern
|
|
77
|
-
* keeps `bun.lock` for local dev while publishing `package-lock.json` for
|
|
78
|
-
* consumers), in which case every present lockfile must be regenerated so both
|
|
79
|
-
* stay in sync with package.json.
|
|
80
|
-
* @param projectDir - Absolute path to the project directory
|
|
81
|
-
* @returns Ordered list of detected package managers (possibly empty)
|
|
82
|
-
*/
|
|
83
|
-
export declare function detectPackageManagers(projectDir: string): readonly PackageManager[];
|
|
84
|
-
/**
|
|
85
|
-
* Get the regen plan (command/args/lockfile) for a given package manager.
|
|
86
|
-
* @param pm - Package manager to look up
|
|
87
|
-
* @returns Regen plan describing which command to spawn
|
|
88
|
-
*/
|
|
89
|
-
export declare function getLockfileRegenPlan(pm: PackageManager): LockfileRegenPlan;
|
|
90
61
|
/**
|
|
91
62
|
* Hash a file's contents (sha256, hex-encoded). Returns null if the file
|
|
92
63
|
* does not exist or cannot be read. Used to detect whether Lisa mutated
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postinstall-trampoline.d.ts","sourceRoot":"","sources":["../../src/utils/postinstall-trampoline.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"postinstall-trampoline.d.ts","sourceRoot":"","sources":["../../src/utils/postinstall-trampoline.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAU3C,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,oBAAoB,EACpB,qBAAqB,EACrB,wBAAwB,EACxB,oBAAoB,EACrB,MAAM,6BAA6B,CAAC;AAkCrC,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,wBAAwB,EACxB,oBAAoB,GACrB,CAAC;AACF,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,CAAC;AAkBlD;;;;;GAKG;AACH,wBAAgB,0BAA0B,IAAI,OAAO,CAEpD;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,OAAO,CAE/C;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,IAAI,OAAO,CASvC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,uCAAuC,CACrD,MAAM,EAAE,OAAO,GACd,OAAO,CAYT;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAIxD;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOxD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,4BAA4B,CAChD,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,OAAO,KAAa,GAC5B,OAAO,CAAC,IAAI,CAAC,CAgBf;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,2BAA2B,CAC/C,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EAMjB,OAAO,GAAE,OAAO,KAAa,GAC5B,OAAO,CAAC,IAAI,CAAC,CAmCf"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { createHash } from "node:crypto";
|
|
3
|
-
import {
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
4
|
import * as path from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
6
|
import { PM_PATH_ENV_NAMES, PM_PATH_ENV_PREFIXES, sanitizeEnvForReconciliation, } from "./pm-env.js";
|
|
7
|
+
import { LOCKFILE_REGEN_PLANS, detectPackageManagers, enginesForbiddenManagers, getLockfileRegenPlan, } from "./package-manager-detect.js";
|
|
7
8
|
/**
|
|
8
9
|
* Env var set by npm/bun/yarn/pnpm when running lifecycle scripts (postinstall, etc.).
|
|
9
10
|
* Used to detect whether Lisa was invoked as a postinstall child of a package manager.
|
|
@@ -28,45 +29,10 @@ const POLL_INTERVAL_MS = 100;
|
|
|
28
29
|
* writes a moment to quiesce before Lisa re-applies its changes.
|
|
29
30
|
*/
|
|
30
31
|
const SETTLE_DELAY_MS = 250;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
*
|
|
36
|
-
* bun: `bun install` is the canonical way to sync bun.lock after package.json
|
|
37
|
-
* changes. As of bun 1.x there is no `--lockfile-only` flag; `bun install`
|
|
38
|
-
* is already fast when node_modules is up-to-date and will simply update
|
|
39
|
-
* bun.lock to match package.json. We pass `--ignore-scripts` to avoid re-running
|
|
40
|
-
* the parent PM's lifecycle hooks (which triggered this trampoline to begin with).
|
|
41
|
-
*/
|
|
42
|
-
const INSTALL = "install";
|
|
43
|
-
const IGNORE_SCRIPTS = "--ignore-scripts";
|
|
44
|
-
const LOCKFILE_REGEN_PLANS = {
|
|
45
|
-
bun: {
|
|
46
|
-
pm: "bun",
|
|
47
|
-
lockfile: "bun.lock",
|
|
48
|
-
command: "bun",
|
|
49
|
-
args: [INSTALL, IGNORE_SCRIPTS],
|
|
50
|
-
},
|
|
51
|
-
npm: {
|
|
52
|
-
pm: "npm",
|
|
53
|
-
lockfile: "package-lock.json",
|
|
54
|
-
command: "npm",
|
|
55
|
-
args: [INSTALL, "--package-lock-only", IGNORE_SCRIPTS],
|
|
56
|
-
},
|
|
57
|
-
pnpm: {
|
|
58
|
-
pm: "pnpm",
|
|
59
|
-
lockfile: "pnpm-lock.yaml",
|
|
60
|
-
command: "pnpm",
|
|
61
|
-
args: [INSTALL, "--lockfile-only", IGNORE_SCRIPTS],
|
|
62
|
-
},
|
|
63
|
-
yarn: {
|
|
64
|
-
pm: "yarn",
|
|
65
|
-
lockfile: "yarn.lock",
|
|
66
|
-
command: "yarn",
|
|
67
|
-
args: [INSTALL, "--mode", "update-lockfile"],
|
|
68
|
-
},
|
|
69
|
-
};
|
|
32
|
+
// Re-export the package-manager detection surface (imported above from
|
|
33
|
+
// package-manager-detect.ts) so existing importers/tests can keep importing it
|
|
34
|
+
// from this module.
|
|
35
|
+
export { LOCKFILE_REGEN_PLANS, detectPackageManagers, enginesForbiddenManagers, getLockfileRegenPlan, };
|
|
70
36
|
/**
|
|
71
37
|
* Read an env var by name without widening the project-wide process.env ban.
|
|
72
38
|
* Lisa's CLI isn't a Lambda handler or Nest service; it has to introspect its
|
|
@@ -171,29 +137,6 @@ export function getLisaDistDir(moduleUrl) {
|
|
|
171
137
|
// Walk from <dist>/utils/postinstall-trampoline.js → <dist>
|
|
172
138
|
return path.resolve(path.dirname(filename), "..");
|
|
173
139
|
}
|
|
174
|
-
/**
|
|
175
|
-
* Detect which package managers the project uses based on lockfile presence.
|
|
176
|
-
*
|
|
177
|
-
* A project may have more than one lockfile (the CDK dual-lockfile pattern
|
|
178
|
-
* keeps `bun.lock` for local dev while publishing `package-lock.json` for
|
|
179
|
-
* consumers), in which case every present lockfile must be regenerated so both
|
|
180
|
-
* stay in sync with package.json.
|
|
181
|
-
* @param projectDir - Absolute path to the project directory
|
|
182
|
-
* @returns Ordered list of detected package managers (possibly empty)
|
|
183
|
-
*/
|
|
184
|
-
export function detectPackageManagers(projectDir) {
|
|
185
|
-
return Object.values(LOCKFILE_REGEN_PLANS)
|
|
186
|
-
.filter(plan => existsSync(path.join(projectDir, plan.lockfile)))
|
|
187
|
-
.map(plan => plan.pm);
|
|
188
|
-
}
|
|
189
|
-
/**
|
|
190
|
-
* Get the regen plan (command/args/lockfile) for a given package manager.
|
|
191
|
-
* @param pm - Package manager to look up
|
|
192
|
-
* @returns Regen plan describing which command to spawn
|
|
193
|
-
*/
|
|
194
|
-
export function getLockfileRegenPlan(pm) {
|
|
195
|
-
return LOCKFILE_REGEN_PLANS[pm];
|
|
196
|
-
}
|
|
197
140
|
/**
|
|
198
141
|
* Hash a file's contents (sha256, hex-encoded). Returns null if the file
|
|
199
142
|
* does not exist or cannot be read. Used to detect whether Lisa mutated
|
|
@@ -407,10 +350,24 @@ function buildTrampolineHelpers(literals) {
|
|
|
407
350
|
catch { return null; }
|
|
408
351
|
}
|
|
409
352
|
|
|
353
|
+
function enginesForbiddenManagers(dir) {
|
|
354
|
+
try {
|
|
355
|
+
const pkg = JSON.parse(readFileSync(path.join(dir, "package.json"), "utf8"));
|
|
356
|
+
const engines = (pkg && pkg.engines) || {};
|
|
357
|
+
return ["bun", "npm", "yarn", "pnpm"].filter(
|
|
358
|
+
(pm) => typeof engines[pm] === "string" && /please-use|do-not-use/i.test(engines[pm])
|
|
359
|
+
);
|
|
360
|
+
} catch {
|
|
361
|
+
return [];
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
410
365
|
function detectPackageManagers(dir) {
|
|
366
|
+
const forbidden = enginesForbiddenManagers(dir);
|
|
411
367
|
return Object.values(LOCKFILE_PLANS)
|
|
412
|
-
.filter((plan) => existsSync(path.join(dir,
|
|
413
|
-
.map((plan) => plan.pm)
|
|
368
|
+
.filter((plan) => [plan.lockfile].concat(plan.lockfileAlternatives || []).some((f) => existsSync(path.join(dir, f))))
|
|
369
|
+
.map((plan) => plan.pm)
|
|
370
|
+
.filter((pm) => forbidden.indexOf(pm) === -1);
|
|
414
371
|
}
|
|
415
372
|
|
|
416
373
|
async function waitForParent() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postinstall-trampoline.js","sourceRoot":"","sources":["../../src/utils/postinstall-trampoline.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"postinstall-trampoline.js","sourceRoot":"","sources":["../../src/utils/postinstall-trampoline.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
"lodash": ">=4.18.1"
|
|
86
86
|
},
|
|
87
87
|
"name": "@codyswann/lisa",
|
|
88
|
-
"version": "2.171.
|
|
88
|
+
"version": "2.171.1",
|
|
89
89
|
"description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
|
|
90
90
|
"main": "dist/index.js",
|
|
91
91
|
"exports": {
|
|
@@ -8,18 +8,40 @@ if [ -d "node_modules" ]; then
|
|
|
8
8
|
exit 0
|
|
9
9
|
fi
|
|
10
10
|
|
|
11
|
-
# Detect package manager
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
11
|
+
# Detect the package manager this project wants, honoring explicit opt-outs.
|
|
12
|
+
# Precedence: packageManager field > engines "please-use-<pm>" sentinel >
|
|
13
|
+
# lockfile presence (minus any PM the engines forbid) > npm default.
|
|
14
|
+
#
|
|
15
|
+
# This must NOT key on lockfile presence alone. An npm-only project
|
|
16
|
+
# (engines.bun = "please-use-npm", CI runs `npm ci`) that picks up a stray
|
|
17
|
+
# bun.lock would otherwise get `bun install`, re-create the bun.lock, and break
|
|
18
|
+
# — the SE-5221 regression. The engines/packageManager signals are
|
|
19
|
+
# authoritative; lockfiles are only a fallback and never override an opt-out.
|
|
20
|
+
detect_package_manager() {
|
|
21
|
+
_field="" _forced="" _forbidden=""
|
|
22
|
+
if [ -f package.json ] && command -v jq >/dev/null 2>&1; then
|
|
23
|
+
_field=$(jq -r '(.packageManager // "") | sub("@.*$";"")' package.json 2>/dev/null)
|
|
24
|
+
_forced=$(jq -r 'first((.engines // {})[] | strings | capture("please-use-(?<pm>bun|npm|yarn|pnpm)")?.pm) // ""' package.json 2>/dev/null)
|
|
25
|
+
_forbidden=$(jq -r '[(.engines // {}) | to_entries[] | select(((.value|strings) // "") | test("please-use|do-not-use";"i")) | .key] | join(" ")' package.json 2>/dev/null)
|
|
26
|
+
fi
|
|
27
|
+
case "$_field" in bun | npm | yarn | pnpm) printf '%s\n' "$_field"; return 0 ;; esac
|
|
28
|
+
case "$_forced" in bun | npm | yarn | pnpm) printf '%s\n' "$_forced"; return 0 ;; esac
|
|
29
|
+
_pm_allowed() { case " $_forbidden " in *" $1 "*) return 1 ;; *) return 0 ;; esac; }
|
|
30
|
+
if { [ -f bun.lockb ] || [ -f bun.lock ]; } && _pm_allowed bun; then printf 'bun\n'; return 0; fi
|
|
31
|
+
if [ -f pnpm-lock.yaml ] && _pm_allowed pnpm; then printf 'pnpm\n'; return 0; fi
|
|
32
|
+
if [ -f yarn.lock ] && _pm_allowed yarn; then printf 'yarn\n'; return 0; fi
|
|
33
|
+
if [ -f package-lock.json ] && _pm_allowed npm; then printf 'npm\n'; return 0; fi
|
|
34
|
+
printf 'npm\n'
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
PACKAGE_MANAGER="$(detect_package_manager)"
|
|
38
|
+
echo "Detected package manager: ${PACKAGE_MANAGER}"
|
|
39
|
+
case "$PACKAGE_MANAGER" in
|
|
40
|
+
bun) bun install ;;
|
|
41
|
+
pnpm) pnpm install ;;
|
|
42
|
+
yarn) yarn install ;;
|
|
43
|
+
*) npm install ;;
|
|
44
|
+
esac
|
|
23
45
|
|
|
24
46
|
# The tools below use Linux-specific binaries and paths — skip on other platforms.
|
|
25
47
|
if [ "$(uname -s)" != "Linux" ]; then
|
|
@@ -101,12 +101,34 @@ need() { command -v "$1" >/dev/null 2>&1; }
|
|
|
101
101
|
require() { need "$1" || { echo "FATAL: required tool '$1' missing and install failed" >&2; exit 1; }; }
|
|
102
102
|
|
|
103
103
|
# --- package manager (REQUIRED) ---
|
|
104
|
-
|
|
104
|
+
# Resolve the PM from packageManager/engines/lockfiles — emit the manager the
|
|
105
|
+
# `packageManager` inventory field reported, NEVER a hardcoded bun. An npm-only
|
|
106
|
+
# project (engines.bun = "please-use-npm") must install with npm; emitting
|
|
107
|
+
# `bun install` would create a stray bun.lock and break it (the SE-5221
|
|
108
|
+
# regression). Only install/PATH-export the manager actually selected below.
|
|
109
|
+
detect_package_manager() {
|
|
110
|
+
_field="" _forced="" _forbidden=""
|
|
111
|
+
if [ -f package.json ] && command -v jq >/dev/null 2>&1; then
|
|
112
|
+
_field=$(jq -r '(.packageManager // "") | sub("@.*$";"")' package.json 2>/dev/null)
|
|
113
|
+
_forced=$(jq -r 'first((.engines // {})[] | strings | capture("please-use-(?<pm>bun|npm|yarn|pnpm)")?.pm) // ""' package.json 2>/dev/null)
|
|
114
|
+
_forbidden=$(jq -r '[(.engines // {}) | to_entries[] | select(((.value|strings) // "") | test("please-use|do-not-use";"i")) | .key] | join(" ")' package.json 2>/dev/null)
|
|
115
|
+
fi
|
|
116
|
+
case "$_field" in bun | npm | yarn | pnpm) printf '%s\n' "$_field"; return 0 ;; esac
|
|
117
|
+
case "$_forced" in bun | npm | yarn | pnpm) printf '%s\n' "$_forced"; return 0 ;; esac
|
|
118
|
+
_pm_allowed() { case " $_forbidden " in *" $1 "*) return 1 ;; *) return 0 ;; esac; }
|
|
119
|
+
{ [ -f bun.lockb ] || [ -f bun.lock ]; } && _pm_allowed bun && { printf 'bun\n'; return 0; }
|
|
120
|
+
[ -f pnpm-lock.yaml ] && _pm_allowed pnpm && { printf 'pnpm\n'; return 0; }
|
|
121
|
+
[ -f yarn.lock ] && _pm_allowed yarn && { printf 'yarn\n'; return 0; }
|
|
122
|
+
[ -f package-lock.json ] && _pm_allowed npm && { printf 'npm\n'; return 0; }
|
|
123
|
+
printf 'npm\n'
|
|
124
|
+
}
|
|
125
|
+
PM="$(detect_package_manager)"
|
|
126
|
+
if [ "$PM" = "bun" ] && ! need bun; then
|
|
105
127
|
curl -fsSL https://bun.sh/install | bash
|
|
128
|
+
export PATH="$HOME/.bun/bin:$PATH"
|
|
106
129
|
fi
|
|
107
|
-
export PATH="$HOME/.bun/bin:$PATH"
|
|
108
130
|
# NOTE: bun has known proxy package-fetch issues in cloud sessions; retry to survive transient proxy errors.
|
|
109
|
-
for i in 1 2 3; do
|
|
131
|
+
for i in 1 2 3; do "$PM" install && break || sleep 5; done
|
|
110
132
|
|
|
111
133
|
# --- required CLIs ---
|
|
112
134
|
need gh || (sudo apt-get update -y && sudo apt-get install -y gh)
|
|
@@ -101,12 +101,34 @@ need() { command -v "$1" >/dev/null 2>&1; }
|
|
|
101
101
|
require() { need "$1" || { echo "FATAL: required tool '$1' missing and install failed" >&2; exit 1; }; }
|
|
102
102
|
|
|
103
103
|
# --- package manager (REQUIRED) ---
|
|
104
|
-
|
|
104
|
+
# Resolve the PM from packageManager/engines/lockfiles — emit the manager the
|
|
105
|
+
# `packageManager` inventory field reported, NEVER a hardcoded bun. An npm-only
|
|
106
|
+
# project (engines.bun = "please-use-npm") must install with npm; emitting
|
|
107
|
+
# `bun install` would create a stray bun.lock and break it (the SE-5221
|
|
108
|
+
# regression). Only install/PATH-export the manager actually selected below.
|
|
109
|
+
detect_package_manager() {
|
|
110
|
+
_field="" _forced="" _forbidden=""
|
|
111
|
+
if [ -f package.json ] && command -v jq >/dev/null 2>&1; then
|
|
112
|
+
_field=$(jq -r '(.packageManager // "") | sub("@.*$";"")' package.json 2>/dev/null)
|
|
113
|
+
_forced=$(jq -r 'first((.engines // {})[] | strings | capture("please-use-(?<pm>bun|npm|yarn|pnpm)")?.pm) // ""' package.json 2>/dev/null)
|
|
114
|
+
_forbidden=$(jq -r '[(.engines // {}) | to_entries[] | select(((.value|strings) // "") | test("please-use|do-not-use";"i")) | .key] | join(" ")' package.json 2>/dev/null)
|
|
115
|
+
fi
|
|
116
|
+
case "$_field" in bun | npm | yarn | pnpm) printf '%s\n' "$_field"; return 0 ;; esac
|
|
117
|
+
case "$_forced" in bun | npm | yarn | pnpm) printf '%s\n' "$_forced"; return 0 ;; esac
|
|
118
|
+
_pm_allowed() { case " $_forbidden " in *" $1 "*) return 1 ;; *) return 0 ;; esac; }
|
|
119
|
+
{ [ -f bun.lockb ] || [ -f bun.lock ]; } && _pm_allowed bun && { printf 'bun\n'; return 0; }
|
|
120
|
+
[ -f pnpm-lock.yaml ] && _pm_allowed pnpm && { printf 'pnpm\n'; return 0; }
|
|
121
|
+
[ -f yarn.lock ] && _pm_allowed yarn && { printf 'yarn\n'; return 0; }
|
|
122
|
+
[ -f package-lock.json ] && _pm_allowed npm && { printf 'npm\n'; return 0; }
|
|
123
|
+
printf 'npm\n'
|
|
124
|
+
}
|
|
125
|
+
PM="$(detect_package_manager)"
|
|
126
|
+
if [ "$PM" = "bun" ] && ! need bun; then
|
|
105
127
|
curl -fsSL https://bun.sh/install | bash
|
|
128
|
+
export PATH="$HOME/.bun/bin:$PATH"
|
|
106
129
|
fi
|
|
107
|
-
export PATH="$HOME/.bun/bin:$PATH"
|
|
108
130
|
# NOTE: bun has known proxy package-fetch issues in cloud sessions; retry to survive transient proxy errors.
|
|
109
|
-
for i in 1 2 3; do
|
|
131
|
+
for i in 1 2 3; do "$PM" install && break || sleep 5; done
|
|
110
132
|
|
|
111
133
|
# --- required CLIs ---
|
|
112
134
|
need gh || (sudo apt-get update -y && sudo apt-get install -y gh)
|