@vellumai/assistant 0.4.26 → 0.4.30
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.
- package/.env.example +2 -2
- package/AGENTS.md +5 -0
- package/ARCHITECTURE.md +207 -105
- package/Dockerfile +1 -1
- package/README.md +111 -113
- package/bun.lock +0 -3
- package/docs/architecture/integrations.md +0 -1
- package/docs/architecture/memory.md +100 -63
- package/docs/error-handling.md +71 -0
- package/docs/runbook-trusted-contacts.md +89 -52
- package/docs/trusted-contact-access.md +48 -46
- package/package.json +3 -3
- package/scripts/compare-benchmarks.sh +12 -5
- package/scripts/ipc/check-swift-decoder-drift.ts +5 -3
- package/scripts/test.sh +89 -5
- package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +50 -37
- package/src/__tests__/access-request-decision.test.ts +0 -1
- package/src/__tests__/account-registry.test.ts +1 -1
- package/src/__tests__/actor-token-service.test.ts +40 -26
- package/src/__tests__/agent-loop-thinking.test.ts +29 -13
- package/src/__tests__/agent-loop.test.ts +2 -1
- package/src/__tests__/app-builder-tool-scripts.test.ts +1 -1
- package/src/__tests__/app-executors.test.ts +7 -17
- package/src/__tests__/approval-routes-http.test.ts +2 -2
- package/src/__tests__/asset-materialize-tool.test.ts +7 -7
- package/src/__tests__/asset-search-tool.test.ts +7 -7
- package/src/__tests__/assistant-feature-flags-integration.test.ts +18 -10
- package/src/__tests__/browser-fill-credential.test.ts +1 -1
- package/src/__tests__/browser-skill-endstate.test.ts +10 -1
- package/src/__tests__/bundled-skill-retrieval-guard.test.ts +218 -0
- package/src/__tests__/call-controller.test.ts +99 -69
- package/src/__tests__/call-start-guardian-guard.test.ts +1 -1
- package/src/__tests__/channel-approval-routes.test.ts +157 -114
- package/src/__tests__/channel-approval.test.ts +8 -0
- package/src/__tests__/channel-approvals.test.ts +39 -1
- package/src/__tests__/channel-guardian.test.ts +176 -275
- package/src/__tests__/channel-readiness-service.test.ts +6 -2
- package/src/__tests__/channel-reply-delivery.test.ts +33 -2
- package/src/__tests__/channel-retry-sweep.test.ts +14 -14
- package/src/__tests__/checker.test.ts +12 -31
- package/src/__tests__/claude-code-tool-profiles.test.ts +1 -1
- package/src/__tests__/commit-message-enrichment-service.test.ts +71 -59
- package/src/__tests__/compaction.benchmark.test.ts +6 -2
- package/src/__tests__/computer-use-tools.test.ts +1 -1
- package/src/__tests__/config-schema.test.ts +66 -7
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +29 -29
- package/src/__tests__/contacts-tools.test.ts +63 -2
- package/src/__tests__/context-overflow-approval.test.ts +141 -0
- package/src/__tests__/context-overflow-policy.test.ts +171 -0
- package/src/__tests__/context-overflow-reducer.test.ts +533 -0
- package/src/__tests__/context-window-manager.test.ts +97 -0
- package/src/__tests__/conversation-attention-telegram.test.ts +38 -46
- package/src/__tests__/conversation-pairing.test.ts +2 -2
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +214 -10
- package/src/__tests__/conversation-routes.test.ts +4 -7
- package/src/__tests__/credential-broker-browser-fill.test.ts +13 -2
- package/src/__tests__/credential-security-e2e.test.ts +1 -1
- package/src/__tests__/credential-security-invariants.test.ts +1 -1
- package/src/__tests__/credential-vault-unit.test.ts +1 -1
- package/src/__tests__/credential-vault.test.ts +11 -8
- package/src/__tests__/daemon-lifecycle.test.ts +2 -2
- package/src/__tests__/daemon-server-session-init.test.ts +6 -6
- package/src/__tests__/delete-managed-skill-tool.test.ts +1 -1
- package/src/__tests__/deterministic-verification-control-plane.test.ts +2 -2
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +9 -0
- package/src/__tests__/emit-signal-routing-intent.test.ts +4 -0
- package/src/__tests__/encrypted-store.test.ts +10 -7
- package/src/__tests__/ephemeral-permissions.test.ts +3 -3
- package/src/__tests__/file-edit-tool.test.ts +1 -1
- package/src/__tests__/file-read-tool.test.ts +1 -1
- package/src/__tests__/file-write-tool.test.ts +1 -1
- package/src/__tests__/fixtures/credential-security-fixtures.ts +87 -64
- package/src/__tests__/fixtures/media-reuse-fixtures.ts +37 -31
- package/src/__tests__/fixtures/mock-signup-server.ts +171 -115
- package/src/__tests__/fixtures/proxy-fixtures.ts +39 -39
- package/src/__tests__/followup-tools.test.ts +1 -1
- package/src/__tests__/gateway-only-guard.test.ts +4 -0
- package/src/__tests__/gemini-image-service.test.ts +2 -2
- package/src/__tests__/guardian-actions-endpoint.test.ts +543 -1
- package/src/__tests__/guardian-control-plane-policy.test.ts +15 -15
- package/src/__tests__/guardian-dispatch.test.ts +79 -1
- package/src/__tests__/guardian-grant-minting.test.ts +20 -20
- package/src/__tests__/guardian-outbound-http.test.ts +1 -2
- package/src/__tests__/guardian-principal-id-roundtrip.test.ts +0 -41
- package/src/__tests__/guardian-routing-invariants.test.ts +36 -16
- package/src/__tests__/guardian-routing-state.test.ts +36 -52
- package/src/__tests__/guardian-verification-intent-routing.test.ts +4 -6
- package/src/__tests__/guardian-verify-setup-skill-regression.test.ts +6 -8
- package/src/__tests__/handle-user-message-secret-resume.test.ts +39 -1
- package/src/__tests__/handlers-cu-observation-blob.test.ts +21 -10
- package/src/__tests__/handlers-telegram-config.test.ts +14 -14
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +23 -2
- package/src/__tests__/headless-browser-interactions.test.ts +1 -1
- package/src/__tests__/headless-browser-navigate.test.ts +1 -1
- package/src/__tests__/headless-browser-read-tools.test.ts +1 -1
- package/src/__tests__/headless-browser-snapshot.test.ts +1 -1
- package/src/__tests__/heartbeat-service.test.ts +45 -2
- package/src/__tests__/host-file-edit-tool.test.ts +1 -1
- package/src/__tests__/host-file-read-tool.test.ts +1 -1
- package/src/__tests__/host-file-write-tool.test.ts +1 -1
- package/src/__tests__/host-shell-tool.test.ts +1 -1
- package/src/__tests__/inbound-invite-redemption.test.ts +17 -19
- package/src/__tests__/ingress-reconcile.test.ts +2 -2
- package/src/__tests__/integrations-cli.test.ts +232 -0
- package/src/__tests__/intent-routing.test.ts +7 -5
- package/src/__tests__/invite-redemption-service.test.ts +5 -4
- package/src/__tests__/{ingress-routes-http.test.ts → invite-routes-http.test.ts} +42 -321
- package/src/__tests__/ipc-snapshot.test.ts +32 -31
- package/src/__tests__/managed-skill-lifecycle.test.ts +1 -1
- package/src/__tests__/mcp-cli.test.ts +136 -57
- package/src/__tests__/mcp-client-auth.test.ts +95 -0
- package/src/__tests__/media-generate-image.test.ts +2 -2
- package/src/__tests__/media-reuse-story.e2e.test.ts +8 -8
- package/src/__tests__/memory-regressions.test.ts +6 -6
- package/src/__tests__/messaging-send-tool.test.ts +1 -1
- package/src/__tests__/migration-cross-version-compatibility.test.ts +1855 -0
- package/src/__tests__/migration-export-http.test.ts +540 -0
- package/src/__tests__/migration-import-commit-http.test.ts +823 -0
- package/src/__tests__/migration-import-preflight-http.test.ts +755 -0
- package/src/__tests__/migration-parity-persistence.test.ts +1854 -0
- package/src/__tests__/migration-transport.test.ts +904 -0
- package/src/__tests__/migration-validate-http.test.ts +698 -0
- package/src/__tests__/migration-wizard.test.ts +1289 -0
- package/src/__tests__/nl-approval-parser.test.ts +305 -0
- package/src/__tests__/non-member-access-request.test.ts +17 -17
- package/src/__tests__/notification-decision-strategy.test.ts +110 -2
- package/src/__tests__/notification-deep-link.test.ts +18 -0
- package/src/__tests__/notification-guardian-path.test.ts +0 -1
- package/src/__tests__/oauth-provider-profiles.test.ts +34 -0
- package/src/__tests__/oauth2-gateway-transport.test.ts +1 -1
- package/src/__tests__/playbook-execution.test.ts +1 -1
- package/src/__tests__/playbook-tools.test.ts +1 -1
- package/src/__tests__/provider-error-scenarios.test.ts +68 -0
- package/src/__tests__/provider-streaming.benchmark.test.ts +3 -1
- package/src/__tests__/proxy-approval-callback.test.ts +1 -1
- package/src/__tests__/qdrant-manager.test.ts +40 -11
- package/src/__tests__/rebind-secrets-screen.test.ts +839 -0
- package/src/__tests__/recording-handler.test.ts +2 -2
- package/src/__tests__/recording-intent-handler.test.ts +3 -3
- package/src/__tests__/recording-state-machine.test.ts +2 -2
- package/src/__tests__/relay-server.test.ts +507 -228
- package/src/__tests__/reminder-store.test.ts +8 -0
- package/src/__tests__/reminder.test.ts +8 -0
- package/src/__tests__/{resolve-guardian-trust-class.test.ts → resolve-trust-class.test.ts} +11 -17
- package/src/__tests__/retry-after-extraction.test.ts +111 -0
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +1 -1
- package/src/__tests__/schedule-tools.test.ts +1 -1
- package/src/__tests__/script-proxy-certs.test.ts +1 -1
- package/src/__tests__/script-proxy-connect-tunnel.test.ts +2 -3
- package/src/__tests__/script-proxy-decision-trace.test.ts +2 -2
- package/src/__tests__/script-proxy-http-forwarder.test.ts +1 -1
- package/src/__tests__/script-proxy-injection-runtime.test.ts +5 -5
- package/src/__tests__/script-proxy-mitm-handler.test.ts +4 -4
- package/src/__tests__/script-proxy-policy-runtime.test.ts +2 -2
- package/src/__tests__/script-proxy-policy.test.ts +2 -2
- package/src/__tests__/script-proxy-profile-template-fallback.test.ts +127 -0
- package/src/__tests__/script-proxy-session-manager.test.ts +4 -7
- package/src/__tests__/script-proxy-session-runtime.test.ts +1 -6
- package/src/__tests__/secret-onetime-send.test.ts +4 -4
- package/src/__tests__/secret-scanner-executor.test.ts +2 -2
- package/src/__tests__/send-endpoint-busy.test.ts +11 -9
- package/src/__tests__/send-notification-tool.test.ts +2 -2
- package/src/__tests__/session-abort-tool-results.test.ts +17 -2
- package/src/__tests__/session-agent-loop.test.ts +456 -35
- package/src/__tests__/session-confirmation-signals.test.ts +3 -2
- package/src/__tests__/session-conflict-gate.test.ts +20 -3
- package/src/__tests__/session-init.benchmark.test.ts +2 -2
- package/src/__tests__/session-load-history-repair.test.ts +7 -7
- package/src/__tests__/session-media-retry.test.ts +147 -0
- package/src/__tests__/session-pre-run-repair.test.ts +17 -2
- package/src/__tests__/session-profile-injection.test.ts +20 -3
- package/src/__tests__/session-provider-retry-repair.test.ts +86 -6
- package/src/__tests__/session-queue.test.ts +33 -18
- package/src/__tests__/session-runtime-assembly.test.ts +147 -1
- package/src/__tests__/session-runtime-workspace.test.ts +40 -0
- package/src/__tests__/session-slash-known.test.ts +21 -3
- package/src/__tests__/session-slash-queue.test.ts +17 -2
- package/src/__tests__/session-slash-unknown.test.ts +17 -2
- package/src/__tests__/session-surfaces-deselection.test.ts +208 -0
- package/src/__tests__/session-workspace-cache-state.test.ts +2 -2
- package/src/__tests__/session-workspace-injection.test.ts +17 -2
- package/src/__tests__/session-workspace-tool-tracking.test.ts +17 -2
- package/src/__tests__/shell-credential-ref.test.ts +1 -1
- package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -1
- package/src/__tests__/skill-feature-flags-integration.test.ts +9 -5
- package/src/__tests__/skill-feature-flags.test.ts +18 -12
- package/src/__tests__/skill-load-feature-flag.test.ts +5 -4
- package/src/__tests__/skill-load-tool.test.ts +1 -1
- package/src/__tests__/skill-script-runner-host.test.ts +1 -1
- package/src/__tests__/skill-script-runner-sandbox.test.ts +1 -1
- package/src/__tests__/skill-script-runner.test.ts +1 -1
- package/src/__tests__/skill-tool-factory.test.ts +1 -1
- package/src/__tests__/slack-block-formatting.test.ts +100 -0
- package/src/__tests__/slack-inbound-verification.test.ts +346 -0
- package/src/__tests__/slack-reaction-approvals.test.ts +77 -0
- package/src/__tests__/slack-skill.test.ts +4 -2
- package/src/__tests__/starter-task-flow.test.ts +0 -1
- package/src/__tests__/subagent-tools.test.ts +3 -3
- package/src/__tests__/swarm-recursion.test.ts +1 -1
- package/src/__tests__/swarm-session-integration.test.ts +1 -1
- package/src/__tests__/swarm-tool.test.ts +1 -1
- package/src/__tests__/task-management-tools.test.ts +1 -1
- package/src/__tests__/task-tools.test.ts +1 -1
- package/src/__tests__/terminal-tools.test.ts +1 -1
- package/src/__tests__/test-support/browser-skill-harness.ts +39 -27
- package/src/__tests__/test-support/computer-use-skill-harness.ts +14 -14
- package/src/__tests__/tool-approval-handler.test.ts +15 -15
- package/src/__tests__/tool-execution-abort-cleanup.test.ts +1 -1
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +1 -1
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +2 -2
- package/src/__tests__/tool-executor-shell-integration.test.ts +1 -1
- package/src/__tests__/tool-executor.test.ts +23 -182
- package/src/__tests__/tool-grant-request-escalation.test.ts +11 -11
- package/src/__tests__/tool-permission-simulate-handler.test.ts +4 -4
- package/src/__tests__/transfer-progress-screen.test.ts +1180 -0
- package/src/__tests__/trust-context-guards.test.ts +25 -29
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +23 -21
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +37 -40
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +29 -25
- package/src/__tests__/trusted-contact-multichannel.test.ts +25 -24
- package/src/__tests__/trusted-contact-verification.test.ts +64 -76
- package/src/__tests__/turn-commit.test.ts +18 -18
- package/src/__tests__/twilio-provider.test.ts +7 -7
- package/src/__tests__/validation-results-screen.test.ts +1107 -0
- package/src/__tests__/view-image-tool.test.ts +1 -1
- package/src/__tests__/voice-invite-redemption.test.ts +4 -3
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +12 -12
- package/src/__tests__/voice-session-bridge.test.ts +24 -24
- package/src/agent/attachments.ts +3 -1
- package/src/agent/loop.ts +13 -13
- package/src/agent/message-types.ts +13 -7
- package/src/amazon/cart.ts +59 -32
- package/src/amazon/checkout.ts +25 -14
- package/src/amazon/client.ts +61 -58
- package/src/amazon/product-details.ts +3 -3
- package/src/amazon/request-extractor.ts +46 -31
- package/src/amazon/search.ts +6 -4
- package/src/amazon/session.ts +33 -24
- package/src/approvals/AGENTS.md +26 -0
- package/src/approvals/approval-primitive.ts +87 -64
- package/src/approvals/guardian-decision-primitive.ts +172 -81
- package/src/approvals/guardian-request-resolvers.ts +262 -155
- package/src/autonomy/autonomy-resolver.ts +7 -5
- package/src/autonomy/autonomy-store.ts +34 -19
- package/src/autonomy/disposition-mapper.ts +5 -5
- package/src/autonomy/index.ts +6 -6
- package/src/autonomy/types.ts +7 -3
- package/src/browser-extension-relay/client.ts +50 -19
- package/src/browser-extension-relay/protocol.ts +11 -11
- package/src/browser-extension-relay/server.ts +45 -20
- package/src/bundler/app-bundler.ts +75 -50
- package/src/bundler/bundle-scanner.ts +145 -41
- package/src/bundler/bundle-signer.ts +16 -14
- package/src/bundler/signature-verifier.ts +36 -33
- package/src/calls/call-constants.ts +10 -3
- package/src/calls/call-controller.ts +473 -214
- package/src/calls/call-conversation-messages.ts +25 -15
- package/src/calls/call-domain.ts +401 -148
- package/src/calls/call-pointer-message-composer.ts +26 -21
- package/src/calls/call-pointer-messages.ts +52 -28
- package/src/calls/call-recovery.ts +53 -37
- package/src/calls/call-state-machine.ts +37 -7
- package/src/calls/call-state.ts +35 -13
- package/src/calls/call-store.ts +165 -77
- package/src/calls/elevenlabs-client.ts +39 -20
- package/src/calls/guardian-action-sweep.ts +42 -24
- package/src/calls/guardian-dispatch.ts +79 -56
- package/src/calls/guardian-question-copy.ts +28 -23
- package/src/calls/relay-server.ts +1149 -532
- package/src/calls/speaker-identification.ts +21 -15
- package/src/calls/twilio-config.ts +34 -17
- package/src/calls/twilio-provider.ts +108 -55
- package/src/calls/twilio-rest.ts +212 -100
- package/src/calls/twilio-routes.ts +165 -92
- package/src/calls/types.ts +55 -7
- package/src/calls/voice-quality.ts +6 -4
- package/src/calls/voice-session-bridge.ts +181 -133
- package/src/channels/config.ts +18 -14
- package/src/channels/types.ts +38 -10
- package/src/cli/amazon.ts +333 -227
- package/src/cli/config-commands.ts +236 -146
- package/src/cli/core-commands.ts +403 -329
- package/src/cli/email-guardrails.ts +38 -19
- package/src/cli/email.ts +207 -153
- package/src/cli/influencer.ts +58 -56
- package/src/cli/integrations.ts +306 -0
- package/src/cli/ipc-client.ts +24 -19
- package/src/cli/map.ts +176 -129
- package/src/cli/mcp.ts +260 -152
- package/src/cli/sequence.ts +165 -107
- package/src/cli/twitter.ts +302 -218
- package/src/cli.ts +418 -279
- package/src/commands/cc-command-registry.ts +52 -27
- package/src/config/agent-schema.ts +217 -134
- package/src/config/assistant-feature-flags.ts +23 -18
- package/src/config/bundled-skills/_shared/CLI_RETRIEVAL_PATTERN.md +19 -0
- package/src/config/bundled-skills/app-builder/SKILL.md +193 -1500
- package/src/config/bundled-skills/app-builder/TOOLS.json +70 -18
- package/src/config/bundled-skills/app-builder/tools/app-create.ts +7 -4
- package/src/config/bundled-skills/app-builder/tools/app-delete.ts +6 -3
- package/src/config/bundled-skills/app-builder/tools/app-file-edit.ts +7 -4
- package/src/config/bundled-skills/app-builder/tools/app-file-list.ts +6 -3
- package/src/config/bundled-skills/app-builder/tools/app-file-read.ts +6 -3
- package/src/config/bundled-skills/app-builder/tools/app-file-write.ts +7 -4
- package/src/config/bundled-skills/app-builder/tools/app-list.ts +6 -3
- package/src/config/bundled-skills/app-builder/tools/app-query.ts +6 -3
- package/src/config/bundled-skills/app-builder/tools/app-update.ts +6 -3
- package/src/config/bundled-skills/browser/TOOLS.json +59 -2
- package/src/config/bundled-skills/browser/tools/browser-click.ts +5 -2
- package/src/config/bundled-skills/browser/tools/browser-close.ts +5 -2
- package/src/config/bundled-skills/browser/tools/browser-extract.ts +5 -2
- package/src/config/bundled-skills/browser/tools/browser-fill-credential.ts +5 -2
- package/src/config/bundled-skills/browser/tools/browser-hover.ts +5 -2
- package/src/config/bundled-skills/browser/tools/browser-navigate.ts +5 -2
- package/src/config/bundled-skills/browser/tools/browser-press-key.ts +5 -2
- package/src/config/bundled-skills/browser/tools/browser-screenshot.ts +5 -2
- package/src/config/bundled-skills/browser/tools/browser-scroll.ts +5 -2
- package/src/config/bundled-skills/browser/tools/browser-select-option.ts +5 -2
- package/src/config/bundled-skills/browser/tools/browser-snapshot.ts +5 -2
- package/src/config/bundled-skills/browser/tools/browser-type.ts +5 -2
- package/src/config/bundled-skills/browser/tools/browser-wait-for-download.ts +13 -6
- package/src/config/bundled-skills/browser/tools/browser-wait-for.ts +5 -2
- package/src/config/bundled-skills/chatgpt-import/TOOLS.json +4 -0
- package/src/config/bundled-skills/claude-code/TOOLS.json +4 -0
- package/src/config/bundled-skills/claude-code/tools/claude-code.ts +5 -2
- package/src/config/bundled-skills/computer-use/SKILL.md +2 -2
- package/src/config/bundled-skills/computer-use/TOOLS.json +50 -2
- package/src/config/bundled-skills/computer-use/tools/computer-use-click.ts +6 -3
- package/src/config/bundled-skills/computer-use/tools/computer-use-done.ts +6 -3
- package/src/config/bundled-skills/computer-use/tools/computer-use-double-click.ts +10 -3
- package/src/config/bundled-skills/computer-use/tools/computer-use-drag.ts +6 -3
- package/src/config/bundled-skills/computer-use/tools/computer-use-key.ts +6 -3
- package/src/config/bundled-skills/computer-use/tools/computer-use-open-app.ts +6 -3
- package/src/config/bundled-skills/computer-use/tools/computer-use-request-control.ts +10 -3
- package/src/config/bundled-skills/computer-use/tools/computer-use-respond.ts +6 -3
- package/src/config/bundled-skills/computer-use/tools/computer-use-right-click.ts +10 -3
- package/src/config/bundled-skills/computer-use/tools/computer-use-run-applescript.ts +10 -3
- package/src/config/bundled-skills/computer-use/tools/computer-use-scroll.ts +6 -3
- package/src/config/bundled-skills/computer-use/tools/computer-use-type-text.ts +6 -3
- package/src/config/bundled-skills/computer-use/tools/computer-use-wait.ts +6 -3
- package/src/config/bundled-skills/configure-settings/SKILL.md +28 -14
- package/src/config/bundled-skills/contacts/SKILL.md +453 -15
- package/src/config/bundled-skills/contacts/TOOLS.json +22 -2
- package/src/config/bundled-skills/contacts/tools/contact-merge.ts +79 -20
- package/src/config/bundled-skills/contacts/tools/contact-search.ts +55 -18
- package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +64 -19
- package/src/config/bundled-skills/document/TOOLS.json +8 -0
- package/src/config/bundled-skills/document/tools/document-create.ts +5 -2
- package/src/config/bundled-skills/document/tools/document-update.ts +5 -2
- package/src/config/bundled-skills/doordash/doordash-cli.ts +17 -7
- package/src/config/bundled-skills/email-setup/SKILL.md +12 -9
- package/src/config/bundled-skills/followups/TOOLS.json +12 -0
- package/src/config/bundled-skills/followups/tools/followup-create.ts +5 -2
- package/src/config/bundled-skills/followups/tools/followup-list.ts +5 -2
- package/src/config/bundled-skills/followups/tools/followup-resolve.ts +5 -2
- package/src/config/bundled-skills/google-calendar/TOOLS.json +124 -26
- package/src/config/bundled-skills/google-calendar/calendar-client.ts +44 -32
- package/src/config/bundled-skills/google-calendar/tools/calendar-check-availability.ts +11 -5
- package/src/config/bundled-skills/google-calendar/tools/calendar-create-event.ts +13 -7
- package/src/config/bundled-skills/google-calendar/tools/calendar-get-event.ts +11 -5
- package/src/config/bundled-skills/google-calendar/tools/calendar-list-events.ts +13 -7
- package/src/config/bundled-skills/google-calendar/tools/calendar-rsvp.ts +28 -12
- package/src/config/bundled-skills/google-calendar/tools/shared.ts +6 -4
- package/src/config/bundled-skills/google-calendar/types.ts +3 -3
- package/src/config/bundled-skills/guardian-verify-setup/SKILL.md +88 -33
- package/src/config/bundled-skills/image-studio/TOOLS.json +12 -2
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +48 -25
- package/src/config/bundled-skills/knowledge-graph/TOOLS.json +13 -3
- package/src/config/bundled-skills/knowledge-graph/tools/graph-query.ts +60 -35
- package/src/config/bundled-skills/mcp-setup/SKILL.md +75 -0
- package/src/config/bundled-skills/media-processing/SKILL.md +55 -15
- package/src/config/bundled-skills/media-processing/TOOLS.json +48 -2
- package/src/config/bundled-skills/media-processing/__tests__/concurrency-pool.test.ts +12 -10
- package/src/config/bundled-skills/media-processing/__tests__/cost-tracker.test.ts +34 -19
- package/src/config/bundled-skills/media-processing/__tests__/preprocess.test.ts +82 -66
- package/src/config/bundled-skills/media-processing/services/audio-transcribe.ts +148 -0
- package/src/config/bundled-skills/media-processing/services/concurrency-pool.ts +1 -1
- package/src/config/bundled-skills/media-processing/services/cost-tracker.ts +8 -3
- package/src/config/bundled-skills/media-processing/services/gemini-map.ts +117 -53
- package/src/config/bundled-skills/media-processing/services/gemini-video.ts +273 -0
- package/src/config/bundled-skills/media-processing/services/preprocess.ts +185 -97
- package/src/config/bundled-skills/media-processing/services/processing-pipeline.ts +32 -27
- package/src/config/bundled-skills/media-processing/services/reduce.ts +101 -24
- package/src/config/bundled-skills/media-processing/tools/analyze-keyframes.ts +121 -55
- package/src/config/bundled-skills/media-processing/tools/extract-keyframes.ts +58 -24
- package/src/config/bundled-skills/media-processing/tools/generate-clip.ts +198 -92
- package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +98 -70
- package/src/config/bundled-skills/media-processing/tools/media-diagnostics.ts +59 -19
- package/src/config/bundled-skills/media-processing/tools/media-status.ts +26 -10
- package/src/config/bundled-skills/media-processing/tools/query-media-events.ts +29 -14
- package/src/config/bundled-skills/messaging/SKILL.md +7 -5
- package/src/config/bundled-skills/messaging/TOOLS.json +232 -186
- package/src/config/bundled-skills/messaging/tools/gmail-archive-by-query.ts +31 -13
- package/src/config/bundled-skills/messaging/tools/gmail-archive.ts +16 -10
- package/src/config/bundled-skills/messaging/tools/gmail-batch-label.ts +18 -9
- package/src/config/bundled-skills/messaging/tools/gmail-download-attachment.ts +23 -16
- package/src/config/bundled-skills/messaging/tools/gmail-draft.ts +28 -12
- package/src/config/bundled-skills/messaging/tools/gmail-filters.ts +41 -21
- package/src/config/bundled-skills/messaging/tools/gmail-follow-up.ts +44 -23
- package/src/config/bundled-skills/messaging/tools/gmail-forward.ts +73 -33
- package/src/config/bundled-skills/messaging/tools/gmail-label.ts +15 -9
- package/src/config/bundled-skills/messaging/tools/gmail-list-attachments.ts +22 -14
- package/src/config/bundled-skills/messaging/tools/gmail-outreach-scan.ts +99 -50
- package/src/config/bundled-skills/messaging/tools/gmail-send-draft.ts +14 -8
- package/src/config/bundled-skills/messaging/tools/gmail-send-with-attachments.ts +63 -44
- package/src/config/bundled-skills/messaging/tools/gmail-sender-digest.ts +90 -46
- package/src/config/bundled-skills/messaging/tools/gmail-summarize-thread.ts +43 -22
- package/src/config/bundled-skills/messaging/tools/gmail-trash.ts +15 -9
- package/src/config/bundled-skills/messaging/tools/gmail-triage.ts +51 -22
- package/src/config/bundled-skills/messaging/tools/gmail-unsubscribe.ts +62 -26
- package/src/config/bundled-skills/messaging/tools/gmail-vacation.ts +34 -19
- package/src/config/bundled-skills/messaging/tools/google-contacts.ts +32 -16
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-activity.ts +10 -4
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +91 -47
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +21 -9
- package/src/config/bundled-skills/messaging/tools/messaging-auth-test.ts +9 -3
- package/src/config/bundled-skills/messaging/tools/messaging-draft.ts +30 -17
- package/src/config/bundled-skills/messaging/tools/messaging-list-conversations.ts +10 -4
- package/src/config/bundled-skills/messaging/tools/messaging-mark-read.ts +14 -6
- package/src/config/bundled-skills/messaging/tools/messaging-read.ts +16 -5
- package/src/config/bundled-skills/messaging/tools/messaging-reply.ts +63 -36
- package/src/config/bundled-skills/messaging/tools/messaging-search.ts +10 -4
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +30 -12
- package/src/config/bundled-skills/messaging/tools/messaging-sender-digest.ts +48 -29
- package/src/config/bundled-skills/messaging/tools/scan-result-store.ts +20 -6
- package/src/config/bundled-skills/messaging/tools/send-notification.ts +1 -1
- package/src/config/bundled-skills/messaging/tools/sequence-analytics.ts +59 -22
- package/src/config/bundled-skills/messaging/tools/sequence-cancel.ts +13 -7
- package/src/config/bundled-skills/messaging/tools/sequence-create.ts +27 -12
- package/src/config/bundled-skills/messaging/tools/sequence-delete.ts +14 -6
- package/src/config/bundled-skills/messaging/tools/sequence-enroll.ts +30 -11
- package/src/config/bundled-skills/messaging/tools/sequence-enrollment-list.ts +16 -8
- package/src/config/bundled-skills/messaging/tools/sequence-get.ts +31 -13
- package/src/config/bundled-skills/messaging/tools/sequence-import.ts +38 -22
- package/src/config/bundled-skills/messaging/tools/sequence-list.ts +16 -7
- package/src/config/bundled-skills/messaging/tools/sequence-pause.ts +29 -10
- package/src/config/bundled-skills/messaging/tools/sequence-resume.ts +16 -8
- package/src/config/bundled-skills/messaging/tools/sequence-update.ts +35 -16
- package/src/config/bundled-skills/messaging/tools/shared.ts +26 -12
- package/src/config/bundled-skills/notifications/SKILL.md +3 -2
- package/src/config/bundled-skills/notifications/TOOLS.json +7 -13
- package/src/config/bundled-skills/notifications/tools/send-notification.ts +69 -34
- package/src/config/bundled-skills/notifications/tools/shared.ts +1 -1
- package/src/config/bundled-skills/phone-calls/SKILL.md +46 -48
- package/src/config/bundled-skills/phone-calls/TOOLS.json +13 -1
- package/src/config/bundled-skills/phone-calls/tools/call-end.ts +1 -1
- package/src/config/bundled-skills/phone-calls/tools/call-start.ts +1 -1
- package/src/config/bundled-skills/phone-calls/tools/call-status.ts +1 -1
- package/src/config/bundled-skills/playbooks/TOOLS.json +16 -0
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +91 -51
- package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +30 -16
- package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +66 -27
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +89 -42
- package/src/config/bundled-skills/public-ingress/SKILL.md +26 -19
- package/src/config/bundled-skills/reminder/TOOLS.json +15 -2
- package/src/config/bundled-skills/reminder/tools/reminder-cancel.ts +5 -2
- package/src/config/bundled-skills/reminder/tools/reminder-create.ts +5 -2
- package/src/config/bundled-skills/reminder/tools/reminder-list.ts +5 -2
- package/src/config/bundled-skills/schedule/SKILL.md +33 -15
- package/src/config/bundled-skills/schedule/TOOLS.json +17 -1
- package/src/config/bundled-skills/schedule/tools/schedule-create.ts +5 -2
- package/src/config/bundled-skills/schedule/tools/schedule-delete.ts +5 -2
- package/src/config/bundled-skills/schedule/tools/schedule-list.ts +5 -2
- package/src/config/bundled-skills/schedule/tools/schedule-update.ts +5 -2
- package/src/config/bundled-skills/screen-recording/SKILL.md +11 -3
- package/src/config/bundled-skills/self-upgrade/SKILL.md +9 -8
- package/src/config/bundled-skills/slack/SKILL.md +30 -1
- package/src/config/bundled-skills/slack/TOOLS.json +122 -17
- package/src/config/bundled-skills/slack/tools/shared.ts +7 -5
- package/src/config/bundled-skills/slack/tools/slack-add-reaction.ts +11 -5
- package/src/config/bundled-skills/slack/tools/slack-channel-details.ts +11 -5
- package/src/config/bundled-skills/slack/tools/slack-channel-permissions.ts +146 -0
- package/src/config/bundled-skills/slack/tools/slack-configure-channels.ts +46 -16
- package/src/config/bundled-skills/slack/tools/slack-delete-message.ts +11 -5
- package/src/config/bundled-skills/slack/tools/slack-edit-message.ts +28 -0
- package/src/config/bundled-skills/slack/tools/slack-leave-channel.ts +12 -6
- package/src/config/bundled-skills/slack/tools/slack-scan-digest.ts +120 -0
- package/src/config/bundled-skills/slack-app-setup/SKILL.md +200 -0
- package/src/config/bundled-skills/sms-setup/SKILL.md +5 -8
- package/src/config/bundled-skills/subagent/TOOLS.json +22 -2
- package/src/config/bundled-skills/subagent/tools/subagent-abort.ts +5 -2
- package/src/config/bundled-skills/subagent/tools/subagent-message.ts +5 -2
- package/src/config/bundled-skills/subagent/tools/subagent-read.ts +5 -2
- package/src/config/bundled-skills/subagent/tools/subagent-spawn.ts +5 -2
- package/src/config/bundled-skills/subagent/tools/subagent-status.ts +5 -2
- package/src/config/bundled-skills/tasks/TOOLS.json +86 -14
- package/src/config/bundled-skills/tasks/tools/task-delete.ts +5 -2
- package/src/config/bundled-skills/tasks/tools/task-list-add.ts +5 -2
- package/src/config/bundled-skills/tasks/tools/task-list-remove.ts +5 -2
- package/src/config/bundled-skills/tasks/tools/task-list-show.ts +5 -2
- package/src/config/bundled-skills/tasks/tools/task-list-update.ts +5 -2
- package/src/config/bundled-skills/tasks/tools/task-list.ts +5 -2
- package/src/config/bundled-skills/tasks/tools/task-queue-run.ts +5 -2
- package/src/config/bundled-skills/tasks/tools/task-run.ts +5 -2
- package/src/config/bundled-skills/tasks/tools/task-save.ts +5 -2
- package/src/config/bundled-skills/telegram-setup/SKILL.md +7 -8
- package/src/config/bundled-skills/transcribe/TOOLS.json +4 -0
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +232 -127
- package/src/config/bundled-skills/twilio-setup/SKILL.md +7 -12
- package/src/config/bundled-skills/twitter/SKILL.md +19 -2
- package/src/config/bundled-skills/voice-setup/SKILL.md +5 -5
- package/src/config/bundled-skills/watcher/TOOLS.json +20 -0
- package/src/config/bundled-skills/watcher/tools/watcher-create.ts +5 -2
- package/src/config/bundled-skills/watcher/tools/watcher-delete.ts +5 -2
- package/src/config/bundled-skills/watcher/tools/watcher-digest.ts +5 -2
- package/src/config/bundled-skills/watcher/tools/watcher-list.ts +5 -2
- package/src/config/bundled-skills/watcher/tools/watcher-update.ts +5 -2
- package/src/config/bundled-skills/weather/TOOLS.json +4 -0
- package/src/config/bundled-skills/weather/tools/get-weather.ts +5 -2
- package/src/config/bundled-tool-registry.ts +2 -0
- package/src/config/calls-schema.ts +108 -63
- package/src/config/channel-permission-profiles.ts +155 -0
- package/src/config/computer-use-prompt.ts +7 -7
- package/src/config/core-schema.ts +239 -155
- package/src/config/defaults.ts +2 -2
- package/src/config/elevenlabs-schema.ts +15 -15
- package/src/config/env-registry.ts +33 -33
- package/src/config/env.ts +4 -1
- package/src/config/feature-flag-registry.json +31 -7
- package/src/config/loader.ts +118 -58
- package/src/config/mcp-schema.ts +29 -15
- package/src/config/memory-schema.ts +434 -229
- package/src/config/notifications-schema.ts +4 -4
- package/src/config/sandbox-schema.ts +2 -2
- package/src/config/schema.ts +12 -2
- package/src/config/skill-state.ts +27 -15
- package/src/config/skills-schema.ts +72 -23
- package/src/config/skills.ts +303 -143
- package/src/config/system-prompt.ts +25 -6
- package/src/config/types.ts +1 -1
- package/src/config/update-bulletin-format.ts +3 -3
- package/src/config/update-bulletin-state.ts +15 -6
- package/src/config/update-bulletin-template-path.ts +8 -4
- package/src/config/update-bulletin.ts +33 -14
- package/src/config/user-reference.ts +8 -8
- package/src/contacts/contact-events.ts +21 -0
- package/src/contacts/contact-store.ts +813 -100
- package/src/contacts/contacts-write.ts +287 -0
- package/src/contacts/index.ts +13 -4
- package/src/contacts/startup-migration.ts +21 -0
- package/src/contacts/types.ts +73 -2
- package/src/context/token-estimator.ts +54 -31
- package/src/context/tool-result-truncation.ts +41 -7
- package/src/context/window-manager.ts +225 -120
- package/src/daemon/approval-generators.ts +83 -55
- package/src/daemon/approved-devices-store.ts +33 -20
- package/src/daemon/assistant-attachments.ts +157 -101
- package/src/daemon/auth-manager.ts +17 -15
- package/src/daemon/classifier.ts +117 -46
- package/src/daemon/computer-use-session.ts +316 -187
- package/src/daemon/config-watcher.ts +91 -44
- package/src/daemon/connection-policy.ts +18 -10
- package/src/daemon/context-overflow-approval.ts +48 -0
- package/src/daemon/context-overflow-policy.ts +50 -0
- package/src/daemon/context-overflow-reducer.ts +300 -0
- package/src/daemon/daemon-control.ts +79 -51
- package/src/daemon/date-context.ts +119 -69
- package/src/daemon/dictation-profile-store.ts +94 -48
- package/src/daemon/dictation-text-processing.ts +33 -12
- package/src/daemon/doordash-steps.ts +92 -49
- package/src/daemon/guardian-action-generators.ts +62 -46
- package/src/daemon/guardian-verification-intent.ts +35 -19
- package/src/daemon/handlers/apps.ts +258 -113
- package/src/daemon/handlers/avatar.ts +20 -15
- package/src/daemon/handlers/computer-use.ts +82 -39
- package/src/daemon/handlers/config-channels.ts +146 -69
- package/src/daemon/handlers/config-heartbeat.ts +114 -59
- package/src/daemon/handlers/config-inbox.ts +213 -160
- package/src/daemon/handlers/config-ingress.ts +127 -55
- package/src/daemon/handlers/config-integrations.ts +145 -88
- package/src/daemon/handlers/config-model.ts +58 -22
- package/src/daemon/handlers/config-platform.ts +40 -16
- package/src/daemon/handlers/config-scheduling.ts +109 -48
- package/src/daemon/handlers/config-slack-channel.ts +67 -35
- package/src/daemon/handlers/config-slack.ts +21 -20
- package/src/daemon/handlers/config-telegram.ts +100 -70
- package/src/daemon/handlers/config-tools.ts +103 -55
- package/src/daemon/handlers/config-trust.ts +50 -20
- package/src/daemon/handlers/config.ts +72 -24
- package/src/daemon/handlers/contacts.ts +163 -0
- package/src/daemon/handlers/diagnostics.ts +90 -48
- package/src/daemon/handlers/documents.ts +74 -46
- package/src/daemon/handlers/guardian-actions.ts +57 -77
- package/src/daemon/handlers/home-base.ts +19 -16
- package/src/daemon/handlers/identity.ts +65 -45
- package/src/daemon/handlers/index.ts +78 -54
- package/src/daemon/handlers/misc.ts +664 -234
- package/src/daemon/handlers/navigate-settings.ts +14 -11
- package/src/daemon/handlers/oauth-connect.ts +48 -35
- package/src/daemon/handlers/open-bundle-handler.ts +31 -24
- package/src/daemon/handlers/pairing.ts +51 -25
- package/src/daemon/handlers/publish.ts +55 -33
- package/src/daemon/handlers/recording.ts +378 -162
- package/src/daemon/handlers/sessions.ts +922 -423
- package/src/daemon/handlers/shared.ts +202 -117
- package/src/daemon/handlers/signing.ts +25 -6
- package/src/daemon/handlers/subagents.ts +117 -56
- package/src/daemon/handlers/twitter-auth.ts +70 -49
- package/src/daemon/handlers/work-items.ts +264 -112
- package/src/daemon/handlers/workspace-files.ts +27 -20
- package/src/daemon/handlers.ts +2 -2
- package/src/daemon/history-repair.ts +16 -15
- package/src/daemon/identity-helpers.ts +4 -4
- package/src/daemon/install-cli-launchers.ts +33 -22
- package/src/daemon/ipc-blob-store.ts +38 -24
- package/src/daemon/ipc-contract/apps.ts +61 -50
- package/src/daemon/ipc-contract/computer-use.ts +47 -37
- package/src/daemon/ipc-contract/contacts.ts +69 -0
- package/src/daemon/ipc-contract/diagnostics.ts +14 -14
- package/src/daemon/ipc-contract/documents.ts +8 -8
- package/src/daemon/ipc-contract/guardian-actions.ts +4 -4
- package/src/daemon/ipc-contract/inbox.ts +12 -71
- package/src/daemon/ipc-contract/integrations.ts +57 -44
- package/src/daemon/ipc-contract/memory.ts +3 -5
- package/src/daemon/ipc-contract/messages.ts +95 -69
- package/src/daemon/ipc-contract/notifications.ts +10 -6
- package/src/daemon/ipc-contract/pairing.ts +8 -8
- package/src/daemon/ipc-contract/schedules.ts +20 -20
- package/src/daemon/ipc-contract/sessions.ts +89 -57
- package/src/daemon/ipc-contract/settings.ts +12 -7
- package/src/daemon/ipc-contract/shared.ts +9 -7
- package/src/daemon/ipc-contract/skills.ts +46 -26
- package/src/daemon/ipc-contract/subagents.ts +9 -9
- package/src/daemon/ipc-contract/surfaces.ts +0 -1
- package/src/daemon/ipc-contract/trust.ts +11 -11
- package/src/daemon/ipc-contract/work-items.ts +33 -28
- package/src/daemon/ipc-contract/workspace.ts +28 -21
- package/src/daemon/ipc-contract-inventory.json +10 -4
- package/src/daemon/ipc-contract-inventory.ts +29 -26
- package/src/daemon/ipc-contract.ts +111 -44
- package/src/daemon/ipc-handler.ts +27 -19
- package/src/daemon/ipc-protocol.ts +22 -12
- package/src/daemon/ipc-validate.ts +91 -46
- package/src/daemon/lifecycle.ts +39 -3
- package/src/daemon/main.ts +10 -8
- package/src/daemon/media-visibility-policy.ts +3 -1
- package/src/daemon/pairing-store.ts +72 -40
- package/src/daemon/providers-setup.ts +35 -25
- package/src/daemon/recording-executor.ts +37 -30
- package/src/daemon/recording-intent-fallback.ts +58 -28
- package/src/daemon/recording-intent.ts +71 -61
- package/src/daemon/ride-shotgun-handler.ts +201 -121
- package/src/daemon/seed-files.ts +28 -17
- package/src/daemon/server.ts +23 -14
- package/src/daemon/session-agent-loop-handlers.ts +270 -135
- package/src/daemon/session-agent-loop.ts +796 -253
- package/src/daemon/session-attachments.ts +109 -40
- package/src/daemon/session-conflict-gate.ts +72 -28
- package/src/daemon/session-dynamic-profile.ts +36 -22
- package/src/daemon/session-error.ts +68 -45
- package/src/daemon/session-evictor.ts +17 -10
- package/src/daemon/session-history.ts +201 -89
- package/src/daemon/session-lifecycle.ts +80 -44
- package/src/daemon/session-media-retry.ts +104 -42
- package/src/daemon/session-memory.ts +77 -55
- package/src/daemon/session-messaging.ts +261 -111
- package/src/daemon/session-notifiers.ts +57 -45
- package/src/daemon/session-process.ts +370 -154
- package/src/daemon/session-queue-manager.ts +30 -13
- package/src/daemon/session-runtime-assembly.ts +61 -15
- package/src/daemon/session-skill-tools.ts +84 -36
- package/src/daemon/session-slash.ts +178 -113
- package/src/daemon/session-surfaces.ts +498 -212
- package/src/daemon/session-tool-setup.ts +24 -16
- package/src/daemon/session-usage.ts +26 -13
- package/src/daemon/session-workspace.ts +7 -4
- package/src/daemon/session.ts +18 -19
- package/src/daemon/shutdown-handlers.ts +36 -33
- package/src/daemon/tls-certs.ts +90 -57
- package/src/daemon/tool-side-effects.ts +97 -65
- package/src/daemon/trace-emitter.ts +8 -7
- package/src/daemon/video-thumbnail.ts +55 -25
- package/src/daemon/watch-handler.ts +164 -86
- package/src/email/provider.ts +1 -1
- package/src/email/providers/agentmail.ts +87 -45
- package/src/email/providers/index.ts +19 -14
- package/src/email/service.ts +52 -24
- package/src/email/types.ts +2 -2
- package/src/errors.ts +1 -1
- package/src/events/bus.ts +30 -10
- package/src/events/domain-events.ts +20 -13
- package/src/events/index.ts +6 -6
- package/src/events/tool-audit-listener.ts +34 -20
- package/src/events/tool-domain-event-publisher.ts +22 -20
- package/src/events/tool-metrics-listener.ts +26 -21
- package/src/events/tool-notification-listener.ts +5 -5
- package/src/events/tool-profiling-listener.ts +33 -23
- package/src/events/tool-trace-listener.ts +70 -46
- package/src/export/formatter.ts +38 -32
- package/src/followups/followup-store.ts +43 -36
- package/src/followups/index.ts +2 -2
- package/src/followups/types.ts +1 -1
- package/src/gallery/default-gallery.ts +37 -34
- package/src/gallery/gallery-manifest.ts +9 -9
- package/src/heartbeat/heartbeat-service.ts +59 -37
- package/src/home-base/app-link-store.ts +14 -12
- package/src/home-base/bootstrap.ts +14 -8
- package/src/home-base/prebuilt/seed.ts +34 -26
- package/src/home-base/prebuilt-home-base-updater.ts +14 -8
- package/src/hooks/cli.ts +56 -43
- package/src/hooks/config.ts +27 -14
- package/src/hooks/discovery.ts +53 -33
- package/src/hooks/manager.ts +50 -26
- package/src/hooks/runner.ts +35 -29
- package/src/hooks/templates.ts +38 -15
- package/src/hooks/types.ts +13 -13
- package/src/inbound/platform-callback-registration.ts +21 -15
- package/src/inbound/public-ingress-urls.ts +9 -6
- package/src/index.ts +20 -19
- package/src/influencer/client.ts +261 -117
- package/src/instrument.ts +3 -1
- package/src/logfire.ts +64 -39
- package/src/mcp/client.ts +107 -55
- package/src/mcp/manager.ts +45 -18
- package/src/mcp/mcp-oauth-provider.ts +114 -62
- package/src/media/gemini-image-service.ts +75 -23
- package/src/memory/account-store.ts +16 -9
- package/src/memory/admin.ts +87 -57
- package/src/memory/app-git-service.ts +77 -47
- package/src/memory/app-store.ts +148 -78
- package/src/memory/attachments-store.ts +123 -53
- package/src/memory/canonical-guardian-store.ts +190 -48
- package/src/memory/channel-delivery-store.ts +5 -5
- package/src/memory/channel-guardian-store.ts +31 -16
- package/src/memory/checkpoints.ts +14 -7
- package/src/memory/clarification-resolver.ts +219 -104
- package/src/memory/conflict-intent.ts +74 -23
- package/src/memory/conflict-policy.ts +20 -7
- package/src/memory/conflict-store.ts +144 -94
- package/src/memory/contradiction-checker.ts +257 -132
- package/src/memory/conversation-attention-store.ts +74 -32
- package/src/memory/conversation-bootstrap.ts +28 -0
- package/src/memory/conversation-crud.ts +12 -5
- package/src/memory/conversation-display-order-migration.ts +7 -7
- package/src/memory/conversation-key-store.ts +18 -13
- package/src/memory/conversation-queries.ts +130 -52
- package/src/memory/conversation-store.ts +43 -26
- package/src/memory/conversation-title-service.ts +89 -66
- package/src/memory/db-init.ts +94 -2
- package/src/memory/db.ts +10 -3
- package/src/memory/delivery-channels.ts +12 -6
- package/src/memory/delivery-crud.ts +26 -12
- package/src/memory/delivery-status.ts +19 -16
- package/src/memory/embedding-backend.ts +205 -77
- package/src/memory/embedding-gemini.ts +23 -10
- package/src/memory/embedding-local.ts +89 -44
- package/src/memory/embedding-ollama.ts +25 -13
- package/src/memory/embedding-openai.ts +20 -11
- package/src/memory/embedding-runtime-manager.ts +163 -90
- package/src/memory/entity-extractor.ts +185 -123
- package/src/memory/external-conversation-store.ts +30 -12
- package/src/memory/fingerprint.ts +2 -2
- package/src/memory/fts-reconciler.ts +57 -28
- package/src/memory/guardian-action-store.ts +162 -100
- package/src/memory/guardian-approvals.ts +63 -129
- package/src/memory/guardian-rate-limits.ts +20 -9
- package/src/memory/guardian-verification.ts +82 -35
- package/src/memory/indexer.ts +96 -55
- package/src/memory/{ingress-invite-store.ts → invite-store.ts} +28 -169
- package/src/memory/items-extractor.ts +313 -157
- package/src/memory/job-handlers/backfill.ts +116 -63
- package/src/memory/job-handlers/cleanup.ts +64 -41
- package/src/memory/job-handlers/conflict.ts +90 -49
- package/src/memory/job-handlers/embedding.ts +32 -17
- package/src/memory/job-handlers/extraction.ts +58 -33
- package/src/memory/job-handlers/index-maintenance.ts +31 -17
- package/src/memory/job-handlers/media-processing.ts +65 -24
- package/src/memory/job-handlers/summarization.ts +186 -128
- package/src/memory/job-utils.ts +100 -57
- package/src/memory/jobs-store.ts +235 -142
- package/src/memory/jobs-worker.ts +167 -83
- package/src/memory/llm-request-log-store.ts +13 -11
- package/src/memory/llm-usage-store.ts +35 -26
- package/src/memory/media-store.ts +151 -44
- package/src/memory/message-content.ts +28 -18
- package/src/memory/migrations/001-job-deferrals.ts +11 -5
- package/src/memory/migrations/002-tool-invocations-fk.ts +14 -6
- package/src/memory/migrations/003-memory-fts-backfill.ts +11 -5
- package/src/memory/migrations/004-entity-relation-dedup.ts +17 -11
- package/src/memory/migrations/005-fingerprint-scope-unique.ts +36 -21
- package/src/memory/migrations/006-scope-salted-fingerprints.ts +35 -20
- package/src/memory/migrations/007-assistant-id-to-self.ts +40 -27
- package/src/memory/migrations/008-remove-assistant-id-columns.ts +58 -36
- package/src/memory/migrations/009-llm-usage-events-drop-assistant-id.ts +36 -22
- package/src/memory/migrations/010-ext-conv-bindings-channel-chat-unique.ts +21 -11
- package/src/memory/migrations/011-call-sessions-provider-sid-dedup.ts +30 -15
- package/src/memory/migrations/012-call-sessions-add-initiated-from.ts +4 -2
- package/src/memory/migrations/013-guardian-action-tables.ts +29 -11
- package/src/memory/migrations/014-backfill-inbox-thread-state.ts +35 -21
- package/src/memory/migrations/015-drop-active-search-index.ts +17 -11
- package/src/memory/migrations/016-memory-segments-indexes.ts +7 -3
- package/src/memory/migrations/017-memory-items-indexes.ts +4 -2
- package/src/memory/migrations/018-remaining-table-indexes.ts +13 -5
- package/src/memory/migrations/019-notification-tables-schema-migration.ts +34 -20
- package/src/memory/migrations/020-rename-macos-ios-channel-to-vellum.ts +87 -53
- package/src/memory/migrations/021-conversation-status-indexes.ts +7 -3
- package/src/memory/migrations/022-add-origin-interface.ts +4 -2
- package/src/memory/migrations/023-memory-item-sources-indexes.ts +4 -2
- package/src/memory/migrations/024-embedding-vector-blob.ts +34 -18
- package/src/memory/migrations/025-messages-fts-backfill.ts +11 -5
- package/src/memory/migrations/026-guardian-verification-sessions.ts +80 -14
- package/src/memory/migrations/026a-embeddings-nullable-vector-json.ts +42 -26
- package/src/memory/migrations/027-notification-delivery-pairing-columns.ts +22 -8
- package/src/memory/migrations/027a-guardian-bootstrap-token.ts +11 -3
- package/src/memory/migrations/028-call-session-mode.ts +13 -3
- package/src/memory/migrations/028-notification-delivery-client-ack.ts +22 -8
- package/src/memory/migrations/029-channel-inbound-delivered-segments.ts +7 -3
- package/src/memory/migrations/030-guardian-action-followup.ts +46 -8
- package/src/memory/migrations/030-guardian-verification-purpose.ts +4 -2
- package/src/memory/migrations/031-conversations-thread-type-index.ts +4 -2
- package/src/memory/migrations/032-guardian-delivery-conversation-index.ts +4 -2
- package/src/memory/migrations/032-notification-delivery-thread-decision.ts +22 -8
- package/src/memory/migrations/033-scoped-approval-grants.ts +1 -1
- package/src/memory/migrations/034-guardian-action-tool-metadata.ts +15 -3
- package/src/memory/migrations/035-guardian-action-supersession.ts +15 -3
- package/src/memory/migrations/036-normalize-phone-identities.ts +101 -87
- package/src/memory/migrations/037-voice-invite-columns.ts +22 -4
- package/src/memory/migrations/038-actor-token-records.ts +5 -9
- package/src/memory/migrations/039-actor-refresh-token-records.ts +7 -13
- package/src/memory/migrations/100-core-tables.ts +1 -1
- package/src/memory/migrations/101-watchers-and-logs.ts +1 -1
- package/src/memory/migrations/103-complex-migrations.ts +9 -9
- package/src/memory/migrations/104-core-indexes.ts +188 -64
- package/src/memory/migrations/105-contacts-and-triage.ts +28 -10
- package/src/memory/migrations/106-call-sessions.ts +58 -16
- package/src/memory/migrations/107-followups.ts +16 -6
- package/src/memory/migrations/108-tasks-and-work-items.ts +43 -11
- package/src/memory/migrations/109-external-conversation-bindings.ts +11 -5
- package/src/memory/migrations/110-channel-guardian.ts +48 -10
- package/src/memory/migrations/111-media-assets.ts +52 -18
- package/src/memory/migrations/112-assistant-inbox.ts +32 -12
- package/src/memory/migrations/113-late-migrations.ts +12 -12
- package/src/memory/migrations/114-notifications.ts +28 -12
- package/src/memory/migrations/115-sequences.ts +10 -4
- package/src/memory/migrations/116-messages-fts.ts +1 -1
- package/src/memory/migrations/117-conversation-attention.ts +16 -6
- package/src/memory/migrations/118-reminder-routing-intent.ts +7 -3
- package/src/memory/migrations/119-schema-indexes-and-columns.ts +35 -15
- package/src/memory/migrations/120-fk-cascade-rebuilds.ts +36 -17
- package/src/memory/migrations/121-canonical-guardian-requests.ts +25 -9
- package/src/memory/migrations/122-canonical-guardian-requester-chat-id.ts +11 -3
- package/src/memory/migrations/123-canonical-guardian-deliveries-destination-index.ts +4 -2
- package/src/memory/migrations/124-voice-invite-display-metadata.ts +15 -3
- package/src/memory/migrations/125-guardian-principal-id-columns.ts +22 -4
- package/src/memory/migrations/126-backfill-guardian-principal-id.ts +174 -126
- package/src/memory/migrations/127-guardian-principal-id-not-null.ts +58 -42
- package/src/memory/migrations/128-contacts-role-principal.ts +26 -0
- package/src/memory/migrations/129-contact-channels-access-fields.ts +105 -0
- package/src/memory/migrations/130-contact-channels-type-ext-chat-id-index.ts +15 -0
- package/src/memory/migrations/131-drop-legacy-member-guardian-tables.ts +134 -0
- package/src/memory/migrations/132-contacts-assistant-id.ts +21 -0
- package/src/memory/migrations/133-assistant-contact-metadata.ts +21 -0
- package/src/memory/migrations/index.ts +83 -73
- package/src/memory/migrations/registry.ts +53 -37
- package/src/memory/migrations/validate-migration-state.ts +73 -46
- package/src/memory/profile-compiler.ts +58 -24
- package/src/memory/published-pages-store.ts +12 -16
- package/src/memory/qdrant-circuit-breaker.ts +28 -20
- package/src/memory/qdrant-client.ts +99 -63
- package/src/memory/qdrant-manager.ts +89 -57
- package/src/memory/query-builder.ts +9 -7
- package/src/memory/raw-query.ts +63 -14
- package/src/memory/recall-cache.ts +15 -8
- package/src/memory/retrieval-budget.ts +0 -1
- package/src/memory/retriever.ts +385 -192
- package/src/memory/schema-migration.ts +1 -1
- package/src/memory/schema.ts +56 -56
- package/src/memory/scoped-approval-grants.ts +99 -45
- package/src/memory/search/entity.ts +102 -40
- package/src/memory/search/formatting.ts +70 -52
- package/src/memory/search/lexical.ts +82 -43
- package/src/memory/search/ranking.ts +103 -39
- package/src/memory/search/semantic.ts +59 -35
- package/src/memory/search/types.ts +8 -8
- package/src/memory/segmenter.ts +20 -12
- package/src/memory/shared-app-links-store.ts +21 -16
- package/src/memory/slack-thread-store.ts +187 -0
- package/src/memory/task-memory-cleanup.ts +18 -8
- package/src/memory/tool-usage-store.ts +27 -19
- package/src/memory/validation.ts +4 -2
- package/src/messaging/activity-analyzer.ts +7 -7
- package/src/messaging/draft-store.ts +13 -10
- package/src/messaging/email-classifier.ts +73 -37
- package/src/messaging/index.ts +3 -3
- package/src/messaging/outreach-classifier.ts +76 -38
- package/src/messaging/provider-types.ts +2 -4
- package/src/messaging/provider.ts +37 -8
- package/src/messaging/providers/gmail/adapter.ts +183 -66
- package/src/messaging/providers/gmail/client.ts +3 -1
- package/src/messaging/providers/gmail/mime-builder.ts +21 -19
- package/src/messaging/providers/gmail/people-client.ts +22 -9
- package/src/messaging/providers/gmail/types.ts +6 -6
- package/src/messaging/providers/slack/adapter.ts +93 -43
- package/src/messaging/providers/slack/client.ts +165 -48
- package/src/messaging/providers/slack/types.ts +10 -0
- package/src/messaging/providers/sms/adapter.ts +76 -40
- package/src/messaging/providers/sms/client.ts +4 -4
- package/src/messaging/providers/telegram-bot/adapter.ts +52 -30
- package/src/messaging/providers/telegram-bot/client.ts +7 -7
- package/src/messaging/providers/whatsapp/adapter.ts +58 -31
- package/src/messaging/providers/whatsapp/client.ts +4 -4
- package/src/messaging/registry.ts +9 -5
- package/src/messaging/style-analyzer.ts +69 -39
- package/src/messaging/thread-summarizer.ts +101 -53
- package/src/messaging/triage-engine.ts +111 -82
- package/src/messaging/types.ts +10 -10
- package/src/migrations/config-merge.ts +18 -10
- package/src/migrations/data-layout.ts +35 -22
- package/src/migrations/data-merge.ts +17 -7
- package/src/migrations/hooks-merge.ts +43 -16
- package/src/migrations/index.ts +6 -6
- package/src/migrations/log.ts +9 -5
- package/src/migrations/skills-merge.ts +17 -7
- package/src/migrations/workspace-layout.ts +39 -25
- package/src/notifications/AGENTS.md +5 -0
- package/src/notifications/adapters/macos.ts +21 -14
- package/src/notifications/adapters/slack.ts +90 -0
- package/src/notifications/adapters/sms.ts +28 -15
- package/src/notifications/adapters/telegram.ts +24 -15
- package/src/notifications/broadcaster.ts +108 -52
- package/src/notifications/conversation-pairing.ts +64 -29
- package/src/notifications/copy-composer.ts +165 -95
- package/src/notifications/decision-engine.ts +353 -147
- package/src/notifications/decisions-store.ts +26 -10
- package/src/notifications/deliveries-store.ts +23 -13
- package/src/notifications/destination-resolver.ts +83 -24
- package/src/notifications/deterministic-checks.ts +78 -27
- package/src/notifications/emit-signal.ts +95 -41
- package/src/notifications/events-store.ts +13 -7
- package/src/notifications/guardian-question-mode.ts +125 -75
- package/src/notifications/preference-extractor.ts +85 -53
- package/src/notifications/preference-summary.ts +31 -18
- package/src/notifications/preferences-store.ts +29 -18
- package/src/notifications/runtime-dispatch.ts +22 -12
- package/src/notifications/signal.ts +4 -4
- package/src/notifications/thread-candidates.ts +59 -23
- package/src/notifications/thread-seed-composer.ts +45 -27
- package/src/notifications/types.ts +19 -10
- package/src/oauth/connect-orchestrator.ts +105 -54
- package/src/oauth/connect-types.ts +3 -3
- package/src/oauth/provider-profiles.ts +102 -59
- package/src/oauth/scope-policy.ts +5 -2
- package/src/oauth/token-persistence.ts +58 -24
- package/src/outbound-proxy/certs.ts +284 -0
- package/src/outbound-proxy/config.ts +94 -0
- package/src/outbound-proxy/connect-tunnel.ts +84 -0
- package/src/outbound-proxy/health.ts +62 -0
- package/src/outbound-proxy/host-pattern-match.ts +67 -0
- package/src/outbound-proxy/http-forwarder.ts +162 -0
- package/src/outbound-proxy/index.ts +80 -0
- package/src/outbound-proxy/logging.ts +193 -0
- package/src/outbound-proxy/mitm-handler.ts +292 -0
- package/src/outbound-proxy/policy.ts +172 -0
- package/src/outbound-proxy/router.ts +64 -0
- package/src/outbound-proxy/server.ts +145 -0
- package/src/outbound-proxy/types.ts +150 -0
- package/src/permissions/checker.ts +481 -189
- package/src/permissions/defaults.ts +135 -108
- package/src/permissions/prompter.ts +53 -27
- package/src/permissions/secret-prompter.ts +21 -15
- package/src/permissions/shell-identity.ts +47 -16
- package/src/permissions/trust-store.ts +185 -73
- package/src/permissions/types.ts +22 -12
- package/src/permissions/workspace-policy.ts +47 -38
- package/src/playbooks/index.ts +10 -2
- package/src/playbooks/playbook-compiler.ts +30 -24
- package/src/playbooks/types.ts +11 -8
- package/src/providers/anthropic/client.ts +328 -168
- package/src/providers/failover.ts +57 -22
- package/src/providers/fireworks/client.ts +9 -5
- package/src/providers/gemini/client.ts +61 -39
- package/src/providers/model-intents.ts +40 -33
- package/src/providers/ollama/client.ts +7 -7
- package/src/providers/openai/client.ts +109 -68
- package/src/providers/openrouter/client.ts +9 -5
- package/src/providers/provider-send-message.ts +59 -27
- package/src/providers/ratelimit.ts +25 -8
- package/src/providers/registry.ts +86 -38
- package/src/providers/retry.ts +93 -37
- package/src/providers/stream-timeout.ts +5 -3
- package/src/providers/types.ts +7 -6
- package/src/runtime/AGENTS.md +42 -0
- package/src/runtime/access-request-helper.ts +118 -68
- package/src/runtime/actor-refresh-token-store.ts +21 -16
- package/src/runtime/actor-token-store.ts +25 -18
- package/src/runtime/actor-trust-resolver.ts +191 -80
- package/src/runtime/approval-conversation-turn.ts +39 -26
- package/src/runtime/approval-message-composer.ts +116 -84
- package/src/runtime/assistant-event-hub.ts +25 -6
- package/src/runtime/assistant-event.ts +4 -4
- package/src/runtime/assistant-scope.ts +1 -1
- package/src/runtime/auth/__tests__/guard-tests.test.ts +36 -14
- package/src/runtime/auth/context.ts +8 -7
- package/src/runtime/auth/credential-service.ts +60 -38
- package/src/runtime/auth/external-assistant-id.ts +16 -8
- package/src/runtime/auth/index.ts +23 -16
- package/src/runtime/auth/require-bound-guardian.ts +44 -0
- package/src/runtime/auth/route-policy.ts +166 -104
- package/src/runtime/auth/scopes.ts +22 -29
- package/src/runtime/auth/subject.ts +19 -13
- package/src/runtime/auth/token-service.ts +3 -3
- package/src/runtime/auth/types.ts +23 -23
- package/src/runtime/channel-approval-parser.ts +37 -14
- package/src/runtime/channel-approval-types.ts +30 -4
- package/src/runtime/channel-approvals.ts +49 -23
- package/src/runtime/channel-guardian-service.ts +144 -103
- package/src/runtime/channel-invite-transport.ts +5 -3
- package/src/runtime/channel-invite-transports/telegram.ts +16 -10
- package/src/runtime/channel-invite-transports/voice.ts +7 -7
- package/src/runtime/channel-readiness-service.ts +139 -90
- package/src/runtime/channel-readiness-types.ts +4 -2
- package/src/runtime/channel-reply-delivery.ts +83 -14
- package/src/runtime/channel-retry-sweep.ts +111 -62
- package/src/runtime/confirmation-request-guardian-bridge.ts +73 -54
- package/src/runtime/gateway-client.ts +122 -55
- package/src/runtime/gateway-internal-client.ts +86 -0
- package/src/runtime/guardian-action-conversation-turn.ts +34 -18
- package/src/runtime/guardian-action-followup-executor.ts +115 -45
- package/src/runtime/guardian-action-grant-minter.ts +40 -24
- package/src/runtime/guardian-action-message-composer.ts +105 -84
- package/src/runtime/guardian-action-service.ts +127 -0
- package/src/runtime/guardian-decision-types.ts +28 -13
- package/src/runtime/guardian-outbound-actions.ts +9 -0
- package/src/runtime/guardian-reply-router.ts +274 -145
- package/src/runtime/guardian-vellum-migration.ts +38 -24
- package/src/runtime/guardian-verification-templates.ts +24 -12
- package/src/runtime/http-router.ts +175 -0
- package/src/runtime/http-server.ts +913 -680
- package/src/runtime/http-types.ts +2 -2
- package/src/runtime/invite-redemption-service.ts +211 -134
- package/src/runtime/invite-redemption-templates.ts +18 -11
- package/src/runtime/{ingress-service.ts → invite-service.ts} +92 -151
- package/src/runtime/local-actor-identity.ts +73 -55
- package/src/runtime/middleware/auth.ts +25 -14
- package/src/runtime/middleware/error-handler.ts +15 -11
- package/src/runtime/middleware/rate-limiter.ts +23 -17
- package/src/runtime/middleware/request-logger.ts +4 -4
- package/src/runtime/middleware/twilio-validation.ts +29 -20
- package/src/runtime/migrations/migration-transport.ts +575 -0
- package/src/runtime/migrations/migration-wizard.ts +715 -0
- package/src/runtime/migrations/rebind-secrets-screen.ts +351 -0
- package/src/runtime/migrations/transfer-progress-screen.ts +321 -0
- package/src/runtime/migrations/validation-results-screen.ts +467 -0
- package/src/runtime/migrations/vbundle-builder.ts +295 -0
- package/src/runtime/migrations/vbundle-import-analyzer.ts +212 -0
- package/src/runtime/migrations/vbundle-importer.ts +339 -0
- package/src/runtime/migrations/vbundle-validator.ts +356 -0
- package/src/runtime/nl-approval-parser.ts +138 -0
- package/src/runtime/pending-interactions.ts +16 -7
- package/src/runtime/routes/access-request-decision.ts +73 -52
- package/src/runtime/routes/app-routes.ts +56 -38
- package/src/runtime/routes/approval-routes.ts +144 -92
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +930 -0
- package/src/runtime/routes/approval-strategies/guardian-legacy-fallback-strategy.ts +82 -0
- package/src/runtime/routes/approval-strategies/guardian-text-engine-strategy.ts +151 -0
- package/src/runtime/routes/attachment-routes.ts +59 -48
- package/src/runtime/routes/brain-graph-routes.ts +85 -69
- package/src/runtime/routes/call-routes.ts +79 -38
- package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +10 -10
- package/src/runtime/routes/channel-delivery-routes.ts +19 -14
- package/src/runtime/routes/channel-guardian-routes.ts +3 -3
- package/src/runtime/routes/channel-inbound-routes.ts +2 -2
- package/src/runtime/routes/channel-readiness-routes.ts +12 -6
- package/src/runtime/routes/channel-route-shared.ts +67 -25
- package/src/runtime/routes/channel-routes.ts +4 -6
- package/src/runtime/routes/contact-routes.ts +374 -17
- package/src/runtime/routes/conversation-attention-routes.ts +57 -28
- package/src/runtime/routes/conversation-routes.ts +321 -174
- package/src/runtime/routes/debug-routes.ts +14 -10
- package/src/runtime/routes/events-routes.ts +90 -57
- package/src/runtime/routes/global-search-routes.ts +266 -0
- package/src/runtime/routes/guardian-action-routes.ts +112 -113
- package/src/runtime/routes/guardian-approval-interception.ts +325 -874
- package/src/runtime/routes/guardian-approval-prompt.ts +40 -24
- package/src/runtime/routes/guardian-approval-reply-helpers.ts +135 -0
- package/src/runtime/routes/guardian-bootstrap-routes.ts +55 -36
- package/src/runtime/routes/guardian-expiry-sweep.ts +63 -37
- package/src/runtime/routes/guardian-refresh-routes.ts +40 -19
- package/src/runtime/routes/identity-routes.ts +71 -42
- package/src/runtime/routes/inbound-conversation.ts +17 -11
- package/src/runtime/routes/inbound-message-handler.ts +305 -1459
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +880 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +600 -0
- package/src/runtime/routes/inbound-stages/bootstrap-intercept.ts +214 -0
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +116 -0
- package/src/runtime/routes/inbound-stages/escalation-intercept.ts +167 -0
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +185 -0
- package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +132 -0
- package/src/runtime/routes/inbound-stages/verification-intercept.ts +340 -0
- package/src/runtime/routes/integration-routes.ts +60 -21
- package/src/runtime/routes/invite-routes.ts +140 -0
- package/src/runtime/routes/migration-routes.ts +434 -0
- package/src/runtime/routes/pairing-routes.ts +157 -79
- package/src/runtime/routes/secret-routes.ts +6 -2
- package/src/runtime/routes/twilio-routes.ts +443 -249
- package/src/runtime/slack-block-formatting.ts +176 -0
- package/src/runtime/tool-grant-request-helper.ts +36 -27
- package/src/runtime/{guardian-context-resolver.ts → trust-context-resolver.ts} +29 -41
- package/src/schedule/integration-status.ts +44 -9
- package/src/schedule/recurrence-engine.ts +47 -24
- package/src/schedule/recurrence-types.ts +12 -7
- package/src/schedule/schedule-store.ts +166 -83
- package/src/schedule/scheduler.ts +37 -24
- package/src/security/encrypted-store.ts +68 -38
- package/src/security/keychain.ts +183 -120
- package/src/security/oauth-callback-registry.ts +3 -3
- package/src/security/oauth2.ts +226 -138
- package/src/security/redaction.ts +24 -24
- package/src/security/secret-allowlist.ts +46 -21
- package/src/security/secret-ingress.ts +15 -7
- package/src/security/secret-scanner.ts +193 -104
- package/src/security/secure-keys.ts +9 -3
- package/src/security/token-manager.ts +99 -40
- package/src/security/tool-approval-digest.ts +3 -3
- package/src/sequence/analytics.ts +52 -27
- package/src/sequence/engine.ts +135 -72
- package/src/sequence/guardrails.ts +32 -20
- package/src/sequence/importer.ts +75 -37
- package/src/sequence/reply-matcher.ts +36 -18
- package/src/sequence/store.ts +137 -75
- package/src/sequence/types.ts +30 -16
- package/src/services/published-app-updater.ts +26 -16
- package/src/services/vercel-deploy.ts +19 -15
- package/src/skills/active-skill-tools.ts +3 -3
- package/src/skills/clawhub.ts +178 -90
- package/src/skills/include-graph.ts +24 -17
- package/src/skills/managed-store.ts +89 -42
- package/src/skills/path-classifier.ts +10 -10
- package/src/skills/remote-skill-policy.ts +31 -22
- package/src/skills/slash-commands.ts +36 -30
- package/src/skills/tool-manifest.ts +60 -31
- package/src/skills/version-hash.ts +25 -15
- package/src/slack/slack-webhook.ts +19 -15
- package/src/subagent/index.ts +4 -8
- package/src/subagent/manager.ts +119 -69
- package/src/subagent/types.ts +9 -12
- package/src/swarm/backend-claude-code.ts +124 -45
- package/src/swarm/checkpoint.ts +36 -16
- package/src/swarm/graph-utils.ts +1 -3
- package/src/swarm/index.ts +38 -19
- package/src/swarm/limits.ts +13 -4
- package/src/swarm/orchestrator.ts +108 -57
- package/src/swarm/plan-validator.ts +23 -17
- package/src/swarm/router-planner.ts +51 -22
- package/src/swarm/router-prompts.ts +4 -1
- package/src/swarm/synthesizer.ts +26 -18
- package/src/swarm/types.ts +14 -4
- package/src/swarm/worker-backend.ts +36 -26
- package/src/swarm/worker-prompts.ts +13 -9
- package/src/swarm/worker-runner.ts +40 -34
- package/src/tasks/candidate-store.ts +14 -6
- package/src/tasks/ephemeral-permissions.ts +9 -5
- package/src/tasks/task-compiler.ts +41 -38
- package/src/tasks/task-runner.ts +54 -26
- package/src/tasks/task-scheduler.ts +1 -1
- package/src/tasks/task-store.ts +20 -7
- package/src/tasks/tool-sanitizer.ts +3 -3
- package/src/tools/apps/definitions.ts +23 -15
- package/src/tools/apps/executors.ts +122 -40
- package/src/tools/apps/open-proxy.ts +5 -5
- package/src/tools/apps/registry.ts +2 -2
- package/src/tools/assets/materialize.ts +59 -41
- package/src/tools/assets/search.ts +86 -48
- package/src/tools/browser/api-map.ts +52 -36
- package/src/tools/browser/auth-cache.ts +21 -18
- package/src/tools/browser/auth-detector.ts +43 -28
- package/src/tools/browser/auto-navigate.ts +149 -68
- package/src/tools/browser/browser-execution.ts +9 -3
- package/src/tools/browser/headless-browser.ts +287 -150
- package/src/tools/browser/jit-auth.ts +37 -21
- package/src/tools/browser/network-recorder.ts +138 -56
- package/src/tools/browser/recording-store.ts +22 -15
- package/src/tools/browser/runtime-check.ts +8 -5
- package/src/tools/browser/x-auto-navigate.ts +88 -47
- package/src/tools/calls/call-end.ts +10 -7
- package/src/tools/calls/call-start.ts +30 -20
- package/src/tools/calls/call-status.ts +8 -5
- package/src/tools/claude-code/claude-code.ts +301 -165
- package/src/tools/computer-use/definitions.ts +175 -130
- package/src/tools/computer-use/registry.ts +2 -2
- package/src/tools/computer-use/request-computer-control.ts +21 -13
- package/src/tools/computer-use/skill-proxy-bridge.ts +1 -1
- package/src/tools/credentials/account-registry.ts +52 -35
- package/src/tools/credentials/broker-types.ts +1 -1
- package/src/tools/credentials/broker.ts +97 -55
- package/src/tools/credentials/domain-policy.ts +5 -2
- package/src/tools/credentials/host-pattern-match.ts +15 -8
- package/src/tools/credentials/metadata-store.ts +93 -43
- package/src/tools/credentials/policy-types.ts +5 -2
- package/src/tools/credentials/policy-validate.ts +21 -14
- package/src/tools/credentials/post-connect-hooks.ts +18 -7
- package/src/tools/credentials/resolve.ts +11 -10
- package/src/tools/credentials/selection.ts +30 -25
- package/src/tools/credentials/tool-policy.ts +5 -2
- package/src/tools/credentials/vault.ts +538 -185
- package/src/tools/document/document-tool.ts +23 -17
- package/src/tools/document/editor-template.ts +12 -7
- package/src/tools/execution-target.ts +13 -10
- package/src/tools/execution-timeout.ts +6 -5
- package/src/tools/executor.ts +141 -74
- package/src/tools/filesystem/edit.ts +82 -45
- package/src/tools/filesystem/fuzzy-match.ts +70 -32
- package/src/tools/filesystem/read.ts +46 -28
- package/src/tools/filesystem/view-image.ts +86 -42
- package/src/tools/filesystem/write.ts +53 -32
- package/src/tools/followups/followup_create.ts +43 -17
- package/src/tools/followups/followup_list.ts +28 -13
- package/src/tools/followups/followup_resolve.ts +9 -6
- package/src/tools/guardian-control-plane-policy.ts +15 -14
- package/src/tools/host-filesystem/edit.ts +77 -42
- package/src/tools/host-filesystem/read.ts +52 -33
- package/src/tools/host-filesystem/write.ts +50 -29
- package/src/tools/host-terminal/host-shell.ts +97 -61
- package/src/tools/mcp/mcp-tool-factory.ts +21 -14
- package/src/tools/memory/definitions.ts +60 -28
- package/src/tools/memory/handlers.ts +149 -77
- package/src/tools/memory/register.ts +39 -16
- package/src/tools/network/__tests__/web-search.test.ts +236 -177
- package/src/tools/network/domain-normalize.ts +13 -9
- package/src/tools/network/script-proxy/__tests__/logging.test.ts +193 -123
- package/src/tools/network/script-proxy/__tests__/policy.test.ts +225 -127
- package/src/tools/network/script-proxy/index.ts +1 -17
- package/src/tools/network/script-proxy/session-manager.ts +178 -86
- package/src/tools/network/url-safety.ts +56 -34
- package/src/tools/network/web-fetch.ts +273 -155
- package/src/tools/network/web-search.ts +166 -81
- package/src/tools/permission-checker.ts +24 -25
- package/src/tools/policy-context.ts +8 -5
- package/src/tools/registry.ts +73 -46
- package/src/tools/reminder/reminder-store.ts +65 -44
- package/src/tools/reminder/reminder.ts +76 -35
- package/src/tools/schedule/create.ts +44 -21
- package/src/tools/schedule/delete.ts +8 -5
- package/src/tools/schedule/list.ts +39 -19
- package/src/tools/schedule/update.ts +49 -26
- package/src/tools/secret-detection-handler.ts +130 -49
- package/src/tools/sensitive-output-placeholders.ts +15 -8
- package/src/tools/shared/filesystem/edit-engine.ts +45 -14
- package/src/tools/shared/filesystem/errors.ts +18 -18
- package/src/tools/shared/filesystem/file-ops-service.ts +59 -32
- package/src/tools/shared/filesystem/format-diff.ts +21 -11
- package/src/tools/shared/filesystem/path-policy.ts +17 -13
- package/src/tools/shared/filesystem/size-guard.ts +8 -4
- package/src/tools/shared/filesystem/types.ts +2 -2
- package/src/tools/shared/shell-output.ts +4 -3
- package/src/tools/side-effects.ts +36 -28
- package/src/tools/skills/delete-managed.ts +30 -17
- package/src/tools/skills/load.ts +88 -46
- package/src/tools/skills/sandbox-runner.ts +62 -46
- package/src/tools/skills/scaffold-managed.ts +98 -48
- package/src/tools/skills/script-contract.ts +5 -2
- package/src/tools/skills/skill-script-runner.ts +29 -13
- package/src/tools/skills/skill-tool-factory.ts +20 -10
- package/src/tools/subagent/abort.ts +10 -4
- package/src/tools/subagent/message.ts +14 -8
- package/src/tools/subagent/read.ts +20 -11
- package/src/tools/subagent/spawn.ts +14 -6
- package/src/tools/subagent/status.ts +7 -4
- package/src/tools/swarm/delegate.ts +75 -49
- package/src/tools/system/avatar-generator.ts +46 -33
- package/src/tools/system/navigate-settings.ts +29 -19
- package/src/tools/system/open-system-settings.ts +30 -20
- package/src/tools/system/request-permission.ts +59 -44
- package/src/tools/system/version.ts +27 -16
- package/src/tools/system/voice-config.ts +116 -53
- package/src/tools/tasks/index.ts +8 -8
- package/src/tools/tasks/task-delete.ts +61 -22
- package/src/tools/tasks/task-list.ts +23 -11
- package/src/tools/tasks/task-run.ts +41 -16
- package/src/tools/tasks/task-save.ts +27 -10
- package/src/tools/tasks/work-item-enqueue.ts +114 -48
- package/src/tools/tasks/work-item-list.ts +20 -10
- package/src/tools/tasks/work-item-remove.ts +49 -15
- package/src/tools/tasks/work-item-run.ts +34 -13
- package/src/tools/tasks/work-item-update.ts +84 -31
- package/src/tools/terminal/backends/native.ts +64 -35
- package/src/tools/terminal/backends/types.ts +6 -2
- package/src/tools/terminal/parser.ts +200 -125
- package/src/tools/terminal/safe-env.ts +27 -21
- package/src/tools/terminal/sandbox-diagnostics.ts +31 -13
- package/src/tools/terminal/sandbox.ts +10 -6
- package/src/tools/terminal/shell.ts +134 -68
- package/src/tools/tool-approval-handler.ts +239 -140
- package/src/tools/types.ts +79 -22
- package/src/tools/ui-surface/definitions.ts +124 -89
- package/src/tools/ui-surface/registry.ts +2 -2
- package/src/tools/watch/screen-watch.ts +50 -32
- package/src/tools/watch/watch-state.ts +41 -15
- package/src/tools/watcher/create.ts +37 -15
- package/src/tools/watcher/delete.ts +9 -6
- package/src/tools/watcher/digest.ts +10 -6
- package/src/tools/watcher/list.ts +37 -14
- package/src/tools/watcher/update.ts +33 -18
- package/src/tools/weather/service.ts +331 -174
- package/src/twitter/client.ts +261 -138
- package/src/twitter/oauth-client.ts +17 -13
- package/src/twitter/router.ts +51 -23
- package/src/twitter/session.ts +27 -18
- package/src/types/qrcode.d.ts +6 -3
- package/src/usage/actors.ts +16 -16
- package/src/usage/types.ts +3 -3
- package/src/util/bundled-asset.ts +10 -6
- package/src/util/canonicalize-identity.ts +11 -4
- package/src/util/clipboard.ts +7 -7
- package/src/util/content-id.ts +3 -3
- package/src/util/debounce.ts +3 -2
- package/src/util/diff.ts +55 -33
- package/src/util/errors.ts +31 -27
- package/src/util/fs.ts +8 -2
- package/src/util/log-redact.ts +12 -12
- package/src/util/logger.ts +112 -51
- package/src/util/network-info.ts +13 -5
- package/src/util/object.ts +4 -2
- package/src/util/phone.ts +4 -4
- package/src/util/platform.ts +80 -58
- package/src/util/pricing.ts +49 -31
- package/src/util/retry.ts +39 -7
- package/src/util/row-mapper.ts +7 -4
- package/src/util/silently.ts +7 -4
- package/src/util/spawn.ts +48 -0
- package/src/util/spinner.ts +9 -7
- package/src/util/time.ts +16 -3
- package/src/util/truncate.ts +1 -1
- package/src/util/voice-code.ts +6 -4
- package/src/util/xml.ts +5 -1
- package/src/version.ts +12 -8
- package/src/watcher/engine.ts +71 -44
- package/src/watcher/provider-registry.ts +1 -1
- package/src/watcher/providers/github.ts +40 -23
- package/src/watcher/providers/gmail.ts +59 -38
- package/src/watcher/providers/google-calendar.ts +62 -48
- package/src/watcher/providers/linear.ts +219 -150
- package/src/watcher/providers/slack.ts +125 -29
- package/src/watcher/watcher-store.ts +75 -55
- package/src/work-items/work-item-runner.ts +62 -29
- package/src/work-items/work-item-store.ts +137 -47
- package/src/workspace/commit-message-enrichment-service.ts +65 -25
- package/src/workspace/commit-message-provider.ts +14 -12
- package/src/workspace/git-service.ts +355 -239
- package/src/workspace/heartbeat-service.ts +74 -37
- package/src/workspace/provider-commit-message-generator.ts +95 -70
- package/src/workspace/top-level-renderer.ts +10 -8
- package/src/workspace/top-level-scanner.ts +9 -3
- package/src/workspace/turn-commit.ts +63 -36
- package/src/__tests__/ingress-member-store.test.ts +0 -294
- package/src/__tests__/script-proxy-router.test.ts +0 -215
- package/src/config/bundled-skills/trusted-contacts/SKILL.md +0 -372
- package/src/memory/guardian-bindings.ts +0 -158
- package/src/memory/ingress-member-store.ts +0 -352
- package/src/runtime/routes/ingress-routes.ts +0 -229
- package/src/tools/network/script-proxy/__tests__/router.test.ts +0 -77
- package/src/tools/network/script-proxy/certs.ts +0 -7
- package/src/tools/network/script-proxy/connect-tunnel.ts +0 -1
- package/src/tools/network/script-proxy/http-forwarder.ts +0 -2
- package/src/tools/network/script-proxy/logging.ts +0 -12
- package/src/tools/network/script-proxy/mitm-handler.ts +0 -2
- package/src/tools/network/script-proxy/policy.ts +0 -4
- package/src/tools/network/script-proxy/router.ts +0 -2
- package/src/tools/network/script-proxy/server.ts +0 -5
- package/src/tools/network/script-proxy/types.ts +0 -19
|
@@ -8,465 +8,9 @@ You are an expert app builder and visual designer. When the user asks you to cre
|
|
|
8
8
|
|
|
9
9
|
**Every app gets its own visual identity.** A plant tracker should feel earthy and green. A finance dashboard should feel precise and navy. A fitness app should feel energetic and purple. Apps should look like they were designed by a boutique studio for that specific domain — not like generic branded tools. Think standalone premium product, not template.
|
|
10
10
|
|
|
11
|
-
**Your default behavior:** Build immediately. The user types "build me a habit tracker" and you deliver a complete, polished app with a domain-matched color palette,
|
|
12
|
-
|
|
13
|
-
## Design Philosophy
|
|
14
|
-
|
|
15
|
-
Every app you create must clear this bar: **Would someone screenshot this and share it?** If the answer is no, you haven't tried hard enough.
|
|
16
|
-
|
|
17
|
-
### The Quality Bar
|
|
18
|
-
|
|
19
|
-
Your apps compete with products built by professional design teams. That means:
|
|
20
|
-
|
|
21
|
-
- Every screen has visual depth — layers, shadows, gradients, texture
|
|
22
|
-
- Typography creates clear hierarchy — not everything is 14px regular weight
|
|
23
|
-
- Color is intentional and atmospheric — not just "blue buttons on white"
|
|
24
|
-
- Interactions feel physical — elements respond to hover, press, and focus
|
|
25
|
-
- Empty states are designed moments, not error messages
|
|
26
|
-
- The page loads with grace — elements stagger in, content shimmers while loading
|
|
27
|
-
|
|
28
|
-
### Anti-AI-Slop Rules
|
|
29
|
-
|
|
30
|
-
These are hard prohibitions. Violating any of these produces that unmistakable "AI-generated" look:
|
|
31
|
-
|
|
32
|
-
- **NEVER** use flat cards with no depth — every card needs a subtle 1px border and gentle shadow, not heavy multi-layer shadows
|
|
33
|
-
- **NEVER** ship an app with zero animations — at minimum: page load stagger, hover states, state transitions
|
|
34
|
-
- **NEVER** make all text the same size and weight — establish clear hierarchy with at least 3 distinct levels
|
|
35
|
-
- **NEVER** use a pure white (`#fff`) or pure dark (`#000`/`#0a0a0a`) background — ALWAYS tint it to match the domain (cream `#FEFCF9` for lifestyle, sage `#F0F5F0` for nature, cool gray `#F5F7FA` for finance, warm blush `#FDF6F3` for wellness)
|
|
36
|
-
- **NEVER** leave clickable elements without hover AND active states
|
|
37
|
-
- **NEVER** hand-code SVG/CSS charts (lines, bars, sparklines, gauges) — ALWAYS use `vellum.widgets.lineChart()`, `.barChart()`, `.sparkline()`, or `.progressRing()`. They handle bounds, clipping, scaling, and dark mode correctly. Hand-coded charts invariably overflow and bleed into adjacent elements.
|
|
38
|
-
- **ALWAYS** use emoji as visual identifiers in stat cards, list items, and navigation — they replace icon libraries and add instant personality (🍎 for food, 🔥 for streaks, 💰 for money, 🌿 for plants)
|
|
39
|
-
- **ALWAYS** apply the accent-word pattern in hero headings — color ONE key word or phrase in the accent color: "Your <span style='color: var(--accent)'>Week</span> in Motion"
|
|
40
|
-
- **ALWAYS** include a contextual/personalized header — a greeting ("Good morning"), date ("Saturday, Feb 15"), or welcome ("Welcome back, Alex") — not just the app title
|
|
41
|
-
- **ALWAYS** include at least one pill-shaped trust/status badge somewhere visible — "🌟 Trusted by 12,000+ users", "+8.2% this week", "✨ Pro plan"
|
|
42
|
-
- **ALWAYS** use tight letter-spacing on headings (`-0.02em` to `-0.04em`)
|
|
43
|
-
- **ALWAYS** use `clamp()` for display/heading text so it scales fluidly
|
|
44
|
-
- **ALWAYS** add at least one accent gradient somewhere — a hero, a button, a decorative element
|
|
45
|
-
- **ALWAYS** give the app a distinct visual personality — if you removed the content, could you still tell which app this is?
|
|
46
|
-
|
|
47
|
-
### Color Strategy
|
|
48
|
-
|
|
49
|
-
- **Theme-match your palette to the domain.** Don't default to violet. Pick the color that feels right: emerald/sage for plants & nature, purple for fitness & wellness, amber/gold for finance & productivity, rose for social & lifestyle, indigo for tech & developer tools.
|
|
50
|
-
- **Define custom CSS variables at the top of `<style>`** for every app:
|
|
51
|
-
```css
|
|
52
|
-
:root {
|
|
53
|
-
--accent: #18B07A; /* domain-matched accent */
|
|
54
|
-
--accent-light: #ECFDF5; /* tinted surface */
|
|
55
|
-
--bg-tint: #F0F5F0; /* warm/cool background tint */
|
|
56
|
-
}
|
|
57
|
-
@media (prefers-color-scheme: dark) {
|
|
58
|
-
:root {
|
|
59
|
-
--accent: #38CF93;
|
|
60
|
-
--accent-light: #073D2E;
|
|
61
|
-
--bg-tint: #0A1A14;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
```
|
|
65
|
-
- **Background tint examples:** `#FEFCF9` cream (lifestyle), `#F0F5F0` sage (nature), `#F5F7FA` cool gray (finance), `#FDF6F3` warm blush (wellness), `#F5F3FF` lavender (creative). Apply to `body { background: var(--bg-tint); }`.
|
|
66
|
-
- **60-30-10 rule:** 60% tinted background/surface, 30% secondary/text, 10% accent. Never use accent for large areas.
|
|
67
|
-
- **Status colors are semantic:** emerald = success/positive, rose = danger/destructive, amber = warning/attention. Don't use these for decoration.
|
|
68
|
-
- **`--v-*` tokens remain available** for spacing, radius, shadows, and animations. Use them for layout consistency. But stop defaulting to `--v-violet-*` for accent — use your domain-matched `--accent` variable instead.
|
|
69
|
-
- For branded/themed apps, write custom CSS with `@media (prefers-color-scheme: dark)` overrides instead of mixing `--v-*` auto-switching variables with hardcoded colors.
|
|
70
|
-
|
|
71
|
-
### Typography Rules
|
|
72
|
-
|
|
73
|
-
- **Display/hero text:** `font-weight: 800`, `letter-spacing: -0.03em`, `clamp(1.75rem, 4vw, 2.5rem)` for fluid sizing
|
|
74
|
-
- **Accent-word technique:** In hero headings, wrap ONE key word in a `<span>` with the accent color or a gradient. This is the single most impactful typography move: `<h1>Track your <span class="accent-word">Growth</span> daily</h1>`. Use `.accent-word { color: var(--accent); }` or apply a gradient fill.
|
|
75
|
-
- **Section headings:** `font-weight: 700`, `letter-spacing: -0.02em`, `--v-font-size-xl` or `--v-font-size-2xl`
|
|
76
|
-
- **Body text:** `--v-font-size-base` (14px), `line-height: 1.55`
|
|
77
|
-
- **Labels/captions:** `text-transform: uppercase`, `letter-spacing: 0.04em`, `--v-font-size-xs`, `font-weight: 600`, `color: var(--v-text-muted)`
|
|
78
|
-
- **Monospace data:** Use `--v-font-mono` for numbers in metrics, code, timestamps
|
|
79
|
-
|
|
80
|
-
### Spacing & Layout
|
|
81
|
-
|
|
82
|
-
- Use the `--v-spacing-*` scale consistently — don't mix arbitrary pixel values with token values
|
|
83
|
-
- **Card padding:** `--v-spacing-lg` (16px) minimum, `--v-spacing-xl` (24px) for hero/featured cards
|
|
84
|
-
- **Section gaps:** `--v-spacing-xxl` (32px) to `--v-spacing-xxxl` (48px) between major sections — Lovable-quality apps use generous whitespace
|
|
85
|
-
- **Hero to first content:** minimum `--v-spacing-xxxl` (48px)
|
|
86
|
-
- **Element gaps:** `--v-spacing-sm` to `--v-spacing-md` between related elements
|
|
87
|
-
- **When in doubt, add more whitespace.** The #1 difference between AI-generated and designer-quality is spacing. Double what feels right, then evaluate.
|
|
88
|
-
- Use CSS Grid for dashboards and complex layouts. Use Flexbox for single-axis arrangements.
|
|
89
|
-
- Every layout should look good from 400px to 600px wide
|
|
90
|
-
|
|
91
|
-
## Visual Techniques Cookbook
|
|
92
|
-
|
|
93
|
-
Copy-paste-ready CSS techniques. All work in the sandboxed WebView with no external dependencies.
|
|
94
|
-
|
|
95
|
-
### Animated Gradient Background
|
|
96
|
-
|
|
97
|
-
Choose **one** of the following color variants (do not combine both):
|
|
98
|
-
|
|
99
|
-
**Variant A — Warm pastels (light, airy feel):**
|
|
100
|
-
```css
|
|
101
|
-
body {
|
|
102
|
-
background: linear-gradient(-45deg, #fef3c7, #fce7f3, #e0e7ff, #d1fae5);
|
|
103
|
-
background-size: 400% 400%;
|
|
104
|
-
animation: gradientShift 15s ease infinite;
|
|
105
|
-
}
|
|
106
|
-
@keyframes gradientShift {
|
|
107
|
-
0%, 100% { background-position: 0% 50%; }
|
|
108
|
-
50% { background-position: 100% 50%; }
|
|
109
|
-
}
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
**Variant B — Dark jewel tones (deep, rich feel):**
|
|
113
|
-
```css
|
|
114
|
-
body {
|
|
115
|
-
background: linear-gradient(-45deg, #0f172a, #1e1b4b, #172554, #0c4a6e);
|
|
116
|
-
background-size: 400% 400%;
|
|
117
|
-
animation: gradientShift 15s ease infinite;
|
|
118
|
-
}
|
|
119
|
-
@keyframes gradientShift {
|
|
120
|
-
0%, 100% { background-position: 0% 50%; }
|
|
121
|
-
50% { background-position: 100% 50%; }
|
|
122
|
-
}
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
### Mesh Gradient (Layered Radials)
|
|
126
|
-
```css
|
|
127
|
-
body {
|
|
128
|
-
background:
|
|
129
|
-
radial-gradient(ellipse at 20% 50%, color-mix(in srgb, var(--v-rose-400) 15%, transparent) 0%, transparent 50%),
|
|
130
|
-
radial-gradient(ellipse at 80% 20%, color-mix(in srgb, var(--v-amber-400) 12%, transparent) 0%, transparent 50%),
|
|
131
|
-
radial-gradient(ellipse at 50% 80%, color-mix(in srgb, var(--v-teal-400) 10%, transparent) 0%, transparent 50%),
|
|
132
|
-
var(--v-bg);
|
|
133
|
-
}
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
### Glassmorphism Card
|
|
137
|
-
```css
|
|
138
|
-
.glass-card {
|
|
139
|
-
background: color-mix(in srgb, var(--v-surface) 70%, transparent);
|
|
140
|
-
backdrop-filter: blur(12px);
|
|
141
|
-
-webkit-backdrop-filter: blur(12px);
|
|
142
|
-
border: 1px solid color-mix(in srgb, var(--v-surface-border) 50%, transparent);
|
|
143
|
-
border-radius: var(--v-radius-lg);
|
|
144
|
-
box-shadow: var(--v-shadow-lg);
|
|
145
|
-
}
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
### Layered Shadows (Realistic Depth)
|
|
149
|
-
```css
|
|
150
|
-
.elevated-card {
|
|
151
|
-
box-shadow:
|
|
152
|
-
0 1px 2px rgba(0,0,0,0.04),
|
|
153
|
-
0 4px 8px rgba(0,0,0,0.06),
|
|
154
|
-
0 12px 24px rgba(0,0,0,0.08);
|
|
155
|
-
transition: box-shadow var(--v-duration-standard), transform var(--v-duration-standard);
|
|
156
|
-
}
|
|
157
|
-
.elevated-card:hover {
|
|
158
|
-
transform: translateY(-2px);
|
|
159
|
-
box-shadow:
|
|
160
|
-
0 2px 4px rgba(0,0,0,0.04),
|
|
161
|
-
0 8px 16px rgba(0,0,0,0.08),
|
|
162
|
-
0 24px 48px rgba(0,0,0,0.12);
|
|
163
|
-
}
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
### Noise/Grain Texture Overlay
|
|
167
|
-
```css
|
|
168
|
-
body::before {
|
|
169
|
-
content: '';
|
|
170
|
-
position: fixed;
|
|
171
|
-
inset: 0;
|
|
172
|
-
opacity: 0.03;
|
|
173
|
-
pointer-events: none;
|
|
174
|
-
z-index: 9999;
|
|
175
|
-
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
|
|
176
|
-
}
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
### Gradient Text
|
|
180
|
-
```css
|
|
181
|
-
.gradient-text {
|
|
182
|
-
background: linear-gradient(135deg, var(--v-rose-500), var(--v-amber-400));
|
|
183
|
-
-webkit-background-clip: text;
|
|
184
|
-
-webkit-text-fill-color: transparent;
|
|
185
|
-
background-clip: text;
|
|
186
|
-
}
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
### Glow Effect
|
|
190
|
-
```css
|
|
191
|
-
.glow-accent {
|
|
192
|
-
box-shadow:
|
|
193
|
-
0 0 20px color-mix(in srgb, var(--v-accent) 30%, transparent),
|
|
194
|
-
0 0 40px color-mix(in srgb, var(--v-accent) 15%, transparent);
|
|
195
|
-
}
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
### Dot Grid Pattern Background
|
|
199
|
-
```css
|
|
200
|
-
.dot-pattern {
|
|
201
|
-
background-image: radial-gradient(circle, var(--v-surface-border) 1px, transparent 1px);
|
|
202
|
-
background-size: 20px 20px;
|
|
203
|
-
}
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
### Staggered Reveal Animation
|
|
207
|
-
```css
|
|
208
|
-
.reveal { opacity: 0; transform: translateY(20px); transition: opacity 0.6s ease, transform 0.6s ease; }
|
|
209
|
-
.reveal.visible { opacity: 1; transform: translateY(0); }
|
|
210
|
-
```
|
|
211
|
-
```javascript
|
|
212
|
-
const observer = new IntersectionObserver((entries) => {
|
|
213
|
-
entries.forEach((entry, i) => {
|
|
214
|
-
if (entry.isIntersecting) {
|
|
215
|
-
setTimeout(() => entry.target.classList.add('visible'), i * 100);
|
|
216
|
-
observer.unobserve(entry.target);
|
|
217
|
-
}
|
|
218
|
-
});
|
|
219
|
-
}, { threshold: 0.1 });
|
|
220
|
-
document.querySelectorAll('.reveal').forEach(el => observer.observe(el));
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
### Card Hover (Lift + Border Glow)
|
|
224
|
-
```css
|
|
225
|
-
.interactive-card {
|
|
226
|
-
transition: transform var(--v-duration-standard), box-shadow var(--v-duration-standard),
|
|
227
|
-
border-color var(--v-duration-standard);
|
|
228
|
-
border: 1px solid var(--v-surface-border);
|
|
229
|
-
cursor: pointer;
|
|
230
|
-
}
|
|
231
|
-
.interactive-card:hover {
|
|
232
|
-
transform: translateY(-4px);
|
|
233
|
-
box-shadow: var(--v-shadow-lg), 0 0 0 1px color-mix(in srgb, var(--v-accent) 20%, transparent);
|
|
234
|
-
border-color: color-mix(in srgb, var(--v-accent) 40%, var(--v-surface-border));
|
|
235
|
-
}
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
### Loading Skeleton Shimmer
|
|
239
|
-
```css
|
|
240
|
-
.skeleton {
|
|
241
|
-
background: linear-gradient(90deg,
|
|
242
|
-
var(--v-surface) 25%,
|
|
243
|
-
color-mix(in srgb, var(--v-surface-border) 50%, var(--v-surface)) 50%,
|
|
244
|
-
var(--v-surface) 75%);
|
|
245
|
-
background-size: 200% 100%;
|
|
246
|
-
animation: shimmer 1.5s infinite;
|
|
247
|
-
border-radius: var(--v-radius-sm);
|
|
248
|
-
}
|
|
249
|
-
.skeleton-text { height: 14px; margin-bottom: 8px; width: 80%; }
|
|
250
|
-
.skeleton-heading { height: 24px; margin-bottom: 12px; width: 60%; }
|
|
251
|
-
.skeleton-avatar { width: 40px; height: 40px; border-radius: 50%; }
|
|
252
|
-
@keyframes shimmer { to { background-position: -200% 0; } }
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
### Animated Checkmark (Success Feedback)
|
|
256
|
-
```css
|
|
257
|
-
.checkmark-circle {
|
|
258
|
-
width: 48px; height: 48px; border-radius: 50%;
|
|
259
|
-
background: var(--v-success); display: flex;
|
|
260
|
-
align-items: center; justify-content: center;
|
|
261
|
-
animation: scaleIn 0.3s ease;
|
|
262
|
-
}
|
|
263
|
-
.checkmark-circle::after {
|
|
264
|
-
content: ''; width: 12px; height: 20px;
|
|
265
|
-
border: solid white; border-width: 0 3px 3px 0;
|
|
266
|
-
transform: rotate(45deg); margin-top: -4px;
|
|
267
|
-
animation: checkDraw 0.2s 0.2s ease both;
|
|
268
|
-
}
|
|
269
|
-
@keyframes scaleIn { from { transform: scale(0); } to { transform: scale(1); } }
|
|
270
|
-
@keyframes checkDraw { from { opacity: 0; } to { opacity: 1; } }
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
### Navigation Bar (Sticky Header)
|
|
274
|
-
```html
|
|
275
|
-
<nav class="app-navbar">
|
|
276
|
-
<div class="navbar-brand">🌿 PlantCare</div>
|
|
277
|
-
<div class="navbar-links">
|
|
278
|
-
<a href="#" class="nav-link active">Dashboard</a>
|
|
279
|
-
<a href="#" class="nav-link">My Plants</a>
|
|
280
|
-
<a href="#" class="nav-link">Schedule</a>
|
|
281
|
-
</div>
|
|
282
|
-
<button class="v-button navbar-cta">Add Plant</button>
|
|
283
|
-
</nav>
|
|
284
|
-
```
|
|
285
|
-
```css
|
|
286
|
-
.app-navbar {
|
|
287
|
-
position: sticky; top: 0; z-index: 100;
|
|
288
|
-
display: flex; align-items: center; gap: var(--v-spacing-lg);
|
|
289
|
-
padding: var(--v-spacing-md) var(--v-spacing-xl);
|
|
290
|
-
background: color-mix(in srgb, var(--bg-tint, var(--v-bg)) 85%, transparent);
|
|
291
|
-
backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
|
|
292
|
-
border-bottom: 1px solid var(--v-surface-border);
|
|
293
|
-
}
|
|
294
|
-
.navbar-brand { font-weight: 700; font-size: var(--v-font-size-lg); }
|
|
295
|
-
.navbar-links { display: flex; gap: var(--v-spacing-sm); margin-left: auto; }
|
|
296
|
-
.navbar-links .nav-link {
|
|
297
|
-
padding: var(--v-spacing-xs) var(--v-spacing-md); border-radius: var(--v-radius-md);
|
|
298
|
-
color: var(--v-text-secondary); font-weight: 500; font-size: var(--v-font-size-sm);
|
|
299
|
-
text-decoration: none; transition: all var(--v-duration-fast);
|
|
300
|
-
}
|
|
301
|
-
.navbar-links .nav-link:hover { color: var(--v-text); background: var(--v-surface); }
|
|
302
|
-
.navbar-links .nav-link.active { color: var(--accent, var(--v-accent)); font-weight: 600; }
|
|
303
|
-
.navbar-cta { margin-left: var(--v-spacing-sm); padding: var(--v-spacing-xs) var(--v-spacing-lg); font-size: var(--v-font-size-sm); }
|
|
304
|
-
```
|
|
305
|
-
|
|
306
|
-
### Pill Badge / Trust Badge
|
|
307
|
-
```html
|
|
308
|
-
<span class="trust-pill">🌟 Trusted by 12,000+ homes</span>
|
|
309
|
-
<span class="trust-pill accent">+8.2% this week</span>
|
|
310
|
-
```
|
|
311
|
-
```css
|
|
312
|
-
.trust-pill {
|
|
313
|
-
display: inline-flex; align-items: center; gap: var(--v-spacing-xs);
|
|
314
|
-
padding: var(--v-spacing-xs) var(--v-spacing-md);
|
|
315
|
-
background: var(--v-surface); border: 1px solid var(--v-surface-border);
|
|
316
|
-
border-radius: var(--v-radius-md); font-size: var(--v-font-size-xs);
|
|
317
|
-
font-weight: 600; color: var(--v-text-secondary);
|
|
318
|
-
}
|
|
319
|
-
.trust-pill.accent {
|
|
320
|
-
background: color-mix(in srgb, var(--accent, var(--v-accent)) 10%, transparent);
|
|
321
|
-
border-color: color-mix(in srgb, var(--accent, var(--v-accent)) 25%, transparent);
|
|
322
|
-
color: var(--accent, var(--v-accent));
|
|
323
|
-
}
|
|
324
|
-
```
|
|
325
|
-
|
|
326
|
-
### Emoji Stat Card
|
|
327
|
-
```html
|
|
328
|
-
<div class="emoji-stat-row">
|
|
329
|
-
<div class="emoji-stat-card">
|
|
330
|
-
<span class="emoji-stat-icon">🔥</span>
|
|
331
|
-
<span class="emoji-stat-value">1,284</span>
|
|
332
|
-
<span class="emoji-stat-label">Calories</span>
|
|
333
|
-
</div>
|
|
334
|
-
<div class="emoji-stat-card">
|
|
335
|
-
<span class="emoji-stat-icon">🏃</span>
|
|
336
|
-
<span class="emoji-stat-value">8,421</span>
|
|
337
|
-
<span class="emoji-stat-label">Steps</span>
|
|
338
|
-
</div>
|
|
339
|
-
<div class="emoji-stat-card">
|
|
340
|
-
<span class="emoji-stat-icon">💧</span>
|
|
341
|
-
<span class="emoji-stat-value">2.4L</span>
|
|
342
|
-
<span class="emoji-stat-label">Hydration</span>
|
|
343
|
-
</div>
|
|
344
|
-
</div>
|
|
345
|
-
```
|
|
346
|
-
```css
|
|
347
|
-
.emoji-stat-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: var(--v-spacing-md); }
|
|
348
|
-
.emoji-stat-card {
|
|
349
|
-
background: var(--v-surface); border: 1px solid var(--v-surface-border);
|
|
350
|
-
border-radius: var(--v-radius-lg); padding: var(--v-spacing-lg);
|
|
351
|
-
display: flex; flex-direction: column; align-items: center; gap: var(--v-spacing-xs);
|
|
352
|
-
text-align: center;
|
|
353
|
-
}
|
|
354
|
-
.emoji-stat-icon { font-size: 28px; line-height: 1; }
|
|
355
|
-
.emoji-stat-value { font-size: var(--v-font-size-xl); font-weight: 700; color: var(--v-text); }
|
|
356
|
-
.emoji-stat-label { font-size: var(--v-font-size-xs); color: var(--v-text-muted); text-transform: uppercase; letter-spacing: 0.04em; }
|
|
357
|
-
```
|
|
11
|
+
**Your default behavior:** Build immediately. The user types "build me a habit tracker" and you deliver a complete, polished app with a domain-matched color palette, atmospheric background, and thoughtful interactions. Don't ask what colors they want. Don't show wireframes. Just build something stunning and let them refine from there.
|
|
358
12
|
|
|
359
|
-
|
|
360
|
-
```html
|
|
361
|
-
<h1>Track your <span class="accent-word">Growth</span> daily</h1>
|
|
362
|
-
<!-- Or with gradient variant: -->
|
|
363
|
-
<h1>Imagine it. <span class="v-gradient-text">See it.</span></h1>
|
|
364
|
-
```
|
|
365
|
-
```css
|
|
366
|
-
.accent-word { color: var(--accent, var(--v-accent)); }
|
|
367
|
-
/* Gradient variant — use .v-gradient-text from the design system, or customize: */
|
|
368
|
-
.accent-gradient {
|
|
369
|
-
background: linear-gradient(135deg, var(--accent, var(--v-rose-500)), var(--v-amber-400));
|
|
370
|
-
-webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;
|
|
371
|
-
}
|
|
372
|
-
```
|
|
373
|
-
|
|
374
|
-
### Interactive Pill Toggles
|
|
375
|
-
```html
|
|
376
|
-
<div class="pill-toggles">
|
|
377
|
-
<button class="pill-toggle active">1W</button>
|
|
378
|
-
<button class="pill-toggle">1M</button>
|
|
379
|
-
<button class="pill-toggle">3M</button>
|
|
380
|
-
<button class="pill-toggle">1Y</button>
|
|
381
|
-
</div>
|
|
382
|
-
```
|
|
383
|
-
```css
|
|
384
|
-
.pill-toggles {
|
|
385
|
-
display: inline-flex; gap: var(--v-spacing-xxs);
|
|
386
|
-
background: var(--v-surface); border: 1px solid var(--v-surface-border);
|
|
387
|
-
border-radius: var(--v-radius-md); padding: var(--v-spacing-xxs);
|
|
388
|
-
}
|
|
389
|
-
.pill-toggle {
|
|
390
|
-
padding: var(--v-spacing-xs) var(--v-spacing-md);
|
|
391
|
-
border-radius: var(--v-radius-md); border: none; background: none;
|
|
392
|
-
font-size: var(--v-font-size-sm); font-weight: 500; color: var(--v-text-secondary);
|
|
393
|
-
cursor: pointer; transition: all var(--v-duration-fast);
|
|
394
|
-
}
|
|
395
|
-
.pill-toggle:hover { color: var(--v-text); }
|
|
396
|
-
.pill-toggle.active {
|
|
397
|
-
background: var(--accent, var(--v-accent)); color: white; font-weight: 600;
|
|
398
|
-
box-shadow: var(--v-shadow-sm);
|
|
399
|
-
}
|
|
400
|
-
```
|
|
401
|
-
```javascript
|
|
402
|
-
document.querySelectorAll('.pill-toggles').forEach(group => {
|
|
403
|
-
group.addEventListener('click', (e) => {
|
|
404
|
-
if (!e.target.classList.contains('pill-toggle')) return;
|
|
405
|
-
group.querySelectorAll('.pill-toggle').forEach(b => b.classList.remove('active'));
|
|
406
|
-
e.target.classList.add('active');
|
|
407
|
-
});
|
|
408
|
-
});
|
|
409
|
-
```
|
|
410
|
-
|
|
411
|
-
### Suggestion Chips
|
|
412
|
-
```html
|
|
413
|
-
<div class="chip-group">
|
|
414
|
-
<button class="chip">🏠 All Rooms</button>
|
|
415
|
-
<button class="chip">🛋️ Living Room</button>
|
|
416
|
-
<button class="chip">🍳 Kitchen</button>
|
|
417
|
-
<button class="chip">🛏️ Bedroom</button>
|
|
418
|
-
<button class="chip active">🚿 Bathroom</button>
|
|
419
|
-
</div>
|
|
420
|
-
```
|
|
421
|
-
```css
|
|
422
|
-
.chip-group { display: flex; flex-wrap: wrap; gap: var(--v-spacing-xs); }
|
|
423
|
-
.chip {
|
|
424
|
-
padding: var(--v-spacing-xs) var(--v-spacing-md);
|
|
425
|
-
border-radius: var(--v-radius-md); border: 1px solid var(--v-surface-border);
|
|
426
|
-
background: var(--v-surface); font-size: var(--v-font-size-sm);
|
|
427
|
-
color: var(--v-text-secondary); cursor: pointer; transition: all var(--v-duration-fast);
|
|
428
|
-
}
|
|
429
|
-
.chip:hover { border-color: var(--accent, var(--v-accent)); color: var(--v-text); }
|
|
430
|
-
.chip.active {
|
|
431
|
-
background: color-mix(in srgb, var(--accent, var(--v-accent)) 12%, transparent);
|
|
432
|
-
border-color: var(--accent, var(--v-accent)); color: var(--accent, var(--v-accent)); font-weight: 600;
|
|
433
|
-
}
|
|
434
|
-
```
|
|
435
|
-
|
|
436
|
-
### Category Card Row
|
|
437
|
-
```html
|
|
438
|
-
<div class="category-cards">
|
|
439
|
-
<div class="category-card">
|
|
440
|
-
<span class="category-icon">🧹</span>
|
|
441
|
-
<span class="category-name">Standard Clean</span>
|
|
442
|
-
<span class="category-meta">2-3 hrs · From $60</span>
|
|
443
|
-
</div>
|
|
444
|
-
<div class="category-card">
|
|
445
|
-
<span class="category-icon">✨</span>
|
|
446
|
-
<span class="category-name">Deep Clean</span>
|
|
447
|
-
<span class="category-meta">4-5 hrs · From $120</span>
|
|
448
|
-
</div>
|
|
449
|
-
<div class="category-card">
|
|
450
|
-
<span class="category-icon">📦</span>
|
|
451
|
-
<span class="category-name">Move-Out</span>
|
|
452
|
-
<span class="category-meta">5-7 hrs · From $180</span>
|
|
453
|
-
</div>
|
|
454
|
-
</div>
|
|
455
|
-
```
|
|
456
|
-
```css
|
|
457
|
-
.category-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: var(--v-spacing-md); }
|
|
458
|
-
.category-card {
|
|
459
|
-
background: var(--v-surface); border: 1px solid var(--v-surface-border);
|
|
460
|
-
border-radius: var(--v-radius-lg); padding: var(--v-spacing-lg);
|
|
461
|
-
display: flex; flex-direction: column; align-items: center; gap: var(--v-spacing-sm);
|
|
462
|
-
text-align: center; cursor: pointer;
|
|
463
|
-
transition: transform var(--v-duration-fast), border-color var(--v-duration-fast);
|
|
464
|
-
}
|
|
465
|
-
.category-card:hover { transform: translateY(-2px); border-color: var(--accent, var(--v-accent)); }
|
|
466
|
-
.category-icon { font-size: 32px; line-height: 1; }
|
|
467
|
-
.category-name { font-weight: 600; font-size: var(--v-font-size-base); color: var(--v-text); }
|
|
468
|
-
.category-meta { font-size: var(--v-font-size-xs); color: var(--v-text-muted); }
|
|
469
|
-
```
|
|
13
|
+
**Design quality is delegated to the `frontend-design` skill.** That skill defines your aesthetic principles: typography, color strategy, motion, spatial composition, and visual detail. Follow it completely for every build. This skill (app-builder) handles the technical infrastructure: sandbox constraints, data bridge, widget API, app lifecycle, and interaction patterns.
|
|
470
14
|
|
|
471
15
|
## Workflow
|
|
472
16
|
|
|
@@ -475,7 +19,7 @@ document.querySelectorAll('.pill-toggles').forEach(group => {
|
|
|
475
19
|
**Default: just build.** When a user says "build me a habit tracker," don't ask what colors they want or how many fields to include. Immediately:
|
|
476
20
|
|
|
477
21
|
1. Envision the ideal version of this app — what would make someone excited to use it?
|
|
478
|
-
2. Pick a distinctive visual direction
|
|
22
|
+
2. Pick a distinctive visual direction following the `frontend-design` skill
|
|
479
23
|
3. Design a clean data schema
|
|
480
24
|
4. Build the complete, polished app with animations, interactions, and empty states
|
|
481
25
|
|
|
@@ -485,11 +29,14 @@ document.querySelectorAll('.pill-toggles').forEach(group => {
|
|
|
485
29
|
|
|
486
30
|
**When in doubt, build something impressive** and let the user refine with `app_update`. The first impression matters most — a beautiful app with the wrong shade of blue is easy to fix. A correct but ugly app is hard to come back from.
|
|
487
31
|
|
|
32
|
+
**There are no "quick" builds.** Every app, regardless of complexity, gets the full design treatment. A 3-field form and a 20-section dashboard get the same design care. The only difference is scope, not quality.
|
|
33
|
+
|
|
488
34
|
### 2. Design the Data Schema
|
|
489
35
|
|
|
490
36
|
Create a JSON Schema that defines the structure of a single record. Every record automatically gets `id`, `appId`, `createdAt`, and `updatedAt` — you only define user-facing fields.
|
|
491
37
|
|
|
492
38
|
Schema guidelines:
|
|
39
|
+
|
|
493
40
|
- Use `type: "object"` at the top level
|
|
494
41
|
- Define `properties` for each field
|
|
495
42
|
- Supported types: `string`, `number`, `boolean`
|
|
@@ -497,13 +44,20 @@ Schema guidelines:
|
|
|
497
44
|
- Keep schemas reasonably flat — encode complex nested data as JSON strings when needed
|
|
498
45
|
|
|
499
46
|
Example schema for a project tracker:
|
|
47
|
+
|
|
500
48
|
```json
|
|
501
49
|
{
|
|
502
50
|
"type": "object",
|
|
503
51
|
"properties": {
|
|
504
52
|
"title": { "type": "string" },
|
|
505
|
-
"status": {
|
|
506
|
-
|
|
53
|
+
"status": {
|
|
54
|
+
"type": "string",
|
|
55
|
+
"enum": ["backlog", "in-progress", "review", "done"]
|
|
56
|
+
},
|
|
57
|
+
"priority": {
|
|
58
|
+
"type": "string",
|
|
59
|
+
"enum": ["low", "medium", "high", "critical"]
|
|
60
|
+
},
|
|
507
61
|
"description": { "type": "string" },
|
|
508
62
|
"tags": { "type": "string" }
|
|
509
63
|
},
|
|
@@ -531,29 +85,29 @@ A design system CSS is auto-injected inside a `@layer`, so your styles always ta
|
|
|
531
85
|
|
|
532
86
|
Available design tokens:
|
|
533
87
|
|
|
534
|
-
| Category
|
|
535
|
-
|
|
536
|
-
| **Backgrounds** | `--v-bg`, `--v-surface`, `--v-surface-border`
|
|
537
|
-
| **Text**
|
|
538
|
-
| **Accent**
|
|
539
|
-
| **Status**
|
|
540
|
-
| **Spacing**
|
|
541
|
-
| **Radius**
|
|
542
|
-
| **Shadows**
|
|
543
|
-
| **Typography**
|
|
544
|
-
| **Animation**
|
|
545
|
-
| **Palettes**
|
|
88
|
+
| Category | Tokens |
|
|
89
|
+
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
90
|
+
| **Backgrounds** | `--v-bg`, `--v-surface`, `--v-surface-border` |
|
|
91
|
+
| **Text** | `--v-text`, `--v-text-secondary`, `--v-text-muted` |
|
|
92
|
+
| **Accent** | `--v-accent`, `--v-accent-hover` |
|
|
93
|
+
| **Status** | `--v-success`, `--v-danger`, `--v-warning` |
|
|
94
|
+
| **Spacing** | `--v-spacing-xxs` (2px) / `-xs` (4px) / `-sm` (8px) / `-md` (12px) / `-lg` (16px) / `-xl` (24px) / `-xxl` (32px) / `-xxxl` (48px) |
|
|
95
|
+
| **Radius** | `--v-radius-xs` (2px) / `-sm` (4px) / `-md` (8px) / `-lg` (12px) / `-xl` (16px) / `-pill` (999px) |
|
|
96
|
+
| **Shadows** | `--v-shadow-sm`, `--v-shadow-md`, `--v-shadow-lg` |
|
|
97
|
+
| **Typography** | `--v-font-family`, `--v-font-mono`, `--v-font-size-xs` (10px) / `-sm` (11px) / `-base` (14px) / `-lg` (17px) / `-xl` (22px) / `-2xl` (26px), `--v-line-height` |
|
|
98
|
+
| **Animation** | `--v-duration-fast` (0.15s) / `-standard` (0.25s) / `-slow` (0.4s) |
|
|
99
|
+
| **Palettes** | `--v-slate-{950..50}`, `--v-emerald-*`, `--v-violet-*`, `--v-indigo-*`, `--v-rose-*`, `--v-amber-*` |
|
|
546
100
|
|
|
547
101
|
Utility classes: `.v-button` (`.secondary`/`.danger`/`.ghost`), `.v-card`, `.v-list`/`.v-list-item`, `.v-badge` (`.success`/`.warning`/`.danger`), `.v-input-row`, `.v-empty-state`, `.v-toggle`.
|
|
548
102
|
|
|
549
103
|
**Custom themes:** When the user wants a specific branded look, write complete CSS with hardcoded colors and `@media (prefers-color-scheme: dark)` for dark variants. Don't mix `--v-*` auto-switching variables with hardcoded colors in the same element.
|
|
550
104
|
|
|
551
105
|
**Theme detection in JavaScript:**
|
|
106
|
+
|
|
552
107
|
```javascript
|
|
553
108
|
console.log(window.vellum.theme.mode); // 'light' or 'dark'
|
|
554
|
-
window.addEventListener(
|
|
555
|
-
|
|
556
|
-
console.log('Theme:', e.detail.mode);
|
|
109
|
+
window.addEventListener("vellum-theme-change", (e) => {
|
|
110
|
+
console.log("Theme:", e.detail.mode);
|
|
557
111
|
});
|
|
558
112
|
```
|
|
559
113
|
|
|
@@ -561,617 +115,127 @@ window.addEventListener('vellum-theme-change', (e) => {
|
|
|
561
115
|
|
|
562
116
|
A CSS/JS widget library is auto-injected alongside the design system. Use these for standard UI patterns — skip them when custom HTML serves the user better.
|
|
563
117
|
|
|
564
|
-
**Layout
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
`.v-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
`.v-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
`.v-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
</div>
|
|
612
|
-
</div>
|
|
613
|
-
```
|
|
614
|
-
|
|
615
|
-
`.v-search-bar` — Search input with clear button:
|
|
616
|
-
```html
|
|
617
|
-
<div class="v-search-bar">
|
|
618
|
-
<input type="text" placeholder="Search..." id="search">
|
|
619
|
-
<button class="v-search-clear">✕</button>
|
|
620
|
-
</div>
|
|
621
|
-
```
|
|
622
|
-
|
|
623
|
-
`.v-empty-state` — No-data placeholder with CTA:
|
|
624
|
-
```html
|
|
625
|
-
<div class="v-empty-state">
|
|
626
|
-
<div class="v-empty-icon">📋</div>
|
|
627
|
-
<div class="v-empty-title">No items yet</div>
|
|
628
|
-
<div class="v-empty-desc">Create your first item to get started.</div>
|
|
629
|
-
<button class="v-button">Create Item</button>
|
|
630
|
-
</div>
|
|
631
|
-
```
|
|
632
|
-
|
|
633
|
-
**Additional layout widgets** (use with semantic HTML, all support `--v-*` tokens):
|
|
634
|
-
|
|
635
|
-
| Widget | Usage | Key Classes/Modifiers |
|
|
636
|
-
|---|---|---|
|
|
637
|
-
| `.v-timeline` | Vertical timeline | `.v-timeline-entry` (`.active`/`.success`/`.error`), `.v-timeline-time`, `.v-timeline-title`, `.v-timeline-desc` |
|
|
638
|
-
| `.v-action-list` | Rows with per-item actions | `.v-action-list-item`, `.v-action-content`, `.v-action-title`, `.v-action-subtitle`, `.v-action-buttons` |
|
|
639
|
-
| `.v-card-grid` | Responsive card grid | Wrap `.v-card` elements |
|
|
640
|
-
| `.v-progress-bar` | Horizontal progress | `.v-progress-header`, `.v-progress-track`, `.v-progress-fill` (`.success`/`.warning`/`.danger`) |
|
|
641
|
-
| `.v-status-badge` | Colored pill with dot | `.success`, `.error`, `.warning`, `.info` |
|
|
642
|
-
| `.v-stat-row` | Horizontal label-value pairs | `.v-stat`, `.v-stat-label`, `.v-stat-value` |
|
|
643
|
-
| `.v-toast` | Notification banner | `.success`, `.error`, `.warning`, `.info` — prefer `vellum.widgets.toast()` |
|
|
644
|
-
| `.v-divider` | Section separator | Optional text label inside |
|
|
645
|
-
| `.v-avatar-row` | Contact/team display | `.v-avatar`, `.v-avatar-info`, `.v-avatar-name`, `.v-avatar-subtitle` |
|
|
646
|
-
| `.v-tag-group` | Wrapping tag row | Wrap `.v-badge` elements |
|
|
647
|
-
|
|
648
|
-
**Domain-specific widgets** (infer HTML structure from class names):
|
|
649
|
-
|
|
650
|
-
| Widget | Purpose | Key Classes |
|
|
651
|
-
|---|---|---|
|
|
652
|
-
| `.v-weather-card` | Temperature + forecast | `.v-weather-main`, `.v-weather-temp`, `.v-weather-condition`, `.v-weather-icon`, `.v-weather-details`, `.v-weather-forecast`, `.v-weather-forecast-item` |
|
|
653
|
-
| `.v-stock-ticker` | Price display + chart | `.v-stock-header`, `.v-stock-symbol`, `.v-stock-price`, `.v-stock-change` (`.up`/`.down`), `.v-stock-chart`, `.v-stock-meta` |
|
|
654
|
-
| `.v-flight-card` | Flight info | `.v-flight-header`, `.v-flight-airline`, `.v-flight-price`, `.v-flight-route`, `.v-flight-endpoint`, `.v-flight-time`, `.v-flight-code`, `.v-flight-duration`, `.v-flight-line` |
|
|
655
|
-
| `.v-billing-chart` | Usage/billing display | `.v-billing-header`, `.v-billing-total`, `.v-billing-period`, `.v-billing-canvas`, `.v-billing-legend`, `.v-billing-legend-item`, `.v-billing-legend-dot` |
|
|
656
|
-
| `.v-boarding-pass` | Pass-styled layout | `.v-bp-header`, `.v-bp-route`, `.v-bp-city`, `.v-bp-details`, `.v-bp-field`, `.v-bp-field-label`, `.v-bp-field-value` |
|
|
657
|
-
| `.v-itinerary` | Day-by-day travel plan | `.v-itinerary-day`, `.v-itinerary-date`, `.v-itinerary-item`, `.v-itinerary-time`, `.v-itinerary-content`, `.v-itinerary-title`, `.v-itinerary-location` |
|
|
658
|
-
| `.v-receipt` | Receipt layout | `.v-receipt-header`, `.v-receipt-store`, `.v-receipt-items`, `.v-receipt-line`, `.v-receipt-divider`, `.v-receipt-total` |
|
|
659
|
-
| `.v-invoice` | Formal invoice | `.v-invoice-header`, `.v-invoice-title`, `.v-invoice-number`, `.v-invoice-parties`, `.v-invoice-party-label`, `.v-invoice-party-name`, `.v-invoice-table`, `.v-invoice-totals`, `.v-invoice-line` (`.total`) |
|
|
660
|
-
|
|
661
|
-
**Content & landing page components:**
|
|
662
|
-
|
|
663
|
-
`.v-hero` — Hero banner with gradient background, trust badge, and accent word:
|
|
664
|
-
```html
|
|
665
|
-
<div class="v-hero">
|
|
666
|
-
<span class="v-hero-badge">✨ Now with 4x faster generation</span>
|
|
667
|
-
<h1>Imagine it. <span class="v-gradient-text">See it.</span></h1>
|
|
668
|
-
<p class="v-hero-subtitle">A compelling tagline that makes users feel something.</p>
|
|
669
|
-
</div>
|
|
670
|
-
```
|
|
671
|
-
|
|
672
|
-
`.v-section-header` — Section intro with label:
|
|
673
|
-
```html
|
|
674
|
-
<div class="v-section-header">
|
|
675
|
-
<span class="v-section-label">🎯 Section</span>
|
|
676
|
-
<h2>Section Title</h2>
|
|
677
|
-
<p class="v-section-desc">Description text.</p>
|
|
678
|
-
</div>
|
|
679
|
-
```
|
|
680
|
-
|
|
681
|
-
`.v-feature-grid` + `.v-feature-card` — Feature showcase with hover lift:
|
|
682
|
-
```html
|
|
683
|
-
<div class="v-feature-grid">
|
|
684
|
-
<div class="v-feature-card">
|
|
685
|
-
<div class="v-feature-icon">🚀</div>
|
|
686
|
-
<div class="v-feature-title">Feature Name</div>
|
|
687
|
-
<div class="v-feature-desc">Short description.</div>
|
|
688
|
-
</div>
|
|
689
|
-
</div>
|
|
690
|
-
```
|
|
691
|
-
|
|
692
|
-
`.v-pullquote` — Blockquote with gradient accent border. `.v-comparison` — Before/after cards (3-column grid with `.before`/`.after` modifiers). `.v-page` — Centered container (max-width 600px). Use `.v-animate-in` on children for staggered fade-in. Use `.v-gradient-text` for accent-colored gradient text.
|
|
693
|
-
|
|
694
|
-
`.v-slideshow` — Presentation slide deck with transitions and navigation. Init with `vellum.widgets.slideshow()`:
|
|
695
|
-
```html
|
|
696
|
-
<div class="v-slideshow" id="deck">
|
|
697
|
-
<div class="v-slide">
|
|
698
|
-
<div class="v-slide-header">
|
|
699
|
-
<span class="v-slide-label">Overview</span>
|
|
700
|
-
</div>
|
|
701
|
-
<h1 class="v-slide-title">The city that never <span class="accent-word">sleeps</span></h1>
|
|
702
|
-
<p class="v-slide-body">Body text here...</p>
|
|
703
|
-
<div class="v-slide-stats">
|
|
704
|
-
<div class="v-slide-stat">
|
|
705
|
-
<span class="v-slide-stat-value">8.3M</span>
|
|
706
|
-
<span class="v-slide-stat-label">Residents</span>
|
|
707
|
-
</div>
|
|
708
|
-
</div>
|
|
709
|
-
</div>
|
|
710
|
-
<div class="v-slide"><!-- Slide 2 --></div>
|
|
711
|
-
<div class="v-slide"><!-- Slide 3 --></div>
|
|
712
|
-
</div>
|
|
713
|
-
```
|
|
714
|
-
Slide content helpers: `.v-slide-label` (section label with colored dot), `.v-slide-title` (responsive heading), `.v-slide-body` (body text, max-width 540px), `.v-slide-stats` (auto-fit grid), `.v-slide-stat` / `.v-slide-stat-value` / `.v-slide-stat-label` (big-number cards), `.v-slide-quote` / `.v-slide-quote-attribution` (blockquote), `.v-slide-list` (styled list), `.v-slide-columns` / `.v-slide-column` (2-column comparison grid).
|
|
118
|
+
**Layout widgets** (class names, infer HTML structure):
|
|
119
|
+
|
|
120
|
+
| Widget | Purpose |
|
|
121
|
+
| ------------------------------------------------------------ | -------------------------------------------------------------- |
|
|
122
|
+
| `.v-metric-card` (`.v-metric-grid`) | Big number with emoji icon, label, trend |
|
|
123
|
+
| `.v-data-table` | Sortable table with sticky header, `th[data-sortable]` |
|
|
124
|
+
| `.v-tabs` / `.v-tab-bar` / `.v-tab-panel` | Tab navigation with keyboard support |
|
|
125
|
+
| `.v-accordion` / `.v-accordion-item` | Collapsible sections |
|
|
126
|
+
| `.v-search-bar` | Search input with clear button |
|
|
127
|
+
| `.v-empty-state` | No-data placeholder with CTA |
|
|
128
|
+
| `.v-timeline` / `.v-timeline-entry` | Vertical timeline (`.active`/`.success`/`.error`) |
|
|
129
|
+
| `.v-action-list` / `.v-action-list-item` | Rows with per-item actions |
|
|
130
|
+
| `.v-card-grid` | Responsive card grid |
|
|
131
|
+
| `.v-progress-bar` / `.v-progress-track` / `.v-progress-fill` | Horizontal progress |
|
|
132
|
+
| `.v-status-badge` | Colored pill with dot (`.success`/`.error`/`.warning`/`.info`) |
|
|
133
|
+
| `.v-stat-row` / `.v-stat` | Horizontal label-value pairs |
|
|
134
|
+
| `.v-toast` | Notification banner — prefer `vellum.widgets.toast()` |
|
|
135
|
+
| `.v-avatar-row` | Contact/team display |
|
|
136
|
+
| `.v-tag-group` | Wrapping tag row |
|
|
137
|
+
|
|
138
|
+
**Domain-specific widgets** (class names, infer HTML structure):
|
|
139
|
+
|
|
140
|
+
| Widget | Purpose |
|
|
141
|
+
| ------------------ | ---------------------- |
|
|
142
|
+
| `.v-weather-card` | Temperature + forecast |
|
|
143
|
+
| `.v-stock-ticker` | Price display + chart |
|
|
144
|
+
| `.v-flight-card` | Flight info with route |
|
|
145
|
+
| `.v-billing-chart` | Usage/billing display |
|
|
146
|
+
| `.v-boarding-pass` | Pass-styled layout |
|
|
147
|
+
| `.v-itinerary` | Day-by-day travel plan |
|
|
148
|
+
| `.v-receipt` | Receipt layout |
|
|
149
|
+
| `.v-invoice` | Formal invoice |
|
|
150
|
+
|
|
151
|
+
**Content & landing page components** (class names, infer HTML structure):
|
|
152
|
+
|
|
153
|
+
| Widget | Purpose |
|
|
154
|
+
| ------------------------------------------------ | --------------------------------------------------- |
|
|
155
|
+
| `.v-hero` / `.v-hero-badge` / `.v-hero-subtitle` | Hero banner with gradient, trust badge, accent word |
|
|
156
|
+
| `.v-section-header` / `.v-section-label` | Section intro with label |
|
|
157
|
+
| `.v-feature-grid` / `.v-feature-card` | Feature showcase with hover lift |
|
|
158
|
+
| `.v-pullquote` | Blockquote with gradient accent border |
|
|
159
|
+
| `.v-comparison` | Before/after cards (`.before`/`.after`) |
|
|
160
|
+
| `.v-page` | Centered container (max-width 600px) |
|
|
161
|
+
| `.v-gradient-text` | Accent-colored gradient text |
|
|
162
|
+
| `.v-animate-in` | Staggered fade-in for children |
|
|
163
|
+
|
|
164
|
+
**Slideshow** (`.v-slideshow`): Presentation slide deck with transitions. Init with `vellum.widgets.slideshow()`. Slide helpers: `.v-slide`, `.v-slide-label`, `.v-slide-title`, `.v-slide-body`, `.v-slide-stats`, `.v-slide-stat`, `.v-slide-quote`, `.v-slide-list`, `.v-slide-columns`.
|
|
715
165
|
|
|
716
166
|
#### Widget JavaScript utilities
|
|
717
167
|
|
|
718
168
|
Interactive utilities at `window.vellum.widgets.*`:
|
|
719
169
|
|
|
720
|
-
**SVG
|
|
170
|
+
**Charts** (always use these instead of hand-coding SVG/CSS charts):
|
|
171
|
+
|
|
721
172
|
```javascript
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
173
|
+
vellum.widgets.sparkline("container-id", [10, 25, 15, 30], {
|
|
174
|
+
width: 200,
|
|
175
|
+
height: 40,
|
|
176
|
+
color: "var(--v-success)",
|
|
177
|
+
strokeWidth: 2,
|
|
178
|
+
fill: true,
|
|
725
179
|
});
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
],
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
vellum.widgets.
|
|
741
|
-
|
|
180
|
+
vellum.widgets.barChart(
|
|
181
|
+
"container-id",
|
|
182
|
+
[
|
|
183
|
+
{ label: "Jan", value: 120 },
|
|
184
|
+
{ label: "Feb", value: 180, color: "var(--v-success)" },
|
|
185
|
+
],
|
|
186
|
+
{
|
|
187
|
+
width: 400,
|
|
188
|
+
height: 200,
|
|
189
|
+
showLabels: true,
|
|
190
|
+
showValues: true,
|
|
191
|
+
horizontal: false,
|
|
192
|
+
},
|
|
193
|
+
);
|
|
194
|
+
vellum.widgets.lineChart(
|
|
195
|
+
"container-id",
|
|
196
|
+
[
|
|
197
|
+
{ label: "Mon", value: 42 },
|
|
198
|
+
{ label: "Tue", value: 58 },
|
|
199
|
+
],
|
|
200
|
+
{ width: 400, height: 200, showDots: true, showGrid: true, gridLines: 4 },
|
|
201
|
+
);
|
|
202
|
+
vellum.widgets.progressRing("container-id", 75, {
|
|
203
|
+
size: 100,
|
|
204
|
+
strokeWidth: 8,
|
|
205
|
+
color: "var(--v-success)",
|
|
206
|
+
label: "75%",
|
|
742
207
|
});
|
|
743
208
|
```
|
|
744
209
|
|
|
745
210
|
**Data Formatting:**
|
|
211
|
+
|
|
746
212
|
```javascript
|
|
747
|
-
vellum.widgets.formatCurrency(1234.56,
|
|
748
|
-
vellum.widgets.formatDate(
|
|
749
|
-
vellum.widgets.formatDate(
|
|
213
|
+
vellum.widgets.formatCurrency(1234.56, "USD"); // "$1,234.56"
|
|
214
|
+
vellum.widgets.formatDate("2025-01-15", "relative"); // "3d ago"
|
|
215
|
+
vellum.widgets.formatDate("2025-01-15", "short"); // "1/15/25"
|
|
750
216
|
vellum.widgets.formatNumber(1234567, { compact: true }); // "1.2M"
|
|
751
|
-
vellum.widgets.formatNumber(0.156, { decimals: 1 }); // "0.2"
|
|
752
217
|
```
|
|
753
218
|
|
|
754
219
|
**Interactive Behaviors:**
|
|
755
|
-
```javascript
|
|
756
|
-
vellum.widgets.sortTable('table-id'); // Wire th[data-sortable] click-to-sort
|
|
757
|
-
vellum.widgets.sortTable('table-id', 0); // Sort by column 0 immediately
|
|
758
|
-
vellum.widgets.filterTable('table-id', 'search-input-id'); // Live text search
|
|
759
|
-
vellum.widgets.tabs('tabs-id'); // Tab switching + keyboard nav
|
|
760
|
-
vellum.widgets.accordion('accordion-id', { allowMultiple: true });
|
|
761
|
-
vellum.widgets.multiSelect('table-id'); // Checkboxes + select-all
|
|
762
|
-
vellum.widgets.toast('Saved!', 'success', 4000); // Auto-dismiss notification
|
|
763
|
-
vellum.widgets.toast('Connection lost', 'error', 0); // Manual dismiss
|
|
764
|
-
vellum.widgets.countdown('timer-el', '2025-12-31T00:00:00Z', {
|
|
765
|
-
onComplete: () => console.log('Done!')
|
|
766
|
-
});
|
|
767
|
-
|
|
768
|
-
// Slideshow — presentation deck with transitions and navigation
|
|
769
|
-
vellum.widgets.slideshow('deck', {
|
|
770
|
-
transition: 'fade', showDots: true, showArrows: true,
|
|
771
|
-
showCounter: true, keyboard: true, loop: true
|
|
772
|
-
});
|
|
773
|
-
// Returns: { goTo(index), next(), prev() }
|
|
774
|
-
```
|
|
775
|
-
|
|
776
|
-
#### Composition recipes
|
|
777
|
-
|
|
778
|
-
Combine widgets with wiring code to build complex UIs:
|
|
779
|
-
|
|
780
|
-
**Search-driven list with suggestion chips** — filter items with quick-tap categories:
|
|
781
|
-
```html
|
|
782
|
-
<div class="v-search-bar"><input id="search" placeholder="Search..."></div>
|
|
783
|
-
<div class="chip-group" style="margin-top: var(--v-spacing-sm);">
|
|
784
|
-
<button class="chip active" data-filter="all">🏠 All</button>
|
|
785
|
-
<button class="chip" data-filter="kitchen">🍳 Kitchen</button>
|
|
786
|
-
<button class="chip" data-filter="bedroom">🛏️ Bedroom</button>
|
|
787
|
-
<button class="chip" data-filter="bathroom">🚿 Bathroom</button>
|
|
788
|
-
</div>
|
|
789
|
-
<ul class="v-action-list" id="list"></ul>
|
|
790
|
-
<div class="v-empty-state" id="empty" hidden>
|
|
791
|
-
<div class="v-empty-icon">🔍</div>
|
|
792
|
-
<div class="v-empty-title">No results</div>
|
|
793
|
-
</div>
|
|
794
|
-
```
|
|
795
|
-
```javascript
|
|
796
|
-
let activeFilter = 'all';
|
|
797
|
-
document.getElementById('search').addEventListener('input', filterList);
|
|
798
|
-
document.querySelectorAll('.chip[data-filter]').forEach(chip => {
|
|
799
|
-
chip.addEventListener('click', () => {
|
|
800
|
-
document.querySelectorAll('.chip[data-filter]').forEach(c => c.classList.remove('active'));
|
|
801
|
-
chip.classList.add('active');
|
|
802
|
-
activeFilter = chip.dataset.filter;
|
|
803
|
-
filterList();
|
|
804
|
-
});
|
|
805
|
-
});
|
|
806
|
-
|
|
807
|
-
function filterList() {
|
|
808
|
-
const q = document.getElementById('search').value.toLowerCase();
|
|
809
|
-
let visible = 0;
|
|
810
|
-
document.querySelectorAll('#list .v-action-list-item').forEach(item => {
|
|
811
|
-
const textMatch = item.textContent.toLowerCase().includes(q);
|
|
812
|
-
const catMatch = activeFilter === 'all' || item.dataset.category === activeFilter;
|
|
813
|
-
item.hidden = !(textMatch && catMatch);
|
|
814
|
-
if (!item.hidden) visible++;
|
|
815
|
-
});
|
|
816
|
-
document.getElementById('empty').hidden = visible > 0;
|
|
817
|
-
}
|
|
818
|
-
```
|
|
819
220
|
|
|
820
|
-
**Form with inline validation:**
|
|
821
|
-
```html
|
|
822
|
-
<form id="create-form" novalidate>
|
|
823
|
-
<div class="v-input-row">
|
|
824
|
-
<label>Title *</label>
|
|
825
|
-
<input id="title" required placeholder="Enter title">
|
|
826
|
-
<span class="field-error" id="title-error"></span>
|
|
827
|
-
</div>
|
|
828
|
-
<div class="v-input-row">
|
|
829
|
-
<label>Priority</label>
|
|
830
|
-
<select id="priority">
|
|
831
|
-
<option value="low">Low</option>
|
|
832
|
-
<option value="medium" selected>Medium</option>
|
|
833
|
-
<option value="high">High</option>
|
|
834
|
-
</select>
|
|
835
|
-
</div>
|
|
836
|
-
<button type="submit" class="v-button" id="submit-btn">Create</button>
|
|
837
|
-
</form>
|
|
838
|
-
```
|
|
839
|
-
```css
|
|
840
|
-
.field-error { color: var(--v-danger); font-size: var(--v-font-size-xs); min-height: 1em; }
|
|
841
|
-
input:invalid:not(:placeholder-shown) { border-color: var(--v-danger); }
|
|
842
|
-
```
|
|
843
221
|
```javascript
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
try {
|
|
853
|
-
await window.vellum.data.create({
|
|
854
|
-
title,
|
|
855
|
-
priority: document.getElementById('priority').value
|
|
856
|
-
});
|
|
857
|
-
vellum.widgets.toast('Created!', 'success');
|
|
858
|
-
e.target.reset();
|
|
859
|
-
document.getElementById('title-error').textContent = '';
|
|
860
|
-
await loadRecords();
|
|
861
|
-
} catch (err) {
|
|
862
|
-
vellum.widgets.toast('Failed to create', 'error');
|
|
863
|
-
} finally {
|
|
864
|
-
document.getElementById('submit-btn').disabled = false;
|
|
865
|
-
}
|
|
222
|
+
vellum.widgets.sortTable("table-id"); // Wire th[data-sortable] click-to-sort
|
|
223
|
+
vellum.widgets.filterTable("table-id", "input-id"); // Live text search
|
|
224
|
+
vellum.widgets.tabs("tabs-id"); // Tab switching + keyboard nav
|
|
225
|
+
vellum.widgets.accordion("accordion-id", { allowMultiple: true });
|
|
226
|
+
vellum.widgets.multiSelect("table-id"); // Checkboxes + select-all
|
|
227
|
+
vellum.widgets.toast("Saved!", "success", 4000); // Auto-dismiss notification
|
|
228
|
+
vellum.widgets.countdown("timer-el", "2025-12-31T00:00:00Z", {
|
|
229
|
+
onComplete: () => {},
|
|
866
230
|
});
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
<h1 style="margin: var(--v-spacing-xs) 0;">Good morning, <span class="accent-word">Alex</span></h1>
|
|
875
|
-
<span class="trust-pill accent">🔥 7-day streak</span>
|
|
876
|
-
</div>
|
|
877
|
-
|
|
878
|
-
<!-- Pill toggles for time range -->
|
|
879
|
-
<div class="pill-toggles" style="margin-bottom: var(--v-spacing-xl);">
|
|
880
|
-
<button class="pill-toggle active">1W</button>
|
|
881
|
-
<button class="pill-toggle">1M</button>
|
|
882
|
-
<button class="pill-toggle">3M</button>
|
|
883
|
-
<button class="pill-toggle">1Y</button>
|
|
884
|
-
</div>
|
|
885
|
-
|
|
886
|
-
<!-- Emoji stat cards -->
|
|
887
|
-
<div class="emoji-stat-row" style="margin-bottom: var(--v-spacing-xxl);">
|
|
888
|
-
<div class="emoji-stat-card">
|
|
889
|
-
<span class="emoji-stat-icon">🔥</span>
|
|
890
|
-
<span class="emoji-stat-value" id="cal-value">1,284</span>
|
|
891
|
-
<span class="emoji-stat-label">Calories</span>
|
|
892
|
-
</div>
|
|
893
|
-
<div class="emoji-stat-card">
|
|
894
|
-
<span class="emoji-stat-icon">🏃</span>
|
|
895
|
-
<span class="emoji-stat-value" id="steps-value">8,421</span>
|
|
896
|
-
<span class="emoji-stat-label">Steps</span>
|
|
897
|
-
</div>
|
|
898
|
-
<div class="emoji-stat-card">
|
|
899
|
-
<span class="emoji-stat-icon">💧</span>
|
|
900
|
-
<span class="emoji-stat-value" id="hydration-value">2.4L</span>
|
|
901
|
-
<span class="emoji-stat-label">Hydration</span>
|
|
902
|
-
</div>
|
|
903
|
-
</div>
|
|
904
|
-
|
|
905
|
-
<!-- Chart + trend badge -->
|
|
906
|
-
<div class="v-card" style="margin-bottom: var(--v-spacing-xxl);">
|
|
907
|
-
<div style="display:flex; justify-content:space-between; align-items:center; margin-bottom: var(--v-spacing-md);">
|
|
908
|
-
<h3 style="margin:0;">Weekly Activity</h3>
|
|
909
|
-
<span class="trust-pill accent">📈 +12% vs last week</span>
|
|
910
|
-
</div>
|
|
911
|
-
<div id="chart" style="height:200px;"></div>
|
|
912
|
-
</div>
|
|
913
|
-
|
|
914
|
-
<!-- Atmospheric tagline -->
|
|
915
|
-
<p style="text-align:center; color: var(--v-text-muted); font-size: var(--v-font-size-sm); font-style:italic;">Powered by your consistency.</p>
|
|
916
|
-
```
|
|
917
|
-
```javascript
|
|
918
|
-
function esc(s) { const d = document.createElement('div'); d.textContent = String(s); return d.innerHTML; }
|
|
919
|
-
|
|
920
|
-
async function loadDashboard() {
|
|
921
|
-
const records = await window.vellum.data.query();
|
|
922
|
-
// Update stat values from real data
|
|
923
|
-
// Render chart
|
|
924
|
-
vellum.widgets.barChart('chart', records.map(r => ({
|
|
925
|
-
label: esc(r.data.name), value: r.data.amount
|
|
926
|
-
})));
|
|
927
|
-
}
|
|
928
|
-
// Wire pill toggles
|
|
929
|
-
document.querySelectorAll('.pill-toggles').forEach(group => {
|
|
930
|
-
group.addEventListener('click', (e) => {
|
|
931
|
-
if (!e.target.classList.contains('pill-toggle')) return;
|
|
932
|
-
group.querySelectorAll('.pill-toggle').forEach(b => b.classList.remove('active'));
|
|
933
|
-
e.target.classList.add('active');
|
|
934
|
-
// Re-fetch data for selected range
|
|
935
|
-
});
|
|
936
|
-
});
|
|
937
|
-
```
|
|
938
|
-
|
|
939
|
-
**Landing page** — nav bar + trust badge hero + accent word + category cards:
|
|
940
|
-
```html
|
|
941
|
-
<div class="v-page">
|
|
942
|
-
<!-- Navigation bar -->
|
|
943
|
-
<nav class="app-navbar reveal">
|
|
944
|
-
<div class="navbar-brand">✨ SparkClean</div>
|
|
945
|
-
<div class="navbar-links">
|
|
946
|
-
<a href="#" class="nav-link active">Home</a>
|
|
947
|
-
<a href="#" class="nav-link">Services</a>
|
|
948
|
-
<a href="#" class="nav-link">Pricing</a>
|
|
949
|
-
</div>
|
|
950
|
-
<button class="v-button navbar-cta">Book Now</button>
|
|
951
|
-
</nav>
|
|
952
|
-
|
|
953
|
-
<!-- Hero with trust badge + accent word -->
|
|
954
|
-
<div class="v-hero reveal">
|
|
955
|
-
<span class="v-hero-badge">🌟 Trusted by 12,000+ homes</span>
|
|
956
|
-
<h1>Your home, <span class="v-gradient-text">spotless.</span></h1>
|
|
957
|
-
<p class="v-hero-subtitle">Professional cleaning matched to your schedule. Book in 60 seconds.</p>
|
|
958
|
-
</div>
|
|
959
|
-
|
|
960
|
-
<!-- Category cards -->
|
|
961
|
-
<div class="reveal">
|
|
962
|
-
<h2 style="text-align:center; margin-bottom: var(--v-spacing-xl);">Our <span class="accent-word">Services</span></h2>
|
|
963
|
-
<div class="category-cards">
|
|
964
|
-
<div class="category-card">
|
|
965
|
-
<span class="category-icon">🧹</span>
|
|
966
|
-
<span class="category-name">Standard Clean</span>
|
|
967
|
-
<span class="category-meta">2-3 hrs · From $60</span>
|
|
968
|
-
</div>
|
|
969
|
-
<div class="category-card">
|
|
970
|
-
<span class="category-icon">✨</span>
|
|
971
|
-
<span class="category-name">Deep Clean</span>
|
|
972
|
-
<span class="category-meta">4-5 hrs · From $120</span>
|
|
973
|
-
</div>
|
|
974
|
-
<div class="category-card">
|
|
975
|
-
<span class="category-icon">📦</span>
|
|
976
|
-
<span class="category-name">Move-Out</span>
|
|
977
|
-
<span class="category-meta">5-7 hrs · From $180</span>
|
|
978
|
-
</div>
|
|
979
|
-
</div>
|
|
980
|
-
</div>
|
|
981
|
-
|
|
982
|
-
<!-- Feature grid -->
|
|
983
|
-
<div class="v-feature-grid">
|
|
984
|
-
<div class="v-feature-card reveal"><div class="v-feature-icon">⚡</div><div class="v-feature-title">Fast Booking</div><div class="v-feature-desc">Book in under 60 seconds.</div></div>
|
|
985
|
-
<div class="v-feature-card reveal"><div class="v-feature-icon">🛡️</div><div class="v-feature-title">Insured</div><div class="v-feature-desc">Fully bonded & insured teams.</div></div>
|
|
986
|
-
<div class="v-feature-card reveal"><div class="v-feature-icon">💚</div><div class="v-feature-title">Eco Products</div><div class="v-feature-desc">Safe for kids & pets.</div></div>
|
|
987
|
-
</div>
|
|
988
|
-
|
|
989
|
-
<!-- Atmospheric tagline -->
|
|
990
|
-
<p class="reveal" style="text-align:center; color: var(--v-text-muted); font-style:italic;">A cleaner home starts here.</p>
|
|
991
|
-
</div>
|
|
992
|
-
```
|
|
993
|
-
```javascript
|
|
994
|
-
const observer = new IntersectionObserver((entries) => {
|
|
995
|
-
entries.forEach((entry, i) => {
|
|
996
|
-
if (entry.isIntersecting) {
|
|
997
|
-
setTimeout(() => entry.target.classList.add('visible'), i * 120);
|
|
998
|
-
observer.unobserve(entry.target);
|
|
999
|
-
}
|
|
1000
|
-
});
|
|
1001
|
-
}, { threshold: 0.1 });
|
|
1002
|
-
document.querySelectorAll('.reveal').forEach(el => observer.observe(el));
|
|
1003
|
-
```
|
|
1004
|
-
|
|
1005
|
-
**Multi-select table** — checkboxes + bulk toolbar:
|
|
1006
|
-
```html
|
|
1007
|
-
<table class="v-data-table" id="my-table">
|
|
1008
|
-
<thead><tr>
|
|
1009
|
-
<th><input type="checkbox"></th>
|
|
1010
|
-
<th data-sortable>Name</th>
|
|
1011
|
-
<th data-sortable>Status</th>
|
|
1012
|
-
</tr></thead>
|
|
1013
|
-
<tbody>
|
|
1014
|
-
<tr data-id="1"><td><input type="checkbox"></td><td>Item 1</td><td>Active</td></tr>
|
|
1015
|
-
</tbody>
|
|
1016
|
-
</table>
|
|
1017
|
-
<div id="bulk-toolbar" hidden style="position:sticky;bottom:0;padding:12px;background:var(--v-surface);border-top:1px solid var(--v-surface-border);display:flex;gap:8px;">
|
|
1018
|
-
<button class="v-button danger" onclick="handleBulk('delete')">Delete Selected</button>
|
|
1019
|
-
<button class="v-button secondary" onclick="handleBulk('archive')">Archive</button>
|
|
1020
|
-
</div>
|
|
1021
|
-
```
|
|
1022
|
-
```javascript
|
|
1023
|
-
vellum.widgets.multiSelect('my-table');
|
|
1024
|
-
document.getElementById('my-table').addEventListener('change', () => {
|
|
1025
|
-
const any = document.querySelectorAll('#my-table tbody input:checked').length > 0;
|
|
1026
|
-
document.getElementById('bulk-toolbar').hidden = !any;
|
|
1027
|
-
});
|
|
1028
|
-
|
|
1029
|
-
async function handleBulk(action) {
|
|
1030
|
-
const ids = Array.from(document.querySelectorAll('#my-table tbody input:checked'))
|
|
1031
|
-
.map(cb => cb.closest('tr').dataset.id);
|
|
1032
|
-
if (action === 'delete') {
|
|
1033
|
-
const ok = await window.vellum.confirm('Delete items?', `Delete ${ids.length} selected items?`);
|
|
1034
|
-
if (!ok) return;
|
|
1035
|
-
for (const id of ids) await window.vellum.data.delete(id);
|
|
1036
|
-
vellum.widgets.toast(`Deleted ${ids.length} items`, 'success');
|
|
1037
|
-
}
|
|
1038
|
-
await loadRecords();
|
|
1039
|
-
}
|
|
1040
|
-
```
|
|
1041
|
-
|
|
1042
|
-
**Presentation slideshow** — multi-slide deck with 8 layout variants (title, stats, bullets, quote, comparison, visual, timeline, closing). Use the slideshow widget for presentations, pitch decks, and multi-slide educational content. The model provides slide content; the widget handles navigation, transitions, and keyboard support. Never tell the user how to navigate slides — the UI is self-explanatory.
|
|
1043
|
-
|
|
1044
|
-
> **For comprehensive slide design guidelines, see the "Presentation Slide Design" section below.** The following HTML shows the structural template for all 8 layout types.
|
|
1045
|
-
|
|
1046
|
-
```html
|
|
1047
|
-
<!DOCTYPE html>
|
|
1048
|
-
<html lang="en">
|
|
1049
|
-
<head>
|
|
1050
|
-
<meta charset="UTF-8">
|
|
1051
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
1052
|
-
<style>
|
|
1053
|
-
:root { --v-accent: #8B5CF6; }
|
|
1054
|
-
body { margin: 0; padding: 0; background: linear-gradient(-45deg, #0f172a, #1e1b4b, #172554); min-height: 100vh; }
|
|
1055
|
-
.v-slideshow { border-radius: 0; min-height: 100vh; }
|
|
1056
|
-
.accent-word { color: var(--v-accent); }
|
|
1057
|
-
.trust-pill { display: inline-flex; align-items: center; gap: 6px; padding: 6px 14px; border-radius: 8px; font-size: 13px; font-weight: 500; background: color-mix(in srgb, var(--v-surface) 60%, transparent); border: 1px solid var(--v-surface-border); color: var(--v-text-secondary); margin-top: var(--v-spacing-lg); }
|
|
1058
|
-
.trust-pill.accent { border-color: color-mix(in srgb, var(--v-accent) 30%, transparent); color: var(--v-accent); }
|
|
1059
|
-
.v-slide-list li { font-size: 15px; line-height: 1.7; }
|
|
1060
|
-
.v-slide-columns h3 { margin: 0 0 var(--v-spacing-sm); color: var(--v-text); font-size: var(--v-font-size-lg); }
|
|
1061
|
-
.slide-visual { position: relative; overflow: hidden; }
|
|
1062
|
-
.slide-visual-bg { position: absolute; inset: 0; background: radial-gradient(ellipse at 30% 40%, color-mix(in srgb, var(--v-accent) 15%, transparent), transparent 70%), radial-gradient(ellipse at 70% 60%, color-mix(in srgb, var(--v-forest-500, #22c55e) 10%, transparent), transparent 60%); }
|
|
1063
|
-
.slide-visual-overlay { position: relative; z-index: 1; background: color-mix(in srgb, var(--v-bg) 40%, transparent); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px); border-radius: var(--v-radius-lg); padding: var(--v-spacing-xl); max-width: 500px; }
|
|
1064
|
-
</style>
|
|
1065
|
-
</head>
|
|
1066
|
-
<body>
|
|
1067
|
-
<div class="v-slideshow" id="deck">
|
|
1068
|
-
|
|
1069
|
-
<!-- 1. Title slide -->
|
|
1070
|
-
<div class="v-slide">
|
|
1071
|
-
<span class="v-slide-label">Introduction</span>
|
|
1072
|
-
<h1 class="v-slide-title">The city that never <span class="accent-word">sleeps</span></h1>
|
|
1073
|
-
<p class="v-slide-body">A brief subtitle or tagline here.</p>
|
|
1074
|
-
<span class="trust-pill accent">🗽 8.3 million residents</span>
|
|
1075
|
-
</div>
|
|
1076
|
-
|
|
1077
|
-
<!-- 2. Content + Stats slide -->
|
|
1078
|
-
<div class="v-slide">
|
|
1079
|
-
<span class="v-slide-label">By the Numbers</span>
|
|
1080
|
-
<h2 class="v-slide-title">Economy at a glance</h2>
|
|
1081
|
-
<p class="v-slide-body">New York generates more GDP than most countries...</p>
|
|
1082
|
-
<div class="v-slide-stats">
|
|
1083
|
-
<div class="v-slide-stat"><span class="v-slide-stat-value">$2.1T</span><span class="v-slide-stat-label">Metro GDP</span></div>
|
|
1084
|
-
<div class="v-slide-stat"><span class="v-slide-stat-value">4.7M</span><span class="v-slide-stat-label">Jobs</span></div>
|
|
1085
|
-
<div class="v-slide-stat"><span class="v-slide-stat-value">#1</span><span class="v-slide-stat-label">Financial Hub</span></div>
|
|
1086
|
-
</div>
|
|
1087
|
-
</div>
|
|
1088
|
-
|
|
1089
|
-
<!-- 3. Bullet points slide -->
|
|
1090
|
-
<div class="v-slide">
|
|
1091
|
-
<span class="v-slide-label">Culture</span>
|
|
1092
|
-
<h2 class="v-slide-title">What makes it <span class="accent-word">unique</span></h2>
|
|
1093
|
-
<ul class="v-slide-list">
|
|
1094
|
-
<li>🎭 Broadway — 41 professional theaters in the Theater District</li>
|
|
1095
|
-
<li>🏛️ 80+ world-class museums including the Met and MoMA</li>
|
|
1096
|
-
<li>🍕 Over 27,000 restaurants spanning every cuisine on earth</li>
|
|
1097
|
-
<li>🌳 843 acres of Central Park in the heart of Manhattan</li>
|
|
1098
|
-
</ul>
|
|
1099
|
-
</div>
|
|
1100
|
-
|
|
1101
|
-
<!-- 4. Quote slide -->
|
|
1102
|
-
<div class="v-slide" style="justify-content: center; align-items: center; text-align: center;">
|
|
1103
|
-
<div class="v-slide-quote" style="border-left: none; padding-left: 0;">
|
|
1104
|
-
"There is no place like New York. It is the most exciting city in the world."
|
|
1105
|
-
</div>
|
|
1106
|
-
<div class="v-slide-quote-attribution">— John Updike</div>
|
|
1107
|
-
</div>
|
|
1108
|
-
|
|
1109
|
-
<!-- 5. Comparison / Two-column slide -->
|
|
1110
|
-
<div class="v-slide">
|
|
1111
|
-
<span class="v-slide-label">Comparison</span>
|
|
1112
|
-
<h2 class="v-slide-title">Manhattan vs Brooklyn</h2>
|
|
1113
|
-
<div class="v-slide-columns">
|
|
1114
|
-
<div class="v-slide-column">
|
|
1115
|
-
<h3>🏙️ Manhattan</h3>
|
|
1116
|
-
<p class="v-slide-body" style="margin-bottom: var(--v-spacing-sm);">Financial center, dense skyscrapers, high-energy nightlife, world-famous landmarks.</p>
|
|
1117
|
-
<span class="v-slide-stat-value">1.6M</span>
|
|
1118
|
-
<span class="v-slide-stat-label">Population</span>
|
|
1119
|
-
</div>
|
|
1120
|
-
<div class="v-slide-column">
|
|
1121
|
-
<h3>🌉 Brooklyn</h3>
|
|
1122
|
-
<p class="v-slide-body" style="margin-bottom: var(--v-spacing-sm);">Creative hub, brownstone neighborhoods, artisan food scene, waterfront parks.</p>
|
|
1123
|
-
<span class="v-slide-stat-value">2.7M</span>
|
|
1124
|
-
<span class="v-slide-stat-label">Population</span>
|
|
1125
|
-
</div>
|
|
1126
|
-
</div>
|
|
1127
|
-
</div>
|
|
1128
|
-
|
|
1129
|
-
<!-- 6. Image/visual slide -->
|
|
1130
|
-
<div class="v-slide slide-visual">
|
|
1131
|
-
<div class="slide-visual-bg"></div>
|
|
1132
|
-
<div class="slide-visual-overlay">
|
|
1133
|
-
<span class="v-slide-label">Skyline</span>
|
|
1134
|
-
<h2 class="v-slide-title">An iconic <span class="accent-word">horizon</span></h2>
|
|
1135
|
-
<p class="v-slide-body">The Manhattan skyline is recognized worldwide...</p>
|
|
1136
|
-
</div>
|
|
1137
|
-
</div>
|
|
1138
|
-
|
|
1139
|
-
<!-- 7. Timeline slide -->
|
|
1140
|
-
<div class="v-slide">
|
|
1141
|
-
<span class="v-slide-label">History</span>
|
|
1142
|
-
<h2 class="v-slide-title">Key <span class="accent-word">milestones</span></h2>
|
|
1143
|
-
<div class="v-timeline" style="margin-top: var(--v-spacing-lg);">
|
|
1144
|
-
<div class="v-timeline-entry"><span class="v-timeline-time">1626</span><span class="v-timeline-title">Manhattan purchased</span></div>
|
|
1145
|
-
<div class="v-timeline-entry"><span class="v-timeline-time">1886</span><span class="v-timeline-title">Statue of Liberty dedicated</span></div>
|
|
1146
|
-
<div class="v-timeline-entry active"><span class="v-timeline-time">1931</span><span class="v-timeline-title">Empire State Building opens</span></div>
|
|
1147
|
-
</div>
|
|
1148
|
-
</div>
|
|
1149
|
-
|
|
1150
|
-
<!-- 8. Closing / CTA slide -->
|
|
1151
|
-
<div class="v-slide" style="text-align: center; align-items: center;">
|
|
1152
|
-
<h1 class="v-slide-title">The world's <span class="accent-word">capital</span></h1>
|
|
1153
|
-
<p class="v-slide-body" style="max-width: 400px;">New York isn't just a city — it's an idea that never stops evolving.</p>
|
|
1154
|
-
<div class="v-slide-stats" style="margin-top: var(--v-spacing-xxl);">
|
|
1155
|
-
<div class="v-slide-stat"><span class="v-slide-stat-value">800+</span><span class="v-slide-stat-label">Languages spoken</span></div>
|
|
1156
|
-
<div class="v-slide-stat"><span class="v-slide-stat-value">62M</span><span class="v-slide-stat-label">Annual visitors</span></div>
|
|
1157
|
-
</div>
|
|
1158
|
-
</div>
|
|
1159
|
-
|
|
1160
|
-
</div>
|
|
1161
|
-
<script>
|
|
1162
|
-
document.addEventListener('DOMContentLoaded', function() {
|
|
1163
|
-
vellum.widgets.slideshow('deck', {
|
|
1164
|
-
transition: 'fade',
|
|
1165
|
-
showDots: true,
|
|
1166
|
-
showArrows: true,
|
|
1167
|
-
showCounter: true,
|
|
1168
|
-
keyboard: true,
|
|
1169
|
-
loop: true
|
|
1170
|
-
});
|
|
231
|
+
vellum.widgets.slideshow("deck", {
|
|
232
|
+
transition: "fade",
|
|
233
|
+
showDots: true,
|
|
234
|
+
showArrows: true,
|
|
235
|
+
showCounter: true,
|
|
236
|
+
keyboard: true,
|
|
237
|
+
loop: true,
|
|
1171
238
|
});
|
|
1172
|
-
</script>
|
|
1173
|
-
</body>
|
|
1174
|
-
</html>
|
|
1175
239
|
```
|
|
1176
240
|
|
|
1177
241
|
#### When to use widgets vs custom HTML
|
|
@@ -1179,25 +243,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
1179
243
|
- **Use widgets** for standard patterns — tables, metrics, timelines, notifications, presentations
|
|
1180
244
|
- **Use custom HTML** for novel or creative UIs — games, art tools, unique dashboards
|
|
1181
245
|
- **Mix freely** — widgets compose well together and with custom elements
|
|
1182
|
-
-
|
|
1183
|
-
|
|
1184
|
-
#### Advanced techniques
|
|
1185
|
-
|
|
1186
|
-
Use modern web APIs to build genuinely impressive apps:
|
|
1187
|
-
|
|
1188
|
-
- **Canvas 2D / WebGL** — charts, visualization, drawing, games, generative art
|
|
1189
|
-
- **SVG** — icons, diagrams, interactive graphics
|
|
1190
|
-
- **CSS animations & keyframes** — loading states, micro-interactions, page transitions
|
|
1191
|
-
- **CSS transforms** — drag-and-drop, card flips, 3D effects
|
|
1192
|
-
- **CSS gradients & filters** — blur effects, color overlays, rich backgrounds
|
|
1193
|
-
- **CSS Grid subgrid** — complex dashboard layouts
|
|
1194
|
-
- **Web Audio API** — sound effects, metronomes, music tools
|
|
1195
|
-
- **requestAnimationFrame** — smooth animations, interactive canvases
|
|
1196
|
-
- **Drag and drop** (HTML5) — reorderable lists, kanban boards
|
|
1197
|
-
- **IntersectionObserver** — scroll-triggered animations, lazy rendering
|
|
1198
|
-
- **ResizeObserver** — responsive canvas/chart sizing
|
|
1199
|
-
|
|
1200
|
-
Don't reach for these when a simple list will do, but don't avoid them when they'd make the app genuinely better.
|
|
246
|
+
- **ALWAYS use `vellum.widgets.*` chart functions** instead of hand-coding SVG/CSS charts. They handle overflow clipping, bounds, scaling, and dark mode. Hand-coded charts break layouts.
|
|
1201
247
|
|
|
1202
248
|
#### Data bridge API
|
|
1203
249
|
|
|
@@ -1209,6 +255,7 @@ The HTML interface can read and write records via `window.vellum.data`. All meth
|
|
|
1209
255
|
- `window.vellum.data.delete(recordId)` — Deletes a record by ID. Returns void.
|
|
1210
256
|
|
|
1211
257
|
Important:
|
|
258
|
+
|
|
1212
259
|
- Call `query()` on page load to populate initial state
|
|
1213
260
|
- User fields live in `record.data` (e.g., `record.data.title`)
|
|
1214
261
|
- Record IDs are UUID strings
|
|
@@ -1222,8 +269,9 @@ Important:
|
|
|
1222
269
|
#### JavaScript patterns
|
|
1223
270
|
|
|
1224
271
|
Initialize apps with clean state management:
|
|
272
|
+
|
|
1225
273
|
```javascript
|
|
1226
|
-
document.addEventListener(
|
|
274
|
+
document.addEventListener("DOMContentLoaded", async () => {
|
|
1227
275
|
await loadRecords();
|
|
1228
276
|
});
|
|
1229
277
|
|
|
@@ -1234,473 +282,118 @@ async function loadRecords() {
|
|
|
1234
282
|
allRecords = await window.vellum.data.query();
|
|
1235
283
|
render();
|
|
1236
284
|
} catch (err) {
|
|
1237
|
-
console.error(
|
|
285
|
+
console.error("Failed to load:", err);
|
|
1238
286
|
}
|
|
1239
287
|
}
|
|
1240
288
|
|
|
1241
289
|
function render() {
|
|
1242
290
|
// Re-render UI from allRecords
|
|
1243
|
-
// Apply client-side filtering/sorting
|
|
1244
291
|
}
|
|
1245
292
|
```
|
|
1246
293
|
|
|
1247
|
-
|
|
1248
|
-
```javascript
|
|
1249
|
-
const state = {
|
|
1250
|
-
records: [],
|
|
1251
|
-
filter: localStorage.getItem('filter') || 'all',
|
|
1252
|
-
sortBy: localStorage.getItem('sortBy') || 'createdAt',
|
|
1253
|
-
searchQuery: '',
|
|
1254
|
-
editingId: null,
|
|
1255
|
-
};
|
|
1256
|
-
|
|
1257
|
-
function setState(updates) {
|
|
1258
|
-
Object.assign(state, updates);
|
|
1259
|
-
render();
|
|
1260
|
-
}
|
|
1261
|
-
```
|
|
294
|
+
**HTML escaping:** Always escape user-controlled data before inserting into the DOM via `innerHTML`:
|
|
1262
295
|
|
|
1263
|
-
**Loading state pattern:**
|
|
1264
296
|
```javascript
|
|
1265
|
-
|
|
1266
|
-
document.
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
<div class="skeleton skeleton-text" style="width:60%"></div>`;
|
|
1270
|
-
const records = await window.vellum.data.query();
|
|
1271
|
-
setState({ records });
|
|
297
|
+
function esc(s) {
|
|
298
|
+
const d = document.createElement("div");
|
|
299
|
+
d.textContent = String(s);
|
|
300
|
+
return d.innerHTML;
|
|
1272
301
|
}
|
|
1273
302
|
```
|
|
1274
303
|
|
|
1275
|
-
**HTML escaping:** Always escape user-controlled data before inserting it into the DOM via `innerHTML`. Use this utility:
|
|
1276
|
-
```javascript
|
|
1277
|
-
function esc(s) { const d = document.createElement('div'); d.textContent = String(s); return d.innerHTML; }
|
|
1278
|
-
```
|
|
1279
|
-
Then wrap every user data interpolation: `` `<td>${esc(record.data.name)}</td>` ``. Alternatively, use `textContent` or DOM APIs to set text without innerHTML. Failing to escape leads to XSS vulnerabilities.
|
|
1280
|
-
|
|
1281
304
|
### 4. Single-Page App Views
|
|
1282
305
|
|
|
1283
|
-
Apps run inside a sandboxed WebView that blocks all navigation
|
|
1284
|
-
|
|
1285
|
-
#### View switching pattern
|
|
1286
|
-
|
|
1287
|
-
Use a simple `showView()` function to toggle between sections:
|
|
1288
|
-
```html
|
|
1289
|
-
<nav class="app-nav">
|
|
1290
|
-
<button class="nav-link active" onclick="showView('home')">Home</button>
|
|
1291
|
-
<button class="nav-link" onclick="showView('settings')">Settings</button>
|
|
1292
|
-
</nav>
|
|
1293
|
-
|
|
1294
|
-
<div id="view-home" class="view">
|
|
1295
|
-
<!-- Home content -->
|
|
1296
|
-
</div>
|
|
1297
|
-
<div id="view-settings" class="view" hidden>
|
|
1298
|
-
<!-- Settings content -->
|
|
1299
|
-
</div>
|
|
1300
|
-
|
|
1301
|
-
<style>
|
|
1302
|
-
.app-nav { display: flex; gap: 4px; padding: 8px 12px; background: var(--v-surface); border-bottom: 1px solid var(--v-surface-border); }
|
|
1303
|
-
.nav-link { padding: 6px 14px; border-radius: 6px; border: none; background: none; color: var(--v-text-secondary); font-size: 13px; font-weight: 500; cursor: pointer; transition: all 150ms; }
|
|
1304
|
-
.nav-link:hover { background: var(--v-surface-border); color: var(--v-text); }
|
|
1305
|
-
.nav-link.active { background: var(--v-accent); color: white; }
|
|
1306
|
-
</style>
|
|
1307
|
-
```
|
|
306
|
+
Apps run inside a sandboxed WebView that blocks all navigation. All apps are effectively single-page. When an app needs multiple views, use JavaScript to swap content:
|
|
307
|
+
|
|
1308
308
|
```javascript
|
|
1309
309
|
function showView(name) {
|
|
1310
|
-
document.querySelectorAll(
|
|
1311
|
-
document.getElementById(
|
|
1312
|
-
document
|
|
1313
|
-
|
|
310
|
+
document.querySelectorAll(".view").forEach((v) => (v.hidden = true));
|
|
311
|
+
document.getElementById("view-" + name).hidden = false;
|
|
312
|
+
document
|
|
313
|
+
.querySelectorAll(".nav-link")
|
|
314
|
+
.forEach((btn) => btn.classList.remove("active"));
|
|
315
|
+
document
|
|
316
|
+
.querySelector(`[onclick="showView('${name}')"]`)
|
|
317
|
+
?.classList.add("active");
|
|
1314
318
|
}
|
|
1315
319
|
```
|
|
1316
320
|
|
|
1317
|
-
For detail pages, call `showView('detail')` and populate the detail section's content dynamically before showing it. Use a "Back" button that calls `showView('home')` to return to the list.
|
|
1318
|
-
|
|
1319
321
|
### 5. Create and Open the App
|
|
1320
322
|
|
|
1321
323
|
Call `app_create` with:
|
|
324
|
+
|
|
1322
325
|
- `name`: Short descriptive name
|
|
1323
326
|
- `description`: One-sentence summary
|
|
1324
327
|
- `schema_json`: JSON schema as string
|
|
1325
|
-
- `html`: Complete HTML document as string
|
|
1326
|
-
- `auto_open`: (optional, defaults to `true`) Shows an inline preview card in chat
|
|
1327
|
-
- `preview`: Always include
|
|
1328
|
-
|
|
1329
|
-
Since `auto_open` defaults to `true`, an inline preview card is shown in chat after creation. The app is NOT opened in a workspace panel automatically — users open it explicitly if desired by clicking 'Open App' on the inline card. The app appears in Things (sidebar) immediately after creation via the `app_files_changed` broadcast.
|
|
1330
|
-
|
|
1331
|
-
#### Preview metadata
|
|
1332
|
-
|
|
1333
|
-
Always include preview metadata in `app_create` calls. The app shows as an inline card in chat first — no workspace opens automatically. Users can click 'Open App' on the inline card to open the workspace.
|
|
1334
|
-
|
|
1335
|
-
Both `ui_show` and `app_create` support a `preview` object for an inline chat preview card. Always include it so the user sees a compact summary of what was built.
|
|
1336
|
-
|
|
1337
|
-
**With `ui_show`:**
|
|
1338
|
-
```json
|
|
1339
|
-
{
|
|
1340
|
-
"surface_type": "dynamic_page",
|
|
1341
|
-
"data": {
|
|
1342
|
-
"html": "...",
|
|
1343
|
-
"preview": {
|
|
1344
|
-
"title": "Expense Tracker",
|
|
1345
|
-
"subtitle": "Personal Finance",
|
|
1346
|
-
"description": "Track daily expenses with category breakdowns.",
|
|
1347
|
-
"icon": "💰",
|
|
1348
|
-
"metrics": [
|
|
1349
|
-
{ "label": "Records", "value": "24" },
|
|
1350
|
-
{ "label": "Categories", "value": "8" }
|
|
1351
|
-
]
|
|
1352
|
-
}
|
|
1353
|
-
}
|
|
1354
|
-
}
|
|
1355
|
-
```
|
|
1356
|
-
|
|
1357
|
-
**With `app_create` (image URL icon):**
|
|
1358
|
-
```json
|
|
1359
|
-
{
|
|
1360
|
-
"name": "Microsoft Overview",
|
|
1361
|
-
"schema_json": "{}",
|
|
1362
|
-
"html": "...",
|
|
1363
|
-
"preview": {
|
|
1364
|
-
"title": "Microsoft",
|
|
1365
|
-
"subtitle": "3 Slides",
|
|
1366
|
-
"icon": "https://www.microsoft.com/favicon.ico",
|
|
1367
|
-
"metrics": [
|
|
1368
|
-
{ "label": "Founded", "value": "1975" },
|
|
1369
|
-
{ "label": "Market Cap", "value": "$2.98T" }
|
|
1370
|
-
]
|
|
1371
|
-
}
|
|
1372
|
-
}
|
|
1373
|
-
```
|
|
328
|
+
- `html`: (optional) Complete HTML document as string for `index.html`. If omitted, a minimal scaffold is created — you can then write `index.html` and other files via `app_file_write`.
|
|
329
|
+
- `auto_open`: (optional, defaults to `true`) Shows an inline preview card in chat
|
|
330
|
+
- `preview`: Always include — `title` (required), `subtitle`, `description`, `icon` (image URL preferred, emoji fallback), `metrics` (up to 3 key-value pills)
|
|
1374
331
|
|
|
1375
|
-
|
|
1376
|
-
```json
|
|
1377
|
-
{
|
|
1378
|
-
"name": "Expense Tracker",
|
|
1379
|
-
"schema_json": "{}",
|
|
1380
|
-
"html": "...",
|
|
1381
|
-
"preview": {
|
|
1382
|
-
"title": "Expense Tracker",
|
|
1383
|
-
"icon": "💰",
|
|
1384
|
-
"metrics": [
|
|
1385
|
-
{ "label": "Records", "value": "24" },
|
|
1386
|
-
{ "label": "Categories", "value": "8" }
|
|
1387
|
-
]
|
|
1388
|
-
}
|
|
1389
|
-
}
|
|
1390
|
-
```
|
|
1391
|
-
|
|
1392
|
-
Preview fields: `title` (required), `subtitle`, `description`, `icon`, `metrics` (up to 3 key-value pills). The `icon` field accepts an emoji or an image URL. **Prefer an image URL whenever you have a relevant one** — logos, favicons, product images, headshots, flags, album art, or any image you encountered during research. The preview card renders image URLs as a thumbnail automatically. Fall back to emoji only when there is no natural image. When `app_create` is called with `auto_open: true` (the default), the inline preview card is shown in chat — the app is NOT automatically opened in a workspace panel.
|
|
332
|
+
The app is NOT opened in a workspace panel automatically — users open it via the 'Open App' button on the inline card.
|
|
1393
333
|
|
|
1394
334
|
### 6. Handle Iteration
|
|
1395
335
|
|
|
1396
|
-
When the user requests changes
|
|
1397
|
-
|
|
1398
|
-
#### Editing code
|
|
1399
|
-
|
|
1400
|
-
- **`app_file_edit`** — preferred for modifying existing code. Provide `app_id`, `path` (e.g. `index.html`, `styles.css`), `old_string` (exact text to find), and `new_string` (replacement). Use this for targeted changes like updating styles, fixing bugs, or adding features.
|
|
1401
|
-
- **`app_file_write`** — use when creating a new file or when changes are so extensive that a full rewrite is cleaner. Provide `app_id`, `path`, and `content`.
|
|
1402
|
-
- Always include a **`status`** parameter when calling `app_file_edit` or `app_file_write` — a brief human-readable message describing what you are doing (e.g. "adding dark mode styles", "updating navigation layout", "fixing chart rendering bug"). This gives the user visible progress feedback.
|
|
1403
|
-
|
|
1404
|
-
#### Metadata vs code changes
|
|
1405
|
-
|
|
1406
|
-
- **`app_update`** — use for metadata changes only: `name`, `description`, and `schema_json`. Do not use it for code changes.
|
|
1407
|
-
- **`app_file_edit`** / **`app_file_write`** — use for all code changes (HTML, CSS, JS). The surface refreshes automatically after file edits.
|
|
1408
|
-
- If schema changes affect existing records, mention this.
|
|
1409
|
-
|
|
1410
|
-
#### Multi-file apps
|
|
1411
|
-
|
|
1412
|
-
Apps can have multiple files beyond `index.html`. Use separate files for CSS and JavaScript to keep code organized:
|
|
1413
|
-
|
|
1414
|
-
- Create additional files with `app_file_write` (e.g. `styles.css`, `app.js`, `components/chart.js`).
|
|
1415
|
-
- Link them from `index.html` using `<link rel="stylesheet" href="styles.css">` and `<script src="app.js"></script>`.
|
|
1416
|
-
- Use `app_file_list` to see all files in an app.
|
|
1417
|
-
- Use `app_file_read` to read any file with line numbers (helpful before making edits).
|
|
1418
|
-
|
|
1419
|
-
Use `app_delete` to start over. Use `app_list` to check existing apps. Use `app_query` to inspect app data.
|
|
1420
|
-
|
|
1421
|
-
## Interactive Quality Standard
|
|
1422
|
-
|
|
1423
|
-
Every app must meet these interaction baselines — they're the difference between "works" and "feels professional."
|
|
1424
|
-
|
|
1425
|
-
### Feedback for Every Action
|
|
1426
|
-
|
|
1427
|
-
Every user action must produce visible feedback:
|
|
1428
|
-
```javascript
|
|
1429
|
-
// After creating a record
|
|
1430
|
-
vellum.widgets.toast('Task created', 'success');
|
|
1431
|
-
|
|
1432
|
-
// After deleting
|
|
1433
|
-
vellum.widgets.toast('Deleted', 'success');
|
|
1434
|
-
|
|
1435
|
-
// After updating
|
|
1436
|
-
vellum.widgets.toast('Changes saved', 'success');
|
|
1437
|
-
|
|
1438
|
-
// On error
|
|
1439
|
-
vellum.widgets.toast('Something went wrong', 'error');
|
|
1440
|
-
```
|
|
1441
|
-
|
|
1442
|
-
### Confirmation for Destructive Actions
|
|
336
|
+
When the user requests changes, prefer **`app_file_edit`** over rewriting the entire file.
|
|
1443
337
|
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
'Delete this item?',
|
|
1449
|
-
'This action cannot be undone.'
|
|
1450
|
-
);
|
|
1451
|
-
if (!confirmed) return;
|
|
1452
|
-
await window.vellum.data.delete(id);
|
|
1453
|
-
vellum.widgets.toast('Deleted', 'success');
|
|
1454
|
-
await loadRecords();
|
|
1455
|
-
}
|
|
1456
|
-
```
|
|
1457
|
-
`window.vellum.confirm(title, message)` returns a `Promise<boolean>` — `true` if the user clicks OK, `false` for Cancel. It shows a native macOS dialog.
|
|
1458
|
-
|
|
1459
|
-
### Form Validation
|
|
1460
|
-
|
|
1461
|
-
Validate before submit, show errors inline:
|
|
1462
|
-
```css
|
|
1463
|
-
.field-error {
|
|
1464
|
-
color: var(--v-danger);
|
|
1465
|
-
font-size: var(--v-font-size-xs);
|
|
1466
|
-
margin-top: 2px;
|
|
1467
|
-
min-height: 1em;
|
|
1468
|
-
}
|
|
1469
|
-
input.invalid, select.invalid {
|
|
1470
|
-
border-color: var(--v-danger);
|
|
1471
|
-
box-shadow: 0 0 0 2px color-mix(in srgb, var(--v-danger) 15%, transparent);
|
|
1472
|
-
}
|
|
1473
|
-
```
|
|
1474
|
-
- Disable submit button while a required field is empty
|
|
1475
|
-
- Clear error messages on input focus
|
|
1476
|
-
- Show loading state on submit button during async operations
|
|
1477
|
-
|
|
1478
|
-
### Loading States
|
|
1479
|
-
|
|
1480
|
-
Never show a blank screen while data loads:
|
|
1481
|
-
```javascript
|
|
1482
|
-
function showLoading() {
|
|
1483
|
-
container.innerHTML = `
|
|
1484
|
-
<div class="skeleton skeleton-heading"></div>
|
|
1485
|
-
<div class="skeleton skeleton-text"></div>
|
|
1486
|
-
<div class="skeleton skeleton-text" style="width:70%"></div>`;
|
|
1487
|
-
}
|
|
1488
|
-
```
|
|
1489
|
-
- Disable buttons during async operations to prevent double-submit
|
|
1490
|
-
- Use the skeleton shimmer CSS from the Visual Techniques section
|
|
1491
|
-
|
|
1492
|
-
### Keyboard Navigation
|
|
338
|
+
- **`app_file_edit`** — preferred for targeted changes (styles, bugs, features). Provide `app_id`, `path`, `old_string`, `new_string`.
|
|
339
|
+
- **`app_file_write`** — use when creating new files or when changes are so extensive a full rewrite is cleaner.
|
|
340
|
+
- **`app_update`** — metadata only: `name`, `description`, `schema_json`. Not for code changes.
|
|
341
|
+
- Always include a **`status`** parameter describing what you're doing.
|
|
1493
342
|
|
|
1494
|
-
|
|
1495
|
-
- `Enter` submits forms, activates buttons
|
|
1496
|
-
- `Escape` closes modals, cancels edits, clears search
|
|
1497
|
-
- Use `tabindex` only when natural DOM order is insufficient
|
|
343
|
+
Apps can have multiple files (`styles.css`, `app.js`, etc.). Link from `index.html` with standard tags.
|
|
1498
344
|
|
|
1499
|
-
##
|
|
345
|
+
## Interaction Standards
|
|
1500
346
|
|
|
1501
|
-
|
|
347
|
+
Every app must meet these baselines:
|
|
1502
348
|
|
|
1503
|
-
- **
|
|
1504
|
-
- **
|
|
1505
|
-
- **
|
|
1506
|
-
- **
|
|
1507
|
-
- **
|
|
349
|
+
- **Feedback for every action:** Use `vellum.widgets.toast()` after creates, deletes, updates, and errors.
|
|
350
|
+
- **Confirmation for destructive actions:** Use `window.vellum.confirm(title, message)` before deleting or resetting. Returns `Promise<boolean>`.
|
|
351
|
+
- **Form validation:** Validate before submit, show errors inline, disable submit during async operations.
|
|
352
|
+
- **Loading states:** Never show a blank screen while data loads. Use skeleton shimmer or spinners.
|
|
353
|
+
- **Keyboard navigation:** `Tab` between elements, `Enter` to submit, `Escape` to close/cancel.
|
|
1508
354
|
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
Before delivering any app, mentally verify these 10 items — they cover the gap between "functional" and "designer-quality":
|
|
1512
|
-
|
|
1513
|
-
1. **Domain-matched palette** — Is the accent color appropriate for this domain? (Not default violet)
|
|
1514
|
-
2. **Tinted background** — Does the body have a warm/cool tint instead of pure white/dark?
|
|
1515
|
-
3. **Emoji stat cards** — Are there emoji icons in metric cards, list items, or navigation?
|
|
1516
|
-
4. **Accent word in heading** — Is ONE key word in the hero heading colored or gradient-filled?
|
|
1517
|
-
5. **Contextual header** — Is there a greeting, date, or personalized welcome (not just an app title)?
|
|
1518
|
-
6. **Trust/status pill badge** — Is there at least one pill badge with a stat, streak, or social proof?
|
|
1519
|
-
7. **Generous spacing** — Are section gaps 32-48px? Does the layout feel spacious, not cramped?
|
|
1520
|
-
8. **Clean card borders** — Do cards use subtle 1px borders instead of heavy multi-layer shadows?
|
|
1521
|
-
9. **Interactive elements** — Are there pill toggles, suggestion chips, or filter controls?
|
|
1522
|
-
10. **Atmospheric tagline** — Is there a warm, human-sounding line at the bottom or between sections?
|
|
355
|
+
## Presentation Slide Design
|
|
1523
356
|
|
|
1524
|
-
|
|
357
|
+
Slides are a different domain from apps. Skip app-specific patterns (contextual headers, search/filter, toast notifications, form validation, data bridge). Slides are static content.
|
|
1525
358
|
|
|
1526
|
-
|
|
1527
|
-
|---|---|---|
|
|
1528
|
-
| `.v-pill-toggles` | Time range / filter toggle group | `.v-pill-toggle` (`.active`) — container with pill buttons |
|
|
1529
|
-
| `.v-chip-group` | Suggestion / filter chip row | `.v-chip` (`.active`) — wrapping row of clickable pills |
|
|
1530
|
-
| `.v-metric-card .v-metric-icon` | Emoji icon in metric cards | Place emoji `<span>` with `.v-metric-icon` inside `.v-metric-card` |
|
|
1531
|
-
| `.v-slideshow` | Presentation slide deck with transitions | `.v-slide` (`.active`), `.v-slide-label`, `.v-slide-title`, `.v-slide-body`, `.v-slide-stats`, `.v-slide-stat`, `.v-slide-quote` — init with `vellum.widgets.slideshow()` |
|
|
359
|
+
**Key principles:**
|
|
1532
360
|
|
|
1533
|
-
|
|
361
|
+
- One idea per slide — understood in 3 seconds
|
|
362
|
+
- Layout variety — 3+ different types per deck, never consecutive same-type
|
|
363
|
+
- 8 layout types: Title, Stats, Bullets, Quote, Comparison, Timeline, Visual/Immersive, Closing/CTA
|
|
364
|
+
- Bold backgrounds — dark, gradient, or strongly tinted
|
|
365
|
+
- Max 6 bullets per slide, max 3 sentences body text
|
|
366
|
+
- Never go below 15px for any visible text
|
|
1534
367
|
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
### Slide Design Philosophy
|
|
1538
|
-
|
|
1539
|
-
- **One idea per slide** — each slide communicates a single concept, not a cluster of related points
|
|
1540
|
-
- **Glanceable, not readable** — a slide should be understood in 3 seconds; dense text belongs in documents, not presentations
|
|
1541
|
-
- **Visual storytelling arc** — open strong, build context, create emotional resonance, close with impact
|
|
1542
|
-
- **Cinematic quality bar** — every deck should feel at home in a startup pitch, TED talk, or Apple keynote
|
|
1543
|
-
- **The slide is the visual** — don't describe what the audience should imagine; show it through layout, color, and typography
|
|
1544
|
-
|
|
1545
|
-
### What App Rules to Skip for Slides
|
|
1546
|
-
|
|
1547
|
-
The general app design checklist does NOT apply to slide decks. Specifically skip:
|
|
1548
|
-
|
|
1549
|
-
- Contextual header/greeting ("Good morning, Alex") — slides are not dashboards
|
|
1550
|
-
- Search/filter, pill toggles, suggestion chips — slides are not interactive apps
|
|
1551
|
-
- Toast notifications, confirm dialogs, form validation — no CRUD in slides
|
|
1552
|
-
- Data bridge API / `window.vellum.data` — slides are static content
|
|
1553
|
-
- Skeleton loading states — slides render instantly
|
|
1554
|
-
- Mandatory trust/status pill badge — use only when slide content calls for it (e.g., a "verified" badge on a stats slide)
|
|
1555
|
-
- Mandatory emoji stat cards — use when they strengthen the message, skip when they clutter
|
|
1556
|
-
- The app Pre-Ship Design Checklist — use the Slide Pre-Ship Checklist instead
|
|
1557
|
-
|
|
1558
|
-
### Slide Typography
|
|
1559
|
-
|
|
1560
|
-
- **Title slides:** `clamp(2rem, 5vw, 3rem)`, weight 800 — much larger than app text
|
|
1561
|
-
- **Body text:** `clamp(1rem, 2.5vw, 1.25rem)` — larger than app body (14px); keep to 2–3 sentences max
|
|
1562
|
-
- **Stat values:** `clamp(1.75rem, 4vw, 2.5rem)` — big numbers are the most impactful element on any slide
|
|
1563
|
-
- **Accent-word technique is ESSENTIAL** — even more than apps, every heading should color one key word with the accent color
|
|
1564
|
-
- **Contrast is everything** — near-white on dark, near-black on light; no washed-out middle ground
|
|
1565
|
-
- **Never go below 15px** for any visible text — if it doesn't fit, cut words, don't shrink font
|
|
1566
|
-
|
|
1567
|
-
### Slide Color & Visual Treatment
|
|
1568
|
-
|
|
1569
|
-
- **Bold, full-bleed backgrounds** — warm cream, blush pink, soft lavender, deep navy, rich purple, dark emerald; vary light and dark across the deck
|
|
1570
|
-
- **Animated gradient backgrounds** are ideal for title and closing slides — use `background-size: 400% 400%` with CSS animation
|
|
1571
|
-
- **Domain-matched palettes still apply**, just executed more dramatically — a finance deck is navy/gold, a health deck is teal/white
|
|
1572
|
-
- **One accent color used sparingly** — titles, stat borders, label dots, CTA buttons; never more than one accent
|
|
1573
|
-
- **Glassmorphism works well** for slide overlays on visual/immersive slides — `backdrop-filter: blur()` with semi-transparent bg
|
|
1574
|
-
- **Full-screen immersion:** `.v-slideshow` should use `border-radius: 0; min-height: 100vh` for edge-to-edge feel
|
|
1575
|
-
- **Vary background darkness across slides** — alternate between dark, medium, and light backgrounds to create visual rhythm
|
|
1576
|
-
|
|
1577
|
-
### Slide Layout Rhythm
|
|
1578
|
-
|
|
1579
|
-
When to use each of the 8 layout variants:
|
|
1580
|
-
|
|
1581
|
-
| Type | When to Use |
|
|
1582
|
-
|---|---|
|
|
1583
|
-
| **Title** | Bold title with accent word, subtitle, optional badge — always first |
|
|
1584
|
-
| **Stats** | Early for credibility; 2–4 stat cards with big numbers |
|
|
1585
|
-
| **Bullets / Content** | Core message; 3–5 bullets max, or 2–3 sentence body |
|
|
1586
|
-
| **Quote** | Emotional punctuation; center-aligned, breaks visual pattern |
|
|
1587
|
-
| **Comparison** | Two-column before/after, entity comparison, or pros/cons |
|
|
1588
|
-
| **Timeline** | Chronological progression; milestones, history, roadmap, or process steps using `.v-timeline-entry` entries |
|
|
1589
|
-
| **Visual / Immersive** | Gradient background with glass overlay, minimal text |
|
|
1590
|
-
| **Closing / CTA** | Bold title, short takeaway, optional stat reinforcement |
|
|
1591
|
-
|
|
1592
|
-
**Layout rhythm rules:**
|
|
1593
|
-
|
|
1594
|
-
- **NEVER** two slides of the same type back-to-back
|
|
1595
|
-
- **5–8 slides:** title → stats → bullets → quote → comparison or timeline or visual → closing
|
|
1596
|
-
- **3–4 slides:** title → stats or bullets → closing
|
|
1597
|
-
- **10+ slides:** repeat content/stats but always separate with a quote, timeline, or visual slide
|
|
1598
|
-
- **Every deck needs at least 3 different layout types** — variety creates visual interest
|
|
1599
|
-
|
|
1600
|
-
### Slide Anti-Slop Rules
|
|
1601
|
-
|
|
1602
|
-
- **NEVER** more than 6 bullet points per slide — if you have more, split into two slides
|
|
1603
|
-
- **NEVER** body text smaller than 15px — cut words instead of shrinking
|
|
1604
|
-
- **NEVER** the same background color on consecutive slides — vary dark/light/gradient
|
|
1605
|
-
- **NEVER** skip accent-word on title/heading slides — it's the #1 visual technique
|
|
1606
|
-
- **NEVER** use `.v-slide-label` on every single slide — aim for 40–60% of slides
|
|
1607
|
-
- **NEVER** center-align bullet slides — only center quotes and closing slides
|
|
1608
|
-
- **NEVER** use the same stat value format everywhere — mix `$2.4M`, `147%`, `3x`, `12k+` for variety
|
|
1609
|
-
- **NEVER** hand-code charts on slides — use `vellum.widgets.lineChart()` / `.barChart()` / `.sparkline()` / `.progressRing()` rendered into a `<div>` with a fixed height. Hand-coded chart SVGs bleed into adjacent slide elements.
|
|
1610
|
-
|
|
1611
|
-
### Slide Pre-Ship Checklist
|
|
1612
|
-
|
|
1613
|
-
Before delivering any slide deck, verify:
|
|
1614
|
-
|
|
1615
|
-
1. **Domain-matched palette** — colors match the topic (not default violet for everything)
|
|
1616
|
-
2. **Bold background** — dark, gradient, or strongly tinted; not plain white
|
|
1617
|
-
3. **Accent word in every title** — one key word colored with the accent
|
|
1618
|
-
4. **One idea per slide** — each slide understood in 3 seconds
|
|
1619
|
-
5. **Layout variety** — 3+ different layout types, no consecutive same-type
|
|
1620
|
-
6. **Typography scale** — clear hierarchy; titles much larger than body text
|
|
1621
|
-
7. **Sparse content** — max 6 bullets, max 3 sentences body text per slide
|
|
1622
|
-
8. **Visual punctuation** — at least one quote, visual, or center-aligned slide
|
|
1623
|
-
9. **Strong open and close** — impactful title slide, clear takeaway closing
|
|
1624
|
-
10. **Immersive feel** — full-viewport slides, `min-height: 100vh; border-radius: 0`
|
|
1625
|
-
|
|
1626
|
-
### What Great Slide Decks Look Like
|
|
1627
|
-
|
|
1628
|
-
- **Startup pitch deck** — dark navy animated gradient, accent-word title, trust pill on stats, big stat numbers (`$12M ARR`, `3x growth`), customer quote mid-deck, CTA closing with one bold ask
|
|
1629
|
-
- **Company overview** — corporate blue on charcoal, stats-heavy early slides, comparison slide (us vs. competitors), timeline slide, professional/minimal emoji usage
|
|
1630
|
-
- **Educational deck** — bright accent on light background, emoji in bullet points for visual anchoring, expert quote, glass overlay visual slide, "key takeaways" closing
|
|
1631
|
-
- **Creative agency deck** — bold saturated palette, animated gradient backgrounds, minimal text per slide, maximum visual drama, notable client quote, portfolio-style comparison
|
|
368
|
+
Init with `vellum.widgets.slideshow()`. Use `.v-slide` with helpers: `.v-slide-label`, `.v-slide-title`, `.v-slide-body`, `.v-slide-stats`, `.v-slide-stat`, `.v-slide-quote`, `.v-slide-list`, `.v-slide-columns`.
|
|
1632
369
|
|
|
1633
370
|
## Error Handling
|
|
1634
371
|
|
|
1635
|
-
-
|
|
1636
|
-
-
|
|
1637
|
-
- If the
|
|
1638
|
-
-
|
|
1639
|
-
```javascript
|
|
1640
|
-
try {
|
|
1641
|
-
await window.vellum.data.create(data);
|
|
1642
|
-
vellum.widgets.toast('Created!', 'success');
|
|
1643
|
-
} catch (err) {
|
|
1644
|
-
console.error('Create failed:', err);
|
|
1645
|
-
vellum.widgets.toast('Failed to save. Please try again.', 'error');
|
|
1646
|
-
}
|
|
1647
|
-
```
|
|
1648
|
-
- Never let a failed data operation silently pass — always show a toast or inline error message.
|
|
1649
|
-
- If the page loads with no data, show a designed empty state (`.v-empty-state`) — never a blank screen.
|
|
1650
|
-
- For forms, show validation errors inline next to the relevant field, not as an alert.
|
|
372
|
+
- All `window.vellum.data` calls must be wrapped in `try/catch` with user-friendly feedback.
|
|
373
|
+
- Never let a failed operation silently pass — always show a toast or inline error.
|
|
374
|
+
- If the page loads with no data, show a designed empty state (`.v-empty-state`).
|
|
375
|
+
- For forms, show validation errors inline next to the relevant field.
|
|
1651
376
|
|
|
1652
377
|
## Actionable UI
|
|
1653
378
|
|
|
1654
|
-
When the user wants to triage
|
|
1655
|
-
|
|
1656
|
-
### Pattern
|
|
1657
|
-
1. **Fetch data** — use the relevant tools to gather the items
|
|
1658
|
-
2. **Generate interactive UI** — render a `dynamic_page` with selectable items and action buttons
|
|
1659
|
-
3. **User selects + clicks action** — the UI sends a `surfaceAction` with an action ID and selected item IDs
|
|
1660
|
-
4. **Execute tools** — parse the action, call the appropriate tools
|
|
1661
|
-
5. **Update UI** — use `ui_update` to remove processed items and show feedback via `widgets.toast()`
|
|
1662
|
-
|
|
1663
|
-
### HTML structure
|
|
1664
|
-
Choose the best layout for the data: grouped cards with checkboxes, data tables with selectable rows, kanban columns, stacked list items with inline actions, or any creative layout. The key constraint: items must be selectable and action buttons must call `sendAction` with the selected item IDs.
|
|
1665
|
-
|
|
1666
|
-
### CSS building blocks
|
|
1667
|
-
- `.v-action-bar` — sticky bar at top, auto-hidden when nothing selected. Contains `.v-action-bar-count` and `.v-action-bar-buttons`
|
|
1668
|
-
- `.v-action-progress` — inline progress bar for bulk operations
|
|
1669
|
-
- `.v-group-header` / `.v-group-body` — collapsible grouped sections
|
|
1670
|
-
- `.v-row-removing` — fade-out + slide animation for processed items
|
|
1671
|
-
|
|
1672
|
-
### Action data conventions
|
|
1673
|
-
- Use semantic action IDs: `archive`, `unsubscribe`, `delete`, `move`, `mark_read`
|
|
1674
|
-
- Always include selected item IDs: `sendAction("archive", { ids: ["msg_1", "msg_2"] })`
|
|
1675
|
-
|
|
1676
|
-
### Processing flow
|
|
1677
|
-
1. Parse the `surfaceAction` to get the action ID and data
|
|
1678
|
-
2. Use `vellum.confirm(title, message)` for destructive actions before executing
|
|
1679
|
-
3. Call the relevant tools with the item IDs
|
|
1680
|
-
4. Use `ui_update` to remove processed items and update counts
|
|
1681
|
-
5. Show `widgets.toast()` for feedback
|
|
1682
|
-
|
|
1683
|
-
### Error handling
|
|
1684
|
-
- Handle partial failures: remove successful items, toast count, keep failed items selectable for retry
|
|
379
|
+
When the user wants to triage or bulk-act on items, generate an interactive UI with selectable items and action buttons.
|
|
1685
380
|
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
381
|
+
1. Fetch data with relevant tools
|
|
382
|
+
2. Render a `dynamic_page` with selectable items and action buttons
|
|
383
|
+
3. User selects + clicks action — UI sends `surfaceAction` with action ID and selected IDs
|
|
384
|
+
4. Execute tools, update UI with `ui_update`, show feedback via `widgets.toast()`
|
|
385
|
+
5. Use `window.vellum.confirm()` for destructive actions
|
|
1690
386
|
|
|
1691
387
|
## Home Base
|
|
1692
388
|
|
|
1693
|
-
Home Base starts from a prebuilt scaffold. When updating
|
|
389
|
+
Home Base starts from a prebuilt scaffold. When updating, preserve required task-lane anchors and apply changes through `app_file_edit` or `app_file_write`.
|
|
1694
390
|
|
|
1695
|
-
Home Base buttons send prefilled natural-language prompts through `vellum.sendAction`. Treat these as normal user messages
|
|
1696
|
-
- For appearance changes: keep customization color-first, ask for explicit confirmation before applying a full-dashboard update.
|
|
1697
|
-
- For optional capability setup tasks (voice/computer control/ambient): keep them user-initiated and request permissions only when required for the chosen path.
|
|
1698
|
-
- If a prompt is underspecified, ask one brief follow-up and continue.
|
|
391
|
+
Home Base buttons send prefilled natural-language prompts through `vellum.sendAction`. Treat these as normal user messages.
|
|
1699
392
|
|
|
1700
393
|
## External Links
|
|
1701
394
|
|
|
1702
|
-
|
|
395
|
+
Use `vellum.openLink(url, metadata)` to make items clickable. Construct deep-link URLs when possible. Include `metadata.provider` and `metadata.type` for context.
|
|
1703
396
|
|
|
1704
397
|
## Branding
|
|
1705
398
|
|
|
1706
|
-
A "Built on Vellum" badge is auto-injected into every
|
|
399
|
+
A "Built on Vellum" badge is auto-injected into every page. Do NOT add your own.
|