motia 0.15.4-beta.170-888624 → 0.15.4-beta.170-803755

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/dist/dev.mjs CHANGED
@@ -9,6 +9,7 @@ import { createDevWatchers } from "./dev-watchers.mjs";
9
9
  import { processPlugins } from "./plugins/process-plugins.mjs";
10
10
  import "./plugins/index.mjs";
11
11
  import { getRedisClient, getRedisConnectionInfo, stopRedisConnection } from "./redis/connection.mjs";
12
+ import { validatePythonEnvironment } from "./utils/validate-python-environment.mjs";
12
13
  import { createMermaidGenerator, createServer, getProjectIdentifier, trackEvent } from "@motiadev/core";
13
14
  import { flush } from "@amplitude/analytics-node";
14
15
  import { BullMQEventAdapter } from "@motiadev/adapter-bullmq-events";
@@ -31,7 +32,12 @@ const dev = async (port, hostname, disableVerbose, enableMermaid, motiaFileStora
31
32
  total_step_files: stepFiles.length,
32
33
  project_name: getProjectIdentifier(baseDir)
33
34
  });
34
- if (hasPythonFiles) {
35
+ const pythonValidation = await validatePythonEnvironment({
36
+ baseDir,
37
+ hasPythonFiles
38
+ });
39
+ if (!pythonValidation.success) process.exit(1);
40
+ if (pythonValidation.hasPythonFiles) {
35
41
  activatePythonVenv({
36
42
  baseDir,
37
43
  isVerbose
package/dist/dev.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"dev.mjs","names":["redisClient: RedisClientType","plugins: MotiaPlugin[]"],"sources":["../src/dev.ts"],"sourcesContent":["import { flush } from '@amplitude/analytics-node'\nimport { BullMQEventAdapter } from '@motiadev/adapter-bullmq-events'\nimport { RedisCronAdapter } from '@motiadev/adapter-redis-cron'\nimport { RedisStateAdapter } from '@motiadev/adapter-redis-state'\nimport { RedisStreamAdapterManager } from '@motiadev/adapter-redis-streams'\nimport {\n createMermaidGenerator,\n createServer,\n getProjectIdentifier,\n type MotiaPlugin,\n trackEvent,\n} from '@motiadev/core'\nimport type { RedisClientType } from 'redis'\nimport { deployEndpoints } from './cloud/endpoints'\nimport { isTutorialDisabled, workbenchBase } from './constants'\nimport { createDevWatchers } from './dev-watchers'\nimport { generateLockedData, getStepFiles, getStreamFiles } from './generate-locked-data'\nimport { loadMotiaConfig } from './load-motia-config'\nimport { processPlugins } from './plugins'\nimport { getRedisClient, getRedisConnectionInfo, stopRedisConnection } from './redis/connection'\nimport { activatePythonVenv } from './utils/activate-python-env'\nimport { identifyUser } from './utils/analytics'\nimport { version } from './version'\n\nexport const dev = async (\n port: number,\n hostname: string,\n disableVerbose: boolean,\n enableMermaid: boolean,\n motiaFileStorageDir?: string,\n): Promise<void> => {\n const baseDir = process.cwd()\n const isVerbose = !disableVerbose\n\n identifyUser()\n\n const stepFiles = [...getStepFiles(baseDir), ...getStreamFiles(baseDir)]\n const hasPythonFiles = stepFiles.some((file) => file.endsWith('.py'))\n\n trackEvent('dev_server_started', {\n port,\n verbose_mode: isVerbose,\n mermaid_enabled: enableMermaid,\n has_python_files: hasPythonFiles,\n total_step_files: stepFiles.length,\n project_name: getProjectIdentifier(baseDir),\n })\n\n if (hasPythonFiles) {\n activatePythonVenv({ baseDir, isVerbose })\n trackEvent('python_environment_activated')\n }\n\n const motiaFileStoragePath = motiaFileStorageDir || '.motia'\n\n const appConfig = await loadMotiaConfig(baseDir)\n\n const redisClient: RedisClientType = await getRedisClient(motiaFileStoragePath, appConfig)\n\n const adapters = {\n eventAdapter:\n appConfig.adapters?.events ||\n new BullMQEventAdapter({\n connection: getRedisConnectionInfo(),\n prefix: 'motia:events',\n }),\n cronAdapter: appConfig.adapters?.cron || new RedisCronAdapter(redisClient),\n streamAdapter: appConfig.adapters?.streams || new RedisStreamAdapterManager(redisClient),\n }\n\n const lockedData = await generateLockedData({\n projectDir: baseDir,\n streamAdapter: adapters.streamAdapter,\n redisClient,\n streamAuth: appConfig.streamAuth,\n })\n\n const state = appConfig.adapters?.state || new RedisStateAdapter(redisClient)\n\n const config = { isVerbose }\n\n const motiaServer = createServer(lockedData, state, config, adapters, appConfig.app)\n const watcher = createDevWatchers(lockedData, motiaServer, motiaServer.motiaEventManager, motiaServer.cronManager)\n const plugins: MotiaPlugin[] = await processPlugins(motiaServer)\n\n // Initialize mermaid generator\n if (enableMermaid) {\n const mermaidGenerator = createMermaidGenerator(baseDir)\n mermaidGenerator.initialize(lockedData)\n trackEvent('mermaid_generator_initialized')\n }\n\n deployEndpoints(motiaServer, lockedData)\n\n motiaServer.app.get('/__motia', (_, res) => {\n const meta = {\n version,\n isDev: true,\n isTutorialDisabled,\n workbenchBase,\n }\n\n res //\n .header('Access-Control-Allow-Origin', '*')\n .header('Access-Control-Allow-Private-Network', 'true')\n .status(200)\n .json(meta)\n })\n\n trackEvent('dev_server_ready', {\n port,\n flows_count: lockedData.flows?.length || 0,\n steps_count: lockedData.activeSteps?.length || 0,\n flows: Object.keys(lockedData.flows || {}),\n steps: lockedData.activeSteps.map((step) => step.config.name),\n streams: Object.keys(lockedData.getStreams() || {}),\n runtime_version: version,\n environment: process.env.NODE_ENV || 'development',\n })\n\n const { applyMiddleware } = await import('@motiadev/workbench/middleware')\n\n await applyMiddleware({\n app: motiaServer.app,\n port,\n workbenchBase,\n plugins: plugins.flatMap((item) => item.workbench),\n })\n\n motiaServer.server.listen(port, hostname)\n console.log('🚀 Server ready and listening on port', port)\n console.log(`🔗 Open http://localhost:${port}${workbenchBase} to open workbench 🛠️`)\n\n process.on('SIGTERM', async () => {\n trackEvent('dev_server_shutdown', { reason: 'SIGTERM' })\n motiaServer.server.close()\n await watcher.stop()\n await stopRedisConnection()\n await flush().promise\n process.exit(0)\n })\n\n process.on('SIGINT', async () => {\n trackEvent('dev_server_shutdown', { reason: 'SIGINT' })\n motiaServer.server.close()\n await watcher.stop()\n await stopRedisConnection()\n await flush().promise\n process.exit(0)\n })\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"dev.mjs","names":["redisClient: RedisClientType","plugins: MotiaPlugin[]"],"sources":["../src/dev.ts"],"sourcesContent":["import { flush } from '@amplitude/analytics-node'\nimport { BullMQEventAdapter } from '@motiadev/adapter-bullmq-events'\nimport { RedisCronAdapter } from '@motiadev/adapter-redis-cron'\nimport { RedisStateAdapter } from '@motiadev/adapter-redis-state'\nimport { RedisStreamAdapterManager } from '@motiadev/adapter-redis-streams'\nimport {\n createMermaidGenerator,\n createServer,\n getProjectIdentifier,\n type MotiaPlugin,\n trackEvent,\n} from '@motiadev/core'\nimport type { RedisClientType } from 'redis'\nimport { deployEndpoints } from './cloud/endpoints'\nimport { isTutorialDisabled, workbenchBase } from './constants'\nimport { createDevWatchers } from './dev-watchers'\nimport { generateLockedData, getStepFiles, getStreamFiles } from './generate-locked-data'\nimport { loadMotiaConfig } from './load-motia-config'\nimport { processPlugins } from './plugins'\nimport { getRedisClient, getRedisConnectionInfo, stopRedisConnection } from './redis/connection'\nimport { activatePythonVenv } from './utils/activate-python-env'\nimport { identifyUser } from './utils/analytics'\nimport { validatePythonEnvironment } from './utils/validate-python-environment'\nimport { version } from './version'\n\nexport const dev = async (\n port: number,\n hostname: string,\n disableVerbose: boolean,\n enableMermaid: boolean,\n motiaFileStorageDir?: string,\n): Promise<void> => {\n const baseDir = process.cwd()\n const isVerbose = !disableVerbose\n\n identifyUser()\n\n const stepFiles = [...getStepFiles(baseDir), ...getStreamFiles(baseDir)]\n const hasPythonFiles = stepFiles.some((file) => file.endsWith('.py'))\n\n trackEvent('dev_server_started', {\n port,\n verbose_mode: isVerbose,\n mermaid_enabled: enableMermaid,\n has_python_files: hasPythonFiles,\n total_step_files: stepFiles.length,\n project_name: getProjectIdentifier(baseDir),\n })\n\n const pythonValidation = await validatePythonEnvironment({ baseDir, hasPythonFiles })\n if (!pythonValidation.success) {\n process.exit(1)\n }\n\n if (pythonValidation.hasPythonFiles) {\n activatePythonVenv({ baseDir, isVerbose })\n trackEvent('python_environment_activated')\n }\n\n const motiaFileStoragePath = motiaFileStorageDir || '.motia'\n\n const appConfig = await loadMotiaConfig(baseDir)\n\n const redisClient: RedisClientType = await getRedisClient(motiaFileStoragePath, appConfig)\n\n const adapters = {\n eventAdapter:\n appConfig.adapters?.events ||\n new BullMQEventAdapter({\n connection: getRedisConnectionInfo(),\n prefix: 'motia:events',\n }),\n cronAdapter: appConfig.adapters?.cron || new RedisCronAdapter(redisClient),\n streamAdapter: appConfig.adapters?.streams || new RedisStreamAdapterManager(redisClient),\n }\n\n const lockedData = await generateLockedData({\n projectDir: baseDir,\n streamAdapter: adapters.streamAdapter,\n redisClient,\n streamAuth: appConfig.streamAuth,\n })\n\n const state = appConfig.adapters?.state || new RedisStateAdapter(redisClient)\n\n const config = { isVerbose }\n\n const motiaServer = createServer(lockedData, state, config, adapters, appConfig.app)\n const watcher = createDevWatchers(lockedData, motiaServer, motiaServer.motiaEventManager, motiaServer.cronManager)\n const plugins: MotiaPlugin[] = await processPlugins(motiaServer)\n\n // Initialize mermaid generator\n if (enableMermaid) {\n const mermaidGenerator = createMermaidGenerator(baseDir)\n mermaidGenerator.initialize(lockedData)\n trackEvent('mermaid_generator_initialized')\n }\n\n deployEndpoints(motiaServer, lockedData)\n\n motiaServer.app.get('/__motia', (_, res) => {\n const meta = {\n version,\n isDev: true,\n isTutorialDisabled,\n workbenchBase,\n }\n\n res //\n .header('Access-Control-Allow-Origin', '*')\n .header('Access-Control-Allow-Private-Network', 'true')\n .status(200)\n .json(meta)\n })\n\n trackEvent('dev_server_ready', {\n port,\n flows_count: lockedData.flows?.length || 0,\n steps_count: lockedData.activeSteps?.length || 0,\n flows: Object.keys(lockedData.flows || {}),\n steps: lockedData.activeSteps.map((step) => step.config.name),\n streams: Object.keys(lockedData.getStreams() || {}),\n runtime_version: version,\n environment: process.env.NODE_ENV || 'development',\n })\n\n const { applyMiddleware } = await import('@motiadev/workbench/middleware')\n\n await applyMiddleware({\n app: motiaServer.app,\n port,\n workbenchBase,\n plugins: plugins.flatMap((item) => item.workbench),\n })\n\n motiaServer.server.listen(port, hostname)\n console.log('🚀 Server ready and listening on port', port)\n console.log(`🔗 Open http://localhost:${port}${workbenchBase} to open workbench 🛠️`)\n\n process.on('SIGTERM', async () => {\n trackEvent('dev_server_shutdown', { reason: 'SIGTERM' })\n motiaServer.server.close()\n await watcher.stop()\n await stopRedisConnection()\n await flush().promise\n process.exit(0)\n })\n\n process.on('SIGINT', async () => {\n trackEvent('dev_server_shutdown', { reason: 'SIGINT' })\n motiaServer.server.close()\n await watcher.stop()\n await stopRedisConnection()\n await flush().promise\n process.exit(0)\n })\n}\n"],"mappings":"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"}
package/dist/start.mjs CHANGED
@@ -6,6 +6,7 @@ import { workbenchBase } from "./constants.mjs";
6
6
  import { processPlugins } from "./plugins/process-plugins.mjs";
7
7
  import "./plugins/index.mjs";
8
8
  import { getRedisClient, getRedisConnectionInfo, stopRedisConnection } from "./redis/connection.mjs";
9
+ import { validatePythonEnvironment } from "./utils/validate-python-environment.mjs";
9
10
  import { createServer } from "@motiadev/core";
10
11
  import path from "path";
11
12
  import { BullMQEventAdapter } from "@motiadev/adapter-bullmq-events";
@@ -17,7 +18,12 @@ import { RedisStreamAdapterManager } from "@motiadev/adapter-redis-streams";
17
18
  const start = async (port, hostname, disableVerbose, motiaFileStorageDir) => {
18
19
  const baseDir = process.cwd();
19
20
  const isVerbose = !disableVerbose;
20
- if ([...getStepFiles(baseDir), ...getStreamFiles(baseDir)].some((file) => file.endsWith(".py"))) {
21
+ const pythonValidation = await validatePythonEnvironment({
22
+ baseDir,
23
+ hasPythonFiles: [...getStepFiles(baseDir), ...getStreamFiles(baseDir)].some((file) => file.endsWith(".py"))
24
+ });
25
+ if (!pythonValidation.success) process.exit(1);
26
+ if (pythonValidation.hasPythonFiles) {
21
27
  console.log("⚙️ Activating Python environment...");
22
28
  activatePythonVenv({
23
29
  baseDir,
@@ -1 +1 @@
1
- {"version":3,"file":"start.mjs","names":["redisClient: RedisClientType","plugins: MotiaPlugin[]"],"sources":["../src/start.ts"],"sourcesContent":["import { BullMQEventAdapter } from '@motiadev/adapter-bullmq-events'\nimport { RedisCronAdapter } from '@motiadev/adapter-redis-cron'\nimport { RedisStateAdapter } from '@motiadev/adapter-redis-state'\nimport { RedisStreamAdapterManager } from '@motiadev/adapter-redis-streams'\nimport { createServer, type MotiaPlugin } from '@motiadev/core'\nimport path from 'path'\nimport type { RedisClientType } from 'redis'\nimport { workbenchBase } from './constants'\nimport { generateLockedData, getStepFiles, getStreamFiles } from './generate-locked-data'\nimport { loadMotiaConfig } from './load-motia-config'\nimport { processPlugins } from './plugins/index'\nimport { getRedisClient, getRedisConnectionInfo, stopRedisConnection } from './redis/connection'\nimport { activatePythonVenv } from './utils/activate-python-env'\nimport { version } from './version'\n\nexport const start = async (\n port: number,\n hostname: string,\n disableVerbose: boolean,\n motiaFileStorageDir?: string,\n): Promise<void> => {\n const baseDir = process.cwd()\n const isVerbose = !disableVerbose\n\n const stepFiles = [...getStepFiles(baseDir), ...getStreamFiles(baseDir)]\n const hasPythonFiles = stepFiles.some((file) => file.endsWith('.py'))\n\n if (hasPythonFiles) {\n console.log('⚙️ Activating Python environment...')\n activatePythonVenv({ baseDir, isVerbose })\n }\n\n const motiaFileStoragePath = motiaFileStorageDir || '.motia'\n\n const dotMotia = path.join(baseDir, motiaFileStoragePath)\n const appConfig = await loadMotiaConfig(baseDir)\n\n const redisClient: RedisClientType = await getRedisClient(dotMotia, appConfig)\n\n const adapters = {\n eventAdapter:\n appConfig.adapters?.events ||\n new BullMQEventAdapter({\n connection: getRedisConnectionInfo(),\n }),\n cronAdapter: appConfig.adapters?.cron || new RedisCronAdapter(redisClient),\n streamAdapter: appConfig.adapters?.streams || new RedisStreamAdapterManager(redisClient),\n }\n const lockedData = await generateLockedData({\n projectDir: baseDir,\n streamAdapter: adapters.streamAdapter,\n redisClient,\n streamAuth: appConfig.streamAuth,\n })\n\n const state = appConfig.adapters?.state || new RedisStateAdapter(redisClient)\n\n const config = { isVerbose, isDev: false, version }\n\n const motiaServer = createServer(lockedData, state, config, adapters, appConfig.app)\n const plugins: MotiaPlugin[] = await processPlugins(motiaServer)\n\n if (!process.env.MOTIA_DOCKER_DISABLE_WORKBENCH) {\n const { applyMiddleware } = await import('@motiadev/workbench/middleware')\n await applyMiddleware({\n app: motiaServer.app,\n port,\n workbenchBase,\n plugins: plugins.flatMap((item) => item.workbench),\n })\n }\n\n motiaServer.server.listen(port, hostname)\n console.log('🚀 Server ready and listening on port', port)\n console.log(`🔗 Open http://${hostname}:${port}${workbenchBase} to open workbench 🛠️`)\n\n process.on('SIGTERM', async () => {\n motiaServer.server.close()\n await stopRedisConnection()\n process.exit(0)\n })\n\n process.on('SIGINT', async () => {\n motiaServer.server.close()\n await stopRedisConnection()\n process.exit(0)\n })\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAeA,MAAa,QAAQ,OACnB,MACA,UACA,gBACA,wBACkB;CAClB,MAAM,UAAU,QAAQ,KAAK;CAC7B,MAAM,YAAY,CAAC;AAKnB,KAHkB,CAAC,GAAG,aAAa,QAAQ,EAAE,GAAG,eAAe,QAAQ,CAAC,CACvC,MAAM,SAAS,KAAK,SAAS,MAAM,CAAC,EAEjD;AAClB,UAAQ,IAAI,sCAAsC;AAClD,qBAAmB;GAAE;GAAS;GAAW,CAAC;;CAG5C,MAAM,uBAAuB,uBAAuB;CAEpD,MAAM,WAAW,KAAK,KAAK,SAAS,qBAAqB;CACzD,MAAM,YAAY,MAAM,gBAAgB,QAAQ;CAEhD,MAAMA,cAA+B,MAAM,eAAe,UAAU,UAAU;CAE9E,MAAM,WAAW;EACf,cACE,UAAU,UAAU,UACpB,IAAI,mBAAmB,EACrB,YAAY,wBAAwB,EACrC,CAAC;EACJ,aAAa,UAAU,UAAU,QAAQ,IAAI,iBAAiB,YAAY;EAC1E,eAAe,UAAU,UAAU,WAAW,IAAI,0BAA0B,YAAY;EACzF;CAYD,MAAM,cAAc,aAXD,MAAM,mBAAmB;EAC1C,YAAY;EACZ,eAAe,SAAS;EACxB;EACA,YAAY,UAAU;EACvB,CAAC,EAEY,UAAU,UAAU,SAAS,IAAI,kBAAkB,YAAY,EAE9D;EAAE;EAAW,OAAO;EAAO;EAAS,EAES,UAAU,UAAU,IAAI;CACpF,MAAMC,UAAyB,MAAM,eAAe,YAAY;AAEhE,KAAI,CAAC,QAAQ,IAAI,gCAAgC;EAC/C,MAAM,EAAE,oBAAoB,MAAM,OAAO;AACzC,QAAM,gBAAgB;GACpB,KAAK,YAAY;GACjB;GACA;GACA,SAAS,QAAQ,SAAS,SAAS,KAAK,UAAU;GACnD,CAAC;;AAGJ,aAAY,OAAO,OAAO,MAAM,SAAS;AACzC,SAAQ,IAAI,yCAAyC,KAAK;AAC1D,SAAQ,IAAI,kBAAkB,SAAS,GAAG,OAAO,cAAc,wBAAwB;AAEvF,SAAQ,GAAG,WAAW,YAAY;AAChC,cAAY,OAAO,OAAO;AAC1B,QAAM,qBAAqB;AAC3B,UAAQ,KAAK,EAAE;GACf;AAEF,SAAQ,GAAG,UAAU,YAAY;AAC/B,cAAY,OAAO,OAAO;AAC1B,QAAM,qBAAqB;AAC3B,UAAQ,KAAK,EAAE;GACf"}
1
+ {"version":3,"file":"start.mjs","names":["redisClient: RedisClientType","plugins: MotiaPlugin[]"],"sources":["../src/start.ts"],"sourcesContent":["import { BullMQEventAdapter } from '@motiadev/adapter-bullmq-events'\nimport { RedisCronAdapter } from '@motiadev/adapter-redis-cron'\nimport { RedisStateAdapter } from '@motiadev/adapter-redis-state'\nimport { RedisStreamAdapterManager } from '@motiadev/adapter-redis-streams'\nimport { createServer, type MotiaPlugin } from '@motiadev/core'\nimport path from 'path'\nimport type { RedisClientType } from 'redis'\nimport { workbenchBase } from './constants'\nimport { generateLockedData, getStepFiles, getStreamFiles } from './generate-locked-data'\nimport { loadMotiaConfig } from './load-motia-config'\nimport { processPlugins } from './plugins/index'\nimport { getRedisClient, getRedisConnectionInfo, stopRedisConnection } from './redis/connection'\nimport { activatePythonVenv } from './utils/activate-python-env'\nimport { validatePythonEnvironment } from './utils/validate-python-environment'\nimport { version } from './version'\n\nexport const start = async (\n port: number,\n hostname: string,\n disableVerbose: boolean,\n motiaFileStorageDir?: string,\n): Promise<void> => {\n const baseDir = process.cwd()\n const isVerbose = !disableVerbose\n\n const stepFiles = [...getStepFiles(baseDir), ...getStreamFiles(baseDir)]\n const hasPythonFiles = stepFiles.some((file) => file.endsWith('.py'))\n\n const pythonValidation = await validatePythonEnvironment({ baseDir, hasPythonFiles })\n if (!pythonValidation.success) {\n process.exit(1)\n }\n\n if (pythonValidation.hasPythonFiles) {\n console.log('⚙️ Activating Python environment...')\n activatePythonVenv({ baseDir, isVerbose })\n }\n\n const motiaFileStoragePath = motiaFileStorageDir || '.motia'\n\n const dotMotia = path.join(baseDir, motiaFileStoragePath)\n const appConfig = await loadMotiaConfig(baseDir)\n\n const redisClient: RedisClientType = await getRedisClient(dotMotia, appConfig)\n\n const adapters = {\n eventAdapter:\n appConfig.adapters?.events ||\n new BullMQEventAdapter({\n connection: getRedisConnectionInfo(),\n }),\n cronAdapter: appConfig.adapters?.cron || new RedisCronAdapter(redisClient),\n streamAdapter: appConfig.adapters?.streams || new RedisStreamAdapterManager(redisClient),\n }\n const lockedData = await generateLockedData({\n projectDir: baseDir,\n streamAdapter: adapters.streamAdapter,\n redisClient,\n streamAuth: appConfig.streamAuth,\n })\n\n const state = appConfig.adapters?.state || new RedisStateAdapter(redisClient)\n\n const config = { isVerbose, isDev: false, version }\n\n const motiaServer = createServer(lockedData, state, config, adapters, appConfig.app)\n const plugins: MotiaPlugin[] = await processPlugins(motiaServer)\n\n if (!process.env.MOTIA_DOCKER_DISABLE_WORKBENCH) {\n const { applyMiddleware } = await import('@motiadev/workbench/middleware')\n await applyMiddleware({\n app: motiaServer.app,\n port,\n workbenchBase,\n plugins: plugins.flatMap((item) => item.workbench),\n })\n }\n\n motiaServer.server.listen(port, hostname)\n console.log('🚀 Server ready and listening on port', port)\n console.log(`🔗 Open http://${hostname}:${port}${workbenchBase} to open workbench 🛠️`)\n\n process.on('SIGTERM', async () => {\n motiaServer.server.close()\n await stopRedisConnection()\n process.exit(0)\n })\n\n process.on('SIGINT', async () => {\n motiaServer.server.close()\n await stopRedisConnection()\n process.exit(0)\n })\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAgBA,MAAa,QAAQ,OACnB,MACA,UACA,gBACA,wBACkB;CAClB,MAAM,UAAU,QAAQ,KAAK;CAC7B,MAAM,YAAY,CAAC;CAKnB,MAAM,mBAAmB,MAAM,0BAA0B;EAAE;EAAS,gBAHlD,CAAC,GAAG,aAAa,QAAQ,EAAE,GAAG,eAAe,QAAQ,CAAC,CACvC,MAAM,SAAS,KAAK,SAAS,MAAM,CAAC;EAEe,CAAC;AACrF,KAAI,CAAC,iBAAiB,QACpB,SAAQ,KAAK,EAAE;AAGjB,KAAI,iBAAiB,gBAAgB;AACnC,UAAQ,IAAI,sCAAsC;AAClD,qBAAmB;GAAE;GAAS;GAAW,CAAC;;CAG5C,MAAM,uBAAuB,uBAAuB;CAEpD,MAAM,WAAW,KAAK,KAAK,SAAS,qBAAqB;CACzD,MAAM,YAAY,MAAM,gBAAgB,QAAQ;CAEhD,MAAMA,cAA+B,MAAM,eAAe,UAAU,UAAU;CAE9E,MAAM,WAAW;EACf,cACE,UAAU,UAAU,UACpB,IAAI,mBAAmB,EACrB,YAAY,wBAAwB,EACrC,CAAC;EACJ,aAAa,UAAU,UAAU,QAAQ,IAAI,iBAAiB,YAAY;EAC1E,eAAe,UAAU,UAAU,WAAW,IAAI,0BAA0B,YAAY;EACzF;CAYD,MAAM,cAAc,aAXD,MAAM,mBAAmB;EAC1C,YAAY;EACZ,eAAe,SAAS;EACxB;EACA,YAAY,UAAU;EACvB,CAAC,EAEY,UAAU,UAAU,SAAS,IAAI,kBAAkB,YAAY,EAE9D;EAAE;EAAW,OAAO;EAAO;EAAS,EAES,UAAU,UAAU,IAAI;CACpF,MAAMC,UAAyB,MAAM,eAAe,YAAY;AAEhE,KAAI,CAAC,QAAQ,IAAI,gCAAgC;EAC/C,MAAM,EAAE,oBAAoB,MAAM,OAAO;AACzC,QAAM,gBAAgB;GACpB,KAAK,YAAY;GACjB;GACA;GACA,SAAS,QAAQ,SAAS,SAAS,KAAK,UAAU;GACnD,CAAC;;AAGJ,aAAY,OAAO,OAAO,MAAM,SAAS;AACzC,SAAQ,IAAI,yCAAyC,KAAK;AAC1D,SAAQ,IAAI,kBAAkB,SAAS,GAAG,OAAO,cAAc,wBAAwB;AAEvF,SAAQ,GAAG,WAAW,YAAY;AAChC,cAAY,OAAO,OAAO;AAC1B,QAAM,qBAAqB;AAC3B,UAAQ,KAAK,EAAE;GACf;AAEF,SAAQ,GAAG,UAAU,YAAY;AAC/B,cAAY,OAAO,OAAO;AAC1B,QAAM,qBAAqB;AAC3B,UAAQ,KAAK,EAAE;GACf"}
@@ -1,11 +1,17 @@
1
1
  import { checkIfFileExists } from "../create/utils.mjs";
2
+ import path from "path";
2
3
 
3
4
  //#region src/utils/get-package-manager.ts
4
5
  const getPackageManager = (dir) => {
5
- if (checkIfFileExists(dir, "yarn.lock")) return "yarn";
6
- else if (checkIfFileExists(dir, "pnpm-lock.yaml")) return "pnpm";
7
- else if (checkIfFileExists(dir, "package-lock.json")) return "npm";
8
- else return "unknown";
6
+ let currentDir = dir;
7
+ while (currentDir !== path.dirname(currentDir)) {
8
+ if (checkIfFileExists(currentDir, "yarn.lock")) return "yarn";
9
+ else if (checkIfFileExists(currentDir, "pnpm-lock.yaml")) return "pnpm";
10
+ else if (checkIfFileExists(currentDir, "package-lock.json")) return "npm";
11
+ else if (checkIfFileExists(currentDir, "bun.lockb") || checkIfFileExists(currentDir, "bun.lock")) return "bun";
12
+ currentDir = path.dirname(currentDir);
13
+ }
14
+ return "npm";
9
15
  };
10
16
 
11
17
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"get-package-manager.mjs","names":[],"sources":["../../src/utils/get-package-manager.ts"],"sourcesContent":["import { checkIfFileExists } from '../create/utils'\n\nexport const getPackageManager = (dir: string): string => {\n if (checkIfFileExists(dir, 'yarn.lock')) {\n return 'yarn'\n } else if (checkIfFileExists(dir, 'pnpm-lock.yaml')) {\n return 'pnpm'\n } else if (checkIfFileExists(dir, 'package-lock.json')) {\n return 'npm'\n } else {\n return 'unknown'\n }\n}\n"],"mappings":";;;AAEA,MAAa,qBAAqB,QAAwB;AACxD,KAAI,kBAAkB,KAAK,YAAY,CACrC,QAAO;UACE,kBAAkB,KAAK,iBAAiB,CACjD,QAAO;UACE,kBAAkB,KAAK,oBAAoB,CACpD,QAAO;KAEP,QAAO"}
1
+ {"version":3,"file":"get-package-manager.mjs","names":[],"sources":["../../src/utils/get-package-manager.ts"],"sourcesContent":["import path from 'path'\nimport { checkIfFileExists } from '../create/utils'\n\nexport const getPackageManager = (dir: string): string => {\n let currentDir = dir\n\n while (currentDir !== path.dirname(currentDir)) {\n if (checkIfFileExists(currentDir, 'yarn.lock')) {\n return 'yarn'\n } else if (checkIfFileExists(currentDir, 'pnpm-lock.yaml')) {\n return 'pnpm'\n } else if (checkIfFileExists(currentDir, 'package-lock.json')) {\n return 'npm'\n } else if (checkIfFileExists(currentDir, 'bun.lockb') || checkIfFileExists(currentDir, 'bun.lock')) {\n return 'bun'\n }\n currentDir = path.dirname(currentDir)\n }\n\n return 'npm'\n}\n"],"mappings":";;;;AAGA,MAAa,qBAAqB,QAAwB;CACxD,IAAI,aAAa;AAEjB,QAAO,eAAe,KAAK,QAAQ,WAAW,EAAE;AAC9C,MAAI,kBAAkB,YAAY,YAAY,CAC5C,QAAO;WACE,kBAAkB,YAAY,iBAAiB,CACxD,QAAO;WACE,kBAAkB,YAAY,oBAAoB,CAC3D,QAAO;WACE,kBAAkB,YAAY,YAAY,IAAI,kBAAkB,YAAY,WAAW,CAChG,QAAO;AAET,eAAa,KAAK,QAAQ,WAAW;;AAGvC,QAAO"}
@@ -0,0 +1,63 @@
1
+ import { internalLogger } from "./internal-logger.mjs";
2
+ import { getPythonCommand } from "./python-version-utils.mjs";
3
+ import { getPackageManager } from "./get-package-manager.mjs";
4
+ import fs from "fs";
5
+ import path from "path";
6
+
7
+ //#region src/utils/validate-python-environment.ts
8
+ function getInstallCommand(baseDir) {
9
+ switch (getPackageManager(baseDir)) {
10
+ case "yarn": return "yarn install";
11
+ case "pnpm": return "pnpm install";
12
+ case "bun": return "bun install";
13
+ case "npm":
14
+ default: return "npm install";
15
+ }
16
+ }
17
+ async function validatePythonEnvironment({ baseDir, hasPythonFiles, pythonVersion = "3.13" }) {
18
+ if (!hasPythonFiles) return {
19
+ success: true,
20
+ hasPythonFiles: false
21
+ };
22
+ try {
23
+ await getPythonCommand(pythonVersion, baseDir);
24
+ } catch {
25
+ internalLogger.error("Python is not installed");
26
+ internalLogger.info("Python files were detected in your project but Python 3 is not available");
27
+ internalLogger.info("Please install Python 3.10 or higher: https://www.python.org/downloads/");
28
+ return {
29
+ success: false,
30
+ hasPythonFiles: true
31
+ };
32
+ }
33
+ const venvPath = path.join(baseDir, "python_modules");
34
+ if (!fs.existsSync(venvPath)) {
35
+ const installCmd = getInstallCommand(baseDir);
36
+ internalLogger.error("Python environment not configured");
37
+ internalLogger.info("The python_modules directory was not found");
38
+ internalLogger.info(`Run '${installCmd}' to set up your Python environment`);
39
+ return {
40
+ success: false,
41
+ hasPythonFiles: true
42
+ };
43
+ }
44
+ const libPath = path.join(venvPath, "lib");
45
+ if (!fs.existsSync(libPath)) {
46
+ const installCmd = getInstallCommand(baseDir);
47
+ internalLogger.error("Python environment is incomplete");
48
+ internalLogger.info("The python_modules directory exists but appears to be corrupted");
49
+ internalLogger.info(`Run '${installCmd}' to recreate your Python environment`);
50
+ return {
51
+ success: false,
52
+ hasPythonFiles: true
53
+ };
54
+ }
55
+ return {
56
+ success: true,
57
+ hasPythonFiles: true
58
+ };
59
+ }
60
+
61
+ //#endregion
62
+ export { validatePythonEnvironment };
63
+ //# sourceMappingURL=validate-python-environment.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-python-environment.mjs","names":[],"sources":["../../src/utils/validate-python-environment.ts"],"sourcesContent":["import fs from 'fs'\nimport path from 'path'\nimport { getPackageManager } from './get-package-manager'\nimport { internalLogger } from './internal-logger'\nimport { getPythonCommand } from './python-version-utils'\n\nexport interface ValidationResult {\n success: boolean\n hasPythonFiles: boolean\n}\n\ninterface ValidateConfig {\n baseDir: string\n hasPythonFiles: boolean\n pythonVersion?: string\n}\n\nfunction getInstallCommand(baseDir: string): string {\n const pm = getPackageManager(baseDir)\n switch (pm) {\n case 'yarn':\n return 'yarn install'\n case 'pnpm':\n return 'pnpm install'\n case 'bun':\n return 'bun install'\n case 'npm':\n default:\n return 'npm install'\n }\n}\n\nexport async function validatePythonEnvironment({\n baseDir,\n hasPythonFiles,\n pythonVersion = '3.13',\n}: ValidateConfig): Promise<ValidationResult> {\n if (!hasPythonFiles) {\n return { success: true, hasPythonFiles: false }\n }\n\n try {\n await getPythonCommand(pythonVersion, baseDir)\n } catch {\n internalLogger.error('Python is not installed')\n internalLogger.info('Python files were detected in your project but Python 3 is not available')\n internalLogger.info('Please install Python 3.10 or higher: https://www.python.org/downloads/')\n return { success: false, hasPythonFiles: true }\n }\n\n const venvPath = path.join(baseDir, 'python_modules')\n if (!fs.existsSync(venvPath)) {\n const installCmd = getInstallCommand(baseDir)\n internalLogger.error('Python environment not configured')\n internalLogger.info('The python_modules directory was not found')\n internalLogger.info(`Run '${installCmd}' to set up your Python environment`)\n return { success: false, hasPythonFiles: true }\n }\n\n const libPath = path.join(venvPath, 'lib')\n if (!fs.existsSync(libPath)) {\n const installCmd = getInstallCommand(baseDir)\n internalLogger.error('Python environment is incomplete')\n internalLogger.info('The python_modules directory exists but appears to be corrupted')\n internalLogger.info(`Run '${installCmd}' to recreate your Python environment`)\n return { success: false, hasPythonFiles: true }\n }\n\n return { success: true, hasPythonFiles: true }\n}\n"],"mappings":";;;;;;;AAiBA,SAAS,kBAAkB,SAAyB;AAElD,SADW,kBAAkB,QAAQ,EACrC;EACE,KAAK,OACH,QAAO;EACT,KAAK,OACH,QAAO;EACT,KAAK,MACH,QAAO;EACT,KAAK;EACL,QACE,QAAO;;;AAIb,eAAsB,0BAA0B,EAC9C,SACA,gBACA,gBAAgB,UAC4B;AAC5C,KAAI,CAAC,eACH,QAAO;EAAE,SAAS;EAAM,gBAAgB;EAAO;AAGjD,KAAI;AACF,QAAM,iBAAiB,eAAe,QAAQ;SACxC;AACN,iBAAe,MAAM,0BAA0B;AAC/C,iBAAe,KAAK,2EAA2E;AAC/F,iBAAe,KAAK,0EAA0E;AAC9F,SAAO;GAAE,SAAS;GAAO,gBAAgB;GAAM;;CAGjD,MAAM,WAAW,KAAK,KAAK,SAAS,iBAAiB;AACrD,KAAI,CAAC,GAAG,WAAW,SAAS,EAAE;EAC5B,MAAM,aAAa,kBAAkB,QAAQ;AAC7C,iBAAe,MAAM,oCAAoC;AACzD,iBAAe,KAAK,6CAA6C;AACjE,iBAAe,KAAK,QAAQ,WAAW,qCAAqC;AAC5E,SAAO;GAAE,SAAS;GAAO,gBAAgB;GAAM;;CAGjD,MAAM,UAAU,KAAK,KAAK,UAAU,MAAM;AAC1C,KAAI,CAAC,GAAG,WAAW,QAAQ,EAAE;EAC3B,MAAM,aAAa,kBAAkB,QAAQ;AAC7C,iBAAe,MAAM,mCAAmC;AACxD,iBAAe,KAAK,kEAAkE;AACtF,iBAAe,KAAK,QAAQ,WAAW,uCAAuC;AAC9E,SAAO;GAAE,SAAS;GAAO,gBAAgB;GAAM;;AAGjD,QAAO;EAAE,SAAS;EAAM,gBAAgB;EAAM"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "motia",
3
3
  "description": "Build production-grade backends with a single primitive. APIs, background jobs, Queues, Workflows, and AI agents - unified in one system with built-in State management, Streaming, and Observability.",
4
- "version": "0.15.4-beta.170-888624",
4
+ "version": "0.15.4-beta.170-803755",
5
5
  "license": "Elastic-2.0",
6
6
  "type": "module",
7
7
  "repository": {
@@ -46,13 +46,13 @@
46
46
  "table": "^6.9.0",
47
47
  "ts-node": "^10.9.2",
48
48
  "zod": "^4.1.12",
49
- "@motiadev/adapter-redis-state": "0.15.4-beta.170-888624",
50
- "@motiadev/adapter-bullmq-events": "0.15.4-beta.170-888624",
51
- "@motiadev/adapter-redis-streams": "0.15.4-beta.170-888624",
52
- "@motiadev/core": "0.15.4-beta.170-888624",
53
- "@motiadev/stream-client-node": "0.15.4-beta.170-888624",
54
- "@motiadev/workbench": "0.15.4-beta.170-888624",
55
- "@motiadev/adapter-redis-cron": "0.15.4-beta.170-888624"
49
+ "@motiadev/adapter-bullmq-events": "0.15.4-beta.170-803755",
50
+ "@motiadev/adapter-redis-cron": "0.15.4-beta.170-803755",
51
+ "@motiadev/adapter-redis-state": "0.15.4-beta.170-803755",
52
+ "@motiadev/adapter-redis-streams": "0.15.4-beta.170-803755",
53
+ "@motiadev/stream-client-node": "0.15.4-beta.170-803755",
54
+ "@motiadev/workbench": "0.15.4-beta.170-803755",
55
+ "@motiadev/core": "0.15.4-beta.170-803755"
56
56
  },
57
57
  "devDependencies": {
58
58
  "@amplitude/analytics-types": "^2.9.2",