Skip to content

Feat/trigger executor command#494

Merged
toiroakr merged 9 commits intomainfrom
feat/trigger-executor-command
Feb 2, 2026
Merged

Feat/trigger executor command#494
toiroakr merged 9 commits intomainfrom
feat/trigger-executor-command

Conversation

@toiroakr
Copy link
Copy Markdown
Contributor

@toiroakr toiroakr commented Jan 28, 2026

This pull request introduces a new set of CLI commands for managing executors and their jobs, along with supporting code and documentation. It also adds a new test executor and updates integration tests to reflect these changes. The most important changes are grouped below.


New Executor CLI Commands:

  • Added a new executor CLI command with trigger and jobs subcommands for managing executors and their jobs, including options for payloads, waiting for job completion, and viewing logs (packages/sdk/src/cli/executor/index.ts, packages/sdk/src/cli/executor/trigger.ts, packages/sdk/src/cli/executor/status.ts, packages/sdk/src/cli/executor/transform.ts, packages/sdk/src/cli/executor/jobs.ts) [1] [2] [3] [4].
  • Registered the new executor command in the main CLI entrypoint (packages/sdk/src/cli/index.ts) [1] [2].

Documentation Updates:

  • Added a new CLI reference page for executor commands, including detailed usage examples and explanations of options (packages/sdk/docs/cli/executor.md).
  • Updated the main CLI reference to include the new executor commands section (packages/sdk/docs/cli-reference.md).

SDK Exports:

  • Exported new executor-related functions and types from the CLI SDK library (packages/sdk/src/cli/lib.ts).

Testing and Example Executors:

  • Added a new example executor testWebhook.ts that demonstrates an incoming webhook trigger (example/executors/testWebhook.ts).
  • Updated E2E and integration tests to account for the new executor and its generated files (example/e2e/executor.test.ts, example/tests/apply_command.test.ts) [1] [2].

Workflow Execution Improvements:

  • Improved workflow execution polling by using a helper to determine terminal statuses, including PENDING_RESUME (packages/sdk/src/cli/workflow/executions.ts) [1] [2].
CleanShot 2026-01-28 at 16 40 57 CleanShot 2026-01-28 at 16 47 02

@toiroakr toiroakr requested a review from remiposo as a code owner January 28, 2026 05:17
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Jan 28, 2026

⚠️ No Changeset found

Latest commit: 4f69211

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Jan 28, 2026

Open in StackBlitz

npm i https://pkg.pr.new/tailor-platform/sdk/@tailor-platform/create-sdk@494

commit: 4f69211

@github-actions

This comment has been minimized.

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

View issue and 4 additional flags in Devin Review.

Open in Devin Review

Comment thread packages/sdk/src/cli/executor/jobs.ts Outdated
@github-actions

This comment has been minimized.

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 new potential issue.

View issue and 6 additional flags in Devin Review.

Open in Devin Review

let payload: JsonObject | undefined;
if (args.payload) {
try {
payload = JSON.parse(args.payload);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 JSON.parse result not validated to be an object before assignment to JsonObject type

When parsing the payload argument in trigger.ts, JSON.parse(args.payload) is directly assigned to a variable typed as JsonObject. However, JSON.parse can return any valid JSON value (string, number, boolean, null, or array), not just objects.

Click to expand

Issue

At line 101, the code parses user input:

let payload: JsonObject | undefined;
if (args.payload) {
  try {
    payload = JSON.parse(args.payload);
  } catch { ... }
}

If a user provides a valid JSON string that isn't an object (e.g., "hello", 123, true, null, or [1,2,3]), the JSON.parse will succeed but the result won't be a JsonObject. This causes a type mismatch at runtime.

Impact

  • User passes --payload '123' → parses to number 123, not an object
  • User passes --payload '[1,2,3]' → parses to array, not an object
  • The API call at packages/sdk/src/cli/executor/trigger.ts:40-44 may fail or behave unexpectedly when receiving a non-object payload

Expected Behavior

The code should validate that the parsed JSON is actually an object before assigning it to payload.

Recommendation: Add validation after JSON.parse to ensure the result is an object:

const parsed = JSON.parse(args.payload);
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
  throw new Error('Payload must be a JSON object, not an array, primitive, or null.');
}
payload = parsed;
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@toiroakr toiroakr force-pushed the feat/trigger-executor-command branch from 4e45e41 to 72b5111 Compare January 28, 2026 05:52
@github-actions

This comment has been minimized.

@toiroakr toiroakr force-pushed the feat/trigger-executor-command branch from 72b5111 to 7277049 Compare January 28, 2026 05:55
@github-actions

This comment has been minimized.

@toiroakr toiroakr force-pushed the feat/trigger-executor-command branch from 7277049 to 7974095 Compare January 28, 2026 06:05
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

Comment thread packages/sdk/docs/cli/executor.md Outdated
Comment thread packages/sdk/src/cli/executor/trigger.ts
Comment thread packages/sdk/src/cli/executor/jobs.ts Outdated
@github-actions

This comment has been minimized.

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 new potential issue.

View issue and 18 additional flags in Devin Review.

Open in Devin Review

const jobs = await listExecutorJobs({
executorName: args.executorName as string,
status: args.status,
limit: args.limit ? Number.parseInt(args.limit, 10) : undefined,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Missing validation for --limit argument allows NaN or negative values to be passed to API

The --limit argument in the executor jobs command is parsed using Number.parseInt(args.limit, 10) without validation.

Click to expand

Problem

When a user provides an invalid value like --limit abc or --limit -5, the code passes NaN or a negative number directly to the API:

limit: args.limit ? Number.parseInt(args.limit, 10) : undefined,
  • Number.parseInt("abc", 10) returns NaN
  • Number.parseInt("-5", 10) returns -5

Expected Behavior

The limit should be validated as a positive integer before being passed to the API, similar to how packages/sdk/src/cli/workspace/list.ts:14 handles it:

const limitSchema = z.coerce.number().int().positive().optional();

Impact

Users will receive confusing API errors instead of clear validation messages when providing invalid limit values.

Recommendation: Add validation for the limit argument using a zod schema similar to the workspace list command: const limitSchema = z.coerce.number().int().positive().optional(); and validate before calling listExecutorJobs.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@toiroakr toiroakr force-pushed the feat/trigger-executor-command branch 2 times, most recently from d9117b3 to 3f0430a Compare January 30, 2026 01:21
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 new potential issue.

View issue and 26 additional flags in Devin Review.

Open in Devin Review

Comment on lines 343 to 347
configPath: args.config,
dryRun: args["dry-run"],
yes: args.yes,
noSchemaCheck: args["schema-check"] === false,
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 --no-schema-check flag is ignored because apply command reads a non-existent schema-check arg

The CLI defines the boolean option as "no-schema-check", but when wiring CLI args into apply(), it sets noSchemaCheck using args["schema-check"] === false.

Actual behavior:

  • Passing --no-schema-check sets args["no-schema-check"] === true, but this is never read.
  • args["schema-check"] is undefined (arg not declared), so args["schema-check"] === false is always false.
  • Result: noSchemaCheck is always false, so schema checks are never skipped even when the user requests it.

Expected behavior:

  • noSchemaCheck should reflect args["no-schema-check"] (or the equivalent negated --schema-check style arg if that existed).

Impact:

  • Documented CLI behavior is broken; users cannot bypass schema checks (which can block apply in situations where skipping is intended, e.g., CI/debugging).
Relevant code
"no-schema-check": { type: "boolean", ... }
...
noSchemaCheck: args["schema-check"] === false,

(Refers to lines 334-347)

Recommendation: Change the mapping to noSchemaCheck: Boolean(args["no-schema-check"]) (or rename the option to --schema-check/--no-schema-check consistently and read the correct key). Add/adjust a unit test to ensure the flag propagates into apply().

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@toiroakr toiroakr force-pushed the feat/trigger-executor-command branch from 3f0430a to 9c5a0be Compare January 30, 2026 01:44
@github-actions

This comment has been minimized.

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 new potential issue.

View issue and 26 additional flags in Devin Review.

Open in Devin Review

Comment thread packages/sdk/src/cli/executor/list.ts Outdated
logger.out(formatTableWithHeaders(headers, rows));

// Show hint if there are webhook executors
const hasWebhook = executors.some((e) => e.triggerType === "webhook");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Webhook hint detection uses inconsistent trigger type string comparison

The webhook hint in list.ts checks for triggerType === "webhook", but this string is only produced when the executor has a valid triggerConfig with case: "incomingWebhook". When triggerConfig is undefined or missing, formatTriggerTypeForList falls back to executorTriggerTypeToString() which returns "incomingWebhook" instead of "webhook".

Click to expand

Expected vs Actual

Expected: The hint "To see webhook URLs, run: tailor-sdk executor webhook list" should appear whenever there are executors with INCOMING_WEBHOOK trigger type.

Actual: The hint will not appear if an incoming webhook executor has missing/undefined triggerConfig, because:

  • formatTriggerTypeForList (transform.ts:131-147) returns "webhook" only when config.case === "incomingWebhook"
  • Otherwise it falls back to executorTriggerTypeToString() (status.ts:163-164) which returns "incomingWebhook"
  • The check e.triggerType === "webhook" in list.ts:74 would then fail

Impact

This is a minor UX issue - users may not see the helpful hint about viewing webhook URLs in edge cases where the executor has an INCOMING_WEBHOOK trigger type but missing config.

Recommendation: Change the comparison to also check for "incomingWebhook": const hasWebhook = executors.some((e) => e.triggerType === "webhook" || e.triggerType === "incomingWebhook" || e.triggerType.startsWith("webhook"));

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

toiroakr and others added 4 commits January 30, 2026 15:36
- Rename --watch to --wait for consistency with workflow commands
- Add -W alias for --wait, -i alias for --interval
- Add --logs/-l option to display function/workflow execution logs
- Remove type cast for jobId (proto now includes the field)
- Replace printData with logger.out
- Replace table import with formatKeyValueTable

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add JSDoc comments with @param and @returns to status/transform functions
- Fix unused variable names in schema.test.ts (field -> _field)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add PENDING_RESUME status to terminal state checks in watchExecutorJob
and waitForCompletion functions to prevent infinite loops when a
workflow enters the PENDING_RESUME state.

- Use isWorkflowExecutionTerminalStatus helper in workflow/executions.ts
- Add PENDING_RESUME handling with appropriate warning message in executor/jobs.ts
- Remove unused exports to fix knip errors

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
toiroakr and others added 4 commits January 30, 2026 15:36
- Add executor command documentation (trigger, jobs)
- Update CLI reference to include executor commands section
- Use waitForExecution for workflow targets to show real-time progress
  (status changes and running job names, same as workflow start --wait)
- Fix log/result indentation in output for better readability
- Change spinner text from "Polling..." to "Waiting for workflow to complete..."

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add --data (-d) and --header (-H) options (curl-compatible)
- Headers can be specified multiple times: -H "Key: Value"
- Internally combines into { body: {...}, headers: {...} } structure
- Update documentation with new options and examples

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add trigger type validation for executor trigger command:
  - EVENT trigger type cannot be triggered manually
  - SCHEDULE trigger type does not accept --data/--header options
- Add --limit option for executor jobs command (default: 50, max: 1000)
- Remove fetchAll to avoid fetching all jobs at once
- Update documentation with trigger type restrictions

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Align executor CLI commands with the main branch's politty migration.
Updates index.ts, jobs.ts, and trigger.ts to use Zod schemas and
politty's defineCommand API.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@toiroakr toiroakr force-pushed the feat/trigger-executor-command branch from 9c5a0be to 58482d5 Compare February 1, 2026 08:36
@github-actions

This comment has been minimized.

Use humanizeRelativeTime from format.ts instead of duplicating
formatDistanceToNowStrict logic in logger.ts.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Feb 1, 2026

Code Metrics Report (packages/sdk)

main (502050f) #494 (4c7a273) +/-
Coverage 49.9% 47.8% -2.1%
Code to Test Ratio 1:0.3 1:0.3 -0.1
Details
  |                    | main (502050f) | #494 (4c7a273) |  +/-  |
  |--------------------|----------------|----------------|-------|
- | Coverage           |          49.9% |          47.8% | -2.1% |
  |   Files            |            198 |            204 |    +6 |
  |   Lines            |           6563 |           6852 |  +289 |
+ |   Covered          |           3278 |           3281 |    +3 |
- | Code to Test Ratio |          1:0.3 |          1:0.3 |  -0.1 |
  |   Code             |          36225 |          37144 |  +919 |
  |   Test             |          13606 |          13606 |     0 |

Code coverage of files in pull request scope (16.0% → 8.1%)

Files Coverage +/- Status
packages/sdk/src/cli/executor/index.ts 100.0% +100.0% added
packages/sdk/src/cli/executor/jobs.ts 0.6% +0.6% added
packages/sdk/src/cli/executor/status.ts 0.0% 0.0% added
packages/sdk/src/cli/executor/transform.ts 0.0% 0.0% added
packages/sdk/src/cli/executor/trigger.ts 1.2% +1.2% added
packages/sdk/src/cli/index.ts 100.0% 0.0% modified
packages/sdk/src/cli/utils/logger.ts 53.7% +2.3% modified
packages/sdk/src/cli/workflow/executions.ts 0.9% 0.0% modified
packages/sdk/src/cli/workflow/start.ts 1.2% 0.0% modified
packages/sdk/src/cli/workflow/status.ts 0.0% 0.0% added

SDK Configure Bundle Size

main (502050f) #494 (4c7a273) +/-
configure-index-size 7.03KB 7.03KB 0KB
dependency-chunks-size 22.11KB 22.11KB 0KB
total-bundle-size 29.14KB 29.14KB 0KB

Runtime Performance

main (502050f) #494 (4c7a273) +/-
Generate Median 2,461ms 2,487ms 26ms
Generate Max 2,898ms 2,542ms -356ms
Apply Build Median 2,677ms 2,685ms 8ms
Apply Build Max 2,709ms 2,747ms 38ms

Type Performance (instantiations)

main (502050f) #494 (4c7a273) +/-
tailordb-basic 135,435 135,435 0
tailordb-optional 5,230 5,230 0
tailordb-relation 5,103 5,103 0
tailordb-validate 3,994 3,994 0
tailordb-hooks 7,147 7,147 0
tailordb-object 12,934 12,934 0
tailordb-enum 3,862 3,862 0
resolver-basic 13,789 13,789 0
resolver-nested 30,536 30,536 0
resolver-array 22,580 22,580 0
executor-schedule 12,347 12,347 0
executor-webhook 8,909 8,909 0
executor-record 13,567 13,567 0
executor-resolver 16,077 16,077 0
executor-operation-function 8,887 8,887 0
executor-operation-gql 8,890 8,890 0
executor-operation-webhook 8,903 8,903 0
executor-operation-workflow 10,176 10,176 0

Reported by octocov

Copy link
Copy Markdown
Contributor

@remiposo remiposo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@toiroakr toiroakr merged commit 9000e4a into main Feb 2, 2026
19 checks passed
@toiroakr toiroakr deleted the feat/trigger-executor-command branch February 2, 2026 01:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants