dotdo 0.0.1 → 0.1.0
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/LICENSE +1 -1
- package/README.md +446 -315
- package/cli/README.md +238 -0
- package/cli/agent.ts +72 -0
- package/cli/bin.js +44 -0
- package/cli/bin.ts +38 -0
- package/cli/build.ts +157 -0
- package/cli/commands/auth/login.ts +14 -0
- package/cli/commands/auth/logout.ts +6 -0
- package/cli/commands/auth/whoami.ts +16 -0
- package/cli/commands/deploy-multi.ts +245 -0
- package/cli/commands/dev/deploy.ts +100 -0
- package/cli/commands/dev/dev.ts +95 -0
- package/cli/commands/dev/logs.ts +91 -0
- package/cli/commands/dev-local.ts +88 -0
- package/cli/commands/do-ops.ts +314 -0
- package/cli/commands/index.ts +100 -0
- package/cli/commands/init.ts +247 -0
- package/cli/commands/introspect/emitter.ts +315 -0
- package/cli/commands/introspect/index.ts +193 -0
- package/cli/commands/link.ts +598 -0
- package/cli/commands/snippets.ts +415 -0
- package/cli/commands/tunnel.ts +239 -0
- package/cli/device-auth.ts +289 -0
- package/cli/fallback.ts +12 -0
- package/cli/index.ts +121 -0
- package/cli/main.ts +246 -0
- package/cli/mcp-stdio.ts +790 -0
- package/cli/package.json +62 -0
- package/cli/runtime/do-registry.ts +193 -0
- package/cli/runtime/embedded-db.ts +344 -0
- package/cli/runtime/index.ts +9 -0
- package/cli/runtime/miniflare-adapter.ts +162 -0
- package/cli/sandbox.ts +82 -0
- package/cli/src/args.ts +174 -0
- package/cli/src/auth.ts +55 -0
- package/cli/src/commands/call.ts +84 -0
- package/cli/src/commands/charge.ts +96 -0
- package/cli/src/commands/config.ts +115 -0
- package/cli/src/commands/email.ts +112 -0
- package/cli/src/commands/llm.ts +115 -0
- package/cli/src/commands/queue.ts +134 -0
- package/cli/src/commands/text.ts +86 -0
- package/cli/src/config.ts +185 -0
- package/cli/src/output.ts +246 -0
- package/cli/src/rpc.ts +192 -0
- package/cli/utils/config.ts +282 -0
- package/cli/utils/detect.ts +73 -0
- package/cli/utils/index.ts +15 -0
- package/cli/utils/logger.ts +232 -0
- package/dist/ai/index.js +19 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/template-literals.js +852 -0
- package/dist/ai/template-literals.js.map +1 -0
- package/dist/api/middleware/auth-federation.js +573 -0
- package/dist/api/middleware/auth-federation.js.map +1 -0
- package/dist/api/middleware/auth.js +545 -0
- package/dist/api/middleware/auth.js.map +1 -0
- package/dist/db/actions.js +212 -0
- package/dist/db/actions.js.map +1 -0
- package/dist/db/auth.js +506 -0
- package/dist/db/auth.js.map +1 -0
- package/dist/db/branches.js +65 -0
- package/dist/db/branches.js.map +1 -0
- package/dist/db/clickhouse.js +1074 -0
- package/dist/db/clickhouse.js.map +1 -0
- package/dist/db/dlq.js +39 -0
- package/dist/db/dlq.js.map +1 -0
- package/dist/db/events.js +28 -0
- package/dist/db/events.js.map +1 -0
- package/dist/db/exec.js +64 -0
- package/dist/db/exec.js.map +1 -0
- package/dist/db/files.js +85 -0
- package/dist/db/files.js.map +1 -0
- package/dist/db/flags.js +24 -0
- package/dist/db/flags.js.map +1 -0
- package/dist/db/git.js +116 -0
- package/dist/db/git.js.map +1 -0
- package/dist/db/iceberg/inverted-index.js +862 -0
- package/dist/db/iceberg/inverted-index.js.map +1 -0
- package/dist/db/iceberg/puffin.js +878 -0
- package/dist/db/iceberg/puffin.js.map +1 -0
- package/dist/db/iceberg/search-manifest.js +422 -0
- package/dist/db/iceberg/search-manifest.js.map +1 -0
- package/dist/db/iceberg/types.js +8 -0
- package/dist/db/iceberg/types.js.map +1 -0
- package/dist/db/index.js +121 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/integrations.js +368 -0
- package/dist/db/integrations.js.map +1 -0
- package/dist/db/json-indexes.js +332 -0
- package/dist/db/json-indexes.js.map +1 -0
- package/dist/db/linked-accounts.js +287 -0
- package/dist/db/linked-accounts.js.map +1 -0
- package/dist/db/nouns.js +183 -0
- package/dist/db/nouns.js.map +1 -0
- package/dist/db/objects.js +170 -0
- package/dist/db/objects.js.map +1 -0
- package/dist/db/primitives/dag-scheduler/index.js +869 -0
- package/dist/db/primitives/dag-scheduler/index.js.map +1 -0
- package/dist/db/primitives/exactly-once-context.js +237 -0
- package/dist/db/primitives/exactly-once-context.js.map +1 -0
- package/dist/db/primitives/index.js +62 -0
- package/dist/db/primitives/index.js.map +1 -0
- package/dist/db/primitives/keyed-router.js +145 -0
- package/dist/db/primitives/keyed-router.js.map +1 -0
- package/dist/db/primitives/observability.js +162 -0
- package/dist/db/primitives/observability.js.map +1 -0
- package/dist/db/primitives/schema-evolution.js +643 -0
- package/dist/db/primitives/schema-evolution.js.map +1 -0
- package/dist/db/primitives/stateful-operator/index.js +770 -0
- package/dist/db/primitives/stateful-operator/index.js.map +1 -0
- package/dist/db/primitives/temporal-store.js +306 -0
- package/dist/db/primitives/temporal-store.js.map +1 -0
- package/dist/db/primitives/typed-column-store.js +1229 -0
- package/dist/db/primitives/typed-column-store.js.map +1 -0
- package/dist/db/primitives/utils/duration.js +162 -0
- package/dist/db/primitives/utils/duration.js.map +1 -0
- package/dist/db/primitives/utils/murmur3.js +116 -0
- package/dist/db/primitives/utils/murmur3.js.map +1 -0
- package/dist/db/primitives/watermark-service.js +136 -0
- package/dist/db/primitives/watermark-service.js.map +1 -0
- package/dist/db/primitives/window-manager.js +764 -0
- package/dist/db/primitives/window-manager.js.map +1 -0
- package/dist/db/relationships.js +66 -0
- package/dist/db/relationships.js.map +1 -0
- package/dist/db/schema-minimal.js +61 -0
- package/dist/db/schema-minimal.js.map +1 -0
- package/dist/db/search.js +28 -0
- package/dist/db/search.js.map +1 -0
- package/dist/db/stores.js +1665 -0
- package/dist/db/stores.js.map +1 -0
- package/dist/db/things.js +297 -0
- package/dist/db/things.js.map +1 -0
- package/dist/db/vault.js +171 -0
- package/dist/db/vault.js.map +1 -0
- package/dist/db/verbs.js +102 -0
- package/dist/db/verbs.js.map +1 -0
- package/dist/do/base.js +48 -0
- package/dist/do/base.js.map +1 -0
- package/dist/do/tiny.js +31 -0
- package/dist/do/tiny.js.map +1 -0
- package/dist/lib/DOAuth.js +261 -0
- package/dist/lib/DOAuth.js.map +1 -0
- package/dist/lib/DODispatcher.js +72 -0
- package/dist/lib/DODispatcher.js.map +1 -0
- package/dist/lib/Modifier.js +189 -0
- package/dist/lib/Modifier.js.map +1 -0
- package/dist/lib/StateStorage.js +403 -0
- package/dist/lib/StateStorage.js.map +1 -0
- package/dist/lib/TypeRegistry.js +122 -0
- package/dist/lib/TypeRegistry.js.map +1 -0
- package/dist/lib/ai/gateway.js +247 -0
- package/dist/lib/ai/gateway.js.map +1 -0
- package/dist/lib/ai/tool-loop-agent.js +591 -0
- package/dist/lib/ai/tool-loop-agent.js.map +1 -0
- package/dist/lib/auto-wiring.js +439 -0
- package/dist/lib/auto-wiring.js.map +1 -0
- package/dist/lib/browse/browserbase.js +163 -0
- package/dist/lib/browse/browserbase.js.map +1 -0
- package/dist/lib/browse/cloudflare.js +144 -0
- package/dist/lib/browse/cloudflare.js.map +1 -0
- package/dist/lib/browse/index.js +62 -0
- package/dist/lib/browse/index.js.map +1 -0
- package/dist/lib/browse/types.js +13 -0
- package/dist/lib/browse/types.js.map +1 -0
- package/dist/lib/cache/index.js +37 -0
- package/dist/lib/cache/index.js.map +1 -0
- package/dist/lib/cache/visibility.js +638 -0
- package/dist/lib/cache/visibility.js.map +1 -0
- package/dist/lib/capabilities.js +268 -0
- package/dist/lib/capabilities.js.map +1 -0
- package/dist/lib/channels/base.js +106 -0
- package/dist/lib/channels/base.js.map +1 -0
- package/dist/lib/channels/discord.js +94 -0
- package/dist/lib/channels/discord.js.map +1 -0
- package/dist/lib/channels/email.js +204 -0
- package/dist/lib/channels/email.js.map +1 -0
- package/dist/lib/channels/index.js +90 -0
- package/dist/lib/channels/index.js.map +1 -0
- package/dist/lib/channels/mdxui-chat.js +95 -0
- package/dist/lib/channels/mdxui-chat.js.map +1 -0
- package/dist/lib/channels/slack-blockkit.js +121 -0
- package/dist/lib/channels/slack-blockkit.js.map +1 -0
- package/dist/lib/channels/types.js +7 -0
- package/dist/lib/channels/types.js.map +1 -0
- package/dist/lib/cloudflare/ai.js +654 -0
- package/dist/lib/cloudflare/ai.js.map +1 -0
- package/dist/lib/cloudflare/index.js +88 -0
- package/dist/lib/cloudflare/index.js.map +1 -0
- package/dist/lib/cloudflare/kv.js +342 -0
- package/dist/lib/cloudflare/kv.js.map +1 -0
- package/dist/lib/cloudflare/queues.js +434 -0
- package/dist/lib/cloudflare/queues.js.map +1 -0
- package/dist/lib/cloudflare/r2.js +604 -0
- package/dist/lib/cloudflare/r2.js.map +1 -0
- package/dist/lib/cloudflare/vectorize.js +494 -0
- package/dist/lib/cloudflare/vectorize.js.map +1 -0
- package/dist/lib/cloudflare/workflows.js +569 -0
- package/dist/lib/cloudflare/workflows.js.map +1 -0
- package/dist/lib/colo/caching.js +196 -0
- package/dist/lib/colo/caching.js.map +1 -0
- package/dist/lib/colo/detection.js +194 -0
- package/dist/lib/colo/detection.js.map +1 -0
- package/dist/lib/colo/external-data.js +219 -0
- package/dist/lib/colo/external-data.js.map +1 -0
- package/dist/lib/colo/globe-data.js +179 -0
- package/dist/lib/colo/globe-data.js.map +1 -0
- package/dist/lib/colo/index.js +16 -0
- package/dist/lib/colo/index.js.map +1 -0
- package/dist/lib/decorators.js +37 -0
- package/dist/lib/decorators.js.map +1 -0
- package/dist/lib/discovery.js +81 -0
- package/dist/lib/discovery.js.map +1 -0
- package/dist/lib/executors/AgenticFunctionExecutor.js +619 -0
- package/dist/lib/executors/AgenticFunctionExecutor.js.map +1 -0
- package/dist/lib/executors/BaseFunctionExecutor.js +328 -0
- package/dist/lib/executors/BaseFunctionExecutor.js.map +1 -0
- package/dist/lib/executors/CascadeExecutor.js +418 -0
- package/dist/lib/executors/CascadeExecutor.js.map +1 -0
- package/dist/lib/executors/CodeFunctionExecutor.js +904 -0
- package/dist/lib/executors/CodeFunctionExecutor.js.map +1 -0
- package/dist/lib/executors/GenerativeFunctionExecutor.js +904 -0
- package/dist/lib/executors/GenerativeFunctionExecutor.js.map +1 -0
- package/dist/lib/executors/HumanFunctionExecutor.js +884 -0
- package/dist/lib/executors/HumanFunctionExecutor.js.map +1 -0
- package/dist/lib/executors/ParallelStepExecutor.js +308 -0
- package/dist/lib/executors/ParallelStepExecutor.js.map +1 -0
- package/dist/lib/executors/types.js +12 -0
- package/dist/lib/executors/types.js.map +1 -0
- package/dist/lib/experiments.js +89 -0
- package/dist/lib/experiments.js.map +1 -0
- package/dist/lib/flags/store.js +262 -0
- package/dist/lib/flags/store.js.map +1 -0
- package/dist/lib/functions/FunctionComposition.js +467 -0
- package/dist/lib/functions/FunctionComposition.js.map +1 -0
- package/dist/lib/functions/FunctionMiddleware.js +457 -0
- package/dist/lib/functions/FunctionMiddleware.js.map +1 -0
- package/dist/lib/functions/FunctionRegistry.js +426 -0
- package/dist/lib/functions/FunctionRegistry.js.map +1 -0
- package/dist/lib/functions/createFunction.js +1048 -0
- package/dist/lib/functions/createFunction.js.map +1 -0
- package/dist/lib/humans/index.js +68 -0
- package/dist/lib/humans/index.js.map +1 -0
- package/dist/lib/humans/templates.js +117 -0
- package/dist/lib/humans/templates.js.map +1 -0
- package/dist/lib/identity.js +98 -0
- package/dist/lib/identity.js.map +1 -0
- package/dist/lib/index.js +9 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/logging/error-logger.js +163 -0
- package/dist/lib/logging/error-logger.js.map +1 -0
- package/dist/lib/logging/index.js +160 -0
- package/dist/lib/logging/index.js.map +1 -0
- package/dist/lib/mixins/bash.js +753 -0
- package/dist/lib/mixins/bash.js.map +1 -0
- package/dist/lib/mixins/fs.js +648 -0
- package/dist/lib/mixins/fs.js.map +1 -0
- package/dist/lib/mixins/git.js +1006 -0
- package/dist/lib/mixins/git.js.map +1 -0
- package/dist/lib/mixins/npm.js +662 -0
- package/dist/lib/mixins/npm.js.map +1 -0
- package/dist/lib/noun-id.js +278 -0
- package/dist/lib/noun-id.js.map +1 -0
- package/dist/lib/rate-limit/sliding-window.js +148 -0
- package/dist/lib/rate-limit/sliding-window.js.map +1 -0
- package/dist/lib/rate-limit.js +110 -0
- package/dist/lib/rate-limit.js.map +1 -0
- package/dist/lib/rpc/bindings.js +548 -0
- package/dist/lib/rpc/bindings.js.map +1 -0
- package/dist/lib/rpc/index.js +64 -0
- package/dist/lib/rpc/index.js.map +1 -0
- package/dist/lib/safe-stringify.js +223 -0
- package/dist/lib/safe-stringify.js.map +1 -0
- package/dist/lib/sandbox/miniflare-sandbox.js +1007 -0
- package/dist/lib/sandbox/miniflare-sandbox.js.map +1 -0
- package/dist/lib/sqids.js +110 -0
- package/dist/lib/sqids.js.map +1 -0
- package/dist/lib/sql/adapters/index.js +10 -0
- package/dist/lib/sql/adapters/index.js.map +1 -0
- package/dist/lib/sql/adapters/node-sql-parser.js +552 -0
- package/dist/lib/sql/adapters/node-sql-parser.js.map +1 -0
- package/dist/lib/sql/adapters/pgsql-parser.js +1190 -0
- package/dist/lib/sql/adapters/pgsql-parser.js.map +1 -0
- package/dist/lib/sql/index.js +277 -0
- package/dist/lib/sql/index.js.map +1 -0
- package/dist/lib/sql/types.js +56 -0
- package/dist/lib/sql/types.js.map +1 -0
- package/dist/lib/type-classifier.js +126 -0
- package/dist/lib/type-classifier.js.map +1 -0
- package/dist/lib/utils/html.js +47 -0
- package/dist/lib/utils/html.js.map +1 -0
- package/dist/lib/validation.js +48 -0
- package/dist/lib/validation.js.map +1 -0
- package/dist/lib/vault/store.js +411 -0
- package/dist/lib/vault/store.js.map +1 -0
- package/dist/metrics/hunch.js +739 -0
- package/dist/metrics/hunch.js.map +1 -0
- package/dist/objects/API.js +302 -0
- package/dist/objects/API.js.map +1 -0
- package/dist/objects/Agent.js +179 -0
- package/dist/objects/Agent.js.map +1 -0
- package/dist/objects/AgenticFunctionExecutor.js +8 -0
- package/dist/objects/AgenticFunctionExecutor.js.map +1 -0
- package/dist/objects/App.js +83 -0
- package/dist/objects/App.js.map +1 -0
- package/dist/objects/Browser.js +884 -0
- package/dist/objects/Browser.js.map +1 -0
- package/dist/objects/Business.js +107 -0
- package/dist/objects/Business.js.map +1 -0
- package/dist/objects/CLI.js +221 -0
- package/dist/objects/CLI.js.map +1 -0
- package/dist/objects/CodeFunctionExecutor.js +8 -0
- package/dist/objects/CodeFunctionExecutor.js.map +1 -0
- package/dist/objects/Collection.js +161 -0
- package/dist/objects/Collection.js.map +1 -0
- package/dist/objects/DO.js +41 -0
- package/dist/objects/DO.js.map +1 -0
- package/dist/objects/DOBase.js +2309 -0
- package/dist/objects/DOBase.js.map +1 -0
- package/dist/objects/DOCache.js +153 -0
- package/dist/objects/DOCache.js.map +1 -0
- package/dist/objects/DOFull.js +1676 -0
- package/dist/objects/DOFull.js.map +1 -0
- package/dist/objects/DOTiny.js +207 -0
- package/dist/objects/DOTiny.js.map +1 -0
- package/dist/objects/Directory.js +199 -0
- package/dist/objects/Directory.js.map +1 -0
- package/dist/objects/Entity.js +413 -0
- package/dist/objects/Entity.js.map +1 -0
- package/dist/objects/Function.js +116 -0
- package/dist/objects/Function.js.map +1 -0
- package/dist/objects/Human.js +231 -0
- package/dist/objects/Human.js.map +1 -0
- package/dist/objects/HumanFunctionExecutor.js +8 -0
- package/dist/objects/HumanFunctionExecutor.js.map +1 -0
- package/dist/objects/IcebergMetadataDO.js +938 -0
- package/dist/objects/IcebergMetadataDO.js.map +1 -0
- package/dist/objects/IntegrationsDO.js +1174 -0
- package/dist/objects/IntegrationsDO.js.map +1 -0
- package/dist/objects/ObservabilityBroadcaster.js +149 -0
- package/dist/objects/ObservabilityBroadcaster.js.map +1 -0
- package/dist/objects/Package.js +154 -0
- package/dist/objects/Package.js.map +1 -0
- package/dist/objects/Product.js +193 -0
- package/dist/objects/Product.js.map +1 -0
- package/dist/objects/SDK.js +152 -0
- package/dist/objects/SDK.js.map +1 -0
- package/dist/objects/SaaS.js +235 -0
- package/dist/objects/SaaS.js.map +1 -0
- package/dist/objects/SandboxDO.js +759 -0
- package/dist/objects/SandboxDO.js.map +1 -0
- package/dist/objects/Service.js +337 -0
- package/dist/objects/Service.js.map +1 -0
- package/dist/objects/Site.js +80 -0
- package/dist/objects/Site.js.map +1 -0
- package/dist/objects/Startup.js +479 -0
- package/dist/objects/Startup.js.map +1 -0
- package/dist/objects/ThingsDO.js +170 -0
- package/dist/objects/ThingsDO.js.map +1 -0
- package/dist/objects/VectorShardDO.js +650 -0
- package/dist/objects/VectorShardDO.js.map +1 -0
- package/dist/objects/Worker.js +144 -0
- package/dist/objects/Worker.js.map +1 -0
- package/dist/objects/Workflow.js +196 -0
- package/dist/objects/Workflow.js.map +1 -0
- package/dist/objects/WorkflowFactory.js +313 -0
- package/dist/objects/WorkflowFactory.js.map +1 -0
- package/dist/objects/WorkflowRuntime.js +863 -0
- package/dist/objects/WorkflowRuntime.js.map +1 -0
- package/dist/objects/circuit-breaker-bulkhead.js +178 -0
- package/dist/objects/circuit-breaker-bulkhead.js.map +1 -0
- package/dist/objects/createFunction.js +934 -0
- package/dist/objects/createFunction.js.map +1 -0
- package/dist/objects/index.js +80 -0
- package/dist/objects/index.js.map +1 -0
- package/dist/objects/lifecycle/Branch.js +275 -0
- package/dist/objects/lifecycle/Branch.js.map +1 -0
- package/dist/objects/lifecycle/Clone.js +1499 -0
- package/dist/objects/lifecycle/Clone.js.map +1 -0
- package/dist/objects/lifecycle/Compact.js +237 -0
- package/dist/objects/lifecycle/Compact.js.map +1 -0
- package/dist/objects/lifecycle/Promote.js +476 -0
- package/dist/objects/lifecycle/Promote.js.map +1 -0
- package/dist/objects/lifecycle/Shard.js +560 -0
- package/dist/objects/lifecycle/Shard.js.map +1 -0
- package/dist/objects/lifecycle/index.js +15 -0
- package/dist/objects/lifecycle/index.js.map +1 -0
- package/dist/objects/lifecycle/types.js +33 -0
- package/dist/objects/lifecycle/types.js.map +1 -0
- package/dist/objects/mixins/infrastructure.js +171 -0
- package/dist/objects/mixins/infrastructure.js.map +1 -0
- package/dist/objects/modules/StoresModule.js +153 -0
- package/dist/objects/modules/StoresModule.js.map +1 -0
- package/dist/objects/persistence/checkpoint-manager.js +606 -0
- package/dist/objects/persistence/checkpoint-manager.js.map +1 -0
- package/dist/objects/persistence/index.js +72 -0
- package/dist/objects/persistence/index.js.map +1 -0
- package/dist/objects/persistence/migration-runner.js +562 -0
- package/dist/objects/persistence/migration-runner.js.map +1 -0
- package/dist/objects/persistence/replication-manager.js +501 -0
- package/dist/objects/persistence/replication-manager.js.map +1 -0
- package/dist/objects/persistence/tiered-storage-manager.js +595 -0
- package/dist/objects/persistence/tiered-storage-manager.js.map +1 -0
- package/dist/objects/persistence/types.js +14 -0
- package/dist/objects/persistence/types.js.map +1 -0
- package/dist/objects/persistence/wal-manager.js +653 -0
- package/dist/objects/persistence/wal-manager.js.map +1 -0
- package/dist/objects/presets/index.js +20 -0
- package/dist/objects/presets/index.js.map +1 -0
- package/dist/objects/presets/primitives.js +188 -0
- package/dist/objects/presets/primitives.js.map +1 -0
- package/dist/objects/primitives/alarm-adapter.js +141 -0
- package/dist/objects/primitives/alarm-adapter.js.map +1 -0
- package/dist/objects/primitives/index.js +337 -0
- package/dist/objects/primitives/index.js.map +1 -0
- package/dist/objects/primitives/storage-adapter.js +182 -0
- package/dist/objects/primitives/storage-adapter.js.map +1 -0
- package/dist/objects/primitives/with-primitives.js +102 -0
- package/dist/objects/primitives/with-primitives.js.map +1 -0
- package/dist/objects/services/StoreManager.js +227 -0
- package/dist/objects/services/StoreManager.js.map +1 -0
- package/dist/objects/services/index.js +13 -0
- package/dist/objects/services/index.js.map +1 -0
- package/dist/objects/transport/auth-layer.js +1451 -0
- package/dist/objects/transport/auth-layer.js.map +1 -0
- package/dist/objects/transport/capnweb-target.js +355 -0
- package/dist/objects/transport/capnweb-target.js.map +1 -0
- package/dist/objects/transport/chain.js +441 -0
- package/dist/objects/transport/chain.js.map +1 -0
- package/dist/objects/transport/handler.js +58 -0
- package/dist/objects/transport/handler.js.map +1 -0
- package/dist/objects/transport/index.js +53 -0
- package/dist/objects/transport/index.js.map +1 -0
- package/dist/objects/transport/mcp-server.js +691 -0
- package/dist/objects/transport/mcp-server.js.map +1 -0
- package/dist/objects/transport/rest-autowire.js +1508 -0
- package/dist/objects/transport/rest-autowire.js.map +1 -0
- package/dist/objects/transport/rest-router.js +440 -0
- package/dist/objects/transport/rest-router.js.map +1 -0
- package/dist/objects/transport/rpc-server.js +1539 -0
- package/dist/objects/transport/rpc-server.js.map +1 -0
- package/dist/objects/transport/shared.js +576 -0
- package/dist/objects/transport/shared.js.map +1 -0
- package/dist/objects/transport/sync-engine.js +291 -0
- package/dist/objects/transport/sync-engine.js.map +1 -0
- package/dist/objects/transport/types.js +8 -0
- package/dist/objects/transport/types.js.map +1 -0
- package/dist/sandbox/index.js +258 -0
- package/dist/sandbox/index.js.map +1 -0
- package/dist/snippets/artifacts-config.js +241 -0
- package/dist/snippets/artifacts-config.js.map +1 -0
- package/dist/snippets/artifacts-ingest.js +832 -0
- package/dist/snippets/artifacts-ingest.js.map +1 -0
- package/dist/snippets/artifacts-serve.js +1035 -0
- package/dist/snippets/artifacts-serve.js.map +1 -0
- package/dist/snippets/artifacts-types.js +161 -0
- package/dist/snippets/artifacts-types.js.map +1 -0
- package/dist/snippets/cache-probe.js +376 -0
- package/dist/snippets/cache-probe.js.map +1 -0
- package/dist/snippets/cache.js +10 -0
- package/dist/snippets/cache.js.map +1 -0
- package/dist/snippets/events.js +469 -0
- package/dist/snippets/events.js.map +1 -0
- package/dist/snippets/index.js +7 -0
- package/dist/snippets/index.js.map +1 -0
- package/dist/snippets/proxy.js +495 -0
- package/dist/snippets/proxy.js.map +1 -0
- package/dist/snippets/search.js +1759 -0
- package/dist/snippets/search.js.map +1 -0
- package/dist/streams/index.js +30 -0
- package/dist/streams/index.js.map +1 -0
- package/dist/streams/observability.js +68 -0
- package/dist/streams/observability.js.map +1 -0
- package/dist/types/AI.js +92 -0
- package/dist/types/AI.js.map +1 -0
- package/dist/types/AIFunction.js +171 -0
- package/dist/types/AIFunction.js.map +1 -0
- package/dist/types/BrowseVerb.js +89 -0
- package/dist/types/BrowseVerb.js.map +1 -0
- package/dist/types/Browser.js +31 -0
- package/dist/types/Browser.js.map +1 -0
- package/dist/types/Chaos.js +15 -0
- package/dist/types/Chaos.js.map +1 -0
- package/dist/types/CloudflareBindings.js +109 -0
- package/dist/types/CloudflareBindings.js.map +1 -0
- package/dist/types/Collection.js +50 -0
- package/dist/types/Collection.js.map +1 -0
- package/dist/types/DO.js +2 -0
- package/dist/types/DO.js.map +1 -0
- package/dist/types/DOLocation.js +63 -0
- package/dist/types/DOLocation.js.map +1 -0
- package/dist/types/EventHandler.js +57 -0
- package/dist/types/EventHandler.js.map +1 -0
- package/dist/types/Experiment.js +33 -0
- package/dist/types/Experiment.js.map +1 -0
- package/dist/types/Flag.js +57 -0
- package/dist/types/Flag.js.map +1 -0
- package/dist/types/Lifecycle.js +13 -0
- package/dist/types/Lifecycle.js.map +1 -0
- package/dist/types/Location.js +169 -0
- package/dist/types/Location.js.map +1 -0
- package/dist/types/Noun.js +66 -0
- package/dist/types/Noun.js.map +1 -0
- package/dist/types/SessionEvent.js +194 -0
- package/dist/types/SessionEvent.js.map +1 -0
- package/dist/types/Thing.js +55 -0
- package/dist/types/Thing.js.map +1 -0
- package/dist/types/ThingDO.js +153 -0
- package/dist/types/ThingDO.js.map +1 -0
- package/dist/types/Things.js +2 -0
- package/dist/types/Things.js.map +1 -0
- package/dist/types/Verb.js +119 -0
- package/dist/types/Verb.js.map +1 -0
- package/dist/types/WorkflowContext.js +70 -0
- package/dist/types/WorkflowContext.js.map +1 -0
- package/dist/types/analytics-api.js +13 -0
- package/dist/types/analytics-api.js.map +1 -0
- package/dist/types/capabilities.js +135 -0
- package/dist/types/capabilities.js.map +1 -0
- package/dist/types/drizzle.js +12 -0
- package/dist/types/drizzle.js.map +1 -0
- package/dist/types/event.js +201 -0
- package/dist/types/event.js.map +1 -0
- package/dist/types/fn.js +12 -0
- package/dist/types/fn.js.map +1 -0
- package/dist/types/iceberg.js +48 -0
- package/dist/types/iceberg.js.map +1 -0
- package/dist/types/ids.js +170 -0
- package/dist/types/ids.js.map +1 -0
- package/dist/types/index.js +41 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/introspect.js +54 -0
- package/dist/types/introspect.js.map +1 -0
- package/dist/types/observability.js +124 -0
- package/dist/types/observability.js.map +1 -0
- package/dist/types/sync-protocol.js +175 -0
- package/dist/types/sync-protocol.js.map +1 -0
- package/dist/types/vector.js +13 -0
- package/dist/types/vector.js.map +1 -0
- package/dist/workflows/ScheduleManager.js +473 -0
- package/dist/workflows/ScheduleManager.js.map +1 -0
- package/dist/workflows/StepDOBridge.js +149 -0
- package/dist/workflows/StepDOBridge.js.map +1 -0
- package/dist/workflows/StepResultStorage.js +232 -0
- package/dist/workflows/StepResultStorage.js.map +1 -0
- package/dist/workflows/WaitForEventManager.js +461 -0
- package/dist/workflows/WaitForEventManager.js.map +1 -0
- package/dist/workflows/analyzer.js +332 -0
- package/dist/workflows/analyzer.js.map +1 -0
- package/dist/workflows/compat/activity-router.js +484 -0
- package/dist/workflows/compat/activity-router.js.map +1 -0
- package/dist/workflows/compat/backends/cloudflare-workflows.js +431 -0
- package/dist/workflows/compat/backends/cloudflare-workflows.js.map +1 -0
- package/dist/workflows/compat/backends/index.js +14 -0
- package/dist/workflows/compat/backends/index.js.map +1 -0
- package/dist/workflows/compat/errors/index.js +375 -0
- package/dist/workflows/compat/errors/index.js.map +1 -0
- package/dist/workflows/compat/index.js +79 -0
- package/dist/workflows/compat/index.js.map +1 -0
- package/dist/workflows/compat/inngest/index.js +989 -0
- package/dist/workflows/compat/inngest/index.js.map +1 -0
- package/dist/workflows/compat/qstash/index.js +1263 -0
- package/dist/workflows/compat/qstash/index.js.map +1 -0
- package/dist/workflows/compat/temporal/activities.js +739 -0
- package/dist/workflows/compat/temporal/activities.js.map +1 -0
- package/dist/workflows/compat/temporal/child-workflows.js +154 -0
- package/dist/workflows/compat/temporal/child-workflows.js.map +1 -0
- package/dist/workflows/compat/temporal/client.js +381 -0
- package/dist/workflows/compat/temporal/client.js.map +1 -0
- package/dist/workflows/compat/temporal/context.js +309 -0
- package/dist/workflows/compat/temporal/context.js.map +1 -0
- package/dist/workflows/compat/temporal/determinism.js +216 -0
- package/dist/workflows/compat/temporal/determinism.js.map +1 -0
- package/dist/workflows/compat/temporal/errors.js +128 -0
- package/dist/workflows/compat/temporal/errors.js.map +1 -0
- package/dist/workflows/compat/temporal/index.js +2464 -0
- package/dist/workflows/compat/temporal/index.js.map +1 -0
- package/dist/workflows/compat/temporal/saga.js +504 -0
- package/dist/workflows/compat/temporal/saga.js.map +1 -0
- package/dist/workflows/compat/temporal/signals.js +364 -0
- package/dist/workflows/compat/temporal/signals.js.map +1 -0
- package/dist/workflows/compat/temporal/storage.js +271 -0
- package/dist/workflows/compat/temporal/storage.js.map +1 -0
- package/dist/workflows/compat/temporal/timers.js +347 -0
- package/dist/workflows/compat/temporal/timers.js.map +1 -0
- package/dist/workflows/compat/temporal/types.js +7 -0
- package/dist/workflows/compat/temporal/types.js.map +1 -0
- package/dist/workflows/compat/temporal/unified-primitives.js +339 -0
- package/dist/workflows/compat/temporal/unified-primitives.js.map +1 -0
- package/dist/workflows/compat/trigger/index.js +468 -0
- package/dist/workflows/compat/trigger/index.js.map +1 -0
- package/dist/workflows/compat/utils/index.js +69 -0
- package/dist/workflows/compat/utils/index.js.map +1 -0
- package/dist/workflows/context/correlation-capability.js +266 -0
- package/dist/workflows/context/correlation-capability.js.map +1 -0
- package/dist/workflows/context/correlation.js +484 -0
- package/dist/workflows/context/correlation.js.map +1 -0
- package/dist/workflows/context/experiment.js +289 -0
- package/dist/workflows/context/experiment.js.map +1 -0
- package/dist/workflows/context/flag.js +244 -0
- package/dist/workflows/context/flag.js.map +1 -0
- package/dist/workflows/context/foundation.js +648 -0
- package/dist/workflows/context/foundation.js.map +1 -0
- package/dist/workflows/context/human-base.js +106 -0
- package/dist/workflows/context/human-base.js.map +1 -0
- package/dist/workflows/context/human.js +368 -0
- package/dist/workflows/context/human.js.map +1 -0
- package/dist/workflows/context/measure.js +354 -0
- package/dist/workflows/context/measure.js.map +1 -0
- package/dist/workflows/context/rate-limit.js +358 -0
- package/dist/workflows/context/rate-limit.js.map +1 -0
- package/dist/workflows/context/user.js +117 -0
- package/dist/workflows/context/user.js.map +1 -0
- package/dist/workflows/context/vault.js +360 -0
- package/dist/workflows/context/vault.js.map +1 -0
- package/dist/workflows/data/entity-events/entity-events.js +489 -0
- package/dist/workflows/data/entity-events/entity-events.js.map +1 -0
- package/dist/workflows/data/experiment/index.js +599 -0
- package/dist/workflows/data/experiment/index.js.map +1 -0
- package/dist/workflows/data/goal/context.js +558 -0
- package/dist/workflows/data/goal/context.js.map +1 -0
- package/dist/workflows/data/goal/index.js +32 -0
- package/dist/workflows/data/goal/index.js.map +1 -0
- package/dist/workflows/data/measure/index.js +840 -0
- package/dist/workflows/data/measure/index.js.map +1 -0
- package/dist/workflows/data/stream/index.js +1149 -0
- package/dist/workflows/data/stream/index.js.map +1 -0
- package/dist/workflows/data/track/context.js +883 -0
- package/dist/workflows/data/track/context.js.map +1 -0
- package/dist/workflows/data/track/index.js +15 -0
- package/dist/workflows/data/track/index.js.map +1 -0
- package/dist/workflows/data/view/context.js +864 -0
- package/dist/workflows/data/view/context.js.map +1 -0
- package/dist/workflows/domain.js +93 -0
- package/dist/workflows/domain.js.map +1 -0
- package/dist/workflows/flag.js +176 -0
- package/dist/workflows/flag.js.map +1 -0
- package/dist/workflows/flags.js +217 -0
- package/dist/workflows/flags.js.map +1 -0
- package/dist/workflows/hash.js +209 -0
- package/dist/workflows/hash.js.map +1 -0
- package/dist/workflows/index.js +50 -0
- package/dist/workflows/index.js.map +1 -0
- package/dist/workflows/on.js +378 -0
- package/dist/workflows/on.js.map +1 -0
- package/dist/workflows/pipeline-promise.js +481 -0
- package/dist/workflows/pipeline-promise.js.map +1 -0
- package/dist/workflows/pipeline-types.js +20 -0
- package/dist/workflows/pipeline-types.js.map +1 -0
- package/dist/workflows/proxy.js +76 -0
- package/dist/workflows/proxy.js.map +1 -0
- package/dist/workflows/runtime.js +310 -0
- package/dist/workflows/runtime.js.map +1 -0
- package/dist/workflows/schedule-builder.js +327 -0
- package/dist/workflows/schedule-builder.js.map +1 -0
- package/dist/workflows/visibility/index.js +146 -0
- package/dist/workflows/visibility/index.js.map +1 -0
- package/dist/workflows/visibility/query-parser.js +150 -0
- package/dist/workflows/visibility/query-parser.js.map +1 -0
- package/dist/workflows/visibility/store.js +223 -0
- package/dist/workflows/visibility/store.js.map +1 -0
- package/dist/workflows/visibility/types.js +30 -0
- package/dist/workflows/visibility/types.js.map +1 -0
- package/dist/workflows/workflow.js +53 -0
- package/dist/workflows/workflow.js.map +1 -0
- package/package.json +294 -46
package/README.md
CHANGED
|
@@ -1,444 +1,575 @@
|
|
|
1
|
-
#
|
|
1
|
+
# [.do](https://platform.do)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Build your 1-Person Unicorn.**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
```typescript
|
|
6
|
+
import { Startup } from 'dotdo'
|
|
7
|
+
import { priya, ralph, tom, mark, sally } from 'agents.do'
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
│ │ Cloudflare Workers + Durable Objects + SQLite │ │
|
|
23
|
-
│ └─────────────────────────────────────────────────────────────────────┘ │
|
|
24
|
-
└─────────────────────────────────────────────────────────────────────────────┘
|
|
9
|
+
export class MyStartup extends Startup {
|
|
10
|
+
async launch() {
|
|
11
|
+
const spec = priya`define the MVP for ${this.hypothesis}`
|
|
12
|
+
let app = ralph`build ${spec}`
|
|
13
|
+
|
|
14
|
+
do {
|
|
15
|
+
app = ralph`improve ${app} per ${tom}`
|
|
16
|
+
} while (!await tom.approve(app))
|
|
17
|
+
|
|
18
|
+
mark`announce the launch`
|
|
19
|
+
sally`start selling`
|
|
20
|
+
|
|
21
|
+
// Your business is running. Go back to bed.
|
|
22
|
+
}
|
|
23
|
+
}
|
|
25
24
|
```
|
|
26
25
|
|
|
27
|
-
|
|
26
|
+
You just deployed a startup with a product team, engineering, marketing, and sales.
|
|
28
27
|
|
|
29
|
-
|
|
28
|
+
It's Tuesday. You're one person.
|
|
30
29
|
|
|
31
|
-
|
|
32
|
-
- **Event Sourcing**: Immutable audit trails for compliance and AI reasoning
|
|
33
|
-
- **Durable Execution**: Actions with state machines, retries, and guaranteed delivery
|
|
34
|
-
- **Multi-Transport**: Workers RPC, HTTP, WebSocket, and MCP for AI tool integration
|
|
35
|
-
- **Edge-First**: Runs on Cloudflare's global edge network for sub-100ms latency
|
|
30
|
+
---
|
|
36
31
|
|
|
37
|
-
##
|
|
32
|
+
## How This Actually Works
|
|
38
33
|
|
|
39
|
-
|
|
40
|
-
|
|
34
|
+
dotdo is built on [Cap'n Web](https://github.com/cloudflare/capnweb), an object-capability RPC system with promise pipelining. When you write:
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
const spec = priya`define the MVP`
|
|
38
|
+
const app = await ralph`build ${spec}`
|
|
41
39
|
```
|
|
42
40
|
|
|
43
|
-
|
|
41
|
+
You're making **one** network round trip, not two. The unawaited promise from `priya` is passed directly to `ralph`—the server receives the entire pipeline and executes it in one pass. This is **Promise Pipelining**.
|
|
42
|
+
|
|
43
|
+
If you `await` each step, you force separate round trips. Only await what you actually need.
|
|
44
|
+
|
|
45
|
+
The template literal syntax (`priya\`...\``) isn't string interpolation—it's a remote procedure call. The agent receives your intent, executes with its tools, and returns structured output.
|
|
44
46
|
|
|
45
47
|
```typescript
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
async processOrder(orderId: string) {
|
|
51
|
-
// Track the event (immutable audit trail)
|
|
52
|
-
await this.track({
|
|
53
|
-
type: 'Order.processing',
|
|
54
|
-
source: 'order-service',
|
|
55
|
-
data: { orderId }
|
|
56
|
-
})
|
|
57
|
-
|
|
58
|
-
// Create a durable action that survives failures
|
|
59
|
-
return this.doAction({
|
|
60
|
-
actor: 'system',
|
|
61
|
-
object: `order:${orderId}`,
|
|
62
|
-
action: 'process'
|
|
63
|
-
})
|
|
64
|
-
}
|
|
65
|
-
}
|
|
48
|
+
// This runs as a single batch, not N separate calls
|
|
49
|
+
const sprint = await priya`plan the sprint`
|
|
50
|
+
.map(issue => ralph`build ${issue}`)
|
|
51
|
+
.map(code => tom`review ${code}`)
|
|
66
52
|
```
|
|
67
53
|
|
|
68
|
-
|
|
54
|
+
The `.map()` isn't JavaScript's array method. It's a **Magic Map** that records your callback, sends it to the server, and replays it for each result. Record-replay, not code transfer. All in one network round trip.
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Meet Your Team
|
|
59
|
+
|
|
60
|
+
| Agent | Role |
|
|
61
|
+
|-------|------|
|
|
62
|
+
| **Priya** | Product—specs, roadmaps, priorities |
|
|
63
|
+
| **Ralph** | Engineering—builds what you need |
|
|
64
|
+
| **Tom** | Tech Lead—architecture, code review |
|
|
65
|
+
| **Rae** | Frontend—React, UI, accessibility |
|
|
66
|
+
| **Mark** | Marketing—copy, content, launches |
|
|
67
|
+
| **Sally** | Sales—outreach, demos, closing |
|
|
68
|
+
| **Quinn** | QA—testing, edge cases, quality |
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
Each agent has real identity—email, GitHub account, avatar. When Tom reviews your PR, you'll see `@tom-do` commenting. They're not chatbots. They're workers.
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
import { priya, ralph, tom, mark, quinn } from 'agents.do'
|
|
71
74
|
|
|
75
|
+
priya`what should we build next?`
|
|
76
|
+
ralph`implement the user dashboard`
|
|
77
|
+
tom`review the pull request`
|
|
78
|
+
mark`write a blog post about our launch`
|
|
79
|
+
quinn`test ${feature} thoroughly`
|
|
72
80
|
```
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
81
|
+
|
|
82
|
+
No method names. No parameters. No awaits. Just say what you want.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## The $ Context
|
|
87
|
+
|
|
88
|
+
Every Durable Object has a workflow context (`$`) that handles execution, events, and scheduling:
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
// Three durability levels
|
|
92
|
+
$.send(event) // Fire-and-forget (best-effort)
|
|
93
|
+
$.try(action) // Single attempt (fail-fast)
|
|
94
|
+
$.do(action) // Durable with retries (guaranteed)
|
|
95
|
+
|
|
96
|
+
// Event handlers via two-level proxy
|
|
97
|
+
$.on.Customer.signup(handler) // No class definitions needed
|
|
98
|
+
$.on.Payment.failed(handler) // Any Noun.verb combination
|
|
99
|
+
$.on.*.created(handler) // Wildcards supported
|
|
100
|
+
|
|
101
|
+
// Scheduling via fluent DSL
|
|
102
|
+
$.every.monday.at('9am')(handler) // Parses to CRON
|
|
103
|
+
$.every.hour(handler) // No CRON syntax required
|
|
104
|
+
$.every('first monday', handler) // Natural language
|
|
105
|
+
|
|
106
|
+
// Cross-DO resolution with circuit breakers
|
|
107
|
+
await $.Customer(id).notify() // RPC with automatic retry
|
|
108
|
+
await $.Order(id).fulfill() // Stub caching + LRU eviction
|
|
91
109
|
```
|
|
92
110
|
|
|
93
|
-
|
|
111
|
+
The event DSL uses Proxies. `$.on.Customer` returns a Proxy. `.signup` returns a function. No boilerplate classes, no `CustomerSignupEvent` definitions. Infinite combinations.
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Connect From Anywhere
|
|
94
116
|
|
|
95
|
-
|
|
117
|
+
Your Durable Object is already an API. No routes to define. No schemas to maintain.
|
|
96
118
|
|
|
97
119
|
```typescript
|
|
98
|
-
|
|
99
|
-
const user = await this.Thing.create({
|
|
100
|
-
ns: 'acme.com', // Namespace
|
|
101
|
-
type: 'user', // Entity type
|
|
102
|
-
id: 'john', // Unique ID
|
|
103
|
-
data: {
|
|
104
|
-
name: 'John Doe',
|
|
105
|
-
email: 'john@acme.com'
|
|
106
|
-
}
|
|
107
|
-
})
|
|
108
|
-
// URL: https://acme.com/user/john
|
|
120
|
+
import { $Context } from 'dotdo'
|
|
109
121
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
const followers = await this.Thing.references(user.url, 'follows')
|
|
122
|
+
const $ = $Context('https://my-startup.example.com.ai')
|
|
123
|
+
await $.Customer('alice').orders.create({ item: 'widget', qty: 5 })
|
|
113
124
|
```
|
|
114
125
|
|
|
115
|
-
|
|
126
|
+
The same promise pipelining works over HTTP. One round trip for the entire chain. Your DO methods become your API automatically.
|
|
116
127
|
|
|
117
|
-
|
|
128
|
+
```typescript
|
|
129
|
+
// Local development
|
|
130
|
+
import { $ } from 'dotdo'
|
|
131
|
+
await $.Customer('alice') // Auto-connects to localhost or do.config.ts
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Works in browsers, Node.js, mobile apps, other Workers. The client is just a Proxy—it records your calls, sends them as a single request, and returns the result. No SDK generation. No API versioning headaches. Your code IS your contract.
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## The DO in .do
|
|
139
|
+
|
|
140
|
+
dotdo runs on [Cloudflare Durable Objects](https://developers.cloudflare.com/durable-objects/)—V8 isolates with SQLite storage, globally distributed with single-threaded consistency guarantees. But we've added layers:
|
|
141
|
+
|
|
142
|
+
### Sharding
|
|
143
|
+
|
|
144
|
+
A single DO has a 10GB SQLite limit. We shard automatically:
|
|
118
145
|
|
|
119
146
|
```typescript
|
|
120
|
-
//
|
|
121
|
-
await
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
data: { role: 'primary' }
|
|
147
|
+
// Hash-based distribution across 16 shards
|
|
148
|
+
await startup.shard({
|
|
149
|
+
key: 'customerId',
|
|
150
|
+
count: 16,
|
|
151
|
+
strategy: 'hash' // or 'range', 'round-robin', custom
|
|
126
152
|
})
|
|
127
|
-
|
|
128
|
-
// Query relationships
|
|
129
|
-
const authorships = await this.relationships(userUrl, 'authored')
|
|
130
153
|
```
|
|
131
154
|
|
|
132
|
-
|
|
155
|
+
Maximum 1000 shards per DO. Consistent hashing minimizes redistribution on scale events.
|
|
133
156
|
|
|
134
|
-
|
|
157
|
+
### Geo-Replication
|
|
135
158
|
|
|
136
159
|
```typescript
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
data: { orderId: '123', amount: 99.99 },
|
|
142
|
-
correlationId: 'request-abc'
|
|
160
|
+
await startup.replicate({
|
|
161
|
+
primary: 'us-east',
|
|
162
|
+
secondaries: ['eu-west', 'asia-pacific'],
|
|
163
|
+
readPreference: 'nearest', // or 'primary', 'secondary'
|
|
143
164
|
})
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Read from the closest replica. Write to primary. Automatic failover.
|
|
168
|
+
|
|
169
|
+
### City/Colo Targeting
|
|
144
170
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
171
|
+
```typescript
|
|
172
|
+
await thing.promote({
|
|
173
|
+
colo: 'Tokyo', // IATA code: 'nrt'
|
|
174
|
+
region: 'asia-pacific',
|
|
175
|
+
preserveHistory: true
|
|
150
176
|
})
|
|
151
177
|
```
|
|
152
178
|
|
|
153
|
-
|
|
179
|
+
24 IATA codes. 9 geographic regions. Data residency compliance built in.
|
|
180
|
+
|
|
181
|
+
### Promote/Demote
|
|
154
182
|
|
|
155
|
-
|
|
183
|
+
Scale dynamically. Start as a Thing (row in parent DO), promote to independent DO when it needs isolation:
|
|
156
184
|
|
|
157
185
|
```typescript
|
|
158
|
-
//
|
|
159
|
-
await
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
action: 'generate'
|
|
186
|
+
// Thing → Durable Object
|
|
187
|
+
const newDO = await customer.promote({
|
|
188
|
+
namespace: 'https://customers.acme.com',
|
|
189
|
+
colo: 'Frankfurt' // GDPR compliance
|
|
163
190
|
})
|
|
164
191
|
|
|
165
|
-
// Durable
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
retryDelay: 1000
|
|
173
|
-
}
|
|
174
|
-
})
|
|
192
|
+
// Durable Object → Thing (fold back in)
|
|
193
|
+
await customer.demote({ preserveHistory: true })
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Tiered Storage: Hot → Warm → Cold
|
|
175
199
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
200
|
+
```
|
|
201
|
+
┌─────────────────────────────────────────────────────────────────────┐
|
|
202
|
+
│ HOT: DO SQLite │
|
|
203
|
+
│ Active working set. 50ms reads. 10GB per shard. │
|
|
204
|
+
└────────────────────────────┬────────────────────────────────────────┘
|
|
205
|
+
│ Cloudflare Pipelines (streaming)
|
|
206
|
+
▼
|
|
207
|
+
┌─────────────────────────────────────────────────────────────────────┐
|
|
208
|
+
│ WARM: R2 + Iceberg/Parquet │
|
|
209
|
+
│ Cross-DO queries. 100-150ms. Partitioned by (ns, type, visibility) │
|
|
210
|
+
└────────────────────────────┬────────────────────────────────────────┘
|
|
211
|
+
│ R2 SQL / ClickHouse
|
|
212
|
+
▼
|
|
213
|
+
┌─────────────────────────────────────────────────────────────────────┐
|
|
214
|
+
│ COLD: ClickHouse + R2 Archive │
|
|
215
|
+
│ Analytics, aggregations, time-series. Pennies per TB. │
|
|
216
|
+
└─────────────────────────────────────────────────────────────────────┘
|
|
180
217
|
```
|
|
181
218
|
|
|
182
|
-
|
|
219
|
+
Data flows automatically. Old versions archive to R2. Analytics stream to Iceberg. You query with SQL.
|
|
183
220
|
|
|
184
|
-
|
|
221
|
+
**Why this matters:** Traditional data warehouses charge per-query compute and massive egress fees. Cloudflare R2 has **$0 egress**. Your analytics cost pennies, not thousands.
|
|
185
222
|
|
|
186
|
-
|
|
187
|
-
// Store compiled artifact
|
|
188
|
-
await this.storeArtifact({
|
|
189
|
-
key: 'module:user-service',
|
|
190
|
-
type: 'esm',
|
|
191
|
-
source: 'https://github.com/acme/user-service',
|
|
192
|
-
sourceHash: 'abc123',
|
|
193
|
-
content: compiledModule,
|
|
194
|
-
expiresAt: new Date(Date.now() + 86400000) // 24h TTL
|
|
195
|
-
})
|
|
223
|
+
---
|
|
196
224
|
|
|
197
|
-
|
|
198
|
-
const cached = await this.getArtifactBySource(sourceUrl, 'esm')
|
|
199
|
-
```
|
|
225
|
+
## Pricing Reality Check
|
|
200
226
|
|
|
201
|
-
|
|
227
|
+
| Service | Egress | Storage | Compute |
|
|
228
|
+
|---------|--------|---------|---------|
|
|
229
|
+
| **Cloudflare R2** | **$0** | $0.015/GB-mo | Operations only |
|
|
230
|
+
| **AWS S3** | $0.09/GB | $0.023/GB-mo | + transfer fees |
|
|
231
|
+
| **Snowflake** | $0.05-0.12/GB | Credit-based | Warehouse costs |
|
|
232
|
+
| **BigQuery** | $0.05-0.12/GB | $0.02/GB-mo | $5/TB queried |
|
|
202
233
|
|
|
203
|
-
|
|
234
|
+
With R2:
|
|
235
|
+
- **10GB free** storage
|
|
236
|
+
- **10M free** Class B operations/month
|
|
237
|
+
- **$0 egress forever**
|
|
204
238
|
|
|
205
|
-
|
|
206
|
-
async handleWorkflow($: WorkflowContext) {
|
|
207
|
-
// Register event handlers
|
|
208
|
-
$.on.Order.created = async (event) => {
|
|
209
|
-
await $.do('process', event.data)
|
|
210
|
-
$.set('status', 'processing')
|
|
211
|
-
}
|
|
239
|
+
We're not subsidizing this. Cloudflare's network architecture makes egress free. Your data warehouse runs at a fraction of legacy costs.
|
|
212
240
|
|
|
213
|
-
|
|
214
|
-
$.every.cron('0 * * * *') = async () => {
|
|
215
|
-
await $.send('cleanup', { olderThan: '24h' })
|
|
216
|
-
}
|
|
241
|
+
---
|
|
217
242
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
```
|
|
243
|
+
## 38 API-Compatible SDKs
|
|
244
|
+
|
|
245
|
+
Use the APIs you already know. We've built edge-native compatibility layers:
|
|
222
246
|
|
|
223
|
-
|
|
247
|
+
**Databases:**
|
|
248
|
+
`@dotdo/postgres` · `@dotdo/mysql` · `@dotdo/mongo` · `@dotdo/supabase` · `@dotdo/firebase` · `@dotdo/neon` · `@dotdo/planetscale` · `@dotdo/cockroach` · `@dotdo/tidb` · `@dotdo/turso` · `@dotdo/duckdb` · `@dotdo/couchdb`
|
|
224
249
|
|
|
225
|
-
|
|
250
|
+
**Messaging:**
|
|
251
|
+
`@dotdo/kafka` · `@dotdo/redis` · `@dotdo/nats` · `@dotdo/sqs` · `@dotdo/pubsub`
|
|
226
252
|
|
|
227
|
-
|
|
253
|
+
**Real-time:**
|
|
254
|
+
`@dotdo/pusher` · `@dotdo/ably` · `@dotdo/socketio`
|
|
255
|
+
|
|
256
|
+
**Search:**
|
|
257
|
+
`@dotdo/elasticsearch` · `@dotdo/algolia` · `@dotdo/meilisearch` · `@dotdo/typesense` · `@dotdo/orama`
|
|
258
|
+
|
|
259
|
+
**Vector:**
|
|
260
|
+
`@dotdo/pinecone` · `@dotdo/qdrant` · `@dotdo/weaviate` · `@dotdo/chroma`
|
|
261
|
+
|
|
262
|
+
**Graph:**
|
|
263
|
+
`@dotdo/neo4j`
|
|
228
264
|
|
|
229
265
|
```typescript
|
|
230
|
-
//
|
|
231
|
-
|
|
232
|
-
|
|
266
|
+
// Drop-in replacement
|
|
267
|
+
import { createClient } from '@dotdo/supabase'
|
|
268
|
+
|
|
269
|
+
const supabase = createClient(url, key)
|
|
270
|
+
const { data } = await supabase.from('users').select('*')
|
|
233
271
|
```
|
|
234
272
|
|
|
235
|
-
|
|
273
|
+
Same API. But running on Durable Objects with automatic sharding, geo-replication, and tiered storage. Your existing code works. Your AI agents can use familiar APIs. It scales to millions.
|
|
236
274
|
|
|
237
|
-
|
|
238
|
-
curl -X POST https://your-do.workers.dev/rpc \
|
|
239
|
-
-H 'Authorization: Bearer $TOKEN' \
|
|
240
|
-
-H 'Content-Type: application/json' \
|
|
241
|
-
-d '{"method": "Thing.create", "params": [{"ns": "acme.com", "type": "user", "id": "jane", "data": {"name": "Jane"}}]}'
|
|
242
|
-
```
|
|
275
|
+
---
|
|
243
276
|
|
|
244
|
-
|
|
277
|
+
## Why We Rebuilt Everything
|
|
245
278
|
|
|
246
|
-
|
|
279
|
+
We didn't want to reimplement Git, Bash, MongoDB, Kafka, and Supabase from scratch.
|
|
247
280
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
281
|
+
But when we dispatched 10,000 parallel AI agents, everything crumbled:
|
|
282
|
+
- **Databases** hit connection limits and lock contention
|
|
283
|
+
- **Filesystems** couldn't handle concurrent writes
|
|
284
|
+
- **Git** servers choked on parallel clone operations
|
|
285
|
+
- **Message queues** backed up under sustained load
|
|
251
286
|
|
|
252
|
-
|
|
253
|
-
curl -X POST https://your-do.workers.dev/mcp/tools/search \
|
|
254
|
-
-d '{"query": "active premium users", "collections": ["users"]}'
|
|
287
|
+
The fundamental problem: traditional infrastructure was built for **thousands of human users**, not **millions of parallel AI agents**.
|
|
255
288
|
|
|
256
|
-
|
|
257
|
-
curl -X POST https://your-do.workers.dev/mcp/tools/fetch \
|
|
258
|
-
-d '{"target": "https://acme.com/user/john"}'
|
|
289
|
+
So we rebuilt everything on a different primitive.
|
|
259
290
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
## The V8 Isolate: A Virtual Chrome Tab
|
|
294
|
+
|
|
295
|
+
A Cloudflare Worker is a **V8 isolate**—the same JavaScript engine that runs in Chrome. Think of it as a virtual browser tab:
|
|
296
|
+
|
|
297
|
+
- **0ms cold start** (no container spin-up)
|
|
298
|
+
- **Instant execution** (no process overhead)
|
|
299
|
+
- **Global distribution** (runs in 300+ cities)
|
|
300
|
+
- **Isolated by design** (no shared memory attacks)
|
|
301
|
+
|
|
302
|
+
A Durable Object adds **persistent state** to that isolate:
|
|
303
|
+
- **SQLite storage** (10GB per instance)
|
|
304
|
+
- **Single-threaded consistency** (no locks needed)
|
|
305
|
+
- **Guaranteed delivery** (exactly-once semantics)
|
|
306
|
+
- **Location pinning** (data residency compliance)
|
|
307
|
+
|
|
308
|
+
This is the primitive we built on. Not VMs. Not containers. **V8 isolates with durable state, running on the edge, right next to your users.**
|
|
309
|
+
|
|
310
|
+
---
|
|
264
311
|
|
|
265
|
-
|
|
312
|
+
## Extended Primitives: What V8 Isolates Can't Do
|
|
313
|
+
|
|
314
|
+
V8 isolates don't have filesystems, Git, or shells. We built them from scratch:
|
|
315
|
+
|
|
316
|
+
### fsx: Filesystem on SQLite
|
|
266
317
|
|
|
267
318
|
```typescript
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
params: [{ type: 'notification', limit: 10 }]
|
|
273
|
-
}))
|
|
319
|
+
await $.fs.write('data/report.json', data)
|
|
320
|
+
await $.fs.read('content/index.mdx')
|
|
321
|
+
await $.fs.glob('**/*.ts')
|
|
322
|
+
await $.fs.mkdir('uploads', { recursive: true })
|
|
274
323
|
```
|
|
275
324
|
|
|
276
|
-
|
|
325
|
+
Full POSIX semantics implemented on DO SQLite. Not a wrapper—a complete filesystem:
|
|
326
|
+
- **Inodes** stored as rows
|
|
327
|
+
- **Directory trees** as hierarchical queries
|
|
328
|
+
- **Tiered storage**: hot (SQLite) → warm (R2) → cold (archive)
|
|
329
|
+
- Works anywhere V8 runs
|
|
277
330
|
|
|
278
|
-
|
|
279
|
-
# Discover endpoints
|
|
280
|
-
curl https://your-do.workers.dev/
|
|
331
|
+
### gitx: Git on fsx + R2
|
|
281
332
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
333
|
+
```typescript
|
|
334
|
+
await $.git.clone('https://github.com/org/repo')
|
|
335
|
+
await $.git.checkout('feature-branch')
|
|
336
|
+
await $.git.commit('feat: add new feature')
|
|
337
|
+
await $.git.push('origin', 'main')
|
|
285
338
|
```
|
|
286
339
|
|
|
287
|
-
|
|
340
|
+
Complete Git internals reimplemented for edge:
|
|
341
|
+
- **Blobs, trees, commits** stored in R2 (content-addressable)
|
|
342
|
+
- **SHA-1 hashing** via `crypto.subtle`
|
|
343
|
+
- **Refs** tracked in DO metadata
|
|
344
|
+
- **Event-driven sync** when repos change
|
|
345
|
+
|
|
346
|
+
Your agents can version control without shelling out to `git`.
|
|
288
347
|
|
|
289
|
-
|
|
348
|
+
### bashx: Shell Without VMs
|
|
290
349
|
|
|
291
350
|
```typescript
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
@requirePermission('orders:write')
|
|
296
|
-
async createOrder(data: OrderData) {
|
|
297
|
-
// Auth context automatically available
|
|
298
|
-
const { userId, organizationId, permissions } = this.getAuthContext()
|
|
299
|
-
|
|
300
|
-
return this.create('orders', {
|
|
301
|
-
...data,
|
|
302
|
-
createdBy: userId,
|
|
303
|
-
organization: organizationId
|
|
304
|
-
})
|
|
305
|
-
}
|
|
306
|
-
}
|
|
351
|
+
const result = await $.bash`npm install && npm run build`
|
|
352
|
+
await $.bash`ffmpeg -i input.mp4 -c:v libx264 output.mp4`
|
|
353
|
+
await $.bash`python analyze.py --input ${data}`
|
|
307
354
|
```
|
|
308
355
|
|
|
309
|
-
|
|
310
|
-
-
|
|
311
|
-
-
|
|
312
|
-
-
|
|
313
|
-
-
|
|
314
|
-
- Session management with expiry and refresh
|
|
356
|
+
Shell execution without spawning VMs:
|
|
357
|
+
- **AST-based safety analysis** (tree-sitter parsing)
|
|
358
|
+
- **Native file ops** (cat, ls, head use fsx directly)
|
|
359
|
+
- **Tiered execution**: pure JS → Workers → Containers
|
|
360
|
+
- **Sandboxed per-request** with resource limits
|
|
315
361
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
- Input validation via Zod schemas
|
|
320
|
-
- Sandboxed code execution with blocked globals
|
|
362
|
+
Commands are parsed, classified by impact (read/write/delete/network/system), and blocked if dangerous unless explicitly confirmed.
|
|
363
|
+
|
|
364
|
+
---
|
|
321
365
|
|
|
322
|
-
##
|
|
366
|
+
## Why the Compat Layer Exists
|
|
323
367
|
|
|
324
|
-
|
|
368
|
+
We built 38 API-compatible SDKs because developers know these APIs—and because every one of them breaks under parallel agent load:
|
|
325
369
|
|
|
370
|
+
| Original | Problem at Scale | @dotdo Solution |
|
|
371
|
+
|----------|------------------|-----------------|
|
|
372
|
+
| **Supabase** | Connection pooling limits | Sharded across DOs |
|
|
373
|
+
| **MongoDB** | Write lock contention | Single-threaded per shard |
|
|
374
|
+
| **Redis** | Memory limits per instance | Tiered to R2 |
|
|
375
|
+
| **Kafka** | Partition rebalancing storms | DO-native queues |
|
|
376
|
+
| **Postgres** | Connection exhaustion | Per-tenant DO isolation |
|
|
377
|
+
|
|
378
|
+
Each compat package provides the **exact same API** but runs on Durable Objects with automatic sharding, replication, and tiering. Your code doesn't change. It just scales.
|
|
379
|
+
|
|
380
|
+
---
|
|
381
|
+
|
|
382
|
+
## Humans When It Matters (humans.do)
|
|
383
|
+
|
|
384
|
+
AI does the work. Humans make the decisions.
|
|
385
|
+
|
|
386
|
+
```typescript
|
|
387
|
+
import { legal, ceo, cfo } from 'humans.do'
|
|
388
|
+
|
|
389
|
+
// Same syntax as agents
|
|
390
|
+
const contract = await legal`review this agreement`
|
|
391
|
+
const approved = await ceo`approve the partnership`
|
|
392
|
+
|
|
393
|
+
// With SLA and channel
|
|
394
|
+
const reviewed = await legal`review contract for ${amount}`
|
|
395
|
+
.timeout('4 hours')
|
|
396
|
+
.via('slack')
|
|
397
|
+
|
|
398
|
+
// Custom roles
|
|
399
|
+
import { createHumanTemplate } from 'humans.do'
|
|
400
|
+
const seniorAccountant = createHumanTemplate('senior-accountant')
|
|
401
|
+
await seniorAccountant`approve refund over ${amount}`
|
|
402
|
+
|
|
403
|
+
// Or explicit escalation
|
|
404
|
+
escalation = this.HumanFunction({
|
|
405
|
+
trigger: 'refund > $10000 OR audit_risk > 0.8',
|
|
406
|
+
role: 'senior-accountant',
|
|
407
|
+
sla: '4 hours',
|
|
408
|
+
})
|
|
326
409
|
```
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
410
|
+
|
|
411
|
+
### Two Human APIs
|
|
412
|
+
|
|
413
|
+
- **`$.human.*`** — Internal escalation (employees, org roles)
|
|
414
|
+
- **`$.user.*`** — End-user interaction (app users)
|
|
415
|
+
|
|
416
|
+
```typescript
|
|
417
|
+
// Internal escalation
|
|
418
|
+
await $.human.approve('Approve this expense?', { role: 'cfo' })
|
|
419
|
+
|
|
420
|
+
// End-user interaction
|
|
421
|
+
const confirmed = await $.user.confirm('Delete this item?')
|
|
422
|
+
const name = await $.user.prompt('Enter your name')
|
|
423
|
+
const size = await $.user.select('Choose size', ['S', 'M', 'L'])
|
|
335
424
|
```
|
|
336
425
|
|
|
337
|
-
|
|
426
|
+
### Multi-Channel Notifications
|
|
338
427
|
|
|
339
|
-
|
|
428
|
+
| Channel | Description |
|
|
429
|
+
|---------|-------------|
|
|
430
|
+
| **Slack BlockKit** | Interactive messages with approve/reject buttons |
|
|
431
|
+
| **Discord** | Webhook with embeds and reactions |
|
|
432
|
+
| **Email** | HTML templates with action links |
|
|
433
|
+
| **MDXUI Chat** | In-app real-time chat interface |
|
|
340
434
|
|
|
341
|
-
|
|
342
|
-
|---------|---------|
|
|
343
|
-
| [Functions.do](https://functions.do) | Atomic, composable business logic |
|
|
344
|
-
| [Database.do](https://database.do) | AI-native data with vector search |
|
|
345
|
-
| [Workflows.do](https://workflows.do) | Declarative orchestration |
|
|
346
|
-
| [APIs.do](https://apis.do) | Unified REST/GraphQL gateway |
|
|
347
|
-
| [Events.do](https://events.do) | Event sourcing and streaming |
|
|
348
|
-
| [Actions.do](https://actions.do) | Durable execution and retries |
|
|
349
|
-
| [RPC.do](https://rpc.do) | Multi-transport RPC framework |
|
|
350
|
-
| [MCP.do](https://mcp.do) | Model Context Protocol server |
|
|
351
|
-
| [CLI.do](https://cli.do) | Developer tooling |
|
|
352
|
-
| [Agents.do](https://agents.do) | AI agent deployment |
|
|
435
|
+
Messages route to Slack, email, SMS. Your workflow waits for response. Full audit trail.
|
|
353
436
|
|
|
354
|
-
|
|
437
|
+
---
|
|
355
438
|
|
|
356
|
-
##
|
|
439
|
+
## The Journey
|
|
357
440
|
|
|
358
|
-
|
|
359
|
-
# wrangler.toml
|
|
360
|
-
name = "my-do"
|
|
441
|
+
### 1. Foundation Sprint
|
|
361
442
|
|
|
362
|
-
|
|
363
|
-
name = "MY_DO"
|
|
364
|
-
class_name = "MyDO"
|
|
443
|
+
Before you build, get clarity. Define customer, problem, differentiation:
|
|
365
444
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
445
|
+
```typescript
|
|
446
|
+
const hypothesis = await $.foundation({
|
|
447
|
+
customer: 'Freelance developers who hate tax season',
|
|
448
|
+
problem: 'Spending 20+ hours on taxes instead of shipping code',
|
|
449
|
+
differentiation: 'AI does 95%, human CPA reviews edge cases',
|
|
450
|
+
})
|
|
370
451
|
|
|
371
|
-
|
|
452
|
+
// Output: "If we help freelance developers automate tax preparation
|
|
453
|
+
// with AI-powered analysis and human CPA oversight, they will pay
|
|
454
|
+
// $299/year because it saves them 20+ hours."
|
|
455
|
+
```
|
|
372
456
|
|
|
373
|
-
###
|
|
457
|
+
### 2. Experimentation Machine
|
|
374
458
|
|
|
375
|
-
|
|
459
|
+
Test your hypothesis with built-in HUNCH metrics:
|
|
376
460
|
|
|
377
461
|
```typescript
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
462
|
+
const pmf = await $.measure({
|
|
463
|
+
hairOnFire: metrics.urgency, // Is this a must-have?
|
|
464
|
+
usage: metrics.weeklyActive, // Are they using it?
|
|
465
|
+
nps: metrics.netPromoterScore, // Would they recommend?
|
|
466
|
+
churn: metrics.monthlyChurn, // Are they staying?
|
|
467
|
+
ltv_cac: metrics.lifetimeValue / metrics.acquisitionCost,
|
|
382
468
|
})
|
|
383
469
|
|
|
384
|
-
|
|
385
|
-
|
|
470
|
+
await $.experiment('pricing-test', {
|
|
471
|
+
variants: ['$199/year', '$299/year', '$29/month'],
|
|
472
|
+
metric: 'conversion_rate',
|
|
473
|
+
confidence: 0.95,
|
|
474
|
+
})
|
|
386
475
|
```
|
|
387
476
|
|
|
388
|
-
###
|
|
477
|
+
### 3. Autonomous Business
|
|
389
478
|
|
|
390
|
-
|
|
479
|
+
When you find PMF, scale. Agents operate. You set policy.
|
|
391
480
|
|
|
392
481
|
```typescript
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
482
|
+
$.on.Customer.signup((customer) => {
|
|
483
|
+
agents.onboarding.welcome(customer)
|
|
484
|
+
agents.support.scheduleCheckin(customer, '24h')
|
|
485
|
+
})
|
|
486
|
+
|
|
487
|
+
$.on.Return.completed(async (return_) => {
|
|
488
|
+
const review = await agents.qa.review(return_)
|
|
489
|
+
if (review.confidence > 0.95) {
|
|
490
|
+
agents.filing.submit(return_)
|
|
491
|
+
} else {
|
|
492
|
+
humans.cpa.review(return_)
|
|
399
493
|
}
|
|
400
|
-
|
|
494
|
+
})
|
|
495
|
+
|
|
496
|
+
$.every.month.on(1).at('9am')(() => {
|
|
497
|
+
agents.billing.processSubscriptions()
|
|
498
|
+
agents.reporting.generateMRR()
|
|
499
|
+
})
|
|
401
500
|
```
|
|
402
501
|
|
|
403
|
-
|
|
502
|
+
Revenue flows. Profit compounds. You're one person.
|
|
404
503
|
|
|
405
|
-
|
|
504
|
+
---
|
|
505
|
+
|
|
506
|
+
## Quick Start
|
|
507
|
+
|
|
508
|
+
```bash
|
|
509
|
+
npm install dotdo
|
|
510
|
+
npx dotdo init my-startup
|
|
511
|
+
npx dotdo dev
|
|
512
|
+
```
|
|
406
513
|
|
|
407
514
|
```typescript
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
515
|
+
import { Startup } from 'dotdo'
|
|
516
|
+
|
|
517
|
+
export class MyStartup extends Startup {
|
|
518
|
+
hypothesis = {
|
|
519
|
+
customer: 'Who you serve',
|
|
520
|
+
problem: 'What pain you solve',
|
|
521
|
+
solution: 'How you solve it',
|
|
413
522
|
}
|
|
414
|
-
}
|
|
523
|
+
}
|
|
415
524
|
```
|
|
416
525
|
|
|
417
|
-
|
|
526
|
+
---
|
|
527
|
+
|
|
528
|
+
## Architecture
|
|
529
|
+
|
|
530
|
+
```
|
|
531
|
+
api/ # Hono HTTP + middleware
|
|
532
|
+
objects/ # Durable Object classes (DO.ts base, 72K lines)
|
|
533
|
+
├── Agent.ts # AI worker with tools
|
|
534
|
+
├── Human.ts # Approval workflows
|
|
535
|
+
├── Entity.ts # Domain objects
|
|
536
|
+
└── Startup.ts # Business container
|
|
537
|
+
types/ # TypeScript types (Thing, Noun, Verb, WorkflowContext)
|
|
538
|
+
db/ # Drizzle schemas + tiered storage
|
|
539
|
+
├── iceberg/ # Parquet navigation (50-150ms)
|
|
540
|
+
├── clickhouse.ts # Analytics queries
|
|
541
|
+
└── stores.ts # Things, Actions, Events, Search
|
|
542
|
+
workflows/ # $ context DSL
|
|
543
|
+
├── on.ts # Event handlers
|
|
544
|
+
├── proxy.ts # Pipeline promises
|
|
545
|
+
└── context/ # Execution modes
|
|
546
|
+
compat/ # 38 API-compatible SDKs
|
|
547
|
+
agents/ # Multi-provider agent SDK
|
|
548
|
+
```
|
|
418
549
|
|
|
419
|
-
|
|
550
|
+
---
|
|
420
551
|
|
|
421
|
-
|
|
552
|
+
## The Technical Foundation
|
|
422
553
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
554
|
+
- **Runtime:** Cloudflare Workers (V8 isolates, 0ms cold starts)
|
|
555
|
+
- **Storage:** Durable Objects (SQLite, single-threaded consistency)
|
|
556
|
+
- **Object Storage:** R2 ($0 egress, Iceberg/Parquet)
|
|
557
|
+
- **Analytics:** ClickHouse (time-series, aggregations)
|
|
558
|
+
- **RPC:** Cap'n Web (promise pipelining, magic map)
|
|
559
|
+
- **Agents:** Unified SDK (Claude, OpenAI, Vercel AI)
|
|
560
|
+
- **UI:** [MDXUI](https://mdxui.dev) (Beacon sites, Cockpit apps)
|
|
561
|
+
- **Auth:** [org.ai](https://id.org.ai) (federated identity, AI + humans)
|
|
428
562
|
|
|
429
|
-
|
|
563
|
+
---
|
|
430
564
|
|
|
431
|
-
|
|
432
|
-
- [`@dotdo/middleware`](https://www.npmjs.com/package/@dotdo/middleware) - Middleware utilities
|
|
433
|
-
- [`hono`](https://www.npmjs.com/package/hono) - Lightweight web framework
|
|
565
|
+
**Solo founders** — Get a team without hiring one.
|
|
434
566
|
|
|
435
|
-
|
|
567
|
+
**Small teams** — AI does the work, humans decide.
|
|
436
568
|
|
|
437
|
-
|
|
569
|
+
**Growing startups** — Add humans without changing code.
|
|
438
570
|
|
|
439
571
|
---
|
|
440
572
|
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
</p>
|
|
573
|
+
[platform.do](https://platform.do) · [agents.do](https://agents.do) · [workers.do](https://workers.do) · [workflows.do](https://workflows.do)
|
|
574
|
+
|
|
575
|
+
MIT License
|