@phnx-labs/agents-cli 1.22.114 → 1.22.115

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 (176) hide show
  1. package/CHANGELOG.md +110 -0
  2. package/README.md +22 -102
  3. package/dist/browser.js +0 -0
  4. package/dist/cli/command-registry.js +0 -7
  5. package/dist/commands/accounts.d.ts +3 -77
  6. package/dist/commands/accounts.js +13 -366
  7. package/dist/commands/audit.js +1 -1
  8. package/dist/commands/auth.js +0 -2
  9. package/dist/commands/browser.d.ts +53 -0
  10. package/dist/commands/browser.js +199 -9
  11. package/dist/commands/doctor.d.ts +2 -3
  12. package/dist/commands/doctor.js +0 -11
  13. package/dist/commands/events.d.ts +1 -3
  14. package/dist/commands/events.js +4 -7
  15. package/dist/commands/exec.d.ts +0 -1
  16. package/dist/commands/exec.js +2 -7
  17. package/dist/commands/feed-watch.js +52 -8
  18. package/dist/commands/focus.js +1 -1
  19. package/dist/commands/go.d.ts +0 -17
  20. package/dist/commands/go.js +2 -19
  21. package/dist/commands/logs.js +1 -1
  22. package/dist/commands/mcp.js +8 -83
  23. package/dist/commands/memory.js +4 -47
  24. package/dist/commands/message.js +4 -4
  25. package/dist/commands/plugins.js +1 -93
  26. package/dist/commands/repo.js +0 -44
  27. package/dist/commands/resume.js +4 -1
  28. package/dist/commands/secrets-passthrough.js +2 -2
  29. package/dist/commands/send.d.ts +4 -4
  30. package/dist/commands/send.js +6 -51
  31. package/dist/commands/sessions-backup-setup.js +1 -1
  32. package/dist/commands/sessions-resume.js +0 -1
  33. package/dist/commands/sessions-share.d.ts +5 -7
  34. package/dist/commands/sessions-share.js +98 -49
  35. package/dist/commands/sessions.js +1 -8
  36. package/dist/commands/setup-browser.js +18 -2
  37. package/dist/commands/setup-computer.js +20 -6
  38. package/dist/commands/setup-secrets.js +24 -4
  39. package/dist/commands/setup-terminal.d.ts +3 -0
  40. package/dist/commands/setup-terminal.js +22 -0
  41. package/dist/commands/setup.d.ts +1 -1
  42. package/dist/commands/setup.js +20 -10
  43. package/dist/commands/skills.js +0 -8
  44. package/dist/commands/ssh.d.ts +6 -0
  45. package/dist/commands/ssh.js +92 -233
  46. package/dist/commands/sync.js +14 -5
  47. package/dist/commands/teams.js +1 -1
  48. package/dist/commands/traces.js +1 -1
  49. package/dist/lib/accounts/add.d.ts +0 -5
  50. package/dist/lib/accounts/add.js +1 -7
  51. package/dist/lib/artifacts-client.d.ts +20 -0
  52. package/dist/lib/artifacts-client.js +46 -0
  53. package/dist/lib/auth-mint.js +2 -2
  54. package/dist/lib/browser/runtime-state.d.ts +55 -0
  55. package/dist/lib/browser/runtime-state.js +99 -18
  56. package/dist/lib/browser/service.js +21 -1
  57. package/dist/lib/cli-resources.js +3 -1
  58. package/dist/lib/cloud/dispatch.js +1 -1
  59. package/dist/lib/cloudflare/creds.d.ts +10 -0
  60. package/dist/lib/cloudflare/creds.js +46 -0
  61. package/dist/lib/cloudflare/provision.d.ts +35 -0
  62. package/dist/lib/cloudflare/provision.js +144 -0
  63. package/dist/lib/computer/sessions-list.d.ts +55 -0
  64. package/dist/lib/computer/sessions-list.js +168 -1
  65. package/dist/lib/daemon/daemon.js +8 -1
  66. package/dist/lib/daemon/feed-stream-service.d.ts +23 -0
  67. package/dist/lib/daemon/feed-stream-service.js +40 -0
  68. package/dist/lib/daemon-services.d.ts +1 -1
  69. package/dist/lib/daemon-services.js +5 -0
  70. package/dist/lib/devices/connect.d.ts +49 -5
  71. package/dist/lib/devices/connect.js +169 -21
  72. package/dist/lib/feed/envelope.d.ts +79 -0
  73. package/dist/lib/feed/envelope.js +23 -0
  74. package/dist/lib/feed/events.d.ts +6 -0
  75. package/dist/lib/feed/events.js +8 -0
  76. package/dist/lib/feed/hub-server.d.ts +86 -0
  77. package/dist/lib/feed/hub-server.js +334 -0
  78. package/dist/lib/feed/hub.d.ts +95 -0
  79. package/dist/lib/feed/hub.js +255 -0
  80. package/dist/lib/feed/tool-activity.d.ts +108 -0
  81. package/dist/lib/feed/tool-activity.js +313 -0
  82. package/dist/lib/feed/tools.d.ts +198 -0
  83. package/dist/lib/feed/tools.js +265 -0
  84. package/dist/lib/feed/watch.d.ts +50 -50
  85. package/dist/lib/feed/watch.js +147 -16
  86. package/dist/lib/format.d.ts +1 -1
  87. package/dist/lib/format.js +1 -1
  88. package/dist/lib/git.d.ts +0 -16
  89. package/dist/lib/git.js +0 -58
  90. package/dist/lib/helper-versions.js +1 -1
  91. package/dist/lib/hosts/remote-cmd.d.ts +51 -1
  92. package/dist/lib/hosts/remote-cmd.js +125 -8
  93. package/dist/lib/hosts/remote-cmd.test-fixture.d.ts +2 -0
  94. package/dist/lib/hosts/remote-cmd.test-fixture.js +22 -0
  95. package/dist/lib/mcp.js +17 -11
  96. package/dist/lib/probe.d.ts +4 -1
  97. package/dist/lib/probe.js +5 -2
  98. package/dist/lib/pwsh.d.ts +33 -0
  99. package/dist/lib/pwsh.js +56 -0
  100. package/dist/lib/redact.d.ts +8 -0
  101. package/dist/lib/redact.js +11 -0
  102. package/dist/lib/refresh.d.ts +6 -2
  103. package/dist/lib/refresh.js +92 -72
  104. package/dist/lib/secrets-cli.d.ts +11 -0
  105. package/dist/lib/secrets-cli.js +30 -0
  106. package/dist/lib/secrets-client.js +3 -2
  107. package/dist/lib/session/detached.d.ts +7 -0
  108. package/dist/lib/session/detached.js +29 -0
  109. package/dist/lib/session/remote/peer-stream.d.ts +24 -2
  110. package/dist/lib/session/remote/peer-stream.js +33 -6
  111. package/dist/lib/session/sync/backend.d.ts +3 -3
  112. package/dist/lib/session/sync/backend.js +3 -3
  113. package/dist/lib/session/sync/provision.d.ts +1 -1
  114. package/dist/lib/session/sync/provision.js +2 -2
  115. package/dist/lib/sessions-client.js +0 -3
  116. package/dist/lib/setup-tool-install.d.ts +3 -0
  117. package/dist/lib/setup-tool-install.js +26 -0
  118. package/dist/lib/setup-tool-status.d.ts +22 -0
  119. package/dist/lib/setup-tool-status.js +215 -0
  120. package/dist/lib/share-runtime.d.ts +11 -0
  121. package/dist/lib/share-runtime.js +63 -0
  122. package/dist/lib/smart-launch.d.ts +1 -5
  123. package/dist/lib/smart-launch.js +3 -11
  124. package/dist/lib/ssh-exec.d.ts +44 -0
  125. package/dist/lib/ssh-exec.js +119 -0
  126. package/dist/lib/startup/command-registry.d.ts +6 -4
  127. package/dist/lib/startup/command-registry.js +10 -7
  128. package/dist/lib/state.js +2 -2
  129. package/dist/lib/storage/selection.d.ts +2 -2
  130. package/dist/lib/storage/selection.js +2 -2
  131. package/dist/lib/sync-umbrella.d.ts +5 -0
  132. package/dist/lib/sync-umbrella.js +18 -10
  133. package/dist/lib/traces/backend.d.ts +1 -2
  134. package/dist/lib/traces/backend.js +1 -2
  135. package/dist/lib/traces/provision.d.ts +1 -1
  136. package/dist/lib/traces/provision.js +2 -2
  137. package/dist/lib/types.d.ts +8 -6
  138. package/package.json +2 -3
  139. package/dist/commands/artifacts-setup.d.ts +0 -53
  140. package/dist/commands/artifacts-setup.js +0 -161
  141. package/dist/commands/artifacts.d.ts +0 -18
  142. package/dist/commands/artifacts.js +0 -58
  143. package/dist/commands/attach.d.ts +0 -12
  144. package/dist/commands/attach.js +0 -86
  145. package/dist/commands/auth-mint.d.ts +0 -12
  146. package/dist/commands/auth-mint.js +0 -108
  147. package/dist/commands/reconnect.d.ts +0 -46
  148. package/dist/commands/reconnect.js +0 -115
  149. package/dist/commands/share.d.ts +0 -293
  150. package/dist/commands/share.js +0 -1424
  151. package/dist/lib/share/analytics.d.ts +0 -13
  152. package/dist/lib/share/analytics.js +0 -45
  153. package/dist/lib/share/backend.d.ts +0 -120
  154. package/dist/lib/share/backend.js +0 -176
  155. package/dist/lib/share/capture.d.ts +0 -31
  156. package/dist/lib/share/capture.js +0 -174
  157. package/dist/lib/share/config.d.ts +0 -72
  158. package/dist/lib/share/config.js +0 -211
  159. package/dist/lib/share/delete.d.ts +0 -123
  160. package/dist/lib/share/delete.js +0 -173
  161. package/dist/lib/share/html.d.ts +0 -20
  162. package/dist/lib/share/html.js +0 -88
  163. package/dist/lib/share/http-error.d.ts +0 -53
  164. package/dist/lib/share/http-error.js +0 -65
  165. package/dist/lib/share/og.d.ts +0 -26
  166. package/dist/lib/share/og.js +0 -84
  167. package/dist/lib/share/provision.d.ts +0 -127
  168. package/dist/lib/share/provision.js +0 -285
  169. package/dist/lib/share/publish.d.ts +0 -379
  170. package/dist/lib/share/publish.js +0 -818
  171. package/dist/lib/share/worker-template.d.ts +0 -27
  172. package/dist/lib/share/worker-template.js +0 -2424
  173. package/dist/lib/storage/index.d.ts +0 -14
  174. package/dist/lib/storage/index.js +0 -14
  175. package/dist/lib/storage/visibility.d.ts +0 -82
  176. package/dist/lib/storage/visibility.js +0 -99
@@ -1,379 +0,0 @@
1
- import { type ShareConfig } from './config.js';
2
- import { type ShareBackendKind } from './backend.js';
3
- import { type ShareVisibility } from '../storage/visibility.js';
4
- /** The share upload result. `body`/`retryAfter` carry the server's error
5
- * response so a failed publish can surface WHY (the Worker returns
6
- * `{"error":"…"}` + a `Retry-After` on a 429); they are read only on `!ok`
7
- * paths, and only ever fed through the bounded {@link extractShareHttpError}. */
8
- type PutResult = {
9
- ok: boolean;
10
- status: number;
11
- url?: string;
12
- /** Response body text, present on the `!ok` path so the error can be extracted. */
13
- body?: string;
14
- /** `Retry-After` header value, present on a 429. */
15
- retryAfter?: string;
16
- };
17
- export type PutFn = (url: string, body: Buffer, headers: Record<string, string>) => Promise<PutResult>;
18
- interface PublishEndpoint {
19
- baseUrl: string;
20
- token: string;
21
- }
22
- export interface PublishOptions {
23
- /** Internal resolved backend; publishFile sets this after authentication. */
24
- backendKind?: ShareBackendKind;
25
- slug?: string;
26
- /**
27
- * Auto-expire window. Relative (`30d`, `12h`), absolute (`2026-08-01`), or
28
- * `never` / `none` / `permanent` for no expiry. When omitted, publishes default
29
- * to {@link DEFAULT_SHARE_EXPIRE} so an accidental share decays instead of
30
- * living forever (RUSH-2443).
31
- */
32
- expire?: string;
33
- contentType?: string;
34
- /**
35
- * Server-enforced visibility (RUSH-3135). `public` (default) is listed in
36
- * the gallery; `unlisted` is a capability URL (GET still 200, X-Robots-Tag:
37
- * noindex, hidden from gallery/list — obscurity, NOT authentication);
38
- * `private` is token-gated (the Worker serves it only to a request carrying
39
- * the matching viewer key, else 404 — the real read-auth fix, PHNX-3654);
40
- * `me` requires a Phoenix session and is visible only to the signed-in owner;
41
- * `org` requires the same and is visible to members of the same Phoenix
42
- * organization.
43
- */
44
- visibility?: ShareVisibility;
45
- /**
46
- * Hide this page from the public `/<user>` gallery and `agents artifacts share list`
47
- * (metadata `visibility=unlisted`). The direct URL is still world-readable —
48
- * unlisted, not secret (RUSH-2443). Alias of `--visibility unlisted` /
49
- * `--private` on the CLI. Kept so `sessions share` and existing callers do
50
- * not break.
51
- */
52
- unlisted?: boolean;
53
- /**
54
- * Token-gate this page (`--protected` → `visibility=private`, PHNX-3654). The
55
- * CLI mints a random viewer token, the Worker stores only its SHA-256 hash,
56
- * and the published URL carries `?k=<token>`; a request without a matching
57
- * `?k=` / `Authorization: Bearer` gets a `404`. Unlike `unlisted` (obscurity),
58
- * this is enforced read-auth. Alias of `--visibility private`.
59
- */
60
- protected?: boolean;
61
- /**
62
- * Bypass the pre-publish sensitive-content scan (emails / credential-shaped
63
- * strings). Required when the page intentionally carries those patterns.
64
- */
65
- force?: boolean;
66
- /** Generate + attach an OG cover for HTML pages (default true). */
67
- cover?: boolean;
68
- /** Inject the Cloudflare Web Analytics beacon (default true for HTML). */
69
- analytics?: boolean;
70
- /** Override the analytics token from share config. */
71
- analyticsToken?: string;
72
- /** Override the GitHub username used for the URL namespace (BYO path). */
73
- githubUser?: string;
74
- /**
75
- * Override the managed public handle (PHNX-3547). Managed publishes normally
76
- * namespace under the email local-part; when that handle is taken — or a
77
- * vanity namespace is wanted — pass an alternate. Sanitized to
78
- * `[a-z0-9-]` (max 63 chars, matching the Worker); the Worker binds it with
79
- * the same first-writer claim as a derived handle. Ignored on BYO (use
80
- * `githubUser` there).
81
- */
82
- handle?: string;
83
- /** DI seam for tests — override the persisted share endpoint config. */
84
- config?: ShareConfig;
85
- /** DI seam for tests — override the keychain-backed write token. Selects BYO. */
86
- writeToken?: string;
87
- /** DI seam for tests — override `readSession()`. `null` means signed out. */
88
- session?: import('../identity/client.js').PhoenixSession | null;
89
- /**
90
- * Override the sharer's avatar URL stamped on the object (test seam). When
91
- * omitted it is derived from the signed-in email via {@link resolveShareAvatar};
92
- * an empty string suppresses the stamp (initials-only bar).
93
- */
94
- avatar?: string;
95
- /** Force the BYO Cloudflare path even when signed in. */
96
- byo?: boolean;
97
- /** DI seam for tests — override the real HTTP PUT. */
98
- uploader?: PutFn;
99
- /** DI seam for tests — override cover capture (returns a PNG buffer or null). */
100
- capturer?: (htmlPath: string) => Promise<Buffer | null>;
101
- /**
102
- * Human display title, shown instead of the slug in the gallery and
103
- * `agents artifacts share list`. When omitted, one is derived (HTML `<title>`,
104
- * else a Markdown frontmatter `title:`, else the filename) — a share always
105
- * carries a label, never a blocking prompt (see {@link deriveLabel}).
106
- */
107
- label?: string;
108
- /**
109
- * Structured metadata (`--meta key=value`, repeatable). Keys are validated by
110
- * {@link parseMetaEntries} — lowercase `[a-z0-9-]`, and may not collide with
111
- * {@link RESERVED_META_KEYS} (Worker-stamped owner/visibility/expires-at,
112
- * plus provenance the CLI sets automatically).
113
- */
114
- meta?: Record<string, string>;
115
- /**
116
- * Skip revision retention on this publish — overwrite an existing slug's
117
- * object in place with no `<slug>/rev-<ts>` backup of the version it replaces
118
- * (default: keep it; see docs/distribution.md).
119
- */
120
- noRevision?: boolean;
121
- /** DI seam for tests — override provenance auto-capture (agent/session/host/repo/date). */
122
- provenance?: ShareProvenance;
123
- }
124
- export { type ShareVisibility } from '../storage/visibility.js';
125
- /** The visibility levels a publish `--visibility` may select — the Worker's own
126
- * set. `private` (token-gated, PHNX-3654) is settable only at publish time,
127
- * since it mints a viewer token the metadata-edit route can't carry, so it is
128
- * NOT in {@link SHARE_VISIBILITY_LEVELS} (the in-place `share visibility <level>`
129
- * set). */
130
- export declare const PUBLISH_VISIBILITY_LEVELS: readonly ShareVisibility[];
131
- /** The visibility levels an ALREADY-published share may be re-scoped to in place
132
- * — the set `share visibility <target> <level>` and the inline owner control
133
- * accept. Excludes `private`: re-scoping to token-gated needs a fresh viewer
134
- * token, which only the publish path mints. */
135
- export declare const SHARE_VISIBILITY_LEVELS: readonly ShareVisibility[];
136
- export interface PublishResult {
137
- url: string;
138
- /** URL-safe object name, explicit (`--slug`) or deterministically derived. */
139
- slug?: string;
140
- expiresAt?: string;
141
- coverUrl?: string;
142
- /** Server-enforced visibility stamped on the object. */
143
- visibility?: ShareVisibility;
144
- /** True when the page was published with `visibility=unlisted`. */
145
- unlisted?: boolean;
146
- /** The raw viewer token minted for a `private` (token-gated) publish, or
147
- * undefined for any other visibility. It rides in {@link url} as `?k=<token>`;
148
- * only its hash is stored server-side. Treat as a secret. */
149
- viewerToken?: string;
150
- /** The label stored with this share — explicit (`--label`) or derived. */
151
- label?: string;
152
- /** Whether `label` came from `--label` or was auto-derived. */
153
- labelSource?: 'explicit' | 'derived';
154
- }
155
- /**
156
- * `--protected` / `{ protected: true }` map to `private` (token-gated — it wins
157
- * over `--unlisted` when both are set, being the stronger control); `--unlisted`
158
- * maps to `unlisted`; `--visibility private|unlisted|me|org` passes through;
159
- * otherwise `visibility` (default public).
160
- */
161
- export declare function resolveShareVisibility(opts?: {
162
- visibility?: ShareVisibility;
163
- unlisted?: boolean;
164
- protected?: boolean;
165
- }): ShareVisibility;
166
- /** SHA-256 hex of a viewer token — the form the Worker also computes and stores,
167
- * so a CLI-side preview of the stored hash matches. Exported for tests. */
168
- export declare function hashViewerToken(token: string): string;
169
- /**
170
- * The loud stderr warning printed on an `unlisted` / `--private` publish
171
- * (PHNX-3654): `unlisted` is obscurity, NOT read-authentication — anyone with
172
- * the URL can read it. Points the user at the real controls (`--protected`,
173
- * `--expire`, `me`/`org`). Lives here beside the visibility logic; `share.ts`
174
- * prints it so the lib layer stays free of `console.*`.
175
- */
176
- export declare function unlistedNotPrivateWarning(): string;
177
- export interface ShareProvenance {
178
- /** Harness/agent name (`AGENTS_AGENT_NAME`), when publishing from an agent run. */
179
- agent?: string;
180
- /** Session id (`AGENTS_SESSION_ID` / `AGENT_SESSION_ID`), when publishing from an agent run. */
181
- session?: string;
182
- /** The machine the publish ran from (`os.hostname()`) — always present. */
183
- host?: string;
184
- /** git repo name at publish time, absent outside a git checkout — never invented. */
185
- repo?: string;
186
- /** ISO date (`yyyy-mm-dd`) this publish happened, from the local clock. */
187
- date?: string;
188
- }
189
- /**
190
- * Reserved `customMetadata` keys a `--meta key=value` may not target (see
191
- * {@link parseMetaEntries}). Matches the Worker's `RESERVED_METADATA_KEYS`:
192
- * provenance the CLI sets automatically, plus `expires-at` / `visibility` /
193
- * `owner` which the Worker stamps itself.
194
- */
195
- export declare const RESERVED_META_KEYS: readonly ["expires-at", "published-at", "visibility", "viewer-token-hash", "owner", "org_domain", "agent", "session", "host", "repo", "date", "avatar", "label", "label-source", "og-title", "og-description", "og-generated", "og-source-etag"];
196
- /**
197
- * Auto-capture publish provenance from the exec env, git, and the local clock.
198
- * Every field is present only when the environment genuinely carries it — a
199
- * human running the command by hand outside a git repo yields `session`/`agent`/
200
- * `repo` all undefined, never an invented value. `host` is always present
201
- * (`os.hostname()` never fails to return something real about where the publish
202
- * ran, so it isn't "invented" in the same sense).
203
- */
204
- export declare function resolveShareProvenance(opts?: {
205
- env?: NodeJS.ProcessEnv;
206
- hostname?: string;
207
- dir?: string;
208
- now?: Date;
209
- }): ShareProvenance;
210
- /**
211
- * The sharer's avatar URL, stamped so the share bar can show a real profile
212
- * picture instead of only the initials circle. A hosted OAuth profile image
213
- * already known to identity (PhoenixSession.avatarUrl — captured at login and
214
- * refreshed from `/api/v1/auth/me`) wins outright; only when none exists do we
215
- * fall back to a Gravatar keyed on the SHA-256 of the signed-in user's
216
- * lowercased email (Gravatar resolves either MD5 or SHA-256), with `d=404` so
217
- * Gravatar returns 404 for a user who has none — the bar's `<img>` onerror
218
- * then falls back to the initials circle. Only the hash lands in public
219
- * metadata, never the raw email. Returns '' when signed out (BYO without a
220
- * Phoenix session), leaving the bar on the initials circle.
221
- *
222
- * `opts.session === null` means "explicitly signed out" (a test seam / BYO) and
223
- * yields ''; `undefined` reads the real persisted session.
224
- */
225
- export declare function resolveShareAvatar(opts?: {
226
- session?: import('../identity/client.js').PhoenixSession | null;
227
- }): string;
228
- /**
229
- * Parse repeated `--meta key=value` CLI args into a validated metadata record.
230
- * Keys are lowercase `[a-z0-9-]`, up to 64 characters, and may not collide with
231
- * {@link RESERVED_META_KEYS} (Worker-stamped owner/visibility/expires-at, plus
232
- * the provenance the CLI sets automatically, plus label/label-source) — throws
233
- * naming the offending pair on any violation.
234
- */
235
- export declare function parseMetaEntries(pairs: string[]): Record<string, string>;
236
- /** Throws when the combined `customMetadata` payload would exceed {@link MAX_METADATA_BYTES}. */
237
- export declare function assertMetadataSize(customMetadata: Record<string, string>): void;
238
- /**
239
- * Collapse a label to a single line before it goes into the `x-share-label`
240
- * header or public customMetadata. `<title>[^<]{1,200}</title>` matches
241
- * newlines (`[^<]` excludes only `<`), and `.trim()` only strips leading/
242
- * trailing whitespace, not embedded newlines — a multi-line `<title>` (or an
243
- * explicit `--label`/`--title` the caller typed with a literal newline) was
244
- * previously passed straight into `Headers.set()` unsanitized, which throws
245
- * an unhandled `TypeError: Invalid value` and crashes the publish outright.
246
- */
247
- export declare function sanitizeLabel(text: string): string;
248
- /**
249
- * Make a free-text value safe to put in an HTTP header.
250
- *
251
- * `fetch` encodes header values as a **ByteString**, so any code point above 255
252
- * throws `TypeError: Cannot convert argument to a ByteString` — an unhandled
253
- * crash with a stack trace, mid-publish, after the body has already been read.
254
- * Reproduced by publishing a session whose title ended in `…` (U+2026), and
255
- * reachable by any emoji, curly quote, accented name, or CJK text in a `--label`,
256
- * a `--meta` value, or a repo name.
257
- *
258
- * The transliterations above cover what actually shows up; anything else outside
259
- * latin1 is dropped, and a value that transliterates to nothing at all (a title
260
- * written entirely in a non-latin script) degrades to a marker rather than an
261
- * empty header. This value is the **latin1-safe floor** every Worker can read: a
262
- * pre-Unicode Worker only ever sees `x-share-<field>`, so it MUST stay folded.
263
- * Full Unicode rides ALONGSIDE it in a percent-encoded companion header
264
- * (`toPercentHeaderValue` / {@link needsUnicodeCompanion}), which a new Worker
265
- * opts into via `x-share-encoding: percent` and an old one ignores — so a
266
- * Japanese/emoji title renders in full on an updated Worker and still folds
267
- * gracefully everywhere else (PHNX-2786).
268
- */
269
- export declare function toHeaderValue(text: string): string;
270
- /**
271
- * Whether text carries a code point above latin1 (U+00FF) — the meaningful
272
- * display content `fetch`'s ByteString cannot hold, which {@link toHeaderValue}
273
- * therefore transliterates or drops. This is the range worth carrying in the
274
- * percent-encoded companion: an em dash, a curly quote, an emoji, or any
275
- * CJK/Arabic/Hindi text. A plain accented latin1 name (`José`, é = U+00E9) is
276
- * NOT lossy and needs no companion.
277
- *
278
- * `toHeaderValue` ALSO strips C0/C1 control characters (below U+0020, and
279
- * U+007F–U+009F), which this deliberately does not flag: a raw ANSI/control
280
- * sequence is not display text and must not be reconstructed into a page's
281
- * rendered metadata, so it stays dropped on both the old and new Worker paths.
282
- */
283
- export declare function needsUnicodeCompanion(text: string): boolean;
284
- /**
285
- * Percent-encode a single-line free-text value for the `x-share-<field>-u`
286
- * companion header. Whitespace is collapsed first (matching the folded value's
287
- * single-line shape), then `encodeURIComponent` makes it pure-ASCII and
288
- * header-safe. The Worker recovers the original with `decodeURIComponent`.
289
- */
290
- export declare function toPercentHeaderValue(text: string): string;
291
- /**
292
- * Best-effort human title when `--label` is omitted: the HTML `<title>`, else a
293
- * Markdown frontmatter `title:`, else the filename. Always returns something —
294
- * a headless publish must never hang waiting on a prompt for one.
295
- */
296
- export declare function deriveLabel(filePath: string, body: Buffer): string;
297
- /** Default auto-expire for unflagged publishes — accidental links decay (RUSH-2443). */
298
- export declare const DEFAULT_SHARE_EXPIRE = "30d";
299
- /** `30d` / `12h` / `2026-08-01` → an absolute ISO timestamp (or undefined). */
300
- export declare function parseExpire(spec: string | undefined): string | undefined;
301
- /**
302
- * Resolve the publish expiry. Omitted → {@link DEFAULT_SHARE_EXPIRE}. Explicit
303
- * `never` / `none` / `permanent` → no expiry. Anything else → {@link parseExpire}.
304
- */
305
- export declare function resolveExpire(spec: string | undefined): string | undefined;
306
- type SensitiveHitKind = 'email' | 'credential';
307
- interface SensitiveHit {
308
- kind: SensitiveHitKind;
309
- /** Short redacted sample so the error names *what* was found without dumping it. */
310
- sample: string;
311
- }
312
- /**
313
- * Mask every email address in `text`, so a page can be published without tripping
314
- * {@link scanShareContent}.
315
- *
316
- * Lives here, beside the scanner, rather than in `lib/redact.ts`: it exists solely
317
- * to satisfy this gate, and sharing {@link EMAIL_RE} is what makes the masking
318
- * *sufficient* to clear it rather than merely reducing the hit count. Two copies of
319
- * the pattern in two modules would drift, and the failure mode of that drift is a
320
- * refused publish at runtime.
321
- *
322
- * Deliberately NOT part of `redactSecrets`: an email is not a credential, and a
323
- * transcript rendered for a private gist or local review reads better with the real
324
- * author addresses intact. It only becomes a leak once the text is PUBLISHED — a
325
- * world-readable page carrying seven of them is the RUSH-2428 incident.
326
- *
327
- * The whole address goes, domain included — a personal domain identifies its owner
328
- * as surely as the local part does, and keeping it would buy the reader nothing.
329
- */
330
- export declare function redactEmails(text: string): string;
331
- /**
332
- * Scan a text body for email addresses and credential-shaped strings. Returns
333
- * the first few hits (deduped by kind+sample). Binary / non-text bodies yield
334
- * nothing — the gate is for HTML/text reports, not screenshots.
335
- */
336
- export declare function scanShareContent(body: string | Buffer): SensitiveHit[];
337
- /** Build the refuse message when the pre-publish scan finds sensitive content. */
338
- export declare function formatSensitiveContentError(hits: SensitiveHit[]): string;
339
- /** Derive a URL-safe slug from a filename, stripping its path and extension. */
340
- export declare function slugify(name: string): string;
341
- /** The project the file belongs to — git repo name, else the cwd's basename. */
342
- export declare function detectProject(dir?: string): string;
343
- /**
344
- * Stable default slug for an artifact: prefer its HTML `<title>` or Markdown
345
- * frontmatter `title:`, then fall back to its filename. The same artifact title
346
- * always yields the same slug, so republishing without `--slug` updates the same
347
- * URL. `--slug` remains an exact override.
348
- */
349
- export declare function defaultSlug(filePath: string, body?: Buffer): string;
350
- /**
351
- * Best-effort OG cover: capture a screenshot, upload it as `<slug>.png`, and return
352
- * the page body with og:image meta injected (+ the cover URL). All IO is injected
353
- * (`put`, `capturer`), so this whole path is unit-testable without config/keychain.
354
- * Any miss — no capturer output, a failed upload — returns the original body and no
355
- * coverUrl, so publishing never fails because a cover couldn't be made.
356
- */
357
- export declare function attachOgCover(filePath: string, body: Buffer, ctx: {
358
- /** Absolute URL to PUT the cover to, `${pageUrl}.png`. Doubles as the cover URL. */
359
- pngUrl: string;
360
- pageUrl: string;
361
- put: PutFn;
362
- pngHeaders: Record<string, string>;
363
- capturer: (p: string) => Promise<Buffer | null>;
364
- }): Promise<{
365
- body: Buffer;
366
- coverUrl?: string;
367
- }>;
368
- /** Resolve the publisher's GitHub username, with an explicit override winning first. */
369
- export declare function resolveShareUsername(opts?: {
370
- githubUser?: string;
371
- }): Promise<string>;
372
- /** Build the R2 object key from a namespace username and a slug part. */
373
- export declare function buildShareKey(username: string, slugPart: string): string;
374
- export declare function publishFile(filePath: string, opts?: PublishOptions): Promise<PublishResult>;
375
- /** Sanitize a caller-chosen managed handle to the Worker's namespace shape.
376
- * Returns '' when the result is empty or over the Worker's 63-char cap (the
377
- * caller then falls back to the derived handle / errors). */
378
- export declare function resolveManagedHandle(handle: string | undefined): string;
379
- export declare function publishToEndpoint(filePath: string, endpoint: PublishEndpoint, opts?: PublishOptions): Promise<PublishResult>;