frameyard 0.8.0 → 0.9.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 (285) hide show
  1. package/CHANGELOG.md +110 -14
  2. package/GLOSSARY.md +112 -2
  3. package/README.md +302 -265
  4. package/dist/assets/integrations.d.ts +8 -4
  5. package/dist/assets/integrations.d.ts.map +1 -1
  6. package/dist/assets/integrations.js +8 -4
  7. package/dist/assets/integrations.js.map +1 -1
  8. package/dist/assets/provenance.d.ts +2 -2
  9. package/dist/assets/provenance.d.ts.map +1 -1
  10. package/dist/assets/provenance.js +5 -3
  11. package/dist/assets/provenance.js.map +1 -1
  12. package/dist/assets/tts-supertonic.d.ts +28 -0
  13. package/dist/assets/tts-supertonic.d.ts.map +1 -0
  14. package/dist/assets/tts-supertonic.js +156 -0
  15. package/dist/assets/tts-supertonic.js.map +1 -0
  16. package/dist/assets/tts.d.ts +18 -6
  17. package/dist/assets/tts.d.ts.map +1 -1
  18. package/dist/assets/tts.js +219 -97
  19. package/dist/assets/tts.js.map +1 -1
  20. package/dist/cli.js +1685 -93
  21. package/dist/cli.js.map +1 -1
  22. package/dist/composition/format.d.ts +1 -1
  23. package/dist/composition/format.d.ts.map +1 -1
  24. package/dist/composition/format.js +1 -1
  25. package/dist/composition/format.js.map +1 -1
  26. package/dist/context.d.ts +82 -0
  27. package/dist/context.d.ts.map +1 -0
  28. package/dist/context.js +277 -0
  29. package/dist/context.js.map +1 -0
  30. package/dist/contracts.d.ts +25 -0
  31. package/dist/contracts.d.ts.map +1 -1
  32. package/dist/contracts.js.map +1 -1
  33. package/dist/doctor.d.ts +14 -1
  34. package/dist/doctor.d.ts.map +1 -1
  35. package/dist/doctor.js +166 -7
  36. package/dist/doctor.js.map +1 -1
  37. package/dist/errors.d.ts +1 -1
  38. package/dist/errors.d.ts.map +1 -1
  39. package/dist/errors.js.map +1 -1
  40. package/dist/fonts/add.d.ts +41 -0
  41. package/dist/fonts/add.d.ts.map +1 -0
  42. package/dist/fonts/add.js +259 -0
  43. package/dist/fonts/add.js.map +1 -0
  44. package/dist/fonts/binary.d.ts +4 -0
  45. package/dist/fonts/binary.d.ts.map +1 -0
  46. package/dist/fonts/binary.js +21 -0
  47. package/dist/fonts/binary.js.map +1 -0
  48. package/dist/fonts/css.d.ts +4 -0
  49. package/dist/fonts/css.d.ts.map +1 -0
  50. package/dist/fonts/css.js +50 -0
  51. package/dist/fonts/css.js.map +1 -0
  52. package/dist/fonts/fontsource.d.ts +107 -0
  53. package/dist/fonts/fontsource.d.ts.map +1 -0
  54. package/dist/fonts/fontsource.js +565 -0
  55. package/dist/fonts/fontsource.js.map +1 -0
  56. package/dist/fonts/index.d.ts +11 -0
  57. package/dist/fonts/index.d.ts.map +1 -0
  58. package/dist/fonts/index.js +11 -0
  59. package/dist/fonts/index.js.map +1 -0
  60. package/dist/fonts/install.d.ts +24 -0
  61. package/dist/fonts/install.d.ts.map +1 -0
  62. package/dist/fonts/install.js +145 -0
  63. package/dist/fonts/install.js.map +1 -0
  64. package/dist/fonts/manifest.d.ts +21 -0
  65. package/dist/fonts/manifest.d.ts.map +1 -0
  66. package/dist/fonts/manifest.js +96 -0
  67. package/dist/fonts/manifest.js.map +1 -0
  68. package/dist/fonts/options.d.ts +9 -0
  69. package/dist/fonts/options.d.ts.map +1 -0
  70. package/dist/fonts/options.js +66 -0
  71. package/dist/fonts/options.js.map +1 -0
  72. package/dist/fonts/schema.d.ts +4 -0
  73. package/dist/fonts/schema.d.ts.map +1 -0
  74. package/dist/fonts/schema.js +316 -0
  75. package/dist/fonts/schema.js.map +1 -0
  76. package/dist/fonts/summary.d.ts +16 -0
  77. package/dist/fonts/summary.d.ts.map +1 -0
  78. package/dist/fonts/summary.js +22 -0
  79. package/dist/fonts/summary.js.map +1 -0
  80. package/dist/fonts/types.d.ts +56 -0
  81. package/dist/fonts/types.d.ts.map +1 -0
  82. package/dist/fonts/types.js +8 -0
  83. package/dist/fonts/types.js.map +1 -0
  84. package/dist/fonts/verify.d.ts +33 -0
  85. package/dist/fonts/verify.d.ts.map +1 -0
  86. package/dist/fonts/verify.js +200 -0
  87. package/dist/fonts/verify.js.map +1 -0
  88. package/dist/html/validate.d.ts.map +1 -1
  89. package/dist/html/validate.js +59 -0
  90. package/dist/html/validate.js.map +1 -1
  91. package/dist/index.d.ts +3 -3
  92. package/dist/index.d.ts.map +1 -1
  93. package/dist/index.js +1 -1
  94. package/dist/index.js.map +1 -1
  95. package/dist/inspect.d.ts +61 -0
  96. package/dist/inspect.d.ts.map +1 -0
  97. package/dist/inspect.js +325 -0
  98. package/dist/inspect.js.map +1 -0
  99. package/dist/lint.d.ts +63 -0
  100. package/dist/lint.d.ts.map +1 -0
  101. package/dist/lint.js +265 -0
  102. package/dist/lint.js.map +1 -0
  103. package/dist/policy.d.ts +69 -0
  104. package/dist/policy.d.ts.map +1 -0
  105. package/dist/policy.js +361 -0
  106. package/dist/policy.js.map +1 -0
  107. package/dist/preview/timeline-data.d.ts +17 -69
  108. package/dist/preview/timeline-data.d.ts.map +1 -1
  109. package/dist/preview/timeline-host.d.ts.map +1 -1
  110. package/dist/preview/timeline-host.js +70 -45
  111. package/dist/preview/timeline-host.js.map +1 -1
  112. package/dist/preview/timeline-main.d.ts.map +1 -1
  113. package/dist/preview/timeline-main.js +47 -4
  114. package/dist/preview/timeline-main.js.map +1 -1
  115. package/dist/project.d.ts +10 -3
  116. package/dist/project.d.ts.map +1 -1
  117. package/dist/project.js +20 -17
  118. package/dist/project.js.map +1 -1
  119. package/dist/renderer/ffmpeg.d.ts +42 -2
  120. package/dist/renderer/ffmpeg.d.ts.map +1 -1
  121. package/dist/renderer/ffmpeg.js +254 -22
  122. package/dist/renderer/ffmpeg.js.map +1 -1
  123. package/dist/renderer/index.js +1 -1
  124. package/dist/renderer/index.js.map +1 -1
  125. package/dist/renderer/keyframe-expressions.d.ts +39 -0
  126. package/dist/renderer/keyframe-expressions.d.ts.map +1 -0
  127. package/dist/renderer/keyframe-expressions.js +180 -0
  128. package/dist/renderer/keyframe-expressions.js.map +1 -0
  129. package/dist/renderer/timeline.d.ts +2 -0
  130. package/dist/renderer/timeline.d.ts.map +1 -1
  131. package/dist/renderer/timeline.js +89 -116
  132. package/dist/renderer/timeline.js.map +1 -1
  133. package/dist/runtime/host.d.ts.map +1 -1
  134. package/dist/runtime/host.js +4 -0
  135. package/dist/runtime/host.js.map +1 -1
  136. package/dist/scaffold.d.ts +3 -0
  137. package/dist/scaffold.d.ts.map +1 -1
  138. package/dist/scaffold.js +48 -320
  139. package/dist/scaffold.js.map +1 -1
  140. package/dist/server/composition-html.d.ts +2 -0
  141. package/dist/server/composition-html.d.ts.map +1 -1
  142. package/dist/server/composition-html.js +7 -0
  143. package/dist/server/composition-html.js.map +1 -1
  144. package/dist/server/server.d.ts.map +1 -1
  145. package/dist/server/server.js +31 -1
  146. package/dist/server/server.js.map +1 -1
  147. package/dist/server/timeline-preview-data.d.ts.map +1 -1
  148. package/dist/server/timeline-preview-data.js +12 -34
  149. package/dist/server/timeline-preview-data.js.map +1 -1
  150. package/dist/server/timeline-preview-html.d.ts.map +1 -1
  151. package/dist/server/timeline-preview-html.js +18 -2
  152. package/dist/server/timeline-preview-html.js.map +1 -1
  153. package/dist/templates.d.ts +16 -0
  154. package/dist/templates.d.ts.map +1 -0
  155. package/dist/templates.js +186 -0
  156. package/dist/templates.js.map +1 -0
  157. package/dist/timeline/easing.d.ts +36 -0
  158. package/dist/timeline/easing.d.ts.map +1 -0
  159. package/dist/timeline/easing.js +225 -0
  160. package/dist/timeline/easing.js.map +1 -0
  161. package/dist/timeline/keyframes.d.ts +23 -0
  162. package/dist/timeline/keyframes.d.ts.map +1 -0
  163. package/dist/timeline/keyframes.js +95 -0
  164. package/dist/timeline/keyframes.js.map +1 -0
  165. package/dist/timeline/plan.d.ts +6 -12
  166. package/dist/timeline/plan.d.ts.map +1 -1
  167. package/dist/timeline/plan.js +17 -30
  168. package/dist/timeline/plan.js.map +1 -1
  169. package/dist/timeline/resolve.d.ts +12 -0
  170. package/dist/timeline/resolve.d.ts.map +1 -1
  171. package/dist/timeline/resolve.js +105 -9
  172. package/dist/timeline/resolve.js.map +1 -1
  173. package/dist/timeline/scene.d.ts +126 -0
  174. package/dist/timeline/scene.d.ts.map +1 -0
  175. package/dist/timeline/scene.js +109 -0
  176. package/dist/timeline/scene.js.map +1 -0
  177. package/dist/timeline/schema.d.ts +31 -0
  178. package/dist/timeline/schema.d.ts.map +1 -1
  179. package/dist/timeline/schema.js +240 -9
  180. package/dist/timeline/schema.js.map +1 -1
  181. package/dist/timeline/transitions.d.ts +21 -0
  182. package/dist/timeline/transitions.d.ts.map +1 -0
  183. package/dist/timeline/transitions.js +23 -0
  184. package/dist/timeline/transitions.js.map +1 -0
  185. package/dist/version.d.ts +1 -1
  186. package/dist/version.js +1 -1
  187. package/docs/adr/0007-make-html-documents-the-composition-unit.md +1 -1
  188. package/docs/adr/0010-make-timelines-the-render-unit.md +3 -2
  189. package/docs/adr/0014-compose-timeline-clips-with-css-blend-modes.md +2 -1
  190. package/docs/adr/0015-inherit-composition-format-from-the-project.md +2 -2
  191. package/docs/adr/0016-author-compositions-as-html-fragments.md +1 -1
  192. package/docs/adr/0018-animate-timeline-clips-with-keyframes.md +35 -0
  193. package/docs/adr/0019-make-same-track-overlap-the-transition-window.md +36 -0
  194. package/docs/adr/0020-crossfade-audio-clips-on-audio-tracks.md +27 -0
  195. package/docs/adr/0021-project-timeline-scenes-once.md +32 -0
  196. package/docs/adr/0022-gate-heavy-operations-with-a-workspace-resource-policy.md +35 -0
  197. package/docs/adr/0023-pin-fonts-as-project-assets.md +98 -0
  198. package/docs/migration-0.4.md +2 -2
  199. package/docs/preview-testing.md +19 -6
  200. package/docs/{v0.1-design.md → v0.x-design.md} +55 -30
  201. package/examples/blend/README.md +3 -3
  202. package/examples/demo/README.md +2 -2
  203. package/examples/intro/README.md +71 -0
  204. package/examples/intro/assets/fonts/figtree/LICENSE.txt +93 -0
  205. package/examples/intro/assets/fonts/figtree/figtree-latin-wght-normal.woff2 +0 -0
  206. package/examples/intro/assets/fonts/instrument-serif/LICENSE.txt +93 -0
  207. package/examples/intro/assets/fonts/instrument-serif/instrument-serif-latin-400-italic.woff2 +0 -0
  208. package/examples/intro/assets/fonts/space-mono/LICENSE.txt +93 -0
  209. package/examples/intro/assets/fonts/space-mono/space-mono-latin-400-normal.woff2 +0 -0
  210. package/examples/intro/assets/fonts/space-mono/space-mono-latin-700-normal.woff2 +0 -0
  211. package/examples/intro/assets/grain.png +0 -0
  212. package/examples/intro/assets/score.ogg +0 -0
  213. package/examples/intro/compositions/brand.html +412 -0
  214. package/examples/intro/compositions/chrome.controller.js +63 -0
  215. package/examples/intro/compositions/chrome.html +256 -0
  216. package/examples/intro/compositions/lattice.controller.js +148 -0
  217. package/examples/intro/compositions/lattice.html +308 -0
  218. package/examples/intro/compositions/opening.html +504 -0
  219. package/examples/intro/compositions/studio.html +930 -0
  220. package/examples/intro/compositions/theme.css +218 -0
  221. package/examples/intro/fy.config.js +13 -0
  222. package/examples/intro/fy.fonts.json +100 -0
  223. package/examples/intro/scripts/make-grain.mjs +79 -0
  224. package/examples/intro/scripts/make-score.mjs +702 -0
  225. package/examples/intro/timelines/intro.timeline.json +60 -0
  226. package/examples/keyframes/README.md +76 -0
  227. package/examples/keyframes/compositions/backdrop.html +60 -0
  228. package/examples/keyframes/compositions/card.html +99 -0
  229. package/examples/keyframes/fy.config.js +10 -0
  230. package/examples/keyframes/timelines/keyframes.timeline.json +60 -0
  231. package/examples/nested/README.md +112 -0
  232. package/examples/nested/assets/pulse.wav +0 -0
  233. package/examples/nested/compositions/backdrop.html +84 -0
  234. package/examples/nested/compositions/card.html +275 -0
  235. package/examples/nested/compositions/overlay.html +307 -0
  236. package/examples/nested/fy.config.js +13 -0
  237. package/examples/nested/scripts/make-pulse.sh +20 -0
  238. package/examples/nested/timelines/chapter-a.timeline.json +39 -0
  239. package/examples/nested/timelines/chapter-b.timeline.json +39 -0
  240. package/examples/nested/timelines/nested-reel.timeline.json +52 -0
  241. package/examples/static/README.md +2 -2
  242. package/examples/transitions/README.md +128 -0
  243. package/examples/transitions/assets/alpha.wav +0 -0
  244. package/examples/transitions/assets/beta.wav +0 -0
  245. package/examples/transitions/assets/gamma.wav +0 -0
  246. package/examples/transitions/compositions/alpha.html +56 -0
  247. package/examples/transitions/compositions/beta.html +56 -0
  248. package/examples/transitions/compositions/gamma.html +56 -0
  249. package/examples/transitions/fy.config.js +12 -0
  250. package/examples/transitions/timelines/audio-crossfade.timeline.json +44 -0
  251. package/examples/transitions/timelines/transitions.timeline.json +31 -0
  252. package/examples/video/README.md +4 -4
  253. package/examples/webgl/README.md +1 -1
  254. package/package.json +12 -5
  255. package/scaffolds/init/AGENTS.md +131 -0
  256. package/scaffolds/init/README.md +56 -0
  257. package/scaffolds/init/compositions/hello.html +79 -0
  258. package/scaffolds/init/fy.config.js +9 -0
  259. package/scaffolds/init/gitignore.template +1 -0
  260. package/scaffolds/init/package.json +11 -0
  261. package/scaffolds/init/props/hello.json +4 -0
  262. package/scaffolds/init/props/main.json +6 -0
  263. package/scaffolds/init/timelines/main.timeline.json +20 -0
  264. package/scaffolds/local-models/LOCAL-MODELS.md +77 -0
  265. package/scaffolds/local-models/fy.policy.json +5 -0
  266. package/scaffolds/local-models/opencode/opencode.jsonc +17 -0
  267. package/scaffolds/local-models/pi/APPEND_SYSTEM.md +21 -0
  268. package/scaffolds/local-models/pi/sandbox.json +15 -0
  269. package/scaffolds/local-models/pi/settings.json +15 -0
  270. package/skills/frameyard/README.md +1 -0
  271. package/skills/frameyard/SKILL.md +59 -61
  272. package/skills/frameyard/references/audio-assets.md +32 -3
  273. package/skills/frameyard/references/common-mistakes.md +53 -2
  274. package/skills/frameyard/references/deterministic-authoring.md +10 -3
  275. package/skills/frameyard/references/diagnostics.md +31 -1
  276. package/skills/frameyard/references/failure-recovery.md +32 -6
  277. package/skills/frameyard/references/fonts.md +132 -0
  278. package/skills/frameyard/references/json-results.md +119 -6
  279. package/skills/frameyard/references/quick-reference.md +222 -0
  280. package/skills/frameyard/references/timelines.md +97 -7
  281. /package/examples/blend/{video.config.js → fy.config.js} +0 -0
  282. /package/examples/demo/{video.config.js → fy.config.js} +0 -0
  283. /package/examples/static/{video.config.js → fy.config.js} +0 -0
  284. /package/examples/video/{video.config.js → fy.config.js} +0 -0
  285. /package/examples/webgl/{video.config.js → fy.config.js} +0 -0
package/dist/policy.js ADDED
@@ -0,0 +1,361 @@
1
+ import { readFile, stat } from "node:fs/promises";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import { isPlainObject } from "./contracts.js";
5
+ import { FrameyardError } from "./errors.js";
6
+ /** Project-local resource policy file discovered from the working directory upward. */
7
+ export const POLICY_FILE_NAME = "fy.policy.json";
8
+ export const POLICY_TIERS = ["light", "authoring", "full"];
9
+ export const RESOURCE_PROFILES = ["shared-cpu"];
10
+ export const MAX_STILL_FRAMES = 32;
11
+ export const SHARED_CPU_MAX_WORKERS = 2;
12
+ export const SHARED_CPU_MAX_CONCURRENCY = 1;
13
+ const POLICY_VERSION = 1;
14
+ const POLICY_FIELDS = new Set(["version", "policy", "profile", "maxStillFrames", "allowOverwrite"]);
15
+ export const TIER_DEFAULTS = {
16
+ light: { maxStillFrames: 1, allowOverwrite: false },
17
+ authoring: { maxStillFrames: 4, allowOverwrite: false },
18
+ full: { maxStillFrames: MAX_STILL_FRAMES, allowOverwrite: true },
19
+ };
20
+ function isPolicyTier(value) {
21
+ return typeof value === "string" && POLICY_TIERS.includes(value);
22
+ }
23
+ function isResourceProfile(value) {
24
+ return typeof value === "string" && RESOURCE_PROFILES.includes(value);
25
+ }
26
+ function policyError(message, details) {
27
+ throw new FrameyardError("POLICY_INVALID", message, { details });
28
+ }
29
+ async function isFile(filePath) {
30
+ try {
31
+ return (await stat(filePath)).isFile();
32
+ }
33
+ catch {
34
+ return false;
35
+ }
36
+ }
37
+ /** Walks up from a directory until it finds fy.policy.json. */
38
+ export async function findPolicyFile(start = process.cwd()) {
39
+ let current = path.resolve(start);
40
+ try {
41
+ if (!(await stat(current)).isDirectory()) {
42
+ current = path.dirname(current);
43
+ }
44
+ }
45
+ catch {
46
+ return undefined;
47
+ }
48
+ while (true) {
49
+ const candidate = path.join(current, POLICY_FILE_NAME);
50
+ if (await isFile(candidate)) {
51
+ return candidate;
52
+ }
53
+ const parent = path.dirname(current);
54
+ if (parent === current) {
55
+ return undefined;
56
+ }
57
+ current = parent;
58
+ }
59
+ }
60
+ function validatePolicyFile(value, filePath) {
61
+ if (!isPlainObject(value)) {
62
+ policyError(`${POLICY_FILE_NAME} must contain a JSON object.`, {
63
+ path: filePath,
64
+ suggestion: `Write a policy file such as { "version": 1, "policy": "authoring" }.`,
65
+ });
66
+ }
67
+ for (const key of Object.keys(value)) {
68
+ if (!POLICY_FIELDS.has(key)) {
69
+ policyError(`${POLICY_FILE_NAME} contains an unknown field "${key}".`, {
70
+ path: filePath,
71
+ jsonPath: `$.${key}`,
72
+ allowed: [...POLICY_FIELDS],
73
+ suggestion: "Remove the field or use one of the documented policy fields.",
74
+ });
75
+ }
76
+ }
77
+ if (value.version !== POLICY_VERSION) {
78
+ policyError(`${POLICY_FILE_NAME} must declare "version": ${POLICY_VERSION}.`, {
79
+ path: filePath,
80
+ jsonPath: "$.version",
81
+ value: value.version,
82
+ allowed: [POLICY_VERSION],
83
+ });
84
+ }
85
+ if (!isPolicyTier(value.policy)) {
86
+ policyError(`${POLICY_FILE_NAME} must declare policy as "light", "authoring", or "full".`, {
87
+ path: filePath,
88
+ jsonPath: "$.policy",
89
+ value: value.policy,
90
+ allowed: [...POLICY_TIERS],
91
+ });
92
+ }
93
+ const tier = value.policy;
94
+ const defaults = TIER_DEFAULTS[tier];
95
+ if (value.profile !== undefined && !isResourceProfile(value.profile)) {
96
+ policyError(`${POLICY_FILE_NAME} profile must be "shared-cpu".`, {
97
+ path: filePath,
98
+ jsonPath: "$.profile",
99
+ value: value.profile,
100
+ allowed: [...RESOURCE_PROFILES],
101
+ });
102
+ }
103
+ let maxStillFrames = defaults.maxStillFrames;
104
+ if (value.maxStillFrames !== undefined) {
105
+ if (!Number.isInteger(value.maxStillFrames) ||
106
+ value.maxStillFrames < 1 ||
107
+ value.maxStillFrames > MAX_STILL_FRAMES) {
108
+ policyError(`${POLICY_FILE_NAME} maxStillFrames must be an integer from 1 to ${MAX_STILL_FRAMES}.`, {
109
+ path: filePath,
110
+ jsonPath: "$.maxStillFrames",
111
+ value: value.maxStillFrames,
112
+ allowed: { min: 1, max: MAX_STILL_FRAMES },
113
+ });
114
+ }
115
+ if (value.maxStillFrames > defaults.maxStillFrames) {
116
+ policyError(`${POLICY_FILE_NAME} maxStillFrames cannot exceed the ${tier} default of ${defaults.maxStillFrames}.`, {
117
+ path: filePath,
118
+ jsonPath: "$.maxStillFrames",
119
+ value: value.maxStillFrames,
120
+ limit: defaults.maxStillFrames,
121
+ suggestion: "A policy file can only tighten the tier limits.",
122
+ });
123
+ }
124
+ maxStillFrames = value.maxStillFrames;
125
+ }
126
+ let allowOverwrite = defaults.allowOverwrite;
127
+ if (value.allowOverwrite !== undefined) {
128
+ if (typeof value.allowOverwrite !== "boolean") {
129
+ policyError(`${POLICY_FILE_NAME} allowOverwrite must be a boolean.`, {
130
+ path: filePath,
131
+ jsonPath: "$.allowOverwrite",
132
+ value: value.allowOverwrite,
133
+ });
134
+ }
135
+ if (value.allowOverwrite === true && !defaults.allowOverwrite) {
136
+ policyError(`${POLICY_FILE_NAME} allowOverwrite cannot be true in the ${tier} tier.`, {
137
+ path: filePath,
138
+ jsonPath: "$.allowOverwrite",
139
+ value: value.allowOverwrite,
140
+ suggestion: "A policy file can only tighten the tier limits; use FRAMEYARD_POLICY=full to allow overwrites.",
141
+ });
142
+ }
143
+ allowOverwrite = value.allowOverwrite;
144
+ }
145
+ return {
146
+ tier,
147
+ ...(value.profile !== undefined ? { profile: value.profile } : {}),
148
+ maxStillFrames,
149
+ allowOverwrite,
150
+ };
151
+ }
152
+ async function loadPolicyFile(filePath) {
153
+ let text;
154
+ try {
155
+ text = await readFile(filePath, "utf8");
156
+ }
157
+ catch (error) {
158
+ throw new FrameyardError("POLICY_INVALID", `Could not read ${filePath}.`, {
159
+ cause: error,
160
+ details: { path: filePath },
161
+ });
162
+ }
163
+ let value;
164
+ try {
165
+ value = JSON.parse(text);
166
+ }
167
+ catch (error) {
168
+ policyError(`${filePath} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`, {
169
+ path: filePath,
170
+ });
171
+ }
172
+ return {
173
+ ...validatePolicyFile(value, filePath),
174
+ source: "file",
175
+ path: filePath,
176
+ };
177
+ }
178
+ /**
179
+ * Loads the resource policy for the current workspace.
180
+ *
181
+ * `FRAMEYARD_POLICY` replaces the policy file entirely, so an explicit human
182
+ * override also resets the file's profile and tightened limits. Without the
183
+ * variable, the nearest `fy.policy.json` from `cwd` upward wins; without
184
+ * a file, the default is `full`.
185
+ */
186
+ export async function loadResourcePolicy(options = {}) {
187
+ const env = options.env ?? process.env;
188
+ const requested = env.FRAMEYARD_POLICY;
189
+ if (requested !== undefined) {
190
+ const value = requested.trim();
191
+ if (!isPolicyTier(value)) {
192
+ policyError(`FRAMEYARD_POLICY must be "light", "authoring", or "full"; received "${requested}".`, {
193
+ source: "env",
194
+ value: requested,
195
+ allowed: [...POLICY_TIERS],
196
+ });
197
+ }
198
+ const defaults = TIER_DEFAULTS[value];
199
+ return {
200
+ tier: value,
201
+ ...defaults,
202
+ source: "env",
203
+ };
204
+ }
205
+ const filePath = await findPolicyFile(options.cwd ?? process.cwd());
206
+ if (filePath === undefined) {
207
+ const defaults = TIER_DEFAULTS.full;
208
+ return {
209
+ tier: "full",
210
+ ...defaults,
211
+ source: "default",
212
+ };
213
+ }
214
+ return loadPolicyFile(filePath);
215
+ }
216
+ /** Resolves the effective profile from the CLI flag and the policy file. */
217
+ export function resolveProfile(policy, requested) {
218
+ if (requested === undefined) {
219
+ return policy.profile;
220
+ }
221
+ if (!isResourceProfile(requested)) {
222
+ throw new FrameyardError("USAGE", `--profile must be "shared-cpu"; received "${requested}".`);
223
+ }
224
+ return requested;
225
+ }
226
+ /** Returns the operation allowlist for a tier. */
227
+ export function allowedOperations(tier) {
228
+ const operations = ["lint", "context", "doctor", "init", "dev", "still", "font"];
229
+ if (tier !== "light") {
230
+ operations.push("check");
231
+ }
232
+ if (tier === "full") {
233
+ operations.push("tts", "transcribe", "render");
234
+ }
235
+ return operations;
236
+ }
237
+ export function operationAllowed(tier, operation) {
238
+ return allowedOperations(tier).includes(operation);
239
+ }
240
+ function operationSuggestion(operation, tier) {
241
+ if (operation === "check") {
242
+ return "Use lint and still in the light tier, or run check from authoring or full.";
243
+ }
244
+ if (operation === "render" || operation === "tts" || operation === "transcribe") {
245
+ return `Run the command with --dry-run to produce a handoff plan, or set FRAMEYARD_POLICY=full when the user explicitly asks for the heavy operation.`;
246
+ }
247
+ if (operation === "font") {
248
+ return `Font list and verify are available in every tier; adding fonts requires authoring or full.`;
249
+ }
250
+ return `The ${tier} policy does not allow ${operation}.`;
251
+ }
252
+ export function assertOperationAllowed(policy, operation, options = {}) {
253
+ if (options.dryRun === true) {
254
+ return;
255
+ }
256
+ if (operationAllowed(policy.tier, operation)) {
257
+ return;
258
+ }
259
+ throw new FrameyardError("RESOURCE_POLICY_BLOCKED", `"${operation}" is blocked by the ${policy.tier} resource policy.`, {
260
+ details: {
261
+ policy: policy.tier,
262
+ operation,
263
+ allowed: allowedOperations(policy.tier),
264
+ suggestion: operationSuggestion(operation, policy.tier),
265
+ },
266
+ });
267
+ }
268
+ const TIER_ORDER = { light: 0, authoring: 1, full: 2 };
269
+ /** Requires a minimum tier for subcommands that share one policy operation. */
270
+ export function assertPolicyTier(policy, required, operation) {
271
+ if (TIER_ORDER[policy.tier] >= TIER_ORDER[required]) {
272
+ return;
273
+ }
274
+ throw new FrameyardError("RESOURCE_POLICY_BLOCKED", `"${operation}" requires the ${required} resource policy; the active policy is ${policy.tier}.`, {
275
+ details: {
276
+ policy: policy.tier,
277
+ required,
278
+ operation,
279
+ allowed: allowedOperations(policy.tier),
280
+ suggestion: `Ask the user to run the command with FRAMEYARD_POLICY=${required} when it is intended.`,
281
+ },
282
+ });
283
+ }
284
+ export function assertStillFrameLimit(policy, requested) {
285
+ if (requested <= policy.maxStillFrames) {
286
+ return;
287
+ }
288
+ throw new FrameyardError("RESOURCE_POLICY_LIMIT", `Still requested ${requested} frames; the ${policy.tier} policy allows at most ${policy.maxStillFrames}.`, {
289
+ details: {
290
+ policy: policy.tier,
291
+ limit: policy.maxStillFrames,
292
+ requested,
293
+ suggestion: `Capture at most ${policy.maxStillFrames} frames per invocation, or use FRAMEYARD_POLICY=full for a larger inspection batch.`,
294
+ },
295
+ });
296
+ }
297
+ export function assertOverwriteAllowed(policy, operation) {
298
+ if (policy.allowOverwrite) {
299
+ return;
300
+ }
301
+ throw new FrameyardError("RESOURCE_POLICY_BLOCKED", `--${operation} is blocked by the ${policy.tier} resource policy.`, {
302
+ details: {
303
+ policy: policy.tier,
304
+ operation,
305
+ allowed: false,
306
+ suggestion: "Use a new output path, or ask the user to run the command with FRAMEYARD_POLICY=full when replacement is intended.",
307
+ },
308
+ });
309
+ }
310
+ export function assertProfileLimit(profile, option, requested, limit) {
311
+ if (requested <= limit) {
312
+ return;
313
+ }
314
+ throw new FrameyardError("RESOURCE_PROFILE_CONFLICT", `--${option} ${requested} exceeds the ${profile} profile limit of ${limit}.`, {
315
+ details: {
316
+ profile,
317
+ option,
318
+ requested,
319
+ limit,
320
+ suggestion: "Lower the value, or omit --profile when the machine is not shared with a local model.",
321
+ },
322
+ });
323
+ }
324
+ export function shouldLowerPriority(policy, profile, requested) {
325
+ return requested || profile === "shared-cpu" || policy.tier === "authoring" || policy.tier === "light";
326
+ }
327
+ /**
328
+ * Lowers the current process priority so it yields to a local model. Children
329
+ * inherit the nice value on Unix. This is best effort on platforms that do not
330
+ * expose process priorities.
331
+ */
332
+ export function lowerProcessPriority() {
333
+ try {
334
+ const priority = process.platform === "win32" ? os.constants.priority.PRIORITY_BELOW_NORMAL : os.constants.priority.PRIORITY_LOW;
335
+ os.setPriority(0, priority);
336
+ }
337
+ catch {
338
+ // Priority changes are advisory; rendering still proceeds when unsupported.
339
+ }
340
+ }
341
+ /** Serializable policy details for JSON results and diagnostics. */
342
+ export function policyDetails(policy) {
343
+ return {
344
+ policy: policy.tier,
345
+ ...(policy.profile !== undefined ? { profile: policy.profile } : {}),
346
+ maxStillFrames: policy.maxStillFrames,
347
+ allowOverwrite: policy.allowOverwrite,
348
+ source: policy.source,
349
+ ...(policy.path !== undefined ? { path: policy.path } : {}),
350
+ };
351
+ }
352
+ export function describePolicy(policy) {
353
+ const parts = [policy.tier];
354
+ if (policy.profile !== undefined) {
355
+ parts.push(policy.profile);
356
+ }
357
+ parts.push(`still ≤${policy.maxStillFrames}`);
358
+ parts.push(policy.allowOverwrite ? "overwrite allowed" : "overwrite blocked");
359
+ return parts.join(", ");
360
+ }
361
+ //# sourceMappingURL=policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.js","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"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"}
@@ -1,68 +1,18 @@
1
- import type { CompositionDiagnostic, Props } from "../contracts.js";
2
- import type { BlendMode } from "../timeline/schema.js";
3
- export type TimelinePreviewFit = "contain" | "cover" | "stretch";
4
- export interface TimelinePreviewTransform {
5
- fit: TimelinePreviewFit;
6
- x: number;
7
- y: number;
8
- width?: number;
9
- height?: number;
10
- scale: number;
11
- rotation: number;
12
- opacity: number;
13
- }
14
- export interface TimelinePreviewClipAudio {
15
- muted: boolean;
16
- gain: number;
17
- }
18
- export interface TimelinePreviewCompositionSource {
19
- kind: "composition";
20
- id: string;
1
+ import type { AudioVolumeEnvelope, CompositionDiagnostic } from "../contracts.js";
2
+ import type { TimelineSceneClip, TimelineSceneCompositionSource, TimelineSceneInput, TimelineSceneMediaSource, TimelineSceneNestedSource, TimelineSceneTransition } from "../timeline/scene.js";
3
+ export interface TimelinePreviewCompositionSource extends TimelineSceneCompositionSource {
21
4
  url: string;
22
- width: number;
23
- height: number;
24
- /** True when the composition is captured once and never seeked. */
25
- static?: boolean;
26
- durationInFrames?: number;
27
5
  }
28
- export interface TimelinePreviewNestedTimelineSource {
29
- kind: "timeline";
30
- id: string;
6
+ export interface TimelinePreviewNestedSource extends TimelineSceneNestedSource {
31
7
  url: string;
32
- width: number;
33
- height: number;
34
- durationInFrames: number;
35
8
  }
36
- export interface TimelinePreviewMediaSource {
37
- kind: "video" | "image" | "audio";
38
- src: string;
9
+ export interface TimelinePreviewMediaSource extends TimelineSceneMediaSource {
39
10
  url: string;
40
- width?: number;
41
- height?: number;
42
- durationInFrames?: number;
43
- hasAudio?: boolean;
44
- }
45
- export type TimelinePreviewSource = TimelinePreviewCompositionSource | TimelinePreviewNestedTimelineSource | TimelinePreviewMediaSource;
46
- export interface TimelinePreviewClip {
47
- id: string;
48
- track: string;
49
- source: TimelinePreviewSource;
50
- start: number;
51
- duration: number;
52
- end: number;
53
- sourceIn: number;
54
- props?: Props;
55
- transform: TimelinePreviewTransform;
56
- blend: BlendMode;
57
- audio: TimelinePreviewClipAudio;
58
- }
59
- export interface TimelinePreviewTrack {
60
- id: string;
61
- kind: "video" | "audio";
62
- name?: string;
63
- gain?: number;
64
- muted?: boolean;
65
11
  }
12
+ export type TimelinePreviewSource = TimelinePreviewCompositionSource | TimelinePreviewNestedSource | TimelinePreviewMediaSource;
13
+ /** A resolved timeline clip with a browser-fetchable URL on its source. */
14
+ export type TimelinePreviewClip = TimelineSceneClip<TimelinePreviewSource>;
15
+ export type TimelinePreviewTransition = TimelineSceneTransition;
66
16
  export interface TimelinePreviewAudioClip {
67
17
  src: string;
68
18
  url: string;
@@ -70,19 +20,17 @@ export interface TimelinePreviewAudioClip {
70
20
  trimStart: number;
71
21
  trimDuration?: number;
72
22
  volume: number;
73
- }
74
- export interface TimelinePreviewData {
23
+ envelopes?: AudioVolumeEnvelope[];
24
+ }
25
+ /**
26
+ * The serialized resolved timeline the preview host projects on every seek.
27
+ * Absolute paths are replaced by URLs; everything else keeps the resolved
28
+ * shape so the scene module can run in the browser unchanged.
29
+ */
30
+ export interface TimelinePreviewData extends TimelineSceneInput<TimelinePreviewSource> {
75
31
  timeline: string;
76
32
  entry: string;
77
- format: {
78
- width: number;
79
- height: number;
80
- fps: number;
81
- };
82
- durationInFrames: number;
83
33
  background?: string;
84
- tracks: TimelinePreviewTrack[];
85
- clips: TimelinePreviewClip[];
86
34
  audioClips: TimelinePreviewAudioClip[];
87
35
  diagnostics: CompositionDiagnostic[];
88
36
  }
@@ -1 +1 @@
1
- {"version":3,"file":"timeline-data.d.ts","sourceRoot":"","sources":["../../src/preview/timeline-data.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"timeline-data.d.ts","sourceRoot":"","sources":["../../src/preview/timeline-data.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAClF,OAAO,KAAK,EACV,iBAAiB,EACjB,8BAA8B,EAC9B,kBAAkB,EAClB,wBAAwB,EACxB,yBAAyB,EACzB,uBAAuB,EACxB,MAAM,sBAAsB,CAAC;AAE9B,MAAM,WAAW,gCAAiC,SAAQ,8BAA8B;IACtF,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,2BAA4B,SAAQ,yBAAyB;IAC5E,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,0BAA2B,SAAQ,wBAAwB;IAC1E,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,MAAM,qBAAqB,GAC7B,gCAAgC,GAChC,2BAA2B,GAC3B,0BAA0B,CAAC;AAE/B,2EAA2E;AAC3E,MAAM,MAAM,mBAAmB,GAAG,iBAAiB,CAAC,qBAAqB,CAAC,CAAC;AAE3E,MAAM,MAAM,yBAAyB,GAAG,uBAAuB,CAAC;AAEhE,MAAM,WAAW,wBAAwB;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,mBAAmB,EAAE,CAAC;CACnC;AAED;;;;GAIG;AACH,MAAM,WAAW,mBAAoB,SAAQ,kBAAkB,CAAC,qBAAqB,CAAC;IACpF,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,wBAAwB,EAAE,CAAC;IACvC,WAAW,EAAE,qBAAqB,EAAE,CAAC;CACtC"}
@@ -1 +1 @@
1
- {"version":3,"file":"timeline-host.d.ts","sourceRoot":"","sources":["../../src/preview/timeline-host.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,mBAAmB,EAGpB,MAAM,oBAAoB,CAAC;AAkC5B,MAAM,WAAW,mBAAmB;IAClC,8DAA8D;IAC9D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kDAAkD;IAClD,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IAC/C,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB,0EAA0E;IAC1E,aAAa,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;IACtE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAkHD,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,mBAAmB,EACzB,OAAO,GAAE,mBAAwB,GAChC,YAAY,CAwOd"}
1
+ {"version":3,"file":"timeline-host.d.ts","sourceRoot":"","sources":["../../src/preview/timeline-host.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,mBAAmB,EAAyB,MAAM,oBAAoB,CAAC;AAoCrF,MAAM,WAAW,mBAAmB;IAClC,8DAA8D;IAC9D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kDAAkD;IAClD,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IAC/C,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB,0EAA0E;IAC1E,aAAa,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;IACtE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AA+HD,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,mBAAmB,EACzB,OAAO,GAAE,mBAAwB,GAChC,YAAY,CAoPd"}