external-subagent 0.3.0 → 0.3.1

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/cli/constants.mjs CHANGED
@@ -8,7 +8,7 @@ const IS_DEBUG_VARIANT = process.env.EXTERNAL_SUBAGENT_VARIANT === 'debug';
8
8
 
9
9
  export const PRODUCT_NAME = IS_DEBUG_VARIANT ? 'external-subagent-debug' : 'external-subagent';
10
10
  export const PRODUCT_ID = IS_DEBUG_VARIANT ? 'external_subagent_debug' : 'external_subagent';
11
- export const VERSION = '0.3.0';
11
+ export const VERSION = '0.3.1';
12
12
  export const LAUNCH_AGENT_LABEL = IS_DEBUG_VARIANT ? 'com.external-subagent-debug.daemon' : 'com.external-subagent.daemon';
13
13
  export const DAEMON_BIN_NAME = IS_DEBUG_VARIANT ? 'external-subagent-debugd' : 'external-subagentd';
14
14
  export const MCP_BIN_NAME = IS_DEBUG_VARIANT ? 'external-subagent-debug-mcp' : 'external-subagent-mcp';
package/cli/rpc.mjs CHANGED
@@ -7,6 +7,7 @@ export const MAX_FRAME_BYTES = 512 * 1024;
7
7
  export const MAX_RESPONSE_FRAME_BYTES = 2 * 1024 * 1024;
8
8
  export const MAX_RESULT_CHUNK_BYTES = 256 * 1024;
9
9
  export const AGENT_PROBE_TRANSPORT_TIMEOUT_MS = 200_000;
10
+ export const SPAWN_TRANSPORT_TIMEOUT_MS = 150_000;
10
11
  export const MIN_TASK_ID = 10_000_000;
11
12
  export const MAX_TASK_ID = 99_999_999;
12
13
 
@@ -38,6 +39,7 @@ export function waitTransportTimeoutMs(waitTime = 290) {
38
39
  export function daemonTransportTimeoutMs(command, params = {}) {
39
40
  if (command === 'wait') return waitTransportTimeoutMs(params.wait_time);
40
41
  if (command === 'agent-probe' || command === 'agent-models') return AGENT_PROBE_TRANSPORT_TIMEOUT_MS;
42
+ if (command === 'create' || command === 'spawn') return SPAWN_TRANSPORT_TIMEOUT_MS;
41
43
  return 6000;
42
44
  }
43
45
 
@@ -136,8 +138,10 @@ function methodFor(command, input) {
136
138
  } };
137
139
  }
138
140
  case 'send': {
139
- rejectUnknownFields('send', input, new Set(['agent_id', 'message_id', 'content']));
141
+ rejectUnknownFields('send', input, new Set(['agent_id', 'message_id', 'mode', 'content']));
142
+ if (!['queue', 'steer'].includes(input.mode)) throw new CliError('VALIDATION', 'send mode must be queue or steer', 2);
140
143
  return { method: 'task_message', params: {
144
+ mode: input.mode,
141
145
  agent_id: daemonTaskId(input.agent_id),
142
146
  ...(input.message_id ? { message_id: input.message_id } : {}),
143
147
  content: input.content,
@@ -205,7 +209,7 @@ export function projectDaemonResult(command, result) {
205
209
  case 'agent-probe': return { evidence: result.evidence, status: result.status };
206
210
  case 'agent-models': return result.catalog ?? result;
207
211
  case 'create': case 'spawn':
208
- return { agent_id: publicTaskId(result.task.agent_id), status: result.task.status };
212
+ return { agent_id: publicTaskId(result.task.agent_id), status: result.task.status, session_id: result.task.session_id ?? null };
209
213
  case 'wait': {
210
214
  const { result: taskResult, task, activity, kind: _kind, ...rest } = result;
211
215
  return { ...rest, task: publicTaskHeader(task), activity, result: publicResult(taskResult) };
@@ -1,20 +1,20 @@
1
1
  {
2
2
  "schema_version": 1,
3
3
  "product": "external-subagent",
4
- "version": "0.3.0",
4
+ "version": "0.3.1",
5
5
  "platform": "darwin-arm64",
6
6
  "files": [
7
7
  {
8
8
  "name": "external-subagentd",
9
- "bytes": 9771664,
9
+ "bytes": 9911616,
10
10
  "mode": "755",
11
- "sha256": "b7e34283d40d91f5e210f6b91884a1fbfd4291a3454a1127d45c83566edb9b93"
11
+ "sha256": "d3f6d45a32d7675ba68fa059e70cca4c85f1ed781441b53dddfa7585751ea339"
12
12
  },
13
13
  {
14
14
  "name": "external-subagent-mcp",
15
- "bytes": 937840,
15
+ "bytes": 935760,
16
16
  "mode": "755",
17
- "sha256": "2f811110d1acf479ddfe62a5f00913e7d38cbe7a58d51c7c14c4ab6fa5a08247"
17
+ "sha256": "504256978a7cf0cc16b13c8f53d75bca3c53bf65d1286a3c9bc22dc923cd0476"
18
18
  }
19
19
  ]
20
20
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "external-subagent",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Manage bounded ZCode, DeepSeek Harness (DSH), Codex, and Google Antigravity (agy) subagent tasks through a local MCP service for any local host (Codex, ZCode, or a custom MCP client)",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -52,6 +52,7 @@
52
52
  "postpack": "node scripts/release/check-native-tarball.mjs",
53
53
  "prepublishOnly": "node scripts/release/check-native-tarball.mjs --staged",
54
54
  "test:install": "node --test tests/install/*.test.mjs",
55
+ "test:affected": "node scripts/test/affected.mjs",
55
56
  "check": "node --check bin/external-subagent.mjs && node --check bin/external-subagent-mcp.mjs && node --check bin/external-subagent-debug.mjs && node --check bin/external-subagent-debug-mcp.mjs && node --check cli/main.mjs"
56
57
  },
57
58
  "engines": {
@@ -60,6 +60,7 @@
60
60
  },
61
61
  "spawn": {
62
62
  "type": "object",
63
+ "description": "Start one durable subagent in an absolute repository workspace, returning after establishing the new session.",
63
64
  "required": ["repository", "prompt"],
64
65
  "properties": {
65
66
  "subagent": { "type": "string", "minLength": 1, "description": "Subagent route key; omission uses configured default_subagent or returns subagent_required. Null is invalid; dsh production spawn requires its enabled + spawn_supported + pinned-runtime configuration." },
@@ -102,7 +103,7 @@
102
103
  },
103
104
  "wait": {
104
105
  "type": "object",
105
- "description": "Wait returns early only for an actionable pending request (permission requests need allow/deny; user-input requests carry the full embedded question and need answer with non-empty content) or a terminal result; ordinary progress, message receipts, already-responded and unsupported requests never wake it. The pending_requests output projection is capped at 100 actionable records, while the wake decision scans the full pending set. activity carries the text tail incrementally: each wait returns only the text appended since the previous wait (an empty tail means nothing new), every byte is delivered by wait at most once, and latest_text_truncated flags undelivered bytes that rolled out of the bounded window (that response degrades to the whole window); a terminal response also strips bytes repeating the embedded result page verbatim. activity also carries a 200-char verified reasoning tail, tool calls started in the last 60 seconds, and telemetry status.",
106
+ "description": "Wait up to 290 seconds by default. Returns early only when an actionable pending request exists (permission requests need allow/deny; user-input requests carry the full embedded question and need answer with non-empty content) or the terminal result is available; ordinary progress, message receipts, already-responded and unsupported requests never wake it, and its timeout still returns timed_out=true. When the final result is embedded with complete=true no further result call is needed; a partial page directs you to external_subagent_result with next_offset. A failed terminal result also carries failure_message: usually the daemon's bounded single-line JSON failure detail, but an early fail_claim row may be plain text, so treat it as an opaque bounded string and attempt JSON parsing defensively (null when the task has no persisted detail or the outcome is not a failure). Read failure_message before falling back to daemon logs or sqlite. The pending_requests projection stays capped at 100 records while the wake decision scans the full pending set, and the request that woke the wait is always part of the returned projection so its request_id can be answered directly. activity carries the text tail incrementally: each wait returns only the text appended since the previous wait (an empty tail means nothing new), every byte is delivered by wait at most once, and latest_text_truncated flags the case where undelivered bytes rolled out of the bounded window so this response degraded to the whole window (on the terminal response, bytes repeating the embedded result page verbatim are stripped so they are not shipped twice), a 200-char verified reasoning tail, tool calls started in the last 60 seconds, and telemetry status; activity also exposes last_tool_calls as up to three [tool, arg] string pairs in chronological order across turns (tool up to 64 characters, arg up to 512 UTF-8 bytes), last_activity_age_ms (null before any activity), and model_request_active; additionally in_flight_tool_count counts tracked in-flight tool calls (scheduled or started without a matching result, error or permission resolution; 0 when there is no snapshot or the adapter has no per-call lifecycle tracking, such as codex) and oldest_in_flight_tool_age_ms is the age since the oldest tracked in-flight call first appeared (null when none is tracked); use observe only when these suggest a meaningless loop.",
106
107
  "required": ["agent_id"],
107
108
  "properties": {
108
109
  "agent_id": { "type": "integer", "minimum": 10000000, "maximum": 99999999 },
@@ -182,11 +183,11 @@
182
183
  "additionalProperties": false,
183
184
  "properties": {
184
185
  "external_subagent_status": { "input": [], "output": ["mcp_version", "components", "capabilities", "subagents"] },
185
- "external_subagent_spawn": { "input": ["subagent", "repository", "permission_mode", "prompt", "model", "effort", "write_manifest"], "output": ["agent_id", "status"], "idempotent": false },
186
+ "external_subagent_spawn": { "input": ["subagent", "repository", "permission_mode", "prompt", "model", "effort", "write_manifest"], "output": ["agent_id", "status", "session_id"], "idempotent": false },
186
187
  "external_subagent_wait": { "input": ["agent_id", "wait_time", "message_id"], "output": ["task", "pending_requests", "result_available", "activity", "result", "instruction", "timed_out", "message_receipt"] },
187
188
  "external_subagent_observe": { "input": ["agent_id"], "output": ["tools", "reasoning", "coverage"], "idempotent": true },
188
189
  "external_subagent_list": { "input": ["subagent", "repository", "phase", "outcome", "cursor", "limit"], "output": ["tasks", "next_cursor"] },
189
- "external_subagent_send": { "input": ["agent_id", "message_id", "content"], "output": ["message_id", "disposition"] },
190
+ "external_subagent_send": { "input": ["agent_id", "message_id", "mode", "content"], "required": ["agent_id", "mode", "content"], "mode": ["queue", "steer"], "output": ["message_id", "disposition"] },
190
191
  "external_subagent_respond": { "input": ["agent_id", "request_id", "decision", "content"], "output": ["disposition", "requested_decision", "effective_decision", "policy_overrode", "policy_reason_code"] },
191
192
  "external_subagent_cancel": { "input": ["agent_id"], "output": ["task"] },
192
193
  "external_subagent_result": { "input": ["agent_id", "offset", "limit"], "output": ["task", "result"] },