robotrock 0.4.0 → 0.5.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 +17 -2
- package/dist/ai/index.d.ts +2 -2
- package/dist/ai/{index.js → index.mjs} +10 -3
- package/dist/ai/trigger.d.ts +1 -1
- package/dist/ai/{trigger.js → trigger.mjs} +6 -3
- package/dist/ai/workflow.d.ts +1 -1
- package/dist/ai/{workflow.js → workflow.mjs} +6 -3
- package/dist/{chunk-D2FBSEZK.js → chunk-3ZYQE5LF.mjs} +1 -1
- package/dist/{chunk-RW2CQQZU.js → chunk-CWQTNK24.mjs} +117 -24
- package/dist/chunk-CWQTNK24.mjs.map +1 -0
- package/dist/{chunk-PZTTI6MW.js → chunk-E7ZWBFZ6.mjs} +2 -2
- package/dist/chunk-VNXWLPRV.mjs +4203 -0
- package/dist/chunk-VNXWLPRV.mjs.map +1 -0
- package/dist/{index.js → index.mjs} +14 -14
- package/dist/{index.js.map → index.mjs.map} +1 -1
- package/dist/schemas/{index.js → index.mjs} +2 -2
- package/dist/trigger/{index.js → index.mjs} +4 -4
- package/dist/workflow/index.d.ts +22 -2
- package/dist/workflow/{index.js → index.mjs} +21 -5
- package/dist/workflow/index.mjs.map +1 -0
- package/dist/{workflow-iDk0Hlyg.d.ts → workflow-CUkzjf6m.d.ts} +97 -13
- package/package.json +6 -2
- package/dist/chunk-2KFY7ZJV.js +0 -157
- package/dist/chunk-2KFY7ZJV.js.map +0 -1
- package/dist/chunk-RW2CQQZU.js.map +0 -1
- package/dist/workflow/index.js.map +0 -1
- /package/dist/ai/{index.js.map → index.mjs.map} +0 -0
- /package/dist/ai/{trigger.js.map → trigger.mjs.map} +0 -0
- /package/dist/ai/{workflow.js.map → workflow.mjs.map} +0 -0
- /package/dist/{chunk-D2FBSEZK.js.map → chunk-3ZYQE5LF.mjs.map} +0 -0
- /package/dist/{chunk-PZTTI6MW.js.map → chunk-E7ZWBFZ6.mjs.map} +0 -0
- /package/dist/schemas/{index.js.map → index.mjs.map} +0 -0
- /package/dist/trigger/{index.js.map → index.mjs.map} +0 -0
|
@@ -8,35 +8,35 @@ import {
|
|
|
8
8
|
resolveRobotRockClient,
|
|
9
9
|
resolveRobotRockConfig,
|
|
10
10
|
toDiscriminatedApprovalResult
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-E7ZWBFZ6.mjs";
|
|
12
12
|
import {
|
|
13
13
|
DEFAULT_THREAD_UPDATE_STATUS,
|
|
14
14
|
assignToSchema,
|
|
15
15
|
createTaskBodySchema,
|
|
16
|
+
external_exports,
|
|
16
17
|
taskContextSchema,
|
|
17
18
|
threadUpdateBodySchema,
|
|
18
19
|
threadUpdateInputSchema,
|
|
19
20
|
threadUpdateStatusSchema,
|
|
20
21
|
threadUpdateStatuses
|
|
21
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-VNXWLPRV.mjs";
|
|
22
23
|
|
|
23
24
|
// src/webhook.ts
|
|
24
25
|
import { createHmac, timingSafeEqual } from "crypto";
|
|
25
|
-
import { z } from "zod";
|
|
26
26
|
var ROBOTROCK_SIGNATURE_HEADER = "x-robotrock-signature";
|
|
27
|
-
var robotRockWebhookPayloadBodySchema =
|
|
28
|
-
taskId:
|
|
29
|
-
action:
|
|
30
|
-
id:
|
|
31
|
-
title:
|
|
32
|
-
data:
|
|
27
|
+
var robotRockWebhookPayloadBodySchema = external_exports.object({
|
|
28
|
+
taskId: external_exports.string().min(1),
|
|
29
|
+
action: external_exports.object({
|
|
30
|
+
id: external_exports.string().min(1),
|
|
31
|
+
title: external_exports.string().min(1),
|
|
32
|
+
data: external_exports.unknown()
|
|
33
33
|
}),
|
|
34
|
-
handledBy:
|
|
35
|
-
handledAt:
|
|
36
|
-
handlerType:
|
|
34
|
+
handledBy: external_exports.string().min(1).optional(),
|
|
35
|
+
handledAt: external_exports.string().min(1),
|
|
36
|
+
handlerType: external_exports.string().min(1)
|
|
37
37
|
});
|
|
38
38
|
var robotRockWebhookPayloadSchema = robotRockWebhookPayloadBodySchema.extend({
|
|
39
|
-
headers:
|
|
39
|
+
headers: external_exports.record(external_exports.string())
|
|
40
40
|
});
|
|
41
41
|
var RobotRockWebhookError = class extends Error {
|
|
42
42
|
constructor(message, code, details) {
|
|
@@ -146,4 +146,4 @@ export {
|
|
|
146
146
|
toDiscriminatedApprovalResult,
|
|
147
147
|
verifyRobotRockWebhook
|
|
148
148
|
};
|
|
149
|
-
//# sourceMappingURL=index.
|
|
149
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/webhook.ts"],"sourcesContent":["import { createHmac, timingSafeEqual } from \"node:crypto\";\nimport { z } from \"zod\";\n\nconst ROBOTROCK_SIGNATURE_HEADER = \"x-robotrock-signature\";\n\nconst robotRockWebhookPayloadBodySchema = z.object({\n taskId: z.string().min(1),\n action: z.object({\n id: z.string().min(1),\n title: z.string().min(1),\n data: z.unknown(),\n }),\n handledBy: z.string().min(1).optional(),\n handledAt: z.string().min(1),\n handlerType: z.string().min(1),\n});\n\nconst robotRockWebhookPayloadSchema = robotRockWebhookPayloadBodySchema.extend({\n headers: z.record(z.string()),\n});\n\nexport type RobotRockWebhookErrorCode =\n | \"MISSING_WEBHOOK_SECRET\"\n | \"MISSING_SIGNATURE\"\n | \"INVALID_SIGNATURE\"\n | \"INVALID_JSON\"\n | \"INVALID_PAYLOAD\";\n\nexport class RobotRockWebhookError extends Error {\n constructor(\n message: string,\n public readonly code: RobotRockWebhookErrorCode,\n public readonly details?: unknown\n ) {\n super(message);\n this.name = \"RobotRockWebhookError\";\n }\n}\n\nexport type RobotRockWebhookPayload = z.infer<typeof robotRockWebhookPayloadSchema>;\n\nexport interface VerifyRobotRockWebhookOptions {\n /**\n * Override shared secret (defaults to ROBOTROCK_WEBHOOK_SECRET).\n * Keep undefined in production to enforce the canonical env var.\n */\n secret?: string;\n /**\n * Resolve the tenant signing secret by public task id (hosted MCP uses Convex).\n * Used when secret is not passed explicitly.\n */\n resolveSecret?: (taskId: string) => Promise<string | undefined>;\n /** Signature header to read. @default \"x-robotrock-signature\" */\n signatureHeader?: string;\n}\n\n/**\n * Verify a RobotRock webhook request and return a validated payload.\n * Throws RobotRockWebhookError with machine-readable `code` for audit logging.\n */\nexport async function verifyRobotRockWebhook(\n request: Request,\n options: VerifyRobotRockWebhookOptions = {}\n): Promise<RobotRockWebhookPayload> {\n const signatureHeaderName = options.signatureHeader ?? ROBOTROCK_SIGNATURE_HEADER;\n const signature = request.headers.get(signatureHeaderName);\n\n if (!signature) {\n throw new RobotRockWebhookError(\n `Missing webhook signature header: ${signatureHeaderName}`,\n \"MISSING_SIGNATURE\"\n );\n }\n\n const rawBody = await request.text();\n const secret = await resolveWebhookSigningSecret(rawBody, options);\n\n if (!secret) {\n throw new RobotRockWebhookError(\n \"Missing webhook signing secret for verification\",\n \"MISSING_WEBHOOK_SECRET\"\n );\n }\n\n assertValidSignature(rawBody, signature, secret);\n\n let parsedBody: unknown;\n try {\n parsedBody = JSON.parse(rawBody);\n } catch (error) {\n throw new RobotRockWebhookError(\"Webhook body is not valid JSON\", \"INVALID_JSON\", {\n cause: error instanceof Error ? error.message : String(error),\n });\n }\n\n const payloadResult = robotRockWebhookPayloadBodySchema.safeParse(parsedBody);\n if (!payloadResult.success) {\n throw new RobotRockWebhookError(\n \"Webhook payload schema validation failed\",\n \"INVALID_PAYLOAD\",\n payloadResult.error.flatten()\n );\n }\n\n return {\n ...payloadResult.data,\n headers: normalizeHeaders(request.headers),\n };\n}\n\nasync function resolveWebhookSigningSecret(\n rawBody: string,\n options: VerifyRobotRockWebhookOptions\n): Promise<string | undefined> {\n if (options.secret) {\n return options.secret;\n }\n\n if (options.resolveSecret) {\n const taskId = peekWebhookTaskId(rawBody);\n if (taskId) {\n const resolved = await options.resolveSecret(taskId);\n if (resolved) {\n return resolved;\n }\n }\n }\n\n return process.env.ROBOTROCK_WEBHOOK_SECRET;\n}\n\nfunction peekWebhookTaskId(rawBody: string): string | undefined {\n try {\n const parsed: unknown = JSON.parse(rawBody);\n if (\n typeof parsed === \"object\" &&\n parsed !== null &&\n \"taskId\" in parsed &&\n typeof (parsed as { taskId: unknown }).taskId === \"string\"\n ) {\n return (parsed as { taskId: string }).taskId;\n }\n } catch {\n // fall through\n }\n return undefined;\n}\n\nfunction assertValidSignature(rawBody: string, signature: string, secret: string): void {\n const expected = `sha256=${createHmac(\"sha256\", secret).update(rawBody).digest(\"hex\")}`;\n const expectedBuffer = Buffer.from(expected);\n const receivedBuffer = Buffer.from(signature);\n\n if (\n expectedBuffer.length !== receivedBuffer.length ||\n !timingSafeEqual(expectedBuffer, receivedBuffer)\n ) {\n throw new RobotRockWebhookError(\"Webhook signature verification failed\", \"INVALID_SIGNATURE\");\n }\n}\n\nfunction normalizeHeaders(headers: Headers): Record<string, string> {\n const result: Record<string, string> = {};\n headers.forEach((value, key) => {\n result[key] = value;\n });\n return result;\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/webhook.ts"],"sourcesContent":["import { createHmac, timingSafeEqual } from \"node:crypto\";\nimport { z } from \"zod\";\n\nconst ROBOTROCK_SIGNATURE_HEADER = \"x-robotrock-signature\";\n\nconst robotRockWebhookPayloadBodySchema = z.object({\n taskId: z.string().min(1),\n action: z.object({\n id: z.string().min(1),\n title: z.string().min(1),\n data: z.unknown(),\n }),\n handledBy: z.string().min(1).optional(),\n handledAt: z.string().min(1),\n handlerType: z.string().min(1),\n});\n\nconst robotRockWebhookPayloadSchema = robotRockWebhookPayloadBodySchema.extend({\n headers: z.record(z.string()),\n});\n\nexport type RobotRockWebhookErrorCode =\n | \"MISSING_WEBHOOK_SECRET\"\n | \"MISSING_SIGNATURE\"\n | \"INVALID_SIGNATURE\"\n | \"INVALID_JSON\"\n | \"INVALID_PAYLOAD\";\n\nexport class RobotRockWebhookError extends Error {\n constructor(\n message: string,\n public readonly code: RobotRockWebhookErrorCode,\n public readonly details?: unknown\n ) {\n super(message);\n this.name = \"RobotRockWebhookError\";\n }\n}\n\nexport type RobotRockWebhookPayload = z.infer<typeof robotRockWebhookPayloadSchema>;\n\nexport interface VerifyRobotRockWebhookOptions {\n /**\n * Override shared secret (defaults to ROBOTROCK_WEBHOOK_SECRET).\n * Keep undefined in production to enforce the canonical env var.\n */\n secret?: string;\n /**\n * Resolve the tenant signing secret by public task id (hosted MCP uses Convex).\n * Used when secret is not passed explicitly.\n */\n resolveSecret?: (taskId: string) => Promise<string | undefined>;\n /** Signature header to read. @default \"x-robotrock-signature\" */\n signatureHeader?: string;\n}\n\n/**\n * Verify a RobotRock webhook request and return a validated payload.\n * Throws RobotRockWebhookError with machine-readable `code` for audit logging.\n */\nexport async function verifyRobotRockWebhook(\n request: Request,\n options: VerifyRobotRockWebhookOptions = {}\n): Promise<RobotRockWebhookPayload> {\n const signatureHeaderName = options.signatureHeader ?? ROBOTROCK_SIGNATURE_HEADER;\n const signature = request.headers.get(signatureHeaderName);\n\n if (!signature) {\n throw new RobotRockWebhookError(\n `Missing webhook signature header: ${signatureHeaderName}`,\n \"MISSING_SIGNATURE\"\n );\n }\n\n const rawBody = await request.text();\n const secret = await resolveWebhookSigningSecret(rawBody, options);\n\n if (!secret) {\n throw new RobotRockWebhookError(\n \"Missing webhook signing secret for verification\",\n \"MISSING_WEBHOOK_SECRET\"\n );\n }\n\n assertValidSignature(rawBody, signature, secret);\n\n let parsedBody: unknown;\n try {\n parsedBody = JSON.parse(rawBody);\n } catch (error) {\n throw new RobotRockWebhookError(\"Webhook body is not valid JSON\", \"INVALID_JSON\", {\n cause: error instanceof Error ? error.message : String(error),\n });\n }\n\n const payloadResult = robotRockWebhookPayloadBodySchema.safeParse(parsedBody);\n if (!payloadResult.success) {\n throw new RobotRockWebhookError(\n \"Webhook payload schema validation failed\",\n \"INVALID_PAYLOAD\",\n payloadResult.error.flatten()\n );\n }\n\n return {\n ...payloadResult.data,\n headers: normalizeHeaders(request.headers),\n };\n}\n\nasync function resolveWebhookSigningSecret(\n rawBody: string,\n options: VerifyRobotRockWebhookOptions\n): Promise<string | undefined> {\n if (options.secret) {\n return options.secret;\n }\n\n if (options.resolveSecret) {\n const taskId = peekWebhookTaskId(rawBody);\n if (taskId) {\n const resolved = await options.resolveSecret(taskId);\n if (resolved) {\n return resolved;\n }\n }\n }\n\n return process.env.ROBOTROCK_WEBHOOK_SECRET;\n}\n\nfunction peekWebhookTaskId(rawBody: string): string | undefined {\n try {\n const parsed: unknown = JSON.parse(rawBody);\n if (\n typeof parsed === \"object\" &&\n parsed !== null &&\n \"taskId\" in parsed &&\n typeof (parsed as { taskId: unknown }).taskId === \"string\"\n ) {\n return (parsed as { taskId: string }).taskId;\n }\n } catch {\n // fall through\n }\n return undefined;\n}\n\nfunction assertValidSignature(rawBody: string, signature: string, secret: string): void {\n const expected = `sha256=${createHmac(\"sha256\", secret).update(rawBody).digest(\"hex\")}`;\n const expectedBuffer = Buffer.from(expected);\n const receivedBuffer = Buffer.from(signature);\n\n if (\n expectedBuffer.length !== receivedBuffer.length ||\n !timingSafeEqual(expectedBuffer, receivedBuffer)\n ) {\n throw new RobotRockWebhookError(\"Webhook signature verification failed\", \"INVALID_SIGNATURE\");\n }\n}\n\nfunction normalizeHeaders(headers: Headers): Record<string, string> {\n const result: Record<string, string> = {};\n headers.forEach((value, key) => {\n result[key] = value;\n });\n return result;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
threadUpdateMessageSchema,
|
|
9
9
|
threadUpdateStatusSchema,
|
|
10
10
|
threadUpdateStatuses
|
|
11
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-VNXWLPRV.mjs";
|
|
12
12
|
export {
|
|
13
13
|
DEFAULT_THREAD_UPDATE_STATUS,
|
|
14
14
|
assignToSchema,
|
|
@@ -20,4 +20,4 @@ export {
|
|
|
20
20
|
threadUpdateStatusSchema,
|
|
21
21
|
threadUpdateStatuses
|
|
22
22
|
};
|
|
23
|
-
//# sourceMappingURL=index.
|
|
23
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isRobotRockHandlerWebhookPayload,
|
|
3
3
|
resolveWaitTiming
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-3ZYQE5LF.mjs";
|
|
5
5
|
import {
|
|
6
6
|
createClient,
|
|
7
7
|
resolveRobotRockConfig,
|
|
8
8
|
toDiscriminatedApprovalResult
|
|
9
|
-
} from "../chunk-
|
|
10
|
-
import "../chunk-
|
|
9
|
+
} from "../chunk-E7ZWBFZ6.mjs";
|
|
10
|
+
import "../chunk-VNXWLPRV.mjs";
|
|
11
11
|
|
|
12
12
|
// src/trigger/index.ts
|
|
13
13
|
import { task, wait } from "@trigger.dev/sdk";
|
|
@@ -75,4 +75,4 @@ export {
|
|
|
75
75
|
approveByHumanTask,
|
|
76
76
|
sendToHumanTask
|
|
77
77
|
};
|
|
78
|
-
//# sourceMappingURL=index.
|
|
78
|
+
//# sourceMappingURL=index.mjs.map
|
package/dist/workflow/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DiscriminatedApprovalResult } from '../schemas/index.js';
|
|
1
|
+
import { DiscriminatedApprovalResult, ThreadUpdateStatus, ThreadUpdate } from '../schemas/index.js';
|
|
2
2
|
export { ApprovalResult, TaskContextInput, TaskResult } from '../schemas/index.js';
|
|
3
3
|
import { S as SendToHumanActionInput, a as SendToHumanInput } from '../client-BOm2Ce2f.js';
|
|
4
4
|
export { R as RobotRockHandlerWebhookPayload } from '../handler-webhook-BqEi6Bk-.js';
|
|
@@ -31,5 +31,25 @@ declare function sendToHumanInWorkflow<const A extends readonly SendToHumanActio
|
|
|
31
31
|
* Approve / decline gate for Vercel Workflow (`sendToHumanInWorkflow` with fixed actions).
|
|
32
32
|
*/
|
|
33
33
|
declare function approveByHumanInWorkflow(payload: ApproveByHumanWorkflowPayload): Promise<Expand<DiscriminatedApprovalResult<typeof APPROVE_BY_HUMAN_ACTIONS>>>;
|
|
34
|
+
type SendUpdateWorkflowPayload = {
|
|
35
|
+
/** Thread to log the update against (from a prior task's `threadId`). */
|
|
36
|
+
threadId: string;
|
|
37
|
+
/** Short status update (1-2 sentences) shown in the inbox status bar. */
|
|
38
|
+
message: string;
|
|
39
|
+
/** Lifecycle status driving the status-bar icon/color. @default "info" */
|
|
40
|
+
status?: ThreadUpdateStatus;
|
|
41
|
+
/** Inbox app bucket. Overrides `ROBOTROCK_APP` when set. */
|
|
42
|
+
app?: string;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Durable thread update for Vercel Workflow.
|
|
46
|
+
*
|
|
47
|
+
* Wraps {@link createClient}'s `sendUpdate` in a `"use step"` so progress
|
|
48
|
+
* reports are retried and recorded in the run. Fire-and-forget: returns the
|
|
49
|
+
* created update without suspending the workflow (no human wait involved).
|
|
50
|
+
*
|
|
51
|
+
* Call from a function with `"use workflow"` as its first statement.
|
|
52
|
+
*/
|
|
53
|
+
declare function sendUpdateInWorkflow(payload: SendUpdateWorkflowPayload): Promise<ThreadUpdate>;
|
|
34
54
|
|
|
35
|
-
export { type ApproveByHumanWorkflowPayload, DiscriminatedApprovalResult, type SendToHumanWorkflowPayload, approveByHumanInWorkflow, sendToHumanInWorkflow };
|
|
55
|
+
export { type ApproveByHumanWorkflowPayload, DiscriminatedApprovalResult, type SendToHumanWorkflowPayload, type SendUpdateWorkflowPayload, ThreadUpdate, ThreadUpdateStatus, approveByHumanInWorkflow, sendToHumanInWorkflow, sendUpdateInWorkflow };
|
|
@@ -2,16 +2,16 @@ import {
|
|
|
2
2
|
isRobotRockHandlerWebhookPayload,
|
|
3
3
|
parseValidUntilMs,
|
|
4
4
|
resolveWaitTiming
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-3ZYQE5LF.mjs";
|
|
6
6
|
import {
|
|
7
7
|
createClient,
|
|
8
8
|
resolveRobotRockConfig,
|
|
9
9
|
toDiscriminatedApprovalResult
|
|
10
|
-
} from "../chunk-
|
|
10
|
+
} from "../chunk-E7ZWBFZ6.mjs";
|
|
11
11
|
import {
|
|
12
12
|
__callDispose,
|
|
13
13
|
__using
|
|
14
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-VNXWLPRV.mjs";
|
|
15
15
|
|
|
16
16
|
// src/workflow/index.ts
|
|
17
17
|
import { createWebhook, sleep } from "workflow";
|
|
@@ -92,8 +92,24 @@ async function approveByHumanInWorkflow(payload) {
|
|
|
92
92
|
actions: APPROVE_BY_HUMAN_ACTIONS
|
|
93
93
|
});
|
|
94
94
|
}
|
|
95
|
+
async function sendRobotRockUpdate(payload) {
|
|
96
|
+
"use step";
|
|
97
|
+
const { app, ...update } = payload;
|
|
98
|
+
const baseConfig = resolveRobotRockConfig();
|
|
99
|
+
const client = createClient({
|
|
100
|
+
apiKey: baseConfig.apiKey,
|
|
101
|
+
baseUrl: baseConfig.baseUrl,
|
|
102
|
+
...app ?? baseConfig.app ? { app: app ?? baseConfig.app } : {},
|
|
103
|
+
...baseConfig.version ? { version: baseConfig.version } : {}
|
|
104
|
+
});
|
|
105
|
+
return client.sendUpdate(update);
|
|
106
|
+
}
|
|
107
|
+
async function sendUpdateInWorkflow(payload) {
|
|
108
|
+
return sendRobotRockUpdate(payload);
|
|
109
|
+
}
|
|
95
110
|
export {
|
|
96
111
|
approveByHumanInWorkflow,
|
|
97
|
-
sendToHumanInWorkflow
|
|
112
|
+
sendToHumanInWorkflow,
|
|
113
|
+
sendUpdateInWorkflow
|
|
98
114
|
};
|
|
99
|
-
//# sourceMappingURL=index.
|
|
115
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/workflow/index.ts"],"sourcesContent":["import { createWebhook, sleep } from \"workflow\";\nimport type {\n DiscriminatedApprovalResult,\n ThreadUpdate,\n ThreadUpdateStatus,\n} from \"../schemas/index.js\";\nimport {\n createClient,\n type SendToHumanActionInput,\n type SendToHumanInput,\n} from \"../client.js\";\nimport { resolveRobotRockConfig } from \"../env.js\";\nimport { toDiscriminatedApprovalResult } from \"../approval-result.js\";\nimport {\n isRobotRockHandlerWebhookPayload,\n type RobotRockHandlerWebhookPayload,\n} from \"../handler-webhook.js\";\nimport { parseValidUntilMs, resolveWaitTiming } from \"../wait-timing.js\";\n\nexport type SendToHumanWorkflowPayload<\n A extends readonly SendToHumanActionInput[] = readonly SendToHumanActionInput[],\n> = SendToHumanInput<A> & {\n /** Inbox app bucket. Overrides `ROBOTROCK_APP` when set. */\n app?: string;\n};\n\nexport type ApproveByHumanWorkflowPayload = Omit<SendToHumanWorkflowPayload, \"actions\">;\n\ntype Expand<T> = T extends unknown ? { [K in keyof T]: T[K] } : never;\n\nconst APPROVE_BY_HUMAN_ACTIONS = [\n { id: \"approve\", title: \"Approve\" },\n { id: \"decline\", title: \"Decline\" },\n] as const;\n\ntype CreateTaskStepInput = {\n webhookUrl: string;\n app?: string;\n validUntil: Date | string;\n taskInput: Omit<SendToHumanWorkflowPayload, \"validUntil\" | \"app\">;\n};\n\n/**\n * Creates the RobotRock inbox task with the workflow webhook URL as the handler.\n * Marked as a step so API calls run in full Node.js with retries.\n */\nasync function createRobotRockTaskForWebhook(input: CreateTaskStepInput) {\n \"use step\";\n\n const baseConfig = resolveRobotRockConfig();\n const client = createClient({\n apiKey: baseConfig.apiKey,\n baseUrl: baseConfig.baseUrl,\n ...((input.app ?? baseConfig.app) ? { app: input.app ?? baseConfig.app } : {}),\n ...(baseConfig.version ? { version: baseConfig.version } : {}),\n webhook: { url: input.webhookUrl },\n });\n\n return client.sendToHuman({\n ...input.taskInput,\n validUntil: input.validUntil,\n });\n}\n\nasync function parseRobotRockWebhookRequest(request: Request) {\n \"use step\";\n\n const body: unknown = await request.json();\n if (!isRobotRockHandlerWebhookPayload(body)) {\n throw new Error(\n \"Workflow webhook completed with unexpected payload; expected RobotRock handler body (taskId, action.id, action.data).\"\n );\n }\n\n return body;\n}\n\n/**\n * Durable human-in-the-loop wait for Vercel Workflow.\n *\n * Call from a function with `\"use workflow\"` as its first statement. Creates a\n * {@link createWebhook} URL, registers it as the RobotRock task webhook, and\n * suspends until a human handles an action or `validUntil` passes.\n */\nexport async function sendToHumanInWorkflow<\n const A extends readonly SendToHumanActionInput[],\n>(\n payload: SendToHumanWorkflowPayload<A>\n): Promise<Expand<DiscriminatedApprovalResult<A>>> {\n const { validUntil: validUntilInput, app, ...taskInput } = payload;\n const { validUntil, timeout } = resolveWaitTiming(validUntilInput);\n const timeoutMs = parseValidUntilMs(validUntil) - Date.now();\n\n using webhook = createWebhook();\n\n const sendResult = await createRobotRockTaskForWebhook({\n webhookUrl: webhook.url,\n app,\n validUntil,\n taskInput,\n });\n\n const outcome = await Promise.race([\n webhook.then((request) => parseRobotRockWebhookRequest(request)),\n sleep(timeoutMs).then(() => ({ timedOut: true }) as const),\n ]);\n\n if (\"timedOut\" in outcome) {\n throw new Error(`Human response timed out before validUntil (${timeout})`);\n }\n\n const output: RobotRockHandlerWebhookPayload = outcome;\n\n return toDiscriminatedApprovalResult(payload.actions, {\n id: output.taskId,\n createdAt: new Date(),\n status: \"handled\",\n context: sendResult.task.context,\n validUntil: Date.now(),\n handledAt: new Date(output.handledAt).getTime(),\n handled: {\n action: {\n id: output.action.id,\n data: output.action.data,\n },\n handledBy: output.handledBy,\n },\n }) as unknown as Expand<DiscriminatedApprovalResult<A>>;\n}\n\n/**\n * Approve / decline gate for Vercel Workflow (`sendToHumanInWorkflow` with fixed actions).\n */\nexport async function approveByHumanInWorkflow(\n payload: ApproveByHumanWorkflowPayload\n): Promise<Expand<DiscriminatedApprovalResult<typeof APPROVE_BY_HUMAN_ACTIONS>>> {\n return sendToHumanInWorkflow({\n ...payload,\n actions: APPROVE_BY_HUMAN_ACTIONS,\n });\n}\n\nexport type SendUpdateWorkflowPayload = {\n /** Thread to log the update against (from a prior task's `threadId`). */\n threadId: string;\n /** Short status update (1-2 sentences) shown in the inbox status bar. */\n message: string;\n /** Lifecycle status driving the status-bar icon/color. @default \"info\" */\n status?: ThreadUpdateStatus;\n /** Inbox app bucket. Overrides `ROBOTROCK_APP` when set. */\n app?: string;\n};\n\n/**\n * Posts a thread update via `client.sendUpdate()`. Marked as a step so the API\n * call runs in full Node.js with retries and is recorded in the workflow run.\n */\nasync function sendRobotRockUpdate(payload: SendUpdateWorkflowPayload): Promise<ThreadUpdate> {\n \"use step\";\n\n const { app, ...update } = payload;\n const baseConfig = resolveRobotRockConfig();\n const client = createClient({\n apiKey: baseConfig.apiKey,\n baseUrl: baseConfig.baseUrl,\n ...((app ?? baseConfig.app) ? { app: app ?? baseConfig.app } : {}),\n ...(baseConfig.version ? { version: baseConfig.version } : {}),\n });\n\n return client.sendUpdate(update);\n}\n\n/**\n * Durable thread update for Vercel Workflow.\n *\n * Wraps {@link createClient}'s `sendUpdate` in a `\"use step\"` so progress\n * reports are retried and recorded in the run. Fire-and-forget: returns the\n * created update without suspending the workflow (no human wait involved).\n *\n * Call from a function with `\"use workflow\"` as its first statement.\n */\nexport async function sendUpdateInWorkflow(\n payload: SendUpdateWorkflowPayload\n): Promise<ThreadUpdate> {\n return sendRobotRockUpdate(payload);\n}\n\nexport type { RobotRockHandlerWebhookPayload } from \"../handler-webhook.js\";\nexport type {\n ApprovalResult,\n DiscriminatedApprovalResult,\n TaskContextInput,\n TaskResult,\n ThreadUpdate,\n ThreadUpdateStatus,\n} from \"../schemas/index.js\";\n"],"mappings":"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","names":[]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as ai from 'ai';
|
|
2
2
|
import { ToolApprovalResponse } from 'ai';
|
|
3
3
|
import { z } from 'zod';
|
|
4
|
-
import { b as RobotRock, a as SendToHumanInput, S as SendToHumanActionInput } from './client-BOm2Ce2f.js';
|
|
5
|
-
import { DiscriminatedApprovalResult } from './schemas/index.js';
|
|
4
|
+
import { b as RobotRock, a as SendToHumanInput, S as SendToHumanActionInput, l as SendUpdateInput } from './client-BOm2Ce2f.js';
|
|
5
|
+
import { DiscriminatedApprovalResult, ThreadUpdate } from './schemas/index.js';
|
|
6
6
|
|
|
7
7
|
declare const APPROVE_BY_HUMAN_ACTIONS$1: readonly [{
|
|
8
8
|
readonly id: "approve";
|
|
@@ -35,6 +35,14 @@ type RobotRockAiWorkflowContext = {
|
|
|
35
35
|
type RobotRockAiContext = RobotRockAiPollingContext | RobotRockAiTriggerContext | RobotRockAiWorkflowContext;
|
|
36
36
|
declare function normalizeRobotRockAiContext(clientOrContext: RobotRock | RobotRockAiContext): RobotRockAiContext;
|
|
37
37
|
declare function sendToHumanForAi<A extends readonly SendToHumanActionInput[] = readonly SendToHumanActionInput[]>(context: RobotRockAiContext, payload: SendToHumanInput<A>): Promise<DiscriminatedApprovalResult<A>>;
|
|
38
|
+
/**
|
|
39
|
+
* Posts a thread update for an AI tool, routing by execution mode.
|
|
40
|
+
*
|
|
41
|
+
* `sendUpdate` is fire-and-forget (no human wait), so only the workflow path
|
|
42
|
+
* needs durability — it runs inside a `"use step"`. Trigger and polling modes
|
|
43
|
+
* issue the request directly.
|
|
44
|
+
*/
|
|
45
|
+
declare function sendUpdateForAi(context: RobotRockAiContext, payload: SendUpdateInput): Promise<ThreadUpdate>;
|
|
38
46
|
declare function approveByHumanForAi(context: RobotRockAiContext, payload: Omit<SendToHumanInput, "actions"> & {
|
|
39
47
|
app?: string;
|
|
40
48
|
}): Promise<DiscriminatedApprovalResult<typeof APPROVE_BY_HUMAN_ACTIONS$1>>;
|
|
@@ -101,13 +109,13 @@ declare const approveByHumanInputSchema: z.ZodObject<{
|
|
|
101
109
|
description: z.ZodString;
|
|
102
110
|
contextSummary: z.ZodOptional<z.ZodString>;
|
|
103
111
|
}, "strip", z.ZodTypeAny, {
|
|
104
|
-
description: string;
|
|
105
112
|
name: string;
|
|
113
|
+
description: string;
|
|
106
114
|
type?: string | undefined;
|
|
107
115
|
contextSummary?: string | undefined;
|
|
108
116
|
}, {
|
|
109
|
-
description: string;
|
|
110
117
|
name: string;
|
|
118
|
+
description: string;
|
|
111
119
|
type?: string | undefined;
|
|
112
120
|
contextSummary?: string | undefined;
|
|
113
121
|
}>;
|
|
@@ -127,8 +135,8 @@ type ApproveByHumanToolDurableOptions = ApproveByHumanToolOptions & RobotRockAiC
|
|
|
127
135
|
* - `approveByHumanTool({ mode: "workflow", app?: "my-agent" })` — durable wait via Vercel Workflow.
|
|
128
136
|
*/
|
|
129
137
|
declare function approveByHumanTool(clientOrContext: RobotRock | ApproveByHumanToolDurableOptions, maybeOptions?: ApproveByHumanToolOptions): ai.Tool<{
|
|
130
|
-
description: string;
|
|
131
138
|
name: string;
|
|
139
|
+
description: string;
|
|
132
140
|
type?: string | undefined;
|
|
133
141
|
contextSummary?: string | undefined;
|
|
134
142
|
}, HumanToolResult>;
|
|
@@ -141,11 +149,11 @@ declare const sendToHumanToolInputSchema: z.ZodObject<{
|
|
|
141
149
|
data: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
142
150
|
ui: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
143
151
|
}, "strip", z.ZodTypeAny, {
|
|
144
|
-
ui?: Record<string, unknown> | undefined;
|
|
145
152
|
data?: Record<string, unknown> | undefined;
|
|
146
|
-
}, {
|
|
147
153
|
ui?: Record<string, unknown> | undefined;
|
|
154
|
+
}, {
|
|
148
155
|
data?: Record<string, unknown> | undefined;
|
|
156
|
+
ui?: Record<string, unknown> | undefined;
|
|
149
157
|
}>>;
|
|
150
158
|
validUntil: z.ZodOptional<z.ZodString>;
|
|
151
159
|
assignTo: z.ZodOptional<z.ZodEffects<z.ZodObject<{
|
|
@@ -170,8 +178,8 @@ declare const sendToHumanToolInputSchema: z.ZodObject<{
|
|
|
170
178
|
description?: string | undefined;
|
|
171
179
|
validUntil?: string | undefined;
|
|
172
180
|
context?: {
|
|
173
|
-
ui?: Record<string, unknown> | undefined;
|
|
174
181
|
data?: Record<string, unknown> | undefined;
|
|
182
|
+
ui?: Record<string, unknown> | undefined;
|
|
175
183
|
} | undefined;
|
|
176
184
|
assignTo?: {
|
|
177
185
|
users?: string[] | undefined;
|
|
@@ -183,8 +191,8 @@ declare const sendToHumanToolInputSchema: z.ZodObject<{
|
|
|
183
191
|
description?: string | undefined;
|
|
184
192
|
validUntil?: string | undefined;
|
|
185
193
|
context?: {
|
|
186
|
-
ui?: Record<string, unknown> | undefined;
|
|
187
194
|
data?: Record<string, unknown> | undefined;
|
|
195
|
+
ui?: Record<string, unknown> | undefined;
|
|
188
196
|
} | undefined;
|
|
189
197
|
assignTo?: {
|
|
190
198
|
users?: string[] | undefined;
|
|
@@ -196,6 +204,11 @@ type CreateSendToHumanToolOptions<A extends readonly SendToHumanActionInput[] =
|
|
|
196
204
|
defaultType?: string;
|
|
197
205
|
description?: string;
|
|
198
206
|
toolName?: string;
|
|
207
|
+
/**
|
|
208
|
+
* Group every task this tool creates onto a shared thread. Pass the same
|
|
209
|
+
* value to {@link createSendUpdateTool} so updates land on the same thread.
|
|
210
|
+
*/
|
|
211
|
+
threadId?: string;
|
|
199
212
|
};
|
|
200
213
|
type CreateSendToHumanToolDurableOptions<A extends readonly SendToHumanActionInput[] = readonly SendToHumanActionInput[]> = CreateSendToHumanToolOptions<A> & RobotRockAiContext & {
|
|
201
214
|
mode: "trigger" | "workflow";
|
|
@@ -213,8 +226,8 @@ declare function createSendToHumanTool<A extends readonly SendToHumanActionInput
|
|
|
213
226
|
description?: string | undefined;
|
|
214
227
|
validUntil?: string | undefined;
|
|
215
228
|
context?: {
|
|
216
|
-
ui?: Record<string, unknown> | undefined;
|
|
217
229
|
data?: Record<string, unknown> | undefined;
|
|
230
|
+
ui?: Record<string, unknown> | undefined;
|
|
218
231
|
} | undefined;
|
|
219
232
|
assignTo?: {
|
|
220
233
|
users?: string[] | undefined;
|
|
@@ -222,11 +235,77 @@ declare function createSendToHumanTool<A extends readonly SendToHumanActionInput
|
|
|
222
235
|
} | undefined;
|
|
223
236
|
}, HumanToolResult>;
|
|
224
237
|
|
|
238
|
+
/**
|
|
239
|
+
* Result returned to the model by {@link createSendUpdateTool}.
|
|
240
|
+
*
|
|
241
|
+
* Updates are fire-and-forget, so a missing thread (no task created yet) is
|
|
242
|
+
* reported as `{ posted: false }` instead of throwing — that way an agent loop
|
|
243
|
+
* is never aborted by a non-critical progress update. Genuine failures (auth,
|
|
244
|
+
* validation, server errors) still throw.
|
|
245
|
+
*/
|
|
246
|
+
type SendUpdateToolResult = {
|
|
247
|
+
posted: true;
|
|
248
|
+
threadId: string;
|
|
249
|
+
update: ThreadUpdate;
|
|
250
|
+
} | {
|
|
251
|
+
posted: false;
|
|
252
|
+
threadId: string;
|
|
253
|
+
reason: "thread_not_found";
|
|
254
|
+
message: string;
|
|
255
|
+
};
|
|
256
|
+
declare const sendUpdateToolInputSchema: z.ZodObject<{
|
|
257
|
+
threadId: z.ZodOptional<z.ZodString>;
|
|
258
|
+
message: z.ZodString;
|
|
259
|
+
status: z.ZodOptional<z.ZodEnum<["info", "queued", "running", "waiting", "succeeded", "failed", "cancelled"]>>;
|
|
260
|
+
}, "strip", z.ZodTypeAny, {
|
|
261
|
+
message: string;
|
|
262
|
+
status?: "info" | "queued" | "running" | "waiting" | "succeeded" | "failed" | "cancelled" | undefined;
|
|
263
|
+
threadId?: string | undefined;
|
|
264
|
+
}, {
|
|
265
|
+
message: string;
|
|
266
|
+
status?: "info" | "queued" | "running" | "waiting" | "succeeded" | "failed" | "cancelled" | undefined;
|
|
267
|
+
threadId?: string | undefined;
|
|
268
|
+
}>;
|
|
269
|
+
type CreateSendUpdateToolOptions = {
|
|
270
|
+
/**
|
|
271
|
+
* Session thread to post updates to when the model does not supply `threadId`.
|
|
272
|
+
* Pass the same value to {@link createSendToHumanTool} to auto-thread tasks
|
|
273
|
+
* and updates together.
|
|
274
|
+
*/
|
|
275
|
+
threadId?: string;
|
|
276
|
+
description?: string;
|
|
277
|
+
};
|
|
278
|
+
type CreateSendUpdateToolDurableOptions = CreateSendUpdateToolOptions & RobotRockAiContext & {
|
|
279
|
+
mode: "trigger" | "workflow";
|
|
280
|
+
};
|
|
281
|
+
/**
|
|
282
|
+
* AI SDK tool that posts a progress update to a RobotRock thread.
|
|
283
|
+
*
|
|
284
|
+
* Fire-and-forget (no human wait): the agent reports status as it works.
|
|
285
|
+
*
|
|
286
|
+
* - `createSendUpdateTool(robotrock, options?)` — polling client (default).
|
|
287
|
+
* - `createSendUpdateTool({ mode: "trigger", app?: "my-agent" })` — Trigger.dev worker.
|
|
288
|
+
* - `createSendUpdateTool({ mode: "workflow", app?: "my-agent" })` — Vercel Workflow (durable step).
|
|
289
|
+
*
|
|
290
|
+
* The thread is resolved from the tool input `threadId`, falling back to a
|
|
291
|
+
* session `threadId` in the options. Provide at least one.
|
|
292
|
+
*/
|
|
293
|
+
declare function createSendUpdateTool(clientOrOptions: RobotRock | CreateSendUpdateToolDurableOptions, maybeOptions?: CreateSendUpdateToolOptions): ai.Tool<{
|
|
294
|
+
message: string;
|
|
295
|
+
status?: "info" | "queued" | "running" | "waiting" | "succeeded" | "failed" | "cancelled" | undefined;
|
|
296
|
+
threadId?: string | undefined;
|
|
297
|
+
}, SendUpdateToolResult>;
|
|
298
|
+
|
|
225
299
|
type CreateRobotRockAiToolsOptions = {
|
|
226
300
|
/** @default "polling" when `client` is passed; `"trigger"` or `"workflow"` for durable waits. */
|
|
227
301
|
mode?: "polling" | "trigger" | "workflow";
|
|
228
302
|
client?: RobotRock;
|
|
229
303
|
app?: string;
|
|
304
|
+
/**
|
|
305
|
+
* Shared thread for tasks and updates these tools create. Enables the
|
|
306
|
+
* `sendUpdate` tool to auto-thread onto tasks made by the `sendToHuman` tool.
|
|
307
|
+
*/
|
|
308
|
+
threadId?: string;
|
|
230
309
|
};
|
|
231
310
|
/**
|
|
232
311
|
* Build AI SDK tools for a given RobotRock execution mode.
|
|
@@ -249,8 +328,8 @@ type CreateRobotRockAiToolsOptions = {
|
|
|
249
328
|
declare function createRobotRockAiTools(options: CreateRobotRockAiToolsOptions): {
|
|
250
329
|
context: RobotRockAiContext;
|
|
251
330
|
approveByHuman: (toolOptions?: ApproveByHumanToolOptions) => ai.Tool<{
|
|
252
|
-
description: string;
|
|
253
331
|
name: string;
|
|
332
|
+
description: string;
|
|
254
333
|
type?: string | undefined;
|
|
255
334
|
contextSummary?: string | undefined;
|
|
256
335
|
}, HumanToolResult>;
|
|
@@ -260,14 +339,19 @@ declare function createRobotRockAiTools(options: CreateRobotRockAiToolsOptions):
|
|
|
260
339
|
description?: string | undefined;
|
|
261
340
|
validUntil?: string | undefined;
|
|
262
341
|
context?: {
|
|
263
|
-
ui?: Record<string, unknown> | undefined;
|
|
264
342
|
data?: Record<string, unknown> | undefined;
|
|
343
|
+
ui?: Record<string, unknown> | undefined;
|
|
265
344
|
} | undefined;
|
|
266
345
|
assignTo?: {
|
|
267
346
|
users?: string[] | undefined;
|
|
268
347
|
groups?: string[] | undefined;
|
|
269
348
|
} | undefined;
|
|
270
349
|
}, HumanToolResult>;
|
|
350
|
+
sendUpdate: (toolOptions?: CreateSendUpdateToolOptions) => ai.Tool<{
|
|
351
|
+
message: string;
|
|
352
|
+
status?: "info" | "queued" | "running" | "waiting" | "succeeded" | "failed" | "cancelled" | undefined;
|
|
353
|
+
threadId?: string | undefined;
|
|
354
|
+
}, SendUpdateToolResult>;
|
|
271
355
|
};
|
|
272
356
|
/** Shorthand for `{ mode: "trigger", app }`. */
|
|
273
357
|
declare function createRobotRockAiTriggerContext(options?: Omit<RobotRockAiTriggerContext, "mode">): RobotRockAiContext;
|
|
@@ -306,4 +390,4 @@ declare function resolveToolApprovalsViaRobotRock(clientOrContext: RobotRock | R
|
|
|
306
390
|
*/
|
|
307
391
|
declare function runWithRobotRockApprovals<T>(options: RunWithRobotRockApprovalsOptions<T>): Promise<T>;
|
|
308
392
|
|
|
309
|
-
export { APPROVE_BY_HUMAN_ACTIONS as A,
|
|
393
|
+
export { APPROVE_BY_HUMAN_ACTIONS as A, createRobotRockNeedsApproval as B, type CreateSendToHumanToolOptions as C, createRobotRockToolApproval as D, resolveToolApprovalsViaRobotRock as E, type FormatToolApprovalTaskOptions as F, runWithRobotRockApprovals as G, type HumanToolResult as H, type RobotRockToolApprovalDecision as I, type ResolveToolApprovalsOptions as J, type RobotRockToolApprovalConfig as K, type RunWithRobotRockApprovalsOptions as L, type RobotRockToolCallInfo as R, type SendUpdateToolResult as S, type ToolApprovalRequestPart as T, approveByHumanTool as a, approveByHumanInputSchema as b, type ApproveByHumanToolOptions as c, type ApproveByHumanToolDurableOptions as d, createSendToHumanTool as e, type CreateSendToHumanToolDurableOptions as f, createSendUpdateTool as g, sendUpdateToolInputSchema as h, type CreateSendUpdateToolOptions as i, type CreateSendUpdateToolDurableOptions as j, approveByHumanForAi as k, sendToHumanForAi as l, sendUpdateForAi as m, normalizeRobotRockAiContext as n, type RobotRockAiContext as o, type RobotRockAiMode as p, type RobotRockAiPollingContext as q, type RobotRockAiTriggerContext as r, sendToHumanToolInputSchema as s, type RobotRockAiWorkflowContext as t, createRobotRockAiTools as u, createRobotRockAiTriggerContext as v, createRobotRockAiWorkflowContext as w, type CreateRobotRockAiToolsOptions as x, applyRobotRockToolApprovalToTools as y, collectApprovalRequests as z };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "robotrock",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Human-in-the-loop approval workflows for AI agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -54,9 +54,13 @@
|
|
|
54
54
|
"ai-sdk"
|
|
55
55
|
],
|
|
56
56
|
"license": "MIT",
|
|
57
|
+
"homepage": "https://docs.robotrock.io",
|
|
57
58
|
"repository": {
|
|
58
59
|
"type": "git",
|
|
59
|
-
"url": "git+https://github.com/
|
|
60
|
+
"url": "git+https://github.com/quintenb/robotrock-sdk.git"
|
|
61
|
+
},
|
|
62
|
+
"bugs": {
|
|
63
|
+
"url": "https://github.com/quintenb/robotrock-sdk/issues"
|
|
60
64
|
},
|
|
61
65
|
"dependencies": {
|
|
62
66
|
"zod": "^3.25.0"
|
package/dist/chunk-2KFY7ZJV.js
DELETED
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : /* @__PURE__ */ Symbol.for("Symbol." + name);
|
|
2
|
-
var __typeError = (msg) => {
|
|
3
|
-
throw TypeError(msg);
|
|
4
|
-
};
|
|
5
|
-
var __using = (stack, value, async) => {
|
|
6
|
-
if (value != null) {
|
|
7
|
-
if (typeof value !== "object" && typeof value !== "function") __typeError("Object expected");
|
|
8
|
-
var dispose, inner;
|
|
9
|
-
if (async) dispose = value[__knownSymbol("asyncDispose")];
|
|
10
|
-
if (dispose === void 0) {
|
|
11
|
-
dispose = value[__knownSymbol("dispose")];
|
|
12
|
-
if (async) inner = dispose;
|
|
13
|
-
}
|
|
14
|
-
if (typeof dispose !== "function") __typeError("Object not disposable");
|
|
15
|
-
if (inner) dispose = function() {
|
|
16
|
-
try {
|
|
17
|
-
inner.call(this);
|
|
18
|
-
} catch (e) {
|
|
19
|
-
return Promise.reject(e);
|
|
20
|
-
}
|
|
21
|
-
};
|
|
22
|
-
stack.push([async, dispose, value]);
|
|
23
|
-
} else if (async) {
|
|
24
|
-
stack.push([async]);
|
|
25
|
-
}
|
|
26
|
-
return value;
|
|
27
|
-
};
|
|
28
|
-
var __callDispose = (stack, error, hasError) => {
|
|
29
|
-
var E = typeof SuppressedError === "function" ? SuppressedError : function(e, s, m, _) {
|
|
30
|
-
return _ = Error(m), _.name = "SuppressedError", _.error = e, _.suppressed = s, _;
|
|
31
|
-
};
|
|
32
|
-
var fail = (e) => error = hasError ? new E(e, error, "An error was suppressed during disposal") : (hasError = true, e);
|
|
33
|
-
var next = (it) => {
|
|
34
|
-
while (it = stack.pop()) {
|
|
35
|
-
try {
|
|
36
|
-
var result = it[1] && it[1].call(it[2]);
|
|
37
|
-
if (it[0]) return Promise.resolve(result).then(next, (e) => (fail(e), next()));
|
|
38
|
-
} catch (e) {
|
|
39
|
-
fail(e);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
if (hasError) throw error;
|
|
43
|
-
};
|
|
44
|
-
return next();
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
// src/schemas/index.ts
|
|
48
|
-
import { z } from "zod";
|
|
49
|
-
var safeUrlSchema = z.string().refine((url) => url.startsWith("http://") || url.startsWith("https://"), {
|
|
50
|
-
message: "URL must start with http:// or https://"
|
|
51
|
-
});
|
|
52
|
-
var jsonSchema7Schema = z.custom(
|
|
53
|
-
(val) => typeof val === "object" && val !== null,
|
|
54
|
-
{ message: "Must be a valid JSON Schema object" }
|
|
55
|
-
);
|
|
56
|
-
var uiSchemaSchema = z.custom((val) => typeof val === "object" && val !== null, {
|
|
57
|
-
message: "Must be a valid UiSchema object"
|
|
58
|
-
});
|
|
59
|
-
var webhookHandlerSchema = z.object({
|
|
60
|
-
type: z.literal("webhook"),
|
|
61
|
-
url: safeUrlSchema,
|
|
62
|
-
headers: z.record(z.string())
|
|
63
|
-
});
|
|
64
|
-
var triggerHandlerSchema = webhookHandlerSchema.extend({
|
|
65
|
-
type: z.literal("trigger"),
|
|
66
|
-
tokenId: z.string().min(1)
|
|
67
|
-
});
|
|
68
|
-
var handlerSchema = z.discriminatedUnion("type", [webhookHandlerSchema, triggerHandlerSchema]);
|
|
69
|
-
var taskActionSchema = z.object({
|
|
70
|
-
id: z.string().min(1),
|
|
71
|
-
title: z.string().min(1),
|
|
72
|
-
description: z.string().optional(),
|
|
73
|
-
schema: jsonSchema7Schema.optional(),
|
|
74
|
-
ui: uiSchemaSchema.optional(),
|
|
75
|
-
data: z.record(z.unknown()).optional(),
|
|
76
|
-
handlers: z.array(handlerSchema).min(1).optional()
|
|
77
|
-
});
|
|
78
|
-
var uiFieldSchemaSchema = z.object({
|
|
79
|
-
"ui:widget": z.string().optional(),
|
|
80
|
-
"ui:title": z.string().optional(),
|
|
81
|
-
"ui:description": z.string().optional(),
|
|
82
|
-
"ui:options": z.record(z.unknown()).optional(),
|
|
83
|
-
items: z.lazy(() => z.record(uiFieldSchemaSchema)).optional()
|
|
84
|
-
}).passthrough();
|
|
85
|
-
var contextUiSchema = z.record(uiFieldSchemaSchema).optional();
|
|
86
|
-
var contextDataSchema = z.object({
|
|
87
|
-
data: z.record(z.unknown()),
|
|
88
|
-
ui: contextUiSchema
|
|
89
|
-
}).optional();
|
|
90
|
-
var taskContextSchema = z.object({
|
|
91
|
-
app: z.string().min(1).optional(),
|
|
92
|
-
type: z.string().min(1),
|
|
93
|
-
name: z.string().min(1),
|
|
94
|
-
description: z.string().optional(),
|
|
95
|
-
validUntil: z.string().optional(),
|
|
96
|
-
context: contextDataSchema,
|
|
97
|
-
version: z.literal(2).optional(),
|
|
98
|
-
actions: z.array(taskActionSchema).min(1, "At least one action is required")
|
|
99
|
-
});
|
|
100
|
-
var assignToSchema = z.object({
|
|
101
|
-
users: z.array(z.string().email()).optional(),
|
|
102
|
-
groups: z.array(z.string().min(1)).optional()
|
|
103
|
-
}).refine(
|
|
104
|
-
(data) => {
|
|
105
|
-
const groups = data.groups ?? [];
|
|
106
|
-
if (groups.includes("all") && groups.length > 1) {
|
|
107
|
-
return false;
|
|
108
|
-
}
|
|
109
|
-
return true;
|
|
110
|
-
},
|
|
111
|
-
{ message: 'Cannot combine "all" with other group slugs' }
|
|
112
|
-
);
|
|
113
|
-
var threadUpdateMessageSchema = z.string().min(1).max(500);
|
|
114
|
-
var threadUpdateStatuses = [
|
|
115
|
-
"info",
|
|
116
|
-
"queued",
|
|
117
|
-
"running",
|
|
118
|
-
"waiting",
|
|
119
|
-
"succeeded",
|
|
120
|
-
"failed",
|
|
121
|
-
"cancelled"
|
|
122
|
-
];
|
|
123
|
-
var threadUpdateStatusSchema = z.enum(threadUpdateStatuses);
|
|
124
|
-
var DEFAULT_THREAD_UPDATE_STATUS = "info";
|
|
125
|
-
var threadUpdateInputSchema = z.object({
|
|
126
|
-
message: threadUpdateMessageSchema,
|
|
127
|
-
status: threadUpdateStatusSchema.optional()
|
|
128
|
-
});
|
|
129
|
-
var createTaskBodySchema = taskContextSchema.extend({
|
|
130
|
-
assignTo: assignToSchema.optional(),
|
|
131
|
-
/**
|
|
132
|
-
* Groups related tasks together. When omitted, the server generates one and
|
|
133
|
-
* returns it so the caller can reuse it on later tasks in the same thread.
|
|
134
|
-
*/
|
|
135
|
-
threadId: z.string().min(1).optional(),
|
|
136
|
-
/**
|
|
137
|
-
* Optional initial status update logged against the task's thread. Shows in
|
|
138
|
-
* the inbox status bar and the thread update log.
|
|
139
|
-
*/
|
|
140
|
-
update: threadUpdateInputSchema.optional()
|
|
141
|
-
});
|
|
142
|
-
var threadUpdateBodySchema = threadUpdateInputSchema;
|
|
143
|
-
|
|
144
|
-
export {
|
|
145
|
-
__using,
|
|
146
|
-
__callDispose,
|
|
147
|
-
taskContextSchema,
|
|
148
|
-
assignToSchema,
|
|
149
|
-
threadUpdateMessageSchema,
|
|
150
|
-
threadUpdateStatuses,
|
|
151
|
-
threadUpdateStatusSchema,
|
|
152
|
-
DEFAULT_THREAD_UPDATE_STATUS,
|
|
153
|
-
threadUpdateInputSchema,
|
|
154
|
-
createTaskBodySchema,
|
|
155
|
-
threadUpdateBodySchema
|
|
156
|
-
};
|
|
157
|
-
//# sourceMappingURL=chunk-2KFY7ZJV.js.map
|