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,315 @@
1
+ /**
2
+ * Type Emitter - Generate .do/types.d.ts from schemas
3
+ *
4
+ * Converts MdxSchema and DOSchema into TypeScript declaration files.
5
+ */
6
+
7
+ import type { MdxSchema, MdxEntity } from '../../../db/schema/mdx'
8
+ import type { DOSchema, DOClassSchema } from '../../../types/introspect'
9
+
10
+ export interface TypeEmitterOptions {
11
+ /** Include JSDoc comments */
12
+ includeComments?: boolean
13
+ /** Module name for declare module */
14
+ moduleName?: string
15
+ }
16
+
17
+ export interface EmittedTypes {
18
+ /** The generated .d.ts content */
19
+ content: string
20
+ /** Entity names found */
21
+ entities: string[]
22
+ /** Method signatures found */
23
+ methods: string[]
24
+ /** Event types found */
25
+ events: string[]
26
+ }
27
+
28
+ /**
29
+ * Convert MDX field type to TypeScript type
30
+ */
31
+ function mdxTypeToTs(type: string): string {
32
+ // Handle array types [->Type]
33
+ if (type.startsWith('[') && type.endsWith(']')) {
34
+ const inner = type.slice(1, -1)
35
+ return `${mdxTypeToTs(inner)}[]`
36
+ }
37
+
38
+ // Handle relationship operators
39
+ const operators = ['->', '~>', '<-', '<~']
40
+ for (const op of operators) {
41
+ if (type.startsWith(op)) {
42
+ return type.slice(op.length)
43
+ }
44
+ }
45
+
46
+ // Handle code blocks
47
+ if (type.startsWith('`') && type.endsWith('`')) {
48
+ return mdxTypeToTs(type.slice(1, -1))
49
+ }
50
+
51
+ // Primitive mappings
52
+ const primitives: Record<string, string> = {
53
+ string: 'string',
54
+ number: 'number',
55
+ boolean: 'boolean',
56
+ Date: 'Date',
57
+ date: 'Date',
58
+ any: 'unknown',
59
+ object: 'Record<string, unknown>',
60
+ }
61
+
62
+ return primitives[type] || type
63
+ }
64
+
65
+ /**
66
+ * Generate entity interface from MdxEntity
67
+ */
68
+ function emitEntityInterface(name: string, entity: MdxEntity, includeComments: boolean): string {
69
+ const lines: string[] = []
70
+
71
+ if (includeComments && entity.description) {
72
+ lines.push(` /** ${entity.description} */`)
73
+ }
74
+
75
+ lines.push(` export interface ${name} {`)
76
+ lines.push(` id: string`)
77
+
78
+ for (const [fieldName, field] of Object.entries(entity.fields)) {
79
+ const tsType = mdxTypeToTs(field.type)
80
+ if (includeComments && field.description) {
81
+ lines.push(` /** ${field.description} */`)
82
+ }
83
+ lines.push(` ${fieldName}: ${tsType}`)
84
+ }
85
+
86
+ lines.push(` }`)
87
+
88
+ return lines.join('\n')
89
+ }
90
+
91
+ /**
92
+ * Generate state union type
93
+ */
94
+ function emitStateType(name: string, states: string[]): string {
95
+ const stateUnion = states.map((s) => `'${s}'`).join(' | ')
96
+ return ` export type ${name}State = ${stateUnion}`
97
+ }
98
+
99
+ /**
100
+ * Generate event type
101
+ */
102
+ function emitEventType(entityName: string, events: string[]): string {
103
+ const lines: string[] = []
104
+ for (const event of events) {
105
+ // Parse event like "Customer.signup" or just "signup"
106
+ const [noun, verb] = event.includes('.') ? event.split('.') : [entityName, event]
107
+ lines.push(` '${noun}.${verb}': { ${noun.toLowerCase()}: ${noun} }`)
108
+ }
109
+ return lines.join('\n')
110
+ }
111
+
112
+ /**
113
+ * Emit types from MDX schema
114
+ */
115
+ export function emitFromMdxSchema(schema: MdxSchema, options: TypeEmitterOptions = {}): EmittedTypes {
116
+ const { includeComments = true, moduleName = '@dotdo/client' } = options
117
+
118
+ const entities: string[] = []
119
+ const events: string[] = []
120
+ const entityBlocks: string[] = []
121
+ const stateBlocks: string[] = []
122
+ const eventLines: string[] = []
123
+
124
+ for (const [name, entity] of Object.entries(schema.entities)) {
125
+ entities.push(name)
126
+ entityBlocks.push(emitEntityInterface(name, entity, includeComments))
127
+
128
+ if (entity.states && entity.states.length > 0) {
129
+ stateBlocks.push(emitStateType(name, entity.states))
130
+ }
131
+
132
+ if (entity.events && entity.events.length > 0) {
133
+ events.push(...entity.events)
134
+ eventLines.push(emitEventType(name, entity.events))
135
+ }
136
+ }
137
+
138
+ const content = `// Auto-generated by dotdo introspect
139
+ // Source: ${schema.source}
140
+ // Do not edit manually
141
+
142
+ declare module '${moduleName}' {
143
+ // ============================================================================
144
+ // ENTITIES
145
+ // ============================================================================
146
+
147
+ ${entityBlocks.join('\n\n')}
148
+
149
+ // ============================================================================
150
+ // STATE TYPES
151
+ // ============================================================================
152
+
153
+ ${stateBlocks.join('\n\n') || ' // No state types defined'}
154
+
155
+ // ============================================================================
156
+ // ENTITY REGISTRY
157
+ // ============================================================================
158
+
159
+ export interface Entities {
160
+ ${entities.map((e) => ` ${e}: ${e}`).join('\n')}
161
+ }
162
+
163
+ // ============================================================================
164
+ // EVENTS
165
+ // ============================================================================
166
+
167
+ export interface Events {
168
+ ${eventLines.join('\n') || ' // No events defined'}
169
+ }
170
+ }
171
+ `
172
+
173
+ return {
174
+ content,
175
+ entities,
176
+ methods: [],
177
+ events,
178
+ }
179
+ }
180
+
181
+ /**
182
+ * Emit types from DOSchema (runtime introspection)
183
+ */
184
+ export function emitFromDOSchema(schema: DOSchema, options: TypeEmitterOptions = {}): EmittedTypes {
185
+ const { includeComments = true, moduleName = '@dotdo/client' } = options
186
+
187
+ const entities: string[] = []
188
+ const methods: string[] = []
189
+ const classBlocks: string[] = []
190
+ const methodLines: string[] = []
191
+
192
+ for (const cls of schema.classes) {
193
+ entities.push(cls.name)
194
+ classBlocks.push(emitDOClassInterface(cls, includeComments))
195
+
196
+ // Extract methods from tools
197
+ for (const tool of cls.tools) {
198
+ const methodName = `${cls.name}.${tool.name}`
199
+ methods.push(methodName)
200
+ methodLines.push(` '${methodName}': (input: unknown) => Promise<unknown>`)
201
+ }
202
+ }
203
+
204
+ const content = `// Auto-generated by dotdo introspect
205
+ // Namespace: ${schema.ns}
206
+ // Do not edit manually
207
+
208
+ declare module '${moduleName}' {
209
+ // ============================================================================
210
+ // DO CLASSES
211
+ // ============================================================================
212
+
213
+ ${classBlocks.join('\n\n')}
214
+
215
+ // ============================================================================
216
+ // METHODS
217
+ // ============================================================================
218
+
219
+ export interface Methods {
220
+ ${methodLines.join('\n') || ' // No methods defined'}
221
+ }
222
+
223
+ // ============================================================================
224
+ // NOUNS
225
+ // ============================================================================
226
+
227
+ export interface Nouns {
228
+ ${schema.nouns.map((n) => ` ${n.noun}: { singular: '${n.noun}', plural: '${n.plural}' }`).join('\n')}
229
+ }
230
+ }
231
+ `
232
+
233
+ return {
234
+ content,
235
+ entities,
236
+ methods,
237
+ events: [],
238
+ }
239
+ }
240
+
241
+ /**
242
+ * Emit DO class interface
243
+ */
244
+ function emitDOClassInterface(cls: DOClassSchema, includeComments: boolean): string {
245
+ const lines: string[] = []
246
+
247
+ if (includeComments) {
248
+ lines.push(` /** DO Class: ${cls.name} (${cls.type}) */`)
249
+ }
250
+
251
+ lines.push(` export interface ${cls.name} {`)
252
+ lines.push(` id: string`)
253
+
254
+ for (const prop of cls.properties) {
255
+ if (includeComments && prop.description) {
256
+ lines.push(` /** ${prop.description} */`)
257
+ }
258
+ const required = prop.required !== false ? '' : '?'
259
+ lines.push(` ${prop.name}${required}: ${prop.type}`)
260
+ }
261
+
262
+ lines.push(` }`)
263
+
264
+ return lines.join('\n')
265
+ }
266
+
267
+ /**
268
+ * Merge multiple EmittedTypes into one
269
+ */
270
+ export function mergeEmittedTypes(types: EmittedTypes[], moduleName = '@dotdo/client'): string {
271
+ const allEntities = new Set<string>()
272
+ const allMethods = new Set<string>()
273
+ const allEvents = new Set<string>()
274
+ const entityBlocks: string[] = []
275
+ const methodLines: string[] = []
276
+ const eventLines: string[] = []
277
+
278
+ for (const t of types) {
279
+ for (const e of t.entities) allEntities.add(e)
280
+ for (const m of t.methods) allMethods.add(m)
281
+ for (const ev of t.events) allEvents.add(ev)
282
+ }
283
+
284
+ // Extract entity blocks from content (simplified)
285
+ for (const t of types) {
286
+ const match = t.content.match(/\/\/ ENTITIES[\s\S]*?(export interface \w+[\s\S]*?})/g)
287
+ if (match) {
288
+ entityBlocks.push(...match)
289
+ }
290
+ }
291
+
292
+ return `// Auto-generated by dotdo introspect
293
+ // Do not edit manually
294
+
295
+ declare module '${moduleName}' {
296
+ export interface Entities {
297
+ ${Array.from(allEntities)
298
+ .map((e) => ` ${e}: ${e}`)
299
+ .join('\n')}
300
+ }
301
+
302
+ export interface Methods {
303
+ ${Array.from(allMethods)
304
+ .map((m) => ` '${m}': (...args: unknown[]) => Promise<unknown>`)
305
+ .join('\n')}
306
+ }
307
+
308
+ export interface Events {
309
+ ${Array.from(allEvents)
310
+ .map((e) => ` '${e}': unknown`)
311
+ .join('\n')}
312
+ }
313
+ }
314
+ `
315
+ }
@@ -0,0 +1,193 @@
1
+ /**
2
+ * dotdo introspect - Generate .do/types.d.ts from schemas
3
+ *
4
+ * Usage:
5
+ * dotdo introspect Generate types
6
+ * dotdo introspect --watch Watch mode
7
+ * dotdo introspect --check Validate only (no write)
8
+ * dotdo introspect --out <path> Custom output path
9
+ */
10
+
11
+ import { existsSync, mkdirSync, writeFileSync, readFileSync, watch } from 'node:fs'
12
+ import { join, dirname, resolve } from 'node:path'
13
+ import { loadAndMergeSchemas } from '../../../db/schema/mdx'
14
+ import { emitFromMdxSchema, mergeEmittedTypes, type EmittedTypes } from './emitter'
15
+
16
+ export interface IntrospectOptions {
17
+ /** Project root directory */
18
+ root?: string
19
+ /** Output file path */
20
+ out?: string
21
+ /** Watch mode */
22
+ watch?: boolean
23
+ /** Check only (no write) */
24
+ check?: boolean
25
+ /** Verbose output */
26
+ verbose?: boolean
27
+ }
28
+
29
+ const DEFAULT_OUTPUT = '.do/types.d.ts'
30
+
31
+ /**
32
+ * Parse CLI arguments into options
33
+ */
34
+ function parseArgs(args: string[]): IntrospectOptions {
35
+ const options: IntrospectOptions = {}
36
+
37
+ for (let i = 0; i < args.length; i++) {
38
+ const arg = args[i]
39
+
40
+ if (arg === '--watch' || arg === '-w') {
41
+ options.watch = true
42
+ } else if (arg === '--check' || arg === '-c') {
43
+ options.check = true
44
+ } else if (arg === '--verbose' || arg === '-v') {
45
+ options.verbose = true
46
+ } else if (arg === '--out' || arg === '-o') {
47
+ options.out = args[++i]
48
+ } else if (arg === '--root' || arg === '-r') {
49
+ options.root = args[++i]
50
+ } else if (!arg.startsWith('-')) {
51
+ // Positional arg = root directory
52
+ options.root = arg
53
+ }
54
+ }
55
+
56
+ return options
57
+ }
58
+
59
+ /**
60
+ * Generate types from project schemas
61
+ */
62
+ async function generateTypes(options: IntrospectOptions): Promise<EmittedTypes | null> {
63
+ const root = resolve(options.root || process.cwd())
64
+ const outPath = options.out || join(root, DEFAULT_OUTPUT)
65
+
66
+ if (options.verbose) {
67
+ console.log(`šŸ“ Scanning: ${root}`)
68
+ }
69
+
70
+ // Load and merge all schema files
71
+ const merged = await loadAndMergeSchemas(root)
72
+
73
+ if (Object.keys(merged.entities).length === 0) {
74
+ console.log('āš ļø No schemas found. Create a DB.mdx file to get started.')
75
+ return null
76
+ }
77
+
78
+ // Emit types
79
+ const emitted = emitFromMdxSchema(
80
+ {
81
+ entities: merged.entities,
82
+ source: merged.sources.join(', '),
83
+ },
84
+ { includeComments: true },
85
+ )
86
+
87
+ if (options.verbose) {
88
+ console.log(`šŸ“¦ Found ${emitted.entities.length} entities:`)
89
+ for (const e of emitted.entities) {
90
+ console.log(` - ${e}`)
91
+ }
92
+ }
93
+
94
+ if (options.check) {
95
+ // Check mode - compare with existing
96
+ if (existsSync(outPath)) {
97
+ const existing = readFileSync(outPath, 'utf-8')
98
+ if (existing === emitted.content) {
99
+ console.log('āœ… Types are up to date')
100
+ return emitted
101
+ } else {
102
+ console.log('āŒ Types are out of date. Run `dotdo introspect` to update.')
103
+ process.exitCode = 1
104
+ return emitted
105
+ }
106
+ } else {
107
+ console.log(`āŒ Types file not found: ${outPath}`)
108
+ process.exitCode = 1
109
+ return emitted
110
+ }
111
+ }
112
+
113
+ // Write types file
114
+ const outDir = dirname(outPath)
115
+ if (!existsSync(outDir)) {
116
+ mkdirSync(outDir, { recursive: true })
117
+ }
118
+
119
+ writeFileSync(outPath, emitted.content, 'utf-8')
120
+ console.log(`āœ… Generated ${outPath}`)
121
+ console.log(` ${emitted.entities.length} entities, ${emitted.events.length} events`)
122
+
123
+ return emitted
124
+ }
125
+
126
+ /**
127
+ * Watch mode - regenerate on file changes
128
+ */
129
+ async function watchMode(options: IntrospectOptions): Promise<void> {
130
+ const root = resolve(options.root || process.cwd())
131
+
132
+ console.log(`šŸ‘€ Watching for changes in ${root}...`)
133
+
134
+ // Initial generation
135
+ await generateTypes(options)
136
+
137
+ // Watch for changes
138
+ const watcher = watch(root, { recursive: true }, async (eventType, filename) => {
139
+ if (!filename) return
140
+
141
+ // Only watch MDX files
142
+ if (filename.endsWith('.mdx') || filename.endsWith('.do.mdx')) {
143
+ console.log(`\nšŸ“ Changed: ${filename}`)
144
+ await generateTypes({ ...options, verbose: false })
145
+ }
146
+ })
147
+
148
+ // Keep process running
149
+ process.on('SIGINT', () => {
150
+ watcher.close()
151
+ console.log('\nšŸ‘‹ Stopped watching')
152
+ process.exit(0)
153
+ })
154
+ }
155
+
156
+ /**
157
+ * Main command handler
158
+ */
159
+ export async function run(args: string[]): Promise<void> {
160
+ const options = parseArgs(args)
161
+
162
+ // Show help
163
+ if (args.includes('--help') || args.includes('-h')) {
164
+ console.log(`
165
+ Usage: dotdo introspect [options] [root]
166
+
167
+ Generate TypeScript types from DB.mdx schema files.
168
+
169
+ Options:
170
+ -o, --out <path> Output path (default: .do/types.d.ts)
171
+ -w, --watch Watch mode - regenerate on changes
172
+ -c, --check Check if types are up to date (CI mode)
173
+ -v, --verbose Verbose output
174
+ -r, --root <path> Project root directory
175
+ -h, --help Show this help
176
+
177
+ Examples:
178
+ dotdo introspect Generate types
179
+ dotdo introspect --watch Watch mode
180
+ dotdo introspect --check CI validation
181
+ dotdo introspect --out types.d.ts Custom output
182
+ `)
183
+ return
184
+ }
185
+
186
+ if (options.watch) {
187
+ await watchMode(options)
188
+ } else {
189
+ await generateTypes(options)
190
+ }
191
+ }
192
+
193
+ export { emitFromMdxSchema, emitFromDOSchema, mergeEmittedTypes } from './emitter'