@codyswann/lisa 4.28.2 → 4.28.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/dist/cli/doctor-merge-drivers.d.ts.map +1 -1
  2. package/dist/cli/doctor-merge-drivers.js +4 -2
  3. package/dist/cli/doctor-merge-drivers.js.map +1 -1
  4. package/dist/codex/scripts/block-no-verify.sh +302 -97
  5. package/dist/core/learnings.d.ts +1 -1
  6. package/dist/core/learnings.d.ts.map +1 -1
  7. package/dist/core/learnings.js +1 -1
  8. package/dist/core/learnings.js.map +1 -1
  9. package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
  10. package/dist/core/project-config-learnings.d.ts +49 -0
  11. package/dist/core/project-config-learnings.d.ts.map +1 -0
  12. package/dist/core/project-config-learnings.js +87 -0
  13. package/dist/core/project-config-learnings.js.map +1 -0
  14. package/dist/core/project-config.d.ts +2 -18
  15. package/dist/core/project-config.d.ts.map +1 -1
  16. package/dist/core/project-config.js +4 -57
  17. package/dist/core/project-config.js.map +1 -1
  18. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  19. package/dist/core/upstream-evidence-manifest.js +9 -5
  20. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  21. package/dist/migrations/ensure-learnings-gitattributes.d.ts.map +1 -1
  22. package/dist/migrations/ensure-learnings-gitattributes.js +6 -5
  23. package/dist/migrations/ensure-learnings-gitattributes.js.map +1 -1
  24. package/dist/migrations/ensure-learnings-merge-driver.d.ts.map +1 -1
  25. package/dist/migrations/ensure-learnings-merge-driver.js +6 -3
  26. package/dist/migrations/ensure-learnings-merge-driver.js.map +1 -1
  27. package/package.json +3 -3
  28. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  29. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  30. package/plugins/lisa/.codex-plugin/skills/lisa-drive-pr-to-merge/SKILL.md +7 -3
  31. package/plugins/lisa/.codex-plugin/skills/lisa-persist-learning/SKILL.md +1 -1
  32. package/plugins/lisa/hooks/block-no-verify.agy.sh +302 -97
  33. package/plugins/lisa/skills/lisa-drive-pr-to-merge/SKILL.md +7 -3
  34. package/plugins/lisa/skills/lisa-persist-learning/SKILL.md +1 -1
  35. package/plugins/lisa-agy/hooks/block-no-verify.agy.sh +302 -97
  36. package/plugins/lisa-agy/plugin.json +1 -1
  37. package/plugins/lisa-agy/skills/lisa-drive-pr-to-merge/SKILL.md +7 -3
  38. package/plugins/lisa-agy/skills/lisa-persist-learning/SKILL.md +1 -1
  39. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  40. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  41. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  42. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  43. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  44. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  45. package/plugins/lisa-copilot/skills/lisa-drive-pr-to-merge/SKILL.md +7 -3
  46. package/plugins/lisa-copilot/skills/lisa-persist-learning/SKILL.md +1 -1
  47. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  48. package/plugins/lisa-cursor/skills/lisa-drive-pr-to-merge/SKILL.md +7 -3
  49. package/plugins/lisa-cursor/skills/lisa-persist-learning/SKILL.md +1 -1
  50. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  51. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  52. package/plugins/lisa-expo-agy/plugin.json +1 -1
  53. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  54. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  55. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  56. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  57. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  58. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  59. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  60. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  61. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  62. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  63. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  64. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  65. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  66. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  67. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  68. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  69. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  70. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  71. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  72. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  73. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  74. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  75. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  76. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  77. package/plugins/lisa-rails-agy/plugin.json +1 -1
  78. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  79. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  80. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  81. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  82. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  83. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  84. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  85. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  86. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  87. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  88. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  89. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  90. package/plugins/src/base/hooks/block-no-verify.agy.sh +302 -97
  91. package/plugins/src/base/skills/lisa-drive-pr-to-merge/SKILL.md +7 -3
  92. package/plugins/src/base/skills/lisa-persist-learning/SKILL.md +1 -1
  93. package/scripts/verify-packed-learnings-contract.mjs +101 -2
  94. package/dist/core/learnings-merge-driver-config.d.ts +0 -7
  95. package/dist/core/learnings-merge-driver-config.d.ts.map +0 -1
  96. package/dist/core/learnings-merge-driver-config.js +0 -58
  97. package/dist/core/learnings-merge-driver-config.js.map +0 -1
@@ -2,7 +2,14 @@
2
2
  /** Empirical proof that the packed public learnings API preserves v2 semantics. */
3
3
  import assert from "node:assert/strict";
4
4
  import { execFile } from "node:child_process";
5
- import { mkdir, mkdtemp, readFile, rm } from "node:fs/promises";
5
+ import {
6
+ mkdir,
7
+ mkdtemp,
8
+ readFile,
9
+ rm,
10
+ symlink,
11
+ writeFile,
12
+ } from "node:fs/promises";
6
13
  import path from "node:path";
7
14
  import { pathToFileURL } from "node:url";
8
15
  import { promisify } from "node:util";
@@ -10,6 +17,8 @@ import { promisify } from "node:util";
10
17
  const executeFile = promisify(execFile);
11
18
  const root = path.resolve(import.meta.dirname, "..");
12
19
  const temporary = await mkdtemp(path.join(root, ".packed-learnings-proof-"));
20
+ const packedConfigFile = ".lisa.config.json";
21
+ const packedLearningsFile = "docs/knowledge/PROJECT_LEARNINGS.md";
13
22
 
14
23
  try {
15
24
  const archive = path.join(temporary, "lisa-packed.tgz");
@@ -29,6 +38,96 @@ try {
29
38
  assert.equal(learnings.MAX_STABLE_TOKEN_BYTES, 128);
30
39
  assert.equal(learnings.LEARNINGS_CONTRACT.maxTokens, 14_900);
31
40
 
41
+ const configProject = path.join(temporary, "config-consumer");
42
+ await mkdir(configProject);
43
+ await writeFile(
44
+ path.join(configProject, packedConfigFile),
45
+ `${JSON.stringify({
46
+ learnings: {
47
+ file: packedLearningsFile,
48
+ mergeDriver: false,
49
+ },
50
+ })}\n`,
51
+ "utf8"
52
+ );
53
+ const packedConfig = await learnings.readProjectConfig(configProject);
54
+ assert.deepEqual(packedConfig.learnings, {
55
+ file: packedLearningsFile,
56
+ mergeDriver: false,
57
+ });
58
+ assert.deepEqual(learnings.resolveLearningsSettings(packedConfig), {
59
+ learningsFile: packedLearningsFile,
60
+ mergeDriverEnabled: false,
61
+ });
62
+ await writeFile(
63
+ path.join(configProject, packedConfigFile),
64
+ '{"learnings":{"mergeDriver":"false"}}\n',
65
+ "utf8"
66
+ );
67
+ await assert.rejects(
68
+ learnings.readProjectConfig(configProject),
69
+ /learnings\.mergeDriver.*expected boolean.*received "false"/iu
70
+ );
71
+
72
+ const typeConsumer = path.join(temporary, "type-consumer");
73
+ await mkdir(path.join(typeConsumer, "node_modules", "@codyswann"), {
74
+ recursive: true,
75
+ });
76
+ await symlink(
77
+ packedRoot,
78
+ path.join(typeConsumer, "node_modules", "@codyswann", "lisa"),
79
+ "dir"
80
+ );
81
+ await writeFile(
82
+ path.join(typeConsumer, "tsconfig.json"),
83
+ `${JSON.stringify(
84
+ {
85
+ compilerOptions: {
86
+ module: "NodeNext",
87
+ moduleResolution: "NodeNext",
88
+ noEmit: true,
89
+ skipLibCheck: true,
90
+ strict: true,
91
+ target: "ES2022",
92
+ },
93
+ include: ["consumer.ts"],
94
+ },
95
+ null,
96
+ 2
97
+ )}\n`,
98
+ "utf8"
99
+ );
100
+ await writeFile(
101
+ path.join(typeConsumer, "consumer.ts"),
102
+ `import { resolveLearningsSettings, type LearningsConfig, type ProjectConfig } from "@codyswann/lisa/learnings";
103
+
104
+ const absent: LearningsConfig = {};
105
+ const explicitTrue: LearningsConfig = { mergeDriver: true };
106
+ const explicitFalse: LearningsConfig = { mergeDriver: false };
107
+ const withFile: LearningsConfig = { file: "docs/LEARNINGS.md", mergeDriver: false };
108
+ const configs: ProjectConfig[] = [
109
+ { learnings: absent },
110
+ { learnings: explicitTrue },
111
+ { learnings: explicitFalse },
112
+ { learnings: withFile },
113
+ ];
114
+ for (const config of configs) resolveLearningsSettings(config);
115
+ // @ts-expect-error mergeDriver is a boolean opt-out, never a string
116
+ const invalid: LearningsConfig = { mergeDriver: "false" };
117
+ void invalid;
118
+ `,
119
+ "utf8"
120
+ );
121
+ await executeFile(
122
+ process.execPath,
123
+ [
124
+ path.join(root, "node_modules", "typescript", "bin", "tsc"),
125
+ "-p",
126
+ typeConsumer,
127
+ ],
128
+ { cwd: typeConsumer }
129
+ );
130
+
32
131
  const packedVictim = "packed-victim";
33
132
  const packedProvenance = "issue:#2015";
34
133
  const packedDate = "2026-08-26";
@@ -261,7 +360,7 @@ try {
261
360
  assert.equal(await readFile(overflow.file, "utf8"), beforeOverflowCollision);
262
361
 
263
362
  console.log(
264
- "[EVIDENCE: packed-learnings-contract] v1=migratable legacy=bounded entries=hardened stamps=hardened race=9 stale=8 chain=stable collision=atomic overflow=fork merge=2 projection=bounded"
363
+ "[EVIDENCE: packed-learnings-contract] config=validated merge-driver=opt-out types=closed v1=migratable legacy=bounded entries=hardened stamps=hardened race=9 stale=8 chain=stable collision=atomic overflow=fork merge=2 projection=bounded"
265
364
  );
266
365
  } finally {
267
366
  await rm(temporary, { recursive: true, force: true });
@@ -1,7 +0,0 @@
1
- /**
2
- * Whether this project accepts the merge-driver registration.
3
- * @param projectRoot - Host project directory
4
- * @returns False only when `learnings.mergeDriver` is explicitly `false`
5
- */
6
- export declare function isLearningsMergeDriverEnabled(projectRoot: string): Promise<boolean>;
7
- //# sourceMappingURL=learnings-merge-driver-config.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"learnings-merge-driver-config.d.ts","sourceRoot":"","sources":["../../src/core/learnings-merge-driver-config.ts"],"names":[],"mappings":"AA6CA;;;;GAIG;AACH,wBAAsB,6BAA6B,CACjD,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,OAAO,CAAC,CAQlB"}
@@ -1,58 +0,0 @@
1
- /**
2
- * Host opt-out for the project-learnings union merge driver.
3
- *
4
- * `lisa apply` registers the driver automatically, and the TypeScript stack
5
- * wires `lisa apply` into `postinstall` — so an ordinary `npm install` writes
6
- * `merge.lisa-learnings.driver` into `.git/config` with no separate human step.
7
- * That is not an escalation over `npm install` itself, which already runs
8
- * arbitrary code, but it does persist an executable hook that fires on ordinary
9
- * git operations for as long as the clone exists, outside npm's lifecycle. A
10
- * host that would rather not carry that hook needs a way to say so.
11
- *
12
- * This reads `.lisa.config.json` directly rather than extending the validated
13
- * `ProjectConfig` schema: `project-config.ts` sits exactly at its 300-line lint
14
- * cap, and forcing an extraction of its cross-cutting learnings validators to
15
- * make room would be a far larger change than this flag warrants. Keeping the
16
- * flag beside the feature it governs also means the driver's opt-out is
17
- * readable in one place.
18
- *
19
- * Opt-out only, and strictly `=== false`: absent, malformed, or non-boolean
20
- * values all leave the driver enabled, matching the zero-configuration default
21
- * every other Lisa guardrail uses. A malformed config must not silently disable
22
- * a data-integrity guard.
23
- * @module core/learnings-merge-driver-config
24
- */
25
- import { readFile } from "node:fs/promises";
26
- import * as path from "node:path";
27
- const CONFIG_FILE = ".lisa.config.json";
28
- /**
29
- * Read one inert own property without invoking an accessor.
30
- * @param candidate - Value to inspect
31
- * @param key - Property name to read
32
- * @returns The own data value, when present
33
- */
34
- function readOwn(candidate, key) {
35
- if (candidate === null || typeof candidate !== "object") {
36
- return undefined;
37
- }
38
- const descriptor = Object.getOwnPropertyDescriptor(candidate, key);
39
- return descriptor !== undefined && "value" in descriptor
40
- ? descriptor.value
41
- : undefined;
42
- }
43
- /**
44
- * Whether this project accepts the merge-driver registration.
45
- * @param projectRoot - Host project directory
46
- * @returns False only when `learnings.mergeDriver` is explicitly `false`
47
- */
48
- export async function isLearningsMergeDriverEnabled(projectRoot) {
49
- try {
50
- const raw = await readFile(path.join(projectRoot, CONFIG_FILE), "utf8");
51
- const learnings = readOwn(JSON.parse(raw), "learnings");
52
- return readOwn(learnings, "mergeDriver") !== false;
53
- }
54
- catch {
55
- return true;
56
- }
57
- }
58
- //# sourceMappingURL=learnings-merge-driver-config.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"learnings-merge-driver-config.js","sourceRoot":"","sources":["../../src/core/learnings-merge-driver-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,MAAM,WAAW,GAAG,mBAAmB,CAAC;AAExC;;;;;GAKG;AACH,SAAS,OAAO,CAAC,SAAkB,EAAE,GAAW;IAC9C,IAAI,SAAS,KAAK,IAAI,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;QACxD,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,UAAU,GAAG,MAAM,CAAC,wBAAwB,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IACnE,OAAO,UAAU,KAAK,SAAS,IAAI,OAAO,IAAI,UAAU;QACtD,CAAC,CAAC,UAAU,CAAC,KAAK;QAClB,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,WAAmB;IAEnB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,EAAE,MAAM,CAAC,CAAC;QACxE,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAY,EAAE,WAAW,CAAC,CAAC;QACnE,OAAO,OAAO,CAAC,SAAS,EAAE,aAAa,CAAC,KAAK,KAAK,CAAC;IACrD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}