@sweny-ai/core 0.1.133 → 0.1.134

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/dist/claude.d.ts CHANGED
@@ -1,232 +1,5 @@
1
1
  /**
2
- * Claude Client — Headless Claude Code backend
3
- *
4
- * Uses the @anthropic-ai/claude-agent-sdk to run headless Claude Code
5
- * as the LLM backend. Tools are exposed via an in-process MCP server
6
- * that Claude Code calls during execution.
7
- *
8
- * This is the ONLY supported LLM backend. The whole point of sweny
9
- * is to use headless Claude Code — never the raw Anthropic API.
2
+ * Back-compat shim. The Claude Code adapter moved to `./harness/claude-code.ts`
3
+ * as `ClaudeCodeHarness` (#330). Existing imports of `./claude.js` keep working.
10
4
  */
11
- import type { Claude, Tool, ToolContext, NodeResult, JSONSchema, Logger, McpServerConfig } from "./types.js";
12
- import { type AgentAccess, type SandboxMode } from "./agent-env.js";
13
- /**
14
- * Built-in tools disallowed for the route-evaluation (`evaluate`) and
15
- * reflection/judge (`ask`) calls.
16
- *
17
- * These are pure classification calls over prior-node data that can be
18
- * attacker-influenceable (a prior node summarizes an untrusted issue body,
19
- * PR diff, log line, etc.). They must never be able to mutate the workspace
20
- * or shell out, regardless of any node's own `disallowed_tools` policy.
21
- * `maxTurns: 1` already bounds them; this removes the powerful built-ins
22
- * from the model's context entirely as structural defense-in-depth.
23
- */
24
- export declare const CLASSIFICATION_DISALLOWED_TOOLS: readonly ["Bash", "Write", "Edit", "MultiEdit", "NotebookEdit", "WebFetch", "WebSearch"];
25
- /**
26
- * Built-in tools disallowed for a node run with `readOnly: true` (dry run,
27
- * #380): everything that can edit the workspace, shell out (and so reach
28
- * `gh`, `curl`, `git push`), spawn a subagent that could, or fetch an
29
- * arbitrary URL (a GET can still trigger a webhook or exfiltrate data).
30
- * Read, Grep, Glob and WebSearch stay available for analysis.
31
- */
32
- export declare const READ_ONLY_DISALLOWED_TOOLS: readonly ["Bash", "Write", "Edit", "MultiEdit", "NotebookEdit", "Task", "Agent", "WebFetch"];
33
- /** How sweny resolves which credentials reach the Claude Code subprocess. */
34
- export type SwenyAuthMode = "auto" | "api-key" | "oauth";
35
- export interface ResolveAuthEnvOpts {
36
- /** Explicit override; when absent, read from `env.SWENY_AUTH`. Test seam. */
37
- mode?: SwenyAuthMode;
38
- /** Logger for the debug line + invalid-value warning. */
39
- logger?: Pick<Logger, "debug" | "warn">;
40
- }
41
- /**
42
- * Decide which auth credentials survive into the Claude Code subprocess env.
43
- *
44
- * sweny does not select the winning credential (the spawned agent and any
45
- * on-disk `~/.claude/.credentials.json` do that). This function only controls
46
- * what is *present* in the env we hand the agent.
47
- *
48
- * Modes (`SWENY_AUTH`, default `auto`):
49
- * - `auto` — today's protective behavior: when an OAuth token is present,
50
- * strip `ANTHROPIC_API_KEY` so a stray `.env` key cannot
51
- * silently bill a metered API account. `ANTHROPIC_AUTH_TOKEN`
52
- * (a bearer token, not a console key) is never touched.
53
- * - `api-key` — user explicitly authenticates a gateway with a key/bearer:
54
- * preserve both even when an OAuth token is also present.
55
- * - `oauth` — user explicitly wants subscription/OAuth: strip both
56
- * `ANTHROPIC_API_KEY` and `ANTHROPIC_AUTH_TOKEN` so a leftover
57
- * credential cannot win at the agent. Fails closed.
58
- *
59
- * Base-URL presence is deliberately NOT a signal here: pass-through proxies
60
- * (corporate egress, observability) set `ANTHROPIC_BASE_URL` while still
61
- * billing the real key, so inferring "use the key" from a base URL would
62
- * re-introduce a surprise-billing path. Intent must be explicit.
63
- *
64
- * An unrecognized `SWENY_AUTH` value falls back to `auto` with a warning
65
- * (never throws — an env typo must not crash a CI run).
66
- *
67
- * Pure: returns a copy, never mutates the input.
68
- */
69
- export declare function resolveAuthEnv(env: Record<string, string>, opts?: ResolveAuthEnvOpts): Record<string, string>;
70
- export interface ClaudeClientOptions {
71
- /** Model override */
72
- model?: string;
73
- /** Max turns for tool use loop (default: 20) */
74
- maxTurns?: number;
75
- /** Working directory for Claude Code (default: process.cwd()) */
76
- cwd?: string;
77
- /** Logger */
78
- logger?: Logger;
79
- /** Default tool context for standalone usage (not via executor) */
80
- defaultContext?: ToolContext;
81
- /** Catalog defaults, overridden by per-run skill servers and explicit mcpServers. */
82
- defaultMcpServers?: Record<string, McpServerConfig>;
83
- /** Explicit external MCP servers, overriding defaults and per-run skill servers. */
84
- mcpServers?: Record<string, McpServerConfig>;
85
- /**
86
- * Extra env var names passed to the agent subprocess on top of the
87
- * allowlist (see agent-env.ts). `"*"` inherits the full environment.
88
- * Default: `SWENY_ENV_PASSTHROUGH` (comma-separated).
89
- */
90
- envPassthrough?: string[];
91
- /**
92
- * Scope the agent env to the allowlist. Default: `SWENY_ENV_SCOPE`, else on
93
- * when CI is truthy and off locally (full env).
94
- */
95
- envScope?: boolean;
96
- /**
97
- * SDK sandbox for agent commands: `auto` (sandbox when the host supports
98
- * it, else warn and run unsandboxed), `strict` (sandbox or fail), `off`.
99
- * Default: `SWENY_SANDBOX`, else `auto` when CI is truthy, `off` otherwise.
100
- */
101
- sandbox?: SandboxMode;
102
- /** Extra hosts sandboxed commands may reach. Default: `SWENY_SANDBOX_ALLOWED_DOMAINS`. */
103
- sandboxAllowedDomains?: string[];
104
- /** Sandbox preflight probe (test seam). Returns a reason when the sandbox cannot run. */
105
- sandboxProbe?: () => string | undefined;
106
- }
107
- /**
108
- * Wire an optional timeout + caller signal onto a single AbortController.
109
- *
110
- * Returns undefined when neither a timeout nor a signal is supplied so the
111
- * default code path (no abortController, no timer) is byte-for-byte unchanged.
112
- *
113
- * `reason()` reports whether the abort came from the timeout timer or an
114
- * external signal, so callers can log a distinct timeout message.
115
- */
116
- export declare function makeAbort(timeoutMs?: number, signal?: AbortSignal): {
117
- controller: AbortController;
118
- clear: () => void;
119
- reason: () => "timeout" | "signal" | undefined;
120
- } | undefined;
121
- export declare class ClaudeClient implements Claude {
122
- private model;
123
- private maxTurns;
124
- private cwd;
125
- private logger;
126
- private defaultContext;
127
- private mcpServers;
128
- private defaultMcpServers;
129
- private envPassthrough;
130
- private sandboxMode;
131
- private sandboxAllowedDomains;
132
- private sandboxProbe;
133
- private sandboxWarned;
134
- private envScope;
135
- constructor(opts?: ClaudeClientOptions);
136
- /**
137
- * Build env for the Claude Code subprocess (#360). Applies auth precedence
138
- * via {@link resolveAuthEnv} on the full process env (it reads
139
- * `SWENY_AUTH`). When env scoping is on (default in CI, see
140
- * {@link resolveEnvScope}) the result is narrowed to the allowlist plus
141
- * `extraVars` (the node's declared skill env vars) and the operator
142
- * passthrough list, and the withheld names (never values) are reported once
143
- * per process ({@link reportWithheldEnv}). When off, the full env passes through as before.
144
- */
145
- private buildEnv;
146
- run(opts: {
147
- instruction: string;
148
- context: Record<string, unknown>;
149
- tools: Tool[];
150
- outputSchema?: JSONSchema;
151
- onProgress?: (message: string) => void;
152
- maxTurns?: number;
153
- disallowedTools?: string[];
154
- model?: string;
155
- /** Abort the query after this many ms. Default: no timeout (back-compat). */
156
- timeoutMs?: number;
157
- /** Caller-supplied abort signal. Aborting it interrupts the query. */
158
- signal?: AbortSignal;
159
- /** MCP servers declared by the current node's skills. */
160
- mcpServers?: Record<string, McpServerConfig>;
161
- /** Dry run (#380): no external MCP servers, no write-capable built-ins. */
162
- readOnly?: boolean;
163
- /** Env var names + sandbox hosts this node's skills need (#360). */
164
- agentAccess?: AgentAccess;
165
- }): Promise<NodeResult>;
166
- evaluate(opts: {
167
- question: string;
168
- context: Record<string, unknown>;
169
- choices: {
170
- id: string;
171
- description: string;
172
- }[];
173
- /** Abort the query after this many ms. Default: no timeout (back-compat). */
174
- timeoutMs?: number;
175
- /** Caller-supplied abort signal. Aborting it interrupts the query. */
176
- signal?: AbortSignal;
177
- }): Promise<string | null>;
178
- ask(opts: {
179
- instruction: string;
180
- context: Record<string, unknown>;
181
- model?: string;
182
- /** Abort the query after this many ms. Default: no timeout (back-compat). */
183
- timeoutMs?: number;
184
- /** Caller-supplied abort signal. Aborting it interrupts the query. */
185
- signal?: AbortSignal;
186
- }): Promise<string>;
187
- }
188
- /**
189
- * Best-effort recovery of typed output from a tool_result's `content`.
190
- *
191
- * The MCP protocol sends tool results as string content. Our in-process
192
- * wrapper JSON-stringifies structured output before returning; external
193
- * MCP servers generally do the same for JSON payloads. If the string
194
- * looks like a JSON object or array and parses, return the parsed value
195
- * so verify's output-path walks work against typed data.
196
- *
197
- * Raw strings are preserved verbatim. JSON-primitive strings (e.g. the
198
- * literal four characters `"42"`) are intentionally NOT parsed — we
199
- * cannot distinguish a tool that returned the number 42 (wrapper sends
200
- * `"42"`) from a tool that returned the string "42" (wrapper also sends
201
- * `"42"`). Preserving the string is safer than guessing.
202
- */
203
- /**
204
- * Build the prompt used by `ClaudeClient.evaluate()` to pick a routing edge.
205
- *
206
- * Extracted as a pure function so the prompt body can be unit tested without
207
- * spinning up an SDK query. The body is part of the routing contract: workflow
208
- * authors and downstream maintainers rely on the model leaning on structured
209
- * fields rather than prose narrative when picking an edge, especially in the
210
- * fallback case where a source node did not declare an `output` schema (the
211
- * executor's schema-strict filter only kicks in when a schema is present;
212
- * see `buildRouteEvalEntry` in executor.ts).
213
- *
214
- * Any change to this prompt should keep:
215
- * - The three "Evaluation rules" pointing the model at structured fields
216
- * and away from prose narrative.
217
- * - A terminal directive to return ONLY the choice ID.
218
- */
219
- export declare function buildEvaluatePrompt(question: string, context: Record<string, unknown>, choices: {
220
- id: string;
221
- description: string;
222
- }[]): string;
223
- export declare function parseToolResultContent(content: unknown): unknown;
224
- /**
225
- * Produce a short, single-line description of a tool-error payload suitable
226
- * for the CI log stream. The full parsed value stays on the ToolCall for
227
- * verify and downstream tooling — this is only for inline observability.
228
- *
229
- * Collapses newlines, trims whitespace, and caps to 300 chars so a huge
230
- * API response body doesn't flood the log.
231
- */
232
- export declare function summarizeToolError(parsed: unknown): string;
5
+ export * from "./harness/claude-code.js";