@ontrails/trails 1.0.0-beta.23 → 1.0.0-beta.24

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/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # trails
2
2
 
3
+ ## 1.0.0-beta.24
4
+
5
+ ### Patch Changes
6
+
7
+ - dac49c2: Restore caller-facing direct input for `trails run` so positional JSON,
8
+ `--input-json`, and `--input` payloads map to the target trail input unless
9
+ callers explicitly use the `input` wrapper for control-field collisions.
10
+ - @ontrails/commander@1.0.0-beta.24
11
+ - @ontrails/adapter-kit@1.0.0-beta.24
12
+ - @ontrails/cli@1.0.0-beta.24
13
+ - @ontrails/core@1.0.0-beta.24
14
+ - @ontrails/http@1.0.0-beta.24
15
+ - @ontrails/mcp@1.0.0-beta.24
16
+ - @ontrails/observe@1.0.0-beta.24
17
+ - @ontrails/permits@1.0.0-beta.24
18
+ - @ontrails/topographer@1.0.0-beta.24
19
+ - @ontrails/tracing@1.0.0-beta.24
20
+ - @ontrails/warden@1.0.0-beta.24
21
+ - @ontrails/wayfinder@1.0.0-beta.24
22
+
3
23
  ## 1.0.0-beta.23
4
24
 
5
25
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ontrails/trails",
3
- "version": "1.0.0-beta.23",
3
+ "version": "1.0.0-beta.24",
4
4
  "bin": {
5
5
  "trails": "./bin/trails.ts"
6
6
  },
@@ -27,23 +27,23 @@
27
27
  },
28
28
  "dependencies": {
29
29
  "@clack/prompts": "^1.1.0",
30
- "@ontrails/adapter-kit": "^1.0.0-beta.23",
31
- "@ontrails/cli": "^1.0.0-beta.23",
32
- "@ontrails/commander": "^1.0.0-beta.23",
33
- "@ontrails/core": "^1.0.0-beta.23",
34
- "@ontrails/http": "^1.0.0-beta.23",
35
- "@ontrails/mcp": "^1.0.0-beta.23",
36
- "@ontrails/observe": "^1.0.0-beta.23",
37
- "@ontrails/permits": "^1.0.0-beta.23",
38
- "@ontrails/topographer": "^1.0.0-beta.23",
39
- "@ontrails/tracing": "^1.0.0-beta.23",
40
- "@ontrails/warden": "^1.0.0-beta.23",
41
- "@ontrails/wayfinder": "^1.0.0-beta.23",
30
+ "@ontrails/adapter-kit": "^1.0.0-beta.24",
31
+ "@ontrails/cli": "^1.0.0-beta.24",
32
+ "@ontrails/commander": "^1.0.0-beta.24",
33
+ "@ontrails/core": "^1.0.0-beta.24",
34
+ "@ontrails/http": "^1.0.0-beta.24",
35
+ "@ontrails/mcp": "^1.0.0-beta.24",
36
+ "@ontrails/observe": "^1.0.0-beta.24",
37
+ "@ontrails/permits": "^1.0.0-beta.24",
38
+ "@ontrails/topographer": "^1.0.0-beta.24",
39
+ "@ontrails/tracing": "^1.0.0-beta.24",
40
+ "@ontrails/warden": "^1.0.0-beta.24",
41
+ "@ontrails/wayfinder": "^1.0.0-beta.24",
42
42
  "commander": "^14.0.3",
43
43
  "typescript": "^5.9.3",
44
44
  "zod": "^4.3.5"
45
45
  },
46
46
  "devDependencies": {
47
- "@ontrails/testing": "^1.0.0-beta.23"
47
+ "@ontrails/testing": "^1.0.0-beta.24"
48
48
  }
49
49
  }
package/src/trails/run.ts CHANGED
@@ -33,6 +33,7 @@ import {
33
33
  AmbiguousError,
34
34
  NotFoundError,
35
35
  Result,
36
+ ValidationError,
36
37
  run,
37
38
  trail,
38
39
  } from '@ontrails/core';
@@ -313,26 +314,58 @@ const buildAmbiguousExampleInput = (): {
313
314
  return { id: 'shared.id', rootDir: root };
314
315
  };
315
316
 
316
- const runTrailInputSchema = z.object({
317
- app: z
318
- .string()
319
- .optional()
320
- .describe(
321
- 'Workspace app to resolve the trail ID against; required when the ID is exposed by more than one app'
322
- ),
323
- id: z.string().describe('Trail ID to invoke'),
324
- input: z
325
- .unknown()
326
- .optional()
327
- .describe(
328
- 'Parsed input for the resolved trail; the CLI surface JSON.parses the inline argument before passing it through'
329
- ),
330
- module: z.string().optional().describe('Path to the app module'),
331
- rootDir: z.string().optional().describe('Workspace root directory'),
332
- });
317
+ const runTrailInputSchema = z
318
+ .object({
319
+ app: z
320
+ .string()
321
+ .optional()
322
+ .describe(
323
+ 'Workspace app to resolve the trail ID against; required when the ID is exposed by more than one app'
324
+ ),
325
+ id: z.string().describe('Trail ID to invoke'),
326
+ input: z
327
+ .unknown()
328
+ .optional()
329
+ .describe(
330
+ 'Parsed input for the resolved trail; the CLI surface JSON.parses the inline argument before passing it through'
331
+ ),
332
+ module: z.string().optional().describe('Path to the app module'),
333
+ rootDir: z.string().optional().describe('Workspace root directory'),
334
+ })
335
+ .catchall(z.unknown());
333
336
 
334
337
  type RunTrailInput = z.output<typeof runTrailInputSchema>;
335
338
 
339
+ const RUN_TRAIL_CONTROL_KEYS = new Set([
340
+ 'app',
341
+ 'id',
342
+ 'input',
343
+ 'module',
344
+ 'rootDir',
345
+ ]);
346
+
347
+ const directInputEntries = (
348
+ input: RunTrailInput
349
+ ): readonly (readonly [string, unknown])[] =>
350
+ Object.entries(input).filter(([key]) => !RUN_TRAIL_CONTROL_KEYS.has(key));
351
+
352
+ const resolveInnerTrailInput = (
353
+ input: RunTrailInput
354
+ ): Result<unknown, ValidationError> => {
355
+ const entries = directInputEntries(input);
356
+ if (entries.length === 0) {
357
+ return Result.ok(input.input);
358
+ }
359
+ if (Object.hasOwn(input, 'input')) {
360
+ return Result.err(
361
+ new ValidationError(
362
+ 'trails run received both direct input fields and an explicit input wrapper. Use one shape: either {"name":"Alpha"} or {"input":{"name":"Alpha"}}.'
363
+ )
364
+ );
365
+ }
366
+ return Result.ok(Object.fromEntries(entries));
367
+ };
368
+
336
369
  // ---------------------------------------------------------------------------
337
370
  // Trail definition
338
371
  // ---------------------------------------------------------------------------
@@ -345,6 +378,10 @@ export const runTrail = trail('run', {
345
378
  return rootDirResult;
346
379
  }
347
380
  const rootDir = rootDirResult.value;
381
+ const innerInput = resolveInnerTrailInput(input);
382
+ if (innerInput.isErr()) {
383
+ return innerInput;
384
+ }
348
385
 
349
386
  // Single-app back-compat: if the caller provided `module`, trust it.
350
387
  const moduleResolution = await resolveRunModulePath(
@@ -365,7 +402,7 @@ export const runTrail = trail('run', {
365
402
  const lease = leaseResult.value;
366
403
 
367
404
  try {
368
- const result = await run(lease.app, input.id, input.input, {
405
+ const result = await run(lease.app, input.id, innerInput.value, {
369
406
  ctx: ctx.permit === undefined ? {} : { permit: ctx.permit },
370
407
  });
371
408
  if (result.isErr()) {