0xray 4.0.13 → 4.0.14

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 (976) hide show
  1. package/.grok-plugin/plugin.json +1 -1
  2. package/.opencode/skills/api-design/SKILL.md +37 -0
  3. package/.opencode/skills/architect-tools/SKILL.md +37 -0
  4. package/.opencode/skills/architecture-patterns/SKILL.md +37 -0
  5. package/.opencode/skills/auto-format/SKILL.md +37 -0
  6. package/.opencode/skills/backend-engineer/SKILL.md +49 -0
  7. package/.opencode/skills/boot-orchestrator/SKILL.md +33 -0
  8. package/.opencode/skills/bug-triage/SKILL.md +43 -0
  9. package/.opencode/skills/code-analyzer/SKILL.md +45 -0
  10. package/.opencode/skills/code-review/SKILL.md +52 -0
  11. package/.opencode/skills/content-creator/SKILL.md +38 -0
  12. package/.opencode/skills/database-engineer/SKILL.md +46 -0
  13. package/.opencode/skills/devops-engineer/SKILL.md +49 -0
  14. package/.opencode/skills/enforcer/SKILL.md +37 -0
  15. package/.opencode/skills/framework-compliance-audit/SKILL.md +37 -0
  16. package/.opencode/skills/frontend-engineer/SKILL.md +49 -0
  17. package/.opencode/skills/frontend-ui-ux-engineer/SKILL.md +41 -0
  18. package/.opencode/skills/git-workflow/SKILL.md +37 -0
  19. package/.opencode/skills/growth-strategist/SKILL.md +48 -0
  20. package/.opencode/skills/hermes-agent/SKILL.md +212 -0
  21. package/.opencode/skills/inference-improve/SKILL.md +97 -0
  22. package/.opencode/skills/lint/SKILL.md +37 -0
  23. package/.opencode/skills/log-monitor/SKILL.md +44 -0
  24. package/.opencode/skills/mobile-developer/SKILL.md +42 -0
  25. package/.opencode/skills/model-health-check/SKILL.md +37 -0
  26. package/.opencode/skills/multimodal-looker/SKILL.md +45 -0
  27. package/.opencode/skills/orchestrator/SKILL.md +61 -0
  28. package/.opencode/skills/performance-analysis/SKILL.md +37 -0
  29. package/.opencode/skills/performance-engineer/SKILL.md +41 -0
  30. package/.opencode/skills/performance-optimization/SKILL.md +37 -0
  31. package/.opencode/skills/processor-pipeline/SKILL.md +37 -0
  32. package/.opencode/skills/project-analysis/SKILL.md +42 -0
  33. package/.opencode/skills/refactoring-strategies/SKILL.md +37 -0
  34. package/.opencode/skills/registry.json +65 -0
  35. package/.opencode/skills/researcher/SKILL.md +50 -0
  36. package/.opencode/skills/security-audit/SKILL.md +48 -0
  37. package/.opencode/skills/security-scan/SKILL.md +37 -0
  38. package/.opencode/skills/seo-consultant/SKILL.md +43 -0
  39. package/.opencode/skills/session-management/SKILL.md +36 -0
  40. package/.opencode/skills/state-manager/SKILL.md +37 -0
  41. package/.opencode/skills/storyteller/SKILL.md +130 -0
  42. package/.opencode/skills/strategist/SKILL.md +44 -0
  43. package/.opencode/skills/tech-writer/SKILL.md +37 -0
  44. package/.opencode/skills/testing-best-practices/SKILL.md +37 -0
  45. package/.opencode/skills/testing-strategy/SKILL.md +54 -0
  46. package/.opencode/skills/ui-ux-design/SKILL.md +603 -0
  47. package/.opencode/skills/xray-orchestrator/SKILL.md +141 -0
  48. package/.opencode/skills/xray-orchestrator/index.ts +267 -0
  49. package/.xray/features.json +1 -1
  50. package/.xray/features.schema.json +1 -1
  51. package/AGENTS-consumer.md +4 -2
  52. package/AGENTS.md +8 -1
  53. package/README.md +1 -1
  54. package/SKILLS.md +1 -1
  55. package/dist/.gitignore.default +67 -0
  56. package/dist/AGENTS.md +232 -0
  57. package/dist/CHANGELOG.md +2788 -0
  58. package/dist/LICENSE +21 -0
  59. package/dist/README.md +233 -0
  60. package/dist/SKILLS.md +166 -0
  61. package/dist/agents/architect.d.ts +2 -0
  62. package/dist/agents/architect.js +56 -0
  63. package/dist/agents/backend-engineer.d.ts +8 -0
  64. package/dist/agents/backend-engineer.js +81 -0
  65. package/dist/agents/bug-triage-specialist.d.ts +2 -0
  66. package/dist/agents/bug-triage-specialist.js +74 -0
  67. package/dist/agents/code-analyzer.d.ts +7 -0
  68. package/dist/agents/code-analyzer.js +150 -0
  69. package/dist/agents/code-reviewer.d.ts +2 -0
  70. package/dist/agents/code-reviewer.js +69 -0
  71. package/dist/agents/content-creator.d.ts +9 -0
  72. package/dist/agents/content-creator.js +72 -0
  73. package/dist/agents/database-engineer.d.ts +8 -0
  74. package/dist/agents/database-engineer.js +76 -0
  75. package/dist/agents/devops-engineer.d.ts +8 -0
  76. package/dist/agents/devops-engineer.js +84 -0
  77. package/dist/agents/frontend-engineer.d.ts +8 -0
  78. package/dist/agents/frontend-engineer.js +78 -0
  79. package/dist/agents/frontend-ui-ux-engineer.d.ts +8 -0
  80. package/dist/agents/frontend-ui-ux-engineer.js +64 -0
  81. package/dist/agents/growth-strategist.d.ts +8 -0
  82. package/dist/agents/growth-strategist.js +111 -0
  83. package/dist/agents/index.d.ts +25 -0
  84. package/dist/agents/index.js +47 -0
  85. package/dist/agents/known-names.d.ts +26 -0
  86. package/dist/agents/known-names.js +72 -0
  87. package/dist/agents/librarian-agents-updater.d.ts +30 -0
  88. package/dist/agents/librarian-agents-updater.js +333 -0
  89. package/dist/agents/log-monitor.d.ts +2 -0
  90. package/dist/agents/log-monitor.js +109 -0
  91. package/dist/agents/mobile-developer.d.ts +9 -0
  92. package/dist/agents/mobile-developer.js +102 -0
  93. package/dist/agents/multimodal-looker.d.ts +9 -0
  94. package/dist/agents/multimodal-looker.js +93 -0
  95. package/dist/agents/performance-engineer.d.ts +8 -0
  96. package/dist/agents/performance-engineer.js +86 -0
  97. package/dist/agents/refactorer.d.ts +2 -0
  98. package/dist/agents/refactorer.js +80 -0
  99. package/dist/agents/registry.d.ts +37 -0
  100. package/dist/agents/registry.js +354 -0
  101. package/dist/agents/researcher.d.ts +2 -0
  102. package/dist/agents/researcher.js +83 -0
  103. package/dist/agents/security-auditor.d.ts +2 -0
  104. package/dist/agents/security-auditor.js +158 -0
  105. package/dist/agents/seo-consultant.d.ts +8 -0
  106. package/dist/agents/seo-consultant.js +53 -0
  107. package/dist/agents/strategist.d.ts +7 -0
  108. package/dist/agents/strategist.js +47 -0
  109. package/dist/agents/tech-writer.d.ts +8 -0
  110. package/dist/agents/tech-writer.js +84 -0
  111. package/dist/agents/testing-lead.d.ts +2 -0
  112. package/dist/agents/testing-lead.js +95 -0
  113. package/dist/agents/types.d.ts +45 -0
  114. package/dist/agents/types.js +1 -0
  115. package/dist/analytics/consent-manager.d.ts +92 -0
  116. package/dist/analytics/consent-manager.js +257 -0
  117. package/dist/analytics/emerging-pattern-detector.d.ts +66 -0
  118. package/dist/analytics/emerging-pattern-detector.js +259 -0
  119. package/dist/analytics/pattern-learning-engine.d.ts +79 -0
  120. package/dist/analytics/pattern-learning-engine.js +277 -0
  121. package/dist/analytics/pattern-performance-tracker.d.ts +96 -0
  122. package/dist/analytics/pattern-performance-tracker.js +335 -0
  123. package/dist/analytics/predictive-analytics.d.ts +40 -0
  124. package/dist/analytics/predictive-analytics.js +247 -0
  125. package/dist/analytics/prompt-pattern-analyzer.d.ts +98 -0
  126. package/dist/analytics/prompt-pattern-analyzer.js +370 -0
  127. package/dist/analytics/routing-performance-analyzer.d.ts +100 -0
  128. package/dist/analytics/routing-performance-analyzer.js +355 -0
  129. package/dist/analytics/routing-refiner.d.ts +102 -0
  130. package/dist/analytics/routing-refiner.js +377 -0
  131. package/dist/analytics/simple-pattern-analyzer.d.ts +79 -0
  132. package/dist/analytics/simple-pattern-analyzer.js +296 -0
  133. package/dist/architect/architect-tools.d.ts +70 -0
  134. package/dist/architect/architect-tools.js +437 -0
  135. package/dist/architect/architectural-integrity.d.ts +20 -0
  136. package/dist/architect/architectural-integrity.js +78 -0
  137. package/dist/benchmark/performance-benchmark.d.ts +103 -0
  138. package/dist/benchmark/performance-benchmark.js +373 -0
  139. package/dist/cli/commands/analytics-disable.d.ts +9 -0
  140. package/dist/cli/commands/analytics-disable.js +72 -0
  141. package/dist/cli/commands/analytics-enable-action.d.ts +8 -0
  142. package/dist/cli/commands/analytics-enable-action.js +82 -0
  143. package/dist/cli/commands/analytics-preview.d.ts +9 -0
  144. package/dist/cli/commands/analytics-preview.js +106 -0
  145. package/dist/cli/commands/analytics-status.d.ts +9 -0
  146. package/dist/cli/commands/analytics-status.js +68 -0
  147. package/dist/cli/commands/antigravity-status.d.ts +9 -0
  148. package/dist/cli/commands/antigravity-status.js +106 -0
  149. package/dist/cli/commands/archive-logs.d.ts +23 -0
  150. package/dist/cli/commands/archive-logs.js +160 -0
  151. package/dist/cli/commands/credible-init.d.ts +11 -0
  152. package/dist/cli/commands/credible-init.js +82 -0
  153. package/dist/cli/commands/enforce.d.ts +12 -0
  154. package/dist/cli/commands/enforce.js +78 -0
  155. package/dist/cli/commands/foundry-mint-wear.d.ts +3 -0
  156. package/dist/cli/commands/foundry-mint-wear.js +17 -0
  157. package/dist/cli/commands/govern.d.ts +29 -0
  158. package/dist/cli/commands/govern.js +149 -0
  159. package/dist/cli/commands/grok-install.d.ts +7 -0
  160. package/dist/cli/commands/grok-install.js +16 -0
  161. package/dist/cli/commands/hermes-install.d.ts +2 -0
  162. package/dist/cli/commands/hermes-install.js +90 -0
  163. package/dist/cli/commands/mcp-install.d.ts +4 -0
  164. package/dist/cli/commands/mcp-install.js +253 -0
  165. package/dist/cli/commands/openclaw-install.d.ts +2 -0
  166. package/dist/cli/commands/openclaw-install.js +80 -0
  167. package/dist/cli/commands/opencode-install.d.ts +2 -0
  168. package/dist/cli/commands/opencode-install.js +153 -0
  169. package/dist/cli/commands/plugin-commands.d.ts +18 -0
  170. package/dist/cli/commands/plugin-commands.js +245 -0
  171. package/dist/cli/commands/publish-agent.d.ts +15 -0
  172. package/dist/cli/commands/publish-agent.js +184 -0
  173. package/dist/cli/commands/security-audit.d.ts +23 -0
  174. package/dist/cli/commands/security-audit.js +219 -0
  175. package/dist/cli/commands/skill-install.d.ts +6 -0
  176. package/dist/cli/commands/skill-install.js +522 -0
  177. package/dist/cli/commands/status.d.ts +41 -0
  178. package/dist/cli/commands/status.js +199 -0
  179. package/dist/cli/commands/storyteller.d.ts +19 -0
  180. package/dist/cli/commands/storyteller.js +230 -0
  181. package/dist/cli/index.d.ts +7 -0
  182. package/dist/cli/index.js +996 -0
  183. package/dist/cli/server.d.ts +1 -0
  184. package/dist/cli/server.js +147 -0
  185. package/dist/config/default-agents.d.ts +12 -0
  186. package/dist/config/default-agents.js +16 -0
  187. package/dist/config/routing-mappings.d.ts +26 -0
  188. package/dist/config/routing-mappings.js +151 -0
  189. package/dist/core/activity-logger.d.ts +71 -0
  190. package/dist/core/activity-logger.js +259 -0
  191. package/dist/core/adaptive-kernel.d.ts +108 -0
  192. package/dist/core/adaptive-kernel.js +191 -0
  193. package/dist/core/agent-spawn-gate.d.ts +56 -0
  194. package/dist/core/agent-spawn-gate.js +120 -0
  195. package/dist/core/boot-orchestrator.d.ts +99 -0
  196. package/dist/core/boot-orchestrator.js +809 -0
  197. package/dist/core/bridge.mjs +922 -0
  198. package/dist/core/codex-formatter.d.ts +95 -0
  199. package/dist/core/codex-formatter.js +218 -0
  200. package/dist/core/codex-injector.d.ts +73 -0
  201. package/dist/core/codex-injector.js +423 -0
  202. package/dist/core/config-loader.d.ts +59 -0
  203. package/dist/core/config-loader.js +157 -0
  204. package/dist/core/config-paths.d.ts +66 -0
  205. package/dist/core/config-paths.js +169 -0
  206. package/dist/core/context-loader.d.ts +120 -0
  207. package/dist/core/context-loader.js +268 -0
  208. package/dist/core/context-validator.d.ts +52 -0
  209. package/dist/core/context-validator.js +211 -0
  210. package/dist/core/features-config.d.ts +531 -0
  211. package/dist/core/features-config.js +524 -0
  212. package/dist/core/framework-logger.d.ts +76 -0
  213. package/dist/core/framework-logger.js +275 -0
  214. package/dist/core/index.d.ts +5 -0
  215. package/dist/core/index.js +6 -0
  216. package/dist/core/kernel-patterns.d.ts +129 -0
  217. package/dist/core/kernel-patterns.js +301 -0
  218. package/dist/core/logging-config.d.ts +10 -0
  219. package/dist/core/logging-config.js +43 -0
  220. package/dist/core/model-router.d.ts +56 -0
  221. package/dist/core/model-router.js +134 -0
  222. package/dist/core/orchestrator.d.ts +71 -0
  223. package/dist/core/orchestrator.js +408 -0
  224. package/dist/core/system-prompt-generator.d.ts +34 -0
  225. package/dist/core/system-prompt-generator.js +264 -0
  226. package/dist/core/trace-context.d.ts +12 -0
  227. package/dist/core/trace-context.js +33 -0
  228. package/dist/core/xray-activation.d.ts +14 -0
  229. package/dist/core/xray-activation.js +135 -0
  230. package/dist/delegation/agent-delegator.d.ts +185 -0
  231. package/dist/delegation/agent-delegator.js +768 -0
  232. package/dist/delegation/agent-expertise.d.ts +15 -0
  233. package/dist/delegation/agent-expertise.js +155 -0
  234. package/dist/delegation/analytics/index.d.ts +11 -0
  235. package/dist/delegation/analytics/index.js +11 -0
  236. package/dist/delegation/analytics/learning-engine.d.ts +84 -0
  237. package/dist/delegation/analytics/learning-engine.js +276 -0
  238. package/dist/delegation/analytics/outcome-tracker.d.ts +117 -0
  239. package/dist/delegation/analytics/outcome-tracker.js +278 -0
  240. package/dist/delegation/analytics/routing-analytics.d.ts +60 -0
  241. package/dist/delegation/analytics/routing-analytics.js +192 -0
  242. package/dist/delegation/ast-code-parser.d.ts +173 -0
  243. package/dist/delegation/ast-code-parser.js +877 -0
  244. package/dist/delegation/codebase-context-analyzer.d.ts +164 -0
  245. package/dist/delegation/codebase-context-analyzer.js +1040 -0
  246. package/dist/delegation/complexity-analyzer.d.ts +110 -0
  247. package/dist/delegation/complexity-analyzer.js +281 -0
  248. package/dist/delegation/complexity-core.d.ts +119 -0
  249. package/dist/delegation/complexity-core.js +219 -0
  250. package/dist/delegation/config/types.d.ts +247 -0
  251. package/dist/delegation/config/types.js +6 -0
  252. package/dist/delegation/dependency-graph-builder.d.ts +94 -0
  253. package/dist/delegation/dependency-graph-builder.js +408 -0
  254. package/dist/delegation/index.d.ts +25 -0
  255. package/dist/delegation/index.js +20 -0
  256. package/dist/delegation/metrics-aggregator.d.ts +91 -0
  257. package/dist/delegation/metrics-aggregator.js +334 -0
  258. package/dist/delegation/session-coordinator.d.ts +132 -0
  259. package/dist/delegation/session-coordinator.js +351 -0
  260. package/dist/delegation/strategy-selector.d.ts +27 -0
  261. package/dist/delegation/strategy-selector.js +107 -0
  262. package/dist/delegation/voting-coordinator.d.ts +48 -0
  263. package/dist/delegation/voting-coordinator.js +374 -0
  264. package/dist/delegation/voting-types.d.ts +154 -0
  265. package/dist/delegation/voting-types.js +9 -0
  266. package/dist/delegation/weighted-voting-aggregator.d.ts +36 -0
  267. package/dist/delegation/weighted-voting-aggregator.js +193 -0
  268. package/dist/enforcement/core/index.d.ts +14 -0
  269. package/dist/enforcement/core/index.js +18 -0
  270. package/dist/enforcement/core/rule-executor.d.ts +157 -0
  271. package/dist/enforcement/core/rule-executor.js +364 -0
  272. package/dist/enforcement/core/rule-hierarchy.d.ts +145 -0
  273. package/dist/enforcement/core/rule-hierarchy.js +258 -0
  274. package/dist/enforcement/core/rule-registry.d.ts +196 -0
  275. package/dist/enforcement/core/rule-registry.js +239 -0
  276. package/dist/enforcement/core/violation-fixer.d.ts +105 -0
  277. package/dist/enforcement/core/violation-fixer.js +650 -0
  278. package/dist/enforcement/enforcer-tools.d.ts +85 -0
  279. package/dist/enforcement/enforcer-tools.js +818 -0
  280. package/dist/enforcement/index.d.ts +22 -0
  281. package/dist/enforcement/index.js +40 -0
  282. package/dist/enforcement/loaders/agent-triage-loader.d.ts +98 -0
  283. package/dist/enforcement/loaders/agent-triage-loader.js +221 -0
  284. package/dist/enforcement/loaders/agents-md-validation-loader.d.ts +75 -0
  285. package/dist/enforcement/loaders/agents-md-validation-loader.js +251 -0
  286. package/dist/enforcement/loaders/base-loader.d.ts +82 -0
  287. package/dist/enforcement/loaders/base-loader.js +85 -0
  288. package/dist/enforcement/loaders/codex-loader.d.ts +76 -0
  289. package/dist/enforcement/loaders/codex-loader.js +395 -0
  290. package/dist/enforcement/loaders/index.d.ts +36 -0
  291. package/dist/enforcement/loaders/index.js +39 -0
  292. package/dist/enforcement/loaders/loader-orchestrator.d.ts +96 -0
  293. package/dist/enforcement/loaders/loader-orchestrator.js +167 -0
  294. package/dist/enforcement/loaders/processor-loader.d.ts +59 -0
  295. package/dist/enforcement/loaders/processor-loader.js +112 -0
  296. package/dist/enforcement/rule-enforcer.d.ts +142 -0
  297. package/dist/enforcement/rule-enforcer.js +298 -0
  298. package/dist/enforcement/test-auto-healing.d.ts +83 -0
  299. package/dist/enforcement/test-auto-healing.js +325 -0
  300. package/dist/enforcement/types.d.ts +500 -0
  301. package/dist/enforcement/types.js +29 -0
  302. package/dist/enforcement/validators/architecture-validators.d.ts +154 -0
  303. package/dist/enforcement/validators/architecture-validators.js +599 -0
  304. package/dist/enforcement/validators/base-validator.d.ts +87 -0
  305. package/dist/enforcement/validators/base-validator.js +107 -0
  306. package/dist/enforcement/validators/code-quality-validators.d.ts +88 -0
  307. package/dist/enforcement/validators/code-quality-validators.js +335 -0
  308. package/dist/enforcement/validators/index.d.ts +14 -0
  309. package/dist/enforcement/validators/index.js +20 -0
  310. package/dist/enforcement/validators/security-validators.d.ts +52 -0
  311. package/dist/enforcement/validators/security-validators.js +219 -0
  312. package/dist/enforcement/validators/testing-validators.d.ts +80 -0
  313. package/dist/enforcement/validators/testing-validators.js +252 -0
  314. package/dist/enforcement/validators/validator-registry.d.ts +91 -0
  315. package/dist/enforcement/validators/validator-registry.js +149 -0
  316. package/dist/execution/opencode-cli-invoker.d.ts +8 -0
  317. package/dist/execution/opencode-cli-invoker.js +173 -0
  318. package/dist/execution/proposal-applier.d.ts +24 -0
  319. package/dist/execution/proposal-applier.js +254 -0
  320. package/dist/governance/codex-policy.service.d.ts +56 -0
  321. package/dist/governance/codex-policy.service.js +166 -0
  322. package/dist/governance/governance-core.d.ts +53 -0
  323. package/dist/governance/governance-core.js +168 -0
  324. package/dist/governance/governance-service.d.ts +39 -0
  325. package/dist/governance/governance-service.js +351 -0
  326. package/dist/governance/governance-types.d.ts +90 -0
  327. package/dist/governance/governance-types.js +11 -0
  328. package/dist/governance/llm-governance-provider.d.ts +16 -0
  329. package/dist/governance/llm-governance-provider.js +284 -0
  330. package/dist/governance/local-confer.d.ts +10 -0
  331. package/dist/governance/local-confer.js +27 -0
  332. package/dist/index.d.ts +28 -0
  333. package/dist/index.js +24 -0
  334. package/dist/inference/deploy-verifier.d.ts +26 -0
  335. package/dist/inference/deploy-verifier.js +161 -0
  336. package/dist/inference/index.d.ts +10 -0
  337. package/dist/inference/index.js +5 -0
  338. package/dist/inference/inference-accumulator.d.ts +29 -0
  339. package/dist/inference/inference-accumulator.js +126 -0
  340. package/dist/inference/inference-agent-invoker.d.ts +3 -0
  341. package/dist/inference/inference-agent-invoker.js +67 -0
  342. package/dist/inference/inference-applier.d.ts +4 -0
  343. package/dist/inference/inference-applier.js +178 -0
  344. package/dist/inference/inference-cycle.d.ts +70 -0
  345. package/dist/inference/inference-cycle.js +392 -0
  346. package/dist/inference/inference-proposal-generator.d.ts +3 -0
  347. package/dist/inference/inference-proposal-generator.js +149 -0
  348. package/dist/inference/semantic-patterns.d.ts +7 -0
  349. package/dist/inference/semantic-patterns.js +310 -0
  350. package/dist/inference/session-capture.d.ts +32 -0
  351. package/dist/inference/session-capture.js +308 -0
  352. package/dist/infrastructure/iac-validator.d.ts +150 -0
  353. package/dist/infrastructure/iac-validator.js +465 -0
  354. package/dist/infrastructure/schemas/cloud-schemas.d.ts +482 -0
  355. package/dist/infrastructure/schemas/cloud-schemas.js +488 -0
  356. package/dist/integrations/base/ExampleIntegration.d.ts +46 -0
  357. package/dist/integrations/base/ExampleIntegration.js +180 -0
  358. package/dist/integrations/base/Integration.d.ts +266 -0
  359. package/dist/integrations/base/Integration.js +394 -0
  360. package/dist/integrations/base/README.md +446 -0
  361. package/dist/integrations/base/index.d.ts +11 -0
  362. package/dist/integrations/base/index.js +15 -0
  363. package/dist/integrations/base/registry.d.ts +272 -0
  364. package/dist/integrations/base/registry.js +605 -0
  365. package/dist/integrations/base/types.d.ts +167 -0
  366. package/dist/integrations/base/types.js +117 -0
  367. package/dist/integrations/cursor/README.md +61 -0
  368. package/dist/integrations/cursor/hooks/after-file-edit.js +38 -0
  369. package/dist/integrations/cursor/hooks/cursor-hook-utils.js +170 -0
  370. package/dist/integrations/cursor/hooks/cursor-usage-receipt.js +298 -0
  371. package/dist/integrations/cursor/hooks/hooks.json +20 -0
  372. package/dist/integrations/cursor/hooks/pre-compact.js +88 -0
  373. package/dist/integrations/cursor/hooks/pre-tool-use.js +105 -0
  374. package/dist/integrations/enforcement-gate.d.ts +44 -0
  375. package/dist/integrations/enforcement-gate.js +348 -0
  376. package/dist/integrations/governance/governance-client.d.ts +75 -0
  377. package/dist/integrations/governance/governance-client.js +315 -0
  378. package/dist/integrations/governance/index.d.ts +98 -0
  379. package/dist/integrations/governance/index.js +365 -0
  380. package/dist/integrations/governance/types.d.ts +238 -0
  381. package/dist/integrations/governance/types.js +96 -0
  382. package/dist/integrations/grok/grok-cli.d.ts +31 -0
  383. package/dist/integrations/grok/grok-cli.js +222 -0
  384. package/dist/integrations/grok/hooks/grok-hook-activity.js +53 -0
  385. package/dist/integrations/grok/hooks/grok-hook-utils.js +372 -0
  386. package/dist/integrations/grok/hooks/post-tool-use.js +118 -0
  387. package/dist/integrations/grok/hooks/pre-tool-use.js +136 -0
  388. package/dist/integrations/grok/hooks/session-start.js +189 -0
  389. package/dist/integrations/grok/plugin/0xray/.mcp.json +35 -0
  390. package/dist/integrations/grok/plugin/0xray/hooks/hooks.json +70 -0
  391. package/dist/integrations/hermes-agent/.mcp.json +32 -0
  392. package/dist/integrations/hermes-agent/__init__.py +790 -0
  393. package/dist/integrations/hermes-agent/__pycache__/__init__.cpython-313.pyc +0 -0
  394. package/dist/integrations/hermes-agent/__pycache__/schemas.cpython-313.pyc +0 -0
  395. package/dist/integrations/hermes-agent/__pycache__/tools.cpython-313.pyc +0 -0
  396. package/dist/integrations/hermes-agent/after-install.md +71 -0
  397. package/dist/integrations/hermes-agent/bridge.mjs +1060 -0
  398. package/dist/integrations/hermes-agent/conftest.py +14 -0
  399. package/dist/integrations/hermes-agent/logs/framework/routing-outcomes.json +1 -0
  400. package/dist/integrations/hermes-agent/plugin.yaml +12 -0
  401. package/dist/integrations/hermes-agent/schemas.py +149 -0
  402. package/dist/integrations/hermes-agent/test_plugin.py +1100 -0
  403. package/dist/integrations/hermes-agent/tools.py +357 -0
  404. package/dist/integrations/hooks/confer-hook-runtime.mjs +49 -0
  405. package/dist/integrations/hooks/delegation-gate-runtime.mjs +110 -0
  406. package/dist/integrations/hooks/pipeline-hook-runtime.mjs +211 -0
  407. package/dist/integrations/hooks/plan-hook-runtime.mjs +68 -0
  408. package/dist/integrations/hooks/station-hook-runtime.cjs +509 -0
  409. package/dist/integrations/hooks/station-hook-runtime.mjs +26 -0
  410. package/dist/integrations/hooks/station-memory-ingest.mjs +45 -0
  411. package/dist/integrations/hooks/station-memory-match.mjs +47 -0
  412. package/dist/integrations/hooks/synthesis-hook-runtime.mjs +50 -0
  413. package/dist/integrations/hooks/user-aside-hook-runtime.mjs +49 -0
  414. package/dist/integrations/openclaw/README.md +134 -0
  415. package/dist/integrations/openclaw/api-server.d.ts +86 -0
  416. package/dist/integrations/openclaw/api-server.js +388 -0
  417. package/dist/integrations/openclaw/client.d.ts +125 -0
  418. package/dist/integrations/openclaw/client.js +499 -0
  419. package/dist/integrations/openclaw/config.d.ts +95 -0
  420. package/dist/integrations/openclaw/config.js +372 -0
  421. package/dist/integrations/openclaw/hooks/pre-tool-gate-runtime.mjs +102 -0
  422. package/dist/integrations/openclaw/hooks/xray-hooks.d.ts +123 -0
  423. package/dist/integrations/openclaw/hooks/xray-hooks.js +279 -0
  424. package/dist/integrations/openclaw/index.d.ts +100 -0
  425. package/dist/integrations/openclaw/index.js +367 -0
  426. package/dist/integrations/openclaw/plugin/xray-pre-tool/index.js +75 -0
  427. package/dist/integrations/openclaw/plugin/xray-pre-tool/openclaw.plugin.json +10 -0
  428. package/dist/integrations/openclaw/plugin/xray-pre-tool/package.json +12 -0
  429. package/dist/integrations/openclaw/pre-tool-gate.d.ts +19 -0
  430. package/dist/integrations/openclaw/pre-tool-gate.js +39 -0
  431. package/dist/integrations/openclaw/types.d.ts +425 -0
  432. package/dist/integrations/openclaw/types.js +152 -0
  433. package/dist/integrations/plugins/index.d.ts +9 -0
  434. package/dist/integrations/plugins/index.js +9 -0
  435. package/dist/integrations/plugins/plugin-integration.d.ts +288 -0
  436. package/dist/integrations/plugins/plugin-integration.js +605 -0
  437. package/dist/integrations/plugins/plugin-registry.d.ts +223 -0
  438. package/dist/integrations/plugins/plugin-registry.js +579 -0
  439. package/dist/mcps/agent-resolver.d.ts +45 -0
  440. package/dist/mcps/agent-resolver.js +105 -0
  441. package/dist/mcps/architect-tools.server.d.ts +16 -0
  442. package/dist/mcps/architect-tools.server.js +217 -0
  443. package/dist/mcps/auto-format.server.d.ts +18 -0
  444. package/dist/mcps/auto-format.server.js +395 -0
  445. package/dist/mcps/boot-orchestrator.server.d.ts +48 -0
  446. package/dist/mcps/boot-orchestrator.server.js +835 -0
  447. package/dist/mcps/config/config-loader.d.ts +56 -0
  448. package/dist/mcps/config/config-loader.js +140 -0
  449. package/dist/mcps/config/config-validator.d.ts +40 -0
  450. package/dist/mcps/config/config-validator.js +101 -0
  451. package/dist/mcps/config/index.d.ts +31 -0
  452. package/dist/mcps/config/index.js +30 -0
  453. package/dist/mcps/config/plugin-server-registry.d.ts +126 -0
  454. package/dist/mcps/config/plugin-server-registry.js +222 -0
  455. package/dist/mcps/config/server-config-registry.d.ts +51 -0
  456. package/dist/mcps/config/server-config-registry.js +349 -0
  457. package/dist/mcps/connection/connection-manager.d.ts +39 -0
  458. package/dist/mcps/connection/connection-manager.js +79 -0
  459. package/dist/mcps/connection/connection-pool.d.ts +64 -0
  460. package/dist/mcps/connection/connection-pool.js +164 -0
  461. package/dist/mcps/connection/mcp-connection.d.ts +66 -0
  462. package/dist/mcps/connection/mcp-connection.js +233 -0
  463. package/dist/mcps/connection/process-spawner.d.ts +24 -0
  464. package/dist/mcps/connection/process-spawner.js +34 -0
  465. package/dist/mcps/enforcer-tools.server.d.ts +26 -0
  466. package/dist/mcps/enforcer-tools.server.js +712 -0
  467. package/dist/mcps/estimation.server.d.ts +19 -0
  468. package/dist/mcps/estimation.server.js +149 -0
  469. package/dist/mcps/framework-compliance-audit.server.d.ts +20 -0
  470. package/dist/mcps/framework-compliance-audit.server.js +471 -0
  471. package/dist/mcps/framework-help.server.d.ts +13 -0
  472. package/dist/mcps/framework-help.server.js +383 -0
  473. package/dist/mcps/governance.server.d.ts +36 -0
  474. package/dist/mcps/governance.server.js +499 -0
  475. package/dist/mcps/in-process-skill-registry.d.ts +20 -0
  476. package/dist/mcps/in-process-skill-registry.js +48 -0
  477. package/dist/mcps/index.d.ts +17 -0
  478. package/dist/mcps/index.js +65 -0
  479. package/dist/mcps/knowledge-skills/api-design.server.d.ts +13 -0
  480. package/dist/mcps/knowledge-skills/api-design.server.js +92 -0
  481. package/dist/mcps/knowledge-skills/architecture-patterns.server.d.ts +13 -0
  482. package/dist/mcps/knowledge-skills/architecture-patterns.server.js +82 -0
  483. package/dist/mcps/knowledge-skills/bug-triage-specialist.server.d.ts +31 -0
  484. package/dist/mcps/knowledge-skills/bug-triage-specialist.server.js +434 -0
  485. package/dist/mcps/knowledge-skills/code-analyzer.server.d.ts +29 -0
  486. package/dist/mcps/knowledge-skills/code-analyzer.server.js +578 -0
  487. package/dist/mcps/knowledge-skills/code-review.server.d.ts +44 -0
  488. package/dist/mcps/knowledge-skills/code-review.server.js +783 -0
  489. package/dist/mcps/knowledge-skills/content-creator.server.d.ts +11 -0
  490. package/dist/mcps/knowledge-skills/content-creator.server.js +234 -0
  491. package/dist/mcps/knowledge-skills/database-design.server.d.ts +41 -0
  492. package/dist/mcps/knowledge-skills/database-design.server.js +788 -0
  493. package/dist/mcps/knowledge-skills/devops-deployment.server.d.ts +41 -0
  494. package/dist/mcps/knowledge-skills/devops-deployment.server.js +1147 -0
  495. package/dist/mcps/knowledge-skills/git-workflow.server.d.ts +13 -0
  496. package/dist/mcps/knowledge-skills/git-workflow.server.js +83 -0
  497. package/dist/mcps/knowledge-skills/growth-strategist.server.d.ts +11 -0
  498. package/dist/mcps/knowledge-skills/growth-strategist.server.js +339 -0
  499. package/dist/mcps/knowledge-skills/log-monitor.server.d.ts +22 -0
  500. package/dist/mcps/knowledge-skills/log-monitor.server.js +431 -0
  501. package/dist/mcps/knowledge-skills/mobile-development.server.d.ts +17 -0
  502. package/dist/mcps/knowledge-skills/mobile-development.server.js +495 -0
  503. package/dist/mcps/knowledge-skills/multimodal-looker.server.d.ts +53 -0
  504. package/dist/mcps/knowledge-skills/multimodal-looker.server.js +1028 -0
  505. package/dist/mcps/knowledge-skills/performance-optimization.server.d.ts +69 -0
  506. package/dist/mcps/knowledge-skills/performance-optimization.server.js +1537 -0
  507. package/dist/mcps/knowledge-skills/project-analysis.server.d.ts +35 -0
  508. package/dist/mcps/knowledge-skills/project-analysis.server.js +724 -0
  509. package/dist/mcps/knowledge-skills/refactoring-strategies.server.d.ts +31 -0
  510. package/dist/mcps/knowledge-skills/refactoring-strategies.server.js +762 -0
  511. package/dist/mcps/knowledge-skills/security-audit.server.d.ts +46 -0
  512. package/dist/mcps/knowledge-skills/security-audit.server.js +684 -0
  513. package/dist/mcps/knowledge-skills/seo-consultant.server.d.ts +24 -0
  514. package/dist/mcps/knowledge-skills/seo-consultant.server.js +745 -0
  515. package/dist/mcps/knowledge-skills/session-management.server.d.ts +22 -0
  516. package/dist/mcps/knowledge-skills/session-management.server.js +394 -0
  517. package/dist/mcps/knowledge-skills/skill-invocation.server.d.ts +32 -0
  518. package/dist/mcps/knowledge-skills/skill-invocation.server.js +454 -0
  519. package/dist/mcps/knowledge-skills/storyteller.server.d.ts +11 -0
  520. package/dist/mcps/knowledge-skills/storyteller.server.js +167 -0
  521. package/dist/mcps/knowledge-skills/strategist.server.d.ts +15 -0
  522. package/dist/mcps/knowledge-skills/strategist.server.js +172 -0
  523. package/dist/mcps/knowledge-skills/tech-writer.server.d.ts +45 -0
  524. package/dist/mcps/knowledge-skills/tech-writer.server.js +1016 -0
  525. package/dist/mcps/knowledge-skills/testing-best-practices.server.d.ts +34 -0
  526. package/dist/mcps/knowledge-skills/testing-best-practices.server.js +694 -0
  527. package/dist/mcps/knowledge-skills/testing-strategy.server.d.ts +45 -0
  528. package/dist/mcps/knowledge-skills/testing-strategy.server.js +689 -0
  529. package/dist/mcps/knowledge-skills/ui-ux-design.server.d.ts +67 -0
  530. package/dist/mcps/knowledge-skills/ui-ux-design.server.js +1265 -0
  531. package/dist/mcps/lint.server.d.ts +15 -0
  532. package/dist/mcps/lint.server.js +340 -0
  533. package/dist/mcps/mcp-client.d.ts +157 -0
  534. package/dist/mcps/mcp-client.js +574 -0
  535. package/dist/mcps/model-health-check.server.d.ts +14 -0
  536. package/dist/mcps/model-health-check.server.js +201 -0
  537. package/dist/mcps/orchestrator/aside-context.d.ts +21 -0
  538. package/dist/mcps/orchestrator/aside-context.js +207 -0
  539. package/dist/mcps/orchestrator/config/agent-capabilities.d.ts +39 -0
  540. package/dist/mcps/orchestrator/config/agent-capabilities.js +128 -0
  541. package/dist/mcps/orchestrator/config/memory-routing-bridge.d.ts +12 -0
  542. package/dist/mcps/orchestrator/config/memory-routing-bridge.js +71 -0
  543. package/dist/mcps/orchestrator/execution/execution-planner.d.ts +64 -0
  544. package/dist/mcps/orchestrator/execution/execution-planner.js +320 -0
  545. package/dist/mcps/orchestrator/handlers/complexity-handler.d.ts +55 -0
  546. package/dist/mcps/orchestrator/handlers/complexity-handler.js +285 -0
  547. package/dist/mcps/orchestrator/handlers/status-handler.d.ts +71 -0
  548. package/dist/mcps/orchestrator/handlers/status-handler.js +239 -0
  549. package/dist/mcps/orchestrator/handlers/task-handler.d.ts +59 -0
  550. package/dist/mcps/orchestrator/handlers/task-handler.js +354 -0
  551. package/dist/mcps/orchestrator/index.d.ts +6 -0
  552. package/dist/mcps/orchestrator/index.js +5 -0
  553. package/dist/mcps/orchestrator/server.d.ts +38 -0
  554. package/dist/mcps/orchestrator/server.js +538 -0
  555. package/dist/mcps/orchestrator/types.d.ts +131 -0
  556. package/dist/mcps/orchestrator/types.js +6 -0
  557. package/dist/mcps/orchestrator.server.d.ts +10 -0
  558. package/dist/mcps/orchestrator.server.js +20 -0
  559. package/dist/mcps/performance-analysis.server.d.ts +25 -0
  560. package/dist/mcps/performance-analysis.server.js +488 -0
  561. package/dist/mcps/processor-pipeline.server.d.ts +29 -0
  562. package/dist/mcps/processor-pipeline.server.js +531 -0
  563. package/dist/mcps/protocol/protocol-constants.d.ts +46 -0
  564. package/dist/mcps/protocol/protocol-constants.js +46 -0
  565. package/dist/mcps/registry.json +109 -0
  566. package/dist/mcps/researcher-confidence.d.ts +21 -0
  567. package/dist/mcps/researcher-confidence.js +92 -0
  568. package/dist/mcps/researcher.server.d.ts +29 -0
  569. package/dist/mcps/researcher.server.js +419 -0
  570. package/dist/mcps/security-scan.server.d.ts +19 -0
  571. package/dist/mcps/security-scan.server.js +517 -0
  572. package/dist/mcps/shared/knowledge-skill-base.d.ts +17 -0
  573. package/dist/mcps/shared/knowledge-skill-base.js +52 -0
  574. package/dist/mcps/shared/prompt-security-validator.d.ts +44 -0
  575. package/dist/mcps/shared/prompt-security-validator.js +148 -0
  576. package/dist/mcps/shared/security-scanner.d.ts +119 -0
  577. package/dist/mcps/shared/security-scanner.js +429 -0
  578. package/dist/mcps/simulation/index.d.ts +12 -0
  579. package/dist/mcps/simulation/index.js +12 -0
  580. package/dist/mcps/simulation/server-simulations.d.ts +39 -0
  581. package/dist/mcps/simulation/server-simulations.js +219 -0
  582. package/dist/mcps/simulation/simulation-engine.d.ts +51 -0
  583. package/dist/mcps/simulation/simulation-engine.js +96 -0
  584. package/dist/mcps/state-manager.server.d.ts +27 -0
  585. package/dist/mcps/state-manager.server.js +609 -0
  586. package/dist/mcps/tools/index.d.ts +14 -0
  587. package/dist/mcps/tools/index.js +14 -0
  588. package/dist/mcps/tools/tool-cache.d.ts +53 -0
  589. package/dist/mcps/tools/tool-cache.js +112 -0
  590. package/dist/mcps/tools/tool-discovery.d.ts +27 -0
  591. package/dist/mcps/tools/tool-discovery.js +65 -0
  592. package/dist/mcps/tools/tool-executor.d.ts +41 -0
  593. package/dist/mcps/tools/tool-executor.js +75 -0
  594. package/dist/mcps/tools/tool-registry.d.ts +42 -0
  595. package/dist/mcps/tools/tool-registry.js +67 -0
  596. package/dist/mcps/types/index.d.ts +13 -0
  597. package/dist/mcps/types/index.js +15 -0
  598. package/dist/mcps/types/json-rpc.types.d.ts +35 -0
  599. package/dist/mcps/types/json-rpc.types.js +7 -0
  600. package/dist/mcps/types/mcp.types.d.ts +105 -0
  601. package/dist/mcps/types/mcp.types.js +7 -0
  602. package/dist/memory-routing/index.d.ts +6 -0
  603. package/dist/memory-routing/index.js +4 -0
  604. package/dist/memory-routing/null-provider.d.ts +14 -0
  605. package/dist/memory-routing/null-provider.js +63 -0
  606. package/dist/memory-routing/provider-loader.d.ts +6 -0
  607. package/dist/memory-routing/provider-loader.js +165 -0
  608. package/dist/memory-routing/provider-registry.d.ts +8 -0
  609. package/dist/memory-routing/provider-registry.js +41 -0
  610. package/dist/memory-routing/types.d.ts +111 -0
  611. package/dist/memory-routing/types.js +7 -0
  612. package/dist/memory-routing/validate-config.d.ts +7 -0
  613. package/dist/memory-routing/validate-config.js +32 -0
  614. package/dist/metrics/agent-metrics.d.ts +169 -0
  615. package/dist/metrics/agent-metrics.js +574 -0
  616. package/dist/metrics/index.d.ts +6 -0
  617. package/dist/metrics/index.js +6 -0
  618. package/dist/monitoring/advanced-profiler.d.ts +51 -0
  619. package/dist/monitoring/advanced-profiler.js +232 -0
  620. package/dist/monitoring/memory-monitor.d.ts +113 -0
  621. package/dist/monitoring/memory-monitor.js +315 -0
  622. package/dist/monitoring/nudge-watchdog.d.ts +87 -0
  623. package/dist/monitoring/nudge-watchdog.js +355 -0
  624. package/dist/monitoring/test-auto-generation-monitor.d.ts +64 -0
  625. package/dist/monitoring/test-auto-generation-monitor.js +157 -0
  626. package/dist/nucleus/aside-worktree.d.ts +41 -0
  627. package/dist/nucleus/aside-worktree.js +164 -0
  628. package/dist/nucleus/autonomy-kernel.d.ts +55 -0
  629. package/dist/nucleus/autonomy-kernel.js +234 -0
  630. package/dist/nucleus/confer.d.ts +57 -0
  631. package/dist/nucleus/confer.js +322 -0
  632. package/dist/nucleus/default-plugins.d.ts +17 -0
  633. package/dist/nucleus/default-plugins.js +173 -0
  634. package/dist/nucleus/delegation-gate.d.ts +105 -0
  635. package/dist/nucleus/delegation-gate.js +582 -0
  636. package/dist/nucleus/govern-http.d.ts +59 -0
  637. package/dist/nucleus/govern-http.js +175 -0
  638. package/dist/nucleus/index.d.ts +17 -0
  639. package/dist/nucleus/index.js +12 -0
  640. package/dist/nucleus/kernel.d.ts +51 -0
  641. package/dist/nucleus/kernel.js +62 -0
  642. package/dist/nucleus/lead-dev-plan-persistence.d.ts +70 -0
  643. package/dist/nucleus/lead-dev-plan-persistence.js +402 -0
  644. package/dist/nucleus/pending-delegations.d.ts +71 -0
  645. package/dist/nucleus/pending-delegations.js +285 -0
  646. package/dist/nucleus/plugin-registry.d.ts +132 -0
  647. package/dist/nucleus/plugin-registry.js +175 -0
  648. package/dist/nucleus/spawn-plan-resolution.d.ts +20 -0
  649. package/dist/nucleus/spawn-plan-resolution.js +42 -0
  650. package/dist/nucleus/suit-temperament.d.ts +40 -0
  651. package/dist/nucleus/suit-temperament.js +159 -0
  652. package/dist/nucleus/synthesis-completion.d.ts +6 -0
  653. package/dist/nucleus/synthesis-completion.js +29 -0
  654. package/dist/nucleus/synthesis-consult-receipt.d.ts +32 -0
  655. package/dist/nucleus/synthesis-consult-receipt.js +171 -0
  656. package/dist/nucleus/synthesis-context.d.ts +31 -0
  657. package/dist/nucleus/synthesis-context.js +86 -0
  658. package/dist/nucleus/synthesis.d.ts +54 -0
  659. package/dist/nucleus/synthesis.js +196 -0
  660. package/dist/nucleus/thin-dispatch.d.ts +33 -0
  661. package/dist/nucleus/thin-dispatch.js +85 -0
  662. package/dist/nucleus/user-aside.d.ts +70 -0
  663. package/dist/nucleus/user-aside.js +393 -0
  664. package/dist/orchestrator/agent-spawn-governor.d.ts +126 -0
  665. package/dist/orchestrator/agent-spawn-governor.js +558 -0
  666. package/dist/orchestrator/enhanced-multi-agent-orchestrator.d.ts +156 -0
  667. package/dist/orchestrator/enhanced-multi-agent-orchestrator.js +399 -0
  668. package/dist/orchestrator/intelligent-commit-batcher.d.ts +114 -0
  669. package/dist/orchestrator/intelligent-commit-batcher.js +344 -0
  670. package/dist/orchestrator/multi-agent-orchestration-coordinator.d.ts +126 -0
  671. package/dist/orchestrator/multi-agent-orchestration-coordinator.js +455 -0
  672. package/dist/orchestrator/orchestrator.d.ts +141 -0
  673. package/dist/orchestrator/orchestrator.js +648 -0
  674. package/dist/orchestrator/self-direction-activation.d.ts +108 -0
  675. package/dist/orchestrator/self-direction-activation.js +244 -0
  676. package/dist/orchestrator/universal-librarian-consultation.d.ts +98 -0
  677. package/dist/orchestrator/universal-librarian-consultation.js +216 -0
  678. package/dist/orchestrator/universal-registry-bridge.d.ts +84 -0
  679. package/dist/orchestrator/universal-registry-bridge.js +246 -0
  680. package/dist/performance/performance-budget-enforcer.d.ts +157 -0
  681. package/dist/performance/performance-budget-enforcer.js +433 -0
  682. package/dist/performance/performance-regression-tester.d.ts +107 -0
  683. package/dist/performance/performance-regression-tester.js +341 -0
  684. package/dist/plugin/plugin-codex-context.d.ts +18 -0
  685. package/dist/plugin/plugin-codex-context.js +87 -0
  686. package/dist/plugin/plugin-helpers.d.ts +23 -0
  687. package/dist/plugin/plugin-helpers.js +155 -0
  688. package/dist/plugin/plugin-logger.d.ts +8 -0
  689. package/dist/plugin/plugin-logger.js +46 -0
  690. package/dist/plugin/plugin-modules.d.ts +11 -0
  691. package/dist/plugin/plugin-modules.js +144 -0
  692. package/dist/plugin/plugin-quality-gate.d.ts +11 -0
  693. package/dist/plugin/plugin-quality-gate.js +88 -0
  694. package/dist/plugin/plugin-types.d.ts +93 -0
  695. package/dist/plugin/plugin-types.js +1 -0
  696. package/dist/plugin/xray-codex-injection.d.ts +39 -0
  697. package/dist/plugin/xray-codex-injection.js +399 -0
  698. package/dist/postprocessor/PostProcessor.d.ts +108 -0
  699. package/dist/postprocessor/PostProcessor.js +1053 -0
  700. package/dist/postprocessor/analysis/CodeChangeAnalyzer.d.ts +11 -0
  701. package/dist/postprocessor/analysis/CodeChangeAnalyzer.js +50 -0
  702. package/dist/postprocessor/analysis/FailureAnalysisEngine.d.ts +39 -0
  703. package/dist/postprocessor/analysis/FailureAnalysisEngine.js +245 -0
  704. package/dist/postprocessor/autofix/AutoFixEngine.d.ts +48 -0
  705. package/dist/postprocessor/autofix/AutoFixEngine.js +254 -0
  706. package/dist/postprocessor/autofix/FixValidator.d.ts +23 -0
  707. package/dist/postprocessor/autofix/FixValidator.js +56 -0
  708. package/dist/postprocessor/config/ProcessorConfigLoader.d.ts +44 -0
  709. package/dist/postprocessor/config/ProcessorConfigLoader.js +16 -0
  710. package/dist/postprocessor/config.d.ts +6 -0
  711. package/dist/postprocessor/config.js +65 -0
  712. package/dist/postprocessor/escalation/EscalationEngine.d.ts +154 -0
  713. package/dist/postprocessor/escalation/EscalationEngine.js +492 -0
  714. package/dist/postprocessor/integration.d.ts +156 -0
  715. package/dist/postprocessor/integration.js +194 -0
  716. package/dist/postprocessor/metamorphosis/SelfProposalEngine.d.ts +87 -0
  717. package/dist/postprocessor/metamorphosis/SelfProposalEngine.js +472 -0
  718. package/dist/postprocessor/metamorphosis/index.d.ts +2 -0
  719. package/dist/postprocessor/metamorphosis/index.js +1 -0
  720. package/dist/postprocessor/monitoring/MonitoringEngine.d.ts +40 -0
  721. package/dist/postprocessor/monitoring/MonitoringEngine.js +125 -0
  722. package/dist/postprocessor/redeploy/RedeployCoordinator.d.ts +91 -0
  723. package/dist/postprocessor/redeploy/RedeployCoordinator.js +342 -0
  724. package/dist/postprocessor/redeploy/RetryHandler.d.ts +49 -0
  725. package/dist/postprocessor/redeploy/RetryHandler.js +118 -0
  726. package/dist/postprocessor/services/RegressionAnalysisService.d.ts +39 -0
  727. package/dist/postprocessor/services/RegressionAnalysisService.js +130 -0
  728. package/dist/postprocessor/success/SuccessHandler.d.ts +57 -0
  729. package/dist/postprocessor/success/SuccessHandler.js +134 -0
  730. package/dist/postprocessor/triggers/APITrigger.d.ts +34 -0
  731. package/dist/postprocessor/triggers/APITrigger.js +114 -0
  732. package/dist/postprocessor/triggers/GitHookTrigger.d.ts +38 -0
  733. package/dist/postprocessor/triggers/GitHookTrigger.js +557 -0
  734. package/dist/postprocessor/triggers/WebhookTrigger.d.ts +46 -0
  735. package/dist/postprocessor/triggers/WebhookTrigger.js +210 -0
  736. package/dist/postprocessor/types.d.ts +227 -0
  737. package/dist/postprocessor/types.js +4 -0
  738. package/dist/processors/doc-write-guard.d.ts +6 -0
  739. package/dist/processors/doc-write-guard.js +46 -0
  740. package/dist/processors/implementations/agents-md-validation-processor.d.ts +62 -0
  741. package/dist/processors/implementations/agents-md-validation-processor.js +285 -0
  742. package/dist/processors/implementations/async-pattern-processor.d.ts +47 -0
  743. package/dist/processors/implementations/async-pattern-processor.js +157 -0
  744. package/dist/processors/implementations/codex-compliance-processor.d.ts +7 -0
  745. package/dist/processors/implementations/codex-compliance-processor.js +57 -0
  746. package/dist/processors/implementations/commit-batcher-processor.d.ts +13 -0
  747. package/dist/processors/implementations/commit-batcher-processor.js +71 -0
  748. package/dist/processors/implementations/console-log-guard-processor.d.ts +32 -0
  749. package/dist/processors/implementations/console-log-guard-processor.js +162 -0
  750. package/dist/processors/implementations/coverage-analysis-processor.d.ts +19 -0
  751. package/dist/processors/implementations/coverage-analysis-processor.js +137 -0
  752. package/dist/processors/implementations/error-boundary-processor.d.ts +7 -0
  753. package/dist/processors/implementations/error-boundary-processor.js +44 -0
  754. package/dist/processors/implementations/inference-improvement-processor.d.ts +36 -0
  755. package/dist/processors/implementations/inference-improvement-processor.js +262 -0
  756. package/dist/processors/implementations/log-protection-processor.d.ts +29 -0
  757. package/dist/processors/implementations/log-protection-processor.js +117 -0
  758. package/dist/processors/implementations/nudge-processor.d.ts +21 -0
  759. package/dist/processors/implementations/nudge-processor.js +129 -0
  760. package/dist/processors/implementations/performance-budget-processor.d.ts +49 -0
  761. package/dist/processors/implementations/performance-budget-processor.js +216 -0
  762. package/dist/processors/implementations/postprocessor-chain-validator.d.ts +45 -0
  763. package/dist/processors/implementations/postprocessor-chain-validator.js +148 -0
  764. package/dist/processors/implementations/pre-validate-processor.d.ts +7 -0
  765. package/dist/processors/implementations/pre-validate-processor.js +18 -0
  766. package/dist/processors/implementations/publish-preflight-processor.d.ts +37 -0
  767. package/dist/processors/implementations/publish-preflight-processor.js +240 -0
  768. package/dist/processors/implementations/refactoring-logging-processor-wrapper.d.ts +7 -0
  769. package/dist/processors/implementations/refactoring-logging-processor-wrapper.js +33 -0
  770. package/dist/processors/implementations/refactoring-logging-processor.d.ts +31 -0
  771. package/dist/processors/implementations/refactoring-logging-processor.js +96 -0
  772. package/dist/processors/implementations/regression-testing-processor.d.ts +20 -0
  773. package/dist/processors/implementations/regression-testing-processor.js +59 -0
  774. package/dist/processors/implementations/session-capture-processor.d.ts +14 -0
  775. package/dist/processors/implementations/session-capture-processor.js +37 -0
  776. package/dist/processors/implementations/session-summary-processor.d.ts +26 -0
  777. package/dist/processors/implementations/session-summary-processor.js +125 -0
  778. package/dist/processors/implementations/spawn-governance-processor.d.ts +57 -0
  779. package/dist/processors/implementations/spawn-governance-processor.js +218 -0
  780. package/dist/processors/implementations/state-validation-processor.d.ts +11 -0
  781. package/dist/processors/implementations/state-validation-processor.js +15 -0
  782. package/dist/processors/implementations/storytelling-trigger-processor.d.ts +40 -0
  783. package/dist/processors/implementations/storytelling-trigger-processor.js +563 -0
  784. package/dist/processors/implementations/test-auto-creation-processor.d.ts +16 -0
  785. package/dist/processors/implementations/test-auto-creation-processor.js +483 -0
  786. package/dist/processors/implementations/test-execution-processor.d.ts +11 -0
  787. package/dist/processors/implementations/test-execution-processor.js +132 -0
  788. package/dist/processors/implementations/typescript-compilation-processor.d.ts +37 -0
  789. package/dist/processors/implementations/typescript-compilation-processor.js +86 -0
  790. package/dist/processors/implementations/version-compliance-processor.d.ts +80 -0
  791. package/dist/processors/implementations/version-compliance-processor.js +222 -0
  792. package/dist/processors/processor-interfaces.d.ts +126 -0
  793. package/dist/processors/processor-interfaces.js +125 -0
  794. package/dist/processors/processor-manager.d.ts +80 -0
  795. package/dist/processors/processor-manager.js +826 -0
  796. package/dist/processors/processor-types.d.ts +189 -0
  797. package/dist/processors/processor-types.js +11 -0
  798. package/dist/public/XrayService.d.ts +17 -0
  799. package/dist/public/XrayService.js +40 -0
  800. package/dist/public/about.html +228 -0
  801. package/dist/public/enterprise.html +27 -0
  802. package/dist/public/features.html +102 -0
  803. package/dist/public/index.d.ts +4 -0
  804. package/dist/public/index.html +145 -0
  805. package/dist/public/index.js +2 -0
  806. package/dist/reporting/framework-reporting-system.d.ts +19 -0
  807. package/dist/reporting/framework-reporting-system.js +187 -0
  808. package/dist/reporting/log-parser.d.ts +10 -0
  809. package/dist/reporting/log-parser.js +281 -0
  810. package/dist/reporting/metrics.d.ts +15 -0
  811. package/dist/reporting/metrics.js +202 -0
  812. package/dist/reporting/report-formatter.d.ts +5 -0
  813. package/dist/reporting/report-formatter.js +146 -0
  814. package/dist/reporting/types.d.ts +102 -0
  815. package/dist/reporting/types.js +1 -0
  816. package/dist/scripts/activate-kernel-pipeline.d.ts +7 -0
  817. package/dist/scripts/activate-kernel-pipeline.js +101 -0
  818. package/dist/scripts/integration.d.ts +36 -0
  819. package/dist/scripts/integration.js +233 -0
  820. package/dist/scripts/pre-command +26 -0
  821. package/dist/scripts/pre-command.mjs +358 -0
  822. package/dist/security/comprehensive-security-audit.d.ts +157 -0
  823. package/dist/security/comprehensive-security-audit.js +1004 -0
  824. package/dist/security/index.d.ts +13 -0
  825. package/dist/security/index.js +13 -0
  826. package/dist/security/prompt-security-validator.d.ts +44 -0
  827. package/dist/security/prompt-security-validator.js +148 -0
  828. package/dist/security/security-agent-coordinator.d.ts +71 -0
  829. package/dist/security/security-agent-coordinator.js +203 -0
  830. package/dist/security/security-auditor.d.ts +55 -0
  831. package/dist/security/security-auditor.js +583 -0
  832. package/dist/security/security-hardener.d.ts +61 -0
  833. package/dist/security/security-hardener.js +169 -0
  834. package/dist/security/security-hardening-system.d.ts +238 -0
  835. package/dist/security/security-hardening-system.js +726 -0
  836. package/dist/security/security-headers.d.ts +63 -0
  837. package/dist/security/security-headers.js +117 -0
  838. package/dist/security/security-orchestration-layer.d.ts +118 -0
  839. package/dist/security/security-orchestration-layer.js +495 -0
  840. package/dist/security/security-scanner.d.ts +119 -0
  841. package/dist/security/security-scanner.js +429 -0
  842. package/dist/services/inference-tuner.d.ts +76 -0
  843. package/dist/services/inference-tuner.js +300 -0
  844. package/dist/session/index.d.ts +3 -0
  845. package/dist/session/index.js +3 -0
  846. package/dist/session/session-cleanup-manager.d.ts +117 -0
  847. package/dist/session/session-cleanup-manager.js +365 -0
  848. package/dist/session/session-monitor.d.ts +132 -0
  849. package/dist/session/session-monitor.js +502 -0
  850. package/dist/session/session-state-manager.d.ts +144 -0
  851. package/dist/session/session-state-manager.js +521 -0
  852. package/dist/skills/api-design/SKILL.md +37 -0
  853. package/dist/skills/architect-tools/SKILL.md +37 -0
  854. package/dist/skills/architecture-patterns/SKILL.md +37 -0
  855. package/dist/skills/auto-format/SKILL.md +37 -0
  856. package/dist/skills/backend-engineer/SKILL.md +49 -0
  857. package/dist/skills/boot-orchestrator/SKILL.md +33 -0
  858. package/dist/skills/bug-triage/SKILL.md +43 -0
  859. package/dist/skills/code-analyzer/SKILL.md +45 -0
  860. package/dist/skills/code-review/SKILL.md +52 -0
  861. package/dist/skills/content-creator/SKILL.md +38 -0
  862. package/dist/skills/database-engineer/SKILL.md +46 -0
  863. package/dist/skills/devops-engineer/SKILL.md +49 -0
  864. package/dist/skills/enforcer/SKILL.md +37 -0
  865. package/dist/skills/framework-compliance-audit/SKILL.md +37 -0
  866. package/dist/skills/frontend-engineer/SKILL.md +49 -0
  867. package/dist/skills/frontend-ui-ux-engineer/SKILL.md +41 -0
  868. package/dist/skills/git-workflow/SKILL.md +37 -0
  869. package/dist/skills/growth-strategist/SKILL.md +48 -0
  870. package/dist/skills/hermes-agent/SKILL.md +212 -0
  871. package/dist/skills/inference-improve/SKILL.md +97 -0
  872. package/dist/skills/lint/SKILL.md +37 -0
  873. package/dist/skills/log-monitor/SKILL.md +44 -0
  874. package/dist/skills/mobile-developer/SKILL.md +42 -0
  875. package/dist/skills/model-health-check/SKILL.md +37 -0
  876. package/dist/skills/multimodal-looker/SKILL.md +45 -0
  877. package/dist/skills/orchestrator/SKILL.md +61 -0
  878. package/dist/skills/performance-analysis/SKILL.md +37 -0
  879. package/dist/skills/performance-engineer/SKILL.md +41 -0
  880. package/dist/skills/performance-optimization/SKILL.md +37 -0
  881. package/dist/skills/processor-pipeline/SKILL.md +37 -0
  882. package/dist/skills/project-analysis/SKILL.md +42 -0
  883. package/dist/skills/refactoring-strategies/SKILL.md +37 -0
  884. package/dist/skills/registry.json +65 -0
  885. package/dist/skills/researcher/SKILL.md +50 -0
  886. package/dist/skills/security-audit/SKILL.md +48 -0
  887. package/dist/skills/security-scan/SKILL.md +37 -0
  888. package/dist/skills/seo-consultant/SKILL.md +43 -0
  889. package/dist/skills/session-management/SKILL.md +36 -0
  890. package/dist/skills/state-manager/SKILL.md +37 -0
  891. package/dist/skills/storyteller/SKILL.md +130 -0
  892. package/dist/skills/strategist/SKILL.md +44 -0
  893. package/dist/skills/tech-writer/SKILL.md +37 -0
  894. package/dist/skills/testing-best-practices/SKILL.md +37 -0
  895. package/dist/skills/testing-strategy/SKILL.md +54 -0
  896. package/dist/skills/ui-ux-design/SKILL.md +603 -0
  897. package/dist/skills/xray-orchestrator/SKILL.md +141 -0
  898. package/dist/skills/xray-orchestrator/index.d.ts +12 -0
  899. package/dist/skills/xray-orchestrator/index.js +223 -0
  900. package/dist/state/context-providers.d.ts +4 -0
  901. package/dist/state/context-providers.js +1 -0
  902. package/dist/state/index.d.ts +4 -0
  903. package/dist/state/index.js +7 -0
  904. package/dist/state/state-manager.d.ts +41 -0
  905. package/dist/state/state-manager.js +207 -0
  906. package/dist/state/state-types.d.ts +5 -0
  907. package/dist/state/state-types.js +1 -0
  908. package/dist/testing/memory-regression-suite.d.ts +105 -0
  909. package/dist/testing/memory-regression-suite.js +258 -0
  910. package/dist/tools/assess-complexity-tool.d.ts +28 -0
  911. package/dist/tools/assess-complexity-tool.js +44 -0
  912. package/dist/tools/query-routing-tool.d.ts +17 -0
  913. package/dist/tools/query-routing-tool.js +59 -0
  914. package/dist/types/metamorphosis.d.ts +21 -0
  915. package/dist/types/metamorphosis.js +6 -0
  916. package/dist/utils/batch-operations.d.ts +25 -0
  917. package/dist/utils/batch-operations.js +292 -0
  918. package/dist/utils/codex-parser.d.ts +60 -0
  919. package/dist/utils/codex-parser.js +444 -0
  920. package/dist/utils/command-runner.d.ts +32 -0
  921. package/dist/utils/command-runner.js +96 -0
  922. package/dist/utils/import-resolver.d.ts +54 -0
  923. package/dist/utils/import-resolver.js +189 -0
  924. package/dist/utils/language-detector.d.ts +43 -0
  925. package/dist/utils/language-detector.js +382 -0
  926. package/dist/utils/path-resolver.d.ts +48 -0
  927. package/dist/utils/path-resolver.js +112 -0
  928. package/dist/utils/shutdown-handler.d.ts +26 -0
  929. package/dist/utils/shutdown-handler.js +74 -0
  930. package/dist/utils/task-graph.d.ts +29 -0
  931. package/dist/utils/task-graph.js +106 -0
  932. package/dist/utils/test-template-generator.d.ts +25 -0
  933. package/dist/utils/test-template-generator.js +178 -0
  934. package/dist/utils/token-manager.d.ts +48 -0
  935. package/dist/utils/token-manager.js +163 -0
  936. package/dist/validation/agent-config-validator.d.ts +110 -0
  937. package/dist/validation/agent-config-validator.js +280 -0
  938. package/dist/validation/estimation-validator.d.ts +61 -0
  939. package/dist/validation/estimation-validator.js +241 -0
  940. package/dist/validation/orchestration-flow-validator.d.ts +87 -0
  941. package/dist/validation/orchestration-flow-validator.js +606 -0
  942. package/dist/validation/report-content-validator.d.ts +42 -0
  943. package/dist/validation/report-content-validator.js +218 -0
  944. package/llms.txt +5 -3
  945. package/package.json +4 -2
  946. package/scripts/foundry/CHANGELOG.md +34 -0
  947. package/scripts/foundry/README.md +12 -0
  948. package/scripts/foundry/assert-packed-dist-cli.mjs +97 -0
  949. package/scripts/foundry/blip-render.cjs +1237 -0
  950. package/scripts/foundry/blip-rippel.cjs +1963 -0
  951. package/scripts/foundry/blip.mjs +109 -0
  952. package/scripts/foundry/cli.mjs +8 -4
  953. package/scripts/foundry/inspect.mjs +117 -7
  954. package/scripts/foundry/mint-suit.cjs +215 -14
  955. package/scripts/foundry/package.json +6 -0
  956. package/scripts/foundry/plant/agents/blip-inspect.yml +5 -0
  957. package/scripts/foundry/plant/agents/blip.yml +5 -0
  958. package/scripts/foundry/plant/agents/sound-inspect.yml +5 -0
  959. package/scripts/foundry/plant/agents/sound.yml +5 -0
  960. package/scripts/foundry/plant/motions/MOTION-REGISTRY.md +35 -0
  961. package/scripts/foundry/plant/motions/registry.json +81 -0
  962. package/scripts/foundry/plant/skills/blip/SKILL.md +39 -0
  963. package/scripts/foundry/plant/skills/blip-inspect/SKILL.md +32 -0
  964. package/scripts/foundry/plant/skills/inspect/SKILL.md +2 -2
  965. package/scripts/foundry/plant/skills/sound/SKILL.md +29 -0
  966. package/scripts/foundry/plant/skills/sound-inspect/SKILL.md +28 -0
  967. package/scripts/foundry/release-gate.mjs +18 -10
  968. package/scripts/foundry/release.mjs +3 -0
  969. package/scripts/foundry/sound-bed.cjs +454 -0
  970. package/scripts/foundry/sound-rippel.cjs +1434 -0
  971. package/scripts/foundry/sound.mjs +93 -0
  972. package/scripts/node/assert-packed-dist-cli.mjs +4 -0
  973. package/scripts/node/consumer-install-smoke.mjs +20 -1
  974. package/src/integrations/openclaw/plugin/xray-pre-tool/package.json +1 -1
  975. package/xray/features.json +1 -1
  976. package/xray/features.schema.json +1 -1
@@ -0,0 +1,1963 @@
1
+ /**
2
+ * Factory-blip Rippel canvas — Rippel v2 headless port of SimplifiedVisualConverter.
3
+ *
4
+ * SSOT htafolla/rippel-synapse-flow@e5014cd46fbe5f132391333d8296f4416896dbee
5
+ * animationIcons.ts — Animation + ANIMATION_TO_VISUALIZATION
6
+ * types/index.ts — ChecksumResponse.visualConfig { circles[], canvas, tlmCommand }
7
+ * SimplifiedVisualConverter.tsx — routes Animation → viz id, canvas fallback 1280×720
8
+ * MiniAnimationViewer / FiveDimensionalVisualizer — viz backends for those ids
9
+ *
10
+ * This file is the converter spine, not a drawbox/geq label. Brief+seed → checksum
11
+ * visualConfig (CircleConfig[]) → viz backend. Power Plant palette is the Blip theme.
12
+ * v2 look variants (seed + --look): focus | cage.
13
+ * focus — lost sharp-dogfood: solid cyan disc + gold pupil + orbiting stampFocusDisc satellites.
14
+ * Field + mesh verts (solid mass, not wire) carry the mint id under the disc.
15
+ * cage — sparse Wu hairline mesh + field accents (stars, grid, gradient, blinkers).
16
+ * v2 motion: genre tempo + CircleConfig.frequency LFOs (same mill the audio bed uses).
17
+ * 4.44s is a Short: hook → turn → tag on the same motion grid as the bed.
18
+ * Phrase weights (hookEase/turnEase/tagEase) crossfade; binaries stay section flags.
19
+ * Uniqueness is look + field + mesh fingerprint — not more wire in the middle.
20
+ * Wireframe ffmpeg geometry lives in blip-render.cjs and is flag-only.
21
+ */
22
+
23
+ const soundRippel = require("./sound-rippel.cjs");
24
+
25
+ const ENGINE = "rippel-headless";
26
+ const LOOK = "rippel-v2";
27
+ const MOTION_WIDTH = 1280;
28
+ const MOTION_HEIGHT = 720;
29
+ const FPS = 30;
30
+ const TLM = "checksum";
31
+
32
+ const SSOT = {
33
+ repo: "htafolla/rippel-synapse-flow",
34
+ commit: "e5014cd46fbe5f132391333d8296f4416896dbee",
35
+ access: "headless-port",
36
+ paths: [
37
+ "animationIcons.ts",
38
+ "types/index.ts",
39
+ "SimplifiedVisualConverter.tsx",
40
+ "MiniAnimationViewer",
41
+ "FiveDimensionalVisualizer",
42
+ ],
43
+ note: "Rippel v2 — VisualConfig.circles + look variants (focus disc-satellites | cage Wu+field). Soft tints, no photosensitive strobe. Wireframe is flag-only.",
44
+ };
45
+
46
+ const GRID_KINDS = ["floor", "meridian", "ticks", "none"];
47
+ const GRAD_KINDS = ["horizon", "corner", "veil"];
48
+
49
+ const MESH_FAMILIES = [
50
+ "tetra",
51
+ "octa",
52
+ "cube",
53
+ "prism",
54
+ "star",
55
+ "cage",
56
+ "spire",
57
+ "icosa",
58
+ "helix",
59
+ "torus",
60
+ "lattice",
61
+ "flower",
62
+ ];
63
+ const MESH_GAITS = ["tumble", "shear", "pulse", "orbit", "snap"];
64
+ const CORE_STYLES = ["disc", "eclipse", "pulse"];
65
+ const LOOK_KINDS = ["focus", "cage"];
66
+
67
+ /** animationIcons.ts — names are imports into the plant registry. */
68
+ const ANIMATION_TO_VISUALIZATION = {
69
+ orb: "canvas",
70
+ swirl: "3d-sacred",
71
+ snap: "neural",
72
+ waves: "waveform",
73
+ spark: "particles",
74
+ };
75
+
76
+ const THEME = {
77
+ void: [8, 9, 11],
78
+ ink: [245, 247, 250],
79
+ cyan: [61, 224, 232],
80
+ gold: [245, 197, 24],
81
+ blue: [74, 127, 212],
82
+ };
83
+
84
+ const THEME_CYCLE = [THEME.cyan, THEME.gold, THEME.blue, THEME.ink];
85
+ const LIGHT_CYCLE = [THEME.cyan, THEME.gold, THEME.blue];
86
+
87
+ /** getGenreConfig.ts scale tables — same SSOT the sound mill already ported. */
88
+ const SCALES = {
89
+ ambient: [261.63, 311.13, 349.23, 392.0, 466.16],
90
+ techno: [65.41, 87.31, 130.81, 174.61, 196.0],
91
+ phonk: [32.7, 43.65, 55.0, 65.41, 82.41],
92
+ jazz: [130.81, 164.81, 196.0, 220.0, 261.63],
93
+ };
94
+
95
+ const NOTE_NAMES = ["C", "D#", "F", "G", "A#"];
96
+
97
+ const visualCache = new Map();
98
+
99
+ function clamp(n, lo, hi) {
100
+ return n < lo ? lo : n > hi ? hi : n;
101
+ }
102
+
103
+ function seedU32(seedHex, offset) {
104
+ const hex = String(seedHex || "").replace(/^0x/, "");
105
+ const n = Number.parseInt(hex.slice(offset, offset + 8), 16);
106
+ return Number.isFinite(n) ? n >>> 0 : 1;
107
+ }
108
+
109
+ function mulberry32(seed) {
110
+ let t = seed >>> 0;
111
+ return function next() {
112
+ t += 0x6d2b79f5;
113
+ let x = t;
114
+ x = Math.imul(x ^ (x >>> 15), x | 1);
115
+ x ^= x + Math.imul(x ^ (x >>> 7), x | 61);
116
+ return ((x ^ (x >>> 14)) >>> 0) / 4294967296;
117
+ };
118
+ }
119
+
120
+ function rgbHex(rgb) {
121
+ return `#${rgb.map((c) => clamp(c, 0, 255).toString(16).padStart(2, "0")).join("")}`;
122
+ }
123
+
124
+ function parseHex(hex) {
125
+ const h = String(hex || "").replace(/^#/, "");
126
+ return [
127
+ Number.parseInt(h.slice(0, 2), 16) || 0,
128
+ Number.parseInt(h.slice(2, 4), 16) || 0,
129
+ Number.parseInt(h.slice(4, 6), 16) || 0,
130
+ ];
131
+ }
132
+
133
+ function norm3(x, y, z) {
134
+ const len = Math.hypot(x, y, z) || 1;
135
+ return [x / len, y / len, z / len];
136
+ }
137
+
138
+ function kNearestEdges(verts, k) {
139
+ const edges = [];
140
+ const seen = new Set();
141
+ for (let i = 0; i < verts.length; i++) {
142
+ const dist = [];
143
+ for (let j = 0; j < verts.length; j++) {
144
+ if (j === i) continue;
145
+ const dx = verts[i][0] - verts[j][0];
146
+ const dy = verts[i][1] - verts[j][1];
147
+ const dz = verts[i][2] - verts[j][2];
148
+ dist.push({ j, d: dx * dx + dy * dy + dz * dz });
149
+ }
150
+ dist.sort((p, q) => p.d - q.d);
151
+ for (let n = 0; n < k && n < dist.length; n++) {
152
+ const a = i < dist[n].j ? i : dist[n].j;
153
+ const b = i < dist[n].j ? dist[n].j : i;
154
+ const key = `${a}-${b}`;
155
+ if (!seen.has(key)) {
156
+ seen.add(key);
157
+ edges.push([a, b]);
158
+ }
159
+ }
160
+ }
161
+ return edges;
162
+ }
163
+
164
+ function trianglesFromEdges(verts, edges) {
165
+ const adj = verts.map(() => []);
166
+ for (let i = 0; i < edges.length; i++) {
167
+ const a = edges[i][0];
168
+ const b = edges[i][1];
169
+ adj[a].push(b);
170
+ adj[b].push(a);
171
+ }
172
+ const faces = [];
173
+ const seen = new Set();
174
+ for (let a = 0; a < verts.length; a++) {
175
+ for (let bi = 0; bi < adj[a].length; bi++) {
176
+ const b = adj[a][bi];
177
+ if (b <= a) continue;
178
+ for (let ci = 0; ci < adj[a].length; ci++) {
179
+ const c = adj[a][ci];
180
+ if (c <= b) continue;
181
+ if (!adj[b].includes(c)) continue;
182
+ const key = `${a}-${b}-${c}`;
183
+ if (seen.has(key)) continue;
184
+ seen.add(key);
185
+ faces.push([a, b, c]);
186
+ }
187
+ }
188
+ }
189
+ return faces;
190
+ }
191
+
192
+ function platonic(family) {
193
+ if (family === "tetra") {
194
+ return {
195
+ verts: [
196
+ [1, 1, 1],
197
+ [1, -1, -1],
198
+ [-1, 1, -1],
199
+ [-1, -1, 1],
200
+ ].map((v) => norm3(v[0], v[1], v[2])),
201
+ edges: [
202
+ [0, 1],
203
+ [0, 2],
204
+ [0, 3],
205
+ [1, 2],
206
+ [1, 3],
207
+ [2, 3],
208
+ ],
209
+ faces: [
210
+ [0, 1, 2],
211
+ [0, 1, 3],
212
+ [0, 2, 3],
213
+ [1, 2, 3],
214
+ ],
215
+ };
216
+ }
217
+ if (family === "octa") {
218
+ return {
219
+ verts: [
220
+ [1, 0, 0],
221
+ [-1, 0, 0],
222
+ [0, 1, 0],
223
+ [0, -1, 0],
224
+ [0, 0, 1],
225
+ [0, 0, -1],
226
+ ],
227
+ edges: [
228
+ [0, 2],
229
+ [0, 3],
230
+ [0, 4],
231
+ [0, 5],
232
+ [1, 2],
233
+ [1, 3],
234
+ [1, 4],
235
+ [1, 5],
236
+ [2, 4],
237
+ [2, 5],
238
+ [3, 4],
239
+ [3, 5],
240
+ ],
241
+ faces: [
242
+ [0, 2, 4],
243
+ [0, 4, 3],
244
+ [0, 3, 5],
245
+ [0, 5, 2],
246
+ [1, 2, 5],
247
+ [1, 5, 3],
248
+ [1, 3, 4],
249
+ [1, 4, 2],
250
+ ],
251
+ };
252
+ }
253
+ if (family === "cube") {
254
+ const verts = [];
255
+ for (const x of [-1, 1]) for (const y of [-1, 1]) for (const z of [-1, 1]) verts.push(norm3(x, y, z));
256
+ const edges = [];
257
+ for (let i = 0; i < 8; i++) {
258
+ for (let j = i + 1; j < 8; j++) {
259
+ let d = 0;
260
+ for (let k = 0; k < 3; k++) if (verts[i][k] !== verts[j][k]) d += 1;
261
+ if (d === 1) edges.push([i, j]);
262
+ }
263
+ }
264
+ return { verts, edges, faces: trianglesFromEdges(verts, edges) };
265
+ }
266
+ if (family === "prism") {
267
+ const verts = [];
268
+ for (let i = 0; i < 3; i++) {
269
+ const a = (i * Math.PI * 2) / 3;
270
+ verts.push(norm3(Math.cos(a), Math.sin(a), 0.7));
271
+ verts.push(norm3(Math.cos(a), Math.sin(a), -0.7));
272
+ }
273
+ return {
274
+ verts,
275
+ edges: [
276
+ [0, 2],
277
+ [2, 4],
278
+ [4, 0],
279
+ [1, 3],
280
+ [3, 5],
281
+ [5, 1],
282
+ [0, 1],
283
+ [2, 3],
284
+ [4, 5],
285
+ ],
286
+ faces: [
287
+ [0, 2, 4],
288
+ [1, 3, 5],
289
+ [0, 1, 2],
290
+ [2, 1, 3],
291
+ [2, 3, 4],
292
+ [4, 3, 5],
293
+ [4, 5, 0],
294
+ [0, 5, 1],
295
+ ],
296
+ };
297
+ }
298
+ if (family === "star") {
299
+ const a = platonic("tetra");
300
+ const verts = a.verts.concat(a.verts.map((v) => [-v[0], -v[1], -v[2]]));
301
+ const edges = a.edges.concat(a.edges.map((e) => [e[0] + 4, e[1] + 4]));
302
+ const faces = (a.faces || []).concat((a.faces || []).map((f) => [f[0] + 4, f[1] + 4, f[2] + 4]));
303
+ return { verts, edges, faces };
304
+ }
305
+ if (family === "spire") {
306
+ const verts = [[0, 0, 1], [0, 0, -0.35]];
307
+ const edges = [[0, 1]];
308
+ for (let i = 0; i < 5; i++) {
309
+ const a = (i * Math.PI * 2) / 5;
310
+ verts.push(norm3(Math.cos(a) * 0.95, Math.sin(a) * 0.95, -0.2));
311
+ edges.push([0, i + 2], [1, i + 2], [i + 2, 2 + ((i + 1) % 5)]);
312
+ }
313
+ return { verts, edges };
314
+ }
315
+ if (family === "icosa") {
316
+ const phi = (1 + Math.sqrt(5)) / 2;
317
+ const raw = [
318
+ [0, 1, phi],
319
+ [0, 1, -phi],
320
+ [0, -1, phi],
321
+ [0, -1, -phi],
322
+ [1, phi, 0],
323
+ [1, -phi, 0],
324
+ [-1, phi, 0],
325
+ [-1, -phi, 0],
326
+ [phi, 0, 1],
327
+ [phi, 0, -1],
328
+ [-phi, 0, 1],
329
+ [-phi, 0, -1],
330
+ ].map((v) => norm3(v[0], v[1], v[2]));
331
+ const edges = kNearestEdges(raw, 5);
332
+ return { verts: raw, edges, faces: trianglesFromEdges(raw, edges) };
333
+ }
334
+ if (family === "helix") {
335
+ const verts = [];
336
+ const edges = [];
337
+ const n = 10;
338
+ for (let i = 0; i < n; i++) {
339
+ const a = i * 0.82;
340
+ const y = (i / (n - 1)) * 2 - 1;
341
+ verts.push(norm3(Math.cos(a) * 0.92, y, Math.sin(a) * 0.92));
342
+ if (i > 0) edges.push([i - 1, i]);
343
+ if (i > 1) edges.push([i - 2, i]);
344
+ }
345
+ edges.push([0, n - 1], [0, n - 2]);
346
+ return { verts, edges, faces: trianglesFromEdges(verts, edges) };
347
+ }
348
+ if (family === "torus") {
349
+ const verts = [];
350
+ const rings = 7;
351
+ const tube = 4;
352
+ const R = 0.78;
353
+ const r = 0.34;
354
+ for (let i = 0; i < rings; i++) {
355
+ const u = (i * Math.PI * 2) / rings;
356
+ for (let j = 0; j < tube; j++) {
357
+ const v = (j * Math.PI * 2) / tube;
358
+ verts.push(
359
+ norm3(
360
+ (R + r * Math.cos(v)) * Math.cos(u),
361
+ r * Math.sin(v),
362
+ (R + r * Math.cos(v)) * Math.sin(u),
363
+ ),
364
+ );
365
+ }
366
+ }
367
+ const edges = [];
368
+ for (let i = 0; i < rings; i++) {
369
+ for (let j = 0; j < tube; j++) {
370
+ const a = i * tube + j;
371
+ edges.push([a, i * tube + ((j + 1) % tube)]);
372
+ edges.push([a, ((i + 1) % rings) * tube + j]);
373
+ }
374
+ }
375
+ return { verts, edges, faces: trianglesFromEdges(verts, edges).slice(0, 36) };
376
+ }
377
+ if (family === "lattice") {
378
+ const verts = [];
379
+ const idx = new Map();
380
+ const vals = [-0.72, 0, 0.72];
381
+ for (let i = 0; i < vals.length; i++) {
382
+ for (let j = 0; j < vals.length; j++) {
383
+ for (let k = 0; k < vals.length; k++) {
384
+ idx.set(`${i},${j},${k}`, verts.length);
385
+ verts.push(norm3(vals[i], vals[j], vals[k]));
386
+ }
387
+ }
388
+ }
389
+ const edges = [];
390
+ for (let i = 0; i < vals.length; i++) {
391
+ for (let j = 0; j < vals.length; j++) {
392
+ for (let k = 0; k < vals.length; k++) {
393
+ const a = idx.get(`${i},${j},${k}`);
394
+ if (i + 1 < vals.length) edges.push([a, idx.get(`${i + 1},${j},${k}`)]);
395
+ if (j + 1 < vals.length) edges.push([a, idx.get(`${i},${j + 1},${k}`)]);
396
+ if (k + 1 < vals.length) edges.push([a, idx.get(`${i},${j},${k + 1}`)]);
397
+ }
398
+ }
399
+ }
400
+ return { verts, edges, faces: trianglesFromEdges(verts, edges).slice(0, 36) };
401
+ }
402
+ if (family === "flower") {
403
+ const verts = [[0, 0, 0.15]];
404
+ const edges = [];
405
+ for (let ring = 0; ring < 2; ring++) {
406
+ const z = ring === 0 ? 0.2 : -0.28;
407
+ const rad = ring === 0 ? 0.62 : 1;
408
+ for (let i = 0; i < 7; i++) {
409
+ const a = (i * Math.PI * 2) / 7 + ring * 0.22;
410
+ verts.push(norm3(Math.cos(a) * rad, Math.sin(a) * rad, z));
411
+ const vi = verts.length - 1;
412
+ edges.push([0, vi]);
413
+ if (i > 0) edges.push([vi - 1, vi]);
414
+ if (i === 6) edges.push([vi, 1 + ring * 7]);
415
+ }
416
+ }
417
+ for (let i = 0; i < 7; i++) edges.push([1 + i, 8 + i]);
418
+ return { verts, edges, faces: trianglesFromEdges(verts, edges) };
419
+ }
420
+ const verts = [];
421
+ const n = 8;
422
+ const phi = Math.PI * (3 - Math.sqrt(5));
423
+ for (let i = 0; i < n; i++) {
424
+ const y = 1 - (i / (n - 1)) * 2;
425
+ const r = Math.sqrt(Math.max(0, 1 - y * y));
426
+ const a = phi * i;
427
+ verts.push(norm3(Math.cos(a) * r, y, Math.sin(a) * r));
428
+ }
429
+ const edges = [];
430
+ for (let i = 0; i < n; i++) {
431
+ const dist = [];
432
+ for (let j = 0; j < n; j++) {
433
+ if (j === i) continue;
434
+ const dx = verts[i][0] - verts[j][0];
435
+ const dy = verts[i][1] - verts[j][1];
436
+ const dz = verts[i][2] - verts[j][2];
437
+ dist.push({ j, d: dx * dx + dy * dy + dz * dz });
438
+ }
439
+ dist.sort((p, q) => p.d - q.d);
440
+ for (let k = 0; k < 3; k++) {
441
+ const j = dist[k].j;
442
+ const a = i < j ? i : j;
443
+ const b = i < j ? j : i;
444
+ if (!edges.some((e) => e[0] === a && e[1] === b)) edges.push([a, b]);
445
+ }
446
+ }
447
+ return { verts, edges, faces: trianglesFromEdges(verts, edges) };
448
+ }
449
+
450
+ function thinConnectedEdges(edges, vertCount, keep, rng) {
451
+ if (edges.length <= keep) return edges.map((e) => [e[0], e[1]]);
452
+ const adj = Array.from({ length: vertCount }, () => []);
453
+ for (let i = 0; i < edges.length; i++) {
454
+ adj[edges[i][0]].push(edges[i][1]);
455
+ adj[edges[i][1]].push(edges[i][0]);
456
+ }
457
+ const start = (rng() * vertCount) | 0;
458
+ const seen = new Set([start]);
459
+ const kept = [];
460
+ const q = [start];
461
+ while (q.length && kept.length < keep) {
462
+ const v = q.shift();
463
+ const nbrs = adj[v];
464
+ for (let i = 0; i < nbrs.length && kept.length < keep; i++) {
465
+ const w = nbrs[i];
466
+ if (seen.has(w)) continue;
467
+ seen.add(w);
468
+ q.push(w);
469
+ kept.push(v < w ? [v, w] : [w, v]);
470
+ }
471
+ }
472
+ for (let i = 0; i < edges.length && kept.length < keep; i++) {
473
+ const a = edges[i][0];
474
+ const b = edges[i][1];
475
+ if (!kept.some((e) => e[0] === a && e[1] === b)) kept.push([a, b]);
476
+ }
477
+ return kept;
478
+ }
479
+
480
+ function buildMesh(seedHex, brief) {
481
+ const text = String(brief || "factory-blip");
482
+ let mix = 0;
483
+ for (let i = 0; i < text.length; i++) mix = (Math.imul(mix, 33) + text.charCodeAt(i)) >>> 0;
484
+ const rng = mulberry32(seedU32(seedHex, 0) ^ seedU32(seedHex, 8) ^ seedU32(seedHex, 16) ^ mix);
485
+ const family = MESH_FAMILIES[(rng() * MESH_FAMILIES.length) | 0];
486
+ const gait = MESH_GAITS[(rng() * MESH_GAITS.length) | 0];
487
+ const base = platonic(family);
488
+ const jitter = 0.05 + rng() * 0.16;
489
+ const verts = base.verts.map((v) =>
490
+ norm3(v[0] + (rng() - 0.5) * jitter, v[1] + (rng() - 0.5) * jitter, v[2] + (rng() - 0.5) * jitter),
491
+ );
492
+ let edges = base.edges.map((e) => [e[0], e[1]]);
493
+ const extra = (rng() * 3) | 0;
494
+ for (let i = 0; i < extra; i++) {
495
+ const a = (rng() * verts.length) | 0;
496
+ const b = (rng() * verts.length) | 0;
497
+ if (a === b) continue;
498
+ const lo = a < b ? a : b;
499
+ const hi = a < b ? b : a;
500
+ if (!edges.some((e) => e[0] === lo && e[1] === hi)) edges.push([lo, hi]);
501
+ }
502
+ if (edges.length > 16) {
503
+ edges = thinConnectedEdges(edges, verts.length, 10 + ((rng() * 6) | 0), rng);
504
+ }
505
+ let faces = (base.faces && base.faces.length ? base.faces : trianglesFromEdges(verts, edges)).map((f) => [
506
+ f[0],
507
+ f[1],
508
+ f[2],
509
+ ]);
510
+ if (faces.length > 16) faces = faces.slice(0, 16);
511
+ const accentIndex = (rng() * THEME_CYCLE.length) | 0;
512
+ const coreStyle = CORE_STYLES[(rng() * CORE_STYLES.length) | 0];
513
+ return {
514
+ family,
515
+ gait,
516
+ coreStyle,
517
+ id: `${family}-${gait}-${verts.length}v${edges.length}e${faces.length}f-${((rng() * 0xfffffff) | 0).toString(16)}`,
518
+ verts,
519
+ edges,
520
+ faces,
521
+ twist: rng() * Math.PI * 2,
522
+ spin: 1.7 + rng() * 2.4,
523
+ scale: 0.58 + rng() * 0.2,
524
+ warp: 0.06 + rng() * 0.14,
525
+ shells: 1,
526
+ cuts: 3 + ((rng() * 3) | 0),
527
+ dual: false,
528
+ ghost: false,
529
+ fill: false,
530
+ accentIndex,
531
+ accent: THEME_CYCLE[accentIndex],
532
+ };
533
+ }
534
+
535
+ function buildField(seedHex, brief) {
536
+ const text = String(brief || "factory-blip");
537
+ let mix = 1;
538
+ for (let i = 0; i < text.length; i++) mix = (Math.imul(mix, 31) + text.charCodeAt(i)) >>> 0;
539
+ const rng = mulberry32(seedU32(seedHex, 4) ^ seedU32(seedHex, 12) ^ mix ^ 0x51ed);
540
+ const stars = [];
541
+ const want = 16 + ((rng() * 14) | 0);
542
+ for (let i = 0; i < want * 3 && stars.length < want; i++) {
543
+ const x = rng();
544
+ const y = rng();
545
+ if (Math.hypot(x - 0.5, (y - 0.5) * 0.72) < 0.2) continue;
546
+ stars.push({
547
+ x,
548
+ y,
549
+ r: 1.4 + rng() * 1.8,
550
+ color: THEME_CYCLE[(rng() * THEME_CYCLE.length) | 0],
551
+ phase: rng() * Math.PI * 2,
552
+ sparkle: rng() > 0.55,
553
+ });
554
+ }
555
+ const blinkers = [];
556
+ const blinkWant = 3 + ((rng() * 5) | 0);
557
+ for (let i = 0; i < blinkWant; i++) {
558
+ blinkers.push({
559
+ x: rng() < 0.5 ? 0.06 + rng() * 0.16 : 0.78 + rng() * 0.16,
560
+ y: rng() < 0.5 ? 0.07 + rng() * 0.18 : 0.72 + rng() * 0.2,
561
+ color: THEME_CYCLE[(rng() * 3) | 0],
562
+ onAnd: rng() > 0.42,
563
+ });
564
+ }
565
+ return {
566
+ id: `field-${stars.length}s${blinkers.length}b-${((rng() * 0xfffff) | 0).toString(16)}`,
567
+ stars,
568
+ blinkers,
569
+ grid: GRID_KINDS[(rng() * GRID_KINDS.length) | 0],
570
+ gradient: GRAD_KINDS[(rng() * GRAD_KINDS.length) | 0],
571
+ gridColor: THEME_CYCLE[(rng() * 3) | 0],
572
+ gradColor: THEME_CYCLE[(rng() * 3) | 0],
573
+ gradStrength: 0.22 + rng() * 0.16,
574
+ };
575
+ }
576
+
577
+ function rotate3(v, yaw, pitch, roll) {
578
+ const cy = Math.cos(yaw);
579
+ const sy = Math.sin(yaw);
580
+ const x1 = v[0] * cy + v[2] * sy;
581
+ const z1 = -v[0] * sy + v[2] * cy;
582
+ const cp = Math.cos(pitch);
583
+ const sp = Math.sin(pitch);
584
+ const y2 = v[1] * cp - z1 * sp;
585
+ const z2 = v[1] * sp + z1 * cp;
586
+ const cr = Math.cos(roll);
587
+ const sr = Math.sin(roll);
588
+ return [x1 * cr - y2 * sr, x1 * sr + y2 * cr, z2];
589
+ }
590
+
591
+ function projectMesh(mesh, width, height, t, checksum, scaleMul) {
592
+ const gait = mesh.gait || "tumble";
593
+ let yaw = t * mesh.spin + mesh.twist;
594
+ let pitch = Math.sin(t * mesh.spin * 0.42 + mesh.twist) * 0.52;
595
+ let roll = t * 0.38 + mesh.twist * 0.25;
596
+ const beat = beatPhase(checksum, t);
597
+ const kick = kickAccent(beat);
598
+ const and = andAccent(beat);
599
+ const phrase = phraseOf(checksum, t);
600
+ let breathe =
601
+ (scaleMul || 1) *
602
+ mesh.scale *
603
+ (1 + 0.07 * kick + 0.045 * and) *
604
+ phraseMix(phrase, 0.92, 1.06 + 0.08 * phrase.turnHit, 0.88);
605
+ yaw += phrase.turnHit * 0.32;
606
+ let ox = 0;
607
+ let oy = 0;
608
+ if (gait === "snap") {
609
+ const q = Math.floor(beat);
610
+ yaw = q * 1.15 + mesh.twist;
611
+ pitch = Math.sin(q * 1.7 + mesh.twist) * 0.46;
612
+ roll = q * 0.55 + mesh.twist * 0.3;
613
+ } else if (gait === "pulse") {
614
+ breathe *= 1 + mesh.warp * (kick + and * 0.65);
615
+ } else if (gait === "orbit") {
616
+ ox = Math.cos(beat * Math.PI * 2 + mesh.twist) * mesh.warp * 0.42;
617
+ oy = Math.sin(beat * Math.PI + mesh.twist) * mesh.warp * 0.26;
618
+ } else if (gait === "tumble") {
619
+ yaw = beat * mesh.spin + mesh.twist;
620
+ pitch = beat * mesh.spin * 0.38 + Math.sin(mesh.twist) * 0.2;
621
+ roll = beat * mesh.spin * 0.22 + mesh.twist;
622
+ }
623
+ const minSide = Math.min(width, height);
624
+ const cx = (width - 1) * 0.5 + ox * minSide;
625
+ const cy = (height - 1) * 0.5 + oy * minSide;
626
+ const shear = gait === "shear";
627
+ return mesh.verts.map((v) => {
628
+ let r = rotate3(v, yaw, pitch, roll);
629
+ if (shear) {
630
+ r = [
631
+ r[0] + r[1] * Math.sin(beat * Math.PI * 2 + mesh.twist) * mesh.warp * 1.55,
632
+ r[1] + r[2] * Math.cos(beat * Math.PI * 1.4) * mesh.warp,
633
+ r[2],
634
+ ];
635
+ }
636
+ const z = r[2] + 2.35;
637
+ const p = (breathe * minSide) / z;
638
+ return { x: cx + r[0] * p, y: cy + r[1] * p * 0.84, z: r[2] };
639
+ });
640
+ }
641
+
642
+ /**
643
+ * Checksum TLM → VisualConfig. Mirrors types/index.ts ChecksumResponse.visualConfig.
644
+ * Sequence notes + genre frequencies become CircleConfig[] (note, frequency, radius, color).
645
+ */
646
+ function resolveLookKind(opts) {
647
+ const raw = opts && opts.lookKind;
648
+ if (raw) {
649
+ if (!LOOK_KINDS.includes(raw)) {
650
+ const err = new Error(`unknown look "${raw}" (want ${LOOK_KINDS.join("|")})`);
651
+ err.code = "BLIP_LOOK";
652
+ throw err;
653
+ }
654
+ return raw;
655
+ }
656
+ return LOOK_KINDS[seedU32(opts && opts.seedHex, 0) % LOOK_KINDS.length];
657
+ }
658
+
659
+ function buildVisualConfig({ brief, seedHex, genre, width, height, lookKind }) {
660
+ const g = soundRippel.resolveGenre(genre || "ambient");
661
+ const scale = SCALES[g.id] || SCALES.ambient;
662
+ const rng = mulberry32(seedU32(seedHex, 0) ^ seedU32(seedHex, 8));
663
+ const text = String(brief || "factory-blip");
664
+ const count = 6 + (seedU32(seedHex, 16) % 4);
665
+ const circles = [];
666
+ const notes = [];
667
+ const durations = [];
668
+ const velocities = [];
669
+ const frequencies = [];
670
+ for (let i = 0; i < count; i++) {
671
+ const ch = text.charCodeAt(i % text.length) || 32;
672
+ const idx = (ch + Math.floor(rng() * scale.length) + i) % scale.length;
673
+ const frequency = scale[idx];
674
+ const velocity = 0.45 + rng() * 0.5;
675
+ const note = `${NOTE_NAMES[idx % NOTE_NAMES.length]}${3 + (i % 3)}`;
676
+ const radius = 28 + (220 / Math.max(frequency, 40)) * 36 + velocity * 18;
677
+ const color = rgbHex(THEME_CYCLE[i % THEME_CYCLE.length]);
678
+ circles.push({ note, frequency, radius, color });
679
+ notes.push(note);
680
+ durations.push("8n");
681
+ velocities.push(velocity);
682
+ frequencies.push(frequency);
683
+ }
684
+ return {
685
+ tlmCommand: TLM,
686
+ sequence: { notes, durations, velocities },
687
+ genreConfig: {
688
+ tempo: soundRippel.tempoFromSeed(g.id, seedHex),
689
+ phase0: 0,
690
+ instrument: g.voices[0],
691
+ frequencies,
692
+ scale: g.id,
693
+ },
694
+ visualConfig: {
695
+ circles,
696
+ canvas: { width: width || MOTION_WIDTH, height: height || MOTION_HEIGHT, fps: FPS },
697
+ tlmCommand: TLM,
698
+ },
699
+ gematria: {
700
+ promptValue: seedU32(seedHex, 0),
701
+ checksumValue: seedU32(seedHex, 8),
702
+ parity: (seedU32(seedHex, 0) & 1) === 0,
703
+ },
704
+ lookKind: resolveLookKind({ seedHex, lookKind }),
705
+ mesh: buildMesh(seedHex, text),
706
+ field: buildField(seedHex, text),
707
+ };
708
+ }
709
+
710
+ function cachedChecksum(opts) {
711
+ const lookKind = resolveLookKind(opts);
712
+ const key = `${opts.seedHex || ""}::${opts.brief || ""}::${opts.genre || "ambient"}::${opts.width || MOTION_WIDTH}x${opts.height || MOTION_HEIGHT}::${lookKind}`;
713
+ let hit = visualCache.get(key);
714
+ if (!hit) {
715
+ hit = buildVisualConfig({ ...opts, lookKind });
716
+ visualCache.set(key, hit);
717
+ }
718
+ return hit;
719
+ }
720
+
721
+ function fillVoid(buf) {
722
+ const v = THEME.void;
723
+ for (let i = 0; i < buf.length; i += 3) {
724
+ buf[i] = v[0];
725
+ buf[i + 1] = v[1];
726
+ buf[i + 2] = v[2];
727
+ }
728
+ }
729
+
730
+ function mixPixel(buf, width, x, y, color, alpha) {
731
+ if (alpha <= 0) return;
732
+ const xi = x | 0;
733
+ const yi = y | 0;
734
+ if (xi < 0 || yi < 0 || xi >= width) return;
735
+ const height = (buf.length / 3 / width) | 0;
736
+ if (yi >= height) return;
737
+ const i = (yi * width + xi) * 3;
738
+ const a = alpha > 1 ? 1 : alpha;
739
+ buf[i] = (buf[i] + (color[0] - buf[i]) * a + 0.5) | 0;
740
+ buf[i + 1] = (buf[i + 1] + (color[1] - buf[i + 1]) * a + 0.5) | 0;
741
+ buf[i + 2] = (buf[i + 2] + (color[2] - buf[i + 2]) * a + 0.5) | 0;
742
+ }
743
+
744
+ /**
745
+ * Soft falloff over the FULL radius. Confirmed CoS #67 look:
746
+ * hardness ~1.15–2.6 → every stamp is a glow, not a disc. Kept as a
747
+ * primitive; Rippel v2 painters use stampFocusDisc / paintSharpLine.
748
+ */
749
+ function stampDisc(buf, width, height, cx, cy, radius, color, hardness) {
750
+ if (radius <= 0) return;
751
+ const hard = hardness > 0 ? hardness : 2;
752
+ const x0 = Math.max(0, Math.floor(cx - radius));
753
+ const x1 = Math.min(width - 1, Math.ceil(cx + radius));
754
+ const y0 = Math.max(0, Math.floor(cy - radius));
755
+ const y1 = Math.min(height - 1, Math.ceil(cy + radius));
756
+ const r2 = radius * radius;
757
+ for (let y = y0; y <= y1; y++) {
758
+ const dy = y - cy;
759
+ const dy2 = dy * dy;
760
+ for (let x = x0; x <= x1; x++) {
761
+ const dx = x - cx;
762
+ const d2 = dx * dx + dy2;
763
+ if (d2 > r2) continue;
764
+ const u = 1 - Math.sqrt(d2) / radius;
765
+ const a = u <= 0 ? 0 : u >= 1 ? 1 : Math.pow(u, hard);
766
+ mixPixel(buf, width, x, y, color, a);
767
+ }
768
+ }
769
+ }
770
+
771
+ /**
772
+ * In-focus disc: opaque body + thin crisp rim + short glow tail.
773
+ * Not pow(u, ~1.2) across the whole radius (that is the Phase 1 bokeh).
774
+ */
775
+ function stampFocusDisc(buf, width, height, cx, cy, radius, color, opts) {
776
+ if (radius <= 0) return;
777
+ const rimW = opts && opts.rim != null ? opts.rim : 2;
778
+ const glowW = opts && opts.glow != null ? opts.glow : 5;
779
+ const glowA = opts && opts.glowAlpha != null ? opts.glowAlpha : 0.3;
780
+ const rimColor = (opts && opts.rimColor) || THEME.ink;
781
+ const outer = radius + glowW;
782
+ const x0 = Math.max(0, Math.floor(cx - outer));
783
+ const x1 = Math.min(width - 1, Math.ceil(cx + outer));
784
+ const y0 = Math.max(0, Math.floor(cy - outer));
785
+ const y1 = Math.min(height - 1, Math.ceil(cy + outer));
786
+ const bodyR = Math.max(0.5, radius - rimW);
787
+ for (let y = y0; y <= y1; y++) {
788
+ const dy = y - cy;
789
+ const dy2 = dy * dy;
790
+ for (let x = x0; x <= x1; x++) {
791
+ const dx = x - cx;
792
+ const d = Math.sqrt(dx * dx + dy2);
793
+ if (d <= bodyR) {
794
+ mixPixel(buf, width, x, y, color, 1);
795
+ continue;
796
+ }
797
+ if (d <= radius) {
798
+ const u = (radius - d) / Math.max(rimW, 1e-6);
799
+ mixPixel(buf, width, x, y, rimColor, 1);
800
+ mixPixel(buf, width, x, y, color, clamp(u, 0, 1));
801
+ continue;
802
+ }
803
+ if (d <= outer) {
804
+ const u = 1 - (d - radius) / glowW;
805
+ const a = glowA * Math.pow(clamp(u, 0, 1), 3.6);
806
+ mixPixel(buf, width, x, y, color, a);
807
+ }
808
+ }
809
+ }
810
+ }
811
+
812
+ function stampSegment(buf, width, height, x0, y0, x1, y1, radius, color, hardness) {
813
+ const dx = x1 - x0;
814
+ const dy = y1 - y0;
815
+ const len = Math.hypot(dx, dy);
816
+ const steps = Math.max(2, Math.ceil(len / Math.max(1, radius * 0.55)));
817
+ for (let i = 0; i <= steps; i++) {
818
+ const t = i / steps;
819
+ stampDisc(buf, width, height, x0 + dx * t, y0 + dy * t, radius, color, hardness);
820
+ }
821
+ }
822
+
823
+ function stampFocusSegment(buf, width, height, x0, y0, x1, y1, radius, color, opts) {
824
+ const dx = x1 - x0;
825
+ const dy = y1 - y0;
826
+ const len = Math.hypot(dx, dy);
827
+ const steps = Math.max(2, Math.ceil(len / Math.max(1.2, radius * 0.75)));
828
+ const focus = opts || { rim: 1, glow: 2, glowAlpha: 0.18, rimColor: THEME.ink };
829
+ for (let i = 0; i <= steps; i++) {
830
+ const u = i / steps;
831
+ stampFocusDisc(buf, width, height, x0 + dx * u, y0 + dy * u, radius, color, focus);
832
+ }
833
+ }
834
+
835
+ function paintSharpRibbon(buf, width, height, yAtX, color, half, rimColor) {
836
+ const rim = rimColor || THEME.ink;
837
+ const thick = Math.max(1, half);
838
+ for (let x = 0; x < width; x++) {
839
+ const y = yAtX(x);
840
+ for (let d = -thick; d <= thick; d++) {
841
+ mixPixel(buf, width, x, y + d, color, 1);
842
+ }
843
+ mixPixel(buf, width, x, y - thick - 1, rim, 1);
844
+ mixPixel(buf, width, x, y + thick + 1, rim, 1);
845
+ }
846
+ }
847
+
848
+ function visualizationFor(renderer) {
849
+ return ANIMATION_TO_VISUALIZATION[renderer] || null;
850
+ }
851
+
852
+ function circlePulse(circle, t) {
853
+ const hz = Math.max(20, circle.frequency);
854
+ const lfo = Math.sin(2 * Math.PI * (hz / 220) * t);
855
+ const overtone = Math.sin(2 * Math.PI * (hz / 110) * t + 0.7);
856
+ return circle.radius * (0.7 + 0.22 * (0.5 + 0.5 * lfo) + 0.08 * overtone);
857
+ }
858
+
859
+ function beatPhase(checksum, t) {
860
+ const bpm = (checksum.genreConfig && checksum.genreConfig.tempo) || 90;
861
+ const phase0 = (checksum.genreConfig && checksum.genreConfig.phase0) || 0;
862
+ return (t * bpm) / 60 + phase0;
863
+ }
864
+
865
+ /** Soft kick swell — scale only, never a full-field color gate (photosensitive). */
866
+ function kickAccent(beat) {
867
+ const frac = beat - Math.floor(beat);
868
+ if (frac < 0.12) return 0.55 * (1 - frac / 0.12);
869
+ if (frac < 0.28) return 0.18 * (1 - (frac - 0.12) / 0.16);
870
+ return 0;
871
+ }
872
+
873
+ /** Off-beat (the AND) — same grid as the bed hat/cowbell. Scale only. */
874
+ function andAccent(beat) {
875
+ const frac = beat - Math.floor(beat);
876
+ const d = Math.abs(frac - 0.5);
877
+ if (d < 0.1) return 0.45 * (1 - d / 0.1);
878
+ return 0;
879
+ }
880
+
881
+ function phraseOf(checksum, t) {
882
+ const tempo = (checksum && checksum.genreConfig && checksum.genreConfig.tempo) || 90;
883
+ const seconds =
884
+ (checksum &&
885
+ checksum.visualConfig &&
886
+ checksum.visualConfig.canvas &&
887
+ checksum.visualConfig.canvas.duration) ||
888
+ 4.44;
889
+ return soundRippel.shortformPhrase(t, seconds, { beatSec: 60 / tempo });
890
+ }
891
+
892
+ function phraseWeight(phrase, key) {
893
+ const ease = phrase && phrase[`${key}Ease`];
894
+ if (typeof ease === "number") return ease;
895
+ return (phrase && phrase[key]) || 0;
896
+ }
897
+
898
+ function phraseMix(phrase, hookV, turnV, tagV) {
899
+ return (
900
+ hookV * phraseWeight(phrase, "hook") +
901
+ turnV * phraseWeight(phrase, "turn") +
902
+ tagV * phraseWeight(phrase, "tag")
903
+ );
904
+ }
905
+
906
+ function mixRgb(a, b, amount) {
907
+ const u = clamp(amount, 0, 1);
908
+ return [
909
+ (a[0] + (b[0] - a[0]) * u + 0.5) | 0,
910
+ (a[1] + (b[1] - a[1]) * u + 0.5) | 0,
911
+ (a[2] + (b[2] - a[2]) * u + 0.5) | 0,
912
+ ];
913
+ }
914
+
915
+ /** Slow frequency wander (~0.3–0.8 Hz). Not a hard gold flash. */
916
+ function freqTint(circle, t) {
917
+ const hz = Math.max(20, circle.frequency);
918
+ return 0.22 + 0.28 * (0.5 + 0.5 * Math.sin(2 * Math.PI * (hz / 1100) * t));
919
+ }
920
+
921
+ function paintSharpLine(buf, width, height, x0, y0, x1, y1, color, half, rimColor) {
922
+ const rim = rimColor || THEME.ink;
923
+ const thick = Math.max(1, half);
924
+ const dx = x1 - x0;
925
+ const dy = y1 - y0;
926
+ const len = Math.hypot(dx, dy);
927
+ if (len < 0.5) {
928
+ stampFocusDisc(buf, width, height, x0, y0, thick + 1, color, {
929
+ rim: 1,
930
+ glow: 2,
931
+ glowAlpha: 0.16,
932
+ rimColor: rim,
933
+ });
934
+ return;
935
+ }
936
+ const steps = Math.ceil(len);
937
+ const nx = -dy / len;
938
+ const ny = dx / len;
939
+ for (let i = 0; i <= steps; i++) {
940
+ const u = i / steps;
941
+ const x = x0 + dx * u;
942
+ const y = y0 + dy * u;
943
+ for (let d = -thick; d <= thick; d++) {
944
+ mixPixel(buf, width, x + nx * d, y + ny * d, color, 1);
945
+ }
946
+ mixPixel(buf, width, x + nx * (thick + 1), y + ny * (thick + 1), rim, 1);
947
+ mixPixel(buf, width, x - nx * (thick + 1), y - ny * (thick + 1), rim, 1);
948
+ }
949
+ }
950
+
951
+ function fillTri(buf, width, height, a, b, c, color, alpha) {
952
+ if (alpha <= 0) return;
953
+ const minX = Math.max(0, Math.floor(Math.min(a.x, b.x, c.x)));
954
+ const maxX = Math.min(width - 1, Math.ceil(Math.max(a.x, b.x, c.x)));
955
+ const minY = Math.max(0, Math.floor(Math.min(a.y, b.y, c.y)));
956
+ const maxY = Math.min(height - 1, Math.ceil(Math.max(a.y, b.y, c.y)));
957
+ if (maxX - minX > 420 || maxY - minY > 320) return;
958
+ const area = (b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y);
959
+ if (Math.abs(area) < 8) return;
960
+ const a0 = alpha * (area > 0 ? 1 : 0.38);
961
+ for (let y = minY; y <= maxY; y++) {
962
+ for (let x = minX; x <= maxX; x++) {
963
+ const w0 = (b.x - x) * (c.y - y) - (c.x - x) * (b.y - y);
964
+ const w1 = (c.x - x) * (a.y - y) - (a.x - x) * (c.y - y);
965
+ const w2 = (a.x - x) * (b.y - y) - (b.x - x) * (a.y - y);
966
+ if ((w0 >= 0 && w1 >= 0 && w2 >= 0) || (w0 <= 0 && w1 <= 0 && w2 <= 0)) {
967
+ mixPixel(buf, width, x, y, color, a0);
968
+ }
969
+ }
970
+ }
971
+ }
972
+
973
+ function meshAccent(mesh, t) {
974
+ const cuts = mesh.cuts || 3;
975
+ const phase = ((t / 4.44) * cuts + (mesh.accentIndex || 0)) % LIGHT_CYCLE.length;
976
+ const i = phase | 0;
977
+ return mixRgb(LIGHT_CYCLE[i], LIGHT_CYCLE[(i + 1) % LIGHT_CYCLE.length], phase - i);
978
+ }
979
+
980
+ function iridesce(u, t, beat, accent) {
981
+ const cycle = [THEME.cyan, accent || THEME.gold, THEME.gold, THEME.blue];
982
+ const phase = ((u * 0.94 + beat * 0.06 + t * 0.035) % 1 + 1) % 1;
983
+ const p = phase * (cycle.length - 1);
984
+ const i = p | 0;
985
+ const f = p - i;
986
+ return mixRgb(cycle[i], cycle[i + 1] || cycle[cycle.length - 1], f);
987
+ }
988
+
989
+ function livingShade(mesh, t, u, beat, bias) {
990
+ const c = iridesce(u, t, beat, meshAccent(mesh, t));
991
+ return bias ? mixRgb(c, bias, 0.08) : c;
992
+ }
993
+
994
+ /** Hairline Wu stroke: 1px core, coverage AA as the only glow. Gradient via shader(u). */
995
+ function paintGlowLine(buf, width, height, x0, y0, x1, y1, color, opts) {
996
+ const shader = opts && opts.shader;
997
+ const glowA = opts && opts.glowAlpha != null ? opts.glowAlpha : 0.08;
998
+ let ax = x0;
999
+ let ay = y0;
1000
+ let bx = x1;
1001
+ let by = y1;
1002
+ const steep = Math.abs(by - ay) > Math.abs(bx - ax);
1003
+ if (steep) {
1004
+ const sx = ax;
1005
+ ax = ay;
1006
+ ay = sx;
1007
+ const ex = bx;
1008
+ bx = by;
1009
+ by = ex;
1010
+ }
1011
+ if (ax > bx) {
1012
+ const sx = ax;
1013
+ ax = bx;
1014
+ bx = sx;
1015
+ const sy = ay;
1016
+ ay = by;
1017
+ by = sy;
1018
+ }
1019
+ const wdx = bx - ax;
1020
+ const wdy = by - ay;
1021
+ const grad = wdx === 0 ? 0 : wdy / wdx;
1022
+ function plot(px, py, a, u) {
1023
+ if (a <= 0.03) return;
1024
+ const c = shader ? shader(u) : color;
1025
+ if (steep) mixPixel(buf, width, py, px, c, a);
1026
+ else mixPixel(buf, width, px, py, c, a);
1027
+ }
1028
+ let y = ay;
1029
+ const x0i = Math.round(ax);
1030
+ const x1i = Math.round(bx);
1031
+ const span = x1i - x0i || 1;
1032
+ for (let x = x0i; x <= x1i; x++) {
1033
+ const u = (x - x0i) / span;
1034
+ const yi = Math.floor(y);
1035
+ const f = y - yi;
1036
+ plot(x, yi, 1, u);
1037
+ plot(x, yi + 1, f * 0.35 + glowA, u);
1038
+ y += grad;
1039
+ }
1040
+ }
1041
+
1042
+ function paintMeshFaces(buf, width, height, mesh, pts, color, alpha) {
1043
+ if (!mesh.faces || !mesh.faces.length || alpha <= 0) return;
1044
+ const ranked = mesh.faces
1045
+ .map((f) => {
1046
+ const a = pts[f[0]];
1047
+ const b = pts[f[1]];
1048
+ const c = pts[f[2]];
1049
+ return { a, b, c, z: (a.z + b.z + c.z) / 3 };
1050
+ })
1051
+ .sort((p, q) => p.z - q.z);
1052
+ for (let i = 0; i < ranked.length; i++) {
1053
+ fillTri(buf, width, height, ranked[i].a, ranked[i].b, ranked[i].c, color, alpha);
1054
+ }
1055
+ }
1056
+
1057
+ function paintMesh(buf, width, height, mesh, pts, color, half, opts) {
1058
+ const t = (opts && opts.t) || 0;
1059
+ const checksum = (opts && opts.checksum) || { genreConfig: { tempo: 90 } };
1060
+ const beat = beatPhase(checksum, t);
1061
+ const kick = kickAccent(beat);
1062
+ const and = andAccent(beat);
1063
+ const fillA = opts && opts.fill != null ? opts.fill : 0;
1064
+ if (fillA > 0) paintMeshFaces(buf, width, height, mesh, pts, color, fillA);
1065
+ const ranked = mesh.edges
1066
+ .map((e, i) => ({ e, i, z: (pts[e[0]].z + pts[e[1]].z) * 0.5 }))
1067
+ .sort((a, b) => a.z - b.z);
1068
+ for (let i = 0; i < ranked.length; i++) {
1069
+ const [a, b] = ranked[i].e;
1070
+ const bias = color || null;
1071
+ paintGlowLine(buf, width, height, pts[a].x, pts[a].y, pts[b].x, pts[b].y, THEME.cyan, {
1072
+ glowAlpha: 0.07 + 0.03 * kick,
1073
+ shader: (u) => livingShade(mesh, t, u, beat, bias),
1074
+ });
1075
+ }
1076
+ if (ranked.length) {
1077
+ const hot = ranked[0];
1078
+ const [a, b] = hot.e;
1079
+ const life = (beat * 0.7 + mesh.twist) % 1;
1080
+ mixPixel(
1081
+ buf,
1082
+ width,
1083
+ pts[a].x + (pts[b].x - pts[a].x) * life,
1084
+ pts[a].y + (pts[b].y - pts[a].y) * life,
1085
+ livingShade(mesh, t, life, beat, THEME.gold),
1086
+ 0.85 + 0.15 * and,
1087
+ );
1088
+ }
1089
+ }
1090
+
1091
+ function paintChecksumMesh(buf, width, height, t, checksum, opts) {
1092
+ const mesh = checksum.mesh;
1093
+ if (!mesh) return null;
1094
+ const scale = (opts && opts.scale) || 1;
1095
+ const half = (opts && opts.half) || 1;
1096
+ const pts = projectMesh(mesh, width, height, t, checksum, scale);
1097
+ paintMesh(buf, width, height, mesh, pts, opts && opts.color, half, {
1098
+ fill: 0,
1099
+ t,
1100
+ checksum,
1101
+ });
1102
+ return { mesh, pts, dual: null };
1103
+ }
1104
+
1105
+ function paintMeshOverlay(buf, width, height, opts) {
1106
+ const checksum = cachedChecksum({
1107
+ brief: opts.brief,
1108
+ seedHex: opts.seedHex,
1109
+ genre: opts.genre,
1110
+ width,
1111
+ height,
1112
+ lookKind: opts.lookKind,
1113
+ });
1114
+ paintField(buf, width, height, opts.t || 0, checksum);
1115
+ return paintChecksumMesh(buf, width, height, opts.t || 0, checksum, {
1116
+ scale: 0.72,
1117
+ half: 1,
1118
+ });
1119
+ }
1120
+
1121
+ function paintGradient(buf, width, height, field, t) {
1122
+ const aCol = field.gradColor || THEME.blue;
1123
+ const bCol = mixRgb(THEME.gold, THEME.cyan, 0.45 + 0.2 * Math.sin((t || 0) * 0.7));
1124
+ const s = field.gradStrength || 0.2;
1125
+ if (field.gradient === "horizon") {
1126
+ const y0 = (height * 0.58) | 0;
1127
+ for (let y = y0; y < height; y++) {
1128
+ const u = (y - y0) / Math.max(1, height - y0);
1129
+ const c = mixRgb(aCol, bCol, u);
1130
+ const a = s * (0.35 + 0.65 * u);
1131
+ for (let x = 0; x < width; x += 1) mixPixel(buf, width, x, y, c, a);
1132
+ }
1133
+ return;
1134
+ }
1135
+ if (field.gradient === "corner") {
1136
+ const cx = field.stars[0] ? field.stars[0].x * width : width * 0.12;
1137
+ const cy = field.stars[0] ? field.stars[0].y * height : height * 0.18;
1138
+ const reach = Math.min(width, height) * 0.72;
1139
+ const x0 = Math.max(0, (cx - reach) | 0);
1140
+ const x1 = Math.min(width - 1, (cx + reach) | 0);
1141
+ const y0 = Math.max(0, (cy - reach) | 0);
1142
+ const y1 = Math.min(height - 1, (cy + reach) | 0);
1143
+ for (let y = y0; y <= y1; y++) {
1144
+ for (let x = x0; x <= x1; x++) {
1145
+ const d = Math.hypot(x - cx, y - cy) / reach;
1146
+ if (d >= 1) continue;
1147
+ const fade = (1 - d) * (1 - d);
1148
+ mixPixel(buf, width, x, y, mixRgb(aCol, bCol, fade), s * fade);
1149
+ }
1150
+ }
1151
+ return;
1152
+ }
1153
+ const y1 = (height * 0.28) | 0;
1154
+ for (let y = 0; y < y1; y++) {
1155
+ const u = 1 - y / y1;
1156
+ const c = mixRgb(THEME.cyan, aCol, 0.35 + 0.4 * u);
1157
+ for (let x = 0; x < width; x += 1) mixPixel(buf, width, x, y, c, s * u);
1158
+ }
1159
+ }
1160
+
1161
+ function paintGrid(buf, width, height, field, t, checksum) {
1162
+ if (!field.grid || field.grid === "none") return;
1163
+ const beat = beatPhase(checksum || { genreConfig: { tempo: 90 } }, t || 0);
1164
+ const accent = field.gridColor || THEME.cyan;
1165
+ const line = (x0, y0, x1, y1) =>
1166
+ paintGlowLine(buf, width, height, x0, y0, x1, y1, accent, {
1167
+ glowAlpha: 0.07,
1168
+ shader: (u) => iridesce(u, t || 0, beat, accent),
1169
+ });
1170
+ const cx = (width - 1) * 0.5;
1171
+ if (field.grid === "ticks") {
1172
+ for (let i = 0; i < 9; i++) {
1173
+ const x = ((i + 1) / 10) * width;
1174
+ line(x, 8, x, 28);
1175
+ line(x, height - 28, x, height - 8);
1176
+ }
1177
+ for (let i = 0; i < 5; i++) {
1178
+ const y = ((i + 1) / 6) * height;
1179
+ line(8, y, 28, y);
1180
+ line(width - 28, y, width - 8, y);
1181
+ }
1182
+ return;
1183
+ }
1184
+ if (field.grid === "meridian") {
1185
+ line(28, 28, width - 28, 28);
1186
+ line(28, height - 28, width - 28, height - 28);
1187
+ line(28, 28, 28, height - 28);
1188
+ line(width - 28, 28, width - 28, height - 28);
1189
+ const inset = width * 0.17;
1190
+ line(inset, 40, inset * 0.82, height - 40);
1191
+ line(width - inset, 40, width - inset * 0.82, height - 40);
1192
+ return;
1193
+ }
1194
+ const vanishY = height * 0.64;
1195
+ const floorY = height * 0.76;
1196
+ line(0, floorY, width, floorY);
1197
+ for (let i = -4; i <= 4; i++) {
1198
+ if (i === 0) continue;
1199
+ line(cx + i * width * 0.05, vanishY, cx + i * width * 0.26, height - 6);
1200
+ }
1201
+ for (let k = 1; k <= 3; k++) {
1202
+ const y = floorY + (height - 8 - floorY) * (k / 4);
1203
+ const span = width * (0.24 + k * 0.14);
1204
+ line(cx - span, y, cx + span, y);
1205
+ }
1206
+ }
1207
+
1208
+ function paintField(buf, width, height, t, checksum) {
1209
+ const field = checksum.field;
1210
+ if (!field) return;
1211
+ const beat = beatPhase(checksum, t);
1212
+ const kick = kickAccent(beat);
1213
+ const and = andAccent(beat);
1214
+ paintGradient(buf, width, height, field, t);
1215
+ paintGrid(buf, width, height, field, t, checksum);
1216
+ const stars = field.stars || [];
1217
+ for (let i = 0; i < stars.length; i++) {
1218
+ const star = stars[i];
1219
+ const twinkle = 0.42 + 0.5 * (0.5 + 0.5 * Math.sin(beat * Math.PI * 2 + star.phase));
1220
+ const sx = star.x * width;
1221
+ const sy = star.y * height;
1222
+ const color = iridesce(star.phase, t, beat, star.color);
1223
+ mixPixel(buf, width, sx, sy, color, twinkle);
1224
+ mixPixel(buf, width, sx + 1, sy, color, twinkle * 0.35);
1225
+ mixPixel(buf, width, sx, sy + 1, color, twinkle * 0.35);
1226
+ }
1227
+ const blinkers = field.blinkers || [];
1228
+ for (let i = 0; i < blinkers.length; i++) {
1229
+ const b = blinkers[i];
1230
+ const on = b.onAnd ? and : kick;
1231
+ if (on < 0.08) continue;
1232
+ stampFocusDisc(buf, width, height, b.x * width, b.y * height, 1.8 + on * 1.4, b.color, {
1233
+ rim: 1,
1234
+ glow: 2,
1235
+ glowAlpha: 0.16,
1236
+ rimColor: THEME.ink,
1237
+ });
1238
+ }
1239
+ }
1240
+
1241
+ function startFrame(buf, width, height, t, checksum) {
1242
+ fillVoid(buf);
1243
+ paintField(buf, width, height, t, checksum);
1244
+ }
1245
+
1246
+ function layoutRings(circles, width, height, t, checksum) {
1247
+ const cx = (width - 1) * 0.5;
1248
+ const cy = (height - 1) * 0.5;
1249
+ const minSide = Math.min(width, height);
1250
+ const beat = beatPhase(checksum, t);
1251
+ const scramble = mulberry32(
1252
+ ((checksum.gematria && checksum.gematria.promptValue) || 1) ^
1253
+ ((checksum.gematria && checksum.gematria.checksumValue) || 1) ^
1254
+ 0x9e3779b9,
1255
+ );
1256
+ return circles.map((circle, i) => {
1257
+ const inner = i % 2 === 0;
1258
+ const phase = scramble() * Math.PI * 2;
1259
+ const ecc = 0.62 + scramble() * 0.22;
1260
+ const drift = 0.85 + scramble() * 0.7;
1261
+ const spin = inner ? -t * 3.6 * drift - beat * 0.22 : t * 2.3 * drift + beat * 0.14;
1262
+ const ang = (i / circles.length) * Math.PI * 2 + spin + phase;
1263
+ const wobble = Math.sin(beat * Math.PI * 2 + phase) * minSide * 0.007;
1264
+ const orbit = minSide * (inner ? 0.18 + scramble() * 0.05 : 0.29 + scramble() * 0.05) + wobble + (circle.frequency / 2000) * minSide * 0.04;
1265
+ return {
1266
+ circle,
1267
+ inner,
1268
+ x: cx + Math.cos(ang) * orbit,
1269
+ y: cy + Math.sin(ang) * orbit * ecc,
1270
+ r: circlePulse(circle, t + phase * 0.2),
1271
+ color: parseHex(circle.color),
1272
+ };
1273
+ });
1274
+ }
1275
+
1276
+ function layoutRing(circles, width, height, t, checksum) {
1277
+ return layoutRings(circles, width, height, t, checksum || { genreConfig: { tempo: 90 } });
1278
+ }
1279
+
1280
+ /** Lost sharp-dogfood ring: two orbital bands, stampFocusDisc satellites, beat-locked spin. */
1281
+ function layoutFocusRing(circles, width, height, t, checksum) {
1282
+ const cx = (width - 1) * 0.5;
1283
+ const cy = (height - 1) * 0.5;
1284
+ const minSide = Math.min(width, height);
1285
+ const beat = beatPhase(checksum, t);
1286
+ const phrase = phraseOf(checksum, t);
1287
+ const spin = t * phraseMix(phrase, 0.22, 0.52, 0.16) + beat * Math.PI * 0.12;
1288
+ const orbitMul = phraseMix(phrase, 0.8, 1.08 + phrase.turnHit * 0.1, 0.64);
1289
+ const rMul = phraseMix(phrase, 0.42, 0.42, 0.3);
1290
+ return circles.map((circle, i) => {
1291
+ const ang = (i / circles.length) * Math.PI * 2 + spin;
1292
+ const orbit = minSide * (0.16 + (i % 3) * 0.07) * orbitMul;
1293
+ return {
1294
+ circle,
1295
+ x: cx + Math.cos(ang) * orbit,
1296
+ y: cy + Math.sin(ang) * orbit * 0.72,
1297
+ r: circlePulse(circle, t + i * 0.11) * (rMul / 0.42),
1298
+ color: parseHex(circle.color),
1299
+ };
1300
+ });
1301
+ }
1302
+
1303
+ function paintFocusSatellites(buf, width, height, t, checksum) {
1304
+ if (!checksum || checksum.lookKind !== "focus") return;
1305
+ const circles = checksum.visualConfig && checksum.visualConfig.circles;
1306
+ if (!circles || !circles.length) return;
1307
+ for (const placed of layoutFocusRing(circles, width, height, t, checksum)) {
1308
+ stampFocusDisc(buf, width, height, placed.x, placed.y, placed.r * 0.42, placed.color, {
1309
+ rim: 1.6,
1310
+ glow: 4,
1311
+ glowAlpha: 0.24,
1312
+ rimColor: THEME.ink,
1313
+ });
1314
+ }
1315
+ }
1316
+
1317
+ /** Field under focus: gradient + stars + blinkers. No grid through the disc. */
1318
+ function paintFocusField(buf, width, height, t, checksum) {
1319
+ const field = checksum && checksum.field;
1320
+ if (!field) return;
1321
+ paintGradient(buf, width, height, field, t);
1322
+ const beat = beatPhase(checksum, t);
1323
+ const kick = kickAccent(beat);
1324
+ const and = andAccent(beat);
1325
+ const stars = field.stars || [];
1326
+ for (let i = 0; i < stars.length; i++) {
1327
+ const star = stars[i];
1328
+ const twinkle = 0.42 + 0.5 * (0.5 + 0.5 * Math.sin(beat * Math.PI * 2 + star.phase));
1329
+ const sx = star.x * width;
1330
+ const sy = star.y * height;
1331
+ const color = iridesce(star.phase, t, beat, star.color);
1332
+ mixPixel(buf, width, sx, sy, color, twinkle);
1333
+ mixPixel(buf, width, sx + 1, sy, color, twinkle * 0.35);
1334
+ mixPixel(buf, width, sx, sy + 1, color, twinkle * 0.35);
1335
+ }
1336
+ const blinkers = field.blinkers || [];
1337
+ for (let i = 0; i < blinkers.length; i++) {
1338
+ const b = blinkers[i];
1339
+ const on = b.onAnd ? and : kick;
1340
+ if (on < 0.08) continue;
1341
+ stampFocusDisc(buf, width, height, b.x * width, b.y * height, 1.8 + on * 1.4, b.color, {
1342
+ rim: 1,
1343
+ glow: 2,
1344
+ glowAlpha: 0.16,
1345
+ rimColor: THEME.ink,
1346
+ });
1347
+ }
1348
+ }
1349
+
1350
+ /** Mesh fingerprint as solid mass — verts only, off the equator so orbFocusWidth stays honest. */
1351
+ function paintFocusMeshMass(buf, width, height, t, checksum) {
1352
+ const mesh = checksum && checksum.mesh;
1353
+ if (!mesh || !mesh.verts || !mesh.verts.length) return;
1354
+ const pts = projectMesh(mesh, width, height, t, checksum, 0.78);
1355
+ const cx = (width - 1) * 0.5;
1356
+ const cy = (height - 1) * 0.5;
1357
+ const keep = Math.min(width, height) * 0.16;
1358
+ for (let i = 0; i < pts.length; i++) {
1359
+ const p = pts[i];
1360
+ if (Math.abs(p.y - cy) < keep * 0.38 && Math.abs(p.x - cx) < keep * 1.15) continue;
1361
+ const color = THEME_CYCLE[((mesh.accentIndex || 0) + i) % THEME_CYCLE.length];
1362
+ stampFocusDisc(buf, width, height, p.x, p.y, 3.6 + (i % 3) * 0.8, color, {
1363
+ rim: 1.1,
1364
+ glow: 2.6,
1365
+ glowAlpha: 0.18,
1366
+ rimColor: THEME.ink,
1367
+ });
1368
+ }
1369
+ }
1370
+
1371
+ /** orb focus — cyan disc + gold pupil + satellites. Field + mesh mass carry the mint id. */
1372
+ function paintFocusOrb(buf, width, height, t, checksum) {
1373
+ fillVoid(buf);
1374
+ paintFocusField(buf, width, height, t, checksum);
1375
+ paintFocusMeshMass(buf, width, height, t, checksum);
1376
+ const cx = (width - 1) * 0.5;
1377
+ const cy = (height - 1) * 0.5;
1378
+ const minSide = Math.min(width, height);
1379
+ const phrase = phraseOf(checksum, t);
1380
+ const mesh = checksum && checksum.mesh;
1381
+ const style = (mesh && mesh.coreStyle) || "disc";
1382
+ const pulse = style === "pulse" ? 0.012 : 0;
1383
+ const core =
1384
+ minSide *
1385
+ (0.11 +
1386
+ 0.018 * Math.sin(t * 1.7) +
1387
+ 0.018 * phrase.turnHit +
1388
+ 0.01 * phraseWeight(phrase, "tag") +
1389
+ pulse);
1390
+ stampFocusDisc(buf, width, height, cx, cy, core * 1.08, THEME.cyan, {
1391
+ rim: 2.2,
1392
+ glow: 7,
1393
+ glowAlpha: 0.28,
1394
+ rimColor: THEME.ink,
1395
+ });
1396
+ stampFocusDisc(buf, width, height, cx, cy, core * 0.4, THEME.gold, {
1397
+ rim: 1.6,
1398
+ glow: 3,
1399
+ glowAlpha: 0.22,
1400
+ rimColor: THEME.gold,
1401
+ });
1402
+ paintFocusSatellites(buf, width, height, t, checksum);
1403
+ }
1404
+
1405
+ /** orb → canvas / Orb Glow v2. Seed look: focus (disc satellites) or cage (Wu + field). */
1406
+ function paintCanvas(buf, width, height, t, checksum) {
1407
+ if (checksum.lookKind === "focus") {
1408
+ return paintFocusOrb(buf, width, height, t, checksum);
1409
+ }
1410
+ startFrame(buf, width, height, t, checksum);
1411
+ paintChecksumMesh(buf, width, height, t, checksum, {
1412
+ scale: 0.95,
1413
+ half: 1,
1414
+ noFill: true,
1415
+ });
1416
+ const cx = (width - 1) * 0.5;
1417
+ const cy = (height - 1) * 0.5;
1418
+ const minSide = Math.min(width, height);
1419
+ const beat = beatPhase(checksum, t);
1420
+ const nucleus = paintOrbNucleus(buf, width, height, cx, cy, minSide, beat, checksum.mesh, checksum);
1421
+ const tickR = nucleus.radius;
1422
+ const tickA = beat * Math.PI * 2;
1423
+ stampFocusDisc(
1424
+ buf,
1425
+ width,
1426
+ height,
1427
+ cx + Math.cos(tickA) * tickR,
1428
+ cy + Math.sin(tickA) * tickR,
1429
+ 5,
1430
+ THEME.gold,
1431
+ { rim: 1.2, glow: 3, glowAlpha: 0.2, rimColor: THEME.ink },
1432
+ );
1433
+ const ghostA = tickA - 0.55;
1434
+ stampFocusDisc(
1435
+ buf,
1436
+ width,
1437
+ height,
1438
+ cx + Math.cos(ghostA) * tickR,
1439
+ cy + Math.sin(ghostA) * tickR,
1440
+ 3,
1441
+ THEME.ink,
1442
+ { rim: 1, glow: 2, glowAlpha: 0.12, rimColor: THEME.ink },
1443
+ );
1444
+ }
1445
+
1446
+ /** Orb-only nucleus. Other viz do not wear this bullseye. Color cuts + size on the grid; seed picks disc/eclipse/pulse. */
1447
+ function paintOrbNucleus(buf, width, height, cx, cy, minSide, beat, mesh, checksum) {
1448
+ const kick = kickAccent(beat);
1449
+ const and = andAccent(beat);
1450
+ const style = (mesh && mesh.coreStyle) || "disc";
1451
+ const swell = style === "pulse" ? 0.55 + 0.55 * kick + 0.35 * and : 0.5 + 0.35 * kick + 0.22 * and;
1452
+ const core = minSide * (style === "pulse" ? 0.092 + 0.028 * swell : 0.1 + 0.014 * swell);
1453
+ const t = checksum && checksum.genreConfig ? (beat * 60) / (checksum.genreConfig.tempo || 90) : beat;
1454
+ const outer = mixRgb(THEME.cyan, (mesh && meshAccent(mesh, t)) || THEME.gold, 0.28 + 0.45 * and);
1455
+ const inner = mixRgb(THEME.gold, THEME.cyan, 0.18 + 0.62 * and);
1456
+ stampFocusDisc(buf, width, height, cx, cy, core * 1.08, outer, {
1457
+ rim: 2.2,
1458
+ glow: 5,
1459
+ glowAlpha: 0.18,
1460
+ rimColor: THEME.ink,
1461
+ });
1462
+ const ix = style === "eclipse" ? cx + Math.cos(beat * Math.PI * 2) * core * 0.22 : cx;
1463
+ const iy = style === "eclipse" ? cy + Math.sin(beat * Math.PI) * core * 0.12 : cy;
1464
+ stampFocusDisc(buf, width, height, ix, iy, core * (style === "eclipse" ? 0.48 : 0.4), inner, {
1465
+ rim: 1.6,
1466
+ glow: 5,
1467
+ glowAlpha: 0.28,
1468
+ rimColor: THEME.ink,
1469
+ });
1470
+ return { radius: core * 1.08, style };
1471
+ }
1472
+
1473
+ /** Solid cyan/gold disc from center, then short rim. Mesh edges past the disc are not the body. */
1474
+ function orbFocusWidth(buf, width, height) {
1475
+ const cx = (width - 1) * 0.5;
1476
+ const cy = ((buf.length / 3 / width) | 0) * 0.5;
1477
+ const y = cy | 0;
1478
+ function sample(x) {
1479
+ const i = (y * width + (x | 0)) * 3;
1480
+ return [buf[i], buf[i + 1], buf[i + 2]];
1481
+ }
1482
+ function luma(x) {
1483
+ const [r, g, b] = sample(x);
1484
+ return (r * 0.3 + g * 0.59 + b * 0.11) / 255;
1485
+ }
1486
+ function isBody(x) {
1487
+ const [r, g, b] = sample(x);
1488
+ const cyan = g > 160 && b > 160 && r < 160;
1489
+ const gold = r > 180 && g > 140 && b < 110;
1490
+ const ink = r > 200 && g > 200 && b > 200;
1491
+ return cyan || gold || ink;
1492
+ }
1493
+ const peak = luma(cx);
1494
+ let hi = cx;
1495
+ for (let x = cx; x < width; x++) {
1496
+ if (isBody(x)) hi = x;
1497
+ else break;
1498
+ }
1499
+ let lo = hi;
1500
+ for (let x = hi; x < width; x++) {
1501
+ if (luma(x) <= 0.12) {
1502
+ lo = x;
1503
+ break;
1504
+ }
1505
+ if (!isBody(x)) {
1506
+ lo = x;
1507
+ break;
1508
+ }
1509
+ lo = x;
1510
+ }
1511
+ return { peak, inner: hi - cx, drop: lo - hi };
1512
+ }
1513
+
1514
+ /** swirl → 3d-sacred v2. Seed mesh is the sacred body — lines, not vertex beads. */
1515
+ function paintSacred(buf, width, height, t, checksum) {
1516
+ startFrame(buf, width, height, t, checksum);
1517
+ paintChecksumMesh(buf, width, height, t, checksum, {
1518
+ scale: 0.92,
1519
+ half: 1,
1520
+ });
1521
+ paintFocusSatellites(buf, width, height, t, checksum);
1522
+ }
1523
+
1524
+ /** snap → neural v2. Dual-ring lattice, hub, skip-links, frequency + beat pulses. */
1525
+ function paintNeural(buf, width, height, t, checksum) {
1526
+ startFrame(buf, width, height, t, checksum);
1527
+ const cx = (width - 1) * 0.5;
1528
+ const cy = (height - 1) * 0.5;
1529
+ const beat = beatPhase(checksum, t);
1530
+ const kick = kickAccent(beat);
1531
+ const worn = paintChecksumMesh(buf, width, height, t, checksum, {
1532
+ scale: 0.9,
1533
+ half: 1,
1534
+ });
1535
+ const pts = (worn && worn.pts) || [];
1536
+ const mesh = checksum.mesh;
1537
+ const node = { rim: 1.4, glow: 3, glowAlpha: 0.18, rimColor: THEME.ink };
1538
+ if (mesh && pts.length) {
1539
+ paintFocusSatellites(buf, width, height, t, checksum);
1540
+ return;
1541
+ }
1542
+ const placed = layoutRings(checksum.visualConfig.circles, width, height, t * 1.55, checksum);
1543
+ for (let i = 0; i < placed.length; i++) {
1544
+ const wander = Math.sin(t * 3.4 + i * 2.1) * 16;
1545
+ const a = {
1546
+ ...placed[i],
1547
+ x: placed[i].x + wander,
1548
+ y: placed[i].y + Math.cos(t * 2.7 + i) * 10,
1549
+ };
1550
+ const rawB = placed[(i + 1) % placed.length];
1551
+ const rawSkip = placed[(i + 2) % placed.length];
1552
+ const b = { x: rawB.x - wander * 0.3, y: rawB.y };
1553
+ const skip = { x: rawSkip.x, y: rawSkip.y + wander * 0.2 };
1554
+ paintSharpLine(buf, width, height, a.x, a.y, b.x, b.y, THEME.blue, 1);
1555
+ paintSharpLine(buf, width, height, a.x, a.y, skip.x, skip.y, THEME.blue, 1);
1556
+ paintSharpLine(buf, width, height, cx, cy, a.x, a.y, THEME.blue, 1);
1557
+ const speed = 1.8 + a.circle.frequency / 140;
1558
+ const travel = (t * speed + i * 0.17) % 1;
1559
+ const inbound = (t * speed * 1.35 + beat * 0.08 + i * 0.41) % 1;
1560
+ const third = (t * speed * 0.55 + i * 0.63) % 1;
1561
+ stampFocusDisc(
1562
+ buf,
1563
+ width,
1564
+ height,
1565
+ a.x + (b.x - a.x) * travel,
1566
+ a.y + (b.y - a.y) * travel,
1567
+ 5,
1568
+ THEME.gold,
1569
+ node,
1570
+ );
1571
+ stampFocusDisc(
1572
+ buf,
1573
+ width,
1574
+ height,
1575
+ a.x + (cx - a.x) * inbound,
1576
+ a.y + (cy - a.y) * inbound,
1577
+ 4,
1578
+ THEME.cyan,
1579
+ node,
1580
+ );
1581
+ stampFocusDisc(
1582
+ buf,
1583
+ width,
1584
+ height,
1585
+ a.x + (skip.x - a.x) * third,
1586
+ a.y + (skip.y - a.y) * third,
1587
+ 3,
1588
+ THEME.ink,
1589
+ node,
1590
+ );
1591
+ }
1592
+ for (const seat of placed) {
1593
+ stampFocusDisc(
1594
+ buf,
1595
+ width,
1596
+ height,
1597
+ seat.x,
1598
+ seat.y,
1599
+ 7 + kick * 1.5,
1600
+ mixRgb(seat.color, THEME.gold, freqTint(seat.circle, t)),
1601
+ node,
1602
+ );
1603
+ }
1604
+ paintFocusSatellites(buf, width, height, t, checksum);
1605
+ }
1606
+
1607
+ /** waves → waveform v2. Harmonic ribbons + beat envelope + traveling gold needle. */
1608
+ function paintWaveform(buf, width, height, t, checksum) {
1609
+ startFrame(buf, width, height, t, checksum);
1610
+ paintChecksumMesh(buf, width, height, t, checksum, { scale: 0.72, half: 1 });
1611
+ const mid = (height - 1) * 0.5;
1612
+ const beat = beatPhase(checksum, t);
1613
+ const kick = kickAccent(beat);
1614
+ const env = 0.88 + 0.12 * Math.max(0, Math.sin(beat * Math.PI * 2));
1615
+ const circles = checksum.visualConfig.circles;
1616
+ paintSharpRibbon(buf, width, height, () => mid, THEME.ink, 1, THEME.void);
1617
+ circles.forEach((circle, i) => {
1618
+ const color = iridesce(i / Math.max(1, circles.length), t, beat, parseHex(circle.color));
1619
+ const amp0 = height * (0.05 + (circle.radius / 420) * 0.11) * env;
1620
+ const f0 = 0.0065 + circle.frequency / 22000;
1621
+ const shift = t * (circle.frequency / 1.85);
1622
+ const gem = (checksum.gematria && checksum.gematria.checksumValue) || 1;
1623
+ const phase = i * 0.85 + ((gem >>> ((i * 5) % 24)) & 255) / 70;
1624
+ const jitter = 0.08 + ((gem >>> ((i * 3) % 16)) & 7) / 90;
1625
+ paintSharpRibbon(
1626
+ buf,
1627
+ width,
1628
+ height,
1629
+ (x) =>
1630
+ mid +
1631
+ Math.sin((x + shift) * f0 + phase) * amp0 +
1632
+ Math.sin((x + shift) * f0 * 2 + phase * 1.3) * amp0 * 0.28 +
1633
+ Math.sin((x + shift) * f0 * 5.3 + phase * 2.1) * amp0 * jitter,
1634
+ i === 0 ? THEME.cyan : color,
1635
+ i === 0 ? 3 : 2,
1636
+ );
1637
+ paintSharpRibbon(
1638
+ buf,
1639
+ width,
1640
+ height,
1641
+ (x) => mid + Math.sin((x - shift * 0.7) * f0 * 3 + phase) * amp0 * 0.18,
1642
+ i % 2 === 0 ? THEME.gold : THEME.blue,
1643
+ 1,
1644
+ );
1645
+ });
1646
+ const tickX = ((beat % 1) * width) | 0;
1647
+ const tickH = height * 0.22 * (0.45 + kick);
1648
+ for (let y = mid - tickH; y <= mid + tickH; y++) {
1649
+ mixPixel(buf, width, tickX, y, THEME.gold, 1);
1650
+ mixPixel(buf, width, tickX - 1, y, THEME.ink, 1);
1651
+ mixPixel(buf, width, tickX + 1, y, THEME.ink, 1);
1652
+ }
1653
+ paintFocusSatellites(buf, width, height, t, checksum);
1654
+ }
1655
+
1656
+ /** spark → particles v2. Seed mesh is the spark — lines, not bead rain. */
1657
+ function paintParticles(buf, width, height, t, checksum) {
1658
+ startFrame(buf, width, height, t, checksum);
1659
+ const cx = (width - 1) * 0.5;
1660
+ const cy = (height - 1) * 0.5;
1661
+ const minSide = Math.min(width, height);
1662
+ const beat = beatPhase(checksum, t);
1663
+ const kick = kickAccent(beat);
1664
+ const worn = paintChecksumMesh(buf, width, height, t, checksum, {
1665
+ scale: 0.85,
1666
+ half: 1,
1667
+ });
1668
+ const mote = { rim: 1, glow: 2, glowAlpha: 0.16, rimColor: THEME.ink };
1669
+ const mesh = checksum.mesh;
1670
+ const pts = worn && worn.pts;
1671
+ const circles = checksum.visualConfig.circles;
1672
+ if (mesh && pts) {
1673
+ paintFocusSatellites(buf, width, height, t, checksum);
1674
+ return;
1675
+ }
1676
+ const placed = layoutRings(circles, width, height, t * 1.15, checksum);
1677
+ for (let i = 0; i < placed.length; i++) {
1678
+ const src = placed[i];
1679
+ const tint = freqTint(src.circle, t);
1680
+ const orbitR = 22 + (i % 3) * 11 + Math.sin(t * 1.7 + i) * 5;
1681
+ const segs = 11;
1682
+ for (let s = 0; s < segs; s++) {
1683
+ if ((s + i * 3) % 4 === 0) continue;
1684
+ const a0 = (s / segs) * Math.PI * 2 + t * 3.4 + i * 0.7;
1685
+ const a1 = a0 + (Math.PI * 2 * 0.32) / segs;
1686
+ paintSharpLine(
1687
+ buf,
1688
+ width,
1689
+ height,
1690
+ src.x + Math.cos(a0) * orbitR,
1691
+ src.y + Math.sin(a0) * orbitR * 0.72,
1692
+ src.x + Math.cos(a1) * orbitR,
1693
+ src.y + Math.sin(a1) * orbitR * 0.72,
1694
+ THEME.blue,
1695
+ 1,
1696
+ );
1697
+ }
1698
+ const moteCount = 18;
1699
+ for (let k = 0; k < moteCount; k++) {
1700
+ const life = (t * (1.25 + src.circle.frequency / 420) + k * 0.11 + i * 0.07) % 1;
1701
+ const orbital = k % 3 === 0;
1702
+ const dart = Math.sin(t * 5.1 + k * 1.3 + i) * 0.35;
1703
+ const ang = orbital ? t * (3.2 + (k % 5) * 0.28) + i + k + dart : t * 4.2 + i * 1.3 + k * 0.62 + dart;
1704
+ const dist = orbital
1705
+ ? 18 + (k % 4) * 10 + Math.sin(beat * Math.PI * 2 + k) * 4
1706
+ : life * minSide * 0.38 * (0.7 + kick * 0.12);
1707
+ const x = src.x + Math.cos(ang) * dist;
1708
+ const y = src.y + Math.sin(ang) * dist * (orbital ? 0.72 : 1);
1709
+ const size = Math.max(2.2, (1 - life) * (3.2 + (k % 3)) + kick * 0.6);
1710
+ const color = mixRgb(src.color, THEME.gold, k % 2 === 0 ? tint : tint * 0.4);
1711
+ stampFocusDisc(buf, width, height, x, y, size, color, mote);
1712
+ if (life > 0.12 && !orbital) {
1713
+ const prev = life - 0.1;
1714
+ const pd = prev * minSide * 0.36;
1715
+ stampFocusDisc(buf, width, height, src.x + Math.cos(ang) * pd, src.y + Math.sin(ang) * pd, size * 0.55, color, {
1716
+ rim: 1,
1717
+ glow: 1,
1718
+ glowAlpha: 0.1,
1719
+ rimColor: THEME.ink,
1720
+ });
1721
+ }
1722
+ }
1723
+ stampFocusDisc(buf, width, height, src.x, src.y, 6 + kick, mixRgb(THEME.ink, THEME.gold, tint), mote);
1724
+ }
1725
+ paintFocusSatellites(buf, width, height, t, checksum);
1726
+ }
1727
+
1728
+ function paintVisualization(visualization, buf, width, height, t, checksum) {
1729
+ if (visualization === "canvas") return paintCanvas(buf, width, height, t, checksum);
1730
+ if (visualization === "3d-sacred") return paintSacred(buf, width, height, t, checksum);
1731
+ if (visualization === "neural") return paintNeural(buf, width, height, t, checksum);
1732
+ if (visualization === "waveform") return paintWaveform(buf, width, height, t, checksum);
1733
+ if (visualization === "particles") return paintParticles(buf, width, height, t, checksum);
1734
+ const err = new Error(`no Rippel visualization for "${visualization}"`);
1735
+ err.code = "BLIP_RIPPEL_VIZ";
1736
+ throw err;
1737
+ }
1738
+
1739
+ function paintRippelFrame(opts) {
1740
+ const renderer = String(opts.renderer || "");
1741
+ const visualization = visualizationFor(renderer);
1742
+ if (!visualization) {
1743
+ const err = new Error(`no Rippel headless path for "${renderer}"`);
1744
+ err.code = "BLIP_RIPPEL_MISS";
1745
+ throw err;
1746
+ }
1747
+ const width = opts.width || MOTION_WIDTH;
1748
+ const height = opts.height || MOTION_HEIGHT;
1749
+ if (width < 1280 || height < 720) {
1750
+ const err = new Error(`Rippel motions must be ≥720p (got ${width}×${height})`);
1751
+ err.code = "BLIP_RIPPEL_RES";
1752
+ throw err;
1753
+ }
1754
+ const buf = opts.buffer || Buffer.alloc(width * height * 3);
1755
+ if (buf.length < width * height * 3) {
1756
+ const err = new Error("Rippel frame buffer too small");
1757
+ err.code = "BLIP_RIPPEL_BUF";
1758
+ throw err;
1759
+ }
1760
+ const checksum = cachedChecksum({
1761
+ brief: opts.brief,
1762
+ seedHex: opts.seedHex,
1763
+ genre: opts.genre,
1764
+ width,
1765
+ height,
1766
+ lookKind: opts.lookKind,
1767
+ });
1768
+ paintVisualization(visualization, buf, width, height, opts.t || 0, checksum);
1769
+ return {
1770
+ buffer: buf,
1771
+ width,
1772
+ height,
1773
+ visualization,
1774
+ engine: ENGINE,
1775
+ look: LOOK,
1776
+ lookKind: checksum.lookKind,
1777
+ visualConfig: checksum.visualConfig,
1778
+ tlmCommand: checksum.tlmCommand,
1779
+ tempo: checksum.genreConfig && checksum.genreConfig.tempo,
1780
+ mesh: fingerprintMesh(checksum.mesh),
1781
+ field: fingerprintField(checksum.field),
1782
+ };
1783
+ }
1784
+
1785
+ function framesDiffer(a, b) {
1786
+ if (!a || !b || a.length !== b.length) return true;
1787
+ const step = a.length > 12_000 ? 3 : 1;
1788
+ for (let i = 0; i < a.length; i += step) {
1789
+ if (a[i] !== b[i]) return true;
1790
+ }
1791
+ return false;
1792
+ }
1793
+
1794
+ function edgeSharpness(buf, width) {
1795
+ const height = (buf.length / 3 / width) | 0;
1796
+ let edges = 0;
1797
+ let lit = 0;
1798
+ function luma(x, y) {
1799
+ const i = (y * width + x) * 3;
1800
+ return buf[i] * 0.3 + buf[i + 1] * 0.59 + buf[i + 2] * 0.11;
1801
+ }
1802
+ for (let y = 1; y < height - 1; y += 2) {
1803
+ for (let x = 1; x < width - 1; x += 2) {
1804
+ const v = luma(x, y);
1805
+ if (v < 18) continue;
1806
+ lit += 1;
1807
+ if (Math.abs(v - luma(x + 1, y)) > 36 || Math.abs(v - luma(x, y + 1)) > 36) edges += 1;
1808
+ }
1809
+ }
1810
+ return { edges, lit, ratio: lit ? edges / lit : 0 };
1811
+ }
1812
+
1813
+ function goldPixelCount(buf) {
1814
+ let n = 0;
1815
+ for (let i = 0; i < buf.length; i += 3) {
1816
+ if (buf[i] > 200 && buf[i + 1] > 150 && buf[i + 1] < 230 && buf[i + 2] < 70) n += 1;
1817
+ }
1818
+ return n;
1819
+ }
1820
+
1821
+ function sampleMotionFrames(renderer, seedHex, durationSec, brief) {
1822
+ const a = paintRippelFrame({ renderer, t: 0, seedHex, brief, durationSec });
1823
+ const b = paintRippelFrame({
1824
+ renderer,
1825
+ t: (durationSec || 4.44) * 0.5,
1826
+ seedHex,
1827
+ brief,
1828
+ durationSec,
1829
+ });
1830
+ const c = paintRippelFrame({
1831
+ renderer,
1832
+ t: (durationSec || 4.44) * 0.25,
1833
+ seedHex,
1834
+ brief,
1835
+ durationSec,
1836
+ });
1837
+ const d = paintRippelFrame({
1838
+ renderer,
1839
+ t: (durationSec || 4.44) * 0.75,
1840
+ seedHex,
1841
+ brief,
1842
+ durationSec,
1843
+ });
1844
+ return {
1845
+ visualization: a.visualization,
1846
+ look: a.look,
1847
+ width: a.width,
1848
+ height: a.height,
1849
+ differ: framesDiffer(a.buffer, b.buffer),
1850
+ living:
1851
+ framesDiffer(a.buffer, b.buffer) &&
1852
+ framesDiffer(a.buffer, c.buffer) &&
1853
+ framesDiffer(b.buffer, d.buffer) &&
1854
+ framesDiffer(c.buffer, d.buffer),
1855
+ sharpness: edgeSharpness(a.buffer, a.width),
1856
+ circleCount: a.visualConfig.circles.length,
1857
+ tempo: a.tempo,
1858
+ mesh: a.mesh,
1859
+ field: a.field,
1860
+ lookKind: a.lookKind,
1861
+ fill: frameFill(a.buffer),
1862
+ };
1863
+ }
1864
+
1865
+ function fingerprintField(field) {
1866
+ if (!field) return null;
1867
+ return {
1868
+ id: field.id,
1869
+ grid: field.grid,
1870
+ gradient: field.gradient,
1871
+ starCount: (field.stars && field.stars.length) || 0,
1872
+ blinkerCount: (field.blinkers && field.blinkers.length) || 0,
1873
+ };
1874
+ }
1875
+
1876
+ function fingerprintMesh(mesh) {
1877
+ if (!mesh) return null;
1878
+ return {
1879
+ id: mesh.id,
1880
+ family: mesh.family,
1881
+ gait: mesh.gait,
1882
+ vertexCount: mesh.verts.length,
1883
+ edgeCount: mesh.edges.length,
1884
+ faceCount: (mesh.faces && mesh.faces.length) || 0,
1885
+ shells: mesh.shells || 1,
1886
+ dual: Boolean(mesh.dual),
1887
+ fill: Boolean(mesh.fill),
1888
+ ghost: Boolean(mesh.ghost),
1889
+ coreStyle: mesh.coreStyle || "disc",
1890
+ };
1891
+ }
1892
+
1893
+ function frameFill(buf) {
1894
+ const v = THEME.void;
1895
+ let lit = 0;
1896
+ const pixels = buf.length / 3;
1897
+ for (let i = 0; i < buf.length; i += 3) {
1898
+ if (Math.abs(buf[i] - v[0]) > 2 || Math.abs(buf[i + 1] - v[1]) > 2 || Math.abs(buf[i + 2] - v[2]) > 2) {
1899
+ lit += 1;
1900
+ }
1901
+ }
1902
+ return lit / pixels;
1903
+ }
1904
+
1905
+ function summarizeVisual(checksum) {
1906
+ if (!checksum || !checksum.visualConfig) return null;
1907
+ return {
1908
+ tlmCommand: checksum.tlmCommand,
1909
+ canvas: checksum.visualConfig.canvas,
1910
+ circleCount: checksum.visualConfig.circles.length,
1911
+ notes: checksum.visualConfig.circles.map((c) => c.note),
1912
+ frequencies: checksum.visualConfig.circles.map((c) => c.frequency),
1913
+ lookKind: checksum.lookKind || null,
1914
+ mesh: fingerprintMesh(checksum.mesh),
1915
+ field: fingerprintField(checksum.field),
1916
+ };
1917
+ }
1918
+
1919
+ module.exports = {
1920
+ ENGINE,
1921
+ LOOK,
1922
+ MOTION_WIDTH,
1923
+ MOTION_HEIGHT,
1924
+ FPS,
1925
+ SSOT,
1926
+ ANIMATION_TO_VISUALIZATION,
1927
+ THEME,
1928
+ SCALES,
1929
+ visualizationFor,
1930
+ buildVisualConfig,
1931
+ cachedChecksum,
1932
+ paintRippelFrame,
1933
+ framesDiffer,
1934
+ sampleMotionFrames,
1935
+ summarizeVisual,
1936
+ stampDisc,
1937
+ stampFocusDisc,
1938
+ orbFocusWidth,
1939
+ edgeSharpness,
1940
+ goldPixelCount,
1941
+ kickAccent,
1942
+ andAccent,
1943
+ beatPhase,
1944
+ phraseOf,
1945
+ phraseMix,
1946
+ phraseWeight,
1947
+ motionGrid: soundRippel.motionGrid,
1948
+ fillVoid,
1949
+ buildMesh,
1950
+ buildField,
1951
+ paintMeshOverlay,
1952
+ paintField,
1953
+ fingerprintMesh,
1954
+ fingerprintField,
1955
+ frameFill,
1956
+ MESH_FAMILIES,
1957
+ MESH_GAITS,
1958
+ CORE_STYLES,
1959
+ LOOK_KINDS,
1960
+ GRID_KINDS,
1961
+ GRAD_KINDS,
1962
+ resolveLookKind,
1963
+ };