@kontextmind/kxm 0.7.7 → 0.7.9

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.
@@ -15159,6 +15159,7 @@ function defaultSpawn(command, args, options) {
15159
15159
  let child;
15160
15160
  const finish = () => {
15161
15161
  if (finished) return;
15162
+ if (stopping && !killSent) return;
15162
15163
  finished = true;
15163
15164
  for (const timer of [wallTimer, killTimer, drainTimer, reapTimer]) clearTimeout(timer);
15164
15165
  options.signal?.removeEventListener("abort", onAbort);
@@ -15168,7 +15169,18 @@ function defaultSpawn(command, args, options) {
15168
15169
  child?.unref();
15169
15170
  const started = Boolean(child?.pid);
15170
15171
  if (started && !observedChildExit) error ??= new Error("process_exit_unobserved");
15171
- resolve9({ stdout: Buffer.concat(stdout).toString("utf8"), stderr: Buffer.concat(stderr).toString("utf8"), code, signal, started, observedChildExit, terminationRequested: stopping, ...error ? { error } : {} });
15172
+ const unverifiedDescendants = stopping || started && !observedChildExit;
15173
+ resolve9({
15174
+ stdout: Buffer.concat(stdout).toString("utf8"),
15175
+ stderr: Buffer.concat(stderr).toString("utf8"),
15176
+ code,
15177
+ signal,
15178
+ started,
15179
+ observedChildExit,
15180
+ terminationRequested: stopping,
15181
+ ...unverifiedDescendants ? { unverifiedDescendants: true } : {},
15182
+ ...error ? { error } : {}
15183
+ });
15172
15184
  };
15173
15185
  const kill = (requested) => {
15174
15186
  killProcessTree(child, requested);
@@ -15199,7 +15211,7 @@ function defaultSpawn(command, args, options) {
15199
15211
  cwd: options.cwd,
15200
15212
  env: options.env ?? process.env,
15201
15213
  stdio: ["pipe", "pipe", "pipe"],
15202
- shell: false,
15214
+ shell: options.shell === true,
15203
15215
  windowsHide: true,
15204
15216
  detached: process.platform !== "win32"
15205
15217
  });
@@ -15243,7 +15255,7 @@ function defaultSpawn(command, args, options) {
15243
15255
  closed = true;
15244
15256
  code = exitCode;
15245
15257
  signal = exitSignal;
15246
- if (!stopping || killSent) finish();
15258
+ finish();
15247
15259
  });
15248
15260
  options.signal?.addEventListener("abort", onAbort, { once: true });
15249
15261
  if (options.signal?.aborted) onAbort();
@@ -15684,6 +15696,31 @@ function defaultRunner(env) {
15684
15696
  }
15685
15697
  };
15686
15698
  }
15699
+ function commandResultFromSpawn(result) {
15700
+ const errno = result.error && "code" in result.error ? result.error.code : void 0;
15701
+ const error = (typeof errno === "string" && errno ? errno : void 0) ?? result.error?.message ?? (result.observedChildExit !== true ? "auth_probe_exit_unobserved" : void 0);
15702
+ return {
15703
+ ok: result.code === 0 && !error,
15704
+ code: result.code,
15705
+ stdout: result.stdout,
15706
+ stderr: result.stderr,
15707
+ ...error ? { error } : {}
15708
+ };
15709
+ }
15710
+ function defaultAsyncRunner(env, signal) {
15711
+ return async (command, args, timeoutMs) => {
15712
+ try {
15713
+ return commandResultFromSpawn(await defaultSpawn(command, args, {
15714
+ env,
15715
+ timeoutMs,
15716
+ signal,
15717
+ shell: harnessSpawnUsesShell(command)
15718
+ }));
15719
+ } catch (error) {
15720
+ return { ok: false, code: null, stdout: "", stderr: "", error: error instanceof Error ? error.message : "spawn_failed" };
15721
+ }
15722
+ };
15723
+ }
15687
15724
  function firstLine(text) {
15688
15725
  const line = text.split(/\r?\n/).map((candidate) => candidate.trim()).find(Boolean);
15689
15726
  return line && line.length <= 200 ? line : void 0;
@@ -15882,6 +15919,13 @@ function probeHarnesses(options = {}) {
15882
15919
  harnesses: BUILTIN_HARNESSES.map((entry) => probeEntry(entry, runCommand, timeoutMs, platform, options))
15883
15920
  };
15884
15921
  }
15922
+ async function probeHarnessesAsync(options = {}) {
15923
+ return replayHarnessProbe(
15924
+ options.runCommand ?? defaultAsyncRunner(options.env ?? process.env, options.signal),
15925
+ (runCommand) => probeHarnesses({ ...options, runCommand }),
15926
+ 256
15927
+ );
15928
+ }
15885
15929
  function eligibleHarnesses(inventory) {
15886
15930
  const eligible = inventory.harnesses.filter((entry) => entry !== void 0 && entry.detected && entry.authenticated === true).map((entry) => entry.id);
15887
15931
  if (eligible.length === 0) throw new Error("no_authenticated_harness");
@@ -16118,35 +16162,31 @@ var PendingHarnessCommand = class {
16118
16162
  this.key = key;
16119
16163
  }
16120
16164
  };
16121
- async function probeHarnessAssignmentAsync(options) {
16165
+ async function replayHarnessProbe(run, execute, limit) {
16122
16166
  const observed = /* @__PURE__ */ new Map();
16123
- const run = options.runCommand ?? (async (command, args, timeoutMs) => {
16124
- const result = await defaultSpawn(command, args, { env: options.env, timeoutMs, signal: options.signal });
16125
- const error = result.error?.message ?? (result.observedChildExit !== true ? "auth_probe_exit_unobserved" : void 0);
16126
- return {
16127
- ok: result.code === 0 && !error,
16128
- code: result.code,
16129
- stdout: result.stdout,
16130
- stderr: result.stderr,
16131
- ...error ? { error } : {}
16132
- };
16133
- });
16134
- for (let commands = 0; commands <= 32; commands++) {
16167
+ for (let commands = 0; commands <= limit; commands++) {
16135
16168
  try {
16136
- return probeHarnessAssignment({ ...options, runCommand(command, args, timeoutMs) {
16169
+ return execute((command, args, timeoutMs) => {
16137
16170
  const key = JSON.stringify([command, args, timeoutMs]);
16138
16171
  const result = observed.get(key);
16139
16172
  if (result) return result;
16140
16173
  throw new PendingHarnessCommand(command, args, timeoutMs, key);
16141
- } });
16174
+ });
16142
16175
  } catch (pending) {
16143
16176
  if (!(pending instanceof PendingHarnessCommand)) throw pending;
16144
- if (commands === 32) throw new Error("auth_probe_command_limit");
16177
+ if (commands === limit) throw new Error("auth_probe_command_limit");
16145
16178
  observed.set(pending.key, await run(pending.command, pending.args, pending.timeoutMs));
16146
16179
  }
16147
16180
  }
16148
16181
  throw new Error("auth_probe_command_limit");
16149
16182
  }
16183
+ async function probeHarnessAssignmentAsync(options) {
16184
+ return replayHarnessProbe(
16185
+ options.runCommand ?? defaultAsyncRunner(options.env ?? process.env, options.signal),
16186
+ (runCommand) => probeHarnessAssignment({ ...options, runCommand }),
16187
+ 32
16188
+ );
16189
+ }
16150
16190
  function probeHarnessesForModel(modelSpec, options = {}) {
16151
16191
  const timeoutMs = options.timeoutMs ?? 3e3;
16152
16192
  const runCommand = options.runCommand ?? defaultRunner(options.env ?? process.env);
@@ -16167,6 +16207,13 @@ function probeHarnessesForModel(modelSpec, options = {}) {
16167
16207
  )
16168
16208
  };
16169
16209
  }
16210
+ async function probeHarnessesForModelAsync(modelSpec, options = {}) {
16211
+ return replayHarnessProbe(
16212
+ options.runCommand ?? defaultAsyncRunner(options.env ?? process.env, options.signal),
16213
+ (runCommand) => probeHarnessesForModel(modelSpec, { ...options, runCommand }),
16214
+ 256
16215
+ );
16216
+ }
16170
16217
  function scopesFor(scope, entry) {
16171
16218
  if (scope === "self") return ["self"];
16172
16219
  if (scope === "extensions") return entry.update.extensions ? ["extensions"] : [];
@@ -22351,9 +22398,28 @@ import { join as join11 } from "node:path";
22351
22398
  import { createHash as createHash7, randomUUID as randomUUID3 } from "node:crypto";
22352
22399
  import { lstat, mkdir, open, rename } from "node:fs/promises";
22353
22400
  import { join as join6 } from "node:path";
22401
+ var ONESHOT_EVIDENCE_SCHEMA = "kxm.oneshot-evidence.v2";
22402
+ var RETIRED_ONESHOT_EVIDENCE_SCHEMAS = /* @__PURE__ */ new Set(["kxm.oneshot-evidence.v1"]);
22354
22403
  var TEXT_LIMIT = 4 * 1024 * 1024;
22404
+ var ARGV_LIMIT = 64 * 1024;
22355
22405
  var RECORD_LIMIT = 16 * 1024 * 1024;
22356
22406
  var digest = (value) => `sha256:${createHash7("sha256").update(value).digest("hex")}`;
22407
+ function parseOneShotEvidenceRecord(bytes) {
22408
+ let parsed;
22409
+ try {
22410
+ parsed = JSON.parse(bytes);
22411
+ } catch {
22412
+ throw new Error("oneshot_evidence_record_invalid");
22413
+ }
22414
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
22415
+ throw new Error("oneshot_evidence_record_invalid");
22416
+ }
22417
+ const schema = parsed.schema;
22418
+ if (typeof schema !== "string") throw new Error("oneshot_evidence_record_invalid");
22419
+ if (RETIRED_ONESHOT_EVIDENCE_SCHEMAS.has(schema)) throw new Error("oneshot_evidence_schema_retired");
22420
+ if (schema !== ONESHOT_EVIDENCE_SCHEMA) throw new Error("oneshot_evidence_schema_unknown");
22421
+ return parsed;
22422
+ }
22357
22423
  async function beginOneShotEvidence(root, intent, sensitive) {
22358
22424
  await mkdir(root, { recursive: true, mode: 448 });
22359
22425
  const stat = await lstat(root);
@@ -22367,11 +22433,11 @@ async function beginOneShotEvidence(root, intent, sensitive) {
22367
22433
  const redact = (value) => {
22368
22434
  let text = value;
22369
22435
  for (const secret of secrets) text = text.replaceAll(secret, "[REDACTED]");
22370
- return text.replace(/(\b(?:authorization|api[_-]?key|access[_-]?token|refresh[_-]?token|password|secret)\b["']?\s*[:=]\s*["']?)(?:Bearer\s+)?[^\s"',;}]+/gi, "$1[REDACTED]");
22436
+ return text.replace(/(\b(?:authorization|api[_-]?key|access[_-]?token|refresh[_-]?token|password|secret)\b["']?\s*[:=]\s*["']?)(?:Bearer\s+)?[^\s"',;}]+/gi, "$1[REDACTED]").replace(/\bBearer\s+[A-Za-z0-9._~+/=-]+/gi, "Bearer [REDACTED]");
22371
22437
  };
22372
- const bounded = (value) => {
22438
+ const bounded = (value, max = TEXT_LIMIT) => {
22373
22439
  const bytes = Buffer.from(redact(value));
22374
- return { text: bytes.subarray(0, TEXT_LIMIT).toString("utf8"), truncated: bytes.length > TEXT_LIMIT, sha256: digest(value) };
22440
+ return { text: bytes.subarray(0, max).toString("utf8"), truncated: bytes.length > max, sha256: digest(redact(value)) };
22375
22441
  };
22376
22442
  const write = async (name, value) => {
22377
22443
  const current = await lstat(dir);
@@ -22380,6 +22446,7 @@ async function beginOneShotEvidence(root, intent, sensitive) {
22380
22446
  }
22381
22447
  const bytes = JSON.stringify(value);
22382
22448
  if (Buffer.byteLength(bytes) > RECORD_LIMIT) throw new Error("oneshot_evidence_record_limit");
22449
+ parseOneShotEvidenceRecord(bytes);
22383
22450
  const target = join6(dir, name);
22384
22451
  const partial = `${target}.partial`;
22385
22452
  const file = await open(partial, "wx", 384);
@@ -22401,7 +22468,7 @@ async function beginOneShotEvidence(root, intent, sensitive) {
22401
22468
  return digest(bytes);
22402
22469
  };
22403
22470
  await write("intent.json", {
22404
- schema: "kxm.oneshot-evidence.v1",
22471
+ schema: ONESHOT_EVIDENCE_SCHEMA,
22405
22472
  id,
22406
22473
  recordedAt: (/* @__PURE__ */ new Date()).toISOString(),
22407
22474
  runId: intent.runId,
@@ -22412,9 +22479,10 @@ async function beginOneShotEvidence(root, intent, sensitive) {
22412
22479
  provider: intent.provider,
22413
22480
  requestedModel: intent.model,
22414
22481
  cwd: intent.cwd,
22415
- command: intent.command,
22416
- argv: bounded(JSON.stringify(intent.args)),
22482
+ command: redact(intent.command),
22483
+ argv: bounded(JSON.stringify(intent.args), ARGV_LIMIT),
22417
22484
  stdin: intent.input === void 0 ? null : bounded(intent.input),
22485
+ env: null,
22418
22486
  acceptance: false
22419
22487
  });
22420
22488
  let finished = false;
@@ -22424,7 +22492,7 @@ async function beginOneShotEvidence(root, intent, sensitive) {
22424
22492
  if (finished) throw new Error("oneshot_evidence_already_finished");
22425
22493
  finished = true;
22426
22494
  return write("result.json", {
22427
- schema: "kxm.oneshot-evidence.v1",
22495
+ schema: ONESHOT_EVIDENCE_SCHEMA,
22428
22496
  id,
22429
22497
  recordedAt: (/* @__PURE__ */ new Date()).toISOString(),
22430
22498
  stdout: bounded(result.stdout),
@@ -22434,6 +22502,7 @@ async function beginOneShotEvidence(root, intent, sensitive) {
22434
22502
  started: result.started ?? null,
22435
22503
  observedChildExit: result.observedChildExit ?? null,
22436
22504
  terminationRequested: result.terminationRequested ?? null,
22505
+ unverifiedDescendants: result.unverifiedDescendants ?? null,
22437
22506
  error: result.error ? bounded(result.error.message) : null,
22438
22507
  observation: bounded(JSON.stringify(observation)),
22439
22508
  acceptance: false
@@ -26106,7 +26175,8 @@ Return a final JSON object with an "outcome" field chosen from ${JSON.stringify(
26106
26175
  parsed = { text: "", isError: true };
26107
26176
  }
26108
26177
  const aborted = request.signal.aborted || procResult.error?.message === "process_aborted";
26109
- const effectUncertain = procResult.terminationRequested === true || Boolean(procResult.signal) || procResult.error?.message === "process_exit_unobserved" || procResult.observedChildExit === false && procResult.started !== false;
26178
+ const unverifiedDescendants = procResult.unverifiedDescendants === true || procResult.terminationRequested === true || procResult.error?.message === "process_exit_unobserved" || procResult.observedChildExit === false && procResult.started !== false;
26179
+ const effectUncertain = unverifiedDescendants || Boolean(procResult.signal);
26110
26180
  const transportFailed = procResult.code !== 0 || Boolean(procResult.error) || effectUncertain;
26111
26181
  const outcome = aborted ? "cancelled" : transportFailed || parsed.isError ? "failed" : determineOutcome(parsed.text, request.allowedOutcomes);
26112
26182
  const providerMetadata = {
@@ -26118,6 +26188,7 @@ Return a final JSON object with an "outcome" field chosen from ${JSON.stringify(
26118
26188
  if (procResult.observedChildExit !== void 0) providerMetadata.observedChildExit = procResult.observedChildExit;
26119
26189
  if (procResult.started !== void 0) providerMetadata.processStarted = procResult.started;
26120
26190
  if (procResult.terminationRequested !== void 0) providerMetadata.terminationRequested = procResult.terminationRequested;
26191
+ if (unverifiedDescendants) providerMetadata.descendantEffects = "unverified";
26121
26192
  if (procResult.error) {
26122
26193
  const reason = procResult.error.message;
26123
26194
  providerMetadata.processError = /^process_(aborted|timeout|output_limit|stdin_error|stdio_error|stdio_unclosed|exit_unobserved)$/.test(reason) ? reason : "process_error";
@@ -26598,7 +26669,6 @@ async function startVnextRuntimeSupervisorInner(paths, requestedPortOption, now)
26598
26669
  });
26599
26670
  } catch (err) {
26600
26671
  earlyError = err;
26601
- drivePromise = Promise.reject(err);
26602
26672
  }
26603
26673
  await Promise.resolve();
26604
26674
  if (earlyError) {
@@ -26624,6 +26694,7 @@ async function startVnextRuntimeSupervisorInner(paths, requestedPortOption, now)
26624
26694
  } catch {
26625
26695
  }
26626
26696
  }
26697
+ }).catch(() => {
26627
26698
  });
26628
26699
  sendJson(response, 202, {
26629
26700
  ok: true,
@@ -27109,19 +27180,21 @@ function createVnextPiProducer(options = {}) {
27109
27180
  const parsed = parseModelString(defaultModel);
27110
27181
  return { provider: parsed.provider, model: parsed.model };
27111
27182
  }
27112
- function checkPiAuth(provider, model) {
27183
+ async function checkPiAuth(provider, model, signal) {
27113
27184
  if (options.inventory) {
27114
27185
  const piEntry = options.inventory.harnesses.find((h) => h.id === "pi");
27115
27186
  if (!piEntry || !piEntry.detected || piEntry.authenticated === false) {
27116
27187
  throw new Error("pi_not_authenticated: pi harness not authenticated in inventory");
27117
27188
  }
27118
27189
  }
27119
- const probeFn = options.probeHarness ?? probeHarnessAssignment;
27120
- const probe = probeFn({
27190
+ const probeFn = options.probeHarness ?? probeHarnessAssignmentAsync;
27191
+ const probe = await probeFn({
27121
27192
  harness: "pi",
27122
27193
  provider,
27123
27194
  model,
27124
- env: options.env
27195
+ env: options.env,
27196
+ signal,
27197
+ timeoutMs: 1e4
27125
27198
  });
27126
27199
  if (!probe.detected) {
27127
27200
  throw new Error(`pi_not_authenticated: pi harness not detected (${probe.issues.join(", ")})`);
@@ -27197,7 +27270,7 @@ function createVnextPiProducer(options = {}) {
27197
27270
  async produce(request) {
27198
27271
  const startTime = Date.now();
27199
27272
  const resolved = resolveModelForRequest(request);
27200
- checkPiAuth(resolved.provider, resolved.model);
27273
+ await checkPiAuth(resolved.provider, resolved.model, request.signal);
27201
27274
  const session = await getOrCreateSession(request, resolved.model);
27202
27275
  const promptMessage = request.prompt ?? `Execute step ${request.stepId} (attempt ${request.stepAttempt}) for agent ${request.agentId}. Allowed outcomes: ${request.allowedOutcomes.join(", ")}.`;
27203
27276
  let promptResult;
@@ -28815,6 +28888,212 @@ function executeSshRun(params) {
28815
28888
  durationMs: Date.now() - startTime
28816
28889
  };
28817
28890
  }
28891
+
28892
+ // plugins/kxm/src/subagent-control.ts
28893
+ import { randomUUID as randomUUID5 } from "node:crypto";
28894
+ var SUBAGENT_TYPES = Object.freeze([
28895
+ "general",
28896
+ "Explore",
28897
+ "Plan",
28898
+ "Reviewer",
28899
+ "Auditor"
28900
+ ]);
28901
+ var DEFAULT_SUBAGENT_MODELS = Object.freeze({
28902
+ general: "grok/grok-4.6",
28903
+ Explore: "openrouter/qwen/qwen3-coder-plus",
28904
+ Plan: "claude/fable",
28905
+ Reviewer: "openai/gpt-5.6-sol",
28906
+ Auditor: "claude/fable"
28907
+ });
28908
+ function narrowSubagentTools(requestedTools, parentTools) {
28909
+ if (!requestedTools || requestedTools.length === 0) {
28910
+ return parentTools ? [...parentTools] : ["read", "grep", "find"];
28911
+ }
28912
+ if (!parentTools || parentTools.length === 0) {
28913
+ return [...requestedTools];
28914
+ }
28915
+ const parentSet = new Set(parentTools);
28916
+ const narrowed = [];
28917
+ for (const tool of requestedTools) {
28918
+ if (parentSet.has(tool)) {
28919
+ narrowed.push(tool);
28920
+ }
28921
+ }
28922
+ if (narrowed.length === 0 && requestedTools.length > 0) {
28923
+ throw new Error(
28924
+ `Cannot spawn subagent: requested tools [${requestedTools.join(", ")}] expand beyond parent capabilities.`
28925
+ );
28926
+ }
28927
+ return narrowed;
28928
+ }
28929
+ var SubagentManager = class {
28930
+ subagents = /* @__PURE__ */ new Map();
28931
+ /**
28932
+ * Spawns a new managed subagent with strict capability boundaries.
28933
+ */
28934
+ spawn(params) {
28935
+ if (!params.prompt || !params.prompt.trim()) {
28936
+ throw new Error('Subagent "prompt" is required.');
28937
+ }
28938
+ if (!params.description || !params.description.trim()) {
28939
+ throw new Error('Subagent "description" is required.');
28940
+ }
28941
+ const type = params.type ?? "general";
28942
+ const model = params.model ?? DEFAULT_SUBAGENT_MODELS[type] ?? "grok/grok-4.6";
28943
+ const thinking = params.thinking ?? "low";
28944
+ const allowedTools = narrowSubagentTools(params.allowed_tools, params.parent_tools);
28945
+ const id = `ag_${randomUUID5().replaceAll("-", "").slice(0, 10)}`;
28946
+ const now = (/* @__PURE__ */ new Date()).toISOString();
28947
+ const record2 = {
28948
+ id,
28949
+ description: params.description.trim(),
28950
+ type,
28951
+ model,
28952
+ thinking,
28953
+ allowedTools,
28954
+ status: params.background === false ? "completed" : "running",
28955
+ turnsMax: params.turns ?? 10,
28956
+ turnsCompleted: 0,
28957
+ prompt: params.prompt.trim(),
28958
+ createdAt: now,
28959
+ updatedAt: now,
28960
+ steeringMessages: []
28961
+ };
28962
+ this.subagents.set(id, record2);
28963
+ return record2;
28964
+ }
28965
+ /**
28966
+ * Dispatches an action from the `agent_control` tool.
28967
+ */
28968
+ control(params) {
28969
+ const action = params.action;
28970
+ if (action === "info") {
28971
+ const kind = params.kind ?? "active";
28972
+ if (kind === "types") {
28973
+ return {
28974
+ ok: true,
28975
+ action: "info",
28976
+ types: SUBAGENT_TYPES
28977
+ };
28978
+ }
28979
+ if (kind === "models") {
28980
+ return {
28981
+ ok: true,
28982
+ action: "info",
28983
+ result: JSON.stringify(DEFAULT_SUBAGENT_MODELS)
28984
+ };
28985
+ }
28986
+ const active = Array.from(this.subagents.values()).map((ag) => ({
28987
+ id: ag.id,
28988
+ description: ag.description,
28989
+ type: ag.type,
28990
+ status: ag.status
28991
+ }));
28992
+ return {
28993
+ ok: true,
28994
+ action: "info",
28995
+ activeAgents: active
28996
+ };
28997
+ }
28998
+ if (!params.agent_id) {
28999
+ return {
29000
+ ok: false,
29001
+ action,
29002
+ error: 'Parameter "agent_id" is required for result, steer, and stop actions.'
29003
+ };
29004
+ }
29005
+ const agent = this.subagents.get(params.agent_id);
29006
+ if (!agent) {
29007
+ return {
29008
+ ok: false,
29009
+ action,
29010
+ agent_id: params.agent_id,
29011
+ error: `Subagent "${params.agent_id}" not found.`
29012
+ };
29013
+ }
29014
+ if (action === "result") {
29015
+ return {
29016
+ ok: true,
29017
+ action: "result",
29018
+ agent_id: agent.id,
29019
+ status: agent.status,
29020
+ result: agent.output ?? `[Subagent is currently ${agent.status}]`
29021
+ };
29022
+ }
29023
+ if (action === "steer") {
29024
+ if (!params.message || !params.message.trim()) {
29025
+ return {
29026
+ ok: false,
29027
+ action: "steer",
29028
+ agent_id: agent.id,
29029
+ error: 'Parameter "message" is required for steer action.'
29030
+ };
29031
+ }
29032
+ if (agent.status === "completed" || agent.status === "stopped" || agent.status === "failed") {
29033
+ return {
29034
+ ok: false,
29035
+ action: "steer",
29036
+ agent_id: agent.id,
29037
+ error: `Cannot steer subagent "${agent.id}" because it is already ${agent.status}.`
29038
+ };
29039
+ }
29040
+ agent.steeringMessages.push({
29041
+ text: params.message.trim(),
29042
+ injectedAt: (/* @__PURE__ */ new Date()).toISOString(),
29043
+ processed: false
29044
+ });
29045
+ agent.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
29046
+ return {
29047
+ ok: true,
29048
+ action: "steer",
29049
+ agent_id: agent.id,
29050
+ status: agent.status,
29051
+ steered: true
29052
+ };
29053
+ }
29054
+ if (action === "stop") {
29055
+ agent.status = "stopped";
29056
+ agent.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
29057
+ return {
29058
+ ok: true,
29059
+ action: "stop",
29060
+ agent_id: agent.id,
29061
+ status: "stopped",
29062
+ stopped: true
29063
+ };
29064
+ }
29065
+ return {
29066
+ ok: false,
29067
+ action,
29068
+ error: `Unknown control action "${action}".`
29069
+ };
29070
+ }
29071
+ /**
29072
+ * Retrieves an agent record by ID.
29073
+ */
29074
+ get(agentId) {
29075
+ return this.subagents.get(agentId);
29076
+ }
29077
+ /**
29078
+ * Marks a subagent as completed with output.
29079
+ */
29080
+ complete(agentId, output) {
29081
+ const agent = this.subagents.get(agentId);
29082
+ if (agent) {
29083
+ agent.status = "completed";
29084
+ agent.output = output;
29085
+ agent.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
29086
+ }
29087
+ }
29088
+ /**
29089
+ * Returns all active running subagents.
29090
+ */
29091
+ listActive() {
29092
+ return Array.from(this.subagents.values()).filter(
29093
+ (ag) => ag.status === "running" || ag.status === "pending" || ag.status === "blocked"
29094
+ );
29095
+ }
29096
+ };
28818
29097
  export {
28819
29098
  BUILTIN_HARNESSES,
28820
29099
  BUILTIN_HARNESS_IDS,
@@ -28825,6 +29104,7 @@ export {
28825
29104
  DEFAULT_LOG_MAX_FILES,
28826
29105
  DEFAULT_MODES_CONFIG,
28827
29106
  DEFAULT_SOCKET_DIR,
29107
+ DEFAULT_SUBAGENT_MODELS,
28828
29108
  IMPROVEMENT_REPORT_SCHEMA,
28829
29109
  IMPROVEMENT_REPORT_V1_SCHEMA,
28830
29110
  LOG_LEVEL_PRIORITY,
@@ -28835,7 +29115,9 @@ export {
28835
29115
  PI_NATIVE_BRAKE_PROVIDERS,
28836
29116
  PiSession,
28837
29117
  SAFE_HARNESS_COMMAND_ID,
29118
+ SUBAGENT_TYPES,
28838
29119
  SteelClient,
29120
+ SubagentManager,
28839
29121
  VIEWPORT_PRESETS,
28840
29122
  VNEXT_ABSENT_MEMORY_REVISION,
28841
29123
  VNEXT_EVENT_STORE_SCHEMA_VERSION,
@@ -28898,6 +29180,7 @@ export {
28898
29180
  isVnextRuntimeContextClosed,
28899
29181
  isWindowsHarnessShim,
28900
29182
  loadModesConfig,
29183
+ narrowSubagentTools,
28901
29184
  newVnextAssignmentId,
28902
29185
  newVnextAttemptId,
28903
29186
  newVnextCommandId,
@@ -28921,7 +29204,9 @@ export {
28921
29204
  probeHarnessAssignment,
28922
29205
  probeHarnessAssignmentAsync,
28923
29206
  probeHarnesses,
29207
+ probeHarnessesAsync,
28924
29208
  probeHarnessesForModel,
29209
+ probeHarnessesForModelAsync,
28925
29210
  projectRuntimeKey,
28926
29211
  pruneSocketDir,
28927
29212
  readVnextRunStatus,