source dump of claude code
1/**
2 * Team Memory Sync Types
3 *
4 * Zod schemas and types for the repo-scoped team memory sync API.
5 * Based on the backend API contract from anthropic/anthropic#250711.
6 */
7
8import { z } from 'zod/v4'
9import { lazySchema } from '../../utils/lazySchema.js'
10
11/**
12 * Content portion of team memory data - flat key-value storage.
13 * Keys are file paths relative to the team memory directory (e.g. "MEMORY.md", "patterns.md").
14 * Values are UTF-8 string content (typically Markdown).
15 */
16export const TeamMemoryContentSchema = lazySchema(() =>
17 z.object({
18 entries: z.record(z.string(), z.string()),
19 // Per-key SHA-256 of entry content (`sha256:<hex>`). Added in
20 // anthropic/anthropic#283027. Optional for forward-compat with older
21 // server deployments; empty map when entries is empty.
22 entryChecksums: z.record(z.string(), z.string()).optional(),
23 }),
24)
25
26/**
27 * Full response from GET /api/claude_code/team_memory
28 */
29export const TeamMemoryDataSchema = lazySchema(() =>
30 z.object({
31 organizationId: z.string(),
32 repo: z.string(),
33 version: z.number(),
34 lastModified: z.string(), // ISO 8601 timestamp
35 checksum: z.string(), // SHA256 with 'sha256:' prefix
36 content: TeamMemoryContentSchema(),
37 }),
38)
39
40/**
41 * Structured 413 error body from the server (anthropic/anthropic#293258).
42 * The server's RequestTooLargeException serializes error_code and the
43 * extra_details dict flattened into error.details. We only model the
44 * too-many-entries case; entry-too-large is handled via MAX_FILE_SIZE_BYTES
45 * pre-check on the client side and would need a separate schema.
46 */
47export const TeamMemoryTooManyEntriesSchema = lazySchema(() =>
48 z.object({
49 error: z.object({
50 details: z.object({
51 error_code: z.literal('team_memory_too_many_entries'),
52 max_entries: z.number().int().positive(),
53 received_entries: z.number().int().positive(),
54 }),
55 }),
56 }),
57)
58
59export type TeamMemoryData = z.infer<ReturnType<typeof TeamMemoryDataSchema>>
60
61/**
62 * A file skipped during push because it contains a detected secret.
63 * The path is relative to the team memory directory. Only the matched
64 * gitleaks rule ID is recorded — never the secret value itself.
65 */
66export type SkippedSecretFile = {
67 path: string
68 /** Gitleaks rule ID (e.g., "github-pat", "aws-access-token") */
69 ruleId: string
70 /** Human-readable label derived from rule ID */
71 label: string
72}
73
74/**
75 * Result from fetching team memory
76 */
77export type TeamMemorySyncFetchResult = {
78 success: boolean
79 data?: TeamMemoryData
80 isEmpty?: boolean // true if 404 (no data exists)
81 notModified?: boolean // true if 304 (ETag matched, no changes)
82 checksum?: string // ETag from response header
83 error?: string
84 skipRetry?: boolean
85 errorType?: 'auth' | 'timeout' | 'network' | 'parse' | 'unknown'
86 httpStatus?: number
87}
88
89/**
90 * Lightweight metadata-only probe result (GET ?view=hashes).
91 * Contains per-key checksums without entry bodies. Used to refresh
92 * serverChecksums cheaply during 412 conflict resolution.
93 */
94export type TeamMemoryHashesResult = {
95 success: boolean
96 version?: number
97 checksum?: string
98 entryChecksums?: Record<string, string>
99 error?: string
100 errorType?: 'auth' | 'timeout' | 'network' | 'parse' | 'unknown'
101 httpStatus?: number
102}
103
104/**
105 * Result from uploading team memory with conflict info
106 */
107export type TeamMemorySyncPushResult = {
108 success: boolean
109 filesUploaded: number
110 checksum?: string
111 conflict?: boolean // true if 412 Precondition Failed
112 error?: string
113 /** Files skipped because they contain detected secrets (PSR M22174). */
114 skippedSecrets?: SkippedSecretFile[]
115 errorType?:
116 | 'auth'
117 | 'timeout'
118 | 'network'
119 | 'conflict'
120 | 'unknown'
121 | 'no_oauth'
122 | 'no_repo'
123 httpStatus?: number
124}
125
126/**
127 * Result from uploading team memory
128 */
129export type TeamMemorySyncUploadResult = {
130 success: boolean
131 checksum?: string
132 lastModified?: string
133 conflict?: boolean // true if 412 Precondition Failed
134 error?: string
135 errorType?: 'auth' | 'timeout' | 'network' | 'unknown'
136 httpStatus?: number
137 /**
138 * Structured error_code from a parsed 413 body (anthropic/anthropic#293258).
139 * Currently only 'team_memory_too_many_entries' is modelled; if the server
140 * adds more (entry_too_large, total_bytes_exceeded) they'd extend this
141 * union. Passed straight through to the tengu_team_mem_sync_push event
142 * as a Datadog-filterable facet.
143 */
144 serverErrorCode?: 'team_memory_too_many_entries'
145 /**
146 * Server-enforced max_entries, populated when serverErrorCode is
147 * team_memory_too_many_entries. Lets the caller cache the effective
148 * (possibly per-org) limit for subsequent pushes.
149 */
150 serverMaxEntries?: number
151 /**
152 * How many entries the rejected push would have produced after merge.
153 * Populated alongside serverMaxEntries.
154 */
155 serverReceivedEntries?: number
156}