@wrongstack/core 0.9.4 → 0.9.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/dist/{agent-subagent-runner-DaF_EgRG.d.ts → agent-subagent-runner-C4qt9e5Y.d.ts} +1 -1
  2. package/dist/{config-SkMIDN9L.d.ts → config-CWva0qoL.d.ts} +4 -0
  3. package/dist/coordination/index.d.ts +8 -7
  4. package/dist/coordination/index.js +672 -46
  5. package/dist/coordination/index.js.map +1 -1
  6. package/dist/defaults/index.d.ts +12 -11
  7. package/dist/defaults/index.js +780 -23
  8. package/dist/defaults/index.js.map +1 -1
  9. package/dist/execution/index.d.ts +7 -6
  10. package/dist/execution/index.js +1 -0
  11. package/dist/execution/index.js.map +1 -1
  12. package/dist/extension/index.d.ts +4 -3
  13. package/dist/{index-CP8638Wm.d.ts → index-aizK8olO.d.ts} +3 -2
  14. package/dist/{index-Bsha5K4D.d.ts → index-p95HQ22A.d.ts} +3 -2
  15. package/dist/index.d.ts +22 -16
  16. package/dist/index.js +861 -35
  17. package/dist/index.js.map +1 -1
  18. package/dist/infrastructure/index.d.ts +2 -2
  19. package/dist/kernel/index.d.ts +4 -3
  20. package/dist/{mcp-servers-BouUWYW6.d.ts → mcp-servers-BkVEqkRe.d.ts} +1 -1
  21. package/dist/{multi-agent-coordinator-DTXF2aAl.d.ts → multi-agent-coordinator-bRaI_aD1.d.ts} +1 -1
  22. package/dist/{null-fleet-bus-Chrc_3Pp.d.ts → null-fleet-bus-DKM3Iy9d.d.ts} +183 -3
  23. package/dist/{secret-scrubber-DttNiGYA.d.ts → permission-bPuzAy4x.d.ts} +1 -6
  24. package/dist/{permission-policy-BpCGYBud.d.ts → permission-policy-BUQSutpl.d.ts} +8 -1
  25. package/dist/{plan-templates-envSmNlZ.d.ts → plan-templates-fkQTyz3U.d.ts} +25 -1
  26. package/dist/sdd/index.d.ts +5 -4
  27. package/dist/sdd/index.js +1 -0
  28. package/dist/sdd/index.js.map +1 -1
  29. package/dist/secret-scrubber-3MHDDAtm.d.ts +6 -0
  30. package/dist/{secret-scrubber-QSeI0ADi.d.ts → secret-scrubber-7rSC_emZ.d.ts} +1 -1
  31. package/dist/security/index.d.ts +4 -3
  32. package/dist/security/index.js +37 -6
  33. package/dist/security/index.js.map +1 -1
  34. package/dist/storage/index.d.ts +3 -2
  35. package/dist/storage/index.js +88 -5
  36. package/dist/storage/index.js.map +1 -1
  37. package/dist/{tool-executor-CsktM3h9.d.ts → tool-executor-Boo3dekH.d.ts} +1 -1
  38. package/dist/types/index.d.ts +6 -5
  39. package/dist/types/index.js.map +1 -1
  40. package/dist/utils/index.d.ts +12 -1
  41. package/dist/utils/index.js +85 -1
  42. package/dist/utils/index.js.map +1 -1
  43. package/package.json +1 -1
  44. package/skills/api-design/SKILL.md +139 -0
  45. package/skills/audit-log/SKILL.md +87 -14
  46. package/skills/bug-hunter/SKILL.md +42 -19
  47. package/skills/docker-deploy/SKILL.md +155 -0
  48. package/skills/git-flow/SKILL.md +53 -1
  49. package/skills/multi-agent/SKILL.md +42 -0
  50. package/skills/node-modern/SKILL.md +57 -1
  51. package/skills/observability/SKILL.md +134 -0
  52. package/skills/prompt-engineering/SKILL.md +46 -19
  53. package/skills/react-modern/SKILL.md +92 -1
  54. package/skills/refactor-planner/SKILL.md +49 -1
  55. package/skills/sdd/SKILL.md +12 -1
  56. package/skills/security-scanner/SKILL.md +46 -1
  57. package/skills/skill-creator/SKILL.md +49 -52
  58. package/skills/testing/SKILL.md +170 -0
  59. package/skills/typescript-strict/SKILL.md +98 -1
package/dist/index.js CHANGED
@@ -4124,14 +4124,100 @@ function deepEqual(a, b) {
4124
4124
  return false;
4125
4125
  }
4126
4126
 
4127
+ // src/utils/json-repair.ts
4128
+ function completePartialObject(s) {
4129
+ let result = s;
4130
+ const trimmed = result.trim();
4131
+ if (!trimmed.startsWith("{")) return s;
4132
+ for (let pass = 0; pass < 3; pass++) {
4133
+ let braceDepth = 0;
4134
+ let inString2 = false;
4135
+ let escaped2 = false;
4136
+ let foundClose = false;
4137
+ for (const ch of result) {
4138
+ if (escaped2) {
4139
+ escaped2 = false;
4140
+ continue;
4141
+ }
4142
+ if (ch === "\\") {
4143
+ escaped2 = true;
4144
+ continue;
4145
+ }
4146
+ if (ch === '"') {
4147
+ inString2 = !inString2;
4148
+ continue;
4149
+ }
4150
+ if (inString2) continue;
4151
+ if (ch === "{") {
4152
+ braceDepth++;
4153
+ foundClose = false;
4154
+ } else if (ch === "}") {
4155
+ braceDepth--;
4156
+ if (braceDepth === 0) foundClose = true;
4157
+ }
4158
+ }
4159
+ if (foundClose || braceDepth <= 0) break;
4160
+ result += "}".repeat(braceDepth);
4161
+ }
4162
+ if (tryParse(result).ok) return result;
4163
+ let inString = false;
4164
+ let escaped = false;
4165
+ for (let i = result.length - 1; i >= 0; i--) {
4166
+ const ch = result[i];
4167
+ if (escaped) {
4168
+ escaped = false;
4169
+ continue;
4170
+ }
4171
+ if (ch === "\\") {
4172
+ escaped = true;
4173
+ continue;
4174
+ }
4175
+ if (ch === '"') {
4176
+ let nextNonWs;
4177
+ for (let j = i + 1; j < result.length; j++) {
4178
+ const nc = result[j];
4179
+ if (nc === " " || nc === " " || nc === "\n" || nc === "\r") continue;
4180
+ nextNonWs = result[j];
4181
+ break;
4182
+ }
4183
+ if (nextNonWs === ":") {
4184
+ continue;
4185
+ } else {
4186
+ inString = !inString;
4187
+ continue;
4188
+ }
4189
+ }
4190
+ }
4191
+ if (inString) {
4192
+ result = result.trimEnd();
4193
+ if (result.endsWith("\\")) result = result.slice(0, -1);
4194
+ let depth = 0;
4195
+ for (const ch of result) {
4196
+ if (ch === "{") depth++;
4197
+ else if (ch === "}") depth = Math.max(0, depth - 1);
4198
+ }
4199
+ result += '"' + "}".repeat(Math.max(1, depth));
4200
+ }
4201
+ return result;
4202
+ }
4203
+ function tryParse(s) {
4204
+ try {
4205
+ return { ok: true, value: JSON.parse(s) };
4206
+ } catch {
4207
+ return { ok: false };
4208
+ }
4209
+ }
4210
+
4127
4211
  // src/storage/session-store.ts
4128
4212
  init_atomic_write();
4129
4213
  var DefaultSessionStore = class {
4130
4214
  dir;
4131
4215
  events;
4216
+ secretScrubber;
4132
4217
  constructor(opts) {
4133
4218
  this.dir = opts.dir;
4134
4219
  this.events = opts.events;
4220
+ this.secretScrubber = opts.secretScrubber;
4135
4221
  }
4136
4222
  /** Join session ID to its absolute path within the store directory. */
4137
4223
  sessionPath(id, ext) {
@@ -4156,7 +4242,11 @@ var DefaultSessionStore = class {
4156
4242
  );
4157
4243
  }
4158
4244
  try {
4159
- return new FileSessionWriter(id, handle, startedAt, meta, this.events, { dir: shardDir, filePath: file });
4245
+ return new FileSessionWriter(id, handle, startedAt, meta, this.events, {
4246
+ dir: shardDir,
4247
+ filePath: file,
4248
+ secretScrubber: this.secretScrubber
4249
+ });
4160
4250
  } catch (err) {
4161
4251
  await handle.close().catch(() => {
4162
4252
  });
@@ -4186,7 +4276,7 @@ var DefaultSessionStore = class {
4186
4276
  provider: data.metadata.provider
4187
4277
  },
4188
4278
  this.events,
4189
- { resumed: true, dir: this.dir, filePath: file }
4279
+ { resumed: true, dir: this.dir, filePath: file, secretScrubber: this.secretScrubber }
4190
4280
  );
4191
4281
  return { writer, data };
4192
4282
  } catch (err) {
@@ -4392,6 +4482,7 @@ var FileSessionWriter = class {
4392
4482
  this.resumed = opts.resumed ?? false;
4393
4483
  this.manifestFile = opts.dir ? path6.join(opts.dir, `${id}.summary.json`) : "";
4394
4484
  this.filePath = opts.filePath ?? "";
4485
+ this.secretScrubber = opts.secretScrubber;
4395
4486
  this.summary = {
4396
4487
  id,
4397
4488
  title: "(empty session)",
@@ -4420,6 +4511,29 @@ var FileSessionWriter = class {
4420
4511
  resumed;
4421
4512
  appendFailCount = 0;
4422
4513
  lastAppendWarnAt = 0;
4514
+ secretScrubber;
4515
+ /**
4516
+ * Scrub secrets out of conversation-turn events before they are observed
4517
+ * for the summary, written to the JSONL log, or surfaced on resume. Only
4518
+ * `user_input` / `llm_response` carry free-form user/model text; other event
4519
+ * types either have no secret-bearing content or are already scrubbed
4520
+ * upstream (tool results). Returns the event unchanged when no scrubber is
4521
+ * configured.
4522
+ */
4523
+ scrubEvent(event) {
4524
+ const s = this.secretScrubber;
4525
+ if (!s) return event;
4526
+ if (event.type === "user_input") {
4527
+ return {
4528
+ ...event,
4529
+ content: typeof event.content === "string" ? s.scrub(event.content) : s.scrubObject(event.content)
4530
+ };
4531
+ }
4532
+ if (event.type === "llm_response") {
4533
+ return { ...event, content: s.scrubObject(event.content) };
4534
+ }
4535
+ return event;
4536
+ }
4423
4537
  promptIndex = 0;
4424
4538
  pendingFileSnapshots = [];
4425
4539
  /** Tracks open tool_use IDs during the current run to serialize on close for resume. */
@@ -4452,9 +4566,10 @@ var FileSessionWriter = class {
4452
4566
  this.initDone = true;
4453
4567
  await this.writeSessionStartLazy();
4454
4568
  }
4455
- this.observeForSummary(event);
4569
+ const scrubbed = this.scrubEvent(event);
4570
+ this.observeForSummary(scrubbed);
4456
4571
  try {
4457
- await this.handle.appendFile(`${JSON.stringify(event)}
4572
+ await this.handle.appendFile(`${JSON.stringify(scrubbed)}
4458
4573
  `, "utf8");
4459
4574
  } catch (err) {
4460
4575
  this.appendFailCount++;
@@ -5077,6 +5192,7 @@ function isSecretField2(name) {
5077
5192
  }
5078
5193
 
5079
5194
  // src/storage/config-loader.ts
5195
+ init_atomic_write();
5080
5196
  var BEHAVIOR_DEFAULTS = {
5081
5197
  version: 1,
5082
5198
  context: {
@@ -5237,6 +5353,40 @@ var DefaultConfigLoader = class {
5237
5353
  }
5238
5354
  return Object.freeze(cfg);
5239
5355
  }
5356
+ /**
5357
+ * Persist a sync config to ~/.wrongstack/sync.json, with the token encrypted
5358
+ * by the vault (if provided). The file is isolated from the main config
5359
+ * hierarchy to prevent accidental commits.
5360
+ */
5361
+ async persistSyncConfig(cfg) {
5362
+ let toWrite = { ...cfg };
5363
+ if (this.vault && toWrite.githubToken && !toWrite.githubToken.startsWith("enc:")) {
5364
+ toWrite = { ...toWrite, githubToken: this.vault.encrypt(toWrite.githubToken) };
5365
+ }
5366
+ await atomicWrite(this.paths.syncConfig, JSON.stringify(toWrite, null, 2), { mode: 384 });
5367
+ }
5368
+ /**
5369
+ * Read ~/.wrongstack/sync.json (encrypted GitHub token storage) and decrypt
5370
+ * the token if a vault is available. Returns null if the file doesn't exist.
5371
+ * This is separate from main config loading because sync.json is intentionally
5372
+ * isolated — it should never be part of project-local or env-driven config.
5373
+ */
5374
+ async loadSyncConfig() {
5375
+ try {
5376
+ const raw = await fsp2.readFile(this.paths.syncConfig, "utf8");
5377
+ const parsed = safeParse(raw);
5378
+ if (!parsed.ok || !parsed.value) return null;
5379
+ if (this.vault) {
5380
+ const decrypted = decryptConfigSecrets2({ sync: parsed.value }, this.vault);
5381
+ return decrypted.sync ?? null;
5382
+ }
5383
+ return parsed.value;
5384
+ } catch (err) {
5385
+ if (err.code === "ENOENT") return null;
5386
+ console.warn("[config] Failed to load sync config:", err);
5387
+ return null;
5388
+ }
5389
+ }
5240
5390
  async readJson(file) {
5241
5391
  let raw;
5242
5392
  try {
@@ -6160,7 +6310,11 @@ var DefaultPermissionPolicy = class {
6160
6310
  return { permission: "deny", source: "deny", reason: "session soft deny (user pressed no)" };
6161
6311
  }
6162
6312
  if (this.sessionAllowed.has(subjectKey)) {
6163
- return { permission: "auto", source: "trust", reason: "session soft allow (user pressed yes)" };
6313
+ return {
6314
+ permission: "auto",
6315
+ source: "trust",
6316
+ reason: "session soft allow (user pressed yes)"
6317
+ };
6164
6318
  }
6165
6319
  if (entry?.deny && subject && matchAny(entry.deny, subject)) {
6166
6320
  return { permission: "deny", source: "deny", reason: "matched deny pattern" };
@@ -6180,7 +6334,11 @@ var DefaultPermissionPolicy = class {
6180
6334
  const decision = await this.promptDelegate(tool, input, subject ?? tool.name);
6181
6335
  if (decision === "always") {
6182
6336
  await this.trust({ tool: tool.name, pattern: subject ?? tool.name });
6183
- return { permission: "auto", source: "user", reason: "destructive yolo always-allowed" };
6337
+ return {
6338
+ permission: "auto",
6339
+ source: "user",
6340
+ reason: "destructive yolo always-allowed"
6341
+ };
6184
6342
  }
6185
6343
  if (decision === "deny") {
6186
6344
  await this.deny({ tool: tool.name, pattern: subject ?? tool.name });
@@ -6188,13 +6346,22 @@ var DefaultPermissionPolicy = class {
6188
6346
  }
6189
6347
  return { permission: decision === "yes" ? "auto" : "deny", source: "user" };
6190
6348
  }
6191
- return { permission: "confirm", source: "yolo_destructive", riskTier: "destructive", reason: "destructive tool needs explicit approval even in yolo mode" };
6349
+ return {
6350
+ permission: "confirm",
6351
+ source: "yolo_destructive",
6352
+ riskTier: "destructive",
6353
+ reason: "destructive tool needs explicit approval even in yolo mode"
6354
+ };
6192
6355
  }
6193
6356
  return { permission: "auto", source: "yolo" };
6194
6357
  }
6195
6358
  if (tool.name === "write" && subject) {
6196
6359
  if (ctx.hasRead(subject)) {
6197
- return { permission: "auto", source: "context", reason: "file already read in this session" };
6360
+ return {
6361
+ permission: "auto",
6362
+ source: "context",
6363
+ reason: "file already read in this session"
6364
+ };
6198
6365
  }
6199
6366
  }
6200
6367
  if (tool.permission === "auto" && !tool.mutating) {
@@ -6302,6 +6469,10 @@ var AutoApprovePermissionPolicy = class _AutoApprovePermissionPolicy {
6302
6469
  // arbitrary shell — use exec for constrained shell
6303
6470
  "write",
6304
6471
  // arbitrary file write
6472
+ "edit",
6473
+ // arbitrary in-project file modification (equivalent to write)
6474
+ "replace",
6475
+ // arbitrary multi-file find/replace (equivalent to write)
6305
6476
  "scaffold",
6306
6477
  // arbitrary file generation outside project root
6307
6478
  "patch",
@@ -6311,12 +6482,22 @@ var AutoApprovePermissionPolicy = class _AutoApprovePermissionPolicy {
6311
6482
  "exec"
6312
6483
  // restricted shell but with arbitrary command args
6313
6484
  ]);
6485
+ /**
6486
+ * Tools from MCP servers (`mcp__<server>__<tool>`) are external code of
6487
+ * unknown capability — they may wrap a shell or filesystem. They are
6488
+ * fail-closed here: not auto-approved for subagents by default, so the
6489
+ * leader must allow them explicitly per-spawn.
6490
+ */
6491
+ static isMcpTool(name) {
6492
+ return name.startsWith("mcp__");
6493
+ }
6314
6494
  async evaluate(tool) {
6315
- if (tool.permission === "deny" || _AutoApprovePermissionPolicy.DENY.has(tool.name)) {
6495
+ const blocked = _AutoApprovePermissionPolicy.DENY.has(tool.name) || _AutoApprovePermissionPolicy.isMcpTool(tool.name);
6496
+ if (tool.permission === "deny" || blocked) {
6316
6497
  return {
6317
6498
  permission: "deny",
6318
6499
  source: "subagent_guard",
6319
- reason: _AutoApprovePermissionPolicy.DENY.has(tool.name) ? `tool ${tool.name} is not auto-approved for subagents \u2014 ask the leader to allow it explicitly` : "tool default deny"
6500
+ reason: blocked ? `tool ${tool.name} is not auto-approved for subagents \u2014 ask the leader to allow it explicitly` : "tool default deny"
6320
6501
  };
6321
6502
  }
6322
6503
  return { permission: "auto", source: "yolo" };
@@ -6561,7 +6742,12 @@ function safeJsonOrRaw(s) {
6561
6742
  try {
6562
6743
  return JSON.parse(s);
6563
6744
  } catch {
6564
- return { _raw: s };
6745
+ const repaired = completePartialObject(s);
6746
+ try {
6747
+ return JSON.parse(repaired);
6748
+ } catch {
6749
+ return { _raw: repaired };
6750
+ }
6565
6751
  }
6566
6752
  }
6567
6753
  function handleToolUseStop(state, ev) {
@@ -11283,11 +11469,46 @@ Working rules:
11283
11469
  - When in doubt, flag as medium rather than ignoring potential issues`
11284
11470
  // Budgets are set by the orchestrator per task — see fleet.ts header.
11285
11471
  };
11472
+ var CRITIC_AGENT = {
11473
+ id: "critic",
11474
+ name: "Critic",
11475
+ role: "critic",
11476
+ prompt: `You are the Critic agent. Your job is to evaluate code quality,
11477
+ architectural decisions, and proposed changes against project conventions,
11478
+ engineering standards, and known quality gates. You do not write code \u2014
11479
+ you judge it.
11480
+
11481
+ Scope:
11482
+ - Evaluate bug severity and fix quality from Bug Hunter reports
11483
+ - Score refactoring plans from Refactor Planner (risk, completeness, trade-offs)
11484
+ - Flag gaps in test coverage, error handling, and edge case coverage
11485
+ - Assess whether a proposed change aligns with existing project patterns
11486
+ - Detect over-engineering or under-engineering relative to the problem scope
11487
+
11488
+ Input format you accept:
11489
+ { "task": "evaluate | score | review", "subject": "bug_report | refactor_plan | diff", "focus": "correctness | maintainability | risk | all" }
11490
+
11491
+ Output: Markdown critic report:
11492
+ - ## Overall Score (0-10 with rationale)
11493
+ - ## Strengths (what's solid)
11494
+ - ## Weaknesses (what needs work)
11495
+ - ## Specific Concerns (with file:line when applicable)
11496
+ - ## Verdict: **Approve / Needs Revision / Reject**
11497
+
11498
+ Working rules:
11499
+ - Be specific \u2014 "looks fine" is not a review. Cite concrete evidence.
11500
+ - When scoring, explain the delta from a perfect score.
11501
+ - If you have no basis to evaluate a concern, say so rather than speculating.
11502
+ - Prioritise correctness over style; correctness issues block approval.
11503
+ - Score thresholds: \u22657 = Approve, 4-6 = Needs Revision, <4 = Reject`
11504
+ // Budgets are set by the orchestrator per task — see fleet.ts header.
11505
+ };
11286
11506
  var FLEET_ROSTER = {
11287
11507
  "audit-log": AUDIT_LOG_AGENT,
11288
11508
  "bug-hunter": BUG_HUNTER_AGENT,
11289
11509
  "refactor-planner": REFACTOR_PLANNER_AGENT,
11290
11510
  "security-scanner": SECURITY_SCANNER_AGENT,
11511
+ "critic": CRITIC_AGENT,
11291
11512
  ...Object.fromEntries(
11292
11513
  ALL_AGENT_DEFINITIONS.map((d) => [d.config.role, d.config])
11293
11514
  )
@@ -11297,6 +11518,7 @@ var FLEET_ROSTER_BUDGETS = {
11297
11518
  "bug-hunter": { timeoutMs: 10 * 60 * 60 * 1e3, maxIterations: 8e3, maxToolCalls: 2e4 },
11298
11519
  "refactor-planner": { timeoutMs: 7.5 * 60 * 60 * 1e3, maxIterations: 6e3, maxToolCalls: 18e3 },
11299
11520
  "security-scanner": { timeoutMs: 10 * 60 * 60 * 1e3, maxIterations: 8e3, maxToolCalls: 2e4 },
11521
+ "critic": { timeoutMs: 5 * 60 * 60 * 1e3, maxIterations: 4e3, maxToolCalls: 12e3 },
11300
11522
  ...Object.fromEntries(
11301
11523
  ALL_AGENT_DEFINITIONS.map((d) => [d.config.role, d.budget])
11302
11524
  )
@@ -11377,10 +11599,10 @@ FLEET_ROSTER_BUDGETS["gemini-cli"] = { timeoutMs: 10 * 60 * 60 * 1e3, maxIterati
11377
11599
  FLEET_ROSTER_BUDGETS["copilot"] = { timeoutMs: 10 * 60 * 60 * 1e3, maxIterations: 8e3, maxToolCalls: 2e4 };
11378
11600
  FLEET_ROSTER_BUDGETS["openhands"] = { timeoutMs: 10 * 60 * 60 * 1e3, maxIterations: 8e3, maxToolCalls: 2e4 };
11379
11601
  FLEET_ROSTER_BUDGETS["goose"] = { timeoutMs: 10 * 60 * 60 * 1e3, maxIterations: 8e3, maxToolCalls: 2e4 };
11380
- ({
11602
+ var FLEET_ROSTER_WITHACP = {
11381
11603
  ...FLEET_ROSTER,
11382
11604
  ...Object.fromEntries(ACP_AGENTS.map((a) => [a.role, a]))
11383
- });
11605
+ };
11384
11606
 
11385
11607
  // src/coordination/multi-agent-coordinator.ts
11386
11608
  var DefaultMultiAgentCoordinator = class extends EventEmitter {
@@ -12768,6 +12990,106 @@ var FleetUsageAggregator = class {
12768
12990
  snap.lastEventAt = e.ts;
12769
12991
  }
12770
12992
  };
12993
+
12994
+ // src/coordination/subagent-nicknames.ts
12995
+ var NICKNAME_POOL = {
12996
+ // Physics & fundamental sciences
12997
+ "einstein": { name: "Einstein", domain: "physics" },
12998
+ "newton": { name: "Newton", domain: "physics" },
12999
+ "feynman": { name: "Feynman", domain: "physics" },
13000
+ "dirac": { name: "Dirac", domain: "physics" },
13001
+ "bohr": { name: "Bohr", domain: "physics" },
13002
+ "planck": { name: "Planck", domain: "physics" },
13003
+ "curie": { name: "Curie", domain: "physics" },
13004
+ "fermi": { name: "Fermi", domain: "physics" },
13005
+ "heisenberg": { name: "Heisenberg", domain: "physics" },
13006
+ "schrodinger": { name: "Schr\xF6dinger", domain: "physics" },
13007
+ // Mathematics
13008
+ "euclid": { name: "Euclid", domain: "math" },
13009
+ "gauss": { name: "Gauss", domain: "math" },
13010
+ "turing": { name: "Turing", domain: "math" },
13011
+ "poincare": { name: "Poincar\xE9", domain: "math" },
13012
+ "riemann": { name: "Riemann", domain: "math" },
13013
+ "hilbert": { name: "Hilbert", domain: "math" },
13014
+ "pythagoras": { name: "Pythagoras", domain: "math" },
13015
+ // Computing & information theory
13016
+ "von-neumann": { name: "Von Neumann", domain: "computing" },
13017
+ "shannon": { name: "Shannon", domain: "computing" },
13018
+ "hopper": { name: "Hopper", domain: "computing" },
13019
+ "backus": { name: "Backus", domain: "computing" },
13020
+ "knuth": { name: "Knuth", domain: "computing" },
13021
+ "torvalds": { name: "Torvalds", domain: "computing" },
13022
+ "stallman": { name: "Stallman", domain: "computing" },
13023
+ "berners-lee": { name: "Berners-Lee", domain: "computing" },
13024
+ "babbage": { name: "Babbage", domain: "computing" },
13025
+ "lovelace": { name: "Lovelace", domain: "computing" },
13026
+ "klein": { name: "Klein", domain: "computing" },
13027
+ // Electronics & electrical engineering
13028
+ "edison": { name: "Edison", domain: "ee" },
13029
+ "tesla": { name: "Tesla", domain: "ee" },
13030
+ "faraday": { name: "Faraday", domain: "ee" },
13031
+ "maxwell": { name: "Maxwell", domain: "ee" },
13032
+ "ohm": { name: "Ohm", domain: "ee" },
13033
+ "bell": { name: "Bell", domain: "ee" },
13034
+ "marconi": { name: "Marconi", domain: "ee" },
13035
+ "lamarr": { name: "Lamarr", domain: "ee" },
13036
+ // General science / multi-disciplinary
13037
+ "darwin": { name: "Darwin", domain: "biology" },
13038
+ "mendel": { name: "Mendel", domain: "biology" },
13039
+ "pasteur": { name: "Pasteur", domain: "biology" },
13040
+ "hawking": { name: "Hawking", domain: "cosmology" },
13041
+ "sagan": { name: "Sagan", domain: "cosmology" },
13042
+ // Chemistry / materials
13043
+ "lavoisier": { name: "Lavoisier", domain: "chemistry" },
13044
+ "mendeleev": { name: "Mendeleev", domain: "chemistry" }
13045
+ };
13046
+ var ALL_NICKNAMES = Object.values(NICKNAME_POOL);
13047
+ var DOMAIN_PREFERENCES = {
13048
+ "security": ["shannon", "turing", "lamarr", "stallman"],
13049
+ "bug-hunter": ["darwin", "curie", "feynman", "fermi"],
13050
+ "refactor": ["gauss", "hilbert", "euclid", "planck"],
13051
+ "audit-log": ["sagan", "hawking", "poincare", "newton"],
13052
+ "planner": ["hilbert", "gauss", "turing", "euclid"],
13053
+ "researcher": ["sagan", "hawking", "darwin", "pasteur"],
13054
+ "explorer": ["marconi", "bell", "columbus", "polo"],
13055
+ "testing": ["pasteur", "curie", "fermi", "bohr"],
13056
+ "frontend": ["lovelace", "hopper", "babbage", "backus"],
13057
+ "backend": ["torvalds", "stallman", "von-neumann", "backus"],
13058
+ "database": ["turing", "shannon", "backus", "knuth"],
13059
+ "devops": ["tesla", "edison", "faraday", "bell"],
13060
+ "security-scanner": ["shannon", "turing", "lamarr", "stallman"],
13061
+ "refactor-planner": ["gauss", "hilbert", "planck", "newton"],
13062
+ "architect": ["von-neumann", "turing", "gauss", "hilbert"],
13063
+ "critic": ["einstein", "feynman", "dirac", "bohr"],
13064
+ "e2e": ["hopper", "bell", "marconi", "tesla"],
13065
+ "performance": ["knuth", "gauss", "planck", "feynman"],
13066
+ "chaos": ["tesla", "edison", "curie", "fermi"],
13067
+ "cost": ["oh", "bell", "marconi", "tesla"],
13068
+ // default fallback
13069
+ "default": ["einstein", "newton", "curie", "tesla", "edison", "turing", "shannon", "hopper", "knuth", "stallman"]
13070
+ };
13071
+ function assignNickname(role, used) {
13072
+ const preferences = [
13073
+ ...DOMAIN_PREFERENCES[role] ?? [],
13074
+ ...DOMAIN_PREFERENCES["default"] ?? []
13075
+ ];
13076
+ for (const key of preferences) {
13077
+ if (!used.has(key)) {
13078
+ return `${NICKNAME_POOL[key].name} (${formatRole(role)})`;
13079
+ }
13080
+ }
13081
+ for (const entry of ALL_NICKNAMES) {
13082
+ const key = Object.entries(NICKNAME_POOL).find(([, v]) => v.name === entry.name)?.[0];
13083
+ if (key && !used.has(key)) {
13084
+ return `${entry.name} (${formatRole(role)})`;
13085
+ }
13086
+ }
13087
+ const counter = used.size + 1;
13088
+ return `Scientist #${counter} (${formatRole(role)})`;
13089
+ }
13090
+ function formatRole(role) {
13091
+ return role.split(/[-_]/).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
13092
+ }
12771
13093
  function makeSpawnTool(director, roster) {
12772
13094
  const inputSchema = {
12773
13095
  type: "object",
@@ -12992,7 +13314,6 @@ function makeFleetSessionTool(director) {
12992
13314
  type: "object",
12993
13315
  properties: {
12994
13316
  subagentId: { type: "string", description: "Subagent id to read the transcript of." },
12995
- /** Number of trailing lines to return (last N JSONL lines). Default: all. */
12996
13317
  tail: { type: "number", description: "Number of trailing JSONL lines to return. Omit for the full transcript." }
12997
13318
  },
12998
13319
  required: ["subagentId"]
@@ -13028,8 +13349,6 @@ function makeFleetHealthTool(director) {
13028
13349
  id: s.id,
13029
13350
  status: s.status,
13030
13351
  lastEventAt: usage?.lastEventAt,
13031
- // Budget pressure: fraction of each limit consumed if we have it.
13032
- // BudgetWarning events carry used/limit ratios; surface them here.
13033
13352
  budgetPressure: {
13034
13353
  iterations: usage?.iterations,
13035
13354
  toolCalls: usage?.toolCalls,
@@ -13041,6 +13360,415 @@ function makeFleetHealthTool(director) {
13041
13360
  }
13042
13361
  };
13043
13362
  }
13363
+ function makeCollabDebugTool(director) {
13364
+ return {
13365
+ name: "collab_debug",
13366
+ description: "Start a collaborative debugging session: BugHunter, RefactorPlanner, and Critic run in parallel on the same target files. BugHunter finds bugs and emits bug.found events. RefactorPlanner listens for bug.found and emits refactor.plan events. Critic evaluates both and emits critic.evaluation events. Returns a structured report with overall verdict (approve / needs_revision / reject).",
13367
+ permission: "auto",
13368
+ mutating: false,
13369
+ inputSchema: {
13370
+ type: "object",
13371
+ properties: {
13372
+ targetPaths: {
13373
+ type: "array",
13374
+ items: { type: "string" },
13375
+ description: "File paths / glob patterns to scan for bugs."
13376
+ },
13377
+ timeoutMs: {
13378
+ type: "number",
13379
+ description: "Timeout in ms. Default: 600000 (10 minutes)."
13380
+ }
13381
+ },
13382
+ required: ["targetPaths"]
13383
+ },
13384
+ async execute(input) {
13385
+ const i = input;
13386
+ if (!i.targetPaths?.length) {
13387
+ return { error: "collab_debug: targetPaths is required and must be non-empty." };
13388
+ }
13389
+ const options = {
13390
+ targetPaths: i.targetPaths,
13391
+ timeoutMs: i.timeoutMs
13392
+ };
13393
+ try {
13394
+ const report = await director.spawnCollab(options);
13395
+ return {
13396
+ sessionId: report.sessionId,
13397
+ overallVerdict: report.overallVerdict,
13398
+ bugCount: report.bugs.length,
13399
+ planCount: report.refactorPlans.length,
13400
+ evaluationCount: report.evaluations.length,
13401
+ summary: report.summary,
13402
+ bugs: report.bugs,
13403
+ refactorPlans: report.refactorPlans,
13404
+ evaluations: report.evaluations
13405
+ };
13406
+ } catch (err) {
13407
+ const msg = err instanceof Error ? err.message : String(err);
13408
+ return { error: "collab_debug failed: " + msg };
13409
+ }
13410
+ }
13411
+ };
13412
+ }
13413
+ function makeFleetEmitTool(director) {
13414
+ return {
13415
+ name: "fleet_emit",
13416
+ description: "Emit a structured event on the FleetBus. Use this when you find a bug (bug.found), complete a refactor plan (refactor.plan), or finish an evaluation (critic.evaluation). Events are routed to other agents in the collab session.",
13417
+ permission: "auto",
13418
+ mutating: false,
13419
+ inputSchema: {
13420
+ type: "object",
13421
+ properties: {
13422
+ type: {
13423
+ type: "string",
13424
+ description: "Event type: bug.found | refactor.plan | critic.evaluation"
13425
+ },
13426
+ payload: {
13427
+ type: "object",
13428
+ description: "Event payload matching the event type."
13429
+ }
13430
+ },
13431
+ required: ["type", "payload"]
13432
+ },
13433
+ async execute(input) {
13434
+ const i = input;
13435
+ director.fleet.emit({
13436
+ subagentId: director.id,
13437
+ ts: Date.now(),
13438
+ type: i.type,
13439
+ payload: i.payload
13440
+ });
13441
+ return { ok: true, event: i.type };
13442
+ }
13443
+ };
13444
+ }
13445
+ var CollabSession = class extends EventEmitter {
13446
+ sessionId;
13447
+ options;
13448
+ snapshot;
13449
+ director;
13450
+ fleetBus;
13451
+ subagentIds = /* @__PURE__ */ new Map();
13452
+ // role → subagentId
13453
+ bugs = /* @__PURE__ */ new Map();
13454
+ plans = /* @__PURE__ */ new Map();
13455
+ evaluations = /* @__PURE__ */ new Map();
13456
+ disposers = new Array();
13457
+ settled = false;
13458
+ timeoutMs;
13459
+ constructor(director, fleetBus, options) {
13460
+ super();
13461
+ this.sessionId = randomUUID();
13462
+ this.options = options;
13463
+ this.director = director;
13464
+ this.fleetBus = fleetBus;
13465
+ this.timeoutMs = options.timeoutMs ?? 10 * 60 * 1e3;
13466
+ if (options.prebuiltSnapshot) {
13467
+ this.snapshot = options.prebuiltSnapshot;
13468
+ } else {
13469
+ this.snapshot = {
13470
+ id: this.sessionId,
13471
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
13472
+ files: []
13473
+ };
13474
+ }
13475
+ }
13476
+ /**
13477
+ * Read the target files from disk and populate the snapshot.
13478
+ * Call this after construction if you did not provide a prebuiltSnapshot
13479
+ * and want the session to operate on real file contents.
13480
+ */
13481
+ async buildSnapshot() {
13482
+ if (this.snapshot.files.length > 0) return this.snapshot;
13483
+ for (const filePath of this.options.targetPaths) {
13484
+ try {
13485
+ const content = await fsp2.readFile(filePath, "utf8");
13486
+ const ext = filePath.split(".").pop() ?? "";
13487
+ const language = ext === "ts" || ext === "tsx" ? "typescript" : ext === "js" || ext === "jsx" ? "javascript" : ext === "md" ? "markdown" : ext === "json" ? "json" : void 0;
13488
+ this.snapshot.files.push({ path: filePath, content, language });
13489
+ } catch {
13490
+ this.snapshot.files.push({ path: filePath, content: "", language: void 0 });
13491
+ }
13492
+ }
13493
+ return this.snapshot;
13494
+ }
13495
+ /**
13496
+ * Start the collaborative session: snapshot files, spawn all three agents,
13497
+ * wire up event routing, and wait for completion.
13498
+ */
13499
+ async start() {
13500
+ if (this.settled) throw new Error("session already settled");
13501
+ this.settled = true;
13502
+ await this.buildSnapshot();
13503
+ this.wireFleetBus();
13504
+ const [bugHunterId, refactorPlannerId, criticId] = await Promise.all([
13505
+ this.spawnAgent("bug-hunter", this.buildBugHunterTask()),
13506
+ this.spawnAgent("refactor-planner", this.buildRefactorPlannerTask()),
13507
+ this.spawnAgent("critic", this.buildCriticTask())
13508
+ ]);
13509
+ this.subagentIds.set("bug-hunter", bugHunterId);
13510
+ this.subagentIds.set("refactor-planner", refactorPlannerId);
13511
+ this.subagentIds.set("critic", criticId);
13512
+ const timeout = new Promise((_, reject) => {
13513
+ setTimeout(
13514
+ () => reject(new Error(`CollabSession timed out after ${this.timeoutMs}ms`)),
13515
+ this.timeoutMs
13516
+ );
13517
+ });
13518
+ let results;
13519
+ try {
13520
+ results = await Promise.race([
13521
+ Promise.all([
13522
+ this.director.awaitTasks([bugHunterId]),
13523
+ this.director.awaitTasks([refactorPlannerId]),
13524
+ this.director.awaitTasks([criticId])
13525
+ ]),
13526
+ timeout
13527
+ ]);
13528
+ } catch (err) {
13529
+ this.cleanup();
13530
+ const error = err instanceof Error ? err : new Error(String(err));
13531
+ this.emit("session.error", error);
13532
+ throw error;
13533
+ }
13534
+ for (const result of results.flat()) {
13535
+ await this.parseAndEmit(result);
13536
+ }
13537
+ const report = this.assembleReport();
13538
+ this.cleanup();
13539
+ this.emit("session.done", report);
13540
+ return report;
13541
+ }
13542
+ /**
13543
+ * Parse a completed agent's final text output and route the structured
13544
+ * findings onto the FleetBus. Agents are instructed to emit one JSON object
13545
+ * per finding / plan / evaluation; we scan the output for balanced JSON
13546
+ * objects (tolerating prose, markdown, and ```json fences around them) and
13547
+ * dispatch each by its discriminating key. The wired FleetBus listeners then
13548
+ * collect them into the bugs / plans / evaluations maps.
13549
+ *
13550
+ * Failed or empty results are ignored, and a single malformed object never
13551
+ * aborts the collation pass — see {@link extractJsonObjects}.
13552
+ */
13553
+ async parseAndEmit(result) {
13554
+ if (result.status !== "success" || result.result == null) return;
13555
+ const text = typeof result.result === "string" ? result.result : JSON.stringify(result.result);
13556
+ for (const obj of this.extractJsonObjects(text)) {
13557
+ const type = "finding" in obj ? "bug.found" : "plan" in obj ? "refactor.plan" : "evaluation" in obj ? "critic.evaluation" : null;
13558
+ if (!type) continue;
13559
+ this.fleetBus.emit({
13560
+ subagentId: result.subagentId,
13561
+ taskId: result.taskId,
13562
+ ts: Date.now(),
13563
+ type,
13564
+ payload: obj
13565
+ });
13566
+ }
13567
+ }
13568
+ /**
13569
+ * Extract every top-level JSON object embedded in free-form agent text.
13570
+ * Scans for balanced braces while respecting string literals and escape
13571
+ * sequences, so prose, markdown headers, and code fences around the JSON
13572
+ * are skipped. Malformed spans are dropped silently rather than thrown.
13573
+ */
13574
+ extractJsonObjects(text) {
13575
+ const objects = [];
13576
+ let depth = 0;
13577
+ let start = -1;
13578
+ let inString = false;
13579
+ let escaped = false;
13580
+ for (let i = 0; i < text.length; i++) {
13581
+ const ch = text[i];
13582
+ if (inString) {
13583
+ if (escaped) escaped = false;
13584
+ else if (ch === "\\") escaped = true;
13585
+ else if (ch === '"') inString = false;
13586
+ continue;
13587
+ }
13588
+ if (ch === '"') {
13589
+ inString = true;
13590
+ } else if (ch === "{") {
13591
+ if (depth === 0) start = i;
13592
+ depth++;
13593
+ } else if (ch === "}" && depth > 0) {
13594
+ depth--;
13595
+ if (depth === 0 && start >= 0) {
13596
+ const candidate = text.slice(start, i + 1);
13597
+ try {
13598
+ const parsed = JSON.parse(candidate);
13599
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
13600
+ objects.push(parsed);
13601
+ }
13602
+ } catch {
13603
+ }
13604
+ start = -1;
13605
+ }
13606
+ }
13607
+ }
13608
+ return objects;
13609
+ }
13610
+ async spawnAgent(role, taskBrief) {
13611
+ const cfg = {
13612
+ id: `${role}-${this.sessionId}`,
13613
+ name: role,
13614
+ role
13615
+ // No fleet_emit tool — agents output structured JSON, the Director parses
13616
+ // results and emits FleetBus events. This keeps the agent simple and the
13617
+ // routing deterministic.
13618
+ };
13619
+ const subagentId = await this.director.spawn(cfg);
13620
+ await this.director.assign({
13621
+ id: randomUUID(),
13622
+ subagentId,
13623
+ description: taskBrief
13624
+ });
13625
+ return subagentId;
13626
+ }
13627
+ buildBugHunterTask() {
13628
+ this.options.targetPaths.join(", ");
13629
+ const scratchpad = this.director.sharedScratchpadPath ?? "/tmp";
13630
+ const fileContents = this.snapshot.files.map((f) => `=== ${f.path} ===
13631
+ ${f.content}`).join("\n\n");
13632
+ return `You are BugHunter. Scan the following files for bugs and code smells.
13633
+
13634
+ Target files:
13635
+ ${fileContents}
13636
+
13637
+ For each bug found, write ONE valid JSON line to the scratchpad with this exact structure:
13638
+ { "finding": { "id": "<uuid>", "type": "<pattern>", "severity": "<critical|high|medium|low>", "location": { "file": "<path>", "line": <n> }, "description": "<explain>", "suggestedFix": "<optional>" } }.
13639
+ After scanning all files, write your full markdown bug report to the shared scratchpad at:
13640
+ ${scratchpad}/bug-hunter-report-${this.sessionId}.md`;
13641
+ }
13642
+ buildRefactorPlannerTask() {
13643
+ const scratchpad = this.director.sharedScratchpadPath ?? "/tmp";
13644
+ const fileContents = this.snapshot.files.map((f) => `=== ${f.path} ===
13645
+ ${f.content}`).join("\n\n");
13646
+ return `You are RefactorPlanner. Plan refactorings for the following files.
13647
+
13648
+ Target files:
13649
+ ${fileContents}
13650
+
13651
+ Listen for bug.found events from BugHunter on the fleet bus. For each bug, create a refactor plan and write one JSON line per plan:
13652
+ { "plan": { "id": "<uuid>", "basedOnBugIds": ["<bug-id>"], "phases": [...], "riskScore": "<low|medium|high>", "estimatedChangeCount": <n>, "rollbackStrategy": "<text>" } }.
13653
+ After planning, write your full markdown plan to:
13654
+ ${scratchpad}/refactor-plan-${this.sessionId}.md`;
13655
+ }
13656
+ buildCriticTask() {
13657
+ const scratchpad = this.director.sharedScratchpadPath ?? "/tmp";
13658
+ const fileContents = this.snapshot.files.map((f) => `=== ${f.path} ===
13659
+ ${f.content}`).join("\n\n");
13660
+ return `You are Critic. Evaluate bug findings and refactor plans as they arrive via fleet bus events.
13661
+
13662
+ Target files:
13663
+ ${fileContents}
13664
+
13665
+ Subscribe to bug.found events (from BugHunter) and refactor.plan events (from RefactorPlanner). For each subject, write one JSON line per evaluation:
13666
+ { "evaluation": { "id": "<uuid>", "subjectType": "<bug_finding|refactor_plan>", "subjectId": "<id>", "score": <0-10>, "verdict": "<approve|needs_revision|reject>", "strengths": [...], "weaknesses": [...], "concerns": [...] } }.
13667
+ After all evaluations, write your markdown critic report to:
13668
+ ${scratchpad}/critic-report-${this.sessionId}.md`;
13669
+ }
13670
+ wireFleetBus() {
13671
+ const d1 = this.fleetBus.filter("bug.found", (e) => {
13672
+ const payload = e.payload;
13673
+ if (payload?.finding) {
13674
+ this.bugs.set(payload.finding.id, payload.finding);
13675
+ this.emit("bug.found", payload);
13676
+ }
13677
+ });
13678
+ this.disposers.push(d1);
13679
+ const d2 = this.fleetBus.filter("refactor.plan", (e) => {
13680
+ const payload = e.payload;
13681
+ if (payload?.plan) {
13682
+ this.plans.set(payload.plan.id, payload.plan);
13683
+ this.emit("refactor.plan", payload);
13684
+ }
13685
+ });
13686
+ this.disposers.push(d2);
13687
+ const d3 = this.fleetBus.filter("critic.evaluation", (e) => {
13688
+ const payload = e.payload;
13689
+ if (payload?.evaluation) {
13690
+ this.evaluations.set(payload.evaluation.id, payload.evaluation);
13691
+ this.emit("critic.evaluation", payload);
13692
+ }
13693
+ });
13694
+ this.disposers.push(d3);
13695
+ }
13696
+ assembleReport() {
13697
+ const bugList = Array.from(this.bugs.values());
13698
+ const planList = Array.from(this.plans.values());
13699
+ const evalList = Array.from(this.evaluations.values());
13700
+ const verdictOrder = {
13701
+ approve: 0,
13702
+ needs_revision: 1,
13703
+ reject: 2
13704
+ };
13705
+ const overallVerdict = evalList.reduce(
13706
+ (worst, eval_) => {
13707
+ const w = verdictOrder[worst];
13708
+ const c = verdictOrder[eval_.verdict];
13709
+ return c > w ? eval_.verdict : worst;
13710
+ },
13711
+ "approve"
13712
+ );
13713
+ const summary = this.buildMarkdownSummary(bugList, planList, evalList, overallVerdict);
13714
+ return {
13715
+ sessionId: this.sessionId,
13716
+ startedAt: this.snapshot.createdAt,
13717
+ completedAt: (/* @__PURE__ */ new Date()).toISOString(),
13718
+ targetPaths: this.options.targetPaths,
13719
+ bugs: bugList,
13720
+ refactorPlans: planList,
13721
+ evaluations: evalList,
13722
+ overallVerdict,
13723
+ summary
13724
+ };
13725
+ }
13726
+ buildMarkdownSummary(bugs, plans, evals, overallVerdict) {
13727
+ const lines = [
13728
+ `## Collaborative Debugging Report \u2014 ${this.sessionId}`,
13729
+ "",
13730
+ `**Target:** ${this.options.targetPaths.join(", ")}`,
13731
+ `**Overall Verdict:** **${overallVerdict.toUpperCase()}**`,
13732
+ ""
13733
+ ];
13734
+ if (bugs.length > 0) {
13735
+ lines.push("### Bugs Found", "");
13736
+ for (const b of bugs) {
13737
+ lines.push(
13738
+ `- **[${b.severity.toUpperCase()}]** \`${b.location.file}:${b.location.line}\` \u2014 ${b.description}`
13739
+ );
13740
+ }
13741
+ lines.push("");
13742
+ }
13743
+ if (plans.length > 0) {
13744
+ lines.push("### Refactor Plans", "");
13745
+ for (const p of plans) {
13746
+ lines.push(`- **Phase plan** (risk: ${p.riskScore}, ~${p.estimatedChangeCount} changes)`);
13747
+ for (const phase of p.phases) {
13748
+ lines.push(` - Phase ${phase.number}: ${phase.title} [${phase.risk}]`);
13749
+ }
13750
+ }
13751
+ lines.push("");
13752
+ }
13753
+ if (evals.length > 0) {
13754
+ lines.push("### Critic Evaluations", "");
13755
+ for (const e of evals) {
13756
+ lines.push(`- [${e.subjectType}] score=${e.score}/10 \u2014 **${e.verdict.toUpperCase()}**`);
13757
+ for (const c of e.concerns) {
13758
+ if (c.severity === "blocking") {
13759
+ lines.push(` - ${c.description}`);
13760
+ }
13761
+ }
13762
+ }
13763
+ lines.push("");
13764
+ }
13765
+ return lines.join("\n");
13766
+ }
13767
+ cleanup() {
13768
+ for (const dispose of this.disposers) dispose();
13769
+ this.disposers.length = 0;
13770
+ }
13771
+ };
13044
13772
 
13045
13773
  // src/coordination/director.ts
13046
13774
  var FleetSpawnBudgetError = class extends Error {
@@ -13119,6 +13847,8 @@ var Director = class {
13119
13847
  subagentBridges = /* @__PURE__ */ new Map();
13120
13848
  /** Tracks per-spawn config + assigned task ids for manifest writing. */
13121
13849
  manifestEntries = /* @__PURE__ */ new Map();
13850
+ /** Tracks assigned nicknames so the same name is never reused in one fleet. */
13851
+ _usedNicknames = /* @__PURE__ */ new Set();
13122
13852
  manifestPath;
13123
13853
  roster;
13124
13854
  directorPreamble;
@@ -13412,9 +14142,21 @@ var Director = class {
13412
14142
  }
13413
14143
  }
13414
14144
  let result;
14145
+ const needsNickname = config.name === config.role || !config.name || config.name === "subagent";
14146
+ if (needsNickname) {
14147
+ const role = config.role ?? "subagent";
14148
+ if (this.fleetManager) {
14149
+ this.fleetManager.assignNicknameAndRecord("", config, priceLookup);
14150
+ } else {
14151
+ config.name = assignNickname(role, this._usedNicknames);
14152
+ this._usedNicknames.add(config.name.split(" ")[0].toLowerCase().replace(/[^a-z0-9-]/g, "-"));
14153
+ }
14154
+ }
13415
14155
  result = await this.coordinator.spawn(config);
13416
14156
  if (this.fleetManager) {
13417
- this.fleetManager.recordSpawn(result.subagentId, config, priceLookup);
14157
+ if (!needsNickname) {
14158
+ this.fleetManager.recordSpawn(result.subagentId, config, priceLookup);
14159
+ }
13418
14160
  } else {
13419
14161
  this.spawnCount += 1;
13420
14162
  this.subagentMeta.set(result.subagentId, {
@@ -13850,7 +14592,9 @@ var Director = class {
13850
14592
  makeFleetStatusTool(this),
13851
14593
  makeFleetUsageTool(this),
13852
14594
  makeFleetSessionTool(this),
13853
- makeFleetHealthTool(this)
14595
+ makeFleetHealthTool(this),
14596
+ makeCollabDebugTool(this),
14597
+ makeFleetEmitTool(this)
13854
14598
  ];
13855
14599
  return t2;
13856
14600
  }
@@ -13862,6 +14606,17 @@ var Director = class {
13862
14606
  async acquireCheckpointLock() {
13863
14607
  return this.stateCheckpoint ? this.stateCheckpoint.acquireLock() : true;
13864
14608
  }
14609
+ /**
14610
+ * Start a collaborative debugging session: BugHunter, RefactorPlanner,
14611
+ * and Critic run in parallel on the same target files, with findings
14612
+ * flowing through the FleetBus (bug.found → refactor.plan →
14613
+ * critic.evaluation). Returns a structured CollabDebugReport when all
14614
+ * three agents complete or the session times out.
14615
+ */
14616
+ async spawnCollab(options) {
14617
+ const session = new CollabSession(this, this.fleet, options);
14618
+ return session.start();
14619
+ }
13865
14620
  /**
13866
14621
  * Resume from a prior checkpoint snapshot (loaded via
13867
14622
  * `loadDirectorState()`). Re-attach to the fleet mid-flight so
@@ -15623,10 +16378,10 @@ var AISpecBuilder = class {
15623
16378
  async saveSession() {
15624
16379
  if (!this.sessionPath) return;
15625
16380
  try {
15626
- const fsp18 = await import('fs/promises');
16381
+ const fsp19 = await import('fs/promises');
15627
16382
  const path31 = await import('path');
15628
16383
  const { atomicWrite: atomicWrite2 } = await Promise.resolve().then(() => (init_atomic_write(), atomic_write_exports));
15629
- await fsp18.mkdir(path31.dirname(this.sessionPath), { recursive: true });
16384
+ await fsp19.mkdir(path31.dirname(this.sessionPath), { recursive: true });
15630
16385
  await atomicWrite2(this.sessionPath, JSON.stringify(this.session, null, 2));
15631
16386
  } catch {
15632
16387
  }
@@ -15635,8 +16390,8 @@ var AISpecBuilder = class {
15635
16390
  async loadSession() {
15636
16391
  if (!this.sessionPath) return false;
15637
16392
  try {
15638
- const fsp18 = await import('fs/promises');
15639
- const raw = await fsp18.readFile(this.sessionPath, "utf8");
16393
+ const fsp19 = await import('fs/promises');
16394
+ const raw = await fsp19.readFile(this.sessionPath, "utf8");
15640
16395
  const loaded = JSON.parse(raw);
15641
16396
  if (loaded?.id && loaded?.phase && loaded?.title) {
15642
16397
  this.session = loaded;
@@ -15650,8 +16405,8 @@ var AISpecBuilder = class {
15650
16405
  async deleteSession() {
15651
16406
  if (!this.sessionPath) return;
15652
16407
  try {
15653
- const fsp18 = await import('fs/promises');
15654
- await fsp18.unlink(this.sessionPath);
16408
+ const fsp19 = await import('fs/promises');
16409
+ await fsp19.unlink(this.sessionPath);
15655
16410
  } catch {
15656
16411
  }
15657
16412
  }
@@ -18785,7 +19540,25 @@ var CloudSync = class {
18785
19540
  baseTreeSha,
18786
19541
  `Sync ${cfg.categories.join(", ")} \u2014 ${(/* @__PURE__ */ new Date()).toISOString()}`
18787
19542
  );
18788
- await this.updateRef(token, owner, repoName, branch, commitSha);
19543
+ try {
19544
+ await this.updateRef(token, owner, repoName, branch, commitSha);
19545
+ } catch (err) {
19546
+ if (err instanceof Error && err.message.includes("422")) {
19547
+ const remote = await this.getRef(token, owner, repoName, branch);
19548
+ const currentSha = remote.object.sha;
19549
+ const rebasedCommitSha = await this.createCommit(
19550
+ token,
19551
+ owner,
19552
+ repoName,
19553
+ newTreeSha,
19554
+ currentSha,
19555
+ `Sync ${cfg.categories.join(", ")} \u2014 ${(/* @__PURE__ */ new Date()).toISOString()}`
19556
+ );
19557
+ await this.updateRef(token, owner, repoName, branch, rebasedCommitSha);
19558
+ } else {
19559
+ throw err;
19560
+ }
19561
+ }
18789
19562
  const syncState = {
18790
19563
  version: 1,
18791
19564
  sha: commitSha,
@@ -20806,16 +21579,16 @@ Use \`/security report <number>\` to view a specific report.` };
20806
21579
  }
20807
21580
  const index = Number.parseInt(reportId, 10) - 1;
20808
21581
  if (!Number.isNaN(index) && reports[index]) {
20809
- const { readFile: readFile34 } = await import('fs/promises');
20810
- const content = await readFile34(join(reportsDir, reports[index]), "utf-8");
21582
+ const { readFile: readFile35 } = await import('fs/promises');
21583
+ const content = await readFile35(join(reportsDir, reports[index]), "utf-8");
20811
21584
  return { message: `# Security Report
20812
21585
 
20813
21586
  ${content}` };
20814
21587
  }
20815
21588
  const match = reports.find((r) => r.includes(reportId));
20816
21589
  if (match) {
20817
- const { readFile: readFile34 } = await import('fs/promises');
20818
- const content = await readFile34(join(reportsDir, match), "utf-8");
21590
+ const { readFile: readFile35 } = await import('fs/promises');
21591
+ const content = await readFile35(join(reportsDir, match), "utf-8");
20819
21592
  return { message: `# Security Report
20820
21593
 
20821
21594
  ${content}` };
@@ -20898,6 +21671,8 @@ var FleetManager = class {
20898
21671
  pendingTasks = /* @__PURE__ */ new Map();
20899
21672
  subagentMeta = /* @__PURE__ */ new Map();
20900
21673
  priceLookups = /* @__PURE__ */ new Map();
21674
+ /** Tracks which nickname keys are already assigned — prevents collisions. */
21675
+ _usedNicknames = /* @__PURE__ */ new Set();
20901
21676
  /** The coordinator (wired via setCoordinator by Director after construction). */
20902
21677
  coordinator = null;
20903
21678
  constructor(opts = {}) {
@@ -20978,6 +21753,30 @@ var FleetManager = class {
20978
21753
  }
20979
21754
  return null;
20980
21755
  }
21756
+ /**
21757
+ * Assign a memorable nickname (e.g. "Einstein (Bug Hunter)") to the config,
21758
+ * record it so the same name is never reused, then record the spawn.
21759
+ *
21760
+ * Call this INSTEAD of `recordSpawn` when you want automatic nicknames.
21761
+ * The nickname is written back to `config.name` BEFORE the coordinator
21762
+ * sees the config, so the manifest, logs, and fleet UI all show it.
21763
+ */
21764
+ assignNicknameAndRecord(subagentId, config, priceLookup) {
21765
+ const role = config.role ?? "subagent";
21766
+ const nickname = assignNickname(role, this._usedNicknames);
21767
+ const baseKey = nickname.split(" ")[0].toLowerCase().replace(/[^a-z0-9-]/g, "-");
21768
+ this._usedNicknames.add(baseKey);
21769
+ config.name = nickname;
21770
+ this.recordSpawn(subagentId, config, priceLookup);
21771
+ return nickname;
21772
+ }
21773
+ /**
21774
+ * Returns the set of already-assigned nickname keys — useful for debugging
21775
+ * and testing.
21776
+ */
21777
+ get usedNicknames() {
21778
+ return this._usedNicknames;
21779
+ }
20981
21780
  /**
20982
21781
  * Records a spawn: increments counter, stores metadata, updates state checkpoint,
20983
21782
  * and schedules a debounced manifest write. Call AFTER the coordinator
@@ -23391,10 +24190,28 @@ var DefaultPluginAPI = class {
23391
24190
  }
23392
24191
  this.pipelines = readonlyPipelines;
23393
24192
  const tr = init.toolRegistry;
24193
+ const isOfficial = init.official === true;
24194
+ const assertCanMutateTool = (name, op) => {
24195
+ if (isOfficial) return;
24196
+ const currentOwner = tr.ownerOf(name);
24197
+ if (currentOwner === void 0) return;
24198
+ const ownedSolelyByMe = currentOwner.split("+").every((seg) => seg === owner);
24199
+ if (!ownedSolelyByMe) {
24200
+ throw new Error(
24201
+ `Plugin "${owner}" may not ${op} tool "${name}" \u2014 it is owned by "${currentOwner}". Only official (first-party) plugins may modify tools they do not own.`
24202
+ );
24203
+ }
24204
+ };
23394
24205
  this.tools = {
23395
24206
  register: (t2) => tr.register(t2, owner),
23396
- unregister: (name) => tr.unregister(name),
23397
- wrap: (name, wrapper) => tr.wrap(name, wrapper, owner),
24207
+ unregister: (name) => {
24208
+ assertCanMutateTool(name, "unregister");
24209
+ return tr.unregister(name);
24210
+ },
24211
+ wrap: (name, wrapper) => {
24212
+ assertCanMutateTool(name, "wrap");
24213
+ tr.wrap(name, wrapper, owner);
24214
+ },
23398
24215
  get: (name) => tr.get(name),
23399
24216
  list: () => tr.list()
23400
24217
  };
@@ -25442,9 +26259,12 @@ function dim2(s) {
25442
26259
  }
25443
26260
 
25444
26261
  // src/plugins/sync-plugin.ts
26262
+ init_atomic_write();
25445
26263
  function createSyncPlugin(opts) {
25446
26264
  let cloud = null;
25447
26265
  let configStore;
26266
+ let vault;
26267
+ let syncConfigPath;
25448
26268
  return {
25449
26269
  name: "wstack-sync",
25450
26270
  version: "1.0.0",
@@ -25456,6 +26276,8 @@ function createSyncPlugin(opts) {
25456
26276
  const rawConfig = api.config;
25457
26277
  const paths = opts?.paths ?? rawConfig.paths;
25458
26278
  configStore = opts?.configStore ?? rawConfig.configStore;
26279
+ vault = opts?.vault ?? rawConfig.vault;
26280
+ syncConfigPath = paths?.syncConfig;
25459
26281
  if (!paths || !configStore) {
25460
26282
  api.log.warn("[sync] paths or configStore not available \u2014 /sync disabled");
25461
26283
  return;
@@ -25471,7 +26293,7 @@ function createSyncPlugin(opts) {
25471
26293
  }
25472
26294
  );
25473
26295
  void cloud.loadState();
25474
- api.slashCommands.register(buildSyncCommand(cloud, configStore));
26296
+ api.slashCommands.register(buildSyncCommand(cloud, configStore, vault, syncConfigPath));
25475
26297
  api.log.info("[sync] loaded \u2014 /sync available. Run /sync to get started.");
25476
26298
  },
25477
26299
  teardown(api) {
@@ -25483,7 +26305,7 @@ function createSyncPlugin(opts) {
25483
26305
  }
25484
26306
  };
25485
26307
  }
25486
- function buildSyncCommand(cloud, configStore) {
26308
+ function buildSyncCommand(cloud, configStore, vault, syncConfigPath) {
25487
26309
  return {
25488
26310
  name: "sync",
25489
26311
  description: "Cloud sync: /sync [status|enable|disable|push|pull|categories]",
@@ -25511,13 +26333,17 @@ function buildSyncCommand(cloud, configStore) {
25511
26333
  if (!repo || !repo.includes("/")) {
25512
26334
  return { message: 'Invalid repo format. Expected "owner/repo".' };
25513
26335
  }
26336
+ const storedToken = vault ? vault.encrypt(token) : token;
25514
26337
  const syncConfig = {
25515
26338
  enabled: true,
25516
26339
  repo,
25517
- githubToken: token,
26340
+ githubToken: storedToken,
25518
26341
  categories: cats.length > 0 ? cats : ALL_SYNC_CATEGORIES,
25519
26342
  lastSyncedAt: void 0
25520
26343
  };
26344
+ if (syncConfigPath) {
26345
+ await atomicWrite(syncConfigPath, JSON.stringify(syncConfig, null, 2), { mode: 384 });
26346
+ }
25521
26347
  configStore.update({ sync: syncConfig });
25522
26348
  await cloud.loadState();
25523
26349
  return {
@@ -26344,6 +27170,6 @@ ${formatPlan(updated)}`
26344
27170
  };
26345
27171
  }
26346
27172
 
26347
- export { AGENTS_BY_PHASE, AGENT_CATALOG, AISpecBuilder, ALL_AGENT_DEFINITIONS, ALL_FLEET_AGENTS, ALL_SYNC_CATEGORIES, AUDIT_LOG_AGENT, Agent, AgentError, AutoApprovePermissionPolicy, AutoCompactionMiddleware, AutoExecutor, AutoPhasePlanner, AutoPhaseRunner, AutonomousRunner, BUG_HUNTER_AGENT, BudgetExceededError, CONTEXT_WINDOW_MODES, CheckpointManager, CloudSync, ConfigError, ConfigMigrationError, Container, Context, ConversationState, DEFAULT_AUTONOMY_CONFIG, DEFAULT_CONFIG_MIGRATIONS, DEFAULT_CONTEXT_CONFIG, DEFAULT_CONTEXT_WINDOW_MODE_ID, DEFAULT_DIRECTOR_PREAMBLE, DEFAULT_DISPATCH_ROLE, DEFAULT_MAX_ITERATIONS, DEFAULT_MODES, DEFAULT_RECOVERY_STRATEGIES, DEFAULT_SPEC_TEMPLATE, DEFAULT_SUBAGENT_BASELINE, DEFAULT_TOOLS_CONFIG, DefaultAttachmentStore, DefaultConfigLoader, DefaultConfigStore, DefaultErrorHandler, DefaultHealthRegistry, DefaultLogger, DefaultMemoryStore, DefaultModeStore, DefaultModelsRegistry, DefaultMultiAgentCoordinator, DefaultPathResolver, DefaultPermissionPolicy, DefaultPluginAPI, DefaultPromptStore, DefaultProviderRunner, DefaultRetryPolicy, DefaultSecretScrubber, DefaultSecretVault, DefaultSessionReader, DefaultSessionRewinder, DefaultSessionStore, DefaultSkillLoader, DefaultSystemPromptBuilder, DefaultTaskStore, DefaultTokenCounter, Director, DirectorStateCheckpoint, DoneConditionChecker, ERROR_CODES, EternalAutonomyEngine, EventBus, ExtensionRegistry, FLEET_ROSTER, FLEET_ROSTER_BUDGETS, FleetBus, FleetManager, FleetSpawnBudgetError, FleetUsageAggregator, FsError, GitignoreUpdater, HybridCompactor, InMemoryAgentBridge, InMemoryBridgeTransport, InMemoryMetricsSink, InputBuilder, IntelligentCompactor, KERNEL_API_VERSION, LAYER_1_IDENTITY, LLMSelector, MAX_JOURNAL_ENTRIES, NULL_FLEET_BUS, NoopMetricsSink, NoopTracer, OTelTracer, PROMETHEUS_CONTENT_TYPE, ParallelEternalEngine, PhaseGraphBuilder, PhaseOrchestrator, PhaseStore, Pipeline, PluginError, ProviderError, ProviderRegistry, QueueStore, REFACTOR_PLANNER_AGENT, RecoveryLock, ReportGenerator, RunController, SECURITY_SCANNER_AGENT, SPEC_TEMPLATES, ScopedEventBus, SddParallelRun, SddTaskDecomposer, SecurityScanner, SecurityScannerOrchestrator, SelectiveCompactor, SessionAnalyzer, SessionError, SkillGenerator, SkillInstaller, SkillManifestStore, SlashCommandRegistry, SpecDrivenDev, SpecParser, SpecStore, SpecVersioning, SubagentBudget, TOKENS, TaskFlow, TaskGenerator, TaskGraphStore, TaskTracker, TechStackDetector, ToolError, ToolExecutor, ToolRegistry, WorktreeManager, WrongStackError, addPlanItem, allServers, analyzeCriticalPath, appendJournal, applyRosterBudget, asBlocks, asText, assertSafePath, atomicWrite, attachAutoExtend, attachPlanCheckpoint, attachTodosCheckpoint, awsServer, blockServer, braveSearchServer, buildBtwBlock, buildChildEnv, buildGoalPreamble, buildOtlpMetricsRequest, buildOtlpTracesRequest, buildRecoveryStrategies, classifyFamily, clearPlan, color, compileGlob, compileUserRegex, composeDirectorPrompt, composeSubagentPrompt, computeTaskProgress, consumeBtwNotes, context7Server, contextManagerTool, createAutoExecutor, createAutoPhaseFromTaskGraph, createContextManagerTool, createDefaultPipelines, createDelegateTool, createGitPlugin, createMcpControlTool, createMessage, createObservabilityPlugin, createPlanPlugin, createPromptsPlugin, createSecurityPlugin, createSecuritySlashCommand, createSkillsPlugin, createSyncPlugin, createToolOutputSerializer, decryptConfigSecrets, defaultGitignoreUpdater, defaultOrchestrator, defaultReportGenerator, defaultSecurityScanner, defaultSkillGenerator, defaultTechStackDetector, deriveTodosFromPlanItem, detectNewlineStyle, dispatchAgent, downloadGitHubTarball, emptyGoal, emptyPlan, encryptConfigSecrets, ensureDir, estimateRequestTokens, estimateTextTokens, estimateToolDefTokens, estimateToolInputTokens, estimateToolResultTokens, everArtServer, extractRunEnv, filesystemServer, findCriticalPath, formatContextWindowModeList, formatGoal, formatPlan, formatPlanTemplates, formatTodosList, getAgentDefinition, getContextWindowMode, getPlanTemplate, getTemplate, githubServer, goalFilePath, googleMapsServer, isAgentError, isConfigError, isContextWindowModeId, isFsError, isImageBlock, isPluginError, isSessionError, isTextBlock, isThinkingBlock, isToolError, isToolResultBlock, isToolUseBlock, isWrongStackError, listContextWindowModes, listPlanTemplates, listTemplates, loadDirectorState, loadGoal, loadPlan, loadPlugins, loadProjectModes, loadTodosCheckpoint, loadUserModes, makeAgentSubagentRunner, makeAutonomyPromptContributor, makeContinueToNextIterationTool, makeDirectorSessionFactory, makeLLMClassifier, matchAny, matchGlob, migratePlaintextSecrets, miniMaxVisionServer, normalizeToLf, parseContinueDirective, parseSkillRef, pendingBtwCount, projectHash, removePlanItem, renderProgress, renderPrometheus, renderSpecAnalysis, renderTaskGraph, renderTaskList, repairToolUseAdjacency, resolveContextWindowPolicy, resolveWstackPaths, rewriteConfigEncrypted, rosterSummaryFromConfigs, runConfigMigrations, safeParse, safeStringify, sanitizeJsonString, saveGoal, savePlan, saveTodosCheckpoint, scoreAgents, securitySlashCommand, sentinelServer, setBtwNote, setPlanItemStatus, slackServer, startMetricsServer, startOtlpMetricsExporter, startOtlpTraceExporter, stripAnsi, summarizeUsage, templateToMarkdown, toStyle, toWrongStackError, topologicalSort, unifiedDiff, unloadPlugins, validateAgainstSchema, wireMetricsToEvents, wrapAsState, zaiVisionServer };
27173
+ export { ACP_AGENTS, AGENTS_BY_PHASE, AGENT_CATALOG, AISpecBuilder, ALL_AGENT_DEFINITIONS, ALL_FLEET_AGENTS, ALL_SYNC_CATEGORIES, AUDIT_LOG_AGENT, Agent, AgentError, AutoApprovePermissionPolicy, AutoCompactionMiddleware, AutoExecutor, AutoPhasePlanner, AutoPhaseRunner, AutonomousRunner, BUG_HUNTER_AGENT, BudgetExceededError, CONTEXT_WINDOW_MODES, CheckpointManager, CloudSync, ConfigError, ConfigMigrationError, Container, Context, ConversationState, DEFAULT_AUTONOMY_CONFIG, DEFAULT_CONFIG_MIGRATIONS, DEFAULT_CONTEXT_CONFIG, DEFAULT_CONTEXT_WINDOW_MODE_ID, DEFAULT_DIRECTOR_PREAMBLE, DEFAULT_DISPATCH_ROLE, DEFAULT_MAX_ITERATIONS, DEFAULT_MODES, DEFAULT_RECOVERY_STRATEGIES, DEFAULT_SPEC_TEMPLATE, DEFAULT_SUBAGENT_BASELINE, DEFAULT_TOOLS_CONFIG, DefaultAttachmentStore, DefaultConfigLoader, DefaultConfigStore, DefaultErrorHandler, DefaultHealthRegistry, DefaultLogger, DefaultMemoryStore, DefaultModeStore, DefaultModelsRegistry, DefaultMultiAgentCoordinator, DefaultPathResolver, DefaultPermissionPolicy, DefaultPluginAPI, DefaultPromptStore, DefaultProviderRunner, DefaultRetryPolicy, DefaultSecretScrubber, DefaultSecretVault, DefaultSessionReader, DefaultSessionRewinder, DefaultSessionStore, DefaultSkillLoader, DefaultSystemPromptBuilder, DefaultTaskStore, DefaultTokenCounter, Director, DirectorStateCheckpoint, DoneConditionChecker, ERROR_CODES, EternalAutonomyEngine, EventBus, ExtensionRegistry, FLEET_ROSTER, FLEET_ROSTER_BUDGETS, FLEET_ROSTER_WITHACP, FleetBus, FleetCostCapError, FleetManager, FleetSpawnBudgetError, FleetUsageAggregator, FsError, GitignoreUpdater, HybridCompactor, InMemoryAgentBridge, InMemoryBridgeTransport, InMemoryMetricsSink, InputBuilder, IntelligentCompactor, KERNEL_API_VERSION, LAYER_1_IDENTITY, LLMSelector, MAX_JOURNAL_ENTRIES, NULL_FLEET_BUS, NoopMetricsSink, NoopTracer, OTelTracer, PROMETHEUS_CONTENT_TYPE, ParallelEternalEngine, PhaseGraphBuilder, PhaseOrchestrator, PhaseStore, Pipeline, PluginError, ProviderError, ProviderRegistry, QueueStore, REFACTOR_PLANNER_AGENT, RecoveryLock, ReportGenerator, RunController, SECURITY_SCANNER_AGENT, SPEC_TEMPLATES, ScopedEventBus, SddParallelRun, SddTaskDecomposer, SecurityScanner, SecurityScannerOrchestrator, SelectiveCompactor, SessionAnalyzer, SessionError, SkillGenerator, SkillInstaller, SkillManifestStore, SlashCommandRegistry, SpecDrivenDev, SpecParser, SpecStore, SpecVersioning, SubagentBudget, TOKENS, TaskFlow, TaskGenerator, TaskGraphStore, TaskTracker, TechStackDetector, ToolError, ToolExecutor, ToolRegistry, WorktreeManager, WrongStackError, addPlanItem, allServers, analyzeCriticalPath, appendJournal, applyRosterBudget, asBlocks, asText, assertSafePath, atomicWrite, attachAutoExtend, attachPlanCheckpoint, attachTodosCheckpoint, awsServer, blockServer, braveSearchServer, buildBtwBlock, buildChildEnv, buildGoalPreamble, buildOtlpMetricsRequest, buildOtlpTracesRequest, buildRecoveryStrategies, classifyFamily, clearPlan, color, compileGlob, compileUserRegex, completePartialObject, composeDirectorPrompt, composeSubagentPrompt, computeTaskProgress, consumeBtwNotes, context7Server, contextManagerTool, createAutoExecutor, createAutoPhaseFromTaskGraph, createContextManagerTool, createDefaultPipelines, createDelegateTool, createGitPlugin, createMcpControlTool, createMessage, createObservabilityPlugin, createPlanPlugin, createPromptsPlugin, createSecurityPlugin, createSecuritySlashCommand, createSkillsPlugin, createSyncPlugin, createToolOutputSerializer, decryptConfigSecrets, defaultGitignoreUpdater, defaultOrchestrator, defaultReportGenerator, defaultSecurityScanner, defaultSkillGenerator, defaultTechStackDetector, deriveTodosFromPlanItem, detectNewlineStyle, dispatchAgent, downloadGitHubTarball, emptyGoal, emptyPlan, encryptConfigSecrets, ensureDir, estimateRequestTokens, estimateTextTokens, estimateToolDefTokens, estimateToolInputTokens, estimateToolResultTokens, everArtServer, extractRunEnv, filesystemServer, findCriticalPath, formatContextWindowModeList, formatGoal, formatPlan, formatPlanTemplates, formatTodosList, getAgentDefinition, getContextWindowMode, getPlanTemplate, getTemplate, githubServer, goalFilePath, googleMapsServer, isAgentError, isConfigError, isContextWindowModeId, isFsError, isImageBlock, isPluginError, isSessionError, isTextBlock, isThinkingBlock, isToolError, isToolResultBlock, isToolUseBlock, isWrongStackError, listContextWindowModes, listPlanTemplates, listTemplates, loadDirectorState, loadGoal, loadPlan, loadPlugins, loadProjectModes, loadTodosCheckpoint, loadUserModes, makeAgentSubagentRunner, makeAskTool, makeAssignTool, makeAutonomyPromptContributor, makeAwaitTasksTool, makeCollabDebugTool, makeContinueToNextIterationTool, makeDirectorSessionFactory, makeFleetEmitTool, makeFleetHealthTool, makeFleetSessionTool, makeFleetStatusTool, makeFleetUsageTool, makeLLMClassifier, makeRollUpTool, makeSpawnTool, makeTerminateTool, matchAny, matchGlob, migratePlaintextSecrets, miniMaxVisionServer, normalizeToLf, parseContinueDirective, parseSkillRef, pendingBtwCount, projectHash, removePlanItem, renderProgress, renderPrometheus, renderSpecAnalysis, renderTaskGraph, renderTaskList, repairToolUseAdjacency, resolveContextWindowPolicy, resolveWstackPaths, rewriteConfigEncrypted, rosterSummaryFromConfigs, runConfigMigrations, safeParse, safeStringify, sanitizeJsonString, saveGoal, savePlan, saveTodosCheckpoint, scoreAgents, securitySlashCommand, sentinelServer, setBtwNote, setPlanItemStatus, slackServer, startMetricsServer, startOtlpMetricsExporter, startOtlpTraceExporter, stripAnsi, summarizeUsage, templateToMarkdown, toStyle, toWrongStackError, topologicalSort, unifiedDiff, unloadPlugins, validateAgainstSchema, wireMetricsToEvents, wrapAsState, zaiVisionServer };
26348
27174
  //# sourceMappingURL=index.js.map
26349
27175
  //# sourceMappingURL=index.js.map