@zuroku/cli
Advanced tools
+17
-12
@@ -187,8 +187,13 @@ #!/usr/bin/env node | ||
| var HTML_MAX_BYTES = 5 * 1024 * 1024; | ||
| function rewriteHtmlForRename(html, renameMap) { | ||
| function rewriteHtmlForRename(html, renameMap, providedFilenames = []) { | ||
| const map = /* @__PURE__ */ new Map(); | ||
| for (const f of providedFilenames) map.set(f, f); | ||
| for (const { from, to } of renameMap) map.set(from, to); | ||
| let out = html; | ||
| for (const { from, to } of renameMap) { | ||
| if (from === to) continue; | ||
| for (const [from, to] of map) { | ||
| const escaped = from.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); | ||
| out = out.replace(new RegExp(`(img/)${escaped}(?=["'\\s),])`, "g"), `$1${to}`); | ||
| out = out.replace( | ||
| new RegExp(`(?:img|images)/${escaped}(?=["'\\s),])`, "g"), | ||
| `img/${to}` | ||
| ); | ||
| } | ||
@@ -312,5 +317,6 @@ return out; | ||
| const htmlOriginal = htmlBuf.toString("utf8"); | ||
| const htmlText = renameMap.length > 0 ? rewriteHtmlForRename(htmlOriginal, renameMap) : htmlOriginal; | ||
| if (renameMap.length > 0 && htmlText !== htmlOriginal) { | ||
| info(`html: rewrote <img src> references for ${renameMap.length} compressed asset(s)`); | ||
| const providedFilenames = assets.map((a) => a.filename); | ||
| const htmlText = rewriteHtmlForRename(htmlOriginal, renameMap, providedFilenames); | ||
| if (htmlText !== htmlOriginal) { | ||
| info(`html: rewrote img src references (path normalize / extension rename)`); | ||
| } | ||
@@ -330,3 +336,2 @@ const htmlForUpload = htmlText !== htmlOriginal ? Buffer.from(htmlText, "utf8") : htmlBuf; | ||
| const { references, expectedFilenames } = extractHtmlAssetRefs(htmlText); | ||
| const providedFilenames = assets.map((a) => a.filename); | ||
| const provided = new Set(providedFilenames); | ||
@@ -486,5 +491,6 @@ const missing = [...expectedFilenames].filter((f) => !provided.has(f)); | ||
| const htmlOriginal = htmlBuf.toString("utf8"); | ||
| const htmlText = renameMap.length > 0 ? rewriteHtmlForRename(htmlOriginal, renameMap) : htmlOriginal; | ||
| if (renameMap.length > 0 && htmlText !== htmlOriginal) { | ||
| info(`html: rewrote <img src> references for ${renameMap.length} compressed asset(s)`); | ||
| const providedFilenames = assets.map((a) => a.filename); | ||
| const htmlText = rewriteHtmlForRename(htmlOriginal, renameMap, providedFilenames); | ||
| if (htmlText !== htmlOriginal) { | ||
| info(`html: rewrote img src references (path normalize / extension rename)`); | ||
| } | ||
@@ -504,3 +510,2 @@ const htmlForUpload = htmlText !== htmlOriginal ? Buffer.from(htmlText, "utf8") : htmlBuf; | ||
| const { references, expectedFilenames } = extractHtmlAssetRefs(htmlText); | ||
| const providedFilenames = assets.map((a) => a.filename); | ||
| const provided = new Set(providedFilenames); | ||
@@ -507,0 +512,0 @@ const missing = [...expectedFilenames].filter((f) => !provided.has(f)); |
+1
-1
| { | ||
| "name": "@zuroku/cli", | ||
| "version": "0.1.3", | ||
| "version": "0.1.4", | ||
| "type": "module", | ||
@@ -5,0 +5,0 @@ "description": "Command-line publisher for zuroku — upload AI-generated graphic-recording HTML + assets to your zuroku instance.", |
+13
-0
@@ -50,2 +50,3 @@ # @zuroku/cli | ||
| | `zuroku publish <html> <assets...>` | Upload an HTML page and its referenced images. | | ||
| | `zuroku update <slug-or-id> <html> [images...]` | Republish an existing project, keeping its slug / URL (full asset replacement). | | ||
| | `zuroku list` | List the publishes owned by the current token. | | ||
@@ -57,2 +58,13 @@ | `zuroku delete <slug>` | Soft-delete a publish. | | ||
| ### Update an existing publish | ||
| `zuroku update` republishes the same slug / URL (no `-2` suffix). The asset set is fully replaced — pass every image you want present after the update. | ||
| ```bash | ||
| # slug or id (both work). HTML auto-rewrite & preflight are identical to publish. | ||
| zuroku update my-cool-page ./index.html ./img/*.png | ||
| ``` | ||
| Use this when you tweak the HTML or swap images but want the URL stable. To get a brand-new URL instead, `zuroku publish` again. | ||
| ## HTML / asset constraints | ||
@@ -73,2 +85,3 @@ | ||
| | `[WRONG-PATH]` | `<img src>` does not start with `img/`. | | ||
| | `LOCAL_PATH_LEAK` | HTML body contains an author-machine path (`/Users/…`, `/home/…`, `file://`, `C:\Users\…`, `/var/folders/…`). These 404 for viewers — strip them before publishing. Bypass with `ZUROKU_SKIP_PREFLIGHT=1` (debug only). | | ||
@@ -75,0 +88,0 @@ ## Visibility |
@@ -7,3 +7,3 @@ --- | ||
| author: AI-Driven-R-D-Dept | ||
| version: '0.1.2' | ||
| version: '0.1.3' | ||
| user-invocable: true | ||
@@ -76,2 +76,29 @@ argument-hint: <html-path> [image-paths...] --title "..." [--no-compress] [--visibility private|curator] [--private] | ||
| ### R5. local-path leak preflight (v0.1.3+) | ||
| preflight は asset 参照だけでなく **HTML 全体を text として scan** し、viewer 環境では絶対に解決しない作者マシン path を見つけたら `LOCAL_PATH_LEAK` で fail-fast する: | ||
| | pattern | severity | 例 | | ||
| |---|---|---| | ||
| | `/Users/<name>/...` | error | macOS の個人 home | | ||
| | `/home/<name>/...` | error | Linux の個人 home | | ||
| | `file://...` | error | local file URI | | ||
| | `C:\Users\...` / `Documents\` / `Desktop\` | error | Windows の個人 path | | ||
| | `/var/folders/...` | error | macOS の TMPDIR layout | | ||
| | `~/...` | warn | warn のみ、publish は通る | | ||
| 検知された場合は **HTML 側を直して** から再 publish する (絶対パスを削除 / 公開 URL に置換 / ファイル名だけ抽象的に言及)。`<code>` ブロックや本文中の引用にも leak しやすい。 | ||
| ## update (republish) — slug を維持して上書き (v0.1.3+) | ||
| ```bash | ||
| # slug でも id でも OK。HTML auto-rewrite / preflight は publish と同じ。 | ||
| zuroku update my-cool-page ./index.html ./img/*.png | ||
| ``` | ||
| - 既存 project の HTML と asset を **完全置換** して同じ slug / URL で再公開する (`-2` は付かない)。 | ||
| - asset は **全置換**。残したい画像も含めて positional 引数で渡すこと (省略すると 0 件で送られる)。 | ||
| - 新しい URL を発行したい場合は `update` でなく `publish` を使う。 | ||
| - 内部的には `republish-init` → `uploadHtml`/`uploadAsset` (新 token) → `republish` の 3 段階。失敗しても manifest swap (3 段目) までは旧版が viewer に出続ける。 | ||
| ## 認証 | ||
@@ -122,2 +149,3 @@ | ||
| | `INVALID_INPUT [MISSING]` | HTML 内 src と asset の filename 不一致 | preflight メッセージの Suggested fixes を読む | | ||
| | `LOCAL_PATH_LEAK` | HTML 本文に `/Users/...` 等の作者マシン path が混入 (v0.1.3+ で検知) | HTML 側で絶対パスを削除 / 公開 URL に置換 / ファイル名だけ抽象的に言及 | | ||
| | 配信ページで画像 404 | (v0.1.1+ では自動 rewrite される。それ以前 / HTML を直接書き換えていた場合) basename 不一致。HTML の `<img src="img/...">` と asset 引数の filename を再確認 | | ||
@@ -124,0 +152,0 @@ | `UNSUPPORTED_MEDIA 415` | SVG / Content-Type 偽装 | PNG/JPEG/WebP/GIF のみ | |
Sorry, the diff of this file is too big to display
138237
2.82%783
0.64%133
10.83%