@doist/automations-cli 1.20.2 → 1.21.0
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/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
collectSkillStatus,
|
|
8
8
|
getInstaller,
|
|
9
9
|
updateAllInstalledSkills
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-ZWFZ2DD3.js";
|
|
11
11
|
|
|
12
12
|
// ../../node_modules/ajv/dist/compile/codegen/code.js
|
|
13
13
|
var require_code = __commonJS({
|
|
@@ -6899,7 +6899,7 @@ import { fileURLToPath } from "node:url";
|
|
|
6899
6899
|
// package.json
|
|
6900
6900
|
var package_default = {
|
|
6901
6901
|
name: "@doist/automations-cli",
|
|
6902
|
-
version: "1.
|
|
6902
|
+
version: "1.21.0",
|
|
6903
6903
|
description: "Command-line client for Todoist Automations",
|
|
6904
6904
|
type: "module",
|
|
6905
6905
|
bin: {
|
|
@@ -6945,7 +6945,7 @@ var package_default = {
|
|
|
6945
6945
|
dependencies: {
|
|
6946
6946
|
"@doist/cli-core": "1.7.0",
|
|
6947
6947
|
"@napi-rs/keyring": "2.1.0",
|
|
6948
|
-
ai: "7.0.
|
|
6948
|
+
ai: "7.0.137",
|
|
6949
6949
|
commander: "15.0.0",
|
|
6950
6950
|
oauth4webapi: "3.8.8",
|
|
6951
6951
|
open: "11.0.4"
|
|
@@ -6953,7 +6953,7 @@ var package_default = {
|
|
|
6953
6953
|
devDependencies: {
|
|
6954
6954
|
"@doist/automations-core": "*",
|
|
6955
6955
|
"@doist/automations-sdk": "*",
|
|
6956
|
-
"@types/node": "24.19.
|
|
6956
|
+
"@types/node": "24.19.2",
|
|
6957
6957
|
"conventional-changelog-conventionalcommits": "9.3.1",
|
|
6958
6958
|
esbuild: "0.28.2",
|
|
6959
6959
|
"semantic-release": "25.0.9",
|
|
@@ -28149,6 +28149,7 @@ var cronScheduleSchema = (() => {
|
|
|
28149
28149
|
});
|
|
28150
28150
|
})();
|
|
28151
28151
|
var scheduleValueSchema = external_exports.union([intervalScheduleSchema, cronScheduleSchema]).meta({ description: "The schedule definition for the trigger." });
|
|
28152
|
+
var TRIGGER_TYPES = ["schedule", "webhook", "api"];
|
|
28152
28153
|
var scheduleTriggerSchema = external_exports.object({
|
|
28153
28154
|
type: external_exports.literal("schedule"),
|
|
28154
28155
|
value: scheduleValueSchema,
|
|
@@ -28986,7 +28987,7 @@ var ImportLocalOAuthConnectionBodySchema = external_exports.object({
|
|
|
28986
28987
|
* matched to it.
|
|
28987
28988
|
*/
|
|
28988
28989
|
repairConnectionId: external_exports.uuid().optional()
|
|
28989
|
-
});
|
|
28990
|
+
}).meta({ id: "ImportLocalOAuthConnection" });
|
|
28990
28991
|
var LocalOAuthSetupSchema = external_exports.object({
|
|
28991
28992
|
/** RFC 7591 registration endpoint; null when the server offers none. */
|
|
28992
28993
|
registrationEndpoint: external_exports.string().url().nullable(),
|
|
@@ -29138,20 +29139,20 @@ var updateAutomationSchema = external_exports.object({
|
|
|
29138
29139
|
manifest: manifestSchema.optional()
|
|
29139
29140
|
}).refine((data) => Object.keys(data).length > 0, {
|
|
29140
29141
|
message: "At least one field must be provided"
|
|
29141
|
-
});
|
|
29142
|
+
}).meta({ id: "UpdateAutomation" });
|
|
29142
29143
|
var updateAutomationMetadataSchema = external_exports.object({
|
|
29143
29144
|
name: external_exports.string().min(1),
|
|
29144
29145
|
description: external_exports.string()
|
|
29145
|
-
});
|
|
29146
|
+
}).meta({ id: "UpdateAutomationMetadata" });
|
|
29146
29147
|
var updateAutomationScheduleSchema = external_exports.object({
|
|
29147
29148
|
value: scheduleValueSchema
|
|
29148
|
-
});
|
|
29149
|
+
}).meta({ id: "UpdateAutomationSchedule" });
|
|
29149
29150
|
var updateAutomationVisibilitySchema = external_exports.object({
|
|
29150
29151
|
visibility: external_exports.enum(AUTOMATION_VISIBILITIES)
|
|
29151
|
-
});
|
|
29152
|
+
}).meta({ id: "UpdateAutomationVisibility" });
|
|
29152
29153
|
var moveAutomationSchema = external_exports.object({
|
|
29153
29154
|
visibility: external_exports.enum(AUTOMATION_VISIBILITIES).default("workspace")
|
|
29154
|
-
});
|
|
29155
|
+
}).meta({ id: "MoveAutomation" });
|
|
29155
29156
|
|
|
29156
29157
|
// ../../packages/core/dist/esm/schemas/automation-connection.schema.js
|
|
29157
29158
|
var AutomationConnectionMappingSchema = external_exports.object({
|
|
@@ -29168,7 +29169,7 @@ var UpsertAutomationConnectionSchema = external_exports.object({
|
|
|
29168
29169
|
* the service infers the role from `connection.capabilities[0]`.
|
|
29169
29170
|
*/
|
|
29170
29171
|
connectionType: external_exports.enum(CONNECTION_TYPES).optional()
|
|
29171
|
-
}).strict();
|
|
29172
|
+
}).strict().meta({ id: "UpsertAutomationConnection" });
|
|
29172
29173
|
var SetAutomationConnectionsSchema = external_exports.object({
|
|
29173
29174
|
mappings: external_exports.array(AutomationConnectionMappingSchema).nonempty("mappings cannot be empty")
|
|
29174
29175
|
}).strict();
|
|
@@ -29326,8 +29327,29 @@ var automationDraftListResponseSchema = external_exports.object({
|
|
|
29326
29327
|
var finalizeAutomationDraftResponseSchema = external_exports.object({
|
|
29327
29328
|
automation: automationSchema
|
|
29328
29329
|
});
|
|
29330
|
+
var draftTestTriggerSelectorSchema = external_exports.union([
|
|
29331
|
+
external_exports.object({ index: external_exports.int().min(0) }),
|
|
29332
|
+
external_exports.object({ event: external_exports.string().min(1) })
|
|
29333
|
+
]);
|
|
29334
|
+
var testAutomationDraftRequestSchema = external_exports.object({
|
|
29335
|
+
trigger: draftTestTriggerSelectorSchema.optional(),
|
|
29336
|
+
payload: external_exports.unknown().optional(),
|
|
29337
|
+
metadata: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
|
|
29338
|
+
}).meta({ id: "TestAutomationDraftRequest" });
|
|
29339
|
+
var draftTestTriggerSchema = external_exports.object({
|
|
29340
|
+
index: external_exports.int().min(0),
|
|
29341
|
+
count: external_exports.int().min(1),
|
|
29342
|
+
type: external_exports.enum(TRIGGER_TYPES),
|
|
29343
|
+
event: external_exports.string().optional(),
|
|
29344
|
+
inputSource: external_exports.enum(["schedule", "sample-event", "supplied", "empty"])
|
|
29345
|
+
});
|
|
29329
29346
|
var testAutomationDraftResponseSchema = external_exports.object({
|
|
29330
|
-
success: external_exports.literal(true)
|
|
29347
|
+
success: external_exports.literal(true),
|
|
29348
|
+
draftId: external_exports.string(),
|
|
29349
|
+
testRunId: external_exports.string(),
|
|
29350
|
+
status: external_exports.enum(AUTOMATION_RUN_STATUSES),
|
|
29351
|
+
connectorCalls: external_exports.literal("mocked"),
|
|
29352
|
+
trigger: draftTestTriggerSchema
|
|
29331
29353
|
});
|
|
29332
29354
|
var AUTOMATION_OPEN_DRAFT_CONFLICT_CODE = "automation_open_draft_conflict";
|
|
29333
29355
|
var AutomationOpenDraftConflictSchema = external_exports.object({
|
|
@@ -29340,13 +29362,25 @@ var AutomationDraftNotReadySchema = external_exports.object({
|
|
|
29340
29362
|
code: external_exports.literal(AUTOMATION_DRAFT_NOT_READY_CODE),
|
|
29341
29363
|
message: external_exports.string()
|
|
29342
29364
|
});
|
|
29365
|
+
var DRAFT_TEST_REQUEST_ERROR_CODES = [
|
|
29366
|
+
"draft_test_not_ready",
|
|
29367
|
+
"draft_test_trigger_not_found",
|
|
29368
|
+
"draft_test_payload_required",
|
|
29369
|
+
"draft_test_payload_filtered",
|
|
29370
|
+
"draft_test_payload_invalid",
|
|
29371
|
+
"draft_test_payload_unsupported"
|
|
29372
|
+
];
|
|
29373
|
+
var DraftTestRequestErrorSchema = external_exports.object({
|
|
29374
|
+
code: external_exports.enum(DRAFT_TEST_REQUEST_ERROR_CODES),
|
|
29375
|
+
message: external_exports.string()
|
|
29376
|
+
});
|
|
29343
29377
|
|
|
29344
29378
|
// ../../packages/core/dist/esm/schemas/automation-draft-connection.schema.js
|
|
29345
29379
|
var CreateAutomationDraftConnectionSchema = external_exports.object({
|
|
29346
29380
|
connectorId: external_exports.string().trim().min(1, "connectorId is required"),
|
|
29347
29381
|
connectionType: external_exports.enum(CONNECTION_TYPES),
|
|
29348
29382
|
connectionId: uuidv7Schema.min(1, "connectionId is required")
|
|
29349
|
-
}).strict();
|
|
29383
|
+
}).strict().meta({ id: "CreateAutomationDraftConnection" });
|
|
29350
29384
|
var AutomationDraftConnectionSchema = external_exports.object({
|
|
29351
29385
|
draftId: external_exports.string(),
|
|
29352
29386
|
connectorId: external_exports.string(),
|
|
@@ -29515,13 +29549,13 @@ var getChatConversationsQuerySchema = external_exports.object({
|
|
|
29515
29549
|
});
|
|
29516
29550
|
var createChatConversationSchema = external_exports.object({
|
|
29517
29551
|
title: external_exports.string().nullable().optional()
|
|
29518
|
-
});
|
|
29552
|
+
}).meta({ id: "CreateChatConversation" });
|
|
29519
29553
|
var updateChatConversationSchema = external_exports.object({
|
|
29520
29554
|
title: external_exports.string().nullable().optional(),
|
|
29521
29555
|
isArchived: external_exports.boolean().optional()
|
|
29522
29556
|
}).refine((value) => value.title !== void 0 || value.isArchived !== void 0, {
|
|
29523
29557
|
message: "At least one field must be provided"
|
|
29524
|
-
});
|
|
29558
|
+
}).meta({ id: "UpdateChatConversation" });
|
|
29525
29559
|
|
|
29526
29560
|
// ../../packages/core/dist/esm/schemas/automation-preview-artifact.schema.js
|
|
29527
29561
|
var automationPreviewSources = ["synthetic", "run"];
|
|
@@ -29651,10 +29685,23 @@ var automationTestRunStepStatusSchema = external_exports.object({
|
|
|
29651
29685
|
stepId: external_exports.string().min(1),
|
|
29652
29686
|
status: external_exports.enum(AUTOMATION_RUN_STATUSES)
|
|
29653
29687
|
});
|
|
29688
|
+
var automationTestRunFailedStepSchema = external_exports.object({
|
|
29689
|
+
stepId: external_exports.string().min(1),
|
|
29690
|
+
description: external_exports.string().optional(),
|
|
29691
|
+
error: external_exports.string().optional()
|
|
29692
|
+
});
|
|
29654
29693
|
var automationTestRunProgressSchema = external_exports.object({
|
|
29655
29694
|
draftId: external_exports.string().min(1),
|
|
29656
29695
|
status: external_exports.enum(AUTOMATION_RUN_STATUSES),
|
|
29657
|
-
steps: external_exports.array(automationTestRunStepStatusSchema).default([])
|
|
29696
|
+
steps: external_exports.array(automationTestRunStepStatusSchema).default([]),
|
|
29697
|
+
// Optional so results stored before these fields existed still parse.
|
|
29698
|
+
runId: external_exports.string().min(1).optional(),
|
|
29699
|
+
failedStep: automationTestRunFailedStepSchema.optional(),
|
|
29700
|
+
/** Why a failed or skipped run stopped. */
|
|
29701
|
+
error: external_exports.string().optional(),
|
|
29702
|
+
result: AutomationRunResultSchema.nullable().optional(),
|
|
29703
|
+
/** A test run simulates every connector call, reads included. */
|
|
29704
|
+
connectorCalls: external_exports.literal("mocked").optional()
|
|
29658
29705
|
});
|
|
29659
29706
|
var automationTestRunPreviewTriggerSchema = external_exports.union([
|
|
29660
29707
|
external_exports.object({
|
|
@@ -29947,6 +29994,47 @@ var cohortMatrixResponseSchema = external_exports.object({
|
|
|
29947
29994
|
rows: external_exports.array(cohortMatrixRowSchema)
|
|
29948
29995
|
});
|
|
29949
29996
|
|
|
29997
|
+
// ../../packages/core/dist/esm/schemas/draft-test-run.schema.js
|
|
29998
|
+
var DraftTestRunFailedStepSchema = external_exports.object({
|
|
29999
|
+
stepId: external_exports.string(),
|
|
30000
|
+
description: external_exports.string(),
|
|
30001
|
+
error: external_exports.string().nullable()
|
|
30002
|
+
});
|
|
30003
|
+
var draftTestRunDetailDtoBaseShape = {
|
|
30004
|
+
id: external_exports.string(),
|
|
30005
|
+
draftId: external_exports.string(),
|
|
30006
|
+
// The automation an edit draft belongs to; null for a draft of a new automation.
|
|
30007
|
+
automationId: external_exports.string().nullable(),
|
|
30008
|
+
mode: external_exports.literal("test"),
|
|
30009
|
+
// A test run simulates every connector call, reads included, with a model.
|
|
30010
|
+
connectorCalls: external_exports.literal("mocked"),
|
|
30011
|
+
createdAt: external_exports.string(),
|
|
30012
|
+
updatedAt: external_exports.string(),
|
|
30013
|
+
result: AutomationRunResultSchema.nullable(),
|
|
30014
|
+
temporalUrl: external_exports.string().nullish(),
|
|
30015
|
+
steps: external_exports.array(AutomationRunStepDtoSchema),
|
|
30016
|
+
failedStep: DraftTestRunFailedStepSchema.nullable()
|
|
30017
|
+
};
|
|
30018
|
+
var DraftTestRunDetailDtoSchema = external_exports.discriminatedUnion("status", [
|
|
30019
|
+
external_exports.object({ ...draftTestRunDetailDtoBaseShape, status: external_exports.literal("pending") }),
|
|
30020
|
+
external_exports.object({ ...draftTestRunDetailDtoBaseShape, status: external_exports.literal("running") }),
|
|
30021
|
+
external_exports.object({ ...draftTestRunDetailDtoBaseShape, status: external_exports.literal("completed") }),
|
|
30022
|
+
external_exports.object({ ...draftTestRunDetailDtoBaseShape, status: external_exports.literal("cancelled") }),
|
|
30023
|
+
external_exports.object({ ...draftTestRunDetailDtoBaseShape, status: external_exports.literal("data-expired") }),
|
|
30024
|
+
external_exports.object({
|
|
30025
|
+
...draftTestRunDetailDtoBaseShape,
|
|
30026
|
+
status: external_exports.literal("failed"),
|
|
30027
|
+
failureReason: external_exports.string().nullish(),
|
|
30028
|
+
failureCategory: external_exports.enum(FAILURE_CATEGORIES).nullish().catch(null)
|
|
30029
|
+
}),
|
|
30030
|
+
external_exports.object({
|
|
30031
|
+
...draftTestRunDetailDtoBaseShape,
|
|
30032
|
+
status: external_exports.literal("skipped"),
|
|
30033
|
+
skipReason: external_exports.string().nullish(),
|
|
30034
|
+
skipCategory: external_exports.enum(SKIP_CATEGORIES).nullish()
|
|
30035
|
+
})
|
|
30036
|
+
]);
|
|
30037
|
+
|
|
29950
30038
|
// ../../packages/core/dist/esm/types/workspace.types.js
|
|
29951
30039
|
var WORKSPACE_PLANS = ["STARTER", "BUSINESS"];
|
|
29952
30040
|
var WORKSPACE_ROLES = ["ADMIN", "MEMBER", "GUEST"];
|
|
@@ -30139,7 +30227,7 @@ var NotificationResponseSchema = external_exports.object({
|
|
|
30139
30227
|
const isStatusResponse = data.status !== void 0 && data.action === void 0;
|
|
30140
30228
|
const isAnswer = data.action === "answer" && data.value !== void 0 && data.status === void 0;
|
|
30141
30229
|
return isStatusResponse || isAnswer;
|
|
30142
|
-
}, { message: 'Provide either { status } or { action: "answer", value }' });
|
|
30230
|
+
}, { message: 'Provide either { status } or { action: "answer", value }' }).meta({ id: "NotificationResponse" });
|
|
30143
30231
|
var NOTIFICATION_STATUSES = [
|
|
30144
30232
|
...INFO_NOTIFICATION_STATUSES,
|
|
30145
30233
|
...PROMPT_NOTIFICATION_STATUSES
|
|
@@ -30322,10 +30410,10 @@ var RegisterPushSubscriptionSchema = external_exports.object({
|
|
|
30322
30410
|
endpoint: external_exports.url().max(768),
|
|
30323
30411
|
keys: PushSubscriptionKeysSchema,
|
|
30324
30412
|
deviceName: external_exports.string().max(255).optional()
|
|
30325
|
-
});
|
|
30413
|
+
}).meta({ id: "RegisterPushSubscription" });
|
|
30326
30414
|
var UpdatePushSubscriptionSchema = external_exports.object({
|
|
30327
30415
|
deviceName: external_exports.string().max(255).nullable().optional()
|
|
30328
|
-
});
|
|
30416
|
+
}).meta({ id: "UpdatePushSubscription" });
|
|
30329
30417
|
var RemovePushSubscriptionByEndpointQuerySchema = external_exports.object({
|
|
30330
30418
|
endpoint: external_exports.url().max(768)
|
|
30331
30419
|
});
|
|
@@ -30359,7 +30447,7 @@ var createSubscriptionSchema = external_exports.object({
|
|
|
30359
30447
|
triggerEventId: external_exports.string().min(1, "Trigger event ID is required"),
|
|
30360
30448
|
outputSchema: external_exports.record(external_exports.string(), external_exports.unknown()),
|
|
30361
30449
|
inputSchema: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
|
|
30362
|
-
});
|
|
30450
|
+
}).meta({ id: "CreateSubscription" });
|
|
30363
30451
|
var subscriptionResponseSchema = external_exports.object({
|
|
30364
30452
|
id: external_exports.string(),
|
|
30365
30453
|
agentId: external_exports.string(),
|
|
@@ -30395,7 +30483,7 @@ var UserOnboardingStateSchema = external_exports.object({
|
|
|
30395
30483
|
});
|
|
30396
30484
|
var AcceptTermsSchema = external_exports.object({
|
|
30397
30485
|
version: external_exports.string().trim().min(1).max(64)
|
|
30398
|
-
});
|
|
30486
|
+
}).meta({ id: "AcceptTerms" });
|
|
30399
30487
|
var ConnectorIdSchema = external_exports.string().trim().min(1);
|
|
30400
30488
|
var InterestedConnectorIdsSchema = external_exports.array(ConnectorIdSchema).max(100);
|
|
30401
30489
|
var ConnectorPreferencesSchema = external_exports.object({
|
|
@@ -30442,7 +30530,7 @@ var UserPreferencesSchema = external_exports.object({
|
|
|
30442
30530
|
});
|
|
30443
30531
|
var CompleteOnboardingSchema = external_exports.object({
|
|
30444
30532
|
connectors: ConnectorPreferencesUpdateSchema.optional()
|
|
30445
|
-
}).default({});
|
|
30533
|
+
}).default({}).meta({ id: "CompleteOnboarding" });
|
|
30446
30534
|
var UpdateUserPreferencesSchema = external_exports.object({
|
|
30447
30535
|
connectors: ConnectorPreferencesUpdateSchema.optional(),
|
|
30448
30536
|
notifications: NotificationPreferencesUpdateSchema.optional(),
|
|
@@ -30461,7 +30549,7 @@ var UpdateUserPreferencesSchema = external_exports.object({
|
|
|
30461
30549
|
value.notifications?.usageBalance
|
|
30462
30550
|
];
|
|
30463
30551
|
return channelGroups.some((group) => group && ("email" in group && group.email !== void 0 || group.push !== void 0));
|
|
30464
|
-
}, { message: "At least one preference field must be provided" });
|
|
30552
|
+
}, { message: "At least one preference field must be provided" }).meta({ id: "UpdateUserPreferences" });
|
|
30465
30553
|
|
|
30466
30554
|
// ../../packages/core/dist/esm/schemas/webhook-events/automation-created.event.js
|
|
30467
30555
|
var AutomationCreatedDataSchema = external_exports.object({
|
|
@@ -30637,14 +30725,14 @@ var CreateWebhookEventSubscriptionRequestSchema = external_exports.object({
|
|
|
30637
30725
|
eventTypes: external_exports.array(external_exports.enum(WEBHOOK_EVENT_TYPES)).min(1),
|
|
30638
30726
|
subjectAutomationId: external_exports.string().optional(),
|
|
30639
30727
|
description: external_exports.string().max(WEBHOOK_EVENT_SUBSCRIPTION_DESCRIPTION_MAX_LENGTH).optional()
|
|
30640
|
-
}).superRefine(rejectAccountScopedWithSubject);
|
|
30728
|
+
}).superRefine(rejectAccountScopedWithSubject).meta({ id: "CreateWebhookEventSubscriptionRequest" });
|
|
30641
30729
|
var UpdateWebhookEventSubscriptionRequestSchema = external_exports.object({
|
|
30642
30730
|
url: WebhookEndpointUrlSchema,
|
|
30643
30731
|
eventTypes: external_exports.array(external_exports.enum(WEBHOOK_EVENT_TYPES)).min(1),
|
|
30644
30732
|
status: external_exports.enum(WEBHOOK_EVENT_SUBSCRIPTION_STATUSES),
|
|
30645
30733
|
description: external_exports.string().max(WEBHOOK_EVENT_SUBSCRIPTION_DESCRIPTION_MAX_LENGTH).nullable(),
|
|
30646
30734
|
subjectAutomationId: external_exports.string().nullable()
|
|
30647
|
-
}).partial().superRefine(rejectAccountScopedWithSubject);
|
|
30735
|
+
}).partial().superRefine(rejectAccountScopedWithSubject).meta({ id: "UpdateWebhookEventSubscriptionRequest" });
|
|
30648
30736
|
var WebhookEventDeliveryDtoSchema = external_exports.object({
|
|
30649
30737
|
id: external_exports.string(),
|
|
30650
30738
|
eventType: external_exports.enum(WEBHOOK_EVENT_TYPES),
|
|
@@ -31117,7 +31205,8 @@ var automationDraftsEndpoints = {
|
|
|
31117
31205
|
list: root3,
|
|
31118
31206
|
detail: (id) => `${root3}/${encodeURIComponent(id)}`,
|
|
31119
31207
|
finalize: (id) => `${root3}/${encodeURIComponent(id)}/finalize`,
|
|
31120
|
-
test: (id) => `${root3}/${encodeURIComponent(id)}/test
|
|
31208
|
+
test: (id) => `${root3}/${encodeURIComponent(id)}/test`,
|
|
31209
|
+
testRun: (id, runId) => `${root3}/${encodeURIComponent(id)}/test-runs/${encodeURIComponent(runId)}`
|
|
31121
31210
|
};
|
|
31122
31211
|
|
|
31123
31212
|
// ../../packages/sdk/dist/esm/clients/automation-drafts/automation-drafts-client.js
|
|
@@ -31131,6 +31220,16 @@ function getDraftNotReadyError(error62) {
|
|
|
31131
31220
|
const parsed = AutomationDraftNotReadySchema.safeParse(error62.responseData);
|
|
31132
31221
|
return parsed.success ? parsed.data : null;
|
|
31133
31222
|
}
|
|
31223
|
+
function getDraftTestRequestError(error62) {
|
|
31224
|
+
if (!(error62 instanceof AutomationsRequestError) || error62.httpStatusCode !== 400) {
|
|
31225
|
+
return null;
|
|
31226
|
+
}
|
|
31227
|
+
const parsed = DraftTestRequestErrorSchema.safeParse(error62.responseData);
|
|
31228
|
+
return parsed.success ? parsed.data : null;
|
|
31229
|
+
}
|
|
31230
|
+
function isRequestOptions(value) {
|
|
31231
|
+
return Boolean(value && ("signal" in value || "headers" in value));
|
|
31232
|
+
}
|
|
31134
31233
|
var AutomationDraftsClient = class extends BaseClient {
|
|
31135
31234
|
async list(args = {}, options) {
|
|
31136
31235
|
const { cursor, limit } = CursorPaginationSchema.parse(args);
|
|
@@ -31191,16 +31290,35 @@ var AutomationDraftsClient = class extends BaseClient {
|
|
|
31191
31290
|
});
|
|
31192
31291
|
return finalizeAutomationDraftResponseSchema.parse(data);
|
|
31193
31292
|
}
|
|
31194
|
-
|
|
31293
|
+
/** Starts a test run; `request` picks the trigger and supplies the event to test with. */
|
|
31294
|
+
async test(draftId, requestOrOptions, options) {
|
|
31195
31295
|
const id = IdSchema.parse(draftId);
|
|
31296
|
+
const request2 = isRequestOptions(requestOrOptions) ? void 0 : requestOrOptions;
|
|
31196
31297
|
const data = await this.request({
|
|
31197
31298
|
method: "POST",
|
|
31198
31299
|
path: automationDraftsEndpoints.test(id),
|
|
31199
|
-
|
|
31300
|
+
body: request2 ? testAutomationDraftRequestSchema.parse(request2) : void 0,
|
|
31301
|
+
options: isRequestOptions(requestOrOptions) ? requestOrOptions : options
|
|
31200
31302
|
});
|
|
31201
31303
|
return testAutomationDraftResponseSchema.parse(data);
|
|
31202
31304
|
}
|
|
31305
|
+
/** A test run of this draft, with its steps; `args` match the run detail's. */
|
|
31306
|
+
async getTestRun(draftId, runId, args = {}, options) {
|
|
31307
|
+
const data = await this.request({
|
|
31308
|
+
method: "GET",
|
|
31309
|
+
path: automationDraftsEndpoints.testRun(IdSchema.parse(draftId), IdSchema.parse(runId)),
|
|
31310
|
+
query: toTestRunQuery(args),
|
|
31311
|
+
options
|
|
31312
|
+
});
|
|
31313
|
+
return DraftTestRunDetailDtoSchema.parse(data);
|
|
31314
|
+
}
|
|
31203
31315
|
};
|
|
31316
|
+
function toTestRunQuery(args) {
|
|
31317
|
+
return {
|
|
31318
|
+
includeGeneratedCode: args.includeGeneratedCode ? true : void 0,
|
|
31319
|
+
includeToolCallPreviews: args.includeToolCallPreviews
|
|
31320
|
+
};
|
|
31321
|
+
}
|
|
31204
31322
|
|
|
31205
31323
|
// ../../packages/sdk/dist/esm/clients/automation-runs/endpoints.js
|
|
31206
31324
|
var automationRunsEndpoints = {
|
|
@@ -31209,7 +31327,7 @@ var automationRunsEndpoints = {
|
|
|
31209
31327
|
};
|
|
31210
31328
|
|
|
31211
31329
|
// ../../packages/sdk/dist/esm/clients/automation-runs/automation-runs-client.js
|
|
31212
|
-
function
|
|
31330
|
+
function isRequestOptions2(value) {
|
|
31213
31331
|
return Boolean(value && ("signal" in value || "headers" in value));
|
|
31214
31332
|
}
|
|
31215
31333
|
var AutomationRunsClient = class extends BaseClient {
|
|
@@ -31228,8 +31346,8 @@ var AutomationRunsClient = class extends BaseClient {
|
|
|
31228
31346
|
async get(automationId, runId, argsOrOptions, options) {
|
|
31229
31347
|
const aId = IdSchema.parse(automationId);
|
|
31230
31348
|
const rId = IdSchema.parse(runId);
|
|
31231
|
-
const args =
|
|
31232
|
-
const requestOptions =
|
|
31349
|
+
const args = isRequestOptions2(argsOrOptions) ? void 0 : argsOrOptions;
|
|
31350
|
+
const requestOptions = isRequestOptions2(argsOrOptions) ? argsOrOptions : options;
|
|
31233
31351
|
const data = await this.request({
|
|
31234
31352
|
method: "GET",
|
|
31235
31353
|
path: automationRunsEndpoints.detail(aId, rId),
|
|
@@ -31488,7 +31606,9 @@ var WorkspaceAutomationDraftConnectionsClient = class extends BaseClient {
|
|
|
31488
31606
|
var workspaceAutomationDraftsEndpoints = {
|
|
31489
31607
|
list: (workspaceId) => `${root7(workspaceId)}`,
|
|
31490
31608
|
detail: (workspaceId, id) => `${root7(workspaceId)}/${encodeURIComponent(id)}`,
|
|
31491
|
-
finalize: (workspaceId, id) => `${root7(workspaceId)}/${encodeURIComponent(id)}/finalize
|
|
31609
|
+
finalize: (workspaceId, id) => `${root7(workspaceId)}/${encodeURIComponent(id)}/finalize`,
|
|
31610
|
+
test: (workspaceId, id) => `${root7(workspaceId)}/${encodeURIComponent(id)}/test`,
|
|
31611
|
+
testRun: (workspaceId, id, runId) => `${root7(workspaceId)}/${encodeURIComponent(id)}/test-runs/${encodeURIComponent(runId)}`
|
|
31492
31612
|
};
|
|
31493
31613
|
function root7(workspaceId) {
|
|
31494
31614
|
return `/workspaces/${encodeURIComponent(workspaceId)}/automation-drafts`;
|
|
@@ -31554,6 +31674,24 @@ var WorkspaceAutomationDraftsClient = class extends BaseClient {
|
|
|
31554
31674
|
});
|
|
31555
31675
|
return finalizeAutomationDraftResponseSchema.parse(data);
|
|
31556
31676
|
}
|
|
31677
|
+
async test(workspaceId, draftId, request2 = {}, options) {
|
|
31678
|
+
const data = await this.request({
|
|
31679
|
+
method: "POST",
|
|
31680
|
+
path: workspaceAutomationDraftsEndpoints.test(IdSchema.parse(workspaceId), IdSchema.parse(draftId)),
|
|
31681
|
+
body: testAutomationDraftRequestSchema.parse(request2),
|
|
31682
|
+
options
|
|
31683
|
+
});
|
|
31684
|
+
return testAutomationDraftResponseSchema.parse(data);
|
|
31685
|
+
}
|
|
31686
|
+
async getTestRun(workspaceId, draftId, runId, args = {}, options) {
|
|
31687
|
+
const data = await this.request({
|
|
31688
|
+
method: "GET",
|
|
31689
|
+
path: workspaceAutomationDraftsEndpoints.testRun(IdSchema.parse(workspaceId), IdSchema.parse(draftId), IdSchema.parse(runId)),
|
|
31690
|
+
query: toTestRunQuery(args),
|
|
31691
|
+
options
|
|
31692
|
+
});
|
|
31693
|
+
return DraftTestRunDetailDtoSchema.parse(data);
|
|
31694
|
+
}
|
|
31557
31695
|
};
|
|
31558
31696
|
|
|
31559
31697
|
// ../../packages/sdk/dist/esm/clients/workspace-chat/endpoints.js
|
|
@@ -32497,25 +32635,47 @@ function summarizeRun(run) {
|
|
|
32497
32635
|
result: run.result,
|
|
32498
32636
|
temporalUrl: run.temporalUrl,
|
|
32499
32637
|
triggeredBy: run.triggeredBy,
|
|
32500
|
-
steps: run.steps
|
|
32501
|
-
|
|
32502
|
-
|
|
32503
|
-
|
|
32504
|
-
|
|
32505
|
-
|
|
32506
|
-
|
|
32507
|
-
|
|
32508
|
-
|
|
32509
|
-
|
|
32510
|
-
|
|
32511
|
-
|
|
32512
|
-
|
|
32513
|
-
|
|
32514
|
-
|
|
32515
|
-
|
|
32516
|
-
|
|
32517
|
-
|
|
32638
|
+
steps: summarizeRunSteps(run.steps)
|
|
32639
|
+
};
|
|
32640
|
+
}
|
|
32641
|
+
function summarizeRunSteps(steps) {
|
|
32642
|
+
return steps.map((step) => ({
|
|
32643
|
+
stepId: step.stepId,
|
|
32644
|
+
type: step.type,
|
|
32645
|
+
description: step.description,
|
|
32646
|
+
status: step.status,
|
|
32647
|
+
startedAt: step.startedAt,
|
|
32648
|
+
completedAt: step.completedAt,
|
|
32649
|
+
error: step.error,
|
|
32650
|
+
toolCalls: step.toolCalls?.map((toolCall) => ({
|
|
32651
|
+
id: toolCall.id,
|
|
32652
|
+
name: toolCall.name,
|
|
32653
|
+
argumentKeys: toolCall.argumentKeys,
|
|
32654
|
+
hasResult: toolCall.hasResult,
|
|
32655
|
+
hasError: toolCall.hasError,
|
|
32656
|
+
resultPreview: toolCall.resultPreview,
|
|
32657
|
+
errorPreview: toolCall.errorPreview,
|
|
32658
|
+
timestamp: toolCall.timestamp
|
|
32518
32659
|
}))
|
|
32660
|
+
}));
|
|
32661
|
+
}
|
|
32662
|
+
|
|
32663
|
+
// ../../packages/sdk/dist/esm/summaries/draft-test-run-summary.js
|
|
32664
|
+
function summarizeDraftTestRun(run) {
|
|
32665
|
+
return {
|
|
32666
|
+
id: run.id,
|
|
32667
|
+
draftId: run.draftId,
|
|
32668
|
+
automationId: run.automationId,
|
|
32669
|
+
status: run.status,
|
|
32670
|
+
connectorCalls: run.connectorCalls,
|
|
32671
|
+
createdAt: run.createdAt,
|
|
32672
|
+
updatedAt: run.updatedAt,
|
|
32673
|
+
failureCategory: getRunOutcomeCategory(run),
|
|
32674
|
+
failureReason: getRunOutcomeReason(run),
|
|
32675
|
+
failedStep: run.failedStep,
|
|
32676
|
+
result: run.result,
|
|
32677
|
+
temporalUrl: run.temporalUrl,
|
|
32678
|
+
steps: summarizeRunSteps(run.steps)
|
|
32519
32679
|
};
|
|
32520
32680
|
}
|
|
32521
32681
|
|
|
@@ -34168,7 +34328,9 @@ async function runApiCommand(command, operation, presentation, execution = {}) {
|
|
|
34168
34328
|
try {
|
|
34169
34329
|
const globalOptions = getGlobalOptions(command);
|
|
34170
34330
|
mode = getOutputMode(globalOptions);
|
|
34171
|
-
const apiConfiguration = await resolveApiConfiguration(globalOptions
|
|
34331
|
+
const apiConfiguration = await resolveApiConfiguration(globalOptions, {
|
|
34332
|
+
minimumTokenLifetimeMs: execution.minimumTokenLifetimeMs
|
|
34333
|
+
});
|
|
34172
34334
|
source = apiConfiguration.source;
|
|
34173
34335
|
const context = {
|
|
34174
34336
|
api: createAutomationsApi(apiConfiguration),
|
|
@@ -34184,6 +34346,8 @@ async function runApiCommand(command, operation, presentation, execution = {}) {
|
|
|
34184
34346
|
);
|
|
34185
34347
|
stopEarlySpinner();
|
|
34186
34348
|
writeResult(mode, result, presentation);
|
|
34349
|
+
const exitCode = execution.exitCode?.(result);
|
|
34350
|
+
if (exitCode !== void 0) process.exitCode = exitCode;
|
|
34187
34351
|
} catch (error62) {
|
|
34188
34352
|
if (abortController.signal.aborted) {
|
|
34189
34353
|
writeFailure(mode, "interrupted", {
|
|
@@ -34351,16 +34515,21 @@ function formatRun(run) {
|
|
|
34351
34515
|
`Failure reason: ${getRunOutcomeReason(run) ?? "none"}`,
|
|
34352
34516
|
`Result: ${run.result?.text ?? "none"}`,
|
|
34353
34517
|
`Steps: ${run.steps.length}`,
|
|
34354
|
-
...isInsufficientCredit(run) ? ["", topUpAdvisory()] : []
|
|
34518
|
+
...isInsufficientCredit(run) ? ["", topUpAdvisory()] : [],
|
|
34519
|
+
...formatRunSteps(run.steps)
|
|
34355
34520
|
];
|
|
34356
|
-
|
|
34521
|
+
return lines.join("\n");
|
|
34522
|
+
}
|
|
34523
|
+
function formatRunSteps(steps, { toolCallLabel = "Tool" } = {}) {
|
|
34524
|
+
const lines = [];
|
|
34525
|
+
for (const [index, step] of steps.entries()) {
|
|
34357
34526
|
lines.push("", `${index + 1}. ${step.stepId} [${step.status}] ${step.description}`);
|
|
34358
34527
|
lines.push(` Type: ${step.type}`);
|
|
34359
34528
|
if (step.startedAt) lines.push(` Started: ${step.startedAt}`);
|
|
34360
34529
|
if (step.completedAt) lines.push(` Completed: ${step.completedAt}`);
|
|
34361
34530
|
if (step.error) lines.push(` Error: ${step.error}`);
|
|
34362
34531
|
for (const toolCall of step.toolCalls ?? []) {
|
|
34363
|
-
lines.push(`
|
|
34532
|
+
lines.push(` ${toolCallLabel}: ${toolCall.name} (${toolCall.id})`);
|
|
34364
34533
|
if (toolCall.argumentKeys.length > 0) {
|
|
34365
34534
|
lines.push(` Args: ${toolCall.argumentKeys.join(", ")}`);
|
|
34366
34535
|
}
|
|
@@ -34370,7 +34539,7 @@ function formatRun(run) {
|
|
|
34370
34539
|
if (toolCall.resultPreview) lines.push(` Result preview: ${toolCall.resultPreview}`);
|
|
34371
34540
|
}
|
|
34372
34541
|
}
|
|
34373
|
-
return lines
|
|
34542
|
+
return lines;
|
|
34374
34543
|
}
|
|
34375
34544
|
function getResourceName(manifest) {
|
|
34376
34545
|
if (!isRecord2(manifest)) return "(unnamed)";
|
|
@@ -36842,6 +37011,8 @@ async function readSource(options, input2) {
|
|
|
36842
37011
|
|
|
36843
37012
|
// src/commands/draft/draft-service.ts
|
|
36844
37013
|
import { CliError as CliError4, getErrorMessage as getErrorMessage7 } from "@doist/cli-core";
|
|
37014
|
+
import { readFile as readFile3 } from "node:fs/promises";
|
|
37015
|
+
import { setTimeout as wait2 } from "node:timers/promises";
|
|
36845
37016
|
|
|
36846
37017
|
// src/lib/manifest-diff.ts
|
|
36847
37018
|
function stableStringify(value) {
|
|
@@ -36904,7 +37075,11 @@ function resolveDraftApi(api, workspaceId, signal) {
|
|
|
36904
37075
|
upsertConnection: (draftId, body) => api.automationDraftConnections.upsert(draftId, body, { signal }),
|
|
36905
37076
|
getConnectionStatus: async (draftId) => (await api.automationDraftConnections.getStatus(draftId, { signal })).validation,
|
|
36906
37077
|
finalize: (draftId) => api.automationDrafts.finalize(draftId, { signal }),
|
|
36907
|
-
getAutomation: (automationId) => api.automations.get(automationId, { signal })
|
|
37078
|
+
getAutomation: (automationId) => api.automations.get(automationId, { signal }),
|
|
37079
|
+
test: (draftId, request2) => api.automationDrafts.test(draftId, request2, { signal }),
|
|
37080
|
+
getTestRun: (draftId, runId, args, requestSignal) => api.automationDrafts.getTestRun(draftId, runId, args, {
|
|
37081
|
+
signal: requestSignal ?? signal
|
|
37082
|
+
})
|
|
36908
37083
|
};
|
|
36909
37084
|
}
|
|
36910
37085
|
return {
|
|
@@ -36918,7 +37093,11 @@ function resolveDraftApi(api, workspaceId, signal) {
|
|
|
36918
37093
|
signal
|
|
36919
37094
|
})).validation,
|
|
36920
37095
|
finalize: (draftId) => api.workspaceAutomationDrafts.finalize(workspaceId, draftId, { signal }),
|
|
36921
|
-
getAutomation: (automationId) => api.workspaceAutomations.get(workspaceId, automationId, { signal })
|
|
37096
|
+
getAutomation: (automationId) => api.workspaceAutomations.get(workspaceId, automationId, { signal }),
|
|
37097
|
+
test: (draftId, request2) => api.workspaceAutomationDrafts.test(workspaceId, draftId, request2, { signal }),
|
|
37098
|
+
getTestRun: (draftId, runId, args, requestSignal) => api.workspaceAutomationDrafts.getTestRun(workspaceId, draftId, runId, args, {
|
|
37099
|
+
signal: requestSignal ?? signal
|
|
37100
|
+
})
|
|
36922
37101
|
};
|
|
36923
37102
|
}
|
|
36924
37103
|
async function createDraft(draftApi, { manifest, automationId }) {
|
|
@@ -37054,12 +37233,7 @@ async function publishDraft(draftApi, { draftId, confirmed }) {
|
|
|
37054
37233
|
} catch (error62) {
|
|
37055
37234
|
const notReady = getDraftNotReadyError(error62);
|
|
37056
37235
|
if (!notReady) throw error62;
|
|
37057
|
-
throw
|
|
37058
|
-
hints: [
|
|
37059
|
-
`See the issues: tda draft view ${draftId}`,
|
|
37060
|
-
`Bind connections: tda draft connect ${draftId} --auto`
|
|
37061
|
-
]
|
|
37062
|
-
});
|
|
37236
|
+
throw draftNotReadyError(notReady.message, draftId, draftApi.scope);
|
|
37063
37237
|
}
|
|
37064
37238
|
const automationId = published.automation.id;
|
|
37065
37239
|
let automation;
|
|
@@ -37137,6 +37311,136 @@ function normaliseManifest(manifest) {
|
|
|
37137
37311
|
const parsed = manifestSchema.safeParse(manifest);
|
|
37138
37312
|
return parsed.success ? parsed.data : manifest;
|
|
37139
37313
|
}
|
|
37314
|
+
var DEFAULT_POLL_INTERVALS_MS = { first: 2e3, max: 1e4 };
|
|
37315
|
+
var STATUS_REQUEST_GRACE_MS = 1e4;
|
|
37316
|
+
var OPEN_RUN_STATUSES = /* @__PURE__ */ new Set([
|
|
37317
|
+
"pending",
|
|
37318
|
+
"running"
|
|
37319
|
+
]);
|
|
37320
|
+
async function startDraftTest(draftApi, {
|
|
37321
|
+
draftId,
|
|
37322
|
+
request: request2,
|
|
37323
|
+
wait: waitFor,
|
|
37324
|
+
signal
|
|
37325
|
+
}) {
|
|
37326
|
+
let started;
|
|
37327
|
+
try {
|
|
37328
|
+
started = await draftApi.test(draftId, request2);
|
|
37329
|
+
} catch (error62) {
|
|
37330
|
+
const refusal = getDraftTestRequestError(error62);
|
|
37331
|
+
if (!refusal) throw error62;
|
|
37332
|
+
throw toDraftTestCliError(refusal, draftId, draftApi.scope);
|
|
37333
|
+
}
|
|
37334
|
+
const base = {
|
|
37335
|
+
draftId,
|
|
37336
|
+
testRunId: started.testRunId,
|
|
37337
|
+
trigger: started.trigger,
|
|
37338
|
+
connectorCalls: started.connectorCalls,
|
|
37339
|
+
command: `tda draft test-run ${draftId} ${started.testRunId} ${scopeFlag(draftApi.scope)}`
|
|
37340
|
+
};
|
|
37341
|
+
if (!waitFor) {
|
|
37342
|
+
return { action: "test_started", ...base, status: started.status };
|
|
37343
|
+
}
|
|
37344
|
+
const intervals = waitFor.pollIntervalsMs ?? DEFAULT_POLL_INTERVALS_MS;
|
|
37345
|
+
const deadline = Date.now() + waitFor.timeoutMs;
|
|
37346
|
+
let intervalMs = intervals.first;
|
|
37347
|
+
let last = null;
|
|
37348
|
+
while (true) {
|
|
37349
|
+
const requestTimeout = AbortSignal.timeout(
|
|
37350
|
+
Math.max(deadline - Date.now(), 0) + (waitFor.requestGraceMs ?? STATUS_REQUEST_GRACE_MS)
|
|
37351
|
+
);
|
|
37352
|
+
try {
|
|
37353
|
+
last = await draftApi.getTestRun(
|
|
37354
|
+
draftId,
|
|
37355
|
+
started.testRunId,
|
|
37356
|
+
void 0,
|
|
37357
|
+
AbortSignal.any([signal, requestTimeout])
|
|
37358
|
+
);
|
|
37359
|
+
} catch (error62) {
|
|
37360
|
+
if (signal.aborted || !requestTimeout.aborted) throw error62;
|
|
37361
|
+
return toFinished(base, last, "timed_out");
|
|
37362
|
+
}
|
|
37363
|
+
if (!OPEN_RUN_STATUSES.has(last.status)) {
|
|
37364
|
+
return toFinished(base, last, toOutcome(last.status));
|
|
37365
|
+
}
|
|
37366
|
+
const remainingMs = deadline - Date.now();
|
|
37367
|
+
if (remainingMs <= 0) {
|
|
37368
|
+
return toFinished(base, last, "timed_out");
|
|
37369
|
+
}
|
|
37370
|
+
await wait2(Math.min(intervalMs, remainingMs), void 0, { signal });
|
|
37371
|
+
intervalMs = Math.min(intervalMs * 2, intervals.max);
|
|
37372
|
+
}
|
|
37373
|
+
}
|
|
37374
|
+
function toFinished(base, run, outcome) {
|
|
37375
|
+
return {
|
|
37376
|
+
action: "test_finished",
|
|
37377
|
+
...base,
|
|
37378
|
+
outcome,
|
|
37379
|
+
status: run?.status ?? "pending",
|
|
37380
|
+
failedStep: run?.failedStep ?? null,
|
|
37381
|
+
error: run?.failedStep?.error ?? (run ? getRunOutcomeReason(run) : null) ?? (run?.status === "data-expired" ? "Temporal no longer holds this run's history, so its outcome is unknown" : null),
|
|
37382
|
+
result: run?.result ?? null
|
|
37383
|
+
};
|
|
37384
|
+
}
|
|
37385
|
+
function toOutcome(status) {
|
|
37386
|
+
switch (status) {
|
|
37387
|
+
case "completed":
|
|
37388
|
+
return "passed";
|
|
37389
|
+
case "skipped":
|
|
37390
|
+
return "skipped";
|
|
37391
|
+
case "cancelled":
|
|
37392
|
+
return "cancelled";
|
|
37393
|
+
default:
|
|
37394
|
+
return "failed";
|
|
37395
|
+
}
|
|
37396
|
+
}
|
|
37397
|
+
function draftNotReadyError(message, draftId, scope) {
|
|
37398
|
+
const flag = scopeFlag(scope);
|
|
37399
|
+
return new CliError4("DRAFT_NOT_READY", message, {
|
|
37400
|
+
hints: [
|
|
37401
|
+
`See the issues: tda draft view ${draftId} ${flag}`,
|
|
37402
|
+
`Bind connections: tda draft connect ${draftId} --auto ${flag}`
|
|
37403
|
+
]
|
|
37404
|
+
});
|
|
37405
|
+
}
|
|
37406
|
+
function toDraftTestCliError(refusal, draftId, scope) {
|
|
37407
|
+
const flag = scopeFlag(scope);
|
|
37408
|
+
switch (refusal.code) {
|
|
37409
|
+
case "draft_test_not_ready":
|
|
37410
|
+
return draftNotReadyError(refusal.message, draftId, scope);
|
|
37411
|
+
case "draft_test_payload_required":
|
|
37412
|
+
case "draft_test_payload_filtered":
|
|
37413
|
+
return new CliError4(refusal.code.toUpperCase(), refusal.message, {
|
|
37414
|
+
hints: [
|
|
37415
|
+
`Test with a real event: tda draft test ${draftId} --trigger <event> --payload-file <path> ${flag}`
|
|
37416
|
+
]
|
|
37417
|
+
});
|
|
37418
|
+
default:
|
|
37419
|
+
return new CliError4(refusal.code.toUpperCase(), refusal.message);
|
|
37420
|
+
}
|
|
37421
|
+
}
|
|
37422
|
+
function parseTriggerOption(value) {
|
|
37423
|
+
return /^\d+$/.test(value) ? { index: Number(value) } : { event: value };
|
|
37424
|
+
}
|
|
37425
|
+
async function readTestPayloadFile(path) {
|
|
37426
|
+
let content;
|
|
37427
|
+
try {
|
|
37428
|
+
content = await readFile3(path, "utf8");
|
|
37429
|
+
} catch (error62) {
|
|
37430
|
+
throw new CliError4(
|
|
37431
|
+
"PAYLOAD_UNREADABLE",
|
|
37432
|
+
`Could not read ${path}: ${getErrorMessage7(error62)}`
|
|
37433
|
+
);
|
|
37434
|
+
}
|
|
37435
|
+
try {
|
|
37436
|
+
return JSON.parse(content);
|
|
37437
|
+
} catch (error62) {
|
|
37438
|
+
throw new CliError4(
|
|
37439
|
+
"PAYLOAD_UNREADABLE",
|
|
37440
|
+
`${path} is not valid JSON: ${getErrorMessage7(error62)}`
|
|
37441
|
+
);
|
|
37442
|
+
}
|
|
37443
|
+
}
|
|
37140
37444
|
|
|
37141
37445
|
// src/commands/draft/format.ts
|
|
37142
37446
|
function formatDraftDelete(result) {
|
|
@@ -37246,6 +37550,72 @@ function describeDiff(diff) {
|
|
|
37246
37550
|
if (diff.steps.reordered) parts.push("steps reordered");
|
|
37247
37551
|
return parts.join("; ");
|
|
37248
37552
|
}
|
|
37553
|
+
var MOCKED_CONNECTOR_CALLS_LINE = "Connector calls: mocked (simulated by a model; nothing was read from or written to your services)";
|
|
37554
|
+
function formatDraftTestRun(run) {
|
|
37555
|
+
const reason = getRunOutcomeReason(run);
|
|
37556
|
+
const lines = [
|
|
37557
|
+
`Test run: ${run.id}`,
|
|
37558
|
+
`Draft: ${run.draftId}`,
|
|
37559
|
+
`Automation: ${run.automationId ?? "none (the draft creates a new one)"}`,
|
|
37560
|
+
`Status: ${run.status}`,
|
|
37561
|
+
MOCKED_CONNECTOR_CALLS_LINE,
|
|
37562
|
+
`Created: ${run.createdAt}`,
|
|
37563
|
+
`Updated: ${run.updatedAt}`
|
|
37564
|
+
];
|
|
37565
|
+
if (run.failedStep) {
|
|
37566
|
+
lines.push(
|
|
37567
|
+
`Failed step: ${run.failedStep.stepId} (${run.failedStep.description})`,
|
|
37568
|
+
`Error: ${run.failedStep.error ?? reason ?? "none reported"}`
|
|
37569
|
+
);
|
|
37570
|
+
} else if (reason) {
|
|
37571
|
+
lines.push(`${run.status === "skipped" ? "Skip" : "Failure"} reason: ${reason}`);
|
|
37572
|
+
}
|
|
37573
|
+
lines.push(
|
|
37574
|
+
`Result: ${run.result?.text ?? "none"}`,
|
|
37575
|
+
`Steps: ${run.steps.length}`,
|
|
37576
|
+
...formatRunSteps(run.steps, { toolCallLabel: "Tool (mocked)" })
|
|
37577
|
+
);
|
|
37578
|
+
return lines.join("\n");
|
|
37579
|
+
}
|
|
37580
|
+
var INPUT_SOURCE_LABELS = {
|
|
37581
|
+
schedule: "as a scheduled run",
|
|
37582
|
+
"sample-event": "with the built-in sample event",
|
|
37583
|
+
supplied: "with the supplied payload",
|
|
37584
|
+
empty: "with an empty request body"
|
|
37585
|
+
};
|
|
37586
|
+
var OUTCOME_LABELS = {
|
|
37587
|
+
passed: "passed",
|
|
37588
|
+
failed: "failed",
|
|
37589
|
+
skipped: "was skipped",
|
|
37590
|
+
cancelled: "was cancelled",
|
|
37591
|
+
timed_out: "did not finish before the timeout"
|
|
37592
|
+
};
|
|
37593
|
+
function formatDraftTest(result) {
|
|
37594
|
+
const { trigger } = result;
|
|
37595
|
+
const which = trigger.type === "webhook" ? `webhook ${trigger.event}` : trigger.type;
|
|
37596
|
+
const lines = [
|
|
37597
|
+
result.action === "test_started" ? `Started test run ${result.testRunId} for draft ${result.draftId}.` : `Test run ${result.testRunId} for draft ${result.draftId} ${OUTCOME_LABELS[result.outcome]}.`,
|
|
37598
|
+
`Trigger: ${trigger.index} of ${trigger.count} (${which}), ${INPUT_SOURCE_LABELS[trigger.inputSource]}`
|
|
37599
|
+
];
|
|
37600
|
+
if (result.action === "test_finished") {
|
|
37601
|
+
if (result.outcome === "timed_out") lines.push(`Status: ${result.status}`);
|
|
37602
|
+
if (result.failedStep) {
|
|
37603
|
+
lines.push(
|
|
37604
|
+
`Failed step: ${result.failedStep.stepId} (${result.failedStep.description})`
|
|
37605
|
+
);
|
|
37606
|
+
}
|
|
37607
|
+
if (result.error)
|
|
37608
|
+
lines.push(`${result.outcome === "skipped" ? "Reason" : "Error"}: ${result.error}`);
|
|
37609
|
+
if (result.result) lines.push(`Result: ${result.result.text}`);
|
|
37610
|
+
}
|
|
37611
|
+
lines.push(MOCKED_CONNECTOR_CALLS_LINE, `Details: ${result.command}`);
|
|
37612
|
+
if (trigger.count > 1) {
|
|
37613
|
+
lines.push(
|
|
37614
|
+
`This draft has ${trigger.count} triggers; test another with --trigger <index|event>.`
|
|
37615
|
+
);
|
|
37616
|
+
}
|
|
37617
|
+
return lines.join("\n");
|
|
37618
|
+
}
|
|
37249
37619
|
|
|
37250
37620
|
// src/commands/draft/validate-command.ts
|
|
37251
37621
|
import { CliError as CliError5 } from "@doist/cli-core";
|
|
@@ -37300,8 +37670,10 @@ function formatManifestValidation(result) {
|
|
|
37300
37670
|
}
|
|
37301
37671
|
|
|
37302
37672
|
// src/commands/draft/index.ts
|
|
37673
|
+
var DEFAULT_TEST_WAIT = "10m";
|
|
37674
|
+
var TOKEN_LIFETIME_MARGIN_MS = 2 * 60 * 1e3;
|
|
37303
37675
|
function registerDraftCommand(program) {
|
|
37304
|
-
const draft = program.command("draft").description("Author and inspect automation drafts");
|
|
37676
|
+
const draft = program.command("draft").description("Author, test and inspect automation drafts");
|
|
37305
37677
|
registerDraftValidateCommand(draft);
|
|
37306
37678
|
addWorkspaceScopeOptions(
|
|
37307
37679
|
addCursorPaginationOptions(
|
|
@@ -37425,6 +37797,63 @@ function registerDraftCommand(program) {
|
|
|
37425
37797
|
{ spinner: options.yes === true ? "Publishing..." : "Loading draft..." }
|
|
37426
37798
|
);
|
|
37427
37799
|
});
|
|
37800
|
+
addWorkspaceScopeOptions(
|
|
37801
|
+
draft.command("test").description("Start a test run of a draft, with mocked connector calls").argument("<draft-id>", "Draft ID").option("--wait", "Wait for the run to end and exit 1 unless it passed").option(
|
|
37802
|
+
"--timeout <duration>",
|
|
37803
|
+
`How long --wait waits, such as 90s or 15m (default ${DEFAULT_TEST_WAIT})`
|
|
37804
|
+
).option(
|
|
37805
|
+
"--trigger <index|event>",
|
|
37806
|
+
"The trigger to test: its position in the manifest's triggers, or a webhook event"
|
|
37807
|
+
).option(
|
|
37808
|
+
"--payload-file <path>",
|
|
37809
|
+
"A JSON event to test with: a webhook trigger's event or an API trigger's body"
|
|
37810
|
+
)
|
|
37811
|
+
).action(async (draftId, options, command) => {
|
|
37812
|
+
await runApiCommand(
|
|
37813
|
+
command,
|
|
37814
|
+
async ({ api, signal }) => {
|
|
37815
|
+
if (options.timeout !== void 0 && options.wait !== true) {
|
|
37816
|
+
throw new Error("--timeout only applies with --wait.");
|
|
37817
|
+
}
|
|
37818
|
+
const timeoutMs = parseTestTimeout(options.timeout ?? DEFAULT_TEST_WAIT);
|
|
37819
|
+
const draftApi = resolveDraftApi(api, await resolveWorkspaceScope(options), signal);
|
|
37820
|
+
return startDraftTest(draftApi, {
|
|
37821
|
+
draftId,
|
|
37822
|
+
request: {
|
|
37823
|
+
...options.trigger !== void 0 ? { trigger: parseTriggerOption(options.trigger) } : {},
|
|
37824
|
+
...options.payloadFile !== void 0 ? { payload: await readTestPayloadFile(options.payloadFile) } : {}
|
|
37825
|
+
},
|
|
37826
|
+
wait: options.wait === true ? { timeoutMs } : null,
|
|
37827
|
+
signal
|
|
37828
|
+
});
|
|
37829
|
+
},
|
|
37830
|
+
{ human: formatDraftTest },
|
|
37831
|
+
{
|
|
37832
|
+
spinner: options.wait === true ? "Testing draft..." : "Starting test run...",
|
|
37833
|
+
minimumTokenLifetimeMs: options.wait === true ? tryParseTestTimeout(options.timeout ?? DEFAULT_TEST_WAIT) + TOKEN_LIFETIME_MARGIN_MS : void 0,
|
|
37834
|
+
exitCode: (result) => result.action === "test_finished" && result.outcome !== "passed" ? 1 : void 0
|
|
37835
|
+
}
|
|
37836
|
+
);
|
|
37837
|
+
});
|
|
37838
|
+
addWorkspaceScopeOptions(
|
|
37839
|
+
draft.command("test-run").description("Show a draft's test run with step and failure details").argument("<draft-id>", "Draft ID").argument("<run-id>", "Test run ID").option("--full", "Include raw step results and generated code in machine output")
|
|
37840
|
+
).action(async (draftId, runId, options, command) => {
|
|
37841
|
+
await runApiCommand(
|
|
37842
|
+
command,
|
|
37843
|
+
async ({ api, signal }) => {
|
|
37844
|
+
const draftApi = resolveDraftApi(api, await resolveWorkspaceScope(options), signal);
|
|
37845
|
+
return draftApi.getTestRun(draftId, runId, {
|
|
37846
|
+
includeGeneratedCode: options.full === true,
|
|
37847
|
+
includeToolCallPreviews: true
|
|
37848
|
+
});
|
|
37849
|
+
},
|
|
37850
|
+
{
|
|
37851
|
+
human: formatDraftTestRun,
|
|
37852
|
+
json: options.full === true ? void 0 : summarizeDraftTestRun
|
|
37853
|
+
},
|
|
37854
|
+
{ spinner: "Loading test run..." }
|
|
37855
|
+
);
|
|
37856
|
+
});
|
|
37428
37857
|
addWorkspaceScopeOptions(
|
|
37429
37858
|
draft.command("delete").description("Delete a draft after previewing which one it is").argument("<draft-id>", "Draft ID").option("--yes", "Confirm deletion")
|
|
37430
37859
|
).action(async (draftId, options, command) => {
|
|
@@ -37461,6 +37890,20 @@ function streamDraftList(options, fetchPage) {
|
|
|
37461
37890
|
async (args) => summarizeDraftListPage(await fetchPage(args))
|
|
37462
37891
|
);
|
|
37463
37892
|
}
|
|
37893
|
+
function tryParseTestTimeout(value) {
|
|
37894
|
+
try {
|
|
37895
|
+
return durationStringToMilliseconds(value);
|
|
37896
|
+
} catch {
|
|
37897
|
+
return 0;
|
|
37898
|
+
}
|
|
37899
|
+
}
|
|
37900
|
+
function parseTestTimeout(value) {
|
|
37901
|
+
try {
|
|
37902
|
+
return durationStringToMilliseconds(value);
|
|
37903
|
+
} catch {
|
|
37904
|
+
throw new Error(`Invalid --timeout ${value}; use a duration such as 90s, 15m or 1h.`);
|
|
37905
|
+
}
|
|
37906
|
+
}
|
|
37464
37907
|
|
|
37465
37908
|
// src/commands/run/index.ts
|
|
37466
37909
|
import { Option as Option7 } from "commander";
|