pageship 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +18 -107
  2. package/dist/cli.mjs +1886 -505
  3. package/dist/skills/LICENSE +21 -0
  4. package/dist/skills/pageship/SKILL.md +150 -0
  5. package/dist/skills/pageship/references/download.md +9 -0
  6. package/dist/skills/pageship/references/list-and-history.md +15 -0
  7. package/dist/skills/pageship/references/restore.md +9 -0
  8. package/dist/skills/pageship/references/visibility.md +12 -0
  9. package/dist/skills/pageship-chart/SKILL.md +110 -0
  10. package/dist/skills/pageship-code-block/SKILL.md +113 -0
  11. package/dist/skills/pageship-code-block/references/highlight-lock.json +542 -0
  12. package/dist/skills/pageship-code-block/references/highlight.mjs +138 -0
  13. package/dist/skills/pageship-decision-record/SKILL.md +43 -0
  14. package/dist/skills/pageship-diagram/SKILL.md +92 -0
  15. package/dist/skills/pageship-diagram/references/check-diagram.js +301 -0
  16. package/dist/skills/pageship-diagram/references/computed-layout.md +49 -0
  17. package/dist/skills/pageship-diagram/references/layout.mjs +310 -0
  18. package/dist/skills/pageship-diagram/references/mermaid.md +89 -0
  19. package/dist/skills/pageship-diagram/references/svg.md +205 -0
  20. package/dist/skills/pageship-docs/NOTICES.md +35 -0
  21. package/dist/skills/pageship-docs/SKILL.md +67 -0
  22. package/dist/skills/pageship-docs/references/ask.md +18 -0
  23. package/dist/skills/pageship-docs/references/check.md +39 -0
  24. package/dist/skills/pageship-docs/references/content.md +29 -0
  25. package/dist/skills/pageship-docs/references/design.md +60 -0
  26. package/dist/skills/pageship-docs/references/file.md +52 -0
  27. package/dist/skills/pageship-docs/references/plain-default.md +331 -0
  28. package/dist/skills/pageship-explainer/SKILL.md +92 -0
  29. package/dist/skills/pageship-interaction/SKILL.md +115 -0
  30. package/dist/skills/pageship-interaction/references/pointer.md +271 -0
  31. package/dist/skills/pageship-interaction/references/step-through.md +146 -0
  32. package/dist/skills/pageship-key-figures/SKILL.md +127 -0
  33. package/dist/skills/pageship-media/SKILL.md +122 -0
  34. package/dist/skills/pageship-motion/SKILL.md +58 -0
  35. package/dist/skills/pageship-plan/SKILL.md +55 -0
  36. package/dist/skills/pageship-report/SKILL.md +29 -0
  37. package/dist/skills/pageship-review-report/SKILL.md +90 -0
  38. package/dist/skills/pageship-slide-deck/SKILL.md +53 -0
  39. package/dist/skills/pageship-slide-deck/references/engine.md +362 -0
  40. package/dist/skills/pageship-spec/SKILL.md +58 -0
  41. package/dist/skills/pageship-table/SKILL.md +243 -0
  42. package/dist/skills/pageship-table/references/sort-and-filter.md +235 -0
  43. package/package.json +1 -1
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Uzair Sajid
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,150 @@
1
+ ---
2
+ name: pageship
3
+ description: Publish an HTML file to Pageship and manage what is published. Use when the user asks to publish, share or get a link to a document, update its published copy, change its visibility, list, inspect history, download or restore published documents, or sign in to Pageship. To write, edit, rename or move a document, load pageship-docs instead.
4
+ license: MIT
5
+ metadata:
6
+ version: "0.2.0"
7
+ ---
8
+
9
+ # Pageship
10
+
11
+ Use the installed `pageship` CLI in JSON mode, and decide every next step from its result.
12
+
13
+ ## When to publish
14
+
15
+ Publish a file only when the user asked for it in this conversation, or accepted your offer to publish it. After that, publish later changes to the same document in this conversation as new revisions, without asking again.
16
+
17
+ A document marker in a file (`<!-- pageship:v1 document=<id> -->`) records that the file was published once. It is not a request. When you change a file that has a marker and the user hasn't asked to publish it in this conversation, offer to publish the change as a new revision, and upload nothing until the user agrees.
18
+
19
+ ## Write or change a document
20
+
21
+ When the user asks to write, change, rename or move a document, load `pageship-docs` and follow it, even when the same request asks you to publish. When it hands over the file, publish it if the user asked. If `pageship-docs` isn't installed, say so and offer the setup guide at https://pageship.dev/setup-guide, which installs it. If the user declines, write the document without the authoring skills, then publish it if the user asked.
22
+
23
+ ## Reading a result
24
+
25
+ With `--json`, the CLI prints one JSON object on one line. Parse it before you do anything else.
26
+
27
+ - `status` names the result. Decide from it, not from `message`.
28
+ - `message` is text for the user. Show it when you report a problem.
29
+ - `outcome` is `succeeded`, `pending` or `failed`, and `ok` is `true` only on `succeeded`.
30
+ - `succeeded`: the command did what was asked. A `next` here is optional further work, such as the next page of a list.
31
+ - `pending`: the command stopped safely to wait for the user's approval or decision, and changed nothing its follow-up would repeat. It always carries `next` or `resolutions`. Get the approval or decision, then run it.
32
+ - `failed`: the command could not do what was asked. Fix the reported cause first. A `next` here is a safe retry.
33
+ - `next` is one follow-up command. `resolutions` holds named alternatives for a decision, each a follow-up command or a list of them.
34
+ - Other fields depend on the status, such as `document`, `candidates`, `choices`, `user` or `idempotencyKey`.
35
+ - `skills install` returns `skills_installed` or `skills_modified`, as described in [Install the Pageship skills](#install-the-pageship-skills).
36
+
37
+ A follow-up has a `command` and an `args` array. Run it as `pageship --json <command> <args...>` with `args` unchanged. They already carry the server, target document, expected revision and retry key, so never rebuild them from memory.
38
+
39
+ ## Install the CLI
40
+
41
+ If the shell can't find `pageship`, tell the user the Pageship CLI isn't installed and offer to install it. Only with their consent, follow the setup guide at https://pageship.dev/setup-guide. It asks before it changes their environment.
42
+
43
+ ## Check readiness
44
+
45
+ To check whether this installation can publish before you start, run:
46
+
47
+ ```sh
48
+ pageship --json status
49
+ ```
50
+
51
+ Status only reads; it never signs in, claims an address or uploads. On `admitted`, sign-in and the workspace address are set, unless `next` is a `login`: that comes from an older server that does not report the address, and running it confirms the address. A `next` of `skills install` on `admitted` is about the skills, below. On `signed_out` or `address_required`, sign in as described below. On `uninvited`, report the `message`: the user must ask the server owner for an invitation, or sign in with another account using `login --restart`. On `unreachable`, `client_too_old`, `server_too_old`, `unsupported` or `configuration_unreadable`, report the `message`; signing in does not fix these. A ready status does not prove that a publish will succeed.
52
+
53
+ Status also reports the Pageship skills in `skills`: `missing`, `current` or `older` than the CLI. They never block publishing, and a status that is otherwise ready still succeeds. When `skills` is `missing` or `older`, tell the user, and install them as below only if they agree. Never run a `skills install` from `next` without asking.
54
+
55
+ ## Install the Pageship skills
56
+
57
+ The CLI carries the Pageship skills for its own version. With the user's agreement, install or update them:
58
+
59
+ ```sh
60
+ pageship --json skills install
61
+ ```
62
+
63
+ On `skills_installed`, they are in `~/.agents/skills`, and linked from `~/.claude/skills` when Claude Code is set up. On `skills_modified`, nothing was written: the folders in `folders` were changed after the CLI installed them, or the CLI has no record of them. Show the user those folders. Run `resolutions.force` only if they agree to replace them and lose those changes.
64
+
65
+ Both results, and `status`, list in `missing` what the CLI looked for and did not find: the recommended skills `frontend-design` and `design-taste-frontend`, and `node`, Node 20 or later, which the authoring skills' scripts need. The CLI never installs them, and they never change the outcome. Mention them, and offer the setup guide at https://pageship.dev/setup-guide.
66
+
67
+ ## Sign in
68
+
69
+ On `signed_out`, start authorization:
70
+
71
+ ```sh
72
+ pageship --json login
73
+ ```
74
+
75
+ On `authorization_pending`, give the user `verificationUriComplete` and `userCode`. After they approve, run the returned `next`. On `expired`, run the returned `next` for a new code. Login is ready only when it returns `authorized`. Then retry the command that returned `signed_out`. Use `--restart` only when the user wants a new authorization attempt.
76
+
77
+ On `choice_required` from `login`, authorization succeeded, but the workspace address is not selected. Ask the user to choose one of the `hostname` values in `resolutions.select`, then run that entry. For new choices, run `resolutions.refresh`. Never invent a subdomain. A `stale_choice` reason includes fresh choices; ask again. On `address_required` from `status` or `publish`, run the returned `next` to finish address selection, then retry the original command.
78
+
79
+ On `reauthentication_required`, ask the user to sign in to the Pageship dashboard again so it can verify their GitHub login. Then run the returned `next`. Starting a new authorization does not fix this outcome.
80
+
81
+ When `login` returns `cancelled`, `interrupted` or `request_failed` with a `user`, authorization succeeded and the credential is kept, but no address is selected. Run the returned `next` when the user is ready.
82
+
83
+ ## Publish
84
+
85
+ Set the shell placeholder `PAGESHIP_FILE` to one nonempty `.html` or `.htm` file. Pageship uses the server's configured per-file size limit. A new document is private. An existing source-path match does not overwrite a document.
86
+
87
+ ```sh
88
+ pageship --json publish "$PAGESHIP_FILE"
89
+ ```
90
+
91
+ The CLI records each published file's real path in its publish manifest on this machine, so running the same command again for that file revises its document without a choice, and a fresh session needs no remembered document ID. Inside a Git checkout with an origin remote, the file belongs to a project. A project file without a manifest entry, such as one in another checkout, is looked up by its project and repository-relative path on the server. `document.project` shows the readable remote, and it is `null` for a loose file outside any project.
92
+
93
+ After a successful upload the CLI adds the document marker to the end of the local file, so the file and the published revision match. The marker lets the file find its document after a rename or a move, and on another machine in a checkout of the same project. Keep the marker when you edit or regenerate the file, and do not write or change it yourself. To publish a file exactly as it is, add `--no-marker`.
94
+
95
+ ### Report the publish
96
+
97
+ On `published`, tell the user:
98
+
99
+ - the document URL, `document.url`;
100
+ - who can read it, from `document.visibility`: a private document opens only for its owner, signed in;
101
+ - whether this publish created a new document or revised an existing one, from `change`: `created` or `revised`.
102
+
103
+ Keep `idempotencyKey` only while you resolve an uncertain attempt.
104
+
105
+ ### When the publish stops for a decision
106
+
107
+ On `project_mismatch`, the file's marker names a document from another project, for example a fork. Nothing changed. Show the user the returned `document` and ask whether to revise it with the `resolutions.revise` entry or create a separate document with `resolutions.new`.
108
+
109
+ On `marker_unavailable`, the marker names a document that was not found or is not the user's, and nothing was uploaded. Ask before running the returned `next`, which creates a separate document.
110
+
111
+ A `revision_conflict` from a plain publish means the document changed after this machine last published it, for example from another machine or the dashboard. Nothing changed. Show the user the returned current `document` and ask whether to revise it with the `resolutions.revise` entry or create a separate document with `resolutions.new`.
112
+
113
+ On `source_collision`, inspect each candidate's `url`, `id` and current `revisionId`. Ask whether to revise one inspected candidate or create a separate private document. The collision itself changes nothing. For a separate document, run `resolutions.new`. For a revision, run the matching entry in `resolutions.revise`. On a `revision_conflict` after that, inspect the returned current `document` and ask again before using the fresh `resolutions.revise` entry. Pageship never rebases or overwrites a newer revision automatically.
114
+
115
+ ### Revise a chosen document
116
+
117
+ An unmarked loose file is not matched by path, so on another machine, or from another path, publishing it creates a new document. To update a specific document, set `PAGESHIP_DOCUMENT` to its `id` from `list`, and `PAGESHIP_REVISION` to its current `revisionId`, then run:
118
+
119
+ ```sh
120
+ pageship --json publish "$PAGESHIP_FILE" --revise "$PAGESHIP_DOCUMENT" --expected-revision "$PAGESHIP_REVISION"
121
+ ```
122
+
123
+ This works for any document the user owns, even when the file moved or belongs to another project. Another account's document returns `unavailable`. Later plain publishes of this file revise the named document, and its marker names it. After `--new`, they revise the new one.
124
+
125
+ ## Share a document
126
+
127
+ A request to share a document, or to send someone its link, is a request to publish it. Publish it as above and report the publish. A new document is private. When the result is private, ask whether to make it public, and say in the question that anyone with the link can then read it. When it is already public, because the user made it public earlier, say so and don't ask. Change visibility only after the user agrees, as in [visibility](references/visibility.md).
128
+
129
+ ## Use another server
130
+
131
+ The CLI uses the hosted Pageship service by default. Only when the user names another Pageship server, such as a local development server, add `--server <origin>` to every command you start yourself. Returned `next` and `resolutions` arguments already carry that server, so run them unchanged.
132
+
133
+ ## Manage published documents
134
+
135
+ Load the reference for the task:
136
+
137
+ - [List and history](references/list-and-history.md): find a document's `id`, `visibility`, current `revisionId` and `url`, and inspect its revisions.
138
+ - [Download](references/download.md): read a document's HTML, current or from an earlier revision.
139
+ - [Visibility](references/visibility.md): make a document public or private.
140
+ - [Restore](references/restore.md): make an earlier revision current again.
141
+
142
+ Deleting a document, recovering a deleted one, changing a document's display title and revoking a CLI installation happen in the dashboard, at https://app.pageship.dev for the hosted service. The CLI has no commands for them yet, so give the user the dashboard link.
143
+
144
+ ## Handle other outcomes
145
+
146
+ - `usage_error`: correct the reported arguments before retrying.
147
+ - `upload_too_large` or `invalid_file`: fix the file indicated by the result before retrying.
148
+ - `invalid_action`, `invalid_restore`, `unavailable` or `idempotency_conflict`: stop and resolve the reported input or selection. Generate a new idempotency key only for a different operation.
149
+ - `request_failed` or `interrupted`: retry the returned `next` unchanged when present. During `publish` or `restore`, it preserves the idempotency key. Without `next`, resolve the reported server or transport problem and rerun the original command.
150
+ - Any other status: report its `status`, `message` and exit code without guessing a follow-up command.
@@ -0,0 +1,9 @@
1
+ # Download
2
+
3
+ To read a document's HTML, run:
4
+
5
+ ```sh
6
+ pageship --json download "$PAGESHIP_DOCUMENT" --output "$PAGESHIP_OUTPUT"
7
+ ```
8
+
9
+ Set `PAGESHIP_DOCUMENT` to the document's `id` from `list`, and `PAGESHIP_OUTPUT` to a path that does not exist. For a historical revision, add `--revision <revisionId>` with an ID from `history`. The bytes go only to that file. On `output_exists`, nothing was written or replaced; choose another path. A download never changes the document or its visibility.
@@ -0,0 +1,15 @@
1
+ # List and history
2
+
3
+ List documents to find their `id`, `visibility`, current `revisionId` and `url`:
4
+
5
+ ```sh
6
+ pageship --json list
7
+ ```
8
+
9
+ Set `PAGESHIP_DOCUMENT` to one listed `id` and inspect its revisions, newest first. The entry with `isCurrent: true` is the current revision:
10
+
11
+ ```sh
12
+ pageship --json history "$PAGESHIP_DOCUMENT"
13
+ ```
14
+
15
+ A listing holds at most 100 documents and a history at most 50 revisions. When `next` is present, run it for the next page. Listing and history never change a document.
@@ -0,0 +1,9 @@
1
+ # Restore
2
+
3
+ Restoring makes an earlier revision current again. Run `history` as in [list and history](list-and-history.md), confirm with the user which revision to restore, then set `PAGESHIP_DOCUMENT` to the document's `id`, `PAGESHIP_REVISION` to the chosen `revisionId` and `PAGESHIP_CURRENT` to the current `revisionId`, all from the latest `history` or `list` result:
4
+
5
+ ```sh
6
+ pageship --json restore "$PAGESHIP_DOCUMENT" --revision "$PAGESHIP_REVISION" --expected-revision "$PAGESHIP_CURRENT"
7
+ ```
8
+
9
+ On `restored`, report the document URL. On `revision_conflict`, nothing was restored: run the returned `next` history command, show the user the new current revision, and ask again. On `request_failed` or `interrupted`, run the returned `next` unchanged; the idempotency key returns the original result instead of restoring twice.
@@ -0,0 +1,12 @@
1
+ # Visibility
2
+
3
+ A private document opens only for its owner, signed in. Anyone with the link can read a public one, without signing in.
4
+
5
+ Change visibility only when the user asked for a policy by name, such as "make it public", or agreed when you asked after sharing. Set `PAGESHIP_DOCUMENT` to the document's `id`, then run one of:
6
+
7
+ ```sh
8
+ pageship --json visibility "$PAGESHIP_DOCUMENT" public
9
+ pageship --json visibility "$PAGESHIP_DOCUMENT" private
10
+ ```
11
+
12
+ On `visibility_updated`, report the returned `document.visibility` and `document.url`. Publishing a new revision keeps the document's visibility.
@@ -0,0 +1,110 @@
1
+ ---
2
+ name: pageship-chart
3
+ description: Later step of pageship-docs: for a request to write or edit a document, load pageship-docs first; load this skill first only when the user names it. Pattern for charts in a Pageship HTML document, loaded by a pageship- kind skill before it draws a chart.
4
+ license: MIT
5
+ metadata:
6
+ version: "0.2.0"
7
+ ---
8
+
9
+ # Chart
10
+
11
+ A chart answers one question about the source's numbers at a glance. You draw it as inline SVG on an honest scale, with every value the reader needs printed on the page, never with a chart library or Mermaid.
12
+
13
+ Unless another pageship- skill loaded this one, start as [pageship-docs says](../pageship-docs/SKILL.md#starting-at-a-kind-or-pattern-skill).
14
+
15
+ ## 1. Pick the form from the question
16
+
17
+ Write down the question the reader brings to these numbers, in one sentence, such as "How did page load time change week by week?". A value the source lacks stays a gap in the chart and an open question.
18
+
19
+ | The reader asks | Form | Rules |
20
+ | --------------------------------------- | --------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
21
+ | How did it change over time? | Line chart for a level or rate; vertical bars for a count per period | Time runs left to right, one even step per period. A missing period keeps its place and breaks the line. |
22
+ | Which is largest, in what rank? | Horizontal bars, sorted by value, largest at the top | Category labels sit left of the bars. Catch-all groups such as "other" or "untagged" go last whatever their size. |
23
+ | What share of the whole? | One horizontal bar split into parts, for up to five parts; sorted bars of shares beyond | Only when the source says the parts don't overlap and add up to the whole. Print each share and the total. Shares come from the source's counts. |
24
+ | How are the values spread? | Histogram of counts per bin; a dot plot for up to 30 single values | Use the bins the source gives, in order. When bins differ in width, draw equal-width bars labelled with each range, and say so in the scale note. |
25
+ | How does one measure relate to another? | Scatter plot, one dot per item | Label each dot with its name when there are 12 dots or fewer. Draw a trend line or give a correlation figure only when the source gives one. Describe what the dots show; say that one measure drives the other only when the source does. |
26
+
27
+ Draw no pie, donut, 3D, radar or dual-axis chart. One chart holds at most four series. With more, draw small multiples: one small chart per series, side by side, on the same scale.
28
+
29
+ ## 2. Set an honest scale
30
+
31
+ - **Bars start at zero.** A bar's length is its value.
32
+ - **A line or scatter axis may start above zero** to show change. When it does, mark it twice: a break mark on the axis just above the origin (two short parallel slanted lines), and a scale note in the caption such as "The vertical axis starts at 40%."
33
+ - **Linear scales.** Use a log scale only when values span more than a hundredfold, all above zero. Mark it in the axis title ("log scale") and in the scale note.
34
+ - **Even ticks.** Three to six ticks at round values (multiples of 1, 2, 2.5 or 5 times a power of ten), with faint gridlines.
35
+ - **One scale per comparison.** Charts the reader compares side by side share the same axes.
36
+ - **Convert, then label in the source's terms.** Plot durations in one unit, such as hours, and write the labels as the source writes them ("1 h 05 min").
37
+
38
+ ## 3. Label the data
39
+
40
+ A reader who sees only the figure can read it:
41
+
42
+ - **A caption** in `<figcaption>` saying what is measured, the unit, the period or range, and the source as it names itself, such as "Median page load time by week, 6 January to 30 March 2025, in seconds. Source: browser monitoring export.", plus the scale note. It may state the source's own reading of the data, attributed as the source attributes it.
43
+ - **Axis titles** with units, and tick labels on both axes.
44
+ - **Printed values.** Write the value on or beside every bar, at the end of every line, and at every point the text mentions. When a line has too many points to label, put its values in a table next to the chart.
45
+ - **Direct labels.** Name each series at the end of its line or beside its bars instead of in a legend.
46
+ - **The kind of number.** Measured values are solid. Targets are a dashed line labelled "Target" with its value. Estimates and forecasts are dashed or outlined, and labelled with their kind.
47
+ - **Sample data.** When the user asked for sample or illustrative data, print "Sample data" inside the SVG, at the top of the chart, and start the caption with "Sample data, not measured:".
48
+
49
+ ## 4. Draw the SVG
50
+
51
+ Write static SVG markup with the coordinates computed as you write. For each value `v` on an axis from `min` to `max` drawn across `length` pixels from `start`, the position is `start + (v - min) / (max - min) × length`. On a log scale, use `start + (log v - log min) / (log max - log min) × length`. On a vertical axis, subtract from the axis's bottom edge.
52
+
53
+ ```html
54
+ <figure class="chart">
55
+ <div class="scroll">
56
+ <svg
57
+ width="640"
58
+ height="300"
59
+ viewBox="0 0 640 300"
60
+ role="img"
61
+ aria-labelledby="deploys-t deploys-d"
62
+ >
63
+ <title id="deploys-t">Deploys in March by team</title>
64
+ <desc id="deploys-d">Payments 48, search 31, mobile 22, other 9.</desc>
65
+ <!-- gridlines and axes -->
66
+ <g class="series" data-series="Deploys">
67
+ <rect x="120" y="40" width="48" height="200"><title>Payments: 48 deploys</title></rect>
68
+ <!-- its other marks, value labels and direct label -->
69
+ </g>
70
+ </svg>
71
+ </div>
72
+ <figcaption>
73
+ Deploys to production in March 2025, a count per team. Source: release log.
74
+ </figcaption>
75
+ </figure>
76
+ ```
77
+
78
+ - Give the SVG a fixed `width` and `height` equal to its `viewBox`, at most 680 wide, inside `<div class="scroll">`.
79
+ - Use 14px text for labels and values.
80
+ - Wrap each series in `<g class="series" data-series="…">`, named as its direct label names it, holding its marks, value labels, direct label and its own target or forecast line, which takes `class="target"` or `class="forecast"`. A chart of one series has one.
81
+ - Colour it as [Colours](#colours) says.
82
+ - Leave margins inside the `viewBox` for axis titles, tick labels and value labels. No label touches another label, a line or a bar. When category names are long, use horizontal bars rather than slanting the text.
83
+ - The `<desc>` lists the values plotted, or names the table beside the chart that holds them.
84
+ - Give each data mark, a bar or a point's marker, a `<title>` naming its series, category and exact value as the page or the chart's table prints them, such as `<title>Payments, March: 48 deploys</title>`. Add [the pointer states](../pageship-interaction/references/pointer.md), which show it on hover, focus and tap.
85
+
86
+ Buttons that highlight or filter series show every series by default.
87
+
88
+ ## Colours
89
+
90
+ Colour the chart in the stylesheet, with `fill` and `stroke`, from [the look's colour variables](../pageship-docs/references/design.md#the-looks-colour-variables) and no other colour:
91
+
92
+ | Part | Variable |
93
+ | ---------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
94
+ | Each series' data marks, and its target or forecast line | `--series-1` to `--series-4`: number the series once per document, in the order they first appear |
95
+ | The series a chart's question is about, or the focus mark of a one-series chart | `--accent`, in that chart only |
96
+ | Marks the source gives a status, by [the design rules' statuses](../pageship-docs/references/design.md#the-looks-colour-variables) | `--good`, `--warn` or `--bad`, in place of the series colour, in a `<g data-status="…">` holding the mark and a `<text class="status">` naming the rating, such as "Breach" |
97
+ | Gridlines | `--line` |
98
+ | Axes, axis titles, ticks and tick labels | `--muted` |
99
+ | Direct labels, printed values and other text | `--fg` |
100
+
101
+ Colour never carries meaning alone: a series also differs by its direct label, line style or marker shape. Text stays `--fg` or `--muted`, because the series colours meet only the 3:1 marks need.
102
+
103
+ ## Check
104
+
105
+ - Take the largest and the smallest value on each chart and confirm, from the coordinates, that each sits where the scale puts it.
106
+ - Confirm the same for every reference line and bracket, such as a target or a period marker. On an axis of bins, a threshold sits on the boundary between the two bins it separates.
107
+
108
+ ## Hand over
109
+
110
+ List any value you derived, such as a share or a unit conversion.
@@ -0,0 +1,113 @@
1
+ ---
2
+ name: pageship-code-block
3
+ description: Later step of pageship-docs: for a request to write or edit a document, load pageship-docs first; load this skill first only when the user names it. Pattern for code in a Pageship HTML document, such as source code, commands, configuration or logs, loaded by a pageship- kind skill before the first code block.
4
+ license: MIT
5
+ metadata:
6
+ version: "0.2.0"
7
+ ---
8
+
9
+ # Code block
10
+
11
+ A code block shows the few lines of code the text is about and names where they come from. You highlight it while you write, so the page loads no highlighter.
12
+
13
+ Unless another pageship- skill loaded this one, start as [pageship-docs says](../pageship-docs/SKILL.md#starting-at-a-kind-or-pattern-skill).
14
+
15
+ ## 1. Choose the lines
16
+
17
+ - Show the lines the text talks about: the statement, function or config section that carries the point, plus only the lines a reader needs to place it.
18
+ - A block holds at most 25 lines. For more, cut lines or split it into two blocks with a sentence between them.
19
+ - A whole file appears only when it is 25 lines or fewer and the text discusses every line, never just because the request points to it.
20
+ - Cut whole lines only, and mark each cut with one comment line in the block's language, such as `// …` or `# …`.
21
+ - To show a change, use a `diff` block of the changed lines with at most three unchanged lines around each change, and only when the source gives both versions or a diff. When it gives only the new version, show that and say in prose what changed, as the source says it.
22
+ - A command the reader runs gets its own block. Add its output only when the source gives it and the text discusses it.
23
+
24
+ ## 2. Copy the code exactly
25
+
26
+ - Every line comes from the source as written: the same names, indentation, comments and line breaks. Don't fix, reformat, rename, complete, translate or wrap code. A long line stays one line.
27
+ - Code the source doesn't contain doesn't appear. When the reader would need code the source doesn't give, such as how to run something, write an open question. Write an example of your own only when the user asks for one, with "Illustrative" in its label.
28
+ - Prose about a block says what the source says about the code, or what its lines plainly do. Describe the behaviour a change replaced or the failure it prevents only in the source's words.
29
+ - Replace a secret, such as a token, password or private key, with `REDACTED`, and say so in the label.
30
+
31
+ ## 3. Highlight each block
32
+
33
+ Run [highlight.mjs](references/highlight.mjs) with Node 20 or later. Give it the block's Shiki language ID, such as `typescript`, `python`, `bash` or `diff`, or `text` for program output and languages Shiki lacks. Pass the block's lines on standard input:
34
+
35
+ ```sh
36
+ node <this skill's folder>/references/highlight.mjs typescript <<'EOF'
37
+ export function cartTotal(items: Item[]): number {
38
+ // …
39
+ }
40
+ EOF
41
+ ```
42
+
43
+ It prints the block's `<pre>`, escaped and coloured for light and dark. Paste it as printed; to change a block, change its lines and run the script again. The first run installs Shiki 4.4.3 with npm into the temporary folder; to skip that, set `PAGESHIP_SHIKI` to a folder whose `node_modules` already holds Shiki 4.4.3.
44
+
45
+ Without Node, or when the script says it could not install Shiki, write the block as an escaped `<pre tabindex="0"><code>`, with the first line right after `<code>`, and say in the hand-over that highlighting was skipped and why.
46
+
47
+ ## 4. Write the markup
48
+
49
+ <!-- prettier-ignore -->
50
+ ```html
51
+ <figure class="code">
52
+ <figcaption>
53
+ <span class="code-name">src/cart/total.ts</span>
54
+ <span class="code-meta">TypeScript · lines 12–19</span>
55
+ </figcaption>
56
+ <pre class="shiki ..." style="..." tabindex="0"><code>...</code></pre>
57
+ </figure>
58
+ ```
59
+
60
+ - **The label** names where the code comes from: the file path, with the line range when you read the file. Code from no file is named by what it is, such as "Command", "Output" or "Query". The meta part names the language, and adds "Illustrative" or "secret redacted" when they apply.
61
+ - Add no copy button and no line-number gutter.
62
+
63
+ Add this to the stylesheet, after the look's own rules. A highlighted block keeps its theme's background.
64
+
65
+ ```css
66
+ figure.code {
67
+ margin: 1.5rem 0;
68
+ min-width: 0;
69
+ max-width: 100%;
70
+ }
71
+ figure.code figcaption {
72
+ display: flex;
73
+ flex-wrap: wrap;
74
+ gap: 0.25rem 0.75rem;
75
+ margin-bottom: 0.375rem;
76
+ overflow-wrap: anywhere;
77
+ }
78
+ .code-name {
79
+ font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
80
+ color: var(--fg);
81
+ }
82
+ figure.code pre {
83
+ margin: 0;
84
+ max-width: 100%;
85
+ overflow-x: auto;
86
+ line-height: 1.5;
87
+ tab-size: 4;
88
+ border: 1px solid var(--line);
89
+ }
90
+ @media screen and (prefers-color-scheme: dark) {
91
+ .shiki,
92
+ .shiki span {
93
+ color: var(--shiki-dark) !important;
94
+ }
95
+ .shiki {
96
+ background-color: var(--shiki-dark-bg) !important;
97
+ }
98
+ }
99
+ @media print {
100
+ figure.code pre {
101
+ overflow: visible;
102
+ white-space: pre-wrap;
103
+ overflow-wrap: anywhere;
104
+ }
105
+ }
106
+ ```
107
+
108
+ A block inside a grid or flex item needs `min-width: 0` on that item too, or a long line widens the page.
109
+
110
+ ## Check
111
+
112
+ - A distinctive line of each block, other than an "Illustrative" one, matches the source character for character.
113
+ - In dark mode, highlighted blocks show the dark theme.