@heycys/gallery 0.2.3 → 0.2.4
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 +1 -1
- package/THIRD-PARTY-NOTICES.md +1 -1
- package/assets/preview/runtime.js +156 -0
- package/assets/preview/shell.html +107 -0
- package/assets/writing-preferences.md +1 -1
- package/browser/editor/components/divider/index.mjs +1 -1
- package/browser/editor/page/annotate/card.mjs +6 -0
- package/browser/editor/page/annotate/index.mjs +22 -2
- package/browser/editor/page/columns/index.mjs +1 -1
- package/browser/editor/page/conflicts.mjs +1 -1
- package/browser/editor/page/drag/index.mjs +1 -1
- package/browser/editor/page/editor.mjs +39 -3
- package/browser/editor/page/focus.mjs +104 -0
- package/browser/editor/page/handle/index.mjs +14 -2
- package/browser/editor/page/links/index.mjs +2 -2
- package/browser/editor/page/quiet.mjs +3 -3
- package/browser/editor/page/resize/index.mjs +1 -1
- package/browser/editor/page/session.mjs +4 -1
- package/browser/editor/page/ui.mjs +1 -1
- package/browser/shared/annotations.mjs +22 -3
- package/browser/shared/block-packs.mjs +13 -4
- package/browser/shared/document-look.mjs +14 -0
- package/browser/shared/drafts.mjs +1 -1
- package/browser/shared/extension-manifest.mjs +40 -12
- package/browser/shared/favorite-merge.mjs +17 -0
- package/browser/shared/favorites.mjs +77 -0
- package/browser/shared/i18n/en.mjs +123 -24
- package/browser/shared/outline-ops.mjs +109 -0
- package/browser/shared/outline.mjs +6 -0
- package/browser/shared/pages.mjs +20 -8
- package/browser/shared/paths.mjs +5 -2
- package/browser/shared/preference-documents.mjs +137 -0
- package/browser/shared/presence.mjs +94 -0
- package/browser/shared/preview-server.mjs +8 -5
- package/browser/shared/qa-levels.mjs +9 -1
- package/browser/shared/session.mjs +4 -0
- package/browser/shared/shipped-blocks.mjs +22 -4
- package/browser/shared/startup.mjs +101 -0
- package/browser/shared/workspace-columns.mjs +1 -1
- package/browser/shared/workspace-look.mjs +21 -8
- package/browser/shared/workspace-registry.mjs +6 -3
- package/browser/shared/workspace.mjs +37 -10
- package/browser/shared/writing-preferences.mjs +2 -42
- package/dist/chunk-25LYSMAE.mjs +2 -0
- package/dist/chunk-2I6ZVC5O.mjs +2 -0
- package/dist/{chunk-M4NRDYI5.mjs → chunk-2MYTOOP6.mjs} +1 -1
- package/dist/chunk-2VNENLER.mjs +2 -0
- package/dist/chunk-3FERXZF5.mjs +4 -0
- package/dist/chunk-3M6SBBGU.mjs +2 -0
- package/dist/chunk-3VCAAF34.mjs +2 -0
- package/dist/{chunk-WD4U6XXT.mjs → chunk-3ZTRLGSA.mjs} +1 -1
- package/dist/chunk-4FRA5AUE.mjs +2 -0
- package/dist/chunk-4LR2QEC2.mjs +4 -0
- package/dist/chunk-56SVJENP.mjs +966 -0
- package/dist/chunk-5CQISL2G.mjs +4 -0
- package/dist/{chunk-RRKJMHNX.mjs → chunk-5I5ZDDWC.mjs} +5 -5
- package/dist/chunk-5IHDLEB4.mjs +10 -0
- package/dist/chunk-5LRDMV7O.mjs +2 -0
- package/dist/chunk-5MVUYRKG.mjs +5 -0
- package/dist/chunk-5TLLIZT7.mjs +2 -0
- package/dist/chunk-6ILJWFYW.mjs +4 -0
- package/dist/chunk-6N25CJ6Y.mjs +3 -0
- package/dist/{chunk-SQ6Y2ZMA.mjs → chunk-7DTINW6U.mjs} +2 -2
- package/dist/chunk-7KWAGKIK.mjs +2 -0
- package/dist/chunk-7WNUOAFK.mjs +2 -0
- package/dist/chunk-7XCRW5RC.mjs +2 -0
- package/dist/{chunk-BYNPEUDS.mjs → chunk-7XSDTILF.mjs} +1 -1
- package/dist/chunk-ABKYFOVR.mjs +2 -0
- package/dist/chunk-AMUF7PUN.mjs +2 -0
- package/dist/{chunk-FJLM7YE7.mjs → chunk-B2EIMERT.mjs} +2 -2
- package/dist/{chunk-QNECWMGR.mjs → chunk-B45IAAU6.mjs} +1 -1
- package/dist/chunk-B6RAGF4R.mjs +2 -0
- package/dist/chunk-BSJKFE7I.mjs +4 -0
- package/dist/chunk-C72EEVLK.mjs +2 -0
- package/dist/chunk-CRAUKZ23.mjs +4 -0
- package/dist/chunk-F4CT35KL.mjs +2 -0
- package/dist/chunk-F63BNJLG.mjs +2 -0
- package/dist/chunk-FBKUPS44.mjs +2 -0
- package/dist/chunk-FL52ZL5Z.mjs +15 -0
- package/dist/chunk-FOZCU4VW.mjs +2 -0
- package/dist/chunk-G5HV7BC3.mjs +2 -0
- package/dist/{chunk-ERLAIBOA.mjs → chunk-GB5SOYQJ.mjs} +2 -2
- package/dist/chunk-GN3SG3IF.mjs +2 -0
- package/dist/{chunk-6QWQXHAV.mjs → chunk-HFTBVEZK.mjs} +1 -1
- package/dist/chunk-IOW5HLRK.mjs +2 -0
- package/dist/chunk-IQ3GJNTI.mjs +6 -0
- package/dist/chunk-K6SPFBUJ.mjs +2 -0
- package/dist/chunk-K7Y7SPTS.mjs +2 -0
- package/dist/chunk-L2IJCEUH.mjs +2 -0
- package/dist/{chunk-GPIWQ4X4.mjs → chunk-L3VT6LM4.mjs} +1 -1
- package/dist/chunk-L4WLQYFC.mjs +5 -0
- package/dist/{chunk-NLDF35P5.mjs → chunk-LAMCAGK6.mjs} +1 -1
- package/dist/chunk-LHGKPMTI.mjs +2 -0
- package/dist/chunk-LJZIYVNA.mjs +3 -0
- package/dist/chunk-LSVCTLS2.mjs +2 -0
- package/dist/chunk-LZY74XTP.mjs +2 -0
- package/dist/chunk-MC4LRSVH.mjs +2 -0
- package/dist/chunk-MCEXN4G5.mjs +2 -0
- package/dist/chunk-MTLAOCFF.mjs +181 -0
- package/dist/chunk-MZ66LN3B.mjs +2 -0
- package/dist/chunk-N5QWJRRI.mjs +2 -0
- package/dist/chunk-NF4MMOUB.mjs +2 -0
- package/dist/chunk-NHJYAJ73.mjs +3 -0
- package/dist/chunk-NRSD7SVY.mjs +2 -0
- package/dist/chunk-NT23I4XW.mjs +2 -0
- package/dist/chunk-NUALABIS.mjs +3 -0
- package/dist/chunk-NW6LAU22.mjs +2 -0
- package/dist/chunk-NWWHDGKF.mjs +5 -0
- package/dist/chunk-OFRCVMSJ.mjs +2 -0
- package/dist/chunk-OKVQQ3CX.mjs +4 -0
- package/dist/chunk-OM24O4KR.mjs +8 -0
- package/dist/{chunk-4B2TB5K2.mjs → chunk-PBMOC7KA.mjs} +2 -2
- package/dist/chunk-PVTCP43W.mjs +2 -0
- package/dist/chunk-Q62HZAJS.mjs +2 -0
- package/dist/chunk-QBJWIR3Q.mjs +2 -0
- package/dist/chunk-QDSEZX7Z.mjs +6 -0
- package/dist/chunk-QR4V4A2Z.mjs +15 -0
- package/dist/{chunk-QVGOPHOF.mjs → chunk-QRLVVZ3R.mjs} +1 -1
- package/dist/chunk-QW3QG67J.mjs +2 -0
- package/dist/chunk-R2T2EVWY.mjs +8 -0
- package/dist/{chunk-JJNHKGTD.mjs → chunk-R5RERE6G.mjs} +1 -1
- package/dist/chunk-RFHEWT3Y.mjs +5 -0
- package/dist/chunk-RS2Z2JQP.mjs +2 -0
- package/dist/chunk-S6YEC4GE.mjs +16 -0
- package/dist/chunk-SHZLMGGW.mjs +2 -0
- package/dist/chunk-TALJQM2O.mjs +2 -0
- package/dist/chunk-TLNJWEFY.mjs +22 -0
- package/dist/{chunk-ZLS2FRS6.mjs → chunk-TQZU7D7C.mjs} +1 -1
- package/dist/chunk-UTKNWYBA.mjs +2 -0
- package/dist/chunk-V3TM3TEN.mjs +2 -0
- package/dist/chunk-V3XROSP5.mjs +7 -0
- package/dist/{chunk-6QBHU4DF.mjs → chunk-V5JTW2LH.mjs} +1 -1
- package/dist/chunk-VAXLSISW.mjs +4 -0
- package/dist/chunk-VBHI3RG6.mjs +2 -0
- package/dist/{chunk-CRDG6EF2.mjs → chunk-VKZJRGDR.mjs} +1 -1
- package/dist/chunk-VZXZM7NS.mjs +2 -0
- package/dist/chunk-WDS6HEPE.mjs +2 -0
- package/dist/chunk-WHGANNEY.mjs +13 -0
- package/dist/chunk-WMJWC4QY.mjs +56 -0
- package/dist/{chunk-UTMAY3WK.mjs → chunk-WWONJJQS.mjs} +1 -1
- package/dist/chunk-X4WNLFIK.mjs +2 -0
- package/dist/chunk-XNNCQROX.mjs +11 -0
- package/dist/chunk-XRYECF23.mjs +170 -0
- package/dist/{chunk-225ALKYI.mjs → chunk-Z4NEXXFK.mjs} +1 -1
- package/dist/{chunk-PKVK6WFC.mjs → chunk-ZFVF2YPV.mjs} +2 -2
- package/dist/chunk-ZM2IX3R2.mjs +2 -0
- package/dist/chunk-ZNGGDUZI.mjs +2 -0
- package/dist/chunk-ZOEJQOKT.mjs +2 -0
- package/dist/cli.mjs +1 -1
- package/dist/server.mjs +1 -1
- package/dist/update-fetch.mjs +1 -1
- package/dist/worker.mjs +1 -1
- package/package.json +1 -1
- package/release.json +3 -3
- package/skill/SKILL.md +54 -148
- package/skill/references/building-blocks.md +4 -4
- package/skill/references/charts-and-figures.md +73 -0
- package/skill/references/extensions.md +47 -4
- package/skill/references/pages-and-data.md +22 -3
- package/skill/references/preference-files.md +7 -0
- package/skill/references/previews.md +17 -0
- package/skill/references/writing-html.md +21 -82
- package/web/assets/index-B4uUluLM.js +15 -0
- package/web/assets/index-C3vHT8sH.css +1 -0
- package/web/index.html +2 -2
- package/dist/chunk-2HS7ZBPU.mjs +0 -2
- package/dist/chunk-3F57LEN5.mjs +0 -2
- package/dist/chunk-4OZWXZE5.mjs +0 -5
- package/dist/chunk-5GK7HS62.mjs +0 -2
- package/dist/chunk-6GV3CBB2.mjs +0 -2
- package/dist/chunk-6NLXUKAY.mjs +0 -4
- package/dist/chunk-6XD6U3QA.mjs +0 -5
- package/dist/chunk-6Y3HYOBM.mjs +0 -2
- package/dist/chunk-7EFHNQ5B.mjs +0 -3
- package/dist/chunk-7M2BQQGZ.mjs +0 -2
- package/dist/chunk-7UZUQQ7Q.mjs +0 -554
- package/dist/chunk-ALZ6ZENZ.mjs +0 -3
- package/dist/chunk-BX5AKINW.mjs +0 -15
- package/dist/chunk-DR73Y2UJ.mjs +0 -3
- package/dist/chunk-EURLTOTZ.mjs +0 -4
- package/dist/chunk-F4ZA6JRZ.mjs +0 -3
- package/dist/chunk-FNCCVGKX.mjs +0 -2
- package/dist/chunk-FOJ3K5Z3.mjs +0 -6
- package/dist/chunk-FQ72LZHB.mjs +0 -2
- package/dist/chunk-G7N7YFVD.mjs +0 -2
- package/dist/chunk-GIRXJBGC.mjs +0 -2
- package/dist/chunk-GKOBB6DH.mjs +0 -2
- package/dist/chunk-GMJD7ID3.mjs +0 -2
- package/dist/chunk-GQJMVSSN.mjs +0 -2
- package/dist/chunk-HX4DLE3J.mjs +0 -10
- package/dist/chunk-IS7N3N6Q.mjs +0 -168
- package/dist/chunk-JEUK3ZO7.mjs +0 -2
- package/dist/chunk-JPG2LBQM.mjs +0 -11
- package/dist/chunk-JYK5WJPM.mjs +0 -2
- package/dist/chunk-KLQP46Y3.mjs +0 -4
- package/dist/chunk-L55NOXBE.mjs +0 -4
- package/dist/chunk-LCB6MARS.mjs +0 -5
- package/dist/chunk-LJLVCU6W.mjs +0 -16
- package/dist/chunk-LMUZQK5O.mjs +0 -2
- package/dist/chunk-NMF3IPYA.mjs +0 -13
- package/dist/chunk-ONKC4BCC.mjs +0 -2
- package/dist/chunk-OU6ZZVBX.mjs +0 -5
- package/dist/chunk-PUOQ65NC.mjs +0 -2
- package/dist/chunk-QJAVCTY7.mjs +0 -2
- package/dist/chunk-QP7BOHE4.mjs +0 -2
- package/dist/chunk-S3SX3COT.mjs +0 -20
- package/dist/chunk-SQ3FQCCN.mjs +0 -8
- package/dist/chunk-T4Y2ZSVX.mjs +0 -4
- package/dist/chunk-TANZRINB.mjs +0 -2
- package/dist/chunk-UGWMMEJ5.mjs +0 -15
- package/dist/chunk-UTF7GBQU.mjs +0 -4
- package/dist/chunk-V4ZHRALW.mjs +0 -170
- package/dist/chunk-XBNFXWAW.mjs +0 -6
- package/dist/chunk-XZV72SQ4.mjs +0 -2
- package/dist/chunk-YFJB534W.mjs +0 -2
- package/dist/chunk-Z6OKLRHC.mjs +0 -2
- package/dist/chunk-ZMHUDYLV.mjs +0 -2
- package/web/assets/index-D8P8uhDW.js +0 -15
- package/web/assets/index-FLb9jCfl.css +0 -1
- /package/dist/{chunk-PAREWQGB.mjs → chunk-NOGQX56R.mjs} +0 -0
package/skill/SKILL.md
CHANGED
|
@@ -5,180 +5,86 @@ description: "Gallery: turn supplied materials into a polished, interactive HTML
|
|
|
5
5
|
|
|
6
6
|
# Gallery
|
|
7
7
|
|
|
8
|
-
Create
|
|
8
|
+
Create an HTML document whose claims, numbers and visual encodings trace back to the supplied materials. You write ordinary HTML; the `gallery` command turns it into the kit's blocks, checks it and exports one offline file, while the user watches and edits it in the browser.
|
|
9
9
|
|
|
10
10
|
## Before anything: the gallery command
|
|
11
11
|
|
|
12
|
-
This skill holds the instructions; the tools are the npm package `@heycys/gallery`, the `gallery` command. This skill is Gallery 0.2.
|
|
12
|
+
This skill holds the instructions; the tools are the npm package `@heycys/gallery`, the `gallery` command. This skill is Gallery 0.2.4's and needs `@heycys/gallery` ^0.2.4: 0.2.4 or a later 0.2.x.
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
- No Node, or `node --version` older than 22.13: tell the user to install the current LTS from https://nodejs.org (or with their system's package manager), then start again.
|
|
20
|
-
- npm says `EACCES` (macOS and Linux, where npm's global folder belongs to the system): never use `sudo`. Tell the user, and offer either of these: give npm a folder of their own (`npm config set prefix ~/.npm-global`, add `~/.npm-global/bin` to `PATH` in their shell profile, open a new terminal, install again); or run every command as `npx -y @heycys/gallery@^0.2.3 <command> …` instead of `gallery <command> …`.
|
|
21
|
-
- Use `npx -y @heycys/gallery@^0.2.3 <command> …` likewise wherever a global install is not allowed (a sandbox, CI). It is slower: a few seconds more per command.
|
|
22
|
-
- On Windows, `gallery` works in PowerShell right after the install, in the same terminal. Only when PowerShell says running scripts is disabled (`gallery.ps1`): run `gallery.cmd` with the same arguments, or ask the user to run `Set-ExecutionPolicy -Scope CurrentUser RemoteSigned` once.
|
|
23
|
-
- After an upgrade, run `gallery open --no-browser` once: the server of the version before stops by itself, and this starts the new one. Tell the user that `gallery skill install` brings this skill to the new version too (an Agent session started after it reads it).
|
|
24
|
-
3. The documents live in a workspace, a folder: `--workspace <dir>` (every command takes it), else `GALLERY_WORKSPACE`, else the nearest folder up from the current one holding `gallery.json`, else `Gallery` in the user's Documents folder, `~/Documents/Gallery` (made on first use; on Windows the Documents folder Explorer shows, OneDrive's when OneDrive backs it up). `gallery new`, `gallery import`, `gallery list` and `gallery open` print it as `工作区:<path>`. When a command prints `Cannot write the workspace <path> (…)` (a sandbox that allows writes only in the project, or a system that has not let the terminal into Documents), ask the user to allow Gallery to write there, or pass `--workspace <a folder in the project>` to every command.
|
|
25
|
-
- Gallery remembers every workspace used on this machine: `gallery workspaces` lists them, and `gallery list <words> --all` searches the documents of them all. When a document the user names is not in the current workspace, search with `--all` first, then pass the `工作区:` line printed before it as `--workspace`.
|
|
26
|
-
- Do not make a workspace of your own for a task unless the user asks for one; when you make one, give it the project's name: `gallery init <dir> --name "<project name>"`.
|
|
27
|
-
4. The browser service: `gallery new` and `gallery import` start the workspace's local server (or use the one running) and open the user's browser at the document, `gallery open [<slug>]` starts or reuses it and opens the user's browser (each takes `--no-browser`: the address without a tab), and each prints the address on its `交给用户` line: give it to the user all the same (the browser opened may not be Chrome or Edge, or not in front of them). Editing in the browser and `gallery qa` need Chrome or Edge. In a cloud sandbox the user cannot reach (`127.0.0.1` there is not their computer), skip the address: hand over the exported file instead. `gallery stop` stops the server (`Stopped the server on port …`, or `No Gallery server runs for <workspace>.`).
|
|
28
|
-
5. Every command but `gallery serve` returns by itself, the server's included (it runs on after the command; `gallery serve` runs it in the foreground, for the user's own terminal: you start it with `gallery open --no-browser`): run each in the foreground, with no `timeout` wrapper, background job or `Start-Process`. When you ask the user to allow commands, `gallery *` covers them all (`gallery.cmd *` in PowerShell). In Windows PowerShell 5.1, give a command no `2>&1` (it makes its warnings errors) and read files with the file tool or `Get-Content -Encoding UTF8`. Resolve `references/` and `sdk/` from the folder holding this `SKILL.md`.
|
|
14
|
+
- Run `gallery --version`. When `gallery` is missing or older than `^0.2.4` takes, ask the user (no need when they already said to install), then `npm i -g @heycys/gallery@^0.2.4`; if that cannot be done, `npx -y @heycys/gallery@^0.2.4 doctor` says what to do, and the same prefix runs any command. A version newer than `^0.2.4` takes means this skill is the older one: install nothing.
|
|
15
|
+
- A command printing `需要处理:…`, or `gallery --version` printing `技能:…` (this skill is older than the gallery) or `新版本:…` (npm has a newer one): run `gallery doctor` and do what its last `下一步:` line says. None stops the task: tell the user once, and update nothing without their yes unless they already said to.
|
|
16
|
+
- Workspace: `--workspace <dir>`, else `GALLERY_WORKSPACE`, else the nearest folder up holding `gallery.json`, else `~/Documents/Gallery`. `gallery workspaces` lists those this machine has used; `gallery list <words> --all` searches them all. Make a workspace only when asked.
|
|
17
|
+
- Commands return by themselves (the server runs on): run each in the foreground, with no `timeout`, background job or `Start-Process`. Ask the user to allow `gallery *` (`gallery.cmd *` in PowerShell); in PowerShell 5.1 give no `2>&1`. Resolve `references/` and `sdk/` from this file's folder.
|
|
18
|
+
- Users edit at the `交给用户(…):` address in Chrome or Edge (`gallery qa` needs one too). In a cloud sandbox they cannot reach, skip addresses and hand over the export.
|
|
29
19
|
|
|
30
|
-
**写作偏好** (
|
|
20
|
+
**写作偏好** (the user's writing rules): before writing or revising, run `gallery preferences list` and read the enabled files that bear on the task, by title and scope. Priority: the user's request, the preferences in listed order, this skill. Change preference files, their order or on/off state only when asked ([references/preference-files.md](references/preference-files.md)). A custom page has none.
|
|
31
21
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
A document is the folder `<workspace>/<slug>/`: `doc.html`, the page you write, and `doc.json`, its title and description (and the reader's 字体与布局 as `look`, which you keep when you rewrite it, as you keep the workspace's default `look` in `gallery.json`: writing-html.md). Documents link to each other by ordinary relative links between these files (`../<slug>/doc.html`: writing-html.md). A document made before Gallery 0.1 has `report.html` and `report.json` instead: write those (Gallery reads and writes them under their names; never rename them). Below, `doc.html` and `doc.json` stand for either.
|
|
22
|
+
One Agent writes a document at a time; the user's browser edits merge with yours. A document is the folder `<workspace>/<slug>/`: `doc.html`, the page you write, and `doc.json`, its title, description and look (change them with `gallery set`). A document made before Gallery 0.1 has `report.html` and `report.json`: write those under their names. Below, `doc.html` and `doc.json` stand for either.
|
|
35
23
|
|
|
36
24
|
## Workflow
|
|
37
25
|
|
|
38
|
-
1. Read
|
|
39
|
-
2. Create
|
|
40
|
-
|
|
41
|
-
-
|
|
42
|
-
-
|
|
43
|
-
-
|
|
44
|
-
|
|
45
|
-
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
- Read [references/example-report.html](references/example-report.html) first: a catalogue of every block once, each written the way the tools read it, its words saying what the block is; take the blocks you need. Then read [references/writing-html.md](references/writing-html.md), whole.
|
|
49
|
-
- Write so that the user watches the document grow: as soon as you can outline it, replace the starter section with its skeleton (the opening summary's place and each section's heading), then write it a section at a time, one edit each. The page shows each save; one write of the whole document at the end leaves the user looking at the starter page until then.
|
|
50
|
-
- Materials can be large: list a folder before you read in it, and read what the document needs; no `du` or glob over a whole disk or tree.
|
|
51
|
-
- Take numbers and conclusions from the materials themselves: a summary of them, a subagent's too, is a lead to check, not a source.
|
|
52
|
-
- A task board, a number or a chart over a table of the user's (a board of tasks by status, a data dashboard) is Gallery's own views of a table, never a block of your own: an ordinary table carrying `data-doc-chart-source="<key>"`, then an instance of `gallery/kanban`, `gallery/metric` or `gallery/chart-view` with the same `data-doc-from="<key>"`, its settings one line of JSON. `gallery block add <name>` puts the block in, and `gallery block show gallery/<name>` (or `show kanban`) prints how to write it ([references/pages-and-data.md](references/pages-and-data.md#a-view-of-a-table)). Run `gallery block add <name>` before you write the instance, not after: an instance of a block that is not in the workspace stays read-only (`gallery export` notes it). Write the table first and the views below it, as each block's writing.md does (above it works, and `gallery check` notes it). These views read a table of their own document; a custom page's card that reads another document's table (`workspace.query("table")`) is a block of your own ([Custom pages](#custom-pages-自定义页), step 4).
|
|
53
|
-
- The document's data stays in `doc.html`. Its pictures and files go right in `<workspace>/<slug>/assets/` (writing-html.md's [Pictures](references/writing-html.md#pictures) says how to name and size them). Raw inputs that should travel with it go in `<workspace>/<slug>/materials/`.
|
|
54
|
-
5. Export, check and look:
|
|
55
|
-
- `gallery export <slug>` makes the plain HTML of `doc.html` the kit's markup, gives every block its `data-block-id`, checks the document and writes the deliverable `<workspace>/exports/<slug>.html` ([what its lines mean](#what-the-commands-print)).
|
|
56
|
-
- `gallery qa <slug>` exports first when needed, opens the export in Chrome or Edge at 1024, 736 and 360px (every disclosure, Sheet panel and detail card in turn), prints each failure and warning with its place in the document's file (`doc.html:<line>`, `report.html:<line>` in an older document), and pictures what it flags and, in a plain run, up to 12 blocks (what you changed first, then the cards; a `--blocks` run pictures every block it names) in the folder its `Pictures of this run in <path>` line names (a run with nothing to picture, no block changed and no card, says so in its verdict and names the `--tiles` run to make instead). Read its whole output (the verdict comes last, then the deliverable's line) and look at the pictures: `changed/` holds what you changed or moved; `cards/` the cards no look has pictured yet, your own drawings, charts and custom blocks first, tables last (not your edits); `blocks/` and `tiles/` what you ask for with `gallery qa <slug> --blocks a,b` or `--tiles` (the whole page, each panel and card). A picture shows all an element draws: a mark cut at its edge is cut on the page too.
|
|
57
|
-
- Open at least every picture of `flagged/` and of `changed/`, at each width, then those of `cards/` that show what you drew yourself (your charts, drawings and flowcharts); open the rest as the document needs. Its `Not opened yet: …` line, right before the verdict, lists every picture of the run in one place, none opened for you: count by it. In the handoff name the pictures you opened: a width or a block whose pictures you did not open is not one you looked at.
|
|
58
|
-
- Each run empties only its own folders before it pictures: `flagged/` every run; `changed/` and `cards/` a plain run; `blocks/` a `--blocks` run; `tiles/` a `--tiles` run. Open a run's pictures before you run the same kind again.
|
|
59
|
-
- After your last edit, run a plain `gallery qa <slug>`; then, when a line of it says `not pictured` and gives a `gallery qa <slug> --blocks …` command (blocks past a run's twelve, at a list's end; or blocks a tall moved block holds that none of its pictures showed at a width, `N of them not pictured at 360px: …`), run that command too, not instead of it. A `--blocks` run pictures the blocks named alone: its `Not pictured by this run …` line, before the verdict, names the changed blocks and the cards it left, which a plain run pictures.
|
|
60
|
-
- In the pictures, fix what reads badly though nothing flagged it, such as a single character alone on a line (a heading's or a label's last character wrapped), a line or a mark drawn through text, or one cell or metric left alone on a row of a grid.
|
|
61
|
-
- To fix what either finds, re-read what the `Re-read` line names, change `doc.html` (never a generated file) and run `gallery qa` again until nothing fails.
|
|
62
|
-
- Exit 3 is one of two things. `UNVERIFIED <why>: nothing was looked at`: there is no Chrome or Edge, or the one installed did not start (qa tries it twice, with a fresh profile each time). When a browser is installed, run `gallery qa` once more; if it says `UNVERIFIED` again, or there is none, look at the export at those widths yourself, its disclosures and detail cards opened (the page does not scroll sideways, only tables and formula blocks do; no label of a chart or a drawing is clipped, overlaps another or reads under 11px; leave the controls at its top right alone unless the user asks), and say so in the handoff. Or a verdict `nothing failed …; not verified at N places`, with an `UNVERIFIED` line for each place (a wait that ran out, a detail card that did not open, a Sheet panel that stayed hidden, a picture not taken): the rest was looked at; run `gallery qa` once more, then look yourself only at the places those lines name, and say so in the handoff.
|
|
63
|
-
- `gallery check <slug>` runs the checks alone and changes nothing.
|
|
26
|
+
1. **Read the rules:** `gallery preferences list`, then the enabled files that bear on this document.
|
|
27
|
+
2. **Create it, send the address.** `gallery new <slug> "<title>" "<description>"` (a lowercase kebab-case slug), or `gallery import <file> [<slug> ["<title>"]]` for a file to turn into the document (Markdown, HTML, Word, PDF, …). It starts the server and ends with a `交给用户(…):` line: send that address to the user at once, in a message of its own, before you read further. Follow its `下一步:`; place the document in the tree as [Organizing documents](#organizing-documents) says.
|
|
28
|
+
3. **Write `doc.html`.** Read [references/writing-html.md](references/writing-html.md), whole. For one block's markup, search [references/example-report.html](references/example-report.html) for its class (it shows every block once; do not read it through). Before a chart or a diagram, read [references/charts-and-figures.md](references/charts-and-figures.md).
|
|
29
|
+
- Let the user watch it grow: replace the starter section with the skeleton (each section's heading) as soon as you can outline it, then write one section per edit; one write at the end leaves them on the starter page.
|
|
30
|
+
- Take numbers and conclusions from the materials; a summary of them, a subagent's too, is a lead to check, not a source. List a folder before you read in it; raw inputs that travel with the document go in `<slug>/materials/`.
|
|
31
|
+
- A task board, a number or a chart over a user's table is Gallery's own view of a table: an ordinary table with `data-doc-chart-source="<key>"`, then an instance of `gallery/kanban`, `gallery/metric` or `gallery/chart-view` with `data-doc-from="<key>"`. Run `gallery block add <name>` before you write the instance; `gallery block show <name>` prints how ([references/pages-and-data.md](references/pages-and-data.md#a-view-of-a-table)).
|
|
32
|
+
4. **Export, check and look.** `gallery export <slug>` writes the kit's markup and every block's `data-block-id` into the page, checks it, and writes the deliverable `<workspace>/exports/<slug>.html` (`--format pdf|markdown` for the others: `gallery help export`); `gallery check <slug>` runs the checks alone.
|
|
33
|
+
- Run `gallery qa <slug>`, open the pictures its `要看的图(N 张):` list numbers (`不用看:` names the rest), fix each `FAIL` (re-read the files a `重读:` line names first), and run it again until nothing fails. Fix what reads badly though nothing flagged it: a single character alone on a line, a line or mark through text, one cell left alone on a row of a grid.
|
|
34
|
+
- `UNVERIFIED` (exit 3 nothing looked at, 4 some places not verified): run qa once more; if it stays, look yourself at the export, or the places its lines name, at 1024, 736 and 360px, disclosures and detail cards opened, and say so in the handoff.
|
|
35
|
+
5. **Hand over** ([Handoff](#handoff)).
|
|
64
36
|
|
|
65
37
|
## What the commands print
|
|
66
38
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
| Line | Means |
|
|
70
|
-
| --- | --- |
|
|
71
|
-
| `技能:<folder> 是 Gallery <version> 的,比这个 gallery … 旧;…` | `gallery --version`'s, after the version: that Gallery skill (this one, maybe) is older than the gallery: offer the user the command it gives (the first section) |
|
|
72
|
-
| `新版本:npm 上有 Gallery <version>…` | `gallery --version`'s: npm has a newer Gallery: offer the update, once in the conversation (the first section) |
|
|
73
|
-
| `工作区:<path>` | the workspace the command worked in (`gallery new`, `gallery import`, `gallery list`, `gallery open`, `gallery init`); `gallery list --all` prints it before each document it finds in another workspace: pass it as `--workspace` to work on that document |
|
|
74
|
-
| `工作区名字:没有(…);…gallery workspaces --name "<项目名>"…` | `gallery new` and `gallery init` in a workspace with no name of its own: when you made it for a project, name it after the project with that command; a workspace that is the user's own, leave as it is |
|
|
75
|
-
| `gallery workspaces`: `路径:`, `文档:`, `服务:`, `不在了` | the workspaces this machine has used, each with its path, its document count and last edit, and its server's address while one runs; `不在了` a folder that is gone (it stays registered; nothing to do) |
|
|
76
|
-
| `写作偏好:…(<path>)`, `Made now: …` | where 写作偏好 is (`gallery new`, `gallery import`, `gallery list`): read it before you write (`空`: the user emptied it); `gallery list` makes the file when there is none, and says so on a `Made now:` line of its own: it is the user's, never yours to change |
|
|
77
|
-
| `交给用户(…):<address>` | the address where the user watches and edits the document: send it to them now, in a message of its own (`gallery new`, `gallery import`, `gallery open`), and again in the handoff |
|
|
78
|
-
| `Agent 自用(…):<address>` | the document's page alone, editable, with no frame: yours (to try a custom block in), not for the user |
|
|
79
|
-
| `Wrote: …`, `Undone: …`, `Kept (--keep): …`, `Read back: …`, `Not opened yet: …` | `gallery block try`'s, made on a scratch copy of the document (`doc.html` not written; `--keep` makes it on `doc.html` and leaves the write): what each gesture or step wrote, each part of the instance with the lines it took out and put in, those lines under it (`-`, `+`: read them), that a Ctrl+Z for each write gave the copy back, and that a fresh page of what it wrote shows what it wrote as the page did (what the page showed and never wrote, a filter or an editor left open, is a `note`: not to be written); `Picture of the instance after …` names a picture to open, which no one has looked at for you, and the `Not opened yet: …` line after it lists it (`gallery block check` ends with one too, for its pictures); a `note` line asks what the check's do. In the handoff name each gesture tried and what it wrote |
|
|
80
|
-
| `gallery page try`'s lines and exit code | as `gallery block try`'s, of one card of the page (`page.html` not written; `--keep` writes it): `Wrote:` names that card's data parts, and `nothing else in page.html changed`; a write anywhere else (another card, the card's place) is a `FAIL`. The exit codes are `gallery block try`'s (below) |
|
|
81
|
-
| `gallery page check`: `FAIL page.html:<line>: …`, `note page.html:<line>: card <id> (<block>): the workspace had not answered its read of …`, `Changes since …`, `Not opened yet: …` | each problem at its line (exit 1: fix each, then check again); what changed since the last check that found nothing (cards added, removed, moved, resized, their data with the lines): only the cards you meant; the pictures to open. A `note` (no failure) says a card was pictured before the workspace answered its read, and the `OK` line then ends `; but N cards were pictured before the workspace answered it (see "note" above), so their pictures do not show what they read`: such a picture says nothing of what the card shows, so open the page in Gallery or run the check again (your own card that reads `context.workspace` is covered too). Another `note` says a card holds no value for a setting its block cannot show anything without (`weather`'s city, `countdown`'s date: `note page.html:<line>: card <id> (<block>) holds no city …`), and the `OK` line ends `; and one card asks for a setting no one gave (see "note" above): c8 (city)`: its picture is the card's ask for it, so ask the user or take it from the workspace and write it ([Custom pages](#custom-pages-自定义页), step 4). A `FAIL` that says the browser did not answer within N s is a look that stopped (the looks after it were not made): a script of the page that never ends does this; run the check once more, and when it stops at the same place, the page holds it up. `OK <slug>` exit 0; `UNVERIFIED` exit 3, the page not looked at in a browser (its structure checked): run it once more |
|
|
82
|
-
| `gallery block try`'s exit code | 0 it wrote, the Ctrl+Z took it back and a fresh page read it back · 1 a problem of the block's (gestures that wrote nothing, said with what came of the last; an undo that left part of a write; a fresh page that shows the block otherwise in what was written, or writes as it opens): fix it, check it, try again · 2 a mistake in the command (a selector that finds nothing: the line lists the classes the instance shows; an option a `<select>` has not; a steps file that does not read; one at a later step is said after what the steps before it wrote, which `--keep` leaves in `doc.html`) · 3 `UNVERIFIED`, the trial not seen through (no browser or server, a page that loaded itself again), its line saying why, `doc.html` holding nothing of it: run it once more |
|
|
83
|
-
| `This workspace's Gallery server runs on port …` | the server started or reused: nothing to wait for or keep running |
|
|
84
|
-
| `Preview: not started …` | no server, so no `交给用户` address: run `gallery open <slug> --no-browser` and give the user the address it prints (not in a cloud sandbox they cannot reach) |
|
|
85
|
-
| `Next: …`, `Hand in: …` | the steps after `gallery new` or `gallery import`: follow them |
|
|
86
|
-
| `Placed it …`, `Moved …`, `位置:…` | where `gallery new --under`/`--after` or `gallery move` put the document in the sidebar's tree, and where a document is (`gallery list`): say it in the handoff |
|
|
87
|
-
| `Set <slug>:` and its lines | what `gallery set` changed; re-read the files its `Re-read` line names before you edit them |
|
|
88
|
-
| `Cannot write the workspace <path> (…)` | ask the user to allow it, or pass `--workspace <a folder you may write>` |
|
|
89
|
-
| `FAIL <slug>: N problems` | the checks failed, nothing exported (exit 1): fix each |
|
|
90
|
-
| `OK <slug>`, `Checked N documents: …` | `gallery check`'s tally: those passed |
|
|
91
|
-
| `fix …` | act on it (a path of this machine, a heavy picture) |
|
|
92
|
-
| `note …` | advice, never a failure |
|
|
93
|
-
| `note … kept by the script: .x` | your script selects that block by these names, so the user cannot delete or convert it: rename a class or id the script does not select it by |
|
|
94
|
-
| `icon … the page's header none` | `gallery set <slug> --icon <that icon>` writes it in the header too, `--icon none` takes it out of both |
|
|
95
|
-
| `Re-read <files> …` | the tools wrote these: re-read exactly them before editing |
|
|
96
|
-
| `preview …`, `annotations …` | said once: which of your plain HTML the browser page made the kit's markup (never the user's edits); 批注 Gallery's server deleted, their words gone from the blocks they are on (`gallery export`, `gallery check` and `gallery qa` say it right after the write) |
|
|
97
|
-
| `交给用户(离线文件):<path>` | the deliverable (the export's last line; qa's last lines, after its verdict) |
|
|
98
|
-
| `natural <file>: … rewritten in this file as the kit's markup` | the export rewrote those elements of `doc.html`, by line, into the kit's markup (a `<pre>` became `div.doc-code`, its `language-x` moved to `data-language`): nothing to fix, but the file is not what you wrote: re-read it, as the `Re-read` line names it, before you edit it (from `gallery check`: `not rewritten yet`, the export will). The line goes on to say what each became (a table's `<caption>` a note line above it, its header cells highlighted) and that the words and numbers are unchanged. The indented lines under it say, by line, what the conversion did with an element (`line 12, code: tabindex kept on its <pre>`): nothing to fix, unless a line says what to write |
|
|
99
|
-
| `Exported <path> …` and other `title`, `icon`, `ids` lines | what the export did (or, from `gallery check`, will do): nothing to do |
|
|
100
|
-
| `chart …` | how a chart drawn from a table reads it (its rows, each column numbers or words): nothing to do |
|
|
101
|
-
| qa `FAIL` · `WARN` · `INFO` | fix it · look at its picture and fix what reads badly, never cutting words or columns · nothing to do |
|
|
102
|
-
| qa `UNVERIFIED <why>: nothing was looked at` · an `UNVERIFIED` line among the findings | nothing looked at: run qa once more, then look at the export yourself and say so · that place alone not looked at (the rest was): run qa once more, then look yourself at that place and say so |
|
|
103
|
-
| `Not pictured by this run …` | a `--blocks` run's: blocks changed and cards it did not picture (with `no earlier look`, every card outside those named); the plain `gallery qa <slug>` it names pictures them |
|
|
104
|
-
| `gallery qa`'s exit code | 0 nothing failed (warnings may remain) · 1 a failure, or the export it ran first failed · 2 an export missing or stale with `--no-export`, or `--blocks` naming an id the document has not (nothing looked at, no picture removed: name ids as qa printed them) · 3 something not verified: nothing at all (`UNVERIFIED <why>`: no Chrome or Edge, or one that did not start), or the places its `UNVERIFIED` lines name |
|
|
105
|
-
| qa's lines per width (`1024px fail 0 · …`) | what that look found; `1024×768` is the 1024px page in a shorter window |
|
|
106
|
-
|
|
107
|
-
## Revising a document
|
|
108
|
-
|
|
109
|
-
When the user names a document by its title or topic, find it with `gallery list <words>` (words of its title or topic; those whose title, description or slug holds them come first, then those whose text does, with `正文:` and the first place; `gallery list` alone lists every document, the one edited last first): it prints each document's slug, title, description, place in the tree, address, last edit and file. A search of the `doc.html` files themselves (grep) is fine too. An address the user gives (`http://127.0.0.1:<port>/#<title words>-<page id>`, the workbench's address bar or 复制块链接, `/<block id>` after it for a block) names its document by the id at its end, and the words before it may be out of date: `gallery list <address>` prints that document, or says it is in the trash, and every command that takes a slug takes the address, or the link after its `#`, as well. The id comes from the folder's name, so an address from another workspace can name this workspace's folder of that name: before you change anything, compare the title `gallery list <address>` prints, and its `工作区:` line, with what the user means. A path the user gives (the workbench's 复制本地路径 copies one) is that document's `doc.html`; its folder's name is its slug, the folder holding it the workspace (pass it as `--workspace` when it is not the one the commands find).
|
|
110
|
-
|
|
111
|
-
Before you change anything, run `gallery open <slug> --no-browser` and give the user the address on its `交给用户` line, even when they say the page is open: it reuses the running server without opening another tab, and it keeps the document as it stands so that the first `gallery qa` pictures what you change. It prints no `写作偏好` line: read `<home>/preferences.md` before you change anything.
|
|
39
|
+
A line that asks something of you starts with a fixed word, in Chinese whatever the user's language:
|
|
112
40
|
|
|
113
|
-
|
|
41
|
+
- `交给用户:` or `交给用户(…):` an address or file for the user: copy it whole into your message.
|
|
42
|
+
- `下一步:` do it. `重读:` the tools wrote these files: re-read exactly them before you edit them.
|
|
43
|
+
- `问题:` fails: fix each, run the command again (checks mark each `FAIL`, a pass `OK`). `提示:` advice, not a failure.
|
|
44
|
+
- `需要处理:` something outside the document (Node, the skill, the workspace, the browser): `gallery doctor`.
|
|
45
|
+
- Exit codes: 0 done, 1 something to fix, 2 a mistake in the command, 3 (and qa's 4) `UNVERIFIED`: not looked at, or in part.
|
|
46
|
+
- The lists (`list`, `workspaces`, `page list`, `block list`, `trash list`, `notes`, `history`, `status`) take `--json`, whose fields are only ever added to. `gallery help <command> [<subcommand>]` gives a command's options: look one up instead of guessing.
|
|
114
47
|
|
|
115
|
-
|
|
48
|
+
## Revising a document
|
|
116
49
|
|
|
117
|
-
- `
|
|
118
|
-
-
|
|
119
|
-
-
|
|
120
|
-
-
|
|
121
|
-
-
|
|
122
|
-
-
|
|
123
|
-
-
|
|
124
|
-
-
|
|
125
|
-
-
|
|
126
|
-
-
|
|
50
|
+
- **Find it:** `gallery list <words>` prints each document's slug, title, place, address, last edit and file. An address the user gives names its document by the id at its end (every command that takes a slug takes it); one from another workspace can name this workspace's folder of that name, so compare the title and `工作区:` with what they mean. A path they give (复制本地路径) is that document's `doc.html`; its folder's name is the slug.
|
|
51
|
+
- **"This document", "here", "this paragraph":** `gallery status` first: the document open in their browser, the block they selected, each document's save state (a conflict or unsaved changes come as a `问题:` line): ask the user to settle them before you change the file.
|
|
52
|
+
- **Before you change anything,** read the applicable preferences and give the user the address (`gallery list <slug>` ends with its `交给用户(…):` line, or how to start the server). Gallery keeps the version before your change by itself: it is what 「Agent 的修改」 marks and `gallery revert` takes back.
|
|
53
|
+
- **Edit small.** Map a long `doc.html` by a search of its headings and ids (`<h2`, `<h3`, `data-block-id`, with line numbers) and read the part you change. Right before each change re-read that part and replace only it. A script may replace exact spans, each found once, in one write, stopping when a span is missing or repeated; write it for Node (`python` may be a stub). Write each file with the file tool, one per call (several heredocs in one Git Bash command fail). A change of several edits: make them one right after another.
|
|
54
|
+
- **Keep what is the user's:** the start tag of each block you change (`data-block-id`, `style`, classes may be their edits). A moved block, or one wrapped in a new container, keeps its id (cut and paste the element as it is); an id stays on its own element, not moved from an item or a container onto a paragraph in it; an added or copied block has none, and a deleted id is not reused; a split keeps the id on the first part, a merge the first block's; when unsure, drop it. `gallery check` reports a repeated or misplaced id.
|
|
55
|
+
- **A block made another** (a table made Sheet tabs, a list a flowchart) carries every fact of the old one: numbers, units, scope line, colors. Say what could not go.
|
|
56
|
+
- **After an export or the user's first edit** the file holds the kit's markup: re-read it. The export's `natural …` lines say which of their elements it rewrote (words and numbers stay): tell them.
|
|
57
|
+
- **Beyond the request:** you may change what the revision needs (a term defined where it now first appears) and name it in the handoff. A change that touches data: recheck the summary, charts, units and denominators using it.
|
|
58
|
+
- **批注 (annotations):** `gallery notes <slug>` lists them, each `text` a suggestion on the `quote` it is anchored to. Work through them when the user asks: carry out each `text` where it is anchored, leave one that does not fit its words and ask in the handoff; where one conflicts with the request, the request wins: name it. `gallery notes done <slug> <id>…` marks those carried out; `gallery notes remove` only when the user asks (not `annotations.json` by hand). Gallery deletes an annotation whose words are gone, so keep the words in the blocks it is on. Say which you carried out, left, and which went with their words.
|
|
59
|
+
- **Undo** when the user asks: `gallery revert <slug>` takes back your changes since they last confirmed, keeping theirs (exit 1: nothing to take back); it prints the version it saved first, which `gallery history <slug>`'s `--restore` brings back. `gallery history` lists earlier versions.
|
|
127
60
|
|
|
128
61
|
## Organizing documents
|
|
129
62
|
|
|
130
|
-
|
|
63
|
+
`gallery list --tree` prints the sidebar's tree; a document is named by its slug, link or address.
|
|
131
64
|
|
|
132
|
-
-
|
|
133
|
-
- Move
|
|
134
|
-
-
|
|
135
|
-
-
|
|
136
|
-
-
|
|
137
|
-
-
|
|
138
|
-
|
|
139
|
-
## Custom pages (自定义页)
|
|
140
|
-
|
|
141
|
-
A page has no 写作偏好: do not read it for rules, and Workflow step 1 is for documents (a `gallery list` that made it in passing changes nothing of that). A card made for "me" (my tasks) needs who that is: a setting of the card, never written into a block's code, asked or taken as step 4 says (写作偏好 may name them: read it for that alone, none of its rules is a page's).
|
|
142
|
-
|
|
143
|
-
A custom page is the user's own page in the workbench's sidebar, yours to design: the folder `pages/<slug>/` of the workspace, `page.html` (any HTML, CSS and script of yours, [pages-and-data.md](references/pages-and-data.md#a-page-is-yours-to-design); a board of cards is one way, `<div class="gallery-board" data-board-id="main">`, each card a `<section class="gallery-card" data-card-id="…" data-x data-y data-w data-h>` around one custom block's instance, in square cells, twelve to a row) and `page.json` (its title and icon), opened at `/#@<slug>`. On a board the user moves, resizes, adds and deletes its cards there (the grip at a card's top-right corner: a drag moves it, a click opens its menu, 大小, 设置… and 删除; 添加自定义块 is the first row of the ··· menu at the right of the workbench's top bar, and puts a card on the page's first board), and types in them. The page draws no big title: its name is the sidebar's, the tab's and the top bar's, so write no `<h1>` of the page's name (one in `header.gallery-page-head` is not drawn). Keep a card's top-right corner clear (28 × 28 px, 6px in): the grip stands over it while the pointer is on the card; you write it when they ask for a page or a card ("首页加一张卡片…", "给我做一个读书页").
|
|
144
|
-
|
|
145
|
-
1. Run `gallery page list` and `gallery block list` first: the pages there are, and the blocks a card can be (自定义页可用, and Gallery's own not yet added). "首页" is `pages/home` (a page as any: the user may rename or trash it). Gallery makes it once, when its server first starts in a workspace (`gallery init` does too), with its own cards, which the user may have moved, filled in or taken off; until then `gallery page list` and the commands of `home` say it is not made yet, and `gallery open --no-browser` makes it: run that once, then again. Extend it with `gallery page add home <block>`, never write its `page.html` over whole; one the user trashed stays away. A new page only when the user asks: `gallery page new <slug> "<title>"`. A blank page they made in the sidebar (新建页面, `page-…`, an empty main) is one to write whole.
|
|
146
|
-
2. Send the address first, before you write any card: on the `交给用户` line of `gallery page new <slug> "<title>"` (a server running prints it; without one, `gallery page open <slug> --no-browser` does), or of `gallery page open home --no-browser` for the home page, in a message of its own: the user watches the cards arrive.
|
|
147
|
-
3. On a page that is there, change only the cards the request needs. Every other card keeps its `data-card-id`, its place and its data parts as they are: the user placed them, and a note's words are theirs. Put a card on with `gallery page add <slug> <block>` (the first free spot by the block's default size, or `--x --y --w --h`; it gives the card its id and pushes down what it meets); re-read `page.html` right before each change you make in it by hand, and replace that card alone.
|
|
148
|
-
4. Use one of Gallery's own blocks when it fits the request exactly (two packs: Gallery 风格's by a bare name, and 柔光风格's, off till the user turns it on, as `gallery-soft/<name>`; `gallery block add <name>` puts one in, and comes before `gallery page add`: `today`, `note`, `countdown`, `habit`, `weather` (a city's weather, from Open-Meteo: it goes online), and `todos`, `recent`, `stats`, `heatmap`, which read the workspace: its to-dos, the documents edited last, its counts, its edits by day; the user ticks a to-do on `todos`, and the tick is written into the document it is in as the user's own edit, which the page's Ctrl+Z takes back), and `gallery/static` for a card that only shows what you write (a heading, links, a short list, a picture: its file in `pages/<slug>/assets/`, written `assets/<file>`; it is for a custom page alone, a document's HTML is written as it is; it takes any size of cells, 4 × 4 at first, and does not grow with its words, so write the `data-w` and `data-h` it needs). When one is close but not exact (other fields, another look, another rule), do not settle for it, and do not write a block from nothing either: copy it with `gallery block new <id> --recipe <name>` and change the copy (a count by day, glasses of water or times, starts from `habit`: `gallery block new <id> --recipe habit`; a recipe, a block already made, takes no `--script`, `--flow`, `--data` or `--page`): its name, words, description, `preview.svg`, writing.md and example.html, which the command lists; Gallery's own stays as it ships. Make a block of your own from nothing ([references/building-blocks.md](references/building-blocks.md), and [references/pages-and-data.md](references/pages-and-data.md) for a card's size and settings and for what it reads: `gallery block new <id> --page --data` for a card that keeps what the user enters, `places` holding `page`) for a card that does something or keeps data the user changes that none of Gallery's is near, and for a read-only card over the workspace's data or the web's that none of Gallery's shows (a count by day, a rate, a feed, the rows of another document's table: `kanban`, `metric` and `chart-view` are views inside a document and read no table from a page): it is a block too (`needs` `workspace` or `net:<host>`; start from `heatmap` or `weather` with `--recipe`), never the page's own script or HTML. What a card holds stays in its card (a data part, its settings), never in the page's own HTML. A card that shows nothing without a setting the user did not give (`weather`'s city, `countdown`'s date, a block of your own with its owner) is asked about: ask the user, or take it from what the workspace says (写作偏好, the documents; ask when that is a guess), and tell them in the handoff what it holds and where you took it from, or that the card still asks for it. Give it with the add, `gallery page add home weather --set city=上海` (each `--set <key>=<value>`, no JSON to quote, held to the setting's type: a date is `YYYY-MM-DD`); for a card already there, write it in the card's settings part (its `<script type="application/json">`, as the block's writing.md shows), re-reading `page.html` right before and changing that part alone. `gallery page check` notes a card whose required setting is empty.
|
|
149
|
-
5. Try each gesture of a new block on its card: `gallery page try <slug> <card id> --press <selector>` (the gestures and `--steps` of `gallery block try`, on a scratch copy of the page): its `Wrote:` lines name that card's data parts alone, then the page's own Ctrl+Z gives the copy back and a fresh page reads it back. Then `gallery page check <slug>` until it prints `OK`: each `FAIL page.html:<line>` (an id missing or twice, cards sharing cells or past the row, a block a page does not run, a file of `assets/` not there or a frame of one, a card whose content does not fit it; the page's own scripts and stylesheets pass); open the pictures its `Not opened yet` line lists (1280, 1920 and 600px wide, light and dark) and read its `Changes since …` lines: they name the cards you meant to change and no other, but those that end `(the user's, on the page)`, the user's own gestures on the page since the last check (a card moved, words typed in it): leave those as they are, never put one back. A line that ends `(put there by Gallery)` is the home page's own today or note, there before you came (a new workspace's first check of `home` lists them): leave those too.
|
|
150
|
-
6. At the end tell the user what you changed (each card, by what it shows) and where: the page's title in the sidebar (with 新建 and 搜索), and the address again. A card that goes online (`weather`, or a block whose needs name `net:<host>`) shows nothing until the user allows it: tell them to press 允许访问 on the card, and never write that consent yourself.
|
|
151
|
-
- A page is no document: no opening summary, no source line, no export; 写作偏好 is for documents.
|
|
152
|
-
- Its look is yours to choose (a header of your own that is no title, colors of its own in its `<style>`), written for both themes: the dark ones under `:root[data-doc-effective-theme="dark"]`.
|
|
153
|
-
- Its own scripts are yours too, a board or none; what a card does is its block's, which the server puts in.
|
|
65
|
+
- **New document:** where the user says (`gallery new … --under <document>`, last under it, or `--first`; `--after <document>`). With no place named, run `gallery list --tree` and put it under the document whose topic it belongs to, else at the top; say where in the handoff.
|
|
66
|
+
- **Move** only when asked: `gallery move <document> --under <document>|--top`, `--after` or `--first` for the place, with those under it.
|
|
67
|
+
- **Delete** with `gallery trash <entry>…` (a document, a custom page, a web link; the documents under a trashed one move up, as in the sidebar), not by removing folders, which leaves a broken sidebar entry. `gallery trash list` shows the trash, `gallery trash restore` puts one back; `gallery trash empty` deletes for good: only when the user explicitly asks.
|
|
68
|
+
- **Copy** with `gallery duplicate <document>` or `gallery copy <document> --to <workspace>`, not by copying the folder (block ids, annotations and history would come along).
|
|
69
|
+
- **Title, icon, description, font, layout:** `gallery set <document> --title … --icon <emoji, or none> --description … --font …` writes the header and `doc.json` together; edit neither by hand. Re-read `doc.html` after it.
|
|
70
|
+
- **Columns, favorites, web links, workspaces in the sidebar:** `gallery column`, `gallery favorite`, `gallery link`, `gallery workspaces`. Extensions: `gallery extension list`, then the AGENT.md it lists ([references/extensions.md](references/extensions.md)). Report each place (`位置:`) in the handoff.
|
|
71
|
+
- **Custom pages (自定义页)** are the user's own pages in the sidebar, which you design when they ask ("首页加一张卡片…", "给我做一个读书页"). A page is no document (no 写作偏好, no export): read [Working on a custom page](references/pages-and-data.md#working-on-a-custom-page) first. Reorder, rename or trash pages only when asked.
|
|
154
72
|
|
|
155
73
|
## Output contract
|
|
156
74
|
|
|
157
|
-
- `<
|
|
158
|
-
- Everything document-specific (data, visuals, styles, scripts) stays in `doc.html` and its `assets
|
|
75
|
+
- `<slug>/doc.html` and `doc.json` are the editable sources; `<workspace>/.gallery/` is Gallery's own; `<workspace>/exports/<slug>.html` is the offline, single-file deliverable. Export again after the last source edit. In the handoff the clickable HTML is the export or a verified byte-identical copy, not a source or a page of the local server.
|
|
76
|
+
- Everything document-specific (data, visuals, styles, scripts) stays in `doc.html` and its `assets/`; the kit's blocks, styles and `sdk/` are not yours to change. A document's own script cannot write the file, so a control that keeps what a reader enters (a ledger, a checklist, a form) is a custom block's data part (`gallery block new <id> --data`). Otherwise make a custom block only when the user clearly wants one to use again, not one per document: `gallery block list` first (`gallery block add <name>` adds one of Gallery's own), then [references/building-blocks.md](references/building-blocks.md) (a script: [references/block-script.md](references/block-script.md)). For a document that uses it too, make the document first (steps 1–2), then the block, the instance last.
|
|
159
77
|
|
|
160
78
|
## Handoff
|
|
161
79
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
- the
|
|
165
|
-
-
|
|
166
|
-
- the
|
|
167
|
-
- where a document you made sits in the sidebar's tree when you chose its place, and every move you made;
|
|
168
|
-
- for a revision, the blocks you changed, the changes the user did not name, what a conversion dropped, and what a change of structure left side by side (two headings of one name, one right after the other, after a move).
|
|
80
|
+
- the deliverable: the path on the last `交给用户(离线文件):` line, copied whole, and the document's address (not in a cloud sandbox they cannot reach). An edit after the export, the user's too, needs another export;
|
|
81
|
+
- what `gallery qa` flagged, what you fixed, the pictures you opened by name (a width or block whose pictures you did not open is one you did not look at), or that it could not run;
|
|
82
|
+
- the sentences that are your own inference, not the materials', and where they are;
|
|
83
|
+
- where a document you made sits in the sidebar, and every move you made;
|
|
84
|
+
- for a revision: the blocks you changed, the changes the user did not name, what a conversion dropped, what a change of structure left side by side.
|
|
169
85
|
|
|
170
|
-
Before you hand over, do the review 写作偏好 asks for
|
|
86
|
+
Before you hand over, do the review 写作偏好 asks for (a subagent's reading, a check of the numbers), when it asks for one.
|
|
171
87
|
|
|
172
88
|
## References
|
|
173
89
|
|
|
174
|
-
|
|
175
|
-
| --- | --- |
|
|
176
|
-
| The user's rules for writing: what to write, the opening summary, titles, fidelity, evidence and data | 写作偏好, `<home>/preferences.md` |
|
|
177
|
-
| How a block is written | [references/example-report.html](references/example-report.html) |
|
|
178
|
-
| The rules behind the blocks: the page, what plain HTML becomes, figures and charts you draw yourself | [references/writing-html.md](references/writing-html.md) |
|
|
179
|
-
| A custom block (a block to use again), when the user asks for one: the block, its flow, files, manifest and instance; sharing a block pack | [references/building-blocks.md](references/building-blocks.md) |
|
|
180
|
-
| A block's script (`kit.js`) and how it writes back to the file | [references/block-script.md](references/block-script.md) |
|
|
181
|
-
| A card of a custom page (size, settings), and a block that reads the workspace's data, a table of its document or the web | [references/pages-and-data.md](references/pages-and-data.md) |
|
|
182
|
-
| Sidebar columns or workbench/backend extensions (`gallery extension new/install/list/check/remove`), when requested | [references/extensions.md](references/extensions.md) |
|
|
183
|
-
| Exact API types | `sdk/*.d.ts`, from [`sdk/index.d.ts`](sdk/index.d.ts) |
|
|
184
|
-
| What each command does and prints | `gallery help`, `gallery <command> --help` |
|
|
90
|
+
A clickable UI proposal or standalone prototype: [references/previews.md](references/previews.md). Exact API types: `sdk/*.d.ts`, from [`sdk/index.d.ts`](sdk/index.d.ts).
|
|
@@ -38,14 +38,14 @@ One block, one manifest and one `context` stand in either place; the two differ
|
|
|
38
38
|
|
|
39
39
|
## The flow
|
|
40
40
|
|
|
41
|
-
When the user wants a document that uses the block too, the document comes first: `gallery new`, its address sent, its skeleton written (SKILL.md, Workflow steps 1–
|
|
41
|
+
When the user wants a document that uses the block too, the document comes first: `gallery new`, its address sent, its skeleton written (SKILL.md, Workflow steps 1–3). Then make the block as below, write the instance in its section at step 5, and try it there at step 6.
|
|
42
42
|
|
|
43
43
|
1. `gallery block list` first: what the workspace has now, in two groups by where a block may stand (文档里可用, in documents; 自定义页可用, on custom pages), each with its version, whether the menus can insert it, and what is there and cannot be used, with why; then Gallery's own blocks it has not added yet. When one does what the user asks, use it: `gallery block show <id>` prints its parts, how to write it and its example (`gallery block show gallery/<name>` does so for one of Gallery's own the workspace has not added yet, and ends with the line that adds it; `show` and `check` take its bare name too, `gallery block show heatmap`, as `add` does, a block of the workspace's own by that name staying `local/`'s). When one of Gallery's own does, `gallery block add <name>` puts it in as it ships, and it needs no check and no try (Gallery's own blocks, below).
|
|
44
44
|
2. `gallery block new <id>`: a new block in `<home>/components/<scope>/<name>/`, its `id` being `<scope>/<name>`, the scope `local` when you name none: the default pack (默认块包, first in 设置 › 组件列表), where a single block goes, with no pack of its own to make. It writes a block that passes the check, for you to replace. Add `--script` only when the block must do something when a reader uses it: a static block runs no code, is the one to start with, and is all most blocks need. Add `--flow` when it holds blocks of the document's own under its markup (a card around any content): a slot, `body` (Slots, below). Add `--data` for a block that keeps what a reader enters in the file, the usual reason to make one (a list of lines, a field that adds one, a button that takes one away): a data part `items` (JSON on one line, as `context.editJSON` writes it), a `kit.js` that reads it with `context.readJSON` and writes it with `context.editJSON`, a field (`DocKit.input`) and buttons hidden where nothing is written, and an `example()` that adds a line, which works on `template.html`'s empty instance as on `example.html`'s: rename the part and its fields for what the block keeps, and keep that shape. Add `--page` for a custom page's card (its places `["page"]`, a `card` of two sizes). `--data` and `--page` go together or alone, and either goes with `--script`; neither goes with `--flow` (a page has no slot, and `--data` is a part of its own), nor with `--recipe <name>`, which starts from one of Gallery's own (below). Each scaffold passes `gallery block check`, and `gallery block try` on its field (`--type .component-field "words" --then Enter`), as it is.
|
|
45
45
|
3. Write its files (below): the manifest, `template.html`, `example.html`, its style and, with `--script`, `kit.js`, then what a writer needs to know.
|
|
46
|
-
4. `gallery block check <id>`, until it prints `OK`. It says each problem at its file and line; one with no line is of that file, or of the page, as a whole. Then open `overview-light.png` and `overview-dark.png` in the folder it prints, each the pictures of 360, 736 and 1024px wide of a theme side by side, `example.html` above the line and `template.html` below it, then at full size each width where they show something to fix, and `edit-1024-light.png` and `edit-360-light.png`, as the editing page draws it, `context.canEdit()` true: what the block draws only where a reader can edit (a handle, a button), which an export leaves out. A block that draws nothing more there gives the export's pictures again, and the check says so. It has run them and looked at nothing for you: a
|
|
46
|
+
4. `gallery block check <id>`, until it prints `OK`. It says each problem at its file and line; one with no line is of that file, or of the page, as a whole. Then open `overview-light.png` and `overview-dark.png` in the folder it prints, each the pictures of 360, 736 and 1024px wide of a theme side by side, `example.html` above the line and `template.html` below it, then at full size each width where they show something to fix, and `edit-1024-light.png` and `edit-360-light.png`, as the editing page draws it, `context.canEdit()` true: what the block draws only where a reader can edit (a handle, a button), which an export leaves out. A block that draws nothing more there gives the export's pictures again, and the check says so. It has run them and looked at nothing for you: a `下一步:open the N pictures of this run …` line right before the verdict lists every picture of the run in one place (`gallery qa` lists its own as 「要看的图」): count by it. In the handoff name the pictures you opened. A block with a data part whose export (`1024-light.png`, where `context.canEdit()` is false) still shows an enabled button, field, select or textarea gets a note: a control that writes is drawn hidden there, which you see by comparing that picture with `edit-1024-light.png`.
|
|
47
47
|
5. Use it where the user asked: in a document, write the element as `example.html` does (when the user wants no document, in one of its own made with `gallery new`, named in the handoff: step 6 tries the block there). The user finds it in "/" under its name. `gallery export <slug>` exports it as any block, and `gallery qa <slug>` pictures it among the cards. Around an instance, the document's words say what the block is and where its data comes from. A value that a reader's gesture changes (a count by column, a status, a score, a total) goes in the document's words only with when it held ("截至 11 月 5 日,…"), as an opening summary may need it; otherwise point to the block, which shows it as it is now. How to use the block on the editing page (drag a card, press a dot) goes in the handoff and in writing.md, not in the document: its export and PDF show the block read-only. Then `gallery block check <id> --documents`: it runs each instance the workspace's documents hold as step 4 runs the example, a section for each document, each problem at its line of the document's file (`board/doc.html:15`), the pictures in `documents/<slug>/` of the folder it prints, so that an instance filled otherwise than the example (a long title, an empty table) is tried as the reader's page runs it. It writes no document.
|
|
48
|
-
6. Try each gesture a reader makes, in the page, with `gallery block try`, one command for each, on the instance step 5 wrote (named after the slug by its `data-block-id` when the document holds more than one; one in another block's slot is one of them): `--drag <selector> --to <selector>` (a card dragged to another column or place), `--press <selector>` (a dot, a button), `--key <selector> <key>` (Enter, Space or an arrow on a control the block draws), `--type <selector> <words>` (words typed in a field it draws or in a text part, the Chinese through an input method, as the user types) or `--select <selector> <value>` (an option of a `<select>`, by its value or its words), as `gallery block try <slug> --drag .kanban-card --to ".kanban-column:nth-child(3)"`; `--then <key>` presses a key after it where the focus is, as `--type .habit-name 多喝水 --then Enter` for a field that writes on Enter. What a reader does in several gestures (a rename: `Control+a` in the field, the new name, Enter; a form) goes in a steps file, `--steps <file>`: a JSON list of steps, each naming one gesture as the options do, without their `--`, as `[{ "key": [".habit-name", "Control+a"] }, { "type": [".habit-name", "多喝水"], "then": "Enter" }, { "select": [".habit-unit", "杯"] }, { "drag": ".kanban-card", "to": ".kanban-column:nth-child(3)" }]`, made one after another in one page. Each selector is the first element of the instance that it finds, as `kit.js` draws it: `Nothing in the instance is …` lists the classes the instance shows. Words go in pressed at the element's middle, the caret at the end of what it holds, so that into a field that holds words already they go after them, and the Gesture line says so (`it held "餐饮", and the words went after it`); where a step before left the focus in it there is no press, and they go in at the caret where that step left it (a press puts it where the pointer lands, an arrow key moves it), which the Gesture line says too (`the caret inside what it held`); `--replace` (`"replace": true` in a step, `{ "type": [".category", "交通"], "replace": true }`) selects all the field holds first, so that they take its place, as a reader's Ctrl+A does. The command makes the trial on a scratch copy of the document, its page alone, editable, in a Chrome or Edge of its own, headless: `doc.html` is not written and the user's page shows nothing of it, and the copy goes at the end, whatever came of it. It makes each gesture there with the pointer or the keys (a drag in steps, released as it comes onto its target), waits until the copy has what it wrote, and prints it: `Wrote: tasks (-1 +1 of its 8 lines); nothing outside the instance changed (data-block-id aside)`, each part with the lines the gesture took out and put in, and under it those lines, `-` and `+`: read them, they are what a reader's gesture writes to the file (with `--steps`, `Wrote: nothing` of a step that wrote nothing, a press that opens a field, which is fine). Then it undoes as a reader does, a Ctrl+Z for each write the page took, the last first (each `context.edit` is one undo step: a gesture that wrote twice takes two), and says `Undone: one Ctrl+Z, and the copy of doc.html is as it was (data-block-id aside)`, and opens what the gestures wrote in a fresh page, where the block is to mount, write nothing as it opens and show what it showed after them of what they wrote: `Read back: …`. What the page showed and never wrote (a filter or a tab chosen, an editor left open) a fresh page does not keep, and need not: a `note` line says what differed. Write what a reader keeps, never what they only look through. `--keep` makes the trial on `doc.html` itself and leaves the write, which every page open on the document shows, the user's too: say so in the handoff. Open the picture its `Picture of the instance after …` line names: no one has looked at it for you, and the
|
|
48
|
+
6. Try each gesture a reader makes, in the page, with `gallery block try`, one command for each, on the instance step 5 wrote (named after the slug by its `data-block-id` when the document holds more than one; one in another block's slot is one of them): `--drag <selector> --to <selector>` (a card dragged to another column or place), `--press <selector>` (a dot, a button), `--key <selector> <key>` (Enter, Space or an arrow on a control the block draws), `--type <selector> <words>` (words typed in a field it draws or in a text part, the Chinese through an input method, as the user types) or `--select <selector> <value>` (an option of a `<select>`, by its value or its words), as `gallery block try <slug> --drag .kanban-card --to ".kanban-column:nth-child(3)"`; `--then <key>` presses a key after it where the focus is, as `--type .habit-name 多喝水 --then Enter` for a field that writes on Enter. What a reader does in several gestures (a rename: `Control+a` in the field, the new name, Enter; a form) goes in a steps file, `--steps <file>`: a JSON list of steps, each naming one gesture as the options do, without their `--`, as `[{ "key": [".habit-name", "Control+a"] }, { "type": [".habit-name", "多喝水"], "then": "Enter" }, { "select": [".habit-unit", "杯"] }, { "drag": ".kanban-card", "to": ".kanban-column:nth-child(3)" }]`, made one after another in one page. Each selector is the first element of the instance that it finds, as `kit.js` draws it: `Nothing in the instance is …` lists the classes the instance shows. Words go in pressed at the element's middle, the caret at the end of what it holds, so that into a field that holds words already they go after them, and the Gesture line says so (`it held "餐饮", and the words went after it`); where a step before left the focus in it there is no press, and they go in at the caret where that step left it (a press puts it where the pointer lands, an arrow key moves it), which the Gesture line says too (`the caret inside what it held`); `--replace` (`"replace": true` in a step, `{ "type": [".category", "交通"], "replace": true }`) selects all the field holds first, so that they take its place, as a reader's Ctrl+A does. The command makes the trial on a scratch copy of the document, its page alone, editable, in a Chrome or Edge of its own, headless: `doc.html` is not written and the user's page shows nothing of it, and the copy goes at the end, whatever came of it. It makes each gesture there with the pointer or the keys (a drag in steps, released as it comes onto its target), waits until the copy has what it wrote, and prints it: `Wrote: tasks (-1 +1 of its 8 lines); nothing outside the instance changed (data-block-id aside)`, each part with the lines the gesture took out and put in, and under it those lines, `-` and `+`: read them, they are what a reader's gesture writes to the file (with `--steps`, `Wrote: nothing` of a step that wrote nothing, a press that opens a field, which is fine). Then it undoes as a reader does, a Ctrl+Z for each write the page took, the last first (each `context.edit` is one undo step: a gesture that wrote twice takes two), and says `Undone: one Ctrl+Z, and the copy of doc.html is as it was (data-block-id aside)`, and opens what the gestures wrote in a fresh page, where the block is to mount, write nothing as it opens and show what it showed after them of what they wrote: `Read back: …`. What the page showed and never wrote (a filter or a tab chosen, an editor left open) a fresh page does not keep, and need not: a `note` line says what differed. Write what a reader keeps, never what they only look through. `--keep` makes the trial on `doc.html` itself and leaves the write, which every page open on the document shows, the user's too: say so in the handoff. Open the picture its `Picture of the instance after …` line names: no one has looked at it for you, and the `下一步:open the 1 picture of this run …` line after it lists it. A `note` line asks what the check's notes ask (a write that lays a part out anew: change the write as [Writing back](block-script.md#writing-back) says; none for a write that is `context.editJSON`'s own layout, nothing to change: a part on several lines that closes to one line as its list empties, or an entry in it that opens to lines of its own as it comes to hold an object; editJSON opens no part that stands on one line, which stays on one line, compact, one that closed to one line too). Exit 1 is a problem to fix in the block: gestures that wrote nothing say what came of the last (no `context.edit` came of it, the page refused one and the console says why, an HTML5 drag was dropped nowhere: a list a card is dropped on cancels `dragenter` as well as `dragover`; words typed in a field that writes on Enter: add `--then Enter`), an undo that did not take a write back says what still differs, and a fresh page that shows the block otherwise than the page did after the gestures, in what they wrote, says what (a value kept in memory and not in the part, or written in a form the mount does not read), as does one that writes as it opens (draw what the parts hold, and write on a gesture alone); fix it, run `gallery block check <id>`, and try the gestures again. Exit 2 is a mistake in the command; one found at a step after others were made is said after what those wrote, which `--keep` leaves in `doc.html`. Exit 3 (`UNVERIFIED`) is a trial not seen through, its line saying why (no browser, a page that loaded itself again as the block changed): run it once more.
|
|
49
49
|
A gesture the command cannot make (the block inserted from "/" by its name, or a word of `words`, the pinyin of its name), make yourself when you can drive Chrome or Edge by its DevTools protocol, from Node 22's own `fetch` and `WebSocket`, with nothing to install. Start one of its own at the `Agent 自用` address that `gallery new`, `gallery import` or `gallery open` prints: the document's page alone, editable, with no frame around it (`--headless=new --remote-debugging-port=<port> --user-data-dir=<a new folder> <address>`; `http://127.0.0.1:<port>/json/list` gives the tab's `webSocketDebuggerUrl`, and `Input.dispatchMouseEvent`, `Input.dispatchKeyEvent` and `Runtime.evaluate` do the rest). Copy `doc.html` first. A gesture's write goes to the file by itself: `<html>`'s `data-ge-save` leaves `saved` (`waiting`, then `syncing`) and says `saved` again once the file has it (`held`: a card waits for the reader; `offline` or `stopped`: the server). Then read the part in `doc.html`: it holds what the gesture meant, and nothing outside it changed but `data-block-id`: the page gives a block it saves a change of one where it has none (the instance, the section it stands in), and an undo leaves it, so compare `doc.html` with your copy with every `data-block-id` taken out. Press Ctrl+Z once with the focus in no field the block draws (in an `input`, a `select`, a `textarea` or an editable element of its own, Ctrl+Z is that field's: a click on a paragraph beside the block takes the focus off it), wait for `saved`, and see the part as it was. At the end `doc.html` is your copy again, but for those ids and what the user changed meanwhile at the address you sent: undo each step, the insert too, then close your Chrome. Anything of the trial an undo left (the page was loaded again, a card held a step), take out yourself once your Chrome is closed, as any change of yours, `doc.html` read again first: the instance, and an empty paragraph you made for it, keeping the rest and the ids. Write the whole copy back only where `doc.html` differs from it in what the trial left alone, ids aside, and never while a page of yours is open on the document: over more, it takes away what the user wrote meanwhile and shows them a card saying so, and a page of yours open on it holds on a card of its own.
|
|
50
50
|
In the handoff name the gestures you tried, and only those, each by its command or its steps and what it wrote, and what the user changed meanwhile, which stays. When you could not try one, by the command or yourself, say plainly in the handoff that you did not try it in the page.
|
|
51
51
|
|
|
@@ -233,7 +233,7 @@ A block pack (自定义块包) is a scope of blocks shared as one: the folder `c
|
|
|
233
233
|
2. `kit.js`: what a browser refuses, what an export refuses, what it registers, a type check against `sdk/`, what the types alone say of code a browser runs being a note;
|
|
234
234
|
3. `style.css`: each selector, what an export cannot hold;
|
|
235
235
|
4. `template.html` and `example.html`: as the page of a document, by what `gallery check` runs, and `template.html` as what a menu can put in;
|
|
236
|
-
5. both in a temporary document, exported, in Chrome or Edge under the export's policy: the console, a dialog or a window it opens, a page that loads itself again or stops answering, mount and dehydrate, what piles up in the instance or outside it, a text part the block redraws, a data part a mount changes, a write with no gesture once the page takes edits, the way back to the file, a page wider than the window, and the pictures. The way back runs the block's `example` ([Writing back](block-script.md#writing-back)), a small edit made by the change a reader's gesture calls: it must change a data part and nothing else, the server must take what it wrote, and with the part put back, as an undo does, the block must show what it showed. Its `way back` line says what the example wrote, each part and how many of its lines changed, and that the server took it; a note says a write that lays a part out anew (lines a change did not mean, a line left blank), and a list a card is dropped on that listens for `dragover` and not for `dragenter`, at the line of `kit.js` that listens. A block with a data part and no `example` gets a note: nothing has tried its way back (none where that part is its `settings` alone, which the card's form writes and the block only reads). An `example` that changes nothing on an instance (the template's empty one, usually) is a `FAIL` said at `kit.js`; no note for a write that lays JSON out as `context.editJSON` itself does (a part on several lines closing to one line as its list empties, an entry in it opening to lines of its own as it comes to hold an object; a part on one line stays on one line). A note says too that an instance of a block with a data part, in the export's look, still shows an enabled button, field, select or textarea. After the pictures a
|
|
236
|
+
5. both in a temporary document, exported, in Chrome or Edge under the export's policy: the console, a dialog or a window it opens, a page that loads itself again or stops answering, mount and dehydrate, what piles up in the instance or outside it, a text part the block redraws, a data part a mount changes, a write with no gesture once the page takes edits, the way back to the file, a page wider than the window, and the pictures. The way back runs the block's `example` ([Writing back](block-script.md#writing-back)), a small edit made by the change a reader's gesture calls: it must change a data part and nothing else, the server must take what it wrote, and with the part put back, as an undo does, the block must show what it showed. Its `way back` line says what the example wrote, each part and how many of its lines changed, and that the server took it; a note says a write that lays a part out anew (lines a change did not mean, a line left blank), and a list a card is dropped on that listens for `dragover` and not for `dragenter`, at the line of `kit.js` that listens. A block with a data part and no `example` gets a note: nothing has tried its way back (none where that part is its `settings` alone, which the card's form writes and the block only reads). An `example` that changes nothing on an instance (the template's empty one, usually) is a `FAIL` said at `kit.js`; no note for a write that lays JSON out as `context.editJSON` itself does (a part on several lines closing to one line as its list empties, an entry in it opening to lines of its own as it comes to hold an object; a part on one line stays on one line). A note says too that an instance of a block with a data part, in the export's look, still shows an enabled button, field, select or textarea. After the pictures a `下一步:open the N pictures of this run …` line lists them all. Exit 3 and `UNVERIFIED` when no browser ran it, or the browser went while it ran: run it again, or export a document that holds it and look yourself.
|
|
237
237
|
|
|
238
238
|
With `--documents` it prints a section more for each document of the workspace that holds instances of it, those in another block's slot too: each instance run as the fifth section runs the example, each problem at its line of the document's file (`board/doc.html:15`), no document written.
|
|
239
239
|
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Figures and charts
|
|
2
|
+
|
|
3
|
+
The rules for what you draw yourself, read when a document needs a chart, a diagram or a layout of its own. [writing-html.md](writing-html.md) has the rest of the page's rules; the example report ([example-report.html](example-report.html)) shows a chart from JSON, a chart from a table, a timeline, `.box-path`, `.branch` and a metric strip written out.
|
|
4
|
+
|
|
5
|
+
A figure the reader looks at as one picture, with a title, is a card: `<figure class="doc-figure">`, its title an `h3`, a scope or unit line `p.doc-figure-caption`. Data charts are types of your own (`DocCharts.define`); diagrams, timelines and architectures are your own HTML or SVG inside the card. A layout that is no figure is a whole block. Draw what the materials call for in the form that shows it best.
|
|
6
|
+
|
|
7
|
+
The card draws the frame and the surface once: draw no second outer box (a border, a background, a shadow) inside `figure.doc-figure`. The words in a figure or a whole block are the user's to fix in place, not to split: a `<p>`, a heading or an `<li>` in them stays one. The user moves, resizes, retitles and copies a card.
|
|
8
|
+
|
|
9
|
+
**A chart** (intervals, distributions, small multiples, slopes, anything on axes), as the example's slope chart is: a card holding `<div data-doc-chart="type">` with its data as JSON, and the type defined once in the document's script with `DocCharts.define(type, draw)` (`type` lowercase letters, digits and hyphens, a letter first). The same type draws every chart declared with it, each from its own data.
|
|
10
|
+
|
|
11
|
+
- The kit calls `draw({ host, data, tokens, width, height })` with the host emptied, and again whenever its width, the theme or the card's height change; `height` is the card's height when the reader set one, else `null`. Draw into `host` with d3 v7 (on the page), and give the SVG `role="img"` and an `aria-label`.
|
|
12
|
+
- Give the data its shape once in JSDoc, on a line of its own right above the declaration (`/** @type {Array<{ label: string, value: number }>} */` then `const rows = data;`): untyped, d3 reads its values as strings and the checks put type notes on code that is correct. `d3.min` and `d3.max` may give `undefined`: write `?? 0`.
|
|
13
|
+
- Colors come from `tokens`: `text`, `muted`, `border`, `grid`, `surface`, `bg`, `accent`, `accentSoft`, `success`, `warning`, `danger`, `series[0..5]` (the kit's variables: `series[0]` is `--doc-series-1`, `accentSoft` `--doc-accent-soft`), and status colors from `tokens.tone("success" | "danger" | "warning" | "info" | "neutral")` ([sdk/doc-tokens.d.ts](../sdk/doc-tokens.d.ts)).
|
|
14
|
+
- Text in the host is the document's font at 16px, and in a group of class `axis` the kit's axis look (13px, muted): set a `font-size` only to change that, never under 13px. Measure the label column from the longest label (draw a text in the host and read `getComputedTextLength`), never a fixed width; when that leaves the plot too little room (long labels, a phone's width), put the labels above their rows. Draw for 360px as well: fewer ticks, labels that fit. `ticks(n)` is only a hint to d3 and may draw more (on 0–8,000, `ticks(3)` draws five); `tickValues` caps the count: at most four along a phone's axis, such as the domain's ends and middle, as the example's lollipop gives them. `gallery qa` warns `ticks` where an axis's labels crowd.
|
|
15
|
+
- Keep marks off the words: a zero, reference or grid line stops short of a label or a value's text, or the text moves clear of it, and a label stands at least 4px from the mark under or beside it. A length (a bar, a stem) starts at a baseline the reader can name (zero, or the axis's start as it is labeled), never at a number picked to fit the data. A legend belongs to the card: say the encoding in its `p.doc-figure-caption` or draw a key inside the chart, never in a paragraph outside the card; name the marks by shape or series (实心/空心, the series' name), never by light or dark, which the dark theme inverts.
|
|
16
|
+
- Show each set of values once, where it is read. When the chart labels every value, or the text gives them, fold its table (a table of a chart drawn from a table: the keyed form below; of one drawn from JSON: a disclosure right after its card, as the example's slope chart has it) or leave the value labels off. Keep the table in sight only when the reader needs exact numbers the chart does not show (more columns, many rows). The text and the opening summary give the takeaway (the largest, the smallest, a total), not every value again.
|
|
17
|
+
- To change what a chart shows, change its JSON; change its `define` code to change how every chart of that type draws.
|
|
18
|
+
- An interactive one is `DocCharts.define(type, { mount })`: `mount` gets what `draw` gets and a `signal` (for `addEventListener`), starts once in the emptied host with its controls, and may return `update(context)` and `destroy()` ([sdk/doc-charts.d.ts](../sdk/doc-charts.d.ts)).
|
|
19
|
+
|
|
20
|
+
**A chart drawn from a table**, as the example's lollipop is: write `data-doc-chart="<type>"` on the `<table>`, its `<caption>` the title; the tools put the card right after the table and link the two by a key. The kit calls your type's `draw` with `data` the table's rows: an object per body row, in the file's order, keyed by the header's words (give each column words of its own, never none), and `data.columns` the header's words in order. A value is `null` for an empty cell, a dash or `n/a`; a number when the cell writes one number (`12.5%` is 12.5, `3.6亿` 360000000, `约 20` 20; read from a cell's `data-sort-value` when it has one); else the cell's words: a range (`3–5 天`), a ratio (`3 / 4`), and every cell of a column whose header cell has `data-sort-type="text"` or `"date"`. Rows of a `<tfoot>` are left out of the chart, but a table with a `<tfoot>` has no table tools in the preview: keep a total out of a table you chart and say it in the text (a total row in the body is charted as a row). Type it with `/** @type {DocTableRows} */` on the line above `const rows = data;`. The chart draws again whenever the user edits the table, and they may add, rename or delete any row: so draw everything from the rows. Domains and ticks come from the values (`[0, d3.max(…)]` for a length, `d3.extent` for a position, `.nice()`), highlights and groups from a column of the table (a 重点 or 类别 column), never from row labels, numbers or the reason for an empty cell written in the code; an empty cell draws as a gap or a neutral no-value, its reason said in the table or the text. Merged cells, or a key no table carries, draw nothing (the card says why). Give a type drawn from a table a name of its own: drawn from JSON elsewhere, its `data` would have another shape. `gallery check` prints how each one reads its table (`chart …`: its rows, each column numbers or words), and a `note` where a column reads as numbers in some rows and words in others.
|
|
21
|
+
|
|
22
|
+
Written this way, on the `<table>`, the table always shows, its card after it. To fold the table under its card from the start (the chart labels its values, or the text gives them), write the card with a key of your own and the table carrying the same key; once exported, a chart card may stay in a column or a panel while its table's frame moves elsewhere:
|
|
23
|
+
|
|
24
|
+
<!-- you write -->
|
|
25
|
+
```html
|
|
26
|
+
<figure class="doc-figure">
|
|
27
|
+
<h3>各类别的数值</h3>
|
|
28
|
+
<div data-doc-chart="table-dots" data-doc-chart-data="values"></div>
|
|
29
|
+
</figure>
|
|
30
|
+
<details>
|
|
31
|
+
<summary>数据</summary>
|
|
32
|
+
<table data-doc-chart-source="values">
|
|
33
|
+
<thead><tr><th>类别</th><th>数值</th></tr></thead>
|
|
34
|
+
<tbody><tr><td>类别 A</td><td>12</td></tr><tr><td>类别 B</td><td>18</td></tr></tbody>
|
|
35
|
+
</table>
|
|
36
|
+
</details>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
```js
|
|
40
|
+
// data: the table's rows, each keyed by its header's words; data.columns the header's words in order.
|
|
41
|
+
DocCharts.define("table-dots", ({ host, data, tokens, width }) => {
|
|
42
|
+
/** @type {DocTableRows} */
|
|
43
|
+
const rows = data;
|
|
44
|
+
const [name, value] = rows.columns;
|
|
45
|
+
const points = rows.flatMap((row) => (typeof row[value] === "number" ? [{ label: String(row[name]), value: row[value] }] : []));
|
|
46
|
+
// The label column as wide as its longest label (the example's lollipop also puts long ones above their rows).
|
|
47
|
+
const probe = d3.select(host).append("svg").append("text");
|
|
48
|
+
const left = Math.ceil(d3.max(points, (point) => probe.text(point.label).node()?.getComputedTextLength() ?? 0) ?? 0) + 16;
|
|
49
|
+
probe.node()?.ownerSVGElement?.remove();
|
|
50
|
+
const tall = points.length * 36 + 40;
|
|
51
|
+
const x = d3.scaleLinear([0, d3.max(points, (point) => point.value) ?? 0], [left, width - 24]).nice();
|
|
52
|
+
const y = d3.scaleBand(points.map((point) => point.label), [8, tall - 28]);
|
|
53
|
+
const svg = d3.select(host).append("svg").attr("width", width).attr("height", tall).attr("role", "img").attr("aria-label", `${value},按${name}`);
|
|
54
|
+
// Three ticks when narrow, the domain's ends and middle: ticks(3) is a hint d3 may exceed.
|
|
55
|
+
const [low, high] = x.domain();
|
|
56
|
+
svg.append("g").attr("class", "axis").attr("transform", `translate(0,${tall - 28})`).call(d3.axisBottom(x).tickValues(width < 520 ? [low, (low + high) / 2, high] : x.ticks(5)));
|
|
57
|
+
svg.append("g").attr("class", "axis").attr("transform", `translate(${left},0)`).call(d3.axisLeft(y).tickSize(0));
|
|
58
|
+
svg.append("g").selectAll("circle").data(points).join("circle")
|
|
59
|
+
.attr("cx", (point) => x(point.value)).attr("cy", (point) => (y(point.label) ?? 0) + y.bandwidth() / 2).attr("r", 5).attr("fill", tokens.series[0]);
|
|
60
|
+
});
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**A drawing in a card** (a layered structure, a diagram of parts, an architecture, a timeline), as the example's timeline, `.box-path` and `.branch` are: your own HTML and CSS, or inline SVG, inside `figure.doc-figure` after its title and caption. Give its elements classes of your own (never `doc-…`) and style them in the page's `<style>`: draw what the figure needs (boxes, lines, gaps, sizes) but not the card's frame, colored with the kit's variables so that it follows the dark theme.
|
|
64
|
+
|
|
65
|
+
- A `<figure>` inside the drawing is part of it, not a card of its own.
|
|
66
|
+
- How parts relate (who calls, reads or feeds whom; where a flow branches, merges or loops) is drawn as boxes joined by arrows, not said in a caption or repeated in a table. The example draws both kinds. `.box-path`, HTML and CSS: each box but the last draws its line (`::after`) and its arrowhead (`::before`), one box under another with arrows down on a phone, in a row with arrows right from `@media (min-width: 560px)`. `.branch`, inline SVG: one box into two, its lines ending in a `<marker>` arrowhead (`marker-end`), colored by classes with `--doc-muted`, `--doc-border` and `--doc-accent`.
|
|
67
|
+
- Give each figure's SVG `<defs>` ids a prefix of its own (`<marker id="fig-branch-arrow">`, as the example's): two figures with the same id fail the repeated-id check; a copy the user makes gets its own prefix. Write markers, gradients and clip paths as attributes (`marker-end="url(#fig-branch-arrow)"`), not in a `<style>` inside the SVG.
|
|
68
|
+
- A `viewBox` scales the drawing, its text with it: 14-unit text in a viewBox 800 wide reads at 6px on a 360px phone. Size the text in the viewBox's units so that it reads at 11px or more at 360px, or lay the drawing out for narrow widths (HTML that wraps, an `@media` rule, or a chart of your own drawn from its width). The other way too: a viewBox sized for a phone grows its text with the card on a wide page (14 units in a viewBox 320 wide read at 31px drawn 712px wide), so give such an SVG a `max-width` (the example's `.branch`: 360px).
|
|
69
|
+
- `gallery qa` pictures it, warns `overflow-in-block` when its words run past their box at some width (give them room in an `@media` rule), `cut-in-block` when a box of a fixed height cuts off its words or marks (let it grow: `min-height`) and `svg-text-small` when a viewBox draws its text under 11px.
|
|
70
|
+
|
|
71
|
+
**A whole block** (整体块): a layout of your own that is no figure (a strip of metrics, a comparison panel, controls your script handles that only change what a reader looks at), as the example's `.metric-strip` is. Give it a class of your own (never `doc-…`) and style it in the page's `<style>` with the kit's variables. The user moves it whole and can fix its words in the preview; `gallery qa` warns `overflow-in-block` and `cut-in-block` as for a drawing. A drawing, a diagram or a timeline is a figure, in a card, not a whole block.
|
|
72
|
+
|
|
73
|
+
**A picture**: a diagram, scan or photo the materials come with ([Pictures](writing-html.md#pictures)).
|