blokctl 0.2.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 (169) hide show
  1. package/dist/commands/build/index.d.ts +2 -0
  2. package/dist/commands/build/index.js +210 -0
  3. package/dist/commands/config/index.d.ts +1 -0
  4. package/dist/commands/config/index.js +46 -0
  5. package/dist/commands/cost/index.d.ts +1 -0
  6. package/dist/commands/cost/index.js +74 -0
  7. package/dist/commands/create/node.d.ts +2 -0
  8. package/dist/commands/create/node.js +541 -0
  9. package/dist/commands/create/project.d.ts +2 -0
  10. package/dist/commands/create/project.js +941 -0
  11. package/dist/commands/create/utils/Examples.d.ts +39 -0
  12. package/dist/commands/create/utils/Examples.js +983 -0
  13. package/dist/commands/create/workflow.d.ts +2 -0
  14. package/dist/commands/create/workflow.js +109 -0
  15. package/dist/commands/deploy/index.d.ts +2 -0
  16. package/dist/commands/deploy/index.js +176 -0
  17. package/dist/commands/dev/index.d.ts +2 -0
  18. package/dist/commands/dev/index.js +190 -0
  19. package/dist/commands/generate/GenerationAnalytics.d.ts +61 -0
  20. package/dist/commands/generate/GenerationAnalytics.js +162 -0
  21. package/dist/commands/generate/GenerationAnalytics.test.d.ts +1 -0
  22. package/dist/commands/generate/GenerationAnalytics.test.js +407 -0
  23. package/dist/commands/generate/NodeFileWriter.d.ts +5 -0
  24. package/dist/commands/generate/NodeFileWriter.js +240 -0
  25. package/dist/commands/generate/NodeGenerator.d.ts +20 -0
  26. package/dist/commands/generate/NodeGenerator.js +181 -0
  27. package/dist/commands/generate/NodeGenerator.test.d.ts +1 -0
  28. package/dist/commands/generate/NodeGenerator.test.js +101 -0
  29. package/dist/commands/generate/PromptVersioning.d.ts +25 -0
  30. package/dist/commands/generate/PromptVersioning.js +71 -0
  31. package/dist/commands/generate/PromptVersioning.test.d.ts +1 -0
  32. package/dist/commands/generate/PromptVersioning.test.js +120 -0
  33. package/dist/commands/generate/RegisterNode.d.ts +3 -0
  34. package/dist/commands/generate/RegisterNode.js +37 -0
  35. package/dist/commands/generate/RuntimeGenerator.d.ts +40 -0
  36. package/dist/commands/generate/RuntimeGenerator.js +369 -0
  37. package/dist/commands/generate/RuntimeGenerator.test.d.ts +1 -0
  38. package/dist/commands/generate/RuntimeGenerator.test.js +553 -0
  39. package/dist/commands/generate/TriggerGenerator.d.ts +22 -0
  40. package/dist/commands/generate/TriggerGenerator.js +220 -0
  41. package/dist/commands/generate/TriggerGenerator.test.d.ts +1 -0
  42. package/dist/commands/generate/TriggerGenerator.test.js +209 -0
  43. package/dist/commands/generate/WorkflowGenerator.d.ts +20 -0
  44. package/dist/commands/generate/WorkflowGenerator.js +131 -0
  45. package/dist/commands/generate/WorkflowGenerator.test.d.ts +1 -0
  46. package/dist/commands/generate/WorkflowGenerator.test.js +77 -0
  47. package/dist/commands/generate/e2e/NodeGenerator.e2e.test.d.ts +1 -0
  48. package/dist/commands/generate/e2e/NodeGenerator.e2e.test.js +216 -0
  49. package/dist/commands/generate/e2e/RuntimeGenerator.e2e.test.d.ts +1 -0
  50. package/dist/commands/generate/e2e/RuntimeGenerator.e2e.test.js +759 -0
  51. package/dist/commands/generate/e2e/TriggerGenerator.e2e.test.d.ts +1 -0
  52. package/dist/commands/generate/e2e/TriggerGenerator.e2e.test.js +295 -0
  53. package/dist/commands/generate/e2e/WorkflowGenerator.e2e.test.d.ts +1 -0
  54. package/dist/commands/generate/e2e/WorkflowGenerator.e2e.test.js +353 -0
  55. package/dist/commands/generate/index.d.ts +1 -0
  56. package/dist/commands/generate/index.js +418 -0
  57. package/dist/commands/generate/prompts/create-fn-node.system.d.ts +5 -0
  58. package/dist/commands/generate/prompts/create-fn-node.system.js +256 -0
  59. package/dist/commands/generate/prompts/create-node-manifest.system.d.ts +4 -0
  60. package/dist/commands/generate/prompts/create-node-manifest.system.js +41 -0
  61. package/dist/commands/generate/prompts/create-node.system.d.ts +5 -0
  62. package/dist/commands/generate/prompts/create-node.system.js +114 -0
  63. package/dist/commands/generate/prompts/create-readme.system.d.ts +4 -0
  64. package/dist/commands/generate/prompts/create-readme.system.js +83 -0
  65. package/dist/commands/generate/prompts/create-runtime.system.d.ts +5 -0
  66. package/dist/commands/generate/prompts/create-runtime.system.js +284 -0
  67. package/dist/commands/generate/prompts/create-trigger.system.d.ts +5 -0
  68. package/dist/commands/generate/prompts/create-trigger.system.js +293 -0
  69. package/dist/commands/generate/prompts/create-workflow.system.d.ts +5 -0
  70. package/dist/commands/generate/prompts/create-workflow.system.js +476 -0
  71. package/dist/commands/generate/prompts/register-node.system.d.ts +4 -0
  72. package/dist/commands/generate/prompts/register-node.system.js +26 -0
  73. package/dist/commands/generate/validators/CompilationValidator.d.ts +9 -0
  74. package/dist/commands/generate/validators/CompilationValidator.js +86 -0
  75. package/dist/commands/generate/validators/CompilationValidator.test.d.ts +1 -0
  76. package/dist/commands/generate/validators/CompilationValidator.test.js +161 -0
  77. package/dist/commands/generate/validators/NodeValidator.d.ts +18 -0
  78. package/dist/commands/generate/validators/NodeValidator.js +217 -0
  79. package/dist/commands/generate/validators/NodeValidator.test.d.ts +1 -0
  80. package/dist/commands/generate/validators/NodeValidator.test.js +281 -0
  81. package/dist/commands/generate/validators/WorkflowValidator.d.ts +6 -0
  82. package/dist/commands/generate/validators/WorkflowValidator.js +301 -0
  83. package/dist/commands/generate/validators/WorkflowValidator.test.d.ts +1 -0
  84. package/dist/commands/generate/validators/WorkflowValidator.test.js +647 -0
  85. package/dist/commands/generate/validators/index.d.ts +4 -0
  86. package/dist/commands/generate/validators/index.js +2 -0
  87. package/dist/commands/graph/index.d.ts +1 -0
  88. package/dist/commands/graph/index.js +69 -0
  89. package/dist/commands/install/index.d.ts +1 -0
  90. package/dist/commands/install/index.js +4 -0
  91. package/dist/commands/install/node.d.ts +4 -0
  92. package/dist/commands/install/node.js +136 -0
  93. package/dist/commands/install/workflow.d.ts +4 -0
  94. package/dist/commands/install/workflow.js +62 -0
  95. package/dist/commands/login/index.d.ts +2 -0
  96. package/dist/commands/login/index.js +77 -0
  97. package/dist/commands/logout/index.d.ts +2 -0
  98. package/dist/commands/logout/index.js +20 -0
  99. package/dist/commands/marketplace/runtime.d.ts +54 -0
  100. package/dist/commands/marketplace/runtime.js +350 -0
  101. package/dist/commands/migrate/index.d.ts +1 -0
  102. package/dist/commands/migrate/index.js +14 -0
  103. package/dist/commands/migrate/node.d.ts +2 -0
  104. package/dist/commands/migrate/node.js +110 -0
  105. package/dist/commands/monitor/index.d.ts +1 -0
  106. package/dist/commands/monitor/index.js +28 -0
  107. package/dist/commands/monitor/monitor-component.d.ts +1 -0
  108. package/dist/commands/monitor/monitor-component.js +271 -0
  109. package/dist/commands/monitor/static/index.html +2124 -0
  110. package/dist/commands/monitor/static-web-server.d.ts +1 -0
  111. package/dist/commands/monitor/static-web-server.js +89 -0
  112. package/dist/commands/profile/index.d.ts +1 -0
  113. package/dist/commands/profile/index.js +112 -0
  114. package/dist/commands/publish/index.d.ts +1 -0
  115. package/dist/commands/publish/index.js +4 -0
  116. package/dist/commands/publish/node.d.ts +4 -0
  117. package/dist/commands/publish/node.js +231 -0
  118. package/dist/commands/publish/workflow.d.ts +4 -0
  119. package/dist/commands/publish/workflow.js +165 -0
  120. package/dist/commands/search/docs.d.ts +17 -0
  121. package/dist/commands/search/docs.js +179 -0
  122. package/dist/commands/search/index.d.ts +1 -0
  123. package/dist/commands/search/index.js +5 -0
  124. package/dist/commands/search/indexer.d.ts +10 -0
  125. package/dist/commands/search/indexer.js +265 -0
  126. package/dist/commands/search/nodes.d.ts +4 -0
  127. package/dist/commands/search/nodes.js +101 -0
  128. package/dist/commands/search/workflow.d.ts +4 -0
  129. package/dist/commands/search/workflow.js +100 -0
  130. package/dist/commands/trace/index.d.ts +1 -0
  131. package/dist/commands/trace/index.js +26 -0
  132. package/dist/commands/trace/startStudio.d.ts +8 -0
  133. package/dist/commands/trace/startStudio.js +116 -0
  134. package/dist/index.d.ts +17 -0
  135. package/dist/index.js +186 -0
  136. package/dist/services/commander.d.ts +9 -0
  137. package/dist/services/commander.js +20 -0
  138. package/dist/services/constants.d.ts +1 -0
  139. package/dist/services/constants.js +3 -0
  140. package/dist/services/local-token-manager.d.ts +14 -0
  141. package/dist/services/local-token-manager.js +99 -0
  142. package/dist/services/non-interactive.d.ts +5 -0
  143. package/dist/services/non-interactive.js +30 -0
  144. package/dist/services/package-manager.d.ts +35 -0
  145. package/dist/services/package-manager.js +111 -0
  146. package/dist/services/posthog.d.ts +31 -0
  147. package/dist/services/posthog.js +159 -0
  148. package/dist/services/registry-manager.d.ts +9 -0
  149. package/dist/services/registry-manager.js +26 -0
  150. package/dist/services/runtime-detector.d.ts +23 -0
  151. package/dist/services/runtime-detector.js +181 -0
  152. package/dist/services/runtime-setup.d.ts +36 -0
  153. package/dist/services/runtime-setup.js +250 -0
  154. package/dist/services/utils.d.ts +2 -0
  155. package/dist/services/utils.js +29 -0
  156. package/dist/services/workflow-loader.d.ts +30 -0
  157. package/dist/services/workflow-loader.js +46 -0
  158. package/dist/studio-dist/assets/charts-Dso0hPUR.js +68 -0
  159. package/dist/studio-dist/assets/graph-CsV2nWGn.js +23 -0
  160. package/dist/studio-dist/assets/icons-zP8LLgPh.js +311 -0
  161. package/dist/studio-dist/assets/index-CLyEkXMx.css +1 -0
  162. package/dist/studio-dist/assets/index-CNXFX_ar.js +27 -0
  163. package/dist/studio-dist/assets/react-vendor--Eh9ivFN.js +17 -0
  164. package/dist/studio-dist/assets/tanstack-query-CiM1U6F5.js +1 -0
  165. package/dist/studio-dist/assets/tanstack-router-Btjy0MKq.js +25 -0
  166. package/dist/studio-dist/assets/tanstack-table-DhwRvuH2.js +22 -0
  167. package/dist/studio-dist/favicon.svg +5 -0
  168. package/dist/studio-dist/index.html +21 -0
  169. package/package.json +75 -0
@@ -0,0 +1,250 @@
1
+ import child_process from "node:child_process";
2
+ import path from "node:path";
3
+ import util from "node:util";
4
+ import fsExtra from "fs-extra";
5
+ const exec = util.promisify(child_process.exec);
6
+ export async function setupRuntime(runtime, githubRepoLocal, projectDir, spinner) {
7
+ const sdkSourcePath = path.join(githubRepoLocal, "sdks", runtime.sdkDir);
8
+ const blokctlRuntimeDir = path.join(projectDir, ".blok", "runtimes", runtime.kind);
9
+ const projectRuntimeDir = path.join(projectDir, "runtimes", runtime.kind);
10
+ if (!fsExtra.existsSync(sdkSourcePath)) {
11
+ throw new Error(`SDK source for ${runtime.label} not found at ${sdkSourcePath}. Make sure the Blok repository is up to date.`);
12
+ }
13
+ spinner.message(`Setting up ${runtime.label} runtime...`);
14
+ fsExtra.ensureDirSync(path.dirname(blokctlRuntimeDir));
15
+ fsExtra.copySync(sdkSourcePath, blokctlRuntimeDir);
16
+ fsExtra.ensureDirSync(projectRuntimeDir);
17
+ const nodesDir = path.join(projectRuntimeDir, "nodes");
18
+ fsExtra.ensureDirSync(nodesDir);
19
+ let startCmdOverride;
20
+ switch (runtime.kind) {
21
+ case "python3":
22
+ await setupPython3(blokctlRuntimeDir, projectRuntimeDir, spinner);
23
+ break;
24
+ case "go":
25
+ await setupGo(blokctlRuntimeDir, spinner);
26
+ break;
27
+ case "rust":
28
+ await setupRust(blokctlRuntimeDir, spinner);
29
+ break;
30
+ case "java":
31
+ startCmdOverride = await setupJava(blokctlRuntimeDir, spinner);
32
+ break;
33
+ case "csharp":
34
+ await setupCSharp(blokctlRuntimeDir, spinner);
35
+ break;
36
+ case "php":
37
+ await setupPhp(blokctlRuntimeDir, spinner);
38
+ break;
39
+ case "ruby":
40
+ startCmdOverride = await setupRuby(blokctlRuntimeDir, spinner, runtime.defaultPort);
41
+ break;
42
+ }
43
+ spinner.message(`${runtime.label} runtime setup complete.`);
44
+ return {
45
+ port: runtime.defaultPort,
46
+ startCmd: startCmdOverride || runtime.startCmd,
47
+ cwd: path.relative(projectDir, blokctlRuntimeDir),
48
+ kind: runtime.kind,
49
+ label: runtime.label,
50
+ };
51
+ }
52
+ async function setupPython3(sdkDir, projectRuntimeDir, spinner) {
53
+ spinner.message("Creating Python3 virtual environment...");
54
+ await createPythonVenv(sdkDir);
55
+ spinner.message("Python3 virtual environment created.");
56
+ spinner.message("Installing Python3 packages...");
57
+ const venvPip = path.join(sdkDir, "python3_runtime", "bin", "pip3");
58
+ const requirementsFile = path.join(sdkDir, "requirements.txt");
59
+ if (fsExtra.existsSync(requirementsFile)) {
60
+ await exec(`"${venvPip}" install -r "${requirementsFile}"`, { cwd: sdkDir });
61
+ }
62
+ spinner.message("Python3 packages installed.");
63
+ const nodesLink = path.join(projectRuntimeDir, "nodes");
64
+ const sdkNodesDir = path.join(sdkDir, "nodes");
65
+ if (fsExtra.existsSync(sdkNodesDir) && !fsExtra.existsSync(nodesLink)) {
66
+ fsExtra.symlinkSync(sdkNodesDir, nodesLink, "junction");
67
+ }
68
+ const coreLink = path.join(projectRuntimeDir, "core");
69
+ const sdkCoreDir = path.join(sdkDir, "core");
70
+ if (fsExtra.existsSync(sdkCoreDir) && !fsExtra.existsSync(coreLink)) {
71
+ fsExtra.symlinkSync(sdkCoreDir, coreLink, "junction");
72
+ }
73
+ }
74
+ async function createPythonVenv(sdkDir) {
75
+ await exec("python3 -m venv python3_runtime", { cwd: sdkDir, timeout: 60000 });
76
+ }
77
+ async function setupGo(sdkDir, spinner) {
78
+ spinner.message("Downloading Go dependencies...");
79
+ await exec("go mod download", { cwd: sdkDir, timeout: 120000 });
80
+ spinner.message("Go dependencies installed.");
81
+ }
82
+ async function setupRust(sdkDir, spinner) {
83
+ spinner.message("Building Rust project (this may take a few minutes on first build)...");
84
+ await exec("cargo build --release", { cwd: sdkDir, timeout: 600000 });
85
+ spinner.message("Rust project built.");
86
+ }
87
+ async function setupJava(sdkDir, spinner) {
88
+ spinner.message("Building Java project with Maven...");
89
+ await exec("mvn package -q -DskipTests", { cwd: sdkDir, timeout: 300000 });
90
+ spinner.message("Java project built.");
91
+ const javaCandidates = ["java", "/opt/homebrew/opt/openjdk/bin/java"];
92
+ for (const javaBin of javaCandidates) {
93
+ try {
94
+ await exec(`${javaBin} --version`, { timeout: 5000 });
95
+ if (javaBin !== "java") {
96
+ return `${javaBin} -jar target/blok-java-1.0.0.jar`;
97
+ }
98
+ return undefined;
99
+ }
100
+ catch {
101
+ }
102
+ }
103
+ return undefined;
104
+ }
105
+ async function setupCSharp(sdkDir, spinner) {
106
+ spinner.message("Restoring .NET packages...");
107
+ await exec("dotnet restore", { cwd: sdkDir, timeout: 120000 });
108
+ spinner.message(".NET packages restored.");
109
+ }
110
+ async function setupPhp(sdkDir, spinner) {
111
+ spinner.message("Installing PHP dependencies...");
112
+ await exec("composer install --no-dev --optimize-autoloader", { cwd: sdkDir, timeout: 120000 });
113
+ spinner.message("PHP dependencies installed.");
114
+ }
115
+ async function setupRuby(sdkDir, spinner, port) {
116
+ const bundleCandidates = ["bundle", "/opt/homebrew/opt/ruby/bin/bundle"];
117
+ let resolvedBundle = "bundle";
118
+ for (const bin of bundleCandidates) {
119
+ try {
120
+ const { stdout } = await exec(`${bin} --version`, { timeout: 5000 });
121
+ const match = stdout.match(/(\d+)\./);
122
+ const major = match ? Number.parseInt(match[1], 10) : 0;
123
+ if (major >= 2) {
124
+ resolvedBundle = bin;
125
+ break;
126
+ }
127
+ }
128
+ catch {
129
+ }
130
+ }
131
+ spinner.message("Installing Ruby dependencies...");
132
+ await exec(`"${resolvedBundle}" install`, { cwd: sdkDir, timeout: 120000 });
133
+ spinner.message("Ruby dependencies installed.");
134
+ return `${resolvedBundle} exec rackup --host 0.0.0.0 -p ${port} config.ru`;
135
+ }
136
+ export function writeProjectConfig(projectDir, runtimeConfigs, triggerConfigs) {
137
+ const config = {};
138
+ if (runtimeConfigs.length > 0) {
139
+ config.runtimes = {};
140
+ for (const rc of runtimeConfigs) {
141
+ config.runtimes[rc.kind] = rc;
142
+ }
143
+ }
144
+ if (triggerConfigs && triggerConfigs.length > 0) {
145
+ config.triggers = {};
146
+ for (const tc of triggerConfigs) {
147
+ config.triggers[tc.kind] = tc;
148
+ }
149
+ }
150
+ const configPath = path.join(projectDir, ".blok", "config.json");
151
+ fsExtra.ensureDirSync(path.dirname(configPath));
152
+ fsExtra.writeFileSync(configPath, JSON.stringify(config, null, 2));
153
+ }
154
+ export function readProjectConfig(projectDir) {
155
+ const configPath = path.join(projectDir, ".blok", "config.json");
156
+ if (!fsExtra.existsSync(configPath)) {
157
+ return null;
158
+ }
159
+ return JSON.parse(fsExtra.readFileSync(configPath, "utf8"));
160
+ }
161
+ export function generateRuntimeEnvVars(runtimeConfigs) {
162
+ if (runtimeConfigs.length === 0)
163
+ return "";
164
+ const lines = ["\n# Runtimes (auto-configured by blokctl)"];
165
+ for (const rc of runtimeConfigs) {
166
+ const envKey = rc.kind === "csharp" ? "CSHARP" : rc.kind.toUpperCase();
167
+ lines.push(`RUNTIME_${envKey}_HOST=localhost`);
168
+ lines.push(`RUNTIME_${envKey}_PORT=${rc.port}`);
169
+ }
170
+ return lines.join("\n");
171
+ }
172
+ export function generateSupervisordConfig(runtimeConfigs) {
173
+ let config = "";
174
+ for (const rc of runtimeConfigs) {
175
+ config += `
176
+ [program:${rc.kind}_runtime]
177
+ command=${rc.startCmd}
178
+ directory=/app/${rc.cwd}
179
+ environment=PORT="${rc.port}",HOST="0.0.0.0"
180
+ autostart=true
181
+ autorestart=true
182
+ stderr_logfile=/var/log/${rc.kind}.err.log
183
+ stdout_logfile=/var/log/${rc.kind}.out.log
184
+ `;
185
+ }
186
+ return config;
187
+ }
188
+ const TRIGGER_PORTS = {
189
+ http: 4000,
190
+ sse: 4001,
191
+ websocket: 4002,
192
+ grpc: 4003,
193
+ cron: 4004,
194
+ queue: 4005,
195
+ pubsub: 4006,
196
+ webhook: 4007,
197
+ worker: 4008,
198
+ };
199
+ const TRIGGER_LABELS = {
200
+ http: "HTTP Trigger",
201
+ sse: "SSE Trigger",
202
+ websocket: "WebSocket Trigger",
203
+ grpc: "gRPC Trigger",
204
+ cron: "Cron Trigger",
205
+ queue: "Queue Trigger",
206
+ pubsub: "PubSub Trigger",
207
+ webhook: "Webhook Trigger",
208
+ worker: "Worker Trigger",
209
+ };
210
+ export function getTriggerPort(triggerKind) {
211
+ return TRIGGER_PORTS[triggerKind] ?? 4000;
212
+ }
213
+ export function getTriggerLabel(triggerKind) {
214
+ return TRIGGER_LABELS[triggerKind] ?? `${triggerKind.toUpperCase()} Trigger`;
215
+ }
216
+ export function createTriggerConfig(triggerKind) {
217
+ const port = getTriggerPort(triggerKind);
218
+ return {
219
+ kind: triggerKind,
220
+ label: getTriggerLabel(triggerKind),
221
+ port,
222
+ entryPoint: `src/triggers/${triggerKind}/index.ts`,
223
+ startCmd: `bun run src/triggers/${triggerKind}/index.ts`,
224
+ };
225
+ }
226
+ export function generateTriggerEnvVars(triggerConfigs) {
227
+ if (triggerConfigs.length === 0)
228
+ return "";
229
+ const lines = ["\n# Triggers (auto-configured by blokctl)"];
230
+ for (const tc of triggerConfigs) {
231
+ lines.push(`TRIGGER_${tc.kind.toUpperCase()}_PORT=${tc.port}`);
232
+ }
233
+ return lines.join("\n");
234
+ }
235
+ export function generateTriggerSupervisordConfig(triggerConfigs) {
236
+ let config = "";
237
+ for (const tc of triggerConfigs) {
238
+ config += `
239
+ [program:${tc.kind}_trigger]
240
+ command=${tc.startCmd}
241
+ directory=/app
242
+ environment=PORT="${tc.port}",HOST="0.0.0.0"
243
+ autostart=true
244
+ autorestart=true
245
+ stderr_logfile=/var/log/${tc.kind}_trigger.err.log
246
+ stdout_logfile=/var/log/${tc.kind}_trigger.out.log
247
+ `;
248
+ }
249
+ return config;
250
+ }
@@ -0,0 +1,2 @@
1
+ export declare function getPackageVersion(): Promise<string>;
2
+ export declare function getPreferredEditor(): string;
@@ -0,0 +1,29 @@
1
+ import os from "node:os";
2
+ import path, { dirname } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import fs from "fs-extra";
5
+ export async function getPackageVersion() {
6
+ const __filename = fileURLToPath(import.meta.url);
7
+ const __dirname = dirname(__filename);
8
+ const pkgJsonPath = path.join(__dirname, "..", "..", "package.json");
9
+ const content = (await fs.readJSON(pkgJsonPath));
10
+ return content?.version;
11
+ }
12
+ export function getPreferredEditor() {
13
+ const configPath = `${os.homedir()}/.blok/config.json`;
14
+ try {
15
+ if (fs.existsSync(configPath)) {
16
+ const config = JSON.parse(fs.readFileSync(configPath, "utf8"));
17
+ if (config.defaultEditor) {
18
+ return config.defaultEditor;
19
+ }
20
+ }
21
+ }
22
+ catch (error) {
23
+ }
24
+ return process.env.TERM_PROGRAM === "vscode"
25
+ ? "Visual Studio Code"
26
+ : process.env.TERM_PROGRAM === "cursor"
27
+ ? "Cursor"
28
+ : "Visual Studio Code";
29
+ }
@@ -0,0 +1,30 @@
1
+ export interface WorkflowDef {
2
+ name: string;
3
+ version: string;
4
+ description?: string;
5
+ trigger: Record<string, unknown>;
6
+ steps: Array<{
7
+ name: string;
8
+ node: string;
9
+ type?: string;
10
+ runtime?: string;
11
+ conditions?: Array<{
12
+ type: "if" | "else";
13
+ expression?: string;
14
+ steps?: Array<{
15
+ name: string;
16
+ node: string;
17
+ type?: string;
18
+ runtime?: string;
19
+ }>;
20
+ }>;
21
+ }>;
22
+ nodes: Record<string, unknown>;
23
+ }
24
+ export interface LoadedWorkflow {
25
+ name: string;
26
+ filePath: string;
27
+ def: WorkflowDef;
28
+ }
29
+ export declare function loadWorkflows(directory: string): Promise<LoadedWorkflow[]>;
30
+ export declare function loadWorkflow(directory: string, name: string): Promise<LoadedWorkflow | null>;
@@ -0,0 +1,46 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ export async function loadWorkflows(directory) {
4
+ const jsonDir = path.join(directory, "workflows", "json");
5
+ if (!fs.existsSync(jsonDir)) {
6
+ const altDir = path.join(directory, "workflows");
7
+ if (fs.existsSync(altDir)) {
8
+ return scanDirectory(altDir);
9
+ }
10
+ return [];
11
+ }
12
+ return scanDirectory(jsonDir);
13
+ }
14
+ export async function loadWorkflow(directory, name) {
15
+ const all = await loadWorkflows(directory);
16
+ return all.find((w) => w.name === name) ?? null;
17
+ }
18
+ function scanDirectory(dir) {
19
+ const workflows = [];
20
+ if (!fs.existsSync(dir))
21
+ return workflows;
22
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
23
+ for (const entry of entries) {
24
+ if (entry.isFile() && entry.name.endsWith(".json")) {
25
+ const filePath = path.join(dir, entry.name);
26
+ try {
27
+ const content = fs.readFileSync(filePath, "utf-8");
28
+ const parsed = JSON.parse(content);
29
+ if (parsed.name && parsed.trigger && parsed.steps && parsed.nodes) {
30
+ workflows.push({
31
+ name: parsed.name,
32
+ filePath,
33
+ def: parsed,
34
+ });
35
+ }
36
+ }
37
+ catch {
38
+ }
39
+ }
40
+ else if (entry.isDirectory()) {
41
+ const subWorkflows = scanDirectory(path.join(dir, entry.name));
42
+ workflows.push(...subWorkflows);
43
+ }
44
+ }
45
+ return workflows;
46
+ }