The identical helper function was duplicated across ClaudeAdapter.ts, CursorAdapter.ts, and opencodeRuntime.ts. Consolidate into the shared schemaJson module and import from there.
Unified · Split
| @@ -82,9 +82,9 @@ import { · 81 unmodified lines | |||
| 82 | ProviderAdapterValidationError, | 82 | ProviderAdapterValidationError, |
| 83 | type ProviderAdapterError, | 83 | type ProviderAdapterError, |
| 84 | } from "../Errors.ts"; | 84 | } from "../Errors.ts"; |
| 85 | import { encodeJsonStringForDiagnostics } from "@t3tools/shared/schemaJson"; | ||
| 85 | import { type ClaudeAdapterShape } from "../Services/ClaudeAdapter.ts"; | 86 | import { type ClaudeAdapterShape } from "../Services/ClaudeAdapter.ts"; |
| 86 | import { type EventNdjsonLogger, makeEventNdjsonLogger } from "./EventNdjsonLogger.ts"; | 87 | import { type EventNdjsonLogger, makeEventNdjsonLogger } from "./EventNdjsonLogger.ts"; |
| 87 | const encodeUnknownJsonStringExit = Schema.encodeUnknownExit(Schema.UnknownFromJsonString); | ||
| 88 | const decodeUnknownJsonStringExit = Schema.decodeUnknownExit(Schema.UnknownFromJsonString); | 88 | const decodeUnknownJsonStringExit = Schema.decodeUnknownExit(Schema.UnknownFromJsonString); |
| 89 | 89 | ||
| 90 | const PROVIDER = ProviderDriverKind.make("claudeAgent"); | 90 | const PROVIDER = ProviderDriverKind.make("claudeAgent"); |
| @@ -95,11 +95,6 @@ type ClaudeToolResultStreamKind = Extract< · 4 unmodified lines | |||
| 95 | >; | 95 | >; |
| 96 | type ClaudeSdkEffort = NonNullable<ClaudeQueryOptions["effort"]>; | 96 | type ClaudeSdkEffort = NonNullable<ClaudeQueryOptions["effort"]>; |
| 97 | 97 | ||
| 98 | function encodeJsonStringForDiagnostics(input: unknown): string | undefined { | ||
| 99 | const result = encodeUnknownJsonStringExit(input); | ||
| 100 | return Exit.isSuccess(result) ? result.value : undefined; | ||
| 101 | } | ||
| 102 | |||
| 103 | type PromptQueueItem = | 98 | type PromptQueueItem = |
| 104 | | { | 99 | | { |
| 105 | readonly type: "message"; | 100 | readonly type: "message"; |
| @@ -72,10 +72,10 @@ import { · 71 unmodified lines | |||
| 72 | extractPlanMarkdown, | 72 | extractPlanMarkdown, |
| 73 | extractTodosAsPlan, | 73 | extractTodosAsPlan, |
| 74 | } from "../acp/CursorAcpExtension.ts"; | 74 | } from "../acp/CursorAcpExtension.ts"; |
| 75 | import { encodeJsonStringForDiagnostics } from "@t3tools/shared/schemaJson"; | ||
| 75 | import { type CursorAdapterShape } from "../Services/CursorAdapter.ts"; | 76 | import { type CursorAdapterShape } from "../Services/CursorAdapter.ts"; |
| 76 | import { resolveCursorAcpBaseModelId } from "./CursorProvider.ts"; | 77 | import { resolveCursorAcpBaseModelId } from "./CursorProvider.ts"; |
| 77 | import { type EventNdjsonLogger, makeEventNdjsonLogger } from "./EventNdjsonLogger.ts"; | 78 | import { type EventNdjsonLogger, makeEventNdjsonLogger } from "./EventNdjsonLogger.ts"; |
| 78 | const encodeUnknownJsonStringExit = Schema.encodeUnknownExit(Schema.UnknownFromJsonString); | ||
| 79 | 79 | ||
| 80 | const PROVIDER = ProviderDriverKind.make("cursor"); | 80 | const PROVIDER = ProviderDriverKind.make("cursor"); |
| 81 | const CURSOR_RESUME_VERSION = 1 as const; | 81 | const CURSOR_RESUME_VERSION = 1 as const; |
| @@ -83,11 +83,6 @@ const ACP_PLAN_MODE_ALIASES = ["plan", "architect"]; · 1 unmodified line | |||
| 83 | const ACP_IMPLEMENT_MODE_ALIASES = ["code", "agent", "default", "chat", "implement"]; | 83 | const ACP_IMPLEMENT_MODE_ALIASES = ["code", "agent", "default", "chat", "implement"]; |
| 84 | const ACP_APPROVAL_MODE_ALIASES = ["ask"]; | 84 | const ACP_APPROVAL_MODE_ALIASES = ["ask"]; |
| 85 | 85 | ||
| 86 | function encodeJsonStringForDiagnostics(input: unknown): string | undefined { | ||
| 87 | const result = encodeUnknownJsonStringExit(input); | ||
| 88 | return Exit.isSuccess(result) ? result.value : undefined; | ||
| 89 | } | ||
| 90 | |||
| 91 | export interface CursorAdapterLiveOptions { | 86 | export interface CursorAdapterLiveOptions { |
| 92 | readonly environment?: NodeJS.ProcessEnv; | 87 | readonly environment?: NodeJS.ProcessEnv; |
| 93 | readonly nativeEventLogPath?: string; | 88 | readonly nativeEventLogPath?: string; |
| @@ -24,14 +24,13 @@ import * as P from "effect/Predicate"; · 23 unmodified lines | |||
| 24 | import * as Ref from "effect/Ref"; | 24 | import * as Ref from "effect/Ref"; |
| 25 | import * as Result from "effect/Result"; | 25 | import * as Result from "effect/Result"; |
| 26 | import * as Scope from "effect/Scope"; | 26 | import * as Scope from "effect/Scope"; |
| 27 | import * as Schema from "effect/Schema"; | ||
| 28 | import * as Stream from "effect/Stream"; | 27 | import * as Stream from "effect/Stream"; |
| 29 | import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process"; | 28 | import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process"; |
| 30 | 29 | ||
| 30 | import { encodeJsonStringForDiagnostics } from "@t3tools/shared/schemaJson"; | ||
| 31 | import { isWindowsCommandNotFound } from "../processRunner.ts"; | 31 | import { isWindowsCommandNotFound } from "../processRunner.ts"; |
| 32 | import { collectStreamAsString } from "./providerSnapshot.ts"; | 32 | import { collectStreamAsString } from "./providerSnapshot.ts"; |
| 33 | import * as NetService from "@t3tools/shared/Net"; | 33 | import * as NetService from "@t3tools/shared/Net"; |
| 34 | const encodeUnknownJsonStringExit = Schema.encodeUnknownExit(Schema.UnknownFromJsonString); | ||
| 35 | const OPENCODE_EMPTY_CONFIG_CONTENT = "{}"; | 34 | const OPENCODE_EMPTY_CONFIG_CONTENT = "{}"; |
| 36 | 35 | ||
| 37 | const OPENCODE_SERVER_READY_PREFIX = "opencode server listening"; | 36 | const OPENCODE_SERVER_READY_PREFIX = "opencode server listening"; |
| @@ -58,11 +57,6 @@ export class OpenCodeRuntimeError extends Data.TaggedError(OPENCODE_RUNTIME_ERRO · 20 unmodified lines | |||
| 58 | P.isTagged(u, OPENCODE_RUNTIME_ERROR_TAG); | 57 | P.isTagged(u, OPENCODE_RUNTIME_ERROR_TAG); |
| 59 | } | 58 | } |
| 60 | 59 | ||
| 61 | function encodeJsonStringForDiagnostics(input: unknown): string | undefined { | ||
| 62 | const result = encodeUnknownJsonStringExit(input); | ||
| 63 | return Exit.isSuccess(result) ? result.value : undefined; | ||
| 64 | } | ||
| 65 | |||
| 66 | export function openCodeRuntimeErrorDetail(cause: unknown): string { | 60 | export function openCodeRuntimeErrorDetail(cause: unknown): string { |
| 67 | if (OpenCodeRuntimeError.is(cause)) return cause.detail; | 61 | if (OpenCodeRuntimeError.is(cause)) return cause.detail; |
| 68 | if (cause instanceof Error && cause.message.trim().length > 0) return cause.message.trim(); | 62 | if (cause instanceof Error && cause.message.trim().length > 0) return cause.message.trim(); |
| @@ -84,6 +84,17 @@ export const fromLenientJsonString = new SchemaTransformation.Transformation( · 83 unmodified lines | |||
| 84 | SchemaGetter.stringifyJson(), | 84 | SchemaGetter.stringifyJson(), |
| 85 | ); | 85 | ); |
| 86 | 86 | ||
| 87 | const encodeUnknownJsonStringExit = Schema.encodeUnknownExit(Schema.UnknownFromJsonString); | ||
| 88 | |||
| 89 | /** | ||
| 90 | * Attempt to encode an unknown value to a JSON string for diagnostic output. | ||
| 91 | * Returns `undefined` on encoding failure instead of throwing. | ||
| 92 | */ | ||
| 93 | export function encodeJsonStringForDiagnostics(input: unknown): string | undefined { | ||
| 94 | const result = encodeUnknownJsonStringExit(input); | ||
| 95 | return Exit.isSuccess(result) ? result.value : undefined; | ||
| 96 | } | ||
| 97 | |||
| 87 | export const prettyJsonString = SchemaGetter.parseJson<string>().compose( | 98 | export const prettyJsonString = SchemaGetter.parseJson<string>().compose( |
| 88 | SchemaGetter.stringifyJson({ space: 2 }), | 99 | SchemaGetter.stringifyJson({ space: 2 }), |
| 89 | ); | 100 | ); |