@markdstage/markdstage 0.1.1

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 (67) hide show
  1. package/README.md +90 -0
  2. package/bin/markdstage.mjs +12 -0
  3. package/package.json +45 -0
  4. package/shared/README.md +1014 -0
  5. package/shared/THIRD-PARTY-NOTICES.md +19 -0
  6. package/shared/deck-state.mjs +105 -0
  7. package/shared/docs/custom-theme-authoring.md +208 -0
  8. package/shared/markdown-deck.mjs +220 -0
  9. package/shared/markdstage-guide.mjs +276 -0
  10. package/shared/presenter-window.mjs +17 -0
  11. package/shared/renderer/architecture-document.mjs +596 -0
  12. package/shared/renderer/architecture-edit.mjs +298 -0
  13. package/shared/renderer/architecture-editor.mjs +449 -0
  14. package/shared/renderer/architecture.mjs +4033 -0
  15. package/shared/renderer/import-path.mjs +11 -0
  16. package/shared/renderer/index.html +106 -0
  17. package/shared/renderer/renderer.js +2082 -0
  18. package/shared/renderer/slides.css +614 -0
  19. package/shared/renderer/speaker-notes.mjs +106 -0
  20. package/shared/renderer/theme.mjs +205 -0
  21. package/shared/runtime/browser.mjs +539 -0
  22. package/shared/runtime/custom-theme.mjs +135 -0
  23. package/shared/runtime/deck-session.mjs +188 -0
  24. package/shared/runtime/errors.mjs +17 -0
  25. package/shared/runtime/output-paths.mjs +159 -0
  26. package/shared/runtime/output.mjs +385 -0
  27. package/shared/runtime/presentation-server.mjs +505 -0
  28. package/shared/runtime/static-files.mjs +70 -0
  29. package/shared/schema/README.md +228 -0
  30. package/shared/schema/architecture-v1.schema.json +664 -0
  31. package/shared/schema/examples/web-app.architecture.json +119 -0
  32. package/shared/schema/theme-metadata-v1.schema.json +75 -0
  33. package/shared/schema/theme-v1.json +84 -0
  34. package/shared/scripts/architecture-assets.mjs +226 -0
  35. package/shared/scripts/asset-paths.mjs +92 -0
  36. package/shared/scripts/atomic-markdown-replace.mjs +46 -0
  37. package/shared/scripts/markdown-blocks.mjs +182 -0
  38. package/shared/scripts/markdown-files.mjs +63 -0
  39. package/shared/scripts/markdown-save-coordinator.mjs +18 -0
  40. package/shared/scripts/markdown-watcher.mjs +80 -0
  41. package/shared/scripts/theme-paths.mjs +108 -0
  42. package/shared/scripts/vendor-assets.mjs +132 -0
  43. package/shared/scripts/workspace-root.mjs +32 -0
  44. package/shared/vendor/highlight.LICENSE +29 -0
  45. package/shared/vendor/highlight.min.js +1244 -0
  46. package/shared/vendor/marked.min.js +6 -0
  47. package/shared/vendor/mermaid.min.js.part-0001 +268 -0
  48. package/shared/vendor/mermaid.min.js.part-0002 +304 -0
  49. package/shared/vendor/mermaid.min.js.part-0003 +324 -0
  50. package/shared/vendor/mermaid.min.js.part-0004 +374 -0
  51. package/shared/vendor/mermaid.min.js.part-0005 +564 -0
  52. package/shared/vendor/mermaid.min.js.part-0006 +1308 -0
  53. package/shared/vendor/mermaid.min.js.part-0007 +269 -0
  54. package/shared/vendor/purify.min.js +3 -0
  55. package/shared/vendor/vendor-assets.lock.json +60 -0
  56. package/src/cli.mjs +347 -0
  57. package/src/commands/capture.mjs +23 -0
  58. package/src/commands/export.mjs +18 -0
  59. package/src/commands/guide.mjs +23 -0
  60. package/src/commands/inspect.mjs +35 -0
  61. package/src/commands/present.mjs +91 -0
  62. package/src/commands/skill.mjs +114 -0
  63. package/src/commands/validate.mjs +79 -0
  64. package/src/deck.mjs +63 -0
  65. package/src/exit.mjs +58 -0
  66. package/src/runtime.mjs +77 -0
  67. package/src/skills.mjs +155 -0
@@ -0,0 +1,228 @@
1
+ # Architecture DSL v1 — JSON Schema
2
+
3
+ This is the **machine-readable schema** for JSON written in `architecture` code
4
+ fences. It supports editor completion and validation as well as automated CI validation.
5
+
6
+ | File | Purpose |
7
+ | --- | --- |
8
+ | `architecture-v1.schema.json` | JSON Schema for DSL v1 (draft 2020-12) |
9
+ | `examples/*.architecture.json` | Working examples with `$schema` |
10
+
11
+ This directory is **intentionally included in the distribution ZIP** so users can
12
+ reference the schema locally. The extension does not load it at runtime (see
13
+ `.github/RELEASING.md`).
14
+
15
+ ## Usage
16
+
17
+ ### 1. Author a `.architecture.json` file
18
+
19
+ Set `$schema` to a **relative path** so VS Code and similar editors can resolve it
20
+ from the file location and provide completion and validation in place.
21
+
22
+ ```json
23
+ {
24
+ "$schema": "../architecture-v1.schema.json",
25
+ "version": 1,
26
+ "elements": []
27
+ }
28
+ ```
29
+
30
+ A relative path rather than an absolute URL keeps validation working immediately
31
+ after cloning or forking the repository and while offline. The completed JSON can
32
+ be pasted directly into an ` ```architecture ` fence with the `$schema` line intact;
33
+ the parser accepts and ignores root `$schema`.
34
+
35
+ ### 2. Associate the schema by extension
36
+
37
+ Add a mapping to `.vscode/settings.json` to validate without a `$schema` line.
38
+
39
+ ```json
40
+ {
41
+ "json.schemas": [
42
+ {
43
+ "fileMatch": ["*.architecture.json"],
44
+ "url": "./.github/extensions/markdstage/schema/architecture-v1.schema.json"
45
+ }
46
+ ]
47
+ }
48
+ ```
49
+
50
+ ### 3. Custom images
51
+
52
+ `node.icon` and standalone `image.src` use the same `assetPath` definition.
53
+ References are restricted to workspace-relative paths beginning with `assets/`,
54
+ and only SVG / PNG / WebP / JPG / JPEG are accepted. External URLs, data URIs,
55
+ absolute paths, `..`, and non-ASCII paths are rejected.
56
+
57
+ ```json
58
+ {
59
+ "$schema": "../architecture-v1.schema.json",
60
+ "version": 1,
61
+ "elements": [
62
+ {
63
+ "type": "image",
64
+ "id": "system-map",
65
+ "src": "assets/system-map.svg",
66
+ "fit": "contain",
67
+ "ariaLabel": "Complete system diagram",
68
+ "x": 80,
69
+ "y": 80,
70
+ "width": 720,
71
+ "height": 420
72
+ }
73
+ ]
74
+ }
75
+ ```
76
+
77
+ `fit` accepts `contain` (default), `cover`, or `stretch`. As with other flow
78
+ elements, omit `x` / `y` under layout management. The Architecture Editor asset
79
+ API, not JSON Schema, validates asset existence, MIME type, signature, and the
80
+ 10 MB import limit.
81
+
82
+ ## Responsibilities of the schema and parser
83
+
84
+ **The schema validates shape; `parseArchitecture` validates semantics.** The
85
+ schema does not replace the parser. JSON Schema cannot express the following
86
+ constraints, so `renderer/architecture.mjs` is authoritative:
87
+
88
+ | Constraint | Why it cannot be represented |
89
+ | --- | --- |
90
+ | A `connector` `from` / `to` refers to an existing non-connector element | Requires document-wide reference resolution |
91
+ | Self-referencing connectors are prohibited | Same as above |
92
+ | Each `id` is unique across the complete tree | Applies to the flattened set of nested elements |
93
+ | 200 elements / 100 connectors / 20,000 text characters | Aggregated **after flattening**, not expressible by `maxItems` on one array |
94
+ | 64 KiB source | String length before parsing |
95
+ | Layout fit (`children do not fit`) | Calculated dynamically from child sizes and group interior dimensions |
96
+ | Child `width` / `height` maximum under `layout` | Maximum depends on `cellWidth` / `cellHeight` |
97
+ | The `assets/` file referenced by `node.icon` / `image.src` exists | The parser does not access the file system; a missing file renders an empty image region |
98
+
99
+ `parseArchitecture` can fail even after schema validation. **The parser always
100
+ makes the final determination of whether a diagram can render.**
101
+
102
+ ### Invariant: P ⊆ A, except for documented divergences
103
+
104
+ As a rule, documents accepted by the parser (P) must also be accepted by the
105
+ schema (A). Allowing the reverse divergence, where a permissive schema accepts
106
+ content that fails during rendering, defeats the purpose of the schema. An
107
+ overly strict schema merely warns on a working diagram. Therefore, **any
108
+ divergence must make the schema stricter, and every instance is listed below.**
109
+
110
+ #### Documented divergences
111
+
112
+ | # | Case | Behavior | Reason |
113
+ | --- | --- | --- | --- |
114
+ | 1 | A child of a group with `layout` has nonnumeric `x` / `y` | Parser accepts; schema rejects | Placement is calculated automatically under `layout`, so the parser silently discards `x` / `y` without validating their values. This likely indicates an authoring mistake that the schema should report. Tightening the parser would reject previously accepted input and would be a breaking change. |
115
+
116
+ Divergences are recorded as `divergence` entries in `test/schema/corpus.mjs`,
117
+ and tests fail when no reason string is present. **CI detects silent divergence.**
118
+
119
+ ### Case handling where representations intentionally differ
120
+
121
+ The implementation's `LITERAL_COLORS` regular expression uses the `/i` flag and
122
+ accepts values such as `#ABC` and `BLACK`. JSON Schema `pattern` has no flag
123
+ concept, so the schema manually expands upper- and lowercase character classes.
124
+ Only here do the `.source` and `pattern` strings differ. Equivalence is tested by
125
+ whether both return the same result for the same input
126
+ (`literal colour pattern is behaviourally equivalent to LITERAL_COLORS`).
127
+
128
+ Asset paths deliberately avoid this issue. `ASSET_PATH_PATTERN` and its
129
+ backward-compatible `ICON_ASSET_PATTERN` alias do **not** use `/i`; they build
130
+ allowed extensions with explicit case expansion such as `[Ss][Vv][Gg]`. The
131
+ `.source` can therefore be copied directly into `pattern`.
132
+ `RegExp.prototype.source` always normalizes `/` to `\/`, so both sides pass
133
+ through `new RegExp(...)` before comparison.
134
+ `schema pattern matches ICON_ASSET_PATTERN` protects string equality, and
135
+ `icon asset pattern is behaviourally equivalent between schema and parser`
136
+ protects concrete accepted and rejected cases.
137
+
138
+ ## Versioning, compatibility, and migration policy
139
+
140
+ ### v1 guarantees
141
+
142
+ `version` is `1`, and omission also means `1`. **DSL v1 is stable.** While v1 is
143
+ supported, the following guarantees apply:
144
+
145
+ - **A document accepted as v1 will continue to be accepted as v1.** Existing
146
+ decks will not suddenly fail.
147
+ - The **meaning** of rendered output—where elements are and what connects to
148
+ what—is preserved.
149
+
150
+ Not guaranteed:
151
+
152
+ - Pixel-exact rendering. Font metrics, theme tokens, and connector pathfinding
153
+ improvements may alter appearance. **This remains the v1 contract after
154
+ stabilization**; it is not a temporary experimental reservation. Save PDF
155
+ output as the artifact when pixel-exact preservation is required.
156
+ - Diagnostic message wording.
157
+
158
+ ### Compatible changes allowed within v1
159
+
160
+ | Change | Example |
161
+ | --- | --- |
162
+ | Add a new optional key | Add an optional style key to `node` |
163
+ | Add an enum value | Add a `shape` or built-in `icon` value; this phase expanded icons from 5 to 11 |
164
+ | Accept previously rejected input | Accept root `$schema` or an `assets/` path in `icon`, both implemented in this phase |
165
+ | Relax a limit | Increase the `points` maximum above 12 |
166
+ | Improve diagnostic messages | Add remediation guidance, implemented in this phase |
167
+
168
+ None of these changes causes previously accepted input to be rejected.
169
+
170
+ ### When a breaking change is required
171
+
172
+ v1 will not remove or rename keys, remove enum values, reduce limits, or change
173
+ defaults. If such a change becomes necessary:
174
+
175
+ 1. Introduce `version: 2` and add `architecture-v2.schema.json`. **Do not delete
176
+ or modify** `architecture-v1.schema.json`.
177
+ 2. The parser accepts **both v1 and v2**, branching on `version`.
178
+ 3. Add v1-to-v2 migration instructions to this file.
179
+ 4. Before retiring v1, emit deprecation warnings for at least one release.
180
+
181
+ In short, **the meaning of an existing `version` never changes later.** Increase
182
+ the number and support the old version in parallel when semantics must change.
183
+
184
+ ## Repository-wide constraints
185
+
186
+ CI (`npm run test:schema`) dynamically scans repository Markdown and requires
187
+ **every discovered ` ```architecture ` block to pass both schema and parser
188
+ validation.** Because the list is not hardcoded, new examples are validated
189
+ automatically.
190
+
191
+ Consequently, **an intentionally invalid `architecture` block cannot appear
192
+ anywhere in the repository.** To document an error example, use one of these
193
+ approaches:
194
+
195
+ - Change the language identifier, for example to ` ```jsonc ` or ` ```text `.
196
+ Only ` ```architecture ` is scanned.
197
+ - Write the invalid example as inline code or in a table instead of a code fence.
198
+ - Put the invalid example in `test/schema/corpus.mjs`, where rejection is expected.
199
+
200
+ ## Keeping schema and implementation synchronized
201
+
202
+ `test/schema/architecture-schema.test.mjs` protects these properties:
203
+
204
+ 1. The schema is valid draft 2020-12 and compiles with ajv.
205
+ 2. Every repository `architecture` block and `examples/*.architecture.json`
206
+ passes **both schema and parser** validation.
207
+ 3. Both validators agree over the conformance corpus in `corpus.mjs`.
208
+ 4. Constants embedded in the schema match exports from `architecture.mjs`.
209
+
210
+ For item 4, every uppercase constant exported by `architecture.mjs` must be
211
+ classified as embedded in the schema, semantic-validation-only, or rendering-only
212
+ (layout / routing). Forgetting to classify a new export fails the tests. The
213
+ third bucket, `rendererOnly`, is also verified to **not** appear in the schema.
214
+ This prevents rendering-tuning values such as routing weights or reroute counts
215
+ from accidentally becoming fixed parts of the DSL.
216
+
217
+ ### Conditional property: `direction` for `layered`
218
+
219
+ `layout.direction` is allowed only when `type` is `"layered"`. The schema
220
+ expresses this with `allOf` / `if` / `not` / `then`, matching parser behavior.
221
+ Both reject `direction` on any other layout.
222
+
223
+ Because `layered` calculates hierarchy from connector direction, **do not specify
224
+ child `x` / `y`**. This matches existing `grid` / `row` / `column` behavior.
225
+
226
+ The validation library (`ajv`) is a **root devDependency**. The extension ships
227
+ as a ZIP and must run without `node_modules`, so do not import the schema or ajv
228
+ from `renderer/architecture.mjs`.