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,282 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config Utility
|
|
3
|
+
*
|
|
4
|
+
* Loads and manages CLI configuration from various sources:
|
|
5
|
+
* - wrangler.toml / wrangler.jsonc
|
|
6
|
+
* - dotdo.config.ts
|
|
7
|
+
* - package.json (dotdo field)
|
|
8
|
+
* - environment variables
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import * as fs from 'fs'
|
|
12
|
+
import * as path from 'path'
|
|
13
|
+
|
|
14
|
+
export interface DotdoConfig {
|
|
15
|
+
// Project settings
|
|
16
|
+
name?: string
|
|
17
|
+
entryPoint?: string
|
|
18
|
+
srcDir?: string
|
|
19
|
+
outDir?: string
|
|
20
|
+
|
|
21
|
+
// Development
|
|
22
|
+
port?: number
|
|
23
|
+
host?: string
|
|
24
|
+
persist?: boolean | string
|
|
25
|
+
|
|
26
|
+
// Cloudflare settings
|
|
27
|
+
compatibilityDate?: string
|
|
28
|
+
compatibilityFlags?: string[]
|
|
29
|
+
accountId?: string
|
|
30
|
+
|
|
31
|
+
// Durable Objects
|
|
32
|
+
durableObjects?: Record<string, {
|
|
33
|
+
className: string
|
|
34
|
+
scriptName?: string
|
|
35
|
+
}>
|
|
36
|
+
|
|
37
|
+
// Bindings
|
|
38
|
+
d1Databases?: Record<string, string>
|
|
39
|
+
r2Buckets?: string[]
|
|
40
|
+
kvNamespaces?: string[]
|
|
41
|
+
|
|
42
|
+
// Deploy targets
|
|
43
|
+
deploy?: {
|
|
44
|
+
cloudflare?: boolean
|
|
45
|
+
vercel?: boolean
|
|
46
|
+
fly?: boolean
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Tunnel settings
|
|
50
|
+
tunnel?: {
|
|
51
|
+
name?: string
|
|
52
|
+
configPath?: string
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Default configuration
|
|
57
|
+
const defaultConfig: DotdoConfig = {
|
|
58
|
+
port: 8787,
|
|
59
|
+
host: 'localhost',
|
|
60
|
+
srcDir: '.',
|
|
61
|
+
outDir: 'dist',
|
|
62
|
+
entryPoint: 'index.ts',
|
|
63
|
+
compatibilityDate: '2024-01-01',
|
|
64
|
+
compatibilityFlags: ['nodejs_compat'],
|
|
65
|
+
persist: true,
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Find the project root directory
|
|
70
|
+
*/
|
|
71
|
+
export function findProjectRoot(startDir: string = process.cwd()): string {
|
|
72
|
+
let dir = startDir
|
|
73
|
+
|
|
74
|
+
while (dir !== path.dirname(dir)) {
|
|
75
|
+
if (fs.existsSync(path.join(dir, 'package.json'))) {
|
|
76
|
+
return dir
|
|
77
|
+
}
|
|
78
|
+
dir = path.dirname(dir)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return startDir
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Load wrangler configuration
|
|
86
|
+
*/
|
|
87
|
+
function loadWranglerConfig(projectRoot: string): Partial<DotdoConfig> {
|
|
88
|
+
const config: Partial<DotdoConfig> = {}
|
|
89
|
+
|
|
90
|
+
// Try wrangler.jsonc first
|
|
91
|
+
const jsoncPath = path.join(projectRoot, 'wrangler.jsonc')
|
|
92
|
+
if (fs.existsSync(jsoncPath)) {
|
|
93
|
+
try {
|
|
94
|
+
// Remove comments for JSON parsing
|
|
95
|
+
const content = fs.readFileSync(jsoncPath, 'utf-8')
|
|
96
|
+
.replace(/\/\*[\s\S]*?\*\//g, '')
|
|
97
|
+
.replace(/\/\/.*/g, '')
|
|
98
|
+
const wrangler = JSON.parse(content)
|
|
99
|
+
return extractWranglerConfig(wrangler)
|
|
100
|
+
} catch {
|
|
101
|
+
// Ignore parse errors
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Try wrangler.toml
|
|
106
|
+
const tomlPath = path.join(projectRoot, 'wrangler.toml')
|
|
107
|
+
if (fs.existsSync(tomlPath)) {
|
|
108
|
+
try {
|
|
109
|
+
// Simple TOML parsing for basic fields
|
|
110
|
+
const content = fs.readFileSync(tomlPath, 'utf-8')
|
|
111
|
+
const lines = content.split('\n')
|
|
112
|
+
|
|
113
|
+
for (const line of lines) {
|
|
114
|
+
const match = line.match(/^(\w+)\s*=\s*["']?([^"'\n]+)["']?/)
|
|
115
|
+
if (match) {
|
|
116
|
+
const [, key, value] = match
|
|
117
|
+
if (key === 'name') config.name = value
|
|
118
|
+
if (key === 'main') config.entryPoint = value
|
|
119
|
+
if (key === 'compatibility_date') config.compatibilityDate = value
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
} catch {
|
|
123
|
+
// Ignore parse errors
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return config
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Extract dotdo config from wrangler format
|
|
132
|
+
*/
|
|
133
|
+
function extractWranglerConfig(wrangler: Record<string, unknown>): Partial<DotdoConfig> {
|
|
134
|
+
const config: Partial<DotdoConfig> = {}
|
|
135
|
+
|
|
136
|
+
if (wrangler.name) config.name = String(wrangler.name)
|
|
137
|
+
if (wrangler.main) config.entryPoint = String(wrangler.main)
|
|
138
|
+
if (wrangler.compatibility_date) config.compatibilityDate = String(wrangler.compatibility_date)
|
|
139
|
+
if (Array.isArray(wrangler.compatibility_flags)) config.compatibilityFlags = wrangler.compatibility_flags.map(String)
|
|
140
|
+
|
|
141
|
+
// Durable Objects
|
|
142
|
+
if (wrangler.durable_objects && typeof wrangler.durable_objects === 'object') {
|
|
143
|
+
const doConfig = wrangler.durable_objects as { bindings?: Array<{ name: string; class_name: string; script_name?: string }> }
|
|
144
|
+
if (Array.isArray(doConfig.bindings)) {
|
|
145
|
+
config.durableObjects = {}
|
|
146
|
+
for (const binding of doConfig.bindings) {
|
|
147
|
+
config.durableObjects[binding.name] = {
|
|
148
|
+
className: binding.class_name,
|
|
149
|
+
scriptName: binding.script_name,
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return config
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Load dotdo.config.ts if present
|
|
160
|
+
*/
|
|
161
|
+
async function loadDotdoConfig(projectRoot: string): Promise<Partial<DotdoConfig>> {
|
|
162
|
+
const configPath = path.join(projectRoot, 'dotdo.config.ts')
|
|
163
|
+
|
|
164
|
+
if (!fs.existsSync(configPath)) {
|
|
165
|
+
return {}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
try {
|
|
169
|
+
// Dynamic import for TypeScript config
|
|
170
|
+
const configModule = await import(configPath)
|
|
171
|
+
return configModule.default ?? configModule
|
|
172
|
+
} catch {
|
|
173
|
+
return {}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Load config from package.json dotdo field
|
|
179
|
+
*/
|
|
180
|
+
function loadPackageJsonConfig(projectRoot: string): Partial<DotdoConfig> {
|
|
181
|
+
const pkgPath = path.join(projectRoot, 'package.json')
|
|
182
|
+
|
|
183
|
+
if (!fs.existsSync(pkgPath)) {
|
|
184
|
+
return {}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
try {
|
|
188
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'))
|
|
189
|
+
return pkg.dotdo ?? {}
|
|
190
|
+
} catch {
|
|
191
|
+
return {}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Load config from environment variables
|
|
197
|
+
*/
|
|
198
|
+
function loadEnvConfig(): Partial<DotdoConfig> {
|
|
199
|
+
const config: Partial<DotdoConfig> = {}
|
|
200
|
+
|
|
201
|
+
if (process.env.DOTDO_PORT) config.port = parseInt(process.env.DOTDO_PORT, 10)
|
|
202
|
+
if (process.env.DOTDO_HOST) config.host = process.env.DOTDO_HOST
|
|
203
|
+
if (process.env.CLOUDFLARE_ACCOUNT_ID) config.accountId = process.env.CLOUDFLARE_ACCOUNT_ID
|
|
204
|
+
|
|
205
|
+
return config
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Load complete configuration from all sources
|
|
210
|
+
*
|
|
211
|
+
* Priority (highest to lowest):
|
|
212
|
+
* 1. Environment variables
|
|
213
|
+
* 2. dotdo.config.ts
|
|
214
|
+
* 3. package.json dotdo field
|
|
215
|
+
* 4. wrangler.toml / wrangler.jsonc
|
|
216
|
+
* 5. Default values
|
|
217
|
+
*/
|
|
218
|
+
export function loadConfig(projectRoot?: string): DotdoConfig {
|
|
219
|
+
const root = projectRoot ?? findProjectRoot()
|
|
220
|
+
|
|
221
|
+
const wranglerConfig = loadWranglerConfig(root)
|
|
222
|
+
const pkgConfig = loadPackageJsonConfig(root)
|
|
223
|
+
const envConfig = loadEnvConfig()
|
|
224
|
+
|
|
225
|
+
// Note: dotdo.config.ts loading is async, so we load it synchronously here
|
|
226
|
+
// For full async support, use loadConfigAsync
|
|
227
|
+
|
|
228
|
+
return {
|
|
229
|
+
...defaultConfig,
|
|
230
|
+
...wranglerConfig,
|
|
231
|
+
...pkgConfig,
|
|
232
|
+
...envConfig,
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Load configuration asynchronously (includes dotdo.config.ts)
|
|
238
|
+
*/
|
|
239
|
+
export async function loadConfigAsync(projectRoot?: string): Promise<DotdoConfig> {
|
|
240
|
+
const root = projectRoot ?? findProjectRoot()
|
|
241
|
+
|
|
242
|
+
const wranglerConfig = loadWranglerConfig(root)
|
|
243
|
+
const pkgConfig = loadPackageJsonConfig(root)
|
|
244
|
+
const dotdoConfig = await loadDotdoConfig(root)
|
|
245
|
+
const envConfig = loadEnvConfig()
|
|
246
|
+
|
|
247
|
+
return {
|
|
248
|
+
...defaultConfig,
|
|
249
|
+
...wranglerConfig,
|
|
250
|
+
...pkgConfig,
|
|
251
|
+
...dotdoConfig,
|
|
252
|
+
...envConfig,
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Save configuration to dotdo.config.ts
|
|
258
|
+
*/
|
|
259
|
+
export function saveConfig(config: Partial<DotdoConfig>, projectRoot?: string): void {
|
|
260
|
+
const root = projectRoot ?? findProjectRoot()
|
|
261
|
+
const configPath = path.join(root, 'dotdo.config.ts')
|
|
262
|
+
|
|
263
|
+
const content = `/**
|
|
264
|
+
* dotdo configuration
|
|
265
|
+
* Generated by dotdo CLI
|
|
266
|
+
*/
|
|
267
|
+
|
|
268
|
+
import type { DotdoConfig } from 'dotdo/cli'
|
|
269
|
+
|
|
270
|
+
export default ${JSON.stringify(config, null, 2)} satisfies DotdoConfig
|
|
271
|
+
`
|
|
272
|
+
|
|
273
|
+
fs.writeFileSync(configPath, content, 'utf-8')
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Get a specific config value
|
|
278
|
+
*/
|
|
279
|
+
export function getConfigValue<K extends keyof DotdoConfig>(key: K): DotdoConfig[K] {
|
|
280
|
+
const config = loadConfig()
|
|
281
|
+
return config[key]
|
|
282
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code vs Natural Language Detection
|
|
3
|
+
*
|
|
4
|
+
* Uses heuristics to detect whether user input is code or natural language.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export function looksLikeCode(input: string): boolean {
|
|
8
|
+
const trimmed = input.trim()
|
|
9
|
+
|
|
10
|
+
// Empty or whitespace-only is not code
|
|
11
|
+
if (!trimmed) {
|
|
12
|
+
return false
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Natural language indicators - check these FIRST
|
|
16
|
+
// If input starts with common NL patterns, treat as natural language
|
|
17
|
+
const nlStarters =
|
|
18
|
+
/^(please|help|what|how|why|when|where|who|which|can|could|would|should|explain|create|list|deploy|run the)\b/i
|
|
19
|
+
|
|
20
|
+
if (nlStarters.test(trimmed)) {
|
|
21
|
+
return false
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Code patterns
|
|
25
|
+
const codePatterns = [
|
|
26
|
+
/=>/, // arrow function
|
|
27
|
+
/\breturn\s/, // return statement
|
|
28
|
+
/^\w+\.\w+\(/, // method call at start (Math.sqrt, console.log)
|
|
29
|
+
/^const\s|^let\s|^var\s/, // variable declaration
|
|
30
|
+
/^function\s/, // function declaration
|
|
31
|
+
/^async\s+function\s/, // async function declaration
|
|
32
|
+
/^class\s/, // class declaration
|
|
33
|
+
/^import\s|^export\s/, // module syntax
|
|
34
|
+
/^await\s/, // await expression
|
|
35
|
+
/`[^`]*\$\{[^}]*\}[^`]*`/, // template literal with interpolation
|
|
36
|
+
/\?\s*[^:]+\s*:/, // ternary expression
|
|
37
|
+
/===|!==|&&|\|\|/, // comparison/logical operators
|
|
38
|
+
/\.\.\./, // spread operator
|
|
39
|
+
/^\{[^}]*:[^}]*\}$/, // object literal (simple)
|
|
40
|
+
/^\[[^\]]*\]$/, // array literal
|
|
41
|
+
/^\[[^\]]*\]\.\w+\(/, // array with method call
|
|
42
|
+
/\.\w+\([^)]*\)\.\w+\(/, // chained method calls
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
if (codePatterns.some((pattern) => pattern.test(trimmed))) {
|
|
46
|
+
return true
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Arithmetic expression pattern - more specific
|
|
50
|
+
// Must be primarily operators, digits, parens, and single-letter variables
|
|
51
|
+
if (/^[\w\d\s+\-*/()%^.]+$/.test(trimmed)) {
|
|
52
|
+
// Check if it has arithmetic operators
|
|
53
|
+
if (/[+\-*/]/.test(trimmed)) {
|
|
54
|
+
// Make sure it's not natural language by checking word patterns
|
|
55
|
+
const words = trimmed.split(/\s+/)
|
|
56
|
+
// If all "words" are short (1-2 chars after removing parens) or numbers, it's likely arithmetic
|
|
57
|
+
const looksArithmetic = words.every((w) => {
|
|
58
|
+
// Strip parentheses for length check
|
|
59
|
+
const stripped = w.replace(/[()]/g, '')
|
|
60
|
+
return (
|
|
61
|
+
stripped.length <= 2 ||
|
|
62
|
+
/^[\d.]+$/.test(stripped) ||
|
|
63
|
+
/^[+\-*/()%^]+$/.test(w)
|
|
64
|
+
)
|
|
65
|
+
})
|
|
66
|
+
if (looksArithmetic) {
|
|
67
|
+
return true
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return false
|
|
73
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utils Module
|
|
3
|
+
*
|
|
4
|
+
* Exports all utility functions for CLI operations.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export { Logger, Spinner, createLogger, logger, type LogLevel, type LoggerOptions } from './logger'
|
|
8
|
+
export {
|
|
9
|
+
loadConfig,
|
|
10
|
+
loadConfigAsync,
|
|
11
|
+
saveConfig,
|
|
12
|
+
findProjectRoot,
|
|
13
|
+
getConfigValue,
|
|
14
|
+
type DotdoConfig,
|
|
15
|
+
} from './config'
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logger Utility
|
|
3
|
+
*
|
|
4
|
+
* Provides consistent, colorful logging for CLI operations.
|
|
5
|
+
* Supports different log levels and contexts.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'success'
|
|
9
|
+
|
|
10
|
+
export interface LoggerOptions {
|
|
11
|
+
level?: LogLevel
|
|
12
|
+
context?: string
|
|
13
|
+
silent?: boolean
|
|
14
|
+
colors?: boolean
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// ANSI color codes
|
|
18
|
+
const colors = {
|
|
19
|
+
reset: '\x1b[0m',
|
|
20
|
+
dim: '\x1b[2m',
|
|
21
|
+
bold: '\x1b[1m',
|
|
22
|
+
red: '\x1b[31m',
|
|
23
|
+
green: '\x1b[32m',
|
|
24
|
+
yellow: '\x1b[33m',
|
|
25
|
+
blue: '\x1b[34m',
|
|
26
|
+
magenta: '\x1b[35m',
|
|
27
|
+
cyan: '\x1b[36m',
|
|
28
|
+
gray: '\x1b[90m',
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Icons for different log levels
|
|
32
|
+
const icons = {
|
|
33
|
+
debug: colors.gray + '[debug]' + colors.reset,
|
|
34
|
+
info: colors.blue + '[info]' + colors.reset,
|
|
35
|
+
warn: colors.yellow + '[warn]' + colors.reset,
|
|
36
|
+
error: colors.red + '[error]' + colors.reset,
|
|
37
|
+
success: colors.green + '[ok]' + colors.reset,
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Log level priority
|
|
41
|
+
const levelPriority: Record<LogLevel, number> = {
|
|
42
|
+
debug: 0,
|
|
43
|
+
info: 1,
|
|
44
|
+
warn: 2,
|
|
45
|
+
error: 3,
|
|
46
|
+
success: 1,
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Logger class for CLI output
|
|
51
|
+
*/
|
|
52
|
+
export class Logger {
|
|
53
|
+
private level: LogLevel
|
|
54
|
+
private context: string
|
|
55
|
+
private silent: boolean
|
|
56
|
+
private useColors: boolean
|
|
57
|
+
|
|
58
|
+
constructor(options: LoggerOptions = {}) {
|
|
59
|
+
this.level = options.level ?? (process.env.DEBUG ? 'debug' : 'info')
|
|
60
|
+
this.context = options.context ?? ''
|
|
61
|
+
this.silent = options.silent ?? false
|
|
62
|
+
this.useColors = options.colors ?? (process.stdout.isTTY ?? false)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Format a message with context and level
|
|
67
|
+
*/
|
|
68
|
+
private format(level: LogLevel, message: string, data?: Record<string, unknown>): string {
|
|
69
|
+
const icon = this.useColors ? icons[level] : `[${level}]`
|
|
70
|
+
const ctx = this.context ? this.useColors ? `${colors.dim}(${this.context})${colors.reset}` : `(${this.context})` : ''
|
|
71
|
+
|
|
72
|
+
let output = `${icon} ${ctx} ${message}`
|
|
73
|
+
|
|
74
|
+
if (data) {
|
|
75
|
+
const dataStr = JSON.stringify(data, null, 2)
|
|
76
|
+
output += this.useColors ? `\n${colors.dim}${dataStr}${colors.reset}` : `\n${dataStr}`
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return output
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Check if a log level should be output
|
|
84
|
+
*/
|
|
85
|
+
private shouldLog(level: LogLevel): boolean {
|
|
86
|
+
return !this.silent && levelPriority[level] >= levelPriority[this.level]
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Debug level logging
|
|
91
|
+
*/
|
|
92
|
+
debug(message: string, data?: Record<string, unknown>): void {
|
|
93
|
+
if (this.shouldLog('debug')) {
|
|
94
|
+
console.log(this.format('debug', message, data))
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Info level logging
|
|
100
|
+
*/
|
|
101
|
+
info(message: string, data?: Record<string, unknown>): void {
|
|
102
|
+
if (this.shouldLog('info')) {
|
|
103
|
+
console.log(this.format('info', message, data))
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Warning level logging
|
|
109
|
+
*/
|
|
110
|
+
warn(message: string, data?: Record<string, unknown>): void {
|
|
111
|
+
if (this.shouldLog('warn')) {
|
|
112
|
+
console.warn(this.format('warn', message, data))
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Error level logging
|
|
118
|
+
*/
|
|
119
|
+
error(message: string, data?: Record<string, unknown>): void {
|
|
120
|
+
if (this.shouldLog('error')) {
|
|
121
|
+
console.error(this.format('error', message, data))
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Success level logging
|
|
127
|
+
*/
|
|
128
|
+
success(message: string, data?: Record<string, unknown>): void {
|
|
129
|
+
if (this.shouldLog('success')) {
|
|
130
|
+
console.log(this.format('success', message, data))
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Plain output without formatting
|
|
136
|
+
*/
|
|
137
|
+
log(message: string): void {
|
|
138
|
+
if (!this.silent) {
|
|
139
|
+
console.log(message)
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Create a child logger with additional context
|
|
145
|
+
*/
|
|
146
|
+
child(context: string): Logger {
|
|
147
|
+
return new Logger({
|
|
148
|
+
level: this.level,
|
|
149
|
+
context: this.context ? `${this.context}:${context}` : context,
|
|
150
|
+
silent: this.silent,
|
|
151
|
+
colors: this.useColors,
|
|
152
|
+
})
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Create a spinner for long operations
|
|
157
|
+
*/
|
|
158
|
+
spinner(message: string): Spinner {
|
|
159
|
+
return new Spinner(message, this)
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Spinner for long-running operations
|
|
165
|
+
*/
|
|
166
|
+
export class Spinner {
|
|
167
|
+
private message: string
|
|
168
|
+
private logger: Logger
|
|
169
|
+
private frames = ['|', '/', '-', '\\']
|
|
170
|
+
private frameIndex = 0
|
|
171
|
+
private interval: ReturnType<typeof setInterval> | null = null
|
|
172
|
+
|
|
173
|
+
constructor(message: string, logger: Logger) {
|
|
174
|
+
this.message = message
|
|
175
|
+
this.logger = logger
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Start the spinner
|
|
180
|
+
*/
|
|
181
|
+
start(): void {
|
|
182
|
+
if (process.stdout.isTTY) {
|
|
183
|
+
this.interval = setInterval(() => {
|
|
184
|
+
process.stdout.write(`\r${colors.cyan}${this.frames[this.frameIndex]}${colors.reset} ${this.message}`)
|
|
185
|
+
this.frameIndex = (this.frameIndex + 1) % this.frames.length
|
|
186
|
+
}, 100)
|
|
187
|
+
} else {
|
|
188
|
+
this.logger.info(this.message)
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Stop the spinner with success
|
|
194
|
+
*/
|
|
195
|
+
succeed(message?: string): void {
|
|
196
|
+
this.stop()
|
|
197
|
+
this.logger.success(message ?? this.message)
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Stop the spinner with failure
|
|
202
|
+
*/
|
|
203
|
+
fail(message?: string): void {
|
|
204
|
+
this.stop()
|
|
205
|
+
this.logger.error(message ?? this.message)
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Stop the spinner
|
|
210
|
+
*/
|
|
211
|
+
stop(): void {
|
|
212
|
+
if (this.interval) {
|
|
213
|
+
clearInterval(this.interval)
|
|
214
|
+
this.interval = null
|
|
215
|
+
if (process.stdout.isTTY) {
|
|
216
|
+
process.stdout.write('\r' + ' '.repeat(this.message.length + 10) + '\r')
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Create a new logger instance
|
|
224
|
+
*/
|
|
225
|
+
export function createLogger(context?: string, options?: Omit<LoggerOptions, 'context'>): Logger {
|
|
226
|
+
return new Logger({ ...options, context })
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Default logger instance
|
|
231
|
+
*/
|
|
232
|
+
export const logger = createLogger('dotdo')
|
|
@@ -106,7 +106,7 @@ function parseJSON(text) {
|
|
|
106
106
|
}
|
|
107
107
|
// Try extracting from markdown code blocks
|
|
108
108
|
const codeBlockMatch = text.match(/```(?:json)?\s*([\s\S]*?)```/);
|
|
109
|
-
if (codeBlockMatch) {
|
|
109
|
+
if (codeBlockMatch?.[1]) {
|
|
110
110
|
try {
|
|
111
111
|
return JSON.parse(codeBlockMatch[1].trim());
|
|
112
112
|
}
|
|
@@ -116,7 +116,7 @@ function parseJSON(text) {
|
|
|
116
116
|
}
|
|
117
117
|
// Try extracting JSON object/array from text
|
|
118
118
|
const jsonMatch = text.match(/(\{[\s\S]*\}|\[[\s\S]*\])/);
|
|
119
|
-
if (jsonMatch) {
|
|
119
|
+
if (jsonMatch?.[1]) {
|
|
120
120
|
try {
|
|
121
121
|
return JSON.parse(jsonMatch[1]);
|
|
122
122
|
}
|