primitive-admin 1.0.44 → 1.0.45

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 (71) hide show
  1. package/README.md +43 -0
  2. package/assets/skill/skills/primitive-platform/SKILL.md +85 -26
  3. package/dist/bin/primitive.js +6 -0
  4. package/dist/bin/primitive.js.map +1 -1
  5. package/dist/src/commands/analytics.js +16 -16
  6. package/dist/src/commands/analytics.js.map +1 -1
  7. package/dist/src/commands/apps.js +14 -14
  8. package/dist/src/commands/apps.js.map +1 -1
  9. package/dist/src/commands/auth.js +70 -20
  10. package/dist/src/commands/auth.js.map +1 -1
  11. package/dist/src/commands/blob-buckets.js +11 -11
  12. package/dist/src/commands/blob-buckets.js.map +1 -1
  13. package/dist/src/commands/catalog.js +17 -17
  14. package/dist/src/commands/catalog.js.map +1 -1
  15. package/dist/src/commands/collection-type-configs.js +5 -5
  16. package/dist/src/commands/collection-type-configs.js.map +1 -1
  17. package/dist/src/commands/collections.js +6 -6
  18. package/dist/src/commands/collections.js.map +1 -1
  19. package/dist/src/commands/comparisons.js +6 -6
  20. package/dist/src/commands/comparisons.js.map +1 -1
  21. package/dist/src/commands/cron-triggers.js +17 -17
  22. package/dist/src/commands/cron-triggers.js.map +1 -1
  23. package/dist/src/commands/database-types.js +13 -13
  24. package/dist/src/commands/database-types.js.map +1 -1
  25. package/dist/src/commands/databases.js +132 -8
  26. package/dist/src/commands/databases.js.map +1 -1
  27. package/dist/src/commands/email-templates.js +6 -6
  28. package/dist/src/commands/email-templates.js.map +1 -1
  29. package/dist/src/commands/env.js +6 -6
  30. package/dist/src/commands/env.js.map +1 -1
  31. package/dist/src/commands/group-type-configs.js +6 -6
  32. package/dist/src/commands/group-type-configs.js.map +1 -1
  33. package/dist/src/commands/groups.js +7 -7
  34. package/dist/src/commands/groups.js.map +1 -1
  35. package/dist/src/commands/init.js +175 -144
  36. package/dist/src/commands/init.js.map +1 -1
  37. package/dist/src/commands/integrations.js +31 -21
  38. package/dist/src/commands/integrations.js.map +1 -1
  39. package/dist/src/commands/prompts.js +17 -16
  40. package/dist/src/commands/prompts.js.map +1 -1
  41. package/dist/src/commands/rule-sets.js +8 -8
  42. package/dist/src/commands/rule-sets.js.map +1 -1
  43. package/dist/src/commands/sync.js +803 -275
  44. package/dist/src/commands/sync.js.map +1 -1
  45. package/dist/src/commands/tokens.js +9 -9
  46. package/dist/src/commands/tokens.js.map +1 -1
  47. package/dist/src/commands/users.js +44 -3
  48. package/dist/src/commands/users.js.map +1 -1
  49. package/dist/src/commands/webhooks.js +18 -18
  50. package/dist/src/commands/webhooks.js.map +1 -1
  51. package/dist/src/commands/workflows.js +273 -63
  52. package/dist/src/commands/workflows.js.map +1 -1
  53. package/dist/src/lib/api-client.js +240 -72
  54. package/dist/src/lib/api-client.js.map +1 -1
  55. package/dist/src/lib/migration-nag.js +163 -0
  56. package/dist/src/lib/migration-nag.js.map +1 -0
  57. package/dist/src/lib/output.js +58 -6
  58. package/dist/src/lib/output.js.map +1 -1
  59. package/dist/src/lib/refresh-admin-credentials.js +103 -0
  60. package/dist/src/lib/refresh-admin-credentials.js.map +1 -0
  61. package/dist/src/lib/template.js +80 -1
  62. package/dist/src/lib/template.js.map +1 -1
  63. package/dist/src/lib/toml-database-config.js +384 -0
  64. package/dist/src/lib/toml-database-config.js.map +1 -0
  65. package/dist/src/lib/toml-params-validator.js +183 -0
  66. package/dist/src/lib/toml-params-validator.js.map +1 -0
  67. package/dist/src/lib/workflow-fragments.js +121 -0
  68. package/dist/src/lib/workflow-fragments.js.map +1 -0
  69. package/dist/src/lib/workflow-toml-validator.js +328 -0
  70. package/dist/src/lib/workflow-toml-validator.js.map +1 -0
  71. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toml-database-config.js","sourceRoot":"","sources":["../../../src/lib/toml-database-config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,183 @@
1
+ /**
2
+ * Validator: every `$params.X` reference inside an operation's
3
+ * `definition` must correspond to a declared param in
4
+ * `[[operations.params]]` (or the legacy JSON-string params object).
5
+ *
6
+ * Background (issue #752): a typo like `$params.proectId` used to
7
+ * silently no-op at runtime. With native TOML, we can catch these at
8
+ * `sync push` time with the file path and line number of the
9
+ * operation block where the bad reference appears.
10
+ *
11
+ * Design notes:
12
+ * - Line attribution is per-operation, not per-reference. We don't
13
+ * parse `definition` line-by-line; we just locate the
14
+ * `[[operations]]` header for the named op in the raw source and
15
+ * report that line. This is the load-bearing UX (jump to the
16
+ * offending op block); pinpointing the exact `$params.X` reference
17
+ * inside a sub-table would require swapping the TOML parser, which
18
+ * the issue explicitly leaves to implementer judgement.
19
+ * - We intentionally diverge from the server-side `collectParamRefs`
20
+ * in `database-type-operations-controller.ts:1163`. The server pushes
21
+ * the full path (e.g. `"X.Y"` for `$params.X.Y`); the CLI extracts
22
+ * only the first segment (`"X"`). Net effect: the CLI validator is
23
+ * more lenient than the server — `$params.X.Y` passes the CLI check
24
+ * when `X` alone is declared in `[[operations.params]]`, even though
25
+ * the server treats the full path as the lookup key. The server
26
+ * remains authoritative; the CLI's first-segment extraction is a
27
+ * pragmatic choice so authors can declare structured params (e.g.
28
+ * `config: { type: "object" }`) and reference sub-fields like
29
+ * `$params.config.subKey` without listing every sub-field
30
+ * individually (review feedback r3246635661).
31
+ */
32
+ /**
33
+ * Walk an arbitrary JSON-ish value and collect `$params.X` references
34
+ * found in string-valued leaves, returning only the first dotted segment
35
+ * (`"X"` for `$params.X.Y`). Intentionally more lenient than the
36
+ * server-side helper, which pushes the full path — see the module
37
+ * doc-comment for the rationale.
38
+ */
39
+ export function collectParamRefs(value) {
40
+ const refs = [];
41
+ if (typeof value === "string") {
42
+ const match = value.match(/^\$params\.(.+)$/);
43
+ if (match) {
44
+ const first = match[1].split(/[.\[]/)[0];
45
+ if (first)
46
+ refs.push(first);
47
+ }
48
+ }
49
+ else if (Array.isArray(value)) {
50
+ for (const item of value) {
51
+ refs.push(...collectParamRefs(item));
52
+ }
53
+ }
54
+ else if (value !== null && typeof value === "object") {
55
+ for (const v of Object.values(value)) {
56
+ refs.push(...collectParamRefs(v));
57
+ }
58
+ }
59
+ return refs;
60
+ }
61
+ /**
62
+ * Normalize a `params` value (object, array, or JSON string) into the
63
+ * set of declared param names.
64
+ */
65
+ export function declaredParamNames(params) {
66
+ const names = new Set();
67
+ if (params == null)
68
+ return names;
69
+ let value = params;
70
+ if (typeof value === "string") {
71
+ try {
72
+ value = JSON.parse(value);
73
+ }
74
+ catch {
75
+ return names;
76
+ }
77
+ }
78
+ if (Array.isArray(value)) {
79
+ for (const row of value) {
80
+ if (row && typeof row === "object" && typeof row.name === "string") {
81
+ names.add(row.name);
82
+ }
83
+ }
84
+ }
85
+ else if (typeof value === "object" && value !== null) {
86
+ for (const key of Object.keys(value)) {
87
+ names.add(key);
88
+ }
89
+ }
90
+ return names;
91
+ }
92
+ /**
93
+ * Find the 1-indexed line number in `rawToml` where the `[[operations]]`
94
+ * block declaring `opName` starts. Returns 0 if not found.
95
+ *
96
+ * Implementation: walk in source order, track the most recent
97
+ * `[[operations]]` header, and when we see a `name = "<opName>"` line
98
+ * before the next `[[operations]]` or top-level header, return that
99
+ * header's line.
100
+ */
101
+ export function locateOperationLine(rawToml, opName) {
102
+ const lines = rawToml.split(/\r?\n/);
103
+ let lastOpHeader = 0;
104
+ let armed = false;
105
+ for (let i = 0; i < lines.length; i++) {
106
+ const line = lines[i].trim();
107
+ if (line === "[[operations]]") {
108
+ lastOpHeader = i + 1;
109
+ armed = true;
110
+ continue;
111
+ }
112
+ if (!armed)
113
+ continue;
114
+ // Another array-of-tables / top-level table → not this op anymore.
115
+ if (line.startsWith("[[") && line !== "[[operations]]" && !line.startsWith("[[operations.")) {
116
+ armed = false;
117
+ continue;
118
+ }
119
+ if (line.startsWith("[") && !line.startsWith("[[") && !line.startsWith("[operations.")) {
120
+ armed = false;
121
+ continue;
122
+ }
123
+ const m = line.match(/^name\s*=\s*["'](.+)["']\s*$/);
124
+ if (m && m[1] === opName) {
125
+ return lastOpHeader;
126
+ }
127
+ }
128
+ return 0;
129
+ }
130
+ /**
131
+ * Validate `$params` references across every operation in a parsed
132
+ * database-type config.
133
+ *
134
+ * Errors (blocking):
135
+ * - A `$params.X` reference inside `definition` where `X` is not
136
+ * declared in `[[operations.params]]`.
137
+ *
138
+ * Warnings (soft, not blocking):
139
+ * - A param declared in `[[operations.params]]` that is not referenced
140
+ * anywhere in `definition`. Authors may be staging a deprecation.
141
+ */
142
+ export function validateOperations(opts) {
143
+ const errors = [];
144
+ const warnings = [];
145
+ for (const op of opts.operations) {
146
+ if (!op || !op.name)
147
+ continue;
148
+ const declared = declaredParamNames(op.params);
149
+ const refs = new Set(collectParamRefs(op.definition));
150
+ const line = locateOperationLine(opts.rawToml, op.name);
151
+ for (const ref of refs) {
152
+ if (!declared.has(ref)) {
153
+ errors.push({
154
+ file: opts.filePath,
155
+ line,
156
+ op: op.name,
157
+ message: `$params.${ref} not declared in [[operations.params]] for operation '${op.name}'`,
158
+ });
159
+ }
160
+ }
161
+ for (const name of declared) {
162
+ if (!refs.has(name)) {
163
+ warnings.push({
164
+ file: opts.filePath,
165
+ line,
166
+ op: op.name,
167
+ message: `param '${name}' declared but not referenced in operation '${op.name}'`,
168
+ });
169
+ }
170
+ }
171
+ }
172
+ return { errors, warnings };
173
+ }
174
+ /**
175
+ * Format a validation issue as `<file>:<line>: <message>`.
176
+ */
177
+ export function formatIssue(issue) {
178
+ if (issue.line > 0) {
179
+ return `${issue.file}:${issue.line}: ${issue.message}`;
180
+ }
181
+ return `${issue.file}: ${issue.message}`;
182
+ }
183
+ //# sourceMappingURL=toml-params-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toml-params-validator.js","sourceRoot":"","sources":["../../../src/lib/toml-params-validator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * CLI-only workflow fragment expansion.
3
+ *
4
+ * Workflows may declare `include = ["fragment-name", ...]` at the top of
5
+ * their TOML. The CLI expands those references into a fully-flattened
6
+ * `[[steps]]` list before push — the server never sees fragments and
7
+ * stores only the canonical, expanded JSON.
8
+ *
9
+ * Pinned decisions (#744):
10
+ * - CLI-only. No server-side WorkflowFragment model.
11
+ * - Fragments live at <workflowDir>/../workflow-fragments/<name>.toml.
12
+ * - Fragment files are `[[steps]]` lists only — no `[workflow]` block.
13
+ * - No recursive includes in v1 (fragments cannot themselves `include`).
14
+ * - Unique step ids validated post-expansion; collisions name both
15
+ * locations in the error message.
16
+ *
17
+ * Wiring: `parseTomlFile()` in `cli/src/commands/sync.ts` calls
18
+ * `expandWorkflowTomlData()` after parsing. All 24 push parse sites in
19
+ * sync.ts route through that single seam, so the expansion is uniform.
20
+ * The standalone `expandWorkflow(filePath)` helper backs the
21
+ * `primitive workflows expand` subcommand for debugging.
22
+ */
23
+ import { existsSync, readFileSync } from "fs";
24
+ import { dirname, join, basename } from "path";
25
+ import * as TOML from "@iarna/toml";
26
+ /**
27
+ * Read and expand a workflow TOML file from disk. Returns the parsed
28
+ * TOML with all `include` fragments spliced in. If the file has no
29
+ * `include` key, the parsed TOML is returned unchanged.
30
+ */
31
+ export function expandWorkflow(workflowPath) {
32
+ const content = readFileSync(workflowPath, "utf-8");
33
+ const parsed = TOML.parse(content);
34
+ return expandWorkflowTomlData(parsed, workflowPath);
35
+ }
36
+ /**
37
+ * Expand the `include` key of an already-parsed TOML object. Resolves
38
+ * fragment files relative to `<workflowPath>/../../workflow-fragments/`.
39
+ * Use this when the TOML has already been parsed elsewhere (e.g. inside
40
+ * `parseTomlFile()`).
41
+ */
42
+ export function expandWorkflowTomlData(parsed, workflowPath) {
43
+ // Fast path: nothing to expand. Preserve the original shape exactly —
44
+ // including the absence of a `steps` field, since not every TOML file
45
+ // routed through `parseTomlFile()` represents a workflow.
46
+ if (!("include" in parsed)) {
47
+ return parsed;
48
+ }
49
+ const includeList = parsed.include;
50
+ if (!Array.isArray(includeList)) {
51
+ throw new Error(`Workflow '${workflowPath}' has an 'include' key but it is not an array. Use \`include = ["fragment-name"]\`.`);
52
+ }
53
+ // Resolve fragments directory: sibling of workflow's parent directory.
54
+ // E.g. workflow at config/workflows/foo.toml
55
+ // fragments at config/workflow-fragments/<name>.toml
56
+ const fragmentsDir = join(dirname(workflowPath), "..", "workflow-fragments");
57
+ const workflowOwnSteps = Array.isArray(parsed.steps)
58
+ ? parsed.steps
59
+ : [];
60
+ const allOriginated = [];
61
+ for (const fragmentName of includeList) {
62
+ if (typeof fragmentName !== "string" || fragmentName.length === 0) {
63
+ throw new Error(`Workflow '${workflowPath}' has an invalid include entry: ${JSON.stringify(fragmentName)}. Each entry must be a fragment name string.`);
64
+ }
65
+ const fragmentPath = join(fragmentsDir, `${fragmentName}.toml`);
66
+ const fragment = readFragmentSafely(fragmentPath, workflowPath, fragmentName);
67
+ for (const step of fragment.steps) {
68
+ allOriginated.push({ step, origin: `fragment '${fragmentName}'` });
69
+ }
70
+ }
71
+ for (const step of workflowOwnSteps) {
72
+ allOriginated.push({ step, origin: `workflow '${basename(workflowPath)}'` });
73
+ }
74
+ assertUniqueStepIds(allOriginated, workflowPath);
75
+ // Build the expanded object: drop `include`, replace `steps` with the
76
+ // concatenated list. Preserve all other top-level keys (workflow,
77
+ // triggers, configs, etc.) exactly as parsed.
78
+ const result = { ...parsed };
79
+ delete result.include;
80
+ result.steps = allOriginated.map((o) => o.step);
81
+ return result;
82
+ }
83
+ function readFragmentSafely(fragmentPath, workflowPath, fragmentName) {
84
+ if (!existsSync(fragmentPath)) {
85
+ throw new Error(`Workflow '${workflowPath}' includes fragment '${fragmentName}' but the file does not exist at '${fragmentPath}'.`);
86
+ }
87
+ let parsed;
88
+ try {
89
+ const content = readFileSync(fragmentPath, "utf-8");
90
+ parsed = TOML.parse(content);
91
+ }
92
+ catch (err) {
93
+ throw new Error(`Failed to parse fragment '${fragmentName}' at '${fragmentPath}': ${err?.message ?? err}`);
94
+ }
95
+ if ("include" in parsed) {
96
+ throw new Error(`Fragment '${fragmentName}' at '${fragmentPath}' contains its own 'include' key — recursive includes are not supported in v1. Inline the steps directly into this fragment.`);
97
+ }
98
+ if ("workflow" in parsed) {
99
+ throw new Error(`Fragment '${fragmentName}' at '${fragmentPath}' contains a [workflow] block. Fragment files must be [[steps]] lists only.`);
100
+ }
101
+ const steps = Array.isArray(parsed.steps)
102
+ ? parsed.steps
103
+ : [];
104
+ return { steps };
105
+ }
106
+ function assertUniqueStepIds(originated, workflowPath) {
107
+ const seen = new Map();
108
+ for (const { step, origin } of originated) {
109
+ const id = step?.id;
110
+ if (id === undefined || id === null)
111
+ continue; // let downstream code complain about missing ids
112
+ if (typeof id !== "string")
113
+ continue;
114
+ if (seen.has(id)) {
115
+ const firstOrigin = seen.get(id);
116
+ throw new Error(`Step id '${id}' appears twice when expanding workflow '${workflowPath}': first in ${firstOrigin}, then in ${origin}.`);
117
+ }
118
+ seen.set(id, origin);
119
+ }
120
+ }
121
+ //# sourceMappingURL=workflow-fragments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-fragments.js","sourceRoot":"","sources":["../../../src/lib/workflow-fragments.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,328 @@
1
+ /**
2
+ * Push-time validator for workflow TOML files (issue #685).
3
+ *
4
+ * Detects the common footgun where a user writes `[steps.<id>.<field>]` under
5
+ * an open `[[steps]]` array. TOML parses that as a sub-table on the
6
+ * most-recent step keyed by the step's id (e.g. `steps[0]["refresh-each"]`),
7
+ * not as the intended `steps[0].request`. The result is a step with an
8
+ * unrecognized top-level field — the runtime silently ignores it, and the
9
+ * step then runs with an empty `request` block.
10
+ *
11
+ * The validator walks every step in `tomlData.steps[]` and reports any
12
+ * top-level field not in the universal-and-consumed allowlist. The allowlist
13
+ * is the union of:
14
+ * - Universal step fields declared on `BaseStepDefinition` in
15
+ * `src/workflows/runner/types.ts`
16
+ * - The top-level fields each step runner in `src/workflows/steps/`
17
+ * actually reads
18
+ *
19
+ * The list is universal-only (not per-kind) by design: the CLI doesn't know
20
+ * which step kinds exist on a given server version, and a per-kind list
21
+ * would couple the CLI tightly to the runtime. A universal allowlist
22
+ * catches the misnested-header footgun cleanly while staying tolerant of
23
+ * future step kinds that consume top-level fields already in the union.
24
+ *
25
+ * Maintenance: when a new step kind starts reading a new top-level field,
26
+ * add the field name to `ALLOWLISTED_FIELDS` below. See `cli/README.md`
27
+ * for the maintenance note.
28
+ */
29
+ /**
30
+ * Universal-only allowlist of top-level fields permitted on a step.
31
+ *
32
+ * Membership combines:
33
+ * 1) Universal fields on `BaseStepDefinition` in
34
+ * `src/workflows/runner/types.ts` and the runner engine's reads of
35
+ * `stepDef.*`.
36
+ * 2) The union of top-level fields actually consumed by step runners in
37
+ * `src/workflows/steps/` (audited 2026-05-15).
38
+ *
39
+ * Keep this sorted to make diffs reviewable.
40
+ */
41
+ const ALLOWLISTED_FIELDS = new Set([
42
+ // Universal (BaseStepDefinition + engine).
43
+ "as",
44
+ "concurrency",
45
+ "continueOnError",
46
+ "description",
47
+ "forEach",
48
+ "id",
49
+ "kind",
50
+ "maxItems",
51
+ "name",
52
+ "runIf",
53
+ "saveAs",
54
+ "selector",
55
+ "strict",
56
+ "successWhen",
57
+ "timeout",
58
+ // Per-kind, union across runners.
59
+ "_testSteps", // workflow.call test-mode override
60
+ "action",
61
+ "appId",
62
+ "asBase64",
63
+ "attachments",
64
+ "blobId",
65
+ "bodyMode",
66
+ "bucketId",
67
+ "bucketKey",
68
+ "cacheTtlSeconds",
69
+ "configId",
70
+ "content",
71
+ "contentBase64",
72
+ "contentType",
73
+ "context",
74
+ "cursor",
75
+ "cursorField",
76
+ "databaseId",
77
+ "direction",
78
+ "dryRun",
79
+ "durationMs",
80
+ "email",
81
+ "events",
82
+ "expiresInSeconds",
83
+ "feature",
84
+ "filename",
85
+ "filters",
86
+ "groupBy",
87
+ "groupId",
88
+ "groupType",
89
+ "htmlBody",
90
+ "includeUserDetails",
91
+ "input",
92
+ "integrationKey",
93
+ "itemsField",
94
+ "limit",
95
+ "maxPages",
96
+ "message",
97
+ "messages",
98
+ "metrics",
99
+ "model",
100
+ "modelOverride",
101
+ "ms",
102
+ "multipartFields",
103
+ "onPartialFailure",
104
+ "operationName",
105
+ "output",
106
+ "page",
107
+ "params",
108
+ "payload",
109
+ "plugins",
110
+ "prompt",
111
+ "promptKey",
112
+ "query",
113
+ "queryType",
114
+ "request",
115
+ "route",
116
+ "runs",
117
+ "sort",
118
+ "step", // collect: nested inner step definition
119
+ "subject",
120
+ "tags",
121
+ "temperature",
122
+ "templateType",
123
+ "textBody",
124
+ "thinkingLevel",
125
+ "to",
126
+ "tools",
127
+ "tool_choice",
128
+ "top_p",
129
+ "toUserId",
130
+ "type",
131
+ "user",
132
+ "userId",
133
+ "userUlid",
134
+ "variables",
135
+ "windowDays",
136
+ "workflowKey",
137
+ ]);
138
+ /**
139
+ * Walk a parsed workflow TOML document and return all unknown-field errors.
140
+ *
141
+ * @param tomlData The output of `TOML.parse()` for a workflow TOML file.
142
+ * @returns An array of error objects, one per offending field. Empty if no
143
+ * errors were found.
144
+ */
145
+ export function validateWorkflowToml(tomlData) {
146
+ const errors = [];
147
+ if (tomlData === null || tomlData === undefined) {
148
+ return errors;
149
+ }
150
+ const steps = tomlData.steps;
151
+ // No steps section at all → nothing to validate. This is fine for
152
+ // partial TOML files (some commands accept a metadata-only file).
153
+ if (steps === undefined || steps === null) {
154
+ return errors;
155
+ }
156
+ // `steps` is a table instead of an array. This typically means the user
157
+ // wrote `[steps.foo]` with no preceding `[[steps]]` array marker, so
158
+ // TOML resolved `steps` to a table. The runtime expects an array — flag
159
+ // it with a clear shape diagnostic.
160
+ if (!Array.isArray(steps)) {
161
+ if (typeof steps === "object") {
162
+ errors.push({
163
+ stepIndex: -1,
164
+ stepId: null,
165
+ field: "__steps_shape__",
166
+ hint: 'The `steps` section is a table, not an array. Workflow TOML expects `[[steps]]` array markers — add `[[steps]]` before any `[steps.<field>]` blocks.',
167
+ });
168
+ }
169
+ else {
170
+ errors.push({
171
+ stepIndex: -1,
172
+ stepId: null,
173
+ field: "__steps_shape__",
174
+ hint: `The \`steps\` section must be an array of step tables (received: ${typeof steps}).`,
175
+ });
176
+ }
177
+ return errors;
178
+ }
179
+ for (let i = 0; i < steps.length; i++) {
180
+ const step = steps[i];
181
+ // Defensive: array entry isn't an object. Should be near-impossible with
182
+ // valid `[[steps]]` syntax, but possible if the user writes `steps =
183
+ // ["a", "b"]`. Surface it so the user gets a diagnostic instead of a
184
+ // silent skip.
185
+ if (step === null || typeof step !== "object" || Array.isArray(step)) {
186
+ errors.push({
187
+ stepIndex: i,
188
+ stepId: null,
189
+ field: "__step_shape__",
190
+ hint: `Each entry in \`steps[]\` must be a table. Got: ${step === null ? "null" : Array.isArray(step) ? "array" : typeof step}.`,
191
+ });
192
+ continue;
193
+ }
194
+ validateStepObject(step, i, /* parentStepId */ null, errors);
195
+ // Codex finding 2 (PR #762, 2026-05-15): a `collect` step's nested
196
+ // `step` field is itself a step definition that the collect runner
197
+ // executes. The outer-step allowlist accepts `step` as a top-level
198
+ // field, but that's a structural pass-through — we need to recurse
199
+ // into the inner step's keys to catch the same misnested-header
200
+ // footgun (e.g. `[steps.step.call.request]` parses as `step.step =
201
+ // { call: { request: {...} } }`, with `call` as an unknown inner
202
+ // field; without the recursion this slips through). We only recurse
203
+ // for `kind === "collect"` — other kinds with a `step`-named field
204
+ // (none today) would need their own audit.
205
+ if (step.kind === "collect" &&
206
+ step.step !== null &&
207
+ typeof step.step === "object" &&
208
+ !Array.isArray(step.step)) {
209
+ const outerStepId = typeof step.id === "string" ? step.id : null;
210
+ validateStepObject(step.step, i, outerStepId, errors);
211
+ }
212
+ }
213
+ return errors;
214
+ }
215
+ /**
216
+ * Validate a single step object's top-level keys against the allowlist and
217
+ * push any errors found onto `errors`. Used for both the top-level
218
+ * `steps[]` walk and the recursive `collect.step` walk.
219
+ *
220
+ * When `parentStepId` is set, the step being validated is the inner step
221
+ * of a `collect`. Errors carry the outer-step context so the rendered
222
+ * diagnostic can point operators at the right slot in the TOML.
223
+ */
224
+ function validateStepObject(step, stepIndex, parentStepId, errors) {
225
+ const stepId = typeof step.id === "string" ? step.id : null;
226
+ for (const key of Object.keys(step)) {
227
+ const value = step[key];
228
+ // Codex finding 1 (PR #762, 2026-05-15): self-id misnesting must be
229
+ // checked BEFORE the allowlist skip. When the step's `id` happens to
230
+ // match an allowlisted field name (e.g. `id = "query"`,
231
+ // `id = "request"`, `id = "input"`, `id = "output"`), TOML's
232
+ // `[steps.<id>.<sub-field>]` misnest produces a sub-table on the step
233
+ // keyed by the id — the same shape the validator was meant to catch.
234
+ // The allowlist would otherwise skip it as "expected per-kind field".
235
+ // Heuristic: when `step[step.id]` is a non-array table, this is
236
+ // (effectively always) the misnest pattern. Scalars are fine (the
237
+ // user really did mean to set the scalar field).
238
+ const isSelfIdMisnest = stepId !== null &&
239
+ key === stepId &&
240
+ value !== null &&
241
+ typeof value === "object" &&
242
+ !Array.isArray(value);
243
+ if (!isSelfIdMisnest && ALLOWLISTED_FIELDS.has(key))
244
+ continue;
245
+ // Two failure modes are common enough to call out specifically in
246
+ // the hint:
247
+ //
248
+ // 1) `[steps.<id>.<field>]` under `[[steps]]` — TOML places the
249
+ // sub-table under `steps[N][<id>]`. We detect this when the
250
+ // unknown field name equals the step's own id (including the
251
+ // self-id-allowlist-collision case above). We use the first
252
+ // sub-key of the offending value (e.g. `request`) to build a
253
+ // concrete corrected-form example so the user sees exactly what
254
+ // to rewrite, not just an abstract `<field>`.
255
+ //
256
+ // 2) Any other unknown top-level field — covered by the generic hint.
257
+ let hint;
258
+ if (stepId !== null && key === stepId) {
259
+ const subKey = value && typeof value === "object" && !Array.isArray(value)
260
+ ? Object.keys(value)[0]
261
+ : null;
262
+ const exampleSub = subKey ?? "request";
263
+ hint =
264
+ `This is usually caused by writing [steps.${stepId}.${exampleSub}] instead of [steps.${exampleSub}]. ` +
265
+ `TOML can't address an array element by id — use [steps.${exampleSub}] (refers to the most recent step).`;
266
+ }
267
+ else {
268
+ hint =
269
+ `\`${key}\` is not a recognized step field. ` +
270
+ `If you meant to write a nested config block on this step, use [steps.${key}] (which refers to the most recent step) instead of [steps.<id>.${key}].`;
271
+ }
272
+ errors.push({
273
+ stepIndex,
274
+ stepId,
275
+ field: key,
276
+ hint,
277
+ parentStepId,
278
+ });
279
+ }
280
+ }
281
+ /**
282
+ * Render a multi-line diagnostic for a list of errors. Designed for the
283
+ * shape called out in the issue:
284
+ *
285
+ * Error in workflows/refresh.toml:
286
+ * steps[0] (id="refresh-each") has unknown field "refresh-each".
287
+ * This is usually caused by writing [steps.refresh-each.request] instead of [steps.request].
288
+ * TOML can't address an array element by id — use [steps.request] (refers to the most recent step).
289
+ *
290
+ * @param filePath The TOML file path (or display name) to include in the
291
+ * header.
292
+ * @param errors The error list from `validateWorkflowToml`.
293
+ * @returns A multi-line string ready to print to stderr.
294
+ */
295
+ export function formatWorkflowTomlErrors(filePath, errors) {
296
+ if (errors.length === 0)
297
+ return "";
298
+ const lines = [`Error in ${filePath}:`];
299
+ for (const err of errors) {
300
+ if (err.field === "__steps_shape__") {
301
+ lines.push(` ${err.hint}`);
302
+ continue;
303
+ }
304
+ if (err.field === "__step_shape__") {
305
+ lines.push(` steps[${err.stepIndex}] is malformed: ${err.hint}`);
306
+ continue;
307
+ }
308
+ // For errors inside a `collect` step's nested inner step (codex review,
309
+ // 2026-05-15), use a `steps[N].step` slot prefix so operators see that
310
+ // the offending field is on the inner step, not the outer collect.
311
+ // The outer step's id (if any) is also included in the prefix so the
312
+ // diagnostic can be cross-referenced against the parent's TOML header.
313
+ const isInnerStep = err.parentStepId !== undefined;
314
+ const slot = isInnerStep
315
+ ? `steps[${err.stepIndex}].step`
316
+ : `steps[${err.stepIndex}]`;
317
+ const idPart = err.stepId ? ` (id="${err.stepId}")` : "";
318
+ const parentPart = isInnerStep && err.parentStepId
319
+ ? ` (inside collect step id="${err.parentStepId}")`
320
+ : isInnerStep
321
+ ? ` (inside collect step)`
322
+ : "";
323
+ lines.push(` ${slot}${idPart}${parentPart} has unknown field "${err.field}".`);
324
+ lines.push(` ${err.hint}`);
325
+ }
326
+ return lines.join("\n");
327
+ }
328
+ //# sourceMappingURL=workflow-toml-validator.js.map