@litfamily/litopencode 1.0.31 → 1.0.33

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 (282) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/README-Ko-KR.md +6 -6
  3. package/README.md +6 -6
  4. package/TRADEMARK.md +12 -0
  5. package/dist/activation-primary-prompts.js +5 -1
  6. package/dist/activation-probe.js +1 -0
  7. package/dist/activation-prompt-utils.d.ts +1 -1
  8. package/dist/activation-reentry.d.ts +20 -0
  9. package/dist/activation-reentry.js +110 -1
  10. package/dist/activation-routing.d.ts +2 -1
  11. package/dist/activation-routing.js +100 -11
  12. package/dist/activation-workflow-prompts.d.ts +4 -0
  13. package/dist/activation-workflow-prompts.js +30 -0
  14. package/dist/activation.d.ts +1 -1
  15. package/dist/activation.js +44 -5
  16. package/dist/adhd-next.d.ts +51 -0
  17. package/dist/adhd-next.js +150 -0
  18. package/dist/agents/defaults.js +1 -1
  19. package/dist/cli/managed-skill-assets.d.ts +1 -1
  20. package/dist/cli/managed-skill-assets.js +7 -1
  21. package/dist/cli/native-skill-integrity.js +1 -1
  22. package/dist/cli.js +7 -1
  23. package/dist/commands.d.ts +28 -1
  24. package/dist/commands.js +58 -5
  25. package/dist/durable-plan.d.ts +5 -1
  26. package/dist/durable-plan.js +14 -2
  27. package/dist/features.d.ts +80 -1
  28. package/dist/features.js +105 -1
  29. package/dist/hooks.js +3 -0
  30. package/dist/ledger.js +12 -1
  31. package/dist/plan-scope-roots.d.ts +23 -0
  32. package/dist/plan-scope-roots.js +116 -0
  33. package/dist/restart-notice.d.ts +7 -0
  34. package/dist/restart-notice.js +40 -0
  35. package/dist/secret-shapes.js +5 -5
  36. package/dist/server.js +4 -0
  37. package/dist/session-liveness.d.ts +20 -0
  38. package/dist/session-liveness.js +99 -0
  39. package/dist/skills.d.ts +22 -1
  40. package/dist/skills.js +36 -0
  41. package/dist/start-work-typed.d.ts +34 -0
  42. package/dist/start-work-typed.js +167 -0
  43. package/dist/state.d.ts +3 -0
  44. package/dist/state.js +3 -0
  45. package/dist/tools.js +22 -2
  46. package/dist/tui/mission-band.d.ts +22 -1
  47. package/dist/tui/mission-band.js +75 -16
  48. package/dist/tui/mission-looks.d.ts +38 -0
  49. package/dist/tui/mission-looks.js +73 -0
  50. package/dist/tui/mission-model.d.ts +2 -0
  51. package/dist/tui/mission-model.js +3 -1
  52. package/dist/tui/mission-rainbow.d.ts +33 -0
  53. package/dist/tui/mission-rainbow.js +90 -0
  54. package/dist/tui/mission-source.d.ts +49 -0
  55. package/dist/tui/mission-source.js +217 -2
  56. package/dist/tui/mission-text.d.ts +2 -0
  57. package/dist/tui/mission-text.js +9 -1
  58. package/dist/tui/mission-threads.d.ts +58 -0
  59. package/dist/tui/mission-threads.js +128 -0
  60. package/dist/tui.js +112 -7
  61. package/dist/uiux-visual-catalog.js +8 -1
  62. package/dist/v2/events.js +3 -0
  63. package/dist/v2/session-hooks.js +38 -5
  64. package/dist/workflow-stack.d.ts +53 -0
  65. package/dist/workflow-stack.js +196 -0
  66. package/docs/assets/readme/badge-version.svg +1 -1
  67. package/docs/assets/skills/lit-schematic.webp +0 -0
  68. package/docs/reference-Ko-KR.md +48 -3
  69. package/docs/reference.md +54 -3
  70. package/package.json +1 -1
  71. package/skills/frontend-ui-ux/SKILL.md +3 -2
  72. package/skills/frontend-ui-ux/kit/components.css +414 -0
  73. package/skills/frontend-ui-ux/kit/fonts.json +22 -0
  74. package/skills/frontend-ui-ux/kit/layouts/landing.html +164 -0
  75. package/skills/frontend-ui-ux/kit/layouts/settings.html +114 -0
  76. package/skills/frontend-ui-ux/kit/layouts/workspace.html +115 -0
  77. package/skills/frontend-ui-ux/kit/styles/computational-brutalism.json +227 -0
  78. package/skills/frontend-ui-ux/kit/styles/field-notes.json +205 -0
  79. package/skills/frontend-ui-ux/kit/styles/graphite.json +200 -0
  80. package/skills/frontend-ui-ux/kit/styles/meadow.json +199 -0
  81. package/skills/frontend-ui-ux/kit/styles/neo-brutalism.json +222 -0
  82. package/skills/frontend-ui-ux/kit/ui.js +226 -0
  83. package/skills/frontend-ui-ux/references/brand-and-imagery.md +2 -2
  84. package/skills/frontend-ui-ux/references/complete-contract.md +2 -1
  85. package/skills/frontend-ui-ux/references/craft-floor.md +6 -2
  86. package/skills/frontend-ui-ux/references/default-editorial-pixel.json +3 -0
  87. package/skills/frontend-ui-ux/references/house-styles.md +236 -0
  88. package/skills/frontend-ui-ux/references/motion-guide.md +2 -2
  89. package/skills/frontend-ui-ux/references/production.md +3 -1
  90. package/skills/frontend-ui-ux/references/slop-register.md +4 -4
  91. package/skills/frontend-ui-ux/scripts/design-lock.mjs +400 -0
  92. package/skills/frontend-ui-ux/scripts/pixel-art.mjs +60 -0
  93. package/skills/frontend-ui-ux/scripts/probe-lock.mjs +235 -0
  94. package/skills/frontend-ui-ux/scripts/probe-page.mjs +34 -12
  95. package/skills/frontend-ui-ux/scripts/probe-static.mjs +16 -3
  96. package/skills/frontend-ui-ux/scripts/probe-thresholds.json +8 -2
  97. package/skills/frontend-ui-ux/scripts/probe.mjs +35 -7
  98. package/skills/lit-adhd/SKILL.md +209 -0
  99. package/skills/lit-adhd/references/brief-format.md +46 -0
  100. package/skills/lit-adhd/references/card-examples.md +103 -0
  101. package/skills/lit-adhd/references/status-taxonomy.md +34 -0
  102. package/skills/lit-adhd/scripts/rewind.mjs +933 -0
  103. package/skills/lit-diagram-drawer/SKILL.md +4 -3
  104. package/skills/lit-diagram-drawer/references/style-guide.md +20 -11
  105. package/skills/lit-diagram-drawer/references/type-architecture.md +3 -3
  106. package/skills/lit-diagram-drawer/references/type-dependency.md +1 -1
  107. package/skills/lit-diagram-drawer/references/type-tree.md +3 -3
  108. package/skills/lit-diagram-drawer/references/type-wardley.md +1 -1
  109. package/skills/lit-diagram-drawer/references/verifier-guide.md +1 -0
  110. package/skills/lit-diagram-drawer/scripts/craft-thresholds.json +1 -2
  111. package/skills/lit-diagram-drawer/scripts/visual-quality.mjs +1 -2
  112. package/skills/lit-docx/SKILL.md +2 -1
  113. package/skills/lit-handoff/SKILL.md +2 -0
  114. package/skills/lit-hijack/SKILL.md +422 -0
  115. package/skills/lit-hijack/references/capture-and-provenance.md +87 -0
  116. package/skills/lit-hijack/references/clean-room-build.md +111 -0
  117. package/skills/lit-hijack/references/distil-and-licence.md +100 -0
  118. package/skills/lit-hijack/references/gap-and-port-design.md +126 -0
  119. package/skills/lit-hijack/references/parity-and-report.md +110 -0
  120. package/skills/lit-hijack/scripts/hijack.mjs +993 -0
  121. package/skills/lit-plan/SKILL.md +8 -0
  122. package/skills/lit-pptx/SKILL.md +27 -11
  123. package/skills/lit-pptx/fonts/jetbrains-mono/JetBrainsMono-Bold.ttf +0 -0
  124. package/skills/lit-pptx/fonts/jetbrains-mono/JetBrainsMono-Regular.ttf +0 -0
  125. package/skills/lit-pptx/fonts/jetbrains-mono/OFL.txt +93 -0
  126. package/skills/lit-pptx/fonts/jetbrains-mono/SOURCE.md +17 -0
  127. package/skills/lit-pptx/references/density-and-fill.md +9 -3
  128. package/skills/lit-pptx/references/direction-step.md +21 -6
  129. package/skills/lit-pptx/references/examples/04-lecture-chalk-ko.md +3 -6
  130. package/skills/lit-pptx/references/examples/05-research-talk-paper-en.md +1 -5
  131. package/skills/lit-pptx/references/examples/08-reliability-keynote-night-en.md +0 -4
  132. package/skills/lit-pptx/references/examples/09-status-update-ledger-en.md +2 -2
  133. package/skills/lit-pptx/references/examples/11-forecast-review-night-ko.md +4 -7
  134. package/skills/lit-pptx/references/examples/13-engineering-review-computational-brutalism-ko.md +173 -0
  135. package/skills/lit-pptx/references/examples/14-launch-pitch-neo-brutalism-ko.md +154 -0
  136. package/skills/lit-pptx/references/examples/15-design-lecture-bauhaus-ko.md +139 -0
  137. package/skills/lit-pptx/references/examples/16-community-programme-riso-ko.md +158 -0
  138. package/skills/lit-pptx/references/examples/17-public-data-briefing-newsroom-ko.md +179 -0
  139. package/skills/lit-pptx/references/layout-families.md +65 -47
  140. package/skills/lit-pptx/references/title-treatments.md +83 -134
  141. package/skills/lit-pptx/references/tonalities/atlas.md +3 -3
  142. package/skills/lit-pptx/references/tonalities/bauhaus.md +140 -0
  143. package/skills/lit-pptx/references/tonalities/chalk.md +7 -6
  144. package/skills/lit-pptx/references/tonalities/computational-brutalism.md +150 -0
  145. package/skills/lit-pptx/references/tonalities/gazette.md +1 -1
  146. package/skills/lit-pptx/references/tonalities/ledger.md +1 -1
  147. package/skills/lit-pptx/references/tonalities/neo-brutalism.md +161 -0
  148. package/skills/lit-pptx/references/tonalities/newsroom.md +144 -0
  149. package/skills/lit-pptx/references/tonalities/night.md +1 -1
  150. package/skills/lit-pptx/references/tonalities/paper.md +2 -2
  151. package/skills/lit-pptx/references/tonalities/riso.md +137 -0
  152. package/skills/lit-pptx/references/tonalities/signal.md +3 -3
  153. package/skills/lit-pptx/references/tonalities/studio.md +7 -6
  154. package/skills/lit-pptx/run.mjs +2 -1
  155. package/skills/lit-pptx/scripts/compile-deck.js +1 -1
  156. package/skills/lit-pptx/scripts/craft-thresholds.json +4 -8
  157. package/skills/lit-pptx/scripts/craft_extras.py +56 -3
  158. package/skills/lit-pptx/scripts/deck_output.py +75 -90
  159. package/skills/lit-pptx/scripts/embed_fonts.py +13 -1
  160. package/skills/lit-pptx/scripts/layout_inventory.py +12 -5
  161. package/skills/lit-pptx/scripts/lib/grid-resolver.js +101 -110
  162. package/skills/lit-pptx/scripts/lib/layout-resolver.js +9 -15
  163. package/skills/lit-pptx/scripts/lib/render-pack.js +373 -566
  164. package/skills/lit-pptx/scripts/lib/slide-grid.js +104 -0
  165. package/skills/lit-pptx/scripts/lib/template-registry.js +57 -6
  166. package/skills/lit-pptx/scripts/qa_deck.py +10 -11
  167. package/skills/lit-pptx/scripts/render_pages.py +118 -0
  168. package/skills/lit-pptx/templates/tonalities/atlas/pack.yaml +1 -1
  169. package/skills/lit-pptx/templates/tonalities/bauhaus/pack.yaml +98 -0
  170. package/skills/lit-pptx/templates/tonalities/chalk/pack.yaml +1 -1
  171. package/skills/lit-pptx/templates/tonalities/computational-brutalism/pack.yaml +99 -0
  172. package/skills/lit-pptx/templates/tonalities/gazette/pack.yaml +1 -1
  173. package/skills/lit-pptx/templates/tonalities/ledger/pack.yaml +1 -1
  174. package/skills/lit-pptx/templates/tonalities/neo-brutalism/pack.yaml +107 -0
  175. package/skills/lit-pptx/templates/tonalities/newsroom/pack.yaml +99 -0
  176. package/skills/lit-pptx/templates/tonalities/night/pack.yaml +1 -1
  177. package/skills/lit-pptx/templates/tonalities/paper/pack.yaml +1 -1
  178. package/skills/lit-pptx/templates/tonalities/riso/pack.yaml +99 -0
  179. package/skills/lit-pptx/templates/tonalities/signal/pack.yaml +2 -2
  180. package/skills/lit-pptx/templates/tonalities/studio/pack.yaml +1 -1
  181. package/skills/lit-recap/SKILL.md +4 -0
  182. package/skills/lit-schematic/SKILL.md +118 -0
  183. package/skills/lit-schematic/examples/iso-heat-exchanger/build.mjs +38 -0
  184. package/skills/lit-schematic/examples/iso-heat-exchanger/scene.mjs +133 -0
  185. package/skills/lit-schematic/examples/journal-adsorption-rig/build.mjs +87 -0
  186. package/skills/lit-schematic/examples/pid-dosing-skid/build.mjs +85 -0
  187. package/skills/lit-schematic/references/cutaway-outputs.md +70 -0
  188. package/skills/lit-schematic/references/isometric-craft.md +101 -0
  189. package/skills/lit-schematic/references/journal-figures.md +72 -0
  190. package/skills/lit-schematic/references/kit-api.md +134 -0
  191. package/skills/lit-schematic/references/pfd-and-layout.md +53 -0
  192. package/skills/lit-schematic/references/pid-drafting.md +103 -0
  193. package/skills/lit-schematic/references/pid-symbols.md +163 -0
  194. package/skills/lit-schematic/references/verification.md +100 -0
  195. package/skills/lit-schematic/scripts/doctor.mjs +57 -0
  196. package/skills/lit-schematic/scripts/lib/figure.mjs +81 -0
  197. package/skills/lit-schematic/scripts/lib/fonts.mjs +25 -0
  198. package/skills/lit-schematic/scripts/lib/geom.mjs +113 -0
  199. package/skills/lit-schematic/scripts/lib/interactive.mjs +292 -0
  200. package/skills/lit-schematic/scripts/lib/isa.mjs +115 -0
  201. package/skills/lit-schematic/scripts/lib/iso.mjs +719 -0
  202. package/skills/lit-schematic/scripts/lib/legend-sheet.mjs +162 -0
  203. package/skills/lit-schematic/scripts/lib/pid.mjs +937 -0
  204. package/skills/lit-schematic/scripts/lib/png.mjs +132 -0
  205. package/skills/lit-schematic/scripts/lib/qa-core.mjs +658 -0
  206. package/skills/lit-schematic/scripts/lib/route.mjs +218 -0
  207. package/skills/lit-schematic/scripts/lib/sheet.mjs +890 -0
  208. package/skills/lit-schematic/scripts/lib/svg.mjs +82 -0
  209. package/skills/lit-schematic/scripts/lib/theme.mjs +115 -0
  210. package/skills/lit-schematic/scripts/motion.mjs +129 -0
  211. package/skills/lit-schematic/scripts/qa.mjs +92 -0
  212. package/skills/lit-schematic/scripts/render.mjs +233 -0
  213. package/skills/lit-schematic/scripts/scaffold.mjs +60 -0
  214. package/skills/lit-scientific-visualization/SKILL.md +27 -4
  215. package/skills/lit-typographic-motion/SKILL.md +19 -17
  216. package/skills/lit-typographic-motion/THIRD_PARTY_NOTICES +9 -0
  217. package/skills/lit-typographic-motion/engine/accents.mjs +6 -0
  218. package/skills/lit-typographic-motion/engine/assets.mjs +282 -0
  219. package/skills/lit-typographic-motion/engine/blender/runner.py +228 -0
  220. package/skills/lit-typographic-motion/engine/blender.mjs +126 -0
  221. package/skills/lit-typographic-motion/engine/board.mjs +138 -0
  222. package/skills/lit-typographic-motion/engine/cover/assets.mjs +11 -8
  223. package/skills/lit-typographic-motion/engine/cover/capture.mjs +6 -6
  224. package/skills/lit-typographic-motion/engine/cover/render.mjs +20 -7
  225. package/skills/lit-typographic-motion/engine/cover/treatment.mjs +30 -3
  226. package/skills/lit-typographic-motion/engine/fill.mjs +54 -0
  227. package/skills/lit-typographic-motion/engine/gallery.mjs +118 -0
  228. package/skills/lit-typographic-motion/engine/house.mjs +42 -0
  229. package/skills/lit-typographic-motion/engine/look.mjs +65 -8
  230. package/skills/lit-typographic-motion/engine/loudness.mjs +101 -0
  231. package/skills/lit-typographic-motion/engine/scaffold.mjs +219 -0
  232. package/skills/lit-typographic-motion/engine/score.mjs +594 -0
  233. package/skills/lit-typographic-motion/engine/sound.mjs +9 -57
  234. package/skills/lit-typographic-motion/engine/stage/capture.mjs +23 -9
  235. package/skills/lit-typographic-motion/engine/stage/clock.js +8 -2
  236. package/skills/lit-typographic-motion/engine/stage/cover-init.js +12 -1
  237. package/skills/lit-typographic-motion/engine/stage/frame-worker.mjs +15 -7
  238. package/skills/lit-typographic-motion/engine/stage/gate.mjs +48 -4
  239. package/skills/lit-typographic-motion/engine/stage/qa-page.js +16 -5
  240. package/skills/lit-typographic-motion/engine/stage/qa.mjs +148 -7
  241. package/skills/lit-typographic-motion/engine/stage/render.mjs +69 -7
  242. package/skills/lit-typographic-motion/engine/stage/scan.mjs +20 -1
  243. package/skills/lit-typographic-motion/engine/stage/stage-kit.js +85 -4
  244. package/skills/lit-typographic-motion/engine/stills.mjs +1 -1
  245. package/skills/lit-typographic-motion/engine/styles.mjs +221 -0
  246. package/skills/lit-typographic-motion/engine/text.mjs +1 -1
  247. package/skills/lit-typographic-motion/engine/treatment.mjs +190 -6
  248. package/skills/lit-typographic-motion/engine/vendor/three/LICENSE +21 -0
  249. package/skills/lit-typographic-motion/engine/vendor/three/addons/environments/RoomEnvironment.js +144 -0
  250. package/skills/lit-typographic-motion/engine/vendor/three/addons/geometries/RoundedBoxGeometry.js +155 -0
  251. package/skills/lit-typographic-motion/engine/vendor/three/three.module.js +54571 -0
  252. package/skills/lit-typographic-motion/gate.mjs +18 -2
  253. package/skills/lit-typographic-motion/probe.mjs +13 -1
  254. package/skills/lit-typographic-motion/recipes/hero-3d/expected.json +64 -0
  255. package/skills/lit-typographic-motion/recipes/hero-3d/index.html +132 -0
  256. package/skills/lit-typographic-motion/recipes/orbit-loop/expected.json +2 -0
  257. package/skills/lit-typographic-motion/recipes/painted-light/expected.json +2 -0
  258. package/skills/lit-typographic-motion/recipes/weight-tide/expected.json +2 -0
  259. package/skills/lit-typographic-motion/references/cover.md +56 -13
  260. package/skills/lit-typographic-motion/references/craft-loop.md +20 -7
  261. package/skills/lit-typographic-motion/references/depth.md +112 -0
  262. package/skills/lit-typographic-motion/references/runtime.md +21 -6
  263. package/skills/lit-typographic-motion/references/sound.md +76 -0
  264. package/skills/lit-typographic-motion/references/stage.md +50 -7
  265. package/skills/lit-typographic-motion/references/studio.md +162 -0
  266. package/skills/lit-typographic-motion/references/style-bibles.md +18 -0
  267. package/skills/lit-typographic-motion/references/treatment.md +108 -9
  268. package/skills/lit-typographic-motion/render.mjs +60 -3
  269. package/skills/lit-typographic-motion/styles/paper.json +185 -0
  270. package/skills/lit-typographic-motion/styles/swiss-signal.json +188 -0
  271. package/skills/lit-typographic-motion/styles/terminalcore.json +182 -0
  272. package/skills/lit-typographic-motion/styles/tidal.json +187 -0
  273. package/skills/litresearch/SKILL.md +2 -0
  274. package/skills/managed-skill-manifest.json +517 -88
  275. package/skills/readme-studio/SKILL.md +1 -1
  276. package/skills/review-work/SKILL.md +2 -0
  277. package/skills/start-work/SKILL.md +8 -0
  278. package/skills/workflow-loop/SKILL.md +4 -0
  279. package/tools/check-pack-payload.mjs +5 -2
  280. package/tools/payload-substance-parity.json +4 -3
  281. package/tools/qa-cover-recipes.mjs +4 -3
  282. package/tools/version-manifests.json +2 -2
@@ -0,0 +1,219 @@
1
+ // `render.mjs scaffold --out <dir>`: the starting stage page, written from the treatment, so every film
2
+ // has the same architecture: the COPY block, one <section> per shot with its type placed in the shot's
3
+ // type zone and an empty subject group in its subject zone, entrances and hand-offs on the house
4
+ // style's tokens, and one DRAW function per shot where the drawing goes. The page passes the style
5
+ // rules as written; the drawing is the model's. A 3D film (`depth: "3d"`) also gets the three.js
6
+ // world: an import map onto the vendored build, a full-frame canvas behind the shots, one persistent
7
+ // protagonist group lit and shadowed in the style's palette, and one WORLD function per shot. It never
8
+ // overwrites an existing page.
9
+ import { existsSync, mkdirSync, writeFileSync } from "node:fs";
10
+ import path from "node:path";
11
+ import { EXIT } from "./constants.mjs";
12
+ import { BLENDER, findBlender, plateFrames } from "./blender.mjs";
13
+ import { asksPathTraced, frameSize, loadTreatment } from "./treatment.mjs";
14
+
15
+ const HANGUL = /[ㄱ-ㆎ가-힣]/u;
16
+
17
+ // Which copy lines each shot shows: the treatment's `lines` when given; otherwise spread in order over
18
+ // the shots that have a type zone, the first line on the first and the last line on the last.
19
+ export function linesPerShot(treatment) {
20
+ const beats = treatment.beats;
21
+ if (beats.some((b) => Array.isArray(b.lines))) return beats.map((b) => (Array.isArray(b.lines) ? b.lines : []));
22
+ const lines = treatment.copy.lines.map((_, i) => i);
23
+ const textShots = beats.map((b, i) => (b.layout === "full" ? null : i)).filter((i) => i !== null);
24
+ const out = beats.map(() => []);
25
+ if (!textShots.length) return out;
26
+ lines.forEach((line, k) => {
27
+ const at = lines.length > 1 ? Math.round((k * (textShots.length - 1)) / (lines.length - 1)) : 0;
28
+ out[textShots[at]].push(line);
29
+ });
30
+ return out;
31
+ }
32
+
33
+ // The scaffold page for a stage treatment.
34
+ export function scaffoldHtml(treatment) {
35
+ const { width, height } = frameSize(treatment);
36
+ const perShot = linesPerShot(treatment);
37
+ const lang = treatment.copy.lines.some((line) => HANGUL.test(line)) ? "ko" : "en";
38
+ const sections = treatment.beats.map((b, i) => {
39
+ const lines = perShot[i];
40
+ const roleOf = (k) => (k > 0 ? "lit-body lit-muted" : b.layout === "title" ? "lit-display lit-ink" : "lit-headline lit-ink");
41
+ const type = b.layout === "full" || !lines.length ? "" : `\n <div class="type" data-zone="type">${lines.map((line, k) => `\n <p class="${roleOf(k)}" data-copy="${line}"></p>`).join("")}\n </div>`;
42
+ return ` <!-- shot ${i + 1}: ${String(b.purpose).replace(/--/gu, "-")} -->\n <section class="shot" data-shot="${i}">\n <svg class="subject" data-zone="subject"></svg>${type}\n </section>`;
43
+ }).join("\n");
44
+ const plated = treatment.render3d === "blender";
45
+ const solid = treatment.depth === "3d" && !plated;
46
+ const worlds = treatment.beats.map((b, i) => ` // shot ${i + 1} (${b.layout})\n (s, hero, cam, t) => {},`).join("\n");
47
+ const head3d = solid ? `
48
+ <script type="importmap">{ "imports": { "three": "/lit/three/three.module.js", "three/addons/": "/lit/three/addons/" } }</script>` : "";
49
+ const canvas3d = solid ? `<canvas id="world" width="${width}" height="${height}"></canvas>\n` : "";
50
+ const style3d = solid ? `
51
+ #world { position: absolute; left: 0; top: 0; width: ${width}px; height: ${height}px; }` : "";
52
+ const plate3d = plated ? `
53
+ // The world is a Blender plate (stage/plate/, rendered from stage/scene.py): one full-frame picture per
54
+ // film frame behind the shots. The page draws the type, labels and panels over it.
55
+ const PLATE = LitStage.plate({ parent: document.body, fps: ${BLENDER.plateFps}, count: ${plateFrames(treatment)} });
56
+ ` : "";
57
+ const world3d = solid ? `
58
+ // The world: one scene for the whole film, drawn on the GPU rung (software when it is missing). The
59
+ // protagonist lives in HERO from the first frame to the last; each shot's WORLD function poses it,
60
+ // the camera and anything else as a function of the shot's progress. The camera is aimed so the
61
+ // world origin sits at the centre of the shot's subject zone. More parts of the vendored build:
62
+ // three/addons/geometries/RoundedBoxGeometry.js.
63
+ const PAL = LitStyle.palette;
64
+ const renderer = new THREE.WebGLRenderer({ canvas: document.getElementById("world"), antialias: true, alpha: true, preserveDrawingBuffer: true });
65
+ renderer.setPixelRatio(1);
66
+ renderer.setSize(${width}, ${height}, false);
67
+ renderer.setClearColor(0x000000, 0);
68
+ renderer.outputColorSpace = THREE.SRGBColorSpace;
69
+ renderer.toneMapping = THREE.ACESFilmicToneMapping;
70
+ renderer.shadowMap.enabled = true;
71
+ renderer.shadowMap.type = THREE.PCFSoftShadowMap;
72
+ const scene = new THREE.Scene();
73
+ scene.environment = new THREE.PMREMGenerator(renderer).fromScene(new RoomEnvironment(), 0.04).texture;
74
+ const cam = new THREE.PerspectiveCamera(32, ${width} / ${height}, 0.1, 100);
75
+ const key = new THREE.DirectionalLight(0xffffff, 2.2);
76
+ key.position.set(3, 6, 4);
77
+ key.castShadow = true;
78
+ key.shadow.mapSize.set(2048, 2048);
79
+ key.shadow.radius = 4;
80
+ key.shadow.bias = -0.0004; // without these a turning object's shadow acne flickers as flashes
81
+ key.shadow.normalBias = 0.03;
82
+ scene.add(key, new THREE.HemisphereLight(PAL.surface ?? PAL.ground, PAL.ground, 0.6));
83
+ const floor = new THREE.Mesh(new THREE.PlaneGeometry(40, 40), new THREE.ShadowMaterial({ opacity: 0.18 }));
84
+ floor.rotation.x = -Math.PI / 2;
85
+ floor.receiveShadow = true;
86
+ scene.add(floor);
87
+ const HERO = new THREE.Group();
88
+ scene.add(HERO);
89
+
90
+ // Aim the camera so the origin lands on the centre of the shot's subject zone.
91
+ function aim(layout) {
92
+ const z = LitStage.zone(layout, "subject");
93
+ cam.setViewOffset(${width}, ${height}, ${width} / 2 - (z.x + z.w / 2), ${height} / 2 - (z.y + z.h / 2), ${width}, ${height});
94
+ return z.h / ${height};
95
+ }
96
+
97
+ const WORLD = [
98
+ ${worlds}
99
+ ];
100
+
101
+ function drawWorld(s, t) {
102
+ cam.position.set(0, 1.6, 7);
103
+ cam.lookAt(0, 0.6, 0);
104
+ aim(s.beat.layout);
105
+ WORLD[s.index](s, HERO, cam, t);
106
+ renderer.render(scene, cam);
107
+ }
108
+ ` : "";
109
+ const scriptOpen = solid ? `<script type="module">
110
+ import * as THREE from "three";
111
+ import { RoomEnvironment } from "three/addons/environments/RoomEnvironment.js";
112
+ ` : "<script>\n";
113
+ const draws = treatment.beats.map((b, i) => ` // shot ${i + 1} (${b.layout}): ${String(b.hero).replace(/\*\//gu, "* /")}\n (s, svg, t) => {},`).join("\n");
114
+ return `<!doctype html>
115
+ <html lang="${lang}">
116
+ <head>
117
+ <meta charset="utf-8">
118
+ <link rel="stylesheet" href="/lit/fonts.css">
119
+ <link rel="stylesheet" href="/lit/style.css">
120
+ <script src="/lit/style.js"></script>
121
+ <script src="/lit/stage-kit.js"></script>${head3d}
122
+ <style>
123
+ html, body { width: ${width}px; height: ${height}px; }
124
+ .shot { position: absolute; left: 0; top: 0; width: ${width}px; height: ${height}px; visibility: hidden; }
125
+ .subject { position: absolute; overflow: visible; }
126
+ .type { display: flex; flex-direction: column; justify-content: center; gap: 0.4em; }${style3d}
127
+ </style>
128
+ </head>
129
+ <body>
130
+ ${canvas3d}${sections}
131
+ ${scriptOpen} // The film's words: every copy line of treatment.json, verbatim. Edit them here.
132
+ const COPY = ${JSON.stringify(treatment.copy.lines, null, 2).replace(/\n/gu, "\n ")};
133
+
134
+ const { define, shot, place, tokens, text, clamp, clip } = LitStage;
135
+ const T = tokens();
136
+ const BEATS = LitTimeline.beats;
137
+ const SHOTS = [...document.querySelectorAll(".shot")];
138
+ SHOTS.forEach((el, i) => {
139
+ place(el.querySelector('[data-zone="subject"]'), BEATS[i].layout, "subject");
140
+ const type = el.querySelector('[data-zone="type"]');
141
+ if (type) place(type, BEATS[i].layout, "type");
142
+ });
143
+ for (const el of document.querySelectorAll("[data-copy]")) {
144
+ el.textContent = COPY[Number(el.dataset.copy)];
145
+ text(el);
146
+ }
147
+
148
+ // One function per shot: draw the subject into its svg (the subject zone) as a function of the
149
+ // shot's progress. s is LitStage.shot(t): s.p (0..1), s.local (seconds), s.enter(delay, dur).
150
+ const DRAW = [
151
+ ${draws}
152
+ ];
153
+
154
+ // How a shot hands off to the next, over the style's exit duration before the cut.
155
+ const HANDOFF = T.dur.exit;
156
+ const handoff = { wipe: (el, p) => clip.wipe(el, p, "left"), iris: (el, p) => clip.circle(el, p, { cx: 50, cy: 50 }), dissolve: (el, p) => { el.style.opacity = String(p); } };
157
+
158
+ function paint(i, s, t) {
159
+ const el = SHOTS[i];
160
+ el.style.visibility = "visible";
161
+ const type = el.querySelector('[data-zone="type"]');
162
+ if (type) {
163
+ const e = s.enter(0.1);
164
+ type.style.opacity = String(e);
165
+ type.style.transform = \`translateY(\${(1 - e) * 24}px)\`;
166
+ }
167
+ DRAW[i](s, el.querySelector('[data-zone="subject"]'), t);
168
+ }
169
+ ${world3d}${plate3d}
170
+ define({ width: ${width}, height: ${height}, fps: ${treatment.fps ?? 60}, duration: ${treatment.durationSec}, render(t) {
171
+ for (const el of SHOTS) Object.assign(el.style, { visibility: "hidden", opacity: "", clipPath: "", transform: "", zIndex: "" });
172
+ const s = shot(t);${plated ? "\n PLATE(t);" : ""}
173
+ paint(s.index, s, t);${solid ? "\n drawWorld(s, t);" : ""}
174
+ const next = SHOTS[s.index + 1];
175
+ const into = clamp((t - (s.beat.t1 - HANDOFF)) / HANDOFF);
176
+ if (next && into > 0) {
177
+ const p = T.ease.move(into);
178
+ const kind = s.beat.transition;
179
+ if (handoff[kind]) {
180
+ next.style.zIndex = "1";
181
+ paint(s.index + 1, shot(BEATS[s.index + 1].t0), t);
182
+ handoff[kind](next, p);
183
+ } else if (kind === "push") {
184
+ SHOTS[s.index].style.transform = \`translateX(\${-p * ${width}}px)\`;
185
+ paint(s.index + 1, shot(BEATS[s.index + 1].t0), t);
186
+ next.style.transform = \`translateX(\${(1 - p) * ${width}}px)\`;
187
+ }
188
+ }
189
+ } });
190
+ </script>
191
+ </body>
192
+ </html>
193
+ `;
194
+ }
195
+
196
+ // The scaffold's word on the 3D renderer. A Blender film draws its world in stage/scene.py. A film that asks
197
+ // for high-quality 3D is pointed at that rung when Blender is installed, and told what it will do instead
198
+ // when it is not.
199
+ function rungNote(treatment, out, env) {
200
+ if (treatment.depth !== "3d") return "";
201
+ if (treatment.render3d === "blender") return ` This is a Blender film: write the world in ${path.join(out, "stage", "scene.py")}, look at the preview stills (blender --out ${out}), render the plate (blender --out ${out} --final), and show it under the type with LitStage.plate() in place of the three.js world (references/depth.md, the Blender rung).`;
202
+ if (!asksPathTraced(treatment.request)) return "";
203
+ const found = findBlender({ env });
204
+ return found
205
+ ? `\nBLENDER: ${found.path} (${found.source}) is installed and the request asks for high-quality 3D. Take the Blender rung: set render3d "blender" in the treatment, write stage/scene.py, and keep this page for the type, labels and panels over the plate (references/depth.md, the Blender rung).`
206
+ : "\nBLENDER: not found (LITOPENCODE_BLENDER, /Applications/Blender.app, blender on PATH). The request asks for high-quality 3D, so build the world in three.js on the GPU rung and say in the reply that Blender is not installed.";
207
+ }
208
+
209
+ // Writes `<out>/stage/index.html` from the treatment and returns the note to print; refuses to replace
210
+ // a page.
211
+ export function scaffoldCommand(out, { env = process.env } = {}) {
212
+ const { treatment } = loadTreatment(out);
213
+ if (treatment.path !== "stage") throw Object.assign(new Error("BLOCKED_TREATMENT_INVALID (16): field path: scaffold writes a stage page; this treatment takes the type path"), { exitCode: EXIT.BLOCKED_TREATMENT_INVALID });
214
+ const file = path.join(out, "stage", "index.html");
215
+ if (existsSync(file)) throw Object.assign(new Error(`${file} exists; scaffold never overwrites a page (move it away to start again)`), { exitCode: 2 });
216
+ mkdirSync(path.dirname(file), { recursive: true });
217
+ writeFileSync(file, scaffoldHtml(treatment));
218
+ return `SCAFFOLD: ${file} (style ${treatment.style}, ${treatment.beats.length} shots). Draw each shot's subject in its DRAW function, then render the board: stage --out ${out} --round 1 --stills-only${rungNote(treatment, out, env)}`;
219
+ }