@hraness/slopcamera 3.2.7 → 3.3.1

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 (188) hide show
  1. package/NOTICE.md +1 -7
  2. package/PRIVACY.md +16 -7
  3. package/README.md +65 -20
  4. package/apps/desktop/README.md +14 -130
  5. package/apps/desktop/application/context.ts +6 -9
  6. package/apps/desktop/application/default-registry.ts +26 -10
  7. package/apps/desktop/application/operation.ts +14 -5
  8. package/apps/desktop/application/operations/index.ts +4 -1
  9. package/apps/desktop/application/operations/spatial-behavior.ts +151 -0
  10. package/apps/desktop/application/operations/spatial-direction.ts +222 -0
  11. package/apps/desktop/application/operations/spatial-rendered-audit.ts +174 -0
  12. package/apps/desktop/application/operations/spatial-review.ts +194 -0
  13. package/apps/desktop/application/operations/spatial-scene.ts +25 -1
  14. package/apps/desktop/application/registry.ts +2 -2
  15. package/apps/desktop/application/spatial-asset-admission.ts +201 -0
  16. package/apps/desktop/application/spatial-assets.ts +160 -31
  17. package/apps/desktop/application/spatial-render.ts +217 -20
  18. package/apps/desktop/application/spatial-rendered-audit.ts +273 -0
  19. package/apps/desktop/application/spatial-review.ts +361 -0
  20. package/apps/desktop/application/spatial-spz.ts +48 -3
  21. package/apps/desktop/application/spatial-world-import.ts +26 -5
  22. package/apps/desktop/application/spatial-world-metadata.ts +105 -0
  23. package/apps/desktop/cli/args.ts +528 -97
  24. package/apps/desktop/cli/capability-manifest.ts +374 -0
  25. package/apps/desktop/cli/cinema-renderer.ts +608 -0
  26. package/apps/desktop/cli/command-host-resources.ts +31 -2
  27. package/apps/desktop/cli/commands.ts +1215 -70
  28. package/apps/desktop/cli/gateway-review-provider.ts +334 -0
  29. package/apps/desktop/cli/help.ts +183 -23
  30. package/apps/desktop/cli/html-scene.ts +139 -28
  31. package/apps/desktop/cli/io.ts +2 -1
  32. package/apps/desktop/cli/main.ts +26 -50
  33. package/apps/desktop/cli/menubar.ts +244 -0
  34. package/apps/desktop/cli/music-analysis-service.ts +61 -0
  35. package/apps/desktop/cli/portable-surface.ts +18 -5
  36. package/apps/desktop/cli/spatial-asset-service.ts +124 -0
  37. package/apps/desktop/cli/spatial-design-service.ts +237 -0
  38. package/apps/desktop/cli/spatial-generate-service.ts +370 -0
  39. package/apps/desktop/cli/spatial-scene-service.ts +268 -4
  40. package/apps/desktop/cli/workflow-code.ts +1 -1
  41. package/apps/desktop/code/application-node-planner.ts +0 -47
  42. package/apps/desktop/code/host-source-layout.ts +46 -0
  43. package/apps/desktop/code/public.ts +0 -1
  44. package/apps/desktop/code/runtime-identity.ts +50 -8
  45. package/apps/desktop/code/semantic-builder.ts +24 -43
  46. package/apps/desktop/code/source-bundle.ts +23 -6
  47. package/apps/desktop/code/source-typecheck.ts +131 -43
  48. package/apps/desktop/code/worker-client.ts +14 -2
  49. package/apps/desktop/contracts/cinema.ts +736 -0
  50. package/apps/desktop/contracts/index.ts +1 -0
  51. package/apps/desktop/contracts/spatial-asset.ts +16 -0
  52. package/apps/desktop/contracts/spatial-world.ts +26 -3
  53. package/apps/desktop/core/cinema-plan.ts +1320 -0
  54. package/apps/desktop/core/index.ts +1 -0
  55. package/apps/desktop/core/music-analysis.ts +124 -1
  56. package/apps/desktop/core/storage.ts +75 -0
  57. package/apps/desktop/dist/cli/main.js +737 -291
  58. package/apps/desktop/html-overlay/audio-reactivity.ts +127 -0
  59. package/apps/desktop/html-overlay/index.ts +9 -0
  60. package/apps/desktop/html-overlay/runtime.ts +2 -0
  61. package/apps/desktop/html-overlay/scene.ts +29 -0
  62. package/apps/desktop/html-overlay/spatial.ts +619 -57
  63. package/apps/desktop/workflows/cinematic-world.ts +127 -0
  64. package/apps/desktop/workflows/index.ts +6 -0
  65. package/dist/cli.js +32 -434
  66. package/dist/code/advanced.js +1 -269
  67. package/dist/code/index.js +16 -2239
  68. package/dist/generate.js +1 -23
  69. package/dist/host-resources.js +1 -25
  70. package/dist/index-0bbesn4m.js +35 -0
  71. package/dist/index-296qhpf2.js +3 -0
  72. package/dist/index-3cxf2c58.js +3 -0
  73. package/dist/index-77fjfg9f.js +3 -0
  74. package/dist/index-80a36bc0.js +3 -0
  75. package/dist/index-a3vvs3rf.js +3 -0
  76. package/dist/index-b3geqczn.js +5 -0
  77. package/dist/index-cgpkyjqa.js +3 -0
  78. package/dist/index-f0ptv8dm.js +7 -0
  79. package/dist/index-grk47tgs.js +3 -0
  80. package/dist/index-qry58nj2.js +10 -0
  81. package/dist/index.js +1 -240
  82. package/dist/operations.js +1 -28
  83. package/dist/skill-install-gx7afxsd.js +2 -0
  84. package/dist/vectorize/worker.js +1 -141
  85. package/dist/workflow.js +1 -15
  86. package/docs/README.md +5 -1
  87. package/docs/studio.md +1 -1
  88. package/package.json +11 -24
  89. package/skills/slopcamera/SKILL.md +14 -1
  90. package/skills/slopcamera/references/diagrams.md +5 -14
  91. package/skills/slopcamera/references/directed-scenes.md +22 -2
  92. package/skills/slopcamera/references/gateway-media.md +15 -1
  93. package/skills/slopcamera/references/image-galleries.md +166 -0
  94. package/skills/slopcamera/references/install.md +2 -2
  95. package/skills/slopcamera/references/music-video.md +23 -3
  96. package/skills/slopcamera/references/parametric-design.md +14 -0
  97. package/skills/slopcamera/references/reference-led-3d.md +1 -1
  98. package/skills/slopcamera/references/scene-building.md +32 -0
  99. package/skills/slopcamera/references/social-collage-banners.md +204 -0
  100. package/skills/slopcamera/references/support.md +25 -0
  101. package/skills/slopcamera/references/web-media-excerpts.md +120 -0
  102. package/skills/slopcamera/references/workflows-sdk.md +3 -3
  103. package/skills/slopcamera/scripts/compose-social-collage-banner.ts +728 -0
  104. package/src/capability-manifest.ts +361 -0
  105. package/src/cli.ts +250 -102
  106. package/src/code/canonical-json.ts +9 -0
  107. package/src/generate.ts +2 -2
  108. package/src/icon.ts +1111 -0
  109. package/src/image-gallery.ts +1049 -0
  110. package/src/index.ts +11 -23
  111. package/src/mcp/boundary.ts +11 -11
  112. package/src/mcp/index.ts +3 -0
  113. package/src/mcp/server.ts +2 -1
  114. package/src/mcp/tools.ts +1642 -130
  115. package/src/mcp/types.ts +19 -0
  116. package/src/operations.ts +412 -0
  117. package/src/portable-capability-manifest.ts +67 -0
  118. package/src/scene-gallery.ts +184 -0
  119. package/src/spatial-scene/asset-admission.ts +183 -0
  120. package/src/spatial-scene/audit-rendered.ts +692 -0
  121. package/src/spatial-scene/audit.ts +617 -0
  122. package/src/spatial-scene/behavior-audit.ts +252 -0
  123. package/src/spatial-scene/behavior-bake.ts +233 -0
  124. package/src/spatial-scene/behavior-fns.ts +585 -0
  125. package/src/spatial-scene/behavior-gallery.ts +109 -0
  126. package/src/spatial-scene/behavior-stdlib.ts +323 -0
  127. package/src/spatial-scene/behavior-trace.ts +325 -0
  128. package/src/spatial-scene/behavior.ts +618 -0
  129. package/src/spatial-scene/build.ts +632 -0
  130. package/src/spatial-scene/camera-rig.ts +125 -0
  131. package/src/spatial-scene/camera-track.ts +4 -2
  132. package/src/spatial-scene/character.ts +124 -0
  133. package/src/spatial-scene/contracts.ts +75 -7
  134. package/src/spatial-scene/design-templates.ts +351 -0
  135. package/src/spatial-scene/design.ts +327 -0
  136. package/src/spatial-scene/direction-compile.ts +584 -0
  137. package/src/spatial-scene/direction.ts +122 -0
  138. package/src/spatial-scene/effects.ts +149 -0
  139. package/src/spatial-scene/evaluate.ts +109 -29
  140. package/src/spatial-scene/gallery.ts +277 -0
  141. package/src/spatial-scene/generate.ts +239 -0
  142. package/src/spatial-scene/geometry-native.ts +165 -0
  143. package/src/spatial-scene/geometry.ts +1216 -0
  144. package/src/spatial-scene/gltf.ts +600 -77
  145. package/src/spatial-scene/identity.ts +55 -2
  146. package/src/spatial-scene/index.ts +36 -0
  147. package/src/spatial-scene/inspect.ts +35 -6
  148. package/src/spatial-scene/material-lighting.ts +609 -0
  149. package/src/spatial-scene/math.ts +21 -4
  150. package/src/spatial-scene/motion-evidence.ts +88 -0
  151. package/src/spatial-scene/parametric.ts +765 -0
  152. package/src/spatial-scene/particle-preparation.ts +183 -0
  153. package/src/spatial-scene/particle.ts +195 -0
  154. package/src/spatial-scene/patch.ts +109 -15
  155. package/src/spatial-scene/performance.ts +1613 -0
  156. package/src/spatial-scene/probe.ts +137 -0
  157. package/src/spatial-scene/recipe-pack.ts +86 -0
  158. package/src/spatial-scene/render-effects.ts +240 -0
  159. package/src/spatial-scene/review.ts +639 -0
  160. package/src/spatial-scene/simulation-bake.ts +206 -0
  161. package/src/spatial-scene/simulation.ts +187 -0
  162. package/src/spatial-scene/solve.ts +366 -0
  163. package/src/spatial-scene/temporal-audit.ts +354 -0
  164. package/src/support-completion.ts +16 -0
  165. package/src/support.ts +42 -0
  166. package/src/version.ts +1 -1
  167. package/apps/desktop/application/operations/recording/index.ts +0 -5
  168. package/apps/desktop/application/operations/recording/pause.ts +0 -34
  169. package/apps/desktop/application/operations/recording/resume.ts +0 -34
  170. package/apps/desktop/application/operations/recording/shared.ts +0 -199
  171. package/apps/desktop/application/operations/recording/start.ts +0 -169
  172. package/apps/desktop/application/operations/recording/stop.ts +0 -34
  173. package/apps/desktop/capture/protocol.ts +0 -689
  174. package/apps/desktop/cli/capture-bundle.ts +0 -1117
  175. package/apps/desktop/cli/recording-controller.ts +0 -1567
  176. package/apps/desktop/cli/recording-daemon.ts +0 -931
  177. package/dist/index-42zsesc1.js +0 -2257
  178. package/dist/index-7308egqr.js +0 -48
  179. package/dist/index-8txs6fkn.js +0 -712
  180. package/dist/index-mcy8z0br.js +0 -192
  181. package/dist/index-p63wavx0.js +0 -2029
  182. package/dist/index-r7gdhmsp.js +0 -424
  183. package/dist/index-rvghzt7b.js +0 -2013
  184. package/dist/index-sh6xbav6.js +0 -1219
  185. package/dist/index-z1w83f81.js +0 -4
  186. package/dist/index-z7239b4h.js +0 -2363
  187. package/dist/skill-install-dh0ntqba.js +0 -10
  188. package/src/desktop.ts +0 -253
@@ -4,6 +4,12 @@ import type {
4
4
  CandidateProjectRenderInput,
5
5
  SpatialInspectInput, SpatialInspectOutput, SpatialPatchInput, SpatialPatchOutput,
6
6
  SpatialEvaluateInput, SpatialEvaluateOutput,
7
+ SpatialDirectionCheckInput, SpatialDirectionCheckOutput,
8
+ SpatialDirectionCompileInput, SpatialDirectionCompileOutput,
9
+ SpatialDirectionGalleryInput, SpatialDirectionGalleryOutput,
10
+ SpatialEffectsCheckInput, SpatialEffectsCheckOutput,
11
+ SpatialEffectsPlanInput, SpatialEffectsPlanOutput,
12
+ SpatialTemporalAuditInput, SpatialTemporalAuditOutput,
7
13
  BindCandidateRevisionOutput,
8
14
  CommitProjectEditsOutput,
9
15
  CreateCandidateRevisionOutput,
@@ -50,11 +56,6 @@ import type {
50
56
  ProjectRenderPlanOutput,
51
57
  ProjectSnapshotOutput,
52
58
  PromoteVariantSelectionOutput,
53
- RecordingPauseOutput,
54
- RecordingResumeOutput,
55
- RecordingStartInput,
56
- RecordingStartOutput,
57
- RecordingStopOutput,
58
59
  SceneAnalysisOperationInput,
59
60
  SceneAnalysisOperationOutput,
60
61
  SelectVariantInput,
@@ -301,8 +302,6 @@ export type MediaAudioEffectsOptions =
301
302
  OperationInputValue<MediaAudioEffectsInput>;
302
303
  export type MediaColorGradeOptions =
303
304
  OperationInputValue<MediaColorGradeInput>;
304
- export type RecordingStartOptions =
305
- OperationInputValue<RecordingStartInput>;
306
305
 
307
306
  export type FaceFollowOptions = {
308
307
  readonly [Key in keyof Omit<FollowFacesInput, "project">]:
@@ -1043,6 +1042,24 @@ export class WorkflowBuilder {
1043
1042
  this.#graph.operationByKind(key, { input, kind: "scene.patch", version: 1 }, options),
1044
1043
  evaluate: (key: string, input: OperationInputValue<SpatialEvaluateInput>, options?: OperationNodeOptions): Ref<SpatialEvaluateOutput> =>
1045
1044
  this.#graph.operationByKind(key, { input, kind: "scene.evaluate", version: 1 }, options),
1045
+ /**
1046
+ * Pure semantic planning and review operations: direction checking and
1047
+ * compilation, bounded galleries, render-effects binding, and sampled
1048
+ * temporal audit. They propose and review documents; they never mutate a
1049
+ * project, render media, or select a candidate.
1050
+ */
1051
+ directionCheck: (key: string, input: OperationInputValue<SpatialDirectionCheckInput> | SpatialDirectionCheckInput, options?: OperationNodeOptions): Ref<SpatialDirectionCheckOutput> =>
1052
+ this.#graph.operationByKind(key, { input, kind: "scene.direction.check", version: 1 }, options),
1053
+ directionCompile: (key: string, input: OperationInputValue<SpatialDirectionCompileInput> | SpatialDirectionCompileInput, options?: OperationNodeOptions): Ref<SpatialDirectionCompileOutput> =>
1054
+ this.#graph.operationByKind(key, { input, kind: "scene.direction.compile", version: 1 }, options),
1055
+ directionGallery: (key: string, input: OperationInputValue<SpatialDirectionGalleryInput> | SpatialDirectionGalleryInput, options?: OperationNodeOptions): Ref<SpatialDirectionGalleryOutput> =>
1056
+ this.#graph.operationByKind(key, { input, kind: "scene.direction.gallery", version: 1 }, options),
1057
+ effectsCheck: (key: string, input: OperationInputValue<SpatialEffectsCheckInput> | SpatialEffectsCheckInput, options?: OperationNodeOptions): Ref<SpatialEffectsCheckOutput> =>
1058
+ this.#graph.operationByKind(key, { input, kind: "scene.effects.check", version: 1 }, options),
1059
+ effectsPlan: (key: string, input: OperationInputValue<SpatialEffectsPlanInput> | SpatialEffectsPlanInput, options?: OperationNodeOptions): Ref<SpatialEffectsPlanOutput> =>
1060
+ this.#graph.operationByKind(key, { input, kind: "scene.effects.plan", version: 1 }, options),
1061
+ temporalAudit: (key: string, input: OperationInputValue<SpatialTemporalAuditInput> | SpatialTemporalAuditInput, options?: OperationNodeOptions): Ref<SpatialTemporalAuditOutput> =>
1062
+ this.#graph.operationByKind(key, { input, kind: "scene.temporal-audit", version: 1 }, options),
1046
1063
  });
1047
1064
 
1048
1065
  readonly spatialProject = Object.freeze({
@@ -1344,42 +1361,6 @@ export class WorkflowBuilder {
1344
1361
  }, options),
1345
1362
  });
1346
1363
 
1347
- readonly recording = Object.freeze({
1348
- pause: (
1349
- key: string,
1350
- options?: OperationNodeOptions,
1351
- ): Ref<RecordingPauseOutput> => this.#graph.operationByKind(key, {
1352
- input: {},
1353
- kind: "recording.pause",
1354
- version: 1,
1355
- }, options),
1356
- resume: (
1357
- key: string,
1358
- options?: OperationNodeOptions,
1359
- ): Ref<RecordingResumeOutput> => this.#graph.operationByKind(key, {
1360
- input: {},
1361
- kind: "recording.resume",
1362
- version: 1,
1363
- }, options),
1364
- start: (
1365
- key: string,
1366
- input: RecordingStartOptions,
1367
- options?: OperationNodeOptions,
1368
- ): Ref<RecordingStartOutput> => this.#graph.operationByKind(key, {
1369
- input,
1370
- kind: "recording.start",
1371
- version: 2,
1372
- }, options),
1373
- stop: (
1374
- key: string,
1375
- options?: OperationNodeOptions,
1376
- ): Ref<RecordingStopOutput> => this.#graph.operationByKind(key, {
1377
- input: {},
1378
- kind: "recording.stop",
1379
- version: 1,
1380
- }, options),
1381
- });
1382
-
1383
1364
  private constructor(graph: WorkflowGraphBuilder) {
1384
1365
  this.#graph = graph;
1385
1366
  }
@@ -28,6 +28,7 @@ import {
28
28
  canonicalJson,
29
29
  sha256Hex,
30
30
  } from "../core/canonical-json";
31
+ import { hostSourceRoots } from "./host-source-layout";
31
32
  import type { WorkflowBundleIdentity as GraphWorkflowBundleIdentity } from "./contracts";
32
33
  import { typecheckWorkflowSnapshot } from "./source-typecheck";
33
34
  import { captureWorkerProcessStartIdentity } from "./worker-process-identity";
@@ -52,6 +53,10 @@ const MAX_TIMER_DURATION_MS = 2_147_483_647;
52
53
  const BUNDLER_GUARDIAN_HANDSHAKE_MS = 2_000;
53
54
  const BUNDLER_GUARDIAN_DIAGNOSTIC_BYTES = 2_000;
54
55
 
56
+ // Spawned helpers always run the checked TypeScript sources, never a path
57
+ // derived from this module's bundled location below apps/desktop/dist/cli.
58
+ const HOST_ROOTS = hostSourceRoots(import.meta.dir);
59
+
55
60
  const BUNDLE_SUBPROCESS_SOURCE = String.raw`
56
61
  import { fstatSync } from "node:fs";
57
62
  const processIdentity = await import(process.argv[5]);
@@ -756,11 +761,16 @@ async function startBundlerRetirementGuardian(options: {
756
761
  "--has-lease",
757
762
  options.inheritedHostResourceFileDescriptor === 0 ? "false" : "true",
758
763
  "--identity-module",
759
- pathToFileURL(join(import.meta.dir, "worker-process-identity.ts")).href,
764
+ pathToFileURL(join(
765
+ HOST_ROOTS.desktopRoot,
766
+ "code",
767
+ "worker-process-identity.ts",
768
+ )).href,
760
769
  "--host-resource-lock-module",
761
770
  pathToFileURL(join(
762
- import.meta.dir,
763
- "../../../src/host-resource-posix.ts",
771
+ HOST_ROOTS.repositoryRoot,
772
+ "src",
773
+ "host-resource-posix.ts",
764
774
  )).href,
765
775
  ],
766
776
  {
@@ -941,6 +951,7 @@ async function buildWorkflowBundle(
941
951
  modules: readonly CapturedSourceModule[],
942
952
  aliases: Readonly<Record<string, string>>,
943
953
  configSearchPath: string,
954
+ hostBoundary: string,
944
955
  includeRuntimeTypes: boolean,
945
956
  semanticCheck: boolean,
946
957
  inheritedHostResourceFileDescriptor: number,
@@ -979,6 +990,7 @@ async function buildWorkflowBundle(
979
990
  aliases,
980
991
  configSearchPath,
981
992
  entryPath,
993
+ hostBoundary,
982
994
  includeRuntimeTypes,
983
995
  sourceRoot,
984
996
  });
@@ -997,7 +1009,11 @@ async function buildWorkflowBundle(
997
1009
  outputPath,
998
1010
  inheritedHostResourceFileDescriptor === 0 ? "0" : "3",
999
1011
  String(maximumBundleBytes),
1000
- pathToFileURL(join(import.meta.dir, "worker-process-identity.ts")).href,
1012
+ pathToFileURL(join(
1013
+ HOST_ROOTS.desktopRoot,
1014
+ "code",
1015
+ "worker-process-identity.ts",
1016
+ )).href,
1001
1017
  ],
1002
1018
  {
1003
1019
  cwd: sourceRoot,
@@ -1571,14 +1587,15 @@ async function bundleWorkflowSourceInternal(
1571
1587
  const aliasSpecifiers = new Set(sourceGraph.bareImports);
1572
1588
  const aliases = await bareImportAliases(
1573
1589
  [...aliasSpecifiers].sort(),
1574
- resolve(options.bareImportResolutionRoot ?? import.meta.dir),
1590
+ resolve(options.bareImportResolutionRoot ?? HOST_ROOTS.desktopRoot),
1575
1591
  );
1576
1592
  const entryRelativePath = relative(allowedRoot, entryPath);
1577
1593
  const bytes = await buildWorkflowBundle(
1578
1594
  entryRelativePath,
1579
1595
  sourceGraph.modules,
1580
1596
  aliases,
1581
- resolve(options.bareImportResolutionRoot ?? import.meta.dir),
1597
+ resolve(options.bareImportResolutionRoot ?? HOST_ROOTS.desktopRoot),
1598
+ HOST_ROOTS.repositoryRoot,
1582
1599
  (
1583
1600
  sourceGraph.bareImports.some(specifier => (
1584
1601
  specifier === "bun" || specifier.startsWith("node:")
@@ -1,4 +1,4 @@
1
- import { dirname, isAbsolute, relative, resolve } from "node:path";
1
+ import { dirname, isAbsolute, join, relative, resolve } from "node:path";
2
2
 
3
3
  import ts from "typescript";
4
4
 
@@ -12,11 +12,38 @@ const WORKFLOW_GLOBALS_SOURCE = [
12
12
  "declare const process: any;",
13
13
  "",
14
14
  ].join("\n");
15
+ // Packed distributions ship no host tsconfig; this closed fallback preserves
16
+ // the host compiler contract instead of adopting a foreign caller tsconfig.
17
+ const PACKED_WORKFLOW_CONFIG = {
18
+ compilerOptions: {
19
+ allowImportingTsExtensions: true,
20
+ exactOptionalPropertyTypes: true,
21
+ isolatedModules: true,
22
+ jsx: "react-jsx",
23
+ lib: ["ES2023", "DOM", "DOM.Iterable"],
24
+ module: "Preserve",
25
+ moduleDetection: "force",
26
+ moduleResolution: "Bundler",
27
+ noEmit: true,
28
+ noFallthroughCasesInSwitch: true,
29
+ noImplicitOverride: true,
30
+ noImplicitReturns: true,
31
+ noUncheckedIndexedAccess: true,
32
+ noUnusedLocals: true,
33
+ noUnusedParameters: true,
34
+ skipLibCheck: true,
35
+ strict: true,
36
+ target: "ES2023",
37
+ useUnknownInCatchVariables: true,
38
+ verbatimModuleSyntax: true,
39
+ },
40
+ };
15
41
 
16
42
  export interface TypecheckWorkflowSnapshotOptions {
17
43
  readonly aliases: Readonly<Record<string, string>>;
18
44
  readonly configSearchPath: string;
19
45
  readonly entryPath: string;
46
+ readonly hostBoundary: string;
20
47
  readonly includeRuntimeTypes: boolean;
21
48
  readonly sourceRoot: string;
22
49
  }
@@ -26,6 +53,37 @@ function isWithin(root: string, candidate: string): boolean {
26
53
  return fromRoot === "" || (!fromRoot.startsWith("..") && !isAbsolute(fromRoot));
27
54
  }
28
55
 
56
+ /** Finds the host tsconfig without crossing into a foreign caller tree. */
57
+ function boundedHostConfigPath(
58
+ searchPath: string,
59
+ boundary: string,
60
+ ): string | undefined {
61
+ const limit = resolve(boundary);
62
+ let candidate = resolve(searchPath);
63
+ while (isWithin(limit, candidate)) {
64
+ const path = join(candidate, "tsconfig.json");
65
+ if (ts.sys.fileExists(path)) return path;
66
+ const parent = dirname(candidate);
67
+ if (parent === candidate) return undefined;
68
+ candidate = parent;
69
+ }
70
+ return undefined;
71
+ }
72
+
73
+ /**
74
+ * Resolves the installed @types/bun package from the host tree so runtime
75
+ * types never depend on the caller's working directory or dependencies.
76
+ */
77
+ function bunTypeRoots(hostBoundary: string): string | undefined {
78
+ try {
79
+ return dirname(dirname(
80
+ Bun.resolveSync("@types/bun/package.json", resolve(hostBoundary)),
81
+ ));
82
+ } catch {
83
+ return undefined;
84
+ }
85
+ }
86
+
29
87
  function diagnosticText(
30
88
  diagnostic: ts.Diagnostic,
31
89
  sourceRoot: string,
@@ -77,49 +135,72 @@ function boundedDiagnostics(
77
135
  export function typecheckWorkflowSnapshot(
78
136
  options: TypecheckWorkflowSnapshotOptions,
79
137
  ): void {
80
- const configPath = ts.findConfigFile(
81
- resolve(options.configSearchPath),
82
- path => ts.sys.fileExists(path),
83
- "tsconfig.json",
138
+ const configPath = boundedHostConfigPath(
139
+ options.configSearchPath,
140
+ options.hostBoundary,
84
141
  );
142
+ const hostDirectory = configPath === undefined
143
+ ? resolve(options.hostBoundary)
144
+ : dirname(configPath);
145
+ let parsedOptions: ts.CompilerOptions;
85
146
  if (configPath === undefined) {
86
- throw new ApplicationError(
87
- "internal",
88
- "Workflow semantic checking could not locate the host TypeScript configuration.",
147
+ const parsed = ts.parseJsonConfigFileContent(
148
+ PACKED_WORKFLOW_CONFIG,
149
+ ts.sys,
150
+ hostDirectory,
151
+ {
152
+ composite: false,
153
+ declaration: false,
154
+ emitDeclarationOnly: false,
155
+ incremental: false,
156
+ noEmit: true,
157
+ },
158
+ "slopcamera-packed-workflow.tsconfig.json",
89
159
  );
90
- }
91
- const config = ts.readConfigFile(configPath, path => ts.sys.readFile(path));
92
- if (config.error !== undefined) {
93
- throw new ApplicationError(
94
- "internal",
95
- `Workflow semantic checking could not read the host TypeScript configuration: ${
96
- diagnosticText(config.error, options.sourceRoot)
97
- }`,
98
- );
99
- }
100
- const parsed = ts.parseJsonConfigFileContent(
101
- config.config,
102
- ts.sys,
103
- dirname(configPath),
104
- {
105
- composite: false,
106
- declaration: false,
107
- emitDeclarationOnly: false,
108
- incremental: false,
109
- noEmit: true,
110
- },
111
- configPath,
112
- );
113
- if (parsed.errors.length > 0) {
114
- throw new ApplicationError(
115
- "internal",
116
- `Workflow semantic checking could not parse the host TypeScript configuration:\n${
117
- boundedDiagnostics(parsed.errors, options.sourceRoot)
118
- }`,
160
+ if (parsed.errors.length > 0) {
161
+ throw new ApplicationError(
162
+ "internal",
163
+ `Workflow semantic checking could not apply its packed TypeScript configuration:\n${
164
+ boundedDiagnostics(parsed.errors, options.sourceRoot)
165
+ }`,
166
+ );
167
+ }
168
+ parsedOptions = parsed.options;
169
+ } else {
170
+ const config = ts.readConfigFile(configPath, path => ts.sys.readFile(path));
171
+ if (config.error !== undefined) {
172
+ throw new ApplicationError(
173
+ "internal",
174
+ `Workflow semantic checking could not read the host TypeScript configuration: ${
175
+ diagnosticText(config.error, options.sourceRoot)
176
+ }`,
177
+ );
178
+ }
179
+ const parsed = ts.parseJsonConfigFileContent(
180
+ config.config,
181
+ ts.sys,
182
+ hostDirectory,
183
+ {
184
+ composite: false,
185
+ declaration: false,
186
+ emitDeclarationOnly: false,
187
+ incremental: false,
188
+ noEmit: true,
189
+ },
190
+ configPath,
119
191
  );
192
+ if (parsed.errors.length > 0) {
193
+ throw new ApplicationError(
194
+ "internal",
195
+ `Workflow semantic checking could not parse the host TypeScript configuration:\n${
196
+ boundedDiagnostics(parsed.errors, options.sourceRoot)
197
+ }`,
198
+ );
199
+ }
200
+ parsedOptions = parsed.options;
120
201
  }
121
202
  const typecheckImporterPath = resolve(
122
- dirname(configPath),
203
+ hostDirectory,
123
204
  "slopcamera-workflow-typecheck.ts",
124
205
  );
125
206
  const aliasPaths = Object.fromEntries(
@@ -132,7 +213,7 @@ export function typecheckWorkflowSnapshot(
132
213
  const declaration = ts.resolveModuleName(
133
214
  specifier,
134
215
  typecheckImporterPath,
135
- parsed.options,
216
+ parsedOptions,
136
217
  ts.sys,
137
218
  ).resolvedModule?.resolvedFileName;
138
219
  return [
@@ -143,8 +224,14 @@ export function typecheckWorkflowSnapshot(
143
224
  ];
144
225
  }),
145
226
  );
227
+ // Runtime-typed workflows use the host's installed @types/bun when it is
228
+ // present and the explicit any-globals shim when it is not.
229
+ const runtimeTypeRoots = options.includeRuntimeTypes
230
+ ? bunTypeRoots(options.hostBoundary)
231
+ : undefined;
232
+ const realRuntimeTypes = runtimeTypeRoots !== undefined;
146
233
  const compilerOptions: ts.CompilerOptions = {
147
- ...parsed.options,
234
+ ...parsedOptions,
148
235
  baseUrl: options.sourceRoot,
149
236
  composite: false,
150
237
  declaration: false,
@@ -152,10 +239,11 @@ export function typecheckWorkflowSnapshot(
152
239
  incremental: false,
153
240
  noEmit: true,
154
241
  paths: {
155
- ...parsed.options.paths,
242
+ ...parsedOptions.paths,
156
243
  ...aliasPaths,
157
244
  },
158
- types: options.includeRuntimeTypes ? ["bun"] : [],
245
+ ...(realRuntimeTypes ? { typeRoots: [runtimeTypeRoots] } : {}),
246
+ types: realRuntimeTypes ? ["bun"] : [],
159
247
  };
160
248
  delete compilerOptions.tsBuildInfoFile;
161
249
  const host = ts.createCompilerHost(compilerOptions, true);
@@ -189,7 +277,7 @@ export function typecheckWorkflowSnapshot(
189
277
  options: compilerOptions,
190
278
  rootNames: [
191
279
  options.entryPath,
192
- ...(options.includeRuntimeTypes ? [] : [WORKFLOW_GLOBALS_PATH]),
280
+ ...(realRuntimeTypes ? [] : [WORKFLOW_GLOBALS_PATH]),
193
281
  ],
194
282
  });
195
283
  const diagnostics = program.getSourceFiles()
@@ -22,6 +22,7 @@ import { z } from "zod";
22
22
 
23
23
  import { ApplicationError } from "../application/errors";
24
24
  import type { OperationDiscovery } from "../application/registry";
25
+ import { hostSourceRoots } from "./host-source-layout";
25
26
  import { canonicalJson } from "../core/canonical-json";
26
27
  import {
27
28
  AuthoredWorkflowGraphV1Schema,
@@ -46,6 +47,9 @@ const DEFAULT_TIMEOUT_MS = 30_000;
46
47
  const DEFAULT_MAXIMUM_DIAGNOSTIC_BYTES = 64 * 1024;
47
48
  const CODE_WORKER_CANCEL_GRACE_MS = 250;
48
49
  export const MAX_CODE_WORKER_POOL_SIZE = 4;
50
+ // Spawned helpers always run the checked TypeScript sources, never a path
51
+ // derived from this module's bundled location below apps/desktop/dist/cli.
52
+ const HOST_ROOTS = hostSourceRoots(import.meta.dir);
49
53
 
50
54
  const WorkerBuiltWorkflowSchema = z.strictObject({
51
55
  graph: AuthoredWorkflowGraphV1Schema,
@@ -856,7 +860,11 @@ async function startCodeWorkerLeaseGuardian(options: {
856
860
  "Code-worker host-resource lease descriptor is unsafe to inherit.",
857
861
  );
858
862
  }
859
- const guardianEntryPath = join(import.meta.dir, "worker-lease-guardian.ts");
863
+ const guardianEntryPath = join(
864
+ HOST_ROOTS.desktopRoot,
865
+ "code",
866
+ "worker-lease-guardian.ts",
867
+ );
860
868
  const guardian = spawn(
861
869
  options.bunExecutable,
862
870
  [
@@ -1435,7 +1443,11 @@ export async function startCodeWorker(
1435
1443
  );
1436
1444
  }
1437
1445
  const workerEntryPath = resolve(
1438
- options.workerEntryPath ?? join(import.meta.dir, "worker-entry.ts"),
1446
+ options.workerEntryPath ?? join(
1447
+ HOST_ROOTS.desktopRoot,
1448
+ "code",
1449
+ "worker-entry.ts",
1450
+ ),
1439
1451
  );
1440
1452
  const workerEntrySha256 = createHash("sha256")
1441
1453
  .update(await readFile(workerEntryPath))