@tagma/sdk 0.7.37 → 0.7.39

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.
Files changed (53) hide show
  1. package/README.md +24 -16
  2. package/dist/completions/file-exists.d.ts.map +1 -1
  3. package/dist/completions/file-exists.js +3 -5
  4. package/dist/completions/file-exists.js.map +1 -1
  5. package/dist/completions/output-check.js +1 -1
  6. package/dist/completions/output-check.js.map +1 -1
  7. package/dist/config-ops.d.ts +11 -7
  8. package/dist/config-ops.d.ts.map +1 -1
  9. package/dist/config-ops.js +128 -13
  10. package/dist/config-ops.js.map +1 -1
  11. package/dist/drivers/opencode.d.ts.map +1 -1
  12. package/dist/drivers/opencode.js +23 -18
  13. package/dist/drivers/opencode.js.map +1 -1
  14. package/dist/index.d.ts +1 -1
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js.map +1 -1
  17. package/dist/middlewares/static-context.d.ts.map +1 -1
  18. package/dist/middlewares/static-context.js +6 -6
  19. package/dist/middlewares/static-context.js.map +1 -1
  20. package/dist/pipeline-runner.d.ts.map +1 -1
  21. package/dist/pipeline-runner.js +36 -6
  22. package/dist/pipeline-runner.js.map +1 -1
  23. package/dist/plugin-config.d.ts +6 -0
  24. package/dist/plugin-config.d.ts.map +1 -0
  25. package/dist/plugin-config.js +26 -0
  26. package/dist/plugin-config.js.map +1 -0
  27. package/dist/schema.d.ts.map +1 -1
  28. package/dist/schema.js +47 -16
  29. package/dist/schema.js.map +1 -1
  30. package/dist/tagma.d.ts +4 -1
  31. package/dist/tagma.d.ts.map +1 -1
  32. package/dist/tagma.js +13 -3
  33. package/dist/tagma.js.map +1 -1
  34. package/dist/triggers/directory.d.ts.map +1 -1
  35. package/dist/triggers/directory.js +4 -6
  36. package/dist/triggers/directory.js.map +1 -1
  37. package/dist/triggers/file.d.ts.map +1 -1
  38. package/dist/triggers/file.js +3 -4
  39. package/dist/triggers/file.js.map +1 -1
  40. package/dist/triggers/manual.d.ts.map +1 -1
  41. package/dist/triggers/manual.js +6 -2
  42. package/dist/triggers/manual.js.map +1 -1
  43. package/dist/validate-raw.d.ts.map +1 -1
  44. package/dist/validate-raw.js +184 -21
  45. package/dist/validate-raw.js.map +1 -1
  46. package/dist/workdir.d.ts +3 -0
  47. package/dist/workdir.d.ts.map +1 -0
  48. package/dist/workdir.js +12 -0
  49. package/dist/workdir.js.map +1 -0
  50. package/dist/workflow.d.ts.map +1 -1
  51. package/dist/workflow.js +144 -34
  52. package/dist/workflow.js.map +1 -1
  53. package/package.json +4 -4
@@ -1,6 +1,7 @@
1
1
  import { resolve, dirname, isAbsolute, relative } from 'path';
2
2
  import { TriggerTimeoutError, linkAbort, } from '@tagma/types';
3
3
  import { parseOptionalPluginTimeout } from '../duration';
4
+ import { requiredPluginString, resolvePluginPath } from '../plugin-config';
4
5
  const IS_WINDOWS = process.platform === 'win32';
5
6
  function pathsEqual(a, b) {
6
7
  return IS_WINDOWS ? a.toLowerCase() === b.toLowerCase() : a === b;
@@ -28,10 +29,8 @@ export const FileTrigger = {
28
29
  },
29
30
  },
30
31
  watch(config, ctx) {
31
- const filePath = config.path;
32
- if (!filePath)
33
- throw new Error(`file trigger: "path" is required`);
34
- const safePath = resolve(ctx.workDir, filePath);
32
+ const filePath = requiredPluginString(config, 'path', 'file trigger');
33
+ const safePath = resolvePluginPath(filePath, ctx.workDir, { allowAbsoluteOutside: true });
35
34
  const timeoutMs = parseOptionalPluginTimeout(config.timeout, 0);
36
35
  const disposeController = new AbortController();
37
36
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"file.js","sourceRoot":"","sources":["../../src/triggers/file.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"file.js","sourceRoot":"","sources":["../../src/triggers/file.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"manual.d.ts","sourceRoot":"","sources":["../../src/triggers/manual.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,aAAa,EAGnB,MAAM,cAAc,CAAC;AAGtB,eAAO,MAAM,aAAa,EAAE,aAkF3B,CAAC"}
1
+ {"version":3,"file":"manual.d.ts","sourceRoot":"","sources":["../../src/triggers/manual.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,aAAa,EAGnB,MAAM,cAAc,CAAC;AAItB,eAAO,MAAM,aAAa,EAAE,aAqF3B,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { TriggerBlockedError, TriggerTimeoutError, linkAbort, } from '@tagma/types';
2
2
  import { parseOptionalPluginTimeout } from '../duration';
3
+ import { optionalPluginString } from '../plugin-config';
3
4
  export const ManualTrigger = {
4
5
  name: 'manual',
5
6
  schema: {
@@ -25,8 +26,11 @@ export const ManualTrigger = {
25
26
  if (ctx.signal.aborted) {
26
27
  throw new Error('Pipeline aborted');
27
28
  }
28
- const message = config.message ??
29
- `Manual confirmation required for task "${ctx.taskId}"`;
29
+ const configuredMessage = optionalPluginString(config, 'message', 'manual trigger');
30
+ const defaultMessage = `Manual confirmation required for task "${ctx.taskId}"`;
31
+ const message = configuredMessage !== undefined && configuredMessage.trim() !== ''
32
+ ? configuredMessage
33
+ : defaultMessage;
30
34
  const timeoutMs = parseOptionalPluginTimeout(config.timeout, 0);
31
35
  const metadata = config.metadata && typeof config.metadata === 'object'
32
36
  ? config.metadata
@@ -1 +1 @@
1
- {"version":3,"file":"manual.js","sourceRoot":"","sources":["../../src/triggers/manual.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,SAAS,GAIV,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AAEzD,MAAM,CAAC,MAAM,aAAa,GAAkB;IAC1C,IAAI,EAAE,QAAQ;IACd,MAAM,EAAE;QACN,WAAW,EAAE,gEAAgE;QAC7E,MAAM,EAAE;YACN,OAAO,EAAE;gBACP,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,uEAAuE;gBACpF,WAAW,EAAE,mCAAmC;aACjD;YACD,OAAO,EAAE;gBACP,IAAI,EAAE,UAAU;gBAChB,WAAW,EAAE,+DAA+D;gBAC5E,WAAW,EAAE,KAAK;aACnB;YACD,QAAQ,EAAE;gBACR,IAAI,EAAE,MAAM;gBACZ,WAAW,EAAE,wDAAwD;aACtE;SACF;KACF;IAED,KAAK,CAAC,MAA+B,EAAE,GAAmB;QACxD,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;QACtC,CAAC;QAED,MAAM,OAAO,GACV,MAAM,CAAC,OAA8B;YACtC,0CAA0C,GAAG,CAAC,MAAM,GAAG,CAAC;QAC1D,MAAM,SAAS,GAAG,0BAA0B,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAChE,MAAM,QAAQ,GACZ,MAAM,CAAC,QAAQ,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ;YACpD,CAAC,CAAE,MAAM,CAAC,QAAoC;YAC9C,CAAC,CAAC,SAAS,CAAC;QAEhB,MAAM,OAAO,GAAG,GAAG,CAAC,eAAe,CAAC,OAAO,CAAC;YAC1C,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,OAAO;YACP,SAAS;YACT,QAAQ;SACT,CAAC,CAAC;QAEH,IAAI,mBAAmB,GAAG,GAAG,EAAE;YAC7B,2BAA2B;QAC7B,CAAC,CAAC;QACF,MAAM,KAAK,GAAG,CAAC,KAAK,IAAI,EAAE;YACxB,mBAAmB,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC;YACrF,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC;gBACxC,QAAQ,QAAQ,CAAC,OAAO,EAAE,CAAC;oBACzB,KAAK,UAAU;wBACb,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,CAAC,UAAU,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC;oBACrF,KAAK,UAAU;wBACb,+DAA+D;wBAC/D,MAAM,IAAI,mBAAmB,CAC3B,8BAA8B,QAAQ,CAAC,KAAK,IAAI,MAAM,EAAE;4BACtD,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAClD,CAAC;oBACJ,KAAK,SAAS;wBACZ,MAAM,IAAI,mBAAmB,CAC3B,2BAA2B,QAAQ,CAAC,MAAM,IAAI,kBAAkB,EAAE,CACnE,CAAC;oBACJ,KAAK,SAAS;wBACZ,MAAM,IAAI,mBAAmB,CAC3B,2BAA2B,QAAQ,CAAC,MAAM,IAAI,kBAAkB,EAAE,CACnE,CAAC;gBACN,CAAC;YACH,CAAC;oBAAS,CAAC;gBACT,mBAAmB,EAAE,CAAC;YACxB,CAAC;QACH,CAAC,CAAC,EAAE,CAAC;QAEL,OAAO;YACL,KAAK;YACL,OAAO,CAAC,MAAM,GAAG,yBAAyB;gBACxC,mBAAmB,EAAE,CAAC;gBACtB,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACxB,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"manual.js","sourceRoot":"","sources":["../../src/triggers/manual.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"validate-raw.d.ts","sourceRoot":"","sources":["../src/validate-raw.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAEV,YAAY,EAEZ,iBAAiB,EAGlB,MAAM,cAAc,CAAC;AA8KtB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,QAAQ,CAAC,OAAO,CAAC,EAAE,kBAAkB,CAAC;CACvC;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,SAAS,CAAC,CAAC,CAAC;IACvE,QAAQ,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,SAAS,CAAC,CAAC,CAAC;IAC1E,QAAQ,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,SAAS,CAAC,CAAC,CAAC;CAC3E;AAED,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG,SAAS,CAAC;AAErD,MAAM,WAAW,eAAe;IAC9B,gEAAgE;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,kBAAkB,CAAC;CAC/B;AAoKD;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,iBAAiB,EACzB,UAAU,CAAC,EAAE,gBAAgB,GAC5B,eAAe,EAAE,CAmanB"}
1
+ {"version":3,"file":"validate-raw.d.ts","sourceRoot":"","sources":["../src/validate-raw.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAEV,YAAY,EAEZ,iBAAiB,EAGlB,MAAM,cAAc,CAAC;AA0PtB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,QAAQ,CAAC,OAAO,CAAC,EAAE,kBAAkB,CAAC;CACvC;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,SAAS,CAAC,CAAC,CAAC;IACvE,QAAQ,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,SAAS,CAAC,CAAC,CAAC;IAC1E,QAAQ,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,SAAS,CAAC,CAAC,CAAC;CAC3E;AAED,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG,SAAS,CAAC;AAErD,MAAM,WAAW,eAAe;IAC9B,gEAAgE;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,kBAAkB,CAAC;CAC/B;AAsMD;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,iBAAiB,EACzB,UAAU,CAAC,EAAE,gBAAgB,GAC5B,eAAe,EAAE,CAwdnB"}
@@ -74,7 +74,79 @@ const isValidId = isValidTaskId;
74
74
  const VALID_ON_FAILURE = new Set(['skip_downstream', 'stop_all', 'ignore']);
75
75
  const VALID_PIPELINE_MODES = new Set(['trusted', 'safe']);
76
76
  const PERMISSION_FIELDS = ['read', 'write', 'execute'];
77
+ const PERMISSION_FIELD_SET = new Set(PERMISSION_FIELDS);
77
78
  const ENV_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
79
+ const PIPELINE_FIELDS = new Set([
80
+ 'name',
81
+ 'mode',
82
+ 'secrets',
83
+ 'driver',
84
+ 'model',
85
+ 'reasoning_effort',
86
+ 'permissions',
87
+ 'timeout',
88
+ 'max_concurrency',
89
+ 'plugins',
90
+ 'hooks',
91
+ 'tracks',
92
+ ]);
93
+ const TRACK_FIELDS = new Set([
94
+ 'id',
95
+ 'name',
96
+ 'color',
97
+ 'secrets',
98
+ 'agent_profile',
99
+ 'model',
100
+ 'reasoning_effort',
101
+ 'permissions',
102
+ 'driver',
103
+ 'cwd',
104
+ 'middlewares',
105
+ 'on_failure',
106
+ 'tasks',
107
+ ]);
108
+ const TASK_FIELDS = new Set([
109
+ 'id',
110
+ 'name',
111
+ 'prompt',
112
+ 'command',
113
+ 'secrets',
114
+ 'depends_on',
115
+ 'trigger',
116
+ 'continue_from',
117
+ 'model',
118
+ 'reasoning_effort',
119
+ 'permissions',
120
+ 'driver',
121
+ 'timeout',
122
+ 'middlewares',
123
+ 'completion',
124
+ 'agent_profile',
125
+ 'cwd',
126
+ 'inputs',
127
+ 'outputs',
128
+ // Legacy public field with a dedicated diagnostic below.
129
+ 'ports',
130
+ ]);
131
+ const COMMAND_SHELL_FIELDS = new Set(['shell']);
132
+ const COMMAND_ARGV_FIELDS = new Set(['argv']);
133
+ const INPUT_BINDING_FIELDS = new Set([
134
+ 'value',
135
+ 'from',
136
+ 'default',
137
+ 'required',
138
+ 'type',
139
+ 'enum',
140
+ 'description',
141
+ ]);
142
+ const OUTPUT_BINDING_FIELDS = new Set([
143
+ 'value',
144
+ 'from',
145
+ 'default',
146
+ 'type',
147
+ 'enum',
148
+ 'description',
149
+ ]);
78
150
  // Built-in plugin types always known to the SDK core, regardless of which
79
151
  // external plugin packages are installed. These MUST stay in sync with the
80
152
  // types that `bootstrapBuiltins()` registers, otherwise the editor will
@@ -119,14 +191,17 @@ function validateCommandConfig(value, path, label, errors) {
119
191
  }
120
192
  return true;
121
193
  }
194
+ const rawRecord = value;
122
195
  const raw = value;
123
196
  if (kind === 'shell') {
197
+ validateUnknownFields(rawRecord, COMMAND_SHELL_FIELDS, path, label, errors);
124
198
  if (!raw.shell || raw.shell.trim().length === 0) {
125
199
  errors.push({ path: `${path}.shell`, message: `${label}.shell must not be empty` });
126
200
  return false;
127
201
  }
128
202
  return true;
129
203
  }
204
+ validateUnknownFields(rawRecord, COMMAND_ARGV_FIELDS, path, label, errors);
130
205
  if (!raw.argv || raw.argv.length === 0) {
131
206
  errors.push({
132
207
  path: `${path}.argv`,
@@ -159,9 +234,33 @@ function commandInputReferences(command) {
159
234
  function isRecord(value) {
160
235
  return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
161
236
  }
237
+ function validateUnknownFields(value, allowed, basePath, label, errors) {
238
+ if (!isRecord(value))
239
+ return;
240
+ for (const field of Object.keys(value)) {
241
+ if (allowed.has(field))
242
+ continue;
243
+ errors.push({
244
+ path: basePath ? `${basePath}.${field}` : field,
245
+ message: `Unknown ${label} field "${field}"`,
246
+ });
247
+ }
248
+ }
162
249
  function isNonEmptyString(value) {
163
250
  return typeof value === 'string' && value.trim().length > 0;
164
251
  }
252
+ function validateOptionalString(value, path, label, errors) {
253
+ if (value === undefined)
254
+ return false;
255
+ if (!isNonEmptyString(value)) {
256
+ errors.push({
257
+ path,
258
+ message: `${label} must be a non-empty string`,
259
+ });
260
+ return false;
261
+ }
262
+ return true;
263
+ }
165
264
  function validateStringList(value, path, label, errors) {
166
265
  if (value === undefined)
167
266
  return [];
@@ -264,6 +363,7 @@ const HOOK_FIELDS = [
264
363
  'pipeline_complete',
265
364
  'pipeline_error',
266
365
  ];
366
+ const HOOK_FIELD_SET = new Set(HOOK_FIELDS);
267
367
  function validateHooks(value, errors) {
268
368
  if (value === undefined)
269
369
  return;
@@ -271,6 +371,11 @@ function validateHooks(value, errors) {
271
371
  errors.push({ path: 'hooks', message: 'hooks must be an object map' });
272
372
  return;
273
373
  }
374
+ for (const field of Object.keys(value)) {
375
+ if (!HOOK_FIELD_SET.has(field)) {
376
+ errors.push({ path: `hooks.${field}`, message: `Unknown hook event "${field}"` });
377
+ }
378
+ }
274
379
  for (const field of HOOK_FIELDS) {
275
380
  if (!(field in value))
276
381
  continue;
@@ -289,14 +394,7 @@ function validateHooks(value, errors) {
289
394
  }
290
395
  }
291
396
  function validateReasoningEffort(value, path, errors) {
292
- if (value === undefined)
293
- return;
294
- if (!isNonEmptyString(value)) {
295
- errors.push({
296
- path,
297
- message: 'reasoning_effort must be a non-empty string',
298
- });
299
- }
397
+ validateOptionalString(value, path, 'reasoning_effort', errors);
300
398
  }
301
399
  /**
302
400
  * Validate a raw pipeline config.
@@ -312,6 +410,10 @@ function validateReasoningEffort(value, path, errors) {
312
410
  */
313
411
  export function validateRaw(config, knownTypes) {
314
412
  const errors = [];
413
+ if (!isRecord(config)) {
414
+ errors.push({ path: 'pipeline', message: 'pipeline must be an object' });
415
+ return errors;
416
+ }
315
417
  const knownTriggers = knownTypes
316
418
  ? new Set([...BUILTIN_TRIGGER_TYPES, ...(knownTypes.triggers ?? [])])
317
419
  : null;
@@ -325,16 +427,19 @@ export function validateRaw(config, knownTypes) {
325
427
  ? new Set([...BUILTIN_MIDDLEWARE_TYPES, ...(knownTypes.middlewares ?? [])])
326
428
  : null;
327
429
  // Top level
430
+ validateUnknownFields(config, PIPELINE_FIELDS, '', 'pipeline', errors);
328
431
  if (!isNonEmptyString(config.name)) {
329
432
  errors.push({ path: 'name', message: 'Pipeline name is required' });
330
433
  }
331
- if (config.mode && !VALID_PIPELINE_MODES.has(config.mode)) {
434
+ if (config.mode !== undefined && !VALID_PIPELINE_MODES.has(config.mode)) {
332
435
  errors.push({
333
436
  path: 'mode',
334
437
  message: `Invalid mode "${config.mode}". Expected "trusted" or "safe".`,
335
438
  });
336
439
  }
337
440
  validateReasoningEffort(config.reasoning_effort, 'reasoning_effort', errors);
441
+ validateOptionalString(config.driver, 'driver', 'driver', errors);
442
+ validateOptionalString(config.model, 'model', 'model', errors);
338
443
  if (config.timeout !== undefined) {
339
444
  const validation = validateDuration(config.timeout);
340
445
  if (!validation.ok) {
@@ -355,7 +460,7 @@ export function validateRaw(config, knownTypes) {
355
460
  validateStringList(config.plugins, 'plugins', 'plugins', errors);
356
461
  validateSecretList(config.secrets, 'secrets', errors);
357
462
  validateHooks(config.hooks, errors);
358
- if (knownDrivers && config.driver && !knownDrivers.has(config.driver)) {
463
+ if (knownDrivers && isNonEmptyString(config.driver) && !knownDrivers.has(config.driver)) {
359
464
  errors.push({
360
465
  path: 'driver',
361
466
  message: `Unknown driver type "${config.driver}"`,
@@ -389,6 +494,7 @@ export function validateRaw(config, knownTypes) {
389
494
  continue;
390
495
  }
391
496
  const track = maybeTrack;
497
+ validateUnknownFields(track, TRACK_FIELDS, trackPath, 'track', errors);
392
498
  if (!isNonEmptyString(track.id)) {
393
499
  errors.push({ path: `${trackPath}.id`, message: 'Track id is required' });
394
500
  }
@@ -407,14 +513,19 @@ export function validateRaw(config, knownTypes) {
407
513
  if (!isNonEmptyString(track.name)) {
408
514
  errors.push({ path: `${trackPath}.name`, message: 'Track name is required' });
409
515
  }
410
- if (track.on_failure && !VALID_ON_FAILURE.has(track.on_failure)) {
516
+ if (track.on_failure !== undefined && !VALID_ON_FAILURE.has(track.on_failure)) {
411
517
  errors.push({
412
518
  path: `${trackPath}.on_failure`,
413
519
  message: `Invalid on_failure value "${track.on_failure}". Expected "skip_downstream", "stop_all", or "ignore".`,
414
520
  });
415
521
  }
522
+ validateOptionalString(track.color, `${trackPath}.color`, 'track.color', errors);
523
+ validateOptionalString(track.driver, `${trackPath}.driver`, 'track.driver', errors);
524
+ validateOptionalString(track.model, `${trackPath}.model`, 'track.model', errors);
525
+ validateOptionalString(track.agent_profile, `${trackPath}.agent_profile`, 'track.agent_profile', errors);
526
+ validateOptionalString(track.cwd, `${trackPath}.cwd`, 'track.cwd', errors);
416
527
  validateReasoningEffort(track.reasoning_effort, `${trackPath}.reasoning_effort`, errors);
417
- if (knownDrivers && track.driver && !knownDrivers.has(track.driver)) {
528
+ if (knownDrivers && isNonEmptyString(track.driver) && !knownDrivers.has(track.driver)) {
418
529
  errors.push({
419
530
  path: `${trackPath}.driver`,
420
531
  message: `Unknown driver type "${track.driver}"`,
@@ -468,6 +579,7 @@ export function validateRaw(config, knownTypes) {
468
579
  continue;
469
580
  }
470
581
  const task = maybeTask;
582
+ validateUnknownFields(maybeTask, TASK_FIELDS, taskPath, `task "${typeof task.id === 'string' ? task.id : ki}"`, errors);
471
583
  if (!isNonEmptyString(task.id)) {
472
584
  errors.push({ path: `${taskPath}.id`, message: 'Task id is required' });
473
585
  continue; // Can't check further without an id
@@ -491,6 +603,7 @@ export function validateRaw(config, knownTypes) {
491
603
  });
492
604
  }
493
605
  seenTaskIds.add(task.id);
606
+ const hasPromptField = task.prompt !== undefined;
494
607
  const hasPromptKey = typeof task.prompt === 'string';
495
608
  const hasCommandField = isCommandTaskConfig(task);
496
609
  const hasCommandKey = commandConfigKind(task.command) !== null;
@@ -518,14 +631,20 @@ export function validateRaw(config, knownTypes) {
518
631
  message: `Task "${task.id}": cannot have both "prompt" and "command"`,
519
632
  });
520
633
  }
521
- else if (!hasPromptKey && !hasCommandField) {
634
+ else if (!hasPromptField && !hasCommandField) {
522
635
  errors.push({
523
636
  path: taskPath,
524
637
  message: `Task "${task.id}": must have "prompt" or "command"`,
525
638
  });
526
639
  }
527
640
  else {
528
- if (hasPromptKey && task.prompt.trim().length === 0) {
641
+ if (hasPromptField && !hasPromptKey) {
642
+ errors.push({
643
+ path: `${taskPath}.prompt`,
644
+ message: 'task.prompt must be a non-empty string',
645
+ });
646
+ }
647
+ else if (hasPromptKey && task.prompt.trim().length === 0) {
529
648
  errors.push({
530
649
  path: taskPath,
531
650
  message: `Task "${task.id}": prompt content cannot be empty`,
@@ -545,8 +664,13 @@ export function validateRaw(config, knownTypes) {
545
664
  });
546
665
  }
547
666
  }
667
+ validateOptionalString(task.name, `${taskPath}.name`, 'task.name', errors);
668
+ validateOptionalString(task.driver, `${taskPath}.driver`, 'task.driver', errors);
669
+ validateOptionalString(task.model, `${taskPath}.model`, 'task.model', errors);
670
+ validateOptionalString(task.agent_profile, `${taskPath}.agent_profile`, 'task.agent_profile', errors);
671
+ validateOptionalString(task.cwd, `${taskPath}.cwd`, 'task.cwd', errors);
548
672
  validateReasoningEffort(task.reasoning_effort, `${taskPath}.reasoning_effort`, errors);
549
- if (knownDrivers && task.driver && !knownDrivers.has(task.driver)) {
673
+ if (knownDrivers && isNonEmptyString(task.driver) && !knownDrivers.has(task.driver)) {
550
674
  errors.push({
551
675
  path: `${taskPath}.driver`,
552
676
  message: `Unknown driver type "${task.driver}"`,
@@ -680,6 +804,7 @@ function validatePermissions(value, basePath, errors) {
680
804
  return;
681
805
  }
682
806
  const p = value;
807
+ validateUnknownFields(p, PERMISSION_FIELD_SET, basePath, 'permissions', errors);
683
808
  for (const field of PERMISSION_FIELDS) {
684
809
  const path = `${basePath}.${field}`;
685
810
  if (!(field in p)) {
@@ -727,6 +852,48 @@ const INPUT_TASK_STREAM_FIELDS = [
727
852
  ];
728
853
  const OUTPUT_BINDING_SOURCES = ['stdout', 'stderr', 'normalizedOutput'];
729
854
  const OUTPUT_BINDING_JSON_RE = /^json\.[A-Za-z_][A-Za-z0-9_]*$/;
855
+ function pushInvalidInputBindingSource(task, name, source, path, errors) {
856
+ errors.push({
857
+ path,
858
+ message: `Task "${task.id}": input binding "${name}" from "${source}" must reference an upstream output or stream ` +
859
+ '(use outputs.<name>, taskId.<name>, taskId.outputs.<name>, taskId.stdout, taskId.stderr, taskId.normalizedOutput, or taskId.exitCode)',
860
+ });
861
+ }
862
+ function validateInputBindingSourceShape(task, name, source, path, errors) {
863
+ if (source.startsWith('outputs.')) {
864
+ const outputName = source.slice('outputs.'.length);
865
+ if (PORT_NAME_RE.test(outputName))
866
+ return true;
867
+ pushInvalidInputBindingSource(task, name, source, path, errors);
868
+ return false;
869
+ }
870
+ if (!source.includes('.')) {
871
+ pushInvalidInputBindingSource(task, name, source, path, errors);
872
+ return false;
873
+ }
874
+ const outputMarker = '.outputs.';
875
+ const outputIdx = source.lastIndexOf(outputMarker);
876
+ if (outputIdx > 0) {
877
+ const outputName = source.slice(outputIdx + outputMarker.length);
878
+ if (PORT_NAME_RE.test(outputName))
879
+ return true;
880
+ pushInvalidInputBindingSource(task, name, source, path, errors);
881
+ return false;
882
+ }
883
+ for (const field of INPUT_TASK_STREAM_FIELDS) {
884
+ const suffix = `.${field}`;
885
+ if (source.endsWith(suffix) && source.length > suffix.length)
886
+ return true;
887
+ }
888
+ const dot = source.lastIndexOf('.');
889
+ if (dot > 0) {
890
+ const outputName = source.slice(dot + 1);
891
+ if (PORT_NAME_RE.test(outputName))
892
+ return true;
893
+ }
894
+ pushInvalidInputBindingSource(task, name, source, path, errors);
895
+ return false;
896
+ }
730
897
  function validateBindingMap(value, basePath, kind, errors) {
731
898
  if (value === undefined)
732
899
  return;
@@ -748,6 +915,7 @@ function validateBindingMap(value, basePath, kind, errors) {
748
915
  continue;
749
916
  }
750
917
  const binding = rawBinding;
918
+ validateUnknownFields(binding, kind === 'inputs' ? INPUT_BINDING_FIELDS : OUTPUT_BINDING_FIELDS, path, `task.${kind}.${name}`, errors);
751
919
  if ('from' in binding && typeof binding.from !== 'string') {
752
920
  errors.push({ path: `${path}.from`, message: `task.${kind}.${name}.from must be a string` });
753
921
  }
@@ -805,12 +973,7 @@ function validateInputBindingSources(task, trackId, taskPath, index, errors) {
805
973
  const source = rawBinding.from;
806
974
  if (typeof source !== 'string')
807
975
  continue;
808
- if (!source.startsWith('outputs.') && !source.includes('.')) {
809
- errors.push({
810
- path: `${taskPath}.inputs.${name}.from`,
811
- message: `Task "${task.id}": input binding "${name}" from "${source}" must reference an upstream output or stream ` +
812
- '(use outputs.<name>, taskId.<name>, taskId.outputs.<name>, taskId.stdout, taskId.stderr, taskId.normalizedOutput, or taskId.exitCode)',
813
- });
976
+ if (!validateInputBindingSourceShape(task, name, source, `${taskPath}.inputs.${name}.from`, errors)) {
814
977
  continue;
815
978
  }
816
979
  const upstreamRef = bindingSourceTaskRef(source);