gutterpress 0.0.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.
Files changed (230) hide show
  1. package/README.md +422 -0
  2. package/dist/CGATS21_CRPC1-g0e3k7kr.icc +0 -0
  3. package/dist/api/index.d.ts +76 -0
  4. package/dist/api/index.js +272 -0
  5. package/dist/assets/preview/scripts/pagedjs-bridge.d.ts +1 -0
  6. package/dist/assets/preview/scripts/pagedjs-interface.d.ts +1 -0
  7. package/dist/assets/preview/scripts/preview-shell.d.ts +1 -0
  8. package/dist/audit-1jrwwacz.js +66 -0
  9. package/dist/build-5s92kgpc.js +77 -0
  10. package/dist/chapter-01-6fn9pvd0.md +31 -0
  11. package/dist/chapter-01-7jwqg1ct.md +20 -0
  12. package/dist/chapter-01-jj8ftn4c.md +29 -0
  13. package/dist/chapter-01-rkpyvjna.md +26 -0
  14. package/dist/checks/asset/approved-fonts.d.ts +3 -0
  15. package/dist/checks/asset/extensions.d.ts +41 -0
  16. package/dist/checks/asset/font-license.d.ts +3 -0
  17. package/dist/checks/asset/image-alpha.d.ts +3 -0
  18. package/dist/checks/asset/image-color-space.d.ts +3 -0
  19. package/dist/checks/asset/image-file-size.d.ts +3 -0
  20. package/dist/checks/asset/image-resolution.d.ts +3 -0
  21. package/dist/checks/asset/image-tac.d.ts +3 -0
  22. package/dist/checks/asset/index.d.ts +7 -0
  23. package/dist/checks/formatter.d.ts +3 -0
  24. package/dist/checks/heuristic/index.d.ts +4 -0
  25. package/dist/checks/heuristic/layer-count.d.ts +3 -0
  26. package/dist/checks/heuristic/placement-variance.d.ts +3 -0
  27. package/dist/checks/heuristic/section-density.d.ts +3 -0
  28. package/dist/checks/heuristic/text-density.d.ts +3 -0
  29. package/dist/checks/pdf/bleed.d.ts +3 -0
  30. package/dist/checks/pdf/bookmarks.d.ts +3 -0
  31. package/dist/checks/pdf/color-spaces.d.ts +3 -0
  32. package/dist/checks/pdf/cross-refs.d.ts +3 -0
  33. package/dist/checks/pdf/embedded-fonts.d.ts +3 -0
  34. package/dist/checks/pdf/image-resolution.d.ts +3 -0
  35. package/dist/checks/pdf/index.d.ts +15 -0
  36. package/dist/checks/pdf/ink-coverage.d.ts +3 -0
  37. package/dist/checks/pdf/page-labels.d.ts +3 -0
  38. package/dist/checks/pdf/page-size.d.ts +3 -0
  39. package/dist/checks/pdf/pdfx-markers.d.ts +3 -0
  40. package/dist/checks/pdf/pdfx-metadata.d.ts +3 -0
  41. package/dist/checks/pdf/pdfx-structure.d.ts +6 -0
  42. package/dist/checks/pdf/qpdf-structure.d.ts +3 -0
  43. package/dist/checks/pdf/rasterized-pages.d.ts +3 -0
  44. package/dist/checks/pdf/toc-links.d.ts +3 -0
  45. package/dist/checks/pdf/transparency.d.ts +3 -0
  46. package/dist/checks/policy.d.ts +61 -0
  47. package/dist/checks/register-builtins.d.ts +17 -0
  48. package/dist/checks/registry.d.ts +40 -0
  49. package/dist/checks/runner.d.ts +25 -0
  50. package/dist/checks/source/accessibility-alt-text.d.ts +3 -0
  51. package/dist/checks/source/accessibility-heading-order.d.ts +3 -0
  52. package/dist/checks/source/config-file.d.ts +8 -0
  53. package/dist/checks/source/htmlhint.d.ts +3 -0
  54. package/dist/checks/source/index.d.ts +6 -0
  55. package/dist/checks/source/local-refs.d.ts +3 -0
  56. package/dist/checks/source/markdownlint.d.ts +3 -0
  57. package/dist/checks/source/stylelint.d.ts +3 -0
  58. package/dist/checks/tool-check.d.ts +23 -0
  59. package/dist/checks/types.d.ts +52 -0
  60. package/dist/cli-1tyj4bk3.js +124 -0
  61. package/dist/cli-37x76zdn.js +4 -0
  62. package/dist/cli-506tg37g.js +26 -0
  63. package/dist/cli-5bxx0c4y.js +464 -0
  64. package/dist/cli-7ykx7pp0.js +12378 -0
  65. package/dist/cli-h7phg3ka.js +746 -0
  66. package/dist/cli-hvqjs342.js +284 -0
  67. package/dist/cli-yja077f6.js +92 -0
  68. package/dist/cli.js +157 -0
  69. package/dist/constants.d.ts +17 -0
  70. package/dist/doctor-25zjt8dz.js +57 -0
  71. package/dist/favicon-wkbm9cjn.ico +0 -0
  72. package/dist/git-http-yrb4ag6z.js +17 -0
  73. package/dist/index-1tyj4bk3.js +124 -0
  74. package/dist/index-37x76zdn.js +4 -0
  75. package/dist/index-3h3fef7r.js +15218 -0
  76. package/dist/index-5bxx0c4y.js +464 -0
  77. package/dist/index-yja077f6.js +92 -0
  78. package/dist/index.d.ts +32 -0
  79. package/dist/index.js +310 -0
  80. package/dist/lib/app-heartbeat.d.ts +102 -0
  81. package/dist/lib/asset-inline.d.ts +73 -0
  82. package/dist/lib/browser-pool.d.ts +17 -0
  83. package/dist/lib/build-error.d.ts +52 -0
  84. package/dist/lib/build-fingerprint.d.ts +15 -0
  85. package/dist/lib/build-preflight.d.ts +43 -0
  86. package/dist/lib/build-runner.d.ts +161 -0
  87. package/dist/lib/build-staging.d.ts +64 -0
  88. package/dist/lib/chromium.d.ts +20 -0
  89. package/dist/lib/cli-args.d.ts +45 -0
  90. package/dist/lib/desktop.d.ts +14 -0
  91. package/dist/lib/diagnostics.d.ts +64 -0
  92. package/dist/lib/embedded-assets.d.ts +29 -0
  93. package/dist/lib/exec.d.ts +84 -0
  94. package/dist/lib/fetch-timeout.d.ts +41 -0
  95. package/dist/lib/ghostscript.d.ts +48 -0
  96. package/dist/lib/host-policy.d.ts +75 -0
  97. package/dist/lib/image-inspect.d.ts +32 -0
  98. package/dist/lib/install-hints.d.ts +21 -0
  99. package/dist/lib/lint-runner.d.ts +10 -0
  100. package/dist/lib/manifest-config.d.ts +31 -0
  101. package/dist/lib/manifest-doc.d.ts +25 -0
  102. package/dist/lib/manifest.d.ts +41 -0
  103. package/dist/lib/markdown/assemble.d.ts +78 -0
  104. package/dist/lib/markdown/chapter-id.d.ts +24 -0
  105. package/dist/lib/markdown/images.d.ts +34 -0
  106. package/dist/lib/markdown/index.d.ts +78 -0
  107. package/dist/lib/markdown/markdown-it-paged.d.ts +30 -0
  108. package/dist/lib/markdown/plugins.d.ts +69 -0
  109. package/dist/lib/markdown/renderer.d.ts +111 -0
  110. package/dist/lib/npm-plugin-installer.d.ts +33 -0
  111. package/dist/lib/open-path.d.ts +5 -0
  112. package/dist/lib/output-paths.d.ts +23 -0
  113. package/dist/lib/pagedjs-marker.d.ts +42 -0
  114. package/dist/lib/pagedjs.d.ts +26 -0
  115. package/dist/lib/pagination.d.ts +169 -0
  116. package/dist/lib/pdf-inspect.d.ts +123 -0
  117. package/dist/lib/pdf-parse.d.ts +57 -0
  118. package/dist/lib/plugin-manager.d.ts +108 -0
  119. package/dist/lib/plugin-vendor.d.ts +107 -0
  120. package/dist/lib/presets.d.ts +45 -0
  121. package/dist/lib/printsafe.d.ts +17 -0
  122. package/dist/lib/project-scaffold.d.ts +116 -0
  123. package/dist/lib/project-source.d.ts +140 -0
  124. package/dist/lib/project-templates.d.ts +49 -0
  125. package/dist/lib/publish/butler.d.ts +10 -0
  126. package/dist/lib/publish/command-runner.d.ts +18 -0
  127. package/dist/lib/publish/connect.d.ts +23 -0
  128. package/dist/lib/publish/manifest-publish.d.ts +9 -0
  129. package/dist/lib/publish/providers/azure-swa.d.ts +3 -0
  130. package/dist/lib/publish/providers/drivethrurpg.d.ts +10 -0
  131. package/dist/lib/publish/providers/guided.d.ts +3 -0
  132. package/dist/lib/publish/providers/itch.d.ts +5 -0
  133. package/dist/lib/publish/providers/kdp.d.ts +9 -0
  134. package/dist/lib/publish/providers/shopify.d.ts +5 -0
  135. package/dist/lib/publish/registry.d.ts +5 -0
  136. package/dist/lib/publish/run-publish.d.ts +30 -0
  137. package/dist/lib/publish/selections.d.ts +25 -0
  138. package/dist/lib/publish/types.d.ts +258 -0
  139. package/dist/lib/remote-auth/clone.d.ts +87 -0
  140. package/dist/lib/remote-auth/conflict-resolution.d.ts +29 -0
  141. package/dist/lib/remote-auth/diagnose.d.ts +77 -0
  142. package/dist/lib/remote-auth/generic-auth.d.ts +97 -0
  143. package/dist/lib/remote-auth/git-http.d.ts +85 -0
  144. package/dist/lib/remote-auth/github-auth.d.ts +69 -0
  145. package/dist/lib/remote-auth/github-repos.d.ts +64 -0
  146. package/dist/lib/remote-auth/operation-log.d.ts +66 -0
  147. package/dist/lib/remote-auth/recovery/abort-interrupted-operation.d.ts +103 -0
  148. package/dist/lib/remote-auth/recovery/backup.d.ts +113 -0
  149. package/dist/lib/remote-auth/recovery/classify.d.ts +109 -0
  150. package/dist/lib/remote-auth/recovery/context.d.ts +47 -0
  151. package/dist/lib/remote-auth/recovery/dispatch.d.ts +33 -0
  152. package/dist/lib/remote-auth/recovery/failsafe.d.ts +33 -0
  153. package/dist/lib/remote-auth/recovery/inspect.d.ts +74 -0
  154. package/dist/lib/remote-auth/recovery/manual-guidance.d.ts +28 -0
  155. package/dist/lib/remote-auth/recovery/outcome-mapping.d.ts +58 -0
  156. package/dist/lib/remote-auth/recovery/policy.d.ts +47 -0
  157. package/dist/lib/remote-auth/recovery/recover-auth.d.ts +42 -0
  158. package/dist/lib/remote-auth/recovery/recover-binary-conflict.d.ts +37 -0
  159. package/dist/lib/remote-auth/recovery/recover-corrupt-index.d.ts +40 -0
  160. package/dist/lib/remote-auth/recovery/recover-detached-head.d.ts +70 -0
  161. package/dist/lib/remote-auth/recovery/recover-interrupted-cherry-pick.d.ts +23 -0
  162. package/dist/lib/remote-auth/recovery/recover-interrupted-merge.d.ts +28 -0
  163. package/dist/lib/remote-auth/recovery/recover-interrupted-rebase.d.ts +39 -0
  164. package/dist/lib/remote-auth/recovery/recover-merge-conflict.d.ts +34 -0
  165. package/dist/lib/remote-auth/recovery/recover-missing-git-dir.d.ts +37 -0
  166. package/dist/lib/remote-auth/recovery/recover-missing-objects.d.ts +56 -0
  167. package/dist/lib/remote-auth/recovery/recover-network.d.ts +34 -0
  168. package/dist/lib/remote-auth/recovery/recover-non-fast-forward.d.ts +27 -0
  169. package/dist/lib/remote-auth/recovery/recover-stale-lock.d.ts +76 -0
  170. package/dist/lib/remote-auth/recovery/recover-unrelated-histories.d.ts +44 -0
  171. package/dist/lib/remote-auth/recovery/recover-wrong-remote.d.ts +35 -0
  172. package/dist/lib/remote-auth/recovery/types.d.ts +235 -0
  173. package/dist/lib/remote-auth/resolution-plan.d.ts +64 -0
  174. package/dist/lib/remote-auth/sync-messages.d.ts +26 -0
  175. package/dist/lib/remote-auth/sync-types.d.ts +225 -0
  176. package/dist/lib/remote-auth/sync.d.ts +45 -0
  177. package/dist/lib/remote-auth/test-access.d.ts +47 -0
  178. package/dist/lib/remote-auth/test-support/git-http-server.d.ts +71 -0
  179. package/dist/lib/remote-auth/token-store.d.ts +95 -0
  180. package/dist/lib/remote-auth/transport.d.ts +105 -0
  181. package/dist/lib/slug.d.ts +28 -0
  182. package/dist/lib/snippets.d.ts +39 -0
  183. package/dist/lib/source-provider.d.ts +244 -0
  184. package/dist/lib/static-serve.d.ts +54 -0
  185. package/dist/lib/style-resolver.d.ts +30 -0
  186. package/dist/lib/theme-import.d.ts +70 -0
  187. package/dist/lib/theme-manager.d.ts +128 -0
  188. package/dist/lib/tool-probe.d.ts +37 -0
  189. package/dist/lib/validation-exec.d.ts +47 -0
  190. package/dist/lib/validation-profile.d.ts +18 -0
  191. package/dist/lib/version.d.ts +9 -0
  192. package/dist/lint-f63nxjfj.js +65 -0
  193. package/dist/manifest-n1gh3qw5.yaml +9 -0
  194. package/dist/manifest-ryyg71nf.yaml +9 -0
  195. package/dist/manifest.schema-rn1dpdpn.json +564 -0
  196. package/dist/new-7b08a42h.js +105 -0
  197. package/dist/paged.polyfill-n95pbxfn.js +33288 -0
  198. package/dist/pagedjs-bridge-vn4hk9fx.js +111 -0
  199. package/dist/pagedjs-interface-80g3xa8p.js +498 -0
  200. package/dist/platform.d.ts +100 -0
  201. package/dist/plugin-wf2cbmwc.js +129 -0
  202. package/dist/preflight-tg4mpz1h.js +222 -0
  203. package/dist/preview/file-watcher.d.ts +174 -0
  204. package/dist/preview/http-server.d.ts +45 -0
  205. package/dist/preview/lifecycle.d.ts +67 -0
  206. package/dist/preview/server-context.d.ts +36 -0
  207. package/dist/preview-h2bwbb2x.js +102 -0
  208. package/dist/preview-shell-rghtfmc8.js +155 -0
  209. package/dist/project-source-0tg0r6vm.js +17 -0
  210. package/dist/publish-ztaet53r.js +233 -0
  211. package/dist/render.d.ts +20 -0
  212. package/dist/render.js +682 -0
  213. package/dist/repair-jkp4n3j8.js +171 -0
  214. package/dist/schema/manifest.types.d.ts +218 -0
  215. package/dist/server.d.ts +34 -0
  216. package/dist/source-provider-hp96b5jf.js +46 -0
  217. package/dist/test-helpers/testkit.d.ts +91 -0
  218. package/dist/theme-0yzvthe8.css +65 -0
  219. package/dist/theme-570zmh2t.css +58 -0
  220. package/dist/theme-6a2fngc8.json +6 -0
  221. package/dist/theme-cd6efzjw.json +6 -0
  222. package/dist/theme-nya4nqh6.css +70 -0
  223. package/dist/theme-tqfypc1w.json +6 -0
  224. package/dist/theme-xt0hjb1b.json +6 -0
  225. package/dist/theme-zz2ktzqs.css +60 -0
  226. package/dist/types.d.ts +31 -0
  227. package/dist/utils/file-utils.d.ts +53 -0
  228. package/dist/utils/logger.d.ts +59 -0
  229. package/dist/validate-k2drs19j.js +99 -0
  230. package/package.json +102 -0
@@ -0,0 +1,171 @@
1
+ import {
2
+ buildRecoveryContext,
3
+ classifyFromHealth,
4
+ classifyGitError,
5
+ inspectRepo,
6
+ isAppHeartbeatFresh,
7
+ isUnbornRepo,
8
+ makeManualGuidance,
9
+ recover,
10
+ verifyRepoReadable
11
+ } from "./cli-7ykx7pp0.js";
12
+ import {
13
+ FileTokenStore,
14
+ defaultConfigDir
15
+ } from "./cli-h7phg3ka.js";
16
+ import {
17
+ UsageError,
18
+ rejectExtraPositionals,
19
+ rejectUnknownFlags
20
+ } from "./cli-hvqjs342.js";
21
+ import"./cli-5bxx0c4y.js";
22
+ import"./cli-1tyj4bk3.js";
23
+ import"./cli-yja077f6.js";
24
+ import"./cli-37x76zdn.js";
25
+
26
+ // src/commands/repair.ts
27
+ import { defineCommand } from "citty";
28
+ import * as readline from "node:readline/promises";
29
+ import path from "node:path";
30
+ async function promptYesNo(question) {
31
+ if (!process.stdin.isTTY)
32
+ return false;
33
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
34
+ try {
35
+ const answer = (await rl.question(`${question} [y/N] `)).trim().toLowerCase();
36
+ return answer === "y" || answer === "yes";
37
+ } finally {
38
+ rl.close();
39
+ }
40
+ }
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
+ var commandArgs = {
87
+ dir: {
88
+ type: "positional",
89
+ description: "Project directory (defaults to the current directory)",
90
+ required: false
91
+ },
92
+ check: {
93
+ type: "boolean",
94
+ description: "Diagnose only — never change anything (exit 1 when repair is needed)",
95
+ default: false
96
+ },
97
+ yes: {
98
+ type: "boolean",
99
+ description: "Approve the repair without prompting",
100
+ default: false
101
+ },
102
+ force: {
103
+ type: "boolean",
104
+ description: "Repair even if the Gutterpress app appears to have this project open",
105
+ default: false
106
+ }
107
+ };
108
+ var repair_default = defineCommand({
109
+ meta: {
110
+ name: "repair",
111
+ description: "Diagnose and repair the project's version history"
112
+ },
113
+ args: commandArgs,
114
+ async run({ args, rawArgs }) {
115
+ try {
116
+ rejectUnknownFlags(rawArgs, commandArgs, "repair");
117
+ rejectExtraPositionals(args._, 1, "repair");
118
+ } catch (error) {
119
+ if (error instanceof UsageError) {
120
+ console.error(error.message);
121
+ process.exitCode = error.exitCode;
122
+ return;
123
+ }
124
+ throw error;
125
+ }
126
+ 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) {
135
+ try {
136
+ await verifyRepoReadable(ctx.repoDir);
137
+ } catch (err) {
138
+ if (!isUnbornRepo(ctx.repoDir)) {
139
+ kind = classifyGitError(err, health);
140
+ }
141
+ }
142
+ }
143
+ if (kind === null) {
144
+ console.log("Your project's version history looks healthy. Nothing to repair.");
145
+ return;
146
+ }
147
+ const guidance = makeManualGuidance(ctx, kind);
148
+ console.log(`Found a problem: ${guidance.userSummary}`);
149
+ if (args.check) {
150
+ console.log(`
151
+ Run \`gutterpress repair\` to fix it. ${guidance.recommendedNextStep}`);
152
+ process.exitCode = 1;
153
+ return;
154
+ }
155
+ if (!args.force && await isAppHeartbeatFresh(ctx.repoDir)) {
156
+ console.log(`
157
+ The Gutterpress app appears to have this project open. Close it first, or re-run with --force.`);
158
+ process.exitCode = 1;
159
+ return;
160
+ }
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;
166
+ }
167
+ }
168
+ });
169
+ export {
170
+ repair_default as default
171
+ };
@@ -0,0 +1,218 @@
1
+ export type CheckSeverity = "error" | "warning" | "info";
2
+ export interface PluginConfig {
3
+ path?: string;
4
+ name?: string;
5
+ /** Exact project-local npm version. Legacy ranges remain informational. */
6
+ version?: string;
7
+ /** Named module export to use when the package has no default plugin export. */
8
+ export?: string;
9
+ priority?: number;
10
+ options?: Record<string, unknown>;
11
+ /**
12
+ * Per-project enable flag (#30). Absent or `true` = active; `false` = the
13
+ * entry stays in the manifest (reversible toggle) but is skipped by
14
+ * `resolveConfig` so it is not loaded at build/preview time.
15
+ */
16
+ enabled?: boolean;
17
+ }
18
+ /**
19
+ * Non-secret, per-provider publish settings (#35), keyed by provider id —
20
+ * the same spelling as `gutterpress publish --provider <id>`. Secrets (API
21
+ * keys, tokens) NEVER live in the manifest — they belong to the host's
22
+ * credential store (CLI: 0600 file under the user config dir; desktop:
23
+ * Electron safeStorage).
24
+ */
25
+ /**
26
+ * The name (label) of the SAVED credential this book uses for a provider, when
27
+ * the user keeps more than one (e.g. two itch.io accounts). It is NOT a secret
28
+ * — just a reference into the host credential store's named entries; empty/
29
+ * absent uses the default (bare-host) credential. This book-level choice
30
+ * overrides any project/global default.
31
+ */
32
+ export interface PublishSettings {
33
+ itch?: {
34
+ /** itch.io project as `user/game` (the butler push target). */
35
+ target?: string;
36
+ /** butler channel name (default: "pdf"). */
37
+ channel?: string;
38
+ /** Saved-credential label to use (see PublishSettings doc). */
39
+ credential?: string;
40
+ };
41
+ drivethrurpg?: {
42
+ /** Existing product page URL, when updating a published title. */
43
+ productUrl?: string;
44
+ };
45
+ kdp?: Record<string, never>;
46
+ "azure-swa"?: {
47
+ /** Deploy environment (default: "production"). */
48
+ env?: string;
49
+ /** Saved-credential label to use (see PublishSettings doc). */
50
+ credential?: string;
51
+ };
52
+ shopify?: {
53
+ /** The store domain, e.g. `my-store.myshopify.com`. */
54
+ shop?: string;
55
+ /** Existing product GID/id to update instead of creating a new one. */
56
+ productId?: string;
57
+ /** Admin GraphQL API version (default: "2026-04"). */
58
+ apiVersion?: string;
59
+ /** Saved-credential label to use (see PublishSettings doc). */
60
+ credential?: string;
61
+ };
62
+ }
63
+ export interface GutterpressManifest {
64
+ title?: string;
65
+ authors?: string[];
66
+ publish?: PublishSettings;
67
+ preset?: "dtrpg" | "book";
68
+ styles?: string[];
69
+ plugins?: (string | PluginConfig)[];
70
+ source?: {
71
+ files?: string[] | null;
72
+ };
73
+ pdfx?: {
74
+ flavor?: "x1a" | "x3";
75
+ icc?: string;
76
+ stripAnnotations?: boolean;
77
+ };
78
+ page?: {
79
+ width?: number;
80
+ height?: number;
81
+ tolerance?: number;
82
+ };
83
+ ink?: {
84
+ maxTac?: number;
85
+ tacTolerance?: number;
86
+ };
87
+ lint?: {
88
+ enabled?: boolean;
89
+ configPath?: string | null;
90
+ };
91
+ validate?: {
92
+ enabled?: boolean;
93
+ checks?: Record<string, boolean | {
94
+ enabled?: boolean;
95
+ severity?: CheckSeverity;
96
+ options?: Record<string, unknown>;
97
+ }>;
98
+ source?: {
99
+ markdownlint?: string | false;
100
+ htmlhint?: string | false;
101
+ stylelint?: string | false;
102
+ /**
103
+ * @deprecated `:::name` container syntax was removed 2026-05-17 and the
104
+ * callout-validation check it gated was removed at the same time. This
105
+ * field is now a no-op kept for backward-compatible manifest parsing.
106
+ * Will be removed in a future major version. See
107
+ * docs/migrations/2026-05-removing-container-syntax.md.
108
+ */
109
+ allowedCallouts?: string[];
110
+ };
111
+ assets?: {
112
+ maxImageSize?: number;
113
+ minImageDpi?: number;
114
+ allowedColorSpaces?: string[];
115
+ allowAlpha?: boolean;
116
+ approvedFontFiles?: string[];
117
+ requireFontLicense?: boolean;
118
+ };
119
+ pdf?: {
120
+ requireBookmarks?: boolean;
121
+ requireTocLinks?: boolean;
122
+ minImageResolution?: number;
123
+ forbidTransparency?: boolean;
124
+ requireBleed?: boolean;
125
+ bleedSize?: number;
126
+ };
127
+ heuristics?: {
128
+ maxDecorativeLayers?: number;
129
+ textDensityRange?: {
130
+ min?: number;
131
+ max?: number;
132
+ };
133
+ maxParagraphsPerSection?: number;
134
+ };
135
+ };
136
+ }
137
+ export interface ResolvedPluginConfig {
138
+ path?: string;
139
+ name?: string;
140
+ /** Exact version for a project-local vendored npm plugin. */
141
+ version?: string;
142
+ /** Named module export selected as the plugin function. */
143
+ export?: string;
144
+ priority: number;
145
+ options: Record<string, unknown>;
146
+ }
147
+ /**
148
+ * Fully-resolved config. Every field is a concrete default with one
149
+ * deliberate exception: `styles` (ARCH finding #2). There is no preset
150
+ * default for it — `undefined` means "the manifest didn't set one", and
151
+ * `resolveActiveStyles` (style-resolver.ts) is the single source of truth for
152
+ * what that resolves to (styles/book.css, else the first discovered `.css`,
153
+ * else `[]`). Baking a preset default in here defeated that fallback chain.
154
+ */
155
+ export interface ResolvedConfig {
156
+ title: string;
157
+ authors: string[];
158
+ styles?: string[];
159
+ plugins: ResolvedPluginConfig[];
160
+ source: {
161
+ files: string[] | null;
162
+ };
163
+ pdfx: {
164
+ flavor: "x1a" | "x3";
165
+ icc: string;
166
+ stripAnnotations: boolean;
167
+ };
168
+ page: {
169
+ width: number;
170
+ height: number;
171
+ tolerance: number;
172
+ };
173
+ ink: {
174
+ maxTac: number;
175
+ tacTolerance: number;
176
+ };
177
+ lint: {
178
+ enabled: boolean;
179
+ configPath: string | null;
180
+ };
181
+ validate: {
182
+ enabled: boolean;
183
+ checks: Record<string, boolean | {
184
+ enabled?: boolean;
185
+ severity?: CheckSeverity;
186
+ options?: Record<string, unknown>;
187
+ }>;
188
+ source: {
189
+ markdownlint: string | false | null;
190
+ htmlhint: string | false | null;
191
+ stylelint: string | false | null;
192
+ };
193
+ assets: {
194
+ maxImageSize: number;
195
+ minImageDpi: number;
196
+ allowedColorSpaces: string[];
197
+ allowAlpha: boolean;
198
+ approvedFontFiles: string[];
199
+ requireFontLicense: boolean;
200
+ };
201
+ pdf: {
202
+ requireBookmarks: boolean;
203
+ requireTocLinks: boolean;
204
+ minImageResolution: number;
205
+ forbidTransparency: boolean;
206
+ requireBleed: boolean;
207
+ bleedSize: number;
208
+ };
209
+ heuristics: {
210
+ maxDecorativeLayers: number;
211
+ textDensityRange: {
212
+ min: number;
213
+ max: number;
214
+ };
215
+ maxParagraphsPerSection: number;
216
+ };
217
+ };
218
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Preview server entry point.
3
+ *
4
+ * Loads config via lib/manifest, generates HTML via lib/markdown, and serves
5
+ * the preview through a node:http + `ws` HTTP+WebSocket server (see
6
+ * `src/preview/http-server.ts`). Live reload is handled by broadcasting
7
+ * `full-reload` over the HMR WebSocket whenever the file watcher fires.
8
+ */
9
+ import type { PreviewServerOptions } from './types';
10
+ export interface PreviewServerHandle {
11
+ url: string;
12
+ port: number;
13
+ host: string;
14
+ inputPath: string;
15
+ /** Stop the server, file watcher, and any signal handlers. */
16
+ stop: () => Promise<void>;
17
+ /** Switch the watched directory and regenerate HTML. */
18
+ restart: (newInputPath: string) => Promise<void>;
19
+ }
20
+ export interface StartPreviewServerOptions extends PreviewServerOptions {
21
+ /**
22
+ * Install SIGINT/SIGTERM handlers that shut down the server on Ctrl+C.
23
+ * Defaults to true (CLI usage). Library/embedded callers (Electron+SvelteKit)
24
+ * should pass false and call handle.stop() themselves.
25
+ */
26
+ installSignalHandlers?: boolean;
27
+ }
28
+ /**
29
+ * Start the preview server backed by a node:http + `ws` HTTP/WebSocket server.
30
+ *
31
+ * Returns a handle the caller can use to introspect the URL or stop the server.
32
+ * CLI callers can simply ignore the handle and rely on SIGINT/SIGTERM.
33
+ */
34
+ export declare function startPreviewServer(options: StartPreviewServerOptions): Promise<PreviewServerHandle>;
@@ -0,0 +1,46 @@
1
+ import {
2
+ AUTO_SNAPSHOT_MESSAGE,
3
+ HISTORY_PAGE_LIMIT,
4
+ RESTORE_BACKUP_MESSAGE,
5
+ SNAPSHOT_STAGING_MARKER,
6
+ __repoLockQueueSizeForTests,
7
+ gitAuthor,
8
+ gitDirFor,
9
+ gitScopeFor,
10
+ hasPendingChanges,
11
+ hasUncommittedChanges,
12
+ isNoChangesError,
13
+ listWorkdirChanges,
14
+ providerFor,
15
+ readGitAuthor,
16
+ resolveGitAuthor,
17
+ restoreVersionWithBackup,
18
+ snapshotStagingMarkerPath,
19
+ snapshotWorkingTreeUnlocked,
20
+ stageChanges,
21
+ withRepoLock
22
+ } from "./cli-5bxx0c4y.js";
23
+ import"./cli-1tyj4bk3.js";
24
+ import"./cli-37x76zdn.js";
25
+ export {
26
+ withRepoLock,
27
+ stageChanges,
28
+ snapshotWorkingTreeUnlocked,
29
+ snapshotStagingMarkerPath,
30
+ restoreVersionWithBackup,
31
+ resolveGitAuthor,
32
+ readGitAuthor,
33
+ providerFor,
34
+ listWorkdirChanges,
35
+ isNoChangesError,
36
+ hasUncommittedChanges,
37
+ hasPendingChanges,
38
+ gitScopeFor,
39
+ gitDirFor,
40
+ gitAuthor,
41
+ __repoLockQueueSizeForTests,
42
+ SNAPSHOT_STAGING_MARKER,
43
+ RESTORE_BACKUP_MESSAGE,
44
+ HISTORY_PAGE_LIMIT,
45
+ AUTO_SNAPSHOT_MESSAGE
46
+ };
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Shared CLI test-scaffolding kit.
3
+ *
4
+ * TEST-ONLY. This module is imported exclusively by `*.test.ts` files — it is
5
+ * never referenced by production entrypoints (`src/index.ts`, `src/cli.ts`),
6
+ * so it never lands in the `bun build`/`bun build --compile` output. It exists
7
+ * to kill the copy-pasted scaffolding that used to live inline in dozens of
8
+ * test files (`makeTempDir` ~13×, `makeCtx` ~2× for the CheckContext shape,
9
+ * plus the isomorphic-git repo builders).
10
+ *
11
+ * Where copies differed meaningfully, the canonical helper keeps every
12
+ * behavior via options rather than silently picking one — callers pass the
13
+ * exact prefix/author/content they relied on.
14
+ */
15
+ import { spyOn } from "bun:test";
16
+ import type { FsClient } from "isomorphic-git";
17
+ import type { CheckContext } from "../checks/types";
18
+ /**
19
+ * Create a fresh, unique temp directory under `os.tmpdir()`.
20
+ *
21
+ * The `prefix` is purely a human-readable naming segment for the OS-assigned
22
+ * unique dir (handy when eyeballing leftover fixtures); callers that relied on
23
+ * a suite-specific prefix pass it through so behavior is byte-identical.
24
+ */
25
+ export declare function makeTempDir(prefix?: string): Promise<string>;
26
+ /**
27
+ * Build a {@link CheckContext} for check/policy unit tests, filling the
28
+ * required fields with defaults and shallow-merging a partial override
29
+ * (last-write-wins), matching the copies that lived in
30
+ * `checks.test.ts` / `policy.test.ts`.
31
+ */
32
+ export declare function makeCtx(partial?: Partial<CheckContext>): CheckContext;
33
+ export interface TestAuthor {
34
+ name: string;
35
+ email: string;
36
+ }
37
+ /** The author most recovery-test copies used. */
38
+ export declare const DEFAULT_TEST_AUTHOR: TestAuthor;
39
+ export interface InitRepoOptions {
40
+ branch?: string;
41
+ content?: string;
42
+ message?: string;
43
+ author?: TestAuthor;
44
+ fs?: FsClient;
45
+ }
46
+ /**
47
+ * Initialize a git repo with a single committed `chapter-01.md` and return the
48
+ * initial commit oid. Every varying bit (branch, file content, commit message,
49
+ * author, fs impl) is an option so the previously-bespoke copies map onto it
50
+ * without changing behavior.
51
+ */
52
+ export declare function initRepo(dir: string, opts?: InitRepoOptions): Promise<string>;
53
+ /**
54
+ * Like {@link initRepo} but defaults to the `"initial"` commit message the
55
+ * `makeTestRepo` copies used. Always on `main`. Returns the commit oid.
56
+ */
57
+ export declare function makeTestRepo(dir: string, opts?: Omit<InitRepoOptions, "branch">): Promise<string>;
58
+ export interface CommitFileOptions {
59
+ message?: string;
60
+ author?: TestAuthor;
61
+ fs?: FsClient;
62
+ }
63
+ /**
64
+ * Write `body` to `filename` inside an existing repo, stage it and commit.
65
+ * Defaults the message to `add <filename>` (the copies' convention). Returns
66
+ * the commit oid.
67
+ */
68
+ export declare function commitFile(dir: string, filename: string, body: string, opts?: CommitFileOptions): Promise<string>;
69
+ /**
70
+ * Thrown by {@link stubProcessExit}'s stub instead of actually terminating
71
+ * the test worker. Carries the exit code so `expect(...).rejects.toThrow(...)`
72
+ * can assert on it directly.
73
+ */
74
+ export declare class ProcessExitSignal extends Error {
75
+ code: number;
76
+ constructor(code: number);
77
+ }
78
+ /**
79
+ * Replace `process.exit` with a stub that THROWS a {@link ProcessExitSignal}
80
+ * instead of ending the process — mirroring real `process.exit()` semantics
81
+ * (nothing after the call site ever runs) while staying observable in tests.
82
+ * Command handlers routinely do `log.error(...); process.exit(code);` with no
83
+ * `return` after — without this, a naive no-op stub would fall through into
84
+ * whatever code follows and throw on unrelated undefined state.
85
+ *
86
+ * Callers MUST `mockRestore()` the returned spy (e.g. in `afterEach`) —
87
+ * `process` is a shared global across the whole test run, exactly like the
88
+ * `spyOn`/`mockRestore` discipline documented in
89
+ * `build-runner.browser-lifecycle.test.ts`.
90
+ */
91
+ export declare function stubProcessExit(): ReturnType<typeof spyOn<typeof process, "exit">>;
@@ -0,0 +1,65 @@
1
+ /* =============================================================================
2
+ TTRPG Supplement — gutterpress built-in theme (theme.css)
3
+ Bold headings, parchment fills, boxed blocks. Customize the tokens in :root.
4
+ ============================================================================= */
5
+
6
+ :root {
7
+ --color-ink: #241a12; /* body text */
8
+ --color-ink-muted: #5c4a36; /* captions, secondary text */
9
+ --color-accent: #7a2222; /* headings, key accents */
10
+ --color-paper: #faf4e6; /* parchment page background */
11
+ --color-tint: #efe3c8; /* stat-block / callout fill */
12
+ --color-rule: #b89a6a; /* borders, rules */
13
+
14
+ --font-body: "Palatino Linotype", "Book Antiqua", Palatino, serif;
15
+ --font-display: "Trajan Pro", "Cinzel", "Georgia", serif;
16
+ --font-mono: "Consolas", "Menlo", monospace;
17
+
18
+ --scale-h1: 2.4rem;
19
+ --scale-h2: 1.7rem;
20
+ --scale-h3: 1.25rem;
21
+ --leading: 1.45;
22
+ }
23
+
24
+ @page {
25
+ size: 8.5in 11in;
26
+ margin: 0.7in;
27
+ }
28
+
29
+ body {
30
+ color: var(--color-ink);
31
+ background: var(--color-paper);
32
+ font-family: var(--font-body);
33
+ line-height: var(--leading);
34
+ font-size: 10.5pt;
35
+ }
36
+
37
+ h1, h2, h3 {
38
+ font-family: var(--font-display);
39
+ color: var(--color-accent);
40
+ letter-spacing: 0.02em;
41
+ text-transform: uppercase;
42
+ font-weight: 700;
43
+ }
44
+ h1 { font-size: var(--scale-h1); margin: 0 0 0.5em; border-bottom: 3px double var(--color-rule); padding-bottom: 0.2em; }
45
+ h2 { font-size: var(--scale-h2); margin: 1.3em 0 0.4em; }
46
+ h3 { font-size: var(--scale-h3); margin: 1.1em 0 0.3em; letter-spacing: 0; }
47
+
48
+ p { margin: 0 0 0.7em; }
49
+
50
+ a { color: var(--color-accent); text-decoration: none; }
51
+
52
+ blockquote {
53
+ margin: 1em 0; padding: 0.6em 0.9em;
54
+ background: var(--color-tint);
55
+ border: 1px solid var(--color-rule);
56
+ border-radius: 4px;
57
+ }
58
+
59
+ table {
60
+ width: 100%; border-collapse: collapse; margin: 1em 0;
61
+ }
62
+ th, td { border: 1px solid var(--color-rule); padding: 0.35em 0.6em; text-align: left; }
63
+ th { background: var(--color-tint); font-family: var(--font-display); }
64
+
65
+ code, pre { font-family: var(--font-mono); font-size: 0.9em; }
@@ -0,0 +1,58 @@
1
+ /* =============================================================================
2
+ Clean Book — gutterpress built-in theme (theme.css)
3
+ A calm, classic long-form book look. Customize the tokens in :root.
4
+ ============================================================================= */
5
+
6
+ :root {
7
+ --color-ink: #1a1a1a; /* body text */
8
+ --color-ink-muted: #555555; /* captions, secondary text */
9
+ --color-accent: #2b4c7e; /* headings, links */
10
+ --color-paper: #ffffff; /* page background */
11
+ --color-rule: #d9d9d9; /* borders, rules */
12
+
13
+ --font-body: "Georgia", "Times New Roman", serif;
14
+ --font-display: "Georgia", "Times New Roman", serif;
15
+ --font-mono: "Menlo", "Consolas", monospace;
16
+
17
+ --scale-h1: 2.1rem;
18
+ --scale-h2: 1.5rem;
19
+ --scale-h3: 1.2rem;
20
+ --leading: 1.55;
21
+ }
22
+
23
+ @page {
24
+ size: 6in 9in;
25
+ margin: 0.85in 0.75in;
26
+ }
27
+
28
+ body {
29
+ color: var(--color-ink);
30
+ background: var(--color-paper);
31
+ font-family: var(--font-body);
32
+ line-height: var(--leading);
33
+ font-size: 11pt;
34
+ }
35
+
36
+ h1, h2, h3 {
37
+ font-family: var(--font-display);
38
+ color: var(--color-accent);
39
+ line-height: 1.2;
40
+ font-weight: 600;
41
+ }
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; }
45
+
46
+ p { margin: 0 0 0.8em; text-align: justify; hyphens: auto; }
47
+
48
+ a { color: var(--color-accent); text-decoration: none; }
49
+
50
+ blockquote {
51
+ margin: 1em 0; padding: 0.2em 0 0.2em 1em;
52
+ border-left: 3px solid var(--color-rule);
53
+ color: var(--color-ink-muted); font-style: italic;
54
+ }
55
+
56
+ code, pre { font-family: var(--font-mono); font-size: 0.9em; }
57
+
58
+ hr { border: 0; border-top: 1px solid var(--color-rule); margin: 1.5em 0; }
@@ -0,0 +1,6 @@
1
+ {
2
+ "name": "TTRPG Supplement",
3
+ "author": "gutterpress",
4
+ "description": "Bold display headings, warm parchment fills, and boxed stat blocks for game books.",
5
+ "preview": null
6
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "name": "Zine",
3
+ "author": "gutterpress",
4
+ "description": "High-contrast, punchy sans-serif look for short photocopier-friendly zines.",
5
+ "preview": null
6
+ }