@karmaniverous/jeeves-runner 0.7.2 → 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,9 +1006,25 @@ function parseResultLines(stdout) {
1006
1006
  }
1007
1007
  return { tokens, resultMeta };
1008
1008
  }
1009
- /** Resolve the command and arguments for a script based on its file extension. */
1010
- function resolveCommand(script) {
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 = {}) {
1011
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
1012
1028
  switch (ext) {
1013
1029
  case '.ps1':
1014
1030
  return {
@@ -1027,7 +1043,7 @@ function resolveCommand(script) {
1027
1043
  * Execute a job script as a child process. Captures output, parses metadata, enforces timeout.
1028
1044
  */
1029
1045
  function executeJob(options) {
1030
- const { script, dbPath, jobId, runId, timeoutMs, commandResolver, sourceType = 'path', } = options;
1046
+ const { script, dbPath, jobId, runId, timeoutMs, commandResolver, sourceType = 'path', runners, } = options;
1031
1047
  const startTime = Date.now();
1032
1048
  // For inline scripts, write to a temp file and clean up after.
1033
1049
  let tempFile = null;
@@ -1043,7 +1059,7 @@ function executeJob(options) {
1043
1059
  const stderrBuffer = new RingBuffer(100);
1044
1060
  const { command, args } = commandResolver
1045
1061
  ? commandResolver(effectiveScript)
1046
- : resolveCommand(effectiveScript);
1062
+ : resolveCommand(effectiveScript, runners);
1047
1063
  const child = spawn(command, args, {
1048
1064
  env: {
1049
1065
  ...process.env,
@@ -1445,6 +1461,7 @@ function createScheduler(deps) {
1445
1461
  runId,
1446
1462
  timeoutMs: timeout_ms ?? undefined,
1447
1463
  sourceType: source_type ?? 'path',
1464
+ runners: config.runners,
1448
1465
  });
1449
1466
  }
1450
1467
  runRepository.finishRun(runId, result);
@@ -1712,6 +1729,8 @@ const runnerConfigSchema = z.object({
1712
1729
  log: logSchema.default({ level: 'info' }),
1713
1730
  /** Gateway configuration for session-type jobs. */
1714
1731
  gateway: gatewaySchema.default({ url: 'http://127.0.0.1:18789' }),
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({}),
1715
1734
  });
1716
1735
 
1717
1736
  /**
package/dist/index.d.ts CHANGED
@@ -25,11 +25,11 @@ declare const runnerConfigSchema: z.ZodObject<{
25
25
  }, z.core.$strip>>;
26
26
  log: z.ZodDefault<z.ZodObject<{
27
27
  level: z.ZodDefault<z.ZodEnum<{
28
- error: "error";
29
28
  trace: "trace";
30
29
  debug: "debug";
31
30
  info: "info";
32
31
  warn: "warn";
32
+ error: "error";
33
33
  fatal: "fatal";
34
34
  }>>;
35
35
  file: z.ZodOptional<z.ZodString>;
@@ -38,6 +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
+ runners: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
41
42
  }, z.core.$strip>;
42
43
  /** Inferred runner configuration type. */
43
44
  type RunnerConfig = z.infer<typeof runnerConfigSchema>;
@@ -102,10 +103,10 @@ type Queue = z.infer<typeof queueSchema>;
102
103
 
103
104
  /** Run status enumeration schema (pending, running, ok, error, timeout, skipped). */
104
105
  declare const runStatusSchema: z.ZodEnum<{
106
+ error: "error";
105
107
  pending: "pending";
106
108
  running: "running";
107
109
  ok: "ok";
108
- error: "error";
109
110
  timeout: "timeout";
110
111
  skipped: "skipped";
111
112
  }>;
@@ -120,10 +121,10 @@ declare const runSchema: z.ZodObject<{
120
121
  id: z.ZodNumber;
121
122
  jobId: z.ZodString;
122
123
  status: z.ZodEnum<{
124
+ error: "error";
123
125
  pending: "pending";
124
126
  running: "running";
125
127
  ok: "ok";
126
- error: "error";
127
128
  timeout: "timeout";
128
129
  skipped: "skipped";
129
130
  }>;
@@ -289,7 +290,14 @@ interface ExecutionOptions {
289
290
  commandResolver?: (script: string) => ResolvedCommand;
290
291
  /** Source type: 'path' uses script as file path, 'inline' writes script content to a temp file. */
291
292
  sourceType?: 'path' | 'inline';
293
+ /** Custom command runners keyed by file extension (e.g. { ".ts": "node /path/to/tsx/cli.mjs" }). */
294
+ runners?: Record<string, string>;
292
295
  }
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;
293
301
  /**
294
302
  * Execute a job script as a child process. Captures output, parses metadata, enforces timeout.
295
303
  */
@@ -544,5 +552,5 @@ declare function createMaintenance(db: DatabaseSync, config: MaintenanceConfig,
544
552
  */
545
553
  declare function runMigrations(db: DatabaseSync): void;
546
554
 
547
- export { closeConnection, createClient, createConnection, createGatewayClient, createMaintenance, createNotifier, createRunner, createScheduler, executeJob, executeSession, getNextFireTime, jobSchema, queueSchema, 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 };
548
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,6 +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
+ /** 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({}),
74
76
  });
75
77
 
76
78
  /**
@@ -1165,9 +1167,25 @@ function parseResultLines(stdout) {
1165
1167
  }
1166
1168
  return { tokens, resultMeta };
1167
1169
  }
1168
- /** Resolve the command and arguments for a script based on its file extension. */
1169
- function resolveCommand(script) {
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 = {}) {
1170
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
1171
1189
  switch (ext) {
1172
1190
  case '.ps1':
1173
1191
  return {
@@ -1186,7 +1204,7 @@ function resolveCommand(script) {
1186
1204
  * Execute a job script as a child process. Captures output, parses metadata, enforces timeout.
1187
1205
  */
1188
1206
  function executeJob(options) {
1189
- const { script, dbPath, jobId, runId, timeoutMs, commandResolver, sourceType = 'path', } = options;
1207
+ const { script, dbPath, jobId, runId, timeoutMs, commandResolver, sourceType = 'path', runners, } = options;
1190
1208
  const startTime = Date.now();
1191
1209
  // For inline scripts, write to a temp file and clean up after.
1192
1210
  let tempFile = null;
@@ -1202,7 +1220,7 @@ function executeJob(options) {
1202
1220
  const stderrBuffer = new RingBuffer(100);
1203
1221
  const { command, args } = commandResolver
1204
1222
  ? commandResolver(effectiveScript)
1205
- : resolveCommand(effectiveScript);
1223
+ : resolveCommand(effectiveScript, runners);
1206
1224
  const child = spawn(command, args, {
1207
1225
  env: {
1208
1226
  ...process.env,
@@ -1604,6 +1622,7 @@ function createScheduler(deps) {
1604
1622
  runId,
1605
1623
  timeoutMs: timeout_ms ?? undefined,
1606
1624
  sourceType: source_type ?? 'path',
1625
+ runners: config.runners,
1607
1626
  });
1608
1627
  }
1609
1628
  runRepository.finishRun(runId, result);
@@ -2052,4 +2071,4 @@ function createClient(dbPath) {
2052
2071
  };
2053
2072
  }
2054
2073
 
2055
- export { closeConnection, createClient, createConnection, createGatewayClient, createMaintenance, createNotifier, createRunner, createScheduler, executeJob, executeSession, getNextFireTime, jobSchema, queueSchema, 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.2",
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",