agentbox-sdk 0.1.516 → 0.1.518

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.
@@ -687,6 +713,15 @@ array containing each `questionId` and its selected or custom `values`, or use
687
713
  Question answers cannot modify unrelated tool arguments. Ordinary tool requests
688
714
  use the same API without `answers`.
689
715
 
716
+ Codex can also ask without pausing (`request_user_input_async`): the app-server
717
+ accepts the call itself and the turn keeps working. That ask is not a permission
718
+ request; it arrives as a `message.completed` event carrying `questions` (same
719
+ `AgentUserQuestion` shape, bare-string options become labels) next to the text
720
+ Codex rendered for it. Nothing is pending, so there is nothing to respond to:
721
+ relay the user's choice as a follow-up message (`run.sendMessage()` while the
722
+ run is live, otherwise the next run of the session). Claude Code and OpenCode
723
+ have no non-blocking ask; their questions always pause as `permission.requested`.
724
+
690
725
  Native runtimes own a POSIX process group by default. Termination is bounded and
691
726
  escalates to SIGKILL if the process ignores SIGTERM. A supervisor that launches
692
727
  each run in its own process group can set `processGroup: "inherited"`; that
@@ -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-DjHP7dFq.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-DjHP7dFq.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-YV3DQS6Z.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";
@@ -153,6 +405,34 @@ function normalizeUserQuestions(provider, input) {
153
405
  return result;
154
406
  });
155
407
  }
408
+ function normalizeAsyncUserQuestions(provider, questions) {
409
+ if (!Array.isArray(questions) || !questions.length || questions.length > 10) return void 0;
410
+ try {
411
+ return questions.map((value, index) => {
412
+ const item = record(value);
413
+ if (item.isSecret === true) throw new Error("Secret questions cannot be relayed");
414
+ const options = item.options ?? [];
415
+ if (!Array.isArray(options) || options.length > 30) throw new Error("Unsupported agent question options");
416
+ const result = {
417
+ id: String(index),
418
+ question: text(item.title ?? item.question, 1e4),
419
+ ...item.header ? { header: text(item.header, 200) } : {},
420
+ // Codex async options are bare strings; blocking shapes use {label, description}.
421
+ options: options.map((value2) => {
422
+ if (typeof value2 === "string") return { label: text(value2, 1e3) };
423
+ const option = record(value2);
424
+ return { label: text(option.label, 1e3), ...option.description ? { description: text(option.description, 1e4) } : {} };
425
+ }),
426
+ multiple: provider === "claude-code" ? item.multiSelect === true : provider === "open-code" && item.multiple === true,
427
+ allowCustom: provider === "open-code" ? item.custom !== false : true
428
+ };
429
+ if (new Set(result.options.map((option) => option.label)).size !== result.options.length) throw new Error("Duplicate agent question options");
430
+ return result;
431
+ });
432
+ } catch {
433
+ return void 0;
434
+ }
435
+ }
156
436
  function validateUserAnswers(questions, answers) {
157
437
  if (!questions?.length || !answers || answers.length !== questions.length || new Set(answers.map((answer) => answer.questionId)).size !== answers.length) throw new Error("Answer each agent question once");
158
438
  return questions.map((question) => {
@@ -3566,6 +3846,13 @@ async function consumeClaudeMessages(request, sink, messages, executeStartedAt,
3566
3846
  "This Claude Code installation does not expose the native /goal command."
3567
3847
  );
3568
3848
  }
3849
+ sink.emitEvent(
3850
+ createNormalizedEvent(
3851
+ "harness.commands",
3852
+ { provider: request.provider, runId: request.runId },
3853
+ { commands: claudeHarnessCommands(sys) }
3854
+ )
3855
+ );
3569
3856
  if (sys.session_id) {
3570
3857
  debugClaude(
3571
3858
  "\u2605 session.init session_id=%s (%dms)",
@@ -4285,6 +4572,9 @@ function compactEnv(values) {
4285
4572
  function buildCodexSandboxMode(options) {
4286
4573
  return options.fullAccess ? "danger-full-access" : options.provider?.sandboxMode ?? (options.configuration === "native" ? void 0 : options.sandbox ? "workspace-write" : "read-only");
4287
4574
  }
4575
+ function buildCodexThreadConfig(request) {
4576
+ return request.run.reasoning ? { config: { model_reasoning_effort: request.run.reasoning } } : {};
4577
+ }
4288
4578
  function buildThreadParams(cwd, options, request) {
4289
4579
  return {
4290
4580
  cwd,
@@ -4292,6 +4582,7 @@ function buildThreadParams(cwd, options, request) {
4292
4582
  ...request.options.provider?.serviceTier !== void 0 ? { serviceTier: request.options.provider.serviceTier } : {},
4293
4583
  ...options.provider?.approvalPolicy ? { approvalPolicy: options.provider.approvalPolicy } : options.configuration === "native" && !options.fullAccess ? {} : { approvalPolicy: !options.fullAccess && isInteractiveApproval(options) ? "untrusted" : "never" },
4294
4584
  sandbox: buildCodexSandboxMode(options),
4585
+ ...buildCodexThreadConfig(request),
4295
4586
  serviceName: "agentbox",
4296
4587
  // Persist the rollout on disk so follow-up runs can call `thread/resume`.
4297
4588
  // `ephemeral: true` threads have no rollout file and resume fails with
@@ -4308,6 +4599,7 @@ function buildResumeParams(cwd, options, request) {
4308
4599
  ...request.options.provider?.serviceTier !== void 0 ? { serviceTier: request.options.provider.serviceTier } : {},
4309
4600
  ...options.provider?.approvalPolicy ? { approvalPolicy: options.provider.approvalPolicy } : options.configuration === "native" && !options.fullAccess ? {} : { approvalPolicy: !options.fullAccess && isInteractiveApproval(options) ? "untrusted" : "never" },
4310
4601
  sandbox: buildCodexSandboxMode(options),
4602
+ ...buildCodexThreadConfig(request),
4311
4603
  ...request.run.systemPrompt ? { developerInstructions: request.run.systemPrompt } : options.configuration === "native" ? {} : { developerInstructions: null },
4312
4604
  // We only need the thread id back; we never read `thread.turns`.
4313
4605
  // Without this Codex hydrates the full history into the response and
@@ -4325,6 +4617,7 @@ function buildForkParams(cwd, options, request) {
4325
4617
  ...request.options.provider?.serviceTier !== void 0 ? { serviceTier: request.options.provider.serviceTier } : {},
4326
4618
  ...options.provider?.approvalPolicy ? { approvalPolicy: options.provider.approvalPolicy } : options.configuration === "native" && !options.fullAccess ? {} : { approvalPolicy: !options.fullAccess && isInteractiveApproval(options) ? "untrusted" : "never" },
4327
4619
  sandbox: buildCodexSandboxMode(options),
4620
+ ...buildCodexThreadConfig(request),
4328
4621
  ...request.run.systemPrompt ? { developerInstructions: request.run.systemPrompt } : options.configuration === "native" ? {} : { developerInstructions: null },
4329
4622
  excludeTurns: true
4330
4623
  };
@@ -4372,6 +4665,51 @@ function buildCodexTurnStartParams(params) {
4372
4665
  };
4373
4666
  }
4374
4667
  var CODEX_CANCEL_TURN_TEXT = "Run cancelled by the host.";
4668
+ var CODEX_INIT_PROMPT = "Generate a file named AGENTS.md that serves as a contributor guide for this repository.";
4669
+ var CODEX_BUILTIN_COMMAND_NAMES = new Set(
4670
+ builtinHarnessCommands("codex").map((command) => command.name)
4671
+ );
4672
+ function replaceCodexPromptText(inputItems, text2) {
4673
+ let replaced = false;
4674
+ const next = inputItems.map((item) => {
4675
+ if (item.type !== "text" || replaced) return item;
4676
+ replaced = true;
4677
+ return { ...item, text: text2 };
4678
+ });
4679
+ return replaced ? next : [{ type: "text", text: text2, text_elements: [] }, ...next];
4680
+ }
4681
+ function resolveCodexCommandDispatch(command, inputItems, skillNames) {
4682
+ if (!command) return { kind: "turn", inputItems };
4683
+ const args = command.args;
4684
+ switch (command.name) {
4685
+ case "compact":
4686
+ return { kind: "compact" };
4687
+ case "review":
4688
+ return {
4689
+ kind: "review",
4690
+ target: args ? { type: "custom", instructions: args } : { type: "uncommittedChanges" }
4691
+ };
4692
+ case "init":
4693
+ return { kind: "turn", inputItems: replaceCodexPromptText(inputItems, args ? `${CODEX_INIT_PROMPT} ${args}` : CODEX_INIT_PROMPT) };
4694
+ default:
4695
+ if (skillNames.has(command.name)) {
4696
+ const mention = codexSkillMention(command.name);
4697
+ return { kind: "turn", inputItems: replaceCodexPromptText(inputItems, args ? `${mention} ${args}` : mention) };
4698
+ }
4699
+ return { kind: "turn", inputItems };
4700
+ }
4701
+ }
4702
+ var HARNESS_COMMANDS_SETTLE_GRACE_MS = 500;
4703
+ async function listCodexHarnessCommands(client, cwd) {
4704
+ try {
4705
+ const list = await withTimeout(client.request("skills/list", { cwds: [cwd] }), 5e3);
4706
+ if (!list) throw new Error("skills/list timed out");
4707
+ return codexHarnessCommands(list);
4708
+ } catch (error) {
4709
+ debugCodex("skills/list unavailable; reporting built-in commands only: %o", error);
4710
+ return builtinHarnessCommands("codex");
4711
+ }
4712
+ }
4375
4713
  async function terminateBackgroundTerminals(client, threadId) {
4376
4714
  await withTimeout((async () => {
4377
4715
  try {
@@ -4442,8 +4780,12 @@ function toNormalizedCodexEvents(runId, notification) {
4442
4780
  return [];
4443
4781
  }
4444
4782
  if (item.type === "agentMessage" && typeof item.text === "string") {
4783
+ const questions = normalizeAsyncUserQuestions(AgentProvider.Codex, item.questions);
4445
4784
  return [
4446
- createNormalizedEvent("message.completed", base, { text: item.text })
4785
+ createNormalizedEvent("message.completed", base, {
4786
+ text: item.text,
4787
+ ...questions ? { questions } : {}
4788
+ })
4447
4789
  ];
4448
4790
  }
4449
4791
  if (item.type === "reasoning" && item.summary) {
@@ -5070,19 +5412,9 @@ async function createRuntime(request, inputParts) {
5070
5412
  };
5071
5413
  }
5072
5414
  async function buildCodexInputItems(options, inputParts) {
5073
- const textPrompt = joinTextParts(
5074
- inputParts.filter(
5075
- (part) => part.type === "text"
5076
- )
5415
+ const inputItems = inputParts.flatMap(
5416
+ (part) => part.type === "text" && part.text.trim().length > 0 ? [{ type: "text", text: part.text, text_elements: [] }] : []
5077
5417
  );
5078
- const inputItems = [];
5079
- if (textPrompt.trim().length > 0) {
5080
- inputItems.push({
5081
- type: "text",
5082
- text: textPrompt,
5083
- text_elements: []
5084
- });
5085
- }
5086
5418
  inputItems.push(
5087
5419
  ...await mapToCodexPromptParts(
5088
5420
  inputParts,
@@ -5484,17 +5816,40 @@ var CodexAgentAdapter = class {
5484
5816
  const modes = await client.request("collaborationMode/list", {});
5485
5817
  if (!modes.data.some((mode) => mode.mode === request.run.mode)) throw new Error("This Codex installation does not support the requested planning mode.");
5486
5818
  }
5819
+ const emitHarnessCommands = (commands) => sink.emitEvent(
5820
+ createNormalizedEvent(
5821
+ "harness.commands",
5822
+ { provider: request.provider, runId: request.runId },
5823
+ { commands }
5824
+ )
5825
+ );
5826
+ const inventory = listCodexHarnessCommands(client, cwd).then((commands) => {
5827
+ emitHarnessCommands(commands);
5828
+ return commands;
5829
+ });
5830
+ inventory.catch(() => void 0);
5487
5831
  if (request.run.goal) {
5488
5832
  await client.request("thread/goal/set", { threadId: threadResponse.thread.id, objective: request.run.goal, status: "active" });
5489
5833
  }
5490
- await client.request(
5491
- "turn/start",
5492
- buildCodexTurnStartParams({
5493
- threadId: threadResponse.thread.id,
5494
- inputItems: runtime.inputItems,
5495
- request
5496
- })
5834
+ const command = request.run.command;
5835
+ const skillNames = new Set(
5836
+ command && !CODEX_BUILTIN_COMMAND_NAMES.has(command.name) ? (await inventory).filter((entry) => entry.source !== "builtin").map((entry) => entry.name) : []
5497
5837
  );
5838
+ const dispatch = resolveCodexCommandDispatch(command, runtime.inputItems, skillNames);
5839
+ if (dispatch.kind === "compact") {
5840
+ await client.request("thread/compact/start", { threadId: threadResponse.thread.id });
5841
+ } else if (dispatch.kind === "review") {
5842
+ await client.request("review/start", { threadId: threadResponse.thread.id, target: dispatch.target, delivery: "inline" });
5843
+ } else {
5844
+ await client.request(
5845
+ "turn/start",
5846
+ buildCodexTurnStartParams({
5847
+ threadId: threadResponse.thread.id,
5848
+ inputItems: dispatch.inputItems,
5849
+ request
5850
+ })
5851
+ );
5852
+ }
5498
5853
  let completionResult;
5499
5854
  let completionError;
5500
5855
  try {
@@ -5502,6 +5857,10 @@ var CodexAgentAdapter = class {
5502
5857
  } catch (err) {
5503
5858
  completionError = err;
5504
5859
  }
5860
+ await withTimeout(
5861
+ inventory.catch(() => void 0),
5862
+ HARNESS_COMMANDS_SETTLE_GRACE_MS
5863
+ );
5505
5864
  endWait();
5506
5865
  if (completionError !== void 0) {
5507
5866
  if (abortInvoked) {
@@ -5724,6 +6083,60 @@ function toRawEvent3(runId, payload, type) {
5724
6083
  function injectedTaskResultChild(text2) {
5725
6084
  return /<task id="?([^"\s>]+)"? state="?(?:completed|error)"?>/.exec(text2)?.[1];
5726
6085
  }
6086
+ function resolveOpenCodeCommandDispatch(command, harnessCommands) {
6087
+ if (!command) return { kind: "prompt" };
6088
+ if (command.name === "compact") return { kind: "summarize" };
6089
+ const known = harnessCommands.find((entry) => entry.name === command.name);
6090
+ if (!known) return { kind: "prompt" };
6091
+ if (known.source === "skill")
6092
+ return { kind: "prompt", text: skillDirective(command.name, command.args) };
6093
+ return { kind: "command", command: command.name, arguments: command.args };
6094
+ }
6095
+ function replaceOpenCodePromptText(parts, text2) {
6096
+ let replaced = false;
6097
+ const next = parts.map((part) => {
6098
+ if (part.type !== "text" || replaced) return part;
6099
+ replaced = true;
6100
+ return { ...part, text: text2 };
6101
+ });
6102
+ return replaced ? next : [{ type: "text", text: text2 }, ...next];
6103
+ }
6104
+ var OPENCODE_COMMAND_DISCOVERY_TIMEOUT_MS = 5e3;
6105
+ async function listOpenCodeHarnessCommands(runtime) {
6106
+ const init = {
6107
+ headers: runtime.previewHeaders,
6108
+ signal: AbortSignal.timeout(OPENCODE_COMMAND_DISCOVERY_TIMEOUT_MS)
6109
+ };
6110
+ try {
6111
+ const listed = await withTimeout(
6112
+ Promise.all([
6113
+ fetchJson(`${runtime.baseUrl}/command`, init),
6114
+ fetchJson(`${runtime.baseUrl}/skill`, init).catch(
6115
+ () => []
6116
+ )
6117
+ ]),
6118
+ OPENCODE_COMMAND_DISCOVERY_TIMEOUT_MS
6119
+ );
6120
+ if (!listed) {
6121
+ debugOpencode(
6122
+ "GET /command did not answer within %dms; reporting built-in commands only",
6123
+ OPENCODE_COMMAND_DISCOVERY_TIMEOUT_MS
6124
+ );
6125
+ return builtinHarnessCommands("open-code");
6126
+ }
6127
+ const [commands, skills] = listed;
6128
+ return openCodeHarnessCommands(
6129
+ Array.isArray(commands) ? commands : [],
6130
+ Array.isArray(skills) ? skills : []
6131
+ );
6132
+ } catch (error) {
6133
+ debugOpencode(
6134
+ "GET /command unavailable; reporting built-in commands only: %o",
6135
+ error
6136
+ );
6137
+ return builtinHarnessCommands("open-code");
6138
+ }
6139
+ }
5727
6140
  function toOpenCodeModel(model) {
5728
6141
  if (!model) {
5729
6142
  return void 0;
@@ -6748,6 +7161,32 @@ var OpenCodeAgentAdapter = class {
6748
7161
  const name = request.run.mode === "plan" ? "plan" : "build";
6749
7162
  if (!agents.some((agent) => agent.name === name)) throw new Error(`This OpenCode installation does not expose the ${name} agent.`);
6750
7163
  }
7164
+ const harnessCommands = await listOpenCodeHarnessCommands(runtime);
7165
+ sink.emitEvent(
7166
+ createNormalizedEvent(
7167
+ "harness.commands",
7168
+ { provider: request.provider, runId: request.runId },
7169
+ { commands: harnessCommands }
7170
+ )
7171
+ );
7172
+ const commandDispatch = resolveOpenCodeCommandDispatch(request.run.command, harnessCommands);
7173
+ if (commandDispatch.kind === "command" && request.run.systemPrompt) {
7174
+ throw new Error(
7175
+ "OpenCode commands do not support a per-run systemPrompt. Use a normal prompt, or configure the systemPrompt on the Agent at setup time."
7176
+ );
7177
+ }
7178
+ const dispatchBlocking = (endpoint, body) => {
7179
+ void fetch(`${runtime.baseUrl}/session/${sessionId}/${endpoint}`, {
7180
+ method: "POST",
7181
+ headers: { "content-type": "application/json", ...runtime.previewHeaders },
7182
+ body: JSON.stringify(body)
7183
+ }).then((response) => {
7184
+ if (!response.ok) throw new Error(`POST /session/${sessionId}/${endpoint} returned ${response.status}`);
7185
+ }).catch((error) => {
7186
+ if (!dispatchError) dispatchError = error;
7187
+ resolveSessionTerminal();
7188
+ });
7189
+ };
6751
7190
  const dispatchPrompt = async (parts) => {
6752
7191
  const body = JSON.stringify({
6753
7192
  ...request.run.model ? { model: toOpenCodeModel(request.run.model) } : {},
@@ -6816,7 +7255,24 @@ var OpenCodeAgentAdapter = class {
6816
7255
  sendToSession(queued);
6817
7256
  }
6818
7257
  try {
6819
- await dispatchPrompt(mapToOpenCodeParts(inputParts));
7258
+ if (commandDispatch.kind === "summarize") {
7259
+ const model = toOpenCodeModel(request.run.model);
7260
+ if (!model?.providerID) throw new Error("OpenCode compaction needs a provider-qualified model id.");
7261
+ dispatchBlocking("summarize", { providerID: model.providerID, modelID: model.modelID });
7262
+ } else if (commandDispatch.kind === "command") {
7263
+ dispatchBlocking("command", {
7264
+ command: commandDispatch.command,
7265
+ arguments: commandDispatch.arguments,
7266
+ parts: mapToOpenCodeParts(inputParts).filter((part) => part.type === "file"),
7267
+ ...request.run.model?.includes("/") ? { model: request.run.model } : {},
7268
+ ...request.run.mode ? { agent: request.run.mode === "plan" ? "plan" : "build" } : request.options.configuration === "native" ? {} : { agent: agentSlug }
7269
+ });
7270
+ } else {
7271
+ const parts = mapToOpenCodeParts(inputParts);
7272
+ await dispatchPrompt(
7273
+ commandDispatch.text === void 0 ? parts : replaceOpenCodePromptText(parts, commandDispatch.text)
7274
+ );
7275
+ }
6820
7276
  } catch (error) {
6821
7277
  if (!dispatchError) {
6822
7278
  dispatchError = error;
@@ -7574,7 +8030,10 @@ function harnessCapabilities(provider) {
7574
8030
  function resolveHarnessCommand(provider, input) {
7575
8031
  const first = typeof input === "string" ? input : input.find((part) => part.type === "text")?.text;
7576
8032
  const match = first?.match(/^\s*\/(plan|agent|goal)(?:\s+([\s\S]*))?$/);
7577
- if (!match) return { input };
8033
+ if (!match) {
8034
+ const invocation = first ? parseHarnessCommandInvocation(first) : void 0;
8035
+ return invocation ? { input, command: invocation } : { input };
8036
+ }
7578
8037
  const command = match[1];
7579
8038
  if (!harnessCapabilities(provider).commands.includes(command)) throw new Error(`/${command} is not supported by ${provider}.`);
7580
8039
  const body = match[2]?.trim() ?? "";
@@ -7591,6 +8050,17 @@ function resolveHarnessCommand(provider, input) {
7591
8050
  }
7592
8051
 
7593
8052
  export {
8053
+ MAX_HARNESS_COMMANDS,
8054
+ MAX_HARNESS_COMMAND_NAME,
8055
+ MAX_HARNESS_COMMAND_DESCRIPTION,
8056
+ MAX_HARNESS_COMMAND_ARGUMENT_HINT,
8057
+ builtinHarnessCommands,
8058
+ parseHarnessCommandInvocation,
8059
+ claudeHarnessCommands,
8060
+ codexHarnessCommands,
8061
+ codexSkillMention,
8062
+ openCodeHarnessCommands,
8063
+ skillDirective,
7594
8064
  agentboxRoot,
7595
8065
  getAgentLayout,
7596
8066
  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-DjHP7dFq.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-DjHP7dFq.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-YV3DQS6Z.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;
@@ -95,6 +180,15 @@ interface MessageCompletedEvent extends NormalizedAgentEventBase {
95
180
  * the assistant turn rather than the user one.
96
181
  */
97
182
  messageId?: string;
183
+ /**
184
+ * Questions the harness asked without pausing the turn (Codex
185
+ * `request_user_input_async`: an `agentMessage` item with
186
+ * `delivery: "async"`). Nothing is pending and the run keeps working;
187
+ * an answer, if any, is a follow-up user message (`AgentRun.sendMessage`
188
+ * while the run is live, or the next run). Blocking questions never use
189
+ * this field: they arrive as `permission.requested` with `kind: "question"`.
190
+ */
191
+ questions?: AgentUserQuestion[];
98
192
  }
99
193
  /** Work the harness left running past its turn (background shell, monitor,
100
194
  * background subagent, scheduled wakeup). */
@@ -132,7 +226,17 @@ interface NativePlanEvent extends NormalizedAgentEventBase {
132
226
  type: "plan.completed";
133
227
  text: string;
134
228
  }
135
- type NormalizedAgentEvent = NativePlanEvent | RunStartedEvent | MessageStartedEvent | MessageInjectedEvent | TextDeltaEvent | ReasoningDeltaEvent | ToolCallStartedEvent | ToolCallDeltaEvent | ToolCallCompletedEvent | PermissionRequestedEvent | PermissionResolvedEvent | MessageCompletedEvent | BackgroundTasksEvent | RunCompletedEvent | RunCancelledEvent | RunErrorEvent;
229
+ /**
230
+ * Slash commands the harness reports for this session: built-ins usable
231
+ * headlessly plus the skills, custom commands, plugin commands, and MCP
232
+ * prompts discovered in its environment. Emitted once a run knows them
233
+ * (Claude Code `system/init`, Codex `skills/list`, OpenCode `GET /command`).
234
+ */
235
+ interface HarnessCommandsEvent extends NormalizedAgentEventBase {
236
+ type: "harness.commands";
237
+ commands: HarnessCommandDescriptor[];
238
+ }
239
+ type NormalizedAgentEvent = NativePlanEvent | HarnessCommandsEvent | RunStartedEvent | MessageStartedEvent | MessageInjectedEvent | TextDeltaEvent | ReasoningDeltaEvent | ToolCallStartedEvent | ToolCallDeltaEvent | ToolCallCompletedEvent | PermissionRequestedEvent | PermissionResolvedEvent | MessageCompletedEvent | BackgroundTasksEvent | RunCompletedEvent | RunCancelledEvent | RunErrorEvent;
136
240
  declare function createNormalizedEvent<TType extends NormalizedAgentEventType>(type: TType, base: Omit<NormalizedAgentEventBase, "type" | "timestamp"> & {
137
241
  timestamp?: string;
138
242
  }, extra?: Record<string, unknown>): NormalizedAgentEvent;
@@ -421,6 +525,14 @@ interface AgentRunConfig {
421
525
  mode?: "plan" | "default";
422
526
  /** Native goal objective. Unsupported harnesses reject it. */
423
527
  goal?: string;
528
+ /**
529
+ * Leading `/name args` token of {@link input}, as parsed by
530
+ * `resolveHarnessCommand`. The input keeps the raw text: Claude Code
531
+ * dispatches slash commands itself, while the Codex and OpenCode adapters
532
+ * map known names to native calls (compaction, review, commands, skills)
533
+ * and send unknown ones as plain text.
534
+ */
535
+ command?: HarnessCommandInvocation;
424
536
  }
425
537
  type AgentApprovalMode = "auto" | "interactive";
426
538
  type AgentPermissionKind = "bash" | "edit" | "tool" | "network" | "file-change" | "question" | "plan" | "unknown";
@@ -872,4 +984,4 @@ interface AgentProviderAdapter<P extends AgentProviderName = AgentProviderName>
872
984
  attachSendMessage(request: AgentAttachRequest<P>, content: UserContent): Promise<void>;
873
985
  }
874
986
 
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 };
987
+ 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.518",
4
4
  "description": "Swappable coding agents and sandbox providers for Bun and TypeScript.",
5
5
  "license": "MIT",
6
6
  "repository": {