@karmaniverous/jeeves-runner 0.7.3 → 0.7.4

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.
@@ -1006,11 +1006,25 @@ function parseResultLines(stdout) {
1006
1006
  }
1007
1007
  return { tokens, resultMeta };
1008
1008
  }
1009
- /** TypeScript file extensions that should be executed via tsRunner. */
1010
- const TS_EXTENSIONS = new Set(['.ts', '.tsx', '.mts', '.cts']);
1011
- /** Resolve the command and arguments for a script based on its file extension. */
1012
- function resolveCommand(script, tsRunner = 'tsx') {
1009
+ /** Resolve the command and arguments for a script based on its file extension.
1010
+ * Custom runners (keyed by extension) take priority over built-in defaults.
1011
+ * The runner string is split on whitespace: first token is the command,
1012
+ * remaining tokens are prefix args inserted before the script path. */
1013
+ function resolveCommand(script, runners = {}) {
1013
1014
  const ext = extname(script).toLowerCase();
1015
+ const key = ext.replace(/^\./, '');
1016
+ // Check custom runners first
1017
+ const customRunner = runners[key];
1018
+ if (customRunner) {
1019
+ const parts = customRunner.trim().split(/\s+/);
1020
+ if (parts[0]) {
1021
+ return {
1022
+ command: parts[0],
1023
+ args: [...parts.slice(1), script],
1024
+ };
1025
+ }
1026
+ }
1027
+ // Built-in defaults
1014
1028
  switch (ext) {
1015
1029
  case '.ps1':
1016
1030
  return {
@@ -1021,9 +1035,6 @@ function resolveCommand(script, tsRunner = 'tsx') {
1021
1035
  case '.bat':
1022
1036
  return { command: 'cmd.exe', args: ['/c', script] };
1023
1037
  default:
1024
- if (TS_EXTENSIONS.has(ext)) {
1025
- return { command: tsRunner, args: [script] };
1026
- }
1027
1038
  // .js, .mjs, .cjs, or anything else: run with node
1028
1039
  return { command: 'node', args: [script] };
1029
1040
  }
@@ -1032,7 +1043,7 @@ function resolveCommand(script, tsRunner = 'tsx') {
1032
1043
  * Execute a job script as a child process. Captures output, parses metadata, enforces timeout.
1033
1044
  */
1034
1045
  function executeJob(options) {
1035
- const { script, dbPath, jobId, runId, timeoutMs, commandResolver, sourceType = 'path', tsRunner, } = options;
1046
+ const { script, dbPath, jobId, runId, timeoutMs, commandResolver, sourceType = 'path', runners, } = options;
1036
1047
  const startTime = Date.now();
1037
1048
  // For inline scripts, write to a temp file and clean up after.
1038
1049
  let tempFile = null;
@@ -1048,7 +1059,7 @@ function executeJob(options) {
1048
1059
  const stderrBuffer = new RingBuffer(100);
1049
1060
  const { command, args } = commandResolver
1050
1061
  ? commandResolver(effectiveScript)
1051
- : resolveCommand(effectiveScript, tsRunner);
1062
+ : resolveCommand(effectiveScript, runners);
1052
1063
  const child = spawn(command, args, {
1053
1064
  env: {
1054
1065
  ...process.env,
@@ -1450,7 +1461,7 @@ function createScheduler(deps) {
1450
1461
  runId,
1451
1462
  timeoutMs: timeout_ms ?? undefined,
1452
1463
  sourceType: source_type ?? 'path',
1453
- tsRunner: config.tsRunner,
1464
+ runners: config.runners,
1454
1465
  });
1455
1466
  }
1456
1467
  runRepository.finishRun(runId, result);
@@ -1718,8 +1729,8 @@ const runnerConfigSchema = z.object({
1718
1729
  log: logSchema.default({ level: 'info' }),
1719
1730
  /** Gateway configuration for session-type jobs. */
1720
1731
  gateway: gatewaySchema.default({ url: 'http://127.0.0.1:18789' }),
1721
- /** Command used to execute .ts/.tsx/.mts/.cts scripts. Defaults to 'tsx'. Can be an absolute path. */
1722
- tsRunner: z.string().default('tsx'),
1732
+ /** Custom command runners keyed by file extension. The command string is split on whitespace; first token is the executable, rest are prefix args before the script path. Falls back to built-in defaults for unconfigured extensions. */
1733
+ runners: z.record(z.string(), z.string().trim().min(1)).default({}),
1723
1734
  });
1724
1735
 
1725
1736
  /**
package/dist/index.d.ts CHANGED
@@ -38,7 +38,7 @@ declare const runnerConfigSchema: z.ZodObject<{
38
38
  url: z.ZodDefault<z.ZodString>;
39
39
  tokenPath: z.ZodOptional<z.ZodString>;
40
40
  }, z.core.$strip>>;
41
- tsRunner: z.ZodDefault<z.ZodString>;
41
+ runners: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
42
42
  }, z.core.$strip>;
43
43
  /** Inferred runner configuration type. */
44
44
  type RunnerConfig = z.infer<typeof runnerConfigSchema>;
@@ -290,13 +290,14 @@ interface ExecutionOptions {
290
290
  commandResolver?: (script: string) => ResolvedCommand;
291
291
  /** Source type: 'path' uses script as file path, 'inline' writes script content to a temp file. */
292
292
  sourceType?: 'path' | 'inline';
293
- /** Command used to execute TypeScript files. Defaults to 'tsx'. */
294
- tsRunner?: string;
293
+ /** Custom command runners keyed by file extension (e.g. { ".ts": "node /path/to/tsx/cli.mjs" }). */
294
+ runners?: Record<string, string>;
295
295
  }
296
- /** TypeScript file extensions that should be executed via tsRunner. */
297
- declare const TS_EXTENSIONS: Set<string>;
298
- /** Resolve the command and arguments for a script based on its file extension. */
299
- declare function resolveCommand(script: string, tsRunner?: string): ResolvedCommand;
296
+ /** Resolve the command and arguments for a script based on its file extension.
297
+ * Custom runners (keyed by extension) take priority over built-in defaults.
298
+ * The runner string is split on whitespace: first token is the command,
299
+ * remaining tokens are prefix args inserted before the script path. */
300
+ declare function resolveCommand(script: string, runners?: Record<string, string>): ResolvedCommand;
300
301
  /**
301
302
  * Execute a job script as a child process. Captures output, parses metadata, enforces timeout.
302
303
  */
@@ -551,5 +552,5 @@ declare function createMaintenance(db: DatabaseSync, config: MaintenanceConfig,
551
552
  */
552
553
  declare function runMigrations(db: DatabaseSync): void;
553
554
 
554
- export { TS_EXTENSIONS, closeConnection, createClient, createConnection, createGatewayClient, createMaintenance, createNotifier, createRunner, createScheduler, executeJob, executeSession, getNextFireTime, jobSchema, queueSchema, resolveCommand, runMigrations, runSchema, runStatusSchema, runTriggerSchema, runnerConfigSchema, validateSchedule };
555
+ export { closeConnection, createClient, createConnection, createGatewayClient, createMaintenance, createNotifier, createRunner, createScheduler, executeJob, executeSession, getNextFireTime, jobSchema, queueSchema, resolveCommand, runMigrations, runSchema, runStatusSchema, runTriggerSchema, runnerConfigSchema, validateSchedule };
555
556
  export type { ExecutionOptions, ExecutionResult, GatewayClient, GatewayClientOptions, Job, Maintenance, MaintenanceConfig, Notifier, NotifyConfig, NotifyLogger, Queue, QueueItem, ResolvedCommand, Run, RunStatus, RunTrigger, Runner, RunnerClient, RunnerConfig, RunnerDeps, ScheduleInvalid, ScheduleValid, ScheduleValidation, Scheduler, SchedulerDeps, SessionExecutionOptions, SessionInfo, SessionMessage, SpawnSessionOptions, SpawnSessionResult };
package/dist/mjs/index.js CHANGED
@@ -71,8 +71,8 @@ const runnerConfigSchema = z.object({
71
71
  log: logSchema.default({ level: 'info' }),
72
72
  /** Gateway configuration for session-type jobs. */
73
73
  gateway: gatewaySchema.default({ url: 'http://127.0.0.1:18789' }),
74
- /** Command used to execute .ts/.tsx/.mts/.cts scripts. Defaults to 'tsx'. Can be an absolute path. */
75
- tsRunner: z.string().default('tsx'),
74
+ /** Custom command runners keyed by file extension. The command string is split on whitespace; first token is the executable, rest are prefix args before the script path. Falls back to built-in defaults for unconfigured extensions. */
75
+ runners: z.record(z.string(), z.string().trim().min(1)).default({}),
76
76
  });
77
77
 
78
78
  /**
@@ -1167,11 +1167,25 @@ function parseResultLines(stdout) {
1167
1167
  }
1168
1168
  return { tokens, resultMeta };
1169
1169
  }
1170
- /** TypeScript file extensions that should be executed via tsRunner. */
1171
- const TS_EXTENSIONS = new Set(['.ts', '.tsx', '.mts', '.cts']);
1172
- /** Resolve the command and arguments for a script based on its file extension. */
1173
- function resolveCommand(script, tsRunner = 'tsx') {
1170
+ /** Resolve the command and arguments for a script based on its file extension.
1171
+ * Custom runners (keyed by extension) take priority over built-in defaults.
1172
+ * The runner string is split on whitespace: first token is the command,
1173
+ * remaining tokens are prefix args inserted before the script path. */
1174
+ function resolveCommand(script, runners = {}) {
1174
1175
  const ext = extname(script).toLowerCase();
1176
+ const key = ext.replace(/^\./, '');
1177
+ // Check custom runners first
1178
+ const customRunner = runners[key];
1179
+ if (customRunner) {
1180
+ const parts = customRunner.trim().split(/\s+/);
1181
+ if (parts[0]) {
1182
+ return {
1183
+ command: parts[0],
1184
+ args: [...parts.slice(1), script],
1185
+ };
1186
+ }
1187
+ }
1188
+ // Built-in defaults
1175
1189
  switch (ext) {
1176
1190
  case '.ps1':
1177
1191
  return {
@@ -1182,9 +1196,6 @@ function resolveCommand(script, tsRunner = 'tsx') {
1182
1196
  case '.bat':
1183
1197
  return { command: 'cmd.exe', args: ['/c', script] };
1184
1198
  default:
1185
- if (TS_EXTENSIONS.has(ext)) {
1186
- return { command: tsRunner, args: [script] };
1187
- }
1188
1199
  // .js, .mjs, .cjs, or anything else: run with node
1189
1200
  return { command: 'node', args: [script] };
1190
1201
  }
@@ -1193,7 +1204,7 @@ function resolveCommand(script, tsRunner = 'tsx') {
1193
1204
  * Execute a job script as a child process. Captures output, parses metadata, enforces timeout.
1194
1205
  */
1195
1206
  function executeJob(options) {
1196
- const { script, dbPath, jobId, runId, timeoutMs, commandResolver, sourceType = 'path', tsRunner, } = options;
1207
+ const { script, dbPath, jobId, runId, timeoutMs, commandResolver, sourceType = 'path', runners, } = options;
1197
1208
  const startTime = Date.now();
1198
1209
  // For inline scripts, write to a temp file and clean up after.
1199
1210
  let tempFile = null;
@@ -1209,7 +1220,7 @@ function executeJob(options) {
1209
1220
  const stderrBuffer = new RingBuffer(100);
1210
1221
  const { command, args } = commandResolver
1211
1222
  ? commandResolver(effectiveScript)
1212
- : resolveCommand(effectiveScript, tsRunner);
1223
+ : resolveCommand(effectiveScript, runners);
1213
1224
  const child = spawn(command, args, {
1214
1225
  env: {
1215
1226
  ...process.env,
@@ -1611,7 +1622,7 @@ function createScheduler(deps) {
1611
1622
  runId,
1612
1623
  timeoutMs: timeout_ms ?? undefined,
1613
1624
  sourceType: source_type ?? 'path',
1614
- tsRunner: config.tsRunner,
1625
+ runners: config.runners,
1615
1626
  });
1616
1627
  }
1617
1628
  runRepository.finishRun(runId, result);
@@ -2060,4 +2071,4 @@ function createClient(dbPath) {
2060
2071
  };
2061
2072
  }
2062
2073
 
2063
- export { TS_EXTENSIONS, closeConnection, createClient, createConnection, createGatewayClient, createMaintenance, createNotifier, createRunner, createScheduler, executeJob, executeSession, getNextFireTime, jobSchema, queueSchema, resolveCommand, runMigrations, runSchema, runStatusSchema, runTriggerSchema, runnerConfigSchema, validateSchedule };
2074
+ export { closeConnection, createClient, createConnection, createGatewayClient, createMaintenance, createNotifier, createRunner, createScheduler, executeJob, executeSession, getNextFireTime, jobSchema, queueSchema, resolveCommand, runMigrations, runSchema, runStatusSchema, runTriggerSchema, runnerConfigSchema, validateSchedule };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@karmaniverous/jeeves-runner",
3
- "version": "0.7.3",
3
+ "version": "0.7.4",
4
4
  "author": "Jason Williscroft",
5
5
  "description": "Graph-aware job execution engine with SQLite state. Part of the Jeeves platform.",
6
6
  "license": "BSD-3-Clause",