motia 0.0.28 → 0.0.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Motia
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.BuildPrinter = void 0;
7
+ const cli_output_manager_1 = require("./cli-output-manager");
8
+ const colors_1 = __importDefault(require("colors"));
9
+ const printer_1 = require("@motiadev/core/dist/src/printer");
10
+ const building = colors_1.default.yellow('➜ [BUILDING]');
11
+ const built = colors_1.default.green('✓ [BUILT]');
12
+ const failed = colors_1.default.red('✘ [FAILED]');
13
+ const skipped = colors_1.default.gray('- [SKIPPED]');
14
+ class BuildPrinter {
15
+ constructor() {
16
+ this.printer = new printer_1.Printer(process.cwd());
17
+ this.output = new cli_output_manager_1.CLIOutputManager();
18
+ }
19
+ printStepBuilding(step) {
20
+ const stepType = this.printer.getStepType(step);
21
+ const stepPath = this.printer.getStepPath(step);
22
+ const stepTag = this.printer.stepTag;
23
+ this.output.logStep(step.filePath, `${building} ${stepTag} ${stepType} ${stepPath}`);
24
+ }
25
+ printStepBuilt(step) {
26
+ const stepType = this.printer.getStepType(step);
27
+ const stepPath = this.printer.getStepPath(step);
28
+ const stepTag = this.printer.stepTag;
29
+ this.output.updateStep(step.filePath, `${built} ${stepTag} ${stepType} ${stepPath}`);
30
+ }
31
+ printStepFailed(step, error) {
32
+ const stepType = this.printer.getStepType(step);
33
+ const stepPath = this.printer.getStepPath(step);
34
+ const stepTag = this.printer.stepTag;
35
+ this.output.updateStep(step.filePath, `${failed} ${stepTag} ${stepType} ${stepPath} ${error.message}`);
36
+ }
37
+ printStepSkipped(step, reason) {
38
+ const stepType = this.printer.getStepType(step);
39
+ const stepPath = this.printer.getStepPath(step);
40
+ const stepTag = this.printer.stepTag;
41
+ this.output.logStep(step.filePath, `${skipped} ${stepTag} ${stepType} ${stepPath} ${reason}`);
42
+ }
43
+ }
44
+ exports.BuildPrinter = BuildPrinter;
@@ -0,0 +1,170 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.build = void 0;
40
+ const locked_data_1 = require("@motiadev/core/dist/src/locked-data");
41
+ const printer_1 = require("@motiadev/core/dist/src/printer");
42
+ const colors_1 = __importDefault(require("colors"));
43
+ const esbuild = __importStar(require("esbuild"));
44
+ const fs_1 = __importDefault(require("fs"));
45
+ const path_1 = __importDefault(require("path"));
46
+ const generate_locked_data_1 = require("../generate-locked-data");
47
+ const build_printer_1 = require("./build-printer");
48
+ const child_process_1 = require("child_process");
49
+ const archiver_1 = __importDefault(require("archiver"));
50
+ class Builder {
51
+ constructor(projectDir) {
52
+ this.projectDir = projectDir;
53
+ this.distDir = path_1.default.join(projectDir, 'dist');
54
+ this.stepsConfig = {};
55
+ this.printer = new build_printer_1.BuildPrinter();
56
+ }
57
+ registerStep(args) {
58
+ this.stepsConfig[args.bundlePath] = {
59
+ type: args.type,
60
+ entrypointPath: args.entrypointPath,
61
+ config: args.step.config,
62
+ };
63
+ }
64
+ }
65
+ const buildPython = async (step, builder) => {
66
+ const archive = (0, archiver_1.default)('zip', { zlib: { level: 9 } });
67
+ const entrypointPath = step.filePath.replace(builder.projectDir, '');
68
+ const bundlePath = path_1.default.join('python', entrypointPath.replace(/(.*)\.py$/, '$1.zip'));
69
+ const outfile = path_1.default.join(builder.distDir, bundlePath);
70
+ return new Promise((resolve, reject) => {
71
+ try {
72
+ // Ensure output directory exists
73
+ fs_1.default.mkdirSync(path_1.default.dirname(outfile), { recursive: true });
74
+ builder.printer.printStepBuilding(step);
75
+ const type = 'python';
76
+ const child = (0, child_process_1.spawn)('python', [path_1.default.join(__dirname, 'python-builder.py'), step.filePath], {
77
+ cwd: builder.projectDir,
78
+ stdio: [undefined, undefined, undefined, 'ipc'],
79
+ });
80
+ builder.registerStep({ entrypointPath, bundlePath, step, type });
81
+ archive.pipe(fs_1.default.createWriteStream(outfile));
82
+ child.on('message', (message) => {
83
+ message.forEach((file) => {
84
+ archive.append(fs_1.default.createReadStream(path_1.default.join(builder.projectDir, file)), { name: file });
85
+ });
86
+ });
87
+ child.on('close', (code) => {
88
+ if (code !== 0) {
89
+ builder.printer.printStepFailed(step, new Error('Python builder failed'));
90
+ return reject(new Error('Python builder failed'));
91
+ }
92
+ builder.printer.printStepBuilt(step);
93
+ archive.finalize();
94
+ });
95
+ archive.on('close', () => resolve());
96
+ archive.on('error', (err) => reject(err));
97
+ }
98
+ catch (err) {
99
+ builder.printer.printStepFailed(step, err);
100
+ reject(err);
101
+ }
102
+ });
103
+ };
104
+ const buildNode = async (step, builder) => {
105
+ const relativeFilePath = step.filePath.replace(builder.projectDir, '');
106
+ const entrypointPath = relativeFilePath.replace(/(.*)\.(ts|js)$/, '$1.js');
107
+ const entrypointMapPath = entrypointPath.replace(/(.*)\.js$/, '$1.js.map');
108
+ const bundlePath = path_1.default.join('node', entrypointPath.replace(/(.*)\.js$/, '$1.zip'));
109
+ const outputJsFile = path_1.default.join(builder.distDir, 'node', entrypointPath);
110
+ const outputMapFile = path_1.default.join(builder.distDir, 'node', entrypointMapPath);
111
+ const type = 'node';
112
+ builder.registerStep({ entrypointPath, bundlePath, step, type });
113
+ builder.printer.printStepBuilding(step);
114
+ try {
115
+ await esbuild.build({
116
+ entryPoints: [step.filePath],
117
+ bundle: true,
118
+ sourcemap: true,
119
+ outfile: outputJsFile,
120
+ platform: 'node',
121
+ });
122
+ await new Promise((resolve, reject) => {
123
+ const archive = (0, archiver_1.default)('zip', { zlib: { level: 9 } });
124
+ archive.pipe(fs_1.default.createWriteStream(path_1.default.join(builder.distDir, bundlePath)));
125
+ archive.append(fs_1.default.createReadStream(outputJsFile), { name: entrypointPath });
126
+ archive.append(fs_1.default.createReadStream(outputMapFile), { name: entrypointMapPath });
127
+ archive.finalize();
128
+ archive.on('close', () => {
129
+ fs_1.default.unlinkSync(outputJsFile);
130
+ fs_1.default.unlinkSync(outputMapFile);
131
+ resolve();
132
+ });
133
+ archive.on('error', (err) => reject(err));
134
+ });
135
+ builder.printer.printStepBuilt(step);
136
+ }
137
+ catch (err) {
138
+ builder.printer.printStepFailed(step, err);
139
+ }
140
+ };
141
+ const build = async () => {
142
+ const projectDir = process.cwd();
143
+ const builder = new Builder(projectDir);
144
+ const stepsConfigPath = path_1.default.join(projectDir, 'dist', 'motia.steps.json');
145
+ const lockedData = new locked_data_1.LockedData(projectDir);
146
+ const promises = [];
147
+ const distDir = path_1.default.join(projectDir, 'dist');
148
+ lockedData.printer = new printer_1.NoPrinter(projectDir); // let's make it not print anything
149
+ fs_1.default.rmSync(distDir, { recursive: true, force: true });
150
+ fs_1.default.mkdirSync(distDir, { recursive: true });
151
+ lockedData.onStep('step-created', (step) => {
152
+ if (step.config.type === 'noop') {
153
+ return;
154
+ }
155
+ else if (step.filePath.endsWith('.ts') || step.filePath.endsWith('.js')) {
156
+ return promises.push(buildNode(step, builder));
157
+ }
158
+ else if (step.filePath.endsWith('.py')) {
159
+ return promises.push(buildPython(step, builder));
160
+ }
161
+ else {
162
+ return builder.printer.printStepSkipped(step, 'File not supported');
163
+ }
164
+ });
165
+ await (0, generate_locked_data_1.collectFlows)(path_1.default.join(projectDir, 'steps'), lockedData);
166
+ await Promise.all(promises);
167
+ fs_1.default.writeFileSync(stepsConfigPath, JSON.stringify(builder.stepsConfig, null, 2));
168
+ console.log(colors_1.default.green('✓ [SUCCESS] '), 'Build completed');
169
+ };
170
+ exports.build = build;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.CLIOutputManager = void 0;
7
+ const readline_1 = __importDefault(require("readline"));
8
+ class CLIOutputManager {
9
+ constructor() {
10
+ this.lines = new Map(); // Track line positions
11
+ this.lineCount = 0;
12
+ }
13
+ logStep(id, message) {
14
+ this.lines.set(id, this.lineCount);
15
+ process.stdout.write(`${message}\n`);
16
+ this.lineCount++;
17
+ }
18
+ updateStep(id, newMessage) {
19
+ const lineIndex = this.lines.get(id);
20
+ if (lineIndex === undefined)
21
+ return;
22
+ readline_1.default.moveCursor(process.stdout, 0, -(this.lineCount - lineIndex));
23
+ readline_1.default.clearLine(process.stdout, 0);
24
+ process.stdout.write(`${newMessage}\n`);
25
+ readline_1.default.moveCursor(process.stdout, 0, this.lineCount - lineIndex - 1);
26
+ }
27
+ }
28
+ exports.CLIOutputManager = CLIOutputManager;
@@ -0,0 +1,31 @@
1
+ import os
2
+ import sys
3
+ import json
4
+ import modulegraph.modulegraph
5
+
6
+ NODEIPCFD = int(os.environ["NODE_CHANNEL_FD"])
7
+
8
+ def trace_imports(entry_file):
9
+ module_dir = os.path.dirname(os.path.abspath(entry_file))
10
+ """Find all imported Python files starting from an entry file."""
11
+ # Add both the module directory and current Python path to search paths
12
+ paths = [module_dir] + sys.path
13
+ graph = modulegraph.modulegraph.ModuleGraph(paths)
14
+ graph.run_script(entry_file)
15
+
16
+ files = set()
17
+ cwd = os.getcwd()
18
+ for mod in graph.nodes():
19
+ if mod.filename and mod.filename.endswith(".py"):
20
+ abs_path = os.path.abspath(mod.filename)
21
+ if abs_path.startswith(cwd):
22
+ rel_path = os.path.relpath(abs_path, cwd)
23
+ files.add(rel_path)
24
+
25
+ return list(files)
26
+
27
+ if __name__ == "__main__":
28
+ entry_file = sys.argv[1] # Get entrypoint from CLI args
29
+ files = trace_imports(entry_file)
30
+ bytes_message = (json.dumps(files) + '\n').encode('utf-8')
31
+ os.write(NODEIPCFD, bytes_message)
package/dist/src/cli.js CHANGED
@@ -4,13 +4,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  return (mod && mod.__esModule) ? mod : { "default": mod };
5
5
  };
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
+ /* eslint-disable @typescript-eslint/no-require-imports */
7
8
  const commander_1 = require("commander");
8
9
  const path_1 = __importDefault(require("path"));
9
10
  const fs_1 = __importDefault(require("fs"));
10
11
  const defaultPort = 3000;
11
- // eslint-disable-next-line @typescript-eslint/no-require-imports
12
12
  require('dotenv/config');
13
- // eslint-disable-next-line @typescript-eslint/no-require-imports
14
13
  require('ts-node').register({
15
14
  transpileOnly: true,
16
15
  compilerOptions: { module: 'commonjs' },
@@ -21,7 +20,6 @@ commander_1.program
21
20
  .option('-n, --name <project name>', 'The name for your project, used to create a directory, use ./ or . to create it under the existing directory')
22
21
  .option('-t, --template <template name>', 'The motia template name to use for your project')
23
22
  .action(async (arg) => {
24
- // eslint-disable-next-line @typescript-eslint/no-require-imports
25
23
  const { create } = require('./create');
26
24
  await create({
27
25
  projectName: arg.project ?? '.',
@@ -32,7 +30,6 @@ commander_1.program
32
30
  .command('templates')
33
31
  .description('Prints the list of available templates')
34
32
  .action(async () => {
35
- // eslint-disable-next-line @typescript-eslint/no-require-imports
36
33
  const { templates } = require('./create/templates');
37
34
  console.log(`📝 Available templates: \n\n ${Object.keys(templates).join('\n')}`);
38
35
  });
@@ -40,6 +37,7 @@ commander_1.program
40
37
  .command('dev')
41
38
  .description('Start the development server')
42
39
  .option('-p, --port <port>', 'The port to run the server on', `${defaultPort}`)
40
+ .option('-v, --verbose', 'Enable verbose logging')
43
41
  .option('-d, --debug', 'Enable debug logging')
44
42
  .action(async (arg) => {
45
43
  if (arg.debug) {
@@ -47,19 +45,25 @@ commander_1.program
47
45
  process.env.LOG_LEVEL = 'debug';
48
46
  }
49
47
  const port = arg.port ? parseInt(arg.port) : defaultPort;
50
- const { dev } = require('./dev'); // eslint-disable-line @typescript-eslint/no-require-imports
51
- await dev(port);
48
+ const { dev } = require('./dev');
49
+ await dev(port, arg.verbose);
50
+ });
51
+ commander_1.program
52
+ .command('build')
53
+ .description('Build the project')
54
+ .action(async () => {
55
+ const { build } = require('./builder/build');
56
+ await build();
52
57
  });
53
58
  commander_1.program
54
59
  .command('get-config')
55
60
  .description('Get the generated config for your project')
56
61
  .option('-o, --output <port>', 'Path to write the generated config')
57
62
  .action(async (arg) => {
58
- // eslint-disable-next-line @typescript-eslint/no-require-imports
59
63
  const { generateLockedData } = require('./src/generate/locked-data');
60
64
  const lockedData = await generateLockedData(path_1.default.join(process.cwd()));
61
65
  if (arg.output) {
62
- const fs = require('fs'); // eslint-disable-line @typescript-eslint/no-require-imports
66
+ const fs = require('fs');
63
67
  fs.writeFileSync(path_1.default.join(arg.output, '.motia.generated.json'), JSON.stringify(lockedData, null, 2));
64
68
  console.log(`📄 Wrote locked data to ${arg.output}`);
65
69
  return;
@@ -101,7 +105,7 @@ generate
101
105
  .description('Create a new step with interactive prompts')
102
106
  .option('-d, --dir <step file path>', 'The path relative to the steps directory, used to create the step file')
103
107
  .action(async (arg) => {
104
- const { createStep } = require('./create-step'); // eslint-disable-line @typescript-eslint/no-require-imports
108
+ const { createStep } = require('./create-step');
105
109
  await createStep({
106
110
  stepFilePath: arg.dir,
107
111
  });
@@ -117,7 +121,7 @@ state
117
121
  console.error('Error: State file not found at', statePath);
118
122
  process.exit(1);
119
123
  }
120
- const state = require(statePath); // eslint-disable-line @typescript-eslint/no-require-imports
124
+ const state = require(statePath);
121
125
  console.log(JSON.stringify(state, null, 2));
122
126
  }
123
127
  catch (error) {
@@ -18,7 +18,7 @@ export const handler: StepHandler<typeof config> = async (req, { logger, emit })
18
18
  logger.info('processing default flow api step', req)
19
19
 
20
20
  await emit({
21
- type: 'test-state',
21
+ topic: 'test-state',
22
22
  data: {},
23
23
  })
24
24
 
@@ -23,7 +23,7 @@ export const handler: StepHandler<typeof config> = async (input, { traceId, logg
23
23
  await state.set<any>(traceId, 'test', message)
24
24
 
25
25
  await emit({
26
- type: 'check-state-change',
26
+ topic: 'check-state-change',
27
27
  data: {key: 'test', expected: message}
28
28
  })
29
29
  }
@@ -14,7 +14,7 @@ export const handler = async ({ logger, emit }) => {
14
14
 
15
15
  // Example emit
16
16
  // await emit({
17
- // type: 'event-type',
17
+ // topic: 'event-type',
18
18
  // data: {}
19
19
  // })
20
20
  }
@@ -14,6 +14,6 @@ async def handler(context):
14
14
 
15
15
  # Example emit
16
16
  # await context.emit({
17
- # "type": "event-type",
17
+ # "topic": "event-type",
18
18
  # "data": {}
19
19
  # })
@@ -16,7 +16,7 @@ def handler(context)
16
16
 
17
17
  # Example emit
18
18
  # context.emit({
19
- # type: 'event-type',
19
+ # topic: 'event-type',
20
20
  # data: {}
21
21
  # })
22
22
  end
@@ -16,7 +16,7 @@ export const handler: StepHandler<typeof config> = async ({ logger, emit }) => {
16
16
 
17
17
  // Example emit
18
18
  // await emit({
19
- // type: 'event-type',
19
+ // topic: 'event-type',
20
20
  // data: {}
21
21
  // })
22
22
  }
@@ -16,7 +16,7 @@ export const handler = async ({ logger, emit }: FlowContext) => {
16
16
 
17
17
  // Example emit
18
18
  // await emit({
19
- // type: 'event-type',
19
+ // topic: 'event-type',
20
20
  // data: {}
21
21
  // })
22
22
  }
@@ -21,7 +21,7 @@ export const handler = async (input, { logger, emit }) => {
21
21
 
22
22
  // Example emit
23
23
  // await emit({
24
- // type: 'event-type',
24
+ // topic: 'event-type',
25
25
  // data: {}
26
26
  // })
27
27
  }
@@ -15,6 +15,6 @@ async def handler(args, ctx):
15
15
 
16
16
  # Add your handler logic here
17
17
  # await ctx.emit({
18
- # type: 'event-type',
18
+ # topic: 'event-type',
19
19
  # data: {}
20
20
  # })
@@ -16,7 +16,7 @@ def handler(input, context)
16
16
 
17
17
  # Example emit
18
18
  # context.emit({
19
- # type: 'event-type',
19
+ # topic: 'event-type',
20
20
  # data: {}
21
21
  # })
22
22
  end
@@ -24,7 +24,7 @@ export const handler: StepHandler<typeof config> = async (input, { logger, emit
24
24
 
25
25
  // Example emit
26
26
  // await emit({
27
- // type: 'event-type',
27
+ // topic: 'event-type',
28
28
  // data: {}
29
29
  // })
30
30
  }
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.workflowConfigEndpoints = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const workflowConfigEndpoints = (server, baseDir) => {
10
+ const { app } = server;
11
+ app.post('/flows/:id/config', async (req, res) => {
12
+ const { id } = req.params;
13
+ const config = req.body;
14
+ const configDir = path_1.default.join(baseDir, '.motia', 'flow-config');
15
+ const configPath = path_1.default.join(configDir, `${id}.workflow.config.json`);
16
+ try {
17
+ fs_1.default.mkdirSync(configDir, { recursive: true });
18
+ fs_1.default.writeFileSync(configPath, JSON.stringify(config, null, 2));
19
+ res.status(200).send({ message: 'Workflow config saved' });
20
+ }
21
+ catch (error) {
22
+ console.error('Error saving workflow config:', error);
23
+ res.status(500).json({ error: 'Failed to save workflow config' });
24
+ }
25
+ });
26
+ app.get('/flows/:id/config', async (req, res) => {
27
+ const { id } = req.params;
28
+ const configPath = path_1.default.join(baseDir, '.motia', 'flow-config', `${id}.workflow.config.json`);
29
+ try {
30
+ const config = fs_1.default.existsSync(configPath) ? JSON.parse(fs_1.default.readFileSync(configPath, 'utf8')) : {};
31
+ res.status(200).send(config);
32
+ }
33
+ catch (error) {
34
+ console.error('Error reading workflow config:', error);
35
+ res.status(200).send({});
36
+ }
37
+ });
38
+ };
39
+ exports.workflowConfigEndpoints = workflowConfigEndpoints;
package/dist/src/dev.js CHANGED
@@ -4,17 +4,19 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.dev = void 0;
7
+ // packages/snap/src/dev.ts
7
8
  const core_1 = require("@motiadev/core");
8
9
  const generate_locked_data_1 = require("./generate-locked-data");
9
10
  const path_1 = __importDefault(require("path"));
10
11
  const dev_watchers_1 = require("./dev-watchers");
11
12
  const state_endpoints_1 = require("./dev/state-endpoints");
13
+ const workflow_config_endpoints_1 = require("./dev/workflow-config-endpoints");
12
14
  // eslint-disable-next-line @typescript-eslint/no-require-imports
13
15
  require('ts-node').register({
14
16
  transpileOnly: true,
15
17
  compilerOptions: { module: 'commonjs' },
16
18
  });
17
- const dev = async (port) => {
19
+ const dev = async (port, isVerbose) => {
18
20
  const baseDir = process.cwd();
19
21
  const lockedData = await (0, generate_locked_data_1.generateLockedData)(baseDir);
20
22
  const eventManager = (0, core_1.createEventManager)();
@@ -23,11 +25,13 @@ const dev = async (port) => {
23
25
  filePath: path_1.default.join(baseDir, '.motia'),
24
26
  });
25
27
  await state.init();
26
- const motiaServer = await (0, core_1.createServer)(lockedData, eventManager, state);
28
+ const config = { isVerbose };
29
+ const motiaServer = await (0, core_1.createServer)(lockedData, eventManager, state, config);
27
30
  const motiaEventManager = (0, core_1.createStepHandlers)(lockedData, eventManager, state);
28
31
  const watcher = (0, dev_watchers_1.createDevWatchers)(lockedData, motiaServer, motiaEventManager, motiaServer.cronManager);
29
32
  watcher.init();
30
33
  (0, state_endpoints_1.stateEndpoints)(motiaServer, state);
34
+ (0, workflow_config_endpoints_1.workflowConfigEndpoints)(motiaServer, baseDir);
31
35
  motiaServer.server.listen(port);
32
36
  console.log('🚀 Server ready and listening on port', port);
33
37
  console.log(`🔗 Open http://localhost:${port}/ to open workbench 🛠️`);
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.generateLockedData = void 0;
6
+ exports.generateLockedData = exports.collectFlows = void 0;
7
7
  const core_1 = require("@motiadev/core");
8
8
  const crypto_1 = require("crypto");
9
9
  const fs_1 = __importDefault(require("fs"));
@@ -16,7 +16,7 @@ const collectFlows = async (baseDir, lockedData) => {
16
16
  for (const item of folderItems) {
17
17
  const filePath = path_1.default.join(baseDir, item.name);
18
18
  if (item.isDirectory()) {
19
- steps = steps.concat(await collectFlows(filePath, lockedData));
19
+ steps = steps.concat(await (0, exports.collectFlows)(filePath, lockedData));
20
20
  }
21
21
  else if (item.name.match(/\.step\.(ts|js|py|rb)$/)) {
22
22
  const config = await (0, core_1.getStepConfig)(filePath);
@@ -29,6 +29,7 @@ const collectFlows = async (baseDir, lockedData) => {
29
29
  }
30
30
  return steps;
31
31
  };
32
+ exports.collectFlows = collectFlows;
32
33
  const generateLockedData = async (projectDir) => {
33
34
  try {
34
35
  /*
@@ -36,7 +37,7 @@ const generateLockedData = async (projectDir) => {
36
37
  * but we might want to remove this and scan the entire current directory
37
38
  */
38
39
  const lockedData = new core_1.LockedData(projectDir);
39
- await collectFlows(path_1.default.join(projectDir, 'steps'), lockedData);
40
+ await (0, exports.collectFlows)(path_1.default.join(projectDir, 'steps'), lockedData);
40
41
  return lockedData;
41
42
  }
42
43
  catch (error) {
package/package.json CHANGED
@@ -1,23 +1,26 @@
1
1
  {
2
2
  "name": "motia",
3
- "version": "0.0.28",
3
+ "version": "0.0.30",
4
4
  "license": "MIT",
5
5
  "bin": {
6
6
  "motia": "dist/src/cli.js"
7
7
  },
8
8
  "dependencies": {
9
+ "archiver": "^7.0.1",
9
10
  "chokidar": "^4.0.3",
10
11
  "colors": "^1.4.0",
11
12
  "commander": "^13.0.0",
12
13
  "dotenv": "^16.4.7",
14
+ "esbuild": "^0.25.0",
13
15
  "figlet": "^1.8.0",
14
16
  "inquirer": "^12.4.1",
15
17
  "ts-node": "^10.9.2",
16
18
  "yaml": "^2.7.0",
17
- "@motiadev/core": "0.0.28",
18
- "@motiadev/workbench": "0.0.28"
19
+ "@motiadev/core": "0.0.30",
20
+ "@motiadev/workbench": "0.0.30"
19
21
  },
20
22
  "devDependencies": {
23
+ "@types/archiver": "^6.0.3",
21
24
  "@types/figlet": "^1.7.0",
22
25
  "@types/jest": "^29.5.14",
23
26
  "jest": "^29.7.0",
@@ -26,7 +29,8 @@
26
29
  },
27
30
  "scripts": {
28
31
  "move:templates": "sh scripts/move-templates.sh",
29
- "build": "rm -rf dist && tsc && pnpm run move:templates",
32
+ "move:python": "sh scripts/move-python.sh",
33
+ "build": "rm -rf dist && tsc && pnpm run move:templates && pnpm run move:python",
30
34
  "lint": "eslint --config ../../eslint.config.js"
31
35
  }
32
36
  }
@@ -0,0 +1 @@
1
+ cp src/builder/python-builder.py dist/src/builder/python-builder.py