gutterpress 0.11.11-alpha.1 → 0.11.11-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/api/index.js +2 -2
- package/dist/{build-ycaavzsb.js → build-pjd42x09.js} +4 -4
- package/dist/checks/asset/extensions.d.ts +2 -2
- package/dist/checks/policy.d.ts +5 -7
- package/dist/checks/register-builtins.d.ts +6 -6
- package/dist/checks/registry.d.ts +1 -1
- package/dist/{cli-kgd355eh.js → cli-1kdtzgxm.js} +1 -1
- package/dist/{cli-g3xd0x9z.js → cli-d2he8zph.js} +6 -6
- package/dist/{cli-wtw5nfsx.js → cli-ny50k8md.js} +1 -1
- package/dist/{cli-p40641zw.js → cli-tjhn2mdn.js} +3 -3
- package/dist/cli.js +12 -12
- package/dist/{doctor-71dxjkpz.js → doctor-qkh9byxa.js} +2 -2
- package/dist/engine/shared/cdp.d.ts +5 -9
- package/dist/engine/shared/pdf-inspect.d.ts +0 -4
- package/dist/{engine-fv61tyn7.js → engine-132czsq9.js} +1 -1
- package/dist/{engine-sq1kpg5s.js → engine-bgd4aa99.js} +2 -2
- package/dist/{ext-rkfntmtv.js → ext-271xnh70.js} +4 -4
- package/dist/{index-dxt4t7et.js → index-b6p1fh61.js} +1 -1
- package/dist/{index-b7q4wev1.js → index-mw8b25yx.js} +3 -3
- package/dist/{index-wdqymw2k.js → index-ssjh6tnd.js} +5 -5
- package/dist/index.js +3 -3
- package/dist/lib/asset-inline.d.ts +1 -2
- package/dist/lib/build-error.d.ts +4 -6
- package/dist/lib/build-fingerprint.d.ts +3 -4
- package/dist/lib/build-preflight.d.ts +4 -6
- package/dist/lib/build-runner.d.ts +24 -35
- package/dist/lib/build-staging.d.ts +3 -5
- package/dist/lib/cli-args.d.ts +1 -1
- package/dist/lib/desktop.d.ts +2 -8
- package/dist/lib/engine.d.ts +2 -2
- package/dist/lib/exec.d.ts +3 -6
- package/dist/lib/fetch-timeout.d.ts +3 -4
- package/dist/lib/ghostscript.d.ts +1 -1
- package/dist/lib/host-policy.d.ts +6 -8
- package/dist/lib/image-inspect.d.ts +2 -2
- package/dist/lib/install-hints.d.ts +2 -3
- package/dist/lib/manifest-config.d.ts +2 -3
- package/dist/lib/manifest-doc.d.ts +2 -3
- package/dist/lib/manifest.d.ts +4 -7
- package/dist/lib/markdown/assemble.d.ts +7 -13
- package/dist/lib/markdown/gutterpress-css.d.ts +6 -9
- package/dist/lib/markdown/images.d.ts +0 -7
- package/dist/lib/markdown/index.d.ts +7 -11
- package/dist/lib/markdown/markers.d.ts +3 -4
- package/dist/lib/markdown/plugins.d.ts +9 -12
- package/dist/lib/markdown/renderer.d.ts +10 -14
- package/dist/lib/missing-asset-placeholder.d.ts +2 -5
- package/dist/lib/output-paths.d.ts +4 -5
- package/dist/lib/pdf-inspect.d.ts +5 -5
- package/dist/lib/pdf-parse.d.ts +6 -7
- package/dist/lib/presets.d.ts +2 -3
- package/dist/lib/project-source.d.ts +3 -4
- package/dist/lib/publish/command-runner.d.ts +1 -1
- package/dist/lib/publish/connect-google.d.ts +2 -2
- package/dist/lib/publish/types.d.ts +3 -3
- package/dist/lib/remote-auth/clone.d.ts +2 -2
- package/dist/lib/remote-auth/converge-merge.d.ts +1 -1
- package/dist/lib/remote-auth/diagnose.d.ts +3 -3
- package/dist/lib/remote-auth/generic-auth.d.ts +1 -1
- package/dist/lib/remote-auth/git-http.d.ts +5 -5
- package/dist/lib/remote-auth/github-auth.d.ts +3 -3
- package/dist/lib/remote-auth/github-repos.d.ts +4 -4
- package/dist/lib/remote-auth/sync-types.d.ts +1 -1
- package/dist/lib/remote-auth/sync.d.ts +1 -1
- package/dist/lib/remote-auth/test-access.d.ts +1 -1
- package/dist/lib/remote-auth/token-store.d.ts +1 -1
- package/dist/lib/remote-auth/transport.d.ts +3 -3
- package/dist/lib/render-parity-raster.d.ts +28 -0
- package/dist/lib/render-parity.d.ts +4 -1
- package/dist/lib/source-provider.d.ts +4 -5
- package/dist/lib/static-serve.d.ts +8 -13
- package/dist/lib/style-resolver.d.ts +1 -1
- package/dist/lib/targets.d.ts +1 -5
- package/dist/lib/tool-probe.d.ts +2 -3
- package/dist/lib/validation-exec.d.ts +3 -4
- package/dist/{new-c6pmpvhw.js → new-7w4ezfpy.js} +4 -4
- package/dist/platform.d.ts +8 -41
- package/dist/{preflight-9vq1ygh4.js → preflight-f3h6arjp.js} +4 -4
- package/dist/preview/file-watcher.d.ts +3 -5
- package/dist/preview/lifecycle.d.ts +9 -17
- package/dist/{preview-bridge-b4jbtb79.js → preview-bridge-8jhd1wpb.js} +1 -1
- package/dist/{preview-interface-x22vcqyw.js → preview-interface-twd6nsf5.js} +8 -10
- package/dist/{preview-shell-tqndvhbx.js → preview-shell-y8yrm3f0.js} +8 -19
- package/dist/{preview-6n5ava6c.js → preview-y39jrpbs.js} +4 -4
- package/dist/{publish-9an2a1ma.js → publish-tvj3xh8m.js} +4 -4
- package/dist/render.d.ts +5 -5
- package/dist/render.js +2 -2
- package/dist/schema/manifest.types.d.ts +2 -2
- package/dist/utils/logger.d.ts +1 -2
- package/dist/{validate-0rrjva48.js → validate-9enr4ecc.js} +4 -4
- package/package.json +1 -1
package/dist/lib/presets.d.ts
CHANGED
|
@@ -24,7 +24,7 @@ export type PresetId = (typeof PRESET_IDS)[number];
|
|
|
24
24
|
export declare const DTRPG_PRESET: VendorPreset;
|
|
25
25
|
/**
|
|
26
26
|
* A neutral, vendor-agnostic default for authors who aren't targeting a
|
|
27
|
-
* specific print vendor
|
|
27
|
+
* specific print vendor. Standard 6x9in trade-book trim size,
|
|
28
28
|
* no vendor total-area-coverage (TAC) cap, and no PDF/X forcing:
|
|
29
29
|
*
|
|
30
30
|
* - `page`: 6in x 9in (432 x 648pt) — the common generic trade paperback trim.
|
|
@@ -57,8 +57,7 @@ export declare function warnOnce(id: string, message: string, sink?: (msg: strin
|
|
|
57
57
|
/** Test-only reset hook — clears all warn-once dedup state. */
|
|
58
58
|
export declare function resetWarnOnce(): void;
|
|
59
59
|
/**
|
|
60
|
-
* Resolve a manifest/CLI `preset` value to the {@link VendorPreset} it names
|
|
61
|
-
* (UX finding M48).
|
|
60
|
+
* Resolve a manifest/CLI `preset` value to the {@link VendorPreset} it names.
|
|
62
61
|
*
|
|
63
62
|
* - Unset (`undefined`): defaults to `dtrpg`. That is the PRODUCT default,
|
|
64
63
|
* not a compatibility accident (ADR 0008): Gutterpress's primary audience
|
|
@@ -41,7 +41,7 @@ export type ProjectSource = {
|
|
|
41
41
|
* What the UI may offer for a given source. Derived purely from the source
|
|
42
42
|
* type; no I/O.
|
|
43
43
|
*
|
|
44
|
-
* NOTE
|
|
44
|
+
* NOTE: today the desktop only reads `canSnapshot` (it gates the
|
|
45
45
|
* StatusBar "Version history" affordance). The other flags —
|
|
46
46
|
* `canEnableVersionHistory`, `canViewHistory`, `canRestoreSnapshot`, `canRead`,
|
|
47
47
|
* `canWriteLocal`, `authManagedByApp` — are computed and part of the DTO but
|
|
@@ -51,9 +51,8 @@ export type ProjectSource = {
|
|
|
51
51
|
*
|
|
52
52
|
* Deliberately NO `canSync` here: syncability is a credential-aware question
|
|
53
53
|
* only `diagnoseProjectRemote().canSync` (remote-auth/diagnose.ts) can answer.
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
* were a recurring source of contradictory sync behavior. Remote PRESENCE, for
|
|
54
|
+
* A second, weaker `canSync` here (= hasRemote, any protocol, no credential
|
|
55
|
+
* check) would be a source of contradictory sync behavior. Remote PRESENCE, for
|
|
57
56
|
* display purposes, lives on the classification itself (`source.hasRemote`).
|
|
58
57
|
*/
|
|
59
58
|
export interface ProjectCapabilities {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CommandRunner } from "./types.ts";
|
|
2
2
|
/**
|
|
3
|
-
* Default idle budget
|
|
3
|
+
* Default idle budget: applied BY THE RUNNER whenever
|
|
4
4
|
* `timeoutMs` is omitted, so no call site (a provider upload, a
|
|
5
5
|
* `commandExists` probe) can silently regain hang-forever behavior by
|
|
6
6
|
* forgetting to pass it. `timeoutMs: 0` is the explicit opt-out. Idle, not
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared Google Drive connect flow (#221) — the ONE implementation behind
|
|
3
|
-
* both the CLI's `--connect` branch and
|
|
4
|
-
*
|
|
3
|
+
* both the CLI's `--connect` branch and the desktop's connect route, mirroring
|
|
4
|
+
* how `connect.ts` is shared for pasted-token providers.
|
|
5
5
|
*
|
|
6
6
|
* Unlike `connectPublishProvider` (verify-before-store for a PASTED token),
|
|
7
7
|
* this flow is verify-by-construction: `GoogleAuthProvider.connect()` only
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* (DriveThruRPG, Amazon KDP), stages a validated upload package and hands the
|
|
7
7
|
* author a checklist + the platform's upload URL ("guided" publishing).
|
|
8
8
|
*
|
|
9
|
-
* Architecture mirrors the remote-auth subsystem
|
|
9
|
+
* Architecture mirrors the remote-auth subsystem:
|
|
10
10
|
* - The lib NEVER touches OS keychains, the network, or child processes
|
|
11
11
|
* directly through ambient globals — hosts inject a {@link TokenStore},
|
|
12
12
|
* and tests inject {@link PublishDeps.fetch} / {@link PublishDeps.runCommand}.
|
|
@@ -89,7 +89,7 @@ export interface PublishProviderInfo {
|
|
|
89
89
|
* browser consent flow (see `google-auth.ts`'s `GoogleAuthProvider` for
|
|
90
90
|
* the gdrive precedent). UIs branch on this to swap the paste-a-key form
|
|
91
91
|
* for a "Connect …" button; {@link connectPublishProvider} REJECTS oauth
|
|
92
|
-
* providers outright so the
|
|
92
|
+
* providers outright so the paste-a-token path can never store an
|
|
93
93
|
* unverifiable credential for one (#221).
|
|
94
94
|
*/
|
|
95
95
|
connect?: "token" | "oauth";
|
|
@@ -135,7 +135,7 @@ export type CommandRunner = (cmd: string, args: string[], options?: {
|
|
|
135
135
|
/** Called once per output line — drives live progress logs. */
|
|
136
136
|
onOutput?: (line: string) => void;
|
|
137
137
|
/**
|
|
138
|
-
* Idle-kill budget in ms
|
|
138
|
+
* Idle-kill budget in ms. If the child produces no output and
|
|
139
139
|
* has not exited within this window, it is SIGKILL'd and the run rejects
|
|
140
140
|
* with a timeout error, so a stalled upload can't hang publish forever.
|
|
141
141
|
* Omitted / undefined = the runner's default (defaultCommandRunner applies
|
|
@@ -54,9 +54,9 @@ export interface CloneRepositoryResult {
|
|
|
54
54
|
*/
|
|
55
55
|
export declare function sanitizeCloneFolderName(name: string): string;
|
|
56
56
|
/**
|
|
57
|
-
* Clone a remote repository over smart HTTPS into `dir
|
|
57
|
+
* Clone a remote repository over smart HTTPS into `dir`.
|
|
58
58
|
*
|
|
59
|
-
* - HTTPS only (isomorphic-git has no SSH
|
|
59
|
+
* - HTTPS only (isomorphic-git has no SSH).
|
|
60
60
|
* - `singleBranch` always; `depth` opts into shallow (full by default — see
|
|
61
61
|
* the WHY on {@link CloneRepositoryOptions.depth}).
|
|
62
62
|
* - Tokens embedded in the URL are stripped and (when a `tokenStore` is
|
|
@@ -32,7 +32,7 @@ export interface ConvergeResult {
|
|
|
32
32
|
export declare const CONVERGE_PREPARE_MESSAGE = "Getting your changes ready to combine with the online version";
|
|
33
33
|
/** Snapshot message for the post-merge restore commit (kept-both/edits). */
|
|
34
34
|
export declare const CONVERGE_RESTORE_MESSAGE = "Kept both versions of the files that can't be combined";
|
|
35
|
-
/** The merge commit message
|
|
35
|
+
/** The merge commit message. */
|
|
36
36
|
export declare const CONVERGE_MERGE_MESSAGE = "Combined your changes with the online version";
|
|
37
37
|
/**
|
|
38
38
|
* diff3 merge that NEVER reports a conflict: clean hunks merge exactly like
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Project remote diagnostics (#14
|
|
2
|
+
* Project remote diagnostics (#14).
|
|
3
3
|
*
|
|
4
4
|
* Pure-lib replacement for the issue's original shell diagnostics
|
|
5
5
|
* (`git status` / `git remote -v` / `git branch --show-current` — all
|
|
@@ -26,7 +26,7 @@ export type ForgeKind = "github" | "gitea" | "forgejo" | "gitlab" | "bitbucket"
|
|
|
26
26
|
* - `ready-to-sync` — HTTPS remote with a stored credential (sync lands
|
|
27
27
|
* with #15's sync phase; the plumbing is in place).
|
|
28
28
|
* - `ssh-use-own-tools` — SSH remote: full local features, sync externally
|
|
29
|
-
*
|
|
29
|
+
* . The UI layers the "switch to HTTPS" hint on recognized hosts.
|
|
30
30
|
*/
|
|
31
31
|
export type RemoteGuidanceId = "local-only" | "connect-github-to-sync" | "https-connect-server" | "ready-to-sync" | "ssh-use-own-tools";
|
|
32
32
|
export interface ProjectRemoteDiagnosis {
|
|
@@ -45,7 +45,7 @@ export interface ProjectRemoteDiagnosis {
|
|
|
45
45
|
/** Token-settings deep link for recognized non-GitHub forges. */
|
|
46
46
|
tokenSettingsUrl: string | null;
|
|
47
47
|
/**
|
|
48
|
-
*
|
|
48
|
+
* hasRemote && smart-HTTPS && credential stored. The sync
|
|
49
49
|
* flow (#15 D5) is live, so this is the real "offer the Sync action"
|
|
50
50
|
* gate, not a future-capability hint.
|
|
51
51
|
*/
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Timeout wrapper for the isomorphic-git HTTP client
|
|
2
|
+
* Timeout wrapper for the isomorphic-git HTTP client.
|
|
3
3
|
*
|
|
4
4
|
* Every git transport call in this subsystem (`git.fetch`/`git.push`/
|
|
5
5
|
* `git.clone`) is invoked with no timeout: if the TCP connection succeeds but
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* guard every fetch with `AbortSignal.timeout`; this brings the same discipline
|
|
12
12
|
* to the git transport, at the one place a default client is chosen.
|
|
13
13
|
*
|
|
14
|
-
* Design (
|
|
14
|
+
* Design (a naive deadline on `request()` is WRONG for pushes):
|
|
15
15
|
* isomorphic-git passes upload bodies as an ARRAY of buffers, which the node
|
|
16
16
|
* client collects and sends with Content-Length — `request()` then resolves
|
|
17
17
|
* only when the response HEADERS arrive, i.e. after the ENTIRE pack upload.
|
|
@@ -67,9 +67,9 @@ export declare const SMALL_BODY_MAX_BYTES: number;
|
|
|
67
67
|
* {@link SMALL_BODY_MAX_BYTES}. isomorphic-git always passes bodies as arrays
|
|
68
68
|
* of byte chunks, so small ones are sizable synchronously. Any chunk WITHOUT
|
|
69
69
|
* a numeric byteLength makes the body unsizable → NOT small, so it gets the
|
|
70
|
-
* long upload backstop rather than the idle deadline as a total cap (
|
|
71
|
-
*
|
|
72
|
-
*
|
|
70
|
+
* long upload backstop rather than the idle deadline as a total cap (do not
|
|
71
|
+
* count unsizable chunks as 0 bytes — that is the exact opposite of that
|
|
72
|
+
* intent).
|
|
73
73
|
*/
|
|
74
74
|
export declare function isSmallBody(body: unknown): boolean;
|
|
75
75
|
/**
|
|
@@ -10,7 +10,7 @@ export interface DeviceCodeInfo {
|
|
|
10
10
|
/** Minimum seconds between token polls. */
|
|
11
11
|
interval: number;
|
|
12
12
|
}
|
|
13
|
-
/** Host-supplied callbacks for the interactive connect flow
|
|
13
|
+
/** Host-supplied callbacks for the interactive connect flow. */
|
|
14
14
|
export interface HostCallbacks {
|
|
15
15
|
/** Called once with the code/URL so the UI can display them. */
|
|
16
16
|
onUserCode(info: DeviceCodeInfo): void;
|
|
@@ -25,7 +25,7 @@ export interface HostCallbacks {
|
|
|
25
25
|
*/
|
|
26
26
|
export declare function resolveGitHubClientId(explicit?: string): string;
|
|
27
27
|
export declare const GITHUB_HOST = "github.com";
|
|
28
|
-
/** Author-friendly message for connectivity failures
|
|
28
|
+
/** Author-friendly message for connectivity failures. */
|
|
29
29
|
export declare const OFFLINE_MESSAGE = "Couldn't reach GitHub. Check your connection and try again.";
|
|
30
30
|
export interface GitHubAuthProviderOptions {
|
|
31
31
|
/** Explicit client id (overrides env + default). */
|
|
@@ -35,7 +35,7 @@ export interface GitHubAuthProviderOptions {
|
|
|
35
35
|
/** Injectable sleep for tests (so polling tests run instantly). */
|
|
36
36
|
sleepImpl?: (ms: number) => Promise<void>;
|
|
37
37
|
}
|
|
38
|
-
/** GitHub device-flow credential acquisition
|
|
38
|
+
/** GitHub device-flow credential acquisition. */
|
|
39
39
|
export declare class GitHubAuthProvider {
|
|
40
40
|
private readonly clientId;
|
|
41
41
|
private readonly fetchImpl;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* GitHub repo discovery (#15
|
|
2
|
+
* GitHub repo discovery (#15).
|
|
3
3
|
*
|
|
4
4
|
* Plain `fetch` against the GitHub REST API — deliberately no `@octokit`
|
|
5
5
|
* dependency. Lists every repository the user can access (`GET /user/repos`,
|
|
6
|
-
* the OAuth `repo`-scope model
|
|
6
|
+
* the OAuth `repo`-scope model), the
|
|
7
7
|
* branches of a chosen repository, and (via the Git Trees API) the gutterpress
|
|
8
8
|
* book projects inside a repo. The two REST listings paginate; the Git Trees
|
|
9
9
|
* call is a single request that handles the API's `truncated` flag instead. All
|
|
@@ -31,8 +31,8 @@ export interface GitHubApiOptions {
|
|
|
31
31
|
/**
|
|
32
32
|
* List every repository the user can access — own, collaborator, and org
|
|
33
33
|
* member — via `GET /user/repos` (paginated). The OAuth `repo` scope makes
|
|
34
|
-
* the full set visible with zero install/selection steps
|
|
35
|
-
*
|
|
34
|
+
* the full set visible with zero install/selection steps. `sort=pushed` puts
|
|
35
|
+
* recently-active books first; callers must
|
|
36
36
|
* PRESERVE this order (the picker renders it as "most recent first").
|
|
37
37
|
*/
|
|
38
38
|
export declare function listGitHubRepositories(credential: HostCredential, options?: GitHubApiOptions): Promise<RemoteRepository[]>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Type/interface declarations for snapshot-first sync
|
|
3
|
-
* (#15
|
|
3
|
+
* (#15). Shared by the orchestrator, transport and
|
|
4
4
|
* convergence modules share ONE definition of each result/option shape.
|
|
5
5
|
* Pure type surface — no runtime code.
|
|
6
6
|
*/
|
|
@@ -17,7 +17,7 @@ export declare function isPushRejected(e: unknown): boolean;
|
|
|
17
17
|
*/
|
|
18
18
|
export declare function isUnrelatedHistories(e: unknown): boolean;
|
|
19
19
|
/**
|
|
20
|
-
* Snapshot-first sync
|
|
20
|
+
* Snapshot-first sync. Serialized on the per-repo lock; one
|
|
21
21
|
* function-scoped object cache, released on return.
|
|
22
22
|
*
|
|
23
23
|
* If someone pushes between our fetch and our push, the push is rejected and
|
|
@@ -39,7 +39,7 @@ export declare const FAILURE_MESSAGES: Record<RemoteAccessFailureReason, string>
|
|
|
39
39
|
* - Never throws — every outcome is a classified {@link RemoteAccessResult}.
|
|
40
40
|
* - SSH URLs return `ssh-unsupported` with zero network traffic.
|
|
41
41
|
* - Credentials embedded in the URL are stripped and used for auth when no
|
|
42
|
-
* explicit credential is supplied
|
|
42
|
+
* explicit credential is supplied — they never leak onward.
|
|
43
43
|
* - `defaultBranch` comes from the server's `HEAD` symref when advertised.
|
|
44
44
|
*/
|
|
45
45
|
export declare function testRemoteAccess(options: TestRemoteAccessOptions): Promise<RemoteAccessResult>;
|
|
@@ -14,7 +14,7 @@ export interface HostCredential {
|
|
|
14
14
|
createdAt: number;
|
|
15
15
|
}
|
|
16
16
|
/**
|
|
17
|
-
* Host-keyed credential vault contract
|
|
17
|
+
* Host-keyed credential vault contract. Implementations
|
|
18
18
|
* are provided by the HOST APP (Electron safeStorage, CLI 0600 file); the lib
|
|
19
19
|
* only consumes this interface.
|
|
20
20
|
*/
|
|
@@ -19,8 +19,8 @@ export declare function isCredentialTransmissionSafe(url: string): boolean;
|
|
|
19
19
|
/**
|
|
20
20
|
* Thrown by {@link onAuthFor} when a stored credential EXISTS but the remote
|
|
21
21
|
* URL fails {@link isCredentialTransmissionSafe} (non-loopback http). Loud and
|
|
22
|
-
* typed on purpose: the
|
|
23
|
-
*
|
|
22
|
+
* typed on purpose: silently withholding the credential surfaces as a 401 →
|
|
23
|
+
* "auth" → "reconnect" loop. The `code` string is the
|
|
24
24
|
* STABLE contract (matchable across dynamic-import boundaries).
|
|
25
25
|
*/
|
|
26
26
|
export declare class InsecureTransportError extends Error {
|
|
@@ -70,7 +70,7 @@ export declare function failureOutcome(e: unknown, snapshotId?: string): {
|
|
|
70
70
|
export declare function setupErrorMessage(e: unknown): string | null;
|
|
71
71
|
/**
|
|
72
72
|
* Snapshot-first step used by syncProject
|
|
73
|
-
|
|
73
|
+
*: commit any unsaved work in the WHOLE repo BEFORE any network
|
|
74
74
|
* or merge step, so a forced post-merge checkout can never discard it. The
|
|
75
75
|
* working-tree check runs lazily at action time on the caller's function-scoped
|
|
76
76
|
* object cache (released with the operation).
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Diff } from "./render-parity.ts";
|
|
2
|
+
export interface RgbImage {
|
|
3
|
+
w: number;
|
|
4
|
+
h: number;
|
|
5
|
+
/** Packed RGB, 3 bytes per pixel. */
|
|
6
|
+
data: Uint8Array;
|
|
7
|
+
}
|
|
8
|
+
/** Parse a binary PPM (P6, maxval 255) — what `pdftoppm` writes by default. */
|
|
9
|
+
export declare function parsePpm(buf: Uint8Array): RgbImage;
|
|
10
|
+
/**
|
|
11
|
+
* Count pixels where any channel differs by more than `tolerance` (a fraction
|
|
12
|
+
* of 255; 0.01 = 1%), and return a copy of `cand` with those pixels painted
|
|
13
|
+
* red. Images of different sizes differ everywhere and get no diff image.
|
|
14
|
+
*/
|
|
15
|
+
export declare function comparePixels(base: RgbImage, cand: RgbImage, tolerance: number): {
|
|
16
|
+
differing: number;
|
|
17
|
+
marked: RgbImage | null;
|
|
18
|
+
};
|
|
19
|
+
/** Encode an RGB image as a PNG (8-bit truecolour, no filtering). */
|
|
20
|
+
export declare function encodePng(img: RgbImage): Uint8Array;
|
|
21
|
+
/**
|
|
22
|
+
* Raster-compare the first `pageCount` pages of two PDFs. Returns one `raster`
|
|
23
|
+
* diff per differing page and writes `diff-NNN.png` for each into `outDir`.
|
|
24
|
+
*/
|
|
25
|
+
export declare function rasterDiffs(basePdf: string, candPdf: string, pageCount: number, outDir: string, options?: {
|
|
26
|
+
dpi?: number;
|
|
27
|
+
tolerance?: number;
|
|
28
|
+
}): Promise<Diff[]>;
|
|
@@ -41,7 +41,7 @@ export declare function extractReport(pdfPath: string): Promise<Report>;
|
|
|
41
41
|
* rounded to 3 decimals before it gets here.
|
|
42
42
|
*/
|
|
43
43
|
export declare function serializeReport(report: Report): string;
|
|
44
|
-
export type WaiverKind = "page-count" | "page-size" | "text" | "image";
|
|
44
|
+
export type WaiverKind = "page-count" | "page-size" | "text" | "image" | "raster";
|
|
45
45
|
export interface Waiver {
|
|
46
46
|
/** 1-based page number. Omit for kind "page-count" (there is no page). */
|
|
47
47
|
page?: number;
|
|
@@ -70,6 +70,9 @@ export interface CompareOptions {
|
|
|
70
70
|
/** Points. Applies to text run and image extents (x/y/w/h). Default 0.5. */
|
|
71
71
|
tolerance?: number;
|
|
72
72
|
waivers?: Waiver[];
|
|
73
|
+
/** Diffs found outside the report — the `raster` diffs of `compare
|
|
74
|
+
* --raster` (render-parity-raster.ts) — waived like every other kind. */
|
|
75
|
+
extraDiffs?: Diff[];
|
|
73
76
|
}
|
|
74
77
|
export interface CompareResult {
|
|
75
78
|
/** Diffs NOT excused by any waiver — non-empty means the gate fails. */
|
|
@@ -105,7 +105,7 @@ export interface SourceProvider {
|
|
|
105
105
|
/**
|
|
106
106
|
* Run `fn` exclusively per resolved project dir (FIFO promise chaining).
|
|
107
107
|
* Exported for the remote-clone surface (#15) so clone/fetch operations share
|
|
108
|
-
* the SAME queue as snapshot/restore —
|
|
108
|
+
* the SAME queue as snapshot/restore — one per-repo lock.
|
|
109
109
|
*/
|
|
110
110
|
export declare function withRepoLock<T>(projectDir: string, fn: () => Promise<T>): Promise<T>;
|
|
111
111
|
/**
|
|
@@ -164,7 +164,7 @@ export declare function stageChanges(dir: string, changes: WorkdirChanges, cache
|
|
|
164
164
|
/**
|
|
165
165
|
* True when the working tree differs from the index (added/modified/deleted
|
|
166
166
|
* files). Used to skip empty snapshots. Exported (lock-free) for the sync
|
|
167
|
-
* surface (#15
|
|
167
|
+
* surface (#15) — callers outside a lock should prefer the
|
|
168
168
|
* provider operations.
|
|
169
169
|
*/
|
|
170
170
|
export declare function hasPendingChanges(dir: string, cache?: GitCache): Promise<boolean>;
|
|
@@ -177,14 +177,13 @@ export declare function hasPendingChanges(dir: string, cache?: GitCache): Promis
|
|
|
177
177
|
* sync-check path per the sync-simplicity mandate): this is for build
|
|
178
178
|
* *provenance* — the build fingerprint records whether the tree was clean at
|
|
179
179
|
* build time, where a `git add`-ed-but-not-committed change must still count
|
|
180
|
-
* as dirty (the
|
|
181
|
-
* WORKDIR-vs-STAGE-only check silently dropped it).
|
|
180
|
+
* as dirty (the WORKDIR-vs-STAGE-only check silently drops it).
|
|
182
181
|
*/
|
|
183
182
|
export declare function hasUncommittedChanges(dir: string, cache?: GitCache): Promise<boolean>;
|
|
184
183
|
/**
|
|
185
184
|
* Lock-free snapshot of the full working tree (stage everything + commit).
|
|
186
185
|
*
|
|
187
|
-
* Exported for the sync surface (#15
|
|
186
|
+
* Exported for the sync surface (#15): `syncProject` holds
|
|
188
187
|
* the per-repo lock for snapshot → fetch → merge → push as ONE sequence, so it
|
|
189
188
|
* needs the lock-free internal rather than `provider.snapshot()` (taking the
|
|
190
189
|
* per-method lock inside the sync lock would deadlock the FIFO queue).
|
|
@@ -4,20 +4,15 @@ import http from "node:http";
|
|
|
4
4
|
* in this package: the build-time pagination server and PDF-render server
|
|
5
5
|
* (build-runner.ts) and the live preview server (preview/http-server.ts).
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* in preview vs build-time pagination with no error, a silent divergence
|
|
10
|
-
* class. One table now; add a new extension once.
|
|
7
|
+
* One table for every server: a type added to only one would render
|
|
8
|
+
* differently in preview vs build-time pagination with no error.
|
|
11
9
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* servers above. Added below; if a third image format shows up, add it to
|
|
19
|
-
* BOTH tables in the same commit (asset-inline.ts is out of scope for this
|
|
20
|
-
* PR — see docs/reviews/duplication-audit-2026-07-28.md).
|
|
10
|
+
* `asset-inline.ts`'s `MIME_BY_EXT` is a separate table answering a separate
|
|
11
|
+
* question ("what Content-Type does a data: URI need when embedding this file
|
|
12
|
+
* inline" vs. this table's "what Content-Type does an HTTP response need"). A
|
|
13
|
+
* new image format must be added to BOTH tables in the same commit, or (as
|
|
14
|
+
* once happened with `.webp`/`.avif`) a copied image is served as
|
|
15
|
+
* `application/octet-stream`.
|
|
21
16
|
*/
|
|
22
17
|
export declare const STATIC_MIME: Record<string, string>;
|
|
23
18
|
/**
|
|
@@ -34,7 +34,7 @@ export declare function resolveActiveStyles(projectDir: string, manifestStyles?:
|
|
|
34
34
|
* the way the manifest stores them — project-relative, e.g.
|
|
35
35
|
* `../../shared/styles/components.css` — so toggling one on writes the right
|
|
36
36
|
* entry. Omit it (or pass the project itself) for the single-project case, which
|
|
37
|
-
*
|
|
37
|
+
* scans only the project.
|
|
38
38
|
*/
|
|
39
39
|
export declare function listProjectStyles(projectDir: string, opts?: {
|
|
40
40
|
repoRoot?: string;
|
package/dist/lib/targets.d.ts
CHANGED
|
@@ -17,9 +17,6 @@ import { type VendorPreset } from "./presets";
|
|
|
17
17
|
* skipped because its tools are missing becomes a synthetic error, so
|
|
18
18
|
* "validated for dtrpg" can never silently mean "the dtrpg checks didn't
|
|
19
19
|
* run".
|
|
20
|
-
*
|
|
21
|
-
* Grown from the old `validate --profile dtrpg` (validation-profile.ts,
|
|
22
|
-
* deleted): the profile was this exact idea hardcoded for one destination.
|
|
23
20
|
*/
|
|
24
21
|
/** The deep-partial preset shape a target may overlay. */
|
|
25
22
|
export type TargetOverlay = {
|
|
@@ -77,8 +74,7 @@ export declare function overlayPreset(preset: VendorPreset, target: PublishTarge
|
|
|
77
74
|
* The strict-PDF fill-ins applied to EVERY post-build PDF validation
|
|
78
75
|
* regardless of preset/target: any of these left `undefined` by the config
|
|
79
76
|
* becomes an error-severity check, without overwriting an author's explicit
|
|
80
|
-
* choice (including an explicit disable).
|
|
81
|
-
* validation-profile.ts (ARCH #21).
|
|
77
|
+
* choice (including an explicit disable).
|
|
82
78
|
*/
|
|
83
79
|
export declare const DEFAULT_STRICT_PDF_CHECKS: readonly ["pdf.structure.qpdf", "pdf.print.pdfx-markers", "pdf.print.pdfx-metadata", "pdf.print.embedded-fonts"];
|
|
84
80
|
export declare function applyDefaultPdfStrictChecks(config: ResolvedConfig): ResolvedConfig;
|
package/dist/lib/tool-probe.d.ts
CHANGED
|
@@ -19,9 +19,8 @@
|
|
|
19
19
|
*
|
|
20
20
|
* One implementation; one place to fix bugs. Spawning goes through
|
|
21
21
|
* exec.ts's `execCapture`, which also owns the shared, correctly
|
|
22
|
-
* delimiter-joined `enhancedPath`
|
|
23
|
-
*
|
|
24
|
-
* docs/reviews 2026-07-10-architecture-critical-review.md, finding #3).
|
|
22
|
+
* delimiter-joined `enhancedPath` — do not keep a second copy of that PATH
|
|
23
|
+
* construction here.
|
|
25
24
|
*/
|
|
26
25
|
/**
|
|
27
26
|
* Returns true if `tool` is resolvable via the platform's path-probe command.
|
|
@@ -30,10 +30,9 @@ export interface ValidationExecutionArgs {
|
|
|
30
30
|
* only, without touching the manifest's `validate.source.stylelint`
|
|
31
31
|
* setting on disk (#272 — one CSS gate, not two). Set by the build
|
|
32
32
|
* pipeline's `runQualityGates` (build-runner.ts) from `--skip-lint` /
|
|
33
|
-
* `config.lint.enabled: false`, so that flag disables just
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* panel) leaves this unset and gets the manifest's own setting.
|
|
33
|
+
* `config.lint.enabled: false`, so that flag disables just this one check.
|
|
34
|
+
* Every other caller (`gutterpress validate`/`preflight`, the desktop
|
|
35
|
+
* Problems panel) leaves this unset and gets the manifest's own setting.
|
|
37
36
|
*/
|
|
38
37
|
skipStylelint?: boolean;
|
|
39
38
|
/**
|
|
@@ -7,16 +7,16 @@ import {
|
|
|
7
7
|
TARGET_IDS,
|
|
8
8
|
scaffoldExtension,
|
|
9
9
|
scaffoldProject
|
|
10
|
-
} from "./cli-
|
|
10
|
+
} from "./cli-d2he8zph.js";
|
|
11
11
|
import {
|
|
12
12
|
resolveGhostscript
|
|
13
|
-
} from "./cli-
|
|
13
|
+
} from "./cli-1kdtzgxm.js";
|
|
14
14
|
import {
|
|
15
15
|
UsageError,
|
|
16
16
|
rejectExtraPositionals,
|
|
17
17
|
rejectUnknownFlags
|
|
18
|
-
} from "./cli-
|
|
19
|
-
import"./cli-
|
|
18
|
+
} from "./cli-ny50k8md.js";
|
|
19
|
+
import"./cli-tjhn2mdn.js";
|
|
20
20
|
import {
|
|
21
21
|
EXIT_CODES
|
|
22
22
|
} from "./cli-46ycxe6r.js";
|
package/dist/platform.d.ts
CHANGED
|
@@ -2,22 +2,19 @@
|
|
|
2
2
|
* Platform abstraction contract (GitHub #41).
|
|
3
3
|
*
|
|
4
4
|
* The desktop talks to its host through ONE seam so that the app code never
|
|
5
|
-
* branches on
|
|
6
|
-
*
|
|
7
|
-
* backed by the File System Access API drops in behind the same interface and
|
|
8
|
-
* the app code does not change.
|
|
5
|
+
* branches on the host directly. The only host is Electron (IPC + native
|
|
6
|
+
* dialogs).
|
|
9
7
|
*
|
|
10
8
|
* This module is **types only** — it is imported by the browser SPA via
|
|
11
9
|
* `import type`, so it must never pull in a Node runtime dependency.
|
|
12
10
|
*
|
|
13
11
|
* Canonical home: `gutterpress`. The desktop re-exports these types
|
|
14
|
-
* from `src/lib/platform/` and implements them in `electron-adapter.ts
|
|
15
|
-
*
|
|
12
|
+
* from `src/lib/platform/` and implements them in `electron-adapter.ts`.
|
|
13
|
+
* Keep the implementation in lockstep with this contract.
|
|
16
14
|
*/
|
|
17
15
|
/**
|
|
18
|
-
* The narrow set of
|
|
19
|
-
*
|
|
20
|
-
* IO, filesystem watching, and OS-keychain-backed secrets.
|
|
16
|
+
* The narrow set of host file primitives: raw file IO and filesystem
|
|
17
|
+
* watching.
|
|
21
18
|
*
|
|
22
19
|
* Host RPC services that are *also* host-divergent (preview/build/doctor/prefs/
|
|
23
20
|
* updater) are modelled separately as {@link HostServices} so this primitive
|
|
@@ -45,56 +42,26 @@ export interface FileWriteResult {
|
|
|
45
42
|
mtimeMs: number;
|
|
46
43
|
}
|
|
47
44
|
export interface PlatformAdapter {
|
|
48
|
-
/** Which host backs this adapter. Lets the rare unavoidable branch be explicit. */
|
|
49
|
-
readonly platform: "electron" | "web";
|
|
50
|
-
/**
|
|
51
|
-
* Prompt the user to choose a project folder.
|
|
52
|
-
* @returns the absolute path, or `null` if the user cancelled.
|
|
53
|
-
* Electron: native directory dialog. Web: File System Access API.
|
|
54
|
-
*/
|
|
55
|
-
openFolder(): Promise<string | null>;
|
|
56
45
|
/**
|
|
57
46
|
* Read a UTF-8 text file by absolute path.
|
|
58
|
-
* Editor seam for #38/#39 — no current consumer in 0.4.0.
|
|
59
47
|
*/
|
|
60
48
|
readFile(path: string): Promise<string>;
|
|
61
49
|
/**
|
|
62
50
|
* Write a UTF-8 text file by absolute path, creating/overwriting it.
|
|
63
51
|
* Resolves with the post-write {@link FileWriteResult} (`{ mtimeMs }`) so the
|
|
64
|
-
* editor (#44) can record the on-disk baseline mtime
|
|
65
|
-
* value are unaffected (additive widening — was `Promise<void>`).
|
|
52
|
+
* editor (#44) can record the on-disk baseline mtime.
|
|
66
53
|
*/
|
|
67
54
|
writeFile(path: string, content: string): Promise<FileWriteResult>;
|
|
68
|
-
/**
|
|
69
|
-
* List the immediate entries of a directory (single level, no recursion).
|
|
70
|
-
* @returns each entry's `name`, absolute `path`, and whether it `isDir`.
|
|
71
|
-
* Editor seam for #38 (file-tree sidebar). Electron: `node:fs/promises`
|
|
72
|
-
* `readdir`. Web: File System Access API (0.6.0).
|
|
73
|
-
*/
|
|
74
|
-
listDir(path: string): Promise<Array<{
|
|
75
|
-
name: string;
|
|
76
|
-
path: string;
|
|
77
|
-
isDir: boolean;
|
|
78
|
-
}>>;
|
|
79
55
|
/**
|
|
80
56
|
* Stat a file by absolute path (GitHub #44). Used by the editor to confirm a
|
|
81
57
|
* `watchFolder` event reflects a real on-disk change (mtime moved) versus the
|
|
82
58
|
* self-echo of our own `writeFile`. Resolves with `exists: false` rather than
|
|
83
|
-
* rejecting when the path is absent.
|
|
59
|
+
* rejecting when the path is absent.
|
|
84
60
|
*/
|
|
85
61
|
statFile(path: string): Promise<FileStat>;
|
|
86
62
|
/**
|
|
87
63
|
* Watch a folder for changes, invoking `cb` on each change.
|
|
88
64
|
* @returns an unsubscribe function.
|
|
89
|
-
* Web has no general recursive-watch primitive — `WebAdapter` throws here
|
|
90
|
-
* until 0.6.0. Electron wiring lands with the in-app editor (#38).
|
|
91
65
|
*/
|
|
92
66
|
watchFolder(path: string, cb: () => void): () => void;
|
|
93
|
-
/**
|
|
94
|
-
* Read a secret by key (e.g. a GitHub token). Lands with #12.
|
|
95
|
-
* Electron: OS keychain via `safeStorage`. Web: encrypted localStorage.
|
|
96
|
-
*/
|
|
97
|
-
getSecret(key: string): Promise<string | null>;
|
|
98
|
-
/** Store a secret by key. Lands with #12. */
|
|
99
|
-
setSecret(key: string, value: string): Promise<void>;
|
|
100
67
|
}
|
|
@@ -2,16 +2,16 @@ import {
|
|
|
2
2
|
executeValidation,
|
|
3
3
|
publishTargetFor,
|
|
4
4
|
reportMissingTools
|
|
5
|
-
} from "./cli-
|
|
5
|
+
} from "./cli-d2he8zph.js";
|
|
6
6
|
import {
|
|
7
7
|
log
|
|
8
|
-
} from "./cli-
|
|
8
|
+
} from "./cli-1kdtzgxm.js";
|
|
9
9
|
import {
|
|
10
10
|
UsageError,
|
|
11
11
|
rejectExtraPositionals,
|
|
12
12
|
rejectUnknownFlags
|
|
13
|
-
} from "./cli-
|
|
14
|
-
import"./cli-
|
|
13
|
+
} from "./cli-ny50k8md.js";
|
|
14
|
+
import"./cli-tjhn2mdn.js";
|
|
15
15
|
import {
|
|
16
16
|
EXIT_CODES
|
|
17
17
|
} from "./cli-46ycxe6r.js";
|
|
@@ -125,11 +125,9 @@ export declare function externalWatchTargets(projectDir: string, config: {
|
|
|
125
125
|
* Create and configure a file watcher for the project's input directory plus
|
|
126
126
|
* the book's declared external dependencies (see {@link externalWatchTargets}).
|
|
127
127
|
*
|
|
128
|
-
* Nothing is mirrored anywhere: the
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
* The project is served straight from disk and stylesheets are inlined at
|
|
132
|
-
* render time, so an external dependency needs watching, not staging.
|
|
128
|
+
* Nothing is mirrored anywhere: the project is served straight from disk and
|
|
129
|
+
* stylesheets are inlined at render time, so an external dependency needs
|
|
130
|
+
* watching, not staging.
|
|
133
131
|
*/
|
|
134
132
|
export declare function createFileWatcher(state: ServerState): FSWatcher;
|
|
135
133
|
/**
|