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.
- package/README.md +422 -0
- package/dist/CGATS21_CRPC1-g0e3k7kr.icc +0 -0
- package/dist/api/index.d.ts +76 -0
- package/dist/api/index.js +272 -0
- package/dist/assets/preview/scripts/pagedjs-bridge.d.ts +1 -0
- package/dist/assets/preview/scripts/pagedjs-interface.d.ts +1 -0
- package/dist/assets/preview/scripts/preview-shell.d.ts +1 -0
- package/dist/audit-1jrwwacz.js +66 -0
- package/dist/build-5s92kgpc.js +77 -0
- package/dist/chapter-01-6fn9pvd0.md +31 -0
- package/dist/chapter-01-7jwqg1ct.md +20 -0
- package/dist/chapter-01-jj8ftn4c.md +29 -0
- package/dist/chapter-01-rkpyvjna.md +26 -0
- package/dist/checks/asset/approved-fonts.d.ts +3 -0
- package/dist/checks/asset/extensions.d.ts +41 -0
- package/dist/checks/asset/font-license.d.ts +3 -0
- package/dist/checks/asset/image-alpha.d.ts +3 -0
- package/dist/checks/asset/image-color-space.d.ts +3 -0
- package/dist/checks/asset/image-file-size.d.ts +3 -0
- package/dist/checks/asset/image-resolution.d.ts +3 -0
- package/dist/checks/asset/image-tac.d.ts +3 -0
- package/dist/checks/asset/index.d.ts +7 -0
- package/dist/checks/formatter.d.ts +3 -0
- package/dist/checks/heuristic/index.d.ts +4 -0
- package/dist/checks/heuristic/layer-count.d.ts +3 -0
- package/dist/checks/heuristic/placement-variance.d.ts +3 -0
- package/dist/checks/heuristic/section-density.d.ts +3 -0
- package/dist/checks/heuristic/text-density.d.ts +3 -0
- package/dist/checks/pdf/bleed.d.ts +3 -0
- package/dist/checks/pdf/bookmarks.d.ts +3 -0
- package/dist/checks/pdf/color-spaces.d.ts +3 -0
- package/dist/checks/pdf/cross-refs.d.ts +3 -0
- package/dist/checks/pdf/embedded-fonts.d.ts +3 -0
- package/dist/checks/pdf/image-resolution.d.ts +3 -0
- package/dist/checks/pdf/index.d.ts +15 -0
- package/dist/checks/pdf/ink-coverage.d.ts +3 -0
- package/dist/checks/pdf/page-labels.d.ts +3 -0
- package/dist/checks/pdf/page-size.d.ts +3 -0
- package/dist/checks/pdf/pdfx-markers.d.ts +3 -0
- package/dist/checks/pdf/pdfx-metadata.d.ts +3 -0
- package/dist/checks/pdf/pdfx-structure.d.ts +6 -0
- package/dist/checks/pdf/qpdf-structure.d.ts +3 -0
- package/dist/checks/pdf/rasterized-pages.d.ts +3 -0
- package/dist/checks/pdf/toc-links.d.ts +3 -0
- package/dist/checks/pdf/transparency.d.ts +3 -0
- package/dist/checks/policy.d.ts +61 -0
- package/dist/checks/register-builtins.d.ts +17 -0
- package/dist/checks/registry.d.ts +40 -0
- package/dist/checks/runner.d.ts +25 -0
- package/dist/checks/source/accessibility-alt-text.d.ts +3 -0
- package/dist/checks/source/accessibility-heading-order.d.ts +3 -0
- package/dist/checks/source/config-file.d.ts +8 -0
- package/dist/checks/source/htmlhint.d.ts +3 -0
- package/dist/checks/source/index.d.ts +6 -0
- package/dist/checks/source/local-refs.d.ts +3 -0
- package/dist/checks/source/markdownlint.d.ts +3 -0
- package/dist/checks/source/stylelint.d.ts +3 -0
- package/dist/checks/tool-check.d.ts +23 -0
- package/dist/checks/types.d.ts +52 -0
- package/dist/cli-1tyj4bk3.js +124 -0
- package/dist/cli-37x76zdn.js +4 -0
- package/dist/cli-506tg37g.js +26 -0
- package/dist/cli-5bxx0c4y.js +464 -0
- package/dist/cli-7ykx7pp0.js +12378 -0
- package/dist/cli-h7phg3ka.js +746 -0
- package/dist/cli-hvqjs342.js +284 -0
- package/dist/cli-yja077f6.js +92 -0
- package/dist/cli.js +157 -0
- package/dist/constants.d.ts +17 -0
- package/dist/doctor-25zjt8dz.js +57 -0
- package/dist/favicon-wkbm9cjn.ico +0 -0
- package/dist/git-http-yrb4ag6z.js +17 -0
- package/dist/index-1tyj4bk3.js +124 -0
- package/dist/index-37x76zdn.js +4 -0
- package/dist/index-3h3fef7r.js +15218 -0
- package/dist/index-5bxx0c4y.js +464 -0
- package/dist/index-yja077f6.js +92 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.js +310 -0
- package/dist/lib/app-heartbeat.d.ts +102 -0
- package/dist/lib/asset-inline.d.ts +73 -0
- package/dist/lib/browser-pool.d.ts +17 -0
- package/dist/lib/build-error.d.ts +52 -0
- package/dist/lib/build-fingerprint.d.ts +15 -0
- package/dist/lib/build-preflight.d.ts +43 -0
- package/dist/lib/build-runner.d.ts +161 -0
- package/dist/lib/build-staging.d.ts +64 -0
- package/dist/lib/chromium.d.ts +20 -0
- package/dist/lib/cli-args.d.ts +45 -0
- package/dist/lib/desktop.d.ts +14 -0
- package/dist/lib/diagnostics.d.ts +64 -0
- package/dist/lib/embedded-assets.d.ts +29 -0
- package/dist/lib/exec.d.ts +84 -0
- package/dist/lib/fetch-timeout.d.ts +41 -0
- package/dist/lib/ghostscript.d.ts +48 -0
- package/dist/lib/host-policy.d.ts +75 -0
- package/dist/lib/image-inspect.d.ts +32 -0
- package/dist/lib/install-hints.d.ts +21 -0
- package/dist/lib/lint-runner.d.ts +10 -0
- package/dist/lib/manifest-config.d.ts +31 -0
- package/dist/lib/manifest-doc.d.ts +25 -0
- package/dist/lib/manifest.d.ts +41 -0
- package/dist/lib/markdown/assemble.d.ts +78 -0
- package/dist/lib/markdown/chapter-id.d.ts +24 -0
- package/dist/lib/markdown/images.d.ts +34 -0
- package/dist/lib/markdown/index.d.ts +78 -0
- package/dist/lib/markdown/markdown-it-paged.d.ts +30 -0
- package/dist/lib/markdown/plugins.d.ts +69 -0
- package/dist/lib/markdown/renderer.d.ts +111 -0
- package/dist/lib/npm-plugin-installer.d.ts +33 -0
- package/dist/lib/open-path.d.ts +5 -0
- package/dist/lib/output-paths.d.ts +23 -0
- package/dist/lib/pagedjs-marker.d.ts +42 -0
- package/dist/lib/pagedjs.d.ts +26 -0
- package/dist/lib/pagination.d.ts +169 -0
- package/dist/lib/pdf-inspect.d.ts +123 -0
- package/dist/lib/pdf-parse.d.ts +57 -0
- package/dist/lib/plugin-manager.d.ts +108 -0
- package/dist/lib/plugin-vendor.d.ts +107 -0
- package/dist/lib/presets.d.ts +45 -0
- package/dist/lib/printsafe.d.ts +17 -0
- package/dist/lib/project-scaffold.d.ts +116 -0
- package/dist/lib/project-source.d.ts +140 -0
- package/dist/lib/project-templates.d.ts +49 -0
- package/dist/lib/publish/butler.d.ts +10 -0
- package/dist/lib/publish/command-runner.d.ts +18 -0
- package/dist/lib/publish/connect.d.ts +23 -0
- package/dist/lib/publish/manifest-publish.d.ts +9 -0
- package/dist/lib/publish/providers/azure-swa.d.ts +3 -0
- package/dist/lib/publish/providers/drivethrurpg.d.ts +10 -0
- package/dist/lib/publish/providers/guided.d.ts +3 -0
- package/dist/lib/publish/providers/itch.d.ts +5 -0
- package/dist/lib/publish/providers/kdp.d.ts +9 -0
- package/dist/lib/publish/providers/shopify.d.ts +5 -0
- package/dist/lib/publish/registry.d.ts +5 -0
- package/dist/lib/publish/run-publish.d.ts +30 -0
- package/dist/lib/publish/selections.d.ts +25 -0
- package/dist/lib/publish/types.d.ts +258 -0
- package/dist/lib/remote-auth/clone.d.ts +87 -0
- package/dist/lib/remote-auth/conflict-resolution.d.ts +29 -0
- package/dist/lib/remote-auth/diagnose.d.ts +77 -0
- package/dist/lib/remote-auth/generic-auth.d.ts +97 -0
- package/dist/lib/remote-auth/git-http.d.ts +85 -0
- package/dist/lib/remote-auth/github-auth.d.ts +69 -0
- package/dist/lib/remote-auth/github-repos.d.ts +64 -0
- package/dist/lib/remote-auth/operation-log.d.ts +66 -0
- package/dist/lib/remote-auth/recovery/abort-interrupted-operation.d.ts +103 -0
- package/dist/lib/remote-auth/recovery/backup.d.ts +113 -0
- package/dist/lib/remote-auth/recovery/classify.d.ts +109 -0
- package/dist/lib/remote-auth/recovery/context.d.ts +47 -0
- package/dist/lib/remote-auth/recovery/dispatch.d.ts +33 -0
- package/dist/lib/remote-auth/recovery/failsafe.d.ts +33 -0
- package/dist/lib/remote-auth/recovery/inspect.d.ts +74 -0
- package/dist/lib/remote-auth/recovery/manual-guidance.d.ts +28 -0
- package/dist/lib/remote-auth/recovery/outcome-mapping.d.ts +58 -0
- package/dist/lib/remote-auth/recovery/policy.d.ts +47 -0
- package/dist/lib/remote-auth/recovery/recover-auth.d.ts +42 -0
- package/dist/lib/remote-auth/recovery/recover-binary-conflict.d.ts +37 -0
- package/dist/lib/remote-auth/recovery/recover-corrupt-index.d.ts +40 -0
- package/dist/lib/remote-auth/recovery/recover-detached-head.d.ts +70 -0
- package/dist/lib/remote-auth/recovery/recover-interrupted-cherry-pick.d.ts +23 -0
- package/dist/lib/remote-auth/recovery/recover-interrupted-merge.d.ts +28 -0
- package/dist/lib/remote-auth/recovery/recover-interrupted-rebase.d.ts +39 -0
- package/dist/lib/remote-auth/recovery/recover-merge-conflict.d.ts +34 -0
- package/dist/lib/remote-auth/recovery/recover-missing-git-dir.d.ts +37 -0
- package/dist/lib/remote-auth/recovery/recover-missing-objects.d.ts +56 -0
- package/dist/lib/remote-auth/recovery/recover-network.d.ts +34 -0
- package/dist/lib/remote-auth/recovery/recover-non-fast-forward.d.ts +27 -0
- package/dist/lib/remote-auth/recovery/recover-stale-lock.d.ts +76 -0
- package/dist/lib/remote-auth/recovery/recover-unrelated-histories.d.ts +44 -0
- package/dist/lib/remote-auth/recovery/recover-wrong-remote.d.ts +35 -0
- package/dist/lib/remote-auth/recovery/types.d.ts +235 -0
- package/dist/lib/remote-auth/resolution-plan.d.ts +64 -0
- package/dist/lib/remote-auth/sync-messages.d.ts +26 -0
- package/dist/lib/remote-auth/sync-types.d.ts +225 -0
- package/dist/lib/remote-auth/sync.d.ts +45 -0
- package/dist/lib/remote-auth/test-access.d.ts +47 -0
- package/dist/lib/remote-auth/test-support/git-http-server.d.ts +71 -0
- package/dist/lib/remote-auth/token-store.d.ts +95 -0
- package/dist/lib/remote-auth/transport.d.ts +105 -0
- package/dist/lib/slug.d.ts +28 -0
- package/dist/lib/snippets.d.ts +39 -0
- package/dist/lib/source-provider.d.ts +244 -0
- package/dist/lib/static-serve.d.ts +54 -0
- package/dist/lib/style-resolver.d.ts +30 -0
- package/dist/lib/theme-import.d.ts +70 -0
- package/dist/lib/theme-manager.d.ts +128 -0
- package/dist/lib/tool-probe.d.ts +37 -0
- package/dist/lib/validation-exec.d.ts +47 -0
- package/dist/lib/validation-profile.d.ts +18 -0
- package/dist/lib/version.d.ts +9 -0
- package/dist/lint-f63nxjfj.js +65 -0
- package/dist/manifest-n1gh3qw5.yaml +9 -0
- package/dist/manifest-ryyg71nf.yaml +9 -0
- package/dist/manifest.schema-rn1dpdpn.json +564 -0
- package/dist/new-7b08a42h.js +105 -0
- package/dist/paged.polyfill-n95pbxfn.js +33288 -0
- package/dist/pagedjs-bridge-vn4hk9fx.js +111 -0
- package/dist/pagedjs-interface-80g3xa8p.js +498 -0
- package/dist/platform.d.ts +100 -0
- package/dist/plugin-wf2cbmwc.js +129 -0
- package/dist/preflight-tg4mpz1h.js +222 -0
- package/dist/preview/file-watcher.d.ts +174 -0
- package/dist/preview/http-server.d.ts +45 -0
- package/dist/preview/lifecycle.d.ts +67 -0
- package/dist/preview/server-context.d.ts +36 -0
- package/dist/preview-h2bwbb2x.js +102 -0
- package/dist/preview-shell-rghtfmc8.js +155 -0
- package/dist/project-source-0tg0r6vm.js +17 -0
- package/dist/publish-ztaet53r.js +233 -0
- package/dist/render.d.ts +20 -0
- package/dist/render.js +682 -0
- package/dist/repair-jkp4n3j8.js +171 -0
- package/dist/schema/manifest.types.d.ts +218 -0
- package/dist/server.d.ts +34 -0
- package/dist/source-provider-hp96b5jf.js +46 -0
- package/dist/test-helpers/testkit.d.ts +91 -0
- package/dist/theme-0yzvthe8.css +65 -0
- package/dist/theme-570zmh2t.css +58 -0
- package/dist/theme-6a2fngc8.json +6 -0
- package/dist/theme-cd6efzjw.json +6 -0
- package/dist/theme-nya4nqh6.css +70 -0
- package/dist/theme-tqfypc1w.json +6 -0
- package/dist/theme-xt0hjb1b.json +6 -0
- package/dist/theme-zz2ktzqs.css +60 -0
- package/dist/types.d.ts +31 -0
- package/dist/utils/file-utils.d.ts +53 -0
- package/dist/utils/logger.d.ts +59 -0
- package/dist/validate-k2drs19j.js +99 -0
- package/package.json +102 -0
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import type { ProjectCapabilities, ProjectSource } from "./project-source.ts";
|
|
2
|
+
/**
|
|
3
|
+
* isomorphic-git object cache scoped to ONE operation and released with it.
|
|
4
|
+
* NEVER hold one in module state: reading any object from a packfile loads
|
|
5
|
+
* the ENTIRE pack into the cache (multi-GB RSS on large repos). See the
|
|
6
|
+
* matching note in remote-auth/sync.ts.
|
|
7
|
+
*/
|
|
8
|
+
type GitCache = Record<string, unknown>;
|
|
9
|
+
/** One entry in a project's version history (a Git commit, abstracted). */
|
|
10
|
+
export interface SnapshotEntry {
|
|
11
|
+
/** Opaque revision id (a commit SHA for the local-git provider). */
|
|
12
|
+
id: string;
|
|
13
|
+
/** Author-supplied or auto-generated snapshot message. */
|
|
14
|
+
message: string;
|
|
15
|
+
/** Epoch milliseconds the snapshot was taken. */
|
|
16
|
+
timestamp: number;
|
|
17
|
+
/** Display name recorded for the snapshot author, if any. */
|
|
18
|
+
author?: string;
|
|
19
|
+
}
|
|
20
|
+
/** Inputs for initialising local version history on a folder (#25 default). */
|
|
21
|
+
export interface InitVersionHistoryOptions {
|
|
22
|
+
projectDir: string;
|
|
23
|
+
authorName?: string;
|
|
24
|
+
authorEmail?: string;
|
|
25
|
+
initialMessage?: string;
|
|
26
|
+
}
|
|
27
|
+
/** Inputs for taking a snapshot (commit) of the current working tree. */
|
|
28
|
+
export interface SnapshotOptions {
|
|
29
|
+
projectDir: string;
|
|
30
|
+
message: string;
|
|
31
|
+
authorName?: string;
|
|
32
|
+
authorEmail?: string;
|
|
33
|
+
/**
|
|
34
|
+
* Root of the Git repository the commit goes to. Defaults to `projectDir`.
|
|
35
|
+
* When the project is a subfolder of a repo, this is the enclosing repo root
|
|
36
|
+
* (the snapshot commits the whole tree — plain git, no per-folder scoping).
|
|
37
|
+
*/
|
|
38
|
+
repoRoot?: string;
|
|
39
|
+
/** Optional log file for debugging snapshot operations. */
|
|
40
|
+
logFile?: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The git repo directory a project's operations run against. A project IS its
|
|
44
|
+
* git repo: opening a subfolder of a multi-book repo just opens the repo, and
|
|
45
|
+
* every operation (snapshot, history, restore, sync) runs on the repo root over
|
|
46
|
+
* the WHOLE tree — plain git semantics, no per-book scoping. Defensive: older
|
|
47
|
+
* persisted sources without `repoRoot` fall back to the project path.
|
|
48
|
+
*/
|
|
49
|
+
export declare function gitScopeFor(source: Extract<ProjectSource, {
|
|
50
|
+
type: "local-git-folder";
|
|
51
|
+
}>): string;
|
|
52
|
+
/** Inputs for restoring the working tree to a prior snapshot. */
|
|
53
|
+
export interface RestoreSnapshotOptions {
|
|
54
|
+
projectDir: string;
|
|
55
|
+
id: string;
|
|
56
|
+
}
|
|
57
|
+
/** Paging inputs for {@link SourceProvider.listHistoryPage}. */
|
|
58
|
+
export interface ListHistoryOptions {
|
|
59
|
+
/** Max entries per page (clamped to [1, 500]; default {@link HISTORY_PAGE_LIMIT}). */
|
|
60
|
+
limit?: number;
|
|
61
|
+
/**
|
|
62
|
+
* Continuation cursor: the `id` of the LAST entry of the previous page.
|
|
63
|
+
* The returned page starts strictly after it (newest-first order).
|
|
64
|
+
*/
|
|
65
|
+
before?: string;
|
|
66
|
+
}
|
|
67
|
+
/** One page of version history (see {@link SourceProvider.listHistoryPage}). */
|
|
68
|
+
export interface HistoryPage {
|
|
69
|
+
entries: SnapshotEntry[];
|
|
70
|
+
/** True when older entries exist past this page (pass the last id as `before`). */
|
|
71
|
+
hasMore: boolean;
|
|
72
|
+
}
|
|
73
|
+
/** Default history page size. Bounds the commit walk on huge repositories. */
|
|
74
|
+
export declare const HISTORY_PAGE_LIMIT = 100;
|
|
75
|
+
/**
|
|
76
|
+
* The version-control operations a project source can perform. Implementations
|
|
77
|
+
* are selected by `ProjectSource.type` (see {@link providerFor}).
|
|
78
|
+
*/
|
|
79
|
+
export interface SourceProvider {
|
|
80
|
+
readonly source: ProjectSource;
|
|
81
|
+
readonly capabilities: ProjectCapabilities;
|
|
82
|
+
initVersionHistory(options: InitVersionHistoryOptions): Promise<ProjectSource>;
|
|
83
|
+
snapshot(options: SnapshotOptions): Promise<SnapshotEntry>;
|
|
84
|
+
/**
|
|
85
|
+
* Newest-first history, BOUNDED to the default page size. A convenience
|
|
86
|
+
* wrapper over {@link listHistoryPage} — use that for "load more" paging.
|
|
87
|
+
*/
|
|
88
|
+
listHistory(projectDir: string): Promise<SnapshotEntry[]>;
|
|
89
|
+
/** One page of newest-first history with a `before`-cursor continuation. */
|
|
90
|
+
listHistoryPage(projectDir: string, options?: ListHistoryOptions): Promise<HistoryPage>;
|
|
91
|
+
restore(options: RestoreSnapshotOptions): Promise<void>;
|
|
92
|
+
}
|
|
93
|
+
export declare const SNAPSHOT_STAGING_MARKER = "gutterpress-snapshot-staging";
|
|
94
|
+
/**
|
|
95
|
+
* Run `fn` exclusively per resolved project dir (FIFO promise chaining).
|
|
96
|
+
* Exported for the remote-clone surface (#15) so clone/fetch operations share
|
|
97
|
+
* the SAME queue as snapshot/restore — ADR 0006 D2 requires one per-repo lock.
|
|
98
|
+
*/
|
|
99
|
+
export declare function withRepoLock<T>(projectDir: string, fn: () => Promise<T>): Promise<T>;
|
|
100
|
+
/**
|
|
101
|
+
* Test-only: current number of live per-repo lock queues. Lets tests assert the
|
|
102
|
+
* B4 reclamation actually happens (the map returns to empty once every queued
|
|
103
|
+
* op settles) without exporting the map itself. Same test-hook convention as
|
|
104
|
+
* plugins.ts's `__resetPathPluginCacheForTests`.
|
|
105
|
+
*/
|
|
106
|
+
export declare function __repoLockQueueSizeForTests(): number;
|
|
107
|
+
/**
|
|
108
|
+
* Resolve the commit author identity from an optional display name (exported
|
|
109
|
+
* for the sync surface so merge commits carry the same identity as
|
|
110
|
+
* snapshots).
|
|
111
|
+
*/
|
|
112
|
+
export declare function gitAuthor(name?: string, email?: string): {
|
|
113
|
+
name: string;
|
|
114
|
+
email: string;
|
|
115
|
+
};
|
|
116
|
+
export declare function readGitAuthor(dir: string): Promise<{
|
|
117
|
+
name?: string;
|
|
118
|
+
email?: string;
|
|
119
|
+
}>;
|
|
120
|
+
/**
|
|
121
|
+
* Resolve the author for a commit in `dir`, PER FIELD: caller-supplied →
|
|
122
|
+
* existing repo config (`user.name` / `user.email`) → the gutterpress default.
|
|
123
|
+
*
|
|
124
|
+
* This is the ONE author-resolution rule for every commit gutterpress writes —
|
|
125
|
+
* snapshots, merge commits, conflict resolutions, and recovery rescue commits
|
|
126
|
+
* alike. Do NOT call `gitAuthor` directly at a commit site: it skips the repo
|
|
127
|
+
* config, so a partially configured identity (say a name in Settings, an email
|
|
128
|
+
* in `.git/config`) would produce one identity for the snapshot and a
|
|
129
|
+
* different, defaulted one for the merge commit of the SAME sync.
|
|
130
|
+
*/
|
|
131
|
+
export declare function resolveGitAuthor(dir: string, name?: string, email?: string): Promise<{
|
|
132
|
+
name: string;
|
|
133
|
+
email: string;
|
|
134
|
+
}>;
|
|
135
|
+
/** Workdir-vs-index differences, as `git add -A` staging lists. */
|
|
136
|
+
export interface WorkdirChanges {
|
|
137
|
+
/** New or modified files to `git.add`. */
|
|
138
|
+
adds: string[];
|
|
139
|
+
/** Deleted files to `git.remove`. */
|
|
140
|
+
removes: string[];
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* List workdir-vs-index differences with the library's `git.walk` over the
|
|
144
|
+
* `WORKDIR` and `STAGE` walkers — deliberately NO `TREE` (HEAD) walker, so a
|
|
145
|
+
* snapshot check never reads historical packfiles (multi-GB RSS on large
|
|
146
|
+
* repos). Whole-tree (a project is its git repo). Honours `.gitignore` for
|
|
147
|
+
* untracked paths (which also prunes `.git` itself — `isIgnored` always
|
|
148
|
+
* ignores it), exactly like `statusMatrix` does.
|
|
149
|
+
*/
|
|
150
|
+
export declare function listWorkdirChanges(dir: string, cache?: GitCache): Promise<WorkdirChanges>;
|
|
151
|
+
/**
|
|
152
|
+
* Apply a {@link WorkdirChanges} diff to the index (`git add -A` semantics).
|
|
153
|
+
* Exported so callers that already computed a `WorkdirChanges` via
|
|
154
|
+
* {@link listWorkdirChanges} (e.g. the detached-HEAD recovery handler) can
|
|
155
|
+
* stage it without re-walking the tree or falling back to `git.statusMatrix`,
|
|
156
|
+
* which loads whole packfiles into memory on large repos.
|
|
157
|
+
*/
|
|
158
|
+
export declare function stageChanges(dir: string, changes: WorkdirChanges, cache: GitCache): Promise<void>;
|
|
159
|
+
/**
|
|
160
|
+
* True when the working tree differs from the index (added/modified/deleted
|
|
161
|
+
* files). Used to skip empty snapshots. Exported (lock-free) for the sync
|
|
162
|
+
* surface (#15, ADR 0006 D5) — callers outside a lock should prefer the
|
|
163
|
+
* provider operations.
|
|
164
|
+
*/
|
|
165
|
+
export declare function hasPendingChanges(dir: string, cache?: GitCache): Promise<boolean>;
|
|
166
|
+
/**
|
|
167
|
+
* True when the working tree has ANY uncommitted change relative to HEAD —
|
|
168
|
+
* both WORKDIR-vs-STAGE (unstaged edits) AND STAGE-vs-HEAD (staged-but-
|
|
169
|
+
* uncommitted). This matches `git status --porcelain`'s notion of "dirty".
|
|
170
|
+
*
|
|
171
|
+
* Distinct from {@link hasPendingChanges} (WORKDIR-vs-STAGE only, the hot
|
|
172
|
+
* sync-check path per the sync-simplicity mandate): this is for build
|
|
173
|
+
* *provenance* — the build fingerprint records whether the tree was clean at
|
|
174
|
+
* build time, where a `git add`-ed-but-not-committed change must still count
|
|
175
|
+
* as dirty (the old `git status --porcelain` fingerprint reported it; the
|
|
176
|
+
* WORKDIR-vs-STAGE-only check silently dropped it).
|
|
177
|
+
*/
|
|
178
|
+
export declare function hasUncommittedChanges(dir: string, cache?: GitCache): Promise<boolean>;
|
|
179
|
+
/**
|
|
180
|
+
* Lock-free snapshot of the full working tree (stage everything + commit).
|
|
181
|
+
*
|
|
182
|
+
* Exported for the sync surface (#15, ADR 0006 D5): `syncProject` holds
|
|
183
|
+
* the per-repo lock for snapshot → fetch → merge → push as ONE sequence, so it
|
|
184
|
+
* needs the lock-free internal rather than `provider.snapshot()` (taking the
|
|
185
|
+
* per-method lock inside the sync lock would deadlock the FIFO queue).
|
|
186
|
+
* Callers outside a lock should use `providerFor(source).snapshot()`.
|
|
187
|
+
*/
|
|
188
|
+
export declare function snapshotWorkingTreeUnlocked(options: SnapshotOptions): Promise<SnapshotEntry>;
|
|
189
|
+
/**
|
|
190
|
+
* True for the friendly "nothing new to save" rejection from `snapshot()`.
|
|
191
|
+
* Exported (RC1-3) so the auto-snapshot scheduler in the desktop host can
|
|
192
|
+
* swallow the expected clean-tree rejection without string-matching itself.
|
|
193
|
+
*/
|
|
194
|
+
export declare function isNoChangesError(e: unknown): boolean;
|
|
195
|
+
/**
|
|
196
|
+
* Select the {@link SourceProvider} implementation for a classified source.
|
|
197
|
+
* `managed-github` (#15/#16) is not implemented yet — it throws if reached.
|
|
198
|
+
*/
|
|
199
|
+
export declare function providerFor(source: ProjectSource): SourceProvider;
|
|
200
|
+
/** Resolve the `.git` directory path for a project (used by callers/tests). */
|
|
201
|
+
export declare function gitDirFor(projectDir: string): string;
|
|
202
|
+
/** Marker written before staging and removed after commit; presence means a prior snapshot may have died after staging. */
|
|
203
|
+
export declare function snapshotStagingMarkerPath(projectDir: string): string;
|
|
204
|
+
/** Inputs for {@link restoreVersionWithBackup}. */
|
|
205
|
+
export interface RestoreVersionOptions {
|
|
206
|
+
projectDir: string;
|
|
207
|
+
/** Snapshot id (commit SHA) to restore the working tree to. */
|
|
208
|
+
id: string;
|
|
209
|
+
/** Identity recorded on the automatic pre-restore safety snapshot. */
|
|
210
|
+
authorName?: string;
|
|
211
|
+
authorEmail?: string;
|
|
212
|
+
}
|
|
213
|
+
/** Result of {@link restoreVersionWithBackup}. */
|
|
214
|
+
export interface RestoreVersionResult {
|
|
215
|
+
/** The snapshot id the working tree was restored to. */
|
|
216
|
+
restoredId: string;
|
|
217
|
+
/**
|
|
218
|
+
* Id of the automatic safety snapshot taken of the pre-restore state, or
|
|
219
|
+
* `undefined` when the working tree was already clean (its state is already
|
|
220
|
+
* the latest snapshot, so no backup was needed).
|
|
221
|
+
*/
|
|
222
|
+
backupId?: string;
|
|
223
|
+
}
|
|
224
|
+
/** Message recorded on the automatic pre-restore safety snapshot. */
|
|
225
|
+
export declare const RESTORE_BACKUP_MESSAGE = "Automatic backup before restoring an earlier version";
|
|
226
|
+
/**
|
|
227
|
+
* Message recorded on every host-scheduled automatic snapshot. The desktop's
|
|
228
|
+
* history UI groups consecutive entries carrying EXACTLY this message, so the
|
|
229
|
+
* string is a contract — change it only with a matching UI update.
|
|
230
|
+
*/
|
|
231
|
+
export declare const AUTO_SNAPSHOT_MESSAGE = "Automatic snapshot";
|
|
232
|
+
/**
|
|
233
|
+
* Restore the working tree to a prior snapshot SAFELY (#13): if the current
|
|
234
|
+
* state has unsaved-to-history changes, an automatic safety snapshot is
|
|
235
|
+
* committed FIRST, so a restore can never lose work — the pre-restore state
|
|
236
|
+
* stays reachable through the same View History UI. This is the operation the
|
|
237
|
+
* desktop's "Restore Version" action calls; the raw `provider.restore()` is the
|
|
238
|
+
* low-level primitive.
|
|
239
|
+
*
|
|
240
|
+
* Pure isomorphic-git via the provider layer (CLAUDE.md §7). Throws when the
|
|
241
|
+
* folder has no version history.
|
|
242
|
+
*/
|
|
243
|
+
export declare function restoreVersionWithBackup(options: RestoreVersionOptions): Promise<RestoreVersionResult>;
|
|
244
|
+
export {};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import http from "node:http";
|
|
2
|
+
/**
|
|
3
|
+
* Extension -> Content-Type map shared by every localhost static file server
|
|
4
|
+
* in this package: the build-time pagination server and PDF-render server
|
|
5
|
+
* (build-runner.ts) and the live preview server (preview/http-server.ts).
|
|
6
|
+
*
|
|
7
|
+
* Previously two independent 17-entry tables that had to be edited in lockstep
|
|
8
|
+
* (finding #17) — a new asset type added to only one would render differently
|
|
9
|
+
* in preview vs build-time pagination with no error, a silent divergence
|
|
10
|
+
* class. One table now; add a new extension once.
|
|
11
|
+
*
|
|
12
|
+
* That same divergence class recurred once more (2026-07-28 duplication
|
|
13
|
+
* audit): this table and `asset-inline.ts`'s `MIME_BY_EXT` — a separate table
|
|
14
|
+
* answering a separate question, "what Content-Type does a data: URI need
|
|
15
|
+
* when embedding this file inline," vs. this table's "what Content-Type does
|
|
16
|
+
* an HTTP response need" — had drifted again, missing `.webp`/`.avif` here.
|
|
17
|
+
* A large (>512KB, over the inliner's threshold) WebP/AVIF image was copied
|
|
18
|
+
* as a real file and then served as `application/octet-stream` by both
|
|
19
|
+
* servers above. Added below; if a third image format shows up, add it to
|
|
20
|
+
* BOTH tables in the same commit (asset-inline.ts is out of scope for this
|
|
21
|
+
* PR — see docs/reviews/duplication-audit-2026-07-28.md).
|
|
22
|
+
*/
|
|
23
|
+
export declare const STATIC_MIME: Record<string, string>;
|
|
24
|
+
/**
|
|
25
|
+
* Confine an already-decoded relative path to `root`, guarding against path
|
|
26
|
+
* traversal (`..` segments, absolute-looking paths escaping via `..`).
|
|
27
|
+
* Returns `null` if the resolved path escapes `root`.
|
|
28
|
+
*
|
|
29
|
+
* Shared by {@link resolveStaticPath} (which decodes a URL pathname first)
|
|
30
|
+
* AND by callers that already hold a decoded string with no pathname
|
|
31
|
+
* semantics to strip. Query-string values are NOT dot-segment-normalized by
|
|
32
|
+
* the WHATWG URL parser the way `url.pathname` is, so any route reading a raw
|
|
33
|
+
* query value as a filesystem-relative path must run it through this guard.
|
|
34
|
+
*/
|
|
35
|
+
export declare function resolveWithinRoot(relPath: string, root: string): string | null;
|
|
36
|
+
/**
|
|
37
|
+
* Resolve a request URL pathname to an absolute path inside `root`, guarding
|
|
38
|
+
* against path traversal (`..`, encoded separators, absolute-looking paths).
|
|
39
|
+
* Returns `null` if the pathname cannot be decoded or the resolved path
|
|
40
|
+
* escapes `root` — callers turn that into a 403/404 as fits their route.
|
|
41
|
+
*/
|
|
42
|
+
export declare function resolveStaticPath(urlPathname: string, root: string): string | null;
|
|
43
|
+
/**
|
|
44
|
+
* Minimal static file responder: read `filePath` and write it to `res` with
|
|
45
|
+
* the `STATIC_MIME` content-type (falling back to `application/octet-stream`);
|
|
46
|
+
* 404 on any read failure (missing file, directory, permission error).
|
|
47
|
+
*
|
|
48
|
+
* Deliberately minimal — no directory-index fallback, no HTML
|
|
49
|
+
* post-processing, no cache-control shaping. Callers that need those (the
|
|
50
|
+
* preview server's HMR-snippet injection + directory `index.html` fallback)
|
|
51
|
+
* build on top of `resolveStaticPath` + `STATIC_MIME` directly instead of
|
|
52
|
+
* this helper.
|
|
53
|
+
*/
|
|
54
|
+
export declare function serveFile(filePath: string, res: http.ServerResponse): Promise<void>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/** One resolvable project stylesheet for the CSS editor's picker. */
|
|
2
|
+
export interface ProjectStyle {
|
|
3
|
+
/** Absolute path to the `.css` file. */
|
|
4
|
+
path: string;
|
|
5
|
+
/** Project-relative, "/"-separated display name (e.g. `themes/dark/theme.css`). */
|
|
6
|
+
displayName: string;
|
|
7
|
+
/** True when this stylesheet is in the manifest `styles:` list (the active set). */
|
|
8
|
+
active: boolean;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* THE canonical "which stylesheet does this project use?" resolver — consumed by
|
|
12
|
+
* BOTH the renderer (to `<link>` them) and the editor (to edit them), so they
|
|
13
|
+
* can never disagree. Returns project-relative paths:
|
|
14
|
+
* 1. the manifest `styles:` list, if it has any entries; else
|
|
15
|
+
* 2. the first conventional stylesheet the project actually has
|
|
16
|
+
* (`FALLBACK_PRIORITY`); else
|
|
17
|
+
* 3. the first discovered `.css` anywhere we scan (deterministic); else
|
|
18
|
+
* 4. `[]` — the project has no stylesheet (an honest empty, never a phantom
|
|
19
|
+
* link to a missing file).
|
|
20
|
+
* `manifestStyles` is the manifest's `styles:` value (the caller already has it
|
|
21
|
+
* resolved); pass `undefined` to have it read from the manifest.
|
|
22
|
+
*/
|
|
23
|
+
export declare function resolveActiveStyles(projectDir: string, manifestStyles?: string[]): Promise<string[]>;
|
|
24
|
+
/**
|
|
25
|
+
* Resolve a project's editable stylesheets for the picker: the ACTIVE set
|
|
26
|
+
* (`resolveActiveStyles`, marked `active: true`) followed by the project's OTHER
|
|
27
|
+
* discovered `.css` files (alphabetical). `projectDir` must be absolute. Returns
|
|
28
|
+
* `[]` for a project with no stylesheets at all.
|
|
29
|
+
*/
|
|
30
|
+
export declare function listProjectStyles(projectDir: string): Promise<ProjectStyle[]>;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { type PrintSafeWarning } from "./printsafe.ts";
|
|
2
|
+
import { type ThemeInfo } from "./theme-manager.ts";
|
|
3
|
+
/** Reject a raw archive larger than this before unzipping (zip-bomb surface). */
|
|
4
|
+
export declare const MAX_THEME_ARCHIVE_BYTES: number;
|
|
5
|
+
/** Reject an archive whose entries expand past this in total (zip-bomb surface). */
|
|
6
|
+
export declare const MAX_THEME_UNZIPPED_BYTES: number;
|
|
7
|
+
/** A non-fatal issue surfaced to the author after a successful import. */
|
|
8
|
+
export interface ThemeImportWarning {
|
|
9
|
+
code: "print-safety" | "no-theme-json" | "unnamed-theme" | "extra-files";
|
|
10
|
+
message: string;
|
|
11
|
+
}
|
|
12
|
+
/** Outcome of a `.zip` / `.css` import: the imported theme + any warnings. */
|
|
13
|
+
export interface ThemeImportResult {
|
|
14
|
+
theme: ThemeInfo;
|
|
15
|
+
warnings: ThemeImportWarning[];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Is this zip entry name unsafe to extract? Rejects absolute paths (posix or
|
|
19
|
+
* Windows drive), and any `..` segment (zip-slip / path traversal). Callers
|
|
20
|
+
* ALSO do a resolved-containment check as defense-in-depth.
|
|
21
|
+
*/
|
|
22
|
+
export declare function isUnsafeZipEntryPath(name: string): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Locate the theme root inside a zip's entry names: the directory that directly
|
|
25
|
+
* contains `theme.css`, allowed at the archive root (`""`) or exactly one level
|
|
26
|
+
* down. Returns the root prefix (`""` for root, or the single sub-directory
|
|
27
|
+
* name), or `null` when there is no unambiguous theme root (none, or more than
|
|
28
|
+
* one candidate folder each holding a `theme.css`).
|
|
29
|
+
*/
|
|
30
|
+
export declare function locateThemeRoot(names: string[]): string | null;
|
|
31
|
+
/**
|
|
32
|
+
* Split print-safety findings into the one that REJECTS the import (a CSS
|
|
33
|
+
* syntax/parse failure — the stylesheet is unusable) vs. WARN findings the
|
|
34
|
+
* author should still see (remote URLs, risky print effects, paged.js crash
|
|
35
|
+
* selectors) that import anyway. The discriminator is the rule id, not
|
|
36
|
+
* severity: `no-remote-urls`/`no-pagedjs-crash-selectors` are `error`-severity
|
|
37
|
+
* but the #106 spec still imports them with a warning; only `syntax-error`
|
|
38
|
+
* refuses.
|
|
39
|
+
*/
|
|
40
|
+
export declare function classifyThemeCssFindings(findings: PrintSafeWarning[]): {
|
|
41
|
+
reject: PrintSafeWarning | null;
|
|
42
|
+
warnings: PrintSafeWarning[];
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* From a theme folder's relative file paths, return the ones that are neither
|
|
46
|
+
* `theme.css`/`theme.json` nor a recognized bundled asset (font/image/css).
|
|
47
|
+
* These trigger a non-fatal "unexpected extra files" warning — the import
|
|
48
|
+
* still copies the whole folder.
|
|
49
|
+
*/
|
|
50
|
+
export declare function unexpectedThemeFiles(relPaths: string[]): string[];
|
|
51
|
+
/**
|
|
52
|
+
* Import a theme from a `.zip` package. Unzips in memory (fflate), rejects
|
|
53
|
+
* unsafe paths and over-cap archives, locates the theme root (at the archive
|
|
54
|
+
* root or one folder down), extracts just that subtree to a temp folder, and
|
|
55
|
+
* finalizes via {@link finalizeThemeImport}. Lands the theme in
|
|
56
|
+
* `themes/<uniqueId>/` (never overwrites an existing theme).
|
|
57
|
+
*/
|
|
58
|
+
export declare function importThemeFromZip(projectDir: string, archive: Uint8Array): Promise<ThemeImportResult>;
|
|
59
|
+
/**
|
|
60
|
+
* Import a theme from a bare `.css` file by wrapping it into a one-file theme
|
|
61
|
+
* folder (`theme.css` + a synthesized `theme.json` naming it). REJECTS a CSS
|
|
62
|
+
* that fails to parse.
|
|
63
|
+
*/
|
|
64
|
+
export declare function importThemeFromCssText(projectDir: string, css: string, name: string): Promise<ThemeImportResult>;
|
|
65
|
+
/**
|
|
66
|
+
* Import a theme from a local file path, dispatched by extension: `.zip` →
|
|
67
|
+
* {@link importThemeFromZip}, `.css` → {@link importThemeFromCssText}. The
|
|
68
|
+
* desktop's host reads the path from a native file picker and calls this.
|
|
69
|
+
*/
|
|
70
|
+
export declare function importThemeFromFile(projectDir: string, filePath: string): Promise<ThemeImportResult>;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/** Folder (relative to the project root) themes are copied into on apply/import. */
|
|
2
|
+
export declare const THEMES_DIR = "themes";
|
|
3
|
+
/** The built-in themes shipped as embedded assets (ids are folder names). */
|
|
4
|
+
export declare const BUILT_IN_THEME_IDS: readonly ["clean-book", "ttrpg-supplement", "zine", "technical-doc"];
|
|
5
|
+
export type BuiltInThemeId = (typeof BUILT_IN_THEME_IDS)[number];
|
|
6
|
+
/** Parsed `theme.json` metadata (every field optional in the file). */
|
|
7
|
+
export interface ThemeMetadata {
|
|
8
|
+
name?: string;
|
|
9
|
+
author?: string;
|
|
10
|
+
description?: string;
|
|
11
|
+
/** Optional preview image path (relative to the theme folder). */
|
|
12
|
+
preview?: string | null;
|
|
13
|
+
}
|
|
14
|
+
/** Author-friendly metadata for one theme (built-in or project). */
|
|
15
|
+
export interface ThemeInfo {
|
|
16
|
+
/** Stable id (a built-in id, or a slug for imported/applied themes). */
|
|
17
|
+
id: string;
|
|
18
|
+
/** Display name. */
|
|
19
|
+
name: string;
|
|
20
|
+
/** Theme author, when known. */
|
|
21
|
+
author?: string;
|
|
22
|
+
/** One-line description. */
|
|
23
|
+
description: string;
|
|
24
|
+
/** `"builtin"` (embedded) or `"project"` (copied into the project). */
|
|
25
|
+
kind: "builtin" | "project";
|
|
26
|
+
/** Optional preview image path relative to the theme folder. */
|
|
27
|
+
preview?: string | null;
|
|
28
|
+
}
|
|
29
|
+
/** A built-in theme resolved to disk (extracted from the embedded assets). */
|
|
30
|
+
export interface ResolvedTheme {
|
|
31
|
+
info: ThemeInfo;
|
|
32
|
+
/** Absolute path to the theme's `theme.css` (in the extracted assets dir). */
|
|
33
|
+
cssPath: string;
|
|
34
|
+
/** Absolute path to the theme's folder. */
|
|
35
|
+
dir: string;
|
|
36
|
+
}
|
|
37
|
+
/** Which theme to apply: a built-in id, or a project theme already on disk. */
|
|
38
|
+
export type ApplyThemeTarget = {
|
|
39
|
+
kind: "builtin";
|
|
40
|
+
id: BuiltInThemeId | string;
|
|
41
|
+
} | {
|
|
42
|
+
kind: "project";
|
|
43
|
+
id: string;
|
|
44
|
+
};
|
|
45
|
+
/** List the built-in themes (metadata read from the extracted embedded assets). */
|
|
46
|
+
export declare function listBuiltInThemes(): Promise<ThemeInfo[]>;
|
|
47
|
+
/** Resolve a built-in theme to its extracted `theme.css` + parsed metadata. */
|
|
48
|
+
export declare function resolveBuiltInTheme(id: string): Promise<ResolvedTheme>;
|
|
49
|
+
/**
|
|
50
|
+
* List the themes that live inside the project under `themes/<id>/` (each a
|
|
51
|
+
* folder with a `theme.css`). Returns `[]` when there is no `themes/` folder.
|
|
52
|
+
*/
|
|
53
|
+
export declare function listProjectThemes(projectDir: string): Promise<ThemeInfo[]>;
|
|
54
|
+
/**
|
|
55
|
+
* Read the project's currently active theme (the theme whose `theme.css` is in
|
|
56
|
+
* the manifest `styles:` list AND whose folder exists under `themes/`). Returns
|
|
57
|
+
* `null` when no theme is applied.
|
|
58
|
+
*/
|
|
59
|
+
export declare function getActiveTheme(projectDir: string): Promise<ThemeInfo | null>;
|
|
60
|
+
/**
|
|
61
|
+
* Read the project's "previous theme" — the theme active immediately before the
|
|
62
|
+
* current one (#106). Returns `null` when there is no recorded previous theme,
|
|
63
|
+
* when its folder no longer exists, or when it is (somehow) already the active
|
|
64
|
+
* theme. The reference is persisted indefinitely (no timer) in the manifest.
|
|
65
|
+
*/
|
|
66
|
+
export declare function getPreviousTheme(projectDir: string): Promise<ThemeInfo | null>;
|
|
67
|
+
/**
|
|
68
|
+
* Revert to the previously active theme (#106): re-apply the theme recorded by
|
|
69
|
+
* {@link getPreviousTheme}. Because {@link applyTheme} itself records the
|
|
70
|
+
* now-current theme as the new "previous", reverting is a toggle — revert again
|
|
71
|
+
* returns to where you were. Throws when there is no previous theme to revert to.
|
|
72
|
+
*/
|
|
73
|
+
export declare function revertTheme(projectDir: string): Promise<ThemeInfo>;
|
|
74
|
+
/**
|
|
75
|
+
* Apply a theme to the project: COPY the theme folder into `themes/<id>/`
|
|
76
|
+
* (built-in themes are copied out of the embedded assets; project themes are
|
|
77
|
+
* already present) and wire the manifest so its `theme.css` is the active
|
|
78
|
+
* stylesheet. Returns the applied {@link ThemeInfo}.
|
|
79
|
+
*
|
|
80
|
+
* No-data-loss mandate (UX review M6): a project theme's `theme.css` is the
|
|
81
|
+
* exact file the Design panel writes token edits into, so re-copying a
|
|
82
|
+
* built-in over an EXISTING `themes/<id>/` would silently discard every
|
|
83
|
+
* customization the author made after the first apply. Applying a built-in
|
|
84
|
+
* therefore never overwrites an existing project theme folder — if one is
|
|
85
|
+
* already there (customized or not), the built-in is copied into a fresh id
|
|
86
|
+
* (via the same {@link uniqueThemeId} helper import/folder-import uses) and
|
|
87
|
+
* THAT becomes active, leaving the original folder untouched. In the normal UI flow the
|
|
88
|
+
* Appearance grid hides a built-in card once its project copy exists (so this
|
|
89
|
+
* path isn't reachable by clicking Apply twice); this guard is the
|
|
90
|
+
* defense-in-depth backstop for any other caller of this function.
|
|
91
|
+
*/
|
|
92
|
+
export declare function applyTheme(projectDir: string, target: ApplyThemeTarget): Promise<ThemeInfo>;
|
|
93
|
+
/**
|
|
94
|
+
* Import a theme from a local folder by copying it into the project's
|
|
95
|
+
* `themes/<id>/`. The folder MUST contain a `theme.css`. Metadata comes from
|
|
96
|
+
* its `theme.json` (synthesised from the folder name when absent). The imported
|
|
97
|
+
* theme becomes available to {@link applyTheme}; importing does NOT auto-apply.
|
|
98
|
+
*/
|
|
99
|
+
export declare function importThemeFromFolder(projectDir: string, sourceDir: string): Promise<ThemeInfo>;
|
|
100
|
+
/**
|
|
101
|
+
* Import a theme from a URL using the global `fetch` (bundle-safe — no node http
|
|
102
|
+
* client). Two shapes are supported:
|
|
103
|
+
*
|
|
104
|
+
* - RAW CSS: a `…/theme.css` (or any `.css`) URL → fetched as the theme's
|
|
105
|
+
* `theme.css`; metadata is synthesised from the URL.
|
|
106
|
+
* - THEME FOLDER: a base URL (no `.css`) → we fetch `<base>/theme.json`
|
|
107
|
+
* (optional) and `<base>/theme.css` (required) to assemble the theme.
|
|
108
|
+
*
|
|
109
|
+
* The fetched theme is written into the project's `themes/<id>/`. Bundled fonts
|
|
110
|
+
* are NOT followed for URL imports (a single CSS file + optional metadata) to
|
|
111
|
+
* keep the fetch surface small and predictable; authors wanting bundled assets
|
|
112
|
+
* use folder import.
|
|
113
|
+
*/
|
|
114
|
+
export declare function importThemeFromUrl(projectDir: string, url: string): Promise<ThemeInfo>;
|
|
115
|
+
/**
|
|
116
|
+
* Read a theme's CSS for previewing. Built-in themes read from the embedded
|
|
117
|
+
* assets; project themes read from `themes/<id>/theme.css`. Used by the host to
|
|
118
|
+
* feed the renderer a sample-render thumbnail (the renderer never touches fs).
|
|
119
|
+
*/
|
|
120
|
+
export declare function readThemeCss(projectDir: string | null, source: {
|
|
121
|
+
kind: "builtin" | "project";
|
|
122
|
+
id: string;
|
|
123
|
+
}): Promise<string>;
|
|
124
|
+
/**
|
|
125
|
+
* Remove an imported/applied project theme folder. If it was the active theme,
|
|
126
|
+
* its `styles:` entry is dropped too. Never touches built-in (embedded) themes.
|
|
127
|
+
*/
|
|
128
|
+
export declare function removeProjectTheme(projectDir: string, id: string): Promise<void>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-platform tool detection helper.
|
|
3
|
+
*
|
|
4
|
+
* Wraps the platform's "where is this binary?" command:
|
|
5
|
+
* - Windows: where.exe
|
|
6
|
+
* - POSIX: which
|
|
7
|
+
*
|
|
8
|
+
* Used in two places in the lib:
|
|
9
|
+
* - packages/cli/src/checks/tool-check.ts — the validation gate, decides
|
|
10
|
+
* which checks to skip when their backing CLI tool isn't installed.
|
|
11
|
+
* - packages/cli/src/lib/chromium.ts — PATH-fallback for Chromium when the
|
|
12
|
+
* fixed-path scan misses non-default installs (Scoop, Chocolatey, Brave,
|
|
13
|
+
* Vivaldi, Arc, portable installs).
|
|
14
|
+
* - packages/cli/src/lib/ghostscript.ts — PATH tier of the shared
|
|
15
|
+
* cross-platform Ghostscript resolver.
|
|
16
|
+
* - packages/cli/src/lib/build-runner.ts — pre-flight check at the top of
|
|
17
|
+
* runBuild so a missing tool becomes an actionable error in 50ms instead
|
|
18
|
+
* of a confusing ENOENT 90 seconds into the pipeline.
|
|
19
|
+
*
|
|
20
|
+
* One implementation; one place to fix bugs. Spawning goes through
|
|
21
|
+
* exec.ts's `execCapture`, which also owns the shared, correctly
|
|
22
|
+
* delimiter-joined `enhancedPath` (this file used to keep its own copy of
|
|
23
|
+
* that PATH construction, and exec.ts's copy hardcoded `:` — see
|
|
24
|
+
* docs/reviews 2026-07-10-architecture-critical-review.md, finding #3).
|
|
25
|
+
*/
|
|
26
|
+
/**
|
|
27
|
+
* Returns true if `tool` is resolvable via the platform's path-probe command.
|
|
28
|
+
*/
|
|
29
|
+
export declare function isToolAvailable(tool: string): Promise<boolean>;
|
|
30
|
+
/**
|
|
31
|
+
* Returns the absolute path of `tool` if it's resolvable on PATH, or undefined.
|
|
32
|
+
*
|
|
33
|
+
* On Windows, where.exe prints one match per line (the first is the highest-
|
|
34
|
+
* priority match in PATH). On POSIX, which prints exactly one line. We always
|
|
35
|
+
* return the first line.
|
|
36
|
+
*/
|
|
37
|
+
export declare function findTool(tool: string): Promise<string | undefined>;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { type OutputFormat } from "../checks/formatter";
|
|
2
|
+
import { type RunnerOptions, type RunnerReport } from "../checks/runner";
|
|
3
|
+
import { type ToolCheckResult } from "../checks/tool-check";
|
|
4
|
+
import type { CheckContext, CheckResult } from "../checks/types";
|
|
5
|
+
import { type ValidationProfile } from "./validation-profile";
|
|
6
|
+
import type { ResolvedConfig } from "../schema/manifest.types";
|
|
7
|
+
import "../checks/register-builtins";
|
|
8
|
+
export interface ValidationExecutionArgs {
|
|
9
|
+
manifest?: string;
|
|
10
|
+
pdf?: string;
|
|
11
|
+
input?: string;
|
|
12
|
+
category?: string;
|
|
13
|
+
only?: string;
|
|
14
|
+
skip?: string;
|
|
15
|
+
phase?: string;
|
|
16
|
+
profile?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface ValidationExecutionResult {
|
|
19
|
+
config: ResolvedConfig;
|
|
20
|
+
profile?: ValidationProfile;
|
|
21
|
+
context: CheckContext;
|
|
22
|
+
runnerOptions: RunnerOptions;
|
|
23
|
+
tools: ToolCheckResult;
|
|
24
|
+
report: RunnerReport;
|
|
25
|
+
}
|
|
26
|
+
export declare function executeValidation(args: ValidationExecutionArgs): Promise<ValidationExecutionResult>;
|
|
27
|
+
export interface ReportAndCheckResult {
|
|
28
|
+
ok: boolean;
|
|
29
|
+
execution: ValidationExecutionResult;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Run validation and emit the standard text/json report. Returns ok=false when
|
|
33
|
+
* the report contains errors so callers can decide how to surface failure
|
|
34
|
+
* (process.exit for the CLI; throw for the build runner).
|
|
35
|
+
*/
|
|
36
|
+
export declare function executeAndReport(args: ValidationExecutionArgs, format?: OutputFormat): Promise<ReportAndCheckResult>;
|
|
37
|
+
/**
|
|
38
|
+
* Derive the extra PDF summary lines (Max TAC / Fonts / Rasterized pages) shown
|
|
39
|
+
* after the standard report in text mode.
|
|
40
|
+
*
|
|
41
|
+
* These read the structured `code` / `data` fields on each CheckResult — NOT the
|
|
42
|
+
* human-readable `message` — so rewording a check message can never silently
|
|
43
|
+
* break the CLI summary. A line is emitted only when the corresponding check
|
|
44
|
+
* actually produced a result; a check skipped by missing tools / filters yields
|
|
45
|
+
* no result and therefore no (misleading) summary line.
|
|
46
|
+
*/
|
|
47
|
+
export declare function buildPdfSummaryLines(results: CheckResult[]): string[];
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ResolvedConfig } from "../schema/manifest.types";
|
|
2
|
+
export type ValidationProfile = "dtrpg";
|
|
3
|
+
export declare const DTRPG_STRICT_PDF_CHECKS: readonly ["pdf.structure.qpdf", "pdf.print.pdfx-markers", "pdf.print.pdfx-metadata", "pdf.print.embedded-fonts"];
|
|
4
|
+
/**
|
|
5
|
+
* Fill in the strict PDF checks (structure/PDF-X markers/metadata/embedded
|
|
6
|
+
* fonts) for any of them the config left unset, without overwriting an
|
|
7
|
+
* author's explicit choice. ARCH finding #21: replaces the old
|
|
8
|
+
* `applyDtrpgPdfDefaults` name, which implied a dtrpg-only opt-in even though
|
|
9
|
+
* `executeValidation` applies it to every PDF validation regardless of
|
|
10
|
+
* profile/preset — see validation-exec.ts.
|
|
11
|
+
*/
|
|
12
|
+
export declare function applyDefaultPdfStrictChecks(config: ResolvedConfig): ResolvedConfig;
|
|
13
|
+
/**
|
|
14
|
+
* @deprecated Use {@link applyDefaultPdfStrictChecks} — kept as an alias so
|
|
15
|
+
* existing call sites keep resolving under the old, dtrpg-branded name.
|
|
16
|
+
*/
|
|
17
|
+
export declare const applyDtrpgPdfDefaults: typeof applyDefaultPdfStrictChecks;
|
|
18
|
+
export declare function applyValidationProfile(config: ResolvedConfig, profile: ValidationProfile): ResolvedConfig;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
type PackageMeta = {
|
|
2
|
+
version: string;
|
|
3
|
+
dependencies: Record<string, string>;
|
|
4
|
+
devDependencies: Record<string, string>;
|
|
5
|
+
};
|
|
6
|
+
export declare const PACKAGE_META: PackageMeta;
|
|
7
|
+
/** The gutterpress lib version, e.g. `"0.7.1"`. */
|
|
8
|
+
export declare const PACKAGE_VERSION: string;
|
|
9
|
+
export {};
|