@opencow-ai/opencow-agent-sdk 0.4.15 → 0.4.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,5 @@
1
1
  import type { UUID } from 'crypto';
2
2
  import { type AgentId, type SessionId } from '../types/ids.js';
3
- import type { AttributionSnapshotMessage } from '../types/logs.js';
4
3
  import { type ContextCollapseCommitEntry, type ContextCollapseSnapshotEntry, type Entry, type FileHistorySnapshotMessage, type LogOption, type PersistedWorktreeSession, type SerializedMessage, type TranscriptMessage } from '../types/logs.js';
5
4
  import type { AssistantMessage, AttachmentMessage, Message, SystemMessage, UserMessage } from '../types/message.js';
6
5
  import type { QueueOperationMessage } from '../types/messageQueueTypes.js';
@@ -162,7 +161,6 @@ export declare function recordQueueOperation(queueOp: QueueOperationMessage): Pr
162
161
  */
163
162
  export declare function removeTranscriptMessage(targetUuid: UUID): Promise<void>;
164
163
  export declare function recordFileHistorySnapshot(messageId: UUID, snapshot: FileHistorySnapshot, isSnapshotUpdate: boolean): Promise<void>;
165
- export declare function recordAttributionSnapshot(snapshot: AttributionSnapshotMessage): Promise<void>;
166
164
  export declare function recordContentReplacement(replacements: ContentReplacementRecord[], agentId?: AgentId): Promise<void>;
167
165
  /**
168
166
  * Reset the session file pointer after switchSession/regenerateSessionId.
@@ -404,7 +402,6 @@ export declare function searchSessionsByCustomTitle(query: string, options?: {
404
402
  }): Promise<LogOption[]>;
405
403
  /**
406
404
  * Loads all messages, summaries, and file history snapshots from a transcript file.
407
- * Returns the messages, summaries, custom titles, tags, file history snapshots, and attribution snapshots.
408
405
  */
409
406
  export declare function loadTranscriptFile(filePath: string, opts?: {
410
407
  keepAllLeaves?: boolean;
@@ -422,7 +419,6 @@ export declare function loadTranscriptFile(filePath: string, opts?: {
422
419
  modes: Map<UUID, string>;
423
420
  worktreeStates: Map<UUID, PersistedWorktreeSession | null>;
424
421
  fileHistorySnapshots: Map<UUID, FileHistorySnapshotMessage>;
425
- attributionSnapshots: Map<UUID, AttributionSnapshotMessage>;
426
422
  contentReplacements: Map<UUID, ContentReplacementRecord[]>;
427
423
  agentContentReplacements: Map<AgentId, ContentReplacementRecord[]>;
428
424
  contextCollapseCommits: ContextCollapseCommitEntry[];
@@ -221,11 +221,6 @@ export declare const SettingsSchema: () => z.ZodObject<{
221
221
  respectGitignore: z.ZodOptional<z.ZodBoolean>;
222
222
  cleanupPeriodDays: z.ZodOptional<z.ZodNumber>;
223
223
  env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodCoercedString<unknown>>>;
224
- attribution: z.ZodOptional<z.ZodObject<{
225
- commit: z.ZodOptional<z.ZodString>;
226
- pr: z.ZodOptional<z.ZodString>;
227
- }, z.core.$strip>>;
228
- includeCoAuthoredBy: z.ZodOptional<z.ZodBoolean>;
229
224
  includeGitInstructions: z.ZodOptional<z.ZodBoolean>;
230
225
  permissions: z.ZodOptional<z.ZodObject<{
231
226
  additionalDirectories: z.ZodOptional<z.ZodArray<z.ZodString>>;
@@ -14,7 +14,6 @@ import type { AgentId } from '../types/ids.js';
14
14
  import type { Message, UserMessage } from '../types/message.js';
15
15
  import type { LoadedPlugin, PluginError } from '../types/plugin.js';
16
16
  import type { DeepImmutable } from '../types/utils.js';
17
- import { type AttributionState } from '../session/commitAttribution.js';
18
17
  import type { EffortValue } from '../lib/effort.js';
19
18
  import type { FileHistoryState } from '../session/fileHistory.js';
20
19
  import type { REPLHookContext } from '../controller/hooks/postSamplingHooks.js';
@@ -163,7 +162,6 @@ export type AppState = DeepImmutable<{
163
162
  };
164
163
  agentDefinitions: AgentDefinitionsResult;
165
164
  fileHistory: FileHistoryState;
166
- attribution: AttributionState;
167
165
  todos: {
168
166
  [agentId: string]: TodoList;
169
167
  };
@@ -4,7 +4,6 @@ import type { HookJSONOutput, AsyncHookJSONOutput, SyncHookJSONOutput } from '..
4
4
  import type { Message } from 'src/types/message.js';
5
5
  import type { PermissionResult } from 'src/permissions/PermissionResult.js';
6
6
  import type { AppState } from '../state/AppStateStore.js';
7
- import type { AttributionState } from '../session/commitAttribution.js';
8
7
  export declare function isHookEvent(value: string): value is HookEvent;
9
8
  export declare const promptRequestSchema: () => z.ZodObject<{
10
9
  prompt: z.ZodString;
@@ -190,7 +189,6 @@ export declare function isAsyncHookJSONOutput(json: HookJSONOutput): json is Asy
190
189
  /** Context passed to callback hooks for state access */
191
190
  export type HookCallbackContext = {
192
191
  getAppState: () => AppState;
193
- updateAttributionState: (updater: (prev: AttributionState) => AttributionState) => void;
194
192
  };
195
193
  /** Hook that is a callback. */
196
194
  export type HookCallback = {
@@ -37,7 +37,6 @@ export type LogOption = {
37
37
  customTitle?: string;
38
38
  tag?: string;
39
39
  fileHistorySnapshots?: FileHistorySnapshot[];
40
- attributionSnapshots?: AttributionSnapshotMessage[];
41
40
  contextCollapseCommits?: ContextCollapseCommitEntry[];
42
41
  contextCollapseSnapshot?: ContextCollapseSnapshotEntry;
43
42
  gitBranch?: string;
@@ -174,30 +173,6 @@ export type FileHistorySnapshotMessage = {
174
173
  snapshot: FileHistorySnapshot;
175
174
  isSnapshotUpdate: boolean;
176
175
  };
177
- /**
178
- * Per-file attribution state tracking Claude's character contributions.
179
- */
180
- export type FileAttributionState = {
181
- contentHash: string;
182
- claudeContribution: number;
183
- mtime: number;
184
- };
185
- /**
186
- * Attribution snapshot message stored in session transcript.
187
- * Tracks character-level contributions by Claude for commit attribution.
188
- */
189
- export type AttributionSnapshotMessage = {
190
- type: 'attribution-snapshot';
191
- messageId: UUID;
192
- surface: string;
193
- fileStates: Record<string, FileAttributionState>;
194
- promptCount?: number;
195
- promptCountAtLastCommit?: number;
196
- permissionPromptCount?: number;
197
- permissionPromptCountAtLastCommit?: number;
198
- escapeCount?: number;
199
- escapeCountAtLastCommit?: number;
200
- };
201
176
  export type TranscriptMessage = SerializedMessage & {
202
177
  parentUuid: UUID | null;
203
178
  logicalParentUuid?: UUID | null;
@@ -270,5 +245,5 @@ export type ContextCollapseSnapshotEntry = {
270
245
  armed: boolean;
271
246
  lastSpawnTokens: number;
272
247
  };
273
- export type Entry = TranscriptMessage | SummaryMessage | CustomTitleMessage | AiTitleMessage | LastPromptMessage | TaskSummaryMessage | TagMessage | AgentNameMessage | AgentColorMessage | AgentSettingMessage | PRLinkMessage | FileHistorySnapshotMessage | AttributionSnapshotMessage | QueueOperationMessage | SpeculationAcceptMessage | ModeEntry | WorktreeStateEntry | ContentReplacementEntry | ContextCollapseCommitEntry | ContextCollapseSnapshotEntry;
248
+ export type Entry = TranscriptMessage | SummaryMessage | CustomTitleMessage | AiTitleMessage | LastPromptMessage | TaskSummaryMessage | TagMessage | AgentNameMessage | AgentColorMessage | AgentSettingMessage | PRLinkMessage | FileHistorySnapshotMessage | QueueOperationMessage | SpeculationAcceptMessage | ModeEntry | WorktreeStateEntry | ContentReplacementEntry | ContextCollapseCommitEntry | ContextCollapseSnapshotEntry;
274
249
  export declare function sortLogs(logs: LogOption[]): LogOption[];
@@ -32,7 +32,6 @@ import type { ThinkingConfig } from '../lib/thinking.js';
32
32
  import type { MCPServerConnection, ServerResource } from '../capabilities/mcp/types.js';
33
33
  import type { QuerySource } from '../constants/querySource.js';
34
34
  import type { SDKStatus } from '../entrypoints/sdk/coreTypes.js';
35
- import type { AttributionState } from '../session/commitAttribution.js';
36
35
  import type { FileHistoryState } from '../session/fileHistory.js';
37
36
  export type ToolInputJSONSchema = {
38
37
  [x: string]: unknown;
@@ -168,7 +167,6 @@ export type ToolRuntimeContext = {
168
167
  */
169
168
  uploadMedia?: UploadMediaFn;
170
169
  updateFileHistoryState: (updater: (prev: FileHistoryState) => FileHistoryState) => void;
171
- updateAttributionState: (updater: (prev: AttributionState) => AttributionState) => void;
172
170
  setConversationId?: (id: UUID) => void;
173
171
  agentId?: AgentId;
174
172
  agentType?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opencow-ai/opencow-agent-sdk",
3
- "version": "0.4.15",
3
+ "version": "0.4.17",
4
4
  "description": "Claude Code opened to any LLM — OpenAI, Gemini, DeepSeek, Ollama, and 200+ models",
5
5
  "type": "module",
6
6
  "main": "./dist/sdk.js",
@@ -1,14 +0,0 @@
1
- /**
2
- * Check if a file should be excluded from attribution based on Linguist-style rules.
3
- *
4
- * @param filePath - Relative file path from repository root
5
- * @returns true if the file should be excluded from attribution
6
- */
7
- export declare function isGeneratedFile(filePath: string): boolean;
8
- /**
9
- * Filter a list of files to exclude generated files.
10
- *
11
- * @param files - Array of file paths
12
- * @returns Array of files that are not generated
13
- */
14
- export declare function filterGeneratedFiles(files: string[]): string[];
@@ -1,121 +0,0 @@
1
- /**
2
- * Team Memory Sync Service
3
- *
4
- * Syncs team memory files between the local filesystem and the server API.
5
- * Team memory is scoped per-repo (identified by git remote hash) and shared
6
- * across all authenticated org members.
7
- *
8
- * API contract (anthropic/anthropic#250711 + #283027):
9
- * GET /api/claude_code/team_memory?repo={owner/repo} → TeamMemoryData (includes entryChecksums)
10
- * GET /api/claude_code/team_memory?repo={owner/repo}&view=hashes → metadata + entryChecksums only (no entry bodies)
11
- * PUT /api/claude_code/team_memory?repo={owner/repo} → upload entries (upsert semantics)
12
- * 404 = no data exists yet
13
- *
14
- * Sync semantics:
15
- * - Pull overwrites local files with server content (server wins per-key).
16
- * - Push uploads only keys whose content hash differs from serverChecksums
17
- * (delta upload). Server uses upsert: keys not in the PUT are preserved.
18
- * - File deletions do NOT propagate: deleting a local file won't remove it
19
- * from the server, and the next pull will restore it locally.
20
- *
21
- * State management:
22
- * All mutable state (ETag tracking, watcher suppression) lives in a
23
- * SyncState object created by the caller and threaded through every call.
24
- * This avoids module-level mutable state and gives tests natural isolation.
25
- */
26
- import { type TeamMemorySyncPushResult } from './types.js';
27
- /**
28
- * Mutable state for the team memory sync service.
29
- * Created once per session by the watcher and passed to all sync functions.
30
- * Tests create a fresh instance per test for isolation.
31
- */
32
- export type SyncState = {
33
- /** Last known server checksum (ETag) for conditional requests. */
34
- lastKnownChecksum: string | null;
35
- /**
36
- * Per-key content hash (`sha256:<hex>`) of what we believe the server
37
- * currently holds. Populated from server-provided entryChecksums on pull
38
- * and from local hashes on successful push. Used to compute the delta on
39
- * push — only keys whose local hash differs are uploaded.
40
- */
41
- serverChecksums: Map<string, string>;
42
- /**
43
- * Server-enforced max_entries cap, learned from a structured 413 response
44
- * (anthropic/anthropic#293258 adds error_code + extra_details.max_entries).
45
- * Stays null until a 413 is observed — the server's cap is GB-tunable
46
- * per-org so there is no correct client-side default. While null,
47
- * readLocalTeamMemory sends everything and lets the server be
48
- * authoritative (it rejects atomically).
49
- */
50
- serverMaxEntries: number | null;
51
- };
52
- export declare function createSyncState(): SyncState;
53
- /**
54
- * Compute `sha256:<hex>` over the UTF-8 bytes of the given content.
55
- * Format matches the server's entryChecksums values (anthropic/anthropic#283027)
56
- * so local-vs-server comparison works by direct string equality.
57
- */
58
- export declare function hashContent(content: string): string;
59
- /**
60
- * Split a delta into PUT-sized batches under MAX_PUT_BODY_BYTES each.
61
- *
62
- * Greedy bin-packing over sorted keys — sorting gives deterministic batches
63
- * across calls, which matters for ETag stability if the conflict loop retries
64
- * after a partial commit. The byte count is the full serialized body
65
- * including JSON overhead, so what we measure is what axios sends.
66
- *
67
- * A single entry exceeding MAX_PUT_BODY_BYTES goes into its own solo batch
68
- * (MAX_FILE_SIZE_BYTES=250K already caps individual files; a ~250K solo body
69
- * is above our soft cap but below the gateway's observed real threshold).
70
- */
71
- export declare function batchDeltaByBytes(delta: Record<string, string>): Array<Record<string, string>>;
72
- /**
73
- * Check if team memory sync is available (requires first-party OAuth).
74
- */
75
- export declare function isTeamMemorySyncAvailable(): boolean;
76
- /**
77
- * Pull team memory from the server and write to local directory.
78
- * Returns true if any files were updated.
79
- */
80
- export declare function pullTeamMemory(state: SyncState, options?: {
81
- skipEtagCache?: boolean;
82
- }): Promise<{
83
- success: boolean;
84
- filesWritten: number;
85
- /** Number of entries the server returned, regardless of whether they were written to disk. */
86
- entryCount: number;
87
- notModified?: boolean;
88
- error?: string;
89
- }>;
90
- /**
91
- * Push local team memory files to the server with optimistic locking.
92
- *
93
- * Uses delta upload: only keys whose local content hash differs from
94
- * serverChecksums are included in the PUT. On 412 conflict, probes
95
- * GET ?view=hashes to refresh serverChecksums, recomputes the delta
96
- * (naturally excluding keys where a teammate's push matches ours),
97
- * and retries. No merge, no disk writes — server-only new keys from
98
- * a teammate's concurrent push propagate on the next pull.
99
- *
100
- * Local-wins-on-conflict is the opposite of syncTeamMemory's pull-first
101
- * semantics. This is intentional: pushTeamMemory is triggered by a local edit,
102
- * and that edit must not be silently discarded just because a teammate pushed
103
- * in the meantime. Content-level merge (same key, both changed) is not
104
- * attempted — the local version simply overwrites the server version for that
105
- * key, and the server's edit to that key is lost. This is the lesser evil:
106
- * the local user is actively editing and can re-incorporate the teammate's
107
- * changes, whereas silently discarding the local edit loses work the user
108
- * just did with no recourse.
109
- */
110
- export declare function pushTeamMemory(state: SyncState): Promise<TeamMemorySyncPushResult>;
111
- /**
112
- * Bidirectional sync: pull from server, merge with local, push back.
113
- * Server entries take precedence on conflict (last-write-wins by the server).
114
- * Push uses conflict resolution (retries on 412) via pushTeamMemory.
115
- */
116
- export declare function syncTeamMemory(state: SyncState): Promise<{
117
- success: boolean;
118
- filesPulled: number;
119
- filesPushed: number;
120
- error?: string;
121
- }>;
@@ -1,132 +0,0 @@
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
- import { z } from 'zod/v4';
8
- /**
9
- * Content portion of team memory data - flat key-value storage.
10
- * Keys are file paths relative to the team memory directory (e.g. "MEMORY.md", "patterns.md").
11
- * Values are UTF-8 string content (typically Markdown).
12
- */
13
- export declare const TeamMemoryContentSchema: () => z.ZodObject<{
14
- entries: z.ZodRecord<z.ZodString, z.ZodString>;
15
- entryChecksums: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
16
- }, z.core.$strip>;
17
- /**
18
- * Full response from GET /api/claude_code/team_memory
19
- */
20
- export declare const TeamMemoryDataSchema: () => z.ZodObject<{
21
- organizationId: z.ZodString;
22
- repo: z.ZodString;
23
- version: z.ZodNumber;
24
- lastModified: z.ZodString;
25
- checksum: z.ZodString;
26
- content: z.ZodObject<{
27
- entries: z.ZodRecord<z.ZodString, z.ZodString>;
28
- entryChecksums: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
29
- }, z.core.$strip>;
30
- }, z.core.$strip>;
31
- /**
32
- * Structured 413 error body from the server (anthropic/anthropic#293258).
33
- * The server's RequestTooLargeException serializes error_code and the
34
- * extra_details dict flattened into error.details. We only model the
35
- * too-many-entries case; entry-too-large is handled via MAX_FILE_SIZE_BYTES
36
- * pre-check on the client side and would need a separate schema.
37
- */
38
- export declare const TeamMemoryTooManyEntriesSchema: () => z.ZodObject<{
39
- error: z.ZodObject<{
40
- details: z.ZodObject<{
41
- error_code: z.ZodLiteral<"team_memory_too_many_entries">;
42
- max_entries: z.ZodNumber;
43
- received_entries: z.ZodNumber;
44
- }, z.core.$strip>;
45
- }, z.core.$strip>;
46
- }, z.core.$strip>;
47
- export type TeamMemoryData = z.infer<ReturnType<typeof TeamMemoryDataSchema>>;
48
- /**
49
- * A file skipped during push because it contains a detected secret.
50
- * The path is relative to the team memory directory. Only the matched
51
- * gitleaks rule ID is recorded — never the secret value itself.
52
- */
53
- export type SkippedSecretFile = {
54
- path: string;
55
- /** Gitleaks rule ID (e.g., "github-pat", "aws-access-token") */
56
- ruleId: string;
57
- /** Human-readable label derived from rule ID */
58
- label: string;
59
- };
60
- /**
61
- * Result from fetching team memory
62
- */
63
- export type TeamMemorySyncFetchResult = {
64
- success: boolean;
65
- data?: TeamMemoryData;
66
- isEmpty?: boolean;
67
- notModified?: boolean;
68
- checksum?: string;
69
- error?: string;
70
- skipRetry?: boolean;
71
- errorType?: 'auth' | 'timeout' | 'network' | 'parse' | 'unknown';
72
- httpStatus?: number;
73
- };
74
- /**
75
- * Lightweight metadata-only probe result (GET ?view=hashes).
76
- * Contains per-key checksums without entry bodies. Used to refresh
77
- * serverChecksums cheaply during 412 conflict resolution.
78
- */
79
- export type TeamMemoryHashesResult = {
80
- success: boolean;
81
- version?: number;
82
- checksum?: string;
83
- entryChecksums?: Record<string, string>;
84
- error?: string;
85
- errorType?: 'auth' | 'timeout' | 'network' | 'parse' | 'unknown';
86
- httpStatus?: number;
87
- };
88
- /**
89
- * Result from uploading team memory with conflict info
90
- */
91
- export type TeamMemorySyncPushResult = {
92
- success: boolean;
93
- filesUploaded: number;
94
- checksum?: string;
95
- conflict?: boolean;
96
- error?: string;
97
- /** Files skipped because they contain detected secrets (PSR M22174). */
98
- skippedSecrets?: SkippedSecretFile[];
99
- errorType?: 'auth' | 'timeout' | 'network' | 'conflict' | 'unknown' | 'no_oauth' | 'no_repo';
100
- httpStatus?: number;
101
- };
102
- /**
103
- * Result from uploading team memory
104
- */
105
- export type TeamMemorySyncUploadResult = {
106
- success: boolean;
107
- checksum?: string;
108
- lastModified?: string;
109
- conflict?: boolean;
110
- error?: string;
111
- errorType?: 'auth' | 'timeout' | 'network' | 'unknown';
112
- httpStatus?: number;
113
- /**
114
- * Structured error_code from a parsed 413 body (anthropic/anthropic#293258).
115
- * Currently only 'team_memory_too_many_entries' is modelled; if the server
116
- * adds more (entry_too_large, total_bytes_exceeded) they'd extend this
117
- * union. Passed straight through to the tengu_team_mem_sync_push event
118
- * as a Datadog-filterable facet.
119
- */
120
- serverErrorCode?: 'team_memory_too_many_entries';
121
- /**
122
- * Server-enforced max_entries, populated when serverErrorCode is
123
- * team_memory_too_many_entries. Lets the caller cache the effective
124
- * (possibly per-org) limit for subsequent pushes.
125
- */
126
- serverMaxEntries?: number;
127
- /**
128
- * How many entries the rejected push would have produced after merge.
129
- * Populated alongside serverMaxEntries.
130
- */
131
- serverReceivedEntries?: number;
132
- };
@@ -1,78 +0,0 @@
1
- /**
2
- * Team Memory File Watcher
3
- *
4
- * Watches the team memory directory for changes and triggers
5
- * a debounced push to the server when files are modified.
6
- * Performs an initial pull on startup, then starts a directory-level
7
- * fs.watch so first-time writes to a fresh repo get picked up.
8
- */
9
- import { type SyncState } from './index.js';
10
- import type { TeamMemorySyncPushResult } from './types.js';
11
- /**
12
- * Permanent = retry without user action will fail the same way.
13
- * - no_oauth / no_repo: pre-request client checks, no status code
14
- * - 4xx except 409/429: client error (404 missing repo, 413 too many
15
- * entries, 403 permission). 409 is a transient conflict — server state
16
- * changed under us, a fresh push after next pull can succeed. 429 is a
17
- * rate limit — watcher-driven backoff is fine.
18
- */
19
- export declare function isPermanentFailure(r: TeamMemorySyncPushResult): boolean;
20
- /**
21
- * Start the team memory sync system.
22
- *
23
- * Returns early (before creating any state) if:
24
- * - TEAMMEM build flag is off
25
- * - team memory is disabled (isTeamMemoryEnabled)
26
- * - OAuth is not available (isTeamMemorySyncAvailable)
27
- * - the current repo has no github.com remote
28
- *
29
- * The early github.com check prevents a noisy failure mode where the
30
- * watcher starts, it fires on local edits, and every push/pull
31
- * logs `errorType: no_repo` forever. Team memory is GitHub-scoped on
32
- * the server side, so non-github.com remotes can never sync anyway.
33
- *
34
- * Pulls from server, then starts the file watcher unconditionally.
35
- * The watcher must start even when the server has no content yet
36
- * (fresh EAP repo) — otherwise Claude's first team-memory write
37
- * depends entirely on PostToolUse hooks firing notifyTeamMemoryWrite,
38
- * which is a chicken-and-egg: Claude's write rate is low enough that
39
- * a fresh partner can sit in the bootstrap dead zone for days.
40
- */
41
- export declare function startTeamMemoryWatcher(): Promise<void>;
42
- /**
43
- * Call this when a team memory file is written (e.g. from PostToolUse hooks).
44
- * Schedules a push explicitly in case fs.watch misses the write —
45
- * a file written in the same tick the watcher starts may not fire an
46
- * event, and some platforms coalesce rapid successive writes.
47
- * If the watcher does fire, the debounce timer just resets.
48
- */
49
- export declare function notifyTeamMemoryWrite(): Promise<void>;
50
- /**
51
- * Stop the file watcher and flush pending changes.
52
- * Note: runs within the 2s graceful shutdown budget, so the flush
53
- * is best-effort — if the HTTP PUT doesn't complete in time,
54
- * process.exit() will kill it.
55
- */
56
- export declare function stopTeamMemoryWatcher(): Promise<void>;
57
- /**
58
- * Test-only: reset module state and optionally seed syncState.
59
- * The feature('TEAMMEM') gate at the top of startTeamMemoryWatcher() is
60
- * always false in bun test, so tests can't set syncState through the normal
61
- * path. This helper lets tests drive notifyTeamMemoryWrite() /
62
- * stopTeamMemoryWatcher() directly.
63
- *
64
- * `skipWatcher: true` marks the watcher as already-started without actually
65
- * starting it. Tests that only exercise the schedulePush/flush path don't
66
- * need a real watcher.
67
- */
68
- export declare function _resetWatcherStateForTesting(opts?: {
69
- syncState?: SyncState;
70
- skipWatcher?: boolean;
71
- pushSuppressedReason?: string | null;
72
- }): void;
73
- /**
74
- * Test-only: start the real fs.watch on a specified directory.
75
- * Used by the fd-count regression test — startTeamMemoryWatcher() is gated
76
- * by feature('TEAMMEM') which is false under bun test.
77
- */
78
- export declare function _startFileWatcherForTesting(dir: string): Promise<void>;
@@ -1,12 +0,0 @@
1
- /**
2
- * Creates a sequential execution wrapper for async functions to prevent race conditions.
3
- * Ensures that concurrent calls to the wrapped function are executed one at a time
4
- * in the order they were received, while preserving the correct return values.
5
- *
6
- * This is useful for operations that must be performed sequentially, such as
7
- * file writes or database updates that could cause conflicts if executed concurrently.
8
- *
9
- * @param fn - The async function to wrap with sequential execution
10
- * @returns A wrapped version of the function that executes calls sequentially
11
- */
12
- export declare function sequential<T extends unknown[], R>(fn: (...args: T) => Promise<R>): (...args: T) => Promise<R>;
@@ -1,40 +0,0 @@
1
- import type { AppState } from '../state/AppStateStore.js';
2
- export type AttributionTexts = {
3
- commit: string;
4
- pr: string;
5
- };
6
- /**
7
- * Returns attribution text for commits and PRs based on user settings.
8
- * Handles:
9
- * - Dynamic model name via getPublicModelName()
10
- * - Custom attribution settings (settings.attribution.commit/pr)
11
- * - Backward compatibility with deprecated includeCoAuthoredBy setting
12
- * - Remote mode: returns session URL for attribution
13
- */
14
- export declare function getAttributionTexts(): AttributionTexts;
15
- /**
16
- * Count user messages with visible text content in a list of non-sidechain messages.
17
- * Excludes tool_result blocks, terminal output, and empty messages.
18
- *
19
- * Callers should pass messages already filtered to exclude sidechain messages.
20
- */
21
- export declare function countUserPromptsInMessages(messages: ReadonlyArray<{
22
- type: string;
23
- message?: {
24
- content?: unknown;
25
- };
26
- }>): number;
27
- /**
28
- * Get enhanced PR attribution text with Claude contribution stats.
29
- *
30
- * Format: "🤖 Generated with Claude Code (93% 3-shotted by claude-opus-4-5)"
31
- *
32
- * Rules:
33
- * - Shows Claude contribution percentage from commit attribution
34
- * - Shows N-shotted where N is the prompt count (1-shotted, 2-shotted, etc.)
35
- * - Shows short model name (e.g., claude-opus-4-5)
36
- * - Returns default attribution if stats can't be computed
37
- *
38
- * @param getAppState Function to get the current AppState (from command context)
39
- */
40
- export declare function getEnhancedPRAttribution(getAppState: () => AppState): Promise<string>;