@codyswann/lisa 2.236.0 → 2.237.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.
Files changed (66) hide show
  1. package/dist/cli/check-learnings-budget-cmd.d.ts +20 -0
  2. package/dist/cli/check-learnings-budget-cmd.d.ts.map +1 -0
  3. package/dist/cli/check-learnings-budget-cmd.js +59 -0
  4. package/dist/cli/check-learnings-budget-cmd.js.map +1 -0
  5. package/dist/cli/index.d.ts +3 -0
  6. package/dist/cli/index.d.ts.map +1 -1
  7. package/dist/cli/index.js +29 -1
  8. package/dist/cli/index.js.map +1 -1
  9. package/dist/core/learnings-budget-check.d.ts +42 -0
  10. package/dist/core/learnings-budget-check.d.ts.map +1 -0
  11. package/dist/core/learnings-budget-check.js +210 -0
  12. package/dist/core/learnings-budget-check.js.map +1 -0
  13. package/dist/core/learnings-document.js +6 -1
  14. package/dist/core/learnings-document.js.map +1 -1
  15. package/package.json +1 -1
  16. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  17. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  18. package/plugins/lisa-agy/plugin.json +1 -1
  19. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  20. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  21. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  22. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  23. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  24. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  25. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  26. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  27. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  28. package/plugins/lisa-expo-agy/plugin.json +1 -1
  29. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  30. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  31. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  32. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  33. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  34. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  35. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  36. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  37. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  38. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  39. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  40. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  41. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  42. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  43. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  44. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  45. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  46. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  47. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  48. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  49. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  50. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  51. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  52. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  53. package/plugins/lisa-rails-agy/plugin.json +1 -1
  54. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  55. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  56. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  57. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  58. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  59. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  60. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  61. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  62. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  63. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  64. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  65. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  66. package/scripts/check-learnings-budget.ts +29 -163
@@ -0,0 +1,20 @@
1
+ /** Injectable collaborators for {@link runCheckLearningsBudget}. */
2
+ export interface CheckLearningsBudgetDependencies {
3
+ /** Working directory used to resolve the config and default file. */
4
+ readonly cwd?: string;
5
+ /** Sink for the pass / missing informational line (defaults to stdout). */
6
+ readonly log?: (message: string) => void;
7
+ /** Sink for the violation diagnostic (defaults to stderr). */
8
+ readonly error?: (message: string) => void;
9
+ }
10
+ /**
11
+ * Run the budget check for one project and return the intended process exit
12
+ * code (0 pass or missing, 1 violation). Never throws for an expected
13
+ * condition — a missing learnings file resolves to a silent, successful pass.
14
+ * @param fileArg - Optional explicit learnings file to check (default: resolved
15
+ * from `.lisa.config.json`)
16
+ * @param dependencies - Injectable collaborators for tests
17
+ * @returns Process exit code
18
+ */
19
+ export declare function runCheckLearningsBudget(fileArg: string | undefined, dependencies?: CheckLearningsBudgetDependencies): Promise<number>;
20
+ //# sourceMappingURL=check-learnings-budget-cmd.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-learnings-budget-cmd.d.ts","sourceRoot":"","sources":["../../src/cli/check-learnings-budget-cmd.ts"],"names":[],"mappings":"AAyBA,oEAAoE;AACpE,MAAM,WAAW,gCAAgC;IAC/C,qEAAqE;IACrE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,2EAA2E;IAC3E,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,8DAA8D;IAC9D,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAC5C;AAoBD;;;;;;;;GAQG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,YAAY,GAAE,gCAAqC,GAClD,OAAO,CAAC,MAAM,CAAC,CAuBjB"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * `lisa check-learnings-budget` — fail CI when a project's learnings file breaks
3
+ * its hard budget.
4
+ *
5
+ * This is the delivery vehicle that carries the budget gate (built into Lisa's
6
+ * core) out to every host project's CI: the Lisa-managed reusable quality
7
+ * workflow invokes this command with `bunx`, which resolves the project's
8
+ * learnings file from `.lisa.config.json` and checks it against the shared
9
+ * contract. The learnings path is ALWAYS resolved through the
10
+ * executable config resolver — never hardcoded — so a project that relocates
11
+ * its rules directory is still gated at the right file. A project with no
12
+ * learnings file is the common, expected case and passes silently (exit 0), so
13
+ * hosts that have never recorded a learning stay green with zero configuration.
14
+ * @module cli/check-learnings-budget-cmd
15
+ */
16
+ import * as path from "node:path";
17
+ import { checkLearningsBudget, formatDiagnosticPath, } from "../core/learnings-budget-check.js";
18
+ import { readProjectConfig, resolveProjectLearningsFile, } from "../core/project-config.js";
19
+ /**
20
+ * Resolve the learnings file to check: an explicit path argument wins;
21
+ * otherwise the project config's resolved learnings path (never hardcoded).
22
+ * @param fileArg - Optional explicit learnings file argument
23
+ * @param cwd - Working directory the run is anchored to
24
+ * @returns Absolute learnings file path
25
+ */
26
+ async function resolveLearningsPath(fileArg, cwd) {
27
+ if (fileArg !== undefined) {
28
+ return path.resolve(cwd, fileArg);
29
+ }
30
+ const config = await readProjectConfig(cwd);
31
+ return path.resolve(cwd, resolveProjectLearningsFile(config));
32
+ }
33
+ /**
34
+ * Run the budget check for one project and return the intended process exit
35
+ * code (0 pass or missing, 1 violation). Never throws for an expected
36
+ * condition — a missing learnings file resolves to a silent, successful pass.
37
+ * @param fileArg - Optional explicit learnings file to check (default: resolved
38
+ * from `.lisa.config.json`)
39
+ * @param dependencies - Injectable collaborators for tests
40
+ * @returns Process exit code
41
+ */
42
+ export async function runCheckLearningsBudget(fileArg, dependencies = {}) {
43
+ const cwd = dependencies.cwd ?? process.cwd();
44
+ const log = dependencies.log ?? ((message) => console.log(message));
45
+ const error = dependencies.error ?? ((message) => console.error(message));
46
+ const resolvedFile = await resolveLearningsPath(fileArg, cwd);
47
+ const result = await checkLearningsBudget(resolvedFile);
48
+ if (result.kind === "missing") {
49
+ log(`no learnings file at ${formatDiagnosticPath(resolvedFile)} — nothing to check`);
50
+ return 0;
51
+ }
52
+ if (result.kind === "violation") {
53
+ error(`check-learnings-budget: ${formatDiagnosticPath(resolvedFile)}: ${result.detail}`);
54
+ return 1;
55
+ }
56
+ log(`${formatDiagnosticPath(resolvedFile)}: learnings budget passed (${result.entryCount}/${result.maxEntries} entries, ${result.measuredTokens}/${result.maxTokens} maxTokens)`);
57
+ return 0;
58
+ }
59
+ //# sourceMappingURL=check-learnings-budget-cmd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-learnings-budget-cmd.js","sourceRoot":"","sources":["../../src/cli/check-learnings-budget-cmd.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EACL,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,iBAAiB,EACjB,2BAA2B,GAC5B,MAAM,2BAA2B,CAAC;AAYnC;;;;;;GAMG;AACH,KAAK,UAAU,oBAAoB,CACjC,OAA2B,EAC3B,GAAW;IAEX,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACpC,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,GAAG,CAAC,CAAC;IAC5C,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,2BAA2B,CAAC,MAAM,CAAC,CAAC,CAAC;AAChE,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,OAA2B,EAC3B,eAAiD,EAAE;IAEnD,MAAM,GAAG,GAAG,YAAY,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAC9C,MAAM,GAAG,GAAG,YAAY,CAAC,GAAG,IAAI,CAAC,CAAC,OAAe,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;IAC5E,MAAM,KAAK,GACT,YAAY,CAAC,KAAK,IAAI,CAAC,CAAC,OAAe,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;IACtE,MAAM,YAAY,GAAG,MAAM,oBAAoB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAC9D,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC,YAAY,CAAC,CAAC;IACxD,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC9B,GAAG,CACD,wBAAwB,oBAAoB,CAAC,YAAY,CAAC,qBAAqB,CAChF,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QAChC,KAAK,CACH,2BAA2B,oBAAoB,CAAC,YAAY,CAAC,KAAK,MAAM,CAAC,MAAM,EAAE,CAClF,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;IACD,GAAG,CACD,GAAG,oBAAoB,CAAC,YAAY,CAAC,8BAA8B,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,UAAU,aAAa,MAAM,CAAC,cAAc,IAAI,MAAM,CAAC,SAAS,aAAa,CAC7K,CAAC;IACF,OAAO,CAAC,CAAC;AACX,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { Command } from "commander";
2
2
  import { runApply } from "./apply.js";
3
+ import { runCheckLearningsBudget } from "./check-learnings-budget-cmd.js";
3
4
  import { runCrossPollinate } from "./cross-pollinate-cmd.js";
4
5
  import { runDoctor } from "./doctor.js";
5
6
  import { printUpdateWarning } from "./print-update-warning.js";
@@ -34,6 +35,8 @@ export interface ProgramDependencies {
34
35
  runSync: typeof runSync;
35
36
  /** Serves the Lisa settings console (after a config sync). */
36
37
  runUi: typeof runUi;
38
+ /** Checks the project learnings file against its hard budget. */
39
+ runCheckLearningsBudget: typeof runCheckLearningsBudget;
37
40
  /** Runs the non-fatal npm update check (defaults to {@link runUpdateCheck}). */
38
41
  runUpdateCheck: typeof runUpdateCheck;
39
42
  /** Prints the update warning (defaults to {@link printUpdateWarning}). */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAEL,iBAAiB,EAClB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAG/C,OAAO,EAAE,OAAO,EAAuB,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAE,KAAK,EAAqB,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,6EAA6E;IAC7E,QAAQ,EAAE,OAAO,QAAQ,CAAC;IAC1B,kEAAkE;IAClE,eAAe,EAAE,OAAO,eAAe,CAAC;IACxC,4DAA4D;IAC5D,YAAY,EAAE,OAAO,YAAY,CAAC;IAClC,wCAAwC;IACxC,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,yDAAyD;IACzD,SAAS,EAAE,OAAO,SAAS,CAAC;IAC5B,qCAAqC;IACrC,SAAS,EAAE,OAAO,SAAS,CAAC;IAC5B,4EAA4E;IAC5E,iBAAiB,EAAE,OAAO,iBAAiB,CAAC;IAC5C,2EAA2E;IAC3E,OAAO,EAAE,OAAO,OAAO,CAAC;IACxB,8DAA8D;IAC9D,KAAK,EAAE,OAAO,KAAK,CAAC;IACpB,gFAAgF;IAChF,cAAc,EAAE,OAAO,cAAc,CAAC;IACtC,0EAA0E;IAC1E,kBAAkB,EAAE,OAAO,kBAAkB,CAAC;CAC/C;AAyGD;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAC3B,YAAY,GAAE,OAAO,CAAC,mBAAmB,CAAM,GAC9C,OAAO,CA4ET;AAED,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EAEL,iBAAiB,EAClB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAG/C,OAAO,EAAE,OAAO,EAAuB,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAE,KAAK,EAAqB,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,6EAA6E;IAC7E,QAAQ,EAAE,OAAO,QAAQ,CAAC;IAC1B,kEAAkE;IAClE,eAAe,EAAE,OAAO,eAAe,CAAC;IACxC,4DAA4D;IAC5D,YAAY,EAAE,OAAO,YAAY,CAAC;IAClC,wCAAwC;IACxC,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,yDAAyD;IACzD,SAAS,EAAE,OAAO,SAAS,CAAC;IAC5B,qCAAqC;IACrC,SAAS,EAAE,OAAO,SAAS,CAAC;IAC5B,4EAA4E;IAC5E,iBAAiB,EAAE,OAAO,iBAAiB,CAAC;IAC5C,2EAA2E;IAC3E,OAAO,EAAE,OAAO,OAAO,CAAC;IACxB,8DAA8D;IAC9D,KAAK,EAAE,OAAO,KAAK,CAAC;IACpB,iEAAiE;IACjE,uBAAuB,EAAE,OAAO,uBAAuB,CAAC;IACxD,gFAAgF;IAChF,cAAc,EAAE,OAAO,cAAc,CAAC;IACtC,0EAA0E;IAC1E,kBAAkB,EAAE,OAAO,kBAAkB,CAAC;CAC/C;AAuID;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAC3B,YAAY,GAAE,OAAO,CAAC,mBAAmB,CAAM,GAC9C,OAAO,CAiFT;AAED,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC"}
package/dist/cli/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { Command } from "commander";
2
2
  import { runApply } from "./apply.js";
3
+ import { runCheckLearningsBudget } from "./check-learnings-budget-cmd.js";
3
4
  import { runCrossPollinate, } from "./cross-pollinate-cmd.js";
4
5
  import { runDoctor } from "./doctor.js";
5
6
  import { printUpdateWarning } from "./print-update-warning.js";
@@ -23,11 +24,30 @@ const DEFAULT_DEPENDENCIES = {
23
24
  runCrossPollinate,
24
25
  runSync,
25
26
  runUi,
27
+ runCheckLearningsBudget,
26
28
  runUpdateCheck,
27
29
  printUpdateWarning,
28
30
  };
29
31
  /** Shared help text for the optional project-path positional argument. */
30
32
  const PATH_ARG_DESCRIPTION = "Project path (default: current directory)";
33
+ /**
34
+ * Register the `check-learnings-budget` gate command. Extracted so the broader
35
+ * maintenance-command registrar stays within the function-length budget.
36
+ * @param program - Commander program to mutate
37
+ * @param deps - Program dependencies
38
+ */
39
+ function addCheckLearningsBudgetCommand(program, deps) {
40
+ program
41
+ .command("check-learnings-budget")
42
+ .description("Fail if the project learnings file exceeds its hard budget (missing file passes)")
43
+ .argument("[path]", "Learnings file to check (default: resolved from .lisa.config.json)")
44
+ .action(async (targetPath) => {
45
+ const code = await deps.runCheckLearningsBudget(targetPath);
46
+ if (code !== 0) {
47
+ process.exitCode = code;
48
+ }
49
+ });
50
+ }
31
51
  /**
32
52
  * Register CLI maintenance commands that do not run the root update warning.
33
53
  * @param program - Commander program to mutate
@@ -81,6 +101,7 @@ function addMaintenanceCommands(program, deps) {
81
101
  .action(async (targetPath, options) => {
82
102
  await deps.runUi(targetPath, options);
83
103
  });
104
+ addCheckLearningsBudgetCommand(program, deps);
84
105
  program
85
106
  .command("cross-pollinate")
86
107
  .description("Make locally-authored agent definitions available to the other agents this project supports")
@@ -116,7 +137,14 @@ export function createProgram(dependencies = {}) {
116
137
  // Run the npm update-check once per invocation, before the matched action.
117
138
  // It is non-fatal: a failed check never blocks the action from running.
118
139
  program.hook("preAction", async (_thisCommand, actionCommand) => {
119
- if (["doctor", "sync", "ui", "update", "version"].includes(actionCommand.name())) {
140
+ if ([
141
+ "doctor",
142
+ "sync",
143
+ "ui",
144
+ "update",
145
+ "version",
146
+ "check-learnings-budget",
147
+ ].includes(actionCommand.name())) {
120
148
  return;
121
149
  }
122
150
  if (program.opts().updateCheck === false) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /** A learnings file that satisfies every hard budget. */
2
+ export interface LearningsBudgetOk {
3
+ readonly kind: "ok";
4
+ readonly entryCount: number;
5
+ readonly maxEntries: number;
6
+ readonly measuredTokens: number;
7
+ readonly maxTokens: number;
8
+ }
9
+ /** No learnings file exists at the resolved path — an expected, silent case. */
10
+ export interface LearningsBudgetMissing {
11
+ readonly kind: "missing";
12
+ readonly detail: string;
13
+ }
14
+ /** The learnings file breached a budget or is otherwise unsafe or invalid. */
15
+ export interface LearningsBudgetViolation {
16
+ readonly kind: "violation";
17
+ readonly detail: string;
18
+ }
19
+ /** Structured outcome of one budget check. */
20
+ export type LearningsBudgetResult = LearningsBudgetOk | LearningsBudgetMissing | LearningsBudgetViolation;
21
+ /**
22
+ * Check one already-resolved absolute learnings path against the shared hard
23
+ * budgets. Callers resolve the path (from config or an explicit argument) and
24
+ * decide the exit policy from the returned discriminated union.
25
+ * @param file - Absolute learnings file path
26
+ * @returns Structured budget-check result
27
+ */
28
+ export declare function checkLearningsBudget(file: string): Promise<LearningsBudgetResult>;
29
+ /**
30
+ * Render a caught failure without allowing filesystem paths or control bytes
31
+ * embedded in an Error message to forge additional terminal/CI output.
32
+ * @param error - Unknown thrown failure
33
+ * @returns Stable, single-line diagnostic detail
34
+ */
35
+ export declare function formatErrorDetail(error: unknown): string;
36
+ /**
37
+ * Quote one path after applying terminal-safe JSON-style escaping.
38
+ * @param file - Path to render in diagnostics
39
+ * @returns Quoted, terminal-safe path
40
+ */
41
+ export declare function formatDiagnosticPath(file: string): string;
42
+ //# sourceMappingURL=learnings-budget-check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"learnings-budget-check.d.ts","sourceRoot":"","sources":["../../src/core/learnings-budget-check.ts"],"names":[],"mappings":"AA4BA,yDAAyD;AACzD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,gFAAgF;AAChF,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,8EAA8E;AAC9E,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,8CAA8C;AAC9C,MAAM,MAAM,qBAAqB,GAC7B,iBAAiB,GACjB,sBAAsB,GACtB,wBAAwB,CAAC;AAE7B;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,qBAAqB,CAAC,CAgChC;AA2CD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAYxD;AAoCD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEzD"}
@@ -0,0 +1,210 @@
1
+ /**
2
+ * Reusable core check for the canonical project-learnings document and its hard
3
+ * budgets.
4
+ *
5
+ * Extracted from the package-facing `scripts/check-learnings-budget.ts` so the
6
+ * identical bounded-read, token-budget, per-entry validation, and canonical
7
+ * format checks can be shared by every caller — the existing package script and
8
+ * the `lisa check-learnings-budget` CLI subcommand that ships the gate into host
9
+ * projects' CI. Every hardening property of the original script is preserved
10
+ * here: a bounded regular-file read, an `O_NONBLOCK` open with TOCTOU stat
11
+ * checks, and terminal-escape-safe diagnostic text. The function never throws
12
+ * for an expected condition — a missing file is a distinct result and every
13
+ * other failure is a `violation` carrying a single-line, terminal-safe detail —
14
+ * so each caller owns its own exit policy.
15
+ * @module learnings-budget-check
16
+ */
17
+ import { constants } from "node:fs";
18
+ import { open } from "node:fs/promises";
19
+ import { LEARNINGS_CONTRACT, estimateLearningTokens, } from "./learnings-contract.js";
20
+ import { parseLearningsFile, renderLearningsFile, } from "./learnings-document.js";
21
+ import { validateLearningEntry } from "./learnings-entry.js";
22
+ /**
23
+ * Check one already-resolved absolute learnings path against the shared hard
24
+ * budgets. Callers resolve the path (from config or an explicit argument) and
25
+ * decide the exit policy from the returned discriminated union.
26
+ * @param file - Absolute learnings file path
27
+ * @returns Structured budget-check result
28
+ */
29
+ export async function checkLearningsBudget(file) {
30
+ try {
31
+ const content = await readBoundedRegularFile(file, LEARNINGS_CONTRACT.maxTokens);
32
+ const measuredTokens = estimateLearningTokens(content);
33
+ if (measuredTokens > LEARNINGS_CONTRACT.maxTokens) {
34
+ throw new Error(`maxTokens exceeded: measured ${measuredTokens}, allowed ${LEARNINGS_CONTRACT.maxTokens}`);
35
+ }
36
+ const entries = parseLearningsFile(content);
37
+ for (const entry of entries) {
38
+ validateLearningEntry(entry);
39
+ }
40
+ if (renderLearningsFile(entries) !== content) {
41
+ throw new Error("non-canonical project learnings format");
42
+ }
43
+ return {
44
+ kind: "ok",
45
+ entryCount: entries.length,
46
+ maxEntries: LEARNINGS_CONTRACT.maxEntries,
47
+ measuredTokens,
48
+ maxTokens: LEARNINGS_CONTRACT.maxTokens,
49
+ };
50
+ }
51
+ catch (error) {
52
+ const detail = formatErrorDetail(error);
53
+ return isFileNotFound(error)
54
+ ? { kind: "missing", detail }
55
+ : { kind: "violation", detail: withRemediation(detail, file) };
56
+ }
57
+ }
58
+ /**
59
+ * Append a terse, actionable remediation clause to a file-level budget breach
60
+ * so an operator reading CI output learns the fix, not just the number. Only
61
+ * the whole-file budgets (token ceiling, entry count, canonical format) are
62
+ * augmented; per-entry validation failures already name the offending entry
63
+ * and are left verbatim, as are non-budget filesystem errors.
64
+ * @param detail - Terminal-safe diagnostic detail
65
+ * @param file - Absolute learnings file path
66
+ * @returns The detail, with a remediation clause when one applies
67
+ */
68
+ function withRemediation(detail, file) {
69
+ if (detail.startsWith("Invalid learning entry")) {
70
+ return detail;
71
+ }
72
+ const target = formatDiagnosticPath(file);
73
+ if (detail.includes("maxEntries")) {
74
+ return `${detail} — consolidate or remove entries in ${target} to fit the learnings budget`;
75
+ }
76
+ if (detail.includes("maxTokens")) {
77
+ return `${detail} — shorten or remove entries in ${target} to fit the learnings budget`;
78
+ }
79
+ if (detail.includes("canonical") || detail.includes("format")) {
80
+ return `${detail} — re-generate ${target} with the learnings writer to restore the canonical format`;
81
+ }
82
+ return detail;
83
+ }
84
+ /**
85
+ * Whether a caught failure is a "file does not exist" filesystem error, which
86
+ * callers treat as an expected, silent condition rather than a violation.
87
+ * @param error - Unknown thrown failure
88
+ * @returns True when the error reports an absent path
89
+ */
90
+ function isFileNotFound(error) {
91
+ return (error !== null &&
92
+ typeof error === "object" &&
93
+ readOwnString(error, "code") === "ENOENT");
94
+ }
95
+ /**
96
+ * Render a caught failure without allowing filesystem paths or control bytes
97
+ * embedded in an Error message to forge additional terminal/CI output.
98
+ * @param error - Unknown thrown failure
99
+ * @returns Stable, single-line diagnostic detail
100
+ */
101
+ export function formatErrorDetail(error) {
102
+ if (error !== null && typeof error === "object") {
103
+ const code = readOwnString(error, "code");
104
+ if (code !== undefined && /^[A-Z][A-Z0-9_]*$/u.test(code)) {
105
+ const syscall = readOwnString(error, "syscall");
106
+ return syscall === undefined
107
+ ? `filesystem error ${code}`
108
+ : `filesystem error ${code} during ${escapeDiagnosticText(syscall)}`;
109
+ }
110
+ }
111
+ const message = error instanceof Error ? error.message : String(error);
112
+ return escapeDiagnosticText(message);
113
+ }
114
+ /**
115
+ * Read one inert own string property without invoking an accessor.
116
+ * @param candidate - Object to inspect
117
+ * @param key - Property name to read
118
+ * @returns The own string value, or undefined
119
+ */
120
+ function readOwnString(candidate, key) {
121
+ const descriptor = Object.getOwnPropertyDescriptor(candidate, key);
122
+ return descriptor !== undefined &&
123
+ "value" in descriptor &&
124
+ typeof descriptor.value === "string"
125
+ ? descriptor.value
126
+ : undefined;
127
+ }
128
+ /**
129
+ * Escape terminal controls while retaining ordinary diagnostic wording.
130
+ * @param value - Raw diagnostic text
131
+ * @returns Terminal-safe, single-line text
132
+ */
133
+ function escapeDiagnosticText(value) {
134
+ const jsonBody = JSON.stringify(value).slice(1, -1);
135
+ return Array.from(jsonBody)
136
+ .map(character => {
137
+ const code = character.charCodeAt(0);
138
+ const isForbidden = (code >= 0x7f && code <= 0x9f) || code === 0x2028 || code === 0x2029;
139
+ return isForbidden
140
+ ? `\\u${code.toString(16).padStart(4, "0")}`
141
+ : character;
142
+ })
143
+ .join("");
144
+ }
145
+ /**
146
+ * Quote one path after applying terminal-safe JSON-style escaping.
147
+ * @param file - Path to render in diagnostics
148
+ * @returns Quoted, terminal-safe path
149
+ */
150
+ export function formatDiagnosticPath(file) {
151
+ return `"${escapeDiagnosticText(file)}"`;
152
+ }
153
+ /**
154
+ * Read at most one byte beyond the hard budget from one verified regular-file
155
+ * handle. Non-blocking open prevents a FIFO path from stalling the gate.
156
+ * @param file - Absolute candidate learnings path
157
+ * @param maximumBytes - Shared executable maxTokens byte ceiling
158
+ * @returns Strictly decoded UTF-8 content within the byte ceiling
159
+ */
160
+ async function readBoundedRegularFile(file, maximumBytes) {
161
+ const handle = await open(file, constants.O_RDONLY | constants.O_NONBLOCK);
162
+ try {
163
+ const before = await handle.stat({ bigint: true });
164
+ if (!before.isFile()) {
165
+ throw new Error("unsafe input: expected a regular file");
166
+ }
167
+ if (before.size > BigInt(maximumBytes)) {
168
+ throw new Error(`maxTokens exceeded: measured ${before.size}, allowed ${maximumBytes}`);
169
+ }
170
+ const buffer = Buffer.allocUnsafe(maximumBytes + 1);
171
+ const bytesRead = await fillBuffer(handle, buffer, 0);
172
+ if (bytesRead > maximumBytes) {
173
+ throw new Error(`maxTokens exceeded: measured at least ${bytesRead}, allowed ${maximumBytes}`);
174
+ }
175
+ const after = await handle.stat({ bigint: true });
176
+ if (after.dev !== before.dev ||
177
+ after.ino !== before.ino ||
178
+ after.size !== before.size ||
179
+ after.mtimeNs !== before.mtimeNs ||
180
+ after.ctimeNs !== before.ctimeNs) {
181
+ throw new Error("unsafe input: file changed during bounded read");
182
+ }
183
+ return new TextDecoder("utf-8", { fatal: true }).decode(buffer.subarray(0, bytesRead));
184
+ }
185
+ finally {
186
+ await handle.close();
187
+ }
188
+ }
189
+ /**
190
+ * Fill a fixed buffer from a handle via bounded recursion, returning the total
191
+ * bytes read. Recursion (rather than a mutable accumulator) keeps the module
192
+ * within the repository's immutability lint rules while preserving the
193
+ * original loop's "stop at EOF or buffer end" semantics; depth is bounded by
194
+ * the small fixed buffer, which a learnings file fills in one or two reads.
195
+ * @param handle - Verified regular-file handle
196
+ * @param buffer - Destination buffer sized to the byte ceiling plus one
197
+ * @param offset - Bytes already read into the buffer
198
+ * @returns Total bytes read into the buffer
199
+ */
200
+ async function fillBuffer(handle, buffer, offset) {
201
+ if (offset >= buffer.length) {
202
+ return offset;
203
+ }
204
+ const result = await handle.read(buffer, offset, buffer.length - offset, null);
205
+ if (result.bytesRead === 0) {
206
+ return offset;
207
+ }
208
+ return fillBuffer(handle, buffer, offset + result.bytesRead);
209
+ }
210
+ //# sourceMappingURL=learnings-budget-check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"learnings-budget-check.js","sourceRoot":"","sources":["../../src/core/learnings-budget-check.ts"],"names":[],"mappings":"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"}
@@ -66,7 +66,12 @@ function validateParsedLearningEntry(candidate, index) {
66
66
  }
67
67
  catch (error) {
68
68
  const id = readDiagnosticEntryId(candidate);
69
- const label = id === undefined ? `entry ${index + 1}` : `entry ${JSON.stringify(id)}`;
69
+ // Single-quote the id rather than JSON.stringify it: the message is later
70
+ // rendered through a JSON-body escaper for terminal safety, which would
71
+ // double-escape embedded double quotes into `\"id\"`. Single quotes read
72
+ // cleanly and are not re-escaped, while control-character neutralization
73
+ // still happens downstream.
74
+ const label = id === undefined ? `entry ${index + 1}` : `entry '${id}'`;
70
75
  const detail = error instanceof Error ? error.message : String(error);
71
76
  throw new Error(`Invalid learning ${label}: ${detail}`);
72
77
  }
@@ -1 +1 @@
1
- {"version":3,"file":"learnings-document.js","sourceRoot":"","sources":["../../src/core/learnings-document.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"learnings-document.js","sourceRoot":"","sources":["../../src/core/learnings-document.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -102,7 +102,7 @@
102
102
  "form-data": ">=4.0.6"
103
103
  },
104
104
  "name": "@codyswann/lisa",
105
- "version": "2.236.0",
105
+ "version": "2.237.0",
106
106
  "description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
107
107
  "main": "dist/index.js",
108
108
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "2.236.0",
3
+ "version": "2.237.0",
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",
3
- "version": "2.236.0",
3
+ "version": "2.237.0",
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",
3
- "version": "2.236.0",
3
+ "version": "2.237.0",
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": "2.236.0",
3
+ "version": "2.237.0",
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-cdk",
3
- "version": "2.236.0",
3
+ "version": "2.237.0",
4
4
  "description": "AWS CDK-specific Lisa plugin.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "2.236.0",
3
+ "version": "2.237.0",
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-cdk",
3
- "version": "2.236.0",
3
+ "version": "2.237.0",
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-cdk",
3
- "version": "2.236.0",
3
+ "version": "2.237.0",
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",
3
- "version": "2.236.0",
3
+ "version": "2.237.0",
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",
3
- "version": "2.236.0",
3
+ "version": "2.237.0",
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-expo",
3
- "version": "2.236.0",
3
+ "version": "2.237.0",
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-expo",
3
- "version": "2.236.0",
3
+ "version": "2.237.0",
4
4
  "description": "Expo and 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-expo",
3
- "version": "2.236.0",
3
+ "version": "2.237.0",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"