baselane 0.1.0 → 0.1.2
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/apply.js +51 -1
- package/dist/cli.js +2 -1
- package/dist/drift-cmd.js +1 -1
- package/package.json +11 -7
package/dist/apply.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { lstat, mkdir, readFile, stat, writeFile } from "node:fs/promises";
|
|
2
2
|
import { dirname, join, resolve, sep } from "node:path";
|
|
3
|
-
import { isEntryFile, loadBuiltinPack, mergeManagedRegion, renderPack } from "@baselane/packs";
|
|
3
|
+
import { buildManifest, extractManagedRegions, isEntryFile, loadBuiltinPack, mergeManagedRegion, renderPack, sha256Hex, } from "@baselane/packs";
|
|
4
|
+
import { readManifestWithFallback, targetLocation, writeManifestFile } from "@baselane/materialize";
|
|
4
5
|
async function exists(path) {
|
|
5
6
|
try {
|
|
6
7
|
await stat(path);
|
|
@@ -93,8 +94,57 @@ export async function applyResolvedPack(targetDir, pack, opts) {
|
|
|
93
94
|
await writeFile(abs, content, "utf8");
|
|
94
95
|
}
|
|
95
96
|
}
|
|
97
|
+
if (!opts.dryRun) {
|
|
98
|
+
await recordApplyManifest(targetDir, pack, files, written);
|
|
99
|
+
}
|
|
96
100
|
return { written: written.sort(), skipped: skipped.sort() };
|
|
97
101
|
}
|
|
102
|
+
/** Writes/updates the target's harness.json after an apply, so `baselane drift` works on the
|
|
103
|
+
* apply path exactly as it does after `baselane install`. Merges into any existing manifest
|
|
104
|
+
* (other packs' pins and receipts survive). Files apply SKIPPED (pre-existing, no --force) are
|
|
105
|
+
* deliberately left out of the receipt: apply didn't write them, so drift shouldn't police them. */
|
|
106
|
+
async function recordApplyManifest(targetDir, pack, files, written) {
|
|
107
|
+
const loc = targetLocation({ global: false, dir: targetDir });
|
|
108
|
+
const { manifest: existing } = await readManifestWithFallback(loc);
|
|
109
|
+
const writtenSet = new Set(written);
|
|
110
|
+
const vendored = new Map((existing?.materialized.vendored ?? []).map((v) => [v.path, v]));
|
|
111
|
+
const managed = new Map((existing?.materialized.managedRegions ?? []).map((m) => [m.path, m]));
|
|
112
|
+
for (const [rel, content] of Object.entries(files)) {
|
|
113
|
+
if (isEntryFile(rel)) {
|
|
114
|
+
// The region merge runs on every apply, so after apply the region is on disk whether or
|
|
115
|
+
// not this run changed it. Its body derives only from the rendered content, so hash the
|
|
116
|
+
// null-merge instead of re-reading disk.
|
|
117
|
+
const region = extractManagedRegions(mergeManagedRegion(null, content, pack.id, pack.version))
|
|
118
|
+
.find((r) => r.packId === pack.id);
|
|
119
|
+
if (!region)
|
|
120
|
+
continue;
|
|
121
|
+
const others = (managed.get(rel)?.regions ?? []).filter((r) => r.packId !== pack.id);
|
|
122
|
+
managed.set(rel, {
|
|
123
|
+
path: rel,
|
|
124
|
+
regions: [...others, { packId: pack.id, version: pack.version, sha256: sha256Hex(region.body) }],
|
|
125
|
+
});
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
if (!writtenSet.has(rel))
|
|
129
|
+
continue;
|
|
130
|
+
vendored.set(rel, { path: rel, sha256: sha256Hex(content) });
|
|
131
|
+
}
|
|
132
|
+
const byPath = (a, b) => a.path.localeCompare(b.path);
|
|
133
|
+
const manifest = buildManifest({
|
|
134
|
+
target: loc.target,
|
|
135
|
+
packs: { ...(existing?.packs ?? {}), [pack.id]: pack.version },
|
|
136
|
+
registry: existing?.registry ?? null,
|
|
137
|
+
capabilities: existing?.capabilities ?? {},
|
|
138
|
+
receipt: {
|
|
139
|
+
vendored: [...vendored.values()].sort(byPath),
|
|
140
|
+
managedRegions: [...managed.values()].sort(byPath),
|
|
141
|
+
derivedCommitted: existing?.materialized.derivedCommitted ?? [],
|
|
142
|
+
resolutions: existing?.materialized.resolutions ?? {},
|
|
143
|
+
capabilities: existing?.materialized.capabilities ?? {},
|
|
144
|
+
},
|
|
145
|
+
});
|
|
146
|
+
await writeManifestFile(loc.manifestPath, manifest);
|
|
147
|
+
}
|
|
98
148
|
/** Built-in-pack convenience wrapper over applyResolvedPack — kept so existing callers that
|
|
99
149
|
* only ever deal in built-in pack ids don't need to load the pack themselves. */
|
|
100
150
|
export async function applyPack(targetDir, packId, opts) {
|
package/dist/cli.js
CHANGED
|
@@ -71,7 +71,8 @@ export async function main(argv, deps = {}) {
|
|
|
71
71
|
});
|
|
72
72
|
const label = argv.includes("--dry-run") ? "would write" : "wrote";
|
|
73
73
|
console.log(`baselane apply ${pack.id}: ${label} ${r.written.length} file(s)` +
|
|
74
|
-
(r.skipped.length ? `, skipped ${r.skipped.length} existing (use --force): ${r.skipped.join(", ")}` : "")
|
|
74
|
+
(r.skipped.length ? `, skipped ${r.skipped.length} existing (use --force): ${r.skipped.join(", ")}` : "") +
|
|
75
|
+
(argv.includes("--dry-run") ? "" : " · harness.json updated — run \"baselane drift\" anytime"));
|
|
75
76
|
return 0;
|
|
76
77
|
}
|
|
77
78
|
if (cmd === "graph" && dir) {
|
package/dist/drift-cmd.js
CHANGED
|
@@ -19,7 +19,7 @@ export async function runDrift(opts) {
|
|
|
19
19
|
const loc = targetLocation({ global: opts.global, dir: opts.dir, homeDir: opts.homeDir });
|
|
20
20
|
const { manifest } = await readManifestWithFallback(loc);
|
|
21
21
|
if (manifest === null)
|
|
22
|
-
throw new Error(`drift: no harness.json at ${loc.manifestPath} — run baselane install first`);
|
|
22
|
+
throw new Error(`drift: no harness.json at ${loc.manifestPath} — run baselane apply or install first`);
|
|
23
23
|
const unreadable = [];
|
|
24
24
|
const vendored = [];
|
|
25
25
|
for (const entry of manifest.materialized.vendored) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "baselane",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Git-native package manager for AI coding harnesses — audit a repo, apply workflow packs, and keep agent config in sync.",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -13,9 +13,10 @@
|
|
|
13
13
|
"license": "Apache-2.0",
|
|
14
14
|
"repository": {
|
|
15
15
|
"type": "git",
|
|
16
|
-
"url": "git+https://github.com/
|
|
16
|
+
"url": "git+https://github.com/baselane-sh/baselane.git",
|
|
17
|
+
"directory": "apps/cli"
|
|
17
18
|
},
|
|
18
|
-
"homepage": "https://baselane
|
|
19
|
+
"homepage": "https://github.com/baselane-sh/baselane",
|
|
19
20
|
"keywords": [
|
|
20
21
|
"ai",
|
|
21
22
|
"agents",
|
|
@@ -33,16 +34,19 @@
|
|
|
33
34
|
"README.md"
|
|
34
35
|
],
|
|
35
36
|
"dependencies": {
|
|
36
|
-
"@baselane/analyze": "0.1.
|
|
37
|
-
"@baselane/distribute": "0.1.
|
|
38
|
-
"@baselane/packs": "0.1.
|
|
39
|
-
"@baselane/materialize": "0.1.
|
|
37
|
+
"@baselane/analyze": "0.1.2",
|
|
38
|
+
"@baselane/distribute": "0.1.2",
|
|
39
|
+
"@baselane/packs": "0.1.2",
|
|
40
|
+
"@baselane/materialize": "0.1.2"
|
|
40
41
|
},
|
|
41
42
|
"devDependencies": {
|
|
42
43
|
"@types/node": "^24.0.0",
|
|
43
44
|
"typescript": "^5.9.0",
|
|
44
45
|
"vitest": "^2.0.0"
|
|
45
46
|
},
|
|
47
|
+
"bugs": {
|
|
48
|
+
"url": "https://github.com/baselane-sh/baselane/issues"
|
|
49
|
+
},
|
|
46
50
|
"scripts": {
|
|
47
51
|
"test": "vitest run",
|
|
48
52
|
"typecheck": "tsc --noEmit",
|