@doist/automations-cli 1.2.0 → 1.3.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/README.md +39 -11
- package/dist/{chunk-XHAVDKEN.js → chunk-DYIIMUG3.js} +32 -2
- package/dist/chunk-DYIIMUG3.js.map +7 -0
- package/dist/index.js +1951 -1727
- package/dist/index.js.map +4 -4
- package/dist/lib/skills/update-installed.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-XHAVDKEN.js.map +0 -7
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
collectSkillStatus,
|
|
6
6
|
getInstaller,
|
|
7
7
|
updateAllInstalledSkills
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-DYIIMUG3.js";
|
|
9
9
|
|
|
10
10
|
// src/index.ts
|
|
11
11
|
import { Command } from "commander";
|
|
@@ -15,7 +15,7 @@ import { fileURLToPath } from "node:url";
|
|
|
15
15
|
// package.json
|
|
16
16
|
var package_default = {
|
|
17
17
|
name: "@doist/automations-cli",
|
|
18
|
-
version: "1.
|
|
18
|
+
version: "1.3.0",
|
|
19
19
|
description: "Command-line client for Todoist Automations",
|
|
20
20
|
type: "module",
|
|
21
21
|
bin: {
|
|
@@ -63,7 +63,7 @@ var package_default = {
|
|
|
63
63
|
"@napi-rs/keyring": "1.3.0",
|
|
64
64
|
ai: "7.0.77",
|
|
65
65
|
commander: "15.0.0",
|
|
66
|
-
oauth4webapi: "3.8.
|
|
66
|
+
oauth4webapi: "3.8.8",
|
|
67
67
|
open: "11.0.2",
|
|
68
68
|
"p-limit": "3.1.0"
|
|
69
69
|
},
|
|
@@ -19109,1820 +19109,1882 @@ var sendAdminTestEmailResponseSchema = external_exports.object({
|
|
|
19109
19109
|
messageId: external_exports.string()
|
|
19110
19110
|
});
|
|
19111
19111
|
|
|
19112
|
-
// ../../packages/core/dist/esm/
|
|
19113
|
-
var
|
|
19114
|
-
|
|
19115
|
-
|
|
19116
|
-
|
|
19112
|
+
// ../../packages/core/dist/esm/types/failure-category.types.js
|
|
19113
|
+
var FAILURE_CATEGORIES = [
|
|
19114
|
+
"mcp_upstream_unavailable",
|
|
19115
|
+
"mcp_client_missing",
|
|
19116
|
+
"mcp_tool_missing",
|
|
19117
|
+
"mcp_tool_call_failed",
|
|
19118
|
+
"llm_schema_validation",
|
|
19119
|
+
"llm_empty_response",
|
|
19120
|
+
"json_parse_error",
|
|
19121
|
+
"code_execution_error",
|
|
19122
|
+
"code_generation_error",
|
|
19123
|
+
"step_execution_error",
|
|
19124
|
+
"step_failure_pattern",
|
|
19125
|
+
"schema_validation",
|
|
19126
|
+
"template_variable_error",
|
|
19127
|
+
"invalid_configuration",
|
|
19128
|
+
"invalid_manifest",
|
|
19129
|
+
"automation_not_found",
|
|
19130
|
+
"timeout",
|
|
19131
|
+
"runtime_error",
|
|
19132
|
+
"insufficient_credit",
|
|
19133
|
+
"billing_unavailable",
|
|
19134
|
+
"unknown"
|
|
19135
|
+
];
|
|
19136
|
+
|
|
19137
|
+
// ../../packages/core/dist/esm/schemas/query-param.schema.js
|
|
19138
|
+
var isoDateTimeOrDateQueryParamSchema = external_exports.union([
|
|
19139
|
+
external_exports.iso.datetime({ offset: true }),
|
|
19140
|
+
external_exports.iso.date()
|
|
19141
|
+
]);
|
|
19142
|
+
var booleanQueryParamSchema = external_exports.preprocess((value) => value === "true" ? true : value === "false" ? false : value, external_exports.boolean());
|
|
19143
|
+
var booleanQueryFlagSchema = booleanQueryParamSchema.optional().transform((value) => value === true);
|
|
19144
|
+
|
|
19145
|
+
// ../../packages/core/dist/esm/schemas/automation-run.schema.js
|
|
19146
|
+
var AUTOMATION_RUN_RESULT_TEXT_MAX_LENGTH = 4e3;
|
|
19147
|
+
var DATE_ONLY_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
|
|
19148
|
+
var MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1e3;
|
|
19149
|
+
function resolveRunDateRange({ since, until }) {
|
|
19150
|
+
const untilExclusive = until !== void 0 && DATE_ONLY_PATTERN.test(until);
|
|
19151
|
+
return {
|
|
19152
|
+
since: since ? new Date(DATE_ONLY_PATTERN.test(since) ? `${since}T00:00:00.000Z` : since) : void 0,
|
|
19153
|
+
until: until ? new Date(untilExclusive ? (/* @__PURE__ */ new Date(`${until}T00:00:00.000Z`)).getTime() + MILLISECONDS_PER_DAY : until) : void 0,
|
|
19154
|
+
untilExclusive
|
|
19155
|
+
};
|
|
19156
|
+
}
|
|
19157
|
+
function isEmptyRunDateRange(range) {
|
|
19158
|
+
const { since, until, untilExclusive } = resolveRunDateRange(range);
|
|
19159
|
+
if (!since || !until)
|
|
19160
|
+
return false;
|
|
19161
|
+
return untilExclusive ? since.getTime() >= until.getTime() : since.getTime() > until.getTime();
|
|
19162
|
+
}
|
|
19163
|
+
var ListAutomationRunsQuerySchema = external_exports.object({
|
|
19164
|
+
status: external_exports.enum(AUTOMATION_RUN_STATUSES).optional(),
|
|
19165
|
+
since: isoDateTimeOrDateQueryParamSchema.optional(),
|
|
19166
|
+
until: isoDateTimeOrDateQueryParamSchema.optional()
|
|
19167
|
+
}).superRefine((query, ctx) => {
|
|
19168
|
+
if (isEmptyRunDateRange(query)) {
|
|
19169
|
+
ctx.addIssue({
|
|
19170
|
+
code: "custom",
|
|
19171
|
+
path: ["since"],
|
|
19172
|
+
message: "since must not be after until"
|
|
19173
|
+
});
|
|
19174
|
+
}
|
|
19117
19175
|
});
|
|
19118
|
-
var
|
|
19119
|
-
|
|
19120
|
-
|
|
19121
|
-
scopes: external_exports.array(external_exports.string()),
|
|
19122
|
-
connectionIds: external_exports.array(external_exports.string())
|
|
19123
|
-
}).optional(),
|
|
19124
|
-
triggers: external_exports.object({
|
|
19125
|
-
scopes: external_exports.array(external_exports.string()),
|
|
19126
|
-
connectionIds: external_exports.array(external_exports.string()),
|
|
19127
|
-
supportedEvents: external_exports.array(TriggerSupportedEventSchema)
|
|
19128
|
-
}).optional()
|
|
19176
|
+
var AutomationRunResultSchema = external_exports.object({
|
|
19177
|
+
type: external_exports.literal("markdown"),
|
|
19178
|
+
text: external_exports.string().trim().min(1).max(AUTOMATION_RUN_RESULT_TEXT_MAX_LENGTH)
|
|
19129
19179
|
});
|
|
19130
|
-
var
|
|
19180
|
+
var RolloutCompatibleAutomationRunResultSchema = AutomationRunResultSchema.nullish().transform((result) => {
|
|
19181
|
+
return result ?? null;
|
|
19182
|
+
});
|
|
19183
|
+
var AutomationRunDtoSchema = external_exports.object({
|
|
19131
19184
|
id: external_exports.string(),
|
|
19132
|
-
|
|
19133
|
-
|
|
19134
|
-
|
|
19135
|
-
|
|
19136
|
-
|
|
19137
|
-
|
|
19138
|
-
|
|
19139
|
-
|
|
19140
|
-
* independent from whether a third-party connector requires account setup.
|
|
19141
|
-
*/
|
|
19142
|
-
isSystem: external_exports.boolean().optional(),
|
|
19143
|
-
/**
|
|
19144
|
-
* Managed connectors (e.g. WhatsApp) share a single linked identity across
|
|
19145
|
-
* connection types — one onboarding covers both action and trigger uses.
|
|
19146
|
-
* The FE collapses per-type rows into a single account when this is true.
|
|
19147
|
-
*/
|
|
19148
|
-
isManaged: external_exports.boolean().optional()
|
|
19185
|
+
automationId: external_exports.string(),
|
|
19186
|
+
status: external_exports.enum(AUTOMATION_RUN_STATUSES),
|
|
19187
|
+
createdAt: external_exports.string(),
|
|
19188
|
+
updatedAt: external_exports.string(),
|
|
19189
|
+
failureReason: external_exports.string().nullish(),
|
|
19190
|
+
failureCategory: external_exports.enum(FAILURE_CATEGORIES).nullish(),
|
|
19191
|
+
result: RolloutCompatibleAutomationRunResultSchema,
|
|
19192
|
+
temporalUrl: external_exports.string().nullish()
|
|
19149
19193
|
});
|
|
19150
|
-
var
|
|
19151
|
-
|
|
19194
|
+
var MAX_TOOL_CALL_ARGUMENT_KEYS = 32;
|
|
19195
|
+
var MAX_TOOL_CALL_ARGUMENT_KEY_LENGTH = 64;
|
|
19196
|
+
var MAX_TOOL_CALL_PREVIEW_LENGTH = 500;
|
|
19197
|
+
var MAX_TOOL_CALLS_WITH_PREVIEWS = 20;
|
|
19198
|
+
var MAX_TOOL_CALL_PREVIEW_TOTAL_LENGTH = 2e3;
|
|
19199
|
+
var MAX_TOOL_CALL_ENTITY_LENGTH = 100;
|
|
19200
|
+
var MAX_TOOL_CALL_RESULT_PARSE_LENGTH = 1e4;
|
|
19201
|
+
var TOOL_CALL_OUTCOMES = ["data", "empty", "no-result", "error"];
|
|
19202
|
+
var TOOL_CALL_ERROR_CATEGORIES = [
|
|
19203
|
+
"authentication",
|
|
19204
|
+
"permission",
|
|
19205
|
+
"rate-limit",
|
|
19206
|
+
"timeout",
|
|
19207
|
+
"connection",
|
|
19208
|
+
"invalid-request",
|
|
19209
|
+
"unknown"
|
|
19210
|
+
];
|
|
19211
|
+
var ToolCallTimestampSchema = external_exports.union([external_exports.string(), external_exports.date()]).transform((timestamp) => timestamp instanceof Date ? timestamp.toISOString() : timestamp);
|
|
19212
|
+
var SafeToolCallDtoSchema = external_exports.object({
|
|
19213
|
+
id: external_exports.string(),
|
|
19214
|
+
name: external_exports.string(),
|
|
19215
|
+
argumentKeys: external_exports.array(external_exports.string()),
|
|
19216
|
+
hasResult: external_exports.boolean(),
|
|
19217
|
+
hasError: external_exports.boolean(),
|
|
19218
|
+
outcome: external_exports.enum(TOOL_CALL_OUTCOMES).optional(),
|
|
19219
|
+
errorCategory: external_exports.enum(TOOL_CALL_ERROR_CATEGORIES).optional(),
|
|
19220
|
+
resultPreview: external_exports.string().max(MAX_TOOL_CALL_PREVIEW_LENGTH).optional(),
|
|
19221
|
+
errorPreview: external_exports.string().max(MAX_TOOL_CALL_PREVIEW_LENGTH).optional(),
|
|
19222
|
+
timestamp: ToolCallTimestampSchema
|
|
19152
19223
|
});
|
|
19153
|
-
var
|
|
19224
|
+
var LegacyToolCallDtoInputSchema = external_exports.object({
|
|
19225
|
+
id: external_exports.string(),
|
|
19154
19226
|
name: external_exports.string(),
|
|
19155
|
-
|
|
19227
|
+
arguments: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
|
|
19228
|
+
result: external_exports.unknown().optional(),
|
|
19229
|
+
error: external_exports.unknown().optional(),
|
|
19230
|
+
errorStatus: external_exports.number().int().min(100).max(599).optional(),
|
|
19231
|
+
errorCode: external_exports.string().optional(),
|
|
19232
|
+
timestamp: ToolCallTimestampSchema
|
|
19233
|
+
});
|
|
19234
|
+
var ToolCallDtoInputSchema = external_exports.union([SafeToolCallDtoSchema, LegacyToolCallDtoInputSchema]);
|
|
19235
|
+
var ToolCallDtoSchema = external_exports.preprocess((toolCall) => {
|
|
19236
|
+
const parsed = ToolCallDtoInputSchema.safeParse(toolCall);
|
|
19237
|
+
return parsed.success ? normalizeToolCallDto(parsed.data) : toolCall;
|
|
19238
|
+
}, SafeToolCallDtoSchema);
|
|
19239
|
+
var ToolCallDtosSchema = external_exports.preprocess((toolCalls) => {
|
|
19240
|
+
if (!Array.isArray(toolCalls)) {
|
|
19241
|
+
return toolCalls;
|
|
19242
|
+
}
|
|
19243
|
+
const parsedToolCalls = toolCalls.map((toolCall) => ToolCallDtoInputSchema.safeParse(toolCall)).filter((result) => result.success).map((result) => result.data);
|
|
19244
|
+
return parsedToolCalls.length === toolCalls.length ? normalizeToolCallDtos(parsedToolCalls) : toolCalls;
|
|
19245
|
+
}, external_exports.array(SafeToolCallDtoSchema));
|
|
19246
|
+
var AUTOMATION_RUN_DEBUG_REASONS = [
|
|
19247
|
+
"condition-not-met",
|
|
19248
|
+
"exit-condition-met",
|
|
19249
|
+
"ask-terminated",
|
|
19250
|
+
"ask-expired",
|
|
19251
|
+
"run-result-not-configured",
|
|
19252
|
+
"run-result-empty"
|
|
19253
|
+
];
|
|
19254
|
+
var AutomationRunDebugReasonSchema = external_exports.enum(AUTOMATION_RUN_DEBUG_REASONS);
|
|
19255
|
+
var AutomationRunStepDtoOutputSchema = external_exports.object({
|
|
19256
|
+
stepId: external_exports.string(),
|
|
19257
|
+
type: external_exports.string(),
|
|
19156
19258
|
description: external_exports.string(),
|
|
19157
|
-
|
|
19259
|
+
status: external_exports.enum(AUTOMATION_RUN_STATUSES),
|
|
19260
|
+
startedAt: external_exports.string().optional(),
|
|
19261
|
+
completedAt: external_exports.string().optional(),
|
|
19262
|
+
result: external_exports.unknown().optional(),
|
|
19263
|
+
error: external_exports.string().optional(),
|
|
19264
|
+
generatedCode: external_exports.string().optional(),
|
|
19265
|
+
toolCalls: ToolCallDtosSchema.optional(),
|
|
19266
|
+
debugReason: AutomationRunDebugReasonSchema.optional()
|
|
19158
19267
|
});
|
|
19159
|
-
var
|
|
19160
|
-
|
|
19161
|
-
|
|
19268
|
+
var AutomationRunStepDtoSchema = AutomationRunStepDtoOutputSchema;
|
|
19269
|
+
var AutomationRunDetailDtoSchema = external_exports.object({
|
|
19270
|
+
id: external_exports.string(),
|
|
19271
|
+
automationId: external_exports.string(),
|
|
19272
|
+
status: external_exports.enum([...AUTOMATION_RUN_STATUSES, "data-expired"]),
|
|
19273
|
+
createdAt: external_exports.string(),
|
|
19274
|
+
updatedAt: external_exports.string(),
|
|
19275
|
+
failureReason: external_exports.string().nullish(),
|
|
19276
|
+
failureCategory: external_exports.enum(FAILURE_CATEGORIES).nullish(),
|
|
19277
|
+
result: RolloutCompatibleAutomationRunResultSchema,
|
|
19278
|
+
temporalUrl: external_exports.string().nullish(),
|
|
19279
|
+
steps: external_exports.array(AutomationRunStepDtoSchema)
|
|
19162
19280
|
});
|
|
19163
|
-
|
|
19164
|
-
|
|
19165
|
-
|
|
19166
|
-
|
|
19167
|
-
|
|
19168
|
-
var durationStringRegex = new RegExp(`^\\d+(${durationPattern})$`);
|
|
19169
|
-
var durationStringWithCaptureRegex = new RegExp(`^(\\d+)(${durationPattern})$`);
|
|
19170
|
-
var intervalScheduleRegex = new RegExp(`^\\d+(${durationPattern})(\\/\\d+(${durationPattern}))?$`);
|
|
19171
|
-
function durationStringToMilliseconds(value) {
|
|
19172
|
-
const match = value.match(durationStringWithCaptureRegex);
|
|
19173
|
-
if (!match) {
|
|
19174
|
-
throw new Error(`Invalid duration string: ${value}`);
|
|
19175
|
-
}
|
|
19176
|
-
const [, rawAmount, rawUnit] = match;
|
|
19177
|
-
const multiplierMap = {
|
|
19178
|
-
ms: 1,
|
|
19179
|
-
s: 1e3,
|
|
19180
|
-
m: 60 * 1e3,
|
|
19181
|
-
h: 60 * 60 * 1e3,
|
|
19182
|
-
d: 24 * 60 * 60 * 1e3,
|
|
19183
|
-
w: 7 * 24 * 60 * 60 * 1e3
|
|
19184
|
-
};
|
|
19185
|
-
const multiplier = multiplierMap[rawUnit];
|
|
19186
|
-
if (multiplier === void 0) {
|
|
19187
|
-
throw new Error(`Invalid duration unit in string: ${value}`);
|
|
19281
|
+
function summarizeToolCallArgumentKeys(args) {
|
|
19282
|
+
const keys = Object.keys(args ?? {}).sort();
|
|
19283
|
+
const kept = keys.slice(0, MAX_TOOL_CALL_ARGUMENT_KEYS).map((key) => key.length > MAX_TOOL_CALL_ARGUMENT_KEY_LENGTH ? `${key.slice(0, MAX_TOOL_CALL_ARGUMENT_KEY_LENGTH)}\u2026` : key);
|
|
19284
|
+
if (keys.length > MAX_TOOL_CALL_ARGUMENT_KEYS) {
|
|
19285
|
+
kept.push(`\u2026+${keys.length - MAX_TOOL_CALL_ARGUMENT_KEYS} more`);
|
|
19188
19286
|
}
|
|
19189
|
-
return
|
|
19287
|
+
return kept;
|
|
19190
19288
|
}
|
|
19191
|
-
|
|
19192
|
-
|
|
19193
|
-
|
|
19194
|
-
var ifConditionRegex = new RegExp(`^\\{\\{\\s*${ifConditionReferencePattern}\\s*\\}\\}\\s*(?:==|!=)\\s*'[^']*'$`);
|
|
19195
|
-
function isWord(segment, { underscore }) {
|
|
19196
|
-
if (segment.length === 0)
|
|
19197
|
-
return false;
|
|
19198
|
-
for (let index = 0; index < segment.length; index++) {
|
|
19199
|
-
const char = segment[index];
|
|
19200
|
-
const isAlpha = char >= "a" && char <= "z" || char >= "A" && char <= "Z";
|
|
19201
|
-
const isDigit = char >= "0" && char <= "9";
|
|
19202
|
-
const isUnderscore = underscore && char === "_";
|
|
19203
|
-
if (index === 0) {
|
|
19204
|
-
if (!isAlpha && !isUnderscore)
|
|
19205
|
-
return false;
|
|
19206
|
-
} else if (!isAlpha && !isDigit && !isUnderscore) {
|
|
19207
|
-
return false;
|
|
19208
|
-
}
|
|
19289
|
+
function summarizeToolCallPayloadPreview(payload) {
|
|
19290
|
+
if (typeof payload === "string") {
|
|
19291
|
+
return summarizePayloadSize(payload);
|
|
19209
19292
|
}
|
|
19210
|
-
|
|
19293
|
+
if (Array.isArray(payload)) {
|
|
19294
|
+
return `${payload.length} item${payload.length === 1 ? "" : "s"} returned`;
|
|
19295
|
+
}
|
|
19296
|
+
if (payload && typeof payload === "object") {
|
|
19297
|
+
const keys = summarizeToolCallArgumentKeys(payload);
|
|
19298
|
+
return truncateToolCallPreview(keys.length === 0 ? "Object returned" : `Object returned with fields: ${keys.join(", ")}`);
|
|
19299
|
+
}
|
|
19300
|
+
return `${getPrimitivePayloadType(payload)} returned`;
|
|
19211
19301
|
}
|
|
19212
|
-
function
|
|
19213
|
-
const
|
|
19214
|
-
|
|
19215
|
-
|
|
19216
|
-
const [id, ...segments] = rest;
|
|
19217
|
-
if (id === void 0 || !isWord(id, { underscore: false }))
|
|
19218
|
-
return false;
|
|
19219
|
-
return segments.every((segment) => isWord(segment, { underscore: true }));
|
|
19302
|
+
function summarizeToolCallResult(toolName, payload) {
|
|
19303
|
+
const result = parseJsonPayload(payload);
|
|
19304
|
+
if (payload === void 0 || result === null) {
|
|
19305
|
+
return { outcome: "no-result", preview: summarizeToolCallPayloadPreview(payload) };
|
|
19220
19306
|
}
|
|
19221
|
-
|
|
19222
|
-
|
|
19223
|
-
|
|
19224
|
-
|
|
19307
|
+
const tool = getToolCallDescription(toolName);
|
|
19308
|
+
const collection = getResultCollection(result, tool.entity);
|
|
19309
|
+
const textCollection = typeof payload === "string" && payload.length > MAX_TOOL_CALL_RESULT_PARSE_LENGTH ? null : getTextCollectionSummary(result, tool);
|
|
19310
|
+
const outcome = collection?.length === 0 || textCollection === 0 ? "empty" : "data";
|
|
19311
|
+
if (collection) {
|
|
19312
|
+
const summary = `${tool.action} ${collection.length} ${formatEntity(tool.entity, collection.length)}`;
|
|
19313
|
+
const projectCount = getProjectCount(collection, tool.entity);
|
|
19314
|
+
return {
|
|
19315
|
+
outcome,
|
|
19316
|
+
preview: truncateToolCallPreview(projectCount > 1 ? `${summary} across ${projectCount} projects` : summary)
|
|
19317
|
+
};
|
|
19225
19318
|
}
|
|
19226
|
-
|
|
19319
|
+
if (textCollection !== null) {
|
|
19320
|
+
return {
|
|
19321
|
+
outcome,
|
|
19322
|
+
preview: truncateToolCallPreview(`${tool.action} ${textCollection} ${formatEntity(tool.entity, textCollection)}`)
|
|
19323
|
+
};
|
|
19324
|
+
}
|
|
19325
|
+
if (isRecord(result) && !["Found", "Returned"].includes(tool.action)) {
|
|
19326
|
+
return {
|
|
19327
|
+
outcome,
|
|
19328
|
+
preview: truncateToolCallPreview(tool.action === "Retrieved" ? `Retrieved ${tool.entity} details` : `${tool.action} ${formatEntity(tool.entity, 1)}`)
|
|
19329
|
+
};
|
|
19330
|
+
}
|
|
19331
|
+
return { outcome, preview: summarizeToolCallPayloadPreview(payload) };
|
|
19227
19332
|
}
|
|
19228
|
-
function
|
|
19229
|
-
if (
|
|
19230
|
-
return
|
|
19231
|
-
const closeIndex = condition.indexOf("}}");
|
|
19232
|
-
if (closeIndex === -1)
|
|
19233
|
-
return null;
|
|
19234
|
-
const reference = condition.slice(2, closeIndex).trim();
|
|
19235
|
-
if (!isValidReference(reference))
|
|
19236
|
-
return null;
|
|
19237
|
-
const afterReference = condition.slice(closeIndex + 2).trimStart();
|
|
19238
|
-
const operator = afterReference.startsWith("==") ? "==" : afterReference.startsWith("!=") ? "!=" : null;
|
|
19239
|
-
if (!operator)
|
|
19240
|
-
return null;
|
|
19241
|
-
const afterOperator = afterReference.slice(2).trimStart();
|
|
19242
|
-
if (afterOperator.length < 2 || !afterOperator.startsWith("'") || !afterOperator.endsWith("'")) {
|
|
19243
|
-
return null;
|
|
19333
|
+
function classifyToolCallOutcome(toolName, result, error61, errorDetails = {}) {
|
|
19334
|
+
if (error61 !== void 0) {
|
|
19335
|
+
return { outcome: "error", errorCategory: classifyToolCallError(error61, errorDetails) };
|
|
19244
19336
|
}
|
|
19245
|
-
|
|
19246
|
-
if (literal2.includes("'"))
|
|
19247
|
-
return null;
|
|
19248
|
-
return { reference, operator, literal: literal2 };
|
|
19337
|
+
return { outcome: summarizeToolCallResult(toolName, result).outcome };
|
|
19249
19338
|
}
|
|
19250
|
-
|
|
19251
|
-
|
|
19252
|
-
function getManifestTriggers(manifest) {
|
|
19253
|
-
return manifest.triggers ?? [];
|
|
19339
|
+
function summarizePayloadSize(payload) {
|
|
19340
|
+
return `${payload.length} character${payload.length === 1 ? "" : "s"} returned`;
|
|
19254
19341
|
}
|
|
19255
|
-
function
|
|
19256
|
-
|
|
19257
|
-
|
|
19258
|
-
|
|
19259
|
-
|
|
19260
|
-
|
|
19342
|
+
function summarizeToolCallsWithPreviewLimits(toolCalls, summarize) {
|
|
19343
|
+
let previewsKept = 0;
|
|
19344
|
+
let previewLength = 0;
|
|
19345
|
+
return toolCalls.map((toolCall) => {
|
|
19346
|
+
const shouldIncludePreview = previewsKept < MAX_TOOL_CALLS_WITH_PREVIEWS && previewLength < MAX_TOOL_CALL_PREVIEW_TOTAL_LENGTH;
|
|
19347
|
+
const summary = summarize(toolCall, { includePreview: shouldIncludePreview });
|
|
19348
|
+
const nextPreviewLength = (summary.resultPreview?.length ?? 0) + (summary.errorPreview?.length ?? 0);
|
|
19349
|
+
if (nextPreviewLength === 0 || previewsKept < MAX_TOOL_CALLS_WITH_PREVIEWS && previewLength + nextPreviewLength <= MAX_TOOL_CALL_PREVIEW_TOTAL_LENGTH) {
|
|
19350
|
+
previewsKept += nextPreviewLength > 0 ? 1 : 0;
|
|
19351
|
+
previewLength += nextPreviewLength;
|
|
19352
|
+
return summary;
|
|
19353
|
+
}
|
|
19354
|
+
return stripToolCallPreviews(summary);
|
|
19355
|
+
});
|
|
19261
19356
|
}
|
|
19262
|
-
function
|
|
19263
|
-
|
|
19264
|
-
return false;
|
|
19265
|
-
if (schema === "string")
|
|
19266
|
-
return true;
|
|
19267
|
-
if (typeof schema !== "object" || schema === null)
|
|
19268
|
-
return false;
|
|
19269
|
-
const typedSchema = schema;
|
|
19270
|
-
return typedSchema["type"] === "string";
|
|
19357
|
+
function normalizeToolCallDtos(toolCalls) {
|
|
19358
|
+
return summarizeToolCallsWithPreviewLimits(toolCalls, normalizeToolCallDto);
|
|
19271
19359
|
}
|
|
19272
|
-
function
|
|
19273
|
-
|
|
19274
|
-
|
|
19275
|
-
|
|
19276
|
-
|
|
19277
|
-
|
|
19360
|
+
function normalizeToolCallDto(toolCall, options = {}) {
|
|
19361
|
+
const includePreview = options.includePreview ?? true;
|
|
19362
|
+
if ("argumentKeys" in toolCall) {
|
|
19363
|
+
return includePreview ? toolCall : stripToolCallPreviews(toolCall);
|
|
19364
|
+
}
|
|
19365
|
+
const hasResult = hasToolCallResult(toolCall.result);
|
|
19366
|
+
const resultSummary = includePreview && hasResult ? summarizeToolCallResult(toolCall.name, toolCall.result) : void 0;
|
|
19367
|
+
const diagnostic = toolCall.error === void 0 && resultSummary ? { outcome: resultSummary.outcome } : classifyToolCallOutcome(toolCall.name, toolCall.result, toolCall.error, {
|
|
19368
|
+
status: toolCall.errorStatus,
|
|
19369
|
+
code: toolCall.errorCode
|
|
19370
|
+
});
|
|
19371
|
+
return {
|
|
19372
|
+
id: toolCall.id,
|
|
19373
|
+
name: toolCall.name,
|
|
19374
|
+
argumentKeys: summarizeToolCallArgumentKeys(toolCall.arguments),
|
|
19375
|
+
hasResult,
|
|
19376
|
+
hasError: toolCall.error !== void 0,
|
|
19377
|
+
outcome: diagnostic.outcome,
|
|
19378
|
+
...diagnostic.errorCategory ? { errorCategory: diagnostic.errorCategory } : {},
|
|
19379
|
+
...resultSummary ? { resultPreview: resultSummary.preview } : {},
|
|
19380
|
+
...includePreview && toolCall.error !== void 0 ? { errorPreview: summarizeToolCallPayloadPreview(toolCall.error) } : {},
|
|
19381
|
+
timestamp: toolCall.timestamp
|
|
19382
|
+
};
|
|
19278
19383
|
}
|
|
19279
|
-
function
|
|
19280
|
-
|
|
19281
|
-
|
|
19384
|
+
function hasToolCallResult(result) {
|
|
19385
|
+
return result !== void 0 && result !== null && result !== "null";
|
|
19386
|
+
}
|
|
19387
|
+
function stripToolCallPreviews(toolCall) {
|
|
19388
|
+
const { resultPreview: _resultPreview, errorPreview: _errorPreview, ...withoutPreview } = toolCall;
|
|
19389
|
+
return withoutPreview;
|
|
19390
|
+
}
|
|
19391
|
+
function truncateToolCallPreview(preview) {
|
|
19392
|
+
return truncate(preview, MAX_TOOL_CALL_PREVIEW_LENGTH);
|
|
19393
|
+
}
|
|
19394
|
+
function truncateToolCallEntity(entity) {
|
|
19395
|
+
return truncate(entity, MAX_TOOL_CALL_ENTITY_LENGTH);
|
|
19396
|
+
}
|
|
19397
|
+
function truncate(value, maxLength) {
|
|
19398
|
+
return value.length <= maxLength ? value : `${value.slice(0, maxLength - 1)}\u2026`;
|
|
19399
|
+
}
|
|
19400
|
+
function escapeRegExp(value) {
|
|
19401
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
19402
|
+
}
|
|
19403
|
+
function getPrimitivePayloadType(payload) {
|
|
19404
|
+
if (payload === null) {
|
|
19405
|
+
return "Null";
|
|
19282
19406
|
}
|
|
19283
|
-
|
|
19284
|
-
|
|
19407
|
+
switch (typeof payload) {
|
|
19408
|
+
case "boolean":
|
|
19409
|
+
return "Boolean";
|
|
19410
|
+
case "number":
|
|
19411
|
+
return "Number";
|
|
19412
|
+
case "bigint":
|
|
19413
|
+
return "BigInt";
|
|
19414
|
+
default:
|
|
19415
|
+
return "Value";
|
|
19285
19416
|
}
|
|
19286
|
-
|
|
19287
|
-
|
|
19288
|
-
|
|
19289
|
-
|
|
19290
|
-
|
|
19291
|
-
return false;
|
|
19292
|
-
const propertySchema = properties[currentProperty];
|
|
19293
|
-
if (!propertySchema || typeof propertySchema !== "object") {
|
|
19294
|
-
return false;
|
|
19417
|
+
}
|
|
19418
|
+
function classifyToolCallError(_error, { status, code }) {
|
|
19419
|
+
const statusCategory = status === void 0 ? void 0 : classifyToolCallHttpStatus(status);
|
|
19420
|
+
if (statusCategory) {
|
|
19421
|
+
return statusCategory;
|
|
19295
19422
|
}
|
|
19296
|
-
|
|
19297
|
-
|
|
19423
|
+
const codeCategory = code === void 0 ? void 0 : classifyToolCallErrorCode(code);
|
|
19424
|
+
if (codeCategory) {
|
|
19425
|
+
return codeCategory;
|
|
19298
19426
|
}
|
|
19299
|
-
return
|
|
19427
|
+
return "unknown";
|
|
19300
19428
|
}
|
|
19301
|
-
function
|
|
19302
|
-
if (
|
|
19303
|
-
return
|
|
19304
|
-
if (
|
|
19305
|
-
return
|
|
19306
|
-
|
|
19307
|
-
|
|
19308
|
-
|
|
19309
|
-
|
|
19310
|
-
if (
|
|
19429
|
+
function classifyToolCallHttpStatus(status) {
|
|
19430
|
+
if (status === 401)
|
|
19431
|
+
return "authentication";
|
|
19432
|
+
if (status === 403)
|
|
19433
|
+
return "permission";
|
|
19434
|
+
if (status === 429)
|
|
19435
|
+
return "rate-limit";
|
|
19436
|
+
if (status === 400)
|
|
19437
|
+
return "invalid-request";
|
|
19438
|
+
if (status === 408 || status === 504)
|
|
19439
|
+
return "timeout";
|
|
19440
|
+
return void 0;
|
|
19441
|
+
}
|
|
19442
|
+
function classifyToolCallErrorCode(code) {
|
|
19443
|
+
const normalizedCode = code.toUpperCase();
|
|
19444
|
+
if (normalizedCode === "ETIMEDOUT")
|
|
19445
|
+
return "timeout";
|
|
19446
|
+
if (/^(?:ECONN\w*|ENOTFOUND|EAI_AGAIN)$/u.test(normalizedCode))
|
|
19447
|
+
return "connection";
|
|
19448
|
+
return void 0;
|
|
19449
|
+
}
|
|
19450
|
+
function parseJsonPayload(payload) {
|
|
19451
|
+
if (typeof payload !== "string" || payload.length > MAX_TOOL_CALL_RESULT_PARSE_LENGTH || !["{", "[", '"'].includes(payload[0] ?? "") && payload !== "null") {
|
|
19452
|
+
return payload;
|
|
19453
|
+
}
|
|
19454
|
+
let parsed = payload;
|
|
19455
|
+
for (let index = 0; index < 2 && typeof parsed === "string"; index += 1) {
|
|
19456
|
+
try {
|
|
19457
|
+
parsed = JSON.parse(parsed);
|
|
19458
|
+
} catch {
|
|
19459
|
+
break;
|
|
19460
|
+
}
|
|
19461
|
+
}
|
|
19462
|
+
return parsed;
|
|
19463
|
+
}
|
|
19464
|
+
function getTextCollectionSummary(payload, tool) {
|
|
19465
|
+
if (typeof payload !== "string" || tool.action !== "Found") {
|
|
19311
19466
|
return null;
|
|
19312
|
-
|
|
19313
|
-
|
|
19467
|
+
}
|
|
19468
|
+
const match = new RegExp(`\\b(?:found|returned|matching|showing)\\s+(\\d+)\\s+(?:${escapeRegExp(tool.entity)}|${escapeRegExp(pluralize(tool.entity))})\\b`, "iu").exec(payload);
|
|
19469
|
+
if (!match?.[1]) {
|
|
19314
19470
|
return null;
|
|
19315
|
-
|
|
19471
|
+
}
|
|
19472
|
+
const count = Number(match[1]);
|
|
19473
|
+
return Number.isSafeInteger(count) && count >= 0 ? count : null;
|
|
19316
19474
|
}
|
|
19317
|
-
|
|
19318
|
-
|
|
19319
|
-
|
|
19320
|
-
|
|
19321
|
-
|
|
19322
|
-
|
|
19323
|
-
|
|
19324
|
-
|
|
19325
|
-
|
|
19326
|
-
|
|
19327
|
-
|
|
19328
|
-
|
|
19329
|
-
|
|
19330
|
-
|
|
19331
|
-
|
|
19332
|
-
|
|
19333
|
-
|
|
19334
|
-
|
|
19335
|
-
|
|
19336
|
-
|
|
19337
|
-
|
|
19338
|
-
|
|
19339
|
-
|
|
19340
|
-
|
|
19341
|
-
|
|
19342
|
-
|
|
19343
|
-
|
|
19344
|
-
|
|
19345
|
-
|
|
19346
|
-
|
|
19347
|
-
|
|
19348
|
-
|
|
19349
|
-
|
|
19350
|
-
|
|
19351
|
-
|
|
19352
|
-
return
|
|
19475
|
+
function getToolCallDescription(toolName) {
|
|
19476
|
+
const tokens = toolName.slice(toolName.lastIndexOf(".") + 1).toLowerCase().split(/[-_./]/);
|
|
19477
|
+
return {
|
|
19478
|
+
action: getToolCallAction(tokens),
|
|
19479
|
+
entity: getToolCallEntity(tokens)
|
|
19480
|
+
};
|
|
19481
|
+
}
|
|
19482
|
+
function getToolCallAction(tokens) {
|
|
19483
|
+
if (tokens.some((token) => ["find", "search", "list"].includes(token)))
|
|
19484
|
+
return "Found";
|
|
19485
|
+
if (tokens.some((token) => ["get", "read", "retrieve"].includes(token)))
|
|
19486
|
+
return "Retrieved";
|
|
19487
|
+
if (tokens.some((token) => ["add", "create"].includes(token)))
|
|
19488
|
+
return "Created";
|
|
19489
|
+
if (tokens.some((token) => ["update", "edit", "modify"].includes(token)))
|
|
19490
|
+
return "Updated";
|
|
19491
|
+
if (tokens.some((token) => ["delete", "remove"].includes(token)))
|
|
19492
|
+
return "Deleted";
|
|
19493
|
+
if (tokens.some((token) => ["uncomplete", "reopen"].includes(token)))
|
|
19494
|
+
return "Reopened";
|
|
19495
|
+
if (tokens.some((token) => ["complete", "close"].includes(token)))
|
|
19496
|
+
return "Completed";
|
|
19497
|
+
if (tokens.includes("archive"))
|
|
19498
|
+
return "Archived";
|
|
19499
|
+
if (tokens.some((token) => ["send", "reply", "post", "publish", "notify"].includes(token)))
|
|
19500
|
+
return "Sent";
|
|
19501
|
+
if (tokens.some((token) => ["copy", "clone", "duplicate"].includes(token)))
|
|
19502
|
+
return "Copied";
|
|
19503
|
+
if (tokens.some((token) => ["move", "transfer"].includes(token)))
|
|
19504
|
+
return "Moved";
|
|
19505
|
+
if (tokens.includes("rename"))
|
|
19506
|
+
return "Renamed";
|
|
19507
|
+
if (tokens.includes("trash"))
|
|
19508
|
+
return "Trashed";
|
|
19509
|
+
if (tokens.some((token) => ["restore", "untrash"].includes(token)))
|
|
19510
|
+
return "Restored";
|
|
19511
|
+
if (tokens.some((token) => ["append", "insert", "replace"].includes(token)))
|
|
19512
|
+
return "Updated";
|
|
19513
|
+
return "Returned";
|
|
19514
|
+
}
|
|
19515
|
+
function getToolCallEntity(tokens) {
|
|
19516
|
+
const actionIndex = tokens.findIndex((token) => TOOL_CALL_ACTION_TOKENS.has(token));
|
|
19517
|
+
const entityTokens = tokens.slice(actionIndex + 1);
|
|
19518
|
+
const qualifierIndex = entityTokens.findIndex((token) => TOOL_CALL_FILLER_TOKENS.has(token));
|
|
19519
|
+
const primaryTokens = qualifierIndex > 0 ? entityTokens.slice(0, qualifierIndex) : entityTokens;
|
|
19520
|
+
const entity = [...primaryTokens].reverse().find((token) => token.length > 1 && !TOOL_CALL_FILLER_TOKENS.has(token));
|
|
19521
|
+
return entity ? truncateToolCallEntity(singularize(entity)) : "item";
|
|
19522
|
+
}
|
|
19523
|
+
var TOOL_CALL_ACTION_TOKENS = /* @__PURE__ */ new Set([
|
|
19524
|
+
"find",
|
|
19525
|
+
"search",
|
|
19526
|
+
"list",
|
|
19527
|
+
"get",
|
|
19528
|
+
"read",
|
|
19529
|
+
"retrieve",
|
|
19530
|
+
"add",
|
|
19531
|
+
"create",
|
|
19532
|
+
"update",
|
|
19533
|
+
"edit",
|
|
19534
|
+
"modify",
|
|
19535
|
+
"delete",
|
|
19536
|
+
"remove",
|
|
19537
|
+
"uncomplete",
|
|
19538
|
+
"reopen",
|
|
19539
|
+
"complete",
|
|
19540
|
+
"close",
|
|
19541
|
+
"archive",
|
|
19542
|
+
"send",
|
|
19543
|
+
"reply",
|
|
19544
|
+
"post",
|
|
19545
|
+
"publish",
|
|
19546
|
+
"notify",
|
|
19547
|
+
"copy",
|
|
19548
|
+
"clone",
|
|
19549
|
+
"duplicate",
|
|
19550
|
+
"move",
|
|
19551
|
+
"transfer",
|
|
19552
|
+
"rename",
|
|
19553
|
+
"trash",
|
|
19554
|
+
"restore",
|
|
19555
|
+
"untrash",
|
|
19556
|
+
"append",
|
|
19557
|
+
"insert",
|
|
19558
|
+
"replace"
|
|
19559
|
+
]);
|
|
19560
|
+
var TOOL_CALL_FILLER_TOKENS = /* @__PURE__ */ new Set(["by", "to", "from", "for", "with", "all"]);
|
|
19561
|
+
function getResultCollection(payload, entity) {
|
|
19562
|
+
if (Array.isArray(payload)) {
|
|
19563
|
+
return payload;
|
|
19353
19564
|
}
|
|
19354
|
-
|
|
19355
|
-
|
|
19356
|
-
const dayOfMonth = createCronField("0?[1-9]|[12]\\d|3[01]");
|
|
19357
|
-
const month = createCronField("0?[1-9]|1[0-2]");
|
|
19358
|
-
const dayOfWeek = createCronField("[0-6]");
|
|
19359
|
-
const cronExpressionRegex = new RegExp(`^${minutes}\\s+${hours}\\s+${dayOfMonth}\\s+${month}\\s+${dayOfWeek}$`);
|
|
19360
|
-
const timezoneRegex = new RegExp(`^${timezoneComponent}(?:/${timezoneComponent})*$`);
|
|
19361
|
-
return external_exports.object({
|
|
19362
|
-
timezone: external_exports.string().regex(timezoneRegex, "Must be a valid IANA Time Zone name").meta({
|
|
19363
|
-
description: "IANA Time Zone name (e.g., America/New_York). Required for cron schedules."
|
|
19364
|
-
}),
|
|
19365
|
-
expression: external_exports.string().regex(cronExpressionRegex, "Must be a valid 5-part cron expression").meta({
|
|
19366
|
-
description: "Standard 5-part cron expression (minute hour day month dayOfWeek)"
|
|
19367
|
-
})
|
|
19368
|
-
}).meta({
|
|
19369
|
-
description: "A cron schedule with required timezone"
|
|
19370
|
-
});
|
|
19371
|
-
})();
|
|
19372
|
-
var scheduleValueSchema = external_exports.union([intervalScheduleSchema, cronScheduleSchema]).meta({ description: "The schedule definition for the trigger." });
|
|
19373
|
-
var scheduleTriggerSchema = external_exports.object({
|
|
19374
|
-
type: external_exports.literal("schedule"),
|
|
19375
|
-
value: scheduleValueSchema,
|
|
19376
|
-
description: external_exports.string().optional().meta({ description: "A natural language description of what the trigger does." })
|
|
19377
|
-
});
|
|
19378
|
-
var webhookTriggerSchema = external_exports.object({
|
|
19379
|
-
type: external_exports.literal("webhook"),
|
|
19380
|
-
event: external_exports.string({
|
|
19381
|
-
message: 'Webhook triggers require an "event" field with the event type (e.g., "todoist.item.added").'
|
|
19382
|
-
}).regex(/^[a-z0-9-]+\.[a-z0-9_]+\.[a-z0-9_]+(\.[a-z0-9_]+)*$/, "Event type must be in the format 'connector.entity.action' with exactly 3 required parts, optionally followed by additional segments (e.g., 'todoist.item.added', 'google-calendar.event.created')").meta({
|
|
19383
|
-
description: "The event type to listen for (e.g., 'todoist.item.added', 'gmail.message.new'). This references a specific trigger definition from a connector."
|
|
19384
|
-
}),
|
|
19385
|
-
outputSchema: external_exports.object({
|
|
19386
|
-
type: external_exports.string({
|
|
19387
|
-
message: 'outputSchema must be a valid JSON Schema with a "type" field. Use {"type": "string"} or {"type": "object", ...}.'
|
|
19388
|
-
})
|
|
19389
|
-
}, {
|
|
19390
|
-
message: 'Webhook triggers require an "outputSchema" field describing the trigger payload structure.'
|
|
19391
|
-
}).catchall(external_exports.unknown()).meta({
|
|
19392
|
-
description: "A JSON Schema that describes the structure of the trigger payload."
|
|
19393
|
-
}),
|
|
19394
|
-
inputSchema: external_exports.record(external_exports.string(), external_exports.unknown()).optional().meta({
|
|
19395
|
-
description: "An optional JSON Schema to filter the CloudEvent data field. Only events matching this schema will trigger the automation."
|
|
19396
|
-
}),
|
|
19397
|
-
description: external_exports.string().optional().meta({ description: "A natural language description of what the trigger does." })
|
|
19398
|
-
});
|
|
19399
|
-
var apiTriggerIdSchema = external_exports.string().regex(uuidv7Regex, "API trigger ID must be a valid UUIDv7");
|
|
19400
|
-
var apiTriggerSchema = external_exports.object({
|
|
19401
|
-
type: external_exports.literal("api"),
|
|
19402
|
-
id: apiTriggerIdSchema.optional().meta({
|
|
19403
|
-
description: "A system-generated unique ID for the trigger endpoint (UUIDv7 format). Auto-generated if not provided."
|
|
19404
|
-
}),
|
|
19405
|
-
outputSchema: external_exports.object({
|
|
19406
|
-
type: external_exports.string({
|
|
19407
|
-
message: 'outputSchema must be a valid JSON Schema with a "type" field. Use {"type": "string"} or {"type": "object", ...}.'
|
|
19408
|
-
})
|
|
19409
|
-
}, {
|
|
19410
|
-
message: 'API triggers require an "outputSchema" field describing the trigger payload structure.'
|
|
19411
|
-
}).catchall(external_exports.unknown()).meta({
|
|
19412
|
-
description: "A JSON Schema that describes the structure of the trigger payload."
|
|
19413
|
-
}),
|
|
19414
|
-
inputSchema: external_exports.object({
|
|
19415
|
-
type: external_exports.string({
|
|
19416
|
-
message: 'inputSchema must be a valid JSON Schema with a "type" field. Use {"type": "string"} or {"type": "object", ...}.'
|
|
19417
|
-
})
|
|
19418
|
-
}, {
|
|
19419
|
-
message: 'API triggers with input validation require an "inputSchema" field to validate incoming request payloads.'
|
|
19420
|
-
}).catchall(external_exports.unknown()).optional().meta({
|
|
19421
|
-
description: "Optional JSON Schema to validate incoming request payloads."
|
|
19422
|
-
}),
|
|
19423
|
-
description: external_exports.string().optional().meta({ description: "A natural language description of what the trigger does." })
|
|
19424
|
-
});
|
|
19425
|
-
var triggerSchema = external_exports.discriminatedUnion("type", [scheduleTriggerSchema, webhookTriggerSchema, apiTriggerSchema], {
|
|
19426
|
-
message: 'Invalid trigger configuration. Schedule triggers need "value", webhook triggers need "event" and "outputSchema", API triggers need "outputSchema" (and optionally "id" and "inputSchema" for advanced features). Use the correct fields for your trigger type.'
|
|
19427
|
-
}).meta({ description: "Defines the event that initiates an automation run." });
|
|
19428
|
-
function validateTriggersConstraints(triggers, ctx) {
|
|
19429
|
-
if (triggers.length === 0)
|
|
19430
|
-
return;
|
|
19431
|
-
const types = new Set(triggers.map((t) => t.type));
|
|
19432
|
-
if (types.size > 1) {
|
|
19433
|
-
ctx.addIssue({
|
|
19434
|
-
code: external_exports.ZodIssueCode.custom,
|
|
19435
|
-
message: "All triggers must be the same type. Cannot mix schedule, webhook, and api triggers."
|
|
19436
|
-
});
|
|
19437
|
-
return;
|
|
19565
|
+
if (!isRecord(payload)) {
|
|
19566
|
+
return null;
|
|
19438
19567
|
}
|
|
19439
|
-
const
|
|
19440
|
-
|
|
19441
|
-
|
|
19442
|
-
|
|
19443
|
-
|
|
19444
|
-
|
|
19445
|
-
return;
|
|
19568
|
+
const collection = payload[entity] ?? payload[pluralize(entity)] ?? payload[`${entity}s`] ?? payload.items ?? payload.data ?? payload.results ?? payload.value;
|
|
19569
|
+
return Array.isArray(collection) ? collection : null;
|
|
19570
|
+
}
|
|
19571
|
+
function getProjectCount(items, entity) {
|
|
19572
|
+
if (entity !== "task") {
|
|
19573
|
+
return 0;
|
|
19446
19574
|
}
|
|
19447
|
-
|
|
19448
|
-
|
|
19449
|
-
|
|
19450
|
-
|
|
19451
|
-
ctx.addIssue({
|
|
19452
|
-
code: external_exports.ZodIssueCode.custom,
|
|
19453
|
-
message: `All webhook triggers must be from the same connector. Found: ${[...connectors].join(", ")}.`
|
|
19454
|
-
});
|
|
19455
|
-
return;
|
|
19575
|
+
const projectIds = /* @__PURE__ */ new Set();
|
|
19576
|
+
for (const item of items) {
|
|
19577
|
+
if (!isRecord(item)) {
|
|
19578
|
+
continue;
|
|
19456
19579
|
}
|
|
19457
|
-
const
|
|
19458
|
-
if (
|
|
19459
|
-
|
|
19460
|
-
code: external_exports.ZodIssueCode.custom,
|
|
19461
|
-
message: `Duplicate trigger events are not allowed: ${[...new Set(duplicateEvents)].join(", ")}.`
|
|
19462
|
-
});
|
|
19580
|
+
const projectId = item.projectId ?? item.project_id;
|
|
19581
|
+
if (typeof projectId === "string" || typeof projectId === "number") {
|
|
19582
|
+
projectIds.add(String(projectId));
|
|
19463
19583
|
}
|
|
19464
19584
|
}
|
|
19585
|
+
return projectIds.size;
|
|
19465
19586
|
}
|
|
19466
|
-
|
|
19467
|
-
|
|
19468
|
-
}
|
|
19469
|
-
|
|
19470
|
-
|
|
19471
|
-
|
|
19472
|
-
}
|
|
19473
|
-
|
|
19474
|
-
|
|
19475
|
-
|
|
19476
|
-
|
|
19477
|
-
|
|
19478
|
-
}
|
|
19479
|
-
|
|
19480
|
-
}
|
|
19481
|
-
|
|
19482
|
-
|
|
19483
|
-
|
|
19484
|
-
}
|
|
19485
|
-
|
|
19486
|
-
|
|
19487
|
-
|
|
19488
|
-
|
|
19489
|
-
|
|
19490
|
-
|
|
19491
|
-
|
|
19587
|
+
function formatEntity(entity, count) {
|
|
19588
|
+
return count === 1 ? entity : pluralize(entity);
|
|
19589
|
+
}
|
|
19590
|
+
function singularize(value) {
|
|
19591
|
+
if (value === "people") {
|
|
19592
|
+
return "person";
|
|
19593
|
+
}
|
|
19594
|
+
if (value.endsWith("ies")) {
|
|
19595
|
+
return `${value.slice(0, -3)}y`;
|
|
19596
|
+
}
|
|
19597
|
+
if (value.endsWith("ses") || value.endsWith("xes") || value.endsWith("ches") || value.endsWith("shes")) {
|
|
19598
|
+
return value.slice(0, -2);
|
|
19599
|
+
}
|
|
19600
|
+
return value.endsWith("s") ? value.slice(0, -1) : value;
|
|
19601
|
+
}
|
|
19602
|
+
function pluralize(value) {
|
|
19603
|
+
if (value === "person") {
|
|
19604
|
+
return "people";
|
|
19605
|
+
}
|
|
19606
|
+
if (value.endsWith("y")) {
|
|
19607
|
+
return `${value.slice(0, -1)}ies`;
|
|
19608
|
+
}
|
|
19609
|
+
return value.endsWith("s") ? `${value}es` : `${value}s`;
|
|
19610
|
+
}
|
|
19611
|
+
function isRecord(value) {
|
|
19612
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
19613
|
+
}
|
|
19614
|
+
|
|
19615
|
+
// ../../packages/core/dist/esm/schemas/admin-reliability.schema.js
|
|
19616
|
+
var MAX_RELIABILITY_WINDOW_DAYS = 90;
|
|
19617
|
+
var MAX_RELIABILITY_WINDOW_MS = MAX_RELIABILITY_WINDOW_DAYS * 24 * 60 * 60 * 1e3;
|
|
19618
|
+
var adminReliabilityQuerySchema = external_exports.object({
|
|
19619
|
+
since: isoDateTimeOrDateQueryParamSchema.optional(),
|
|
19620
|
+
until: isoDateTimeOrDateQueryParamSchema.optional()
|
|
19621
|
+
}).refine((query) => {
|
|
19622
|
+
if (isEmptyRunDateRange(query))
|
|
19623
|
+
return false;
|
|
19624
|
+
const { since, until } = resolveRunDateRange(query);
|
|
19625
|
+
if (!since)
|
|
19626
|
+
return true;
|
|
19627
|
+
const rangeEnd = until ?? /* @__PURE__ */ new Date();
|
|
19628
|
+
return rangeEnd.getTime() - since.getTime() <= MAX_RELIABILITY_WINDOW_MS;
|
|
19629
|
+
}, {
|
|
19630
|
+
path: ["since"],
|
|
19631
|
+
message: `Date range must be at most ${MAX_RELIABILITY_WINDOW_DAYS} days`
|
|
19632
|
+
});
|
|
19633
|
+
var adminReliabilityTotalsSchema = external_exports.object({
|
|
19634
|
+
totalAutomations: external_exports.number(),
|
|
19635
|
+
enabledAutomations: external_exports.number(),
|
|
19636
|
+
totalLiveRuns: external_exports.number(),
|
|
19637
|
+
terminalLiveRuns: external_exports.number(),
|
|
19638
|
+
completedLiveRuns: external_exports.number(),
|
|
19639
|
+
failedLiveRuns: external_exports.number(),
|
|
19640
|
+
insufficientCreditFailures: external_exports.number(),
|
|
19641
|
+
reliabilityFailures: external_exports.number(),
|
|
19642
|
+
failureRate: external_exports.number(),
|
|
19643
|
+
reliabilityFailureRate: external_exports.number()
|
|
19644
|
+
});
|
|
19645
|
+
var adminReliabilityFailureCategorySchema = external_exports.object({
|
|
19646
|
+
category: external_exports.enum(FAILURE_CATEGORIES).nullable(),
|
|
19647
|
+
failures: external_exports.number(),
|
|
19648
|
+
shareOfFailedRuns: external_exports.number(),
|
|
19649
|
+
shareOfTerminalRuns: external_exports.number(),
|
|
19650
|
+
includedInReliabilityRate: external_exports.boolean()
|
|
19651
|
+
});
|
|
19652
|
+
var adminReliabilityDailyRowSchema = external_exports.object({
|
|
19653
|
+
date: external_exports.iso.date(),
|
|
19654
|
+
terminalLiveRuns: external_exports.number(),
|
|
19655
|
+
completedLiveRuns: external_exports.number(),
|
|
19656
|
+
failedLiveRuns: external_exports.number(),
|
|
19657
|
+
insufficientCreditFailures: external_exports.number(),
|
|
19658
|
+
reliabilityFailures: external_exports.number(),
|
|
19659
|
+
reliabilityFailureRate: external_exports.number()
|
|
19660
|
+
});
|
|
19661
|
+
var adminReliabilityResponseSchema = external_exports.object({
|
|
19662
|
+
since: external_exports.iso.datetime({ offset: true }),
|
|
19663
|
+
until: external_exports.iso.datetime({ offset: true }),
|
|
19664
|
+
totals: adminReliabilityTotalsSchema,
|
|
19665
|
+
failureCategories: external_exports.array(adminReliabilityFailureCategorySchema),
|
|
19666
|
+
daily: external_exports.array(adminReliabilityDailyRowSchema)
|
|
19492
19667
|
});
|
|
19493
|
-
|
|
19494
|
-
|
|
19668
|
+
|
|
19669
|
+
// ../../packages/core/dist/esm/schemas/connector.schema.js
|
|
19670
|
+
var TriggerSupportedEventSchema = external_exports.object({
|
|
19671
|
+
id: external_exports.string(),
|
|
19672
|
+
name: external_exports.string(),
|
|
19673
|
+
description: external_exports.string()
|
|
19495
19674
|
});
|
|
19496
|
-
var
|
|
19497
|
-
|
|
19675
|
+
var ConnectorCapabilitiesSchema = external_exports.object({
|
|
19676
|
+
mcp: external_exports.object({
|
|
19677
|
+
serverUrl: external_exports.string(),
|
|
19678
|
+
scopes: external_exports.array(external_exports.string()),
|
|
19679
|
+
connectionIds: external_exports.array(external_exports.string())
|
|
19680
|
+
}).optional(),
|
|
19681
|
+
triggers: external_exports.object({
|
|
19682
|
+
scopes: external_exports.array(external_exports.string()),
|
|
19683
|
+
connectionIds: external_exports.array(external_exports.string()),
|
|
19684
|
+
supportedEvents: external_exports.array(TriggerSupportedEventSchema)
|
|
19685
|
+
}).optional()
|
|
19498
19686
|
});
|
|
19499
|
-
var
|
|
19500
|
-
id:
|
|
19501
|
-
|
|
19502
|
-
description: external_exports.string()
|
|
19503
|
-
|
|
19504
|
-
|
|
19505
|
-
|
|
19506
|
-
|
|
19507
|
-
|
|
19508
|
-
|
|
19509
|
-
|
|
19687
|
+
var ConnectorSchema = external_exports.object({
|
|
19688
|
+
id: external_exports.string(),
|
|
19689
|
+
name: external_exports.string(),
|
|
19690
|
+
description: external_exports.string(),
|
|
19691
|
+
iconUrl: external_exports.url().nullable().optional(),
|
|
19692
|
+
capabilities: ConnectorCapabilitiesSchema,
|
|
19693
|
+
/** Whether this connector has any user account setup flow. */
|
|
19694
|
+
requiresConnection: external_exports.boolean(),
|
|
19695
|
+
/**
|
|
19696
|
+
* Whether the connector is a product-owned built-in service. This is
|
|
19697
|
+
* independent from whether a third-party connector requires account setup.
|
|
19698
|
+
*/
|
|
19699
|
+
isSystem: external_exports.boolean().optional(),
|
|
19700
|
+
/**
|
|
19701
|
+
* Managed connectors (e.g. WhatsApp) share a single linked identity across
|
|
19702
|
+
* connection types — one onboarding covers both action and trigger uses.
|
|
19703
|
+
* The FE collapses per-type rows into a single account when this is true.
|
|
19704
|
+
*/
|
|
19705
|
+
isManaged: external_exports.boolean().optional()
|
|
19510
19706
|
});
|
|
19511
|
-
var
|
|
19512
|
-
|
|
19513
|
-
"gemini-2.5-flash",
|
|
19514
|
-
"gemini-3.1-pro",
|
|
19515
|
-
"claude-haiku-4-5",
|
|
19516
|
-
"claude-sonnet-4-6"
|
|
19517
|
-
];
|
|
19518
|
-
var DEFAULT_LLM_MODEL = "claude-haiku-4-5";
|
|
19519
|
-
var llmStepSchema = baseStepSchema.merge(external_exports.object({
|
|
19520
|
-
type: external_exports.literal("llm"),
|
|
19521
|
-
prompt: external_exports.string().meta({ description: "The prompt template to be sent to the LLM." }),
|
|
19522
|
-
outputSchema: stepOutputSchema,
|
|
19523
|
-
model: external_exports.enum(SUPPORTED_LLM_MODELS).meta({
|
|
19524
|
-
description: `The specific model to use. Supported models: ${SUPPORTED_LLM_MODELS.join(", ")}.`
|
|
19525
|
-
}),
|
|
19526
|
-
tools: external_exports.record(external_exports.string(), external_exports.array(external_exports.string())).default({}).meta({
|
|
19527
|
-
description: 'A mapping from MCP server connector IDs to arrays of their tool names (e.g., {"todoist": ["find-tasks-by-date"], "linear": ["create-issue"]}).'
|
|
19528
|
-
})
|
|
19529
|
-
})).strict();
|
|
19530
|
-
var codegenStepSchema = baseStepSchema.merge(external_exports.object({
|
|
19531
|
-
type: external_exports.literal("codegen"),
|
|
19532
|
-
prompt: external_exports.string().meta({
|
|
19533
|
-
description: "The goal or instruction for what the generated code should accomplish."
|
|
19534
|
-
}),
|
|
19535
|
-
outputSchema: stepOutputSchema,
|
|
19536
|
-
model: external_exports.enum(SUPPORTED_LLM_MODELS).meta({
|
|
19537
|
-
description: `The specific model to use for code generation. Supported models: ${SUPPORTED_LLM_MODELS.join(", ")}.`
|
|
19538
|
-
}),
|
|
19539
|
-
tools: external_exports.record(external_exports.string(), external_exports.array(external_exports.string())).default({}).meta({
|
|
19540
|
-
description: 'A mapping from MCP server connector IDs to arrays of their tool names that will be available in the generated code (e.g., {"todoist": ["find-tasks", "update-tasks"]}).'
|
|
19541
|
-
}),
|
|
19542
|
-
extractedUrls: external_exports.array(external_exports.url()).optional().meta({
|
|
19543
|
-
description: "URLs that will be fetched during step execution (auto-extracted from prompt examples)"
|
|
19544
|
-
})
|
|
19545
|
-
}));
|
|
19546
|
-
var runtimeSchema = external_exports.object({
|
|
19547
|
-
language: external_exports.literal("typescript").meta({
|
|
19548
|
-
description: "Programming language. Only 'typescript' is supported in v0."
|
|
19549
|
-
}),
|
|
19550
|
-
version: external_exports.enum(SUPPORTED_RUNTIME_VERSIONS).meta({
|
|
19551
|
-
description: "Language specification version. Supported values: '5.9', '6.0'."
|
|
19552
|
-
})
|
|
19553
|
-
}).meta({
|
|
19554
|
-
description: "Defines the execution environment for the code step."
|
|
19707
|
+
var GetConnectorsQuerySchema = external_exports.object({
|
|
19708
|
+
query: external_exports.string().optional()
|
|
19555
19709
|
});
|
|
19556
|
-
var
|
|
19557
|
-
|
|
19558
|
-
|
|
19559
|
-
|
|
19560
|
-
|
|
19561
|
-
}),
|
|
19562
|
-
code: external_exports.string().meta({
|
|
19563
|
-
description: "The code to execute. It has access to trigger and steps objects."
|
|
19564
|
-
}),
|
|
19565
|
-
extractedUrls: external_exports.array(external_exports.url()).optional().meta({
|
|
19566
|
-
description: "URLs that will be fetched during step execution (auto-extracted from code)"
|
|
19567
|
-
})
|
|
19568
|
-
}));
|
|
19569
|
-
var searchStepSchema = baseStepSchema.merge(external_exports.object({
|
|
19570
|
-
type: external_exports.literal("search"),
|
|
19571
|
-
prompt: external_exports.string().min(1).meta({
|
|
19572
|
-
description: "The search prompt to execute using web search."
|
|
19573
|
-
}),
|
|
19574
|
-
outputSchema: searchStepOutputSchema,
|
|
19575
|
-
model: external_exports.enum(SUPPORTED_LLM_MODELS).optional().meta({
|
|
19576
|
-
description: `The specific model to use for processing search results. Defaults to ${DEFAULT_LLM_MODEL}.`
|
|
19577
|
-
})
|
|
19578
|
-
}));
|
|
19579
|
-
var delayStepOutputSchema = external_exports.object({
|
|
19580
|
-
type: external_exports.literal("object").meta({
|
|
19581
|
-
description: 'Must be "object" for delay steps.'
|
|
19582
|
-
})
|
|
19583
|
-
}).catchall(external_exports.unknown()).meta({
|
|
19584
|
-
description: 'JSON Schema for delay step output. Must include {"type": "object"}.'
|
|
19710
|
+
var connectorDetailsSchema = external_exports.object({
|
|
19711
|
+
name: external_exports.string(),
|
|
19712
|
+
displayName: external_exports.string(),
|
|
19713
|
+
description: external_exports.string(),
|
|
19714
|
+
iconUrl: external_exports.string().nullable().optional()
|
|
19585
19715
|
});
|
|
19586
|
-
var
|
|
19587
|
-
|
|
19588
|
-
|
|
19589
|
-
duration: durationStringSchema.meta({
|
|
19590
|
-
description: "Duration to delay the execution for as a duration string, e.g., '1d', '1w', '2h'."
|
|
19591
|
-
}),
|
|
19592
|
-
outputSchema: delayStepOutputSchema
|
|
19593
|
-
})).strict();
|
|
19594
|
-
var baseAskStepSchema = baseStepSchema.omit({ execution: true });
|
|
19595
|
-
var askExpiresAfterSchema = durationStringSchema.refine((value) => durationStringToMilliseconds(value) <= ASK_EXPIRES_AFTER_MAX_MS, {
|
|
19596
|
-
message: "Ask expiresAfter must not exceed 30 days"
|
|
19597
|
-
}).meta({
|
|
19598
|
-
description: "How long to wait for a response before the prompt expires, as a duration string (e.g. '1w'). Defaults to 1w, capped at 30d. On expiry the run terminates."
|
|
19716
|
+
var connectorListResponseSchema = external_exports.object({
|
|
19717
|
+
data: external_exports.array(ConnectorSchema),
|
|
19718
|
+
nextCursor: external_exports.string().nullable()
|
|
19599
19719
|
});
|
|
19600
|
-
|
|
19601
|
-
|
|
19602
|
-
|
|
19603
|
-
|
|
19604
|
-
|
|
19605
|
-
|
|
19606
|
-
|
|
19607
|
-
|
|
19608
|
-
|
|
19609
|
-
|
|
19610
|
-
|
|
19611
|
-
|
|
19612
|
-
|
|
19613
|
-
|
|
19614
|
-
|
|
19615
|
-
|
|
19616
|
-
|
|
19617
|
-
|
|
19618
|
-
|
|
19619
|
-
|
|
19620
|
-
|
|
19720
|
+
|
|
19721
|
+
// ../../packages/core/dist/esm/utils/duration.js
|
|
19722
|
+
var durationUnits = ["ms", "s", "m", "h", "d", "w"];
|
|
19723
|
+
var createDurationPattern = (units) => units.join("|");
|
|
19724
|
+
var durationPattern = createDurationPattern(durationUnits);
|
|
19725
|
+
var durationStringRegex = new RegExp(`^\\d+(${durationPattern})$`);
|
|
19726
|
+
var durationStringWithCaptureRegex = new RegExp(`^(\\d+)(${durationPattern})$`);
|
|
19727
|
+
var intervalScheduleRegex = new RegExp(`^\\d+(${durationPattern})(\\/\\d+(${durationPattern}))?$`);
|
|
19728
|
+
function durationStringToMilliseconds(value) {
|
|
19729
|
+
const match = value.match(durationStringWithCaptureRegex);
|
|
19730
|
+
if (!match) {
|
|
19731
|
+
throw new Error(`Invalid duration string: ${value}`);
|
|
19732
|
+
}
|
|
19733
|
+
const [, rawAmount, rawUnit] = match;
|
|
19734
|
+
const multiplierMap = {
|
|
19735
|
+
ms: 1,
|
|
19736
|
+
s: 1e3,
|
|
19737
|
+
m: 60 * 1e3,
|
|
19738
|
+
h: 60 * 60 * 1e3,
|
|
19739
|
+
d: 24 * 60 * 60 * 1e3,
|
|
19740
|
+
w: 7 * 24 * 60 * 60 * 1e3
|
|
19741
|
+
};
|
|
19742
|
+
const multiplier = multiplierMap[rawUnit];
|
|
19743
|
+
if (multiplier === void 0) {
|
|
19744
|
+
throw new Error(`Invalid duration unit in string: ${value}`);
|
|
19745
|
+
}
|
|
19746
|
+
return Number.parseInt(rawAmount, 10) * multiplier;
|
|
19747
|
+
}
|
|
19748
|
+
|
|
19749
|
+
// ../../packages/core/dist/esm/utils/if-condition.js
|
|
19750
|
+
var ifConditionReferencePattern = "(?:steps\\.[a-zA-Z][a-zA-Z0-9]*(?:\\.[a-zA-Z_]\\w*)*|trigger(?:\\.[a-zA-Z_]\\w*)+)";
|
|
19751
|
+
var ifConditionRegex = new RegExp(`^\\{\\{\\s*${ifConditionReferencePattern}\\s*\\}\\}\\s*(?:==|!=)\\s*'[^']*'$`);
|
|
19752
|
+
function isWord(segment, { underscore }) {
|
|
19753
|
+
if (segment.length === 0)
|
|
19754
|
+
return false;
|
|
19755
|
+
for (let index = 0; index < segment.length; index++) {
|
|
19756
|
+
const char = segment[index];
|
|
19757
|
+
const isAlpha = char >= "a" && char <= "z" || char >= "A" && char <= "Z";
|
|
19758
|
+
const isDigit = char >= "0" && char <= "9";
|
|
19759
|
+
const isUnderscore = underscore && char === "_";
|
|
19760
|
+
if (index === 0) {
|
|
19761
|
+
if (!isAlpha && !isUnderscore)
|
|
19762
|
+
return false;
|
|
19763
|
+
} else if (!isAlpha && !isDigit && !isUnderscore) {
|
|
19764
|
+
return false;
|
|
19621
19765
|
}
|
|
19622
|
-
seen.add(value);
|
|
19623
19766
|
}
|
|
19624
|
-
|
|
19625
|
-
|
|
19626
|
-
|
|
19627
|
-
|
|
19628
|
-
|
|
19629
|
-
|
|
19630
|
-
|
|
19631
|
-
|
|
19632
|
-
|
|
19633
|
-
|
|
19634
|
-
type: external_exports.literal("ask"),
|
|
19635
|
-
message: external_exports.string().min(1).meta({
|
|
19636
|
-
description: 'The short headline shown to the user, e.g. "Archive or delete 3 inactive projects?".'
|
|
19637
|
-
}),
|
|
19638
|
-
details: external_exports.string().optional().meta({
|
|
19639
|
-
description: "Optional longer markdown context, e.g. a preview of what each option would do."
|
|
19640
|
-
}),
|
|
19641
|
-
options: askOptionsSchema,
|
|
19642
|
-
expiresAfter: askExpiresAfterSchema.optional().default(ASK_EXPIRES_AFTER_DEFAULT),
|
|
19643
|
-
outputSchema: askStepOutputSchema
|
|
19644
|
-
})).strict();
|
|
19645
|
-
var stepSchema = external_exports.discriminatedUnion("type", [
|
|
19646
|
-
llmStepSchema,
|
|
19647
|
-
codegenStepSchema,
|
|
19648
|
-
codeStepSchema,
|
|
19649
|
-
searchStepSchema,
|
|
19650
|
-
delayStepSchema,
|
|
19651
|
-
askStepSchema
|
|
19652
|
-
]);
|
|
19653
|
-
var MANIFEST_VERSIONS = [0, 1];
|
|
19654
|
-
var CURRENT_MANIFEST_VERSION = MANIFEST_VERSIONS[MANIFEST_VERSIONS.length - 1];
|
|
19655
|
-
var manifestVersionSchema = (() => {
|
|
19656
|
-
const [firstVersion, ...otherVersions] = MANIFEST_VERSIONS;
|
|
19657
|
-
let schema = external_exports.literal(firstVersion);
|
|
19658
|
-
for (const version2 of otherVersions) {
|
|
19659
|
-
schema = schema.or(external_exports.literal(version2));
|
|
19767
|
+
return true;
|
|
19768
|
+
}
|
|
19769
|
+
function isValidReference(reference) {
|
|
19770
|
+
const parts = reference.split(".");
|
|
19771
|
+
const [head, ...rest] = parts;
|
|
19772
|
+
if (head === "steps") {
|
|
19773
|
+
const [id, ...segments] = rest;
|
|
19774
|
+
if (id === void 0 || !isWord(id, { underscore: false }))
|
|
19775
|
+
return false;
|
|
19776
|
+
return segments.every((segment) => isWord(segment, { underscore: true }));
|
|
19660
19777
|
}
|
|
19661
|
-
|
|
19662
|
-
|
|
19663
|
-
|
|
19664
|
-
});
|
|
19665
|
-
var manifestSchemaBase = external_exports.object({
|
|
19666
|
-
manifestVersion: manifestVersionSchema,
|
|
19667
|
-
name: external_exports.string().min(1).meta({
|
|
19668
|
-
description: "A human-readable name for the automation that can include spaces."
|
|
19669
|
-
}),
|
|
19670
|
-
description: external_exports.string().meta({ description: "A human-readable description of the automation's purpose." }),
|
|
19671
|
-
triggers: triggersSchema,
|
|
19672
|
-
overlap: external_exports.enum([
|
|
19673
|
-
"skip",
|
|
19674
|
-
"buffer_one",
|
|
19675
|
-
"buffer_all",
|
|
19676
|
-
"cancel_other",
|
|
19677
|
-
"terminate_other",
|
|
19678
|
-
"allow_all"
|
|
19679
|
-
]).optional().default("skip").meta({
|
|
19680
|
-
description: 'Defines policy for overlapping runs. Defaults to "skip".'
|
|
19681
|
-
}),
|
|
19682
|
-
execution: executionPolicySchema.optional().meta({ description: "Global defaults for timeout and retry behavior." }),
|
|
19683
|
-
resultFrom: resultFromSchema.optional(),
|
|
19684
|
-
steps: external_exports.array(stepSchema).nonempty().meta({ description: "An ordered array of step objects that define the workflow." })
|
|
19685
|
-
}).meta({ description: "The root schema for an Automation Manifest, defining its behavior." });
|
|
19686
|
-
var manifestSchema = manifestSchemaBase.superRefine(validateManifestResultFrom).superRefine(validateManifestTemplateVariables).superRefine(validateManifestAskOverlap).superRefine(validateManifestAskChoiceEnum);
|
|
19687
|
-
var partialManifestSchema = manifestSchemaBase.partial().extend({
|
|
19688
|
-
// Override steps to allow empty array for drafts (remove .nonempty() requirement)
|
|
19689
|
-
steps: external_exports.array(stepSchema).default([]),
|
|
19690
|
-
// Override triggers to allow empty array for drafts (remove .nonempty() but keep invariants)
|
|
19691
|
-
triggers: external_exports.array(triggerSchema).superRefine(validateTriggersConstraints).optional()
|
|
19692
|
-
}).required({
|
|
19693
|
-
manifestVersion: true,
|
|
19694
|
-
steps: true
|
|
19695
|
-
});
|
|
19696
|
-
var templateVariableRegex = /\{\{\s*[\w.]+\s*\}\}/g;
|
|
19697
|
-
var codeStepReferenceRegex = /\bsteps\.([a-zA-Z][a-zA-Z0-9]*)(?:\.([a-zA-Z_][\w.]*))?/g;
|
|
19698
|
-
var backtickStepReferenceRegex = /`steps\.([a-zA-Z][a-zA-Z0-9]*)(?:\.([a-zA-Z_][\w.]*))?`/g;
|
|
19699
|
-
function extractStepReferences(text, regex) {
|
|
19700
|
-
const references = [];
|
|
19701
|
-
for (const match of text.matchAll(regex)) {
|
|
19702
|
-
const stepId = match[1];
|
|
19703
|
-
if (!stepId)
|
|
19704
|
-
continue;
|
|
19705
|
-
const propertyPathStr = match[2];
|
|
19706
|
-
const propertyPath = propertyPathStr ? propertyPathStr.split(".") : [];
|
|
19707
|
-
references.push({ stepId, propertyPath });
|
|
19778
|
+
if (head === "trigger") {
|
|
19779
|
+
if (rest.length === 0)
|
|
19780
|
+
return false;
|
|
19781
|
+
return rest.every((segment) => isWord(segment, { underscore: true }));
|
|
19708
19782
|
}
|
|
19709
|
-
return
|
|
19783
|
+
return false;
|
|
19710
19784
|
}
|
|
19711
|
-
function
|
|
19712
|
-
if (
|
|
19785
|
+
function parseIfCondition(condition) {
|
|
19786
|
+
if (!condition.startsWith("{{"))
|
|
19787
|
+
return null;
|
|
19788
|
+
const closeIndex = condition.indexOf("}}");
|
|
19789
|
+
if (closeIndex === -1)
|
|
19790
|
+
return null;
|
|
19791
|
+
const reference = condition.slice(2, closeIndex).trim();
|
|
19792
|
+
if (!isValidReference(reference))
|
|
19793
|
+
return null;
|
|
19794
|
+
const afterReference = condition.slice(closeIndex + 2).trimStart();
|
|
19795
|
+
const operator = afterReference.startsWith("==") ? "==" : afterReference.startsWith("!=") ? "!=" : null;
|
|
19796
|
+
if (!operator)
|
|
19797
|
+
return null;
|
|
19798
|
+
const afterOperator = afterReference.slice(2).trimStart();
|
|
19799
|
+
if (afterOperator.length < 2 || !afterOperator.startsWith("'") || !afterOperator.endsWith("'")) {
|
|
19713
19800
|
return null;
|
|
19714
19801
|
}
|
|
19715
|
-
|
|
19802
|
+
const literal2 = afterOperator.slice(1, -1);
|
|
19803
|
+
if (literal2.includes("'"))
|
|
19804
|
+
return null;
|
|
19805
|
+
return { reference, operator, literal: literal2 };
|
|
19716
19806
|
}
|
|
19717
|
-
|
|
19718
|
-
|
|
19719
|
-
|
|
19720
|
-
|
|
19721
|
-
const guardError = validateGuardReference({
|
|
19722
|
-
stepId,
|
|
19723
|
-
referencedStepId,
|
|
19724
|
-
currentStepGuard,
|
|
19725
|
-
referencedGuard: context.guards.get(referencedStepId),
|
|
19726
|
-
sourceType
|
|
19727
|
-
});
|
|
19728
|
-
if (guardError) {
|
|
19729
|
-
return guardError;
|
|
19730
|
-
}
|
|
19731
|
-
if (propertyPath.length > 0) {
|
|
19732
|
-
const stepOutputSchema2 = context.steps.get(referencedStepId);
|
|
19733
|
-
if (stepOutputSchema2) {
|
|
19734
|
-
const isValid = validatePropertyPathInSchema(stepOutputSchema2, propertyPath);
|
|
19735
|
-
if (!isValid) {
|
|
19736
|
-
return `Step "${stepId}" ${sourceType} references "steps.${referencedStepId}.${propertyPath.join(".")}" but this property path does not exist in step "${referencedStepId}"'s outputSchema.`;
|
|
19737
|
-
}
|
|
19738
|
-
}
|
|
19739
|
-
}
|
|
19740
|
-
return null;
|
|
19807
|
+
|
|
19808
|
+
// ../../packages/core/dist/esm/schemas/manifest.helpers.js
|
|
19809
|
+
function getManifestTriggers(manifest) {
|
|
19810
|
+
return manifest.triggers ?? [];
|
|
19741
19811
|
}
|
|
19742
|
-
function
|
|
19743
|
-
|
|
19744
|
-
|
|
19745
|
-
|
|
19812
|
+
function hasTriggerType(value) {
|
|
19813
|
+
if (!value || typeof value !== "object")
|
|
19814
|
+
return false;
|
|
19815
|
+
const manifest = value;
|
|
19816
|
+
const triggers = getManifestTriggers(manifest);
|
|
19817
|
+
return triggers.length > 0 && typeof triggers[0]?.type === "string";
|
|
19818
|
+
}
|
|
19819
|
+
function isStringTypedSchema(schema) {
|
|
19820
|
+
if (!schema)
|
|
19821
|
+
return false;
|
|
19822
|
+
if (schema === "string")
|
|
19823
|
+
return true;
|
|
19824
|
+
if (typeof schema !== "object" || schema === null)
|
|
19825
|
+
return false;
|
|
19826
|
+
const typedSchema = schema;
|
|
19827
|
+
return typedSchema["type"] === "string";
|
|
19828
|
+
}
|
|
19829
|
+
function isPlainStringSchema(schema) {
|
|
19830
|
+
if (!isStringTypedSchema(schema))
|
|
19831
|
+
return false;
|
|
19832
|
+
if (schema === "string")
|
|
19833
|
+
return true;
|
|
19834
|
+
return Object.keys(schema).length === 1;
|
|
19835
|
+
}
|
|
19836
|
+
function validatePropertyPathInSchema(schema, propertyPath) {
|
|
19837
|
+
if (propertyPath.length === 0) {
|
|
19838
|
+
return true;
|
|
19746
19839
|
}
|
|
19747
|
-
|
|
19748
|
-
|
|
19749
|
-
if (rest.length === 0) {
|
|
19750
|
-
return `Step "${stepId}" ${sourceType} references "{{trigger}}" without a property. Use {{trigger.<property>}} syntax (e.g., {{trigger.payload}}, {{trigger.metadata}}).`;
|
|
19751
|
-
}
|
|
19752
|
-
if (context.triggerType === "schedule" && rest[0] === "payload") {
|
|
19753
|
-
return `Step "${stepId}" references "{{trigger.payload}}" but schedule triggers have no payload. Add a step to fetch the data you need.`;
|
|
19754
|
-
}
|
|
19755
|
-
if (context.triggerType === "schedule" && rest[0] === "user") {
|
|
19756
|
-
if (context.scheduleInjectsTimezone && rest.length === 2 && rest[1] === "timezone") {
|
|
19757
|
-
return null;
|
|
19758
|
-
}
|
|
19759
|
-
return `Step "${stepId}" ${sourceType} references "{{trigger.${rest.join(".")}}}" but schedule triggers only provide "{{trigger.user.timezone}}", and only for cron schedules with a timezone. Interval schedules provide no trigger data.`;
|
|
19760
|
-
}
|
|
19761
|
-
if (context.triggerOutputSchemas.length > 0) {
|
|
19762
|
-
const invalidSchemas = context.triggerOutputSchemas.filter((schema) => !validatePropertyPathInSchema(schema, rest));
|
|
19763
|
-
if (invalidSchemas.length > 0) {
|
|
19764
|
-
return `Step "${stepId}" ${sourceType} references "{{trigger.${rest.join(".")}}}" but this property path does not exist in all trigger outputSchemas. The path must be valid for every trigger since any one may fire the automation.`;
|
|
19765
|
-
}
|
|
19766
|
-
} else {
|
|
19767
|
-
return `Step "${stepId}" ${sourceType} references "{{trigger.${rest.join(".")}}}" but this trigger type has no outputSchema and cannot provide trigger data at runtime.`;
|
|
19768
|
-
}
|
|
19769
|
-
return null;
|
|
19840
|
+
if (!schema.type || schema.type !== "object") {
|
|
19841
|
+
return false;
|
|
19770
19842
|
}
|
|
19771
|
-
|
|
19772
|
-
|
|
19773
|
-
|
|
19774
|
-
|
|
19775
|
-
|
|
19776
|
-
return
|
|
19777
|
-
|
|
19778
|
-
|
|
19779
|
-
|
|
19780
|
-
context,
|
|
19781
|
-
sourceType,
|
|
19782
|
-
currentStepGuard
|
|
19783
|
-
});
|
|
19843
|
+
const properties = schema.properties;
|
|
19844
|
+
if (!properties)
|
|
19845
|
+
return true;
|
|
19846
|
+
const [currentProperty, ...remainingPath] = propertyPath;
|
|
19847
|
+
if (!currentProperty)
|
|
19848
|
+
return false;
|
|
19849
|
+
const propertySchema = properties[currentProperty];
|
|
19850
|
+
if (!propertySchema || typeof propertySchema !== "object") {
|
|
19851
|
+
return false;
|
|
19784
19852
|
}
|
|
19785
|
-
|
|
19786
|
-
|
|
19787
|
-
function extractTemplateVariables(prompt) {
|
|
19788
|
-
const variables = [];
|
|
19789
|
-
for (const match of prompt.matchAll(templateVariableRegex)) {
|
|
19790
|
-
const variable = match[0]?.replace(/\{\{\s*|\s*\}\}/g, "").trim();
|
|
19791
|
-
if (variable) {
|
|
19792
|
-
variables.push(variable);
|
|
19793
|
-
}
|
|
19853
|
+
if (remainingPath.length > 0) {
|
|
19854
|
+
return validatePropertyPathInSchema(propertySchema, remainingPath);
|
|
19794
19855
|
}
|
|
19795
|
-
return
|
|
19856
|
+
return true;
|
|
19796
19857
|
}
|
|
19797
|
-
function
|
|
19798
|
-
if (
|
|
19799
|
-
return
|
|
19800
|
-
|
|
19801
|
-
|
|
19858
|
+
function resolvePropertySchemaInSchema(schema, propertyPath) {
|
|
19859
|
+
if (propertyPath.length === 0)
|
|
19860
|
+
return schema;
|
|
19861
|
+
if (!schema.type || schema.type !== "object")
|
|
19862
|
+
return null;
|
|
19863
|
+
const properties = schema.properties;
|
|
19864
|
+
if (!properties)
|
|
19865
|
+
return null;
|
|
19866
|
+
const [currentProperty, ...remainingPath] = propertyPath;
|
|
19867
|
+
if (!currentProperty)
|
|
19868
|
+
return null;
|
|
19869
|
+
const propertySchema = properties[currentProperty];
|
|
19870
|
+
if (!propertySchema || typeof propertySchema !== "object")
|
|
19871
|
+
return null;
|
|
19872
|
+
return resolvePropertySchemaInSchema(propertySchema, remainingPath);
|
|
19802
19873
|
}
|
|
19803
|
-
|
|
19804
|
-
|
|
19805
|
-
|
|
19806
|
-
|
|
19807
|
-
|
|
19808
|
-
|
|
19809
|
-
|
|
19810
|
-
|
|
19811
|
-
|
|
19812
|
-
|
|
19813
|
-
|
|
19814
|
-
|
|
19815
|
-
|
|
19816
|
-
}
|
|
19817
|
-
}
|
|
19818
|
-
|
|
19819
|
-
|
|
19820
|
-
|
|
19821
|
-
|
|
19822
|
-
|
|
19823
|
-
|
|
19824
|
-
|
|
19825
|
-
|
|
19826
|
-
|
|
19827
|
-
|
|
19828
|
-
|
|
19829
|
-
|
|
19830
|
-
|
|
19831
|
-
|
|
19832
|
-
|
|
19833
|
-
|
|
19834
|
-
|
|
19835
|
-
|
|
19836
|
-
|
|
19837
|
-
|
|
19838
|
-
|
|
19839
|
-
message: `Ask step "${step.id ?? stepIndex}" outputSchema choice enum must contain only string values; ask options always emit strings.`,
|
|
19840
|
-
path: choicePath
|
|
19841
|
-
});
|
|
19842
|
-
continue;
|
|
19843
|
-
}
|
|
19844
|
-
const optionValues = (step.options ?? []).map((option) => option?.value).filter((value) => typeof value === "string");
|
|
19845
|
-
const optionSet = new Set(optionValues);
|
|
19846
|
-
const enumSet = new Set(choiceEnum);
|
|
19847
|
-
const missing = optionValues.filter((value) => !enumSet.has(value));
|
|
19848
|
-
const unexpected = choiceEnum.filter((value) => !optionSet.has(value));
|
|
19849
|
-
if (missing.length === 0 && unexpected.length === 0)
|
|
19850
|
-
continue;
|
|
19851
|
-
const detail = [
|
|
19852
|
-
missing.length > 0 ? `missing ${missing.map((v) => `'${v}'`).join(", ")}` : "",
|
|
19853
|
-
unexpected.length > 0 ? `unexpected ${unexpected.map((v) => `'${v}'`).join(", ")}` : ""
|
|
19854
|
-
].filter(Boolean).join("; ");
|
|
19855
|
-
ctx.addIssue({
|
|
19856
|
-
code: external_exports.ZodIssueCode.custom,
|
|
19857
|
-
message: `Ask step "${step.id ?? stepIndex}" outputSchema choice enum must list exactly the option values (${detail}).`,
|
|
19858
|
-
path: choicePath
|
|
19859
|
-
});
|
|
19860
|
-
}
|
|
19861
|
-
}
|
|
19862
|
-
function validateManifestResultFrom(data, ctx) {
|
|
19863
|
-
if (!data.resultFrom) {
|
|
19864
|
-
return;
|
|
19874
|
+
|
|
19875
|
+
// ../../packages/core/dist/esm/schemas/manifest.schema.js
|
|
19876
|
+
var uuidv7Regex = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-7[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$/i;
|
|
19877
|
+
var uuidv7Schema = external_exports.string().regex(uuidv7Regex);
|
|
19878
|
+
var timezoneComponent = "[A-Za-z0-9+]+(?:[._+-][A-Za-z0-9+]+)*";
|
|
19879
|
+
var durationStringSchema = external_exports.string().regex(durationStringRegex, "Must be a valid duration string (e.g., '500ms', '10s', '1m')").meta({
|
|
19880
|
+
description: "A duration string, composed of a positive integer and a unit: 'ms', 's', 'm', 'h', 'd', 'w'."
|
|
19881
|
+
});
|
|
19882
|
+
var retrySchema = external_exports.object({
|
|
19883
|
+
maxAttempts: external_exports.number().int().min(EXECUTION_RETRY_MIN_RETRIES).max(EXECUTION_RETRY_MAX_RETRIES).default(EXECUTION_RETRY_DEFAULT_RETRIES).meta({ description: "The number of retries after the initial step attempt." }),
|
|
19884
|
+
strategy: external_exports.enum(["fixed", "exponential_backoff"]).default("exponential_backoff").meta({ description: "The backoff strategy to use for retries." }),
|
|
19885
|
+
delay: durationStringSchema.default(EXECUTION_RETRY_DEFAULT_DELAY).meta({
|
|
19886
|
+
description: "The initial delay between retries (e.g., '500ms', '1m', '10m')."
|
|
19887
|
+
})
|
|
19888
|
+
}).meta({ description: "Defines the retry policy for a failed step." });
|
|
19889
|
+
var onErrorSchema = external_exports.object({
|
|
19890
|
+
retries: retrySchema.optional()
|
|
19891
|
+
}).meta({
|
|
19892
|
+
description: "Defines the error handling policy for the automation or a specific step."
|
|
19893
|
+
});
|
|
19894
|
+
var executionTimeoutSchema = durationStringSchema.refine((value) => {
|
|
19895
|
+
const milliseconds = durationStringToMilliseconds(value);
|
|
19896
|
+
return milliseconds >= EXECUTION_TIMEOUT_MIN_MS && milliseconds <= EXECUTION_TIMEOUT_MAX_MS;
|
|
19897
|
+
}, { message: "Execution timeout must be between 1 minute and 60 minutes" }).meta({
|
|
19898
|
+
description: "Maximum runtime for a single step, expressed as a duration string (e.g., '10m')."
|
|
19899
|
+
});
|
|
19900
|
+
var executionPolicySchema = external_exports.object({
|
|
19901
|
+
timeout: executionTimeoutSchema.optional().default(EXECUTION_TIMEOUT_DEFAULT),
|
|
19902
|
+
onError: onErrorSchema.optional()
|
|
19903
|
+
}).meta({
|
|
19904
|
+
description: "Defines how long a step may run and how failures are retried. Available globally and per step."
|
|
19905
|
+
});
|
|
19906
|
+
var intervalScheduleSchema = external_exports.string().regex(intervalScheduleRegex, "Must be a valid interval string (e.g., '45m' or '6h/5h')").meta({ description: "An interval string (e.g., '45m' or '6h/5h')." });
|
|
19907
|
+
var cronScheduleSchema = (() => {
|
|
19908
|
+
function createCronField(rangePattern) {
|
|
19909
|
+
return `(?:(?:(?:\\*|(?:${rangePattern})(?:-(?:${rangePattern}))?)(?:\\/\\d+)?)(?:,(?:(?:\\*|(?:${rangePattern})(?:-(?:${rangePattern}))?)(?:\\/\\d+)?))*)`;
|
|
19865
19910
|
}
|
|
19866
|
-
const
|
|
19867
|
-
const
|
|
19868
|
-
|
|
19869
|
-
|
|
19870
|
-
|
|
19871
|
-
|
|
19872
|
-
|
|
19873
|
-
|
|
19911
|
+
const minutes = createCronField("[0-5]?\\d");
|
|
19912
|
+
const hours = createCronField("[01]?\\d|2[0-3]");
|
|
19913
|
+
const dayOfMonth = createCronField("0?[1-9]|[12]\\d|3[01]");
|
|
19914
|
+
const month = createCronField("0?[1-9]|1[0-2]");
|
|
19915
|
+
const dayOfWeek = createCronField("[0-6]");
|
|
19916
|
+
const cronExpressionRegex = new RegExp(`^${minutes}\\s+${hours}\\s+${dayOfMonth}\\s+${month}\\s+${dayOfWeek}$`);
|
|
19917
|
+
const timezoneRegex = new RegExp(`^${timezoneComponent}(?:/${timezoneComponent})*$`);
|
|
19918
|
+
return external_exports.object({
|
|
19919
|
+
timezone: external_exports.string().regex(timezoneRegex, "Must be a valid IANA Time Zone name").meta({
|
|
19920
|
+
description: "IANA Time Zone name (e.g., America/New_York). Required for cron schedules."
|
|
19921
|
+
}),
|
|
19922
|
+
expression: external_exports.string().regex(cronExpressionRegex, "Must be a valid 5-part cron expression").meta({
|
|
19923
|
+
description: "Standard 5-part cron expression (minute hour day month dayOfWeek)"
|
|
19924
|
+
})
|
|
19925
|
+
}).meta({
|
|
19926
|
+
description: "A cron schedule with required timezone"
|
|
19927
|
+
});
|
|
19928
|
+
})();
|
|
19929
|
+
var scheduleValueSchema = external_exports.union([intervalScheduleSchema, cronScheduleSchema]).meta({ description: "The schedule definition for the trigger." });
|
|
19930
|
+
var scheduleTriggerSchema = external_exports.object({
|
|
19931
|
+
type: external_exports.literal("schedule"),
|
|
19932
|
+
value: scheduleValueSchema,
|
|
19933
|
+
description: external_exports.string().optional().meta({ description: "A natural language description of what the trigger does." })
|
|
19934
|
+
});
|
|
19935
|
+
var webhookTriggerSchema = external_exports.object({
|
|
19936
|
+
type: external_exports.literal("webhook"),
|
|
19937
|
+
event: external_exports.string({
|
|
19938
|
+
message: 'Webhook triggers require an "event" field with the event type (e.g., "todoist.item.added").'
|
|
19939
|
+
}).regex(/^[a-z0-9-]+\.[a-z0-9_]+\.[a-z0-9_]+(\.[a-z0-9_]+)*$/, "Event type must be in the format 'connector.entity.action' with exactly 3 required parts, optionally followed by additional segments (e.g., 'todoist.item.added', 'google-calendar.event.created')").meta({
|
|
19940
|
+
description: "The event type to listen for (e.g., 'todoist.item.added', 'gmail.message.new'). This references a specific trigger definition from a connector."
|
|
19941
|
+
}),
|
|
19942
|
+
outputSchema: external_exports.object({
|
|
19943
|
+
type: external_exports.string({
|
|
19944
|
+
message: 'outputSchema must be a valid JSON Schema with a "type" field. Use {"type": "string"} or {"type": "object", ...}.'
|
|
19945
|
+
})
|
|
19946
|
+
}, {
|
|
19947
|
+
message: 'Webhook triggers require an "outputSchema" field describing the trigger payload structure.'
|
|
19948
|
+
}).catchall(external_exports.unknown()).meta({
|
|
19949
|
+
description: "A JSON Schema that describes the structure of the trigger payload."
|
|
19950
|
+
}),
|
|
19951
|
+
inputSchema: external_exports.record(external_exports.string(), external_exports.unknown()).optional().meta({
|
|
19952
|
+
description: "An optional JSON Schema to filter the CloudEvent data field. Only events matching this schema will trigger the automation."
|
|
19953
|
+
}),
|
|
19954
|
+
description: external_exports.string().optional().meta({ description: "A natural language description of what the trigger does." })
|
|
19955
|
+
});
|
|
19956
|
+
var apiTriggerIdSchema = external_exports.string().regex(uuidv7Regex, "API trigger ID must be a valid UUIDv7");
|
|
19957
|
+
var apiTriggerSchema = external_exports.object({
|
|
19958
|
+
type: external_exports.literal("api"),
|
|
19959
|
+
id: apiTriggerIdSchema.optional().meta({
|
|
19960
|
+
description: "A system-generated unique ID for the trigger endpoint (UUIDv7 format). Auto-generated if not provided."
|
|
19961
|
+
}),
|
|
19962
|
+
outputSchema: external_exports.object({
|
|
19963
|
+
type: external_exports.string({
|
|
19964
|
+
message: 'outputSchema must be a valid JSON Schema with a "type" field. Use {"type": "string"} or {"type": "object", ...}.'
|
|
19965
|
+
})
|
|
19966
|
+
}, {
|
|
19967
|
+
message: 'API triggers require an "outputSchema" field describing the trigger payload structure.'
|
|
19968
|
+
}).catchall(external_exports.unknown()).meta({
|
|
19969
|
+
description: "A JSON Schema that describes the structure of the trigger payload."
|
|
19970
|
+
}),
|
|
19971
|
+
inputSchema: external_exports.object({
|
|
19972
|
+
type: external_exports.string({
|
|
19973
|
+
message: 'inputSchema must be a valid JSON Schema with a "type" field. Use {"type": "string"} or {"type": "object", ...}.'
|
|
19974
|
+
})
|
|
19975
|
+
}, {
|
|
19976
|
+
message: 'API triggers with input validation require an "inputSchema" field to validate incoming request payloads.'
|
|
19977
|
+
}).catchall(external_exports.unknown()).optional().meta({
|
|
19978
|
+
description: "Optional JSON Schema to validate incoming request payloads."
|
|
19979
|
+
}),
|
|
19980
|
+
description: external_exports.string().optional().meta({ description: "A natural language description of what the trigger does." })
|
|
19981
|
+
});
|
|
19982
|
+
var triggerSchema = external_exports.discriminatedUnion("type", [scheduleTriggerSchema, webhookTriggerSchema, apiTriggerSchema], {
|
|
19983
|
+
message: 'Invalid trigger configuration. Schedule triggers need "value", webhook triggers need "event" and "outputSchema", API triggers need "outputSchema" (and optionally "id" and "inputSchema" for advanced features). Use the correct fields for your trigger type.'
|
|
19984
|
+
}).meta({ description: "Defines the event that initiates an automation run." });
|
|
19985
|
+
function validateTriggersConstraints(triggers, ctx) {
|
|
19986
|
+
if (triggers.length === 0)
|
|
19874
19987
|
return;
|
|
19875
|
-
|
|
19876
|
-
if (
|
|
19988
|
+
const types = new Set(triggers.map((t) => t.type));
|
|
19989
|
+
if (types.size > 1) {
|
|
19877
19990
|
ctx.addIssue({
|
|
19878
19991
|
code: external_exports.ZodIssueCode.custom,
|
|
19879
|
-
message:
|
|
19880
|
-
path: ["resultFrom", "stepId"]
|
|
19992
|
+
message: "All triggers must be the same type. Cannot mix schedule, webhook, and api triggers."
|
|
19881
19993
|
});
|
|
19882
19994
|
return;
|
|
19883
19995
|
}
|
|
19884
|
-
const
|
|
19885
|
-
if (
|
|
19996
|
+
const triggerType = triggers[0]?.type;
|
|
19997
|
+
if ((triggerType === "schedule" || triggerType === "api") && triggers.length > 1) {
|
|
19886
19998
|
ctx.addIssue({
|
|
19887
19999
|
code: external_exports.ZodIssueCode.custom,
|
|
19888
|
-
message: `
|
|
19889
|
-
path: ["resultFrom", "stepId"]
|
|
20000
|
+
message: `Only one ${triggerType} trigger is allowed per automation.`
|
|
19890
20001
|
});
|
|
19891
20002
|
return;
|
|
19892
20003
|
}
|
|
19893
|
-
if (
|
|
19894
|
-
|
|
20004
|
+
if (triggerType === "webhook") {
|
|
20005
|
+
const events = triggers.map((t) => t.type === "webhook" ? t.event : "");
|
|
20006
|
+
const connectors = new Set(events.map((e) => e.split(".")[0]));
|
|
20007
|
+
if (connectors.size > 1) {
|
|
19895
20008
|
ctx.addIssue({
|
|
19896
20009
|
code: external_exports.ZodIssueCode.custom,
|
|
19897
|
-
message:
|
|
19898
|
-
|
|
20010
|
+
message: `All webhook triggers must be from the same connector. Found: ${[...connectors].join(", ")}.`
|
|
20011
|
+
});
|
|
20012
|
+
return;
|
|
20013
|
+
}
|
|
20014
|
+
const duplicateEvents = events.filter((e, i) => events.indexOf(e) !== i);
|
|
20015
|
+
if (duplicateEvents.length > 0) {
|
|
20016
|
+
ctx.addIssue({
|
|
20017
|
+
code: external_exports.ZodIssueCode.custom,
|
|
20018
|
+
message: `Duplicate trigger events are not allowed: ${[...new Set(duplicateEvents)].join(", ")}.`
|
|
19899
20019
|
});
|
|
19900
20020
|
}
|
|
19901
|
-
return;
|
|
19902
|
-
}
|
|
19903
|
-
const propertyPath = data.resultFrom.path.split(".");
|
|
19904
|
-
const resolvedSchema = resolvePropertySchemaInSchema(outputSchema, propertyPath);
|
|
19905
|
-
if (!resolvedSchema) {
|
|
19906
|
-
ctx.addIssue({
|
|
19907
|
-
code: external_exports.ZodIssueCode.custom,
|
|
19908
|
-
message: `resultFrom.path "${data.resultFrom.path}" does not exist in step "${referencedStep.id}" outputSchema.`,
|
|
19909
|
-
path: ["resultFrom", "path"]
|
|
19910
|
-
});
|
|
19911
|
-
return;
|
|
19912
|
-
}
|
|
19913
|
-
if (!isStringTypedSchema(resolvedSchema)) {
|
|
19914
|
-
ctx.addIssue({
|
|
19915
|
-
code: external_exports.ZodIssueCode.custom,
|
|
19916
|
-
message: "resultFrom.path must resolve to a string value.",
|
|
19917
|
-
path: ["resultFrom", "path"]
|
|
19918
|
-
});
|
|
19919
|
-
}
|
|
19920
|
-
}
|
|
19921
|
-
function isNonScalarSchema(schema) {
|
|
19922
|
-
const type = schema.type;
|
|
19923
|
-
if (type === "object" || type === "array")
|
|
19924
|
-
return true;
|
|
19925
|
-
if (Array.isArray(type) && (type.includes("object") || type.includes("array")))
|
|
19926
|
-
return true;
|
|
19927
|
-
const structural = schema;
|
|
19928
|
-
return structural.properties !== void 0 || structural.items !== void 0;
|
|
19929
|
-
}
|
|
19930
|
-
function ifConditionLiteralError({ reference, literal: literal2, stepId, schema }) {
|
|
19931
|
-
const enumValues = schema.enum;
|
|
19932
|
-
if (Array.isArray(enumValues)) {
|
|
19933
|
-
if (enumValues.some((value) => String(value) === literal2))
|
|
19934
|
-
return null;
|
|
19935
|
-
const allowed = enumValues.map((value) => `'${String(value)}'`).join(", ");
|
|
19936
|
-
return `Step "${stepId}" condition compares "${reference}" to '${literal2}', which is not one of its allowed values: ${allowed}.`;
|
|
19937
|
-
}
|
|
19938
|
-
if (isNonScalarSchema(schema)) {
|
|
19939
|
-
return `Step "${stepId}" condition compares "${reference}", which is an object or array, to a string literal and can never match. Reference a scalar property instead.`;
|
|
19940
20021
|
}
|
|
19941
|
-
return null;
|
|
19942
20022
|
}
|
|
19943
|
-
|
|
19944
|
-
|
|
19945
|
-
if (!parsed)
|
|
19946
|
-
return null;
|
|
19947
|
-
const { reference, literal: literal2 } = parsed;
|
|
19948
|
-
const parts = reference.split(".");
|
|
19949
|
-
if (parts[0] === "steps") {
|
|
19950
|
-
const referencedStepId = parts[1];
|
|
19951
|
-
if (!referencedStepId)
|
|
19952
|
-
return null;
|
|
19953
|
-
const outputSchema = context.steps.get(referencedStepId);
|
|
19954
|
-
if (!outputSchema)
|
|
19955
|
-
return null;
|
|
19956
|
-
const propertyPath = parts.slice(2);
|
|
19957
|
-
const resolved = propertyPath.length === 0 ? outputSchema : resolvePropertySchemaInSchema(outputSchema, propertyPath);
|
|
19958
|
-
if (!resolved)
|
|
19959
|
-
return null;
|
|
19960
|
-
return ifConditionLiteralError({ reference, literal: literal2, stepId, schema: resolved });
|
|
19961
|
-
}
|
|
19962
|
-
if (parts[0] === "trigger") {
|
|
19963
|
-
const propertyPath = parts.slice(1);
|
|
19964
|
-
if (propertyPath.length === 0)
|
|
19965
|
-
return null;
|
|
19966
|
-
let firstError = null;
|
|
19967
|
-
let anyResolved = false;
|
|
19968
|
-
for (const schema of context.triggerOutputSchemas) {
|
|
19969
|
-
const resolved = resolvePropertySchemaInSchema(schema, propertyPath);
|
|
19970
|
-
if (!resolved)
|
|
19971
|
-
continue;
|
|
19972
|
-
anyResolved = true;
|
|
19973
|
-
const error61 = ifConditionLiteralError({ reference, literal: literal2, stepId, schema: resolved });
|
|
19974
|
-
if (!error61)
|
|
19975
|
-
return null;
|
|
19976
|
-
firstError ??= error61;
|
|
19977
|
-
}
|
|
19978
|
-
return anyResolved ? firstError : null;
|
|
19979
|
-
}
|
|
19980
|
-
return null;
|
|
19981
|
-
}
|
|
19982
|
-
function validateManifestTemplateVariables(data, ctx) {
|
|
19983
|
-
const triggers = resolveTriggersFromData(data);
|
|
19984
|
-
const firstTrigger = triggers[0];
|
|
19985
|
-
const scheduleValue = firstTrigger?.value;
|
|
19986
|
-
const scheduleInjectsTimezone = firstTrigger?.type === "schedule" && typeof scheduleValue === "object" && scheduleValue !== null && typeof scheduleValue.timezone === "string";
|
|
19987
|
-
const context = {
|
|
19988
|
-
triggerType: firstTrigger?.type,
|
|
19989
|
-
scheduleInjectsTimezone,
|
|
19990
|
-
triggerOutputSchemas: [],
|
|
19991
|
-
steps: /* @__PURE__ */ new Map(),
|
|
19992
|
-
guards: /* @__PURE__ */ new Map()
|
|
19993
|
-
};
|
|
19994
|
-
for (const trigger of triggers) {
|
|
19995
|
-
if ((trigger.type === "webhook" || trigger.type === "api" || trigger.type === "manual") && trigger.outputSchema) {
|
|
19996
|
-
context.triggerOutputSchemas.push(trigger.outputSchema);
|
|
19997
|
-
}
|
|
19998
|
-
}
|
|
19999
|
-
const steps = data.steps || [];
|
|
20000
|
-
for (let stepIndex = 0; stepIndex < steps.length; stepIndex++) {
|
|
20001
|
-
const step = steps[stepIndex];
|
|
20002
|
-
if (!step)
|
|
20003
|
-
continue;
|
|
20004
|
-
const currentStepGuard = step.if;
|
|
20005
|
-
const unavailableStepRefs = /* @__PURE__ */ new Set();
|
|
20006
|
-
const propertyPathErrors = [];
|
|
20007
|
-
const processStepRef = (ref, sourceType, fieldPath) => {
|
|
20008
|
-
if (!context.steps.has(ref.stepId)) {
|
|
20009
|
-
unavailableStepRefs.add(ref.stepId);
|
|
20010
|
-
return;
|
|
20011
|
-
}
|
|
20012
|
-
const guardError = validateGuardReference({
|
|
20013
|
-
stepId: step.id,
|
|
20014
|
-
referencedStepId: ref.stepId,
|
|
20015
|
-
currentStepGuard,
|
|
20016
|
-
referencedGuard: context.guards.get(ref.stepId),
|
|
20017
|
-
sourceType
|
|
20018
|
-
});
|
|
20019
|
-
if (guardError) {
|
|
20020
|
-
propertyPathErrors.push({ message: guardError, path: fieldPath });
|
|
20021
|
-
return;
|
|
20022
|
-
}
|
|
20023
|
-
const stepOutputSchema2 = context.steps.get(ref.stepId);
|
|
20024
|
-
if (!stepOutputSchema2 || ref.propertyPath.length === 0) {
|
|
20025
|
-
return;
|
|
20026
|
-
}
|
|
20027
|
-
const isValid = validatePropertyPathInSchema(stepOutputSchema2, ref.propertyPath);
|
|
20028
|
-
if (!isValid) {
|
|
20029
|
-
propertyPathErrors.push({
|
|
20030
|
-
message: `Step "${step.id}" ${sourceType} references "steps.${ref.stepId}.${ref.propertyPath.join(".")}" but this property path does not exist in step "${ref.stepId}"'s outputSchema.`,
|
|
20031
|
-
path: fieldPath
|
|
20032
|
-
});
|
|
20033
|
-
}
|
|
20034
|
-
};
|
|
20035
|
-
if (typeof step.if === "string") {
|
|
20036
|
-
for (const variable of extractTemplateVariables(step.if)) {
|
|
20037
|
-
const error61 = validateTemplateVariable({
|
|
20038
|
-
variable,
|
|
20039
|
-
context,
|
|
20040
|
-
stepId: step.id,
|
|
20041
|
-
currentStepGuard,
|
|
20042
|
-
sourceType: "condition"
|
|
20043
|
-
});
|
|
20044
|
-
if (error61) {
|
|
20045
|
-
ctx.addIssue({
|
|
20046
|
-
code: external_exports.ZodIssueCode.custom,
|
|
20047
|
-
message: error61,
|
|
20048
|
-
path: ["steps", stepIndex, "if"]
|
|
20049
|
-
});
|
|
20050
|
-
}
|
|
20051
|
-
}
|
|
20052
|
-
const literalError = validateIfConditionLiteral({
|
|
20053
|
-
condition: step.if,
|
|
20054
|
-
context,
|
|
20055
|
-
stepId: step.id
|
|
20056
|
-
});
|
|
20057
|
-
if (literalError) {
|
|
20058
|
-
ctx.addIssue({
|
|
20059
|
-
code: external_exports.ZodIssueCode.custom,
|
|
20060
|
-
message: literalError,
|
|
20061
|
-
path: ["steps", stepIndex, "if"]
|
|
20062
|
-
});
|
|
20063
|
-
}
|
|
20064
|
-
}
|
|
20065
|
-
if ("prompt" in step && typeof step.prompt === "string") {
|
|
20066
|
-
const variables = extractTemplateVariables(step.prompt);
|
|
20067
|
-
for (const variable of variables) {
|
|
20068
|
-
const error61 = validateTemplateVariable({
|
|
20069
|
-
variable,
|
|
20070
|
-
context,
|
|
20071
|
-
stepId: step.id,
|
|
20072
|
-
currentStepGuard
|
|
20073
|
-
});
|
|
20074
|
-
if (!error61)
|
|
20075
|
-
continue;
|
|
20076
|
-
const parts = variable.split(".");
|
|
20077
|
-
if (parts[0] === "steps" && parts[1] && !context.steps.has(parts[1]) && error61.includes("before it is available")) {
|
|
20078
|
-
unavailableStepRefs.add(parts[1]);
|
|
20079
|
-
} else {
|
|
20080
|
-
ctx.addIssue({
|
|
20081
|
-
code: external_exports.ZodIssueCode.custom,
|
|
20082
|
-
message: error61,
|
|
20083
|
-
path: ["steps", stepIndex, "prompt"]
|
|
20084
|
-
});
|
|
20085
|
-
}
|
|
20086
|
-
}
|
|
20087
|
-
const backtickRefs = extractStepReferences(step.prompt, backtickStepReferenceRegex);
|
|
20088
|
-
for (const ref of backtickRefs) {
|
|
20089
|
-
processStepRef(ref, "prompt", ["steps", stepIndex, "prompt"]);
|
|
20090
|
-
}
|
|
20091
|
-
}
|
|
20092
|
-
if (step.type === "ask") {
|
|
20093
|
-
const askTextFields = [
|
|
20094
|
-
{ fieldName: "message", value: "message" in step ? step.message : void 0 },
|
|
20095
|
-
{ fieldName: "details", value: "details" in step ? step.details : void 0 }
|
|
20096
|
-
];
|
|
20097
|
-
for (const { fieldName, value } of askTextFields) {
|
|
20098
|
-
if (typeof value !== "string")
|
|
20099
|
-
continue;
|
|
20100
|
-
for (const variable of extractTemplateVariables(value)) {
|
|
20101
|
-
const error61 = validateTemplateVariable({
|
|
20102
|
-
variable,
|
|
20103
|
-
context,
|
|
20104
|
-
stepId: step.id,
|
|
20105
|
-
currentStepGuard,
|
|
20106
|
-
sourceType: fieldName
|
|
20107
|
-
});
|
|
20108
|
-
if (!error61)
|
|
20109
|
-
continue;
|
|
20110
|
-
ctx.addIssue({
|
|
20111
|
-
code: external_exports.ZodIssueCode.custom,
|
|
20112
|
-
message: error61,
|
|
20113
|
-
path: ["steps", stepIndex, fieldName]
|
|
20114
|
-
});
|
|
20115
|
-
}
|
|
20116
|
-
}
|
|
20117
|
-
}
|
|
20118
|
-
if (step.type === "code" && "code" in step && typeof step.code === "string") {
|
|
20119
|
-
const codeRefs = extractStepReferences(step.code, codeStepReferenceRegex);
|
|
20120
|
-
for (const ref of codeRefs) {
|
|
20121
|
-
processStepRef(ref, "code", ["steps", stepIndex, "code"]);
|
|
20122
|
-
}
|
|
20123
|
-
}
|
|
20124
|
-
for (const referencedStepId of unavailableStepRefs) {
|
|
20125
|
-
const sourceType = step.type === "code" ? "code" : "prompt";
|
|
20126
|
-
const fieldName = step.type === "code" ? "code" : "prompt";
|
|
20127
|
-
ctx.addIssue({
|
|
20128
|
-
code: external_exports.ZodIssueCode.custom,
|
|
20129
|
-
message: `Step "${step.id}" ${sourceType} references step "${referencedStepId}" before it is available. Steps can only reference outputs from earlier steps.`,
|
|
20130
|
-
path: ["steps", stepIndex, fieldName]
|
|
20131
|
-
});
|
|
20132
|
-
}
|
|
20133
|
-
for (const err of propertyPathErrors) {
|
|
20134
|
-
ctx.addIssue({
|
|
20135
|
-
code: external_exports.ZodIssueCode.custom,
|
|
20136
|
-
message: err.message,
|
|
20137
|
-
path: err.path
|
|
20138
|
-
});
|
|
20139
|
-
}
|
|
20140
|
-
if (step.type === "llm" || step.type === "codegen" || step.type === "code" || step.type === "ask") {
|
|
20141
|
-
context.steps.set(step.id, step.outputSchema);
|
|
20142
|
-
} else if (step.type === "search") {
|
|
20143
|
-
context.steps.set(step.id, { type: "string" });
|
|
20144
|
-
}
|
|
20145
|
-
context.guards.set(step.id, currentStepGuard);
|
|
20146
|
-
}
|
|
20147
|
-
}
|
|
20148
|
-
|
|
20149
|
-
// ../../packages/core/dist/esm/schemas/admin-sample-automation.schema.js
|
|
20150
|
-
var sampleAutomationIdSchema = external_exports.string().trim().min(1, "Sample automation ID is required").max(100, "Sample automation ID must be 100 characters or fewer").regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, "Sample automation ID must use lowercase letters, numbers, and hyphens only");
|
|
20151
|
-
var sampleAutomationInstructionsSchema = external_exports.string().nullable();
|
|
20152
|
-
var adminSampleAutomationSchema = external_exports.object({
|
|
20153
|
-
id: sampleAutomationIdSchema,
|
|
20154
|
-
manifest: manifestSchema,
|
|
20155
|
-
instructions: sampleAutomationInstructionsSchema.default(null),
|
|
20156
|
-
connectorNames: external_exports.array(external_exports.string()),
|
|
20157
|
-
connectorDetails: external_exports.array(connectorDetailsSchema),
|
|
20158
|
-
isPublished: external_exports.boolean(),
|
|
20159
|
-
isOneClickInstallEnabled: external_exports.boolean().default(false),
|
|
20160
|
-
staffPick: external_exports.boolean().default(false),
|
|
20161
|
-
createdAt: external_exports.string().datetime(),
|
|
20162
|
-
updatedAt: external_exports.string().datetime()
|
|
20023
|
+
var triggersSchema = external_exports.array(triggerSchema).nonempty({ message: "At least one trigger is required." }).superRefine(validateTriggersConstraints).meta({
|
|
20024
|
+
description: "An array of triggers for the automation. Multiple webhook triggers from the same connector are supported."
|
|
20163
20025
|
});
|
|
20164
|
-
var
|
|
20165
|
-
var
|
|
20166
|
-
|
|
20167
|
-
manifest: manifestSchema,
|
|
20168
|
-
instructions: sampleAutomationInstructionsSchema.default(null),
|
|
20169
|
-
isPublished: external_exports.boolean().default(false),
|
|
20170
|
-
isOneClickInstallEnabled: external_exports.boolean().default(false),
|
|
20171
|
-
staffPick: external_exports.boolean().default(false)
|
|
20026
|
+
var stepIdSchema = external_exports.string().regex(/^[a-zA-Z][a-zA-Z0-9]*$/, "ID must be in camelCase format (no dashes or underscores allowed)").meta({ description: "A unique camelCase identifier for the step." });
|
|
20027
|
+
var resultFromPathSchema = external_exports.string().regex(/^[a-zA-Z_]\w*(\.[a-zA-Z_]\w*)*$/, 'Path must be a dot-separated property path like "text" or "task.description".').meta({
|
|
20028
|
+
description: 'Dot-separated property path relative to a step output, such as "text" or "task.description".'
|
|
20172
20029
|
});
|
|
20173
|
-
var
|
|
20174
|
-
|
|
20175
|
-
|
|
20176
|
-
|
|
20177
|
-
|
|
20178
|
-
|
|
20030
|
+
var resultFromSchema = external_exports.object({
|
|
20031
|
+
stepId: stepIdSchema.meta({
|
|
20032
|
+
description: "The step whose output should be used as the persisted run result."
|
|
20033
|
+
}),
|
|
20034
|
+
path: resultFromPathSchema.optional()
|
|
20035
|
+
}).strict().meta({
|
|
20036
|
+
description: "Declares which step output becomes the persisted user-facing automation run result."
|
|
20179
20037
|
});
|
|
20180
|
-
var
|
|
20181
|
-
|
|
20038
|
+
var stepOutputSchema = external_exports.object({
|
|
20039
|
+
type: external_exports.string({
|
|
20040
|
+
message: 'outputSchema must be a valid JSON Schema with a "type" field. Use {"type": "string"} or {"type": "object", ...}.'
|
|
20041
|
+
})
|
|
20042
|
+
}).catchall(external_exports.unknown()).meta({ description: "A JSON Schema object defining the expected output of this step." });
|
|
20043
|
+
var searchStepOutputSchema = external_exports.object({
|
|
20044
|
+
type: external_exports.literal("string").meta({
|
|
20045
|
+
description: 'Must be "string" for search steps.'
|
|
20046
|
+
})
|
|
20047
|
+
}).strict().default({ type: "string" }).meta({
|
|
20048
|
+
description: 'JSON Schema for search step output. Must be exactly {"type": "string"}.'
|
|
20182
20049
|
});
|
|
20183
|
-
var
|
|
20184
|
-
|
|
20050
|
+
var exitOnSchema = external_exports.record(external_exports.string(), external_exports.unknown()).meta({
|
|
20051
|
+
description: "A JSON Schema object that terminates the automation's run if matched. Otherwise, or if omitted, the automation continues to the next step."
|
|
20185
20052
|
});
|
|
20186
|
-
|
|
20187
|
-
|
|
20188
|
-
var AUTOMATION_CONNECTION_STATUSES = ["ready", "almost-ready", "not-ready"];
|
|
20189
|
-
var AUTOMATION_VISIBILITIES = ["private", "workspace"];
|
|
20190
|
-
var AUTOMATION_DISABLED_REASONS = [
|
|
20191
|
-
"creator-left-workspace",
|
|
20192
|
-
"workspace-plan-lapsed"
|
|
20193
|
-
];
|
|
20194
|
-
|
|
20195
|
-
// ../../packages/core/dist/esm/schemas/connection.schema.js
|
|
20196
|
-
var CreateConnectionParamsSchema = external_exports.object({
|
|
20197
|
-
connectorId: external_exports.string(),
|
|
20198
|
-
capability: external_exports.enum(CONNECTION_TYPES),
|
|
20199
|
-
name: external_exports.string().optional()
|
|
20200
|
-
});
|
|
20201
|
-
var CreateConnectionBodySchema = external_exports.object({
|
|
20202
|
-
automationIds: external_exports.array(external_exports.uuid()).optional()
|
|
20203
|
-
});
|
|
20204
|
-
var OAuthConnectionSetupSchema = external_exports.object({
|
|
20205
|
-
kind: external_exports.literal("oauth"),
|
|
20206
|
-
authorizationUrl: external_exports.string().url()
|
|
20207
|
-
});
|
|
20208
|
-
var ManagedConnectionSetupSchema = external_exports.object({
|
|
20209
|
-
kind: external_exports.literal("managed"),
|
|
20210
|
-
code: external_exports.string().regex(MANAGED_CONNECTION_SETUP_CODE_EXACT_REGEX),
|
|
20211
|
-
instructions: external_exports.string(),
|
|
20212
|
-
deepLinkUrl: external_exports.string().url().nullable(),
|
|
20213
|
-
expiresAt: external_exports.iso.datetime()
|
|
20214
|
-
});
|
|
20215
|
-
var ConnectionSetupSchema = external_exports.discriminatedUnion("kind", [
|
|
20216
|
-
OAuthConnectionSetupSchema,
|
|
20217
|
-
ManagedConnectionSetupSchema
|
|
20218
|
-
]);
|
|
20219
|
-
var CreateConnectionResponseSchema = external_exports.object({
|
|
20220
|
-
connectionId: external_exports.uuid(),
|
|
20221
|
-
setup: ConnectionSetupSchema.nullable()
|
|
20222
|
-
});
|
|
20223
|
-
var ConnectionCapabilitySchema = external_exports.object({
|
|
20224
|
-
capability: external_exports.enum(CONNECTION_TYPES),
|
|
20225
|
-
scopes: external_exports.array(external_exports.string()),
|
|
20226
|
-
authorizedAt: external_exports.iso.datetime()
|
|
20227
|
-
});
|
|
20228
|
-
var ConnectionSchema = external_exports.object({
|
|
20229
|
-
id: external_exports.uuid(),
|
|
20230
|
-
name: external_exports.string(),
|
|
20231
|
-
connectorId: external_exports.string(),
|
|
20232
|
-
connectorIconUrl: external_exports.url().nullable().optional(),
|
|
20233
|
-
capabilities: external_exports.array(ConnectionCapabilitySchema),
|
|
20234
|
-
accountDisplayLabel: external_exports.string().optional(),
|
|
20235
|
-
status: external_exports.enum(CONNECTION_STATUSES).optional(),
|
|
20236
|
-
createdAt: external_exports.string().optional(),
|
|
20237
|
-
metadata: external_exports.record(external_exports.string(), external_exports.unknown()),
|
|
20238
|
-
setup: ConnectionSetupSchema.nullable()
|
|
20239
|
-
});
|
|
20240
|
-
var ConnectionDetailsSchema = external_exports.object({
|
|
20241
|
-
id: external_exports.uuid(),
|
|
20242
|
-
name: external_exports.string(),
|
|
20243
|
-
connectorId: external_exports.string(),
|
|
20244
|
-
connectorIconUrl: external_exports.url().nullable().optional(),
|
|
20245
|
-
capabilities: external_exports.array(ConnectionCapabilitySchema),
|
|
20246
|
-
accountDisplayLabel: external_exports.string(),
|
|
20247
|
-
status: external_exports.enum(CONNECTION_STATUSES),
|
|
20248
|
-
createdAt: external_exports.string(),
|
|
20249
|
-
metadata: external_exports.record(external_exports.string(), external_exports.unknown()),
|
|
20250
|
-
setup: ConnectionSetupSchema.nullable()
|
|
20251
|
-
});
|
|
20252
|
-
var GetConnectionsQuerySchema = external_exports.object({
|
|
20253
|
-
/**
|
|
20254
|
-
* Capability filter. `type` is accepted as a deprecated alias during the
|
|
20255
|
-
* rolling-deploy window where older FE/SDK builds may still send the old
|
|
20256
|
-
* query param. Remove once all clients are on the post-PR1 SDK.
|
|
20257
|
-
*/
|
|
20258
|
-
capability: external_exports.enum(CONNECTION_TYPES).optional(),
|
|
20259
|
-
type: external_exports.enum(CONNECTION_TYPES).optional(),
|
|
20260
|
-
connectorId: external_exports.string().optional(),
|
|
20261
|
-
status: external_exports.enum(CONNECTION_STATUSES).optional()
|
|
20262
|
-
});
|
|
20263
|
-
var GetConnectionsResponseSchema = external_exports.object({
|
|
20264
|
-
connections: external_exports.array(ConnectionSchema)
|
|
20265
|
-
});
|
|
20266
|
-
var DependentAutomationSchema = external_exports.object({
|
|
20267
|
-
id: external_exports.string(),
|
|
20268
|
-
name: external_exports.string(),
|
|
20269
|
-
description: external_exports.string(),
|
|
20270
|
-
enabled: external_exports.boolean(),
|
|
20271
|
-
connectorStatus: external_exports.enum(["ready", "attention", "missing"]),
|
|
20272
|
-
requiredConnectionTypes: external_exports.array(external_exports.enum(CONNECTION_TYPES))
|
|
20273
|
-
});
|
|
20274
|
-
var GetConnectionDependentAutomationsResponseSchema = external_exports.object({
|
|
20275
|
-
automations: external_exports.array(DependentAutomationSchema)
|
|
20276
|
-
});
|
|
20277
|
-
var CONNECTION_IN_USE_CONFLICT_CODE = "connection_in_use_conflict";
|
|
20278
|
-
var BlockingAutomationSchema = external_exports.object({
|
|
20279
|
-
id: external_exports.string(),
|
|
20280
|
-
name: external_exports.string()
|
|
20053
|
+
var ifConditionSchema = external_exports.string().regex(ifConditionRegex, `Must be a single comparison, e.g. "{{steps.askUser.choice}} == 'archive'": a {{steps.<id>.<path>}} or {{trigger.<path>}} reference, then == or !=, then a single-quoted literal. No boolean combinators.`).meta({
|
|
20054
|
+
description: `An optional condition gating whether this step runs, e.g. "{{steps.askUser.choice}} == 'archive'". A single comparison against an earlier step or trigger value; when false the step is skipped.`
|
|
20281
20055
|
});
|
|
20282
|
-
var
|
|
20283
|
-
|
|
20284
|
-
|
|
20285
|
-
|
|
20056
|
+
var baseStepSchema = external_exports.object({
|
|
20057
|
+
id: stepIdSchema,
|
|
20058
|
+
title: external_exports.string().optional().meta({ description: "A short human-readable title of the step." }),
|
|
20059
|
+
description: external_exports.string().meta({ description: "A human-readable description of what the step does." }),
|
|
20060
|
+
if: ifConditionSchema.optional(),
|
|
20061
|
+
exitOn: exitOnSchema.optional().meta({
|
|
20062
|
+
description: "A JSON Schema object that terminates the automation's run if the step output matches. If omitted or not matched, execution continues."
|
|
20063
|
+
}),
|
|
20064
|
+
execution: executionPolicySchema.optional().meta({
|
|
20065
|
+
description: "Overrides the global execution policy (timeout and retries) for this step."
|
|
20066
|
+
})
|
|
20286
20067
|
});
|
|
20287
|
-
|
|
20288
|
-
|
|
20289
|
-
|
|
20290
|
-
|
|
20291
|
-
|
|
20292
|
-
|
|
20068
|
+
var SUPPORTED_LLM_MODELS = [
|
|
20069
|
+
"gemini-2.5-flash-lite",
|
|
20070
|
+
"gemini-2.5-flash",
|
|
20071
|
+
"gemini-3.1-pro",
|
|
20072
|
+
"claude-haiku-4-5",
|
|
20073
|
+
"claude-sonnet-4-6"
|
|
20074
|
+
];
|
|
20075
|
+
var DEFAULT_LLM_MODEL = "claude-haiku-4-5";
|
|
20076
|
+
var llmStepSchema = baseStepSchema.merge(external_exports.object({
|
|
20077
|
+
type: external_exports.literal("llm"),
|
|
20078
|
+
prompt: external_exports.string().meta({ description: "The prompt template to be sent to the LLM." }),
|
|
20079
|
+
outputSchema: stepOutputSchema,
|
|
20080
|
+
model: external_exports.enum(SUPPORTED_LLM_MODELS).meta({
|
|
20081
|
+
description: `The specific model to use. Supported models: ${SUPPORTED_LLM_MODELS.join(", ")}.`
|
|
20293
20082
|
}),
|
|
20294
|
-
external_exports.
|
|
20295
|
-
|
|
20296
|
-
|
|
20083
|
+
tools: external_exports.record(external_exports.string(), external_exports.array(external_exports.string())).default({}).meta({
|
|
20084
|
+
description: 'A mapping from MCP server connector IDs to arrays of their tool names (e.g., {"todoist": ["find-tasks-by-date"], "linear": ["create-issue"]}).'
|
|
20085
|
+
})
|
|
20086
|
+
})).strict();
|
|
20087
|
+
var codegenStepSchema = baseStepSchema.merge(external_exports.object({
|
|
20088
|
+
type: external_exports.literal("codegen"),
|
|
20089
|
+
prompt: external_exports.string().meta({
|
|
20090
|
+
description: "The goal or instruction for what the generated code should accomplish."
|
|
20297
20091
|
}),
|
|
20298
|
-
|
|
20299
|
-
|
|
20300
|
-
|
|
20092
|
+
outputSchema: stepOutputSchema,
|
|
20093
|
+
model: external_exports.enum(SUPPORTED_LLM_MODELS).meta({
|
|
20094
|
+
description: `The specific model to use for code generation. Supported models: ${SUPPORTED_LLM_MODELS.join(", ")}.`
|
|
20301
20095
|
}),
|
|
20302
|
-
external_exports.
|
|
20303
|
-
|
|
20304
|
-
lastRun: external_exports.iso.datetime(),
|
|
20305
|
-
failureReason: external_exports.string().optional()
|
|
20096
|
+
tools: external_exports.record(external_exports.string(), external_exports.array(external_exports.string())).default({}).meta({
|
|
20097
|
+
description: 'A mapping from MCP server connector IDs to arrays of their tool names that will be available in the generated code (e.g., {"todoist": ["find-tasks", "update-tasks"]}).'
|
|
20306
20098
|
}),
|
|
20307
|
-
external_exports.
|
|
20308
|
-
|
|
20309
|
-
lastRun: external_exports.iso.datetime()
|
|
20099
|
+
extractedUrls: external_exports.array(external_exports.url()).optional().meta({
|
|
20100
|
+
description: "URLs that will be fetched during step execution (auto-extracted from prompt examples)"
|
|
20310
20101
|
})
|
|
20311
|
-
|
|
20312
|
-
var
|
|
20313
|
-
|
|
20314
|
-
|
|
20315
|
-
|
|
20316
|
-
|
|
20317
|
-
|
|
20318
|
-
|
|
20319
|
-
|
|
20320
|
-
|
|
20321
|
-
// null means the automation belongs to the creator's personal space
|
|
20322
|
-
workspaceId: external_exports.string().nullable(),
|
|
20323
|
-
visibility: external_exports.enum(AUTOMATION_VISIBILITIES),
|
|
20324
|
-
isOwner: external_exports.boolean(),
|
|
20325
|
-
disabledReason: external_exports.enum(AUTOMATION_DISABLED_REASONS).nullable()
|
|
20326
|
-
});
|
|
20327
|
-
var automationListResponseSchema = external_exports.object({
|
|
20328
|
-
data: external_exports.array(automationSchema),
|
|
20329
|
-
nextCursor: external_exports.string().nullable()
|
|
20330
|
-
});
|
|
20331
|
-
var updateAutomationSchema = external_exports.object({
|
|
20332
|
-
enabled: external_exports.boolean().optional(),
|
|
20333
|
-
manifest: manifestSchema.optional()
|
|
20334
|
-
}).refine((data) => Object.keys(data).length > 0, {
|
|
20335
|
-
message: "At least one field must be provided"
|
|
20102
|
+
}));
|
|
20103
|
+
var runtimeSchema = external_exports.object({
|
|
20104
|
+
language: external_exports.literal("typescript").meta({
|
|
20105
|
+
description: "Programming language. Only 'typescript' is supported in v0."
|
|
20106
|
+
}),
|
|
20107
|
+
version: external_exports.enum(SUPPORTED_RUNTIME_VERSIONS).meta({
|
|
20108
|
+
description: "Language specification version. Supported values: '5.9', '6.0'."
|
|
20109
|
+
})
|
|
20110
|
+
}).meta({
|
|
20111
|
+
description: "Defines the execution environment for the code step."
|
|
20336
20112
|
});
|
|
20337
|
-
var
|
|
20338
|
-
|
|
20339
|
-
|
|
20113
|
+
var codeStepSchema = baseStepSchema.merge(external_exports.object({
|
|
20114
|
+
type: external_exports.literal("code"),
|
|
20115
|
+
outputSchema: stepOutputSchema,
|
|
20116
|
+
runtime: runtimeSchema.optional().default({ language: "typescript", version: "5.9" }).meta({
|
|
20117
|
+
description: "An object defining the execution environment. If omitted, it defaults to TypeScript 5.9."
|
|
20118
|
+
}),
|
|
20119
|
+
code: external_exports.string().meta({
|
|
20120
|
+
description: "The code to execute. It has access to trigger and steps objects."
|
|
20121
|
+
}),
|
|
20122
|
+
extractedUrls: external_exports.array(external_exports.url()).optional().meta({
|
|
20123
|
+
description: "URLs that will be fetched during step execution (auto-extracted from code)"
|
|
20124
|
+
})
|
|
20125
|
+
}));
|
|
20126
|
+
var searchStepSchema = baseStepSchema.merge(external_exports.object({
|
|
20127
|
+
type: external_exports.literal("search"),
|
|
20128
|
+
prompt: external_exports.string().min(1).meta({
|
|
20129
|
+
description: "The search prompt to execute using web search."
|
|
20130
|
+
}),
|
|
20131
|
+
outputSchema: searchStepOutputSchema,
|
|
20132
|
+
model: external_exports.enum(SUPPORTED_LLM_MODELS).optional().meta({
|
|
20133
|
+
description: `The specific model to use for processing search results. Defaults to ${DEFAULT_LLM_MODEL}.`
|
|
20134
|
+
})
|
|
20135
|
+
}));
|
|
20136
|
+
var delayStepOutputSchema = external_exports.object({
|
|
20137
|
+
type: external_exports.literal("object").meta({
|
|
20138
|
+
description: 'Must be "object" for delay steps.'
|
|
20139
|
+
})
|
|
20140
|
+
}).catchall(external_exports.unknown()).meta({
|
|
20141
|
+
description: 'JSON Schema for delay step output. Must include {"type": "object"}.'
|
|
20340
20142
|
});
|
|
20341
|
-
var
|
|
20342
|
-
|
|
20143
|
+
var baseDelayStepSchema = baseStepSchema.omit({ execution: true });
|
|
20144
|
+
var delayStepSchema = baseDelayStepSchema.merge(external_exports.object({
|
|
20145
|
+
type: external_exports.literal("delay"),
|
|
20146
|
+
duration: durationStringSchema.meta({
|
|
20147
|
+
description: "Duration to delay the execution for as a duration string, e.g., '1d', '1w', '2h'."
|
|
20148
|
+
}),
|
|
20149
|
+
outputSchema: delayStepOutputSchema
|
|
20150
|
+
})).strict();
|
|
20151
|
+
var baseAskStepSchema = baseStepSchema.omit({ execution: true });
|
|
20152
|
+
var askExpiresAfterSchema = durationStringSchema.refine((value) => durationStringToMilliseconds(value) <= ASK_EXPIRES_AFTER_MAX_MS, {
|
|
20153
|
+
message: "Ask expiresAfter must not exceed 30 days"
|
|
20154
|
+
}).meta({
|
|
20155
|
+
description: "How long to wait for a response before the prompt expires, as a duration string (e.g. '1w'). Defaults to 1w, capped at 30d. On expiry the run terminates."
|
|
20343
20156
|
});
|
|
20344
|
-
|
|
20345
|
-
|
|
20346
|
-
|
|
20347
|
-
|
|
20348
|
-
|
|
20349
|
-
|
|
20350
|
-
|
|
20351
|
-
|
|
20352
|
-
|
|
20353
|
-
|
|
20354
|
-
|
|
20355
|
-
|
|
20356
|
-
|
|
20357
|
-
|
|
20358
|
-
|
|
20359
|
-
|
|
20360
|
-
|
|
20361
|
-
|
|
20362
|
-
|
|
20363
|
-
|
|
20364
|
-
|
|
20365
|
-
|
|
20366
|
-
|
|
20367
|
-
|
|
20368
|
-
|
|
20369
|
-
|
|
20370
|
-
|
|
20371
|
-
|
|
20372
|
-
|
|
20373
|
-
|
|
20374
|
-
|
|
20375
|
-
|
|
20376
|
-
*/
|
|
20377
|
-
isSystem: external_exports.boolean().optional()
|
|
20378
|
-
});
|
|
20379
|
-
var AutomationConnectionSchema = external_exports.object({
|
|
20380
|
-
connectorId: external_exports.string(),
|
|
20381
|
-
connectionId: external_exports.uuid(),
|
|
20382
|
-
connectorName: external_exports.string(),
|
|
20383
|
-
connectorIconUrl: external_exports.url().nullable().optional(),
|
|
20384
|
-
status: external_exports.enum(CONNECTION_STATUSES),
|
|
20385
|
-
type: external_exports.enum(CONNECTION_TYPES)
|
|
20386
|
-
});
|
|
20387
|
-
var ConnectorTypeStatusSchema = external_exports.object({
|
|
20388
|
-
required: external_exports.boolean(),
|
|
20389
|
-
status: external_exports.enum(CONNECTOR_TYPE_STATUSES),
|
|
20390
|
-
connection: ConnectionSchema.pick({
|
|
20391
|
-
id: true,
|
|
20392
|
-
accountDisplayLabel: true,
|
|
20393
|
-
status: true,
|
|
20394
|
-
createdAt: true
|
|
20395
|
-
}).optional(),
|
|
20396
|
-
setup: ConnectionSetupSchema.nullable()
|
|
20397
|
-
});
|
|
20398
|
-
var AutomationConnectorStatusSchema = external_exports.object({
|
|
20399
|
-
id: external_exports.string(),
|
|
20400
|
-
name: external_exports.string(),
|
|
20401
|
-
description: external_exports.string(),
|
|
20402
|
-
iconUrl: external_exports.string().nullable(),
|
|
20403
|
-
mcp: ConnectorTypeStatusSchema,
|
|
20404
|
-
trigger: ConnectorTypeStatusSchema
|
|
20405
|
-
});
|
|
20406
|
-
var AutomationConnectionValidationSchema = external_exports.object({
|
|
20407
|
-
required: external_exports.array(RequiredConnectorSchema),
|
|
20408
|
-
mapped: external_exports.array(AutomationConnectionSchema),
|
|
20409
|
-
missing: external_exports.array(external_exports.object({
|
|
20410
|
-
connectorName: external_exports.string(),
|
|
20411
|
-
connectionType: external_exports.enum(CONNECTION_TYPES),
|
|
20412
|
-
reason: external_exports.enum(CONNECTION_ISSUE_REASONS)
|
|
20413
|
-
})),
|
|
20414
|
-
connectors: external_exports.array(AutomationConnectorStatusSchema),
|
|
20415
|
-
isReady: external_exports.boolean()
|
|
20416
|
-
});
|
|
20417
|
-
var GetRequiredConnectorsResponseSchema = external_exports.object({
|
|
20418
|
-
required: external_exports.array(RequiredConnectorSchema)
|
|
20419
|
-
});
|
|
20420
|
-
var GetAutomationConnectionsResponseSchema = external_exports.object({
|
|
20421
|
-
data: external_exports.array(AutomationConnectionSchema)
|
|
20157
|
+
var askOptionSchema = external_exports.object({
|
|
20158
|
+
label: external_exports.string().min(1).meta({ description: "The button text shown to the user." }),
|
|
20159
|
+
value: external_exports.string().min(1).meta({
|
|
20160
|
+
description: "The machine value emitted as the choice. Unique within the step."
|
|
20161
|
+
}),
|
|
20162
|
+
terminate: external_exports.boolean().optional().default(false).meta({
|
|
20163
|
+
description: 'When true, choosing this option stops the run and no later steps execute (the explicit "deny"/"stop" path).'
|
|
20164
|
+
})
|
|
20165
|
+
}).strict().meta({ description: "A single selectable option in an ask step." });
|
|
20166
|
+
var askOptionsSchema = external_exports.array(askOptionSchema).min(2, "An ask step requires at least two options.").superRefine((options, ctx) => {
|
|
20167
|
+
const seen = /* @__PURE__ */ new Set();
|
|
20168
|
+
for (let index = 0; index < options.length; index++) {
|
|
20169
|
+
const value = options[index]?.value;
|
|
20170
|
+
if (value === void 0)
|
|
20171
|
+
continue;
|
|
20172
|
+
if (seen.has(value)) {
|
|
20173
|
+
ctx.addIssue({
|
|
20174
|
+
code: external_exports.ZodIssueCode.custom,
|
|
20175
|
+
message: `Duplicate option value "${value}". Option values must be unique within an ask step.`,
|
|
20176
|
+
path: [index, "value"]
|
|
20177
|
+
});
|
|
20178
|
+
}
|
|
20179
|
+
seen.add(value);
|
|
20180
|
+
}
|
|
20181
|
+
}).meta({ description: "Two or more options the user chooses between." });
|
|
20182
|
+
var askStepOutputSchema = stepOutputSchema.refine((schema) => {
|
|
20183
|
+
const properties = schema.properties;
|
|
20184
|
+
return schema.type === "object" && typeof properties === "object" && properties !== null && "choice" in properties;
|
|
20185
|
+
}, {
|
|
20186
|
+
message: 'Ask steps must declare an outputSchema of type "object" with a "choice" property.'
|
|
20187
|
+
}).meta({
|
|
20188
|
+
description: 'A JSON Schema describing the ask step output. Must be an object with a "choice" property whose value is one of the option values.'
|
|
20422
20189
|
});
|
|
20423
|
-
var
|
|
20424
|
-
|
|
20190
|
+
var askStepSchema = baseAskStepSchema.merge(external_exports.object({
|
|
20191
|
+
type: external_exports.literal("ask"),
|
|
20192
|
+
message: external_exports.string().min(1).meta({
|
|
20193
|
+
description: 'The short headline shown to the user, e.g. "Archive or delete 3 inactive projects?".'
|
|
20194
|
+
}),
|
|
20195
|
+
details: external_exports.string().optional().meta({
|
|
20196
|
+
description: "Optional longer markdown context, e.g. a preview of what each option would do."
|
|
20197
|
+
}),
|
|
20198
|
+
options: askOptionsSchema,
|
|
20199
|
+
expiresAfter: askExpiresAfterSchema.optional().default(ASK_EXPIRES_AFTER_DEFAULT),
|
|
20200
|
+
outputSchema: askStepOutputSchema
|
|
20201
|
+
})).strict();
|
|
20202
|
+
var stepSchema = external_exports.discriminatedUnion("type", [
|
|
20203
|
+
llmStepSchema,
|
|
20204
|
+
codegenStepSchema,
|
|
20205
|
+
codeStepSchema,
|
|
20206
|
+
searchStepSchema,
|
|
20207
|
+
delayStepSchema,
|
|
20208
|
+
askStepSchema
|
|
20209
|
+
]);
|
|
20210
|
+
var MANIFEST_VERSIONS = [0, 1];
|
|
20211
|
+
var CURRENT_MANIFEST_VERSION = MANIFEST_VERSIONS[MANIFEST_VERSIONS.length - 1];
|
|
20212
|
+
var manifestVersionSchema = (() => {
|
|
20213
|
+
const [firstVersion, ...otherVersions] = MANIFEST_VERSIONS;
|
|
20214
|
+
let schema = external_exports.literal(firstVersion);
|
|
20215
|
+
for (const version2 of otherVersions) {
|
|
20216
|
+
schema = schema.or(external_exports.literal(version2));
|
|
20217
|
+
}
|
|
20218
|
+
return schema;
|
|
20219
|
+
})().meta({
|
|
20220
|
+
description: `The version of the manifest schema. Latest is ${MANIFEST_VERSIONS[MANIFEST_VERSIONS.length - 1]}.`
|
|
20425
20221
|
});
|
|
20426
|
-
var
|
|
20427
|
-
|
|
20428
|
-
|
|
20222
|
+
var manifestSchemaBase = external_exports.object({
|
|
20223
|
+
manifestVersion: manifestVersionSchema,
|
|
20224
|
+
name: external_exports.string().min(1).meta({
|
|
20225
|
+
description: "A human-readable name for the automation that can include spaces."
|
|
20226
|
+
}),
|
|
20227
|
+
description: external_exports.string().meta({ description: "A human-readable description of the automation's purpose." }),
|
|
20228
|
+
triggers: triggersSchema,
|
|
20229
|
+
overlap: external_exports.enum([
|
|
20230
|
+
"skip",
|
|
20231
|
+
"buffer_one",
|
|
20232
|
+
"buffer_all",
|
|
20233
|
+
"cancel_other",
|
|
20234
|
+
"terminate_other",
|
|
20235
|
+
"allow_all"
|
|
20236
|
+
]).optional().default("skip").meta({
|
|
20237
|
+
description: 'Defines policy for overlapping runs. Defaults to "skip".'
|
|
20238
|
+
}),
|
|
20239
|
+
execution: executionPolicySchema.optional().meta({ description: "Global defaults for timeout and retry behavior." }),
|
|
20240
|
+
resultFrom: resultFromSchema.optional(),
|
|
20241
|
+
steps: external_exports.array(stepSchema).nonempty().meta({ description: "An ordered array of step objects that define the workflow." })
|
|
20242
|
+
}).meta({ description: "The root schema for an Automation Manifest, defining its behavior." });
|
|
20243
|
+
var manifestSchema = manifestSchemaBase.superRefine(validateManifestResultFrom).superRefine(validateManifestTemplateVariables).superRefine(validateManifestAskOverlap).superRefine(validateManifestAskChoiceEnum);
|
|
20244
|
+
var partialManifestSchema = manifestSchemaBase.partial().extend({
|
|
20245
|
+
// Override steps to allow empty array for drafts (remove .nonempty() requirement)
|
|
20246
|
+
steps: external_exports.array(stepSchema).default([]),
|
|
20247
|
+
// Override triggers to allow empty array for drafts (remove .nonempty() but keep invariants)
|
|
20248
|
+
triggers: external_exports.array(triggerSchema).superRefine(validateTriggersConstraints).optional()
|
|
20249
|
+
}).required({
|
|
20250
|
+
manifestVersion: true,
|
|
20251
|
+
steps: true
|
|
20429
20252
|
});
|
|
20430
|
-
|
|
20431
|
-
|
|
20432
|
-
var
|
|
20433
|
-
|
|
20434
|
-
|
|
20435
|
-
|
|
20436
|
-
|
|
20437
|
-
|
|
20438
|
-
|
|
20439
|
-
|
|
20440
|
-
|
|
20441
|
-
|
|
20442
|
-
|
|
20443
|
-
|
|
20444
|
-
"schema_validation",
|
|
20445
|
-
"template_variable_error",
|
|
20446
|
-
"invalid_configuration",
|
|
20447
|
-
"invalid_manifest",
|
|
20448
|
-
"automation_not_found",
|
|
20449
|
-
"timeout",
|
|
20450
|
-
"runtime_error",
|
|
20451
|
-
"insufficient_credit",
|
|
20452
|
-
"billing_unavailable",
|
|
20453
|
-
"unknown"
|
|
20454
|
-
];
|
|
20455
|
-
|
|
20456
|
-
// ../../packages/core/dist/esm/schemas/automation-run.schema.js
|
|
20457
|
-
var AUTOMATION_RUN_RESULT_TEXT_MAX_LENGTH = 4e3;
|
|
20458
|
-
var RunDateFilterSchema = external_exports.union([external_exports.iso.datetime({ offset: true }), external_exports.iso.date()]);
|
|
20459
|
-
var DATE_ONLY_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
|
|
20460
|
-
var MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1e3;
|
|
20461
|
-
function resolveRunDateRange({ since, until }) {
|
|
20462
|
-
const untilExclusive = until !== void 0 && DATE_ONLY_PATTERN.test(until);
|
|
20463
|
-
return {
|
|
20464
|
-
since: since ? new Date(DATE_ONLY_PATTERN.test(since) ? `${since}T00:00:00.000Z` : since) : void 0,
|
|
20465
|
-
until: until ? new Date(untilExclusive ? (/* @__PURE__ */ new Date(`${until}T00:00:00.000Z`)).getTime() + MILLISECONDS_PER_DAY : until) : void 0,
|
|
20466
|
-
untilExclusive
|
|
20467
|
-
};
|
|
20253
|
+
var templateVariableRegex = /\{\{\s*[\w.]+\s*\}\}/g;
|
|
20254
|
+
var codeStepReferenceRegex = /\bsteps\.([a-zA-Z][a-zA-Z0-9]*)(?:\.([a-zA-Z_][\w.]*))?/g;
|
|
20255
|
+
var backtickStepReferenceRegex = /`steps\.([a-zA-Z][a-zA-Z0-9]*)(?:\.([a-zA-Z_][\w.]*))?`/g;
|
|
20256
|
+
function extractStepReferences(text, regex) {
|
|
20257
|
+
const references = [];
|
|
20258
|
+
for (const match of text.matchAll(regex)) {
|
|
20259
|
+
const stepId = match[1];
|
|
20260
|
+
if (!stepId)
|
|
20261
|
+
continue;
|
|
20262
|
+
const propertyPathStr = match[2];
|
|
20263
|
+
const propertyPath = propertyPathStr ? propertyPathStr.split(".") : [];
|
|
20264
|
+
references.push({ stepId, propertyPath });
|
|
20265
|
+
}
|
|
20266
|
+
return references;
|
|
20468
20267
|
}
|
|
20469
|
-
|
|
20470
|
-
|
|
20471
|
-
|
|
20472
|
-
until: RunDateFilterSchema.optional()
|
|
20473
|
-
}).superRefine((query, ctx) => {
|
|
20474
|
-
const { since, until, untilExclusive } = resolveRunDateRange(query);
|
|
20475
|
-
if (!since || !until) {
|
|
20476
|
-
return;
|
|
20268
|
+
function validateGuardReference({ stepId, referencedStepId, currentStepGuard, referencedGuard, sourceType }) {
|
|
20269
|
+
if (referencedGuard === void 0 || referencedGuard === currentStepGuard) {
|
|
20270
|
+
return null;
|
|
20477
20271
|
}
|
|
20478
|
-
|
|
20479
|
-
|
|
20480
|
-
|
|
20481
|
-
|
|
20482
|
-
|
|
20483
|
-
message: "since must not be after until"
|
|
20484
|
-
});
|
|
20272
|
+
return `Step "${stepId}" ${sourceType} references step "${referencedStepId}", which only runs when \`if: ${referencedGuard}\`. A step may reference a conditional step only when it carries the identical \`if\` condition.`;
|
|
20273
|
+
}
|
|
20274
|
+
function validateStepReference({ stepId, referencedStepId, propertyPath, context, sourceType, currentStepGuard }) {
|
|
20275
|
+
if (!context.steps.has(referencedStepId)) {
|
|
20276
|
+
return `Step "${stepId}" ${sourceType} references step "${referencedStepId}" before it is available. Steps can only reference outputs from earlier steps.`;
|
|
20485
20277
|
}
|
|
20486
|
-
|
|
20487
|
-
|
|
20488
|
-
|
|
20489
|
-
|
|
20490
|
-
|
|
20491
|
-
|
|
20492
|
-
|
|
20493
|
-
|
|
20494
|
-
|
|
20495
|
-
id: external_exports.string(),
|
|
20496
|
-
automationId: external_exports.string(),
|
|
20497
|
-
status: external_exports.enum(AUTOMATION_RUN_STATUSES),
|
|
20498
|
-
createdAt: external_exports.string(),
|
|
20499
|
-
updatedAt: external_exports.string(),
|
|
20500
|
-
failureReason: external_exports.string().nullish(),
|
|
20501
|
-
failureCategory: external_exports.enum(FAILURE_CATEGORIES).nullish(),
|
|
20502
|
-
result: RolloutCompatibleAutomationRunResultSchema,
|
|
20503
|
-
temporalUrl: external_exports.string().nullish()
|
|
20504
|
-
});
|
|
20505
|
-
var MAX_TOOL_CALL_ARGUMENT_KEYS = 32;
|
|
20506
|
-
var MAX_TOOL_CALL_ARGUMENT_KEY_LENGTH = 64;
|
|
20507
|
-
var MAX_TOOL_CALL_PREVIEW_LENGTH = 500;
|
|
20508
|
-
var MAX_TOOL_CALLS_WITH_PREVIEWS = 20;
|
|
20509
|
-
var MAX_TOOL_CALL_PREVIEW_TOTAL_LENGTH = 2e3;
|
|
20510
|
-
var MAX_TOOL_CALL_ENTITY_LENGTH = 100;
|
|
20511
|
-
var MAX_TOOL_CALL_RESULT_PARSE_LENGTH = 1e4;
|
|
20512
|
-
var TOOL_CALL_OUTCOMES = ["data", "empty", "no-result", "error"];
|
|
20513
|
-
var TOOL_CALL_ERROR_CATEGORIES = [
|
|
20514
|
-
"authentication",
|
|
20515
|
-
"permission",
|
|
20516
|
-
"rate-limit",
|
|
20517
|
-
"timeout",
|
|
20518
|
-
"connection",
|
|
20519
|
-
"invalid-request",
|
|
20520
|
-
"unknown"
|
|
20521
|
-
];
|
|
20522
|
-
var ToolCallTimestampSchema = external_exports.union([external_exports.string(), external_exports.date()]).transform((timestamp) => timestamp instanceof Date ? timestamp.toISOString() : timestamp);
|
|
20523
|
-
var SafeToolCallDtoSchema = external_exports.object({
|
|
20524
|
-
id: external_exports.string(),
|
|
20525
|
-
name: external_exports.string(),
|
|
20526
|
-
argumentKeys: external_exports.array(external_exports.string()),
|
|
20527
|
-
hasResult: external_exports.boolean(),
|
|
20528
|
-
hasError: external_exports.boolean(),
|
|
20529
|
-
outcome: external_exports.enum(TOOL_CALL_OUTCOMES).optional(),
|
|
20530
|
-
errorCategory: external_exports.enum(TOOL_CALL_ERROR_CATEGORIES).optional(),
|
|
20531
|
-
resultPreview: external_exports.string().max(MAX_TOOL_CALL_PREVIEW_LENGTH).optional(),
|
|
20532
|
-
errorPreview: external_exports.string().max(MAX_TOOL_CALL_PREVIEW_LENGTH).optional(),
|
|
20533
|
-
timestamp: ToolCallTimestampSchema
|
|
20534
|
-
});
|
|
20535
|
-
var LegacyToolCallDtoInputSchema = external_exports.object({
|
|
20536
|
-
id: external_exports.string(),
|
|
20537
|
-
name: external_exports.string(),
|
|
20538
|
-
arguments: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
|
|
20539
|
-
result: external_exports.unknown().optional(),
|
|
20540
|
-
error: external_exports.unknown().optional(),
|
|
20541
|
-
errorStatus: external_exports.number().int().min(100).max(599).optional(),
|
|
20542
|
-
errorCode: external_exports.string().optional(),
|
|
20543
|
-
timestamp: ToolCallTimestampSchema
|
|
20544
|
-
});
|
|
20545
|
-
var ToolCallDtoInputSchema = external_exports.union([SafeToolCallDtoSchema, LegacyToolCallDtoInputSchema]);
|
|
20546
|
-
var ToolCallDtoSchema = external_exports.preprocess((toolCall) => {
|
|
20547
|
-
const parsed = ToolCallDtoInputSchema.safeParse(toolCall);
|
|
20548
|
-
return parsed.success ? normalizeToolCallDto(parsed.data) : toolCall;
|
|
20549
|
-
}, SafeToolCallDtoSchema);
|
|
20550
|
-
var ToolCallDtosSchema = external_exports.preprocess((toolCalls) => {
|
|
20551
|
-
if (!Array.isArray(toolCalls)) {
|
|
20552
|
-
return toolCalls;
|
|
20278
|
+
const guardError = validateGuardReference({
|
|
20279
|
+
stepId,
|
|
20280
|
+
referencedStepId,
|
|
20281
|
+
currentStepGuard,
|
|
20282
|
+
referencedGuard: context.guards.get(referencedStepId),
|
|
20283
|
+
sourceType
|
|
20284
|
+
});
|
|
20285
|
+
if (guardError) {
|
|
20286
|
+
return guardError;
|
|
20553
20287
|
}
|
|
20554
|
-
|
|
20555
|
-
|
|
20556
|
-
|
|
20557
|
-
|
|
20558
|
-
|
|
20559
|
-
|
|
20560
|
-
|
|
20561
|
-
|
|
20562
|
-
"run-result-not-configured",
|
|
20563
|
-
"run-result-empty"
|
|
20564
|
-
];
|
|
20565
|
-
var AutomationRunDebugReasonSchema = external_exports.enum(AUTOMATION_RUN_DEBUG_REASONS);
|
|
20566
|
-
var AutomationRunStepDtoOutputSchema = external_exports.object({
|
|
20567
|
-
stepId: external_exports.string(),
|
|
20568
|
-
type: external_exports.string(),
|
|
20569
|
-
description: external_exports.string(),
|
|
20570
|
-
status: external_exports.enum(AUTOMATION_RUN_STATUSES),
|
|
20571
|
-
startedAt: external_exports.string().optional(),
|
|
20572
|
-
completedAt: external_exports.string().optional(),
|
|
20573
|
-
result: external_exports.unknown().optional(),
|
|
20574
|
-
error: external_exports.string().optional(),
|
|
20575
|
-
generatedCode: external_exports.string().optional(),
|
|
20576
|
-
toolCalls: ToolCallDtosSchema.optional(),
|
|
20577
|
-
debugReason: AutomationRunDebugReasonSchema.optional()
|
|
20578
|
-
});
|
|
20579
|
-
var AutomationRunStepDtoSchema = AutomationRunStepDtoOutputSchema;
|
|
20580
|
-
var AutomationRunDetailDtoSchema = external_exports.object({
|
|
20581
|
-
id: external_exports.string(),
|
|
20582
|
-
automationId: external_exports.string(),
|
|
20583
|
-
status: external_exports.enum([...AUTOMATION_RUN_STATUSES, "data-expired"]),
|
|
20584
|
-
createdAt: external_exports.string(),
|
|
20585
|
-
updatedAt: external_exports.string(),
|
|
20586
|
-
failureReason: external_exports.string().nullish(),
|
|
20587
|
-
failureCategory: external_exports.enum(FAILURE_CATEGORIES).nullish(),
|
|
20588
|
-
result: RolloutCompatibleAutomationRunResultSchema,
|
|
20589
|
-
temporalUrl: external_exports.string().nullish(),
|
|
20590
|
-
steps: external_exports.array(AutomationRunStepDtoSchema)
|
|
20591
|
-
});
|
|
20592
|
-
function summarizeToolCallArgumentKeys(args) {
|
|
20593
|
-
const keys = Object.keys(args ?? {}).sort();
|
|
20594
|
-
const kept = keys.slice(0, MAX_TOOL_CALL_ARGUMENT_KEYS).map((key) => key.length > MAX_TOOL_CALL_ARGUMENT_KEY_LENGTH ? `${key.slice(0, MAX_TOOL_CALL_ARGUMENT_KEY_LENGTH)}\u2026` : key);
|
|
20595
|
-
if (keys.length > MAX_TOOL_CALL_ARGUMENT_KEYS) {
|
|
20596
|
-
kept.push(`\u2026+${keys.length - MAX_TOOL_CALL_ARGUMENT_KEYS} more`);
|
|
20288
|
+
if (propertyPath.length > 0) {
|
|
20289
|
+
const stepOutputSchema2 = context.steps.get(referencedStepId);
|
|
20290
|
+
if (stepOutputSchema2) {
|
|
20291
|
+
const isValid = validatePropertyPathInSchema(stepOutputSchema2, propertyPath);
|
|
20292
|
+
if (!isValid) {
|
|
20293
|
+
return `Step "${stepId}" ${sourceType} references "steps.${referencedStepId}.${propertyPath.join(".")}" but this property path does not exist in step "${referencedStepId}"'s outputSchema.`;
|
|
20294
|
+
}
|
|
20295
|
+
}
|
|
20597
20296
|
}
|
|
20598
|
-
return
|
|
20297
|
+
return null;
|
|
20599
20298
|
}
|
|
20600
|
-
function
|
|
20601
|
-
|
|
20602
|
-
|
|
20299
|
+
function validateTemplateVariable({ variable, context, stepId, currentStepGuard, sourceType = "prompt" }) {
|
|
20300
|
+
const parts = variable.split(".").filter(Boolean);
|
|
20301
|
+
if (parts.length === 0) {
|
|
20302
|
+
return null;
|
|
20603
20303
|
}
|
|
20604
|
-
|
|
20605
|
-
|
|
20304
|
+
const [root13, ...rest] = parts;
|
|
20305
|
+
if (root13 === "trigger") {
|
|
20306
|
+
if (rest.length === 0) {
|
|
20307
|
+
return `Step "${stepId}" ${sourceType} references "{{trigger}}" without a property. Use {{trigger.<property>}} syntax (e.g., {{trigger.payload}}, {{trigger.metadata}}).`;
|
|
20308
|
+
}
|
|
20309
|
+
if (context.triggerType === "schedule" && rest[0] === "payload") {
|
|
20310
|
+
return `Step "${stepId}" references "{{trigger.payload}}" but schedule triggers have no payload. Add a step to fetch the data you need.`;
|
|
20311
|
+
}
|
|
20312
|
+
if (context.triggerType === "schedule" && rest[0] === "user") {
|
|
20313
|
+
if (context.scheduleInjectsTimezone && rest.length === 2 && rest[1] === "timezone") {
|
|
20314
|
+
return null;
|
|
20315
|
+
}
|
|
20316
|
+
return `Step "${stepId}" ${sourceType} references "{{trigger.${rest.join(".")}}}" but schedule triggers only provide "{{trigger.user.timezone}}", and only for cron schedules with a timezone. Interval schedules provide no trigger data.`;
|
|
20317
|
+
}
|
|
20318
|
+
if (context.triggerOutputSchemas.length > 0) {
|
|
20319
|
+
const invalidSchemas = context.triggerOutputSchemas.filter((schema) => !validatePropertyPathInSchema(schema, rest));
|
|
20320
|
+
if (invalidSchemas.length > 0) {
|
|
20321
|
+
return `Step "${stepId}" ${sourceType} references "{{trigger.${rest.join(".")}}}" but this property path does not exist in all trigger outputSchemas. The path must be valid for every trigger since any one may fire the automation.`;
|
|
20322
|
+
}
|
|
20323
|
+
} else {
|
|
20324
|
+
return `Step "${stepId}" ${sourceType} references "{{trigger.${rest.join(".")}}}" but this trigger type has no outputSchema and cannot provide trigger data at runtime.`;
|
|
20325
|
+
}
|
|
20326
|
+
return null;
|
|
20606
20327
|
}
|
|
20607
|
-
if (
|
|
20608
|
-
const
|
|
20609
|
-
|
|
20328
|
+
if (root13 === "steps") {
|
|
20329
|
+
const referencedStepId = rest[0];
|
|
20330
|
+
if (!referencedStepId) {
|
|
20331
|
+
return `Step "${stepId}" ${sourceType} references "steps" but is missing the step identifier in template variable "{{${variable}}}". Use {{steps.<stepId>}} syntax.`;
|
|
20332
|
+
}
|
|
20333
|
+
return validateStepReference({
|
|
20334
|
+
stepId,
|
|
20335
|
+
referencedStepId,
|
|
20336
|
+
propertyPath: rest.slice(1),
|
|
20337
|
+
context,
|
|
20338
|
+
sourceType,
|
|
20339
|
+
currentStepGuard
|
|
20340
|
+
});
|
|
20610
20341
|
}
|
|
20611
|
-
return
|
|
20342
|
+
return `Step "${stepId}" ${sourceType} references unsupported template variable "{{${variable}}}". Allowed roots are {{trigger...}} and {{steps.<stepId>...}}.`;
|
|
20612
20343
|
}
|
|
20613
|
-
function
|
|
20614
|
-
const
|
|
20615
|
-
|
|
20616
|
-
|
|
20617
|
-
|
|
20618
|
-
|
|
20619
|
-
|
|
20620
|
-
const textCollection = typeof payload === "string" && payload.length > MAX_TOOL_CALL_RESULT_PARSE_LENGTH ? null : getTextCollectionSummary(result, tool);
|
|
20621
|
-
const outcome = collection?.length === 0 || textCollection === 0 ? "empty" : "data";
|
|
20622
|
-
if (collection) {
|
|
20623
|
-
const summary = `${tool.action} ${collection.length} ${formatEntity(tool.entity, collection.length)}`;
|
|
20624
|
-
const projectCount = getProjectCount(collection, tool.entity);
|
|
20625
|
-
return {
|
|
20626
|
-
outcome,
|
|
20627
|
-
preview: truncateToolCallPreview(projectCount > 1 ? `${summary} across ${projectCount} projects` : summary)
|
|
20628
|
-
};
|
|
20629
|
-
}
|
|
20630
|
-
if (textCollection !== null) {
|
|
20631
|
-
return {
|
|
20632
|
-
outcome,
|
|
20633
|
-
preview: truncateToolCallPreview(`${tool.action} ${textCollection} ${formatEntity(tool.entity, textCollection)}`)
|
|
20634
|
-
};
|
|
20635
|
-
}
|
|
20636
|
-
if (isRecord(result) && !["Found", "Returned"].includes(tool.action)) {
|
|
20637
|
-
return {
|
|
20638
|
-
outcome,
|
|
20639
|
-
preview: truncateToolCallPreview(tool.action === "Retrieved" ? `Retrieved ${tool.entity} details` : `${tool.action} ${formatEntity(tool.entity, 1)}`)
|
|
20640
|
-
};
|
|
20344
|
+
function extractTemplateVariables(prompt) {
|
|
20345
|
+
const variables = [];
|
|
20346
|
+
for (const match of prompt.matchAll(templateVariableRegex)) {
|
|
20347
|
+
const variable = match[0]?.replace(/\{\{\s*|\s*\}\}/g, "").trim();
|
|
20348
|
+
if (variable) {
|
|
20349
|
+
variables.push(variable);
|
|
20350
|
+
}
|
|
20641
20351
|
}
|
|
20642
|
-
return
|
|
20352
|
+
return variables;
|
|
20643
20353
|
}
|
|
20644
|
-
function
|
|
20645
|
-
if (
|
|
20646
|
-
return
|
|
20354
|
+
function resolveTriggersFromData(data) {
|
|
20355
|
+
if (data.triggers && Array.isArray(data.triggers) && data.triggers.length > 0) {
|
|
20356
|
+
return data.triggers;
|
|
20647
20357
|
}
|
|
20648
|
-
return
|
|
20649
|
-
}
|
|
20650
|
-
function summarizePayloadSize(payload) {
|
|
20651
|
-
return `${payload.length} character${payload.length === 1 ? "" : "s"} returned`;
|
|
20652
|
-
}
|
|
20653
|
-
function summarizeToolCallsWithPreviewLimits(toolCalls, summarize) {
|
|
20654
|
-
let previewsKept = 0;
|
|
20655
|
-
let previewLength = 0;
|
|
20656
|
-
return toolCalls.map((toolCall) => {
|
|
20657
|
-
const shouldIncludePreview = previewsKept < MAX_TOOL_CALLS_WITH_PREVIEWS && previewLength < MAX_TOOL_CALL_PREVIEW_TOTAL_LENGTH;
|
|
20658
|
-
const summary = summarize(toolCall, { includePreview: shouldIncludePreview });
|
|
20659
|
-
const nextPreviewLength = (summary.resultPreview?.length ?? 0) + (summary.errorPreview?.length ?? 0);
|
|
20660
|
-
if (nextPreviewLength === 0 || previewsKept < MAX_TOOL_CALLS_WITH_PREVIEWS && previewLength + nextPreviewLength <= MAX_TOOL_CALL_PREVIEW_TOTAL_LENGTH) {
|
|
20661
|
-
previewsKept += nextPreviewLength > 0 ? 1 : 0;
|
|
20662
|
-
previewLength += nextPreviewLength;
|
|
20663
|
-
return summary;
|
|
20664
|
-
}
|
|
20665
|
-
return stripToolCallPreviews(summary);
|
|
20666
|
-
});
|
|
20667
|
-
}
|
|
20668
|
-
function normalizeToolCallDtos(toolCalls) {
|
|
20669
|
-
return summarizeToolCallsWithPreviewLimits(toolCalls, normalizeToolCallDto);
|
|
20358
|
+
return [];
|
|
20670
20359
|
}
|
|
20671
|
-
|
|
20672
|
-
|
|
20673
|
-
|
|
20674
|
-
|
|
20360
|
+
var BOUNDED_OVERLAP_MODES = ["skip", "buffer_one", "cancel_other", "terminate_other"];
|
|
20361
|
+
function validateManifestAskOverlap(data, ctx) {
|
|
20362
|
+
const steps = data.steps || [];
|
|
20363
|
+
const hasAskStep = steps.some((step) => step?.type === "ask");
|
|
20364
|
+
if (!hasAskStep)
|
|
20365
|
+
return;
|
|
20366
|
+
const overlap = data.overlap ?? "skip";
|
|
20367
|
+
if (!BOUNDED_OVERLAP_MODES.includes(overlap)) {
|
|
20368
|
+
ctx.addIssue({
|
|
20369
|
+
code: external_exports.ZodIssueCode.custom,
|
|
20370
|
+
message: `Manifests with an ask step must use a bounded overlap mode (${BOUNDED_OVERLAP_MODES.join(", ")}). "${overlap}" can accumulate parked or buffered runs while a prompt waits for a response.`,
|
|
20371
|
+
path: ["overlap"]
|
|
20372
|
+
});
|
|
20675
20373
|
}
|
|
20676
|
-
const hasResult = hasToolCallResult(toolCall.result);
|
|
20677
|
-
const resultSummary = includePreview && hasResult ? summarizeToolCallResult(toolCall.name, toolCall.result) : void 0;
|
|
20678
|
-
const diagnostic = toolCall.error === void 0 && resultSummary ? { outcome: resultSummary.outcome } : classifyToolCallOutcome(toolCall.name, toolCall.result, toolCall.error, {
|
|
20679
|
-
status: toolCall.errorStatus,
|
|
20680
|
-
code: toolCall.errorCode
|
|
20681
|
-
});
|
|
20682
|
-
return {
|
|
20683
|
-
id: toolCall.id,
|
|
20684
|
-
name: toolCall.name,
|
|
20685
|
-
argumentKeys: summarizeToolCallArgumentKeys(toolCall.arguments),
|
|
20686
|
-
hasResult,
|
|
20687
|
-
hasError: toolCall.error !== void 0,
|
|
20688
|
-
outcome: diagnostic.outcome,
|
|
20689
|
-
...diagnostic.errorCategory ? { errorCategory: diagnostic.errorCategory } : {},
|
|
20690
|
-
...resultSummary ? { resultPreview: resultSummary.preview } : {},
|
|
20691
|
-
...includePreview && toolCall.error !== void 0 ? { errorPreview: summarizeToolCallPayloadPreview(toolCall.error) } : {},
|
|
20692
|
-
timestamp: toolCall.timestamp
|
|
20693
|
-
};
|
|
20694
20374
|
}
|
|
20695
|
-
function
|
|
20696
|
-
|
|
20697
|
-
|
|
20698
|
-
|
|
20699
|
-
|
|
20700
|
-
|
|
20701
|
-
|
|
20702
|
-
|
|
20703
|
-
|
|
20704
|
-
|
|
20705
|
-
|
|
20706
|
-
|
|
20707
|
-
}
|
|
20708
|
-
|
|
20709
|
-
|
|
20710
|
-
|
|
20711
|
-
|
|
20712
|
-
|
|
20375
|
+
function validateManifestAskChoiceEnum(data, ctx) {
|
|
20376
|
+
const steps = data.steps || [];
|
|
20377
|
+
for (let stepIndex = 0; stepIndex < steps.length; stepIndex++) {
|
|
20378
|
+
const step = steps[stepIndex];
|
|
20379
|
+
if (!step || step.type !== "ask")
|
|
20380
|
+
continue;
|
|
20381
|
+
const choicePath = ["steps", stepIndex, "outputSchema", "properties", "choice", "enum"];
|
|
20382
|
+
const choiceSchema = step.outputSchema?.properties?.choice;
|
|
20383
|
+
const choiceEnum = choiceSchema?.enum;
|
|
20384
|
+
if (!Array.isArray(choiceEnum)) {
|
|
20385
|
+
ctx.addIssue({
|
|
20386
|
+
code: external_exports.ZodIssueCode.custom,
|
|
20387
|
+
message: `Ask step "${step.id ?? stepIndex}" outputSchema must declare choice as an enum of the option values.`,
|
|
20388
|
+
path: choicePath
|
|
20389
|
+
});
|
|
20390
|
+
continue;
|
|
20391
|
+
}
|
|
20392
|
+
const nonStringEnum = choiceEnum.filter((value) => typeof value !== "string");
|
|
20393
|
+
if (nonStringEnum.length > 0) {
|
|
20394
|
+
ctx.addIssue({
|
|
20395
|
+
code: external_exports.ZodIssueCode.custom,
|
|
20396
|
+
message: `Ask step "${step.id ?? stepIndex}" outputSchema choice enum must contain only string values; ask options always emit strings.`,
|
|
20397
|
+
path: choicePath
|
|
20398
|
+
});
|
|
20399
|
+
continue;
|
|
20400
|
+
}
|
|
20401
|
+
const optionValues = (step.options ?? []).map((option) => option?.value).filter((value) => typeof value === "string");
|
|
20402
|
+
const optionSet = new Set(optionValues);
|
|
20403
|
+
const enumSet = new Set(choiceEnum);
|
|
20404
|
+
const missing = optionValues.filter((value) => !enumSet.has(value));
|
|
20405
|
+
const unexpected = choiceEnum.filter((value) => !optionSet.has(value));
|
|
20406
|
+
if (missing.length === 0 && unexpected.length === 0)
|
|
20407
|
+
continue;
|
|
20408
|
+
const detail = [
|
|
20409
|
+
missing.length > 0 ? `missing ${missing.map((v) => `'${v}'`).join(", ")}` : "",
|
|
20410
|
+
unexpected.length > 0 ? `unexpected ${unexpected.map((v) => `'${v}'`).join(", ")}` : ""
|
|
20411
|
+
].filter(Boolean).join("; ");
|
|
20412
|
+
ctx.addIssue({
|
|
20413
|
+
code: external_exports.ZodIssueCode.custom,
|
|
20414
|
+
message: `Ask step "${step.id ?? stepIndex}" outputSchema choice enum must list exactly the option values (${detail}).`,
|
|
20415
|
+
path: choicePath
|
|
20416
|
+
});
|
|
20417
|
+
}
|
|
20713
20418
|
}
|
|
20714
|
-
function
|
|
20715
|
-
if (
|
|
20716
|
-
return
|
|
20419
|
+
function validateManifestResultFrom(data, ctx) {
|
|
20420
|
+
if (!data.resultFrom) {
|
|
20421
|
+
return;
|
|
20717
20422
|
}
|
|
20718
|
-
|
|
20719
|
-
|
|
20720
|
-
|
|
20721
|
-
|
|
20722
|
-
|
|
20723
|
-
|
|
20724
|
-
|
|
20725
|
-
|
|
20726
|
-
|
|
20423
|
+
const steps = data.steps || [];
|
|
20424
|
+
const referencedStep = steps.find((step) => step.id === data.resultFrom?.stepId);
|
|
20425
|
+
if (!referencedStep) {
|
|
20426
|
+
ctx.addIssue({
|
|
20427
|
+
code: external_exports.ZodIssueCode.custom,
|
|
20428
|
+
message: `resultFrom.stepId references unknown step "${data.resultFrom.stepId}".`,
|
|
20429
|
+
path: ["resultFrom", "stepId"]
|
|
20430
|
+
});
|
|
20431
|
+
return;
|
|
20727
20432
|
}
|
|
20728
|
-
|
|
20729
|
-
|
|
20730
|
-
|
|
20731
|
-
|
|
20732
|
-
|
|
20433
|
+
if (referencedStep.if) {
|
|
20434
|
+
ctx.addIssue({
|
|
20435
|
+
code: external_exports.ZodIssueCode.custom,
|
|
20436
|
+
message: `resultFrom.stepId references step "${referencedStep.id}", which only runs conditionally (\`if\`). resultFrom must point at a step that always runs.`,
|
|
20437
|
+
path: ["resultFrom", "stepId"]
|
|
20438
|
+
});
|
|
20439
|
+
return;
|
|
20733
20440
|
}
|
|
20734
|
-
const
|
|
20735
|
-
if (
|
|
20736
|
-
|
|
20441
|
+
const outputSchema = referencedStep.outputSchema;
|
|
20442
|
+
if (!outputSchema) {
|
|
20443
|
+
ctx.addIssue({
|
|
20444
|
+
code: external_exports.ZodIssueCode.custom,
|
|
20445
|
+
message: `resultFrom.stepId references step "${referencedStep.id}" without an outputSchema.`,
|
|
20446
|
+
path: ["resultFrom", "stepId"]
|
|
20447
|
+
});
|
|
20448
|
+
return;
|
|
20449
|
+
}
|
|
20450
|
+
if (!data.resultFrom.path) {
|
|
20451
|
+
if (!isPlainStringSchema(outputSchema)) {
|
|
20452
|
+
ctx.addIssue({
|
|
20453
|
+
code: external_exports.ZodIssueCode.custom,
|
|
20454
|
+
message: "resultFrom.path may be omitted only when the referenced step outputSchema is a string.",
|
|
20455
|
+
path: ["resultFrom", "path"]
|
|
20456
|
+
});
|
|
20457
|
+
}
|
|
20458
|
+
return;
|
|
20459
|
+
}
|
|
20460
|
+
const propertyPath = data.resultFrom.path.split(".");
|
|
20461
|
+
const resolvedSchema = resolvePropertySchemaInSchema(outputSchema, propertyPath);
|
|
20462
|
+
if (!resolvedSchema) {
|
|
20463
|
+
ctx.addIssue({
|
|
20464
|
+
code: external_exports.ZodIssueCode.custom,
|
|
20465
|
+
message: `resultFrom.path "${data.resultFrom.path}" does not exist in step "${referencedStep.id}" outputSchema.`,
|
|
20466
|
+
path: ["resultFrom", "path"]
|
|
20467
|
+
});
|
|
20468
|
+
return;
|
|
20469
|
+
}
|
|
20470
|
+
if (!isStringTypedSchema(resolvedSchema)) {
|
|
20471
|
+
ctx.addIssue({
|
|
20472
|
+
code: external_exports.ZodIssueCode.custom,
|
|
20473
|
+
message: "resultFrom.path must resolve to a string value.",
|
|
20474
|
+
path: ["resultFrom", "path"]
|
|
20475
|
+
});
|
|
20737
20476
|
}
|
|
20738
|
-
return "unknown";
|
|
20739
|
-
}
|
|
20740
|
-
function classifyToolCallHttpStatus(status) {
|
|
20741
|
-
if (status === 401)
|
|
20742
|
-
return "authentication";
|
|
20743
|
-
if (status === 403)
|
|
20744
|
-
return "permission";
|
|
20745
|
-
if (status === 429)
|
|
20746
|
-
return "rate-limit";
|
|
20747
|
-
if (status === 400)
|
|
20748
|
-
return "invalid-request";
|
|
20749
|
-
if (status === 408 || status === 504)
|
|
20750
|
-
return "timeout";
|
|
20751
|
-
return void 0;
|
|
20752
20477
|
}
|
|
20753
|
-
function
|
|
20754
|
-
const
|
|
20755
|
-
if (
|
|
20756
|
-
return
|
|
20757
|
-
if (
|
|
20758
|
-
return
|
|
20759
|
-
|
|
20478
|
+
function isNonScalarSchema(schema) {
|
|
20479
|
+
const type = schema.type;
|
|
20480
|
+
if (type === "object" || type === "array")
|
|
20481
|
+
return true;
|
|
20482
|
+
if (Array.isArray(type) && (type.includes("object") || type.includes("array")))
|
|
20483
|
+
return true;
|
|
20484
|
+
const structural = schema;
|
|
20485
|
+
return structural.properties !== void 0 || structural.items !== void 0;
|
|
20760
20486
|
}
|
|
20761
|
-
function
|
|
20762
|
-
|
|
20763
|
-
|
|
20487
|
+
function ifConditionLiteralError({ reference, literal: literal2, stepId, schema }) {
|
|
20488
|
+
const enumValues = schema.enum;
|
|
20489
|
+
if (Array.isArray(enumValues)) {
|
|
20490
|
+
if (enumValues.some((value) => String(value) === literal2))
|
|
20491
|
+
return null;
|
|
20492
|
+
const allowed = enumValues.map((value) => `'${String(value)}'`).join(", ");
|
|
20493
|
+
return `Step "${stepId}" condition compares "${reference}" to '${literal2}', which is not one of its allowed values: ${allowed}.`;
|
|
20764
20494
|
}
|
|
20765
|
-
|
|
20766
|
-
|
|
20767
|
-
try {
|
|
20768
|
-
parsed = JSON.parse(parsed);
|
|
20769
|
-
} catch {
|
|
20770
|
-
break;
|
|
20771
|
-
}
|
|
20495
|
+
if (isNonScalarSchema(schema)) {
|
|
20496
|
+
return `Step "${stepId}" condition compares "${reference}", which is an object or array, to a string literal and can never match. Reference a scalar property instead.`;
|
|
20772
20497
|
}
|
|
20773
|
-
return
|
|
20498
|
+
return null;
|
|
20774
20499
|
}
|
|
20775
|
-
function
|
|
20776
|
-
|
|
20500
|
+
function validateIfConditionLiteral({ condition, context, stepId }) {
|
|
20501
|
+
const parsed = parseIfCondition(condition);
|
|
20502
|
+
if (!parsed)
|
|
20777
20503
|
return null;
|
|
20504
|
+
const { reference, literal: literal2 } = parsed;
|
|
20505
|
+
const parts = reference.split(".");
|
|
20506
|
+
if (parts[0] === "steps") {
|
|
20507
|
+
const referencedStepId = parts[1];
|
|
20508
|
+
if (!referencedStepId)
|
|
20509
|
+
return null;
|
|
20510
|
+
const outputSchema = context.steps.get(referencedStepId);
|
|
20511
|
+
if (!outputSchema)
|
|
20512
|
+
return null;
|
|
20513
|
+
const propertyPath = parts.slice(2);
|
|
20514
|
+
const resolved = propertyPath.length === 0 ? outputSchema : resolvePropertySchemaInSchema(outputSchema, propertyPath);
|
|
20515
|
+
if (!resolved)
|
|
20516
|
+
return null;
|
|
20517
|
+
return ifConditionLiteralError({ reference, literal: literal2, stepId, schema: resolved });
|
|
20778
20518
|
}
|
|
20779
|
-
|
|
20780
|
-
|
|
20781
|
-
|
|
20519
|
+
if (parts[0] === "trigger") {
|
|
20520
|
+
const propertyPath = parts.slice(1);
|
|
20521
|
+
if (propertyPath.length === 0)
|
|
20522
|
+
return null;
|
|
20523
|
+
let firstError = null;
|
|
20524
|
+
let anyResolved = false;
|
|
20525
|
+
for (const schema of context.triggerOutputSchemas) {
|
|
20526
|
+
const resolved = resolvePropertySchemaInSchema(schema, propertyPath);
|
|
20527
|
+
if (!resolved)
|
|
20528
|
+
continue;
|
|
20529
|
+
anyResolved = true;
|
|
20530
|
+
const error61 = ifConditionLiteralError({ reference, literal: literal2, stepId, schema: resolved });
|
|
20531
|
+
if (!error61)
|
|
20532
|
+
return null;
|
|
20533
|
+
firstError ??= error61;
|
|
20534
|
+
}
|
|
20535
|
+
return anyResolved ? firstError : null;
|
|
20782
20536
|
}
|
|
20783
|
-
|
|
20784
|
-
return Number.isSafeInteger(count) && count >= 0 ? count : null;
|
|
20537
|
+
return null;
|
|
20785
20538
|
}
|
|
20786
|
-
function
|
|
20787
|
-
const
|
|
20788
|
-
|
|
20789
|
-
|
|
20790
|
-
|
|
20539
|
+
function validateManifestTemplateVariables(data, ctx) {
|
|
20540
|
+
const triggers = resolveTriggersFromData(data);
|
|
20541
|
+
const firstTrigger = triggers[0];
|
|
20542
|
+
const scheduleValue = firstTrigger?.value;
|
|
20543
|
+
const scheduleInjectsTimezone = firstTrigger?.type === "schedule" && typeof scheduleValue === "object" && scheduleValue !== null && typeof scheduleValue.timezone === "string";
|
|
20544
|
+
const context = {
|
|
20545
|
+
triggerType: firstTrigger?.type,
|
|
20546
|
+
scheduleInjectsTimezone,
|
|
20547
|
+
triggerOutputSchemas: [],
|
|
20548
|
+
steps: /* @__PURE__ */ new Map(),
|
|
20549
|
+
guards: /* @__PURE__ */ new Map()
|
|
20791
20550
|
};
|
|
20792
|
-
|
|
20793
|
-
|
|
20794
|
-
|
|
20795
|
-
|
|
20796
|
-
if (tokens.some((token) => ["get", "read", "retrieve"].includes(token)))
|
|
20797
|
-
return "Retrieved";
|
|
20798
|
-
if (tokens.some((token) => ["add", "create"].includes(token)))
|
|
20799
|
-
return "Created";
|
|
20800
|
-
if (tokens.some((token) => ["update", "edit", "modify"].includes(token)))
|
|
20801
|
-
return "Updated";
|
|
20802
|
-
if (tokens.some((token) => ["delete", "remove"].includes(token)))
|
|
20803
|
-
return "Deleted";
|
|
20804
|
-
if (tokens.some((token) => ["uncomplete", "reopen"].includes(token)))
|
|
20805
|
-
return "Reopened";
|
|
20806
|
-
if (tokens.some((token) => ["complete", "close"].includes(token)))
|
|
20807
|
-
return "Completed";
|
|
20808
|
-
if (tokens.includes("archive"))
|
|
20809
|
-
return "Archived";
|
|
20810
|
-
if (tokens.some((token) => ["send", "reply", "post", "publish", "notify"].includes(token)))
|
|
20811
|
-
return "Sent";
|
|
20812
|
-
if (tokens.some((token) => ["copy", "clone", "duplicate"].includes(token)))
|
|
20813
|
-
return "Copied";
|
|
20814
|
-
if (tokens.some((token) => ["move", "transfer"].includes(token)))
|
|
20815
|
-
return "Moved";
|
|
20816
|
-
if (tokens.includes("rename"))
|
|
20817
|
-
return "Renamed";
|
|
20818
|
-
if (tokens.includes("trash"))
|
|
20819
|
-
return "Trashed";
|
|
20820
|
-
if (tokens.some((token) => ["restore", "untrash"].includes(token)))
|
|
20821
|
-
return "Restored";
|
|
20822
|
-
if (tokens.some((token) => ["append", "insert", "replace"].includes(token)))
|
|
20823
|
-
return "Updated";
|
|
20824
|
-
return "Returned";
|
|
20825
|
-
}
|
|
20826
|
-
function getToolCallEntity(tokens) {
|
|
20827
|
-
const actionIndex = tokens.findIndex((token) => TOOL_CALL_ACTION_TOKENS.has(token));
|
|
20828
|
-
const entityTokens = tokens.slice(actionIndex + 1);
|
|
20829
|
-
const qualifierIndex = entityTokens.findIndex((token) => TOOL_CALL_FILLER_TOKENS.has(token));
|
|
20830
|
-
const primaryTokens = qualifierIndex > 0 ? entityTokens.slice(0, qualifierIndex) : entityTokens;
|
|
20831
|
-
const entity = [...primaryTokens].reverse().find((token) => token.length > 1 && !TOOL_CALL_FILLER_TOKENS.has(token));
|
|
20832
|
-
return entity ? truncateToolCallEntity(singularize(entity)) : "item";
|
|
20833
|
-
}
|
|
20834
|
-
var TOOL_CALL_ACTION_TOKENS = /* @__PURE__ */ new Set([
|
|
20835
|
-
"find",
|
|
20836
|
-
"search",
|
|
20837
|
-
"list",
|
|
20838
|
-
"get",
|
|
20839
|
-
"read",
|
|
20840
|
-
"retrieve",
|
|
20841
|
-
"add",
|
|
20842
|
-
"create",
|
|
20843
|
-
"update",
|
|
20844
|
-
"edit",
|
|
20845
|
-
"modify",
|
|
20846
|
-
"delete",
|
|
20847
|
-
"remove",
|
|
20848
|
-
"uncomplete",
|
|
20849
|
-
"reopen",
|
|
20850
|
-
"complete",
|
|
20851
|
-
"close",
|
|
20852
|
-
"archive",
|
|
20853
|
-
"send",
|
|
20854
|
-
"reply",
|
|
20855
|
-
"post",
|
|
20856
|
-
"publish",
|
|
20857
|
-
"notify",
|
|
20858
|
-
"copy",
|
|
20859
|
-
"clone",
|
|
20860
|
-
"duplicate",
|
|
20861
|
-
"move",
|
|
20862
|
-
"transfer",
|
|
20863
|
-
"rename",
|
|
20864
|
-
"trash",
|
|
20865
|
-
"restore",
|
|
20866
|
-
"untrash",
|
|
20867
|
-
"append",
|
|
20868
|
-
"insert",
|
|
20869
|
-
"replace"
|
|
20870
|
-
]);
|
|
20871
|
-
var TOOL_CALL_FILLER_TOKENS = /* @__PURE__ */ new Set(["by", "to", "from", "for", "with", "all"]);
|
|
20872
|
-
function getResultCollection(payload, entity) {
|
|
20873
|
-
if (Array.isArray(payload)) {
|
|
20874
|
-
return payload;
|
|
20875
|
-
}
|
|
20876
|
-
if (!isRecord(payload)) {
|
|
20877
|
-
return null;
|
|
20878
|
-
}
|
|
20879
|
-
const collection = payload[entity] ?? payload[pluralize(entity)] ?? payload[`${entity}s`] ?? payload.items ?? payload.data ?? payload.results ?? payload.value;
|
|
20880
|
-
return Array.isArray(collection) ? collection : null;
|
|
20881
|
-
}
|
|
20882
|
-
function getProjectCount(items, entity) {
|
|
20883
|
-
if (entity !== "task") {
|
|
20884
|
-
return 0;
|
|
20551
|
+
for (const trigger of triggers) {
|
|
20552
|
+
if ((trigger.type === "webhook" || trigger.type === "api" || trigger.type === "manual") && trigger.outputSchema) {
|
|
20553
|
+
context.triggerOutputSchemas.push(trigger.outputSchema);
|
|
20554
|
+
}
|
|
20885
20555
|
}
|
|
20886
|
-
const
|
|
20887
|
-
for (
|
|
20888
|
-
|
|
20556
|
+
const steps = data.steps || [];
|
|
20557
|
+
for (let stepIndex = 0; stepIndex < steps.length; stepIndex++) {
|
|
20558
|
+
const step = steps[stepIndex];
|
|
20559
|
+
if (!step)
|
|
20889
20560
|
continue;
|
|
20561
|
+
const currentStepGuard = step.if;
|
|
20562
|
+
const unavailableStepRefs = /* @__PURE__ */ new Set();
|
|
20563
|
+
const propertyPathErrors = [];
|
|
20564
|
+
const processStepRef = (ref, sourceType, fieldPath) => {
|
|
20565
|
+
if (!context.steps.has(ref.stepId)) {
|
|
20566
|
+
unavailableStepRefs.add(ref.stepId);
|
|
20567
|
+
return;
|
|
20568
|
+
}
|
|
20569
|
+
const guardError = validateGuardReference({
|
|
20570
|
+
stepId: step.id,
|
|
20571
|
+
referencedStepId: ref.stepId,
|
|
20572
|
+
currentStepGuard,
|
|
20573
|
+
referencedGuard: context.guards.get(ref.stepId),
|
|
20574
|
+
sourceType
|
|
20575
|
+
});
|
|
20576
|
+
if (guardError) {
|
|
20577
|
+
propertyPathErrors.push({ message: guardError, path: fieldPath });
|
|
20578
|
+
return;
|
|
20579
|
+
}
|
|
20580
|
+
const stepOutputSchema2 = context.steps.get(ref.stepId);
|
|
20581
|
+
if (!stepOutputSchema2 || ref.propertyPath.length === 0) {
|
|
20582
|
+
return;
|
|
20583
|
+
}
|
|
20584
|
+
const isValid = validatePropertyPathInSchema(stepOutputSchema2, ref.propertyPath);
|
|
20585
|
+
if (!isValid) {
|
|
20586
|
+
propertyPathErrors.push({
|
|
20587
|
+
message: `Step "${step.id}" ${sourceType} references "steps.${ref.stepId}.${ref.propertyPath.join(".")}" but this property path does not exist in step "${ref.stepId}"'s outputSchema.`,
|
|
20588
|
+
path: fieldPath
|
|
20589
|
+
});
|
|
20590
|
+
}
|
|
20591
|
+
};
|
|
20592
|
+
if (typeof step.if === "string") {
|
|
20593
|
+
for (const variable of extractTemplateVariables(step.if)) {
|
|
20594
|
+
const error61 = validateTemplateVariable({
|
|
20595
|
+
variable,
|
|
20596
|
+
context,
|
|
20597
|
+
stepId: step.id,
|
|
20598
|
+
currentStepGuard,
|
|
20599
|
+
sourceType: "condition"
|
|
20600
|
+
});
|
|
20601
|
+
if (error61) {
|
|
20602
|
+
ctx.addIssue({
|
|
20603
|
+
code: external_exports.ZodIssueCode.custom,
|
|
20604
|
+
message: error61,
|
|
20605
|
+
path: ["steps", stepIndex, "if"]
|
|
20606
|
+
});
|
|
20607
|
+
}
|
|
20608
|
+
}
|
|
20609
|
+
const literalError = validateIfConditionLiteral({
|
|
20610
|
+
condition: step.if,
|
|
20611
|
+
context,
|
|
20612
|
+
stepId: step.id
|
|
20613
|
+
});
|
|
20614
|
+
if (literalError) {
|
|
20615
|
+
ctx.addIssue({
|
|
20616
|
+
code: external_exports.ZodIssueCode.custom,
|
|
20617
|
+
message: literalError,
|
|
20618
|
+
path: ["steps", stepIndex, "if"]
|
|
20619
|
+
});
|
|
20620
|
+
}
|
|
20890
20621
|
}
|
|
20891
|
-
|
|
20892
|
-
|
|
20893
|
-
|
|
20622
|
+
if ("prompt" in step && typeof step.prompt === "string") {
|
|
20623
|
+
const variables = extractTemplateVariables(step.prompt);
|
|
20624
|
+
for (const variable of variables) {
|
|
20625
|
+
const error61 = validateTemplateVariable({
|
|
20626
|
+
variable,
|
|
20627
|
+
context,
|
|
20628
|
+
stepId: step.id,
|
|
20629
|
+
currentStepGuard
|
|
20630
|
+
});
|
|
20631
|
+
if (!error61)
|
|
20632
|
+
continue;
|
|
20633
|
+
const parts = variable.split(".");
|
|
20634
|
+
if (parts[0] === "steps" && parts[1] && !context.steps.has(parts[1]) && error61.includes("before it is available")) {
|
|
20635
|
+
unavailableStepRefs.add(parts[1]);
|
|
20636
|
+
} else {
|
|
20637
|
+
ctx.addIssue({
|
|
20638
|
+
code: external_exports.ZodIssueCode.custom,
|
|
20639
|
+
message: error61,
|
|
20640
|
+
path: ["steps", stepIndex, "prompt"]
|
|
20641
|
+
});
|
|
20642
|
+
}
|
|
20643
|
+
}
|
|
20644
|
+
const backtickRefs = extractStepReferences(step.prompt, backtickStepReferenceRegex);
|
|
20645
|
+
for (const ref of backtickRefs) {
|
|
20646
|
+
processStepRef(ref, "prompt", ["steps", stepIndex, "prompt"]);
|
|
20647
|
+
}
|
|
20894
20648
|
}
|
|
20649
|
+
if (step.type === "ask") {
|
|
20650
|
+
const askTextFields = [
|
|
20651
|
+
{ fieldName: "message", value: "message" in step ? step.message : void 0 },
|
|
20652
|
+
{ fieldName: "details", value: "details" in step ? step.details : void 0 }
|
|
20653
|
+
];
|
|
20654
|
+
for (const { fieldName, value } of askTextFields) {
|
|
20655
|
+
if (typeof value !== "string")
|
|
20656
|
+
continue;
|
|
20657
|
+
for (const variable of extractTemplateVariables(value)) {
|
|
20658
|
+
const error61 = validateTemplateVariable({
|
|
20659
|
+
variable,
|
|
20660
|
+
context,
|
|
20661
|
+
stepId: step.id,
|
|
20662
|
+
currentStepGuard,
|
|
20663
|
+
sourceType: fieldName
|
|
20664
|
+
});
|
|
20665
|
+
if (!error61)
|
|
20666
|
+
continue;
|
|
20667
|
+
ctx.addIssue({
|
|
20668
|
+
code: external_exports.ZodIssueCode.custom,
|
|
20669
|
+
message: error61,
|
|
20670
|
+
path: ["steps", stepIndex, fieldName]
|
|
20671
|
+
});
|
|
20672
|
+
}
|
|
20673
|
+
}
|
|
20674
|
+
}
|
|
20675
|
+
if (step.type === "code" && "code" in step && typeof step.code === "string") {
|
|
20676
|
+
const codeRefs = extractStepReferences(step.code, codeStepReferenceRegex);
|
|
20677
|
+
for (const ref of codeRefs) {
|
|
20678
|
+
processStepRef(ref, "code", ["steps", stepIndex, "code"]);
|
|
20679
|
+
}
|
|
20680
|
+
}
|
|
20681
|
+
for (const referencedStepId of unavailableStepRefs) {
|
|
20682
|
+
const sourceType = step.type === "code" ? "code" : "prompt";
|
|
20683
|
+
const fieldName = step.type === "code" ? "code" : "prompt";
|
|
20684
|
+
ctx.addIssue({
|
|
20685
|
+
code: external_exports.ZodIssueCode.custom,
|
|
20686
|
+
message: `Step "${step.id}" ${sourceType} references step "${referencedStepId}" before it is available. Steps can only reference outputs from earlier steps.`,
|
|
20687
|
+
path: ["steps", stepIndex, fieldName]
|
|
20688
|
+
});
|
|
20689
|
+
}
|
|
20690
|
+
for (const err of propertyPathErrors) {
|
|
20691
|
+
ctx.addIssue({
|
|
20692
|
+
code: external_exports.ZodIssueCode.custom,
|
|
20693
|
+
message: err.message,
|
|
20694
|
+
path: err.path
|
|
20695
|
+
});
|
|
20696
|
+
}
|
|
20697
|
+
if (step.type === "llm" || step.type === "codegen" || step.type === "code" || step.type === "ask") {
|
|
20698
|
+
context.steps.set(step.id, step.outputSchema);
|
|
20699
|
+
} else if (step.type === "search") {
|
|
20700
|
+
context.steps.set(step.id, { type: "string" });
|
|
20701
|
+
}
|
|
20702
|
+
context.guards.set(step.id, currentStepGuard);
|
|
20895
20703
|
}
|
|
20896
|
-
return projectIds.size;
|
|
20897
|
-
}
|
|
20898
|
-
function formatEntity(entity, count) {
|
|
20899
|
-
return count === 1 ? entity : pluralize(entity);
|
|
20900
|
-
}
|
|
20901
|
-
function singularize(value) {
|
|
20902
|
-
if (value === "people") {
|
|
20903
|
-
return "person";
|
|
20904
|
-
}
|
|
20905
|
-
if (value.endsWith("ies")) {
|
|
20906
|
-
return `${value.slice(0, -3)}y`;
|
|
20907
|
-
}
|
|
20908
|
-
if (value.endsWith("ses") || value.endsWith("xes") || value.endsWith("ches") || value.endsWith("shes")) {
|
|
20909
|
-
return value.slice(0, -2);
|
|
20910
|
-
}
|
|
20911
|
-
return value.endsWith("s") ? value.slice(0, -1) : value;
|
|
20912
|
-
}
|
|
20913
|
-
function pluralize(value) {
|
|
20914
|
-
if (value === "person") {
|
|
20915
|
-
return "people";
|
|
20916
|
-
}
|
|
20917
|
-
if (value.endsWith("y")) {
|
|
20918
|
-
return `${value.slice(0, -1)}ies`;
|
|
20919
|
-
}
|
|
20920
|
-
return value.endsWith("s") ? `${value}es` : `${value}s`;
|
|
20921
|
-
}
|
|
20922
|
-
function isRecord(value) {
|
|
20923
|
-
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
20924
20704
|
}
|
|
20925
20705
|
|
|
20706
|
+
// ../../packages/core/dist/esm/schemas/admin-sample-automation.schema.js
|
|
20707
|
+
var sampleAutomationIdSchema = external_exports.string().trim().min(1, "Sample automation ID is required").max(100, "Sample automation ID must be 100 characters or fewer").regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, "Sample automation ID must use lowercase letters, numbers, and hyphens only");
|
|
20708
|
+
var sampleAutomationInstructionsSchema = external_exports.string().nullable();
|
|
20709
|
+
var adminSampleAutomationSchema = external_exports.object({
|
|
20710
|
+
id: sampleAutomationIdSchema,
|
|
20711
|
+
manifest: manifestSchema,
|
|
20712
|
+
instructions: sampleAutomationInstructionsSchema.default(null),
|
|
20713
|
+
connectorNames: external_exports.array(external_exports.string()),
|
|
20714
|
+
connectorDetails: external_exports.array(connectorDetailsSchema),
|
|
20715
|
+
isPublished: external_exports.boolean(),
|
|
20716
|
+
isOneClickInstallEnabled: external_exports.boolean().default(false),
|
|
20717
|
+
staffPick: external_exports.boolean().default(false),
|
|
20718
|
+
createdAt: external_exports.string().datetime(),
|
|
20719
|
+
updatedAt: external_exports.string().datetime()
|
|
20720
|
+
});
|
|
20721
|
+
var adminSampleAutomationsSchema = external_exports.array(adminSampleAutomationSchema);
|
|
20722
|
+
var createAdminSampleAutomationSchema = external_exports.object({
|
|
20723
|
+
id: sampleAutomationIdSchema,
|
|
20724
|
+
manifest: manifestSchema,
|
|
20725
|
+
instructions: sampleAutomationInstructionsSchema.default(null),
|
|
20726
|
+
isPublished: external_exports.boolean().default(false),
|
|
20727
|
+
isOneClickInstallEnabled: external_exports.boolean().default(false),
|
|
20728
|
+
staffPick: external_exports.boolean().default(false)
|
|
20729
|
+
});
|
|
20730
|
+
var updateAdminSampleAutomationSchema = external_exports.object({
|
|
20731
|
+
manifest: manifestSchema,
|
|
20732
|
+
instructions: sampleAutomationInstructionsSchema.optional(),
|
|
20733
|
+
isPublished: external_exports.boolean(),
|
|
20734
|
+
isOneClickInstallEnabled: external_exports.boolean().optional(),
|
|
20735
|
+
staffPick: external_exports.boolean().optional()
|
|
20736
|
+
});
|
|
20737
|
+
var toggleAdminSampleAutomationPublicationSchema = external_exports.object({
|
|
20738
|
+
isPublished: external_exports.boolean()
|
|
20739
|
+
});
|
|
20740
|
+
var deleteAdminSampleAutomationSchema = external_exports.object({
|
|
20741
|
+
title: external_exports.string().min(1, "Sample automation title confirmation is required")
|
|
20742
|
+
});
|
|
20743
|
+
|
|
20744
|
+
// ../../packages/core/dist/esm/types/automation.types.js
|
|
20745
|
+
var AUTOMATION_CONNECTION_STATUSES = ["ready", "almost-ready", "not-ready"];
|
|
20746
|
+
var AUTOMATION_VISIBILITIES = ["private", "workspace"];
|
|
20747
|
+
var AUTOMATION_DISABLED_REASONS = [
|
|
20748
|
+
"creator-left-workspace",
|
|
20749
|
+
"workspace-plan-lapsed"
|
|
20750
|
+
];
|
|
20751
|
+
|
|
20752
|
+
// ../../packages/core/dist/esm/schemas/connection.schema.js
|
|
20753
|
+
var CreateConnectionParamsSchema = external_exports.object({
|
|
20754
|
+
connectorId: external_exports.string(),
|
|
20755
|
+
capability: external_exports.enum(CONNECTION_TYPES),
|
|
20756
|
+
name: external_exports.string().optional()
|
|
20757
|
+
});
|
|
20758
|
+
var CreateConnectionBodySchema = external_exports.object({
|
|
20759
|
+
automationIds: external_exports.array(external_exports.uuid()).optional()
|
|
20760
|
+
});
|
|
20761
|
+
var OAuthConnectionSetupSchema = external_exports.object({
|
|
20762
|
+
kind: external_exports.literal("oauth"),
|
|
20763
|
+
authorizationUrl: external_exports.string().url()
|
|
20764
|
+
});
|
|
20765
|
+
var ManagedConnectionSetupSchema = external_exports.object({
|
|
20766
|
+
kind: external_exports.literal("managed"),
|
|
20767
|
+
code: external_exports.string().regex(MANAGED_CONNECTION_SETUP_CODE_EXACT_REGEX),
|
|
20768
|
+
instructions: external_exports.string(),
|
|
20769
|
+
deepLinkUrl: external_exports.string().url().nullable(),
|
|
20770
|
+
expiresAt: external_exports.iso.datetime()
|
|
20771
|
+
});
|
|
20772
|
+
var ConnectionSetupSchema = external_exports.discriminatedUnion("kind", [
|
|
20773
|
+
OAuthConnectionSetupSchema,
|
|
20774
|
+
ManagedConnectionSetupSchema
|
|
20775
|
+
]);
|
|
20776
|
+
var CreateConnectionResponseSchema = external_exports.object({
|
|
20777
|
+
connectionId: external_exports.uuid(),
|
|
20778
|
+
setup: ConnectionSetupSchema.nullable()
|
|
20779
|
+
});
|
|
20780
|
+
var ConnectionCapabilitySchema = external_exports.object({
|
|
20781
|
+
capability: external_exports.enum(CONNECTION_TYPES),
|
|
20782
|
+
scopes: external_exports.array(external_exports.string()),
|
|
20783
|
+
authorizedAt: external_exports.iso.datetime()
|
|
20784
|
+
});
|
|
20785
|
+
var ConnectionSchema = external_exports.object({
|
|
20786
|
+
id: external_exports.uuid(),
|
|
20787
|
+
name: external_exports.string(),
|
|
20788
|
+
connectorId: external_exports.string(),
|
|
20789
|
+
connectorIconUrl: external_exports.url().nullable().optional(),
|
|
20790
|
+
capabilities: external_exports.array(ConnectionCapabilitySchema),
|
|
20791
|
+
accountDisplayLabel: external_exports.string().optional(),
|
|
20792
|
+
status: external_exports.enum(CONNECTION_STATUSES).optional(),
|
|
20793
|
+
createdAt: external_exports.string().optional(),
|
|
20794
|
+
metadata: external_exports.record(external_exports.string(), external_exports.unknown()),
|
|
20795
|
+
setup: ConnectionSetupSchema.nullable()
|
|
20796
|
+
});
|
|
20797
|
+
var ConnectionDetailsSchema = external_exports.object({
|
|
20798
|
+
id: external_exports.uuid(),
|
|
20799
|
+
name: external_exports.string(),
|
|
20800
|
+
connectorId: external_exports.string(),
|
|
20801
|
+
connectorIconUrl: external_exports.url().nullable().optional(),
|
|
20802
|
+
capabilities: external_exports.array(ConnectionCapabilitySchema),
|
|
20803
|
+
accountDisplayLabel: external_exports.string(),
|
|
20804
|
+
status: external_exports.enum(CONNECTION_STATUSES),
|
|
20805
|
+
createdAt: external_exports.string(),
|
|
20806
|
+
metadata: external_exports.record(external_exports.string(), external_exports.unknown()),
|
|
20807
|
+
setup: ConnectionSetupSchema.nullable()
|
|
20808
|
+
});
|
|
20809
|
+
var GetConnectionsQuerySchema = external_exports.object({
|
|
20810
|
+
/**
|
|
20811
|
+
* Capability filter. `type` is accepted as a deprecated alias during the
|
|
20812
|
+
* rolling-deploy window where older FE/SDK builds may still send the old
|
|
20813
|
+
* query param. Remove once all clients are on the post-PR1 SDK.
|
|
20814
|
+
*/
|
|
20815
|
+
capability: external_exports.enum(CONNECTION_TYPES).optional(),
|
|
20816
|
+
type: external_exports.enum(CONNECTION_TYPES).optional(),
|
|
20817
|
+
connectorId: external_exports.string().optional(),
|
|
20818
|
+
status: external_exports.enum(CONNECTION_STATUSES).optional()
|
|
20819
|
+
});
|
|
20820
|
+
var GetConnectionsResponseSchema = external_exports.object({
|
|
20821
|
+
connections: external_exports.array(ConnectionSchema)
|
|
20822
|
+
});
|
|
20823
|
+
var DependentAutomationSchema = external_exports.object({
|
|
20824
|
+
id: external_exports.string(),
|
|
20825
|
+
name: external_exports.string(),
|
|
20826
|
+
description: external_exports.string(),
|
|
20827
|
+
enabled: external_exports.boolean(),
|
|
20828
|
+
connectorStatus: external_exports.enum(["ready", "attention", "missing"]),
|
|
20829
|
+
requiredConnectionTypes: external_exports.array(external_exports.enum(CONNECTION_TYPES))
|
|
20830
|
+
});
|
|
20831
|
+
var GetConnectionDependentAutomationsResponseSchema = external_exports.object({
|
|
20832
|
+
automations: external_exports.array(DependentAutomationSchema)
|
|
20833
|
+
});
|
|
20834
|
+
var CONNECTION_IN_USE_CONFLICT_CODE = "connection_in_use_conflict";
|
|
20835
|
+
var BlockingAutomationSchema = external_exports.object({
|
|
20836
|
+
id: external_exports.string(),
|
|
20837
|
+
name: external_exports.string()
|
|
20838
|
+
});
|
|
20839
|
+
var ConnectionInUseConflictSchema = external_exports.object({
|
|
20840
|
+
code: external_exports.literal(CONNECTION_IN_USE_CONFLICT_CODE),
|
|
20841
|
+
message: external_exports.string(),
|
|
20842
|
+
automations: external_exports.array(BlockingAutomationSchema)
|
|
20843
|
+
});
|
|
20844
|
+
|
|
20845
|
+
// ../../packages/core/dist/esm/schemas/automation.schema.js
|
|
20846
|
+
var runStatusSchema = external_exports.discriminatedUnion("status", [
|
|
20847
|
+
external_exports.object({
|
|
20848
|
+
status: external_exports.literal("pending"),
|
|
20849
|
+
lastRun: external_exports.iso.datetime().optional()
|
|
20850
|
+
}),
|
|
20851
|
+
external_exports.object({
|
|
20852
|
+
status: external_exports.literal("running"),
|
|
20853
|
+
lastRun: external_exports.iso.datetime()
|
|
20854
|
+
}),
|
|
20855
|
+
external_exports.object({
|
|
20856
|
+
status: external_exports.literal("completed"),
|
|
20857
|
+
lastRun: external_exports.iso.datetime()
|
|
20858
|
+
}),
|
|
20859
|
+
external_exports.object({
|
|
20860
|
+
status: external_exports.literal("failed"),
|
|
20861
|
+
lastRun: external_exports.iso.datetime(),
|
|
20862
|
+
failureReason: external_exports.string().optional()
|
|
20863
|
+
}),
|
|
20864
|
+
external_exports.object({
|
|
20865
|
+
status: external_exports.literal("cancelled"),
|
|
20866
|
+
lastRun: external_exports.iso.datetime()
|
|
20867
|
+
})
|
|
20868
|
+
]);
|
|
20869
|
+
var automationSchema = external_exports.object({
|
|
20870
|
+
id: external_exports.string(),
|
|
20871
|
+
connections: external_exports.array(ConnectionDetailsSchema),
|
|
20872
|
+
enabled: external_exports.boolean(),
|
|
20873
|
+
status: runStatusSchema,
|
|
20874
|
+
connectionStatus: external_exports.enum(AUTOMATION_CONNECTION_STATUSES),
|
|
20875
|
+
draftId: external_exports.string().nullable(),
|
|
20876
|
+
manifest: external_exports.union([manifestSchema, external_exports.record(external_exports.string(), external_exports.unknown())]).nullable(),
|
|
20877
|
+
updatedAt: external_exports.iso.datetime(),
|
|
20878
|
+
// null means the automation belongs to the creator's personal space
|
|
20879
|
+
workspaceId: external_exports.string().nullable(),
|
|
20880
|
+
visibility: external_exports.enum(AUTOMATION_VISIBILITIES),
|
|
20881
|
+
isOwner: external_exports.boolean(),
|
|
20882
|
+
disabledReason: external_exports.enum(AUTOMATION_DISABLED_REASONS).nullable()
|
|
20883
|
+
});
|
|
20884
|
+
var automationListResponseSchema = external_exports.object({
|
|
20885
|
+
data: external_exports.array(automationSchema),
|
|
20886
|
+
nextCursor: external_exports.string().nullable()
|
|
20887
|
+
});
|
|
20888
|
+
var updateAutomationSchema = external_exports.object({
|
|
20889
|
+
enabled: external_exports.boolean().optional(),
|
|
20890
|
+
manifest: manifestSchema.optional()
|
|
20891
|
+
}).refine((data) => Object.keys(data).length > 0, {
|
|
20892
|
+
message: "At least one field must be provided"
|
|
20893
|
+
});
|
|
20894
|
+
var updateAutomationMetadataSchema = external_exports.object({
|
|
20895
|
+
name: external_exports.string().min(1),
|
|
20896
|
+
description: external_exports.string()
|
|
20897
|
+
});
|
|
20898
|
+
var updateAutomationScheduleSchema = external_exports.object({
|
|
20899
|
+
value: scheduleValueSchema
|
|
20900
|
+
});
|
|
20901
|
+
|
|
20902
|
+
// ../../packages/core/dist/esm/schemas/automation-connection.schema.js
|
|
20903
|
+
var AutomationConnectionMappingSchema = external_exports.object({
|
|
20904
|
+
connectorId: external_exports.string().trim().min(1, "connectorId is required"),
|
|
20905
|
+
connectionId: external_exports.string().trim().min(1, "connectionId is required")
|
|
20906
|
+
}).strict();
|
|
20907
|
+
var UpsertAutomationConnectionSchema = external_exports.object({
|
|
20908
|
+
connectionId: uuidv7Schema.min(1, "connectionId is required"),
|
|
20909
|
+
/**
|
|
20910
|
+
* Manifest slot to bind this connection to. Required when the
|
|
20911
|
+
* connection carries more than one capability (managed connectors
|
|
20912
|
+
* can cover both `mcp` and `trigger` after a single
|
|
20913
|
+
* onboarding). Optional for single-capability connections, where
|
|
20914
|
+
* the service infers the role from `connection.capabilities[0]`.
|
|
20915
|
+
*/
|
|
20916
|
+
connectionType: external_exports.enum(CONNECTION_TYPES).optional()
|
|
20917
|
+
}).strict();
|
|
20918
|
+
var SetAutomationConnectionsSchema = external_exports.object({
|
|
20919
|
+
mappings: external_exports.array(AutomationConnectionMappingSchema).nonempty("mappings cannot be empty")
|
|
20920
|
+
}).strict();
|
|
20921
|
+
var RequiredConnectorSchema = external_exports.object({
|
|
20922
|
+
connectorName: external_exports.string(),
|
|
20923
|
+
connectorId: external_exports.string(),
|
|
20924
|
+
connectorDisplayName: external_exports.string(),
|
|
20925
|
+
description: external_exports.string(),
|
|
20926
|
+
connectorIconUrl: external_exports.string().nullable(),
|
|
20927
|
+
requiredTypes: external_exports.array(external_exports.enum(CONNECTION_TYPES)),
|
|
20928
|
+
/** Whether uses of this connector require a Connection binding. */
|
|
20929
|
+
requiresConnection: external_exports.boolean(),
|
|
20930
|
+
/**
|
|
20931
|
+
* Product-owned built-in status. Connection validation uses
|
|
20932
|
+
* `requiresConnection` independently from this UI classification.
|
|
20933
|
+
*/
|
|
20934
|
+
isSystem: external_exports.boolean().optional()
|
|
20935
|
+
});
|
|
20936
|
+
var AutomationConnectionSchema = external_exports.object({
|
|
20937
|
+
connectorId: external_exports.string(),
|
|
20938
|
+
connectionId: external_exports.uuid(),
|
|
20939
|
+
connectorName: external_exports.string(),
|
|
20940
|
+
connectorIconUrl: external_exports.url().nullable().optional(),
|
|
20941
|
+
status: external_exports.enum(CONNECTION_STATUSES),
|
|
20942
|
+
type: external_exports.enum(CONNECTION_TYPES)
|
|
20943
|
+
});
|
|
20944
|
+
var ConnectorTypeStatusSchema = external_exports.object({
|
|
20945
|
+
required: external_exports.boolean(),
|
|
20946
|
+
status: external_exports.enum(CONNECTOR_TYPE_STATUSES),
|
|
20947
|
+
connection: ConnectionSchema.pick({
|
|
20948
|
+
id: true,
|
|
20949
|
+
accountDisplayLabel: true,
|
|
20950
|
+
status: true,
|
|
20951
|
+
createdAt: true
|
|
20952
|
+
}).optional(),
|
|
20953
|
+
setup: ConnectionSetupSchema.nullable()
|
|
20954
|
+
});
|
|
20955
|
+
var AutomationConnectorStatusSchema = external_exports.object({
|
|
20956
|
+
id: external_exports.string(),
|
|
20957
|
+
name: external_exports.string(),
|
|
20958
|
+
description: external_exports.string(),
|
|
20959
|
+
iconUrl: external_exports.string().nullable(),
|
|
20960
|
+
mcp: ConnectorTypeStatusSchema,
|
|
20961
|
+
trigger: ConnectorTypeStatusSchema
|
|
20962
|
+
});
|
|
20963
|
+
var AutomationConnectionValidationSchema = external_exports.object({
|
|
20964
|
+
required: external_exports.array(RequiredConnectorSchema),
|
|
20965
|
+
mapped: external_exports.array(AutomationConnectionSchema),
|
|
20966
|
+
missing: external_exports.array(external_exports.object({
|
|
20967
|
+
connectorName: external_exports.string(),
|
|
20968
|
+
connectionType: external_exports.enum(CONNECTION_TYPES),
|
|
20969
|
+
reason: external_exports.enum(CONNECTION_ISSUE_REASONS)
|
|
20970
|
+
})),
|
|
20971
|
+
connectors: external_exports.array(AutomationConnectorStatusSchema),
|
|
20972
|
+
isReady: external_exports.boolean()
|
|
20973
|
+
});
|
|
20974
|
+
var GetRequiredConnectorsResponseSchema = external_exports.object({
|
|
20975
|
+
required: external_exports.array(RequiredConnectorSchema)
|
|
20976
|
+
});
|
|
20977
|
+
var GetAutomationConnectionsResponseSchema = external_exports.object({
|
|
20978
|
+
data: external_exports.array(AutomationConnectionSchema)
|
|
20979
|
+
});
|
|
20980
|
+
var UpsertAutomationConnectionResponseSchema = external_exports.object({
|
|
20981
|
+
data: AutomationConnectionSchema
|
|
20982
|
+
});
|
|
20983
|
+
var ManifestConnectionCheckResultSchema = AutomationConnectionValidationSchema.pick({
|
|
20984
|
+
required: true,
|
|
20985
|
+
connectors: true
|
|
20986
|
+
});
|
|
20987
|
+
|
|
20926
20988
|
// ../../packages/core/dist/esm/schemas/automation-execution.schema.js
|
|
20927
20989
|
var AutomationRunDebugEventSchema = external_exports.union([
|
|
20928
20990
|
external_exports.object({
|
|
@@ -21487,10 +21549,6 @@ var FILTER_OPERATORS = ["and", "or"];
|
|
|
21487
21549
|
var MAX_COHORT_RESULTS = 366;
|
|
21488
21550
|
var MAX_COHORT_ROWS = 120;
|
|
21489
21551
|
|
|
21490
|
-
// ../../packages/core/dist/esm/schemas/query-param.schema.js
|
|
21491
|
-
var booleanQueryParamSchema = external_exports.preprocess((value) => value === "true" ? true : value === "false" ? false : value, external_exports.boolean());
|
|
21492
|
-
var booleanQueryFlagSchema = booleanQueryParamSchema.optional().transform((value) => value === true);
|
|
21493
|
-
|
|
21494
21552
|
// ../../packages/core/dist/esm/schemas/cohorts.schema.js
|
|
21495
21553
|
var FRONTEND_COHORT_EVENTS = [
|
|
21496
21554
|
"session:started",
|
|
@@ -22465,16 +22523,28 @@ var AutomationsNetworkError = class extends Error {
|
|
|
22465
22523
|
var AutomationsRequestError = class extends Error {
|
|
22466
22524
|
httpStatusCode;
|
|
22467
22525
|
responseData;
|
|
22468
|
-
|
|
22526
|
+
/**
|
|
22527
|
+
* The scope the route required, taken from the `scope` parameter of a
|
|
22528
|
+
* `WWW-Authenticate` challenge. Undefined when the response carried no
|
|
22529
|
+
* challenge, or one without that parameter — and in a browser unless the
|
|
22530
|
+
* header is listed in `Access-Control-Expose-Headers`, which is why callers
|
|
22531
|
+
* must still work without it.
|
|
22532
|
+
*/
|
|
22533
|
+
requiredScope;
|
|
22534
|
+
constructor(message, httpStatusCode, responseData, requiredScope2) {
|
|
22469
22535
|
super(message);
|
|
22470
22536
|
this.name = "AutomationsRequestError";
|
|
22471
22537
|
this.httpStatusCode = httpStatusCode;
|
|
22472
22538
|
this.responseData = responseData;
|
|
22539
|
+
this.requiredScope = requiredScope2;
|
|
22473
22540
|
}
|
|
22474
22541
|
isAuthError() {
|
|
22475
22542
|
return this.httpStatusCode === 401 || this.httpStatusCode === 403;
|
|
22476
22543
|
}
|
|
22477
22544
|
};
|
|
22545
|
+
function parseChallengeScope(header) {
|
|
22546
|
+
return header?.match(/scope="([^"]+)"/)?.[1];
|
|
22547
|
+
}
|
|
22478
22548
|
|
|
22479
22549
|
// ../../packages/sdk/dist/esm/transport/http-client.js
|
|
22480
22550
|
function buildUrl(baseUrl, path, query) {
|
|
@@ -22534,7 +22604,7 @@ async function request(args) {
|
|
|
22534
22604
|
const data = await readResponseBody(response);
|
|
22535
22605
|
if (!response.ok) {
|
|
22536
22606
|
const message = typeof data === "object" && data !== null && "message" in data ? String(data.message) : response.statusText || `Request failed with status ${response.status}`;
|
|
22537
|
-
throw new AutomationsRequestError(message, response.status, data);
|
|
22607
|
+
throw new AutomationsRequestError(message, response.status, data, parseChallengeScope(response.headers.get("WWW-Authenticate")));
|
|
22538
22608
|
}
|
|
22539
22609
|
return data;
|
|
22540
22610
|
}
|
|
@@ -23779,6 +23849,22 @@ function initialEnvironmentName() {
|
|
|
23779
23849
|
|
|
23780
23850
|
// src/lib/auth-records.ts
|
|
23781
23851
|
var CONFIG_VERSION = 1;
|
|
23852
|
+
async function getDefaultWorkspaceId() {
|
|
23853
|
+
return getEnvironmentDefault("default_workspace", getEnvironment().name);
|
|
23854
|
+
}
|
|
23855
|
+
async function setDefaultWorkspaceId(workspaceId) {
|
|
23856
|
+
await setEnvironmentDefault("default_workspace", getEnvironment().name, workspaceId);
|
|
23857
|
+
}
|
|
23858
|
+
async function getEnvironmentDefault(key, environment) {
|
|
23859
|
+
return (await read())[key]?.[environment] ?? null;
|
|
23860
|
+
}
|
|
23861
|
+
async function setEnvironmentDefault(key, environment, id) {
|
|
23862
|
+
const config2 = await read();
|
|
23863
|
+
const defaults = { ...config2[key] };
|
|
23864
|
+
if (id === null) delete defaults[environment];
|
|
23865
|
+
else defaults[environment] = id;
|
|
23866
|
+
await write({ ...config2, [key]: defaults });
|
|
23867
|
+
}
|
|
23782
23868
|
function configPath() {
|
|
23783
23869
|
return getConfigPath(SERVICE_NAME);
|
|
23784
23870
|
}
|
|
@@ -23856,14 +23942,10 @@ function createAutomationsRecordStore() {
|
|
|
23856
23942
|
await write({ ...config2, accounts: next, default_account: defaults });
|
|
23857
23943
|
},
|
|
23858
23944
|
async getDefaultId() {
|
|
23859
|
-
return (
|
|
23945
|
+
return getEnvironmentDefault("default_account", environment());
|
|
23860
23946
|
},
|
|
23861
23947
|
async setDefaultId(id) {
|
|
23862
|
-
|
|
23863
|
-
const defaults = { ...config2.default_account };
|
|
23864
|
-
if (id === null) delete defaults[environment()];
|
|
23865
|
-
else defaults[environment()] = id;
|
|
23866
|
-
await write({ ...config2, default_account: defaults });
|
|
23948
|
+
await setEnvironmentDefault("default_account", environment(), id);
|
|
23867
23949
|
}
|
|
23868
23950
|
};
|
|
23869
23951
|
}
|
|
@@ -23912,28 +23994,32 @@ import { attachLoginCommand } from "@doist/cli-core/auth";
|
|
|
23912
23994
|
import { CliError, getConfigPath as getConfigPath3, getErrorMessage as getErrorMessage3 } from "@doist/cli-core";
|
|
23913
23995
|
import { refreshAccessToken } from "@doist/cli-core/auth";
|
|
23914
23996
|
|
|
23915
|
-
// src/lib/auth-provider.ts
|
|
23916
|
-
import { getErrorMessage } from "@doist/cli-core";
|
|
23917
|
-
import { createPkceProvider } from "@doist/cli-core/auth";
|
|
23918
|
-
|
|
23919
23997
|
// src/lib/auth-scopes.ts
|
|
23920
23998
|
import { InvalidArgumentError as InvalidArgumentError3 } from "commander";
|
|
23921
|
-
var
|
|
23999
|
+
var IDENTITY_SCOPES = ["user:read", "workspaces:read"];
|
|
23922
24000
|
var WRITE_SCOPES = [
|
|
23923
24001
|
"automations:automations:write",
|
|
23924
24002
|
"automations:automations:execute",
|
|
23925
24003
|
"automations:connections:write",
|
|
23926
|
-
"automations:chat:write"
|
|
24004
|
+
"automations:chat:write",
|
|
24005
|
+
"automations:workspaces:write",
|
|
24006
|
+
"automations:workspaces:execute"
|
|
23927
24007
|
];
|
|
23928
24008
|
var READ_ONLY_SCOPES = WRITE_SCOPES.flatMap(
|
|
23929
24009
|
(code) => scopeDefinition(code).impliedScopes ?? []
|
|
23930
24010
|
);
|
|
23931
24011
|
var ADDITIONAL_WRITE_SCOPES = {
|
|
23932
|
-
workspaces: ["automations:workspaces:write", "automations:workspaces:execute"],
|
|
23933
24012
|
notifications: ["automations:notifications:write"],
|
|
23934
24013
|
settings: ["automations:settings:write"],
|
|
23935
24014
|
webhooks: ["automations:webhooks:write"]
|
|
23936
24015
|
};
|
|
24016
|
+
function additionalScopeFlagFor(scope) {
|
|
24017
|
+
return ADDITIONAL_SCOPE_FLAGS.find(
|
|
24018
|
+
(flag) => ADDITIONAL_WRITE_SCOPES[flag].some(
|
|
24019
|
+
(code) => code === scope || (scopeDefinition(code).impliedScopes ?? []).includes(scope)
|
|
24020
|
+
)
|
|
24021
|
+
);
|
|
24022
|
+
}
|
|
23937
24023
|
var ADDITIONAL_SCOPE_FLAGS = Object.keys(
|
|
23938
24024
|
ADDITIONAL_WRITE_SCOPES
|
|
23939
24025
|
);
|
|
@@ -23952,7 +24038,7 @@ function resolveScopes(context) {
|
|
|
23952
24038
|
const additional = extractAdditionalScopes(context.flags).flatMap(
|
|
23953
24039
|
(flag) => scopesFor(flag, context.readOnly)
|
|
23954
24040
|
);
|
|
23955
|
-
return [
|
|
24041
|
+
return [...IDENTITY_SCOPES, ...base, ...additional];
|
|
23956
24042
|
}
|
|
23957
24043
|
function parseAdditionalScopes(raw) {
|
|
23958
24044
|
const requested = raw.split(",").map((part) => part.trim());
|
|
@@ -23992,6 +24078,8 @@ function formatScopesHelp() {
|
|
|
23992
24078
|
}
|
|
23993
24079
|
|
|
23994
24080
|
// src/lib/auth-provider.ts
|
|
24081
|
+
import { getErrorMessage } from "@doist/cli-core";
|
|
24082
|
+
import { createPkceProvider } from "@doist/cli-core/auth";
|
|
23995
24083
|
var ERROR_HINTS = ["Try again: tda auth login"];
|
|
23996
24084
|
function createAutomationsAuthProvider() {
|
|
23997
24085
|
return {
|
|
@@ -24194,14 +24282,29 @@ function explainAuthFailure(error61, source) {
|
|
|
24194
24282
|
return new CredentialError(
|
|
24195
24283
|
"INSUFFICIENT_SCOPE",
|
|
24196
24284
|
"Your login does not grant what this command needs.",
|
|
24197
|
-
|
|
24198
|
-
"Run `tda auth login` to authorize again, without --read-only.",
|
|
24199
|
-
"Pass --additional-scopes if the command needs an opt-in scope."
|
|
24200
|
-
]
|
|
24285
|
+
insufficientScopeFixes(requiredScope(error61))
|
|
24201
24286
|
);
|
|
24202
24287
|
}
|
|
24203
24288
|
return error61;
|
|
24204
24289
|
}
|
|
24290
|
+
function insufficientScopeFixes(scope) {
|
|
24291
|
+
if (!scope) {
|
|
24292
|
+
return [
|
|
24293
|
+
"Run `tda auth login` to authorize again, without --read-only.",
|
|
24294
|
+
"Pass --additional-scopes if the command needs an opt-in scope."
|
|
24295
|
+
];
|
|
24296
|
+
}
|
|
24297
|
+
const flag = additionalScopeFlagFor(scope);
|
|
24298
|
+
return [
|
|
24299
|
+
`This needs the \`${scope}\` scope, which your login does not have.`,
|
|
24300
|
+
flag ? `Run \`tda auth login --additional-scopes ${flag}\` to grant it.` : "Run `tda auth login` to authorize again, without --read-only."
|
|
24301
|
+
];
|
|
24302
|
+
}
|
|
24303
|
+
function requiredScope(error61) {
|
|
24304
|
+
if (typeof error61 !== "object" || error61 === null || !("requiredScope" in error61)) return void 0;
|
|
24305
|
+
const scope = error61.requiredScope;
|
|
24306
|
+
return typeof scope === "string" ? scope : void 0;
|
|
24307
|
+
}
|
|
24205
24308
|
function httpStatus(error61) {
|
|
24206
24309
|
if (typeof error61 !== "object" || error61 === null || !("httpStatusCode" in error61))
|
|
24207
24310
|
return void 0;
|
|
@@ -25090,6 +25193,26 @@ async function runApiCommand(command, operation, presentation, execution = {}) {
|
|
|
25090
25193
|
}
|
|
25091
25194
|
}
|
|
25092
25195
|
|
|
25196
|
+
// src/lib/workspace-scope.ts
|
|
25197
|
+
async function resolveWorkspaceScope(options) {
|
|
25198
|
+
if (options.workspace !== void 0 && options.personal) {
|
|
25199
|
+
throw new Error("Use either --workspace or --personal, not both.");
|
|
25200
|
+
}
|
|
25201
|
+
if (options.workspace !== void 0) {
|
|
25202
|
+
return options.workspace;
|
|
25203
|
+
}
|
|
25204
|
+
if (options.personal) {
|
|
25205
|
+
return null;
|
|
25206
|
+
}
|
|
25207
|
+
return getDefaultWorkspaceId();
|
|
25208
|
+
}
|
|
25209
|
+
function addWorkspaceScopeOptions(command) {
|
|
25210
|
+
return command.option(
|
|
25211
|
+
"--workspace <workspace-id>",
|
|
25212
|
+
"Act on this workspace instead of your personal space"
|
|
25213
|
+
).option("--personal", "Act on your personal space, ignoring any pinned workspace");
|
|
25214
|
+
}
|
|
25215
|
+
|
|
25093
25216
|
// src/commands/read/format.ts
|
|
25094
25217
|
function formatAutomationList(page) {
|
|
25095
25218
|
if (page.data.length === 0) return "No automations found.";
|
|
@@ -25311,44 +25434,67 @@ function capitalize(value) {
|
|
|
25311
25434
|
// src/commands/automation/index.ts
|
|
25312
25435
|
function registerAutomationCommand(program) {
|
|
25313
25436
|
const automation = program.command("automation").description("Inspect and manage published automations");
|
|
25314
|
-
|
|
25315
|
-
|
|
25316
|
-
|
|
25317
|
-
|
|
25318
|
-
|
|
25319
|
-
|
|
25320
|
-
|
|
25321
|
-
|
|
25322
|
-
|
|
25437
|
+
addWorkspaceScopeOptions(
|
|
25438
|
+
addCursorPaginationOptions(automation.command("list").description("List automations"))
|
|
25439
|
+
).action(async (options, command) => {
|
|
25440
|
+
await runApiCommand(
|
|
25441
|
+
command,
|
|
25442
|
+
async ({ api, signal }) => {
|
|
25443
|
+
const workspaceId = await resolveWorkspaceScope(options);
|
|
25444
|
+
return collectCursorPages(
|
|
25445
|
+
options,
|
|
25446
|
+
(args) => workspaceId === null ? api.automations.list(args, { signal }) : api.workspaceAutomations.list(workspaceId, args, { signal })
|
|
25447
|
+
);
|
|
25448
|
+
},
|
|
25449
|
+
{ human: formatAutomationList, json: summarizeAutomationPage },
|
|
25450
|
+
{
|
|
25451
|
+
spinner: "Loading automations...",
|
|
25452
|
+
streamNdjson: async function* ({ api, signal }) {
|
|
25453
|
+
const workspaceId = await resolveWorkspaceScope(options);
|
|
25454
|
+
yield* streamAutomationList(
|
|
25323
25455
|
options,
|
|
25324
|
-
(args) => api.automations.list(args, { signal })
|
|
25325
|
-
)
|
|
25456
|
+
(args) => workspaceId === null ? api.automations.list(args, { signal }) : api.workspaceAutomations.list(workspaceId, args, { signal })
|
|
25457
|
+
);
|
|
25326
25458
|
}
|
|
25327
|
-
|
|
25328
|
-
|
|
25329
|
-
);
|
|
25330
|
-
|
|
25459
|
+
}
|
|
25460
|
+
);
|
|
25461
|
+
});
|
|
25462
|
+
addWorkspaceScopeOptions(
|
|
25463
|
+
automation.command("view").description("Show an automation and its manifest").argument("<automation-id>", "Automation ID")
|
|
25464
|
+
).action(async (automationId, options, command) => {
|
|
25331
25465
|
await runApiCommand(
|
|
25332
25466
|
command,
|
|
25333
|
-
({ api, signal }) =>
|
|
25467
|
+
async ({ api, signal }) => {
|
|
25468
|
+
const workspaceId = await resolveWorkspaceScope(options);
|
|
25469
|
+
return workspaceId === null ? api.automations.get(automationId, { signal }) : api.workspaceAutomations.get(workspaceId, automationId, { signal });
|
|
25470
|
+
},
|
|
25334
25471
|
{ human: formatAutomation, json: summarizeAutomation },
|
|
25335
25472
|
{ spinner: "Loading automation..." }
|
|
25336
25473
|
);
|
|
25337
25474
|
});
|
|
25338
25475
|
registerEnabledStateCommand(automation, "enable", true);
|
|
25339
25476
|
registerEnabledStateCommand(automation, "disable", false);
|
|
25340
|
-
|
|
25477
|
+
addWorkspaceScopeOptions(
|
|
25478
|
+
automation.command("trigger").description("Start a live automation run without waiting for it to finish").argument("<automation-id>", "Automation ID")
|
|
25479
|
+
).action(async (automationId, options, command) => {
|
|
25341
25480
|
await runApiCommand(
|
|
25342
25481
|
command,
|
|
25343
25482
|
async ({ api, signal }) => {
|
|
25344
|
-
const
|
|
25483
|
+
const workspaceId = await resolveWorkspaceScope(options);
|
|
25484
|
+
const automation2 = workspaceId === null ? await api.automations.get(automationId, { signal }) : await api.workspaceAutomations.get(workspaceId, automationId, {
|
|
25485
|
+
signal
|
|
25486
|
+
});
|
|
25345
25487
|
const triggerType = hasTriggerType(automation2.manifest) ? getManifestTriggers(automation2.manifest)[0]?.type : void 0;
|
|
25346
25488
|
if (triggerType !== "schedule") {
|
|
25347
25489
|
throw new Error(
|
|
25348
25490
|
"This automation can only be triggered via its configured mechanism, not manually."
|
|
25349
25491
|
);
|
|
25350
25492
|
}
|
|
25351
|
-
|
|
25493
|
+
if (workspaceId === null) {
|
|
25494
|
+
await api.automations.trigger(automationId, { signal });
|
|
25495
|
+
} else {
|
|
25496
|
+
await api.workspaceAutomations.trigger(workspaceId, automationId, { signal });
|
|
25497
|
+
}
|
|
25352
25498
|
return { action: "triggered", automationId };
|
|
25353
25499
|
},
|
|
25354
25500
|
{ human: formatAutomationTrigger },
|
|
@@ -27552,6 +27698,83 @@ function registerUpdateCommand(program) {
|
|
|
27552
27698
|
});
|
|
27553
27699
|
}
|
|
27554
27700
|
|
|
27701
|
+
// src/commands/workspace/format.ts
|
|
27702
|
+
function formatWorkspaceList(workspaces) {
|
|
27703
|
+
if (workspaces.length === 0) {
|
|
27704
|
+
return "No workspaces. Automations you create belong to your personal space.";
|
|
27705
|
+
}
|
|
27706
|
+
return workspaces.map((workspace) => {
|
|
27707
|
+
const locked = workspace.access === "locked" ? " (locked: plan does not cover Automations)" : "";
|
|
27708
|
+
return `${workspace.id} ${workspace.name} ${workspace.plan} ${workspace.role}${locked}`;
|
|
27709
|
+
}).join("\n");
|
|
27710
|
+
}
|
|
27711
|
+
function summarizeWorkspaceList(workspaces) {
|
|
27712
|
+
return { workspaces };
|
|
27713
|
+
}
|
|
27714
|
+
function formatCurrentWorkspace(result) {
|
|
27715
|
+
return result.workspaceId === null ? "Personal space. Pin a workspace with `tda workspace use <workspace-id>`." : `Workspace ${result.workspaceId}`;
|
|
27716
|
+
}
|
|
27717
|
+
function formatWorkspaceSelection(result) {
|
|
27718
|
+
return result.action === "cleared" ? "Cleared. Commands now act on your personal space." : `Pinned ${result.name ?? result.workspaceId}. \`automation list\`, \`view\` and \`trigger\` now act on this workspace; everything else stays personal. Use --personal for a one-off.`;
|
|
27719
|
+
}
|
|
27720
|
+
|
|
27721
|
+
// src/commands/workspace/index.ts
|
|
27722
|
+
function registerWorkspaceCommand(program) {
|
|
27723
|
+
const workspace = program.command("workspace").description("List Todoist workspaces and choose which one commands act on");
|
|
27724
|
+
workspace.command("list").description("List the workspaces you can use").action(async (_options, command) => {
|
|
27725
|
+
await runApiCommand(
|
|
27726
|
+
command,
|
|
27727
|
+
({ api, signal }) => api.workspaces.list({ signal }),
|
|
27728
|
+
{
|
|
27729
|
+
human: formatWorkspaceList,
|
|
27730
|
+
json: summarizeWorkspaceList,
|
|
27731
|
+
ndjson: (workspaces) => workspaces
|
|
27732
|
+
},
|
|
27733
|
+
{ spinner: "Loading workspaces..." }
|
|
27734
|
+
);
|
|
27735
|
+
});
|
|
27736
|
+
workspace.command("use").description("Pin a workspace for subsequent commands").argument("<workspace-id>", "Workspace ID").action(async (workspaceId, _options, command) => {
|
|
27737
|
+
await runApiCommand(
|
|
27738
|
+
command,
|
|
27739
|
+
async ({ api, signal }) => {
|
|
27740
|
+
const workspaces = await api.workspaces.list({ signal });
|
|
27741
|
+
const match = workspaces.find((candidate) => candidate.id === workspaceId);
|
|
27742
|
+
if (!match) {
|
|
27743
|
+
throw new Error(
|
|
27744
|
+
`No workspace ${workspaceId} available to you. Run \`tda workspace list\` to see which are.`
|
|
27745
|
+
);
|
|
27746
|
+
}
|
|
27747
|
+
if (match.access !== "full") {
|
|
27748
|
+
throw new Error(
|
|
27749
|
+
`${match.name} is on a plan that does not cover Automations, so its automations cannot run. Run \`tda workspace list\` to see which are usable.`
|
|
27750
|
+
);
|
|
27751
|
+
}
|
|
27752
|
+
await setDefaultWorkspaceId(workspaceId);
|
|
27753
|
+
return { action: "selected", workspaceId, name: match.name };
|
|
27754
|
+
},
|
|
27755
|
+
{ human: formatWorkspaceSelection },
|
|
27756
|
+
{ spinner: "Checking workspace..." }
|
|
27757
|
+
);
|
|
27758
|
+
});
|
|
27759
|
+
workspace.command("current").description("Show which workspace commands act on").action(async (_options, command) => {
|
|
27760
|
+
await runLocalCommand(
|
|
27761
|
+
command,
|
|
27762
|
+
async () => ({ workspaceId: await getDefaultWorkspaceId() }),
|
|
27763
|
+
{ human: formatCurrentWorkspace }
|
|
27764
|
+
);
|
|
27765
|
+
});
|
|
27766
|
+
workspace.command("clear").description("Unpin the workspace and go back to your personal space").action(async (_options, command) => {
|
|
27767
|
+
await runLocalCommand(
|
|
27768
|
+
command,
|
|
27769
|
+
async () => {
|
|
27770
|
+
await setDefaultWorkspaceId(null);
|
|
27771
|
+
return { action: "cleared", workspaceId: null };
|
|
27772
|
+
},
|
|
27773
|
+
{ human: formatWorkspaceSelection }
|
|
27774
|
+
);
|
|
27775
|
+
});
|
|
27776
|
+
}
|
|
27777
|
+
|
|
27555
27778
|
// src/lib/command-output.ts
|
|
27556
27779
|
function configureCommandOutput(command) {
|
|
27557
27780
|
return command.configureOutput({
|
|
@@ -27584,6 +27807,7 @@ function createProgram() {
|
|
|
27584
27807
|
registerChatCommand(program);
|
|
27585
27808
|
registerSkillCommand(program);
|
|
27586
27809
|
registerUpdateCommand(program);
|
|
27810
|
+
registerWorkspaceCommand(program);
|
|
27587
27811
|
return program;
|
|
27588
27812
|
}
|
|
27589
27813
|
function collect2(value, previous) {
|