craftar 0.10.1 → 0.12.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/core/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,373 @@
1
+ import { promises as fs } from "node:fs";
2
+ import path from "node:path";
3
+ import { execFile } from "node:child_process";
4
+ import { promisify } from "node:util";
5
+ import { exists } from "./forge.js";
6
+ import { withLock } from "./home-lock.js";
7
+ import { hashNormalized } from "./text.js";
8
+ /* ------------------------------------------------------------------ */
9
+ /* What counts as a URL, and credentials (spec 13 §6.1, §4.3) */
10
+ /* ------------------------------------------------------------------ */
11
+ const SCHEME_URL = /^[A-Za-z][A-Za-z0-9+.-]*:\/\//;
12
+ /** The SCP-like form `<user>@<host>:<path>`; without a user, `host:path` stays a path (a drive letter looks the same). */
13
+ const SCP_URL = /^[^\s/\\:@]+@[^\s/\\:]+:/;
14
+ /** A `forge:` value is a git URL (a remote Forge) or a path resolved from the workspace root. */
15
+ export function classifyForge(value) {
16
+ const v = value.trim();
17
+ return SCHEME_URL.test(v) || SCP_URL.test(v) ? "url" : "path";
18
+ }
19
+ /**
20
+ * True when a `forge:` value carries a credential: a user or password in an `http(s)` URL, a password
21
+ * in any other scheme, or a `<x>:<y>@` before the first `/` or `\` whatever the value reads as — so a
22
+ * password never reaches a message that prints the value (spec 13 §6.1, §14 item 11).
23
+ */
24
+ export function credentialFault(raw) {
25
+ const value = raw.trim();
26
+ const head = value.split(/[/\\]/, 1)[0];
27
+ if (/^[^@]*:[^@]*@/.test(head) && !SCHEME_URL.test(value))
28
+ return true;
29
+ const scheme = SCHEME_URL.exec(value);
30
+ if (!scheme)
31
+ return false;
32
+ // Read the authority as written, never through a parser: a spelling WHATWG URL rejects
33
+ // (`host:badport`) must not slip through and be printed later. It runs to the first `/`, as git
34
+ // reads an ssh URL — a `?` or `#` in a password stays inside it. Fail closed.
35
+ const rest = value.slice(scheme[0].length);
36
+ const authority = rest.slice(0, rest.search(/\/|$/));
37
+ const at = authority.lastIndexOf("@");
38
+ if (at === -1)
39
+ return false;
40
+ const userinfo = authority.slice(0, at);
41
+ if (/^https?:\/\/$/i.test(scheme[0]))
42
+ return userinfo !== "";
43
+ return userinfo.includes(":");
44
+ }
45
+ /* ------------------------------------------------------------------ */
46
+ /* The cache key (spec 13 §6.3) */
47
+ /* ------------------------------------------------------------------ */
48
+ /** Scheme and host lowercased; a trailing `/`, then `.git`, dropped. */
49
+ function normalizeUrl(url) {
50
+ let u = url.trim();
51
+ const scheme = SCHEME_URL.exec(u);
52
+ if (scheme) {
53
+ const rest = u.slice(scheme[0].length);
54
+ const slash = rest.indexOf("/");
55
+ const host = slash === -1 ? rest : rest.slice(0, slash);
56
+ u = scheme[0].toLowerCase() + host.toLowerCase() + (slash === -1 ? "" : rest.slice(slash));
57
+ }
58
+ else {
59
+ const at = u.indexOf("@");
60
+ const colon = u.indexOf(":", at);
61
+ if (at !== -1 && colon !== -1)
62
+ u = u.slice(0, at + 1) + u.slice(at + 1, colon).toLowerCase() + u.slice(colon);
63
+ }
64
+ u = u.replace(/\/+$/, "");
65
+ return u.replace(/\.git$/, "");
66
+ }
67
+ /** `<readable slug of host and path>-<first 12 hex of sha256(normalized url)>`. The URL holds no credentials (§4.3). */
68
+ export function cacheKey(url) {
69
+ const normalized = normalizeUrl(url);
70
+ // The one hash helper (node-cli rule), though a URL has no line endings to normalize.
71
+ const hash = hashNormalized(normalized).slice("sha256:".length, "sha256:".length + 12);
72
+ const withoutScheme = normalized.replace(SCHEME_URL, "").replace(/^[^@/]*@/, "");
73
+ const slug = withoutScheme
74
+ .replace(/[^A-Za-z0-9._-]+/g, "-")
75
+ .replace(/^-+|-+$/g, "")
76
+ .toLowerCase()
77
+ .slice(0, 60)
78
+ .replace(/-+$/, "");
79
+ return `${slug}-${hash}`;
80
+ }
81
+ export function parseLsRemote(stdout) {
82
+ const out = { head: null, heads: new Map(), tags: new Map() };
83
+ for (const line of stdout.split(/\r?\n/)) {
84
+ if (!line.trim())
85
+ continue;
86
+ const symref = /^ref:\s+refs\/heads\/(\S+)\s+HEAD$/.exec(line);
87
+ if (symref) {
88
+ out.head = symref[1];
89
+ continue;
90
+ }
91
+ const [sha, name] = line.split("\t");
92
+ if (!sha || !name)
93
+ continue;
94
+ if (name.startsWith("refs/heads/"))
95
+ out.heads.set(name.slice("refs/heads/".length), sha);
96
+ else if (name.startsWith("refs/tags/")) {
97
+ const tag = name.slice("refs/tags/".length);
98
+ // An annotated tag's object comes first; its `^{}` line is the commit, which wins.
99
+ if (tag.endsWith("^{}"))
100
+ out.tags.set(tag.slice(0, -3), sha);
101
+ else if (!out.tags.has(tag))
102
+ out.tags.set(tag, sha);
103
+ }
104
+ }
105
+ return out;
106
+ }
107
+ const FULL_SHA = /^[0-9a-f]{40}$/;
108
+ /**
109
+ * The commit a requested ref names, in the order of spec 13 §6.2. A full SHA is returned as is: the
110
+ * caller checks it exists once the fetch has run. Abbreviated SHAs are refused on purpose — their
111
+ * meaning changes as the repository grows.
112
+ */
113
+ export function resolveRef(refs, ref, url) {
114
+ if (ref === null) {
115
+ const branch = refs.head;
116
+ const commit = branch === null ? undefined : refs.heads.get(branch);
117
+ if (branch === null || commit === undefined)
118
+ throw new Error(`${url} has no default branch to follow — set ref in craftar.yaml`);
119
+ return { commit, defaultBranch: branch };
120
+ }
121
+ if (FULL_SHA.test(ref))
122
+ return { commit: ref, defaultBranch: null };
123
+ const qualified = /^refs\/(heads|tags)\/(.+)$/.exec(ref);
124
+ if (qualified) {
125
+ const commit = (qualified[1] === "heads" ? refs.heads : refs.tags).get(qualified[2]);
126
+ if (commit === undefined)
127
+ throw new Error(`ref "${ref}" not found in ${url}`);
128
+ return { commit, defaultBranch: null };
129
+ }
130
+ const branch = refs.heads.get(ref);
131
+ const tag = refs.tags.get(ref);
132
+ if (branch !== undefined && tag !== undefined)
133
+ throw new Error(`ref "${ref}" is both a branch and a tag in ${url} — write refs/heads/${ref} or refs/tags/${ref}`);
134
+ const commit = branch ?? tag;
135
+ if (commit === undefined)
136
+ throw new Error(`ref "${ref}" not found in ${url}`);
137
+ return { commit, defaultBranch: null };
138
+ }
139
+ /** The remote could not be reached; `cached` says what the cache could still offer. */
140
+ export class ForgeFetchError extends Error {
141
+ url;
142
+ gitMessage;
143
+ haveCopy;
144
+ cached;
145
+ constructor(url, gitMessage,
146
+ /** A completed fetch left a copy, whether or not it can resolve the ref. */
147
+ haveCopy, cached) {
148
+ super(`cannot fetch the Forge ${url}: ${gitMessage}`);
149
+ this.url = url;
150
+ this.gitMessage = gitMessage;
151
+ this.haveCopy = haveCopy;
152
+ this.cached = cached;
153
+ }
154
+ }
155
+ /** Reading the cache only (`--offline`, `targets`) found no copy of this Forge. */
156
+ export class NoCachedCopyError extends Error {
157
+ url;
158
+ constructor(url) {
159
+ super(`the Forge ${url} has no cached copy yet`);
160
+ this.url = url;
161
+ }
162
+ }
163
+ const execFileP = promisify(execFile);
164
+ export const defaultGit = async (args, opts = {}) => {
165
+ const env = { ...process.env };
166
+ // CI fails fast instead of hanging on a credential prompt; a terminal may still prompt (spec 13 §14 item 4).
167
+ if (opts.remote && !process.stdin.isTTY)
168
+ env.GIT_TERMINAL_PROMPT = "0";
169
+ try {
170
+ const { stdout } = await execFileP("git", args, { env, maxBuffer: 64 * 1024 * 1024 });
171
+ return stdout;
172
+ }
173
+ catch (e) {
174
+ const err = e;
175
+ const line = (err.stderr ?? "").split(/\r?\n/).map((l) => l.trim()).find((l) => l) ?? err.message;
176
+ throw new Error(line.replace(/^fatal:\s*/, ""));
177
+ }
178
+ };
179
+ /** The tree for `ref` of the remote Forge at `url`, fetching first unless offline or the ref is a full SHA already cached. */
180
+ export async function ensureTree(written, ref, opts) {
181
+ // As classifyForge reads it: git would choke on a stray leading space.
182
+ const url = written.trim();
183
+ const git = opts.git ?? defaultGit;
184
+ // Absolute once: `git -C repo.git worktree add <dir>` would read a relative dir from inside repo.git.
185
+ const home = path.resolve(opts.home);
186
+ const entry = path.join(home, "forges", cacheKey(url));
187
+ const repo = path.join(entry, "repo.git");
188
+ const stamp = path.join(entry, "fetched");
189
+ // A copy exists once a fetch completed: an init whose fetch then failed leaves no stamp.
190
+ const haveCopy = await exists(stamp);
191
+ const fetchedAt = async () => {
192
+ const text = (await exists(stamp)) ? (await fs.readFile(stamp, "utf8")).trim() : "";
193
+ return /^\d{4}-\d{2}-\d{2}T[\d:.]+Z$/.test(text) ? text : null;
194
+ };
195
+ const label = ref ?? "the default branch";
196
+ // A full SHA already in the cache names the same commit whatever the remote does: no fetch (§14 item 3).
197
+ const cachedSha = ref !== null && FULL_SHA.test(ref) && haveCopy && (await hasCommit(git, repo, ref));
198
+ let resolved;
199
+ let fetched = false;
200
+ if (opts.offline || cachedSha) {
201
+ if (!haveCopy)
202
+ throw new NoCachedCopyError(url);
203
+ resolved = cachedSha ? { commit: ref, defaultBranch: null } : resolveRef(await cachedRefs(git, repo), ref, url);
204
+ if (!(await hasCommit(git, repo, resolved.commit)))
205
+ throw new Error(`ref "${label}" not found in ${url}`);
206
+ }
207
+ else {
208
+ let refs;
209
+ try {
210
+ refs = parseLsRemote(await git(["ls-remote", "--symref", url], { remote: true }));
211
+ }
212
+ catch (e) {
213
+ throw new ForgeFetchError(url, e.message, haveCopy, await cachedFallback(git, repo, haveCopy, ref, url, await fetchedAt()));
214
+ }
215
+ resolved = resolveRef(refs, ref, url);
216
+ try {
217
+ await fs.mkdir(entry, { recursive: true });
218
+ }
219
+ catch (e) {
220
+ throw new Error(`cannot write the Forge cache in ${home}: ${e.code ?? e.message}`);
221
+ }
222
+ await withEntryLock(entry, opts, async () => {
223
+ if (!(await exists(path.join(repo, "HEAD"))))
224
+ await git(["init", "--quiet", "--bare", repo]);
225
+ try {
226
+ await git(["-C", repo, "fetch", "--quiet", "--prune", url, "+refs/heads/*:refs/heads/*", "+refs/tags/*:refs/tags/*"], { remote: true });
227
+ }
228
+ catch (e) {
229
+ throw new ForgeFetchError(url, e.message, haveCopy, await cachedFallback(git, repo, haveCopy, ref, url, await fetchedAt()));
230
+ }
231
+ // A bare repository filled by fetch does not keep the remote's HEAD; --offline without a ref needs it.
232
+ if (refs.head)
233
+ await git(["-C", repo, "symbolic-ref", "HEAD", `refs/heads/${refs.head}`]);
234
+ await fs.writeFile(stamp, new Date().toISOString() + "\n");
235
+ });
236
+ fetched = true;
237
+ if (!(await hasCommit(git, repo, resolved.commit)))
238
+ throw new Error(`ref "${label}" not found in ${url}`);
239
+ }
240
+ const dir = await treeFor(git, entry, repo, resolved.commit, opts);
241
+ if (fetched)
242
+ await cleanup(git, entry, repo, resolved.commit, opts);
243
+ return { dir, commit: resolved.commit, defaultBranch: resolved.defaultBranch, fetched, fetchedAt: await fetchedAt() };
244
+ }
245
+ async function hasCommit(git, repo, sha) {
246
+ try {
247
+ await git(["-C", repo, "cat-file", "-e", `${sha}^{commit}`]);
248
+ return true;
249
+ }
250
+ catch {
251
+ return false;
252
+ }
253
+ }
254
+ /** The refs as the last fetch left them in the bare repository, in `ls-remote`'s shape. */
255
+ async function cachedRefs(git, repo) {
256
+ const lines = [];
257
+ try {
258
+ lines.push(`ref: ${(await git(["-C", repo, "symbolic-ref", "HEAD"])).trim()}\tHEAD`);
259
+ }
260
+ catch {
261
+ // no recorded default branch
262
+ }
263
+ const listed = await git(["-C", repo, "for-each-ref", "--format=%(objectname)\t%(refname)\t%(*objectname)", "refs/heads", "refs/tags"]);
264
+ for (const line of listed.split(/\r?\n/)) {
265
+ const [sha, name, peeled] = line.split("\t");
266
+ if (!sha || !name)
267
+ continue;
268
+ lines.push(`${sha}\t${name}`);
269
+ if (peeled)
270
+ lines.push(`${peeled}\t${name}^{}`);
271
+ }
272
+ return parseLsRemote(lines.join("\n"));
273
+ }
274
+ async function cachedFallback(git, repo, haveRepo, ref, url, fetchedAt) {
275
+ if (!haveRepo)
276
+ return null;
277
+ try {
278
+ const { commit } = ref !== null && FULL_SHA.test(ref) ? { commit: ref } : resolveRef(await cachedRefs(git, repo), ref, url);
279
+ return (await hasCommit(git, repo, commit)) ? { commit, fetchedAt } : null;
280
+ }
281
+ catch {
282
+ return null;
283
+ }
284
+ }
285
+ /** One worktree per resolved commit; never written to after creation. A failure leaves no half-made tree. */
286
+ async function treeFor(git, entry, repo, commit, opts) {
287
+ const dir = path.join(entry, "trees", commit);
288
+ // Complete once Craftar wrote `<commit>.ok` under the lock, after `worktree add` returned. Git's own
289
+ // `.git` file comes before the checkout, so a run cut short — or one still checking out in another
290
+ // process — leaves a tree without the marker: it is removed and made again, never loaded half.
291
+ const marker = `${dir}.ok`;
292
+ const complete = async () => (await exists(marker)) && (await exists(path.join(dir, ".git")));
293
+ if (!(await complete())) {
294
+ await withEntryLock(entry, opts, async () => {
295
+ if (await complete())
296
+ return;
297
+ if (await exists(dir)) {
298
+ await git(["-C", repo, "worktree", "remove", "--force", dir]).catch(() => { });
299
+ await fs.rm(dir, { recursive: true, force: true });
300
+ }
301
+ await git(["-C", repo, "worktree", "prune"]).catch(() => { });
302
+ await fs.mkdir(path.dirname(dir), { recursive: true });
303
+ try {
304
+ // The commit's bytes, the same on every platform (spec 13 §8): no host setting rewrites the
305
+ // checkout — not core.autocrlf, not core.eol (native CRLF on Git for Windows, applied to a
306
+ // Forge's `text=auto`), not a global attributes file. A Forge's own `eol=` still applies: that
307
+ // is the Forge author's choice.
308
+ await git(["-c", "core.autocrlf=false", "-c", "core.eol=lf", "-c", "core.attributesFile=", "-C", repo, "worktree", "add", "--quiet", "--detach", dir, commit]);
309
+ await fs.writeFile(marker, `${new Date().toISOString()}\n`);
310
+ }
311
+ catch (e) {
312
+ await git(["-C", repo, "worktree", "remove", "--force", dir]).catch(() => { });
313
+ await fs.rm(dir, { recursive: true, force: true });
314
+ await git(["-C", repo, "worktree", "prune"]).catch(() => { });
315
+ throw new Error(`cannot create the Forge tree ${dir}: ${e.message}`);
316
+ }
317
+ });
318
+ }
319
+ const used = `${dir}.used`;
320
+ const now = new Date();
321
+ await fs.writeFile(used, "").catch(() => { });
322
+ await fs.utimes(used, now, now).catch(() => { });
323
+ return dir;
324
+ }
325
+ /** Trees unused for `cleanupMs` go, except the one in use; `repo.git` is left to git. */
326
+ async function cleanup(git, entry, repo, inUse, opts) {
327
+ const trees = path.join(entry, "trees");
328
+ const limit = Date.now() - (opts.cleanupMs ?? 14 * 24 * 60 * 60 * 1000);
329
+ // When a tree was last used: its `.used` stamp, else its completion marker, else the directory — so a
330
+ // tree whose run died before stamping it still ages out.
331
+ const lastUse = async (commit) => {
332
+ for (const p of [`${commit}.used`, `${commit}.ok`, commit]) {
333
+ const st = await fs.stat(path.join(trees, p)).catch(() => null);
334
+ if (st)
335
+ return st.mtimeMs;
336
+ }
337
+ return null;
338
+ };
339
+ let removed = false;
340
+ for (const name of await fs.readdir(trees).catch(() => [])) {
341
+ if (name.includes(".") || name === inUse)
342
+ continue;
343
+ const used = await lastUse(name);
344
+ if (used === null || used >= limit)
345
+ continue;
346
+ await withEntryLock(entry, opts, async () => {
347
+ // Again under the lock: a reader may have touched the stamp since (readers take no lock).
348
+ const again = await lastUse(name);
349
+ if (again === null || again >= limit)
350
+ return;
351
+ await git(["-C", repo, "worktree", "remove", "--force", path.join(trees, name)]).catch(() => { });
352
+ for (const p of [name, `${name}.used`, `${name}.ok`])
353
+ await fs.rm(path.join(trees, p), { recursive: true, force: true });
354
+ removed = true;
355
+ });
356
+ }
357
+ // A stamp or marker whose tree is gone (a reader stamped it as cleanup took the tree) goes too — under
358
+ // the lock, so it never races a rebuild between its `rm` of the tree and the `.ok` it then writes.
359
+ await withEntryLock(entry, opts, async () => {
360
+ for (const name of await fs.readdir(trees).catch(() => [])) {
361
+ const m = /^(.+)\.(used|ok)$/.exec(name);
362
+ if (m && !(await exists(path.join(trees, m[1]))))
363
+ await fs.rm(path.join(trees, name), { force: true });
364
+ }
365
+ });
366
+ if (removed)
367
+ await git(["-C", repo, "worktree", "prune"]).catch(() => { });
368
+ }
369
+ /** The entry's lock (`<entry>/lock`), through the one helper the registry shares (spec 21 §5.4). */
370
+ function withEntryLock(entry, opts, body) {
371
+ return withLock(path.join(entry, "lock"), "the Forge cache entry", opts, body);
372
+ }
373
+ //# sourceMappingURL=remote.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote.js","sourceRoot":"","sources":["../../src/core/remote.ts"],"names":[],"mappings":"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"}
package/dist/core/sync.js CHANGED
@@ -1,13 +1,16 @@
1
1
  import { promises as fs } from "node:fs";
2
2
  import path from "node:path";
3
- import YAML from "yaml";
3
+ import { isDeepStrictEqual } from "node:util";
4
4
  import { loadForge, exists, listFiles, FORGE_MANIFEST } from "./forge.js";
5
5
  import { resolve, substitute, paramsFor, sectionKey, sectionsFor } from "./resolve.js";
6
6
  import { hashNormalized, stripBom, toLf } from "./text.js";
7
+ import { parseWorkspaceYaml } from "./workspace-yaml.js";
8
+ import { classifyForge, credentialFault, ensureTree, ForgeFetchError, NoCachedCopyError } from "./remote.js";
9
+ import { resolveHome } from "./home-lock.js";
7
10
  import { deepMerge } from "./merge.js";
8
11
  import { canonicalValue, checkDeclaredOnce, expandSections, firstMarkerLine, markerLine, parseSections } from "./sections.js";
9
12
  import { placeholders, bodyFile, emittedFile } from "./extract.js";
10
- import { LockSchema, WorkspaceConfigSchema } from "../schema/index.js";
13
+ import { LOCK_SCHEMAS, LockSchema, WorkspaceConfigSchema } from "../schema/index.js";
11
14
  import { claudeCode } from "../emitters/claude-code.js";
12
15
  import { kiro } from "../emitters/kiro.js";
13
16
  import { agentsMd } from "../emitters/agents-md.js";
@@ -28,24 +31,91 @@ export async function emitFor(t, emitter, base) {
28
31
  throw new Error(`internal: the ${t} emitter returned before walking every ingredient aimed at it`);
29
32
  return files;
30
33
  }
31
- export async function loadWorkspace(root) {
34
+ export async function loadWorkspace(root, opts = {}) {
32
35
  root = path.resolve(root);
33
36
  const file = path.join(root, WORKSPACE_FILE);
34
37
  if (!(await exists(file)))
35
38
  throw new Error(`${WORKSPACE_FILE} not found in ${root} — run \`craftar import --workspace "${root}" --from claude-code --forge <dir> --profile <name> --write-config\` to create it`);
36
- const base = YAML.parse(await fs.readFile(file, "utf8")) ?? {};
39
+ const base = parseWorkspaceYaml(WORKSPACE_FILE, await fs.readFile(file, "utf8")) ?? {};
37
40
  const localFile = path.join(root, LOCAL_FILE);
38
41
  const hasLocal = await exists(localFile);
39
- const local = hasLocal ? YAML.parse(await fs.readFile(localFile, "utf8")) ?? {} : {};
42
+ const local = hasLocal ? parseWorkspaceYaml(LOCAL_FILE, await fs.readFile(localFile, "utf8")) ?? {} : {};
43
+ // Before anything can print the value: a credential in either file is refused by file and field (spec 13 §4.3).
44
+ for (const [name, raw] of [[WORKSPACE_FILE, base], [LOCAL_FILE, local]]) {
45
+ const value = raw !== null && typeof raw === "object" ? raw.forge : undefined;
46
+ if (typeof value === "string" && credentialFault(value))
47
+ throw new Error(`${name} › forge holds credentials in the URL — remove them and let git authenticate (credential helper, SSH agent; see README › Remote Forge)`);
48
+ }
49
+ const fromLocalFile = local !== null && typeof local === "object" && Object.hasOwn(local, "forge");
40
50
  const parsed = WorkspaceConfigSchema.safeParse(deepMerge(base, local));
41
51
  // Named, as a Forge file is: a wrong-shape `overrides.sections` key fails here (spec 11 §5.2).
42
52
  if (!parsed.success)
43
53
  throw new Error(`invalid ${WORKSPACE_FILE}${hasLocal ? ` (merged with ${LOCAL_FILE})` : ""}: ${parsed.error.message}`);
44
54
  const config = parsed.data;
45
- const forgeRoot = /^[a-z]+:\/\/|^git@/.test(config.forge) ? config.forge : path.resolve(root, config.forge);
55
+ const remote = classifyForge(config.forge) === "url";
56
+ const warnings = [];
57
+ if (fromLocalFile)
58
+ warnings.push(`Forge overridden by ${LOCAL_FILE} (${config.forge}) — do not commit ${LOCK_FILE} or the generated files`);
59
+ if (remote) {
60
+ if (opts.refuseRemote)
61
+ throw new Error(opts.refuseRemote(config.forge));
62
+ const { tree, origin, warning } = await remoteTree(config.forge, config.ref ?? null, opts, fromLocalFile);
63
+ if (warning)
64
+ warnings.push(warning);
65
+ return { root, config, forge: await loadForge(tree), origin, warnings };
66
+ }
67
+ const forgeRoot = path.resolve(root, config.forge);
46
68
  if (!(await exists(forgeRoot)))
47
- throw new Error(`Forge not found at ${forgeRoot} (remote Forges are not supported yet — clone it and point \`forge:\` at the path)`);
48
- return { root, config, forge: await loadForge(forgeRoot) };
69
+ throw new Error(`Forge not found at ${forgeRoot}`);
70
+ // A path means the working tree as it is; a ref beside it is ignored, said out loud (Ruling 9).
71
+ if (config.ref !== undefined)
72
+ warnings.unshift(`ref "${config.ref}" is ignored: the Forge is a path (${config.forge}), read as its working tree`);
73
+ const origin = { kind: "path", source: config.forge, ref: null, defaultBranch: null, fetched: false, fromLocalFile };
74
+ return { root, config, forge: await loadForge(forgeRoot), origin, warnings };
75
+ }
76
+ const short = (sha) => sha.slice(0, 8);
77
+ /** Fetch (or not) by the rule of `opts.mode`, and say what was used (spec 13 §4.1, §4.8). */
78
+ async function remoteTree(url, ref, opts, fromLocalFile) {
79
+ const home = resolveHome(opts.home);
80
+ const mode = opts.mode ?? "read";
81
+ const offline = opts.offline || mode === "no-fetch";
82
+ const origin = (t) => ({
83
+ kind: "remote",
84
+ source: url,
85
+ ref,
86
+ defaultBranch: t.defaultBranch,
87
+ fetched: t.fetched,
88
+ ...(t.fetchedAt ? { fetchedAt: t.fetchedAt } : {}),
89
+ fromLocalFile,
90
+ });
91
+ const used = (t) => `the cached copy at ${short(t.commit)}, fetched ${t.fetchedAt ?? "never"}`;
92
+ if (offline) {
93
+ let t;
94
+ try {
95
+ t = await ensureTree(url, ref, { home, offline: true });
96
+ }
97
+ catch (e) {
98
+ if (!(e instanceof NoCachedCopyError))
99
+ throw e;
100
+ // `targets` (no-fetch) takes no --offline: point at a command that fetches.
101
+ throw new Error(`${e.message} — ${opts.offline ? "run without --offline once to fetch it" : "run craftar status once to fetch it"}`);
102
+ }
103
+ return { tree: t.dir, origin: origin(t), warning: opts.offline ? `Forge ${url} not fetched (--offline) — using ${used(t)}` : null };
104
+ }
105
+ try {
106
+ const t = await ensureTree(url, ref, { home });
107
+ return { tree: t.dir, origin: origin(t), warning: null };
108
+ }
109
+ catch (e) {
110
+ if (!(e instanceof ForgeFetchError))
111
+ throw e;
112
+ if (!e.cached)
113
+ throw new Error(`cannot fetch the Forge ${url}: ${e.gitMessage} — ${e.haveCopy ? `and the cached copy cannot resolve ${ref ?? "the default branch"}` : "and there is no cached copy to fall back on"}`);
114
+ if (mode === "sync")
115
+ throw new Error(`cannot fetch the Forge ${url}: ${e.gitMessage} — run with --offline to use the cached copy (${short(e.cached.commit)} fetched ${e.cached.fetchedAt ?? "never"})`);
116
+ const t = await ensureTree(url, ref, { home, offline: true });
117
+ return { tree: t.dir, origin: origin(t), warning: `Forge ${url} not fetched (${e.gitMessage}) — using ${used(t)}` };
118
+ }
49
119
  }
50
120
  /**
51
121
  * The Forge and (optionally) the workspace a command operates on.
@@ -56,13 +126,17 @@ export async function resolveForgeSource(opts) {
56
126
  if (opts.forge !== undefined && opts.workspace !== undefined) {
57
127
  throw new Error("pass either --forge or --workspace, not both — two sources for one Forge");
58
128
  }
59
- if (opts.forge !== undefined)
129
+ if (opts.forge !== undefined) {
130
+ // A URL is not a directory to load: a remote Forge is read through a workspace that names it (spec 13 §4.4).
131
+ if (classifyForge(opts.forge) === "url")
132
+ throw new Error("--forge takes a directory; to read a remote Forge, run inside a workspace that names it");
60
133
  return { forge: await loadForge(path.resolve(opts.forge)) };
134
+ }
61
135
  const root = path.resolve(opts.workspace ?? ".");
62
136
  if (!(await exists(path.join(root, WORKSPACE_FILE)))) {
63
137
  throw new Error(`no ${WORKSPACE_FILE} in ${root} — run this inside a workspace, pass --workspace <dir>, or point at the Forge with --forge <dir>`);
64
138
  }
65
- const workspace = await loadWorkspace(root);
139
+ const workspace = await loadWorkspace(root, opts);
66
140
  return { forge: workspace.forge, workspace };
67
141
  }
68
142
  /**
@@ -185,7 +259,7 @@ function guardOutput(ing, file, out, p, resolution, params) {
185
259
  }
186
260
  export async function plan(ws) {
187
261
  const resolution = resolve(ws.forge, ws.config);
188
- const warnings = [...resolution.warnings];
262
+ const warnings = [...ws.warnings, ...resolution.warnings];
189
263
  if (resolution.targets.length === 0) {
190
264
  warnings.push("no targets resolved — nothing will be emitted and every file in craftar.lock becomes an orphan (an empty list in craftar.local.yaml replaces the workspace's)");
191
265
  }
@@ -266,7 +340,11 @@ export async function readLock(root) {
266
340
  const f = path.join(root, LOCK_FILE);
267
341
  if (!(await exists(f)))
268
342
  return null;
269
- return LockSchema.parse(JSON.parse(await fs.readFile(f, "utf8")));
343
+ const raw = JSON.parse(await fs.readFile(f, "utf8"));
344
+ // A lock a later craftar wrote is refused by name, not with a zod dump (spec 13 §4.6).
345
+ if (raw !== null && typeof raw === "object" && Object.hasOwn(raw, "schema") && !LOCK_SCHEMAS.includes(raw.schema))
346
+ throw new Error(`${LOCK_FILE} declares schema ${JSON.stringify(raw.schema)}, which this craftar does not read — upgrade craftar`);
347
+ return LockSchema.parse(raw);
270
348
  }
271
349
  export async function writeLock(root, lock) {
272
350
  await fs.writeFile(path.join(root, LOCK_FILE), JSON.stringify(lock, null, 2) + "\n", "utf8");
@@ -366,14 +444,22 @@ export async function apply(ws, p, statuses, opts = {}) {
366
444
  break;
367
445
  }
368
446
  }
369
- const lock = {
370
- schema: 1,
371
- forge: { source: ws.config.forge, commit: ws.forge.commit },
447
+ // Schema 2, in this key order (spec 13 §5.2): what the sync used, not only what it wrote.
448
+ const built = {
449
+ schema: 2,
450
+ forge: { source: ws.config.forge, ref: ws.origin.ref, commit: ws.forge.commit },
372
451
  profile: ws.config.profile,
452
+ recipes: p.resolution.recipes,
453
+ targets: p.resolution.targets,
373
454
  generatedAt: new Date().toISOString(),
374
455
  files: entries.sort((a, b) => a.path.localeCompare(b.path)),
375
456
  };
376
- if (!opts.dryRun)
457
+ // Rewritten only when its content changes: generatedAt is when it last did (Ruling 10). A schema 1
458
+ // lock always differs, so the first sync with this craftar upgrades it.
459
+ const onDisk = opts.dryRun ? null : await readLock(ws.root);
460
+ const unchanged = onDisk !== null && isDeepStrictEqual({ ...onDisk, generatedAt: null }, { ...built, generatedAt: null });
461
+ const lock = unchanged ? onDisk : built;
462
+ if (!opts.dryRun && !unchanged)
377
463
  await writeLock(ws.root, lock);
378
464
  return { written, removed, skipped, lock };
379
465
  }