Archilyzer · Source

archilyzer

Archilyzer
git clone https://archilyzer.pages.dev/source/archilyzer.git
Log | Files | Refs | README | LICENSE

commit 5c0f1bf848b802c7c754b1f775602203b2180660
parent 0a951783f3bacb96c122bd5627ea59be64b53869
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date:   Tue,  6 Oct 2026 12:31:50 -0400

ops: pnpm ops publish (a verb in the body) and pnpm ops get publish; the eight build/deploy actions named as its aliases

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Diffstat:
Mscripts/archilyzer-ops.mjs | 38+++++++++++++++++++++++++++++++-------
Mscripts/archilyzer-ops.test.mjs | 19++++++++++++++++++-
2 files changed, 49 insertions(+), 8 deletions(-)

diff --git a/scripts/archilyzer-ops.mjs b/scripts/archilyzer-ops.mjs @@ -88,11 +88,14 @@ const GETTERS = { // single tag's assignments, each carrying the provenance of the pin. tags: (tag) => tag ? `/api/ops/tags?tag=${encodeURIComponent(tag)}` : "/api/ops/tags", + // The publish status (release 18): the index, the lane, a row per site, the + // hub and the homepage with their chips, and the plan Publish now would run. + publish: () => "/api/ops/publish", }; // Nouns whose read takes no argument. `get channel` without a slug is a // mistake; `get tags` without one is the whole vocabulary. -const GET_ARG_OPTIONAL = new Set(["tags"]); +const GET_ARG_OPTIONAL = new Set(["tags", "publish"]); const ACTIONS = [ "channel-priority", @@ -117,15 +120,19 @@ const ACTIONS = [ "fetch-posts", // A screenshot and the attached media of specific archived posts. "capture-posts", + // Publishing as stages (release 18): {"verb": "index" | "build" | "deploy" | + // "hub" | "homepage" | "now" | "stale", …} — one run of stages on the + // editor's publish queue. The eight rows below are its aliases. + "publish", "build-index", "build-deploy", "build-site", - // Deploy the ALREADY-BUILT export/out — build-deploy's other half, and the - // one a preview is for: build once, look at the preview, then ship the same - // bundle to production without rebuilding it. + // Deploy the site's ALREADY-BUILT bundle — build-deploy's other half, and + // the one a preview is for: build once, look at the preview, then ship the + // same bundle to production without rebuilding it. "deploy-site", - // The HUB (the export app in hub mode, into the same export/out a site - // build uses) and its deploy to homepage.json's Pages project. + // The HUB (the export app in hub mode, into its own bundle) and its deploy + // to homepage.json's Pages project. "build-hub", "deploy-hub", // The HOMEPAGE (the `homepage` package, Archilyzer's own site, into @@ -321,6 +328,7 @@ export function usage() { " [--wait-timeout <seconds>] [--quiet]", " pnpm ops get channel <slug> [--counts]", " pnpm ops get tags [<tagId>]", + " pnpm ops get publish", " pnpm ops list", "", `Actions: ${ACTIONS.join(", ")}`, @@ -331,6 +339,22 @@ export function usage() { "--wait-timeout <seconds> gives up and exits 1 instead of waiting forever.", " Default: no timeout — the queue may legitimately hold a job for hours.", "", + 'publish runs publish stages on the editor\'s publish queue, one at a time,', + ' under one run id: {"verb": …}. "index" updates the index; "build" builds', + ' "siteId"/"siteIds" (forced; the index first when stale; "runner":', + ' "docker" builds every site in containers); "deploy" ships their built', + ' bundles (production, "preview": "<branch>", or "to": "local"; "force"', + ' redeploys a bundle already shipped there); "hub" / "homepage" build', + ' them, {"deploy": true} deploys after; "now" is Publish now (the stale', + ' index, then each policy target); "stale" builds every stale site. The', + ' answer lists every job ({target, kind, jobId}) and --wait follows them', + ' all. A site never built is refused: "no build of <id> in <dir> —', + ' archilyzer publish build <id>". `get publish` is the status.', + "", + 'build-index, build-site, build-deploy, deploy-site, build-hub, deploy-hub,', + ' build-homepage and deploy-homepage are publish\'s aliases, with their old', + ' bodies and answers ("skipData" is accepted and ignored).', + "", 'build-site, build-deploy and deploy-site all take "siteId" (one) or', ' "siteIds" (a list).', "", @@ -390,7 +414,7 @@ export function usage() { " alone. The alias is printed after the response. Lowercase letters,", ' digits and dashes, up to 28 characters; "main" is refused.', "", - 'build-hub builds the hub into export/out; {"deploy": true} deploys it', + 'build-hub builds the hub into its bundle; {"deploy": true} deploys it', ' after, and deploy-hub ships the one already built. Both deploy to the', " Pages project set on /sites under Hub, and take \"preview\" too.", "", diff --git a/scripts/archilyzer-ops.test.mjs b/scripts/archilyzer-ops.test.mjs @@ -359,7 +359,24 @@ test("build-hub and deploy-hub are POSTs to their own routes, named in the usage assert.equal(deploy.path, "/api/ops/deploy-hub"); assert.deepEqual(deploy.body, {}); assert.match(usage(), /Actions:.*build-hub, deploy-hub/); - assert.match(usage(), /build-hub builds the hub into export\/out/); + assert.match(usage(), /build-hub builds the hub into its bundle/); +}); + +// Publishing as stages (release 18): one route, a verb in the body; the status +// is a read. +test("publish is a POST to its route, and get publish the status, named in the usage", () => { + const p = parseArgs(["publish", "--json", '{"verb":"deploy","siteId":"jer","preview":"r18"}', "--wait"]); + assert.equal(p.method, "POST"); + assert.equal(p.path, "/api/ops/publish"); + assert.deepEqual(p.body, { verb: "deploy", siteId: "jer", preview: "r18" }); + assert.equal(p.wait, true); + const g = parseArgs(["get", "publish"]); + assert.equal(g.method, "GET"); + assert.equal(g.path, "/api/ops/publish"); + assert.match(usage(), /Actions:.*capture-posts, publish, build-index/); + assert.match(usage(), /pnpm ops get publish/); + assert.match(usage(), /"now" is Publish now/); + assert.match(usage(), /publish's aliases, with their old/); }); // The homepage's pair (release 11 slice O4), the hub's twins: a POST each, the