@codyswann/lisa 2.297.5 → 2.298.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/all/copy-contents/.gitattributes +9 -0
- package/dist/cli/gate-commands.d.ts +22 -3
- package/dist/cli/gate-commands.d.ts.map +1 -1
- package/dist/cli/gate-commands.js +49 -1
- package/dist/cli/gate-commands.js.map +1 -1
- package/dist/cli/install-merge-driver-cmd.d.ts +21 -0
- package/dist/cli/install-merge-driver-cmd.d.ts.map +1 -0
- package/dist/cli/install-merge-driver-cmd.js +37 -0
- package/dist/cli/install-merge-driver-cmd.js.map +1 -0
- package/dist/cli/merge-learnings-cmd.d.ts +24 -0
- package/dist/cli/merge-learnings-cmd.d.ts.map +1 -0
- package/dist/cli/merge-learnings-cmd.js +82 -0
- package/dist/cli/merge-learnings-cmd.js.map +1 -0
- package/dist/core/learnings-budget-check.d.ts.map +1 -1
- package/dist/core/learnings-budget-check.js +18 -3
- package/dist/core/learnings-budget-check.js.map +1 -1
- package/dist/core/learnings-document.d.ts +46 -0
- package/dist/core/learnings-document.d.ts.map +1 -1
- package/dist/core/learnings-document.js +82 -4
- package/dist/core/learnings-document.js.map +1 -1
- package/dist/core/learnings-file-safety.d.ts.map +1 -1
- package/dist/core/learnings-file-safety.js +22 -0
- package/dist/core/learnings-file-safety.js.map +1 -1
- package/dist/core/learnings-merge-driver-config.d.ts +7 -0
- package/dist/core/learnings-merge-driver-config.d.ts.map +1 -0
- package/dist/core/learnings-merge-driver-config.js +58 -0
- package/dist/core/learnings-merge-driver-config.js.map +1 -0
- package/dist/core/learnings-merge-driver-install.d.ts +45 -0
- package/dist/core/learnings-merge-driver-install.d.ts.map +1 -0
- package/dist/core/learnings-merge-driver-install.js +161 -0
- package/dist/core/learnings-merge-driver-install.js.map +1 -0
- package/dist/core/learnings-merge-driver.d.ts +83 -0
- package/dist/core/learnings-merge-driver.d.ts.map +1 -0
- package/dist/core/learnings-merge-driver.js +100 -0
- package/dist/core/learnings-merge-driver.js.map +1 -0
- package/dist/core/learnings-merge.d.ts +23 -0
- package/dist/core/learnings-merge.d.ts.map +1 -0
- package/dist/core/learnings-merge.js +198 -0
- package/dist/core/learnings-merge.js.map +1 -0
- package/dist/core/learnings-writer.d.ts +6 -0
- package/dist/core/learnings-writer.d.ts.map +1 -1
- package/dist/core/learnings-writer.js +32 -89
- package/dist/core/learnings-writer.js.map +1 -1
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +28 -4
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/dist/health/storage.d.ts.map +1 -1
- package/dist/health/storage.js +7 -20
- package/dist/health/storage.js.map +1 -1
- package/dist/migrations/ensure-learnings-gitattributes.d.ts +43 -0
- package/dist/migrations/ensure-learnings-gitattributes.d.ts.map +1 -0
- package/dist/migrations/ensure-learnings-gitattributes.js +93 -0
- package/dist/migrations/ensure-learnings-gitattributes.js.map +1 -0
- package/dist/migrations/ensure-learnings-merge-driver.d.ts +46 -0
- package/dist/migrations/ensure-learnings-merge-driver.d.ts.map +1 -0
- package/dist/migrations/ensure-learnings-merge-driver.js +70 -0
- package/dist/migrations/ensure-learnings-merge-driver.js.map +1 -0
- package/dist/migrations/index.d.ts +2 -0
- package/dist/migrations/index.d.ts.map +1 -1
- package/dist/migrations/index.js +6 -0
- package/dist/migrations/index.js.map +1 -1
- package/dist/standards/storage.d.ts.map +1 -1
- package/dist/standards/storage.js +7 -20
- package/dist/standards/storage.js.map +1 -1
- package/dist/utils/atomic-file-write.d.ts +30 -0
- package/dist/utils/atomic-file-write.d.ts.map +1 -0
- package/dist/utils/atomic-file-write.js +61 -0
- package/dist/utils/atomic-file-write.js.map +1 -0
- package/dist/utils/directory-sync.d.ts.map +1 -0
- package/dist/utils/directory-sync.js.map +1 -0
- package/package.json +1 -1
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-drive-pr-to-merge/SKILL.md +12 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-persist-learning/SKILL.md +1 -0
- package/plugins/lisa/skills/lisa-drive-pr-to-merge/SKILL.md +12 -0
- package/plugins/lisa/skills/lisa-persist-learning/SKILL.md +1 -0
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/skills/lisa-drive-pr-to-merge/SKILL.md +12 -0
- package/plugins/lisa-agy/skills/lisa-persist-learning/SKILL.md +1 -0
- 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-copilot/skills/lisa-drive-pr-to-merge/SKILL.md +12 -0
- package/plugins/lisa-copilot/skills/lisa-persist-learning/SKILL.md +1 -0
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/skills/lisa-drive-pr-to-merge/SKILL.md +12 -0
- package/plugins/lisa-cursor/skills/lisa-persist-learning/SKILL.md +1 -0
- 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/plugins/src/base/skills/lisa-drive-pr-to-merge/SKILL.md +12 -0
- package/plugins/src/base/skills/lisa-persist-learning/SKILL.md +1 -0
- package/dist/health/directory-sync.d.ts.map +0 -1
- package/dist/health/directory-sync.js.map +0 -1
- /package/dist/{health → utils}/directory-sync.d.ts +0 -0
- /package/dist/{health → utils}/directory-sync.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/health/storage.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/health/storage.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,YAAY,EAAwB,MAAM,eAAe,CAAC;AAExE,eAAO,MAAM,kBAAkB,6BAA6B,CAAC;AAC7D,eAAO,MAAM,uBAAuB,QAAa,CAAC;AAElD,oEAAoE;AACpE,MAAM,MAAM,gBAAgB,GACxB;IACE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,GACD;IAAE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;CAAE,GAChC;IAAE,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/D,+CAA+C;AAC/C,MAAM,MAAM,iBAAiB,GACzB;IACE,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;CAC/B,GACD;IACE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;CAC/B,CAAC;AAEN;;;;GAIG;AACH,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,gBAAgB,CAAC,CAkB3B;AAED;;;;;;GAMG;AACH,wBAAsB,uBAAuB,CAC3C,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,OAAO,GACjB,OAAO,CAAC,iBAAiB,CAAC,CA+B5B;AAeD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM,CAEhE"}
|
package/dist/health/storage.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/** Confined, bounded, atomic storage for the latest completed Health v1 run. */
|
|
2
2
|
import * as fse from "fs-extra";
|
|
3
|
-
import { lstat, open, realpath
|
|
3
|
+
import { lstat, open, realpath } from "node:fs/promises";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { withFileTargetLock } from "../core/learnings-lock.js";
|
|
6
|
+
import { writeFileAtomically } from "../utils/atomic-file-write.js";
|
|
6
7
|
import { validateHealthResult } from "./contract.js";
|
|
7
|
-
import { syncContainingDirectory } from "./directory-sync.js";
|
|
8
8
|
export const HEALTH_RESULT_PATH = ".lisa/health/latest.json";
|
|
9
9
|
export const MAX_HEALTH_RESULT_BYTES = 256 * 1024;
|
|
10
10
|
/**
|
|
@@ -43,7 +43,7 @@ export async function readLatestHealthResult(projectRoot) {
|
|
|
43
43
|
export async function writeLatestHealthResult(projectRoot, candidate) {
|
|
44
44
|
const result = validateHealthResult(candidate);
|
|
45
45
|
const serialized = serializeValidatedHealthResult(result);
|
|
46
|
-
const {
|
|
46
|
+
const { target } = await resolveWriteTarget(projectRoot);
|
|
47
47
|
return withFileTargetLock(target, async () => {
|
|
48
48
|
await assertSafeTarget(target);
|
|
49
49
|
const current = await readLatestHealthResult(projectRoot);
|
|
@@ -62,23 +62,10 @@ export async function writeLatestHealthResult(projectRoot, candidate) {
|
|
|
62
62
|
return unchanged(target, current.result);
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
await handle.writeFile(serialized, "utf8");
|
|
70
|
-
await handle.sync();
|
|
71
|
-
}
|
|
72
|
-
finally {
|
|
73
|
-
await handle.close();
|
|
74
|
-
}
|
|
75
|
-
await assertSafeTarget(target);
|
|
76
|
-
await rename(temporary, target);
|
|
77
|
-
await syncContainingDirectory(directory);
|
|
78
|
-
}
|
|
79
|
-
finally {
|
|
80
|
-
await rm(temporary, { force: true });
|
|
81
|
-
}
|
|
65
|
+
await writeFileAtomically(target, serialized, {
|
|
66
|
+
mode: 0o600,
|
|
67
|
+
beforeRename: () => assertSafeTarget(target),
|
|
68
|
+
});
|
|
82
69
|
return Object.freeze({ status: "written", path: target, result });
|
|
83
70
|
});
|
|
84
71
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/health/storage.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/health/storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { Migration, MigrationContext, MigrationResult } from "./migration.interface.js";
|
|
2
|
+
/**
|
|
3
|
+
* Migration: bind the project's ACTUAL learnings ledger to the union merge
|
|
4
|
+
* driver in `.gitattributes`.
|
|
5
|
+
*
|
|
6
|
+
* The copy-contents template ships the default `.lisa/PROJECT_LEARNINGS.md`
|
|
7
|
+
* path, which is correct for most projects but silently wrong for any project
|
|
8
|
+
* that relocates its ledger via the validated `learnings.file` override in
|
|
9
|
+
* `.lisa.config.json`. A `.gitattributes` pointing at a path the project does
|
|
10
|
+
* not use leaves the ledger on git's default text merge — the exact corruption
|
|
11
|
+
* this campaign exists to remove — with nothing to indicate it.
|
|
12
|
+
*
|
|
13
|
+
* Running after the copy strategies, this resolves the ledger path through the
|
|
14
|
+
* executable config resolver (never hardcoded) and rewrites the Lisa-managed
|
|
15
|
+
* block. It uses the same guardrail-marker merge the template does, so every
|
|
16
|
+
* host-authored attribute (LFS, linguist, eol) outside the block is preserved,
|
|
17
|
+
* and it converges to the same content as the template whenever the project
|
|
18
|
+
* uses the default path.
|
|
19
|
+
*/
|
|
20
|
+
export declare class EnsureLearningsGitattributesMigration implements Migration {
|
|
21
|
+
readonly name = "ensure-learnings-gitattributes";
|
|
22
|
+
readonly description = "Bind the project's configured learnings ledger path to the union merge driver in .gitattributes";
|
|
23
|
+
/**
|
|
24
|
+
* Applies whenever the managed block does not already match the resolved
|
|
25
|
+
* ledger path.
|
|
26
|
+
* @param ctx - Migration context
|
|
27
|
+
* @returns True when there is work to do
|
|
28
|
+
*/
|
|
29
|
+
applies(ctx: MigrationContext): Promise<boolean>;
|
|
30
|
+
/**
|
|
31
|
+
* Rewrite the Lisa-managed `.gitattributes` block for the resolved ledger.
|
|
32
|
+
* @param ctx - Migration context
|
|
33
|
+
* @returns Result describing the action taken
|
|
34
|
+
*/
|
|
35
|
+
apply(ctx: MigrationContext): Promise<MigrationResult>;
|
|
36
|
+
/**
|
|
37
|
+
* Compute the current and intended `.gitattributes` contents.
|
|
38
|
+
* @param ctx - Migration context
|
|
39
|
+
* @returns Existing content and the content this migration would write
|
|
40
|
+
*/
|
|
41
|
+
private resolveContent;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=ensure-learnings-gitattributes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ensure-learnings-gitattributes.d.ts","sourceRoot":"","sources":["../../src/migrations/ensure-learnings-gitattributes.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,SAAS,EACT,gBAAgB,EAChB,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAIlC;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,qCAAsC,YAAW,SAAS;IACrE,QAAQ,CAAC,IAAI,oCAAoC;IACjD,QAAQ,CAAC,WAAW,qGACgF;IAEpG;;;;;OAKG;IACG,OAAO,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;IAKtD;;;;OAIG;IACG,KAAK,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;IAyB5D;;;;OAIG;YACW,cAAc;CAsB7B"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import * as fse from "fs-extra";
|
|
2
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import { isLearningsMergeDriverEnabled } from "../core/learnings-merge-driver-config.js";
|
|
5
|
+
import { renderLearningsGitattributesBlock } from "../core/learnings-merge-driver.js";
|
|
6
|
+
import { readProjectConfig, resolveProjectLearningsFile, } from "../core/project-config.js";
|
|
7
|
+
import { mergeCopyContents } from "../strategies/copy-contents.js";
|
|
8
|
+
const GITATTRIBUTES = ".gitattributes";
|
|
9
|
+
/**
|
|
10
|
+
* Migration: bind the project's ACTUAL learnings ledger to the union merge
|
|
11
|
+
* driver in `.gitattributes`.
|
|
12
|
+
*
|
|
13
|
+
* The copy-contents template ships the default `.lisa/PROJECT_LEARNINGS.md`
|
|
14
|
+
* path, which is correct for most projects but silently wrong for any project
|
|
15
|
+
* that relocates its ledger via the validated `learnings.file` override in
|
|
16
|
+
* `.lisa.config.json`. A `.gitattributes` pointing at a path the project does
|
|
17
|
+
* not use leaves the ledger on git's default text merge — the exact corruption
|
|
18
|
+
* this campaign exists to remove — with nothing to indicate it.
|
|
19
|
+
*
|
|
20
|
+
* Running after the copy strategies, this resolves the ledger path through the
|
|
21
|
+
* executable config resolver (never hardcoded) and rewrites the Lisa-managed
|
|
22
|
+
* block. It uses the same guardrail-marker merge the template does, so every
|
|
23
|
+
* host-authored attribute (LFS, linguist, eol) outside the block is preserved,
|
|
24
|
+
* and it converges to the same content as the template whenever the project
|
|
25
|
+
* uses the default path.
|
|
26
|
+
*/
|
|
27
|
+
export class EnsureLearningsGitattributesMigration {
|
|
28
|
+
name = "ensure-learnings-gitattributes";
|
|
29
|
+
description = "Bind the project's configured learnings ledger path to the union merge driver in .gitattributes";
|
|
30
|
+
/**
|
|
31
|
+
* Applies whenever the managed block does not already match the resolved
|
|
32
|
+
* ledger path.
|
|
33
|
+
* @param ctx - Migration context
|
|
34
|
+
* @returns True when there is work to do
|
|
35
|
+
*/
|
|
36
|
+
async applies(ctx) {
|
|
37
|
+
const { current, next } = await this.resolveContent(ctx);
|
|
38
|
+
return current !== next;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Rewrite the Lisa-managed `.gitattributes` block for the resolved ledger.
|
|
42
|
+
* @param ctx - Migration context
|
|
43
|
+
* @returns Result describing the action taken
|
|
44
|
+
*/
|
|
45
|
+
async apply(ctx) {
|
|
46
|
+
const { current, next } = await this.resolveContent(ctx);
|
|
47
|
+
if (current === next) {
|
|
48
|
+
return { name: this.name, action: "noop" };
|
|
49
|
+
}
|
|
50
|
+
const message = `Bound the learnings ledger to the union merge driver in ${GITATTRIBUTES}`;
|
|
51
|
+
if (ctx.dryRun) {
|
|
52
|
+
ctx.logger.dry(`Would update ${GITATTRIBUTES} for the learnings ledger`);
|
|
53
|
+
return {
|
|
54
|
+
name: this.name,
|
|
55
|
+
action: "applied",
|
|
56
|
+
changedFiles: [GITATTRIBUTES],
|
|
57
|
+
message,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
await writeFile(path.join(ctx.projectDir, GITATTRIBUTES), next, "utf8");
|
|
61
|
+
ctx.logger.success(message);
|
|
62
|
+
return {
|
|
63
|
+
name: this.name,
|
|
64
|
+
action: "applied",
|
|
65
|
+
changedFiles: [GITATTRIBUTES],
|
|
66
|
+
message,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Compute the current and intended `.gitattributes` contents.
|
|
71
|
+
* @param ctx - Migration context
|
|
72
|
+
* @returns Existing content and the content this migration would write
|
|
73
|
+
*/
|
|
74
|
+
async resolveContent(ctx) {
|
|
75
|
+
const target = path.join(ctx.projectDir, GITATTRIBUTES);
|
|
76
|
+
const current = (await fse.pathExists(target))
|
|
77
|
+
? await readFile(target, "utf8")
|
|
78
|
+
: "";
|
|
79
|
+
// Honour the same opt-out as the driver registration: shipping an
|
|
80
|
+
// attribute that binds the ledger to a driver the host declined would be
|
|
81
|
+
// inert at best and confusing at worst.
|
|
82
|
+
if (!(await isLearningsMergeDriverEnabled(ctx.projectDir))) {
|
|
83
|
+
return { current, next: current };
|
|
84
|
+
}
|
|
85
|
+
const config = await readProjectConfig(ctx.projectDir);
|
|
86
|
+
const block = renderLearningsGitattributesBlock(resolveProjectLearningsFile(config));
|
|
87
|
+
return {
|
|
88
|
+
current,
|
|
89
|
+
next: current === "" ? block : mergeCopyContents(block, current),
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=ensure-learnings-gitattributes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ensure-learnings-gitattributes.js","sourceRoot":"","sources":["../../src/migrations/ensure-learnings-gitattributes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { Migration, MigrationContext, MigrationResult } from "./migration.interface.js";
|
|
2
|
+
/**
|
|
3
|
+
* Migration: register the project-learnings union merge driver locally.
|
|
4
|
+
*
|
|
5
|
+
* Every learner pass runs on its own `learning/<fingerprint>` branch in its own
|
|
6
|
+
* worktree, so concurrent passes produce concurrent pull requests that each
|
|
7
|
+
* rewrite the same JSONL block. Git's default line merge turns that into
|
|
8
|
+
* conflict markers inside the ledger, and a merge that "succeeds" by taking one
|
|
9
|
+
* side silently discards the other branch's consolidation
|
|
10
|
+
* (CodySwannGT/lisa#1995).
|
|
11
|
+
*
|
|
12
|
+
* The `.gitattributes` half of the fix is committed and ships through the
|
|
13
|
+
* template pipeline, but git refuses to read a merge-driver COMMAND from a
|
|
14
|
+
* repository — a committed command would execute arbitrary code on `git merge`
|
|
15
|
+
* in any clone. The command is therefore machine-local, and this migration is
|
|
16
|
+
* what writes it, on every `lisa apply`, for host projects and Lisa's own
|
|
17
|
+
* repository alike.
|
|
18
|
+
*
|
|
19
|
+
* Degrading safely is the design point: without registration git falls back to
|
|
20
|
+
* its built-in text merge, which is exactly today's behavior. Nothing regresses
|
|
21
|
+
* in an unregistered checkout — it simply loses the union.
|
|
22
|
+
*
|
|
23
|
+
* Because `lisa apply` runs from `postinstall`, this registration happens on an
|
|
24
|
+
* ordinary `npm install` with no separate operator step. That is convenient but
|
|
25
|
+
* it does persist an executable hook in `.git/config` that fires on ordinary
|
|
26
|
+
* git operations, outside npm's lifecycle — so hosts can decline it by setting
|
|
27
|
+
* `learnings.mergeDriver: false` in `.lisa.config.json`.
|
|
28
|
+
*/
|
|
29
|
+
export declare class EnsureLearningsMergeDriverMigration implements Migration {
|
|
30
|
+
readonly name = "ensure-learnings-merge-driver";
|
|
31
|
+
readonly description = "Register the lisa-learnings git merge driver so concurrent learning branches union by entry id instead of conflicting";
|
|
32
|
+
/**
|
|
33
|
+
* Applies inside any git working tree. Registration itself is idempotent, so
|
|
34
|
+
* this only has to exclude directories where git config cannot exist.
|
|
35
|
+
* @param ctx - Migration context
|
|
36
|
+
* @returns True when there is work to do
|
|
37
|
+
*/
|
|
38
|
+
applies(ctx: MigrationContext): Promise<boolean>;
|
|
39
|
+
/**
|
|
40
|
+
* Register the merge driver in the project's local git config.
|
|
41
|
+
* @param ctx - Migration context
|
|
42
|
+
* @returns Result describing the action taken
|
|
43
|
+
*/
|
|
44
|
+
apply(ctx: MigrationContext): Promise<MigrationResult>;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=ensure-learnings-merge-driver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ensure-learnings-merge-driver.d.ts","sourceRoot":"","sources":["../../src/migrations/ensure-learnings-merge-driver.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,SAAS,EACT,gBAAgB,EAChB,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAElC;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,mCAAoC,YAAW,SAAS;IACnE,QAAQ,CAAC,IAAI,mCAAmC;IAChD,QAAQ,CAAC,WAAW,2HAA2I;IAE/J;;;;;OAKG;IACG,OAAO,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;IAOtD;;;;OAIG;IACG,KAAK,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;CAoB7D"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { canInstallLearningsMergeDriver, installLearningsMergeDriver, } from "../core/learnings-merge-driver-install.js";
|
|
2
|
+
import { LEARNINGS_MERGE_DRIVER_NAME } from "../core/learnings-merge-driver.js";
|
|
3
|
+
import { isLearningsMergeDriverEnabled } from "../core/learnings-merge-driver-config.js";
|
|
4
|
+
/**
|
|
5
|
+
* Migration: register the project-learnings union merge driver locally.
|
|
6
|
+
*
|
|
7
|
+
* Every learner pass runs on its own `learning/<fingerprint>` branch in its own
|
|
8
|
+
* worktree, so concurrent passes produce concurrent pull requests that each
|
|
9
|
+
* rewrite the same JSONL block. Git's default line merge turns that into
|
|
10
|
+
* conflict markers inside the ledger, and a merge that "succeeds" by taking one
|
|
11
|
+
* side silently discards the other branch's consolidation
|
|
12
|
+
* (CodySwannGT/lisa#1995).
|
|
13
|
+
*
|
|
14
|
+
* The `.gitattributes` half of the fix is committed and ships through the
|
|
15
|
+
* template pipeline, but git refuses to read a merge-driver COMMAND from a
|
|
16
|
+
* repository — a committed command would execute arbitrary code on `git merge`
|
|
17
|
+
* in any clone. The command is therefore machine-local, and this migration is
|
|
18
|
+
* what writes it, on every `lisa apply`, for host projects and Lisa's own
|
|
19
|
+
* repository alike.
|
|
20
|
+
*
|
|
21
|
+
* Degrading safely is the design point: without registration git falls back to
|
|
22
|
+
* its built-in text merge, which is exactly today's behavior. Nothing regresses
|
|
23
|
+
* in an unregistered checkout — it simply loses the union.
|
|
24
|
+
*
|
|
25
|
+
* Because `lisa apply` runs from `postinstall`, this registration happens on an
|
|
26
|
+
* ordinary `npm install` with no separate operator step. That is convenient but
|
|
27
|
+
* it does persist an executable hook in `.git/config` that fires on ordinary
|
|
28
|
+
* git operations, outside npm's lifecycle — so hosts can decline it by setting
|
|
29
|
+
* `learnings.mergeDriver: false` in `.lisa.config.json`.
|
|
30
|
+
*/
|
|
31
|
+
export class EnsureLearningsMergeDriverMigration {
|
|
32
|
+
name = "ensure-learnings-merge-driver";
|
|
33
|
+
description = `Register the ${LEARNINGS_MERGE_DRIVER_NAME} git merge driver so concurrent learning branches union by entry id instead of conflicting`;
|
|
34
|
+
/**
|
|
35
|
+
* Applies inside any git working tree. Registration itself is idempotent, so
|
|
36
|
+
* this only has to exclude directories where git config cannot exist.
|
|
37
|
+
* @param ctx - Migration context
|
|
38
|
+
* @returns True when there is work to do
|
|
39
|
+
*/
|
|
40
|
+
async applies(ctx) {
|
|
41
|
+
if (!(await isLearningsMergeDriverEnabled(ctx.projectDir))) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
return canInstallLearningsMergeDriver(ctx.projectDir);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Register the merge driver in the project's local git config.
|
|
48
|
+
* @param ctx - Migration context
|
|
49
|
+
* @returns Result describing the action taken
|
|
50
|
+
*/
|
|
51
|
+
async apply(ctx) {
|
|
52
|
+
if (!(await isLearningsMergeDriverEnabled(ctx.projectDir))) {
|
|
53
|
+
return { name: this.name, action: "noop" };
|
|
54
|
+
}
|
|
55
|
+
if (!(await canInstallLearningsMergeDriver(ctx.projectDir))) {
|
|
56
|
+
return { name: this.name, action: "noop" };
|
|
57
|
+
}
|
|
58
|
+
if (ctx.dryRun) {
|
|
59
|
+
ctx.logger.dry(`Would register the ${LEARNINGS_MERGE_DRIVER_NAME} git merge driver`);
|
|
60
|
+
return { name: this.name, action: "applied" };
|
|
61
|
+
}
|
|
62
|
+
const result = await installLearningsMergeDriver(ctx.projectDir);
|
|
63
|
+
if (result.kind !== "installed") {
|
|
64
|
+
return { name: this.name, action: "noop" };
|
|
65
|
+
}
|
|
66
|
+
ctx.logger.success(result.detail);
|
|
67
|
+
return { name: this.name, action: "applied", message: result.detail };
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=ensure-learnings-merge-driver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ensure-learnings-merge-driver.js","sourceRoot":"","sources":["../../src/migrations/ensure-learnings-merge-driver.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,8BAA8B,EAC9B,2BAA2B,GAC5B,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,2BAA2B,EAAE,MAAM,mCAAmC,CAAC;AAChF,OAAO,EAAE,6BAA6B,EAAE,MAAM,0CAA0C,CAAC;AAOzF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,OAAO,mCAAmC;IACrC,IAAI,GAAG,+BAA+B,CAAC;IACvC,WAAW,GAAG,gBAAgB,2BAA2B,4FAA4F,CAAC;IAE/J;;;;;OAKG;IACH,KAAK,CAAC,OAAO,CAAC,GAAqB;QACjC,IAAI,CAAC,CAAC,MAAM,6BAA6B,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;YAC3D,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,8BAA8B,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACxD,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,KAAK,CAAC,GAAqB;QAC/B,IAAI,CAAC,CAAC,MAAM,6BAA6B,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;YAC3D,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAC7C,CAAC;QACD,IAAI,CAAC,CAAC,MAAM,8BAA8B,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;YAC5D,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAC7C,CAAC;QACD,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YACf,GAAG,CAAC,MAAM,CAAC,GAAG,CACZ,sBAAsB,2BAA2B,mBAAmB,CACrE,CAAC;YACF,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;QAChD,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,2BAA2B,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACjE,IAAI,MAAM,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAChC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAC7C,CAAC;QACD,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAClC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;IACxE,CAAC;CACF"}
|
|
@@ -2,6 +2,8 @@ import type { Migration, MigrationContext, MigrationResult } from "./migration.i
|
|
|
2
2
|
export type { Migration, MigrationAction, MigrationContext, MigrationResult, } from "./migration.interface.js";
|
|
3
3
|
export { EnsureAuditIgnoreLocalExclusionsMigration } from "./ensure-audit-ignore-local-exclusions.js";
|
|
4
4
|
export { EnsureJestRnMockAccessibilityManagerMigration } from "./ensure-jest-rn-mock-accessibility-manager.js";
|
|
5
|
+
export { EnsureLearningsGitattributesMigration } from "./ensure-learnings-gitattributes.js";
|
|
6
|
+
export { EnsureLearningsMergeDriverMigration } from "./ensure-learnings-merge-driver.js";
|
|
5
7
|
export { EnsureLisaPostinstallMigration } from "./ensure-lisa-postinstall.js";
|
|
6
8
|
export { EnsureSonarExcludesLisaHarnessMigration } from "./ensure-sonar-excludes-lisa-harness.js";
|
|
7
9
|
export { EnsureTsconfigLocalFilesFallbackMigration } from "./ensure-tsconfig-local-files-fallback.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EACV,SAAS,EACT,gBAAgB,EAChB,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAElC,YAAY,EACV,SAAS,EACT,eAAe,EACf,gBAAgB,EAChB,eAAe,GAChB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,yCAAyC,EAAE,MAAM,2CAA2C,CAAC;AACtG,OAAO,EAAE,6CAA6C,EAAE,MAAM,gDAAgD,CAAC;AAC/G,OAAO,EAAE,qCAAqC,EAAE,MAAM,qCAAqC,CAAC;AAC5F,OAAO,EAAE,mCAAmC,EAAE,MAAM,oCAAoC,CAAC;AACzF,OAAO,EAAE,8BAA8B,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,EAAE,uCAAuC,EAAE,MAAM,yCAAyC,CAAC;AAClG,OAAO,EAAE,yCAAyC,EAAE,MAAM,2CAA2C,CAAC;AACtG,OAAO,EAAE,iCAAiC,EAAE,MAAM,kCAAkC,CAAC;AACrF,OAAO,EAAE,oCAAoC,EAAE,MAAM,qCAAqC,CAAC;AAC3F,OAAO,EAAE,oCAAoC,EAAE,MAAM,qCAAqC,CAAC;AAC3F,OAAO,EAAE,gCAAgC,EAAE,MAAM,gCAAgC,CAAC;AAElF;;GAEG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAuB;IAElD;;;OAGG;gBACS,UAAU,CAAC,EAAE,SAAS,SAAS,EAAE;IAgB7C;;;OAGG;IACH,MAAM,IAAI,SAAS,SAAS,EAAE;IAI9B;;;;OAIG;IACG,mBAAmB,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ/D;;;;OAIG;IACG,MAAM,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,SAAS,eAAe,EAAE,CAAC;CAazE;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,IAAI,iBAAiB,CAE3D"}
|
package/dist/migrations/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { EnsureAuditIgnoreLocalExclusionsMigration } from "./ensure-audit-ignore-local-exclusions.js";
|
|
2
2
|
import { EnsureJestRnMockAccessibilityManagerMigration } from "./ensure-jest-rn-mock-accessibility-manager.js";
|
|
3
|
+
import { EnsureLearningsGitattributesMigration } from "./ensure-learnings-gitattributes.js";
|
|
4
|
+
import { EnsureLearningsMergeDriverMigration } from "./ensure-learnings-merge-driver.js";
|
|
3
5
|
import { EnsureLisaPostinstallMigration } from "./ensure-lisa-postinstall.js";
|
|
4
6
|
import { EnsureSonarExcludesLisaHarnessMigration } from "./ensure-sonar-excludes-lisa-harness.js";
|
|
5
7
|
import { EnsureTsconfigLocalFilesFallbackMigration } from "./ensure-tsconfig-local-files-fallback.js";
|
|
@@ -9,6 +11,8 @@ import { ReconcileClaudeStackPluginsMigration } from "./reconcile-claude-stack-p
|
|
|
9
11
|
import { UntrackCodexMarketplaceMigration } from "./untrack-codex-marketplace.js";
|
|
10
12
|
export { EnsureAuditIgnoreLocalExclusionsMigration } from "./ensure-audit-ignore-local-exclusions.js";
|
|
11
13
|
export { EnsureJestRnMockAccessibilityManagerMigration } from "./ensure-jest-rn-mock-accessibility-manager.js";
|
|
14
|
+
export { EnsureLearningsGitattributesMigration } from "./ensure-learnings-gitattributes.js";
|
|
15
|
+
export { EnsureLearningsMergeDriverMigration } from "./ensure-learnings-merge-driver.js";
|
|
12
16
|
export { EnsureLisaPostinstallMigration } from "./ensure-lisa-postinstall.js";
|
|
13
17
|
export { EnsureSonarExcludesLisaHarnessMigration } from "./ensure-sonar-excludes-lisa-harness.js";
|
|
14
18
|
export { EnsureTsconfigLocalFilesFallbackMigration } from "./ensure-tsconfig-local-files-fallback.js";
|
|
@@ -31,6 +35,8 @@ export class MigrationRegistry {
|
|
|
31
35
|
new EnsureTsconfigLocalFilesFallbackMigration(),
|
|
32
36
|
new EnsureAuditIgnoreLocalExclusionsMigration(),
|
|
33
37
|
new EnsureJestRnMockAccessibilityManagerMigration(),
|
|
38
|
+
new EnsureLearningsGitattributesMigration(),
|
|
39
|
+
new EnsureLearningsMergeDriverMigration(),
|
|
34
40
|
new EnsureLisaPostinstallMigration(),
|
|
35
41
|
new EnsureSonarExcludesLisaHarnessMigration(),
|
|
36
42
|
new EnsureWikiSourceDeclaredMigration(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yCAAyC,EAAE,MAAM,2CAA2C,CAAC;AACtG,OAAO,EAAE,6CAA6C,EAAE,MAAM,gDAAgD,CAAC;AAC/G,OAAO,EAAE,8BAA8B,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,EAAE,uCAAuC,EAAE,MAAM,yCAAyC,CAAC;AAClG,OAAO,EAAE,yCAAyC,EAAE,MAAM,2CAA2C,CAAC;AACtG,OAAO,EAAE,iCAAiC,EAAE,MAAM,kCAAkC,CAAC;AACrF,OAAO,EAAE,oCAAoC,EAAE,MAAM,qCAAqC,CAAC;AAC3F,OAAO,EAAE,oCAAoC,EAAE,MAAM,qCAAqC,CAAC;AAC3F,OAAO,EAAE,gCAAgC,EAAE,MAAM,gCAAgC,CAAC;AAalF,OAAO,EAAE,yCAAyC,EAAE,MAAM,2CAA2C,CAAC;AACtG,OAAO,EAAE,6CAA6C,EAAE,MAAM,gDAAgD,CAAC;AAC/G,OAAO,EAAE,8BAA8B,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,EAAE,uCAAuC,EAAE,MAAM,yCAAyC,CAAC;AAClG,OAAO,EAAE,yCAAyC,EAAE,MAAM,2CAA2C,CAAC;AACtG,OAAO,EAAE,iCAAiC,EAAE,MAAM,kCAAkC,CAAC;AACrF,OAAO,EAAE,oCAAoC,EAAE,MAAM,qCAAqC,CAAC;AAC3F,OAAO,EAAE,oCAAoC,EAAE,MAAM,qCAAqC,CAAC;AAC3F,OAAO,EAAE,gCAAgC,EAAE,MAAM,gCAAgC,CAAC;AAElF;;GAEG;AACH,MAAM,OAAO,iBAAiB;IACX,UAAU,CAAuB;IAElD;;;OAGG;IACH,YAAY,UAAiC;QAC3C,IAAI,CAAC,UAAU,GAAG,UAAU,IAAI;YAC9B,IAAI,oCAAoC,EAAE;YAC1C,IAAI,yCAAyC,EAAE;YAC/C,IAAI,yCAAyC,EAAE;YAC/C,IAAI,6CAA6C,EAAE;YACnD,IAAI,8BAA8B,EAAE;YACpC,IAAI,uCAAuC,EAAE;YAC7C,IAAI,iCAAiC,EAAE;YACvC,IAAI,oCAAoC,EAAE;YAC1C,IAAI,gCAAgC,EAAE;SACvC,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,MAAM;QACJ,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,mBAAmB,CAAC,GAAqB;QAC7C,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACxC,IAAI,SAAS,CAAC,gBAAgB,EAAE,CAAC;gBAC/B,MAAM,SAAS,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC;YACxC,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,MAAM,CAAC,GAAqB;QAChC,MAAM,OAAO,GAAsB,EAAE,CAAC;QACtC,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACxC,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAC/C,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;gBAC1D,SAAS;YACX,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC1C,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvB,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB;IACrC,OAAO,IAAI,iBAAiB,EAAE,CAAC;AACjC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/standards/storage.ts"],"names":[],"mappings":"AAOA,OAAO,EAEL,KAAK,cAAc,EAEpB,MAAM,eAAe,CAAC;AAOvB,eAAO,MAAM,yBAAyB,QAAa,CAAC;AAMpD,2DAA2D;AAC3D,MAAM,MAAM,wBAAwB,GAChC;IAAE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAA;CAAE,GAChE;IAAE,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAA;CAAE,GAC9B;IAAE,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/D,wEAAwE;AACxE,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACxD;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,EACnB,GAAG,GAAE,IAAiB,EACtB,YAAY,GAAE,8BAAmC,GAChD,OAAO,CAAC,wBAAwB,CAAC,CAanC;AAsDD;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,OAAO,EAClB,GAAG,GAAE,IAAiB,GACrB,OAAO,CAAC;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAA;CAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/standards/storage.ts"],"names":[],"mappings":"AAOA,OAAO,EAEL,KAAK,cAAc,EAEpB,MAAM,eAAe,CAAC;AAOvB,eAAO,MAAM,yBAAyB,QAAa,CAAC;AAMpD,2DAA2D;AAC3D,MAAM,MAAM,wBAAwB,GAChC;IAAE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAA;CAAE,GAChE;IAAE,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAA;CAAE,GAC9B;IAAE,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/D,wEAAwE;AACxE,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACxD;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,EACnB,GAAG,GAAE,IAAiB,EACtB,YAAY,GAAE,8BAAmC,GAChD,OAAO,CAAC,wBAAwB,CAAC,CAanC;AAsDD;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,OAAO,EAClB,GAAG,GAAE,IAAiB,GACrB,OAAO,CAAC;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAA;CAAE,CAAC,CAYpE"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/** Confined, bounded, atomic storage for standards-conformance proof. */
|
|
2
2
|
import * as fse from "fs-extra";
|
|
3
3
|
import { constants as fsConstants } from "node:fs";
|
|
4
|
-
import { lstat, open, realpath
|
|
4
|
+
import { lstat, open, realpath } from "node:fs/promises";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { withFileTargetLock } from "../core/learnings-lock.js";
|
|
7
|
-
import {
|
|
7
|
+
import { writeFileAtomically } from "../utils/atomic-file-write.js";
|
|
8
8
|
import { STANDARDS_PROOF_PATH, validateStandardsProof, } from "./contract.js";
|
|
9
9
|
import { MALFORMED_STANDARDS_PROOF_REASON, safeStandardsStorageReason, safeStandardsValidationReason, } from "./storage-reasons.js";
|
|
10
10
|
export const MAX_STANDARDS_PROOF_BYTES = 128 * 1024;
|
|
@@ -86,26 +86,13 @@ function unreadable(reason) {
|
|
|
86
86
|
export async function writeStandardsProof(projectRoot, candidate, now = new Date()) {
|
|
87
87
|
const proof = validateStandardsProof(candidate, now);
|
|
88
88
|
const serialized = serialize(proof);
|
|
89
|
-
const {
|
|
89
|
+
const { target } = await resolveWriteTarget(projectRoot);
|
|
90
90
|
return await withFileTargetLock(target, async () => {
|
|
91
91
|
await assertSafeTarget(target);
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
await handle.writeFile(serialized, "utf8");
|
|
97
|
-
await handle.sync();
|
|
98
|
-
}
|
|
99
|
-
finally {
|
|
100
|
-
await handle.close();
|
|
101
|
-
}
|
|
102
|
-
await assertSafeTarget(target);
|
|
103
|
-
await rename(temporary, target);
|
|
104
|
-
await syncContainingDirectory(directory);
|
|
105
|
-
}
|
|
106
|
-
finally {
|
|
107
|
-
await rm(temporary, { force: true });
|
|
108
|
-
}
|
|
92
|
+
await writeFileAtomically(target, serialized, {
|
|
93
|
+
mode: 0o600,
|
|
94
|
+
beforeRename: () => assertSafeTarget(target),
|
|
95
|
+
});
|
|
109
96
|
return Object.freeze({ path: target, proof });
|
|
110
97
|
});
|
|
111
98
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/standards/storage.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,SAAS,IAAI,WAAW,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/standards/storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type OpenDirectory } from "./directory-sync.js";
|
|
2
|
+
/** Injectable collaborators and per-call policy for {@link writeFileAtomically}. */
|
|
3
|
+
export interface AtomicWriteOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Explicit POSIX permission bits for the published file. Omit to keep the
|
|
6
|
+
* platform default (`0o666` minus umask) — the learnings ledger is a
|
|
7
|
+
* committed, human-read file, and forcing `0o600` would silently tighten its
|
|
8
|
+
* permissions on the next write.
|
|
9
|
+
*/
|
|
10
|
+
readonly mode?: number;
|
|
11
|
+
/**
|
|
12
|
+
* Caller safety re-check run after the content is durably written but before
|
|
13
|
+
* the rename publishes it. Used by every call site to re-assert that the
|
|
14
|
+
* target's parents have not been swapped for a symlink mid-write; throwing
|
|
15
|
+
* here aborts the publish and still removes the temp file.
|
|
16
|
+
*/
|
|
17
|
+
readonly beforeRename?: () => Promise<void>;
|
|
18
|
+
/** Test-only directory opener forwarded to {@link syncContainingDirectory}. */
|
|
19
|
+
readonly openDirectory?: OpenDirectory;
|
|
20
|
+
/** Test-only observer proving the file handle is fsynced before rename. */
|
|
21
|
+
readonly onFileSync?: () => Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Atomically and durably replace one file's contents.
|
|
25
|
+
* @param target - Absolute path to publish
|
|
26
|
+
* @param content - Full UTF-8 payload to write
|
|
27
|
+
* @param options - Permission policy and injectable collaborators
|
|
28
|
+
*/
|
|
29
|
+
export declare function writeFileAtomically(target: string, content: string, options?: AtomicWriteOptions): Promise<void>;
|
|
30
|
+
//# sourceMappingURL=atomic-file-write.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atomic-file-write.d.ts","sourceRoot":"","sources":["../../src/utils/atomic-file-write.ts"],"names":[],"mappings":"AAqBA,OAAO,EAEL,KAAK,aAAa,EACnB,MAAM,qBAAqB,CAAC;AAE7B,oFAAoF;AACpF,MAAM,WAAW,kBAAkB;IACjC;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,+EAA+E;IAC/E,QAAQ,CAAC,aAAa,CAAC,EAAE,aAAa,CAAC;IACvC,2EAA2E;IAC3E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3C;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAcf"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One atomic, durable file-replacement primitive shared by every Lisa writer
|
|
3
|
+
* that publishes a small canonical document.
|
|
4
|
+
*
|
|
5
|
+
* This block was previously copy-pasted four times — twice in
|
|
6
|
+
* `src/core/learnings-writer.ts` and once each in `src/health/storage.ts` and
|
|
7
|
+
* `src/standards/storage.ts` — and the copies had already drifted apart: the
|
|
8
|
+
* two storage writers fsync the file handle and the containing directory, while
|
|
9
|
+
* both learnings copies fsynced neither. A rename is atomic with respect to
|
|
10
|
+
* concurrent readers, but without the fsync pair the rename can reach disk
|
|
11
|
+
* before the data does, so a power loss could publish a renamed-but-empty
|
|
12
|
+
* ledger (CodySwannGT/lisa#1995). Consolidating removes the drift and gives the
|
|
13
|
+
* learnings writer the durability the storage writers already had.
|
|
14
|
+
*
|
|
15
|
+
* The write is exclusive (`wx`) into a per-process, per-call temp name, so two
|
|
16
|
+
* writers can never share a temp file, and the temp is always removed — a
|
|
17
|
+
* failure leaves the previous target byte-identical rather than truncated.
|
|
18
|
+
* @module utils/atomic-file-write
|
|
19
|
+
*/
|
|
20
|
+
import { open, rename, rm } from "node:fs/promises";
|
|
21
|
+
import * as path from "node:path";
|
|
22
|
+
import { syncContainingDirectory, } from "./directory-sync.js";
|
|
23
|
+
/**
|
|
24
|
+
* Atomically and durably replace one file's contents.
|
|
25
|
+
* @param target - Absolute path to publish
|
|
26
|
+
* @param content - Full UTF-8 payload to write
|
|
27
|
+
* @param options - Permission policy and injectable collaborators
|
|
28
|
+
*/
|
|
29
|
+
export async function writeFileAtomically(target, content, options = {}) {
|
|
30
|
+
const directory = path.dirname(target);
|
|
31
|
+
const temporary = path.join(directory, `.${path.basename(target)}.${process.pid}.${crypto.randomUUID()}.tmp`);
|
|
32
|
+
try {
|
|
33
|
+
await writeDurableTemporary(temporary, content, options);
|
|
34
|
+
await options.beforeRename?.();
|
|
35
|
+
await rename(temporary, target);
|
|
36
|
+
await syncContainingDirectory(directory, options.openDirectory);
|
|
37
|
+
}
|
|
38
|
+
finally {
|
|
39
|
+
await rm(temporary, { force: true });
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Write the payload to an exclusive temp file and flush it to disk.
|
|
44
|
+
* @param temporary - Per-call temp path
|
|
45
|
+
* @param content - Full UTF-8 payload
|
|
46
|
+
* @param options - Permission policy and injectable collaborators
|
|
47
|
+
*/
|
|
48
|
+
async function writeDurableTemporary(temporary, content, options) {
|
|
49
|
+
const handle = options.mode === undefined
|
|
50
|
+
? await open(temporary, "wx")
|
|
51
|
+
: await open(temporary, "wx", options.mode);
|
|
52
|
+
try {
|
|
53
|
+
await handle.writeFile(content, "utf8");
|
|
54
|
+
await handle.sync();
|
|
55
|
+
await options.onFileSync?.();
|
|
56
|
+
}
|
|
57
|
+
finally {
|
|
58
|
+
await handle.close();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=atomic-file-write.js.map
|