@knpkv/ai-claude 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 knpkv
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,21 @@
1
+ # @knpkv/ai-claude
2
+
3
+ An Effect AI `LanguageModel` backed by a local Claude CLI process.
4
+
5
+ ```ts
6
+ import { NodeServices } from "@effect/platform-node"
7
+ import { Effect } from "effect"
8
+ import { LanguageModel } from "effect/unstable/ai"
9
+ import { model } from "@knpkv/ai-claude"
10
+
11
+ const program = LanguageModel.generateText({ prompt: "Review the current change." }).pipe(
12
+ Effect.provide(model({ cwd: "/absolute/path/to/repository" })),
13
+ Effect.provide(NodeServices.layer)
14
+ )
15
+ ```
16
+
17
+ The default access mode is read-only. It starts Claude in non-interactive plan mode with only read-oriented tools. Set `access: "workspace-write"` to allow `Edit` and `Write`; shell execution remains disabled in both modes.
18
+
19
+ Requests time out after two minutes by default. Output is bounded, prompts are sent over stdin, sessions are not persisted, and Claude's JSON response is schema-decoded before it enters the Effect AI response model. Effect toolkits and file prompt parts are rejected.
20
+
21
+ The child process does not inherit the full host environment. It receives only `PATH`, home/config locations (`HOME`, `USERPROFILE`, `XDG_CONFIG_HOME`, and `CLAUDE_CONFIG_DIR`), and direct Anthropic authentication/gateway settings (`ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, and `ANTHROPIC_BASE_URL`) when those values are present. Other provider credentials and session-scoped variables are not forwarded.
@@ -0,0 +1,24 @@
1
+ import { Schema } from "effect";
2
+ import { AiError } from "effect/unstable/ai";
3
+ declare const ClaudeTransportError_base: Schema.Class<ClaudeTransportError, Schema.TaggedStruct<"ClaudeTransportError", {
4
+ readonly cause: Schema.Defect;
5
+ readonly diagnostic: Schema.String;
6
+ readonly phase: Schema.Literals<readonly ["process", "timeout"]>;
7
+ }>, import("effect/Cause").YieldableError>;
8
+ export declare class ClaudeTransportError extends ClaudeTransportError_base {
9
+ }
10
+ declare const ClaudeFailureCause_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
11
+ readonly _tag: "ClaudeFailureCause";
12
+ } & Readonly<A>;
13
+ export declare class ClaudeFailureCause extends ClaudeFailureCause_base<{
14
+ readonly reason: string;
15
+ }> {
16
+ }
17
+ export declare const invalidInput: (description: string, method: string) => AiError.AiError;
18
+ export declare const invalidOutput: (description: string, method: string) => AiError.AiError;
19
+ export declare const configurationFailure: (cause: unknown, method: string) => AiError.AiError;
20
+ export declare const unsupportedSchema: (cause: unknown, method: string) => AiError.AiError;
21
+ export declare const transportFailure: (phase: ClaudeTransportError["phase"], diagnostic: string, cause: unknown) => ClaudeTransportError;
22
+ export declare const transportToAiError: (error: ClaudeTransportError, method: string) => AiError.AiError;
23
+ export {};
24
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,MAAM,EAAE,MAAM,QAAQ,CAAA;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;;;;;;AAI5C,qBAAa,oBAAqB,SAAQ,yBAOzC;CAAG;;;;AAEJ,qBAAa,kBAAmB,SAAQ,wBAAuC;IAC7E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB,CAAC;CAAG;AAEL,eAAO,MAAM,YAAY,GAAI,aAAa,MAAM,EAAE,QAAQ,MAAM,KAAG,OAAO,CAAC,OAKvE,CAAA;AAEJ,eAAO,MAAM,aAAa,GAAI,aAAa,MAAM,EAAE,QAAQ,MAAM,KAAG,OAAO,CAAC,OAKxE,CAAA;AAEJ,eAAO,MAAM,oBAAoB,GAAI,OAAO,OAAO,EAAE,QAAQ,MAAM,KAAG,OAAO,CAAC,OAa1E,CAAA;AAEJ,eAAO,MAAM,iBAAiB,GAAI,OAAO,OAAO,EAAE,QAAQ,MAAM,KAAG,OAAO,CAAC,OAOvE,CAAA;AAEJ,eAAO,MAAM,gBAAgB,GAC3B,OAAO,oBAAoB,CAAC,OAAO,CAAC,EACpC,YAAY,MAAM,EAClB,OAAO,OAAO,KACb,oBAA8E,CAAA;AAEjF,eAAO,MAAM,kBAAkB,GAAI,OAAO,oBAAoB,EAAE,QAAQ,MAAM,KAAG,OAAO,CAAC,OAarF,CAAA"}
package/dist/errors.js ADDED
@@ -0,0 +1,56 @@
1
+ import { Data, Predicate, Schema } from "effect";
2
+ import { AiError } from "effect/unstable/ai";
3
+ const MODULE = "ClaudeCliLanguageModel";
4
+ export class ClaudeTransportError extends Schema.TaggedErrorClass()("ClaudeTransportError", {
5
+ cause: Schema.Defect(),
6
+ diagnostic: Schema.String,
7
+ phase: Schema.Literals(["process", "timeout"])
8
+ }) {
9
+ }
10
+ export class ClaudeFailureCause extends Data.TaggedError("ClaudeFailureCause") {
11
+ }
12
+ export const invalidInput = (description, method) => AiError.make({
13
+ module: MODULE,
14
+ method,
15
+ reason: new AiError.InvalidUserInputError({ description })
16
+ });
17
+ export const invalidOutput = (description, method) => AiError.make({
18
+ module: MODULE,
19
+ method,
20
+ reason: new AiError.InvalidOutputError({ description })
21
+ });
22
+ export const configurationFailure = (cause, method) => AiError.make({
23
+ module: MODULE,
24
+ method,
25
+ reason: new AiError.InternalProviderError({
26
+ description: "Unable to read the reviewed Claude CLI environment",
27
+ metadata: {
28
+ "claude-cli": {
29
+ cause: Predicate.isError(cause) ? cause.name : "typed-cause",
30
+ phase: "configuration"
31
+ }
32
+ }
33
+ })
34
+ });
35
+ export const unsupportedSchema = (cause, method) => AiError.make({
36
+ module: MODULE,
37
+ method,
38
+ reason: new AiError.UnsupportedSchemaError({
39
+ description: Predicate.isError(cause) ? cause.message : "Claude CLI cannot represent the requested schema"
40
+ })
41
+ });
42
+ export const transportFailure = (phase, diagnostic, cause) => new ClaudeTransportError({ cause, diagnostic, phase });
43
+ export const transportToAiError = (error, method) => AiError.make({
44
+ module: MODULE,
45
+ method,
46
+ reason: new AiError.InternalProviderError({
47
+ description: `Claude CLI ${error.phase} failure: ${error.diagnostic}`,
48
+ metadata: {
49
+ "claude-cli": {
50
+ cause: Predicate.isError(error.cause) ? error.cause.name : "typed-cause",
51
+ phase: error.phase
52
+ }
53
+ }
54
+ })
55
+ });
56
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Effect AI adapter for the local Claude CLI.
3
+ *
4
+ * @since 0.0.0
5
+ */
6
+ export { model } from "./model.js";
7
+ export type { ClaudeModelOptions } from "./model.js";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAClC,YAAY,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Effect AI adapter for the local Claude CLI.
3
+ *
4
+ * @since 0.0.0
5
+ */
6
+ export { model } from "./model.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA"}
@@ -0,0 +1,23 @@
1
+ import type { Duration } from "effect";
2
+ import { LanguageModel, Model } from "effect/unstable/ai";
3
+ import { ChildProcessSpawner } from "effect/unstable/process";
4
+ /** Options for a local Claude CLI-backed Effect AI model. */
5
+ export interface ClaudeModelOptions {
6
+ /** Working directory exposed to Claude. */
7
+ readonly cwd: string;
8
+ /** Claude executable name or absolute path. Defaults to `claude`. */
9
+ readonly executable?: string;
10
+ /** Claude model identifier. Defaults to the CLI-configured model. */
11
+ readonly model?: string;
12
+ /** Workspace access granted to Claude. Defaults to `read-only`. */
13
+ readonly access?: "read-only" | "workspace-write";
14
+ /** Maximum duration of one CLI invocation. Defaults to two minutes. */
15
+ readonly timeout?: Duration.Input;
16
+ /** Maximum captured stdout bytes. Defaults to 4 MiB. */
17
+ readonly maxOutputBytes?: number;
18
+ /** Maximum captured stderr bytes. Defaults to 256 KiB. */
19
+ readonly maxStderrBytes?: number;
20
+ }
21
+ /** Creates an Effect AI model backed by a non-interactive local Claude CLI process. */
22
+ export declare const model: (options: ClaudeModelOptions) => Model.Model<"claude-cli", LanguageModel.LanguageModel, ChildProcessSpawner.ChildProcessSpawner>;
23
+ //# sourceMappingURL=model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AACtC,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAEzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAwC7D,6DAA6D;AAC7D,MAAM,WAAW,kBAAkB;IACjC,2CAA2C;IAC3C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,qEAAqE;IACrE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,qEAAqE;IACrE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,mEAAmE;IACnE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,iBAAiB,CAAA;IACjD,uEAAuE;IACvE,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAA;IACjC,wDAAwD;IACxD,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAA;IAChC,0DAA0D;IAC1D,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CACjC;AAgID,uFAAuF;AACvF,eAAO,MAAM,KAAK,GAChB,SAAS,kBAAkB,KAC1B,KAAK,CAAC,KAAK,CAAC,YAAY,EAAE,aAAa,CAAC,aAAa,EAAE,mBAAmB,CAAC,mBAAmB,CAK9F,CAAA"}
package/dist/model.js ADDED
@@ -0,0 +1,134 @@
1
+ import { Config, Effect, Layer, Option, Schema, Stream } from "effect";
2
+ import { LanguageModel, Model } from "effect/unstable/ai";
3
+ import { ChildProcessSpawner } from "effect/unstable/process";
4
+ import { configurationFailure, invalidInput, invalidOutput, unsupportedSchema } from "./errors.js";
5
+ import { renderPrompt } from "./prompt.js";
6
+ import { runClaude } from "./runner.js";
7
+ const DEFAULT_MAX_OUTPUT_BYTES = 4 * 1024 * 1024;
8
+ const DEFAULT_MAX_STDERR_BYTES = 256 * 1024;
9
+ const DEFAULT_TIMEOUT = "2 minutes";
10
+ const STREAM_TEXT_ID = "claude-cli-output";
11
+ const JsonString = Schema.fromJsonString(Schema.Json);
12
+ const optionalEnvironmentValue = (name) => Config.option(Config.string(name));
13
+ const childEnvironment = Config.all({
14
+ anthropicApiKey: optionalEnvironmentValue("ANTHROPIC_API_KEY"),
15
+ anthropicAuthToken: optionalEnvironmentValue("ANTHROPIC_AUTH_TOKEN"),
16
+ anthropicBaseUrl: optionalEnvironmentValue("ANTHROPIC_BASE_URL"),
17
+ claudeConfigDirectory: optionalEnvironmentValue("CLAUDE_CONFIG_DIR"),
18
+ home: optionalEnvironmentValue("HOME"),
19
+ path: optionalEnvironmentValue("PATH"),
20
+ userProfile: optionalEnvironmentValue("USERPROFILE"),
21
+ xdgConfigHome: optionalEnvironmentValue("XDG_CONFIG_HOME")
22
+ }).pipe(Config.map((configured) => ({
23
+ ...(Option.isSome(configured.anthropicApiKey) ? { ANTHROPIC_API_KEY: configured.anthropicApiKey.value } : {}),
24
+ ...(Option.isSome(configured.anthropicAuthToken)
25
+ ? { ANTHROPIC_AUTH_TOKEN: configured.anthropicAuthToken.value }
26
+ : {}),
27
+ ...(Option.isSome(configured.anthropicBaseUrl) ? { ANTHROPIC_BASE_URL: configured.anthropicBaseUrl.value } : {}),
28
+ ...(Option.isSome(configured.claudeConfigDirectory)
29
+ ? { CLAUDE_CONFIG_DIR: configured.claudeConfigDirectory.value }
30
+ : {}),
31
+ ...(Option.isSome(configured.home) ? { HOME: configured.home.value } : {}),
32
+ ...(Option.isSome(configured.path) ? { PATH: configured.path.value } : {}),
33
+ ...(Option.isSome(configured.userProfile) ? { USERPROFILE: configured.userProfile.value } : {}),
34
+ ...(Option.isSome(configured.xdgConfigHome) ? { XDG_CONFIG_HOME: configured.xdgConfigHome.value } : {})
35
+ })));
36
+ const usageFrom = (usage) => ({
37
+ inputTokens: {
38
+ cacheRead: usage?.cache_read_input_tokens,
39
+ cacheWrite: usage?.cache_creation_input_tokens,
40
+ total: usage === undefined
41
+ ? undefined
42
+ : (usage.input_tokens ?? 0) +
43
+ (usage.cache_creation_input_tokens ?? 0) +
44
+ (usage.cache_read_input_tokens ?? 0),
45
+ uncached: usage?.input_tokens
46
+ },
47
+ outputTokens: {
48
+ reasoning: undefined,
49
+ text: usage?.output_tokens,
50
+ total: usage?.output_tokens
51
+ }
52
+ });
53
+ const encodeJson = (value, method) => Schema.encodeUnknownEffect(JsonString)(value).pipe(Effect.mapError((cause) => unsupportedSchema(cause, method)));
54
+ const schemaArgument = (options, method) => {
55
+ if (options.responseFormat.type === "text")
56
+ return Effect.succeed(undefined);
57
+ const responseSchema = options.responseFormat.schema;
58
+ return Effect.try({
59
+ try: () => Schema.toJsonSchemaDocument(responseSchema),
60
+ catch: (cause) => unsupportedSchema(cause, method)
61
+ }).pipe(Effect.flatMap((document) => encodeJson({
62
+ $defs: document.definitions,
63
+ $schema: "https://json-schema.org/draft/2020-12/schema",
64
+ ...document.schema
65
+ }, method)));
66
+ };
67
+ const normalizeOptions = Effect.fn("ClaudeCliLanguageModel.normalizeOptions")(function* (options, method) {
68
+ const normalized = {
69
+ access: options.access ?? "read-only",
70
+ cwd: options.cwd,
71
+ environment: yield* childEnvironment.pipe(Effect.mapError((cause) => configurationFailure(cause, method))),
72
+ executable: options.executable ?? "claude",
73
+ maxOutputBytes: options.maxOutputBytes ?? DEFAULT_MAX_OUTPUT_BYTES,
74
+ maxStderrBytes: options.maxStderrBytes ?? DEFAULT_MAX_STDERR_BYTES,
75
+ model: options.model,
76
+ timeout: options.timeout ?? DEFAULT_TIMEOUT
77
+ };
78
+ if (normalized.cwd.trim().length === 0) {
79
+ return yield* invalidInput("cwd must not be empty", method);
80
+ }
81
+ if (!Number.isSafeInteger(normalized.maxOutputBytes) || normalized.maxOutputBytes <= 0) {
82
+ return yield* invalidInput("maxOutputBytes must be a positive safe integer", method);
83
+ }
84
+ if (!Number.isSafeInteger(normalized.maxStderrBytes) || normalized.maxStderrBytes <= 0) {
85
+ return yield* invalidInput("maxStderrBytes must be a positive safe integer", method);
86
+ }
87
+ return normalized;
88
+ });
89
+ const resultText = (result, method) => {
90
+ if (result.structured_output !== undefined)
91
+ return encodeJson(result.structured_output, method);
92
+ if (result.result !== undefined)
93
+ return Effect.succeed(result.result);
94
+ return Effect.fail(invalidOutput("Claude CLI result contained no output", method));
95
+ };
96
+ const makeService = Effect.fn("ClaudeCliLanguageModel.make")(function* (options) {
97
+ const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
98
+ return yield* LanguageModel.make({
99
+ generateText: Effect.fn("ClaudeCliLanguageModel.generateText")(function* (providerOptions) {
100
+ const prompt = yield* renderPrompt(providerOptions, "generateText");
101
+ const jsonSchema = yield* schemaArgument(providerOptions, "generateText");
102
+ const normalized = yield* normalizeOptions(options, "generateText");
103
+ const result = yield* runClaude({ ...normalized, jsonSchema, prompt }, "generateText", spawner);
104
+ const text = yield* resultText(result, "generateText");
105
+ const parts = [
106
+ { type: "text", text },
107
+ { type: "finish", reason: "stop", response: undefined, usage: usageFrom(result.usage) }
108
+ ];
109
+ return parts;
110
+ }),
111
+ streamText: (providerOptions) => Stream.unwrap(Effect.gen(function* () {
112
+ const prompt = yield* renderPrompt(providerOptions, "streamText");
113
+ const jsonSchema = yield* schemaArgument(providerOptions, "streamText");
114
+ const normalized = yield* normalizeOptions(options, "streamText");
115
+ const result = yield* runClaude({ ...normalized, jsonSchema, prompt }, "streamText", spawner);
116
+ const text = yield* resultText(result, "streamText");
117
+ const parts = [
118
+ { type: "text-start", id: STREAM_TEXT_ID },
119
+ { type: "text-delta", id: STREAM_TEXT_ID, delta: text },
120
+ { type: "text-end", id: STREAM_TEXT_ID },
121
+ {
122
+ type: "finish",
123
+ reason: "stop",
124
+ response: undefined,
125
+ usage: usageFrom(result.usage)
126
+ }
127
+ ];
128
+ return Stream.fromIterable(parts);
129
+ }))
130
+ });
131
+ });
132
+ /** Creates an Effect AI model backed by a non-interactive local Claude CLI process. */
133
+ export const model = (options) => Model.make("claude-cli", options.model ?? "default", Layer.effect(LanguageModel.LanguageModel, makeService(options)));
134
+ //# sourceMappingURL=model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAEtE,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAEzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAC7D,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAClG,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAEvC,MAAM,wBAAwB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAA;AAChD,MAAM,wBAAwB,GAAG,GAAG,GAAG,IAAI,CAAA;AAC3C,MAAM,eAAe,GAAG,WAAW,CAAA;AACnC,MAAM,cAAc,GAAG,mBAAmB,CAAA;AAC1C,MAAM,UAAU,GAAG,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;AAErD,MAAM,wBAAwB,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAA;AAErF,MAAM,gBAAgB,GAAG,MAAM,CAAC,GAAG,CAAC;IAClC,eAAe,EAAE,wBAAwB,CAAC,mBAAmB,CAAC;IAC9D,kBAAkB,EAAE,wBAAwB,CAAC,sBAAsB,CAAC;IACpE,gBAAgB,EAAE,wBAAwB,CAAC,oBAAoB,CAAC;IAChE,qBAAqB,EAAE,wBAAwB,CAAC,mBAAmB,CAAC;IACpE,IAAI,EAAE,wBAAwB,CAAC,MAAM,CAAC;IACtC,IAAI,EAAE,wBAAwB,CAAC,MAAM,CAAC;IACtC,WAAW,EAAE,wBAAwB,CAAC,aAAa,CAAC;IACpD,aAAa,EAAE,wBAAwB,CAAC,iBAAiB,CAAC;CAC3D,CAAC,CAAC,IAAI,CACL,MAAM,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAC1B,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,UAAU,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7G,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,kBAAkB,CAAC;QAC9C,CAAC,CAAC,EAAE,oBAAoB,EAAE,UAAU,CAAC,kBAAkB,CAAC,KAAK,EAAE;QAC/D,CAAC,CAAC,EAAE,CAAC;IACP,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,UAAU,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAChH,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,qBAAqB,CAAC;QACjD,CAAC,CAAC,EAAE,iBAAiB,EAAE,UAAU,CAAC,qBAAqB,CAAC,KAAK,EAAE;QAC/D,CAAC,CAAC,EAAE,CAAC;IACP,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1E,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1E,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/F,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,UAAU,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;CACxG,CAAC,CAAC,CACJ,CAAA;AAoBD,MAAM,SAAS,GAAG,CAAC,KAA4B,EAAiC,EAAE,CAAC,CAAC;IAClF,WAAW,EAAE;QACX,SAAS,EAAE,KAAK,EAAE,uBAAuB;QACzC,UAAU,EAAE,KAAK,EAAE,2BAA2B;QAC9C,KAAK,EAAE,KAAK,KAAK,SAAS;YACxB,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,IAAI,CAAC,CAAC;gBACzB,CAAC,KAAK,CAAC,2BAA2B,IAAI,CAAC,CAAC;gBACxC,CAAC,KAAK,CAAC,uBAAuB,IAAI,CAAC,CAAC;QACxC,QAAQ,EAAE,KAAK,EAAE,YAAY;KAC9B;IACD,YAAY,EAAE;QACZ,SAAS,EAAE,SAAS;QACpB,IAAI,EAAE,KAAK,EAAE,aAAa;QAC1B,KAAK,EAAE,KAAK,EAAE,aAAa;KAC5B;CACF,CAAC,CAAA;AAEF,MAAM,UAAU,GAAG,CAAC,KAAc,EAAE,MAAc,EAA0C,EAAE,CAC5F,MAAM,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAChD,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,iBAAiB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAC7D,CAAA;AAEH,MAAM,cAAc,GAAG,CACrB,OAAsC,EACtC,MAAc,EACsC,EAAE;IACtD,IAAI,OAAO,CAAC,cAAc,CAAC,IAAI,KAAK,MAAM;QAAE,OAAO,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IAC5E,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,MAAM,CAAA;IACpD,OAAO,MAAM,CAAC,GAAG,CAAC;QAChB,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,cAAc,CAAC;QACtD,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,iBAAiB,CAAC,KAAK,EAAE,MAAM,CAAC;KACnD,CAAC,CAAC,IAAI,CACL,MAAM,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAC1B,UAAU,CAAC;QACT,KAAK,EAAE,QAAQ,CAAC,WAAW;QAC3B,OAAO,EAAE,8CAA8C;QACvD,GAAG,QAAQ,CAAC,MAAM;KACnB,EAAE,MAAM,CAAC,CACX,CACF,CAAA;AACH,CAAC,CAAA;AAaD,MAAM,gBAAgB,GAAG,MAAM,CAAC,EAAE,CAAC,yCAAyC,CAAC,CAAC,QAAQ,CAAC,EACrF,OAA2B,EAC3B,MAAc;IAEd,MAAM,UAAU,GAAsB;QACpC,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,WAAW;QACrC,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,WAAW,EAAE,KAAK,CAAC,CAAC,gBAAgB,CAAC,IAAI,CACvC,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,oBAAoB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAChE;QACD,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,QAAQ;QAC1C,cAAc,EAAE,OAAO,CAAC,cAAc,IAAI,wBAAwB;QAClE,cAAc,EAAE,OAAO,CAAC,cAAc,IAAI,wBAAwB;QAClE,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,eAAe;KAC5C,CAAA;IACD,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvC,OAAO,KAAK,CAAC,CAAC,YAAY,CAAC,uBAAuB,EAAE,MAAM,CAAC,CAAA;IAC7D,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,cAAc,CAAC,IAAI,UAAU,CAAC,cAAc,IAAI,CAAC,EAAE,CAAC;QACvF,OAAO,KAAK,CAAC,CAAC,YAAY,CAAC,gDAAgD,EAAE,MAAM,CAAC,CAAA;IACtF,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,cAAc,CAAC,IAAI,UAAU,CAAC,cAAc,IAAI,CAAC,EAAE,CAAC;QACvF,OAAO,KAAK,CAAC,CAAC,YAAY,CAAC,gDAAgD,EAAE,MAAM,CAAC,CAAA;IACtF,CAAC;IACD,OAAO,UAAU,CAAA;AACnB,CAAC,CAAC,CAAA;AAEF,MAAM,UAAU,GAAG,CAAC,MAAoB,EAAE,MAAc,EAA0C,EAAE;IAClG,IAAI,MAAM,CAAC,iBAAiB,KAAK,SAAS;QAAE,OAAO,UAAU,CAAC,MAAM,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAA;IAC/F,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IACrE,OAAO,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,uCAAuC,EAAE,MAAM,CAAC,CAAC,CAAA;AACpF,CAAC,CAAA;AAED,MAAM,WAAW,GAAG,MAAM,CAAC,EAAE,CAAC,6BAA6B,CAAC,CAAC,QAAQ,CAAC,EAAC,OAA2B;IAChG,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,mBAAmB,CAAC,mBAAmB,CAAA;IAC9D,OAAO,KAAK,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC;QAC/B,YAAY,EAAE,MAAM,CAAC,EAAE,CAAC,qCAAqC,CAAC,CAAC,QAAQ,CAAC,EAAC,eAAe;YACtF,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,YAAY,CAAC,eAAe,EAAE,cAAc,CAAC,CAAA;YACnE,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,cAAc,CAAC,eAAe,EAAE,cAAc,CAAC,CAAA;YACzE,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,gBAAgB,CAAC,OAAO,EAAE,cAAc,CAAC,CAAA;YACnE,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC,EAAE,GAAG,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,cAAc,EAAE,OAAO,CAAC,CAAA;YAC/F,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,cAAc,CAAC,CAAA;YACtD,MAAM,KAAK,GAAgC;gBACzC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;gBACtB,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;aACxF,CAAA;YACD,OAAO,KAAK,CAAA;QACd,CAAC,CAAC;QACF,UAAU,EAAE,CAAC,eAAe,EAAE,EAAE,CAC9B,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAChC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,YAAY,CAAC,eAAe,EAAE,YAAY,CAAC,CAAA;YACjE,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,cAAc,CAAC,eAAe,EAAE,YAAY,CAAC,CAAA;YACvE,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,gBAAgB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAA;YACjE,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC,EAAE,GAAG,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,YAAY,EAAE,OAAO,CAAC,CAAA;YAC7F,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;YACpD,MAAM,KAAK,GAAsC;gBAC/C,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,cAAc,EAAE;gBAC1C,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,IAAI,EAAE;gBACvD,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,cAAc,EAAE;gBACxC;oBACE,IAAI,EAAE,QAAQ;oBACd,MAAM,EAAE,MAAM;oBACd,QAAQ,EAAE,SAAS;oBACnB,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC;iBAC/B;aACF,CAAA;YACD,OAAO,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAA;QACnC,CAAC,CAAC,CAAC;KACN,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,uFAAuF;AACvF,MAAM,CAAC,MAAM,KAAK,GAAG,CACnB,OAA2B,EACsE,EAAE,CACnG,KAAK,CAAC,IAAI,CACR,YAAY,EACZ,OAAO,CAAC,KAAK,IAAI,SAAS,EAC1B,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,aAAa,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC,CAChE,CAAA"}
@@ -0,0 +1,5 @@
1
+ import { Effect } from "effect";
2
+ import type { LanguageModel } from "effect/unstable/ai";
3
+ import { invalidInput } from "./errors.js";
4
+ export declare const renderPrompt: (options: LanguageModel.ProviderOptions, method: string) => Effect.Effect<string, ReturnType<typeof invalidInput>>;
5
+ //# sourceMappingURL=prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../src/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC/B,OAAO,KAAK,EAAE,aAAa,EAAU,MAAM,oBAAoB,CAAA;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AA0B1C,eAAO,MAAM,YAAY,GACvB,SAAS,aAAa,CAAC,eAAe,EACtC,QAAQ,MAAM,KACb,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAsBpD,CAAA"}
package/dist/prompt.js ADDED
@@ -0,0 +1,38 @@
1
+ import { Effect } from "effect";
2
+ import { invalidInput } from "./errors.js";
3
+ const renderTextParts = (parts, method) => Effect.gen(function* () {
4
+ const rendered = [];
5
+ for (const part of parts) {
6
+ switch (part.type) {
7
+ case "reasoning":
8
+ case "text": {
9
+ rendered.push(part.text);
10
+ break;
11
+ }
12
+ default: {
13
+ return yield* invalidInput(`Claude CLI does not support ${part.type} prompt parts`, method);
14
+ }
15
+ }
16
+ }
17
+ return rendered.join("\n");
18
+ });
19
+ export const renderPrompt = (options, method) => Effect.gen(function* () {
20
+ if (options.tools.length > 0) {
21
+ return yield* invalidInput("Effect AI toolkits are not supported by the Claude CLI adapter", method);
22
+ }
23
+ const messages = [];
24
+ for (const message of options.prompt.content) {
25
+ if (message.role === "system") {
26
+ messages.push(`System:\n${message.content}`);
27
+ continue;
28
+ }
29
+ if (message.role === "tool") {
30
+ return yield* invalidInput("Effect AI tool messages are not supported by the Claude CLI adapter", method);
31
+ }
32
+ const content = yield* renderTextParts(message.content, method);
33
+ const role = message.role === "assistant" ? "Assistant" : "User";
34
+ messages.push(`${role}:\n${content}`);
35
+ }
36
+ return messages.join("\n\n");
37
+ });
38
+ //# sourceMappingURL=prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../src/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE/B,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C,MAAM,eAAe,GAAG,CACtB,KAAiC,EACjC,MAAc,EAC0C,EAAE,CAC1D,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,QAAQ,GAAkB,EAAE,CAAA;IAClC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;YAClB,KAAK,WAAW,CAAC;YACjB,KAAK,MAAM,CAAC,CAAC,CAAC;gBACZ,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;gBACxB,MAAK;YACP,CAAC;YACD,OAAO,CAAC,CAAC,CAAC;gBACR,OAAO,KAAK,CAAC,CAAC,YAAY,CACxB,+BAA+B,IAAI,CAAC,IAAI,eAAe,EACvD,MAAM,CACP,CAAA;YACH,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAC5B,CAAC,CAAC,CAAA;AAEJ,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,OAAsC,EACtC,MAAc,EAC0C,EAAE,CAC1D,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,OAAO,KAAK,CAAC,CAAC,YAAY,CAAC,gEAAgE,EAAE,MAAM,CAAC,CAAA;IACtG,CAAC;IAED,MAAM,QAAQ,GAAkB,EAAE,CAAA;IAClC,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QAC7C,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC9B,QAAQ,CAAC,IAAI,CAAC,YAAY,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;YAC5C,SAAQ;QACV,CAAC;QACD,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC5B,OAAO,KAAK,CAAC,CAAC,YAAY,CAAC,qEAAqE,EAAE,MAAM,CAAC,CAAA;QAC3G,CAAC;QAED,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;QAC/D,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAA;QAChE,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,MAAM,OAAO,EAAE,CAAC,CAAA;IACvC,CAAC;IAED,OAAO,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;AAC9B,CAAC,CAAC,CAAA"}
@@ -0,0 +1,19 @@
1
+ import { Effect, Schema } from "effect";
2
+ import { invalidOutput } from "./errors.js";
3
+ declare const ClaudeResult: Schema.Struct<{
4
+ readonly type: Schema.Literal<"result">;
5
+ readonly subtype: Schema.String;
6
+ readonly is_error: Schema.Boolean;
7
+ readonly result: Schema.optional<Schema.String>;
8
+ readonly structured_output: Schema.optional<Schema.Unknown>;
9
+ readonly usage: Schema.optional<Schema.Struct<{
10
+ readonly input_tokens: Schema.optional<Schema.Int>;
11
+ readonly output_tokens: Schema.optional<Schema.Int>;
12
+ readonly cache_creation_input_tokens: Schema.optional<Schema.Int>;
13
+ readonly cache_read_input_tokens: Schema.optional<Schema.Int>;
14
+ }>>;
15
+ }>;
16
+ export type ClaudeResult = typeof ClaudeResult.Type;
17
+ export declare const decodeClaudeOutput: (stdout: string, method: string) => Effect.Effect<ClaudeResult, ReturnType<typeof invalidOutput>>;
18
+ export {};
19
+ //# sourceMappingURL=protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAW3C,QAAA,MAAM,YAAY;;;;;;;;;;;;EAOhB,CAAA;AAEF,MAAM,MAAM,YAAY,GAAG,OAAO,YAAY,CAAC,IAAI,CAAA;AAInD,eAAO,MAAM,kBAAkB,GAC7B,QAAQ,MAAM,EACd,QAAQ,MAAM,KACb,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAc5D,CAAA"}
@@ -0,0 +1,28 @@
1
+ import { Effect, Schema } from "effect";
2
+ import { invalidOutput } from "./errors.js";
3
+ const TokenCount = Schema.Int.check(Schema.isGreaterThanOrEqualTo(0));
4
+ const ClaudeUsage = Schema.Struct({
5
+ input_tokens: Schema.optional(TokenCount),
6
+ output_tokens: Schema.optional(TokenCount),
7
+ cache_creation_input_tokens: Schema.optional(TokenCount),
8
+ cache_read_input_tokens: Schema.optional(TokenCount)
9
+ });
10
+ const ClaudeResult = Schema.Struct({
11
+ type: Schema.Literal("result"),
12
+ subtype: Schema.String,
13
+ is_error: Schema.Boolean,
14
+ result: Schema.optional(Schema.String),
15
+ structured_output: Schema.optional(Schema.Unknown),
16
+ usage: Schema.optional(ClaudeUsage)
17
+ });
18
+ const decodeResult = Schema.decodeUnknownEffect(Schema.fromJsonString(ClaudeResult));
19
+ export const decodeClaudeOutput = (stdout, method) => decodeResult(stdout.trim()).pipe(Effect.catch(() => {
20
+ const nonEmptyLines = stdout.split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
21
+ return Effect.forEach(nonEmptyLines, (line) => decodeResult(line)).pipe(Effect.flatMap((events) => {
22
+ const result = events.length === 0 ? undefined : events[events.length - 1];
23
+ return result === undefined
24
+ ? Effect.fail(invalidOutput("Claude CLI emitted no result event", method))
25
+ : Effect.succeed(result);
26
+ }), Effect.mapError(() => invalidOutput("Claude CLI emitted malformed JSON output", method)));
27
+ }));
28
+ //# sourceMappingURL=protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE3C,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAA;AAErE,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC;IAChC,YAAY,EAAE,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC;IACzC,aAAa,EAAE,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC;IAC1C,2BAA2B,EAAE,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC;IACxD,uBAAuB,EAAE,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC;CACrD,CAAC,CAAA;AAEF,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC,MAAM;IACtB,QAAQ,EAAE,MAAM,CAAC,OAAO;IACxB,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC;IACtC,iBAAiB,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC;IAClD,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC;CACpC,CAAC,CAAA;AAIF,MAAM,YAAY,GAAG,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,CAAA;AAEpF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,MAAc,EACd,MAAc,EACiD,EAAE,CACjE,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAC9B,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE;IAChB,MAAM,aAAa,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IACrG,OAAO,MAAM,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CACrE,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;QACxB,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QAC1E,OAAO,MAAM,KAAK,SAAS;YACzB,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,oCAAoC,EAAE,MAAM,CAAC,CAAC;YAC1E,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IAC5B,CAAC,CAAC,EACF,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,0CAA0C,EAAE,MAAM,CAAC,CAAC,CACzF,CAAA;AACH,CAAC,CAAC,CACH,CAAA"}
@@ -0,0 +1,45 @@
1
+ import { Effect, Stream } from "effect";
2
+ import type { Duration } from "effect";
3
+ import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process";
4
+ interface RunOptions {
5
+ readonly access: "read-only" | "workspace-write";
6
+ readonly cwd: string;
7
+ readonly environment: Readonly<Record<string, string>>;
8
+ readonly executable: string;
9
+ readonly jsonSchema: string | undefined;
10
+ readonly maxOutputBytes: number;
11
+ readonly maxStderrBytes: number;
12
+ readonly model: string | undefined;
13
+ readonly prompt: string;
14
+ readonly timeout: Duration.Input;
15
+ }
16
+ export declare const runClaude: (options: RunOptions, method: string, spawner: {
17
+ spawn(command: ChildProcess.Command): Effect.Effect<ChildProcessSpawner.ChildProcessHandle, import("effect/PlatformError").PlatformError, import("effect/Scope").Scope>;
18
+ exitCode(command: ChildProcess.Command): Effect.Effect<ChildProcessSpawner.ExitCode, import("effect/PlatformError").PlatformError>;
19
+ streamString(command: ChildProcess.Command, options?: {
20
+ readonly includeStderr?: boolean | undefined;
21
+ }): Stream.Stream<string, import("effect/PlatformError").PlatformError>;
22
+ streamLines(command: ChildProcess.Command, options?: {
23
+ readonly includeStderr?: boolean | undefined;
24
+ }): Stream.Stream<string, import("effect/PlatformError").PlatformError>;
25
+ lines(command: ChildProcess.Command, options?: {
26
+ readonly includeStderr?: boolean | undefined;
27
+ }): Effect.Effect<Array<string>, import("effect/PlatformError").PlatformError>;
28
+ string(command: ChildProcess.Command, options?: {
29
+ readonly includeStderr?: boolean | undefined;
30
+ }): Effect.Effect<string, import("effect/PlatformError").PlatformError>;
31
+ }) => Effect.Effect<{
32
+ readonly type: "result";
33
+ readonly subtype: string;
34
+ readonly is_error: boolean;
35
+ readonly usage?: {
36
+ readonly input_tokens?: number | undefined;
37
+ readonly output_tokens?: number | undefined;
38
+ readonly cache_creation_input_tokens?: number | undefined;
39
+ readonly cache_read_input_tokens?: number | undefined;
40
+ } | undefined;
41
+ readonly result?: string | undefined;
42
+ readonly structured_output?: unknown;
43
+ }, import("effect/unstable/ai/AiError").AiError, never>;
44
+ export {};
45
+ //# sourceMappingURL=runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,MAAM,EAAa,MAAM,EAAE,MAAM,QAAQ,CAAA;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AACtC,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAK3E,UAAU,UAAU;IAClB,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,iBAAiB,CAAA;IAChD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IACtD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;IACvC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAA;CACjC;AA6FD,eAAO,MAAM,SAAS;;;;8BAsDy1C,CAAC;;;8BAAgS,CAAC;;;8BAAyP,CAAC;;;8BAAyO,CAAC;;;;;;;;;;;;;;uDADnnE,CAAA"}
package/dist/runner.js ADDED
@@ -0,0 +1,86 @@
1
+ import { Cause, Effect, Predicate, Stream } from "effect";
2
+ import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process";
3
+ import { ClaudeFailureCause, transportFailure, transportToAiError } from "./errors.js";
4
+ import { decodeClaudeOutput } from "./protocol.js";
5
+ const collectBounded = (source, maximumBytes, label, method) => source.pipe(Stream.mapError((cause) => transportFailure("process", `Failed while reading Claude CLI ${label} for ${method}`, cause)), Stream.runFoldEffect(() => ({ chunks: [], size: 0 }), (collected, chunk) => {
6
+ const size = collected.size + chunk.byteLength;
7
+ return size > maximumBytes
8
+ ? Effect.fail(transportFailure("process", `Claude CLI ${label} exceeded ${maximumBytes} bytes for ${method}`, new ClaudeFailureCause({ reason: `${label}-limit-exceeded` })))
9
+ : Effect.succeed({ chunks: [...collected.chunks, chunk], size });
10
+ }), Effect.flatMap((collected) => Stream.fromIterable(collected.chunks).pipe(Stream.decodeText(), Stream.mkString, Effect.mapError((cause) => transportFailure("process", `Claude CLI ${label} was not valid UTF-8 for ${method}`, cause)))));
11
+ const redactDiagnostic = (diagnostic, cwd) => {
12
+ const safeLines = diagnostic.split("\n").map((line) => {
13
+ const lower = line.toLowerCase();
14
+ return lower.includes("authorization") || lower.includes("api_key") || lower.includes("api key") ||
15
+ lower.includes("token")
16
+ ? "[redacted]"
17
+ : line.replaceAll(cwd, "<cwd>");
18
+ });
19
+ return safeLines.join("\n").trim().slice(0, 1_000);
20
+ };
21
+ const makeArguments = (options) => {
22
+ const tools = options.access === "workspace-write" ? "Read,Glob,Grep,Edit,Write" : "Read,Glob,Grep";
23
+ const permissionMode = options.access === "workspace-write" ? "acceptEdits" : "plan";
24
+ const arguments_ = [
25
+ "--print",
26
+ "--output-format",
27
+ "json",
28
+ "--input-format",
29
+ "text",
30
+ "--permission-mode",
31
+ permissionMode,
32
+ "--tools",
33
+ tools,
34
+ "--no-session-persistence",
35
+ "--safe-mode"
36
+ ];
37
+ if (options.model !== undefined)
38
+ arguments_.push("--model", options.model);
39
+ if (options.jsonSchema !== undefined)
40
+ arguments_.push("--json-schema", options.jsonSchema);
41
+ return arguments_;
42
+ };
43
+ const makeCommand = (options, arguments_) => Object.freeze(ChildProcess.make(options.executable, Object.freeze([...arguments_]), Object.freeze({
44
+ cwd: options.cwd,
45
+ env: Object.freeze({ ...options.environment }),
46
+ extendEnv: false,
47
+ forceKillAfter: "3 seconds",
48
+ killSignal: "SIGTERM",
49
+ shell: false,
50
+ stderr: "pipe",
51
+ stdin: Object.freeze({
52
+ stream: Stream.make(options.prompt).pipe(Stream.encodeText),
53
+ endOnDone: true
54
+ }),
55
+ stdout: "pipe"
56
+ })));
57
+ export const runClaude = Effect.fn("ClaudeCliLanguageModel.runClaude")(function* (options, method, spawner) {
58
+ const command = makeCommand(options, makeArguments(options));
59
+ const execution = Effect.gen(function* () {
60
+ const handle = yield* spawner.spawn(command).pipe(Effect.mapError((cause) => transportFailure("process", "Unable to start Claude CLI", cause)));
61
+ const collected = yield* Effect.all({
62
+ exitCode: handle.exitCode.pipe(Effect.mapError((cause) => transportFailure("process", "Unable to read Claude CLI exit status", cause))),
63
+ stderr: collectBounded(handle.stderr, options.maxStderrBytes, "stderr", method),
64
+ stdout: collectBounded(handle.stdout, options.maxOutputBytes, "stdout", method)
65
+ }, { concurrency: "unbounded" });
66
+ if (collected.exitCode !== ChildProcessSpawner.ExitCode(0)) {
67
+ const diagnostic = redactDiagnostic(collected.stderr, options.cwd);
68
+ const suffix = diagnostic.length > 0 ? `: ${diagnostic}` : "";
69
+ return yield* transportFailure("process", `Claude CLI exited with code ${collected.exitCode}${suffix}`, new ClaudeFailureCause({ reason: `exit-${collected.exitCode}` }));
70
+ }
71
+ const result = yield* decodeClaudeOutput(collected.stdout, method);
72
+ if (result.is_error) {
73
+ return yield* transportFailure("process", "Claude CLI returned an error result", new ClaudeFailureCause({ reason: "error-result" }));
74
+ }
75
+ return result;
76
+ }).pipe(Effect.scoped);
77
+ return yield* execution.pipe(Effect.timeout(options.timeout), Effect.mapError((cause) => {
78
+ if (Predicate.isTagged(cause, "ClaudeTransportError"))
79
+ return transportToAiError(cause, method);
80
+ if (Cause.isTimeoutError(cause)) {
81
+ return transportToAiError(transportFailure("timeout", "Claude CLI timed out", cause), method);
82
+ }
83
+ return cause;
84
+ }));
85
+ });
86
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@knpkv/ai-claude",
3
+ "version": "0.1.0",
4
+ "description": "Effect AI language model backed by the local Claude CLI",
5
+ "license": "MIT",
6
+ "author": "knpkv",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/knpkv/npm.git",
10
+ "directory": "packages/ai-claude"
11
+ },
12
+ "type": "module",
13
+ "sideEffects": false,
14
+ "main": "./dist/index.js",
15
+ "types": "./dist/index.d.ts",
16
+ "exports": {
17
+ ".": {
18
+ "types": "./dist/index.d.ts",
19
+ "import": "./dist/index.js"
20
+ }
21
+ },
22
+ "files": [
23
+ "dist",
24
+ "README.md"
25
+ ],
26
+ "publishConfig": {
27
+ "access": "public"
28
+ },
29
+ "engines": {
30
+ "node": ">=24"
31
+ },
32
+ "peerDependencies": {
33
+ "effect": "4.0.0-beta.98"
34
+ },
35
+ "devDependencies": {
36
+ "@effect/platform-node": "4.0.0-beta.98",
37
+ "@effect/vitest": "4.0.0-beta.98",
38
+ "@types/node": "latest",
39
+ "effect": "4.0.0-beta.98",
40
+ "rimraf": "^6.1.3",
41
+ "typescript": "~6.0.3",
42
+ "vitest": "^4.1.10"
43
+ },
44
+ "keywords": [
45
+ "effect",
46
+ "ai",
47
+ "claude",
48
+ "cli"
49
+ ],
50
+ "scripts": {
51
+ "build": "rimraf dist && tsc && node scripts/validate-dist.mjs",
52
+ "check": "tsc --noEmit",
53
+ "clean": "rimraf dist *.tsbuildinfo",
54
+ "lint": "eslint \"{src,test}/**/*.ts\"",
55
+ "test": "vitest run",
56
+ "test:exports": "pnpm build"
57
+ }
58
+ }