@neta-art/cohub-cli 8.4.1 → 9.1.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/README.md +66 -30
- package/dist/board-export.d.ts +21 -36
- package/dist/board-export.js +163 -88
- package/dist/board-kernel.d.ts +2 -3
- package/dist/board-kernel.js +3428 -3770
- package/dist/board-time.d.ts +3 -0
- package/dist/board-time.js +28 -0
- package/dist/commands/apps.js +2 -2
- package/dist/commands/auth.js +2 -2
- package/dist/commands/boards/examples.d.ts +8 -2
- package/dist/commands/boards/examples.js +79 -411
- package/dist/commands/boards.d.ts +4 -9
- package/dist/commands/boards.js +365 -286
- package/dist/commands/desktop.d.ts +1 -5
- package/dist/commands/desktop.js +5 -16
- package/dist/commands/generations.js +1 -1
- package/dist/commands/me.js +1 -1
- package/dist/commands/public.js +3 -3
- package/dist/commands/references.js +3 -0
- package/dist/commands/referrals.js +2 -2
- package/dist/commands/run.js +3 -3
- package/dist/commands/runtime.d.ts +1 -1
- package/dist/commands/runtime.js +14 -9
- package/dist/commands/sandboxd-binary.d.ts +1 -1
- package/dist/commands/sandboxd-binary.js +2 -23
- package/dist/commands/search.js +15 -7
- package/dist/commands/space-activity.js +3 -5
- package/dist/commands/space-displays.d.ts +2 -0
- package/dist/commands/space-displays.js +347 -0
- package/dist/commands/space-files.d.ts +5 -0
- package/dist/commands/space-files.js +215 -0
- package/dist/commands/space-invitations.js +3 -3
- package/dist/commands/spaces.d.ts +3 -11
- package/dist/commands/spaces.js +146 -75
- package/dist/index.js +8 -5
- package/dist/runtime/launch.d.ts +2 -0
- package/dist/runtime/launch.js +38 -8
- package/dist/runtime/presentation.d.ts +1 -0
- package/dist/runtime/presentation.js +3 -2
- package/dist/runtime/supervisor.d.ts +1 -0
- package/dist/runtime/supervisor.js +2 -1
- package/dist/space-files/limit.d.ts +2 -0
- package/dist/space-files/limit.js +16 -0
- package/dist/space-files/operands.d.ts +16 -0
- package/dist/space-files/operands.js +33 -0
- package/dist/space-files/transfer.d.ts +53 -0
- package/dist/space-files/transfer.js +296 -0
- package/dist/space-files/upload.d.ts +14 -0
- package/dist/space-files/upload.js +53 -0
- package/dist/space.d.ts +18 -16
- package/dist/space.js +86 -39
- package/dist/web.d.ts +1 -0
- package/dist/web.js +6 -0
- package/package.json +2 -2
- package/dist/commands/board-domain.d.ts +0 -2
- package/dist/commands/board-domain.js +0 -16
- package/dist/commands/boards/animation.d.ts +0 -2
- package/dist/commands/boards/animation.js +0 -171
- package/dist/commands/boards/appearance.d.ts +0 -2
- package/dist/commands/boards/appearance.js +0 -127
- package/dist/commands/boards/batch.d.ts +0 -4
- package/dist/commands/boards/batch.js +0 -62
- package/dist/commands/boards/connections.d.ts +0 -2
- package/dist/commands/boards/connections.js +0 -95
- package/dist/commands/boards/context.d.ts +0 -31
- package/dist/commands/boards/context.js +0 -71
- package/dist/commands/boards/items.d.ts +0 -2
- package/dist/commands/boards/items.js +0 -184
- package/dist/commands/boards/transactions.d.ts +0 -12
- package/dist/commands/boards/transactions.js +0 -69
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
const UNITS = { "": 1, ms: 1, s: 1000, m: 60_000 };
|
|
2
|
+
export function parseBoardTime(value, name = "time") {
|
|
3
|
+
const match = /^\s*(\d+(?:\.\d+)?|\.\d+)\s*(ms|s|m)?\s*$/i.exec(value);
|
|
4
|
+
if (!match?.[1])
|
|
5
|
+
throw new Error(`${name}: expected a time such as 1500, 500ms, 12.5s or 2m`);
|
|
6
|
+
return Math.round(Number(match[1]) * (UNITS[(match[2] ?? "").toLowerCase()] ?? 1) * 1000) / 1000;
|
|
7
|
+
}
|
|
8
|
+
export function parseBoardTimes(value, name = "--at", limit = 10_000) {
|
|
9
|
+
const parts = value.split(":");
|
|
10
|
+
if (parts.length === 1)
|
|
11
|
+
return [parseBoardTime(value, name)];
|
|
12
|
+
if (parts.length !== 3)
|
|
13
|
+
throw new Error(`${name}: expected a time or start:end:step`);
|
|
14
|
+
const [start, end, step] = parts.map((part) => parseBoardTime(part, name));
|
|
15
|
+
if (step <= 0)
|
|
16
|
+
throw new Error(`${name}: step must be greater than zero`);
|
|
17
|
+
if (end < start)
|
|
18
|
+
throw new Error(`${name}: end must not be before start`);
|
|
19
|
+
const count = Math.floor((end - start) / step + 1e-9) + 1;
|
|
20
|
+
if (count > limit)
|
|
21
|
+
throw new Error(`${name}: ${count} frames exceed the limit of ${limit}`);
|
|
22
|
+
return Array.from({ length: count }, (_, index) => Math.round((start + index * step) * 1000) / 1000);
|
|
23
|
+
}
|
|
24
|
+
export function formatBoardTime(ms) {
|
|
25
|
+
if (ms < 1000)
|
|
26
|
+
return `${ms}ms`;
|
|
27
|
+
return `${Number((ms / 1000).toFixed(3))}s`;
|
|
28
|
+
}
|
package/dist/commands/apps.js
CHANGED
|
@@ -275,7 +275,7 @@ export function registerApps(program) {
|
|
|
275
275
|
.description("List apps in the target space")
|
|
276
276
|
.option("--json", "Output as JSON")
|
|
277
277
|
.action(async (opts) => {
|
|
278
|
-
const spaceId = await resolveSpace(appsCmd);
|
|
278
|
+
const spaceId = await resolveSpace(appsCmd, { home: true });
|
|
279
279
|
const client = createClient();
|
|
280
280
|
try {
|
|
281
281
|
const result = await client.apps.listBySpace(spaceId);
|
|
@@ -421,7 +421,7 @@ export function registerApps(program) {
|
|
|
421
421
|
const source = opts.source ? parseChoice(opts.source, "source", ["workspace", "local"]) : resolveDefaultAppSource();
|
|
422
422
|
if (target.targetType === "port" && opts.source)
|
|
423
423
|
return error("Invalid source", "--source applies only to --file and --dir.");
|
|
424
|
-
const spaceId = await resolveSpace(appsCmd);
|
|
424
|
+
const spaceId = await resolveSpace(appsCmd, { home: true });
|
|
425
425
|
const client = createClient();
|
|
426
426
|
let { targetType, targetRef } = target;
|
|
427
427
|
let sourceRef = null;
|
package/dist/commands/auth.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { authSource, loginWithDeviceFlow, readAuthSession, refreshAccessToken, requestDeviceCode, revokeAndClearAuthSession, verifyDeviceCode } from "../auth.js";
|
|
2
|
-
import {
|
|
2
|
+
import { clearHomeSpaceCache } from "../space.js";
|
|
3
3
|
import { createClient } from "../client.js";
|
|
4
4
|
import { table, json as outJson, jsonRequested, ok, error, spinner, handleHttp } from "../output.js";
|
|
5
5
|
export function registerAuth(program) {
|
|
@@ -68,7 +68,7 @@ export function registerAuth(program) {
|
|
|
68
68
|
.description("Clear stored Logto session")
|
|
69
69
|
.action(async () => {
|
|
70
70
|
await revokeAndClearAuthSession();
|
|
71
|
-
|
|
71
|
+
clearHomeSpaceCache();
|
|
72
72
|
if (process.env.COHUB_EXECUTION_TOKEN?.trim()) {
|
|
73
73
|
ok("Local session cleared. COHUB_EXECUTION_TOKEN is still set.");
|
|
74
74
|
}
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import type { Command } from "commander";
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Starter documents for `boards create -i` and patches for `boards apply -i`.
|
|
4
|
+
* Every example is a valid Board patch; `boards.test.ts` checks that.
|
|
5
|
+
*/
|
|
6
|
+
export declare const BOARD_EXAMPLES: Record<string, {
|
|
7
|
+
description: string;
|
|
8
|
+
value: Record<string, unknown>;
|
|
9
|
+
}>;
|
|
4
10
|
export declare function registerBoardExampleCommands(boards: Command): void;
|
|
@@ -1,429 +1,97 @@
|
|
|
1
1
|
import { json } from "../../output.js";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
type: "text",
|
|
13
|
-
position: { x:
|
|
14
|
-
size: { width:
|
|
15
|
-
rotation: 0,
|
|
16
|
-
props: { text: "Launch plan", fontSize: 32 },
|
|
17
|
-
style: { color: "brand" },
|
|
18
|
-
}],
|
|
19
|
-
connections: [],
|
|
20
|
-
effects: [],
|
|
21
|
-
compositions: [],
|
|
22
|
-
},
|
|
23
|
-
"create:workflow": {
|
|
24
|
-
items: [
|
|
25
|
-
{
|
|
26
|
-
id: "request",
|
|
27
|
-
type: "text",
|
|
28
|
-
position: { x: 80, y: 190 },
|
|
29
|
-
size: { width: 180, height: 48 },
|
|
30
|
-
rotation: 0,
|
|
31
|
-
props: { text: "Request", fontSize: 28 },
|
|
32
|
-
style: { color: "brand" },
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
id: "agent",
|
|
36
|
-
type: "geo",
|
|
37
|
-
position: { x: 360, y: 150 },
|
|
38
|
-
size: { width: 240, height: 120 },
|
|
39
|
-
rotation: 0,
|
|
40
|
-
props: { shape: "rounded", text: "Agent" },
|
|
41
|
-
style: { color: "blue", fillOpacity: 0.08 },
|
|
2
|
+
/**
|
|
3
|
+
* Starter documents for `boards create -i` and patches for `boards apply -i`.
|
|
4
|
+
* Every example is a valid Board patch; `boards.test.ts` checks that.
|
|
5
|
+
*/
|
|
6
|
+
export const BOARD_EXAMPLES = {
|
|
7
|
+
basic: {
|
|
8
|
+
description: "A title, a note and a shape.",
|
|
9
|
+
value: {
|
|
10
|
+
board: { title: "Launch plan" },
|
|
11
|
+
items: {
|
|
12
|
+
title: { type: "text", position: { x: 80, y: 60 }, props: { text: "Launch plan", fontSize: 48, fontWeight: 700 } },
|
|
13
|
+
note: { type: "text", position: { x: 80, y: 140 }, props: { text: "Ship the beta to ten design partners, then widen.", fontSize: 20, width: 420 } },
|
|
14
|
+
goal: { type: "shape", position: { x: 600, y: 60 }, size: { width: 240, height: 140 }, style: { stroke: "green", fill: "green", fillOpacity: 0.12, radius: 16 }, props: { text: "Beta in March" } },
|
|
42
15
|
},
|
|
43
|
-
|
|
44
|
-
id: "result",
|
|
45
|
-
type: "geo",
|
|
46
|
-
position: { x: 700, y: 150 },
|
|
47
|
-
size: { width: 240, height: 120 },
|
|
48
|
-
rotation: 0,
|
|
49
|
-
props: { shape: "rounded", text: "Result" },
|
|
50
|
-
style: { color: "green", fillOpacity: 0.08 },
|
|
51
|
-
},
|
|
52
|
-
],
|
|
53
|
-
connections: [
|
|
54
|
-
{ id: "request-agent", source: { itemId: "request" }, target: { itemId: "agent" }, relation: "triggers", label: "invoke" },
|
|
55
|
-
{ id: "agent-result", source: { itemId: "agent" }, target: { itemId: "result" }, relation: "produces", label: "output" },
|
|
56
|
-
],
|
|
57
|
-
effects: [],
|
|
58
|
-
compositions: [],
|
|
16
|
+
},
|
|
59
17
|
},
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
type: "
|
|
65
|
-
position: { x:
|
|
66
|
-
size: { width:
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
props: {},
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
id: "demo-video",
|
|
73
|
-
type: "video",
|
|
74
|
-
position: { x: 760, y: 100 },
|
|
75
|
-
size: { width: 480, height: 270 },
|
|
76
|
-
rotation: 0,
|
|
77
|
-
source: { kind: "space-file", path: "assets/demo.mp4" },
|
|
78
|
-
props: {},
|
|
18
|
+
workflow: {
|
|
19
|
+
description: "Steps joined by bound arrows with relations.",
|
|
20
|
+
value: {
|
|
21
|
+
items: {
|
|
22
|
+
request: { type: "shape", position: { x: 80, y: 160 }, size: { width: 200, height: 110 }, style: { stroke: "brand" }, props: { geometry: "rounded", text: "Request" } },
|
|
23
|
+
agent: { type: "shape", position: { x: 400, y: 160 }, size: { width: 200, height: 110 }, style: { stroke: "blue", fill: "blue", fillOpacity: 0.08 }, props: { geometry: "rounded", text: "Agent" } },
|
|
24
|
+
result: { type: "shape", position: { x: 720, y: 160 }, size: { width: 200, height: 110 }, style: { stroke: "green", fill: "green", fillOpacity: 0.08 }, props: { geometry: "rounded", text: "Result" } },
|
|
25
|
+
"request-agent": { type: "arrow", props: { start: { item: "request" }, end: { item: "agent" }, relation: "triggers", label: "invoke" } },
|
|
26
|
+
"agent-result": { type: "arrow", props: { start: { item: "agent" }, end: { item: "result" }, relation: "produces", label: "output" } },
|
|
79
27
|
},
|
|
80
|
-
|
|
81
|
-
id: "soundtrack",
|
|
82
|
-
type: "audio",
|
|
83
|
-
position: { x: 80, y: 500 },
|
|
84
|
-
size: { width: 400, height: 96 },
|
|
85
|
-
rotation: 0,
|
|
86
|
-
source: { kind: "space-file", path: "assets/soundtrack.mp3" },
|
|
87
|
-
props: {},
|
|
88
|
-
},
|
|
89
|
-
{
|
|
90
|
-
id: "brief",
|
|
91
|
-
type: "file",
|
|
92
|
-
position: { x: 520, y: 500 },
|
|
93
|
-
size: { width: 320, height: 180 },
|
|
94
|
-
rotation: 0,
|
|
95
|
-
source: { kind: "space-file", path: "docs/brief.md" },
|
|
96
|
-
props: {},
|
|
97
|
-
},
|
|
98
|
-
],
|
|
99
|
-
connections: [],
|
|
100
|
-
effects: [],
|
|
101
|
-
compositions: [],
|
|
28
|
+
},
|
|
102
29
|
},
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
type: "
|
|
108
|
-
position: { x: 120, y:
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
props: { text: "
|
|
112
|
-
style: { color: "brand" },
|
|
30
|
+
slides: {
|
|
31
|
+
description: "Frames as slides; children move and clip with their frame.",
|
|
32
|
+
value: {
|
|
33
|
+
items: {
|
|
34
|
+
s1: { type: "frame", position: { x: 0, y: 0 }, size: { width: 1600, height: 900 }, props: { label: "Intro" } },
|
|
35
|
+
"s1-title": { type: "text", parent: "s1", position: { x: 120, y: 120 }, props: { text: "Special relativity", fontSize: 96, fontWeight: 700 } },
|
|
36
|
+
"s1-sub": { type: "text", parent: "s1", position: { x: 120, y: 260 }, props: { text: "Nothing outruns light", fontSize: 40 } },
|
|
37
|
+
s2: { type: "frame", position: { x: 1800, y: 0 }, size: { width: 1600, height: 900 }, props: { label: "Time dilation" } },
|
|
38
|
+
"s2-title": { type: "text", parent: "s2", position: { x: 120, y: 120 }, props: { text: "Moving clocks run slow", fontSize: 72, fontWeight: 700 } },
|
|
113
39
|
},
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
kind: "effects.pulse",
|
|
127
|
-
kindVersion: 1,
|
|
128
|
-
lifecycle: "when-visible",
|
|
129
|
-
timeOrigin: "visible",
|
|
130
|
-
seed: "pulse-title",
|
|
131
|
-
params: { amount: 0.04, period: 1600 },
|
|
132
|
-
}],
|
|
133
|
-
compositions: [
|
|
134
|
-
{
|
|
135
|
-
id: "intro",
|
|
136
|
-
name: "Intro",
|
|
137
|
-
timeline: {
|
|
138
|
-
duration: 800,
|
|
139
|
-
tracks: [{
|
|
140
|
-
id: "title-opacity",
|
|
141
|
-
target: { type: "item", itemId: "title" },
|
|
142
|
-
channel: "style.opacity",
|
|
143
|
-
fill: "both",
|
|
144
|
-
keyframes: [{ time: 0, value: 0 }, { time: 800, value: 1, easing: "ease-out-cubic" }],
|
|
145
|
-
}],
|
|
146
|
-
},
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
lesson: {
|
|
43
|
+
description: "An animated lesson: entrances, a drawn arrow, typed text and camera moves with pause markers.",
|
|
44
|
+
value: {
|
|
45
|
+
items: {
|
|
46
|
+
s1: { type: "frame", size: { width: 1600, height: 900 }, props: { label: "Length contraction" } },
|
|
47
|
+
title: { type: "text", parent: "s1", position: { x: 120, y: 100 }, props: { text: "Moving rulers get shorter", fontSize: 72, fontWeight: 700 } },
|
|
48
|
+
ruler: { type: "shape", parent: "s1", position: { x: 200, y: 420 }, size: { width: 800, height: 60 }, style: { stroke: "blue", fill: "blue", fillOpacity: 0.15 }, props: { text: "1 m" } },
|
|
49
|
+
caption: { type: "text", parent: "s1", position: { x: 200, y: 560 }, props: { text: "L = L₀ √(1 − v²/c²)", fontSize: 44, font: "serif", reveal: 1 } },
|
|
50
|
+
motion: { type: "arrow", parent: "s1", style: { stroke: "rose", strokeWidth: 4 }, props: { start: { x: 200, y: 360 }, end: { x: 1000, y: 360 }, label: "v → c" } },
|
|
51
|
+
glow: { type: "effect", parent: "s1", position: { x: 1050, y: 380 }, size: { width: 160, height: 160 }, style: { fill: "amber" }, props: { kind: "glow" } },
|
|
147
52
|
},
|
|
148
|
-
{
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
start: 0,
|
|
159
|
-
duration: 900,
|
|
160
|
-
easing: "ease-out-cubic",
|
|
161
|
-
seed: "reveal-stroke",
|
|
162
|
-
}],
|
|
53
|
+
animations: {
|
|
54
|
+
lecture: {
|
|
55
|
+
markers: [{ at: 1500, label: "Ruler", pause: true }, { at: 5000, label: "Formula", pause: true }],
|
|
56
|
+
tracks: {
|
|
57
|
+
"title-in": { target: "title", property: "opacity", composite: "add", keyframes: [{ at: 0, value: 0 }, { at: 600, value: 1, ease: "ease-out" }] },
|
|
58
|
+
"arrow-draw": { target: "motion", property: "style.trim", keyframes: [{ at: 800, value: 0 }, { at: 1800, value: 1, ease: "ease-in-out" }] },
|
|
59
|
+
"ruler-shrink": { target: "ruler", property: "scale", keyframes: [{ at: 2000, value: 1 }, { at: 4000, value: { x: 0.45, y: 1 }, ease: "ease-in-out" }] },
|
|
60
|
+
"caption-type": { target: "caption", property: "props.reveal", keyframes: [{ at: 4200, value: 0 }, { at: 6000, value: 1 }] },
|
|
61
|
+
"camera-focus": { target: "camera", property: "focus", keyframes: [{ at: 0, value: "s1" }, { at: 2000, value: "ruler" }, { at: 4500, value: "s1" }] },
|
|
62
|
+
},
|
|
163
63
|
},
|
|
164
64
|
},
|
|
165
|
-
],
|
|
166
|
-
},
|
|
167
|
-
"item:text": {
|
|
168
|
-
id: "title",
|
|
169
|
-
type: "text",
|
|
170
|
-
position: { x: 120, y: 80 },
|
|
171
|
-
size: { width: 320, height: 48 },
|
|
172
|
-
rotation: 0,
|
|
173
|
-
props: { text: "Launch plan", fontSize: 32 },
|
|
174
|
-
style: { color: "brand" },
|
|
175
|
-
},
|
|
176
|
-
"item:image": {
|
|
177
|
-
id: "hero",
|
|
178
|
-
type: "image",
|
|
179
|
-
position: { x: 120, y: 160 },
|
|
180
|
-
size: { width: 640, height: 360 },
|
|
181
|
-
rotation: 0,
|
|
182
|
-
source: { kind: "space-file", path: "assets/hero.webp" },
|
|
183
|
-
props: {},
|
|
184
|
-
},
|
|
185
|
-
"item:geo": {
|
|
186
|
-
id: "goal",
|
|
187
|
-
type: "geo",
|
|
188
|
-
position: { x: 120, y: 160 },
|
|
189
|
-
size: { width: 280, height: 140 },
|
|
190
|
-
rotation: 0,
|
|
191
|
-
props: { shape: "rounded", text: "Ship" },
|
|
192
|
-
style: { color: "green", fillOpacity: 0.12 },
|
|
193
|
-
},
|
|
194
|
-
"item:frame": {
|
|
195
|
-
id: "scene",
|
|
196
|
-
type: "frame",
|
|
197
|
-
position: { x: 80, y: 60 },
|
|
198
|
-
size: { width: 960, height: 540 },
|
|
199
|
-
rotation: 0,
|
|
200
|
-
props: { label: "Scene 1" },
|
|
201
|
-
style: { color: "neutral" },
|
|
202
|
-
},
|
|
203
|
-
"item:draw": {
|
|
204
|
-
id: "stroke",
|
|
205
|
-
type: "draw",
|
|
206
|
-
rotation: 0,
|
|
207
|
-
props: { points: [{ x: 102, y: 198, p: 0.5 }, { x: 190, y: 102, p: 0.5 }, { x: 278, y: 198, p: 0.5 }] },
|
|
208
|
-
style: { color: "violet", strokeWidth: 4 },
|
|
209
|
-
},
|
|
210
|
-
"item:arrow": {
|
|
211
|
-
id: "arrow",
|
|
212
|
-
type: "arrow",
|
|
213
|
-
rotation: 0,
|
|
214
|
-
props: { start: { x: 116, y: 150 }, end: { x: 344, y: 150 }, bend: 0, arrowStart: false, arrowEnd: true, label: "next" },
|
|
215
|
-
style: { color: "brand", strokeWidth: 2.5 },
|
|
216
|
-
},
|
|
217
|
-
"item:video": {
|
|
218
|
-
id: "demo-video",
|
|
219
|
-
type: "video",
|
|
220
|
-
position: { x: 120, y: 160 },
|
|
221
|
-
size: { width: 640, height: 360 },
|
|
222
|
-
rotation: 0,
|
|
223
|
-
source: { kind: "space-file", path: "assets/demo.mp4" },
|
|
224
|
-
props: {},
|
|
225
|
-
},
|
|
226
|
-
"item:audio": {
|
|
227
|
-
id: "soundtrack",
|
|
228
|
-
type: "audio",
|
|
229
|
-
position: { x: 120, y: 540 },
|
|
230
|
-
size: { width: 480, height: 96 },
|
|
231
|
-
rotation: 0,
|
|
232
|
-
source: { kind: "space-file", path: "assets/soundtrack.mp3" },
|
|
233
|
-
props: {},
|
|
234
|
-
},
|
|
235
|
-
"item:file": {
|
|
236
|
-
id: "brief",
|
|
237
|
-
type: "file",
|
|
238
|
-
position: { x: 120, y: 160 },
|
|
239
|
-
size: { width: 360, height: 220 },
|
|
240
|
-
rotation: 0,
|
|
241
|
-
source: { kind: "space-file", path: "docs/brief.md" },
|
|
242
|
-
props: {},
|
|
243
|
-
},
|
|
244
|
-
"item:task": {
|
|
245
|
-
id: "task",
|
|
246
|
-
type: "task",
|
|
247
|
-
position: { x: 120, y: 160 },
|
|
248
|
-
size: { width: 420, height: 240 },
|
|
249
|
-
rotation: 0,
|
|
250
|
-
props: { taskRunId: "task-run-id", snapshot: { taskType: "generation", status: "running", title: "Generate concept", artifactCount: 0, artifacts: [] } },
|
|
251
|
-
},
|
|
252
|
-
"effect:pulse": {
|
|
253
|
-
id: "pulse-title",
|
|
254
|
-
target: { type: "item", itemId: "title" },
|
|
255
|
-
kind: "effects.pulse",
|
|
256
|
-
kindVersion: 1,
|
|
257
|
-
lifecycle: "when-visible",
|
|
258
|
-
timeOrigin: "visible",
|
|
259
|
-
seed: "pulse-title",
|
|
260
|
-
params: { amount: 0.04, period: 1600 },
|
|
261
|
-
},
|
|
262
|
-
"effect:float": {
|
|
263
|
-
id: "float-hero",
|
|
264
|
-
target: { type: "item", itemId: "hero" },
|
|
265
|
-
kind: "effects.float",
|
|
266
|
-
kindVersion: 1,
|
|
267
|
-
lifecycle: "when-visible",
|
|
268
|
-
timeOrigin: "visible",
|
|
269
|
-
seed: "float-hero",
|
|
270
|
-
params: { distance: 8, period: 2200 },
|
|
271
|
-
},
|
|
272
|
-
"effect:deal": {
|
|
273
|
-
id: "deal-title",
|
|
274
|
-
target: { type: "item", itemId: "title" },
|
|
275
|
-
kind: "effects.deal",
|
|
276
|
-
kindVersion: 1,
|
|
277
|
-
lifecycle: "on-enter",
|
|
278
|
-
timeOrigin: "activation",
|
|
279
|
-
seed: "deal-title",
|
|
280
|
-
params: {},
|
|
281
|
-
},
|
|
282
|
-
"motion:enter-deal": {
|
|
283
|
-
enter: {
|
|
284
|
-
kind: "effects.deal",
|
|
285
|
-
kindVersion: 1,
|
|
286
|
-
params: {},
|
|
287
|
-
},
|
|
288
|
-
},
|
|
289
|
-
"composition:fade": {
|
|
290
|
-
id: "intro",
|
|
291
|
-
name: "Intro",
|
|
292
|
-
timeline: {
|
|
293
|
-
duration: 800,
|
|
294
|
-
tracks: [{
|
|
295
|
-
id: "title-opacity",
|
|
296
|
-
target: { type: "item", itemId: "title" },
|
|
297
|
-
channel: "style.opacity",
|
|
298
|
-
fill: "both",
|
|
299
|
-
keyframes: [
|
|
300
|
-
{ time: 0, value: 0 },
|
|
301
|
-
{ time: 800, value: 1, easing: "ease-out-cubic" },
|
|
302
|
-
],
|
|
303
|
-
}],
|
|
304
|
-
},
|
|
305
|
-
},
|
|
306
|
-
"composition:reveal": {
|
|
307
|
-
id: "reveal",
|
|
308
|
-
name: "Reveal",
|
|
309
|
-
timeline: {
|
|
310
|
-
duration: 600,
|
|
311
|
-
clips: [{ id: "reveal-title", kind: "text.reveal", kindVersion: 1, target: { type: "item", itemId: "title" }, start: 0, duration: 600, fill: "both", easing: "ease-out-cubic", params: { mode: "words" }, seed: "reveal-title" }],
|
|
312
|
-
},
|
|
313
|
-
},
|
|
314
|
-
"composition:motion-path": {
|
|
315
|
-
id: "motion",
|
|
316
|
-
name: "Motion path",
|
|
317
|
-
timeline: {
|
|
318
|
-
duration: 1200,
|
|
319
|
-
clips: [{ id: "move-hero", kind: "motion.path", kindVersion: 1, target: { type: "item", itemId: "hero" }, start: 0, duration: 1200, fill: "both", easing: "ease-in-out-cubic", params: { points: [{ x: 0, y: 0 }, { x: 160, y: -40 }, { x: 320, y: 0 }], orient: true }, seed: "move-hero" }],
|
|
320
|
-
},
|
|
321
|
-
},
|
|
322
|
-
"composition:draw-reveal": {
|
|
323
|
-
id: "draw-stroke",
|
|
324
|
-
name: "Draw stroke",
|
|
325
|
-
timeline: {
|
|
326
|
-
duration: 900,
|
|
327
|
-
clips: [{ id: "reveal-stroke", kind: "draw.reveal", kindVersion: 1, target: { type: "item", itemId: "stroke" }, start: 0, duration: 900, easing: "ease-out-cubic", seed: "reveal-stroke" }],
|
|
328
|
-
},
|
|
329
|
-
},
|
|
330
|
-
"composition:trail": {
|
|
331
|
-
id: "move-with-trail",
|
|
332
|
-
name: "Move with trail",
|
|
333
|
-
timeline: {
|
|
334
|
-
duration: 1200,
|
|
335
|
-
clips: [
|
|
336
|
-
{ id: "move-hero", kind: "motion.path", kindVersion: 1, target: { type: "item", itemId: "hero" }, start: 0, duration: 1200, easing: "ease-in-out-cubic", fill: "both", params: { points: [{ x: 0, y: 0 }, { x: 320, y: 0 }] }, seed: "move-hero" },
|
|
337
|
-
{ id: "trail-hero", kind: "effects.trail", kindVersion: 1, target: { type: "item", itemId: "hero" }, start: 0, duration: 1200, params: { alpha: 0.48 }, seed: "trail-hero" },
|
|
338
|
-
],
|
|
339
|
-
},
|
|
340
|
-
},
|
|
341
|
-
"composition:impact": {
|
|
342
|
-
id: "impact",
|
|
343
|
-
name: "Impact",
|
|
344
|
-
timeline: {
|
|
345
|
-
duration: 500,
|
|
346
|
-
clips: [{ id: "impact-ring", kind: "effects.impact", kindVersion: 1, target: { type: "board" }, start: 0, duration: 500, layer: "front", params: { center: { x: 400, y: 300 }, radius: 120 }, seed: "impact-ring" }],
|
|
347
|
-
},
|
|
348
|
-
},
|
|
349
|
-
"composition:flash": {
|
|
350
|
-
id: "flash",
|
|
351
|
-
name: "Flash",
|
|
352
|
-
timeline: {
|
|
353
|
-
duration: 300,
|
|
354
|
-
clips: [{ id: "screen-flash", kind: "effects.flash", kindVersion: 1, target: { type: "board" }, start: 0, duration: 300, layer: "screen", params: { alpha: 0.3 }, seed: "screen-flash" }],
|
|
355
|
-
},
|
|
356
|
-
},
|
|
357
|
-
"composition:particles": {
|
|
358
|
-
id: "celebrate",
|
|
359
|
-
name: "Celebrate",
|
|
360
|
-
timeline: {
|
|
361
|
-
duration: 1000,
|
|
362
|
-
clips: [{ id: "particles", kind: "effects.particles", kindVersion: 1, target: { type: "board" }, start: 0, duration: 1000, layer: "front", params: { count: 420, bounds: { x: 0, y: 0, width: 800, height: 600 } }, seed: "particles" }],
|
|
363
|
-
},
|
|
364
|
-
playback: { endBehavior: "reset" },
|
|
365
|
-
},
|
|
366
|
-
"composition:camera-shake": {
|
|
367
|
-
id: "shake",
|
|
368
|
-
name: "Camera shake",
|
|
369
|
-
timeline: {
|
|
370
|
-
duration: 500,
|
|
371
|
-
clips: [{ id: "shake-camera", kind: "camera.shake", kindVersion: 1, target: { type: "camera" }, start: 0, duration: 500, layer: "screen", params: { amount: 8, frequency: 28 }, seed: "shake-camera" }],
|
|
372
65
|
},
|
|
373
66
|
},
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
target: { type: "camera" },
|
|
384
|
-
start: 0,
|
|
385
|
-
duration: 700,
|
|
386
|
-
layer: "screen",
|
|
387
|
-
fill: "forwards",
|
|
388
|
-
easing: "ease-out-cubic",
|
|
389
|
-
params: { focus: { type: "item", itemId: "title" }, fit: "contain", padding: 32 },
|
|
390
|
-
seed: "focus-title",
|
|
391
|
-
}],
|
|
67
|
+
sketch: {
|
|
68
|
+
description: "A code-drawn item; `src` is a module in the Space exporting draw(ctx, frame).",
|
|
69
|
+
value: {
|
|
70
|
+
items: {
|
|
71
|
+
wave: { type: "sketch", position: { x: 0, y: 0 }, size: { width: 640, height: 360 }, props: { src: "sketches/wave.js", params: { amplitude: 60 } } },
|
|
72
|
+
},
|
|
73
|
+
animations: {
|
|
74
|
+
loop: { duration: 4000, play: "always", tracks: {} },
|
|
75
|
+
},
|
|
392
76
|
},
|
|
393
77
|
},
|
|
394
78
|
};
|
|
395
|
-
export const BOARD_EXAMPLE_KEYS = Object.keys(templates);
|
|
396
|
-
export function boardExample(kind, type) {
|
|
397
|
-
const key = type ? `${kind}:${type}` : kind;
|
|
398
|
-
const template = templates[key];
|
|
399
|
-
if (!template)
|
|
400
|
-
throw new Error(`Unknown Board example: ${key}`);
|
|
401
|
-
return template;
|
|
402
|
-
}
|
|
403
79
|
export function registerBoardExampleCommands(boards) {
|
|
404
|
-
boards.command("examples [
|
|
405
|
-
.description("Print
|
|
406
|
-
.option("--list", "List available examples")
|
|
80
|
+
boards.command("examples [name]")
|
|
81
|
+
.description("Print a starter Board document or list the examples")
|
|
407
82
|
.addHelpText("after", `
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
cohub boards examples composition fade > intro.json`)
|
|
422
|
-
.action((kind, type, options) => {
|
|
423
|
-
if (options.list)
|
|
424
|
-
return json(BOARD_EXAMPLE_KEYS);
|
|
425
|
-
if (!kind)
|
|
426
|
-
throw new Error("Example kind is required. Use --list to see available examples.");
|
|
427
|
-
json(boardExample(kind, type));
|
|
83
|
+
Examples are valid input for create and apply:
|
|
84
|
+
cohub boards examples lesson > lesson.json
|
|
85
|
+
cohub boards create lesson.board -i lesson.json`)
|
|
86
|
+
.action((name) => {
|
|
87
|
+
if (!name) {
|
|
88
|
+
for (const [key, example] of Object.entries(BOARD_EXAMPLES))
|
|
89
|
+
console.log(`${key.padEnd(10)} ${example.description}`);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const example = BOARD_EXAMPLES[name];
|
|
93
|
+
if (!example)
|
|
94
|
+
throw new Error(`Unknown example ${name}; expected ${Object.keys(BOARD_EXAMPLES).join(", ")}`);
|
|
95
|
+
json(example.value);
|
|
428
96
|
});
|
|
429
97
|
}
|
|
@@ -1,17 +1,12 @@
|
|
|
1
1
|
import type { Command } from "commander";
|
|
2
2
|
import { parseBoardJsonObject } from "../board-command-support.js";
|
|
3
3
|
export declare const parseJsonObject: typeof parseBoardJsonObject;
|
|
4
|
-
export declare function
|
|
4
|
+
export declare function parseRect(value: string, name?: string): {
|
|
5
5
|
x: number;
|
|
6
6
|
y: number;
|
|
7
7
|
width: number;
|
|
8
8
|
height: number;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
id: string;
|
|
13
|
-
title: string;
|
|
14
|
-
version: number;
|
|
15
|
-
};
|
|
16
|
-
}, path: string): void;
|
|
9
|
+
};
|
|
10
|
+
/** `frames/%04d.png` → `frames/0012.png`; a sequence needs a `%d` placeholder. */
|
|
11
|
+
export declare function framePath(pattern: string, index: number): string;
|
|
17
12
|
export declare function registerBoards(program: Command): Command;
|