build(deps): bump zod from 3.25.76 to 4.4.3 (#11719)

Bumps [zod](https://github.com/colinhacks/zod) from 3.25.76 to 4.4.3.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/colinhacks/zod/releases">zod's
releases</a>.</em></p>
<blockquote>
<h2>v4.4.3</h2>
<h2>Commits:</h2>
<ul>
<li>4c2fa95ce3f3390fbc522324e406b4e9e89b88f9 docs: use Zernio primary
wordmark for gold sponsor logo</li>
<li>2aeec83eb135e3a83756e973ef44845fc5a455d2 docs: prune lapsed gold
sponsors and rebalance logo sizing</li>
<li>7391be88ac1ee5cd02057f5ccc012a1f5df4efd0 docs: prune lapsed
silver/bronze sponsors and add active ones</li>
<li>2c703322a21b4e2b12f33f49ea8430c451a68b4f docs: normalize bronze
sponsor logos to github avatar pattern</li>
<li>9195250cab0e7950efe39c3926d6c203b4b0a170 docs: remove Mintlify from
bronze sponsors (churned)</li>
<li>b8dffe9e62f17e6571e6249d05cc5102b54d94e4 docs: remove Numeric and
Speakeasy (2+ missed monthly cycles)</li>
<li>1cab69383fcdeae2a366d5e2a2fc4d8fc765d168 fix(v4): restore catch
handling for absent object keys (<a
href="https://redirect.github.com/colinhacks/zod/issues/5937">#5937</a>)
(<a
href="https://redirect.github.com/colinhacks/zod/issues/5939">#5939</a>)</li>
<li>c2be4f819064eed62c7c350a2d399b5faecd15f8 fix(v4): generalize
optin/fallback to transform; restore preprocess on absent keys (<a
href="https://redirect.github.com/colinhacks/zod/issues/5941">#5941</a>)</li>
<li>f3c9ec03ba7a28ae72d25cc295f38674bee0f559 4.4.3</li>
<li>1fb56a5c18c27102dbc92260a4007c7732a0ccca docs: document release
procedure in AGENTS.md</li>
</ul>
<h2>v4.4.2</h2>
<h2>Commits:</h2>
<ul>
<li>0c62df0ea19fd05abdf90473e9eef7eea530fab2 Clean up docs navigation
and stale labels (<a
href="https://redirect.github.com/colinhacks/zod/issues/5901">#5901</a>)</li>
<li>20cc794895cc8604fe0c87d83a5d1c3f89fad0ac chore: add security policy
and refresh tooling deps</li>
<li>6fbe07b0177efdd1bf1c0b05160e70d7a0702337 fix(docs): heading anchor
links now include the hash so it doesnt scoll all the way up, follows
navbar logic (<a
href="https://redirect.github.com/colinhacks/zod/issues/5791">#5791</a>)</li>
<li>4bbed1b1c73eca4ce9e59b1189ed236aa6c8b5bd Tighten discriminated union
option typing</li>
<li>bbac3e567e7fccfaaf7cdc97f1ce30c295e2c908 Update PR guidance for
agents</li>
<li>cf0dc942a32805c292fff59ade20a7ace980735a Merge remote-tracking
branch 'origin/main' into fix-discriminated-union-key-constraint</li>
<li>292c894a5fd2aa42e527900b83d8d7a3009a709c docs: add Zernio gold
sponsor</li>
<li>1fc9f311c28dcf80d0bb5a36b177086cbc3d8eca docs: document codec
inversion</li>
<li>1373c85da9aeff704a9762d27bc58699618aefb7 docs: remove AI disclosure
guidance</li>
<li>e20d02b473c08e3a4e557bc610b1b5fac079b649 chore: ignore triage
notes</li>
<li>e58ea4d91b1dfe8194b73508203213cbc7e9c936 docs: test Zod Mini tab
code heights</li>
<li>905761a5d127e8d5dd2ebb3bc88c75cb0b8149ff docs: document preprocess
input type narrowing</li>
<li>bf64bac850d4dee2b7dde7e64909d5d796d32043 chore: tighten test
guidance in AGENTS.md</li>
<li>8ec4e73f4c4693b6361ad591be40fb41eb8a9f95 chore: update play.ts
scratch</li>
<li>02c2baf7d0d615872fa4528a8020603b71211702 Make z.preprocess defer
optionality to inner schema (<a
href="https://redirect.github.com/colinhacks/zod/issues/5929">#5929</a>)</li>
<li>88015df8e25c44fb5385eb3ef28935119cd5edea fix(docs): drop deprecated
<code>baseUrl</code> from tsconfig</li>
<li>c59d4474e3b4cad1b323462186cf607178ce8267 4.4.2</li>
</ul>
<h2>v4.4.1</h2>
<h2>Commits:</h2>
<ul>
<li>481f7be4238c83ed58183f921b2646f340a91c6a ci: gate release publishing
on full test workflow</li>
<li>95ccab423aec720b2523c3a64cdc7e3204537cc7 test(v3): restore optional
undefined expectations</li>
<li>cede2c63739a5823d6aa5093d291e9a111da943d fix(v4): reject tuple holes
before required defaults (<a
href="https://redirect.github.com/colinhacks/zod/issues/5900">#5900</a>)</li>
<li>edd0bf0f5ada4a8dc581c259407d7bbad0a71ea7 release: 4.4.1</li>
<li>180d83d1dbe6a59260710cc8637a3dea2281ee56 docs: remove Jazz featured
sponsor</li>
</ul>
<h2>v4.4.0</h2>
<h2>4.4.0</h2>
<p>This is a minor release with a wide set of correctness and soundness
fixes. Some fixes intentionally make Zod stricter, so code that depended
on previously accepted invalid or ambiguous inputs may need small
updates.</p>
<h2>Potentially breaking bug fixes</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="1fb56a5c18"><code>1fb56a5</code></a>
docs: document release procedure in AGENTS.md</li>
<li><a
href="f3c9ec03ba"><code>f3c9ec0</code></a>
4.4.3</li>
<li><a
href="c2be4f8190"><code>c2be4f8</code></a>
fix(v4): generalize optin/fallback to transform; restore preprocess on
absent...</li>
<li><a
href="1cab69383f"><code>1cab693</code></a>
fix(v4): restore catch handling for absent object keys (<a
href="https://redirect.github.com/colinhacks/zod/issues/5937">#5937</a>)
(<a
href="https://redirect.github.com/colinhacks/zod/issues/5939">#5939</a>)</li>
<li><a
href="b8dffe9e62"><code>b8dffe9</code></a>
docs: remove Numeric and Speakeasy (2+ missed monthly cycles)</li>
<li><a
href="9195250cab"><code>9195250</code></a>
docs: remove Mintlify from bronze sponsors (churned)</li>
<li><a
href="2c703322a2"><code>2c70332</code></a>
docs: normalize bronze sponsor logos to github avatar pattern</li>
<li><a
href="7391be88ac"><code>7391be8</code></a>
docs: prune lapsed silver/bronze sponsors and add active ones</li>
<li><a
href="2aeec83eb1"><code>2aeec83</code></a>
docs: prune lapsed gold sponsors and rebalance logo sizing</li>
<li><a
href="4c2fa95ce3"><code>4c2fa95</code></a>
docs: use Zernio primary wordmark for gold sponsor logo</li>
<li>Additional commits viewable in <a
href="https://github.com/colinhacks/zod/compare/v3.25.76...v4.4.3">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new
releaser for zod since your current version.</p>
</details>
<br />

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Priya Raman <priya@paperclip.ing>
Co-authored-by: Paperclip <noreply@paperclip.ing>
This commit is contained in:
dependabot[bot] 2026-08-21 00:04:14 -07:00 committed by GitHub
parent 773a9dade6
commit 3abe9e2134
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
63 changed files with 889 additions and 752 deletions

View File

@ -47,7 +47,7 @@
"dependencies": {
"@modelcontextprotocol/sdk": "^1.30.0",
"googleapis": "^174.0.1",
"zod": "^3.24.2"
"zod": "^4.4.3"
},
"devDependencies": {
"@types/node": "^22.20.1",

View File

@ -7,7 +7,7 @@ export type ToolResult = CallToolResult;
export interface GoogleSheetsToolDefinition {
name: string;
description: string;
schema: z.AnyZodObject;
schema: z.ZodObject;
annotations: ToolAnnotations;
execute: (input: Record<string, unknown>) => Promise<ToolResult>;
}
@ -84,7 +84,7 @@ function formatTextResponse(value: unknown): ToolResult {
}
function errorMessage(error: unknown): string {
if (error instanceof z.ZodError) return error.errors.map((entry) => entry.message).join("; ");
if (error instanceof z.ZodError) return error.issues.map((entry) => entry.message).join("; ");
if (error instanceof Error) return error.message;
return String(error);
}

View File

@ -45,7 +45,7 @@
},
"dependencies": {
"@modelcontextprotocol/sdk": "^1.30.0",
"zod": "^3.24.2"
"zod": "^4.4.3"
},
"devDependencies": {
"@types/node": "^22.20.1",

View File

@ -7,7 +7,7 @@ export type ToolResult = CallToolResult;
export interface KvToolDefinition {
name: string;
description: string;
schema: z.AnyZodObject;
schema: z.ZodObject;
annotations: ToolAnnotations;
execute: (input: Record<string, unknown>) => Promise<ToolResult>;
}
@ -50,7 +50,7 @@ function formatTextResponse(value: unknown): ToolResult {
}
function errorMessage(error: unknown): string {
if (error instanceof z.ZodError) return error.errors.map((entry) => entry.message).join("; ");
if (error instanceof z.ZodError) return error.issues.map((entry) => entry.message).join("; ");
if (error instanceof Error) return error.message;
return String(error);
}

View File

@ -45,7 +45,7 @@
"dependencies": {
"@modelcontextprotocol/sdk": "^1.30.0",
"@paperclipai/shared": "workspace:*",
"zod": "^3.24.2"
"zod": "^4.4.3"
},
"devDependencies": {
"@types/node": "^22.20.1",

View File

@ -19,7 +19,7 @@ import { formatErrorResponse, formatTextResponse } from "./format.js";
export interface ToolDefinition {
name: string;
description: string;
schema: z.AnyZodObject;
schema: z.ZodObject;
execute: (input: Record<string, unknown>) => Promise<{
content: Array<{ type: "text"; text: string }>;
}>;
@ -51,26 +51,26 @@ function parseOptionalJson(raw: string | undefined | null): unknown {
return JSON.parse(raw);
}
const companyIdOptional = z.string().uuid().optional().nullable();
const agentIdOptional = z.string().uuid().optional().nullable();
const companyIdOptional = z.string().guid().optional().nullable();
const agentIdOptional = z.string().guid().optional().nullable();
const issueIdSchema = z.string().min(1);
const projectIdSchema = z.string().min(1);
const goalIdSchema = z.string().uuid();
const approvalIdSchema = z.string().uuid();
const goalIdSchema = z.string().guid();
const approvalIdSchema = z.string().guid();
const documentKeySchema = z.string().trim().min(1).max(64);
const listIssuesSchema = z.object({
companyId: companyIdOptional,
status: z.string().optional(),
projectId: z.string().uuid().optional(),
assigneeAgentId: z.string().uuid().optional(),
participantAgentId: z.string().uuid().optional(),
projectId: z.string().guid().optional(),
assigneeAgentId: z.string().guid().optional(),
participantAgentId: z.string().guid().optional(),
assigneeUserId: z.string().optional(),
touchedByUserId: z.string().optional(),
inboxArchivedByUserId: z.string().optional(),
unreadForUserId: z.string().optional(),
labelId: z.string().uuid().optional(),
executionWorkspaceId: z.string().uuid().optional(),
labelId: z.string().guid().optional(),
executionWorkspaceId: z.string().guid().optional(),
originKind: z.string().optional(),
originId: z.string().optional(),
includeRoutineExecutions: z.boolean().optional(),
@ -80,7 +80,7 @@ const listIssuesSchema = z.object({
const listCommentsSchema = z.object({
issueId: issueIdSchema,
after: z.string().uuid().optional(),
after: z.string().guid().optional(),
order: z.enum(["asc", "desc"]).optional(),
limit: z.number().int().positive().max(500).optional(),
});
@ -92,7 +92,7 @@ const upsertDocumentToolSchema = z.object({
format: z.enum(["markdown"]).default("markdown"),
body: z.string().max(524288),
changeSummary: z.string().trim().max(500).nullable().optional(),
baseRevisionId: z.string().uuid().nullable().optional(),
baseRevisionId: z.string().guid().nullable().optional(),
});
const createIssueToolSchema = z.object({
@ -116,8 +116,8 @@ const addCommentToolSchema = z.object({
const createSuggestTasksToolSchema = z.object({
issueId: issueIdSchema,
idempotencyKey: z.string().trim().max(255).nullable().optional(),
sourceCommentId: z.string().uuid().nullable().optional(),
sourceRunId: z.string().uuid().nullable().optional(),
sourceCommentId: z.string().guid().nullable().optional(),
sourceRunId: z.string().guid().nullable().optional(),
title: z.string().trim().max(240).nullable().optional(),
summary: z.string().trim().max(1000).nullable().optional(),
continuationPolicy: issueThreadInteractionContinuationPolicySchema.optional().default("wake_assignee"),
@ -127,8 +127,8 @@ const createSuggestTasksToolSchema = z.object({
const createAskUserQuestionsToolSchema = z.object({
issueId: issueIdSchema,
idempotencyKey: z.string().trim().max(255).nullable().optional(),
sourceCommentId: z.string().uuid().nullable().optional(),
sourceRunId: z.string().uuid().nullable().optional(),
sourceCommentId: z.string().guid().nullable().optional(),
sourceRunId: z.string().guid().nullable().optional(),
title: z.string().trim().max(240).nullable().optional(),
summary: z.string().trim().max(1000).nullable().optional(),
continuationPolicy: issueThreadInteractionContinuationPolicySchema.optional().default("wake_assignee"),
@ -138,8 +138,8 @@ const createAskUserQuestionsToolSchema = z.object({
const createRequestConfirmationToolSchema = z.object({
issueId: issueIdSchema,
idempotencyKey: z.string().trim().max(255).nullable().optional(),
sourceCommentId: z.string().uuid().nullable().optional(),
sourceRunId: z.string().uuid().nullable().optional(),
sourceCommentId: z.string().guid().nullable().optional(),
sourceRunId: z.string().guid().nullable().optional(),
title: z.string().trim().max(240).nullable().optional(),
summary: z.string().trim().max(1000).nullable().optional(),
continuationPolicy: issueThreadInteractionContinuationPolicySchema.optional().default("none"),
@ -149,8 +149,8 @@ const createRequestConfirmationToolSchema = z.object({
const createRequestCheckboxConfirmationToolSchema = z.object({
issueId: issueIdSchema,
idempotencyKey: z.string().trim().max(255).nullable().optional(),
sourceCommentId: z.string().uuid().nullable().optional(),
sourceRunId: z.string().uuid().nullable().optional(),
sourceCommentId: z.string().guid().nullable().optional(),
sourceRunId: z.string().guid().nullable().optional(),
title: z.string().trim().max(240).nullable().optional(),
summary: z.string().trim().max(1000).nullable().optional(),
continuationPolicy: issueThreadInteractionContinuationPolicySchema.optional().default("wake_assignee"),
@ -176,7 +176,7 @@ const apiRequestSchema = z.object({
const workspaceRuntimeControlTargetSchema = z.object({
workspaceCommandId: z.string().min(1).optional().nullable(),
runtimeServiceId: z.string().uuid().optional().nullable(),
runtimeServiceId: z.string().guid().optional().nullable(),
serviceIndex: z.number().int().nonnegative().optional().nullable(),
});
@ -187,7 +187,7 @@ const issueWorkspaceRuntimeControlSchema = z.object({
const waitForIssueWorkspaceServiceSchema = z.object({
issueId: issueIdSchema,
runtimeServiceId: z.string().uuid().optional().nullable(),
runtimeServiceId: z.string().guid().optional().nullable(),
serviceName: z.string().min(1).optional().nullable(),
timeoutSeconds: z.number().int().positive().max(300).optional(),
});
@ -287,7 +287,7 @@ export function createToolDefinitions(client: PaperclipApiClient): ToolDefinitio
makeTool(
"paperclipGetHeartbeatContext",
"Get compact heartbeat context for an issue",
z.object({ issueId: issueIdSchema, wakeCommentId: z.string().uuid().optional() }),
z.object({ issueId: issueIdSchema, wakeCommentId: z.string().guid().optional() }),
async ({ issueId, wakeCommentId }) => {
const qs = wakeCommentId ? `?wakeCommentId=${encodeURIComponent(wakeCommentId)}` : "";
return client.requestJson("GET", `/issues/${encodeURIComponent(issueId)}/heartbeat-context${qs}`);
@ -309,7 +309,7 @@ export function createToolDefinitions(client: PaperclipApiClient): ToolDefinitio
makeTool(
"paperclipGetComment",
"Get a specific issue comment by id",
z.object({ issueId: issueIdSchema, commentId: z.string().uuid() }),
z.object({ issueId: issueIdSchema, commentId: z.string().guid() }),
async ({ issueId, commentId }) =>
client.requestJson("GET", `/issues/${encodeURIComponent(issueId)}/comments/${encodeURIComponent(commentId)}`),
),
@ -558,7 +558,7 @@ export function createToolDefinitions(client: PaperclipApiClient): ToolDefinitio
z.object({
issueId: issueIdSchema,
key: documentKeySchema,
revisionId: z.string().uuid(),
revisionId: z.string().guid(),
}),
async ({ issueId, key, revisionId }) =>
client.requestJson(

View File

@ -109,7 +109,7 @@
},
"dependencies": {
"@paperclipai/shared": "workspace:*",
"zod": "^3.24.2"
"zod": "^4.4.3"
},
"devDependencies": {
"@types/node": "^22.20.1",

View File

@ -45,7 +45,7 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"zod": "^3.24.2"
"zod": "^4.4.3"
},
"devDependencies": {
"@types/node": "^22.20.1",

View File

@ -101,11 +101,11 @@ export const secretsConfigSchema = z.object({
export const telemetryConfigSchema = z.object({
enabled: z.boolean().default(true),
}).passthrough().default({});
}).passthrough().prefault({});
export const updatesConfigSchema = z.object({
checkEnabled: z.boolean().default(true),
}).passthrough().default({});
}).passthrough().prefault({});
export const paperclipConfigSchema = z
.object({
@ -210,18 +210,14 @@ function isRecord(value: unknown): value is Record<string, unknown> {
}
function unwrapConfigSchema(schema: z.ZodTypeAny): z.ZodTypeAny {
let current = schema;
let current: z.ZodTypeAny = schema;
while (true) {
if (current instanceof z.ZodEffects) {
current = current.innerType();
continue;
}
if (current instanceof z.ZodOptional) {
current = current.unwrap();
current = current.unwrap() as z.ZodTypeAny;
continue;
}
if (current instanceof z.ZodDefault) {
current = current.removeDefault();
current = current.unwrap() as z.ZodTypeAny;
continue;
}
return current;

View File

@ -44,7 +44,7 @@ const skillMetadataValueSchema: z.ZodType<unknown> = z.lazy(() =>
z.boolean(),
z.null(),
z.array(skillMetadataValueSchema),
z.record(skillMetadataValueSchema),
z.record(z.string(), skillMetadataValueSchema),
])
);
@ -52,7 +52,7 @@ export const skillFrontmatterSchema = z.object({
name: z.string().regex(SKILL_FRONTMATTER_SLUG_RE, "Expected a lowercase URL slug."),
description: z.string().min(1),
"allowed-tools": z.array(z.string()).optional(),
metadata: z.record(skillMetadataValueSchema).optional(),
metadata: z.record(z.string(), skillMetadataValueSchema).optional(),
}).passthrough();
export const skillFrontmatterKnownKeys = [

View File

@ -74,7 +74,7 @@ export const createCliAuthChallengeSchema = z.object({
command: z.string().min(1).max(240),
clientName: z.string().max(120).optional().nullable(),
requestedAccess: boardCliAuthAccessLevelSchema.default("board"),
requestedCompanyId: z.string().uuid().optional().nullable(),
requestedCompanyId: z.string().guid().optional().nullable(),
});
export type CreateCliAuthChallenge = z.infer<typeof createCliAuthChallengeSchema>;
@ -88,7 +88,7 @@ export type ResolveCliAuthChallenge = z.infer<typeof resolveCliAuthChallengeSche
export const createBoardApiKeySchema = z.object({
name: z.string().trim().min(1).max(120).default("paperclipai cli"),
expiresAt: z.coerce.date().optional().nullable(),
requestedCompanyId: z.string().uuid().optional().nullable(),
requestedCompanyId: z.string().guid().optional().nullable(),
});
export type CreateBoardApiKey = z.infer<typeof createBoardApiKeySchema>;
@ -128,8 +128,8 @@ export type UpdateCompanyMemberWithPermissions = z.infer<typeof updateCompanyMem
export const archiveCompanyMemberSchema = z.object({
reassignment: z
.object({
assigneeAgentId: z.string().uuid().optional().nullable(),
assigneeUserId: z.string().uuid().optional().nullable(),
assigneeAgentId: z.string().guid().optional().nullable(),
assigneeUserId: z.string().guid().optional().nullable(),
})
.optional()
.nullable(),
@ -146,7 +146,7 @@ export const archiveCompanyMemberSchema = z.object({
export type ArchiveCompanyMember = z.infer<typeof archiveCompanyMemberSchema>;
export const updateUserCompanyAccessSchema = z.object({
companyIds: z.array(z.string().uuid()).default([]),
companyIds: z.array(z.string().guid()).default([]),
});
export type UpdateUserCompanyAccess = z.infer<typeof updateUserCompanyAccessSchema>;

View File

@ -18,8 +18,8 @@ export type AdapterAuthSessionFailure = z.infer<typeof adapterAuthSessionFailure
// The public response schema. `.strict()` rejects an extra field, so a prompt, a
// token, an account identifier, or a provider lease identifier never validates.
export const adapterAuthSessionResponseSchema = z.object({
sessionId: z.string().uuid(),
environmentId: z.string().uuid(),
sessionId: z.string().guid(),
environmentId: z.string().guid(),
status: adapterAuthSessionStatusSchema,
expiresAt: isoDateTime.nullable(),
failure: adapterAuthSessionFailureSchema.nullable(),
@ -40,7 +40,7 @@ export type AdapterAuthSessionOwnerResponse =
z.infer<typeof adapterAuthSessionOwnerResponseSchema>;
export const startAdapterAuthSessionRequestSchema = z.object({
environmentId: z.string().uuid(),
environmentId: z.string().guid(),
adapterType: z.enum(AGENT_ADAPTER_TYPES),
ttlSeconds: z.number().int().min(60).max(24 * 60 * 60).optional(),
}).strict();

View File

@ -8,7 +8,7 @@ export const adapterRegistryEntrySchema = z
envKeys: z.array(z.string()).optional(),
allowFqdns: z.array(z.string()).optional(),
probeCommand: z.array(z.string()).optional(),
defaultEnv: z.record(z.string()).optional(),
defaultEnv: z.record(z.string(), z.string()).optional(),
})
.strict();

View File

@ -29,7 +29,7 @@ export const agentSkillAssignmentModeSchema = z.enum([
export const agentDesiredSkillEntrySchema = z.object({
key: z.string().min(1),
versionId: z.string().uuid().nullable(),
versionId: z.string().guid().nullable(),
});
export const agentDesiredSkillSelectionSchema = z.union([
@ -40,8 +40,8 @@ export const agentDesiredSkillSelectionSchema = z.union([
export const agentSkillEntrySchema = z.object({
key: z.string().min(1),
runtimeName: z.string().min(1).nullable(),
versionId: z.string().uuid().nullable().optional(),
currentVersionId: z.string().uuid().nullable().optional(),
versionId: z.string().guid().nullable().optional(),
currentVersionId: z.string().guid().nullable().optional(),
desired: z.boolean(),
managed: z.boolean(),
state: agentSkillStateSchema,

View File

@ -9,6 +9,7 @@ import { agentAdapterTypeSchema } from "../adapter-type.js";
import { envConfigSchema } from "./secret.js";
import { trustAuthorizationPolicySchema, trustPresetSchema } from "./trust-policy.js";
import { agentDesiredSkillSelectionSchema } from "./adapter-skills.js";
import { objectWithoutDefaults } from "./partial.js";
export const agentPermissionsSchema = z.object({
canCreateAgents: z.boolean().optional().default(false),
@ -73,14 +74,14 @@ export const createAgentSchema = z.object({
role: z.enum(AGENT_ROLES).optional().default("general"),
title: z.string().optional().nullable(),
icon: z.enum(AGENT_ICON_NAMES).optional().nullable(),
reportsTo: z.string().uuid().optional().nullable(),
reportsTo: z.string().guid().optional().nullable(),
capabilities: z.string().optional().nullable(),
desiredSkills: z.array(agentDesiredSkillSelectionSchema).optional(),
adapterType: agentAdapterTypeSchema,
adapterConfig: adapterConfigSchema.optional().default({}),
instructionsBundle: createAgentInstructionsBundleSchema.optional(),
runtimeConfig: agentRuntimeConfigSchema.optional().default({}),
defaultEnvironmentId: z.string().uuid().optional().nullable(),
defaultEnvironmentId: z.string().guid().optional().nullable(),
budgetMonthlyCents: z.number().int().nonnegative().optional().default(0),
permissions: agentPermissionsSchema.optional(),
metadata: z.record(z.string(), z.unknown()).optional().nullable(),
@ -116,14 +117,15 @@ export const builtInAgentResetSchema = z.object({
export type BuiltInAgentReset = z.infer<typeof builtInAgentResetSchema>;
export const createAgentHireSchema = createAgentSchema.extend({
sourceIssueId: z.string().uuid().optional().nullable(),
sourceIssueIds: z.array(z.string().uuid()).optional(),
sourceIssueId: z.string().guid().optional().nullable(),
sourceIssueIds: z.array(z.string().guid()).optional(),
});
export type CreateAgentHire = z.infer<typeof createAgentHireSchema>;
export const updateAgentSchema = createAgentSchema
.omit({ permissions: true })
export const updateAgentSchema = objectWithoutDefaults(
createAgentSchema.omit({ permissions: true }),
)
.partial()
.extend({
permissions: z.never().optional(),
@ -143,11 +145,11 @@ export type UpdateAgentInstructionsPath = z.infer<typeof updateAgentInstructions
export const taskBridgeAgentKeyScopeSchema = z.object({
kind: z.literal("task_bridge"),
projectId: z.string().uuid().optional().nullable(),
projectIds: z.array(z.string().uuid()).max(50).optional(),
parentIssueId: z.string().uuid().optional().nullable(),
parentIssueIds: z.array(z.string().uuid()).max(50).optional(),
allowedAssigneeAgentIds: z.array(z.string().uuid()).max(50).optional(),
projectId: z.string().guid().optional().nullable(),
projectIds: z.array(z.string().guid()).max(50).optional(),
parentIssueId: z.string().guid().optional().nullable(),
parentIssueIds: z.array(z.string().guid()).max(50).optional(),
allowedAssigneeAgentIds: z.array(z.string().guid()).max(50).optional(),
}).strict().superRefine((value, ctx) => {
const hasProjectBoundary = Boolean(value.projectId) || Boolean(value.projectIds?.length);
const hasParentBoundary = Boolean(value.parentIssueId) || Boolean(value.parentIssueIds?.length);
@ -166,7 +168,7 @@ export const standardAgentKeyScopeSchema = z.object({
export const skillTestAgentKeyScopeSchema = z.object({
kind: z.literal("skill_test"),
issueId: z.string().uuid(),
issueId: z.string().guid(),
}).strict();
export const agentApiKeyScopeSchema = z.union([
@ -226,7 +228,7 @@ export const testAdapterEnvironmentSchema = z.object({
* environment is non-local (SSH/sandbox), the test probes are executed
* inside that environment so the result reflects real agent execution.
*/
environmentId: z.string().uuid().optional().nullable(),
environmentId: z.string().guid().optional().nullable(),
});
export type TestAdapterEnvironment = z.infer<typeof testAdapterEnvironmentSchema>;

View File

@ -4,9 +4,9 @@ import { multilineTextSchema } from "./text.js";
export const createApprovalSchema = z.object({
type: z.enum(APPROVAL_TYPES),
requestedByAgentId: z.string().uuid().optional().nullable(),
requestedByAgentId: z.string().guid().optional().nullable(),
payload: z.record(z.string(), z.unknown()),
issueIds: z.array(z.string().uuid()).optional(),
issueIds: z.array(z.string().guid()).optional(),
});
export type CreateApproval = z.infer<typeof createApprovalSchema>;

View File

@ -12,10 +12,10 @@ export const companyArtifactGroupBySchema = z.enum(["none", "task", "parent_task
export const companyArtifactsQuerySchema = z.object({
kind: z.enum(["image", "video", "text", "document", "file", "all"]).optional().default("all"),
projectId: z.string().uuid().optional(),
projectId: z.string().guid().optional(),
q: z.string().trim().max(COMPANY_ARTIFACTS_MAX_QUERY_LENGTH).optional(),
groupBy: companyArtifactGroupBySchema.optional().default("none"),
groupIssueId: z.string().uuid().optional(),
groupIssueId: z.string().guid().optional(),
starred: z.preprocess(
(value) => value === "true" ? true : value === "false" ? false : value,
z.boolean(),
@ -41,16 +41,16 @@ export const companyArtifactSchema = z.object({
openPath: z.string().nullable(),
downloadPath: z.string().nullable(),
issue: z.object({
id: z.string().uuid(),
id: z.string().guid(),
identifier: z.string(),
title: z.string(),
}),
project: z.object({
id: z.string().uuid(),
id: z.string().guid(),
name: z.string(),
}).nullable(),
createdByAgent: z.object({
id: z.string().uuid(),
id: z.string().guid(),
name: z.string(),
}).nullable(),
updatedAt: z.string().datetime(),
@ -61,7 +61,7 @@ export const companyArtifactGroupSchema = z.object({
id: z.string().min(1),
groupBy: companyArtifactGroupBySchema.exclude(["none"]),
issue: z.object({
id: z.string().uuid(),
id: z.string().guid(),
identifier: z.string(),
title: z.string(),
}),

View File

@ -8,7 +8,7 @@ import {
export const upsertBudgetPolicySchema = z.object({
scopeType: z.enum(BUDGET_SCOPE_TYPES),
scopeId: z.string().uuid(),
scopeId: z.string().guid(),
metric: z.enum(BUDGET_METRICS).optional().default("billed_cents"),
windowKind: z.enum(BUDGET_WINDOW_KINDS).optional().default("calendar_month_utc"),
amount: z.number().int().nonnegative(),

View File

@ -22,7 +22,7 @@ export type SetupTokenTransportAdvisory = z.infer<typeof setupTokenTransportAdvi
// still derives the owner and the definition; this body carries no owner. A
// missing capture starts a first-write login instead.
export const claudeSetupTokenOverwriteSchema = z.object({
expectedSecretId: z.string().uuid(),
expectedSecretId: z.string().guid(),
expectedLatestVersion: z.number().int().min(1),
}).strict();
export type ClaudeSetupTokenOverwrite =
@ -43,7 +43,7 @@ export type ClaudeSetupTokenOverwrite =
// runtime does not support a caller-supplied session length, so the schema
// exposes no `ttlSeconds` field; a legacy `ttlSeconds` fails the strict parse.
export const startClaudeSetupTokenSessionRequestSchema = z.object({
environmentId: z.string().uuid(),
environmentId: z.string().guid(),
adapterType: z.enum(AGENT_ADAPTER_TYPES),
overwrite: claudeSetupTokenOverwriteSchema.optional(),
}).strict();
@ -63,7 +63,7 @@ const sessionIdSchema = z.string().min(1).max(256);
// identifier never validates.
export const claudeSetupTokenSessionResponseSchema = z.object({
sessionId: sessionIdSchema,
environmentId: z.string().uuid(),
environmentId: z.string().guid(),
status: adapterAuthSessionStatusSchema,
expiresAt: isoDateTime.nullable(),
failure: adapterAuthSessionFailureSchema.nullable(),
@ -163,7 +163,7 @@ export type ClaudeSetupTokenCompletionResponse =
// route returns a fixed 404 for a missing or a foreign value, so a 200 body
// always describes a present owner value.
export const claudeOAuthTokenStatusResponseSchema = z.object({
secretId: z.string().uuid(),
secretId: z.string().guid(),
latestVersion: z.number().int().min(1),
}).strict();
export type ClaudeOAuthTokenStatusResponse =

View File

@ -236,7 +236,7 @@ export const portabilityManifestSchema = z.object({
generatedAt: z.string().datetime(),
source: z
.object({
companyId: z.string().uuid(),
companyId: z.string().guid(),
companyName: z.string().min(1),
})
.nullable(),
@ -283,7 +283,7 @@ export const portabilityTargetSchema = z.discriminatedUnion("mode", [
}),
z.object({
mode: z.literal("existing_company"),
companyId: z.string().uuid(),
companyId: z.string().guid(),
}),
]);

View File

@ -18,9 +18,9 @@ export const companySkillVersionFileInventoryEntrySchema = companySkillFileInven
});
export const companySkillSchema = z.object({
id: z.string().uuid(),
companyId: z.string().uuid(),
folderId: z.string().uuid().nullable().optional(),
id: z.string().guid(),
companyId: z.string().guid(),
folderId: z.string().guid().nullable().optional(),
folderPath: z.string().nullable().optional(),
key: z.string().min(1),
slug: z.string().min(1),
@ -41,12 +41,12 @@ export const companySkillSchema = z.object({
categories: z.array(z.string().min(1)).default([]),
sharingScope: companySkillSharingScopeSchema,
publicShareToken: z.string().nullable(),
forkedFromSkillId: z.string().uuid().nullable(),
forkedFromCompanyId: z.string().uuid().nullable(),
forkedFromSkillId: z.string().guid().nullable(),
forkedFromCompanyId: z.string().guid().nullable(),
starCount: z.number().int().nonnegative(),
installCount: z.number().int().nonnegative(),
forkCount: z.number().int().nonnegative(),
currentVersionId: z.string().uuid().nullable(),
currentVersionId: z.string().guid().nullable(),
metadata: z.record(z.string(), z.unknown()).nullable(),
createdAt: z.coerce.date(),
updatedAt: z.coerce.date(),
@ -71,7 +71,7 @@ export const companySkillListItemSchema = companySkillSchema.extend({
});
export const companySkillUsageAgentSchema = z.object({
id: z.string().uuid(),
id: z.string().guid(),
name: z.string().min(1),
urlKey: z.string().min(1),
adapterType: z.string().min(1),
@ -79,11 +79,11 @@ export const companySkillUsageAgentSchema = z.object({
actualState: z.string().nullable().describe(
"Runtime adapter skill state when explicitly fetched; company skill detail reads return null without probing agent runtimes.",
),
versionId: z.string().uuid().nullable(),
versionId: z.string().guid().nullable(),
});
export const companySkillOriginalSummarySchema = z.object({
id: z.string().uuid(),
id: z.string().guid(),
name: z.string().min(1),
slug: z.string().min(1),
sourceType: companySkillSourceTypeSchema,
@ -93,9 +93,9 @@ export const companySkillOriginalSummarySchema = z.object({
export const companySkillForkSummarySchema = companySkillOriginalSummarySchema.extend({
key: z.string().min(1),
forkedFromSkillId: z.string().uuid().nullable(),
forkedFromCompanyId: z.string().uuid().nullable(),
currentVersionId: z.string().uuid().nullable(),
forkedFromSkillId: z.string().guid().nullable(),
forkedFromCompanyId: z.string().guid().nullable(),
currentVersionId: z.string().guid().nullable(),
createdByCurrentActor: z.boolean(),
diverged: z.boolean(),
createdAt: z.coerce.date(),
@ -108,7 +108,7 @@ export const companySkillListQuerySchema = z.object({
categories: z.array(z.string().min(1)).optional(),
scope: companySkillSharingScopeSchema.optional(),
include: z.array(companySkillListIncludeSchema).optional(),
folderId: z.string().uuid().optional(),
folderId: z.string().guid().optional(),
includeSubtree: z.boolean().optional(),
});
@ -118,13 +118,13 @@ export const companySkillCategoryCountSchema = z.object({
});
export const companySkillVersionSchema = z.object({
id: z.string().uuid(),
companyId: z.string().uuid(),
companySkillId: z.string().uuid(),
id: z.string().guid(),
companyId: z.string().guid(),
companySkillId: z.string().guid(),
revisionNumber: z.number().int().positive(),
label: z.string().nullable(),
fileInventory: z.array(companySkillVersionFileInventoryEntrySchema).default([]),
authorAgentId: z.string().uuid().nullable(),
authorAgentId: z.string().guid().nullable(),
authorUserId: z.string().nullable(),
createdAt: z.coerce.date(),
});
@ -146,17 +146,17 @@ export const companySkillVersionCreateSchema = z.object({
}).default({});
export const companySkillStarResultSchema = z.object({
skillId: z.string().uuid(),
skillId: z.string().guid(),
starred: z.boolean(),
starCount: z.number().int().nonnegative(),
});
export const companySkillCommentSchema = z.object({
id: z.string().uuid(),
companyId: z.string().uuid(),
companySkillId: z.string().uuid(),
parentCommentId: z.string().uuid().nullable(),
authorAgentId: z.string().uuid().nullable(),
id: z.string().guid(),
companyId: z.string().guid(),
companySkillId: z.string().guid(),
parentCommentId: z.string().guid().nullable(),
authorAgentId: z.string().guid().nullable(),
authorUserId: z.string().nullable(),
body: z.string(),
deletedAt: z.coerce.date().nullable(),
@ -166,7 +166,7 @@ export const companySkillCommentSchema = z.object({
export const companySkillCommentCreateSchema = z.object({
body: z.string().min(1),
parentCommentId: z.string().uuid().nullable().optional(),
parentCommentId: z.string().guid().nullable().optional(),
});
export const companySkillCommentUpdateSchema = z.object({
@ -177,11 +177,11 @@ export const companySkillForkSchema = z.object({
name: z.string().min(1).nullable().optional(),
slug: z.string().min(1).nullable().optional(),
sharingScope: companySkillSharingScopeSchema.optional(),
reassignAgentIds: z.array(z.string().uuid()).optional(),
reassignAgentIds: z.array(z.string().guid()).optional(),
}).default({});
export const companySkillForkReassignmentSchema = z.object({
agentId: z.string().uuid(),
agentId: z.string().guid(),
previousSkillKey: z.string().min(1),
nextSkillKey: z.string().min(1),
});
@ -193,7 +193,7 @@ export const companySkillForkResultSchema = z.object({
});
export const companySkillForkPrecheckResultSchema = z.object({
skillId: z.string().uuid(),
skillId: z.string().guid(),
original: companySkillOriginalSummarySchema,
agentUsageCount: z.number().int().nonnegative(),
usedByAgents: z.array(companySkillUsageAgentSchema),
@ -253,7 +253,7 @@ export const companySkillAuditFindingSchema = z.object({
});
export const companySkillAuditResultSchema = z.object({
skillId: z.string().uuid(),
skillId: z.string().guid(),
installedHash: z.string().nullable(),
originHash: z.string().nullable(),
verdict: z.enum(["pass", "warning", "fail"]),
@ -276,19 +276,19 @@ export const companySkillImportSchema = z.object({
});
export const companySkillProjectScanRequestSchema = z.object({
projectIds: z.array(z.string().uuid()).optional(),
workspaceIds: z.array(z.string().uuid()).optional(),
projectIds: z.array(z.string().guid()).optional(),
workspaceIds: z.array(z.string().guid()).optional(),
mode: z.enum(["import", "preview"]).optional(),
selection: z.array(z.object({
workspaceId: z.string().uuid(),
workspaceId: z.string().guid(),
path: z.string().min(1),
slug: z.string().min(1).optional(),
})).optional(),
});
export const companySkillProjectBrowseRequestSchema = z.object({
projectId: z.string().uuid(),
workspaceId: z.string().uuid(),
projectId: z.string().guid(),
workspaceId: z.string().guid(),
path: z.string().nullable().optional(),
});
@ -300,8 +300,8 @@ export const companySkillProjectBrowseEntrySchema = z.object({
});
export const companySkillProjectBrowseResultSchema = z.object({
projectId: z.string().uuid(),
workspaceId: z.string().uuid(),
projectId: z.string().guid(),
workspaceId: z.string().guid(),
workspaceName: z.string().min(1),
path: z.string().min(1),
parentPath: z.string().nullable(),
@ -313,21 +313,21 @@ export const companySkillProjectScanCandidateSchema = z.object({
slug: z.string().min(1),
name: z.string().min(1),
description: z.string().nullable(),
workspaceId: z.string().uuid(),
workspaceId: z.string().guid(),
workspaceName: z.string().min(1),
projectId: z.string().uuid(),
projectId: z.string().guid(),
projectName: z.string().min(1),
directoryRoot: z.string().min(1),
relativePath: z.string().min(1),
status: z.enum(["new", "already_imported", "conflict", "skipped"]),
existingSkillId: z.string().uuid().optional(),
existingSkillId: z.string().guid().optional(),
reason: z.string().min(1).optional(),
});
export const companySkillProjectScanSkippedSchema = z.object({
projectId: z.string().uuid().nullable(),
projectId: z.string().guid().nullable(),
projectName: z.string().min(1).nullable(),
workspaceId: z.string().uuid().nullable(),
workspaceId: z.string().guid().nullable(),
workspaceName: z.string().nullable(),
path: z.string().nullable(),
reason: z.string().min(1),
@ -336,12 +336,12 @@ export const companySkillProjectScanSkippedSchema = z.object({
export const companySkillProjectScanConflictSchema = z.object({
slug: z.string().min(1),
key: z.string().min(1),
projectId: z.string().uuid(),
projectId: z.string().guid(),
projectName: z.string().min(1),
workspaceId: z.string().uuid(),
workspaceId: z.string().guid(),
workspaceName: z.string().min(1),
path: z.string().min(1),
existingSkillId: z.string().uuid(),
existingSkillId: z.string().guid(),
existingSkillKey: z.string().min(1),
existingSourceLocator: z.string().nullable(),
reason: z.string().min(1),
@ -360,7 +360,7 @@ export const companySkillProjectScanResultSchema = z.object({
});
export const companySkillCreateSchema = z.object({
folderId: z.string().uuid().nullable().optional(),
folderId: z.string().guid().nullable().optional(),
name: z.string().min(1),
slug: z.string().min(1).nullable().optional(),
description: z.string().nullable().optional(),
@ -372,11 +372,11 @@ export const companySkillCreateSchema = z.object({
homepageUrl: z.string().nullable().optional(),
categories: z.array(z.string().min(1)).optional(),
sharingScope: companySkillSharingScopeSchema.optional(),
forkedFromSkillId: z.string().uuid().nullable().optional(),
forkedFromSkillId: z.string().guid().nullable().optional(),
});
export const companySkillFileDetailSchema = z.object({
skillId: z.string().uuid(),
skillId: z.string().guid(),
path: z.string().min(1),
kind: z.enum(["skill", "markdown", "reference", "script", "asset", "other"]),
content: z.string(),
@ -398,9 +398,9 @@ export const companySkillFileDeleteSchema = z.object({
export const companySkillTestRunStatusSchema = z.enum(["queued", "running", "succeeded", "failed", "cancelled"]);
export const companySkillTestInputSchema = z.object({
id: z.string().uuid(),
companyId: z.string().uuid(),
skillId: z.string().uuid(),
id: z.string().guid(),
companyId: z.string().guid(),
skillId: z.string().guid(),
name: z.string().min(1),
content: z.string(),
createdBy: z.string().nullable(),
@ -423,14 +423,14 @@ export const companySkillTestInputUpdateSchema = z.object({
export const companySkillTestRunTemplateSchema = z.object({
id: z.string().min(1),
companyId: z.string().uuid(),
companyId: z.string().guid(),
name: z.string().min(1),
description: z.string().nullable(),
body: z.string().min(1),
builtIn: z.boolean(),
createdByAgentId: z.string().uuid().nullable(),
createdByAgentId: z.string().guid().nullable(),
createdByUserId: z.string().nullable(),
updatedByAgentId: z.string().uuid().nullable(),
updatedByAgentId: z.string().guid().nullable(),
updatedByUserId: z.string().nullable(),
deletedAt: z.coerce.date().nullable(),
createdAt: z.coerce.date(),
@ -471,15 +471,15 @@ export const companySkillTestRunCostSummarySchema = z.object({
});
export const companySkillTestRunSchema = z.object({
id: z.string().uuid(),
companyId: z.string().uuid(),
skillId: z.string().uuid(),
inputId: z.string().uuid().nullable(),
id: z.string().guid(),
companyId: z.string().guid(),
skillId: z.string().guid(),
inputId: z.string().guid().nullable(),
inputSnapshot: z.string(),
skillVersionId: z.string().uuid(),
agentId: z.string().uuid(),
skillVersionId: z.string().guid(),
agentId: z.string().guid(),
agentConfigSnapshot: z.record(z.string(), z.unknown()),
issueId: z.string().uuid(),
issueId: z.string().guid(),
templateId: z.string().nullable(),
templateName: z.string().nullable(),
templateBody: z.string().nullable(),
@ -500,20 +500,20 @@ export const companySkillTestRunSchema = z.object({
});
export const companySkillTestRunCreateSchema = z.object({
inputId: z.string().uuid().nullable().optional(),
inputId: z.string().guid().nullable().optional(),
content: z.string().min(1).nullable().optional(),
agentId: z.string().uuid(),
agentId: z.string().guid(),
templateId: z.string().min(1).nullable().optional(),
templateSnapshot: companySkillTestRunTemplateSnapshotSchema.nullable().optional(),
// Re-run pins the viewed run's skill version instead of the live head, so the
// new run reproduces the same snapshots (golden-path step 5).
skillVersionId: z.string().uuid().nullable().optional(),
skillVersionId: z.string().guid().nullable().optional(),
}).refine((value) => Boolean(value.inputId) || Boolean(value.content?.trim()), {
message: "inputId or content is required",
});
export const companySkillTestRunListQuerySchema = z.object({
inputId: z.string().uuid().optional(),
inputId: z.string().guid().optional(),
});
export const catalogSkillKindSchema = z.enum(["bundled", "optional"]);

View File

@ -4,8 +4,9 @@ import {
ISSUE_THREAD_INTERACTION_RESOLVER_POLICIES,
MAX_COMPANY_ATTACHMENT_MAX_BYTES,
} from "../constants.js";
import { objectWithoutDefaults } from "./partial.js";
const logoAssetIdSchema = z.string().uuid().nullable().optional();
const logoAssetIdSchema = z.string().guid().nullable().optional();
const brandColorSchema = z.string().regex(/^#[0-9a-fA-F]{6}$/).nullable().optional();
const feedbackDataSharingTermsVersionSchema = z.string().min(1).nullable().optional();
const attachmentMaxBytesSchema = z
@ -37,21 +38,23 @@ export const createCompanySchema = z.object({
export type CreateCompany = z.infer<typeof createCompanySchema>;
export const updateCompanySchema = createCompanySchema
.partial()
.extend({
status: z.enum(COMPANY_STATUSES).optional(),
spentMonthlyCents: z.number().int().nonnegative().optional(),
requireBoardApprovalForNewAgents: z.boolean().optional(),
interactionResolverGovernance: interactionResolverGovernanceSchema.optional(),
feedbackDataSharingEnabled: z.boolean().optional(),
feedbackDataSharingConsentAt: z.coerce.date().nullable().optional(),
feedbackDataSharingConsentByUserId: z.string().min(1).nullable().optional(),
feedbackDataSharingTermsVersion: feedbackDataSharingTermsVersionSchema,
brandColor: brandColorSchema,
logoAssetId: logoAssetIdSchema,
attachmentMaxBytes: attachmentMaxBytesSchema.optional(),
});
export const updateCompanySchema = objectWithoutDefaults(
createCompanySchema
.partial()
.extend({
status: z.enum(COMPANY_STATUSES).optional(),
spentMonthlyCents: z.number().int().nonnegative().optional(),
requireBoardApprovalForNewAgents: z.boolean().optional(),
interactionResolverGovernance: interactionResolverGovernanceSchema.optional(),
feedbackDataSharingEnabled: z.boolean().optional(),
feedbackDataSharingConsentAt: z.coerce.date().nullable().optional(),
feedbackDataSharingConsentByUserId: z.string().min(1).nullable().optional(),
feedbackDataSharingTermsVersion: feedbackDataSharingTermsVersionSchema,
brandColor: brandColorSchema,
logoAssetId: logoAssetIdSchema,
attachmentMaxBytes: attachmentMaxBytesSchema.optional(),
}),
);
export type UpdateCompany = z.infer<typeof updateCompanySchema>;

View File

@ -2,11 +2,11 @@ import { z } from "zod";
import { BILLING_TYPES, COST_STATUSES } from "../constants.js";
export const createCostEventSchema = z.object({
agentId: z.string().uuid(),
issueId: z.string().uuid().optional().nullable(),
projectId: z.string().uuid().optional().nullable(),
goalId: z.string().uuid().optional().nullable(),
heartbeatRunId: z.string().uuid().optional().nullable(),
agentId: z.string().guid(),
issueId: z.string().guid().optional().nullable(),
projectId: z.string().guid().optional().nullable(),
goalId: z.string().guid().optional().nullable(),
heartbeatRunId: z.string().guid().optional().nullable(),
billingCode: z.string().optional().nullable(),
provider: z.string().min(1),
biller: z.string().min(1).optional(),

View File

@ -5,7 +5,7 @@ export const decisionEffectStalenessSchema = z.enum(["strict", "lenient"]);
export const decisionOptionStyleSchema = z.enum(["default", "primary", "destructive"]);
const decisionEffectBaseShape = {
targetIssueId: z.string().uuid(),
targetIssueId: z.string().guid(),
staleness: decisionEffectStalenessSchema,
};
@ -21,12 +21,12 @@ export const createIssueDecisionEffectSchema = z.object({
draft: z.object({
title: z.string().trim().min(1).max(500),
description: z.string().max(100_000).nullable().optional(),
parentId: z.string().uuid().nullable().optional(),
assigneeAgentId: z.string().uuid().nullable().optional(),
parentId: z.string().guid().nullable().optional(),
assigneeAgentId: z.string().guid().nullable().optional(),
assigneeUserId: z.string().trim().min(1).nullable().optional(),
projectId: z.string().uuid().nullable().optional(),
goalId: z.string().uuid().nullable().optional(),
blockedByIssueIds: z.array(z.string().uuid()).max(100).optional(),
projectId: z.string().guid().nullable().optional(),
goalId: z.string().guid().nullable().optional(),
blockedByIssueIds: z.array(z.string().guid()).max(100).optional(),
}),
});
@ -40,14 +40,14 @@ export const updateIssueStatusDecisionEffectSchema = z.object({
export const assignIssueDecisionEffectSchema = z.object({
type: z.literal("assign_issue"),
...decisionEffectBaseShape,
assigneeAgentId: z.string().uuid().nullable().optional(),
assigneeAgentId: z.string().guid().nullable().optional(),
assigneeUserId: z.string().trim().min(1).nullable().optional(),
comment: z.string().trim().min(1).max(20_000).nullable().optional(),
});
export const cancelIssueTreeDecisionEffectSchema = z.object({
type: z.literal("cancel_issue_tree"),
targetIssueId: z.string().uuid(),
targetIssueId: z.string().guid(),
staleness: z.literal("strict"),
reasonComment: z.string().trim().min(1).max(20_000),
});
@ -55,7 +55,7 @@ export const cancelIssueTreeDecisionEffectSchema = z.object({
export const resolveBlockerDecisionEffectSchema = z.object({
type: z.literal("resolve_blocker"),
...decisionEffectBaseShape,
removeBlockedByIssueIds: z.array(z.string().uuid()).min(1).max(100),
removeBlockedByIssueIds: z.array(z.string().guid()).min(1).max(100),
});
export const decisionEffectSchema = z.discriminatedUnion("type", [

View File

@ -44,16 +44,16 @@ export const documentAnnotationAnchorSelectorSchema = z.object({
}).strict();
export const createDocumentAnnotationThreadSchema = z.object({
baseRevisionId: z.string().uuid(),
baseRevisionId: z.string().guid(),
baseRevisionNumber: z.number().int().positive(),
selector: documentAnnotationAnchorSelectorSchema,
body: multilineTextSchema.pipe(z.string().min(1).max(20_000)),
issueCommentId: z.string().uuid().nullable().optional(),
issueCommentId: z.string().guid().nullable().optional(),
}).strict();
export const createDocumentAnnotationCommentSchema = z.object({
body: multilineTextSchema.pipe(z.string().min(1).max(20_000)),
issueCommentId: z.string().uuid().nullable().optional(),
issueCommentId: z.string().guid().nullable().optional(),
}).strict();
export const updateDocumentAnnotationThreadSchema = z.object({

View File

@ -31,8 +31,8 @@ export type EnvironmentCustomImageSetupConnectionSummary =
z.infer<typeof environmentCustomImageSetupConnectionSummarySchema>;
export const environmentCustomImageTemplateSchema = z.object({
id: z.string().uuid(),
environmentId: z.string().uuid(),
id: z.string().guid(),
environmentId: z.string().guid(),
provider: providerKeySchema,
templateKind: environmentCustomImageTemplateKindSchema,
templateRef: z.string().min(1).nullable(),
@ -40,10 +40,10 @@ export const environmentCustomImageTemplateSchema = z.object({
sourceEnvironmentConfigFingerprint: z.string().min(1).nullable(),
status: environmentCustomImageTemplateStatusSchema,
createdByUserId: z.string().min(1).nullable(),
createdByAgentId: z.string().uuid().nullable(),
createdByAgentId: z.string().guid().nullable(),
capturedAt: isoDateTime.nullable(),
lastUsedAt: isoDateTime.nullable(),
supersededByTemplateId: z.string().uuid().nullable(),
supersededByTemplateId: z.string().guid().nullable(),
metadata: optionalRecordSchema,
createdAt: isoDateTime,
updatedAt: isoDateTime,
@ -52,16 +52,16 @@ export type EnvironmentCustomImageTemplate =
z.infer<typeof environmentCustomImageTemplateSchema>;
export const environmentCustomImageSetupSessionSchema = z.object({
id: z.string().uuid(),
environmentId: z.string().uuid(),
templateId: z.string().uuid().nullable(),
promotedTemplateId: z.string().uuid().nullable(),
id: z.string().guid(),
environmentId: z.string().guid(),
templateId: z.string().guid().nullable(),
promotedTemplateId: z.string().guid().nullable(),
provider: providerKeySchema,
providerLeaseId: z.string().min(1).nullable(),
environmentLeaseId: z.string().uuid().nullable(),
environmentLeaseId: z.string().guid().nullable(),
status: environmentCustomImageSetupSessionStatusSchema,
startedByUserId: z.string().min(1).nullable(),
startedByAgentId: z.string().uuid().nullable(),
startedByAgentId: z.string().guid().nullable(),
baseTemplateRef: z.string().min(1).nullable(),
expiresAt: isoDateTime.nullable(),
finishedAt: isoDateTime.nullable(),
@ -76,7 +76,7 @@ export type EnvironmentCustomImageSetupSession =
z.infer<typeof environmentCustomImageSetupSessionSchema>;
export const startEnvironmentCustomImageSetupSessionSchema = z.object({
templateId: z.string().uuid().optional().nullable(),
templateId: z.string().guid().optional().nullable(),
ttlSeconds: z.number().int().min(60).max(24 * 60 * 60).optional(),
}).strict();
export type StartEnvironmentCustomImageSetupSession =

View File

@ -30,26 +30,26 @@ const workspaceOverviewStatusFilterSchema = z.preprocess((value) => {
}, z.array(executionWorkspaceStatusSchema).optional());
export const workspaceOverviewQuerySchema = z.object({
projectId: z.string().uuid().optional(),
projectId: z.string().guid().optional(),
status: workspaceOverviewStatusFilterSchema,
limit: z.coerce.number().int().min(1).max(WORKSPACE_OVERVIEW_MAX_LIMIT).optional().default(WORKSPACE_OVERVIEW_DEFAULT_LIMIT),
offset: z.coerce.number().int().min(0).optional().default(0),
}).strict();
export const executionWorkspaceConfigSchema = z.object({
environmentId: z.string().uuid().optional().nullable(),
environmentId: z.string().guid().optional().nullable(),
provisionCommand: z.string().optional().nullable(),
runtimeProvisionCommand: z.string().optional().nullable(),
teardownCommand: z.string().optional().nullable(),
cleanupCommand: z.string().optional().nullable(),
workspaceRuntime: z.record(z.string(), z.unknown()).optional().nullable(),
desiredState: z.enum(["running", "stopped", "manual"]).optional().nullable(),
serviceStates: z.record(z.enum(["running", "stopped", "manual"])).optional().nullable(),
serviceStates: z.record(z.string(), z.enum(["running", "stopped", "manual"])).optional().nullable(),
}).strict();
export const workspaceRuntimeControlTargetSchema = z.object({
workspaceCommandId: z.string().min(1).optional().nullable(),
runtimeServiceId: z.string().uuid().optional().nullable(),
runtimeServiceId: z.string().guid().optional().nullable(),
serviceIndex: z.number().int().nonnegative().optional().nullable(),
}).strict();
@ -77,7 +77,7 @@ export const executionWorkspaceCloseActionSchema = z.object({
}).strict();
export const executionWorkspaceCloseLinkedIssueSchema = z.object({
id: z.string().uuid(),
id: z.string().guid(),
identifier: z.string().nullable(),
title: z.string(),
status: z.string(),
@ -101,11 +101,11 @@ export const executionWorkspaceCloseGitReadinessSchema = z.object({
export const workspaceRuntimeServiceSchema = z.object({
id: z.string(),
companyId: z.string().uuid(),
projectId: z.string().uuid().nullable(),
projectWorkspaceId: z.string().uuid().nullable(),
executionWorkspaceId: z.string().uuid().nullable(),
issueId: z.string().uuid().nullable(),
companyId: z.string().guid(),
projectId: z.string().guid().nullable(),
projectWorkspaceId: z.string().guid().nullable(),
executionWorkspaceId: z.string().guid().nullable(),
issueId: z.string().guid().nullable(),
scopeType: z.enum(["project_workspace", "execution_workspace", "run", "agent"]),
scopeId: z.string().nullable(),
serviceName: z.string(),
@ -118,8 +118,8 @@ export const workspaceRuntimeServiceSchema = z.object({
url: z.string().nullable(),
provider: z.enum(["local_process", "adapter_managed"]),
providerRef: z.string().nullable(),
ownerAgentId: z.string().uuid().nullable(),
startedByRunId: z.string().uuid().nullable(),
ownerAgentId: z.string().guid().nullable(),
startedByRunId: z.string().guid().nullable(),
lastUsedAt: z.coerce.date(),
startedAt: z.coerce.date(),
stoppedAt: z.coerce.date().nullable(),
@ -130,7 +130,7 @@ export const workspaceRuntimeServiceSchema = z.object({
updatedAt: z.coerce.date(),
}).strict();
export const executionWorkspaceCloseReadinessSchema = z.object({
workspaceId: z.string().uuid(),
workspaceId: z.string().guid(),
deliveryState: executionWorkspaceDeliveryStateSchema,
state: executionWorkspaceCloseReadinessStateSchema,
blockingReasons: z.array(z.string()),

View File

@ -20,7 +20,7 @@ export const externalObjectCanonicalIdentitySchema = z
scheme: z.enum(["http", "https"]),
host: z.string().trim().min(1),
path: z.string().trim().min(1),
queryParamHashes: z.record(z.string().regex(/^[a-f0-9]{64}$/)).optional(),
queryParamHashes: z.record(z.string(), z.string().regex(/^[a-f0-9]{64}$/)).optional(),
})
.strict();

View File

@ -13,7 +13,7 @@ export const feedbackDataSharingPreferenceSchema = z.enum(FEEDBACK_DATA_SHARING_
export const upsertIssueFeedbackVoteSchema = z.object({
targetType: feedbackTargetTypeSchema,
targetId: z.string().uuid(),
targetId: z.string().guid(),
vote: feedbackVoteValueSchema,
reason: z.string().trim().max(1000).optional(),
allowSharing: z.boolean().optional(),

View File

@ -2,12 +2,12 @@ import { z } from "zod";
import { AGENT_ADAPTER_TYPES, FINANCE_DIRECTIONS, FINANCE_EVENT_KINDS, FINANCE_UNITS } from "../constants.js";
export const createFinanceEventSchema = z.object({
agentId: z.string().uuid().optional().nullable(),
issueId: z.string().uuid().optional().nullable(),
projectId: z.string().uuid().optional().nullable(),
goalId: z.string().uuid().optional().nullable(),
heartbeatRunId: z.string().uuid().optional().nullable(),
costEventId: z.string().uuid().optional().nullable(),
agentId: z.string().guid().optional().nullable(),
issueId: z.string().guid().optional().nullable(),
projectId: z.string().guid().optional().nullable(),
goalId: z.string().guid().optional().nullable(),
heartbeatRunId: z.string().guid().optional().nullable(),
costEventId: z.string().guid().optional().nullable(),
billingCode: z.string().optional().nullable(),
description: z.string().max(500).optional().nullable(),
eventKind: z.enum(FINANCE_EVENT_KINDS),

View File

@ -7,10 +7,10 @@ export const folderSlugSchema = z.string().trim().min(1).max(120).regex(
);
export const folderSchema = z.object({
id: z.string().uuid(),
companyId: z.string().uuid(),
id: z.string().guid(),
companyId: z.string().guid(),
kind: folderKindSchema,
parentId: z.string().uuid().nullable(),
parentId: z.string().guid().nullable(),
name: z.string().min(1),
slug: folderSlugSchema,
systemKey: z.string().nullable(),
@ -35,7 +35,7 @@ export const folderListResultSchema = z.object({
export const createFolderSchema = z.object({
kind: folderKindSchema,
parentId: z.string().uuid().optional().nullable(),
parentId: z.string().guid().optional().nullable(),
name: z.string().trim().min(1).max(120),
slug: folderSlugSchema.optional().nullable(),
color: z.string().trim().min(1).max(80).optional().nullable(),
@ -52,7 +52,7 @@ export const updateFolderSchema = z.object({
});
export const moveFolderSchema = z.object({
parentId: z.string().uuid().optional().nullable(),
parentId: z.string().guid().optional().nullable(),
position: z.number().int().min(0),
});
@ -62,8 +62,8 @@ export const ensureMySkillFolderSchema = z.object({
export const moveFolderItemSchema = z.object({
kind: folderKindSchema,
itemId: z.string().uuid(),
folderId: z.string().uuid().optional().nullable(),
itemId: z.string().guid(),
folderId: z.string().guid().optional().nullable(),
});
export type CreateFolder = z.infer<typeof createFolderSchema>;

View File

@ -1,17 +1,18 @@
import { z } from "zod";
import { GOAL_LEVELS, GOAL_STATUSES } from "../constants.js";
import { objectWithoutDefaults } from "./partial.js";
export const createGoalSchema = z.object({
title: z.string().min(1),
description: z.string().optional().nullable(),
level: z.enum(GOAL_LEVELS).optional().default("task"),
status: z.enum(GOAL_STATUSES).optional().default("planned"),
parentId: z.string().uuid().optional().nullable(),
ownerAgentId: z.string().uuid().optional().nullable(),
parentId: z.string().guid().optional().nullable(),
ownerAgentId: z.string().guid().optional().nullable(),
});
export type CreateGoal = z.infer<typeof createGoalSchema>;
export const updateGoalSchema = createGoalSchema.partial();
export const updateGoalSchema = objectWithoutDefaults(createGoalSchema).partial();
export type UpdateGoal = z.infer<typeof updateGoalSchema>;

View File

@ -4,7 +4,7 @@ export const inboxAgentPolicyModeSchema = z.enum(["open", "allowlist", "disabled
export const updateInboxAgentPolicySchema = z.object({
mode: inboxAgentPolicyModeSchema,
allowedAgentIds: z.array(z.string().uuid()).max(100).default([]),
allowedAgentIds: z.array(z.string().guid()).max(100).default([]),
}).strict().superRefine((value, ctx) => {
if (value.mode !== "allowlist" && value.allowedAgentIds.length > 0) {
ctx.addIssue({

View File

@ -10,6 +10,7 @@ import {
MIN_ISSUE_GRAPH_LIVENESS_AUTO_RECOVERY_LOOKBACK_HOURS,
} from "../types/instance.js";
import { feedbackDataSharingPreferenceSchema } from "./feedback.js";
import { shapeWithoutDefaults } from "./partial.js";
function presetSchema<T extends readonly number[]>(presets: T, label: string) {
return z.number().refine(
@ -36,7 +37,10 @@ export const instanceGeneralSettingsSchema = z.object({
executionMode: z.enum(["kubernetes", "any"]).optional(),
}).strict();
export const patchInstanceGeneralSettingsSchema = instanceGeneralSettingsSchema.partial();
export const patchInstanceGeneralSettingsSchema = z
.object(shapeWithoutDefaults(instanceGeneralSettingsSchema.shape))
.partial()
.strict();
export const instanceExperimentalSettingsSchema = z.object({
enableEnvironments: z.boolean().default(false),
@ -81,11 +85,17 @@ export const instanceExperimentalSettingsSchema = z.object({
.default(DEFAULT_ISSUE_GRAPH_LIVENESS_AUTO_RECOVERY_LOOKBACK_HOURS),
}).strict();
export const patchInstanceExperimentalSettingsSchema = instanceExperimentalSettingsSchema
.omit({
worktreeRunExecutionActivatedAt: true,
worktreeRunExecutionActivationInstanceId: true,
})
export const patchInstanceExperimentalSettingsSchema = z
.object(
shapeWithoutDefaults(
instanceExperimentalSettingsSchema
.omit({
worktreeRunExecutionActivatedAt: true,
worktreeRunExecutionActivationInstanceId: true,
})
.shape,
),
)
.partial()
.strip();
@ -98,11 +108,11 @@ export const managedSettingMetadataSchema = z.object({
// instances every overlaid key is listed in `managedKeys`; self-hosted
// responses omit the field entirely.
export const instanceExperimentalSettingsWithManagedSchema = instanceExperimentalSettingsSchema.extend({
managedKeys: z.record(managedSettingMetadataSchema).optional(),
managedKeys: z.record(z.string(), managedSettingMetadataSchema).optional(),
}).strict();
export const patchInstanceSettingsSchema = z.object({
defaultEnvironmentId: z.string().uuid().nullable().optional(),
defaultEnvironmentId: z.string().guid().nullable().optional(),
}).strict();
export const issueGraphLivenessAutoRecoveryRequestSchema = z.object({
@ -115,17 +125,24 @@ export const issueGraphLivenessAutoRecoveryRequestSchema = z.object({
}).strict();
export type InstanceGeneralSettings = z.infer<typeof instanceGeneralSettingsSchema>;
export type PatchInstanceGeneralSettings = z.infer<typeof patchInstanceGeneralSettingsSchema>;
// The patch schema removes each default so an absent key stays absent. Declare
// the type from the full settings type, so every field keeps its precise type.
export type PatchInstanceGeneralSettings = Partial<InstanceGeneralSettings>;
export type InstanceExperimentalSettings = z.infer<typeof instanceExperimentalSettingsSchema>;
export type PatchInstanceExperimentalSettings = z.infer<typeof patchInstanceExperimentalSettingsSchema>;
export type PatchInstanceExperimentalSettings = Partial<
Omit<
InstanceExperimentalSettings,
"worktreeRunExecutionActivatedAt" | "worktreeRunExecutionActivationInstanceId"
>
>;
export type PatchInstanceSettings = z.infer<typeof patchInstanceSettingsSchema>;
export type IssueGraphLivenessAutoRecoveryRequest = z.infer<
typeof issueGraphLivenessAutoRecoveryRequestSchema
>;
export const instanceSettingsSchema = z.object({
id: z.string().uuid(),
defaultEnvironmentId: z.string().uuid().nullable(),
id: z.string().guid(),
defaultEnvironmentId: z.string().guid().nullable(),
general: instanceGeneralSettingsSchema,
experimental: instanceExperimentalSettingsWithManagedSchema,
createdAt: z.union([z.date(), z.string().datetime()]),

View File

@ -38,6 +38,7 @@ import {
} from "../constants.js";
import { multilineTextSchema } from "./text.js";
import { lowTrustReviewPresetPolicySchema, trustAuthorizationPolicySchema } from "./trust-policy.js";
import { objectWithoutDefaults } from "./partial.js";
export const issueBlockedInboxStateSchema = z.enum([
"needs_attention",
@ -65,12 +66,12 @@ export const issueBlockedInboxReasonSchema = z.enum([
]);
export const issueBlockedInboxIssueRefSchema = z.object({
id: z.string().uuid(),
id: z.string().guid(),
identifier: z.string().nullable(),
title: z.string(),
status: z.enum(ISSUE_STATUSES),
priority: z.enum(ISSUE_PRIORITIES),
assigneeAgentId: z.string().uuid().nullable(),
assigneeAgentId: z.string().guid().nullable(),
assigneeUserId: z.string().nullable(),
}).strict();
@ -82,7 +83,7 @@ export const issueBlockedInboxAttentionSchema = z.object({
stoppedSinceAt: z.string().datetime().nullable(),
owner: z.object({
type: z.enum(["agent", "user", "board", "external", "unknown"]),
agentId: z.string().uuid().nullable(),
agentId: z.string().guid().nullable(),
userId: z.string().nullable(),
label: z.string().nullable(),
}).strict(),
@ -93,8 +94,8 @@ export const issueBlockedInboxAttentionSchema = z.object({
sourceIssue: issueBlockedInboxIssueRefSchema.nullable(),
leafIssue: issueBlockedInboxIssueRefSchema.nullable(),
recoveryIssue: issueBlockedInboxIssueRefSchema.nullable(),
approvalId: z.string().uuid().nullable(),
interactionId: z.string().uuid().nullable(),
approvalId: z.string().guid().nullable(),
interactionId: z.string().guid().nullable(),
sampleIssueIdentifier: z.string().nullable(),
redaction: z.object({
externalDetailsRedacted: z.boolean(),
@ -158,7 +159,7 @@ export const issueExecutionWorkspaceSettingsSchema = z
.object({
mode: z.enum(ISSUE_EXECUTION_WORKSPACE_PREFERENCES).optional(),
sharedWorkspaceConcurrency: z.enum(["auto", "serialize", "allow"]).optional(),
environmentId: z.string().uuid().optional().nullable(),
environmentId: z.string().guid().optional().nullable(),
workspaceStrategy: executionWorkspaceStrategySchema.optional().nullable(),
workspaceRuntime: z.record(z.string(), z.unknown()).optional().nullable(),
networkEgress: z.object({
@ -187,7 +188,7 @@ export const issueAssigneeAdapterOverridesSchema = z
const issueExecutionStagePrincipalBaseSchema = z.object({
type: z.enum(["agent", "user"]),
agentId: z.string().uuid().optional().nullable(),
agentId: z.string().guid().optional().nullable(),
userId: z.string().optional().nullable(),
});
@ -211,7 +212,7 @@ export const issueExecutionStagePrincipalSchema = issueExecutionStagePrincipalBa
});
export const issueExecutionStageParticipantSchema = issueExecutionStagePrincipalBaseSchema.extend({
id: z.string().uuid().optional(),
id: z.string().guid().optional(),
}).superRefine((value, ctx) => {
if (value.type === "agent") {
if (!value.agentId) {
@ -231,7 +232,7 @@ export const issueExecutionStageParticipantSchema = issueExecutionStagePrincipal
});
export const issueExecutionStageSchema = z.object({
id: z.string().uuid().optional(),
id: z.string().guid().optional(),
type: z.enum(ISSUE_EXECUTION_STAGE_TYPES),
approvalsNeeded: z.literal(1).optional().default(1),
participants: z.array(issueExecutionStageParticipantSchema).default([]),
@ -282,31 +283,31 @@ export const issueReviewRequestSchema = z.object({
export const issueExecutionStateSchema = z.object({
status: z.enum(ISSUE_EXECUTION_STATE_STATUSES),
currentStageId: z.string().uuid().nullable(),
currentStageId: z.string().guid().nullable(),
currentStageIndex: z.number().int().nonnegative().nullable(),
currentStageType: z.enum(ISSUE_EXECUTION_STAGE_TYPES).nullable(),
currentParticipant: issueExecutionStagePrincipalSchema.nullable(),
returnAssignee: issueExecutionStagePrincipalSchema.nullable(),
reviewRequest: issueReviewRequestSchema.nullable().optional().default(null),
completedStageIds: z.array(z.string().uuid()).default([]),
lastDecisionId: z.string().uuid().nullable(),
completedStageIds: z.array(z.string().guid()).default([]),
lastDecisionId: z.string().guid().nullable(),
lastDecisionOutcome: z.enum(ISSUE_EXECUTION_DECISION_OUTCOMES).nullable(),
monitor: issueExecutionMonitorStateSchema.optional().nullable(),
changesRequestedCount: z.number().int().nonnegative().optional().default(0),
});
export const issueRecoveryActionReadModelSchema = z.object({
id: z.string().uuid(),
companyId: z.string().uuid(),
sourceIssueId: z.string().uuid(),
recoveryIssueId: z.string().uuid().nullable(),
id: z.string().guid(),
companyId: z.string().guid(),
sourceIssueId: z.string().guid(),
recoveryIssueId: z.string().guid().nullable(),
kind: z.enum(ISSUE_RECOVERY_ACTION_KINDS),
status: z.enum(ISSUE_RECOVERY_ACTION_STATUSES),
ownerType: z.enum(ISSUE_RECOVERY_ACTION_OWNER_TYPES),
ownerAgentId: z.string().uuid().nullable(),
ownerAgentId: z.string().guid().nullable(),
ownerUserId: z.string().nullable(),
previousOwnerAgentId: z.string().uuid().nullable(),
returnOwnerAgentId: z.string().uuid().nullable(),
previousOwnerAgentId: z.string().guid().nullable(),
returnOwnerAgentId: z.string().guid().nullable(),
cause: z.string().min(1),
fingerprint: z.string().min(1),
evidence: z.record(z.string(), z.unknown()),
@ -334,7 +335,7 @@ const RESOLVE_ISSUE_RECOVERY_ACTION_OUTCOMES = [
] as const;
export const resolveIssueRecoveryActionSchema = z.object({
actionId: z.string().uuid().optional(),
actionId: z.string().guid().optional(),
outcome: z.enum(RESOLVE_ISSUE_RECOVERY_ACTION_OUTCOMES),
sourceIssueStatus: z.enum(["todo", "done", "in_review", "blocked"]),
resolutionNote: multilineTextSchema.optional().nullable(),
@ -430,20 +431,20 @@ function withCreateIssueStatusDefault<T extends z.ZodRawShape>(schema: z.ZodObje
}
const createIssueBaseSchema = z.object({
projectId: z.string().uuid().optional().nullable(),
projectWorkspaceId: z.string().uuid().optional().nullable(),
goalId: z.string().uuid().optional().nullable(),
parentId: z.string().uuid().optional().nullable(),
blockedByIssueIds: z.array(z.string().uuid()).optional(),
projectId: z.string().guid().optional().nullable(),
projectWorkspaceId: z.string().guid().optional().nullable(),
goalId: z.string().guid().optional().nullable(),
parentId: z.string().guid().optional().nullable(),
blockedByIssueIds: z.array(z.string().guid()).optional(),
unblockDescriptor: z.object({
owner: z.union([
z.object({ agentId: z.string().uuid() }).strict(),
z.object({ agentId: z.string().guid() }).strict(),
z.object({ userId: z.string().trim().min(1) }).strict(),
z.literal("board"),
]),
action: multilineTextSchema.pipe(z.string().trim().min(1).max(2_000)),
}).strict().optional().nullable(),
inheritExecutionWorkspaceFromIssueId: z.string().uuid().optional().nullable(),
inheritExecutionWorkspaceFromIssueId: z.string().guid().optional().nullable(),
title: z.string().min(1),
description: multilineTextSchema.optional().nullable(),
status: z.enum(ISSUE_STATUSES),
@ -451,7 +452,7 @@ const createIssueBaseSchema = z.object({
harnessKind: z.enum(ISSUE_HARNESS_KINDS).optional().nullable(),
priority: z.enum(ISSUE_PRIORITIES).optional().default("medium"),
reviewPolicy: z.enum(ISSUE_REVIEW_POLICIES).optional().nullable(),
assigneeAgentId: z.string().uuid().optional().nullable(),
assigneeAgentId: z.string().guid().optional().nullable(),
assigneeUserId: z.string().optional().nullable(),
requestDepth: issueRequestDepthInputSchema.optional().default(0),
createdByUserId: z.string().optional().nullable(),
@ -459,16 +460,16 @@ const createIssueBaseSchema = z.object({
billingCode: z.string().optional().nullable(),
assigneeAdapterOverrides: issueAssigneeAdapterOverridesSchema.optional().nullable(),
executionPolicy: issueExecutionPolicySchema.optional().nullable(),
executionWorkspaceId: z.string().uuid().optional().nullable(),
executionWorkspaceId: z.string().guid().optional().nullable(),
executionWorkspacePreference: z.enum(ISSUE_EXECUTION_WORKSPACE_PREFERENCES).optional().nullable(),
executionWorkspaceSettings: issueExecutionWorkspaceSettingsSchema.optional().nullable(),
labelIds: z.array(z.string().uuid()).optional(),
labelIds: z.array(z.string().guid()).optional(),
watchdogDiscovery: z.object({
kind: z.enum(ISSUE_WATCHDOG_DISCOVERY_KINDS),
evidenceMarkdown: multilineTextSchema.optional().nullable(),
}).strict().optional().nullable(),
watchdog: z.object({
agentId: z.string().uuid(),
agentId: z.string().guid(),
instructions: multilineTextSchema.optional().nullable(),
}).strict().optional().nullable(),
});
@ -517,7 +518,7 @@ export const createIssueSchema = withCreateIssueStatusDefault(
export type CreateIssue = z.infer<typeof createIssueSchema>;
export const upsertIssueWatchdogSchema = z.object({
agentId: z.string().uuid(),
agentId: z.string().guid(),
instructions: multilineTextSchema.optional().nullable(),
}).strict();
@ -537,7 +538,7 @@ export const createChildIssueSchema = withCreateIssueStatusDefault(createIssueBa
export type CreateChildIssue = z.infer<typeof createChildIssueSchema>;
export const createAcceptedPlanDecompositionSchema = z.object({
acceptedPlanRevisionId: z.string().uuid(),
acceptedPlanRevisionId: z.string().guid(),
children: z.array(createChildIssueSchema).min(1).max(25),
});
@ -550,16 +551,18 @@ export const createIssueLabelSchema = z.object({
export type CreateIssueLabel = z.infer<typeof createIssueLabelSchema>;
export const updateIssueSchema = createIssueBaseSchema.omit({
createdByUserId: true,
responsibleUserId: true,
watchdog: true,
}).partial().extend({
export const updateIssueSchema = objectWithoutDefaults(
createIssueBaseSchema.omit({
createdByUserId: true,
responsibleUserId: true,
watchdog: true,
}),
).partial().extend({
requestDepth: issueRequestDepthInputSchema.optional(),
assigneeAgentId: z.string().trim().min(1).optional().nullable(),
comment: multilineTextSchema.pipe(z.string().min(1)).optional(),
onBehalfOfUserId: z.string().trim().min(1).optional().nullable(),
reviewInteractionId: z.string().uuid().optional(),
reviewInteractionId: z.string().guid().optional(),
reviewRequest: issueReviewRequestSchema.optional().nullable(),
reopen: z.boolean().optional(),
resume: z.boolean().optional(),
@ -586,7 +589,7 @@ export const stalledReviewDecisionSchema = z.object({
export type StalledReviewDecision = z.infer<typeof stalledReviewDecisionSchema>;
export const checkoutIssueSchema = z.object({
agentId: z.string().uuid(),
agentId: z.string().guid(),
expectedStatuses: z.array(z.enum(ISSUE_STATUSES)).nonempty(),
});
@ -631,21 +634,21 @@ const issueCommentMetadataKeyValueRowSchema = issueCommentMetadataBaseRowSchema.
const issueCommentMetadataIssueLinkRowSchema = issueCommentMetadataBaseRowSchema.extend({
type: z.literal("issue_link"),
issueId: z.string().uuid().nullable().optional(),
issueId: z.string().guid().nullable().optional(),
identifier: z.string().trim().min(1).max(80).nullable().optional(),
title: z.string().trim().min(1).max(240).nullable().optional(),
}).strict();
const issueCommentMetadataAgentLinkRowSchema = issueCommentMetadataBaseRowSchema.extend({
type: z.literal("agent_link"),
agentId: z.string().uuid(),
agentId: z.string().guid(),
name: z.string().trim().min(1).max(160).nullable().optional(),
}).strict();
const issueCommentMetadataRunLinkRowSchema = issueCommentMetadataBaseRowSchema.extend({
type: z.literal("run_link"),
runId: z.string().uuid(),
agentId: z.string().uuid().nullable().optional(),
runId: z.string().guid(),
agentId: z.string().guid().nullable().optional(),
title: z.string().trim().min(1).max(160).nullable().optional(),
}).strict();
@ -673,7 +676,7 @@ export const issueCommentMetadataSectionSchema = z.object({
export const issueCommentMetadataSchema = z.object({
version: z.literal(1),
sourceRunId: z.string().uuid().nullable().optional(),
sourceRunId: z.string().guid().nullable().optional(),
authorizationReason: z.string().trim().min(1).max(160).nullable().optional(),
sections: z.array(issueCommentMetadataSectionSchema).min(1).max(20),
}).strict();
@ -721,15 +724,15 @@ export const issueDocumentKeySchema = z
export const suggestedTaskDraftSchema = z.object({
clientKey: z.string().trim().min(1).max(120),
parentClientKey: z.string().trim().min(1).max(120).nullable().optional(),
parentId: z.string().uuid().nullable().optional(),
parentId: z.string().guid().nullable().optional(),
title: z.string().trim().min(1).max(240),
description: multilineTextSchema.pipe(z.string().trim().max(20000)).nullable().optional(),
priority: z.enum(ISSUE_PRIORITIES).nullable().optional(),
workMode: z.enum(ISSUE_WORK_MODES).nullable().optional(),
assigneeAgentId: z.string().uuid().nullable().optional(),
assigneeAgentId: z.string().guid().nullable().optional(),
assigneeUserId: z.string().trim().min(1).nullable().optional(),
projectId: z.string().uuid().nullable().optional(),
goalId: z.string().uuid().nullable().optional(),
projectId: z.string().guid().nullable().optional(),
goalId: z.string().guid().nullable().optional(),
billingCode: z.string().trim().max(120).nullable().optional(),
labels: z.array(z.string().trim().min(1).max(48)).max(20).optional(),
hiddenInPreview: z.boolean().optional(),
@ -745,7 +748,7 @@ export const suggestedTaskDraftSchema = z.object({
export const suggestTasksPayloadSchema = z.object({
version: z.literal(1),
defaultParentId: z.string().uuid().nullable().optional(),
defaultParentId: z.string().guid().nullable().optional(),
tasks: z.array(suggestedTaskDraftSchema).min(1).max(50),
}).superRefine((value, ctx) => {
const seenClientKeys = new Set<string>();
@ -764,10 +767,10 @@ export const suggestTasksPayloadSchema = z.object({
export const suggestTasksResultCreatedTaskSchema = z.object({
clientKey: z.string().trim().min(1).max(120),
issueId: z.string().uuid(),
issueId: z.string().guid(),
identifier: z.string().trim().min(1).nullable().optional(),
title: z.string().trim().min(1).nullable().optional(),
parentIssueId: z.string().uuid().nullable().optional(),
parentIssueId: z.string().guid().nullable().optional(),
parentIdentifier: z.string().trim().min(1).nullable().optional(),
});
@ -858,10 +861,10 @@ export const askUserQuestionsResultSchema = z.object({
cancelled: z.literal(true).optional(),
cancellationReason: z.string().trim().max(4000).nullable().optional(),
expirationReason: z.enum(["superseded_by_comment", "superseded_by_newer_interaction"]).optional(),
commentId: z.string().uuid().nullable().optional(),
commentId: z.string().guid().nullable().optional(),
// Set alongside expirationReason "superseded_by_newer_interaction": the id of
// the newer sibling ask_user_questions that replaced this one (PAP-437).
supersededByInteractionId: z.string().uuid().nullable().optional(),
supersededByInteractionId: z.string().guid().nullable().optional(),
summaryMarkdown: z.string().max(20000).nullable().optional(),
});
@ -878,10 +881,10 @@ const requestConfirmationTargetBaseSchema = z.object({
export const requestConfirmationIssueDocumentTargetSchema = requestConfirmationTargetBaseSchema.extend({
type: z.literal("issue_document"),
issueId: z.string().uuid().nullable().optional(),
documentId: z.string().uuid().nullable().optional(),
issueId: z.string().guid().nullable().optional(),
documentId: z.string().guid().nullable().optional(),
key: issueDocumentKeySchema,
revisionId: z.string().uuid(),
revisionId: z.string().guid(),
revisionNumber: z.number().int().positive().nullable().optional(),
});
@ -899,12 +902,12 @@ export const requestConfirmationTargetSchema = z.discriminatedUnion("type", [
export const requestConfirmationToolActionPayloadSchema = z.object({
version: z.literal(1),
actionRequestId: z.string().uuid(),
invocationId: z.string().uuid(),
actionRequestId: z.string().guid(),
invocationId: z.string().guid(),
toolName: z.string().trim().min(1).max(500),
toolDisplayName: z.string().trim().min(1).max(500),
connectionId: z.string().uuid().nullable(),
applicationId: z.string().uuid().nullable(),
connectionId: z.string().guid().nullable(),
applicationId: z.string().guid().nullable(),
appDisplayName: z.string().trim().min(1).max(500).nullable(),
risk: z.enum(["write", "destructive"]),
previewMarkdown: z.string().trim().min(1).max(20000),
@ -915,10 +918,10 @@ export const requestConfirmationToolActionPayloadSchema = z.object({
export const requestConfirmationSecretProposalPayloadSchema = z.object({
version: z.literal(1),
proposalId: z.string().uuid(),
proposalId: z.string().guid(),
sourceSecretLabel: z.string().trim().min(1).max(500),
configPath: z.string().trim().min(1).max(500),
targetAgentId: z.string().uuid(),
targetAgentId: z.string().guid(),
targetAgentName: z.string().trim().min(1).max(500),
justification: z.string().trim().min(1).max(20000),
expiresAt: z.string().datetime({ offset: true }),
@ -1045,9 +1048,9 @@ export const requestConfirmationResumeFailureSchema = z.object({
errorCode: z.string().trim().min(1).max(120).nullable(),
attempt: z.number().int().min(0).max(100),
maxAttempts: z.number().int().min(0).max(100),
runId: z.string().uuid().nullable().optional(),
retryRunId: z.string().uuid().nullable().optional(),
recoveryActionId: z.string().uuid().nullable().optional(),
runId: z.string().guid().nullable().optional(),
retryRunId: z.string().guid().nullable().optional(),
recoveryActionId: z.string().guid().nullable().optional(),
updatedAt: z.string().trim().min(1).nullable().optional(),
});
@ -1084,8 +1087,8 @@ export const requestConfirmationResultSchema = z.object({
"addressee_deleted",
]),
reason: z.string().trim().max(4000).nullable().optional(),
commentId: z.string().uuid().nullable().optional(),
supersededByInteractionId: z.string().uuid().nullable().optional(),
commentId: z.string().guid().nullable().optional(),
supersededByInteractionId: z.string().guid().nullable().optional(),
staleTarget: requestConfirmationTargetSchema.nullable().optional(),
resumeFailure: requestConfirmationResumeFailureSchema.nullable().optional(),
toolAction: requestConfirmationToolActionResultSchema.optional(),
@ -1119,7 +1122,7 @@ export const requestItemVerdictsItemSchema = z.object({
description: z.string().trim().max(500).nullable().optional(),
previewMarkdown: z.string().max(20000).nullable().optional(),
href: requestConfirmationHrefSchema.nullable().optional(),
attachmentId: z.string().uuid().nullable().optional(),
attachmentId: z.string().guid().nullable().optional(),
});
export const requestItemVerdictsPayloadSchema = z.object({
@ -1200,10 +1203,10 @@ export const requestItemVerdictsResultItemSchema = z.object({
verdict: requestItemVerdictValueSchema,
reason: z.string().trim().max(4000).nullable().optional(),
resolvedByUserId: z.string().trim().min(1).max(255).nullable().optional(),
resolvedByAgentId: z.string().uuid().nullable().optional(),
resolvedByRunId: z.string().uuid().nullable().optional(),
resolvedByAgentId: z.string().guid().nullable().optional(),
resolvedByRunId: z.string().guid().nullable().optional(),
resolvedAt: z.union([z.string().datetime(), z.date()]),
commentId: z.string().uuid().nullable().optional(),
commentId: z.string().guid().nullable().optional(),
}).superRefine((value, ctx) => {
if (!value.resolvedByUserId && !value.resolvedByAgentId) {
ctx.addIssue({
@ -1228,7 +1231,7 @@ export const requestItemVerdictsResultSchema = z.object({
complete: z.boolean(),
items: z.array(requestItemVerdictsResultItemSchema)
.max(REQUEST_ITEM_VERDICTS_ITEM_LIMIT),
commentId: z.string().uuid().nullable().optional(),
commentId: z.string().guid().nullable().optional(),
staleTarget: requestConfirmationTargetSchema.nullable().optional(),
}).superRefine((value, ctx) => {
const itemIds = new Set<string>();
@ -1246,7 +1249,7 @@ export const requestItemVerdictsResultSchema = z.object({
const createIssueThreadInteractionCommon = {
resolverPolicy: issueThreadInteractionResolverPolicySchema.optional(),
addresseeAgentId: z.string().uuid().nullable().optional(),
addresseeAgentId: z.string().guid().nullable().optional(),
};
export const createIssueThreadInteractionSchema = z.discriminatedUnion("kind", [
@ -1254,8 +1257,8 @@ export const createIssueThreadInteractionSchema = z.discriminatedUnion("kind", [
...createIssueThreadInteractionCommon,
kind: z.literal("suggest_tasks"),
idempotencyKey: z.string().trim().max(255).nullable().optional(),
sourceCommentId: z.string().uuid().nullable().optional(),
sourceRunId: z.string().uuid().nullable().optional(),
sourceCommentId: z.string().guid().nullable().optional(),
sourceRunId: z.string().guid().nullable().optional(),
title: z.string().trim().max(240).nullable().optional(),
summary: z.string().trim().max(1000).nullable().optional(),
continuationPolicy: issueThreadInteractionContinuationPolicySchema.optional().default("wake_assignee"),
@ -1265,8 +1268,8 @@ export const createIssueThreadInteractionSchema = z.discriminatedUnion("kind", [
...createIssueThreadInteractionCommon,
kind: z.literal("ask_user_questions"),
idempotencyKey: z.string().trim().max(255).nullable().optional(),
sourceCommentId: z.string().uuid().nullable().optional(),
sourceRunId: z.string().uuid().nullable().optional(),
sourceCommentId: z.string().guid().nullable().optional(),
sourceRunId: z.string().guid().nullable().optional(),
title: z.string().trim().max(240).nullable().optional(),
summary: z.string().trim().max(1000).nullable().optional(),
continuationPolicy: issueThreadInteractionContinuationPolicySchema.optional().default("wake_assignee"),
@ -1276,8 +1279,8 @@ export const createIssueThreadInteractionSchema = z.discriminatedUnion("kind", [
...createIssueThreadInteractionCommon,
kind: z.literal("request_confirmation"),
idempotencyKey: z.string().trim().max(255).nullable().optional(),
sourceCommentId: z.string().uuid().nullable().optional(),
sourceRunId: z.string().uuid().nullable().optional(),
sourceCommentId: z.string().guid().nullable().optional(),
sourceRunId: z.string().guid().nullable().optional(),
title: z.string().trim().max(240).nullable().optional(),
summary: z.string().trim().max(1000).nullable().optional(),
continuationPolicy: issueThreadInteractionContinuationPolicySchema.optional().default("none"),
@ -1287,8 +1290,8 @@ export const createIssueThreadInteractionSchema = z.discriminatedUnion("kind", [
...createIssueThreadInteractionCommon,
kind: z.literal("request_checkbox_confirmation"),
idempotencyKey: z.string().trim().max(255).nullable().optional(),
sourceCommentId: z.string().uuid().nullable().optional(),
sourceRunId: z.string().uuid().nullable().optional(),
sourceCommentId: z.string().guid().nullable().optional(),
sourceRunId: z.string().guid().nullable().optional(),
title: z.string().trim().max(240).nullable().optional(),
summary: z.string().trim().max(1000).nullable().optional(),
continuationPolicy: issueThreadInteractionContinuationPolicySchema.optional().default("wake_assignee"),
@ -1298,8 +1301,8 @@ export const createIssueThreadInteractionSchema = z.discriminatedUnion("kind", [
...createIssueThreadInteractionCommon,
kind: z.literal("request_item_verdicts"),
idempotencyKey: z.string().trim().max(255).nullable().optional(),
sourceCommentId: z.string().uuid().nullable().optional(),
sourceRunId: z.string().uuid().nullable().optional(),
sourceCommentId: z.string().guid().nullable().optional(),
sourceRunId: z.string().guid().nullable().optional(),
title: z.string().trim().max(240).nullable().optional(),
summary: z.string().trim().max(1000).nullable().optional(),
continuationPolicy: issueThreadInteractionContinuationPolicySchema.optional().default("wake_assignee"),
@ -1388,13 +1391,13 @@ export const submitIssueThreadInteractionVerdictsSchema = z.object({
export type SubmitIssueThreadInteractionVerdicts = z.infer<typeof submitIssueThreadInteractionVerdictsSchema>;
export const linkIssueApprovalSchema = z.object({
approvalId: z.string().uuid(),
approvalId: z.string().guid(),
});
export type LinkIssueApproval = z.infer<typeof linkIssueApprovalSchema>;
export const createIssueAttachmentMetadataSchema = z.object({
issueCommentId: z.string().uuid().optional().nullable(),
issueCommentId: z.string().guid().optional().nullable(),
});
export type CreateIssueAttachmentMetadata = z.infer<typeof createIssueAttachmentMetadataSchema>;
@ -1408,7 +1411,7 @@ export const upsertIssueDocumentSchema = z.object({
format: issueDocumentFormatSchema,
body: multilineTextSchema.pipe(z.string().max(524288)),
changeSummary: z.string().trim().max(500).nullable().optional(),
baseRevisionId: z.string().uuid().nullable().optional(),
baseRevisionId: z.string().guid().nullable().optional(),
});
export const restoreIssueDocumentRevisionSchema = z.object({});

View File

@ -0,0 +1,41 @@
import { z } from "zod";
// Remove each `.default()` wrapper from one field. The wrapper can sit at the
// top, or under an `.optional()` or `.nullable()` wrapper, so this walks the
// chain and keeps the `optional`/`nullable` wrappers. The field then has no
// default at any level of the outer chain.
function fieldWithoutDefault(field: z.ZodTypeAny): z.ZodTypeAny {
if (field instanceof z.ZodDefault) {
return fieldWithoutDefault(field.unwrap() as z.ZodTypeAny);
}
if (field instanceof z.ZodOptional) {
return z.optional(fieldWithoutDefault(field.unwrap() as z.ZodTypeAny));
}
if (field instanceof z.ZodNullable) {
return z.nullable(fieldWithoutDefault(field.unwrap() as z.ZodTypeAny));
}
return field;
}
// Zod 4 keeps a field `.default()` active after `.partial()`. A patch parse then
// fills the default for an absent key. The merge then overwrites a stored value
// that the caller did not send. A patch schema must keep only the keys the
// caller sends. This helper removes each top-level field default from an object
// shape. `.partial()` then leaves an absent key absent.
export function shapeWithoutDefaults(shape: z.ZodRawShape): z.ZodRawShape {
return Object.fromEntries(
Object.entries(shape).map(([key, field]) => [
key,
fieldWithoutDefault(field as z.ZodTypeAny),
]),
);
}
// Build a patch object schema from a base object schema. The result drops each
// top-level `.default()`, so a `.partial()` parse keeps only the keys the caller
// sends. Chain `.partial()` and any `.extend()`/`.refine()` on the result.
export function objectWithoutDefaults<T extends z.ZodRawShape>(
schema: z.ZodObject<T>,
): z.ZodObject<T> {
return z.object(shapeWithoutDefaults(schema.shape)) as unknown as z.ZodObject<T>;
}

View File

@ -24,22 +24,22 @@ export const pipelineStageApproverSchema = z.object({
export const pipelineStageOnEnterSchema = z.object({
type: z.literal("run_routine"),
routineId: z.string().uuid(),
routineId: z.string().guid(),
id: z.string().trim().min(1).max(200).optional(),
projectId: z.string().uuid().optional().nullable(),
projectWorkspaceId: z.string().uuid().optional().nullable(),
executionWorkspaceId: z.string().uuid().optional().nullable(),
projectId: z.string().guid().optional().nullable(),
projectWorkspaceId: z.string().guid().optional().nullable(),
executionWorkspaceId: z.string().guid().optional().nullable(),
executionWorkspacePreference: z.enum(ISSUE_EXECUTION_WORKSPACE_PREFERENCES).optional().nullable(),
executionWorkspaceSettings: issueExecutionWorkspaceSettingsSchema.optional().nullable(),
}).passthrough();
export const pipelineStageAutomationSchema = z.object({
routineId: z.string().uuid().optional().nullable(),
assigneeAgentId: z.string().uuid().optional().nullable(),
routineId: z.string().guid().optional().nullable(),
assigneeAgentId: z.string().guid().optional().nullable(),
instructionsBody: z.string().optional().nullable(),
projectId: z.string().uuid().optional().nullable(),
projectWorkspaceId: z.string().uuid().optional().nullable(),
executionWorkspaceId: z.string().uuid().optional().nullable(),
projectId: z.string().guid().optional().nullable(),
projectWorkspaceId: z.string().guid().optional().nullable(),
executionWorkspaceId: z.string().guid().optional().nullable(),
executionWorkspacePreference: z.enum(ISSUE_EXECUTION_WORKSPACE_PREFERENCES).optional().nullable(),
executionWorkspaceSettings: issueExecutionWorkspaceSettingsSchema.optional().nullable(),
}).passthrough();
@ -52,7 +52,7 @@ export const pipelineStageCarryOverPolicySchema = z.object({
});
export const pipelineStageBreakdownSchema = z.object({
targetPipelineId: z.string().uuid(),
targetPipelineId: z.string().guid(),
targetStageKey: z.string().trim().min(1).max(120),
pieceNoun: z.string().trim().min(1).max(80).default("piece"),
carryOverPolicy: pipelineStageCarryOverPolicySchema.optional(),
@ -137,7 +137,7 @@ export const pipelineAutomationRetryCleanupOptionsSchema = z.object({
export const pipelineAutomationRetryRequestSchema = z.object({
scope: pipelineAutomationRetryScopeSchema,
targetStageId: z.string().uuid().nullable().optional(),
targetStageId: z.string().guid().nullable().optional(),
expectedVersion: z.number().int().positive(),
cleanup: pipelineAutomationRetryCleanupOptionsSchema.default({
retireDirectChildren: true,

View File

@ -251,7 +251,7 @@ export const pluginManagedAgentDeclarationSchema = z.object({
instructions: z.object({
entryFile: z.string().min(1).max(200).optional(),
content: z.string().max(200_000).optional(),
files: z.record(z.string().max(200_000)).optional(),
files: z.record(z.string(), z.string().max(200_000)).optional(),
assetPath: z.string().min(1).max(500).optional(),
}).optional(),
});
@ -287,7 +287,7 @@ export const pluginManagedRoutineDeclarationSchema = z.object({
description: z.string().max(10_000).nullable().optional(),
assigneeRef: pluginManagedResourceRefSchema.extend({ resourceKind: z.literal("agent") }).nullable().optional(),
projectRef: pluginManagedResourceRefSchema.extend({ resourceKind: z.literal("project") }).nullable().optional(),
goalId: z.string().uuid().nullable().optional(),
goalId: z.string().guid().nullable().optional(),
status: z.enum(ROUTINE_STATUSES).optional(),
priority: z.enum(ISSUE_PRIORITIES).optional(),
concurrencyPolicy: z.enum(ROUTINE_CONCURRENCY_POLICIES).optional(),
@ -1200,7 +1200,7 @@ export type InstallPlugin = z.infer<typeof installPluginSchema>;
* the plugin's instanceConfigSchema is done at the service layer.
*/
export const upsertPluginConfigSchema = z.object({
companyId: z.string().uuid(),
companyId: z.string().guid(),
configJson: z.record(z.string(), z.unknown()),
});
@ -1211,7 +1211,7 @@ export type UpsertPluginConfig = z.infer<typeof upsertPluginConfigSchema>;
* Allows a partial merge of config values.
*/
export const patchPluginConfigSchema = z.object({
companyId: z.string().uuid(),
companyId: z.string().guid(),
configJson: z.record(z.string(), z.unknown()),
});

View File

@ -2,6 +2,7 @@ import { z } from "zod";
import { PROJECT_STATUSES, PROJECT_ICON_NAMES } from "../constants.js";
import { envConfigSchema } from "./secret.js";
import { trustAuthorizationPolicySchema } from "./trust-policy.js";
import { objectWithoutDefaults } from "./partial.js";
const executionWorkspaceStrategySchema = z
.object({
@ -21,8 +22,8 @@ export const projectExecutionWorkspacePolicySchema = z
sharedWorkspaceConcurrency: z.enum(["auto", "serialize", "allow"]).optional(),
defaultMode: z.enum(["shared_workspace", "isolated_workspace", "operator_branch", "adapter_default"]).optional(),
allowIssueOverride: z.boolean().optional(),
defaultProjectWorkspaceId: z.string().uuid().optional().nullable(),
environmentId: z.string().uuid().optional().nullable(),
defaultProjectWorkspaceId: z.string().guid().optional().nullable(),
environmentId: z.string().guid().optional().nullable(),
workspaceStrategy: executionWorkspaceStrategySchema.optional().nullable(),
workspaceRuntime: z.record(z.string(), z.unknown()).optional().nullable(),
branchPolicy: z.record(z.string(), z.unknown()).optional().nullable(),
@ -36,7 +37,7 @@ export const projectExecutionWorkspacePolicySchema = z
export const projectWorkspaceRuntimeConfigSchema = z.object({
workspaceRuntime: z.record(z.string(), z.unknown()).optional().nullable(),
desiredState: z.enum(["running", "stopped", "manual"]).optional().nullable(),
serviceStates: z.record(z.enum(["running", "stopped", "manual"])).optional().nullable(),
serviceStates: z.record(z.string(), z.enum(["running", "stopped", "manual"])).optional().nullable(),
}).strict();
const projectWorkspaceSourceTypeSchema = z.enum(["local_path", "git_repo", "remote_managed", "non_git_path"]);
@ -101,12 +102,12 @@ export type UpdateProjectWorkspace = z.infer<typeof updateProjectWorkspaceSchema
const projectFields = {
/** @deprecated Use goalIds instead */
goalId: z.string().uuid().optional().nullable(),
goalIds: z.array(z.string().uuid()).optional(),
goalId: z.string().guid().optional().nullable(),
goalIds: z.array(z.string().guid()).optional(),
name: z.string().min(1),
description: z.string().optional().nullable(),
status: z.enum(PROJECT_STATUSES).optional().default("backlog"),
leadAgentId: z.string().uuid().optional().nullable(),
leadAgentId: z.string().guid().optional().nullable(),
targetDate: z.string().optional().nullable(),
color: z.string().optional().nullable(),
icon: z.enum(PROJECT_ICON_NAMES).optional().nullable(),
@ -122,7 +123,9 @@ export const createProjectSchema = z.object({
export type CreateProject = z.infer<typeof createProjectSchema>;
export const updateProjectSchema = z.object(projectFields).partial();
export const updateProjectSchema = objectWithoutDefaults(
z.object(projectFields),
).partial();
export type UpdateProject = z.infer<typeof updateProjectSchema>;

View File

@ -16,6 +16,7 @@ import {
} from "./issue.js";
import { envConfigSchema } from "./secret.js";
import { isValidRoutineDateString } from "../routine-variables.js";
import { objectWithoutDefaults } from "./partial.js";
const routineVariableValueSchema = z.union([z.string(), z.number().finite(), z.boolean()]);
@ -62,13 +63,13 @@ export const routineVariableSchema = z.object({
});
export const createRoutineSchema = z.object({
projectId: z.string().uuid().optional().nullable(),
folderId: z.string().uuid().optional().nullable(),
goalId: z.string().uuid().optional().nullable(),
parentIssueId: z.string().uuid().optional().nullable(),
projectId: z.string().guid().optional().nullable(),
folderId: z.string().guid().optional().nullable(),
goalId: z.string().guid().optional().nullable(),
parentIssueId: z.string().guid().optional().nullable(),
title: z.string().trim().min(1).max(200),
description: z.string().optional().nullable(),
assigneeAgentId: z.string().uuid().optional().nullable(),
assigneeAgentId: z.string().guid().optional().nullable(),
priority: z.enum(ISSUE_PRIORITIES).optional().default("medium"),
status: z.enum(ROUTINE_STATUSES).optional().default("active"),
concurrencyPolicy: z.enum(ROUTINE_CONCURRENCY_POLICIES).optional().default("coalesce_if_active"),
@ -81,21 +82,21 @@ export const createRoutineSchema = z.object({
export type CreateRoutine = z.infer<typeof createRoutineSchema>;
export const updateRoutineSchema = createRoutineSchema.partial().extend({
baseRevisionId: z.string().uuid().optional().nullable(),
export const updateRoutineSchema = objectWithoutDefaults(createRoutineSchema).partial().extend({
baseRevisionId: z.string().guid().optional().nullable(),
});
export type UpdateRoutine = z.infer<typeof updateRoutineSchema>;
export const routineRevisionSnapshotRoutineV1Schema = z.object({
id: z.string().uuid(),
companyId: z.string().uuid(),
projectId: z.string().uuid().nullable(),
folderId: z.string().uuid().nullable().optional(),
goalId: z.string().uuid().nullable(),
parentIssueId: z.string().uuid().nullable(),
id: z.string().guid(),
companyId: z.string().guid(),
projectId: z.string().guid().nullable(),
folderId: z.string().guid().nullable().optional(),
goalId: z.string().guid().nullable(),
parentIssueId: z.string().guid().nullable(),
title: z.string().trim().min(1).max(200),
description: z.string().nullable(),
assigneeAgentId: z.string().uuid().nullable(),
assigneeAgentId: z.string().guid().nullable(),
priority: z.enum(ISSUE_PRIORITIES),
status: z.enum(ROUTINE_STATUSES),
concurrencyPolicy: z.enum(ROUTINE_CONCURRENCY_POLICIES),
@ -108,7 +109,7 @@ export const routineRevisionSnapshotRoutineV1Schema = z.object({
}).strict();
export const routineRevisionSnapshotTriggerV1Schema = z.object({
id: z.string().uuid(),
id: z.string().guid(),
kind: z.enum(ROUTINE_TRIGGER_KINDS),
label: z.string().nullable(),
enabled: z.boolean(),
@ -164,15 +165,15 @@ export const updateRoutineTriggerSchema = z.object({
export type UpdateRoutineTrigger = z.infer<typeof updateRoutineTriggerSchema>;
export const runRoutineSchema = z.object({
triggerId: z.string().uuid().optional().nullable(),
triggerId: z.string().guid().optional().nullable(),
payload: z.record(z.string(), z.unknown()).optional().nullable(),
variables: z.record(z.string(), routineVariableValueSchema).optional().nullable(),
projectId: z.string().uuid().optional().nullable(),
projectWorkspaceId: z.string().uuid().optional().nullable(),
assigneeAgentId: z.string().uuid().optional().nullable(),
projectId: z.string().guid().optional().nullable(),
projectWorkspaceId: z.string().guid().optional().nullable(),
assigneeAgentId: z.string().guid().optional().nullable(),
idempotencyKey: z.string().trim().max(255).optional().nullable(),
source: z.enum(["manual", "api"]).optional().default("manual"),
executionWorkspaceId: z.string().uuid().optional().nullable(),
executionWorkspaceId: z.string().guid().optional().nullable(),
executionWorkspacePreference: z.enum(ISSUE_EXECUTION_WORKSPACE_PREFERENCES).optional().nullable(),
executionWorkspaceSettings: issueExecutionWorkspaceSettingsSchema.optional().nullable(),
});

View File

@ -19,7 +19,7 @@ export const envBindingPlainSchema = z.object({
export const envBindingSecretRefSchema = z.object({
type: z.literal("secret_ref"),
secretId: z.string().uuid(),
secretId: z.string().guid(),
version: secretVersionSelectorSchema.optional(),
projectionClass: z.enum(SECRET_PROJECTION_CLASSES).optional(),
projectionAllowlistKey: z.string().trim().min(1).max(160).optional().nullable(),
@ -47,7 +47,7 @@ export const createSecretSchema = z.object({
name: z.string().min(1),
key: secretKeySchema.optional(),
provider: z.enum(SECRET_PROVIDERS).optional(),
providerConfigId: z.string().uuid().optional().nullable(),
providerConfigId: z.string().guid().optional().nullable(),
managedMode: z.enum(SECRET_MANAGED_MODES).optional(),
value: z.string().min(1).optional().nullable(),
description: z.string().optional().nullable(),
@ -110,7 +110,7 @@ export const rotateSecretSchema = z.object({
value: z.string().min(1).optional().nullable(),
externalRef: z.string().optional().nullable(),
providerVersionRef: z.string().optional().nullable(),
providerConfigId: z.string().uuid().optional().nullable(),
providerConfigId: z.string().guid().optional().nullable(),
}).superRefine(requireSecretRotationInput);
export type RotateSecret = z.infer<typeof rotateSecretSchema>;
@ -119,7 +119,7 @@ export const updateSecretSchema = z.object({
name: z.string().min(1).optional(),
key: secretKeySchema.optional(),
status: z.enum(SECRET_STATUSES).optional(),
providerConfigId: z.string().uuid().optional().nullable(),
providerConfigId: z.string().guid().optional().nullable(),
description: z.string().optional().nullable(),
externalRef: z.string().optional().nullable(),
providerMetadata: z.record(z.string(), z.unknown()).optional().nullable(),
@ -134,7 +134,7 @@ export const secretBindingTargetSchema = z.object({
});
export const createSecretBindingSchema = secretBindingTargetSchema.extend({
secretId: z.string().uuid(),
secretId: z.string().guid(),
versionSelector: secretVersionSelectorSchema.default("latest"),
required: z.boolean().default(true),
label: z.string().optional().nullable(),
@ -150,7 +150,7 @@ export const createUserSecretDefinitionSchema = z.object({
description: z.string().trim().max(500).optional().nullable(),
status: creatableSecretStatusSchema.optional(),
provider: z.enum(SECRET_PROVIDERS).optional(),
providerConfigId: z.string().uuid().optional().nullable(),
providerConfigId: z.string().guid().optional().nullable(),
managedMode: z.enum(SECRET_MANAGED_MODES).optional(),
providerMetadata: z.record(z.string(), z.unknown()).optional().nullable(),
usageGuidance: z.string().trim().max(1000).optional().nullable(),
@ -162,7 +162,7 @@ export const updateUserSecretDefinitionSchema = z.object({
name: z.string().trim().min(1).max(160).optional(),
description: z.string().trim().max(500).optional().nullable(),
status: z.enum(SECRET_STATUSES).optional(),
providerConfigId: z.string().uuid().optional().nullable(),
providerConfigId: z.string().guid().optional().nullable(),
providerMetadata: z.record(z.string(), z.unknown()).optional().nullable(),
usageGuidance: z.string().trim().max(1000).optional().nullable(),
});
@ -171,11 +171,11 @@ export type UpdateUserSecretDefinition = z.infer<typeof updateUserSecretDefiniti
export const createUserSecretValueSchema = z.object({
definitionKey: secretKeySchema.optional(),
definitionId: z.string().uuid().optional(),
definitionId: z.string().guid().optional(),
value: z.string().min(1).optional().nullable(),
externalRef: z.string().optional().nullable(),
providerVersionRef: z.string().optional().nullable(),
providerConfigId: z.string().uuid().optional().nullable(),
providerConfigId: z.string().guid().optional().nullable(),
}).superRefine((value, ctx) => {
if (!value.definitionKey && !value.definitionId) {
ctx.addIssue({
@ -200,7 +200,7 @@ export const updateUserSecretValueSchema = z.object({
value: z.string().min(1).optional().nullable(),
externalRef: z.string().min(1).optional().nullable(),
providerVersionRef: z.string().min(1).optional().nullable(),
providerConfigId: z.string().uuid().optional().nullable(),
providerConfigId: z.string().guid().optional().nullable(),
});
export type UpdateUserSecretValue = z.infer<typeof updateUserSecretValueSchema>;
@ -209,7 +209,7 @@ export const rotateUserSecretValueSchema = z.object({
value: z.string().min(1).optional().nullable(),
externalRef: z.string().min(1).optional().nullable(),
providerVersionRef: z.string().min(1).optional().nullable(),
providerConfigId: z.string().uuid().optional().nullable(),
providerConfigId: z.string().guid().optional().nullable(),
}).superRefine(requireSecretRotationInput);
export type RotateUserSecretValue = z.infer<typeof rotateUserSecretValueSchema>;
@ -376,7 +376,7 @@ export const updateSecretProviderConfigSchema = z.object({
export type UpdateSecretProviderConfig = z.infer<typeof updateSecretProviderConfigSchema>;
export const remoteSecretImportPreviewSchema = z.object({
providerConfigId: z.string().uuid(),
providerConfigId: z.string().guid(),
query: z.string().trim().max(200).optional().nullable(),
nextToken: z.string().trim().min(1).max(4096).optional().nullable(),
pageSize: z.number().int().min(1).max(100).optional(),
@ -386,7 +386,7 @@ export type RemoteSecretImportPreview = z.infer<typeof remoteSecretImportPreview
export const secretProviderConfigDiscoveryPreviewSchema = z.object({
provider: z.enum(SECRET_PROVIDERS),
config: z.record(z.unknown()).default({}),
config: z.record(z.string(), z.unknown()).default({}),
query: z.string().trim().max(200).optional().nullable(),
nextToken: z.string().trim().min(1).max(4096).optional().nullable(),
pageSize: z.number().int().min(1).max(100).optional(),
@ -418,7 +418,7 @@ export const remoteSecretImportSelectionSchema = z.object({
});
export const remoteSecretImportSchema = z.object({
providerConfigId: z.string().uuid(),
providerConfigId: z.string().guid(),
secrets: z.array(remoteSecretImportSelectionSchema).min(1).max(100),
});

View File

@ -1,6 +1,6 @@
import { z } from "zod";
const sidebarOrderedIdSchema = z.string().uuid();
const sidebarOrderedIdSchema = z.string().guid();
export const sidebarOrderPreferenceSchema = z.object({
orderedIds: z.array(sidebarOrderedIdSchema),

View File

@ -77,14 +77,14 @@ export const skillPolicySubjectSchema = z.discriminatedUnion("type", [
z.object({ type: z.literal("all_agents") }).strict(),
z.object({
type: z.literal("agents"),
agentIds: z.array(z.string().uuid()).min(1).max(500)
agentIds: z.array(z.string().guid()).min(1).max(500)
.refine((values) => new Set(values).size === values.length, "Agent IDs must be unique"),
}).strict(),
z.object({ type: z.literal("roles"), roles: nonEmptyUniqueStrings }).strict(),
]);
export const skillPolicyResourceSelectorSchema = z.object({
skillIds: z.array(z.string().uuid()).min(1).max(500).optional(),
skillIds: z.array(z.string().guid()).min(1).max(500).optional(),
skillKeys: nonEmptyUniqueStrings.optional(),
sourceTypes: z.array(skillPolicySourceTypeSchema).min(1)
.refine((values) => new Set(values).size === values.length, "Source types must be unique")
@ -116,7 +116,7 @@ export const replaceSkillPolicySchema = skillPolicyDocumentSchema.extend({
}).strict();
export const skillPolicyEvaluationResourceSchema = z.object({
skillId: z.string().uuid().optional(),
skillId: z.string().guid().optional(),
skillKey: z.string().trim().min(1).max(512).optional(),
sourceType: skillPolicySourceTypeSchema.optional(),
sourceLocator: skillPolicySourceLocatorSchema.optional(),
@ -125,7 +125,7 @@ export const skillPolicyEvaluationResourceSchema = z.object({
export const evaluateSkillPolicySchema = z.object({
action: skillPolicyActionSchema,
resource: skillPolicyEvaluationResourceSchema.default({}),
principal: z.object({ agentId: z.string().uuid() }).strict().optional(),
principal: z.object({ agentId: z.string().guid() }).strict().optional(),
}).strict();
export type SkillPolicyAction = z.infer<typeof skillPolicyActionSchema>;

View File

@ -32,7 +32,7 @@ export const statusCardRefreshPolicySchema = z
intervalMinutes: z.number().int().positive().optional(),
debounceSeconds: z.number().int().positive().optional(),
maxUpdatesPerHour: z.number().int().positive().optional(),
triggers: statusCardRefreshTriggersSchema.default({}),
triggers: statusCardRefreshTriggersSchema.prefault({}),
activeHours: z
.object({
start: z.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/),
@ -61,41 +61,41 @@ export const statusCardFingerprintSchema = z.record(
latestHumanCommentAt: z.string().datetime().nullable().optional(),
identifier: z.string().nullable().optional(),
title: z.string().optional(),
assigneeAgentId: z.string().uuid().nullable().optional(),
assigneeAgentId: z.string().guid().nullable().optional(),
assigneeUserId: z.string().nullable().optional(),
}),
);
export const statusCardSchema = z.object({
id: z.string().uuid(),
companyId: z.string().uuid(),
id: z.string().guid(),
companyId: z.string().guid(),
createdByUserId: z.string().nullable(),
createdByAgentId: z.string().uuid().nullable(),
createdByAgentId: z.string().guid().nullable(),
title: z.string().nullable(),
titlePinned: z.boolean(),
interestPrompt: z.string(),
queries: z.array(companySearchQuerySchema),
queryVersion: z.number().int().nonnegative(),
queryCompiledAt: z.string().datetime().nullable(),
queryCompiledByAgentId: z.string().uuid().nullable(),
agentId: z.string().uuid().nullable(),
queryCompiledByAgentId: z.string().guid().nullable(),
agentId: z.string().guid().nullable(),
refreshPolicy: statusCardRefreshPolicySchema,
state: statusCardStateSchema,
pendingChangeCount: z.number().int().nonnegative(),
lastChangeAt: z.string().datetime().nullable(),
fingerprint: statusCardFingerprintSchema.nullable(),
fingerprintAt: z.string().datetime().nullable(),
mentionedIssueIds: z.array(z.string().uuid()).default([]),
documentId: z.string().uuid().nullable(),
mentionedIssueIds: z.array(z.string().guid()).default([]),
documentId: z.string().guid().nullable(),
lastUpdateRunKind: z.enum(["full", "incremental"]).nullable(),
lastGeneratedAt: z.string().datetime().nullable(),
lastModel: z.string().nullable(),
generatingIssueId: z.string().uuid().nullable(),
generatingIssueId: z.string().guid().nullable(),
failureReason: z.string().nullable(),
nextEvalAt: z.string().datetime().nullable(),
archivedAt: z.string().datetime().nullable(),
archivedByUserId: z.string().nullable(),
archivedByAgentId: z.string().uuid().nullable(),
archivedByAgentId: z.string().guid().nullable(),
createdAt: z.string().datetime(),
updatedAt: z.string().datetime(),
summaryBody: z.string().nullable().optional(),
@ -105,7 +105,7 @@ export const statusCardSchema = z.object({
});
export const statusCardUpdateChangeSchema = z.object({
issueId: z.string().uuid(),
issueId: z.string().guid(),
identifier: z.string(),
from: z.string().nullable(),
to: z.string().nullable(),
@ -113,12 +113,12 @@ export const statusCardUpdateChangeSchema = z.object({
});
export const statusCardUpdateSchema = z.object({
id: z.string().uuid(),
cardId: z.string().uuid(),
id: z.string().guid(),
cardId: z.string().guid(),
kind: statusCardUpdateKindSchema,
trigger: statusCardUpdateTriggerSchema,
generationIssueId: z.string().uuid().nullable(),
runId: z.string().uuid().nullable(),
generationIssueId: z.string().guid().nullable(),
runId: z.string().guid().nullable(),
changes: z.array(statusCardUpdateChangeSchema),
inputTokens: z.number().int().nonnegative(),
outputTokens: z.number().int().nonnegative(),
@ -133,7 +133,7 @@ export const statusCardUpdateSchema = z.object({
});
export const statusCardSummaryRevisionSchema = z.object({
id: z.string().uuid(),
id: z.string().guid(),
revisionNumber: z.number().int().positive(),
title: z.string().nullable(),
body: z.string(),
@ -152,7 +152,7 @@ export const createStatusCardSchema = z.object({
interestPrompt: z.string().trim().min(1).max(20_000),
title: z.string().trim().min(1).max(300).optional(),
titlePinned: z.boolean().default(false),
agentId: z.string().uuid().nullable().optional(),
agentId: z.string().guid().nullable().optional(),
refreshPolicy: statusCardRefreshPolicySchema.default(defaultStatusCardRefreshPolicy),
});
@ -161,7 +161,7 @@ export const patchStatusCardSchema = z
interestPrompt: z.string().trim().min(1).max(20_000).optional(),
title: z.string().trim().min(1).max(300).nullable().optional(),
titlePinned: z.boolean().optional(),
agentId: z.string().uuid().nullable().optional(),
agentId: z.string().guid().nullable().optional(),
refreshPolicy: statusCardRefreshPolicySchema.optional(),
archived: z.boolean().optional(),
})
@ -175,14 +175,14 @@ export const writeStatusCardQuerySchema = z.object({
queries: z.array(companySearchQuerySchema).min(1).max(10),
title: z.string().trim().min(1).max(300),
changeSummary: z.string().trim().min(1).max(2_000),
generationIssueId: z.string().uuid(),
generationIssueId: z.string().guid(),
});
export const writeStatusCardSummarySchema = z.object({
markdown: z.string().trim().min(1).max(200_000),
title: z.string().trim().min(1).max(300).optional(),
changeSummary: z.string().trim().min(1).max(2_000),
generationIssueId: z.string().uuid(),
generationIssueId: z.string().guid(),
model: z.string().trim().min(1).max(200).optional().nullable(),
});

View File

@ -5,7 +5,7 @@ import {
SUMMARY_SLOT_STATUSES,
} from "../constants.js";
const optionalScopeIdSchema = z.string().uuid().optional().nullable();
const optionalScopeIdSchema = z.string().guid().optional().nullable();
export const summarySlotScopeKindSchema = z.enum(SUMMARY_SLOT_SCOPE_KINDS);
export const summarySlotKeySchema = z.enum(SUMMARY_SLOT_KEYS);
@ -53,8 +53,8 @@ export const writeSummarySlotSchema = z
markdown: z.string().trim().min(1).max(200_000),
title: z.string().trim().min(1).max(200).optional().nullable(),
changeSummary: z.string().trim().min(1).max(1_000).optional().nullable(),
baseRevisionId: z.string().uuid().optional().nullable(),
generationIssueId: z.string().uuid().optional().nullable(),
baseRevisionId: z.string().guid().optional().nullable(),
generationIssueId: z.string().guid().optional().nullable(),
model: z.string().trim().min(1).max(200).optional().nullable(),
})
.strict();

View File

@ -31,6 +31,7 @@ import {
TOOL_RUNTIME_SLOT_STATUSES,
} from "../constants.js";
import { jsonSchemaSchema } from "./plugin.js";
import { objectWithoutDefaults } from "./partial.js";
export const toolApplicationTypeSchema = z.enum(TOOL_APPLICATION_TYPES);
export const toolApplicationStatusSchema = z.enum(TOOL_APPLICATION_STATUSES);
@ -91,7 +92,7 @@ function rejectSensitiveConfigKeys(value: unknown, ctx: z.RefinementCtx, path: A
}
export const toolCredentialSecretRefSchema = z.object({
secretId: z.string().uuid(),
secretId: z.string().guid(),
versionSelector: z.union([z.literal("latest"), z.number().int().positive()]).optional(),
configPath: z.string().trim().min(1).max(200),
required: z.boolean().optional(),
@ -104,7 +105,7 @@ export const toolCredentialSecretRefSchema = z.object({
export const mcpConnectionCredentialRefSchema = z.object({
name: z.string().trim().min(1).max(120),
secretId: z.string().uuid(),
secretId: z.string().guid(),
version: z.union([z.literal("latest"), z.number().int().positive()]).optional(),
placement: toolCredentialPlacementSchema,
key: z.string().trim().min(1).max(160),
@ -118,7 +119,7 @@ export const toolRedactedValueSummarySchema = z.object({
sizeBytes: z.number().int().min(0).optional().nullable(),
sha256: z.string().trim().regex(/^[a-f0-9]{64}$/i).optional().nullable(),
redactedFields: z.array(z.string().trim().min(1).max(200)).default([]).optional(),
artifactId: z.string().uuid().optional().nullable(),
artifactId: z.string().guid().optional().nullable(),
});
export const createToolApplicationSchema = z.object({
@ -127,8 +128,8 @@ export const createToolApplicationSchema = z.object({
description: z.string().max(4000).optional().nullable(),
type: toolApplicationTypeSchema,
status: toolApplicationStatusSchema.optional(),
pluginId: z.string().uuid().optional().nullable(),
ownerAgentId: z.string().uuid().optional().nullable(),
pluginId: z.string().guid().optional().nullable(),
ownerAgentId: z.string().guid().optional().nullable(),
ownerUserId: z.string().optional().nullable(),
metadata: z.record(z.string(), z.unknown()).optional().nullable(),
});
@ -143,7 +144,7 @@ export const updateToolApplicationSchema = createToolApplicationSchema.partial()
export type UpdateToolApplication = z.infer<typeof updateToolApplicationSchema>;
export const createToolConnectionSchema = z.object({
applicationId: z.string().uuid().optional(),
applicationId: z.string().guid().optional(),
applicationName: z.string().trim().min(1).max(160).optional(),
name: z.string().trim().min(1).max(160),
transport: toolConnectionTransportSchema.optional(),
@ -160,7 +161,7 @@ export const createToolConnectionSchema = z.object({
export type CreateToolConnection = z.infer<typeof createToolConnectionSchema>;
export const updateToolConnectionSchema = createToolConnectionSchema.omit({ applicationId: true }).partial().refine(
export const updateToolConnectionSchema = objectWithoutDefaults(createToolConnectionSchema.omit({ applicationId: true })).partial().refine(
(value) => Object.keys(value).length > 0,
{ message: "At least one tool connection field is required" },
);
@ -168,9 +169,9 @@ export const updateToolConnectionSchema = createToolConnectionSchema.omit({ appl
export type UpdateToolConnection = z.infer<typeof updateToolConnectionSchema>;
export const connectionGrantSchema = z.object({
id: z.string().uuid(),
companyId: z.string().uuid(),
connectionId: z.string().uuid(),
id: z.string().guid(),
companyId: z.string().guid(),
connectionId: z.string().guid(),
kind: connectionGrantKindSchema,
subjectUserId: z.string().nullable(),
providerTenant: z.object({
@ -180,10 +181,10 @@ export const connectionGrantSchema = z.object({
credentialSecretRefs: z.array(toolCredentialSecretRefSchema),
status: connectionGrantStatusSchema,
isDefault: z.boolean(),
createdByAgentId: z.string().uuid().nullable(),
createdByAgentId: z.string().guid().nullable(),
createdByUserId: z.string().nullable(),
revokedAt: z.coerce.date().nullable(),
revokedByAgentId: z.string().uuid().nullable(),
revokedByAgentId: z.string().guid().nullable(),
revokedByUserId: z.string().nullable(),
lastUsedAt: z.coerce.date().nullable(),
createdAt: z.coerce.date(),
@ -219,7 +220,7 @@ export const connectionTokenRequestSchema = z.object({
subject: connectionTokenSubjectSchema.optional().default({ type: "app" }),
scope: connectionTokenScopeSchema.optional(),
requestedTtlSeconds: z.number().int().positive().max(86_400).optional(),
grantId: z.string().uuid().optional(),
grantId: z.string().guid().optional(),
}).strict();
export const startConnectionAuthorizationSchema = z.object({
@ -264,7 +265,7 @@ export const connectToolAppSchema = z.object({
name: z.string().trim().min(1).max(160).optional(),
credentialValues: z.record(z.string().trim().min(1).max(200), z.string().min(1)).optional(),
configValues: z.record(z.string().trim().min(1).max(200), z.unknown()).optional(),
applicationId: z.string().uuid().optional(),
applicationId: z.string().guid().optional(),
}).refine(
(value) => Boolean(value.galleryKey) !== Boolean(value.link),
{ message: "Provide exactly one of galleryKey or link" },
@ -279,20 +280,20 @@ export const reconnectToolAppSchema = z.object({
export type ReconnectToolApp = z.infer<typeof reconnectToolAppSchema>;
export const finishToolAppSchema = z.object({
enabledCatalogEntryIds: z.array(z.string().uuid()).max(500).default([]),
askFirstCatalogEntryIds: z.array(z.string().uuid()).max(500).default([]),
reviewedCatalogEntryIds: z.array(z.string().uuid()).max(500).optional(),
enabledCatalogEntryIds: z.array(z.string().guid()).max(500).default([]),
askFirstCatalogEntryIds: z.array(z.string().guid()).max(500).default([]),
reviewedCatalogEntryIds: z.array(z.string().guid()).max(500).optional(),
access: z.union([
z.literal("all_agents"),
z.object({ agentIds: z.array(z.string().uuid()).min(1).max(250) }),
z.object({ agentIds: z.array(z.string().guid()).min(1).max(250) }),
]),
});
export type FinishToolApp = z.infer<typeof finishToolAppSchema>;
export const upsertToolCatalogEntrySchema = z.object({
applicationId: z.string().uuid(),
connectionId: z.string().uuid(),
applicationId: z.string().guid(),
connectionId: z.string().guid(),
entryKind: toolCatalogEntryKindSchema.default("tool"),
toolName: z.string().trim().min(1).max(240),
title: z.string().trim().max(240).optional().nullable(),
@ -322,7 +323,7 @@ export const createToolProfileSchema = z.object({
export type CreateToolProfile = z.infer<typeof createToolProfileSchema>;
export const updateToolProfileSchema = createToolProfileSchema.partial().refine(
export const updateToolProfileSchema = objectWithoutDefaults(createToolProfileSchema).partial().refine(
(value) => Object.keys(value).length > 0,
{ message: "At least one tool profile field is required" },
);
@ -330,12 +331,12 @@ export const updateToolProfileSchema = createToolProfileSchema.partial().refine(
export type UpdateToolProfile = z.infer<typeof updateToolProfileSchema>;
export const createToolProfileEntrySchema = z.object({
profileId: z.string().uuid(),
profileId: z.string().guid(),
selectorType: toolProfileEntrySelectorTypeSchema,
effect: toolProfileEntryEffectSchema.default("include"),
applicationId: z.string().uuid().optional().nullable(),
connectionId: z.string().uuid().optional().nullable(),
catalogEntryId: z.string().uuid().optional().nullable(),
applicationId: z.string().guid().optional().nullable(),
connectionId: z.string().guid().optional().nullable(),
catalogEntryId: z.string().guid().optional().nullable(),
toolName: z.string().trim().min(1).max(240).optional().nullable(),
riskLevel: toolRiskLevelSchema.optional().nullable(),
conditions: z.record(z.string(), z.unknown()).optional().nullable(),
@ -347,7 +348,7 @@ export const createToolProfileEntryForProfileSchema = createToolProfileEntrySche
export type CreateToolProfileEntryForProfile = z.infer<typeof createToolProfileEntryForProfileSchema>;
export const updateToolProfileEntrySchema = createToolProfileEntryForProfileSchema.partial().refine(
export const updateToolProfileEntrySchema = objectWithoutDefaults(createToolProfileEntryForProfileSchema).partial().refine(
(value) => Object.keys(value).length > 0,
{ message: "At least one tool profile entry field is required" },
);
@ -367,7 +368,7 @@ export const duplicateToolProfileSchema = z.object({
export type DuplicateToolProfile = z.infer<typeof duplicateToolProfileSchema>;
export const updateToolProfileWithEntriesSchema = createToolProfileSchema.partial().extend({
export const updateToolProfileWithEntriesSchema = objectWithoutDefaults(createToolProfileSchema).partial().extend({
entries: z.array(createToolProfileEntryForProfileSchema).max(250).optional(),
}).refine(
(value) => Object.keys(value).length > 0,
@ -378,7 +379,7 @@ export type UpdateToolProfileWithEntries = z.infer<typeof updateToolProfileWithE
export const reviewToolProfileNewToolsSchema = z.object({
decisions: z.array(z.object({
catalogEntryId: z.string().uuid(),
catalogEntryId: z.string().guid(),
decision: z.enum(["allow", "keep_blocked"]),
})).min(1).max(250),
});
@ -387,13 +388,13 @@ export type ReviewToolProfileNewTools = z.infer<typeof reviewToolProfileNewTools
export const deleteToolProfileSchema = z.object({
force: z.boolean().default(false),
reassignToProfileId: z.string().uuid().optional(),
}).default({});
reassignToProfileId: z.string().guid().optional(),
}).prefault({});
export type DeleteToolProfile = z.infer<typeof deleteToolProfileSchema>;
export const createToolProfileBindingSchema = z.object({
profileId: z.string().uuid(),
profileId: z.string().guid(),
targetType: toolProfileBindingTargetTypeSchema,
targetId: z.string().trim().min(1).max(200),
priority: z.number().int().min(0).max(10000).default(100),
@ -423,14 +424,14 @@ export const toolMcpGatewayAuthConfigSchema = z.object({
defaultTtlSeconds: z.number().int().positive().max(31_536_000).nullable().default(7_776_000),
requireFiniteExpiry: z.boolean().default(true),
longLivedTokenRequiresOverride: z.boolean().default(true),
}).default({}),
}).prefault({}),
oauth: z.object({
enabled: z.literal(false).default(false),
reservedFor: z.literal("v1_5").default("v1_5"),
protectedResourceMetadataPath: z.string().trim().max(240).optional().nullable(),
dynamicClientRegistration: z.literal(false).optional(),
authorizationCodePkce: z.literal(false).optional(),
}).default({}),
}).prefault({}),
});
export const toolMcpGatewayHeaderPolicySchema = z.object({
@ -438,7 +439,7 @@ export const toolMcpGatewayHeaderPolicySchema = z.object({
callerPassthrough: z.object({
enabled: z.boolean().default(false),
allowedHeaders: z.array(headerNameSchema).max(50).default([]),
}).default({}),
}).prefault({}),
staticHeaders: z.array(z.object({
name: headerNameSchema,
valueRef: z.string().trim().max(240).optional().nullable(),
@ -447,11 +448,11 @@ export const toolMcpGatewayHeaderPolicySchema = z.object({
generatedMetadata: z.object({
enabled: z.boolean().default(false),
allowedHeaders: z.array(headerNameSchema).max(20).default([]),
}).default({}),
}).prefault({}),
responseHeaders: z.object({
forwardMcpRequiredHeaders: z.boolean().default(true),
forwardSafeCacheHeaders: z.boolean().default(true),
}).default({}),
}).prefault({}),
});
export const toolMcpGatewayMetadataPolicySchema = z.object({
@ -476,14 +477,14 @@ export const createToolMcpGatewaySchema = z.object({
slug: z.string().trim().min(1).max(120).regex(safeKeyPattern).optional(),
displaySlug: z.string().trim().min(1).max(120).regex(safeKeyPattern).optional(),
description: z.string().max(4000).optional().nullable(),
profileId: z.string().uuid(),
profileId: z.string().guid(),
defaultProfileMode: toolMcpGatewayDefaultProfileModeSchema.default("gateway_only").optional(),
contextScopeType: toolMcpGatewayContextScopeTypeSchema.default("none").optional(),
contextScopeId: z.string().trim().min(1).max(200).optional().nullable(),
agentId: z.string().uuid().optional().nullable(),
projectId: z.string().uuid().optional().nullable(),
issueId: z.string().uuid().optional().nullable(),
approvalIssueId: z.string().uuid().optional().nullable(),
agentId: z.string().guid().optional().nullable(),
projectId: z.string().guid().optional().nullable(),
issueId: z.string().guid().optional().nullable(),
approvalIssueId: z.string().guid().optional().nullable(),
authConfig: toolMcpGatewayAuthConfigSchema.optional(),
headerPolicy: toolMcpGatewayHeaderPolicySchema.optional(),
metadataPolicy: toolMcpGatewayMetadataPolicySchema.optional(),
@ -493,7 +494,7 @@ export const createToolMcpGatewaySchema = z.object({
export type CreateToolMcpGateway = z.infer<typeof createToolMcpGatewaySchema>;
export const updateToolMcpGatewaySchema = createToolMcpGatewaySchema
export const updateToolMcpGatewaySchema = objectWithoutDefaults(createToolMcpGatewaySchema)
.partial()
.extend({ status: toolMcpGatewayStatusSchema.optional() })
.refine((value) => Object.keys(value).length > 0, { message: "At least one gateway field is required" });
@ -554,29 +555,29 @@ const timeWindowConditionSchema = z.object({
const actorConditionSchema = z.object({
actorType: z.enum(["agent", "user", "system", "plugin"]).optional(),
actorTypes: z.array(z.enum(["agent", "user", "system", "plugin"])).max(20).optional(),
agentId: z.string().uuid().optional(),
agentIds: z.array(z.string().uuid()).max(100).optional(),
agentId: z.string().guid().optional(),
agentIds: z.array(z.string().guid()).max(100).optional(),
}).strict();
const contextConditionSchema = z.object({
projectId: z.string().uuid().optional(),
projectIds: z.array(z.string().uuid()).max(100).optional(),
routineId: z.string().uuid().optional(),
routineIds: z.array(z.string().uuid()).max(100).optional(),
issueId: z.string().uuid().optional(),
issueIds: z.array(z.string().uuid()).max(100).optional(),
projectId: z.string().guid().optional(),
projectIds: z.array(z.string().guid()).max(100).optional(),
routineId: z.string().guid().optional(),
routineIds: z.array(z.string().guid()).max(100).optional(),
issueId: z.string().guid().optional(),
issueIds: z.array(z.string().guid()).max(100).optional(),
requireIssue: z.boolean().optional(),
requireProject: z.boolean().optional(),
requireRoutine: z.boolean().optional(),
}).strict();
const credentialScopeConditionSchema = z.object({
applicationId: z.string().uuid().optional(),
applicationIds: z.array(z.string().uuid()).max(100).optional(),
connectionId: z.string().uuid().optional(),
connectionIds: z.array(z.string().uuid()).max(100).optional(),
catalogEntryId: z.string().uuid().optional(),
catalogEntryIds: z.array(z.string().uuid()).max(100).optional(),
applicationId: z.string().guid().optional(),
applicationIds: z.array(z.string().guid()).max(100).optional(),
connectionId: z.string().guid().optional(),
connectionIds: z.array(z.string().guid()).max(100).optional(),
catalogEntryId: z.string().guid().optional(),
catalogEntryIds: z.array(z.string().guid()).max(100).optional(),
applicationKey: z.string().trim().min(1).max(160).optional(),
applicationKeys: z.array(z.string().trim().min(1).max(160)).max(100).optional(),
providerType: z.string().trim().min(1).max(160).optional(),
@ -622,7 +623,7 @@ export const createToolPolicySchema = z.object({
export type CreateToolPolicy = z.infer<typeof createToolPolicySchema>;
export const updateToolPolicySchema = createToolPolicySchema.partial().refine(
export const updateToolPolicySchema = objectWithoutDefaults(createToolPolicySchema).partial().refine(
(value) => Object.keys(value).length > 0,
{ message: "At least one tool policy field is required" },
);
@ -630,7 +631,7 @@ export const updateToolPolicySchema = createToolPolicySchema.partial().refine(
export type UpdateToolPolicy = z.infer<typeof updateToolPolicySchema>;
export const reorderToolPoliciesSchema = z.object({
policyIds: z.array(z.string().uuid()).min(1).max(500),
policyIds: z.array(z.string().guid()).min(1).max(500),
});
export type ReorderToolPolicies = z.infer<typeof reorderToolPoliciesSchema>;
@ -643,11 +644,11 @@ export type DuplicateToolPolicy = z.infer<typeof duplicateToolPolicySchema>;
export const createToolInvocationSchema = z.object({
idempotencyKey: z.string().trim().min(1).max(300).optional().nullable(),
issueId: z.string().uuid().optional().nullable(),
runId: z.string().uuid().optional().nullable(),
applicationId: z.string().uuid().optional().nullable(),
connectionId: z.string().uuid().optional().nullable(),
catalogEntryId: z.string().uuid().optional().nullable(),
issueId: z.string().guid().optional().nullable(),
runId: z.string().guid().optional().nullable(),
applicationId: z.string().guid().optional().nullable(),
connectionId: z.string().guid().optional().nullable(),
catalogEntryId: z.string().guid().optional().nullable(),
toolName: z.string().trim().min(1).max(240),
argumentsHash: z.string().trim().max(128).optional().nullable(),
argumentsSummary: toolRedactedValueSummarySchema.optional().nullable(),
@ -656,8 +657,8 @@ export const createToolInvocationSchema = z.object({
export type CreateToolInvocation = z.infer<typeof createToolInvocationSchema>;
export const createToolActionRequestSchema = z.object({
invocationId: z.string().uuid(),
issueId: z.string().uuid().optional().nullable(),
invocationId: z.string().guid(),
issueId: z.string().guid().optional().nullable(),
canonicalArgumentsHash: z.string().trim().min(1).max(128),
canonicalArgumentsSummary: toolRedactedValueSummarySchema,
signedArguments: z.string().trim().max(4096).optional().nullable(),
@ -668,7 +669,7 @@ export const createToolActionRequestSchema = z.object({
export type CreateToolActionRequest = z.infer<typeof createToolActionRequestSchema>;
export const toolConnectionTestCallSchema = z.object({
agentId: z.string().uuid(),
agentId: z.string().guid(),
toolName: z.string().trim().min(1).max(240),
parameters: z.unknown().optional(),
});
@ -683,31 +684,31 @@ export type ImportMcpJson = z.infer<typeof importMcpJsonSchema>;
export const toolAccessSelectorSchema = z.object({
actorType: z.enum(["agent", "user", "system", "plugin"]).optional(),
agentId: z.string().uuid().optional(),
agentIds: z.array(z.string().uuid()).optional(),
projectId: z.string().uuid().optional(),
projectIds: z.array(z.string().uuid()).optional(),
routineId: z.string().uuid().optional(),
routineIds: z.array(z.string().uuid()).optional(),
issueId: z.string().uuid().optional(),
issueIds: z.array(z.string().uuid()).optional(),
gatewayId: z.string().uuid().optional(),
gatewayIds: z.array(z.string().uuid()).optional(),
agentId: z.string().guid().optional(),
agentIds: z.array(z.string().guid()).optional(),
projectId: z.string().guid().optional(),
projectIds: z.array(z.string().guid()).optional(),
routineId: z.string().guid().optional(),
routineIds: z.array(z.string().guid()).optional(),
issueId: z.string().guid().optional(),
issueIds: z.array(z.string().guid()).optional(),
gatewayId: z.string().guid().optional(),
gatewayIds: z.array(z.string().guid()).optional(),
gatewayPublicId: z.string().trim().min(1).max(120).regex(safeKeyPattern).optional(),
gatewayPublicIds: z.array(z.string().trim().min(1).max(120).regex(safeKeyPattern)).optional(),
gatewayTokenId: z.string().uuid().optional(),
gatewayTokenIds: z.array(z.string().uuid()).optional(),
gatewayTokenId: z.string().guid().optional(),
gatewayTokenIds: z.array(z.string().guid()).optional(),
clientSubjectType: toolMcpGatewayTokenSubjectTypeSchema.optional(),
clientSubjectTypes: z.array(toolMcpGatewayTokenSubjectTypeSchema).optional(),
clientName: z.string().trim().min(1).max(160).optional(),
clientNames: z.array(z.string().trim().min(1).max(160)).optional(),
externalClient: z.boolean().optional(),
applicationId: z.string().uuid().optional(),
applicationIds: z.array(z.string().uuid()).optional(),
connectionId: z.string().uuid().optional(),
connectionIds: z.array(z.string().uuid()).optional(),
catalogEntryId: z.string().uuid().optional(),
catalogEntryIds: z.array(z.string().uuid()).optional(),
applicationId: z.string().guid().optional(),
applicationIds: z.array(z.string().guid()).optional(),
connectionId: z.string().guid().optional(),
connectionIds: z.array(z.string().guid()).optional(),
catalogEntryId: z.string().guid().optional(),
catalogEntryIds: z.array(z.string().guid()).optional(),
toolName: z.string().trim().min(1).max(240).optional(),
toolNames: z.array(z.string().trim().min(1).max(240)).optional(),
riskLevel: toolRiskLevelSchema.optional(),
@ -780,29 +781,29 @@ export const revokeToolTrustRuleSchema = z.object({
export type RevokeToolTrustRule = z.infer<typeof revokeToolTrustRuleSchema>;
export const toolPolicyTestRequestSchema = z.object({
companyId: z.string().uuid(),
companyId: z.string().guid(),
actor: z.object({
actorType: z.enum(["agent", "user", "system", "plugin"]),
actorId: z.string().trim().min(1).max(240),
agentId: z.string().uuid().optional().nullable(),
agentId: z.string().guid().optional().nullable(),
}),
runContext: z.object({
heartbeatRunId: z.string().uuid().optional().nullable(),
issueId: z.string().uuid().optional().nullable(),
projectId: z.string().uuid().optional().nullable(),
routineId: z.string().uuid().optional().nullable(),
gatewayId: z.string().uuid().optional().nullable(),
heartbeatRunId: z.string().guid().optional().nullable(),
issueId: z.string().guid().optional().nullable(),
projectId: z.string().guid().optional().nullable(),
routineId: z.string().guid().optional().nullable(),
gatewayId: z.string().guid().optional().nullable(),
gatewayPublicId: z.string().trim().min(1).max(120).regex(safeKeyPattern).optional().nullable(),
gatewayTokenId: z.string().uuid().optional().nullable(),
gatewayTokenId: z.string().guid().optional().nullable(),
clientSubjectType: toolMcpGatewayTokenSubjectTypeSchema.optional().nullable(),
clientSubjectId: z.string().trim().min(1).max(240).optional().nullable(),
clientName: z.string().trim().min(1).max(160).optional().nullable(),
externalClient: z.boolean().optional().nullable(),
}).optional().nullable(),
request: z.object({
applicationId: z.string().uuid().optional().nullable(),
connectionId: z.string().uuid().optional().nullable(),
catalogEntryId: z.string().uuid().optional().nullable(),
applicationId: z.string().guid().optional().nullable(),
connectionId: z.string().guid().optional().nullable(),
catalogEntryId: z.string().guid().optional().nullable(),
toolName: z.string().trim().min(1).max(240),
arguments: z.unknown().optional(),
idempotencyKey: z.string().trim().min(1).max(512).optional().nullable(),

View File

@ -10,17 +10,17 @@ export const trustPresetSchema = z.enum(TRUST_PRESETS);
export const lowTrustOutputPromotionTargetSchema = z.object({
type: z.literal("issue"),
issueId: z.string().uuid(),
issueId: z.string().guid(),
}).strict();
export const lowTrustBoundarySchema = z.object({
mode: z.literal(LOW_TRUST_REVIEW_PRESET),
companyId: z.string().uuid().optional(),
projectIds: z.array(z.string().uuid()).optional(),
rootIssueId: z.string().uuid().optional(),
issueIds: z.array(z.string().uuid()).optional(),
allowedAgentIds: z.array(z.string().uuid()).optional(),
allowedSecretBindingIds: z.array(z.string().uuid()).optional(),
companyId: z.string().guid().optional(),
projectIds: z.array(z.string().guid()).optional(),
rootIssueId: z.string().guid().optional(),
issueIds: z.array(z.string().guid()).optional(),
allowedAgentIds: z.array(z.string().guid()).optional(),
allowedSecretBindingIds: z.array(z.string().guid()).optional(),
allowedToolClasses: z.array(z.string().trim().min(1)).optional(),
outputPromotionTarget: lowTrustOutputPromotionTargetSchema.optional(),
}).strict();
@ -58,13 +58,13 @@ export const sourceTrustArtifactKindSchema = z.enum(["issue", "comment", "docume
export const sourceTrustMetadataSchema = z.object({
preset: trustPresetSchema,
disposition: z.enum(["quarantined", "promoted"]),
sourceIssueId: z.string().uuid().nullable().optional(),
sourceRunId: z.string().uuid().nullable().optional(),
sourceAgentId: z.string().uuid().nullable().optional(),
sourceIssueId: z.string().guid().nullable().optional(),
sourceRunId: z.string().guid().nullable().optional(),
sourceAgentId: z.string().guid().nullable().optional(),
promotedFrom: z.object({
artifactKind: sourceTrustArtifactKindSchema,
artifactId: z.string().uuid(),
issueId: z.string().uuid().nullable().optional(),
artifactId: z.string().guid(),
issueId: z.string().guid().nullable().optional(),
}).strict().nullable().optional(),
promotedByActorType: z.enum(["agent", "user", "system"]).nullable().optional(),
promotedByActorId: z.string().trim().min(1).nullable().optional(),

View File

@ -1,5 +1,6 @@
import { z } from "zod";
import { workspaceFileRefSchema } from "./workspace-file-resource.js";
import { objectWithoutDefaults } from "./partial.js";
function attachmentContentPath(attachmentId: string): string {
return `/api/attachments/${attachmentId}/content`;
@ -35,7 +36,7 @@ export const issueWorkProductReviewStateSchema = z.enum([
]);
export const attachmentArtifactWorkProductMetadataSchema = z.object({
attachmentId: z.string().uuid(),
attachmentId: z.string().guid(),
contentType: z.string().min(1),
byteSize: z.number().int().nonnegative(),
contentPath: z.string().min(1),
@ -78,9 +79,9 @@ export const issueWorkProductMetadataSchema = z
export type IssueWorkProductMetadata = z.infer<typeof issueWorkProductMetadataSchema>;
export const createIssueWorkProductSchema = z.object({
projectId: z.string().uuid().optional().nullable(),
executionWorkspaceId: z.string().uuid().optional().nullable(),
runtimeServiceId: z.string().uuid().optional().nullable(),
projectId: z.string().guid().optional().nullable(),
executionWorkspaceId: z.string().guid().optional().nullable(),
runtimeServiceId: z.string().guid().optional().nullable(),
type: issueWorkProductTypeSchema,
provider: z.string().min(1),
externalId: z.string().optional().nullable(),
@ -92,11 +93,13 @@ export const createIssueWorkProductSchema = z.object({
healthStatus: z.enum(["unknown", "healthy", "unhealthy"]).optional().default("unknown"),
summary: z.string().optional().nullable(),
metadata: issueWorkProductMetadataSchema.optional().nullable(),
createdByRunId: z.string().uuid().optional().nullable(),
createdByRunId: z.string().guid().optional().nullable(),
});
export type CreateIssueWorkProduct = z.infer<typeof createIssueWorkProductSchema>;
export const updateIssueWorkProductSchema = createIssueWorkProductSchema.partial();
export const updateIssueWorkProductSchema = objectWithoutDefaults(
createIssueWorkProductSchema,
).partial();
export type UpdateIssueWorkProduct = z.infer<typeof updateIssueWorkProductSchema>;

View File

@ -14,11 +14,11 @@ export const workspaceFileResourceKindSchema = z.enum(["file", "directory", "rem
export const workspaceFileRefSchema = z.object({
kind: z.literal("workspace_file"),
issueId: z.string().uuid().optional(),
projectId: z.string().uuid().optional(),
issueId: z.string().guid().optional(),
projectId: z.string().guid().optional(),
projectName: z.string().min(1).optional(),
workspaceKind: workspaceFileWorkspaceKindSchema,
workspaceId: z.string().uuid(),
workspaceId: z.string().guid(),
relativePath: z.string().min(1),
line: z.number().int().positive().nullable().optional(),
column: z.number().int().positive().nullable().optional(),
@ -26,8 +26,8 @@ export const workspaceFileRefSchema = z.object({
});
export const workspaceFileResourceQuerySchema = z.object({
projectId: z.string().uuid().optional(),
workspaceId: z.string().uuid().optional(),
projectId: z.string().guid().optional(),
workspaceId: z.string().guid().optional(),
path: z
.string()
.min(1)
@ -47,8 +47,8 @@ export const workspaceFileAvailabilityRequestSchema = z.object({
});
export const workspaceFileListQuerySchema = z.object({
projectId: z.string().uuid().optional(),
workspaceId: z.string().uuid().optional(),
projectId: z.string().guid().optional(),
workspaceId: z.string().guid().optional(),
workspace: workspaceFileSelectorSchema.optional(),
path: z
.string()
@ -85,8 +85,8 @@ export const resolvedWorkspaceResourceSchema = z.object({
displayPath: z.string().min(1),
workspaceLabel: z.string().min(1),
workspaceKind: workspaceFileWorkspaceKindSchema,
workspaceId: z.string().uuid(),
projectId: z.string().uuid().nullable().optional(),
workspaceId: z.string().guid(),
projectId: z.string().guid().nullable().optional(),
projectName: z.string().min(1).nullable().optional(),
contentType: z.string().nullable().optional(),
byteSize: z.number().int().nonnegative().nullable().optional(),
@ -100,8 +100,8 @@ export const resolvedWorkspaceResourceSchema = z.object({
});
export const normalizedWorkspaceFileAvailabilityQuerySchema = z.object({
projectId: z.string().uuid().nullable(),
workspaceId: z.string().uuid().nullable(),
projectId: z.string().guid().nullable(),
workspaceId: z.string().guid().nullable(),
path: z.string().min(1),
workspace: workspaceFileSelectorSchema,
});

View File

@ -390,13 +390,13 @@ importers:
dependencies:
'@modelcontextprotocol/sdk':
specifier: ^1.30.0
version: 1.30.0(zod@3.25.76)
version: 1.30.0(zod@4.4.3)
googleapis:
specifier: ^174.0.1
version: 174.0.1
zod:
specifier: ^3.24.2
version: 3.25.76
specifier: ^4.4.3
version: 4.4.3
devDependencies:
'@types/node':
specifier: ^22.20.1
@ -412,10 +412,10 @@ importers:
dependencies:
'@modelcontextprotocol/sdk':
specifier: ^1.30.0
version: 1.30.0(zod@3.25.76)
version: 1.30.0(zod@4.4.3)
zod:
specifier: ^3.24.2
version: 3.25.76
specifier: ^4.4.3
version: 4.4.3
devDependencies:
'@types/node':
specifier: ^22.20.1
@ -431,13 +431,13 @@ importers:
dependencies:
'@modelcontextprotocol/sdk':
specifier: ^1.30.0
version: 1.30.0(zod@3.25.76)
version: 1.30.0(zod@4.4.3)
'@paperclipai/shared':
specifier: workspace:*
version: link:../shared
zod:
specifier: ^3.24.2
version: 3.25.76
specifier: ^4.4.3
version: 4.4.3
devDependencies:
'@types/node':
specifier: ^22.20.1
@ -703,8 +703,8 @@ importers:
specifier: ^19.2.8
version: 19.2.8
zod:
specifier: ^3.24.2
version: 3.25.76
specifier: ^4.4.3
version: 4.4.3
devDependencies:
'@types/node':
specifier: ^22.20.1
@ -719,8 +719,8 @@ importers:
packages/shared:
dependencies:
zod:
specifier: ^3.24.2
version: 3.25.76
specifier: ^4.4.3
version: 4.4.3
devDependencies:
'@types/node':
specifier: ^22.20.1
@ -871,8 +871,8 @@ importers:
specifier: ^8.21.3
version: 8.21.3
zod:
specifier: ^3.24.2
version: 3.25.76
specifier: ^4.4.3
version: 4.4.3
devDependencies:
'@types/express':
specifier: ^5.0.0
@ -9546,7 +9546,7 @@ snapshots:
optionalDependencies:
'@types/react': 19.2.18
'@better-auth/core@1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@3.25.76))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0)':
'@better-auth/core@1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0)':
dependencies:
'@better-auth/utils': 0.4.2
'@better-fetch/fetch': 1.3.1
@ -9560,38 +9560,38 @@ snapshots:
optionalDependencies:
'@opentelemetry/api': 1.9.1
'@better-auth/drizzle-adapter@1.6.28(@better-auth/core@1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@3.25.76))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)(drizzle-orm@0.45.2(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.1)(kysely@0.29.5)(pg@8.18.0)(postgres@3.4.9)(sqlite3@5.1.7))':
'@better-auth/drizzle-adapter@1.6.28(@better-auth/core@1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)(drizzle-orm@0.45.2(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.1)(kysely@0.29.5)(pg@8.18.0)(postgres@3.4.9)(sqlite3@5.1.7))':
dependencies:
'@better-auth/core': 1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@3.25.76))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0)
'@better-auth/core': 1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0)
'@better-auth/utils': 0.4.2
optionalDependencies:
drizzle-orm: 0.45.2(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.1)(kysely@0.29.5)(pg@8.18.0)(postgres@3.4.9)(sqlite3@5.1.7)
'@better-auth/kysely-adapter@1.6.28(@better-auth/core@1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@3.25.76))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)(kysely@0.29.5)':
'@better-auth/kysely-adapter@1.6.28(@better-auth/core@1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)(kysely@0.29.5)':
dependencies:
'@better-auth/core': 1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@3.25.76))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0)
'@better-auth/core': 1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0)
'@better-auth/utils': 0.4.2
optionalDependencies:
kysely: 0.29.5
'@better-auth/memory-adapter@1.6.28(@better-auth/core@1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@3.25.76))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)':
'@better-auth/memory-adapter@1.6.28(@better-auth/core@1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)':
dependencies:
'@better-auth/core': 1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@3.25.76))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0)
'@better-auth/core': 1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0)
'@better-auth/utils': 0.4.2
'@better-auth/mongo-adapter@1.6.28(@better-auth/core@1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@3.25.76))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)':
'@better-auth/mongo-adapter@1.6.28(@better-auth/core@1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)':
dependencies:
'@better-auth/core': 1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@3.25.76))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0)
'@better-auth/core': 1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0)
'@better-auth/utils': 0.4.2
'@better-auth/prisma-adapter@1.6.28(@better-auth/core@1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@3.25.76))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)':
'@better-auth/prisma-adapter@1.6.28(@better-auth/core@1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)':
dependencies:
'@better-auth/core': 1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@3.25.76))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0)
'@better-auth/core': 1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0)
'@better-auth/utils': 0.4.2
'@better-auth/telemetry@1.6.28(@better-auth/core@1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@3.25.76))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)':
'@better-auth/telemetry@1.6.28(@better-auth/core@1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)':
dependencies:
'@better-auth/core': 1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@3.25.76))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0)
'@better-auth/core': 1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0)
'@better-auth/utils': 0.4.2
'@better-fetch/fetch': 1.3.1
@ -11110,6 +11110,28 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@modelcontextprotocol/sdk@1.30.0(zod@4.4.3)':
dependencies:
'@hono/node-server': 2.1.0(hono@4.13.2)
ajv: 8.20.0
ajv-formats: 3.0.1(ajv@8.20.0)
content-type: 1.0.5
cors: 2.8.6
cross-spawn: 7.0.6
eventsource: 3.0.7
eventsource-parser: 3.1.1
express: 5.2.1
express-rate-limit: 8.6.2(express@5.2.1)
hono: 4.13.2
jose: 6.2.8
json-schema-typed: 8.0.2
pkce-challenge: 5.0.1
raw-body: 3.0.2
zod: 4.4.3
zod-to-json-schema: 3.25.2(zod@4.4.3)
transitivePeerDependencies:
- supports-color
'@napi-rs/lzma-linux-x64-gnu@1.5.1':
optional: true
@ -13697,13 +13719,13 @@ snapshots:
better-auth@1.6.28(@opentelemetry/api@1.9.1)(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.1)(kysely@0.29.5)(pg@8.18.0)(postgres@3.4.9)(sqlite3@5.1.7))(pg@8.18.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(vitest@4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(jsdom@30.0.1(@noble/hashes@2.3.0))(vite@6.4.3(@types/node@22.20.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.12))):
dependencies:
'@better-auth/core': 1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@3.25.76))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0)
'@better-auth/drizzle-adapter': 1.6.28(@better-auth/core@1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@3.25.76))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)(drizzle-orm@0.45.2(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.1)(kysely@0.29.5)(pg@8.18.0)(postgres@3.4.9)(sqlite3@5.1.7))
'@better-auth/kysely-adapter': 1.6.28(@better-auth/core@1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@3.25.76))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)(kysely@0.29.5)
'@better-auth/memory-adapter': 1.6.28(@better-auth/core@1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@3.25.76))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)
'@better-auth/mongo-adapter': 1.6.28(@better-auth/core@1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@3.25.76))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)
'@better-auth/prisma-adapter': 1.6.28(@better-auth/core@1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@3.25.76))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)
'@better-auth/telemetry': 1.6.28(@better-auth/core@1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@3.25.76))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)
'@better-auth/core': 1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0)
'@better-auth/drizzle-adapter': 1.6.28(@better-auth/core@1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)(drizzle-orm@0.45.2(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.1)(kysely@0.29.5)(pg@8.18.0)(postgres@3.4.9)(sqlite3@5.1.7))
'@better-auth/kysely-adapter': 1.6.28(@better-auth/core@1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)(kysely@0.29.5)
'@better-auth/memory-adapter': 1.6.28(@better-auth/core@1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)
'@better-auth/mongo-adapter': 1.6.28(@better-auth/core@1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)
'@better-auth/prisma-adapter': 1.6.28(@better-auth/core@1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)
'@better-auth/telemetry': 1.6.28(@better-auth/core@1.6.28(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.4.3))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)
'@better-auth/utils': 0.4.2
'@better-fetch/fetch': 1.3.1
'@noble/ciphers': 2.3.0
@ -17660,6 +17682,10 @@ snapshots:
dependencies:
zod: 3.25.76
zod-to-json-schema@3.25.2(zod@4.4.3):
dependencies:
zod: 4.4.3
zod@3.25.76: {}
zod@4.4.3: {}

View File

@ -80,7 +80,7 @@
"sharp": "^0.35.3",
"ssh2": "^1.17.0",
"ws": "^8.21.3",
"zod": "^3.24.2"
"zod": "^4.4.3"
},
"devDependencies": {
"@types/express": "^5.0.0",

View File

@ -95,17 +95,17 @@ const createActivitySchema = z.object({
action: z.string().min(1),
entityType: z.string().min(1),
entityId: z.string().min(1),
agentId: z.string().uuid().optional().nullable(),
details: z.record(z.unknown()).optional().nullable(),
agentId: z.string().guid().optional().nullable(),
details: z.record(z.string(), z.unknown()).optional().nullable(),
});
const agentActionAuditActorScopeSchema = z.enum(["agents", "all"]);
const agentActionAuditQuerySchema = z.object({
actorScope: agentActionAuditActorScopeSchema.default("agents"),
agentId: z.string().uuid().optional(),
agentId: z.string().guid().optional(),
responsibleUserId: z.string().min(1).optional(),
runId: z.string().uuid().optional(),
runId: z.string().guid().optional(),
entityType: z.string().min(1).optional(),
entityId: z.string().min(1).optional(),
action: z.string().min(1).optional(),

View File

@ -48,29 +48,29 @@ const caseKeySchema = z.string().trim().min(1).max(512);
const documentKeySchema = z.string().trim().min(1).max(120).regex(/^[A-Za-z0-9_.:-]+$/);
const createCaseSchema = z.object({
projectId: z.string().uuid().nullable().optional(),
projectId: z.string().guid().nullable().optional(),
caseType: caseTypeSchema,
key: caseKeySchema.nullable().optional(),
title: z.string().trim().min(1).max(500),
summary: z.string().max(8_000).nullable().optional(),
status: caseStatusSchema.optional(),
fields: jsonObjectSchema.optional(),
parentCaseId: z.string().uuid().nullable().optional(),
parentCaseId: z.string().guid().nullable().optional(),
}).strict();
const patchCaseSchema = z.object({
projectId: z.string().uuid().nullable().optional(),
projectId: z.string().guid().nullable().optional(),
title: z.string().trim().min(1).max(500).optional(),
summary: z.string().max(8_000).nullable().optional(),
status: caseStatusSchema.optional(),
fields: jsonObjectSchema.optional(),
parentCaseId: z.string().uuid().nullable().optional(),
labels: z.array(z.string().uuid()).max(100).optional(),
labelIds: z.array(z.string().uuid()).max(100).optional(),
parentCaseId: z.string().guid().nullable().optional(),
labels: z.array(z.string().guid()).max(100).optional(),
labelIds: z.array(z.string().guid()).max(100).optional(),
}).strict();
const createIssueLinkSchema = z.object({
issueId: z.string().uuid(),
issueId: z.string().guid(),
role: z.enum(CASE_LINK_ROLES),
}).strict();
@ -79,7 +79,7 @@ const upsertCaseDocumentSchema = z.object({
format: z.string().trim().min(1).max(80).optional().default("markdown"),
body: z.string().max(200_000),
changeSummary: z.string().trim().max(1_000).nullable().optional(),
baseRevisionId: z.string().uuid().nullable().optional(),
baseRevisionId: z.string().guid().nullable().optional(),
}).strict();
const queryListParamSchema = z.union([z.string(), z.array(z.string())]).optional();
@ -89,13 +89,13 @@ const listCasesQuerySchema = z.object({
types: queryListParamSchema,
status: z.string().trim().min(1).max(120).optional(),
statuses: queryListParamSchema,
project: z.string().uuid().optional(),
projectId: z.string().uuid().optional(),
project: z.string().guid().optional(),
projectId: z.string().guid().optional(),
projectIds: queryListParamSchema,
includeNoProject: z.enum(["true", "false", "1", "0"]).optional(),
label: z.string().uuid().optional(),
labelId: z.string().uuid().optional(),
parent: z.string().uuid().optional(),
label: z.string().guid().optional(),
labelId: z.string().guid().optional(),
parent: z.string().guid().optional(),
q: z.string().trim().min(1).max(200).optional(),
includeAncestors: z.enum(["true", "false", "1", "0"]).optional(),
limit: z.coerce.number().int().min(1).max(200).optional().default(100),

View File

@ -316,9 +316,9 @@ export function companyRoutes(db: Db, storage?: StorageService, options?: Compan
from: z.string().optional(),
to: z.string().optional(),
userId: z.string().min(1).optional(),
goalId: z.string().uuid().optional(),
projectId: z.string().uuid().optional(),
issueId: z.string().uuid().optional(),
goalId: z.string().guid().optional(),
projectId: z.string().guid().optional(),
issueId: z.string().guid().optional(),
limit: z.string().optional(),
offset: z.string().optional(),
}).passthrough();

View File

@ -6,18 +6,18 @@ import { decisionTrainingService, logActivity } from "../services/index.js";
import { assertBoard, assertCompanyAccess, getActorInfo, hasCompanyAccess } from "./authz.js";
const sourceKindSchema = z.enum(["interaction", "approval", "execution_decision"]);
const exampleIdSchema = z.string().uuid();
const exampleIdSchema = z.string().guid();
const createSchema = z.object({
sourceKind: sourceKindSchema,
sourceId: z.string().uuid(),
issueId: z.string().uuid(),
sourceId: z.string().guid(),
issueId: z.string().guid(),
notes: z.string().max(100_000).default(""),
}).strict();
const updateSchema = z.object({ notes: z.string().max(100_000) }).strict();
const previewSchema = z.object({
sourceKind: sourceKindSchema,
sourceId: z.string().uuid(),
issueId: z.string().uuid(),
sourceId: z.string().guid(),
issueId: z.string().guid(),
}).strict();
function requireHumanUser(req: Request, res: Response) {
@ -116,7 +116,7 @@ export function decisionTrainingRoutes(db: Db) {
assertBoard(req);
assertCompanyAccess(req, companyId);
const parsed = z.object({
project: z.string().uuid().optional(),
project: z.string().guid().optional(),
kind: sourceKindSchema.optional(),
author: z.string().optional(),
q: z.string().trim().max(500).optional(),

View File

@ -28,14 +28,14 @@ const createSchema = z.object({
expiresAt: z.coerce.date().optional(),
idempotencyKey: z.string().trim().min(1).max(500).nullable().optional(),
continuationPolicy: z.enum(["none", "wake_origin_agent"]).optional(),
metadata: z.record(z.unknown()).optional(),
metadata: z.record(z.string(), z.unknown()).optional(),
}).strict();
const bundleSchema = z.object({ title: z.string().trim().min(1).max(500), summary: z.string().max(100_000), decisions: z.array(createSchema).min(1).max(50) }).strict();
const decideSchema = z.object({ optionId: z.string().trim().min(1).max(120), inputValues: z.record(z.string().max(20_000)).optional(), idempotencyKey: z.string().trim().min(1).max(500).nullable().optional() }).strict();
const decideSchema = z.object({ optionId: z.string().trim().min(1).max(120), inputValues: z.record(z.string(), z.string().max(20_000)).optional(), idempotencyKey: z.string().trim().min(1).max(500).nullable().optional() }).strict();
const dismissSchema = z.object({ reason: z.string().max(20_000).nullable().optional() }).strict();
const statsQuerySchema = z.object({
groupBy: z.literal("ruleKey"),
originAgentId: z.string().uuid().optional(),
originAgentId: z.string().guid().optional(),
since: z.coerce.date().optional(),
}).strict();
@ -147,7 +147,7 @@ export function decisionRoutes(db: Db, options: DecisionServiceOptions) {
});
router.get("/companies/:companyId/decisions", async (req, res) => {
const companyId = req.params.companyId as string; assertBoard(req); assertCompanyAccess(req, companyId);
const query = z.object({ status: z.enum(["open", "decided", "expired", "cancelled"]).optional(), bundleId: z.string().uuid().optional(), targetIssueId: z.string().uuid().optional(), originAgentId: z.string().uuid().optional(), limit: z.coerce.number().int().positive().max(100).optional() }).safeParse(req.query);
const query = z.object({ status: z.enum(["open", "decided", "expired", "cancelled"]).optional(), bundleId: z.string().guid().optional(), targetIssueId: z.string().guid().optional(), originAgentId: z.string().guid().optional(), limit: z.coerce.number().int().positive().max(100).optional() }).safeParse(req.query);
if (!query.success) { res.status(400).json({ error: "Invalid decision filters", details: query.error.flatten() }); return; }
res.json(await svc.list(companyId, query.data));
});

View File

@ -171,7 +171,7 @@ function readQuery(query: unknown) {
parsed = workspaceFileResourceQuerySchema.parse(query);
} catch (error) {
if (error instanceof ZodError) {
const refinement = error.errors.find((issue) => {
const refinement = error.issues.find((issue) => {
const code = (issue as { params?: { code?: string } }).params?.code;
return code === "invalid_path" || code === "invalid_target";
});
@ -194,7 +194,7 @@ function readListQuery(query: unknown) {
parsed = workspaceFileListQuerySchema.parse(query);
} catch (error) {
if (error instanceof ZodError) {
const refinement = error.errors.find((issue) => {
const refinement = error.issues.find((issue) => {
const code = (issue as { params?: { code?: string } }).params?.code;
return code === "invalid_query" || code === "invalid_target" || code === "invalid_path";
});

View File

@ -265,18 +265,18 @@ function prefersMinimalIssueUpdateResponse(req: Request) {
}
const refreshExternalObjectsSchema = z.object({
objectIds: z.array(z.string().uuid()).max(50).optional(),
objectIds: z.array(z.string().guid()).max(50).optional(),
}).strict();
const inboxArchiveBodySchema = z.object({
userId: z.string().trim().min(1).optional(),
}).strict().default({});
const externalObjectSummariesSchema = z.object({
issueIds: z.array(z.string().uuid()).max(1000),
issueIds: z.array(z.string().guid()).max(1000),
}).strict();
const promoteLowTrustOutputSchema = z.object({
sourceArtifactKind: z.enum(["comment", "document", "work_product", "issue"]),
sourceArtifactId: z.string().uuid(),
sourceArtifactId: z.string().guid(),
title: z.string().trim().min(1).max(200),
summary: z.string().trim().min(1).max(8_000),
});
@ -460,7 +460,7 @@ function requiresPaperclipAttachmentMetadata(input: {
}
const attachmentArtifactMetadataInputSchema = z.object({
attachmentId: z.string().uuid(),
attachmentId: z.string().guid(),
}).passthrough();
function buildCreateIssueActivityStatusDetails(

View File

@ -255,148 +255,183 @@ type OpenApiPathRegistration = {
[key: string]: unknown;
};
const zodTypeName = (schema: z.ZodTypeAny) => schema._def.typeName as string;
// Zod 4 stores each schema definition on `_def` with a lowercase `type`
// discriminator and moves the wrapped members onto that def. This loose view
// lets the converter read those members, because Zod 4 does not export a
// public type for every internal def shape.
type ZodDefAny = Record<string, unknown> & { type: string };
const zodDef = (schema: z.ZodTypeAny): ZodDefAny => schema._def as unknown as ZodDefAny;
const zodTypeName = (schema: z.ZodTypeAny): string => zodDef(schema).type;
function unwrapSchema(schema: z.ZodTypeAny): z.ZodTypeAny {
const typeName = zodTypeName(schema);
if (typeName === "ZodOptional" || typeName === "ZodDefault" || typeName === "ZodCatch") {
return unwrapSchema(schema._def.innerType);
const def = zodDef(schema);
if (def.type === "optional" || def.type === "default" || def.type === "catch") {
return unwrapSchema(def.innerType as z.ZodTypeAny);
}
if (typeName === "ZodEffects") {
return unwrapSchema(schema._def.schema);
// A `.transform()` or `.pipe()` becomes a pipe. Read the input schema so the
// published contract describes the value a client sends.
if (def.type === "pipe") {
return unwrapSchema(def.in as z.ZodTypeAny);
}
return schema;
}
function isOptionalSchema(schema: z.ZodTypeAny): boolean {
const typeName = zodTypeName(schema);
if (typeName === "ZodOptional" || typeName === "ZodDefault" || typeName === "ZodCatch") {
const def = zodDef(schema);
if (def.type === "optional" || def.type === "default" || def.type === "catch") {
return true;
}
if (typeName === "ZodEffects") {
return isOptionalSchema(schema._def.schema);
if (def.type === "pipe") {
return isOptionalSchema(def.in as z.ZodTypeAny);
}
if (typeName === "ZodNullable") {
return isOptionalSchema(schema._def.innerType);
if (def.type === "nullable") {
return isOptionalSchema(def.innerType as z.ZodTypeAny);
}
return false;
}
function applyStringChecks(jsonSchema: JsonSchema, checks: Array<Record<string, unknown>>) {
// Zod 4 stores each check as an object with a `_zod.def` that carries a `check`
// name and the check members. Read that def to describe the constraint.
function checkDef(check: unknown): Record<string, unknown> | undefined {
return (check as { _zod?: { def?: Record<string, unknown> } })._zod?.def;
}
function applyStringChecks(jsonSchema: JsonSchema, checks: ReadonlyArray<unknown>) {
for (const check of checks) {
if (check.kind === "min") jsonSchema.minLength = check.value;
if (check.kind === "max") jsonSchema.maxLength = check.value;
if (check.kind === "email") jsonSchema.format = "email";
if (check.kind === "url") jsonSchema.format = "uri";
if (check.kind === "uuid") jsonSchema.format = "uuid";
if (check.kind === "datetime") jsonSchema.format = "date-time";
if (check.kind === "regex" && check.regex instanceof RegExp) {
jsonSchema.pattern = check.regex.source;
const def = checkDef(check);
if (!def) continue;
if (def.check === "min_length") jsonSchema.minLength = def.minimum;
else if (def.check === "max_length") jsonSchema.maxLength = def.maximum;
else if (def.check === "string_format") {
if (def.format === "email") jsonSchema.format = "email";
else if (def.format === "url") jsonSchema.format = "uri";
// Zod 3 `.uuid()` maps to `.guid()` in zod 4 to keep the loose UUID
// format. Publish both as the OpenAPI `uuid` format so the spec does not
// change.
else if (def.format === "uuid" || def.format === "guid") jsonSchema.format = "uuid";
else if (def.format === "datetime") jsonSchema.format = "date-time";
// Zod 4 stores a `.regex()` pattern as a `RegExp`; publish its source.
else if (def.format === "regex") {
if (def.pattern instanceof RegExp) jsonSchema.pattern = def.pattern.source;
else if (typeof def.pattern === "string") jsonSchema.pattern = def.pattern;
}
}
}
}
function applyNumberChecks(jsonSchema: JsonSchema, checks: Array<Record<string, unknown>>) {
function applyNumberChecks(jsonSchema: JsonSchema, checks: ReadonlyArray<unknown>) {
for (const check of checks) {
if (check.kind === "int") jsonSchema.type = "integer";
if (check.kind === "min") {
jsonSchema.minimum = check.value;
if (!check.inclusive) jsonSchema.exclusiveMinimum = true;
}
if (check.kind === "max") {
jsonSchema.maximum = check.value;
if (!check.inclusive) jsonSchema.exclusiveMaximum = true;
const def = checkDef(check);
if (!def) continue;
// `.int()` records a number-format check such as `safeint`.
if (def.check === "number_format") {
if (typeof def.format === "string" && def.format.includes("int")) {
jsonSchema.type = "integer";
}
} else if (def.check === "greater_than") {
jsonSchema.minimum = def.value;
if (!def.inclusive) jsonSchema.exclusiveMinimum = true;
} else if (def.check === "less_than") {
jsonSchema.maximum = def.value;
if (!def.inclusive) jsonSchema.exclusiveMaximum = true;
}
}
}
function zodToOpenApiSchema(schema: z.ZodTypeAny): JsonSchema {
const unwrapped = unwrapSchema(schema);
const typeName = zodTypeName(unwrapped);
const def = zodDef(unwrapped);
const typeName = def.type;
if (typeName === "ZodString") {
if (typeName === "string") {
const jsonSchema: JsonSchema = { type: "string" };
applyStringChecks(jsonSchema, unwrapped._def.checks ?? []);
applyStringChecks(jsonSchema, (def.checks as unknown[]) ?? []);
return jsonSchema;
}
if (typeName === "ZodNumber") {
if (typeName === "number") {
const jsonSchema: JsonSchema = { type: "number" };
applyNumberChecks(jsonSchema, unwrapped._def.checks ?? []);
applyNumberChecks(jsonSchema, (def.checks as unknown[]) ?? []);
return jsonSchema;
}
if (typeName === "ZodBoolean") return { type: "boolean" };
if (typeName === "ZodDate") return { type: "string", format: "date-time" };
if (typeName === "ZodAny" || typeName === "ZodUnknown") return {};
if (typeName === "boolean") return { type: "boolean" };
if (typeName === "date") return { type: "string", format: "date-time" };
if (typeName === "any" || typeName === "unknown") return {};
if (typeName === "ZodLiteral") {
const value = unwrapped._def.value;
return { type: typeof value, enum: [value] };
if (typeName === "literal") {
const values = def.values as unknown[];
return { type: typeof values[0], enum: values };
}
if (typeName === "ZodEnum") {
return { type: "string", enum: unwrapped._def.values };
}
if (typeName === "ZodNativeEnum") {
const values = Object.values(unwrapped._def.values).filter(
(value) => typeof value === "string" || typeof value === "number",
// Zod 4 merges string enums and native enums into one `enum` type and stores
// the members on `entries`. A pure string enum keeps `type: "string"`; a
// native enum can hold numbers, so it publishes the values without a type.
if (typeName === "enum") {
const values = Array.from(
new Set(
Object.values(def.entries as Record<string, unknown>).filter(
(value) => typeof value === "string" || typeof value === "number",
),
),
);
return { enum: Array.from(new Set(values)) };
if (values.every((value) => typeof value === "string")) {
return { type: "string", enum: values };
}
return { enum: values };
}
if (typeName === "ZodArray") {
return { type: "array", items: zodToOpenApiSchema(unwrapped._def.type) };
if (typeName === "array") {
return { type: "array", items: zodToOpenApiSchema(def.element as z.ZodTypeAny) };
}
if (typeName === "ZodRecord") {
if (typeName === "record") {
return {
type: "object",
additionalProperties: zodToOpenApiSchema(unwrapped._def.valueType),
additionalProperties: zodToOpenApiSchema(def.valueType as z.ZodTypeAny),
};
}
if (typeName === "ZodNullable") {
return { ...zodToOpenApiSchema(unwrapped._def.innerType), nullable: true };
if (typeName === "nullable") {
return { ...zodToOpenApiSchema(def.innerType as z.ZodTypeAny), nullable: true };
}
if (typeName === "ZodUnion") {
return { oneOf: unwrapped._def.options.map((option: z.ZodTypeAny) => zodToOpenApiSchema(option)) };
}
if (typeName === "ZodDiscriminatedUnion") {
// Zod 4 represents a plain union and a discriminated union as one `union`
// type with the members on `options`.
if (typeName === "union") {
return {
oneOf: Array.from(unwrapped._def.options.values()).map((option) =>
zodToOpenApiSchema(option as z.ZodTypeAny),
),
oneOf: (def.options as z.ZodTypeAny[]).map((option) => zodToOpenApiSchema(option)),
};
}
if (typeName === "ZodIntersection") {
if (typeName === "intersection") {
return {
allOf: [
zodToOpenApiSchema(unwrapped._def.left),
zodToOpenApiSchema(unwrapped._def.right),
zodToOpenApiSchema(def.left as z.ZodTypeAny),
zodToOpenApiSchema(def.right as z.ZodTypeAny),
],
};
}
if (typeName === "ZodObject") {
const shape = unwrapped._def.shape();
if (typeName === "object") {
const shape = def.shape as Record<string, z.ZodTypeAny>;
const properties: Record<string, JsonSchema> = {};
const required: string[] = [];
for (const [key, value] of Object.entries(shape)) {
const propertySchema = value as z.ZodTypeAny;
properties[key] = zodToOpenApiSchema(propertySchema);
if (!isOptionalSchema(propertySchema)) required.push(key);
properties[key] = zodToOpenApiSchema(value);
if (!isOptionalSchema(value)) required.push(key);
}
const jsonSchema: JsonSchema = { type: "object", properties };
if (required.length > 0) jsonSchema.required = required;
// A `.strict()` Zod object forbids an unknown key. Publish that constraint
// as `additionalProperties: false`, so a client, a gateway, or a handler
// that treats the contract as authoritative rejects an extra property too.
if (unwrapped._def.unknownKeys === "strict") jsonSchema.additionalProperties = false;
// A `.strict()` Zod object forbids an unknown key. Zod 4 records that as a
// `never` catchall. Publish the constraint as `additionalProperties: false`,
// so a client, a gateway, or a handler that treats the contract as
// authoritative rejects an extra property too.
const catchall = def.catchall as z.ZodTypeAny | undefined;
if (catchall && zodDef(catchall).type === "never") {
jsonSchema.additionalProperties = false;
}
return jsonSchema;
}
@ -445,13 +480,13 @@ function normalizeResponses(responses: Record<string, OpenApiResponse> = {}) {
function parametersFromSchema(schema: z.ZodTypeAny, location: "path" | "query") {
const objectSchema = unwrapSchema(schema);
if (zodTypeName(objectSchema) !== "ZodObject") return [];
const shape = objectSchema._def.shape();
if (zodTypeName(objectSchema) !== "object") return [];
const shape = zodDef(objectSchema).shape as Record<string, z.ZodTypeAny>;
return Object.entries(shape).map(([name, value]) => ({
name,
in: location,
required: location === "path" ? true : !isOptionalSchema(value as z.ZodTypeAny),
schema: zodToOpenApiSchema(value as z.ZodTypeAny),
required: location === "path" ? true : !isOptionalSchema(value),
schema: zodToOpenApiSchema(value),
}));
}
@ -511,7 +546,7 @@ const ErrorSchema = registry.register(
);
const responses = {
ok: (schema: z.ZodTypeAny = z.record(z.unknown())) => ({
ok: (schema: z.ZodTypeAny = z.record(z.string(), z.unknown())) => ({
description: "Success",
content: { "application/json": { schema } },
}),
@ -600,11 +635,11 @@ const importRequestBody = (schema: z.ZodTypeAny) => ({
const r = responses;
const externalObjectSummariesBodySchema = z.object({
issueIds: z.array(z.string().uuid()).max(1000),
issueIds: z.array(z.string().guid()).max(1000),
}).strict();
const refreshExternalObjectsBodySchema = z.object({
objectIds: z.array(z.string().uuid()).max(50).optional(),
objectIds: z.array(z.string().guid()).max(50).optional(),
}).strict();
// The start route reads the body directly, so document the accepted fields
@ -653,9 +688,9 @@ const workTimelineQuerySchema = z.object({
from: z.string().optional(),
to: z.string().optional(),
userId: z.string().optional(),
goalId: z.string().uuid().optional(),
projectId: z.string().uuid().optional(),
issueId: z.string().uuid().optional(),
goalId: z.string().guid().optional(),
projectId: z.string().guid().optional(),
issueId: z.string().guid().optional(),
limit: z.string().optional(),
offset: z.string().optional(),
}).strict();
@ -709,7 +744,7 @@ const workTimelineResponseSchema = z.object({
function paramsSchemaFromPath(routePath: string): z.ZodObject<z.ZodRawShape> | undefined {
const names = [...routePath.matchAll(/\{([A-Za-z0-9_]+)\}/g)].map((match) => match[1]);
if (names.length === 0) return undefined;
const shape: z.ZodRawShape = {};
const shape: Record<string, z.ZodTypeAny> = {};
for (const name of names) {
shape[name] = z.string();
}
@ -1713,7 +1748,7 @@ registry.registerPath({
const AgentSecretListResponseSchema = z.object({
secrets: z.array(z.object({
secretRef: z.string().uuid(),
secretRef: z.string().guid(),
key: z.string(),
name: z.string(),
description: z.string().nullable(),
@ -1735,10 +1770,10 @@ const createAgentSecretProposalSchema = z.discriminatedUnion("kind", [
}),
z.object({
kind: z.literal("binding"),
secretId: z.string().uuid().optional(),
secretId: z.string().guid().optional(),
sourceConfigPath: z.string().min(1).optional(),
secretProposalId: z.string().uuid().optional(),
targetAgentId: z.string().uuid().optional(),
secretProposalId: z.string().guid().optional(),
targetAgentId: z.string().guid().optional(),
configPath: z.string().min(1),
justification: z.string().min(1),
}),
@ -1760,7 +1795,7 @@ const approveSecretProposalSchema = z.object({
overrides: z.object({
name: z.string().min(1).optional(),
description: z.string().optional().nullable(),
providerConfigId: z.string().uuid().optional().nullable(),
providerConfigId: z.string().guid().optional().nullable(),
}).optional(),
});
@ -1788,7 +1823,7 @@ registry.registerPath({
path: "/api/agents/me/secret-proposals/{id}",
tags: ["secrets"],
summary: "Withdraw a pending secret proposal",
request: { params: z.object({ id: z.string().uuid() }) },
request: { params: z.object({ id: z.string().guid() }) },
responses: { 200: r.ok(), 401: r.unauthorized, 403: r.forbidden, 404: r.notFound, 409: r.conflict },
});
@ -3026,7 +3061,7 @@ registry.registerPath({
tags: ["secrets"],
summary: "List company secret proposals for board review",
request: {
params: z.object({ companyId: z.string().uuid() }),
params: z.object({ companyId: z.string().guid() }),
query: z.object({ status: z.enum(["pending", "approved", "rejected", "withdrawn", "expired"]).optional() }),
},
responses: { 200: r.ok(), 401: r.unauthorized, 403: r.forbidden },
@ -3038,7 +3073,7 @@ registry.registerPath({
tags: ["secrets"],
summary: "Approve and execute a secret proposal as the approving board user",
request: {
params: z.object({ companyId: z.string().uuid(), id: z.string().uuid() }),
params: z.object({ companyId: z.string().guid(), id: z.string().guid() }),
body: jsonBody(approveSecretProposalSchema),
},
responses: { 200: r.ok(), 400: r.badRequest, 401: r.unauthorized, 403: r.forbidden, 404: r.notFound, 409: r.conflict, 422: r.unprocessable },
@ -3050,7 +3085,7 @@ registry.registerPath({
tags: ["secrets"],
summary: "Reject a pending secret proposal and dependent bindings",
request: {
params: z.object({ companyId: z.string().uuid(), id: z.string().uuid() }),
params: z.object({ companyId: z.string().guid(), id: z.string().guid() }),
body: jsonBody(rejectSecretProposalSchema),
},
responses: { 200: r.ok(), 400: r.badRequest, 401: r.unauthorized, 403: r.forbidden, 404: r.notFound, 409: r.conflict, 422: r.unprocessable },
@ -3423,9 +3458,9 @@ registry.registerPath({
request: {
params: z.object({ companyId: z.string() }),
query: z.object({
agentId: z.string().uuid().optional(),
agentId: z.string().guid().optional(),
responsibleUserId: z.string().min(1).optional(),
runId: z.string().uuid().optional(),
runId: z.string().guid().optional(),
entityType: z.string().min(1).optional(),
entityId: z.string().min(1).optional(),
action: z.string().min(1).optional(),
@ -3447,9 +3482,9 @@ registry.registerPath({
request: {
params: z.object({ companyId: z.string() }),
query: z.object({
agentId: z.string().uuid().optional(),
agentId: z.string().guid().optional(),
responsibleUserId: z.string().min(1).optional(),
runId: z.string().uuid().optional(),
runId: z.string().guid().optional(),
entityType: z.string().min(1).optional(),
entityId: z.string().min(1).optional(),
action: z.string().min(1).optional(),
@ -3484,8 +3519,8 @@ registry.registerPath({
action: z.string().min(1),
entityType: z.string().min(1),
entityId: z.string().min(1),
agentId: z.string().uuid().optional().nullable(),
details: z.record(z.unknown()).optional().nullable(),
agentId: z.string().guid().optional().nullable(),
details: z.record(z.string(), z.unknown()).optional().nullable(),
})),
},
responses: { 200: r.ok(), 400: r.badRequest, 401: r.unauthorized },
@ -3850,9 +3885,9 @@ registerCurrentRoute({
summary: "List decisions",
query: z.object({
status: z.enum(["open", "decided", "expired", "cancelled"]).optional(),
bundleId: z.string().uuid().optional(),
targetIssueId: z.string().uuid().optional(),
originAgentId: z.string().uuid().optional(),
bundleId: z.string().guid().optional(),
targetIssueId: z.string().guid().optional(),
originAgentId: z.string().guid().optional(),
limit: z.coerce.number().int().positive().max(100).optional(),
}),
responses: { 200: r.ok(), 400: r.badRequest, 401: r.unauthorized, 403: r.forbidden },
@ -3865,7 +3900,7 @@ registerCurrentRoute({
summary: "Get decision telemetry grouped by rule key",
query: z.object({
groupBy: z.literal("ruleKey"),
originAgentId: z.string().uuid().optional(),
originAgentId: z.string().guid().optional(),
since: z.string().datetime().optional(),
}),
responses: { 200: r.ok(), 400: r.badRequest, 401: r.unauthorized, 403: r.forbidden },
@ -3920,8 +3955,8 @@ registerCurrentRoute({
summary: "Capture a decision training example",
body: z.object({
sourceKind: decisionTrainingSourceKindSchema,
sourceId: z.string().uuid(),
issueId: z.string().uuid(),
sourceId: z.string().guid(),
issueId: z.string().guid(),
notes: z.string().max(100_000).default(""),
}).strict(),
responses: { 201: r.ok(), 400: r.badRequest, 401: r.unauthorized, 403: r.forbidden, 404: r.notFound, 409: r.conflict },
@ -3934,8 +3969,8 @@ registerCurrentRoute({
summary: "Preview a decision training snapshot",
body: z.object({
sourceKind: decisionTrainingSourceKindSchema,
sourceId: z.string().uuid(),
issueId: z.string().uuid(),
sourceId: z.string().guid(),
issueId: z.string().guid(),
}).strict(),
responses: { 200: r.ok(), 400: r.badRequest, 401: r.unauthorized, 403: r.forbidden, 404: r.notFound, 409: r.conflict },
});
@ -3946,7 +3981,7 @@ registerCurrentRoute({
tags: ["decision-training"],
summary: "List decision training examples",
query: z.object({
project: z.string().uuid().optional(),
project: z.string().guid().optional(),
kind: decisionTrainingSourceKindSchema.optional(),
author: z.string().optional(),
q: z.string().max(500).optional(),
@ -5813,7 +5848,7 @@ registry.registerPath({
request: {
body: jsonBody(z.object({
tool: z.string(),
parameters: z.record(z.unknown()).optional(),
parameters: z.record(z.string(), z.unknown()).optional(),
runContext: z.object({
agentId: z.string(),
runId: z.string(),
@ -5922,7 +5957,7 @@ registry.registerPath({
summary: "Set company-scoped plugin config",
request: {
params: z.object({ pluginId: z.string() }),
body: jsonBody(z.object({ companyId: z.string(), configJson: z.record(z.unknown()) })),
body: jsonBody(z.object({ companyId: z.string(), configJson: z.record(z.string(), z.unknown()) })),
},
responses: { 200: r.ok(), 400: r.badRequest, 401: r.unauthorized },
});
@ -5934,7 +5969,7 @@ registry.registerPath({
summary: "Test company-scoped plugin config",
request: {
params: z.object({ pluginId: z.string() }),
body: jsonBody(z.object({ companyId: z.string(), configJson: z.record(z.unknown()) })),
body: jsonBody(z.object({ companyId: z.string(), configJson: z.record(z.string(), z.unknown()) })),
},
responses: { 200: r.ok(), 400: r.badRequest, 401: r.unauthorized },
});
@ -5996,7 +6031,7 @@ registry.registerPath({
body: jsonBody(z.object({
key: z.string(),
companyId: z.string().optional(),
params: z.record(z.unknown()).optional(),
params: z.record(z.string(), z.unknown()).optional(),
})),
},
responses: { 200: r.ok(), 401: r.unauthorized },
@ -6012,7 +6047,7 @@ registry.registerPath({
body: jsonBody(z.object({
key: z.string(),
companyId: z.string().optional(),
params: z.record(z.unknown()).optional(),
params: z.record(z.string(), z.unknown()).optional(),
})),
},
responses: { 200: r.ok(), 401: r.unauthorized },
@ -6027,7 +6062,7 @@ registry.registerPath({
params: z.object({ pluginId: z.string(), key: z.string() }),
body: jsonBody(z.object({
companyId: z.string().optional(),
params: z.record(z.unknown()).optional(),
params: z.record(z.string(), z.unknown()).optional(),
})),
},
responses: { 200: r.ok(), 401: r.unauthorized },
@ -6042,7 +6077,7 @@ registry.registerPath({
params: z.object({ pluginId: z.string(), key: z.string() }),
body: jsonBody(z.object({
companyId: z.string().optional(),
params: z.record(z.unknown()).optional(),
params: z.record(z.string(), z.unknown()).optional(),
})),
},
responses: { 200: r.ok(), 401: r.unauthorized },
@ -6810,7 +6845,7 @@ for (const route of [
path: route[1],
tags: ["skills"],
summary: route[2],
...(route[0] === "post" ? { body: z.record(z.unknown()).optional() } : {}),
...(route[0] === "post" ? { body: z.record(z.string(), z.unknown()).optional() } : {}),
});
}
@ -6884,7 +6919,7 @@ registerCurrentRoute({
summary: "Promote quarantined low-trust output",
body: z.object({
sourceArtifactKind: z.enum(["comment", "document", "work_product", "issue"]),
sourceArtifactId: z.string().uuid(),
sourceArtifactId: z.string().guid(),
title: z.string().trim().min(1).max(200),
summary: z.string().trim().min(1).max(8_000),
}),
@ -7600,7 +7635,7 @@ const toolGatewaySessionSchema = z.object({
const toolGatewayCallSchema = z.object({
tool: z.string(),
parameters: z.record(z.unknown()).optional(),
parameters: z.record(z.string(), z.unknown()).optional(),
timeoutMs: z.number().int().positive().optional(),
approvedActionRequestId: z.string().optional(),
idempotencyKey: z.string().optional(),
@ -7613,7 +7648,7 @@ const toolGatewayCompanyBodySchema = z.object({
companyId: z.string(),
}).passthrough();
const mcpGatewayProtocolSchema = z.record(z.unknown());
const mcpGatewayProtocolSchema = z.record(z.string(), z.unknown());
registerCurrentRoute({
method: "get",

View File

@ -94,9 +94,9 @@ const casePatchSchema = z.object({
summary: z.string().max(8_000).nullable().optional(),
fields: jsonObjectSchema.optional(),
workspaceRef: jsonObjectSchema.nullable().optional(),
parentCaseId: z.string().uuid().nullable().optional(),
parentCaseId: z.string().guid().nullable().optional(),
expectedVersion: z.number().int().positive().optional(),
leaseToken: z.string().uuid().nullable().optional(),
leaseToken: z.string().guid().nullable().optional(),
});
const ingestCaseSchema = z.object({
caseKey: z.string().max(1_024).nullable().optional(),
@ -104,17 +104,17 @@ const ingestCaseSchema = z.object({
summary: z.string().max(8_000).nullable().optional(),
fields: jsonObjectSchema.optional(),
stageKey: z.string().trim().min(1).max(120).optional(),
parentCaseId: z.string().uuid().nullable().optional(),
parentCaseId: z.string().guid().nullable().optional(),
requestKey: z.string().trim().min(1).max(512).optional(),
workspaceRef: jsonObjectSchema.nullable().optional(),
blockedByCaseIds: z.array(z.string().uuid()).max(100).optional(),
blockedByCaseIds: z.array(z.string().guid()).max(100).optional(),
blockedByCaseKeys: z.array(z.string().max(1_024)).max(100).optional(),
});
const createPipelineSchema = z.object({
key: z.string().trim().min(1).max(120),
name: z.string().trim().min(1).max(200),
description: z.string().max(8_000).nullable().optional(),
projectId: z.string().uuid().nullable().optional(),
projectId: z.string().guid().nullable().optional(),
enforceTransitions: z.boolean().optional(),
stages: z.array(z.object({
key: z.string().trim().min(1).max(120),
@ -146,7 +146,7 @@ const updateStageSchema = z.object({
});
const updateStageAutomationEnvSchema = z.object({
env: envConfigSchema.nullable(),
baseRoutineRevisionId: z.string().uuid().nullable().optional(),
baseRoutineRevisionId: z.string().guid().nullable().optional(),
});
const replaceTransitionsSchema = z.object({
transitions: z.array(z.object({
@ -167,16 +167,16 @@ const breakdownCaseSchema = z.object({
});
const claimCaseSchema = z.object({ leaseSeconds: z.number().int().positive().max(86_400).optional() });
const releaseCaseSchema = z.object({
leaseToken: z.string().uuid().nullable().optional(),
leaseToken: z.string().guid().nullable().optional(),
force: z.boolean().optional(),
});
const transitionCaseSchema = z.object({
toStageKey: z.string().trim().min(1).max(120),
expectedVersion: z.number().int().positive(),
leaseToken: z.string().uuid().nullable().optional(),
leaseToken: z.string().guid().nullable().optional(),
reason: z.string().max(4_000).nullable().optional(),
force: z.boolean().optional(),
acceptSuggestionId: z.string().uuid().optional(),
acceptSuggestionId: z.string().guid().optional(),
});
const suggestTransitionSchema = z.object({
toStageKey: z.string().trim().min(1).max(120),
@ -184,52 +184,52 @@ const suggestTransitionSchema = z.object({
confidence: z.number().min(0).max(1).optional(),
});
const resolveSuggestionSchema = z.object({
suggestionId: z.string().uuid(),
suggestionId: z.string().guid(),
resolution: z.enum(["accept", "dismiss"]),
expectedVersion: z.number().int().positive().optional(),
reason: z.string().max(4_000).nullable().optional(),
leaseToken: z.string().uuid().nullable().optional(),
leaseToken: z.string().guid().nullable().optional(),
});
const acknowledgeDriftSchema = z.object({
expectedVersion: z.number().int().positive().optional(),
});
const retryAutomationQuerySchema = z.object({
scope: pipelineAutomationRetryScopeSchema.default("previous_stage"),
targetStageId: z.string().uuid().optional(),
targetStageId: z.string().guid().optional(),
});
const reviewEditsSchema = z.object({
title: z.string().trim().min(1).max(500).optional(),
summary: z.string().max(8_000).nullable().optional(),
fields: jsonObjectSchema.optional(),
parentCaseId: z.string().uuid().nullable().optional(),
parentCaseId: z.string().guid().nullable().optional(),
});
const reviewCaseSchema = z.object({
decision: z.enum(["approve", "reject", "request_changes"]),
reason: z.string().max(4_000).nullable().optional(),
edits: reviewEditsSchema.optional(),
expectedVersion: z.number().int().positive(),
leaseToken: z.string().uuid().nullable().optional(),
leaseToken: z.string().guid().nullable().optional(),
});
const blockersSchema = z.object({ blockedByCaseIds: z.array(z.string().uuid()).max(100) });
const blockersSchema = z.object({ blockedByCaseIds: z.array(z.string().guid()).max(100) });
const issueLinkRoleSchema = z.enum(["origin", "conversation", "work", "automation"]);
const createIssueLinkSchema = z.object({
issueId: z.string().uuid(),
issueId: z.string().guid(),
role: issueLinkRoleSchema,
});
const bulkReviewSchema = z.object({
items: z.array(reviewCaseSchema.extend({ caseId: z.string().uuid() })).max(100),
items: z.array(reviewCaseSchema.extend({ caseId: z.string().guid() })).max(100),
});
const upsertPipelineDocumentSchema = z.object({
title: z.string().trim().min(1).max(200).optional(),
body: z.string().max(200_000),
baseRevisionId: z.string().uuid().nullable().optional(),
baseRevisionId: z.string().guid().nullable().optional(),
});
const upsertPipelineCaseDocumentSchema = z.object({
title: z.string().trim().min(1).max(200).optional(),
format: z.string().trim().min(1).max(80).optional().default("markdown"),
body: z.string().max(200_000),
changeSummary: z.string().trim().max(1_000).nullable().optional(),
baseRevisionId: z.string().uuid().nullable().optional(),
baseRevisionId: z.string().guid().nullable().optional(),
});
const intakeFieldTypes = new Set(["select", "text", "multiline"]);

View File

@ -26,7 +26,7 @@ type CursorValue = { createdAt: string; id: string };
const cursorValueSchema = z.object({
createdAt: z.string().datetime({ offset: true }),
id: z.string().uuid(),
id: z.string().guid(),
});
function decodeCursor(cursor: string | undefined): CursorValue | null {

View File

@ -33,16 +33,16 @@ import { resolveActiveEnvironmentCustomImageTemplateForRuntime } from "./environ
const secretRefSchema = z.object({
type: z.literal("secret_ref"),
secretId: z.string().uuid(),
secretId: z.string().guid(),
version: z.union([z.literal("latest"), z.number().int().positive()]).optional().default("latest"),
}).strict();
const sshEnvironmentConfigSchema = z.object({
host: z.string({ required_error: "SSH environments require a host." }).trim().min(1, "SSH environments require a host."),
host: z.string({ error: "SSH environments require a host." }).trim().min(1, "SSH environments require a host."),
port: z.coerce.number().int().min(1).max(65535).default(22),
username: z.string({ required_error: "SSH environments require a username." }).trim().min(1, "SSH environments require a username."),
username: z.string({ error: "SSH environments require a username." }).trim().min(1, "SSH environments require a username."),
remoteWorkspacePath: z
.string({ required_error: "SSH environments require a remote workspace path." })
.string({ error: "SSH environments require a remote workspace path." })
.trim()
.min(1, "SSH environments require a remote workspace path.")
.refine((value) => value.startsWith("/"), "SSH remote workspace path must be absolute."),
@ -102,7 +102,7 @@ const pluginEnvironmentConfigSchema = z.object({
/^[a-z0-9][a-z0-9._-]*$/,
"Environment driver key must start with a lowercase alphanumeric and contain only lowercase letters, digits, dots, hyphens, or underscores",
),
driverConfig: z.record(z.unknown()).optional().default({}),
driverConfig: z.record(z.string(), z.unknown()).optional().default({}),
}).strict();
export type ParsedEnvironmentConfig =

View File

@ -128,8 +128,13 @@ export function pluginManifestValidator(): PluginManifestValidator {
};
}
const details = result.error.errors.map((issue) => ({
path: issue.path,
const details = result.error.issues.map((issue) => ({
// Zod 4 types an issue path as `PropertyKey[]`, which can include a
// symbol. A manifest path only has string or number segments, so map a
// rare symbol segment to its string form for a stable message.
path: issue.path.map((segment) =>
typeof segment === "symbol" ? segment.toString() : segment,
),
message: issue.message,
}));