@codyswann/lisa 4.25.2 → 4.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/check-learnings-budget-cmd.d.ts +2 -0
- package/dist/cli/check-learnings-budget-cmd.d.ts.map +1 -1
- package/dist/cli/check-learnings-budget-cmd.js +17 -6
- package/dist/cli/check-learnings-budget-cmd.js.map +1 -1
- package/dist/cli/gate-commands.d.ts +3 -1
- package/dist/cli/gate-commands.d.ts.map +1 -1
- package/dist/cli/gate-commands.js +5 -2
- package/dist/cli/gate-commands.js.map +1 -1
- package/dist/core/configured-learnings-path.d.ts +16 -0
- package/dist/core/configured-learnings-path.d.ts.map +1 -0
- package/dist/core/configured-learnings-path.js +42 -0
- package/dist/core/configured-learnings-path.js.map +1 -0
- package/dist/core/learnings-budget-check.d.ts +13 -3
- package/dist/core/learnings-budget-check.d.ts.map +1 -1
- package/dist/core/learnings-budget-check.js +41 -10
- package/dist/core/learnings-budget-check.js.map +1 -1
- package/dist/core/learnings-overflow-path.d.ts +11 -0
- package/dist/core/learnings-overflow-path.d.ts.map +1 -0
- package/dist/core/learnings-overflow-path.js +19 -0
- package/dist/core/learnings-overflow-path.js.map +1 -0
- package/dist/core/learnings-overflow.d.ts +1 -11
- package/dist/core/learnings-overflow.d.ts.map +1 -1
- package/dist/core/learnings-overflow.js +2 -17
- package/dist/core/learnings-overflow.js.map +1 -1
- package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
- package/dist/core/project-config.d.ts.map +1 -1
- package/dist/core/project-config.js +4 -38
- package/dist/core/project-config.js.map +1 -1
- package/dist/core/safe-relative-markdown-path.d.ts +10 -0
- package/dist/core/safe-relative-markdown-path.d.ts.map +1 -0
- package/dist/core/safe-relative-markdown-path.js +42 -0
- package/dist/core/safe-relative-markdown-path.js.map +1 -0
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +5 -1
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/package.json +3 -3
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-agy/plugin.json +1 -1
- 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-cursor/.claude-plugin/plugin.json +1 -1
- 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/scripts/check-learnings-budget.ts +96 -22
|
@@ -32,6 +32,8 @@ import { existsSync, readFileSync } from "node:fs";
|
|
|
32
32
|
import * as path from "node:path";
|
|
33
33
|
import { pathToFileURL } from "node:url";
|
|
34
34
|
import type * as BudgetCheckModule from "../src/core/learnings-budget-check.js";
|
|
35
|
+
import type * as ConfiguredPathModule from "../src/core/configured-learnings-path.js";
|
|
36
|
+
import type * as OverflowPathModule from "../src/core/learnings-overflow-path.js";
|
|
35
37
|
|
|
36
38
|
type BudgetChecker = Pick<
|
|
37
39
|
typeof BudgetCheckModule,
|
|
@@ -48,9 +50,6 @@ const TEMPLATE_LEARNINGS_FILE = path.resolve(
|
|
|
48
50
|
"PROJECT_LEARNINGS.md"
|
|
49
51
|
);
|
|
50
52
|
|
|
51
|
-
/** Where the contract puts a project's ledger when nothing overrides it. */
|
|
52
|
-
const DEFAULT_LEDGER_RELATIVE = path.join(".lisa", "PROJECT_LEARNINGS.md");
|
|
53
|
-
|
|
54
53
|
/**
|
|
55
54
|
* This repository's own ledger, resolved the way the contract resolves it.
|
|
56
55
|
*
|
|
@@ -58,22 +57,26 @@ const DEFAULT_LEDGER_RELATIVE = path.join(".lisa", "PROJECT_LEARNINGS.md");
|
|
|
58
57
|
* documented default. Resolving it here rather than writing the path into a
|
|
59
58
|
* workflow is what stops the two drifting: an override would otherwise move the
|
|
60
59
|
* ledger and leave every caller checking a file that no longer exists.
|
|
61
|
-
* @returns
|
|
60
|
+
* @returns Project-relative path to the ledger, whether or not it exists
|
|
62
61
|
*/
|
|
63
|
-
function
|
|
62
|
+
async function resolveLedgerRelative(): Promise<string> {
|
|
64
63
|
const configPath = path.join(REPO_ROOT, ".lisa.config.json");
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
64
|
+
const resolver = await loadConfiguredLearningsResolver();
|
|
65
|
+
const parsed: unknown = existsSync(configPath)
|
|
66
|
+
? JSON.parse(readFileSync(configPath, "utf8"))
|
|
67
|
+
: {};
|
|
68
|
+
return resolver(parsed, configPath);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** Resolve this repository's configured ledger to an absolute path. */
|
|
72
|
+
async function resolveLedger(): Promise<string> {
|
|
73
|
+
return path.resolve(REPO_ROOT, await resolveLedgerRelative());
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** Resolve the configured ledger's sibling overflow through the shared rule. */
|
|
77
|
+
async function resolveOverflow(): Promise<string> {
|
|
78
|
+
const resolver = await loadOverflowResolver();
|
|
79
|
+
return path.resolve(REPO_ROOT, resolver(await resolveLedgerRelative()));
|
|
77
80
|
}
|
|
78
81
|
|
|
79
82
|
/**
|
|
@@ -96,14 +99,18 @@ function isSourceCheckout(): boolean {
|
|
|
96
99
|
async function main(): Promise<void> {
|
|
97
100
|
const arguments_ = process.argv.slice(2);
|
|
98
101
|
if (arguments_.length > 1) {
|
|
99
|
-
fail(
|
|
102
|
+
fail(
|
|
103
|
+
"Usage: bun run check:learnings-budget -- [PROJECT_LEARNINGS.md | --overflow]"
|
|
104
|
+
);
|
|
100
105
|
}
|
|
101
106
|
|
|
102
107
|
const checker = await loadBudgetChecker();
|
|
103
108
|
const inspected =
|
|
104
|
-
arguments_
|
|
105
|
-
? await
|
|
106
|
-
:
|
|
109
|
+
arguments_[0] === "--overflow"
|
|
110
|
+
? await checkOverflowSurface(checker, await resolveOverflow())
|
|
111
|
+
: arguments_.length === 1
|
|
112
|
+
? await checkExplicitSurface(checker, arguments_[0] as string)
|
|
113
|
+
: await checkDefaultSurfaces(checker);
|
|
107
114
|
|
|
108
115
|
// VACUITY GUARD. Every path above either judges a document or exits, so this
|
|
109
116
|
// should be unreachable — which is the point. A run that inspected nothing
|
|
@@ -119,6 +126,29 @@ async function main(): Promise<void> {
|
|
|
119
126
|
}
|
|
120
127
|
}
|
|
121
128
|
|
|
129
|
+
/** Check the optional overflow, whose absence is the expected empty state. */
|
|
130
|
+
async function checkOverflowSurface(
|
|
131
|
+
checker: BudgetChecker,
|
|
132
|
+
file: string
|
|
133
|
+
): Promise<number> {
|
|
134
|
+
const result = await checker.checkLearningsBudget(file, {
|
|
135
|
+
surface: "overflow",
|
|
136
|
+
});
|
|
137
|
+
if (result.kind === "missing") {
|
|
138
|
+
console.log(
|
|
139
|
+
`no learnings overflow file at ${checker.formatDiagnosticPath(file)} — nothing to check`
|
|
140
|
+
);
|
|
141
|
+
return 1;
|
|
142
|
+
}
|
|
143
|
+
if (result.kind === "violation") {
|
|
144
|
+
fail(`${checker.formatDiagnosticPath(file)}: ${result.detail}`);
|
|
145
|
+
}
|
|
146
|
+
console.log(
|
|
147
|
+
checker.formatBudgetVerdict(file, result, { surface: "overflow" })
|
|
148
|
+
);
|
|
149
|
+
return 1;
|
|
150
|
+
}
|
|
151
|
+
|
|
122
152
|
/**
|
|
123
153
|
* Check the one document named on the command line.
|
|
124
154
|
* @param checker - The loaded budget checker
|
|
@@ -141,7 +171,7 @@ async function checkExplicitSurface(
|
|
|
141
171
|
*/
|
|
142
172
|
async function checkDefaultSurfaces(checker: BudgetChecker): Promise<number> {
|
|
143
173
|
await check(checker, TEMPLATE_LEARNINGS_FILE);
|
|
144
|
-
const ledger = resolveLedger();
|
|
174
|
+
const ledger = await resolveLedger();
|
|
145
175
|
if (existsSync(ledger)) {
|
|
146
176
|
await check(checker, ledger);
|
|
147
177
|
return 2;
|
|
@@ -213,6 +243,50 @@ async function loadBudgetChecker(): Promise<BudgetChecker> {
|
|
|
213
243
|
} as BudgetChecker;
|
|
214
244
|
}
|
|
215
245
|
|
|
246
|
+
/** Load the pure overflow filename resolver from source or compiled package. */
|
|
247
|
+
async function loadOverflowResolver(): Promise<
|
|
248
|
+
typeof OverflowPathModule.resolveLearningsOverflowFile
|
|
249
|
+
> {
|
|
250
|
+
const packageRoot = path.resolve(import.meta.dir, "..");
|
|
251
|
+
const sourceTypescript = path.join(
|
|
252
|
+
packageRoot,
|
|
253
|
+
"src",
|
|
254
|
+
"core",
|
|
255
|
+
"learnings-overflow-path.ts"
|
|
256
|
+
);
|
|
257
|
+
const runtimeRoot = path.join(
|
|
258
|
+
packageRoot,
|
|
259
|
+
existsSync(sourceTypescript) ? "src" : "dist",
|
|
260
|
+
"core"
|
|
261
|
+
);
|
|
262
|
+
const module_ = (await import(
|
|
263
|
+
pathToFileURL(path.join(runtimeRoot, "learnings-overflow-path.js")).href
|
|
264
|
+
)) as typeof OverflowPathModule;
|
|
265
|
+
return module_.resolveLearningsOverflowFile;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/** Load the dependency-free configured learnings-path resolver. */
|
|
269
|
+
async function loadConfiguredLearningsResolver(): Promise<
|
|
270
|
+
typeof ConfiguredPathModule.resolveLearningsFileFromRawConfig
|
|
271
|
+
> {
|
|
272
|
+
const packageRoot = path.resolve(import.meta.dir, "..");
|
|
273
|
+
const sourceTypescript = path.join(
|
|
274
|
+
packageRoot,
|
|
275
|
+
"src",
|
|
276
|
+
"core",
|
|
277
|
+
"configured-learnings-path.ts"
|
|
278
|
+
);
|
|
279
|
+
const runtimeRoot = path.join(
|
|
280
|
+
packageRoot,
|
|
281
|
+
existsSync(sourceTypescript) ? "src" : "dist",
|
|
282
|
+
"core"
|
|
283
|
+
);
|
|
284
|
+
const module_ = (await import(
|
|
285
|
+
pathToFileURL(path.join(runtimeRoot, "configured-learnings-path.js")).href
|
|
286
|
+
)) as typeof ConfiguredPathModule;
|
|
287
|
+
return module_.resolveLearningsFileFromRawConfig;
|
|
288
|
+
}
|
|
289
|
+
|
|
216
290
|
/** Print one deterministic failure diagnostic and exit non-zero. */
|
|
217
291
|
function fail(message: string): never {
|
|
218
292
|
console.error(`check:learnings-budget: ${message}`);
|