0pflow 0.1.0-dev.00aaa03

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 (197) hide show
  1. package/dist/__tests__/agent-parser.test.d.ts +2 -0
  2. package/dist/__tests__/agent-parser.test.d.ts.map +1 -0
  3. package/dist/__tests__/agent-parser.test.js +64 -0
  4. package/dist/__tests__/agent-parser.test.js.map +1 -0
  5. package/dist/__tests__/agent.e2e.test.d.ts +2 -0
  6. package/dist/__tests__/agent.e2e.test.d.ts.map +1 -0
  7. package/dist/__tests__/agent.e2e.test.js +90 -0
  8. package/dist/__tests__/agent.e2e.test.js.map +1 -0
  9. package/dist/__tests__/agent.test.d.ts +2 -0
  10. package/dist/__tests__/agent.test.d.ts.map +1 -0
  11. package/dist/__tests__/agent.test.js +30 -0
  12. package/dist/__tests__/agent.test.js.map +1 -0
  13. package/dist/__tests__/context.test.d.ts +2 -0
  14. package/dist/__tests__/context.test.d.ts.map +1 -0
  15. package/dist/__tests__/context.test.js +53 -0
  16. package/dist/__tests__/context.test.js.map +1 -0
  17. package/dist/__tests__/dbos.test.d.ts +2 -0
  18. package/dist/__tests__/dbos.test.d.ts.map +1 -0
  19. package/dist/__tests__/dbos.test.js +35 -0
  20. package/dist/__tests__/dbos.test.js.map +1 -0
  21. package/dist/__tests__/factory.test.d.ts +2 -0
  22. package/dist/__tests__/factory.test.d.ts.map +1 -0
  23. package/dist/__tests__/factory.test.js +126 -0
  24. package/dist/__tests__/factory.test.js.map +1 -0
  25. package/dist/__tests__/integration.e2e.test.d.ts +2 -0
  26. package/dist/__tests__/integration.e2e.test.d.ts.map +1 -0
  27. package/dist/__tests__/integration.e2e.test.js +127 -0
  28. package/dist/__tests__/integration.e2e.test.js.map +1 -0
  29. package/dist/__tests__/integration.test.d.ts +2 -0
  30. package/dist/__tests__/integration.test.d.ts.map +1 -0
  31. package/dist/__tests__/integration.test.js +103 -0
  32. package/dist/__tests__/integration.test.js.map +1 -0
  33. package/dist/__tests__/model-config.test.d.ts +2 -0
  34. package/dist/__tests__/model-config.test.d.ts.map +1 -0
  35. package/dist/__tests__/model-config.test.js +48 -0
  36. package/dist/__tests__/model-config.test.js.map +1 -0
  37. package/dist/__tests__/node-registry.test.d.ts +2 -0
  38. package/dist/__tests__/node-registry.test.d.ts.map +1 -0
  39. package/dist/__tests__/node-registry.test.js +63 -0
  40. package/dist/__tests__/node-registry.test.js.map +1 -0
  41. package/dist/__tests__/node.test.d.ts +2 -0
  42. package/dist/__tests__/node.test.d.ts.map +1 -0
  43. package/dist/__tests__/node.test.js +48 -0
  44. package/dist/__tests__/node.test.js.map +1 -0
  45. package/dist/__tests__/registry.test.d.ts +2 -0
  46. package/dist/__tests__/registry.test.d.ts.map +1 -0
  47. package/dist/__tests__/registry.test.js +62 -0
  48. package/dist/__tests__/registry.test.js.map +1 -0
  49. package/dist/__tests__/web-tool.test.d.ts +2 -0
  50. package/dist/__tests__/web-tool.test.d.ts.map +1 -0
  51. package/dist/__tests__/web-tool.test.js +99 -0
  52. package/dist/__tests__/web-tool.test.js.map +1 -0
  53. package/dist/__tests__/workflow.test.d.ts +2 -0
  54. package/dist/__tests__/workflow.test.d.ts.map +1 -0
  55. package/dist/__tests__/workflow.test.js +49 -0
  56. package/dist/__tests__/workflow.test.js.map +1 -0
  57. package/dist/agent.d.ts +46 -0
  58. package/dist/agent.d.ts.map +1 -0
  59. package/dist/agent.js +75 -0
  60. package/dist/agent.js.map +1 -0
  61. package/dist/cli/__tests__/discovery.test.d.ts +2 -0
  62. package/dist/cli/__tests__/discovery.test.d.ts.map +1 -0
  63. package/dist/cli/__tests__/discovery.test.js +26 -0
  64. package/dist/cli/__tests__/discovery.test.js.map +1 -0
  65. package/dist/cli/__tests__/env.test.d.ts +2 -0
  66. package/dist/cli/__tests__/env.test.d.ts.map +1 -0
  67. package/dist/cli/__tests__/env.test.js +32 -0
  68. package/dist/cli/__tests__/env.test.js.map +1 -0
  69. package/dist/cli/__tests__/runs.test.d.ts +2 -0
  70. package/dist/cli/__tests__/runs.test.d.ts.map +1 -0
  71. package/dist/cli/__tests__/runs.test.js +46 -0
  72. package/dist/cli/__tests__/runs.test.js.map +1 -0
  73. package/dist/cli/app.d.ts +6 -0
  74. package/dist/cli/app.d.ts.map +1 -0
  75. package/dist/cli/app.js +21 -0
  76. package/dist/cli/app.js.map +1 -0
  77. package/dist/cli/discovery.d.ts +24 -0
  78. package/dist/cli/discovery.d.ts.map +1 -0
  79. package/dist/cli/discovery.js +88 -0
  80. package/dist/cli/discovery.js.map +1 -0
  81. package/dist/cli/env.d.ts +15 -0
  82. package/dist/cli/env.d.ts.map +1 -0
  83. package/dist/cli/env.js +54 -0
  84. package/dist/cli/env.js.map +1 -0
  85. package/dist/cli/index.d.ts +3 -0
  86. package/dist/cli/index.d.ts.map +1 -0
  87. package/dist/cli/index.js +423 -0
  88. package/dist/cli/index.js.map +1 -0
  89. package/dist/cli/install.d.ts +54 -0
  90. package/dist/cli/install.d.ts.map +1 -0
  91. package/dist/cli/install.js +217 -0
  92. package/dist/cli/install.js.map +1 -0
  93. package/dist/cli/mcp/config.d.ts +5 -0
  94. package/dist/cli/mcp/config.d.ts.map +1 -0
  95. package/dist/cli/mcp/config.js +14 -0
  96. package/dist/cli/mcp/config.js.map +1 -0
  97. package/dist/cli/mcp/lib/templates.d.ts +12 -0
  98. package/dist/cli/mcp/lib/templates.d.ts.map +1 -0
  99. package/dist/cli/mcp/lib/templates.js +77 -0
  100. package/dist/cli/mcp/lib/templates.js.map +1 -0
  101. package/dist/cli/mcp/server.d.ts +5 -0
  102. package/dist/cli/mcp/server.d.ts.map +1 -0
  103. package/dist/cli/mcp/server.js +15 -0
  104. package/dist/cli/mcp/server.js.map +1 -0
  105. package/dist/cli/mcp/serverInfo.d.ts +7 -0
  106. package/dist/cli/mcp/serverInfo.d.ts.map +1 -0
  107. package/dist/cli/mcp/serverInfo.js +7 -0
  108. package/dist/cli/mcp/serverInfo.js.map +1 -0
  109. package/dist/cli/mcp/tools/createApp.d.ts +15 -0
  110. package/dist/cli/mcp/tools/createApp.d.ts.map +1 -0
  111. package/dist/cli/mcp/tools/createApp.js +81 -0
  112. package/dist/cli/mcp/tools/createApp.js.map +1 -0
  113. package/dist/cli/mcp/tools/createDatabase.d.ts +14 -0
  114. package/dist/cli/mcp/tools/createDatabase.d.ts.map +1 -0
  115. package/dist/cli/mcp/tools/createDatabase.js +66 -0
  116. package/dist/cli/mcp/tools/createDatabase.js.map +1 -0
  117. package/dist/cli/mcp/tools/index.d.ts +24 -0
  118. package/dist/cli/mcp/tools/index.d.ts.map +1 -0
  119. package/dist/cli/mcp/tools/index.js +11 -0
  120. package/dist/cli/mcp/tools/index.js.map +1 -0
  121. package/dist/cli/mcp/tools/setupAppSchema.d.ts +17 -0
  122. package/dist/cli/mcp/tools/setupAppSchema.d.ts.map +1 -0
  123. package/dist/cli/mcp/tools/setupAppSchema.js +157 -0
  124. package/dist/cli/mcp/tools/setupAppSchema.js.map +1 -0
  125. package/dist/cli/mcp/types.d.ts +3 -0
  126. package/dist/cli/mcp/types.d.ts.map +1 -0
  127. package/dist/cli/mcp/types.js +2 -0
  128. package/dist/cli/mcp/types.js.map +1 -0
  129. package/dist/cli/runs.d.ts +28 -0
  130. package/dist/cli/runs.d.ts.map +1 -0
  131. package/dist/cli/runs.js +70 -0
  132. package/dist/cli/runs.js.map +1 -0
  133. package/dist/cli/trace.d.ts +31 -0
  134. package/dist/cli/trace.d.ts.map +1 -0
  135. package/dist/cli/trace.js +264 -0
  136. package/dist/cli/trace.js.map +1 -0
  137. package/dist/context.d.ts +13 -0
  138. package/dist/context.d.ts.map +1 -0
  139. package/dist/context.js +25 -0
  140. package/dist/context.js.map +1 -0
  141. package/dist/dbos.d.ts +15 -0
  142. package/dist/dbos.d.ts.map +1 -0
  143. package/dist/dbos.js +27 -0
  144. package/dist/dbos.js.map +1 -0
  145. package/dist/factory.d.ts +6 -0
  146. package/dist/factory.d.ts.map +1 -0
  147. package/dist/factory.js +78 -0
  148. package/dist/factory.js.map +1 -0
  149. package/dist/index.d.ts +20 -0
  150. package/dist/index.d.ts.map +1 -0
  151. package/dist/index.js +18 -0
  152. package/dist/index.js.map +1 -0
  153. package/dist/node.d.ts +19 -0
  154. package/dist/node.d.ts.map +1 -0
  155. package/dist/node.js +16 -0
  156. package/dist/node.js.map +1 -0
  157. package/dist/nodes/agent/executor.d.ts +70 -0
  158. package/dist/nodes/agent/executor.d.ts.map +1 -0
  159. package/dist/nodes/agent/executor.js +230 -0
  160. package/dist/nodes/agent/executor.js.map +1 -0
  161. package/dist/nodes/agent/index.d.ts +7 -0
  162. package/dist/nodes/agent/index.d.ts.map +1 -0
  163. package/dist/nodes/agent/index.js +5 -0
  164. package/dist/nodes/agent/index.js.map +1 -0
  165. package/dist/nodes/agent/model-config.d.ts +42 -0
  166. package/dist/nodes/agent/model-config.d.ts.map +1 -0
  167. package/dist/nodes/agent/model-config.js +58 -0
  168. package/dist/nodes/agent/model-config.js.map +1 -0
  169. package/dist/nodes/agent/parser.d.ts +22 -0
  170. package/dist/nodes/agent/parser.d.ts.map +1 -0
  171. package/dist/nodes/agent/parser.js +42 -0
  172. package/dist/nodes/agent/parser.js.map +1 -0
  173. package/dist/nodes/builtin/index.d.ts +9 -0
  174. package/dist/nodes/builtin/index.d.ts.map +1 -0
  175. package/dist/nodes/builtin/index.js +10 -0
  176. package/dist/nodes/builtin/index.js.map +1 -0
  177. package/dist/nodes/builtin/web.d.ts +25 -0
  178. package/dist/nodes/builtin/web.d.ts.map +1 -0
  179. package/dist/nodes/builtin/web.js +86 -0
  180. package/dist/nodes/builtin/web.js.map +1 -0
  181. package/dist/nodes/registry.d.ts +32 -0
  182. package/dist/nodes/registry.d.ts.map +1 -0
  183. package/dist/nodes/registry.js +58 -0
  184. package/dist/nodes/registry.js.map +1 -0
  185. package/dist/registry.d.ts +31 -0
  186. package/dist/registry.d.ts.map +1 -0
  187. package/dist/registry.js +44 -0
  188. package/dist/registry.js.map +1 -0
  189. package/dist/types.d.ts +63 -0
  190. package/dist/types.d.ts.map +1 -0
  191. package/dist/types.js +2 -0
  192. package/dist/types.js.map +1 -0
  193. package/dist/workflow.d.ts +26 -0
  194. package/dist/workflow.d.ts.map +1 -0
  195. package/dist/workflow.js +50 -0
  196. package/dist/workflow.js.map +1 -0
  197. package/package.json +52 -0
package/dist/agent.js ADDED
@@ -0,0 +1,75 @@
1
+ import { DBOS } from "@dbos-inc/dbos-sdk";
2
+ import { parseAgentSpec } from "./nodes/agent/parser.js";
3
+ import { executeAgent } from "./nodes/agent/executor.js";
4
+ let agentRuntimeConfig = null;
5
+ /**
6
+ * Configure the agent runtime (called by factory)
7
+ * @internal
8
+ */
9
+ export function configureAgentRuntime(config) {
10
+ agentRuntimeConfig = config;
11
+ }
12
+ /**
13
+ * Create a WorkflowContext for agent execution that wraps tool calls in DBOS steps
14
+ */
15
+ function createAgentContext() {
16
+ const ctx = {
17
+ run: async (executable, inputs) => {
18
+ // Validate inputs against schema
19
+ const validated = executable.inputSchema.parse(inputs);
20
+ // Wrap execution in DBOS step for durability
21
+ return DBOS.runStep(async () => executable.execute(ctx, validated), { name: executable.name });
22
+ },
23
+ log: (message, level = "info") => {
24
+ DBOS.logger[level](message);
25
+ },
26
+ };
27
+ return ctx;
28
+ }
29
+ /**
30
+ * Factory for creating agent executables
31
+ */
32
+ export const Agent = {
33
+ create(definition) {
34
+ const tools = definition.tools ?? {};
35
+ // Create the DBOS-registered workflow function for this agent
36
+ async function agentWorkflowImpl(inputs) {
37
+ if (!agentRuntimeConfig) {
38
+ throw new Error("Agent runtime not configured. Make sure to use create0pflow() before executing agents.");
39
+ }
40
+ const ctx = createAgentContext();
41
+ // Parse the agent spec (for system prompt and model override)
42
+ const spec = await parseAgentSpec(definition.specPath);
43
+ // Convert inputs to a user message string
44
+ // If inputs is a string, use directly; otherwise JSON stringify
45
+ const userMessage = typeof inputs === "string" ? inputs : JSON.stringify(inputs, null, 2);
46
+ // Execute the agent with tools from definition
47
+ const result = await executeAgent({
48
+ ctx,
49
+ spec,
50
+ userMessage,
51
+ tools,
52
+ nodeRegistry: agentRuntimeConfig.nodeRegistry,
53
+ modelConfig: agentRuntimeConfig.modelConfig,
54
+ outputSchema: definition.outputSchema,
55
+ });
56
+ return result.output;
57
+ }
58
+ // Register as a DBOS workflow (agent runs as child workflow, tool calls are steps)
59
+ const durableAgentWorkflow = DBOS.registerWorkflow(agentWorkflowImpl, {
60
+ name: definition.name,
61
+ });
62
+ return {
63
+ name: definition.name,
64
+ type: "agent",
65
+ description: definition.description,
66
+ inputSchema: definition.inputSchema,
67
+ outputSchema: definition.outputSchema,
68
+ specPath: definition.specPath,
69
+ tools,
70
+ // execute ignores the ctx param and uses DBOS context instead
71
+ execute: (_ctx, inputs) => durableAgentWorkflow(inputs),
72
+ };
73
+ },
74
+ };
75
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAE1C,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAuCzD,IAAI,kBAAkB,GAA8B,IAAI,CAAC;AAEzD;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,MAA0B;IAC9D,kBAAkB,GAAG,MAAM,CAAC;AAC9B,CAAC;AAED;;GAEG;AACH,SAAS,kBAAkB;IACzB,MAAM,GAAG,GAAoB;QAC3B,GAAG,EAAE,KAAK,EACR,UAAuC,EACvC,MAAc,EACI,EAAE;YACpB,iCAAiC;YACjC,MAAM,SAAS,GAAG,UAAU,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAEvD,6CAA6C;YAC7C,OAAO,IAAI,CAAC,OAAO,CACjB,KAAK,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,SAAS,CAAC,EAC9C,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,CAC1B,CAAC;QACJ,CAAC;QAED,GAAG,EAAE,CAAC,OAAe,EAAE,QAAkB,MAAM,EAAE,EAAE;YACjD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC;QAC9B,CAAC;KACF,CAAC;IAEF,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,MAAM,CACJ,UAA4C;QAE5C,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,IAAI,EAAE,CAAC;QAErC,8DAA8D;QAC9D,KAAK,UAAU,iBAAiB,CAAC,MAAc;YAC7C,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBACxB,MAAM,IAAI,KAAK,CACb,wFAAwF,CACzF,CAAC;YACJ,CAAC;YAED,MAAM,GAAG,GAAG,kBAAkB,EAAE,CAAC;YAEjC,8DAA8D;YAC9D,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;YAEvD,0CAA0C;YAC1C,gEAAgE;YAChE,MAAM,WAAW,GACf,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YAExE,+CAA+C;YAC/C,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC;gBAChC,GAAG;gBACH,IAAI;gBACJ,WAAW;gBACX,KAAK;gBACL,YAAY,EAAE,kBAAkB,CAAC,YAAY;gBAC7C,WAAW,EAAE,kBAAkB,CAAC,WAAW;gBAC3C,YAAY,EAAE,UAAU,CAAC,YAAY;aACtC,CAAC,CAAC;YAEH,OAAO,MAAM,CAAC,MAAiB,CAAC;QAClC,CAAC;QAED,mFAAmF;QACnF,MAAM,oBAAoB,GAAG,IAAI,CAAC,gBAAgB,CAAC,iBAAiB,EAAE;YACpE,IAAI,EAAE,UAAU,CAAC,IAAI;SACtB,CAAC,CAAC;QAEH,OAAO;YACL,IAAI,EAAE,UAAU,CAAC,IAAI;YACrB,IAAI,EAAE,OAAO;YACb,WAAW,EAAE,UAAU,CAAC,WAAW;YACnC,WAAW,EAAE,UAAU,CAAC,WAAW;YACnC,YAAY,EAAE,UAAU,CAAC,YAAY;YACrC,QAAQ,EAAE,UAAU,CAAC,QAAQ;YAC7B,KAAK;YACL,8DAA8D;YAC9D,OAAO,EAAE,CAAC,IAAqB,EAAE,MAAc,EAAE,EAAE,CAAC,oBAAoB,CAAC,MAAM,CAAC;SACjF,CAAC;IACJ,CAAC;CACF,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=discovery.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.test.d.ts","sourceRoot":"","sources":["../../../src/cli/__tests__/discovery.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,26 @@
1
+ // packages/cli/src/__tests__/discovery.test.ts
2
+ import { describe, it, expect } from "vitest";
3
+ import { discoverWorkflows } from "../discovery.js";
4
+ import path from "path";
5
+ describe("discoverWorkflows", () => {
6
+ it("returns empty result if generated/workflows does not exist", async () => {
7
+ const result = await discoverWorkflows("/nonexistent");
8
+ expect(result.workflows).toEqual([]);
9
+ expect(result.warnings).toEqual([]);
10
+ });
11
+ it("discovers workflow executables from uptime-app", async () => {
12
+ const projectRoot = path.resolve(__dirname, "../../../..");
13
+ const uptimeApp = path.join(projectRoot, "examples/uptime-app");
14
+ const result = await discoverWorkflows(uptimeApp);
15
+ expect(result.workflows.length).toBeGreaterThan(0);
16
+ // Returns actual workflow executables with name and type
17
+ expect(result.workflows.some(w => w.name === "url-check")).toBe(true);
18
+ expect(result.workflows.every(w => w.type === "workflow")).toBe(true);
19
+ });
20
+ it("collects warnings for failed imports without throwing", async () => {
21
+ // Warnings are collected, not printed, so caller can decide what to do
22
+ const result = await discoverWorkflows("/nonexistent");
23
+ expect(Array.isArray(result.warnings)).toBe(true);
24
+ });
25
+ });
26
+ //# sourceMappingURL=discovery.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.test.js","sourceRoot":"","sources":["../../../src/cli/__tests__/discovery.test.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,EAAE,CAAC,4DAA4D,EAAE,KAAK,IAAI,EAAE;QAC1E,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,cAAc,CAAC,CAAC;QACvD,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACrC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;QAC9D,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;QAC3D,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,qBAAqB,CAAC,CAAC;QAChE,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAClD,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QACnD,yDAAyD;QACzD,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtE,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;QACrE,uEAAuE;QACvE,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,cAAc,CAAC,CAAC;QACvD,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=env.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.test.d.ts","sourceRoot":"","sources":["../../../src/cli/__tests__/env.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,32 @@
1
+ // packages/cli/src/__tests__/env.test.ts
2
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
3
+ import { findEnvFile } from "../env.js";
4
+ import fs from "fs";
5
+ import path from "path";
6
+ import os from "os";
7
+ describe("findEnvFile", () => {
8
+ let tempDir;
9
+ beforeEach(() => {
10
+ tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "env-test-"));
11
+ });
12
+ afterEach(() => {
13
+ fs.rmSync(tempDir, { recursive: true });
14
+ });
15
+ it("finds .env in current directory", () => {
16
+ fs.writeFileSync(path.join(tempDir, ".env"), "TEST=1");
17
+ const result = findEnvFile(tempDir);
18
+ expect(result).toBe(path.join(tempDir, ".env"));
19
+ });
20
+ it("finds .env in parent directory", () => {
21
+ const subDir = path.join(tempDir, "sub");
22
+ fs.mkdirSync(subDir);
23
+ fs.writeFileSync(path.join(tempDir, ".env"), "TEST=1");
24
+ const result = findEnvFile(subDir);
25
+ expect(result).toBe(path.join(tempDir, ".env"));
26
+ });
27
+ it("returns null if no .env found", () => {
28
+ const result = findEnvFile(tempDir);
29
+ expect(result).toBeNull();
30
+ });
31
+ });
32
+ //# sourceMappingURL=env.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.test.js","sourceRoot":"","sources":["../../../src/cli/__tests__/env.test.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,IAAI,OAAe,CAAC;IAEpB,UAAU,CAAC,GAAG,EAAE;QACd,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,WAAW,CAAC,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAC;QACvD,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACzC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACrB,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAC;QACvD,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;QACnC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC5B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=runs.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runs.test.d.ts","sourceRoot":"","sources":["../../../src/cli/__tests__/runs.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,46 @@
1
+ // packages/cli/src/__tests__/runs.test.ts
2
+ import { describe, it, expect } from "vitest";
3
+ import { listRuns, getRun } from "../runs.js";
4
+ const DATABASE_URL = process.env.DATABASE_URL;
5
+ // Use uptime-app schema for tests (matches examples/uptime-app)
6
+ const TEST_SCHEMA = "uptime_app_dbos";
7
+ describe.skipIf(!DATABASE_URL)("runs", () => {
8
+ it("lists recent workflow runs", async () => {
9
+ const runs = await listRuns(DATABASE_URL, { limit: 10, schema: TEST_SCHEMA });
10
+ expect(Array.isArray(runs)).toBe(true);
11
+ // Each run should have expected fields
12
+ if (runs.length > 0) {
13
+ expect(runs[0]).toHaveProperty("workflow_uuid");
14
+ expect(runs[0]).toHaveProperty("name");
15
+ expect(runs[0]).toHaveProperty("status");
16
+ }
17
+ });
18
+ it("gets a specific run by full id", async () => {
19
+ const runs = await listRuns(DATABASE_URL, { limit: 1, schema: TEST_SCHEMA });
20
+ if (runs.length > 0) {
21
+ const result = await getRun(DATABASE_URL, runs[0].workflow_uuid, TEST_SCHEMA);
22
+ expect(result.run).not.toBeNull();
23
+ expect(result.run.workflow_uuid).toBe(runs[0].workflow_uuid);
24
+ expect(result.ambiguous).toBeUndefined();
25
+ }
26
+ });
27
+ it("gets a specific run by id prefix", async () => {
28
+ const runs = await listRuns(DATABASE_URL, { limit: 1, schema: TEST_SCHEMA });
29
+ if (runs.length > 0) {
30
+ // Use first 8 characters as prefix (like displayed in history)
31
+ const prefix = runs[0].workflow_uuid.slice(0, 8);
32
+ const result = await getRun(DATABASE_URL, prefix, TEST_SCHEMA);
33
+ // Should find the run (may be ambiguous if multiple runs share prefix)
34
+ if (!result.ambiguous) {
35
+ expect(result.run).not.toBeNull();
36
+ expect(result.run.workflow_uuid.startsWith(prefix)).toBe(true);
37
+ }
38
+ }
39
+ });
40
+ it("returns null for non-existent run", async () => {
41
+ const result = await getRun(DATABASE_URL, "non-existent-id", TEST_SCHEMA);
42
+ expect(result.run).toBeNull();
43
+ expect(result.ambiguous).toBeUndefined();
44
+ });
45
+ });
46
+ //# sourceMappingURL=runs.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runs.test.js","sourceRoot":"","sources":["../../../src/cli/__tests__/runs.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Get the app name from package.json in cwd
3
+ * Returns undefined if not found
4
+ */
5
+ export declare function getAppName(): string | undefined;
6
+ //# sourceMappingURL=app.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/cli/app.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAgB,UAAU,IAAI,MAAM,GAAG,SAAS,CAa/C"}
@@ -0,0 +1,21 @@
1
+ // packages/cli/src/app.ts
2
+ import fs from "fs";
3
+ import path from "path";
4
+ /**
5
+ * Get the app name from package.json in cwd
6
+ * Returns undefined if not found
7
+ */
8
+ export function getAppName() {
9
+ const pkgPath = path.join(process.cwd(), "package.json");
10
+ if (!fs.existsSync(pkgPath)) {
11
+ return undefined;
12
+ }
13
+ try {
14
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
15
+ return pkg.name;
16
+ }
17
+ catch {
18
+ return undefined;
19
+ }
20
+ }
21
+ //# sourceMappingURL=app.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/cli/app.ts"],"names":[],"mappings":"AAAA,0BAA0B;AAC1B,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB;;;GAGG;AACH,MAAM,UAAU,UAAU;IACxB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,CAAC,CAAC;IAEzD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;QAC1D,OAAO,GAAG,CAAC,IAAI,CAAC;IAClB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC"}
@@ -0,0 +1,24 @@
1
+ import type { Executable } from "../index.js";
2
+ type AnyExecutable = Executable<any, any>;
3
+ export interface DiscoveryResult {
4
+ workflows: AnyExecutable[];
5
+ warnings: string[];
6
+ }
7
+ export interface NodeDiscoveryResult {
8
+ nodes: Record<string, AnyExecutable>;
9
+ warnings: string[];
10
+ }
11
+ /**
12
+ * Discover and load workflow executables from generated/workflows/ directory
13
+ * Uses jiti to load TypeScript files directly without compilation
14
+ * Returns workflows and any warnings (caller decides whether to display warnings)
15
+ */
16
+ export declare function discoverWorkflows(projectDir: string): Promise<DiscoveryResult>;
17
+ /**
18
+ * Discover and load node executables from src/nodes/ directory
19
+ * Uses jiti to load TypeScript files directly without compilation
20
+ * Returns nodes indexed by name and any warnings
21
+ */
22
+ export declare function discoverNodes(projectDir: string): Promise<NodeDiscoveryResult>;
23
+ export {};
24
+ //# sourceMappingURL=discovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../src/cli/discovery.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAG9C,KAAK,aAAa,GAAG,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AAI1C,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACrC,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAcD;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,eAAe,CAAC,CA8B1B;AAcD;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,mBAAmB,CAAC,CAgC9B"}
@@ -0,0 +1,88 @@
1
+ // packages/cli/src/discovery.ts
2
+ import fs from "fs";
3
+ import path from "path";
4
+ import { createJiti } from "jiti";
5
+ const jiti = createJiti(import.meta.url);
6
+ /**
7
+ * Check if a value is a workflow executable
8
+ */
9
+ function isWorkflow(value) {
10
+ return (value !== null &&
11
+ typeof value === "object" &&
12
+ "type" in value &&
13
+ value.type === "workflow");
14
+ }
15
+ /**
16
+ * Discover and load workflow executables from generated/workflows/ directory
17
+ * Uses jiti to load TypeScript files directly without compilation
18
+ * Returns workflows and any warnings (caller decides whether to display warnings)
19
+ */
20
+ export async function discoverWorkflows(projectDir) {
21
+ const workflowDir = path.join(projectDir, "generated", "workflows");
22
+ if (!fs.existsSync(workflowDir)) {
23
+ return { workflows: [], warnings: [] };
24
+ }
25
+ const files = fs.readdirSync(workflowDir).filter(f => f.endsWith(".ts") || f.endsWith(".js"));
26
+ const workflows = [];
27
+ const warnings = [];
28
+ for (const file of files) {
29
+ const filePath = path.join(workflowDir, file);
30
+ try {
31
+ const module = await jiti.import(filePath);
32
+ // Find the workflow export in the module
33
+ for (const value of Object.values(module)) {
34
+ if (isWorkflow(value)) {
35
+ workflows.push(value);
36
+ break; // One workflow per file
37
+ }
38
+ }
39
+ }
40
+ catch (err) {
41
+ warnings.push(`Failed to load workflow ${file}: ${err}`);
42
+ }
43
+ }
44
+ return { workflows, warnings };
45
+ }
46
+ /**
47
+ * Check if a value is a node executable
48
+ */
49
+ function isNode(value) {
50
+ return (value !== null &&
51
+ typeof value === "object" &&
52
+ "type" in value &&
53
+ value.type === "node");
54
+ }
55
+ /**
56
+ * Discover and load node executables from src/nodes/ directory
57
+ * Uses jiti to load TypeScript files directly without compilation
58
+ * Returns nodes indexed by name and any warnings
59
+ */
60
+ export async function discoverNodes(projectDir) {
61
+ const nodesDir = path.join(projectDir, "src", "nodes");
62
+ const nodes = {};
63
+ const warnings = [];
64
+ if (!fs.existsSync(nodesDir)) {
65
+ return { nodes, warnings };
66
+ }
67
+ const files = fs.readdirSync(nodesDir).filter(f => f.endsWith(".ts") || f.endsWith(".js"));
68
+ for (const file of files) {
69
+ // Skip index files
70
+ if (file === "index.ts" || file === "index.js")
71
+ continue;
72
+ const filePath = path.join(nodesDir, file);
73
+ try {
74
+ const module = await jiti.import(filePath);
75
+ // Find node exports in the module
76
+ for (const value of Object.values(module)) {
77
+ if (isNode(value)) {
78
+ nodes[value.name] = value;
79
+ }
80
+ }
81
+ }
82
+ catch (err) {
83
+ warnings.push(`Failed to load node ${file}: ${err}`);
84
+ }
85
+ }
86
+ return { nodes, warnings };
87
+ }
88
+ //# sourceMappingURL=discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../src/cli/discovery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Walk up from startDir looking for .env file
3
+ * Returns absolute path to .env or null if not found
4
+ */
5
+ export declare function findEnvFile(startDir: string): string | null;
6
+ /**
7
+ * Load .env file into process.env
8
+ * Throws if DATABASE_URL is not set (required for 0pflow)
9
+ */
10
+ export declare function loadEnv(envPath: string): void;
11
+ /**
12
+ * Find .env starting from cwd and load it into process.env
13
+ */
14
+ export declare function resolveEnv(): void;
15
+ //# sourceMappingURL=env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/cli/env.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAmB3D;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAe7C;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,IAAI,CAUjC"}
@@ -0,0 +1,54 @@
1
+ // packages/cli/src/env.ts
2
+ import fs from "fs";
3
+ import path from "path";
4
+ import dotenv from "dotenv";
5
+ /**
6
+ * Walk up from startDir looking for .env file
7
+ * Returns absolute path to .env or null if not found
8
+ */
9
+ export function findEnvFile(startDir) {
10
+ let dir = path.resolve(startDir);
11
+ const root = path.parse(dir).root;
12
+ while (dir !== root) {
13
+ const envPath = path.join(dir, ".env");
14
+ if (fs.existsSync(envPath)) {
15
+ return envPath;
16
+ }
17
+ dir = path.dirname(dir);
18
+ }
19
+ // Check root directory too
20
+ const rootEnv = path.join(root, ".env");
21
+ if (fs.existsSync(rootEnv)) {
22
+ return rootEnv;
23
+ }
24
+ return null;
25
+ }
26
+ /**
27
+ * Load .env file into process.env
28
+ * Throws if DATABASE_URL is not set (required for 0pflow)
29
+ */
30
+ export function loadEnv(envPath) {
31
+ const result = dotenv.config({ path: envPath });
32
+ if (result.error) {
33
+ throw new Error(`Failed to load .env: ${result.error.message}`);
34
+ }
35
+ // DATABASE_URL is required for 0pflow
36
+ if (!process.env.DATABASE_URL) {
37
+ throw new Error("DATABASE_URL not found in .env\n" +
38
+ "Add a PostgreSQL connection string, e.g.:\n" +
39
+ " DATABASE_URL=postgresql://user:pass@localhost:5432/dbname");
40
+ }
41
+ }
42
+ /**
43
+ * Find .env starting from cwd and load it into process.env
44
+ */
45
+ export function resolveEnv() {
46
+ const envPath = findEnvFile(process.cwd());
47
+ if (!envPath) {
48
+ throw new Error("No .env file found in current directory or parents\n" +
49
+ "Create a .env file with at least:\n" +
50
+ " DATABASE_URL=postgresql://user:pass@localhost:5432/dbname");
51
+ }
52
+ loadEnv(envPath);
53
+ }
54
+ //# sourceMappingURL=env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/cli/env.ts"],"names":[],"mappings":"AAAA,0BAA0B;AAC1B,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,QAAgB;IAC1C,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACjC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;IAElC,OAAO,GAAG,KAAK,IAAI,EAAE,CAAC;QACpB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACvC,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3B,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IAED,2BAA2B;IAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACxC,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,OAAO,CAAC,OAAe;IACrC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IAEhD,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,wBAAwB,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAClE,CAAC;IAED,sCAAsC;IACtC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CACb,kCAAkC;YAClC,6CAA6C;YAC7C,6DAA6D,CAC9D,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU;IACxB,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAC3C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,sDAAsD;YACtD,qCAAqC;YACrC,6DAA6D,CAC9D,CAAC;IACJ,CAAC;IACD,OAAO,CAAC,OAAO,CAAC,CAAC;AACnB,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":""}