dotdo 0.0.2 → 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/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/template-literals.js +2 -2
- package/dist/ai/template-literals.js.map +1 -1
- package/dist/api/middleware/auth.js +3 -2
- package/dist/api/middleware/auth.js.map +1 -1
- package/dist/db/iceberg/inverted-index.js +1 -1
- package/dist/db/iceberg/inverted-index.js.map +1 -1
- package/dist/db/iceberg/puffin.js.map +1 -1
- package/dist/db/json-indexes.js.map +1 -1
- package/dist/db/objects.js.map +1 -1
- package/dist/db/primitives/dag-scheduler/index.js +1 -1
- package/dist/db/primitives/dag-scheduler/index.js.map +1 -1
- package/dist/db/primitives/observability.js.map +1 -1
- package/dist/db/primitives/schema-evolution.js.map +1 -1
- package/dist/db/primitives/temporal-store.js.map +1 -1
- package/dist/db/primitives/typed-column-store.js.map +1 -1
- package/dist/db/primitives/utils/duration.js.map +1 -1
- package/dist/db/primitives/utils/murmur3.js +12 -14
- package/dist/db/primitives/utils/murmur3.js.map +1 -1
- package/dist/db/primitives/window-manager.js.map +1 -1
- package/dist/db/stores.js.map +1 -1
- package/dist/db/things.js.map +1 -1
- package/dist/lib/DODispatcher.js +2 -2
- package/dist/lib/DODispatcher.js.map +1 -1
- package/dist/lib/auto-wiring.js.map +1 -1
- package/dist/lib/channels/email.js +1 -1
- package/dist/lib/channels/email.js.map +1 -1
- package/dist/lib/channels/slack-blockkit.js.map +1 -1
- package/dist/lib/cloudflare/ai.js +1 -1
- package/dist/lib/cloudflare/ai.js.map +1 -1
- package/dist/lib/cloudflare/kv.js +1 -1
- package/dist/lib/cloudflare/kv.js.map +1 -1
- package/dist/lib/cloudflare/r2.js +3 -3
- package/dist/lib/cloudflare/r2.js.map +1 -1
- package/dist/lib/cloudflare/vectorize.js.map +1 -1
- package/dist/lib/cloudflare/workflows.js.map +1 -1
- package/dist/lib/executors/AgenticFunctionExecutor.js.map +1 -1
- package/dist/lib/executors/CodeFunctionExecutor.js.map +1 -1
- package/dist/lib/executors/GenerativeFunctionExecutor.js.map +1 -1
- package/dist/lib/executors/HumanFunctionExecutor.js +1 -1
- package/dist/lib/executors/HumanFunctionExecutor.js.map +1 -1
- package/dist/lib/executors/ParallelStepExecutor.js.map +1 -1
- package/dist/lib/experiments.js.map +1 -1
- package/dist/lib/flags/store.js.map +1 -1
- package/dist/lib/functions/FunctionComposition.js.map +1 -1
- package/dist/lib/functions/FunctionMiddleware.js.map +1 -1
- package/dist/lib/functions/FunctionRegistry.js.map +1 -1
- package/dist/lib/humans/templates.js.map +1 -1
- package/dist/lib/identity.js +2 -2
- package/dist/lib/identity.js.map +1 -1
- package/dist/lib/logging/index.js.map +1 -1
- package/dist/lib/mixins/bash.js +1 -73
- package/dist/lib/mixins/bash.js.map +1 -1
- package/dist/lib/mixins/git.js +0 -5
- package/dist/lib/mixins/git.js.map +1 -1
- package/dist/lib/mixins/npm.js.map +1 -1
- package/dist/lib/noun-id.js.map +1 -1
- package/dist/lib/rate-limit/sliding-window.js.map +1 -1
- package/dist/lib/rpc/bindings.js.map +1 -1
- package/dist/lib/safe-stringify.js.map +1 -1
- package/dist/lib/sandbox/miniflare-sandbox.js.map +1 -1
- package/dist/lib/sqids.js.map +1 -1
- package/dist/lib/sql/adapters/node-sql-parser.js.map +1 -1
- package/dist/lib/sql/adapters/pgsql-parser.js +19 -18
- package/dist/lib/sql/adapters/pgsql-parser.js.map +1 -1
- package/dist/metrics/hunch.js.map +1 -1
- package/dist/objects/API.js +1 -1
- package/dist/objects/API.js.map +1 -1
- package/dist/objects/Agent.js.map +1 -1
- package/dist/objects/Browser.js.map +1 -1
- package/dist/objects/CLI.js.map +1 -1
- package/dist/objects/DOBase.js.map +1 -1
- package/dist/objects/DOCache.js +153 -0
- package/dist/objects/DOCache.js.map +1 -0
- package/dist/objects/DOFull.js.map +1 -1
- package/dist/objects/Entity.js.map +1 -1
- package/dist/objects/Human.js.map +1 -1
- package/dist/objects/IcebergMetadataDO.js.map +1 -1
- package/dist/objects/IntegrationsDO.js.map +1 -1
- package/dist/objects/ObservabilityBroadcaster.js.map +1 -1
- package/dist/objects/Package.js.map +1 -1
- package/dist/objects/Product.js +1 -1
- package/dist/objects/Product.js.map +1 -1
- package/dist/objects/SaaS.js.map +1 -1
- package/dist/objects/SandboxDO.js.map +1 -1
- package/dist/objects/Service.js.map +1 -1
- package/dist/objects/VectorShardDO.js +9 -7
- package/dist/objects/VectorShardDO.js.map +1 -1
- package/dist/objects/Workflow.js.map +1 -1
- package/dist/objects/WorkflowFactory.js.map +1 -1
- package/dist/objects/WorkflowRuntime.js.map +1 -1
- package/dist/objects/lifecycle/Branch.js.map +1 -1
- package/dist/objects/lifecycle/Clone.js +1 -1
- package/dist/objects/lifecycle/Clone.js.map +1 -1
- package/dist/objects/lifecycle/Compact.js.map +1 -1
- package/dist/objects/lifecycle/Shard.js.map +1 -1
- package/dist/objects/persistence/checkpoint-manager.js.map +1 -1
- package/dist/objects/persistence/migration-runner.js.map +1 -1
- package/dist/objects/persistence/replication-manager.js +2 -2
- package/dist/objects/persistence/replication-manager.js.map +1 -1
- package/dist/objects/persistence/tiered-storage-manager.js.map +1 -1
- package/dist/objects/persistence/wal-manager.js.map +1 -1
- package/dist/objects/transport/auth-layer.js.map +1 -1
- package/dist/objects/transport/chain.js.map +1 -1
- package/dist/objects/transport/mcp-server.js +7 -6
- package/dist/objects/transport/mcp-server.js.map +1 -1
- package/dist/objects/transport/rest-autowire.js +3 -2
- package/dist/objects/transport/rest-autowire.js.map +1 -1
- package/dist/objects/transport/rest-router.js.map +1 -1
- package/dist/objects/transport/rpc-server.js +18 -15
- package/dist/objects/transport/rpc-server.js.map +1 -1
- package/dist/objects/transport/shared.js +2 -1
- package/dist/objects/transport/shared.js.map +1 -1
- package/dist/snippets/artifacts-ingest.js.map +1 -1
- package/dist/snippets/artifacts-serve.js.map +1 -1
- package/dist/snippets/search.js.map +1 -1
- package/dist/workflows/ScheduleManager.js.map +1 -1
- package/dist/workflows/StepResultStorage.js.map +1 -1
- package/dist/workflows/WaitForEventManager.js.map +1 -1
- package/dist/workflows/compat/backends/cloudflare-workflows.js.map +1 -1
- package/dist/workflows/compat/inngest/index.js.map +1 -1
- package/dist/workflows/compat/qstash/index.js.map +1 -1
- package/dist/workflows/compat/temporal/client.js.map +1 -1
- package/dist/workflows/compat/temporal/index.js.map +1 -1
- package/dist/workflows/compat/trigger/index.js.map +1 -1
- package/dist/workflows/compat/utils/index.js.map +1 -1
- package/dist/workflows/context/correlation.js +2 -2
- package/dist/workflows/context/correlation.js.map +1 -1
- package/dist/workflows/context/experiment.js +1 -1
- package/dist/workflows/context/experiment.js.map +1 -1
- package/dist/workflows/context/flag.js +1 -1
- package/dist/workflows/context/flag.js.map +1 -1
- package/dist/workflows/context/measure.js +1 -1
- package/dist/workflows/context/measure.js.map +1 -1
- package/dist/workflows/context/rate-limit.js.map +1 -1
- package/dist/workflows/data/entity-events/entity-events.js.map +1 -1
- package/dist/workflows/data/experiment/index.js.map +1 -1
- package/dist/workflows/data/goal/context.js +1 -1
- package/dist/workflows/data/goal/context.js.map +1 -1
- package/dist/workflows/data/measure/index.js +1 -1
- package/dist/workflows/data/measure/index.js.map +1 -1
- package/dist/workflows/data/stream/index.js +10 -76
- package/dist/workflows/data/stream/index.js.map +1 -1
- package/dist/workflows/data/track/context.js.map +1 -1
- package/dist/workflows/data/view/context.js.map +1 -1
- package/dist/workflows/domain.js.map +1 -1
- package/dist/workflows/flags.js +1 -1
- package/dist/workflows/flags.js.map +1 -1
- package/dist/workflows/hash.js.map +1 -1
- package/dist/workflows/on.js +1 -1
- package/dist/workflows/on.js.map +1 -1
- package/dist/workflows/schedule-builder.js.map +1 -1
- package/dist/workflows/visibility/index.js +0 -2
- package/dist/workflows/visibility/index.js.map +1 -1
- package/dist/workflows/visibility/query-parser.js.map +1 -1
- package/package.json +18 -3
- package/dist/api/analytics/router.js +0 -601
- package/dist/api/analytics/router.js.map +0 -1
- package/dist/api/index.js +0 -158
- package/dist/api/index.js.map +0 -1
- package/dist/api/middleware/error-handling.js +0 -176
- package/dist/api/middleware/error-handling.js.map +0 -1
- package/dist/api/middleware/request-id.js +0 -21
- package/dist/api/middleware/request-id.js.map +0 -1
- package/dist/api/pages.js +0 -1180
- package/dist/api/pages.js.map +0 -1
- package/dist/api/routes/api.js +0 -612
- package/dist/api/routes/api.js.map +0 -1
- package/dist/api/routes/browsers.js +0 -471
- package/dist/api/routes/browsers.js.map +0 -1
- package/dist/api/routes/do.js +0 -188
- package/dist/api/routes/do.js.map +0 -1
- package/dist/api/routes/mcp.js +0 -459
- package/dist/api/routes/mcp.js.map +0 -1
- package/dist/api/routes/obs.js +0 -445
- package/dist/api/routes/obs.js.map +0 -1
- package/dist/api/routes/openapi.js +0 -794
- package/dist/api/routes/openapi.js.map +0 -1
- package/dist/api/routes/rpc.js +0 -1103
- package/dist/api/routes/rpc.js.map +0 -1
- package/dist/api/routes/sandboxes.js +0 -389
- package/dist/api/routes/sandboxes.js.map +0 -1
- package/dist/api/test-do.js +0 -38
- package/dist/api/test-do.js.map +0 -1
- package/dist/api/types.js +0 -11
- package/dist/api/types.js.map +0 -1
- package/dist/cli/bin.js +0 -2
- package/dist/cli/main.js +0 -52342
- package/dist/do/bash.js +0 -35
- package/dist/do/bash.js.map +0 -1
- package/dist/do/fs.js +0 -25
- package/dist/do/fs.js.map +0 -1
- package/dist/do/full.js +0 -61
- package/dist/do/full.js.map +0 -1
- package/dist/do/git.js +0 -28
- package/dist/do/git.js.map +0 -1
- package/dist/do/index.js +0 -52
- package/dist/do/index.js.map +0 -1
- package/dist/lib/agent/tools/bash.js +0 -336
- package/dist/lib/agent/tools/bash.js.map +0 -1
- package/dist/lib/agent/tools/edit.js +0 -157
- package/dist/lib/agent/tools/edit.js.map +0 -1
- package/dist/lib/agent/tools/glob.js +0 -137
- package/dist/lib/agent/tools/glob.js.map +0 -1
- package/dist/lib/agent/tools/grep.js +0 -315
- package/dist/lib/agent/tools/grep.js.map +0 -1
- package/dist/lib/agent/tools/index.js +0 -71
- package/dist/lib/agent/tools/index.js.map +0 -1
- package/dist/lib/agent/tools/read.js +0 -212
- package/dist/lib/agent/tools/read.js.map +0 -1
- package/dist/lib/agent/tools/types.js +0 -197
- package/dist/lib/agent/tools/types.js.map +0 -1
- package/dist/lib/agent/tools/write.js +0 -159
- package/dist/lib/agent/tools/write.js.map +0 -1
- package/dist/lib/mixins/index.js +0 -29
- package/dist/lib/mixins/index.js.map +0 -1
- package/dist/primitives/bashx/src/ast/analyze.js +0 -1472
- package/dist/primitives/bashx/src/ast/analyze.js.map +0 -1
- package/dist/primitives/bashx/src/ast/parser.js +0 -1488
- package/dist/primitives/bashx/src/ast/parser.js.map +0 -1
- package/dist/primitives/bashx/src/do/commands/crypto.js +0 -1954
- package/dist/primitives/bashx/src/do/commands/crypto.js.map +0 -1
- package/dist/primitives/bashx/src/do/commands/data-processing.js +0 -1812
- package/dist/primitives/bashx/src/do/commands/data-processing.js.map +0 -1
- package/dist/primitives/bashx/src/do/commands/extended-utils.js +0 -804
- package/dist/primitives/bashx/src/do/commands/extended-utils.js.map +0 -1
- package/dist/primitives/bashx/src/do/commands/math-control.js +0 -1122
- package/dist/primitives/bashx/src/do/commands/math-control.js.map +0 -1
- package/dist/primitives/bashx/src/do/commands/posix-utils.js +0 -1015
- package/dist/primitives/bashx/src/do/commands/posix-utils.js.map +0 -1
- package/dist/primitives/bashx/src/do/commands/system-utils.js +0 -687
- package/dist/primitives/bashx/src/do/commands/system-utils.js.map +0 -1
- package/dist/primitives/bashx/src/do/commands/test-command.js +0 -523
- package/dist/primitives/bashx/src/do/commands/test-command.js.map +0 -1
- package/dist/primitives/bashx/src/do/commands/text-processing.js +0 -1550
- package/dist/primitives/bashx/src/do/commands/text-processing.js.map +0 -1
- package/dist/primitives/bashx/src/do/container-executor.js +0 -429
- package/dist/primitives/bashx/src/do/container-executor.js.map +0 -1
- package/dist/primitives/bashx/src/do/index.js +0 -668
- package/dist/primitives/bashx/src/do/index.js.map +0 -1
- package/dist/primitives/bashx/src/do/tiered-executor.js +0 -2647
- package/dist/primitives/bashx/src/do/tiered-executor.js.map +0 -1
- package/dist/primitives/bashx/src/do/worker.js +0 -352
- package/dist/primitives/bashx/src/do/worker.js.map +0 -1
- package/dist/primitives/bashx/src/types.js +0 -10
- package/dist/primitives/bashx/src/types.js.map +0 -1
- package/dist/primitives/fsx/core/backend.js +0 -480
- package/dist/primitives/fsx/core/backend.js.map +0 -1
- package/dist/primitives/fsx/core/constants.js +0 -140
- package/dist/primitives/fsx/core/constants.js.map +0 -1
- package/dist/primitives/fsx/core/fsx.js +0 -1184
- package/dist/primitives/fsx/core/fsx.js.map +0 -1
- package/dist/primitives/fsx/core/glob/glob.js +0 -438
- package/dist/primitives/fsx/core/glob/glob.js.map +0 -1
- package/dist/primitives/fsx/core/glob/index.js +0 -8
- package/dist/primitives/fsx/core/glob/index.js.map +0 -1
- package/dist/primitives/fsx/core/glob/match.js +0 -392
- package/dist/primitives/fsx/core/glob/match.js.map +0 -1
- package/dist/primitives/fsx/core/types.js +0 -307
- package/dist/primitives/fsx/core/types.js.map +0 -1
- package/dist/sdk/capnweb-compat.js +0 -42
- package/dist/sdk/capnweb-compat.js.map +0 -1
- package/dist/sdk/client.js +0 -20
- package/dist/sdk/client.js.map +0 -1
- package/dist/sdk/index.js +0 -17
- package/dist/sdk/index.js.map +0 -1
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DO Command
|
|
3
|
+
*
|
|
4
|
+
* Operations for managing Durable Objects:
|
|
5
|
+
* - list: List all DO instances
|
|
6
|
+
* - show: Show DO state
|
|
7
|
+
* - save: Create snapshot
|
|
8
|
+
* - restore: Restore from snapshot
|
|
9
|
+
* - clone: Clone DO instance
|
|
10
|
+
* - delete: Delete DO instance
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { Command } from 'commander'
|
|
14
|
+
import { createDB } from '../runtime/embedded-db'
|
|
15
|
+
import { createLogger } from '../utils/logger'
|
|
16
|
+
|
|
17
|
+
const logger = createLogger('do')
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Format timestamp for display
|
|
21
|
+
*/
|
|
22
|
+
function formatTime(ts: number): string {
|
|
23
|
+
return new Date(ts * 1000).toLocaleString()
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Format state for display
|
|
28
|
+
*/
|
|
29
|
+
function formatState(state: Record<string, unknown>, indent = 2): string {
|
|
30
|
+
return JSON.stringify(state, null, indent)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export const doCommand = new Command('do')
|
|
34
|
+
.description('Durable Object operations')
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* do:list - List all DO instances
|
|
38
|
+
*/
|
|
39
|
+
doCommand
|
|
40
|
+
.command('list')
|
|
41
|
+
.alias('ls')
|
|
42
|
+
.description('List all Durable Object instances')
|
|
43
|
+
.option('-c, --class <name>', 'Filter by class name')
|
|
44
|
+
.option('--json', 'Output as JSON')
|
|
45
|
+
.action(async (options) => {
|
|
46
|
+
const db = createDB()
|
|
47
|
+
await db.init()
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
const instances = await db.list(options.class)
|
|
51
|
+
|
|
52
|
+
if (options.json) {
|
|
53
|
+
console.log(JSON.stringify(instances, null, 2))
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (instances.length === 0) {
|
|
58
|
+
logger.info('No Durable Objects found')
|
|
59
|
+
return
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
console.log()
|
|
63
|
+
console.log(`Found ${instances.length} Durable Object(s):`)
|
|
64
|
+
console.log()
|
|
65
|
+
|
|
66
|
+
for (const instance of instances) {
|
|
67
|
+
console.log(` ${instance.id}`)
|
|
68
|
+
console.log(` Class: ${instance.className}`)
|
|
69
|
+
console.log(` Created: ${formatTime(instance.createdAt)}`)
|
|
70
|
+
console.log(` Updated: ${formatTime(instance.updatedAt)}`)
|
|
71
|
+
console.log()
|
|
72
|
+
}
|
|
73
|
+
} finally {
|
|
74
|
+
db.close()
|
|
75
|
+
}
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* do:show - Show DO state
|
|
80
|
+
*/
|
|
81
|
+
doCommand
|
|
82
|
+
.command('show <id>')
|
|
83
|
+
.description('Show Durable Object state')
|
|
84
|
+
.option('--json', 'Output as JSON')
|
|
85
|
+
.option('--storage', 'Include storage data')
|
|
86
|
+
.action(async (id, options) => {
|
|
87
|
+
const db = createDB()
|
|
88
|
+
await db.init()
|
|
89
|
+
|
|
90
|
+
try {
|
|
91
|
+
const instance = await db.get(id)
|
|
92
|
+
|
|
93
|
+
if (!instance) {
|
|
94
|
+
logger.error(`Durable Object not found: ${id}`)
|
|
95
|
+
process.exit(1)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (options.json) {
|
|
99
|
+
console.log(JSON.stringify(instance, null, 2))
|
|
100
|
+
return
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
console.log()
|
|
104
|
+
console.log(`Durable Object: ${instance.id}`)
|
|
105
|
+
console.log('─'.repeat(40))
|
|
106
|
+
console.log(` Class: ${instance.className}`)
|
|
107
|
+
console.log(` Created: ${formatTime(instance.createdAt)}`)
|
|
108
|
+
console.log(` Updated: ${formatTime(instance.updatedAt)}`)
|
|
109
|
+
console.log()
|
|
110
|
+
console.log('State:')
|
|
111
|
+
console.log(formatState(instance.state))
|
|
112
|
+
|
|
113
|
+
if (options.storage) {
|
|
114
|
+
console.log()
|
|
115
|
+
console.log('Storage:')
|
|
116
|
+
console.log(formatState(instance.storage))
|
|
117
|
+
}
|
|
118
|
+
console.log()
|
|
119
|
+
} finally {
|
|
120
|
+
db.close()
|
|
121
|
+
}
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* do:save - Create snapshot
|
|
126
|
+
*/
|
|
127
|
+
doCommand
|
|
128
|
+
.command('save <id>')
|
|
129
|
+
.description('Create a snapshot of a Durable Object')
|
|
130
|
+
.option('-l, --label <label>', 'Label for the snapshot')
|
|
131
|
+
.action(async (id, options) => {
|
|
132
|
+
const db = createDB()
|
|
133
|
+
await db.init()
|
|
134
|
+
|
|
135
|
+
try {
|
|
136
|
+
const instance = await db.get(id)
|
|
137
|
+
|
|
138
|
+
if (!instance) {
|
|
139
|
+
logger.error(`Durable Object not found: ${id}`)
|
|
140
|
+
process.exit(1)
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const snapshotId = await db.snapshot(id, options.label)
|
|
144
|
+
logger.success(`Snapshot created: ${snapshotId}`)
|
|
145
|
+
|
|
146
|
+
if (options.label) {
|
|
147
|
+
console.log(` Label: ${options.label}`)
|
|
148
|
+
}
|
|
149
|
+
} finally {
|
|
150
|
+
db.close()
|
|
151
|
+
}
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* do:restore - Restore from snapshot
|
|
156
|
+
*/
|
|
157
|
+
doCommand
|
|
158
|
+
.command('restore <id> <snapshot>')
|
|
159
|
+
.description('Restore a Durable Object from a snapshot')
|
|
160
|
+
.option('-f, --force', 'Force restore without confirmation')
|
|
161
|
+
.action(async (id, snapshotId, options) => {
|
|
162
|
+
const db = createDB()
|
|
163
|
+
await db.init()
|
|
164
|
+
|
|
165
|
+
try {
|
|
166
|
+
const instance = await db.get(id)
|
|
167
|
+
|
|
168
|
+
if (!instance) {
|
|
169
|
+
logger.error(`Durable Object not found: ${id}`)
|
|
170
|
+
process.exit(1)
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// List snapshots if snapshot ID is 'list'
|
|
174
|
+
if (snapshotId === 'list') {
|
|
175
|
+
const snapshots = await db.listSnapshots(id)
|
|
176
|
+
|
|
177
|
+
if (snapshots.length === 0) {
|
|
178
|
+
logger.info('No snapshots found')
|
|
179
|
+
return
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
console.log()
|
|
183
|
+
console.log(`Snapshots for ${id}:`)
|
|
184
|
+
console.log()
|
|
185
|
+
|
|
186
|
+
for (const snap of snapshots) {
|
|
187
|
+
console.log(` ${snap.id}`)
|
|
188
|
+
console.log(` Created: ${formatTime(snap.createdAt)}`)
|
|
189
|
+
if (snap.label) {
|
|
190
|
+
console.log(` Label: ${snap.label}`)
|
|
191
|
+
}
|
|
192
|
+
console.log()
|
|
193
|
+
}
|
|
194
|
+
return
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (!options.force) {
|
|
198
|
+
logger.warn('This will overwrite current state.')
|
|
199
|
+
logger.info('Use --force to confirm')
|
|
200
|
+
process.exit(1)
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
await db.restore(id, snapshotId)
|
|
204
|
+
logger.success(`Restored ${id} from snapshot ${snapshotId}`)
|
|
205
|
+
} finally {
|
|
206
|
+
db.close()
|
|
207
|
+
}
|
|
208
|
+
})
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* do:clone - Clone DO instance
|
|
212
|
+
*/
|
|
213
|
+
doCommand
|
|
214
|
+
.command('clone <source> <target>')
|
|
215
|
+
.description('Clone a Durable Object instance')
|
|
216
|
+
.action(async (sourceId, targetId) => {
|
|
217
|
+
const db = createDB()
|
|
218
|
+
await db.init()
|
|
219
|
+
|
|
220
|
+
try {
|
|
221
|
+
const source = await db.get(sourceId)
|
|
222
|
+
|
|
223
|
+
if (!source) {
|
|
224
|
+
logger.error(`Source Durable Object not found: ${sourceId}`)
|
|
225
|
+
process.exit(1)
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const existing = await db.get(targetId)
|
|
229
|
+
if (existing) {
|
|
230
|
+
logger.error(`Target already exists: ${targetId}`)
|
|
231
|
+
logger.info('Delete it first or choose a different ID')
|
|
232
|
+
process.exit(1)
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
await db.clone(sourceId, targetId)
|
|
236
|
+
logger.success(`Cloned ${sourceId} to ${targetId}`)
|
|
237
|
+
} finally {
|
|
238
|
+
db.close()
|
|
239
|
+
}
|
|
240
|
+
})
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* do:delete - Delete DO instance
|
|
244
|
+
*/
|
|
245
|
+
doCommand
|
|
246
|
+
.command('delete <id>')
|
|
247
|
+
.alias('rm')
|
|
248
|
+
.description('Delete a Durable Object instance')
|
|
249
|
+
.option('-f, --force', 'Force delete without confirmation')
|
|
250
|
+
.action(async (id, options) => {
|
|
251
|
+
const db = createDB()
|
|
252
|
+
await db.init()
|
|
253
|
+
|
|
254
|
+
try {
|
|
255
|
+
const instance = await db.get(id)
|
|
256
|
+
|
|
257
|
+
if (!instance) {
|
|
258
|
+
logger.error(`Durable Object not found: ${id}`)
|
|
259
|
+
process.exit(1)
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (!options.force) {
|
|
263
|
+
logger.warn(`This will permanently delete ${id} and all its snapshots.`)
|
|
264
|
+
logger.info('Use --force to confirm')
|
|
265
|
+
process.exit(1)
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
await db.delete(id)
|
|
269
|
+
logger.success(`Deleted ${id}`)
|
|
270
|
+
} finally {
|
|
271
|
+
db.close()
|
|
272
|
+
}
|
|
273
|
+
})
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* do:snapshots - List snapshots
|
|
277
|
+
*/
|
|
278
|
+
doCommand
|
|
279
|
+
.command('snapshots <id>')
|
|
280
|
+
.description('List snapshots for a Durable Object')
|
|
281
|
+
.option('--json', 'Output as JSON')
|
|
282
|
+
.action(async (id, options) => {
|
|
283
|
+
const db = createDB()
|
|
284
|
+
await db.init()
|
|
285
|
+
|
|
286
|
+
try {
|
|
287
|
+
const snapshots = await db.listSnapshots(id)
|
|
288
|
+
|
|
289
|
+
if (options.json) {
|
|
290
|
+
console.log(JSON.stringify(snapshots, null, 2))
|
|
291
|
+
return
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if (snapshots.length === 0) {
|
|
295
|
+
logger.info(`No snapshots found for ${id}`)
|
|
296
|
+
return
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
console.log()
|
|
300
|
+
console.log(`Snapshots for ${id} (${snapshots.length}):`)
|
|
301
|
+
console.log()
|
|
302
|
+
|
|
303
|
+
for (const snap of snapshots) {
|
|
304
|
+
const label = snap.label ? ` (${snap.label})` : ''
|
|
305
|
+
console.log(` ${snap.id}${label}`)
|
|
306
|
+
console.log(` Created: ${formatTime(snap.createdAt)}`)
|
|
307
|
+
console.log()
|
|
308
|
+
}
|
|
309
|
+
} finally {
|
|
310
|
+
db.close()
|
|
311
|
+
}
|
|
312
|
+
})
|
|
313
|
+
|
|
314
|
+
export default doCommand
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI Command Registry
|
|
3
|
+
*
|
|
4
|
+
* Exports all available CLI commands.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { run as introspectRun } from './introspect'
|
|
8
|
+
|
|
9
|
+
// Service commands (cli.do)
|
|
10
|
+
import { run as callRun } from '../src/commands/call'
|
|
11
|
+
import { run as textRun } from '../src/commands/text'
|
|
12
|
+
import { run as emailRun } from '../src/commands/email'
|
|
13
|
+
import { run as chargeRun } from '../src/commands/charge'
|
|
14
|
+
import { run as queueRun } from '../src/commands/queue'
|
|
15
|
+
import { run as llmRun } from '../src/commands/llm'
|
|
16
|
+
import { run as configRun } from '../src/commands/config'
|
|
17
|
+
|
|
18
|
+
export type CommandHandler = (args: string[]) => Promise<void> | void
|
|
19
|
+
|
|
20
|
+
export interface Command {
|
|
21
|
+
run: CommandHandler
|
|
22
|
+
description?: string
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Command registry object */
|
|
26
|
+
export const commands: Record<string, Command> = {
|
|
27
|
+
// Auth commands
|
|
28
|
+
login: {
|
|
29
|
+
run: async (_args: string[]) => {
|
|
30
|
+
// Placeholder - will be implemented
|
|
31
|
+
},
|
|
32
|
+
description: 'Log in to your account',
|
|
33
|
+
},
|
|
34
|
+
logout: {
|
|
35
|
+
run: async (_args: string[]) => {
|
|
36
|
+
// Placeholder - will be implemented
|
|
37
|
+
},
|
|
38
|
+
description: 'Log out of your account',
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
// Dev commands
|
|
42
|
+
dev: {
|
|
43
|
+
run: async (_args: string[]) => {
|
|
44
|
+
// Placeholder - will be implemented
|
|
45
|
+
},
|
|
46
|
+
description: 'Start development server',
|
|
47
|
+
},
|
|
48
|
+
build: {
|
|
49
|
+
run: async (_args: string[]) => {
|
|
50
|
+
// Placeholder - will be implemented
|
|
51
|
+
},
|
|
52
|
+
description: 'Build the project',
|
|
53
|
+
},
|
|
54
|
+
deploy: {
|
|
55
|
+
run: async (_args: string[]) => {
|
|
56
|
+
// Placeholder - will be implemented
|
|
57
|
+
},
|
|
58
|
+
description: 'Deploy to production',
|
|
59
|
+
},
|
|
60
|
+
init: {
|
|
61
|
+
run: async (_args: string[]) => {
|
|
62
|
+
// Placeholder - will be implemented
|
|
63
|
+
},
|
|
64
|
+
description: 'Initialize a new project',
|
|
65
|
+
},
|
|
66
|
+
introspect: {
|
|
67
|
+
run: introspectRun,
|
|
68
|
+
description: 'Generate .do/types.d.ts from DB.mdx schemas',
|
|
69
|
+
},
|
|
70
|
+
|
|
71
|
+
// Service commands (cli.do)
|
|
72
|
+
call: {
|
|
73
|
+
run: callRun,
|
|
74
|
+
description: 'Make voice calls via calls.do',
|
|
75
|
+
},
|
|
76
|
+
text: {
|
|
77
|
+
run: textRun,
|
|
78
|
+
description: 'Send SMS/MMS via texts.do',
|
|
79
|
+
},
|
|
80
|
+
email: {
|
|
81
|
+
run: emailRun,
|
|
82
|
+
description: 'Send emails via emails.do',
|
|
83
|
+
},
|
|
84
|
+
charge: {
|
|
85
|
+
run: chargeRun,
|
|
86
|
+
description: 'Create charges via payments.do',
|
|
87
|
+
},
|
|
88
|
+
queue: {
|
|
89
|
+
run: queueRun,
|
|
90
|
+
description: 'Queue operations via queue.do',
|
|
91
|
+
},
|
|
92
|
+
llm: {
|
|
93
|
+
run: llmRun,
|
|
94
|
+
description: 'LLM requests via llm.do',
|
|
95
|
+
},
|
|
96
|
+
config: {
|
|
97
|
+
run: configRun,
|
|
98
|
+
description: 'Manage CLI configuration',
|
|
99
|
+
},
|
|
100
|
+
}
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Init Command
|
|
3
|
+
*
|
|
4
|
+
* Scaffolds a new dotdo project with the proper structure.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* npx dotdo init my-startup # Create new project directory
|
|
8
|
+
* npx dotdo init . # Initialize in current directory
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import * as fs from 'node:fs'
|
|
12
|
+
import * as path from 'node:path'
|
|
13
|
+
|
|
14
|
+
// ============================================================================
|
|
15
|
+
// Command Metadata
|
|
16
|
+
// ============================================================================
|
|
17
|
+
|
|
18
|
+
export const name = 'init'
|
|
19
|
+
export const description = 'Initialize a new dotdo project'
|
|
20
|
+
|
|
21
|
+
// ============================================================================
|
|
22
|
+
// Types
|
|
23
|
+
// ============================================================================
|
|
24
|
+
|
|
25
|
+
export interface InitOptions {
|
|
26
|
+
/** Working directory (defaults to process.cwd()) */
|
|
27
|
+
cwd?: string
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// ============================================================================
|
|
31
|
+
// Helpers
|
|
32
|
+
// ============================================================================
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Convert kebab-case or snake_case to PascalCase
|
|
36
|
+
*/
|
|
37
|
+
function toPascalCase(str: string): string {
|
|
38
|
+
return str
|
|
39
|
+
.split(/[-_]/)
|
|
40
|
+
.map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
|
41
|
+
.join('')
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Validate project name
|
|
46
|
+
*/
|
|
47
|
+
function validateProjectName(name: string): void {
|
|
48
|
+
// Allow "." for current directory
|
|
49
|
+
if (name === '.') return
|
|
50
|
+
|
|
51
|
+
// Check for valid npm package name (simplified)
|
|
52
|
+
const validNamePattern = /^[a-z][a-z0-9-]*$/
|
|
53
|
+
|
|
54
|
+
if (!validNamePattern.test(name)) {
|
|
55
|
+
throw new Error(`Invalid project name: "${name}". Must start with a letter and contain only lowercase letters, numbers, and hyphens.`)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// ============================================================================
|
|
60
|
+
// Templates
|
|
61
|
+
// ============================================================================
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Generate src/index.ts content
|
|
65
|
+
*/
|
|
66
|
+
function generateIndexTs(className: string): string {
|
|
67
|
+
return `/**
|
|
68
|
+
* ${className} - A dotdo Startup
|
|
69
|
+
*
|
|
70
|
+
* Build your 1-Person Unicorn.
|
|
71
|
+
*/
|
|
72
|
+
|
|
73
|
+
import { DO } from 'dotdo'
|
|
74
|
+
|
|
75
|
+
export class ${className} extends DO {
|
|
76
|
+
static readonly $type = '${className}'
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Re-export the simple worker as default
|
|
80
|
+
export { default } from 'dotdo/workers/simple'
|
|
81
|
+
`
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Generate wrangler.jsonc content
|
|
86
|
+
*/
|
|
87
|
+
function generateWranglerJsonc(projectName: string, className: string): string {
|
|
88
|
+
return `{
|
|
89
|
+
"$schema": "https://raw.githubusercontent.com/cloudflare/workers-sdk/main/packages/wrangler/config-schema.json",
|
|
90
|
+
"name": "${projectName}",
|
|
91
|
+
"main": "src/index.ts",
|
|
92
|
+
"compatibility_date": "2024-12-01",
|
|
93
|
+
"compatibility_flags": ["nodejs_compat"],
|
|
94
|
+
|
|
95
|
+
// Durable Objects
|
|
96
|
+
"durable_objects": {
|
|
97
|
+
"bindings": [
|
|
98
|
+
{
|
|
99
|
+
"name": "DO",
|
|
100
|
+
"class_name": "${className}",
|
|
101
|
+
"script_name": "${projectName}"
|
|
102
|
+
}
|
|
103
|
+
]
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
"migrations": [
|
|
107
|
+
{
|
|
108
|
+
"tag": "v1",
|
|
109
|
+
"new_sqlite_classes": ["${className}"]
|
|
110
|
+
}
|
|
111
|
+
]
|
|
112
|
+
}
|
|
113
|
+
`
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Generate package.json content
|
|
118
|
+
*/
|
|
119
|
+
function generatePackageJson(projectName: string): string {
|
|
120
|
+
const pkg = {
|
|
121
|
+
name: projectName,
|
|
122
|
+
version: '0.0.1',
|
|
123
|
+
private: true,
|
|
124
|
+
type: 'module',
|
|
125
|
+
scripts: {
|
|
126
|
+
dev: 'wrangler dev',
|
|
127
|
+
deploy: 'wrangler deploy',
|
|
128
|
+
typecheck: 'tsc --noEmit',
|
|
129
|
+
},
|
|
130
|
+
dependencies: {
|
|
131
|
+
dotdo: '^0.1.0',
|
|
132
|
+
},
|
|
133
|
+
devDependencies: {
|
|
134
|
+
'@cloudflare/workers-types': '^4.20241230.0',
|
|
135
|
+
typescript: '^5.7.0',
|
|
136
|
+
wrangler: '^3.99.0',
|
|
137
|
+
},
|
|
138
|
+
}
|
|
139
|
+
return JSON.stringify(pkg, null, 2) + '\n'
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Generate tsconfig.json content
|
|
144
|
+
*/
|
|
145
|
+
function generateTsconfig(): string {
|
|
146
|
+
const config = {
|
|
147
|
+
compilerOptions: {
|
|
148
|
+
target: 'ES2022',
|
|
149
|
+
module: 'ESNext',
|
|
150
|
+
moduleResolution: 'bundler',
|
|
151
|
+
strict: true,
|
|
152
|
+
skipLibCheck: true,
|
|
153
|
+
esModuleInterop: true,
|
|
154
|
+
resolveJsonModule: true,
|
|
155
|
+
isolatedModules: true,
|
|
156
|
+
noEmit: true,
|
|
157
|
+
lib: ['ES2022'],
|
|
158
|
+
types: ['@cloudflare/workers-types'],
|
|
159
|
+
},
|
|
160
|
+
include: ['src/**/*'],
|
|
161
|
+
exclude: ['node_modules'],
|
|
162
|
+
}
|
|
163
|
+
return JSON.stringify(config, null, 2) + '\n'
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// ============================================================================
|
|
167
|
+
// Main Command
|
|
168
|
+
// ============================================================================
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Run the init command
|
|
172
|
+
*/
|
|
173
|
+
export async function run(args: string[], options: InitOptions = {}): Promise<void> {
|
|
174
|
+
const cwd = options.cwd ?? process.cwd()
|
|
175
|
+
|
|
176
|
+
// Get project name from args
|
|
177
|
+
const projectName = args[0]
|
|
178
|
+
|
|
179
|
+
if (!projectName) {
|
|
180
|
+
throw new Error('Please provide a project name: npx dotdo init <project-name>')
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Validate project name
|
|
184
|
+
validateProjectName(projectName)
|
|
185
|
+
|
|
186
|
+
// Determine project directory and name for files
|
|
187
|
+
let projectDir: string
|
|
188
|
+
let actualProjectName: string
|
|
189
|
+
|
|
190
|
+
if (projectName === '.') {
|
|
191
|
+
// Initialize in current directory
|
|
192
|
+
projectDir = cwd
|
|
193
|
+
actualProjectName = path.basename(cwd)
|
|
194
|
+
} else {
|
|
195
|
+
// Create new directory
|
|
196
|
+
projectDir = path.join(cwd, projectName)
|
|
197
|
+
actualProjectName = projectName
|
|
198
|
+
|
|
199
|
+
// Check if directory already exists
|
|
200
|
+
if (fs.existsSync(projectDir)) {
|
|
201
|
+
throw new Error(`Directory "${projectName}" already exists. Please choose a different name or remove the existing directory.`)
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Create project directory
|
|
205
|
+
fs.mkdirSync(projectDir, { recursive: true })
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Derive class name from project name
|
|
209
|
+
const className = toPascalCase(actualProjectName)
|
|
210
|
+
|
|
211
|
+
// Create src directory
|
|
212
|
+
const srcDir = path.join(projectDir, 'src')
|
|
213
|
+
fs.mkdirSync(srcDir, { recursive: true })
|
|
214
|
+
|
|
215
|
+
// Write files
|
|
216
|
+
fs.writeFileSync(
|
|
217
|
+
path.join(srcDir, 'index.ts'),
|
|
218
|
+
generateIndexTs(className)
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
fs.writeFileSync(
|
|
222
|
+
path.join(projectDir, 'wrangler.jsonc'),
|
|
223
|
+
generateWranglerJsonc(actualProjectName, className)
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
fs.writeFileSync(
|
|
227
|
+
path.join(projectDir, 'package.json'),
|
|
228
|
+
generatePackageJson(actualProjectName)
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
fs.writeFileSync(
|
|
232
|
+
path.join(projectDir, 'tsconfig.json'),
|
|
233
|
+
generateTsconfig()
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
// Print success message
|
|
237
|
+
console.log(`\nProject "${actualProjectName}" created successfully!\n`)
|
|
238
|
+
console.log('Next steps:')
|
|
239
|
+
|
|
240
|
+
if (projectName !== '.') {
|
|
241
|
+
console.log(` cd ${projectName}`)
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
console.log(' npm install')
|
|
245
|
+
console.log(' npm run dev')
|
|
246
|
+
console.log('')
|
|
247
|
+
}
|