gutterpress 0.10.0 → 0.10.1-beta.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.
Files changed (57) hide show
  1. package/README.md +3 -16
  2. package/dist/api/index.d.ts +10 -19
  3. package/dist/api/index.js +8 -64
  4. package/dist/{audit-cvarpa72.js → audit-dce99css.js} +5 -5
  5. package/dist/{build-6r502chw.js → build-bj4x0727.js} +5 -5
  6. package/dist/checks/source/index.d.ts +1 -0
  7. package/dist/checks/source/merge-markers.d.ts +3 -0
  8. package/dist/{cli-cqtggsng.js → cli-0z6zf98d.js} +2 -47
  9. package/dist/{cli-eq5naw4m.js → cli-7n848af2.js} +370 -1249
  10. package/dist/{cli-zfcryxg8.js → cli-eewynen9.js} +97 -60
  11. package/dist/{cli-k1065rkg.js → cli-w692g6dx.js} +75 -29
  12. package/dist/{cli-149edp6b.js → cli-ydpf09d9.js} +1 -1
  13. package/dist/cli.js +14 -15
  14. package/dist/{doctor-akvxbtjb.js → doctor-7nd6n2aa.js} +2 -2
  15. package/dist/{engine-ft4cr3ep.js → engine-57vw8zpd.js} +1 -1
  16. package/dist/{engine-b159tbns.js → engine-8kdwy0jz.js} +2 -2
  17. package/dist/{gutterpress-viewer-te8g5grx.js → gutterpress-viewer-tma1qwz2.js} +57 -15
  18. package/dist/{index-ycpvr0am.js → index-7hrvksrb.js} +4 -4
  19. package/dist/{index-mdefp0y5.js → index-dtrftayr.js} +75 -27
  20. package/dist/{index-ge7q9xj3.js → index-h1x7krkg.js} +771 -1482
  21. package/dist/{index-wq3r5pj7.js → index-p0ebr7dh.js} +94 -57
  22. package/dist/index.js +9 -65
  23. package/dist/lib/git-fs.d.ts +43 -0
  24. package/dist/lib/host-policy.d.ts +14 -2
  25. package/dist/lib/remote-auth/clone.d.ts +0 -21
  26. package/dist/lib/remote-auth/converge-merge.d.ts +24 -7
  27. package/dist/lib/remote-auth/generic-auth.d.ts +0 -22
  28. package/dist/lib/remote-auth/git-http.d.ts +1 -1
  29. package/dist/lib/remote-auth/github-auth.d.ts +2 -22
  30. package/dist/lib/remote-auth/operation-log.d.ts +4 -9
  31. package/dist/lib/remote-auth/sync-messages.d.ts +35 -12
  32. package/dist/lib/remote-auth/sync-types.d.ts +30 -101
  33. package/dist/lib/remote-auth/sync.d.ts +19 -21
  34. package/dist/lib/remote-auth/token-store.d.ts +0 -10
  35. package/dist/lib/remote-auth/transport.d.ts +42 -40
  36. package/dist/lib/source-provider.d.ts +12 -0
  37. package/dist/{lint-p2sw53d9.js → lint-c8ze8sqw.js} +5 -5
  38. package/dist/{new-hvq0x91q.js → new-xy2qc300.js} +5 -5
  39. package/dist/{plugin-pssmk0dx.js → plugin-g9hwzjsm.js} +5 -5
  40. package/dist/{preflight-4j00yd0g.js → preflight-prcvdvmk.js} +5 -5
  41. package/dist/{preview-bridge-fz7vpk8m.js → preview-bridge-2nnrs2hy.js} +15 -0
  42. package/dist/{preview-d4s6gk6p.js → preview-h479apj9.js} +5 -5
  43. package/dist/{preview-interface-0ssk8bmm.js → preview-interface-2f5v96hd.js} +411 -88
  44. package/dist/{preview-shell-c5mfa3q0.js → preview-shell-kyjq59d9.js} +80 -25
  45. package/dist/{publish-tkc26en7.js → publish-emk644a8.js} +5 -5
  46. package/dist/{source-provider-3tcj6qg2.js → source-provider-2j5x2hyw.js} +1 -1
  47. package/dist/{source-provider-vanafrt9.js → source-provider-kn41jmbs.js} +1 -1
  48. package/dist/{validate-w9vfefrw.js → validate-be54bdc6.js} +5 -5
  49. package/package.json +1 -1
  50. package/dist/lib/app-heartbeat.d.ts +0 -102
  51. package/dist/lib/remote-auth/image-clash.d.ts +0 -17
  52. package/dist/lib/remote-auth/recovery/classify.d.ts +0 -97
  53. package/dist/lib/remote-auth/recovery/inspect.d.ts +0 -75
  54. package/dist/lib/remote-auth/recovery/locks.d.ts +0 -20
  55. package/dist/lib/remote-auth/recovery/repair.d.ts +0 -29
  56. package/dist/lib/remote-auth/recovery/types.d.ts +0 -39
  57. package/dist/repair-2va4w12t.js +0 -137
@@ -1422,19 +1422,19 @@ var favicon_default = "./favicon-wkbm9cjn.ico";
1422
1422
  var manifest_schema_default = "./manifest.schema-zxgxnbg7.json";
1423
1423
 
1424
1424
  // src/assets/preview/scripts/preview-interface.js
1425
- var preview_interface_default = "./preview-interface-0ssk8bmm.js";
1425
+ var preview_interface_default = "./preview-interface-2f5v96hd.js";
1426
1426
 
1427
1427
  // src/assets/preview/scripts/preview-bridge.js
1428
- var preview_bridge_default = "./preview-bridge-fz7vpk8m.js";
1428
+ var preview_bridge_default = "./preview-bridge-2nnrs2hy.js";
1429
1429
 
1430
1430
  // src/assets/preview/scripts/preview-shell.js
1431
- var preview_shell_default = "./preview-shell-c5mfa3q0.js";
1431
+ var preview_shell_default = "./preview-shell-kyjq59d9.js";
1432
1432
 
1433
1433
  // profiles/CGATS21_CRPC1.icc
1434
1434
  var CGATS21_CRPC1_default = "./CGATS21_CRPC1-g0e3k7kr.icc";
1435
1435
 
1436
1436
  // src/assets/engine/gutterpress-viewer.js
1437
- var gutterpress_viewer_default = "./gutterpress-viewer-te8g5grx.js";
1437
+ var gutterpress_viewer_default = "./gutterpress-viewer-tma1qwz2.js";
1438
1438
 
1439
1439
  // src/assets/engine/gutterpress-agent.js
1440
1440
  var gutterpress_agent_default = "./gutterpress-agent-cazqstr1.js";
@@ -1768,6 +1768,62 @@ var DESC_JS = `(el) => {
1768
1768
  const src = el.tagName === "IMG" ? " src=" + (el.getAttribute("src") || "").slice(-40) : "";
1769
1769
  return el.tagName.toLowerCase() + cls + src;
1770
1770
  }`;
1771
+ var ABS_CONTAINING_BLOCK_JS = `(cs) => {
1772
+ if (cs.position !== "static") return true;
1773
+ for (const prop of [
1774
+ "transform", "translate", "rotate", "scale", "perspective",
1775
+ "filter", "backdropFilter",
1776
+ ]) {
1777
+ const value = cs[prop];
1778
+ if (value && value !== "none") return true;
1779
+ }
1780
+ if (/\\b(layout|paint|strict|content)\\b/.test(cs.contain)) return true;
1781
+ if (cs.containerType && cs.containerType !== "normal") return true;
1782
+ return /\\b(transform|translate|rotate|scale|perspective|filter)\\b/.test(cs.willChange);
1783
+ }`;
1784
+ var CLIP_EDGES_JS = `((establishesAbsContainingBlock) => {
1785
+ const open = () => ({ left: -Infinity, right: Infinity, top: -Infinity, bottom: Infinity });
1786
+ const rootStyle = getComputedStyle(document.documentElement);
1787
+ const propagates = (a, rootOverflow) =>
1788
+ a === document.documentElement ||
1789
+ (a === document.body && rootOverflow === "visible");
1790
+ return (el) => {
1791
+ const edges = open();
1792
+ const chain = [];
1793
+ const elStyle = getComputedStyle(el);
1794
+ const fixed = elStyle.position === "fixed";
1795
+ let binds = !fixed && elStyle.position !== "absolute";
1796
+ for (let a = el.parentElement; a; a = a.parentElement) {
1797
+ const cs = getComputedStyle(a);
1798
+ if (!fixed && !binds && establishesAbsContainingBlock(cs)) binds = true;
1799
+ const own = open();
1800
+ const clipsX =
1801
+ binds && cs.overflowX !== "visible" && !propagates(a, rootStyle.overflowX);
1802
+ const clipsY =
1803
+ binds && cs.overflowY !== "visible" && !propagates(a, rootStyle.overflowY);
1804
+ if (clipsX || clipsY) {
1805
+ const r = a.getBoundingClientRect();
1806
+ const clipMargin = parseFloat(cs.overflowClipMargin) || 0;
1807
+ if (clipsX) {
1808
+ const grow = cs.overflowX === "clip" ? clipMargin : 0;
1809
+ own.left = r.left + parseFloat(cs.borderLeftWidth) - grow;
1810
+ own.right = r.right - parseFloat(cs.borderRightWidth) + grow;
1811
+ edges.left = Math.max(edges.left, own.left);
1812
+ edges.right = Math.min(edges.right, own.right);
1813
+ }
1814
+ if (clipsY) {
1815
+ const grow = cs.overflowY === "clip" ? clipMargin : 0;
1816
+ own.top = r.top + parseFloat(cs.borderTopWidth) - grow;
1817
+ own.bottom = r.bottom - parseFloat(cs.borderBottomWidth) + grow;
1818
+ edges.top = Math.max(edges.top, own.top);
1819
+ edges.bottom = Math.min(edges.bottom, own.bottom);
1820
+ }
1821
+ }
1822
+ chain.push({ ancestor: a, style: cs, edges: own });
1823
+ }
1824
+ return { edges, chain };
1825
+ };
1826
+ })(${ABS_CONTAINING_BLOCK_JS})`;
1771
1827
  function pagePseudoContexts(model) {
1772
1828
  const used = new Set(pseudoVariants(model));
1773
1829
  const standard = new Set(["left", "right", "recto", "verso", "first", "blank"]);
@@ -2237,25 +2293,11 @@ ${mapCss}`;
2237
2293
  return reasons;
2238
2294
  };
2239
2295
 
2240
- // Does this box establish the containing block for an absolutely
2241
- // positioned descendant? Overflow clipping binds an abspos
2242
- // .gp-pin only from its containing block outward MEASURED: a
2243
- // pin whose box lay entirely outside a STATIC overflow:hidden
2244
- // (and overflow:clip) wrapper printed complete and still behind
2245
- // the page text; the wrapper's clip never touched it.
2246
- const establishesAbsContainingBlock = (cs) => {
2247
- if (cs.position !== "static") return true;
2248
- for (const prop of [
2249
- "transform", "translate", "rotate", "scale", "perspective",
2250
- "filter", "backdropFilter",
2251
- ]) {
2252
- const value = cs[prop];
2253
- if (value && value !== "none") return true;
2254
- }
2255
- if (/\\b(layout|paint|strict|content)\\b/.test(cs.contain)) return true;
2256
- if (cs.containerType && cs.containerType !== "normal") return true;
2257
- return /\\b(transform|translate|rotate|scale|perspective|filter)\\b/.test(cs.willChange);
2258
- };
2296
+ // Which ancestors clip a .gp-behind, and where their edges fall —
2297
+ // the same measured rule the pre-print width check clamps against
2298
+ // (see CLIP_EDGES_JS). This pass walks its \`chain\` so it can name
2299
+ // the ancestor doing the cutting.
2300
+ const clipEdges = ${CLIP_EDGES_JS};
2259
2301
 
2260
2302
  for (const el of document.querySelectorAll("*")) {
2261
2303
  const cs = getComputedStyle(el);
@@ -2298,47 +2340,25 @@ ${mapCss}`;
2298
2340
  const boundary = el.closest(".page, .spread");
2299
2341
  if (boundary) {
2300
2342
  const elRect = el.getBoundingClientRect();
2301
- // Clip binding: an in-flow .gp-behind is bound by every
2302
- // ancestor's overflow, but an abspos one only from its
2303
- // containing block outward — static wrappers in between
2304
- // never clip it (measured; see the pass comment above).
2305
- let clipBinds = cs.position !== "absolute" && cs.position !== "fixed";
2306
- for (let ancestor = el.parentElement; ancestor; ancestor = ancestor.parentElement) {
2307
- const ancestorStyle = getComputedStyle(ancestor);
2308
- if (!clipBinds && establishesAbsContainingBlock(ancestorStyle)) clipBinds = true;
2343
+ for (const link of clipEdges(el).chain) {
2344
+ const ancestor = link.ancestor;
2345
+ const ancestorStyle = link.style;
2309
2346
  const reasons = stackingReasons(ancestor, ancestorStyle);
2310
2347
  // Clipping never reorders layers — it can only CUT the
2311
2348
  // art (measured, pass comment above): warn only where the
2312
- // border box crosses a binding ancestor's clip edge on an
2313
- // axis whose overflow is not \`visible\`. The clip edge is
2314
- // the padding box, grown by overflow-clip-margin where
2315
- // that axis's value is \`clip\` (px values only; keyword
2316
- // forms parse NaN -> 0, i.e. the ungrown padding box).
2317
- // 1px epsilon: the measured cut lands exactly at the
2318
- // edge, and sub-pixel layout rounding is not an overhang.
2349
+ // border box crosses THIS ancestor's own clip edges, which
2350
+ // are ±Infinity on any axis it does not bind. 1px epsilon:
2351
+ // the measured cut lands exactly at the edge, and sub-pixel
2352
+ // layout rounding is not an overhang.
2319
2353
  const cuts = [];
2320
- if (clipBinds && (ancestorStyle.overflowX !== "visible" || ancestorStyle.overflowY !== "visible")) {
2321
- const r = ancestor.getBoundingClientRect();
2322
- const clipMargin = parseFloat(ancestorStyle.overflowClipMargin) || 0;
2323
- if (ancestorStyle.overflowX !== "visible") {
2324
- const grow = ancestorStyle.overflowX === "clip" ? clipMargin : 0;
2325
- const left = r.left + parseFloat(ancestorStyle.borderLeftWidth) - grow;
2326
- const right = r.right - parseFloat(ancestorStyle.borderRightWidth) + grow;
2327
- if (elRect.left < left - 1)
2328
- cuts.push(Math.round(left - elRect.left) + "px past its left clip edge");
2329
- if (elRect.right > right + 1)
2330
- cuts.push(Math.round(elRect.right - right) + "px past its right clip edge");
2331
- }
2332
- if (ancestorStyle.overflowY !== "visible") {
2333
- const grow = ancestorStyle.overflowY === "clip" ? clipMargin : 0;
2334
- const top = r.top + parseFloat(ancestorStyle.borderTopWidth) - grow;
2335
- const bottom = r.bottom - parseFloat(ancestorStyle.borderBottomWidth) + grow;
2336
- if (elRect.top < top - 1)
2337
- cuts.push(Math.round(top - elRect.top) + "px past its top clip edge");
2338
- if (elRect.bottom > bottom + 1)
2339
- cuts.push(Math.round(elRect.bottom - bottom) + "px past its bottom clip edge");
2340
- }
2341
- }
2354
+ if (elRect.left < link.edges.left - 1)
2355
+ cuts.push(Math.round(link.edges.left - elRect.left) + "px past its left clip edge");
2356
+ if (elRect.right > link.edges.right + 1)
2357
+ cuts.push(Math.round(elRect.right - link.edges.right) + "px past its right clip edge");
2358
+ if (elRect.top < link.edges.top - 1)
2359
+ cuts.push(Math.round(link.edges.top - elRect.top) + "px past its top clip edge");
2360
+ if (elRect.bottom > link.edges.bottom + 1)
2361
+ cuts.push(Math.round(elRect.bottom - link.edges.bottom) + "px past its bottom clip edge");
2342
2362
  if ((reasons.length || cuts.length) && !seenLayerTraps.has(ancestor)) {
2343
2363
  seenLayerTraps.add(ancestor);
2344
2364
  const effects = [];
@@ -2443,6 +2463,20 @@ async function findWidthOffenders(page, model, bleedSlugExtensionPt, restoreView
2443
2463
  const boxes = JSON.parse(await page.evaluate(`(() => {
2444
2464
  const LIMIT = ${limitPx} + 1;
2445
2465
  const desc = ${DESC_JS};
2466
+ // Shrink-to-fit only reacts to overflow that ESCAPES: a clipping or
2467
+ // scrolling ancestor contains its subtree's overflow, so the
2468
+ // document's own width never grows and the book prints at 1.0x.
2469
+ // MEASURED (Chrome 151, a marker word read off \`pdftotext -bbox\`
2470
+ // against an unshrunk control): a 900px box inside a 300px
2471
+ // \`overflow: hidden\` shell printed unshrunk, as did the same box
2472
+ // under clip/auto/scroll — and a real 208-page book whose two
2473
+ // "offenders" both sat under \`overflow-x: clip\` printed
2474
+ // coordinate-identical with them restored. WHICH ancestors clip, and
2475
+ // where their edges fall, is CLIP_EDGES_JS's measured rule — shared
2476
+ // with the layer-containment audit, which measures overhang past the
2477
+ // same edges. Only the x edges matter here: shrink-to-fit is a width
2478
+ // response.
2479
+ const clipEdges = ${CLIP_EDGES_JS};
2446
2480
  const out = [];
2447
2481
  for (const el of document.querySelectorAll("*")) {
2448
2482
  const r = el.getBoundingClientRect();
@@ -2452,6 +2486,9 @@ async function findWidthOffenders(page, model, bleedSlugExtensionPt, restoreView
2452
2486
  // width) — both trigger the same whole-document shrink-to-fit,
2453
2487
  // measured: a left bleed alone cost 16%.
2454
2488
  if (right <= LIMIT && r.width <= LIMIT && r.left >= -1) continue;
2489
+ // ...but only where it actually escapes its clipping ancestors.
2490
+ const clip = clipEdges(el).edges;
2491
+ if (Math.min(right, clip.right) <= LIMIT && Math.max(r.left, clip.left) >= -1) continue;
2455
2492
  let deepest = true;
2456
2493
  for (const c of el.children) {
2457
2494
  if (c.getBoundingClientRect().width >= r.width - 1) { deepest = false; break; }
@@ -4,8 +4,59 @@ import {
4
4
  findEnclosingRepoDir
5
5
  } from "./cli-v5mp7a6q.js";
6
6
 
7
+ // src/lib/git-fs.ts
8
+ import * as nodeFs from "node:fs";
9
+ var MUTABLE_GIT_METADATA = /(?:^|[\\/])\.git[\\/](?:index|HEAD|packed-refs|refs[\\/].+)$/;
10
+ function needsAtomicWrite(file) {
11
+ return typeof file === "string" && MUTABLE_GIT_METADATA.test(file);
12
+ }
13
+ var tempCounter = 0;
14
+ function tempPathFor(file) {
15
+ return `${file}.gp${process.pid.toString(36)}-${(tempCounter++).toString(36)}.tmp`;
16
+ }
17
+ function writeFile2(file, data, options, callback) {
18
+ const cb = typeof options === "function" ? options : callback;
19
+ const opts = typeof options === "function" ? undefined : options;
20
+ if (!needsAtomicWrite(file)) {
21
+ nodeFs.writeFile(file, data, opts, cb);
22
+ return;
23
+ }
24
+ const temp = tempPathFor(file);
25
+ const failed = (err) => nodeFs.unlink(temp, () => cb(err));
26
+ nodeFs.writeFile(temp, data, opts, (writeErr) => {
27
+ if (writeErr)
28
+ return failed(writeErr);
29
+ nodeFs.rename(temp, file, (renameErr) => {
30
+ if (renameErr)
31
+ return failed(renameErr);
32
+ cb(null);
33
+ });
34
+ });
35
+ }
36
+ async function writeFilePromise(file, data, options) {
37
+ if (!needsAtomicWrite(file)) {
38
+ return nodeFs.promises.writeFile(file, data, options);
39
+ }
40
+ const temp = tempPathFor(file);
41
+ try {
42
+ await nodeFs.promises.writeFile(temp, data, options);
43
+ await nodeFs.promises.rename(temp, file);
44
+ } catch (err) {
45
+ await nodeFs.promises.unlink(temp).catch(() => {});
46
+ throw err;
47
+ }
48
+ }
49
+ var promises2 = {
50
+ ...nodeFs.promises,
51
+ writeFile: writeFilePromise
52
+ };
53
+ var gitFs = {
54
+ ...nodeFs,
55
+ writeFile: writeFile2,
56
+ promises: promises2
57
+ };
58
+
7
59
  // src/lib/source-provider.ts
8
- import * as fs from "node:fs";
9
60
  import path2 from "node:path";
10
61
  import git from "isomorphic-git";
11
62
 
@@ -43,11 +94,6 @@ function createFileLogger(logFile, operation, minLevel = "debug") {
43
94
  error: (step, message, data) => write("error", step, message, data)
44
95
  };
45
96
  }
46
- function resolveLogger(logFile, operation) {
47
- if (!logFile)
48
- return noop;
49
- return createFileLogger(logFile, operation);
50
- }
51
97
  function formatData(data) {
52
98
  if (!data)
53
99
  return "";
@@ -83,7 +129,7 @@ var repoQueues = new Map;
83
129
  function repoLockKey(projectDir) {
84
130
  const resolved = path2.resolve(projectDir);
85
131
  try {
86
- return fs.realpathSync(resolved);
132
+ return gitFs.realpathSync(resolved);
87
133
  } catch {
88
134
  return resolved;
89
135
  }
@@ -114,10 +160,10 @@ function gitAuthor(name, email) {
114
160
  }
115
161
  async function readGitAuthor(dir) {
116
162
  const [name, email] = await Promise.all([
117
- git.getConfig({ fs, dir, path: "user.name" }).catch(() => {
163
+ git.getConfig({ fs: gitFs, dir, path: "user.name" }).catch(() => {
118
164
  return;
119
165
  }),
120
- git.getConfig({ fs, dir, path: "user.email" }).catch(() => {
166
+ git.getConfig({ fs: gitFs, dir, path: "user.email" }).catch(() => {
121
167
  return;
122
168
  })
123
169
  ]);
@@ -134,14 +180,14 @@ async function listWorkdirChanges(dir, cache = {}) {
134
180
  const adds = [];
135
181
  const removes = [];
136
182
  await git.walk({
137
- fs,
183
+ fs: gitFs,
138
184
  dir,
139
185
  cache,
140
186
  trees: [git.WORKDIR(), git.STAGE()],
141
187
  map: async (filepath, [workdir, stage]) => {
142
188
  if (filepath === ".")
143
189
  return;
144
- if (!stage && workdir && await git.isIgnored({ fs, dir, filepath })) {
190
+ if (!stage && workdir && (filepath.startsWith(".git-damaged") || await git.isIgnored({ fs: gitFs, dir, filepath }))) {
145
191
  return null;
146
192
  }
147
193
  const [wType, sType] = await Promise.all([
@@ -165,7 +211,7 @@ async function listWorkdirChanges(dir, cache = {}) {
165
211
  if (workdirOid !== stageOid) {
166
212
  adds.push(filepath);
167
213
  } else {
168
- const fileBytes = await fs.promises.readFile(path2.join(dir, filepath));
214
+ const fileBytes = await gitFs.promises.readFile(path2.join(dir, filepath));
169
215
  const { oid: actualOid } = await git.hashBlob({ object: fileBytes });
170
216
  if (actualOid !== stageOid)
171
217
  adds.push(filepath);
@@ -178,10 +224,10 @@ async function listWorkdirChanges(dir, cache = {}) {
178
224
  }
179
225
  async function stageChanges(dir, changes, cache) {
180
226
  if (changes.adds.length > 0) {
181
- await git.add({ fs, dir, cache, filepath: changes.adds });
227
+ await git.add({ fs: gitFs, dir, cache, filepath: changes.adds });
182
228
  }
183
229
  for (const filepath of changes.removes) {
184
- await git.remove({ fs, dir, cache, filepath });
230
+ await git.remove({ fs: gitFs, dir, cache, filepath });
185
231
  }
186
232
  }
187
233
  async function hasPendingChanges(dir, cache = {}) {
@@ -196,13 +242,13 @@ async function hasUncommittedChanges(dir, cache = {}) {
196
242
  async function stageMatchesHead(dir, cache) {
197
243
  let headOid;
198
244
  try {
199
- headOid = await git.resolveRef({ fs, dir, ref: "HEAD" });
245
+ headOid = await git.resolveRef({ fs: gitFs, dir, ref: "HEAD" });
200
246
  } catch {
201
247
  return false;
202
248
  }
203
249
  let differs = false;
204
250
  await git.walk({
205
- fs,
251
+ fs: gitFs,
206
252
  dir,
207
253
  cache,
208
254
  trees: [git.TREE({ ref: headOid }), git.STAGE()],
@@ -244,10 +290,10 @@ class LocalFolderSourceProvider {
244
290
  }
245
291
  return withRepoLock(dir, async () => {
246
292
  const cache = {};
247
- await git.init({ fs, dir, defaultBranch: DEFAULT_BRANCH });
293
+ await git.init({ fs: gitFs, dir, defaultBranch: DEFAULT_BRANCH });
248
294
  await stageChanges(dir, await listWorkdirChanges(dir, cache), cache);
249
295
  await git.commit({
250
- fs,
296
+ fs: gitFs,
251
297
  dir,
252
298
  cache,
253
299
  message: options.initialMessage?.trim() || "Created project",
@@ -316,7 +362,7 @@ class LocalGitSourceProvider {
316
362
  let commits;
317
363
  try {
318
364
  commits = await git.log({
319
- fs,
365
+ fs: gitFs,
320
366
  dir,
321
367
  cache: {},
322
368
  depth: limit + 2,
@@ -353,7 +399,7 @@ class LocalGitSourceProvider {
353
399
  }
354
400
  async restoreUnlocked(options) {
355
401
  await git.checkout({
356
- fs,
402
+ fs: gitFs,
357
403
  dir: this.dir,
358
404
  cache: {},
359
405
  ref: options.id,
@@ -365,9 +411,9 @@ class LocalGitSourceProvider {
365
411
  async function snapshotWorkingTreeUnlocked(options) {
366
412
  const dir = options.repoRoot ?? options.projectDir;
367
413
  const logger = options.logFile ? createFileLogger(options.logFile, "snapshot") : noopLogger;
368
- const cache = {};
414
+ const cache = options.cache ?? {};
369
415
  const stagingMarker = snapshotStagingMarkerPath(dir);
370
- const staleStaging = fs.existsSync(stagingMarker);
416
+ const staleStaging = gitFs.existsSync(stagingMarker);
371
417
  const changes = await listWorkdirChanges(dir, cache);
372
418
  const workdirClean = changes.adds.length === 0 && changes.removes.length === 0;
373
419
  if (workdirClean && !staleStaging) {
@@ -376,8 +422,8 @@ async function snapshotWorkingTreeUnlocked(options) {
376
422
  }
377
423
  if (workdirClean && staleStaging && await stageMatchesHead(dir, cache)) {
378
424
  logger.debug("snapshot", "stale marker outlived a completed commit — clearing, not recommitting");
379
- fs.rmSync(stagingMarker, { force: true });
380
- const [head2] = await git.log({ fs, dir, cache, depth: 1 });
425
+ gitFs.rmSync(stagingMarker, { force: true });
426
+ const [head2] = await git.log({ fs: gitFs, dir, cache, depth: 1 });
381
427
  return {
382
428
  id: head2.oid,
383
429
  message: head2.commit.message.trim(),
@@ -390,18 +436,18 @@ async function snapshotWorkingTreeUnlocked(options) {
390
436
  removes: changes.removes.length,
391
437
  ...staleStaging ? { recoveredStaleStaging: true } : {}
392
438
  });
393
- fs.writeFileSync(stagingMarker, "");
439
+ gitFs.writeFileSync(stagingMarker, "");
394
440
  await stageChanges(dir, changes, cache);
395
441
  const author = await resolveGitAuthor(dir, options.authorName, options.authorEmail);
396
442
  const id = await git.commit({
397
- fs,
443
+ fs: gitFs,
398
444
  dir,
399
445
  cache,
400
446
  message: options.message,
401
447
  author
402
448
  });
403
- fs.rmSync(stagingMarker, { force: true });
404
- const [head] = await git.log({ fs, dir, cache, depth: 1 });
449
+ gitFs.rmSync(stagingMarker, { force: true });
450
+ const [head] = await git.log({ fs: gitFs, dir, cache, depth: 1 });
405
451
  return {
406
452
  id,
407
453
  message: options.message,
@@ -458,4 +504,4 @@ async function restoreVersionWithBackup(options) {
458
504
  });
459
505
  }
460
506
 
461
- export { resolveLogger, gitScopeFor, HISTORY_PAGE_LIMIT, withRepoLock, __repoLockQueueSizeForTests, resolveGitAuthor, listWorkdirChanges, stageChanges, hasPendingChanges, hasUncommittedChanges, snapshotWorkingTreeUnlocked, isNoChangesError, providerFor, gitDirFor, snapshotStagingMarkerPath, RESTORE_BACKUP_MESSAGE, AUTO_SNAPSHOT_MESSAGE, restoreVersionWithBackup };
507
+ export { gitScopeFor, HISTORY_PAGE_LIMIT, withRepoLock, __repoLockQueueSizeForTests, resolveGitAuthor, listWorkdirChanges, stageChanges, hasPendingChanges, hasUncommittedChanges, snapshotWorkingTreeUnlocked, isNoChangesError, providerFor, gitDirFor, snapshotStagingMarkerPath, RESTORE_BACKUP_MESSAGE, AUTO_SNAPSHOT_MESSAGE, restoreVersionWithBackup };
@@ -4,7 +4,7 @@ import {
4
4
  // package.json
5
5
  var package_default = {
6
6
  name: "gutterpress",
7
- version: "0.10.0",
7
+ version: "0.10.1-beta.2",
8
8
  description: "Markdown-to-PDF converter for professional print layout using a native Chromium print engine and Ghostscript.",
9
9
  author: "itlackey",
10
10
  license: "MPL-2.0",
package/dist/cli.js CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  UsageError,
7
7
  package_default,
8
8
  rejectUnknownFlags
9
- } from "./cli-149edp6b.js";
9
+ } from "./cli-ydpf09d9.js";
10
10
  import {
11
11
  EXIT_CODES
12
12
  } from "./cli-46ycxe6r.js";
@@ -18,17 +18,16 @@ import {
18
18
  import { defineCommand, parseArgs, runMain } from "citty";
19
19
  import { statSync } from "node:fs";
20
20
  var SUBCOMMANDS = {
21
- new: () => import("./new-hvq0x91q.js").then((m) => m.default),
22
- preview: () => import("./preview-d4s6gk6p.js").then((m) => m.default),
23
- build: () => import("./build-6r502chw.js").then((m) => m.default),
24
- publish: () => import("./publish-tkc26en7.js").then((m) => m.default),
25
- lint: () => import("./lint-p2sw53d9.js").then((m) => m.default),
26
- validate: () => import("./validate-w9vfefrw.js").then((m) => m.default),
27
- audit: () => import("./audit-cvarpa72.js").then((m) => m.default),
28
- preflight: () => import("./preflight-4j00yd0g.js").then((m) => m.default),
29
- repair: () => import("./repair-2va4w12t.js").then((m) => m.default),
30
- doctor: () => import("./doctor-akvxbtjb.js").then((m) => m.default),
31
- plugin: () => import("./plugin-pssmk0dx.js").then((m) => m.default)
21
+ new: () => import("./new-xy2qc300.js").then((m) => m.default),
22
+ preview: () => import("./preview-h479apj9.js").then((m) => m.default),
23
+ build: () => import("./build-bj4x0727.js").then((m) => m.default),
24
+ publish: () => import("./publish-emk644a8.js").then((m) => m.default),
25
+ lint: () => import("./lint-c8ze8sqw.js").then((m) => m.default),
26
+ validate: () => import("./validate-be54bdc6.js").then((m) => m.default),
27
+ audit: () => import("./audit-dce99css.js").then((m) => m.default),
28
+ preflight: () => import("./preflight-prcvdvmk.js").then((m) => m.default),
29
+ doctor: () => import("./doctor-7nd6n2aa.js").then((m) => m.default),
30
+ plugin: () => import("./plugin-g9hwzjsm.js").then((m) => m.default)
32
31
  };
33
32
  var VERSION = package_default.version;
34
33
  var main = defineCommand({
@@ -53,7 +52,7 @@ async function preflightRequiredInvocations(rawArgs) {
53
52
  const [command, ...commandArgs] = rawArgs;
54
53
  try {
55
54
  if (command === "new") {
56
- const { newArgs } = await import("./new-hvq0x91q.js");
55
+ const { newArgs } = await import("./new-xy2qc300.js");
57
56
  rejectUnknownFlags(commandArgs, newArgs, "new");
58
57
  const parsed2 = parseArgs(commandArgs, {
59
58
  ...newArgs,
@@ -65,7 +64,7 @@ async function preflightRequiredInvocations(rawArgs) {
65
64
  return;
66
65
  }
67
66
  if (command === "preflight") {
68
- const { preflightArgs } = await import("./preflight-4j00yd0g.js");
67
+ const { preflightArgs } = await import("./preflight-prcvdvmk.js");
69
68
  rejectUnknownFlags(commandArgs, preflightArgs, "preflight");
70
69
  const parsed2 = parseArgs(commandArgs, {
71
70
  ...preflightArgs,
@@ -89,7 +88,7 @@ async function preflightRequiredInvocations(rawArgs) {
89
88
  if (subcommand !== "add") {
90
89
  throw new UsageError(`gutterpress plugin: unknown command "${subcommand}"`);
91
90
  }
92
- const { pluginAddArgs } = await import("./plugin-pssmk0dx.js");
91
+ const { pluginAddArgs } = await import("./plugin-g9hwzjsm.js");
93
92
  rejectUnknownFlags(subcommandArgs, pluginAddArgs, "plugin add");
94
93
  const parsed = parseArgs(subcommandArgs, {
95
94
  ...pluginAddArgs,
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  getSystemDiagnostics,
3
3
  log
4
- } from "./cli-cqtggsng.js";
4
+ } from "./cli-0z6zf98d.js";
5
5
  import {
6
6
  UsageError,
7
7
  rejectExtraPositionals,
8
8
  rejectUnknownFlags
9
- } from "./cli-149edp6b.js";
9
+ } from "./cli-ydpf09d9.js";
10
10
  import"./cli-c41yr7he.js";
11
11
  import"./cli-46ycxe6r.js";
12
12
  import"./cli-37x76zdn.js";
@@ -4,7 +4,7 @@ import {
4
4
  build,
5
5
  connectChromium,
6
6
  getBrowser
7
- } from "./cli-zfcryxg8.js";
7
+ } from "./cli-eewynen9.js";
8
8
  import"./cli-c41yr7he.js";
9
9
  import {
10
10
  BuildError
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  build
3
- } from "./index-wq3r5pj7.js";
3
+ } from "./index-p0ebr7dh.js";
4
4
  import {
5
5
  BuildError,
6
6
  RENDER_TIMEOUT_MS,
7
7
  assertMilestone,
8
8
  connectChromium,
9
9
  getBrowser
10
- } from "./index-ycpvr0am.js";
10
+ } from "./index-7hrvksrb.js";
11
11
  import"./index-37x76zdn.js";
12
12
 
13
13
  // src/lib/engine.ts