@offworld/sdk 0.3.4 → 0.3.5

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/README.md CHANGED
@@ -62,7 +62,7 @@ const globalMap = Paths.globalMap;
62
62
  ```typescript
63
63
  import { cloneRepo, updateRepo, removeRepo } from "@offworld/sdk";
64
64
 
65
- await cloneRepo(repoSource, { shallow: true });
65
+ await cloneRepo(repoSource);
66
66
  await updateRepo("owner/repo");
67
67
  await removeRepo("owner/repo", { referenceOnly: true });
68
68
  ```
@@ -6,6 +6,7 @@ interface StreamPromptOptions {
6
6
  cwd: string;
7
7
  systemPrompt?: string;
8
8
  provider?: string;
9
+ openCodeContext?: OpenCodeContext;
9
10
  model?: string;
10
11
  /** Timeout in milliseconds. Set to 0 or undefined for no timeout. */
11
12
  timeoutMs?: number;
@@ -17,6 +18,75 @@ interface StreamPromptResult {
17
18
  sessionId: string;
18
19
  durationMs: number;
19
20
  }
21
+ interface OpenCodeSession {
22
+ id: string;
23
+ }
24
+ interface OpenCodeEvent {
25
+ type: string;
26
+ properties: Record<string, unknown>;
27
+ }
28
+ interface OpenCodeProviderModel {
29
+ id: string;
30
+ name: string;
31
+ }
32
+ interface OpenCodeProvider {
33
+ id: string;
34
+ name: string;
35
+ models: Record<string, OpenCodeProviderModel>;
36
+ }
37
+ interface OpenCodeProviderListResponse {
38
+ all: OpenCodeProvider[];
39
+ connected: string[];
40
+ default: Record<string, string>;
41
+ }
42
+ interface OpenCodeClient {
43
+ session: {
44
+ create: () => Promise<{
45
+ data: OpenCodeSession;
46
+ error?: unknown;
47
+ }>;
48
+ prompt: (options: {
49
+ path: {
50
+ id: string;
51
+ };
52
+ body: {
53
+ agent?: string;
54
+ parts: Array<{
55
+ type: string;
56
+ text: string;
57
+ }>;
58
+ model?: {
59
+ providerID: string;
60
+ modelID: string;
61
+ };
62
+ };
63
+ }) => Promise<{
64
+ data: unknown;
65
+ error?: unknown;
66
+ }>;
67
+ };
68
+ event: {
69
+ subscribe: () => Promise<{
70
+ stream: AsyncIterable<OpenCodeEvent>;
71
+ }>;
72
+ };
73
+ provider: {
74
+ list: () => Promise<{
75
+ data: OpenCodeProviderListResponse;
76
+ error?: unknown;
77
+ }>;
78
+ };
79
+ }
80
+ interface OpenCodeContext {
81
+ baseUrl: string;
82
+ createClient: (cwd: string) => OpenCodeClient;
83
+ close: () => void;
84
+ }
85
+ interface CreateOpenCodeContextOptions {
86
+ cwd?: string;
87
+ onDebug?: (message: string) => void;
88
+ }
89
+ declare function createOpenCodeContext(options?: CreateOpenCodeContextOptions): Promise<OpenCodeContext>;
20
90
  declare function streamPrompt(options: StreamPromptOptions): Promise<StreamPromptResult>;
21
91
  //#endregion
22
92
  //#region src/ai/errors.d.ts
@@ -97,15 +167,13 @@ declare class TimeoutError extends OpenCodeReferenceError {
97
167
  }
98
168
  //#endregion
99
169
  //#region src/generate.d.ts
100
- /**
101
- * This module provides a streamlined approach to generating reference files
102
- * by delegating all codebase exploration to the AI agent via OpenCode.
103
- */
104
170
  interface GenerateReferenceOptions {
105
171
  /** AI provider ID (e.g., "anthropic", "openai"). Defaults to config value. */
106
172
  provider?: string;
107
173
  /** AI model ID. Defaults to config value. */
108
174
  model?: string;
175
+ /** Shared OpenCode server context for multi-repo generation */
176
+ openCodeContext?: OpenCodeContext;
109
177
  /** Debug callback for detailed logging */
110
178
  onDebug?: (message: string) => void;
111
179
  /** Stream callback for real-time AI output */
@@ -130,5 +198,5 @@ interface GenerateReferenceResult {
130
198
  */
131
199
  declare function generateReferenceWithAI(repoPath: string, repoName: string, options?: GenerateReferenceOptions): Promise<GenerateReferenceResult>;
132
200
  //#endregion
133
- export { DEFAULT_AI_MODEL, DEFAULT_AI_PROVIDER, type GenerateReferenceOptions, type GenerateReferenceResult, InvalidModelError, InvalidProviderError, OpenCodeReferenceError, OpenCodeSDKError, ProviderNotConnectedError, ServerStartError, SessionError, type StreamPromptOptions, type StreamPromptResult, TimeoutError, generateReferenceWithAI, streamPrompt };
201
+ export { DEFAULT_AI_MODEL, DEFAULT_AI_PROVIDER, type GenerateReferenceOptions, type GenerateReferenceResult, InvalidModelError, InvalidProviderError, type OpenCodeClient, type OpenCodeContext, OpenCodeReferenceError, OpenCodeSDKError, ProviderNotConnectedError, ServerStartError, SessionError, type StreamPromptOptions, type StreamPromptResult, TimeoutError, createOpenCodeContext, generateReferenceWithAI, streamPrompt };
134
202
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/ai/opencode.ts","../../src/ai/errors.ts","../../src/generate.ts"],"mappings":";cAca,mBAAA;AAAA,cACA,gBAAA;AAAA,UAEI,mBAAA;EAChB,MAAA;EACA,GAAA;EACA,YAAA;EACA,QAAA;EAEA,KAAA;;EAEA,SAAA;EACA,OAAA,IAAW,OAAA;EACX,QAAA,IAAY,IAAA;AAAA;AAAA,UAGI,kBAAA;EAChB,IAAA;EACA,SAAA;EACA,UAAA;AAAA;AAAA,iBAyLqB,YAAA,CAAa,OAAA,EAAS,mBAAA,GAAsB,OAAA,CAAQ,kBAAA;;;;AA5M1E;;cCXa,sBAAA,SAA+B,KAAA;EAAA,SAI1B,OAAA;EAAA,SAHR,IAAA;cAER,OAAA,UACgB,OAAA;AAAA;;;;cA0BL,gBAAA,SAAyB,sBAAA;EAAA,SAC5B,IAAA;cACG,OAAA;AAAA;;;;cAWA,oBAAA,SAA6B,sBAAA;EAAA,SAKxB,UAAA;EAAA,SACA,kBAAA;EAAA,SALR,IAAA;EAAA,SACA,IAAA;cAGQ,UAAA,UACA,kBAAA;AAAA;;;;cAeL,yBAAA,SAAkC,sBAAA;EAAA,SAK7B,UAAA;EAAA,SACA,kBAAA;EAAA,SALR,IAAA;EAAA,SACA,IAAA;cAGQ,UAAA,UACA,kBAAA;AAAA;;;;cAeL,iBAAA,SAA0B,sBAAA;EAAA,SAKrB,OAAA;EAAA,SACA,UAAA;EAAA,SACA,eAAA;EAAA,SANR,IAAA;EAAA,SACA,IAAA;cAGQ,OAAA,UACA,UAAA,UACA,eAAA;AAAA;;;;cAeL,gBAAA,SAAyB,sBAAA;EAAA,SAMpB,IAAA;EAAA,SALR,IAAA;EAAA,SACA,IAAA;cAGR,OAAA,UACgB,IAAA,uBAChB,OAAA;AAAA;;;AApFF;cAkGa,YAAA,SAAqB,sBAAA;EAAA,SAMhB,SAAA;EAAA,SACA,YAAA;EAAA,SANR,IAAA;EAAA,SACA,IAAA;cAGR,OAAA,UACgB,SAAA,uBACA,YAAA,uBAChB,OAAA;AAAA;;;AA7FF;cA2Ga,YAAA,SAAqB,sBAAA;EAAA,SAKhB,SAAA;EAAA,SACA,SAAA;EAAA,SALR,IAAA;EAAA,SACA,IAAA;cAGQ,SAAA,UACA,SAAA;AAAA;;;;ADjJlB;;;UELiB,wBAAA;EFKe;EEH/B,QAAA;EFI4B;EEF5B,KAAA;EFE4B;EEA5B,OAAA,IAAW,OAAA;EFEK;EEAhB,QAAA,IAAY,IAAA;AAAA;AAAA,UAGI,uBAAA;EFFhB;EEIA,gBAAA;EFFA;EEIA,SAAA;AAAA;;;;;;;;AFMD;;;;iBE2TsB,uBAAA,CACrB,QAAA,UACA,QAAA,UACA,OAAA,GAAS,wBAAA,GACP,OAAA,CAAQ,uBAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/ai/opencode.ts","../../src/ai/errors.ts","../../src/generate.ts"],"mappings":"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"}
package/dist/ai/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { d as toReferenceName, s as loadConfig } from "../config-DW8J4gl5.mjs";
2
- import { c as getCommitSha } from "../clone-DyLvmbJZ.mjs";
2
+ import { c as getCommitSha } from "../clone-Z5ELU2fW.mjs";
3
3
  import { execSync } from "node:child_process";
4
4
  import { z } from "zod";
5
5
 
@@ -457,18 +457,8 @@ function formatToolMessage(tool, state) {
457
457
  default: return `Running ${tool}...`;
458
458
  }
459
459
  }
460
- async function streamPrompt(options) {
461
- const { prompt, cwd, systemPrompt, provider: optProvider, model: optModel, timeoutMs, onDebug, onStream } = options;
462
- const debug = onDebug ?? (() => {});
463
- const stream = onStream ?? (() => {});
464
- const startTime = Date.now();
465
- debug("Loading OpenCode SDK...");
466
- const { createOpencode, createOpencodeClient } = await getOpenCodeSDK();
467
- const maxAttempts = 10;
468
- let server = null;
469
- let client = null;
470
- let port = 0;
471
- const config = {
460
+ function getOpenCodeConfig() {
461
+ return {
472
462
  plugin: [],
473
463
  mcp: {},
474
464
  instructions: [],
@@ -525,19 +515,24 @@ async function streamPrompt(options) {
525
515
  }
526
516
  }
527
517
  };
518
+ }
519
+ async function createOpenCodeContext(options = {}) {
520
+ const debug = options.onDebug ?? (() => {});
521
+ debug("Loading OpenCode SDK...");
522
+ const { createOpencode, createOpencodeClient } = await getOpenCodeSDK();
523
+ const maxAttempts = 10;
524
+ let server = null;
525
+ let port = 0;
526
+ const config = getOpenCodeConfig();
528
527
  debug("Starting embedded OpenCode server...");
529
528
  for (let attempt = 0; attempt < maxAttempts; attempt++) {
530
529
  port = Math.floor(Math.random() * 3e3) + 3e3;
531
530
  try {
532
531
  server = (await createOpencode({
533
532
  port,
534
- cwd,
533
+ cwd: options.cwd,
535
534
  config
536
535
  })).server;
537
- client = createOpencodeClient({
538
- baseUrl: `http://localhost:${port}`,
539
- directory: cwd
540
- });
541
536
  debug(`Server started on port ${port}`);
542
537
  break;
543
538
  } catch (err) {
@@ -545,9 +540,36 @@ async function streamPrompt(options) {
545
540
  throw new ServerStartError("Failed to start OpenCode server", port, err);
546
541
  }
547
542
  }
548
- if (!server || !client) throw new ServerStartError("Failed to start OpenCode server after all attempts");
543
+ if (!server) throw new ServerStartError("Failed to start OpenCode server after all attempts");
544
+ const baseUrl = `http://localhost:${port}`;
545
+ let closed = false;
546
+ return {
547
+ baseUrl,
548
+ createClient: (cwd) => createOpencodeClient({
549
+ baseUrl,
550
+ directory: cwd
551
+ }),
552
+ close: () => {
553
+ if (closed) return;
554
+ closed = true;
555
+ debug("Closing server...");
556
+ server?.close();
557
+ }
558
+ };
559
+ }
560
+ async function streamPrompt(options) {
561
+ const { prompt, cwd, systemPrompt, provider: optProvider, model: optModel, timeoutMs, onDebug, onStream, openCodeContext } = options;
562
+ const debug = onDebug ?? (() => {});
563
+ const stream = onStream ?? (() => {});
564
+ const startTime = Date.now();
549
565
  const providerID = optProvider ?? DEFAULT_AI_PROVIDER;
550
566
  const modelID = optModel ?? DEFAULT_AI_MODEL;
567
+ const shouldCloseContext = !openCodeContext;
568
+ const context = openCodeContext ?? await createOpenCodeContext({
569
+ cwd,
570
+ onDebug: debug
571
+ });
572
+ const client = context.createClient(cwd);
551
573
  try {
552
574
  debug("Creating session...");
553
575
  const sessionResult = await client.session.create();
@@ -644,8 +666,7 @@ async function streamPrompt(options) {
644
666
  durationMs
645
667
  };
646
668
  } finally {
647
- debug("Closing server...");
648
- server.close();
669
+ if (shouldCloseContext) context.close();
649
670
  }
650
671
  }
651
672
 
@@ -913,7 +934,7 @@ function validateReferenceContent(content) {
913
934
  * @returns The generated reference content and commit SHA
914
935
  */
915
936
  async function generateReferenceWithAI(repoPath, repoName, options = {}) {
916
- const { provider, model, onDebug, onStream } = options;
937
+ const { provider, model, onDebug, onStream, openCodeContext } = options;
917
938
  const [configProvider, configModel] = loadConfig().defaultModel?.split("/") ?? [];
918
939
  const aiProvider = provider ?? configProvider;
919
940
  const aiModel = model ?? configModel;
@@ -929,6 +950,7 @@ async function generateReferenceWithAI(repoPath, repoName, options = {}) {
929
950
  cwd: repoPath,
930
951
  provider: aiProvider,
931
952
  model: aiModel,
953
+ openCodeContext,
932
954
  onDebug,
933
955
  onStream
934
956
  });
@@ -942,5 +964,5 @@ async function generateReferenceWithAI(repoPath, repoName, options = {}) {
942
964
  }
943
965
 
944
966
  //#endregion
945
- export { DEFAULT_AI_MODEL, DEFAULT_AI_PROVIDER, InvalidModelError, InvalidProviderError, OpenCodeReferenceError, OpenCodeSDKError, ProviderNotConnectedError, ServerStartError, SessionError, TimeoutError, generateReferenceWithAI, streamPrompt };
967
+ export { DEFAULT_AI_MODEL, DEFAULT_AI_PROVIDER, InvalidModelError, InvalidProviderError, OpenCodeReferenceError, OpenCodeSDKError, ProviderNotConnectedError, ServerStartError, SessionError, TimeoutError, createOpenCodeContext, generateReferenceWithAI, streamPrompt };
946
968
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/ai/errors.ts","../../src/ai/stream/types.ts","../../src/ai/stream/accumulator.ts","../../src/ai/stream/transformer.ts","../../src/ai/opencode.ts","../../src/generate.ts"],"sourcesContent":["/**\n * Base class for OpenCode reference errors\n */\nexport class OpenCodeReferenceError extends Error {\n\treadonly _tag: string = \"OpenCodeReferenceError\";\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic readonly details?: unknown,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"OpenCodeReferenceError\";\n\t}\n}\n\n/**\n * Error when the opencode CLI binary is not installed\n */\nexport class OpenCodeNotInstalledError extends OpenCodeReferenceError {\n\treadonly _tag = \"OpenCodeNotInstalledError\" as const;\n\treadonly hint: string;\n\n\tconstructor() {\n\t\tconst hint =\n\t\t\t\"opencode is required for local AI reference generation. Install it: curl -fsSL https://opencode.ai/install | bash\";\n\t\tsuper(`opencode is not installed. ${hint}`);\n\t\tthis.name = \"OpenCodeNotInstalledError\";\n\t\tthis.hint = hint;\n\t}\n}\n\n/**\n * Error when the @opencode-ai/sdk package is not installed or invalid\n */\nexport class OpenCodeSDKError extends OpenCodeReferenceError {\n\treadonly _tag = \"OpenCodeSDKError\" as const;\n\tconstructor(message?: string) {\n\t\tsuper(\n\t\t\tmessage ?? \"Failed to import @opencode-ai/sdk. Install it with: bun add @opencode-ai/sdk\",\n\t\t);\n\t\tthis.name = \"OpenCodeSDKError\";\n\t}\n}\n\n/**\n * Error when the requested provider is not found\n */\nexport class InvalidProviderError extends OpenCodeReferenceError {\n\treadonly _tag = \"InvalidProviderError\" as const;\n\treadonly hint: string;\n\n\tconstructor(\n\t\tpublic readonly providerID: string,\n\t\tpublic readonly availableProviders: string[],\n\t) {\n\t\tconst hint =\n\t\t\tavailableProviders.length > 0\n\t\t\t\t? `Available providers: ${availableProviders.join(\", \")}`\n\t\t\t\t: \"No providers available. Check your OpenCode configuration.\";\n\t\tsuper(`Provider \"${providerID}\" not found. ${hint}`);\n\t\tthis.name = \"InvalidProviderError\";\n\t\tthis.hint = hint;\n\t}\n}\n\n/**\n * Error when the provider exists but is not connected/authenticated\n */\nexport class ProviderNotConnectedError extends OpenCodeReferenceError {\n\treadonly _tag = \"ProviderNotConnectedError\" as const;\n\treadonly hint: string;\n\n\tconstructor(\n\t\tpublic readonly providerID: string,\n\t\tpublic readonly connectedProviders: string[],\n\t) {\n\t\tconst hint =\n\t\t\tconnectedProviders.length > 0\n\t\t\t\t? `Connected providers: ${connectedProviders.join(\", \")}. Run 'opencode auth ${providerID}' to connect.`\n\t\t\t\t: `No providers connected. Run 'opencode auth ${providerID}' to authenticate.`;\n\t\tsuper(`Provider \"${providerID}\" is not connected. ${hint}`);\n\t\tthis.name = \"ProviderNotConnectedError\";\n\t\tthis.hint = hint;\n\t}\n}\n\n/**\n * Error when the requested model is not found for a provider\n */\nexport class InvalidModelError extends OpenCodeReferenceError {\n\treadonly _tag = \"InvalidModelError\" as const;\n\treadonly hint: string;\n\n\tconstructor(\n\t\tpublic readonly modelID: string,\n\t\tpublic readonly providerID: string,\n\t\tpublic readonly availableModels: string[],\n\t) {\n\t\tconst hint =\n\t\t\tavailableModels.length > 0\n\t\t\t\t? `Available models for ${providerID}: ${availableModels.slice(0, 10).join(\", \")}${availableModels.length > 10 ? ` (and ${availableModels.length - 10} more)` : \"\"}`\n\t\t\t\t: `No models available for provider \"${providerID}\".`;\n\t\tsuper(`Model \"${modelID}\" not found for provider \"${providerID}\". ${hint}`);\n\t\tthis.name = \"InvalidModelError\";\n\t\tthis.hint = hint;\n\t}\n}\n\n/**\n * Error when the OpenCode server fails to start\n */\nexport class ServerStartError extends OpenCodeReferenceError {\n\treadonly _tag = \"ServerStartError\" as const;\n\treadonly hint: string;\n\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic readonly port?: number,\n\t\tdetails?: unknown,\n\t) {\n\t\tconst hint = port\n\t\t\t? `Failed to start server on port ${port}. Ensure no other process is using this port.`\n\t\t\t: \"Failed to start OpenCode server. Check your OpenCode installation and configuration.\";\n\t\tsuper(`${message}. ${hint}`, details);\n\t\tthis.name = \"ServerStartError\";\n\t\tthis.hint = hint;\n\t}\n}\n\n/**\n * Error when a session operation fails\n */\nexport class SessionError extends OpenCodeReferenceError {\n\treadonly _tag = \"SessionError\" as const;\n\treadonly hint: string;\n\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic readonly sessionId?: string,\n\t\tpublic readonly sessionState?: string,\n\t\tdetails?: unknown,\n\t) {\n\t\tconst context = sessionId ? ` (session: ${sessionId})` : \"\";\n\t\tconst stateInfo = sessionState ? ` State: ${sessionState}.` : \"\";\n\t\tconst hint = `Session operation failed${context}.${stateInfo} Try creating a new session.`;\n\t\tsuper(`${message}. ${hint}`, details);\n\t\tthis.name = \"SessionError\";\n\t\tthis.hint = hint;\n\t}\n}\n\n/**\n * Error when a request times out\n */\nexport class TimeoutError extends OpenCodeReferenceError {\n\treadonly _tag = \"TimeoutError\" as const;\n\treadonly hint: string;\n\n\tconstructor(\n\t\tpublic readonly timeoutMs: number,\n\t\tpublic readonly operation: string = \"operation\",\n\t) {\n\t\tconst hint = `The ${operation} did not complete within ${timeoutMs}ms. Consider increasing the timeout or checking if the model is responding.`;\n\t\tsuper(`Timeout: ${operation} did not complete within ${timeoutMs}ms. ${hint}`);\n\t\tthis.name = \"TimeoutError\";\n\t\tthis.hint = hint;\n\t}\n}\n","/**\n * Zod schemas for OpenCode stream events\n * Replaces inline `as` casts with runtime-validated types\n */\n\nimport { z } from \"zod\";\n\nconst PartBaseSchema = z.object({\n\tid: z.string().optional(),\n\tsessionID: z.string().optional(),\n\tmessageID: z.string().optional(),\n});\n\nexport const TextPartSchema = PartBaseSchema.extend({\n\ttype: z.literal(\"text\"),\n\ttext: z.string().optional(),\n});\n\nexport const ToolStatePendingSchema = z.object({\n\tstatus: z.literal(\"pending\"),\n});\n\nexport const ToolStateRunningSchema = z.object({\n\tstatus: z.literal(\"running\"),\n\ttitle: z.string().optional(),\n\tinput: z.unknown().optional(),\n\tmetadata: z.record(z.string(), z.unknown()).optional(),\n\ttime: z\n\t\t.object({\n\t\t\tstart: z.number(),\n\t\t})\n\t\t.optional(),\n});\n\nexport const ToolStateCompletedSchema = z.object({\n\tstatus: z.literal(\"completed\"),\n\ttitle: z.string().optional(),\n\tinput: z.record(z.string(), z.unknown()).optional(),\n\toutput: z.string().optional(),\n\tmetadata: z.record(z.string(), z.unknown()).optional(),\n\ttime: z\n\t\t.object({\n\t\t\tstart: z.number(),\n\t\t\tend: z.number(),\n\t\t})\n\t\t.optional(),\n});\n\nexport const ToolStateErrorSchema = z.object({\n\tstatus: z.literal(\"error\"),\n\terror: z.string().optional(),\n\tinput: z.record(z.string(), z.unknown()).optional(),\n\ttime: z\n\t\t.object({\n\t\t\tstart: z.number(),\n\t\t\tend: z.number(),\n\t\t})\n\t\t.optional(),\n});\n\nexport const ToolStateSchema = z.discriminatedUnion(\"status\", [\n\tToolStatePendingSchema,\n\tToolStateRunningSchema,\n\tToolStateCompletedSchema,\n\tToolStateErrorSchema,\n]);\n\nexport const ToolPartSchema = PartBaseSchema.extend({\n\ttype: z.literal(\"tool\"),\n\tcallID: z.string().optional(),\n\ttool: z.string().optional(),\n\tstate: ToolStateSchema.optional(),\n});\n\nexport const StepStartPartSchema = PartBaseSchema.extend({\n\ttype: z.literal(\"step-start\"),\n});\n\nexport const StepFinishPartSchema = PartBaseSchema.extend({\n\ttype: z.literal(\"step-finish\"),\n\treason: z.string().optional(),\n});\n\nexport const ToolUsePartSchema = PartBaseSchema.extend({\n\ttype: z.literal(\"tool-use\"),\n\ttoolUseId: z.string().optional(),\n\tname: z.string().optional(),\n});\n\nexport const ToolResultPartSchema = PartBaseSchema.extend({\n\ttype: z.literal(\"tool-result\"),\n\ttoolUseId: z.string().optional(),\n});\n\nexport const MessagePartSchema = z.discriminatedUnion(\"type\", [\n\tTextPartSchema,\n\tToolPartSchema,\n\tStepStartPartSchema,\n\tStepFinishPartSchema,\n\tToolUsePartSchema,\n\tToolResultPartSchema,\n]);\n\n/**\n * Session error payload\n */\nexport const SessionErrorSchema = z.object({\n\tname: z.string().optional(),\n\tmessage: z.string().optional(),\n\tcode: z.string().optional(),\n});\n\nexport const MessagePartUpdatedPropsSchema = z.object({\n\tpart: MessagePartSchema,\n});\n\n/**\n * Properties for session.idle event\n */\nexport const SessionIdlePropsSchema = z.object({\n\tsessionID: z.string(),\n});\n\n/**\n * Properties for session.error event\n */\nexport const SessionErrorPropsSchema = z.object({\n\tsessionID: z.string(),\n\terror: SessionErrorSchema.optional(),\n});\n\n/**\n * Properties for session.updated event\n */\nexport const SessionUpdatedPropsSchema = z.object({\n\tsessionID: z.string(),\n\tstatus: z.string().optional(),\n});\n\n/**\n * message.part.updated event\n */\nexport const MessagePartUpdatedEventSchema = z.object({\n\ttype: z.literal(\"message.part.updated\"),\n\tproperties: MessagePartUpdatedPropsSchema,\n});\n\n/**\n * session.idle event\n */\nexport const SessionIdleEventSchema = z.object({\n\ttype: z.literal(\"session.idle\"),\n\tproperties: SessionIdlePropsSchema,\n});\n\n/**\n * session.error event\n */\nexport const SessionErrorEventSchema = z.object({\n\ttype: z.literal(\"session.error\"),\n\tproperties: SessionErrorPropsSchema,\n});\n\n/**\n * session.updated event\n */\nexport const SessionUpdatedEventSchema = z.object({\n\ttype: z.literal(\"session.updated\"),\n\tproperties: SessionUpdatedPropsSchema,\n});\n\n/**\n * Generic event for unknown types (passthrough)\n */\nexport const GenericEventSchema = z.object({\n\ttype: z.string(),\n\tproperties: z.record(z.string(), z.unknown()),\n});\n\nexport type TextPart = z.infer<typeof TextPartSchema>;\nexport type ToolPart = z.infer<typeof ToolPartSchema>;\nexport type ToolState = z.infer<typeof ToolStateSchema>;\nexport type ToolStateRunning = z.infer<typeof ToolStateRunningSchema>;\nexport type ToolUsePart = z.infer<typeof ToolUsePartSchema>;\nexport type ToolResultPart = z.infer<typeof ToolResultPartSchema>;\nexport type MessagePart = z.infer<typeof MessagePartSchema>;\n\nexport type SessionErrorPayload = z.infer<typeof SessionErrorSchema>;\n\nexport type MessagePartUpdatedProps = z.infer<typeof MessagePartUpdatedPropsSchema>;\nexport type SessionIdleProps = z.infer<typeof SessionIdlePropsSchema>;\nexport type SessionErrorProps = z.infer<typeof SessionErrorPropsSchema>;\nexport type SessionUpdatedProps = z.infer<typeof SessionUpdatedPropsSchema>;\n\nexport type MessagePartUpdatedEvent = z.infer<typeof MessagePartUpdatedEventSchema>;\nexport type SessionIdleEvent = z.infer<typeof SessionIdleEventSchema>;\nexport type SessionErrorEvent = z.infer<typeof SessionErrorEventSchema>;\nexport type SessionUpdatedEvent = z.infer<typeof SessionUpdatedEventSchema>;\nexport type GenericEvent = z.infer<typeof GenericEventSchema>;\n\n/**\n * All known stream event types\n */\nexport type StreamEvent =\n\t| MessagePartUpdatedEvent\n\t| SessionIdleEvent\n\t| SessionErrorEvent\n\t| SessionUpdatedEvent\n\t| GenericEvent;\n","/**\n * Text accumulator for stream events\n * Manages accumulation of text parts by ID and provides delta extraction\n */\n\nimport type { TextPart } from \"./types.js\";\n\n/**\n * Accumulates text from streaming message parts.\n * Tracks multiple parts by ID and provides delta text between updates.\n */\nexport class TextAccumulator {\n\tprivate readonly parts = new Map<string, string>();\n\tprivate _firstTextReceived = false;\n\n\t/**\n\t * Whether any text has been received\n\t */\n\tget hasReceivedText(): boolean {\n\t\treturn this._firstTextReceived;\n\t}\n\n\t/**\n\t * Accumulate text from a message part and return the delta (new text only).\n\t * Returns null if the part should be skipped (non-text, no ID, no text).\n\t */\n\taccumulatePart(part: TextPart): string | null {\n\t\tif (part.type !== \"text\" || !part.text || !part.id) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst partId = part.id;\n\t\tconst prevText = this.parts.get(partId) ?? \"\";\n\t\tthis.parts.set(partId, part.text);\n\n\t\tif (!this._firstTextReceived) {\n\t\t\tthis._firstTextReceived = true;\n\t\t}\n\n\t\tif (part.text.length > prevText.length) {\n\t\t\treturn part.text.slice(prevText.length);\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Get the full accumulated text from all parts\n\t */\n\tgetFullText(): string {\n\t\treturn Array.from(this.parts.values()).join(\"\");\n\t}\n\n\t/**\n\t * Get the number of distinct parts accumulated\n\t */\n\tgetPartCount(): number {\n\t\treturn this.parts.size;\n\t}\n\n\t/**\n\t * Get info about each part for debugging\n\t */\n\tgetPartInfo(): Array<{ id: string; length: number }> {\n\t\treturn Array.from(this.parts.entries()).map(([id, text]) => ({\n\t\t\tid,\n\t\t\tlength: text.length,\n\t\t}));\n\t}\n\n\t/**\n\t * Clear accumulated text\n\t */\n\tclear(): void {\n\t\tthis.parts.clear();\n\t\tthis._firstTextReceived = false;\n\t}\n}\n","/**\n * Stream event transformer and parser\n * Safely parses and validates stream events using Zod schemas\n */\n\nimport {\n\tMessagePartUpdatedPropsSchema,\n\tSessionIdlePropsSchema,\n\tSessionErrorPropsSchema,\n\tSessionErrorSchema,\n\ttype TextPart,\n\ttype ToolPart,\n\ttype SessionErrorPayload,\n\ttype MessagePartUpdatedProps,\n\ttype SessionIdleProps,\n\ttype SessionErrorProps,\n} from \"./types.js\";\n\n/**\n * Raw event from the OpenCode SDK stream\n */\nexport interface RawStreamEvent {\n\ttype: string;\n\tproperties: Record<string, unknown>;\n}\n\n/**\n * Result of parsing a stream event\n */\nexport type ParsedEventResult =\n\t| {\n\t\t\ttype: \"message.part.updated\";\n\t\t\tprops: MessagePartUpdatedProps;\n\t\t\ttextPart: TextPart | null;\n\t\t\ttoolPart: ToolPart | null;\n\t }\n\t| { type: \"session.idle\"; props: SessionIdleProps }\n\t| { type: \"session.error\"; props: SessionErrorProps; error: SessionErrorPayload | null }\n\t| { type: \"unknown\"; rawType: string };\n\n/**\n * Parse a raw stream event into a typed result.\n * Uses safe parsing - returns type: \"unknown\" for unrecognized or invalid events.\n */\nexport function parseStreamEvent(event: RawStreamEvent): ParsedEventResult {\n\tswitch (event.type) {\n\t\tcase \"message.part.updated\": {\n\t\t\tconst propsResult = MessagePartUpdatedPropsSchema.safeParse(event.properties);\n\t\t\tif (!propsResult.success) {\n\t\t\t\treturn { type: \"unknown\", rawType: event.type };\n\t\t\t}\n\t\t\tconst props = propsResult.data;\n\t\t\tconst textPart = props.part.type === \"text\" ? props.part : null;\n\t\t\tconst toolPart = props.part.type === \"tool\" ? props.part : null;\n\t\t\treturn { type: \"message.part.updated\", props, textPart, toolPart };\n\t\t}\n\n\t\tcase \"session.idle\": {\n\t\t\tconst propsResult = SessionIdlePropsSchema.safeParse(event.properties);\n\t\t\tif (!propsResult.success) {\n\t\t\t\treturn { type: \"unknown\", rawType: event.type };\n\t\t\t}\n\t\t\treturn { type: \"session.idle\", props: propsResult.data };\n\t\t}\n\n\t\tcase \"session.error\": {\n\t\t\tconst propsResult = SessionErrorPropsSchema.safeParse(event.properties);\n\t\t\tif (!propsResult.success) {\n\t\t\t\treturn { type: \"unknown\", rawType: event.type };\n\t\t\t}\n\t\t\tconst props = propsResult.data;\n\n\t\t\tlet error: SessionErrorPayload | null = null;\n\t\t\tif (props.error) {\n\t\t\t\tconst errorResult = SessionErrorSchema.safeParse(props.error);\n\t\t\t\tif (errorResult.success) {\n\t\t\t\t\terror = errorResult.data;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn { type: \"session.error\", props, error };\n\t\t}\n\n\t\tdefault:\n\t\t\treturn { type: \"unknown\", rawType: event.type };\n\t}\n}\n\nexport function isEventForSession(event: RawStreamEvent, sessionId: string): boolean {\n\tconst props = event.properties;\n\tif (\"sessionID\" in props && typeof props.sessionID === \"string\") {\n\t\treturn props.sessionID === sessionId;\n\t}\n\tif (\n\t\t\"part\" in props &&\n\t\ttypeof props.part === \"object\" &&\n\t\tprops.part !== null &&\n\t\t\"sessionID\" in props.part &&\n\t\ttypeof props.part.sessionID === \"string\"\n\t) {\n\t\treturn props.part.sessionID === sessionId;\n\t}\n\treturn true;\n}\n","import { execSync } from \"node:child_process\";\nimport {\n\tOpenCodeReferenceError,\n\tOpenCodeSDKError,\n\tOpenCodeNotInstalledError,\n\tInvalidProviderError,\n\tProviderNotConnectedError,\n\tInvalidModelError,\n\tServerStartError,\n\tSessionError,\n\tTimeoutError,\n} from \"./errors.js\";\nimport { TextAccumulator, parseStreamEvent, isEventForSession } from \"./stream/index.js\";\n\nexport const DEFAULT_AI_PROVIDER = \"opencode\";\nexport const DEFAULT_AI_MODEL = \"claude-opus-4-5\";\n\nexport interface StreamPromptOptions {\n\tprompt: string;\n\tcwd: string;\n\tsystemPrompt?: string;\n\tprovider?: string;\n\n\tmodel?: string;\n\t/** Timeout in milliseconds. Set to 0 or undefined for no timeout. */\n\ttimeoutMs?: number;\n\tonDebug?: (message: string) => void;\n\tonStream?: (text: string) => void;\n}\n\nexport interface StreamPromptResult {\n\ttext: string;\n\tsessionId: string;\n\tdurationMs: number;\n}\n\ninterface OpenCodeServer {\n\tclose: () => void;\n\turl: string;\n}\n\ninterface OpenCodeSession {\n\tid: string;\n}\n\ninterface OpenCodeEvent {\n\ttype: string;\n\tproperties: Record<string, unknown>;\n}\n\ninterface OpenCodeProviderModel {\n\tid: string;\n\tname: string;\n}\n\ninterface OpenCodeProvider {\n\tid: string;\n\tname: string;\n\tmodels: Record<string, OpenCodeProviderModel>;\n}\n\ninterface OpenCodeProviderListResponse {\n\tall: OpenCodeProvider[];\n\tconnected: string[];\n\tdefault: Record<string, string>;\n}\n\ninterface OpenCodeClient {\n\tsession: {\n\t\tcreate: () => Promise<{ data: OpenCodeSession; error?: unknown }>;\n\t\tprompt: (options: {\n\t\t\tpath: { id: string };\n\t\t\tbody: {\n\t\t\t\tagent?: string;\n\t\t\t\tparts: Array<{ type: string; text: string }>;\n\t\t\t\tmodel?: { providerID: string; modelID: string };\n\t\t\t};\n\t\t}) => Promise<{ data: unknown; error?: unknown }>;\n\t};\n\tevent: {\n\t\tsubscribe: () => Promise<{\n\t\t\tstream: AsyncIterable<OpenCodeEvent>;\n\t\t}>;\n\t};\n\tprovider: {\n\t\tlist: () => Promise<{ data: OpenCodeProviderListResponse; error?: unknown }>;\n\t};\n}\n\ninterface AgentConfig {\n\tdisable?: boolean;\n\tprompt?: string;\n\tdescription?: string;\n\tmode?: string;\n\tpermission?: Record<string, string>;\n\ttools?: Record<string, boolean>;\n}\n\ninterface OpenCodeConfig {\n\tplugin?: unknown[];\n\tmcp?: Record<string, unknown>;\n\tinstructions?: unknown[];\n\tagent?: Record<string, AgentConfig>;\n}\n\ntype CreateOpencodeResult = { server: OpenCodeServer };\ntype CreateOpencodeClientFn = (opts: { baseUrl: string; directory: string }) => OpenCodeClient;\ntype CreateOpencodeFn = (opts: {\n\tport: number;\n\tcwd?: string;\n\tconfig?: OpenCodeConfig;\n}) => Promise<CreateOpencodeResult>;\n\nlet cachedCreateOpencode: CreateOpencodeFn | null = null;\nlet cachedCreateOpencodeClient: CreateOpencodeClientFn | null = null;\n\nfunction assertOpenCodeInstalled(): void {\n\ttry {\n\t\texecSync(\"opencode --version\", { stdio: \"ignore\" });\n\t} catch {\n\t\tthrow new OpenCodeNotInstalledError();\n\t}\n}\n\nasync function getOpenCodeSDK(): Promise<{\n\tcreateOpencode: CreateOpencodeFn;\n\tcreateOpencodeClient: CreateOpencodeClientFn;\n}> {\n\tif (cachedCreateOpencode && cachedCreateOpencodeClient) {\n\t\treturn {\n\t\t\tcreateOpencode: cachedCreateOpencode,\n\t\t\tcreateOpencodeClient: cachedCreateOpencodeClient,\n\t\t};\n\t}\n\n\tassertOpenCodeInstalled();\n\n\ttry {\n\t\tconst sdk = await import(\"@opencode-ai/sdk\");\n\t\tif (\n\t\t\ttypeof sdk.createOpencode !== \"function\" ||\n\t\t\ttypeof sdk.createOpencodeClient !== \"function\"\n\t\t) {\n\t\t\tthrow new OpenCodeSDKError(\"SDK missing required exports\");\n\t\t}\n\t\tcachedCreateOpencode = sdk.createOpencode as CreateOpencodeFn;\n\t\tcachedCreateOpencodeClient = sdk.createOpencodeClient as CreateOpencodeClientFn;\n\t\treturn {\n\t\t\tcreateOpencode: cachedCreateOpencode,\n\t\t\tcreateOpencodeClient: cachedCreateOpencodeClient,\n\t\t};\n\t} catch (error) {\n\t\tif (error instanceof OpenCodeSDKError) {\n\t\t\tthrow error;\n\t\t}\n\t\tthrow new OpenCodeSDKError();\n\t}\n}\n\ninterface ToolRunningState {\n\tstatus: \"running\";\n\ttitle?: string;\n\tinput?: unknown;\n}\n\nfunction formatToolMessage(tool: string | undefined, state: ToolRunningState): string | null {\n\tif (state.title) {\n\t\treturn state.title;\n\t}\n\n\tif (!tool) {\n\t\treturn null;\n\t}\n\n\tconst input =\n\t\tstate.input && typeof state.input === \"object\" && !Array.isArray(state.input)\n\t\t\t? (state.input as Record<string, unknown>)\n\t\t\t: undefined;\n\tif (!input) {\n\t\treturn `Running ${tool}...`;\n\t}\n\n\tswitch (tool) {\n\t\tcase \"read\": {\n\t\t\tconst path = input.filePath ?? input.path;\n\t\t\tif (typeof path === \"string\") {\n\t\t\t\tconst filename = path.split(\"/\").pop();\n\t\t\t\treturn `Reading ${filename}...`;\n\t\t\t}\n\t\t\treturn \"Reading file...\";\n\t\t}\n\t\tcase \"glob\": {\n\t\t\tconst pattern = input.pattern;\n\t\t\tif (typeof pattern === \"string\") {\n\t\t\t\treturn `Globbing ${pattern}...`;\n\t\t\t}\n\t\t\treturn \"Searching files...\";\n\t\t}\n\t\tcase \"grep\": {\n\t\t\tconst pattern = input.pattern;\n\t\t\tif (typeof pattern === \"string\") {\n\t\t\t\tconst truncated = pattern.length > 30 ? `${pattern.slice(0, 30)}...` : pattern;\n\t\t\t\treturn `Searching for \"${truncated}\"...`;\n\t\t\t}\n\t\t\treturn \"Searching content...\";\n\t\t}\n\t\tcase \"list\": {\n\t\t\tconst path = input.path;\n\t\t\tif (typeof path === \"string\") {\n\t\t\t\treturn `Listing ${path}...`;\n\t\t\t}\n\t\t\treturn \"Listing directory...\";\n\t\t}\n\t\tdefault:\n\t\t\treturn `Running ${tool}...`;\n\t}\n}\n\nexport async function streamPrompt(options: StreamPromptOptions): Promise<StreamPromptResult> {\n\tconst {\n\t\tprompt,\n\t\tcwd,\n\t\tsystemPrompt,\n\t\tprovider: optProvider,\n\t\tmodel: optModel,\n\t\ttimeoutMs,\n\t\tonDebug,\n\t\tonStream,\n\t} = options;\n\n\tconst debug = onDebug ?? (() => {});\n\tconst stream = onStream ?? (() => {});\n\tconst startTime = Date.now();\n\n\tdebug(\"Loading OpenCode SDK...\");\n\tconst { createOpencode, createOpencodeClient } = await getOpenCodeSDK();\n\n\tconst maxAttempts = 10;\n\tlet server: OpenCodeServer | null = null;\n\tlet client: OpenCodeClient | null = null;\n\tlet port = 0;\n\n\tconst config: OpenCodeConfig = {\n\t\tplugin: [],\n\t\tmcp: {},\n\t\tinstructions: [],\n\t\tagent: {\n\t\t\tbuild: { disable: true },\n\t\t\tgeneral: { disable: true },\n\t\t\tplan: { disable: true },\n\t\t\texplore: { disable: true },\n\t\t\tanalyze: {\n\t\t\t\tprompt: [\n\t\t\t\t\t\"You are an expert at analyzing open source codebases and producing documentation.\",\n\t\t\t\t\t\"\",\n\t\t\t\t\t\"Your job is to read the codebase and produce structured output based on the user's request.\",\n\t\t\t\t\t\"Use glob to discover files, grep to search for patterns, and read to examine file contents.\",\n\t\t\t\t\t\"\",\n\t\t\t\t\t\"Guidelines:\",\n\t\t\t\t\t\"- Explore the codebase thoroughly before producing output\",\n\t\t\t\t\t\"- Focus on understanding architecture, key abstractions, and usage patterns\",\n\t\t\t\t\t\"- When asked for JSON output, respond with ONLY valid JSON - no markdown, no code blocks\",\n\t\t\t\t\t\"- When asked for prose, write clear and concise documentation\",\n\t\t\t\t\t\"- Always base your analysis on actual code you've read, never speculate\",\n\t\t\t\t].join(\"\\n\"),\n\t\t\t\tmode: \"primary\",\n\t\t\t\tdescription: \"Analyze open source codebases and produce summaries and reference files\",\n\t\t\t\ttools: {\n\t\t\t\t\tread: true,\n\t\t\t\t\tgrep: true,\n\t\t\t\t\tglob: true,\n\t\t\t\t\tlist: true,\n\t\t\t\t\twrite: false,\n\t\t\t\t\tbash: false,\n\t\t\t\t\tdelete: false,\n\t\t\t\t\tedit: false,\n\t\t\t\t\tpatch: false,\n\t\t\t\t\tpath: false,\n\t\t\t\t\ttodowrite: false,\n\t\t\t\t\ttodoread: false,\n\t\t\t\t\twebsearch: false,\n\t\t\t\t\twebfetch: false,\n\t\t\t\t\tcodesearch: false,\n\t\t\t\t\tskill: false,\n\t\t\t\t\ttask: false,\n\t\t\t\t\tmcp: false,\n\t\t\t\t\tquestion: false,\n\t\t\t\t\tplan_enter: false,\n\t\t\t\t\tplan_exit: false,\n\t\t\t\t},\n\t\t\t\tpermission: {\n\t\t\t\t\tedit: \"deny\",\n\t\t\t\t\tbash: \"deny\",\n\t\t\t\t\twebfetch: \"deny\",\n\t\t\t\t\texternal_directory: \"deny\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t};\n\n\tdebug(\"Starting embedded OpenCode server...\");\n\n\tfor (let attempt = 0; attempt < maxAttempts; attempt++) {\n\t\tport = Math.floor(Math.random() * 3000) + 3000;\n\t\ttry {\n\t\t\tconst result = await createOpencode({ port, cwd, config });\n\t\t\tserver = result.server;\n\t\t\tclient = createOpencodeClient({\n\t\t\t\tbaseUrl: `http://localhost:${port}`,\n\t\t\t\tdirectory: cwd,\n\t\t\t});\n\t\t\tdebug(`Server started on port ${port}`);\n\t\t\tbreak;\n\t\t} catch (err) {\n\t\t\tif (err instanceof Error && err.message?.includes(\"port\")) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthrow new ServerStartError(\"Failed to start OpenCode server\", port, err);\n\t\t}\n\t}\n\n\tif (!server || !client) {\n\t\tthrow new ServerStartError(\"Failed to start OpenCode server after all attempts\");\n\t}\n\n\tconst providerID = optProvider ?? DEFAULT_AI_PROVIDER;\n\tconst modelID = optModel ?? DEFAULT_AI_MODEL;\n\n\ttry {\n\t\tdebug(\"Creating session...\");\n\t\tconst sessionResult = await client.session.create();\n\t\tif (sessionResult.error) {\n\t\t\tthrow new SessionError(\"Failed to create session\", undefined, undefined, sessionResult.error);\n\t\t}\n\t\tconst sessionId = sessionResult.data.id;\n\t\tdebug(`Session created: ${sessionId}`);\n\n\t\tdebug(\"Validating provider and model...\");\n\t\tconst providerResult = await client.provider.list();\n\t\tif (providerResult.error) {\n\t\t\tthrow new OpenCodeReferenceError(\"Failed to fetch provider list\", providerResult.error);\n\t\t}\n\n\t\tconst { all: allProviders, connected: connectedProviders } = providerResult.data;\n\t\tconst allProviderIds = allProviders.map((p) => p.id);\n\n\t\tconst provider = allProviders.find((p) => p.id === providerID);\n\t\tif (!provider) {\n\t\t\tthrow new InvalidProviderError(providerID, allProviderIds);\n\t\t}\n\n\t\tif (!connectedProviders.includes(providerID)) {\n\t\t\tthrow new ProviderNotConnectedError(providerID, connectedProviders);\n\t\t}\n\n\t\tconst availableModelIds = Object.keys(provider.models);\n\t\tif (!provider.models[modelID]) {\n\t\t\tthrow new InvalidModelError(modelID, providerID, availableModelIds);\n\t\t}\n\n\t\tdebug(`Provider \"${providerID}\" and model \"${modelID}\" validated`);\n\n\t\tdebug(\"Subscribing to events...\");\n\t\tconst { stream: eventStream } = await client.event.subscribe();\n\n\t\tconst fullPrompt = systemPrompt\n\t\t\t? `${systemPrompt}\\n\\nAnalyzing codebase at: ${cwd}\\n\\n${prompt}`\n\t\t\t: `Analyzing codebase at: ${cwd}\\n\\n${prompt}`;\n\n\t\tdebug(\"Sending prompt...\");\n\t\tconst promptPromise = client.session.prompt({\n\t\t\tpath: { id: sessionId },\n\t\t\tbody: {\n\t\t\t\tagent: \"analyze\",\n\t\t\t\tparts: [{ type: \"text\", text: fullPrompt }],\n\t\t\t\tmodel: { providerID, modelID },\n\t\t\t},\n\t\t});\n\n\t\tconst textAccumulator = new TextAccumulator();\n\t\tdebug(\"Waiting for response...\");\n\n\t\tlet timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n\t\tconst processEvents = async (): Promise<string> => {\n\t\t\tfor await (const event of eventStream) {\n\t\t\t\tif (!isEventForSession(event, sessionId)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst parsed = parseStreamEvent(event);\n\n\t\t\t\tswitch (parsed.type) {\n\t\t\t\t\tcase \"message.part.updated\": {\n\t\t\t\t\t\tif (parsed.toolPart?.state) {\n\t\t\t\t\t\t\tconst { state, tool } = parsed.toolPart;\n\t\t\t\t\t\t\tif (state.status === \"running\") {\n\t\t\t\t\t\t\t\tconst message = formatToolMessage(tool, state);\n\t\t\t\t\t\t\t\tif (message) {\n\t\t\t\t\t\t\t\t\tdebug(message);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (parsed.textPart) {\n\t\t\t\t\t\t\tconst delta = textAccumulator.accumulatePart(parsed.textPart);\n\t\t\t\t\t\t\tif (!textAccumulator.hasReceivedText) {\n\t\t\t\t\t\t\t\tdebug(\"Writing reference...\");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (delta) {\n\t\t\t\t\t\t\t\tstream(delta);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tcase \"session.idle\": {\n\t\t\t\t\t\tif (parsed.props.sessionID === sessionId) {\n\t\t\t\t\t\t\tdebug(\"Response complete\");\n\t\t\t\t\t\t\treturn textAccumulator.getFullText();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tcase \"session.error\": {\n\t\t\t\t\t\tif (parsed.props.sessionID === sessionId) {\n\t\t\t\t\t\t\tconst errorName = parsed.error?.name ?? \"Unknown session error\";\n\t\t\t\t\t\t\tdebug(`Session error: ${JSON.stringify(parsed.props.error)}`);\n\t\t\t\t\t\t\tthrow new SessionError(errorName, sessionId, \"error\", parsed.props.error);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tcase \"unknown\":\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn textAccumulator.getFullText();\n\t\t};\n\n\t\tlet responseText: string;\n\t\tif (timeoutMs && timeoutMs > 0) {\n\t\t\tconst timeoutPromise = new Promise<never>((_, reject) => {\n\t\t\t\ttimeoutId = setTimeout(() => {\n\t\t\t\t\treject(new TimeoutError(timeoutMs, \"session response\"));\n\t\t\t\t}, timeoutMs);\n\t\t\t});\n\t\t\tresponseText = await Promise.race([processEvents(), timeoutPromise]);\n\t\t\tif (timeoutId) clearTimeout(timeoutId);\n\t\t} else {\n\t\t\tresponseText = await processEvents();\n\t\t}\n\n\t\tawait promptPromise;\n\n\t\tif (!responseText) {\n\t\t\tthrow new OpenCodeReferenceError(\"No response received from OpenCode\");\n\t\t}\n\n\t\tdebug(`Response received (${responseText.length} chars)`);\n\n\t\tconst durationMs = Date.now() - startTime;\n\t\tdebug(`Complete in ${durationMs}ms`);\n\n\t\treturn {\n\t\t\ttext: responseText,\n\t\t\tsessionId,\n\t\t\tdurationMs,\n\t\t};\n\t} finally {\n\t\tdebug(\"Closing server...\");\n\t\tserver.close();\n\t}\n}\n","/**\n * This module provides a streamlined approach to generating reference files\n * by delegating all codebase exploration to the AI agent via OpenCode.\n */\n\nimport { streamPrompt, type StreamPromptOptions } from \"./ai/opencode.js\";\nimport { loadConfig, toReferenceName } from \"./config.js\";\nimport { getCommitSha } from \"./clone.js\";\n\nexport interface GenerateReferenceOptions {\n\t/** AI provider ID (e.g., \"anthropic\", \"openai\"). Defaults to config value. */\n\tprovider?: string;\n\t/** AI model ID. Defaults to config value. */\n\tmodel?: string;\n\t/** Debug callback for detailed logging */\n\tonDebug?: (message: string) => void;\n\t/** Stream callback for real-time AI output */\n\tonStream?: (text: string) => void;\n}\n\nexport interface GenerateReferenceResult {\n\t/** The generated reference markdown content */\n\treferenceContent: string;\n\t/** The commit SHA at the time of generation */\n\tcommitSha: string;\n}\n\nfunction createReferenceGenerationPrompt(referenceName: string): string {\n\treturn `You are an expert at analyzing open source libraries and producing reference documentation for AI coding agents.\n\n## PRIMARY GOAL\n\nGenerate a reference markdown file that helps developers USE this library effectively. This is NOT a contribution guide - it's a usage reference for developers consuming this library in their own projects.\n\n## CRITICAL RULES\n\n1. **USER PERSPECTIVE ONLY**: Write for developers who will npm/pip/cargo install this library and use it in THEIR code.\n - DO NOT include: how to contribute, internal test commands, repo-specific policies\n - DO NOT include: \"never mock in tests\" or similar internal dev guidelines\n - DO NOT include: commands like \"npx hereby\", \"just ready\", \"bun test\" that run the library's own tests\n - DO include: how to install, import, configure, and use the public API\n\n2. **NO FRONTMATTER**: Output pure markdown with NO YAML frontmatter. Start directly with the library name heading.\n\n3. **QUICK REFERENCES**: Include a \"Quick References\" section with paths to key entry points in the repo:\n - Paths must be relative from repo root (e.g., \\`src/index.ts\\`, \\`docs/api.md\\`)\n - Include: main entry point, type definitions, README, key docs\n - DO NOT include absolute paths or user-specific paths\n - Keep to 3-5 most important files that help users understand the library\n\n4. **PUBLIC API FOCUS**: Document what users import and call, not internal implementation details.\n - Entry points: what to import from the package\n - Configuration: how to set up/initialize\n - Core methods/functions: the main API surface\n - Types: key TypeScript interfaces users need\n\n5. **MONOREPO AWARENESS**: Many libraries are monorepos with multiple packages:\n - Check for \\`packages/\\`, \\`apps/\\`, \\`crates/\\`, or \\`libs/\\` directories\n - Check root package.json for \\`workspaces\\` field\n - If monorepo: document the package structure and key packages users would install\n - Use full paths from repo root (e.g., \\`packages/core/src/index.ts\\`)\n - Identify which packages are publishable vs internal\n\n## EXPLORATION STEPS\n\nUse Read, Grep, Glob tools to explore:\n1. Root package.json / Cargo.toml - check for workspaces/monorepo config\n2. Check for \\`packages/\\`, \\`apps/\\`, \\`crates/\\` directories\n3. README.md - official usage documentation\n4. For monorepos: explore each publishable package's entry point\n5. docs/ or website/ - find documentation\n6. examples/ - real usage patterns\n7. TypeScript definitions (.d.ts) - public API surface\n\n## OUTPUT FORMAT\n\nIMPORTANT: Reference name is \"${referenceName}\" (for internal tracking only - do NOT include in output).\n\n\\`\\`\\`markdown\n# {Library Name}\n\n{2-3 sentence overview of what this library does and its key value proposition}\n\n## Quick References\n\n| File | Purpose |\n|------|---------|\n| \\`packages/{pkg}/src/index.ts\\` | Main entry point (monorepo example) |\n| \\`src/index.ts\\` | Main entry point (single-package example) |\n| \\`README.md\\` | Documentation |\n\n(For monorepos, include paths to key publishable packages)\n\n## Packages (for monorepos only)\n\n| Package | npm name | Description |\n|---------|----------|-------------|\n| \\`packages/core\\` | \\`@scope/core\\` | Core functionality |\n| \\`packages/react\\` | \\`@scope/react\\` | React bindings |\n\n(OMIT this section for single-package repos)\n\n## When to Use\n\n- {Practical scenario where a developer would reach for this library}\n- {Another real-world use case}\n- {Problem this library solves}\n\n## Installation\n\n\\`\\`\\`bash\n# Single package\nnpm install {package-name}\n\n# Monorepo (show key packages)\nnpm install @scope/core @scope/react\n\\`\\`\\`\n\n## Best Practices\n\n1. {Actionable best practice for USERS of this library}\n2. {Common mistake to avoid when using this library}\n3. {Performance or correctness tip}\n\n## Common Patterns\n\n**{Pattern Name}:**\n\\`\\`\\`{language}\n{Minimal working code example}\n\\`\\`\\`\n\n**{Another Pattern}:**\n\\`\\`\\`{language}\n{Another code example}\n\\`\\`\\`\n\n## API Quick Reference\n\n| Export | Type | Description |\n|--------|------|-------------|\n| \\`{main export}\\` | {type} | {what it does} |\n| \\`{another export}\\` | {type} | {what it does} |\n\n{Add more sections as appropriate for the library: Configuration, Types, CLI Commands (if user-facing), etc.}\n\\`\\`\\`\n\n## QUALITY CHECKLIST\n\nBefore outputting, verify:\n- [ ] NO YAML frontmatter - start directly with # heading\n- [ ] Every code example is something a USER would write, not a contributor\n- [ ] No internal test commands or contribution workflows\n- [ ] Quick References paths are relative from repo root (no absolute/user paths)\n- [ ] Best practices are for using the library, not developing it\n- [ ] If monorepo: Packages section lists publishable packages with npm names\n- [ ] If monorepo: paths include package directory (e.g., \\`packages/core/src/index.ts\\`)\n\nNow explore the codebase and generate the reference content.\n\n## OUTPUT INSTRUCTIONS\n\nAfter exploring, output your complete reference wrapped in XML tags like this:\n\n\\`\\`\\`\n<reference_output>\n(your complete markdown reference here)\n</reference_output>\n\\`\\`\\`\n\nREQUIREMENTS:\n- Start with a level-1 heading with the actual library name (e.g., \"# TanStack Query\")\n- Include sections: Quick References (table), When to Use (bullets), Installation, Best Practices, Common Patterns (with code), API Quick Reference (table)\n- Minimum 2000 characters of actual content - short or placeholder content will be rejected\n- Fill in real information from your exploration - do not use placeholder text like \"{Library Name}\"\n- No YAML frontmatter - start directly with the markdown heading\n- Output ONLY the reference inside the tags, no other text\n\nBegin exploring now.`;\n}\n\n/**\n * Extract the actual reference markdown content from AI response.\n * The response may include echoed prompt/system context before the actual reference.\n * Handles multiple edge cases:\n * - Model echoes the prompt template (skip template content)\n * - Model forgets to close the tag (extract to end of response)\n * - Multiple tag pairs (find the one with real content)\n */\nfunction extractReferenceContent(rawResponse: string, onDebug?: (message: string) => void): string {\n\tconst openTag = \"<reference_output>\";\n\tconst closeTag = \"</reference_output>\";\n\n\tonDebug?.(`[extract] Raw response length: ${rawResponse.length} chars`);\n\n\t// Find all occurrences of open and close tags\n\tconst openIndices: number[] = [];\n\tconst closeIndices: number[] = [];\n\tlet pos = 0;\n\twhile ((pos = rawResponse.indexOf(openTag, pos)) !== -1) {\n\t\topenIndices.push(pos);\n\t\tpos += openTag.length;\n\t}\n\tpos = 0;\n\twhile ((pos = rawResponse.indexOf(closeTag, pos)) !== -1) {\n\t\tcloseIndices.push(pos);\n\t\tpos += closeTag.length;\n\t}\n\n\tonDebug?.(\n\t\t`[extract] Found ${openIndices.length} open tag(s), ${closeIndices.length} close tag(s)`,\n\t);\n\n\t// Helper to clean content (strip markdown fences)\n\tconst cleanContent = (raw: string): string => {\n\t\tlet content = raw.trim();\n\t\tif (content.startsWith(\"```\")) {\n\t\t\tcontent = content.replace(/^```(?:markdown)?\\s*\\n?/, \"\");\n\t\t\tcontent = content.replace(/\\n?```\\s*$/, \"\");\n\t\t}\n\t\treturn content.trim();\n\t};\n\n\t// Helper to check if content is template placeholder\n\tconst isTemplateContent = (content: string): boolean => {\n\t\treturn (\n\t\t\tcontent.includes(\"{Library Name}\") ||\n\t\t\tcontent.includes(\"(your complete markdown reference here)\")\n\t\t);\n\t};\n\n\t// Strategy 1: Find properly paired tags, starting from the LAST open tag\n\t// (Last is more likely to be actual output, not echoed prompt)\n\tfor (let i = openIndices.length - 1; i >= 0; i--) {\n\t\tconst openIdx = openIndices[i];\n\t\tif (openIdx === undefined) continue;\n\n\t\t// Find the first close tag after this open tag\n\t\tconst closeIdx = closeIndices.find((c) => c > openIdx);\n\t\tif (closeIdx !== undefined) {\n\t\t\tconst rawContent = rawResponse.slice(openIdx + openTag.length, closeIdx);\n\t\t\tconst content = cleanContent(rawContent);\n\n\t\t\tonDebug?.(`[extract] Pair ${i}: open=${openIdx}, close=${closeIdx}, len=${content.length}`);\n\t\t\tonDebug?.(\n\t\t\t\t`[extract] Preview: \"${content.slice(0, 200)}${content.length > 200 ? \"...\" : \"\"}\"`,\n\t\t\t);\n\n\t\t\tif (isTemplateContent(content)) {\n\t\t\t\tonDebug?.(`[extract] Skipping pair ${i} - template placeholder content`);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (content.length >= 500) {\n\t\t\t\tonDebug?.(`[extract] Using pair ${i} - valid content`);\n\t\t\t\tvalidateReferenceContent(content);\n\t\t\t\treturn content;\n\t\t\t}\n\t\t\tonDebug?.(`[extract] Pair ${i} too short (${content.length} chars)`);\n\t\t}\n\t}\n\n\t// Strategy 2: Handle unclosed tag - model output <reference_output> but never closed it\n\t// Find the last open tag that has no close tag after it\n\tconst lastOpenIdx = openIndices[openIndices.length - 1];\n\tif (lastOpenIdx !== undefined) {\n\t\tconst hasCloseAfter = closeIndices.some((c) => c > lastOpenIdx);\n\t\tif (!hasCloseAfter) {\n\t\t\tonDebug?.(`[extract] Last open tag at ${lastOpenIdx} is unclosed - extracting to end`);\n\t\t\tconst rawContent = rawResponse.slice(lastOpenIdx + openTag.length);\n\t\t\tconst content = cleanContent(rawContent);\n\n\t\t\tonDebug?.(`[extract] Unclosed content: ${content.length} chars`);\n\t\t\tonDebug?.(\n\t\t\t\t`[extract] Preview: \"${content.slice(0, 200)}${content.length > 200 ? \"...\" : \"\"}\"`,\n\t\t\t);\n\n\t\t\tif (!isTemplateContent(content) && content.length >= 500) {\n\t\t\t\tonDebug?.(`[extract] Using unclosed content - valid`);\n\t\t\t\tvalidateReferenceContent(content);\n\t\t\t\treturn content;\n\t\t\t}\n\t\t}\n\t}\n\n\tonDebug?.(`[extract] No valid content found`);\n\tonDebug?.(`[extract] Response tail: \"${rawResponse.slice(-300)}\"`);\n\n\tthrow new Error(\n\t\t\"Failed to extract reference content: no valid <reference_output> tags found. \" +\n\t\t\t\"The AI may have failed to follow the output format or produced placeholder content.\",\n\t);\n}\n\n/**\n * Validate extracted reference content has minimum required structure.\n * Throws if content is invalid.\n */\nfunction validateReferenceContent(content: string): void {\n\t// Check for template placeholders that indicate the model just echoed the format\n\tconst templatePlaceholders = [\n\t\t\"{Library Name}\",\n\t\t\"{Full overview paragraph}\",\n\t\t\"{Table with 3-5 key files}\",\n\t\t\"{3+ bullet points}\",\n\t\t\"{Install commands}\",\n\t\t\"{3+ numbered items}\",\n\t\t\"{2+ code examples\",\n\t\t\"{Table of key exports}\",\n\t\t\"{Additional sections\",\n\t];\n\n\tconst foundPlaceholders = templatePlaceholders.filter((p) => content.includes(p));\n\tif (foundPlaceholders.length > 0) {\n\t\tthrow new Error(\n\t\t\t`Invalid reference content: contains template placeholders (${foundPlaceholders.slice(0, 3).join(\", \")}). ` +\n\t\t\t\t\"The AI echoed the format instead of generating actual content.\",\n\t\t);\n\t}\n\n\tif (content.length < 500) {\n\t\tthrow new Error(\n\t\t\t`Invalid reference content: too short (${content.length} chars, minimum 500). ` +\n\t\t\t\t\"The AI may have produced placeholder or incomplete content.\",\n\t\t);\n\t}\n\n\tif (!content.startsWith(\"#\")) {\n\t\tthrow new Error(\n\t\t\t\"Invalid reference content: must start with markdown heading. \" +\n\t\t\t\t\"Content must begin with '# Library Name' (no YAML frontmatter).\",\n\t\t);\n\t}\n}\n\n/**\n * Generate a reference markdown file for a repository using AI.\n *\n * Opens an OpenCode session and instructs the AI agent to explore the codebase\n * using Read, Grep, and Glob tools, then produce a comprehensive reference.\n *\n * @param repoPath - Path to the repository to analyze\n * @param repoName - Qualified name of the repo (e.g., \"tanstack/query\" or \"my-local-repo\")\n * @param options - Generation options (provider, model, callbacks)\n * @returns The generated reference content and commit SHA\n */\nexport async function generateReferenceWithAI(\n\trepoPath: string,\n\trepoName: string,\n\toptions: GenerateReferenceOptions = {},\n): Promise<GenerateReferenceResult> {\n\tconst { provider, model, onDebug, onStream } = options;\n\tconst config = loadConfig();\n\n\tconst [configProvider, configModel] = config.defaultModel?.split(\"/\") ?? [];\n\tconst aiProvider = provider ?? configProvider;\n\tconst aiModel = model ?? configModel;\n\n\tonDebug?.(`Starting AI reference generation for ${repoName}`);\n\tonDebug?.(`Repo path: ${repoPath}`);\n\tonDebug?.(`Provider: ${aiProvider ?? \"default\"}, Model: ${aiModel ?? \"default\"}`);\n\n\tconst commitSha = getCommitSha(repoPath);\n\tonDebug?.(`Commit SHA: ${commitSha}`);\n\n\tconst referenceName = toReferenceName(repoName);\n\tonDebug?.(`Reference name: ${referenceName}`);\n\n\tconst promptOptions: StreamPromptOptions = {\n\t\tprompt: createReferenceGenerationPrompt(referenceName),\n\t\tcwd: repoPath,\n\t\tprovider: aiProvider,\n\t\tmodel: aiModel,\n\t\tonDebug,\n\t\tonStream,\n\t};\n\n\tconst result = await streamPrompt(promptOptions);\n\n\tonDebug?.(`Generation complete (${result.durationMs}ms, ${result.text.length} chars)`);\n\n\tconst referenceContent = extractReferenceContent(result.text, onDebug);\n\tonDebug?.(`Extracted reference content (${referenceContent.length} chars)`);\n\n\treturn {\n\t\treferenceContent,\n\t\tcommitSha,\n\t};\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/ai/errors.ts","../../src/ai/stream/types.ts","../../src/ai/stream/accumulator.ts","../../src/ai/stream/transformer.ts","../../src/ai/opencode.ts","../../src/generate.ts"],"sourcesContent":["/**\n * Base class for OpenCode reference errors\n */\nexport class OpenCodeReferenceError extends Error {\n\treadonly _tag: string = \"OpenCodeReferenceError\";\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic readonly details?: unknown,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"OpenCodeReferenceError\";\n\t}\n}\n\n/**\n * Error when the opencode CLI binary is not installed\n */\nexport class OpenCodeNotInstalledError extends OpenCodeReferenceError {\n\treadonly _tag = \"OpenCodeNotInstalledError\" as const;\n\treadonly hint: string;\n\n\tconstructor() {\n\t\tconst hint =\n\t\t\t\"opencode is required for local AI reference generation. Install it: curl -fsSL https://opencode.ai/install | bash\";\n\t\tsuper(`opencode is not installed. ${hint}`);\n\t\tthis.name = \"OpenCodeNotInstalledError\";\n\t\tthis.hint = hint;\n\t}\n}\n\n/**\n * Error when the @opencode-ai/sdk package is not installed or invalid\n */\nexport class OpenCodeSDKError extends OpenCodeReferenceError {\n\treadonly _tag = \"OpenCodeSDKError\" as const;\n\tconstructor(message?: string) {\n\t\tsuper(\n\t\t\tmessage ?? \"Failed to import @opencode-ai/sdk. Install it with: bun add @opencode-ai/sdk\",\n\t\t);\n\t\tthis.name = \"OpenCodeSDKError\";\n\t}\n}\n\n/**\n * Error when the requested provider is not found\n */\nexport class InvalidProviderError extends OpenCodeReferenceError {\n\treadonly _tag = \"InvalidProviderError\" as const;\n\treadonly hint: string;\n\n\tconstructor(\n\t\tpublic readonly providerID: string,\n\t\tpublic readonly availableProviders: string[],\n\t) {\n\t\tconst hint =\n\t\t\tavailableProviders.length > 0\n\t\t\t\t? `Available providers: ${availableProviders.join(\", \")}`\n\t\t\t\t: \"No providers available. Check your OpenCode configuration.\";\n\t\tsuper(`Provider \"${providerID}\" not found. ${hint}`);\n\t\tthis.name = \"InvalidProviderError\";\n\t\tthis.hint = hint;\n\t}\n}\n\n/**\n * Error when the provider exists but is not connected/authenticated\n */\nexport class ProviderNotConnectedError extends OpenCodeReferenceError {\n\treadonly _tag = \"ProviderNotConnectedError\" as const;\n\treadonly hint: string;\n\n\tconstructor(\n\t\tpublic readonly providerID: string,\n\t\tpublic readonly connectedProviders: string[],\n\t) {\n\t\tconst hint =\n\t\t\tconnectedProviders.length > 0\n\t\t\t\t? `Connected providers: ${connectedProviders.join(\", \")}. Run 'opencode auth ${providerID}' to connect.`\n\t\t\t\t: `No providers connected. Run 'opencode auth ${providerID}' to authenticate.`;\n\t\tsuper(`Provider \"${providerID}\" is not connected. ${hint}`);\n\t\tthis.name = \"ProviderNotConnectedError\";\n\t\tthis.hint = hint;\n\t}\n}\n\n/**\n * Error when the requested model is not found for a provider\n */\nexport class InvalidModelError extends OpenCodeReferenceError {\n\treadonly _tag = \"InvalidModelError\" as const;\n\treadonly hint: string;\n\n\tconstructor(\n\t\tpublic readonly modelID: string,\n\t\tpublic readonly providerID: string,\n\t\tpublic readonly availableModels: string[],\n\t) {\n\t\tconst hint =\n\t\t\tavailableModels.length > 0\n\t\t\t\t? `Available models for ${providerID}: ${availableModels.slice(0, 10).join(\", \")}${availableModels.length > 10 ? ` (and ${availableModels.length - 10} more)` : \"\"}`\n\t\t\t\t: `No models available for provider \"${providerID}\".`;\n\t\tsuper(`Model \"${modelID}\" not found for provider \"${providerID}\". ${hint}`);\n\t\tthis.name = \"InvalidModelError\";\n\t\tthis.hint = hint;\n\t}\n}\n\n/**\n * Error when the OpenCode server fails to start\n */\nexport class ServerStartError extends OpenCodeReferenceError {\n\treadonly _tag = \"ServerStartError\" as const;\n\treadonly hint: string;\n\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic readonly port?: number,\n\t\tdetails?: unknown,\n\t) {\n\t\tconst hint = port\n\t\t\t? `Failed to start server on port ${port}. Ensure no other process is using this port.`\n\t\t\t: \"Failed to start OpenCode server. Check your OpenCode installation and configuration.\";\n\t\tsuper(`${message}. ${hint}`, details);\n\t\tthis.name = \"ServerStartError\";\n\t\tthis.hint = hint;\n\t}\n}\n\n/**\n * Error when a session operation fails\n */\nexport class SessionError extends OpenCodeReferenceError {\n\treadonly _tag = \"SessionError\" as const;\n\treadonly hint: string;\n\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic readonly sessionId?: string,\n\t\tpublic readonly sessionState?: string,\n\t\tdetails?: unknown,\n\t) {\n\t\tconst context = sessionId ? ` (session: ${sessionId})` : \"\";\n\t\tconst stateInfo = sessionState ? ` State: ${sessionState}.` : \"\";\n\t\tconst hint = `Session operation failed${context}.${stateInfo} Try creating a new session.`;\n\t\tsuper(`${message}. ${hint}`, details);\n\t\tthis.name = \"SessionError\";\n\t\tthis.hint = hint;\n\t}\n}\n\n/**\n * Error when a request times out\n */\nexport class TimeoutError extends OpenCodeReferenceError {\n\treadonly _tag = \"TimeoutError\" as const;\n\treadonly hint: string;\n\n\tconstructor(\n\t\tpublic readonly timeoutMs: number,\n\t\tpublic readonly operation: string = \"operation\",\n\t) {\n\t\tconst hint = `The ${operation} did not complete within ${timeoutMs}ms. Consider increasing the timeout or checking if the model is responding.`;\n\t\tsuper(`Timeout: ${operation} did not complete within ${timeoutMs}ms. ${hint}`);\n\t\tthis.name = \"TimeoutError\";\n\t\tthis.hint = hint;\n\t}\n}\n","/**\n * Zod schemas for OpenCode stream events\n * Replaces inline `as` casts with runtime-validated types\n */\n\nimport { z } from \"zod\";\n\nconst PartBaseSchema = z.object({\n\tid: z.string().optional(),\n\tsessionID: z.string().optional(),\n\tmessageID: z.string().optional(),\n});\n\nexport const TextPartSchema = PartBaseSchema.extend({\n\ttype: z.literal(\"text\"),\n\ttext: z.string().optional(),\n});\n\nexport const ToolStatePendingSchema = z.object({\n\tstatus: z.literal(\"pending\"),\n});\n\nexport const ToolStateRunningSchema = z.object({\n\tstatus: z.literal(\"running\"),\n\ttitle: z.string().optional(),\n\tinput: z.unknown().optional(),\n\tmetadata: z.record(z.string(), z.unknown()).optional(),\n\ttime: z\n\t\t.object({\n\t\t\tstart: z.number(),\n\t\t})\n\t\t.optional(),\n});\n\nexport const ToolStateCompletedSchema = z.object({\n\tstatus: z.literal(\"completed\"),\n\ttitle: z.string().optional(),\n\tinput: z.record(z.string(), z.unknown()).optional(),\n\toutput: z.string().optional(),\n\tmetadata: z.record(z.string(), z.unknown()).optional(),\n\ttime: z\n\t\t.object({\n\t\t\tstart: z.number(),\n\t\t\tend: z.number(),\n\t\t})\n\t\t.optional(),\n});\n\nexport const ToolStateErrorSchema = z.object({\n\tstatus: z.literal(\"error\"),\n\terror: z.string().optional(),\n\tinput: z.record(z.string(), z.unknown()).optional(),\n\ttime: z\n\t\t.object({\n\t\t\tstart: z.number(),\n\t\t\tend: z.number(),\n\t\t})\n\t\t.optional(),\n});\n\nexport const ToolStateSchema = z.discriminatedUnion(\"status\", [\n\tToolStatePendingSchema,\n\tToolStateRunningSchema,\n\tToolStateCompletedSchema,\n\tToolStateErrorSchema,\n]);\n\nexport const ToolPartSchema = PartBaseSchema.extend({\n\ttype: z.literal(\"tool\"),\n\tcallID: z.string().optional(),\n\ttool: z.string().optional(),\n\tstate: ToolStateSchema.optional(),\n});\n\nexport const StepStartPartSchema = PartBaseSchema.extend({\n\ttype: z.literal(\"step-start\"),\n});\n\nexport const StepFinishPartSchema = PartBaseSchema.extend({\n\ttype: z.literal(\"step-finish\"),\n\treason: z.string().optional(),\n});\n\nexport const ToolUsePartSchema = PartBaseSchema.extend({\n\ttype: z.literal(\"tool-use\"),\n\ttoolUseId: z.string().optional(),\n\tname: z.string().optional(),\n});\n\nexport const ToolResultPartSchema = PartBaseSchema.extend({\n\ttype: z.literal(\"tool-result\"),\n\ttoolUseId: z.string().optional(),\n});\n\nexport const MessagePartSchema = z.discriminatedUnion(\"type\", [\n\tTextPartSchema,\n\tToolPartSchema,\n\tStepStartPartSchema,\n\tStepFinishPartSchema,\n\tToolUsePartSchema,\n\tToolResultPartSchema,\n]);\n\n/**\n * Session error payload\n */\nexport const SessionErrorSchema = z.object({\n\tname: z.string().optional(),\n\tmessage: z.string().optional(),\n\tcode: z.string().optional(),\n});\n\nexport const MessagePartUpdatedPropsSchema = z.object({\n\tpart: MessagePartSchema,\n});\n\n/**\n * Properties for session.idle event\n */\nexport const SessionIdlePropsSchema = z.object({\n\tsessionID: z.string(),\n});\n\n/**\n * Properties for session.error event\n */\nexport const SessionErrorPropsSchema = z.object({\n\tsessionID: z.string(),\n\terror: SessionErrorSchema.optional(),\n});\n\n/**\n * Properties for session.updated event\n */\nexport const SessionUpdatedPropsSchema = z.object({\n\tsessionID: z.string(),\n\tstatus: z.string().optional(),\n});\n\n/**\n * message.part.updated event\n */\nexport const MessagePartUpdatedEventSchema = z.object({\n\ttype: z.literal(\"message.part.updated\"),\n\tproperties: MessagePartUpdatedPropsSchema,\n});\n\n/**\n * session.idle event\n */\nexport const SessionIdleEventSchema = z.object({\n\ttype: z.literal(\"session.idle\"),\n\tproperties: SessionIdlePropsSchema,\n});\n\n/**\n * session.error event\n */\nexport const SessionErrorEventSchema = z.object({\n\ttype: z.literal(\"session.error\"),\n\tproperties: SessionErrorPropsSchema,\n});\n\n/**\n * session.updated event\n */\nexport const SessionUpdatedEventSchema = z.object({\n\ttype: z.literal(\"session.updated\"),\n\tproperties: SessionUpdatedPropsSchema,\n});\n\n/**\n * Generic event for unknown types (passthrough)\n */\nexport const GenericEventSchema = z.object({\n\ttype: z.string(),\n\tproperties: z.record(z.string(), z.unknown()),\n});\n\nexport type TextPart = z.infer<typeof TextPartSchema>;\nexport type ToolPart = z.infer<typeof ToolPartSchema>;\nexport type ToolState = z.infer<typeof ToolStateSchema>;\nexport type ToolStateRunning = z.infer<typeof ToolStateRunningSchema>;\nexport type ToolUsePart = z.infer<typeof ToolUsePartSchema>;\nexport type ToolResultPart = z.infer<typeof ToolResultPartSchema>;\nexport type MessagePart = z.infer<typeof MessagePartSchema>;\n\nexport type SessionErrorPayload = z.infer<typeof SessionErrorSchema>;\n\nexport type MessagePartUpdatedProps = z.infer<typeof MessagePartUpdatedPropsSchema>;\nexport type SessionIdleProps = z.infer<typeof SessionIdlePropsSchema>;\nexport type SessionErrorProps = z.infer<typeof SessionErrorPropsSchema>;\nexport type SessionUpdatedProps = z.infer<typeof SessionUpdatedPropsSchema>;\n\nexport type MessagePartUpdatedEvent = z.infer<typeof MessagePartUpdatedEventSchema>;\nexport type SessionIdleEvent = z.infer<typeof SessionIdleEventSchema>;\nexport type SessionErrorEvent = z.infer<typeof SessionErrorEventSchema>;\nexport type SessionUpdatedEvent = z.infer<typeof SessionUpdatedEventSchema>;\nexport type GenericEvent = z.infer<typeof GenericEventSchema>;\n\n/**\n * All known stream event types\n */\nexport type StreamEvent =\n\t| MessagePartUpdatedEvent\n\t| SessionIdleEvent\n\t| SessionErrorEvent\n\t| SessionUpdatedEvent\n\t| GenericEvent;\n","/**\n * Text accumulator for stream events\n * Manages accumulation of text parts by ID and provides delta extraction\n */\n\nimport type { TextPart } from \"./types.js\";\n\n/**\n * Accumulates text from streaming message parts.\n * Tracks multiple parts by ID and provides delta text between updates.\n */\nexport class TextAccumulator {\n\tprivate readonly parts = new Map<string, string>();\n\tprivate _firstTextReceived = false;\n\n\t/**\n\t * Whether any text has been received\n\t */\n\tget hasReceivedText(): boolean {\n\t\treturn this._firstTextReceived;\n\t}\n\n\t/**\n\t * Accumulate text from a message part and return the delta (new text only).\n\t * Returns null if the part should be skipped (non-text, no ID, no text).\n\t */\n\taccumulatePart(part: TextPart): string | null {\n\t\tif (part.type !== \"text\" || !part.text || !part.id) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst partId = part.id;\n\t\tconst prevText = this.parts.get(partId) ?? \"\";\n\t\tthis.parts.set(partId, part.text);\n\n\t\tif (!this._firstTextReceived) {\n\t\t\tthis._firstTextReceived = true;\n\t\t}\n\n\t\tif (part.text.length > prevText.length) {\n\t\t\treturn part.text.slice(prevText.length);\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Get the full accumulated text from all parts\n\t */\n\tgetFullText(): string {\n\t\treturn Array.from(this.parts.values()).join(\"\");\n\t}\n\n\t/**\n\t * Get the number of distinct parts accumulated\n\t */\n\tgetPartCount(): number {\n\t\treturn this.parts.size;\n\t}\n\n\t/**\n\t * Get info about each part for debugging\n\t */\n\tgetPartInfo(): Array<{ id: string; length: number }> {\n\t\treturn Array.from(this.parts.entries()).map(([id, text]) => ({\n\t\t\tid,\n\t\t\tlength: text.length,\n\t\t}));\n\t}\n\n\t/**\n\t * Clear accumulated text\n\t */\n\tclear(): void {\n\t\tthis.parts.clear();\n\t\tthis._firstTextReceived = false;\n\t}\n}\n","/**\n * Stream event transformer and parser\n * Safely parses and validates stream events using Zod schemas\n */\n\nimport {\n\tMessagePartUpdatedPropsSchema,\n\tSessionIdlePropsSchema,\n\tSessionErrorPropsSchema,\n\tSessionErrorSchema,\n\ttype TextPart,\n\ttype ToolPart,\n\ttype SessionErrorPayload,\n\ttype MessagePartUpdatedProps,\n\ttype SessionIdleProps,\n\ttype SessionErrorProps,\n} from \"./types.js\";\n\n/**\n * Raw event from the OpenCode SDK stream\n */\nexport interface RawStreamEvent {\n\ttype: string;\n\tproperties: Record<string, unknown>;\n}\n\n/**\n * Result of parsing a stream event\n */\nexport type ParsedEventResult =\n\t| {\n\t\t\ttype: \"message.part.updated\";\n\t\t\tprops: MessagePartUpdatedProps;\n\t\t\ttextPart: TextPart | null;\n\t\t\ttoolPart: ToolPart | null;\n\t }\n\t| { type: \"session.idle\"; props: SessionIdleProps }\n\t| { type: \"session.error\"; props: SessionErrorProps; error: SessionErrorPayload | null }\n\t| { type: \"unknown\"; rawType: string };\n\n/**\n * Parse a raw stream event into a typed result.\n * Uses safe parsing - returns type: \"unknown\" for unrecognized or invalid events.\n */\nexport function parseStreamEvent(event: RawStreamEvent): ParsedEventResult {\n\tswitch (event.type) {\n\t\tcase \"message.part.updated\": {\n\t\t\tconst propsResult = MessagePartUpdatedPropsSchema.safeParse(event.properties);\n\t\t\tif (!propsResult.success) {\n\t\t\t\treturn { type: \"unknown\", rawType: event.type };\n\t\t\t}\n\t\t\tconst props = propsResult.data;\n\t\t\tconst textPart = props.part.type === \"text\" ? props.part : null;\n\t\t\tconst toolPart = props.part.type === \"tool\" ? props.part : null;\n\t\t\treturn { type: \"message.part.updated\", props, textPart, toolPart };\n\t\t}\n\n\t\tcase \"session.idle\": {\n\t\t\tconst propsResult = SessionIdlePropsSchema.safeParse(event.properties);\n\t\t\tif (!propsResult.success) {\n\t\t\t\treturn { type: \"unknown\", rawType: event.type };\n\t\t\t}\n\t\t\treturn { type: \"session.idle\", props: propsResult.data };\n\t\t}\n\n\t\tcase \"session.error\": {\n\t\t\tconst propsResult = SessionErrorPropsSchema.safeParse(event.properties);\n\t\t\tif (!propsResult.success) {\n\t\t\t\treturn { type: \"unknown\", rawType: event.type };\n\t\t\t}\n\t\t\tconst props = propsResult.data;\n\n\t\t\tlet error: SessionErrorPayload | null = null;\n\t\t\tif (props.error) {\n\t\t\t\tconst errorResult = SessionErrorSchema.safeParse(props.error);\n\t\t\t\tif (errorResult.success) {\n\t\t\t\t\terror = errorResult.data;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn { type: \"session.error\", props, error };\n\t\t}\n\n\t\tdefault:\n\t\t\treturn { type: \"unknown\", rawType: event.type };\n\t}\n}\n\nexport function isEventForSession(event: RawStreamEvent, sessionId: string): boolean {\n\tconst props = event.properties;\n\tif (\"sessionID\" in props && typeof props.sessionID === \"string\") {\n\t\treturn props.sessionID === sessionId;\n\t}\n\tif (\n\t\t\"part\" in props &&\n\t\ttypeof props.part === \"object\" &&\n\t\tprops.part !== null &&\n\t\t\"sessionID\" in props.part &&\n\t\ttypeof props.part.sessionID === \"string\"\n\t) {\n\t\treturn props.part.sessionID === sessionId;\n\t}\n\treturn true;\n}\n","import { execSync } from \"node:child_process\";\nimport {\n\tOpenCodeReferenceError,\n\tOpenCodeSDKError,\n\tOpenCodeNotInstalledError,\n\tInvalidProviderError,\n\tProviderNotConnectedError,\n\tInvalidModelError,\n\tServerStartError,\n\tSessionError,\n\tTimeoutError,\n} from \"./errors.js\";\nimport { TextAccumulator, parseStreamEvent, isEventForSession } from \"./stream/index.js\";\n\nexport const DEFAULT_AI_PROVIDER = \"opencode\";\nexport const DEFAULT_AI_MODEL = \"claude-opus-4-5\";\n\nexport interface StreamPromptOptions {\n\tprompt: string;\n\tcwd: string;\n\tsystemPrompt?: string;\n\tprovider?: string;\n\topenCodeContext?: OpenCodeContext;\n\n\tmodel?: string;\n\t/** Timeout in milliseconds. Set to 0 or undefined for no timeout. */\n\ttimeoutMs?: number;\n\tonDebug?: (message: string) => void;\n\tonStream?: (text: string) => void;\n}\n\nexport interface StreamPromptResult {\n\ttext: string;\n\tsessionId: string;\n\tdurationMs: number;\n}\n\ninterface OpenCodeServer {\n\tclose: () => void;\n\turl: string;\n}\n\ninterface OpenCodeSession {\n\tid: string;\n}\n\ninterface OpenCodeEvent {\n\ttype: string;\n\tproperties: Record<string, unknown>;\n}\n\ninterface OpenCodeProviderModel {\n\tid: string;\n\tname: string;\n}\n\ninterface OpenCodeProvider {\n\tid: string;\n\tname: string;\n\tmodels: Record<string, OpenCodeProviderModel>;\n}\n\ninterface OpenCodeProviderListResponse {\n\tall: OpenCodeProvider[];\n\tconnected: string[];\n\tdefault: Record<string, string>;\n}\n\nexport interface OpenCodeClient {\n\tsession: {\n\t\tcreate: () => Promise<{ data: OpenCodeSession; error?: unknown }>;\n\t\tprompt: (options: {\n\t\t\tpath: { id: string };\n\t\t\tbody: {\n\t\t\t\tagent?: string;\n\t\t\t\tparts: Array<{ type: string; text: string }>;\n\t\t\t\tmodel?: { providerID: string; modelID: string };\n\t\t\t};\n\t\t}) => Promise<{ data: unknown; error?: unknown }>;\n\t};\n\tevent: {\n\t\tsubscribe: () => Promise<{\n\t\t\tstream: AsyncIterable<OpenCodeEvent>;\n\t\t}>;\n\t};\n\tprovider: {\n\t\tlist: () => Promise<{ data: OpenCodeProviderListResponse; error?: unknown }>;\n\t};\n}\n\nexport interface OpenCodeContext {\n\tbaseUrl: string;\n\tcreateClient: (cwd: string) => OpenCodeClient;\n\tclose: () => void;\n}\n\nexport interface CreateOpenCodeContextOptions {\n\tcwd?: string;\n\tonDebug?: (message: string) => void;\n}\n\ninterface AgentConfig {\n\tdisable?: boolean;\n\tprompt?: string;\n\tdescription?: string;\n\tmode?: string;\n\tpermission?: Record<string, string>;\n\ttools?: Record<string, boolean>;\n}\n\ninterface OpenCodeConfig {\n\tplugin?: unknown[];\n\tmcp?: Record<string, unknown>;\n\tinstructions?: unknown[];\n\tagent?: Record<string, AgentConfig>;\n}\n\ntype CreateOpencodeResult = { server: OpenCodeServer };\ntype CreateOpencodeClientFn = (opts: { baseUrl: string; directory: string }) => OpenCodeClient;\ntype CreateOpencodeFn = (opts: {\n\tport: number;\n\tcwd?: string;\n\tconfig?: OpenCodeConfig;\n}) => Promise<CreateOpencodeResult>;\n\nlet cachedCreateOpencode: CreateOpencodeFn | null = null;\nlet cachedCreateOpencodeClient: CreateOpencodeClientFn | null = null;\n\nfunction assertOpenCodeInstalled(): void {\n\ttry {\n\t\texecSync(\"opencode --version\", { stdio: \"ignore\" });\n\t} catch {\n\t\tthrow new OpenCodeNotInstalledError();\n\t}\n}\n\nasync function getOpenCodeSDK(): Promise<{\n\tcreateOpencode: CreateOpencodeFn;\n\tcreateOpencodeClient: CreateOpencodeClientFn;\n}> {\n\tif (cachedCreateOpencode && cachedCreateOpencodeClient) {\n\t\treturn {\n\t\t\tcreateOpencode: cachedCreateOpencode,\n\t\t\tcreateOpencodeClient: cachedCreateOpencodeClient,\n\t\t};\n\t}\n\n\tassertOpenCodeInstalled();\n\n\ttry {\n\t\tconst sdk = await import(\"@opencode-ai/sdk\");\n\t\tif (\n\t\t\ttypeof sdk.createOpencode !== \"function\" ||\n\t\t\ttypeof sdk.createOpencodeClient !== \"function\"\n\t\t) {\n\t\t\tthrow new OpenCodeSDKError(\"SDK missing required exports\");\n\t\t}\n\t\tcachedCreateOpencode = sdk.createOpencode as CreateOpencodeFn;\n\t\tcachedCreateOpencodeClient = sdk.createOpencodeClient as CreateOpencodeClientFn;\n\t\treturn {\n\t\t\tcreateOpencode: cachedCreateOpencode,\n\t\t\tcreateOpencodeClient: cachedCreateOpencodeClient,\n\t\t};\n\t} catch (error) {\n\t\tif (error instanceof OpenCodeSDKError) {\n\t\t\tthrow error;\n\t\t}\n\t\tthrow new OpenCodeSDKError();\n\t}\n}\n\ninterface ToolRunningState {\n\tstatus: \"running\";\n\ttitle?: string;\n\tinput?: unknown;\n}\n\nfunction formatToolMessage(tool: string | undefined, state: ToolRunningState): string | null {\n\tif (state.title) {\n\t\treturn state.title;\n\t}\n\n\tif (!tool) {\n\t\treturn null;\n\t}\n\n\tconst input =\n\t\tstate.input && typeof state.input === \"object\" && !Array.isArray(state.input)\n\t\t\t? (state.input as Record<string, unknown>)\n\t\t\t: undefined;\n\tif (!input) {\n\t\treturn `Running ${tool}...`;\n\t}\n\n\tswitch (tool) {\n\t\tcase \"read\": {\n\t\t\tconst path = input.filePath ?? input.path;\n\t\t\tif (typeof path === \"string\") {\n\t\t\t\tconst filename = path.split(\"/\").pop();\n\t\t\t\treturn `Reading ${filename}...`;\n\t\t\t}\n\t\t\treturn \"Reading file...\";\n\t\t}\n\t\tcase \"glob\": {\n\t\t\tconst pattern = input.pattern;\n\t\t\tif (typeof pattern === \"string\") {\n\t\t\t\treturn `Globbing ${pattern}...`;\n\t\t\t}\n\t\t\treturn \"Searching files...\";\n\t\t}\n\t\tcase \"grep\": {\n\t\t\tconst pattern = input.pattern;\n\t\t\tif (typeof pattern === \"string\") {\n\t\t\t\tconst truncated = pattern.length > 30 ? `${pattern.slice(0, 30)}...` : pattern;\n\t\t\t\treturn `Searching for \"${truncated}\"...`;\n\t\t\t}\n\t\t\treturn \"Searching content...\";\n\t\t}\n\t\tcase \"list\": {\n\t\t\tconst path = input.path;\n\t\t\tif (typeof path === \"string\") {\n\t\t\t\treturn `Listing ${path}...`;\n\t\t\t}\n\t\t\treturn \"Listing directory...\";\n\t\t}\n\t\tdefault:\n\t\t\treturn `Running ${tool}...`;\n\t}\n}\n\nfunction getOpenCodeConfig(): OpenCodeConfig {\n\treturn {\n\t\tplugin: [],\n\t\tmcp: {},\n\t\tinstructions: [],\n\t\tagent: {\n\t\t\tbuild: { disable: true },\n\t\t\tgeneral: { disable: true },\n\t\t\tplan: { disable: true },\n\t\t\texplore: { disable: true },\n\t\t\tanalyze: {\n\t\t\t\tprompt: [\n\t\t\t\t\t\"You are an expert at analyzing open source codebases and producing documentation.\",\n\t\t\t\t\t\"\",\n\t\t\t\t\t\"Your job is to read the codebase and produce structured output based on the user's request.\",\n\t\t\t\t\t\"Use glob to discover files, grep to search for patterns, and read to examine file contents.\",\n\t\t\t\t\t\"\",\n\t\t\t\t\t\"Guidelines:\",\n\t\t\t\t\t\"- Explore the codebase thoroughly before producing output\",\n\t\t\t\t\t\"- Focus on understanding architecture, key abstractions, and usage patterns\",\n\t\t\t\t\t\"- When asked for JSON output, respond with ONLY valid JSON - no markdown, no code blocks\",\n\t\t\t\t\t\"- When asked for prose, write clear and concise documentation\",\n\t\t\t\t\t\"- Always base your analysis on actual code you've read, never speculate\",\n\t\t\t\t].join(\"\\n\"),\n\t\t\t\tmode: \"primary\",\n\t\t\t\tdescription: \"Analyze open source codebases and produce summaries and reference files\",\n\t\t\t\ttools: {\n\t\t\t\t\tread: true,\n\t\t\t\t\tgrep: true,\n\t\t\t\t\tglob: true,\n\t\t\t\t\tlist: true,\n\t\t\t\t\twrite: false,\n\t\t\t\t\tbash: false,\n\t\t\t\t\tdelete: false,\n\t\t\t\t\tedit: false,\n\t\t\t\t\tpatch: false,\n\t\t\t\t\tpath: false,\n\t\t\t\t\ttodowrite: false,\n\t\t\t\t\ttodoread: false,\n\t\t\t\t\twebsearch: false,\n\t\t\t\t\twebfetch: false,\n\t\t\t\t\tcodesearch: false,\n\t\t\t\t\tskill: false,\n\t\t\t\t\ttask: false,\n\t\t\t\t\tmcp: false,\n\t\t\t\t\tquestion: false,\n\t\t\t\t\tplan_enter: false,\n\t\t\t\t\tplan_exit: false,\n\t\t\t\t},\n\t\t\t\tpermission: {\n\t\t\t\t\tedit: \"deny\",\n\t\t\t\t\tbash: \"deny\",\n\t\t\t\t\twebfetch: \"deny\",\n\t\t\t\t\texternal_directory: \"deny\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t};\n}\n\nexport async function createOpenCodeContext(\n\toptions: CreateOpenCodeContextOptions = {},\n): Promise<OpenCodeContext> {\n\tconst debug = options.onDebug ?? (() => {});\n\n\tdebug(\"Loading OpenCode SDK...\");\n\tconst { createOpencode, createOpencodeClient } = await getOpenCodeSDK();\n\n\tconst maxAttempts = 10;\n\tlet server: OpenCodeServer | null = null;\n\tlet port = 0;\n\n\tconst config = getOpenCodeConfig();\n\n\tdebug(\"Starting embedded OpenCode server...\");\n\n\tfor (let attempt = 0; attempt < maxAttempts; attempt++) {\n\t\tport = Math.floor(Math.random() * 3000) + 3000;\n\t\ttry {\n\t\t\tconst result = await createOpencode({ port, cwd: options.cwd, config });\n\t\t\tserver = result.server;\n\t\t\tdebug(`Server started on port ${port}`);\n\t\t\tbreak;\n\t\t} catch (err) {\n\t\t\tif (err instanceof Error && err.message?.includes(\"port\")) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthrow new ServerStartError(\"Failed to start OpenCode server\", port, err);\n\t\t}\n\t}\n\n\tif (!server) {\n\t\tthrow new ServerStartError(\"Failed to start OpenCode server after all attempts\");\n\t}\n\n\tconst baseUrl = `http://localhost:${port}`;\n\tlet closed = false;\n\n\treturn {\n\t\tbaseUrl,\n\t\tcreateClient: (cwd: string) =>\n\t\t\tcreateOpencodeClient({\n\t\t\t\tbaseUrl,\n\t\t\t\tdirectory: cwd,\n\t\t\t}),\n\t\tclose: () => {\n\t\t\tif (closed) return;\n\t\t\tclosed = true;\n\t\t\tdebug(\"Closing server...\");\n\t\t\tserver?.close();\n\t\t},\n\t};\n}\n\nexport async function streamPrompt(options: StreamPromptOptions): Promise<StreamPromptResult> {\n\tconst {\n\t\tprompt,\n\t\tcwd,\n\t\tsystemPrompt,\n\t\tprovider: optProvider,\n\t\tmodel: optModel,\n\t\ttimeoutMs,\n\t\tonDebug,\n\t\tonStream,\n\t\topenCodeContext,\n\t} = options;\n\n\tconst debug = onDebug ?? (() => {});\n\tconst stream = onStream ?? (() => {});\n\tconst startTime = Date.now();\n\n\tconst providerID = optProvider ?? DEFAULT_AI_PROVIDER;\n\tconst modelID = optModel ?? DEFAULT_AI_MODEL;\n\tconst shouldCloseContext = !openCodeContext;\n\tconst context = openCodeContext ?? (await createOpenCodeContext({ cwd, onDebug: debug }));\n\tconst client = context.createClient(cwd);\n\n\ttry {\n\t\tdebug(\"Creating session...\");\n\t\tconst sessionResult = await client.session.create();\n\t\tif (sessionResult.error) {\n\t\t\tthrow new SessionError(\"Failed to create session\", undefined, undefined, sessionResult.error);\n\t\t}\n\t\tconst sessionId = sessionResult.data.id;\n\t\tdebug(`Session created: ${sessionId}`);\n\n\t\tdebug(\"Validating provider and model...\");\n\t\tconst providerResult = await client.provider.list();\n\t\tif (providerResult.error) {\n\t\t\tthrow new OpenCodeReferenceError(\"Failed to fetch provider list\", providerResult.error);\n\t\t}\n\n\t\tconst { all: allProviders, connected: connectedProviders } = providerResult.data;\n\t\tconst allProviderIds = allProviders.map((p) => p.id);\n\n\t\tconst provider = allProviders.find((p) => p.id === providerID);\n\t\tif (!provider) {\n\t\t\tthrow new InvalidProviderError(providerID, allProviderIds);\n\t\t}\n\n\t\tif (!connectedProviders.includes(providerID)) {\n\t\t\tthrow new ProviderNotConnectedError(providerID, connectedProviders);\n\t\t}\n\n\t\tconst availableModelIds = Object.keys(provider.models);\n\t\tif (!provider.models[modelID]) {\n\t\t\tthrow new InvalidModelError(modelID, providerID, availableModelIds);\n\t\t}\n\n\t\tdebug(`Provider \"${providerID}\" and model \"${modelID}\" validated`);\n\n\t\tdebug(\"Subscribing to events...\");\n\t\tconst { stream: eventStream } = await client.event.subscribe();\n\n\t\tconst fullPrompt = systemPrompt\n\t\t\t? `${systemPrompt}\\n\\nAnalyzing codebase at: ${cwd}\\n\\n${prompt}`\n\t\t\t: `Analyzing codebase at: ${cwd}\\n\\n${prompt}`;\n\n\t\tdebug(\"Sending prompt...\");\n\t\tconst promptPromise = client.session.prompt({\n\t\t\tpath: { id: sessionId },\n\t\t\tbody: {\n\t\t\t\tagent: \"analyze\",\n\t\t\t\tparts: [{ type: \"text\", text: fullPrompt }],\n\t\t\t\tmodel: { providerID, modelID },\n\t\t\t},\n\t\t});\n\n\t\tconst textAccumulator = new TextAccumulator();\n\t\tdebug(\"Waiting for response...\");\n\n\t\tlet timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n\t\tconst processEvents = async (): Promise<string> => {\n\t\t\tfor await (const event of eventStream) {\n\t\t\t\tif (!isEventForSession(event, sessionId)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst parsed = parseStreamEvent(event);\n\n\t\t\t\tswitch (parsed.type) {\n\t\t\t\t\tcase \"message.part.updated\": {\n\t\t\t\t\t\tif (parsed.toolPart?.state) {\n\t\t\t\t\t\t\tconst { state, tool } = parsed.toolPart;\n\t\t\t\t\t\t\tif (state.status === \"running\") {\n\t\t\t\t\t\t\t\tconst message = formatToolMessage(tool, state);\n\t\t\t\t\t\t\t\tif (message) {\n\t\t\t\t\t\t\t\t\tdebug(message);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (parsed.textPart) {\n\t\t\t\t\t\t\tconst delta = textAccumulator.accumulatePart(parsed.textPart);\n\t\t\t\t\t\t\tif (!textAccumulator.hasReceivedText) {\n\t\t\t\t\t\t\t\tdebug(\"Writing reference...\");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (delta) {\n\t\t\t\t\t\t\t\tstream(delta);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tcase \"session.idle\": {\n\t\t\t\t\t\tif (parsed.props.sessionID === sessionId) {\n\t\t\t\t\t\t\tdebug(\"Response complete\");\n\t\t\t\t\t\t\treturn textAccumulator.getFullText();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tcase \"session.error\": {\n\t\t\t\t\t\tif (parsed.props.sessionID === sessionId) {\n\t\t\t\t\t\t\tconst errorName = parsed.error?.name ?? \"Unknown session error\";\n\t\t\t\t\t\t\tdebug(`Session error: ${JSON.stringify(parsed.props.error)}`);\n\t\t\t\t\t\t\tthrow new SessionError(errorName, sessionId, \"error\", parsed.props.error);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tcase \"unknown\":\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn textAccumulator.getFullText();\n\t\t};\n\n\t\tlet responseText: string;\n\t\tif (timeoutMs && timeoutMs > 0) {\n\t\t\tconst timeoutPromise = new Promise<never>((_, reject) => {\n\t\t\t\ttimeoutId = setTimeout(() => {\n\t\t\t\t\treject(new TimeoutError(timeoutMs, \"session response\"));\n\t\t\t\t}, timeoutMs);\n\t\t\t});\n\t\t\tresponseText = await Promise.race([processEvents(), timeoutPromise]);\n\t\t\tif (timeoutId) clearTimeout(timeoutId);\n\t\t} else {\n\t\t\tresponseText = await processEvents();\n\t\t}\n\n\t\tawait promptPromise;\n\n\t\tif (!responseText) {\n\t\t\tthrow new OpenCodeReferenceError(\"No response received from OpenCode\");\n\t\t}\n\n\t\tdebug(`Response received (${responseText.length} chars)`);\n\n\t\tconst durationMs = Date.now() - startTime;\n\t\tdebug(`Complete in ${durationMs}ms`);\n\n\t\treturn {\n\t\t\ttext: responseText,\n\t\t\tsessionId,\n\t\t\tdurationMs,\n\t\t};\n\t} finally {\n\t\tif (shouldCloseContext) {\n\t\t\tcontext.close();\n\t\t}\n\t}\n}\n","/**\n * This module provides a streamlined approach to generating reference files\n * by delegating all codebase exploration to the AI agent via OpenCode.\n */\n\nimport { streamPrompt, type OpenCodeContext, type StreamPromptOptions } from \"./ai/opencode.js\";\nimport { loadConfig, toReferenceName } from \"./config.js\";\nimport { getCommitSha } from \"./clone.js\";\n\nexport interface GenerateReferenceOptions {\n\t/** AI provider ID (e.g., \"anthropic\", \"openai\"). Defaults to config value. */\n\tprovider?: string;\n\t/** AI model ID. Defaults to config value. */\n\tmodel?: string;\n\t/** Shared OpenCode server context for multi-repo generation */\n\topenCodeContext?: OpenCodeContext;\n\t/** Debug callback for detailed logging */\n\tonDebug?: (message: string) => void;\n\t/** Stream callback for real-time AI output */\n\tonStream?: (text: string) => void;\n}\n\nexport interface GenerateReferenceResult {\n\t/** The generated reference markdown content */\n\treferenceContent: string;\n\t/** The commit SHA at the time of generation */\n\tcommitSha: string;\n}\n\nfunction createReferenceGenerationPrompt(referenceName: string): string {\n\treturn `You are an expert at analyzing open source libraries and producing reference documentation for AI coding agents.\n\n## PRIMARY GOAL\n\nGenerate a reference markdown file that helps developers USE this library effectively. This is NOT a contribution guide - it's a usage reference for developers consuming this library in their own projects.\n\n## CRITICAL RULES\n\n1. **USER PERSPECTIVE ONLY**: Write for developers who will npm/pip/cargo install this library and use it in THEIR code.\n - DO NOT include: how to contribute, internal test commands, repo-specific policies\n - DO NOT include: \"never mock in tests\" or similar internal dev guidelines\n - DO NOT include: commands like \"npx hereby\", \"just ready\", \"bun test\" that run the library's own tests\n - DO include: how to install, import, configure, and use the public API\n\n2. **NO FRONTMATTER**: Output pure markdown with NO YAML frontmatter. Start directly with the library name heading.\n\n3. **QUICK REFERENCES**: Include a \"Quick References\" section with paths to key entry points in the repo:\n - Paths must be relative from repo root (e.g., \\`src/index.ts\\`, \\`docs/api.md\\`)\n - Include: main entry point, type definitions, README, key docs\n - DO NOT include absolute paths or user-specific paths\n - Keep to 3-5 most important files that help users understand the library\n\n4. **PUBLIC API FOCUS**: Document what users import and call, not internal implementation details.\n - Entry points: what to import from the package\n - Configuration: how to set up/initialize\n - Core methods/functions: the main API surface\n - Types: key TypeScript interfaces users need\n\n5. **MONOREPO AWARENESS**: Many libraries are monorepos with multiple packages:\n - Check for \\`packages/\\`, \\`apps/\\`, \\`crates/\\`, or \\`libs/\\` directories\n - Check root package.json for \\`workspaces\\` field\n - If monorepo: document the package structure and key packages users would install\n - Use full paths from repo root (e.g., \\`packages/core/src/index.ts\\`)\n - Identify which packages are publishable vs internal\n\n## EXPLORATION STEPS\n\nUse Read, Grep, Glob tools to explore:\n1. Root package.json / Cargo.toml - check for workspaces/monorepo config\n2. Check for \\`packages/\\`, \\`apps/\\`, \\`crates/\\` directories\n3. README.md - official usage documentation\n4. For monorepos: explore each publishable package's entry point\n5. docs/ or website/ - find documentation\n6. examples/ - real usage patterns\n7. TypeScript definitions (.d.ts) - public API surface\n\n## OUTPUT FORMAT\n\nIMPORTANT: Reference name is \"${referenceName}\" (for internal tracking only - do NOT include in output).\n\n\\`\\`\\`markdown\n# {Library Name}\n\n{2-3 sentence overview of what this library does and its key value proposition}\n\n## Quick References\n\n| File | Purpose |\n|------|---------|\n| \\`packages/{pkg}/src/index.ts\\` | Main entry point (monorepo example) |\n| \\`src/index.ts\\` | Main entry point (single-package example) |\n| \\`README.md\\` | Documentation |\n\n(For monorepos, include paths to key publishable packages)\n\n## Packages (for monorepos only)\n\n| Package | npm name | Description |\n|---------|----------|-------------|\n| \\`packages/core\\` | \\`@scope/core\\` | Core functionality |\n| \\`packages/react\\` | \\`@scope/react\\` | React bindings |\n\n(OMIT this section for single-package repos)\n\n## When to Use\n\n- {Practical scenario where a developer would reach for this library}\n- {Another real-world use case}\n- {Problem this library solves}\n\n## Installation\n\n\\`\\`\\`bash\n# Single package\nnpm install {package-name}\n\n# Monorepo (show key packages)\nnpm install @scope/core @scope/react\n\\`\\`\\`\n\n## Best Practices\n\n1. {Actionable best practice for USERS of this library}\n2. {Common mistake to avoid when using this library}\n3. {Performance or correctness tip}\n\n## Common Patterns\n\n**{Pattern Name}:**\n\\`\\`\\`{language}\n{Minimal working code example}\n\\`\\`\\`\n\n**{Another Pattern}:**\n\\`\\`\\`{language}\n{Another code example}\n\\`\\`\\`\n\n## API Quick Reference\n\n| Export | Type | Description |\n|--------|------|-------------|\n| \\`{main export}\\` | {type} | {what it does} |\n| \\`{another export}\\` | {type} | {what it does} |\n\n{Add more sections as appropriate for the library: Configuration, Types, CLI Commands (if user-facing), etc.}\n\\`\\`\\`\n\n## QUALITY CHECKLIST\n\nBefore outputting, verify:\n- [ ] NO YAML frontmatter - start directly with # heading\n- [ ] Every code example is something a USER would write, not a contributor\n- [ ] No internal test commands or contribution workflows\n- [ ] Quick References paths are relative from repo root (no absolute/user paths)\n- [ ] Best practices are for using the library, not developing it\n- [ ] If monorepo: Packages section lists publishable packages with npm names\n- [ ] If monorepo: paths include package directory (e.g., \\`packages/core/src/index.ts\\`)\n\nNow explore the codebase and generate the reference content.\n\n## OUTPUT INSTRUCTIONS\n\nAfter exploring, output your complete reference wrapped in XML tags like this:\n\n\\`\\`\\`\n<reference_output>\n(your complete markdown reference here)\n</reference_output>\n\\`\\`\\`\n\nREQUIREMENTS:\n- Start with a level-1 heading with the actual library name (e.g., \"# TanStack Query\")\n- Include sections: Quick References (table), When to Use (bullets), Installation, Best Practices, Common Patterns (with code), API Quick Reference (table)\n- Minimum 2000 characters of actual content - short or placeholder content will be rejected\n- Fill in real information from your exploration - do not use placeholder text like \"{Library Name}\"\n- No YAML frontmatter - start directly with the markdown heading\n- Output ONLY the reference inside the tags, no other text\n\nBegin exploring now.`;\n}\n\n/**\n * Extract the actual reference markdown content from AI response.\n * The response may include echoed prompt/system context before the actual reference.\n * Handles multiple edge cases:\n * - Model echoes the prompt template (skip template content)\n * - Model forgets to close the tag (extract to end of response)\n * - Multiple tag pairs (find the one with real content)\n */\nfunction extractReferenceContent(rawResponse: string, onDebug?: (message: string) => void): string {\n\tconst openTag = \"<reference_output>\";\n\tconst closeTag = \"</reference_output>\";\n\n\tonDebug?.(`[extract] Raw response length: ${rawResponse.length} chars`);\n\n\t// Find all occurrences of open and close tags\n\tconst openIndices: number[] = [];\n\tconst closeIndices: number[] = [];\n\tlet pos = 0;\n\twhile ((pos = rawResponse.indexOf(openTag, pos)) !== -1) {\n\t\topenIndices.push(pos);\n\t\tpos += openTag.length;\n\t}\n\tpos = 0;\n\twhile ((pos = rawResponse.indexOf(closeTag, pos)) !== -1) {\n\t\tcloseIndices.push(pos);\n\t\tpos += closeTag.length;\n\t}\n\n\tonDebug?.(\n\t\t`[extract] Found ${openIndices.length} open tag(s), ${closeIndices.length} close tag(s)`,\n\t);\n\n\t// Helper to clean content (strip markdown fences)\n\tconst cleanContent = (raw: string): string => {\n\t\tlet content = raw.trim();\n\t\tif (content.startsWith(\"```\")) {\n\t\t\tcontent = content.replace(/^```(?:markdown)?\\s*\\n?/, \"\");\n\t\t\tcontent = content.replace(/\\n?```\\s*$/, \"\");\n\t\t}\n\t\treturn content.trim();\n\t};\n\n\t// Helper to check if content is template placeholder\n\tconst isTemplateContent = (content: string): boolean => {\n\t\treturn (\n\t\t\tcontent.includes(\"{Library Name}\") ||\n\t\t\tcontent.includes(\"(your complete markdown reference here)\")\n\t\t);\n\t};\n\n\t// Strategy 1: Find properly paired tags, starting from the LAST open tag\n\t// (Last is more likely to be actual output, not echoed prompt)\n\tfor (let i = openIndices.length - 1; i >= 0; i--) {\n\t\tconst openIdx = openIndices[i];\n\t\tif (openIdx === undefined) continue;\n\n\t\t// Find the first close tag after this open tag\n\t\tconst closeIdx = closeIndices.find((c) => c > openIdx);\n\t\tif (closeIdx !== undefined) {\n\t\t\tconst rawContent = rawResponse.slice(openIdx + openTag.length, closeIdx);\n\t\t\tconst content = cleanContent(rawContent);\n\n\t\t\tonDebug?.(`[extract] Pair ${i}: open=${openIdx}, close=${closeIdx}, len=${content.length}`);\n\t\t\tonDebug?.(\n\t\t\t\t`[extract] Preview: \"${content.slice(0, 200)}${content.length > 200 ? \"...\" : \"\"}\"`,\n\t\t\t);\n\n\t\t\tif (isTemplateContent(content)) {\n\t\t\t\tonDebug?.(`[extract] Skipping pair ${i} - template placeholder content`);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (content.length >= 500) {\n\t\t\t\tonDebug?.(`[extract] Using pair ${i} - valid content`);\n\t\t\t\tvalidateReferenceContent(content);\n\t\t\t\treturn content;\n\t\t\t}\n\t\t\tonDebug?.(`[extract] Pair ${i} too short (${content.length} chars)`);\n\t\t}\n\t}\n\n\t// Strategy 2: Handle unclosed tag - model output <reference_output> but never closed it\n\t// Find the last open tag that has no close tag after it\n\tconst lastOpenIdx = openIndices[openIndices.length - 1];\n\tif (lastOpenIdx !== undefined) {\n\t\tconst hasCloseAfter = closeIndices.some((c) => c > lastOpenIdx);\n\t\tif (!hasCloseAfter) {\n\t\t\tonDebug?.(`[extract] Last open tag at ${lastOpenIdx} is unclosed - extracting to end`);\n\t\t\tconst rawContent = rawResponse.slice(lastOpenIdx + openTag.length);\n\t\t\tconst content = cleanContent(rawContent);\n\n\t\t\tonDebug?.(`[extract] Unclosed content: ${content.length} chars`);\n\t\t\tonDebug?.(\n\t\t\t\t`[extract] Preview: \"${content.slice(0, 200)}${content.length > 200 ? \"...\" : \"\"}\"`,\n\t\t\t);\n\n\t\t\tif (!isTemplateContent(content) && content.length >= 500) {\n\t\t\t\tonDebug?.(`[extract] Using unclosed content - valid`);\n\t\t\t\tvalidateReferenceContent(content);\n\t\t\t\treturn content;\n\t\t\t}\n\t\t}\n\t}\n\n\tonDebug?.(`[extract] No valid content found`);\n\tonDebug?.(`[extract] Response tail: \"${rawResponse.slice(-300)}\"`);\n\n\tthrow new Error(\n\t\t\"Failed to extract reference content: no valid <reference_output> tags found. \" +\n\t\t\t\"The AI may have failed to follow the output format or produced placeholder content.\",\n\t);\n}\n\n/**\n * Validate extracted reference content has minimum required structure.\n * Throws if content is invalid.\n */\nfunction validateReferenceContent(content: string): void {\n\t// Check for template placeholders that indicate the model just echoed the format\n\tconst templatePlaceholders = [\n\t\t\"{Library Name}\",\n\t\t\"{Full overview paragraph}\",\n\t\t\"{Table with 3-5 key files}\",\n\t\t\"{3+ bullet points}\",\n\t\t\"{Install commands}\",\n\t\t\"{3+ numbered items}\",\n\t\t\"{2+ code examples\",\n\t\t\"{Table of key exports}\",\n\t\t\"{Additional sections\",\n\t];\n\n\tconst foundPlaceholders = templatePlaceholders.filter((p) => content.includes(p));\n\tif (foundPlaceholders.length > 0) {\n\t\tthrow new Error(\n\t\t\t`Invalid reference content: contains template placeholders (${foundPlaceholders.slice(0, 3).join(\", \")}). ` +\n\t\t\t\t\"The AI echoed the format instead of generating actual content.\",\n\t\t);\n\t}\n\n\tif (content.length < 500) {\n\t\tthrow new Error(\n\t\t\t`Invalid reference content: too short (${content.length} chars, minimum 500). ` +\n\t\t\t\t\"The AI may have produced placeholder or incomplete content.\",\n\t\t);\n\t}\n\n\tif (!content.startsWith(\"#\")) {\n\t\tthrow new Error(\n\t\t\t\"Invalid reference content: must start with markdown heading. \" +\n\t\t\t\t\"Content must begin with '# Library Name' (no YAML frontmatter).\",\n\t\t);\n\t}\n}\n\n/**\n * Generate a reference markdown file for a repository using AI.\n *\n * Opens an OpenCode session and instructs the AI agent to explore the codebase\n * using Read, Grep, and Glob tools, then produce a comprehensive reference.\n *\n * @param repoPath - Path to the repository to analyze\n * @param repoName - Qualified name of the repo (e.g., \"tanstack/query\" or \"my-local-repo\")\n * @param options - Generation options (provider, model, callbacks)\n * @returns The generated reference content and commit SHA\n */\nexport async function generateReferenceWithAI(\n\trepoPath: string,\n\trepoName: string,\n\toptions: GenerateReferenceOptions = {},\n): Promise<GenerateReferenceResult> {\n\tconst { provider, model, onDebug, onStream, openCodeContext } = options;\n\tconst config = loadConfig();\n\n\tconst [configProvider, configModel] = config.defaultModel?.split(\"/\") ?? [];\n\tconst aiProvider = provider ?? configProvider;\n\tconst aiModel = model ?? configModel;\n\n\tonDebug?.(`Starting AI reference generation for ${repoName}`);\n\tonDebug?.(`Repo path: ${repoPath}`);\n\tonDebug?.(`Provider: ${aiProvider ?? \"default\"}, Model: ${aiModel ?? \"default\"}`);\n\n\tconst commitSha = getCommitSha(repoPath);\n\tonDebug?.(`Commit SHA: ${commitSha}`);\n\n\tconst referenceName = toReferenceName(repoName);\n\tonDebug?.(`Reference name: ${referenceName}`);\n\n\tconst promptOptions: StreamPromptOptions = {\n\t\tprompt: createReferenceGenerationPrompt(referenceName),\n\t\tcwd: repoPath,\n\t\tprovider: aiProvider,\n\t\tmodel: aiModel,\n\t\topenCodeContext,\n\t\tonDebug,\n\t\tonStream,\n\t};\n\n\tconst result = await streamPrompt(promptOptions);\n\n\tonDebug?.(`Generation complete (${result.durationMs}ms, ${result.text.length} chars)`);\n\n\tconst referenceContent = extractReferenceContent(result.text, onDebug);\n\tonDebug?.(`Extracted reference content (${referenceContent.length} chars)`);\n\n\treturn {\n\t\treferenceContent,\n\t\tcommitSha,\n\t};\n}\n"],"mappings":";;;;;;;;;AAGA,IAAa,yBAAb,cAA4C,MAAM;CACjD,AAAS,OAAe;CACxB,YACC,SACA,AAAgB,SACf;AACD,QAAM,QAAQ;EAFE;AAGhB,OAAK,OAAO;;;;;;AAOd,IAAa,4BAAb,cAA+C,uBAAuB;CACrE,AAAS,OAAO;CAChB,AAAS;CAET,cAAc;EACb,MAAM,OACL;AACD,QAAM,8BAA8B,OAAO;AAC3C,OAAK,OAAO;AACZ,OAAK,OAAO;;;;;;AAOd,IAAa,mBAAb,cAAsC,uBAAuB;CAC5D,AAAS,OAAO;CAChB,YAAY,SAAkB;AAC7B,QACC,WAAW,+EACX;AACD,OAAK,OAAO;;;;;;AAOd,IAAa,uBAAb,cAA0C,uBAAuB;CAChE,AAAS,OAAO;CAChB,AAAS;CAET,YACC,AAAgB,YAChB,AAAgB,oBACf;EACD,MAAM,OACL,mBAAmB,SAAS,IACzB,wBAAwB,mBAAmB,KAAK,KAAK,KACrD;AACJ,QAAM,aAAa,WAAW,eAAe,OAAO;EAPpC;EACA;AAOhB,OAAK,OAAO;AACZ,OAAK,OAAO;;;;;;AAOd,IAAa,4BAAb,cAA+C,uBAAuB;CACrE,AAAS,OAAO;CAChB,AAAS;CAET,YACC,AAAgB,YAChB,AAAgB,oBACf;EACD,MAAM,OACL,mBAAmB,SAAS,IACzB,wBAAwB,mBAAmB,KAAK,KAAK,CAAC,uBAAuB,WAAW,iBACxF,8CAA8C,WAAW;AAC7D,QAAM,aAAa,WAAW,sBAAsB,OAAO;EAP3C;EACA;AAOhB,OAAK,OAAO;AACZ,OAAK,OAAO;;;;;;AAOd,IAAa,oBAAb,cAAuC,uBAAuB;CAC7D,AAAS,OAAO;CAChB,AAAS;CAET,YACC,AAAgB,SAChB,AAAgB,YAChB,AAAgB,iBACf;EACD,MAAM,OACL,gBAAgB,SAAS,IACtB,wBAAwB,WAAW,IAAI,gBAAgB,MAAM,GAAG,GAAG,CAAC,KAAK,KAAK,GAAG,gBAAgB,SAAS,KAAK,SAAS,gBAAgB,SAAS,GAAG,UAAU,OAC9J,qCAAqC,WAAW;AACpD,QAAM,UAAU,QAAQ,4BAA4B,WAAW,KAAK,OAAO;EAR3D;EACA;EACA;AAOhB,OAAK,OAAO;AACZ,OAAK,OAAO;;;;;;AAOd,IAAa,mBAAb,cAAsC,uBAAuB;CAC5D,AAAS,OAAO;CAChB,AAAS;CAET,YACC,SACA,AAAgB,MAChB,SACC;EACD,MAAM,OAAO,OACV,kCAAkC,KAAK,iDACvC;AACH,QAAM,GAAG,QAAQ,IAAI,QAAQ,QAAQ;EANrB;AAOhB,OAAK,OAAO;AACZ,OAAK,OAAO;;;;;;AAOd,IAAa,eAAb,cAAkC,uBAAuB;CACxD,AAAS,OAAO;CAChB,AAAS;CAET,YACC,SACA,AAAgB,WAChB,AAAgB,cAChB,SACC;EAGD,MAAM,OAAO,2BAFG,YAAY,cAAc,UAAU,KAAK,GAET,GAD9B,eAAe,WAAW,aAAa,KAAK,GACD;AAC7D,QAAM,GAAG,QAAQ,IAAI,QAAQ,QAAQ;EAPrB;EACA;AAOhB,OAAK,OAAO;AACZ,OAAK,OAAO;;;;;;AAOd,IAAa,eAAb,cAAkC,uBAAuB;CACxD,AAAS,OAAO;CAChB,AAAS;CAET,YACC,AAAgB,WAChB,AAAgB,YAAoB,aACnC;EACD,MAAM,OAAO,OAAO,UAAU,2BAA2B,UAAU;AACnE,QAAM,YAAY,UAAU,2BAA2B,UAAU,MAAM,OAAO;EAJ9D;EACA;AAIhB,OAAK,OAAO;AACZ,OAAK,OAAO;;;;;;;;;;AC7Jd,MAAM,iBAAiB,EAAE,OAAO;CAC/B,IAAI,EAAE,QAAQ,CAAC,UAAU;CACzB,WAAW,EAAE,QAAQ,CAAC,UAAU;CAChC,WAAW,EAAE,QAAQ,CAAC,UAAU;CAChC,CAAC;AAEF,MAAa,iBAAiB,eAAe,OAAO;CACnD,MAAM,EAAE,QAAQ,OAAO;CACvB,MAAM,EAAE,QAAQ,CAAC,UAAU;CAC3B,CAAC;AAEF,MAAa,yBAAyB,EAAE,OAAO,EAC9C,QAAQ,EAAE,QAAQ,UAAU,EAC5B,CAAC;AAEF,MAAa,yBAAyB,EAAE,OAAO;CAC9C,QAAQ,EAAE,QAAQ,UAAU;CAC5B,OAAO,EAAE,QAAQ,CAAC,UAAU;CAC5B,OAAO,EAAE,SAAS,CAAC,UAAU;CAC7B,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,SAAS,CAAC,CAAC,UAAU;CACtD,MAAM,EACJ,OAAO,EACP,OAAO,EAAE,QAAQ,EACjB,CAAC,CACD,UAAU;CACZ,CAAC;AAEF,MAAa,2BAA2B,EAAE,OAAO;CAChD,QAAQ,EAAE,QAAQ,YAAY;CAC9B,OAAO,EAAE,QAAQ,CAAC,UAAU;CAC5B,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,SAAS,CAAC,CAAC,UAAU;CACnD,QAAQ,EAAE,QAAQ,CAAC,UAAU;CAC7B,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,SAAS,CAAC,CAAC,UAAU;CACtD,MAAM,EACJ,OAAO;EACP,OAAO,EAAE,QAAQ;EACjB,KAAK,EAAE,QAAQ;EACf,CAAC,CACD,UAAU;CACZ,CAAC;AAEF,MAAa,uBAAuB,EAAE,OAAO;CAC5C,QAAQ,EAAE,QAAQ,QAAQ;CAC1B,OAAO,EAAE,QAAQ,CAAC,UAAU;CAC5B,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,SAAS,CAAC,CAAC,UAAU;CACnD,MAAM,EACJ,OAAO;EACP,OAAO,EAAE,QAAQ;EACjB,KAAK,EAAE,QAAQ;EACf,CAAC,CACD,UAAU;CACZ,CAAC;AAEF,MAAa,kBAAkB,EAAE,mBAAmB,UAAU;CAC7D;CACA;CACA;CACA;CACA,CAAC;AAEF,MAAa,iBAAiB,eAAe,OAAO;CACnD,MAAM,EAAE,QAAQ,OAAO;CACvB,QAAQ,EAAE,QAAQ,CAAC,UAAU;CAC7B,MAAM,EAAE,QAAQ,CAAC,UAAU;CAC3B,OAAO,gBAAgB,UAAU;CACjC,CAAC;AAEF,MAAa,sBAAsB,eAAe,OAAO,EACxD,MAAM,EAAE,QAAQ,aAAa,EAC7B,CAAC;AAEF,MAAa,uBAAuB,eAAe,OAAO;CACzD,MAAM,EAAE,QAAQ,cAAc;CAC9B,QAAQ,EAAE,QAAQ,CAAC,UAAU;CAC7B,CAAC;AAEF,MAAa,oBAAoB,eAAe,OAAO;CACtD,MAAM,EAAE,QAAQ,WAAW;CAC3B,WAAW,EAAE,QAAQ,CAAC,UAAU;CAChC,MAAM,EAAE,QAAQ,CAAC,UAAU;CAC3B,CAAC;AAEF,MAAa,uBAAuB,eAAe,OAAO;CACzD,MAAM,EAAE,QAAQ,cAAc;CAC9B,WAAW,EAAE,QAAQ,CAAC,UAAU;CAChC,CAAC;AAEF,MAAa,oBAAoB,EAAE,mBAAmB,QAAQ;CAC7D;CACA;CACA;CACA;CACA;CACA;CACA,CAAC;;;;AAKF,MAAa,qBAAqB,EAAE,OAAO;CAC1C,MAAM,EAAE,QAAQ,CAAC,UAAU;CAC3B,SAAS,EAAE,QAAQ,CAAC,UAAU;CAC9B,MAAM,EAAE,QAAQ,CAAC,UAAU;CAC3B,CAAC;AAEF,MAAa,gCAAgC,EAAE,OAAO,EACrD,MAAM,mBACN,CAAC;;;;AAKF,MAAa,yBAAyB,EAAE,OAAO,EAC9C,WAAW,EAAE,QAAQ,EACrB,CAAC;;;;AAKF,MAAa,0BAA0B,EAAE,OAAO;CAC/C,WAAW,EAAE,QAAQ;CACrB,OAAO,mBAAmB,UAAU;CACpC,CAAC;;;;AAKF,MAAa,4BAA4B,EAAE,OAAO;CACjD,WAAW,EAAE,QAAQ;CACrB,QAAQ,EAAE,QAAQ,CAAC,UAAU;CAC7B,CAAC;;;;AAKF,MAAa,gCAAgC,EAAE,OAAO;CACrD,MAAM,EAAE,QAAQ,uBAAuB;CACvC,YAAY;CACZ,CAAC;;;;AAKF,MAAa,yBAAyB,EAAE,OAAO;CAC9C,MAAM,EAAE,QAAQ,eAAe;CAC/B,YAAY;CACZ,CAAC;;;;AAKF,MAAa,0BAA0B,EAAE,OAAO;CAC/C,MAAM,EAAE,QAAQ,gBAAgB;CAChC,YAAY;CACZ,CAAC;;;;AAKF,MAAa,4BAA4B,EAAE,OAAO;CACjD,MAAM,EAAE,QAAQ,kBAAkB;CAClC,YAAY;CACZ,CAAC;;;;AAKF,MAAa,qBAAqB,EAAE,OAAO;CAC1C,MAAM,EAAE,QAAQ;CAChB,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,SAAS,CAAC;CAC7C,CAAC;;;;;;;;ACtKF,IAAa,kBAAb,MAA6B;CAC5B,AAAiB,wBAAQ,IAAI,KAAqB;CAClD,AAAQ,qBAAqB;;;;CAK7B,IAAI,kBAA2B;AAC9B,SAAO,KAAK;;;;;;CAOb,eAAe,MAA+B;AAC7C,MAAI,KAAK,SAAS,UAAU,CAAC,KAAK,QAAQ,CAAC,KAAK,GAC/C,QAAO;EAGR,MAAM,SAAS,KAAK;EACpB,MAAM,WAAW,KAAK,MAAM,IAAI,OAAO,IAAI;AAC3C,OAAK,MAAM,IAAI,QAAQ,KAAK,KAAK;AAEjC,MAAI,CAAC,KAAK,mBACT,MAAK,qBAAqB;AAG3B,MAAI,KAAK,KAAK,SAAS,SAAS,OAC/B,QAAO,KAAK,KAAK,MAAM,SAAS,OAAO;AAGxC,SAAO;;;;;CAMR,cAAsB;AACrB,SAAO,MAAM,KAAK,KAAK,MAAM,QAAQ,CAAC,CAAC,KAAK,GAAG;;;;;CAMhD,eAAuB;AACtB,SAAO,KAAK,MAAM;;;;;CAMnB,cAAqD;AACpD,SAAO,MAAM,KAAK,KAAK,MAAM,SAAS,CAAC,CAAC,KAAK,CAAC,IAAI,WAAW;GAC5D;GACA,QAAQ,KAAK;GACb,EAAE;;;;;CAMJ,QAAc;AACb,OAAK,MAAM,OAAO;AAClB,OAAK,qBAAqB;;;;;;;;;;;;;;AC/B5B,SAAgB,iBAAiB,OAA0C;AAC1E,SAAQ,MAAM,MAAd;EACC,KAAK,wBAAwB;GAC5B,MAAM,cAAc,8BAA8B,UAAU,MAAM,WAAW;AAC7E,OAAI,CAAC,YAAY,QAChB,QAAO;IAAE,MAAM;IAAW,SAAS,MAAM;IAAM;GAEhD,MAAM,QAAQ,YAAY;AAG1B,UAAO;IAAE,MAAM;IAAwB;IAAO,UAF7B,MAAM,KAAK,SAAS,SAAS,MAAM,OAAO;IAEH,UADvC,MAAM,KAAK,SAAS,SAAS,MAAM,OAAO;IACO;;EAGnE,KAAK,gBAAgB;GACpB,MAAM,cAAc,uBAAuB,UAAU,MAAM,WAAW;AACtE,OAAI,CAAC,YAAY,QAChB,QAAO;IAAE,MAAM;IAAW,SAAS,MAAM;IAAM;AAEhD,UAAO;IAAE,MAAM;IAAgB,OAAO,YAAY;IAAM;;EAGzD,KAAK,iBAAiB;GACrB,MAAM,cAAc,wBAAwB,UAAU,MAAM,WAAW;AACvE,OAAI,CAAC,YAAY,QAChB,QAAO;IAAE,MAAM;IAAW,SAAS,MAAM;IAAM;GAEhD,MAAM,QAAQ,YAAY;GAE1B,IAAI,QAAoC;AACxC,OAAI,MAAM,OAAO;IAChB,MAAM,cAAc,mBAAmB,UAAU,MAAM,MAAM;AAC7D,QAAI,YAAY,QACf,SAAQ,YAAY;;AAItB,UAAO;IAAE,MAAM;IAAiB;IAAO;IAAO;;EAG/C,QACC,QAAO;GAAE,MAAM;GAAW,SAAS,MAAM;GAAM;;;AAIlD,SAAgB,kBAAkB,OAAuB,WAA4B;CACpF,MAAM,QAAQ,MAAM;AACpB,KAAI,eAAe,SAAS,OAAO,MAAM,cAAc,SACtD,QAAO,MAAM,cAAc;AAE5B,KACC,UAAU,SACV,OAAO,MAAM,SAAS,YACtB,MAAM,SAAS,QACf,eAAe,MAAM,QACrB,OAAO,MAAM,KAAK,cAAc,SAEhC,QAAO,MAAM,KAAK,cAAc;AAEjC,QAAO;;;;;ACxFR,MAAa,sBAAsB;AACnC,MAAa,mBAAmB;AA8GhC,IAAI,uBAAgD;AACpD,IAAI,6BAA4D;AAEhE,SAAS,0BAAgC;AACxC,KAAI;AACH,WAAS,sBAAsB,EAAE,OAAO,UAAU,CAAC;SAC5C;AACP,QAAM,IAAI,2BAA2B;;;AAIvC,eAAe,iBAGZ;AACF,KAAI,wBAAwB,2BAC3B,QAAO;EACN,gBAAgB;EAChB,sBAAsB;EACtB;AAGF,0BAAyB;AAEzB,KAAI;EACH,MAAM,MAAM,MAAM,OAAO;AACzB,MACC,OAAO,IAAI,mBAAmB,cAC9B,OAAO,IAAI,yBAAyB,WAEpC,OAAM,IAAI,iBAAiB,+BAA+B;AAE3D,yBAAuB,IAAI;AAC3B,+BAA6B,IAAI;AACjC,SAAO;GACN,gBAAgB;GAChB,sBAAsB;GACtB;UACO,OAAO;AACf,MAAI,iBAAiB,iBACpB,OAAM;AAEP,QAAM,IAAI,kBAAkB;;;AAU9B,SAAS,kBAAkB,MAA0B,OAAwC;AAC5F,KAAI,MAAM,MACT,QAAO,MAAM;AAGd,KAAI,CAAC,KACJ,QAAO;CAGR,MAAM,QACL,MAAM,SAAS,OAAO,MAAM,UAAU,YAAY,CAAC,MAAM,QAAQ,MAAM,MAAM,GACzE,MAAM,QACP;AACJ,KAAI,CAAC,MACJ,QAAO,WAAW,KAAK;AAGxB,SAAQ,MAAR;EACC,KAAK,QAAQ;GACZ,MAAM,OAAO,MAAM,YAAY,MAAM;AACrC,OAAI,OAAO,SAAS,SAEnB,QAAO,WADU,KAAK,MAAM,IAAI,CAAC,KAAK,CACX;AAE5B,UAAO;;EAER,KAAK,QAAQ;GACZ,MAAM,UAAU,MAAM;AACtB,OAAI,OAAO,YAAY,SACtB,QAAO,YAAY,QAAQ;AAE5B,UAAO;;EAER,KAAK,QAAQ;GACZ,MAAM,UAAU,MAAM;AACtB,OAAI,OAAO,YAAY,SAEtB,QAAO,kBADW,QAAQ,SAAS,KAAK,GAAG,QAAQ,MAAM,GAAG,GAAG,CAAC,OAAO,QACpC;AAEpC,UAAO;;EAER,KAAK,QAAQ;GACZ,MAAM,OAAO,MAAM;AACnB,OAAI,OAAO,SAAS,SACnB,QAAO,WAAW,KAAK;AAExB,UAAO;;EAER,QACC,QAAO,WAAW,KAAK;;;AAI1B,SAAS,oBAAoC;AAC5C,QAAO;EACN,QAAQ,EAAE;EACV,KAAK,EAAE;EACP,cAAc,EAAE;EAChB,OAAO;GACN,OAAO,EAAE,SAAS,MAAM;GACxB,SAAS,EAAE,SAAS,MAAM;GAC1B,MAAM,EAAE,SAAS,MAAM;GACvB,SAAS,EAAE,SAAS,MAAM;GAC1B,SAAS;IACR,QAAQ;KACP;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA,CAAC,KAAK,KAAK;IACZ,MAAM;IACN,aAAa;IACb,OAAO;KACN,MAAM;KACN,MAAM;KACN,MAAM;KACN,MAAM;KACN,OAAO;KACP,MAAM;KACN,QAAQ;KACR,MAAM;KACN,OAAO;KACP,MAAM;KACN,WAAW;KACX,UAAU;KACV,WAAW;KACX,UAAU;KACV,YAAY;KACZ,OAAO;KACP,MAAM;KACN,KAAK;KACL,UAAU;KACV,YAAY;KACZ,WAAW;KACX;IACD,YAAY;KACX,MAAM;KACN,MAAM;KACN,UAAU;KACV,oBAAoB;KACpB;IACD;GACD;EACD;;AAGF,eAAsB,sBACrB,UAAwC,EAAE,EACf;CAC3B,MAAM,QAAQ,QAAQ,kBAAkB;AAExC,OAAM,0BAA0B;CAChC,MAAM,EAAE,gBAAgB,yBAAyB,MAAM,gBAAgB;CAEvE,MAAM,cAAc;CACpB,IAAI,SAAgC;CACpC,IAAI,OAAO;CAEX,MAAM,SAAS,mBAAmB;AAElC,OAAM,uCAAuC;AAE7C,MAAK,IAAI,UAAU,GAAG,UAAU,aAAa,WAAW;AACvD,SAAO,KAAK,MAAM,KAAK,QAAQ,GAAG,IAAK,GAAG;AAC1C,MAAI;AAEH,aADe,MAAM,eAAe;IAAE;IAAM,KAAK,QAAQ;IAAK;IAAQ,CAAC,EACvD;AAChB,SAAM,0BAA0B,OAAO;AACvC;WACQ,KAAK;AACb,OAAI,eAAe,SAAS,IAAI,SAAS,SAAS,OAAO,CACxD;AAED,SAAM,IAAI,iBAAiB,mCAAmC,MAAM,IAAI;;;AAI1E,KAAI,CAAC,OACJ,OAAM,IAAI,iBAAiB,qDAAqD;CAGjF,MAAM,UAAU,oBAAoB;CACpC,IAAI,SAAS;AAEb,QAAO;EACN;EACA,eAAe,QACd,qBAAqB;GACpB;GACA,WAAW;GACX,CAAC;EACH,aAAa;AACZ,OAAI,OAAQ;AACZ,YAAS;AACT,SAAM,oBAAoB;AAC1B,WAAQ,OAAO;;EAEhB;;AAGF,eAAsB,aAAa,SAA2D;CAC7F,MAAM,EACL,QACA,KACA,cACA,UAAU,aACV,OAAO,UACP,WACA,SACA,UACA,oBACG;CAEJ,MAAM,QAAQ,kBAAkB;CAChC,MAAM,SAAS,mBAAmB;CAClC,MAAM,YAAY,KAAK,KAAK;CAE5B,MAAM,aAAa,eAAe;CAClC,MAAM,UAAU,YAAY;CAC5B,MAAM,qBAAqB,CAAC;CAC5B,MAAM,UAAU,mBAAoB,MAAM,sBAAsB;EAAE;EAAK,SAAS;EAAO,CAAC;CACxF,MAAM,SAAS,QAAQ,aAAa,IAAI;AAExC,KAAI;AACH,QAAM,sBAAsB;EAC5B,MAAM,gBAAgB,MAAM,OAAO,QAAQ,QAAQ;AACnD,MAAI,cAAc,MACjB,OAAM,IAAI,aAAa,4BAA4B,QAAW,QAAW,cAAc,MAAM;EAE9F,MAAM,YAAY,cAAc,KAAK;AACrC,QAAM,oBAAoB,YAAY;AAEtC,QAAM,mCAAmC;EACzC,MAAM,iBAAiB,MAAM,OAAO,SAAS,MAAM;AACnD,MAAI,eAAe,MAClB,OAAM,IAAI,uBAAuB,iCAAiC,eAAe,MAAM;EAGxF,MAAM,EAAE,KAAK,cAAc,WAAW,uBAAuB,eAAe;EAC5E,MAAM,iBAAiB,aAAa,KAAK,MAAM,EAAE,GAAG;EAEpD,MAAM,WAAW,aAAa,MAAM,MAAM,EAAE,OAAO,WAAW;AAC9D,MAAI,CAAC,SACJ,OAAM,IAAI,qBAAqB,YAAY,eAAe;AAG3D,MAAI,CAAC,mBAAmB,SAAS,WAAW,CAC3C,OAAM,IAAI,0BAA0B,YAAY,mBAAmB;EAGpE,MAAM,oBAAoB,OAAO,KAAK,SAAS,OAAO;AACtD,MAAI,CAAC,SAAS,OAAO,SACpB,OAAM,IAAI,kBAAkB,SAAS,YAAY,kBAAkB;AAGpE,QAAM,aAAa,WAAW,eAAe,QAAQ,aAAa;AAElE,QAAM,2BAA2B;EACjC,MAAM,EAAE,QAAQ,gBAAgB,MAAM,OAAO,MAAM,WAAW;EAE9D,MAAM,aAAa,eAChB,GAAG,aAAa,6BAA6B,IAAI,MAAM,WACvD,0BAA0B,IAAI,MAAM;AAEvC,QAAM,oBAAoB;EAC1B,MAAM,gBAAgB,OAAO,QAAQ,OAAO;GAC3C,MAAM,EAAE,IAAI,WAAW;GACvB,MAAM;IACL,OAAO;IACP,OAAO,CAAC;KAAE,MAAM;KAAQ,MAAM;KAAY,CAAC;IAC3C,OAAO;KAAE;KAAY;KAAS;IAC9B;GACD,CAAC;EAEF,MAAM,kBAAkB,IAAI,iBAAiB;AAC7C,QAAM,0BAA0B;EAEhC,IAAI,YAAkD;EAEtD,MAAM,gBAAgB,YAA6B;AAClD,cAAW,MAAM,SAAS,aAAa;AACtC,QAAI,CAAC,kBAAkB,OAAO,UAAU,CACvC;IAGD,MAAM,SAAS,iBAAiB,MAAM;AAEtC,YAAQ,OAAO,MAAf;KACC,KAAK;AACJ,UAAI,OAAO,UAAU,OAAO;OAC3B,MAAM,EAAE,OAAO,SAAS,OAAO;AAC/B,WAAI,MAAM,WAAW,WAAW;QAC/B,MAAM,UAAU,kBAAkB,MAAM,MAAM;AAC9C,YAAI,QACH,OAAM,QAAQ;;;AAIjB,UAAI,OAAO,UAAU;OACpB,MAAM,QAAQ,gBAAgB,eAAe,OAAO,SAAS;AAC7D,WAAI,CAAC,gBAAgB,gBACpB,OAAM,uBAAuB;AAE9B,WAAI,MACH,QAAO,MAAM;;AAGf;KAGD,KAAK;AACJ,UAAI,OAAO,MAAM,cAAc,WAAW;AACzC,aAAM,oBAAoB;AAC1B,cAAO,gBAAgB,aAAa;;AAErC;KAGD,KAAK;AACJ,UAAI,OAAO,MAAM,cAAc,WAAW;OACzC,MAAM,YAAY,OAAO,OAAO,QAAQ;AACxC,aAAM,kBAAkB,KAAK,UAAU,OAAO,MAAM,MAAM,GAAG;AAC7D,aAAM,IAAI,aAAa,WAAW,WAAW,SAAS,OAAO,MAAM,MAAM;;AAE1E;KAGD,KAAK,UACJ;;;AAGH,UAAO,gBAAgB,aAAa;;EAGrC,IAAI;AACJ,MAAI,aAAa,YAAY,GAAG;GAC/B,MAAM,iBAAiB,IAAI,SAAgB,GAAG,WAAW;AACxD,gBAAY,iBAAiB;AAC5B,YAAO,IAAI,aAAa,WAAW,mBAAmB,CAAC;OACrD,UAAU;KACZ;AACF,kBAAe,MAAM,QAAQ,KAAK,CAAC,eAAe,EAAE,eAAe,CAAC;AACpE,OAAI,UAAW,cAAa,UAAU;QAEtC,gBAAe,MAAM,eAAe;AAGrC,QAAM;AAEN,MAAI,CAAC,aACJ,OAAM,IAAI,uBAAuB,qCAAqC;AAGvE,QAAM,sBAAsB,aAAa,OAAO,SAAS;EAEzD,MAAM,aAAa,KAAK,KAAK,GAAG;AAChC,QAAM,eAAe,WAAW,IAAI;AAEpC,SAAO;GACN,MAAM;GACN;GACA;GACA;WACQ;AACT,MAAI,mBACH,SAAQ,OAAO;;;;;;;;;;AChelB,SAAS,gCAAgC,eAA+B;AACvE,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCAgDwB,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgH9C,SAAS,wBAAwB,aAAqB,SAA6C;CAClG,MAAM,UAAU;CAChB,MAAM,WAAW;AAEjB,WAAU,kCAAkC,YAAY,OAAO,QAAQ;CAGvE,MAAM,cAAwB,EAAE;CAChC,MAAM,eAAyB,EAAE;CACjC,IAAI,MAAM;AACV,SAAQ,MAAM,YAAY,QAAQ,SAAS,IAAI,MAAM,IAAI;AACxD,cAAY,KAAK,IAAI;AACrB,SAAO;;AAER,OAAM;AACN,SAAQ,MAAM,YAAY,QAAQ,UAAU,IAAI,MAAM,IAAI;AACzD,eAAa,KAAK,IAAI;AACtB,SAAO;;AAGR,WACC,mBAAmB,YAAY,OAAO,gBAAgB,aAAa,OAAO,eAC1E;CAGD,MAAM,gBAAgB,QAAwB;EAC7C,IAAI,UAAU,IAAI,MAAM;AACxB,MAAI,QAAQ,WAAW,MAAM,EAAE;AAC9B,aAAU,QAAQ,QAAQ,2BAA2B,GAAG;AACxD,aAAU,QAAQ,QAAQ,cAAc,GAAG;;AAE5C,SAAO,QAAQ,MAAM;;CAItB,MAAM,qBAAqB,YAA6B;AACvD,SACC,QAAQ,SAAS,iBAAiB,IAClC,QAAQ,SAAS,0CAA0C;;AAM7D,MAAK,IAAI,IAAI,YAAY,SAAS,GAAG,KAAK,GAAG,KAAK;EACjD,MAAM,UAAU,YAAY;AAC5B,MAAI,YAAY,OAAW;EAG3B,MAAM,WAAW,aAAa,MAAM,MAAM,IAAI,QAAQ;AACtD,MAAI,aAAa,QAAW;GAE3B,MAAM,UAAU,aADG,YAAY,MAAM,UAAU,IAAgB,SAAS,CAChC;AAExC,aAAU,kBAAkB,EAAE,SAAS,QAAQ,UAAU,SAAS,QAAQ,QAAQ,SAAS;AAC3F,aACC,uBAAuB,QAAQ,MAAM,GAAG,IAAI,GAAG,QAAQ,SAAS,MAAM,QAAQ,GAAG,GACjF;AAED,OAAI,kBAAkB,QAAQ,EAAE;AAC/B,cAAU,2BAA2B,EAAE,iCAAiC;AACxE;;AAGD,OAAI,QAAQ,UAAU,KAAK;AAC1B,cAAU,wBAAwB,EAAE,kBAAkB;AACtD,6BAAyB,QAAQ;AACjC,WAAO;;AAER,aAAU,kBAAkB,EAAE,cAAc,QAAQ,OAAO,SAAS;;;CAMtE,MAAM,cAAc,YAAY,YAAY,SAAS;AACrD,KAAI,gBAAgB,QAEnB;MAAI,CADkB,aAAa,MAAM,MAAM,IAAI,YAAY,EAC3C;AACnB,aAAU,8BAA8B,YAAY,kCAAkC;GAEtF,MAAM,UAAU,aADG,YAAY,MAAM,cAAc,GAAe,CAC1B;AAExC,aAAU,+BAA+B,QAAQ,OAAO,QAAQ;AAChE,aACC,uBAAuB,QAAQ,MAAM,GAAG,IAAI,GAAG,QAAQ,SAAS,MAAM,QAAQ,GAAG,GACjF;AAED,OAAI,CAAC,kBAAkB,QAAQ,IAAI,QAAQ,UAAU,KAAK;AACzD,cAAU,2CAA2C;AACrD,6BAAyB,QAAQ;AACjC,WAAO;;;;AAKV,WAAU,mCAAmC;AAC7C,WAAU,6BAA6B,YAAY,MAAM,KAAK,CAAC,GAAG;AAElE,OAAM,IAAI,MACT,mKAEA;;;;;;AAOF,SAAS,yBAAyB,SAAuB;CAcxD,MAAM,oBAZuB;EAC5B;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,CAE8C,QAAQ,MAAM,QAAQ,SAAS,EAAE,CAAC;AACjF,KAAI,kBAAkB,SAAS,EAC9B,OAAM,IAAI,MACT,8DAA8D,kBAAkB,MAAM,GAAG,EAAE,CAAC,KAAK,KAAK,CAAC,mEAEvG;AAGF,KAAI,QAAQ,SAAS,IACpB,OAAM,IAAI,MACT,yCAAyC,QAAQ,OAAO,mFAExD;AAGF,KAAI,CAAC,QAAQ,WAAW,IAAI,CAC3B,OAAM,IAAI,MACT,+HAEA;;;;;;;;;;;;;AAeH,eAAsB,wBACrB,UACA,UACA,UAAoC,EAAE,EACH;CACnC,MAAM,EAAE,UAAU,OAAO,SAAS,UAAU,oBAAoB;CAGhE,MAAM,CAAC,gBAAgB,eAFR,YAAY,CAEkB,cAAc,MAAM,IAAI,IAAI,EAAE;CAC3E,MAAM,aAAa,YAAY;CAC/B,MAAM,UAAU,SAAS;AAEzB,WAAU,wCAAwC,WAAW;AAC7D,WAAU,cAAc,WAAW;AACnC,WAAU,aAAa,cAAc,UAAU,WAAW,WAAW,YAAY;CAEjF,MAAM,YAAY,aAAa,SAAS;AACxC,WAAU,eAAe,YAAY;CAErC,MAAM,gBAAgB,gBAAgB,SAAS;AAC/C,WAAU,mBAAmB,gBAAgB;CAY7C,MAAM,SAAS,MAAM,aAVsB;EAC1C,QAAQ,gCAAgC,cAAc;EACtD,KAAK;EACL,UAAU;EACV,OAAO;EACP;EACA;EACA;EACA,CAE+C;AAEhD,WAAU,wBAAwB,OAAO,WAAW,MAAM,OAAO,KAAK,OAAO,SAAS;CAEtF,MAAM,mBAAmB,wBAAwB,OAAO,MAAM,QAAQ;AACtE,WAAU,gCAAgC,iBAAiB,OAAO,SAAS;AAE3E,QAAO;EACN;EACA;EACA"}
@@ -196,7 +196,7 @@ const SPARSE_CHECKOUT_DIRS = [
196
196
  * Clone a remote repository to the local repo root.
197
197
  *
198
198
  * @param source - Remote repo source from parseRepoInput()
199
- * @param options - Clone options (shallow, branch, config)
199
+ * @param options - Clone options (branch, config)
200
200
  * @returns The local path where the repo was cloned
201
201
  * @throws RepoExistsError if repo already exists (unless force is true)
202
202
  * @throws GitError if clone fails
@@ -236,7 +236,7 @@ function cleanupEmptyParentDirs(repoPath) {
236
236
  }
237
237
  async function cloneStandard(cloneUrl, repoPath, options) {
238
238
  const args = ["clone"];
239
- if (options.shallow) args.push("--depth", "1");
239
+ if (options.shallow) throw new CloneError("Shallow clones are no longer supported. Use a full clone.");
240
240
  if (options.branch) args.push("--branch", options.branch);
241
241
  args.push(cloneUrl, repoPath);
242
242
  await execGitAsync(args);
@@ -248,7 +248,7 @@ async function cloneSparse(cloneUrl, repoPath, options) {
248
248
  "--no-checkout",
249
249
  "--sparse"
250
250
  ];
251
- if (options.shallow) args.push("--depth", "1");
251
+ if (options.shallow) throw new CloneError("Shallow clones are no longer supported. Use a full clone.");
252
252
  if (options.branch) args.push("--branch", options.branch);
253
253
  args.push(cloneUrl, repoPath);
254
254
  await execGitAsync(args);
@@ -259,18 +259,6 @@ async function cloneSparse(cloneUrl, repoPath, options) {
259
259
  ], repoPath);
260
260
  await execGitAsync(["checkout"], repoPath);
261
261
  }
262
- function isShallowClone(repoPath) {
263
- try {
264
- return execGit(["rev-parse", "--is-shallow-repository"], repoPath) === "true";
265
- } catch {
266
- return false;
267
- }
268
- }
269
- async function unshallowRepo(repoPath) {
270
- if (!isShallowClone(repoPath)) return false;
271
- await execGitAsync(["fetch", "--unshallow"], repoPath);
272
- return true;
273
- }
274
262
  /**
275
263
  * Update a cloned repository by running git fetch and pull.
276
264
  *
@@ -286,11 +274,11 @@ async function updateRepo(qualifiedName, options = {}) {
286
274
  const repoPath = entry.localPath;
287
275
  if (!existsSync(repoPath)) throw new RepoNotFoundError(qualifiedName);
288
276
  const previousSha = getCommitSha(repoPath);
289
- let unshallowed = false;
290
- if (options.unshallow) unshallowed = await unshallowRepo(repoPath);
291
- await execGitAsync(["fetch"], repoPath);
292
- await execGitAsync(["pull", "--ff-only"], repoPath);
293
- const currentSha = getCommitSha(repoPath);
277
+ if (!options.skipFetch) {
278
+ await execGitAsync(["fetch"], repoPath);
279
+ await execGitAsync(["pull", "--ff-only"], repoPath);
280
+ }
281
+ const currentSha = options.skipFetch ? previousSha : getCommitSha(repoPath);
294
282
  upsertGlobalMapEntry(qualifiedName, {
295
283
  ...entry,
296
284
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
@@ -298,8 +286,7 @@ async function updateRepo(qualifiedName, options = {}) {
298
286
  return {
299
287
  updated: previousSha !== currentSha,
300
288
  previousSha,
301
- currentSha,
302
- unshallowed
289
+ currentSha
303
290
  };
304
291
  }
305
292
  async function removeRepo(qualifiedName, options = {}) {
@@ -360,5 +347,5 @@ function getClonedRepoPath(qualifiedName) {
360
347
  }
361
348
 
362
349
  //#endregion
363
- export { upsertGlobalMapEntry as _, cloneRepo as a, getCommitSha as c, listRepos as d, removeRepo as f, removeGlobalMapEntry as g, readGlobalMap as h, RepoNotFoundError as i, isRepoCloned as l, updateRepo as m, GitError as n, getClonedRepoPath as o, unshallowRepo as p, RepoExistsError as r, getCommitDistance as s, CloneError as t, isShallowClone as u, writeGlobalMap as v, writeProjectMap as y };
364
- //# sourceMappingURL=clone-DyLvmbJZ.mjs.map
350
+ export { writeProjectMap as _, cloneRepo as a, getCommitSha as c, removeRepo as d, updateRepo as f, writeGlobalMap as g, upsertGlobalMapEntry as h, RepoNotFoundError as i, isRepoCloned as l, removeGlobalMapEntry as m, GitError as n, getClonedRepoPath as o, readGlobalMap as p, RepoExistsError as r, getCommitDistance as s, CloneError as t, listRepos as u };
351
+ //# sourceMappingURL=clone-Z5ELU2fW.mjs.map