konpeki 0.3.0 → 0.4.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 (162) hide show
  1. package/AGENTS.md +21 -28
  2. package/AUTHORING.md +68 -229
  3. package/CONTRIBUTING.md +10 -23
  4. package/README.md +96 -87
  5. package/SETUP.md +50 -114
  6. package/docs/development.md +43 -248
  7. package/docs/workflow.md +6 -108
  8. package/html/README.md +140 -0
  9. package/html/browser.ts +103 -0
  10. package/html/document.ts +38 -0
  11. package/html/floor.ts +34 -0
  12. package/html/index.html +5 -0
  13. package/html/inspect.ts +313 -0
  14. package/html/preview.css +62 -0
  15. package/html/preview.tsx +463 -0
  16. package/html/review-hints.ts +63 -0
  17. package/html/server.ts +99 -0
  18. package/html/source.ts +104 -0
  19. package/html/starter.ts +6 -0
  20. package/html/theme-authoring.md +176 -0
  21. package/html/theme.md +61 -0
  22. package/index.html +9 -9
  23. package/package.json +21 -35
  24. package/plugin.json +1 -1
  25. package/public/og.png +0 -0
  26. package/runtime/browser-B-29TH1a.mjs +595 -0
  27. package/runtime/floor-Cmk7G3pU.mjs +41 -0
  28. package/runtime/konpeki.mjs +90 -1410
  29. package/runtime/server-BAqC_5WD.mjs +2 -0
  30. package/runtime/server-DfRpfcY9.mjs +205 -0
  31. package/runtime/source-B_Ui9tMp.mjs +141 -0
  32. package/runtime/source-CZQq9GUO.mjs +2 -0
  33. package/skills/konpeki/SKILL.md +88 -172
  34. package/skills/konpeki/assets/blank.html +17 -0
  35. package/skills/konpeki/floor.md +76 -0
  36. package/skills/konpeki/references/cover.md +27 -0
  37. package/skills/konpeki/references/long-document.md +40 -0
  38. package/skills/konpeki/references/one-pager.md +27 -0
  39. package/skills/konpeki/references/patterns.md +118 -0
  40. package/skills/konpeki/references/resume.md +28 -0
  41. package/skills/konpeki/references/slides.md +28 -0
  42. package/skills/konpeki/scripts/ensure-runtime.mjs +10 -31
  43. package/skills/konpeki/scripts/prepare-document.mjs +25 -14
  44. package/src/components/PageBoard.tsx +156 -0
  45. package/src/lib/alignment.ts +21 -0
  46. package/src/lib/page-board.ts +25 -0
  47. package/src/lib/review-position.ts +19 -0
  48. package/src/styles/base.css +4 -6
  49. package/src/styles/feedback.css +97 -61
  50. package/src/styles/shell.css +95 -323
  51. package/theme-base.css +90 -0
  52. package/theme.css +56 -0
  53. package/vite.config.ts +2 -5
  54. package/composition/README.md +0 -156
  55. package/composition/compile.ts +0 -227
  56. package/composition/document.ts +0 -600
  57. package/composition/schema.json +0 -3001
  58. package/composition/schema.ts +0 -437
  59. package/composition/theme-tokens.ts +0 -16
  60. package/composition/types.ts +0 -269
  61. package/composition/validate.ts +0 -226
  62. package/composition/vector.ts +0 -143
  63. package/composition/visualizations.ts +0 -319
  64. package/design/README.md +0 -17
  65. package/design/palettes/README.md +0 -14
  66. package/design/palettes/base.ts +0 -14
  67. package/design/palettes/candidates.ts +0 -19
  68. package/design/palettes/index.ts +0 -78
  69. package/design/review/color-theme.md +0 -44
  70. package/design/review/layout.md +0 -16
  71. package/design/review/text.md +0 -18
  72. package/design/review/typography.md +0 -15
  73. package/design/review/visuals.md +0 -31
  74. package/design/semantic-patterns.md +0 -43
  75. package/design/themes/README.md +0 -40
  76. package/design/themes/index.ts +0 -24
  77. package/design/visual-languages/technical-product.md +0 -17
  78. package/design/visual-review.md +0 -88
  79. package/lib/assets.d.ts +0 -8
  80. package/lib/charts.ts +0 -18
  81. package/lib/contrast.ts +0 -16
  82. package/lib/layouts.ts +0 -50
  83. package/lib/slide.tsx +0 -42
  84. package/lib/taste.ts +0 -17
  85. package/lib/text.tsx +0 -89
  86. package/lib/typeface.ts +0 -44
  87. package/scripts/migrate-react-page.ts +0 -120
  88. package/skills/konpeki/assets/blank.json +0 -23
  89. package/slides/README.md +0 -153
  90. package/slides/architecture/PROMPT.md +0 -31
  91. package/slides/architecture/index.tsx +0 -102
  92. package/slides/article-brief/PROMPT.md +0 -35
  93. package/slides/article-brief/index.tsx +0 -71
  94. package/slides/bar-chart/PROMPT.md +0 -39
  95. package/slides/bar-chart/index.tsx +0 -97
  96. package/slides/comparison/PROMPT.md +0 -29
  97. package/slides/comparison/index.tsx +0 -95
  98. package/slides/decision-memo/PROMPT.md +0 -34
  99. package/slides/decision-memo/index.tsx +0 -85
  100. package/slides/delivery-plan/PROMPT.md +0 -45
  101. package/slides/delivery-plan/index.tsx +0 -105
  102. package/slides/experiment/PROMPT.md +0 -44
  103. package/slides/experiment/index.tsx +0 -127
  104. package/slides/incident-workflow/PROMPT.md +0 -57
  105. package/slides/incident-workflow/index.tsx +0 -78
  106. package/slides/introducing-konpeki/PROMPT.md +0 -40
  107. package/slides/introducing-konpeki/README.md +0 -76
  108. package/slides/introducing-konpeki/SOURCE.md +0 -26
  109. package/slides/introducing-konpeki/author.ts +0 -165
  110. package/slides/introducing-konpeki/composition.json +0 -3270
  111. package/slides/line-chart/PROMPT.md +0 -40
  112. package/slides/line-chart/index.tsx +0 -72
  113. package/slides/migration/PROMPT.md +0 -38
  114. package/slides/migration/index.tsx +0 -89
  115. package/slides/og-images/PROMPT.md +0 -21
  116. package/slides/og-images/index.tsx +0 -76
  117. package/slides/product-introduction/PROMPT.md +0 -24
  118. package/slides/product-introduction/index.tsx +0 -105
  119. package/slides/research-brief/PROMPT.md +0 -40
  120. package/slides/research-brief/index.tsx +0 -104
  121. package/slides/results-explanation/PROMPT.md +0 -32
  122. package/slides/results-explanation/index.tsx +0 -96
  123. package/slides/retrospective/PROMPT.md +0 -43
  124. package/slides/retrospective/index.tsx +0 -105
  125. package/slides/sankey/PROMPT.md +0 -11
  126. package/slides/sankey/index.tsx +0 -93
  127. package/slides/teaching/PROMPT.md +0 -45
  128. package/slides/teaching/index.tsx +0 -124
  129. package/slides/vertical-bar-charts/PROMPT.md +0 -13
  130. package/slides/vertical-bar-charts/index.tsx +0 -97
  131. package/src/app/App.tsx +0 -820
  132. package/src/components/BuildOrb.tsx +0 -40
  133. package/src/components/Canvas.tsx +0 -1185
  134. package/src/components/DiagramTypeIcon.tsx +0 -78
  135. package/src/components/InspectorPanel.tsx +0 -773
  136. package/src/components/LeftPanel.tsx +0 -120
  137. package/src/components/PageSizePicker.tsx +0 -30
  138. package/src/components/Presentation.tsx +0 -105
  139. package/src/components/RevisionNotes.tsx +0 -56
  140. package/src/components/RightPanel.tsx +0 -201
  141. package/src/components/VectorOverflowWarning.tsx +0 -46
  142. package/src/components/WorkspaceChrome.tsx +0 -288
  143. package/src/components/ui.tsx +0 -53
  144. package/src/lib/examples/react-page-migration.json +0 -1295
  145. package/src/lib/examples.ts +0 -42
  146. package/src/lib/export-png.ts +0 -104
  147. package/src/lib/file-session.ts +0 -87
  148. package/src/lib/history.ts +0 -53
  149. package/src/lib/model.ts +0 -188
  150. package/src/lib/page-size.ts +0 -24
  151. package/src/lib/presentation.ts +0 -17
  152. package/src/lib/review.ts +0 -26
  153. package/src/lib/storage.ts +0 -71
  154. package/src/lib/theme.ts +0 -25
  155. package/src/lib/use-file-session.ts +0 -227
  156. package/src/main.tsx +0 -29
  157. package/src/styles/canvas.css +0 -299
  158. package/src/styles/chrome.css +0 -384
  159. package/src/styles/component-previews.css +0 -386
  160. package/src/styles/left-panel.css +0 -166
  161. package/src/styles/presentation.css +0 -72
  162. package/src/styles/right-panel.css +0 -1215
@@ -1,78 +0,0 @@
1
- import type { ReactNode } from 'react';
2
- import '@fontsource/ibm-plex-sans/latin-400.css';
3
- import '@fontsource/ibm-plex-sans/latin-600.css';
4
-
5
- const ink = '#152B39', muted = '#465D6B', accent = '#006B75';
6
- function Copy({ x = 112, y, lines, size = 34, color = ink, weight = 400 }: {
7
- x?: number; y: number; lines: string[]; size?: number; color?: string; weight?: number;
8
- }) {
9
- return <text x={x} y={y} fill={color} fontSize={size} fontWeight={weight}>
10
- {lines.map((s, i) => <tspan key={i} x={x} dy={i ? size * 1.32 : 0}>{s}</tspan>)}
11
- </text>;
12
- }
13
- function Frame({ title, description, page, children }: { title: string; description: string; page: number; children: ReactNode }) {
14
- return <svg xmlns="http://www.w3.org/2000/svg" width="1920" height="1080" viewBox="0 0 1920 1080" fontFamily="IBM Plex Sans" role="img" aria-labelledby={`title-${page} desc-${page}`}>
15
- <title id={`title-${page}`}>{title}</title><desc id={`desc-${page}`}>{description}</desc>
16
- <rect width="1920" height="1080" fill="#FFFFFF" />
17
- <Copy y={135} lines={[title]} size={64} weight={600} />
18
- {children}
19
- <Copy x={1760} y={1025} lines={[`${page} / 3`]} size={26} color={muted} />
20
- </svg>;
21
- }
22
-
23
- const Diagnosis = () => <Frame page={1} title="The release outpaced the connection pool" description="Fictional Lantern incident, 18 August 2026, UTC. API accepts events into a durable queue; workers deliver to customer webhook endpoints. Concurrency rose from 20 to 80 per worker at 09:00 while the pool stayed at 20. At 09:05 oldest pending age was six minutes and queue depth 18,000. At 09:08 API acceptance was healthy, CPU below 50%, outbound timeouts increased. At 09:12 steady traffic, widespread endpoint timeouts and traces waiting for connections support a worker-side bottleneck rather than traffic surge or independent customer failures. Not yet reproduced under controlled load.">
24
- <Copy y={202} lines={['Lantern · fictional incident · 18 August 2026 · all times UTC']} size={28} color={muted} />
25
- <Copy y={290} lines={['API accepts events']} weight={600} />
26
- <Copy x={630} y={290} lines={['Durable queue']} weight={600} />
27
- <Copy x={1150} y={290} lines={['Workers deliver to webhooks']} weight={600} />
28
- <path d="M435 278 H578 M564 266 L578 278 L564 290 M910 278 H1098 M1084 266 L1098 278 L1084 290" stroke={accent} strokeWidth="3" fill="none" />
29
- <Copy y={350} lines={['Objective: 99% of accepted events get a successful endpoint response within five minutes.']} size={31} color={muted} />
30
- <Copy y={447} lines={['09:00 Release']} size={36} weight={600} color={accent} />
31
- <Copy y={502} lines={['Concurrency per worker: 20 → 80', 'Worker count and incoming volume unchanged.']} size={32} />
32
- <Copy y={630} lines={['09:05–09:08 Symptoms']} size={36} weight={600} color={accent} />
33
- <Copy y={685} lines={['18,000 queued events; oldest waiting 6 min.', 'API acceptance healthy; worker CPU <50%.', 'Outbound requests timed out more often.']} size={32} />
34
- <Copy x={970} y={447} lines={['09:12 Test the three explanations']} size={36} weight={600} color={accent} />
35
- <Copy x={970} y={510} lines={['Traffic surge? Volume matched pre-release.', 'Endpoint failures? Many unrelated endpoints.', 'Worker bottleneck? Traces waited for a', 'connection; each pool still had only 20.']} size={32} />
36
- <Copy x={970} y={737} lines={['Supported diagnosis: concurrency / pool mismatch.', 'The evidence points to shared worker capacity.']} size={31} weight={600} />
37
- <Copy x={970} y={853} lines={['The failure has not yet been reproduced', 'in a controlled test.']} size={29} color={muted} />
38
- <Copy y={925} lines={['Queue age = time the oldest', 'pending event has waited.']} size={29} color={muted} />
39
- </Frame>;
40
-
41
- const Mitigation = () => <Frame page={2} title="Rollback relieved waits before the backlog cleared" description="At 09:15 the team rolled concurrency back to 20, without purging the queue or replaying completed jobs. At 09:20 connection waits and timeout rates were back to pre-release levels, but 24,000 events remained queued, down from a peak of 30,000, and oldest pending age was 14 minutes. At 09:40 queue depth was in its usual 0–500 range and oldest age 40 seconds. Recovery after rollback strengthens the diagnosis but does not replace controlled reproduction.">
42
- <Copy y={208} lines={['Operational sequence · all times UTC · fictional incident']} size={28} color={muted} />
43
- <Copy y={340} lines={['09:15']} size={72} color={accent} weight={600} />
44
- <Copy y={410} lines={['Mitigate the mismatch']} size={37} weight={600} />
45
- <Copy y={478} lines={['Roll concurrency back to 20.', 'Keep the durable queue intact.', 'Do not replay completed jobs.']} size={33} />
46
- <Copy y={685} lines={['Why this intervention?']} size={32} weight={600} />
47
- <Copy y={738} lines={['Match concurrent deliveries', 'to the existing 20-connection', 'pool rather than add pressure.']} size={32} />
48
- <Copy x={760} y={340} lines={['09:20']} size={72} color={accent} weight={600} />
49
- <Copy x={760} y={410} lines={['Transport stabilizes']} size={37} weight={600} />
50
- <Copy x={760} y={478} lines={['Connection waits and timeout', 'rates return to pre-release levels.']} size={33} />
51
- <Copy x={760} y={635} lines={['24,000 events remain']} size={40} weight={600} />
52
- <Copy x={760} y={695} lines={['Down from a peak of 30,000.', 'Oldest pending age: 14 min.', 'The backlog is still draining.']} size={32} />
53
- <Copy x={1340} y={340} lines={['09:40']} size={72} color={accent} weight={600} />
54
- <Copy x={1340} y={410} lines={['Queue normalizes']} size={37} weight={600} />
55
- <Copy x={1340} y={478} lines={['Depth returns to its usual', 'range of 0–500 events.']} size={33} />
56
- <Copy x={1340} y={635} lines={['40 seconds']} size={40} weight={600} />
57
- <Copy x={1340} y={695} lines={['Oldest pending event age.', 'Confirm backlog recovery', 'separately from timeouts.']} size={32} />
58
- <Copy y={935} lines={['Recovery after rollback strengthens the diagnosis; controlled reproduction is still needed.']} size={31} color={muted} />
59
- </Frame>;
60
-
61
- const Recovery = () => <Frame page={3} title="Recovery is a measured window, not a clean slate" description="At 10:10 UTC, 99.3% of newly accepted events over the preceding 30 minutes received a successful endpoint response within five minutes, exceeding the 99% objective for that cohort. It does not erase the incident delivery-objective breach. No data loss observed, but event-by-event audit incomplete. Next: reproduce mismatch under load, validate concurrency and pool settings together before release, and add connection-wait time to the rollout dashboard.">
62
- <Copy y={208} lines={['10:10 UTC check · fictional incident']} size={28} color={muted} />
63
- <Copy y={385} lines={['99.3%']} size={132} color={accent} weight={600} />
64
- <Copy y={466} lines={['of newly accepted events']} size={42} weight={600} />
65
- <Copy y={533} lines={['received a successful endpoint response', 'within five minutes in the preceding', '30 minutes (09:40–10:10 UTC).']} size={34} />
66
- <Copy y={730} lines={['Objective: 99% within five minutes.']} size={33} weight={600} />
67
- <Copy y={794} lines={['This cohort met the objective. The incident’s', 'delivery-objective breach still happened.']} size={33} />
68
- <Copy x={1050} y={330} lines={['Close the evidence gaps']} size={43} weight={600} />
69
- <Copy x={1050} y={420} lines={['Reproduce the mismatch under load.']} size={34} weight={600} />
70
- <Copy x={1050} y={473} lines={['Test the supported cause in a controlled run.']} size={31} color={muted} />
71
- <Copy x={1050} y={575} lines={['Validate both settings before release.']} size={34} weight={600} />
72
- <Copy x={1050} y={628} lines={['Check concurrency and pool capacity together.']} size={31} color={muted} />
73
- <Copy x={1050} y={730} lines={['Expose connection-wait time.']} size={34} weight={600} />
74
- <Copy x={1050} y={783} lines={['Add the signal to the rollout dashboard.']} size={31} color={muted} />
75
- <Copy y={957} lines={['No data loss was observed; an event-by-event delivery audit is not yet complete.']} size={31} color={muted} />
76
- </Frame>;
77
-
78
- export default [Diagnosis, Mitigation, Recovery];
@@ -1,40 +0,0 @@
1
- # Public brief excerpt
2
-
3
- This file retains the original creation request and its authoring context.
4
- Implementation debugging and product-development follow-ups are omitted; this
5
- is not the complete conversation record.
6
-
7
- > build a pre to introduce konpeki
8
-
9
- ## Authoring record
10
-
11
- - Requested mode: unspecified. Resolved mode: default.
12
- - Explicit visual preferences: none supplied.
13
- - Interpretation: “pre” means presentation. Build a six-slide English introduction
14
- for people and coding-agent users who have not used Konpeki.
15
- - Direction: white, IBM Plex Sans, dark ink and Konpeki blue; restrained diagrams,
16
- clear hierarchy, no invented metrics or unsupported export claims.
17
- - Sources: the repository's documented capabilities;
18
- see SOURCE.md for concrete references and qualifications.
19
- - Deliverable: composition JSON, browser presentation, reviewed captures.
20
-
21
- ## Public revision request
22
-
23
- > review the example composition and revise if needed
24
-
25
- ### Adaptation record
26
-
27
- - Requested mode: unspecified. Resolved mode: retain default.
28
- - Scope: review the introduction against the current skill-led creation,
29
- file-backed revision and browser-only playground workflows.
30
- - Position Konpeki as a creator of editable visuals, not primarily a slide
31
- explainer. Show a creation brief without a mandatory init or canvas-drafting step;
32
- keep the canvas-first intent / Build it workflow as an alternative.
33
- - Distinguish browser-local playground storage from an agent-opened file session.
34
- Notes and Build it need the latter; Copy prompt resumes an idle agent.
35
- - Replace contributor setup commands with skill installation and current user
36
- prerequisites. Do not imply that every agent uses the same slash command.
37
- - Preserve the six pages, existing Precision/Paper appearance, stable IDs and
38
- unrelated geometry. Precision uses Noto Sans; the IBM Plex direction above
39
- records the original creation, not the current theme.
40
- - Refresh the editable JSON, authoring source, source notes and reviewed captures.
@@ -1,76 +0,0 @@
1
- # Introducing Konpeki
2
-
3
- A six-page English introduction for first-time users. Defaults to Precision on paper
4
- with theme-linked colors and fonts; deck appearance can switch palettes and
5
- Paper/Night without repainting vector elements. Uses the default authoring mode.
6
-
7
- 1. **Meet Konpeki** — create editable visuals with your coding agent.
8
- 2. **Create and revise together** — brief, generate, edit and revise the same file.
9
- 3. **Five semantic components** — Text block, Diagram, Chart, Image and Table.
10
- 4. **Keep the detail editable** — direct editing and targeted agent revision notes.
11
- 5. **Browser or agent editor** — local playground versus file-backed editing.
12
- 6. **Try a real brief** — install the skill and give a one-sentence creation request.
13
-
14
- ## Open and revise
15
-
16
- For repository development, run `mise exec -- pnpm dev` from the root and open
17
- `?example=introducing-konpeki` in the application. A static build serves the same
18
- example after `mise exec -- pnpm build`. Select **Present** for viewing.
19
-
20
- Edits autosave to this example's separate browser-local working copy when storage
21
- is available. **Browser → Download JSON** keeps a portable copy; **Import JSON**
22
- and **Start blank** replace only this working copy. **Reset example** restores
23
- the bundled version. Download existing work before resetting, including when
24
- loading an updated example. Browser storage is not a backup and does not sync
25
- with an agent's file. The playground has no connected agent, Notes or Build it.
26
-
27
- For agent-backed editing, follow [SETUP.md](../../SETUP.md) to install the complete
28
- skill, then ask your agent to open a downloaded or copied composition file.
29
- Browser and agent revisions use that same file in its preview. Continue feedback
30
- in agent chat, or use Notes / Build it and Copy prompt as described in the
31
- [canvas workflow](../../docs/workflow.md). A creation brief selects generate;
32
- init is optional, not a required first step.
33
-
34
- [composition.json](composition.json) is the authoritative editable deck. Each
35
- page contains semantic components. Ordinary text uses native content and typography
36
- fields; diagrams and custom specimens keep editable vector elements. Double-click
37
- ordinary text to edit it directly; Content intent remains separate agent guidance.
38
- This is not a second React deck runtime or a collection of page images.
39
-
40
- [author.ts](author.ts) records the reviewed drawing instructions. Running
41
- `mise exec -- node slides/introducing-konpeki/author.ts` validates and regenerates the JSON;
42
- it **replaces manual canvas revisions**, so do not rerun it over revised work.
43
- See [the public brief excerpt](PROMPT.md) and [source facts / provenance](SOURCE.md).
44
-
45
- ## Review
46
-
47
- - `mise exec -- pnpm check`, `mise exec -- pnpm test` (106 tests),
48
- `mise exec -- pnpm build`, composition validation and `git diff --check`: passed.
49
- The build retains its existing large-chunk advisory.
50
- - Inspected all six canvas pages in Precision Paper, Precision Night and Editorial
51
- Paper at 1920×1080 and 1024×768, DPR2 (36 states). No clipped text or overlapping
52
- labels. Revised the file/playground wording and kept the revision arrow returning
53
- from Revise to Edit, not to a new brief.
54
- - `review.mjs` checked text bounds after font loading and each authored vector
55
- viewport against its component rectangle within 0.5 screen pixels at both sizes.
56
- With a dev or preview server and `agent-browser` available, run:
57
-
58
- ```sh
59
- mise exec -- node slides/introducing-konpeki/review.mjs http://localhost:4318 /tmp/konpeki-intro Precision paper
60
- ```
61
-
62
- Repeat with `Precision night` and `Editorial paper`; inspect captures after
63
- the assertions pass. The script defaults to Plex if no palette is supplied and
64
- explicitly selects its legacy font pairing. An optional final typography ID
65
- tests independent combinations, such as `Green paper plex-serif` or
66
- `Plex night noto-sans`; both passed all six pages at both sizes after separation.
67
- - Precision Paper's accessibility tree exposes page copy, visual descriptions
68
- and the chart's illustrative values. Home / ArrowRight navigation reached all
69
- six pages; Noto Sans weights 400, 500 and 600 loaded. Text on the white canvas
70
- measures 15.59:1 (ink), 6.91:1 (muted) and 9.54:1 (accent).
71
- - Final reviewed presentation captures: [screenshots](screenshots/).
72
- - Chart values are illustrative; diagrams are explanatory artwork, not screenshots.
73
- - Native agent-client installation, PDF/PPTX, mobile, reduced motion, focus styling
74
- and cross-application fidelity were not verified by this content review.
75
-
76
- ![Title slide](screenshots/page-1.png)
@@ -1,26 +0,0 @@
1
- # Source facts and provenance
2
-
3
- This is a factual introduction to Konpeki, not a fictional customer case study.
4
-
5
- | Claim | Repository evidence |
6
- | --- | --- |
7
- | Covers, social graphics, charts, diagrams and presentations share an editable canvas | [Product introduction](../../README.md); [authoring guidance](../../AUTHORING.md) |
8
- | Install the complete skill; a creation brief selects generate, with init optional | [Setup](../../SETUP.md); [canvas workflow](../../docs/workflow.md) |
9
- | In a file-backed preview, valid browser and agent changes update the same composition JSON | [File-backed workflow](../../docs/workflow.md#file-backed-editing-with-an-agent) |
10
- | Five top-level kinds: Text block, Diagram, Chart, Image, Table; stable editable vector IDs | [Composition contract](../../composition/README.md); [types](../../composition/types.ts) |
11
- | Direct text, shape and layout editing with undo/redo | [Product capabilities](../../README.md); [composition operations](../../composition/document.ts) |
12
- | Diagram, Chart and Table previews are structural drafts; real source data is needed for finished artwork | [Canvas workflow](../../docs/workflow.md#documents-and-exports); [factual-fidelity rules](../../AUTHORING.md#requirements) |
13
- | Revision notes and Build it belong to file-backed sessions; Copy prompt resumes an idle agent | [Review handoff](../../docs/workflow.md#file-backed-editing-with-an-agent) |
14
- | Playground examples save independent browser-local copies; import/download JSON, start blank, reset, PNG and Present are available | [Demo hosting](../../docs/development.md#development-server-and-demo-hosting); [storage implementation](../../src/lib/storage.ts); [browser controls](../../src/components/WorkspaceChrome.tsx) |
15
- | Playground files do not sync with an agent session; there is no connected AI or cloud storage | [Demo hosting](../../docs/development.md#development-server-and-demo-hosting) |
16
- | Agent workflow requires Node.js 24+, npm, file/command access and a browser; contributor pnpm setup is separate | [User setup](../../SETUP.md); [development setup](../../docs/development.md) |
17
-
18
- The architecture drawings, vector selection example and component specimens are
19
- original explanatory artwork for this deck, not product screenshots. The tiny
20
- chart uses explicitly labeled illustrative values, not measured product data.
21
- The product-announcement prompt is an example brief, not a customer result.
22
- No third-party image assets or customer claims are used. The retained Precision
23
- theme uses Noto Sans from the repository's Fontsource dependency; theme-linked
24
- text follows the selected palette's font roles. No PDF/PPTX or cross-application
25
- fidelity is claimed. This deck does not establish native agent-client installation
26
- compatibility or an official hosted playground URL.
@@ -1,165 +0,0 @@
1
- // Authoring source. composition.json is the editable deck of record.
2
- // Re-running this script replaces it; preserve canvas revisions before rebuilding.
3
- import { writeFile } from "node:fs/promises";
4
- import { canonicalJSON } from "../../composition/compile.ts";
5
- import { createComponent } from "../../composition/document.ts";
6
- import { validateComposition } from "../../composition/validate.ts";
7
- import {
8
- compositionSchema, canvasSize, canvasPadding,
9
- type CompositionComponent, type CompositionDocument, type CompositionSlide,
10
- type VectorElement,
11
- } from "../../composition/types.ts";
12
-
13
- const ink = "theme:ink", blue = "theme:accent", muted = "theme:muted", line = "theme:divider";
14
- function text(id: string, value: string, x: number, y: number, size = 34, fill = ink, weight = 400): VectorElement {
15
- return { id, kind: "text", text: value, attributes: { x, y, "font-family": size >= 56 ? "theme:heading-font" : "theme:body-font", "font-size": size, "font-weight": weight, fill } };
16
- }
17
- function rect(id: string, x: number, y: number, width: number, height: number, stroke = line, fill = "theme:background"): VectorElement {
18
- return { id, kind: "rect", attributes: { x, y, width, height, rx: 4, fill, stroke, "stroke-width": 2 } };
19
- }
20
- function path(id: string, d: string, stroke = blue, width = 3): VectorElement {
21
- return { id, kind: "path", attributes: { d, fill: "none", stroke, "stroke-width": width, "stroke-linecap": "round", "stroke-linejoin": "round" } };
22
- }
23
- function arrow(id: string, x: number, y: number, end: number) {
24
- return path(id, `M${x} ${y}H${end}M${end - 14} ${y - 12}L${end} ${y}L${end - 14} ${y + 12}`);
25
- }
26
- function component(id: string, kind: CompositionComponent["kind"], x: number, y: number, width: number, height: number, description: string, elements: VectorElement[]): CompositionComponent {
27
- const base = createComponent(kind, 1);
28
- if (base.kind === "diagram" || base.kind === "chart") base.appearance.selection = "explicit";
29
- return { ...base, id, slotIds: [`${id}-content`], preferredRect: { x, y, width, height }, intent: description,
30
- customVisual: { format: "vector", viewBox: { x: 0, y: 0, width, height }, fit: "contain", description, elements } };
31
- }
32
- function copy(id: string, x: number, y: number, width: number, lines: string[], size = 36, color = ink, weight = 400) {
33
- const result = component(id, "text-block", x, y, width, Math.ceil(lines.length * size * 1.4 + 20), lines.join(" "),
34
- lines.map((value, index) => text(`${id}-line-${index + 1}`, value, 0, size + 8 + index * size * 1.4, size, color, weight)));
35
- if (result.kind === "text-block" && (id.endsWith("-title") || id === "brand")) result.appearance.role = "title";
36
- if (result.kind === "text-block") {
37
- delete result.customVisual;
38
- result.content = lines.join("\n");
39
- result.textStyle = { size, weight: weight as 400 | 500 | 600, lineHeight: 1.4,
40
- color: color === blue ? "accent" : color === muted ? "muted" : "ink", font: size >= 56 ? "heading" : "body" };
41
- }
42
- return result;
43
- }
44
- function slide(id: string, name: string, question: string, components: CompositionComponent[]): CompositionSlide {
45
- return { id, name, canvas: canvasSize, innerPadding: canvasPadding, pageNumber: { style: "01/02", color: "muted" },
46
- audience: "People and coding-agent users discovering Konpeki", question, intendedViewingSize: "presentation",
47
- components, contentSlots: components.map((c) => ({ id: c.slotIds[0], label: c.id, role: "body", required: true, instruction: c.intent! })),
48
- groups: [], readingOrder: components.map((c) => ({ kind: "component", id: c.id })), paintOrder: components.map((c) => c.id), relationships: [] };
49
- }
50
- function heading(id: string, title: string, subtitle: string) {
51
- return [copy(`${id}-title`, 112, 88, 1696, [title], 62, ink, 600), copy(`${id}-subtitle`, 112, 184, 1696, [subtitle], 32, muted)];
52
- }
53
-
54
- const slides: CompositionSlide[] = [];
55
- slides.push(slide("introduction", "Meet Konpeki", "What is Konpeki?", [
56
- copy("brand", 112, 140, 820, ["Konpeki"], 112, blue, 600),
57
- copy("promise", 112, 328, 960, ["Create clear visuals", "with your coding agent."], 56, ink, 500),
58
- copy("summary", 112, 548, 870, ["Bring a brief. Get an editable result.", "Keep revising the same document."], 36, muted),
59
- component("shared-canvas", "diagram", 1090, 185, 700, 590, "A single editable composition contains a headline, diagram and supporting text; people and agents revise it.", [
60
- rect("canvas-frame", 8, 25, 670, 395),
61
- text("canvas-title", "From brief to visual", 45, 93, 36, ink, 500),
62
- path("headline-rule", "M45 120H640", line, 2),
63
- rect("source-node", 50, 183, 160, 90, blue), rect("result-node", 310, 183, 320, 90, blue),
64
- text("source-label", "Brief", 98, 239, 28), text("result-label", "Editable visual", 374, 239, 28),
65
- arrow("connection", 228, 228, 292),
66
- path("body-lines", "M50 323H395M50 351H525", line, 8),
67
- text("document-label", "composition.json", 178, 484, 32, blue, 500),
68
- text("participants", "Human edits + agent revisions", 116, 548, 28, muted),
69
- ]),
70
- copy("intro-note", 112, 870, 1696, ["Covers, social graphics, charts, diagrams and presentations."], 34),
71
- ]));
72
-
73
- slides.push(slide("workflow", "Create and revise together", "How do a person and an agent work together?", [
74
- ...heading("workflow", "Start with a brief. Keep editing the result.", "In the agent-opened editor, you and your agent edit the same file."),
75
- component("roundtrip", "diagram", 112, 342, 1696, 470, "Share a brief and materials. The agent creates a visual and opens its file-backed preview. Edit that canvas, then ask for revisions in the same conversation. The agent updates the same file; the loop returns to editing, not a new brief.", [
76
- ...[0, 1, 2, 3].flatMap((index) => {
77
- const x = index * 438;
78
- return [text(`number-${index}`, `0${index + 1}`, x, 48, 26, blue, 500),
79
- text(`step-${index}`, ["Brief", "Generate", "Edit", "Revise"][index], x, 122, 42, ink, 500),
80
- text(`detail-a-${index}`, ["Share your materials.", "Agent creates a visual.", "Edit the open canvas.", "Ask in the same chat."][index], x, 190, 29, muted),
81
- text(`detail-b-${index}`, ["Describe the result.", "Opens its file preview.", "Review the details.", "Agent updates that file."][index], x, 234, 29, muted),
82
- ...(index < 3 ? [arrow(`handoff-${index}`, x + 338, 109, x + 398)] : [])];
83
- }),
84
- path("revision-loop", "M1510 285V365H991V285M979 299L991 285L1003 299", blue),
85
- text("loop-label", "Both edit the same composition.json", 490, 431, 32, blue),
86
- ]),
87
- copy("workflow-note", 112, 870, 1696, ["Prefer to sketch first? Add a component, describe its intent, then choose Build it."], 34, ink),
88
- ]));
89
-
90
- slides.push(slide("components", "Five semantic components", "What can a page contain?", [
91
- ...heading("components", "Five components. One composition.", "Each component keeps its meaning, outer geometry and editable interior."),
92
- component("text-specimen", "text-block", 112, 360, 296, 360, "Text block: headlines, body text, captions and footnotes.", [
93
- text("label", "Text block", 0, 40, 38, ink, 500), text("sample", "Aa", 0, 166, 96, blue),
94
- text("detail-1", "Headlines, body", 0, 277, 28, muted), text("detail-2", "and captions", 0, 317, 28, muted),
95
- ]),
96
- component("diagram-specimen", "diagram", 462, 360, 296, 360, "Diagram: entities and their relationships.", [
97
- text("label", "Diagram", 0, 40, 38, ink, 500), rect("node-1", 4, 112, 94, 78, blue), rect("node-2", 195, 112, 94, 78, blue), arrow("edge", 112, 151, 181),
98
- text("detail-1", "Entities and", 0, 277, 28, muted), text("detail-2", "relationships", 0, 317, 28, muted),
99
- ]),
100
- component("chart-specimen", "chart", 812, 360, 296, 400, "Chart specimen with illustrative values A 2 and B 3; not product measurements.", [
101
- text("label", "Chart", 0, 40, 38, ink, 500), path("axis", "M5 84V209H285", line, 2),
102
- rect("bar-a", 54, 129, 66, 80, blue, blue), rect("bar-b", 188, 89, 66, 120, blue, blue),
103
- text("value-a", "2", 77, 117, 24), text("value-b", "3", 209, 77, 24), text("axis-a", "A", 77, 240, 22, muted), text("axis-b", "B", 209, 240, 22, muted),
104
- text("detail-1", "Quantitative", 0, 297, 28, muted), text("detail-2", "comparisons", 0, 337, 28, muted), text("caveat", "Illustrative values", 0, 388, 26, ink),
105
- ]),
106
- component("image-specimen", "image", 1162, 360, 296, 360, "Image: a visual asset or illustration, represented here by original vector artwork.", [
107
- text("label", "Image", 0, 40, 38, ink, 500), rect("frame", 4, 91, 278, 135),
108
- { id: "sun", kind: "circle", attributes: { cx: 227, cy: 126, r: 17, fill: blue } },
109
- path("landscape", "M24 205L88 135L151 194L193 159L264 205", blue, 4),
110
- text("detail-1", "Visual assets", 0, 277, 28, muted), text("detail-2", "and illustrations", 0, 317, 28, muted),
111
- ]),
112
- component("table-specimen", "table", 1512, 360, 296, 360, "Table: structured comparisons with clear row and column associations.", [
113
- text("label", "Table", 0, 40, 38, ink, 500),
114
- text("col-a", "Stage", 0, 120, 26, ink, 500), text("col-b", "Owner", 157, 120, 26, ink, 500),
115
- path("rules", "M0 136H285M0 190H285M0 244H285", line, 2),
116
- text("row-a", "Create", 0, 174, 25), text("row-a-owner", "Agent", 157, 174, 25), text("row-b", "Review", 0, 228, 25), text("row-b-owner", "You", 157, 228, 25),
117
- text("detail", "Structured detail", 0, 317, 28, muted),
118
- ]),
119
- copy("component-note", 112, 848, 1696, ["Diagram, Chart and Table previews are structural drafts.", "Give the agent real data and sources for finished artwork."], 32, ink),
120
- ]));
121
-
122
- slides.push(slide("editing", "Keep the detail editable", "What remains editable after an agent finishes?", [
123
- ...heading("editing", "Keep editing—or ask your agent", "Change text, shapes and layout directly. Undo and redo stay available."),
124
- component("editable-diagram", "diagram", 112, 340, 980, 475, "Explanatory illustration: a selected Review node inside its owning Diagram component. The shape keeps stable ID review-node.", [
125
- rect("owner", 5, 5, 965, 390), text("owner-label", "Diagram · review-flow", 35, 53, 27, muted),
126
- rect("draft", 55, 158, 220, 120), rect("review-node", 385, 158, 220, 120, blue), rect("present", 715, 158, 220, 120),
127
- text("draft-label", "Draft", 113, 232, 38), text("review-label", "Review", 433, 232, 38, blue, 500), text("present-label", "Present", 753, 232, 38),
128
- arrow("draft-review", 293, 218, 367), arrow("review-present", 623, 218, 697),
129
- ...[[380,153],[600,153],[380,273],[600,273]].map(([x,y], i) => rect(`handle-${i}`,x,y,10,10,blue)),
130
- text("stable-id", "Selected element: review-node", 36, 450, 32, blue),
131
- ]),
132
- copy("editing-actions-title", 1210, 343, 580, ["Ask for a targeted revision"], 35, ink, 500),
133
- copy("editing-actions", 1210, 440, 580, ["Select a component or element.", "Add a Revision note in Notes.", "Choose Build it to submit.", "Agent revises the same file."], 31, muted),
134
- copy("editing-note", 112, 852, 1696, ["Notes and Build it are available in the agent-opened editor, not the browser playground.", "Build it cannot wake an idle agent. Use Copy prompt to resume it."], 32, ink),
135
- ]));
136
-
137
- slides.push(slide("today", "Browser or agent editor", "What can I do here, and what needs a coding agent?", [
138
- ...heading("today", "Try the browser. Continue with your agent.", "The same editable format, with different saving and generation paths."),
139
- copy("available-heading", 112, 350, 790, ["Browser playground"], 42, blue, 500),
140
- copy("available-1", 112, 451, 790, ["Edit an example or start blank.", "Import editable composition JSON."], 33),
141
- copy("available-2", 112, 605, 790, ["Saved only in this browser.", "No connected agent or cloud sync."], 33),
142
- copy("available-3", 112, 790, 790, ["Download JSON to keep your work.", "Export PNG or use Present."], 32, ink),
143
- copy("limits-heading", 1020, 350, 788, ["With your coding agent"], 42, ink, 500),
144
- copy("limits-1", 1020, 451, 788, ["The agent creates and revises visuals.", "Its preview saves to a local JSON file."], 33),
145
- copy("limits-2", 1020, 605, 788, ["Bring downloaded JSON to your agent.", "Continue in its file-backed editor."], 33),
146
- copy("limits-3", 1020, 790, 788, ["Playground and file copies do not sync.", "Review generated facts and visuals."], 32, ink),
147
- ]));
148
-
149
- slides.push(slide("start", "Try a real brief", "How do I start?", [
150
- ...heading("start", "Install the skill. Bring a real brief.", "Ask for a cover, social graphic, chart, diagram or presentation."),
151
- copy("setup-heading", 112, 350, 710, ["Install the Konpeki skill"], 40, ink, 500),
152
- copy("repository", 112, 435, 850, ["github.com/vcfgdev/konpeki"], 38, blue, 500),
153
- copy("commands", 112, 543, 840, ["Use your agent’s skill installer.", "Choose skills/konpeki in the repo."], 34),
154
- copy("requirements", 112, 696, 780, ["Node.js 24+ · npm", "An agent with file + command access", "A browser for the editable preview"], 32, ink),
155
- copy("brief-heading", 1020, 350, 788, ["Then give it one sentence"], 40, ink, 500),
156
- copy("brief", 1020, 450, 788, ["“Use Konpeki to turn these launch", "notes into a product announcement.”"], 35),
157
- copy("next-step", 1020, 696, 788, ["Need an empty canvas? Ask for init.", "A creation brief selects generate."], 32, blue, 500),
158
- copy("closing", 112, 906, 1696, ["Attach your materials; the agent opens and checks the editable result. No separate init needed."], 30, muted),
159
- ]));
160
-
161
- const document: CompositionDocument = { schema: compositionSchema, title: "Introducing Konpeki", authoringMode: "default", theme: { id: "precision", mode: "paper" }, slides };
162
- const result = validateComposition(document);
163
- if (!result.ok) throw new Error(JSON.stringify(result.issues, null, 2));
164
- await writeFile(new URL("./composition.json", import.meta.url), canonicalJSON(result.document) + "\n");
165
- console.log(`Authored ${slides.length} editable slides.`);