@circuitwall/jarela 0.14.0 → 1.0.0
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.
- package/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/app-path-routes-manifest.json +1 -1
- package/.next/standalone/.next/build-manifest.json +2 -2
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +2 -2
- package/.next/standalone/.next/server/app/_not-found.rsc +2 -2
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/api/v1/agents/[id]/route.js +6 -1
- package/.next/standalone/.next/server/app/api/v1/agents/[id]/route.js.map +1 -1
- package/.next/standalone/.next/server/app/api/v1/agents/route.js +6 -1
- package/.next/standalone/.next/server/app/api/v1/agents/route.js.map +1 -1
- package/.next/standalone/.next/server/app/api/v1/bridges/[id]/route.js +9 -1
- package/.next/standalone/.next/server/app/api/v1/bridges/[id]/route.js.map +1 -1
- package/.next/standalone/.next/server/app/api/v1/bridges/route.js +9 -1
- package/.next/standalone/.next/server/app/api/v1/bridges/route.js.map +1 -1
- package/.next/standalone/.next/server/app/api/v1/builtin-tools/route.js +36 -29
- package/.next/standalone/.next/server/app/api/v1/builtin-tools/route.js.map +1 -1
- package/.next/standalone/.next/server/app/api/v1/events/route.js +7 -1
- package/.next/standalone/.next/server/app/api/v1/events/route.js.map +1 -1
- package/.next/standalone/.next/server/app/api/v1/extensions/route.js +3 -3
- package/.next/standalone/.next/server/app/api/v1/extensions/route.js.map +1 -1
- package/.next/standalone/.next/server/app/api/v1/extensions/tools/[name]/secrets/route.js +4 -4
- package/.next/standalone/.next/server/app/api/v1/extensions/tools/[name]/secrets/route.js.map +1 -1
- package/.next/standalone/.next/server/app/api/v1/health/route.js +7 -1
- package/.next/standalone/.next/server/app/api/v1/health/route.js.map +1 -1
- package/.next/standalone/.next/server/app/api/v1/mcp-servers/[name]/route.js +9 -1
- package/.next/standalone/.next/server/app/api/v1/mcp-servers/[name]/route.js.map +1 -1
- package/.next/standalone/.next/server/app/api/v1/mcp-servers/route.js +9 -1
- package/.next/standalone/.next/server/app/api/v1/mcp-servers/route.js.map +1 -1
- package/.next/standalone/.next/server/app/api/v1/models/route.js +6 -1
- package/.next/standalone/.next/server/app/api/v1/models/route.js.map +1 -1
- package/.next/standalone/.next/server/app/api/v1/page-capture/route.js +7 -1
- package/.next/standalone/.next/server/app/api/v1/page-capture/route.js.map +1 -1
- package/.next/standalone/.next/server/app/api/v1/pending-actions/[id]/approve/route.js +14 -7
- package/.next/standalone/.next/server/app/api/v1/pending-actions/[id]/approve/route.js.map +1 -1
- package/.next/standalone/.next/server/app/api/v1/providers/[provider]/models/route.js +28 -0
- package/.next/standalone/.next/server/app/api/v1/providers/[provider]/models/route.js.map +1 -1
- package/.next/standalone/.next/server/app/api/v1/providers/route.js +7 -1
- package/.next/standalone/.next/server/app/api/v1/providers/route.js.map +1 -1
- package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/route.js +16 -2
- package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/route.js.map +1 -1
- package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/run/route.js +8 -1
- package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/run/route.js.map +1 -1
- package/.next/standalone/.next/server/app/api/v1/threads/route.js +6 -1
- package/.next/standalone/.next/server/app/api/v1/threads/route.js.map +1 -1
- package/.next/standalone/.next/server/app/api/v1/tools/route.js +10 -3
- package/.next/standalone/.next/server/app/api/v1/tools/route.js.map +1 -1
- package/.next/standalone/.next/server/app/index.html +2 -2
- package/.next/standalone/.next/server/app/index.rsc +3 -3
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +3 -3
- package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/page.js +56 -0
- package/.next/standalone/.next/server/app/page.js.map +1 -1
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/setup.html +1 -1
- package/.next/standalone/.next/server/app/setup.rsc +2 -2
- package/.next/standalone/.next/server/app/setup.segments/_full.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/setup.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/setup.segments/_index.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/setup.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/setup.segments/setup/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/setup.segments/setup.segment.rsc +1 -1
- package/.next/standalone/.next/server/app-paths-manifest.json +1 -1
- package/.next/standalone/.next/server/chunks/1683.js +2 -2
- package/.next/standalone/.next/server/chunks/2082.js +122 -13
- package/.next/standalone/.next/server/chunks/2082.js.map +1 -1
- package/.next/standalone/.next/server/chunks/210.js +3 -3
- package/.next/standalone/.next/server/chunks/210.js.map +1 -1
- package/.next/standalone/.next/server/chunks/239.js +1902 -1487
- package/.next/standalone/.next/server/chunks/239.js.map +1 -1
- package/.next/standalone/.next/server/chunks/2447.js +9 -1
- package/.next/standalone/.next/server/chunks/2447.js.map +1 -1
- package/.next/standalone/.next/server/chunks/423.js +125 -16
- package/.next/standalone/.next/server/chunks/423.js.map +1 -1
- package/.next/standalone/.next/server/chunks/4631.js +36 -29
- package/.next/standalone/.next/server/chunks/4631.js.map +1 -1
- package/.next/standalone/.next/server/chunks/5937.js +3 -2
- package/.next/standalone/.next/server/chunks/5937.js.map +1 -1
- package/.next/standalone/.next/server/chunks/{947.js → 8866.js} +11321 -10883
- package/.next/standalone/.next/server/chunks/8866.js.map +1 -0
- package/.next/standalone/.next/server/chunks/9032.js +3 -3
- package/.next/standalone/.next/server/chunks/9032.js.map +1 -1
- package/.next/standalone/.next/server/middleware-build-manifest.js +2 -2
- package/.next/standalone/.next/server/middleware.js +122 -13
- package/.next/standalone/.next/server/pages/404.html +2 -2
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/proxy.js.map +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/static/chunks/app/{page-473b39ec30c7f569.js → page-a7cae65f235e2942.js} +57 -1
- package/.next/standalone/.next/static/chunks/app/page-a7cae65f235e2942.js.map +1 -0
- package/.next/standalone/.next/static/css/{6f8b1a84bcbcd467.css → e57bdbbbb5a05779.css} +2 -2
- package/.next/standalone/.next/static/css/e57bdbbbb5a05779.css.map +1 -0
- package/.next/standalone/package.json +9 -1
- package/CHANGELOG.md +90 -0
- package/README.md +30 -2
- package/api/types.ts +8 -0
- package/app/api/v1/agents/[id]/route.ts +7 -0
- package/app/api/v1/agents/route.ts +7 -0
- package/app/api/v1/events/route.ts +8 -0
- package/app/api/v1/extensions/route.ts +2 -2
- package/app/api/v1/extensions/tools/[name]/secrets/route.ts +3 -3
- package/app/api/v1/health/route.ts +8 -0
- package/app/api/v1/models/route.ts +7 -0
- package/app/api/v1/page-capture/route.ts +8 -0
- package/app/api/v1/providers/route.ts +8 -0
- package/app/api/v1/threads/[thread_id]/route.ts +8 -0
- package/app/api/v1/threads/[thread_id]/run/route.ts +9 -0
- package/app/api/v1/threads/route.ts +7 -0
- package/app/api/v1/tools/route.ts +9 -0
- package/components/chat/ContextUsageBar.tsx +44 -0
- package/lib/agents/llm.ts +25 -2
- package/lib/agents/run-thread.ts +13 -1
- package/lib/agents/stream-collector.ts +9 -1
- package/lib/api/serializers.test.ts +15 -0
- package/lib/api/serializers.ts +8 -0
- package/lib/db/migrations.ts +15 -0
- package/lib/health/runner.test.ts +24 -2
- package/lib/mcp/registry.ts +14 -6
- package/lib/providers/anthropic.test.ts +95 -0
- package/lib/providers/anthropic.ts +106 -10
- package/lib/providers/jarela-chat-model.ts +9 -1
- package/lib/providers/known-context-windows.ts +21 -0
- package/lib/providers/types.ts +21 -1
- package/lib/stores/message-usage.test.ts +34 -0
- package/lib/stores/message-usage.ts +15 -3
- package/lib/stores/pricing.test.ts +52 -0
- package/lib/stores/pricing.ts +26 -1
- package/lib/tools/builtins.ts +4 -0
- package/lib/tools/extension-surfaces.test.ts +79 -0
- package/lib/tools/extension-surfaces.ts +153 -0
- package/lib/tools/index.ts +27 -8
- package/lib/tools/list-tools.test.ts +76 -0
- package/lib/tools/list-tools.ts +84 -0
- package/lib/tools/mcp-servers-info.test.ts +73 -0
- package/lib/tools/mcp-servers-info.ts +71 -0
- package/lib/tools/providers-info.test.ts +73 -0
- package/lib/tools/providers-info.ts +106 -0
- package/lib/tools/registry.ts +36 -25
- package/lib/tools/types.ts +13 -0
- package/package.json +9 -1
- package/.next/standalone/.next/server/chunks/947.js.map +0 -1
- package/.next/standalone/.next/static/chunks/app/page-473b39ec30c7f569.js.map +0 -1
- package/.next/standalone/.next/static/css/6f8b1a84bcbcd467.css.map +0 -1
- /package/.next/standalone/.next/static/{T0p2VVPsJPj44rwbmjaFb → d_vhp-lJqfdjRFpnLVIqZ}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{T0p2VVPsJPj44rwbmjaFb → d_vhp-lJqfdjRFpnLVIqZ}/_ssgManifest.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"4631.js","mappings":"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","sources":["webpack://@circuitwall/jarela/./lib/utils/global-state.ts","webpack://@circuitwall/jarela/./lib/tools/wallclock.ts","webpack://@circuitwall/jarela/./lib/tools/registry.ts","webpack://@circuitwall/jarela/./lib/documents/remote/flatten.ts","webpack://@circuitwall/jarela/./lib/documents/remote/upsert.ts","webpack://@circuitwall/jarela/./lib/documents/remote/confluence.ts","webpack://@circuitwall/jarela/./lib/documents/remote/mail.ts","webpack://@circuitwall/jarela/./lib/documents/remote/jira.ts","webpack://@circuitwall/jarela/./lib/documents/remote/github.ts","webpack://@circuitwall/jarela/./lib/documents/remote/index.ts","webpack://@circuitwall/jarela/./lib/utils/text.ts","webpack://@circuitwall/jarela/./lib/utils/json.ts","webpack://@circuitwall/jarela/./lib/utils/oauth-flow-store.ts","webpack://@circuitwall/jarela/./lib/tools/atlassian.ts","webpack://@circuitwall/jarela/./lib/tools/github.ts","webpack://@circuitwall/jarela/./lib/documents/chunker.ts","webpack://@circuitwall/jarela/./lib/documents/indexer.ts","webpack://@circuitwall/jarela/./lib/utils/html.ts","webpack://@circuitwall/jarela/./lib/integrations/gmail-oauth.ts","webpack://@circuitwall/jarela/./lib/integrations/microsoft-oauth.ts","webpack://@circuitwall/jarela/./lib/stores/document-sources.ts"],"sourcesContent":["// Pin a piece of state to globalThis so it survives Next.js dev hot-reload.\n//\n// Without this, every code edit re-evaluates the module, replacing the\n// in-memory state with empty containers — but any active closure still\n// references the OLD set, so listeners/timers/maps go silently dead.\n// The globalThis trick is the standard Next pattern for singletons.\n//\n// `key` must be unique across the app (it lives on globalThis); pick a\n// \"__jarela_<name>\" prefix to keep the namespace tidy.\nexport function getOrCreateGlobal<T>(key: string, factory: () => T): T {\n const g = globalThis as unknown as Record<string, unknown>;\n if (g[key] === undefined) g[key] = factory();\n return g[key] as T;\n}\n","// Per-call wall-clock budgets for tools.\n//\n// Every registered tool is wrapped with a Promise.race against a timer\n// the LLM controls via an injected `deadline_ms` schema field. When the\n// timer fires first, the wrapped tool returns a structured timeout result\n// to the agent instead of throwing — the turn continues, the agent gets a\n// tool message saying \"timed out\", and can recover (retry differently,\n// split the work, or move on).\n//\n// Why \"agent self-set\" instead of a global env knob: the right deadline\n// is hugely context-dependent (a 5s budget for a memory_read is right;\n// the same budget for `npm install` is absurd). The model knows what\n// it's calling, so the model picks. The `deadline_ms` field on every\n// tool's schema makes that picker explicit and self-documenting.\n//\n// Caveat: the underlying tool's promise is abandoned, not aborted. A\n// network call or subprocess started by the tool keeps running until it\n// settles into the void. Tools that own a long-lived resource (fetch,\n// exec) should use the `deadline_ms` value themselves to drive their own\n// abort signal — the wallclock wrapper is the backstop, not the only\n// mechanism.\n\nimport { z } from \"zod\";\nimport { tool, type StructuredToolInterface } from \"@langchain/core/tools\";\n\nconst DEFAULT_DEADLINE_MS = 120_000;\n\nconst DEADLINE_DESCRIPTION =\n \"Optional wall-clock budget for this tool call in milliseconds (default 120000). \" +\n \"When the budget is exceeded the call returns a structured timeout result \" +\n \"and the turn continues so you can recover — pick a value that matches \" +\n \"the expected duration (5000-15000 for fast local ops, 30000-90000 for \" +\n \"network/web calls, larger for shell commands that may build or install).\";\n\ninterface WallclockedFunc {\n (args: Record<string, unknown>, config?: unknown): Promise<unknown>;\n}\n\nexport function wrapWithWallclock<T extends StructuredToolInterface>(t: T): T {\n // Only zod-object schemas can be extended with `deadline_ms`. Other\n // schema shapes (raw JSON Schema, ZodString) pass through unchanged.\n // Those tools still get the wallclock race using the default budget.\n const schema = (t as unknown as { schema: unknown }).schema;\n const extendedSchema = schema instanceof z.ZodObject\n ? schema.extend({ deadline_ms: z.number().int().positive().optional().describe(DEADLINE_DESCRIPTION) })\n : null;\n\n const wrappedFunc: WallclockedFunc = async (args, config) => {\n const deadlineMs = readDeadlineMs(args) ?? DEFAULT_DEADLINE_MS;\n const innerArgs = stripDeadline(args);\n\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeoutPromise = new Promise<string>((resolve) => {\n timer = setTimeout(() => {\n resolve(JSON.stringify({\n ok: false,\n error_code: \"tool_timeout\",\n message:\n `Tool \"${t.name}\" exceeded its wall-clock budget of ${deadlineMs}ms. ` +\n `The call was abandoned; the underlying operation may still be running in the background. ` +\n `Recover by trying a different approach, splitting the work, or moving on — do not retry the same call with the same arguments.`,\n deadline_ms: deadlineMs,\n }));\n }, deadlineMs);\n // Don't keep the event loop alive purely for a timeout race.\n (timer as unknown as { unref?: () => void }).unref?.();\n });\n\n try {\n // Cast: invoke accepts a typed input matching the original schema,\n // but the wrapper is generic over all tools.\n const work = (t as unknown as { invoke: (a: unknown, c?: unknown) => Promise<unknown> }).invoke(innerArgs, config);\n return await Promise.race([work, timeoutPromise]);\n } finally {\n if (timer) clearTimeout(timer);\n }\n };\n\n // Rebuild via the public `tool()` factory so we don't depend on\n // internal field shapes of the StructuredTool class. The new tool\n // keeps the original's name and description, swaps in the extended\n // schema, and routes invocation through wrappedFunc.\n const rebuilt = tool(\n wrappedFunc as never,\n {\n name: t.name,\n description: t.description ?? \"\",\n schema: (extendedSchema ?? schema) as never,\n } as never,\n );\n return rebuilt as unknown as T;\n}\n\nfunction readDeadlineMs(args: Record<string, unknown> | unknown): number | null {\n if (!args || typeof args !== \"object\") return null;\n const v = (args as Record<string, unknown>).deadline_ms;\n return typeof v === \"number\" && Number.isFinite(v) && v > 0 ? v : null;\n}\n\nfunction stripDeadline(args: Record<string, unknown> | unknown): Record<string, unknown> | unknown {\n if (!args || typeof args !== \"object\") return args;\n const { deadline_ms: _ignore, ...rest } = args as Record<string, unknown>;\n void _ignore;\n return rest;\n}\n\n/** Exposed for the tests. */\nexport const __DEFAULT_DEADLINE_MS = DEFAULT_DEADLINE_MS;\n","// Tool registry.\n//\n// Each built-in tool module registers its own tools at module load with\n// two orthogonal axes:\n//\n// * category — topical group (\"Memory\", \"Files\", \"Mail\", …) used by\n// the Agent editor sidebar to organise tools for users.\n// * capability — safety class (\"read\" | \"write\" | \"execute\") used by\n// the future per-capability approval gate, UI badges,\n// and the ADR-0037 output validator. See ADR-0038.\n//\n// lib/tools/index.ts only needs to side-effect-import the modules\n// (see ./builtins.ts) — there is no central map listing every tool by\n// name. Adding a new built-in tool now requires touching exactly two\n// files: the tool file itself, and an `import \"./<name>\";` line in\n// builtins.ts.\n//\n// External tools (loaded from JARELA_TOOLS_DIR at runtime) use the same\n// category vocabulary but are not stored in this registry — see\n// ./external.ts. MCP tools default to category \"MCP\". Both default to\n// capability \"execute\" until manifest-level overrides land (ADR-0038\n// follow-up).\n\nimport type { StructuredToolInterface } from \"@langchain/core/tools\";\nimport { wrapWithWallclock } from \"./wallclock\";\n\nexport type ToolCategory =\n | \"Memory\" | \"Documents\" | \"Files\" | \"Shell\" | \"Web\" | \"Images\" | \"Voice\"\n | \"Schedule\" | \"Atlassian\" | \"JiraAlign\" | \"GitHub\" | \"Mail\" | \"Calendar\" | \"Config\" | \"Agent\" | \"MCP\";\n\n// Safety class. Orthogonal to ToolCategory. See ADR-0038 for definitions\n// and tie-breakers (network reads vs writes, drafts, etc.).\nexport type Capability = \"read\" | \"write\" | \"execute\";\n\n// Optional parent grouping for the Agent editor sidebar.\nexport type ToolGroup = \"Work\" | null;\n\n// Category → group mapping. \"Work\" collapses corporate-auth tools under\n// one header in the Agent editor; everything else is a top-level category.\nconst CATEGORY_GROUPS: Record<Exclude<ToolCategory, \"MCP\">, ToolGroup> = {\n Memory: null, Documents: null, Files: null, Shell: null, Web: null, Images: null, Voice: null,\n Schedule: null, Config: null, Mail: null, Calendar: null, Agent: null,\n Atlassian: \"Work\", JiraAlign: \"Work\", GitHub: \"Work\",\n};\n\nexport type BuiltinCategory = Exclude<ToolCategory, \"MCP\">;\n\ninterface RegistryEntry {\n tool: StructuredToolInterface;\n category: BuiltinCategory;\n capability: Capability;\n group: ToolGroup;\n}\n\nconst REGISTRY = new Map<string, RegistryEntry>();\n\n/**\n * Register one or more tools under a category and capability. Call this at\n * the bottom of each tool file (after the tools are defined). Files with\n * mixed capabilities make multiple calls — see ADR-0038. Throws on\n * duplicate names — collisions are bugs, not warnings.\n */\nexport function registerTools<T extends StructuredToolInterface>(\n category: BuiltinCategory,\n capability: Capability,\n tools: readonly T[],\n): readonly T[] {\n const group = CATEGORY_GROUPS[category];\n const wrapped: T[] = [];\n for (const t of tools) {\n if (REGISTRY.has(t.name)) {\n throw new Error(`[tools] duplicate built-in tool registration: ${t.name}`);\n }\n // Every built-in tool gets the agent-controlled wall-clock wrap so a\n // single stuck call (network hang, fs on a wedged cloud-sync drive,\n // runaway shell) can't pin the turn — see lib/tools/wallclock.ts.\n const w = wrapWithWallclock(t);\n REGISTRY.set(w.name, { tool: w, category, capability, group });\n wrapped.push(w);\n }\n return wrapped;\n}\n\n/** All registered built-in tools, in registration order. */\nexport function registeredTools(): StructuredToolInterface[] {\n return Array.from(REGISTRY.values(), (e) => e.tool);\n}\n\n/** Names of all registered built-in tools — used for collision checks. */\nexport function registeredNames(): ReadonlySet<string> {\n return new Set(REGISTRY.keys());\n}\n\nexport function registeredCategory(name: string): BuiltinCategory | undefined {\n return REGISTRY.get(name)?.category;\n}\n\nexport function registeredCapability(name: string): Capability | undefined {\n return REGISTRY.get(name)?.capability;\n}\n\nexport function registeredGroup(name: string): ToolGroup | undefined {\n return REGISTRY.get(name)?.group;\n}\n\n/** Test-only: clear the registry between cases. */\nexport function _resetRegistry(): void {\n REGISTRY.clear();\n}\n","// Plain-text flatteners for remote document RAG (ADR-0026).\n//\n// Jira issue bodies and comments arrive as Atlassian Document Format\n// (ADF) — a JSON tree of typed nodes. Confluence page bodies arrive as\n// HTML (the `storage` representation). Both have to be flattened to plain\n// text before being chunked by `lib/documents/chunker.ts`, which assumes\n// paragraph-delimited text.\n//\n// These flatteners are intentionally lossy: they keep textual content\n// and paragraph structure, drop markup, links, attachments, embeds.\n// \"Good enough for retrieval\" is the bar — not \"round-trips to source\".\n\ninterface AdfNode {\n type?: string;\n text?: string;\n content?: AdfNode[];\n}\n\n/** Flatten an ADF JSON tree into paragraph-separated plain text. */\nexport function adfToText(adf: unknown): string {\n if (!adf || typeof adf !== \"object\") return \"\";\n const parts: string[] = [];\n function walk(node: AdfNode, depth = 0): void {\n if (!node) return;\n if (typeof node.text === \"string\") {\n parts.push(node.text);\n return;\n }\n const block = node.type && /paragraph|heading|listItem|codeBlock|blockquote|panel/.test(node.type);\n if (Array.isArray(node.content)) {\n for (const c of node.content) walk(c, depth + 1);\n }\n if (block) parts.push(\"\\n\\n\");\n }\n walk(adf as AdfNode);\n // Collapse runs of >2 newlines and trim.\n return parts.join(\"\").replace(/\\n{3,}/g, \"\\n\\n\").trim();\n}\n\n/** Strip Confluence storage-format HTML to plain text. */\nexport function htmlToText(html: string): string {\n if (!html) return \"\";\n let s = html;\n // Drop script / style blocks entirely.\n s = s.replace(/<(script|style)[^>]*>[\\s\\S]*?<\\/\\1>/gi, \"\");\n // Confluence macros sometimes embed CDATA — keep the inner text.\n s = s.replace(/<!\\[CDATA\\[([\\s\\S]*?)\\]\\]>/g, \"$1\");\n // Block-level closes → newline.\n s = s.replace(/<\\/(p|div|h[1-6]|li|tr|br|hr|blockquote|pre)\\s*>/gi, \"\\n\");\n // Self-closing <br>.\n s = s.replace(/<br\\s*\\/?>/gi, \"\\n\");\n // Drop all remaining tags.\n s = s.replace(/<[^>]+>/g, \"\");\n // Decode the handful of entities Atlassian actually emits.\n s = s\n .replace(/ /g, \" \")\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\")\n .replace(/'/g, \"'\");\n // Collapse runs of >2 newlines and trim trailing space per line.\n return s.replace(/[ \\t]+\\n/g, \"\\n\").replace(/\\n{3,}/g, \"\\n\\n\").trim();\n}\n","// Shared upsert path for remote document sources (ADR-0026).\n//\n// Remote sources (Jira issues, Confluence pages) don't have an mtime or a\n// stable filesystem path — the upstream `updated` timestamp plays the same\n// role as mtime, and we synthesize a stable `path` per item (`jira://KEY`\n// or `confluence://pageId`). The rest of the indexed shape matches local\n// folder documents so retrieval through searchDocuments works unchanged.\n\nimport { randomUUID, createHash } from \"node:crypto\";\nimport { getDb } from \"@/lib/db\";\nimport { chunkAndEmbedDocument } from \"../indexer\";\n\nexport interface RemoteDocInput {\n /** Stable synthetic path, e.g. \"jira://ABC-123\" or \"confluence://12345\". */\n path: string;\n /** Human-readable title shown in retrieval results (Jira key+summary,\n * Confluence page title). Stored in `rel_path` so the existing search\n * UI shows it without schema changes. */\n title: string;\n /** ISO timestamp of the upstream `updated` field. Drives change detection\n * via the same column the local indexer uses for filesystem mtime\n * (re-purposed: we hash this string into mtime_ms). */\n externalUpdatedAt: string;\n /** Plain-text body to chunk + embed. Already flattened (ADF→text,\n * HTML→text) by the caller. */\n text: string;\n}\n\ninterface IndexedRow {\n id: string;\n mtime_ms: number;\n content_hash: string;\n}\n\nfunction findExisting(sourceId: string, path: string): IndexedRow | null {\n const row = getDb()\n .prepare(\"SELECT id, mtime_ms, content_hash FROM documents WHERE source_id=? AND path=?\")\n .get(sourceId, path) as IndexedRow | undefined;\n return row ?? null;\n}\n\n// Map an ISO string to a stable integer so we can store it in the existing\n// `mtime_ms` column without a schema change. Hashing keeps the column\n// useful for \"did the upstream record change?\" checks even though ms\n// resolution is meaningless for remote sources.\nfunction isoToMtime(iso: string): number {\n const t = Date.parse(iso);\n if (Number.isFinite(t)) return t;\n // Fall back to a deterministic hash so duplicate calls with the same\n // string still produce the same value.\n const h = createHash(\"sha1\").update(iso).digest();\n return h.readUInt32BE(0);\n}\n\nfunction hashContent(text: string): string {\n return createHash(\"sha256\").update(text).digest(\"hex\");\n}\n\nexport interface UpsertResult {\n status: \"unchanged\" | \"added\" | \"updated\";\n /** Total chunks produced for this document (0 when unchanged). */\n chunks: number;\n /** Chunks that successfully got an embedding vector. */\n embedded: number;\n /** First embed error seen for this document, if any. */\n embedError: string | null;\n}\n\n/**\n * Insert-or-update a single remote document. Returns whether anything\n * actually changed so the caller can update incremental-sync counters.\n * Re-chunks + re-embeds when content changed; otherwise just touches\n * the indexed-at timestamp.\n */\nexport async function upsertRemoteDocument(\n sourceId: string,\n input: RemoteDocInput,\n): Promise<UpsertResult> {\n const db = getDb();\n const t = new Date().toISOString();\n const hash = hashContent(input.text);\n const mtime = isoToMtime(input.externalUpdatedAt);\n const existing = findExisting(sourceId, input.path);\n\n if (existing && existing.content_hash === hash) {\n db.prepare(\"UPDATE documents SET mtime_ms=?, last_indexed_at=? WHERE id=?\")\n .run(mtime, t, existing.id);\n return { status: \"unchanged\", chunks: 0, embedded: 0, embedError: null };\n }\n\n const docId = existing?.id ?? randomUUID();\n const size = Buffer.byteLength(input.text, \"utf8\");\n\n if (existing) {\n db.prepare(\n `UPDATE documents\n SET path=?, rel_path=?, mtime_ms=?, size_bytes=?, content_hash=?, last_indexed_at=?\n WHERE id=?`,\n ).run(input.path, input.title, mtime, size, hash, t, existing.id);\n db.prepare(\"DELETE FROM document_chunks WHERE document_id=?\").run(existing.id);\n } else {\n db.prepare(\n `INSERT INTO documents\n (id, source_id, path, rel_path, mtime_ms, size_bytes, content_hash, last_indexed_at, chunk_count)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, 0)`,\n ).run(docId, sourceId, input.path, input.title, mtime, size, hash, t);\n }\n\n const r = await chunkAndEmbedDocument(docId, input.text, input.path);\n return {\n status: existing ? \"updated\" : \"added\",\n chunks: r.chunks,\n embedded: r.embedded,\n embedError: r.embedError,\n };\n}\n\n/**\n * Drop every indexed document for `sourceId` whose `path` isn't in the\n * keep-set. Returns the count removed. Remote indexers use this only for\n * \"full re-sync\" semantics — incremental syncs don't call it (an upstream\n * item disappearing doesn't necessarily mean it should be evicted; we'd\n * rather keep stale-but-useful content than punch holes silently).\n */\nexport function evictMissing(sourceId: string, keepPaths: Set<string>): number {\n const db = getDb();\n const rows = db.prepare(\"SELECT id, path FROM documents WHERE source_id=?\")\n .all(sourceId) as Array<{ id: string; path: string }>;\n let removed = 0;\n const del = db.prepare(\"DELETE FROM documents WHERE id=?\");\n for (const r of rows) {\n if (!keepPaths.has(r.path)) {\n del.run(r.id);\n removed++;\n }\n }\n return removed;\n}\n","// Confluence remote indexer (ADR-0026).\n//\n// Source kinds handled:\n// - confluence_space → CQL `space = \"<key>\" AND type = page`\n// - confluence_cql → user-supplied CQL (still scoped to `type = page`)\n//\n// Incremental: uses `last_cursor` to avoid re-fetching pages whose\n// `lastmodified` is older than the previous run's high-water mark.\n\nimport {\n _atlassianFetch,\n _resolveAtlassianAuth,\n type AtlassianAuth,\n} from \"@/lib/tools/atlassian\";\nimport {\n parseSourceConfig,\n updateDocumentSourceCursor,\n type DocumentSourceRow,\n} from \"@/lib/stores/document-sources\";\nimport { htmlToText } from \"./flatten\";\nimport { upsertRemoteDocument, type UpsertResult } from \"./upsert\";\n\nconst PAGE_LIMIT = 25;\nconst MAX_PAGES_PER_RUN = 200;\n\ninterface ConfluencePage {\n id: string;\n title: string;\n version?: { when?: string };\n history?: { lastUpdated?: { when?: string }; createdDate?: string };\n body?: { storage?: { value?: string } };\n _links?: { webui?: string };\n}\ninterface ConfluenceSearchResp {\n results?: ConfluencePage[];\n start?: number;\n size?: number;\n limit?: number;\n}\n\nfunction buildCql(source: DocumentSourceRow, since: string | null): string {\n const cfg = parseSourceConfig<{ space_key?: string; cql?: string; recency_days?: number }>(source) ?? {};\n const clauses: string[] = [\"type = page\"];\n if (source.kind === \"confluence_space\") {\n if (!cfg.space_key) throw new Error(\"confluence_space requires config.space_key\");\n clauses.push(`space = \"${cfg.space_key}\"`);\n } else if (source.kind === \"confluence_cql\") {\n if (!cfg.cql) throw new Error(\"confluence_cql requires config.cql\");\n clauses.push(`(${cfg.cql})`);\n }\n if (since) clauses.push(`lastmodified > \"${since.slice(0, 10)}\"`);\n if (cfg.recency_days && cfg.recency_days > 0) {\n clauses.push(`lastmodified > now(\"-${cfg.recency_days}d\")`);\n }\n return clauses.join(\" AND \");\n}\n\nfunction pageUpdatedAt(p: ConfluencePage): string {\n return (\n p.version?.when ??\n p.history?.lastUpdated?.when ??\n p.history?.createdDate ??\n new Date().toISOString()\n );\n}\n\nasync function fetchPage(auth: AtlassianAuth, pageId: string): Promise<ConfluencePage | null> {\n const data = await _atlassianFetch(\n auth,\n `/wiki/rest/api/content/${encodeURIComponent(pageId)}?expand=body.storage,version,history.lastUpdated`,\n ) as ConfluencePage & { error?: string };\n if (!data || (data as { error?: string }).error) return null;\n return data;\n}\n\nexport interface ConfluenceIndexStats {\n scanned: number;\n added: number;\n updated: number;\n unchanged: number;\n errors: number;\n cursor: string | null;\n embedFailed: number;\n embedError: string | null;\n}\n\nexport async function runConfluenceIndexer(source: DocumentSourceRow): Promise<ConfluenceIndexStats> {\n const stats: ConfluenceIndexStats = {\n scanned: 0, added: 0, updated: 0, unchanged: 0, errors: 0,\n cursor: source.last_cursor,\n embedFailed: 0, embedError: null,\n };\n const auth = _resolveAtlassianAuth();\n if (\"error\" in auth) throw new Error(auth.error);\n\n const cql = buildCql(source, source.last_cursor);\n let start = 0;\n let highWater = source.last_cursor;\n\n while (stats.scanned < MAX_PAGES_PER_RUN) {\n const url = `/wiki/rest/api/content/search?cql=${encodeURIComponent(cql)}` +\n `&expand=body.storage,version,history.lastUpdated&limit=${PAGE_LIMIT}&start=${start}`;\n const data = await _atlassianFetch(auth, url) as ConfluenceSearchResp & { error?: string };\n if ((data as { error?: string }).error) throw new Error((data as { error?: string }).error);\n const results = data.results ?? [];\n if (results.length === 0) break;\n\n for (const page of results) {\n stats.scanned++;\n try {\n const text = `${page.title}\\n\\n${htmlToText(page.body?.storage?.value ?? \"\")}`.trim();\n const updatedAt = pageUpdatedAt(page);\n const res: UpsertResult = await upsertRemoteDocument(source.id, {\n path: `confluence://${page.id}`,\n title: page.title,\n externalUpdatedAt: updatedAt,\n text,\n });\n if (res.status === \"added\") stats.added++;\n else if (res.status === \"updated\") stats.updated++;\n else stats.unchanged++;\n stats.embedFailed += res.chunks - res.embedded;\n if (res.embedError && !stats.embedError) stats.embedError = res.embedError;\n if (!highWater || updatedAt > highWater) highWater = updatedAt;\n } catch {\n stats.errors++;\n }\n }\n start += results.length;\n if (results.length < PAGE_LIMIT) break;\n }\n\n if (highWater && highWater !== source.last_cursor) {\n updateDocumentSourceCursor(source.id, highWater);\n stats.cursor = highWater;\n }\n return stats;\n}\n\n/**\n * On-demand: fetch a single Confluence page by id and index it under the\n * shared \"on_demand_url\" source row. Used by the `documents_index_url` tool\n * for \"just pull THIS one page\".\n */\nexport async function indexConfluencePageById(\n sourceId: string,\n pageId: string,\n): Promise<UpsertResult> {\n const auth = _resolveAtlassianAuth();\n if (\"error\" in auth) throw new Error(auth.error);\n const page = await fetchPage(auth, pageId);\n if (!page) throw new Error(`confluence page ${pageId} not found`);\n const text = `${page.title}\\n\\n${htmlToText(page.body?.storage?.value ?? \"\")}`.trim();\n return upsertRemoteDocument(sourceId, {\n path: `confluence://${page.id}`,\n title: page.title,\n externalUpdatedAt: pageUpdatedAt(page),\n text,\n });\n}\n","// Remote mail indexing for Gmail and Outlook.\n//\n// These sources let the user index a filtered slice of mailbox content as\n// searchable documents. The query field is intentionally provider-native:\n// Gmail uses Gmail query syntax, Outlook uses KQL.\n\nimport { stripHtml } from \"@/lib/utils/html\";\nimport { truncateBytes } from \"@/lib/utils/text\";\nimport { googleFetch, resolveGoogleAuth } from \"@/lib/integrations/gmail-oauth\";\nimport { graphFetch, resolveMicrosoftAuth } from \"@/lib/integrations/microsoft-oauth\";\nimport { parseSourceConfig, type DocumentSourceRow } from \"@/lib/stores/document-sources\";\nimport { evictMissing, upsertRemoteDocument } from \"./upsert\";\n\nimport type { RemoteIndexStats } from \"./index\";\n\nconst BODY_CAP = 40_000;\nconst DEFAULT_MAX_RESULTS = 250;\nconst DEFAULT_PAGE_SIZE = 100;\nconst MAX_RESULTS_CAP = 5_000;\n\ninterface Header {\n name?: string;\n value?: string;\n}\n\ninterface GmailMessageList {\n messages?: Array<{ id: string; threadId?: string }>;\n nextPageToken?: string;\n resultSizeEstimate?: number;\n error?: string;\n}\n\ninterface GmailMessage {\n id?: string;\n threadId?: string;\n internalDate?: string;\n snippet?: string;\n labelIds?: string[];\n payload?: {\n headers?: Header[];\n mimeType?: string;\n filename?: string;\n body?: { data?: string };\n parts?: GmailMessage[\"payload\"][];\n };\n error?: string;\n}\n\ninterface GraphEmailAddress {\n name?: string;\n address?: string;\n}\n\ninterface GraphRecipient {\n emailAddress?: GraphEmailAddress;\n}\n\ninterface GraphMessage {\n id?: string;\n conversationId?: string;\n subject?: string;\n bodyPreview?: string;\n body?: { contentType?: \"html\" | \"text\"; content?: string };\n from?: GraphRecipient;\n toRecipients?: GraphRecipient[];\n ccRecipients?: GraphRecipient[];\n receivedDateTime?: string;\n lastModifiedDateTime?: string;\n isRead?: boolean;\n isDraft?: boolean;\n hasAttachments?: boolean;\n categories?: string[];\n parentFolderId?: string;\n webLink?: string;\n}\n\nfunction header(headers: Header[] | undefined, name: string): string | null {\n const hit = (headers ?? []).find((h) => (h.name ?? \"\").toLowerCase() === name.toLowerCase());\n return hit?.value ?? null;\n}\n\nfunction decodeBase64Url(s: string): string {\n try {\n return Buffer.from(s, \"base64url\").toString(\"utf8\");\n } catch {\n return \"\";\n }\n}\n\nfunction findPart(part: { mimeType?: string; filename?: string; body?: { data?: string }; parts?: Array<unknown> } | undefined, mime: string): { mimeType?: string; filename?: string; body?: { data?: string }; parts?: Array<unknown> } | null {\n if (!part) return null;\n if (part.mimeType === mime && !part.filename && part.body?.data) return part;\n for (const child of part.parts ?? []) {\n const hit = findPart(child as Parameters<typeof findPart>[0], mime);\n if (hit) return hit;\n }\n return null;\n}\n\nfunction extractGmailBody(payload: GmailMessage[\"payload\"] | undefined): string {\n if (!payload) return \"\";\n const plain = findPart(payload, \"text/plain\") as { body?: { data?: string } } | null;\n if (plain?.body?.data) return decodeBase64Url(plain.body.data);\n const html = findPart(payload, \"text/html\") as { body?: { data?: string } } | null;\n if (html?.body?.data) {\n return stripHtml(decodeBase64Url(html.body.data), { preserveParagraphs: true });\n }\n return \"\";\n}\n\nfunction recipientToStr(r?: GraphRecipient): string | null {\n const addr = r?.emailAddress?.address;\n if (!addr) return null;\n const name = r?.emailAddress?.name;\n return name && name !== addr ? `${name} <${addr}>` : addr;\n}\n\nfunction summarizeGraphMessage(m: GraphMessage): { title: string; text: string; updatedAt: string } {\n const from = recipientToStr(m.from) ?? \"\";\n const to = (m.toRecipients ?? []).map(recipientToStr).filter(Boolean).join(\", \");\n const cc = (m.ccRecipients ?? []).map(recipientToStr).filter(Boolean).join(\", \");\n const body = m.body?.content ?? m.bodyPreview ?? \"\";\n const plain = m.body?.contentType === \"html\"\n ? stripHtml(body, { preserveParagraphs: true })\n : body;\n const { text: capped } = truncateBytes(plain, BODY_CAP);\n const text = [\n `From: ${from}`,\n to ? `To: ${to}` : null,\n cc ? `Cc: ${cc}` : null,\n m.subject ? `Subject: ${m.subject}` : null,\n m.receivedDateTime ? `Date: ${m.receivedDateTime}` : null,\n \"\",\n capped,\n ].filter((line): line is string => line !== null).join(\"\\n\");\n return {\n title: m.subject?.trim() || m.id || \"(no subject)\",\n text,\n updatedAt: m.lastModifiedDateTime ?? m.receivedDateTime ?? new Date().toISOString(),\n };\n}\n\nfunction gmailSourceConfig(row: DocumentSourceRow): { query: string; max_results: number; page_size: number } {\n const cfg = parseSourceConfig<{ query?: string; max_results?: number; page_size?: number }>(row) ?? {};\n const query = String(cfg.query ?? \"\").trim();\n if (!query) throw new Error(\"gmail_mail source config.query is required\");\n const max_results = Math.min(Math.max(Number(cfg.max_results ?? DEFAULT_MAX_RESULTS), 1), MAX_RESULTS_CAP);\n const page_size = Math.min(Math.max(Number(cfg.page_size ?? DEFAULT_PAGE_SIZE), 1), 100);\n return { query, max_results, page_size };\n}\n\nfunction outlookSourceConfig(row: DocumentSourceRow): { query: string; max_results: number; page_size: number } {\n const cfg = parseSourceConfig<{ query?: string; max_results?: number; page_size?: number }>(row) ?? {};\n const query = String(cfg.query ?? \"\").trim();\n if (!query) throw new Error(\"outlook_mail source config.query is required\");\n const max_results = Math.min(Math.max(Number(cfg.max_results ?? DEFAULT_MAX_RESULTS), 1), MAX_RESULTS_CAP);\n const page_size = Math.min(Math.max(Number(cfg.page_size ?? DEFAULT_PAGE_SIZE), 1), 100);\n return { query, max_results, page_size };\n}\n\nasync function indexGmailMail(row: DocumentSourceRow): Promise<RemoteIndexStats> {\n const auth = resolveGoogleAuth();\n if (\"error\" in auth) throw new Error(auth.error);\n const { query, max_results, page_size } = gmailSourceConfig(row);\n\n const stats: RemoteIndexStats = { scanned: 0, added: 0, updated: 0, unchanged: 0, errors: 0 };\n const keep = new Set<string>();\n let pageToken: string | undefined;\n\n while (stats.scanned < max_results) {\n const limit = Math.min(page_size, max_results - stats.scanned);\n const qs = new URLSearchParams({ q: query, maxResults: String(limit) });\n if (pageToken) qs.set(\"pageToken\", pageToken);\n const list = await googleFetch(\n auth,\n \"Gmail\",\n \"https://gmail.googleapis.com/gmail/v1/users/me\",\n `/messages?${qs.toString()}`,\n ) as GmailMessageList;\n if (list.error) throw new Error(list.error);\n\n const batch = list.messages ?? [];\n if (batch.length === 0) break;\n\n const results = await Promise.all(batch.slice(0, limit).map(async (entry) => {\n const msg = await googleFetch(\n auth,\n \"Gmail\",\n \"https://gmail.googleapis.com/gmail/v1/users/me\",\n `/messages/${encodeURIComponent(entry.id)}?format=full`,\n ) as GmailMessage;\n if (msg.error) throw new Error(msg.error);\n const title = msg.payload ? header(msg.payload.headers, \"Subject\") ?? entry.id : entry.id;\n const body = extractGmailBody(msg.payload);\n const text = [\n `From: ${header(msg.payload?.headers, \"From\") ?? \"\"}`,\n `To: ${header(msg.payload?.headers, \"To\") ?? \"\"}`,\n `Subject: ${title}`,\n `Date: ${header(msg.payload?.headers, \"Date\") ?? \"\"}`,\n msg.snippet ? `Snippet: ${msg.snippet}` : null,\n \"\",\n body,\n ].filter((line): line is string => line !== null).join(\"\\n\");\n const updatedAt = msg.internalDate\n ? new Date(Number(msg.internalDate)).toISOString()\n : header(msg.payload?.headers, \"Date\") ?? new Date().toISOString();\n return upsertRemoteDocument(row.id, {\n path: `gmail://${entry.id}`,\n title,\n externalUpdatedAt: updatedAt,\n text,\n });\n }));\n\n for (const [index, item] of results.entries()) {\n const id = batch[index]?.id ?? \"\";\n if (id) keep.add(`gmail://${id}`);\n stats.scanned++;\n stats.added += item.status === \"added\" ? 1 : 0;\n stats.updated += item.status === \"updated\" ? 1 : 0;\n stats.unchanged += item.status === \"unchanged\" ? 1 : 0;\n stats.errors += item.embedError ? 1 : 0;\n stats.embedFailed = (stats.embedFailed ?? 0) + Math.max(item.chunks - item.embedded, 0);\n if (item.embedError && !stats.embedError) stats.embedError = item.embedError;\n }\n\n pageToken = list.nextPageToken;\n if (!pageToken || batch.length < limit) break;\n }\n\n stats.removed = evictMissing(row.id, keep);\n return stats;\n}\n\nasync function indexOutlookMail(row: DocumentSourceRow): Promise<RemoteIndexStats> {\n const auth = resolveMicrosoftAuth();\n if (\"error\" in auth) throw new Error(auth.error);\n const { query, max_results, page_size } = outlookSourceConfig(row);\n\n const stats: RemoteIndexStats = { scanned: 0, added: 0, updated: 0, unchanged: 0, errors: 0 };\n const keep = new Set<string>();\n let nextLink: string | null = null;\n\n while (stats.scanned < max_results) {\n const limit = Math.min(page_size, max_results - stats.scanned);\n const data = nextLink\n ? await graphFetch(auth, nextLink, { headers: { ConsistencyLevel: \"eventual\" } })\n : await graphFetch(\n auth,\n `/me/messages?$top=${limit}&$count=true&$select=id,subject,bodyPreview,from,toRecipients,ccRecipients,receivedDateTime,lastModifiedDateTime,isRead,isDraft,hasAttachments,categories,parentFolderId,webLink&$search=${encodeURIComponent(`\"${query.replace(/\"/g, '\\\\\"')}\"`)}`,\n { headers: { ConsistencyLevel: \"eventual\" } },\n );\n const payload = data as { value?: GraphMessage[]; \"@odata.nextLink\"?: string; error?: string };\n if (payload.error) throw new Error(payload.error);\n\n const batch = payload.value ?? [];\n if (batch.length === 0) break;\n\n const results = await Promise.all(batch.slice(0, limit).map(async (entry) => {\n const msg = await graphFetch(auth, `/me/messages/${encodeURIComponent(entry.id ?? \"\")}`) as GraphMessage & { error?: string };\n if (msg.error) throw new Error(msg.error);\n const summary = summarizeGraphMessage(msg);\n return upsertRemoteDocument(row.id, {\n path: `outlook://${msg.id ?? entry.id}`,\n title: summary.title,\n externalUpdatedAt: summary.updatedAt,\n text: summary.text,\n });\n }));\n\n for (const [index, item] of results.entries()) {\n const id = batch[index]?.id ?? \"\";\n if (id) keep.add(`outlook://${id}`);\n stats.scanned++;\n stats.added += item.status === \"added\" ? 1 : 0;\n stats.updated += item.status === \"updated\" ? 1 : 0;\n stats.unchanged += item.status === \"unchanged\" ? 1 : 0;\n stats.errors += item.embedError ? 1 : 0;\n stats.embedFailed = (stats.embedFailed ?? 0) + Math.max(item.chunks - item.embedded, 0);\n if (item.embedError && !stats.embedError) stats.embedError = item.embedError;\n }\n\n nextLink = payload[\"@odata.nextLink\"] ?? null;\n if (!nextLink || batch.length < limit) break;\n }\n\n stats.removed = evictMissing(row.id, keep);\n return stats;\n}\n\nexport async function runMailIndexer(source: DocumentSourceRow): Promise<RemoteIndexStats> {\n switch (source.kind) {\n case \"gmail_mail\":\n return indexGmailMail(source);\n case \"outlook_mail\":\n return indexOutlookMail(source);\n default:\n throw new Error(`unsupported mail source kind: ${source.kind}`);\n }\n}\n","// Jira remote indexer (ADR-0026).\n//\n// Source kinds handled:\n// - jira_project → JQL `project = \"<key>\"`\n// - jira_jql → user-supplied JQL\n//\n// Each indexed \"document\" is one issue, with its summary, description and\n// comments flattened into one text body. Comments live on the same chunk\n// graph as the issue body so the same retrieval query can surface either.\n\nimport {\n _atlassianFetch,\n _resolveAtlassianAuth,\n type AtlassianAuth,\n} from \"@/lib/tools/atlassian\";\nimport {\n parseSourceConfig,\n updateDocumentSourceCursor,\n type DocumentSourceRow,\n} from \"@/lib/stores/document-sources\";\nimport { adfToText } from \"./flatten\";\nimport { upsertRemoteDocument, type UpsertResult } from \"./upsert\";\n\nconst PAGE_LIMIT = 50;\nconst MAX_ISSUES_PER_RUN = 500;\n\ninterface JiraComment {\n author?: { displayName?: string };\n created?: string;\n body?: unknown; // ADF\n}\ninterface JiraIssueFields {\n summary?: string;\n description?: unknown; // ADF\n updated?: string;\n comment?: { comments?: JiraComment[]; total?: number };\n}\ninterface JiraIssue {\n key: string;\n fields?: JiraIssueFields;\n}\ninterface JiraSearchResp {\n issues?: JiraIssue[];\n nextPageToken?: string;\n}\n\nfunction buildJql(source: DocumentSourceRow, since: string | null): string {\n const cfg = parseSourceConfig<{ project_key?: string; jql?: string; recency_days?: number }>(source) ?? {};\n const clauses: string[] = [];\n if (source.kind === \"jira_project\") {\n if (!cfg.project_key) throw new Error(\"jira_project requires config.project_key\");\n clauses.push(`project = \"${cfg.project_key}\"`);\n } else if (source.kind === \"jira_jql\") {\n if (!cfg.jql) throw new Error(\"jira_jql requires config.jql\");\n clauses.push(`(${cfg.jql})`);\n }\n if (cfg.recency_days && cfg.recency_days > 0) {\n clauses.push(`updated >= -${cfg.recency_days}d`);\n }\n if (since) clauses.push(`updated > \"${formatJqlDate(since)}\"`);\n // Monotonic order keeps incremental cursors well-defined even on partial runs.\n return `${clauses.join(\" AND \")} ORDER BY updated ASC`;\n}\n\nfunction formatJqlDate(iso: string): string {\n // JQL `updated > \"yyyy/MM/dd HH:mm\"` — minute resolution is enough.\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return iso;\n const pad = (n: number) => String(n).padStart(2, \"0\");\n return `${d.getUTCFullYear()}/${pad(d.getUTCMonth() + 1)}/${pad(d.getUTCDate())} ` +\n `${pad(d.getUTCHours())}:${pad(d.getUTCMinutes())}`;\n}\n\nfunction flattenIssue(issue: JiraIssue, baseUrl: string): { text: string; updatedAt: string } {\n const f = issue.fields ?? {};\n const parts: string[] = [];\n parts.push(`${issue.key} — ${f.summary ?? \"\"}`.trim());\n parts.push(`${baseUrl}/browse/${issue.key}`);\n const desc = adfToText(f.description);\n if (desc) parts.push(desc);\n for (const c of f.comment?.comments ?? []) {\n const body = adfToText(c.body);\n if (!body.trim()) continue;\n const author = c.author?.displayName ?? \"unknown\";\n const ts = c.created ? ` (${c.created.slice(0, 10)})` : \"\";\n parts.push(`Comment by ${author}${ts}:\\n${body}`);\n }\n return {\n text: parts.join(\"\\n\\n\"),\n updatedAt: f.updated ?? new Date().toISOString(),\n };\n}\n\nasync function fetchIssue(auth: AtlassianAuth, key: string): Promise<JiraIssue | null> {\n const data = await _atlassianFetch(\n auth,\n `/rest/api/3/issue/${encodeURIComponent(key)}?fields=summary,description,updated,comment`,\n ) as JiraIssue & { error?: string };\n if (!data || (data as { error?: string }).error) return null;\n return data;\n}\n\nexport interface JiraIndexStats {\n scanned: number;\n added: number;\n updated: number;\n unchanged: number;\n errors: number;\n cursor: string | null;\n embedFailed: number;\n embedError: string | null;\n}\n\nexport async function runJiraIndexer(source: DocumentSourceRow): Promise<JiraIndexStats> {\n const stats: JiraIndexStats = {\n scanned: 0, added: 0, updated: 0, unchanged: 0, errors: 0,\n cursor: source.last_cursor,\n embedFailed: 0, embedError: null,\n };\n const auth = _resolveAtlassianAuth();\n if (\"error\" in auth) throw new Error(auth.error);\n\n const jql = buildJql(source, source.last_cursor);\n let nextPageToken: string | undefined;\n let highWater = source.last_cursor;\n\n while (stats.scanned < MAX_ISSUES_PER_RUN) {\n const data = await _atlassianFetch(auth, \"/rest/api/3/search/jql\", {\n method: \"POST\",\n body: JSON.stringify({\n jql,\n fields: [\"summary\", \"description\", \"updated\", \"comment\"],\n maxResults: PAGE_LIMIT,\n nextPageToken,\n }),\n }) as JiraSearchResp & { error?: string };\n if ((data as { error?: string }).error) throw new Error((data as { error?: string }).error);\n const issues = data.issues ?? [];\n if (issues.length === 0) break;\n\n for (const issue of issues) {\n stats.scanned++;\n try {\n const { text, updatedAt } = flattenIssue(issue, auth.url);\n const res = await upsertRemoteDocument(source.id, {\n path: `jira://${issue.key}`,\n title: `${issue.key}: ${issue.fields?.summary ?? \"\"}`.trim(),\n externalUpdatedAt: updatedAt,\n text,\n });\n if (res.status === \"added\") stats.added++;\n else if (res.status === \"updated\") stats.updated++;\n else stats.unchanged++;\n stats.embedFailed += res.chunks - res.embedded;\n if (res.embedError && !stats.embedError) stats.embedError = res.embedError;\n if (!highWater || updatedAt > highWater) highWater = updatedAt;\n } catch {\n stats.errors++;\n }\n }\n nextPageToken = data.nextPageToken;\n if (!nextPageToken) break;\n }\n\n if (highWater && highWater !== source.last_cursor) {\n updateDocumentSourceCursor(source.id, highWater);\n stats.cursor = highWater;\n }\n return stats;\n}\n\n/** On-demand: fetch & index a single issue by key under the shared\n * on_demand_url source row. */\nexport async function indexJiraIssueByKey(\n sourceId: string,\n key: string,\n): Promise<UpsertResult> {\n const auth = _resolveAtlassianAuth();\n if (\"error\" in auth) throw new Error(auth.error);\n const issue = await fetchIssue(auth, key);\n if (!issue) throw new Error(`jira issue ${key} not found`);\n const { text, updatedAt } = flattenIssue(issue, auth.url);\n return upsertRemoteDocument(sourceId, {\n path: `jira://${issue.key}`,\n title: `${issue.key}: ${issue.fields?.summary ?? \"\"}`.trim(),\n externalUpdatedAt: updatedAt,\n text,\n });\n}\n","// GitHub remote indexer (ADR-0029).\n//\n// Source kinds handled:\n// - github_pulls → all PRs of one repo + their issue comments + review\n// bodies, flattened to one document per PR.\n// - github_repo → text files on one branch of one repo (default branch\n// by default), walked via the Git Trees API. Filtered\n// by the same extension allowlist + binary heuristic\n// as the local-folder walker so the two surfaces stay\n// in sync.\n//\n// On-demand helpers (called via lib/documents/remote/index.ts'\n// indexOnDemand) cover one-shot indexing of a PR / issue / file URL\n// under the shared `on_demand_url` source row.\n\nimport {\n _ghFetch,\n _resolveGithubAuth,\n type GitHubAuth,\n} from \"@/lib/tools/github\";\nimport {\n parseSourceConfig,\n updateDocumentSourceCursor,\n type DocumentSourceRow,\n} from \"@/lib/stores/document-sources\";\nimport { ALLOWED_EXT, isLikelyBinary, lowerExt } from \"../indexer\";\nimport { upsertRemoteDocument, type UpsertResult } from \"./upsert\";\n\nconst PR_PAGE_LIMIT = 50;\nconst MAX_PRS_PER_RUN = 200;\nconst MAX_FILES_PER_RUN = 500;\nconst MAX_FILE_BYTES = 2 * 1024 * 1024; // matches local indexer\n\ninterface GhUserLite { login?: string }\ninterface GhPull {\n number: number;\n title?: string;\n state?: string;\n body?: string;\n updated_at?: string;\n html_url?: string;\n user?: GhUserLite;\n draft?: boolean;\n}\ninterface GhIssueComment {\n user?: GhUserLite;\n created_at?: string;\n body?: string;\n}\ninterface GhReview {\n user?: GhUserLite;\n state?: string;\n submitted_at?: string;\n body?: string;\n}\ninterface GhIssue {\n number: number;\n title?: string;\n body?: string;\n updated_at?: string;\n state?: string;\n html_url?: string;\n user?: GhUserLite;\n}\ninterface GhTreeEntry {\n path: string;\n type: \"blob\" | \"tree\" | \"commit\";\n size?: number;\n sha?: string;\n}\ninterface GhTreeResp {\n sha?: string;\n tree?: GhTreeEntry[];\n truncated?: boolean;\n}\ninterface GhRepo {\n default_branch?: string;\n}\ninterface GhContents {\n type?: \"file\" | \"dir\" | \"symlink\" | \"submodule\";\n encoding?: string;\n content?: string;\n size?: number;\n sha?: string;\n}\n\nfunction ghError(data: unknown): string | null {\n return (data as { error?: string })?.error ?? null;\n}\n\nfunction liteAuthor(u: GhUserLite | undefined): string {\n return u?.login ?? \"unknown\";\n}\n\n// One-document-per-PR text body. Mirrors the Jira flattener: title +\n// URL on the first lines so retrieval results read sensibly even when\n// only the leading chunk surfaces.\nfunction flattenPull(\n pr: GhPull,\n comments: GhIssueComment[],\n reviews: GhReview[],\n): string {\n const parts: string[] = [];\n parts.push(`PR #${pr.number}: ${pr.title ?? \"\"}`.trim());\n if (pr.html_url) parts.push(pr.html_url);\n parts.push(`State: ${pr.state ?? \"unknown\"}${pr.draft ? \" (draft)\" : \"\"} · author: ${liteAuthor(pr.user)}`);\n if (pr.body && pr.body.trim()) parts.push(pr.body.trim());\n for (const c of comments) {\n if (!c.body?.trim()) continue;\n const ts = c.created_at ? ` (${c.created_at.slice(0, 10)})` : \"\";\n parts.push(`Comment by ${liteAuthor(c.user)}${ts}:\\n${c.body.trim()}`);\n }\n for (const r of reviews) {\n if (!r.body?.trim()) continue;\n const ts = r.submitted_at ? ` (${r.submitted_at.slice(0, 10)})` : \"\";\n parts.push(`Review by ${liteAuthor(r.user)} — ${r.state ?? \"\"}${ts}:\\n${r.body.trim()}`);\n }\n return parts.join(\"\\n\\n\");\n}\n\nfunction flattenIssue(issue: GhIssue, comments: GhIssueComment[]): string {\n const parts: string[] = [];\n parts.push(`Issue #${issue.number}: ${issue.title ?? \"\"}`.trim());\n if (issue.html_url) parts.push(issue.html_url);\n parts.push(`State: ${issue.state ?? \"unknown\"} · author: ${liteAuthor(issue.user)}`);\n if (issue.body && issue.body.trim()) parts.push(issue.body.trim());\n for (const c of comments) {\n if (!c.body?.trim()) continue;\n const ts = c.created_at ? ` (${c.created_at.slice(0, 10)})` : \"\";\n parts.push(`Comment by ${liteAuthor(c.user)}${ts}:\\n${c.body.trim()}`);\n }\n return parts.join(\"\\n\\n\");\n}\n\nasync function listIssueComments(auth: GitHubAuth, owner: string, repo: string, n: number): Promise<GhIssueComment[]> {\n const data = await _ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/issues/${n}/comments?per_page=100`,\n );\n return Array.isArray(data) ? (data as GhIssueComment[]) : [];\n}\n\nasync function listReviews(auth: GitHubAuth, owner: string, repo: string, n: number): Promise<GhReview[]> {\n const data = await _ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls/${n}/reviews?per_page=100`,\n );\n return Array.isArray(data) ? (data as GhReview[]) : [];\n}\n\nexport interface GithubIndexStats {\n scanned: number;\n added: number;\n updated: number;\n unchanged: number;\n errors: number;\n cursor: string | null;\n embedFailed: number;\n embedError: string | null;\n}\n\nfunction emptyStats(cursor: string | null): GithubIndexStats {\n return { scanned: 0, added: 0, updated: 0, unchanged: 0, errors: 0, cursor, embedFailed: 0, embedError: null };\n}\n\nfunction applyUpsert(stats: GithubIndexStats, res: UpsertResult): void {\n if (res.status === \"added\") stats.added++;\n else if (res.status === \"updated\") stats.updated++;\n else stats.unchanged++;\n stats.embedFailed += res.chunks - res.embedded;\n if (res.embedError && !stats.embedError) stats.embedError = res.embedError;\n}\n\n// ── github_pulls ──────────────────────────────────────────────────────────\n\ninterface PullsConfig {\n owner?: string;\n repo?: string;\n recency_days?: number;\n state?: \"open\" | \"closed\" | \"all\";\n}\n\nasync function runGithubPullsIndexer(source: DocumentSourceRow): Promise<GithubIndexStats> {\n const cfg = parseSourceConfig<PullsConfig>(source) ?? {};\n if (!cfg.owner || !cfg.repo) throw new Error(\"github_pulls requires config.owner and config.repo\");\n const stats = emptyStats(source.last_cursor);\n const auth = _resolveGithubAuth();\n if (\"error\" in auth) throw new Error(auth.error);\n\n const cutoffMs = cfg.recency_days && cfg.recency_days > 0\n ? Date.now() - cfg.recency_days * 86_400_000\n : null;\n const sinceMs = source.last_cursor ? Date.parse(source.last_cursor) : NaN;\n const state = cfg.state ?? \"all\";\n let highWater = source.last_cursor;\n\n // Sorted by `updated desc` so we can stop early as soon as we drop\n // below the watermark or the recency cutoff.\n let page = 1;\n outer: while (stats.scanned < MAX_PRS_PER_RUN) {\n const data = await _ghFetch(\n auth,\n `/repos/${encodeURIComponent(cfg.owner)}/${encodeURIComponent(cfg.repo)}/pulls` +\n `?state=${state}&sort=updated&direction=desc&per_page=${PR_PAGE_LIMIT}&page=${page}`,\n );\n const err = ghError(data);\n if (err) throw new Error(err);\n const pulls = Array.isArray(data) ? (data as GhPull[]) : [];\n if (pulls.length === 0) break;\n\n for (const pr of pulls) {\n stats.scanned++;\n const updated = pr.updated_at ?? \"\";\n const updatedMs = Date.parse(updated);\n if (cutoffMs !== null && Number.isFinite(updatedMs) && updatedMs < cutoffMs) break outer;\n if (Number.isFinite(sinceMs) && Number.isFinite(updatedMs) && updatedMs <= sinceMs) break outer;\n\n try {\n const [comments, reviews] = await Promise.all([\n listIssueComments(auth, cfg.owner, cfg.repo, pr.number),\n listReviews(auth, cfg.owner, cfg.repo, pr.number),\n ]);\n const text = flattenPull(pr, comments, reviews);\n const res = await upsertRemoteDocument(source.id, {\n path: `github-pull://${cfg.owner}/${cfg.repo}/${pr.number}`,\n title: `PR #${pr.number}: ${pr.title ?? \"\"}`.trim(),\n externalUpdatedAt: updated || new Date().toISOString(),\n text,\n });\n applyUpsert(stats, res);\n if (updated && (!highWater || updated > highWater)) highWater = updated;\n } catch {\n stats.errors++;\n }\n }\n if (pulls.length < PR_PAGE_LIMIT) break;\n page++;\n }\n\n if (highWater && highWater !== source.last_cursor) {\n updateDocumentSourceCursor(source.id, highWater);\n stats.cursor = highWater;\n }\n return stats;\n}\n\n// ── github_repo ───────────────────────────────────────────────────────────\n\ninterface RepoConfig {\n owner?: string;\n repo?: string;\n ref?: string;\n path_prefix?: string;\n}\n\nasync function resolveDefaultBranch(auth: GitHubAuth, owner: string, repo: string): Promise<string> {\n const data = await _ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}`,\n ) as GhRepo & { error?: string };\n if (data.error) throw new Error(data.error);\n if (!data.default_branch) throw new Error(`could not resolve default branch for ${owner}/${repo}`);\n return data.default_branch;\n}\n\nasync function runGithubRepoIndexer(source: DocumentSourceRow): Promise<GithubIndexStats> {\n const cfg = parseSourceConfig<RepoConfig>(source) ?? {};\n if (!cfg.owner || !cfg.repo) throw new Error(\"github_repo requires config.owner and config.repo\");\n const stats = emptyStats(source.last_cursor);\n const auth = _resolveGithubAuth();\n if (\"error\" in auth) throw new Error(auth.error);\n\n const ref = cfg.ref ?? await resolveDefaultBranch(auth, cfg.owner, cfg.repo);\n const tree = await _ghFetch(\n auth,\n `/repos/${encodeURIComponent(cfg.owner)}/${encodeURIComponent(cfg.repo)}/git/trees/${encodeURIComponent(ref)}?recursive=1`,\n ) as GhTreeResp & { error?: string };\n if (tree.error) throw new Error(tree.error);\n const treeSha = tree.sha ?? null;\n\n // Cheap no-op: if the branch head hasn't moved since last walk, skip\n // the whole thing. Saves a contents fetch per file on quiet repos.\n if (treeSha && source.last_cursor === treeSha) {\n stats.cursor = treeSha;\n return stats;\n }\n\n const prefix = (cfg.path_prefix ?? \"\").replace(/^\\/+|\\/+$/g, \"\");\n const blobs = (tree.tree ?? []).filter((e) => {\n if (e.type !== \"blob\") return false;\n if (typeof e.size === \"number\" && e.size > MAX_FILE_BYTES) return false;\n if (!ALLOWED_EXT.has(lowerExt(e.path))) return false;\n if (prefix && !(e.path === prefix || e.path.startsWith(prefix + \"/\"))) return false;\n return true;\n });\n\n for (const entry of blobs) {\n if (stats.scanned >= MAX_FILES_PER_RUN) break;\n stats.scanned++;\n try {\n const contents = await _ghFetch(\n auth,\n `/repos/${encodeURIComponent(cfg.owner)}/${encodeURIComponent(cfg.repo)}/contents/${entry.path\n .split(\"/\").map(encodeURIComponent).join(\"/\")}?ref=${encodeURIComponent(ref)}`,\n ) as GhContents & { error?: string };\n if (contents.error) { stats.errors++; continue; }\n if (contents.type !== \"file\" || !contents.content) continue;\n const buf = Buffer.from(contents.content.replace(/\\s+/g, \"\"), contents.encoding === \"base64\" ? \"base64\" : \"utf8\");\n if (isLikelyBinary(buf)) continue;\n const text = buf.toString(\"utf8\");\n const res = await upsertRemoteDocument(source.id, {\n path: `github-file://${cfg.owner}/${cfg.repo}@${ref}/${entry.path}`,\n title: entry.path,\n externalUpdatedAt: new Date().toISOString(), // tree SHA carries the cursor; per-file mtime would need a commits API call we'd rather skip\n text,\n });\n applyUpsert(stats, res);\n } catch {\n stats.errors++;\n }\n }\n\n if (treeSha && treeSha !== source.last_cursor) {\n updateDocumentSourceCursor(source.id, treeSha);\n stats.cursor = treeSha;\n }\n return stats;\n}\n\n// ── Dispatcher entry-point used by lib/documents/remote/index.ts ──────────\n\nexport async function runGithubIndexer(source: DocumentSourceRow): Promise<GithubIndexStats> {\n if (source.kind === \"github_pulls\") return runGithubPullsIndexer(source);\n if (source.kind === \"github_repo\") return runGithubRepoIndexer(source);\n throw new Error(`runGithubIndexer called with unsupported kind: ${source.kind}`);\n}\n\n// ── On-demand helpers (called from indexOnDemand) ─────────────────────────\n\nexport async function indexGithubPullByUrl(\n sourceId: string,\n owner: string,\n repo: string,\n number: number,\n): Promise<UpsertResult> {\n const auth = _resolveGithubAuth();\n if (\"error\" in auth) throw new Error(auth.error);\n const pr = await _ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls/${number}`,\n ) as GhPull & { error?: string };\n if (pr.error) throw new Error(pr.error);\n const [comments, reviews] = await Promise.all([\n listIssueComments(auth, owner, repo, number),\n listReviews(auth, owner, repo, number),\n ]);\n const text = flattenPull(pr, comments, reviews);\n return upsertRemoteDocument(sourceId, {\n path: `github-pull://${owner}/${repo}/${number}`,\n title: `PR #${number}: ${pr.title ?? \"\"}`.trim(),\n externalUpdatedAt: pr.updated_at ?? new Date().toISOString(),\n text,\n });\n}\n\nexport async function indexGithubIssueByUrl(\n sourceId: string,\n owner: string,\n repo: string,\n number: number,\n): Promise<UpsertResult> {\n const auth = _resolveGithubAuth();\n if (\"error\" in auth) throw new Error(auth.error);\n const issue = await _ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/issues/${number}`,\n ) as GhIssue & { error?: string };\n if (issue.error) throw new Error(issue.error);\n const comments = await listIssueComments(auth, owner, repo, number);\n const text = flattenIssue(issue, comments);\n return upsertRemoteDocument(sourceId, {\n path: `github-issue://${owner}/${repo}/${number}`,\n title: `Issue #${number}: ${issue.title ?? \"\"}`.trim(),\n externalUpdatedAt: issue.updated_at ?? new Date().toISOString(),\n text,\n });\n}\n\nexport async function indexGithubFileByUrl(\n sourceId: string,\n owner: string,\n repo: string,\n ref: string,\n path: string,\n): Promise<UpsertResult> {\n const auth = _resolveGithubAuth();\n if (\"error\" in auth) throw new Error(auth.error);\n const contents = await _ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/contents/${path\n .split(\"/\").map(encodeURIComponent).join(\"/\")}?ref=${encodeURIComponent(ref)}`,\n ) as GhContents & { error?: string };\n if (contents.error) throw new Error(contents.error);\n if (contents.type !== \"file\" || !contents.content) {\n throw new Error(`github contents at ${path} is not a file`);\n }\n const buf = Buffer.from(contents.content.replace(/\\s+/g, \"\"), contents.encoding === \"base64\" ? \"base64\" : \"utf8\");\n if (isLikelyBinary(buf)) throw new Error(`github file ${path} appears to be binary`);\n return upsertRemoteDocument(sourceId, {\n path: `github-file://${owner}/${repo}@${ref}/${path}`,\n title: path,\n externalUpdatedAt: new Date().toISOString(),\n text: buf.toString(\"utf8\"),\n });\n}\n","// Remote document-source dispatcher (ADR-0026).\n//\n// `lib/documents/indexer.ts` walks local folders. For non-local kinds it\n// delegates to one of these per-kind handlers. Keeping the dispatcher tiny\n// (just a switch) keeps the local-folder happy path untouched.\n\nimport {\n createDocumentSource,\n getDocumentSourceByPath,\n markSourceScanned,\n type DocumentSourceRow,\n} from \"@/lib/stores/document-sources\";\nimport { runConfluenceIndexer, indexConfluencePageById } from \"./confluence\";\nimport { runMailIndexer } from \"./mail\";\nimport { runJiraIndexer, indexJiraIssueByKey } from \"./jira\";\nimport {\n runGithubIndexer,\n indexGithubPullByUrl,\n indexGithubIssueByUrl,\n indexGithubFileByUrl,\n} from \"./github\";\nimport type { UpsertResult } from \"./upsert\";\n\nexport interface RemoteIndexStats {\n scanned: number;\n added: number;\n updated: number;\n unchanged: number;\n errors: number;\n removed?: number;\n /** Total chunks across this run that didn't get an embedding vector. */\n embedFailed?: number;\n /** First embed error message seen, if any. */\n embedError?: string | null;\n}\n\n/** Returns true if `kind` is anything other than `local_folder`. */\nexport function isRemoteKind(kind: string): boolean {\n return kind !== \"local_folder\";\n}\n\nexport async function runRemoteSource(source: DocumentSourceRow): Promise<RemoteIndexStats> {\n let lastError: string | null = null;\n let stats: RemoteIndexStats = { scanned: 0, added: 0, updated: 0, unchanged: 0, errors: 0 };\n try {\n switch (source.kind) {\n case \"confluence_space\":\n case \"confluence_cql\": {\n const s = await runConfluenceIndexer(source);\n stats = s;\n break;\n }\n case \"jira_project\":\n case \"jira_jql\": {\n const s = await runJiraIndexer(source);\n stats = s;\n break;\n }\n case \"github_pulls\":\n case \"github_repo\": {\n const s = await runGithubIndexer(source);\n stats = s;\n break;\n }\n case \"gmail_mail\":\n case \"outlook_mail\": {\n const s = await runMailIndexer(source);\n stats = s;\n break;\n }\n case \"on_demand_url\":\n // No background sweep — items are added one-at-a-time via\n // indexOnDemand() from the tool / API surface.\n break;\n default:\n throw new Error(`unsupported remote source kind: ${source.kind}`);\n }\n } catch (err) {\n lastError = err instanceof Error ? err.message : String(err);\n stats.errors++;\n }\n // Mirror the local indexer's surfacing rule: a fetch error wins; otherwise\n // bubble up an embed-failure summary so the operator sees that semantic\n // search is degraded for this source without grepping logs.\n const embedFailed = stats.embedFailed ?? 0;\n const composite = lastError\n ? lastError\n : embedFailed > 0\n ? `${embedFailed} chunk${embedFailed === 1 ? \"\" : \"s\"} failed to embed${stats.embedError ? \": \" + stats.embedError : \"\"}`\n : null;\n markSourceScanned(source.id, composite);\n return stats;\n}\n\n/** Singleton \"on-demand URLs\" source row. Lazily created on first use. */\nconst ON_DEMAND_PATH = \"on-demand://urls\";\nexport function getOrCreateOnDemandSource(): DocumentSourceRow {\n const existing = getDocumentSourceByPath(ON_DEMAND_PATH);\n if (existing) return existing;\n return createDocumentSource({\n path: ON_DEMAND_PATH,\n label: \"On-demand URLs\",\n kind: \"on_demand_url\",\n config: null,\n });\n}\n\n/**\n * Resolve a free-form input (Jira issue key, Jira browse URL, Confluence\n * page URL, GitHub PR/issue/blob URL) to \"fetch this one thing and index\n * it under the on-demand source\". Surfaced via the `documents_index_url`\n * tool + HTTP API. ADR-0029 added the GitHub matchers.\n */\nexport async function indexOnDemand(input: string): Promise<{\n kind: \"jira\" | \"confluence\" | \"github\";\n identifier: string;\n result: UpsertResult;\n source_id: string;\n}> {\n const trimmed = input.trim();\n if (!trimmed) throw new Error(\"input is required\");\n const source = getOrCreateOnDemandSource();\n\n // Bare Jira key.\n const bareKey = /^[A-Z][A-Z0-9_]+-\\d+$/;\n if (bareKey.test(trimmed)) {\n const result = await indexJiraIssueByKey(source.id, trimmed);\n return { kind: \"jira\", identifier: trimmed, result, source_id: source.id };\n }\n // Jira /browse/<KEY>\n const browse = trimmed.match(/\\/browse\\/([A-Z][A-Z0-9_]+-\\d+)/);\n if (browse) {\n const result = await indexJiraIssueByKey(source.id, browse[1]);\n return { kind: \"jira\", identifier: browse[1], result, source_id: source.id };\n }\n // Confluence /wiki/spaces/.../pages/<id>\n const pages = trimmed.match(/\\/wiki\\/spaces\\/[^/]+\\/pages\\/(\\d+)/);\n if (pages) {\n const result = await indexConfluencePageById(source.id, pages[1]);\n return { kind: \"confluence\", identifier: pages[1], result, source_id: source.id };\n }\n // Confluence ?pageId=<id>\n const pageId = trimmed.match(/[?&]pageId=(\\d+)/);\n if (pageId) {\n const result = await indexConfluencePageById(source.id, pageId[1]);\n return { kind: \"confluence\", identifier: pageId[1], result, source_id: source.id };\n }\n // GitHub PR /pull/<n>\n const ghPull = trimmed.match(/^https?:\\/\\/github\\.com\\/([^/]+)\\/([^/]+)\\/pull\\/(\\d+)/);\n if (ghPull) {\n const [, owner, repo, n] = ghPull;\n const result = await indexGithubPullByUrl(source.id, owner, repo, Number(n));\n return { kind: \"github\", identifier: `${owner}/${repo}#${n}`, result, source_id: source.id };\n }\n // GitHub issue /issues/<n>\n const ghIssue = trimmed.match(/^https?:\\/\\/github\\.com\\/([^/]+)\\/([^/]+)\\/issues\\/(\\d+)/);\n if (ghIssue) {\n const [, owner, repo, n] = ghIssue;\n const result = await indexGithubIssueByUrl(source.id, owner, repo, Number(n));\n return { kind: \"github\", identifier: `${owner}/${repo}#${n}`, result, source_id: source.id };\n }\n // GitHub file /blob/<ref>/<path>\n const ghBlob = trimmed.match(/^https?:\\/\\/github\\.com\\/([^/]+)\\/([^/]+)\\/blob\\/([^/]+)\\/(.+)$/);\n if (ghBlob) {\n const [, owner, repo, ref, path] = ghBlob;\n const cleanPath = path.split(\"?\")[0].split(\"#\")[0];\n const result = await indexGithubFileByUrl(source.id, owner, repo, ref, cleanPath);\n return { kind: \"github\", identifier: `${owner}/${repo}@${ref}/${cleanPath}`, result, source_id: source.id };\n }\n\n throw new Error(\n \"could not recognise input — expected a Jira issue key (ABC-123), a /browse/<KEY> URL, \" +\n \"a Confluence /wiki/spaces/.../pages/<id> URL, or a GitHub /pull/<n>, /issues/<n>, or \" +\n \"/blob/<ref>/<path> URL.\",\n );\n}\n","// Cap a string at `maxBytes` UTF-8 bytes. Returns the original (and\n// truncated:false) when already under the cap. Counting bytes — not chars —\n// matters for emoji / CJK / accented characters where char-count would let\n// the payload double the byte budget.\nexport function truncateBytes(s: string, maxBytes: number): { text: string; truncated: boolean } {\n if (Buffer.byteLength(s, \"utf8\") <= maxBytes) return { text: s, truncated: false };\n\n // Slice by char until under the byte cap. Linear scan is fine for the\n // ~30KB caps we use; if a caller ever needs MB-scale truncation, swap for\n // a binary search.\n let end = s.length;\n while (end > 0 && Buffer.byteLength(s.slice(0, end), \"utf8\") > maxBytes) {\n end--;\n }\n return { text: s.slice(0, end), truncated: true };\n}\n","// JSON.parse with a fallback value when the input is malformed (or empty).\n// Used everywhere we read responses from external APIs — they're contractually\n// JSON but a transient 502 / proxy interstitial occasionally returns HTML.\nexport function parseJsonSafe<T>(text: string, fallback: T): T;\nexport function parseJsonSafe<T>(text: string): T | undefined;\nexport function parseJsonSafe<T>(text: string, fallback?: T): T | undefined {\n try {\n return JSON.parse(text) as T;\n } catch {\n return fallback;\n }\n}\n","// Ephemeral state store for in-app OAuth flows (Gmail, Microsoft, ...).\n//\n// Why this exists: the user types client_id + client_secret in the\n// Integrations panel, we POST to /oauth/start, stash them here keyed by a\n// random `state`, and return the provider's authorize URL. The browser\n// bounces back to /oauth/callback with `?code&state`, we exchange, and\n// persist the integration. Meanwhile the panel polls /oauth/status.\n//\n// Pinned to globalThis so HMR in dev doesn't lose pending flows.\n//\n// Same shape used by both gmail-oauth.ts and microsoft-oauth.ts — pass a\n// unique `globalKey` per provider so they don't share a Map.\n\nimport { randomBytes } from \"node:crypto\";\nimport { getOrCreateGlobal } from \"@/lib/utils/global-state\";\n\nexport interface OAuthFlow {\n createdAt: number;\n clientId: string;\n clientSecret: string;\n redirectUri: string;\n status: \"pending\" | \"done\" | \"error\";\n error?: string;\n}\n\nexport interface OAuthFlowStore {\n create(input: { clientId: string; clientSecret: string; redirectUri: string }): {\n state: string;\n flow: OAuthFlow;\n };\n get(state: string): OAuthFlow | undefined;\n update(state: string, patch: Partial<OAuthFlow>): void;\n delete(state: string): void;\n}\n\nconst DEFAULT_TTL_MS = 10 * 60 * 1000;\nconst DEFAULT_MAX_FLOWS = 32;\n\nexport function createOAuthFlowStore(opts: {\n globalKey: string;\n ttlMs?: number;\n maxFlows?: number;\n}): OAuthFlowStore {\n const ttlMs = opts.ttlMs ?? DEFAULT_TTL_MS;\n const maxFlows = opts.maxFlows ?? DEFAULT_MAX_FLOWS;\n const flows = getOrCreateGlobal<Map<string, OAuthFlow>>(opts.globalKey, () => new Map());\n\n function gc(): void {\n const now = Date.now();\n for (const [k, v] of flows) {\n if (now - v.createdAt > ttlMs) flows.delete(k);\n }\n // Hard cap so a stuck UI can't grow this unbounded.\n if (flows.size > maxFlows) {\n const oldest = [...flows.entries()].sort((a, b) => a[1].createdAt - b[1].createdAt);\n for (let i = 0; i < oldest.length - maxFlows; i++) flows.delete(oldest[i][0]);\n }\n }\n\n return {\n create(input) {\n gc();\n const state = randomBytes(16).toString(\"hex\");\n const flow: OAuthFlow = { createdAt: Date.now(), status: \"pending\", ...input };\n flows.set(state, flow);\n return { state, flow };\n },\n get(state) {\n gc();\n return flows.get(state);\n },\n update(state, patch) {\n const f = flows.get(state);\n if (f) Object.assign(f, patch);\n },\n delete(state) {\n flows.delete(state);\n },\n };\n}\n","/**\n * Native Atlassian tools (Jira + Confluence) — direct REST API calls, no MCP.\n *\n * Why this exists: corporate networks often block public PyPI/npm, which makes\n * the `mcp-atlassian` install path fragile. These tools just hit the Atlassian\n * REST API over HTTPS, which goes through the same proxy (EnvHttpProxyAgent)\n * the rest of the server uses — so they work anywhere a browser can reach\n * `*.atlassian.net`.\n *\n * Auth resolution (in priority order):\n * 1. Env: ATLASSIAN_URL, ATLASSIAN_EMAIL, ATLASSIAN_API_TOKEN\n * 2. Memory store: namespace=\"integrations\", key=\"atlassian\", value=\n * { url, email, api_token }\n *\n * The agent can populate option 2 via memory_write if the user shares the\n * credentials in chat — but most users will set env vars at server boot.\n */\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { getIntegrationRaw } from \"@/lib/stores/integrations\";\nimport { parseJsonSafe } from \"@/lib/utils/json\";\nimport { registerTools } from \"./registry\";\n\nexport interface AtlassianAuth {\n url: string; // e.g. \"https://your-team.atlassian.net\"\n email: string;\n apiToken: string;\n}\n\n// Exposed so the integrations test endpoint can probe the live API after save.\nexport function _resolveAtlassianAuth(): AtlassianAuth | { error: string } {\n return resolveAuth();\n}\n\nfunction resolveAuth(): AtlassianAuth | { error: string } {\n // Env first (deployment-level config, wins over per-user secrets stored in DB)\n const envUrl = process.env.ATLASSIAN_URL;\n const envEmail = process.env.ATLASSIAN_EMAIL;\n const envToken = process.env.ATLASSIAN_API_TOKEN;\n if (envUrl && envEmail && envToken) {\n return { url: stripTrailingSlash(envUrl), email: envEmail, apiToken: envToken };\n }\n // Saved integration creds (from the Integrations panel in the UI).\n const saved = getIntegrationRaw(\"atlassian\");\n if (saved?.url && saved.email && saved.api_token) {\n return { url: stripTrailingSlash(saved.url), email: saved.email, apiToken: saved.api_token };\n }\n return {\n error:\n \"Atlassian not configured. Open the gear menu → Integrations tab and add your Atlassian site URL, \" +\n \"email, and API token. (Or set ATLASSIAN_URL / ATLASSIAN_EMAIL / ATLASSIAN_API_TOKEN env vars.)\",\n };\n}\n\nfunction stripTrailingSlash(s: string): string { return s.replace(/\\/+$/, \"\"); }\n\nfunction authHeader(a: AtlassianAuth): string {\n return \"Basic \" + Buffer.from(`${a.email}:${a.apiToken}`).toString(\"base64\");\n}\n\n// Sibling-module accessor: the remote document-RAG indexers (lib/documents/\n// remote/{jira,confluence}.ts, ADR-0026) reuse the same proxy-aware fetch\n// wrapper + auth header so they don't duplicate the Atlassian REST plumbing.\n// Underscore prefix marks it as \"internal API, but reachable across modules\".\nexport async function _atlassianFetch(\n auth: AtlassianAuth,\n path: string,\n init?: RequestInit,\n): Promise<unknown> {\n return atlassianFetch(auth, path, init);\n}\n\nasync function atlassianFetch(\n auth: AtlassianAuth,\n path: string,\n init?: RequestInit,\n): Promise<unknown> {\n const url = path.startsWith(\"http\") ? path : `${auth.url}${path}`;\n const res = await fetch(url, {\n ...init,\n headers: {\n Authorization: authHeader(auth),\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\",\n ...(init?.headers ?? {}),\n },\n });\n const text = await res.text();\n if (!res.ok) {\n return { error: `Atlassian ${res.status}: ${text.slice(0, 500)}`, url };\n }\n return parseJsonSafe<unknown>(text, text);\n}\n\n// ── Jira tools ──────────────────────────────────────────────────────────────\n\nexport const jiraSearchTool = tool(\n async ({ jql, max_results, fields }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const limit = Math.min(max_results ?? 25, 100);\n const fieldList = fields ?? [\"summary\", \"status\", \"assignee\", \"priority\", \"created\", \"updated\"];\n // Atlassian removed /rest/api/3/search in 2025 (returns 410). The replacement\n // is /rest/api/3/search/jql — same JQL semantics, slightly different shape:\n // - POST body: { jql, fields: string[] | \"*all\", maxResults?, nextPageToken? }\n // - Response uses cursor-based `nextPageToken` instead of legacy offset.\n const data = await atlassianFetch(auth, `/rest/api/3/search/jql`, {\n method: \"POST\",\n body: JSON.stringify({ jql, maxResults: limit, fields: fieldList }),\n }) as { issues?: Array<Record<string, unknown>>; nextPageToken?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n issues: (data.issues ?? []).map((i: Record<string, unknown>) => ({\n key: i.key,\n url: `${auth.url}/browse/${i.key}`,\n summary: (i.fields as Record<string, unknown>)?.summary,\n status: ((i.fields as Record<string, unknown>)?.status as Record<string, unknown>)?.name,\n assignee: ((i.fields as Record<string, unknown>)?.assignee as Record<string, unknown>)?.displayName ?? null,\n priority: ((i.fields as Record<string, unknown>)?.priority as Record<string, unknown>)?.name ?? null,\n })),\n next_page_token: data.nextPageToken ?? null,\n });\n },\n {\n name: \"jira_search\",\n description:\n \"Search Jira issues using JQL. **PREFER THIS over shell-exec'ing the jira CLI** — this tool uses \" +\n \"the configured Atlassian credentials directly via REST. Returns key, summary, status, assignee. \" +\n \"JQL examples: 'assignee = currentUser() AND resolution = Unresolved', \" +\n \"'project = ABC AND status = \\\"In Progress\\\"', 'updated >= -7d ORDER BY updated DESC'.\",\n schema: z.object({\n jql: z.string().describe(\"JQL query string\"),\n max_results: z.number().optional().describe(\"Max issues (default 25, max 100)\"),\n fields: z.array(z.string()).optional().describe(\"Field names to fetch; defaults to common ones\"),\n }),\n },\n);\n\nexport const jiraGetIssueTool = tool(\n async ({ issue_key, expand, custom_fields, include_comments }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n\n let resolvedCustom: Array<{ input: string; id: string; name: string }> = [];\n if (custom_fields?.length) {\n const fieldList = await loadJiraFields(auth);\n if (!Array.isArray(fieldList)) return JSON.stringify(fieldList);\n const r = resolveCustomFieldNames(custom_fields, fieldList);\n if (r.unresolved.length) {\n const candidates = fieldList\n .filter((f) => f.custom)\n .slice(0, 25)\n .map((f) => `${f.name} (${f.id})`)\n .join(\"; \");\n return JSON.stringify({\n error: `unresolved custom_fields: ${r.unresolved.join(\", \")}. Pass either the customfield_NNNNN id or the exact display name.`,\n hint_first_25_custom_fields: candidates,\n });\n }\n resolvedCustom = r.resolved;\n }\n\n const expandSet = new Set(expand ?? []);\n if (resolvedCustom.length) {\n expandSet.add(\"names\");\n expandSet.add(\"renderedFields\");\n }\n const params: string[] = [];\n if (expandSet.size) params.push(`expand=${[...expandSet].join(\",\")}`);\n // Always pull issuelinks/subtasks/attachment/parent so callers see what's\n // attached to the issue without a follow-up call. Custom fields are\n // additive — when the caller asked for any, we explicitly enumerate the\n // base set + customs to keep the response shape stable.\n const baseFields = [\n \"summary\", \"description\", \"status\", \"issuetype\", \"priority\",\n \"assignee\", \"reporter\", \"created\", \"updated\", \"labels\", \"components\", \"comment\",\n \"issuelinks\", \"subtasks\", \"attachment\", \"parent\",\n ];\n if (resolvedCustom.length) {\n params.push(`fields=${[...baseFields, ...resolvedCustom.map((c) => c.id)].join(\",\")}`);\n } else {\n params.push(`fields=${baseFields.join(\",\")}`);\n }\n const qs = params.length ? `?${params.join(\"&\")}` : \"\";\n\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/issue/${encodeURIComponent(issue_key)}${qs}`,\n ) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n\n const f = (data.fields ?? {}) as Record<string, unknown>;\n const rendered = (data.renderedFields ?? {}) as Record<string, unknown>;\n\n const customOut: Record<string, unknown> = {};\n for (const c of resolvedCustom) {\n customOut[c.name] = extractFieldValue(f[c.id], rendered[c.id]);\n }\n\n // Issue links: each entry has an `id` (needed by jira_delete_link),\n // a type, and one of inwardIssue / outwardIssue depending on direction.\n const issueLinks = ((f.issuelinks as Array<Record<string, unknown>>) ?? []).map((l) => {\n const t = l.type as Record<string, unknown> | undefined;\n const inward = l.inwardIssue as Record<string, unknown> | undefined;\n const outward = l.outwardIssue as Record<string, unknown> | undefined;\n return {\n id: l.id,\n type: t?.name,\n direction: inward ? \"inward\" : \"outward\",\n verb: inward ? t?.inward : t?.outward,\n other_issue: inward\n ? { key: inward.key, summary: (inward.fields as Record<string, unknown>)?.summary }\n : outward\n ? { key: outward.key, summary: (outward.fields as Record<string, unknown>)?.summary }\n : null,\n };\n });\n\n // Remote/web links live under a separate endpoint — fetch in parallel\n // when requested (and if the issue actually has any) so we don't waste a\n // call on every get. Cheap heuristic: only fetch when the caller passed\n // include_remote_links, or always if expand contains \"remoteLinks\".\n let remoteLinks: Array<Record<string, unknown>> | undefined;\n if (expandSet.has(\"remoteLinks\")) {\n const rl = await atlassianFetch(\n auth,\n `/rest/api/3/issue/${encodeURIComponent(issue_key)}/remotelink`,\n ) as Array<Record<string, unknown>> | { error?: string };\n if (Array.isArray(rl)) {\n remoteLinks = rl.map((entry) => {\n const obj = entry.object as Record<string, unknown> | undefined;\n return { id: entry.id, url: obj?.url, title: obj?.title, summary: obj?.summary };\n });\n }\n }\n\n return JSON.stringify({\n key: data.key,\n url: `${auth.url}/browse/${data.key}`,\n summary: f.summary,\n description: simplifyADF(f.description),\n status: (f.status as Record<string, unknown>)?.name,\n type: (f.issuetype as Record<string, unknown>)?.name,\n priority: (f.priority as Record<string, unknown>)?.name,\n assignee: (f.assignee as Record<string, unknown>)?.displayName ?? null,\n reporter: (f.reporter as Record<string, unknown>)?.displayName ?? null,\n created: f.created,\n updated: f.updated,\n labels: f.labels,\n components: ((f.components as Array<Record<string, unknown>>) ?? []).map((c) => c.name),\n comments_count: ((f.comment as Record<string, unknown>)?.total) ?? 0,\n ...(include_comments ? {\n comments: (((f.comment as Record<string, unknown>)?.comments as Array<Record<string, unknown>>) ?? []).map((c) => ({\n id: c.id,\n author: (c.author as Record<string, unknown>)?.displayName ?? null,\n created: c.created,\n updated: c.updated,\n body: simplifyADF(c.body),\n })),\n } : {}),\n parent: f.parent ? {\n key: (f.parent as Record<string, unknown>).key,\n summary: ((f.parent as Record<string, unknown>).fields as Record<string, unknown>)?.summary,\n } : null,\n subtasks: ((f.subtasks as Array<Record<string, unknown>>) ?? []).map((s) => ({\n key: s.key,\n summary: (s.fields as Record<string, unknown>)?.summary,\n status: ((s.fields as Record<string, unknown>)?.status as Record<string, unknown>)?.name,\n })),\n issue_links: issueLinks,\n attachments: ((f.attachment as Array<Record<string, unknown>>) ?? []).map((a) => ({\n id: a.id,\n filename: a.filename,\n size: a.size,\n mime_type: a.mimeType,\n created: a.created,\n author: (a.author as Record<string, unknown>)?.displayName,\n content_url: a.content,\n })),\n ...(remoteLinks !== undefined ? { remote_links: remoteLinks } : {}),\n ...(resolvedCustom.length ? { custom_fields: customOut } : {}),\n });\n },\n {\n name: \"jira_get_issue\",\n description:\n \"Fetch a single Jira issue by key (e.g. 'PROJ-123'). Returns full detail including description, \" +\n \"parent, sub-tasks, issue_links (with link ids for jira_delete_link), and attachment metadata. \" +\n \"Pass `expand: ['remoteLinks']` to also fetch web/Confluence/GitHub links. \" +\n \"Pass `custom_fields` (display names like 'Vulnerability Description', or `customfield_NNNNN` ids) \" +\n \"to include them in the response under a `custom_fields` map. \" +\n \"Pass `include_comments: true` to include flattened comment bodies (author, timestamps, text). \" +\n \"ADF/rich-text is auto-flattened. \" +\n \"**PREFER THIS over shell-exec'ing the jira CLI.**\",\n schema: z.object({\n issue_key: z.string().describe(\"Issue key like PROJ-123\"),\n expand: z.array(z.string()).optional().describe(\"Fields to expand (e.g. ['changelog', 'transitions'])\"),\n custom_fields: z.array(z.string()).optional().describe(\n \"Custom field display names ('Vulnerability Description') or ids ('customfield_10473') to include\",\n ),\n include_comments: z.boolean().optional().describe(\n \"If true, include a `comments` array with author/created/updated/body for each comment. \" +\n \"Comments come from the same call (no extra API round-trip) but Jira caps the embedded list at ~50 — \" +\n \"use a follow-up call for issues with more.\",\n ),\n }),\n },\n);\n\nexport const jiraCreateIssueTool = tool(\n async ({ project_key, summary, description, issue_type, parent_key, labels, assignee_account_id, custom_fields }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const fields: Record<string, unknown> = {\n project: { key: project_key },\n summary,\n issuetype: { name: issue_type ?? \"Task\" },\n };\n if (description) fields.description = textToADF(description);\n if (parent_key) fields.parent = { key: parent_key };\n if (Array.isArray(labels)) fields.labels = labels;\n if (assignee_account_id) fields.assignee = { accountId: assignee_account_id };\n if (custom_fields && typeof custom_fields === \"object\" && Object.keys(custom_fields).length > 0) {\n const fieldList = await loadJiraFields(auth);\n if (!Array.isArray(fieldList)) return JSON.stringify(fieldList);\n const r = resolveCustomFieldNames(Object.keys(custom_fields), fieldList);\n if (r.unresolved.length) {\n return JSON.stringify({\n error: `unresolved custom_fields: ${r.unresolved.join(\", \")}`,\n hint_first_25_custom_fields: fieldList\n .filter((f) => f.custom).slice(0, 25)\n .map((f) => `${f.name} (${f.id})`).join(\"; \"),\n });\n }\n for (const c of r.resolved) {\n fields[c.id] = (custom_fields as Record<string, unknown>)[c.input];\n }\n }\n const data = await atlassianFetch(auth, `/rest/api/3/issue`, {\n method: \"POST\",\n body: JSON.stringify({ fields }),\n }) as { key?: string; id?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n key: data.key,\n url: data.key ? `${auth.url}/browse/${data.key}` : null,\n });\n },\n {\n name: \"jira_create_issue\",\n description:\n \"Create a new Jira issue. Defaults to issue_type='Task'. Pass parent_key to create a sub-task \" +\n \"or attach a Story to an Epic. Custom fields accept display names or customfield_NNNNN ids. \" +\n \"**PREFER THIS over shell-exec'ing the jira CLI.**\",\n schema: z.object({\n project_key: z.string().describe(\"Project key (e.g. 'ENG')\"),\n summary: z.string().describe(\"Issue title\"),\n description: z.string().optional().describe(\"Plain-text description (auto-converted to ADF)\"),\n issue_type: z.string().optional().describe(\"Issue type name (default: Task; valid: Task, Bug, Story, Epic, Sub-task, …)\"),\n parent_key: z.string().optional().describe(\n \"Parent issue key. Required for Sub-task issue types; also used to attach a Story/Task to an Epic.\",\n ),\n labels: z.array(z.string()).optional().describe(\"Labels to set on the new issue\"),\n assignee_account_id: z.string().optional().describe(\n \"Jira Cloud accountId to assign on creation (use jira_find_user to resolve)\",\n ),\n custom_fields: z.record(z.string(), z.unknown()).optional().describe(\n \"Map of custom field display names or customfield_NNNNN ids → values (e.g. { 'Due Date': '2026-06-15' })\",\n ),\n }),\n },\n);\n\nexport const jiraAddCommentTool = tool(\n async ({ issue_key, body }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await atlassianFetch(auth, `/rest/api/3/issue/${encodeURIComponent(issue_key)}/comment`, {\n method: \"POST\",\n body: JSON.stringify({ body: textToADF(body) }),\n }) as { id?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({ ok: true, comment_id: data.id });\n },\n {\n name: \"jira_add_comment\",\n description:\n \"Add a comment to a Jira issue. Plain text is auto-converted to ADF (Atlassian Document Format). \" +\n \"**PREFER THIS over shell-exec'ing the jira CLI.**\",\n schema: z.object({\n issue_key: z.string(),\n body: z.string().describe(\"Comment text (plain text, line breaks preserved)\"),\n }),\n },\n);\n\nexport const jiraFindUserTool = tool(\n async ({ query }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/user/search?query=${encodeURIComponent(query)}`,\n ) as Array<Record<string, unknown>> | { error?: string };\n if (!Array.isArray(data)) return JSON.stringify(data);\n return JSON.stringify({\n users: data.map((u) => ({\n account_id: u.accountId,\n display_name: u.displayName,\n email: u.emailAddress ?? null,\n active: u.active,\n })),\n });\n },\n {\n name: \"jira_find_user\",\n description:\n \"Look up Jira Cloud users by email or display-name fragment. Returns accountId values \" +\n \"you can pass to jira_update_issue's assignee_account_id. Use when you only have an email.\",\n schema: z.object({\n query: z.string().describe(\"Email address or partial display name\"),\n }),\n },\n);\n\nexport const jiraUpdateIssueTool = tool(\n async ({\n issue_key, summary, description, priority, assignee_account_id, assignee_email,\n fix_versions, labels, labels_add, labels_remove, custom_fields, parent_key,\n }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n\n const fields: Record<string, unknown> = {};\n const update: Record<string, Array<Record<string, unknown>>> = {};\n\n if (typeof summary === \"string\") fields.summary = summary;\n if (typeof description === \"string\") fields.description = textToADF(description);\n if (typeof priority === \"string\") fields.priority = { name: priority };\n if (typeof parent_key === \"string\") {\n // Empty string clears the parent (detach from epic / promote sub-task to standalone).\n fields.parent = parent_key.length > 0 ? { key: parent_key } : null;\n }\n if (Array.isArray(fix_versions)) fields.fixVersions = fix_versions.map((name) => ({ name }));\n if (Array.isArray(labels)) fields.labels = labels;\n\n // Custom fields: caller passes display names (\"Due Date\") or ids\n // (customfield_10015) → values. We resolve names → ids via the same\n // /rest/api/3/field cache jira_get_issue uses. Values are passed through\n // verbatim — Jira accepts strings, numbers, arrays, or full ADF docs\n // depending on the field's underlying type, and forcing one shape here\n // would break the others. The model already knows the field type from a\n // prior get_issue call (or an error message will steer it).\n if (custom_fields && typeof custom_fields === \"object\" && Object.keys(custom_fields).length > 0) {\n const inputs = Object.keys(custom_fields);\n const fieldList = await loadJiraFields(auth);\n if (!Array.isArray(fieldList)) return JSON.stringify(fieldList);\n const r = resolveCustomFieldNames(inputs, fieldList);\n if (r.unresolved.length) {\n return JSON.stringify({\n error: `unresolved custom_fields: ${r.unresolved.join(\", \")}. Pass either the customfield_NNNNN id or the exact display name.`,\n hint_first_25_custom_fields: fieldList\n .filter((f) => f.custom)\n .slice(0, 25)\n .map((f) => `${f.name} (${f.id})`)\n .join(\"; \"),\n });\n }\n for (const c of r.resolved) {\n fields[c.id] = (custom_fields as Record<string, unknown>)[c.input];\n }\n }\n\n if (Array.isArray(labels_add) || Array.isArray(labels_remove)) {\n const ops: Array<Record<string, string>> = [];\n for (const l of labels_add ?? []) ops.push({ add: l });\n for (const l of labels_remove ?? []) ops.push({ remove: l });\n if (ops.length) update.labels = ops;\n }\n\n // Assignee: explicit accountId wins; otherwise resolve email; \"unassigned\" / null clears.\n if (assignee_account_id !== undefined) {\n const v = assignee_account_id;\n if (v === null || v === \"\" || v === \"unassigned\") {\n fields.assignee = { accountId: null };\n } else {\n fields.assignee = { accountId: v };\n }\n } else if (typeof assignee_email === \"string\" && assignee_email.length > 0) {\n if (assignee_email === \"unassigned\") {\n fields.assignee = { accountId: null };\n } else {\n const users = await atlassianFetch(\n auth,\n `/rest/api/3/user/search?query=${encodeURIComponent(assignee_email)}`,\n ) as Array<{ accountId?: string; emailAddress?: string }> | { error?: string };\n if (!Array.isArray(users)) return JSON.stringify(users);\n // Prefer exact email match (case-insensitive); fall back to single result.\n const exact = users.find(\n (u) => (u.emailAddress ?? \"\").toLowerCase() === assignee_email.toLowerCase(),\n );\n const picked = exact ?? (users.length === 1 ? users[0] : undefined);\n if (!picked?.accountId) {\n return JSON.stringify({\n error: `could not resolve assignee_email \"${assignee_email}\" — got ${users.length} matches; ` +\n `pass assignee_account_id explicitly`,\n candidates: users.map((u) => ({ email: u.emailAddress, account_id: u.accountId })),\n });\n }\n fields.assignee = { accountId: picked.accountId };\n }\n }\n\n if (Object.keys(fields).length === 0 && Object.keys(update).length === 0) {\n return JSON.stringify({ error: \"no fields to update — pass at least one of summary, description, priority, assignee_*, fix_versions, labels, labels_add, labels_remove, parent_key, custom_fields\" });\n }\n\n const body: Record<string, unknown> = {};\n if (Object.keys(fields).length) body.fields = fields;\n if (Object.keys(update).length) body.update = update;\n\n const data = await atlassianFetch(auth, `/rest/api/3/issue/${encodeURIComponent(issue_key)}`, {\n method: \"PUT\",\n body: JSON.stringify(body),\n }) as { error?: string } | string;\n // Successful PUT returns 204 No Content → atlassianFetch returns \"\" (parsed as string).\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n key: issue_key,\n url: `${auth.url}/browse/${issue_key}`,\n updated_fields: [...Object.keys(fields), ...Object.keys(update).map((k) => `${k}(±)`)],\n });\n },\n {\n name: \"jira_update_issue\",\n description:\n \"Edit fields on an existing Jira issue: summary, description, priority, assignee, fix versions, \" +\n \"labels, and arbitrary custom fields (including 'Due Date' and 'Story Points' on sites where \" +\n \"those are custom). Pass only the fields you want to change. Description is auto-converted from \" +\n \"plain text to ADF. Labels support either full replace (`labels`) or incremental \" +\n \"`labels_add`/`labels_remove`. Assignee can be set by `assignee_account_id` or by \" +\n \"`assignee_email` (auto-resolved); pass null/\\\"unassigned\\\" to clear. Custom fields accept \" +\n \"display names ('Due Date') or ids ('customfield_10015'); values are passed through verbatim \" +\n \"(string for date/text, number for numeric, full ADF object for rich-text custom fields). \" +\n \"**PREFER THIS over shell-exec'ing the jira CLI.** Disable to make the agent read-only.\",\n schema: z.object({\n issue_key: z.string().describe(\"Issue key like PROJ-123\"),\n summary: z.string().optional().describe(\"New issue title\"),\n description: z.string().optional().describe(\n \"Plain-text description (auto-converted to ADF). Replaces existing description.\",\n ),\n priority: z.string().optional().describe(\"Priority name (e.g. 'High', 'Medium', 'Low')\"),\n assignee_account_id: z.string().nullable().optional().describe(\n \"Jira Cloud accountId; null or 'unassigned' clears assignee\",\n ),\n assignee_email: z.string().optional().describe(\n \"Email to resolve via /user/search; alternative to assignee_account_id\",\n ),\n fix_versions: z.array(z.string()).optional().describe(\n \"Replace fix versions with these names (empty array clears all)\",\n ),\n labels: z.array(z.string()).optional().describe(\n \"Replace labels entirely with this set (empty array clears all)\",\n ),\n labels_add: z.array(z.string()).optional().describe(\"Labels to add (incremental)\"),\n labels_remove: z.array(z.string()).optional().describe(\"Labels to remove (incremental)\"),\n parent_key: z.string().optional().describe(\n \"Reparent: pass a parent issue key to attach this issue to (Epic key for Stories, Story/Task key for Sub-tasks). Pass an empty string to detach from the current parent.\",\n ),\n custom_fields: z.record(z.string(), z.unknown()).optional().describe(\n \"Map of custom field display names or customfield_NNNNN ids → values. \" +\n \"Examples: { \\\"Due Date\\\": \\\"2026-06-15\\\", \\\"Story Points\\\": 8 }. \" +\n \"For rich-text custom fields, pass a full ADF document as the value.\",\n ),\n }),\n },\n);\n\nexport const jiraTransitionsTool = tool(\n async ({ issue_key, transition_name }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n // Step 1: list available transitions for this issue.\n const list = await atlassianFetch(auth, `/rest/api/3/issue/${encodeURIComponent(issue_key)}/transitions`) as { transitions?: Array<{ id: string; name: string }>; error?: string };\n if (list.error) return JSON.stringify(list);\n if (!transition_name) {\n return JSON.stringify({ available_transitions: (list.transitions ?? []).map((t) => t.name) });\n }\n const match = (list.transitions ?? []).find((t) => t.name.toLowerCase() === transition_name.toLowerCase());\n if (!match) {\n return JSON.stringify({\n error: `transition \"${transition_name}\" not available for ${issue_key}`,\n available: (list.transitions ?? []).map((t) => t.name),\n });\n }\n const data = await atlassianFetch(auth, `/rest/api/3/issue/${encodeURIComponent(issue_key)}/transitions`, {\n method: \"POST\",\n body: JSON.stringify({ transition: { id: match.id } }),\n }) as { error?: string };\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, transitioned_to: match.name });\n },\n {\n name: \"jira_transition_issue\",\n description:\n \"Transition a Jira issue's status (e.g. 'In Progress' → 'Done'). \" +\n \"Call without transition_name to list available transitions for the issue. \" +\n \"**PREFER THIS over shell-exec'ing the jira CLI.**\",\n schema: z.object({\n issue_key: z.string(),\n transition_name: z.string().optional().describe(\"Name of the transition (case-insensitive). Omit to list.\"),\n }),\n },\n);\n\nexport const jiraLinkIssuesTool = tool(\n async ({ from_issue, to_issue, link_type, comment }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n\n // Step 1: load global link types and resolve the requested name. Same\n // \"omit to list\" pattern as jira_transition_issue — agents can probe this\n // tool to discover what's available without a separate list endpoint.\n const list = await atlassianFetch(auth, `/rest/api/3/issueLinkType`) as\n | { issueLinkTypes?: Array<{ id: string; name: string; inward: string; outward: string }>; error?: string };\n if (\"error\" in list && list.error) return JSON.stringify(list);\n const types = list.issueLinkTypes ?? [];\n if (!link_type || !from_issue || !to_issue) {\n return JSON.stringify({\n available_link_types: types.map((t) => ({ name: t.name, outward: t.outward, inward: t.inward })),\n usage: \"Pass from_issue, to_issue, and link_type (e.g. 'Blocks'). The link reads as: '<from_issue> <outward verb> <to_issue>'.\",\n });\n }\n const wanted = link_type.toLowerCase();\n const match = types.find((t) => t.name.toLowerCase() === wanted);\n if (!match) {\n return JSON.stringify({\n error: `link_type \"${link_type}\" not configured for this site`,\n available: types.map((t) => t.name),\n });\n }\n\n // Jira's outwardIssue is the SOURCE (subject of the outward verb), inwardIssue\n // is the TARGET. So `{from: A, to: B, type: \"Blocks\"}` reads as \"A blocks B\".\n const body: Record<string, unknown> = {\n type: { name: match.name },\n outwardIssue: { key: from_issue },\n inwardIssue: { key: to_issue },\n };\n if (typeof comment === \"string\" && comment.length > 0) {\n body.comment = { body: textToADF(comment) };\n }\n\n const data = await atlassianFetch(auth, `/rest/api/3/issueLink`, {\n method: \"POST\",\n body: JSON.stringify(body),\n }) as { error?: string } | string;\n // Successful POST returns 201 Created with empty body → \"\" (string).\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n reads_as: `${from_issue} ${match.outward} ${to_issue}`,\n from: { key: from_issue, url: `${auth.url}/browse/${from_issue}` },\n to: { key: to_issue, url: `${auth.url}/browse/${to_issue}` },\n link_type: match.name,\n });\n },\n {\n name: \"jira_link_issues\",\n description:\n \"Create an issue link between two Jira issues (Blocks, Relates, Duplicates, Cloners, etc.). \" +\n \"The link reads left-to-right: 'from_issue <outward verb> to_issue'. For example, \" +\n \"{ from_issue: 'A-1', to_issue: 'B-2', link_type: 'Blocks' } means 'A-1 blocks B-2' \" +\n \"(and 'B-2 is blocked by A-1' shows on the other side automatically). \" +\n \"Call without arguments to list available link types for the site. \" +\n \"**PREFER THIS over shell-exec'ing the jira CLI or hitting REST directly.** Disable to make the agent read-only.\",\n schema: z.object({\n from_issue: z.string().optional().describe(\"Source issue key (subject of the outward verb), e.g. 'PROJ-1'\"),\n to_issue: z.string().optional().describe(\"Target issue key (object of the outward verb), e.g. 'PROJ-2'\"),\n link_type: z.string().optional().describe(\n \"Link type name, case-insensitive (e.g. 'Blocks', 'Relates', 'Duplicates'). Omit to list available types.\",\n ),\n comment: z.string().optional().describe(\n \"Optional plain-text comment posted to the from_issue alongside the link\",\n ),\n }),\n },\n);\n\n// Shape for one issue inside a bulk-create payload. Mirrors the create tool's\n// schema so callers building one off a loop don't have to re-learn fields.\nconst bulkIssueSchema = z.object({\n project_key: z.string(),\n summary: z.string(),\n description: z.string().optional(),\n issue_type: z.string().optional(),\n parent_key: z.string().optional(),\n labels: z.array(z.string()).optional(),\n assignee_account_id: z.string().optional(),\n custom_fields: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport const jiraCreateIssuesBulkTool = tool(\n async ({ issues }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (!issues?.length) return JSON.stringify({ error: \"issues array is empty\" });\n if (issues.length > 50) return JSON.stringify({ error: `bulk endpoint accepts up to 50 per call (got ${issues.length})` });\n\n // Custom fields: do ONE field-cache load if any issue uses them, then\n // resolve names → ids per-issue. Bulk creates that share custom fields\n // (the common case) thus only pay the cache cost once.\n let fieldList: JiraFieldDef[] | undefined;\n const anyCustom = issues.some((i) => i.custom_fields && Object.keys(i.custom_fields).length > 0);\n if (anyCustom) {\n const loaded = await loadJiraFields(auth);\n if (!Array.isArray(loaded)) return JSON.stringify(loaded);\n fieldList = loaded;\n }\n\n const issueUpdates: Array<{ fields: Record<string, unknown> }> = [];\n for (const i of issues) {\n const fields: Record<string, unknown> = {\n project: { key: i.project_key },\n summary: i.summary,\n issuetype: { name: i.issue_type ?? \"Task\" },\n };\n if (i.description) fields.description = textToADF(i.description);\n if (i.parent_key) fields.parent = { key: i.parent_key };\n if (Array.isArray(i.labels)) fields.labels = i.labels;\n if (i.assignee_account_id) fields.assignee = { accountId: i.assignee_account_id };\n if (i.custom_fields && fieldList) {\n const r = resolveCustomFieldNames(Object.keys(i.custom_fields), fieldList);\n if (r.unresolved.length) {\n return JSON.stringify({ error: `unresolved custom_fields on \"${i.summary}\": ${r.unresolved.join(\", \")}` });\n }\n for (const c of r.resolved) {\n fields[c.id] = (i.custom_fields as Record<string, unknown>)[c.input];\n }\n }\n issueUpdates.push({ fields });\n }\n\n const data = await atlassianFetch(auth, `/rest/api/3/issue/bulk`, {\n method: \"POST\",\n body: JSON.stringify({ issueUpdates }),\n }) as {\n issues?: Array<{ key?: string; id?: string }>;\n errors?: Array<{ status: number; elementErrors: { errors?: Record<string, string> } }>;\n error?: string;\n };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n created: (data.issues ?? []).map((i) => ({\n key: i.key,\n url: i.key ? `${auth.url}/browse/${i.key}` : null,\n })),\n errors: data.errors ?? [],\n });\n },\n {\n name: \"jira_create_issues_bulk\",\n description:\n \"Create up to 50 Jira issues in a single API call. Each entry takes the same shape as \" +\n \"jira_create_issue (project_key, summary, description, issue_type, parent_key, labels, \" +\n \"assignee_account_id, custom_fields). Returns per-issue keys plus any partial errors. \" +\n \"**PREFER THIS over many sequential jira_create_issue calls** when creating ≥3 tickets.\",\n schema: z.object({\n issues: z.array(bulkIssueSchema).describe(\"Array of issues to create (1–50)\"),\n }),\n },\n);\n\nexport const jiraAddRemoteLinkTool = tool(\n async ({ issue_key, url, title, summary, icon_url, global_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const body: Record<string, unknown> = {\n object: {\n url,\n title,\n ...(summary ? { summary } : {}),\n ...(icon_url ? { icon: { url16x16: icon_url } } : {}),\n },\n };\n // globalId is what makes a remote link idempotent — repeat-posting with\n // the same globalId updates the existing link instead of creating a dup.\n if (global_id) body.globalId = global_id;\n\n const data = await atlassianFetch(auth, `/rest/api/3/issue/${encodeURIComponent(issue_key)}/remotelink`, {\n method: \"POST\",\n body: JSON.stringify(body),\n }) as { id?: number; self?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n remote_link_id: data.id,\n issue: { key: issue_key, url: `${auth.url}/browse/${issue_key}` },\n target: { url, title },\n });\n },\n {\n name: \"jira_add_remote_link\",\n description:\n \"Attach a web/external link to a Jira issue (Confluence pages, GitHub PRs, dashboards, Slack threads, \" +\n \"any URL). Distinct from jira_link_issues, which links one Jira issue to another. \" +\n \"Pass `global_id` to make the link idempotent — re-posting with the same global_id updates the \" +\n \"existing link rather than creating a duplicate. **PREFER THIS over pasting URLs into the description.**\",\n schema: z.object({\n issue_key: z.string().describe(\"Issue to attach the link to\"),\n url: z.string().describe(\"Target URL\"),\n title: z.string().describe(\"Link title shown in Jira's 'web links' panel\"),\n summary: z.string().optional().describe(\"Optional one-line description shown under the title\"),\n icon_url: z.string().optional().describe(\"Optional 16×16 icon URL\"),\n global_id: z.string().optional().describe(\n \"Optional stable identifier for idempotent upserts (e.g. 'github-pr-1234'). Re-posting with the same value updates the existing link.\",\n ),\n }),\n },\n);\n\nexport const jiraDeleteLinkTool = tool(\n async ({ link_id, link_type, kind }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (!link_id) return JSON.stringify({ error: \"link_id is required (look up via jira_get_issue → issue_links[].id or remote_links[].id)\" });\n\n // \"issue\" = link between two Jira issues (DELETE /issueLink/{id})\n // \"remote\" = link to an external URL (DELETE /issue/{key}/remotelink/{id})\n // Caller must specify because the same numeric id can exist in both spaces.\n if (kind === \"remote\") {\n if (!link_type) {\n return JSON.stringify({ error: \"for kind='remote', pass link_type as the issue key (the link is scoped to an issue)\" });\n }\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/issue/${encodeURIComponent(link_type)}/remotelink/${encodeURIComponent(link_id)}`,\n { method: \"DELETE\" },\n ) as { error?: string } | string;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, deleted: { kind: \"remote\", link_id, issue_key: link_type } });\n }\n\n const data = await atlassianFetch(auth, `/rest/api/3/issueLink/${encodeURIComponent(link_id)}`, {\n method: \"DELETE\",\n }) as { error?: string } | string;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, deleted: { kind: \"issue\", link_id } });\n },\n {\n name: \"jira_delete_link\",\n description:\n \"Delete an issue link (Jira-to-Jira, default) or a remote/web link. Look up the id first with \" +\n \"jira_get_issue (issue_links[].id or remote_links[].id — pass `expand: ['remoteLinks']` for the latter). \" +\n \"For remote links, also pass the issue key as `link_type` since the API is scoped per-issue.\",\n schema: z.object({\n link_id: z.string().describe(\"Numeric link id from jira_get_issue\"),\n kind: z.enum([\"issue\", \"remote\"]).optional().describe(\n \"'issue' (default) for Jira-to-Jira links, 'remote' for web/external URL links\",\n ),\n link_type: z.string().optional().describe(\n \"When kind='remote', the issue key the remote link is attached to (required by Jira's per-issue endpoint)\",\n ),\n }),\n },\n);\n\nexport const jiraUploadAttachmentTool = tool(\n async ({ issue_key, filename, content_base64, content_text }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (!content_base64 && !content_text) {\n return JSON.stringify({ error: \"pass either content_base64 (binary) or content_text (UTF-8)\" });\n }\n\n const buf = content_base64\n ? Buffer.from(content_base64, \"base64\")\n : Buffer.from(content_text!, \"utf8\");\n\n // Jira attachment uploads require X-Atlassian-Token: no-check (CSRF\n // bypass) and multipart/form-data. node's built-in FormData + Blob (Node\n // 22+) handle the body shape; fetch sets the multipart boundary.\n const form = new FormData();\n form.append(\"file\", new Blob([buf]), filename);\n\n const url = `${auth.url}/rest/api/3/issue/${encodeURIComponent(issue_key)}/attachments`;\n const res = await fetch(url, {\n method: \"POST\",\n headers: {\n Authorization: authHeader(auth),\n Accept: \"application/json\",\n \"X-Atlassian-Token\": \"no-check\",\n // Do NOT set Content-Type — fetch fills in the multipart boundary.\n },\n body: form,\n });\n const text = await res.text();\n if (!res.ok) return JSON.stringify({ error: `Atlassian ${res.status}: ${text.slice(0, 500)}` });\n const parsed = parseJsonSafe<Array<{ id: string; filename: string; size: number; mimeType: string; content: string }>>(text, []);\n return JSON.stringify({\n ok: true,\n issue: { key: issue_key, url: `${auth.url}/browse/${issue_key}` },\n attachments: parsed.map((a) => ({\n id: a.id,\n filename: a.filename,\n size: a.size,\n mime_type: a.mimeType,\n content_url: a.content,\n })),\n });\n },\n {\n name: \"jira_upload_attachment\",\n description:\n \"Upload a file as an attachment to a Jira issue. Pass content_base64 for binary files (PNG, PDF, \" +\n \"ZIP, etc.) or content_text for plain UTF-8 text (logs, CSVs, JSON). The agent itself reads/encodes \" +\n \"the source file — this tool only handles the upload. **PREFER THIS over pasting file contents into \" +\n \"a comment.** Disable to make the agent unable to add attachments.\",\n schema: z.object({\n issue_key: z.string().describe(\"Issue to attach to\"),\n filename: z.string().describe(\"Filename shown in Jira (include the extension)\"),\n content_base64: z.string().optional().describe(\"Base64-encoded file contents (use for binary)\"),\n content_text: z.string().optional().describe(\"Raw UTF-8 text contents (use for logs/CSVs/JSON)\"),\n }),\n },\n);\n\nexport const jiraDeleteIssueTool = tool(\n async ({ issue_key, delete_subtasks }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const qs = delete_subtasks ? `?deleteSubtasks=true` : \"\";\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/issue/${encodeURIComponent(issue_key)}${qs}`,\n { method: \"DELETE\" },\n ) as { error?: string } | string;\n // Successful DELETE returns 204 No Content → atlassianFetch returns \"\" (parsed as string).\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, deleted: issue_key });\n },\n {\n name: \"jira_delete_issue\",\n description:\n \"Permanently delete a Jira issue. **DESTRUCTIVE — there is no undo from the API.** By default, \" +\n \"Jira refuses to delete an issue that has sub-tasks; pass delete_subtasks=true to delete them too. \" +\n \"Disable this tool entirely to make the agent unable to delete tickets.\",\n schema: z.object({\n issue_key: z.string().describe(\"Issue to delete\"),\n delete_subtasks: z.boolean().optional().describe(\n \"If true, also delete all sub-tasks. Required when the issue has sub-tasks; otherwise Jira returns 400.\",\n ),\n }),\n },\n);\n\n// ── Jira agile tools ────────────────────────────────────────────────────────\n//\n// Sprint/board/backlog/rank lives at `/rest/agile/1.0/...`, NOT `/rest/api/3/`.\n// Same hostname + same Basic auth as the platform API, so atlassianFetch works\n// unchanged — only the path family differs. See ADR-0035.\n//\n// Sprint state machine: future → active → closed (one-way). Atlassian rejects\n// other transitions server-side, but we validate client-side too so the agent\n// gets a clean error with the list of legal next states instead of a 400.\n\nconst SPRINT_STATES = [\"future\", \"active\", \"closed\"] as const;\ntype SprintState = (typeof SPRINT_STATES)[number];\n\n// Pure — exported for tests. Returns the state argument shape Atlassian's\n// `POST /sprint/{id}` accepts, or an error if the transition is illegal.\nexport function validateSprintTransition(\n current: string | undefined,\n target: SprintState,\n): { ok: true } | { error: string } {\n if (target === \"future\") {\n return { error: \"cannot transition a sprint back to 'future' once created\" };\n }\n if (current === \"closed\") {\n return { error: \"sprint is already closed; no further transitions allowed\" };\n }\n if (target === \"active\" && current && current !== \"future\") {\n return { error: `cannot start a sprint in state '${current}' — only 'future' sprints can be started` };\n }\n if (target === \"closed\" && current && current !== \"active\") {\n return { error: `cannot complete a sprint in state '${current}' — only 'active' sprints can be completed` };\n }\n return { ok: true };\n}\n\nexport const jiraListBoardsTool = tool(\n async ({ project, name, type, max_results }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const params = new URLSearchParams();\n if (project) params.set(\"projectKeyOrId\", project);\n if (name) params.set(\"name\", name);\n if (type) params.set(\"type\", type);\n params.set(\"maxResults\", String(Math.min(max_results ?? 50, 100)));\n const data = await atlassianFetch(auth, `/rest/agile/1.0/board?${params}`) as\n | { values?: Array<Record<string, unknown>>; isLast?: boolean; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n boards: (data.values ?? []).map((b) => ({\n id: b.id,\n name: b.name,\n type: b.type,\n project_key: ((b.location as Record<string, unknown>)?.projectKey) ?? null,\n })),\n is_last: data.isLast ?? null,\n });\n },\n {\n name: \"jira_list_boards\",\n description:\n \"List Jira agile boards (Scrum or Kanban). Filter by project key, name fragment, or board type. \" +\n \"Returns id, name, type, project_key. Use the id with jira_list_sprints / jira_get_backlog / etc.\",\n schema: z.object({\n project: z.string().optional().describe(\"Project key or id to filter by\"),\n name: z.string().optional().describe(\"Board name fragment (case-insensitive contains-match)\"),\n type: z.enum([\"scrum\", \"kanban\", \"simple\"]).optional(),\n max_results: z.number().optional().describe(\"Default 50, max 100\"),\n }),\n },\n);\n\nexport const jiraGetBoardTool = tool(\n async ({ board_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n // Two calls in parallel — board metadata + configuration. The configuration\n // endpoint is what reveals estimation field, sub-query, ranking field, etc.,\n // which the agent often needs alongside the basic board info.\n const [meta, config] = await Promise.all([\n atlassianFetch(auth, `/rest/agile/1.0/board/${encodeURIComponent(board_id)}`),\n atlassianFetch(auth, `/rest/agile/1.0/board/${encodeURIComponent(board_id)}/configuration`),\n ]) as [Record<string, unknown> & { error?: string }, Record<string, unknown> & { error?: string }];\n if (meta.error) return JSON.stringify(meta);\n return JSON.stringify({\n id: meta.id,\n name: meta.name,\n type: meta.type,\n project_key: ((meta.location as Record<string, unknown>)?.projectKey) ?? null,\n configuration: config.error ? null : {\n filter_id: ((config.filter as Record<string, unknown>)?.id) ?? null,\n sub_query: ((config.subQuery as Record<string, unknown>)?.query) ?? null,\n estimation_field: ((config.estimation as Record<string, unknown>)?.field as Record<string, unknown>)?.fieldId ?? null,\n ranking_field: ((config.ranking as Record<string, unknown>)?.rankCustomFieldId) ?? null,\n },\n });\n },\n {\n name: \"jira_get_board\",\n description:\n \"Fetch board metadata and configuration in one call: id, name, type, project_key, plus filter id, \" +\n \"sub-query JQL, estimation field, and ranking custom field. Use this when you need to know how \" +\n \"issues are estimated or ranked on a specific board.\",\n schema: z.object({\n board_id: z.union([z.string(), z.number()]).describe(\"Board id from jira_list_boards\"),\n }),\n },\n);\n\nexport const jiraListSprintsTool = tool(\n async ({ board_id, state, max_results }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const params = new URLSearchParams();\n if (state) params.set(\"state\", state);\n params.set(\"maxResults\", String(Math.min(max_results ?? 50, 100)));\n const data = await atlassianFetch(\n auth,\n `/rest/agile/1.0/board/${encodeURIComponent(board_id)}/sprint?${params}`,\n ) as { values?: Array<Record<string, unknown>>; isLast?: boolean; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n sprints: (data.values ?? []).map((s) => ({\n id: s.id,\n name: s.name,\n state: s.state,\n goal: s.goal ?? null,\n start_date: s.startDate ?? null,\n end_date: s.endDate ?? null,\n complete_date: s.completeDate ?? null,\n origin_board_id: s.originBoardId ?? null,\n })),\n is_last: data.isLast ?? null,\n });\n },\n {\n name: \"jira_list_sprints\",\n description:\n \"List sprints on a board. Filter by state ('active', 'closed', 'future'). Returns sprint id, name, \" +\n \"state, goal, dates, origin_board_id. To list issues IN a sprint, use jira_search with \" +\n \"JQL `sprint = {id}` — that's faster and supports custom field selection.\",\n schema: z.object({\n board_id: z.union([z.string(), z.number()]),\n state: z.enum([\"active\", \"closed\", \"future\"]).optional().describe(\"Comma in API but tool takes one state\"),\n max_results: z.number().optional().describe(\"Default 50, max 100\"),\n }),\n },\n);\n\nexport const jiraGetSprintTool = tool(\n async ({ sprint_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await atlassianFetch(auth, `/rest/agile/1.0/sprint/${encodeURIComponent(sprint_id)}`) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n id: data.id,\n name: data.name,\n state: data.state,\n goal: data.goal ?? null,\n start_date: data.startDate ?? null,\n end_date: data.endDate ?? null,\n complete_date: data.completeDate ?? null,\n origin_board_id: data.originBoardId ?? null,\n });\n },\n {\n name: \"jira_get_sprint\",\n description:\n \"Fetch a single sprint by id. Returns name, state, goal, start/end/complete dates. Use jira_search \" +\n \"with `sprint = {id}` to list its issues.\",\n schema: z.object({ sprint_id: z.union([z.string(), z.number()]) }),\n },\n);\n\nexport const jiraCreateSprintTool = tool(\n async ({ board_id, name, goal, start_date, end_date }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const body: Record<string, unknown> = { originBoardId: Number(board_id), name };\n if (goal) body.goal = goal;\n if (start_date) body.startDate = start_date;\n if (end_date) body.endDate = end_date;\n const data = await atlassianFetch(auth, `/rest/agile/1.0/sprint`, {\n method: \"POST\",\n body: JSON.stringify(body),\n }) as { id?: number; self?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({ ok: true, sprint_id: data.id, board_id });\n },\n {\n name: \"jira_create_sprint\",\n description:\n \"Create a future sprint on a board. New sprints always start in 'future' state — use \" +\n \"jira_update_sprint with state='active' to start it. start_date/end_date are ISO 8601 strings; \" +\n \"they're optional but required by Atlassian before you can start the sprint.\",\n schema: z.object({\n board_id: z.union([z.string(), z.number()]).describe(\"Origin board id\"),\n name: z.string().describe(\"Sprint name\"),\n goal: z.string().optional(),\n start_date: z.string().optional().describe(\"ISO 8601 timestamp\"),\n end_date: z.string().optional().describe(\"ISO 8601 timestamp\"),\n }),\n },\n);\n\nexport const jiraUpdateSprintTool = tool(\n async ({ sprint_id, name, goal, start_date, end_date, state }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n\n if (state) {\n // Validate transition client-side. Fetch current state for a clean error.\n const current = await atlassianFetch(\n auth,\n `/rest/agile/1.0/sprint/${encodeURIComponent(sprint_id)}`,\n ) as { state?: string; error?: string };\n if (current.error) return JSON.stringify(current);\n const check = validateSprintTransition(current.state, state);\n if (\"error\" in check) {\n return JSON.stringify({\n error: check.error,\n current_state: current.state,\n legal_next_states: SPRINT_STATES.filter(\n (s) => !(\"error\" in validateSprintTransition(current.state, s)),\n ),\n });\n }\n }\n\n const body: Record<string, unknown> = {};\n if (name !== undefined) body.name = name;\n if (goal !== undefined) body.goal = goal;\n if (start_date !== undefined) body.startDate = start_date;\n if (end_date !== undefined) body.endDate = end_date;\n if (state !== undefined) body.state = state;\n if (Object.keys(body).length === 0) {\n return JSON.stringify({ error: \"no fields to update — pass at least one of name, goal, start_date, end_date, state\" });\n }\n\n const data = await atlassianFetch(auth, `/rest/agile/1.0/sprint/${encodeURIComponent(sprint_id)}`, {\n method: \"POST\",\n body: JSON.stringify(body),\n }) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n sprint_id,\n state: data.state,\n updated_fields: Object.keys(body),\n });\n },\n {\n name: \"jira_update_sprint\",\n description:\n \"Update a sprint's name, goal, dates, or state. State transitions: future→active (start) or \" +\n \"active→closed (complete). Other transitions are rejected client-side with the list of legal \" +\n \"next states. Pass only the fields you want to change. **Disable to make the agent unable to \" +\n \"start/complete sprints.**\",\n schema: z.object({\n sprint_id: z.union([z.string(), z.number()]),\n name: z.string().optional(),\n goal: z.string().optional(),\n start_date: z.string().optional().describe(\"ISO 8601 timestamp\"),\n end_date: z.string().optional().describe(\"ISO 8601 timestamp\"),\n state: z.enum([\"active\", \"closed\"]).optional().describe(\n \"Target state. 'active' starts a future sprint; 'closed' completes an active sprint.\",\n ),\n }),\n },\n);\n\nexport const jiraDeleteSprintTool = tool(\n async ({ sprint_id, confirm }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (String(confirm) !== String(sprint_id)) {\n return JSON.stringify({\n error:\n `Refusing to delete sprint ${sprint_id}: pass \\`confirm\\` set to the same id to proceed. ` +\n `Sprint deletion is irreversible — the issues are unassigned but historical sprint data is lost.`,\n });\n }\n const data = await atlassianFetch(auth, `/rest/agile/1.0/sprint/${encodeURIComponent(sprint_id)}`, {\n method: \"DELETE\",\n }) as { error?: string } | string;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, deleted_sprint_id: sprint_id });\n },\n {\n name: \"jira_delete_sprint\",\n description:\n \"Permanently delete a sprint. **Irreversible** — issues are unassigned from the sprint but the \" +\n \"sprint's velocity/burndown data is lost. The agent must pass `confirm` set to the same `sprint_id` \" +\n \"to proceed (two-arg gate). **Leave this tool disabled unless the user explicitly wants delete capability.**\",\n schema: z.object({\n sprint_id: z.union([z.string(), z.number()]),\n confirm: z.union([z.string(), z.number()]).describe(\"Must equal `sprint_id` for the delete to proceed\"),\n }),\n },\n);\n\nexport const jiraMoveIssuesToSprintTool = tool(\n async ({ sprint_id, issue_keys }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (!issue_keys.length) return JSON.stringify({ error: \"issue_keys is empty\" });\n if (issue_keys.length > 50) {\n return JSON.stringify({ error: `agile API accepts up to 50 issues per call (got ${issue_keys.length})` });\n }\n const data = await atlassianFetch(\n auth,\n `/rest/agile/1.0/sprint/${encodeURIComponent(sprint_id)}/issue`,\n { method: \"POST\", body: JSON.stringify({ issues: issue_keys }) },\n ) as { error?: string } | string;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, sprint_id, moved: issue_keys });\n },\n {\n name: \"jira_move_issues_to_sprint\",\n description:\n \"Move issues into a sprint. Up to 50 issues per call. Issues already in another sprint are \" +\n \"transparently moved (no separate remove step needed). Use jira_move_issues_to_backlog to remove \" +\n \"issues from sprints without putting them in a new one.\",\n schema: z.object({\n sprint_id: z.union([z.string(), z.number()]),\n issue_keys: z.array(z.string()).describe(\"Issue keys to move (e.g. ['PROJ-1','PROJ-2'])\"),\n }),\n },\n);\n\nexport const jiraMoveIssuesToBacklogTool = tool(\n async ({ issue_keys, board_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (!issue_keys.length) return JSON.stringify({ error: \"issue_keys is empty\" });\n if (issue_keys.length > 50) {\n return JSON.stringify({ error: `agile API accepts up to 50 issues per call (got ${issue_keys.length})` });\n }\n // The board-scoped endpoint /backlog/{boardId}/issue moves issues into THAT\n // board's backlog (preserving rank). The unscoped /backlog/issue endpoint\n // works for Scrum boards but not Kanban. Caller passes board_id when known.\n const path = board_id\n ? `/rest/agile/1.0/backlog/${encodeURIComponent(board_id)}/issue`\n : `/rest/agile/1.0/backlog/issue`;\n const data = await atlassianFetch(auth, path, {\n method: \"POST\",\n body: JSON.stringify({ issues: issue_keys }),\n }) as { error?: string } | string;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, moved_to_backlog: issue_keys, board_id: board_id ?? null });\n },\n {\n name: \"jira_move_issues_to_backlog\",\n description:\n \"Remove issues from their current sprint and put them back on the backlog. Up to 50 issues per \" +\n \"call. Pass `board_id` for Kanban boards (the unscoped endpoint only works for Scrum). For Scrum, \" +\n \"board_id is optional but recommended for clarity.\",\n schema: z.object({\n issue_keys: z.array(z.string()),\n board_id: z.union([z.string(), z.number()]).optional().describe(\n \"Required for Kanban boards; optional but recommended for Scrum\",\n ),\n }),\n },\n);\n\nexport const jiraRankIssuesTool = tool(\n async ({ issues, rank_before_issue, rank_after_issue, rank_custom_field_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (!issues.length) return JSON.stringify({ error: \"issues is empty\" });\n if (issues.length > 50) {\n return JSON.stringify({ error: `agile API accepts up to 50 issues per call (got ${issues.length})` });\n }\n if ((rank_before_issue && rank_after_issue) || (!rank_before_issue && !rank_after_issue)) {\n return JSON.stringify({\n error: \"pass exactly one of rank_before_issue or rank_after_issue (not both, not neither)\",\n });\n }\n const body: Record<string, unknown> = { issues };\n if (rank_before_issue) body.rankBeforeIssue = rank_before_issue;\n if (rank_after_issue) body.rankAfterIssue = rank_after_issue;\n if (rank_custom_field_id !== undefined) body.rankCustomFieldId = rank_custom_field_id;\n const data = await atlassianFetch(auth, `/rest/agile/1.0/issue/rank`, {\n method: \"PUT\",\n body: JSON.stringify(body),\n }) as { error?: string } | string;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n ranked: issues,\n relative_to: rank_before_issue ? { before: rank_before_issue } : { after: rank_after_issue },\n });\n },\n {\n name: \"jira_rank_issues\",\n description:\n \"Rank up to 50 issues relative to a single anchor issue (before XOR after). Pass \" +\n \"rank_custom_field_id only on sites that have a non-default rank field — get it from \" +\n \"jira_get_board.configuration.ranking_field. Order within `issues[]` is preserved.\",\n schema: z.object({\n issues: z.array(z.string()).describe(\"Issue keys in the order they should be placed\"),\n rank_before_issue: z.string().optional().describe(\"Anchor: place `issues` immediately before this key\"),\n rank_after_issue: z.string().optional().describe(\"Anchor: place `issues` immediately after this key\"),\n rank_custom_field_id: z.number().optional().describe(\n \"Custom rank field id (numeric). Default is the global rank field; rarely needed.\",\n ),\n }),\n },\n);\n\n// ── Jira issue extras (comments CRUD, worklogs, attachments, changelog) ─────\n//\n// These fill specific gaps left by the issue-CRUD tools above:\n// - jira_get_issue caps embedded comments at ~50; jira_get_comments paginates.\n// - jira_update_issue can't touch existing comments — that needs the per-comment endpoint.\n// - jira_upload_attachment uploads but doesn't read or delete; the get/delete pair completes it.\n// - jira_get_issue's changelog field is opt-in via expand and capped; the dedicated endpoint paginates.\n// See ADR-0035.\n\nexport const jiraGetCommentsTool = tool(\n async ({ issue_key, start_at, max_results, order_by }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const params = new URLSearchParams();\n if (start_at !== undefined) params.set(\"startAt\", String(start_at));\n params.set(\"maxResults\", String(Math.min(max_results ?? 50, 100)));\n if (order_by) params.set(\"orderBy\", order_by);\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/issue/${encodeURIComponent(issue_key)}/comment?${params}`,\n ) as {\n comments?: Array<Record<string, unknown>>;\n startAt?: number; maxResults?: number; total?: number;\n error?: string;\n };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n issue_key,\n start_at: data.startAt ?? 0,\n max_results: data.maxResults ?? 0,\n total: data.total ?? 0,\n comments: (data.comments ?? []).map((c) => ({\n id: c.id,\n author: (c.author as Record<string, unknown>)?.displayName ?? null,\n created: c.created,\n updated: c.updated,\n body: simplifyADF(c.body),\n })),\n });\n },\n {\n name: \"jira_get_comments\",\n description:\n \"Paginated comment list for a Jira issue. Use this when an issue has more comments than the \" +\n \"embedded list returned by jira_get_issue (Jira caps that at ~50). order_by accepts 'created' \" +\n \"or '-created' for ascending/descending. ADF bodies auto-flattened.\",\n schema: z.object({\n issue_key: z.string(),\n start_at: z.number().optional().describe(\"Offset for pagination (default 0)\"),\n max_results: z.number().optional().describe(\"Default 50, max 100\"),\n order_by: z.enum([\"created\", \"-created\"]).optional(),\n }),\n },\n);\n\nexport const jiraUpdateCommentTool = tool(\n async ({ issue_key, comment_id, body }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/issue/${encodeURIComponent(issue_key)}/comment/${encodeURIComponent(comment_id)}`,\n { method: \"PUT\", body: JSON.stringify({ body: textToADF(body) }) },\n ) as { id?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({ ok: true, comment_id: data.id ?? comment_id });\n },\n {\n name: \"jira_update_comment\",\n description:\n \"Edit an existing comment on a Jira issue. Plain-text body is auto-converted to ADF (same as \" +\n \"jira_add_comment). The author and created timestamp are preserved; updated reflects this edit.\",\n schema: z.object({\n issue_key: z.string(),\n comment_id: z.string().describe(\"Comment id from jira_get_issue.comments[].id or jira_get_comments\"),\n body: z.string(),\n }),\n },\n);\n\nexport const jiraDeleteCommentTool = tool(\n async ({ issue_key, comment_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/issue/${encodeURIComponent(issue_key)}/comment/${encodeURIComponent(comment_id)}`,\n { method: \"DELETE\" },\n ) as { error?: string } | string;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, deleted_comment_id: comment_id, issue_key });\n },\n {\n name: \"jira_delete_comment\",\n description:\n \"Permanently delete a comment from a Jira issue. **Destructive — no undo.** Look up the id via \" +\n \"jira_get_issue (include_comments: true) or jira_get_comments. Disable to make the agent unable \" +\n \"to delete comments.\",\n schema: z.object({ issue_key: z.string(), comment_id: z.string() }),\n },\n);\n\nexport const jiraGetAttachmentContentTool = tool(\n async ({ content_url, as_text }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n // Attachment content URLs from /rest/api/3/issue/{key} come pre-built as\n // absolute URLs under the auth.url host. We accept either absolute or\n // relative; build the request URL accordingly.\n const fullUrl = content_url.startsWith(\"http\")\n ? content_url\n : `${auth.url}${content_url.startsWith(\"/\") ? \"\" : \"/\"}${content_url}`;\n const res = await fetch(fullUrl, { headers: { Authorization: authHeader(auth) } });\n if (!res.ok) {\n const errText = await res.text();\n return JSON.stringify({ error: `Atlassian ${res.status}: ${errText.slice(0, 500)}` });\n }\n const ct = res.headers.get(\"content-type\") ?? \"\";\n const looksText = as_text === true\n || (as_text !== false && /^(text\\/|application\\/(json|xml|yaml|x-yaml))/i.test(ct));\n if (looksText) {\n const text = await res.text();\n return JSON.stringify({\n content_type: ct,\n size: text.length,\n as: \"text\",\n content: text.slice(0, 50_000),\n truncated: text.length > 50_000,\n });\n }\n const buf = Buffer.from(await res.arrayBuffer());\n return JSON.stringify({\n content_type: ct,\n size: buf.length,\n as: \"base64\",\n content: buf.toString(\"base64\"),\n });\n },\n {\n name: \"jira_get_attachment_content\",\n description:\n \"Fetch a Jira issue attachment's bytes by content_url (from jira_get_issue.attachments[].content_url). \" +\n \"Returns UTF-8 text capped at 50KB for text-like content types, or base64 for binary. Override the \" +\n \"auto-detection via `as_text`. Mirrors confluence_get_attachment_content.\",\n schema: z.object({\n content_url: z.string().describe(\"content_url from jira_get_issue.attachments[]\"),\n as_text: z.boolean().optional().describe(\n \"Force text decode (true) or binary base64 (false). Default: auto-detect by content-type.\",\n ),\n }),\n },\n);\n\nexport const jiraDeleteAttachmentTool = tool(\n async ({ attachment_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/attachment/${encodeURIComponent(attachment_id)}`,\n { method: \"DELETE\" },\n ) as { error?: string } | string;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, deleted_attachment_id: attachment_id });\n },\n {\n name: \"jira_delete_attachment\",\n description:\n \"Permanently delete an attachment from a Jira issue by id. **Destructive — no undo.** Look up \" +\n \"the id via jira_get_issue.attachments[].id. Disable to make the agent unable to delete attachments.\",\n schema: z.object({\n attachment_id: z.string().describe(\"Attachment id (from jira_get_issue.attachments[].id)\"),\n }),\n },\n);\n\nexport const jiraAddWorklogTool = tool(\n async ({ issue_key, time_spent, started, comment }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const body: Record<string, unknown> = { timeSpent: time_spent };\n if (started) body.started = started;\n if (comment) body.comment = textToADF(comment);\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/issue/${encodeURIComponent(issue_key)}/worklog`,\n { method: \"POST\", body: JSON.stringify(body) },\n ) as { id?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({ ok: true, worklog_id: data.id, issue_key });\n },\n {\n name: \"jira_add_worklog\",\n description:\n \"Log time spent on a Jira issue. time_spent uses Jira's duration syntax: '1h', '30m', '2d 4h', etc. \" +\n \"started is an ISO 8601 timestamp (defaults to now). comment is plain text auto-converted to ADF.\",\n schema: z.object({\n issue_key: z.string(),\n time_spent: z.string().describe(\"Duration string ('1h', '30m', '2d 4h')\"),\n started: z.string().optional().describe(\"ISO 8601 timestamp; defaults to now\"),\n comment: z.string().optional(),\n }),\n },\n);\n\nexport const jiraListWorklogsTool = tool(\n async ({ issue_key, start_at, max_results }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const params = new URLSearchParams();\n if (start_at !== undefined) params.set(\"startAt\", String(start_at));\n params.set(\"maxResults\", String(Math.min(max_results ?? 50, 1000)));\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/issue/${encodeURIComponent(issue_key)}/worklog?${params}`,\n ) as {\n worklogs?: Array<Record<string, unknown>>;\n startAt?: number; maxResults?: number; total?: number;\n error?: string;\n };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n issue_key,\n start_at: data.startAt ?? 0,\n max_results: data.maxResults ?? 0,\n total: data.total ?? 0,\n worklogs: (data.worklogs ?? []).map((w) => ({\n id: w.id,\n author: (w.author as Record<string, unknown>)?.displayName ?? null,\n time_spent: w.timeSpent,\n time_spent_seconds: w.timeSpentSeconds,\n started: w.started,\n created: w.created,\n updated: w.updated,\n comment: simplifyADF(w.comment),\n })),\n });\n },\n {\n name: \"jira_list_worklogs\",\n description:\n \"List worklog entries on a Jira issue (paginated). Returns id, author, time_spent (display string + \" +\n \"seconds), started, comment. Use to compute totals or audit time tracking.\",\n schema: z.object({\n issue_key: z.string(),\n start_at: z.number().optional(),\n max_results: z.number().optional().describe(\"Default 50, max 1000\"),\n }),\n },\n);\n\nexport const jiraGetChangelogTool = tool(\n async ({ issue_key, start_at, max_results }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const params = new URLSearchParams();\n if (start_at !== undefined) params.set(\"startAt\", String(start_at));\n params.set(\"maxResults\", String(Math.min(max_results ?? 50, 100)));\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/issue/${encodeURIComponent(issue_key)}/changelog?${params}`,\n ) as {\n values?: Array<Record<string, unknown>>;\n startAt?: number; maxResults?: number; total?: number;\n error?: string;\n };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n issue_key,\n start_at: data.startAt ?? 0,\n max_results: data.maxResults ?? 0,\n total: data.total ?? 0,\n changelog: (data.values ?? []).map((entry) => ({\n id: entry.id,\n author: (entry.author as Record<string, unknown>)?.displayName ?? null,\n created: entry.created,\n items: ((entry.items as Array<Record<string, unknown>>) ?? []).map((item) => ({\n field: item.field,\n field_type: item.fieldtype,\n // Atlassian returns both `from`/`to` (raw ids) and `fromString`/`toString`\n // (human-readable). Prefer the human form when present. NB: hasOwn check\n // is required because `toString` is inherited from Object.prototype.\n from: Object.hasOwn(item, \"fromString\") ? item.fromString : (item.from ?? null),\n to: Object.hasOwn(item, \"toString\") ? item.toString : (item.to ?? null),\n })),\n })),\n });\n },\n {\n name: \"jira_get_changelog\",\n description:\n \"Fetch a Jira issue's history (paginated). Each entry has author, timestamp, and a list of \" +\n \"field-level changes (field name, from, to). Useful for 'what changed yesterday?' audits and \" +\n \"for surfacing the previous value of a field.\",\n schema: z.object({\n issue_key: z.string(),\n start_at: z.number().optional(),\n max_results: z.number().optional().describe(\"Default 50, max 100\"),\n }),\n },\n);\n\n// ── Jira project metadata (projects, versions, components, generic enums) ──\n//\n// These let the agent introspect a site without guessing — list projects,\n// list versions on a project, read the canonical issue-type/priority/status\n// names. Mostly thin wrappers around /rest/api/3/project*, /version, /component,\n// and the four enum endpoints. See ADR-0035.\n\nexport const jiraListProjectsTool = tool(\n async ({ query, category_id, max_results, start_at }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const params = new URLSearchParams();\n if (query) params.set(\"query\", query);\n if (category_id !== undefined) params.set(\"categoryId\", String(category_id));\n if (start_at !== undefined) params.set(\"startAt\", String(start_at));\n params.set(\"maxResults\", String(Math.min(max_results ?? 50, 100)));\n const data = await atlassianFetch(auth, `/rest/api/3/project/search?${params}`) as\n | { values?: Array<Record<string, unknown>>; total?: number; isLast?: boolean; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n total: data.total ?? 0,\n is_last: data.isLast ?? null,\n projects: (data.values ?? []).map((p) => ({\n id: p.id,\n key: p.key,\n name: p.name,\n type_key: p.projectTypeKey ?? null,\n style: p.style ?? null,\n lead: ((p.lead as Record<string, unknown>)?.displayName) ?? null,\n })),\n });\n },\n {\n name: \"jira_list_projects\",\n description:\n \"List Jira projects (paginated). Filter by name fragment via `query` or by category. Returns \" +\n \"id, key, name, type, style ('classic'|'next-gen'), lead.\",\n schema: z.object({\n query: z.string().optional().describe(\"Project name/key fragment\"),\n category_id: z.number().optional(),\n start_at: z.number().optional(),\n max_results: z.number().optional().describe(\"Default 50, max 100\"),\n }),\n },\n);\n\nexport const jiraGetProjectTool = tool(\n async ({ project_key, include_versions, include_components, include_issue_types }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const expand: string[] = [];\n if (include_versions) expand.push(\"versions\");\n if (include_components) expand.push(\"components\");\n if (include_issue_types) expand.push(\"issueTypes\");\n const qs = expand.length ? `?expand=${expand.join(\",\")}` : \"\";\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/project/${encodeURIComponent(project_key)}${qs}`,\n ) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n id: data.id,\n key: data.key,\n name: data.name,\n type_key: data.projectTypeKey ?? null,\n style: data.style ?? null,\n description: data.description ?? null,\n lead: ((data.lead as Record<string, unknown>)?.displayName) ?? null,\n url: `${auth.url}/browse/${data.key}`,\n ...(include_versions ? {\n versions: ((data.versions as Array<Record<string, unknown>>) ?? []).map((v) => ({\n id: v.id, name: v.name, released: v.released, archived: v.archived,\n start_date: v.startDate ?? null, release_date: v.releaseDate ?? null,\n })),\n } : {}),\n ...(include_components ? {\n components: ((data.components as Array<Record<string, unknown>>) ?? []).map((c) => ({\n id: c.id, name: c.name,\n lead: ((c.lead as Record<string, unknown>)?.displayName) ?? null,\n })),\n } : {}),\n ...(include_issue_types ? {\n issue_types: ((data.issueTypes as Array<Record<string, unknown>>) ?? []).map((t) => ({\n id: t.id, name: t.name, subtask: t.subtask, hierarchy_level: t.hierarchyLevel,\n })),\n } : {}),\n });\n },\n {\n name: \"jira_get_project\",\n description:\n \"Fetch a single Jira project by key. Optionally include versions, components, and/or issue types \" +\n \"in the response — saves separate calls for the common 'tell me about this project' use case.\",\n schema: z.object({\n project_key: z.string(),\n include_versions: z.boolean().optional(),\n include_components: z.boolean().optional(),\n include_issue_types: z.boolean().optional(),\n }),\n },\n);\n\nexport const jiraListVersionsTool = tool(\n async ({ project_key, start_at, max_results, order_by }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const params = new URLSearchParams();\n if (start_at !== undefined) params.set(\"startAt\", String(start_at));\n params.set(\"maxResults\", String(Math.min(max_results ?? 50, 100)));\n if (order_by) params.set(\"orderBy\", order_by);\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/project/${encodeURIComponent(project_key)}/version?${params}`,\n ) as {\n values?: Array<Record<string, unknown>>;\n total?: number; isLast?: boolean; error?: string;\n };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n total: data.total ?? 0,\n is_last: data.isLast ?? null,\n versions: (data.values ?? []).map((v) => ({\n id: v.id,\n name: v.name,\n released: v.released,\n archived: v.archived,\n start_date: v.startDate ?? null,\n release_date: v.releaseDate ?? null,\n description: v.description ?? null,\n })),\n });\n },\n {\n name: \"jira_list_versions\",\n description:\n \"List versions on a Jira project (paginated). Returns id, name, released/archived flags, dates. \" +\n \"Use jira_create_version to add a new one and jira_update_version to release/archive.\",\n schema: z.object({\n project_key: z.string(),\n start_at: z.number().optional(),\n max_results: z.number().optional().describe(\"Default 50, max 100\"),\n order_by: z.enum([\"sequence\", \"name\", \"startDate\", \"releaseDate\", \"-sequence\", \"-name\", \"-startDate\", \"-releaseDate\"]).optional(),\n }),\n },\n);\n\nexport const jiraCreateVersionTool = tool(\n async ({ project_key, name, description, start_date, release_date, released }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n // Resolve project key → numeric project id (the version endpoint requires id, not key).\n const proj = await atlassianFetch(auth, `/rest/api/3/project/${encodeURIComponent(project_key)}`) as\n { id?: string; error?: string };\n if (proj.error) return JSON.stringify(proj);\n if (!proj.id) return JSON.stringify({ error: `could not resolve project_key \"${project_key}\" to a numeric id` });\n const body: Record<string, unknown> = { projectId: Number(proj.id), name };\n if (description !== undefined) body.description = description;\n if (start_date !== undefined) body.startDate = start_date;\n if (release_date !== undefined) body.releaseDate = release_date;\n if (released !== undefined) body.released = released;\n const data = await atlassianFetch(auth, `/rest/api/3/version`, {\n method: \"POST\", body: JSON.stringify(body),\n }) as { id?: string; name?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({ ok: true, version_id: data.id, name: data.name });\n },\n {\n name: \"jira_create_version\",\n description:\n \"Create a new version on a Jira project. Pass the project key — we resolve it to the numeric id. \" +\n \"start_date / release_date are 'YYYY-MM-DD'. Set released=true to mark released on creation.\",\n schema: z.object({\n project_key: z.string(),\n name: z.string(),\n description: z.string().optional(),\n start_date: z.string().optional().describe(\"YYYY-MM-DD\"),\n release_date: z.string().optional().describe(\"YYYY-MM-DD\"),\n released: z.boolean().optional(),\n }),\n },\n);\n\nexport const jiraUpdateVersionTool = tool(\n async ({ version_id, name, description, start_date, release_date, released, archived }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const body: Record<string, unknown> = {};\n if (name !== undefined) body.name = name;\n if (description !== undefined) body.description = description;\n if (start_date !== undefined) body.startDate = start_date;\n if (release_date !== undefined) body.releaseDate = release_date;\n if (released !== undefined) body.released = released;\n if (archived !== undefined) body.archived = archived;\n if (Object.keys(body).length === 0) {\n return JSON.stringify({ error: \"no fields to update — pass at least one of name, description, start_date, release_date, released, archived\" });\n }\n const data = await atlassianFetch(auth, `/rest/api/3/version/${encodeURIComponent(version_id)}`, {\n method: \"PUT\", body: JSON.stringify(body),\n }) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n version_id,\n released: data.released ?? null,\n archived: data.archived ?? null,\n updated_fields: Object.keys(body),\n });\n },\n {\n name: \"jira_update_version\",\n description:\n \"Edit a version: rename, change dates, mark released/unreleased, mark archived/unarchived. \" +\n \"Pass only the fields you want to change. To 'release' a version, pass released=true (and \" +\n \"release_date if not already set). To unrelease, pass released=false. **Disable to make the \" +\n \"agent unable to release versions.**\",\n schema: z.object({\n version_id: z.string(),\n name: z.string().optional(),\n description: z.string().optional(),\n start_date: z.string().optional(),\n release_date: z.string().optional(),\n released: z.boolean().optional(),\n archived: z.boolean().optional(),\n }),\n },\n);\n\nexport const jiraListComponentsTool = tool(\n async ({ project_key }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/project/${encodeURIComponent(project_key)}/components`,\n ) as Array<Record<string, unknown>> | { error?: string };\n if (!Array.isArray(data)) return JSON.stringify(data);\n return JSON.stringify({\n components: data.map((c) => ({\n id: c.id,\n name: c.name,\n description: c.description ?? null,\n lead: ((c.lead as Record<string, unknown>)?.displayName) ?? null,\n assignee_type: c.assigneeType ?? null,\n })),\n });\n },\n {\n name: \"jira_list_components\",\n description:\n \"List components on a Jira project. Returns id, name, description, lead, default assignee type. \" +\n \"Components are not paginated by Jira — the full list returns in one call.\",\n schema: z.object({ project_key: z.string() }),\n },\n);\n\nexport const jiraCreateComponentTool = tool(\n async ({ project_key, name, description, lead_account_id, assignee_type }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const body: Record<string, unknown> = { project: project_key, name };\n if (description !== undefined) body.description = description;\n if (lead_account_id !== undefined) body.leadAccountId = lead_account_id;\n if (assignee_type !== undefined) body.assigneeType = assignee_type;\n const data = await atlassianFetch(auth, `/rest/api/3/component`, {\n method: \"POST\", body: JSON.stringify(body),\n }) as { id?: string; name?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({ ok: true, component_id: data.id, name: data.name });\n },\n {\n name: \"jira_create_component\",\n description:\n \"Create a component on a Jira project. assignee_type controls default assignee for issues with \" +\n \"this component: 'PROJECT_DEFAULT' | 'COMPONENT_LEAD' | 'PROJECT_LEAD' | 'UNASSIGNED'.\",\n schema: z.object({\n project_key: z.string(),\n name: z.string(),\n description: z.string().optional(),\n lead_account_id: z.string().optional(),\n assignee_type: z.enum([\"PROJECT_DEFAULT\", \"COMPONENT_LEAD\", \"PROJECT_LEAD\", \"UNASSIGNED\"]).optional(),\n }),\n },\n);\n\nconst META_KIND_TO_PATH: Record<string, string> = {\n issue_type: \"/rest/api/3/issuetype\",\n priority: \"/rest/api/3/priority\",\n status: \"/rest/api/3/status\",\n resolution: \"/rest/api/3/resolution\",\n};\nconst META_KINDS = Object.keys(META_KIND_TO_PATH) as ReadonlyArray<keyof typeof META_KIND_TO_PATH>;\n\nexport const jiraListMetaTool = tool(\n async ({ kind }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (!kind) {\n return JSON.stringify({\n available_kinds: META_KINDS,\n usage: \"Pass kind='issue_type' | 'priority' | 'status' | 'resolution' to list that enum's values for the site.\",\n });\n }\n const path = META_KIND_TO_PATH[kind];\n if (!path) {\n return JSON.stringify({ error: `unknown kind \"${kind}\". Expected one of: ${META_KINDS.join(\", \")}.` });\n }\n const data = await atlassianFetch(auth, path) as Array<Record<string, unknown>> | { error?: string };\n if (!Array.isArray(data)) return JSON.stringify(data);\n return JSON.stringify({\n kind,\n values: data.map((v) => ({\n id: v.id,\n name: v.name,\n description: v.description ?? null,\n ...(kind === \"issue_type\" ? { subtask: v.subtask, hierarchy_level: v.hierarchyLevel } : {}),\n ...(kind === \"status\" ? {\n status_category: ((v.statusCategory as Record<string, unknown>)?.name) ?? null,\n } : {}),\n })),\n });\n },\n {\n name: \"jira_list_meta\",\n description:\n \"List values for a Jira site-wide enum: issue types, priorities, statuses, or resolutions. \" +\n \"Pass `kind` = 'issue_type' | 'priority' | 'status' | 'resolution'. Omit `kind` to list available kinds. \" +\n \"Use this before jira_create_issue / jira_update_issue when you don't know the exact name on this site.\",\n schema: z.object({\n kind: z.enum(META_KINDS as [string, ...string[]]).optional(),\n }),\n },\n);\n\n// ── Confluence tools ────────────────────────────────────────────────────────\n//\n// Most tools below use the Confluence v2 REST API (/wiki/api/v2/...). Three\n// gaps still require v1 paths as of 2026 and are flagged inline:\n// - confluence_search: v2 has no CQL endpoint.\n// - confluence_upload_attachment: v2 Attachment group is read-only (CONFCLOUD-77196).\n// - confluence_add_label: v2 Label group is read-only (CONFCLOUD-76866).\n// The remote document-RAG indexer in lib/documents/remote/confluence.ts (ADR-0026)\n// stays on v1 — it has its own concerns and is intentionally untouched here.\n\nexport const confluenceSearchTool = tool(\n async ({ cql, max_results }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const limit = Math.min(max_results ?? 15, 50);\n // v1: CQL search has no v2 equivalent.\n const data = await atlassianFetch(\n auth,\n `/wiki/rest/api/content/search?cql=${encodeURIComponent(cql)}&limit=${limit}`,\n ) as { results?: Array<Record<string, unknown>>; size?: number; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n total: data.size,\n results: (data.results ?? []).map((r: Record<string, unknown>) => ({\n id: r.id,\n type: r.type,\n title: r.title,\n url: `${auth.url}/wiki${((r._links as Record<string, unknown>)?.webui) ?? \"\"}`,\n })),\n });\n },\n {\n name: \"confluence_search\",\n description:\n \"Search Confluence pages with CQL (Confluence Query Language). \" +\n \"Examples: 'type=page AND title~\\\"runbook\\\"', 'space=ENG AND lastmodified > now(\\\"-7d\\\")'.\",\n schema: z.object({\n cql: z.string().describe(\"CQL query string\"),\n max_results: z.number().optional().describe(\"Max results (default 15, max 50)\"),\n }),\n },\n);\n\nexport const confluenceGetPageTool = tool(\n async ({ page_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await atlassianFetch(\n auth,\n `/wiki/api/v2/pages/${encodeURIComponent(page_id)}?body-format=storage,view&include-version=true`,\n ) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n const body = data.body as Record<string, Record<string, unknown> | undefined> | undefined;\n const storageVal = body?.storage?.value as string | undefined;\n const viewVal = body?.view?.value as string | undefined;\n const links = data._links as Record<string, unknown> | undefined;\n const webui = links?.webui as string | undefined;\n return JSON.stringify({\n id: data.id,\n title: data.title,\n url: webui ? `${auth.url}/wiki${webui}` : null,\n space_id: data.spaceId ?? null,\n parent_id: data.parentId ?? null,\n status: data.status,\n version: (data.version as Record<string, unknown> | undefined)?.number ?? null,\n // body_storage round-trips into confluence_update_page; body_view is rendered HTML\n // for summarization. Each capped to 20KB to keep context lean.\n body_storage: storageVal ? storageVal.slice(0, 20_000) : null,\n body_storage_truncated: storageVal ? storageVal.length > 20_000 : false,\n body_view: viewVal ? viewVal.slice(0, 20_000) : null,\n body_view_truncated: viewVal ? viewVal.length > 20_000 : false,\n });\n },\n {\n name: \"confluence_get_page\",\n description:\n \"Fetch a Confluence page by id (v2). Returns title, space_id, parent_id, version, and BOTH \" +\n \"body_storage (round-trippable into confluence_update_page) and body_view (rendered HTML, \" +\n \"easier to summarize). Each body capped at 20KB.\",\n schema: z.object({\n page_id: z.string(),\n }),\n },\n);\n\nexport const confluenceGetPageByTitleTool = tool(\n async ({ space_key, title, include_body }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const sid = await resolveSpaceId(auth, space_key);\n if (typeof sid !== \"string\") return JSON.stringify(sid);\n const params = new URLSearchParams({ title, \"space-id\": sid, limit: \"5\" });\n if (include_body) params.set(\"body-format\", \"storage\");\n const data = await atlassianFetch(auth, `/wiki/api/v2/pages?${params}`) as\n | { results?: Array<Record<string, unknown>>; error?: string };\n if (!Array.isArray(data?.results)) return JSON.stringify(data);\n return JSON.stringify({\n matches: data.results.map((p) => {\n const links = p._links as Record<string, unknown> | undefined;\n const webui = links?.webui as string | undefined;\n const body = p.body as Record<string, Record<string, unknown> | undefined> | undefined;\n return {\n id: p.id,\n title: p.title,\n space_id: p.spaceId,\n parent_id: p.parentId ?? null,\n status: p.status,\n url: webui ? `${auth.url}/wiki${webui}` : null,\n ...(include_body\n ? { body_storage: ((body?.storage?.value as string | undefined) ?? \"\").slice(0, 20_000) }\n : {}),\n };\n }),\n });\n },\n {\n name: \"confluence_get_page_by_title\",\n description:\n \"Find Confluence page(s) by exact title within a space. Auto-resolves `space_key` (e.g. 'ENG') \" +\n \"to the v2 space id. Returns up to 5 matches; pass `include_body: true` to also include storage XHTML.\",\n schema: z.object({\n space_key: z.string().describe(\"Space key like 'ENG'\"),\n title: z.string().describe(\"Exact page title (case-sensitive on Cloud)\"),\n include_body: z.boolean().optional(),\n }),\n },\n);\n\nexport const confluenceGetPageChildrenTool = tool(\n async ({ page_id, cursor, limit }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const params = new URLSearchParams({ limit: String(Math.min(limit ?? 25, 250)) });\n if (cursor) params.set(\"cursor\", cursor);\n const data = await atlassianFetch(\n auth,\n `/wiki/api/v2/pages/${encodeURIComponent(page_id)}/children?${params}`,\n ) as { results?: Array<Record<string, unknown>>; _links?: { next?: string }; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n children: (data.results ?? []).map((p) => ({\n id: p.id,\n title: p.title,\n type: p.type,\n status: p.status,\n parent_id: p.parentId ?? null,\n position: p.position ?? null,\n })),\n next_cursor: parseV2NextCursor(data._links?.next),\n });\n },\n {\n name: \"confluence_get_page_children\",\n description:\n \"List direct children of a Confluence page (cursor-paginated). Pass `cursor` from a prior call's \" +\n \"`next_cursor` to fetch the next page. Default limit 25 (max 250).\",\n schema: z.object({\n page_id: z.string(),\n cursor: z.string().optional(),\n limit: z.number().optional(),\n }),\n },\n);\n\nexport const confluenceGetPageAncestorsTool = tool(\n async ({ page_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await atlassianFetch(\n auth,\n `/wiki/api/v2/pages/${encodeURIComponent(page_id)}/ancestors`,\n ) as { results?: Array<Record<string, unknown>>; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ancestors: (data.results ?? []).map((a) => ({ id: a.id, title: a.title, type: a.type })),\n });\n },\n {\n name: \"confluence_get_page_ancestors\",\n description:\n \"Return the parent chain (root → leaf) for a Confluence page. Useful for breadcrumbs and \" +\n \"understanding where a page lives in the tree.\",\n schema: z.object({ page_id: z.string() }),\n },\n);\n\nexport const confluenceListSpacesTool = tool(\n async ({ cursor, limit, type, status }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const params = new URLSearchParams({ limit: String(Math.min(limit ?? 25, 250)) });\n if (cursor) params.set(\"cursor\", cursor);\n if (type) params.set(\"type\", type);\n if (status) params.set(\"status\", status);\n const data = await atlassianFetch(auth, `/wiki/api/v2/spaces?${params}`) as\n | { results?: Array<Record<string, unknown>>; _links?: { next?: string }; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n spaces: (data.results ?? []).map((s) => ({\n id: s.id,\n key: s.key,\n name: s.name,\n type: s.type,\n status: s.status,\n homepage_id: s.homepageId ?? null,\n })),\n next_cursor: parseV2NextCursor(data._links?.next),\n });\n },\n {\n name: \"confluence_list_spaces\",\n description:\n \"List Confluence spaces (cursor-paginated). Returns id, key, name, type, status, homepage_id. \" +\n \"Useful for discovering space keys to pass to confluence_create_page or confluence_get_page_by_title.\",\n schema: z.object({\n cursor: z.string().optional(),\n limit: z.number().optional(),\n type: z.enum([\"global\", \"personal\", \"collaboration\", \"knowledge_base\"]).optional(),\n status: z.enum([\"current\", \"archived\"]).optional(),\n }),\n },\n);\n\nexport const confluenceGetCommentsTool = tool(\n async ({ page_id, include_inline }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const footerData = await atlassianFetch(\n auth,\n `/wiki/api/v2/pages/${encodeURIComponent(page_id)}/footer-comments?body-format=storage&limit=100`,\n ) as { results?: Array<Record<string, unknown>>; error?: string };\n let inlineData: { results?: Array<Record<string, unknown>>; error?: string } | undefined;\n if (include_inline !== false) {\n // Known v2 bug: some sites 404 here even when comments exist. Tolerate\n // and surface as `inline_warning` so the caller still gets footer comments.\n inlineData = await atlassianFetch(\n auth,\n `/wiki/api/v2/pages/${encodeURIComponent(page_id)}/inline-comments?body-format=storage&limit=100`,\n ) as { results?: Array<Record<string, unknown>>; error?: string };\n }\n if (footerData.error && !Array.isArray(footerData.results)) return JSON.stringify(footerData);\n const flatten = (c: Record<string, unknown>) => {\n const ver = c.version as Record<string, unknown> | undefined;\n const body = c.body as Record<string, Record<string, unknown> | undefined> | undefined;\n return {\n id: c.id,\n version: ver?.number ?? null,\n author_id: c.authorId ?? ver?.authorId ?? null,\n created_at: ver?.createdAt ?? null,\n body_storage: (body?.storage?.value as string | undefined) ?? null,\n parent_comment_id: c.parentCommentId ?? null,\n };\n };\n return JSON.stringify({\n footer_comments: (footerData.results ?? []).map(flatten),\n inline_comments: inlineData && Array.isArray(inlineData.results) ? inlineData.results.map(flatten) : [],\n ...(inlineData && inlineData.error ? { inline_warning: inlineData.error } : {}),\n });\n },\n {\n name: \"confluence_get_comments\",\n description:\n \"List footer comments (and inline comments by default) on a Confluence page. Returns id, \" +\n \"version, author_id, created_at, body_storage, parent_comment_id (for threading). Tolerates \" +\n \"the known v2 inline-comments 404 bug — surfaces it as `inline_warning` rather than failing.\",\n schema: z.object({\n page_id: z.string(),\n include_inline: z.boolean().optional().describe(\"Default true; pass false to skip inline-comments.\"),\n }),\n },\n);\n\nexport const confluenceListAttachmentsTool = tool(\n async ({ page_id, cursor, limit }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const params = new URLSearchParams({ limit: String(Math.min(limit ?? 50, 250)) });\n if (cursor) params.set(\"cursor\", cursor);\n const data = await atlassianFetch(\n auth,\n `/wiki/api/v2/pages/${encodeURIComponent(page_id)}/attachments?${params}`,\n ) as { results?: Array<Record<string, unknown>>; _links?: { next?: string }; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n attachments: (data.results ?? []).map((a) => {\n const ver = a.version as Record<string, unknown> | undefined;\n const links = a._links as Record<string, unknown> | undefined;\n return {\n id: a.id,\n title: a.title,\n media_type: a.mediaType,\n file_size: a.fileSize ?? null,\n created_at: ver?.createdAt ?? null,\n download_link: a.downloadLink ?? null,\n webui_link: links?.webui ?? null,\n };\n }),\n next_cursor: parseV2NextCursor(data._links?.next),\n });\n },\n {\n name: \"confluence_list_attachments\",\n description:\n \"List attachments on a Confluence page (cursor-paginated). Returns id, title, media_type, \" +\n \"file_size, download_link. Use confluence_get_attachment_content with the download_link to \" +\n \"fetch bytes.\",\n schema: z.object({\n page_id: z.string(),\n cursor: z.string().optional(),\n limit: z.number().optional(),\n }),\n },\n);\n\nexport const confluenceGetLabelsTool = tool(\n async ({ page_id, cursor, limit }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const params = new URLSearchParams({ limit: String(Math.min(limit ?? 50, 250)) });\n if (cursor) params.set(\"cursor\", cursor);\n const data = await atlassianFetch(\n auth,\n `/wiki/api/v2/pages/${encodeURIComponent(page_id)}/labels?${params}`,\n ) as { results?: Array<Record<string, unknown>>; _links?: { next?: string }; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n labels: (data.results ?? []).map((l) => ({ id: l.id, name: l.name, prefix: l.prefix })),\n next_cursor: parseV2NextCursor(data._links?.next),\n });\n },\n {\n name: \"confluence_get_labels\",\n description: \"List labels on a Confluence page (cursor-paginated). Default limit 50 (max 250).\",\n schema: z.object({\n page_id: z.string(),\n cursor: z.string().optional(),\n limit: z.number().optional(),\n }),\n },\n);\n\nexport const confluenceGetAttachmentContentTool = tool(\n async ({ download_link, as_text }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n // download_link from v2 is typically `/download/attachments/{pageId}/{filename}?...`\n // — under the /wiki app, NOT under the bare auth.url. Build the absolute URL\n // explicitly because atlassianFetch's plain `${auth.url}${path}` join would\n // miss the /wiki prefix.\n const fullUrl = download_link.startsWith(\"http\")\n ? download_link\n : download_link.startsWith(\"/wiki\")\n ? `${auth.url}${download_link}`\n : `${auth.url}/wiki${download_link.startsWith(\"/\") ? \"\" : \"/\"}${download_link}`;\n const res = await fetch(fullUrl, { headers: { Authorization: authHeader(auth) } });\n if (!res.ok) {\n const errText = await res.text();\n return JSON.stringify({ error: `Atlassian ${res.status}: ${errText.slice(0, 500)}` });\n }\n const ct = res.headers.get(\"content-type\") ?? \"\";\n const looksText = as_text === true\n || (as_text !== false && /^(text\\/|application\\/(json|xml|yaml|x-yaml))/i.test(ct));\n if (looksText) {\n const text = await res.text();\n return JSON.stringify({\n content_type: ct,\n size: text.length,\n as: \"text\",\n content: text.slice(0, 50_000),\n truncated: text.length > 50_000,\n });\n }\n const buf = Buffer.from(await res.arrayBuffer());\n return JSON.stringify({\n content_type: ct,\n size: buf.length,\n as: \"base64\",\n content: buf.toString(\"base64\"),\n });\n },\n {\n name: \"confluence_get_attachment_content\",\n description:\n \"Fetch an attachment's bytes by its download_link (from confluence_list_attachments). Returns \" +\n \"UTF-8 text (capped at 50KB) for text-like content types, or base64 for binary. Override the \" +\n \"auto-detection via `as_text`.\",\n schema: z.object({\n download_link: z.string().describe(\"download_link from confluence_list_attachments\"),\n as_text: z.boolean().optional().describe(\n \"Force text decode (true) or binary base64 (false). Default: auto-detect by content-type.\",\n ),\n }),\n },\n);\n\nexport const confluenceCreatePageTool = tool(\n async ({ space_key, title, parent_id, body_text, body_storage }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const sid = await resolveSpaceId(auth, space_key);\n if (typeof sid !== \"string\") return JSON.stringify(sid);\n const body = resolveBody({ body_text, body_storage });\n if (\"error\" in body) return JSON.stringify(body);\n const payload: Record<string, unknown> = {\n spaceId: sid,\n status: \"current\",\n title,\n body: { representation: body.representation, value: body.value },\n };\n if (parent_id) payload.parentId = parent_id;\n const data = await atlassianFetch(auth, `/wiki/api/v2/pages`, {\n method: \"POST\",\n body: JSON.stringify(payload),\n }) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n const links = data._links as Record<string, unknown> | undefined;\n const webui = links?.webui as string | undefined;\n return JSON.stringify({\n ok: true,\n id: data.id,\n title: data.title,\n space_id: data.spaceId,\n parent_id: data.parentId ?? null,\n version: (data.version as Record<string, unknown> | undefined)?.number ?? 1,\n url: webui ? `${auth.url}/wiki${webui}` : null,\n });\n },\n {\n name: \"confluence_create_page\",\n description:\n \"Create a Confluence page (v2). Pass `space_key` (e.g. 'ENG') — auto-resolved to v2 spaceId. \" +\n \"Pass exactly one of `body_text` (plain text → storage XHTML automatically) or `body_storage` \" +\n \"(raw XHTML for advanced edits). `parent_id` makes it a child page. \" +\n \"Disable to make the agent unable to author Confluence pages.\",\n schema: z.object({\n space_key: z.string(),\n title: z.string(),\n parent_id: z.string().optional().describe(\"Page id of the parent; omit for top-level.\"),\n body_text: z.string().optional().describe(\"Plain text; auto-converted to storage XHTML.\"),\n body_storage: z.string().optional().describe(\"Raw Confluence storage-format XHTML.\"),\n }),\n },\n);\n\nexport const confluenceUpdatePageTool = tool(\n async ({ page_id, title, body_text, body_storage, version_number, version_message }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const body = resolveBody({ body_text, body_storage });\n if (\"error\" in body) return JSON.stringify(body);\n\n let nextVersion = version_number;\n let resolvedTitle: string | undefined = title;\n if (nextVersion === undefined || resolvedTitle === undefined) {\n // PUT requires both title and version even when not changing them, so\n // fetch the current page when either is omitted. Cheaper than asking\n // every caller to do it.\n const current = await atlassianFetch(\n auth,\n `/wiki/api/v2/pages/${encodeURIComponent(page_id)}`,\n ) as { title?: string; version?: { number?: number }; error?: string };\n if (current.error) return JSON.stringify(current);\n if (nextVersion === undefined) {\n const cur = current.version?.number;\n if (typeof cur !== \"number\") return JSON.stringify({ error: \"could not read current version from Confluence response\" });\n nextVersion = cur + 1;\n }\n if (resolvedTitle === undefined) resolvedTitle = current.title;\n }\n\n const payload: Record<string, unknown> = {\n id: page_id,\n status: \"current\",\n title: resolvedTitle,\n body: { representation: body.representation, value: body.value },\n version: { number: nextVersion, ...(version_message ? { message: version_message } : {}) },\n };\n const data = await atlassianFetch(auth, `/wiki/api/v2/pages/${encodeURIComponent(page_id)}`, {\n method: \"PUT\",\n body: JSON.stringify(payload),\n }) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n const links = data._links as Record<string, unknown> | undefined;\n const webui = links?.webui as string | undefined;\n return JSON.stringify({\n ok: true,\n id: data.id,\n title: data.title,\n version: (data.version as Record<string, unknown> | undefined)?.number ?? nextVersion,\n url: webui ? `${auth.url}/wiki${webui}` : null,\n });\n },\n {\n name: \"confluence_update_page\",\n description:\n \"Update an existing Confluence page (v2). Pass exactly one of `body_text` or `body_storage`. \" +\n \"If `version_number` is omitted, the tool auto-fetches the current version and sends current+1 \" +\n \"(Confluence requires strict +1 increments; gaps cause 409). If `title` is omitted, the existing \" +\n \"title is preserved. Avoid back-to-back updates within ~1 second — Confluence may return 409 even \" +\n \"with the correct version. Disable to make the agent read-only on pages.\",\n schema: z.object({\n page_id: z.string(),\n title: z.string().optional().describe(\"New title; omit to keep existing.\"),\n body_text: z.string().optional(),\n body_storage: z.string().optional(),\n version_number: z.number().optional().describe(\n \"Explicit version (must equal currentVersion+1). Omit to auto-fetch and increment.\",\n ),\n version_message: z.string().optional().describe(\"Optional change comment shown in version history.\"),\n }),\n },\n);\n\nexport const confluenceAddCommentTool = tool(\n async ({ page_id, body_text, body_storage, parent_comment_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const body = resolveBody({ body_text, body_storage });\n if (\"error\" in body) return JSON.stringify(body);\n const payload: Record<string, unknown> = {\n pageId: page_id,\n body: { representation: body.representation, value: body.value },\n };\n if (parent_comment_id) payload.parentCommentId = parent_comment_id;\n const data = await atlassianFetch(auth, `/wiki/api/v2/footer-comments`, {\n method: \"POST\",\n body: JSON.stringify(payload),\n }) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n comment_id: data.id,\n page_id,\n parent_comment_id: data.parentCommentId ?? null,\n });\n },\n {\n name: \"confluence_add_comment\",\n description:\n \"Add a footer comment to a Confluence page (v2). Pass exactly one of `body_text` or \" +\n \"`body_storage`. Pass `parent_comment_id` (from confluence_get_comments) to reply in a thread.\",\n schema: z.object({\n page_id: z.string(),\n body_text: z.string().optional(),\n body_storage: z.string().optional(),\n parent_comment_id: z.string().optional().describe(\"To reply to an existing comment.\"),\n }),\n },\n);\n\nexport const confluenceMovePageTool = tool(\n async ({ page_id, position, target_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await atlassianFetch(\n auth,\n `/wiki/api/v2/pages/${encodeURIComponent(page_id)}/move/${encodeURIComponent(position)}/${encodeURIComponent(target_id)}`,\n { method: \"PUT\" },\n ) as { error?: string } | string | Record<string, unknown>;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, page_id, position, target_id });\n },\n {\n name: \"confluence_move_page\",\n description:\n \"Reorder/reparent a Confluence page (v2). `position`: 'before' or 'after' to place as a sibling \" +\n \"of `target_id`; 'append' to make it a child of `target_id`. Non-destructive.\",\n schema: z.object({\n page_id: z.string(),\n position: z.enum([\"before\", \"after\", \"append\"]),\n target_id: z.string().describe(\"Sibling (for before/after) or new parent (for append).\"),\n }),\n },\n);\n\nexport const confluenceUploadAttachmentTool = tool(\n async ({ page_id, filename, content_base64, content_text, comment, minor_edit }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (!content_base64 && !content_text) {\n return JSON.stringify({ error: \"pass either content_base64 (binary) or content_text (UTF-8)\" });\n }\n const buf = content_base64\n ? Buffer.from(content_base64, \"base64\")\n : Buffer.from(content_text!, \"utf8\");\n\n // v1 fallback: v2 Attachment group is read-only as of 2026 (CONFCLOUD-77196).\n // Same multipart shape as jiraUploadAttachmentTool — X-Atlassian-Token: no-check\n // bypasses CSRF; do NOT set Content-Type (fetch fills in the multipart boundary).\n const form = new FormData();\n form.append(\"file\", new Blob([buf]), filename);\n if (typeof comment === \"string\") form.append(\"comment\", comment);\n if (minor_edit) form.append(\"minorEdit\", \"true\");\n\n const url = `${auth.url}/wiki/rest/api/content/${encodeURIComponent(page_id)}/child/attachment`;\n const res = await fetch(url, {\n method: \"POST\",\n headers: {\n Authorization: authHeader(auth),\n Accept: \"application/json\",\n \"X-Atlassian-Token\": \"no-check\",\n },\n body: form,\n });\n const text = await res.text();\n if (!res.ok) return JSON.stringify({ error: `Atlassian ${res.status}: ${text.slice(0, 500)}` });\n const parsed = parseJsonSafe<{\n results?: Array<{ id: string; title: string; metadata?: { mediaType?: string }; extensions?: { fileSize?: number } }>;\n }>(text, {});\n return JSON.stringify({\n ok: true,\n page_id,\n attachments: (parsed.results ?? []).map((a) => ({\n id: a.id,\n title: a.title,\n media_type: a.metadata?.mediaType ?? null,\n file_size: a.extensions?.fileSize ?? null,\n })),\n });\n },\n {\n name: \"confluence_upload_attachment\",\n description:\n \"Attach a file to a Confluence page. Pass content_base64 for binary or content_text for plain \" +\n \"UTF-8. Uses the v1 multipart endpoint (v2 has no attachment-create endpoint as of 2026). \" +\n \"Disable to make the agent unable to add attachments.\",\n schema: z.object({\n page_id: z.string(),\n filename: z.string().describe(\"Filename shown in Confluence (include the extension).\"),\n content_base64: z.string().optional().describe(\"Base64-encoded file contents (use for binary).\"),\n content_text: z.string().optional().describe(\"Raw UTF-8 text contents (use for logs/CSVs/JSON).\"),\n comment: z.string().optional().describe(\"Version comment shown in the attachment history.\"),\n minor_edit: z.boolean().optional().describe(\"If true, doesn't notify watchers.\"),\n }),\n },\n);\n\nexport const confluenceAddLabelTool = tool(\n async ({ page_id, labels }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (!labels.length) return JSON.stringify({ error: \"labels is empty\" });\n // v1 fallback: v2 Label group is read-only as of 2026 (CONFCLOUD-76866).\n const payload = labels.map((name) => ({ prefix: \"global\", name }));\n const data = await atlassianFetch(\n auth,\n `/wiki/rest/api/content/${encodeURIComponent(page_id)}/label`,\n { method: \"POST\", body: JSON.stringify(payload) },\n ) as { results?: Array<{ name?: string; prefix?: string }>; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n page_id,\n added: labels,\n total_labels: (data.results ?? []).map((r) => r.name).filter(Boolean),\n });\n },\n {\n name: \"confluence_add_label\",\n description:\n \"Add one or more labels to a Confluence page (additive — does not replace existing labels). \" +\n \"Uses the v1 endpoint (v2 only reads labels as of 2026).\",\n schema: z.object({\n page_id: z.string(),\n labels: z.array(z.string()).describe(\"Label names to add (e.g. ['runbook', 'on-call']).\"),\n }),\n },\n);\n\n// ── Confluence v2 gap-fillers (ADR-0035) ────────────────────────────────────\n//\n// v2 audit on 2026-05-28 confirmed:\n// - DELETE /pages/{id} exists (with optional purge=true).\n// - PUT/DELETE /footer-comments/{id} and /inline-comments/{id} exist.\n// - DELETE /attachments/{id} exists (with optional purge=true).\n// - Label group is STILL read-only (CONFCLOUD-76866); confluence_remove_label\n// uses the v1 fallback `DELETE /content/{id}/label?name=...`.\n\nexport const confluenceDeletePageTool = tool(\n async ({ page_id, purge, confirm }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (purge && confirm !== page_id) {\n return JSON.stringify({\n error:\n `Refusing to permanently delete page ${page_id}: purge=true requires confirm to equal page_id. ` +\n `A purged page cannot be restored from trash. Drop purge if you only want to soft-delete.`,\n });\n }\n const qs = purge ? `?purge=true` : \"\";\n const data = await atlassianFetch(\n auth,\n `/wiki/api/v2/pages/${encodeURIComponent(page_id)}${qs}`,\n { method: \"DELETE\" },\n ) as { error?: string } | string;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, deleted_page_id: page_id, purged: !!purge });\n },\n {\n name: \"confluence_delete_page\",\n description:\n \"Delete a Confluence page (v2). Default soft-deletes (page goes to trash, restorable). \" +\n \"Pass purge=true for permanent deletion, which **also requires `confirm` to equal page_id** \" +\n \"as a guardrail. Disable to make the agent unable to delete pages.\",\n schema: z.object({\n page_id: z.string(),\n purge: z.boolean().optional().describe(\"If true, permanently delete (skip trash). Requires confirm=page_id.\"),\n confirm: z.string().optional().describe(\"Required when purge=true; must equal page_id.\"),\n }),\n },\n);\n\nconst COMMENT_KIND_TO_PATH: Record<string, string> = {\n footer: \"footer-comments\",\n inline: \"inline-comments\",\n};\n\nexport const confluenceUpdateCommentTool = tool(\n async ({ comment_id, kind, body_text, body_storage, version_number, version_message }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const segment = COMMENT_KIND_TO_PATH[kind];\n if (!segment) {\n return JSON.stringify({ error: `unknown kind \"${kind}\". Expected 'footer' or 'inline'.` });\n }\n const body = resolveBody({ body_text, body_storage });\n if (\"error\" in body) return JSON.stringify(body);\n\n let nextVersion = version_number;\n if (nextVersion === undefined) {\n // PUT requires version.number = current + 1; auto-fetch when not passed.\n const current = await atlassianFetch(\n auth,\n `/wiki/api/v2/${segment}/${encodeURIComponent(comment_id)}`,\n ) as { version?: { number?: number }; error?: string };\n if (current.error) return JSON.stringify(current);\n const cur = current.version?.number;\n if (typeof cur !== \"number\") return JSON.stringify({ error: \"could not read current comment version\" });\n nextVersion = cur + 1;\n }\n\n const payload: Record<string, unknown> = {\n version: { number: nextVersion, ...(version_message ? { message: version_message } : {}) },\n body: { representation: body.representation, value: body.value },\n };\n const data = await atlassianFetch(\n auth,\n `/wiki/api/v2/${segment}/${encodeURIComponent(comment_id)}`,\n { method: \"PUT\", body: JSON.stringify(payload) },\n ) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n comment_id,\n kind,\n version: (data.version as Record<string, unknown> | undefined)?.number ?? nextVersion,\n });\n },\n {\n name: \"confluence_update_comment\",\n description:\n \"Edit an existing Confluence comment (v2). Pass `kind: 'footer' | 'inline'` to route to the \" +\n \"correct endpoint. Same `body_text` xor `body_storage` pattern as confluence_add_comment. If \" +\n \"version_number is omitted, the tool auto-fetches the current version and sends current+1 \" +\n \"(Confluence requires strict +1 increments).\",\n schema: z.object({\n comment_id: z.string(),\n kind: z.enum([\"footer\", \"inline\"]),\n body_text: z.string().optional(),\n body_storage: z.string().optional(),\n version_number: z.number().optional().describe(\"Explicit version (must be current+1). Omit to auto-fetch.\"),\n version_message: z.string().optional(),\n }),\n },\n);\n\nexport const confluenceDeleteCommentTool = tool(\n async ({ comment_id, kind }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const segment = COMMENT_KIND_TO_PATH[kind];\n if (!segment) {\n return JSON.stringify({ error: `unknown kind \"${kind}\". Expected 'footer' or 'inline'.` });\n }\n const data = await atlassianFetch(\n auth,\n `/wiki/api/v2/${segment}/${encodeURIComponent(comment_id)}`,\n { method: \"DELETE\" },\n ) as { error?: string } | string;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, deleted_comment_id: comment_id, kind });\n },\n {\n name: \"confluence_delete_comment\",\n description:\n \"Permanently delete a Confluence comment (v2). Pass `kind: 'footer' | 'inline'`. **Destructive — \" +\n \"no undo.** Disable to make the agent unable to delete comments.\",\n schema: z.object({\n comment_id: z.string(),\n kind: z.enum([\"footer\", \"inline\"]),\n }),\n },\n);\n\nexport const confluenceRemoveLabelTool = tool(\n async ({ page_id, label }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n // v1 fallback — v2 Label group is read-only as of 2026-05-28 (CONFCLOUD-76866).\n // The v1 endpoint accepts the label name as a query param; the prefix\n // defaults to \"global\" which is what confluence_add_label uses.\n const data = await atlassianFetch(\n auth,\n `/wiki/rest/api/content/${encodeURIComponent(page_id)}/label?name=${encodeURIComponent(label)}`,\n { method: \"DELETE\" },\n ) as { error?: string } | string;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, page_id, removed_label: label });\n },\n {\n name: \"confluence_remove_label\",\n description:\n \"Remove a single label from a Confluence page. Uses the v1 endpoint (v2 Label group is still \" +\n \"read-only as of 2026). Counterpart to confluence_add_label.\",\n schema: z.object({\n page_id: z.string(),\n label: z.string().describe(\"Label name to remove (no prefix; we always use 'global')\"),\n }),\n },\n);\n\nexport const confluenceDeleteAttachmentTool = tool(\n async ({ attachment_id, purge, confirm }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (purge && confirm !== attachment_id) {\n return JSON.stringify({\n error:\n `Refusing to permanently delete attachment ${attachment_id}: purge=true requires confirm to equal attachment_id. ` +\n `A purged attachment cannot be restored.`,\n });\n }\n const qs = purge ? `?purge=true` : \"\";\n const data = await atlassianFetch(\n auth,\n `/wiki/api/v2/attachments/${encodeURIComponent(attachment_id)}${qs}`,\n { method: \"DELETE\" },\n ) as { error?: string } | string;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, deleted_attachment_id: attachment_id, purged: !!purge });\n },\n {\n name: \"confluence_delete_attachment\",\n description:\n \"Delete a Confluence attachment by id (v2). Default soft-deletes (trash, restorable). Pass \" +\n \"purge=true for permanent deletion, which **also requires `confirm` to equal attachment_id** \" +\n \"as a guardrail.\",\n schema: z.object({\n attachment_id: z.string(),\n purge: z.boolean().optional(),\n confirm: z.string().optional().describe(\"Required when purge=true; must equal attachment_id.\"),\n }),\n },\n);\n\n// ── Helpers ─────────────────────────────────────────────────────────────────\n\n// Convert plain text → Confluence storage-format XHTML. Splits on blank lines\n// for paragraphs and uses <br/> for single newlines. Escapes &, <, > because\n// Confluence storage rejects unescaped ampersands and stray angle brackets.\n// Pure — exported for unit testing.\nexport function confluenceTextToStorage(text: string): string {\n if (text.length === 0) return \"<p></p>\";\n const escape = (s: string) =>\n s.replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\");\n return text\n .split(/\\n{2,}/)\n .map((para) => `<p>${para.split(\"\\n\").map(escape).join(\"<br/>\")}</p>`)\n .join(\"\");\n}\n\n// Extract the opaque cursor query param from a Confluence v2 `_links.next` URL.\n// v2 cursors are not safe to construct — Atlassian explicitly says \"always parse\n// the next link, never build it\". Pure — exported for unit testing.\nexport function parseV2NextCursor(linksNext: string | undefined): string | null {\n if (!linksNext) return null;\n const m = linksNext.match(/[?&]cursor=([^&]+)/);\n return m ? decodeURIComponent(m[1]) : null;\n}\n\n// Body input dispatcher used by create_page / update_page / add_comment.\n// Callers pass body_text XOR body_storage; this resolves to the wire format\n// or a structured error for the LLM. body_storage is rejected if it contains\n// <script>/<style> — Confluence storage rejects those with opaque 400s, so\n// catch it here with a useful message.\nfunction resolveBody(input: { body_text?: string; body_storage?: string }):\n | { value: string; representation: \"storage\" }\n | { error: string }\n{\n const hasText = typeof input.body_text === \"string\";\n const hasStorage = typeof input.body_storage === \"string\";\n if (hasText && hasStorage) {\n return { error: \"pass exactly one of body_text or body_storage, not both\" };\n }\n if (!hasText && !hasStorage) {\n return { error: \"pass exactly one of body_text or body_storage\" };\n }\n if (hasStorage) {\n const s = input.body_storage!;\n if (/<\\s*(script|style)[\\s>]/i.test(s)) {\n return { error: \"body_storage rejected: <script>/<style> tags are not allowed by Confluence storage format\" };\n }\n return { value: s, representation: \"storage\" };\n }\n return { value: confluenceTextToStorage(input.body_text!), representation: \"storage\" };\n}\n\n// Per-site cache of space key → numeric space id. v2 page endpoints take\n// spaceId, but humans (and the LLM) think in space keys. 1h TTL mirrors\n// loadJiraFields below.\nconst SPACE_ID_CACHE_TTL_MS = 60 * 60 * 1000;\nconst spaceIdCache = new Map<string, { id: string; loaded: number }>();\n\nasync function resolveSpaceId(\n auth: AtlassianAuth,\n spaceKey: string,\n): Promise<string | { error: string }> {\n const cacheKey = `${auth.url}|${spaceKey}`;\n const cached = spaceIdCache.get(cacheKey);\n if (cached && Date.now() - cached.loaded < SPACE_ID_CACHE_TTL_MS) return cached.id;\n const data = await atlassianFetch(\n auth,\n `/wiki/api/v2/spaces?keys=${encodeURIComponent(spaceKey)}&limit=1`,\n ) as { results?: Array<{ id: string; key: string }>; error?: string };\n if (\"error\" in data && data.error) return { error: data.error };\n const hit = (data.results ?? []).find((s) => s.key === spaceKey) ?? data.results?.[0];\n if (!hit?.id) return { error: `space key \"${spaceKey}\" not found` };\n spaceIdCache.set(cacheKey, { id: hit.id, loaded: Date.now() });\n return hit.id;\n}\n\n// Per-site cache of /rest/api/3/field. Custom field IDs are stable per site,\n// but display names can be edited; 1h TTL keeps us fresh without thrashing.\nexport interface JiraFieldDef { id: string; name: string; custom: boolean }\nconst FIELD_CACHE_TTL_MS = 60 * 60 * 1000;\nconst fieldCache = new Map<string, { fields: JiraFieldDef[]; loaded: number }>();\n\nasync function loadJiraFields(auth: AtlassianAuth): Promise<JiraFieldDef[] | { error: string }> {\n const cached = fieldCache.get(auth.url);\n if (cached && Date.now() - cached.loaded < FIELD_CACHE_TTL_MS) return cached.fields;\n const data = await atlassianFetch(auth, `/rest/api/3/field`) as\n | Array<{ id: string; name: string; custom: boolean }>\n | { error?: string };\n if (!Array.isArray(data)) return data as { error: string };\n const fields = data.map((f) => ({ id: f.id, name: f.name, custom: f.custom }));\n fieldCache.set(auth.url, { fields, loaded: Date.now() });\n return fields;\n}\n\n// Pure helper — exported for unit testing. Given a list of caller inputs and\n// the site's field definitions, partition into resolved (matched by id or\n// case-insensitive display name) and unresolved.\nexport function resolveCustomFieldNames(\n inputs: string[],\n fields: JiraFieldDef[],\n): { resolved: Array<{ input: string; id: string; name: string }>; unresolved: string[] } {\n const byId = new Map<string, JiraFieldDef>();\n const byName = new Map<string, JiraFieldDef>();\n for (const f of fields) {\n byId.set(f.id, f);\n byName.set(f.name.toLowerCase(), f);\n }\n const resolved: Array<{ input: string; id: string; name: string }> = [];\n const unresolved: string[] = [];\n for (const input of inputs) {\n const trimmed = input.trim();\n const hit = byId.get(trimmed) ?? byName.get(trimmed.toLowerCase());\n if (hit) resolved.push({ input, id: hit.id, name: hit.name });\n else unresolved.push(input);\n }\n return { resolved, unresolved };\n}\n\n// Coerce a Jira field value (which can be string, number, ADF doc, option\n// object, user object, array of those) into something an LLM can read. When\n// Jira returns a renderedFields HTML version, prefer that — it's the author's\n// formatting, flattened.\nexport function extractFieldValue(raw: unknown, renderedHTML: unknown): unknown {\n if (typeof renderedHTML === \"string\" && renderedHTML.length > 0) {\n return stripHtml(renderedHTML);\n }\n if (raw == null) return null;\n if (typeof raw === \"string\" || typeof raw === \"number\" || typeof raw === \"boolean\") return raw;\n if (Array.isArray(raw)) return raw.map(coerceItem);\n if (typeof raw === \"object\") {\n const obj = raw as Record<string, unknown>;\n if (obj.type === \"doc\" && Array.isArray(obj.content)) return simplifyADF(obj);\n if (typeof obj.value === \"string\") return obj.value;\n if (typeof obj.displayName === \"string\") return obj.displayName;\n if (typeof obj.name === \"string\") return obj.name;\n return obj;\n }\n return raw;\n}\n\nfunction coerceItem(item: unknown): unknown {\n if (!item || typeof item !== \"object\") return item;\n const obj = item as Record<string, unknown>;\n if (typeof obj.value === \"string\") return obj.value;\n if (typeof obj.name === \"string\") return obj.name;\n if (typeof obj.displayName === \"string\") return obj.displayName;\n return obj;\n}\n\nfunction stripHtml(html: string): string {\n return html\n .replace(/<br\\s*\\/?>/gi, \"\\n\")\n .replace(/<\\/p>/gi, \"\\n\\n\")\n .replace(/<\\/li>/gi, \"\\n\")\n .replace(/<li[^>]*>/gi, \"• \")\n .replace(/<[^>]+>/g, \"\")\n .replace(/ /g, \" \")\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/'/g, \"'\")\n .replace(/"/g, '\"')\n .replace(/[ \\t]+\\n/g, \"\\n\")\n .replace(/\\n{3,}/g, \"\\n\\n\")\n .trim();\n}\n\n// Atlassian's REST API takes ADF (Atlassian Document Format), not plain text.\n// This wraps a plain string so the agent doesn't have to know the schema.\nfunction textToADF(text: string): unknown {\n type ADFNode = { type: string; text?: string };\n return {\n type: \"doc\",\n version: 1,\n content: text.split(/\\n\\n+/).map((para) => ({\n type: \"paragraph\",\n content: para.split(\"\\n\").flatMap<ADFNode>((line, i) =>\n i === 0\n ? [{ type: \"text\", text: line }]\n : [{ type: \"hardBreak\" }, { type: \"text\", text: line }],\n ),\n })),\n };\n}\n\n// Best-effort flatten of an ADF document back to plain text. Doesn't preserve\n// formatting but gives the agent something readable to summarize.\nfunction simplifyADF(adf: unknown): string {\n if (!adf || typeof adf !== \"object\") return typeof adf === \"string\" ? adf : \"\";\n const out: string[] = [];\n walk(adf);\n return out.join(\"\").trim();\n\n function walk(node: unknown): void {\n if (!node || typeof node !== \"object\") return;\n const n = node as Record<string, unknown>;\n if (n.type === \"text\" && typeof n.text === \"string\") out.push(n.text);\n if (n.type === \"hardBreak\") out.push(\"\\n\");\n if (n.type === \"paragraph\") { walkChildren(n.content); out.push(\"\\n\\n\"); }\n else if (n.type === \"bulletList\" || n.type === \"orderedList\") walkChildren(n.content);\n else if (n.type === \"listItem\") { out.push(\"• \"); walkChildren(n.content); }\n else walkChildren(n.content);\n }\n function walkChildren(children: unknown): void {\n if (Array.isArray(children)) for (const c of children) walk(c);\n }\n}\n\nregisterTools(\"Atlassian\", \"read\", [\n jiraSearchTool, jiraGetIssueTool, jiraFindUserTool,\n jiraListBoardsTool, jiraGetBoardTool,\n jiraListSprintsTool, jiraGetSprintTool,\n jiraGetCommentsTool, jiraGetAttachmentContentTool,\n jiraListWorklogsTool, jiraGetChangelogTool,\n jiraListProjectsTool, jiraGetProjectTool,\n jiraListVersionsTool, jiraListComponentsTool, jiraListMetaTool,\n confluenceSearchTool, confluenceGetPageTool,\n confluenceGetPageByTitleTool, confluenceGetPageChildrenTool,\n confluenceGetPageAncestorsTool, confluenceListSpacesTool,\n confluenceGetCommentsTool, confluenceListAttachmentsTool,\n confluenceGetLabelsTool, confluenceGetAttachmentContentTool,\n]);\nregisterTools(\"Atlassian\", \"execute\", [\n jiraCreateIssueTool, jiraCreateIssuesBulkTool, jiraUpdateIssueTool,\n jiraAddCommentTool, jiraTransitionsTool,\n jiraLinkIssuesTool, jiraAddRemoteLinkTool, jiraDeleteLinkTool,\n jiraUploadAttachmentTool, jiraDeleteIssueTool,\n jiraCreateSprintTool, jiraUpdateSprintTool, jiraDeleteSprintTool,\n jiraMoveIssuesToSprintTool, jiraMoveIssuesToBacklogTool, jiraRankIssuesTool,\n jiraUpdateCommentTool, jiraDeleteCommentTool, jiraDeleteAttachmentTool,\n jiraAddWorklogTool,\n jiraCreateVersionTool, jiraUpdateVersionTool, jiraCreateComponentTool,\n confluenceCreatePageTool, confluenceUpdatePageTool,\n confluenceAddCommentTool, confluenceMovePageTool,\n confluenceUploadAttachmentTool, confluenceAddLabelTool,\n confluenceDeletePageTool, confluenceUpdateCommentTool, confluenceDeleteCommentTool,\n confluenceRemoveLabelTool, confluenceDeleteAttachmentTool,\n]);\n","/**\n * Native GitHub tools — direct REST API calls, no MCP, no `gh` CLI.\n *\n * Mirrors the Atlassian tool (lib/tools/atlassian.ts) in shape: the agent\n * never shells out, every call goes through the same `fetch` global that\n * already honours the in-app HTTP proxy + custom CA bundle (ADR-0009,\n * ADR-0012). That means these tools work on a corp laptop with the MCP\n * install path blocked, which was the whole point of building them native.\n *\n * Auth resolution (priority order):\n * 1. Env: GITHUB_TOKEN, then GH_TOKEN (matches gh CLI's fallback chain).\n * 2. Memory store: namespace=\"integrations\", key=\"github\", value={ token }.\n *\n * The agent populates option 2 via the propose_config_change /\n * enable_integration flow (ADR-0010); env wins because deployment-level\n * config should beat per-user secrets stored in the local DB.\n */\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { getIntegrationRaw } from \"@/lib/stores/integrations\";\nimport { parseJsonSafe } from \"@/lib/utils/json\";\nimport { isLikelyBinary } from \"@/lib/documents/indexer\";\nimport { registerTools } from \"./registry\";\n\nexport interface GitHubAuth {\n token: string;\n}\n\n// Exposed so the integrations test endpoint can probe the live API after save.\nexport function _resolveGithubAuth(): GitHubAuth | { error: string } {\n return resolveAuth();\n}\n\nfunction resolveAuth(): GitHubAuth | { error: string } {\n const env = process.env.GITHUB_TOKEN ?? process.env.GH_TOKEN;\n if (env && env.trim()) return { token: env.trim() };\n const saved = getIntegrationRaw(\"github\");\n if (saved?.token) return { token: saved.token };\n return {\n error:\n \"GitHub not configured. Open the gear menu → Integrations and add a Personal Access Token. \" +\n \"Create one at github.com/settings/tokens with scopes: repo, read:org. \" +\n \"(Or set GITHUB_TOKEN / GH_TOKEN as an env var.)\",\n };\n}\n\nconst API = \"https://api.github.com\";\n\nasync function ghFetch(\n auth: GitHubAuth,\n path: string,\n init?: RequestInit,\n): Promise<unknown> {\n const url = path.startsWith(\"http\") ? path : `${API}${path}`;\n const res = await fetch(url, {\n ...init,\n headers: {\n Authorization: `Bearer ${auth.token}`,\n Accept: \"application/vnd.github+json\",\n \"X-GitHub-Api-Version\": \"2022-11-28\",\n \"User-Agent\": \"Jarela\",\n ...(init?.headers ?? {}),\n },\n });\n const text = await res.text();\n if (!res.ok) {\n return { error: `GitHub ${res.status}: ${text.slice(0, 500)}`, url };\n }\n if (!text) return {};\n return parseJsonSafe<unknown>(text, text);\n}\n\n// Exposed for sibling modules that need the same auth/proxy/CA-bundle\n// behaviour without duplicating the wrapper (currently:\n// `lib/documents/remote/github.ts`, ADR-0029). Mirrors `_atlassianFetch`.\nexport async function _ghFetch(\n auth: GitHubAuth,\n path: string,\n init?: RequestInit,\n): Promise<unknown> {\n return ghFetch(auth, path, init);\n}\n\n// ── Shared helpers ─────────────────────────────────────────────────────────\n\nconst BODY_CAP = 20_000;\nconst COMMENT_CAP = 8_000;\nconst PATCH_CAP = 8_000;\nconst SNIPPET_CAP = 400;\n\n// Pure-fn body cap. Returns the same `body` field shape as the existing\n// inline ternaries in github_get_issue / github_get_pull (str + truncated\n// flag) so the agent doesn't need to handle two shapes.\nexport function truncate(text: string, cap: number): { text: string; truncated: boolean } {\n if (text.length <= cap) return { text, truncated: false };\n return { text: text.slice(0, cap), truncated: true };\n}\n\n// `/repos/.../contents/{path}` returns a base64-encoded blob; the API also\n// returns the same response shape for directories (as an array). Decode +\n// detect binary so the agent gets useful output for text and a clear\n// not-text signal for everything else.\nexport interface DecodedBlob {\n binary: boolean;\n text?: string;\n size_bytes: number;\n}\nexport function decodeContentsBlob(content: string, encoding: string | undefined): DecodedBlob {\n if (!content) return { binary: false, text: \"\", size_bytes: 0 };\n const b64 = encoding === \"base64\" ? content.replace(/\\s+/g, \"\") : \"\";\n const buf = b64 ? Buffer.from(b64, \"base64\") : Buffer.from(content, \"utf8\");\n if (isLikelyBinary(buf)) return { binary: true, size_bytes: buf.length };\n return { binary: false, text: buf.toString(\"utf8\"), size_bytes: buf.length };\n}\n\n// Trim repo URLs on issue/PR responses to user-facing html_urls (the API\n// returns api.github.com/repos/... which is useless for a human).\ntype GhUser = { login?: string } | null;\ntype GhLabel = { name?: string };\n\nfunction liteUser(u: unknown): string | null {\n return (u as GhUser)?.login ?? null;\n}\nfunction liteLabels(labels: unknown): string[] {\n return (labels as GhLabel[] | undefined ?? []).map((l) => l.name).filter(Boolean) as string[];\n}\n\ntype GhIssueLite = {\n number?: number;\n title?: string;\n state?: string;\n html_url?: string;\n user?: GhUser;\n labels?: GhLabel[];\n pull_request?: unknown; // presence means \"this issue is actually a PR\"\n updated_at?: string;\n comments?: number;\n};\n\n// ── Issue tools ────────────────────────────────────────────────────────────\n\nexport const githubSearchIssuesTool = tool(\n async ({ q, repo, max_results }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const limit = Math.min(max_results ?? 25, 100);\n // `repo:owner/name` is the dominant filter — accept it as a separate\n // parameter so the agent doesn't have to remember GitHub's search syntax\n // for the common case. Anything else goes in `q`.\n const query = repo ? `repo:${repo} ${q}` : q;\n const data = await ghFetch(\n auth,\n `/search/issues?q=${encodeURIComponent(query)}&per_page=${limit}`,\n ) as { items?: GhIssueLite[]; total_count?: number; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n total: data.total_count ?? 0,\n items: (data.items ?? []).map((i) => ({\n number: i.number,\n title: i.title,\n state: i.state,\n is_pr: !!i.pull_request,\n url: i.html_url,\n user: liteUser(i.user),\n labels: liteLabels(i.labels),\n updated_at: i.updated_at,\n comments: i.comments ?? 0,\n })),\n });\n },\n {\n name: \"github_search_issues\",\n description:\n \"Search GitHub issues AND pull requests with the same query syntax as the github.com search bar. \" +\n \"**PREFER THIS over shell-exec'ing the `gh` CLI.** Pass `repo` (\\\"owner/name\\\") to scope the search \" +\n \"to a single repo — the tool prepends `repo:owner/name ` automatically. The `q` body accepts the \" +\n \"full GitHub search vocabulary: 'is:issue is:open assignee:@me', 'is:pr review-requested:@me', \" +\n \"'label:bug created:>2026-01-01', etc. `is_pr` in the response distinguishes PRs from issues.\",\n schema: z.object({\n q: z.string().describe(\"GitHub search query (e.g. 'is:open is:issue label:bug')\"),\n repo: z.string().optional().describe(\"Optional 'owner/name' shortcut; prepended as repo: filter\"),\n max_results: z.number().optional().describe(\"Max items (default 25, max 100)\"),\n }),\n },\n);\n\nexport const githubGetIssueTool = tool(\n async ({ owner, repo, number }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/issues/${number}`,\n ) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n const assignees = (data.assignees as Array<{ login?: string }> | undefined ?? [])\n .map((a) => a.login).filter(Boolean);\n const cap = truncate(typeof data.body === \"string\" ? data.body : \"\", BODY_CAP);\n return JSON.stringify({\n number: data.number,\n title: data.title,\n state: data.state,\n is_pr: !!data.pull_request,\n url: data.html_url,\n author: liteUser(data.user),\n labels: liteLabels(data.labels),\n assignees,\n created_at: data.created_at,\n updated_at: data.updated_at,\n closed_at: data.closed_at,\n comments: data.comments,\n body: cap.text,\n truncated: cap.truncated,\n });\n },\n {\n name: \"github_get_issue\",\n description:\n \"Fetch a single issue (or PR — same endpoint) by number. Returns body capped at 20KB, plus labels, \" +\n \"assignees, and timestamps. **PREFER THIS over shell-exec'ing the `gh` CLI.**\",\n schema: z.object({\n owner: z.string().describe(\"Repository owner (user or org)\"),\n repo: z.string().describe(\"Repository name\"),\n number: z.number().int().positive().describe(\"Issue or PR number\"),\n }),\n },\n);\n\nexport const githubCreateIssueTool = tool(\n async ({ owner, repo, title, body, labels, assignees }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const payload: Record<string, unknown> = { title };\n if (body) payload.body = body;\n if (labels?.length) payload.labels = labels;\n if (assignees?.length) payload.assignees = assignees;\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/issues`,\n { method: \"POST\", body: JSON.stringify(payload) },\n ) as { number?: number; html_url?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({ ok: true, number: data.number, url: data.html_url });\n },\n {\n name: \"github_create_issue\",\n description:\n \"Open a new issue in a repository. **PREFER THIS over shell-exec'ing the `gh` CLI.** Labels and \" +\n \"assignees must already exist on the repo — invalid values produce a 422.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n title: z.string().describe(\"Issue title\"),\n body: z.string().optional().describe(\"Markdown body\"),\n labels: z.array(z.string()).optional().describe(\"Existing label names\"),\n assignees: z.array(z.string()).optional().describe(\"GitHub usernames with access\"),\n }),\n },\n);\n\nexport const githubAddCommentTool = tool(\n async ({ owner, repo, number, body }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n // Same endpoint for issues AND PRs — GitHub treats PR comments as issue\n // comments (the line-level review comments are a different surface).\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/issues/${number}/comments`,\n { method: \"POST\", body: JSON.stringify({ body }) },\n ) as { id?: number; html_url?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({ ok: true, comment_id: data.id, url: data.html_url });\n },\n {\n name: \"github_add_comment\",\n description:\n \"Post a comment on an issue or pull request (GitHub treats both the same). \" +\n \"**PREFER THIS over shell-exec'ing the `gh` CLI.** Body is rendered as GitHub-flavored Markdown.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n number: z.number().int().positive(),\n body: z.string().describe(\"Comment body (GitHub-flavored Markdown)\"),\n }),\n },\n);\n\n// ── Pull-request tools ─────────────────────────────────────────────────────\n\nexport const githubListPullsTool = tool(\n async ({ owner, repo, state, head, base, max_results }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const limit = Math.min(max_results ?? 25, 100);\n const params = new URLSearchParams({ per_page: String(limit) });\n if (state) params.set(\"state\", state);\n if (head) params.set(\"head\", head);\n if (base) params.set(\"base\", base);\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls?${params.toString()}`,\n ) as Array<Record<string, unknown>> | { error?: string; message?: string };\n if (!Array.isArray(data)) return JSON.stringify(data);\n return JSON.stringify({\n pulls: data.map((p) => ({\n number: p.number,\n title: p.title,\n state: p.state,\n draft: p.draft,\n url: p.html_url,\n user: liteUser(p.user),\n head: (p.head as { ref?: string } | null)?.ref ?? null,\n base: (p.base as { ref?: string } | null)?.ref ?? null,\n created_at: p.created_at,\n updated_at: p.updated_at,\n })),\n });\n },\n {\n name: \"github_list_pulls\",\n description:\n \"List pull requests for a repository, optionally filtered by state / head branch / base branch. \" +\n \"**PREFER THIS over shell-exec'ing the `gh` CLI.** For richer detail on a single PR (mergeable, \" +\n \"review state, file count) call github_get_pull.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n state: z.enum([\"open\", \"closed\", \"all\"]).optional().describe(\"Default: open\"),\n head: z.string().optional().describe(\"Filter by head: 'user:branch' or 'org:branch'\"),\n base: z.string().optional().describe(\"Filter by base branch (e.g. 'main')\"),\n max_results: z.number().optional().describe(\"Max PRs (default 25, max 100)\"),\n }),\n },\n);\n\nexport const githubGetPullTool = tool(\n async ({ owner, repo, number }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls/${number}`,\n ) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n const head = data.head as { ref?: string; sha?: string; repo?: { full_name?: string } } | null;\n const base = data.base as { ref?: string; sha?: string } | null;\n const cap = truncate(typeof data.body === \"string\" ? data.body : \"\", BODY_CAP);\n return JSON.stringify({\n number: data.number,\n title: data.title,\n state: data.state,\n draft: data.draft,\n merged: data.merged,\n mergeable: data.mergeable, // null = GitHub still computing\n mergeable_state: data.mergeable_state,\n url: data.html_url,\n author: liteUser(data.user),\n head: head ? { ref: head.ref, sha: head.sha, repo: head.repo?.full_name } : null,\n base: base ? { ref: base.ref, sha: base.sha } : null,\n changed_files: data.changed_files,\n additions: data.additions,\n deletions: data.deletions,\n review_comments: data.review_comments,\n comments: data.comments,\n created_at: data.created_at,\n updated_at: data.updated_at,\n merged_at: data.merged_at,\n body: cap.text,\n truncated: cap.truncated,\n });\n },\n {\n name: \"github_get_pull\",\n description:\n \"Fetch detail on a single pull request — head/base SHAs, mergeable state, additions/deletions, \" +\n \"changed files count, review comment count. **PREFER THIS over shell-exec'ing the `gh` CLI.** \" +\n \"Note: `mergeable` may be null on a freshly-pushed PR; GitHub computes it asynchronously.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n number: z.number().int().positive(),\n }),\n },\n);\n\n// ── Repo info ───────────────────────────────────────────────────────────────\n\nexport const githubGetRepoTool = tool(\n async ({ owner, repo }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}`,\n ) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n full_name: data.full_name,\n url: data.html_url,\n description: data.description,\n visibility: data.visibility ?? (data.private ? \"private\" : \"public\"),\n default_branch: data.default_branch,\n topics: data.topics ?? [],\n language: data.language,\n stars: data.stargazers_count,\n forks: data.forks_count,\n open_issues: data.open_issues_count,\n archived: data.archived,\n pushed_at: data.pushed_at,\n });\n },\n {\n name: \"github_get_repo\",\n description:\n \"Fetch repo summary (default branch, visibility, description, topics, star/fork counts, \" +\n \"open-issue count). **PREFER THIS over shell-exec'ing the `gh` CLI.** Useful before opening \" +\n \"an issue (to confirm the repo exists / pick the right default branch).\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n }),\n },\n);\n\n// ── Issue write / read (cont'd) ────────────────────────────────────────────\n\nexport const githubUpdateIssueTool = tool(\n async ({ owner, repo, number, title, body, state, state_reason, labels, assignees }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const payload: Record<string, unknown> = {};\n if (title !== undefined) payload.title = title;\n if (body !== undefined) payload.body = body;\n if (state !== undefined) payload.state = state;\n if (state_reason !== undefined) payload.state_reason = state_reason;\n if (labels !== undefined) payload.labels = labels;\n if (assignees !== undefined) payload.assignees = assignees;\n if (Object.keys(payload).length === 0) {\n return JSON.stringify({ error: \"no fields to update — pass at least one of title/body/state/labels/assignees\" });\n }\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/issues/${number}`,\n { method: \"PATCH\", body: JSON.stringify(payload) },\n ) as { number?: number; html_url?: string; state?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n number: data.number,\n state: data.state,\n url: data.html_url,\n updated_fields: Object.keys(payload),\n });\n },\n {\n name: \"github_update_issue\",\n description:\n \"Edit an issue or PR (same endpoint): change title, body, labels, assignees, or close/reopen via \" +\n \"`state`. **PREFER THIS over shell-exec'ing the `gh` CLI.** Pass `state: \\\"closed\\\"` with \" +\n \"`state_reason: \\\"completed\\\"` for done-as-intended, or `\\\"not_planned\\\"` for won't-fix.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n number: z.number().int().positive(),\n title: z.string().optional(),\n body: z.string().optional().describe(\"New issue body (Markdown). Replaces, doesn't append.\"),\n state: z.enum([\"open\", \"closed\"]).optional(),\n state_reason: z.enum([\"completed\", \"not_planned\", \"reopened\"]).optional(),\n labels: z.array(z.string()).optional().describe(\"Replaces the label set entirely.\"),\n assignees: z.array(z.string()).optional().describe(\"Replaces the assignee set entirely.\"),\n }),\n },\n);\n\nexport const githubListIssueCommentsTool = tool(\n async ({ owner, repo, number, max_results }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const limit = Math.min(max_results ?? 25, 100);\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/issues/${number}/comments?per_page=${limit}`,\n ) as Array<Record<string, unknown>> | { error?: string };\n if (!Array.isArray(data)) return JSON.stringify(data);\n return JSON.stringify({\n comments: data.map((c) => {\n const cap = truncate(typeof c.body === \"string\" ? c.body : \"\", COMMENT_CAP);\n return {\n id: c.id,\n user: liteUser(c.user),\n created_at: c.created_at,\n updated_at: c.updated_at,\n url: c.html_url,\n body: cap.text,\n truncated: cap.truncated,\n };\n }),\n });\n },\n {\n name: \"github_list_issue_comments\",\n description:\n \"List comments on an issue or PR. **PREFER THIS over shell-exec'ing the `gh` CLI.** Each comment \" +\n \"body is capped at 8 KB; `truncated: true` flags ones that hit the cap.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n number: z.number().int().positive(),\n max_results: z.number().optional().describe(\"Max comments (default 25, max 100)\"),\n }),\n },\n);\n\n// ── Pull-request write ─────────────────────────────────────────────────────\n\nexport const githubCreatePullTool = tool(\n async ({ owner, repo, title, head, base, body, draft, maintainer_can_modify }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const payload: Record<string, unknown> = { title, head, base };\n if (body !== undefined) payload.body = body;\n if (draft !== undefined) payload.draft = draft;\n if (maintainer_can_modify !== undefined) payload.maintainer_can_modify = maintainer_can_modify;\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls`,\n { method: \"POST\", body: JSON.stringify(payload) },\n ) as { number?: number; html_url?: string; draft?: boolean; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({ ok: true, number: data.number, draft: data.draft, url: data.html_url });\n },\n {\n name: \"github_create_pull\",\n description:\n \"Open a pull request. **PREFER THIS over shell-exec'ing the `gh` CLI.** `head` is the branch with \" +\n \"your changes (use `user:branch` for cross-fork PRs); `base` is the branch you want to merge into. \" +\n \"Returns 422 if the head/base pair has no diff or if the branches don't exist.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n title: z.string(),\n head: z.string().describe(\"Source branch ('feature/x' for same-repo, 'user:branch' for fork PRs)\"),\n base: z.string().describe(\"Target branch (typically 'main')\"),\n body: z.string().optional().describe(\"PR description (Markdown)\"),\n draft: z.boolean().optional().describe(\"Open as draft (default false)\"),\n maintainer_can_modify: z.boolean().optional()\n .describe(\"Allow upstream maintainers to push to your fork branch (default true)\"),\n }),\n },\n);\n\nexport const githubUpdatePullTool = tool(\n async ({ owner, repo, number, title, body, state, base, maintainer_can_modify }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const payload: Record<string, unknown> = {};\n if (title !== undefined) payload.title = title;\n if (body !== undefined) payload.body = body;\n if (state !== undefined) payload.state = state;\n if (base !== undefined) payload.base = base;\n if (maintainer_can_modify !== undefined) payload.maintainer_can_modify = maintainer_can_modify;\n if (Object.keys(payload).length === 0) {\n return JSON.stringify({ error: \"no fields to update — pass at least one of title/body/state/base\" });\n }\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls/${number}`,\n { method: \"PATCH\", body: JSON.stringify(payload) },\n ) as { number?: number; html_url?: string; state?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n number: data.number,\n state: data.state,\n url: data.html_url,\n updated_fields: Object.keys(payload),\n });\n },\n {\n name: \"github_update_pull\",\n description:\n \"Edit a pull request: title, body, base branch, or close/reopen. **PREFER THIS over shell-exec'ing \" +\n \"the `gh` CLI.** To MERGE a PR use github_merge_pull — `state` here only opens / closes.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n number: z.number().int().positive(),\n title: z.string().optional(),\n body: z.string().optional(),\n state: z.enum([\"open\", \"closed\"]).optional()\n .describe(\"`closed` here means 'close without merging'. Use github_merge_pull to merge.\"),\n base: z.string().optional().describe(\"Re-target the PR at a different base branch.\"),\n maintainer_can_modify: z.boolean().optional(),\n }),\n },\n);\n\nexport const githubMergePullTool = tool(\n async ({ owner, repo, number, method, commit_title, commit_message, sha }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const payload: Record<string, unknown> = {};\n if (commit_title !== undefined) payload.commit_title = commit_title;\n if (commit_message !== undefined) payload.commit_message = commit_message;\n if (method !== undefined) payload.merge_method = method;\n if (sha !== undefined) payload.sha = sha;\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls/${number}/merge`,\n { method: \"PUT\", body: JSON.stringify(payload) },\n ) as { merged?: boolean; sha?: string; message?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: !!data.merged,\n merged_sha: data.sha ?? null,\n message: data.message ?? null,\n });\n },\n {\n name: \"github_merge_pull\",\n description:\n \"Merge a pull request. **PREFER THIS over shell-exec'ing the `gh` CLI.** `method` selects the \" +\n \"merge strategy (default `merge`); pass `sha` to refuse the merge if the PR head has been \" +\n \"force-pushed since you last looked. 405 means the PR isn't mergeable yet (still in CI / has \" +\n \"conflicts / needs review); 409 means the `sha` guard tripped.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n number: z.number().int().positive(),\n method: z.enum([\"merge\", \"squash\", \"rebase\"]).optional(),\n commit_title: z.string().optional()\n .describe(\"Title for the merge commit (or squash commit). Default: GitHub's auto-generated title.\"),\n commit_message: z.string().optional(),\n sha: z.string().optional()\n .describe(\"Refuse to merge unless the PR head still matches this SHA — guards against TOCTOU.\"),\n }),\n },\n);\n\nexport const githubRequestReviewersTool = tool(\n async ({ owner, repo, number, reviewers, team_reviewers }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (!reviewers?.length && !team_reviewers?.length) {\n return JSON.stringify({ error: \"pass at least one of reviewers or team_reviewers\" });\n }\n const payload: Record<string, unknown> = {};\n if (reviewers?.length) payload.reviewers = reviewers;\n if (team_reviewers?.length) payload.team_reviewers = team_reviewers;\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls/${number}/requested_reviewers`,\n { method: \"POST\", body: JSON.stringify(payload) },\n ) as {\n requested_reviewers?: Array<{ login?: string }>;\n requested_teams?: Array<{ slug?: string }>;\n html_url?: string;\n error?: string;\n };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n requested_users: (data.requested_reviewers ?? []).map((u) => u.login).filter(Boolean),\n requested_teams: (data.requested_teams ?? []).map((t) => t.slug).filter(Boolean),\n url: data.html_url,\n });\n },\n {\n name: \"github_request_reviewers\",\n description:\n \"Request review on a pull request from one or more users and/or teams. **PREFER THIS over \" +\n \"shell-exec'ing the `gh` CLI.** GitHub silently drops invalid usernames / team slugs — check the \" +\n \"returned `requested_users` / `requested_teams` to see who actually got a notification.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n number: z.number().int().positive(),\n reviewers: z.array(z.string()).optional().describe(\"GitHub usernames\"),\n team_reviewers: z.array(z.string()).optional().describe(\"Team slugs (org-scoped)\"),\n }),\n },\n);\n\nexport const githubCreateReviewTool = tool(\n async ({ owner, repo, number, event, body, commit_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (event === \"REQUEST_CHANGES\" && !body?.trim()) {\n return JSON.stringify({ error: \"REQUEST_CHANGES requires a non-empty body explaining what to change\" });\n }\n const payload: Record<string, unknown> = { event };\n if (body !== undefined) payload.body = body;\n if (commit_id !== undefined) payload.commit_id = commit_id;\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls/${number}/reviews`,\n { method: \"POST\", body: JSON.stringify(payload) },\n ) as { id?: number; state?: string; html_url?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({ ok: true, review_id: data.id, state: data.state, url: data.html_url });\n },\n {\n name: \"github_create_review\",\n description:\n \"Submit a pull-request review (approve / request changes / leave a comment). **PREFER THIS over \" +\n \"shell-exec'ing the `gh` CLI.** `event=APPROVE` doesn't require a body. `event=REQUEST_CHANGES` \" +\n \"requires a body. Line-level inline review comments aren't supported by this tool yet — use the \" +\n \"GitHub UI for those.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n number: z.number().int().positive(),\n event: z.enum([\"APPROVE\", \"REQUEST_CHANGES\", \"COMMENT\"]),\n body: z.string().optional().describe(\"Review summary (Markdown). Required for REQUEST_CHANGES.\"),\n commit_id: z.string().optional().describe(\"Pin the review to a specific commit SHA.\"),\n }),\n },\n);\n\n// ── Pull-request read (cont'd) ─────────────────────────────────────────────\n\nexport const githubListPullFilesTool = tool(\n async ({ owner, repo, number, max_results }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const limit = Math.min(max_results ?? 30, 100);\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls/${number}/files?per_page=${limit}`,\n ) as Array<Record<string, unknown>> | { error?: string };\n if (!Array.isArray(data)) return JSON.stringify(data);\n return JSON.stringify({\n files: data.map((f) => {\n const patch = typeof f.patch === \"string\" ? truncate(f.patch, PATCH_CAP) : null;\n return {\n filename: f.filename,\n status: f.status, // added | modified | removed | renamed | …\n additions: f.additions,\n deletions: f.deletions,\n changes: f.changes,\n previous_filename: f.previous_filename,\n sha: f.sha,\n patch: patch?.text,\n patch_truncated: patch?.truncated ?? false,\n };\n }),\n });\n },\n {\n name: \"github_list_pull_files\",\n description:\n \"List files changed in a pull request, with per-file additions/deletions and (capped) patch text. \" +\n \"**PREFER THIS over shell-exec'ing the `gh` CLI.** Each patch caps at 8 KB; `patch_truncated: true` \" +\n \"means the diff was longer than that. GitHub itself caps the response at 3000 files.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n number: z.number().int().positive(),\n max_results: z.number().optional().describe(\"Max files (default 30, max 100)\"),\n }),\n },\n);\n\nexport const githubListPullReviewsTool = tool(\n async ({ owner, repo, number, max_results }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const limit = Math.min(max_results ?? 30, 100);\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls/${number}/reviews?per_page=${limit}`,\n ) as Array<Record<string, unknown>> | { error?: string };\n if (!Array.isArray(data)) return JSON.stringify(data);\n return JSON.stringify({\n reviews: data.map((r) => {\n const cap = truncate(typeof r.body === \"string\" ? r.body : \"\", COMMENT_CAP);\n return {\n id: r.id,\n user: liteUser(r.user),\n state: r.state, // APPROVED | CHANGES_REQUESTED | COMMENTED | DISMISSED | PENDING\n submitted_at: r.submitted_at,\n commit_id: r.commit_id,\n url: r.html_url,\n body: cap.text,\n truncated: cap.truncated,\n };\n }),\n });\n },\n {\n name: \"github_list_pull_reviews\",\n description:\n \"List reviews submitted on a pull request (approvals, change-requests, comment-only). **PREFER THIS \" +\n \"over shell-exec'ing the `gh` CLI.** Use this to check whether a PR is approved before calling \" +\n \"github_merge_pull.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n number: z.number().int().positive(),\n max_results: z.number().optional().describe(\"Max reviews (default 30, max 100)\"),\n }),\n },\n);\n\n// ── Repo content ───────────────────────────────────────────────────────────\n\nexport const githubListBranchesTool = tool(\n async ({ owner, repo, max_results }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const limit = Math.min(max_results ?? 30, 100);\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/branches?per_page=${limit}`,\n ) as Array<Record<string, unknown>> | { error?: string };\n if (!Array.isArray(data)) return JSON.stringify(data);\n return JSON.stringify({\n branches: data.map((b) => ({\n name: b.name,\n commit_sha: (b.commit as { sha?: string } | null)?.sha ?? null,\n protected: b.protected,\n })),\n });\n },\n {\n name: \"github_list_branches\",\n description:\n \"List branches in a repository with their head SHAs and protection state. **PREFER THIS over \" +\n \"shell-exec'ing the `gh` CLI.** Useful before opening a PR (confirm the head branch exists \" +\n \"and is the SHA you expect).\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n max_results: z.number().optional().describe(\"Max branches (default 30, max 100)\"),\n }),\n },\n);\n\nexport const githubGetFileTool = tool(\n async ({ owner, repo, path, ref }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const url = `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/contents/${path\n .split(\"/\").map(encodeURIComponent).join(\"/\")}` + (ref ? `?ref=${encodeURIComponent(ref)}` : \"\");\n const data = await ghFetch(auth, url) as Record<string, unknown> | Array<unknown> | { error?: string };\n if (!Array.isArray(data) && (data as { error?: string }).error) {\n return JSON.stringify(data);\n }\n if (Array.isArray(data) || (data as { type?: string }).type === \"dir\") {\n return JSON.stringify({\n error: `'${path}' is a directory; this tool only reads single files. Pass a path to a file.`,\n });\n }\n const f = data as { type?: string; encoding?: string; content?: string; sha?: string;\n size?: number; html_url?: string; path?: string };\n if (f.type !== \"file\") {\n return JSON.stringify({ error: `unsupported content type '${f.type ?? \"?\"}' at ${path}` });\n }\n const decoded = decodeContentsBlob(f.content ?? \"\", f.encoding);\n if (decoded.binary) {\n return JSON.stringify({\n path: f.path, sha: f.sha, url: f.html_url,\n binary: true, size_bytes: decoded.size_bytes,\n });\n }\n const cap = truncate(decoded.text ?? \"\", BODY_CAP);\n return JSON.stringify({\n path: f.path, sha: f.sha, url: f.html_url,\n binary: false, size_bytes: decoded.size_bytes,\n content: cap.text, truncated: cap.truncated,\n });\n },\n {\n name: \"github_get_file\",\n description:\n \"Read a file's contents from a repo at an optional ref (branch / tag / commit SHA). **PREFER THIS \" +\n \"over shell-exec'ing the `gh` CLI.** Returns up to 20 KB of UTF-8 text; longer files are truncated \" +\n \"with `truncated: true`. Binary files return `binary: true` and `size_bytes` instead of `content`. \" +\n \"GitHub itself rejects files larger than ~1 MB on this endpoint.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n path: z.string().describe(\"Path within the repo (e.g. 'src/lib/index.ts'). Slashes preserved.\"),\n ref: z.string().optional().describe(\"Branch, tag, or commit SHA. Default: repo's default branch.\"),\n }),\n },\n);\n\nexport const githubSearchCodeTool = tool(\n async ({ q, repo, max_results }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const limit = Math.min(max_results ?? 25, 100);\n const query = repo ? `repo:${repo} ${q}` : q;\n const data = await ghFetch(\n auth,\n `/search/code?q=${encodeURIComponent(query)}&per_page=${limit}`,\n { headers: { Accept: \"application/vnd.github.text-match+json\" } },\n ) as {\n items?: Array<{\n name?: string; path?: string; sha?: string; html_url?: string;\n repository?: { full_name?: string };\n text_matches?: Array<{ fragment?: string }>;\n }>;\n total_count?: number;\n error?: string;\n };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n total: data.total_count ?? 0,\n items: (data.items ?? []).map((i) => {\n const fragment = i.text_matches?.[0]?.fragment ?? \"\";\n const snip = truncate(fragment, SNIPPET_CAP);\n return {\n name: i.name,\n path: i.path,\n repo: i.repository?.full_name,\n url: i.html_url,\n sha: i.sha,\n snippet: snip.text,\n snippet_truncated: snip.truncated,\n };\n }),\n });\n },\n {\n name: \"github_search_code\",\n description:\n \"Search file contents across GitHub. **PREFER THIS over shell-exec'ing the `gh` CLI.** Pass `repo` \" +\n \"(\\\"owner/name\\\") to scope to one repo; the tool prepends `repo:owner/name `. The `q` body accepts \" +\n \"GitHub's full code-search syntax: 'language:ts symbolName', 'extension:py path:tests assert', etc. \" +\n \"Each hit returns a 400-char snippet around the match. Note: GitHub code search has stricter rate \" +\n \"limits than other endpoints (10/min for unauthenticated, 30/min for authenticated).\",\n schema: z.object({\n q: z.string().describe(\"Code search query (e.g. 'language:ts isLikelyBinary')\"),\n repo: z.string().optional().describe(\"Optional 'owner/name' shortcut; prepended as repo: filter\"),\n max_results: z.number().optional().describe(\"Max items (default 25, max 100)\"),\n }),\n },\n);\n\nregisterTools(\"GitHub\", \"read\", [\n // Issues — read\n githubSearchIssuesTool, githubGetIssueTool, githubListIssueCommentsTool,\n // Pull requests — read\n githubListPullsTool, githubGetPullTool,\n githubListPullFilesTool, githubListPullReviewsTool,\n // Repo content\n githubGetRepoTool, githubListBranchesTool, githubGetFileTool, githubSearchCodeTool,\n]);\nregisterTools(\"GitHub\", \"execute\", [\n // Issues — write/execute\n githubCreateIssueTool, githubUpdateIssueTool, githubAddCommentTool,\n // Pull requests — write/execute\n githubCreatePullTool, githubUpdatePullTool, githubMergePullTool,\n githubRequestReviewersTool, githubCreateReviewTool,\n]);\n","// Plain-text chunker for document RAG (ADR-0024).\n//\n// Strategy:\n// 1. Split on blank-line paragraph boundaries.\n// 2. Greedily pack paragraphs into chunks up to ~MAX_CHARS.\n// 3. Overlap: prepend the trailing portion of the previous chunk to each\n// new chunk so cross-chunk context survives splits (helps recall when\n// a question spans a paragraph boundary).\n//\n// Char count is used as a token proxy — 1 token ≈ 4 chars for English.\n// MAX_CHARS = 3200 ≈ 800 tokens, well under any embedding-model limit.\n\nconst MAX_CHARS = 3200;\nconst OVERLAP_CHARS = 400;\n\nexport interface Chunk {\n text: string;\n start_offset: number; // byte offset (utf-8) into original text\n end_offset: number;\n}\n\nexport function chunkText(text: string): Chunk[] {\n if (!text || text.length === 0) return [];\n\n // Split on one-or-more blank lines. Keep paragraphs with their separator\n // so offsets stay accurate.\n const paragraphs: { text: string; start: number; end: number }[] = [];\n let cursor = 0;\n const re = /\\n\\s*\\n/g;\n let m: RegExpExecArray | null;\n while ((m = re.exec(text)) !== null) {\n const start = cursor;\n const end = m.index;\n paragraphs.push({ text: text.slice(start, end), start, end });\n cursor = re.lastIndex;\n }\n if (cursor < text.length) {\n paragraphs.push({ text: text.slice(cursor), start: cursor, end: text.length });\n }\n\n const chunks: Chunk[] = [];\n let buf: { text: string; start: number; end: number } | null = null;\n\n for (const p of paragraphs) {\n if (!buf) {\n buf = { text: p.text, start: p.start, end: p.end };\n continue;\n }\n if (buf.text.length + 2 + p.text.length <= MAX_CHARS) {\n buf.text = `${buf.text}\\n\\n${p.text}`;\n buf.end = p.end;\n } else {\n chunks.push({ text: buf.text, start_offset: buf.start, end_offset: buf.end });\n // Overlap: take the tail of the previous chunk.\n const tail = buf.text.slice(Math.max(0, buf.text.length - OVERLAP_CHARS));\n buf = {\n text: `${tail}\\n\\n${p.text}`,\n // Anchor the new chunk's start_offset at the paragraph that's\n // logically new — the overlap tail is prepended for context only.\n start: p.start,\n end: p.end,\n };\n }\n }\n if (buf) {\n chunks.push({ text: buf.text, start_offset: buf.start, end_offset: buf.end });\n }\n\n // If a single paragraph is bigger than MAX_CHARS, the above will emit it\n // as one over-sized chunk. Split it on character boundaries as a last\n // resort so we don't exceed the embedding model's input limit.\n const out: Chunk[] = [];\n for (const c of chunks) {\n if (c.text.length <= MAX_CHARS) {\n out.push(c);\n continue;\n }\n let pos = 0;\n while (pos < c.text.length) {\n const end = Math.min(pos + MAX_CHARS, c.text.length);\n out.push({\n text: c.text.slice(pos, end),\n start_offset: c.start_offset + pos,\n end_offset: c.start_offset + end,\n });\n pos = end - OVERLAP_CHARS;\n if (pos < 0) pos = 0;\n if (end === c.text.length) break;\n }\n }\n return out;\n}\n","// Filesystem walker + indexer for document RAG (ADR-0024).\n//\n// Walks each enabled document_source, identifies text files whose\n// mtime/size differs from the indexed copy, re-chunks + re-embeds them.\n// Files removed on disk are evicted (chunks + document row).\n//\n// Defaults are conservative on purpose: extension allowlist, size cap,\n// directory denylist for VCS / build output. Binary files are skipped via\n// a fast non-printable-byte heuristic on the first 4 KB.\n\nimport { randomUUID, createHash } from \"node:crypto\";\nimport { promises as fs } from \"node:fs\";\nimport { join, relative, sep } from \"node:path\";\nimport { getDb } from \"@/lib/db\";\nimport { embedBestEffort } from \"@/lib/embeddings\";\nimport {\n listEnabledDocumentSources,\n markSourceScanned,\n type DocumentSourceRow,\n} from \"@/lib/stores/document-sources\";\nimport { chunkText } from \"./chunker\";\nimport { isRemoteKind, runRemoteSource, type RemoteIndexStats } from \"./remote\";\n\n// Conservative defaults; v1 is not configurable per source. ADR-0024\n// documents the rationale and the path to opening these up.\nconst ALLOWED_EXT = new Set([\n \".md\", \".markdown\", \".txt\", \".rst\", \".log\",\n \".json\", \".jsonc\", \".yaml\", \".yml\", \".toml\", \".ini\", \".cfg\", \".env\",\n \".ts\", \".tsx\", \".js\", \".jsx\", \".mjs\", \".cjs\",\n \".py\", \".rs\", \".go\", \".java\", \".kt\", \".scala\", \".swift\",\n \".c\", \".cpp\", \".cc\", \".h\", \".hpp\",\n \".cs\", \".rb\", \".php\", \".lua\", \".pl\", \".r\",\n \".sh\", \".bash\", \".zsh\", \".ps1\", \".bat\",\n \".html\", \".htm\", \".css\", \".scss\", \".sass\", \".vue\", \".svelte\",\n \".sql\", \".graphql\", \".proto\",\n \".csv\", \".tsv\",\n]);\nconst SKIP_DIRS = new Set([\n \"node_modules\", \".git\", \".hg\", \".svn\", \".next\", \".turbo\", \".cache\",\n \"dist\", \"build\", \"out\", \"target\", \".venv\", \"venv\", \"env\",\n \"__pycache__\", \".pytest_cache\", \".mypy_cache\",\n \".idea\", \".vscode\", \".vs\",\n \"coverage\", \".nyc_output\",\n]);\nconst MAX_FILE_BYTES = 2 * 1024 * 1024; // 2 MB — bigger files almost always\n // belong in proper RAG, not ad-hoc.\nconst MAX_FILES_PER_SOURCE = 5000;\n// Per-call cap so a freshly-added source with thousands of files doesn't\n// block the scheduler tick for minutes. Subsequent ticks pick up the rest.\nconst MAX_INDEX_PER_TICK_PER_SOURCE = 50;\n\nexport { ALLOWED_EXT, SKIP_DIRS, MAX_FILE_BYTES };\n\nexport function lowerExt(name: string): string {\n const i = name.lastIndexOf(\".\");\n return i < 0 ? \"\" : name.slice(i).toLowerCase();\n}\n\nexport function isLikelyBinary(buf: Buffer): boolean {\n const len = Math.min(buf.length, 4096);\n if (len === 0) return false;\n let suspicious = 0;\n for (let i = 0; i < len; i++) {\n const b = buf[i];\n // NUL byte = almost certainly binary.\n if (b === 0) return true;\n // Outside printable ASCII + common whitespace and not high-bit UTF-8.\n if (b < 0x09 || (b > 0x0d && b < 0x20)) suspicious++;\n }\n return suspicious / len > 0.05;\n}\n\nexport interface FileEntry {\n abs: string;\n rel: string;\n mtime_ms: number;\n size: number;\n}\n\nasync function walk(root: string): Promise<FileEntry[]> {\n const out: FileEntry[] = [];\n // Cloud-synced filesystems (OneDrive's macOS file provider in\n // particular) can re-emit the same entry from readdir during sync\n // transitions, sometimes with a different Unicode normalization\n // (NFC vs NFD). Without dedupe, the second visit would attempt a\n // second INSERT for the same (source_id, path) and trip the UNIQUE\n // constraint on `documents`.\n const seen = new Set<string>();\n async function visit(dir: string): Promise<void> {\n if (out.length >= MAX_FILES_PER_SOURCE) return;\n let entries: import(\"node:fs\").Dirent[];\n try {\n entries = await fs.readdir(dir, { withFileTypes: true });\n } catch {\n return;\n }\n for (const e of entries) {\n if (out.length >= MAX_FILES_PER_SOURCE) return;\n if (e.name.startsWith(\".\")) {\n // Hide dot-dirs by default. Users who want them indexed should\n // pick a more specific subdirectory as the source.\n if (e.isDirectory()) continue;\n // Keep dot-files like .env, .gitignore as text candidates.\n }\n const abs = join(dir, e.name);\n if (e.isDirectory()) {\n if (SKIP_DIRS.has(e.name)) continue;\n if (seen.has(abs)) continue;\n seen.add(abs);\n await visit(abs);\n } else if (e.isFile()) {\n const ext = lowerExt(e.name);\n if (!ALLOWED_EXT.has(ext)) continue;\n if (seen.has(abs)) continue;\n seen.add(abs);\n let st;\n try { st = await fs.stat(abs); } catch { continue; }\n if (st.size > MAX_FILE_BYTES) continue;\n out.push({\n abs,\n rel: relative(root, abs).split(sep).join(\"/\"),\n mtime_ms: Math.floor(st.mtimeMs),\n size: st.size,\n });\n }\n }\n }\n await visit(root);\n return out;\n}\n\ninterface IndexedDocRow {\n id: string;\n path: string;\n mtime_ms: number;\n size_bytes: number;\n content_hash: string;\n}\n\nfunction listIndexedDocs(sourceId: string): Map<string, IndexedDocRow> {\n const rows = getDb()\n .prepare(\"SELECT id, path, mtime_ms, size_bytes, content_hash FROM documents WHERE source_id=?\")\n .all(sourceId) as unknown as IndexedDocRow[];\n const map = new Map<string, IndexedDocRow>();\n for (const r of rows) map.set(r.path, r);\n return map;\n}\n\ninterface UnembeddedChunkRow {\n id: string;\n text: string;\n}\n\nfunction listUnembeddedChunks(documentId: string): UnembeddedChunkRow[] {\n return getDb()\n .prepare(\n `SELECT id, text\n FROM document_chunks\n WHERE document_id=? AND embedding IS NULL\n ORDER BY chunk_index ASC`,\n )\n .all(documentId) as unknown as UnembeddedChunkRow[];\n}\n\nasync function backfillDocumentEmbeddings(documentId: string): Promise<{ missing: number; embedded: number; embedError: string | null }> {\n const rows = listUnembeddedChunks(documentId);\n if (rows.length === 0) return { missing: 0, embedded: 0, embedError: null };\n\n const { vectors, error } = await embedBestEffort(rows.map((r) => r.text));\n const updateEmb = getDb().prepare(\"UPDATE document_chunks SET embedding=? WHERE id=?\");\n let embedded = 0;\n for (let i = 0; i < rows.length; i++) {\n const v = vectors[i];\n if (v == null) continue;\n updateEmb.run(JSON.stringify(v), rows[i].id);\n embedded++;\n }\n return { missing: rows.length, embedded, embedError: error };\n}\n\nexport async function readTextFile(abs: string): Promise<string | null> {\n let buf: Buffer;\n try { buf = await fs.readFile(abs); } catch { return null; }\n if (isLikelyBinary(buf)) return null;\n return buf.toString(\"utf8\");\n}\n\nexport function hashContent(text: string): string {\n return createHash(\"sha256\").update(text).digest(\"hex\");\n}\n\ninterface IndexStats {\n scanned: number;\n added: number;\n updated: number;\n removed: number;\n unchanged: number;\n errors: number;\n embed_failed?: number;\n embed_error?: string | null;\n}\n\nexport async function indexSource(\n source: DocumentSourceRow,\n opts?: { maxFiles?: number },\n): Promise<IndexStats> {\n const stats: IndexStats = { scanned: 0, added: 0, updated: 0, removed: 0, unchanged: 0, errors: 0 };\n const db = getDb();\n let lastError: string | null = null;\n let embedFailed = 0;\n let embedError: string | null = null;\n\n // Resolve real files on disk.\n const files = await walk(source.path);\n stats.scanned = files.length;\n\n const indexed = listIndexedDocs(source.id);\n const onDisk = new Set<string>(files.map((f) => f.abs));\n\n // Drop entries whose file is gone.\n for (const [path, row] of indexed.entries()) {\n if (!onDisk.has(path)) {\n db.prepare(\"DELETE FROM documents WHERE id=?\").run(row.id);\n stats.removed++;\n }\n }\n\n // Index new + changed files.\n const maxThisRun = opts?.maxFiles ?? MAX_INDEX_PER_TICK_PER_SOURCE;\n let processed = 0;\n for (const f of files) {\n if (processed >= maxThisRun) break;\n const existing = indexed.get(f.abs);\n if (existing && existing.mtime_ms === f.mtime_ms && existing.size_bytes === f.size) {\n // Root-cause fix: if a file was indexed while embeddings were\n // unavailable, unchanged files used to be skipped forever and never\n // backfilled. Try to embed any still-null chunks on unchanged docs.\n try {\n const r = await backfillDocumentEmbeddings(existing.id);\n if (r.missing > 0) {\n embedFailed += Math.max(r.missing - r.embedded, 0);\n if (r.embedError && !embedError) embedError = r.embedError;\n processed++;\n }\n } catch (err) {\n lastError = err instanceof Error ? err.message : String(err);\n stats.errors++;\n }\n stats.unchanged++;\n continue;\n }\n\n let text: string | null;\n try { text = await readTextFile(f.abs); } catch {\n stats.errors++;\n continue;\n }\n if (text === null) continue; // binary / unreadable — skip silently.\n\n const hash = hashContent(text);\n if (existing && existing.content_hash === hash) {\n // Mtime/size changed but content didn't — just touch the row.\n db.prepare(\"UPDATE documents SET mtime_ms=?, size_bytes=?, last_indexed_at=? WHERE id=?\")\n .run(f.mtime_ms, f.size, new Date().toISOString(), existing.id);\n try {\n const r = await backfillDocumentEmbeddings(existing.id);\n if (r.missing > 0) {\n embedFailed += Math.max(r.missing - r.embedded, 0);\n if (r.embedError && !embedError) embedError = r.embedError;\n processed++;\n }\n } catch (err) {\n lastError = err instanceof Error ? err.message : String(err);\n stats.errors++;\n }\n stats.unchanged++;\n continue;\n }\n\n try {\n const r = await upsertLocalDocument(source.id, f, text, hash, existing?.id);\n embedFailed += r.chunks - r.embedded;\n if (r.embedError && !embedError) embedError = r.embedError;\n processed++;\n if (existing) stats.updated++;\n else stats.added++;\n } catch (err) {\n lastError = err instanceof Error ? err.message : String(err);\n stats.errors++;\n }\n }\n\n // Embed failures are not fetch failures — but if everything else\n // succeeded we still want them visible on the row, so the operator\n // doesn't have to grep server logs to discover that semantic search\n // is degraded for this source.\n const composite = lastError\n ? lastError\n : embedFailed > 0\n ? `${embedFailed} chunk${embedFailed === 1 ? \"\" : \"s\"} failed to embed${embedError ? \": \" + embedError : \"\"}`\n : null;\n if (embedFailed > 0) {\n stats.embed_failed = embedFailed;\n stats.embed_error = embedError;\n }\n markSourceScanned(source.id, composite);\n return stats;\n}\n\n/**\n * Upsert one local document row (and its chunks). Exported so\n * single-file watcher firings can reuse it without going through\n * a full source sweep.\n */\nexport async function upsertLocalDocument(\n sourceId: string,\n f: FileEntry,\n text: string,\n hash: string,\n existingId: string | undefined,\n): Promise<{ chunks: number; embedded: number; embedError: string | null }> {\n const db = getDb();\n const t = new Date().toISOString();\n const docId = existingId ?? randomUUID();\n\n // Two writers can race on (source_id, path): the full sweep in\n // indexSource() loads listIndexedDocs() once and iterates, while\n // fs-watch firings call reindexLocalFile() per file. If a watcher\n // event lands mid-sweep, both paths can see \"no existing row\" and\n // both try to INSERT, tripping UNIQUE(source_id, path)\n // (lib/db/migrations.ts). REPLACE INTO is unsafe: document_chunks\n // has ON DELETE CASCADE on documents.id, so REPLACE would nuke every\n // chunk on each call. Use ON CONFLICT DO NOTHING, and if we lost the\n // race, adopt the winner's id and overwrite via UPDATE so the latest\n // content still wins.\n let writeId = docId;\n if (existingId) {\n db.prepare(\n `UPDATE documents\n SET path=?, rel_path=?, mtime_ms=?, size_bytes=?, content_hash=?, last_indexed_at=?\n WHERE id=?`,\n ).run(f.abs, f.rel, f.mtime_ms, f.size, hash, t, existingId);\n db.prepare(\"DELETE FROM document_chunks WHERE document_id=?\").run(existingId);\n writeId = existingId;\n } else {\n const info = db.prepare(\n `INSERT INTO documents\n (id, source_id, path, rel_path, mtime_ms, size_bytes, content_hash, last_indexed_at, chunk_count)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, 0)\n ON CONFLICT(source_id, path) DO NOTHING`,\n ).run(docId, sourceId, f.abs, f.rel, f.mtime_ms, f.size, hash, t);\n if (info.changes === 0) {\n const winner = db\n .prepare(\"SELECT id FROM documents WHERE source_id=? AND path=?\")\n .get(sourceId, f.abs) as { id: string } | undefined;\n if (winner) {\n db.prepare(\n `UPDATE documents\n SET rel_path=?, mtime_ms=?, size_bytes=?, content_hash=?, last_indexed_at=?\n WHERE id=?`,\n ).run(f.rel, f.mtime_ms, f.size, hash, t, winner.id);\n db.prepare(\"DELETE FROM document_chunks WHERE document_id=?\").run(winner.id);\n writeId = winner.id;\n }\n }\n }\n\n return chunkAndEmbedDocument(writeId, text, f.rel);\n}\n\n/**\n * Chunk a document's text, persist the chunks, and best-effort embed\n * them. Shared between the local sweep, single-file watcher firings,\n * and remote-source upserts. Returns counts so the caller can aggregate\n * embed failures up to the source row instead of swallowing them.\n */\nexport async function chunkAndEmbedDocument(\n documentId: string,\n text: string,\n _label: string,\n): Promise<{ chunks: number; embedded: number; embedError: string | null }> {\n const db = getDb();\n const chunks = chunkText(text);\n if (chunks.length === 0) {\n db.prepare(\"UPDATE documents SET chunk_count=0 WHERE id=?\").run(documentId);\n return { chunks: 0, embedded: 0, embedError: null };\n }\n\n // Insert chunks first without embeddings — recall falls back to\n // substring scan, so they're useful immediately. Then attempt to embed\n // in a single batch; persist whichever vectors came back.\n const insertChunk = db.prepare(\n `INSERT INTO document_chunks\n (id, document_id, chunk_index, text, start_offset, end_offset, embedding)\n VALUES (?, ?, ?, ?, ?, ?, NULL)`,\n );\n const chunkIds: string[] = [];\n for (let i = 0; i < chunks.length; i++) {\n const id = randomUUID();\n chunkIds.push(id);\n insertChunk.run(id, documentId, i, chunks[i].text, chunks[i].start_offset, chunks[i].end_offset);\n }\n db.prepare(\"UPDATE documents SET chunk_count=? WHERE id=?\").run(chunks.length, documentId);\n\n // embedBestEffort handles retry + halving fallback internally so a\n // single bad input or transient 429 doesn't drop the whole document.\n const { vectors, error } = await embedBestEffort(chunks.map((c) => c.text));\n const updateEmb = db.prepare(\"UPDATE document_chunks SET embedding=? WHERE id=?\");\n let embedded = 0;\n for (let i = 0; i < vectors.length; i++) {\n if (vectors[i] != null) {\n updateEmb.run(JSON.stringify(vectors[i]), chunkIds[i]);\n embedded++;\n }\n }\n return { chunks: chunks.length, embedded, embedError: error };\n}\n\nexport async function indexAllSources(opts?: { maxFilesPerSource?: number }): Promise<{\n source_id: string;\n path: string;\n stats: IndexStats | RemoteIndexStats;\n}[]> {\n const sources = listEnabledDocumentSources();\n const out: { source_id: string; path: string; stats: IndexStats | RemoteIndexStats }[] = [];\n for (const s of sources) {\n try {\n if (isRemoteKind(s.kind)) {\n // Delegate to the per-kind remote handler (ADR-0026). Remote\n // sources don't have an mtime stat — they have their own\n // incremental cursor stored in document_sources.last_cursor.\n const stats = await runRemoteSource(s);\n out.push({ source_id: s.id, path: s.path, stats });\n continue;\n }\n const stats = await indexSource(s, { maxFiles: opts?.maxFilesPerSource });\n out.push({ source_id: s.id, path: s.path, stats });\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n markSourceScanned(s.id, msg);\n console.error(\"[documents] index failed for\", s.path, msg);\n }\n }\n return out;\n}\n","// Cheap HTML → plain text. Not a parser — regex-only, deterministic, no deps.\n//\n// Two modes:\n// - default (preserveParagraphs: false): collapses ALL whitespace to single\n// spaces. Right for web-page summarization where the agent wants prose.\n// - preserveParagraphs: true: keeps newline structure (br → \\n, /p → \\n\\n)\n// and only collapses runs of spaces/tabs. Right for email bodies where the\n// agent benefits from paragraph breaks.\nexport function stripHtml(html: string, opts?: { preserveParagraphs?: boolean }): string {\n let s = html\n .replace(/<style[\\s\\S]*?<\\/style>/gi, \" \")\n .replace(/<script[\\s\\S]*?<\\/script>/gi, \" \")\n .replace(/<noscript[\\s\\S]*?<\\/noscript>/gi, \" \")\n .replace(/<!--[\\s\\S]*?-->/g, \" \");\n\n if (opts?.preserveParagraphs) {\n s = s\n .replace(/<br\\s*\\/?>/gi, \"\\n\")\n .replace(/<\\/p>/gi, \"\\n\\n\");\n // Strip remaining tags with empty (so the br/p newlines we just injected\n // aren't surrounded by stray spaces from the opening tags).\n s = s.replace(/<\\/?[^>]+>/g, \"\");\n } else {\n // Default mode: replace tags with spaces so adjacent words don't merge.\n s = s.replace(/<\\/?[^>]+>/g, \" \");\n }\n\n s = decodeHtmlEntities(s);\n\n s = opts?.preserveParagraphs\n ? s.replace(/[ \\t]+/g, \" \").replace(/\\n{3,}/g, \"\\n\\n\")\n : s.replace(/\\s+/g, \" \");\n\n return s.trim();\n}\n\nexport function decodeHtmlEntities(s: string): string {\n return s\n .replace(/ /g, \" \")\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\");\n}\n","// Ephemeral state store for the in-app Gmail OAuth flow.\n//\n// The user types client_id + client_secret in the Integrations panel and clicks\n// \"Connect Gmail\". We POST those to /oauth/start, which stashes them here keyed\n// by a random `state` token and returns the Google authorize URL. The browser\n// opens that URL; Google bounces back to /oauth/callback with `?code&state`,\n// which exchanges the code for a refresh_token and persists the integration.\n// Meanwhile the panel polls /oauth/status to know when to refresh.\n//\n// Pinned to globalThis so HMR in dev doesn't lose pending flows.\n\nimport { getIntegrationRaw } from \"@/lib/stores/integrations\";\nimport { createOAuthFlowStore, type OAuthFlow } from \"@/lib/utils/oauth-flow-store\";\nimport { parseJsonSafe } from \"@/lib/utils/json\";\n\nexport type { OAuthFlow };\n\nconst flowStore = createOAuthFlowStore({ globalKey: \"__ggOauthFlows\" });\n\nexport const createFlow = flowStore.create;\nexport const getFlow = flowStore.get;\nexport const updateFlow = flowStore.update;\nexport const deleteFlow = flowStore.delete;\n\nexport const GMAIL_SCOPES = [\n \"https://www.googleapis.com/auth/gmail.modify\",\n \"https://www.googleapis.com/auth/gmail.compose\",\n // Calendar: read/write events on the user's existing calendars. Narrow\n // scope on purpose — doesn't grant create/delete of entire calendars\n // (matches the principle-of-least-privilege the Gmail scopes follow).\n \"https://www.googleapis.com/auth/calendar.events\",\n // Read-only metadata of the user's calendar list. Required for the\n // calendarList.list endpoint that powers calendarListCalendarsTool —\n // calendar.events alone returns 403 there.\n \"https://www.googleapis.com/auth/calendar.readonly\",\n];\n\nexport function buildAuthorizeUrl(opts: {\n clientId: string;\n redirectUri: string;\n state: string;\n}): string {\n const p = new URLSearchParams({\n client_id: opts.clientId,\n redirect_uri: opts.redirectUri,\n response_type: \"code\",\n scope: GMAIL_SCOPES.join(\" \"),\n access_type: \"offline\",\n prompt: \"consent\",\n include_granted_scopes: \"true\",\n state: opts.state,\n });\n return `https://accounts.google.com/o/oauth2/v2/auth?${p.toString()}`;\n}\n\nexport async function exchangeCode(opts: {\n code: string;\n clientId: string;\n clientSecret: string;\n redirectUri: string;\n}): Promise<{ refresh_token?: string; access_token?: string; expires_in?: number; scope?: string }> {\n const body = new URLSearchParams({\n code: opts.code,\n client_id: opts.clientId,\n client_secret: opts.clientSecret,\n redirect_uri: opts.redirectUri,\n grant_type: \"authorization_code\",\n });\n const res = await fetch(\"https://oauth2.googleapis.com/token\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: body.toString(),\n signal: AbortSignal.timeout(30_000),\n });\n const text = await res.text();\n const parsed = parseJsonSafe<Record<string, unknown>>(text, {});\n if (!res.ok) {\n const err = (parsed[\"error_description\"] || parsed[\"error\"] || text || `HTTP ${res.status}`) as string;\n throw new Error(err);\n }\n return parsed as { refresh_token?: string; access_token?: string; expires_in?: number; scope?: string };\n}\n\n// ---------------------------------------------------------------------------\n// Shared Google API auth (Gmail + Calendar + any future Google scope)\n// ---------------------------------------------------------------------------\n//\n// The same OAuth client (stored under integration name \"gmail\" for back-compat)\n// grants every Google scope we ask for. Tools across `lib/tools/` share these\n// helpers so a burst of mixed Gmail+Calendar calls hits Google's token\n// endpoint once per refresh, not once per file.\n\nexport interface GoogleAuth {\n client_id: string;\n client_secret: string;\n refresh_token: string;\n}\n\nexport function resolveGoogleAuth(): GoogleAuth | { error: string } {\n const envId = process.env.GMAIL_CLIENT_ID;\n const envSecret = process.env.GMAIL_CLIENT_SECRET;\n const envRefresh = process.env.GMAIL_REFRESH_TOKEN;\n if (envId && envSecret && envRefresh) {\n return { client_id: envId, client_secret: envSecret, refresh_token: envRefresh };\n }\n const saved = getIntegrationRaw(\"gmail\");\n if (saved?.client_id && saved.client_secret && saved.refresh_token) {\n return {\n client_id: saved.client_id,\n client_secret: saved.client_secret,\n refresh_token: saved.refresh_token,\n };\n }\n return {\n error:\n \"Google account not connected. Open the gear menu → Integrations tab → \" +\n \"Gmail card and click Connect Gmail to authorize Gmail + Calendar access.\",\n };\n}\n\ninterface CachedAccessToken { token: string; expires_at: number }\nconst accessTokenCache = new Map<string, CachedAccessToken>();\n\nexport async function getGoogleAccessToken(\n auth: GoogleAuth,\n): Promise<string | { error: string }> {\n const key = auth.refresh_token.slice(0, 20);\n const cached = accessTokenCache.get(key);\n if (cached && cached.expires_at > Date.now() + 60_000) return cached.token;\n\n const body = new URLSearchParams({\n client_id: auth.client_id,\n client_secret: auth.client_secret,\n refresh_token: auth.refresh_token,\n grant_type: \"refresh_token\",\n });\n try {\n const res = await fetch(\"https://oauth2.googleapis.com/token\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: body.toString(),\n signal: AbortSignal.timeout(30_000),\n });\n const text = await res.text();\n if (!res.ok) {\n // Drop any stale cached token so a reconnected (broader-scope) refresh\n // re-exchanges cleanly on the next call.\n accessTokenCache.delete(key);\n return { error: `OAuth token refresh failed (${res.status}): ${text.slice(0, 300)}` };\n }\n const parsed = JSON.parse(text) as { access_token?: string; expires_in?: number };\n if (!parsed.access_token) return { error: \"OAuth response missing access_token\" };\n const expires_at = Date.now() + (parsed.expires_in ?? 3000) * 1000;\n accessTokenCache.set(key, { token: parsed.access_token, expires_at });\n return parsed.access_token;\n } catch (err) {\n return { error: `OAuth token refresh threw: ${err instanceof Error ? err.message : String(err)}` };\n }\n}\n\n/**\n * Shared bearer-auth fetch for Google REST APIs (Gmail, Calendar, ...).\n *\n * Behaviour:\n * - Resolves access token from `auth`; if that fails, the error object is\n * surfaced unchanged so callers can pass it back to the agent.\n * - 204 No Content → `{ ok: true }` (used by DELETE endpoints).\n * - Non-2xx response → `{ error: \"<service> <status>: <body slice>\", url }`.\n * - 2xx with body → parsed JSON if possible, raw text otherwise.\n * - Fetch throws (DNS, abort, timeout) → `{ error: \"<service> fetch threw: ...\" }`.\n *\n * @param service Short tag used in error messages, e.g. \"Gmail\" or \"Calendar\".\n * @param baseUrl Base for relative `path` (e.g. `https://gmail.googleapis.com/gmail/v1/users/me`).\n * @param path Either a full URL (starts with `http`) or path appended to baseUrl.\n */\nexport async function googleFetch(\n auth: GoogleAuth,\n service: string,\n baseUrl: string,\n path: string,\n init?: RequestInit,\n): Promise<unknown> {\n const token = await getGoogleAccessToken(auth);\n if (typeof token !== \"string\") return token;\n const url = path.startsWith(\"http\") ? path : `${baseUrl}${path}`;\n try {\n const res = await fetch(url, {\n ...init,\n headers: {\n Authorization: `Bearer ${token}`,\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\",\n ...(init?.headers ?? {}),\n },\n signal: AbortSignal.timeout(30_000),\n });\n if (res.status === 204) return { ok: true };\n const text = await res.text();\n if (!res.ok) {\n return { error: `${service} ${res.status}: ${text.slice(0, 500)}`, url };\n }\n try { return JSON.parse(text); } catch { return text; }\n } catch (err) {\n return { error: `${service} fetch threw: ${err instanceof Error ? err.message : String(err)}` };\n }\n}\n","// Ephemeral state store + shared auth helpers for the in-app Microsoft OAuth\n// flow. Mirrors lib/integrations/gmail-oauth.ts but targets the Microsoft\n// identity platform (v2.0 endpoint, common tenant by default) and Microsoft\n// Graph as the downstream API surface (Outlook Mail + Calendar in v1).\n//\n// The user types client_id + client_secret in the Integrations panel and\n// clicks \"Connect Outlook\". We POST those to /oauth/start, which stashes\n// them here keyed by a random `state` token and returns the Microsoft\n// authorize URL. The browser opens that URL; MS bounces back to\n// /oauth/callback with `?code&state`, which exchanges the code for a\n// refresh_token (granted because we asked for `offline_access`) and\n// persists the integration. The panel polls /oauth/status separately.\n//\n// Pinned to globalThis so HMR in dev doesn't lose pending flows.\n\nimport { getIntegrationRaw } from \"@/lib/stores/integrations\";\nimport { createOAuthFlowStore, type OAuthFlow } from \"@/lib/utils/oauth-flow-store\";\nimport { parseJsonSafe } from \"@/lib/utils/json\";\n\nexport type { OAuthFlow };\n\nconst flowStore = createOAuthFlowStore({ globalKey: \"__msOauthFlows\" });\n\nexport const createFlow = flowStore.create;\nexport const getFlow = flowStore.get;\nexport const updateFlow = flowStore.update;\nexport const deleteFlow = flowStore.delete;\n\n// Tenant selector. `common` accepts both personal Microsoft accounts\n// (@outlook.com, @hotmail.com, @live.com) and work/school M365 accounts.\n// Switch to `consumers` to lock to personal only, or `organizations` for\n// work/school only. We expose this as an env override for power users but\n// don't surface it in the UI yet.\nconst TENANT = process.env.OUTLOOK_TENANT?.trim() || \"common\";\n\n// Delegated Graph scopes the agent needs. Keep narrow:\n// - offline_access → required for a refresh_token (MS counterpart of\n// Google's access_type=offline).\n// - User.Read → used by the test endpoint to call /me.\n// - Mail.ReadWrite → search/read mail, create drafts, mark read,\n// move to folders (incl. DeletedItems). Does NOT\n// grant sending — matches our Gmail \"drafts only\"\n// stance via gmail.compose.\n// - Calendars.ReadWrite → list/get/create/update/delete events on the\n// user's existing calendars.\nexport const MICROSOFT_SCOPES = [\n \"offline_access\",\n \"User.Read\",\n \"Mail.ReadWrite\",\n \"Calendars.ReadWrite\",\n];\n\nexport function buildAuthorizeUrl(opts: {\n clientId: string;\n redirectUri: string;\n state: string;\n}): string {\n const p = new URLSearchParams({\n client_id: opts.clientId,\n redirect_uri: opts.redirectUri,\n response_type: \"code\",\n response_mode: \"query\",\n scope: MICROSOFT_SCOPES.join(\" \"),\n // Force consent so a returning user actually re-grants any newly-added\n // scope (otherwise MS silently reuses the prior grant minus the new bit).\n prompt: \"consent\",\n state: opts.state,\n });\n return `https://login.microsoftonline.com/${TENANT}/oauth2/v2.0/authorize?${p.toString()}`;\n}\n\n// NOTE: Unlike Google, MS v2 endpoint **requires** the `scope` parameter on\n// every grant_type call (both authorization_code and refresh_token). Leaving\n// it out yields `AADSTS900144: The request body must contain the following\n// parameter: 'scope'.`. We always pass the full scope set.\nexport async function exchangeCode(opts: {\n code: string;\n clientId: string;\n clientSecret: string;\n redirectUri: string;\n}): Promise<{ refresh_token?: string; access_token?: string; expires_in?: number; scope?: string }> {\n const body = new URLSearchParams({\n code: opts.code,\n client_id: opts.clientId,\n client_secret: opts.clientSecret,\n redirect_uri: opts.redirectUri,\n grant_type: \"authorization_code\",\n scope: MICROSOFT_SCOPES.join(\" \"),\n });\n const res = await fetch(`https://login.microsoftonline.com/${TENANT}/oauth2/v2.0/token`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: body.toString(),\n signal: AbortSignal.timeout(30_000),\n });\n const text = await res.text();\n const parsed = parseJsonSafe<Record<string, unknown>>(text, {});\n if (!res.ok) {\n const err = (parsed[\"error_description\"] || parsed[\"error\"] || text || `HTTP ${res.status}`) as string;\n throw new Error(err);\n }\n return parsed as { refresh_token?: string; access_token?: string; expires_in?: number; scope?: string };\n}\n\n// ---------------------------------------------------------------------------\n// Shared Microsoft Graph auth (Outlook Mail + Calendar + future Graph scopes)\n// ---------------------------------------------------------------------------\n\nexport interface MicrosoftAuth {\n client_id: string;\n client_secret: string;\n refresh_token: string;\n}\n\nexport function resolveMicrosoftAuth(): MicrosoftAuth | { error: string } {\n const envId = process.env.OUTLOOK_CLIENT_ID;\n const envSecret = process.env.OUTLOOK_CLIENT_SECRET;\n const envRefresh = process.env.OUTLOOK_REFRESH_TOKEN;\n if (envId && envSecret && envRefresh) {\n return { client_id: envId, client_secret: envSecret, refresh_token: envRefresh };\n }\n const saved = getIntegrationRaw(\"outlook\");\n if (saved?.client_id && saved.client_secret && saved.refresh_token) {\n return {\n client_id: saved.client_id,\n client_secret: saved.client_secret,\n refresh_token: saved.refresh_token,\n };\n }\n return {\n error:\n \"Microsoft account not connected. Open the gear menu → Integrations tab → \" +\n \"Outlook card and click Connect Outlook to authorize Mail + Calendar access.\",\n };\n}\n\ninterface CachedAccessToken { token: string; expires_at: number }\nconst accessTokenCache = new Map<string, CachedAccessToken>();\n\nexport async function getMicrosoftAccessToken(\n auth: MicrosoftAuth,\n): Promise<string | { error: string }> {\n const key = auth.refresh_token.slice(0, 20);\n const cached = accessTokenCache.get(key);\n if (cached && cached.expires_at > Date.now() + 60_000) return cached.token;\n\n const body = new URLSearchParams({\n client_id: auth.client_id,\n client_secret: auth.client_secret,\n refresh_token: auth.refresh_token,\n grant_type: \"refresh_token\",\n // Required on the v2 endpoint even for refresh_token grants.\n scope: MICROSOFT_SCOPES.join(\" \"),\n });\n try {\n const res = await fetch(`https://login.microsoftonline.com/${TENANT}/oauth2/v2.0/token`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: body.toString(),\n signal: AbortSignal.timeout(30_000),\n });\n const text = await res.text();\n if (!res.ok) {\n accessTokenCache.delete(key);\n return { error: `Microsoft OAuth refresh failed (${res.status}): ${text.slice(0, 300)}` };\n }\n const parsed = JSON.parse(text) as { access_token?: string; expires_in?: number };\n if (!parsed.access_token) return { error: \"OAuth response missing access_token\" };\n const expires_at = Date.now() + (parsed.expires_in ?? 3000) * 1000;\n accessTokenCache.set(key, { token: parsed.access_token, expires_at });\n return parsed.access_token;\n } catch (err) {\n return { error: `Microsoft OAuth refresh threw: ${err instanceof Error ? err.message : String(err)}` };\n }\n}\n\n// Shared Graph fetch helper. Used by both lib/tools/outlook.ts and\n// lib/tools/outlook-calendar.ts. Returns parsed JSON or { error: string, url? }.\n// 204 No Content (e.g. successful DELETE) returns { ok: true }.\nexport async function graphFetch(\n auth: MicrosoftAuth,\n path: string,\n init?: RequestInit,\n): Promise<unknown> {\n const token = await getMicrosoftAccessToken(auth);\n if (typeof token !== \"string\") return token;\n const url = path.startsWith(\"http\") ? path : `https://graph.microsoft.com/v1.0${path}`;\n try {\n const res = await fetch(url, {\n ...init,\n headers: {\n Authorization: `Bearer ${token}`,\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\",\n ...(init?.headers ?? {}),\n },\n signal: AbortSignal.timeout(30_000),\n });\n if (res.status === 204) return { ok: true };\n const text = await res.text();\n if (!res.ok) {\n return { error: `Graph ${res.status}: ${text.slice(0, 500)}`, url };\n }\n try { return JSON.parse(text); } catch { return text; }\n } catch (err) {\n return { error: `Graph fetch threw: ${err instanceof Error ? err.message : String(err)}` };\n }\n}\n","// CRUD for the `document_sources` table (ADR-0024). A source is a folder\n// the user has asked Jarela to index for semantic search.\n\nimport { randomUUID } from \"node:crypto\";\nimport { getDb } from \"@/lib/db\";\n\n// ADR-0026 — `kind` discriminates local-folder sources from remote ones\n// (Jira projects, Confluence spaces, saved JQL/CQL, on-demand URL). `config`\n// is a JSON-encoded per-kind blob. `last_cursor` is a per-source incremental\n// watermark (used by remote indexers to do incremental syncs).\n// ADR-0029 added `github_pulls` (PRs of one repo) and `github_repo` (text\n// files on one branch of one repo).\nexport type DocumentSourceKind =\n | \"local_folder\"\n | \"confluence_space\"\n | \"confluence_cql\"\n | \"jira_project\"\n | \"jira_jql\"\n | \"github_pulls\"\n | \"github_repo\"\n | \"gmail_mail\"\n | \"outlook_mail\"\n | \"on_demand_url\";\n\nexport interface DocumentSourceRow {\n id: string;\n path: string;\n label: string | null;\n enabled: number;\n last_scan_at: string | null;\n last_error: string | null;\n created_at: string;\n updated_at: string;\n kind: DocumentSourceKind;\n config: string | null; // JSON; null for local_folder\n last_cursor: string | null; // incremental watermark; null for local_folder\n}\n\nconst now = () => new Date().toISOString();\n\nexport function listDocumentSources(): DocumentSourceRow[] {\n return getDb()\n .prepare(\"SELECT * FROM document_sources ORDER BY created_at ASC\")\n .all() as unknown as DocumentSourceRow[];\n}\n\nexport function listEnabledDocumentSources(): DocumentSourceRow[] {\n return getDb()\n .prepare(\"SELECT * FROM document_sources WHERE enabled=1 ORDER BY created_at ASC\")\n .all() as unknown as DocumentSourceRow[];\n}\n\nexport function getDocumentSource(id: string): DocumentSourceRow | null {\n const row = getDb().prepare(\"SELECT * FROM document_sources WHERE id=?\").get(id);\n return (row as DocumentSourceRow | undefined) ?? null;\n}\n\nexport function getDocumentSourceByPath(path: string): DocumentSourceRow | null {\n const row = getDb().prepare(\"SELECT * FROM document_sources WHERE path=?\").get(path);\n return (row as DocumentSourceRow | undefined) ?? null;\n}\n\nexport function createDocumentSource(input: {\n path: string;\n label?: string | null;\n kind?: DocumentSourceKind;\n config?: Record<string, unknown> | null;\n}): DocumentSourceRow {\n const id = randomUUID();\n const t = now();\n const kind = input.kind ?? \"local_folder\";\n const config = input.config ? JSON.stringify(input.config) : null;\n getDb()\n .prepare(\n `INSERT INTO document_sources\n (id, path, label, enabled, last_scan_at, last_error, created_at, updated_at, kind, config, last_cursor)\n VALUES (?, ?, ?, 1, NULL, NULL, ?, ?, ?, ?, NULL)`,\n )\n .run(id, input.path, input.label ?? null, t, t, kind, config);\n return {\n id,\n path: input.path,\n label: input.label ?? null,\n enabled: 1,\n last_scan_at: null,\n last_error: null,\n created_at: t,\n updated_at: t,\n kind,\n config,\n last_cursor: null,\n };\n}\n\n// Parsed-config accessor — JSON.parse on every call would be fine at our\n// scale but this helper keeps call sites tidy.\nexport function parseSourceConfig<T = Record<string, unknown>>(\n row: DocumentSourceRow,\n): T | null {\n if (!row.config) return null;\n try { return JSON.parse(row.config) as T; } catch { return null; }\n}\n\nexport function updateDocumentSourceCursor(id: string, cursor: string | null): void {\n getDb()\n .prepare(\"UPDATE document_sources SET last_cursor=?, updated_at=? WHERE id=?\")\n .run(cursor, now(), id);\n}\n\nexport function updateDocumentSource(\n id: string,\n patch: { label?: string | null; enabled?: boolean },\n): DocumentSourceRow | null {\n const existing = getDocumentSource(id);\n if (!existing) return null;\n const t = now();\n getDb()\n .prepare(\n `UPDATE document_sources SET label=?, enabled=?, updated_at=? WHERE id=?`,\n )\n .run(\n patch.label === undefined ? existing.label : patch.label,\n patch.enabled === undefined ? existing.enabled : patch.enabled ? 1 : 0,\n t,\n id,\n );\n return getDocumentSource(id);\n}\n\nexport function deleteDocumentSource(id: string): boolean {\n // ON DELETE CASCADE handles documents + chunks.\n return (\n (getDb()\n .prepare(\"DELETE FROM document_sources WHERE id=?\")\n .run(id) as { changes: number }).changes > 0\n );\n}\n\nexport function markSourceScanned(\n id: string,\n error?: string | null,\n): void {\n getDb()\n .prepare(\n \"UPDATE document_sources SET last_scan_at=?, last_error=?, updated_at=? WHERE id=?\",\n )\n .run(now(), error ?? null, now(), id);\n}\n\nexport interface DocumentSourceStats {\n source_id: string;\n document_count: number;\n chunk_count: number;\n embedded_chunk_count: number;\n}\n\nexport function getDocumentSourceStats(sourceId: string): DocumentSourceStats {\n const db = getDb();\n const docs = db\n .prepare(\"SELECT COUNT(*) AS n FROM documents WHERE source_id=?\")\n .get(sourceId) as { n: number };\n const chunks = db\n .prepare(\n `SELECT COUNT(*) AS n\n FROM document_chunks dc JOIN documents d ON dc.document_id = d.id\n WHERE d.source_id=?`,\n )\n .get(sourceId) as { n: number };\n const embedded = db\n .prepare(\n `SELECT COUNT(*) AS n\n FROM document_chunks dc JOIN documents d ON dc.document_id = d.id\n WHERE d.source_id=? AND dc.embedding IS NOT NULL`,\n )\n .get(sourceId) as { n: number };\n return {\n source_id: sourceId,\n document_count: docs.n,\n chunk_count: chunks.n,\n embedded_chunk_count: embedded.n,\n };\n}\n"],"names":["getOrCreateGlobal","key","factory","g","globalThis","undefined","z","tool","DEFAULT_DEADLINE_MS","DEADLINE_DESCRIPTION","wrapWithWallclock","t","schema","extendedSchema","ZodObject","extend","deadline_ms","number","int","positive","optional","describe","wrappedFunc","args","config","deadlineMs","readDeadlineMs","innerArgs","stripDeadline","timer","timeoutPromise","Promise","resolve","setTimeout","JSON","stringify","ok","error_code","message","name","unref","work","invoke","race","clearTimeout","rebuilt","description","v","Number","isFinite","_ignore","rest","__DEFAULT_DEADLINE_MS","CATEGORY_GROUPS","Memory","Documents","Files","Shell","Web","Images","Voice","Schedule","Config","Mail","Calendar","Agent","Atlassian","JiraAlign","GitHub","REGISTRY","Map","registerTools","category","capability","tools","group","wrapped","has","Error","w","set","push","registeredTools","Array","from","values","e","registeredNames","Set","keys","registeredCategory","get","registeredCapability","registeredGroup","_resetRegistry","clear","adfToText","adf","parts","walk","node","depth","text","block","type","test","isArray","content","c","join","replace","trim","htmlToText","html","s","randomUUID","createHash","getDb","chunkAndEmbedDocument","findExisting","sourceId","path","row","prepare","isoToMtime","iso","Date","parse","h","update","digest","readUInt32BE","hashContent","upsertRemoteDocument","input","db","toISOString","hash","mtime","externalUpdatedAt","existing","content_hash","run","id","status","chunks","embedded","embedError","docId","size","Buffer","byteLength","title","r","evictMissing","keepPaths","rows","all","removed","del","_atlassianFetch","_resolveAtlassianAuth","parseSourceConfig","updateDocumentSourceCursor","PAGE_LIMIT","MAX_PAGES_PER_RUN","buildCql","source","since","cfg","clauses","kind","space_key","cql","slice","recency_days","pageUpdatedAt","p","version","when","history","lastUpdated","createdDate","fetchPage","auth","pageId","data","encodeURIComponent","error","runConfluenceIndexer","stats","scanned","added","updated","unchanged","errors","cursor","last_cursor","embedFailed","start","highWater","url","results","length","page","body","storage","value","updatedAt","res","indexConfluencePageById","stripHtml","truncateBytes","googleFetch","resolveGoogleAuth","graphFetch","resolveMicrosoftAuth","BODY_CAP","DEFAULT_MAX_RESULTS","DEFAULT_PAGE_SIZE","MAX_RESULTS_CAP","header","headers","hit","find","toLowerCase","decodeBase64Url","toString","findPart","part","mime","mimeType","filename","child","extractGmailBody","payload","plain","preserveParagraphs","recipientToStr","addr","emailAddress","address","summarizeGraphMessage","m","to","toRecipients","map","filter","Boolean","cc","ccRecipients","bodyPreview","contentType","capped","subject","receivedDateTime","line","lastModifiedDateTime","gmailSourceConfig","query","String","max_results","Math","min","max","page_size","outlookSourceConfig","indexGmailMail","keep","pageToken","limit","qs","URLSearchParams","q","maxResults","list","batch","messages","entry","msg","snippet","internalDate","index","item","entries","add","nextPageToken","indexOutlookMail","nextLink","ConsistencyLevel","summary","runMailIndexer","MAX_ISSUES_PER_RUN","buildJql","project_key","jql","formatJqlDate","d","isNaN","getTime","pad","n","padStart","getUTCFullYear","getUTCMonth","getUTCDate","getUTCHours","getUTCMinutes","flattenIssue","issue","baseUrl","f","fields","desc","comment","comments","author","displayName","ts","created","fetchIssue","runJiraIndexer","method","issues","indexJiraIssueByKey","_ghFetch","_resolveGithubAuth","ALLOWED_EXT","isLikelyBinary","lowerExt","PR_PAGE_LIMIT","MAX_PRS_PER_RUN","MAX_FILES_PER_RUN","MAX_FILE_BYTES","ghError","liteAuthor","u","login","flattenPull","pr","reviews","html_url","state","draft","user","created_at","submitted_at","listIssueComments","owner","repo","listReviews","emptyStats","applyUpsert","runGithubPullsIndexer","cutoffMs","now","sinceMs","NaN","outer","err","pulls","updated_at","updatedMs","resolveDefaultBranch","default_branch","runGithubRepoIndexer","ref","tree","treeSha","sha","prefix","path_prefix","blobs","startsWith","contents","split","buf","encoding","runGithubIndexer","indexGithubPullByUrl","indexGithubIssueByUrl","indexGithubFileByUrl","createDocumentSource","getDocumentSourceByPath","markSourceScanned","isRemoteKind","runRemoteSource","lastError","composite","ON_DEMAND_PATH","getOrCreateOnDemandSource","label","indexOnDemand","trimmed","bareKey","result","identifier","source_id","browse","match","pages","ghPull","ghIssue","ghBlob","cleanPath","maxBytes","truncated","end","parseJsonSafe","fallback","randomBytes","DEFAULT_TTL_MS","DEFAULT_MAX_FLOWS","createOAuthFlowStore","opts","ttlMs","maxFlows","flows","globalKey","gc","k","createdAt","delete","oldest","sort","a","b","i","create","flow","patch","Object","assign","getIntegrationRaw","resolveAuth","envUrl","process","env","ATLASSIAN_URL","envEmail","ATLASSIAN_EMAIL","envToken","ATLASSIAN_API_TOKEN","stripTrailingSlash","email","apiToken","saved","api_token","authHeader","init","atlassianFetch","fetch","Authorization","Accept","jiraSearchTool","fieldList","assignee","priority","next_page_token","object","string","array","jiraGetIssueTool","issue_key","expand","custom_fields","include_comments","resolvedCustom","loadJiraFields","resolveCustomFieldNames","unresolved","candidates","custom","hint_first_25_custom_fields","resolved","expandSet","params","baseFields","rendered","renderedFields","customOut","extractFieldValue","issueLinks","issuelinks","l","inward","inwardIssue","outward","outwardIssue","direction","verb","other_issue","remoteLinks","rl","obj","simplifyADF","issuetype","reporter","labels","components","comments_count","total","parent","subtasks","issue_links","attachments","attachment","mime_type","content_url","remote_links","boolean","jiraCreateIssueTool","issue_type","parent_key","assignee_account_id","project","textToADF","accountId","record","unknown","jiraAddCommentTool","comment_id","jiraFindUserTool","users","account_id","display_name","active","jiraUpdateIssueTool","assignee_email","fix_versions","labels_add","labels_remove","fixVersions","inputs","ops","remove","exact","picked","updated_fields","nullable","jiraTransitionsTool","transition_name","available_transitions","transitions","available","transition","transitioned_to","jiraLinkIssuesTool","from_issue","to_issue","link_type","types","issueLinkTypes","available_link_types","usage","wanted","reads_as","bulkIssueSchema","jiraCreateIssuesBulkTool","anyCustom","some","loaded","issueUpdates","jiraAddRemoteLinkTool","icon_url","global_id","icon","url16x16","globalId","remote_link_id","target","jiraDeleteLinkTool","link_id","deleted","enum","jiraUploadAttachmentTool","content_base64","content_text","form","FormData","append","Blob","parsed","jiraDeleteIssueTool","delete_subtasks","SPRINT_STATES","validateSprintTransition","current","jiraListBoardsTool","boards","location","projectKey","is_last","isLast","jiraGetBoardTool","board_id","meta","configuration","filter_id","sub_query","subQuery","estimation_field","estimation","field","fieldId","ranking_field","ranking","rankCustomFieldId","union","jiraListSprintsTool","sprints","goal","start_date","startDate","end_date","endDate","complete_date","completeDate","origin_board_id","originBoardId","jiraGetSprintTool","sprint_id","jiraCreateSprintTool","jiraUpdateSprintTool","check","current_state","legal_next_states","jiraDeleteSprintTool","confirm","deleted_sprint_id","jiraMoveIssuesToSprintTool","issue_keys","moved","jiraMoveIssuesToBacklogTool","moved_to_backlog","jiraRankIssuesTool","rank_before_issue","rank_after_issue","rank_custom_field_id","rankBeforeIssue","rankAfterIssue","ranked","relative_to","before","after","jiraGetCommentsTool","start_at","order_by","startAt","jiraUpdateCommentTool","jiraDeleteCommentTool","deleted_comment_id","jiraGetAttachmentContentTool","as_text","fullUrl","errText","ct","looksText","content_type","as","arrayBuffer","jiraDeleteAttachmentTool","attachment_id","deleted_attachment_id","jiraAddWorklogTool","time_spent","started","timeSpent","worklog_id","jiraListWorklogsTool","worklogs","time_spent_seconds","timeSpentSeconds","jiraGetChangelogTool","changelog","items","field_type","fieldtype","hasOwn","fromString","jiraListProjectsTool","category_id","projects","type_key","projectTypeKey","style","lead","jiraGetProjectTool","include_versions","include_components","include_issue_types","versions","released","archived","release_date","releaseDate","issue_types","issueTypes","subtask","hierarchy_level","hierarchyLevel","jiraListVersionsTool","jiraCreateVersionTool","proj","projectId","version_id","jiraUpdateVersionTool","jiraListComponentsTool","assignee_type","assigneeType","jiraCreateComponentTool","lead_account_id","leadAccountId","component_id","META_KIND_TO_PATH","resolution","META_KINDS","jiraListMetaTool","available_kinds","status_category","statusCategory","confluenceSearchTool","_links","webui","confluenceGetPageTool","page_id","storageVal","viewVal","view","links","space_id","spaceId","parent_id","parentId","body_storage","body_storage_truncated","body_view","body_view_truncated","confluenceGetPageByTitleTool","include_body","sid","resolveSpaceId","matches","confluenceGetPageChildrenTool","children","position","next_cursor","parseV2NextCursor","next","confluenceGetPageAncestorsTool","ancestors","confluenceListSpacesTool","spaces","homepage_id","homepageId","confluenceGetCommentsTool","include_inline","footerData","inlineData","flatten","ver","author_id","authorId","parent_comment_id","parentCommentId","footer_comments","inline_comments","inline_warning","confluenceListAttachmentsTool","media_type","mediaType","file_size","fileSize","download_link","downloadLink","webui_link","confluenceGetLabelsTool","confluenceGetAttachmentContentTool","confluenceCreatePageTool","body_text","resolveBody","representation","confluenceUpdatePageTool","version_number","version_message","nextVersion","resolvedTitle","cur","confluenceAddCommentTool","confluenceMovePageTool","target_id","confluenceUploadAttachmentTool","minor_edit","metadata","extensions","confluenceAddLabelTool","total_labels","confluenceDeletePageTool","purge","deleted_page_id","purged","COMMENT_KIND_TO_PATH","footer","inline","confluenceUpdateCommentTool","segment","confluenceDeleteCommentTool","confluenceRemoveLabelTool","removed_label","confluenceDeleteAttachmentTool","confluenceTextToStorage","escape","para","linksNext","decodeURIComponent","hasText","hasStorage","SPACE_ID_CACHE_TTL_MS","spaceIdCache","spaceKey","cacheKey","cached","FIELD_CACHE_TTL_MS","fieldCache","byId","byName","raw","renderedHTML","coerceItem","flatMap","out","walkChildren","GITHUB_TOKEN","GH_TOKEN","token","API","ghFetch","COMMENT_CAP","PATCH_CAP","SNIPPET_CAP","truncate","cap","decodeContentsBlob","binary","size_bytes","b64","liteUser","liteLabels","githubSearchIssuesTool","total_count","is_pr","pull_request","githubGetIssueTool","assignees","closed_at","githubCreateIssueTool","githubAddCommentTool","githubListPullsTool","head","base","per_page","githubGetPullTool","merged","mergeable","mergeable_state","full_name","changed_files","additions","deletions","review_comments","merged_at","githubGetRepoTool","visibility","private","topics","language","stars","stargazers_count","forks","forks_count","open_issues","open_issues_count","pushed_at","githubUpdateIssueTool","state_reason","githubListIssueCommentsTool","githubCreatePullTool","maintainer_can_modify","githubUpdatePullTool","githubMergePullTool","commit_title","commit_message","merge_method","merged_sha","githubRequestReviewersTool","reviewers","team_reviewers","requested_users","requested_reviewers","requested_teams","slug","githubCreateReviewTool","event","commit_id","review_id","githubListPullFilesTool","files","changes","previous_filename","patch_truncated","githubListPullReviewsTool","githubListBranchesTool","branches","commit_sha","commit","protected","githubGetFileTool","decoded","githubSearchCodeTool","fragment","text_matches","snip","repository","snippet_truncated","MAX_CHARS","OVERLAP_CHARS","chunkText","paragraphs","re","exec","lastIndex","start_offset","end_offset","tail","pos","promises","fs","relative","sep","embedBestEffort","listEnabledDocumentSources","SKIP_DIRS","MAX_FILES_PER_SOURCE","MAX_INDEX_PER_TICK_PER_SOURCE","lastIndexOf","len","suspicious","root","seen","visit","dir","readdir","withFileTypes","isDirectory","abs","isFile","ext","st","stat","rel","mtime_ms","floor","mtimeMs","listIndexedDocs","listUnembeddedChunks","documentId","backfillDocumentEmbeddings","missing","vectors","updateEmb","readTextFile","readFile","indexSource","indexed","onDisk","maxThisRun","maxFiles","processed","upsertLocalDocument","embed_failed","embed_error","existingId","writeId","info","winner","_label","insertChunk","chunkIds","indexAllSources","sources","maxFilesPerSource","console","decodeHtmlEntities","flowStore","createFlow","getFlow","updateFlow","deleteFlow","GMAIL_SCOPES","buildAuthorizeUrl","client_id","clientId","redirect_uri","redirectUri","response_type","scope","access_type","prompt","include_granted_scopes","exchangeCode","code","client_secret","clientSecret","grant_type","signal","AbortSignal","timeout","envId","GMAIL_CLIENT_ID","envSecret","GMAIL_CLIENT_SECRET","envRefresh","GMAIL_REFRESH_TOKEN","refresh_token","accessTokenCache","getGoogleAccessToken","expires_at","access_token","expires_in","service","TENANT","OUTLOOK_TENANT","MICROSOFT_SCOPES","response_mode","OUTLOOK_CLIENT_ID","OUTLOOK_CLIENT_SECRET","OUTLOOK_REFRESH_TOKEN","getMicrosoftAccessToken","listDocumentSources","getDocumentSource","enabled","last_scan_at","last_error","updateDocumentSource","deleteDocumentSource","getDocumentSourceStats","docs","document_count","chunk_count","embedded_chunk_count"],"sourceRoot":"","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"4631.js","mappings":"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","sources":["webpack://@circuitwall/jarela/./lib/utils/global-state.ts","webpack://@circuitwall/jarela/./lib/tools/wallclock.ts","webpack://@circuitwall/jarela/./lib/tools/registry.ts","webpack://@circuitwall/jarela/./lib/documents/remote/flatten.ts","webpack://@circuitwall/jarela/./lib/documents/remote/upsert.ts","webpack://@circuitwall/jarela/./lib/documents/remote/confluence.ts","webpack://@circuitwall/jarela/./lib/documents/remote/mail.ts","webpack://@circuitwall/jarela/./lib/documents/remote/jira.ts","webpack://@circuitwall/jarela/./lib/documents/remote/github.ts","webpack://@circuitwall/jarela/./lib/documents/remote/index.ts","webpack://@circuitwall/jarela/./lib/utils/text.ts","webpack://@circuitwall/jarela/./lib/utils/json.ts","webpack://@circuitwall/jarela/./lib/utils/oauth-flow-store.ts","webpack://@circuitwall/jarela/./lib/tools/atlassian.ts","webpack://@circuitwall/jarela/./lib/tools/github.ts","webpack://@circuitwall/jarela/./lib/documents/chunker.ts","webpack://@circuitwall/jarela/./lib/documents/indexer.ts","webpack://@circuitwall/jarela/./lib/utils/html.ts","webpack://@circuitwall/jarela/./lib/integrations/gmail-oauth.ts","webpack://@circuitwall/jarela/./lib/integrations/microsoft-oauth.ts","webpack://@circuitwall/jarela/./lib/stores/document-sources.ts"],"sourcesContent":["// Pin a piece of state to globalThis so it survives Next.js dev hot-reload.\n//\n// Without this, every code edit re-evaluates the module, replacing the\n// in-memory state with empty containers — but any active closure still\n// references the OLD set, so listeners/timers/maps go silently dead.\n// The globalThis trick is the standard Next pattern for singletons.\n//\n// `key` must be unique across the app (it lives on globalThis); pick a\n// \"__jarela_<name>\" prefix to keep the namespace tidy.\nexport function getOrCreateGlobal<T>(key: string, factory: () => T): T {\n const g = globalThis as unknown as Record<string, unknown>;\n if (g[key] === undefined) g[key] = factory();\n return g[key] as T;\n}\n","// Per-call wall-clock budgets for tools.\n//\n// Every registered tool is wrapped with a Promise.race against a timer\n// the LLM controls via an injected `deadline_ms` schema field. When the\n// timer fires first, the wrapped tool returns a structured timeout result\n// to the agent instead of throwing — the turn continues, the agent gets a\n// tool message saying \"timed out\", and can recover (retry differently,\n// split the work, or move on).\n//\n// Why \"agent self-set\" instead of a global env knob: the right deadline\n// is hugely context-dependent (a 5s budget for a memory_read is right;\n// the same budget for `npm install` is absurd). The model knows what\n// it's calling, so the model picks. The `deadline_ms` field on every\n// tool's schema makes that picker explicit and self-documenting.\n//\n// Caveat: the underlying tool's promise is abandoned, not aborted. A\n// network call or subprocess started by the tool keeps running until it\n// settles into the void. Tools that own a long-lived resource (fetch,\n// exec) should use the `deadline_ms` value themselves to drive their own\n// abort signal — the wallclock wrapper is the backstop, not the only\n// mechanism.\n\nimport { z } from \"zod\";\nimport { tool, type StructuredToolInterface } from \"@langchain/core/tools\";\n\nconst DEFAULT_DEADLINE_MS = 120_000;\n\nconst DEADLINE_DESCRIPTION =\n \"Optional wall-clock budget for this tool call in milliseconds (default 120000). \" +\n \"When the budget is exceeded the call returns a structured timeout result \" +\n \"and the turn continues so you can recover — pick a value that matches \" +\n \"the expected duration (5000-15000 for fast local ops, 30000-90000 for \" +\n \"network/web calls, larger for shell commands that may build or install).\";\n\ninterface WallclockedFunc {\n (args: Record<string, unknown>, config?: unknown): Promise<unknown>;\n}\n\nexport function wrapWithWallclock<T extends StructuredToolInterface>(t: T): T {\n // Only zod-object schemas can be extended with `deadline_ms`. Other\n // schema shapes (raw JSON Schema, ZodString) pass through unchanged.\n // Those tools still get the wallclock race using the default budget.\n const schema = (t as unknown as { schema: unknown }).schema;\n const extendedSchema = schema instanceof z.ZodObject\n ? schema.extend({ deadline_ms: z.number().int().positive().optional().describe(DEADLINE_DESCRIPTION) })\n : null;\n\n const wrappedFunc: WallclockedFunc = async (args, config) => {\n const deadlineMs = readDeadlineMs(args) ?? DEFAULT_DEADLINE_MS;\n const innerArgs = stripDeadline(args);\n\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeoutPromise = new Promise<string>((resolve) => {\n timer = setTimeout(() => {\n resolve(JSON.stringify({\n ok: false,\n error_code: \"tool_timeout\",\n message:\n `Tool \"${t.name}\" exceeded its wall-clock budget of ${deadlineMs}ms. ` +\n `The call was abandoned; the underlying operation may still be running in the background. ` +\n `Recover by trying a different approach, splitting the work, or moving on — do not retry the same call with the same arguments.`,\n deadline_ms: deadlineMs,\n }));\n }, deadlineMs);\n // Don't keep the event loop alive purely for a timeout race.\n (timer as unknown as { unref?: () => void }).unref?.();\n });\n\n try {\n // Cast: invoke accepts a typed input matching the original schema,\n // but the wrapper is generic over all tools.\n const work = (t as unknown as { invoke: (a: unknown, c?: unknown) => Promise<unknown> }).invoke(innerArgs, config);\n return await Promise.race([work, timeoutPromise]);\n } finally {\n if (timer) clearTimeout(timer);\n }\n };\n\n // Rebuild via the public `tool()` factory so we don't depend on\n // internal field shapes of the StructuredTool class. The new tool\n // keeps the original's name and description, swaps in the extended\n // schema, and routes invocation through wrappedFunc.\n const rebuilt = tool(\n wrappedFunc as never,\n {\n name: t.name,\n description: t.description ?? \"\",\n schema: (extendedSchema ?? schema) as never,\n } as never,\n );\n return rebuilt as unknown as T;\n}\n\nfunction readDeadlineMs(args: Record<string, unknown> | unknown): number | null {\n if (!args || typeof args !== \"object\") return null;\n const v = (args as Record<string, unknown>).deadline_ms;\n return typeof v === \"number\" && Number.isFinite(v) && v > 0 ? v : null;\n}\n\nfunction stripDeadline(args: Record<string, unknown> | unknown): Record<string, unknown> | unknown {\n if (!args || typeof args !== \"object\") return args;\n const { deadline_ms: _ignore, ...rest } = args as Record<string, unknown>;\n void _ignore;\n return rest;\n}\n\n/** Exposed for the tests. */\nexport const __DEFAULT_DEADLINE_MS = DEFAULT_DEADLINE_MS;\n","/**\n * Tool registry.\n *\n * Each built-in tool module registers its own tools at module load with\n * two orthogonal axes:\n *\n * - category — topical group (\"Memory\", \"Files\", \"Mail\", …) used by\n * the Agent editor sidebar to organise tools for users.\n * - capability — safety class (\"read\" | \"write\" | \"execute\") used by\n * the future per-capability approval gate, UI badges,\n * and the ADR-0037 output validator. See ADR-0038.\n *\n * `lib/tools/index.ts` only needs to side-effect-import the modules\n * (see ./builtins.ts) — there is no central map listing every tool by\n * name. Adding a new built-in tool now requires touching exactly two\n * files: the tool file itself, and an `import \"./<name>\";` line in\n * builtins.ts.\n *\n * External tools (loaded from JARELA_TOOLS_DIR at runtime) use the same\n * category vocabulary but are not stored in this registry — see\n * ./external.ts. MCP tools default to category \"MCP\". Both default to\n * capability \"execute\" until manifest-level overrides land (ADR-0038\n * follow-up).\n *\n * Public surface (per `package.json#exports`): `ToolCategory`,\n * `Capability`, `ToolGroup`, `BuiltinCategory`, `registerTools`.\n * Everything else (`registeredTools` / `registeredNames` /\n * `registeredCategory` / etc.) is `@internal` — used only by the in-tree\n * runtime, not part of the plugin contract.\n */\n\nimport type { StructuredToolInterface } from \"@langchain/core/tools\";\nimport { wrapWithWallclock } from \"./wallclock\";\n\nexport type ToolCategory =\n | \"Memory\" | \"Documents\" | \"Files\" | \"Shell\" | \"Web\" | \"Images\" | \"Voice\"\n | \"Schedule\" | \"Atlassian\" | \"JiraAlign\" | \"GitHub\" | \"Mail\" | \"Calendar\" | \"Config\" | \"Agent\" | \"MCP\";\n\n// Safety class. Orthogonal to ToolCategory. See ADR-0038 for definitions\n// and tie-breakers (network reads vs writes, drafts, etc.).\nexport type Capability = \"read\" | \"write\" | \"execute\";\n\n// Optional parent grouping for the Agent editor sidebar.\nexport type ToolGroup = \"Work\" | null;\n\n// Category → group mapping. \"Work\" collapses corporate-auth tools under\n// one header in the Agent editor; everything else is a top-level category.\nconst CATEGORY_GROUPS: Record<Exclude<ToolCategory, \"MCP\">, ToolGroup> = {\n Memory: null, Documents: null, Files: null, Shell: null, Web: null, Images: null, Voice: null,\n Schedule: null, Config: null, Mail: null, Calendar: null, Agent: null,\n Atlassian: \"Work\", JiraAlign: \"Work\", GitHub: \"Work\",\n};\n\nexport type BuiltinCategory = Exclude<ToolCategory, \"MCP\">;\n\ninterface RegistryEntry {\n tool: StructuredToolInterface;\n category: BuiltinCategory;\n capability: Capability;\n group: ToolGroup;\n}\n\nconst REGISTRY = new Map<string, RegistryEntry>();\n\n/**\n * Register one or more tools under a category and capability. Call this at\n * the bottom of each tool file (after the tools are defined). Files with\n * mixed capabilities make multiple calls — see ADR-0038. Throws on\n * duplicate names — collisions are bugs, not warnings.\n */\nexport function registerTools<T extends StructuredToolInterface>(\n category: BuiltinCategory,\n capability: Capability,\n tools: readonly T[],\n): readonly T[] {\n const group = CATEGORY_GROUPS[category];\n const wrapped: T[] = [];\n for (const t of tools) {\n if (REGISTRY.has(t.name)) {\n throw new Error(`[tools] duplicate built-in tool registration: ${t.name}`);\n }\n // Every built-in tool gets the agent-controlled wall-clock wrap so a\n // single stuck call (network hang, fs on a wedged cloud-sync drive,\n // runaway shell) can't pin the turn — see lib/tools/wallclock.ts.\n const w = wrapWithWallclock(t);\n REGISTRY.set(w.name, { tool: w, category, capability, group });\n wrapped.push(w);\n }\n return wrapped;\n}\n\n/** @internal — all registered built-in tools, in registration order. */\nexport function registeredTools(): StructuredToolInterface[] {\n return Array.from(REGISTRY.values(), (e) => e.tool);\n}\n\n/** @internal — names of all registered built-in tools, used for collision checks. */\nexport function registeredNames(): ReadonlySet<string> {\n return new Set(REGISTRY.keys());\n}\n\n/** @internal */\nexport function registeredCategory(name: string): BuiltinCategory | undefined {\n return REGISTRY.get(name)?.category;\n}\n\n/** @internal */\nexport function registeredCapability(name: string): Capability | undefined {\n return REGISTRY.get(name)?.capability;\n}\n\n/** @internal */\nexport function registeredGroup(name: string): ToolGroup | undefined {\n return REGISTRY.get(name)?.group;\n}\n\n/** @internal — test-only: clear the registry between cases. */\nexport function _resetRegistry(): void {\n REGISTRY.clear();\n}\n","// Plain-text flatteners for remote document RAG (ADR-0026).\n//\n// Jira issue bodies and comments arrive as Atlassian Document Format\n// (ADF) — a JSON tree of typed nodes. Confluence page bodies arrive as\n// HTML (the `storage` representation). Both have to be flattened to plain\n// text before being chunked by `lib/documents/chunker.ts`, which assumes\n// paragraph-delimited text.\n//\n// These flatteners are intentionally lossy: they keep textual content\n// and paragraph structure, drop markup, links, attachments, embeds.\n// \"Good enough for retrieval\" is the bar — not \"round-trips to source\".\n\ninterface AdfNode {\n type?: string;\n text?: string;\n content?: AdfNode[];\n}\n\n/** Flatten an ADF JSON tree into paragraph-separated plain text. */\nexport function adfToText(adf: unknown): string {\n if (!adf || typeof adf !== \"object\") return \"\";\n const parts: string[] = [];\n function walk(node: AdfNode, depth = 0): void {\n if (!node) return;\n if (typeof node.text === \"string\") {\n parts.push(node.text);\n return;\n }\n const block = node.type && /paragraph|heading|listItem|codeBlock|blockquote|panel/.test(node.type);\n if (Array.isArray(node.content)) {\n for (const c of node.content) walk(c, depth + 1);\n }\n if (block) parts.push(\"\\n\\n\");\n }\n walk(adf as AdfNode);\n // Collapse runs of >2 newlines and trim.\n return parts.join(\"\").replace(/\\n{3,}/g, \"\\n\\n\").trim();\n}\n\n/** Strip Confluence storage-format HTML to plain text. */\nexport function htmlToText(html: string): string {\n if (!html) return \"\";\n let s = html;\n // Drop script / style blocks entirely.\n s = s.replace(/<(script|style)[^>]*>[\\s\\S]*?<\\/\\1>/gi, \"\");\n // Confluence macros sometimes embed CDATA — keep the inner text.\n s = s.replace(/<!\\[CDATA\\[([\\s\\S]*?)\\]\\]>/g, \"$1\");\n // Block-level closes → newline.\n s = s.replace(/<\\/(p|div|h[1-6]|li|tr|br|hr|blockquote|pre)\\s*>/gi, \"\\n\");\n // Self-closing <br>.\n s = s.replace(/<br\\s*\\/?>/gi, \"\\n\");\n // Drop all remaining tags.\n s = s.replace(/<[^>]+>/g, \"\");\n // Decode the handful of entities Atlassian actually emits.\n s = s\n .replace(/ /g, \" \")\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\")\n .replace(/'/g, \"'\");\n // Collapse runs of >2 newlines and trim trailing space per line.\n return s.replace(/[ \\t]+\\n/g, \"\\n\").replace(/\\n{3,}/g, \"\\n\\n\").trim();\n}\n","// Shared upsert path for remote document sources (ADR-0026).\n//\n// Remote sources (Jira issues, Confluence pages) don't have an mtime or a\n// stable filesystem path — the upstream `updated` timestamp plays the same\n// role as mtime, and we synthesize a stable `path` per item (`jira://KEY`\n// or `confluence://pageId`). The rest of the indexed shape matches local\n// folder documents so retrieval through searchDocuments works unchanged.\n\nimport { randomUUID, createHash } from \"node:crypto\";\nimport { getDb } from \"@/lib/db\";\nimport { chunkAndEmbedDocument } from \"../indexer\";\n\nexport interface RemoteDocInput {\n /** Stable synthetic path, e.g. \"jira://ABC-123\" or \"confluence://12345\". */\n path: string;\n /** Human-readable title shown in retrieval results (Jira key+summary,\n * Confluence page title). Stored in `rel_path` so the existing search\n * UI shows it without schema changes. */\n title: string;\n /** ISO timestamp of the upstream `updated` field. Drives change detection\n * via the same column the local indexer uses for filesystem mtime\n * (re-purposed: we hash this string into mtime_ms). */\n externalUpdatedAt: string;\n /** Plain-text body to chunk + embed. Already flattened (ADF→text,\n * HTML→text) by the caller. */\n text: string;\n}\n\ninterface IndexedRow {\n id: string;\n mtime_ms: number;\n content_hash: string;\n}\n\nfunction findExisting(sourceId: string, path: string): IndexedRow | null {\n const row = getDb()\n .prepare(\"SELECT id, mtime_ms, content_hash FROM documents WHERE source_id=? AND path=?\")\n .get(sourceId, path) as IndexedRow | undefined;\n return row ?? null;\n}\n\n// Map an ISO string to a stable integer so we can store it in the existing\n// `mtime_ms` column without a schema change. Hashing keeps the column\n// useful for \"did the upstream record change?\" checks even though ms\n// resolution is meaningless for remote sources.\nfunction isoToMtime(iso: string): number {\n const t = Date.parse(iso);\n if (Number.isFinite(t)) return t;\n // Fall back to a deterministic hash so duplicate calls with the same\n // string still produce the same value.\n const h = createHash(\"sha1\").update(iso).digest();\n return h.readUInt32BE(0);\n}\n\nfunction hashContent(text: string): string {\n return createHash(\"sha256\").update(text).digest(\"hex\");\n}\n\nexport interface UpsertResult {\n status: \"unchanged\" | \"added\" | \"updated\";\n /** Total chunks produced for this document (0 when unchanged). */\n chunks: number;\n /** Chunks that successfully got an embedding vector. */\n embedded: number;\n /** First embed error seen for this document, if any. */\n embedError: string | null;\n}\n\n/**\n * Insert-or-update a single remote document. Returns whether anything\n * actually changed so the caller can update incremental-sync counters.\n * Re-chunks + re-embeds when content changed; otherwise just touches\n * the indexed-at timestamp.\n */\nexport async function upsertRemoteDocument(\n sourceId: string,\n input: RemoteDocInput,\n): Promise<UpsertResult> {\n const db = getDb();\n const t = new Date().toISOString();\n const hash = hashContent(input.text);\n const mtime = isoToMtime(input.externalUpdatedAt);\n const existing = findExisting(sourceId, input.path);\n\n if (existing && existing.content_hash === hash) {\n db.prepare(\"UPDATE documents SET mtime_ms=?, last_indexed_at=? WHERE id=?\")\n .run(mtime, t, existing.id);\n return { status: \"unchanged\", chunks: 0, embedded: 0, embedError: null };\n }\n\n const docId = existing?.id ?? randomUUID();\n const size = Buffer.byteLength(input.text, \"utf8\");\n\n if (existing) {\n db.prepare(\n `UPDATE documents\n SET path=?, rel_path=?, mtime_ms=?, size_bytes=?, content_hash=?, last_indexed_at=?\n WHERE id=?`,\n ).run(input.path, input.title, mtime, size, hash, t, existing.id);\n db.prepare(\"DELETE FROM document_chunks WHERE document_id=?\").run(existing.id);\n } else {\n db.prepare(\n `INSERT INTO documents\n (id, source_id, path, rel_path, mtime_ms, size_bytes, content_hash, last_indexed_at, chunk_count)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, 0)`,\n ).run(docId, sourceId, input.path, input.title, mtime, size, hash, t);\n }\n\n const r = await chunkAndEmbedDocument(docId, input.text, input.path);\n return {\n status: existing ? \"updated\" : \"added\",\n chunks: r.chunks,\n embedded: r.embedded,\n embedError: r.embedError,\n };\n}\n\n/**\n * Drop every indexed document for `sourceId` whose `path` isn't in the\n * keep-set. Returns the count removed. Remote indexers use this only for\n * \"full re-sync\" semantics — incremental syncs don't call it (an upstream\n * item disappearing doesn't necessarily mean it should be evicted; we'd\n * rather keep stale-but-useful content than punch holes silently).\n */\nexport function evictMissing(sourceId: string, keepPaths: Set<string>): number {\n const db = getDb();\n const rows = db.prepare(\"SELECT id, path FROM documents WHERE source_id=?\")\n .all(sourceId) as Array<{ id: string; path: string }>;\n let removed = 0;\n const del = db.prepare(\"DELETE FROM documents WHERE id=?\");\n for (const r of rows) {\n if (!keepPaths.has(r.path)) {\n del.run(r.id);\n removed++;\n }\n }\n return removed;\n}\n","// Confluence remote indexer (ADR-0026).\n//\n// Source kinds handled:\n// - confluence_space → CQL `space = \"<key>\" AND type = page`\n// - confluence_cql → user-supplied CQL (still scoped to `type = page`)\n//\n// Incremental: uses `last_cursor` to avoid re-fetching pages whose\n// `lastmodified` is older than the previous run's high-water mark.\n\nimport {\n _atlassianFetch,\n _resolveAtlassianAuth,\n type AtlassianAuth,\n} from \"@/lib/tools/atlassian\";\nimport {\n parseSourceConfig,\n updateDocumentSourceCursor,\n type DocumentSourceRow,\n} from \"@/lib/stores/document-sources\";\nimport { htmlToText } from \"./flatten\";\nimport { upsertRemoteDocument, type UpsertResult } from \"./upsert\";\n\nconst PAGE_LIMIT = 25;\nconst MAX_PAGES_PER_RUN = 200;\n\ninterface ConfluencePage {\n id: string;\n title: string;\n version?: { when?: string };\n history?: { lastUpdated?: { when?: string }; createdDate?: string };\n body?: { storage?: { value?: string } };\n _links?: { webui?: string };\n}\ninterface ConfluenceSearchResp {\n results?: ConfluencePage[];\n start?: number;\n size?: number;\n limit?: number;\n}\n\nfunction buildCql(source: DocumentSourceRow, since: string | null): string {\n const cfg = parseSourceConfig<{ space_key?: string; cql?: string; recency_days?: number }>(source) ?? {};\n const clauses: string[] = [\"type = page\"];\n if (source.kind === \"confluence_space\") {\n if (!cfg.space_key) throw new Error(\"confluence_space requires config.space_key\");\n clauses.push(`space = \"${cfg.space_key}\"`);\n } else if (source.kind === \"confluence_cql\") {\n if (!cfg.cql) throw new Error(\"confluence_cql requires config.cql\");\n clauses.push(`(${cfg.cql})`);\n }\n if (since) clauses.push(`lastmodified > \"${since.slice(0, 10)}\"`);\n if (cfg.recency_days && cfg.recency_days > 0) {\n clauses.push(`lastmodified > now(\"-${cfg.recency_days}d\")`);\n }\n return clauses.join(\" AND \");\n}\n\nfunction pageUpdatedAt(p: ConfluencePage): string {\n return (\n p.version?.when ??\n p.history?.lastUpdated?.when ??\n p.history?.createdDate ??\n new Date().toISOString()\n );\n}\n\nasync function fetchPage(auth: AtlassianAuth, pageId: string): Promise<ConfluencePage | null> {\n const data = await _atlassianFetch(\n auth,\n `/wiki/rest/api/content/${encodeURIComponent(pageId)}?expand=body.storage,version,history.lastUpdated`,\n ) as ConfluencePage & { error?: string };\n if (!data || (data as { error?: string }).error) return null;\n return data;\n}\n\nexport interface ConfluenceIndexStats {\n scanned: number;\n added: number;\n updated: number;\n unchanged: number;\n errors: number;\n cursor: string | null;\n embedFailed: number;\n embedError: string | null;\n}\n\nexport async function runConfluenceIndexer(source: DocumentSourceRow): Promise<ConfluenceIndexStats> {\n const stats: ConfluenceIndexStats = {\n scanned: 0, added: 0, updated: 0, unchanged: 0, errors: 0,\n cursor: source.last_cursor,\n embedFailed: 0, embedError: null,\n };\n const auth = _resolveAtlassianAuth();\n if (\"error\" in auth) throw new Error(auth.error);\n\n const cql = buildCql(source, source.last_cursor);\n let start = 0;\n let highWater = source.last_cursor;\n\n while (stats.scanned < MAX_PAGES_PER_RUN) {\n const url = `/wiki/rest/api/content/search?cql=${encodeURIComponent(cql)}` +\n `&expand=body.storage,version,history.lastUpdated&limit=${PAGE_LIMIT}&start=${start}`;\n const data = await _atlassianFetch(auth, url) as ConfluenceSearchResp & { error?: string };\n if ((data as { error?: string }).error) throw new Error((data as { error?: string }).error);\n const results = data.results ?? [];\n if (results.length === 0) break;\n\n for (const page of results) {\n stats.scanned++;\n try {\n const text = `${page.title}\\n\\n${htmlToText(page.body?.storage?.value ?? \"\")}`.trim();\n const updatedAt = pageUpdatedAt(page);\n const res: UpsertResult = await upsertRemoteDocument(source.id, {\n path: `confluence://${page.id}`,\n title: page.title,\n externalUpdatedAt: updatedAt,\n text,\n });\n if (res.status === \"added\") stats.added++;\n else if (res.status === \"updated\") stats.updated++;\n else stats.unchanged++;\n stats.embedFailed += res.chunks - res.embedded;\n if (res.embedError && !stats.embedError) stats.embedError = res.embedError;\n if (!highWater || updatedAt > highWater) highWater = updatedAt;\n } catch {\n stats.errors++;\n }\n }\n start += results.length;\n if (results.length < PAGE_LIMIT) break;\n }\n\n if (highWater && highWater !== source.last_cursor) {\n updateDocumentSourceCursor(source.id, highWater);\n stats.cursor = highWater;\n }\n return stats;\n}\n\n/**\n * On-demand: fetch a single Confluence page by id and index it under the\n * shared \"on_demand_url\" source row. Used by the `documents_index_url` tool\n * for \"just pull THIS one page\".\n */\nexport async function indexConfluencePageById(\n sourceId: string,\n pageId: string,\n): Promise<UpsertResult> {\n const auth = _resolveAtlassianAuth();\n if (\"error\" in auth) throw new Error(auth.error);\n const page = await fetchPage(auth, pageId);\n if (!page) throw new Error(`confluence page ${pageId} not found`);\n const text = `${page.title}\\n\\n${htmlToText(page.body?.storage?.value ?? \"\")}`.trim();\n return upsertRemoteDocument(sourceId, {\n path: `confluence://${page.id}`,\n title: page.title,\n externalUpdatedAt: pageUpdatedAt(page),\n text,\n });\n}\n","// Remote mail indexing for Gmail and Outlook.\n//\n// These sources let the user index a filtered slice of mailbox content as\n// searchable documents. The query field is intentionally provider-native:\n// Gmail uses Gmail query syntax, Outlook uses KQL.\n\nimport { stripHtml } from \"@/lib/utils/html\";\nimport { truncateBytes } from \"@/lib/utils/text\";\nimport { googleFetch, resolveGoogleAuth } from \"@/lib/integrations/gmail-oauth\";\nimport { graphFetch, resolveMicrosoftAuth } from \"@/lib/integrations/microsoft-oauth\";\nimport { parseSourceConfig, type DocumentSourceRow } from \"@/lib/stores/document-sources\";\nimport { evictMissing, upsertRemoteDocument } from \"./upsert\";\n\nimport type { RemoteIndexStats } from \"./index\";\n\nconst BODY_CAP = 40_000;\nconst DEFAULT_MAX_RESULTS = 250;\nconst DEFAULT_PAGE_SIZE = 100;\nconst MAX_RESULTS_CAP = 5_000;\n\ninterface Header {\n name?: string;\n value?: string;\n}\n\ninterface GmailMessageList {\n messages?: Array<{ id: string; threadId?: string }>;\n nextPageToken?: string;\n resultSizeEstimate?: number;\n error?: string;\n}\n\ninterface GmailMessage {\n id?: string;\n threadId?: string;\n internalDate?: string;\n snippet?: string;\n labelIds?: string[];\n payload?: {\n headers?: Header[];\n mimeType?: string;\n filename?: string;\n body?: { data?: string };\n parts?: GmailMessage[\"payload\"][];\n };\n error?: string;\n}\n\ninterface GraphEmailAddress {\n name?: string;\n address?: string;\n}\n\ninterface GraphRecipient {\n emailAddress?: GraphEmailAddress;\n}\n\ninterface GraphMessage {\n id?: string;\n conversationId?: string;\n subject?: string;\n bodyPreview?: string;\n body?: { contentType?: \"html\" | \"text\"; content?: string };\n from?: GraphRecipient;\n toRecipients?: GraphRecipient[];\n ccRecipients?: GraphRecipient[];\n receivedDateTime?: string;\n lastModifiedDateTime?: string;\n isRead?: boolean;\n isDraft?: boolean;\n hasAttachments?: boolean;\n categories?: string[];\n parentFolderId?: string;\n webLink?: string;\n}\n\nfunction header(headers: Header[] | undefined, name: string): string | null {\n const hit = (headers ?? []).find((h) => (h.name ?? \"\").toLowerCase() === name.toLowerCase());\n return hit?.value ?? null;\n}\n\nfunction decodeBase64Url(s: string): string {\n try {\n return Buffer.from(s, \"base64url\").toString(\"utf8\");\n } catch {\n return \"\";\n }\n}\n\nfunction findPart(part: { mimeType?: string; filename?: string; body?: { data?: string }; parts?: Array<unknown> } | undefined, mime: string): { mimeType?: string; filename?: string; body?: { data?: string }; parts?: Array<unknown> } | null {\n if (!part) return null;\n if (part.mimeType === mime && !part.filename && part.body?.data) return part;\n for (const child of part.parts ?? []) {\n const hit = findPart(child as Parameters<typeof findPart>[0], mime);\n if (hit) return hit;\n }\n return null;\n}\n\nfunction extractGmailBody(payload: GmailMessage[\"payload\"] | undefined): string {\n if (!payload) return \"\";\n const plain = findPart(payload, \"text/plain\") as { body?: { data?: string } } | null;\n if (plain?.body?.data) return decodeBase64Url(plain.body.data);\n const html = findPart(payload, \"text/html\") as { body?: { data?: string } } | null;\n if (html?.body?.data) {\n return stripHtml(decodeBase64Url(html.body.data), { preserveParagraphs: true });\n }\n return \"\";\n}\n\nfunction recipientToStr(r?: GraphRecipient): string | null {\n const addr = r?.emailAddress?.address;\n if (!addr) return null;\n const name = r?.emailAddress?.name;\n return name && name !== addr ? `${name} <${addr}>` : addr;\n}\n\nfunction summarizeGraphMessage(m: GraphMessage): { title: string; text: string; updatedAt: string } {\n const from = recipientToStr(m.from) ?? \"\";\n const to = (m.toRecipients ?? []).map(recipientToStr).filter(Boolean).join(\", \");\n const cc = (m.ccRecipients ?? []).map(recipientToStr).filter(Boolean).join(\", \");\n const body = m.body?.content ?? m.bodyPreview ?? \"\";\n const plain = m.body?.contentType === \"html\"\n ? stripHtml(body, { preserveParagraphs: true })\n : body;\n const { text: capped } = truncateBytes(plain, BODY_CAP);\n const text = [\n `From: ${from}`,\n to ? `To: ${to}` : null,\n cc ? `Cc: ${cc}` : null,\n m.subject ? `Subject: ${m.subject}` : null,\n m.receivedDateTime ? `Date: ${m.receivedDateTime}` : null,\n \"\",\n capped,\n ].filter((line): line is string => line !== null).join(\"\\n\");\n return {\n title: m.subject?.trim() || m.id || \"(no subject)\",\n text,\n updatedAt: m.lastModifiedDateTime ?? m.receivedDateTime ?? new Date().toISOString(),\n };\n}\n\nfunction gmailSourceConfig(row: DocumentSourceRow): { query: string; max_results: number; page_size: number } {\n const cfg = parseSourceConfig<{ query?: string; max_results?: number; page_size?: number }>(row) ?? {};\n const query = String(cfg.query ?? \"\").trim();\n if (!query) throw new Error(\"gmail_mail source config.query is required\");\n const max_results = Math.min(Math.max(Number(cfg.max_results ?? DEFAULT_MAX_RESULTS), 1), MAX_RESULTS_CAP);\n const page_size = Math.min(Math.max(Number(cfg.page_size ?? DEFAULT_PAGE_SIZE), 1), 100);\n return { query, max_results, page_size };\n}\n\nfunction outlookSourceConfig(row: DocumentSourceRow): { query: string; max_results: number; page_size: number } {\n const cfg = parseSourceConfig<{ query?: string; max_results?: number; page_size?: number }>(row) ?? {};\n const query = String(cfg.query ?? \"\").trim();\n if (!query) throw new Error(\"outlook_mail source config.query is required\");\n const max_results = Math.min(Math.max(Number(cfg.max_results ?? DEFAULT_MAX_RESULTS), 1), MAX_RESULTS_CAP);\n const page_size = Math.min(Math.max(Number(cfg.page_size ?? DEFAULT_PAGE_SIZE), 1), 100);\n return { query, max_results, page_size };\n}\n\nasync function indexGmailMail(row: DocumentSourceRow): Promise<RemoteIndexStats> {\n const auth = resolveGoogleAuth();\n if (\"error\" in auth) throw new Error(auth.error);\n const { query, max_results, page_size } = gmailSourceConfig(row);\n\n const stats: RemoteIndexStats = { scanned: 0, added: 0, updated: 0, unchanged: 0, errors: 0 };\n const keep = new Set<string>();\n let pageToken: string | undefined;\n\n while (stats.scanned < max_results) {\n const limit = Math.min(page_size, max_results - stats.scanned);\n const qs = new URLSearchParams({ q: query, maxResults: String(limit) });\n if (pageToken) qs.set(\"pageToken\", pageToken);\n const list = await googleFetch(\n auth,\n \"Gmail\",\n \"https://gmail.googleapis.com/gmail/v1/users/me\",\n `/messages?${qs.toString()}`,\n ) as GmailMessageList;\n if (list.error) throw new Error(list.error);\n\n const batch = list.messages ?? [];\n if (batch.length === 0) break;\n\n const results = await Promise.all(batch.slice(0, limit).map(async (entry) => {\n const msg = await googleFetch(\n auth,\n \"Gmail\",\n \"https://gmail.googleapis.com/gmail/v1/users/me\",\n `/messages/${encodeURIComponent(entry.id)}?format=full`,\n ) as GmailMessage;\n if (msg.error) throw new Error(msg.error);\n const title = msg.payload ? header(msg.payload.headers, \"Subject\") ?? entry.id : entry.id;\n const body = extractGmailBody(msg.payload);\n const text = [\n `From: ${header(msg.payload?.headers, \"From\") ?? \"\"}`,\n `To: ${header(msg.payload?.headers, \"To\") ?? \"\"}`,\n `Subject: ${title}`,\n `Date: ${header(msg.payload?.headers, \"Date\") ?? \"\"}`,\n msg.snippet ? `Snippet: ${msg.snippet}` : null,\n \"\",\n body,\n ].filter((line): line is string => line !== null).join(\"\\n\");\n const updatedAt = msg.internalDate\n ? new Date(Number(msg.internalDate)).toISOString()\n : header(msg.payload?.headers, \"Date\") ?? new Date().toISOString();\n return upsertRemoteDocument(row.id, {\n path: `gmail://${entry.id}`,\n title,\n externalUpdatedAt: updatedAt,\n text,\n });\n }));\n\n for (const [index, item] of results.entries()) {\n const id = batch[index]?.id ?? \"\";\n if (id) keep.add(`gmail://${id}`);\n stats.scanned++;\n stats.added += item.status === \"added\" ? 1 : 0;\n stats.updated += item.status === \"updated\" ? 1 : 0;\n stats.unchanged += item.status === \"unchanged\" ? 1 : 0;\n stats.errors += item.embedError ? 1 : 0;\n stats.embedFailed = (stats.embedFailed ?? 0) + Math.max(item.chunks - item.embedded, 0);\n if (item.embedError && !stats.embedError) stats.embedError = item.embedError;\n }\n\n pageToken = list.nextPageToken;\n if (!pageToken || batch.length < limit) break;\n }\n\n stats.removed = evictMissing(row.id, keep);\n return stats;\n}\n\nasync function indexOutlookMail(row: DocumentSourceRow): Promise<RemoteIndexStats> {\n const auth = resolveMicrosoftAuth();\n if (\"error\" in auth) throw new Error(auth.error);\n const { query, max_results, page_size } = outlookSourceConfig(row);\n\n const stats: RemoteIndexStats = { scanned: 0, added: 0, updated: 0, unchanged: 0, errors: 0 };\n const keep = new Set<string>();\n let nextLink: string | null = null;\n\n while (stats.scanned < max_results) {\n const limit = Math.min(page_size, max_results - stats.scanned);\n const data = nextLink\n ? await graphFetch(auth, nextLink, { headers: { ConsistencyLevel: \"eventual\" } })\n : await graphFetch(\n auth,\n `/me/messages?$top=${limit}&$count=true&$select=id,subject,bodyPreview,from,toRecipients,ccRecipients,receivedDateTime,lastModifiedDateTime,isRead,isDraft,hasAttachments,categories,parentFolderId,webLink&$search=${encodeURIComponent(`\"${query.replace(/\"/g, '\\\\\"')}\"`)}`,\n { headers: { ConsistencyLevel: \"eventual\" } },\n );\n const payload = data as { value?: GraphMessage[]; \"@odata.nextLink\"?: string; error?: string };\n if (payload.error) throw new Error(payload.error);\n\n const batch = payload.value ?? [];\n if (batch.length === 0) break;\n\n const results = await Promise.all(batch.slice(0, limit).map(async (entry) => {\n const msg = await graphFetch(auth, `/me/messages/${encodeURIComponent(entry.id ?? \"\")}`) as GraphMessage & { error?: string };\n if (msg.error) throw new Error(msg.error);\n const summary = summarizeGraphMessage(msg);\n return upsertRemoteDocument(row.id, {\n path: `outlook://${msg.id ?? entry.id}`,\n title: summary.title,\n externalUpdatedAt: summary.updatedAt,\n text: summary.text,\n });\n }));\n\n for (const [index, item] of results.entries()) {\n const id = batch[index]?.id ?? \"\";\n if (id) keep.add(`outlook://${id}`);\n stats.scanned++;\n stats.added += item.status === \"added\" ? 1 : 0;\n stats.updated += item.status === \"updated\" ? 1 : 0;\n stats.unchanged += item.status === \"unchanged\" ? 1 : 0;\n stats.errors += item.embedError ? 1 : 0;\n stats.embedFailed = (stats.embedFailed ?? 0) + Math.max(item.chunks - item.embedded, 0);\n if (item.embedError && !stats.embedError) stats.embedError = item.embedError;\n }\n\n nextLink = payload[\"@odata.nextLink\"] ?? null;\n if (!nextLink || batch.length < limit) break;\n }\n\n stats.removed = evictMissing(row.id, keep);\n return stats;\n}\n\nexport async function runMailIndexer(source: DocumentSourceRow): Promise<RemoteIndexStats> {\n switch (source.kind) {\n case \"gmail_mail\":\n return indexGmailMail(source);\n case \"outlook_mail\":\n return indexOutlookMail(source);\n default:\n throw new Error(`unsupported mail source kind: ${source.kind}`);\n }\n}\n","// Jira remote indexer (ADR-0026).\n//\n// Source kinds handled:\n// - jira_project → JQL `project = \"<key>\"`\n// - jira_jql → user-supplied JQL\n//\n// Each indexed \"document\" is one issue, with its summary, description and\n// comments flattened into one text body. Comments live on the same chunk\n// graph as the issue body so the same retrieval query can surface either.\n\nimport {\n _atlassianFetch,\n _resolveAtlassianAuth,\n type AtlassianAuth,\n} from \"@/lib/tools/atlassian\";\nimport {\n parseSourceConfig,\n updateDocumentSourceCursor,\n type DocumentSourceRow,\n} from \"@/lib/stores/document-sources\";\nimport { adfToText } from \"./flatten\";\nimport { upsertRemoteDocument, type UpsertResult } from \"./upsert\";\n\nconst PAGE_LIMIT = 50;\nconst MAX_ISSUES_PER_RUN = 500;\n\ninterface JiraComment {\n author?: { displayName?: string };\n created?: string;\n body?: unknown; // ADF\n}\ninterface JiraIssueFields {\n summary?: string;\n description?: unknown; // ADF\n updated?: string;\n comment?: { comments?: JiraComment[]; total?: number };\n}\ninterface JiraIssue {\n key: string;\n fields?: JiraIssueFields;\n}\ninterface JiraSearchResp {\n issues?: JiraIssue[];\n nextPageToken?: string;\n}\n\nfunction buildJql(source: DocumentSourceRow, since: string | null): string {\n const cfg = parseSourceConfig<{ project_key?: string; jql?: string; recency_days?: number }>(source) ?? {};\n const clauses: string[] = [];\n if (source.kind === \"jira_project\") {\n if (!cfg.project_key) throw new Error(\"jira_project requires config.project_key\");\n clauses.push(`project = \"${cfg.project_key}\"`);\n } else if (source.kind === \"jira_jql\") {\n if (!cfg.jql) throw new Error(\"jira_jql requires config.jql\");\n clauses.push(`(${cfg.jql})`);\n }\n if (cfg.recency_days && cfg.recency_days > 0) {\n clauses.push(`updated >= -${cfg.recency_days}d`);\n }\n if (since) clauses.push(`updated > \"${formatJqlDate(since)}\"`);\n // Monotonic order keeps incremental cursors well-defined even on partial runs.\n return `${clauses.join(\" AND \")} ORDER BY updated ASC`;\n}\n\nfunction formatJqlDate(iso: string): string {\n // JQL `updated > \"yyyy/MM/dd HH:mm\"` — minute resolution is enough.\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return iso;\n const pad = (n: number) => String(n).padStart(2, \"0\");\n return `${d.getUTCFullYear()}/${pad(d.getUTCMonth() + 1)}/${pad(d.getUTCDate())} ` +\n `${pad(d.getUTCHours())}:${pad(d.getUTCMinutes())}`;\n}\n\nfunction flattenIssue(issue: JiraIssue, baseUrl: string): { text: string; updatedAt: string } {\n const f = issue.fields ?? {};\n const parts: string[] = [];\n parts.push(`${issue.key} — ${f.summary ?? \"\"}`.trim());\n parts.push(`${baseUrl}/browse/${issue.key}`);\n const desc = adfToText(f.description);\n if (desc) parts.push(desc);\n for (const c of f.comment?.comments ?? []) {\n const body = adfToText(c.body);\n if (!body.trim()) continue;\n const author = c.author?.displayName ?? \"unknown\";\n const ts = c.created ? ` (${c.created.slice(0, 10)})` : \"\";\n parts.push(`Comment by ${author}${ts}:\\n${body}`);\n }\n return {\n text: parts.join(\"\\n\\n\"),\n updatedAt: f.updated ?? new Date().toISOString(),\n };\n}\n\nasync function fetchIssue(auth: AtlassianAuth, key: string): Promise<JiraIssue | null> {\n const data = await _atlassianFetch(\n auth,\n `/rest/api/3/issue/${encodeURIComponent(key)}?fields=summary,description,updated,comment`,\n ) as JiraIssue & { error?: string };\n if (!data || (data as { error?: string }).error) return null;\n return data;\n}\n\nexport interface JiraIndexStats {\n scanned: number;\n added: number;\n updated: number;\n unchanged: number;\n errors: number;\n cursor: string | null;\n embedFailed: number;\n embedError: string | null;\n}\n\nexport async function runJiraIndexer(source: DocumentSourceRow): Promise<JiraIndexStats> {\n const stats: JiraIndexStats = {\n scanned: 0, added: 0, updated: 0, unchanged: 0, errors: 0,\n cursor: source.last_cursor,\n embedFailed: 0, embedError: null,\n };\n const auth = _resolveAtlassianAuth();\n if (\"error\" in auth) throw new Error(auth.error);\n\n const jql = buildJql(source, source.last_cursor);\n let nextPageToken: string | undefined;\n let highWater = source.last_cursor;\n\n while (stats.scanned < MAX_ISSUES_PER_RUN) {\n const data = await _atlassianFetch(auth, \"/rest/api/3/search/jql\", {\n method: \"POST\",\n body: JSON.stringify({\n jql,\n fields: [\"summary\", \"description\", \"updated\", \"comment\"],\n maxResults: PAGE_LIMIT,\n nextPageToken,\n }),\n }) as JiraSearchResp & { error?: string };\n if ((data as { error?: string }).error) throw new Error((data as { error?: string }).error);\n const issues = data.issues ?? [];\n if (issues.length === 0) break;\n\n for (const issue of issues) {\n stats.scanned++;\n try {\n const { text, updatedAt } = flattenIssue(issue, auth.url);\n const res = await upsertRemoteDocument(source.id, {\n path: `jira://${issue.key}`,\n title: `${issue.key}: ${issue.fields?.summary ?? \"\"}`.trim(),\n externalUpdatedAt: updatedAt,\n text,\n });\n if (res.status === \"added\") stats.added++;\n else if (res.status === \"updated\") stats.updated++;\n else stats.unchanged++;\n stats.embedFailed += res.chunks - res.embedded;\n if (res.embedError && !stats.embedError) stats.embedError = res.embedError;\n if (!highWater || updatedAt > highWater) highWater = updatedAt;\n } catch {\n stats.errors++;\n }\n }\n nextPageToken = data.nextPageToken;\n if (!nextPageToken) break;\n }\n\n if (highWater && highWater !== source.last_cursor) {\n updateDocumentSourceCursor(source.id, highWater);\n stats.cursor = highWater;\n }\n return stats;\n}\n\n/** On-demand: fetch & index a single issue by key under the shared\n * on_demand_url source row. */\nexport async function indexJiraIssueByKey(\n sourceId: string,\n key: string,\n): Promise<UpsertResult> {\n const auth = _resolveAtlassianAuth();\n if (\"error\" in auth) throw new Error(auth.error);\n const issue = await fetchIssue(auth, key);\n if (!issue) throw new Error(`jira issue ${key} not found`);\n const { text, updatedAt } = flattenIssue(issue, auth.url);\n return upsertRemoteDocument(sourceId, {\n path: `jira://${issue.key}`,\n title: `${issue.key}: ${issue.fields?.summary ?? \"\"}`.trim(),\n externalUpdatedAt: updatedAt,\n text,\n });\n}\n","// GitHub remote indexer (ADR-0029).\n//\n// Source kinds handled:\n// - github_pulls → all PRs of one repo + their issue comments + review\n// bodies, flattened to one document per PR.\n// - github_repo → text files on one branch of one repo (default branch\n// by default), walked via the Git Trees API. Filtered\n// by the same extension allowlist + binary heuristic\n// as the local-folder walker so the two surfaces stay\n// in sync.\n//\n// On-demand helpers (called via lib/documents/remote/index.ts'\n// indexOnDemand) cover one-shot indexing of a PR / issue / file URL\n// under the shared `on_demand_url` source row.\n\nimport {\n _ghFetch,\n _resolveGithubAuth,\n type GitHubAuth,\n} from \"@/lib/tools/github\";\nimport {\n parseSourceConfig,\n updateDocumentSourceCursor,\n type DocumentSourceRow,\n} from \"@/lib/stores/document-sources\";\nimport { ALLOWED_EXT, isLikelyBinary, lowerExt } from \"../indexer\";\nimport { upsertRemoteDocument, type UpsertResult } from \"./upsert\";\n\nconst PR_PAGE_LIMIT = 50;\nconst MAX_PRS_PER_RUN = 200;\nconst MAX_FILES_PER_RUN = 500;\nconst MAX_FILE_BYTES = 2 * 1024 * 1024; // matches local indexer\n\ninterface GhUserLite { login?: string }\ninterface GhPull {\n number: number;\n title?: string;\n state?: string;\n body?: string;\n updated_at?: string;\n html_url?: string;\n user?: GhUserLite;\n draft?: boolean;\n}\ninterface GhIssueComment {\n user?: GhUserLite;\n created_at?: string;\n body?: string;\n}\ninterface GhReview {\n user?: GhUserLite;\n state?: string;\n submitted_at?: string;\n body?: string;\n}\ninterface GhIssue {\n number: number;\n title?: string;\n body?: string;\n updated_at?: string;\n state?: string;\n html_url?: string;\n user?: GhUserLite;\n}\ninterface GhTreeEntry {\n path: string;\n type: \"blob\" | \"tree\" | \"commit\";\n size?: number;\n sha?: string;\n}\ninterface GhTreeResp {\n sha?: string;\n tree?: GhTreeEntry[];\n truncated?: boolean;\n}\ninterface GhRepo {\n default_branch?: string;\n}\ninterface GhContents {\n type?: \"file\" | \"dir\" | \"symlink\" | \"submodule\";\n encoding?: string;\n content?: string;\n size?: number;\n sha?: string;\n}\n\nfunction ghError(data: unknown): string | null {\n return (data as { error?: string })?.error ?? null;\n}\n\nfunction liteAuthor(u: GhUserLite | undefined): string {\n return u?.login ?? \"unknown\";\n}\n\n// One-document-per-PR text body. Mirrors the Jira flattener: title +\n// URL on the first lines so retrieval results read sensibly even when\n// only the leading chunk surfaces.\nfunction flattenPull(\n pr: GhPull,\n comments: GhIssueComment[],\n reviews: GhReview[],\n): string {\n const parts: string[] = [];\n parts.push(`PR #${pr.number}: ${pr.title ?? \"\"}`.trim());\n if (pr.html_url) parts.push(pr.html_url);\n parts.push(`State: ${pr.state ?? \"unknown\"}${pr.draft ? \" (draft)\" : \"\"} · author: ${liteAuthor(pr.user)}`);\n if (pr.body && pr.body.trim()) parts.push(pr.body.trim());\n for (const c of comments) {\n if (!c.body?.trim()) continue;\n const ts = c.created_at ? ` (${c.created_at.slice(0, 10)})` : \"\";\n parts.push(`Comment by ${liteAuthor(c.user)}${ts}:\\n${c.body.trim()}`);\n }\n for (const r of reviews) {\n if (!r.body?.trim()) continue;\n const ts = r.submitted_at ? ` (${r.submitted_at.slice(0, 10)})` : \"\";\n parts.push(`Review by ${liteAuthor(r.user)} — ${r.state ?? \"\"}${ts}:\\n${r.body.trim()}`);\n }\n return parts.join(\"\\n\\n\");\n}\n\nfunction flattenIssue(issue: GhIssue, comments: GhIssueComment[]): string {\n const parts: string[] = [];\n parts.push(`Issue #${issue.number}: ${issue.title ?? \"\"}`.trim());\n if (issue.html_url) parts.push(issue.html_url);\n parts.push(`State: ${issue.state ?? \"unknown\"} · author: ${liteAuthor(issue.user)}`);\n if (issue.body && issue.body.trim()) parts.push(issue.body.trim());\n for (const c of comments) {\n if (!c.body?.trim()) continue;\n const ts = c.created_at ? ` (${c.created_at.slice(0, 10)})` : \"\";\n parts.push(`Comment by ${liteAuthor(c.user)}${ts}:\\n${c.body.trim()}`);\n }\n return parts.join(\"\\n\\n\");\n}\n\nasync function listIssueComments(auth: GitHubAuth, owner: string, repo: string, n: number): Promise<GhIssueComment[]> {\n const data = await _ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/issues/${n}/comments?per_page=100`,\n );\n return Array.isArray(data) ? (data as GhIssueComment[]) : [];\n}\n\nasync function listReviews(auth: GitHubAuth, owner: string, repo: string, n: number): Promise<GhReview[]> {\n const data = await _ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls/${n}/reviews?per_page=100`,\n );\n return Array.isArray(data) ? (data as GhReview[]) : [];\n}\n\nexport interface GithubIndexStats {\n scanned: number;\n added: number;\n updated: number;\n unchanged: number;\n errors: number;\n cursor: string | null;\n embedFailed: number;\n embedError: string | null;\n}\n\nfunction emptyStats(cursor: string | null): GithubIndexStats {\n return { scanned: 0, added: 0, updated: 0, unchanged: 0, errors: 0, cursor, embedFailed: 0, embedError: null };\n}\n\nfunction applyUpsert(stats: GithubIndexStats, res: UpsertResult): void {\n if (res.status === \"added\") stats.added++;\n else if (res.status === \"updated\") stats.updated++;\n else stats.unchanged++;\n stats.embedFailed += res.chunks - res.embedded;\n if (res.embedError && !stats.embedError) stats.embedError = res.embedError;\n}\n\n// ── github_pulls ──────────────────────────────────────────────────────────\n\ninterface PullsConfig {\n owner?: string;\n repo?: string;\n recency_days?: number;\n state?: \"open\" | \"closed\" | \"all\";\n}\n\nasync function runGithubPullsIndexer(source: DocumentSourceRow): Promise<GithubIndexStats> {\n const cfg = parseSourceConfig<PullsConfig>(source) ?? {};\n if (!cfg.owner || !cfg.repo) throw new Error(\"github_pulls requires config.owner and config.repo\");\n const stats = emptyStats(source.last_cursor);\n const auth = _resolveGithubAuth();\n if (\"error\" in auth) throw new Error(auth.error);\n\n const cutoffMs = cfg.recency_days && cfg.recency_days > 0\n ? Date.now() - cfg.recency_days * 86_400_000\n : null;\n const sinceMs = source.last_cursor ? Date.parse(source.last_cursor) : NaN;\n const state = cfg.state ?? \"all\";\n let highWater = source.last_cursor;\n\n // Sorted by `updated desc` so we can stop early as soon as we drop\n // below the watermark or the recency cutoff.\n let page = 1;\n outer: while (stats.scanned < MAX_PRS_PER_RUN) {\n const data = await _ghFetch(\n auth,\n `/repos/${encodeURIComponent(cfg.owner)}/${encodeURIComponent(cfg.repo)}/pulls` +\n `?state=${state}&sort=updated&direction=desc&per_page=${PR_PAGE_LIMIT}&page=${page}`,\n );\n const err = ghError(data);\n if (err) throw new Error(err);\n const pulls = Array.isArray(data) ? (data as GhPull[]) : [];\n if (pulls.length === 0) break;\n\n for (const pr of pulls) {\n stats.scanned++;\n const updated = pr.updated_at ?? \"\";\n const updatedMs = Date.parse(updated);\n if (cutoffMs !== null && Number.isFinite(updatedMs) && updatedMs < cutoffMs) break outer;\n if (Number.isFinite(sinceMs) && Number.isFinite(updatedMs) && updatedMs <= sinceMs) break outer;\n\n try {\n const [comments, reviews] = await Promise.all([\n listIssueComments(auth, cfg.owner, cfg.repo, pr.number),\n listReviews(auth, cfg.owner, cfg.repo, pr.number),\n ]);\n const text = flattenPull(pr, comments, reviews);\n const res = await upsertRemoteDocument(source.id, {\n path: `github-pull://${cfg.owner}/${cfg.repo}/${pr.number}`,\n title: `PR #${pr.number}: ${pr.title ?? \"\"}`.trim(),\n externalUpdatedAt: updated || new Date().toISOString(),\n text,\n });\n applyUpsert(stats, res);\n if (updated && (!highWater || updated > highWater)) highWater = updated;\n } catch {\n stats.errors++;\n }\n }\n if (pulls.length < PR_PAGE_LIMIT) break;\n page++;\n }\n\n if (highWater && highWater !== source.last_cursor) {\n updateDocumentSourceCursor(source.id, highWater);\n stats.cursor = highWater;\n }\n return stats;\n}\n\n// ── github_repo ───────────────────────────────────────────────────────────\n\ninterface RepoConfig {\n owner?: string;\n repo?: string;\n ref?: string;\n path_prefix?: string;\n}\n\nasync function resolveDefaultBranch(auth: GitHubAuth, owner: string, repo: string): Promise<string> {\n const data = await _ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}`,\n ) as GhRepo & { error?: string };\n if (data.error) throw new Error(data.error);\n if (!data.default_branch) throw new Error(`could not resolve default branch for ${owner}/${repo}`);\n return data.default_branch;\n}\n\nasync function runGithubRepoIndexer(source: DocumentSourceRow): Promise<GithubIndexStats> {\n const cfg = parseSourceConfig<RepoConfig>(source) ?? {};\n if (!cfg.owner || !cfg.repo) throw new Error(\"github_repo requires config.owner and config.repo\");\n const stats = emptyStats(source.last_cursor);\n const auth = _resolveGithubAuth();\n if (\"error\" in auth) throw new Error(auth.error);\n\n const ref = cfg.ref ?? await resolveDefaultBranch(auth, cfg.owner, cfg.repo);\n const tree = await _ghFetch(\n auth,\n `/repos/${encodeURIComponent(cfg.owner)}/${encodeURIComponent(cfg.repo)}/git/trees/${encodeURIComponent(ref)}?recursive=1`,\n ) as GhTreeResp & { error?: string };\n if (tree.error) throw new Error(tree.error);\n const treeSha = tree.sha ?? null;\n\n // Cheap no-op: if the branch head hasn't moved since last walk, skip\n // the whole thing. Saves a contents fetch per file on quiet repos.\n if (treeSha && source.last_cursor === treeSha) {\n stats.cursor = treeSha;\n return stats;\n }\n\n const prefix = (cfg.path_prefix ?? \"\").replace(/^\\/+|\\/+$/g, \"\");\n const blobs = (tree.tree ?? []).filter((e) => {\n if (e.type !== \"blob\") return false;\n if (typeof e.size === \"number\" && e.size > MAX_FILE_BYTES) return false;\n if (!ALLOWED_EXT.has(lowerExt(e.path))) return false;\n if (prefix && !(e.path === prefix || e.path.startsWith(prefix + \"/\"))) return false;\n return true;\n });\n\n for (const entry of blobs) {\n if (stats.scanned >= MAX_FILES_PER_RUN) break;\n stats.scanned++;\n try {\n const contents = await _ghFetch(\n auth,\n `/repos/${encodeURIComponent(cfg.owner)}/${encodeURIComponent(cfg.repo)}/contents/${entry.path\n .split(\"/\").map(encodeURIComponent).join(\"/\")}?ref=${encodeURIComponent(ref)}`,\n ) as GhContents & { error?: string };\n if (contents.error) { stats.errors++; continue; }\n if (contents.type !== \"file\" || !contents.content) continue;\n const buf = Buffer.from(contents.content.replace(/\\s+/g, \"\"), contents.encoding === \"base64\" ? \"base64\" : \"utf8\");\n if (isLikelyBinary(buf)) continue;\n const text = buf.toString(\"utf8\");\n const res = await upsertRemoteDocument(source.id, {\n path: `github-file://${cfg.owner}/${cfg.repo}@${ref}/${entry.path}`,\n title: entry.path,\n externalUpdatedAt: new Date().toISOString(), // tree SHA carries the cursor; per-file mtime would need a commits API call we'd rather skip\n text,\n });\n applyUpsert(stats, res);\n } catch {\n stats.errors++;\n }\n }\n\n if (treeSha && treeSha !== source.last_cursor) {\n updateDocumentSourceCursor(source.id, treeSha);\n stats.cursor = treeSha;\n }\n return stats;\n}\n\n// ── Dispatcher entry-point used by lib/documents/remote/index.ts ──────────\n\nexport async function runGithubIndexer(source: DocumentSourceRow): Promise<GithubIndexStats> {\n if (source.kind === \"github_pulls\") return runGithubPullsIndexer(source);\n if (source.kind === \"github_repo\") return runGithubRepoIndexer(source);\n throw new Error(`runGithubIndexer called with unsupported kind: ${source.kind}`);\n}\n\n// ── On-demand helpers (called from indexOnDemand) ─────────────────────────\n\nexport async function indexGithubPullByUrl(\n sourceId: string,\n owner: string,\n repo: string,\n number: number,\n): Promise<UpsertResult> {\n const auth = _resolveGithubAuth();\n if (\"error\" in auth) throw new Error(auth.error);\n const pr = await _ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls/${number}`,\n ) as GhPull & { error?: string };\n if (pr.error) throw new Error(pr.error);\n const [comments, reviews] = await Promise.all([\n listIssueComments(auth, owner, repo, number),\n listReviews(auth, owner, repo, number),\n ]);\n const text = flattenPull(pr, comments, reviews);\n return upsertRemoteDocument(sourceId, {\n path: `github-pull://${owner}/${repo}/${number}`,\n title: `PR #${number}: ${pr.title ?? \"\"}`.trim(),\n externalUpdatedAt: pr.updated_at ?? new Date().toISOString(),\n text,\n });\n}\n\nexport async function indexGithubIssueByUrl(\n sourceId: string,\n owner: string,\n repo: string,\n number: number,\n): Promise<UpsertResult> {\n const auth = _resolveGithubAuth();\n if (\"error\" in auth) throw new Error(auth.error);\n const issue = await _ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/issues/${number}`,\n ) as GhIssue & { error?: string };\n if (issue.error) throw new Error(issue.error);\n const comments = await listIssueComments(auth, owner, repo, number);\n const text = flattenIssue(issue, comments);\n return upsertRemoteDocument(sourceId, {\n path: `github-issue://${owner}/${repo}/${number}`,\n title: `Issue #${number}: ${issue.title ?? \"\"}`.trim(),\n externalUpdatedAt: issue.updated_at ?? new Date().toISOString(),\n text,\n });\n}\n\nexport async function indexGithubFileByUrl(\n sourceId: string,\n owner: string,\n repo: string,\n ref: string,\n path: string,\n): Promise<UpsertResult> {\n const auth = _resolveGithubAuth();\n if (\"error\" in auth) throw new Error(auth.error);\n const contents = await _ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/contents/${path\n .split(\"/\").map(encodeURIComponent).join(\"/\")}?ref=${encodeURIComponent(ref)}`,\n ) as GhContents & { error?: string };\n if (contents.error) throw new Error(contents.error);\n if (contents.type !== \"file\" || !contents.content) {\n throw new Error(`github contents at ${path} is not a file`);\n }\n const buf = Buffer.from(contents.content.replace(/\\s+/g, \"\"), contents.encoding === \"base64\" ? \"base64\" : \"utf8\");\n if (isLikelyBinary(buf)) throw new Error(`github file ${path} appears to be binary`);\n return upsertRemoteDocument(sourceId, {\n path: `github-file://${owner}/${repo}@${ref}/${path}`,\n title: path,\n externalUpdatedAt: new Date().toISOString(),\n text: buf.toString(\"utf8\"),\n });\n}\n","// Remote document-source dispatcher (ADR-0026).\n//\n// `lib/documents/indexer.ts` walks local folders. For non-local kinds it\n// delegates to one of these per-kind handlers. Keeping the dispatcher tiny\n// (just a switch) keeps the local-folder happy path untouched.\n\nimport {\n createDocumentSource,\n getDocumentSourceByPath,\n markSourceScanned,\n type DocumentSourceRow,\n} from \"@/lib/stores/document-sources\";\nimport { runConfluenceIndexer, indexConfluencePageById } from \"./confluence\";\nimport { runMailIndexer } from \"./mail\";\nimport { runJiraIndexer, indexJiraIssueByKey } from \"./jira\";\nimport {\n runGithubIndexer,\n indexGithubPullByUrl,\n indexGithubIssueByUrl,\n indexGithubFileByUrl,\n} from \"./github\";\nimport type { UpsertResult } from \"./upsert\";\n\nexport interface RemoteIndexStats {\n scanned: number;\n added: number;\n updated: number;\n unchanged: number;\n errors: number;\n removed?: number;\n /** Total chunks across this run that didn't get an embedding vector. */\n embedFailed?: number;\n /** First embed error message seen, if any. */\n embedError?: string | null;\n}\n\n/** Returns true if `kind` is anything other than `local_folder`. */\nexport function isRemoteKind(kind: string): boolean {\n return kind !== \"local_folder\";\n}\n\nexport async function runRemoteSource(source: DocumentSourceRow): Promise<RemoteIndexStats> {\n let lastError: string | null = null;\n let stats: RemoteIndexStats = { scanned: 0, added: 0, updated: 0, unchanged: 0, errors: 0 };\n try {\n switch (source.kind) {\n case \"confluence_space\":\n case \"confluence_cql\": {\n const s = await runConfluenceIndexer(source);\n stats = s;\n break;\n }\n case \"jira_project\":\n case \"jira_jql\": {\n const s = await runJiraIndexer(source);\n stats = s;\n break;\n }\n case \"github_pulls\":\n case \"github_repo\": {\n const s = await runGithubIndexer(source);\n stats = s;\n break;\n }\n case \"gmail_mail\":\n case \"outlook_mail\": {\n const s = await runMailIndexer(source);\n stats = s;\n break;\n }\n case \"on_demand_url\":\n // No background sweep — items are added one-at-a-time via\n // indexOnDemand() from the tool / API surface.\n break;\n default:\n throw new Error(`unsupported remote source kind: ${source.kind}`);\n }\n } catch (err) {\n lastError = err instanceof Error ? err.message : String(err);\n stats.errors++;\n }\n // Mirror the local indexer's surfacing rule: a fetch error wins; otherwise\n // bubble up an embed-failure summary so the operator sees that semantic\n // search is degraded for this source without grepping logs.\n const embedFailed = stats.embedFailed ?? 0;\n const composite = lastError\n ? lastError\n : embedFailed > 0\n ? `${embedFailed} chunk${embedFailed === 1 ? \"\" : \"s\"} failed to embed${stats.embedError ? \": \" + stats.embedError : \"\"}`\n : null;\n markSourceScanned(source.id, composite);\n return stats;\n}\n\n/** Singleton \"on-demand URLs\" source row. Lazily created on first use. */\nconst ON_DEMAND_PATH = \"on-demand://urls\";\nexport function getOrCreateOnDemandSource(): DocumentSourceRow {\n const existing = getDocumentSourceByPath(ON_DEMAND_PATH);\n if (existing) return existing;\n return createDocumentSource({\n path: ON_DEMAND_PATH,\n label: \"On-demand URLs\",\n kind: \"on_demand_url\",\n config: null,\n });\n}\n\n/**\n * Resolve a free-form input (Jira issue key, Jira browse URL, Confluence\n * page URL, GitHub PR/issue/blob URL) to \"fetch this one thing and index\n * it under the on-demand source\". Surfaced via the `documents_index_url`\n * tool + HTTP API. ADR-0029 added the GitHub matchers.\n */\nexport async function indexOnDemand(input: string): Promise<{\n kind: \"jira\" | \"confluence\" | \"github\";\n identifier: string;\n result: UpsertResult;\n source_id: string;\n}> {\n const trimmed = input.trim();\n if (!trimmed) throw new Error(\"input is required\");\n const source = getOrCreateOnDemandSource();\n\n // Bare Jira key.\n const bareKey = /^[A-Z][A-Z0-9_]+-\\d+$/;\n if (bareKey.test(trimmed)) {\n const result = await indexJiraIssueByKey(source.id, trimmed);\n return { kind: \"jira\", identifier: trimmed, result, source_id: source.id };\n }\n // Jira /browse/<KEY>\n const browse = trimmed.match(/\\/browse\\/([A-Z][A-Z0-9_]+-\\d+)/);\n if (browse) {\n const result = await indexJiraIssueByKey(source.id, browse[1]);\n return { kind: \"jira\", identifier: browse[1], result, source_id: source.id };\n }\n // Confluence /wiki/spaces/.../pages/<id>\n const pages = trimmed.match(/\\/wiki\\/spaces\\/[^/]+\\/pages\\/(\\d+)/);\n if (pages) {\n const result = await indexConfluencePageById(source.id, pages[1]);\n return { kind: \"confluence\", identifier: pages[1], result, source_id: source.id };\n }\n // Confluence ?pageId=<id>\n const pageId = trimmed.match(/[?&]pageId=(\\d+)/);\n if (pageId) {\n const result = await indexConfluencePageById(source.id, pageId[1]);\n return { kind: \"confluence\", identifier: pageId[1], result, source_id: source.id };\n }\n // GitHub PR /pull/<n>\n const ghPull = trimmed.match(/^https?:\\/\\/github\\.com\\/([^/]+)\\/([^/]+)\\/pull\\/(\\d+)/);\n if (ghPull) {\n const [, owner, repo, n] = ghPull;\n const result = await indexGithubPullByUrl(source.id, owner, repo, Number(n));\n return { kind: \"github\", identifier: `${owner}/${repo}#${n}`, result, source_id: source.id };\n }\n // GitHub issue /issues/<n>\n const ghIssue = trimmed.match(/^https?:\\/\\/github\\.com\\/([^/]+)\\/([^/]+)\\/issues\\/(\\d+)/);\n if (ghIssue) {\n const [, owner, repo, n] = ghIssue;\n const result = await indexGithubIssueByUrl(source.id, owner, repo, Number(n));\n return { kind: \"github\", identifier: `${owner}/${repo}#${n}`, result, source_id: source.id };\n }\n // GitHub file /blob/<ref>/<path>\n const ghBlob = trimmed.match(/^https?:\\/\\/github\\.com\\/([^/]+)\\/([^/]+)\\/blob\\/([^/]+)\\/(.+)$/);\n if (ghBlob) {\n const [, owner, repo, ref, path] = ghBlob;\n const cleanPath = path.split(\"?\")[0].split(\"#\")[0];\n const result = await indexGithubFileByUrl(source.id, owner, repo, ref, cleanPath);\n return { kind: \"github\", identifier: `${owner}/${repo}@${ref}/${cleanPath}`, result, source_id: source.id };\n }\n\n throw new Error(\n \"could not recognise input — expected a Jira issue key (ABC-123), a /browse/<KEY> URL, \" +\n \"a Confluence /wiki/spaces/.../pages/<id> URL, or a GitHub /pull/<n>, /issues/<n>, or \" +\n \"/blob/<ref>/<path> URL.\",\n );\n}\n","// Cap a string at `maxBytes` UTF-8 bytes. Returns the original (and\n// truncated:false) when already under the cap. Counting bytes — not chars —\n// matters for emoji / CJK / accented characters where char-count would let\n// the payload double the byte budget.\nexport function truncateBytes(s: string, maxBytes: number): { text: string; truncated: boolean } {\n if (Buffer.byteLength(s, \"utf8\") <= maxBytes) return { text: s, truncated: false };\n\n // Slice by char until under the byte cap. Linear scan is fine for the\n // ~30KB caps we use; if a caller ever needs MB-scale truncation, swap for\n // a binary search.\n let end = s.length;\n while (end > 0 && Buffer.byteLength(s.slice(0, end), \"utf8\") > maxBytes) {\n end--;\n }\n return { text: s.slice(0, end), truncated: true };\n}\n","// JSON.parse with a fallback value when the input is malformed (or empty).\n// Used everywhere we read responses from external APIs — they're contractually\n// JSON but a transient 502 / proxy interstitial occasionally returns HTML.\nexport function parseJsonSafe<T>(text: string, fallback: T): T;\nexport function parseJsonSafe<T>(text: string): T | undefined;\nexport function parseJsonSafe<T>(text: string, fallback?: T): T | undefined {\n try {\n return JSON.parse(text) as T;\n } catch {\n return fallback;\n }\n}\n","// Ephemeral state store for in-app OAuth flows (Gmail, Microsoft, ...).\n//\n// Why this exists: the user types client_id + client_secret in the\n// Integrations panel, we POST to /oauth/start, stash them here keyed by a\n// random `state`, and return the provider's authorize URL. The browser\n// bounces back to /oauth/callback with `?code&state`, we exchange, and\n// persist the integration. Meanwhile the panel polls /oauth/status.\n//\n// Pinned to globalThis so HMR in dev doesn't lose pending flows.\n//\n// Same shape used by both gmail-oauth.ts and microsoft-oauth.ts — pass a\n// unique `globalKey` per provider so they don't share a Map.\n\nimport { randomBytes } from \"node:crypto\";\nimport { getOrCreateGlobal } from \"@/lib/utils/global-state\";\n\nexport interface OAuthFlow {\n createdAt: number;\n clientId: string;\n clientSecret: string;\n redirectUri: string;\n status: \"pending\" | \"done\" | \"error\";\n error?: string;\n}\n\nexport interface OAuthFlowStore {\n create(input: { clientId: string; clientSecret: string; redirectUri: string }): {\n state: string;\n flow: OAuthFlow;\n };\n get(state: string): OAuthFlow | undefined;\n update(state: string, patch: Partial<OAuthFlow>): void;\n delete(state: string): void;\n}\n\nconst DEFAULT_TTL_MS = 10 * 60 * 1000;\nconst DEFAULT_MAX_FLOWS = 32;\n\nexport function createOAuthFlowStore(opts: {\n globalKey: string;\n ttlMs?: number;\n maxFlows?: number;\n}): OAuthFlowStore {\n const ttlMs = opts.ttlMs ?? DEFAULT_TTL_MS;\n const maxFlows = opts.maxFlows ?? DEFAULT_MAX_FLOWS;\n const flows = getOrCreateGlobal<Map<string, OAuthFlow>>(opts.globalKey, () => new Map());\n\n function gc(): void {\n const now = Date.now();\n for (const [k, v] of flows) {\n if (now - v.createdAt > ttlMs) flows.delete(k);\n }\n // Hard cap so a stuck UI can't grow this unbounded.\n if (flows.size > maxFlows) {\n const oldest = [...flows.entries()].sort((a, b) => a[1].createdAt - b[1].createdAt);\n for (let i = 0; i < oldest.length - maxFlows; i++) flows.delete(oldest[i][0]);\n }\n }\n\n return {\n create(input) {\n gc();\n const state = randomBytes(16).toString(\"hex\");\n const flow: OAuthFlow = { createdAt: Date.now(), status: \"pending\", ...input };\n flows.set(state, flow);\n return { state, flow };\n },\n get(state) {\n gc();\n return flows.get(state);\n },\n update(state, patch) {\n const f = flows.get(state);\n if (f) Object.assign(f, patch);\n },\n delete(state) {\n flows.delete(state);\n },\n };\n}\n","/**\n * Native Atlassian tools (Jira + Confluence) — direct REST API calls, no MCP.\n *\n * Why this exists: corporate networks often block public PyPI/npm, which makes\n * the `mcp-atlassian` install path fragile. These tools just hit the Atlassian\n * REST API over HTTPS, which goes through the same proxy (EnvHttpProxyAgent)\n * the rest of the server uses — so they work anywhere a browser can reach\n * `*.atlassian.net`.\n *\n * Auth resolution (in priority order):\n * 1. Env: ATLASSIAN_URL, ATLASSIAN_EMAIL, ATLASSIAN_API_TOKEN\n * 2. Memory store: namespace=\"integrations\", key=\"atlassian\", value=\n * { url, email, api_token }\n *\n * The agent can populate option 2 via memory_write if the user shares the\n * credentials in chat — but most users will set env vars at server boot.\n */\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { getIntegrationRaw } from \"@/lib/stores/integrations\";\nimport { parseJsonSafe } from \"@/lib/utils/json\";\nimport { registerTools } from \"./registry\";\n\nexport interface AtlassianAuth {\n url: string; // e.g. \"https://your-team.atlassian.net\"\n email: string;\n apiToken: string;\n}\n\n// Exposed so the integrations test endpoint can probe the live API after save.\nexport function _resolveAtlassianAuth(): AtlassianAuth | { error: string } {\n return resolveAuth();\n}\n\nfunction resolveAuth(): AtlassianAuth | { error: string } {\n // Env first (deployment-level config, wins over per-user secrets stored in DB)\n const envUrl = process.env.ATLASSIAN_URL;\n const envEmail = process.env.ATLASSIAN_EMAIL;\n const envToken = process.env.ATLASSIAN_API_TOKEN;\n if (envUrl && envEmail && envToken) {\n return { url: stripTrailingSlash(envUrl), email: envEmail, apiToken: envToken };\n }\n // Saved integration creds (from the Integrations panel in the UI).\n const saved = getIntegrationRaw(\"atlassian\");\n if (saved?.url && saved.email && saved.api_token) {\n return { url: stripTrailingSlash(saved.url), email: saved.email, apiToken: saved.api_token };\n }\n return {\n error:\n \"Atlassian not configured. Open the gear menu → Integrations tab and add your Atlassian site URL, \" +\n \"email, and API token. (Or set ATLASSIAN_URL / ATLASSIAN_EMAIL / ATLASSIAN_API_TOKEN env vars.)\",\n };\n}\n\nfunction stripTrailingSlash(s: string): string { return s.replace(/\\/+$/, \"\"); }\n\nfunction authHeader(a: AtlassianAuth): string {\n return \"Basic \" + Buffer.from(`${a.email}:${a.apiToken}`).toString(\"base64\");\n}\n\n// Sibling-module accessor: the remote document-RAG indexers (lib/documents/\n// remote/{jira,confluence}.ts, ADR-0026) reuse the same proxy-aware fetch\n// wrapper + auth header so they don't duplicate the Atlassian REST plumbing.\n// Underscore prefix marks it as \"internal API, but reachable across modules\".\nexport async function _atlassianFetch(\n auth: AtlassianAuth,\n path: string,\n init?: RequestInit,\n): Promise<unknown> {\n return atlassianFetch(auth, path, init);\n}\n\nasync function atlassianFetch(\n auth: AtlassianAuth,\n path: string,\n init?: RequestInit,\n): Promise<unknown> {\n const url = path.startsWith(\"http\") ? path : `${auth.url}${path}`;\n const res = await fetch(url, {\n ...init,\n headers: {\n Authorization: authHeader(auth),\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\",\n ...(init?.headers ?? {}),\n },\n });\n const text = await res.text();\n if (!res.ok) {\n return { error: `Atlassian ${res.status}: ${text.slice(0, 500)}`, url };\n }\n return parseJsonSafe<unknown>(text, text);\n}\n\n// ── Jira tools ──────────────────────────────────────────────────────────────\n\nexport const jiraSearchTool = tool(\n async ({ jql, max_results, fields }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const limit = Math.min(max_results ?? 25, 100);\n const fieldList = fields ?? [\"summary\", \"status\", \"assignee\", \"priority\", \"created\", \"updated\"];\n // Atlassian removed /rest/api/3/search in 2025 (returns 410). The replacement\n // is /rest/api/3/search/jql — same JQL semantics, slightly different shape:\n // - POST body: { jql, fields: string[] | \"*all\", maxResults?, nextPageToken? }\n // - Response uses cursor-based `nextPageToken` instead of legacy offset.\n const data = await atlassianFetch(auth, `/rest/api/3/search/jql`, {\n method: \"POST\",\n body: JSON.stringify({ jql, maxResults: limit, fields: fieldList }),\n }) as { issues?: Array<Record<string, unknown>>; nextPageToken?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n issues: (data.issues ?? []).map((i: Record<string, unknown>) => ({\n key: i.key,\n url: `${auth.url}/browse/${i.key}`,\n summary: (i.fields as Record<string, unknown>)?.summary,\n status: ((i.fields as Record<string, unknown>)?.status as Record<string, unknown>)?.name,\n assignee: ((i.fields as Record<string, unknown>)?.assignee as Record<string, unknown>)?.displayName ?? null,\n priority: ((i.fields as Record<string, unknown>)?.priority as Record<string, unknown>)?.name ?? null,\n })),\n next_page_token: data.nextPageToken ?? null,\n });\n },\n {\n name: \"jira_search\",\n description:\n \"Search Jira issues using JQL. **PREFER THIS over shell-exec'ing the jira CLI** — this tool uses \" +\n \"the configured Atlassian credentials directly via REST. Returns key, summary, status, assignee. \" +\n \"JQL examples: 'assignee = currentUser() AND resolution = Unresolved', \" +\n \"'project = ABC AND status = \\\"In Progress\\\"', 'updated >= -7d ORDER BY updated DESC'.\",\n schema: z.object({\n jql: z.string().describe(\"JQL query string\"),\n max_results: z.number().optional().describe(\"Max issues (default 25, max 100)\"),\n fields: z.array(z.string()).optional().describe(\"Field names to fetch; defaults to common ones\"),\n }),\n },\n);\n\nexport const jiraGetIssueTool = tool(\n async ({ issue_key, expand, custom_fields, include_comments }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n\n let resolvedCustom: Array<{ input: string; id: string; name: string }> = [];\n if (custom_fields?.length) {\n const fieldList = await loadJiraFields(auth);\n if (!Array.isArray(fieldList)) return JSON.stringify(fieldList);\n const r = resolveCustomFieldNames(custom_fields, fieldList);\n if (r.unresolved.length) {\n const candidates = fieldList\n .filter((f) => f.custom)\n .slice(0, 25)\n .map((f) => `${f.name} (${f.id})`)\n .join(\"; \");\n return JSON.stringify({\n error: `unresolved custom_fields: ${r.unresolved.join(\", \")}. Pass either the customfield_NNNNN id or the exact display name.`,\n hint_first_25_custom_fields: candidates,\n });\n }\n resolvedCustom = r.resolved;\n }\n\n const expandSet = new Set(expand ?? []);\n if (resolvedCustom.length) {\n expandSet.add(\"names\");\n expandSet.add(\"renderedFields\");\n }\n const params: string[] = [];\n if (expandSet.size) params.push(`expand=${[...expandSet].join(\",\")}`);\n // Always pull issuelinks/subtasks/attachment/parent so callers see what's\n // attached to the issue without a follow-up call. Custom fields are\n // additive — when the caller asked for any, we explicitly enumerate the\n // base set + customs to keep the response shape stable.\n const baseFields = [\n \"summary\", \"description\", \"status\", \"issuetype\", \"priority\",\n \"assignee\", \"reporter\", \"created\", \"updated\", \"labels\", \"components\", \"comment\",\n \"issuelinks\", \"subtasks\", \"attachment\", \"parent\",\n ];\n if (resolvedCustom.length) {\n params.push(`fields=${[...baseFields, ...resolvedCustom.map((c) => c.id)].join(\",\")}`);\n } else {\n params.push(`fields=${baseFields.join(\",\")}`);\n }\n const qs = params.length ? `?${params.join(\"&\")}` : \"\";\n\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/issue/${encodeURIComponent(issue_key)}${qs}`,\n ) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n\n const f = (data.fields ?? {}) as Record<string, unknown>;\n const rendered = (data.renderedFields ?? {}) as Record<string, unknown>;\n\n const customOut: Record<string, unknown> = {};\n for (const c of resolvedCustom) {\n customOut[c.name] = extractFieldValue(f[c.id], rendered[c.id]);\n }\n\n // Issue links: each entry has an `id` (needed by jira_delete_link),\n // a type, and one of inwardIssue / outwardIssue depending on direction.\n const issueLinks = ((f.issuelinks as Array<Record<string, unknown>>) ?? []).map((l) => {\n const t = l.type as Record<string, unknown> | undefined;\n const inward = l.inwardIssue as Record<string, unknown> | undefined;\n const outward = l.outwardIssue as Record<string, unknown> | undefined;\n return {\n id: l.id,\n type: t?.name,\n direction: inward ? \"inward\" : \"outward\",\n verb: inward ? t?.inward : t?.outward,\n other_issue: inward\n ? { key: inward.key, summary: (inward.fields as Record<string, unknown>)?.summary }\n : outward\n ? { key: outward.key, summary: (outward.fields as Record<string, unknown>)?.summary }\n : null,\n };\n });\n\n // Remote/web links live under a separate endpoint — fetch in parallel\n // when requested (and if the issue actually has any) so we don't waste a\n // call on every get. Cheap heuristic: only fetch when the caller passed\n // include_remote_links, or always if expand contains \"remoteLinks\".\n let remoteLinks: Array<Record<string, unknown>> | undefined;\n if (expandSet.has(\"remoteLinks\")) {\n const rl = await atlassianFetch(\n auth,\n `/rest/api/3/issue/${encodeURIComponent(issue_key)}/remotelink`,\n ) as Array<Record<string, unknown>> | { error?: string };\n if (Array.isArray(rl)) {\n remoteLinks = rl.map((entry) => {\n const obj = entry.object as Record<string, unknown> | undefined;\n return { id: entry.id, url: obj?.url, title: obj?.title, summary: obj?.summary };\n });\n }\n }\n\n return JSON.stringify({\n key: data.key,\n url: `${auth.url}/browse/${data.key}`,\n summary: f.summary,\n description: simplifyADF(f.description),\n status: (f.status as Record<string, unknown>)?.name,\n type: (f.issuetype as Record<string, unknown>)?.name,\n priority: (f.priority as Record<string, unknown>)?.name,\n assignee: (f.assignee as Record<string, unknown>)?.displayName ?? null,\n reporter: (f.reporter as Record<string, unknown>)?.displayName ?? null,\n created: f.created,\n updated: f.updated,\n labels: f.labels,\n components: ((f.components as Array<Record<string, unknown>>) ?? []).map((c) => c.name),\n comments_count: ((f.comment as Record<string, unknown>)?.total) ?? 0,\n ...(include_comments ? {\n comments: (((f.comment as Record<string, unknown>)?.comments as Array<Record<string, unknown>>) ?? []).map((c) => ({\n id: c.id,\n author: (c.author as Record<string, unknown>)?.displayName ?? null,\n created: c.created,\n updated: c.updated,\n body: simplifyADF(c.body),\n })),\n } : {}),\n parent: f.parent ? {\n key: (f.parent as Record<string, unknown>).key,\n summary: ((f.parent as Record<string, unknown>).fields as Record<string, unknown>)?.summary,\n } : null,\n subtasks: ((f.subtasks as Array<Record<string, unknown>>) ?? []).map((s) => ({\n key: s.key,\n summary: (s.fields as Record<string, unknown>)?.summary,\n status: ((s.fields as Record<string, unknown>)?.status as Record<string, unknown>)?.name,\n })),\n issue_links: issueLinks,\n attachments: ((f.attachment as Array<Record<string, unknown>>) ?? []).map((a) => ({\n id: a.id,\n filename: a.filename,\n size: a.size,\n mime_type: a.mimeType,\n created: a.created,\n author: (a.author as Record<string, unknown>)?.displayName,\n content_url: a.content,\n })),\n ...(remoteLinks !== undefined ? { remote_links: remoteLinks } : {}),\n ...(resolvedCustom.length ? { custom_fields: customOut } : {}),\n });\n },\n {\n name: \"jira_get_issue\",\n description:\n \"Fetch a single Jira issue by key (e.g. 'PROJ-123'). Returns full detail including description, \" +\n \"parent, sub-tasks, issue_links (with link ids for jira_delete_link), and attachment metadata. \" +\n \"Pass `expand: ['remoteLinks']` to also fetch web/Confluence/GitHub links. \" +\n \"Pass `custom_fields` (display names like 'Vulnerability Description', or `customfield_NNNNN` ids) \" +\n \"to include them in the response under a `custom_fields` map. \" +\n \"Pass `include_comments: true` to include flattened comment bodies (author, timestamps, text). \" +\n \"ADF/rich-text is auto-flattened. \" +\n \"**PREFER THIS over shell-exec'ing the jira CLI.**\",\n schema: z.object({\n issue_key: z.string().describe(\"Issue key like PROJ-123\"),\n expand: z.array(z.string()).optional().describe(\"Fields to expand (e.g. ['changelog', 'transitions'])\"),\n custom_fields: z.array(z.string()).optional().describe(\n \"Custom field display names ('Vulnerability Description') or ids ('customfield_10473') to include\",\n ),\n include_comments: z.boolean().optional().describe(\n \"If true, include a `comments` array with author/created/updated/body for each comment. \" +\n \"Comments come from the same call (no extra API round-trip) but Jira caps the embedded list at ~50 — \" +\n \"use a follow-up call for issues with more.\",\n ),\n }),\n },\n);\n\nexport const jiraCreateIssueTool = tool(\n async ({ project_key, summary, description, issue_type, parent_key, labels, assignee_account_id, custom_fields }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const fields: Record<string, unknown> = {\n project: { key: project_key },\n summary,\n issuetype: { name: issue_type ?? \"Task\" },\n };\n if (description) fields.description = textToADF(description);\n if (parent_key) fields.parent = { key: parent_key };\n if (Array.isArray(labels)) fields.labels = labels;\n if (assignee_account_id) fields.assignee = { accountId: assignee_account_id };\n if (custom_fields && typeof custom_fields === \"object\" && Object.keys(custom_fields).length > 0) {\n const fieldList = await loadJiraFields(auth);\n if (!Array.isArray(fieldList)) return JSON.stringify(fieldList);\n const r = resolveCustomFieldNames(Object.keys(custom_fields), fieldList);\n if (r.unresolved.length) {\n return JSON.stringify({\n error: `unresolved custom_fields: ${r.unresolved.join(\", \")}`,\n hint_first_25_custom_fields: fieldList\n .filter((f) => f.custom).slice(0, 25)\n .map((f) => `${f.name} (${f.id})`).join(\"; \"),\n });\n }\n for (const c of r.resolved) {\n fields[c.id] = (custom_fields as Record<string, unknown>)[c.input];\n }\n }\n const data = await atlassianFetch(auth, `/rest/api/3/issue`, {\n method: \"POST\",\n body: JSON.stringify({ fields }),\n }) as { key?: string; id?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n key: data.key,\n url: data.key ? `${auth.url}/browse/${data.key}` : null,\n });\n },\n {\n name: \"jira_create_issue\",\n description:\n \"Create a new Jira issue. Defaults to issue_type='Task'. Pass parent_key to create a sub-task \" +\n \"or attach a Story to an Epic. Custom fields accept display names or customfield_NNNNN ids. \" +\n \"**PREFER THIS over shell-exec'ing the jira CLI.**\",\n schema: z.object({\n project_key: z.string().describe(\"Project key (e.g. 'ENG')\"),\n summary: z.string().describe(\"Issue title\"),\n description: z.string().optional().describe(\"Plain-text description (auto-converted to ADF)\"),\n issue_type: z.string().optional().describe(\"Issue type name (default: Task; valid: Task, Bug, Story, Epic, Sub-task, …)\"),\n parent_key: z.string().optional().describe(\n \"Parent issue key. Required for Sub-task issue types; also used to attach a Story/Task to an Epic.\",\n ),\n labels: z.array(z.string()).optional().describe(\"Labels to set on the new issue\"),\n assignee_account_id: z.string().optional().describe(\n \"Jira Cloud accountId to assign on creation (use jira_find_user to resolve)\",\n ),\n custom_fields: z.record(z.string(), z.unknown()).optional().describe(\n \"Map of custom field display names or customfield_NNNNN ids → values (e.g. { 'Due Date': '2026-06-15' })\",\n ),\n }),\n },\n);\n\nexport const jiraAddCommentTool = tool(\n async ({ issue_key, body }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await atlassianFetch(auth, `/rest/api/3/issue/${encodeURIComponent(issue_key)}/comment`, {\n method: \"POST\",\n body: JSON.stringify({ body: textToADF(body) }),\n }) as { id?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({ ok: true, comment_id: data.id });\n },\n {\n name: \"jira_add_comment\",\n description:\n \"Add a comment to a Jira issue. Plain text is auto-converted to ADF (Atlassian Document Format). \" +\n \"**PREFER THIS over shell-exec'ing the jira CLI.**\",\n schema: z.object({\n issue_key: z.string(),\n body: z.string().describe(\"Comment text (plain text, line breaks preserved)\"),\n }),\n },\n);\n\nexport const jiraFindUserTool = tool(\n async ({ query }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/user/search?query=${encodeURIComponent(query)}`,\n ) as Array<Record<string, unknown>> | { error?: string };\n if (!Array.isArray(data)) return JSON.stringify(data);\n return JSON.stringify({\n users: data.map((u) => ({\n account_id: u.accountId,\n display_name: u.displayName,\n email: u.emailAddress ?? null,\n active: u.active,\n })),\n });\n },\n {\n name: \"jira_find_user\",\n description:\n \"Look up Jira Cloud users by email or display-name fragment. Returns accountId values \" +\n \"you can pass to jira_update_issue's assignee_account_id. Use when you only have an email.\",\n schema: z.object({\n query: z.string().describe(\"Email address or partial display name\"),\n }),\n },\n);\n\nexport const jiraUpdateIssueTool = tool(\n async ({\n issue_key, summary, description, priority, assignee_account_id, assignee_email,\n fix_versions, labels, labels_add, labels_remove, custom_fields, parent_key,\n }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n\n const fields: Record<string, unknown> = {};\n const update: Record<string, Array<Record<string, unknown>>> = {};\n\n if (typeof summary === \"string\") fields.summary = summary;\n if (typeof description === \"string\") fields.description = textToADF(description);\n if (typeof priority === \"string\") fields.priority = { name: priority };\n if (typeof parent_key === \"string\") {\n // Empty string clears the parent (detach from epic / promote sub-task to standalone).\n fields.parent = parent_key.length > 0 ? { key: parent_key } : null;\n }\n if (Array.isArray(fix_versions)) fields.fixVersions = fix_versions.map((name) => ({ name }));\n if (Array.isArray(labels)) fields.labels = labels;\n\n // Custom fields: caller passes display names (\"Due Date\") or ids\n // (customfield_10015) → values. We resolve names → ids via the same\n // /rest/api/3/field cache jira_get_issue uses. Values are passed through\n // verbatim — Jira accepts strings, numbers, arrays, or full ADF docs\n // depending on the field's underlying type, and forcing one shape here\n // would break the others. The model already knows the field type from a\n // prior get_issue call (or an error message will steer it).\n if (custom_fields && typeof custom_fields === \"object\" && Object.keys(custom_fields).length > 0) {\n const inputs = Object.keys(custom_fields);\n const fieldList = await loadJiraFields(auth);\n if (!Array.isArray(fieldList)) return JSON.stringify(fieldList);\n const r = resolveCustomFieldNames(inputs, fieldList);\n if (r.unresolved.length) {\n return JSON.stringify({\n error: `unresolved custom_fields: ${r.unresolved.join(\", \")}. Pass either the customfield_NNNNN id or the exact display name.`,\n hint_first_25_custom_fields: fieldList\n .filter((f) => f.custom)\n .slice(0, 25)\n .map((f) => `${f.name} (${f.id})`)\n .join(\"; \"),\n });\n }\n for (const c of r.resolved) {\n fields[c.id] = (custom_fields as Record<string, unknown>)[c.input];\n }\n }\n\n if (Array.isArray(labels_add) || Array.isArray(labels_remove)) {\n const ops: Array<Record<string, string>> = [];\n for (const l of labels_add ?? []) ops.push({ add: l });\n for (const l of labels_remove ?? []) ops.push({ remove: l });\n if (ops.length) update.labels = ops;\n }\n\n // Assignee: explicit accountId wins; otherwise resolve email; \"unassigned\" / null clears.\n if (assignee_account_id !== undefined) {\n const v = assignee_account_id;\n if (v === null || v === \"\" || v === \"unassigned\") {\n fields.assignee = { accountId: null };\n } else {\n fields.assignee = { accountId: v };\n }\n } else if (typeof assignee_email === \"string\" && assignee_email.length > 0) {\n if (assignee_email === \"unassigned\") {\n fields.assignee = { accountId: null };\n } else {\n const users = await atlassianFetch(\n auth,\n `/rest/api/3/user/search?query=${encodeURIComponent(assignee_email)}`,\n ) as Array<{ accountId?: string; emailAddress?: string }> | { error?: string };\n if (!Array.isArray(users)) return JSON.stringify(users);\n // Prefer exact email match (case-insensitive); fall back to single result.\n const exact = users.find(\n (u) => (u.emailAddress ?? \"\").toLowerCase() === assignee_email.toLowerCase(),\n );\n const picked = exact ?? (users.length === 1 ? users[0] : undefined);\n if (!picked?.accountId) {\n return JSON.stringify({\n error: `could not resolve assignee_email \"${assignee_email}\" — got ${users.length} matches; ` +\n `pass assignee_account_id explicitly`,\n candidates: users.map((u) => ({ email: u.emailAddress, account_id: u.accountId })),\n });\n }\n fields.assignee = { accountId: picked.accountId };\n }\n }\n\n if (Object.keys(fields).length === 0 && Object.keys(update).length === 0) {\n return JSON.stringify({ error: \"no fields to update — pass at least one of summary, description, priority, assignee_*, fix_versions, labels, labels_add, labels_remove, parent_key, custom_fields\" });\n }\n\n const body: Record<string, unknown> = {};\n if (Object.keys(fields).length) body.fields = fields;\n if (Object.keys(update).length) body.update = update;\n\n const data = await atlassianFetch(auth, `/rest/api/3/issue/${encodeURIComponent(issue_key)}`, {\n method: \"PUT\",\n body: JSON.stringify(body),\n }) as { error?: string } | string;\n // Successful PUT returns 204 No Content → atlassianFetch returns \"\" (parsed as string).\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n key: issue_key,\n url: `${auth.url}/browse/${issue_key}`,\n updated_fields: [...Object.keys(fields), ...Object.keys(update).map((k) => `${k}(±)`)],\n });\n },\n {\n name: \"jira_update_issue\",\n description:\n \"Edit fields on an existing Jira issue: summary, description, priority, assignee, fix versions, \" +\n \"labels, and arbitrary custom fields (including 'Due Date' and 'Story Points' on sites where \" +\n \"those are custom). Pass only the fields you want to change. Description is auto-converted from \" +\n \"plain text to ADF. Labels support either full replace (`labels`) or incremental \" +\n \"`labels_add`/`labels_remove`. Assignee can be set by `assignee_account_id` or by \" +\n \"`assignee_email` (auto-resolved); pass null/\\\"unassigned\\\" to clear. Custom fields accept \" +\n \"display names ('Due Date') or ids ('customfield_10015'); values are passed through verbatim \" +\n \"(string for date/text, number for numeric, full ADF object for rich-text custom fields). \" +\n \"**PREFER THIS over shell-exec'ing the jira CLI.** Disable to make the agent read-only.\",\n schema: z.object({\n issue_key: z.string().describe(\"Issue key like PROJ-123\"),\n summary: z.string().optional().describe(\"New issue title\"),\n description: z.string().optional().describe(\n \"Plain-text description (auto-converted to ADF). Replaces existing description.\",\n ),\n priority: z.string().optional().describe(\"Priority name (e.g. 'High', 'Medium', 'Low')\"),\n assignee_account_id: z.string().nullable().optional().describe(\n \"Jira Cloud accountId; null or 'unassigned' clears assignee\",\n ),\n assignee_email: z.string().optional().describe(\n \"Email to resolve via /user/search; alternative to assignee_account_id\",\n ),\n fix_versions: z.array(z.string()).optional().describe(\n \"Replace fix versions with these names (empty array clears all)\",\n ),\n labels: z.array(z.string()).optional().describe(\n \"Replace labels entirely with this set (empty array clears all)\",\n ),\n labels_add: z.array(z.string()).optional().describe(\"Labels to add (incremental)\"),\n labels_remove: z.array(z.string()).optional().describe(\"Labels to remove (incremental)\"),\n parent_key: z.string().optional().describe(\n \"Reparent: pass a parent issue key to attach this issue to (Epic key for Stories, Story/Task key for Sub-tasks). Pass an empty string to detach from the current parent.\",\n ),\n custom_fields: z.record(z.string(), z.unknown()).optional().describe(\n \"Map of custom field display names or customfield_NNNNN ids → values. \" +\n \"Examples: { \\\"Due Date\\\": \\\"2026-06-15\\\", \\\"Story Points\\\": 8 }. \" +\n \"For rich-text custom fields, pass a full ADF document as the value.\",\n ),\n }),\n },\n);\n\nexport const jiraTransitionsTool = tool(\n async ({ issue_key, transition_name }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n // Step 1: list available transitions for this issue.\n const list = await atlassianFetch(auth, `/rest/api/3/issue/${encodeURIComponent(issue_key)}/transitions`) as { transitions?: Array<{ id: string; name: string }>; error?: string };\n if (list.error) return JSON.stringify(list);\n if (!transition_name) {\n return JSON.stringify({ available_transitions: (list.transitions ?? []).map((t) => t.name) });\n }\n const match = (list.transitions ?? []).find((t) => t.name.toLowerCase() === transition_name.toLowerCase());\n if (!match) {\n return JSON.stringify({\n error: `transition \"${transition_name}\" not available for ${issue_key}`,\n available: (list.transitions ?? []).map((t) => t.name),\n });\n }\n const data = await atlassianFetch(auth, `/rest/api/3/issue/${encodeURIComponent(issue_key)}/transitions`, {\n method: \"POST\",\n body: JSON.stringify({ transition: { id: match.id } }),\n }) as { error?: string };\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, transitioned_to: match.name });\n },\n {\n name: \"jira_transition_issue\",\n description:\n \"Transition a Jira issue's status (e.g. 'In Progress' → 'Done'). \" +\n \"Call without transition_name to list available transitions for the issue. \" +\n \"**PREFER THIS over shell-exec'ing the jira CLI.**\",\n schema: z.object({\n issue_key: z.string(),\n transition_name: z.string().optional().describe(\"Name of the transition (case-insensitive). Omit to list.\"),\n }),\n },\n);\n\nexport const jiraLinkIssuesTool = tool(\n async ({ from_issue, to_issue, link_type, comment }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n\n // Step 1: load global link types and resolve the requested name. Same\n // \"omit to list\" pattern as jira_transition_issue — agents can probe this\n // tool to discover what's available without a separate list endpoint.\n const list = await atlassianFetch(auth, `/rest/api/3/issueLinkType`) as\n | { issueLinkTypes?: Array<{ id: string; name: string; inward: string; outward: string }>; error?: string };\n if (\"error\" in list && list.error) return JSON.stringify(list);\n const types = list.issueLinkTypes ?? [];\n if (!link_type || !from_issue || !to_issue) {\n return JSON.stringify({\n available_link_types: types.map((t) => ({ name: t.name, outward: t.outward, inward: t.inward })),\n usage: \"Pass from_issue, to_issue, and link_type (e.g. 'Blocks'). The link reads as: '<from_issue> <outward verb> <to_issue>'.\",\n });\n }\n const wanted = link_type.toLowerCase();\n const match = types.find((t) => t.name.toLowerCase() === wanted);\n if (!match) {\n return JSON.stringify({\n error: `link_type \"${link_type}\" not configured for this site`,\n available: types.map((t) => t.name),\n });\n }\n\n // Jira's outwardIssue is the SOURCE (subject of the outward verb), inwardIssue\n // is the TARGET. So `{from: A, to: B, type: \"Blocks\"}` reads as \"A blocks B\".\n const body: Record<string, unknown> = {\n type: { name: match.name },\n outwardIssue: { key: from_issue },\n inwardIssue: { key: to_issue },\n };\n if (typeof comment === \"string\" && comment.length > 0) {\n body.comment = { body: textToADF(comment) };\n }\n\n const data = await atlassianFetch(auth, `/rest/api/3/issueLink`, {\n method: \"POST\",\n body: JSON.stringify(body),\n }) as { error?: string } | string;\n // Successful POST returns 201 Created with empty body → \"\" (string).\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n reads_as: `${from_issue} ${match.outward} ${to_issue}`,\n from: { key: from_issue, url: `${auth.url}/browse/${from_issue}` },\n to: { key: to_issue, url: `${auth.url}/browse/${to_issue}` },\n link_type: match.name,\n });\n },\n {\n name: \"jira_link_issues\",\n description:\n \"Create an issue link between two Jira issues (Blocks, Relates, Duplicates, Cloners, etc.). \" +\n \"The link reads left-to-right: 'from_issue <outward verb> to_issue'. For example, \" +\n \"{ from_issue: 'A-1', to_issue: 'B-2', link_type: 'Blocks' } means 'A-1 blocks B-2' \" +\n \"(and 'B-2 is blocked by A-1' shows on the other side automatically). \" +\n \"Call without arguments to list available link types for the site. \" +\n \"**PREFER THIS over shell-exec'ing the jira CLI or hitting REST directly.** Disable to make the agent read-only.\",\n schema: z.object({\n from_issue: z.string().optional().describe(\"Source issue key (subject of the outward verb), e.g. 'PROJ-1'\"),\n to_issue: z.string().optional().describe(\"Target issue key (object of the outward verb), e.g. 'PROJ-2'\"),\n link_type: z.string().optional().describe(\n \"Link type name, case-insensitive (e.g. 'Blocks', 'Relates', 'Duplicates'). Omit to list available types.\",\n ),\n comment: z.string().optional().describe(\n \"Optional plain-text comment posted to the from_issue alongside the link\",\n ),\n }),\n },\n);\n\n// Shape for one issue inside a bulk-create payload. Mirrors the create tool's\n// schema so callers building one off a loop don't have to re-learn fields.\nconst bulkIssueSchema = z.object({\n project_key: z.string(),\n summary: z.string(),\n description: z.string().optional(),\n issue_type: z.string().optional(),\n parent_key: z.string().optional(),\n labels: z.array(z.string()).optional(),\n assignee_account_id: z.string().optional(),\n custom_fields: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport const jiraCreateIssuesBulkTool = tool(\n async ({ issues }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (!issues?.length) return JSON.stringify({ error: \"issues array is empty\" });\n if (issues.length > 50) return JSON.stringify({ error: `bulk endpoint accepts up to 50 per call (got ${issues.length})` });\n\n // Custom fields: do ONE field-cache load if any issue uses them, then\n // resolve names → ids per-issue. Bulk creates that share custom fields\n // (the common case) thus only pay the cache cost once.\n let fieldList: JiraFieldDef[] | undefined;\n const anyCustom = issues.some((i) => i.custom_fields && Object.keys(i.custom_fields).length > 0);\n if (anyCustom) {\n const loaded = await loadJiraFields(auth);\n if (!Array.isArray(loaded)) return JSON.stringify(loaded);\n fieldList = loaded;\n }\n\n const issueUpdates: Array<{ fields: Record<string, unknown> }> = [];\n for (const i of issues) {\n const fields: Record<string, unknown> = {\n project: { key: i.project_key },\n summary: i.summary,\n issuetype: { name: i.issue_type ?? \"Task\" },\n };\n if (i.description) fields.description = textToADF(i.description);\n if (i.parent_key) fields.parent = { key: i.parent_key };\n if (Array.isArray(i.labels)) fields.labels = i.labels;\n if (i.assignee_account_id) fields.assignee = { accountId: i.assignee_account_id };\n if (i.custom_fields && fieldList) {\n const r = resolveCustomFieldNames(Object.keys(i.custom_fields), fieldList);\n if (r.unresolved.length) {\n return JSON.stringify({ error: `unresolved custom_fields on \"${i.summary}\": ${r.unresolved.join(\", \")}` });\n }\n for (const c of r.resolved) {\n fields[c.id] = (i.custom_fields as Record<string, unknown>)[c.input];\n }\n }\n issueUpdates.push({ fields });\n }\n\n const data = await atlassianFetch(auth, `/rest/api/3/issue/bulk`, {\n method: \"POST\",\n body: JSON.stringify({ issueUpdates }),\n }) as {\n issues?: Array<{ key?: string; id?: string }>;\n errors?: Array<{ status: number; elementErrors: { errors?: Record<string, string> } }>;\n error?: string;\n };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n created: (data.issues ?? []).map((i) => ({\n key: i.key,\n url: i.key ? `${auth.url}/browse/${i.key}` : null,\n })),\n errors: data.errors ?? [],\n });\n },\n {\n name: \"jira_create_issues_bulk\",\n description:\n \"Create up to 50 Jira issues in a single API call. Each entry takes the same shape as \" +\n \"jira_create_issue (project_key, summary, description, issue_type, parent_key, labels, \" +\n \"assignee_account_id, custom_fields). Returns per-issue keys plus any partial errors. \" +\n \"**PREFER THIS over many sequential jira_create_issue calls** when creating ≥3 tickets.\",\n schema: z.object({\n issues: z.array(bulkIssueSchema).describe(\"Array of issues to create (1–50)\"),\n }),\n },\n);\n\nexport const jiraAddRemoteLinkTool = tool(\n async ({ issue_key, url, title, summary, icon_url, global_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const body: Record<string, unknown> = {\n object: {\n url,\n title,\n ...(summary ? { summary } : {}),\n ...(icon_url ? { icon: { url16x16: icon_url } } : {}),\n },\n };\n // globalId is what makes a remote link idempotent — repeat-posting with\n // the same globalId updates the existing link instead of creating a dup.\n if (global_id) body.globalId = global_id;\n\n const data = await atlassianFetch(auth, `/rest/api/3/issue/${encodeURIComponent(issue_key)}/remotelink`, {\n method: \"POST\",\n body: JSON.stringify(body),\n }) as { id?: number; self?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n remote_link_id: data.id,\n issue: { key: issue_key, url: `${auth.url}/browse/${issue_key}` },\n target: { url, title },\n });\n },\n {\n name: \"jira_add_remote_link\",\n description:\n \"Attach a web/external link to a Jira issue (Confluence pages, GitHub PRs, dashboards, Slack threads, \" +\n \"any URL). Distinct from jira_link_issues, which links one Jira issue to another. \" +\n \"Pass `global_id` to make the link idempotent — re-posting with the same global_id updates the \" +\n \"existing link rather than creating a duplicate. **PREFER THIS over pasting URLs into the description.**\",\n schema: z.object({\n issue_key: z.string().describe(\"Issue to attach the link to\"),\n url: z.string().describe(\"Target URL\"),\n title: z.string().describe(\"Link title shown in Jira's 'web links' panel\"),\n summary: z.string().optional().describe(\"Optional one-line description shown under the title\"),\n icon_url: z.string().optional().describe(\"Optional 16×16 icon URL\"),\n global_id: z.string().optional().describe(\n \"Optional stable identifier for idempotent upserts (e.g. 'github-pr-1234'). Re-posting with the same value updates the existing link.\",\n ),\n }),\n },\n);\n\nexport const jiraDeleteLinkTool = tool(\n async ({ link_id, link_type, kind }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (!link_id) return JSON.stringify({ error: \"link_id is required (look up via jira_get_issue → issue_links[].id or remote_links[].id)\" });\n\n // \"issue\" = link between two Jira issues (DELETE /issueLink/{id})\n // \"remote\" = link to an external URL (DELETE /issue/{key}/remotelink/{id})\n // Caller must specify because the same numeric id can exist in both spaces.\n if (kind === \"remote\") {\n if (!link_type) {\n return JSON.stringify({ error: \"for kind='remote', pass link_type as the issue key (the link is scoped to an issue)\" });\n }\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/issue/${encodeURIComponent(link_type)}/remotelink/${encodeURIComponent(link_id)}`,\n { method: \"DELETE\" },\n ) as { error?: string } | string;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, deleted: { kind: \"remote\", link_id, issue_key: link_type } });\n }\n\n const data = await atlassianFetch(auth, `/rest/api/3/issueLink/${encodeURIComponent(link_id)}`, {\n method: \"DELETE\",\n }) as { error?: string } | string;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, deleted: { kind: \"issue\", link_id } });\n },\n {\n name: \"jira_delete_link\",\n description:\n \"Delete an issue link (Jira-to-Jira, default) or a remote/web link. Look up the id first with \" +\n \"jira_get_issue (issue_links[].id or remote_links[].id — pass `expand: ['remoteLinks']` for the latter). \" +\n \"For remote links, also pass the issue key as `link_type` since the API is scoped per-issue.\",\n schema: z.object({\n link_id: z.string().describe(\"Numeric link id from jira_get_issue\"),\n kind: z.enum([\"issue\", \"remote\"]).optional().describe(\n \"'issue' (default) for Jira-to-Jira links, 'remote' for web/external URL links\",\n ),\n link_type: z.string().optional().describe(\n \"When kind='remote', the issue key the remote link is attached to (required by Jira's per-issue endpoint)\",\n ),\n }),\n },\n);\n\nexport const jiraUploadAttachmentTool = tool(\n async ({ issue_key, filename, content_base64, content_text }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (!content_base64 && !content_text) {\n return JSON.stringify({ error: \"pass either content_base64 (binary) or content_text (UTF-8)\" });\n }\n\n const buf = content_base64\n ? Buffer.from(content_base64, \"base64\")\n : Buffer.from(content_text!, \"utf8\");\n\n // Jira attachment uploads require X-Atlassian-Token: no-check (CSRF\n // bypass) and multipart/form-data. node's built-in FormData + Blob (Node\n // 22+) handle the body shape; fetch sets the multipart boundary.\n const form = new FormData();\n form.append(\"file\", new Blob([buf]), filename);\n\n const url = `${auth.url}/rest/api/3/issue/${encodeURIComponent(issue_key)}/attachments`;\n const res = await fetch(url, {\n method: \"POST\",\n headers: {\n Authorization: authHeader(auth),\n Accept: \"application/json\",\n \"X-Atlassian-Token\": \"no-check\",\n // Do NOT set Content-Type — fetch fills in the multipart boundary.\n },\n body: form,\n });\n const text = await res.text();\n if (!res.ok) return JSON.stringify({ error: `Atlassian ${res.status}: ${text.slice(0, 500)}` });\n const parsed = parseJsonSafe<Array<{ id: string; filename: string; size: number; mimeType: string; content: string }>>(text, []);\n return JSON.stringify({\n ok: true,\n issue: { key: issue_key, url: `${auth.url}/browse/${issue_key}` },\n attachments: parsed.map((a) => ({\n id: a.id,\n filename: a.filename,\n size: a.size,\n mime_type: a.mimeType,\n content_url: a.content,\n })),\n });\n },\n {\n name: \"jira_upload_attachment\",\n description:\n \"Upload a file as an attachment to a Jira issue. Pass content_base64 for binary files (PNG, PDF, \" +\n \"ZIP, etc.) or content_text for plain UTF-8 text (logs, CSVs, JSON). The agent itself reads/encodes \" +\n \"the source file — this tool only handles the upload. **PREFER THIS over pasting file contents into \" +\n \"a comment.** Disable to make the agent unable to add attachments.\",\n schema: z.object({\n issue_key: z.string().describe(\"Issue to attach to\"),\n filename: z.string().describe(\"Filename shown in Jira (include the extension)\"),\n content_base64: z.string().optional().describe(\"Base64-encoded file contents (use for binary)\"),\n content_text: z.string().optional().describe(\"Raw UTF-8 text contents (use for logs/CSVs/JSON)\"),\n }),\n },\n);\n\nexport const jiraDeleteIssueTool = tool(\n async ({ issue_key, delete_subtasks }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const qs = delete_subtasks ? `?deleteSubtasks=true` : \"\";\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/issue/${encodeURIComponent(issue_key)}${qs}`,\n { method: \"DELETE\" },\n ) as { error?: string } | string;\n // Successful DELETE returns 204 No Content → atlassianFetch returns \"\" (parsed as string).\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, deleted: issue_key });\n },\n {\n name: \"jira_delete_issue\",\n description:\n \"Permanently delete a Jira issue. **DESTRUCTIVE — there is no undo from the API.** By default, \" +\n \"Jira refuses to delete an issue that has sub-tasks; pass delete_subtasks=true to delete them too. \" +\n \"Disable this tool entirely to make the agent unable to delete tickets.\",\n schema: z.object({\n issue_key: z.string().describe(\"Issue to delete\"),\n delete_subtasks: z.boolean().optional().describe(\n \"If true, also delete all sub-tasks. Required when the issue has sub-tasks; otherwise Jira returns 400.\",\n ),\n }),\n },\n);\n\n// ── Jira agile tools ────────────────────────────────────────────────────────\n//\n// Sprint/board/backlog/rank lives at `/rest/agile/1.0/...`, NOT `/rest/api/3/`.\n// Same hostname + same Basic auth as the platform API, so atlassianFetch works\n// unchanged — only the path family differs. See ADR-0035.\n//\n// Sprint state machine: future → active → closed (one-way). Atlassian rejects\n// other transitions server-side, but we validate client-side too so the agent\n// gets a clean error with the list of legal next states instead of a 400.\n\nconst SPRINT_STATES = [\"future\", \"active\", \"closed\"] as const;\ntype SprintState = (typeof SPRINT_STATES)[number];\n\n// Pure — exported for tests. Returns the state argument shape Atlassian's\n// `POST /sprint/{id}` accepts, or an error if the transition is illegal.\nexport function validateSprintTransition(\n current: string | undefined,\n target: SprintState,\n): { ok: true } | { error: string } {\n if (target === \"future\") {\n return { error: \"cannot transition a sprint back to 'future' once created\" };\n }\n if (current === \"closed\") {\n return { error: \"sprint is already closed; no further transitions allowed\" };\n }\n if (target === \"active\" && current && current !== \"future\") {\n return { error: `cannot start a sprint in state '${current}' — only 'future' sprints can be started` };\n }\n if (target === \"closed\" && current && current !== \"active\") {\n return { error: `cannot complete a sprint in state '${current}' — only 'active' sprints can be completed` };\n }\n return { ok: true };\n}\n\nexport const jiraListBoardsTool = tool(\n async ({ project, name, type, max_results }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const params = new URLSearchParams();\n if (project) params.set(\"projectKeyOrId\", project);\n if (name) params.set(\"name\", name);\n if (type) params.set(\"type\", type);\n params.set(\"maxResults\", String(Math.min(max_results ?? 50, 100)));\n const data = await atlassianFetch(auth, `/rest/agile/1.0/board?${params}`) as\n | { values?: Array<Record<string, unknown>>; isLast?: boolean; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n boards: (data.values ?? []).map((b) => ({\n id: b.id,\n name: b.name,\n type: b.type,\n project_key: ((b.location as Record<string, unknown>)?.projectKey) ?? null,\n })),\n is_last: data.isLast ?? null,\n });\n },\n {\n name: \"jira_list_boards\",\n description:\n \"List Jira agile boards (Scrum or Kanban). Filter by project key, name fragment, or board type. \" +\n \"Returns id, name, type, project_key. Use the id with jira_list_sprints / jira_get_backlog / etc.\",\n schema: z.object({\n project: z.string().optional().describe(\"Project key or id to filter by\"),\n name: z.string().optional().describe(\"Board name fragment (case-insensitive contains-match)\"),\n type: z.enum([\"scrum\", \"kanban\", \"simple\"]).optional(),\n max_results: z.number().optional().describe(\"Default 50, max 100\"),\n }),\n },\n);\n\nexport const jiraGetBoardTool = tool(\n async ({ board_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n // Two calls in parallel — board metadata + configuration. The configuration\n // endpoint is what reveals estimation field, sub-query, ranking field, etc.,\n // which the agent often needs alongside the basic board info.\n const [meta, config] = await Promise.all([\n atlassianFetch(auth, `/rest/agile/1.0/board/${encodeURIComponent(board_id)}`),\n atlassianFetch(auth, `/rest/agile/1.0/board/${encodeURIComponent(board_id)}/configuration`),\n ]) as [Record<string, unknown> & { error?: string }, Record<string, unknown> & { error?: string }];\n if (meta.error) return JSON.stringify(meta);\n return JSON.stringify({\n id: meta.id,\n name: meta.name,\n type: meta.type,\n project_key: ((meta.location as Record<string, unknown>)?.projectKey) ?? null,\n configuration: config.error ? null : {\n filter_id: ((config.filter as Record<string, unknown>)?.id) ?? null,\n sub_query: ((config.subQuery as Record<string, unknown>)?.query) ?? null,\n estimation_field: ((config.estimation as Record<string, unknown>)?.field as Record<string, unknown>)?.fieldId ?? null,\n ranking_field: ((config.ranking as Record<string, unknown>)?.rankCustomFieldId) ?? null,\n },\n });\n },\n {\n name: \"jira_get_board\",\n description:\n \"Fetch board metadata and configuration in one call: id, name, type, project_key, plus filter id, \" +\n \"sub-query JQL, estimation field, and ranking custom field. Use this when you need to know how \" +\n \"issues are estimated or ranked on a specific board.\",\n schema: z.object({\n board_id: z.union([z.string(), z.number()]).describe(\"Board id from jira_list_boards\"),\n }),\n },\n);\n\nexport const jiraListSprintsTool = tool(\n async ({ board_id, state, max_results }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const params = new URLSearchParams();\n if (state) params.set(\"state\", state);\n params.set(\"maxResults\", String(Math.min(max_results ?? 50, 100)));\n const data = await atlassianFetch(\n auth,\n `/rest/agile/1.0/board/${encodeURIComponent(board_id)}/sprint?${params}`,\n ) as { values?: Array<Record<string, unknown>>; isLast?: boolean; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n sprints: (data.values ?? []).map((s) => ({\n id: s.id,\n name: s.name,\n state: s.state,\n goal: s.goal ?? null,\n start_date: s.startDate ?? null,\n end_date: s.endDate ?? null,\n complete_date: s.completeDate ?? null,\n origin_board_id: s.originBoardId ?? null,\n })),\n is_last: data.isLast ?? null,\n });\n },\n {\n name: \"jira_list_sprints\",\n description:\n \"List sprints on a board. Filter by state ('active', 'closed', 'future'). Returns sprint id, name, \" +\n \"state, goal, dates, origin_board_id. To list issues IN a sprint, use jira_search with \" +\n \"JQL `sprint = {id}` — that's faster and supports custom field selection.\",\n schema: z.object({\n board_id: z.union([z.string(), z.number()]),\n state: z.enum([\"active\", \"closed\", \"future\"]).optional().describe(\"Comma in API but tool takes one state\"),\n max_results: z.number().optional().describe(\"Default 50, max 100\"),\n }),\n },\n);\n\nexport const jiraGetSprintTool = tool(\n async ({ sprint_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await atlassianFetch(auth, `/rest/agile/1.0/sprint/${encodeURIComponent(sprint_id)}`) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n id: data.id,\n name: data.name,\n state: data.state,\n goal: data.goal ?? null,\n start_date: data.startDate ?? null,\n end_date: data.endDate ?? null,\n complete_date: data.completeDate ?? null,\n origin_board_id: data.originBoardId ?? null,\n });\n },\n {\n name: \"jira_get_sprint\",\n description:\n \"Fetch a single sprint by id. Returns name, state, goal, start/end/complete dates. Use jira_search \" +\n \"with `sprint = {id}` to list its issues.\",\n schema: z.object({ sprint_id: z.union([z.string(), z.number()]) }),\n },\n);\n\nexport const jiraCreateSprintTool = tool(\n async ({ board_id, name, goal, start_date, end_date }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const body: Record<string, unknown> = { originBoardId: Number(board_id), name };\n if (goal) body.goal = goal;\n if (start_date) body.startDate = start_date;\n if (end_date) body.endDate = end_date;\n const data = await atlassianFetch(auth, `/rest/agile/1.0/sprint`, {\n method: \"POST\",\n body: JSON.stringify(body),\n }) as { id?: number; self?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({ ok: true, sprint_id: data.id, board_id });\n },\n {\n name: \"jira_create_sprint\",\n description:\n \"Create a future sprint on a board. New sprints always start in 'future' state — use \" +\n \"jira_update_sprint with state='active' to start it. start_date/end_date are ISO 8601 strings; \" +\n \"they're optional but required by Atlassian before you can start the sprint.\",\n schema: z.object({\n board_id: z.union([z.string(), z.number()]).describe(\"Origin board id\"),\n name: z.string().describe(\"Sprint name\"),\n goal: z.string().optional(),\n start_date: z.string().optional().describe(\"ISO 8601 timestamp\"),\n end_date: z.string().optional().describe(\"ISO 8601 timestamp\"),\n }),\n },\n);\n\nexport const jiraUpdateSprintTool = tool(\n async ({ sprint_id, name, goal, start_date, end_date, state }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n\n if (state) {\n // Validate transition client-side. Fetch current state for a clean error.\n const current = await atlassianFetch(\n auth,\n `/rest/agile/1.0/sprint/${encodeURIComponent(sprint_id)}`,\n ) as { state?: string; error?: string };\n if (current.error) return JSON.stringify(current);\n const check = validateSprintTransition(current.state, state);\n if (\"error\" in check) {\n return JSON.stringify({\n error: check.error,\n current_state: current.state,\n legal_next_states: SPRINT_STATES.filter(\n (s) => !(\"error\" in validateSprintTransition(current.state, s)),\n ),\n });\n }\n }\n\n const body: Record<string, unknown> = {};\n if (name !== undefined) body.name = name;\n if (goal !== undefined) body.goal = goal;\n if (start_date !== undefined) body.startDate = start_date;\n if (end_date !== undefined) body.endDate = end_date;\n if (state !== undefined) body.state = state;\n if (Object.keys(body).length === 0) {\n return JSON.stringify({ error: \"no fields to update — pass at least one of name, goal, start_date, end_date, state\" });\n }\n\n const data = await atlassianFetch(auth, `/rest/agile/1.0/sprint/${encodeURIComponent(sprint_id)}`, {\n method: \"POST\",\n body: JSON.stringify(body),\n }) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n sprint_id,\n state: data.state,\n updated_fields: Object.keys(body),\n });\n },\n {\n name: \"jira_update_sprint\",\n description:\n \"Update a sprint's name, goal, dates, or state. State transitions: future→active (start) or \" +\n \"active→closed (complete). Other transitions are rejected client-side with the list of legal \" +\n \"next states. Pass only the fields you want to change. **Disable to make the agent unable to \" +\n \"start/complete sprints.**\",\n schema: z.object({\n sprint_id: z.union([z.string(), z.number()]),\n name: z.string().optional(),\n goal: z.string().optional(),\n start_date: z.string().optional().describe(\"ISO 8601 timestamp\"),\n end_date: z.string().optional().describe(\"ISO 8601 timestamp\"),\n state: z.enum([\"active\", \"closed\"]).optional().describe(\n \"Target state. 'active' starts a future sprint; 'closed' completes an active sprint.\",\n ),\n }),\n },\n);\n\nexport const jiraDeleteSprintTool = tool(\n async ({ sprint_id, confirm }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (String(confirm) !== String(sprint_id)) {\n return JSON.stringify({\n error:\n `Refusing to delete sprint ${sprint_id}: pass \\`confirm\\` set to the same id to proceed. ` +\n `Sprint deletion is irreversible — the issues are unassigned but historical sprint data is lost.`,\n });\n }\n const data = await atlassianFetch(auth, `/rest/agile/1.0/sprint/${encodeURIComponent(sprint_id)}`, {\n method: \"DELETE\",\n }) as { error?: string } | string;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, deleted_sprint_id: sprint_id });\n },\n {\n name: \"jira_delete_sprint\",\n description:\n \"Permanently delete a sprint. **Irreversible** — issues are unassigned from the sprint but the \" +\n \"sprint's velocity/burndown data is lost. The agent must pass `confirm` set to the same `sprint_id` \" +\n \"to proceed (two-arg gate). **Leave this tool disabled unless the user explicitly wants delete capability.**\",\n schema: z.object({\n sprint_id: z.union([z.string(), z.number()]),\n confirm: z.union([z.string(), z.number()]).describe(\"Must equal `sprint_id` for the delete to proceed\"),\n }),\n },\n);\n\nexport const jiraMoveIssuesToSprintTool = tool(\n async ({ sprint_id, issue_keys }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (!issue_keys.length) return JSON.stringify({ error: \"issue_keys is empty\" });\n if (issue_keys.length > 50) {\n return JSON.stringify({ error: `agile API accepts up to 50 issues per call (got ${issue_keys.length})` });\n }\n const data = await atlassianFetch(\n auth,\n `/rest/agile/1.0/sprint/${encodeURIComponent(sprint_id)}/issue`,\n { method: \"POST\", body: JSON.stringify({ issues: issue_keys }) },\n ) as { error?: string } | string;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, sprint_id, moved: issue_keys });\n },\n {\n name: \"jira_move_issues_to_sprint\",\n description:\n \"Move issues into a sprint. Up to 50 issues per call. Issues already in another sprint are \" +\n \"transparently moved (no separate remove step needed). Use jira_move_issues_to_backlog to remove \" +\n \"issues from sprints without putting them in a new one.\",\n schema: z.object({\n sprint_id: z.union([z.string(), z.number()]),\n issue_keys: z.array(z.string()).describe(\"Issue keys to move (e.g. ['PROJ-1','PROJ-2'])\"),\n }),\n },\n);\n\nexport const jiraMoveIssuesToBacklogTool = tool(\n async ({ issue_keys, board_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (!issue_keys.length) return JSON.stringify({ error: \"issue_keys is empty\" });\n if (issue_keys.length > 50) {\n return JSON.stringify({ error: `agile API accepts up to 50 issues per call (got ${issue_keys.length})` });\n }\n // The board-scoped endpoint /backlog/{boardId}/issue moves issues into THAT\n // board's backlog (preserving rank). The unscoped /backlog/issue endpoint\n // works for Scrum boards but not Kanban. Caller passes board_id when known.\n const path = board_id\n ? `/rest/agile/1.0/backlog/${encodeURIComponent(board_id)}/issue`\n : `/rest/agile/1.0/backlog/issue`;\n const data = await atlassianFetch(auth, path, {\n method: \"POST\",\n body: JSON.stringify({ issues: issue_keys }),\n }) as { error?: string } | string;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, moved_to_backlog: issue_keys, board_id: board_id ?? null });\n },\n {\n name: \"jira_move_issues_to_backlog\",\n description:\n \"Remove issues from their current sprint and put them back on the backlog. Up to 50 issues per \" +\n \"call. Pass `board_id` for Kanban boards (the unscoped endpoint only works for Scrum). For Scrum, \" +\n \"board_id is optional but recommended for clarity.\",\n schema: z.object({\n issue_keys: z.array(z.string()),\n board_id: z.union([z.string(), z.number()]).optional().describe(\n \"Required for Kanban boards; optional but recommended for Scrum\",\n ),\n }),\n },\n);\n\nexport const jiraRankIssuesTool = tool(\n async ({ issues, rank_before_issue, rank_after_issue, rank_custom_field_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (!issues.length) return JSON.stringify({ error: \"issues is empty\" });\n if (issues.length > 50) {\n return JSON.stringify({ error: `agile API accepts up to 50 issues per call (got ${issues.length})` });\n }\n if ((rank_before_issue && rank_after_issue) || (!rank_before_issue && !rank_after_issue)) {\n return JSON.stringify({\n error: \"pass exactly one of rank_before_issue or rank_after_issue (not both, not neither)\",\n });\n }\n const body: Record<string, unknown> = { issues };\n if (rank_before_issue) body.rankBeforeIssue = rank_before_issue;\n if (rank_after_issue) body.rankAfterIssue = rank_after_issue;\n if (rank_custom_field_id !== undefined) body.rankCustomFieldId = rank_custom_field_id;\n const data = await atlassianFetch(auth, `/rest/agile/1.0/issue/rank`, {\n method: \"PUT\",\n body: JSON.stringify(body),\n }) as { error?: string } | string;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n ranked: issues,\n relative_to: rank_before_issue ? { before: rank_before_issue } : { after: rank_after_issue },\n });\n },\n {\n name: \"jira_rank_issues\",\n description:\n \"Rank up to 50 issues relative to a single anchor issue (before XOR after). Pass \" +\n \"rank_custom_field_id only on sites that have a non-default rank field — get it from \" +\n \"jira_get_board.configuration.ranking_field. Order within `issues[]` is preserved.\",\n schema: z.object({\n issues: z.array(z.string()).describe(\"Issue keys in the order they should be placed\"),\n rank_before_issue: z.string().optional().describe(\"Anchor: place `issues` immediately before this key\"),\n rank_after_issue: z.string().optional().describe(\"Anchor: place `issues` immediately after this key\"),\n rank_custom_field_id: z.number().optional().describe(\n \"Custom rank field id (numeric). Default is the global rank field; rarely needed.\",\n ),\n }),\n },\n);\n\n// ── Jira issue extras (comments CRUD, worklogs, attachments, changelog) ─────\n//\n// These fill specific gaps left by the issue-CRUD tools above:\n// - jira_get_issue caps embedded comments at ~50; jira_get_comments paginates.\n// - jira_update_issue can't touch existing comments — that needs the per-comment endpoint.\n// - jira_upload_attachment uploads but doesn't read or delete; the get/delete pair completes it.\n// - jira_get_issue's changelog field is opt-in via expand and capped; the dedicated endpoint paginates.\n// See ADR-0035.\n\nexport const jiraGetCommentsTool = tool(\n async ({ issue_key, start_at, max_results, order_by }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const params = new URLSearchParams();\n if (start_at !== undefined) params.set(\"startAt\", String(start_at));\n params.set(\"maxResults\", String(Math.min(max_results ?? 50, 100)));\n if (order_by) params.set(\"orderBy\", order_by);\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/issue/${encodeURIComponent(issue_key)}/comment?${params}`,\n ) as {\n comments?: Array<Record<string, unknown>>;\n startAt?: number; maxResults?: number; total?: number;\n error?: string;\n };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n issue_key,\n start_at: data.startAt ?? 0,\n max_results: data.maxResults ?? 0,\n total: data.total ?? 0,\n comments: (data.comments ?? []).map((c) => ({\n id: c.id,\n author: (c.author as Record<string, unknown>)?.displayName ?? null,\n created: c.created,\n updated: c.updated,\n body: simplifyADF(c.body),\n })),\n });\n },\n {\n name: \"jira_get_comments\",\n description:\n \"Paginated comment list for a Jira issue. Use this when an issue has more comments than the \" +\n \"embedded list returned by jira_get_issue (Jira caps that at ~50). order_by accepts 'created' \" +\n \"or '-created' for ascending/descending. ADF bodies auto-flattened.\",\n schema: z.object({\n issue_key: z.string(),\n start_at: z.number().optional().describe(\"Offset for pagination (default 0)\"),\n max_results: z.number().optional().describe(\"Default 50, max 100\"),\n order_by: z.enum([\"created\", \"-created\"]).optional(),\n }),\n },\n);\n\nexport const jiraUpdateCommentTool = tool(\n async ({ issue_key, comment_id, body }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/issue/${encodeURIComponent(issue_key)}/comment/${encodeURIComponent(comment_id)}`,\n { method: \"PUT\", body: JSON.stringify({ body: textToADF(body) }) },\n ) as { id?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({ ok: true, comment_id: data.id ?? comment_id });\n },\n {\n name: \"jira_update_comment\",\n description:\n \"Edit an existing comment on a Jira issue. Plain-text body is auto-converted to ADF (same as \" +\n \"jira_add_comment). The author and created timestamp are preserved; updated reflects this edit.\",\n schema: z.object({\n issue_key: z.string(),\n comment_id: z.string().describe(\"Comment id from jira_get_issue.comments[].id or jira_get_comments\"),\n body: z.string(),\n }),\n },\n);\n\nexport const jiraDeleteCommentTool = tool(\n async ({ issue_key, comment_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/issue/${encodeURIComponent(issue_key)}/comment/${encodeURIComponent(comment_id)}`,\n { method: \"DELETE\" },\n ) as { error?: string } | string;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, deleted_comment_id: comment_id, issue_key });\n },\n {\n name: \"jira_delete_comment\",\n description:\n \"Permanently delete a comment from a Jira issue. **Destructive — no undo.** Look up the id via \" +\n \"jira_get_issue (include_comments: true) or jira_get_comments. Disable to make the agent unable \" +\n \"to delete comments.\",\n schema: z.object({ issue_key: z.string(), comment_id: z.string() }),\n },\n);\n\nexport const jiraGetAttachmentContentTool = tool(\n async ({ content_url, as_text }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n // Attachment content URLs from /rest/api/3/issue/{key} come pre-built as\n // absolute URLs under the auth.url host. We accept either absolute or\n // relative; build the request URL accordingly.\n const fullUrl = content_url.startsWith(\"http\")\n ? content_url\n : `${auth.url}${content_url.startsWith(\"/\") ? \"\" : \"/\"}${content_url}`;\n const res = await fetch(fullUrl, { headers: { Authorization: authHeader(auth) } });\n if (!res.ok) {\n const errText = await res.text();\n return JSON.stringify({ error: `Atlassian ${res.status}: ${errText.slice(0, 500)}` });\n }\n const ct = res.headers.get(\"content-type\") ?? \"\";\n const looksText = as_text === true\n || (as_text !== false && /^(text\\/|application\\/(json|xml|yaml|x-yaml))/i.test(ct));\n if (looksText) {\n const text = await res.text();\n return JSON.stringify({\n content_type: ct,\n size: text.length,\n as: \"text\",\n content: text.slice(0, 50_000),\n truncated: text.length > 50_000,\n });\n }\n const buf = Buffer.from(await res.arrayBuffer());\n return JSON.stringify({\n content_type: ct,\n size: buf.length,\n as: \"base64\",\n content: buf.toString(\"base64\"),\n });\n },\n {\n name: \"jira_get_attachment_content\",\n description:\n \"Fetch a Jira issue attachment's bytes by content_url (from jira_get_issue.attachments[].content_url). \" +\n \"Returns UTF-8 text capped at 50KB for text-like content types, or base64 for binary. Override the \" +\n \"auto-detection via `as_text`. Mirrors confluence_get_attachment_content.\",\n schema: z.object({\n content_url: z.string().describe(\"content_url from jira_get_issue.attachments[]\"),\n as_text: z.boolean().optional().describe(\n \"Force text decode (true) or binary base64 (false). Default: auto-detect by content-type.\",\n ),\n }),\n },\n);\n\nexport const jiraDeleteAttachmentTool = tool(\n async ({ attachment_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/attachment/${encodeURIComponent(attachment_id)}`,\n { method: \"DELETE\" },\n ) as { error?: string } | string;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, deleted_attachment_id: attachment_id });\n },\n {\n name: \"jira_delete_attachment\",\n description:\n \"Permanently delete an attachment from a Jira issue by id. **Destructive — no undo.** Look up \" +\n \"the id via jira_get_issue.attachments[].id. Disable to make the agent unable to delete attachments.\",\n schema: z.object({\n attachment_id: z.string().describe(\"Attachment id (from jira_get_issue.attachments[].id)\"),\n }),\n },\n);\n\nexport const jiraAddWorklogTool = tool(\n async ({ issue_key, time_spent, started, comment }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const body: Record<string, unknown> = { timeSpent: time_spent };\n if (started) body.started = started;\n if (comment) body.comment = textToADF(comment);\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/issue/${encodeURIComponent(issue_key)}/worklog`,\n { method: \"POST\", body: JSON.stringify(body) },\n ) as { id?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({ ok: true, worklog_id: data.id, issue_key });\n },\n {\n name: \"jira_add_worklog\",\n description:\n \"Log time spent on a Jira issue. time_spent uses Jira's duration syntax: '1h', '30m', '2d 4h', etc. \" +\n \"started is an ISO 8601 timestamp (defaults to now). comment is plain text auto-converted to ADF.\",\n schema: z.object({\n issue_key: z.string(),\n time_spent: z.string().describe(\"Duration string ('1h', '30m', '2d 4h')\"),\n started: z.string().optional().describe(\"ISO 8601 timestamp; defaults to now\"),\n comment: z.string().optional(),\n }),\n },\n);\n\nexport const jiraListWorklogsTool = tool(\n async ({ issue_key, start_at, max_results }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const params = new URLSearchParams();\n if (start_at !== undefined) params.set(\"startAt\", String(start_at));\n params.set(\"maxResults\", String(Math.min(max_results ?? 50, 1000)));\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/issue/${encodeURIComponent(issue_key)}/worklog?${params}`,\n ) as {\n worklogs?: Array<Record<string, unknown>>;\n startAt?: number; maxResults?: number; total?: number;\n error?: string;\n };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n issue_key,\n start_at: data.startAt ?? 0,\n max_results: data.maxResults ?? 0,\n total: data.total ?? 0,\n worklogs: (data.worklogs ?? []).map((w) => ({\n id: w.id,\n author: (w.author as Record<string, unknown>)?.displayName ?? null,\n time_spent: w.timeSpent,\n time_spent_seconds: w.timeSpentSeconds,\n started: w.started,\n created: w.created,\n updated: w.updated,\n comment: simplifyADF(w.comment),\n })),\n });\n },\n {\n name: \"jira_list_worklogs\",\n description:\n \"List worklog entries on a Jira issue (paginated). Returns id, author, time_spent (display string + \" +\n \"seconds), started, comment. Use to compute totals or audit time tracking.\",\n schema: z.object({\n issue_key: z.string(),\n start_at: z.number().optional(),\n max_results: z.number().optional().describe(\"Default 50, max 1000\"),\n }),\n },\n);\n\nexport const jiraGetChangelogTool = tool(\n async ({ issue_key, start_at, max_results }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const params = new URLSearchParams();\n if (start_at !== undefined) params.set(\"startAt\", String(start_at));\n params.set(\"maxResults\", String(Math.min(max_results ?? 50, 100)));\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/issue/${encodeURIComponent(issue_key)}/changelog?${params}`,\n ) as {\n values?: Array<Record<string, unknown>>;\n startAt?: number; maxResults?: number; total?: number;\n error?: string;\n };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n issue_key,\n start_at: data.startAt ?? 0,\n max_results: data.maxResults ?? 0,\n total: data.total ?? 0,\n changelog: (data.values ?? []).map((entry) => ({\n id: entry.id,\n author: (entry.author as Record<string, unknown>)?.displayName ?? null,\n created: entry.created,\n items: ((entry.items as Array<Record<string, unknown>>) ?? []).map((item) => ({\n field: item.field,\n field_type: item.fieldtype,\n // Atlassian returns both `from`/`to` (raw ids) and `fromString`/`toString`\n // (human-readable). Prefer the human form when present. NB: hasOwn check\n // is required because `toString` is inherited from Object.prototype.\n from: Object.hasOwn(item, \"fromString\") ? item.fromString : (item.from ?? null),\n to: Object.hasOwn(item, \"toString\") ? item.toString : (item.to ?? null),\n })),\n })),\n });\n },\n {\n name: \"jira_get_changelog\",\n description:\n \"Fetch a Jira issue's history (paginated). Each entry has author, timestamp, and a list of \" +\n \"field-level changes (field name, from, to). Useful for 'what changed yesterday?' audits and \" +\n \"for surfacing the previous value of a field.\",\n schema: z.object({\n issue_key: z.string(),\n start_at: z.number().optional(),\n max_results: z.number().optional().describe(\"Default 50, max 100\"),\n }),\n },\n);\n\n// ── Jira project metadata (projects, versions, components, generic enums) ──\n//\n// These let the agent introspect a site without guessing — list projects,\n// list versions on a project, read the canonical issue-type/priority/status\n// names. Mostly thin wrappers around /rest/api/3/project*, /version, /component,\n// and the four enum endpoints. See ADR-0035.\n\nexport const jiraListProjectsTool = tool(\n async ({ query, category_id, max_results, start_at }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const params = new URLSearchParams();\n if (query) params.set(\"query\", query);\n if (category_id !== undefined) params.set(\"categoryId\", String(category_id));\n if (start_at !== undefined) params.set(\"startAt\", String(start_at));\n params.set(\"maxResults\", String(Math.min(max_results ?? 50, 100)));\n const data = await atlassianFetch(auth, `/rest/api/3/project/search?${params}`) as\n | { values?: Array<Record<string, unknown>>; total?: number; isLast?: boolean; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n total: data.total ?? 0,\n is_last: data.isLast ?? null,\n projects: (data.values ?? []).map((p) => ({\n id: p.id,\n key: p.key,\n name: p.name,\n type_key: p.projectTypeKey ?? null,\n style: p.style ?? null,\n lead: ((p.lead as Record<string, unknown>)?.displayName) ?? null,\n })),\n });\n },\n {\n name: \"jira_list_projects\",\n description:\n \"List Jira projects (paginated). Filter by name fragment via `query` or by category. Returns \" +\n \"id, key, name, type, style ('classic'|'next-gen'), lead.\",\n schema: z.object({\n query: z.string().optional().describe(\"Project name/key fragment\"),\n category_id: z.number().optional(),\n start_at: z.number().optional(),\n max_results: z.number().optional().describe(\"Default 50, max 100\"),\n }),\n },\n);\n\nexport const jiraGetProjectTool = tool(\n async ({ project_key, include_versions, include_components, include_issue_types }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const expand: string[] = [];\n if (include_versions) expand.push(\"versions\");\n if (include_components) expand.push(\"components\");\n if (include_issue_types) expand.push(\"issueTypes\");\n const qs = expand.length ? `?expand=${expand.join(\",\")}` : \"\";\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/project/${encodeURIComponent(project_key)}${qs}`,\n ) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n id: data.id,\n key: data.key,\n name: data.name,\n type_key: data.projectTypeKey ?? null,\n style: data.style ?? null,\n description: data.description ?? null,\n lead: ((data.lead as Record<string, unknown>)?.displayName) ?? null,\n url: `${auth.url}/browse/${data.key}`,\n ...(include_versions ? {\n versions: ((data.versions as Array<Record<string, unknown>>) ?? []).map((v) => ({\n id: v.id, name: v.name, released: v.released, archived: v.archived,\n start_date: v.startDate ?? null, release_date: v.releaseDate ?? null,\n })),\n } : {}),\n ...(include_components ? {\n components: ((data.components as Array<Record<string, unknown>>) ?? []).map((c) => ({\n id: c.id, name: c.name,\n lead: ((c.lead as Record<string, unknown>)?.displayName) ?? null,\n })),\n } : {}),\n ...(include_issue_types ? {\n issue_types: ((data.issueTypes as Array<Record<string, unknown>>) ?? []).map((t) => ({\n id: t.id, name: t.name, subtask: t.subtask, hierarchy_level: t.hierarchyLevel,\n })),\n } : {}),\n });\n },\n {\n name: \"jira_get_project\",\n description:\n \"Fetch a single Jira project by key. Optionally include versions, components, and/or issue types \" +\n \"in the response — saves separate calls for the common 'tell me about this project' use case.\",\n schema: z.object({\n project_key: z.string(),\n include_versions: z.boolean().optional(),\n include_components: z.boolean().optional(),\n include_issue_types: z.boolean().optional(),\n }),\n },\n);\n\nexport const jiraListVersionsTool = tool(\n async ({ project_key, start_at, max_results, order_by }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const params = new URLSearchParams();\n if (start_at !== undefined) params.set(\"startAt\", String(start_at));\n params.set(\"maxResults\", String(Math.min(max_results ?? 50, 100)));\n if (order_by) params.set(\"orderBy\", order_by);\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/project/${encodeURIComponent(project_key)}/version?${params}`,\n ) as {\n values?: Array<Record<string, unknown>>;\n total?: number; isLast?: boolean; error?: string;\n };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n total: data.total ?? 0,\n is_last: data.isLast ?? null,\n versions: (data.values ?? []).map((v) => ({\n id: v.id,\n name: v.name,\n released: v.released,\n archived: v.archived,\n start_date: v.startDate ?? null,\n release_date: v.releaseDate ?? null,\n description: v.description ?? null,\n })),\n });\n },\n {\n name: \"jira_list_versions\",\n description:\n \"List versions on a Jira project (paginated). Returns id, name, released/archived flags, dates. \" +\n \"Use jira_create_version to add a new one and jira_update_version to release/archive.\",\n schema: z.object({\n project_key: z.string(),\n start_at: z.number().optional(),\n max_results: z.number().optional().describe(\"Default 50, max 100\"),\n order_by: z.enum([\"sequence\", \"name\", \"startDate\", \"releaseDate\", \"-sequence\", \"-name\", \"-startDate\", \"-releaseDate\"]).optional(),\n }),\n },\n);\n\nexport const jiraCreateVersionTool = tool(\n async ({ project_key, name, description, start_date, release_date, released }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n // Resolve project key → numeric project id (the version endpoint requires id, not key).\n const proj = await atlassianFetch(auth, `/rest/api/3/project/${encodeURIComponent(project_key)}`) as\n { id?: string; error?: string };\n if (proj.error) return JSON.stringify(proj);\n if (!proj.id) return JSON.stringify({ error: `could not resolve project_key \"${project_key}\" to a numeric id` });\n const body: Record<string, unknown> = { projectId: Number(proj.id), name };\n if (description !== undefined) body.description = description;\n if (start_date !== undefined) body.startDate = start_date;\n if (release_date !== undefined) body.releaseDate = release_date;\n if (released !== undefined) body.released = released;\n const data = await atlassianFetch(auth, `/rest/api/3/version`, {\n method: \"POST\", body: JSON.stringify(body),\n }) as { id?: string; name?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({ ok: true, version_id: data.id, name: data.name });\n },\n {\n name: \"jira_create_version\",\n description:\n \"Create a new version on a Jira project. Pass the project key — we resolve it to the numeric id. \" +\n \"start_date / release_date are 'YYYY-MM-DD'. Set released=true to mark released on creation.\",\n schema: z.object({\n project_key: z.string(),\n name: z.string(),\n description: z.string().optional(),\n start_date: z.string().optional().describe(\"YYYY-MM-DD\"),\n release_date: z.string().optional().describe(\"YYYY-MM-DD\"),\n released: z.boolean().optional(),\n }),\n },\n);\n\nexport const jiraUpdateVersionTool = tool(\n async ({ version_id, name, description, start_date, release_date, released, archived }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const body: Record<string, unknown> = {};\n if (name !== undefined) body.name = name;\n if (description !== undefined) body.description = description;\n if (start_date !== undefined) body.startDate = start_date;\n if (release_date !== undefined) body.releaseDate = release_date;\n if (released !== undefined) body.released = released;\n if (archived !== undefined) body.archived = archived;\n if (Object.keys(body).length === 0) {\n return JSON.stringify({ error: \"no fields to update — pass at least one of name, description, start_date, release_date, released, archived\" });\n }\n const data = await atlassianFetch(auth, `/rest/api/3/version/${encodeURIComponent(version_id)}`, {\n method: \"PUT\", body: JSON.stringify(body),\n }) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n version_id,\n released: data.released ?? null,\n archived: data.archived ?? null,\n updated_fields: Object.keys(body),\n });\n },\n {\n name: \"jira_update_version\",\n description:\n \"Edit a version: rename, change dates, mark released/unreleased, mark archived/unarchived. \" +\n \"Pass only the fields you want to change. To 'release' a version, pass released=true (and \" +\n \"release_date if not already set). To unrelease, pass released=false. **Disable to make the \" +\n \"agent unable to release versions.**\",\n schema: z.object({\n version_id: z.string(),\n name: z.string().optional(),\n description: z.string().optional(),\n start_date: z.string().optional(),\n release_date: z.string().optional(),\n released: z.boolean().optional(),\n archived: z.boolean().optional(),\n }),\n },\n);\n\nexport const jiraListComponentsTool = tool(\n async ({ project_key }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await atlassianFetch(\n auth,\n `/rest/api/3/project/${encodeURIComponent(project_key)}/components`,\n ) as Array<Record<string, unknown>> | { error?: string };\n if (!Array.isArray(data)) return JSON.stringify(data);\n return JSON.stringify({\n components: data.map((c) => ({\n id: c.id,\n name: c.name,\n description: c.description ?? null,\n lead: ((c.lead as Record<string, unknown>)?.displayName) ?? null,\n assignee_type: c.assigneeType ?? null,\n })),\n });\n },\n {\n name: \"jira_list_components\",\n description:\n \"List components on a Jira project. Returns id, name, description, lead, default assignee type. \" +\n \"Components are not paginated by Jira — the full list returns in one call.\",\n schema: z.object({ project_key: z.string() }),\n },\n);\n\nexport const jiraCreateComponentTool = tool(\n async ({ project_key, name, description, lead_account_id, assignee_type }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const body: Record<string, unknown> = { project: project_key, name };\n if (description !== undefined) body.description = description;\n if (lead_account_id !== undefined) body.leadAccountId = lead_account_id;\n if (assignee_type !== undefined) body.assigneeType = assignee_type;\n const data = await atlassianFetch(auth, `/rest/api/3/component`, {\n method: \"POST\", body: JSON.stringify(body),\n }) as { id?: string; name?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({ ok: true, component_id: data.id, name: data.name });\n },\n {\n name: \"jira_create_component\",\n description:\n \"Create a component on a Jira project. assignee_type controls default assignee for issues with \" +\n \"this component: 'PROJECT_DEFAULT' | 'COMPONENT_LEAD' | 'PROJECT_LEAD' | 'UNASSIGNED'.\",\n schema: z.object({\n project_key: z.string(),\n name: z.string(),\n description: z.string().optional(),\n lead_account_id: z.string().optional(),\n assignee_type: z.enum([\"PROJECT_DEFAULT\", \"COMPONENT_LEAD\", \"PROJECT_LEAD\", \"UNASSIGNED\"]).optional(),\n }),\n },\n);\n\nconst META_KIND_TO_PATH: Record<string, string> = {\n issue_type: \"/rest/api/3/issuetype\",\n priority: \"/rest/api/3/priority\",\n status: \"/rest/api/3/status\",\n resolution: \"/rest/api/3/resolution\",\n};\nconst META_KINDS = Object.keys(META_KIND_TO_PATH) as ReadonlyArray<keyof typeof META_KIND_TO_PATH>;\n\nexport const jiraListMetaTool = tool(\n async ({ kind }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (!kind) {\n return JSON.stringify({\n available_kinds: META_KINDS,\n usage: \"Pass kind='issue_type' | 'priority' | 'status' | 'resolution' to list that enum's values for the site.\",\n });\n }\n const path = META_KIND_TO_PATH[kind];\n if (!path) {\n return JSON.stringify({ error: `unknown kind \"${kind}\". Expected one of: ${META_KINDS.join(\", \")}.` });\n }\n const data = await atlassianFetch(auth, path) as Array<Record<string, unknown>> | { error?: string };\n if (!Array.isArray(data)) return JSON.stringify(data);\n return JSON.stringify({\n kind,\n values: data.map((v) => ({\n id: v.id,\n name: v.name,\n description: v.description ?? null,\n ...(kind === \"issue_type\" ? { subtask: v.subtask, hierarchy_level: v.hierarchyLevel } : {}),\n ...(kind === \"status\" ? {\n status_category: ((v.statusCategory as Record<string, unknown>)?.name) ?? null,\n } : {}),\n })),\n });\n },\n {\n name: \"jira_list_meta\",\n description:\n \"List values for a Jira site-wide enum: issue types, priorities, statuses, or resolutions. \" +\n \"Pass `kind` = 'issue_type' | 'priority' | 'status' | 'resolution'. Omit `kind` to list available kinds. \" +\n \"Use this before jira_create_issue / jira_update_issue when you don't know the exact name on this site.\",\n schema: z.object({\n kind: z.enum(META_KINDS as [string, ...string[]]).optional(),\n }),\n },\n);\n\n// ── Confluence tools ────────────────────────────────────────────────────────\n//\n// Most tools below use the Confluence v2 REST API (/wiki/api/v2/...). Three\n// gaps still require v1 paths as of 2026 and are flagged inline:\n// - confluence_search: v2 has no CQL endpoint.\n// - confluence_upload_attachment: v2 Attachment group is read-only (CONFCLOUD-77196).\n// - confluence_add_label: v2 Label group is read-only (CONFCLOUD-76866).\n// The remote document-RAG indexer in lib/documents/remote/confluence.ts (ADR-0026)\n// stays on v1 — it has its own concerns and is intentionally untouched here.\n\nexport const confluenceSearchTool = tool(\n async ({ cql, max_results }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const limit = Math.min(max_results ?? 15, 50);\n // v1: CQL search has no v2 equivalent.\n const data = await atlassianFetch(\n auth,\n `/wiki/rest/api/content/search?cql=${encodeURIComponent(cql)}&limit=${limit}`,\n ) as { results?: Array<Record<string, unknown>>; size?: number; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n total: data.size,\n results: (data.results ?? []).map((r: Record<string, unknown>) => ({\n id: r.id,\n type: r.type,\n title: r.title,\n url: `${auth.url}/wiki${((r._links as Record<string, unknown>)?.webui) ?? \"\"}`,\n })),\n });\n },\n {\n name: \"confluence_search\",\n description:\n \"Search Confluence pages with CQL (Confluence Query Language). \" +\n \"Examples: 'type=page AND title~\\\"runbook\\\"', 'space=ENG AND lastmodified > now(\\\"-7d\\\")'.\",\n schema: z.object({\n cql: z.string().describe(\"CQL query string\"),\n max_results: z.number().optional().describe(\"Max results (default 15, max 50)\"),\n }),\n },\n);\n\nexport const confluenceGetPageTool = tool(\n async ({ page_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await atlassianFetch(\n auth,\n `/wiki/api/v2/pages/${encodeURIComponent(page_id)}?body-format=storage,view&include-version=true`,\n ) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n const body = data.body as Record<string, Record<string, unknown> | undefined> | undefined;\n const storageVal = body?.storage?.value as string | undefined;\n const viewVal = body?.view?.value as string | undefined;\n const links = data._links as Record<string, unknown> | undefined;\n const webui = links?.webui as string | undefined;\n return JSON.stringify({\n id: data.id,\n title: data.title,\n url: webui ? `${auth.url}/wiki${webui}` : null,\n space_id: data.spaceId ?? null,\n parent_id: data.parentId ?? null,\n status: data.status,\n version: (data.version as Record<string, unknown> | undefined)?.number ?? null,\n // body_storage round-trips into confluence_update_page; body_view is rendered HTML\n // for summarization. Each capped to 20KB to keep context lean.\n body_storage: storageVal ? storageVal.slice(0, 20_000) : null,\n body_storage_truncated: storageVal ? storageVal.length > 20_000 : false,\n body_view: viewVal ? viewVal.slice(0, 20_000) : null,\n body_view_truncated: viewVal ? viewVal.length > 20_000 : false,\n });\n },\n {\n name: \"confluence_get_page\",\n description:\n \"Fetch a Confluence page by id (v2). Returns title, space_id, parent_id, version, and BOTH \" +\n \"body_storage (round-trippable into confluence_update_page) and body_view (rendered HTML, \" +\n \"easier to summarize). Each body capped at 20KB.\",\n schema: z.object({\n page_id: z.string(),\n }),\n },\n);\n\nexport const confluenceGetPageByTitleTool = tool(\n async ({ space_key, title, include_body }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const sid = await resolveSpaceId(auth, space_key);\n if (typeof sid !== \"string\") return JSON.stringify(sid);\n const params = new URLSearchParams({ title, \"space-id\": sid, limit: \"5\" });\n if (include_body) params.set(\"body-format\", \"storage\");\n const data = await atlassianFetch(auth, `/wiki/api/v2/pages?${params}`) as\n | { results?: Array<Record<string, unknown>>; error?: string };\n if (!Array.isArray(data?.results)) return JSON.stringify(data);\n return JSON.stringify({\n matches: data.results.map((p) => {\n const links = p._links as Record<string, unknown> | undefined;\n const webui = links?.webui as string | undefined;\n const body = p.body as Record<string, Record<string, unknown> | undefined> | undefined;\n return {\n id: p.id,\n title: p.title,\n space_id: p.spaceId,\n parent_id: p.parentId ?? null,\n status: p.status,\n url: webui ? `${auth.url}/wiki${webui}` : null,\n ...(include_body\n ? { body_storage: ((body?.storage?.value as string | undefined) ?? \"\").slice(0, 20_000) }\n : {}),\n };\n }),\n });\n },\n {\n name: \"confluence_get_page_by_title\",\n description:\n \"Find Confluence page(s) by exact title within a space. Auto-resolves `space_key` (e.g. 'ENG') \" +\n \"to the v2 space id. Returns up to 5 matches; pass `include_body: true` to also include storage XHTML.\",\n schema: z.object({\n space_key: z.string().describe(\"Space key like 'ENG'\"),\n title: z.string().describe(\"Exact page title (case-sensitive on Cloud)\"),\n include_body: z.boolean().optional(),\n }),\n },\n);\n\nexport const confluenceGetPageChildrenTool = tool(\n async ({ page_id, cursor, limit }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const params = new URLSearchParams({ limit: String(Math.min(limit ?? 25, 250)) });\n if (cursor) params.set(\"cursor\", cursor);\n const data = await atlassianFetch(\n auth,\n `/wiki/api/v2/pages/${encodeURIComponent(page_id)}/children?${params}`,\n ) as { results?: Array<Record<string, unknown>>; _links?: { next?: string }; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n children: (data.results ?? []).map((p) => ({\n id: p.id,\n title: p.title,\n type: p.type,\n status: p.status,\n parent_id: p.parentId ?? null,\n position: p.position ?? null,\n })),\n next_cursor: parseV2NextCursor(data._links?.next),\n });\n },\n {\n name: \"confluence_get_page_children\",\n description:\n \"List direct children of a Confluence page (cursor-paginated). Pass `cursor` from a prior call's \" +\n \"`next_cursor` to fetch the next page. Default limit 25 (max 250).\",\n schema: z.object({\n page_id: z.string(),\n cursor: z.string().optional(),\n limit: z.number().optional(),\n }),\n },\n);\n\nexport const confluenceGetPageAncestorsTool = tool(\n async ({ page_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await atlassianFetch(\n auth,\n `/wiki/api/v2/pages/${encodeURIComponent(page_id)}/ancestors`,\n ) as { results?: Array<Record<string, unknown>>; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ancestors: (data.results ?? []).map((a) => ({ id: a.id, title: a.title, type: a.type })),\n });\n },\n {\n name: \"confluence_get_page_ancestors\",\n description:\n \"Return the parent chain (root → leaf) for a Confluence page. Useful for breadcrumbs and \" +\n \"understanding where a page lives in the tree.\",\n schema: z.object({ page_id: z.string() }),\n },\n);\n\nexport const confluenceListSpacesTool = tool(\n async ({ cursor, limit, type, status }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const params = new URLSearchParams({ limit: String(Math.min(limit ?? 25, 250)) });\n if (cursor) params.set(\"cursor\", cursor);\n if (type) params.set(\"type\", type);\n if (status) params.set(\"status\", status);\n const data = await atlassianFetch(auth, `/wiki/api/v2/spaces?${params}`) as\n | { results?: Array<Record<string, unknown>>; _links?: { next?: string }; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n spaces: (data.results ?? []).map((s) => ({\n id: s.id,\n key: s.key,\n name: s.name,\n type: s.type,\n status: s.status,\n homepage_id: s.homepageId ?? null,\n })),\n next_cursor: parseV2NextCursor(data._links?.next),\n });\n },\n {\n name: \"confluence_list_spaces\",\n description:\n \"List Confluence spaces (cursor-paginated). Returns id, key, name, type, status, homepage_id. \" +\n \"Useful for discovering space keys to pass to confluence_create_page or confluence_get_page_by_title.\",\n schema: z.object({\n cursor: z.string().optional(),\n limit: z.number().optional(),\n type: z.enum([\"global\", \"personal\", \"collaboration\", \"knowledge_base\"]).optional(),\n status: z.enum([\"current\", \"archived\"]).optional(),\n }),\n },\n);\n\nexport const confluenceGetCommentsTool = tool(\n async ({ page_id, include_inline }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const footerData = await atlassianFetch(\n auth,\n `/wiki/api/v2/pages/${encodeURIComponent(page_id)}/footer-comments?body-format=storage&limit=100`,\n ) as { results?: Array<Record<string, unknown>>; error?: string };\n let inlineData: { results?: Array<Record<string, unknown>>; error?: string } | undefined;\n if (include_inline !== false) {\n // Known v2 bug: some sites 404 here even when comments exist. Tolerate\n // and surface as `inline_warning` so the caller still gets footer comments.\n inlineData = await atlassianFetch(\n auth,\n `/wiki/api/v2/pages/${encodeURIComponent(page_id)}/inline-comments?body-format=storage&limit=100`,\n ) as { results?: Array<Record<string, unknown>>; error?: string };\n }\n if (footerData.error && !Array.isArray(footerData.results)) return JSON.stringify(footerData);\n const flatten = (c: Record<string, unknown>) => {\n const ver = c.version as Record<string, unknown> | undefined;\n const body = c.body as Record<string, Record<string, unknown> | undefined> | undefined;\n return {\n id: c.id,\n version: ver?.number ?? null,\n author_id: c.authorId ?? ver?.authorId ?? null,\n created_at: ver?.createdAt ?? null,\n body_storage: (body?.storage?.value as string | undefined) ?? null,\n parent_comment_id: c.parentCommentId ?? null,\n };\n };\n return JSON.stringify({\n footer_comments: (footerData.results ?? []).map(flatten),\n inline_comments: inlineData && Array.isArray(inlineData.results) ? inlineData.results.map(flatten) : [],\n ...(inlineData && inlineData.error ? { inline_warning: inlineData.error } : {}),\n });\n },\n {\n name: \"confluence_get_comments\",\n description:\n \"List footer comments (and inline comments by default) on a Confluence page. Returns id, \" +\n \"version, author_id, created_at, body_storage, parent_comment_id (for threading). Tolerates \" +\n \"the known v2 inline-comments 404 bug — surfaces it as `inline_warning` rather than failing.\",\n schema: z.object({\n page_id: z.string(),\n include_inline: z.boolean().optional().describe(\"Default true; pass false to skip inline-comments.\"),\n }),\n },\n);\n\nexport const confluenceListAttachmentsTool = tool(\n async ({ page_id, cursor, limit }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const params = new URLSearchParams({ limit: String(Math.min(limit ?? 50, 250)) });\n if (cursor) params.set(\"cursor\", cursor);\n const data = await atlassianFetch(\n auth,\n `/wiki/api/v2/pages/${encodeURIComponent(page_id)}/attachments?${params}`,\n ) as { results?: Array<Record<string, unknown>>; _links?: { next?: string }; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n attachments: (data.results ?? []).map((a) => {\n const ver = a.version as Record<string, unknown> | undefined;\n const links = a._links as Record<string, unknown> | undefined;\n return {\n id: a.id,\n title: a.title,\n media_type: a.mediaType,\n file_size: a.fileSize ?? null,\n created_at: ver?.createdAt ?? null,\n download_link: a.downloadLink ?? null,\n webui_link: links?.webui ?? null,\n };\n }),\n next_cursor: parseV2NextCursor(data._links?.next),\n });\n },\n {\n name: \"confluence_list_attachments\",\n description:\n \"List attachments on a Confluence page (cursor-paginated). Returns id, title, media_type, \" +\n \"file_size, download_link. Use confluence_get_attachment_content with the download_link to \" +\n \"fetch bytes.\",\n schema: z.object({\n page_id: z.string(),\n cursor: z.string().optional(),\n limit: z.number().optional(),\n }),\n },\n);\n\nexport const confluenceGetLabelsTool = tool(\n async ({ page_id, cursor, limit }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const params = new URLSearchParams({ limit: String(Math.min(limit ?? 50, 250)) });\n if (cursor) params.set(\"cursor\", cursor);\n const data = await atlassianFetch(\n auth,\n `/wiki/api/v2/pages/${encodeURIComponent(page_id)}/labels?${params}`,\n ) as { results?: Array<Record<string, unknown>>; _links?: { next?: string }; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n labels: (data.results ?? []).map((l) => ({ id: l.id, name: l.name, prefix: l.prefix })),\n next_cursor: parseV2NextCursor(data._links?.next),\n });\n },\n {\n name: \"confluence_get_labels\",\n description: \"List labels on a Confluence page (cursor-paginated). Default limit 50 (max 250).\",\n schema: z.object({\n page_id: z.string(),\n cursor: z.string().optional(),\n limit: z.number().optional(),\n }),\n },\n);\n\nexport const confluenceGetAttachmentContentTool = tool(\n async ({ download_link, as_text }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n // download_link from v2 is typically `/download/attachments/{pageId}/{filename}?...`\n // — under the /wiki app, NOT under the bare auth.url. Build the absolute URL\n // explicitly because atlassianFetch's plain `${auth.url}${path}` join would\n // miss the /wiki prefix.\n const fullUrl = download_link.startsWith(\"http\")\n ? download_link\n : download_link.startsWith(\"/wiki\")\n ? `${auth.url}${download_link}`\n : `${auth.url}/wiki${download_link.startsWith(\"/\") ? \"\" : \"/\"}${download_link}`;\n const res = await fetch(fullUrl, { headers: { Authorization: authHeader(auth) } });\n if (!res.ok) {\n const errText = await res.text();\n return JSON.stringify({ error: `Atlassian ${res.status}: ${errText.slice(0, 500)}` });\n }\n const ct = res.headers.get(\"content-type\") ?? \"\";\n const looksText = as_text === true\n || (as_text !== false && /^(text\\/|application\\/(json|xml|yaml|x-yaml))/i.test(ct));\n if (looksText) {\n const text = await res.text();\n return JSON.stringify({\n content_type: ct,\n size: text.length,\n as: \"text\",\n content: text.slice(0, 50_000),\n truncated: text.length > 50_000,\n });\n }\n const buf = Buffer.from(await res.arrayBuffer());\n return JSON.stringify({\n content_type: ct,\n size: buf.length,\n as: \"base64\",\n content: buf.toString(\"base64\"),\n });\n },\n {\n name: \"confluence_get_attachment_content\",\n description:\n \"Fetch an attachment's bytes by its download_link (from confluence_list_attachments). Returns \" +\n \"UTF-8 text (capped at 50KB) for text-like content types, or base64 for binary. Override the \" +\n \"auto-detection via `as_text`.\",\n schema: z.object({\n download_link: z.string().describe(\"download_link from confluence_list_attachments\"),\n as_text: z.boolean().optional().describe(\n \"Force text decode (true) or binary base64 (false). Default: auto-detect by content-type.\",\n ),\n }),\n },\n);\n\nexport const confluenceCreatePageTool = tool(\n async ({ space_key, title, parent_id, body_text, body_storage }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const sid = await resolveSpaceId(auth, space_key);\n if (typeof sid !== \"string\") return JSON.stringify(sid);\n const body = resolveBody({ body_text, body_storage });\n if (\"error\" in body) return JSON.stringify(body);\n const payload: Record<string, unknown> = {\n spaceId: sid,\n status: \"current\",\n title,\n body: { representation: body.representation, value: body.value },\n };\n if (parent_id) payload.parentId = parent_id;\n const data = await atlassianFetch(auth, `/wiki/api/v2/pages`, {\n method: \"POST\",\n body: JSON.stringify(payload),\n }) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n const links = data._links as Record<string, unknown> | undefined;\n const webui = links?.webui as string | undefined;\n return JSON.stringify({\n ok: true,\n id: data.id,\n title: data.title,\n space_id: data.spaceId,\n parent_id: data.parentId ?? null,\n version: (data.version as Record<string, unknown> | undefined)?.number ?? 1,\n url: webui ? `${auth.url}/wiki${webui}` : null,\n });\n },\n {\n name: \"confluence_create_page\",\n description:\n \"Create a Confluence page (v2). Pass `space_key` (e.g. 'ENG') — auto-resolved to v2 spaceId. \" +\n \"Pass exactly one of `body_text` (plain text → storage XHTML automatically) or `body_storage` \" +\n \"(raw XHTML for advanced edits). `parent_id` makes it a child page. \" +\n \"Disable to make the agent unable to author Confluence pages.\",\n schema: z.object({\n space_key: z.string(),\n title: z.string(),\n parent_id: z.string().optional().describe(\"Page id of the parent; omit for top-level.\"),\n body_text: z.string().optional().describe(\"Plain text; auto-converted to storage XHTML.\"),\n body_storage: z.string().optional().describe(\"Raw Confluence storage-format XHTML.\"),\n }),\n },\n);\n\nexport const confluenceUpdatePageTool = tool(\n async ({ page_id, title, body_text, body_storage, version_number, version_message }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const body = resolveBody({ body_text, body_storage });\n if (\"error\" in body) return JSON.stringify(body);\n\n let nextVersion = version_number;\n let resolvedTitle: string | undefined = title;\n if (nextVersion === undefined || resolvedTitle === undefined) {\n // PUT requires both title and version even when not changing them, so\n // fetch the current page when either is omitted. Cheaper than asking\n // every caller to do it.\n const current = await atlassianFetch(\n auth,\n `/wiki/api/v2/pages/${encodeURIComponent(page_id)}`,\n ) as { title?: string; version?: { number?: number }; error?: string };\n if (current.error) return JSON.stringify(current);\n if (nextVersion === undefined) {\n const cur = current.version?.number;\n if (typeof cur !== \"number\") return JSON.stringify({ error: \"could not read current version from Confluence response\" });\n nextVersion = cur + 1;\n }\n if (resolvedTitle === undefined) resolvedTitle = current.title;\n }\n\n const payload: Record<string, unknown> = {\n id: page_id,\n status: \"current\",\n title: resolvedTitle,\n body: { representation: body.representation, value: body.value },\n version: { number: nextVersion, ...(version_message ? { message: version_message } : {}) },\n };\n const data = await atlassianFetch(auth, `/wiki/api/v2/pages/${encodeURIComponent(page_id)}`, {\n method: \"PUT\",\n body: JSON.stringify(payload),\n }) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n const links = data._links as Record<string, unknown> | undefined;\n const webui = links?.webui as string | undefined;\n return JSON.stringify({\n ok: true,\n id: data.id,\n title: data.title,\n version: (data.version as Record<string, unknown> | undefined)?.number ?? nextVersion,\n url: webui ? `${auth.url}/wiki${webui}` : null,\n });\n },\n {\n name: \"confluence_update_page\",\n description:\n \"Update an existing Confluence page (v2). Pass exactly one of `body_text` or `body_storage`. \" +\n \"If `version_number` is omitted, the tool auto-fetches the current version and sends current+1 \" +\n \"(Confluence requires strict +1 increments; gaps cause 409). If `title` is omitted, the existing \" +\n \"title is preserved. Avoid back-to-back updates within ~1 second — Confluence may return 409 even \" +\n \"with the correct version. Disable to make the agent read-only on pages.\",\n schema: z.object({\n page_id: z.string(),\n title: z.string().optional().describe(\"New title; omit to keep existing.\"),\n body_text: z.string().optional(),\n body_storage: z.string().optional(),\n version_number: z.number().optional().describe(\n \"Explicit version (must equal currentVersion+1). Omit to auto-fetch and increment.\",\n ),\n version_message: z.string().optional().describe(\"Optional change comment shown in version history.\"),\n }),\n },\n);\n\nexport const confluenceAddCommentTool = tool(\n async ({ page_id, body_text, body_storage, parent_comment_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const body = resolveBody({ body_text, body_storage });\n if (\"error\" in body) return JSON.stringify(body);\n const payload: Record<string, unknown> = {\n pageId: page_id,\n body: { representation: body.representation, value: body.value },\n };\n if (parent_comment_id) payload.parentCommentId = parent_comment_id;\n const data = await atlassianFetch(auth, `/wiki/api/v2/footer-comments`, {\n method: \"POST\",\n body: JSON.stringify(payload),\n }) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n comment_id: data.id,\n page_id,\n parent_comment_id: data.parentCommentId ?? null,\n });\n },\n {\n name: \"confluence_add_comment\",\n description:\n \"Add a footer comment to a Confluence page (v2). Pass exactly one of `body_text` or \" +\n \"`body_storage`. Pass `parent_comment_id` (from confluence_get_comments) to reply in a thread.\",\n schema: z.object({\n page_id: z.string(),\n body_text: z.string().optional(),\n body_storage: z.string().optional(),\n parent_comment_id: z.string().optional().describe(\"To reply to an existing comment.\"),\n }),\n },\n);\n\nexport const confluenceMovePageTool = tool(\n async ({ page_id, position, target_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await atlassianFetch(\n auth,\n `/wiki/api/v2/pages/${encodeURIComponent(page_id)}/move/${encodeURIComponent(position)}/${encodeURIComponent(target_id)}`,\n { method: \"PUT\" },\n ) as { error?: string } | string | Record<string, unknown>;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, page_id, position, target_id });\n },\n {\n name: \"confluence_move_page\",\n description:\n \"Reorder/reparent a Confluence page (v2). `position`: 'before' or 'after' to place as a sibling \" +\n \"of `target_id`; 'append' to make it a child of `target_id`. Non-destructive.\",\n schema: z.object({\n page_id: z.string(),\n position: z.enum([\"before\", \"after\", \"append\"]),\n target_id: z.string().describe(\"Sibling (for before/after) or new parent (for append).\"),\n }),\n },\n);\n\nexport const confluenceUploadAttachmentTool = tool(\n async ({ page_id, filename, content_base64, content_text, comment, minor_edit }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (!content_base64 && !content_text) {\n return JSON.stringify({ error: \"pass either content_base64 (binary) or content_text (UTF-8)\" });\n }\n const buf = content_base64\n ? Buffer.from(content_base64, \"base64\")\n : Buffer.from(content_text!, \"utf8\");\n\n // v1 fallback: v2 Attachment group is read-only as of 2026 (CONFCLOUD-77196).\n // Same multipart shape as jiraUploadAttachmentTool — X-Atlassian-Token: no-check\n // bypasses CSRF; do NOT set Content-Type (fetch fills in the multipart boundary).\n const form = new FormData();\n form.append(\"file\", new Blob([buf]), filename);\n if (typeof comment === \"string\") form.append(\"comment\", comment);\n if (minor_edit) form.append(\"minorEdit\", \"true\");\n\n const url = `${auth.url}/wiki/rest/api/content/${encodeURIComponent(page_id)}/child/attachment`;\n const res = await fetch(url, {\n method: \"POST\",\n headers: {\n Authorization: authHeader(auth),\n Accept: \"application/json\",\n \"X-Atlassian-Token\": \"no-check\",\n },\n body: form,\n });\n const text = await res.text();\n if (!res.ok) return JSON.stringify({ error: `Atlassian ${res.status}: ${text.slice(0, 500)}` });\n const parsed = parseJsonSafe<{\n results?: Array<{ id: string; title: string; metadata?: { mediaType?: string }; extensions?: { fileSize?: number } }>;\n }>(text, {});\n return JSON.stringify({\n ok: true,\n page_id,\n attachments: (parsed.results ?? []).map((a) => ({\n id: a.id,\n title: a.title,\n media_type: a.metadata?.mediaType ?? null,\n file_size: a.extensions?.fileSize ?? null,\n })),\n });\n },\n {\n name: \"confluence_upload_attachment\",\n description:\n \"Attach a file to a Confluence page. Pass content_base64 for binary or content_text for plain \" +\n \"UTF-8. Uses the v1 multipart endpoint (v2 has no attachment-create endpoint as of 2026). \" +\n \"Disable to make the agent unable to add attachments.\",\n schema: z.object({\n page_id: z.string(),\n filename: z.string().describe(\"Filename shown in Confluence (include the extension).\"),\n content_base64: z.string().optional().describe(\"Base64-encoded file contents (use for binary).\"),\n content_text: z.string().optional().describe(\"Raw UTF-8 text contents (use for logs/CSVs/JSON).\"),\n comment: z.string().optional().describe(\"Version comment shown in the attachment history.\"),\n minor_edit: z.boolean().optional().describe(\"If true, doesn't notify watchers.\"),\n }),\n },\n);\n\nexport const confluenceAddLabelTool = tool(\n async ({ page_id, labels }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (!labels.length) return JSON.stringify({ error: \"labels is empty\" });\n // v1 fallback: v2 Label group is read-only as of 2026 (CONFCLOUD-76866).\n const payload = labels.map((name) => ({ prefix: \"global\", name }));\n const data = await atlassianFetch(\n auth,\n `/wiki/rest/api/content/${encodeURIComponent(page_id)}/label`,\n { method: \"POST\", body: JSON.stringify(payload) },\n ) as { results?: Array<{ name?: string; prefix?: string }>; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n page_id,\n added: labels,\n total_labels: (data.results ?? []).map((r) => r.name).filter(Boolean),\n });\n },\n {\n name: \"confluence_add_label\",\n description:\n \"Add one or more labels to a Confluence page (additive — does not replace existing labels). \" +\n \"Uses the v1 endpoint (v2 only reads labels as of 2026).\",\n schema: z.object({\n page_id: z.string(),\n labels: z.array(z.string()).describe(\"Label names to add (e.g. ['runbook', 'on-call']).\"),\n }),\n },\n);\n\n// ── Confluence v2 gap-fillers (ADR-0035) ────────────────────────────────────\n//\n// v2 audit on 2026-05-28 confirmed:\n// - DELETE /pages/{id} exists (with optional purge=true).\n// - PUT/DELETE /footer-comments/{id} and /inline-comments/{id} exist.\n// - DELETE /attachments/{id} exists (with optional purge=true).\n// - Label group is STILL read-only (CONFCLOUD-76866); confluence_remove_label\n// uses the v1 fallback `DELETE /content/{id}/label?name=...`.\n\nexport const confluenceDeletePageTool = tool(\n async ({ page_id, purge, confirm }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (purge && confirm !== page_id) {\n return JSON.stringify({\n error:\n `Refusing to permanently delete page ${page_id}: purge=true requires confirm to equal page_id. ` +\n `A purged page cannot be restored from trash. Drop purge if you only want to soft-delete.`,\n });\n }\n const qs = purge ? `?purge=true` : \"\";\n const data = await atlassianFetch(\n auth,\n `/wiki/api/v2/pages/${encodeURIComponent(page_id)}${qs}`,\n { method: \"DELETE\" },\n ) as { error?: string } | string;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, deleted_page_id: page_id, purged: !!purge });\n },\n {\n name: \"confluence_delete_page\",\n description:\n \"Delete a Confluence page (v2). Default soft-deletes (page goes to trash, restorable). \" +\n \"Pass purge=true for permanent deletion, which **also requires `confirm` to equal page_id** \" +\n \"as a guardrail. Disable to make the agent unable to delete pages.\",\n schema: z.object({\n page_id: z.string(),\n purge: z.boolean().optional().describe(\"If true, permanently delete (skip trash). Requires confirm=page_id.\"),\n confirm: z.string().optional().describe(\"Required when purge=true; must equal page_id.\"),\n }),\n },\n);\n\nconst COMMENT_KIND_TO_PATH: Record<string, string> = {\n footer: \"footer-comments\",\n inline: \"inline-comments\",\n};\n\nexport const confluenceUpdateCommentTool = tool(\n async ({ comment_id, kind, body_text, body_storage, version_number, version_message }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const segment = COMMENT_KIND_TO_PATH[kind];\n if (!segment) {\n return JSON.stringify({ error: `unknown kind \"${kind}\". Expected 'footer' or 'inline'.` });\n }\n const body = resolveBody({ body_text, body_storage });\n if (\"error\" in body) return JSON.stringify(body);\n\n let nextVersion = version_number;\n if (nextVersion === undefined) {\n // PUT requires version.number = current + 1; auto-fetch when not passed.\n const current = await atlassianFetch(\n auth,\n `/wiki/api/v2/${segment}/${encodeURIComponent(comment_id)}`,\n ) as { version?: { number?: number }; error?: string };\n if (current.error) return JSON.stringify(current);\n const cur = current.version?.number;\n if (typeof cur !== \"number\") return JSON.stringify({ error: \"could not read current comment version\" });\n nextVersion = cur + 1;\n }\n\n const payload: Record<string, unknown> = {\n version: { number: nextVersion, ...(version_message ? { message: version_message } : {}) },\n body: { representation: body.representation, value: body.value },\n };\n const data = await atlassianFetch(\n auth,\n `/wiki/api/v2/${segment}/${encodeURIComponent(comment_id)}`,\n { method: \"PUT\", body: JSON.stringify(payload) },\n ) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n comment_id,\n kind,\n version: (data.version as Record<string, unknown> | undefined)?.number ?? nextVersion,\n });\n },\n {\n name: \"confluence_update_comment\",\n description:\n \"Edit an existing Confluence comment (v2). Pass `kind: 'footer' | 'inline'` to route to the \" +\n \"correct endpoint. Same `body_text` xor `body_storage` pattern as confluence_add_comment. If \" +\n \"version_number is omitted, the tool auto-fetches the current version and sends current+1 \" +\n \"(Confluence requires strict +1 increments).\",\n schema: z.object({\n comment_id: z.string(),\n kind: z.enum([\"footer\", \"inline\"]),\n body_text: z.string().optional(),\n body_storage: z.string().optional(),\n version_number: z.number().optional().describe(\"Explicit version (must be current+1). Omit to auto-fetch.\"),\n version_message: z.string().optional(),\n }),\n },\n);\n\nexport const confluenceDeleteCommentTool = tool(\n async ({ comment_id, kind }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const segment = COMMENT_KIND_TO_PATH[kind];\n if (!segment) {\n return JSON.stringify({ error: `unknown kind \"${kind}\". Expected 'footer' or 'inline'.` });\n }\n const data = await atlassianFetch(\n auth,\n `/wiki/api/v2/${segment}/${encodeURIComponent(comment_id)}`,\n { method: \"DELETE\" },\n ) as { error?: string } | string;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, deleted_comment_id: comment_id, kind });\n },\n {\n name: \"confluence_delete_comment\",\n description:\n \"Permanently delete a Confluence comment (v2). Pass `kind: 'footer' | 'inline'`. **Destructive — \" +\n \"no undo.** Disable to make the agent unable to delete comments.\",\n schema: z.object({\n comment_id: z.string(),\n kind: z.enum([\"footer\", \"inline\"]),\n }),\n },\n);\n\nexport const confluenceRemoveLabelTool = tool(\n async ({ page_id, label }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n // v1 fallback — v2 Label group is read-only as of 2026-05-28 (CONFCLOUD-76866).\n // The v1 endpoint accepts the label name as a query param; the prefix\n // defaults to \"global\" which is what confluence_add_label uses.\n const data = await atlassianFetch(\n auth,\n `/wiki/rest/api/content/${encodeURIComponent(page_id)}/label?name=${encodeURIComponent(label)}`,\n { method: \"DELETE\" },\n ) as { error?: string } | string;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, page_id, removed_label: label });\n },\n {\n name: \"confluence_remove_label\",\n description:\n \"Remove a single label from a Confluence page. Uses the v1 endpoint (v2 Label group is still \" +\n \"read-only as of 2026). Counterpart to confluence_add_label.\",\n schema: z.object({\n page_id: z.string(),\n label: z.string().describe(\"Label name to remove (no prefix; we always use 'global')\"),\n }),\n },\n);\n\nexport const confluenceDeleteAttachmentTool = tool(\n async ({ attachment_id, purge, confirm }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (purge && confirm !== attachment_id) {\n return JSON.stringify({\n error:\n `Refusing to permanently delete attachment ${attachment_id}: purge=true requires confirm to equal attachment_id. ` +\n `A purged attachment cannot be restored.`,\n });\n }\n const qs = purge ? `?purge=true` : \"\";\n const data = await atlassianFetch(\n auth,\n `/wiki/api/v2/attachments/${encodeURIComponent(attachment_id)}${qs}`,\n { method: \"DELETE\" },\n ) as { error?: string } | string;\n if (data && typeof data === \"object\" && \"error\" in data) return JSON.stringify(data);\n return JSON.stringify({ ok: true, deleted_attachment_id: attachment_id, purged: !!purge });\n },\n {\n name: \"confluence_delete_attachment\",\n description:\n \"Delete a Confluence attachment by id (v2). Default soft-deletes (trash, restorable). Pass \" +\n \"purge=true for permanent deletion, which **also requires `confirm` to equal attachment_id** \" +\n \"as a guardrail.\",\n schema: z.object({\n attachment_id: z.string(),\n purge: z.boolean().optional(),\n confirm: z.string().optional().describe(\"Required when purge=true; must equal attachment_id.\"),\n }),\n },\n);\n\n// ── Helpers ─────────────────────────────────────────────────────────────────\n\n// Convert plain text → Confluence storage-format XHTML. Splits on blank lines\n// for paragraphs and uses <br/> for single newlines. Escapes &, <, > because\n// Confluence storage rejects unescaped ampersands and stray angle brackets.\n// Pure — exported for unit testing.\nexport function confluenceTextToStorage(text: string): string {\n if (text.length === 0) return \"<p></p>\";\n const escape = (s: string) =>\n s.replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\");\n return text\n .split(/\\n{2,}/)\n .map((para) => `<p>${para.split(\"\\n\").map(escape).join(\"<br/>\")}</p>`)\n .join(\"\");\n}\n\n// Extract the opaque cursor query param from a Confluence v2 `_links.next` URL.\n// v2 cursors are not safe to construct — Atlassian explicitly says \"always parse\n// the next link, never build it\". Pure — exported for unit testing.\nexport function parseV2NextCursor(linksNext: string | undefined): string | null {\n if (!linksNext) return null;\n const m = linksNext.match(/[?&]cursor=([^&]+)/);\n return m ? decodeURIComponent(m[1]) : null;\n}\n\n// Body input dispatcher used by create_page / update_page / add_comment.\n// Callers pass body_text XOR body_storage; this resolves to the wire format\n// or a structured error for the LLM. body_storage is rejected if it contains\n// <script>/<style> — Confluence storage rejects those with opaque 400s, so\n// catch it here with a useful message.\nfunction resolveBody(input: { body_text?: string; body_storage?: string }):\n | { value: string; representation: \"storage\" }\n | { error: string }\n{\n const hasText = typeof input.body_text === \"string\";\n const hasStorage = typeof input.body_storage === \"string\";\n if (hasText && hasStorage) {\n return { error: \"pass exactly one of body_text or body_storage, not both\" };\n }\n if (!hasText && !hasStorage) {\n return { error: \"pass exactly one of body_text or body_storage\" };\n }\n if (hasStorage) {\n const s = input.body_storage!;\n if (/<\\s*(script|style)[\\s>]/i.test(s)) {\n return { error: \"body_storage rejected: <script>/<style> tags are not allowed by Confluence storage format\" };\n }\n return { value: s, representation: \"storage\" };\n }\n return { value: confluenceTextToStorage(input.body_text!), representation: \"storage\" };\n}\n\n// Per-site cache of space key → numeric space id. v2 page endpoints take\n// spaceId, but humans (and the LLM) think in space keys. 1h TTL mirrors\n// loadJiraFields below.\nconst SPACE_ID_CACHE_TTL_MS = 60 * 60 * 1000;\nconst spaceIdCache = new Map<string, { id: string; loaded: number }>();\n\nasync function resolveSpaceId(\n auth: AtlassianAuth,\n spaceKey: string,\n): Promise<string | { error: string }> {\n const cacheKey = `${auth.url}|${spaceKey}`;\n const cached = spaceIdCache.get(cacheKey);\n if (cached && Date.now() - cached.loaded < SPACE_ID_CACHE_TTL_MS) return cached.id;\n const data = await atlassianFetch(\n auth,\n `/wiki/api/v2/spaces?keys=${encodeURIComponent(spaceKey)}&limit=1`,\n ) as { results?: Array<{ id: string; key: string }>; error?: string };\n if (\"error\" in data && data.error) return { error: data.error };\n const hit = (data.results ?? []).find((s) => s.key === spaceKey) ?? data.results?.[0];\n if (!hit?.id) return { error: `space key \"${spaceKey}\" not found` };\n spaceIdCache.set(cacheKey, { id: hit.id, loaded: Date.now() });\n return hit.id;\n}\n\n// Per-site cache of /rest/api/3/field. Custom field IDs are stable per site,\n// but display names can be edited; 1h TTL keeps us fresh without thrashing.\nexport interface JiraFieldDef { id: string; name: string; custom: boolean }\nconst FIELD_CACHE_TTL_MS = 60 * 60 * 1000;\nconst fieldCache = new Map<string, { fields: JiraFieldDef[]; loaded: number }>();\n\nasync function loadJiraFields(auth: AtlassianAuth): Promise<JiraFieldDef[] | { error: string }> {\n const cached = fieldCache.get(auth.url);\n if (cached && Date.now() - cached.loaded < FIELD_CACHE_TTL_MS) return cached.fields;\n const data = await atlassianFetch(auth, `/rest/api/3/field`) as\n | Array<{ id: string; name: string; custom: boolean }>\n | { error?: string };\n if (!Array.isArray(data)) return data as { error: string };\n const fields = data.map((f) => ({ id: f.id, name: f.name, custom: f.custom }));\n fieldCache.set(auth.url, { fields, loaded: Date.now() });\n return fields;\n}\n\n// Pure helper — exported for unit testing. Given a list of caller inputs and\n// the site's field definitions, partition into resolved (matched by id or\n// case-insensitive display name) and unresolved.\nexport function resolveCustomFieldNames(\n inputs: string[],\n fields: JiraFieldDef[],\n): { resolved: Array<{ input: string; id: string; name: string }>; unresolved: string[] } {\n const byId = new Map<string, JiraFieldDef>();\n const byName = new Map<string, JiraFieldDef>();\n for (const f of fields) {\n byId.set(f.id, f);\n byName.set(f.name.toLowerCase(), f);\n }\n const resolved: Array<{ input: string; id: string; name: string }> = [];\n const unresolved: string[] = [];\n for (const input of inputs) {\n const trimmed = input.trim();\n const hit = byId.get(trimmed) ?? byName.get(trimmed.toLowerCase());\n if (hit) resolved.push({ input, id: hit.id, name: hit.name });\n else unresolved.push(input);\n }\n return { resolved, unresolved };\n}\n\n// Coerce a Jira field value (which can be string, number, ADF doc, option\n// object, user object, array of those) into something an LLM can read. When\n// Jira returns a renderedFields HTML version, prefer that — it's the author's\n// formatting, flattened.\nexport function extractFieldValue(raw: unknown, renderedHTML: unknown): unknown {\n if (typeof renderedHTML === \"string\" && renderedHTML.length > 0) {\n return stripHtml(renderedHTML);\n }\n if (raw == null) return null;\n if (typeof raw === \"string\" || typeof raw === \"number\" || typeof raw === \"boolean\") return raw;\n if (Array.isArray(raw)) return raw.map(coerceItem);\n if (typeof raw === \"object\") {\n const obj = raw as Record<string, unknown>;\n if (obj.type === \"doc\" && Array.isArray(obj.content)) return simplifyADF(obj);\n if (typeof obj.value === \"string\") return obj.value;\n if (typeof obj.displayName === \"string\") return obj.displayName;\n if (typeof obj.name === \"string\") return obj.name;\n return obj;\n }\n return raw;\n}\n\nfunction coerceItem(item: unknown): unknown {\n if (!item || typeof item !== \"object\") return item;\n const obj = item as Record<string, unknown>;\n if (typeof obj.value === \"string\") return obj.value;\n if (typeof obj.name === \"string\") return obj.name;\n if (typeof obj.displayName === \"string\") return obj.displayName;\n return obj;\n}\n\nfunction stripHtml(html: string): string {\n return html\n .replace(/<br\\s*\\/?>/gi, \"\\n\")\n .replace(/<\\/p>/gi, \"\\n\\n\")\n .replace(/<\\/li>/gi, \"\\n\")\n .replace(/<li[^>]*>/gi, \"• \")\n .replace(/<[^>]+>/g, \"\")\n .replace(/ /g, \" \")\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/'/g, \"'\")\n .replace(/"/g, '\"')\n .replace(/[ \\t]+\\n/g, \"\\n\")\n .replace(/\\n{3,}/g, \"\\n\\n\")\n .trim();\n}\n\n// Atlassian's REST API takes ADF (Atlassian Document Format), not plain text.\n// This wraps a plain string so the agent doesn't have to know the schema.\nfunction textToADF(text: string): unknown {\n type ADFNode = { type: string; text?: string };\n return {\n type: \"doc\",\n version: 1,\n content: text.split(/\\n\\n+/).map((para) => ({\n type: \"paragraph\",\n content: para.split(\"\\n\").flatMap<ADFNode>((line, i) =>\n i === 0\n ? [{ type: \"text\", text: line }]\n : [{ type: \"hardBreak\" }, { type: \"text\", text: line }],\n ),\n })),\n };\n}\n\n// Best-effort flatten of an ADF document back to plain text. Doesn't preserve\n// formatting but gives the agent something readable to summarize.\nfunction simplifyADF(adf: unknown): string {\n if (!adf || typeof adf !== \"object\") return typeof adf === \"string\" ? adf : \"\";\n const out: string[] = [];\n walk(adf);\n return out.join(\"\").trim();\n\n function walk(node: unknown): void {\n if (!node || typeof node !== \"object\") return;\n const n = node as Record<string, unknown>;\n if (n.type === \"text\" && typeof n.text === \"string\") out.push(n.text);\n if (n.type === \"hardBreak\") out.push(\"\\n\");\n if (n.type === \"paragraph\") { walkChildren(n.content); out.push(\"\\n\\n\"); }\n else if (n.type === \"bulletList\" || n.type === \"orderedList\") walkChildren(n.content);\n else if (n.type === \"listItem\") { out.push(\"• \"); walkChildren(n.content); }\n else walkChildren(n.content);\n }\n function walkChildren(children: unknown): void {\n if (Array.isArray(children)) for (const c of children) walk(c);\n }\n}\n\nregisterTools(\"Atlassian\", \"read\", [\n jiraSearchTool, jiraGetIssueTool, jiraFindUserTool,\n jiraListBoardsTool, jiraGetBoardTool,\n jiraListSprintsTool, jiraGetSprintTool,\n jiraGetCommentsTool, jiraGetAttachmentContentTool,\n jiraListWorklogsTool, jiraGetChangelogTool,\n jiraListProjectsTool, jiraGetProjectTool,\n jiraListVersionsTool, jiraListComponentsTool, jiraListMetaTool,\n confluenceSearchTool, confluenceGetPageTool,\n confluenceGetPageByTitleTool, confluenceGetPageChildrenTool,\n confluenceGetPageAncestorsTool, confluenceListSpacesTool,\n confluenceGetCommentsTool, confluenceListAttachmentsTool,\n confluenceGetLabelsTool, confluenceGetAttachmentContentTool,\n]);\nregisterTools(\"Atlassian\", \"execute\", [\n jiraCreateIssueTool, jiraCreateIssuesBulkTool, jiraUpdateIssueTool,\n jiraAddCommentTool, jiraTransitionsTool,\n jiraLinkIssuesTool, jiraAddRemoteLinkTool, jiraDeleteLinkTool,\n jiraUploadAttachmentTool, jiraDeleteIssueTool,\n jiraCreateSprintTool, jiraUpdateSprintTool, jiraDeleteSprintTool,\n jiraMoveIssuesToSprintTool, jiraMoveIssuesToBacklogTool, jiraRankIssuesTool,\n jiraUpdateCommentTool, jiraDeleteCommentTool, jiraDeleteAttachmentTool,\n jiraAddWorklogTool,\n jiraCreateVersionTool, jiraUpdateVersionTool, jiraCreateComponentTool,\n confluenceCreatePageTool, confluenceUpdatePageTool,\n confluenceAddCommentTool, confluenceMovePageTool,\n confluenceUploadAttachmentTool, confluenceAddLabelTool,\n confluenceDeletePageTool, confluenceUpdateCommentTool, confluenceDeleteCommentTool,\n confluenceRemoveLabelTool, confluenceDeleteAttachmentTool,\n]);\n","/**\n * Native GitHub tools — direct REST API calls, no MCP, no `gh` CLI.\n *\n * Mirrors the Atlassian tool (lib/tools/atlassian.ts) in shape: the agent\n * never shells out, every call goes through the same `fetch` global that\n * already honours the in-app HTTP proxy + custom CA bundle (ADR-0009,\n * ADR-0012). That means these tools work on a corp laptop with the MCP\n * install path blocked, which was the whole point of building them native.\n *\n * Auth resolution (priority order):\n * 1. Env: GITHUB_TOKEN, then GH_TOKEN (matches gh CLI's fallback chain).\n * 2. Memory store: namespace=\"integrations\", key=\"github\", value={ token }.\n *\n * The agent populates option 2 via the propose_config_change /\n * enable_integration flow (ADR-0010); env wins because deployment-level\n * config should beat per-user secrets stored in the local DB.\n */\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { getIntegrationRaw } from \"@/lib/stores/integrations\";\nimport { parseJsonSafe } from \"@/lib/utils/json\";\nimport { isLikelyBinary } from \"@/lib/documents/indexer\";\nimport { registerTools } from \"./registry\";\n\nexport interface GitHubAuth {\n token: string;\n}\n\n// Exposed so the integrations test endpoint can probe the live API after save.\nexport function _resolveGithubAuth(): GitHubAuth | { error: string } {\n return resolveAuth();\n}\n\nfunction resolveAuth(): GitHubAuth | { error: string } {\n const env = process.env.GITHUB_TOKEN ?? process.env.GH_TOKEN;\n if (env && env.trim()) return { token: env.trim() };\n const saved = getIntegrationRaw(\"github\");\n if (saved?.token) return { token: saved.token };\n return {\n error:\n \"GitHub not configured. Open the gear menu → Integrations and add a Personal Access Token. \" +\n \"Create one at github.com/settings/tokens with scopes: repo, read:org. \" +\n \"(Or set GITHUB_TOKEN / GH_TOKEN as an env var.)\",\n };\n}\n\nconst API = \"https://api.github.com\";\n\nasync function ghFetch(\n auth: GitHubAuth,\n path: string,\n init?: RequestInit,\n): Promise<unknown> {\n const url = path.startsWith(\"http\") ? path : `${API}${path}`;\n const res = await fetch(url, {\n ...init,\n headers: {\n Authorization: `Bearer ${auth.token}`,\n Accept: \"application/vnd.github+json\",\n \"X-GitHub-Api-Version\": \"2022-11-28\",\n \"User-Agent\": \"Jarela\",\n ...(init?.headers ?? {}),\n },\n });\n const text = await res.text();\n if (!res.ok) {\n return { error: `GitHub ${res.status}: ${text.slice(0, 500)}`, url };\n }\n if (!text) return {};\n return parseJsonSafe<unknown>(text, text);\n}\n\n// Exposed for sibling modules that need the same auth/proxy/CA-bundle\n// behaviour without duplicating the wrapper (currently:\n// `lib/documents/remote/github.ts`, ADR-0029). Mirrors `_atlassianFetch`.\nexport async function _ghFetch(\n auth: GitHubAuth,\n path: string,\n init?: RequestInit,\n): Promise<unknown> {\n return ghFetch(auth, path, init);\n}\n\n// ── Shared helpers ─────────────────────────────────────────────────────────\n\nconst BODY_CAP = 20_000;\nconst COMMENT_CAP = 8_000;\nconst PATCH_CAP = 8_000;\nconst SNIPPET_CAP = 400;\n\n// Pure-fn body cap. Returns the same `body` field shape as the existing\n// inline ternaries in github_get_issue / github_get_pull (str + truncated\n// flag) so the agent doesn't need to handle two shapes.\nexport function truncate(text: string, cap: number): { text: string; truncated: boolean } {\n if (text.length <= cap) return { text, truncated: false };\n return { text: text.slice(0, cap), truncated: true };\n}\n\n// `/repos/.../contents/{path}` returns a base64-encoded blob; the API also\n// returns the same response shape for directories (as an array). Decode +\n// detect binary so the agent gets useful output for text and a clear\n// not-text signal for everything else.\nexport interface DecodedBlob {\n binary: boolean;\n text?: string;\n size_bytes: number;\n}\nexport function decodeContentsBlob(content: string, encoding: string | undefined): DecodedBlob {\n if (!content) return { binary: false, text: \"\", size_bytes: 0 };\n const b64 = encoding === \"base64\" ? content.replace(/\\s+/g, \"\") : \"\";\n const buf = b64 ? Buffer.from(b64, \"base64\") : Buffer.from(content, \"utf8\");\n if (isLikelyBinary(buf)) return { binary: true, size_bytes: buf.length };\n return { binary: false, text: buf.toString(\"utf8\"), size_bytes: buf.length };\n}\n\n// Trim repo URLs on issue/PR responses to user-facing html_urls (the API\n// returns api.github.com/repos/... which is useless for a human).\ntype GhUser = { login?: string } | null;\ntype GhLabel = { name?: string };\n\nfunction liteUser(u: unknown): string | null {\n return (u as GhUser)?.login ?? null;\n}\nfunction liteLabels(labels: unknown): string[] {\n return (labels as GhLabel[] | undefined ?? []).map((l) => l.name).filter(Boolean) as string[];\n}\n\ntype GhIssueLite = {\n number?: number;\n title?: string;\n state?: string;\n html_url?: string;\n user?: GhUser;\n labels?: GhLabel[];\n pull_request?: unknown; // presence means \"this issue is actually a PR\"\n updated_at?: string;\n comments?: number;\n};\n\n// ── Issue tools ────────────────────────────────────────────────────────────\n\nexport const githubSearchIssuesTool = tool(\n async ({ q, repo, max_results }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const limit = Math.min(max_results ?? 25, 100);\n // `repo:owner/name` is the dominant filter — accept it as a separate\n // parameter so the agent doesn't have to remember GitHub's search syntax\n // for the common case. Anything else goes in `q`.\n const query = repo ? `repo:${repo} ${q}` : q;\n const data = await ghFetch(\n auth,\n `/search/issues?q=${encodeURIComponent(query)}&per_page=${limit}`,\n ) as { items?: GhIssueLite[]; total_count?: number; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n total: data.total_count ?? 0,\n items: (data.items ?? []).map((i) => ({\n number: i.number,\n title: i.title,\n state: i.state,\n is_pr: !!i.pull_request,\n url: i.html_url,\n user: liteUser(i.user),\n labels: liteLabels(i.labels),\n updated_at: i.updated_at,\n comments: i.comments ?? 0,\n })),\n });\n },\n {\n name: \"github_search_issues\",\n description:\n \"Search GitHub issues AND pull requests with the same query syntax as the github.com search bar. \" +\n \"**PREFER THIS over shell-exec'ing the `gh` CLI.** Pass `repo` (\\\"owner/name\\\") to scope the search \" +\n \"to a single repo — the tool prepends `repo:owner/name ` automatically. The `q` body accepts the \" +\n \"full GitHub search vocabulary: 'is:issue is:open assignee:@me', 'is:pr review-requested:@me', \" +\n \"'label:bug created:>2026-01-01', etc. `is_pr` in the response distinguishes PRs from issues.\",\n schema: z.object({\n q: z.string().describe(\"GitHub search query (e.g. 'is:open is:issue label:bug')\"),\n repo: z.string().optional().describe(\"Optional 'owner/name' shortcut; prepended as repo: filter\"),\n max_results: z.number().optional().describe(\"Max items (default 25, max 100)\"),\n }),\n },\n);\n\nexport const githubGetIssueTool = tool(\n async ({ owner, repo, number }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/issues/${number}`,\n ) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n const assignees = (data.assignees as Array<{ login?: string }> | undefined ?? [])\n .map((a) => a.login).filter(Boolean);\n const cap = truncate(typeof data.body === \"string\" ? data.body : \"\", BODY_CAP);\n return JSON.stringify({\n number: data.number,\n title: data.title,\n state: data.state,\n is_pr: !!data.pull_request,\n url: data.html_url,\n author: liteUser(data.user),\n labels: liteLabels(data.labels),\n assignees,\n created_at: data.created_at,\n updated_at: data.updated_at,\n closed_at: data.closed_at,\n comments: data.comments,\n body: cap.text,\n truncated: cap.truncated,\n });\n },\n {\n name: \"github_get_issue\",\n description:\n \"Fetch a single issue (or PR — same endpoint) by number. Returns body capped at 20KB, plus labels, \" +\n \"assignees, and timestamps. **PREFER THIS over shell-exec'ing the `gh` CLI.**\",\n schema: z.object({\n owner: z.string().describe(\"Repository owner (user or org)\"),\n repo: z.string().describe(\"Repository name\"),\n number: z.number().int().positive().describe(\"Issue or PR number\"),\n }),\n },\n);\n\nexport const githubCreateIssueTool = tool(\n async ({ owner, repo, title, body, labels, assignees }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const payload: Record<string, unknown> = { title };\n if (body) payload.body = body;\n if (labels?.length) payload.labels = labels;\n if (assignees?.length) payload.assignees = assignees;\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/issues`,\n { method: \"POST\", body: JSON.stringify(payload) },\n ) as { number?: number; html_url?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({ ok: true, number: data.number, url: data.html_url });\n },\n {\n name: \"github_create_issue\",\n description:\n \"Open a new issue in a repository. **PREFER THIS over shell-exec'ing the `gh` CLI.** Labels and \" +\n \"assignees must already exist on the repo — invalid values produce a 422.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n title: z.string().describe(\"Issue title\"),\n body: z.string().optional().describe(\"Markdown body\"),\n labels: z.array(z.string()).optional().describe(\"Existing label names\"),\n assignees: z.array(z.string()).optional().describe(\"GitHub usernames with access\"),\n }),\n },\n);\n\nexport const githubAddCommentTool = tool(\n async ({ owner, repo, number, body }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n // Same endpoint for issues AND PRs — GitHub treats PR comments as issue\n // comments (the line-level review comments are a different surface).\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/issues/${number}/comments`,\n { method: \"POST\", body: JSON.stringify({ body }) },\n ) as { id?: number; html_url?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({ ok: true, comment_id: data.id, url: data.html_url });\n },\n {\n name: \"github_add_comment\",\n description:\n \"Post a comment on an issue or pull request (GitHub treats both the same). \" +\n \"**PREFER THIS over shell-exec'ing the `gh` CLI.** Body is rendered as GitHub-flavored Markdown.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n number: z.number().int().positive(),\n body: z.string().describe(\"Comment body (GitHub-flavored Markdown)\"),\n }),\n },\n);\n\n// ── Pull-request tools ─────────────────────────────────────────────────────\n\nexport const githubListPullsTool = tool(\n async ({ owner, repo, state, head, base, max_results }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const limit = Math.min(max_results ?? 25, 100);\n const params = new URLSearchParams({ per_page: String(limit) });\n if (state) params.set(\"state\", state);\n if (head) params.set(\"head\", head);\n if (base) params.set(\"base\", base);\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls?${params.toString()}`,\n ) as Array<Record<string, unknown>> | { error?: string; message?: string };\n if (!Array.isArray(data)) return JSON.stringify(data);\n return JSON.stringify({\n pulls: data.map((p) => ({\n number: p.number,\n title: p.title,\n state: p.state,\n draft: p.draft,\n url: p.html_url,\n user: liteUser(p.user),\n head: (p.head as { ref?: string } | null)?.ref ?? null,\n base: (p.base as { ref?: string } | null)?.ref ?? null,\n created_at: p.created_at,\n updated_at: p.updated_at,\n })),\n });\n },\n {\n name: \"github_list_pulls\",\n description:\n \"List pull requests for a repository, optionally filtered by state / head branch / base branch. \" +\n \"**PREFER THIS over shell-exec'ing the `gh` CLI.** For richer detail on a single PR (mergeable, \" +\n \"review state, file count) call github_get_pull.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n state: z.enum([\"open\", \"closed\", \"all\"]).optional().describe(\"Default: open\"),\n head: z.string().optional().describe(\"Filter by head: 'user:branch' or 'org:branch'\"),\n base: z.string().optional().describe(\"Filter by base branch (e.g. 'main')\"),\n max_results: z.number().optional().describe(\"Max PRs (default 25, max 100)\"),\n }),\n },\n);\n\nexport const githubGetPullTool = tool(\n async ({ owner, repo, number }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls/${number}`,\n ) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n const head = data.head as { ref?: string; sha?: string; repo?: { full_name?: string } } | null;\n const base = data.base as { ref?: string; sha?: string } | null;\n const cap = truncate(typeof data.body === \"string\" ? data.body : \"\", BODY_CAP);\n return JSON.stringify({\n number: data.number,\n title: data.title,\n state: data.state,\n draft: data.draft,\n merged: data.merged,\n mergeable: data.mergeable, // null = GitHub still computing\n mergeable_state: data.mergeable_state,\n url: data.html_url,\n author: liteUser(data.user),\n head: head ? { ref: head.ref, sha: head.sha, repo: head.repo?.full_name } : null,\n base: base ? { ref: base.ref, sha: base.sha } : null,\n changed_files: data.changed_files,\n additions: data.additions,\n deletions: data.deletions,\n review_comments: data.review_comments,\n comments: data.comments,\n created_at: data.created_at,\n updated_at: data.updated_at,\n merged_at: data.merged_at,\n body: cap.text,\n truncated: cap.truncated,\n });\n },\n {\n name: \"github_get_pull\",\n description:\n \"Fetch detail on a single pull request — head/base SHAs, mergeable state, additions/deletions, \" +\n \"changed files count, review comment count. **PREFER THIS over shell-exec'ing the `gh` CLI.** \" +\n \"Note: `mergeable` may be null on a freshly-pushed PR; GitHub computes it asynchronously.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n number: z.number().int().positive(),\n }),\n },\n);\n\n// ── Repo info ───────────────────────────────────────────────────────────────\n\nexport const githubGetRepoTool = tool(\n async ({ owner, repo }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}`,\n ) as Record<string, unknown> & { error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n full_name: data.full_name,\n url: data.html_url,\n description: data.description,\n visibility: data.visibility ?? (data.private ? \"private\" : \"public\"),\n default_branch: data.default_branch,\n topics: data.topics ?? [],\n language: data.language,\n stars: data.stargazers_count,\n forks: data.forks_count,\n open_issues: data.open_issues_count,\n archived: data.archived,\n pushed_at: data.pushed_at,\n });\n },\n {\n name: \"github_get_repo\",\n description:\n \"Fetch repo summary (default branch, visibility, description, topics, star/fork counts, \" +\n \"open-issue count). **PREFER THIS over shell-exec'ing the `gh` CLI.** Useful before opening \" +\n \"an issue (to confirm the repo exists / pick the right default branch).\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n }),\n },\n);\n\n// ── Issue write / read (cont'd) ────────────────────────────────────────────\n\nexport const githubUpdateIssueTool = tool(\n async ({ owner, repo, number, title, body, state, state_reason, labels, assignees }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const payload: Record<string, unknown> = {};\n if (title !== undefined) payload.title = title;\n if (body !== undefined) payload.body = body;\n if (state !== undefined) payload.state = state;\n if (state_reason !== undefined) payload.state_reason = state_reason;\n if (labels !== undefined) payload.labels = labels;\n if (assignees !== undefined) payload.assignees = assignees;\n if (Object.keys(payload).length === 0) {\n return JSON.stringify({ error: \"no fields to update — pass at least one of title/body/state/labels/assignees\" });\n }\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/issues/${number}`,\n { method: \"PATCH\", body: JSON.stringify(payload) },\n ) as { number?: number; html_url?: string; state?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n number: data.number,\n state: data.state,\n url: data.html_url,\n updated_fields: Object.keys(payload),\n });\n },\n {\n name: \"github_update_issue\",\n description:\n \"Edit an issue or PR (same endpoint): change title, body, labels, assignees, or close/reopen via \" +\n \"`state`. **PREFER THIS over shell-exec'ing the `gh` CLI.** Pass `state: \\\"closed\\\"` with \" +\n \"`state_reason: \\\"completed\\\"` for done-as-intended, or `\\\"not_planned\\\"` for won't-fix.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n number: z.number().int().positive(),\n title: z.string().optional(),\n body: z.string().optional().describe(\"New issue body (Markdown). Replaces, doesn't append.\"),\n state: z.enum([\"open\", \"closed\"]).optional(),\n state_reason: z.enum([\"completed\", \"not_planned\", \"reopened\"]).optional(),\n labels: z.array(z.string()).optional().describe(\"Replaces the label set entirely.\"),\n assignees: z.array(z.string()).optional().describe(\"Replaces the assignee set entirely.\"),\n }),\n },\n);\n\nexport const githubListIssueCommentsTool = tool(\n async ({ owner, repo, number, max_results }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const limit = Math.min(max_results ?? 25, 100);\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/issues/${number}/comments?per_page=${limit}`,\n ) as Array<Record<string, unknown>> | { error?: string };\n if (!Array.isArray(data)) return JSON.stringify(data);\n return JSON.stringify({\n comments: data.map((c) => {\n const cap = truncate(typeof c.body === \"string\" ? c.body : \"\", COMMENT_CAP);\n return {\n id: c.id,\n user: liteUser(c.user),\n created_at: c.created_at,\n updated_at: c.updated_at,\n url: c.html_url,\n body: cap.text,\n truncated: cap.truncated,\n };\n }),\n });\n },\n {\n name: \"github_list_issue_comments\",\n description:\n \"List comments on an issue or PR. **PREFER THIS over shell-exec'ing the `gh` CLI.** Each comment \" +\n \"body is capped at 8 KB; `truncated: true` flags ones that hit the cap.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n number: z.number().int().positive(),\n max_results: z.number().optional().describe(\"Max comments (default 25, max 100)\"),\n }),\n },\n);\n\n// ── Pull-request write ─────────────────────────────────────────────────────\n\nexport const githubCreatePullTool = tool(\n async ({ owner, repo, title, head, base, body, draft, maintainer_can_modify }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const payload: Record<string, unknown> = { title, head, base };\n if (body !== undefined) payload.body = body;\n if (draft !== undefined) payload.draft = draft;\n if (maintainer_can_modify !== undefined) payload.maintainer_can_modify = maintainer_can_modify;\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls`,\n { method: \"POST\", body: JSON.stringify(payload) },\n ) as { number?: number; html_url?: string; draft?: boolean; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({ ok: true, number: data.number, draft: data.draft, url: data.html_url });\n },\n {\n name: \"github_create_pull\",\n description:\n \"Open a pull request. **PREFER THIS over shell-exec'ing the `gh` CLI.** `head` is the branch with \" +\n \"your changes (use `user:branch` for cross-fork PRs); `base` is the branch you want to merge into. \" +\n \"Returns 422 if the head/base pair has no diff or if the branches don't exist.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n title: z.string(),\n head: z.string().describe(\"Source branch ('feature/x' for same-repo, 'user:branch' for fork PRs)\"),\n base: z.string().describe(\"Target branch (typically 'main')\"),\n body: z.string().optional().describe(\"PR description (Markdown)\"),\n draft: z.boolean().optional().describe(\"Open as draft (default false)\"),\n maintainer_can_modify: z.boolean().optional()\n .describe(\"Allow upstream maintainers to push to your fork branch (default true)\"),\n }),\n },\n);\n\nexport const githubUpdatePullTool = tool(\n async ({ owner, repo, number, title, body, state, base, maintainer_can_modify }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const payload: Record<string, unknown> = {};\n if (title !== undefined) payload.title = title;\n if (body !== undefined) payload.body = body;\n if (state !== undefined) payload.state = state;\n if (base !== undefined) payload.base = base;\n if (maintainer_can_modify !== undefined) payload.maintainer_can_modify = maintainer_can_modify;\n if (Object.keys(payload).length === 0) {\n return JSON.stringify({ error: \"no fields to update — pass at least one of title/body/state/base\" });\n }\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls/${number}`,\n { method: \"PATCH\", body: JSON.stringify(payload) },\n ) as { number?: number; html_url?: string; state?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n number: data.number,\n state: data.state,\n url: data.html_url,\n updated_fields: Object.keys(payload),\n });\n },\n {\n name: \"github_update_pull\",\n description:\n \"Edit a pull request: title, body, base branch, or close/reopen. **PREFER THIS over shell-exec'ing \" +\n \"the `gh` CLI.** To MERGE a PR use github_merge_pull — `state` here only opens / closes.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n number: z.number().int().positive(),\n title: z.string().optional(),\n body: z.string().optional(),\n state: z.enum([\"open\", \"closed\"]).optional()\n .describe(\"`closed` here means 'close without merging'. Use github_merge_pull to merge.\"),\n base: z.string().optional().describe(\"Re-target the PR at a different base branch.\"),\n maintainer_can_modify: z.boolean().optional(),\n }),\n },\n);\n\nexport const githubMergePullTool = tool(\n async ({ owner, repo, number, method, commit_title, commit_message, sha }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const payload: Record<string, unknown> = {};\n if (commit_title !== undefined) payload.commit_title = commit_title;\n if (commit_message !== undefined) payload.commit_message = commit_message;\n if (method !== undefined) payload.merge_method = method;\n if (sha !== undefined) payload.sha = sha;\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls/${number}/merge`,\n { method: \"PUT\", body: JSON.stringify(payload) },\n ) as { merged?: boolean; sha?: string; message?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: !!data.merged,\n merged_sha: data.sha ?? null,\n message: data.message ?? null,\n });\n },\n {\n name: \"github_merge_pull\",\n description:\n \"Merge a pull request. **PREFER THIS over shell-exec'ing the `gh` CLI.** `method` selects the \" +\n \"merge strategy (default `merge`); pass `sha` to refuse the merge if the PR head has been \" +\n \"force-pushed since you last looked. 405 means the PR isn't mergeable yet (still in CI / has \" +\n \"conflicts / needs review); 409 means the `sha` guard tripped.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n number: z.number().int().positive(),\n method: z.enum([\"merge\", \"squash\", \"rebase\"]).optional(),\n commit_title: z.string().optional()\n .describe(\"Title for the merge commit (or squash commit). Default: GitHub's auto-generated title.\"),\n commit_message: z.string().optional(),\n sha: z.string().optional()\n .describe(\"Refuse to merge unless the PR head still matches this SHA — guards against TOCTOU.\"),\n }),\n },\n);\n\nexport const githubRequestReviewersTool = tool(\n async ({ owner, repo, number, reviewers, team_reviewers }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (!reviewers?.length && !team_reviewers?.length) {\n return JSON.stringify({ error: \"pass at least one of reviewers or team_reviewers\" });\n }\n const payload: Record<string, unknown> = {};\n if (reviewers?.length) payload.reviewers = reviewers;\n if (team_reviewers?.length) payload.team_reviewers = team_reviewers;\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls/${number}/requested_reviewers`,\n { method: \"POST\", body: JSON.stringify(payload) },\n ) as {\n requested_reviewers?: Array<{ login?: string }>;\n requested_teams?: Array<{ slug?: string }>;\n html_url?: string;\n error?: string;\n };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n ok: true,\n requested_users: (data.requested_reviewers ?? []).map((u) => u.login).filter(Boolean),\n requested_teams: (data.requested_teams ?? []).map((t) => t.slug).filter(Boolean),\n url: data.html_url,\n });\n },\n {\n name: \"github_request_reviewers\",\n description:\n \"Request review on a pull request from one or more users and/or teams. **PREFER THIS over \" +\n \"shell-exec'ing the `gh` CLI.** GitHub silently drops invalid usernames / team slugs — check the \" +\n \"returned `requested_users` / `requested_teams` to see who actually got a notification.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n number: z.number().int().positive(),\n reviewers: z.array(z.string()).optional().describe(\"GitHub usernames\"),\n team_reviewers: z.array(z.string()).optional().describe(\"Team slugs (org-scoped)\"),\n }),\n },\n);\n\nexport const githubCreateReviewTool = tool(\n async ({ owner, repo, number, event, body, commit_id }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n if (event === \"REQUEST_CHANGES\" && !body?.trim()) {\n return JSON.stringify({ error: \"REQUEST_CHANGES requires a non-empty body explaining what to change\" });\n }\n const payload: Record<string, unknown> = { event };\n if (body !== undefined) payload.body = body;\n if (commit_id !== undefined) payload.commit_id = commit_id;\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls/${number}/reviews`,\n { method: \"POST\", body: JSON.stringify(payload) },\n ) as { id?: number; state?: string; html_url?: string; error?: string };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({ ok: true, review_id: data.id, state: data.state, url: data.html_url });\n },\n {\n name: \"github_create_review\",\n description:\n \"Submit a pull-request review (approve / request changes / leave a comment). **PREFER THIS over \" +\n \"shell-exec'ing the `gh` CLI.** `event=APPROVE` doesn't require a body. `event=REQUEST_CHANGES` \" +\n \"requires a body. Line-level inline review comments aren't supported by this tool yet — use the \" +\n \"GitHub UI for those.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n number: z.number().int().positive(),\n event: z.enum([\"APPROVE\", \"REQUEST_CHANGES\", \"COMMENT\"]),\n body: z.string().optional().describe(\"Review summary (Markdown). Required for REQUEST_CHANGES.\"),\n commit_id: z.string().optional().describe(\"Pin the review to a specific commit SHA.\"),\n }),\n },\n);\n\n// ── Pull-request read (cont'd) ─────────────────────────────────────────────\n\nexport const githubListPullFilesTool = tool(\n async ({ owner, repo, number, max_results }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const limit = Math.min(max_results ?? 30, 100);\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls/${number}/files?per_page=${limit}`,\n ) as Array<Record<string, unknown>> | { error?: string };\n if (!Array.isArray(data)) return JSON.stringify(data);\n return JSON.stringify({\n files: data.map((f) => {\n const patch = typeof f.patch === \"string\" ? truncate(f.patch, PATCH_CAP) : null;\n return {\n filename: f.filename,\n status: f.status, // added | modified | removed | renamed | …\n additions: f.additions,\n deletions: f.deletions,\n changes: f.changes,\n previous_filename: f.previous_filename,\n sha: f.sha,\n patch: patch?.text,\n patch_truncated: patch?.truncated ?? false,\n };\n }),\n });\n },\n {\n name: \"github_list_pull_files\",\n description:\n \"List files changed in a pull request, with per-file additions/deletions and (capped) patch text. \" +\n \"**PREFER THIS over shell-exec'ing the `gh` CLI.** Each patch caps at 8 KB; `patch_truncated: true` \" +\n \"means the diff was longer than that. GitHub itself caps the response at 3000 files.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n number: z.number().int().positive(),\n max_results: z.number().optional().describe(\"Max files (default 30, max 100)\"),\n }),\n },\n);\n\nexport const githubListPullReviewsTool = tool(\n async ({ owner, repo, number, max_results }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const limit = Math.min(max_results ?? 30, 100);\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls/${number}/reviews?per_page=${limit}`,\n ) as Array<Record<string, unknown>> | { error?: string };\n if (!Array.isArray(data)) return JSON.stringify(data);\n return JSON.stringify({\n reviews: data.map((r) => {\n const cap = truncate(typeof r.body === \"string\" ? r.body : \"\", COMMENT_CAP);\n return {\n id: r.id,\n user: liteUser(r.user),\n state: r.state, // APPROVED | CHANGES_REQUESTED | COMMENTED | DISMISSED | PENDING\n submitted_at: r.submitted_at,\n commit_id: r.commit_id,\n url: r.html_url,\n body: cap.text,\n truncated: cap.truncated,\n };\n }),\n });\n },\n {\n name: \"github_list_pull_reviews\",\n description:\n \"List reviews submitted on a pull request (approvals, change-requests, comment-only). **PREFER THIS \" +\n \"over shell-exec'ing the `gh` CLI.** Use this to check whether a PR is approved before calling \" +\n \"github_merge_pull.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n number: z.number().int().positive(),\n max_results: z.number().optional().describe(\"Max reviews (default 30, max 100)\"),\n }),\n },\n);\n\n// ── Repo content ───────────────────────────────────────────────────────────\n\nexport const githubListBranchesTool = tool(\n async ({ owner, repo, max_results }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const limit = Math.min(max_results ?? 30, 100);\n const data = await ghFetch(\n auth,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/branches?per_page=${limit}`,\n ) as Array<Record<string, unknown>> | { error?: string };\n if (!Array.isArray(data)) return JSON.stringify(data);\n return JSON.stringify({\n branches: data.map((b) => ({\n name: b.name,\n commit_sha: (b.commit as { sha?: string } | null)?.sha ?? null,\n protected: b.protected,\n })),\n });\n },\n {\n name: \"github_list_branches\",\n description:\n \"List branches in a repository with their head SHAs and protection state. **PREFER THIS over \" +\n \"shell-exec'ing the `gh` CLI.** Useful before opening a PR (confirm the head branch exists \" +\n \"and is the SHA you expect).\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n max_results: z.number().optional().describe(\"Max branches (default 30, max 100)\"),\n }),\n },\n);\n\nexport const githubGetFileTool = tool(\n async ({ owner, repo, path, ref }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const url = `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/contents/${path\n .split(\"/\").map(encodeURIComponent).join(\"/\")}` + (ref ? `?ref=${encodeURIComponent(ref)}` : \"\");\n const data = await ghFetch(auth, url) as Record<string, unknown> | Array<unknown> | { error?: string };\n if (!Array.isArray(data) && (data as { error?: string }).error) {\n return JSON.stringify(data);\n }\n if (Array.isArray(data) || (data as { type?: string }).type === \"dir\") {\n return JSON.stringify({\n error: `'${path}' is a directory; this tool only reads single files. Pass a path to a file.`,\n });\n }\n const f = data as { type?: string; encoding?: string; content?: string; sha?: string;\n size?: number; html_url?: string; path?: string };\n if (f.type !== \"file\") {\n return JSON.stringify({ error: `unsupported content type '${f.type ?? \"?\"}' at ${path}` });\n }\n const decoded = decodeContentsBlob(f.content ?? \"\", f.encoding);\n if (decoded.binary) {\n return JSON.stringify({\n path: f.path, sha: f.sha, url: f.html_url,\n binary: true, size_bytes: decoded.size_bytes,\n });\n }\n const cap = truncate(decoded.text ?? \"\", BODY_CAP);\n return JSON.stringify({\n path: f.path, sha: f.sha, url: f.html_url,\n binary: false, size_bytes: decoded.size_bytes,\n content: cap.text, truncated: cap.truncated,\n });\n },\n {\n name: \"github_get_file\",\n description:\n \"Read a file's contents from a repo at an optional ref (branch / tag / commit SHA). **PREFER THIS \" +\n \"over shell-exec'ing the `gh` CLI.** Returns up to 20 KB of UTF-8 text; longer files are truncated \" +\n \"with `truncated: true`. Binary files return `binary: true` and `size_bytes` instead of `content`. \" +\n \"GitHub itself rejects files larger than ~1 MB on this endpoint.\",\n schema: z.object({\n owner: z.string(),\n repo: z.string(),\n path: z.string().describe(\"Path within the repo (e.g. 'src/lib/index.ts'). Slashes preserved.\"),\n ref: z.string().optional().describe(\"Branch, tag, or commit SHA. Default: repo's default branch.\"),\n }),\n },\n);\n\nexport const githubSearchCodeTool = tool(\n async ({ q, repo, max_results }) => {\n const auth = resolveAuth();\n if (\"error\" in auth) return JSON.stringify({ error: auth.error });\n const limit = Math.min(max_results ?? 25, 100);\n const query = repo ? `repo:${repo} ${q}` : q;\n const data = await ghFetch(\n auth,\n `/search/code?q=${encodeURIComponent(query)}&per_page=${limit}`,\n { headers: { Accept: \"application/vnd.github.text-match+json\" } },\n ) as {\n items?: Array<{\n name?: string; path?: string; sha?: string; html_url?: string;\n repository?: { full_name?: string };\n text_matches?: Array<{ fragment?: string }>;\n }>;\n total_count?: number;\n error?: string;\n };\n if (data.error) return JSON.stringify(data);\n return JSON.stringify({\n total: data.total_count ?? 0,\n items: (data.items ?? []).map((i) => {\n const fragment = i.text_matches?.[0]?.fragment ?? \"\";\n const snip = truncate(fragment, SNIPPET_CAP);\n return {\n name: i.name,\n path: i.path,\n repo: i.repository?.full_name,\n url: i.html_url,\n sha: i.sha,\n snippet: snip.text,\n snippet_truncated: snip.truncated,\n };\n }),\n });\n },\n {\n name: \"github_search_code\",\n description:\n \"Search file contents across GitHub. **PREFER THIS over shell-exec'ing the `gh` CLI.** Pass `repo` \" +\n \"(\\\"owner/name\\\") to scope to one repo; the tool prepends `repo:owner/name `. The `q` body accepts \" +\n \"GitHub's full code-search syntax: 'language:ts symbolName', 'extension:py path:tests assert', etc. \" +\n \"Each hit returns a 400-char snippet around the match. Note: GitHub code search has stricter rate \" +\n \"limits than other endpoints (10/min for unauthenticated, 30/min for authenticated).\",\n schema: z.object({\n q: z.string().describe(\"Code search query (e.g. 'language:ts isLikelyBinary')\"),\n repo: z.string().optional().describe(\"Optional 'owner/name' shortcut; prepended as repo: filter\"),\n max_results: z.number().optional().describe(\"Max items (default 25, max 100)\"),\n }),\n },\n);\n\nregisterTools(\"GitHub\", \"read\", [\n // Issues — read\n githubSearchIssuesTool, githubGetIssueTool, githubListIssueCommentsTool,\n // Pull requests — read\n githubListPullsTool, githubGetPullTool,\n githubListPullFilesTool, githubListPullReviewsTool,\n // Repo content\n githubGetRepoTool, githubListBranchesTool, githubGetFileTool, githubSearchCodeTool,\n]);\nregisterTools(\"GitHub\", \"execute\", [\n // Issues — write/execute\n githubCreateIssueTool, githubUpdateIssueTool, githubAddCommentTool,\n // Pull requests — write/execute\n githubCreatePullTool, githubUpdatePullTool, githubMergePullTool,\n githubRequestReviewersTool, githubCreateReviewTool,\n]);\n","// Plain-text chunker for document RAG (ADR-0024).\n//\n// Strategy:\n// 1. Split on blank-line paragraph boundaries.\n// 2. Greedily pack paragraphs into chunks up to ~MAX_CHARS.\n// 3. Overlap: prepend the trailing portion of the previous chunk to each\n// new chunk so cross-chunk context survives splits (helps recall when\n// a question spans a paragraph boundary).\n//\n// Char count is used as a token proxy — 1 token ≈ 4 chars for English.\n// MAX_CHARS = 3200 ≈ 800 tokens, well under any embedding-model limit.\n\nconst MAX_CHARS = 3200;\nconst OVERLAP_CHARS = 400;\n\nexport interface Chunk {\n text: string;\n start_offset: number; // byte offset (utf-8) into original text\n end_offset: number;\n}\n\nexport function chunkText(text: string): Chunk[] {\n if (!text || text.length === 0) return [];\n\n // Split on one-or-more blank lines. Keep paragraphs with their separator\n // so offsets stay accurate.\n const paragraphs: { text: string; start: number; end: number }[] = [];\n let cursor = 0;\n const re = /\\n\\s*\\n/g;\n let m: RegExpExecArray | null;\n while ((m = re.exec(text)) !== null) {\n const start = cursor;\n const end = m.index;\n paragraphs.push({ text: text.slice(start, end), start, end });\n cursor = re.lastIndex;\n }\n if (cursor < text.length) {\n paragraphs.push({ text: text.slice(cursor), start: cursor, end: text.length });\n }\n\n const chunks: Chunk[] = [];\n let buf: { text: string; start: number; end: number } | null = null;\n\n for (const p of paragraphs) {\n if (!buf) {\n buf = { text: p.text, start: p.start, end: p.end };\n continue;\n }\n if (buf.text.length + 2 + p.text.length <= MAX_CHARS) {\n buf.text = `${buf.text}\\n\\n${p.text}`;\n buf.end = p.end;\n } else {\n chunks.push({ text: buf.text, start_offset: buf.start, end_offset: buf.end });\n // Overlap: take the tail of the previous chunk.\n const tail = buf.text.slice(Math.max(0, buf.text.length - OVERLAP_CHARS));\n buf = {\n text: `${tail}\\n\\n${p.text}`,\n // Anchor the new chunk's start_offset at the paragraph that's\n // logically new — the overlap tail is prepended for context only.\n start: p.start,\n end: p.end,\n };\n }\n }\n if (buf) {\n chunks.push({ text: buf.text, start_offset: buf.start, end_offset: buf.end });\n }\n\n // If a single paragraph is bigger than MAX_CHARS, the above will emit it\n // as one over-sized chunk. Split it on character boundaries as a last\n // resort so we don't exceed the embedding model's input limit.\n const out: Chunk[] = [];\n for (const c of chunks) {\n if (c.text.length <= MAX_CHARS) {\n out.push(c);\n continue;\n }\n let pos = 0;\n while (pos < c.text.length) {\n const end = Math.min(pos + MAX_CHARS, c.text.length);\n out.push({\n text: c.text.slice(pos, end),\n start_offset: c.start_offset + pos,\n end_offset: c.start_offset + end,\n });\n pos = end - OVERLAP_CHARS;\n if (pos < 0) pos = 0;\n if (end === c.text.length) break;\n }\n }\n return out;\n}\n","// Filesystem walker + indexer for document RAG (ADR-0024).\n//\n// Walks each enabled document_source, identifies text files whose\n// mtime/size differs from the indexed copy, re-chunks + re-embeds them.\n// Files removed on disk are evicted (chunks + document row).\n//\n// Defaults are conservative on purpose: extension allowlist, size cap,\n// directory denylist for VCS / build output. Binary files are skipped via\n// a fast non-printable-byte heuristic on the first 4 KB.\n\nimport { randomUUID, createHash } from \"node:crypto\";\nimport { promises as fs } from \"node:fs\";\nimport { join, relative, sep } from \"node:path\";\nimport { getDb } from \"@/lib/db\";\nimport { embedBestEffort } from \"@/lib/embeddings\";\nimport {\n listEnabledDocumentSources,\n markSourceScanned,\n type DocumentSourceRow,\n} from \"@/lib/stores/document-sources\";\nimport { chunkText } from \"./chunker\";\nimport { isRemoteKind, runRemoteSource, type RemoteIndexStats } from \"./remote\";\n\n// Conservative defaults; v1 is not configurable per source. ADR-0024\n// documents the rationale and the path to opening these up.\nconst ALLOWED_EXT = new Set([\n \".md\", \".markdown\", \".txt\", \".rst\", \".log\",\n \".json\", \".jsonc\", \".yaml\", \".yml\", \".toml\", \".ini\", \".cfg\", \".env\",\n \".ts\", \".tsx\", \".js\", \".jsx\", \".mjs\", \".cjs\",\n \".py\", \".rs\", \".go\", \".java\", \".kt\", \".scala\", \".swift\",\n \".c\", \".cpp\", \".cc\", \".h\", \".hpp\",\n \".cs\", \".rb\", \".php\", \".lua\", \".pl\", \".r\",\n \".sh\", \".bash\", \".zsh\", \".ps1\", \".bat\",\n \".html\", \".htm\", \".css\", \".scss\", \".sass\", \".vue\", \".svelte\",\n \".sql\", \".graphql\", \".proto\",\n \".csv\", \".tsv\",\n]);\nconst SKIP_DIRS = new Set([\n \"node_modules\", \".git\", \".hg\", \".svn\", \".next\", \".turbo\", \".cache\",\n \"dist\", \"build\", \"out\", \"target\", \".venv\", \"venv\", \"env\",\n \"__pycache__\", \".pytest_cache\", \".mypy_cache\",\n \".idea\", \".vscode\", \".vs\",\n \"coverage\", \".nyc_output\",\n]);\nconst MAX_FILE_BYTES = 2 * 1024 * 1024; // 2 MB — bigger files almost always\n // belong in proper RAG, not ad-hoc.\nconst MAX_FILES_PER_SOURCE = 5000;\n// Per-call cap so a freshly-added source with thousands of files doesn't\n// block the scheduler tick for minutes. Subsequent ticks pick up the rest.\nconst MAX_INDEX_PER_TICK_PER_SOURCE = 50;\n\nexport { ALLOWED_EXT, SKIP_DIRS, MAX_FILE_BYTES };\n\nexport function lowerExt(name: string): string {\n const i = name.lastIndexOf(\".\");\n return i < 0 ? \"\" : name.slice(i).toLowerCase();\n}\n\nexport function isLikelyBinary(buf: Buffer): boolean {\n const len = Math.min(buf.length, 4096);\n if (len === 0) return false;\n let suspicious = 0;\n for (let i = 0; i < len; i++) {\n const b = buf[i];\n // NUL byte = almost certainly binary.\n if (b === 0) return true;\n // Outside printable ASCII + common whitespace and not high-bit UTF-8.\n if (b < 0x09 || (b > 0x0d && b < 0x20)) suspicious++;\n }\n return suspicious / len > 0.05;\n}\n\nexport interface FileEntry {\n abs: string;\n rel: string;\n mtime_ms: number;\n size: number;\n}\n\nasync function walk(root: string): Promise<FileEntry[]> {\n const out: FileEntry[] = [];\n // Cloud-synced filesystems (OneDrive's macOS file provider in\n // particular) can re-emit the same entry from readdir during sync\n // transitions, sometimes with a different Unicode normalization\n // (NFC vs NFD). Without dedupe, the second visit would attempt a\n // second INSERT for the same (source_id, path) and trip the UNIQUE\n // constraint on `documents`.\n const seen = new Set<string>();\n async function visit(dir: string): Promise<void> {\n if (out.length >= MAX_FILES_PER_SOURCE) return;\n let entries: import(\"node:fs\").Dirent[];\n try {\n entries = await fs.readdir(dir, { withFileTypes: true });\n } catch {\n return;\n }\n for (const e of entries) {\n if (out.length >= MAX_FILES_PER_SOURCE) return;\n if (e.name.startsWith(\".\")) {\n // Hide dot-dirs by default. Users who want them indexed should\n // pick a more specific subdirectory as the source.\n if (e.isDirectory()) continue;\n // Keep dot-files like .env, .gitignore as text candidates.\n }\n const abs = join(dir, e.name);\n if (e.isDirectory()) {\n if (SKIP_DIRS.has(e.name)) continue;\n if (seen.has(abs)) continue;\n seen.add(abs);\n await visit(abs);\n } else if (e.isFile()) {\n const ext = lowerExt(e.name);\n if (!ALLOWED_EXT.has(ext)) continue;\n if (seen.has(abs)) continue;\n seen.add(abs);\n let st;\n try { st = await fs.stat(abs); } catch { continue; }\n if (st.size > MAX_FILE_BYTES) continue;\n out.push({\n abs,\n rel: relative(root, abs).split(sep).join(\"/\"),\n mtime_ms: Math.floor(st.mtimeMs),\n size: st.size,\n });\n }\n }\n }\n await visit(root);\n return out;\n}\n\ninterface IndexedDocRow {\n id: string;\n path: string;\n mtime_ms: number;\n size_bytes: number;\n content_hash: string;\n}\n\nfunction listIndexedDocs(sourceId: string): Map<string, IndexedDocRow> {\n const rows = getDb()\n .prepare(\"SELECT id, path, mtime_ms, size_bytes, content_hash FROM documents WHERE source_id=?\")\n .all(sourceId) as unknown as IndexedDocRow[];\n const map = new Map<string, IndexedDocRow>();\n for (const r of rows) map.set(r.path, r);\n return map;\n}\n\ninterface UnembeddedChunkRow {\n id: string;\n text: string;\n}\n\nfunction listUnembeddedChunks(documentId: string): UnembeddedChunkRow[] {\n return getDb()\n .prepare(\n `SELECT id, text\n FROM document_chunks\n WHERE document_id=? AND embedding IS NULL\n ORDER BY chunk_index ASC`,\n )\n .all(documentId) as unknown as UnembeddedChunkRow[];\n}\n\nasync function backfillDocumentEmbeddings(documentId: string): Promise<{ missing: number; embedded: number; embedError: string | null }> {\n const rows = listUnembeddedChunks(documentId);\n if (rows.length === 0) return { missing: 0, embedded: 0, embedError: null };\n\n const { vectors, error } = await embedBestEffort(rows.map((r) => r.text));\n const updateEmb = getDb().prepare(\"UPDATE document_chunks SET embedding=? WHERE id=?\");\n let embedded = 0;\n for (let i = 0; i < rows.length; i++) {\n const v = vectors[i];\n if (v == null) continue;\n updateEmb.run(JSON.stringify(v), rows[i].id);\n embedded++;\n }\n return { missing: rows.length, embedded, embedError: error };\n}\n\nexport async function readTextFile(abs: string): Promise<string | null> {\n let buf: Buffer;\n try { buf = await fs.readFile(abs); } catch { return null; }\n if (isLikelyBinary(buf)) return null;\n return buf.toString(\"utf8\");\n}\n\nexport function hashContent(text: string): string {\n return createHash(\"sha256\").update(text).digest(\"hex\");\n}\n\ninterface IndexStats {\n scanned: number;\n added: number;\n updated: number;\n removed: number;\n unchanged: number;\n errors: number;\n embed_failed?: number;\n embed_error?: string | null;\n}\n\nexport async function indexSource(\n source: DocumentSourceRow,\n opts?: { maxFiles?: number },\n): Promise<IndexStats> {\n const stats: IndexStats = { scanned: 0, added: 0, updated: 0, removed: 0, unchanged: 0, errors: 0 };\n const db = getDb();\n let lastError: string | null = null;\n let embedFailed = 0;\n let embedError: string | null = null;\n\n // Resolve real files on disk.\n const files = await walk(source.path);\n stats.scanned = files.length;\n\n const indexed = listIndexedDocs(source.id);\n const onDisk = new Set<string>(files.map((f) => f.abs));\n\n // Drop entries whose file is gone.\n for (const [path, row] of indexed.entries()) {\n if (!onDisk.has(path)) {\n db.prepare(\"DELETE FROM documents WHERE id=?\").run(row.id);\n stats.removed++;\n }\n }\n\n // Index new + changed files.\n const maxThisRun = opts?.maxFiles ?? MAX_INDEX_PER_TICK_PER_SOURCE;\n let processed = 0;\n for (const f of files) {\n if (processed >= maxThisRun) break;\n const existing = indexed.get(f.abs);\n if (existing && existing.mtime_ms === f.mtime_ms && existing.size_bytes === f.size) {\n // Root-cause fix: if a file was indexed while embeddings were\n // unavailable, unchanged files used to be skipped forever and never\n // backfilled. Try to embed any still-null chunks on unchanged docs.\n try {\n const r = await backfillDocumentEmbeddings(existing.id);\n if (r.missing > 0) {\n embedFailed += Math.max(r.missing - r.embedded, 0);\n if (r.embedError && !embedError) embedError = r.embedError;\n processed++;\n }\n } catch (err) {\n lastError = err instanceof Error ? err.message : String(err);\n stats.errors++;\n }\n stats.unchanged++;\n continue;\n }\n\n let text: string | null;\n try { text = await readTextFile(f.abs); } catch {\n stats.errors++;\n continue;\n }\n if (text === null) continue; // binary / unreadable — skip silently.\n\n const hash = hashContent(text);\n if (existing && existing.content_hash === hash) {\n // Mtime/size changed but content didn't — just touch the row.\n db.prepare(\"UPDATE documents SET mtime_ms=?, size_bytes=?, last_indexed_at=? WHERE id=?\")\n .run(f.mtime_ms, f.size, new Date().toISOString(), existing.id);\n try {\n const r = await backfillDocumentEmbeddings(existing.id);\n if (r.missing > 0) {\n embedFailed += Math.max(r.missing - r.embedded, 0);\n if (r.embedError && !embedError) embedError = r.embedError;\n processed++;\n }\n } catch (err) {\n lastError = err instanceof Error ? err.message : String(err);\n stats.errors++;\n }\n stats.unchanged++;\n continue;\n }\n\n try {\n const r = await upsertLocalDocument(source.id, f, text, hash, existing?.id);\n embedFailed += r.chunks - r.embedded;\n if (r.embedError && !embedError) embedError = r.embedError;\n processed++;\n if (existing) stats.updated++;\n else stats.added++;\n } catch (err) {\n lastError = err instanceof Error ? err.message : String(err);\n stats.errors++;\n }\n }\n\n // Embed failures are not fetch failures — but if everything else\n // succeeded we still want them visible on the row, so the operator\n // doesn't have to grep server logs to discover that semantic search\n // is degraded for this source.\n const composite = lastError\n ? lastError\n : embedFailed > 0\n ? `${embedFailed} chunk${embedFailed === 1 ? \"\" : \"s\"} failed to embed${embedError ? \": \" + embedError : \"\"}`\n : null;\n if (embedFailed > 0) {\n stats.embed_failed = embedFailed;\n stats.embed_error = embedError;\n }\n markSourceScanned(source.id, composite);\n return stats;\n}\n\n/**\n * Upsert one local document row (and its chunks). Exported so\n * single-file watcher firings can reuse it without going through\n * a full source sweep.\n */\nexport async function upsertLocalDocument(\n sourceId: string,\n f: FileEntry,\n text: string,\n hash: string,\n existingId: string | undefined,\n): Promise<{ chunks: number; embedded: number; embedError: string | null }> {\n const db = getDb();\n const t = new Date().toISOString();\n const docId = existingId ?? randomUUID();\n\n // Two writers can race on (source_id, path): the full sweep in\n // indexSource() loads listIndexedDocs() once and iterates, while\n // fs-watch firings call reindexLocalFile() per file. If a watcher\n // event lands mid-sweep, both paths can see \"no existing row\" and\n // both try to INSERT, tripping UNIQUE(source_id, path)\n // (lib/db/migrations.ts). REPLACE INTO is unsafe: document_chunks\n // has ON DELETE CASCADE on documents.id, so REPLACE would nuke every\n // chunk on each call. Use ON CONFLICT DO NOTHING, and if we lost the\n // race, adopt the winner's id and overwrite via UPDATE so the latest\n // content still wins.\n let writeId = docId;\n if (existingId) {\n db.prepare(\n `UPDATE documents\n SET path=?, rel_path=?, mtime_ms=?, size_bytes=?, content_hash=?, last_indexed_at=?\n WHERE id=?`,\n ).run(f.abs, f.rel, f.mtime_ms, f.size, hash, t, existingId);\n db.prepare(\"DELETE FROM document_chunks WHERE document_id=?\").run(existingId);\n writeId = existingId;\n } else {\n const info = db.prepare(\n `INSERT INTO documents\n (id, source_id, path, rel_path, mtime_ms, size_bytes, content_hash, last_indexed_at, chunk_count)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, 0)\n ON CONFLICT(source_id, path) DO NOTHING`,\n ).run(docId, sourceId, f.abs, f.rel, f.mtime_ms, f.size, hash, t);\n if (info.changes === 0) {\n const winner = db\n .prepare(\"SELECT id FROM documents WHERE source_id=? AND path=?\")\n .get(sourceId, f.abs) as { id: string } | undefined;\n if (winner) {\n db.prepare(\n `UPDATE documents\n SET rel_path=?, mtime_ms=?, size_bytes=?, content_hash=?, last_indexed_at=?\n WHERE id=?`,\n ).run(f.rel, f.mtime_ms, f.size, hash, t, winner.id);\n db.prepare(\"DELETE FROM document_chunks WHERE document_id=?\").run(winner.id);\n writeId = winner.id;\n }\n }\n }\n\n return chunkAndEmbedDocument(writeId, text, f.rel);\n}\n\n/**\n * Chunk a document's text, persist the chunks, and best-effort embed\n * them. Shared between the local sweep, single-file watcher firings,\n * and remote-source upserts. Returns counts so the caller can aggregate\n * embed failures up to the source row instead of swallowing them.\n */\nexport async function chunkAndEmbedDocument(\n documentId: string,\n text: string,\n _label: string,\n): Promise<{ chunks: number; embedded: number; embedError: string | null }> {\n const db = getDb();\n const chunks = chunkText(text);\n if (chunks.length === 0) {\n db.prepare(\"UPDATE documents SET chunk_count=0 WHERE id=?\").run(documentId);\n return { chunks: 0, embedded: 0, embedError: null };\n }\n\n // Insert chunks first without embeddings — recall falls back to\n // substring scan, so they're useful immediately. Then attempt to embed\n // in a single batch; persist whichever vectors came back.\n const insertChunk = db.prepare(\n `INSERT INTO document_chunks\n (id, document_id, chunk_index, text, start_offset, end_offset, embedding)\n VALUES (?, ?, ?, ?, ?, ?, NULL)`,\n );\n const chunkIds: string[] = [];\n for (let i = 0; i < chunks.length; i++) {\n const id = randomUUID();\n chunkIds.push(id);\n insertChunk.run(id, documentId, i, chunks[i].text, chunks[i].start_offset, chunks[i].end_offset);\n }\n db.prepare(\"UPDATE documents SET chunk_count=? WHERE id=?\").run(chunks.length, documentId);\n\n // embedBestEffort handles retry + halving fallback internally so a\n // single bad input or transient 429 doesn't drop the whole document.\n const { vectors, error } = await embedBestEffort(chunks.map((c) => c.text));\n const updateEmb = db.prepare(\"UPDATE document_chunks SET embedding=? WHERE id=?\");\n let embedded = 0;\n for (let i = 0; i < vectors.length; i++) {\n if (vectors[i] != null) {\n updateEmb.run(JSON.stringify(vectors[i]), chunkIds[i]);\n embedded++;\n }\n }\n return { chunks: chunks.length, embedded, embedError: error };\n}\n\nexport async function indexAllSources(opts?: { maxFilesPerSource?: number }): Promise<{\n source_id: string;\n path: string;\n stats: IndexStats | RemoteIndexStats;\n}[]> {\n const sources = listEnabledDocumentSources();\n const out: { source_id: string; path: string; stats: IndexStats | RemoteIndexStats }[] = [];\n for (const s of sources) {\n try {\n if (isRemoteKind(s.kind)) {\n // Delegate to the per-kind remote handler (ADR-0026). Remote\n // sources don't have an mtime stat — they have their own\n // incremental cursor stored in document_sources.last_cursor.\n const stats = await runRemoteSource(s);\n out.push({ source_id: s.id, path: s.path, stats });\n continue;\n }\n const stats = await indexSource(s, { maxFiles: opts?.maxFilesPerSource });\n out.push({ source_id: s.id, path: s.path, stats });\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n markSourceScanned(s.id, msg);\n console.error(\"[documents] index failed for\", s.path, msg);\n }\n }\n return out;\n}\n","// Cheap HTML → plain text. Not a parser — regex-only, deterministic, no deps.\n//\n// Two modes:\n// - default (preserveParagraphs: false): collapses ALL whitespace to single\n// spaces. Right for web-page summarization where the agent wants prose.\n// - preserveParagraphs: true: keeps newline structure (br → \\n, /p → \\n\\n)\n// and only collapses runs of spaces/tabs. Right for email bodies where the\n// agent benefits from paragraph breaks.\nexport function stripHtml(html: string, opts?: { preserveParagraphs?: boolean }): string {\n let s = html\n .replace(/<style[\\s\\S]*?<\\/style>/gi, \" \")\n .replace(/<script[\\s\\S]*?<\\/script>/gi, \" \")\n .replace(/<noscript[\\s\\S]*?<\\/noscript>/gi, \" \")\n .replace(/<!--[\\s\\S]*?-->/g, \" \");\n\n if (opts?.preserveParagraphs) {\n s = s\n .replace(/<br\\s*\\/?>/gi, \"\\n\")\n .replace(/<\\/p>/gi, \"\\n\\n\");\n // Strip remaining tags with empty (so the br/p newlines we just injected\n // aren't surrounded by stray spaces from the opening tags).\n s = s.replace(/<\\/?[^>]+>/g, \"\");\n } else {\n // Default mode: replace tags with spaces so adjacent words don't merge.\n s = s.replace(/<\\/?[^>]+>/g, \" \");\n }\n\n s = decodeHtmlEntities(s);\n\n s = opts?.preserveParagraphs\n ? s.replace(/[ \\t]+/g, \" \").replace(/\\n{3,}/g, \"\\n\\n\")\n : s.replace(/\\s+/g, \" \");\n\n return s.trim();\n}\n\nexport function decodeHtmlEntities(s: string): string {\n return s\n .replace(/ /g, \" \")\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\");\n}\n","// Ephemeral state store for the in-app Gmail OAuth flow.\n//\n// The user types client_id + client_secret in the Integrations panel and clicks\n// \"Connect Gmail\". We POST those to /oauth/start, which stashes them here keyed\n// by a random `state` token and returns the Google authorize URL. The browser\n// opens that URL; Google bounces back to /oauth/callback with `?code&state`,\n// which exchanges the code for a refresh_token and persists the integration.\n// Meanwhile the panel polls /oauth/status to know when to refresh.\n//\n// Pinned to globalThis so HMR in dev doesn't lose pending flows.\n\nimport { getIntegrationRaw } from \"@/lib/stores/integrations\";\nimport { createOAuthFlowStore, type OAuthFlow } from \"@/lib/utils/oauth-flow-store\";\nimport { parseJsonSafe } from \"@/lib/utils/json\";\n\nexport type { OAuthFlow };\n\nconst flowStore = createOAuthFlowStore({ globalKey: \"__ggOauthFlows\" });\n\nexport const createFlow = flowStore.create;\nexport const getFlow = flowStore.get;\nexport const updateFlow = flowStore.update;\nexport const deleteFlow = flowStore.delete;\n\nexport const GMAIL_SCOPES = [\n \"https://www.googleapis.com/auth/gmail.modify\",\n \"https://www.googleapis.com/auth/gmail.compose\",\n // Calendar: read/write events on the user's existing calendars. Narrow\n // scope on purpose — doesn't grant create/delete of entire calendars\n // (matches the principle-of-least-privilege the Gmail scopes follow).\n \"https://www.googleapis.com/auth/calendar.events\",\n // Read-only metadata of the user's calendar list. Required for the\n // calendarList.list endpoint that powers calendarListCalendarsTool —\n // calendar.events alone returns 403 there.\n \"https://www.googleapis.com/auth/calendar.readonly\",\n];\n\nexport function buildAuthorizeUrl(opts: {\n clientId: string;\n redirectUri: string;\n state: string;\n}): string {\n const p = new URLSearchParams({\n client_id: opts.clientId,\n redirect_uri: opts.redirectUri,\n response_type: \"code\",\n scope: GMAIL_SCOPES.join(\" \"),\n access_type: \"offline\",\n prompt: \"consent\",\n include_granted_scopes: \"true\",\n state: opts.state,\n });\n return `https://accounts.google.com/o/oauth2/v2/auth?${p.toString()}`;\n}\n\nexport async function exchangeCode(opts: {\n code: string;\n clientId: string;\n clientSecret: string;\n redirectUri: string;\n}): Promise<{ refresh_token?: string; access_token?: string; expires_in?: number; scope?: string }> {\n const body = new URLSearchParams({\n code: opts.code,\n client_id: opts.clientId,\n client_secret: opts.clientSecret,\n redirect_uri: opts.redirectUri,\n grant_type: \"authorization_code\",\n });\n const res = await fetch(\"https://oauth2.googleapis.com/token\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: body.toString(),\n signal: AbortSignal.timeout(30_000),\n });\n const text = await res.text();\n const parsed = parseJsonSafe<Record<string, unknown>>(text, {});\n if (!res.ok) {\n const err = (parsed[\"error_description\"] || parsed[\"error\"] || text || `HTTP ${res.status}`) as string;\n throw new Error(err);\n }\n return parsed as { refresh_token?: string; access_token?: string; expires_in?: number; scope?: string };\n}\n\n// ---------------------------------------------------------------------------\n// Shared Google API auth (Gmail + Calendar + any future Google scope)\n// ---------------------------------------------------------------------------\n//\n// The same OAuth client (stored under integration name \"gmail\" for back-compat)\n// grants every Google scope we ask for. Tools across `lib/tools/` share these\n// helpers so a burst of mixed Gmail+Calendar calls hits Google's token\n// endpoint once per refresh, not once per file.\n\nexport interface GoogleAuth {\n client_id: string;\n client_secret: string;\n refresh_token: string;\n}\n\nexport function resolveGoogleAuth(): GoogleAuth | { error: string } {\n const envId = process.env.GMAIL_CLIENT_ID;\n const envSecret = process.env.GMAIL_CLIENT_SECRET;\n const envRefresh = process.env.GMAIL_REFRESH_TOKEN;\n if (envId && envSecret && envRefresh) {\n return { client_id: envId, client_secret: envSecret, refresh_token: envRefresh };\n }\n const saved = getIntegrationRaw(\"gmail\");\n if (saved?.client_id && saved.client_secret && saved.refresh_token) {\n return {\n client_id: saved.client_id,\n client_secret: saved.client_secret,\n refresh_token: saved.refresh_token,\n };\n }\n return {\n error:\n \"Google account not connected. Open the gear menu → Integrations tab → \" +\n \"Gmail card and click Connect Gmail to authorize Gmail + Calendar access.\",\n };\n}\n\ninterface CachedAccessToken { token: string; expires_at: number }\nconst accessTokenCache = new Map<string, CachedAccessToken>();\n\nexport async function getGoogleAccessToken(\n auth: GoogleAuth,\n): Promise<string | { error: string }> {\n const key = auth.refresh_token.slice(0, 20);\n const cached = accessTokenCache.get(key);\n if (cached && cached.expires_at > Date.now() + 60_000) return cached.token;\n\n const body = new URLSearchParams({\n client_id: auth.client_id,\n client_secret: auth.client_secret,\n refresh_token: auth.refresh_token,\n grant_type: \"refresh_token\",\n });\n try {\n const res = await fetch(\"https://oauth2.googleapis.com/token\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: body.toString(),\n signal: AbortSignal.timeout(30_000),\n });\n const text = await res.text();\n if (!res.ok) {\n // Drop any stale cached token so a reconnected (broader-scope) refresh\n // re-exchanges cleanly on the next call.\n accessTokenCache.delete(key);\n return { error: `OAuth token refresh failed (${res.status}): ${text.slice(0, 300)}` };\n }\n const parsed = JSON.parse(text) as { access_token?: string; expires_in?: number };\n if (!parsed.access_token) return { error: \"OAuth response missing access_token\" };\n const expires_at = Date.now() + (parsed.expires_in ?? 3000) * 1000;\n accessTokenCache.set(key, { token: parsed.access_token, expires_at });\n return parsed.access_token;\n } catch (err) {\n return { error: `OAuth token refresh threw: ${err instanceof Error ? err.message : String(err)}` };\n }\n}\n\n/**\n * Shared bearer-auth fetch for Google REST APIs (Gmail, Calendar, ...).\n *\n * Behaviour:\n * - Resolves access token from `auth`; if that fails, the error object is\n * surfaced unchanged so callers can pass it back to the agent.\n * - 204 No Content → `{ ok: true }` (used by DELETE endpoints).\n * - Non-2xx response → `{ error: \"<service> <status>: <body slice>\", url }`.\n * - 2xx with body → parsed JSON if possible, raw text otherwise.\n * - Fetch throws (DNS, abort, timeout) → `{ error: \"<service> fetch threw: ...\" }`.\n *\n * @param service Short tag used in error messages, e.g. \"Gmail\" or \"Calendar\".\n * @param baseUrl Base for relative `path` (e.g. `https://gmail.googleapis.com/gmail/v1/users/me`).\n * @param path Either a full URL (starts with `http`) or path appended to baseUrl.\n */\nexport async function googleFetch(\n auth: GoogleAuth,\n service: string,\n baseUrl: string,\n path: string,\n init?: RequestInit,\n): Promise<unknown> {\n const token = await getGoogleAccessToken(auth);\n if (typeof token !== \"string\") return token;\n const url = path.startsWith(\"http\") ? path : `${baseUrl}${path}`;\n try {\n const res = await fetch(url, {\n ...init,\n headers: {\n Authorization: `Bearer ${token}`,\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\",\n ...(init?.headers ?? {}),\n },\n signal: AbortSignal.timeout(30_000),\n });\n if (res.status === 204) return { ok: true };\n const text = await res.text();\n if (!res.ok) {\n return { error: `${service} ${res.status}: ${text.slice(0, 500)}`, url };\n }\n try { return JSON.parse(text); } catch { return text; }\n } catch (err) {\n return { error: `${service} fetch threw: ${err instanceof Error ? err.message : String(err)}` };\n }\n}\n","// Ephemeral state store + shared auth helpers for the in-app Microsoft OAuth\n// flow. Mirrors lib/integrations/gmail-oauth.ts but targets the Microsoft\n// identity platform (v2.0 endpoint, common tenant by default) and Microsoft\n// Graph as the downstream API surface (Outlook Mail + Calendar in v1).\n//\n// The user types client_id + client_secret in the Integrations panel and\n// clicks \"Connect Outlook\". We POST those to /oauth/start, which stashes\n// them here keyed by a random `state` token and returns the Microsoft\n// authorize URL. The browser opens that URL; MS bounces back to\n// /oauth/callback with `?code&state`, which exchanges the code for a\n// refresh_token (granted because we asked for `offline_access`) and\n// persists the integration. The panel polls /oauth/status separately.\n//\n// Pinned to globalThis so HMR in dev doesn't lose pending flows.\n\nimport { getIntegrationRaw } from \"@/lib/stores/integrations\";\nimport { createOAuthFlowStore, type OAuthFlow } from \"@/lib/utils/oauth-flow-store\";\nimport { parseJsonSafe } from \"@/lib/utils/json\";\n\nexport type { OAuthFlow };\n\nconst flowStore = createOAuthFlowStore({ globalKey: \"__msOauthFlows\" });\n\nexport const createFlow = flowStore.create;\nexport const getFlow = flowStore.get;\nexport const updateFlow = flowStore.update;\nexport const deleteFlow = flowStore.delete;\n\n// Tenant selector. `common` accepts both personal Microsoft accounts\n// (@outlook.com, @hotmail.com, @live.com) and work/school M365 accounts.\n// Switch to `consumers` to lock to personal only, or `organizations` for\n// work/school only. We expose this as an env override for power users but\n// don't surface it in the UI yet.\nconst TENANT = process.env.OUTLOOK_TENANT?.trim() || \"common\";\n\n// Delegated Graph scopes the agent needs. Keep narrow:\n// - offline_access → required for a refresh_token (MS counterpart of\n// Google's access_type=offline).\n// - User.Read → used by the test endpoint to call /me.\n// - Mail.ReadWrite → search/read mail, create drafts, mark read,\n// move to folders (incl. DeletedItems). Does NOT\n// grant sending — matches our Gmail \"drafts only\"\n// stance via gmail.compose.\n// - Calendars.ReadWrite → list/get/create/update/delete events on the\n// user's existing calendars.\nexport const MICROSOFT_SCOPES = [\n \"offline_access\",\n \"User.Read\",\n \"Mail.ReadWrite\",\n \"Calendars.ReadWrite\",\n];\n\nexport function buildAuthorizeUrl(opts: {\n clientId: string;\n redirectUri: string;\n state: string;\n}): string {\n const p = new URLSearchParams({\n client_id: opts.clientId,\n redirect_uri: opts.redirectUri,\n response_type: \"code\",\n response_mode: \"query\",\n scope: MICROSOFT_SCOPES.join(\" \"),\n // Force consent so a returning user actually re-grants any newly-added\n // scope (otherwise MS silently reuses the prior grant minus the new bit).\n prompt: \"consent\",\n state: opts.state,\n });\n return `https://login.microsoftonline.com/${TENANT}/oauth2/v2.0/authorize?${p.toString()}`;\n}\n\n// NOTE: Unlike Google, MS v2 endpoint **requires** the `scope` parameter on\n// every grant_type call (both authorization_code and refresh_token). Leaving\n// it out yields `AADSTS900144: The request body must contain the following\n// parameter: 'scope'.`. We always pass the full scope set.\nexport async function exchangeCode(opts: {\n code: string;\n clientId: string;\n clientSecret: string;\n redirectUri: string;\n}): Promise<{ refresh_token?: string; access_token?: string; expires_in?: number; scope?: string }> {\n const body = new URLSearchParams({\n code: opts.code,\n client_id: opts.clientId,\n client_secret: opts.clientSecret,\n redirect_uri: opts.redirectUri,\n grant_type: \"authorization_code\",\n scope: MICROSOFT_SCOPES.join(\" \"),\n });\n const res = await fetch(`https://login.microsoftonline.com/${TENANT}/oauth2/v2.0/token`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: body.toString(),\n signal: AbortSignal.timeout(30_000),\n });\n const text = await res.text();\n const parsed = parseJsonSafe<Record<string, unknown>>(text, {});\n if (!res.ok) {\n const err = (parsed[\"error_description\"] || parsed[\"error\"] || text || `HTTP ${res.status}`) as string;\n throw new Error(err);\n }\n return parsed as { refresh_token?: string; access_token?: string; expires_in?: number; scope?: string };\n}\n\n// ---------------------------------------------------------------------------\n// Shared Microsoft Graph auth (Outlook Mail + Calendar + future Graph scopes)\n// ---------------------------------------------------------------------------\n\nexport interface MicrosoftAuth {\n client_id: string;\n client_secret: string;\n refresh_token: string;\n}\n\nexport function resolveMicrosoftAuth(): MicrosoftAuth | { error: string } {\n const envId = process.env.OUTLOOK_CLIENT_ID;\n const envSecret = process.env.OUTLOOK_CLIENT_SECRET;\n const envRefresh = process.env.OUTLOOK_REFRESH_TOKEN;\n if (envId && envSecret && envRefresh) {\n return { client_id: envId, client_secret: envSecret, refresh_token: envRefresh };\n }\n const saved = getIntegrationRaw(\"outlook\");\n if (saved?.client_id && saved.client_secret && saved.refresh_token) {\n return {\n client_id: saved.client_id,\n client_secret: saved.client_secret,\n refresh_token: saved.refresh_token,\n };\n }\n return {\n error:\n \"Microsoft account not connected. Open the gear menu → Integrations tab → \" +\n \"Outlook card and click Connect Outlook to authorize Mail + Calendar access.\",\n };\n}\n\ninterface CachedAccessToken { token: string; expires_at: number }\nconst accessTokenCache = new Map<string, CachedAccessToken>();\n\nexport async function getMicrosoftAccessToken(\n auth: MicrosoftAuth,\n): Promise<string | { error: string }> {\n const key = auth.refresh_token.slice(0, 20);\n const cached = accessTokenCache.get(key);\n if (cached && cached.expires_at > Date.now() + 60_000) return cached.token;\n\n const body = new URLSearchParams({\n client_id: auth.client_id,\n client_secret: auth.client_secret,\n refresh_token: auth.refresh_token,\n grant_type: \"refresh_token\",\n // Required on the v2 endpoint even for refresh_token grants.\n scope: MICROSOFT_SCOPES.join(\" \"),\n });\n try {\n const res = await fetch(`https://login.microsoftonline.com/${TENANT}/oauth2/v2.0/token`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: body.toString(),\n signal: AbortSignal.timeout(30_000),\n });\n const text = await res.text();\n if (!res.ok) {\n accessTokenCache.delete(key);\n return { error: `Microsoft OAuth refresh failed (${res.status}): ${text.slice(0, 300)}` };\n }\n const parsed = JSON.parse(text) as { access_token?: string; expires_in?: number };\n if (!parsed.access_token) return { error: \"OAuth response missing access_token\" };\n const expires_at = Date.now() + (parsed.expires_in ?? 3000) * 1000;\n accessTokenCache.set(key, { token: parsed.access_token, expires_at });\n return parsed.access_token;\n } catch (err) {\n return { error: `Microsoft OAuth refresh threw: ${err instanceof Error ? err.message : String(err)}` };\n }\n}\n\n// Shared Graph fetch helper. Used by both lib/tools/outlook.ts and\n// lib/tools/outlook-calendar.ts. Returns parsed JSON or { error: string, url? }.\n// 204 No Content (e.g. successful DELETE) returns { ok: true }.\nexport async function graphFetch(\n auth: MicrosoftAuth,\n path: string,\n init?: RequestInit,\n): Promise<unknown> {\n const token = await getMicrosoftAccessToken(auth);\n if (typeof token !== \"string\") return token;\n const url = path.startsWith(\"http\") ? path : `https://graph.microsoft.com/v1.0${path}`;\n try {\n const res = await fetch(url, {\n ...init,\n headers: {\n Authorization: `Bearer ${token}`,\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\",\n ...(init?.headers ?? {}),\n },\n signal: AbortSignal.timeout(30_000),\n });\n if (res.status === 204) return { ok: true };\n const text = await res.text();\n if (!res.ok) {\n return { error: `Graph ${res.status}: ${text.slice(0, 500)}`, url };\n }\n try { return JSON.parse(text); } catch { return text; }\n } catch (err) {\n return { error: `Graph fetch threw: ${err instanceof Error ? err.message : String(err)}` };\n }\n}\n","// CRUD for the `document_sources` table (ADR-0024). A source is a folder\n// the user has asked Jarela to index for semantic search.\n\nimport { randomUUID } from \"node:crypto\";\nimport { getDb } from \"@/lib/db\";\n\n// ADR-0026 — `kind` discriminates local-folder sources from remote ones\n// (Jira projects, Confluence spaces, saved JQL/CQL, on-demand URL). `config`\n// is a JSON-encoded per-kind blob. `last_cursor` is a per-source incremental\n// watermark (used by remote indexers to do incremental syncs).\n// ADR-0029 added `github_pulls` (PRs of one repo) and `github_repo` (text\n// files on one branch of one repo).\nexport type DocumentSourceKind =\n | \"local_folder\"\n | \"confluence_space\"\n | \"confluence_cql\"\n | \"jira_project\"\n | \"jira_jql\"\n | \"github_pulls\"\n | \"github_repo\"\n | \"gmail_mail\"\n | \"outlook_mail\"\n | \"on_demand_url\";\n\nexport interface DocumentSourceRow {\n id: string;\n path: string;\n label: string | null;\n enabled: number;\n last_scan_at: string | null;\n last_error: string | null;\n created_at: string;\n updated_at: string;\n kind: DocumentSourceKind;\n config: string | null; // JSON; null for local_folder\n last_cursor: string | null; // incremental watermark; null for local_folder\n}\n\nconst now = () => new Date().toISOString();\n\nexport function listDocumentSources(): DocumentSourceRow[] {\n return getDb()\n .prepare(\"SELECT * FROM document_sources ORDER BY created_at ASC\")\n .all() as unknown as DocumentSourceRow[];\n}\n\nexport function listEnabledDocumentSources(): DocumentSourceRow[] {\n return getDb()\n .prepare(\"SELECT * FROM document_sources WHERE enabled=1 ORDER BY created_at ASC\")\n .all() as unknown as DocumentSourceRow[];\n}\n\nexport function getDocumentSource(id: string): DocumentSourceRow | null {\n const row = getDb().prepare(\"SELECT * FROM document_sources WHERE id=?\").get(id);\n return (row as DocumentSourceRow | undefined) ?? null;\n}\n\nexport function getDocumentSourceByPath(path: string): DocumentSourceRow | null {\n const row = getDb().prepare(\"SELECT * FROM document_sources WHERE path=?\").get(path);\n return (row as DocumentSourceRow | undefined) ?? null;\n}\n\nexport function createDocumentSource(input: {\n path: string;\n label?: string | null;\n kind?: DocumentSourceKind;\n config?: Record<string, unknown> | null;\n}): DocumentSourceRow {\n const id = randomUUID();\n const t = now();\n const kind = input.kind ?? \"local_folder\";\n const config = input.config ? JSON.stringify(input.config) : null;\n getDb()\n .prepare(\n `INSERT INTO document_sources\n (id, path, label, enabled, last_scan_at, last_error, created_at, updated_at, kind, config, last_cursor)\n VALUES (?, ?, ?, 1, NULL, NULL, ?, ?, ?, ?, NULL)`,\n )\n .run(id, input.path, input.label ?? null, t, t, kind, config);\n return {\n id,\n path: input.path,\n label: input.label ?? null,\n enabled: 1,\n last_scan_at: null,\n last_error: null,\n created_at: t,\n updated_at: t,\n kind,\n config,\n last_cursor: null,\n };\n}\n\n// Parsed-config accessor — JSON.parse on every call would be fine at our\n// scale but this helper keeps call sites tidy.\nexport function parseSourceConfig<T = Record<string, unknown>>(\n row: DocumentSourceRow,\n): T | null {\n if (!row.config) return null;\n try { return JSON.parse(row.config) as T; } catch { return null; }\n}\n\nexport function updateDocumentSourceCursor(id: string, cursor: string | null): void {\n getDb()\n .prepare(\"UPDATE document_sources SET last_cursor=?, updated_at=? WHERE id=?\")\n .run(cursor, now(), id);\n}\n\nexport function updateDocumentSource(\n id: string,\n patch: { label?: string | null; enabled?: boolean },\n): DocumentSourceRow | null {\n const existing = getDocumentSource(id);\n if (!existing) return null;\n const t = now();\n getDb()\n .prepare(\n `UPDATE document_sources SET label=?, enabled=?, updated_at=? WHERE id=?`,\n )\n .run(\n patch.label === undefined ? existing.label : patch.label,\n patch.enabled === undefined ? existing.enabled : patch.enabled ? 1 : 0,\n t,\n id,\n );\n return getDocumentSource(id);\n}\n\nexport function deleteDocumentSource(id: string): boolean {\n // ON DELETE CASCADE handles documents + chunks.\n return (\n (getDb()\n .prepare(\"DELETE FROM document_sources WHERE id=?\")\n .run(id) as { changes: number }).changes > 0\n );\n}\n\nexport function markSourceScanned(\n id: string,\n error?: string | null,\n): void {\n getDb()\n .prepare(\n \"UPDATE document_sources SET last_scan_at=?, last_error=?, updated_at=? WHERE id=?\",\n )\n .run(now(), error ?? null, now(), id);\n}\n\nexport interface DocumentSourceStats {\n source_id: string;\n document_count: number;\n chunk_count: number;\n embedded_chunk_count: number;\n}\n\nexport function getDocumentSourceStats(sourceId: string): DocumentSourceStats {\n const db = getDb();\n const docs = db\n .prepare(\"SELECT COUNT(*) AS n FROM documents WHERE source_id=?\")\n .get(sourceId) as { n: number };\n const chunks = db\n .prepare(\n `SELECT COUNT(*) AS n\n FROM document_chunks dc JOIN documents d ON dc.document_id = d.id\n WHERE d.source_id=?`,\n )\n .get(sourceId) as { n: number };\n const embedded = db\n .prepare(\n `SELECT COUNT(*) AS n\n FROM document_chunks dc JOIN documents d ON dc.document_id = d.id\n WHERE d.source_id=? AND dc.embedding IS NOT NULL`,\n )\n .get(sourceId) as { n: number };\n return {\n source_id: sourceId,\n document_count: docs.n,\n chunk_count: chunks.n,\n embedded_chunk_count: embedded.n,\n };\n}\n"],"names":["getOrCreateGlobal","key","factory","g","globalThis","undefined","z","tool","DEFAULT_DEADLINE_MS","DEADLINE_DESCRIPTION","wrapWithWallclock","t","schema","extendedSchema","ZodObject","extend","deadline_ms","number","int","positive","optional","describe","wrappedFunc","args","config","deadlineMs","readDeadlineMs","innerArgs","stripDeadline","timer","timeoutPromise","Promise","resolve","setTimeout","JSON","stringify","ok","error_code","message","name","unref","work","invoke","race","clearTimeout","rebuilt","description","v","Number","isFinite","_ignore","rest","__DEFAULT_DEADLINE_MS","CATEGORY_GROUPS","Memory","Documents","Files","Shell","Web","Images","Voice","Schedule","Config","Mail","Calendar","Agent","Atlassian","JiraAlign","GitHub","REGISTRY","Map","registerTools","category","capability","tools","group","wrapped","has","Error","w","set","push","registeredTools","Array","from","values","e","registeredNames","Set","keys","registeredCategory","get","registeredCapability","registeredGroup","_resetRegistry","clear","adfToText","adf","parts","walk","node","depth","text","block","type","test","isArray","content","c","join","replace","trim","htmlToText","html","s","randomUUID","createHash","getDb","chunkAndEmbedDocument","findExisting","sourceId","path","row","prepare","isoToMtime","iso","Date","parse","h","update","digest","readUInt32BE","hashContent","upsertRemoteDocument","input","db","toISOString","hash","mtime","externalUpdatedAt","existing","content_hash","run","id","status","chunks","embedded","embedError","docId","size","Buffer","byteLength","title","r","evictMissing","keepPaths","rows","all","removed","del","_atlassianFetch","_resolveAtlassianAuth","parseSourceConfig","updateDocumentSourceCursor","PAGE_LIMIT","MAX_PAGES_PER_RUN","buildCql","source","since","cfg","clauses","kind","space_key","cql","slice","recency_days","pageUpdatedAt","p","version","when","history","lastUpdated","createdDate","fetchPage","auth","pageId","data","encodeURIComponent","error","runConfluenceIndexer","stats","scanned","added","updated","unchanged","errors","cursor","last_cursor","embedFailed","start","highWater","url","results","length","page","body","storage","value","updatedAt","res","indexConfluencePageById","stripHtml","truncateBytes","googleFetch","resolveGoogleAuth","graphFetch","resolveMicrosoftAuth","BODY_CAP","DEFAULT_MAX_RESULTS","DEFAULT_PAGE_SIZE","MAX_RESULTS_CAP","header","headers","hit","find","toLowerCase","decodeBase64Url","toString","findPart","part","mime","mimeType","filename","child","extractGmailBody","payload","plain","preserveParagraphs","recipientToStr","addr","emailAddress","address","summarizeGraphMessage","m","to","toRecipients","map","filter","Boolean","cc","ccRecipients","bodyPreview","contentType","capped","subject","receivedDateTime","line","lastModifiedDateTime","gmailSourceConfig","query","String","max_results","Math","min","max","page_size","outlookSourceConfig","indexGmailMail","keep","pageToken","limit","qs","URLSearchParams","q","maxResults","list","batch","messages","entry","msg","snippet","internalDate","index","item","entries","add","nextPageToken","indexOutlookMail","nextLink","ConsistencyLevel","summary","runMailIndexer","MAX_ISSUES_PER_RUN","buildJql","project_key","jql","formatJqlDate","d","isNaN","getTime","pad","n","padStart","getUTCFullYear","getUTCMonth","getUTCDate","getUTCHours","getUTCMinutes","flattenIssue","issue","baseUrl","f","fields","desc","comment","comments","author","displayName","ts","created","fetchIssue","runJiraIndexer","method","issues","indexJiraIssueByKey","_ghFetch","_resolveGithubAuth","ALLOWED_EXT","isLikelyBinary","lowerExt","PR_PAGE_LIMIT","MAX_PRS_PER_RUN","MAX_FILES_PER_RUN","MAX_FILE_BYTES","ghError","liteAuthor","u","login","flattenPull","pr","reviews","html_url","state","draft","user","created_at","submitted_at","listIssueComments","owner","repo","listReviews","emptyStats","applyUpsert","runGithubPullsIndexer","cutoffMs","now","sinceMs","NaN","outer","err","pulls","updated_at","updatedMs","resolveDefaultBranch","default_branch","runGithubRepoIndexer","ref","tree","treeSha","sha","prefix","path_prefix","blobs","startsWith","contents","split","buf","encoding","runGithubIndexer","indexGithubPullByUrl","indexGithubIssueByUrl","indexGithubFileByUrl","createDocumentSource","getDocumentSourceByPath","markSourceScanned","isRemoteKind","runRemoteSource","lastError","composite","ON_DEMAND_PATH","getOrCreateOnDemandSource","label","indexOnDemand","trimmed","bareKey","result","identifier","source_id","browse","match","pages","ghPull","ghIssue","ghBlob","cleanPath","maxBytes","truncated","end","parseJsonSafe","fallback","randomBytes","DEFAULT_TTL_MS","DEFAULT_MAX_FLOWS","createOAuthFlowStore","opts","ttlMs","maxFlows","flows","globalKey","gc","k","createdAt","delete","oldest","sort","a","b","i","create","flow","patch","Object","assign","getIntegrationRaw","resolveAuth","envUrl","process","env","ATLASSIAN_URL","envEmail","ATLASSIAN_EMAIL","envToken","ATLASSIAN_API_TOKEN","stripTrailingSlash","email","apiToken","saved","api_token","authHeader","init","atlassianFetch","fetch","Authorization","Accept","jiraSearchTool","fieldList","assignee","priority","next_page_token","object","string","array","jiraGetIssueTool","issue_key","expand","custom_fields","include_comments","resolvedCustom","loadJiraFields","resolveCustomFieldNames","unresolved","candidates","custom","hint_first_25_custom_fields","resolved","expandSet","params","baseFields","rendered","renderedFields","customOut","extractFieldValue","issueLinks","issuelinks","l","inward","inwardIssue","outward","outwardIssue","direction","verb","other_issue","remoteLinks","rl","obj","simplifyADF","issuetype","reporter","labels","components","comments_count","total","parent","subtasks","issue_links","attachments","attachment","mime_type","content_url","remote_links","boolean","jiraCreateIssueTool","issue_type","parent_key","assignee_account_id","project","textToADF","accountId","record","unknown","jiraAddCommentTool","comment_id","jiraFindUserTool","users","account_id","display_name","active","jiraUpdateIssueTool","assignee_email","fix_versions","labels_add","labels_remove","fixVersions","inputs","ops","remove","exact","picked","updated_fields","nullable","jiraTransitionsTool","transition_name","available_transitions","transitions","available","transition","transitioned_to","jiraLinkIssuesTool","from_issue","to_issue","link_type","types","issueLinkTypes","available_link_types","usage","wanted","reads_as","bulkIssueSchema","jiraCreateIssuesBulkTool","anyCustom","some","loaded","issueUpdates","jiraAddRemoteLinkTool","icon_url","global_id","icon","url16x16","globalId","remote_link_id","target","jiraDeleteLinkTool","link_id","deleted","enum","jiraUploadAttachmentTool","content_base64","content_text","form","FormData","append","Blob","parsed","jiraDeleteIssueTool","delete_subtasks","SPRINT_STATES","validateSprintTransition","current","jiraListBoardsTool","boards","location","projectKey","is_last","isLast","jiraGetBoardTool","board_id","meta","configuration","filter_id","sub_query","subQuery","estimation_field","estimation","field","fieldId","ranking_field","ranking","rankCustomFieldId","union","jiraListSprintsTool","sprints","goal","start_date","startDate","end_date","endDate","complete_date","completeDate","origin_board_id","originBoardId","jiraGetSprintTool","sprint_id","jiraCreateSprintTool","jiraUpdateSprintTool","check","current_state","legal_next_states","jiraDeleteSprintTool","confirm","deleted_sprint_id","jiraMoveIssuesToSprintTool","issue_keys","moved","jiraMoveIssuesToBacklogTool","moved_to_backlog","jiraRankIssuesTool","rank_before_issue","rank_after_issue","rank_custom_field_id","rankBeforeIssue","rankAfterIssue","ranked","relative_to","before","after","jiraGetCommentsTool","start_at","order_by","startAt","jiraUpdateCommentTool","jiraDeleteCommentTool","deleted_comment_id","jiraGetAttachmentContentTool","as_text","fullUrl","errText","ct","looksText","content_type","as","arrayBuffer","jiraDeleteAttachmentTool","attachment_id","deleted_attachment_id","jiraAddWorklogTool","time_spent","started","timeSpent","worklog_id","jiraListWorklogsTool","worklogs","time_spent_seconds","timeSpentSeconds","jiraGetChangelogTool","changelog","items","field_type","fieldtype","hasOwn","fromString","jiraListProjectsTool","category_id","projects","type_key","projectTypeKey","style","lead","jiraGetProjectTool","include_versions","include_components","include_issue_types","versions","released","archived","release_date","releaseDate","issue_types","issueTypes","subtask","hierarchy_level","hierarchyLevel","jiraListVersionsTool","jiraCreateVersionTool","proj","projectId","version_id","jiraUpdateVersionTool","jiraListComponentsTool","assignee_type","assigneeType","jiraCreateComponentTool","lead_account_id","leadAccountId","component_id","META_KIND_TO_PATH","resolution","META_KINDS","jiraListMetaTool","available_kinds","status_category","statusCategory","confluenceSearchTool","_links","webui","confluenceGetPageTool","page_id","storageVal","viewVal","view","links","space_id","spaceId","parent_id","parentId","body_storage","body_storage_truncated","body_view","body_view_truncated","confluenceGetPageByTitleTool","include_body","sid","resolveSpaceId","matches","confluenceGetPageChildrenTool","children","position","next_cursor","parseV2NextCursor","next","confluenceGetPageAncestorsTool","ancestors","confluenceListSpacesTool","spaces","homepage_id","homepageId","confluenceGetCommentsTool","include_inline","footerData","inlineData","flatten","ver","author_id","authorId","parent_comment_id","parentCommentId","footer_comments","inline_comments","inline_warning","confluenceListAttachmentsTool","media_type","mediaType","file_size","fileSize","download_link","downloadLink","webui_link","confluenceGetLabelsTool","confluenceGetAttachmentContentTool","confluenceCreatePageTool","body_text","resolveBody","representation","confluenceUpdatePageTool","version_number","version_message","nextVersion","resolvedTitle","cur","confluenceAddCommentTool","confluenceMovePageTool","target_id","confluenceUploadAttachmentTool","minor_edit","metadata","extensions","confluenceAddLabelTool","total_labels","confluenceDeletePageTool","purge","deleted_page_id","purged","COMMENT_KIND_TO_PATH","footer","inline","confluenceUpdateCommentTool","segment","confluenceDeleteCommentTool","confluenceRemoveLabelTool","removed_label","confluenceDeleteAttachmentTool","confluenceTextToStorage","escape","para","linksNext","decodeURIComponent","hasText","hasStorage","SPACE_ID_CACHE_TTL_MS","spaceIdCache","spaceKey","cacheKey","cached","FIELD_CACHE_TTL_MS","fieldCache","byId","byName","raw","renderedHTML","coerceItem","flatMap","out","walkChildren","GITHUB_TOKEN","GH_TOKEN","token","API","ghFetch","COMMENT_CAP","PATCH_CAP","SNIPPET_CAP","truncate","cap","decodeContentsBlob","binary","size_bytes","b64","liteUser","liteLabels","githubSearchIssuesTool","total_count","is_pr","pull_request","githubGetIssueTool","assignees","closed_at","githubCreateIssueTool","githubAddCommentTool","githubListPullsTool","head","base","per_page","githubGetPullTool","merged","mergeable","mergeable_state","full_name","changed_files","additions","deletions","review_comments","merged_at","githubGetRepoTool","visibility","private","topics","language","stars","stargazers_count","forks","forks_count","open_issues","open_issues_count","pushed_at","githubUpdateIssueTool","state_reason","githubListIssueCommentsTool","githubCreatePullTool","maintainer_can_modify","githubUpdatePullTool","githubMergePullTool","commit_title","commit_message","merge_method","merged_sha","githubRequestReviewersTool","reviewers","team_reviewers","requested_users","requested_reviewers","requested_teams","slug","githubCreateReviewTool","event","commit_id","review_id","githubListPullFilesTool","files","changes","previous_filename","patch_truncated","githubListPullReviewsTool","githubListBranchesTool","branches","commit_sha","commit","protected","githubGetFileTool","decoded","githubSearchCodeTool","fragment","text_matches","snip","repository","snippet_truncated","MAX_CHARS","OVERLAP_CHARS","chunkText","paragraphs","re","exec","lastIndex","start_offset","end_offset","tail","pos","promises","fs","relative","sep","embedBestEffort","listEnabledDocumentSources","SKIP_DIRS","MAX_FILES_PER_SOURCE","MAX_INDEX_PER_TICK_PER_SOURCE","lastIndexOf","len","suspicious","root","seen","visit","dir","readdir","withFileTypes","isDirectory","abs","isFile","ext","st","stat","rel","mtime_ms","floor","mtimeMs","listIndexedDocs","listUnembeddedChunks","documentId","backfillDocumentEmbeddings","missing","vectors","updateEmb","readTextFile","readFile","indexSource","indexed","onDisk","maxThisRun","maxFiles","processed","upsertLocalDocument","embed_failed","embed_error","existingId","writeId","info","winner","_label","insertChunk","chunkIds","indexAllSources","sources","maxFilesPerSource","console","decodeHtmlEntities","flowStore","createFlow","getFlow","updateFlow","deleteFlow","GMAIL_SCOPES","buildAuthorizeUrl","client_id","clientId","redirect_uri","redirectUri","response_type","scope","access_type","prompt","include_granted_scopes","exchangeCode","code","client_secret","clientSecret","grant_type","signal","AbortSignal","timeout","envId","GMAIL_CLIENT_ID","envSecret","GMAIL_CLIENT_SECRET","envRefresh","GMAIL_REFRESH_TOKEN","refresh_token","accessTokenCache","getGoogleAccessToken","expires_at","access_token","expires_in","service","TENANT","OUTLOOK_TENANT","MICROSOFT_SCOPES","response_mode","OUTLOOK_CLIENT_ID","OUTLOOK_CLIENT_SECRET","OUTLOOK_REFRESH_TOKEN","getMicrosoftAccessToken","listDocumentSources","getDocumentSource","enabled","last_scan_at","last_error","updateDocumentSource","deleteDocumentSource","getDocumentSourceStats","docs","document_count","chunk_count","embedded_chunk_count"],"sourceRoot":"","ignoreList":[]}
|