@hraness/slopcamera 3.2.4

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 (441) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE.md +60 -0
  3. package/PRIVACY.md +46 -0
  4. package/README.md +311 -0
  5. package/SECURITY.md +21 -0
  6. package/apps/desktop/README.md +966 -0
  7. package/apps/desktop/analysis/protocol.ts +223 -0
  8. package/apps/desktop/application/capability-binding.ts +594 -0
  9. package/apps/desktop/application/context.ts +97 -0
  10. package/apps/desktop/application/creative-iteration.ts +1385 -0
  11. package/apps/desktop/application/default-registry.ts +146 -0
  12. package/apps/desktop/application/directing-contract.ts +218 -0
  13. package/apps/desktop/application/directing-plan.ts +178 -0
  14. package/apps/desktop/application/errors.ts +18 -0
  15. package/apps/desktop/application/gateway-port.ts +867 -0
  16. package/apps/desktop/application/html-overlay-browser-runtime.ts +687 -0
  17. package/apps/desktop/application/html-overlay-integrity.ts +337 -0
  18. package/apps/desktop/application/html-overlay-renderer.ts +45 -0
  19. package/apps/desktop/application/index.ts +13 -0
  20. package/apps/desktop/application/operation-completion-checkpoint.ts +333 -0
  21. package/apps/desktop/application/operation-effects.ts +94 -0
  22. package/apps/desktop/application/operation.ts +224 -0
  23. package/apps/desktop/application/operations/analysis/faces.ts +244 -0
  24. package/apps/desktop/application/operations/analysis/music.ts +248 -0
  25. package/apps/desktop/application/operations/analysis/project-auto-zooms.ts +302 -0
  26. package/apps/desktop/application/operations/analysis/project-inactivity.ts +381 -0
  27. package/apps/desktop/application/operations/analysis/scenes.ts +272 -0
  28. package/apps/desktop/application/operations/analysis/shared.ts +202 -0
  29. package/apps/desktop/application/operations/derive/edit-batch.ts +967 -0
  30. package/apps/desktop/application/operations/derive/follow-faces.ts +454 -0
  31. package/apps/desktop/application/operations/edit/bind-candidate-revision.ts +91 -0
  32. package/apps/desktop/application/operations/edit/create-candidate-revision.ts +377 -0
  33. package/apps/desktop/application/operations/edit/create-revision.ts +255 -0
  34. package/apps/desktop/application/operations/edit/freeze-revision.ts +182 -0
  35. package/apps/desktop/application/operations/gateway/image.ts +41 -0
  36. package/apps/desktop/application/operations/gateway/index.ts +17 -0
  37. package/apps/desktop/application/operations/gateway/shared.ts +122 -0
  38. package/apps/desktop/application/operations/gateway/speech.ts +41 -0
  39. package/apps/desktop/application/operations/gateway/transcription.ts +42 -0
  40. package/apps/desktop/application/operations/gateway/video.ts +41 -0
  41. package/apps/desktop/application/operations/index.ts +31 -0
  42. package/apps/desktop/application/operations/iteration/create-candidate.ts +240 -0
  43. package/apps/desktop/application/operations/iteration/create-matrix.ts +117 -0
  44. package/apps/desktop/application/operations/iteration/select.ts +155 -0
  45. package/apps/desktop/application/operations/iteration/shared.ts +250 -0
  46. package/apps/desktop/application/operations/media/audio-effects.ts +376 -0
  47. package/apps/desktop/application/operations/media/binding.ts +79 -0
  48. package/apps/desktop/application/operations/media/capabilities.ts +112 -0
  49. package/apps/desktop/application/operations/media/color-grade.ts +343 -0
  50. package/apps/desktop/application/operations/media/html-overlay.ts +802 -0
  51. package/apps/desktop/application/operations/media/index.ts +8 -0
  52. package/apps/desktop/application/operations/media/ingest.ts +303 -0
  53. package/apps/desktop/application/operations/media/overlay.ts +729 -0
  54. package/apps/desktop/application/operations/media/shared.ts +845 -0
  55. package/apps/desktop/application/operations/media/transform-platform.ts +120 -0
  56. package/apps/desktop/application/operations/project/commit-edits.ts +2054 -0
  57. package/apps/desktop/application/operations/project/promote-selection.ts +495 -0
  58. package/apps/desktop/application/operations/project/snapshot.ts +95 -0
  59. package/apps/desktop/application/operations/recording/index.ts +5 -0
  60. package/apps/desktop/application/operations/recording/pause.ts +34 -0
  61. package/apps/desktop/application/operations/recording/resume.ts +34 -0
  62. package/apps/desktop/application/operations/recording/shared.ts +199 -0
  63. package/apps/desktop/application/operations/recording/start.ts +169 -0
  64. package/apps/desktop/application/operations/recording/stop.ts +34 -0
  65. package/apps/desktop/application/operations/render/bind-candidate-output.ts +324 -0
  66. package/apps/desktop/application/operations/render/materialize-selection.ts +322 -0
  67. package/apps/desktop/application/operations/render/project-caption-plan.ts +287 -0
  68. package/apps/desktop/application/operations/render/project-plan.ts +939 -0
  69. package/apps/desktop/application/operations/render/project-spatial-receipt.ts +70 -0
  70. package/apps/desktop/application/operations/render/project.ts +1922 -0
  71. package/apps/desktop/application/operations/shared.ts +67 -0
  72. package/apps/desktop/application/operations/slopcamera-portable.ts +1188 -0
  73. package/apps/desktop/application/operations/slopcamera-visuals.ts +784 -0
  74. package/apps/desktop/application/operations/spatial-project.ts +209 -0
  75. package/apps/desktop/application/operations/spatial-render.ts +415 -0
  76. package/apps/desktop/application/operations/spatial-scene.ts +97 -0
  77. package/apps/desktop/application/operations/studio.ts +143 -0
  78. package/apps/desktop/application/output-publication-lease.ts +163 -0
  79. package/apps/desktop/application/project-publication-lease.ts +233 -0
  80. package/apps/desktop/application/project-store.ts +196 -0
  81. package/apps/desktop/application/receipts.ts +533 -0
  82. package/apps/desktop/application/registry.ts +182 -0
  83. package/apps/desktop/application/spatial-assets.ts +675 -0
  84. package/apps/desktop/application/spatial-compositor-cadence.ts +23 -0
  85. package/apps/desktop/application/spatial-project-authority.ts +35 -0
  86. package/apps/desktop/application/spatial-project-lease.ts +126 -0
  87. package/apps/desktop/application/spatial-project-render-preparation.ts +225 -0
  88. package/apps/desktop/application/spatial-project-store.ts +286 -0
  89. package/apps/desktop/application/spatial-render-projection.ts +201 -0
  90. package/apps/desktop/application/spatial-render.ts +677 -0
  91. package/apps/desktop/application/spatial-spz.ts +44 -0
  92. package/apps/desktop/application/spatial-world-import.ts +135 -0
  93. package/apps/desktop/application/spatial-world-provenance.ts +46 -0
  94. package/apps/desktop/application/studio-port.ts +58 -0
  95. package/apps/desktop/application/verified-receipt-reconciliation.ts +1574 -0
  96. package/apps/desktop/capture/protocol.ts +689 -0
  97. package/apps/desktop/cli/analyzer.ts +406 -0
  98. package/apps/desktop/cli/args.ts +3181 -0
  99. package/apps/desktop/cli/asset-ingest.ts +747 -0
  100. package/apps/desktop/cli/atomic-render-effects.ts +210 -0
  101. package/apps/desktop/cli/atomic-render-platform.ts +205 -0
  102. package/apps/desktop/cli/atomic-render.ts +50 -0
  103. package/apps/desktop/cli/audio-analysis.ts +252 -0
  104. package/apps/desktop/cli/bounded-map.ts +39 -0
  105. package/apps/desktop/cli/bundle-service.ts +256 -0
  106. package/apps/desktop/cli/capabilities.ts +212 -0
  107. package/apps/desktop/cli/capture-bundle.ts +1117 -0
  108. package/apps/desktop/cli/command-host-resources.ts +251 -0
  109. package/apps/desktop/cli/commands.ts +6836 -0
  110. package/apps/desktop/cli/directing-blob.ts +291 -0
  111. package/apps/desktop/cli/directing-media.ts +517 -0
  112. package/apps/desktop/cli/directing-quote.ts +89 -0
  113. package/apps/desktop/cli/directing-service.ts +288 -0
  114. package/apps/desktop/cli/emoji-assets.ts +538 -0
  115. package/apps/desktop/cli/errors.ts +29 -0
  116. package/apps/desktop/cli/face-analysis-service.ts +940 -0
  117. package/apps/desktop/cli/filter-script.ts +76 -0
  118. package/apps/desktop/cli/gateway-application-port.ts +1142 -0
  119. package/apps/desktop/cli/gateway-credential.ts +81 -0
  120. package/apps/desktop/cli/gateway-media-artifacts.ts +723 -0
  121. package/apps/desktop/cli/gateway-media-catalog.ts +922 -0
  122. package/apps/desktop/cli/gateway-media-service.ts +3106 -0
  123. package/apps/desktop/cli/gateway-media-signature.ts +122 -0
  124. package/apps/desktop/cli/gateway-provider-options.ts +562 -0
  125. package/apps/desktop/cli/gateway-scene-provider.ts +391 -0
  126. package/apps/desktop/cli/help.ts +501 -0
  127. package/apps/desktop/cli/html-overlay-gpu.ts +97 -0
  128. package/apps/desktop/cli/html-overlay-renderer.ts +2478 -0
  129. package/apps/desktop/cli/io.ts +290 -0
  130. package/apps/desktop/cli/main.ts +123 -0
  131. package/apps/desktop/cli/media-effects-service.ts +885 -0
  132. package/apps/desktop/cli/media-ingest-model.ts +364 -0
  133. package/apps/desktop/cli/media-ingest-platform.ts +227 -0
  134. package/apps/desktop/cli/media-ingest-program.ts +200 -0
  135. package/apps/desktop/cli/media-ingest.ts +30 -0
  136. package/apps/desktop/cli/music-analysis-service.ts +434 -0
  137. package/apps/desktop/cli/mutation-lock.ts +530 -0
  138. package/apps/desktop/cli/native-assets.d.ts +12 -0
  139. package/apps/desktop/cli/native-media-runtime.macos.ts +7 -0
  140. package/apps/desktop/cli/overlay-playback.ts +177 -0
  141. package/apps/desktop/cli/paths.ts +265 -0
  142. package/apps/desktop/cli/portable-surface.ts +242 -0
  143. package/apps/desktop/cli/project-camera-receipt.ts +112 -0
  144. package/apps/desktop/cli/project-face-camera.ts +394 -0
  145. package/apps/desktop/cli/project-inactivity-service.ts +552 -0
  146. package/apps/desktop/cli/project-media-integrity.ts +121 -0
  147. package/apps/desktop/cli/project-renderer.ts +1526 -0
  148. package/apps/desktop/cli/project-service.ts +519 -0
  149. package/apps/desktop/cli/project-state-transaction.ts +520 -0
  150. package/apps/desktop/cli/query-limits.ts +1 -0
  151. package/apps/desktop/cli/recording-controller.ts +1567 -0
  152. package/apps/desktop/cli/recording-daemon.ts +931 -0
  153. package/apps/desktop/cli/recording-ref.ts +56 -0
  154. package/apps/desktop/cli/renamed-environment.ts +6 -0
  155. package/apps/desktop/cli/renderer.ts +1439 -0
  156. package/apps/desktop/cli/run-cli-test-helper.ts +60 -0
  157. package/apps/desktop/cli/scene-analysis-service.ts +879 -0
  158. package/apps/desktop/cli/spatial-compositor-verifier.ts +213 -0
  159. package/apps/desktop/cli/spatial-project-service.ts +90 -0
  160. package/apps/desktop/cli/spatial-scene-service.ts +105 -0
  161. package/apps/desktop/cli/spatial-world-service.ts +39 -0
  162. package/apps/desktop/cli/speech-analysis-service.ts +682 -0
  163. package/apps/desktop/cli/studio-assemble.ts +58 -0
  164. package/apps/desktop/cli/studio-command.ts +60 -0
  165. package/apps/desktop/cli/studio-custody.ts +60 -0
  166. package/apps/desktop/cli/studio-encode.ts +216 -0
  167. package/apps/desktop/cli/studio-exr.ts +52 -0
  168. package/apps/desktop/cli/studio-files.ts +179 -0
  169. package/apps/desktop/cli/studio-output-validation.ts +162 -0
  170. package/apps/desktop/cli/studio-process.ts +145 -0
  171. package/apps/desktop/cli/studio-runtime.ts +77 -0
  172. package/apps/desktop/cli/studio-scaffold.ts +70 -0
  173. package/apps/desktop/cli/studio-service.ts +301 -0
  174. package/apps/desktop/cli/studio-spatial-asset.ts +248 -0
  175. package/apps/desktop/cli/studio-template-names.ts +3 -0
  176. package/apps/desktop/cli/studio-workflow.ts +19 -0
  177. package/apps/desktop/cli/time.ts +25 -0
  178. package/apps/desktop/cli/workflow-code.ts +584 -0
  179. package/apps/desktop/cli/workflow-runs.ts +576 -0
  180. package/apps/desktop/code/advanced.ts +139 -0
  181. package/apps/desktop/code/application-node-planner.ts +1288 -0
  182. package/apps/desktop/code/compiler.ts +329 -0
  183. package/apps/desktop/code/contracts.ts +13 -0
  184. package/apps/desktop/code/creative-recipes.ts +94 -0
  185. package/apps/desktop/code/define-workflow.ts +115 -0
  186. package/apps/desktop/code/editing.ts +284 -0
  187. package/apps/desktop/code/file-candidate-provenance.ts +420 -0
  188. package/apps/desktop/code/file-candidate.ts +69 -0
  189. package/apps/desktop/code/graph-builder.ts +10 -0
  190. package/apps/desktop/code/host-resource-policy.ts +55 -0
  191. package/apps/desktop/code/plan-contracts.ts +159 -0
  192. package/apps/desktop/code/planning.ts +361 -0
  193. package/apps/desktop/code/public.ts +134 -0
  194. package/apps/desktop/code/reference-projection.ts +62 -0
  195. package/apps/desktop/code/run-contracts.ts +466 -0
  196. package/apps/desktop/code/run-store.ts +2478 -0
  197. package/apps/desktop/code/runtime-identity.ts +328 -0
  198. package/apps/desktop/code/scheduler.ts +3067 -0
  199. package/apps/desktop/code/semantic-builder.ts +1436 -0
  200. package/apps/desktop/code/source-bundle.ts +1641 -0
  201. package/apps/desktop/code/source-typecheck.ts +211 -0
  202. package/apps/desktop/code/testing.ts +79 -0
  203. package/apps/desktop/code/worker-client.ts +1675 -0
  204. package/apps/desktop/code/worker-effects.ts +141 -0
  205. package/apps/desktop/code/worker-entry.ts +435 -0
  206. package/apps/desktop/code/worker-lease-guardian.ts +179 -0
  207. package/apps/desktop/code/worker-process-identity.ts +484 -0
  208. package/apps/desktop/code/worker-protocol.ts +211 -0
  209. package/apps/desktop/code/workflow-effects.ts +132 -0
  210. package/apps/desktop/contracts/analysis.ts +949 -0
  211. package/apps/desktop/contracts/edit.ts +576 -0
  212. package/apps/desktop/contracts/index.ts +9 -0
  213. package/apps/desktop/contracts/media-effects.ts +139 -0
  214. package/apps/desktop/contracts/project-render.ts +644 -0
  215. package/apps/desktop/contracts/project.ts +740 -0
  216. package/apps/desktop/contracts/recording.ts +1434 -0
  217. package/apps/desktop/contracts/render.ts +334 -0
  218. package/apps/desktop/contracts/runtime.ts +155 -0
  219. package/apps/desktop/contracts/spatial-compositor.ts +58 -0
  220. package/apps/desktop/contracts/spatial-project.ts +159 -0
  221. package/apps/desktop/contracts/spatial-world.ts +48 -0
  222. package/apps/desktop/contracts/video-effects.ts +120 -0
  223. package/apps/desktop/core/alignment-apply.ts +400 -0
  224. package/apps/desktop/core/audio-alignment.ts +466 -0
  225. package/apps/desktop/core/auto-zoom.ts +209 -0
  226. package/apps/desktop/core/canonical-json.ts +14 -0
  227. package/apps/desktop/core/emoji.ts +210 -0
  228. package/apps/desktop/core/events.ts +409 -0
  229. package/apps/desktop/core/face-framing.ts +533 -0
  230. package/apps/desktop/core/face-tracks.ts +326 -0
  231. package/apps/desktop/core/inactivity.ts +137 -0
  232. package/apps/desktop/core/index.ts +30 -0
  233. package/apps/desktop/core/intervals.ts +123 -0
  234. package/apps/desktop/core/montage.ts +236 -0
  235. package/apps/desktop/core/music-analysis.ts +518 -0
  236. package/apps/desktop/core/plan.ts +244 -0
  237. package/apps/desktop/core/project-auto-zoom.ts +75 -0
  238. package/apps/desktop/core/project-camera-spatial.ts +676 -0
  239. package/apps/desktop/core/project-camera.ts +403 -0
  240. package/apps/desktop/core/project-captions.ts +888 -0
  241. package/apps/desktop/core/project-inactivity.ts +125 -0
  242. package/apps/desktop/core/project-metadata.ts +927 -0
  243. package/apps/desktop/core/project-plan.ts +375 -0
  244. package/apps/desktop/core/project-render-plan.ts +303 -0
  245. package/apps/desktop/core/project-time.ts +469 -0
  246. package/apps/desktop/core/render-plan.ts +442 -0
  247. package/apps/desktop/core/scene-cache.ts +174 -0
  248. package/apps/desktop/core/scene-sampling.ts +448 -0
  249. package/apps/desktop/core/spatial-compositor.ts +22 -0
  250. package/apps/desktop/core/spatial-durability.ts +99 -0
  251. package/apps/desktop/core/spatial-project.ts +169 -0
  252. package/apps/desktop/core/spatial-shot-clock.ts +32 -0
  253. package/apps/desktop/core/speech-analysis.ts +333 -0
  254. package/apps/desktop/core/storage.ts +970 -0
  255. package/apps/desktop/core/time-map.ts +91 -0
  256. package/apps/desktop/core/time.ts +61 -0
  257. package/apps/desktop/core/video-effects.ts +660 -0
  258. package/apps/desktop/dist/cli/NebulaSans-Bold-26se8aek.otf +0 -0
  259. package/apps/desktop/dist/cli/NebulaSans-Bold-bcz7y08t.woff2 +0 -0
  260. package/apps/desktop/dist/cli/NebulaSans-Book-5ax05zvn.woff2 +0 -0
  261. package/apps/desktop/dist/cli/NebulaSans-Book-8cenzchw.otf +0 -0
  262. package/apps/desktop/dist/cli/main.js +5086 -0
  263. package/apps/desktop/html-overlay/catalog.ts +171 -0
  264. package/apps/desktop/html-overlay/contracts.ts +372 -0
  265. package/apps/desktop/html-overlay/execution-profile.ts +77 -0
  266. package/apps/desktop/html-overlay/index.ts +98 -0
  267. package/apps/desktop/html-overlay/libraries.ts +263 -0
  268. package/apps/desktop/html-overlay/random.ts +49 -0
  269. package/apps/desktop/html-overlay/runtime.ts +813 -0
  270. package/apps/desktop/html-overlay/scaffolds.ts +792 -0
  271. package/apps/desktop/html-overlay/spark-runtime.ts +88 -0
  272. package/apps/desktop/html-overlay/spatial-splat-runtime.ts +60 -0
  273. package/apps/desktop/html-overlay/spatial.ts +720 -0
  274. package/apps/desktop/studio/assets/README.md +39 -0
  275. package/apps/desktop/studio/assets/contracts.ts +129 -0
  276. package/apps/desktop/studio/assets/network.ts +64 -0
  277. package/apps/desktop/studio/assets/poly-haven.ts +148 -0
  278. package/apps/desktop/studio/drivers/blender_driver.py +466 -0
  279. package/apps/desktop/studio/drivers/cadquery_driver.py +176 -0
  280. package/apps/desktop/studio/education/driver.py +308 -0
  281. package/apps/desktop/studio/education/lesson.py +180 -0
  282. package/apps/desktop/studio/education/toolkit.py +249 -0
  283. package/apps/desktop/workflows/chaptered-demo.ts +48 -0
  284. package/apps/desktop/workflows/creative-iteration.ts +107 -0
  285. package/apps/desktop/workflows/creative-selection.ts +92 -0
  286. package/apps/desktop/workflows/fragments.ts +486 -0
  287. package/apps/desktop/workflows/index.ts +93 -0
  288. package/apps/desktop/workflows/polished-screen-demo.ts +128 -0
  289. package/apps/desktop/workflows/scene-direction.ts +12 -0
  290. package/apps/desktop/workflows/social-variants.ts +75 -0
  291. package/apps/desktop/workflows/talking-head-cleanup.ts +53 -0
  292. package/dist/NebulaSans-Bold-26se8aek.otf +0 -0
  293. package/dist/NebulaSans-Bold-bcz7y08t.woff2 +0 -0
  294. package/dist/NebulaSans-Book-5ax05zvn.woff2 +0 -0
  295. package/dist/NebulaSans-Book-8cenzchw.otf +0 -0
  296. package/dist/cli.js +479 -0
  297. package/dist/code/advanced.js +270 -0
  298. package/dist/code/index.js +2240 -0
  299. package/dist/generate.js +24 -0
  300. package/dist/host-resources.js +26 -0
  301. package/dist/index-42zsesc1.js +2257 -0
  302. package/dist/index-7308egqr.js +48 -0
  303. package/dist/index-8txs6fkn.js +712 -0
  304. package/dist/index-mcy8z0br.js +192 -0
  305. package/dist/index-p63wavx0.js +2029 -0
  306. package/dist/index-r7gdhmsp.js +424 -0
  307. package/dist/index-sh6xbav6.js +1219 -0
  308. package/dist/index-z1w83f81.js +4 -0
  309. package/dist/index-z7239b4h.js +2363 -0
  310. package/dist/index-zfeg9hmw.js +2013 -0
  311. package/dist/index.js +241 -0
  312. package/dist/operations.js +29 -0
  313. package/dist/skill-install-dh0ntqba.js +10 -0
  314. package/dist/vectorize/worker.js +142 -0
  315. package/dist/workflow.js +16 -0
  316. package/docs/README.md +38 -0
  317. package/docs/studio.md +215 -0
  318. package/examples/studio/blender/README.md +26 -0
  319. package/examples/studio/blender/character.py +152 -0
  320. package/examples/studio/blender/cloth.py +101 -0
  321. package/examples/studio/blender/color_chart.py +29 -0
  322. package/examples/studio/blender/fluid.py +78 -0
  323. package/examples/studio/blender/import_model.py +74 -0
  324. package/examples/studio/blender/product.py +53 -0
  325. package/examples/studio/blender/shaded_street.py +481 -0
  326. package/examples/studio/blender/studio_scene.py +147 -0
  327. package/examples/studio/cadquery/README.md +13 -0
  328. package/examples/studio/cadquery/bracket.py +36 -0
  329. package/examples/studio/cadquery/import_step.py +12 -0
  330. package/examples/studio/education/README.md +46 -0
  331. package/examples/studio/education/lesson.json +99 -0
  332. package/examples/studio/education/scene.py +7 -0
  333. package/examples/studio/hybrid-scene.ts +96 -0
  334. package/examples/studio/native-workflow.ts +14 -0
  335. package/examples/studio/vgpu/README.md +64 -0
  336. package/examples/studio/vgpu/heat-field.mjs +290 -0
  337. package/package.json +304 -0
  338. package/packages/scene/src/index.ts +1 -0
  339. package/packages/scene/src/scene.ts +215 -0
  340. package/schema/diagram.schema.json +334 -0
  341. package/skills/slopcamera/SKILL.md +45 -0
  342. package/skills/slopcamera/agents/openai.yaml +4 -0
  343. package/skills/slopcamera/references/customization.md +77 -0
  344. package/skills/slopcamera/references/diagrams.md +153 -0
  345. package/skills/slopcamera/references/directed-scenes.md +42 -0
  346. package/skills/slopcamera/references/directing-video.md +18 -0
  347. package/skills/slopcamera/references/educational-video.md +26 -0
  348. package/skills/slopcamera/references/gateway-media.md +134 -0
  349. package/skills/slopcamera/references/install.md +62 -0
  350. package/skills/slopcamera/references/native-studio.md +31 -0
  351. package/skills/slopcamera/references/reference-led-3d.md +140 -0
  352. package/skills/slopcamera/references/rubber-stamp-examples/poster-example-1.jpg +0 -0
  353. package/skills/slopcamera/references/rubber-stamp-examples/poster-example-2.jpg +0 -0
  354. package/skills/slopcamera/references/rubber-stamp-examples/stamp-style-1.png +0 -0
  355. package/skills/slopcamera/references/rubber-stamp-examples/stamp-style-2.png +0 -0
  356. package/skills/slopcamera/references/rubber-stamp-field-notes.md +144 -0
  357. package/skills/slopcamera/references/vectorization.md +29 -0
  358. package/skills/slopcamera/references/video-projects.md +187 -0
  359. package/skills/slopcamera/references/visual-communication.md +120 -0
  360. package/skills/slopcamera/references/workflows-sdk.md +45 -0
  361. package/skills/slopcamera/scripts/compose-rubber-stamp-field-note.ts +229 -0
  362. package/src/artifacts.ts +106 -0
  363. package/src/assets/fonts/nebula-sans/LICENSE.txt +96 -0
  364. package/src/assets/fonts/nebula-sans/NebulaSans-Bold.otf +0 -0
  365. package/src/assets/fonts/nebula-sans/NebulaSans-Bold.woff2 +0 -0
  366. package/src/assets/fonts/nebula-sans/NebulaSans-Book.otf +0 -0
  367. package/src/assets/fonts/nebula-sans/NebulaSans-Book.woff2 +0 -0
  368. package/src/assets/fonts/nebula-sans/PROVENANCE.md +21 -0
  369. package/src/assets.d.ts +9 -0
  370. package/src/cli.ts +601 -0
  371. package/src/cloud-errors.ts +26 -0
  372. package/src/code/advanced.ts +10 -0
  373. package/src/code/boundary.ts +21 -0
  374. package/src/code/canonical-json.ts +129 -0
  375. package/src/code/compiler.ts +953 -0
  376. package/src/code/contracts.ts +576 -0
  377. package/src/code/define-workflow.ts +334 -0
  378. package/src/code/errors.ts +41 -0
  379. package/src/code/graph-builder.ts +945 -0
  380. package/src/code/index.ts +121 -0
  381. package/src/code/json-snapshot.ts +899 -0
  382. package/src/code/json-utf8.ts +88 -0
  383. package/src/code/portable-builder.ts +136 -0
  384. package/src/code/projection.ts +378 -0
  385. package/src/code/public-operations.ts +450 -0
  386. package/src/code/runtime.ts +580 -0
  387. package/src/code/sha256.ts +36 -0
  388. package/src/config.ts +180 -0
  389. package/src/desktop.ts +253 -0
  390. package/src/fs.ts +10 -0
  391. package/src/generate.ts +704 -0
  392. package/src/host-resource-posix.ts +161 -0
  393. package/src/host-resources.ts +1749 -0
  394. package/src/icons.ts +58 -0
  395. package/src/index.ts +200 -0
  396. package/src/label-layout.ts +130 -0
  397. package/src/layout.ts +413 -0
  398. package/src/lint.ts +127 -0
  399. package/src/mcp/boundary.ts +354 -0
  400. package/src/mcp/index.ts +33 -0
  401. package/src/mcp/server.ts +272 -0
  402. package/src/mcp/tools.ts +963 -0
  403. package/src/mcp/types.ts +71 -0
  404. package/src/operations.ts +775 -0
  405. package/src/parse.ts +861 -0
  406. package/src/process-environment.ts +17 -0
  407. package/src/render.ts +437 -0
  408. package/src/skill-install.ts +49 -0
  409. package/src/spatial-scene/authoring.ts +27 -0
  410. package/src/spatial-scene/camera-track.ts +83 -0
  411. package/src/spatial-scene/contracts.ts +277 -0
  412. package/src/spatial-scene/evaluate.ts +145 -0
  413. package/src/spatial-scene/gltf.ts +558 -0
  414. package/src/spatial-scene/identity.ts +260 -0
  415. package/src/spatial-scene/index.ts +10 -0
  416. package/src/spatial-scene/inspect.ts +68 -0
  417. package/src/spatial-scene/math.ts +280 -0
  418. package/src/spatial-scene/patch.ts +131 -0
  419. package/src/spatial-scene/time.ts +53 -0
  420. package/src/studio/contracts.ts +129 -0
  421. package/src/studio/index.ts +2 -0
  422. package/src/studio/plan.ts +156 -0
  423. package/src/studio/shared.ts +41 -0
  424. package/src/theme.ts +68 -0
  425. package/src/tldr.ts +474 -0
  426. package/src/types.ts +212 -0
  427. package/src/vectorize/archive.ts +101 -0
  428. package/src/vectorize/command.ts +797 -0
  429. package/src/vectorize/index.ts +27 -0
  430. package/src/vectorize/limits.ts +61 -0
  431. package/src/vectorize/metrics.ts +351 -0
  432. package/src/vectorize/pixels.ts +323 -0
  433. package/src/vectorize/supervisor.ts +339 -0
  434. package/src/vectorize/svg.ts +188 -0
  435. package/src/vectorize/tool.ts +542 -0
  436. package/src/vectorize/types.ts +113 -0
  437. package/src/vectorize/vectorize.ts +634 -0
  438. package/src/vectorize/worker-protocol.ts +40 -0
  439. package/src/vectorize/worker.ts +209 -0
  440. package/src/version.ts +1 -0
  441. package/src/workflow.ts +409 -0
@@ -0,0 +1,179 @@
1
+ import { fstatSync } from "node:fs";
2
+
3
+ import {
4
+ guardianPinsWorkerProcessId,
5
+ joinAndPinWorkerProcessGroup,
6
+ parseWorkerProcessStartIdentity,
7
+ workerProcessStartIdentityStatus,
8
+ } from "./worker-process-identity";
9
+
10
+ const POLL_MILLISECONDS = 20;
11
+ const INHERITED_LEASE_FILE_DESCRIPTOR = 3;
12
+
13
+ function argument(name: string): string {
14
+ const index = process.argv.indexOf(name);
15
+ const value = index === -1 ? undefined : process.argv[index + 1];
16
+ if (value === undefined || value === "") {
17
+ throw new Error(`Missing code-worker lease-guardian argument: ${name}`);
18
+ }
19
+ return value;
20
+ }
21
+
22
+ function positiveProcessId(value: string): number {
23
+ const processId = Number(value);
24
+ if (!Number.isSafeInteger(processId) || processId < 2) {
25
+ throw new Error("Code-worker lease guardian requires a positive worker PID.");
26
+ }
27
+ return processId;
28
+ }
29
+
30
+ async function waitForWorkerExit(
31
+ processId: number,
32
+ expectedIdentity: string,
33
+ ): Promise<void> {
34
+ while (
35
+ workerProcessStartIdentityStatus(processId, expectedIdentity)
36
+ !== "different-or-dead"
37
+ ) {
38
+ // Unknown identity is not evidence of death. Retain the inherited lease
39
+ // until the exact worker is absent or its PID belongs to another process.
40
+ await Bun.sleep(POLL_MILLISECONDS);
41
+ }
42
+ }
43
+
44
+ async function terminateWorker(
45
+ processId: number,
46
+ expectedIdentity: string,
47
+ ): Promise<void> {
48
+ while (true) {
49
+ const status = workerProcessStartIdentityStatus(
50
+ processId,
51
+ expectedIdentity,
52
+ );
53
+ if (status === "different-or-dead") return;
54
+ if (status === "unknown") {
55
+ await Bun.sleep(POLL_MILLISECONDS);
56
+ continue;
57
+ }
58
+ if (!guardianPinsWorkerProcessId(processId)) {
59
+ // Losing the kernel pin is uncertainty, never permission to signal a
60
+ // reusable numeric PID or release the inherited machine lease.
61
+ await Bun.sleep(POLL_MILLISECONDS);
62
+ continue;
63
+ }
64
+ try {
65
+ // The start identity was reattested immediately before signaling, and
66
+ // this guardian's membership in the worker-led process group keeps that
67
+ // numeric PID allocated across the check-to-signal boundary.
68
+ process.kill(processId, "SIGKILL");
69
+ } catch (error) {
70
+ if (
71
+ typeof error === "object"
72
+ && error !== null
73
+ && "code" in error
74
+ && Reflect.get(error, "code") === "ESRCH"
75
+ ) {
76
+ return;
77
+ }
78
+ // Permission or transient kernel errors are uncertainty, not permission
79
+ // to release the lease. Retry while the exact process remains attested.
80
+ await Bun.sleep(POLL_MILLISECONDS);
81
+ continue;
82
+ }
83
+ break;
84
+ }
85
+ // Retain the inherited kernel lease until the worker is observably gone.
86
+ await waitForWorkerExit(processId, expectedIdentity);
87
+ }
88
+
89
+ type GuardianSignalSource = {
90
+ on(signal: "SIGINT" | "SIGTERM", listener: () => void): unknown;
91
+ };
92
+
93
+ export function installGuardianSignalHandlers(
94
+ signalSource: GuardianSignalSource,
95
+ settle: () => void,
96
+ ): void {
97
+ // Handlers stay installed while asynchronous retirement is in flight. A
98
+ // repeated signal must not restore the default action and drop the lease.
99
+ for (const signal of ["SIGINT", "SIGTERM"] as const) {
100
+ signalSource.on(signal, settle);
101
+ }
102
+ }
103
+
104
+ async function main(): Promise<void> {
105
+ if (process.platform === "win32") {
106
+ throw new Error("Code-worker lease guardians require POSIX descriptors.");
107
+ }
108
+ const workerProcessId = positiveProcessId(argument("--worker-pid"));
109
+ const workerStartIdentity = parseWorkerProcessStartIdentity(
110
+ argument("--worker-start-identity"),
111
+ );
112
+ fstatSync(INHERITED_LEASE_FILE_DESCRIPTOR);
113
+ if (
114
+ workerProcessStartIdentityStatus(workerProcessId, workerStartIdentity)
115
+ !== "exact-live-worker"
116
+ ) {
117
+ throw new Error(
118
+ "Code-worker lease guardian could not attest the exact live worker process.",
119
+ );
120
+ }
121
+ await joinAndPinWorkerProcessGroup(
122
+ workerProcessId,
123
+ workerStartIdentity,
124
+ );
125
+
126
+ let completed = false;
127
+ let settling = false;
128
+ let input = "";
129
+ const settle = async (killWorker: boolean): Promise<void> => {
130
+ if (settling) return;
131
+ settling = true;
132
+ if (killWorker) {
133
+ await terminateWorker(workerProcessId, workerStartIdentity);
134
+ }
135
+ process.exit(0);
136
+ };
137
+
138
+ process.stdin.setEncoding("utf8");
139
+ process.stdin.on("data", chunk => {
140
+ input += typeof chunk === "string" ? chunk : chunk.toString("utf8");
141
+ if (input.length > 64 || (!"complete\n".startsWith(input) && input !== "complete\n")) {
142
+ void settle(true);
143
+ return;
144
+ }
145
+ if (input === "complete\n") {
146
+ completed = true;
147
+ void settle(false);
148
+ }
149
+ });
150
+ process.stdin.once("end", () => {
151
+ void settle(!completed);
152
+ });
153
+ process.stdin.once("error", () => {
154
+ void settle(true);
155
+ });
156
+ installGuardianSignalHandlers(process, () => {
157
+ void settle(true);
158
+ });
159
+
160
+ const workerPoll = setInterval(() => {
161
+ if (
162
+ workerProcessStartIdentityStatus(workerProcessId, workerStartIdentity)
163
+ === "different-or-dead"
164
+ ) {
165
+ void settle(false);
166
+ }
167
+ }, POLL_MILLISECONDS);
168
+ workerPoll.unref();
169
+ process.stdout.write("ready\n");
170
+ }
171
+
172
+ if (import.meta.main) {
173
+ try {
174
+ await main();
175
+ } catch (error) {
176
+ process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
177
+ process.exit(1);
178
+ }
179
+ }
@@ -0,0 +1,484 @@
1
+ import { execFileSync } from "node:child_process";
2
+ import { createHash } from "node:crypto";
3
+ import { readFileSync } from "node:fs";
4
+
5
+ import { dlopen, ptr } from "bun:ffi";
6
+
7
+ export type WorkerProcessStartIdentityStatus =
8
+ | "exact-live-worker"
9
+ | "different-or-dead"
10
+ | "unknown";
11
+
12
+ type ProcessRecordInspection =
13
+ | { readonly status: "alive"; readonly rawStartIdentity: string }
14
+ | { readonly status: "dead" | "unknown" };
15
+
16
+ type DarwinProcessIdentityRecordReader = (
17
+ processId: number,
18
+ ) => Uint8Array | null;
19
+
20
+ const DARWIN_PROC_PID_T_BSDINFO_WITH_UNIQID = 18;
21
+ const DARWIN_PROC_BSDINFO_SIZE = 136;
22
+ const DARWIN_PROC_UNIQIDENTIFIERINFO_SIZE = 56;
23
+ const DARWIN_PROC_BSDINFO_WITH_UNIQID_SIZE =
24
+ DARWIN_PROC_BSDINFO_SIZE + DARWIN_PROC_UNIQIDENTIFIERINFO_SIZE;
25
+ const DARWIN_PROC_BSDINFO_FLAGS_OFFSET = 0;
26
+ const DARWIN_PROC_BSDINFO_STATUS_OFFSET = 4;
27
+ const DARWIN_PROC_BSDINFO_PID_OFFSET = 12;
28
+ const DARWIN_PROC_BSDINFO_START_SECONDS_OFFSET = 120;
29
+ const DARWIN_PROC_BSDINFO_START_MICROSECONDS_OFFSET = 128;
30
+ const DARWIN_PROC_UNIQUE_ID_OFFSET = 16;
31
+ const DARWIN_PROC_ID_VERSION_OFFSET = 32;
32
+ const DARWIN_PROC_FLAG_INEXIT = 0x4;
33
+ const DARWIN_PROCESS_STATUS_IDLE = 1;
34
+ const DARWIN_PROCESS_STATUS_RUNNING = 2;
35
+ const DARWIN_PROCESS_STATUS_SLEEPING = 3;
36
+ const DARWIN_PROCESS_STATUS_STOPPED = 4;
37
+ const DARWIN_PROCESS_STATUS_ZOMBIE = 5;
38
+ const DARWIN_PROCESS_INSPECTION_ATTEMPTS = 3;
39
+ const PROCESS_START_IDENTITY_PATTERN = /^[a-f0-9]{64}$/u;
40
+ const UUID_PATTERN =
41
+ /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/iu;
42
+
43
+ let cachedBootIdentity: string | undefined;
44
+ let cachedDarwinProcPidInfo:
45
+ | ((processId: number, flavor: number, buffer: Uint8Array) => number)
46
+ | undefined;
47
+ let cachedProcessGroupFunctions: {
48
+ readonly getProcessGroup: (processId: number) => number;
49
+ readonly setProcessGroup: (processId: number, groupId: number) => number;
50
+ } | undefined;
51
+
52
+ function digestIdentity(kind: string, value: string): string {
53
+ return createHash("sha256")
54
+ .update(kind, "utf8")
55
+ .update("\0", "utf8")
56
+ .update(value, "utf8")
57
+ .digest("hex");
58
+ }
59
+
60
+ function positiveProcessId(processId: number): number {
61
+ if (!Number.isSafeInteger(processId) || processId < 2) {
62
+ throw new Error("Code-worker process identity requires a positive worker PID.");
63
+ }
64
+ return processId;
65
+ }
66
+
67
+ function processGroupFunctions(): {
68
+ readonly getProcessGroup: (processId: number) => number;
69
+ readonly setProcessGroup: (processId: number, groupId: number) => number;
70
+ } {
71
+ if (cachedProcessGroupFunctions !== undefined) {
72
+ return cachedProcessGroupFunctions;
73
+ }
74
+ const libraryPath = process.platform === "darwin"
75
+ ? "/usr/lib/libSystem.B.dylib"
76
+ : process.platform === "linux"
77
+ ? "libc.so.6"
78
+ : undefined;
79
+ if (libraryPath === undefined) {
80
+ throw new Error(
81
+ `Code-worker process groups are unsupported on ${process.platform}.`,
82
+ );
83
+ }
84
+ const library = dlopen(libraryPath, {
85
+ getpgid: {
86
+ args: ["int"],
87
+ returns: "int",
88
+ },
89
+ setpgid: {
90
+ args: ["int", "int"],
91
+ returns: "int",
92
+ },
93
+ } as const);
94
+ cachedProcessGroupFunctions = {
95
+ getProcessGroup: processId => library.symbols.getpgid(processId),
96
+ setProcessGroup: (processId, groupId) => (
97
+ library.symbols.setpgid(processId, groupId)
98
+ ),
99
+ };
100
+ return cachedProcessGroupFunctions;
101
+ }
102
+
103
+ /**
104
+ * Make the worker a process-group leader before any authored module executes.
105
+ * A process-group leader cannot move to another group or create a new session.
106
+ */
107
+ export function establishCurrentWorkerProcessGroup(): void {
108
+ if (process.platform !== "linux" && process.platform !== "darwin") return;
109
+ const processId = positiveProcessId(process.pid);
110
+ const groups = processGroupFunctions();
111
+ const result = groups.setProcessGroup(0, 0);
112
+ if (
113
+ result !== 0
114
+ && groups.getProcessGroup(0) !== processId
115
+ ) {
116
+ throw new Error("Code worker could not establish its stable process group.");
117
+ }
118
+ if (groups.getProcessGroup(0) !== processId) {
119
+ throw new Error("Code worker process group does not match its process ID.");
120
+ }
121
+ }
122
+
123
+ /**
124
+ * Join the guardian to the exact worker's group. Keeping the guardian in that
125
+ * group pins the numeric worker PID in the kernel until retirement settles,
126
+ * closing the identity-check-to-signal reuse race.
127
+ */
128
+ export async function joinAndPinWorkerProcessGroup(
129
+ workerProcessId: number,
130
+ expectedIdentity: string,
131
+ timeoutMilliseconds = 2_000,
132
+ ): Promise<void> {
133
+ const processId = positiveProcessId(workerProcessId);
134
+ const identity = parseWorkerProcessStartIdentity(expectedIdentity);
135
+ const groups = processGroupFunctions();
136
+ const deadline = Date.now() + timeoutMilliseconds;
137
+ while (Date.now() < deadline) {
138
+ const status = workerProcessStartIdentityStatus(processId, identity);
139
+ if (status === "different-or-dead") {
140
+ throw new Error("Exact code worker exited before its process group was pinned.");
141
+ }
142
+ if (status === "exact-live-worker") {
143
+ groups.setProcessGroup(0, processId);
144
+ if (
145
+ groups.getProcessGroup(0) === processId
146
+ && groups.getProcessGroup(processId) === processId
147
+ && workerProcessStartIdentityStatus(processId, identity)
148
+ === "exact-live-worker"
149
+ ) {
150
+ return;
151
+ }
152
+ }
153
+ await Bun.sleep(20);
154
+ }
155
+ throw new Error("Timed out pinning the exact code-worker process group.");
156
+ }
157
+
158
+ export function guardianPinsWorkerProcessId(workerProcessId: number): boolean {
159
+ if (process.platform !== "linux" && process.platform !== "darwin") return false;
160
+ try {
161
+ const processId = positiveProcessId(workerProcessId);
162
+ return processGroupFunctions().getProcessGroup(0) === processId;
163
+ } catch {
164
+ return false;
165
+ }
166
+ }
167
+
168
+ function processIsDefinitelyMissing(processId: number): boolean {
169
+ try {
170
+ process.kill(processId, 0);
171
+ return false;
172
+ } catch (error) {
173
+ return (
174
+ typeof error === "object"
175
+ && error !== null
176
+ && "code" in error
177
+ && Reflect.get(error, "code") === "ESRCH"
178
+ );
179
+ }
180
+ }
181
+
182
+ function commandText(command: string, arguments_: readonly string[]): string {
183
+ return execFileSync(command, arguments_, {
184
+ encoding: "utf8",
185
+ env: {
186
+ LANG: "C",
187
+ LC_ALL: "C",
188
+ NODE_ENV: "production",
189
+ PATH: "/usr/bin:/bin:/usr/sbin:/sbin",
190
+ TZ: "UTC",
191
+ },
192
+ timeout: 2_000,
193
+ }).trim();
194
+ }
195
+
196
+ function bootIdentity(): string {
197
+ if (cachedBootIdentity !== undefined) return cachedBootIdentity;
198
+ let source: string;
199
+ if (process.platform === "linux") {
200
+ source = readFileSync("/proc/sys/kernel/random/boot_id", "utf8").trim();
201
+ if (!UUID_PATTERN.test(source)) {
202
+ throw new Error("Linux boot identity is malformed.");
203
+ }
204
+ } else if (process.platform === "darwin") {
205
+ source = commandText("/usr/sbin/sysctl", [
206
+ "-n",
207
+ "kern.bootsessionuuid",
208
+ ]).toLowerCase();
209
+ if (!UUID_PATTERN.test(source)) {
210
+ throw new Error("macOS boot identity is malformed.");
211
+ }
212
+ } else {
213
+ throw new Error(
214
+ `Code-worker process identity is unsupported on ${process.platform}.`,
215
+ );
216
+ }
217
+ cachedBootIdentity = digestIdentity("slopcamera-worker-boot", source);
218
+ return cachedBootIdentity;
219
+ }
220
+
221
+ function inspectLinuxProcessRecord(raw: string): ProcessRecordInspection {
222
+ // Field 2 (`comm`) may contain spaces and parentheses. Its final `) ` is the
223
+ // only safe boundary before field 3; field 22 (`starttime`) is then index 19.
224
+ const commandEnd = raw.lastIndexOf(") ");
225
+ if (commandEnd < 2) return { status: "unknown" };
226
+ const fields = raw.slice(commandEnd + 2).trim().split(/\s+/u);
227
+ const state = fields[0];
228
+ if (state === "Z" || state === "X" || state === "x") {
229
+ return { status: "dead" };
230
+ }
231
+ if (
232
+ state !== "R"
233
+ && state !== "S"
234
+ && state !== "D"
235
+ && state !== "T"
236
+ && state !== "t"
237
+ && state !== "W"
238
+ && state !== "K"
239
+ && state !== "P"
240
+ && state !== "I"
241
+ ) {
242
+ return { status: "unknown" };
243
+ }
244
+ const startTicks = fields[19];
245
+ if (startTicks === undefined || !/^[1-9][0-9]{0,31}$/u.test(startTicks)) {
246
+ return { status: "unknown" };
247
+ }
248
+ return { status: "alive", rawStartIdentity: startTicks };
249
+ }
250
+
251
+ function inspectDarwinProcessIdentity(
252
+ raw: Uint8Array,
253
+ expectedProcessId: number,
254
+ ): ProcessRecordInspection {
255
+ if (raw.byteLength < DARWIN_PROC_BSDINFO_WITH_UNIQID_SIZE) {
256
+ return { status: "unknown" };
257
+ }
258
+ const view = new DataView(raw.buffer, raw.byteOffset, raw.byteLength);
259
+ const flags = view.getUint32(DARWIN_PROC_BSDINFO_FLAGS_OFFSET, true);
260
+ const status = view.getUint32(DARWIN_PROC_BSDINFO_STATUS_OFFSET, true);
261
+ const processId = view.getUint32(DARWIN_PROC_BSDINFO_PID_OFFSET, true);
262
+ if (processId !== expectedProcessId) return { status: "unknown" };
263
+ if (
264
+ status === DARWIN_PROCESS_STATUS_ZOMBIE
265
+ || (flags & DARWIN_PROC_FLAG_INEXIT) !== 0
266
+ ) {
267
+ return { status: "dead" };
268
+ }
269
+ if (
270
+ status !== DARWIN_PROCESS_STATUS_IDLE
271
+ && status !== DARWIN_PROCESS_STATUS_RUNNING
272
+ && status !== DARWIN_PROCESS_STATUS_SLEEPING
273
+ && status !== DARWIN_PROCESS_STATUS_STOPPED
274
+ ) {
275
+ return { status: "unknown" };
276
+ }
277
+ const startSeconds = view.getBigUint64(
278
+ DARWIN_PROC_BSDINFO_START_SECONDS_OFFSET,
279
+ true,
280
+ );
281
+ const startMicroseconds = view.getBigUint64(
282
+ DARWIN_PROC_BSDINFO_START_MICROSECONDS_OFFSET,
283
+ true,
284
+ );
285
+ const uniqueId = view.getBigUint64(
286
+ DARWIN_PROC_BSDINFO_SIZE + DARWIN_PROC_UNIQUE_ID_OFFSET,
287
+ true,
288
+ );
289
+ const idVersion = view.getUint32(
290
+ DARWIN_PROC_BSDINFO_SIZE + DARWIN_PROC_ID_VERSION_OFFSET,
291
+ true,
292
+ );
293
+ if (
294
+ startSeconds === 0n
295
+ || startMicroseconds >= 1_000_000n
296
+ || uniqueId === 0n
297
+ || idVersion === 0
298
+ ) {
299
+ return { status: "unknown" };
300
+ }
301
+ return {
302
+ status: "alive",
303
+ rawStartIdentity:
304
+ `${uniqueId}:${String(idVersion)}:${startSeconds}:${startMicroseconds}`,
305
+ };
306
+ }
307
+
308
+ function darwinProcPidInfo():
309
+ ((processId: number, flavor: number, buffer: Uint8Array) => number) | null {
310
+ if (cachedDarwinProcPidInfo !== undefined) return cachedDarwinProcPidInfo;
311
+ try {
312
+ const library = dlopen("/usr/lib/libproc.dylib", {
313
+ proc_pidinfo: {
314
+ args: ["int", "int", "u64", "ptr", "int"],
315
+ returns: "int",
316
+ },
317
+ } as const);
318
+ cachedDarwinProcPidInfo = (processId, flavor, buffer) =>
319
+ library.symbols.proc_pidinfo(
320
+ processId,
321
+ flavor,
322
+ 0,
323
+ ptr(buffer),
324
+ buffer.byteLength,
325
+ );
326
+ } catch {
327
+ return null;
328
+ }
329
+ return cachedDarwinProcPidInfo;
330
+ }
331
+
332
+ function inspectDarwinProcessWithReader(
333
+ processId: number,
334
+ readRecord: DarwinProcessIdentityRecordReader,
335
+ isDefinitelyMissing: (processId: number) => boolean,
336
+ ): ProcessRecordInspection {
337
+ for (
338
+ let attempt = 0;
339
+ attempt < DARWIN_PROCESS_INSPECTION_ATTEMPTS;
340
+ attempt += 1
341
+ ) {
342
+ try {
343
+ const raw = readRecord(processId);
344
+ if (raw !== null) {
345
+ const record = inspectDarwinProcessIdentity(raw, processId);
346
+ if (record.status !== "unknown") return record;
347
+ }
348
+ } catch {
349
+ // A failed kernel read is uncertain and receives the same bounded retry.
350
+ }
351
+ if (isDefinitelyMissing(processId)) return { status: "dead" };
352
+ }
353
+ return { status: "unknown" };
354
+ }
355
+
356
+ function inspectDarwinProcess(processId: number): ProcessRecordInspection {
357
+ return inspectDarwinProcessWithReader(
358
+ processId,
359
+ (targetProcessId) => {
360
+ const inspect = darwinProcPidInfo();
361
+ if (inspect === null) return null;
362
+ const processInfo = Buffer.alloc(DARWIN_PROC_BSDINFO_WITH_UNIQID_SIZE);
363
+ const bytesRead = inspect(
364
+ targetProcessId,
365
+ DARWIN_PROC_PID_T_BSDINFO_WITH_UNIQID,
366
+ processInfo,
367
+ );
368
+ if (bytesRead !== DARWIN_PROC_BSDINFO_WITH_UNIQID_SIZE) return null;
369
+ return processInfo;
370
+ },
371
+ processIsDefinitelyMissing,
372
+ );
373
+ }
374
+
375
+ function inspectProcess(processId: number): ProcessRecordInspection {
376
+ try {
377
+ if (process.platform === "linux") {
378
+ return inspectLinuxProcessRecord(
379
+ readFileSync(`/proc/${processId}/stat`, "utf8").trim(),
380
+ );
381
+ }
382
+ if (process.platform === "darwin") {
383
+ return inspectDarwinProcess(processId);
384
+ }
385
+ return { status: "unknown" };
386
+ } catch (error) {
387
+ if (
388
+ processIsDefinitelyMissing(processId)
389
+ || (
390
+ process.platform === "linux"
391
+ && typeof error === "object"
392
+ && error !== null
393
+ && "code" in error
394
+ && Reflect.get(error, "code") === "ENOENT"
395
+ )
396
+ ) {
397
+ return { status: "dead" };
398
+ }
399
+ return { status: "unknown" };
400
+ }
401
+ }
402
+
403
+ function identityFor(
404
+ processId: number,
405
+ rawStartIdentity: string,
406
+ ): string {
407
+ return digestIdentity(
408
+ "slopcamera-worker-process-start",
409
+ `${bootIdentity()}\0${String(processId)}\0${rawStartIdentity}`,
410
+ );
411
+ }
412
+
413
+ export function parseWorkerProcessStartIdentity(value: string): string {
414
+ if (!PROCESS_START_IDENTITY_PATTERN.test(value)) {
415
+ throw new Error("Code-worker process start identity is malformed.");
416
+ }
417
+ return value;
418
+ }
419
+
420
+ /** Capture one exact live worker identity; PID alone is never sufficient. */
421
+ export function captureWorkerProcessStartIdentity(
422
+ workerProcessId: number,
423
+ ): string {
424
+ const processId = positiveProcessId(workerProcessId);
425
+ const inspection = inspectProcess(processId);
426
+ if (inspection.status !== "alive") {
427
+ throw new Error("Exact live code-worker process identity is unavailable.");
428
+ }
429
+ return identityFor(processId, inspection.rawStartIdentity);
430
+ }
431
+
432
+ /**
433
+ * Reattest the PID before observing or signaling it. Persistent uncertainty is
434
+ * distinct from death so a guardian retains its inherited lease fail closed.
435
+ */
436
+ export function workerProcessStartIdentityStatus(
437
+ workerProcessId: number,
438
+ expectedIdentity: string,
439
+ ): WorkerProcessStartIdentityStatus {
440
+ let processId: number;
441
+ let identity: string;
442
+ try {
443
+ processId = positiveProcessId(workerProcessId);
444
+ identity = parseWorkerProcessStartIdentity(expectedIdentity);
445
+ } catch {
446
+ return "unknown";
447
+ }
448
+ const inspection = inspectProcess(processId);
449
+ if (inspection.status !== "alive") {
450
+ return inspection.status === "dead" ? "different-or-dead" : "unknown";
451
+ }
452
+ try {
453
+ return identityFor(processId, inspection.rawStartIdentity) === identity
454
+ ? "exact-live-worker"
455
+ : "different-or-dead";
456
+ } catch {
457
+ return "unknown";
458
+ }
459
+ }
460
+
461
+ export function inspectLinuxWorkerProcessRecordForTest(
462
+ raw: string,
463
+ ): ProcessRecordInspection {
464
+ return inspectLinuxProcessRecord(raw);
465
+ }
466
+
467
+ export function inspectDarwinWorkerProcessIdentityForTest(
468
+ raw: Uint8Array,
469
+ expectedProcessId: number,
470
+ ): ProcessRecordInspection {
471
+ return inspectDarwinProcessIdentity(raw, expectedProcessId);
472
+ }
473
+
474
+ export function inspectDarwinWorkerProcessWithReaderForTest(
475
+ processId: number,
476
+ readRecord: DarwinProcessIdentityRecordReader,
477
+ isDefinitelyMissing: (processId: number) => boolean,
478
+ ): ProcessRecordInspection {
479
+ return inspectDarwinProcessWithReader(
480
+ processId,
481
+ readRecord,
482
+ isDefinitelyMissing,
483
+ );
484
+ }