@codyswann/lisa 1.85.4 → 1.85.6

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.
Files changed (98) hide show
  1. package/cdk/copy-overwrite/tsconfig.cdk.json +2 -4
  2. package/dist/configs/eslint/base.d.ts +2 -1
  3. package/dist/configs/eslint/base.d.ts.map +1 -1
  4. package/dist/configs/eslint/base.js +4 -3
  5. package/dist/configs/eslint/base.js.map +1 -1
  6. package/dist/configs/eslint/cdk.d.ts +0 -2
  7. package/dist/configs/eslint/cdk.d.ts.map +1 -1
  8. package/dist/configs/eslint/cdk.js +0 -2
  9. package/dist/configs/eslint/cdk.js.map +1 -1
  10. package/dist/configs/eslint/expo.d.ts.map +1 -1
  11. package/dist/configs/eslint/expo.js +0 -1
  12. package/dist/configs/eslint/expo.js.map +1 -1
  13. package/dist/configs/eslint/index.d.ts +0 -1
  14. package/dist/configs/eslint/index.d.ts.map +1 -1
  15. package/dist/configs/eslint/index.js +0 -1
  16. package/dist/configs/eslint/index.js.map +1 -1
  17. package/dist/configs/eslint/nestjs.d.ts +0 -2
  18. package/dist/configs/eslint/nestjs.d.ts.map +1 -1
  19. package/dist/configs/eslint/nestjs.js +0 -2
  20. package/dist/configs/eslint/nestjs.js.map +1 -1
  21. package/dist/configs/eslint/slow.d.ts +0 -1
  22. package/dist/configs/eslint/slow.d.ts.map +1 -1
  23. package/dist/configs/eslint/slow.js +0 -2
  24. package/dist/configs/eslint/slow.js.map +1 -1
  25. package/dist/configs/eslint/typescript.d.ts +0 -1
  26. package/dist/configs/eslint/typescript.d.ts.map +1 -1
  27. package/dist/configs/eslint/typescript.js +0 -2
  28. package/dist/configs/eslint/typescript.js.map +1 -1
  29. package/dist/configs/jest/base.d.ts +0 -3
  30. package/dist/configs/jest/base.d.ts.map +1 -1
  31. package/dist/configs/jest/base.js +0 -2
  32. package/dist/configs/jest/base.js.map +1 -1
  33. package/dist/configs/jest/cdk.d.ts +0 -2
  34. package/dist/configs/jest/cdk.d.ts.map +1 -1
  35. package/dist/configs/jest/cdk.js +0 -1
  36. package/dist/configs/jest/cdk.js.map +1 -1
  37. package/dist/configs/jest/expo.d.ts +0 -2
  38. package/dist/configs/jest/expo.d.ts.map +1 -1
  39. package/dist/configs/jest/expo.js +0 -1
  40. package/dist/configs/jest/expo.js.map +1 -1
  41. package/dist/configs/jest/index.d.ts +0 -1
  42. package/dist/configs/jest/index.d.ts.map +1 -1
  43. package/dist/configs/jest/index.js +0 -1
  44. package/dist/configs/jest/index.js.map +1 -1
  45. package/dist/configs/jest/nestjs.d.ts +0 -2
  46. package/dist/configs/jest/nestjs.d.ts.map +1 -1
  47. package/dist/configs/jest/nestjs.js +0 -1
  48. package/dist/configs/jest/nestjs.js.map +1 -1
  49. package/dist/configs/jest/typescript.d.ts +0 -2
  50. package/dist/configs/jest/typescript.d.ts.map +1 -1
  51. package/dist/configs/jest/typescript.js +0 -1
  52. package/dist/configs/jest/typescript.js.map +1 -1
  53. package/dist/configs/vitest/base.d.ts +0 -4
  54. package/dist/configs/vitest/base.d.ts.map +1 -1
  55. package/dist/configs/vitest/base.js +0 -3
  56. package/dist/configs/vitest/base.js.map +1 -1
  57. package/dist/configs/vitest/cdk.d.ts +0 -2
  58. package/dist/configs/vitest/cdk.d.ts.map +1 -1
  59. package/dist/configs/vitest/cdk.js +0 -1
  60. package/dist/configs/vitest/cdk.js.map +1 -1
  61. package/dist/configs/vitest/index.d.ts +0 -1
  62. package/dist/configs/vitest/index.d.ts.map +1 -1
  63. package/dist/configs/vitest/index.js +0 -1
  64. package/dist/configs/vitest/index.js.map +1 -1
  65. package/dist/configs/vitest/nestjs.d.ts +0 -2
  66. package/dist/configs/vitest/nestjs.d.ts.map +1 -1
  67. package/dist/configs/vitest/nestjs.js +0 -1
  68. package/dist/configs/vitest/nestjs.js.map +1 -1
  69. package/dist/configs/vitest/typescript.d.ts +0 -2
  70. package/dist/configs/vitest/typescript.d.ts.map +1 -1
  71. package/dist/configs/vitest/typescript.js +0 -1
  72. package/dist/configs/vitest/typescript.js.map +1 -1
  73. package/dist/core/lisa.d.ts +42 -7
  74. package/dist/core/lisa.d.ts.map +1 -1
  75. package/dist/core/lisa.js +86 -11
  76. package/dist/core/lisa.js.map +1 -1
  77. package/dist/detection/detectors/rails.d.ts.map +1 -1
  78. package/dist/detection/detectors/rails.js +0 -1
  79. package/dist/detection/detectors/rails.js.map +1 -1
  80. package/dist/utils/fibonacci.d.ts +0 -3
  81. package/dist/utils/fibonacci.d.ts.map +1 -1
  82. package/dist/utils/fibonacci.js +0 -3
  83. package/dist/utils/fibonacci.js.map +1 -1
  84. package/dist/utils/postinstall-trampoline.d.ts +68 -5
  85. package/dist/utils/postinstall-trampoline.d.ts.map +1 -1
  86. package/dist/utils/postinstall-trampoline.js +255 -32
  87. package/dist/utils/postinstall-trampoline.js.map +1 -1
  88. package/expo/copy-overwrite/tsconfig.expo.json +1 -1
  89. package/nestjs/copy-overwrite/tsconfig.nestjs.json +1 -1
  90. package/package.json +1 -1
  91. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  92. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  93. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  94. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  95. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  96. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  97. package/tsconfig/cdk.json +1 -3
  98. package/tsconfig/typescript.json +1 -3
@@ -4,7 +4,6 @@
4
4
  * Identifies Ruby on Rails projects by checking for definitive Rails signals:
5
5
  * `bin/rails` (primary) or `config/application.rb` (secondary). These markers
6
6
  * avoid false positives from other Ruby frameworks like Hanami.
7
- *
8
7
  * @module detection/detectors/rails
9
8
  */
10
9
  import * as path from "node:path";
@@ -1 +1 @@
1
- {"version":3,"file":"rails.js","sourceRoot":"","sources":["../../../src/detection/detectors/rails.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD;;;GAGG;AACH,MAAM,OAAO,aAAa;IACf,IAAI,GAAG,OAAgB,CAAC;IAEjC;;;;OAIG;IACH,KAAK,CAAC,MAAM,CAAC,OAAe;QAC1B,0CAA0C;QAC1C,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QACxD,IAAI,MAAM,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YACnC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,wDAAwD;QACxD,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,gBAAgB,CAAC,CAAC;QACrE,OAAO,MAAM,UAAU,CAAC,aAAa,CAAC,CAAC;IACzC,CAAC;CACF"}
1
+ {"version":3,"file":"rails.js","sourceRoot":"","sources":["../../../src/detection/detectors/rails.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD;;;GAGG;AACH,MAAM,OAAO,aAAa;IACf,IAAI,GAAG,OAAgB,CAAC;IAEjC;;;;OAIG;IACH,KAAK,CAAC,MAAM,CAAC,OAAe;QAC1B,0CAA0C;QAC1C,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QACxD,IAAI,MAAM,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YACnC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,wDAAwD;QACxD,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,gBAAgB,CAAC,CAAC;QACrE,OAAO,MAAM,UAAU,CAAC,aAAa,CAAC,CAAC;IACzC,CAAC;CACF"}
@@ -12,7 +12,6 @@
12
12
  * Uses a two-element pair to track consecutive values, yielding the leading
13
13
  * element on each iteration and advancing the pair forward. Each call returns
14
14
  * an independent iterator, so multiple consumers never interfere.
15
- *
16
15
  * @yields The next Fibonacci number (0n, 1n, 1n, 2n, 3n, 5n, …)
17
16
  * @example
18
17
  * ```typescript
@@ -27,7 +26,6 @@ export declare function fibonacciGenerator(): Generator<bigint, never, unknown>;
27
26
  *
28
27
  * Collects n + 1 values from the generator and returns the final element,
29
28
  * delegating the recurrence to fibonacciGenerator for DRY.
30
- *
31
29
  * @param n - Zero-based position in the Fibonacci sequence (non-negative integer)
32
30
  * @returns The nth Fibonacci number as a BigInt
33
31
  * @throws {RangeError} When n is negative, fractional, NaN, or infinite
@@ -45,7 +43,6 @@ export declare const fibonacci: (n: number) => bigint;
45
43
  * Spreads an empty array of the requested size and maps each slot to the
46
44
  * next generator value, delegating the recurrence to fibonacciGenerator for DRY.
47
45
  * Returns a fresh array on every call so callers can safely consume the result.
48
- *
49
46
  * @param length - How many Fibonacci numbers to collect (non-negative integer)
50
47
  * @returns A new readonly array of the first `length` Fibonacci numbers
51
48
  * @throws {RangeError} When length is negative, fractional, NaN, or infinite
@@ -1 +1 @@
1
- {"version":3,"file":"fibonacci.d.ts","sourceRoot":"","sources":["../../src/utils/fibonacci.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;;;;;;;;;;GAcG;AACH,wBAAiB,kBAAkB,IAAI,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CASvE;AAED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,SAAS,MAAO,MAAM,KAAG,MAYrC,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,iBAAiB,WAAY,MAAM,KAAG,SAAS,MAAM,EASjE,CAAC"}
1
+ {"version":3,"file":"fibonacci.d.ts","sourceRoot":"","sources":["../../src/utils/fibonacci.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;;;;;;;;;GAaG;AACH,wBAAiB,kBAAkB,IAAI,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CASvE;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,SAAS,MAAO,MAAM,KAAG,MAYrC,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,iBAAiB,WAAY,MAAM,KAAG,SAAS,MAAM,EASjE,CAAC"}
@@ -12,7 +12,6 @@
12
12
  * Uses a two-element pair to track consecutive values, yielding the leading
13
13
  * element on each iteration and advancing the pair forward. Each call returns
14
14
  * an independent iterator, so multiple consumers never interfere.
15
- *
16
15
  * @yields The next Fibonacci number (0n, 1n, 1n, 2n, 3n, 5n, …)
17
16
  * @example
18
17
  * ```typescript
@@ -35,7 +34,6 @@ export function* fibonacciGenerator() {
35
34
  *
36
35
  * Collects n + 1 values from the generator and returns the final element,
37
36
  * delegating the recurrence to fibonacciGenerator for DRY.
38
- *
39
37
  * @param n - Zero-based position in the Fibonacci sequence (non-negative integer)
40
38
  * @returns The nth Fibonacci number as a BigInt
41
39
  * @throws {RangeError} When n is negative, fractional, NaN, or infinite
@@ -59,7 +57,6 @@ export const fibonacci = (n) => {
59
57
  * Spreads an empty array of the requested size and maps each slot to the
60
58
  * next generator value, delegating the recurrence to fibonacciGenerator for DRY.
61
59
  * Returns a fresh array on every call so callers can safely consume the result.
62
- *
63
60
  * @param length - How many Fibonacci numbers to collect (non-negative integer)
64
61
  * @returns A new readonly array of the first `length` Fibonacci numbers
65
62
  * @throws {RangeError} When length is negative, fractional, NaN, or infinite
@@ -1 +1 @@
1
- {"version":3,"file":"fibonacci.js","sourceRoot":"","sources":["../../src/utils/fibonacci.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;;;;;;;;;;GAcG;AACH,MAAM,SAAS,CAAC,CAAC,kBAAkB;IACjC,+GAA+G;IAC/G,IAAI,IAAI,GAA8B,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC/C,oFAAoF;IAEpF,SAAS,CAAC;QACR,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC;QACd,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAS,EAAU,EAAE;IAC7C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACzD,MAAM,IAAI,UAAU,CAClB,8CAA8C,MAAM,CAAC,CAAC,CAAC,EAAE,CAC1D,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,kBAAkB,EAAE,CAAC;IACjC,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,MAAM,CACzC,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,EACtB,EAAE,CACH,CAAC;AACJ,CAAC,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,MAAc,EAAqB,EAAE;IACrE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QACxE,MAAM,IAAI,UAAU,CAClB,mDAAmD,MAAM,CAAC,MAAM,CAAC,EAAE,CACpE,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,kBAAkB,EAAE,CAAC;IACjC,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC;AACxD,CAAC,CAAC"}
1
+ {"version":3,"file":"fibonacci.js","sourceRoot":"","sources":["../../src/utils/fibonacci.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;;;;;;;;;GAaG;AACH,MAAM,SAAS,CAAC,CAAC,kBAAkB;IACjC,+GAA+G;IAC/G,IAAI,IAAI,GAA8B,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC/C,oFAAoF;IAEpF,SAAS,CAAC;QACR,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC;QACd,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAS,EAAU,EAAE;IAC7C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACzD,MAAM,IAAI,UAAU,CAClB,8CAA8C,MAAM,CAAC,CAAC,CAAC,EAAE,CAC1D,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,kBAAkB,EAAE,CAAC;IACjC,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,MAAM,CACzC,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,EACtB,EAAE,CACH,CAAC;AACJ,CAAC,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,MAAc,EAAqB,EAAE;IACrE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QACxE,MAAM,IAAI,UAAU,CAClB,mDAAmD,MAAM,CAAC,MAAM,CAAC,EAAE,CACpE,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,kBAAkB,EAAE,CAAC;IACjC,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC;AACxD,CAAC,CAAC"}
@@ -1,3 +1,18 @@
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
+ readonly command: string;
14
+ readonly args: readonly string[];
15
+ }
1
16
  /**
2
17
  * Determine whether this Lisa invocation is running as a package-manager lifecycle
3
18
  * script (postinstall, prepare, etc.). Works across npm, bun, yarn, and pnpm since
@@ -11,6 +26,16 @@ export declare function isRunningAsLifecycleScript(): boolean;
11
26
  * @returns true when running inside the detached reconciliation child
12
27
  */
13
28
  export declare function isRunningAsTrampoline(): boolean;
29
+ /**
30
+ * Detect whether Lisa is running inside a CI environment.
31
+ *
32
+ * Returns false when running inside a Vitest or Jest test runner, even if
33
+ * `CI=true` is set, because test runners are not package-manager processes
34
+ * and the trampoline's parent-liveness check would never terminate.
35
+ * @returns true when common CI env vars indicate we're in a CI runner AND we
36
+ * are not currently inside a test runner process
37
+ */
38
+ export declare function isRunningInCI(): boolean;
14
39
  /**
15
40
  * Decide whether Lisa should spawn a post-install reconciliation trampoline.
16
41
  *
@@ -45,13 +70,51 @@ export declare function shouldSchedulePostinstallReconciliation(dryRun: boolean)
45
70
  */
46
71
  export declare function getLisaDistDir(moduleUrl: string): string;
47
72
  /**
48
- * Spawn a fully detached child process that waits for the parent package manager
49
- * to exit, then re-runs Lisa to reconcile package.json. The child is detached
50
- * (independent process group, stdio ignored, unref'd) so the parent package
51
- * manager does not wait for it.
73
+ * Detect which package managers the project uses based on lockfile presence.
74
+ *
75
+ * A project may have more than one lockfile (the CDK dual-lockfile pattern
76
+ * keeps `bun.lock` for local dev while publishing `package-lock.json` for
77
+ * consumers), in which case every present lockfile must be regenerated so both
78
+ * stay in sync with package.json.
79
+ * @param projectDir - Absolute path to the project directory
80
+ * @returns Ordered list of detected package managers (possibly empty)
81
+ */
82
+ export declare function detectPackageManagers(projectDir: string): readonly PackageManager[];
83
+ /**
84
+ * Get the regen plan (command/args/lockfile) for a given package manager.
85
+ * @param pm - Package manager to look up
86
+ * @returns Regen plan describing which command to spawn
87
+ */
88
+ export declare function getLockfileRegenPlan(pm: PackageManager): LockfileRegenPlan;
89
+ /**
90
+ * Hash a file's contents (sha256, hex-encoded). Returns null if the file
91
+ * does not exist or cannot be read. Used to detect whether Lisa mutated
92
+ * package.json during its apply so we only regenerate lockfiles when needed.
93
+ * @param filePath - Absolute path to the file
94
+ * @returns Hex-encoded sha256 hash, or null if the file is unavailable
95
+ */
96
+ export declare function hashFile(filePath: string): string | null;
97
+ /**
98
+ * Spawn a reconciliation child process that waits for the parent package manager
99
+ * to exit, then re-runs Lisa to reconcile package.json.
100
+ *
101
+ * The child is always spawned fully detached (independent process group, stdio
102
+ * ignored, unref'd) so the parent package manager can exit normally. The
103
+ * trampoline child then detects the parent exiting and re-runs Lisa after the
104
+ * package manager has finished writing package.json.
105
+ *
106
+ * A blocking (non-detached) CI variant was previously attempted so that the
107
+ * parent would wait for reconciliation before the next CI step ran. However,
108
+ * this created a circular deadlock: the package manager blocks waiting for Lisa
109
+ * (postinstall), Lisa blocks waiting for the trampoline child, and the
110
+ * trampoline child polls `parentPid` (the package manager) waiting for it to
111
+ * exit — a wait that can never complete. After the 120 s `MAX_WAIT_MS` timeout
112
+ * the child exits without running reconciliation at all. Always using the
113
+ * detached pattern avoids this deadlock and ensures reconciliation actually runs.
52
114
  * @param projectDir - Absolute path to the project directory Lisa will reconcile
53
115
  * @param lisaDistDir - Absolute path to Lisa's dist directory (where index.js lives)
54
116
  * @param parentPid - PID of the package-manager process to wait on (usually process.ppid)
117
+ * @returns Promise that resolves immediately after spawning the detached child
55
118
  */
56
- export declare function scheduleReconciliationChild(projectDir: string, lisaDistDir: string, parentPid: number): void;
119
+ export declare function scheduleReconciliationChild(projectDir: string, lisaDistDir: string, parentPid: number): Promise<void>;
57
120
  //# sourceMappingURL=postinstall-trampoline.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"postinstall-trampoline.d.ts","sourceRoot":"","sources":["../../src/utils/postinstall-trampoline.ts"],"names":[],"mappings":"AAiDA;;;;;GAKG;AACH,wBAAgB,0BAA0B,IAAI,OAAO,CAEpD;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,OAAO,CAE/C;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,uCAAuC,CACrD,MAAM,EAAE,OAAO,GACd,OAAO,CAIT;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAIxD;AAED;;;;;;;;GAQG;AACH,wBAAgB,2BAA2B,CACzC,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,IAAI,CA4BN"}
1
+ {"version":3,"file":"postinstall-trampoline.d.ts","sourceRoot":"","sources":["../../src/utils/postinstall-trampoline.ts"],"names":[],"mappings":"AAmCA;;;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,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;CAClC;AA6DD;;;;;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,CAIT;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAIxD;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,MAAM,GACjB,SAAS,cAAc,EAAE,CAI3B;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,cAAc,GAAG,iBAAiB,CAE1E;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOxD;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,2BAA2B,CAC/C,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAgCf"}
@@ -1,4 +1,6 @@
1
1
  import { spawn } from "node:child_process";
2
+ import { createHash } from "node:crypto";
3
+ import { existsSync, readFileSync } from "node:fs";
2
4
  import * as path from "node:path";
3
5
  import { fileURLToPath } from "node:url";
4
6
  /**
@@ -25,6 +27,45 @@ const POLL_INTERVAL_MS = 100;
25
27
  * writes a moment to quiesce before Lisa re-applies its changes.
26
28
  */
27
29
  const SETTLE_DELAY_MS = 250;
30
+ /**
31
+ * Per-PM lockfile + regen command mapping. The regen commands are all
32
+ * "sync lockfile without running scripts" variants — we do NOT want to
33
+ * re-run lifecycle scripts (that would re-trigger the trampoline).
34
+ *
35
+ * bun: `bun install` is the canonical way to sync bun.lock after package.json
36
+ * changes. As of bun 1.x there is no `--lockfile-only` flag; `bun install`
37
+ * is already fast when node_modules is up-to-date and will simply update
38
+ * bun.lock to match package.json. We pass `--ignore-scripts` to avoid re-running
39
+ * the parent PM's lifecycle hooks (which triggered this trampoline to begin with).
40
+ */
41
+ const INSTALL = "install";
42
+ const IGNORE_SCRIPTS = "--ignore-scripts";
43
+ const LOCKFILE_REGEN_PLANS = {
44
+ bun: {
45
+ pm: "bun",
46
+ lockfile: "bun.lock",
47
+ command: "bun",
48
+ args: [INSTALL, IGNORE_SCRIPTS],
49
+ },
50
+ npm: {
51
+ pm: "npm",
52
+ lockfile: "package-lock.json",
53
+ command: "npm",
54
+ args: [INSTALL, "--package-lock-only", IGNORE_SCRIPTS],
55
+ },
56
+ pnpm: {
57
+ pm: "pnpm",
58
+ lockfile: "pnpm-lock.yaml",
59
+ command: "pnpm",
60
+ args: [INSTALL, "--lockfile-only", IGNORE_SCRIPTS],
61
+ },
62
+ yarn: {
63
+ pm: "yarn",
64
+ lockfile: "yarn.lock",
65
+ command: "yarn",
66
+ args: [INSTALL, "--mode", "update-lockfile"],
67
+ },
68
+ };
28
69
  /**
29
70
  * Read an env var by name without widening the project-wide process.env ban.
30
71
  * Lisa's CLI isn't a Lambda handler or Nest service; it has to introspect its
@@ -57,6 +98,25 @@ export function isRunningAsLifecycleScript() {
57
98
  export function isRunningAsTrampoline() {
58
99
  return readEnv(TRAMPOLINE_ENV_VAR) === "1";
59
100
  }
101
+ /**
102
+ * Detect whether Lisa is running inside a CI environment.
103
+ *
104
+ * Returns false when running inside a Vitest or Jest test runner, even if
105
+ * `CI=true` is set, because test runners are not package-manager processes
106
+ * and the trampoline's parent-liveness check would never terminate.
107
+ * @returns true when common CI env vars indicate we're in a CI runner AND we
108
+ * are not currently inside a test runner process
109
+ */
110
+ export function isRunningInCI() {
111
+ if (readEnv("VITEST") !== undefined)
112
+ return false;
113
+ if (readEnv("JEST_WORKER_ID") !== undefined)
114
+ return false;
115
+ return (readEnv("CI") === "true" ||
116
+ readEnv("CI") === "1" ||
117
+ readEnv("GITHUB_ACTIONS") === "true" ||
118
+ readEnv("CONTINUOUS_INTEGRATION") === "true");
119
+ }
60
120
  /**
61
121
  * Decide whether Lisa should spawn a post-install reconciliation trampoline.
62
122
  *
@@ -101,15 +161,67 @@ export function getLisaDistDir(moduleUrl) {
101
161
  return path.resolve(path.dirname(filename), "..");
102
162
  }
103
163
  /**
104
- * Spawn a fully detached child process that waits for the parent package manager
105
- * to exit, then re-runs Lisa to reconcile package.json. The child is detached
106
- * (independent process group, stdio ignored, unref'd) so the parent package
107
- * manager does not wait for it.
164
+ * Detect which package managers the project uses based on lockfile presence.
165
+ *
166
+ * A project may have more than one lockfile (the CDK dual-lockfile pattern
167
+ * keeps `bun.lock` for local dev while publishing `package-lock.json` for
168
+ * consumers), in which case every present lockfile must be regenerated so both
169
+ * stay in sync with package.json.
170
+ * @param projectDir - Absolute path to the project directory
171
+ * @returns Ordered list of detected package managers (possibly empty)
172
+ */
173
+ export function detectPackageManagers(projectDir) {
174
+ return Object.values(LOCKFILE_REGEN_PLANS)
175
+ .filter(plan => existsSync(path.join(projectDir, plan.lockfile)))
176
+ .map(plan => plan.pm);
177
+ }
178
+ /**
179
+ * Get the regen plan (command/args/lockfile) for a given package manager.
180
+ * @param pm - Package manager to look up
181
+ * @returns Regen plan describing which command to spawn
182
+ */
183
+ export function getLockfileRegenPlan(pm) {
184
+ return LOCKFILE_REGEN_PLANS[pm];
185
+ }
186
+ /**
187
+ * Hash a file's contents (sha256, hex-encoded). Returns null if the file
188
+ * does not exist or cannot be read. Used to detect whether Lisa mutated
189
+ * package.json during its apply so we only regenerate lockfiles when needed.
190
+ * @param filePath - Absolute path to the file
191
+ * @returns Hex-encoded sha256 hash, or null if the file is unavailable
192
+ */
193
+ export function hashFile(filePath) {
194
+ try {
195
+ const contents = readFileSync(filePath);
196
+ return createHash("sha256").update(contents).digest("hex");
197
+ }
198
+ catch {
199
+ return null;
200
+ }
201
+ }
202
+ /**
203
+ * Spawn a reconciliation child process that waits for the parent package manager
204
+ * to exit, then re-runs Lisa to reconcile package.json.
205
+ *
206
+ * The child is always spawned fully detached (independent process group, stdio
207
+ * ignored, unref'd) so the parent package manager can exit normally. The
208
+ * trampoline child then detects the parent exiting and re-runs Lisa after the
209
+ * package manager has finished writing package.json.
210
+ *
211
+ * A blocking (non-detached) CI variant was previously attempted so that the
212
+ * parent would wait for reconciliation before the next CI step ran. However,
213
+ * this created a circular deadlock: the package manager blocks waiting for Lisa
214
+ * (postinstall), Lisa blocks waiting for the trampoline child, and the
215
+ * trampoline child polls `parentPid` (the package manager) waiting for it to
216
+ * exit — a wait that can never complete. After the 120 s `MAX_WAIT_MS` timeout
217
+ * the child exits without running reconciliation at all. Always using the
218
+ * detached pattern avoids this deadlock and ensures reconciliation actually runs.
108
219
  * @param projectDir - Absolute path to the project directory Lisa will reconcile
109
220
  * @param lisaDistDir - Absolute path to Lisa's dist directory (where index.js lives)
110
221
  * @param parentPid - PID of the package-manager process to wait on (usually process.ppid)
222
+ * @returns Promise that resolves immediately after spawning the detached child
111
223
  */
112
- export function scheduleReconciliationChild(projectDir, lisaDistDir, parentPid) {
224
+ export async function scheduleReconciliationChild(projectDir, lisaDistDir, parentPid) {
113
225
  const nodeBin = process.execPath;
114
226
  const lisaEntry = path.join(lisaDistDir, "index.js");
115
227
  const trampolineSource = buildTrampolineSource({
@@ -121,6 +233,7 @@ export function scheduleReconciliationChild(projectDir, lisaDistDir, parentPid)
121
233
  projectDir,
122
234
  nodeBin,
123
235
  trampolineEnvVar: TRAMPOLINE_ENV_VAR,
236
+ lockfileRegenPlans: LOCKFILE_REGEN_PLANS,
124
237
  });
125
238
  const child = spawn(nodeBin, ["-e", trampolineSource], {
126
239
  cwd: projectDir,
@@ -134,6 +247,8 @@ export function scheduleReconciliationChild(projectDir, lisaDistDir, parentPid)
134
247
  [TRAMPOLINE_ENV_VAR]: "1",
135
248
  },
136
249
  });
250
+ // Fully detach so the parent package manager can exit. The child's
251
+ // waitForParent() will detect the exit and trigger reconciliation.
137
252
  child.unref();
138
253
  }
139
254
  /**
@@ -151,58 +266,166 @@ function inheritedEnv() {
151
266
  * Build the inline JS source that runs inside the detached trampoline child.
152
267
  * The source is passed to `node -e` so it must be self-contained (no imports that
153
268
  * require resolution via package.json, which is exactly the file we're racing).
269
+ *
270
+ * The trampoline now runs in two phases inside the child:
271
+ * 1. Wait for the parent PM to exit, then re-invoke Lisa to reconcile package.json.
272
+ * 2. If Lisa's re-invocation mutated package.json, regenerate whichever lockfiles
273
+ * are present in the project so `bun install --frozen-lockfile` / `npm ci` in
274
+ * downstream CI jobs do not fail with "lockfile had changes, but lockfile is
275
+ * frozen." Lockfile regen runs with `--ignore-scripts` so the parent PM's
276
+ * lifecycle hooks are not re-invoked (which would retrigger this trampoline).
154
277
  * @param params - Embedded constants to inline into the trampoline source
155
278
  * @returns JS source suitable for `node -e`
156
279
  */
157
280
  function buildTrampolineSource(params) {
158
281
  // JSON.stringify gives us safe inline literals for all primitive types.
159
- const parentPid = JSON.stringify(params.parentPid);
160
- const pollIntervalMs = JSON.stringify(params.pollIntervalMs);
161
- const maxWaitMs = JSON.stringify(params.maxWaitMs);
162
- const settleDelayMs = JSON.stringify(params.settleDelayMs);
163
- const lisaEntry = JSON.stringify(params.lisaEntry);
164
- const projectDir = JSON.stringify(params.projectDir);
165
- const nodeBin = JSON.stringify(params.nodeBin);
166
- const trampolineEnvVar = JSON.stringify(params.trampolineEnvVar);
282
+ const literals = {
283
+ parentPid: JSON.stringify(params.parentPid),
284
+ pollIntervalMs: JSON.stringify(params.pollIntervalMs),
285
+ maxWaitMs: JSON.stringify(params.maxWaitMs),
286
+ settleDelayMs: JSON.stringify(params.settleDelayMs),
287
+ lisaEntry: JSON.stringify(params.lisaEntry),
288
+ projectDir: JSON.stringify(params.projectDir),
289
+ nodeBin: JSON.stringify(params.nodeBin),
290
+ trampolineEnvVar: JSON.stringify(params.trampolineEnvVar),
291
+ lockfilePlans: JSON.stringify(params.lockfileRegenPlans),
292
+ };
293
+ return [
294
+ buildTrampolinePrelude(literals),
295
+ buildTrampolineHelpers(literals),
296
+ buildTrampolineMain(literals),
297
+ ].join("\n");
298
+ }
299
+ /**
300
+ * Inline `require` prelude + the lockfile plan table. Kept separate so each
301
+ * chunk of the trampoline source stays under the 75-line max-lines-per-function
302
+ * cap enforced by eslint.
303
+ * @param literals - Inlined JSON-safe literals
304
+ * @param literals.lockfilePlans - JSON-serialized lockfile plan table
305
+ * @returns JS source fragment
306
+ */
307
+ function buildTrampolinePrelude(literals) {
167
308
  return `
168
309
  const { spawn } = require("node:child_process");
310
+ const { createHash } = require("node:crypto");
311
+ const { existsSync, readFileSync } = require("node:fs");
312
+ const path = require("node:path");
169
313
 
314
+ const LOCKFILE_PLANS = ${literals.lockfilePlans};
315
+ `;
316
+ }
317
+ /**
318
+ * Helper functions inlined into the trampoline child: parent-liveness probe,
319
+ * file hasher, package-manager detector, Lisa re-invoker, and best-effort
320
+ * lockfile regenerator. Each mirrors an exported TS helper in this module so
321
+ * the logic stays test-covered via the exported versions.
322
+ * @param literals - Inlined JSON-safe literals
323
+ * @param literals.parentPid - Parent package-manager PID for liveness probe
324
+ * @param literals.pollIntervalMs - Poll interval for parent-liveness checks
325
+ * @param literals.maxWaitMs - Max wait deadline before bailing out
326
+ * @param literals.nodeBin - Node binary path to re-invoke Lisa with
327
+ * @param literals.lisaEntry - Absolute path to Lisa's dist/index.js
328
+ * @param literals.projectDir - Project directory Lisa will reconcile
329
+ * @param literals.trampolineEnvVar - Env var name used to mark child as trampoline
330
+ * @returns JS source fragment
331
+ */
332
+ function buildTrampolineHelpers(literals) {
333
+ return `
170
334
  function isAlive(pid) {
171
335
  if (!pid || pid <= 1) return false;
172
336
  try { process.kill(pid, 0); return true; } catch { return false; }
173
337
  }
174
338
 
175
- // Returns true when the parent has exited, false when the deadline elapsed
176
- // while the parent was still alive. Timing out MUST NOT re-run Lisa —
177
- // that would reintroduce the package.json race the trampoline is designed
178
- // to avoid (parent PM still writing).
339
+ function hashFile(p) {
340
+ try { return createHash("sha256").update(readFileSync(p)).digest("hex"); }
341
+ catch { return null; }
342
+ }
343
+
344
+ function detectPackageManagers(dir) {
345
+ return Object.values(LOCKFILE_PLANS)
346
+ .filter((plan) => existsSync(path.join(dir, plan.lockfile)))
347
+ .map((plan) => plan.pm);
348
+ }
349
+
179
350
  async function waitForParent() {
180
- const deadline = Date.now() + ${maxWaitMs};
351
+ const deadline = Date.now() + ${literals.maxWaitMs};
181
352
  while (Date.now() < deadline) {
182
- if (!isAlive(${parentPid})) return true;
183
- await new Promise((r) => setTimeout(r, ${pollIntervalMs}));
353
+ if (!isAlive(${literals.parentPid})) return true;
354
+ await new Promise((r) => setTimeout(r, ${literals.pollIntervalMs}));
184
355
  }
185
356
  return false;
186
357
  }
187
358
 
359
+ function spawnChild(command, args) {
360
+ return new Promise((resolve) => {
361
+ try {
362
+ const child = spawn(command, args, {
363
+ cwd: ${literals.projectDir},
364
+ stdio: "ignore",
365
+ env: Object.assign({}, process.env, { [${literals.trampolineEnvVar}]: "1" }),
366
+ });
367
+ child.on("exit", (code) => resolve(code === 0));
368
+ child.on("error", () => resolve(false));
369
+ } catch {
370
+ resolve(false);
371
+ }
372
+ });
373
+ }
374
+
375
+ function runLisa() {
376
+ return spawnChild(${literals.nodeBin}, [${literals.lisaEntry}, "--yes", "--skip-git-check", ${literals.projectDir}]);
377
+ }
378
+
379
+ async function regenerateLockfiles() {
380
+ for (const pm of detectPackageManagers(${literals.projectDir})) {
381
+ const plan = LOCKFILE_PLANS[pm];
382
+ if (!plan) continue;
383
+ // Best-effort: failures are intentionally swallowed so a missing PM
384
+ // binary (e.g., no global bun on the PATH) does not cascade into an
385
+ // install failure.
386
+ await spawnChild(plan.command, plan.args);
387
+ }
388
+ }
389
+ `;
390
+ }
391
+ /**
392
+ * Top-level async IIFE that orchestrates the trampoline child:
393
+ * 1) wait for parent PM to exit,
394
+ * 2) hash package.json,
395
+ * 3) re-run Lisa,
396
+ * 4) if Lisa changed package.json, regenerate lockfiles.
397
+ *
398
+ * Timing out MUST NOT re-run Lisa — that would reintroduce the package.json
399
+ * race the trampoline is designed to avoid (parent PM still writing).
400
+ * @param literals - Inlined JSON-safe literals
401
+ * @param literals.settleDelayMs - Settle delay before re-invoking Lisa
402
+ * @param literals.projectDir - Project directory Lisa will reconcile
403
+ * @returns JS source fragment
404
+ */
405
+ function buildTrampolineMain(literals) {
406
+ return `
188
407
  (async () => {
189
408
  try {
190
409
  const parentExited = await waitForParent();
191
410
  if (!parentExited) {
192
- // Parent still running after max wait — bail rather than race the PM.
193
411
  process.exit(0);
194
412
  }
195
- await new Promise((r) => setTimeout(r, ${settleDelayMs}));
196
- const child = spawn(
197
- ${nodeBin},
198
- [${lisaEntry}, "--yes", "--skip-git-check", ${projectDir}],
199
- {
200
- cwd: ${projectDir},
201
- stdio: "ignore",
202
- env: Object.assign({}, process.env, { [${trampolineEnvVar}]: "1" }),
203
- }
204
- );
205
- child.on("exit", () => process.exit(0));
413
+ await new Promise((r) => setTimeout(r, ${literals.settleDelayMs}));
414
+
415
+ const pkgPath = path.join(${literals.projectDir}, "package.json");
416
+ const preHash = hashFile(pkgPath);
417
+
418
+ const lisaOk = await runLisa();
419
+
420
+ const postHash = hashFile(pkgPath);
421
+ const packageJsonChanged =
422
+ lisaOk && preHash !== null && postHash !== null && preHash !== postHash;
423
+
424
+ if (packageJsonChanged) {
425
+ await regenerateLockfiles();
426
+ }
427
+
428
+ process.exit(0);
206
429
  } catch {
207
430
  process.exit(0);
208
431
  }
@@ -1 +1 @@
1
- {"version":3,"file":"postinstall-trampoline.js","sourceRoot":"","sources":["../../src/utils/postinstall-trampoline.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"postinstall-trampoline.js","sourceRoot":"","sources":["../../src/utils/postinstall-trampoline.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  {
2
- "extends": ["expo/tsconfig.base", "./tsconfig.base.json"],
2
+ "extends": ["expo/tsconfig.base", "@codyswann/lisa/tsconfig/base"],
3
3
  "compilerOptions": {
4
4
  "strict": true,
5
5
  "jsx": "react-native",
@@ -1,5 +1,5 @@
1
1
  {
2
- "extends": "./tsconfig.base.json",
2
+ "extends": "@codyswann/lisa/tsconfig/base",
3
3
  "compilerOptions": {
4
4
  "module": "commonjs",
5
5
  "target": "ES2021",
package/package.json CHANGED
@@ -78,7 +78,7 @@
78
78
  "lodash": ">=4.18.1"
79
79
  },
80
80
  "name": "@codyswann/lisa",
81
- "version": "1.85.4",
81
+ "version": "1.85.6",
82
82
  "description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
83
83
  "main": "dist/index.js",
84
84
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "1.85.4",
3
+ "version": "1.85.6",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "1.85.4",
3
+ "version": "1.85.6",
4
4
  "description": "AWS CDK-specific plugin",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "1.85.4",
3
+ "version": "1.85.6",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "1.85.4",
3
+ "version": "1.85.6",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "1.85.4",
3
+ "version": "1.85.6",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "1.85.4",
3
+ "version": "1.85.6",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"