konpeki 0.1.1 → 0.3.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/AGENTS.md +1 -1
- package/CONTRIBUTING.md +36 -0
- package/README.md +57 -21
- package/SECURITY.md +22 -0
- package/SETUP.md +112 -51
- package/composition/README.md +42 -52
- package/composition/compile.ts +2 -2
- package/composition/document.ts +2 -111
- package/composition/schema.json +12 -3
- package/composition/schema.ts +4 -2
- package/composition/types.ts +4 -21
- package/composition/validate.ts +3 -461
- package/composition/visualizations.ts +0 -16
- package/design/themes/README.md +25 -7
- package/design/themes/index.ts +15 -4
- package/docs/development.md +75 -11
- package/docs/workflow.md +60 -11
- package/index.html +17 -1
- package/package.json +10 -2
- package/plugin.json +22 -0
- package/public/og.png +0 -0
- package/runtime/konpeki.mjs +223 -473
- package/skills/konpeki/SKILL.md +186 -0
- package/skills/konpeki/assets/blank.json +23 -0
- package/skills/konpeki/scripts/ensure-runtime.mjs +69 -0
- package/skills/konpeki/scripts/prepare-document.mjs +40 -0
- package/slides/introducing-konpeki/PROMPT.md +21 -0
- package/slides/introducing-konpeki/README.md +52 -30
- package/slides/introducing-konpeki/SOURCE.md +16 -10
- package/slides/introducing-konpeki/author.ts +44 -42
- package/slides/introducing-konpeki/composition.json +1748 -1743
- package/src/app/App.tsx +179 -37
- package/src/components/BuildOrb.tsx +40 -0
- package/src/components/Canvas.tsx +18 -1
- package/src/components/InspectorPanel.tsx +130 -43
- package/src/components/LeftPanel.tsx +16 -3
- package/src/components/RevisionNotes.tsx +56 -0
- package/src/components/WorkspaceChrome.tsx +98 -11
- package/src/lib/examples/react-page-migration.json +1 -1
- package/src/lib/export-png.ts +4 -1
- package/src/lib/file-session.ts +14 -1
- package/src/lib/review.ts +26 -0
- package/src/lib/storage.ts +38 -10
- package/src/lib/use-file-session.ts +49 -13
- package/src/main.tsx +3 -0
- package/src/styles/base.css +16 -0
- package/src/styles/canvas.css +43 -12
- package/src/styles/chrome.css +174 -52
- package/src/styles/feedback.css +39 -4
- package/src/styles/left-panel.css +48 -7
- package/src/styles/right-panel.css +90 -47
- package/src/styles/shell.css +99 -53
- package/.agents/skills/authoring-visuals/SKILL.md +0 -82
package/composition/document.ts
CHANGED
|
@@ -8,29 +8,14 @@ import {
|
|
|
8
8
|
type CompositionSlide,
|
|
9
9
|
type ContentSlot,
|
|
10
10
|
type Rect,
|
|
11
|
-
type SemanticRelationship,
|
|
12
|
-
type ThemeId,
|
|
13
|
-
type AuthoringMode,
|
|
14
11
|
} from "./types.ts";
|
|
15
12
|
import { validateComposition } from "./validate.ts";
|
|
16
13
|
import { appearanceOptions } from "./schema.ts";
|
|
17
14
|
import { diagramDefinition } from "./visualizations.ts";
|
|
18
15
|
|
|
19
16
|
export type Draft = CompositionDocument;
|
|
20
|
-
type LegacyDraft = {
|
|
21
|
-
title: string;
|
|
22
|
-
audience: string;
|
|
23
|
-
question: string;
|
|
24
|
-
themeId: ThemeId;
|
|
25
|
-
themeMode: "paper" | "night";
|
|
26
|
-
authoringMode?: AuthoringMode;
|
|
27
|
-
components: CompositionComponent[];
|
|
28
|
-
readingOrder: string[];
|
|
29
|
-
paintOrder: string[];
|
|
30
|
-
relationships: SemanticRelationship[];
|
|
31
|
-
};
|
|
32
17
|
export type StoredDraftResult =
|
|
33
|
-
{ ok: true; draft: Draft
|
|
18
|
+
{ ok: true; draft: Draft } | { ok: false };
|
|
34
19
|
export type ParsedComposition =
|
|
35
20
|
| { ok: true; document: CompositionDocument }
|
|
36
21
|
| { ok: false; message: string };
|
|
@@ -574,78 +559,6 @@ export function duplicateComponent(draft: Draft, id: string, slideId?: string):
|
|
|
574
559
|
};
|
|
575
560
|
return validMutation(draft, next);
|
|
576
561
|
}
|
|
577
|
-
function legacyToComposition(draft: LegacyDraft): unknown {
|
|
578
|
-
const components = draft.components;
|
|
579
|
-
const rawComponents = components as unknown as Array<
|
|
580
|
-
{
|
|
581
|
-
id: string;
|
|
582
|
-
kind: string;
|
|
583
|
-
slotIds: string[];
|
|
584
|
-
appearance?: { role?: string };
|
|
585
|
-
intent?: string;
|
|
586
|
-
}
|
|
587
|
-
>;
|
|
588
|
-
const contentSlots = rawComponents.flatMap((component) =>
|
|
589
|
-
component.slotIds.map((id) => {
|
|
590
|
-
const kind = component.kind;
|
|
591
|
-
const source =
|
|
592
|
-
kind === "footnote" ||
|
|
593
|
-
(kind === "text-block" && component.appearance?.role === "footnote");
|
|
594
|
-
const role = source
|
|
595
|
-
? "source"
|
|
596
|
-
: kind === "headline" ||
|
|
597
|
-
(kind === "text-block" && component.appearance?.role === "title")
|
|
598
|
-
? "takeaway"
|
|
599
|
-
: ["visual", "evidence", "chart"].includes(kind)
|
|
600
|
-
? "evidence"
|
|
601
|
-
: kind === "image"
|
|
602
|
-
? "image"
|
|
603
|
-
: kind === "table"
|
|
604
|
-
? "table"
|
|
605
|
-
: ["diagram", "process"].includes(kind)
|
|
606
|
-
? "process-step"
|
|
607
|
-
: kind === "text-block"
|
|
608
|
-
? "body"
|
|
609
|
-
: "entity";
|
|
610
|
-
const base = {
|
|
611
|
-
id,
|
|
612
|
-
label: componentLabels[component.kind as CompositionComponent["kind"]] ??
|
|
613
|
-
kind.replaceAll("-", " "),
|
|
614
|
-
required: true,
|
|
615
|
-
instruction: component.intent?.trim() || `Describe ${kind.replaceAll("-", " ")} content.`,
|
|
616
|
-
};
|
|
617
|
-
return role === "source"
|
|
618
|
-
? {
|
|
619
|
-
...base,
|
|
620
|
-
role,
|
|
621
|
-
targets: rawComponents
|
|
622
|
-
.filter((candidate) => candidate.id !== component.id)
|
|
623
|
-
.map((candidate) => candidate.id),
|
|
624
|
-
}
|
|
625
|
-
: { ...base, role };
|
|
626
|
-
}),
|
|
627
|
-
);
|
|
628
|
-
return {
|
|
629
|
-
schema: "konpeki-composition/v3",
|
|
630
|
-
title: draft.title,
|
|
631
|
-
...(draft.authoringMode ? { authoringMode: draft.authoringMode } : {}),
|
|
632
|
-
theme: { id: draft.themeId, mode: draft.themeMode },
|
|
633
|
-
slide: {
|
|
634
|
-
id: "slide-1",
|
|
635
|
-
canvas: canvasSize,
|
|
636
|
-
innerPadding: canvasPadding,
|
|
637
|
-
audience: draft.audience,
|
|
638
|
-
question: draft.question,
|
|
639
|
-
intendedViewingSize: "presentation",
|
|
640
|
-
contentSlots,
|
|
641
|
-
components,
|
|
642
|
-
groups: [],
|
|
643
|
-
readingOrder: draft.readingOrder.map((id) => ({ kind: "component", id })),
|
|
644
|
-
paintOrder: draft.paintOrder,
|
|
645
|
-
relationships: draft.relationships,
|
|
646
|
-
},
|
|
647
|
-
};
|
|
648
|
-
}
|
|
649
562
|
export function serializeDraft(draft: Draft) {
|
|
650
563
|
return JSON.stringify({ version: 2, document: draft });
|
|
651
564
|
}
|
|
@@ -664,31 +577,9 @@ export function parseStoredDraft(raw: string): StoredDraftResult {
|
|
|
664
577
|
return {
|
|
665
578
|
ok: true,
|
|
666
579
|
draft: { ...result.document, title: document.title },
|
|
667
|
-
migrated: result.document.schema !== document.schema,
|
|
668
580
|
};
|
|
669
581
|
}
|
|
670
|
-
|
|
671
|
-
if (
|
|
672
|
-
!legacy ||
|
|
673
|
-
typeof legacy.title !== "string" ||
|
|
674
|
-
typeof legacy.audience !== "string" ||
|
|
675
|
-
typeof legacy.question !== "string" ||
|
|
676
|
-
!Array.isArray(legacy.readingOrder) ||
|
|
677
|
-
!legacy.readingOrder.every((id: unknown) => typeof id === "string")
|
|
678
|
-
)
|
|
679
|
-
return { ok: false };
|
|
680
|
-
const document = legacyToComposition(legacy) as { title: string };
|
|
681
|
-
const result = validateComposition({
|
|
682
|
-
...document,
|
|
683
|
-
title: document.title.trim() || "Untitled composition",
|
|
684
|
-
});
|
|
685
|
-
if (!result.ok)
|
|
686
|
-
return { ok: false };
|
|
687
|
-
return {
|
|
688
|
-
ok: true,
|
|
689
|
-
draft: { ...result.document, title: document.title },
|
|
690
|
-
migrated: true,
|
|
691
|
-
};
|
|
582
|
+
return { ok: false };
|
|
692
583
|
} catch {
|
|
693
584
|
return { ok: false };
|
|
694
585
|
}
|
package/composition/schema.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$id": "https://vcfgdev.github.io/konpeki/composition/
|
|
2
|
+
"$id": "https://vcfgdev.github.io/konpeki/composition/v1/schema.json",
|
|
3
3
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
4
4
|
"additionalProperties": false,
|
|
5
5
|
"properties": {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"type": "string"
|
|
12
12
|
},
|
|
13
13
|
"schema": {
|
|
14
|
-
"const": "konpeki-composition/
|
|
14
|
+
"const": "konpeki-composition/v1"
|
|
15
15
|
},
|
|
16
16
|
"slides": {
|
|
17
17
|
"items": {
|
|
@@ -2968,6 +2968,15 @@
|
|
|
2968
2968
|
"night"
|
|
2969
2969
|
],
|
|
2970
2970
|
"type": "string"
|
|
2971
|
+
},
|
|
2972
|
+
"typography": {
|
|
2973
|
+
"enum": [
|
|
2974
|
+
"plex-sans",
|
|
2975
|
+
"noto-sans",
|
|
2976
|
+
"plex-serif",
|
|
2977
|
+
"hanken-grotesk"
|
|
2978
|
+
],
|
|
2979
|
+
"type": "string"
|
|
2971
2980
|
}
|
|
2972
2981
|
},
|
|
2973
2982
|
"required": [
|
|
@@ -2987,6 +2996,6 @@
|
|
|
2987
2996
|
"title",
|
|
2988
2997
|
"slides"
|
|
2989
2998
|
],
|
|
2990
|
-
"title": "konpeki-composition/
|
|
2999
|
+
"title": "konpeki-composition/v1",
|
|
2991
3000
|
"type": "object"
|
|
2992
3001
|
}
|
package/composition/schema.ts
CHANGED
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
compositionSchema,
|
|
5
5
|
themeIds,
|
|
6
6
|
themeModes,
|
|
7
|
+
typographyIds,
|
|
7
8
|
vectorElementKinds,
|
|
8
9
|
} from "./types.ts";
|
|
9
10
|
import { chartTemplates, diagramTypes } from "./visualizations.ts";
|
|
@@ -309,7 +310,7 @@ const components = componentKinds.map((kind) => {
|
|
|
309
310
|
});
|
|
310
311
|
export const schema = {
|
|
311
312
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
312
|
-
$id: "https://vcfgdev.github.io/konpeki/composition/
|
|
313
|
+
$id: "https://vcfgdev.github.io/konpeki/composition/v1/schema.json",
|
|
313
314
|
title: compositionSchema,
|
|
314
315
|
...object(
|
|
315
316
|
{
|
|
@@ -319,7 +320,8 @@ export const schema = {
|
|
|
319
320
|
theme: object({
|
|
320
321
|
id: enumeration(themeIds),
|
|
321
322
|
mode: enumeration(themeModes),
|
|
322
|
-
|
|
323
|
+
typography: enumeration(typographyIds),
|
|
324
|
+
}, ["id", "mode"]),
|
|
323
325
|
slides: array(
|
|
324
326
|
object(
|
|
325
327
|
{
|
package/composition/types.ts
CHANGED
|
@@ -1,26 +1,7 @@
|
|
|
1
1
|
import type { ChartTemplate, DiagramType } from "./visualizations.ts";
|
|
2
2
|
export type { ChartTemplate, DiagramType } from "./visualizations.ts";
|
|
3
3
|
|
|
4
|
-
export const compositionSchema = "konpeki-composition/
|
|
5
|
-
export const legacyCompositionSchemas = [
|
|
6
|
-
"konpeki-composition/v1",
|
|
7
|
-
"konpeki-composition/v2",
|
|
8
|
-
"konpeki-composition/v3",
|
|
9
|
-
"konpeki-composition/v4",
|
|
10
|
-
"konpeki-composition/v5",
|
|
11
|
-
"konpeki-composition/v6",
|
|
12
|
-
"konpeki-composition/v7",
|
|
13
|
-
"konpeki-composition/v8",
|
|
14
|
-
"konpeki-composition/v9",
|
|
15
|
-
"konpeki-composition/v10",
|
|
16
|
-
"konpeki-composition/v11",
|
|
17
|
-
"konpeki-composition/v12",
|
|
18
|
-
"konpeki-composition/v13",
|
|
19
|
-
"konpeki-composition/v14",
|
|
20
|
-
"konpeki-composition/v15",
|
|
21
|
-
"konpeki-composition/v16",
|
|
22
|
-
"konpeki-composition/v17",
|
|
23
|
-
] as const;
|
|
4
|
+
export const compositionSchema = "konpeki-composition/v1" as const;
|
|
24
5
|
export type CanvasSize = { width: number; height: number };
|
|
25
6
|
export const canvasSize = { width: 1920, height: 1080 } as const;
|
|
26
7
|
export const canvasPadding = {
|
|
@@ -44,6 +25,8 @@ export const themeIds = [
|
|
|
44
25
|
export type ThemeId = (typeof themeIds)[number];
|
|
45
26
|
export const themeModes = ["paper", "night"] as const;
|
|
46
27
|
export type ThemeMode = (typeof themeModes)[number];
|
|
28
|
+
export const typographyIds = ["plex-sans", "noto-sans", "plex-serif", "hanken-grotesk"] as const;
|
|
29
|
+
export type TypographyId = (typeof typographyIds)[number];
|
|
47
30
|
export type Rect = { x: number; y: number; width: number; height: number };
|
|
48
31
|
export type Alignment = "start" | "center" | "end";
|
|
49
32
|
export type TitleStyle = "plain" | "prominent";
|
|
@@ -281,6 +264,6 @@ export type CompositionDocument = {
|
|
|
281
264
|
schema: typeof compositionSchema;
|
|
282
265
|
title: string;
|
|
283
266
|
authoringMode?: AuthoringMode;
|
|
284
|
-
theme?: { id: ThemeId; mode: ThemeMode };
|
|
267
|
+
theme?: { id: ThemeId; mode: ThemeMode; typography?: TypographyId };
|
|
285
268
|
slides: CompositionSlide[];
|
|
286
269
|
};
|