agentbox-sdk 0.1.516 → 0.1.517

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
@@ -133,6 +133,32 @@ a 15s grace as a compatibility fallback. A final
133
133
  default 30 minutes, `0` settles at the first turn end as before, `Infinity`
134
134
  waits forever. On expiry the tasks are stopped best-effort and the run
135
135
  completes with the last turn's text.
136
+
137
+ ### Harness commands
138
+
139
+ A run whose input starts with `/name args` carries the harness's own slash
140
+ command. `resolveHarnessCommand(provider, input)` keeps the text as typed and
141
+ returns `command: { name, args }` for `AgentRunConfig.command`; `/plan`,
142
+ `/agent`, and `/goal` stay harness modes as before. Each adapter dispatches
143
+ what its CLI supports headlessly:
144
+
145
+ - Claude Code parses slash commands from the user message itself (`/compact`,
146
+ `/context`, `/init`, skills, custom commands, plugin commands).
147
+ - Codex maps `/compact` to `thread/compact/start`, `/review [instructions]` to
148
+ `review/start`, `/init` to the TUI's AGENTS.md prompt, and an installed skill
149
+ to its `$name` mention.
150
+ - OpenCode maps `/compact` to `POST /session/:id/summarize`, a configured
151
+ command to `POST /session/:id/command`, and an installed skill to a
152
+ directive the model follows. Configured command calls preserve file and
153
+ image attachments. They reject a per-run `systemPrompt` because OpenCode's
154
+ command endpoint cannot accept it; use a normal prompt or the setup-time
155
+ `OpenCodeAgentOptions.systemPrompt` instead. This also applies to the runtime
156
+ system appendix generated from configured MCPs, skills, sub-agents, or commands.
157
+
158
+ Anything the harness does not know is sent as plain text. Each run emits one
159
+ `harness.commands` event listing what it can run (`HarnessCommandDescriptor[]`:
160
+ name, description, argument hint, source), so a host can build its `/` menu;
161
+ `builtinHarnessCommands(provider)` gives the static list before a run exists.
136
162
  Tasks marked ambient by Claude (such as live-update watchers) do not keep the
137
163
  run waiting. The SDK's full task snapshots take precedence over task start and
138
164
  finish events, whose ordering relative to those snapshots is unspecified.
@@ -1,5 +1,5 @@
1
- import { o as AgentProviderName, h as AgentOptions, t as AgentRunConfig, s as AgentRun, r as AgentResult, a9 as RawAgentEvent, b as AgentAttachRequest, B as AttachedRun, ag as SetupLayout, am as UserContent } from '../types-BKvKgRMY.js';
2
- export { a as AgentApprovalMode, c as AgentCommandConfig, d as AgentCostData, e as AgentExecutionRequest, f as AgentLocalMcpConfig, g as AgentMcpConfig, i as AgentOptionsBase, j as AgentOptionsMap, k as AgentPermissionDecision, l as AgentPermissionKind, m as AgentPermissionResponse, n as AgentProviderAdapter, p as AgentReasoningEffort, q as AgentRemoteMcpConfig, u as AgentRunSink, v as AgentSetupRequest, w as AgentSkillConfig, x as AgentSubAgentConfig, y as AgentUserAnswer, z as AgentUserQuestion, E as ClaudeCodeAgentOptions, F as ClaudeCodeHookConfig, G as ClaudeCodeHookEvent, H as ClaudeCodeHookHandler, I as ClaudeCodeHookMatcherGroup, J as ClaudeCodeHooksConfig, K as ClaudeCodeProviderOptions, L as CodexAgentOptions, M as CodexCommandHook, N as CodexHookEvent, O as CodexHookMatcherGroup, P as CodexHooksConfig, Q as CodexModelProviderConfig, R as CodexProviderOptions, S as DataContent, T as EmbeddedSkillConfig, U as FilePart, V as ImagePart, a1 as OpenCodeAgentOptions, a2 as OpenCodePluginConfig, a3 as OpenCodePluginEvent, a4 as OpenCodePluginHookConfig, a5 as OpenCodeProviderOptions, a6 as OpenRouterPlugin, ab as RepoSkillConfig, ai as TextPart, an as UserContentPart } from '../types-BKvKgRMY.js';
1
+ import { o as AgentProviderName, h as AgentOptions, t as AgentRunConfig, s as AgentRun, r as AgentResult, ak as RawAgentEvent, b as AgentAttachRequest, B as AttachedRun, ar as SetupLayout, ax as UserContent } from '../types-CrbPZ814.js';
2
+ export { a as AgentApprovalMode, c as AgentCommandConfig, d as AgentCostData, e as AgentExecutionRequest, f as AgentLocalMcpConfig, g as AgentMcpConfig, i as AgentOptionsBase, j as AgentOptionsMap, k as AgentPermissionDecision, l as AgentPermissionKind, m as AgentPermissionResponse, n as AgentProviderAdapter, p as AgentReasoningEffort, q as AgentRemoteMcpConfig, u as AgentRunSink, v as AgentSetupRequest, w as AgentSkillConfig, x as AgentSubAgentConfig, y as AgentUserAnswer, z as AgentUserQuestion, E as ClaudeCodeAgentOptions, F as ClaudeCodeHookConfig, G as ClaudeCodeHookEvent, H as ClaudeCodeHookHandler, I as ClaudeCodeHookMatcherGroup, J as ClaudeCodeHooksConfig, K as ClaudeCodeProviderOptions, L as CodexAgentOptions, M as CodexCommandHook, N as CodexHookEvent, O as CodexHookMatcherGroup, P as CodexHooksConfig, Q as CodexModelProviderConfig, R as CodexProviderOptions, S as CodexSkillEntry, T as DataContent, U as EmbeddedSkillConfig, V as FilePart, W as HarnessCommandDescriptor, X as HarnessCommandInvocation, Y as HarnessCommandSource, _ as ImagePart, $ as MAX_HARNESS_COMMANDS, a0 as MAX_HARNESS_COMMAND_ARGUMENT_HINT, a1 as MAX_HARNESS_COMMAND_DESCRIPTION, a2 as MAX_HARNESS_COMMAND_NAME, aa as OpenCodeAgentOptions, ab as OpenCodeCommandEntry, ac as OpenCodePluginConfig, ad as OpenCodePluginEvent, ae as OpenCodePluginHookConfig, af as OpenCodeProviderOptions, ag as OpenCodeSkillEntry, ah as OpenRouterPlugin, am as RepoSkillConfig, at as TextPart, ay as UserContentPart, az as builtinHarnessCommands, aA as claudeHarnessCommands, aB as codexHarnessCommands, aC as codexSkillMention, aF as openCodeHarnessCommands, aG as parseHarnessCommandInvocation, aH as skillDirective } from '../types-CrbPZ814.js';
3
3
  import { S as Sandbox } from '../Sandbox-DcKAU-E3.js';
4
4
  export { AgentProvider } from '../enums.js';
5
5
  import 'e2b';
@@ -133,6 +133,12 @@ interface HarnessCapabilities {
133
133
  }
134
134
  /** Adapter capabilities. Runtime adapters additionally validate commands against the live harness. */
135
135
  declare function harnessCapabilities(provider: AgentProviderName): HarnessCapabilities;
136
- declare function resolveHarnessCommand(provider: AgentProviderName, input: UserContent): Pick<AgentRunConfig, "input" | "mode" | "goal">;
136
+ /**
137
+ * Resolve a leading slash token. `/plan`, `/agent`, and `/goal` are harness
138
+ * modes handled here; any other `/name args` is a harness command left in the
139
+ * input verbatim (Claude Code dispatches it itself) and described by
140
+ * `command` so Codex and OpenCode adapters can map it to their native calls.
141
+ */
142
+ declare function resolveHarnessCommand(provider: AgentProviderName, input: UserContent): Pick<AgentRunConfig, "input" | "mode" | "goal" | "command">;
137
143
 
138
144
  export { AGENT_RESERVED_PORTS, Agent, AgentAttachRequest, AgentOptions, AgentProviderName, AgentResult, AgentRun, AgentRunConfig, AttachedRun, type HarnessCapabilities, type HarnessCommand, SetupLayout, UserContent, agentboxRoot, collectAllAgentReservedPorts, getAgentLayout, harnessCapabilities, resolveHarnessCommand };
@@ -1,10 +1,21 @@
1
1
  import {
2
2
  Agent,
3
+ MAX_HARNESS_COMMANDS,
4
+ MAX_HARNESS_COMMAND_ARGUMENT_HINT,
5
+ MAX_HARNESS_COMMAND_DESCRIPTION,
6
+ MAX_HARNESS_COMMAND_NAME,
3
7
  agentboxRoot,
8
+ builtinHarnessCommands,
9
+ claudeHarnessCommands,
10
+ codexHarnessCommands,
11
+ codexSkillMention,
4
12
  getAgentLayout,
5
13
  harnessCapabilities,
6
- resolveHarnessCommand
7
- } from "../chunk-SERVEWIE.js";
14
+ openCodeHarnessCommands,
15
+ parseHarnessCommandInvocation,
16
+ resolveHarnessCommand,
17
+ skillDirective
18
+ } from "../chunk-U3E62L37.js";
8
19
  import "../chunk-V4M4LPPT.js";
9
20
  import {
10
21
  AGENT_RESERVED_PORTS,
@@ -18,9 +29,20 @@ export {
18
29
  AGENT_RESERVED_PORTS,
19
30
  Agent,
20
31
  AgentProvider,
32
+ MAX_HARNESS_COMMANDS,
33
+ MAX_HARNESS_COMMAND_ARGUMENT_HINT,
34
+ MAX_HARNESS_COMMAND_DESCRIPTION,
35
+ MAX_HARNESS_COMMAND_NAME,
21
36
  agentboxRoot,
37
+ builtinHarnessCommands,
38
+ claudeHarnessCommands,
39
+ codexHarnessCommands,
40
+ codexSkillMention,
22
41
  collectAllAgentReservedPorts,
23
42
  getAgentLayout,
24
43
  harnessCapabilities,
25
- resolveHarnessCommand
44
+ openCodeHarnessCommands,
45
+ parseHarnessCommandInvocation,
46
+ resolveHarnessCommand,
47
+ skillDirective
26
48
  };
@@ -103,6 +103,258 @@ async function* linesFromNodeStream(stream) {
103
103
  // src/agents/providers/claude-code.ts
104
104
  import path8 from "path";
105
105
 
106
+ // src/agents/harness-commands.ts
107
+ var MAX_HARNESS_COMMANDS = 500;
108
+ var MAX_HARNESS_COMMAND_NAME = 200;
109
+ var MAX_HARNESS_COMMAND_DESCRIPTION = 500;
110
+ var MAX_HARNESS_COMMAND_ARGUMENT_HINT = 200;
111
+ var HARNESS_COMMAND_NAME_PATTERN = /^[A-Za-z0-9][\w:.-]*$/;
112
+ function harnessCommandName(raw) {
113
+ const name = raw?.trim();
114
+ if (!name || name.length > MAX_HARNESS_COMMAND_NAME) return void 0;
115
+ return HARNESS_COMMAND_NAME_PATTERN.test(name) ? name : void 0;
116
+ }
117
+ function harnessCommandText(raw, max) {
118
+ const text2 = raw?.trim();
119
+ return text2 ? text2.slice(0, max) : void 0;
120
+ }
121
+ var CLAUDE_BUILTINS = [
122
+ {
123
+ name: "compact",
124
+ description: "Free up context by summarizing the conversation so far",
125
+ argumentHint: "<optional summarization instructions>",
126
+ source: "builtin"
127
+ },
128
+ {
129
+ name: "context",
130
+ description: "Show what is using the context window",
131
+ source: "builtin"
132
+ },
133
+ {
134
+ name: "usage",
135
+ description: "Show token usage and cost for this session",
136
+ source: "builtin"
137
+ },
138
+ {
139
+ name: "recap",
140
+ description: "Summarize what has happened in this session",
141
+ source: "builtin"
142
+ },
143
+ {
144
+ name: "init",
145
+ description: "Create a CLAUDE.md guide for this repository",
146
+ source: "builtin"
147
+ },
148
+ {
149
+ name: "security-review",
150
+ description: "Review pending changes for security issues",
151
+ source: "builtin"
152
+ },
153
+ {
154
+ name: "mcp",
155
+ description: "Show configured MCP servers and their status",
156
+ source: "builtin"
157
+ }
158
+ ];
159
+ var CODEX_BUILTINS = [
160
+ {
161
+ name: "compact",
162
+ description: "Summarize the conversation to free up context",
163
+ source: "builtin"
164
+ },
165
+ {
166
+ name: "review",
167
+ description: "Review the uncommitted changes in the workspace",
168
+ argumentHint: "<optional review instructions>",
169
+ source: "builtin"
170
+ },
171
+ {
172
+ name: "init",
173
+ description: "Create an AGENTS.md contributor guide for this repository",
174
+ argumentHint: "<optional focus>",
175
+ source: "builtin"
176
+ }
177
+ ];
178
+ var OPENCODE_BUILTINS = [
179
+ {
180
+ name: "compact",
181
+ description: "Summarize the session to free up context",
182
+ source: "builtin"
183
+ },
184
+ {
185
+ name: "init",
186
+ description: "Create an AGENTS.md guide for this repository",
187
+ argumentHint: "<optional focus>",
188
+ source: "builtin"
189
+ },
190
+ {
191
+ name: "review",
192
+ description: "Review the current changes",
193
+ argumentHint: "<optional focus>",
194
+ source: "builtin"
195
+ }
196
+ ];
197
+ function builtinHarnessCommands(provider) {
198
+ switch (provider) {
199
+ case "claude-code":
200
+ return CLAUDE_BUILTINS.map((command) => ({ ...command }));
201
+ case "codex":
202
+ return CODEX_BUILTINS.map((command) => ({ ...command }));
203
+ case "open-code":
204
+ return OPENCODE_BUILTINS.map((command) => ({ ...command }));
205
+ default:
206
+ return [];
207
+ }
208
+ }
209
+ function parseHarnessCommandInvocation(text2) {
210
+ const match = text2.match(/^\s*\/([A-Za-z0-9][\w:.-]*)(?:\s+([\s\S]*))?$/);
211
+ const name = match?.[1];
212
+ if (!name) return void 0;
213
+ return { name, args: (match[2] ?? "").trim() };
214
+ }
215
+ var CLAUDE_HIDDEN_BUILTINS = /* @__PURE__ */ new Set([
216
+ "agents",
217
+ "list-agents",
218
+ "advisor",
219
+ "auto-mode-setup",
220
+ "autocompact",
221
+ "clear",
222
+ "reset",
223
+ "new",
224
+ "color",
225
+ "config",
226
+ "design-consent",
227
+ "design-revoke",
228
+ "doctor",
229
+ "effort",
230
+ "exit",
231
+ "quit",
232
+ "extra-usage",
233
+ "fast",
234
+ "goal",
235
+ "heapdump",
236
+ "import",
237
+ "insights",
238
+ "model",
239
+ "output-style",
240
+ "plan",
241
+ "reload-plugins",
242
+ "reload-skills",
243
+ "rename",
244
+ "name",
245
+ "skill-doctor",
246
+ "team-onboarding",
247
+ "ultrareview",
248
+ "usage-credits",
249
+ "workflow-launch-exec",
250
+ "add-dir",
251
+ "stop"
252
+ ]);
253
+ var CLAUDE_BUILTIN_DESCRIPTIONS = new Map(
254
+ CLAUDE_BUILTINS.map((command) => [command.name, command])
255
+ );
256
+ function claudeHarnessCommands(init) {
257
+ const skills = new Set(init.skills ?? []);
258
+ const terminal = new Set(init.terminal_slash_commands ?? []);
259
+ const plugins = new Set((init.plugins ?? []).map((plugin) => plugin.name));
260
+ const seen = /* @__PURE__ */ new Set();
261
+ const commands = [];
262
+ for (const raw of init.slash_commands ?? []) {
263
+ const name = harnessCommandName(raw.replace(/^\//, ""));
264
+ if (!name || seen.has(name) || name.startsWith("__")) continue;
265
+ if (terminal.has(name) || CLAUDE_HIDDEN_BUILTINS.has(name)) continue;
266
+ seen.add(name);
267
+ const known = CLAUDE_BUILTIN_DESCRIPTIONS.get(name);
268
+ const prefix = name.includes(":") ? name.slice(0, name.indexOf(":")) : "";
269
+ const source = known ? "builtin" : prefix && plugins.has(prefix) ? "plugin" : skills.has(name) ? "skill" : "custom";
270
+ commands.push({
271
+ name,
272
+ ...known?.description ? { description: known.description } : {},
273
+ ...known?.argumentHint ? { argumentHint: known.argumentHint } : {},
274
+ source
275
+ });
276
+ }
277
+ return commands.slice(0, MAX_HARNESS_COMMANDS);
278
+ }
279
+ function codexHarnessCommands(list) {
280
+ const commands = builtinHarnessCommands("codex");
281
+ const seen = new Set(commands.map((command) => command.name));
282
+ for (const group of list.data ?? []) {
283
+ for (const skill of group.skills ?? []) {
284
+ const name = harnessCommandName(skill.name);
285
+ if (!name || skill.enabled === false || seen.has(name)) continue;
286
+ seen.add(name);
287
+ const description = harnessCommandText(
288
+ skill.interface?.shortDescription ?? skill.description ?? void 0,
289
+ MAX_HARNESS_COMMAND_DESCRIPTION
290
+ );
291
+ commands.push({
292
+ name,
293
+ ...description ? { description } : {},
294
+ source: skill.pluginId ? "plugin" : "skill"
295
+ });
296
+ }
297
+ }
298
+ return commands.slice(0, MAX_HARNESS_COMMANDS);
299
+ }
300
+ function codexSkillMention(name) {
301
+ const index = name.lastIndexOf(":");
302
+ return `$${index === -1 ? name : name.slice(index + 1)}`;
303
+ }
304
+ var OPENCODE_BUILTIN_DESCRIPTIONS = new Map(
305
+ OPENCODE_BUILTINS.map((command) => [command.name, command])
306
+ );
307
+ var OPENCODE_PLACEHOLDER_HINT = /^\$(?:\d+|ARGUMENTS)$/;
308
+ function openCodeArgumentHint(hints) {
309
+ const named = (hints ?? []).map((hint) => hint.trim()).filter((hint) => hint.length > 0 && !OPENCODE_PLACEHOLDER_HINT.test(hint));
310
+ if (named.length > 0) return named.map((hint) => `<${hint}>`).join(" ");
311
+ return hints?.length ? "<arguments>" : void 0;
312
+ }
313
+ function openCodeHarnessCommands(commands, skills = []) {
314
+ const result = [
315
+ { ...OPENCODE_BUILTIN_DESCRIPTIONS.get("compact") }
316
+ ];
317
+ const seen = new Set(result.map((command) => command.name));
318
+ for (const command of commands) {
319
+ const name = harnessCommandName(command.name);
320
+ if (!name || seen.has(name)) continue;
321
+ seen.add(name);
322
+ const known = OPENCODE_BUILTIN_DESCRIPTIONS.get(name);
323
+ const description = harnessCommandText(
324
+ command.description ?? known?.description,
325
+ MAX_HARNESS_COMMAND_DESCRIPTION
326
+ );
327
+ const hint = harnessCommandText(
328
+ known?.argumentHint ?? openCodeArgumentHint(command.hints),
329
+ MAX_HARNESS_COMMAND_ARGUMENT_HINT
330
+ );
331
+ result.push({
332
+ name,
333
+ ...description ? { description } : {},
334
+ ...hint ? { argumentHint: hint } : {},
335
+ source: command.mcp ? "mcp" : command.source === "command" || known ? "builtin" : "custom"
336
+ });
337
+ }
338
+ for (const skill of skills) {
339
+ const name = harnessCommandName(skill.name);
340
+ if (!name || seen.has(name)) continue;
341
+ seen.add(name);
342
+ const description = harnessCommandText(
343
+ skill.description,
344
+ MAX_HARNESS_COMMAND_DESCRIPTION
345
+ );
346
+ result.push({
347
+ name,
348
+ ...description ? { description } : {},
349
+ source: "skill"
350
+ });
351
+ }
352
+ return result.slice(0, MAX_HARNESS_COMMANDS);
353
+ }
354
+ function skillDirective(name, args) {
355
+ return args ? `Use the "${name}" skill for this: ${args}` : `Use the "${name}" skill.`;
356
+ }
357
+
106
358
  // src/agents/approval.ts
107
359
  function getApprovalMode(options) {
108
360
  return options.approvalMode ?? "auto";
@@ -3566,6 +3818,13 @@ async function consumeClaudeMessages(request, sink, messages, executeStartedAt,
3566
3818
  "This Claude Code installation does not expose the native /goal command."
3567
3819
  );
3568
3820
  }
3821
+ sink.emitEvent(
3822
+ createNormalizedEvent(
3823
+ "harness.commands",
3824
+ { provider: request.provider, runId: request.runId },
3825
+ { commands: claudeHarnessCommands(sys) }
3826
+ )
3827
+ );
3569
3828
  if (sys.session_id) {
3570
3829
  debugClaude(
3571
3830
  "\u2605 session.init session_id=%s (%dms)",
@@ -4285,6 +4544,9 @@ function compactEnv(values) {
4285
4544
  function buildCodexSandboxMode(options) {
4286
4545
  return options.fullAccess ? "danger-full-access" : options.provider?.sandboxMode ?? (options.configuration === "native" ? void 0 : options.sandbox ? "workspace-write" : "read-only");
4287
4546
  }
4547
+ function buildCodexThreadConfig(request) {
4548
+ return request.run.reasoning ? { config: { model_reasoning_effort: request.run.reasoning } } : {};
4549
+ }
4288
4550
  function buildThreadParams(cwd, options, request) {
4289
4551
  return {
4290
4552
  cwd,
@@ -4292,6 +4554,7 @@ function buildThreadParams(cwd, options, request) {
4292
4554
  ...request.options.provider?.serviceTier !== void 0 ? { serviceTier: request.options.provider.serviceTier } : {},
4293
4555
  ...options.provider?.approvalPolicy ? { approvalPolicy: options.provider.approvalPolicy } : options.configuration === "native" && !options.fullAccess ? {} : { approvalPolicy: !options.fullAccess && isInteractiveApproval(options) ? "untrusted" : "never" },
4294
4556
  sandbox: buildCodexSandboxMode(options),
4557
+ ...buildCodexThreadConfig(request),
4295
4558
  serviceName: "agentbox",
4296
4559
  // Persist the rollout on disk so follow-up runs can call `thread/resume`.
4297
4560
  // `ephemeral: true` threads have no rollout file and resume fails with
@@ -4308,6 +4571,7 @@ function buildResumeParams(cwd, options, request) {
4308
4571
  ...request.options.provider?.serviceTier !== void 0 ? { serviceTier: request.options.provider.serviceTier } : {},
4309
4572
  ...options.provider?.approvalPolicy ? { approvalPolicy: options.provider.approvalPolicy } : options.configuration === "native" && !options.fullAccess ? {} : { approvalPolicy: !options.fullAccess && isInteractiveApproval(options) ? "untrusted" : "never" },
4310
4573
  sandbox: buildCodexSandboxMode(options),
4574
+ ...buildCodexThreadConfig(request),
4311
4575
  ...request.run.systemPrompt ? { developerInstructions: request.run.systemPrompt } : options.configuration === "native" ? {} : { developerInstructions: null },
4312
4576
  // We only need the thread id back; we never read `thread.turns`.
4313
4577
  // Without this Codex hydrates the full history into the response and
@@ -4325,6 +4589,7 @@ function buildForkParams(cwd, options, request) {
4325
4589
  ...request.options.provider?.serviceTier !== void 0 ? { serviceTier: request.options.provider.serviceTier } : {},
4326
4590
  ...options.provider?.approvalPolicy ? { approvalPolicy: options.provider.approvalPolicy } : options.configuration === "native" && !options.fullAccess ? {} : { approvalPolicy: !options.fullAccess && isInteractiveApproval(options) ? "untrusted" : "never" },
4327
4591
  sandbox: buildCodexSandboxMode(options),
4592
+ ...buildCodexThreadConfig(request),
4328
4593
  ...request.run.systemPrompt ? { developerInstructions: request.run.systemPrompt } : options.configuration === "native" ? {} : { developerInstructions: null },
4329
4594
  excludeTurns: true
4330
4595
  };
@@ -4372,6 +4637,51 @@ function buildCodexTurnStartParams(params) {
4372
4637
  };
4373
4638
  }
4374
4639
  var CODEX_CANCEL_TURN_TEXT = "Run cancelled by the host.";
4640
+ var CODEX_INIT_PROMPT = "Generate a file named AGENTS.md that serves as a contributor guide for this repository.";
4641
+ var CODEX_BUILTIN_COMMAND_NAMES = new Set(
4642
+ builtinHarnessCommands("codex").map((command) => command.name)
4643
+ );
4644
+ function replaceCodexPromptText(inputItems, text2) {
4645
+ let replaced = false;
4646
+ const next = inputItems.map((item) => {
4647
+ if (item.type !== "text" || replaced) return item;
4648
+ replaced = true;
4649
+ return { ...item, text: text2 };
4650
+ });
4651
+ return replaced ? next : [{ type: "text", text: text2, text_elements: [] }, ...next];
4652
+ }
4653
+ function resolveCodexCommandDispatch(command, inputItems, skillNames) {
4654
+ if (!command) return { kind: "turn", inputItems };
4655
+ const args = command.args;
4656
+ switch (command.name) {
4657
+ case "compact":
4658
+ return { kind: "compact" };
4659
+ case "review":
4660
+ return {
4661
+ kind: "review",
4662
+ target: args ? { type: "custom", instructions: args } : { type: "uncommittedChanges" }
4663
+ };
4664
+ case "init":
4665
+ return { kind: "turn", inputItems: replaceCodexPromptText(inputItems, args ? `${CODEX_INIT_PROMPT} ${args}` : CODEX_INIT_PROMPT) };
4666
+ default:
4667
+ if (skillNames.has(command.name)) {
4668
+ const mention = codexSkillMention(command.name);
4669
+ return { kind: "turn", inputItems: replaceCodexPromptText(inputItems, args ? `${mention} ${args}` : mention) };
4670
+ }
4671
+ return { kind: "turn", inputItems };
4672
+ }
4673
+ }
4674
+ var HARNESS_COMMANDS_SETTLE_GRACE_MS = 500;
4675
+ async function listCodexHarnessCommands(client, cwd) {
4676
+ try {
4677
+ const list = await withTimeout(client.request("skills/list", { cwds: [cwd] }), 5e3);
4678
+ if (!list) throw new Error("skills/list timed out");
4679
+ return codexHarnessCommands(list);
4680
+ } catch (error) {
4681
+ debugCodex("skills/list unavailable; reporting built-in commands only: %o", error);
4682
+ return builtinHarnessCommands("codex");
4683
+ }
4684
+ }
4375
4685
  async function terminateBackgroundTerminals(client, threadId) {
4376
4686
  await withTimeout((async () => {
4377
4687
  try {
@@ -5070,19 +5380,9 @@ async function createRuntime(request, inputParts) {
5070
5380
  };
5071
5381
  }
5072
5382
  async function buildCodexInputItems(options, inputParts) {
5073
- const textPrompt = joinTextParts(
5074
- inputParts.filter(
5075
- (part) => part.type === "text"
5076
- )
5383
+ const inputItems = inputParts.flatMap(
5384
+ (part) => part.type === "text" && part.text.trim().length > 0 ? [{ type: "text", text: part.text, text_elements: [] }] : []
5077
5385
  );
5078
- const inputItems = [];
5079
- if (textPrompt.trim().length > 0) {
5080
- inputItems.push({
5081
- type: "text",
5082
- text: textPrompt,
5083
- text_elements: []
5084
- });
5085
- }
5086
5386
  inputItems.push(
5087
5387
  ...await mapToCodexPromptParts(
5088
5388
  inputParts,
@@ -5484,17 +5784,40 @@ var CodexAgentAdapter = class {
5484
5784
  const modes = await client.request("collaborationMode/list", {});
5485
5785
  if (!modes.data.some((mode) => mode.mode === request.run.mode)) throw new Error("This Codex installation does not support the requested planning mode.");
5486
5786
  }
5787
+ const emitHarnessCommands = (commands) => sink.emitEvent(
5788
+ createNormalizedEvent(
5789
+ "harness.commands",
5790
+ { provider: request.provider, runId: request.runId },
5791
+ { commands }
5792
+ )
5793
+ );
5794
+ const inventory = listCodexHarnessCommands(client, cwd).then((commands) => {
5795
+ emitHarnessCommands(commands);
5796
+ return commands;
5797
+ });
5798
+ inventory.catch(() => void 0);
5487
5799
  if (request.run.goal) {
5488
5800
  await client.request("thread/goal/set", { threadId: threadResponse.thread.id, objective: request.run.goal, status: "active" });
5489
5801
  }
5490
- await client.request(
5491
- "turn/start",
5492
- buildCodexTurnStartParams({
5493
- threadId: threadResponse.thread.id,
5494
- inputItems: runtime.inputItems,
5495
- request
5496
- })
5802
+ const command = request.run.command;
5803
+ const skillNames = new Set(
5804
+ command && !CODEX_BUILTIN_COMMAND_NAMES.has(command.name) ? (await inventory).filter((entry) => entry.source !== "builtin").map((entry) => entry.name) : []
5497
5805
  );
5806
+ const dispatch = resolveCodexCommandDispatch(command, runtime.inputItems, skillNames);
5807
+ if (dispatch.kind === "compact") {
5808
+ await client.request("thread/compact/start", { threadId: threadResponse.thread.id });
5809
+ } else if (dispatch.kind === "review") {
5810
+ await client.request("review/start", { threadId: threadResponse.thread.id, target: dispatch.target, delivery: "inline" });
5811
+ } else {
5812
+ await client.request(
5813
+ "turn/start",
5814
+ buildCodexTurnStartParams({
5815
+ threadId: threadResponse.thread.id,
5816
+ inputItems: dispatch.inputItems,
5817
+ request
5818
+ })
5819
+ );
5820
+ }
5498
5821
  let completionResult;
5499
5822
  let completionError;
5500
5823
  try {
@@ -5502,6 +5825,10 @@ var CodexAgentAdapter = class {
5502
5825
  } catch (err) {
5503
5826
  completionError = err;
5504
5827
  }
5828
+ await withTimeout(
5829
+ inventory.catch(() => void 0),
5830
+ HARNESS_COMMANDS_SETTLE_GRACE_MS
5831
+ );
5505
5832
  endWait();
5506
5833
  if (completionError !== void 0) {
5507
5834
  if (abortInvoked) {
@@ -5724,6 +6051,60 @@ function toRawEvent3(runId, payload, type) {
5724
6051
  function injectedTaskResultChild(text2) {
5725
6052
  return /<task id="?([^"\s>]+)"? state="?(?:completed|error)"?>/.exec(text2)?.[1];
5726
6053
  }
6054
+ function resolveOpenCodeCommandDispatch(command, harnessCommands) {
6055
+ if (!command) return { kind: "prompt" };
6056
+ if (command.name === "compact") return { kind: "summarize" };
6057
+ const known = harnessCommands.find((entry) => entry.name === command.name);
6058
+ if (!known) return { kind: "prompt" };
6059
+ if (known.source === "skill")
6060
+ return { kind: "prompt", text: skillDirective(command.name, command.args) };
6061
+ return { kind: "command", command: command.name, arguments: command.args };
6062
+ }
6063
+ function replaceOpenCodePromptText(parts, text2) {
6064
+ let replaced = false;
6065
+ const next = parts.map((part) => {
6066
+ if (part.type !== "text" || replaced) return part;
6067
+ replaced = true;
6068
+ return { ...part, text: text2 };
6069
+ });
6070
+ return replaced ? next : [{ type: "text", text: text2 }, ...next];
6071
+ }
6072
+ var OPENCODE_COMMAND_DISCOVERY_TIMEOUT_MS = 5e3;
6073
+ async function listOpenCodeHarnessCommands(runtime) {
6074
+ const init = {
6075
+ headers: runtime.previewHeaders,
6076
+ signal: AbortSignal.timeout(OPENCODE_COMMAND_DISCOVERY_TIMEOUT_MS)
6077
+ };
6078
+ try {
6079
+ const listed = await withTimeout(
6080
+ Promise.all([
6081
+ fetchJson(`${runtime.baseUrl}/command`, init),
6082
+ fetchJson(`${runtime.baseUrl}/skill`, init).catch(
6083
+ () => []
6084
+ )
6085
+ ]),
6086
+ OPENCODE_COMMAND_DISCOVERY_TIMEOUT_MS
6087
+ );
6088
+ if (!listed) {
6089
+ debugOpencode(
6090
+ "GET /command did not answer within %dms; reporting built-in commands only",
6091
+ OPENCODE_COMMAND_DISCOVERY_TIMEOUT_MS
6092
+ );
6093
+ return builtinHarnessCommands("open-code");
6094
+ }
6095
+ const [commands, skills] = listed;
6096
+ return openCodeHarnessCommands(
6097
+ Array.isArray(commands) ? commands : [],
6098
+ Array.isArray(skills) ? skills : []
6099
+ );
6100
+ } catch (error) {
6101
+ debugOpencode(
6102
+ "GET /command unavailable; reporting built-in commands only: %o",
6103
+ error
6104
+ );
6105
+ return builtinHarnessCommands("open-code");
6106
+ }
6107
+ }
5727
6108
  function toOpenCodeModel(model) {
5728
6109
  if (!model) {
5729
6110
  return void 0;
@@ -6748,6 +7129,32 @@ var OpenCodeAgentAdapter = class {
6748
7129
  const name = request.run.mode === "plan" ? "plan" : "build";
6749
7130
  if (!agents.some((agent) => agent.name === name)) throw new Error(`This OpenCode installation does not expose the ${name} agent.`);
6750
7131
  }
7132
+ const harnessCommands = await listOpenCodeHarnessCommands(runtime);
7133
+ sink.emitEvent(
7134
+ createNormalizedEvent(
7135
+ "harness.commands",
7136
+ { provider: request.provider, runId: request.runId },
7137
+ { commands: harnessCommands }
7138
+ )
7139
+ );
7140
+ const commandDispatch = resolveOpenCodeCommandDispatch(request.run.command, harnessCommands);
7141
+ if (commandDispatch.kind === "command" && request.run.systemPrompt) {
7142
+ throw new Error(
7143
+ "OpenCode commands do not support a per-run systemPrompt. Use a normal prompt, or configure the systemPrompt on the Agent at setup time."
7144
+ );
7145
+ }
7146
+ const dispatchBlocking = (endpoint, body) => {
7147
+ void fetch(`${runtime.baseUrl}/session/${sessionId}/${endpoint}`, {
7148
+ method: "POST",
7149
+ headers: { "content-type": "application/json", ...runtime.previewHeaders },
7150
+ body: JSON.stringify(body)
7151
+ }).then((response) => {
7152
+ if (!response.ok) throw new Error(`POST /session/${sessionId}/${endpoint} returned ${response.status}`);
7153
+ }).catch((error) => {
7154
+ if (!dispatchError) dispatchError = error;
7155
+ resolveSessionTerminal();
7156
+ });
7157
+ };
6751
7158
  const dispatchPrompt = async (parts) => {
6752
7159
  const body = JSON.stringify({
6753
7160
  ...request.run.model ? { model: toOpenCodeModel(request.run.model) } : {},
@@ -6816,7 +7223,24 @@ var OpenCodeAgentAdapter = class {
6816
7223
  sendToSession(queued);
6817
7224
  }
6818
7225
  try {
6819
- await dispatchPrompt(mapToOpenCodeParts(inputParts));
7226
+ if (commandDispatch.kind === "summarize") {
7227
+ const model = toOpenCodeModel(request.run.model);
7228
+ if (!model?.providerID) throw new Error("OpenCode compaction needs a provider-qualified model id.");
7229
+ dispatchBlocking("summarize", { providerID: model.providerID, modelID: model.modelID });
7230
+ } else if (commandDispatch.kind === "command") {
7231
+ dispatchBlocking("command", {
7232
+ command: commandDispatch.command,
7233
+ arguments: commandDispatch.arguments,
7234
+ parts: mapToOpenCodeParts(inputParts).filter((part) => part.type === "file"),
7235
+ ...request.run.model?.includes("/") ? { model: request.run.model } : {},
7236
+ ...request.run.mode ? { agent: request.run.mode === "plan" ? "plan" : "build" } : request.options.configuration === "native" ? {} : { agent: agentSlug }
7237
+ });
7238
+ } else {
7239
+ const parts = mapToOpenCodeParts(inputParts);
7240
+ await dispatchPrompt(
7241
+ commandDispatch.text === void 0 ? parts : replaceOpenCodePromptText(parts, commandDispatch.text)
7242
+ );
7243
+ }
6820
7244
  } catch (error) {
6821
7245
  if (!dispatchError) {
6822
7246
  dispatchError = error;
@@ -7574,7 +7998,10 @@ function harnessCapabilities(provider) {
7574
7998
  function resolveHarnessCommand(provider, input) {
7575
7999
  const first = typeof input === "string" ? input : input.find((part) => part.type === "text")?.text;
7576
8000
  const match = first?.match(/^\s*\/(plan|agent|goal)(?:\s+([\s\S]*))?$/);
7577
- if (!match) return { input };
8001
+ if (!match) {
8002
+ const invocation = first ? parseHarnessCommandInvocation(first) : void 0;
8003
+ return invocation ? { input, command: invocation } : { input };
8004
+ }
7578
8005
  const command = match[1];
7579
8006
  if (!harnessCapabilities(provider).commands.includes(command)) throw new Error(`/${command} is not supported by ${provider}.`);
7580
8007
  const body = match[2]?.trim() ?? "";
@@ -7591,6 +8018,17 @@ function resolveHarnessCommand(provider, input) {
7591
8018
  }
7592
8019
 
7593
8020
  export {
8021
+ MAX_HARNESS_COMMANDS,
8022
+ MAX_HARNESS_COMMAND_NAME,
8023
+ MAX_HARNESS_COMMAND_DESCRIPTION,
8024
+ MAX_HARNESS_COMMAND_ARGUMENT_HINT,
8025
+ builtinHarnessCommands,
8026
+ parseHarnessCommandInvocation,
8027
+ claudeHarnessCommands,
8028
+ codexHarnessCommands,
8029
+ codexSkillMention,
8030
+ openCodeHarnessCommands,
8031
+ skillDirective,
7594
8032
  agentboxRoot,
7595
8033
  getAgentLayout,
7596
8034
  Agent,
@@ -1,4 +1,4 @@
1
- export { A as AISDKEvent, C as BackgroundTask, D as BackgroundTasksEvent, W as MessageCompletedEvent, X as MessageInjectedEvent, Y as MessageStartedEvent, Z as NativePlanEvent, _ as NormalizedAgentEvent, $ as NormalizedAgentEventBase, a0 as NormalizedAgentEventType, a7 as PermissionRequestedEvent, a8 as PermissionResolvedEvent, a9 as RawAgentEvent, aa as ReasoningDeltaEvent, ac as RunCancelledEvent, ad as RunCompletedEvent, ae as RunErrorEvent, af as RunStartedEvent, ah as TextDeltaEvent, aj as ToolCallCompletedEvent, ak as ToolCallDeltaEvent, al as ToolCallStartedEvent, ao as createNormalizedEvent, ap as normalizeRawAgentEvent, aq as toAISDKEvent, ar as toAISDKStream } from '../types-BKvKgRMY.js';
1
+ export { A as AISDKEvent, C as BackgroundTask, D as BackgroundTasksEvent, Z as HarnessCommandsEvent, a3 as MessageCompletedEvent, a4 as MessageInjectedEvent, a5 as MessageStartedEvent, a6 as NativePlanEvent, a7 as NormalizedAgentEvent, a8 as NormalizedAgentEventBase, a9 as NormalizedAgentEventType, ai as PermissionRequestedEvent, aj as PermissionResolvedEvent, ak as RawAgentEvent, al as ReasoningDeltaEvent, an as RunCancelledEvent, ao as RunCompletedEvent, ap as RunErrorEvent, aq as RunStartedEvent, as as TextDeltaEvent, au as ToolCallCompletedEvent, av as ToolCallDeltaEvent, aw as ToolCallStartedEvent, aD as createNormalizedEvent, aE as normalizeRawAgentEvent, aI as toAISDKEvent, aJ as toAISDKStream } from '../types-CrbPZ814.js';
2
2
  import { AgentProvider } from '../enums.js';
3
3
  import '../Sandbox-DcKAU-E3.js';
4
4
  import 'e2b';
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { A as AISDKEvent, a as AgentApprovalMode, b as AgentAttachRequest, c as AgentCommandConfig, d as AgentCostData, e as AgentExecutionRequest, f as AgentLocalMcpConfig, g as AgentMcpConfig, h as AgentOptions, i as AgentOptionsBase, j as AgentOptionsMap, k as AgentPermissionDecision, l as AgentPermissionKind, m as AgentPermissionResponse, n as AgentProviderAdapter, o as AgentProviderName, p as AgentReasoningEffort, q as AgentRemoteMcpConfig, r as AgentResult, s as AgentRun, t as AgentRunConfig, u as AgentRunSink, v as AgentSetupRequest, w as AgentSkillConfig, x as AgentSubAgentConfig, y as AgentUserAnswer, z as AgentUserQuestion, B as AttachedRun, C as BackgroundTask, D as BackgroundTasksEvent, E as ClaudeCodeAgentOptions, F as ClaudeCodeHookConfig, G as ClaudeCodeHookEvent, H as ClaudeCodeHookHandler, I as ClaudeCodeHookMatcherGroup, J as ClaudeCodeHooksConfig, K as ClaudeCodeProviderOptions, L as CodexAgentOptions, M as CodexCommandHook, N as CodexHookEvent, O as CodexHookMatcherGroup, P as CodexHooksConfig, Q as CodexModelProviderConfig, R as CodexProviderOptions, S as DataContent, T as EmbeddedSkillConfig, U as FilePart, V as ImagePart, W as MessageCompletedEvent, X as MessageInjectedEvent, Y as MessageStartedEvent, Z as NativePlanEvent, _ as NormalizedAgentEvent, $ as NormalizedAgentEventBase, a0 as NormalizedAgentEventType, a1 as OpenCodeAgentOptions, a2 as OpenCodePluginConfig, a3 as OpenCodePluginEvent, a4 as OpenCodePluginHookConfig, a5 as OpenCodeProviderOptions, a6 as OpenRouterPlugin, a7 as PermissionRequestedEvent, a8 as PermissionResolvedEvent, a9 as RawAgentEvent, aa as ReasoningDeltaEvent, ab as RepoSkillConfig, ac as RunCancelledEvent, ad as RunCompletedEvent, ae as RunErrorEvent, af as RunStartedEvent, ag as SetupLayout, ah as TextDeltaEvent, ai as TextPart, aj as ToolCallCompletedEvent, ak as ToolCallDeltaEvent, al as ToolCallStartedEvent, am as UserContent, an as UserContentPart, ao as createNormalizedEvent, ap as normalizeRawAgentEvent, aq as toAISDKEvent, ar as toAISDKStream } from './types-BKvKgRMY.js';
1
+ export { A as AISDKEvent, a as AgentApprovalMode, b as AgentAttachRequest, c as AgentCommandConfig, d as AgentCostData, e as AgentExecutionRequest, f as AgentLocalMcpConfig, g as AgentMcpConfig, h as AgentOptions, i as AgentOptionsBase, j as AgentOptionsMap, k as AgentPermissionDecision, l as AgentPermissionKind, m as AgentPermissionResponse, n as AgentProviderAdapter, o as AgentProviderName, p as AgentReasoningEffort, q as AgentRemoteMcpConfig, r as AgentResult, s as AgentRun, t as AgentRunConfig, u as AgentRunSink, v as AgentSetupRequest, w as AgentSkillConfig, x as AgentSubAgentConfig, y as AgentUserAnswer, z as AgentUserQuestion, B as AttachedRun, C as BackgroundTask, D as BackgroundTasksEvent, E as ClaudeCodeAgentOptions, F as ClaudeCodeHookConfig, G as ClaudeCodeHookEvent, H as ClaudeCodeHookHandler, I as ClaudeCodeHookMatcherGroup, J as ClaudeCodeHooksConfig, K as ClaudeCodeProviderOptions, L as CodexAgentOptions, M as CodexCommandHook, N as CodexHookEvent, O as CodexHookMatcherGroup, P as CodexHooksConfig, Q as CodexModelProviderConfig, R as CodexProviderOptions, S as CodexSkillEntry, T as DataContent, U as EmbeddedSkillConfig, V as FilePart, W as HarnessCommandDescriptor, X as HarnessCommandInvocation, Y as HarnessCommandSource, Z as HarnessCommandsEvent, _ as ImagePart, $ as MAX_HARNESS_COMMANDS, a0 as MAX_HARNESS_COMMAND_ARGUMENT_HINT, a1 as MAX_HARNESS_COMMAND_DESCRIPTION, a2 as MAX_HARNESS_COMMAND_NAME, a3 as MessageCompletedEvent, a4 as MessageInjectedEvent, a5 as MessageStartedEvent, a6 as NativePlanEvent, a7 as NormalizedAgentEvent, a8 as NormalizedAgentEventBase, a9 as NormalizedAgentEventType, aa as OpenCodeAgentOptions, ab as OpenCodeCommandEntry, ac as OpenCodePluginConfig, ad as OpenCodePluginEvent, ae as OpenCodePluginHookConfig, af as OpenCodeProviderOptions, ag as OpenCodeSkillEntry, ah as OpenRouterPlugin, ai as PermissionRequestedEvent, aj as PermissionResolvedEvent, ak as RawAgentEvent, al as ReasoningDeltaEvent, am as RepoSkillConfig, an as RunCancelledEvent, ao as RunCompletedEvent, ap as RunErrorEvent, aq as RunStartedEvent, ar as SetupLayout, as as TextDeltaEvent, at as TextPart, au as ToolCallCompletedEvent, av as ToolCallDeltaEvent, aw as ToolCallStartedEvent, ax as UserContent, ay as UserContentPart, az as builtinHarnessCommands, aA as claudeHarnessCommands, aB as codexHarnessCommands, aC as codexSkillMention, aD as createNormalizedEvent, aE as normalizeRawAgentEvent, aF as openCodeHarnessCommands, aG as parseHarnessCommandInvocation, aH as skillDirective, aI as toAISDKEvent, aJ as toAISDKStream } from './types-CrbPZ814.js';
2
2
  export { AGENT_RESERVED_PORTS, Agent, HarnessCapabilities, HarnessCommand, agentboxRoot, collectAllAgentReservedPorts, getAgentLayout, harnessCapabilities, resolveHarnessCommand } from './agents/index.js';
3
3
  export { A as AsyncCommandHandle, C as CommandEvent, a as CommandOptions, b as CommandResult, D as DaytonaProviderOptions, c as DaytonaSandboxOptions, E as E2bProviderOptions, d as E2bSandboxOptions, G as GitCloneOptions, L as LocalDockerProviderOptions, e as LocalDockerSandboxOptions, M as ModalProviderOptions, f as ModalSandboxOptions, S as Sandbox, g as SandboxDescriptor, h as SandboxListOptions, i as SandboxOptions, j as SandboxOptionsBase, k as SandboxOptionsMap, l as SandboxProviderName, m as SandboxRaw, n as SandboxRawMap, o as SandboxResourceSpec, T as TarballEntry, V as VercelGitSource, p as VercelProviderOptions, q as VercelSandboxOptions } from './Sandbox-DcKAU-E3.js';
4
4
  export { SandboxAdapter, buildGitCloneCommand } from './sandboxes/index.js';
package/dist/index.js CHANGED
@@ -1,10 +1,21 @@
1
1
  import {
2
2
  Agent,
3
+ MAX_HARNESS_COMMANDS,
4
+ MAX_HARNESS_COMMAND_ARGUMENT_HINT,
5
+ MAX_HARNESS_COMMAND_DESCRIPTION,
6
+ MAX_HARNESS_COMMAND_NAME,
3
7
  agentboxRoot,
8
+ builtinHarnessCommands,
9
+ claudeHarnessCommands,
10
+ codexHarnessCommands,
11
+ codexSkillMention,
4
12
  getAgentLayout,
5
13
  harnessCapabilities,
6
- resolveHarnessCommand
7
- } from "./chunk-SERVEWIE.js";
14
+ openCodeHarnessCommands,
15
+ parseHarnessCommandInvocation,
16
+ resolveHarnessCommand,
17
+ skillDirective
18
+ } from "./chunk-U3E62L37.js";
8
19
  import {
9
20
  ProviderLogAssembler,
10
21
  createNormalizedEvent,
@@ -30,18 +41,29 @@ export {
30
41
  AGENT_RESERVED_PORTS,
31
42
  Agent,
32
43
  AgentProvider,
44
+ MAX_HARNESS_COMMANDS,
45
+ MAX_HARNESS_COMMAND_ARGUMENT_HINT,
46
+ MAX_HARNESS_COMMAND_DESCRIPTION,
47
+ MAX_HARNESS_COMMAND_NAME,
33
48
  ProviderLogAssembler,
34
49
  Sandbox,
35
50
  SandboxAdapter,
36
51
  SandboxProvider,
37
52
  agentboxRoot,
38
53
  buildGitCloneCommand,
54
+ builtinHarnessCommands,
55
+ claudeHarnessCommands,
56
+ codexHarnessCommands,
57
+ codexSkillMention,
39
58
  collectAllAgentReservedPorts,
40
59
  createNormalizedEvent,
41
60
  getAgentLayout,
42
61
  harnessCapabilities,
43
62
  normalizeRawAgentEvent,
63
+ openCodeHarnessCommands,
64
+ parseHarnessCommandInvocation,
44
65
  resolveHarnessCommand,
66
+ skillDirective,
45
67
  toAISDKEvent,
46
68
  toAISDKStream
47
69
  };
@@ -9,7 +9,92 @@ interface RawAgentEvent<TPayload = unknown> {
9
9
  payload: TPayload;
10
10
  }
11
11
 
12
- type NormalizedAgentEventType = "plan.completed" | "run.started" | "message.started" | "message.injected" | "text.delta" | "reasoning.delta" | "tool.call.started" | "tool.call.delta" | "tool.call.completed" | "permission.requested" | "permission.resolved" | "message.completed" | "background.tasks" | "run.completed" | "run.cancelled" | "run.error";
12
+ /**
13
+ * Where a harness command comes from. `builtin` commands ship with the CLI;
14
+ * `skill`, `custom`, `plugin`, and `mcp` commands are discovered from the
15
+ * environment the harness runs in and can differ per project.
16
+ */
17
+ type HarnessCommandSource = "builtin" | "skill" | "custom" | "plugin" | "mcp";
18
+ /** A slash command the harness can run, as shown in a host's `/` palette. */
19
+ interface HarnessCommandDescriptor {
20
+ /** Name as typed after the slash, e.g. `compact` or `posthog:signals`. */
21
+ name: string;
22
+ description?: string;
23
+ /** Free-text hint for what follows the name, e.g. `<optional instructions>`. */
24
+ argumentHint?: string;
25
+ source: HarnessCommandSource;
26
+ }
27
+ /** A leading `/name args` token from user input, resolved by each adapter. */
28
+ interface HarnessCommandInvocation {
29
+ name: string;
30
+ /** Text after the command name, trimmed. Empty when none was given. */
31
+ args: string;
32
+ }
33
+ declare const MAX_HARNESS_COMMANDS = 500;
34
+ declare const MAX_HARNESS_COMMAND_NAME = 200;
35
+ declare const MAX_HARNESS_COMMAND_DESCRIPTION = 500;
36
+ declare const MAX_HARNESS_COMMAND_ARGUMENT_HINT = 200;
37
+ /**
38
+ * Commands known to work for every installation of the harness when driven
39
+ * headlessly. A live run replaces this list with what the harness reports.
40
+ */
41
+ declare function builtinHarnessCommands(provider: AgentProviderName): HarnessCommandDescriptor[];
42
+ /**
43
+ * Parse a leading `/name args` token. Only a bare name qualifies: a path such
44
+ * as `/src/app.ts` or a name followed by punctuation is prose, not a command.
45
+ */
46
+ declare function parseHarnessCommandInvocation(text: string): HarnessCommandInvocation | undefined;
47
+ /**
48
+ * Turn Claude Code's `system/init` command inventory into descriptors. The
49
+ * headless CLI already omits commands that need an interactive terminal; this
50
+ * additionally hides host-owned settings, internal commands, and the
51
+ * commands flagged as bound to the local terminal.
52
+ */
53
+ declare function claudeHarnessCommands(init: {
54
+ slash_commands?: string[];
55
+ skills?: string[];
56
+ terminal_slash_commands?: string[];
57
+ plugins?: Array<{
58
+ name: string;
59
+ }>;
60
+ }): HarnessCommandDescriptor[];
61
+ /** One entry of Codex's `skills/list` response. */
62
+ interface CodexSkillEntry {
63
+ name: string;
64
+ description?: string;
65
+ enabled?: boolean;
66
+ pluginId?: string | null;
67
+ interface?: {
68
+ shortDescription?: string;
69
+ displayName?: string;
70
+ } | null;
71
+ }
72
+ /** Codex `skills/list` groups skills per working directory. */
73
+ declare function codexHarnessCommands(list: {
74
+ data?: Array<{
75
+ skills?: CodexSkillEntry[];
76
+ }>;
77
+ }): HarnessCommandDescriptor[];
78
+ /** Skill mention Codex resolves from prompt text (`$name`). */
79
+ declare function codexSkillMention(name: string): string;
80
+ /** One entry of OpenCode's `GET /command` response. */
81
+ interface OpenCodeCommandEntry {
82
+ name: string;
83
+ description?: string;
84
+ mcp?: boolean;
85
+ hints?: string[];
86
+ source?: string;
87
+ }
88
+ /** One entry of OpenCode's `GET /skill` response. */
89
+ interface OpenCodeSkillEntry {
90
+ name: string;
91
+ description?: string;
92
+ }
93
+ declare function openCodeHarnessCommands(commands: OpenCodeCommandEntry[], skills?: OpenCodeSkillEntry[]): HarnessCommandDescriptor[];
94
+ /** Natural-language directive for harnesses whose skills the model invokes. */
95
+ declare function skillDirective(name: string, args: string): string;
96
+
97
+ type NormalizedAgentEventType = "plan.completed" | "harness.commands" | "run.started" | "message.started" | "message.injected" | "text.delta" | "reasoning.delta" | "tool.call.started" | "tool.call.delta" | "tool.call.completed" | "permission.requested" | "permission.resolved" | "message.completed" | "background.tasks" | "run.completed" | "run.cancelled" | "run.error";
13
98
  interface NormalizedAgentEventBase {
14
99
  provider: string;
15
100
  runId: string;
@@ -132,7 +217,17 @@ interface NativePlanEvent extends NormalizedAgentEventBase {
132
217
  type: "plan.completed";
133
218
  text: string;
134
219
  }
135
- type NormalizedAgentEvent = NativePlanEvent | RunStartedEvent | MessageStartedEvent | MessageInjectedEvent | TextDeltaEvent | ReasoningDeltaEvent | ToolCallStartedEvent | ToolCallDeltaEvent | ToolCallCompletedEvent | PermissionRequestedEvent | PermissionResolvedEvent | MessageCompletedEvent | BackgroundTasksEvent | RunCompletedEvent | RunCancelledEvent | RunErrorEvent;
220
+ /**
221
+ * Slash commands the harness reports for this session: built-ins usable
222
+ * headlessly plus the skills, custom commands, plugin commands, and MCP
223
+ * prompts discovered in its environment. Emitted once a run knows them
224
+ * (Claude Code `system/init`, Codex `skills/list`, OpenCode `GET /command`).
225
+ */
226
+ interface HarnessCommandsEvent extends NormalizedAgentEventBase {
227
+ type: "harness.commands";
228
+ commands: HarnessCommandDescriptor[];
229
+ }
230
+ type NormalizedAgentEvent = NativePlanEvent | HarnessCommandsEvent | RunStartedEvent | MessageStartedEvent | MessageInjectedEvent | TextDeltaEvent | ReasoningDeltaEvent | ToolCallStartedEvent | ToolCallDeltaEvent | ToolCallCompletedEvent | PermissionRequestedEvent | PermissionResolvedEvent | MessageCompletedEvent | BackgroundTasksEvent | RunCompletedEvent | RunCancelledEvent | RunErrorEvent;
136
231
  declare function createNormalizedEvent<TType extends NormalizedAgentEventType>(type: TType, base: Omit<NormalizedAgentEventBase, "type" | "timestamp"> & {
137
232
  timestamp?: string;
138
233
  }, extra?: Record<string, unknown>): NormalizedAgentEvent;
@@ -421,6 +516,14 @@ interface AgentRunConfig {
421
516
  mode?: "plan" | "default";
422
517
  /** Native goal objective. Unsupported harnesses reject it. */
423
518
  goal?: string;
519
+ /**
520
+ * Leading `/name args` token of {@link input}, as parsed by
521
+ * `resolveHarnessCommand`. The input keeps the raw text: Claude Code
522
+ * dispatches slash commands itself, while the Codex and OpenCode adapters
523
+ * map known names to native calls (compaction, review, commands, skills)
524
+ * and send unknown ones as plain text.
525
+ */
526
+ command?: HarnessCommandInvocation;
424
527
  }
425
528
  type AgentApprovalMode = "auto" | "interactive";
426
529
  type AgentPermissionKind = "bash" | "edit" | "tool" | "network" | "file-change" | "question" | "plan" | "unknown";
@@ -872,4 +975,4 @@ interface AgentProviderAdapter<P extends AgentProviderName = AgentProviderName>
872
975
  attachSendMessage(request: AgentAttachRequest<P>, content: UserContent): Promise<void>;
873
976
  }
874
977
 
875
- export { type NormalizedAgentEventBase as $, type AISDKEvent as A, type AttachedRun as B, type BackgroundTask as C, type BackgroundTasksEvent as D, type ClaudeCodeAgentOptions as E, type ClaudeCodeHookConfig as F, type ClaudeCodeHookEvent as G, type ClaudeCodeHookHandler as H, type ClaudeCodeHookMatcherGroup as I, type ClaudeCodeHooksConfig as J, type ClaudeCodeProviderOptions as K, type CodexAgentOptions as L, type CodexCommandHook as M, type CodexHookEvent as N, type CodexHookMatcherGroup as O, type CodexHooksConfig as P, type CodexModelProviderConfig as Q, type CodexProviderOptions as R, type DataContent as S, type EmbeddedSkillConfig as T, type FilePart as U, type ImagePart as V, type MessageCompletedEvent as W, type MessageInjectedEvent as X, type MessageStartedEvent as Y, type NativePlanEvent as Z, type NormalizedAgentEvent as _, type AgentApprovalMode as a, type NormalizedAgentEventType as a0, type OpenCodeAgentOptions as a1, type OpenCodePluginConfig as a2, type OpenCodePluginEvent as a3, type OpenCodePluginHookConfig as a4, type OpenCodeProviderOptions as a5, type OpenRouterPlugin as a6, type PermissionRequestedEvent as a7, type PermissionResolvedEvent as a8, type RawAgentEvent as a9, type ReasoningDeltaEvent as aa, type RepoSkillConfig as ab, type RunCancelledEvent as ac, type RunCompletedEvent as ad, type RunErrorEvent as ae, type RunStartedEvent as af, type SetupLayout as ag, type TextDeltaEvent as ah, type TextPart as ai, type ToolCallCompletedEvent as aj, type ToolCallDeltaEvent as ak, type ToolCallStartedEvent as al, type UserContent as am, type UserContentPart as an, createNormalizedEvent as ao, normalizeRawAgentEvent as ap, toAISDKEvent as aq, toAISDKStream as ar, type AgentAttachRequest as b, type AgentCommandConfig as c, type AgentCostData as d, type AgentExecutionRequest as e, type AgentLocalMcpConfig as f, type AgentMcpConfig as g, type AgentOptions as h, type AgentOptionsBase as i, type AgentOptionsMap as j, type AgentPermissionDecision as k, type AgentPermissionKind as l, type AgentPermissionResponse as m, type AgentProviderAdapter as n, type AgentProviderName as o, type AgentReasoningEffort as p, type AgentRemoteMcpConfig as q, type AgentResult as r, type AgentRun as s, type AgentRunConfig as t, type AgentRunSink as u, type AgentSetupRequest as v, type AgentSkillConfig as w, type AgentSubAgentConfig as x, type AgentUserAnswer as y, type AgentUserQuestion as z };
978
+ export { MAX_HARNESS_COMMANDS as $, type AISDKEvent as A, type AttachedRun as B, type BackgroundTask as C, type BackgroundTasksEvent as D, type ClaudeCodeAgentOptions as E, type ClaudeCodeHookConfig as F, type ClaudeCodeHookEvent as G, type ClaudeCodeHookHandler as H, type ClaudeCodeHookMatcherGroup as I, type ClaudeCodeHooksConfig as J, type ClaudeCodeProviderOptions as K, type CodexAgentOptions as L, type CodexCommandHook as M, type CodexHookEvent as N, type CodexHookMatcherGroup as O, type CodexHooksConfig as P, type CodexModelProviderConfig as Q, type CodexProviderOptions as R, type CodexSkillEntry as S, type DataContent as T, type EmbeddedSkillConfig as U, type FilePart as V, type HarnessCommandDescriptor as W, type HarnessCommandInvocation as X, type HarnessCommandSource as Y, type HarnessCommandsEvent as Z, type ImagePart as _, type AgentApprovalMode as a, MAX_HARNESS_COMMAND_ARGUMENT_HINT as a0, MAX_HARNESS_COMMAND_DESCRIPTION as a1, MAX_HARNESS_COMMAND_NAME as a2, type MessageCompletedEvent as a3, type MessageInjectedEvent as a4, type MessageStartedEvent as a5, type NativePlanEvent as a6, type NormalizedAgentEvent as a7, type NormalizedAgentEventBase as a8, type NormalizedAgentEventType as a9, claudeHarnessCommands as aA, codexHarnessCommands as aB, codexSkillMention as aC, createNormalizedEvent as aD, normalizeRawAgentEvent as aE, openCodeHarnessCommands as aF, parseHarnessCommandInvocation as aG, skillDirective as aH, toAISDKEvent as aI, toAISDKStream as aJ, type OpenCodeAgentOptions as aa, type OpenCodeCommandEntry as ab, type OpenCodePluginConfig as ac, type OpenCodePluginEvent as ad, type OpenCodePluginHookConfig as ae, type OpenCodeProviderOptions as af, type OpenCodeSkillEntry as ag, type OpenRouterPlugin as ah, type PermissionRequestedEvent as ai, type PermissionResolvedEvent as aj, type RawAgentEvent as ak, type ReasoningDeltaEvent as al, type RepoSkillConfig as am, type RunCancelledEvent as an, type RunCompletedEvent as ao, type RunErrorEvent as ap, type RunStartedEvent as aq, type SetupLayout as ar, type TextDeltaEvent as as, type TextPart as at, type ToolCallCompletedEvent as au, type ToolCallDeltaEvent as av, type ToolCallStartedEvent as aw, type UserContent as ax, type UserContentPart as ay, builtinHarnessCommands as az, type AgentAttachRequest as b, type AgentCommandConfig as c, type AgentCostData as d, type AgentExecutionRequest as e, type AgentLocalMcpConfig as f, type AgentMcpConfig as g, type AgentOptions as h, type AgentOptionsBase as i, type AgentOptionsMap as j, type AgentPermissionDecision as k, type AgentPermissionKind as l, type AgentPermissionResponse as m, type AgentProviderAdapter as n, type AgentProviderName as o, type AgentReasoningEffort as p, type AgentRemoteMcpConfig as q, type AgentResult as r, type AgentRun as s, type AgentRunConfig as t, type AgentRunSink as u, type AgentSetupRequest as v, type AgentSkillConfig as w, type AgentSubAgentConfig as x, type AgentUserAnswer as y, type AgentUserQuestion as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentbox-sdk",
3
- "version": "0.1.516",
3
+ "version": "0.1.517",
4
4
  "description": "Swappable coding agents and sandbox providers for Bun and TypeScript.",
5
5
  "license": "MIT",
6
6
  "repository": {