@dnyantra/dtly 0.0.0-stage → 0.2.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 (76) hide show
  1. package/LICENSE +26 -0
  2. package/README.md +172 -2
  3. package/dist/cli.d.ts +2 -0
  4. package/dist/cli.js +95 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/core/anim.d.ts +3 -0
  7. package/dist/core/anim.js +61 -0
  8. package/dist/core/anim.js.map +1 -0
  9. package/dist/core/color.d.ts +4 -0
  10. package/dist/core/color.js +28 -0
  11. package/dist/core/color.js.map +1 -0
  12. package/dist/core/ease.d.ts +8 -0
  13. package/dist/core/ease.js +90 -0
  14. package/dist/core/ease.js.map +1 -0
  15. package/dist/core/model.d.ts +229 -0
  16. package/dist/core/model.js +4 -0
  17. package/dist/core/model.js.map +1 -0
  18. package/dist/core/text.d.ts +41 -0
  19. package/dist/core/text.js +222 -0
  20. package/dist/core/text.js.map +1 -0
  21. package/dist/index.d.ts +10 -0
  22. package/dist/index.js +13 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/mcp/index.d.ts +1 -0
  25. package/dist/mcp/index.js +2 -0
  26. package/dist/mcp/index.js.map +1 -0
  27. package/dist/mcp/server.d.ts +3 -0
  28. package/dist/mcp/server.js +193 -0
  29. package/dist/mcp/server.js.map +1 -0
  30. package/dist/node.d.ts +4 -0
  31. package/dist/node.js +6 -0
  32. package/dist/node.js.map +1 -0
  33. package/dist/ops/ops.d.ts +39 -0
  34. package/dist/ops/ops.js +259 -0
  35. package/dist/ops/ops.js.map +1 -0
  36. package/dist/ops/store.d.ts +4 -0
  37. package/dist/ops/store.js +22 -0
  38. package/dist/ops/store.js.map +1 -0
  39. package/dist/presets/index.d.ts +14 -0
  40. package/dist/presets/index.js +235 -0
  41. package/dist/presets/index.js.map +1 -0
  42. package/dist/presets/text.d.ts +5 -0
  43. package/dist/presets/text.js +19 -0
  44. package/dist/presets/text.js.map +1 -0
  45. package/dist/render/export.d.ts +43 -0
  46. package/dist/render/export.js +215 -0
  47. package/dist/render/export.js.map +1 -0
  48. package/dist/render/ffmpeg.d.ts +1 -0
  49. package/dist/render/ffmpeg.js +16 -0
  50. package/dist/render/ffmpeg.js.map +1 -0
  51. package/dist/render/node-host.d.ts +18 -0
  52. package/dist/render/node-host.js +168 -0
  53. package/dist/render/node-host.js.map +1 -0
  54. package/dist/render/renderer.d.ts +36 -0
  55. package/dist/render/renderer.js +372 -0
  56. package/dist/render/renderer.js.map +1 -0
  57. package/dist/starter.d.ts +5 -0
  58. package/dist/starter.js +32 -0
  59. package/dist/starter.js.map +1 -0
  60. package/dist/studio/server.d.ts +12 -0
  61. package/dist/studio/server.js +190 -0
  62. package/dist/studio/server.js.map +1 -0
  63. package/dist/studio-app/app.css +2 -0
  64. package/dist/studio-app/app.css.map +7 -0
  65. package/dist/studio-app/app.js +5 -0
  66. package/dist/studio-app/app.js.map +7 -0
  67. package/dist/studio-app/index.html +15 -0
  68. package/dist/version.d.ts +2 -0
  69. package/dist/version.js +3 -0
  70. package/dist/version.js.map +1 -0
  71. package/fonts/Baloo2.ttf +0 -0
  72. package/fonts/Mukta-Bold.ttf +0 -0
  73. package/fonts/OFL-Baloo2.txt +93 -0
  74. package/fonts/OFL-Mukta.txt +93 -0
  75. package/package.json +84 -4
  76. package/plugin/skills/dtly/SKILL.md +94 -0
@@ -0,0 +1,193 @@
1
+ // DT.ly MCP server — fine-grained, After Effects-style editing for agents.
2
+ // Every tool takes the project file path; edits are saved atomically after each call.
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
6
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
7
+ import * as z from 'zod';
8
+ import { EASE_NAMES } from '../core/ease.js';
9
+ import * as ops from '../ops/ops.js';
10
+ import { editProject, readProject, writeProject } from '../ops/store.js';
11
+ import { listPresets, PRESETS } from '../presets/index.js';
12
+ import { renderContactSheet, renderStill, renderVideoParallel } from '../render/export.js';
13
+ import { VERSION } from '../version.js';
14
+ const studios = new Map();
15
+ export const createMcpServer = () => {
16
+ const server = new McpServer({ name: 'dtly', title: 'DT.ly — from the creator of CustomerPro.in', version: VERSION });
17
+ const projectArg = z.string().describe('Path to the DT.ly project .json file');
18
+ const easeArg = z
19
+ .union([z.string(), z.tuple([z.number(), z.number(), z.number(), z.number()]), z.object({ spring: z.object({ stiffness: z.number().optional(), damping: z.number().optional(), mass: z.number().optional() }) })])
20
+ .optional()
21
+ .describe(`Ease for the segment leaving this keyframe: ${EASE_NAMES.join(', ')}; a cubic-bezier [x1,y1,x2,y2]; or {spring:{stiffness,damping}}`);
22
+ const json = z.any().describe('A JSON value (number, [x,y], colour string, object…)');
23
+ const text = (s) => ({ content: [{ type: 'text', text: s }] });
24
+ const run = (fn) => async () => {
25
+ try {
26
+ return text(await fn());
27
+ }
28
+ catch (e) {
29
+ return { ...text(`Error: ${e.message}`), isError: true };
30
+ }
31
+ };
32
+ const framesDir = (project) => {
33
+ const d = path.join(path.dirname(path.resolve(project)), '.dtly', 'frames');
34
+ fs.mkdirSync(d, { recursive: true });
35
+ return d;
36
+ };
37
+ server.registerTool('project_create', {
38
+ description: 'Create a new DT.ly project with a root composition "main". Defaults: 1080x1920 (9:16), 30 fps, 10 s.',
39
+ inputSchema: { project: projectArg, name: z.string(), width: z.number().optional(), height: z.number().optional(), fps: z.number().optional(), duration: z.number().optional(), background: z.string().optional() },
40
+ }, (a) => run(() => {
41
+ if (fs.existsSync(a.project))
42
+ throw new Error(`${a.project} already exists`);
43
+ writeProject(a.project, ops.newProject(a));
44
+ return `Created ${a.project}\n${ops.describe(readProject(a.project))}`;
45
+ })());
46
+ server.registerTool('project_describe', {
47
+ description: 'Outline of the project: comps, layer stack (index 0 = top), timing, and which properties are animated with keyframe times. Call this before editing.',
48
+ inputSchema: { project: projectArg },
49
+ }, (a) => run(() => ops.describe(readProject(a.project)))());
50
+ server.registerTool('project_validate', {
51
+ description: 'Static checks: broken parent/matte/precomp references, bad in/out points, keyframes outside the comp.',
52
+ inputSchema: { project: projectArg },
53
+ }, (a) => run(() => { const w = ops.validate(readProject(a.project)); return w.length ? w.join('\n') : 'No problems found.'; })());
54
+ server.registerTool('layer_get', {
55
+ description: 'Full JSON of one layer, including every property and keyframe.',
56
+ inputSchema: { project: projectArg, layer: z.string() },
57
+ }, (a) => run(() => JSON.stringify(ops.findLayer(readProject(a.project), a.layer).layer, null, 2))());
58
+ server.registerTool('comp_add', {
59
+ description: 'Add a composition (use for precomps/scenes). Size, fps and duration default to the root comp.',
60
+ inputSchema: { project: projectArg, id: z.string(), name: z.string().optional(), width: z.number().optional(), height: z.number().optional(), fps: z.number().optional(), duration: z.number().optional(), background: z.string().optional() },
61
+ }, (a) => run(() => { const { project, ...c } = a; editProject(project, (p) => ops.addComp(p, c)); return `Added comp ${a.id}`; })());
62
+ server.registerTool('comp_update', {
63
+ description: 'Change a composition: duration, size, fps, background, name, markers. Set root:true to make it the rendered comp.',
64
+ inputSchema: { project: projectArg, comp: z.string(), duration: z.number().optional(), width: z.number().optional(), height: z.number().optional(), fps: z.number().optional(), background: z.string().optional(), name: z.string().optional(), markers: z.array(z.object({ t: z.number(), label: z.string() })).optional(), root: z.boolean().optional() },
65
+ }, (a) => run(() => {
66
+ const { project, comp, root, ...patch } = a;
67
+ editProject(project, (p) => { ops.updateComp(p, comp, Object.fromEntries(Object.entries(patch).filter(([, v]) => v !== undefined))); if (root)
68
+ p.root = comp; });
69
+ return `Updated comp ${comp}`;
70
+ })());
71
+ server.registerTool('layer_add', {
72
+ description: `Add a layer. \`layer\` is the layer JSON without needing an id: {type: "text"|"shape"|"solid"|"image"|"video"|"audio"|"precomp"|"null", name?, inPoint?, outPoint?, transform?: {anchor,position,scale(%),rotation(deg),opacity(%),skew}, effects?, masks?, matte?, parent?, blendMode?, motionBlur?, ...type props}. Text: text,size,weight,color,font,align,maxWidth,lineHeight,tracking,stroke,shadow,box,animators. Shape: shape(rect|ellipse|polygon|path|line),size,radius,points,fill,stroke,strokeWidth,trim{start,end}. Video: src,trimIn,speed,volume,fit. Any numeric/vector/colour property can be {keyframes:[{t,v,ease}]}. index 0 = top of the stack.`,
73
+ inputSchema: { project: projectArg, comp: z.string().optional().describe('Comp id, default root'), layer: z.record(z.string(), z.any()), index: z.number().optional() },
74
+ }, (a) => run(() => {
75
+ const l = editProject(a.project, (p) => ops.addLayer(p, a.comp, a.layer, a.index ?? 0));
76
+ return `Added ${l.type} layer "${l.id}"`;
77
+ })());
78
+ server.registerTool('layer_update', {
79
+ description: 'Deep-merge a patch into a layer (null deletes a key). Arrays and {keyframes} objects are replaced whole. Use keyframe_set for single keyframes.',
80
+ inputSchema: { project: projectArg, layer: z.string(), patch: z.record(z.string(), z.any()) },
81
+ }, (a) => run(() => { editProject(a.project, (p) => ops.updateLayer(p, a.layer, a.patch)); return `Updated ${a.layer}`; })());
82
+ server.registerTool('layer_remove', {
83
+ description: 'Delete a layer (also clears parent/matte links pointing at it).',
84
+ inputSchema: { project: projectArg, layer: z.string() },
85
+ }, (a) => run(() => { editProject(a.project, (p) => ops.removeLayer(p, a.layer)); return `Removed ${a.layer}`; })());
86
+ server.registerTool('layer_move', {
87
+ description: 'Reorder a layer in its comp stack. index 0 = top.',
88
+ inputSchema: { project: projectArg, layer: z.string(), index: z.number() },
89
+ }, (a) => run(() => { editProject(a.project, (p) => ops.moveLayer(p, a.layer, a.index)); return `Moved ${a.layer} to index ${a.index}`; })());
90
+ server.registerTool('layer_duplicate', {
91
+ description: 'Duplicate a layer (placed above the original), optionally shifted in time.',
92
+ inputSchema: { project: projectArg, layer: z.string(), newId: z.string().optional(), timeShift: z.number().optional() },
93
+ }, (a) => run(() => { const l = editProject(a.project, (p) => ops.duplicateLayer(p, a.layer, a)); return `Duplicated as ${l.id}`; })());
94
+ server.registerTool('layer_shift', {
95
+ description: 'Slide a layer in time: moves its in/out points and all of its keyframes by delta seconds.',
96
+ inputSchema: { project: projectArg, layer: z.string(), delta: z.number() },
97
+ }, (a) => run(() => { editProject(a.project, (p) => ops.shiftLayer(p, a.layer, a.delta)); return `Shifted ${a.layer} by ${a.delta}s`; })());
98
+ server.registerTool('property_set', {
99
+ description: 'Set a static property by dot path, e.g. "transform.position", "color", "trim.end", "effects.0.radius", "box.color". Replaces any keyframes on that path.',
100
+ inputSchema: { project: projectArg, layer: z.string(), property: z.string(), value: json },
101
+ }, (a) => run(() => { editProject(a.project, (p) => ops.setProperty(p, a.layer, a.property, a.value)); return `Set ${a.layer}.${a.property}`; })());
102
+ server.registerTool('keyframe_set', {
103
+ description: 'Add or replace one keyframe on a property path (e.g. "transform.position", "transform.scale", "transform.opacity", "trim.end", "box.reveal", "size", "color", "effects.0.radius"). Time is comp seconds. A static property is converted to animated, keeping its old value at the layer inPoint.',
104
+ inputSchema: { project: projectArg, layer: z.string(), property: z.string(), time: z.number(), value: json, ease: easeArg },
105
+ }, (a) => run(() => {
106
+ const kfs = editProject(a.project, (p) => ops.setKeyframe(p, a.layer, a.property, a.time, a.value, a.ease));
107
+ return `${a.layer}.${a.property} keyframes: ${kfs.map((k) => `${k.t}s=${JSON.stringify(k.v)}${k.ease ? `(${JSON.stringify(k.ease)})` : ''}`).join(' ')}`;
108
+ })());
109
+ server.registerTool('keyframe_remove', {
110
+ description: 'Remove the keyframe at a time. If one keyframe remains, the property becomes static.',
111
+ inputSchema: { project: projectArg, layer: z.string(), property: z.string(), time: z.number() },
112
+ }, (a) => run(() => { editProject(a.project, (p) => ops.removeKeyframe(p, a.layer, a.property, a.time)); return `Removed keyframe ${a.time}s on ${a.layer}.${a.property}`; })());
113
+ server.registerTool('keyframe_move', {
114
+ description: 'Retime one keyframe (keeps its value and ease), like dragging a key in the timeline.',
115
+ inputSchema: { project: projectArg, layer: z.string(), property: z.string(), from: z.number(), to: z.number() },
116
+ }, (a) => run(() => { editProject(a.project, (p) => ops.moveKeyframe(p, a.layer, a.property, a.from, a.to)); return `Moved ${a.layer}.${a.property} key ${a.from}s → ${a.to}s`; })());
117
+ server.registerTool('keyframe_ease', {
118
+ description: 'Change the ease of the segment leaving the keyframe at `time` (AE: Keyframe Assistant / speed graph).',
119
+ inputSchema: { project: projectArg, layer: z.string(), property: z.string(), time: z.number(), ease: easeArg },
120
+ }, (a) => run(() => { editProject(a.project, (p) => ops.setEase(p, a.layer, a.property, a.time, (a.ease ?? 'linear'))); return `Ease set`; })());
121
+ server.registerTool('preset_list', {
122
+ description: 'List presets: text animators (text.*), kinetic typography (kinetic.*), openers (opener.*), slideshows (slides.*), transitions (transition.*), elements (element.*), with their parameters.',
123
+ inputSchema: {},
124
+ }, () => run(() => listPresets())());
125
+ server.registerTool('preset_apply', {
126
+ description: 'Apply a preset to the project. See preset_list for names and params.',
127
+ inputSchema: { project: projectArg, preset: z.string(), comp: z.string().optional(), params: z.record(z.string(), z.any()).optional() },
128
+ }, (a) => run(() => {
129
+ const preset = PRESETS[a.preset];
130
+ if (!preset)
131
+ throw new Error(`Unknown preset "${a.preset}". Use preset_list.`);
132
+ const r = editProject(a.project, (p) => preset.apply(p, a.comp, a.params ?? {}));
133
+ return `${a.preset}: ${r.created.length ? `created ${r.created.join(', ')}` : 'applied'}${r.note ? `. ${r.note}` : ''}`;
134
+ })());
135
+ server.registerTool('studio_open', {
136
+ description: 'Open DT.ly Studio (browser preview + timeline editor) for a project and return its URL. The human sees your edits live as you make them with the other tools, and can tweak the timeline themselves; their edits save to the same file. Call project_describe again after they say they changed something.',
137
+ inputSchema: { project: projectArg, open: z.boolean().optional().describe('Also open it in the default browser (default true)'), port: z.number().optional() },
138
+ }, (a) => run(async () => {
139
+ const file = path.resolve(a.project);
140
+ let s = studios.get(file);
141
+ if (!s) {
142
+ const { startStudio } = await import('../studio/server.js');
143
+ s = await startStudio({ project: file, port: a.port ?? 0 });
144
+ studios.set(file, s);
145
+ }
146
+ if (a.open !== false) {
147
+ const { spawn } = await import('node:child_process');
148
+ const opener = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'explorer' : 'xdg-open';
149
+ spawn(opener, [s.url], { stdio: 'ignore', detached: true }).unref();
150
+ }
151
+ return `DT.ly Studio for ${path.basename(file)}: ${s.url}`;
152
+ })());
153
+ server.registerTool('render_frame', {
154
+ description: 'Render one frame and return it as an image so you can check layout, legibility and timing. Use scale ~0.4 for 1080x1920.',
155
+ inputSchema: { project: projectArg, time: z.number(), comp: z.string().optional(), scale: z.number().optional() },
156
+ }, async (a) => {
157
+ try {
158
+ const out = path.join(framesDir(a.project), `frame-${a.time.toFixed(3)}.png`);
159
+ await renderStill(a.project, a.time, out, { comp: a.comp, scale: a.scale ?? 0.4 });
160
+ return { content: [{ type: 'image', data: fs.readFileSync(out).toString('base64'), mimeType: 'image/png' }, { type: 'text', text: `Saved ${out}` }] };
161
+ }
162
+ catch (e) {
163
+ return { ...text(`Error: ${e.message}`), isError: true };
164
+ }
165
+ });
166
+ server.registerTool('render_sheet', {
167
+ description: 'Render a contact sheet of several times in one image — the fastest way to review motion and pacing.',
168
+ inputSchema: { project: projectArg, times: z.array(z.number()), comp: z.string().optional(), columns: z.number().optional() },
169
+ }, async (a) => {
170
+ try {
171
+ const out = path.join(framesDir(a.project), `sheet-${Date.now()}.png`);
172
+ await renderContactSheet(a.project, a.times, out, { comp: a.comp, columns: a.columns, thumbWidth: 200 });
173
+ return { content: [{ type: 'image', data: fs.readFileSync(out).toString('base64'), mimeType: 'image/png' }, { type: 'text', text: `Saved ${out}` }] };
174
+ }
175
+ catch (e) {
176
+ return { ...text(`Error: ${e.message}`), isError: true };
177
+ }
178
+ });
179
+ server.registerTool('render_video', {
180
+ description: 'Render the root comp (or a range) to MP4 with mixed audio. Roughly 2-4x real time on a laptop for 1080x1920.',
181
+ inputSchema: { project: projectArg, out: z.string().describe('Output .mp4 path'), from: z.number().optional(), to: z.number().optional(), comp: z.string().optional(), workers: z.number().optional().describe('Parallel processes; only worth it for long videos (default 1)') },
182
+ }, (a) => run(async () => {
183
+ const t0 = Date.now();
184
+ const r = await renderVideoParallel(a.project, a.out, a);
185
+ return `Rendered ${r.out}: ${r.seconds.toFixed(2)}s, ${r.frames} frames, ${r.audioTracks} audio tracks in ${((Date.now() - t0) / 1000).toFixed(1)}s`;
186
+ })());
187
+ return server;
188
+ };
189
+ // Runs the MCP server over stdio (what `dtly mcp` and the Claude Code plugin start).
190
+ export const startMcpServer = async () => {
191
+ await createMcpServer().connect(new StdioServerTransport());
192
+ };
193
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
package/dist/node.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ export { renderStill, renderContactSheet, renderVideo, renderVideoParallel, loadProject } from './render/export.js';
2
+ export { NodeHost, registerFonts, newCanvas } from './render/node-host.js';
3
+ export { readProject, writeProject, editProject } from './ops/store.js';
4
+ export { checkFfmpeg } from './render/ffmpeg.js';
package/dist/node.js ADDED
@@ -0,0 +1,6 @@
1
+ // DT.ly for Node: rendering to PNG/MP4 with skia-canvas and FFmpeg, and project files on disk.
2
+ export { renderStill, renderContactSheet, renderVideo, renderVideoParallel, loadProject } from './render/export.js';
3
+ export { NodeHost, registerFonts, newCanvas } from './render/node-host.js';
4
+ export { readProject, writeProject, editProject } from './ops/store.js';
5
+ export { checkFfmpeg } from './render/ffmpeg.js';
6
+ //# sourceMappingURL=node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.js","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAAA,+FAA+F;AAC/F,OAAO,EAAC,WAAW,EAAE,kBAAkB,EAAE,WAAW,EAAE,mBAAmB,EAAE,WAAW,EAAC,MAAM,oBAAoB,CAAC;AAClH,OAAO,EAAC,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAC,MAAM,uBAAuB,CAAC;AACzE,OAAO,EAAC,WAAW,EAAE,YAAY,EAAE,WAAW,EAAC,MAAM,gBAAgB,CAAC;AACtE,OAAO,EAAC,WAAW,EAAC,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,39 @@
1
+ import { type Composition, type Ease, type Keyframe, type Layer, type NewLayer, type Project } from '../core/model.js';
2
+ export declare class OpError extends Error {
3
+ }
4
+ export declare const newProject: (o: {
5
+ name: string;
6
+ width?: number;
7
+ height?: number;
8
+ fps?: number;
9
+ duration?: number;
10
+ background?: string;
11
+ }) => Project;
12
+ export declare const getComp: (p: Project, id?: string) => Composition;
13
+ export declare const findLayer: (p: Project, layerId: string) => {
14
+ comp: Composition;
15
+ layer: Layer;
16
+ index: number;
17
+ };
18
+ export declare const uniqueId: (p: Project, base: string) => string;
19
+ export declare const addComp: (p: Project, c: Partial<Composition> & {
20
+ id: string;
21
+ }) => Composition;
22
+ export declare const updateComp: (p: Project, id: string, patch: Partial<Omit<Composition, 'id' | 'layers'>>) => void;
23
+ export declare const addLayer: (p: Project, compId: string | undefined, layer: NewLayer, index?: number) => Layer;
24
+ export declare const deepMerge: (target: Record<string, unknown>, patch: Record<string, unknown>) => Record<string, unknown>;
25
+ export declare const updateLayer: (p: Project, layerId: string, patch: Record<string, unknown>) => Layer;
26
+ export declare const removeLayer: (p: Project, layerId: string) => void;
27
+ export declare const moveLayer: (p: Project, layerId: string, toIndex: number) => void;
28
+ export declare const shiftLayer: (p: Project, layerId: string, delta: number) => void;
29
+ export declare const duplicateLayer: (p: Project, layerId: string, opts?: {
30
+ newId?: string;
31
+ timeShift?: number;
32
+ }) => Layer;
33
+ export declare const setProperty: (p: Project, layerId: string, path: string, value: unknown) => void;
34
+ export declare const setKeyframe: (p: Project, layerId: string, path: string, t: number, v: unknown, ease?: Ease) => Keyframe<unknown>[];
35
+ export declare const removeKeyframe: (p: Project, layerId: string, path: string, t: number) => void;
36
+ export declare const moveKeyframe: (p: Project, layerId: string, path: string, from: number, to: number) => void;
37
+ export declare const setEase: (p: Project, layerId: string, path: string, t: number, ease: Ease) => void;
38
+ export declare const validate: (p: Project) => string[];
39
+ export declare const describe: (p: Project) => string;
@@ -0,0 +1,259 @@
1
+ // Document operations: the fine-grained edits agents (via MCP) and tools make to a project.
2
+ // Every op is a pure-ish mutation of a Project object; IO lives in ./store.ts.
3
+ import { isAnimated } from '../core/model.js';
4
+ export class OpError extends Error {
5
+ }
6
+ export const newProject = (o) => ({
7
+ dtly: 1,
8
+ name: o.name,
9
+ root: 'main',
10
+ comps: [{ id: 'main', name: 'Main', width: o.width ?? 1080, height: o.height ?? 1920, fps: o.fps ?? 30, duration: o.duration ?? 10, background: o.background ?? '#000000', layers: [] }],
11
+ });
12
+ export const getComp = (p, id) => {
13
+ const c = p.comps.find((c) => c.id === (id ?? p.root));
14
+ if (!c)
15
+ throw new OpError(`No composition "${id}". Comps: ${p.comps.map((c) => c.id).join(', ')}`);
16
+ return c;
17
+ };
18
+ export const findLayer = (p, layerId) => {
19
+ for (const comp of p.comps) {
20
+ const index = comp.layers.findIndex((l) => l.id === layerId);
21
+ if (index >= 0)
22
+ return { comp, layer: comp.layers[index], index };
23
+ }
24
+ throw new OpError(`No layer "${layerId}"`);
25
+ };
26
+ const allIds = (p) => new Set(p.comps.flatMap((c) => c.layers.map((l) => l.id)));
27
+ export const uniqueId = (p, base) => {
28
+ const ids = allIds(p);
29
+ const clean = base.replace(/[^a-zA-Z0-9_-]+/g, '-').replace(/^-|-$/g, '') || 'layer';
30
+ if (!ids.has(clean))
31
+ return clean;
32
+ let i = 2;
33
+ while (ids.has(`${clean}-${i}`))
34
+ i++;
35
+ return `${clean}-${i}`;
36
+ };
37
+ export const addComp = (p, c) => {
38
+ if (p.comps.some((x) => x.id === c.id))
39
+ throw new OpError(`Composition "${c.id}" already exists`);
40
+ const root = getComp(p);
41
+ const comp = { width: root.width, height: root.height, fps: root.fps, duration: root.duration, layers: [], ...c };
42
+ p.comps.push(comp);
43
+ return comp;
44
+ };
45
+ export const updateComp = (p, id, patch) => {
46
+ Object.assign(getComp(p, id), patch);
47
+ };
48
+ // Adds a layer. index 0 = top of the stack (After Effects order).
49
+ export const addLayer = (p, compId, layer, index = 0) => {
50
+ const comp = getComp(p, compId);
51
+ const id = layer.id ? (allIds(p).has(layer.id) ? (() => { throw new OpError(`Layer id "${layer.id}" already used`); })() : layer.id) : uniqueId(p, layer.name ?? layer.type);
52
+ const full = { ...layer, id };
53
+ comp.layers.splice(Math.max(0, Math.min(index, comp.layers.length)), 0, full);
54
+ return full;
55
+ };
56
+ const isPlainObject = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
57
+ // Deep merge; `null` deletes a key. Arrays and keyframe objects are replaced wholesale.
58
+ export const deepMerge = (target, patch) => {
59
+ for (const [k, v] of Object.entries(patch)) {
60
+ if (v === null)
61
+ delete target[k];
62
+ else if (isPlainObject(v) && isPlainObject(target[k]) && !('keyframes' in v))
63
+ deepMerge(target[k], v);
64
+ else
65
+ target[k] = v;
66
+ }
67
+ return target;
68
+ };
69
+ export const updateLayer = (p, layerId, patch) => {
70
+ if ('id' in patch)
71
+ throw new OpError('Cannot change a layer id; duplicate it instead');
72
+ const { layer } = findLayer(p, layerId);
73
+ deepMerge(layer, patch);
74
+ return layer;
75
+ };
76
+ export const removeLayer = (p, layerId) => {
77
+ const { comp, index } = findLayer(p, layerId);
78
+ comp.layers.splice(index, 1);
79
+ for (const c of p.comps)
80
+ for (const l of c.layers) {
81
+ if (l.parent === layerId)
82
+ delete l.parent;
83
+ if (l.matte?.layer === layerId)
84
+ delete l.matte;
85
+ }
86
+ };
87
+ export const moveLayer = (p, layerId, toIndex) => {
88
+ const { comp, index, layer } = findLayer(p, layerId);
89
+ comp.layers.splice(index, 1);
90
+ comp.layers.splice(Math.max(0, Math.min(toIndex, comp.layers.length)), 0, layer);
91
+ };
92
+ // Visits every keyframe list inside a value (for shifting/scaling time).
93
+ const eachKeyframes = (v, fn) => {
94
+ if (Array.isArray(v))
95
+ v.forEach((x) => eachKeyframes(x, fn));
96
+ else if (isPlainObject(v)) {
97
+ if (Array.isArray(v.keyframes))
98
+ fn(v.keyframes);
99
+ Object.values(v).forEach((x) => eachKeyframes(x, fn));
100
+ }
101
+ };
102
+ // Slides a layer in time: in/out points and all its keyframes (like dragging the bar in AE).
103
+ export const shiftLayer = (p, layerId, delta) => {
104
+ const { layer } = findLayer(p, layerId);
105
+ if (layer.inPoint !== undefined || delta)
106
+ layer.inPoint = (layer.inPoint ?? 0) + delta;
107
+ if (layer.outPoint !== undefined)
108
+ layer.outPoint += delta;
109
+ eachKeyframes(layer, (kfs) => kfs.forEach((k) => (k.t = +(k.t + delta).toFixed(4))));
110
+ };
111
+ export const duplicateLayer = (p, layerId, opts = {}) => {
112
+ const { comp, index, layer } = findLayer(p, layerId);
113
+ const copy = structuredClone(layer);
114
+ copy.id = opts.newId ?? uniqueId(p, layer.id);
115
+ comp.layers.splice(index, 0, copy);
116
+ if (opts.timeShift)
117
+ shiftLayer(p, copy.id, opts.timeShift);
118
+ return copy;
119
+ };
120
+ // Property paths: "transform.position", "trim.end", "box.reveal", "effects.0.radius", "size".
121
+ const splitPath = (path) => path.split('.').map((s) => (/^\d+$/.test(s) ? Number(s) : s));
122
+ const getAt = (obj, path) => splitPath(path).reduce((o, k) => (o == null ? undefined : o[k]), obj);
123
+ const setAt = (obj, path, value) => {
124
+ const keys = splitPath(path);
125
+ let o = obj;
126
+ keys.slice(0, -1).forEach((k, i) => {
127
+ if (o[k] == null)
128
+ o[k] = typeof keys[i + 1] === 'number' ? [] : {};
129
+ o = o[k];
130
+ });
131
+ o[keys[keys.length - 1]] = value;
132
+ };
133
+ const TIME_EPS = 1e-3;
134
+ export const setProperty = (p, layerId, path, value) => {
135
+ const { layer } = findLayer(p, layerId);
136
+ setAt(layer, path, value);
137
+ };
138
+ // Adds or replaces the keyframe at time t. A static property becomes animated
139
+ // (its current value is kept as a keyframe at the layer's inPoint, like AE's stopwatch).
140
+ export const setKeyframe = (p, layerId, path, t, v, ease) => {
141
+ const { layer } = findLayer(p, layerId);
142
+ const cur = getAt(layer, path);
143
+ let kfs;
144
+ if (isAnimated(cur))
145
+ kfs = cur.keyframes;
146
+ else {
147
+ kfs = [];
148
+ const anchorT = layer.inPoint ?? 0;
149
+ if (cur !== undefined && Math.abs(anchorT - t) > TIME_EPS)
150
+ kfs.push({ t: anchorT, v: cur });
151
+ setAt(layer, path, { keyframes: kfs });
152
+ }
153
+ const existing = kfs.find((k) => Math.abs(k.t - t) < TIME_EPS);
154
+ if (existing) {
155
+ existing.v = v;
156
+ if (ease !== undefined)
157
+ existing.ease = ease;
158
+ }
159
+ else
160
+ kfs.push(ease !== undefined ? { t, v, ease } : { t, v });
161
+ kfs.sort((a, b) => a.t - b.t);
162
+ return kfs;
163
+ };
164
+ export const removeKeyframe = (p, layerId, path, t) => {
165
+ const { layer } = findLayer(p, layerId);
166
+ const cur = getAt(layer, path);
167
+ if (!cur || !isAnimated(cur))
168
+ throw new OpError(`${layerId}.${path} is not animated`);
169
+ const i = cur.keyframes.findIndex((k) => Math.abs(k.t - t) < TIME_EPS);
170
+ if (i < 0)
171
+ throw new OpError(`No keyframe at ${t}s on ${layerId}.${path}`);
172
+ cur.keyframes.splice(i, 1);
173
+ // One keyframe left = a static value again (AE behaviour when you delete down to one).
174
+ if (cur.keyframes.length === 1 && !cur.wiggle)
175
+ setAt(layer, path, cur.keyframes[0].v);
176
+ };
177
+ // Retimes one keyframe, keeping its value and ease (dragging a key in the timeline).
178
+ export const moveKeyframe = (p, layerId, path, from, to) => {
179
+ const { layer } = findLayer(p, layerId);
180
+ const cur = getAt(layer, path);
181
+ const k = cur?.keyframes?.find((k) => Math.abs(k.t - from) < TIME_EPS);
182
+ if (!cur || !k)
183
+ throw new OpError(`No keyframe at ${from}s on ${layerId}.${path}`);
184
+ const target = Math.round(to * 1000) / 1000;
185
+ if (cur.keyframes.some((x) => x !== k && Math.abs(x.t - target) < TIME_EPS))
186
+ throw new OpError(`There is already a keyframe at ${target}s`);
187
+ k.t = target;
188
+ cur.keyframes.sort((a, b) => a.t - b.t);
189
+ };
190
+ export const setEase = (p, layerId, path, t, ease) => {
191
+ const { layer } = findLayer(p, layerId);
192
+ const cur = getAt(layer, path);
193
+ const k = cur?.keyframes?.find((k) => Math.abs(k.t - t) < TIME_EPS);
194
+ if (!k)
195
+ throw new OpError(`No keyframe at ${t}s on ${layerId}.${path}`);
196
+ k.ease = ease;
197
+ };
198
+ // Static checks an agent should run before rendering.
199
+ export const validate = (p) => {
200
+ const warnings = [];
201
+ const ids = new Set();
202
+ for (const c of p.comps) {
203
+ for (const l of c.layers) {
204
+ if (ids.has(l.id))
205
+ warnings.push(`Duplicate layer id "${l.id}"`);
206
+ ids.add(l.id);
207
+ const inP = l.inPoint ?? 0, outP = l.outPoint ?? c.duration;
208
+ if (outP <= inP)
209
+ warnings.push(`${c.id}/${l.id}: outPoint (${outP}) is not after inPoint (${inP})`);
210
+ if (inP >= c.duration)
211
+ warnings.push(`${c.id}/${l.id}: starts after the comp ends (${c.duration}s)`);
212
+ if (l.parent && !c.layers.some((x) => x.id === l.parent))
213
+ warnings.push(`${c.id}/${l.id}: parent "${l.parent}" not in the same comp`);
214
+ if (l.matte && !c.layers.some((x) => x.id === l.matte.layer))
215
+ warnings.push(`${c.id}/${l.id}: matte "${l.matte.layer}" not in the same comp`);
216
+ if (l.type === 'precomp' && !p.comps.some((x) => x.id === l.comp))
217
+ warnings.push(`${c.id}/${l.id}: unknown comp "${l.comp}"`);
218
+ eachKeyframes(l, (kfs) => {
219
+ if (kfs.length === 0)
220
+ warnings.push(`${c.id}/${l.id}: empty keyframe list`);
221
+ kfs.forEach((k) => { if (k.t < 0 || k.t > c.duration + 1)
222
+ warnings.push(`${c.id}/${l.id}: keyframe at ${k.t}s is outside the comp`); });
223
+ });
224
+ }
225
+ }
226
+ if (!p.comps.some((c) => c.id === p.root))
227
+ warnings.push(`Root comp "${p.root}" does not exist`);
228
+ return warnings;
229
+ };
230
+ // Compact, agent-readable outline of the project.
231
+ export const describe = (p) => {
232
+ const lines = [`Project "${p.name}" — root: ${p.root}`];
233
+ for (const c of p.comps) {
234
+ lines.push(`\nComp ${c.id}${c.name ? ` (${c.name})` : ''}: ${c.width}x${c.height} @${c.fps}fps, ${c.duration}s, bg ${c.background ?? 'transparent'}`);
235
+ if (c.markers?.length)
236
+ lines.push(` markers: ${c.markers.map((m) => `${m.t}s ${m.label}`).join(', ')}`);
237
+ c.layers.forEach((l, i) => {
238
+ const animated = [];
239
+ const walk = (v, path) => {
240
+ if (isPlainObject(v)) {
241
+ if (Array.isArray(v.keyframes))
242
+ animated.push(`${path}@[${v.keyframes.map((k) => k.t).join(',')}]`);
243
+ else
244
+ Object.entries(v).forEach(([k, x]) => walk(x, path ? `${path}.${k}` : k));
245
+ }
246
+ else if (Array.isArray(v))
247
+ v.forEach((x, j) => isPlainObject(x) && walk(x, `${path}.${j}`));
248
+ };
249
+ walk(l, '');
250
+ const extra = l.type === 'text' ? ` "${l.text.replace(/\n/g, ' / ').slice(0, 60)}"${l.animators?.length ? ` animators:${l.animators.map((a) => a.unit).join('+')}` : ''}`
251
+ : l.type === 'video' || l.type === 'image' || l.type === 'audio' ? ` ${l.src}`
252
+ : l.type === 'precomp' ? ` → ${l.comp}`
253
+ : l.type === 'shape' ? ` ${l.shape}` : '';
254
+ lines.push(` [${i}] ${l.id} (${l.type})${extra} ${l.inPoint ?? 0}–${l.outPoint ?? c.duration}s${l.parent ? ` parent:${l.parent}` : ''}${l.matte ? ` matte:${l.matte.layer}` : ''}${l.hidden ? ' hidden' : ''}${animated.length ? `\n animated: ${animated.join(' ')}` : ''}`);
255
+ });
256
+ }
257
+ return lines.join('\n');
258
+ };
259
+ //# sourceMappingURL=ops.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ops.js","sourceRoot":"","sources":["../../src/ops/ops.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { Project } from '../core/model.js';
2
+ export declare const readProject: (file: string) => Project;
3
+ export declare const writeProject: (file: string, p: Project) => void;
4
+ export declare const editProject: <T>(file: string, fn: (p: Project) => T) => T;
@@ -0,0 +1,22 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ export const readProject = (file) => {
4
+ const p = JSON.parse(fs.readFileSync(file, 'utf8'));
5
+ if (p.dtly !== 1)
6
+ throw new Error(`${file} is not a DT.ly project`);
7
+ return p;
8
+ };
9
+ export const writeProject = (file, p) => {
10
+ fs.mkdirSync(path.dirname(path.resolve(file)), { recursive: true });
11
+ const tmp = `${file}.tmp`;
12
+ fs.writeFileSync(tmp, JSON.stringify(p, null, 2));
13
+ fs.renameSync(tmp, file);
14
+ };
15
+ // Load → mutate → save, so every edit is persisted atomically.
16
+ export const editProject = (file, fn) => {
17
+ const p = readProject(file);
18
+ const r = fn(p);
19
+ writeProject(file, p);
20
+ return r;
21
+ };
22
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/ops/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,IAAY,EAAW,EAAE;IACnD,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAY,CAAC;IAC/D,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,yBAAyB,CAAC,CAAC;IACpE,OAAO,CAAC,CAAC;AACX,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,IAAY,EAAE,CAAU,EAAE,EAAE;IACvD,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,EAAC,SAAS,EAAE,IAAI,EAAC,CAAC,CAAC;IAClE,MAAM,GAAG,GAAG,GAAG,IAAI,MAAM,CAAC;IAC1B,EAAE,CAAC,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAClD,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;AAC3B,CAAC,CAAC;AAEF,+DAA+D;AAC/D,MAAM,CAAC,MAAM,WAAW,GAAG,CAAI,IAAY,EAAE,EAAqB,EAAK,EAAE;IACvE,MAAM,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IAC5B,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;IAChB,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACtB,OAAO,CAAC,CAAC;AACX,CAAC,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { Project } from '../core/model.js';
2
+ type Params = Record<string, unknown>;
3
+ export interface Preset {
4
+ kind: 'text' | 'kinetic' | 'opener' | 'slides' | 'transition' | 'element';
5
+ description: string;
6
+ params: string;
7
+ apply: (p: Project, comp: string | undefined, params: Params) => {
8
+ created: string[];
9
+ note?: string;
10
+ };
11
+ }
12
+ export declare const PRESETS: Record<string, Preset>;
13
+ export declare const listPresets: () => string;
14
+ export {};