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.
Files changed (313) hide show
  1. package/cli/README.md +238 -0
  2. package/cli/agent.ts +72 -0
  3. package/cli/bin.js +44 -0
  4. package/cli/bin.ts +38 -0
  5. package/cli/build.ts +157 -0
  6. package/cli/commands/auth/login.ts +14 -0
  7. package/cli/commands/auth/logout.ts +6 -0
  8. package/cli/commands/auth/whoami.ts +16 -0
  9. package/cli/commands/deploy-multi.ts +245 -0
  10. package/cli/commands/dev/deploy.ts +100 -0
  11. package/cli/commands/dev/dev.ts +95 -0
  12. package/cli/commands/dev/logs.ts +91 -0
  13. package/cli/commands/dev-local.ts +88 -0
  14. package/cli/commands/do-ops.ts +314 -0
  15. package/cli/commands/index.ts +100 -0
  16. package/cli/commands/init.ts +247 -0
  17. package/cli/commands/introspect/emitter.ts +315 -0
  18. package/cli/commands/introspect/index.ts +193 -0
  19. package/cli/commands/link.ts +598 -0
  20. package/cli/commands/snippets.ts +415 -0
  21. package/cli/commands/tunnel.ts +239 -0
  22. package/cli/device-auth.ts +289 -0
  23. package/cli/fallback.ts +12 -0
  24. package/cli/index.ts +121 -0
  25. package/cli/main.ts +246 -0
  26. package/cli/mcp-stdio.ts +790 -0
  27. package/cli/package.json +62 -0
  28. package/cli/runtime/do-registry.ts +193 -0
  29. package/cli/runtime/embedded-db.ts +344 -0
  30. package/cli/runtime/index.ts +9 -0
  31. package/cli/runtime/miniflare-adapter.ts +162 -0
  32. package/cli/sandbox.ts +82 -0
  33. package/cli/src/args.ts +174 -0
  34. package/cli/src/auth.ts +55 -0
  35. package/cli/src/commands/call.ts +84 -0
  36. package/cli/src/commands/charge.ts +96 -0
  37. package/cli/src/commands/config.ts +115 -0
  38. package/cli/src/commands/email.ts +112 -0
  39. package/cli/src/commands/llm.ts +115 -0
  40. package/cli/src/commands/queue.ts +134 -0
  41. package/cli/src/commands/text.ts +86 -0
  42. package/cli/src/config.ts +185 -0
  43. package/cli/src/output.ts +246 -0
  44. package/cli/src/rpc.ts +192 -0
  45. package/cli/utils/config.ts +282 -0
  46. package/cli/utils/detect.ts +73 -0
  47. package/cli/utils/index.ts +15 -0
  48. package/cli/utils/logger.ts +232 -0
  49. package/dist/ai/template-literals.js +2 -2
  50. package/dist/ai/template-literals.js.map +1 -1
  51. package/dist/api/middleware/auth.js +3 -2
  52. package/dist/api/middleware/auth.js.map +1 -1
  53. package/dist/db/iceberg/inverted-index.js +1 -1
  54. package/dist/db/iceberg/inverted-index.js.map +1 -1
  55. package/dist/db/iceberg/puffin.js.map +1 -1
  56. package/dist/db/json-indexes.js.map +1 -1
  57. package/dist/db/objects.js.map +1 -1
  58. package/dist/db/primitives/dag-scheduler/index.js +1 -1
  59. package/dist/db/primitives/dag-scheduler/index.js.map +1 -1
  60. package/dist/db/primitives/observability.js.map +1 -1
  61. package/dist/db/primitives/schema-evolution.js.map +1 -1
  62. package/dist/db/primitives/temporal-store.js.map +1 -1
  63. package/dist/db/primitives/typed-column-store.js.map +1 -1
  64. package/dist/db/primitives/utils/duration.js.map +1 -1
  65. package/dist/db/primitives/utils/murmur3.js +12 -14
  66. package/dist/db/primitives/utils/murmur3.js.map +1 -1
  67. package/dist/db/primitives/window-manager.js.map +1 -1
  68. package/dist/db/stores.js.map +1 -1
  69. package/dist/db/things.js.map +1 -1
  70. package/dist/lib/DODispatcher.js +2 -2
  71. package/dist/lib/DODispatcher.js.map +1 -1
  72. package/dist/lib/auto-wiring.js.map +1 -1
  73. package/dist/lib/channels/email.js +1 -1
  74. package/dist/lib/channels/email.js.map +1 -1
  75. package/dist/lib/channels/slack-blockkit.js.map +1 -1
  76. package/dist/lib/cloudflare/ai.js +1 -1
  77. package/dist/lib/cloudflare/ai.js.map +1 -1
  78. package/dist/lib/cloudflare/kv.js +1 -1
  79. package/dist/lib/cloudflare/kv.js.map +1 -1
  80. package/dist/lib/cloudflare/r2.js +3 -3
  81. package/dist/lib/cloudflare/r2.js.map +1 -1
  82. package/dist/lib/cloudflare/vectorize.js.map +1 -1
  83. package/dist/lib/cloudflare/workflows.js.map +1 -1
  84. package/dist/lib/executors/AgenticFunctionExecutor.js.map +1 -1
  85. package/dist/lib/executors/CodeFunctionExecutor.js.map +1 -1
  86. package/dist/lib/executors/GenerativeFunctionExecutor.js.map +1 -1
  87. package/dist/lib/executors/HumanFunctionExecutor.js +1 -1
  88. package/dist/lib/executors/HumanFunctionExecutor.js.map +1 -1
  89. package/dist/lib/executors/ParallelStepExecutor.js.map +1 -1
  90. package/dist/lib/experiments.js.map +1 -1
  91. package/dist/lib/flags/store.js.map +1 -1
  92. package/dist/lib/functions/FunctionComposition.js.map +1 -1
  93. package/dist/lib/functions/FunctionMiddleware.js.map +1 -1
  94. package/dist/lib/functions/FunctionRegistry.js.map +1 -1
  95. package/dist/lib/humans/templates.js.map +1 -1
  96. package/dist/lib/identity.js +2 -2
  97. package/dist/lib/identity.js.map +1 -1
  98. package/dist/lib/logging/index.js.map +1 -1
  99. package/dist/lib/mixins/bash.js +1 -73
  100. package/dist/lib/mixins/bash.js.map +1 -1
  101. package/dist/lib/mixins/git.js +0 -5
  102. package/dist/lib/mixins/git.js.map +1 -1
  103. package/dist/lib/mixins/npm.js.map +1 -1
  104. package/dist/lib/noun-id.js.map +1 -1
  105. package/dist/lib/rate-limit/sliding-window.js.map +1 -1
  106. package/dist/lib/rpc/bindings.js.map +1 -1
  107. package/dist/lib/safe-stringify.js.map +1 -1
  108. package/dist/lib/sandbox/miniflare-sandbox.js.map +1 -1
  109. package/dist/lib/sqids.js.map +1 -1
  110. package/dist/lib/sql/adapters/node-sql-parser.js.map +1 -1
  111. package/dist/lib/sql/adapters/pgsql-parser.js +19 -18
  112. package/dist/lib/sql/adapters/pgsql-parser.js.map +1 -1
  113. package/dist/metrics/hunch.js.map +1 -1
  114. package/dist/objects/API.js +1 -1
  115. package/dist/objects/API.js.map +1 -1
  116. package/dist/objects/Agent.js.map +1 -1
  117. package/dist/objects/Browser.js.map +1 -1
  118. package/dist/objects/CLI.js.map +1 -1
  119. package/dist/objects/DOBase.js.map +1 -1
  120. package/dist/objects/DOCache.js +153 -0
  121. package/dist/objects/DOCache.js.map +1 -0
  122. package/dist/objects/DOFull.js.map +1 -1
  123. package/dist/objects/Entity.js.map +1 -1
  124. package/dist/objects/Human.js.map +1 -1
  125. package/dist/objects/IcebergMetadataDO.js.map +1 -1
  126. package/dist/objects/IntegrationsDO.js.map +1 -1
  127. package/dist/objects/ObservabilityBroadcaster.js.map +1 -1
  128. package/dist/objects/Package.js.map +1 -1
  129. package/dist/objects/Product.js +1 -1
  130. package/dist/objects/Product.js.map +1 -1
  131. package/dist/objects/SaaS.js.map +1 -1
  132. package/dist/objects/SandboxDO.js.map +1 -1
  133. package/dist/objects/Service.js.map +1 -1
  134. package/dist/objects/VectorShardDO.js +9 -7
  135. package/dist/objects/VectorShardDO.js.map +1 -1
  136. package/dist/objects/Workflow.js.map +1 -1
  137. package/dist/objects/WorkflowFactory.js.map +1 -1
  138. package/dist/objects/WorkflowRuntime.js.map +1 -1
  139. package/dist/objects/lifecycle/Branch.js.map +1 -1
  140. package/dist/objects/lifecycle/Clone.js +1 -1
  141. package/dist/objects/lifecycle/Clone.js.map +1 -1
  142. package/dist/objects/lifecycle/Compact.js.map +1 -1
  143. package/dist/objects/lifecycle/Shard.js.map +1 -1
  144. package/dist/objects/persistence/checkpoint-manager.js.map +1 -1
  145. package/dist/objects/persistence/migration-runner.js.map +1 -1
  146. package/dist/objects/persistence/replication-manager.js +2 -2
  147. package/dist/objects/persistence/replication-manager.js.map +1 -1
  148. package/dist/objects/persistence/tiered-storage-manager.js.map +1 -1
  149. package/dist/objects/persistence/wal-manager.js.map +1 -1
  150. package/dist/objects/transport/auth-layer.js.map +1 -1
  151. package/dist/objects/transport/chain.js.map +1 -1
  152. package/dist/objects/transport/mcp-server.js +7 -6
  153. package/dist/objects/transport/mcp-server.js.map +1 -1
  154. package/dist/objects/transport/rest-autowire.js +3 -2
  155. package/dist/objects/transport/rest-autowire.js.map +1 -1
  156. package/dist/objects/transport/rest-router.js.map +1 -1
  157. package/dist/objects/transport/rpc-server.js +18 -15
  158. package/dist/objects/transport/rpc-server.js.map +1 -1
  159. package/dist/objects/transport/shared.js +2 -1
  160. package/dist/objects/transport/shared.js.map +1 -1
  161. package/dist/snippets/artifacts-ingest.js.map +1 -1
  162. package/dist/snippets/artifacts-serve.js.map +1 -1
  163. package/dist/snippets/search.js.map +1 -1
  164. package/dist/workflows/ScheduleManager.js.map +1 -1
  165. package/dist/workflows/StepResultStorage.js.map +1 -1
  166. package/dist/workflows/WaitForEventManager.js.map +1 -1
  167. package/dist/workflows/compat/backends/cloudflare-workflows.js.map +1 -1
  168. package/dist/workflows/compat/inngest/index.js.map +1 -1
  169. package/dist/workflows/compat/qstash/index.js.map +1 -1
  170. package/dist/workflows/compat/temporal/client.js.map +1 -1
  171. package/dist/workflows/compat/temporal/index.js.map +1 -1
  172. package/dist/workflows/compat/trigger/index.js.map +1 -1
  173. package/dist/workflows/compat/utils/index.js.map +1 -1
  174. package/dist/workflows/context/correlation.js +2 -2
  175. package/dist/workflows/context/correlation.js.map +1 -1
  176. package/dist/workflows/context/experiment.js +1 -1
  177. package/dist/workflows/context/experiment.js.map +1 -1
  178. package/dist/workflows/context/flag.js +1 -1
  179. package/dist/workflows/context/flag.js.map +1 -1
  180. package/dist/workflows/context/measure.js +1 -1
  181. package/dist/workflows/context/measure.js.map +1 -1
  182. package/dist/workflows/context/rate-limit.js.map +1 -1
  183. package/dist/workflows/data/entity-events/entity-events.js.map +1 -1
  184. package/dist/workflows/data/experiment/index.js.map +1 -1
  185. package/dist/workflows/data/goal/context.js +1 -1
  186. package/dist/workflows/data/goal/context.js.map +1 -1
  187. package/dist/workflows/data/measure/index.js +1 -1
  188. package/dist/workflows/data/measure/index.js.map +1 -1
  189. package/dist/workflows/data/stream/index.js +10 -76
  190. package/dist/workflows/data/stream/index.js.map +1 -1
  191. package/dist/workflows/data/track/context.js.map +1 -1
  192. package/dist/workflows/data/view/context.js.map +1 -1
  193. package/dist/workflows/domain.js.map +1 -1
  194. package/dist/workflows/flags.js +1 -1
  195. package/dist/workflows/flags.js.map +1 -1
  196. package/dist/workflows/hash.js.map +1 -1
  197. package/dist/workflows/on.js +1 -1
  198. package/dist/workflows/on.js.map +1 -1
  199. package/dist/workflows/schedule-builder.js.map +1 -1
  200. package/dist/workflows/visibility/index.js +0 -2
  201. package/dist/workflows/visibility/index.js.map +1 -1
  202. package/dist/workflows/visibility/query-parser.js.map +1 -1
  203. package/package.json +18 -3
  204. package/dist/api/analytics/router.js +0 -601
  205. package/dist/api/analytics/router.js.map +0 -1
  206. package/dist/api/index.js +0 -158
  207. package/dist/api/index.js.map +0 -1
  208. package/dist/api/middleware/error-handling.js +0 -176
  209. package/dist/api/middleware/error-handling.js.map +0 -1
  210. package/dist/api/middleware/request-id.js +0 -21
  211. package/dist/api/middleware/request-id.js.map +0 -1
  212. package/dist/api/pages.js +0 -1180
  213. package/dist/api/pages.js.map +0 -1
  214. package/dist/api/routes/api.js +0 -612
  215. package/dist/api/routes/api.js.map +0 -1
  216. package/dist/api/routes/browsers.js +0 -471
  217. package/dist/api/routes/browsers.js.map +0 -1
  218. package/dist/api/routes/do.js +0 -188
  219. package/dist/api/routes/do.js.map +0 -1
  220. package/dist/api/routes/mcp.js +0 -459
  221. package/dist/api/routes/mcp.js.map +0 -1
  222. package/dist/api/routes/obs.js +0 -445
  223. package/dist/api/routes/obs.js.map +0 -1
  224. package/dist/api/routes/openapi.js +0 -794
  225. package/dist/api/routes/openapi.js.map +0 -1
  226. package/dist/api/routes/rpc.js +0 -1103
  227. package/dist/api/routes/rpc.js.map +0 -1
  228. package/dist/api/routes/sandboxes.js +0 -389
  229. package/dist/api/routes/sandboxes.js.map +0 -1
  230. package/dist/api/test-do.js +0 -38
  231. package/dist/api/test-do.js.map +0 -1
  232. package/dist/api/types.js +0 -11
  233. package/dist/api/types.js.map +0 -1
  234. package/dist/cli/bin.js +0 -2
  235. package/dist/cli/main.js +0 -52342
  236. package/dist/do/bash.js +0 -35
  237. package/dist/do/bash.js.map +0 -1
  238. package/dist/do/fs.js +0 -25
  239. package/dist/do/fs.js.map +0 -1
  240. package/dist/do/full.js +0 -61
  241. package/dist/do/full.js.map +0 -1
  242. package/dist/do/git.js +0 -28
  243. package/dist/do/git.js.map +0 -1
  244. package/dist/do/index.js +0 -52
  245. package/dist/do/index.js.map +0 -1
  246. package/dist/lib/agent/tools/bash.js +0 -336
  247. package/dist/lib/agent/tools/bash.js.map +0 -1
  248. package/dist/lib/agent/tools/edit.js +0 -157
  249. package/dist/lib/agent/tools/edit.js.map +0 -1
  250. package/dist/lib/agent/tools/glob.js +0 -137
  251. package/dist/lib/agent/tools/glob.js.map +0 -1
  252. package/dist/lib/agent/tools/grep.js +0 -315
  253. package/dist/lib/agent/tools/grep.js.map +0 -1
  254. package/dist/lib/agent/tools/index.js +0 -71
  255. package/dist/lib/agent/tools/index.js.map +0 -1
  256. package/dist/lib/agent/tools/read.js +0 -212
  257. package/dist/lib/agent/tools/read.js.map +0 -1
  258. package/dist/lib/agent/tools/types.js +0 -197
  259. package/dist/lib/agent/tools/types.js.map +0 -1
  260. package/dist/lib/agent/tools/write.js +0 -159
  261. package/dist/lib/agent/tools/write.js.map +0 -1
  262. package/dist/lib/mixins/index.js +0 -29
  263. package/dist/lib/mixins/index.js.map +0 -1
  264. package/dist/primitives/bashx/src/ast/analyze.js +0 -1472
  265. package/dist/primitives/bashx/src/ast/analyze.js.map +0 -1
  266. package/dist/primitives/bashx/src/ast/parser.js +0 -1488
  267. package/dist/primitives/bashx/src/ast/parser.js.map +0 -1
  268. package/dist/primitives/bashx/src/do/commands/crypto.js +0 -1954
  269. package/dist/primitives/bashx/src/do/commands/crypto.js.map +0 -1
  270. package/dist/primitives/bashx/src/do/commands/data-processing.js +0 -1812
  271. package/dist/primitives/bashx/src/do/commands/data-processing.js.map +0 -1
  272. package/dist/primitives/bashx/src/do/commands/extended-utils.js +0 -804
  273. package/dist/primitives/bashx/src/do/commands/extended-utils.js.map +0 -1
  274. package/dist/primitives/bashx/src/do/commands/math-control.js +0 -1122
  275. package/dist/primitives/bashx/src/do/commands/math-control.js.map +0 -1
  276. package/dist/primitives/bashx/src/do/commands/posix-utils.js +0 -1015
  277. package/dist/primitives/bashx/src/do/commands/posix-utils.js.map +0 -1
  278. package/dist/primitives/bashx/src/do/commands/system-utils.js +0 -687
  279. package/dist/primitives/bashx/src/do/commands/system-utils.js.map +0 -1
  280. package/dist/primitives/bashx/src/do/commands/test-command.js +0 -523
  281. package/dist/primitives/bashx/src/do/commands/test-command.js.map +0 -1
  282. package/dist/primitives/bashx/src/do/commands/text-processing.js +0 -1550
  283. package/dist/primitives/bashx/src/do/commands/text-processing.js.map +0 -1
  284. package/dist/primitives/bashx/src/do/container-executor.js +0 -429
  285. package/dist/primitives/bashx/src/do/container-executor.js.map +0 -1
  286. package/dist/primitives/bashx/src/do/index.js +0 -668
  287. package/dist/primitives/bashx/src/do/index.js.map +0 -1
  288. package/dist/primitives/bashx/src/do/tiered-executor.js +0 -2647
  289. package/dist/primitives/bashx/src/do/tiered-executor.js.map +0 -1
  290. package/dist/primitives/bashx/src/do/worker.js +0 -352
  291. package/dist/primitives/bashx/src/do/worker.js.map +0 -1
  292. package/dist/primitives/bashx/src/types.js +0 -10
  293. package/dist/primitives/bashx/src/types.js.map +0 -1
  294. package/dist/primitives/fsx/core/backend.js +0 -480
  295. package/dist/primitives/fsx/core/backend.js.map +0 -1
  296. package/dist/primitives/fsx/core/constants.js +0 -140
  297. package/dist/primitives/fsx/core/constants.js.map +0 -1
  298. package/dist/primitives/fsx/core/fsx.js +0 -1184
  299. package/dist/primitives/fsx/core/fsx.js.map +0 -1
  300. package/dist/primitives/fsx/core/glob/glob.js +0 -438
  301. package/dist/primitives/fsx/core/glob/glob.js.map +0 -1
  302. package/dist/primitives/fsx/core/glob/index.js +0 -8
  303. package/dist/primitives/fsx/core/glob/index.js.map +0 -1
  304. package/dist/primitives/fsx/core/glob/match.js +0 -392
  305. package/dist/primitives/fsx/core/glob/match.js.map +0 -1
  306. package/dist/primitives/fsx/core/types.js +0 -307
  307. package/dist/primitives/fsx/core/types.js.map +0 -1
  308. package/dist/sdk/capnweb-compat.js +0 -42
  309. package/dist/sdk/capnweb-compat.js.map +0 -1
  310. package/dist/sdk/client.js +0 -20
  311. package/dist/sdk/client.js.map +0 -1
  312. package/dist/sdk/index.js +0 -17
  313. package/dist/sdk/index.js.map +0 -1
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Config Command
3
+ *
4
+ * Manage CLI configuration
5
+ *
6
+ * Usage:
7
+ * do config get # Show all config
8
+ * do config get api_url # Show specific config value
9
+ * do config set json_output true # Set config value
10
+ * do config unset api_url # Remove config value
11
+ * do config list # List available config keys
12
+ */
13
+
14
+ import { parseArgs, requirePositional } from '../args'
15
+ import { getConfig, setConfig, unsetConfig, defaultConfig, configKeys, isValidConfigKey, parseConfigValue, type Config, type ConfigKey } from '../config'
16
+ import { formatJson, formatTable } from '../output'
17
+
18
+ // ============================================================================
19
+ // Subcommands
20
+ // ============================================================================
21
+
22
+ async function get(rawArgs: string[]): Promise<void> {
23
+ const args = parseArgs(rawArgs)
24
+ const key = args.positional[0] as ConfigKey | undefined
25
+
26
+ const config = await getConfig()
27
+
28
+ if (key) {
29
+ if (!isValidConfigKey(key)) {
30
+ throw new Error(`Unknown config key: ${key}. Run 'do config list' to see available keys.`)
31
+ }
32
+ const value = config[key] ?? defaultConfig[key as keyof typeof defaultConfig]
33
+ console.log(value)
34
+ } else {
35
+ // Show all config
36
+ console.log(formatJson(config, { pretty: true }))
37
+ }
38
+ }
39
+
40
+ async function set(rawArgs: string[]): Promise<void> {
41
+ const args = parseArgs(rawArgs)
42
+
43
+ const key = requirePositional(args, 0, 'config key')
44
+ const valueStr = requirePositional(args, 1, 'config value')
45
+
46
+ if (!isValidConfigKey(key)) {
47
+ throw new Error(`Unknown config key: ${key}. Run 'do config list' to see available keys.`)
48
+ }
49
+
50
+ const value = parseConfigValue(key, valueStr)
51
+ await setConfig({ [key]: value } as Partial<Config>)
52
+
53
+ console.log(`Set ${key} = ${JSON.stringify(value)}`)
54
+ }
55
+
56
+ async function unset(rawArgs: string[]): Promise<void> {
57
+ const args = parseArgs(rawArgs)
58
+
59
+ const key = requirePositional(args, 0, 'config key')
60
+
61
+ if (!isValidConfigKey(key)) {
62
+ throw new Error(`Unknown config key: ${key}. Run 'do config list' to see available keys.`)
63
+ }
64
+
65
+ await unsetConfig(key)
66
+ console.log(`Unset ${key}`)
67
+ }
68
+
69
+ async function list(_rawArgs: string[]): Promise<void> {
70
+ const descriptions: Record<ConfigKey, string> = {
71
+ api_url: 'Base API URL for rpc.do gateway',
72
+ json_output: 'Output JSON instead of human-readable format',
73
+ default_model: 'Default LLM model for llm command',
74
+ default_from: 'Default sender for calls/texts',
75
+ default_email_from: 'Default email sender',
76
+ default_currency: 'Default currency for charges',
77
+ custom_headers: 'Custom headers to include in all requests',
78
+ }
79
+
80
+ for (const key of configKeys) {
81
+ const desc = descriptions[key]
82
+ const defaultValue = defaultConfig[key as keyof typeof defaultConfig]
83
+ console.log(`${key}`)
84
+ console.log(` ${desc}`)
85
+ if (defaultValue !== undefined) {
86
+ console.log(` Default: ${JSON.stringify(defaultValue)}`)
87
+ }
88
+ console.log('')
89
+ }
90
+ }
91
+
92
+ // ============================================================================
93
+ // Command Router
94
+ // ============================================================================
95
+
96
+ export async function run(rawArgs: string[]): Promise<void> {
97
+ const [subcommand, ...restArgs] = rawArgs
98
+
99
+ switch (subcommand) {
100
+ case 'get':
101
+ return get(restArgs)
102
+ case 'set':
103
+ return set(restArgs)
104
+ case 'unset':
105
+ return unset(restArgs)
106
+ case 'list':
107
+ return list(restArgs)
108
+ default:
109
+ if (!subcommand) {
110
+ // Default to get (show all config)
111
+ return get([])
112
+ }
113
+ throw new Error(`Unknown subcommand: ${subcommand}. Available: get, set, unset, list`)
114
+ }
115
+ }
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Email Command
3
+ *
4
+ * Send emails via emails.do
5
+ *
6
+ * Usage:
7
+ * do email user@example.com --subject "Hello" --body "Hi there!"
8
+ * do email user@example.com --template welcome
9
+ * do email user@example.com --subject "Hi" --html "<h1>Hello</h1>"
10
+ * do email user@example.com --subject "Hi" --from noreply@company.com
11
+ * do email user@example.com --template welcome --json
12
+ */
13
+
14
+ import { parseArgs, requirePositional, getStringFlag, getBooleanFlag, isValidEmail } from '../args'
15
+ import { emailsRequest } from '../rpc'
16
+ import { formatJson } from '../output'
17
+ import { getConfig } from '../config'
18
+
19
+ // ============================================================================
20
+ // Types
21
+ // ============================================================================
22
+
23
+ interface EmailRequest {
24
+ to: string
25
+ from?: string
26
+ subject?: string
27
+ text?: string
28
+ html?: string
29
+ template?: string
30
+ variables?: Record<string, unknown>
31
+ }
32
+
33
+ interface EmailResponse {
34
+ email_id: string
35
+ status: string
36
+ }
37
+
38
+ // ============================================================================
39
+ // Command
40
+ // ============================================================================
41
+
42
+ export async function run(rawArgs: string[]): Promise<void> {
43
+ const args = parseArgs(rawArgs)
44
+
45
+ // Validate required arguments
46
+ const to = requirePositional(args, 0, 'email address')
47
+
48
+ if (!isValidEmail(to)) {
49
+ throw new Error(`Invalid email address format`)
50
+ }
51
+
52
+ // Build request
53
+ const request: EmailRequest = {
54
+ to,
55
+ }
56
+
57
+ const from = getStringFlag(args, 'from')
58
+ if (from) {
59
+ if (!isValidEmail(from)) {
60
+ throw new Error(`Invalid --from email address format`)
61
+ }
62
+ request.from = from
63
+ }
64
+
65
+ const subject = getStringFlag(args, 'subject')
66
+ if (subject) {
67
+ request.subject = subject
68
+ }
69
+
70
+ const body = getStringFlag(args, 'body')
71
+ if (body) {
72
+ request.text = body
73
+ }
74
+
75
+ const html = getStringFlag(args, 'html')
76
+ if (html) {
77
+ request.html = html
78
+ }
79
+
80
+ const template = getStringFlag(args, 'template')
81
+ if (template) {
82
+ request.template = template
83
+ }
84
+
85
+ const variables = getStringFlag(args, 'variables')
86
+ if (variables) {
87
+ try {
88
+ request.variables = JSON.parse(variables)
89
+ } catch {
90
+ throw new Error(`Invalid --variables: expected valid JSON`)
91
+ }
92
+ }
93
+
94
+ // Make request
95
+ const response = await emailsRequest<EmailResponse>('/emails', {
96
+ method: 'POST',
97
+ body: request,
98
+ })
99
+
100
+ // Output result
101
+ const config = await getConfig()
102
+ const jsonOutput = getBooleanFlag(args, 'json') || config.json_output
103
+
104
+ if (jsonOutput) {
105
+ console.log(formatJson(response))
106
+ } else {
107
+ console.log(`Email sent: ${response.email_id}`)
108
+ if (response.status) {
109
+ console.log(`Status: ${response.status}`)
110
+ }
111
+ }
112
+ }
@@ -0,0 +1,115 @@
1
+ /**
2
+ * LLM Command
3
+ *
4
+ * Make LLM requests via llm.do (with streaming)
5
+ *
6
+ * Usage:
7
+ * do llm "Summarize this document"
8
+ * do llm "Hello" --model claude-sonnet
9
+ * do llm "Hello" --system "You are a helpful assistant"
10
+ * do llm "Hello" --max-tokens 100
11
+ * do llm "Hello" --temperature 0.7
12
+ * do llm "Hello" --no-stream
13
+ * do llm "Hello" --json
14
+ */
15
+
16
+ import { parseArgs, requirePositional, getStringFlag, getBooleanFlag, getNumberFlag } from '../args'
17
+ import { llmRequest } from '../rpc'
18
+ import { formatJson, parseSSEStream } from '../output'
19
+ import { getConfig } from '../config'
20
+
21
+ // ============================================================================
22
+ // Types
23
+ // ============================================================================
24
+
25
+ interface LLMRequest {
26
+ prompt: string
27
+ model?: string
28
+ system?: string
29
+ max_tokens?: number
30
+ temperature?: number
31
+ stream?: boolean
32
+ }
33
+
34
+ interface LLMResponse {
35
+ response: string
36
+ model?: string
37
+ usage?: {
38
+ prompt_tokens: number
39
+ completion_tokens: number
40
+ total_tokens: number
41
+ }
42
+ }
43
+
44
+ // ============================================================================
45
+ // Command
46
+ // ============================================================================
47
+
48
+ export async function run(rawArgs: string[]): Promise<void> {
49
+ const args = parseArgs(rawArgs)
50
+
51
+ // Validate required arguments
52
+ const prompt = requirePositional(args, 0, 'prompt')
53
+
54
+ // Build request
55
+ const config = await getConfig()
56
+ // --no-stream sets flags['stream'] = false, so check for that
57
+ const streamFlag = args.flags['stream']
58
+ const stream = streamFlag !== false
59
+
60
+ const request: LLMRequest = {
61
+ prompt,
62
+ stream,
63
+ }
64
+
65
+ const model = getStringFlag(args, 'model') ?? config.default_model
66
+ if (model) {
67
+ request.model = model
68
+ }
69
+
70
+ const system = getStringFlag(args, 'system')
71
+ if (system) {
72
+ request.system = system
73
+ }
74
+
75
+ const maxTokens = getNumberFlag(args, 'max-tokens')
76
+ if (maxTokens !== undefined) {
77
+ request.max_tokens = maxTokens
78
+ }
79
+
80
+ const temperature = getNumberFlag(args, 'temperature')
81
+ if (temperature !== undefined) {
82
+ request.temperature = temperature
83
+ }
84
+
85
+ // Handle streaming
86
+ if (stream) {
87
+ const responseStream = await llmRequest<ReadableStream<Uint8Array>>('/completions', {
88
+ method: 'POST',
89
+ body: request,
90
+ stream: true,
91
+ })
92
+
93
+ // Stream output to stdout
94
+ for await (const chunk of parseSSEStream(responseStream)) {
95
+ process.stdout.write(chunk)
96
+ }
97
+ process.stdout.write('\n')
98
+ return
99
+ }
100
+
101
+ // Non-streaming request
102
+ const response = await llmRequest<LLMResponse>('/completions', {
103
+ method: 'POST',
104
+ body: request,
105
+ })
106
+
107
+ // Output result
108
+ const jsonOutput = getBooleanFlag(args, 'json') || config.json_output
109
+
110
+ if (jsonOutput) {
111
+ console.log(formatJson(response))
112
+ } else {
113
+ console.log(response.response)
114
+ }
115
+ }
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Queue Command
3
+ *
4
+ * Queue operations via queue.do
5
+ *
6
+ * Usage:
7
+ * do queue publish my-queue '{"event": "user.signup"}'
8
+ * do queue publish my-queue '{}' --delay 60
9
+ * do queue publish my-queue '<xml>data</xml>' --content-type application/xml
10
+ * do queue list
11
+ * do queue list --json
12
+ */
13
+
14
+ import { parseArgs, requirePositional, getStringFlag, getBooleanFlag, getNumberFlag } from '../args'
15
+ import { queueRequest } from '../rpc'
16
+ import { formatJson, formatTable } from '../output'
17
+ import { getConfig } from '../config'
18
+
19
+ // ============================================================================
20
+ // Types
21
+ // ============================================================================
22
+
23
+ interface PublishResponse {
24
+ message_id: string
25
+ status: string
26
+ }
27
+
28
+ interface QueueInfo {
29
+ name: string
30
+ messages: number
31
+ consumers?: number
32
+ }
33
+
34
+ interface ListQueuesResponse {
35
+ queues: QueueInfo[]
36
+ }
37
+
38
+ // ============================================================================
39
+ // Subcommands
40
+ // ============================================================================
41
+
42
+ async function publish(rawArgs: string[]): Promise<void> {
43
+ const args = parseArgs(rawArgs)
44
+
45
+ // Validate required arguments
46
+ const queueName = requirePositional(args, 0, 'queue name')
47
+ const messageBody = requirePositional(args, 1, 'message body')
48
+
49
+ // Parse message body
50
+ let body: unknown
51
+ const contentType = getStringFlag(args, 'content-type') ?? 'application/json'
52
+
53
+ if (contentType === 'application/json') {
54
+ try {
55
+ body = JSON.parse(messageBody)
56
+ } catch {
57
+ throw new Error(`Invalid message body: expected valid JSON`)
58
+ }
59
+ } else {
60
+ body = messageBody
61
+ }
62
+
63
+ // Build headers
64
+ const headers: Record<string, string> = {
65
+ 'Content-Type': contentType,
66
+ }
67
+
68
+ const delay = getNumberFlag(args, 'delay')
69
+ if (delay !== undefined) {
70
+ headers['X-Delay'] = String(delay)
71
+ }
72
+
73
+ // Make request
74
+ const response = await queueRequest<PublishResponse>(`/queues/${encodeURIComponent(queueName)}/messages`, {
75
+ method: 'POST',
76
+ body,
77
+ headers,
78
+ })
79
+
80
+ // Output result
81
+ const config = await getConfig()
82
+ const jsonOutput = getBooleanFlag(args, 'json') || config.json_output
83
+
84
+ if (jsonOutput) {
85
+ console.log(formatJson(response))
86
+ } else {
87
+ console.log(`Message published: ${response.message_id}`)
88
+ if (response.status) {
89
+ console.log(`Status: ${response.status}`)
90
+ }
91
+ }
92
+ }
93
+
94
+ async function list(rawArgs: string[]): Promise<void> {
95
+ const args = parseArgs(rawArgs)
96
+
97
+ // Make request
98
+ const response = await queueRequest<ListQueuesResponse>('/queues', {
99
+ method: 'GET',
100
+ })
101
+
102
+ // Output result
103
+ const config = await getConfig()
104
+ const jsonOutput = getBooleanFlag(args, 'json') || config.json_output
105
+
106
+ if (jsonOutput) {
107
+ console.log(formatJson(response))
108
+ } else if (response.queues.length === 0) {
109
+ console.log('No queues found')
110
+ } else {
111
+ // Cast to Record<string, unknown>[] for formatTable
112
+ console.log(formatTable(response.queues as unknown as Record<string, unknown>[]))
113
+ }
114
+ }
115
+
116
+ // ============================================================================
117
+ // Command Router
118
+ // ============================================================================
119
+
120
+ export async function run(rawArgs: string[]): Promise<void> {
121
+ const [subcommand, ...restArgs] = rawArgs
122
+
123
+ switch (subcommand) {
124
+ case 'publish':
125
+ return publish(restArgs)
126
+ case 'list':
127
+ return list(restArgs)
128
+ default:
129
+ if (!subcommand) {
130
+ throw new Error(`Missing subcommand. Usage: do queue <publish|list>`)
131
+ }
132
+ throw new Error(`Unknown subcommand: ${subcommand}. Available: publish, list`)
133
+ }
134
+ }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Text Command
3
+ *
4
+ * Send SMS/MMS via texts.do
5
+ *
6
+ * Usage:
7
+ * do text +15551234567 "Reply YES to confirm"
8
+ * do text +15551234567 "Hello" --from +15559876543
9
+ * do text +15551234567 "Check this out" --media-url https://example.com/image.jpg
10
+ * do text +15551234567 "Hello" --json
11
+ */
12
+
13
+ import { parseArgs, requirePositional, getStringFlag, getBooleanFlag, isValidPhoneNumber } from '../args'
14
+ import { textsRequest } from '../rpc'
15
+ import { formatJson } from '../output'
16
+ import { getConfig } from '../config'
17
+
18
+ // ============================================================================
19
+ // Types
20
+ // ============================================================================
21
+
22
+ interface TextRequest {
23
+ to: string
24
+ body: string
25
+ from?: string
26
+ media_url?: string
27
+ }
28
+
29
+ interface TextResponse {
30
+ message_id: string
31
+ status: string
32
+ }
33
+
34
+ // ============================================================================
35
+ // Command
36
+ // ============================================================================
37
+
38
+ export async function run(rawArgs: string[]): Promise<void> {
39
+ const args = parseArgs(rawArgs)
40
+
41
+ // Validate required arguments
42
+ const to = requirePositional(args, 0, 'phone number')
43
+ const body = requirePositional(args, 1, 'message')
44
+
45
+ if (!isValidPhoneNumber(to)) {
46
+ throw new Error(`Invalid phone number format. Use E.164 format (e.g., +15551234567)`)
47
+ }
48
+
49
+ // Build request
50
+ const request: TextRequest = {
51
+ to,
52
+ body,
53
+ }
54
+
55
+ const from = getStringFlag(args, 'from')
56
+ if (from) {
57
+ if (!isValidPhoneNumber(from)) {
58
+ throw new Error(`Invalid --from phone number format. Use E.164 format (e.g., +15551234567)`)
59
+ }
60
+ request.from = from
61
+ }
62
+
63
+ const mediaUrl = getStringFlag(args, 'media-url')
64
+ if (mediaUrl) {
65
+ request.media_url = mediaUrl
66
+ }
67
+
68
+ // Make request
69
+ const response = await textsRequest<TextResponse>('/messages', {
70
+ method: 'POST',
71
+ body: request,
72
+ })
73
+
74
+ // Output result
75
+ const config = await getConfig()
76
+ const jsonOutput = getBooleanFlag(args, 'json') || config.json_output
77
+
78
+ if (jsonOutput) {
79
+ console.log(formatJson(response))
80
+ } else {
81
+ console.log(`Message sent: ${response.message_id}`)
82
+ if (response.status) {
83
+ console.log(`Status: ${response.status}`)
84
+ }
85
+ }
86
+ }