/** * create_thread Tool * * Create an open thread outside of session close. Threads track * unresolved work items that carry across sessions. * * Writes to Supabase (source of truth) + local file (cache). * Falls back to local-only if Supabase is unavailable. * * Phase 3: Semantic dedup gate — before creating, checks existing open * threads by embedding cosine similarity (> 0.85 threshold). Returns * existing thread instead of creating a duplicate. * * Performance target: <500ms (Supabase write + file write) */ import type { ThreadObject, PerformanceData, Project } from "../types/index.js"; export interface CreateThreadParams { /** Thread description */ text: string; /** Associated Linear issue (optional) */ linear_issue?: string; /** Project namespace (default: default) */ project?: Project; /** * R2: force a genuinely new thread past a dedup match. Dedup refuses rather * than merging, so this is the caller's explicit way through — never a * default, because the whole point is that the decision is stated. */ allow_duplicate?: boolean; } /** * Why a write did not store, when it did not (GIT-67/GIT-63). * Absent on success. */ export type NotStoredReason = "no_active_session" | "duplicate_candidate" | "empty_text" | "store_unavailable"; /** * Where a thread actually landed (R3: every response names its store). * `local_only` is the honest middle state from R4 — written somewhere, but * not somewhere durable. */ export type StoredIn = "supabase" | "local" | "local_only" | null; export interface CreateThreadResult { success: boolean; /** * Whether a row exists. Distinct from `success` on purpose: a dedup refusal * is a well-formed answer to a well-formed request, not a crash. */ stored: boolean; /** Whether what was stored survives this machine. */ durable: boolean; /** R3: names the store in-band, which also kills the f104e10d silent-local trap. */ stored_in: StoredIn; reason?: NotStoredReason; thread?: ThreadObject; error?: string; total_open: number; supabase_synced: boolean; supabase_error?: string; performance: PerformanceData; /** Phase 3: true when dedup gate found an existing duplicate */ deduplicated?: boolean; /** Phase 3: dedup gate details */ dedup?: { method: "embedding" | "token_overlap" | "text_normalization" | "skipped"; similarity: number | null; matched_thread_id: string | null; /** R2: the STORED text of the match, so the caller sees what it collided with. */ matched_text?: string; /** R2: both lengths, so a silent discard is arithmetically visible. */ stored_length?: number; submitted_length?: number; }; display?: string; } export declare function createThread(params: CreateThreadParams): Promise; //# sourceMappingURL=create-thread.d.ts.map