Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | 4x 4x 4x 14x 14x 14x 4x 10x 3x 7x 5x 2x 4x 4x 4x 4x 4x 4x | import { z } from "zod";
import { requiredId } from "../utils";
// ============================================================================
// manage_snippet - CQRS Command Tool (discriminated union schema)
// Actions: create, update, delete
// Uses z.discriminatedUnion() for type-safe action handling.
// ============================================================================
// --- Shared schemas ---
// Visibility level schema with flexible coercion
const flexibleVisibility = z.preprocess(
val => {
Eif (typeof val === "string") {
const normalized = val.toLowerCase().trim();
if (["private", "priv"].includes(normalized)) {
return "private";
}
if (["internal", "intern"].includes(normalized)) {
return "internal";
}
if (["public", "pub"].includes(normalized)) {
return "public";
}
}
return val;
},
z.enum(["private", "internal", "public"])
);
// Snippet file schema for multi-file support
const SnippetFileSchema = z.object({
file_path: z
.string()
.min(1)
.describe(
"The path/name of the file within the snippet. Can include subdirectories (e.g., 'src/main.py'). Must be unique within the snippet"
),
content: z
.string()
.optional()
.describe(
"The content of the file. Required for 'create' and 'update' actions. Can be empty string for placeholder files"
),
action: z
.enum(["create", "update", "delete", "move"])
.optional()
.describe(
"Action to perform on the file (only for update operations): 'create' adds a new file, 'update' modifies existing file, 'delete' removes file, 'move' renames file (requires previous_path)"
),
previous_path: z
.string()
.optional()
.describe(
"Original file path when using 'move' action to rename a file. Must match an existing file in the snippet"
),
});
// --- Shared fields ---
const projectIdField = z
.string()
.optional()
.describe("Project ID or URL-encoded path. Leave empty for personal snippets");
// --- Action: create ---
const CreateSnippetSchema = z.object({
action: z.literal("create").describe("Create a new snippet with one or more files"),
projectId: projectIdField.describe(
"Project ID or URL-encoded path to create a project snippet. Leave empty for personal snippet"
),
title: z
.string()
.min(1)
.max(255)
.describe(
"The title of the snippet. Displayed in snippet list and as page title. Max 255 chars"
),
description: z
.string()
.optional()
.describe("Optional description explaining the snippet purpose. Supports markdown"),
visibility: flexibleVisibility
.optional()
.default("private")
.describe(
"Visibility: 'private' (author only), 'internal' (authenticated users), 'public' (everyone). Defaults to 'private'"
),
files: z
.array(
z.object({
file_path: z.string().min(1),
content: z.string(),
})
)
.min(1)
.describe(
"Array of files to include. At least one file required. Each needs file_path and content"
),
});
// --- Action: update ---
const UpdateSnippetSchema = z.object({
action: z.literal("update").describe("Update an existing snippet metadata or files"),
id: requiredId.describe("The ID of the snippet to update"),
projectId: projectIdField.describe(
"Project ID or URL-encoded path. Required for project snippets, leave empty for personal"
),
title: z.string().min(1).max(255).optional().describe("Update the snippet title. Max 255 chars"),
description: z.string().optional().describe("Update the snippet description. Supports markdown"),
visibility: flexibleVisibility.optional().describe("Update the visibility level"),
files: z
.array(SnippetFileSchema)
.optional()
.describe(
"Array of file operations. Each file must specify 'action': create/update/delete/move. Move requires previous_path"
),
});
// --- Action: delete ---
const DeleteSnippetSchema = z.object({
action: z.literal("delete").describe("Permanently delete a snippet"),
id: requiredId.describe("The ID of the snippet to delete. This operation cannot be undone"),
projectId: projectIdField.describe(
"Project ID or URL-encoded path. Required for project snippets, leave empty for personal"
),
});
// --- Discriminated union combining all actions ---
export const ManageSnippetSchema = z.discriminatedUnion("action", [
CreateSnippetSchema,
UpdateSnippetSchema,
DeleteSnippetSchema,
]);
// ============================================================================
// Type exports
// ============================================================================
export type ManageSnippetInput = z.infer<typeof ManageSnippetSchema>;
export type SnippetFile = z.infer<typeof SnippetFileSchema>;
|