@vellumai/assistant 0.8.12 → 0.9.0-staging.2

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 (442) hide show
  1. package/AGENTS.md +0 -14
  2. package/ARCHITECTURE.md +45 -45
  3. package/README.md +1 -1
  4. package/bun.lock +200 -154
  5. package/docs/architecture/integrations.md +3 -3
  6. package/docs/architecture/memory.md +2 -2
  7. package/docs/architecture/security.md +10 -10
  8. package/docs/runbook-trusted-contacts.md +12 -12
  9. package/docs/skills.md +6 -6
  10. package/docs/workflows-testing.md +221 -0
  11. package/docs/workflows.md +510 -0
  12. package/examples/plugins/echo/README.md +5 -5
  13. package/knip.json +2 -0
  14. package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +105 -0
  15. package/node_modules/@vellumai/gateway-client/src/index.ts +12 -0
  16. package/openapi.yaml +7197 -5708
  17. package/package.json +8 -4
  18. package/scripts/generate-openapi.ts +66 -114
  19. package/src/__tests__/access-request-seed-content-blocks.test.ts +213 -0
  20. package/src/__tests__/adaptive-thinking-repair.test.ts +32 -3
  21. package/src/__tests__/agent-loop-output-hooks.test.ts +183 -0
  22. package/src/__tests__/agent-loop-regrowth-guard.test.ts +506 -0
  23. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +2 -0
  24. package/src/__tests__/agent-wake-override-profile.test.ts +77 -0
  25. package/src/__tests__/app-compiler.test.ts +7 -1
  26. package/src/__tests__/app-dir-path-guard.test.ts +27 -3
  27. package/src/__tests__/app-executors.test.ts +43 -0
  28. package/src/__tests__/approval-cascade.test.ts +0 -5
  29. package/src/__tests__/approval-routes-http.test.ts +91 -0
  30. package/src/__tests__/assistant-stream-state.test.ts +107 -0
  31. package/src/__tests__/browser-fill-credential.test.ts +3 -3
  32. package/src/__tests__/bundled-skill-retrieval-guard.test.ts +1 -1
  33. package/src/__tests__/compaction-events.test.ts +63 -7
  34. package/src/__tests__/compaction-trail-store.test.ts +74 -1
  35. package/src/__tests__/compaction.benchmark.test.ts +63 -41
  36. package/src/__tests__/compactor-low-watermark-cut.test.ts +349 -0
  37. package/src/__tests__/context-window-manager-compact-retry.test.ts +64 -0
  38. package/src/__tests__/conversation-abort-tool-results.test.ts +0 -5
  39. package/src/__tests__/conversation-confirmation-signals.test.ts +0 -5
  40. package/src/__tests__/conversation-history-web-search.test.ts +7 -0
  41. package/src/__tests__/conversation-process-callsite.test.ts +0 -5
  42. package/src/__tests__/conversation-provider-retry-repair.test.ts +0 -5
  43. package/src/__tests__/conversation-queue.test.ts +0 -5
  44. package/src/__tests__/conversation-slash-queue.test.ts +0 -5
  45. package/src/__tests__/conversation-slash-unknown.test.ts +0 -5
  46. package/src/__tests__/conversation-speed-override.test.ts +0 -5
  47. package/src/__tests__/conversation-surfaces-data-persist.test.ts +97 -0
  48. package/src/__tests__/conversation-surfaces-task-progress.test.ts +67 -0
  49. package/src/__tests__/conversation-usage.test.ts +2 -0
  50. package/src/__tests__/conversation-workspace-injection.test.ts +0 -5
  51. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -5
  52. package/src/__tests__/credential-broker-browser-fill.test.ts +2 -2
  53. package/src/__tests__/credential-broker-server-use.test.ts +2 -2
  54. package/src/__tests__/credential-broker.test.ts +1 -1
  55. package/src/__tests__/credential-prompt-route.test.ts +417 -0
  56. package/src/__tests__/credential-security-invariants.test.ts +1 -0
  57. package/src/__tests__/credential-vault.test.ts +37 -0
  58. package/src/__tests__/db-schedule-syntax-migration.test.ts +24 -0
  59. package/src/__tests__/dynamic-page-surface.test.ts +219 -0
  60. package/src/__tests__/empty-state-greeting-cache.test.ts +94 -0
  61. package/src/__tests__/gateway-flag-listener.test.ts +24 -7
  62. package/src/__tests__/guardian-action-sweep.test.ts +56 -219
  63. package/src/__tests__/guardian-routing-invariants.test.ts +138 -0
  64. package/src/__tests__/helpers/channel-test-adapter.ts +0 -2
  65. package/src/__tests__/list-messages-hidden-metadata.test.ts +99 -0
  66. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +87 -1
  67. package/src/__tests__/llm-resolver.test.ts +115 -0
  68. package/src/__tests__/managed-profile-guard.test.ts +6 -5
  69. package/src/__tests__/max-tokens-continue-hook.test.ts +184 -0
  70. package/src/__tests__/media-generate-image.test.ts +20 -9
  71. package/src/__tests__/mock-gateway-ipc.ts +23 -0
  72. package/src/__tests__/model-intents.test.ts +1 -1
  73. package/src/__tests__/normalize-onboarding.test.ts +26 -0
  74. package/src/__tests__/notification-decision-strategy.test.ts +4 -2
  75. package/src/__tests__/notification-telegram-adapter.test.ts +21 -3
  76. package/src/__tests__/pending-interactions-resolved-event.test.ts +62 -0
  77. package/src/__tests__/post-turn-tool-result-truncation.test.ts +72 -18
  78. package/src/__tests__/require-fresh-approval.test.ts +425 -1
  79. package/src/__tests__/resolve-app-id.test.ts +56 -0
  80. package/src/__tests__/runtime-events-sse-parity.test.ts +2 -0
  81. package/src/__tests__/schedule-routes-workflow-validation.test.ts +408 -0
  82. package/src/__tests__/schedule-routes.test.ts +257 -4
  83. package/src/__tests__/schedule-store.test.ts +60 -0
  84. package/src/__tests__/schedule-tools.test.ts +247 -2
  85. package/src/__tests__/skill-execute-input.test.ts +85 -0
  86. package/src/__tests__/skill-secret-handling-guard.test.ts +21 -20
  87. package/src/__tests__/skills.test.ts +3 -3
  88. package/src/__tests__/slack-app-setup-skill-regression.test.ts +1 -1
  89. package/src/__tests__/subagent-tool-filtering.test.ts +50 -0
  90. package/src/__tests__/subagent-tool-gate-mode.test.ts +547 -0
  91. package/src/__tests__/system-prompt.test.ts +1 -1
  92. package/src/__tests__/task-progress-nudge-hook.test.ts +372 -0
  93. package/src/__tests__/task-scheduler.test.ts +299 -0
  94. package/src/__tests__/tool-approval-seed-content-blocks.test.ts +209 -0
  95. package/src/__tests__/tool-result-spool.test.ts +3 -1
  96. package/src/__tests__/workspace-migration-102-preserve-heartbeat-enabled-for-existing-workspaces.test.ts +181 -0
  97. package/src/__tests__/workspace-migration-103-upgrade-quality-profile-to-opus-4-8.test.ts +174 -0
  98. package/src/agent/compaction-circuit.ts +11 -0
  99. package/src/agent/loop.ts +181 -12
  100. package/src/api/constants/call-sites.ts +12 -0
  101. package/src/api/events/assistant-thinking-delta.ts +10 -0
  102. package/src/api/events/usage-update.ts +7 -0
  103. package/src/api/index.ts +4 -1
  104. package/src/api/responses/memory-v3-selection-log.ts +18 -11
  105. package/src/approvals/approval-primitive.ts +2 -2
  106. package/src/background-wake/background-wake-routes.test.ts +5 -2
  107. package/src/bundler/compiler-tools.ts +1 -1
  108. package/src/bundler/package-resolver.ts +0 -1
  109. package/src/calls/call-domain.ts +1 -1
  110. package/src/calls/guardian-action-sweep.ts +16 -93
  111. package/src/cli/AGENTS.md +4 -0
  112. package/src/cli/commands/__tests__/schedules.test.ts +430 -1
  113. package/src/cli/commands/credentials.ts +28 -24
  114. package/src/cli/commands/image-generation.ts +23 -9
  115. package/src/cli/commands/notifications.ts +1 -1
  116. package/src/cli/commands/plugins.ts +89 -46
  117. package/src/cli/commands/schedules.ts +384 -11
  118. package/src/cli/lib/__tests__/inspect-plugin.test.ts +69 -5
  119. package/src/cli/lib/__tests__/install-from-github.test.ts +15 -0
  120. package/src/cli/lib/__tests__/upgrade-plugin.test.ts +81 -4
  121. package/src/cli/lib/inspect-plugin.ts +62 -1
  122. package/src/cli/lib/install-from-github.ts +52 -5
  123. package/src/cli/lib/upgrade-plugin.ts +18 -0
  124. package/src/config/__tests__/workflows-schema.test.ts +60 -0
  125. package/src/config/bundled-skills/acp/SKILL.md +2 -2
  126. package/src/config/bundled-skills/app-builder/SKILL.md +1 -1
  127. package/src/config/bundled-skills/app-builder/tools/app-create.ts +6 -1
  128. package/src/config/bundled-skills/app-builder/tools/app-generate-icon.ts +7 -1
  129. package/src/config/bundled-skills/app-builder/tools/app-refresh.ts +7 -1
  130. package/src/config/bundled-skills/app-builder/tools/app-update.ts +10 -1
  131. package/src/config/bundled-skills/image-studio/SKILL.md +66 -19
  132. package/src/config/bundled-skills/image-studio/TOOLS.json +1 -6
  133. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +22 -3
  134. package/src/config/bundled-skills/personal-page/SKILL.md +57 -0
  135. package/src/config/bundled-skills/personal-page/TOOLS.json +27 -0
  136. package/src/config/bundled-skills/personal-page/tools/app-refresh.ts +17 -0
  137. package/src/config/bundled-skills/schedule/SKILL.md +7 -2
  138. package/src/config/bundled-skills/schedule/TOOLS.json +48 -4
  139. package/src/config/bundled-skills/workflows/SKILL.md +214 -0
  140. package/src/config/bundled-skills/workflows/TOOLS.json +84 -0
  141. package/src/config/bundled-skills/workflows/tools/manage-workflows.ts +12 -0
  142. package/src/config/bundled-skills/workflows/tools/run-workflow.ts +12 -0
  143. package/src/config/bundled-tool-registry.ts +14 -2
  144. package/src/config/call-site-defaults.ts +5 -0
  145. package/src/config/feature-flag-registry.json +12 -4
  146. package/src/config/llm-context-resolution.ts +8 -0
  147. package/src/config/llm-resolver.ts +30 -0
  148. package/src/config/preloaded-apps/personal-page/src/components/About.tsx +22 -0
  149. package/src/config/preloaded-apps/personal-page/src/components/App.tsx +16 -0
  150. package/src/config/preloaded-apps/personal-page/src/components/Features.tsx +77 -0
  151. package/src/config/preloaded-apps/personal-page/src/components/Hero.tsx +57 -0
  152. package/src/config/preloaded-apps/personal-page/src/components/Pending.tsx +28 -0
  153. package/src/config/preloaded-apps/personal-page/src/components/animations.tsx +234 -0
  154. package/src/config/preloaded-apps/personal-page/src/components/icons.tsx +48 -0
  155. package/src/config/preloaded-apps/personal-page/src/components/media.ts +16 -0
  156. package/src/config/preloaded-apps/personal-page/src/index.html +20 -0
  157. package/src/config/preloaded-apps/personal-page/src/main.tsx +7 -0
  158. package/src/config/preloaded-apps/personal-page/src/profile-data.ts +82 -0
  159. package/src/config/preloaded-apps/personal-page/src/styles.css +759 -0
  160. package/src/config/schema.ts +2 -0
  161. package/src/config/schemas/call-site-catalog.ts +7 -0
  162. package/src/config/schemas/heartbeat.ts +4 -1
  163. package/src/config/schemas/llm.ts +33 -26
  164. package/src/config/schemas/memory-retrospective.ts +19 -0
  165. package/src/config/schemas/platform.ts +8 -0
  166. package/src/config/schemas/services.ts +5 -2
  167. package/src/config/schemas/workflows.ts +42 -0
  168. package/src/config/skills.ts +3 -3
  169. package/src/context/compactor.ts +273 -39
  170. package/src/context/post-turn-tool-result-truncation.ts +23 -6
  171. package/src/context/tool-result-spool.ts +12 -17
  172. package/src/credential-execution/executable-discovery.ts +1 -1
  173. package/src/credential-execution/process-manager.ts +37 -3
  174. package/src/credential-execution/prompted-credential.ts +205 -0
  175. package/src/daemon/conversation-agent-loop-handlers.ts +14 -0
  176. package/src/daemon/conversation-process.ts +11 -2
  177. package/src/daemon/conversation-surfaces.ts +167 -3
  178. package/src/daemon/conversation-tool-setup.ts +103 -26
  179. package/src/daemon/conversation-usage.ts +2 -0
  180. package/src/daemon/conversation.ts +115 -11
  181. package/src/daemon/handlers/shared.ts +26 -14
  182. package/src/daemon/host-cu-proxy.ts +15 -12
  183. package/src/daemon/host-file-proxy.ts +15 -12
  184. package/src/daemon/host-transfer-proxy.ts +30 -24
  185. package/src/daemon/lifecycle.ts +40 -3
  186. package/src/daemon/message-protocol.ts +3 -0
  187. package/src/daemon/message-types/messages.ts +2 -10
  188. package/src/daemon/message-types/workflows.ts +49 -0
  189. package/src/daemon/parse-actual-tokens-from-error.test.ts +62 -1
  190. package/src/daemon/parse-actual-tokens-from-error.ts +43 -4
  191. package/src/daemon/process-message.ts +6 -0
  192. package/src/daemon/tool-setup-types.ts +57 -0
  193. package/src/daemon/wake-conversation-ops.ts +18 -0
  194. package/src/heartbeat/heartbeat-run-store.ts +8 -2
  195. package/src/home/feed-types.ts +1 -1
  196. package/src/ipc/gateway-flag-listener.ts +28 -6
  197. package/src/mcp/mcp-auth-state.ts +8 -20
  198. package/src/media/__tests__/image-models.test.ts +57 -0
  199. package/src/media/image-models.ts +66 -0
  200. package/src/memory/__tests__/auto-analysis-enqueue.test.ts +38 -0
  201. package/src/memory/__tests__/find-most-recent-retrospective-for.test.ts +12 -2
  202. package/src/memory/__tests__/memory-retrospective-job.test.ts +911 -34
  203. package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +227 -5
  204. package/src/memory/__tests__/memory-retrospective-state.test.ts +195 -0
  205. package/src/memory/__tests__/preloaded-apps.test.ts +85 -0
  206. package/src/memory/auto-analysis-enqueue.ts +14 -1
  207. package/src/memory/compaction-log-store-clickhouse.ts +6 -4
  208. package/src/memory/conversation-crud.ts +9 -2
  209. package/src/memory/conversation-disk-view.ts +1 -1
  210. package/src/memory/conversation-queries.ts +22 -7
  211. package/src/memory/db-init.ts +20 -0
  212. package/src/memory/db-maintenance.ts +16 -0
  213. package/src/memory/embedding-runtime-manager.ts +1 -1
  214. package/src/memory/llm-request-log-source-clickhouse.ts +112 -14
  215. package/src/memory/llm-request-log-source-local.ts +19 -1
  216. package/src/memory/llm-request-log-source.ts +35 -6
  217. package/src/memory/llm-request-log-store.ts +90 -2
  218. package/src/memory/memory-retrospective-constants.ts +9 -0
  219. package/src/memory/memory-retrospective-enqueue.ts +3 -6
  220. package/src/memory/memory-retrospective-fork-boundary.ts +94 -0
  221. package/src/memory/memory-retrospective-job.ts +500 -208
  222. package/src/memory/memory-retrospective-startup-cleanup.ts +97 -19
  223. package/src/memory/memory-retrospective-state.ts +85 -2
  224. package/src/memory/migrations/281-memory-retrospective-remembered-log.ts +40 -0
  225. package/src/memory/migrations/282-schedule-inference-profile.test.ts +77 -0
  226. package/src/memory/migrations/282-schedule-inference-profile.ts +26 -0
  227. package/src/memory/migrations/283-memory-v3-selections-message-id-and-sections.test.ts +102 -0
  228. package/src/memory/migrations/283-memory-v3-selections-message-id-and-sections.ts +53 -0
  229. package/src/memory/migrations/284-workflow-runs.ts +51 -0
  230. package/src/memory/migrations/285-schedule-workflow-mode.ts +26 -0
  231. package/src/memory/migrations/286-workflow-run-trust.ts +27 -0
  232. package/src/memory/migrations/287-conversation-origin-channel-index.ts +15 -0
  233. package/src/memory/migrations/288-backfill-origin-channel-from-bindings.ts +43 -0
  234. package/src/memory/migrations/289-contact-channels-unique-ext-user.ts +115 -0
  235. package/src/memory/migrations/290-schedule-capabilities.test.ts +77 -0
  236. package/src/memory/migrations/290-schedule-capabilities.ts +25 -0
  237. package/src/memory/migrations/__tests__/281-memory-retrospective-remembered-log.test.ts +96 -0
  238. package/src/memory/migrations/__tests__/289-contact-channels-unique-ext-user.test.ts +571 -0
  239. package/src/memory/migrations/index.ts +10 -0
  240. package/src/memory/preloaded-apps.ts +116 -0
  241. package/src/memory/schema/infrastructure.ts +4 -0
  242. package/src/memory/schema/memory-core.ts +4 -0
  243. package/src/memory/v2/__tests__/concept-page-frontmatter-schema.test.ts +45 -0
  244. package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +11 -7
  245. package/src/memory/v2/__tests__/page-store.test.ts +13 -2
  246. package/src/memory/v2/__tests__/qdrant.test.ts +24 -0
  247. package/src/memory/v2/frontmatter-sweep.ts +7 -6
  248. package/src/memory/v2/page-store.ts +4 -3
  249. package/src/memory/v2/qdrant.ts +42 -3
  250. package/src/memory/v2/types.ts +16 -10
  251. package/src/messaging/draft-store.ts +1 -1
  252. package/src/notifications/access-request-copy.ts +200 -113
  253. package/src/notifications/adapters/slack.ts +250 -111
  254. package/src/notifications/adapters/telegram.ts +7 -44
  255. package/src/notifications/approval-card-builder.ts +93 -0
  256. package/src/notifications/broadcaster.ts +74 -0
  257. package/src/notifications/conversation-pairing.ts +8 -6
  258. package/src/notifications/copy-composer.ts +32 -26
  259. package/src/notifications/decision-engine.ts +59 -7
  260. package/src/notifications/guardian-question-mode.ts +145 -155
  261. package/src/notifications/home-feed-side-effect.ts +28 -11
  262. package/src/notifications/notification-utils.ts +66 -0
  263. package/src/notifications/signal.ts +6 -0
  264. package/src/notifications/tool-approval-copy.ts +142 -0
  265. package/src/notifications/types.ts +19 -0
  266. package/src/permissions/threshold.ts +11 -0
  267. package/src/plugin-api/types.ts +16 -4
  268. package/src/plugins/defaults/compaction/window-manager.ts +44 -0
  269. package/src/plugins/defaults/index.ts +46 -0
  270. package/src/plugins/defaults/max-tokens-continue/continue-state-store.ts +53 -0
  271. package/src/plugins/defaults/max-tokens-continue/hooks/post-model-call.ts +80 -0
  272. package/src/plugins/defaults/max-tokens-continue/hooks/stop.ts +20 -0
  273. package/src/plugins/defaults/max-tokens-continue/package.json +14 -0
  274. package/src/plugins/defaults/memory-retrieval/hooks/__tests__/user-prompt-submit.test.ts +37 -0
  275. package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +29 -1
  276. package/src/plugins/defaults/memory-v3-shadow/__tests__/carry-integration.test.ts +8 -3
  277. package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +4 -2
  278. package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +28 -18
  279. package/src/plugins/defaults/memory-v3-shadow/__tests__/section-dense-store.test.ts +67 -0
  280. package/src/plugins/defaults/memory-v3-shadow/__tests__/selection-log-store.test.ts +122 -22
  281. package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-integration.test.ts +2 -0
  282. package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +63 -1
  283. package/src/plugins/defaults/memory-v3-shadow/injector.ts +61 -18
  284. package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +1 -1
  285. package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +39 -10
  286. package/src/plugins/defaults/memory-v3-shadow/section-dense-store.ts +34 -1
  287. package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +112 -47
  288. package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +78 -15
  289. package/src/plugins/defaults/task-progress-nudge/hooks/post-tool-use.ts +206 -0
  290. package/src/plugins/defaults/task-progress-nudge/package.json +15 -0
  291. package/src/prompts/__tests__/system-prompt.test.ts +100 -1
  292. package/src/prompts/__tests__/task-progress-hint-section.test.ts +5 -7
  293. package/src/prompts/normalize-onboarding.ts +2 -0
  294. package/src/prompts/persona-resolver.ts +3 -0
  295. package/src/prompts/system-prompt.ts +51 -2
  296. package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +3 -1
  297. package/src/prompts/templates/system-sections.ts +8 -3
  298. package/src/providers/call-site-routing.ts +6 -3
  299. package/src/providers/fireworks/client.ts +3 -0
  300. package/src/providers/inference/auth.ts +52 -46
  301. package/src/providers/model-intents.ts +2 -2
  302. package/src/providers/openai/__tests__/coerce-object-args.test.ts +105 -0
  303. package/src/providers/openai/chat-completions-provider.ts +47 -9
  304. package/src/providers/openai/coerce-object-args.ts +104 -0
  305. package/src/providers/retry.ts +8 -5
  306. package/src/providers/types.ts +10 -0
  307. package/src/runtime/__tests__/agent-wake.test.ts +629 -7
  308. package/src/runtime/access-request-helper.ts +16 -9
  309. package/src/runtime/agent-wake.ts +302 -51
  310. package/src/runtime/assistant-stream-state.ts +141 -8
  311. package/src/runtime/background-job-runner.ts +9 -0
  312. package/src/runtime/channel-approval-types.ts +1 -0
  313. package/src/runtime/channel-invite-transports/telegram.ts +6 -5
  314. package/src/runtime/channel-invite-transports/voice.ts +2 -2
  315. package/src/runtime/channel-invite-types.ts +4 -2
  316. package/src/runtime/channel-retry-sweep.ts +19 -41
  317. package/src/runtime/finalize-event-delivery.ts +72 -0
  318. package/src/runtime/guardian-action-message-composer.ts +0 -54
  319. package/src/runtime/http-server.ts +6 -14
  320. package/src/runtime/http-types.ts +0 -1
  321. package/src/runtime/message-composer-types.ts +0 -9
  322. package/src/runtime/middleware/__tests__/rate-limiter.test.ts +63 -0
  323. package/src/runtime/middleware/auth.ts +27 -3
  324. package/src/runtime/middleware/rate-limiter.ts +28 -1
  325. package/src/runtime/migrations/vbundle-builder.ts +6 -5
  326. package/src/runtime/pending-interactions.ts +20 -1
  327. package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +232 -173
  328. package/src/runtime/routes/__tests__/plugins-routes.test.ts +18 -0
  329. package/src/runtime/routes/__tests__/retrospective-routes.test.ts +436 -0
  330. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +11 -0
  331. package/src/runtime/routes/approval-routes.ts +35 -8
  332. package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +2 -1
  333. package/src/runtime/routes/btw-routes.ts +37 -1
  334. package/src/runtime/routes/channel-delivery-routes.ts +11 -7
  335. package/src/runtime/routes/channel-route-definitions.ts +3 -0
  336. package/src/runtime/routes/channel-route-shared.ts +3 -1
  337. package/src/runtime/routes/consolidation-routes.ts +17 -13
  338. package/src/runtime/routes/conversation-compaction-routes.ts +159 -119
  339. package/src/runtime/routes/conversation-list-routes.ts +41 -4
  340. package/src/runtime/routes/conversation-query-routes.ts +196 -11
  341. package/src/runtime/routes/conversation-routes.ts +15 -1
  342. package/src/runtime/routes/credential-prompt-routes.ts +39 -17
  343. package/src/runtime/routes/empty-state-greeting-cache.ts +65 -0
  344. package/src/runtime/routes/heartbeat-routes.ts +18 -13
  345. package/src/runtime/routes/image-generation-routes.ts +20 -2
  346. package/src/runtime/routes/inbound-message-handler.ts +13 -12
  347. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +32 -31
  348. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +7 -5
  349. package/src/runtime/routes/inbound-stages/background-dispatch.ts +7 -21
  350. package/src/runtime/routes/inbound-stages/escalation-intercept.ts +5 -5
  351. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +6 -15
  352. package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +1 -1
  353. package/src/runtime/routes/index.ts +6 -0
  354. package/src/runtime/routes/log-export/AGENTS.md +1 -1
  355. package/src/runtime/routes/log-export/workspace-allowlist.ts +1 -1
  356. package/src/runtime/routes/migration-routes.ts +5 -9
  357. package/src/runtime/routes/plugins-routes.ts +26 -0
  358. package/src/runtime/routes/ps-routes.ts +10 -8
  359. package/src/runtime/routes/retrospective-routes.ts +235 -0
  360. package/src/runtime/routes/runs-pagination.ts +75 -0
  361. package/src/runtime/routes/schedule-routes.ts +367 -59
  362. package/src/runtime/routes/sounds-config-routes.ts +239 -0
  363. package/src/runtime/routes/surface-action-routes.ts +84 -4
  364. package/src/runtime/routes/workflow-routes.test.ts +372 -0
  365. package/src/runtime/routes/workflow-routes.ts +363 -0
  366. package/src/runtime/routes/workspace-routes.test.ts +61 -1
  367. package/src/runtime/routes/workspace-routes.ts +26 -1
  368. package/src/runtime/services/__tests__/analyze-conversation.test.ts +38 -0
  369. package/src/runtime/services/analyze-conversation.ts +26 -13
  370. package/src/schedule/inference-profile.ts +28 -0
  371. package/src/schedule/schedule-store.ts +152 -4
  372. package/src/schedule/scheduler-types.ts +6 -0
  373. package/src/schedule/scheduler.ts +96 -0
  374. package/src/security/secret-allowlist.ts +1 -1
  375. package/src/skills/path-classifier.ts +1 -1
  376. package/src/tools/apps/executors.ts +23 -0
  377. package/src/tools/apps/resolve-app-id.ts +42 -0
  378. package/src/tools/browser/browser-execution.ts +9 -11
  379. package/src/tools/credentials/broker.ts +4 -4
  380. package/src/tools/credentials/vault.ts +26 -137
  381. package/src/tools/executor.ts +69 -0
  382. package/src/tools/flag-gated-tools.test.ts +76 -0
  383. package/src/tools/permission-checker.ts +8 -1
  384. package/src/tools/registry.ts +51 -0
  385. package/src/tools/schedule/create.ts +77 -1
  386. package/src/tools/schedule/list.ts +1 -0
  387. package/src/tools/schedule/update.ts +73 -1
  388. package/src/tools/skills/execute.ts +56 -0
  389. package/src/tools/terminal/shell.ts +1 -1
  390. package/src/tools/ui-surface/definitions.ts +91 -2
  391. package/src/tools/workflows/manage-workflows.ts +183 -0
  392. package/src/tools/workflows/run-workflow.test.ts +442 -0
  393. package/src/tools/workflows/run-workflow.ts +88 -0
  394. package/src/types/onboarding-context.ts +2 -0
  395. package/src/usage/attribution.ts +24 -0
  396. package/src/util/canonicalize-identity.ts +12 -3
  397. package/src/util/platform.ts +17 -17
  398. package/src/watcher/__tests__/engine.test.ts +24 -0
  399. package/src/watcher/__tests__/telemetry.test.ts +135 -0
  400. package/src/watcher/engine.ts +7 -0
  401. package/src/watcher/telemetry.ts +74 -0
  402. package/src/workflows/capabilities.test.ts +365 -0
  403. package/src/workflows/capabilities.ts +359 -0
  404. package/src/workflows/deterministic-stringify.ts +27 -0
  405. package/src/workflows/engine-integration.test.ts +656 -0
  406. package/src/workflows/engine.test.ts +1144 -0
  407. package/src/workflows/engine.ts +1078 -0
  408. package/src/workflows/fanout-load.test.ts +168 -0
  409. package/src/workflows/journal-store.test.ts +369 -0
  410. package/src/workflows/journal-store.ts +470 -0
  411. package/src/workflows/leaf-runner.test.ts +704 -0
  412. package/src/workflows/leaf-runner.ts +589 -0
  413. package/src/workflows/library.test.ts +134 -0
  414. package/src/workflows/library.ts +124 -0
  415. package/src/workflows/run-manager.test.ts +711 -0
  416. package/src/workflows/run-manager.ts +593 -0
  417. package/src/workflows/sandbox-escape.test.ts +339 -0
  418. package/src/workflows/sandbox.test.ts +251 -0
  419. package/src/workflows/sandbox.ts +447 -0
  420. package/src/workspace/adaptive-thinking-repair.ts +33 -11
  421. package/src/workspace/migrations/021-move-signals-to-workspace.ts +1 -1
  422. package/src/workspace/migrations/022-move-hooks-to-workspace.ts +1 -1
  423. package/src/workspace/migrations/026-backfill-install-meta.ts +1 -1
  424. package/src/workspace/migrations/030-seed-pkb-autoinject.ts +2 -1
  425. package/src/workspace/migrations/031-drop-user-md.ts +1 -4
  426. package/src/workspace/migrations/048-remove-workspace-hooks.ts +1 -1
  427. package/src/workspace/migrations/056-release-notes-inference-profile-reordering.ts +5 -2
  428. package/src/workspace/migrations/061-move-backup-key-to-workspace.ts +1 -1
  429. package/src/workspace/migrations/082-backfill-managed-profile-labels.ts +8 -2
  430. package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +41 -14
  431. package/src/workspace/migrations/102-preserve-heartbeat-enabled-for-existing-workspaces.ts +69 -0
  432. package/src/workspace/migrations/103-upgrade-quality-profile-to-opus-4-8.ts +83 -0
  433. package/src/workspace/migrations/104-recheck-adaptive-thinking-model-implied-anthropic.ts +133 -0
  434. package/src/workspace/migrations/registry.ts +6 -0
  435. package/src/workspace/migrations/runner.ts +1 -1
  436. package/tsconfig.json +1 -1
  437. package/src/__tests__/guardian-action-copy-generator.test.ts +0 -200
  438. package/src/__tests__/guardian-action-grant-mint-consume.test.ts +0 -579
  439. package/src/__tests__/guardian-action-store.test.ts +0 -106
  440. package/src/daemon/guardian-action-generators.ts +0 -71
  441. package/src/memory/guardian-action-store.ts +0 -484
  442. package/src/runtime/guardian-action-grant-minter.ts +0 -150
@@ -0,0 +1,759 @@
1
+ * {
2
+ font-family:
3
+ "Almarai",
4
+ -apple-system,
5
+ BlinkMacSystemFont,
6
+ "Segoe UI",
7
+ "Roboto",
8
+ "Oxygen",
9
+ "Ubuntu",
10
+ "Cantarell",
11
+ sans-serif;
12
+ box-sizing: border-box;
13
+ margin: 0;
14
+ padding: 0;
15
+ }
16
+
17
+ html,
18
+ body,
19
+ #app {
20
+ background: #000;
21
+ color: #e1e0cc;
22
+ min-height: 100dvh;
23
+ width: 100%;
24
+ overflow-x: hidden;
25
+ }
26
+
27
+ body {
28
+ -webkit-font-smoothing: antialiased;
29
+ -moz-osx-font-smoothing: grayscale;
30
+ }
31
+
32
+ .serif-italic {
33
+ font-family: "Instrument Serif", serif;
34
+ font-style: italic;
35
+ font-weight: 400;
36
+ }
37
+
38
+ /* === Noise textures === */
39
+ .noise-overlay {
40
+ position: absolute;
41
+ inset: 0;
42
+ pointer-events: none;
43
+ background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/></filter><rect width='100%' height='100%' filter='url(%23n)' opacity='0.7'/></svg>");
44
+ opacity: 0.7;
45
+ mix-blend-mode: overlay;
46
+ z-index: 2;
47
+ }
48
+
49
+ .bg-noise {
50
+ background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/></filter><rect width='100%' height='100%' filter='url(%23n)' opacity='0.6'/></svg>");
51
+ }
52
+
53
+ /* === Animations === */
54
+ @keyframes pullUp {
55
+ from {
56
+ transform: translateY(20px);
57
+ opacity: 0;
58
+ }
59
+ to {
60
+ transform: translateY(0);
61
+ opacity: 1;
62
+ }
63
+ }
64
+ @keyframes fadeUp {
65
+ from {
66
+ transform: translateY(20px);
67
+ opacity: 0;
68
+ }
69
+ to {
70
+ transform: translateY(0);
71
+ opacity: 1;
72
+ }
73
+ }
74
+
75
+ .pull-word {
76
+ display: inline-block;
77
+ opacity: 0;
78
+ transform: translateY(20px);
79
+ will-change: transform, opacity;
80
+ }
81
+ .pull-in .pull-word {
82
+ animation: pullUp 0.7s cubic-bezier(0.16, 1, 0.3, 1) forwards;
83
+ }
84
+
85
+ .hero-fade {
86
+ opacity: 0;
87
+ transform: translateY(20px);
88
+ animation: fadeUp 0.9s cubic-bezier(0.16, 1, 0.3, 1) forwards;
89
+ }
90
+
91
+ /* === HERO === */
92
+ .hero {
93
+ height: 100vh;
94
+ height: 100dvh;
95
+ width: 100%;
96
+ padding: 16px;
97
+ position: relative;
98
+ }
99
+ @media (min-width: 768px) {
100
+ .hero {
101
+ padding: 24px;
102
+ }
103
+ }
104
+
105
+ .hero-frame {
106
+ position: relative;
107
+ width: 100%;
108
+ height: 100%;
109
+ border-radius: 16px;
110
+ overflow: hidden;
111
+ background: #050505;
112
+ }
113
+ @media (min-width: 768px) {
114
+ .hero-frame {
115
+ border-radius: 32px;
116
+ }
117
+ }
118
+
119
+ /* Cinematic backdrop: warm light-leaks drifting over near-black, in place
120
+ of a video loop (the sandboxed iframe can't load daemon-served media). */
121
+ .hero-backdrop {
122
+ position: absolute;
123
+ inset: 0;
124
+ z-index: 1;
125
+ background: #050505;
126
+ overflow: hidden;
127
+ }
128
+ .hero-backdrop::before,
129
+ .hero-backdrop::after {
130
+ content: "";
131
+ position: absolute;
132
+ inset: -35%;
133
+ background:
134
+ radial-gradient(
135
+ 42% 50% at 24% 32%,
136
+ rgba(225, 224, 204, 0.16) 0%,
137
+ transparent 70%
138
+ ),
139
+ radial-gradient(
140
+ 36% 46% at 76% 22%,
141
+ rgba(222, 219, 200, 0.09) 0%,
142
+ transparent 70%
143
+ ),
144
+ radial-gradient(
145
+ 52% 62% at 62% 82%,
146
+ rgba(125, 115, 80, 0.22) 0%,
147
+ transparent 70%
148
+ );
149
+ animation: backdropDrift 38s ease-in-out infinite alternate;
150
+ will-change: transform;
151
+ }
152
+ .hero-backdrop::after {
153
+ background:
154
+ radial-gradient(
155
+ 46% 56% at 72% 64%,
156
+ rgba(225, 224, 204, 0.1) 0%,
157
+ transparent 70%
158
+ ),
159
+ radial-gradient(
160
+ 32% 42% at 18% 76%,
161
+ rgba(155, 145, 105, 0.14) 0%,
162
+ transparent 70%
163
+ );
164
+ animation-duration: 52s;
165
+ animation-delay: -18s;
166
+ }
167
+ @keyframes backdropDrift {
168
+ from {
169
+ transform: translate3d(-4%, -3%, 0) scale(1) rotate(0deg);
170
+ }
171
+ to {
172
+ transform: translate3d(4%, 3%, 0) scale(1.18) rotate(5deg);
173
+ }
174
+ }
175
+ @media (prefers-reduced-motion: reduce) {
176
+ .hero-backdrop::before,
177
+ .hero-backdrop::after,
178
+ .card-backdrop::before {
179
+ animation: none;
180
+ }
181
+ }
182
+
183
+ .hero-gradient {
184
+ position: absolute;
185
+ inset: 0;
186
+ background: linear-gradient(
187
+ to bottom,
188
+ rgba(0, 0, 0, 0.3) 0%,
189
+ rgba(0, 0, 0, 0) 35%,
190
+ rgba(0, 0, 0, 0.65) 100%
191
+ );
192
+ z-index: 3;
193
+ pointer-events: none;
194
+ }
195
+
196
+ .navbar {
197
+ position: absolute;
198
+ top: 0;
199
+ left: 50%;
200
+ transform: translateX(-50%);
201
+ background: #000;
202
+ border-bottom-left-radius: 16px;
203
+ border-bottom-right-radius: 16px;
204
+ padding: 8px 16px;
205
+ display: flex;
206
+ align-items: center;
207
+ gap: 12px;
208
+ z-index: 10;
209
+ }
210
+ @media (min-width: 640px) {
211
+ .navbar {
212
+ gap: 24px;
213
+ }
214
+ }
215
+ @media (min-width: 768px) {
216
+ .navbar {
217
+ gap: 48px;
218
+ padding: 10px 32px;
219
+ border-bottom-left-radius: 24px;
220
+ border-bottom-right-radius: 24px;
221
+ }
222
+ }
223
+ @media (min-width: 1024px) {
224
+ .navbar {
225
+ gap: 56px;
226
+ }
227
+ }
228
+
229
+ .navbar a {
230
+ color: rgba(225, 224, 204, 0.8);
231
+ text-decoration: none;
232
+ font-size: 10px;
233
+ transition: color 0.2s ease;
234
+ white-space: nowrap;
235
+ letter-spacing: 0.02em;
236
+ }
237
+ .navbar a:hover {
238
+ color: #e1e0cc;
239
+ }
240
+ @media (min-width: 640px) {
241
+ .navbar a {
242
+ font-size: 12px;
243
+ }
244
+ }
245
+ @media (min-width: 768px) {
246
+ .navbar a {
247
+ font-size: 14px;
248
+ }
249
+ }
250
+
251
+ .hero-content {
252
+ position: absolute;
253
+ bottom: 0;
254
+ left: 0;
255
+ right: 0;
256
+ z-index: 5;
257
+ padding: 20px;
258
+ display: grid;
259
+ grid-template-columns: repeat(12, 1fr);
260
+ gap: 20px;
261
+ align-items: end;
262
+ }
263
+ @media (min-width: 768px) {
264
+ .hero-content {
265
+ padding: 36px;
266
+ gap: 24px;
267
+ }
268
+ }
269
+
270
+ .hero-title-col {
271
+ grid-column: 1 / -1;
272
+ }
273
+ @media (min-width: 768px) {
274
+ .hero-title-col {
275
+ grid-column: 1 / span 8;
276
+ }
277
+ }
278
+
279
+ .hero-desc-col {
280
+ grid-column: 1 / -1;
281
+ display: flex;
282
+ flex-direction: column;
283
+ gap: 20px;
284
+ padding-bottom: 8px;
285
+ }
286
+ @media (min-width: 768px) {
287
+ .hero-desc-col {
288
+ grid-column: 9 / span 4;
289
+ padding-bottom: 24px;
290
+ }
291
+ }
292
+
293
+ .hero-title {
294
+ color: #e1e0cc;
295
+ font-size: 26vw;
296
+ font-weight: 500;
297
+ line-height: 0.85;
298
+ letter-spacing: -0.07em;
299
+ display: inline-block;
300
+ position: relative;
301
+ }
302
+ @media (min-width: 640px) {
303
+ .hero-title {
304
+ font-size: 24vw;
305
+ }
306
+ }
307
+ @media (min-width: 768px) {
308
+ .hero-title {
309
+ font-size: 22vw;
310
+ }
311
+ }
312
+ @media (min-width: 1024px) {
313
+ .hero-title {
314
+ font-size: 20vw;
315
+ }
316
+ }
317
+ @media (min-width: 1280px) {
318
+ .hero-title {
319
+ font-size: 19vw;
320
+ }
321
+ }
322
+ @media (min-width: 1536px) {
323
+ .hero-title {
324
+ font-size: 20vw;
325
+ }
326
+ }
327
+
328
+ .hero-asterisk {
329
+ position: absolute;
330
+ top: 0.65em;
331
+ right: -0.3em;
332
+ font-size: 0.31em;
333
+ font-weight: 400;
334
+ line-height: 1;
335
+ }
336
+
337
+ .hero-desc {
338
+ color: rgba(222, 219, 200, 0.7);
339
+ font-size: 12px;
340
+ line-height: 1.2;
341
+ letter-spacing: -0.005em;
342
+ }
343
+ @media (min-width: 640px) {
344
+ .hero-desc {
345
+ font-size: 14px;
346
+ }
347
+ }
348
+ @media (min-width: 768px) {
349
+ .hero-desc {
350
+ font-size: 16px;
351
+ }
352
+ }
353
+
354
+ .cta-btn {
355
+ display: inline-flex;
356
+ align-items: center;
357
+ gap: 8px;
358
+ background: #dedbc8;
359
+ color: #000;
360
+ border-radius: 9999px;
361
+ padding: 6px 6px 6px 22px;
362
+ font-weight: 500;
363
+ font-size: 14px;
364
+ border: none;
365
+ cursor: pointer;
366
+ align-self: flex-start;
367
+ transition: gap 0.3s ease;
368
+ font-family: inherit;
369
+ }
370
+ .cta-btn:hover {
371
+ gap: 12px;
372
+ }
373
+ @media (min-width: 640px) {
374
+ .cta-btn {
375
+ font-size: 16px;
376
+ }
377
+ }
378
+
379
+ .cta-circle {
380
+ background: #000;
381
+ border-radius: 9999px;
382
+ width: 36px;
383
+ height: 36px;
384
+ display: inline-flex;
385
+ align-items: center;
386
+ justify-content: center;
387
+ color: #e1e0cc;
388
+ transition: transform 0.3s ease;
389
+ flex-shrink: 0;
390
+ }
391
+ .cta-btn:hover .cta-circle {
392
+ transform: scale(1.1);
393
+ }
394
+ @media (min-width: 640px) {
395
+ .cta-circle {
396
+ width: 40px;
397
+ height: 40px;
398
+ }
399
+ }
400
+
401
+ /* === ABOUT === */
402
+ .about {
403
+ background: #000;
404
+ padding: 80px 16px;
405
+ }
406
+ @media (min-width: 768px) {
407
+ .about {
408
+ padding: 140px 32px;
409
+ }
410
+ }
411
+
412
+ .about-card {
413
+ background: #101010;
414
+ text-align: center;
415
+ max-width: 72rem;
416
+ margin: 0 auto;
417
+ padding: 64px 24px;
418
+ border-radius: 18px;
419
+ }
420
+ @media (min-width: 768px) {
421
+ .about-card {
422
+ padding: 140px 56px;
423
+ border-radius: 28px;
424
+ }
425
+ }
426
+
427
+ .about-label {
428
+ color: #dedbc8;
429
+ font-size: 10px;
430
+ margin-bottom: 36px;
431
+ letter-spacing: 0.18em;
432
+ text-transform: uppercase;
433
+ }
434
+ @media (min-width: 640px) {
435
+ .about-label {
436
+ font-size: 12px;
437
+ }
438
+ }
439
+
440
+ .about-heading {
441
+ font-size: 30px;
442
+ max-width: 48rem;
443
+ margin: 0 auto;
444
+ line-height: 0.95;
445
+ font-weight: 400;
446
+ color: #dedbc8;
447
+ }
448
+ @media (min-width: 640px) {
449
+ .about-heading {
450
+ font-size: 36px;
451
+ line-height: 0.9;
452
+ }
453
+ }
454
+ @media (min-width: 768px) {
455
+ .about-heading {
456
+ font-size: 48px;
457
+ }
458
+ }
459
+ @media (min-width: 1024px) {
460
+ .about-heading {
461
+ font-size: 60px;
462
+ }
463
+ }
464
+ @media (min-width: 1280px) {
465
+ .about-heading {
466
+ font-size: 72px;
467
+ }
468
+ }
469
+
470
+ .about-heading .pull-word {
471
+ margin-right: 0.2em;
472
+ }
473
+
474
+ .about-body {
475
+ color: #dedbc8;
476
+ font-size: 13px;
477
+ margin-top: 48px;
478
+ max-width: 44rem;
479
+ margin-left: auto;
480
+ margin-right: auto;
481
+ line-height: 1.55;
482
+ }
483
+ @media (min-width: 640px) {
484
+ .about-body {
485
+ font-size: 15px;
486
+ }
487
+ }
488
+ @media (min-width: 768px) {
489
+ .about-body {
490
+ font-size: 17px;
491
+ }
492
+ }
493
+
494
+ .about-letter {
495
+ display: inline;
496
+ opacity: 0.2;
497
+ transition: opacity 0.15s linear;
498
+ }
499
+
500
+ /* === FEATURES === */
501
+ .features {
502
+ background: #000;
503
+ min-height: 100vh;
504
+ position: relative;
505
+ padding: 80px 16px;
506
+ overflow: hidden;
507
+ }
508
+ @media (min-width: 768px) {
509
+ .features {
510
+ padding: 120px 32px;
511
+ }
512
+ }
513
+
514
+ .features::before {
515
+ content: "";
516
+ position: absolute;
517
+ inset: 0;
518
+ opacity: 0.15;
519
+ pointer-events: none;
520
+ background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
521
+ }
522
+
523
+ .features-inner {
524
+ position: relative;
525
+ max-width: 90rem;
526
+ margin: 0 auto;
527
+ }
528
+
529
+ .features-header {
530
+ max-width: 56rem;
531
+ margin: 0 auto 56px;
532
+ text-align: center;
533
+ font-size: 20px;
534
+ line-height: 1.1;
535
+ font-weight: 400;
536
+ }
537
+ @media (min-width: 640px) {
538
+ .features-header {
539
+ font-size: 24px;
540
+ }
541
+ }
542
+ @media (min-width: 768px) {
543
+ .features-header {
544
+ font-size: 30px;
545
+ margin-bottom: 72px;
546
+ }
547
+ }
548
+ @media (min-width: 1024px) {
549
+ .features-header {
550
+ font-size: 36px;
551
+ }
552
+ }
553
+
554
+ .features-header .line1 {
555
+ color: #dedbc8;
556
+ }
557
+ .features-header .line2 {
558
+ color: #6b7280;
559
+ }
560
+ .features-header .break {
561
+ display: block;
562
+ height: 0.1em;
563
+ }
564
+
565
+ .feature-grid {
566
+ display: grid;
567
+ grid-template-columns: 1fr;
568
+ gap: 12px;
569
+ }
570
+ @media (min-width: 768px) {
571
+ .feature-grid {
572
+ grid-template-columns: repeat(2, 1fr);
573
+ gap: 8px;
574
+ }
575
+ }
576
+ @media (min-width: 1024px) {
577
+ .feature-grid {
578
+ grid-template-columns: repeat(4, 1fr);
579
+ gap: 4px;
580
+ height: 480px;
581
+ }
582
+ }
583
+
584
+ .feature-card {
585
+ background: #212121;
586
+ border-radius: 18px;
587
+ padding: 22px;
588
+ display: flex;
589
+ flex-direction: column;
590
+ min-height: 380px;
591
+ position: relative;
592
+ overflow: hidden;
593
+ opacity: 0;
594
+ transform: scale(0.95);
595
+ transition:
596
+ opacity 0.8s cubic-bezier(0.22, 1, 0.36, 1),
597
+ transform 0.8s cubic-bezier(0.22, 1, 0.36, 1);
598
+ }
599
+ .feature-card.in {
600
+ opacity: 1;
601
+ transform: scale(1);
602
+ }
603
+
604
+ .feature-card.visual {
605
+ padding: 0;
606
+ background: #000;
607
+ min-height: 380px;
608
+ }
609
+ .feature-card.visual .card-backdrop {
610
+ position: absolute;
611
+ inset: 0;
612
+ overflow: hidden;
613
+ }
614
+ .feature-card.visual .card-backdrop::before {
615
+ content: "";
616
+ position: absolute;
617
+ inset: -40%;
618
+ background:
619
+ radial-gradient(
620
+ 48% 55% at 30% 30%,
621
+ rgba(225, 224, 204, 0.18) 0%,
622
+ transparent 70%
623
+ ),
624
+ radial-gradient(
625
+ 40% 50% at 75% 75%,
626
+ rgba(125, 115, 80, 0.26) 0%,
627
+ transparent 70%
628
+ );
629
+ animation: backdropDrift 30s ease-in-out infinite alternate;
630
+ will-change: transform;
631
+ }
632
+ .feature-card.visual .vlabel {
633
+ position: relative;
634
+ z-index: 2;
635
+ margin-top: auto;
636
+ padding: 22px;
637
+ color: #e1e0cc;
638
+ font-size: 18px;
639
+ font-weight: 500;
640
+ }
641
+
642
+ .feature-icon {
643
+ width: 40px;
644
+ height: 40px;
645
+ border-radius: 8px;
646
+ object-fit: cover;
647
+ background: #0a0a0a;
648
+ }
649
+ @media (min-width: 640px) {
650
+ .feature-icon {
651
+ width: 48px;
652
+ height: 48px;
653
+ }
654
+ }
655
+
656
+ .feature-num {
657
+ color: #6b7280;
658
+ font-size: 11px;
659
+ margin-top: 16px;
660
+ letter-spacing: 0.05em;
661
+ }
662
+
663
+ .feature-title {
664
+ color: #dedbc8;
665
+ font-size: 19px;
666
+ font-weight: 500;
667
+ margin-top: 4px;
668
+ margin-bottom: 18px;
669
+ }
670
+
671
+ .feature-list {
672
+ list-style: none;
673
+ padding: 0;
674
+ margin: 0 0 18px 0;
675
+ display: flex;
676
+ flex-direction: column;
677
+ gap: 10px;
678
+ }
679
+
680
+ .feature-list li {
681
+ display: flex;
682
+ gap: 8px;
683
+ align-items: flex-start;
684
+ color: #9ca3af;
685
+ font-size: 12.5px;
686
+ line-height: 1.45;
687
+ }
688
+
689
+ .feature-list .check {
690
+ flex-shrink: 0;
691
+ margin-top: 2px;
692
+ color: #dedbc8;
693
+ }
694
+
695
+ .learn-more {
696
+ margin-top: auto;
697
+ display: inline-flex;
698
+ align-items: center;
699
+ gap: 6px;
700
+ color: #dedbc8;
701
+ font-size: 13px;
702
+ cursor: pointer;
703
+ text-decoration: none;
704
+ align-self: flex-start;
705
+ }
706
+
707
+ .learn-more svg {
708
+ transform: rotate(-45deg);
709
+ transition: transform 0.3s ease;
710
+ }
711
+ .learn-more:hover svg {
712
+ transform: rotate(-45deg) translate(3px, -3px);
713
+ }
714
+
715
+ /* === PENDING (pre-research) === */
716
+ .pending {
717
+ position: relative;
718
+ min-height: 100dvh;
719
+ display: flex;
720
+ align-items: center;
721
+ justify-content: center;
722
+ padding: 32px;
723
+ overflow: hidden;
724
+ }
725
+
726
+ .pending-content {
727
+ position: relative;
728
+ z-index: 3;
729
+ text-align: center;
730
+ display: flex;
731
+ flex-direction: column;
732
+ align-items: center;
733
+ gap: 20px;
734
+ }
735
+
736
+ .pending-label {
737
+ font-size: 11px;
738
+ font-weight: 700;
739
+ letter-spacing: 0.3em;
740
+ color: #6b7280;
741
+ }
742
+
743
+ .pending-heading {
744
+ font-size: clamp(36px, 7vw, 72px);
745
+ font-weight: 800;
746
+ line-height: 1.1;
747
+ color: #e1e0cc;
748
+ }
749
+
750
+ .pending-heading .serif-italic {
751
+ font-weight: 400;
752
+ }
753
+
754
+ .pending-sub {
755
+ max-width: 420px;
756
+ font-size: 14px;
757
+ line-height: 1.7;
758
+ color: #9ca3af;
759
+ }