gutterpress 0.10.0-beta.1 → 0.10.1-beta.1

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 (56) 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-85zn35v8.js → audit-7a37g51p.js} +5 -5
  5. package/dist/{build-1faqmp0y.js → build-kdaet3pd.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-afm8pa0h.js → cli-ak1tagkr.js} +95 -58
  9. package/dist/{cli-5tffrg48.js → cli-df7gcyns.js} +510 -1375
  10. package/dist/{cli-7e79d7se.js → cli-dx6sxj2t.js} +1 -1
  11. package/dist/{cli-v935c2ws.js → cli-mcb484g3.js} +2 -47
  12. package/dist/{cli-k1065rkg.js → cli-w692g6dx.js} +75 -29
  13. package/dist/cli.js +14 -15
  14. package/dist/{doctor-69v5c9wy.js → doctor-vajd5h45.js} +2 -2
  15. package/dist/{engine-nbfdy0pp.js → engine-0nt35svz.js} +2 -2
  16. package/dist/{engine-hrtn0b28.js → engine-gkcqdye5.js} +1 -1
  17. package/dist/{gutterpress-viewer-fb6fhwsy.js → gutterpress-viewer-tma1qwz2.js} +111 -35
  18. package/dist/{index-052x5fef.js → index-6g72h2n1.js} +980 -1677
  19. package/dist/{index-c2b6gyeg.js → index-b2rqw41a.js} +2 -2
  20. package/dist/{index-mdefp0y5.js → index-dtrftayr.js} +75 -27
  21. package/dist/{index-wsydvp08.js → index-kvgq4q3q.js} +94 -57
  22. package/dist/index.js +9 -65
  23. package/dist/lib/build-staging.d.ts +51 -0
  24. package/dist/lib/git-fs.d.ts +43 -0
  25. package/dist/lib/host-policy.d.ts +14 -2
  26. package/dist/lib/remote-auth/clone.d.ts +0 -21
  27. package/dist/lib/remote-auth/converge-merge.d.ts +24 -7
  28. package/dist/lib/remote-auth/generic-auth.d.ts +0 -22
  29. package/dist/lib/remote-auth/git-http.d.ts +1 -1
  30. package/dist/lib/remote-auth/github-auth.d.ts +2 -22
  31. package/dist/lib/remote-auth/operation-log.d.ts +4 -9
  32. package/dist/lib/remote-auth/sync-messages.d.ts +35 -12
  33. package/dist/lib/remote-auth/sync-types.d.ts +30 -101
  34. package/dist/lib/remote-auth/sync.d.ts +19 -21
  35. package/dist/lib/remote-auth/token-store.d.ts +0 -10
  36. package/dist/lib/remote-auth/transport.d.ts +42 -40
  37. package/dist/lib/source-provider.d.ts +12 -0
  38. package/dist/{lint-17404bsx.js → lint-p6a4bkvh.js} +5 -5
  39. package/dist/{new-vsgpxzek.js → new-4cdzfbsj.js} +5 -5
  40. package/dist/{plugin-s4yfpx6p.js → plugin-a89tqspy.js} +5 -5
  41. package/dist/{preflight-1h3apvqh.js → preflight-r4y3f8f9.js} +5 -5
  42. package/dist/{preview-interface-hg5eqv88.js → preview-interface-0ssk8bmm.js} +4 -2
  43. package/dist/{preview-cqf383g4.js → preview-k8n2kew7.js} +5 -5
  44. package/dist/{publish-arvycera.js → publish-jnhjp2vd.js} +5 -5
  45. package/dist/{source-provider-3tcj6qg2.js → source-provider-2j5x2hyw.js} +1 -1
  46. package/dist/{source-provider-vanafrt9.js → source-provider-kn41jmbs.js} +1 -1
  47. package/dist/{validate-ztzq7p35.js → validate-prnybpkx.js} +5 -5
  48. package/package.json +1 -1
  49. package/dist/lib/app-heartbeat.d.ts +0 -102
  50. package/dist/lib/remote-auth/image-clash.d.ts +0 -17
  51. package/dist/lib/remote-auth/recovery/classify.d.ts +0 -97
  52. package/dist/lib/remote-auth/recovery/inspect.d.ts +0 -75
  53. package/dist/lib/remote-auth/recovery/locks.d.ts +0 -20
  54. package/dist/lib/remote-auth/recovery/repair.d.ts +0 -29
  55. package/dist/lib/remote-auth/recovery/types.d.ts +0 -39
  56. package/dist/repair-vmwh2bhe.js +0 -137
package/README.md CHANGED
@@ -133,10 +133,9 @@ The full configuration cascade is `CLI flags > manifest.yaml > preset defaults`.
133
133
 
134
134
  ## Commands
135
135
 
136
- Gutterpress has 11 subcommands. `new`, `preview`, `build`, and `publish` are the
136
+ Gutterpress has 10 subcommands. `new`, `preview`, `build`, and `publish` are the
137
137
  primary author commands; `lint`, `validate`, `audit`, and `preflight` are
138
- CI / advanced checks; `repair` is the version-history escape hatch; and
139
- `doctor` reports system readiness. `plugin` manages project plugins. Every
138
+ CI / advanced checks; and `doctor` reports system readiness. `plugin` manages project plugins. Every
140
139
  command also accepts `--help` for the authoritative, always-current flag list
141
140
  (`gutterpress <command> --help`) — this section is regenerated from the same
142
141
  source.
@@ -315,18 +314,6 @@ gutterpress preflight [dir] --pdf <path> [options]
315
314
 
316
315
  Exits 1 when the computed status is `NO-GO` (errors, or a required check skipped/failed).
317
316
 
318
- ### `gutterpress repair`
319
-
320
- Diagnose and repair the project's version history — no git knowledge (and no system git) required. Detects the states that block syncing (an update that didn't finish, a leftover lock from a crash, a damaged or missing history) and applies the same safe repair the desktop app offers: a safety-copy zip is saved first, and nothing changes without your confirmation.
321
-
322
- ```sh
323
- gutterpress repair [dir]
324
-
325
- --check Diagnose only — never change anything (exit 1 when repair is needed)
326
- --yes Approve the repair without prompting
327
- --force Repair even if the Gutterpress app appears to have this project open
328
- ```
329
-
330
317
  ### `gutterpress doctor`
331
318
 
332
319
  Report the Gutterpress version, platform and config paths, and whether each external tool is available. Missing tools include the features that use them and platform-specific installation guidance.
@@ -369,7 +356,7 @@ Every command follows the same exit-code contract, so CI can branch on the resul
369
356
  | `2` | Usage — the invocation itself was wrong: a bad flag, positional argument, preset, or value. |
370
357
  | `3` | Pipeline — the build/render/export pipeline itself failed for a reason unrelated to usage or findings (I/O error, missing tool, renderer crash). |
371
358
 
372
- This applies uniformly across `build`, `preview`, `lint`, `validate`, `preflight`, `audit`, `repair`, `publish`, `plugin`, `new`, and `doctor`.
359
+ This applies uniformly across `build`, `preview`, `lint`, `validate`, `preflight`, `audit`, `publish`, `plugin`, `new`, and `doctor`.
373
360
 
374
361
  ## Plugins
375
362
 
@@ -43,27 +43,24 @@ export { readManifestFields, setManifestFields, setActiveStyles, } from "../lib/
43
43
  export type { ProjectConfigFields } from "../lib/manifest-config.ts";
44
44
  export { providerFor, restoreVersionWithBackup, isNoChangesError, AUTO_SNAPSHOT_MESSAGE, RESTORE_BACKUP_MESSAGE, HISTORY_PAGE_LIMIT, } from "../lib/source-provider.ts";
45
45
  export type { ListHistoryOptions, HistoryPage, } from "../lib/source-provider.ts";
46
- export { appHeartbeatPath, heartbeatTtlMs, isAppHeartbeatFresh, readAppHeartbeat, removeAppHeartbeat, writeAppHeartbeat, APP_HEARTBEAT_FRESH_MS, } from "../lib/app-heartbeat.ts";
47
- export type { AppHeartbeat } from "../lib/app-heartbeat.ts";
48
- export { autoSnapshotDelayMs, autoSyncDelayMs, isGitInternalPath, AUTO_SNAPSHOT_MIN_MINUTES, AUTO_SNAPSHOT_MAX_MINUTES, AUTO_SNAPSHOT_DEFAULT_MINUTES, AUTO_SYNC_MIN_MINUTES, AUTO_SYNC_MAX_MINUTES, AUTO_SYNC_DEFAULT_MINUTES, } from "../lib/host-policy.ts";
46
+ export { autoSnapshotDelayMs, autoSyncDelayMs, isGitInternalPath, AUTO_SNAPSHOT_MIN_MINUTES, AUTO_SNAPSHOT_MAX_MINUTES, AUTO_SNAPSHOT_DEFAULT_MINUTES, AUTO_SYNC_MIN_MINUTES, AUTO_SYNC_MAX_MINUTES, AUTO_SYNC_DEFAULT_MINUTES, AUTO_SYNC_PUSH_INTERVAL_MINUTES, } from "../lib/host-policy.ts";
49
47
  export type { AutoSnapshotPolicy, AutoSyncPolicy, } from "../lib/host-policy.ts";
50
- export { FileTokenStore, defaultConfigDir, redactCredential, extractUrlCredential, migrateUrlCredential, } from "../lib/remote-auth/token-store.ts";
48
+ export { FileTokenStore, defaultConfigDir, extractUrlCredential, } from "../lib/remote-auth/token-store.ts";
51
49
  export type { HostCredential, TokenStore, UrlCredentialExtraction, } from "../lib/remote-auth/token-store.ts";
52
50
  export { GitHubAuthProvider, resolveGitHubClientId, GITHUB_HOST, } from "../lib/remote-auth/github-auth.ts";
53
- export type { RemoteAuthProvider, HostCallbacks, DeviceCodeInfo, GitHubAuthProviderOptions, } from "../lib/remote-auth/github-auth.ts";
51
+ export type { HostCallbacks, DeviceCodeInfo, GitHubAuthProviderOptions, } from "../lib/remote-auth/github-auth.ts";
54
52
  export { listGitHubRepositories, listGitHubBranches, listRepoBooks, } from "../lib/remote-auth/github-repos.ts";
55
53
  export type { RemoteRepository, RemoteBranch, RepoBook, } from "../lib/remote-auth/github-repos.ts";
56
- export { cloneRepository, readProjectProvenance, provenancePath, sanitizeCloneFolderName, } from "../lib/remote-auth/clone.ts";
57
- export type { CloneRepositoryOptions, CloneRepositoryResult, CloneProgressEvent, ProjectProvenance, } from "../lib/remote-auth/clone.ts";
54
+ export { cloneRepository, sanitizeCloneFolderName, } from "../lib/remote-auth/clone.ts";
55
+ export type { CloneRepositoryOptions, CloneRepositoryResult, CloneProgressEvent, } from "../lib/remote-auth/clone.ts";
58
56
  export { testRemoteAccess, isSshRemoteUrl, } from "../lib/remote-auth/test-access.ts";
59
57
  export type { RemoteAccessResult, RemoteAccessFailureReason, TestRemoteAccessOptions, } from "../lib/remote-auth/test-access.ts";
60
- export { GenericTokenAuthProvider, connectGenericHost, knownForgeTokenUrl, normalizeForgeHost, } from "../lib/remote-auth/generic-auth.ts";
61
- export type { GenericTokenConnectInput, GenericHostCallbacks, GenericAuthOptions, } from "../lib/remote-auth/generic-auth.ts";
58
+ export { connectGenericHost, knownForgeTokenUrl, } from "../lib/remote-auth/generic-auth.ts";
59
+ export type { GenericTokenConnectInput, GenericAuthOptions, } from "../lib/remote-auth/generic-auth.ts";
62
60
  export { diagnoseProjectRemote, parseRemoteOrigin, forgeKindForHost, } from "../lib/remote-auth/diagnose.ts";
63
61
  export type { ProjectRemoteDiagnosis, DiagnoseProjectRemoteOptions, RemoteProtocol, RemoteGuidanceId, ForgeKind, } from "../lib/remote-auth/diagnose.ts";
64
- export { syncProject, pullChanges, pushChanges, SYNC_SNAPSHOT_MESSAGE, } from "../lib/remote-auth/sync.ts";
65
- export type { SyncOutcome, PullOutcome, PushOutcome, SyncProjectOptions, ImageClash, } from "../lib/remote-auth/sync.ts";
66
- export { keepImageVersion, readImageVersion } from "../lib/remote-auth/image-clash.ts";
62
+ export { syncProject, SYNC_SNAPSHOT_MESSAGE, } from "../lib/remote-auth/sync.ts";
63
+ export type { SyncOutcome, SyncProjectOptions, KeptBothFile, } from "../lib/remote-auth/sync.ts";
67
64
  export type { SnapshotEntry, InitVersionHistoryOptions, SnapshotOptions, RestoreSnapshotOptions, RestoreVersionOptions, RestoreVersionResult, SourceProvider, } from "../lib/source-provider.ts";
68
65
  export { runPublish, resolvePublishRequest, } from "../lib/publish/run-publish.ts";
69
66
  export type { RunPublishOptions, RunPublishResult, } from "../lib/publish/run-publish.ts";
@@ -76,11 +73,5 @@ export { PublishSelectionsStore } from "../lib/publish/selections.ts";
76
73
  export type { PublishAccountSelection } from "../lib/publish/selections.ts";
77
74
  export { readPublishSettings, setPublishProviderConfig, } from "../lib/publish/manifest-publish.ts";
78
75
  export type { PublishProvider, PublishProviderId, PublishProviderInfo, PublishProviderKind, PublishConfigField, PublishArtifact, PublishArtifactFormat, PublishAuthStatus, PublishDeps, PublishListingMetadata, PublishOutcome, PublishProduct, PublishProject, PublishRequest, PreflightIssue, CommandRunner, CommandResult, } from "../lib/publish/types.ts";
79
- export { repairRepo } from "../lib/remote-auth/recovery/repair.ts";
80
- export type { RepairOptions, RepairResult } from "../lib/remote-auth/recovery/repair.ts";
81
- export { classifyFromHealth, isLikelyRepoCorruption, RepoNeedsRecoveryError, isRepoNeedsRecoveryError, STALE_LOCK_MIN_AGE_MS, } from "../lib/remote-auth/recovery/classify.ts";
82
- export type { RepairNeed } from "../lib/remote-auth/recovery/classify.ts";
83
- export { inspectRepo, preflightStructuralReason, buildPreflightDiagnostics, verifyRepoReadable, isUnbornRepo, } from "../lib/remote-auth/recovery/inspect.ts";
84
- export type { RepoHealth } from "../lib/remote-auth/recovery/types.ts";
85
- export { resolveLogger, shortOid } from "../lib/remote-auth/operation-log.ts";
76
+ export { resolveLogger } from "../lib/remote-auth/operation-log.ts";
86
77
  export type { OperationLogger, LogData } from "../lib/remote-auth/operation-log.ts";
package/dist/api/index.js CHANGED
@@ -1,16 +1,15 @@
1
1
  import {
2
- APP_HEARTBEAT_FRESH_MS,
3
2
  AUTO_SNAPSHOT_DEFAULT_MINUTES,
4
3
  AUTO_SNAPSHOT_MAX_MINUTES,
5
4
  AUTO_SNAPSHOT_MIN_MINUTES,
6
5
  AUTO_SYNC_DEFAULT_MINUTES,
7
6
  AUTO_SYNC_MAX_MINUTES,
8
7
  AUTO_SYNC_MIN_MINUTES,
8
+ AUTO_SYNC_PUSH_INTERVAL_MINUTES,
9
9
  BUILT_IN_TEMPLATE_IDS,
10
10
  BUILT_IN_THEME_IDS,
11
11
  FileTokenStore,
12
12
  GITHUB_HOST,
13
- GenericTokenAuthProvider,
14
13
  GitHubAuthProvider,
15
14
  MANIFEST_FILENAMES,
16
15
  PLUGINS_DIR,
@@ -18,9 +17,7 @@ import {
18
17
  PRESET_IDS,
19
18
  PublishSelectionsStore,
20
19
  RECOMMENDED_PLUGINS,
21
- RepoNeedsRecoveryError,
22
20
  SNIPPETS_DIR,
23
- STALE_LOCK_MIN_AGE_MS,
24
21
  SYNC_SNAPSHOT_MESSAGE,
25
22
  TARGETS,
26
23
  TARGET_IDS,
@@ -28,12 +25,9 @@ import {
28
25
  addLocalPlugin,
29
26
  addNpmPlugin,
30
27
  adoptFolder,
31
- appHeartbeatPath,
32
28
  applyTheme,
33
29
  autoSnapshotDelayMs,
34
30
  autoSyncDelayMs,
35
- buildPreflightDiagnostics,
36
- classifyFromHealth,
37
31
  cloneRepository,
38
32
  connectGenericHost,
39
33
  connectPublishProvider,
@@ -48,19 +42,12 @@ import {
48
42
  getPreviousTheme,
49
43
  getSystemDiagnostics,
50
44
  hasProjectManifest,
51
- heartbeatTtlMs,
52
45
  importTemplateFromFolder,
53
46
  importThemeFromFile,
54
47
  importThemeFromFolder,
55
48
  importThemeFromUrl,
56
- inspectRepo,
57
- isAppHeartbeatFresh,
58
49
  isGitInternalPath,
59
- isLikelyRepoCorruption,
60
- isRepoNeedsRecoveryError,
61
50
  isSshRemoteUrl,
62
- isUnbornRepo,
63
- keepImageVersion,
64
51
  knownForgeTokenUrl,
65
52
  listBuiltInTemplates,
66
53
  listBuiltInThemes,
@@ -75,28 +62,16 @@ import {
75
62
  listRepoBooks,
76
63
  listSnippets,
77
64
  loadManifestWithPath,
78
- migrateUrlCredential,
79
- normalizeForgeHost,
80
65
  parseRemoteOrigin,
81
- preflightStructuralReason,
82
- provenancePath,
83
66
  publishConnectionStatus,
84
67
  publishCredentialKey,
85
68
  publishProviderFor,
86
69
  publishTargetFor,
87
- pullChanges,
88
- pushChanges,
89
- readAppHeartbeat,
90
- readImageVersion,
91
70
  readManifestFields,
92
- readProjectProvenance,
93
71
  readPublishSettings,
94
72
  readSnippet,
95
73
  readThemeCss,
96
- redactCredential,
97
- removeAppHeartbeat,
98
74
  removeProjectTheme,
99
- repairRepo,
100
75
  resolveActiveStyles,
101
76
  resolveBuiltInTheme,
102
77
  resolveConfig,
@@ -119,15 +94,13 @@ import {
119
94
  substituteVariables,
120
95
  syncProject,
121
96
  testRemoteAccess,
122
- validateProjectPlugins,
123
- verifyRepoReadable,
124
- writeAppHeartbeat
125
- } from "../index-052x5fef.js";
97
+ validateProjectPlugins
98
+ } from "../index-6g72h2n1.js";
126
99
  import {
127
100
  BuildError,
128
101
  DEFAULT_PRINT_OPTS,
129
102
  readyProbeExpr
130
- } from "../index-c2b6gyeg.js";
103
+ } from "../index-b2rqw41a.js";
131
104
  import {
132
105
  AUTO_SNAPSHOT_MESSAGE,
133
106
  HISTORY_PAGE_LIMIT,
@@ -135,9 +108,8 @@ import {
135
108
  isNoChangesError,
136
109
  providerFor,
137
110
  resolveLogger,
138
- restoreVersionWithBackup,
139
- shortOid
140
- } from "../index-mdefp0y5.js";
111
+ restoreVersionWithBackup
112
+ } from "../index-dtrftayr.js";
141
113
  import {
142
114
  capabilitiesFor,
143
115
  detectProjectSource,
@@ -147,8 +119,6 @@ import {
147
119
  } from "../index-v5mp7a6q.js";
148
120
  import"../index-37x76zdn.js";
149
121
  export {
150
- writeAppHeartbeat,
151
- verifyRepoReadable,
152
122
  validateProjectPlugins,
153
123
  testRemoteAccess,
154
124
  syncProject,
@@ -156,7 +126,6 @@ export {
156
126
  startPreviewServer,
157
127
  splitOutPath,
158
128
  slugifyProjectName,
159
- shortOid,
160
129
  setPublishProviderConfig,
161
130
  setPluginEnabled,
162
131
  setManifestFields,
@@ -177,30 +146,18 @@ export {
177
146
  resolveActiveStyles,
178
147
  repoSubPath,
179
148
  repoRootForSource,
180
- repairRepo,
181
149
  removeProjectTheme,
182
- removeAppHeartbeat,
183
- redactCredential,
184
150
  readyProbeExpr,
185
151
  readThemeCss,
186
152
  readSnippet,
187
153
  readPublishSettings,
188
- readProjectProvenance,
189
154
  readManifestFields,
190
- readImageVersion,
191
- readAppHeartbeat,
192
- pushChanges,
193
- pullChanges,
194
155
  publishTargetFor,
195
156
  publishProviderFor,
196
157
  publishCredentialKey,
197
158
  publishConnectionStatus,
198
159
  providerFor,
199
- provenancePath,
200
- preflightStructuralReason,
201
160
  parseRemoteOrigin,
202
- normalizeForgeHost,
203
- migrateUrlCredential,
204
161
  loadManifestWithPath,
205
162
  listSnippets,
206
163
  listRepoBooks,
@@ -215,20 +172,13 @@ export {
215
172
  listBuiltInThemes,
216
173
  listBuiltInTemplates,
217
174
  knownForgeTokenUrl,
218
- keepImageVersion,
219
- isUnbornRepo,
220
175
  isSshRemoteUrl,
221
- isRepoNeedsRecoveryError,
222
176
  isNoChangesError,
223
- isLikelyRepoCorruption,
224
177
  isGitInternalPath,
225
- isAppHeartbeatFresh,
226
- inspectRepo,
227
178
  importThemeFromUrl,
228
179
  importThemeFromFolder,
229
180
  importThemeFromFile,
230
181
  importTemplateFromFolder,
231
- heartbeatTtlMs,
232
182
  hasProjectManifest,
233
183
  getSystemDiagnostics,
234
184
  getPreviousTheme,
@@ -245,13 +195,10 @@ export {
245
195
  connectPublishProvider,
246
196
  connectGenericHost,
247
197
  cloneRepository,
248
- classifyFromHealth,
249
198
  capabilitiesFor,
250
- buildPreflightDiagnostics,
251
199
  autoSyncDelayMs,
252
200
  autoSnapshotDelayMs,
253
201
  applyTheme,
254
- appHeartbeatPath,
255
202
  adoptFolder,
256
203
  addNpmPlugin,
257
204
  addLocalPlugin,
@@ -259,9 +206,7 @@ export {
259
206
  TARGET_IDS,
260
207
  TARGETS,
261
208
  SYNC_SNAPSHOT_MESSAGE,
262
- STALE_LOCK_MIN_AGE_MS,
263
209
  SNIPPETS_DIR,
264
- RepoNeedsRecoveryError,
265
210
  RESTORE_BACKUP_MESSAGE,
266
211
  RECOMMENDED_PLUGINS,
267
212
  PublishSelectionsStore,
@@ -271,19 +216,18 @@ export {
271
216
  MANIFEST_FILENAMES,
272
217
  HISTORY_PAGE_LIMIT,
273
218
  GitHubAuthProvider,
274
- GenericTokenAuthProvider,
275
219
  GITHUB_HOST,
276
220
  FileTokenStore,
277
221
  DEFAULT_PRINT_OPTS,
278
222
  BuildError,
279
223
  BUILT_IN_THEME_IDS,
280
224
  BUILT_IN_TEMPLATE_IDS,
225
+ AUTO_SYNC_PUSH_INTERVAL_MINUTES,
281
226
  AUTO_SYNC_MIN_MINUTES,
282
227
  AUTO_SYNC_MAX_MINUTES,
283
228
  AUTO_SYNC_DEFAULT_MINUTES,
284
229
  AUTO_SNAPSHOT_MIN_MINUTES,
285
230
  AUTO_SNAPSHOT_MESSAGE,
286
231
  AUTO_SNAPSHOT_MAX_MINUTES,
287
- AUTO_SNAPSHOT_DEFAULT_MINUTES,
288
- APP_HEARTBEAT_FRESH_MS
232
+ AUTO_SNAPSHOT_DEFAULT_MINUTES
289
233
  };
@@ -1,20 +1,20 @@
1
1
  import {
2
2
  executeAndReport
3
- } from "./cli-5tffrg48.js";
3
+ } from "./cli-df7gcyns.js";
4
4
  import {
5
5
  log
6
- } from "./cli-v935c2ws.js";
6
+ } from "./cli-mcb484g3.js";
7
7
  import {
8
8
  UsageError,
9
9
  rejectExtraPositionals,
10
10
  rejectUnknownFlags
11
- } from "./cli-7e79d7se.js";
12
- import"./cli-afm8pa0h.js";
11
+ } from "./cli-dx6sxj2t.js";
12
+ import"./cli-ak1tagkr.js";
13
13
  import"./cli-c41yr7he.js";
14
14
  import {
15
15
  EXIT_CODES
16
16
  } from "./cli-46ycxe6r.js";
17
- import"./cli-k1065rkg.js";
17
+ import"./cli-w692g6dx.js";
18
18
  import"./cli-v5mp7a6q.js";
19
19
  import"./cli-37x76zdn.js";
20
20
 
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  runBuild,
3
3
  splitOutPath
4
- } from "./cli-5tffrg48.js";
4
+ } from "./cli-df7gcyns.js";
5
5
  import {
6
6
  log
7
- } from "./cli-v935c2ws.js";
7
+ } from "./cli-mcb484g3.js";
8
8
  import {
9
9
  UsageError,
10
10
  parseEngine,
@@ -12,13 +12,13 @@ import {
12
12
  parsePdfxFlavor,
13
13
  rejectExtraPositionals,
14
14
  rejectUnknownFlags
15
- } from "./cli-7e79d7se.js";
16
- import"./cli-afm8pa0h.js";
15
+ } from "./cli-dx6sxj2t.js";
16
+ import"./cli-ak1tagkr.js";
17
17
  import"./cli-c41yr7he.js";
18
18
  import {
19
19
  BuildError
20
20
  } from "./cli-46ycxe6r.js";
21
- import"./cli-k1065rkg.js";
21
+ import"./cli-w692g6dx.js";
22
22
  import"./cli-v5mp7a6q.js";
23
23
  import"./cli-37x76zdn.js";
24
24
 
@@ -5,3 +5,4 @@ import "./local-refs";
5
5
  import "./accessibility-alt-text";
6
6
  import "./accessibility-heading-order";
7
7
  import "./layout-markers";
8
+ import "./merge-markers";
@@ -0,0 +1,3 @@
1
+ import type { Check } from "../types";
2
+ declare const check: Check;
3
+ export default check;
@@ -1422,7 +1422,7 @@ 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-hg5eqv88.js";
1425
+ var preview_interface_default = "./preview-interface-0ssk8bmm.js";
1426
1426
 
1427
1427
  // src/assets/preview/scripts/preview-bridge.js
1428
1428
  var preview_bridge_default = "./preview-bridge-fz7vpk8m.js";
@@ -1434,7 +1434,7 @@ var preview_shell_default = "./preview-shell-c5mfa3q0.js";
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-fb6fhwsy.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; }