gutterpress 0.9.0-alpha.2 → 0.10.0-alpha.4

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 (138) hide show
  1. package/README.md +18 -4
  2. package/dist/api/index.d.ts +11 -5
  3. package/dist/api/index.js +20 -15
  4. package/dist/assets/preview/scripts/preview-bridge.d.ts +1 -0
  5. package/dist/assets/preview/scripts/preview-interface.d.ts +1 -0
  6. package/dist/{audit-nhn2pjz3.js → audit-k1vnfwvc.js} +10 -7
  7. package/dist/{build-san7fv2z.js → build-hqmwgvdw.js} +14 -8
  8. package/dist/checks/source/index.d.ts +1 -0
  9. package/dist/checks/source/layout-markers.d.ts +3 -0
  10. package/dist/checks/source/local-ref-parser.d.ts +28 -0
  11. package/dist/{cli-e5zhb0xs.js → cli-0r0tq16s.js} +17 -24
  12. package/dist/cli-46ycxe6r.js +18 -0
  13. package/dist/cli-c41yr7he.js +241 -0
  14. package/dist/cli-hp9r2pzt.js +2343 -0
  15. package/dist/{index-yzrh708h.js → cli-k1065rkg.js} +2 -5
  16. package/dist/{cli-k4bd06sd.js → cli-n25qycwz.js} +4986 -5889
  17. package/dist/{cli-najycadg.js → cli-ra0ed2xt.js} +69 -253
  18. package/dist/{cli-506tg37g.js → cli-revgt4pr.js} +2 -1
  19. package/dist/{cli-wchtvxvw.js → cli-v5mp7a6q.js} +14 -1
  20. package/dist/cli.js +20 -18
  21. package/dist/{doctor-hrk0kxxz.js → doctor-dxms7ehm.js} +4 -2
  22. package/dist/engine/compiler/build.d.ts +139 -0
  23. package/dist/engine/compiler/postprocess.d.ts +23 -0
  24. package/dist/engine/compiler/tier2.d.ts +78 -0
  25. package/dist/engine/shared/cdp.d.ts +104 -0
  26. package/dist/engine/shared/content-value.d.ts +64 -0
  27. package/dist/engine/shared/gcpm-extract.d.ts +119 -0
  28. package/dist/engine/shared/margin-box-support.d.ts +12 -0
  29. package/dist/engine/shared/pdf-inspect.d.ts +24 -0
  30. package/dist/engine/shared/synthesis.d.ts +155 -0
  31. package/dist/engine-wa7y9av9.js +41 -0
  32. package/dist/engine-z4p9sr4h.js +40 -0
  33. package/dist/gutterpress-agent-1ctgfz92.js +576 -0
  34. package/dist/gutterpress-viewer-cem7dmr5.js +2349 -0
  35. package/dist/{index-bynn850m.js → index-05y3dnxq.js} +3049 -4015
  36. package/dist/index-9tyq9kks.js +708 -0
  37. package/dist/{cli-yzrh708h.js → index-mdefp0y5.js} +1 -1
  38. package/dist/{index-wchtvxvw.js → index-v5mp7a6q.js} +14 -1
  39. package/dist/index-xxg4zfrg.js +1907 -0
  40. package/dist/index.d.ts +3 -1
  41. package/dist/index.js +24 -17
  42. package/dist/lib/asset-inline.d.ts +36 -0
  43. package/dist/lib/browser-pool.d.ts +18 -0
  44. package/dist/lib/build-error.d.ts +1 -1
  45. package/dist/lib/build-preflight.d.ts +35 -2
  46. package/dist/lib/build-runner.d.ts +45 -17
  47. package/dist/lib/build-staging.d.ts +9 -55
  48. package/dist/lib/cli-args.d.ts +8 -0
  49. package/dist/lib/desktop.d.ts +2 -2
  50. package/dist/lib/embedded-assets.d.ts +1 -1
  51. package/dist/lib/engine.d.ts +33 -0
  52. package/dist/lib/ghostscript.d.ts +46 -1
  53. package/dist/lib/markdown/assemble.d.ts +18 -10
  54. package/dist/lib/markdown/gp-pin-scope.d.ts +1 -0
  55. package/dist/lib/markdown/gutterpress-css.d.ts +125 -0
  56. package/dist/lib/markdown/images.d.ts +26 -0
  57. package/dist/lib/markdown/index.d.ts +4 -2
  58. package/dist/lib/markdown/inline-source.d.ts +10 -0
  59. package/dist/lib/markdown/markers.d.ts +32 -0
  60. package/dist/lib/markdown/renderer.d.ts +8 -3
  61. package/dist/lib/markdown/source-range.d.ts +61 -0
  62. package/dist/lib/missing-asset-placeholder.d.ts +52 -0
  63. package/dist/lib/presets.d.ts +1 -1
  64. package/dist/lib/printsafe.d.ts +2 -3
  65. package/dist/lib/remote-auth/converge-merge.d.ts +48 -0
  66. package/dist/lib/remote-auth/image-clash.d.ts +17 -0
  67. package/dist/lib/remote-auth/recovery/classify.d.ts +55 -67
  68. package/dist/lib/remote-auth/recovery/inspect.d.ts +14 -13
  69. package/dist/lib/remote-auth/recovery/locks.d.ts +20 -0
  70. package/dist/lib/remote-auth/recovery/repair.d.ts +29 -0
  71. package/dist/lib/remote-auth/recovery/types.d.ts +8 -204
  72. package/dist/lib/remote-auth/sync-messages.d.ts +2 -3
  73. package/dist/lib/remote-auth/sync-types.d.ts +35 -63
  74. package/dist/lib/remote-auth/sync.d.ts +11 -18
  75. package/dist/lib/remote-auth/transport.d.ts +14 -7
  76. package/dist/lib/theme-import.d.ts +4 -5
  77. package/dist/{lint-96j9hrj4.js → lint-xjwm5ep8.js} +10 -7
  78. package/dist/{manifest.schema-z61rzw44.json → manifest.schema-zxgxnbg7.json} +21 -0
  79. package/dist/{new-8p38wavc.js → new-kwdwpf0j.js} +12 -8
  80. package/dist/{plugin-ees6nhkc.js → plugin-rg4tnn96.js} +10 -7
  81. package/dist/{preflight-1q6c2edh.js → preflight-3127y25z.js} +10 -7
  82. package/dist/preview/file-watcher.d.ts +13 -17
  83. package/dist/preview/lifecycle.d.ts +1 -1
  84. package/dist/{pagedjs-bridge-vn4hk9fx.js → preview-bridge-fz7vpk8m.js} +8 -0
  85. package/dist/preview-interface-435cczt5.js +1059 -0
  86. package/dist/{preview-y5a2zen1.js → preview-ncgfhqmw.js} +16 -9
  87. package/dist/preview-shell-c5mfa3q0.js +346 -0
  88. package/dist/{project-source-p0gn1wd5.js → project-source-ekcyp63q.js} +1 -1
  89. package/dist/{publish-rm9yb3wh.js → publish-pr0rwh6p.js} +10 -7
  90. package/dist/render.d.ts +3 -4
  91. package/dist/render.js +728 -64
  92. package/dist/{repair-zgq7q2g6.js → repair-8270smfw.js} +45 -79
  93. package/dist/schema/manifest.types.d.ts +38 -0
  94. package/dist/{source-provider-c1rjm2c0.js → source-provider-3tcj6qg2.js} +2 -2
  95. package/dist/source-provider-vanafrt9.js +40 -0
  96. package/dist/{theme-zz2ktzqs.css → theme-h5recz6c.css} +8 -7
  97. package/dist/{theme-570zmh2t.css → theme-j2bagrfx.css} +8 -7
  98. package/dist/{theme-nya4nqh6.css → theme-nn6d53zy.css} +8 -7
  99. package/dist/types.d.ts +7 -0
  100. package/dist/{validate-nr0xa6sa.js → validate-54e17rae.js} +10 -7
  101. package/package.json +6 -6
  102. package/dist/cli-yja077f6.js +0 -92
  103. package/dist/git-http-yrb4ag6z.js +0 -17
  104. package/dist/index-yja077f6.js +0 -92
  105. package/dist/lib/markdown/markdown-it-paged.d.ts +0 -30
  106. package/dist/lib/pagedjs-marker.d.ts +0 -42
  107. package/dist/lib/pagedjs.d.ts +0 -26
  108. package/dist/lib/pagination.d.ts +0 -149
  109. package/dist/lib/remote-auth/conflict-resolution.d.ts +0 -29
  110. package/dist/lib/remote-auth/recovery/abort-interrupted-operation.d.ts +0 -103
  111. package/dist/lib/remote-auth/recovery/backup.d.ts +0 -113
  112. package/dist/lib/remote-auth/recovery/context.d.ts +0 -47
  113. package/dist/lib/remote-auth/recovery/dispatch.d.ts +0 -28
  114. package/dist/lib/remote-auth/recovery/failsafe.d.ts +0 -33
  115. package/dist/lib/remote-auth/recovery/manual-guidance.d.ts +0 -28
  116. package/dist/lib/remote-auth/recovery/outcome-mapping.d.ts +0 -59
  117. package/dist/lib/remote-auth/recovery/policy.d.ts +0 -47
  118. package/dist/lib/remote-auth/recovery/recover-auth.d.ts +0 -42
  119. package/dist/lib/remote-auth/recovery/recover-binary-conflict.d.ts +0 -37
  120. package/dist/lib/remote-auth/recovery/recover-corrupt-index.d.ts +0 -40
  121. package/dist/lib/remote-auth/recovery/recover-detached-head.d.ts +0 -70
  122. package/dist/lib/remote-auth/recovery/recover-interrupted-cherry-pick.d.ts +0 -23
  123. package/dist/lib/remote-auth/recovery/recover-interrupted-merge.d.ts +0 -28
  124. package/dist/lib/remote-auth/recovery/recover-interrupted-rebase.d.ts +0 -39
  125. package/dist/lib/remote-auth/recovery/recover-merge-conflict.d.ts +0 -34
  126. package/dist/lib/remote-auth/recovery/recover-missing-git-dir.d.ts +0 -37
  127. package/dist/lib/remote-auth/recovery/recover-missing-objects.d.ts +0 -56
  128. package/dist/lib/remote-auth/recovery/recover-network.d.ts +0 -34
  129. package/dist/lib/remote-auth/recovery/recover-non-fast-forward.d.ts +0 -27
  130. package/dist/lib/remote-auth/recovery/recover-stale-lock.d.ts +0 -68
  131. package/dist/lib/remote-auth/recovery/recover-unrelated-histories.d.ts +0 -44
  132. package/dist/lib/remote-auth/recovery/recover-wrong-remote.d.ts +0 -35
  133. package/dist/lib/remote-auth/resolution-plan.d.ts +0 -64
  134. package/dist/paged.polyfill-n95pbxfn.js +0 -33288
  135. package/dist/pagedjs-interface-qxvzgwd7.js +0 -557
  136. package/dist/preview-shell-6dqexx1m.js +0 -581
  137. /package/dist/assets/{preview/scripts/pagedjs-bridge.d.ts → engine/gutterpress-agent.d.ts} +0 -0
  138. /package/dist/assets/{preview/scripts/pagedjs-interface.d.ts → engine/gutterpress-viewer.d.ts} +0 -0
@@ -1,26 +1,25 @@
1
1
  import {
2
- buildRecoveryContext,
3
2
  classifyFromHealth,
4
- classifyGitError,
5
3
  inspectRepo,
6
4
  isAppHeartbeatFresh,
7
5
  isUnbornRepo,
8
- makeManualGuidance,
9
- recover,
6
+ repairRepo,
10
7
  verifyRepoReadable
11
- } from "./cli-k4bd06sd.js";
8
+ } from "./cli-n25qycwz.js";
12
9
  import {
13
10
  FileTokenStore,
14
11
  defaultConfigDir
15
- } from "./cli-najycadg.js";
12
+ } from "./cli-ra0ed2xt.js";
16
13
  import {
17
14
  UsageError,
18
15
  rejectExtraPositionals,
19
16
  rejectUnknownFlags
20
- } from "./cli-e5zhb0xs.js";
21
- import"./cli-yzrh708h.js";
22
- import"./cli-wchtvxvw.js";
23
- import"./cli-yja077f6.js";
17
+ } from "./cli-0r0tq16s.js";
18
+ import"./cli-hp9r2pzt.js";
19
+ import"./cli-c41yr7he.js";
20
+ import"./cli-46ycxe6r.js";
21
+ import"./cli-k1065rkg.js";
22
+ import"./cli-v5mp7a6q.js";
24
23
  import"./cli-37x76zdn.js";
25
24
 
26
25
  // src/commands/repair.ts
@@ -38,51 +37,6 @@ async function promptYesNo(question) {
38
37
  rl.close();
39
38
  }
40
39
  }
41
- function describeRepair(req) {
42
- const lines = [
43
- "",
44
- ` ${req.summary}`,
45
- "",
46
- ` • Changes your project files: ${req.willChangeLocalFiles ? "yes" : "no"}`,
47
- ` • Changes version-history internals: ${req.willChangeGitMetadata ? "yes" : "no"}`,
48
- ` • Changes anything online: ${req.willChangeRemote ? "yes" : "no"}`
49
- ];
50
- if (req.backupZipPath) {
51
- lines.push(` • Safety copy saved first: ${req.backupZipPath}`);
52
- }
53
- lines.push("");
54
- return lines.join(`
55
- `);
56
- }
57
- function printResult(result) {
58
- console.log(result.message);
59
- if ("guidance" in result && result.guidance) {
60
- const g = result.guidance;
61
- console.log(`
62
- Next step: ${g.recommendedNextStep}`);
63
- for (const step of g.safeNextSteps ?? [])
64
- console.log(` - ${step}`);
65
- if (g.supportDetails)
66
- console.log(`
67
- Details (for support): ${g.supportDetails}`);
68
- }
69
- if ("backupZipPath" in result && result.backupZipPath) {
70
- console.log(`
71
- Safety copy: ${result.backupZipPath}`);
72
- }
73
- }
74
- function terminalConfirmationGate(autoApprove) {
75
- return {
76
- confirmRepair: async (req) => {
77
- console.log(describeRepair(req));
78
- if (autoApprove) {
79
- console.log("Proceeding (--yes).");
80
- return true;
81
- }
82
- return promptYesNo("Apply this fix?");
83
- }
84
- };
85
- }
86
40
  var commandArgs = {
87
41
  dir: {
88
42
  type: "positional",
@@ -124,46 +78,58 @@ var repair_default = defineCommand({
124
78
  throw error;
125
79
  }
126
80
  const openedDir = path.resolve(args.dir ?? ".");
127
- const ctx = await buildRecoveryContext({
128
- projectDir: openedDir,
129
- confirmation: terminalConfirmationGate(args.yes),
130
- tokenStore: new FileTokenStore(defaultConfigDir())
131
- });
132
- const health = await inspectRepo({ repoDir: ctx.repoDir, source: ctx.source });
133
- let kind = classifyFromHealth(health, { minLockAgeMs: 0 });
134
- if (kind === null) {
81
+ const health = await inspectRepo({ repoDir: openedDir });
82
+ let needsRepair = classifyFromHealth(health, { minLockAgeMs: 0 }) !== null;
83
+ if (!needsRepair && health.hasGitDir) {
135
84
  try {
136
- await verifyRepoReadable(ctx.repoDir);
137
- } catch (err) {
138
- if (!isUnbornRepo(ctx.repoDir)) {
139
- kind = classifyGitError(err, health);
140
- }
85
+ await verifyRepoReadable(openedDir);
86
+ } catch {
87
+ if (!isUnbornRepo(openedDir))
88
+ needsRepair = true;
141
89
  }
142
90
  }
143
- if (kind === null) {
91
+ if (!health.hasGitDir)
92
+ needsRepair = true;
93
+ if (!needsRepair) {
144
94
  console.log("Your project's version history looks healthy. Nothing to repair.");
145
95
  return;
146
96
  }
147
- const guidance = makeManualGuidance(ctx, kind);
148
- console.log(`Found a problem: ${guidance.userSummary}`);
97
+ console.log("Found a problem with this project's version history.");
149
98
  if (args.check) {
150
- console.log(`
151
- Run \`gutterpress repair\` to fix it. ${guidance.recommendedNextStep}`);
99
+ console.log("\nRun `gutterpress repair` to fix it. Your files will not be changed.");
152
100
  process.exitCode = 1;
153
101
  return;
154
102
  }
155
- if (!args.force && await isAppHeartbeatFresh(ctx.repoDir)) {
103
+ if (!args.force && await isAppHeartbeatFresh(openedDir)) {
156
104
  console.log(`
157
105
  The Gutterpress app appears to have this project open. Close it first, or re-run with --force.`);
158
106
  process.exitCode = 1;
159
107
  return;
160
108
  }
161
- const result = await recover(kind, ctx);
162
- console.log("");
163
- printResult(result);
164
- if (result.status !== "recovered" && result.status !== "retry_later") {
165
- process.exitCode = 1;
109
+ if (!args.yes) {
110
+ console.log(`
111
+ The repair never changes your project files. If history has to be rebuilt,
112
+ ` + `the old history folder is kept on disk as a backup and your saved versions
113
+ ` + "are brought back into it wherever they are still readable.");
114
+ if (!await promptYesNo("Repair now?")) {
115
+ console.log("Nothing was changed.");
116
+ process.exitCode = 1;
117
+ return;
118
+ }
166
119
  }
120
+ const result = await repairRepo({
121
+ projectDir: openedDir,
122
+ tokenStore: new FileTokenStore(defaultConfigDir())
123
+ });
124
+ console.log(`
125
+ ${result.message}`);
126
+ for (const action of result.actions)
127
+ console.log(` - ${action}`);
128
+ if (result.damagedGitBackupPath) {
129
+ console.log(` - Old history kept at: ${result.damagedGitBackupPath}`);
130
+ }
131
+ if (result.status !== "repaired")
132
+ process.exitCode = 1;
167
133
  }
168
134
  });
169
135
  export {
@@ -66,6 +66,27 @@ export interface GutterpressManifest {
66
66
  publish?: PublishSettings;
67
67
  /** How the book is designed (ADR 0008). The registry in lib/presets.ts is authoritative. */
68
68
  preset?: "dtrpg" | "book" | "custom";
69
+ /**
70
+ * Pagination engine. Paged.js has been removed (native-only-migration-
71
+ * plan.md Phase 6) — the Gutterpress engine (`src/engine/`, native Chromium
72
+ * pagination) is the only engine. This field and `--engine` on the CLI are
73
+ * accepted-but-ignored for backward compatibility: an explicit "paged"
74
+ * produces a one-line warning and the build proceeds natively regardless.
75
+ */
76
+ engine?: "paged" | "native";
77
+ /**
78
+ * Engine-conditional stylesheets, appended AFTER `styles`. `.native` is the
79
+ * only list that still applies; `.paged` is accepted-but-ignored (a warning
80
+ * fires if it has entries) now that Paged.js has been removed.
81
+ */
82
+ engineStyles?: {
83
+ /**
84
+ * REMOVED — Paged.js has been deleted. Accepted for backward-compatible
85
+ * manifest parsing only; entries here are ignored with a warning.
86
+ */
87
+ paged?: string[];
88
+ native?: string[];
89
+ };
69
90
  /**
70
91
  * Where the book is published (ADR 0008): publish-target ids whose
71
92
  * validation policies this book is checked against. Absent = the preset's
@@ -83,6 +104,15 @@ export interface GutterpressManifest {
83
104
  icc?: string;
84
105
  stripAnnotations?: boolean;
85
106
  };
107
+ /**
108
+ * Native-engine print-production options with no other manifest home
109
+ * (`engine/compiler/postprocess.ts` already implements them; this is the
110
+ * missing manifest surface for reaching them — B.12).
111
+ */
112
+ print?: {
113
+ /** Pad the PDF with blank pages until pageCount is a multiple of this. */
114
+ signature?: number;
115
+ };
86
116
  page?: {
87
117
  width?: number;
88
118
  height?: number;
@@ -163,6 +193,11 @@ export interface ResolvedPluginConfig {
163
193
  export interface ResolvedConfig {
164
194
  title: string;
165
195
  authors: string[];
196
+ /**
197
+ * Resolved pagination engine — always "native"; Paged.js has been removed.
198
+ * See {@link GutterpressManifest.engine}.
199
+ */
200
+ engine: "paged" | "native";
166
201
  /** Validated publish-target ids for this book (may be empty). */
167
202
  targets: string[];
168
203
  styles?: string[];
@@ -175,6 +210,9 @@ export interface ResolvedConfig {
175
210
  icc: string;
176
211
  stripAnnotations: boolean;
177
212
  };
213
+ print: {
214
+ signature: number;
215
+ };
178
216
  page: {
179
217
  width: number;
180
218
  height: number;
@@ -16,8 +16,8 @@ import {
16
16
  snapshotWorkingTreeUnlocked,
17
17
  stageChanges,
18
18
  withRepoLock
19
- } from "./cli-yzrh708h.js";
20
- import"./cli-wchtvxvw.js";
19
+ } from "./cli-k1065rkg.js";
20
+ import"./cli-v5mp7a6q.js";
21
21
  import"./cli-37x76zdn.js";
22
22
  export {
23
23
  withRepoLock,
@@ -0,0 +1,40 @@
1
+ import {
2
+ AUTO_SNAPSHOT_MESSAGE,
3
+ HISTORY_PAGE_LIMIT,
4
+ RESTORE_BACKUP_MESSAGE,
5
+ __repoLockQueueSizeForTests,
6
+ gitDirFor,
7
+ gitScopeFor,
8
+ hasPendingChanges,
9
+ hasUncommittedChanges,
10
+ isNoChangesError,
11
+ listWorkdirChanges,
12
+ providerFor,
13
+ resolveGitAuthor,
14
+ restoreVersionWithBackup,
15
+ snapshotStagingMarkerPath,
16
+ snapshotWorkingTreeUnlocked,
17
+ stageChanges,
18
+ withRepoLock
19
+ } from "./index-mdefp0y5.js";
20
+ import"./index-v5mp7a6q.js";
21
+ import"./index-37x76zdn.js";
22
+ export {
23
+ withRepoLock,
24
+ stageChanges,
25
+ snapshotWorkingTreeUnlocked,
26
+ snapshotStagingMarkerPath,
27
+ restoreVersionWithBackup,
28
+ resolveGitAuthor,
29
+ providerFor,
30
+ listWorkdirChanges,
31
+ isNoChangesError,
32
+ hasUncommittedChanges,
33
+ hasPendingChanges,
34
+ gitScopeFor,
35
+ gitDirFor,
36
+ __repoLockQueueSizeForTests,
37
+ RESTORE_BACKUP_MESSAGE,
38
+ HISTORY_PAGE_LIMIT,
39
+ AUTO_SNAPSHOT_MESSAGE
40
+ };
@@ -14,9 +14,10 @@
14
14
  --font-display: "Impact", "Haettenschweiler", "Arial Black", sans-serif;
15
15
  --font-mono: "Courier New", monospace;
16
16
 
17
- --scale-h1: 2.8rem;
18
- --scale-h2: 1.8rem;
19
- --scale-h3: 1.3rem;
17
+ --fs-body: 10pt;
18
+ --fs-h1: 2.8rem;
19
+ --fs-h2: 1.8rem;
20
+ --fs-h3: 1.3rem;
20
21
  --leading: 1.4;
21
22
  }
22
23
 
@@ -30,7 +31,7 @@ body {
30
31
  background: var(--color-paper);
31
32
  font-family: var(--font-body);
32
33
  line-height: var(--leading);
33
- font-size: 10pt;
34
+ font-size: var(--fs-body);
34
35
  }
35
36
 
36
37
  h1, h2, h3 {
@@ -41,9 +42,9 @@ h1, h2, h3 {
41
42
  line-height: 0.95;
42
43
  font-weight: 900;
43
44
  }
44
- h1 { font-size: var(--scale-h1); margin: 0 0 0.4em; }
45
- h2 { font-size: var(--scale-h2); margin: 1.1em 0 0.3em; }
46
- h3 { font-size: var(--scale-h3); margin: 1em 0 0.25em; }
45
+ h1 { font-size: var(--fs-h1); margin: 0 0 0.4em; }
46
+ h2 { font-size: var(--fs-h2); margin: 1.1em 0 0.3em; }
47
+ h3 { font-size: var(--fs-h3); margin: 1em 0 0.25em; }
47
48
 
48
49
  p { margin: 0 0 0.6em; }
49
50
 
@@ -14,9 +14,10 @@
14
14
  --font-display: "Georgia", "Times New Roman", serif;
15
15
  --font-mono: "Menlo", "Consolas", monospace;
16
16
 
17
- --scale-h1: 2.1rem;
18
- --scale-h2: 1.5rem;
19
- --scale-h3: 1.2rem;
17
+ --fs-body: 11pt;
18
+ --fs-h1: 2.1rem;
19
+ --fs-h2: 1.5rem;
20
+ --fs-h3: 1.2rem;
20
21
  --leading: 1.55;
21
22
  }
22
23
 
@@ -30,7 +31,7 @@ body {
30
31
  background: var(--color-paper);
31
32
  font-family: var(--font-body);
32
33
  line-height: var(--leading);
33
- font-size: 11pt;
34
+ font-size: var(--fs-body);
34
35
  }
35
36
 
36
37
  h1, h2, h3 {
@@ -39,9 +40,9 @@ h1, h2, h3 {
39
40
  line-height: 1.2;
40
41
  font-weight: 600;
41
42
  }
42
- h1 { font-size: var(--scale-h1); margin: 0 0 0.6em; }
43
- h2 { font-size: var(--scale-h2); margin: 1.4em 0 0.4em; }
44
- h3 { font-size: var(--scale-h3); margin: 1.2em 0 0.3em; }
43
+ h1 { font-size: var(--fs-h1); margin: 0 0 0.6em; }
44
+ h2 { font-size: var(--fs-h2); margin: 1.4em 0 0.4em; }
45
+ h3 { font-size: var(--fs-h3); margin: 1.2em 0 0.3em; }
45
46
 
46
47
  p { margin: 0 0 0.8em; text-align: justify; hyphens: auto; }
47
48
 
@@ -15,9 +15,10 @@
15
15
  --font-display: "Helvetica Neue", "Segoe UI", Arial, sans-serif;
16
16
  --font-mono: "SFMono-Regular", "Consolas", "Menlo", monospace;
17
17
 
18
- --scale-h1: 2.0rem;
19
- --scale-h2: 1.45rem;
20
- --scale-h3: 1.15rem;
18
+ --fs-body: 10.5pt;
19
+ --fs-h1: 2.0rem;
20
+ --fs-h2: 1.45rem;
21
+ --fs-h3: 1.15rem;
21
22
  --leading: 1.5;
22
23
  }
23
24
 
@@ -31,7 +32,7 @@ body {
31
32
  background: var(--color-paper);
32
33
  font-family: var(--font-body);
33
34
  line-height: var(--leading);
34
- font-size: 10.5pt;
35
+ font-size: var(--fs-body);
35
36
  }
36
37
 
37
38
  h1, h2, h3 {
@@ -40,9 +41,9 @@ h1, h2, h3 {
40
41
  font-weight: 600;
41
42
  line-height: 1.25;
42
43
  }
43
- h1 { font-size: var(--scale-h1); margin: 0 0 0.5em; color: var(--color-accent); }
44
- h2 { font-size: var(--scale-h2); margin: 1.4em 0 0.4em; border-bottom: 1px solid var(--color-rule); padding-bottom: 0.15em; }
45
- h3 { font-size: var(--scale-h3); margin: 1.2em 0 0.3em; }
44
+ h1 { font-size: var(--fs-h1); margin: 0 0 0.5em; color: var(--color-accent); }
45
+ h2 { font-size: var(--fs-h2); margin: 1.4em 0 0.4em; border-bottom: 1px solid var(--color-rule); padding-bottom: 0.15em; }
46
+ h3 { font-size: var(--fs-h3); margin: 1.2em 0 0.3em; }
46
47
 
47
48
  p { margin: 0 0 0.7em; }
48
49
 
package/dist/types.d.ts CHANGED
@@ -27,4 +27,11 @@ export interface PreviewServerOptions {
27
27
  noWatch: boolean;
28
28
  /** Automatically open browser (default: true) */
29
29
  openBrowser: boolean;
30
+ /**
31
+ * CLI `--engine` override, fed into {@link resolveConfig} the same way
32
+ * `build`'s does (MIGRATION.md Decision #5 — preview and PDF switch
33
+ * together, per project, behind one flag). `undefined` defers to the
34
+ * manifest's `engine:` field (or the "native" default).
35
+ */
36
+ engine?: "paged" | "native";
30
37
  }
@@ -1,18 +1,21 @@
1
1
  import {
2
2
  executeAndReport
3
- } from "./cli-k4bd06sd.js";
3
+ } from "./cli-n25qycwz.js";
4
4
  import {
5
5
  log
6
- } from "./cli-najycadg.js";
6
+ } from "./cli-ra0ed2xt.js";
7
7
  import {
8
- EXIT_CODES,
9
8
  UsageError,
10
9
  rejectExtraPositionals,
11
10
  rejectUnknownFlags
12
- } from "./cli-e5zhb0xs.js";
13
- import"./cli-yzrh708h.js";
14
- import"./cli-wchtvxvw.js";
15
- import"./cli-yja077f6.js";
11
+ } from "./cli-0r0tq16s.js";
12
+ import"./cli-hp9r2pzt.js";
13
+ import"./cli-c41yr7he.js";
14
+ import {
15
+ EXIT_CODES
16
+ } from "./cli-46ycxe6r.js";
17
+ import"./cli-k1065rkg.js";
18
+ import"./cli-v5mp7a6q.js";
16
19
  import"./cli-37x76zdn.js";
17
20
 
18
21
  // src/commands/validate.ts
package/package.json CHANGED
@@ -1,14 +1,13 @@
1
1
  {
2
2
  "name": "gutterpress",
3
- "version": "0.9.0-alpha.2",
4
- "description": "Markdown-to-PDF converter for professional print layout using Paged.js and Ghostscript.",
3
+ "version": "0.10.0-alpha.4",
4
+ "description": "Markdown-to-PDF converter for professional print layout using a native Chromium print engine and Ghostscript.",
5
5
  "author": "itlackey",
6
6
  "license": "MPL-2.0",
7
7
  "keywords": [
8
8
  "markdown",
9
9
  "pdf",
10
10
  "print",
11
- "pagedjs",
12
11
  "ghostscript",
13
12
  "book",
14
13
  "publishing",
@@ -48,11 +47,13 @@
48
47
  "LICENSE"
49
48
  ],
50
49
  "scripts": {
51
- "build:library": "rimraf dist && bun build src/index.ts src/api/index.ts --target=node --packages=external --splitting --outdir=dist && bun build src/render.ts --target=node --packages=external --outdir=dist && node scripts/check-render-pure.mjs && tsc -p tsconfig.build.json",
50
+ "build:library": "bun scripts/build-engine-bundles.mjs && rimraf dist && bun build src/index.ts src/api/index.ts --target=node --packages=external --splitting --outdir=dist && bun build src/render.ts --target=node --packages=external --outdir=dist && node scripts/check-render-pure.mjs && tsc -p tsconfig.build.json",
52
51
  "build": "bun run build:library && bun build src/cli.ts --target=node --packages=external --splitting --outdir=dist",
53
52
  "prepublishOnly": "bun run build",
54
53
  "test": "bun test",
55
- "typecheck": "tsc --noEmit"
54
+ "typecheck": "tsc --noEmit",
55
+ "typecheck:engine-browser": "tsc --noEmit -p src/engine/browser.tsconfig.json",
56
+ "parity:gate": "bun scripts/native-parity-gate.ts"
56
57
  },
57
58
  "engines": {
58
59
  "bun": ">=1.0.0",
@@ -94,7 +95,6 @@
94
95
  "@types/node": "^22.0.0",
95
96
  "@types/semver": "^7.7.1",
96
97
  "@types/ws": "^8.5.13",
97
- "pagedjs": "^0.4.3",
98
98
  "playwright": "^1.60.0",
99
99
  "rimraf": "^6.0.0",
100
100
  "typescript": "^5"
@@ -1,92 +0,0 @@
1
- // src/lib/remote-auth/git-http.ts
2
- import httpNode from "isomorphic-git/http/node";
3
- var GIT_HTTP_IDLE_TIMEOUT_MS = 60000;
4
- var GIT_HTTP_UPLOAD_TIMEOUT_MS = 30 * 60000;
5
- var SMALL_BODY_MAX_BYTES = 256 * 1024;
6
- function isSmallBody(body) {
7
- if (!Array.isArray(body))
8
- return false;
9
- let total = 0;
10
- for (const c of body) {
11
- const size = c?.byteLength;
12
- if (typeof size !== "number")
13
- return false;
14
- total += size;
15
- }
16
- return total <= SMALL_BODY_MAX_BYTES;
17
- }
18
- function gitTimeoutError(what, ms) {
19
- return new Error(`Git network operation timed out after ${Math.round(ms / 1000)}s (${what}); ` + `couldn't reach the remote (ETIMEDOUT).`);
20
- }
21
- function withIdleTimeout(http, idleMs = GIT_HTTP_IDLE_TIMEOUT_MS, uploadMs = GIT_HTTP_UPLOAD_TIMEOUT_MS) {
22
- return {
23
- async request(options) {
24
- let timer;
25
- let trip;
26
- const tripped = new Promise((_, reject) => {
27
- trip = reject;
28
- });
29
- tripped.catch(() => {});
30
- const arm = (ms, what) => {
31
- if (timer)
32
- clearTimeout(timer);
33
- timer = setTimeout(() => trip(gitTimeoutError(what, ms)), ms);
34
- timer.unref?.();
35
- };
36
- const disarm = () => {
37
- if (timer)
38
- clearTimeout(timer);
39
- timer = undefined;
40
- };
41
- const race = (p) => Promise.race([p, tripped]).catch((e) => {
42
- p.catch(() => {});
43
- throw e;
44
- });
45
- const body = options.body;
46
- const isLargeUpload = body != null && !isSmallBody(body);
47
- arm(isLargeUpload ? uploadMs : idleMs, isLargeUpload ? "the upload did not complete" : "the remote did not respond");
48
- let res;
49
- try {
50
- res = await race(http.request(options));
51
- } finally {
52
- disarm();
53
- }
54
- const rawBody = res.body;
55
- if (!rawBody || typeof rawBody[Symbol.asyncIterator] !== "function") {
56
- return res;
57
- }
58
- const source = rawBody[Symbol.asyncIterator]();
59
- const guardedBody = {
60
- async next() {
61
- arm(idleMs, "the remote stopped sending data");
62
- try {
63
- const step = await race(source.next());
64
- disarm();
65
- return step;
66
- } catch (e) {
67
- disarm();
68
- try {
69
- Promise.resolve(source.return?.()).catch(() => {});
70
- } catch {}
71
- throw e;
72
- }
73
- },
74
- return(value) {
75
- disarm();
76
- try {
77
- return Promise.resolve(source.return?.(value) ?? { done: true, value: undefined });
78
- } catch {
79
- return Promise.resolve({ done: true, value: undefined });
80
- }
81
- },
82
- [Symbol.asyncIterator]() {
83
- return this;
84
- }
85
- };
86
- return { ...res, body: guardedBody };
87
- }
88
- };
89
- }
90
- var defaultGitHttp = withIdleTimeout(httpNode);
91
-
92
- export { GIT_HTTP_IDLE_TIMEOUT_MS, GIT_HTTP_UPLOAD_TIMEOUT_MS, SMALL_BODY_MAX_BYTES, isSmallBody, withIdleTimeout, defaultGitHttp };
@@ -1,17 +0,0 @@
1
- import {
2
- GIT_HTTP_IDLE_TIMEOUT_MS,
3
- GIT_HTTP_UPLOAD_TIMEOUT_MS,
4
- SMALL_BODY_MAX_BYTES,
5
- defaultGitHttp,
6
- isSmallBody,
7
- withIdleTimeout
8
- } from "./cli-yja077f6.js";
9
- import"./cli-37x76zdn.js";
10
- export {
11
- withIdleTimeout,
12
- isSmallBody,
13
- defaultGitHttp,
14
- SMALL_BODY_MAX_BYTES,
15
- GIT_HTTP_UPLOAD_TIMEOUT_MS,
16
- GIT_HTTP_IDLE_TIMEOUT_MS
17
- };
@@ -1,92 +0,0 @@
1
- // src/lib/remote-auth/git-http.ts
2
- import httpNode from "isomorphic-git/http/node";
3
- var GIT_HTTP_IDLE_TIMEOUT_MS = 60000;
4
- var GIT_HTTP_UPLOAD_TIMEOUT_MS = 30 * 60000;
5
- var SMALL_BODY_MAX_BYTES = 256 * 1024;
6
- function isSmallBody(body) {
7
- if (!Array.isArray(body))
8
- return false;
9
- let total = 0;
10
- for (const c of body) {
11
- const size = c?.byteLength;
12
- if (typeof size !== "number")
13
- return false;
14
- total += size;
15
- }
16
- return total <= SMALL_BODY_MAX_BYTES;
17
- }
18
- function gitTimeoutError(what, ms) {
19
- return new Error(`Git network operation timed out after ${Math.round(ms / 1000)}s (${what}); ` + `couldn't reach the remote (ETIMEDOUT).`);
20
- }
21
- function withIdleTimeout(http, idleMs = GIT_HTTP_IDLE_TIMEOUT_MS, uploadMs = GIT_HTTP_UPLOAD_TIMEOUT_MS) {
22
- return {
23
- async request(options) {
24
- let timer;
25
- let trip;
26
- const tripped = new Promise((_, reject) => {
27
- trip = reject;
28
- });
29
- tripped.catch(() => {});
30
- const arm = (ms, what) => {
31
- if (timer)
32
- clearTimeout(timer);
33
- timer = setTimeout(() => trip(gitTimeoutError(what, ms)), ms);
34
- timer.unref?.();
35
- };
36
- const disarm = () => {
37
- if (timer)
38
- clearTimeout(timer);
39
- timer = undefined;
40
- };
41
- const race = (p) => Promise.race([p, tripped]).catch((e) => {
42
- p.catch(() => {});
43
- throw e;
44
- });
45
- const body = options.body;
46
- const isLargeUpload = body != null && !isSmallBody(body);
47
- arm(isLargeUpload ? uploadMs : idleMs, isLargeUpload ? "the upload did not complete" : "the remote did not respond");
48
- let res;
49
- try {
50
- res = await race(http.request(options));
51
- } finally {
52
- disarm();
53
- }
54
- const rawBody = res.body;
55
- if (!rawBody || typeof rawBody[Symbol.asyncIterator] !== "function") {
56
- return res;
57
- }
58
- const source = rawBody[Symbol.asyncIterator]();
59
- const guardedBody = {
60
- async next() {
61
- arm(idleMs, "the remote stopped sending data");
62
- try {
63
- const step = await race(source.next());
64
- disarm();
65
- return step;
66
- } catch (e) {
67
- disarm();
68
- try {
69
- Promise.resolve(source.return?.()).catch(() => {});
70
- } catch {}
71
- throw e;
72
- }
73
- },
74
- return(value) {
75
- disarm();
76
- try {
77
- return Promise.resolve(source.return?.(value) ?? { done: true, value: undefined });
78
- } catch {
79
- return Promise.resolve({ done: true, value: undefined });
80
- }
81
- },
82
- [Symbol.asyncIterator]() {
83
- return this;
84
- }
85
- };
86
- return { ...res, body: guardedBody };
87
- }
88
- };
89
- }
90
- var defaultGitHttp = withIdleTimeout(httpNode);
91
-
92
- export { GIT_HTTP_IDLE_TIMEOUT_MS, GIT_HTTP_UPLOAD_TIMEOUT_MS, SMALL_BODY_MAX_BYTES, isSmallBody, withIdleTimeout, defaultGitHttp };