@codyswann/lisa 2.217.8 → 2.218.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 (97) hide show
  1. package/dist/core/learnings-contract.d.ts +38 -0
  2. package/dist/core/learnings-contract.d.ts.map +1 -0
  3. package/dist/core/learnings-contract.js +36 -0
  4. package/dist/core/learnings-contract.js.map +1 -0
  5. package/dist/core/learnings-entry.d.ts +9 -0
  6. package/dist/core/learnings-entry.d.ts.map +1 -0
  7. package/dist/core/learnings-entry.js +233 -0
  8. package/dist/core/learnings-entry.js.map +1 -0
  9. package/dist/core/learnings-file-safety.d.ts +23 -0
  10. package/dist/core/learnings-file-safety.d.ts.map +1 -0
  11. package/dist/core/learnings-file-safety.js +84 -0
  12. package/dist/core/learnings-file-safety.js.map +1 -0
  13. package/dist/core/learnings-lock.d.ts +8 -0
  14. package/dist/core/learnings-lock.d.ts.map +1 -0
  15. package/dist/core/learnings-lock.js +227 -0
  16. package/dist/core/learnings-lock.js.map +1 -0
  17. package/dist/core/learnings-writer.d.ts +22 -0
  18. package/dist/core/learnings-writer.d.ts.map +1 -0
  19. package/dist/core/learnings-writer.js +128 -0
  20. package/dist/core/learnings-writer.js.map +1 -0
  21. package/dist/core/learnings.d.ts +4 -0
  22. package/dist/core/learnings.d.ts.map +1 -0
  23. package/dist/core/learnings.js +4 -0
  24. package/dist/core/learnings.js.map +1 -0
  25. package/dist/core/project-config.d.ts +19 -0
  26. package/dist/core/project-config.d.ts.map +1 -1
  27. package/dist/core/project-config.js +83 -14
  28. package/dist/core/project-config.js.map +1 -1
  29. package/dist/sync/registry.d.ts +0 -12
  30. package/dist/sync/registry.d.ts.map +1 -1
  31. package/dist/sync/registry.js +18 -0
  32. package/dist/sync/registry.js.map +1 -1
  33. package/package.json +2 -1
  34. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  35. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  36. package/plugins/lisa/.codex-plugin/skills/lisa-debrief-apply/SKILL.md +3 -3
  37. package/plugins/lisa/rules/eager/config-resolution.md +9 -0
  38. package/plugins/lisa/rules/reference/config-resolution.md +2 -0
  39. package/plugins/lisa/skills/lisa-debrief-apply/SKILL.md +3 -3
  40. package/plugins/lisa-agy/plugin.json +1 -1
  41. package/plugins/lisa-agy/skills/lisa-debrief-apply/SKILL.md +3 -3
  42. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  43. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  44. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  45. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  46. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  47. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  48. package/plugins/lisa-copilot/rules/eager/config-resolution.md +9 -0
  49. package/plugins/lisa-copilot/rules/reference/config-resolution.md +2 -0
  50. package/plugins/lisa-copilot/skills/lisa-debrief-apply/SKILL.md +3 -3
  51. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  52. package/plugins/lisa-cursor/rules/config-resolution-reference.mdc +2 -0
  53. package/plugins/lisa-cursor/rules/config-resolution.mdc +9 -0
  54. package/plugins/lisa-cursor/skills/lisa-debrief-apply/SKILL.md +3 -3
  55. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  56. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  57. package/plugins/lisa-expo-agy/plugin.json +1 -1
  58. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  59. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  60. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  61. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  62. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  63. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  64. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  65. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  66. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  67. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  68. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  69. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  70. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  71. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  72. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  73. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  74. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  75. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  76. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  77. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  78. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  79. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  80. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  81. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  82. package/plugins/lisa-rails-agy/plugin.json +1 -1
  83. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  84. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  85. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  86. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  87. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  88. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  89. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  90. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  91. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  92. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  93. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  94. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  95. package/plugins/src/base/rules/eager/config-resolution.md +9 -0
  96. package/plugins/src/base/rules/reference/config-resolution.md +2 -0
  97. package/plugins/src/base/skills/lisa-debrief-apply/SKILL.md +3 -3
@@ -0,0 +1,227 @@
1
+ /** Cross-process serialization for project learnings writes. */
2
+ import { link, lstat, readFile, unlink, writeFile } from "node:fs/promises";
3
+ const MAX_LOCK_ATTEMPTS = 200;
4
+ const LOCK_RETRY_DELAY_MS = 10;
5
+ const STALE_LOCK_MS = 30_000;
6
+ /**
7
+ * Serialize same-target writers across processes with an exclusive hard link.
8
+ * @param target - Absolute learnings target
9
+ * @param operation - Complete read, validate, and atomic-write transaction
10
+ * @returns Operation result
11
+ */
12
+ export async function withLearningTargetLock(target, operation) {
13
+ const lockPath = `${target}.lock`;
14
+ const owner = {
15
+ token: crypto.randomUUID(),
16
+ pid: process.pid,
17
+ createdAt: Date.now(),
18
+ };
19
+ const lease = await acquireLock(lockPath, owner, 0);
20
+ try {
21
+ return await operation();
22
+ }
23
+ finally {
24
+ await releaseLock(lockPath, lease);
25
+ }
26
+ }
27
+ /**
28
+ * Publish complete owner metadata atomically via a hard link.
29
+ * @param lockPath - Shared lock path
30
+ * @param owner - Unique owner metadata
31
+ * @param attempt - Current retry count
32
+ * @returns Acquired lock lease
33
+ */
34
+ async function acquireLock(lockPath, owner, attempt) {
35
+ const ownerPath = `${lockPath}.${owner.token}.owner`;
36
+ await writeFile(ownerPath, JSON.stringify(owner), {
37
+ encoding: "utf8",
38
+ flag: "wx",
39
+ });
40
+ const acquired = await publishOwnerLink(ownerPath, lockPath);
41
+ if (acquired) {
42
+ return { owner, ownerPath };
43
+ }
44
+ await removeFileIfPresent(ownerPath);
45
+ if (attempt >= MAX_LOCK_ATTEMPTS) {
46
+ throw new Error(`Timed out waiting for learnings lock: ${lockPath}`);
47
+ }
48
+ await reclaimStaleLock(lockPath);
49
+ await delay(LOCK_RETRY_DELAY_MS);
50
+ return acquireLock(lockPath, owner, attempt + 1);
51
+ }
52
+ /**
53
+ * Try to hard-link fully written owner metadata into the lock path.
54
+ * @param ownerPath - Fully written owner metadata file
55
+ * @param lockPath - Destination lock path
56
+ * @returns Whether publication acquired the lock
57
+ */
58
+ async function publishOwnerLink(ownerPath, lockPath) {
59
+ try {
60
+ await link(ownerPath, lockPath);
61
+ return true;
62
+ }
63
+ catch (error) {
64
+ if (error.code === "EEXIST" ||
65
+ error.code === "ENOENT") {
66
+ return false;
67
+ }
68
+ throw error;
69
+ }
70
+ }
71
+ /**
72
+ * Remove only the lock inode still linked to this lease's owner file.
73
+ * @param lockPath - Shared lock path
74
+ * @param lease - Owner lease retaining the same inode
75
+ */
76
+ async function releaseLock(lockPath, lease) {
77
+ try {
78
+ if (await sameFile(lockPath, lease.ownerPath)) {
79
+ await unlink(lockPath);
80
+ }
81
+ }
82
+ finally {
83
+ await removeFileIfPresent(lease.ownerPath);
84
+ }
85
+ }
86
+ /**
87
+ * Reclaim an expired lock only when its declared process is no longer live.
88
+ * @param lockPath - Shared lock path
89
+ */
90
+ async function reclaimStaleLock(lockPath) {
91
+ const before = await statFile(lockPath);
92
+ if (before === undefined || !before.isFile()) {
93
+ return;
94
+ }
95
+ const owner = await readLockOwner(lockPath);
96
+ const timestamp = owner?.createdAt ?? Number(before.mtimeMs);
97
+ if (Date.now() - timestamp <= STALE_LOCK_MS ||
98
+ (owner !== undefined && isProcessLive(owner.pid))) {
99
+ return;
100
+ }
101
+ const retainedOwnerPath = owner === undefined ? undefined : `${lockPath}.${owner.token}.owner`;
102
+ const quarantine = retainedOwnerPath !== undefined &&
103
+ (await sameFile(lockPath, retainedOwnerPath))
104
+ ? retainedOwnerPath
105
+ : `${lockPath}.${crypto.randomUUID()}.stale`;
106
+ const linked = quarantine === retainedOwnerPath
107
+ ? true
108
+ : await publishOwnerLink(lockPath, quarantine);
109
+ if (!linked) {
110
+ return;
111
+ }
112
+ try {
113
+ if (await sameFile(lockPath, quarantine)) {
114
+ await removeFileIfPresent(lockPath);
115
+ }
116
+ }
117
+ finally {
118
+ await removeFileIfPresent(quarantine);
119
+ }
120
+ }
121
+ /**
122
+ * Read bounded owner metadata; partial or special lock files are unowned.
123
+ * @param lockPath - Shared lock path
124
+ * @returns Parsed owner or undefined
125
+ */
126
+ async function readLockOwner(lockPath) {
127
+ const metadata = await statFile(lockPath);
128
+ if (metadata === undefined || !metadata.isFile() || metadata.size > 512) {
129
+ return undefined;
130
+ }
131
+ try {
132
+ const parsed = JSON.parse(await readFile(lockPath, "utf8"));
133
+ return isLockOwner(parsed) ? parsed : undefined;
134
+ }
135
+ catch {
136
+ return undefined;
137
+ }
138
+ }
139
+ /**
140
+ * Compare two regular-file paths by device and inode.
141
+ * @param left - First file path
142
+ * @param right - Second file path
143
+ * @returns Whether both paths retain the same regular-file inode
144
+ */
145
+ async function sameFile(left, right) {
146
+ const [leftStat, rightStat] = await Promise.all([
147
+ statFile(left),
148
+ statFile(right),
149
+ ]);
150
+ return (leftStat !== undefined &&
151
+ rightStat !== undefined &&
152
+ leftStat.isFile() &&
153
+ rightStat.isFile() &&
154
+ leftStat.dev === rightStat.dev &&
155
+ leftStat.ino === rightStat.ino);
156
+ }
157
+ /**
158
+ * Read file metadata without treating an absent path as an error.
159
+ * @param filePath - Filesystem path
160
+ * @returns File metadata or undefined
161
+ */
162
+ async function statFile(filePath) {
163
+ try {
164
+ return await lstat(filePath);
165
+ }
166
+ catch (error) {
167
+ if (error.code === "ENOENT") {
168
+ return undefined;
169
+ }
170
+ throw error;
171
+ }
172
+ }
173
+ /**
174
+ * Remove one path without recursive deletion.
175
+ * @param filePath - Regular file or hard-link path
176
+ */
177
+ async function removeFileIfPresent(filePath) {
178
+ try {
179
+ await unlink(filePath);
180
+ }
181
+ catch (error) {
182
+ if (error.code !== "ENOENT") {
183
+ throw error;
184
+ }
185
+ }
186
+ }
187
+ /**
188
+ * Narrow parsed lock metadata to the exact ownership shape.
189
+ * @param value - Parsed metadata
190
+ * @returns Whether the metadata is a lock owner
191
+ */
192
+ function isLockOwner(value) {
193
+ if (value === null || typeof value !== "object") {
194
+ return false;
195
+ }
196
+ const owner = value;
197
+ return (typeof owner.token === "string" &&
198
+ typeof owner.pid === "number" &&
199
+ Number.isSafeInteger(owner.pid) &&
200
+ owner.pid > 0 &&
201
+ typeof owner.createdAt === "number" &&
202
+ Number.isSafeInteger(owner.createdAt));
203
+ }
204
+ /**
205
+ * Treat permission-denied PID probes as live and missing PIDs as dead.
206
+ * @param pid - Declared owner process id
207
+ * @returns Whether the process may still be alive
208
+ */
209
+ function isProcessLive(pid) {
210
+ try {
211
+ process.kill(pid, 0);
212
+ return true;
213
+ }
214
+ catch (error) {
215
+ return error.code !== "ESRCH";
216
+ }
217
+ }
218
+ /**
219
+ * Await a short retry delay without blocking the event loop.
220
+ * @param milliseconds - Delay duration
221
+ */
222
+ async function delay(milliseconds) {
223
+ await new Promise(resolve => {
224
+ setTimeout(resolve, milliseconds);
225
+ });
226
+ }
227
+ //# sourceMappingURL=learnings-lock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"learnings-lock.js","sourceRoot":"","sources":["../../src/core/learnings-lock.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { type LearningEntry } from "./learnings-contract.js";
2
+ /**
3
+ * Persist one already-selected learning without generating or truncating it.
4
+ * @param projectRoot - Absolute path to the host project root
5
+ * @param candidate - Untrusted seven-field learning entry
6
+ * @returns Absolute path to the persisted learnings file
7
+ */
8
+ export declare function persistLearningEntry(projectRoot: string, candidate: unknown): Promise<string>;
9
+ /**
10
+ * Render the complete file in one stable, machine-readable Markdown form.
11
+ * @param entries - Validated entries to serialize
12
+ * @returns Canonical Markdown plus JSONL document
13
+ */
14
+ export declare function renderLearningsFile(entries: readonly LearningEntry[]): string;
15
+ /**
16
+ * Parse and revalidate an existing file before it participates in a write.
17
+ * @param content - Existing learnings document
18
+ * @returns Revalidated entries from the document
19
+ */
20
+ export declare function parseLearningsFile(content: string): LearningEntry[];
21
+ export { validateLearningEntry } from "./learnings-entry.js";
22
+ //# sourceMappingURL=learnings-writer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"learnings-writer.d.ts","sourceRoot":"","sources":["../../src/core/learnings-writer.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,KAAK,aAAa,EACnB,MAAM,yBAAyB,CAAC;AAqBjC;;;;;GAKG;AACH,wBAAsB,oBAAoB,CACxC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,OAAO,GACjB,OAAO,CAAC,MAAM,CAAC,CA6BjB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,SAAS,aAAa,EAAE,GAAG,MAAM,CAG7E;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,EAAE,CAsBnE;AAED,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,128 @@
1
+ /** Deterministic persistence for project-local learnings. */
2
+ import * as fse from "fs-extra";
3
+ import { rename, writeFile } from "node:fs/promises";
4
+ import * as path from "node:path";
5
+ import { LEARNINGS_CONTRACT, estimateLearningTokens, } from "./learnings-contract.js";
6
+ import { validateLearningEntry } from "./learnings-entry.js";
7
+ import { assertSafeLearningParents, readExistingLearnings, resolveSafeLearningTarget, } from "./learnings-file-safety.js";
8
+ import { withLearningTargetLock } from "./learnings-lock.js";
9
+ import { readProjectConfig, resolveProjectLearningsFile, } from "./project-config.js";
10
+ const FILE_HEADER = `# Project Learnings
11
+
12
+ <!-- lisa-learnings-contract:v${LEARNINGS_CONTRACT.version} -->
13
+
14
+ `;
15
+ const JSON_FENCE_START = "```jsonl\n";
16
+ const JSON_FENCE_END = "\n```\n";
17
+ /**
18
+ * Persist one already-selected learning without generating or truncating it.
19
+ * @param projectRoot - Absolute path to the host project root
20
+ * @param candidate - Untrusted seven-field learning entry
21
+ * @returns Absolute path to the persisted learnings file
22
+ */
23
+ export async function persistLearningEntry(projectRoot, candidate) {
24
+ const entry = validateLearningEntry(candidate);
25
+ const initialDocument = buildNextDocument([], entry);
26
+ const config = await readProjectConfig(projectRoot);
27
+ const relativeFile = resolveProjectLearningsFile(config);
28
+ const { root, target } = resolveSafeLearningTarget(projectRoot, relativeFile);
29
+ await assertSafeLearningParents(root, path.dirname(target));
30
+ await fse.ensureDir(path.dirname(target));
31
+ return withLearningTargetLock(target, async () => {
32
+ await assertSafeLearningParents(root, path.dirname(target));
33
+ const existing = await readExistingLearnings(target);
34
+ const entries = existing === undefined ? [] : parseLearningsFile(existing);
35
+ const rendered = existing === undefined
36
+ ? initialDocument
37
+ : buildNextDocument(entries, entry);
38
+ const temporary = path.join(path.dirname(target), `.${path.basename(target)}.${process.pid}.${crypto.randomUUID()}.tmp`);
39
+ try {
40
+ await writeFile(temporary, rendered, { encoding: "utf8", flag: "wx" });
41
+ await assertSafeLearningParents(root, path.dirname(target));
42
+ await rename(temporary, target);
43
+ }
44
+ finally {
45
+ await fse.remove(temporary);
46
+ }
47
+ return target;
48
+ });
49
+ }
50
+ /**
51
+ * Render the complete file in one stable, machine-readable Markdown form.
52
+ * @param entries - Validated entries to serialize
53
+ * @returns Canonical Markdown plus JSONL document
54
+ */
55
+ export function renderLearningsFile(entries) {
56
+ const lines = entries.map(entry => JSON.stringify(entry)).join("\n");
57
+ return `${FILE_HEADER}${JSON_FENCE_START}${lines}${JSON_FENCE_END}`;
58
+ }
59
+ /**
60
+ * Parse and revalidate an existing file before it participates in a write.
61
+ * @param content - Existing learnings document
62
+ * @returns Revalidated entries from the document
63
+ */
64
+ export function parseLearningsFile(content) {
65
+ if (estimateLearningTokens(content) > LEARNINGS_CONTRACT.maxTokens) {
66
+ throw new Error(`Project learnings payload exceeds maxTokens ${LEARNINGS_CONTRACT.maxTokens}`);
67
+ }
68
+ if (!content.startsWith(`${FILE_HEADER}${JSON_FENCE_START}`) ||
69
+ !content.endsWith(JSON_FENCE_END)) {
70
+ throw new Error("Invalid project learnings file format");
71
+ }
72
+ const jsonStart = FILE_HEADER.length + JSON_FENCE_START.length;
73
+ const jsonEnd = content.length - JSON_FENCE_END.length;
74
+ const entries = parseJsonLines(content.slice(jsonStart, jsonEnd)).map(validateLearningEntry);
75
+ if (new Set(entries.map(entry => entry.id)).size !== entries.length) {
76
+ throw new Error("Invalid project learnings payload: duplicate ids");
77
+ }
78
+ assertDocumentBudget(content, entries.length, "Project learnings payload");
79
+ return entries;
80
+ }
81
+ export { validateLearningEntry } from "./learnings-entry.js";
82
+ /**
83
+ * Build and budget-check the next canonical document.
84
+ * @param entries - Existing validated entries
85
+ * @param entry - New validated entry
86
+ * @returns Next canonical document
87
+ */
88
+ function buildNextDocument(entries, entry) {
89
+ if (entries.some(current => current.id === entry.id)) {
90
+ throw new Error(`Duplicate learning id: ${entry.id}`);
91
+ }
92
+ const nextEntries = [...entries, entry].sort((left, right) => left.id.localeCompare(right.id));
93
+ const rendered = renderLearningsFile(nextEntries);
94
+ assertDocumentBudget(rendered, nextEntries.length, "Learnings file");
95
+ return rendered;
96
+ }
97
+ /**
98
+ * Enforce the shared entry-count and model-agnostic token upper bounds.
99
+ * @param content - Canonical document
100
+ * @param entryCount - Number of entries in the document
101
+ * @param context - Error-message prefix
102
+ */
103
+ function assertDocumentBudget(content, entryCount, context) {
104
+ if (entryCount > LEARNINGS_CONTRACT.maxEntries) {
105
+ throw new Error(`${context} exceeds maxEntries ${LEARNINGS_CONTRACT.maxEntries}`);
106
+ }
107
+ const estimatedTokens = estimateLearningTokens(content);
108
+ if (estimatedTokens > LEARNINGS_CONTRACT.maxTokens) {
109
+ throw new Error(`${context} exceeds maxTokens ${LEARNINGS_CONTRACT.maxTokens} (measured ${estimatedTokens})`);
110
+ }
111
+ }
112
+ /**
113
+ * Parse the strict JSONL payload with a stable, user-facing error.
114
+ * @param payload - JSONL payload
115
+ * @returns Parsed unknown entry values
116
+ */
117
+ function parseJsonLines(payload) {
118
+ if (payload === "") {
119
+ return [];
120
+ }
121
+ try {
122
+ return payload.split("\n").map(line => JSON.parse(line));
123
+ }
124
+ catch {
125
+ throw new Error("Invalid project learnings JSONL payload");
126
+ }
127
+ }
128
+ //# sourceMappingURL=learnings-writer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"learnings-writer.js","sourceRoot":"","sources":["../../src/core/learnings-writer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export * from "./learnings-contract.js";
2
+ export * from "./learnings-writer.js";
3
+ export { DEFAULT_PROJECT_RULES_FILE, PROJECT_LEARNINGS_FILENAME, resolveProjectLearningsFile, resolveProjectRulesFile, type ProjectConfig, } from "./project-config.js";
4
+ //# sourceMappingURL=learnings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"learnings.d.ts","sourceRoot":"","sources":["../../src/core/learnings.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,OAAO,EACL,0BAA0B,EAC1B,0BAA0B,EAC1B,2BAA2B,EAC3B,uBAAuB,EACvB,KAAK,aAAa,GACnB,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from "./learnings-contract.js";
2
+ export * from "./learnings-writer.js";
3
+ export { DEFAULT_PROJECT_RULES_FILE, PROJECT_LEARNINGS_FILENAME, resolveProjectLearningsFile, resolveProjectRulesFile, } from "./project-config.js";
4
+ //# sourceMappingURL=learnings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"learnings.js","sourceRoot":"","sources":["../../src/core/learnings.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,OAAO,EACL,0BAA0B,EAC1B,0BAA0B,EAC1B,2BAA2B,EAC3B,uBAAuB,GAExB,MAAM,qBAAqB,CAAC"}
@@ -1,6 +1,10 @@
1
1
  import { type Harness } from "./config.js";
2
2
  /** Filename of the per-project config, relative to the destination root */
3
3
  export declare const PROJECT_CONFIG_FILENAME = ".lisa.config.json";
4
+ /** Default durable project-rules destination used by governance skills. */
5
+ export declare const DEFAULT_PROJECT_RULES_FILE = ".claude/rules/PROJECT_RULES.md";
6
+ /** Fixed sibling filename for machine-managed project learnings. */
7
+ export declare const PROJECT_LEARNINGS_FILENAME = "PROJECT_LEARNINGS.md";
4
8
  /**
5
9
  * Schema of `.lisa.config.json`. Additional fields may be added in future
6
10
  * versions; unknown fields are preserved on round-trip.
@@ -8,7 +12,22 @@ export declare const PROJECT_CONFIG_FILENAME = ".lisa.config.json";
8
12
  export interface ProjectConfig {
9
13
  /** Target harness(es) for emitted artifacts */
10
14
  readonly harness?: Harness;
15
+ /** Relative path to the project's durable rules file. */
16
+ readonly projectRulesFile?: string;
11
17
  }
18
+ /**
19
+ * Resolve the validated project-rules path from config or its default.
20
+ * @param config - Parsed project configuration
21
+ * @returns Safe project-relative Markdown path
22
+ */
23
+ export declare function resolveProjectRulesFile(config: ProjectConfig): string;
24
+ /**
25
+ * Keep learned rules separate from hand-authored rules while honoring the same
26
+ * configured directory.
27
+ * @param config - Parsed project configuration
28
+ * @returns Safe project-relative learnings Markdown path
29
+ */
30
+ export declare function resolveProjectLearningsFile(config: ProjectConfig): string;
12
31
  /**
13
32
  * Read `.lisa.config.json` from a destination project, returning {} if absent.
14
33
  *
@@ -1 +1 @@
1
- {"version":3,"file":"project-config.d.ts","sourceRoot":"","sources":["../../src/core/project-config.ts"],"names":[],"mappings":"AAYA,OAAO,EAML,KAAK,OAAO,EACb,MAAM,aAAa,CAAC;AAErB,2EAA2E;AAC3E,eAAO,MAAM,uBAAuB,sBAAsB,CAAC;AAE3D;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,+CAA+C;IAC/C,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,aAAa,CAAC,CAQxB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,IAAI,CAAC,CAKf;AAED;;;;;;;;;GASG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAE3E;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE;IACjD,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,OAAO,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,eAAe,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9C,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;CACnC,GAAG,OAAO,CAQV;AA6BD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,OAAO,GAAG,SAAS,EAC9B,aAAa,EAAE,aAAa,GAC3B,OAAO,CAQT;AA2CD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,OAAO,CAK1D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAGnE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,4BAA4B,CAChD,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,CAAC,CAYtE"}
1
+ {"version":3,"file":"project-config.d.ts","sourceRoot":"","sources":["../../src/core/project-config.ts"],"names":[],"mappings":"AAYA,OAAO,EAML,KAAK,OAAO,EACb,MAAM,aAAa,CAAC;AAErB,2EAA2E;AAC3E,eAAO,MAAM,uBAAuB,sBAAsB,CAAC;AAE3D,2EAA2E;AAC3E,eAAO,MAAM,0BAA0B,mCAAmC,CAAC;AAE3E,oEAAoE;AACpE,eAAO,MAAM,0BAA0B,yBAAyB,CAAC;AAEjE;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,+CAA+C;IAC/C,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,yDAAyD;IACzD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CACpC;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAKrE;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAKzE;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,aAAa,CAAC,CAQxB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,IAAI,CAAC,CAKf;AAED;;;;;;;;;GASG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAE3E;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE;IACjD,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,OAAO,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,eAAe,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9C,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;CACnC,GAAG,OAAO,CAQV;AA6BD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,OAAO,GAAG,SAAS,EAC9B,aAAa,EAAE,aAAa,GAC3B,OAAO,CAQT;AA8GD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,OAAO,CAK1D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAGnE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,4BAA4B,CAChD,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,CAAC,CAYtE"}
@@ -13,6 +13,27 @@ import * as path from "node:path";
13
13
  import { ACCEPTED_HARNESS_INPUTS, DEFAULT_HARNESS, HARNESS_ALIASES, HARNESS_VALUES, LEGACY_HARNESS_ALIASES, } from "./config.js";
14
14
  /** Filename of the per-project config, relative to the destination root */
15
15
  export const PROJECT_CONFIG_FILENAME = ".lisa.config.json";
16
+ /** Default durable project-rules destination used by governance skills. */
17
+ export const DEFAULT_PROJECT_RULES_FILE = ".claude/rules/PROJECT_RULES.md";
18
+ /** Fixed sibling filename for machine-managed project learnings. */
19
+ export const PROJECT_LEARNINGS_FILENAME = "PROJECT_LEARNINGS.md";
20
+ /**
21
+ * Resolve the validated project-rules path from config or its default.
22
+ * @param config - Parsed project configuration
23
+ * @returns Safe project-relative Markdown path
24
+ */
25
+ export function resolveProjectRulesFile(config) {
26
+ return validateProjectRulesFile(config.projectRulesFile ?? DEFAULT_PROJECT_RULES_FILE, PROJECT_CONFIG_FILENAME);
27
+ }
28
+ /**
29
+ * Keep learned rules separate from hand-authored rules while honoring the same
30
+ * configured directory.
31
+ * @param config - Parsed project configuration
32
+ * @returns Safe project-relative learnings Markdown path
33
+ */
34
+ export function resolveProjectLearningsFile(config) {
35
+ return path.posix.join(path.posix.dirname(resolveProjectRulesFile(config)), PROJECT_LEARNINGS_FILENAME);
36
+ }
16
37
  /**
17
38
  * Read `.lisa.config.json` from a destination project, returning {} if absent.
18
39
  *
@@ -129,29 +150,77 @@ export function resolveHarness(flagValue, projectConfig) {
129
150
  * @returns A typed ProjectConfig with only the keys we recognize
130
151
  */
131
152
  function validateProjectConfig(parsed, configPath) {
132
- if (parsed === null || typeof parsed !== "object") {
153
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
133
154
  throw new Error(`Invalid ${PROJECT_CONFIG_FILENAME} at ${configPath}: expected JSON object`);
134
155
  }
135
156
  const obj = parsed;
136
- if (obj.harness === undefined) {
137
- return {};
157
+ const harness = validateOptionalHarness(obj.harness, configPath);
158
+ const projectRulesFile = obj.projectRulesFile === undefined
159
+ ? undefined
160
+ : validateProjectRulesFile(obj.projectRulesFile, configPath);
161
+ return {
162
+ ...(harness === undefined ? {} : { harness }),
163
+ ...(projectRulesFile === undefined ? {} : { projectRulesFile }),
164
+ };
165
+ }
166
+ /**
167
+ * Validate the optional harness while preserving an absent value.
168
+ * @param value - Raw harness value
169
+ * @param configPath - Config source for errors
170
+ * @returns Normalized harness or undefined
171
+ */
172
+ function validateOptionalHarness(value, configPath) {
173
+ if (value === undefined) {
174
+ return undefined;
138
175
  }
139
176
  // A persisted, retired legacy value (e.g. "both") is migrated to its
140
177
  // canonical form rather than rejected — apply rewrites the file (see
141
178
  // detectLegacyHarnessMigration). This keeps pre-fleet projects applying
142
179
  // instead of hard-failing every run on a value newer Lisa versions removed.
143
- const legacy = typeof obj.harness === "string"
144
- ? LEGACY_HARNESS_ALIASES[obj.harness]
145
- : undefined;
146
- const normalized = legacy ??
147
- (typeof obj.harness === "string"
148
- ? normalizeHarness(obj.harness)
149
- : undefined);
150
- if (normalized === undefined) {
151
- const allowed = ACCEPTED_HARNESS_INPUTS.join(" | ");
152
- throw new Error(`Invalid harness in ${configPath}: expected ${allowed}, got ${JSON.stringify(obj.harness)}`);
180
+ const legacy = typeof value === "string" ? LEGACY_HARNESS_ALIASES[value] : undefined;
181
+ const normalized = legacy ?? (typeof value === "string" ? normalizeHarness(value) : undefined);
182
+ if (normalized !== undefined) {
183
+ return normalized;
184
+ }
185
+ const allowed = ACCEPTED_HARNESS_INPUTS.join(" | ");
186
+ throw new Error(`Invalid harness in ${configPath}: expected ${allowed}, got ${JSON.stringify(value)}`);
187
+ }
188
+ /**
189
+ * Validate the configurable rules destination as a safe Markdown path.
190
+ * @param value - Raw configured path
191
+ * @param source - Config source for errors
192
+ * @returns Validated project-relative path
193
+ */
194
+ function validateProjectRulesFile(value, source) {
195
+ if (typeof value !== "string" ||
196
+ value.length === 0 ||
197
+ value.trim() !== value ||
198
+ value.includes("\\") ||
199
+ containsControlCharacter(value) ||
200
+ /^[a-z]:/iu.test(value) ||
201
+ path.posix.isAbsolute(value) ||
202
+ path.win32.isAbsolute(value)) {
203
+ throw new Error(`Invalid projectRulesFile in ${source}: expected a safe relative POSIX path`);
153
204
  }
154
- return { harness: normalized };
205
+ const segments = value.split("/");
206
+ if (segments.some(segment => segment === "" || segment === "." || segment === "..")) {
207
+ throw new Error(`Invalid projectRulesFile in ${source}: path traversal is not allowed`);
208
+ }
209
+ if (path.posix.extname(value).toLowerCase() !== ".md") {
210
+ throw new Error(`Invalid projectRulesFile in ${source}: expected a Markdown file`);
211
+ }
212
+ return value;
213
+ }
214
+ /**
215
+ * Whether a path contains an ASCII control character.
216
+ * @param value - Configured path
217
+ * @returns True when any control character is present
218
+ */
219
+ function containsControlCharacter(value) {
220
+ return Array.from(value).some(character => {
221
+ const code = character.charCodeAt(0);
222
+ return code <= 31 || code === 127;
223
+ });
155
224
  }
156
225
  /**
157
226
  * Narrow an unknown value to the Harness type
@@ -1 +1 @@
1
- {"version":3,"file":"project-config.js","sourceRoot":"","sources":["../../src/core/project-config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"project-config.js","sourceRoot":"","sources":["../../src/core/project-config.ts"],"names":[],"mappings":"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"}
@@ -1,15 +1,3 @@
1
- /**
2
- * Registry of synced settings: the single map between `.lisa.config.json`
3
- * keys, their built-in defaults, and the project artifact files that mirror
4
- * them (test thresholds, lint budgets, mutation gates).
5
- *
6
- * The registry drives `lisa sync`: every entry is populated into the config
7
- * when missing (absorbing an existing artifact value first, falling back to
8
- * the built-in default), and afterwards the config value is written back into
9
- * each artifact file — config is the source of truth unless a value is
10
- * completely missing.
11
- * @module sync/registry
12
- */
13
1
  import type { JsonValue } from "./json-path.js";
14
2
  import type { LegacyAliasMapping } from "./legacy-aliases.js";
15
3
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/sync/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE9D;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,8CAA8C;IAC9C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,2EAA2E;AAC3E,MAAM,WAAW,aAAa;IAC5B,yDAAyD;IACzD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,yEAAyE;IACzE,QAAQ,CAAC,YAAY,EAAE,SAAS,CAAC;IACjC;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACvD,uEAAuE;IACvE,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IAChD;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,sDAAsD;IACtD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,8DAA8D;AAC9D,MAAM,WAAW,WAAW;IAC1B,uCAAuC;IACvC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,oEAAoE;IACpE,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,4CAA4C;IAC5C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAoCD;;;;;GAKG;AACH,eAAO,MAAM,aAAa,EAAE,SAAS,aAAa,EAuIjD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,aAAa,EAAE,SAAS,WAAW,EA0C/C,CAAC"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/sync/registry.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE9D;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,8CAA8C;IAC9C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,2EAA2E;AAC3E,MAAM,WAAW,aAAa;IAC5B,yDAAyD;IACzD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,yEAAyE;IACzE,QAAQ,CAAC,YAAY,EAAE,SAAS,CAAC;IACjC;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACvD,uEAAuE;IACvE,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IAChD;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,sDAAsD;IACtD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,8DAA8D;AAC9D,MAAM,WAAW,WAAW;IAC1B,uCAAuC;IACvC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,oEAAoE;IACpE,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,4CAA4C;IAC5C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAoCD;;;;;GAKG;AACH,eAAO,MAAM,aAAa,EAAE,SAAS,aAAa,EA4IjD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,aAAa,EAAE,SAAS,WAAW,EA0C/C,CAAC"}