clone

push a directory of html from the terminal and get a four-character url back. a deno cli on cloudflare

docs: clarify contracts and JSR skill setup

Dami committed 54d857f
commit
54d857fd619d929fc4761fafc0fdd9eb6fecc2f8
parent
12e659b8eabbd9eac87afaf397636b0f223668f7
author
Dami <dami.etoile@gmail.com>
3 files changed, +94 -49
Mshared/types.ts107++++++++++++++++++++----------
Mskills/nzip/SKILL.md32++++++---
Mskills/nzip/agents/openai.yaml4+-
M shared/types.ts +70 -37
@@ -1,25 +1,37 @@
11 // Wire types shared by the CLI and the Worker.22 // This package must stay runtime-agnostic: Web APIs only, no Deno.* or Workers globals.33 4-/** A single file entry in a manifest. Keys are kept short because they're hashed verbatim. */4+/**5+ * Canonical metadata for one file in a manifest.6+ *7+ * The short property names are part of the version 1 wire format and are8+ * hashed verbatim when deriving the manifest identity.9+ */510 export interface ManifestFile {6- /** sha256 hex of the file bytes */11+ /** Lowercase, 64-character SHA-256 digest of the exact file bytes. */712 h: string;8- /** size in bytes */13+ /** Non-negative file size in bytes. */914 s: number;10- /** content-type, resolved at push time by the CLI */15+ /** Media type stored and served for the file, resolved by the CLI at push time. */1116 ct: string;1217 }1318 14-/** A push's complete file set — the content-addressed description of a site version. */19+/** Complete, versioned file map whose canonical bytes identify one site revision. */1520 export interface Manifest {16- /** manifest format version */21+ /** Manifest schema version. Version `1` is the only supported value. */1722 v: 1;18- /** path (relative, forward slashes, no leading ./) → file entry */23+ /**24+ * Map from validated relative paths to file metadata.25+ *26+ * Paths use forward slashes and omit a leading slash or `./`.27+ */1928 files: Record<string, ManifestFile>;2029 }2130 22-/** A push destination: a raw address, or a vault (optionally with an alias). */31+/**32+ * Destination for a push, expressed as either an exact numeric address or a33+ * registered vault with an optional alias.34+ */2335 export type Target =2436 | {2537 /** Numeric site address in the inclusive range `0x0000`–`0xffff`. */
@@ -38,11 +50,11 @@ export interface PrepareRequest {
3850 manifest: Manifest;3951 }4052 41-/** Reply to `prepare`: the manifest's hash and which blobs the server still needs. */53+/** Reply from `POST /api/push/prepare` describing the content still required. */4254 export interface PrepareResponse {4355 /** Lowercase SHA-256 of the canonical manifest bytes. */4456 manifestHash: string;45- /** blob hashes the server does not have yet */57+ /** Lowercase SHA-256 blob digests that must be uploaded before committing. */4658 missing: string[];4759 }4860
@@ -52,15 +64,15 @@ export interface CommitRequest {
5264 manifest: Manifest;5365 /** Address or vault destination that should receive the new version. */5466 target: Target;55- /** days until expiry; "forever" = no expiry; omitted = server default (14) */67+ /** Lifetime in days, `"forever"` for no expiry, or omitted for the server default. */5668 ttl?: number | "forever";57- /** set a password (string), clear it (null), or preserve it on an existing site (undefined) */69+ /** Password to set, `null` to clear it, or omitted to preserve an existing value. */5870 password?: string | null;5971 }6072 61-/** Reply to `commit`: the allocated address and the live URL for the new push. */73+/** Reply from `POST /api/push/commit` identifying the published site revision. */6274 export interface CommitResponse {63- /** 4-hex address, e.g. "2a3f" */75+ /** Four-character lowercase hexadecimal address, such as `"2a3f"`. */6476 address: string;6577 /** Absolute public URL of the committed site. */6678 url: string;
@@ -68,13 +80,13 @@ export interface CommitResponse {
6880 alias: string | null;6981 /** Lowercase SHA-256 of the committed canonical manifest. */7082 manifestHash: string;71- /** unix seconds, null = permanent */83+ /** Unix expiry timestamp in seconds, or `null` for a permanent site. */7284 expiresAt: number | null;73- /** push sequence number for this site */85+ /** Monotonically increasing push sequence number within this site. */7486 seq: number;7587 }7688 77-/** Summary of a single site, as returned by list/status endpoints. */89+/** Owner-visible summary of one site, as returned by list and status endpoints. */7890 export interface SiteInfo {7991 /** Four-character lowercase hexadecimal site address. */8092 address: string;
@@ -114,7 +126,10 @@ export interface SiteDetail extends SiteInfo {
114126 history: PushInfo[];115127 }116128 117-/** Current uploaded bundle for a site, returned only by the authenticated recovery API. */129+/**130+ * Current manifest for a site, returned only by the authenticated recovery131+ * API and used to locate and verify the bundle's blobs.132+ */118133 export interface SourceResponse {119134 /** Four-character lowercase hexadecimal address of the recovered site. */120135 address: string;
@@ -124,7 +139,7 @@ export interface SourceResponse {
124139 manifest: Manifest;125140 }126141 127-/** A registered vault: its slot, name, and current site count. */142+/** Owner-visible metadata and live site count for a registered vault. */128143 export interface VaultInfo {129144 /** Numeric vault slot in the inclusive range `0x0`–`0xf`. */130145 slot: number;
@@ -148,7 +163,7 @@ export interface StatusResponse {
148163 vaults: VaultInfo[];149164 /** Total number of currently registered sites across every vault. */150165 siteCount: number;151- /** sites expiring within 48h */166+ /** Number of sites whose expiry falls within the next 48 hours. */152167 expiringSoon: number;153168 }154169
@@ -158,11 +173,11 @@ export interface RevertRequest {
158173 toSeq?: number;159174 }160175 161-/** Body of a site PATCH: change TTL and/or password. Omitted fields are left unchanged. */176+/** Body of a site PATCH. Omitted access-policy fields remain unchanged. */162177 export interface PatchSiteRequest {163178 /** New lifetime in days, or `"forever"`; omission preserves the current expiry. */164179 ttl?: number | "forever";165- /** set a password (string), clear it (null), or leave unchanged (undefined) */180+ /** Password to set, `null` to clear it, or omitted to leave it unchanged. */166181 password?: string | null;167182 }168183
@@ -178,13 +193,22 @@ export interface NotifyRequest {
178193 title?: string;179194 /** Required notification body. */180195 body: string;181- /** Optional normalized, same-origin path opened when the notification is tapped. */196+ /**197+ * Optional normalized, same-origin site path opened when the notification is198+ * tapped. A site target is pinned to its current manifest when accepted and199+ * will not open if that site changes before the tap.200+ */182201 path?: string;183- /** Optional provider-independent replacement/deduplication tag. */202+ /** Optional provider-independent tag used to replace a related notification. */184203 tag?: string;185204 }186205 187-/** Reply from `POST /api/notify`; acceptance does not imply delivery. */206+/**207+ * Reply from `POST /api/notify` after durable outbox acceptance.208+ *209+ * Acceptance confirms that eligible deliveries were queued; it does not imply210+ * that a push provider or device displayed the notification.211+ */188212 export interface NotifyResponse {189213 /** Stable identifier for the persisted notification event. */190214 eventId: string;
@@ -194,7 +218,10 @@ export interface NotifyResponse {
194218 inactiveDevices: number;195219 }196220 197-/** Current owner-controlled window during which new notification devices may enroll. */221+/**222+ * Current owner-controlled window during which new notification devices may223+ * request enrollment. An opened window closes automatically after ten minutes.224+ */198225 export interface NotifyPairingWindow {199226 /** Whether the Worker currently accepts new enrollment requests. */200227 enabled: boolean;
@@ -202,7 +229,13 @@ export interface NotifyPairingWindow {
202229 expiresAt: number | null;203230 }204231 205-/** Server-side lifecycle state for an owner-approved notification device. */232+/**233+ * Server-side lifecycle state for a notification device.234+ *235+ * Devices progress from `pending` enrollment to `approved`, then `active` once236+ * a subscription is attached. `disabled`, `revoked`, and `expired` are237+ * non-deliverable states.238+ */206239 export type NotifyDeviceStatus =207240 | "pending"208241 | "approved"
@@ -213,7 +246,7 @@ export type NotifyDeviceStatus =
213246 214247 /** Owner-visible notification device metadata. Subscription secrets are never returned. */215248 export interface NotifyDeviceInfo {216- /** Opaque stable identifier used for revocation. */249+ /** Opaque, stable identifier used for owner actions such as revocation. */217250 id: string;218251 /** Owner-assigned display name, or `null` while pairing is pending. */219252 name: string | null;
@@ -223,7 +256,7 @@ export interface NotifyDeviceInfo {
223256 userAgentSummary: string | null;224257 /** Coarse device class such as phone, tablet, or desktop. */225258 deviceClass: string | null;226- /** Two-letter country code reported by the edge, when available. */259+ /** Two-letter ISO 3166-1 country code reported by the edge, when available. */227260 country: string | null;228261 /** Bounded region code reported by the edge, when available. */229262 region: string | null;
@@ -231,19 +264,19 @@ export interface NotifyDeviceInfo {
231264 asn: number | null;232265 /** Unix timestamp, in seconds, when enrollment began. */233266 createdAt: number;234- /** Unix expiry for an unapproved pairing code, or `null` once inapplicable. */267+ /** Unix expiry timestamp for an unapproved pairing code, or `null` once inapplicable. */235268 pairingExpiresAt: number | null;236- /** Unix expiry for the approved claim, or `null` when unavailable. */269+ /** Unix expiry timestamp for an approved claim, or `null` when inapplicable. */237270 claimExpiresAt: number | null;238- /** Unix timestamp of owner approval, or `null` before approval. */271+ /** Unix timestamp, in seconds, of owner approval, or `null` before approval. */239272 approvedAt: number | null;240- /** Unix timestamp of first active subscription attachment, or `null`. */273+ /** Unix timestamp, in seconds, of first subscription attachment, or `null` before it. */241274 activeAt: number | null;242- /** Unix timestamp of the most recent subscription attachment, or `null`. */275+ /** Unix timestamp, in seconds, of the latest attachment, or `null` if never attached. */243276 lastAttachedAt: number | null;244- /** Unix timestamp of the most recent validated device request, or `null`. */277+ /** Unix timestamp, in seconds, of the latest validated request, or `null` if unseen. */245278 lastSeenAt: number | null;246- /** Unix timestamp of the most recent successful Web Push delivery, or `null`. */279+ /** Unix timestamp, in seconds, of the latest successful delivery, or `null` if none. */247280 lastSuccessAt: number | null;248281 /** Bounded error class only; provider responses and subscription material are excluded. */249282 lastError: string | null;
@@ -257,7 +290,7 @@ export interface NotifyApprovalPreview {
257290 userAgentSummary: string | null;258291 /** Coarse device class such as phone, tablet, or desktop. */259292 deviceClass: string | null;260- /** Two-letter country code reported by the edge, when available. */293+ /** Two-letter ISO 3166-1 country code reported by the edge, when available. */261294 country: string | null;262295 /** Bounded region code reported by the edge, when available. */263296 region: string | null;
M skills/nzip/SKILL.md +22 -10
@@ -1,24 +1,29 @@
11 ---22 name: nzip3-description: Set up, diagnose, and use the nzip HTML sharing CLI with repository-local working directories and safe publishing defaults. Use when installing or authenticating nzip, troubleshooting nzip access, publishing or managing an HTML artifact, pairing notification devices, sending or managing owner notifications, or establishing nzip conventions in a repository.3+description: Install, authenticate, diagnose, and use the nzip HTML sharing CLI with safe publishing defaults. Use when installing nzip from JSR for a user, troubleshooting nzip access, publishing or managing an HTML artifact, pairing notification devices, sending or managing owner notifications, or establishing repository-local artifact conventions.44 ---55 66 # nzip77 8-Use nzip to publish HTML while keeping the editable source beside the repository context that9-produced it. Diagnose the local installation before guessing about unavailable access.8+Use the user-installed nzip CLI to publish HTML. Diagnose the local installation before guessing9+about unavailable access. Keep editable artifact source beside its repository context when one10+exists, but do not clone or download the nzip repository merely to install the CLI.1011 1112 ## Setup1213 13-1. Locate the repository root with `git rev-parse --show-toplevel` when inside a Git repository.14-2. Check for the CLI with `command -v nzip` and `nzip --help`.15-3. If it is missing and Deno is available, install or upgrade it:14+1. Check for the user CLI with `command -v nzip` and `nzip --help`.15+2. If it is missing and Deno is available, install the latest JSR release globally:1616 1717 ```sh1818 deno install -g -A -f -n nzip jsr:@nzip/cli1919 ```2020 21-4. Authenticate only with a server and token supplied by the user or environment:21+ Use the same command to upgrade an existing user installation when the user requests an upgrade22+ or the installed CLI lacks a command required by the task. Do not clone the nzip repository or23+ run its source checkout as the normal installation path. Pin `jsr:@nzip/cli@<version>` only when24+ reproducibility is explicitly required.25+26+3. Authenticate only with a server and token supplied by the user or environment:2227 2328 ```sh2429 nzip auth --server <url> --token <token>
@@ -30,7 +35,14 @@ produced it. Diagnose the local installation before guessing about unavailable a
3035 requires a TTY: in a non-interactive run, omitting `--token` fails instead of prompting, so ask3136 the user to run `nzip auth` themselves. Never print, commit, or invent the token.3237 33-5. Ensure the repository `.gitignore` contains this exact rule:38+## Prepare an artifact workspace39+40+Only perform these repository steps when creating or revising a local artifact:41+42+1. Locate the repository root with `git rev-parse --show-toplevel` when inside a Git repository.43+ Otherwise, use a user-approved working directory; do not download a repository just to obtain44+ one.45+2. Ensure the repository `.gitignore` contains this exact rule:3446 3547 ```gitignore3648 .nzip-*/
@@ -45,8 +57,8 @@ produced it. Diagnose the local installation before guessing about unavailable a
4557 4658 Run checks in this order and stop at the first failure that needs user input:4759 48-1. `command -v nzip` — if missing, follow Setup.49-2. `nzip --help` — confirm the installed command starts.60+1. `command -v nzip` — if missing, follow the JSR installation in Setup.61+2. `nzip --help` — confirm the installed command starts and inspect its supported command surface.5062 3. `nzip status --json` — verify saved authentication, server reachability, and token validity.5163 4. `nzip vault ls --json` — verify available vaults and the default vault.5264
M skills/nzip/agents/openai.yaml +2 -2