@hajimism/dek 0.3.3 → 0.5.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.
- package/CHANGELOG.md +136 -0
- package/README.ja.md +2 -2
- package/README.md +2 -2
- package/package.json +5 -3
- package/skills/dek/SKILL.md +10 -3
- package/skills/dek-design/SKILL.md +42 -0
- package/src/cli/address.ts +95 -18
- package/src/cli/build.ts +2 -2
- package/src/cli/check.ts +2 -1
- package/src/cli/commands.ts +57 -19
- package/src/cli/contract.ts +58 -4
- package/src/cli/files.ts +2 -5
- package/src/cli/flags.ts +1 -1
- package/src/cli/format.ts +5 -4
- package/src/cli/goto.ts +44 -11
- package/src/cli/init.ts +10 -5
- package/src/cli/lint.ts +36 -16
- package/src/cli/ls.ts +5 -1
- package/src/cli/main.ts +51 -14
- package/src/cli/new.ts +28 -8
- package/src/cli/pptx.ts +9 -4
- package/src/cli/ref.ts +92 -9
- package/src/cli/result.ts +47 -6
- package/src/cli/scope.ts +57 -29
- package/src/cli/shot.ts +78 -6
- package/src/cli/show.ts +15 -2
- package/src/cli/text.ts +88 -11
- package/src/cli/theme.ts +58 -10
- package/src/cli/tty.ts +16 -2
- package/src/cli/voice.ts +15 -9
- package/src/core/alignment.ts +320 -0
- package/src/core/annotation-rows.ts +16 -4
- package/src/core/annotations.ts +19 -1
- package/src/core/assets.ts +18 -10
- package/src/core/attribute-value.ts +188 -0
- package/src/core/build.ts +3 -3
- package/src/core/config.ts +61 -12
- package/src/core/css-scan.ts +173 -39
- package/src/core/css-transform.ts +57 -11
- package/src/core/css.ts +19 -13
- package/src/core/diagnostic.ts +5 -1
- package/src/core/escape.ts +43 -0
- package/src/core/foreign-text.ts +138 -0
- package/src/core/github.ts +1 -0
- package/src/core/html-entities.ts +318 -0
- package/src/core/html-scan.ts +49 -27
- package/src/core/html.ts +21 -15
- package/src/core/line-break.ts +275 -0
- package/src/core/lint/asset-refs.ts +50 -8
- package/src/core/lint/files.ts +30 -5
- package/src/core/lint/keys.ts +7 -3
- package/src/core/lint/slide-html.ts +24 -19
- package/src/core/lint/slide-script.ts +7 -5
- package/src/core/mv.ts +57 -27
- package/src/core/order.ts +14 -0
- package/src/core/pack.ts +2 -2
- package/src/core/path.ts +8 -2
- package/src/core/playwright-module.d.ts +13 -1
- package/src/core/playwright-motion.ts +1 -0
- package/src/core/playwright-sheet.ts +1 -0
- package/src/core/playwright-visual.ts +207 -30
- package/src/core/playwright.ts +279 -44
- package/src/core/pptx-package.ts +461 -33
- package/src/core/pptx-paint.ts +1168 -0
- package/src/core/pptx-plan.ts +879 -0
- package/src/core/pptx-text.ts +204 -47
- package/src/core/pptx-theme.ts +222 -0
- package/src/core/pptx.ts +56 -8
- package/src/core/prose.ts +23 -0
- package/src/core/pseudo-text.ts +32 -10
- package/src/core/ref-name.ts +52 -8
- package/src/core/ref.ts +308 -54
- package/src/core/resolve.ts +23 -11
- package/src/core/rumdl.ts +51 -25
- package/src/core/safe-fs.ts +19 -2
- package/src/core/sandbox.ts +217 -0
- package/src/core/shot/morph.ts +1 -1
- package/src/core/shot/motion.ts +2 -3
- package/src/core/shot/still.ts +2 -2
- package/src/core/shot-cache.ts +26 -17
- package/src/core/slide-eval-worker.ts +1 -0
- package/src/core/slide-measure.ts +51 -1
- package/src/core/slide-script-eval.ts +12 -8
- package/src/core/slide-script.ts +114 -20
- package/src/core/spawn.ts +131 -32
- package/src/core/sync.ts +5 -14
- package/src/core/tar.ts +315 -0
- package/src/core/text-contrast.ts +2 -0
- package/src/core/toml-keys.ts +116 -51
- package/src/core/url-attributes.ts +27 -9
- package/src/core/visual-cache.ts +2 -0
- package/src/core/visual.ts +182 -24
- package/src/core/voice.ts +5 -6
- package/src/core/zod.ts +9 -1
- package/src/server/auth.ts +21 -0
- package/src/server/dev.ts +26 -7
- package/src/server/lock.ts +50 -7
- package/src/server/routes.ts +7 -2
- package/src/server/serial.ts +8 -2
- package/src/theme/default.css +4 -0
- package/src/video/bake.ts +6 -2
- package/src/video/mux.ts +27 -3
- package/src/video/recorder.ts +3 -2
- package/src/video/worker.ts +1 -0
- package/src/voice/engine.ts +81 -18
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,142 @@
|
|
|
2
2
|
|
|
3
3
|
Release notes for `@hajimism/dek`. From 0.1.0 on, release-please writes this file from the Conventional Commits on `main`.
|
|
4
4
|
|
|
5
|
+
## [0.5.0](https://github.com/hajimism/dek/compare/v0.4.0...v0.5.0) (2026-10-27)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### ⚠ BREAKING CHANGES
|
|
9
|
+
|
|
10
|
+
* **ref:** a dek.toml that pins a ref whose name holds a control character or a character a person cannot see no longer loads until that line is removed; `dekc pack` refuses a deck so named until its folder is renamed; and `dekc new` and `dekc init --deck` refuse such a name, which they took before. Every other name works as before.
|
|
11
|
+
* where Chromium's sandbox does not start, `dekc shot <ref>` fails until DEK_ALLOW_UNSANDBOXED=1 is set.
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
* **ref:** report the characters in a ref that a person cannot see ([5ca233e](https://github.com/hajimism/dek/commit/5ca233e186125e821f1341cc790636f26654274a))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* **build:** keep a minified stylesheet reading as its source where an escape meets a newline or a comment ([41fd1ba](https://github.com/hajimism/dek/commit/41fd1ba08abc63c8af1d9deb8e2b9d70bb5ceab5))
|
|
21
|
+
* **build:** minify a stylesheet into one that reads as its source does ([bdcffb9](https://github.com/hajimism/dek/commit/bdcffb9edaf7238b33bdf740dc4072c6f8cdaaa1))
|
|
22
|
+
* **cli:** at the project root, hint a command only for the decks that have what it names ([fe3f8fb](https://github.com/hajimism/dek/commit/fe3f8fb12c178a7d8bfcb40b4ed16b52d03a08ae))
|
|
23
|
+
* **cli:** hint `dekc ls` for a deck that is not there, not `dekc ls <it>` ([1ee4554](https://github.com/hajimism/dek/commit/1ee455439734f57eaf03c6c91fd78a9423f4812f))
|
|
24
|
+
* **cli:** name a ref by the ref in the hints about it ([e9d1a47](https://github.com/hajimism/dek/commit/e9d1a47fe282b766bed189212891f1aafcc38a94))
|
|
25
|
+
* **dev:** print a failure of the dev server's lint or voice run instead of dropping it ([14a8e8c](https://github.com/hajimism/dek/commit/14a8e8ceb75247d850407aeeef3bba56f5525a88))
|
|
26
|
+
* give up on a voice engine, a dev server, or a rumdl that never answers ([19023f2](https://github.com/hajimism/dek/commit/19023f2c3987c4e60f2fe7440d4e1d5369ec2f10))
|
|
27
|
+
* keep a file's mode when dek writes it anew ([085d7e8](https://github.com/hajimism/dek/commit/085d7e8e4be2895c975cd76668d4c7af91937d96))
|
|
28
|
+
* **lint:** list rumdl as skipped when what it printed is not SARIF ([74582e0](https://github.com/hajimism/dek/commit/74582e07153aeb77211083e87309cbe6214e8ba3))
|
|
29
|
+
* **lint:** name the path beside a stray space in DEK021's hint only when it is a plain word ([b030691](https://github.com/hajimism/dek/commit/b03069178ab6b318749c0296aca5fc916ebc2cec))
|
|
30
|
+
* **lint:** read a URL in DEK011 as the browser's URL parser reads it ([c0950a5](https://github.com/hajimism/dek/commit/c0950a59b6c25f1c561c101a07750b89c0a87283))
|
|
31
|
+
* **lint:** say to run lint --visual again after lint --visual fails ([a00da44](https://github.com/hajimism/dek/commit/a00da4437aadf6373a4e888213f26d6efdd7462a))
|
|
32
|
+
* **ls:** keep a ref's title, event, and date to one line, as AGENTS.md does ([af85b6e](https://github.com/hajimism/dek/commit/af85b6e8ef63175cfb3166465e533e6b361f166e))
|
|
33
|
+
* **mv:** write script.md, slides, and voice.toml whole, never over the old file ([a7a22b3](https://github.com/hajimism/dek/commit/a7a22b34a1fb073181966bec4a7c7e88b88757ce))
|
|
34
|
+
* print no color code a deck or a ref wrote, only dek's own ([27b6751](https://github.com/hajimism/dek/commit/27b6751eb48d84e2538983c618889f74389d5caa))
|
|
35
|
+
* read a pack's or a GitHub tarball's tar with dek's own reader, so it unpacks no more than was counted ([bdda596](https://github.com/hajimism/dek/commit/bdda596bf5974e6c30f5d273090327d0ed114a6b))
|
|
36
|
+
* read each attribute value as the browser does, its character references decoded ([65a58d1](https://github.com/hajimism/dek/commit/65a58d11497648690c539c8caa4bbe49c246a4c8))
|
|
37
|
+
* read the keys after an array or inline table written over several lines ([fa8f268](https://github.com/hajimism/dek/commit/fa8f2680bec36c3b092f5b7eef5749cd4146d64a))
|
|
38
|
+
* read url() and a string cut short by CR or FF where the browser does ([55296f2](https://github.com/hajimism/dek/commit/55296f2a8f04ffdea958b835132bc2ad4c8054d5))
|
|
39
|
+
* **ref:** keep a ref's names out of hints, and to one short line in messages ([67f7d19](https://github.com/hajimism/dek/commit/67f7d19268cb1032978d62a1a0fe1ec2a209197c))
|
|
40
|
+
* **ref:** refuse a pack whose deck's name holds a control character or one a person cannot see ([373f14f](https://github.com/hajimism/dek/commit/373f14f368057677c33d9c8bbaccc427e048d790))
|
|
41
|
+
* **sample:** set the note on why-dek's read-only card in ink ([586d09d](https://github.com/hajimism/dek/commit/586d09d7e706ae56b731ee9c5a4b6f1b03406d2e))
|
|
42
|
+
* say whenever Chromium draws without its sandbox, and draw a ref there only when asked ([293b3ff](https://github.com/hajimism/dek/commit/293b3ffd0fd12ff042831fc4816e96025d7336af))
|
|
43
|
+
* **server:** keep what the dev server serves out of other sites' pages and frames ([260b0f0](https://github.com/hajimism/dek/commit/260b0f081de5d9821312456abbec2849dfac7fd7))
|
|
44
|
+
* **shot:** send a ref's broken slide script to its author, not to lint ([c1045fa](https://github.com/hajimism/dek/commit/c1045faf8583ca61281b825811a172a72ec0bb6c))
|
|
45
|
+
* **show:** keep the name of keyframes written as a string in the theme excerpt ([072b078](https://github.com/hajimism/dek/commit/072b07848a2799f7d2e98f42962330c2e407bbee))
|
|
46
|
+
* **show:** say a slide is a ref's, and start a part on a line no file can write ([b6b2389](https://github.com/hajimism/dek/commit/b6b2389fe5cf8dfc9dac4fefa1eab88737d7075a))
|
|
47
|
+
* sort dict.toml, decks, and slide files the same way on every machine ([29a3f3c](https://github.com/hajimism/dek/commit/29a3f3c4c6073fbdc5808c9921d296fa8e4125cf))
|
|
48
|
+
* start every program dek runs with the environment as it is now ([ee6b319](https://github.com/hajimism/dek/commit/ee6b319d2772ff39ea82cf3dd8fd763d4fb130c8))
|
|
49
|
+
* stop a command at its timeout, even one that ignores SIGTERM or leaves a process behind ([3b05db7](https://github.com/hajimism/dek/commit/3b05db7ee9c17e68e5d580d744dc457856c29678))
|
|
50
|
+
* **tar:** leave AppleDouble names out, and number that record 27 ([c4fb0ef](https://github.com/hajimism/dek/commit/c4fb0efbb9cd0a73f5335f078fb9b08bca1d35ef))
|
|
51
|
+
* **video:** give up on an ffmpeg that never answers -version ([c0d3c6a](https://github.com/hajimism/dek/commit/c0d3c6a22d0dd8328782661ebc22384313d33487))
|
|
52
|
+
* **visual:** stop sending a DEK031 to theme.css when the theme alone was never measured ([b3321b3](https://github.com/hajimism/dek/commit/b3321b3302389743dd5f0606e2a6367e2635f14d))
|
|
53
|
+
* **voice:** stop waiting on a player that never ends after a say clip ([fc1082b](https://github.com/hajimism/dek/commit/fc1082bf3e8eb012bda822256fe51a067eb086b8))
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
### Refactoring
|
|
57
|
+
|
|
58
|
+
* write the link preview image and remove the dev server's lock through safe-fs ([3ae94c8](https://github.com/hajimism/dek/commit/3ae94c8db6ae9bef4243bec3cc334e1a4a2b9e11))
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
### Documentation
|
|
62
|
+
|
|
63
|
+
* **adr:** keep a ref's words out of dek's hints, and mark what a ref wrote wherever dek prints it ([e4f0787](https://github.com/hajimism/dek/commit/e4f07878aee0f0f887484b800778324a55e0f97d))
|
|
64
|
+
* **adr:** number the --json contract record 31 ([8108f37](https://github.com/hajimism/dek/commit/8108f3770b3c2b24efb57b2ed1064949a998e95b))
|
|
65
|
+
* **adr:** number the fast-check record 26, where this stack adds it ([389948e](https://github.com/hajimism/dek/commit/389948e6e8ef79842d8b429fac5e2d8e5d2ddeb2))
|
|
66
|
+
* **adr:** number the ref-words record 30, and point it at the trust record ([6925755](https://github.com/hajimism/dek/commit/692575572ab5a235ac1256c7b7b11e31a4ddc01f))
|
|
67
|
+
* **adr:** number the sandbox record 29, and point it at the trust record ([e082487](https://github.com/hajimism/dek/commit/e08248711777c3acabd8ac46c1c8a080302de961))
|
|
68
|
+
* **adr:** number the trust record 28, after the records already on this branch ([7a7fbd8](https://github.com/hajimism/dek/commit/7a7fbd8b9cb6f18af2d27f26a1fb962c3e85f30a))
|
|
69
|
+
* **adr:** read a pack's or a repository's tar with dek's own reader ([ba896c8](https://github.com/hajimism/dek/commit/ba896c84daec4a39fdc5d7fdd34c1cf5ccb52394))
|
|
70
|
+
* **adr:** read every attribute value as the browser does ([6a1c698](https://github.com/hajimism/dek/commit/6a1c698fbc74da129c034f175063d8c99a83f9bc))
|
|
71
|
+
* **adr:** say what dek does where Chromium's sandbox cannot start ([f2f940a](https://github.com/hajimism/dek/commit/f2f940ad4c0a216f9f0ec0085da72cfd15414282))
|
|
72
|
+
* **adr:** say whom dek trusts, and what each of them may make it do ([8f26099](https://github.com/hajimism/dek/commit/8f260990674b3c3105b40b276f9e90c6e013e1db))
|
|
73
|
+
* pass the suite timeout on every bun test line in CONTRIBUTING ([6c7182c](https://github.com/hajimism/dek/commit/6c7182cab0564f91088be06b5209c32b6f191efa))
|
|
74
|
+
* say how dek keeps a ref's words apart from its own ([756ba7c](https://github.com/hajimism/dek/commit/756ba7ca74ff05cbd109ef0eab270dea92c52b78))
|
|
75
|
+
* say how long dek waits on rumdl, a voice engine, and the dev server, and how large a ref may be ([e196cd8](https://github.com/hajimism/dek/commit/e196cd81ad83cd90286a91977258bb7c0882eaee))
|
|
76
|
+
* say lint reads an attribute's value and URL as the browser does ([4c67184](https://github.com/hajimism/dek/commit/4c671849309e7ff8015341862b9fc8ec860d0cb7))
|
|
77
|
+
|
|
78
|
+
## [0.4.0](https://github.com/hajimism/dek/compare/v0.3.4...v0.4.0) (2026-10-27)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
### ⚠ BREAKING CHANGES
|
|
82
|
+
|
|
83
|
+
* **theme:** `dekc theme --json` lists in `layouts` only layouts whose names are plain words: letters, marks, and digits of any script and `@%+=:,./_-`, not starting with `=`. A layout whose name holds anything else, such as a space, a quote, `$`, `;`, or a backtick, is no longer in `layouts`; `unprintedLayouts`, present only when there are some, says how many were left out. `dekc theme <layout>` still prints such a layout's example.
|
|
84
|
+
* **ref:** a dek.toml whose [refs] pins a deck name with any other character, starting with a dash, not in NFC, or longer than 64 characters or 200 bytes, such as `owner/repo/talk(1)` or `file/a+b`, no longer loads. Delete the line the error points at, and for a pack its packs/<deck>.tgz and refs/file/<deck>, then pin the deck again under a name a ref can carry.
|
|
85
|
+
|
|
86
|
+
### Bug Fixes
|
|
87
|
+
|
|
88
|
+
* **annotations:** show a deck, slide, or beat that is no plain word as a placeholder in the notes ([3b04e89](https://github.com/hajimism/dek/commit/3b04e89dc22f9ea421919c920594f53a9c02d3be))
|
|
89
|
+
* **cli:** say once where to find a deck's name a retyped command leaves as <deck> ([d4a57d9](https://github.com/hajimism/dek/commit/d4a57d9f7836b2ba2433dc634a136bb7e97be509))
|
|
90
|
+
* **config:** show a key that is no plain word as <key> in an error ([22476a7](https://github.com/hajimism/dek/commit/22476a712ecf0ee4e3c552b1e0fe6f35ac10cacf))
|
|
91
|
+
* **dev:** read .dek/server.json only as the dev server writes it ([c402cb6](https://github.com/hajimism/dek/commit/c402cb6282783425611274fbc0337cd6652add7e))
|
|
92
|
+
* **dev:** read the lock a dev server on port 80 writes ([665e0e2](https://github.com/hajimism/dek/commit/665e0e237c3a639a45fa36dc14ed8bd2e7ad9168))
|
|
93
|
+
* keep reads, writes, and suggested commands inside what the project and dek wrote ([23a667d](https://github.com/hajimism/dek/commit/23a667d199ee5f0b34040c4c33f0c0bcfd47f819))
|
|
94
|
+
* **lint:** name a remote file in DEK020's hint only when it is a plain word ([fb77d02](https://github.com/hajimism/dek/commit/fb77d028db1bb38bea6b43695838d52776b192a7))
|
|
95
|
+
* **lint:** name a slide or asset file in a hint only when it is a plain word ([eeb240c](https://github.com/hajimism/dek/commit/eeb240c418b615067bd66ff45ac6b70361d3bd1b))
|
|
96
|
+
* **lint:** show an unknown key that is no plain word as <key> in DEK008 ([f950def](https://github.com/hajimism/dek/commit/f950def7f80f06da46bd8c913ae84c8c849d5ddf))
|
|
97
|
+
* never follow a link under refs/ when writing a snapshot ([0c843ea](https://github.com/hajimism/dek/commit/0c843ea4193270dd1cc0fde4a04768e210efd911))
|
|
98
|
+
* never write or remove a pack's copy through a link under packs/ ([95980a6](https://github.com/hajimism/dek/commit/95980a631e90ee97eda24784ded50b042111512d))
|
|
99
|
+
* quote every name in a command dek suggests ([d1e608d](https://github.com/hajimism/dek/commit/d1e608d5676e46b7947bd5f43a3315269fd27773))
|
|
100
|
+
* read a project's files only through links that stay inside it ([7ae3815](https://github.com/hajimism/dek/commit/7ae38152eadd6f58d67034169ade9dd749038002))
|
|
101
|
+
* **ref:** accept only letters, digits, dots, dashes, and underscores in a ref's deck name ([1b430e1](https://github.com/hajimism/dek/commit/1b430e1ea3d0f66af2642a5f257af1cefcae3ac0))
|
|
102
|
+
* **ref:** fold names as macOS does when telling whether two refs share a folder ([fdb32ee](https://github.com/hajimism/dek/commit/fdb32ee103facc5a661f20dabf79fe8f91ae48cd))
|
|
103
|
+
* **ref:** refuse a pin whose folders another ref already takes ([0d550d8](https://github.com/hajimism/dek/commit/0d550d897b0cdad86ac3de181bf7fd031061bd66))
|
|
104
|
+
* refuse a decks folder that links out of the project ([83f2ff0](https://github.com/hajimism/dek/commit/83f2ff00079893b8e2dbb2fc5d5b7588435aa4dd))
|
|
105
|
+
* refuse to serve or write inside a ref, as every other command does ([665b2de](https://github.com/hajimism/dek/commit/665b2de7a3e6aa3b67ce6140d3eb2a15fb398ee6))
|
|
106
|
+
* serve a deck's assets only from inside the project ([86743cf](https://github.com/hajimism/dek/commit/86743cf731d97f664e95b75f1441dd238f0eeb11))
|
|
107
|
+
* take a folder for a ref only where dek wrote one, and name it from there ([62cc8df](https://github.com/hajimism/dek/commit/62cc8df0a509a99a55d9db7698683bc3be5523d4))
|
|
108
|
+
* **theme:** leave layouts whose names are no plain word out of --json ([625f6d3](https://github.com/hajimism/dek/commit/625f6d3dab0dfe16dacb272e371b551214621a86))
|
|
109
|
+
* **theme:** print only layout names that are plain words ([62b15d1](https://github.com/hajimism/dek/commit/62b15d18afb91d6adbc2641376d9ca899cb6bf20))
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
### Documentation
|
|
113
|
+
|
|
114
|
+
* say dek follows no link under packs/ either ([5a11b2c](https://github.com/hajimism/dek/commit/5a11b2ca9960a134e261f09f80408fc770aa44da))
|
|
115
|
+
|
|
116
|
+
## [0.3.4](https://github.com/hajimism/dek/compare/v0.3.3...v0.3.4) (2026-10-27)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
### Features
|
|
120
|
+
|
|
121
|
+
* **pptx:** lay out boxes, pictures, text, the theme, and backgrounds as PowerPoint's own ([#27](https://github.com/hajimism/dek/issues/27)) ([eb854e9](https://github.com/hajimism/dek/commit/eb854e9835508792d3e8cfb9dd4046e8750dab7f))
|
|
122
|
+
* **skills:** teach the review in the browser, and add an optional dek-design skill ([2c18b0e](https://github.com/hajimism/dek/commit/2c18b0e339160fb03ca6ce3915b89e37d82c9522))
|
|
123
|
+
* **skills:** teach the review in the browser, and add an optional dek-design skill ([1b04394](https://github.com/hajimism/dek/commit/1b04394023a239706a2fa29d168811e1a1be05d2))
|
|
124
|
+
* **visual:** report awkward line breaks and edges a few pixels off (DEK035, DEK036) ([#28](https://github.com/hajimism/dek/issues/28)) ([ce75fc1](https://github.com/hajimism/dek/commit/ce75fc14937d76ab457298a5aca9116a0fe3778e))
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
### Bug Fixes
|
|
128
|
+
|
|
129
|
+
* refuse a slide script's imports before Bun reads it, so none runs while dek compiles ([2752356](https://github.com/hajimism/dek/commit/275235647869f1e0a040c080476141d3aaa1aaa6))
|
|
130
|
+
* refuse a slide script's imports before Bun reads it, so none runs while dek compiles ([198930c](https://github.com/hajimism/dek/commit/198930c1d41639cc9943f36a3a187ff6eab0f364))
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
### Documentation
|
|
134
|
+
|
|
135
|
+
* **adr:** keep dependency code away from the tokens that publish ([103f17c](https://github.com/hajimism/dek/commit/103f17cebb37dd1750caa4cc242acedf55703809))
|
|
136
|
+
* **adr:** renumber the PPTX records after the line-break ones ([ca43352](https://github.com/hajimism/dek/commit/ca4335267b6eeed7131c4123a8a543a230d65875))
|
|
137
|
+
* **adr:** renumber the PPTX records after the line-break ones ([bef6e12](https://github.com/hajimism/dek/commit/bef6e12915ac301843297fb972cf36288bbf612c))
|
|
138
|
+
* **adr:** ship an optional design skill and raise the official skill's floor to 0.2.2 ([6f39dd1](https://github.com/hajimism/dek/commit/6f39dd1e8234297cb0fb72d93722a419d1921f23))
|
|
139
|
+
* name the optional dek-design skill, and the review the official skill teaches ([6908fa1](https://github.com/hajimism/dek/commit/6908fa195e16d79c75d5b77cda72f708798de34c))
|
|
140
|
+
|
|
5
141
|
## [0.3.3](https://github.com/hajimism/dek/compare/v0.3.2...v0.3.3) (2026-10-21)
|
|
6
142
|
|
|
7
143
|
|
package/README.ja.md
CHANGED
|
@@ -44,7 +44,7 @@ bunx dekc build # 3. dist/2026-04-vite.html — トーク全体がこの 1
|
|
|
44
44
|
|
|
45
45
|
台本を書いて `dekc` を叩けば、HTML を一行も書かずに同梱テーマで発表できます。
|
|
46
46
|
|
|
47
|
-
エージェントと作るなら、公式スキルを `npx skills add hajimism/dek` で、Claude Code なら `/plugin marketplace add hajimism/dek` と `/plugin install dek@dek`
|
|
47
|
+
エージェントと作るなら、公式スキルを `npx skills add hajimism/dek --skill dek` で、Claude Code なら `/plugin marketplace add hajimism/dek` と `/plugin install dek@dek` で入れてください。`dek-design` も、同じ方法で選んで入れられます。プロジェクトの外にいるエージェントは [llms.txt](https://hajimism.github.io/dek/llms.txt) から始められます。[AI エージェントと作る](https://hajimism.github.io/dek/ja/guide/ai.html)を参照してください。
|
|
48
48
|
|
|
49
49
|
続きは [はじめる](https://hajimism.github.io/dek/ja/guide/getting-started.html)へ。通しで 1 本作るなら [チュートリアル](https://hajimism.github.io/dek/ja/guide/tutorial.html)。コマンドの一覧は [CLI リファレンス](https://hajimism.github.io/dek/ja/reference/cli.html)にあります。
|
|
50
50
|
|
|
@@ -64,7 +64,7 @@ bun run dev # または bun run lint:visual / bun run build
|
|
|
64
64
|
```bash
|
|
65
65
|
bun install
|
|
66
66
|
bunx playwright install chromium # 最初に一度。実ブラウザを動かすテストに使う
|
|
67
|
-
bun test --watch
|
|
67
|
+
bun test --watch --timeout=20000
|
|
68
68
|
bun run typecheck
|
|
69
69
|
bun run check # Biome の format + lint
|
|
70
70
|
bun run docs:dev # VitePress
|
package/README.md
CHANGED
|
@@ -44,7 +44,7 @@ bunx dekc build # 3. dist/2026-04-vite.html — the whole talk in one file
|
|
|
44
44
|
|
|
45
45
|
Write the script, run `dekc`, and you can present with the bundled theme without writing a line of HTML.
|
|
46
46
|
|
|
47
|
-
Working with an agent? Install the official skill with `npx skills add hajimism/dek`, or in Claude Code with `/plugin marketplace add hajimism/dek` and `/plugin install dek@dek`; an agent outside any project can start from [llms.txt](https://hajimism.github.io/dek/llms.txt). See [Working with AI Agents](https://hajimism.github.io/dek/guide/ai.html).
|
|
47
|
+
Working with an agent? Install the official skill with `npx skills add hajimism/dek --skill dek`, or in Claude Code with `/plugin marketplace add hajimism/dek` and `/plugin install dek@dek`; `dek-design` is an optional skill installed the same way; an agent outside any project can start from [llms.txt](https://hajimism.github.io/dek/llms.txt). See [Working with AI Agents](https://hajimism.github.io/dek/guide/ai.html).
|
|
48
48
|
|
|
49
49
|
Continue with [Getting Started](https://hajimism.github.io/dek/guide/getting-started.html), or build a real deck end to end in the [Tutorial](https://hajimism.github.io/dek/guide/tutorial.html). Every command is listed in the [CLI reference](https://hajimism.github.io/dek/reference/cli.html).
|
|
50
50
|
|
|
@@ -64,7 +64,7 @@ bun run dev # or bun run lint:visual / bun run build
|
|
|
64
64
|
```bash
|
|
65
65
|
bun install
|
|
66
66
|
bunx playwright install chromium # once, for the tests that drive a real browser
|
|
67
|
-
bun test --watch
|
|
67
|
+
bun test --watch --timeout=20000
|
|
68
68
|
bun run typecheck
|
|
69
69
|
bun run check # Biome format + lint
|
|
70
70
|
bun run docs:dev # VitePress
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hajimism/dek",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "A build system for talks.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Hajime Nakagawa (https://github.com/hajimism)",
|
|
@@ -43,8 +43,8 @@
|
|
|
43
43
|
"ai-agents"
|
|
44
44
|
],
|
|
45
45
|
"scripts": {
|
|
46
|
-
"test": "bun test --parallel=4",
|
|
47
|
-
"test:watch": "bun test --watch",
|
|
46
|
+
"test": "bun test --parallel=4 --timeout=20000",
|
|
47
|
+
"test:watch": "bun test --watch --timeout=20000",
|
|
48
48
|
"typecheck": "tsc --noEmit",
|
|
49
49
|
"knip": "knip",
|
|
50
50
|
"schema": "bun scripts/cli-schema.ts",
|
|
@@ -64,9 +64,11 @@
|
|
|
64
64
|
"@biomejs/biome": "2.5.15",
|
|
65
65
|
"@happy-dom/global-registrator": "21.0.1",
|
|
66
66
|
"@types/bun": "^1.4.2",
|
|
67
|
+
"fast-check": "4.10.2",
|
|
67
68
|
"happy-dom": "21.0.1",
|
|
68
69
|
"knip": "6.41.0",
|
|
69
70
|
"playwright": "^1.63.0",
|
|
71
|
+
"publint": "0.3.25",
|
|
70
72
|
"typescript": "^7.0.2",
|
|
71
73
|
"vitepress": "^1.6.4"
|
|
72
74
|
},
|
package/skills/dek/SKILL.md
CHANGED
|
@@ -16,7 +16,7 @@ dek builds a talk from its script. `script.md` holds what will be said, in order
|
|
|
16
16
|
|
|
17
17
|
## First, ask the dek you have
|
|
18
18
|
|
|
19
|
-
1. `bunx dekc --version` and `bunx dekc help --agent`: every command and flag of the dek installed in this project. This file names few on purpose; use only what that list shows.
|
|
19
|
+
1. `bunx dekc --version` and `bunx dekc help --agent`: every command and flag of the dek installed in this project. This file names few on purpose; use only what that list shows. It is written for dek 0.2.2 or newer; with an older one, follow only that list and `AGENTS.md`.
|
|
20
20
|
2. Read dek's block in `AGENTS.md`. dek rewrites it for the installed version: the conventions lint checks, how to check a slide, and what to do before reporting a deck as done. Follow it as written.
|
|
21
21
|
3. In the deck, `bunx dekc theme`: the classes, tokens, and layouts this deck's theme defines, and `bunx dekc theme <layout>` for a layout's markup. Use nothing else.
|
|
22
22
|
|
|
@@ -39,6 +39,13 @@ A hint that sends a fix to `theme.css` means every slide of the deck shares the
|
|
|
39
39
|
- You have looked at `bunx dekc shot --sheet` and judged the deck's balance.
|
|
40
40
|
- Say what you could not judge, such as the argument and how the timing feels when spoken, and hand it back to the author. Passing lint means nothing measurable is wrong, not that the talk is good.
|
|
41
41
|
|
|
42
|
-
## When the human
|
|
42
|
+
## When the human reviews the deck
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
The human sees what lint cannot. Let them point at it:
|
|
45
|
+
|
|
46
|
+
1. Start the dev server in the background, since it keeps running: `bunx dekc <deck> --port <free port>`, or your harness's preview tool if it has one.
|
|
47
|
+
2. Give them the URL and ask them to press `a`, click what they want changed, write a note, and tell you when they are done. They may not know dek: name the keys, not the commands.
|
|
48
|
+
3. `bunx dekc annotations <deck> --json`, and fix every note. Shoot the slide again with `bunx dekc shot <slug>` and compare it with the note's `shot`. Tell them in short what you changed.
|
|
49
|
+
4. Ask them to look again, until they say the deck is done. Stop the dev server you started.
|
|
50
|
+
|
|
51
|
+
Leave `dekc annotations clear` to the human. If they marked beats while rehearsing, `AGENTS.md` says how to read those too.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dek-design
|
|
3
|
+
description: Make dek slides that read at a glance - a heading that states a claim, one focal point, and no visual difference without a meaning. Use when writing or reviewing the look of slides in a dek deck, or when a deck lints clean but still looks off.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# dek-design
|
|
7
|
+
|
|
8
|
+
The audience sees a slide, holds it in mind, then understands it. Make each step cost as little as it can. Lint measures what a rule can decide, such as overflow and contrast; this skill is for what it cannot. Use only the classes, tokens, and layouts `bunx dekc theme` lists.
|
|
9
|
+
|
|
10
|
+
## Before you start
|
|
11
|
+
|
|
12
|
+
- Projected or read: a talk is spoken, so the words live in `script.md` and a slide shows what the voice cannot. A deck sent to be read alone needs sentences that stand without the speaker.
|
|
13
|
+
- What the audience knows: do not use a term they do not know. If you must, tie it to something they do.
|
|
14
|
+
|
|
15
|
+
## One slide
|
|
16
|
+
|
|
17
|
+
- The `##` heading is the slide's claim, in one sentence: "Builds fail on cold caches", not "Problems". Read in order, the headings tell the whole talk.
|
|
18
|
+
- The body is the evidence for the heading. Show it as a figure, a chart, or a short table where you can.
|
|
19
|
+
- Keep about four groups on a slide at most. With more, nest them or split the slide.
|
|
20
|
+
|
|
21
|
+
## How it looks
|
|
22
|
+
|
|
23
|
+
- One thing stands out most on each slide, and it is the main point. Emphasis used everywhere is emphasis nowhere.
|
|
24
|
+
- Change color, type, or layout only when the meaning changes; the audience looks for a reason in every change, so never vary for variety. Mark sections with one layout used the same way each time.
|
|
25
|
+
- When things differ, make them differ clearly. A small difference is not seen as one.
|
|
26
|
+
- Line things up. Items side by side share their top, their bottom, and the line their text starts on; a row of cards is one height even when one holds less. Items stacked share their left edge. An edge a little off reads as a mistake, not a choice, and a shot shows it where markup does not.
|
|
27
|
+
- What sits close, aligns, or shares a color reads as one group. Do not set items of different rank as a row of equal cards.
|
|
28
|
+
- Position means something: time and steps run left to right, more or better goes up, the general sits above the specific. A person or anything with a direction faces into the slide or toward what it points at.
|
|
29
|
+
- The eye goes from the heading at top left, to the body in the middle, to the conclusion or next step at bottom right.
|
|
30
|
+
|
|
31
|
+
## Charts
|
|
32
|
+
|
|
33
|
+
- A line for a trend, bars to compare values. Show amounts by position or length, not by area, angle, or hue.
|
|
34
|
+
- Label lines and bars directly instead of using a legend. Put each note next to what it explains.
|
|
35
|
+
- No icon or picture that only decorates.
|
|
36
|
+
|
|
37
|
+
## Check
|
|
38
|
+
|
|
39
|
+
1. `bunx dekc ls <deck>` lists the headings in order. Read only them: does the talk hold?
|
|
40
|
+
2. `bunx dekc shot --sheet`, then each slide's own shot: where does the eye land first, and is that the main point? Read `fill` in `bunx dekc check <slug> --json` for where the slide is empty.
|
|
41
|
+
3. In each slide's shot, edges line up: in a row, tops, bottoms, and the first lines of text; in a column, left edges. Fix any that do not.
|
|
42
|
+
4. Every difference in position, color, size, and look has a reason you can say. Remove the ones that do not.
|
package/src/cli/address.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { existsSync } from "node:fs";
|
|
1
|
+
import { existsSync, statSync } from "node:fs";
|
|
2
2
|
import { basename, dirname, join } from "node:path";
|
|
3
|
+
import { shellName } from "../core/escape.ts";
|
|
3
4
|
import { isInside } from "../core/path.ts";
|
|
4
|
-
import {
|
|
5
|
+
import { snapshotName } from "../core/ref.ts";
|
|
6
|
+
import { type AnySpec, COMMANDS, subcommandsOf } from "./commands.ts";
|
|
5
7
|
|
|
6
8
|
/** A deck a hint is about: the name a command takes, and the directory that makes it implicit. */
|
|
7
9
|
export type HintDeck = { name: string; dir: string };
|
|
@@ -10,20 +12,72 @@ export type HintDeck = { name: string; dir: string };
|
|
|
10
12
|
* A hint's commands as they run from `cwd`. Hints are written as if run inside the deck they are
|
|
11
13
|
* about, where a command finds its deck by itself. Run anywhere else, a command that takes a deck
|
|
12
14
|
* needs its name: as the first word outside every deck, and as `--deck` inside another deck,
|
|
13
|
-
* where a first word names something in that deck instead
|
|
14
|
-
* or
|
|
15
|
+
* where a first word names something in that deck instead, or where the name would read as a
|
|
16
|
+
* subcommand or a flag. The name is one shell word, however it is spelled, or `<deck>` when no
|
|
17
|
+
* word holds it alike in every shell, with where to find it unless `note` is false, for a hint
|
|
18
|
+
* that joins several and says it once. A command that already names a deck, or takes none, is
|
|
19
|
+
* left as written.
|
|
15
20
|
*/
|
|
16
|
-
export function addressHint(
|
|
21
|
+
export function addressHint(
|
|
22
|
+
hint: string,
|
|
23
|
+
deck: HintDeck | undefined,
|
|
24
|
+
cwd: string,
|
|
25
|
+
{ note: noted = true }: { note?: boolean } = {},
|
|
26
|
+
): string {
|
|
17
27
|
if (deck === undefined || isInside(cwd, deck.dir)) {
|
|
18
28
|
return hint;
|
|
19
29
|
}
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
30
|
+
const word = shellName(deck.name) ?? DECK_PLACEHOLDER;
|
|
31
|
+
const inOther = deckAround(cwd) !== undefined;
|
|
32
|
+
// The note a placeholder adds names `dekc ls` for the project, not for the deck.
|
|
33
|
+
const note = hint.indexOf(PLACEHOLDER_NOTE);
|
|
34
|
+
let placed = false;
|
|
35
|
+
const addressed = hint.replace(
|
|
36
|
+
COMMAND_RE,
|
|
37
|
+
(whole, command: string, rest: string, offset: number) => {
|
|
38
|
+
const subcommand = SUBCOMMAND_WORDS.get(command)?.has(deck.name) === true;
|
|
39
|
+
// A first word that is a subcommand, or a flag, is never the deck's name.
|
|
40
|
+
const positional = !subcommand && !deck.name.startsWith("-");
|
|
41
|
+
if (
|
|
42
|
+
!DECK_COMMANDS.has(command) ||
|
|
43
|
+
namesDeck(rest, positional ? word : undefined) ||
|
|
44
|
+
(note >= 0 && offset >= note && offset < note + PLACEHOLDER_NOTE.length)
|
|
45
|
+
) {
|
|
46
|
+
return whole;
|
|
47
|
+
}
|
|
48
|
+
placed ||= word === DECK_PLACEHOLDER;
|
|
49
|
+
const flag = inOther || subcommand;
|
|
50
|
+
return `\`dekc ${command} ${flag ? deckFlag(deck.name) : deckWord(deck.name)}${rest}\``;
|
|
51
|
+
},
|
|
52
|
+
);
|
|
53
|
+
return placed && note < 0 && noted ? `${addressed}${PLACEHOLDER_NOTE}` : addressed;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** `hint` with where to find a deck's name, once, when one of its commands has `<deck>` for it. */
|
|
57
|
+
export function withPlaceholderNote(hint: string): string {
|
|
58
|
+
return hint.includes(DECK_PLACEHOLDER) && !hint.includes(PLACEHOLDER_NOTE)
|
|
59
|
+
? `${hint}${PLACEHOLDER_NOTE}`
|
|
60
|
+
: hint;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Where a hint with `<deck>` in it says to find the deck's name. */
|
|
64
|
+
const PLACEHOLDER_NOTE = "; for <deck>, name the deck as `dekc ls` lists it";
|
|
65
|
+
|
|
66
|
+
/** What a command shows for a deck no word holds alike in every shell. */
|
|
67
|
+
const DECK_PLACEHOLDER = "<deck>";
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* A deck's name as the first word of a command: one shell word, `<deck>` when there is none, or
|
|
71
|
+
* `--deck=` when the name starts with a dash, which a first word would read as a flag.
|
|
72
|
+
*/
|
|
73
|
+
export function deckWord(name: string): string {
|
|
74
|
+
return name.startsWith("-") ? deckFlag(name) : (shellName(name) ?? DECK_PLACEHOLDER);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** A deck's name as `--deck`, joined with `=` when it starts with a dash, as a value must be. */
|
|
78
|
+
export function deckFlag(name: string): string {
|
|
79
|
+
const word = shellName(name) ?? DECK_PLACEHOLDER;
|
|
80
|
+
return name.startsWith("-") ? `--deck=${word}` : `--deck ${word}`;
|
|
27
81
|
}
|
|
28
82
|
|
|
29
83
|
/** A backquoted command: `dekc`, a command word, and what follows it up to the closing quote. */
|
|
@@ -33,20 +87,43 @@ const DECK_COMMANDS = new Set(
|
|
|
33
87
|
Object.entries(COMMANDS).flatMap(([name, spec]) => ("scope" in spec && spec.scope ? [name] : [])),
|
|
34
88
|
);
|
|
35
89
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
90
|
+
/** The first word of each command's subcommands, which a deck's name in its place would read as. */
|
|
91
|
+
const SUBCOMMAND_WORDS = new Map(
|
|
92
|
+
Object.entries(COMMANDS).map(([name, spec]) => [
|
|
93
|
+
name,
|
|
94
|
+
new Set(Object.keys(subcommandsOf(spec as AnySpec)).map((sub) => sub.split(" ")[0])),
|
|
95
|
+
]),
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Whether a command's words already name a deck: as `word`, the deck's name as one shell word,
|
|
100
|
+
* when the deck can be named first, as a ref, or with --deck.
|
|
101
|
+
*/
|
|
102
|
+
function namesDeck(rest: string, word: string | undefined): boolean {
|
|
103
|
+
const words = rest.trim();
|
|
104
|
+
const [first] = words.split(/\s+/);
|
|
105
|
+
return (
|
|
106
|
+
(word !== undefined && (words === word || words.startsWith(`${word} `))) ||
|
|
107
|
+
first?.includes("/") === true ||
|
|
108
|
+
/(?:^| )--deck(?:[ =]|$)/.test(rest)
|
|
109
|
+
);
|
|
39
110
|
}
|
|
40
111
|
|
|
41
112
|
/**
|
|
42
113
|
* The deck `path` lies in: the directory under a project's `decks/`, found from the path alone.
|
|
43
|
-
* A source path dek reports is absolute, so no project needs to be resolved to address it.
|
|
114
|
+
* A source path dek reports is absolute, so no project needs to be resolved to address it. A
|
|
115
|
+
* deck that is not there, such as the one a `deck "nope" not found` points at, is none, and a
|
|
116
|
+
* ref's deck, in a snapshot as dek writes one, is named by the ref, as every command that reads
|
|
117
|
+
* one takes it.
|
|
44
118
|
*/
|
|
45
119
|
export function deckAround(path: string): HintDeck | undefined {
|
|
46
120
|
for (let dir = path; dirname(dir) !== dir; dir = dirname(dir)) {
|
|
47
121
|
const parent = dirname(dir);
|
|
48
|
-
|
|
49
|
-
|
|
122
|
+
const root = dirname(parent);
|
|
123
|
+
if (basename(parent) === "decks" && existsSync(join(root, "dek.toml"))) {
|
|
124
|
+
return statSync(dir, { throwIfNoEntry: false })?.isDirectory()
|
|
125
|
+
? { name: snapshotName(root) ?? basename(dir), dir }
|
|
126
|
+
: undefined;
|
|
50
127
|
}
|
|
51
128
|
}
|
|
52
129
|
return undefined;
|
package/src/cli/build.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { lintDeck, lintProject } from "../core/lint.ts";
|
|
|
5
5
|
import { parsePublicUrl } from "../core/ogp.ts";
|
|
6
6
|
import { PLAYWRIGHT_INSTALL, type PlaywrightRunner } from "../core/playwright.ts";
|
|
7
7
|
import { playerScript } from "../runtime/player.ts";
|
|
8
|
-
import { type SkippedCheck, skippedChecks, visualSkipped } from "./result.ts";
|
|
8
|
+
import { RENDERED_RULES, type SkippedCheck, skippedChecks, visualSkipped } from "./result.ts";
|
|
9
9
|
import type { DecksTarget } from "./scope.ts";
|
|
10
10
|
|
|
11
11
|
/**
|
|
@@ -77,7 +77,7 @@ export async function buildCommand(
|
|
|
77
77
|
...skippedChecks([
|
|
78
78
|
...skipped,
|
|
79
79
|
visualSkipped("dekc lint --visual", {
|
|
80
|
-
reason:
|
|
80
|
+
reason: `${RENDERED_RULES} are measured only by \`dekc lint --visual\``,
|
|
81
81
|
...(options.runner ? { runner: options.runner } : {}),
|
|
82
82
|
}),
|
|
83
83
|
]),
|
package/src/cli/check.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Diagnostic } from "../core/diagnostic.ts";
|
|
2
2
|
import { DekError } from "../core/error.ts";
|
|
3
|
+
import { shellQuote } from "../core/escape.ts";
|
|
3
4
|
import type { Fill } from "../core/fill.ts";
|
|
4
5
|
import { lintDeck } from "../core/lint.ts";
|
|
5
6
|
import { type PlaywrightRunner, playwrightMissingError } from "../core/playwright.ts";
|
|
@@ -53,7 +54,7 @@ export async function checkCommand(
|
|
|
53
54
|
|
|
54
55
|
const skipped: SkippedCheck[] = visual
|
|
55
56
|
? []
|
|
56
|
-
: [visualSkipped(`dekc check ${slug}`, { reason: "Playwright is not installed" })];
|
|
57
|
+
: [visualSkipped(`dekc check ${shellQuote(slug)}`, { reason: "Playwright is not installed" })];
|
|
57
58
|
|
|
58
59
|
// A live-only deck is done without voice, so asking for it skips the check rather than failing,
|
|
59
60
|
// the way a missing Playwright skips visual.
|