@sweny-ai/core 0.1.148 → 0.1.150

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.
Files changed (40) hide show
  1. package/dist/cli/builtin-workflows.d.ts +45 -0
  2. package/dist/cli/builtin-workflows.js +129 -0
  3. package/dist/cli/check.d.ts +2 -8
  4. package/dist/cli/check.js +2 -34
  5. package/dist/cli/config.js +8 -3
  6. package/dist/cli/main.js +46 -11
  7. package/dist/cli/packs.d.ts +9 -5
  8. package/dist/cli/packs.js +100 -50
  9. package/dist/executor.js +15 -3
  10. package/dist/harness/acp-rpc.d.ts +75 -0
  11. package/dist/harness/acp-rpc.js +204 -0
  12. package/dist/harness/acp.d.ts +189 -0
  13. package/dist/harness/acp.js +942 -0
  14. package/dist/harness/agents.d.ts +5 -1
  15. package/dist/harness/agents.js +8 -1
  16. package/dist/harness/auth.d.ts +38 -0
  17. package/dist/harness/auth.js +93 -0
  18. package/dist/harness/capabilities.d.ts +30 -0
  19. package/dist/harness/capabilities.js +41 -0
  20. package/dist/harness/claude-code.d.ts +8 -0
  21. package/dist/harness/claude-code.js +8 -1
  22. package/dist/harness/codex.d.ts +10 -1
  23. package/dist/harness/codex.js +17 -3
  24. package/dist/harness/index.d.ts +7 -3
  25. package/dist/harness/index.js +7 -2
  26. package/dist/harness/parse.d.ts +12 -0
  27. package/dist/harness/parse.js +1 -1
  28. package/dist/harness/policy.js +6 -0
  29. package/dist/harness/types.d.ts +6 -0
  30. package/dist/index.d.ts +1 -1
  31. package/dist/node-policy.js +1 -0
  32. package/dist/safe-outputs.d.ts +17 -5
  33. package/dist/safe-outputs.js +85 -11
  34. package/dist/schema.d.ts +80 -0
  35. package/dist/schema.js +23 -0
  36. package/dist/types.d.ts +13 -0
  37. package/dist/workflows/browser.js +2 -2
  38. package/dist/workflows/implement.yml +61 -19
  39. package/dist/workflows/triage.yml +171 -139
  40. package/package.json +1 -1
@@ -0,0 +1,189 @@
1
+ /**
2
+ * ACP harness (#416): runs a node on any Agent Client Protocol agent
3
+ * (`--agent acp:<command>`, for example `acp:opencode acp`,
4
+ * `acp:hermes acp`, `acp:goose acp`, `acp:gemini --experimental-acp`).
5
+ *
6
+ * ACP is the long-tail adapter. It is JSON-RPC 2.0 over the agent's stdio and
7
+ * carries a prompt and a stream of updates; it does not carry sweny's
8
+ * opinions. Read from agentclientprotocol/agent-client-protocol at tag
9
+ * schema-v1.24.1 (`schema/v1/schema.json`, `docs/protocol/v1/*.mdx`):
10
+ * - transports: newline-delimited JSON over stdio (`transports.mdx`).
11
+ * - `initialize` negotiates `protocolVersion` (1) and capabilities
12
+ * (`initialization.mdx`); `InitializeRequest` / `InitializeResponse`.
13
+ * - `session/new {cwd, mcpServers}` returns `{sessionId}`; every agent MUST
14
+ * support stdio MCP servers, http and sse are optional
15
+ * (`session-setup.mdx`, `McpServerStdio`, `McpServerHttp`).
16
+ * - `session/prompt {sessionId, prompt: ContentBlock[]}` streams
17
+ * `session/update` notifications (`agent_message_chunk`, `tool_call`,
18
+ * `tool_call_update`, `usage_update`, ...) and ends with
19
+ * `{stopReason}`; `PromptResponse` has no other field (`prompt-turn.mdx`).
20
+ * - `session/cancel` (notification) ends a turn with stopReason `cancelled`
21
+ * (`prompt-turn.mdx`, Cancellation); pending permission requests get the
22
+ * `cancelled` outcome.
23
+ * - `session/request_permission {toolCall, options}` is how an agent MAY ask
24
+ * before a tool runs; the client picks an option or answers `cancelled`
25
+ * (`tool-calls.mdx`, `RequestPermissionResponse`).
26
+ * - `fs/read_text_file` and `fs/write_text_file` are client methods an agent
27
+ * may use only when the client advertised them (`file-system.mdx`).
28
+ *
29
+ * Every sweny opinion is enforced by sweny here, refused or reported as
30
+ * `degraded` by `policyGate` (see ACP_CAPABILITIES for the honest list):
31
+ * - Structured output: the schema rides in the prompt; sweny parses the last
32
+ * JSON object, checks it and asks once more before giving up.
33
+ * - Tool deny and read-only: best effort through `session/request_permission`
34
+ * (denied classes and every non-read tool under `readOnly` are rejected),
35
+ * plus a refusal of every `fs/write_text_file`. The protocol has no deny list
36
+ * and an agent that does not ask is not stopped, so `policyGate` still
37
+ * reports deny and read-only as unenforced; strict refuses the node unless
38
+ * the process wrapper provides the read-only mount.
39
+ * - Sandbox and egress: none in the protocol. The whole agent process runs
40
+ * inside the sandbox wrapper (sandbox-wrapper.ts); strict refuses without it.
41
+ * - Env: sweny spawns the agent with the scoped env (agent-env.ts).
42
+ * - Skill tools: passed in `session/new` as the stdio MCP server of the tool
43
+ * bridge (#414), so the executor still observes every call.
44
+ * - Turn limit: a watchdog counts tool calls and cancels past the budget.
45
+ * - Timeout: `session/cancel`, a grace period, then the process is killed.
46
+ */
47
+ import type { Logger, McpServerConfig, ToolContext } from "../types.js";
48
+ import { type SandboxMode } from "../agent-env.js";
49
+ import type { AgentHarness, HarnessCapabilities, HarnessCompleteRequest, HarnessId, HarnessInfo, HarnessRunRequest, HarnessRunResult, ToolClass } from "./types.js";
50
+ import { ACP_CAPABILITIES } from "./capabilities.js";
51
+ import { type HarnessPolicyMode } from "./policy.js";
52
+ import { type SandboxWrapper } from "./sandbox-wrapper.js";
53
+ export { ACP_CAPABILITIES };
54
+ /** The ACP major version sweny speaks (`InitializeRequest.protocolVersion`). */
55
+ export declare const ACP_PROTOCOL_VERSION = 1;
56
+ export interface AcpHarnessOptions {
57
+ /**
58
+ * The agent to run: a command line (`"opencode acp"`, the part after `acp:`)
59
+ * or an explicit `{command, args}`. Never run through a shell.
60
+ */
61
+ acpCommand?: string | {
62
+ command: string;
63
+ args: string[];
64
+ };
65
+ /** Tool-call budget the watchdog enforces when a node sets no `max_turns` (default: 20). */
66
+ maxTurns?: number;
67
+ /** Working directory (default: process.cwd()). */
68
+ cwd?: string;
69
+ logger?: Logger;
70
+ /** Default tool context for standalone usage (not via the executor). */
71
+ defaultContext?: ToolContext;
72
+ /** Catalog defaults, overridden by per-run skill servers and explicit mcpServers. */
73
+ defaultMcpServers?: Record<string, McpServerConfig>;
74
+ /** Explicit external MCP servers, overriding defaults and per-run skill servers. */
75
+ mcpServers?: Record<string, McpServerConfig>;
76
+ /** Extra env var names passed through (see agent-env.ts). Default: `SWENY_ENV_PASSTHROUGH`. */
77
+ envPassthrough?: string[];
78
+ /** The agent's own auth env var names, always passed through when scoping (none are assumed). */
79
+ authVars?: string[];
80
+ /** Scope the agent env to the allowlist. Default: `SWENY_ENV_SCOPE`, else on in CI. */
81
+ envScope?: boolean;
82
+ /** Process sandbox mode. Default: `SWENY_SANDBOX`, else `auto` in CI and `off` locally. */
83
+ sandbox?: SandboxMode;
84
+ /** The host's process sandbox wrapper (#360 step 2). `undefined` = detect srt once per process; `null` = none (test seam). */
85
+ sandboxWrapper?: SandboxWrapper | null;
86
+ /** `strict` refuses a node with unenforceable opinions. Default: {@link resolveHarnessPolicy}. */
87
+ policy?: HarnessPolicyMode;
88
+ /** Hosts the agent itself needs (its model API), allowed through the sandbox wrapper. */
89
+ egress?: string[];
90
+ /** Shim command override for the tool bridge (test seam). */
91
+ toolBridgeShim?: {
92
+ command: string;
93
+ args: string[];
94
+ };
95
+ /** Grace period between SIGTERM and SIGKILL, and for the agent to exit on its own (default: 2000 ms). */
96
+ killGraceMs?: number;
97
+ /** How long the agent gets to answer `session/cancel` before it is killed (default: 5000 ms). */
98
+ cancelGraceMs?: number;
99
+ /** How long `initialize` and `session/new` may take (default: 60000 ms). */
100
+ startupTimeoutMs?: number;
101
+ }
102
+ /** Portable tool classes an ACP tool call can be, from its `kind` (schema `ToolKind`) and name. */
103
+ export declare function classifyAcpTool(kind: string | null | undefined, name: string | null | undefined): {
104
+ classes: ToolClass[];
105
+ readOnlySafe: boolean;
106
+ };
107
+ /** Does this tool call name one of sweny's skill tools (they reach the agent as MCP tools of the tool bridge)? */
108
+ export declare function isSkillToolCall(names: readonly (string | null | undefined)[], skillTools: readonly string[]): boolean;
109
+ interface PermissionOption {
110
+ optionId: string;
111
+ kind: string;
112
+ }
113
+ /** The permission outcome for an option list: the first option of a wanted kind, else `cancelled`. */
114
+ export declare function pickPermissionOutcome(options: readonly PermissionOption[], allow: boolean): {
115
+ outcome: "selected";
116
+ optionId: string;
117
+ } | {
118
+ outcome: "cancelled";
119
+ };
120
+ /** A loosely typed JSON object, for reading what the agent sends. */
121
+ type Obj = Record<string, any>;
122
+ /** `McpServerConfig` map to the ACP `mcpServers` array (schema `McpServer`). Returns what the agent cannot load too. */
123
+ export declare function toAcpMcpServers(servers: Record<string, McpServerConfig>, agentHttp: boolean): {
124
+ list: Obj[];
125
+ unsupported: string[];
126
+ };
127
+ export declare class AcpHarness implements AgentHarness {
128
+ readonly id: HarnessId;
129
+ readonly capabilities: HarnessCapabilities;
130
+ /** Empty on purpose: judges use the agent's own default model. */
131
+ readonly defaultJudgeModel = "";
132
+ readonly logger: Logger;
133
+ private agent;
134
+ private maxTurns;
135
+ private cwd;
136
+ private defaultContext;
137
+ private mcpServers;
138
+ private defaultMcpServers;
139
+ private envPassthrough;
140
+ private authVars;
141
+ private envScope;
142
+ private sandboxMode;
143
+ private sandboxWrapper;
144
+ private policyMode;
145
+ private egress;
146
+ private toolBridgeShim;
147
+ private killGraceMs;
148
+ private cancelGraceMs;
149
+ private startupTimeoutMs;
150
+ private agentVersion;
151
+ constructor(opts?: AcpHarnessOptions);
152
+ info(): HarnessInfo;
153
+ /**
154
+ * Is the agent command there? Deliberately does not start it: it would run
155
+ * outside the sandbox wrapper. The version comes from `initialize` on the
156
+ * first run (`agentInfo.version`).
157
+ */
158
+ preflight(): Promise<{
159
+ ok: true;
160
+ version: string;
161
+ } | {
162
+ ok: false;
163
+ reason: string;
164
+ }>;
165
+ /** Env for the agent process: scoped like Claude Code's, with only the auth vars the operator named. */
166
+ private buildEnv;
167
+ /** The node policy, with the harness policy mode and the watchdog budget applied. */
168
+ private compilePolicy;
169
+ /**
170
+ * Talk to one agent process from `initialize` to the last `session/prompt`
171
+ * response, then stop it. Never throws: every failure is on the result.
172
+ */
173
+ private converse;
174
+ /**
175
+ * Run a node. The gate runs first: in strict mode a node whose opinions an
176
+ * ACP agent cannot honor is refused before the agent starts. The agent
177
+ * process runs inside the host's sandbox wrapper (#360 step 2) when the
178
+ * sandbox mode asks for one and the host has one.
179
+ */
180
+ run(req: HarnessRunRequest): Promise<HarnessRunResult>;
181
+ /** Map one conversation onto a NodeResult with Claude Code's semantics. */
182
+ private toResult;
183
+ /**
184
+ * One completion: a fresh session with no MCP servers, every permission
185
+ * request rejected, and any tool call over budget. null when it failed
186
+ * (callers fail closed).
187
+ */
188
+ complete(req: HarnessCompleteRequest): Promise<string | null>;
189
+ }