opencode-swarm 7.114.7 → 7.114.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.
Files changed (50) hide show
  1. package/.opencode/skills/ci-fix-monitor/SKILL.md +8 -13
  2. package/.opencode/skills/commit-pr/SKILL.md +4 -0
  3. package/.opencode/skills/engineering-conventions/SKILL.md +33 -0
  4. package/.opencode/skills/execute/SKILL.md +2 -0
  5. package/.opencode/skills/swarm-ci-monitor/SKILL.md +5 -0
  6. package/.opencode/skills/swarm-pr-feedback/SKILL.md +2 -0
  7. package/.opencode/skills/writing-tests/SKILL.md +2 -0
  8. package/README.md +16 -14
  9. package/dist/agents/template.d.ts +40 -20
  10. package/dist/cli/{curator-qshyr2tc.js → curator-5xt89z05.js} +7 -7
  11. package/dist/cli/{curator-llm-factory-2xgznxyw.js → curator-llm-factory-pnhvf3s3.js} +7 -7
  12. package/dist/cli/{evidence-summary-service-8g594znj.js → evidence-summary-service-fehwj116.js} +1 -1
  13. package/dist/cli/{guardrail-explain-4t8fnysh.js → guardrail-explain-7aztgtyh.js} +8 -8
  14. package/dist/cli/{hive-promoter-5ngbmnrw.js → hive-promoter-q899q2m6.js} +7 -7
  15. package/dist/cli/{index-z01r5483.js → index-54sevh81.js} +8 -8
  16. package/dist/cli/{index-7stsmndb.js → index-6f6y2rbp.js} +3 -3
  17. package/dist/cli/{index-kjbfry6m.js → index-8f2270hc.js} +1 -1
  18. package/dist/cli/{index-gmjrwz34.js → index-m9m7p49w.js} +1 -1
  19. package/dist/cli/{index-qrnhvhmg.js → index-n18yy0z1.js} +26 -2
  20. package/dist/cli/{index-91qesget.js → index-rk6qhyng.js} +2 -2
  21. package/dist/cli/{index-6ctejje2.js → index-typ408f4.js} +710 -630
  22. package/dist/cli/{index-vjvdvjd3.js → index-x12hvfpf.js} +3 -3
  23. package/dist/cli/{index-f6y341yk.js → index-yrrqs4b0.js} +82 -21
  24. package/dist/cli/index.d.ts +34 -0
  25. package/dist/cli/index.js +105 -28
  26. package/dist/cli/{knowledge-escalator-qn7ew687.js → knowledge-escalator-5gwp1ar8.js} +3 -3
  27. package/dist/cli/{knowledge-events-k2xsz5bh.js → knowledge-events-m304swh6.js} +1 -1
  28. package/dist/cli/{knowledge-store-ksa1dr2z.js → knowledge-store-9babt8rd.js} +1 -1
  29. package/dist/cli/{knowledge-validator-2knz0d2t.js → knowledge-validator-t9sym59g.js} +4 -2
  30. package/dist/cli/{skill-generator-w6qd9mde.js → skill-generator-tav44xpm.js} +4 -4
  31. package/dist/commands/ci-monitor.d.ts +18 -0
  32. package/dist/commands/registry.d.ts +8 -0
  33. package/dist/config/skill-mirrors.d.ts +22 -1
  34. package/dist/hooks/adversarial-detector.d.ts +6 -0
  35. package/dist/hooks/delegation-gate.d.ts +19 -0
  36. package/dist/hooks/guardrails/index.d.ts +2 -2
  37. package/dist/hooks/knowledge-validator.d.ts +22 -0
  38. package/dist/index.d.ts +7 -0
  39. package/dist/index.js +194 -169
  40. package/dist/plan/ledger.d.ts +83 -20
  41. package/dist/types/delegation.d.ts +24 -0
  42. package/package.json +1 -1
  43. package/dist/graph/graph-builder.d.ts +0 -39
  44. package/dist/graph/graph-query.d.ts +0 -42
  45. package/dist/graph/graph-store.d.ts +0 -27
  46. package/dist/graph/import-extractor.d.ts +0 -44
  47. package/dist/graph/index.d.ts +0 -16
  48. package/dist/graph/symbol-extractor.d.ts +0 -17
  49. package/dist/graph/types.d.ts +0 -84
  50. package/dist/sandbox/win32/restricted-token-executor.d.ts +0 -9
@@ -68,7 +68,7 @@ import {
68
68
  savePlan,
69
69
  transientBackoff,
70
70
  validateProjectRoot
71
- } from "./index-f6y341yk.js";
71
+ } from "./index-yrrqs4b0.js";
72
72
  import {
73
73
  buildOpenSpecProjectionSync,
74
74
  detectSpeckit,
@@ -111,7 +111,7 @@ import {
111
111
  retireSkill,
112
112
  selectCandidateEntries,
113
113
  syncBundledProjectSkillsIfMissingAsync
114
- } from "./index-vjvdvjd3.js";
114
+ } from "./index-x12hvfpf.js";
115
115
  import {
116
116
  appendUnactionable,
117
117
  quarantineEntry,
@@ -121,10 +121,10 @@ import {
121
121
  validateActionability,
122
122
  validateActionableFields,
123
123
  validateLesson
124
- } from "./index-qrnhvhmg.js";
124
+ } from "./index-n18yy0z1.js";
125
125
  import {
126
126
  readRecentEscalations
127
- } from "./index-7stsmndb.js";
127
+ } from "./index-6f6y2rbp.js";
128
128
  import {
129
129
  effectiveRetrievalOutcomes,
130
130
  readKnowledgeCounterRollups,
@@ -132,7 +132,7 @@ import {
132
132
  recordHiveKnowledgeEvent,
133
133
  recordKnowledgeEvent,
134
134
  resolveKnowledgeEventsPath
135
- } from "./index-kjbfry6m.js";
135
+ } from "./index-8f2270hc.js";
136
136
  import {
137
137
  appendKnowledge,
138
138
  appendRejectedLesson,
@@ -156,7 +156,7 @@ import {
156
156
  rewriteKnowledge,
157
157
  transactFile,
158
158
  transactKnowledge
159
- } from "./index-91qesget.js";
159
+ } from "./index-rk6qhyng.js";
160
160
  import {
161
161
  KNOWLEDGE_SCHEMA_VERSION,
162
162
  OUTCOME_BLOCK_THRESHOLD,
@@ -3064,50 +3064,60 @@ class SQLiteMemoryProvider {
3064
3064
  mkdirSync4(path5.dirname(dbPath), { recursive: true });
3065
3065
  const Db = loadDatabaseCtor2();
3066
3066
  this.db = new Db(dbPath);
3067
- this.db.run("PRAGMA journal_mode = WAL;");
3068
- this.db.run("PRAGMA synchronous = NORMAL;");
3069
- const busyTimeoutMs = Math.min(60000, Math.max(0, Math.trunc(this.config.sqlite.busyTimeoutMs)));
3070
- this.db.run(`PRAGMA busy_timeout = ${busyTimeoutMs};`);
3071
- this.db.run("PRAGMA foreign_keys = ON;");
3072
- this.runMigrations();
3073
- this.backfillScopeKeys();
3074
- this.backfillRecallRunIds();
3075
- this.ftsAvailable = this.initializeFtsIndex();
3076
- this.initializeVecExtension();
3077
- if (this.config.embeddings.enabled && !this.embeddingProvider) {
3078
- try {
3079
- this.embeddingProvider = new LocalEmbeddingProvider({
3080
- model: this.config.embeddings.model,
3081
- dimension: this.config.embeddings.dimension,
3082
- version: this.config.embeddings.version
3083
- });
3084
- } catch (err) {
3085
- this.embeddingProvider = null;
3086
- warn("Failed to construct embedding provider \u2014 dense retrieval disabled", {
3087
- reason: err instanceof Error ? err.message : String(err)
3088
- });
3067
+ try {
3068
+ this.db.run("PRAGMA journal_mode = WAL;");
3069
+ this.db.run("PRAGMA synchronous = NORMAL;");
3070
+ const busyTimeoutMs = Math.min(60000, Math.max(0, Math.trunc(this.config.sqlite.busyTimeoutMs)));
3071
+ this.db.run(`PRAGMA busy_timeout = ${busyTimeoutMs};`);
3072
+ this.db.run("PRAGMA foreign_keys = ON;");
3073
+ this.runMigrations();
3074
+ this.backfillScopeKeys();
3075
+ this.backfillRecallRunIds();
3076
+ this.ftsAvailable = this.initializeFtsIndex();
3077
+ this.initializeVecExtension();
3078
+ if (this.config.embeddings.enabled && !this.embeddingProvider) {
3079
+ try {
3080
+ this.embeddingProvider = new LocalEmbeddingProvider({
3081
+ model: this.config.embeddings.model,
3082
+ dimension: this.config.embeddings.dimension,
3083
+ version: this.config.embeddings.version
3084
+ });
3085
+ } catch (err) {
3086
+ this.embeddingProvider = null;
3087
+ warn("Failed to construct embedding provider \u2014 dense retrieval disabled", {
3088
+ reason: err instanceof Error ? err.message : String(err)
3089
+ });
3090
+ }
3091
+ try {
3092
+ this.embeddingCache = new EmbeddingCache(this.config.embeddings.cacheSize);
3093
+ } catch (err) {
3094
+ this.embeddingCache = null;
3095
+ warn("Failed to construct embedding cache \u2014 recall works without cache", {
3096
+ reason: err instanceof Error ? err.message : String(err)
3097
+ });
3098
+ }
3089
3099
  }
3090
- try {
3091
- this.embeddingCache = new EmbeddingCache(this.config.embeddings.cacheSize);
3092
- } catch (err) {
3093
- this.embeddingCache = null;
3094
- warn("Failed to construct embedding cache \u2014 recall works without cache", {
3095
- reason: err instanceof Error ? err.message : String(err)
3096
- });
3100
+ this.lastAutomaticJsonlMigration = null;
3101
+ await this.migrateLegacyJsonlIfNeeded();
3102
+ const memoryLoad = this.loadMemories();
3103
+ const proposalLoad = this.loadProposals();
3104
+ this.memories = new Map(memoryLoad.records.map((record) => [record.id, record]));
3105
+ this.proposals = new Map(proposalLoad.records.map((proposal) => [proposal.id, proposal]));
3106
+ this.initialized = true;
3107
+ if (memoryLoad.invalidCount > 0) {
3108
+ await this.event("invalid_load", "memory_items", `${memoryLoad.invalidCount} invalid SQLite memory row(s) skipped`);
3097
3109
  }
3098
- }
3099
- this.lastAutomaticJsonlMigration = null;
3100
- await this.migrateLegacyJsonlIfNeeded();
3101
- const memoryLoad = this.loadMemories();
3102
- const proposalLoad = this.loadProposals();
3103
- this.memories = new Map(memoryLoad.records.map((record) => [record.id, record]));
3104
- this.proposals = new Map(proposalLoad.records.map((proposal) => [proposal.id, proposal]));
3105
- this.initialized = true;
3106
- if (memoryLoad.invalidCount > 0) {
3107
- await this.event("invalid_load", "memory_items", `${memoryLoad.invalidCount} invalid SQLite memory row(s) skipped`);
3108
- }
3109
- if (proposalLoad.invalidCount > 0) {
3110
- await this.event("invalid_load", "memory_proposals", `${proposalLoad.invalidCount} invalid SQLite proposal row(s) skipped`);
3110
+ if (proposalLoad.invalidCount > 0) {
3111
+ await this.event("invalid_load", "memory_proposals", `${proposalLoad.invalidCount} invalid SQLite proposal row(s) skipped`);
3112
+ }
3113
+ } catch (err) {
3114
+ try {
3115
+ this.db?.close();
3116
+ } catch {}
3117
+ this.db = null;
3118
+ this.ftsAvailable = false;
3119
+ this.initialized = false;
3120
+ throw err;
3111
3121
  }
3112
3122
  }
3113
3123
  async upsert(record) {
@@ -3132,7 +3142,20 @@ class SQLiteMemoryProvider {
3132
3142
  }
3133
3143
  async withTransaction(fn) {
3134
3144
  const db = this.requireDb();
3135
- return db.transaction(() => fn({}))();
3145
+ if (db.inTransaction) {
3146
+ return await fn({});
3147
+ }
3148
+ db.run("BEGIN IMMEDIATE");
3149
+ try {
3150
+ const result = await fn({});
3151
+ db.run("COMMIT");
3152
+ return result;
3153
+ } catch (err) {
3154
+ try {
3155
+ db.run("ROLLBACK");
3156
+ } catch {}
3157
+ throw err;
3158
+ }
3136
3159
  }
3137
3160
  async delete(id, reason) {
3138
3161
  await this.initialize();
@@ -6403,6 +6426,294 @@ async function handleList2(directory) {
6403
6426
  }
6404
6427
  }
6405
6428
 
6429
+ // src/commands/_shared/url-security.ts
6430
+ import * as child_process2 from "child_process";
6431
+ var MAX_URL_LEN = 2048;
6432
+ var IPV4_PRIVATE = /^10\./;
6433
+ var IPV4_LOOPBACK = /^127\./;
6434
+ var IPV4_LINK_LOCAL = /^169\.254\./;
6435
+ var IPV4_PRIVATE_172 = /^172\.(1[6-9]|2\d|3[0-1])\./;
6436
+ var IPV4_PRIVATE_192 = /^192\.168\./;
6437
+ var IPV4_ZERO_NETWORK = /^0\./;
6438
+ var IPV6_LINK_LOCAL = /^fe80:/i;
6439
+ var IPV6_UNIQUE_LOCAL = /^f[cd][0-9a-f]{2}:/i;
6440
+ var _internals7 = {
6441
+ spawnSync: (cmd, args, options) => {
6442
+ const mergedEnv = mergeEnvForChild(options?.env, options?.envOverrides);
6443
+ return child_process2.spawnSync(cmd, args, {
6444
+ ...options,
6445
+ env: mergedEnv
6446
+ });
6447
+ }
6448
+ };
6449
+ function sanitizeUrl(raw) {
6450
+ let urlStr = raw.trim();
6451
+ urlStr = urlStr.replace(/\[\s*MODE\s*:[^\]]*\]/gi, "");
6452
+ const fragmentIdx = urlStr.indexOf("#");
6453
+ if (fragmentIdx !== -1) {
6454
+ urlStr = urlStr.slice(0, fragmentIdx);
6455
+ }
6456
+ const queryIdx = urlStr.indexOf("?");
6457
+ if (queryIdx !== -1) {
6458
+ urlStr = urlStr.slice(0, queryIdx);
6459
+ }
6460
+ urlStr = urlStr.replace(/^[A-Za-z][A-Za-z0-9+.-]*:\/\/[^@/]+@/, "https://");
6461
+ if (urlStr.length > MAX_URL_LEN) {
6462
+ urlStr = urlStr.slice(0, MAX_URL_LEN);
6463
+ }
6464
+ return urlStr.trim();
6465
+ }
6466
+ function sanitizeErrorEcho(raw, maxLength = 80) {
6467
+ let stripped = "";
6468
+ for (const ch of raw) {
6469
+ const cp = ch.codePointAt(0);
6470
+ if (cp !== undefined && (cp <= 31 || cp === 127)) {
6471
+ stripped += " ";
6472
+ continue;
6473
+ }
6474
+ stripped += ch;
6475
+ }
6476
+ const collapsed = stripped.replace(/\s+/g, " ").trim();
6477
+ if (collapsed.length <= maxLength)
6478
+ return collapsed;
6479
+ return `${collapsed.slice(0, maxLength)}\u2026`;
6480
+ }
6481
+ function containsControlCharacters(value) {
6482
+ for (const ch of value) {
6483
+ const cp = ch.codePointAt(0);
6484
+ if (cp !== undefined && (cp <= 31 || cp === 127)) {
6485
+ return true;
6486
+ }
6487
+ }
6488
+ return false;
6489
+ }
6490
+ function hasNonAsciiHostname(hostname) {
6491
+ for (const ch of hostname) {
6492
+ const cp = ch.codePointAt(0);
6493
+ if (cp !== undefined && cp > 127)
6494
+ return true;
6495
+ }
6496
+ return false;
6497
+ }
6498
+ function isIpv4MappedPrivateHost(inner) {
6499
+ if (IPV4_PRIVATE.test(inner) || IPV4_LOOPBACK.test(inner) || IPV4_LINK_LOCAL.test(inner) || IPV4_PRIVATE_172.test(inner) || IPV4_PRIVATE_192.test(inner) || IPV4_ZERO_NETWORK.test(inner)) {
6500
+ return true;
6501
+ }
6502
+ const firstSegment = inner.split(":", 1)[0];
6503
+ if (!firstSegment)
6504
+ return false;
6505
+ const firstWord = Number.parseInt(firstSegment, 16);
6506
+ if (!Number.isFinite(firstWord))
6507
+ return false;
6508
+ return firstWord >= 0 && firstWord <= 255 || firstWord >= 2560 && firstWord <= 2815 || firstWord >= 32512 && firstWord <= 32767 || firstWord === 43518 || firstWord >= 44048 && firstWord <= 44063 || firstWord === 49320;
6509
+ }
6510
+ function isPrivateHost(url) {
6511
+ const host = url.hostname.toLowerCase().replace(/^\[|\]$/g, "");
6512
+ if (host === "localhost" || host === "::1" || host === "0.0.0.0" || IPV4_LOOPBACK.test(host) || IPV4_ZERO_NETWORK.test(host)) {
6513
+ return true;
6514
+ }
6515
+ if (host.startsWith("localhost") || host === "localhost.com") {
6516
+ return true;
6517
+ }
6518
+ if (IPV4_PRIVATE.test(host) || IPV4_LINK_LOCAL.test(host) || IPV4_PRIVATE_172.test(host) || IPV4_PRIVATE_192.test(host) || IPV6_LINK_LOCAL.test(host) || IPV6_UNIQUE_LOCAL.test(host)) {
6519
+ return true;
6520
+ }
6521
+ if (host.startsWith("::ffff:")) {
6522
+ const inner = host.slice(7);
6523
+ if (isIpv4MappedPrivateHost(inner)) {
6524
+ return true;
6525
+ }
6526
+ }
6527
+ return false;
6528
+ }
6529
+ function validateAndSanitizeGithubUrl(rawUrl, resource) {
6530
+ const sanitized = sanitizeUrl(rawUrl);
6531
+ if (!sanitized) {
6532
+ return { error: "Empty URL" };
6533
+ }
6534
+ if (!sanitized.startsWith("https://")) {
6535
+ return { error: "URL must use HTTPS scheme" };
6536
+ }
6537
+ try {
6538
+ const url = new URL(sanitized);
6539
+ if (hasNonAsciiHostname(url.hostname)) {
6540
+ return { error: "Non-ASCII hostnames are not allowed" };
6541
+ }
6542
+ if (isPrivateHost(url)) {
6543
+ return { error: "Private or localhost URLs are not allowed" };
6544
+ }
6545
+ const githubPattern = new RegExp(`^https:\\/\\/github\\.com\\/([^/]+)\\/([^/]+)\\/${resource}\\/([0-9]+)\\/?$`);
6546
+ if (!githubPattern.test(sanitized)) {
6547
+ return {
6548
+ error: resource === "issues" ? "URL must be a GitHub issue URL (https://github.com/owner/repo/issues/N)" : "URL must be a GitHub pull request URL (https://github.com/owner/repo/pull/N)"
6549
+ };
6550
+ }
6551
+ return { sanitized };
6552
+ } catch {
6553
+ return { error: "Invalid URL format" };
6554
+ }
6555
+ }
6556
+ function detectGitRemote(cwd, laneEnv) {
6557
+ try {
6558
+ const result = _internals7.spawnSync("git", ["remote", "get-url", "origin"], {
6559
+ encoding: "utf-8",
6560
+ stdio: ["ignore", "pipe", "pipe"],
6561
+ timeout: 5000,
6562
+ ...cwd ? { cwd } : {},
6563
+ envOverrides: laneEnv
6564
+ });
6565
+ if (result.status !== 0 || result.error) {
6566
+ return null;
6567
+ }
6568
+ const remoteUrl = (result.stdout ?? "").trim();
6569
+ return remoteUrl || null;
6570
+ } catch {
6571
+ return null;
6572
+ }
6573
+ }
6574
+ function parseGitRemoteUrl(remoteUrl) {
6575
+ const httpsMatch = remoteUrl.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?\/?$/i);
6576
+ if (httpsMatch) {
6577
+ const owner = httpsMatch[1];
6578
+ const repo = httpsMatch[2].replace(/\.git$/, "");
6579
+ if (containsControlCharacters(owner) || containsControlCharacters(repo)) {
6580
+ return null;
6581
+ }
6582
+ return { owner, repo };
6583
+ }
6584
+ const sshMatch = remoteUrl.match(/^git@github\.com:([^/]+)\/([^/]+?)(?:\.git)?$/i);
6585
+ if (sshMatch) {
6586
+ const owner = sshMatch[1];
6587
+ const repo = sshMatch[2].replace(/\.git$/, "");
6588
+ if (containsControlCharacters(owner) || containsControlCharacters(repo)) {
6589
+ return null;
6590
+ }
6591
+ return { owner, repo };
6592
+ }
6593
+ const pathMatch = remoteUrl.match(/\/([^/]+)\/([^/]+?)(?:\.git)?\/?$/);
6594
+ if (pathMatch) {
6595
+ const owner = pathMatch[1];
6596
+ const repo = pathMatch[2].replace(/\.git$/, "");
6597
+ if (containsControlCharacters(owner) || containsControlCharacters(repo)) {
6598
+ return null;
6599
+ }
6600
+ return { owner, repo };
6601
+ }
6602
+ return null;
6603
+ }
6604
+
6605
+ // src/commands/pr-ref.ts
6606
+ var MAX_INSTRUCTIONS_LEN = 1000;
6607
+ function sanitizeInstructions(raw) {
6608
+ const collapsed = raw.replace(/\s+/g, " ").trim();
6609
+ const stripped = collapsed.replace(/\[\s*MODE\s*:[^\]]*\]/gi, "");
6610
+ const normalized = stripped.replace(/\s+/g, " ").trim();
6611
+ if (normalized.length <= MAX_INSTRUCTIONS_LEN)
6612
+ return normalized;
6613
+ return `${normalized.slice(0, MAX_INSTRUCTIONS_LEN)}\u2026`;
6614
+ }
6615
+ function validateAndSanitizeUrl(rawUrl) {
6616
+ return validateAndSanitizeGithubUrl(rawUrl, "pull");
6617
+ }
6618
+ function parsePrRef(input, cwd) {
6619
+ const urlMatch = input.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+)\/pull\/(\d+)\/?$/i);
6620
+ if (urlMatch) {
6621
+ if (containsControlCharacters(urlMatch[1]) || containsControlCharacters(urlMatch[2])) {
6622
+ return null;
6623
+ }
6624
+ return {
6625
+ owner: urlMatch[1],
6626
+ repo: urlMatch[2],
6627
+ number: parseInt(urlMatch[3], 10)
6628
+ };
6629
+ }
6630
+ const shorthandMatch = input.match(/^([^/]+)\/([^#]+)#(\d+)$/);
6631
+ if (shorthandMatch) {
6632
+ if (containsControlCharacters(shorthandMatch[1]) || containsControlCharacters(shorthandMatch[2])) {
6633
+ return null;
6634
+ }
6635
+ return {
6636
+ owner: shorthandMatch[1],
6637
+ repo: shorthandMatch[2],
6638
+ number: parseInt(shorthandMatch[3], 10)
6639
+ };
6640
+ }
6641
+ const bareMatch = input.match(/^(\d+)$/);
6642
+ if (bareMatch) {
6643
+ const prNumber = parseInt(bareMatch[1], 10);
6644
+ const remoteUrl = detectGitRemote(cwd, undefined);
6645
+ if (!remoteUrl) {
6646
+ return null;
6647
+ }
6648
+ const parsed = parseGitRemoteUrl(remoteUrl);
6649
+ if (!parsed) {
6650
+ return null;
6651
+ }
6652
+ return {
6653
+ owner: parsed.owner,
6654
+ repo: parsed.repo,
6655
+ number: prNumber
6656
+ };
6657
+ }
6658
+ return null;
6659
+ }
6660
+ function looksLikePrRef(token) {
6661
+ return /^https?:\/\//i.test(token) || /^[^/]+\/[^#]+#\d+$/.test(token) || /^\d+$/.test(token);
6662
+ }
6663
+ function resolvePrCommandInput(rest, cwd) {
6664
+ if (rest.length === 0) {
6665
+ return null;
6666
+ }
6667
+ const refToken = rest[0];
6668
+ const instructions = sanitizeInstructions(rest.slice(1).join(" "));
6669
+ const isFullUrl = /^https?:\/\//i.test(refToken);
6670
+ const prInfo = parsePrRef(isFullUrl ? sanitizeUrl(refToken) : refToken, cwd);
6671
+ if (!prInfo) {
6672
+ return {
6673
+ error: `Could not parse PR reference from "${sanitizeErrorEcho(refToken)}"`
6674
+ };
6675
+ }
6676
+ const prUrl = `https://github.com/${prInfo.owner}/${prInfo.repo}/pull/${prInfo.number}`;
6677
+ const result = validateAndSanitizeUrl(prUrl);
6678
+ if ("error" in result) {
6679
+ return { error: result.error };
6680
+ }
6681
+ return { prUrl: result.sanitized, instructions };
6682
+ }
6683
+
6684
+ // src/commands/ci-monitor.ts
6685
+ var USAGE = [
6686
+ "Usage: /swarm ci-monitor <pr-url|owner/repo#N|N>",
6687
+ "",
6688
+ "Drive an already human-reviewed, approved pull request to green and",
6689
+ "merged: monitors CI, exhaustively researches and fixes each failure,",
6690
+ "iterates until all required checks are green (max 5 fix cycles), then",
6691
+ "merges. Only invoke after human review is complete.",
6692
+ "",
6693
+ " /swarm ci-monitor https://github.com/owner/repo/pull/42",
6694
+ " /swarm ci-monitor owner/repo#42",
6695
+ " /swarm ci-monitor 42"
6696
+ ].join(`
6697
+ `);
6698
+ function handleCiMonitorCommand(directory, args) {
6699
+ const rest = args.filter((token) => token.trim().length > 0);
6700
+ const resolved = resolvePrCommandInput(rest, directory);
6701
+ if (resolved === null) {
6702
+ return USAGE;
6703
+ }
6704
+ if ("error" in resolved) {
6705
+ return `Error: ${resolved.error}
6706
+
6707
+ ${USAGE}`;
6708
+ }
6709
+ if (resolved.instructions) {
6710
+ return `Error: /swarm ci-monitor takes only a PR reference \u2014 no trailing instructions. Got: "${resolved.instructions}"
6711
+
6712
+ ${USAGE}`;
6713
+ }
6714
+ return `[MODE: CI_MONITOR pr="${resolved.prUrl}"]`;
6715
+ }
6716
+
6406
6717
  // src/commands/ci-simulate.ts
6407
6718
  import * as fs4 from "fs";
6408
6719
  import * as fsPromises2 from "fs/promises";
@@ -6475,7 +6786,7 @@ function timeoutKillSignal(platform) {
6475
6786
  }
6476
6787
  function killProcess(proc) {
6477
6788
  try {
6478
- proc?.kill(timeoutKillSignal(_internals7.platform()));
6789
+ proc?.kill(timeoutKillSignal(_internals8.platform()));
6479
6790
  } catch {}
6480
6791
  }
6481
6792
  async function runExternalTool(options) {
@@ -6495,7 +6806,7 @@ async function runExternalTool(options) {
6495
6806
  let exitSettled = false;
6496
6807
  let settledExitCode = null;
6497
6808
  try {
6498
- proc = _internals7.bunSpawn([options.executable, ...options.args], {
6809
+ proc = _internals8.bunSpawn([options.executable, ...options.args], {
6499
6810
  cwd: options.cwd,
6500
6811
  env: options.env,
6501
6812
  stdin: "ignore",
@@ -6563,7 +6874,7 @@ async function runExternalTool(options) {
6563
6874
  }
6564
6875
  }
6565
6876
  }
6566
- var _internals7 = {
6877
+ var _internals8 = {
6567
6878
  bunSpawn,
6568
6879
  platform: () => process.platform
6569
6880
  };
@@ -6572,7 +6883,7 @@ var _internals7 = {
6572
6883
  var GIT_TIMEOUT_MS2 = 30000;
6573
6884
  var VALIDATION_TIMEOUT_MS = 5 * 60 * 1000;
6574
6885
  var OUTPUT_LIMIT_BYTES = 12000;
6575
- var _internals8 = {
6886
+ var _internals9 = {
6576
6887
  runExternalTool,
6577
6888
  getDefaultBaseBranch,
6578
6889
  platform: process.platform,
@@ -6583,7 +6894,7 @@ var _internals8 = {
6583
6894
  }
6584
6895
  };
6585
6896
  async function runGit2(args, cwd, timeoutMs = GIT_TIMEOUT_MS2) {
6586
- const result = await _internals8.runExternalTool({
6897
+ const result = await _internals9.runExternalTool({
6587
6898
  executable: "git",
6588
6899
  args,
6589
6900
  cwd,
@@ -6601,7 +6912,7 @@ async function runGit2(args, cwd, timeoutMs = GIT_TIMEOUT_MS2) {
6601
6912
  }
6602
6913
  async function runValidationCommand(cmd, cwd, timeoutMs = VALIDATION_TIMEOUT_MS) {
6603
6914
  const [executable, ...args] = cmd;
6604
- const result = await _internals8.runExternalTool({
6915
+ const result = await _internals9.runExternalTool({
6605
6916
  executable,
6606
6917
  args,
6607
6918
  cwd,
@@ -6629,7 +6940,7 @@ async function getCurrentBranchOrRef(directory) {
6629
6940
  return hashResult.stdout.trim();
6630
6941
  }
6631
6942
  async function setupWorktree(projectRoot, prRef, baseBranch, onWorktreeCreated) {
6632
- const worktreeBase = path12.join(_internals8.osTmpdir(), "swarm-ci-simulate");
6943
+ const worktreeBase = path12.join(_internals9.osTmpdir(), "swarm-ci-simulate");
6633
6944
  const worktreeName = `pr-${Date.now()}-${Math.floor(Math.random() * 1e6)}`;
6634
6945
  const worktreePath = path12.join(worktreeBase, worktreeName);
6635
6946
  await fsPromises2.mkdir(worktreeBase, { recursive: true });
@@ -6647,8 +6958,8 @@ async function setupWorktree(projectRoot, prRef, baseBranch, onWorktreeCreated)
6647
6958
  async function cleanupWorktree(worktreePath, projectRoot) {
6648
6959
  const removeResult = await runGit2(["worktree", "remove", "--force", worktreePath], projectRoot);
6649
6960
  try {
6650
- if (_internals8.fs.existsSync(worktreePath)) {
6651
- _internals8.fs.rmSync(worktreePath, { recursive: true, force: true });
6961
+ if (_internals9.fs.existsSync(worktreePath)) {
6962
+ _internals9.fs.rmSync(worktreePath, { recursive: true, force: true });
6652
6963
  }
6653
6964
  } catch {}
6654
6965
  if (removeResult.exitCode !== 0) {
@@ -6730,7 +7041,7 @@ async function handleCiSimulateCommand(directory, args) {
6730
7041
  steps: []
6731
7042
  };
6732
7043
  try {
6733
- const baseBranch = _internals8.getDefaultBaseBranch(directory);
7044
+ const baseBranch = _internals9.getDefaultBaseBranch(directory);
6734
7045
  if (!isSafeGitRef(baseBranch)) {
6735
7046
  throw new Error("Detected default branch is not a safe git reference.");
6736
7047
  }
@@ -6829,7 +7140,7 @@ async function handleClarifyCommand(_directory, args) {
6829
7140
  }
6830
7141
 
6831
7142
  // src/commands/close.ts
6832
- import * as child_process2 from "child_process";
7143
+ import * as child_process3 from "child_process";
6833
7144
  import * as fsSync from "fs";
6834
7145
  import { promises as fs10 } from "fs";
6835
7146
  import path29 from "path";
@@ -7518,7 +7829,7 @@ async function reviseSkill(params) {
7518
7829
  }
7519
7830
  if (!params.delegate) {
7520
7831
  try {
7521
- const revised = _internals9.buildDeterministicRevision(params.currentContent, params.currentVersion, params.violationContexts);
7832
+ const revised = _internals10.buildDeterministicRevision(params.currentContent, params.currentVersion, params.violationContexts);
7522
7833
  const validation = await validateRevisionCandidate(params, revised, "skill_reviser:deterministic");
7523
7834
  if (!validation.passed) {
7524
7835
  return {
@@ -7645,7 +7956,7 @@ async function reviseSkill(params) {
7645
7956
  };
7646
7957
  }
7647
7958
  }
7648
- var _internals9 = {
7959
+ var _internals10 = {
7649
7960
  reviseSkill,
7650
7961
  getSkillVersion,
7651
7962
  buildDeterministicRevision,
@@ -7729,7 +8040,7 @@ function resolveLogPath(directory) {
7729
8040
  function normalizeComplianceVerdict(verdict) {
7730
8041
  return verdict === "violation" ? "violated" : verdict;
7731
8042
  }
7732
- var _internals10 = {
8043
+ var _internals11 = {
7733
8044
  generateId: () => crypto2.randomUUID(),
7734
8045
  appendFileSync: fs5.appendFileSync.bind(fs5),
7735
8046
  readFileSync: fs5.readFileSync.bind(fs5),
@@ -7799,9 +8110,9 @@ function parseFeedbackMarker(raw) {
7799
8110
  function readFeedbackAppliedEntryIds(directory) {
7800
8111
  const resolved = resolveLogPath(directory);
7801
8112
  const processed = new Set;
7802
- if (!_internals10.existsSync(resolved))
8113
+ if (!_internals11.existsSync(resolved))
7803
8114
  return processed;
7804
- const raw = _internals10.readFileSync(resolved, "utf-8");
8115
+ const raw = _internals11.readFileSync(resolved, "utf-8");
7805
8116
  for (const line of raw.split(`
7806
8117
  `)) {
7807
8118
  const trimmed = line.trim();
@@ -7822,15 +8133,15 @@ function appendFeedbackAppliedMarker(directory, processedEntryIds) {
7822
8133
  return;
7823
8134
  const resolved = resolveLogPath(directory);
7824
8135
  const dir = path15.dirname(resolved);
7825
- if (!_internals10.existsSync(dir)) {
7826
- _internals10.mkdirSync(dir, { recursive: true });
8136
+ if (!_internals11.existsSync(dir)) {
8137
+ _internals11.mkdirSync(dir, { recursive: true });
7827
8138
  }
7828
8139
  const marker = {
7829
8140
  type: "feedback_applied",
7830
8141
  timestamp: new Date().toISOString(),
7831
8142
  processedEntryIds: [...new Set(processedEntryIds)]
7832
8143
  };
7833
- _internals10.appendFileSync(resolved, `${JSON.stringify(marker)}
8144
+ _internals11.appendFileSync(resolved, `${JSON.stringify(marker)}
7834
8145
  `, "utf-8");
7835
8146
  }
7836
8147
  function appendSkillUsageEntry(directory, entry) {
@@ -7867,11 +8178,11 @@ function appendSkillUsageEntry(directory, entry) {
7867
8178
  }
7868
8179
  const resolved = validateSwarmPath(directory, "skill-usage.jsonl");
7869
8180
  const dir = path15.dirname(resolved);
7870
- if (!_internals10.existsSync(dir)) {
7871
- _internals10.mkdirSync(dir, { recursive: true });
8181
+ if (!_internals11.existsSync(dir)) {
8182
+ _internals11.mkdirSync(dir, { recursive: true });
7872
8183
  }
7873
8184
  const fullEntry = {
7874
- id: _internals10.generateId(),
8185
+ id: _internals11.generateId(),
7875
8186
  skillPath,
7876
8187
  agentName,
7877
8188
  taskID,
@@ -7881,21 +8192,21 @@ function appendSkillUsageEntry(directory, entry) {
7881
8192
  ...reviewerNotes !== undefined && { reviewerNotes },
7882
8193
  ...skillVersion !== undefined && { skillVersion }
7883
8194
  };
7884
- _internals10.appendFileSync(resolved, `${JSON.stringify(fullEntry)}
8195
+ _internals11.appendFileSync(resolved, `${JSON.stringify(fullEntry)}
7885
8196
  `, "utf-8");
7886
8197
  try {
7887
- const stat2 = _internals10.statSync(resolved);
8198
+ const stat2 = _internals11.statSync(resolved);
7888
8199
  if (stat2.size > SKILL_USAGE_LOG_ROTATE_BYTES) {
7889
- _internals10.pruneSkillUsageLog(directory, SKILL_USAGE_LOG_MAX_ENTRIES_PER_SKILL);
8200
+ _internals11.pruneSkillUsageLog(directory, SKILL_USAGE_LOG_MAX_ENTRIES_PER_SKILL);
7890
8201
  }
7891
8202
  } catch {}
7892
8203
  }
7893
8204
  function readSkillUsageEntries(directory, options) {
7894
8205
  const resolved = resolveLogPath(directory);
7895
- if (!_internals10.existsSync(resolved)) {
8206
+ if (!_internals11.existsSync(resolved)) {
7896
8207
  return [];
7897
8208
  }
7898
- const raw = _internals10.readFileSync(resolved, "utf-8");
8209
+ const raw = _internals11.readFileSync(resolved, "utf-8");
7899
8210
  const entries = [];
7900
8211
  for (const line of raw.split(`
7901
8212
  `)) {
@@ -7938,20 +8249,20 @@ var SKILL_USAGE_LOG_ROTATE_BYTES = 1024 * 1024;
7938
8249
  var SKILL_USAGE_LOG_MAX_ENTRIES_PER_SKILL = 500;
7939
8250
  function readSkillUsageEntriesTail(directory, filters, maxBytes = TAIL_BYTES_DEFAULT) {
7940
8251
  const logPath = resolveLogPath(directory);
7941
- if (!_internals10.existsSync(logPath))
8252
+ if (!_internals11.existsSync(logPath))
7942
8253
  return [];
7943
8254
  try {
7944
8255
  const normalizedMaxBytes = Number.isFinite(maxBytes) ? maxBytes : TAIL_BYTES_DEFAULT;
7945
8256
  const boundedMaxBytes = Math.min(Math.max(1, normalizedMaxBytes), MAX_TAIL_BYTES);
7946
- const stat2 = _internals10.statSync(logPath);
8257
+ const stat2 = _internals11.statSync(logPath);
7947
8258
  const start = Math.max(0, stat2.size - boundedMaxBytes);
7948
- const fd = _internals10.openSync(logPath, "r");
8259
+ const fd = _internals11.openSync(logPath, "r");
7949
8260
  try {
7950
8261
  const readLen = stat2.size - start;
7951
8262
  if (readLen === 0)
7952
8263
  return [];
7953
8264
  const buf = Buffer.alloc(readLen);
7954
- _internals10.readSync(fd, buf, 0, buf.length, start);
8265
+ _internals11.readSync(fd, buf, 0, buf.length, start);
7955
8266
  const content = buf.toString("utf-8");
7956
8267
  let usable;
7957
8268
  if (start > 0) {
@@ -7978,7 +8289,7 @@ function readSkillUsageEntriesTail(directory, filters, maxBytes = TAIL_BYTES_DEF
7978
8289
  }
7979
8290
  return entries;
7980
8291
  } finally {
7981
- _internals10.closeSync(fd);
8292
+ _internals11.closeSync(fd);
7982
8293
  }
7983
8294
  } catch {
7984
8295
  return [];
@@ -8015,10 +8326,10 @@ function computeComplianceByVersion(entries, skillPath) {
8015
8326
  }
8016
8327
  function pruneSkillUsageLog(directory, maxEntriesPerSkill = 500) {
8017
8328
  const resolved = resolveLogPath(directory);
8018
- if (!_internals10.existsSync(resolved)) {
8329
+ if (!_internals11.existsSync(resolved)) {
8019
8330
  return { pruned: 0, remaining: 0 };
8020
8331
  }
8021
- const raw = _internals10.readFileSync(resolved, "utf-8");
8332
+ const raw = _internals11.readFileSync(resolved, "utf-8");
8022
8333
  const lines = raw.split(`
8023
8334
  `);
8024
8335
  const entries = [];
@@ -8048,13 +8359,13 @@ function pruneSkillUsageLog(directory, maxEntriesPerSkill = 500) {
8048
8359
  `).concat(preservedMarkers.length > 0 ? `
8049
8360
  ` : "");
8050
8361
  try {
8051
- _internals10.writeFileSync(tmpPath2, content2, "utf-8");
8052
- _internals10.renameSync(tmpPath2, resolved);
8362
+ _internals11.writeFileSync(tmpPath2, content2, "utf-8");
8363
+ _internals11.renameSync(tmpPath2, resolved);
8053
8364
  } catch (writeErr) {
8054
8365
  const msg = writeErr instanceof Error ? writeErr.message : String(writeErr);
8055
8366
  try {
8056
- if (_internals10.existsSync(tmpPath2)) {
8057
- _internals10.writeFileSync(tmpPath2, "", "utf-8");
8367
+ if (_internals11.existsSync(tmpPath2)) {
8368
+ _internals11.writeFileSync(tmpPath2, "", "utf-8");
8058
8369
  }
8059
8370
  } catch {}
8060
8371
  return { pruned: 0, remaining: 0, error: msg };
@@ -8093,13 +8404,13 @@ function pruneSkillUsageLog(directory, maxEntriesPerSkill = 500) {
8093
8404
  `).concat(`
8094
8405
  `);
8095
8406
  try {
8096
- _internals10.writeFileSync(tmpPath, content, "utf-8");
8097
- _internals10.renameSync(tmpPath, resolved);
8407
+ _internals11.writeFileSync(tmpPath, content, "utf-8");
8408
+ _internals11.renameSync(tmpPath, resolved);
8098
8409
  } catch (writeErr) {
8099
8410
  const msg = writeErr instanceof Error ? writeErr.message : String(writeErr);
8100
8411
  try {
8101
- if (_internals10.existsSync(tmpPath)) {
8102
- _internals10.writeFileSync(tmpPath, "", "utf-8");
8412
+ if (_internals11.existsSync(tmpPath)) {
8413
+ _internals11.writeFileSync(tmpPath, "", "utf-8");
8103
8414
  }
8104
8415
  } catch {}
8105
8416
  return { pruned: 0, remaining: entries.length, error: msg };
@@ -8121,10 +8432,10 @@ async function resolveSourceKnowledgeIds(directory, skillPath) {
8121
8432
  if (!isContained) {
8122
8433
  return [];
8123
8434
  }
8124
- if (!_internals10.existsSync(absolute)) {
8435
+ if (!_internals11.existsSync(absolute)) {
8125
8436
  return [];
8126
8437
  }
8127
- const content = _internals10.readFileSync(absolute, "utf-8");
8438
+ const content = _internals11.readFileSync(absolute, "utf-8");
8128
8439
  return parseGeneratedFromKnowledge(content);
8129
8440
  } catch (err) {
8130
8441
  log("[skill-usage-log] resolveSourceKnowledgeIds failed (fail-open):", err instanceof Error ? err.message : String(err));
@@ -8232,7 +8543,7 @@ var DEFAULT_CURATOR_LLM_TIMEOUT_MS = 300000;
8232
8543
  var MAX_CURATOR_PHASE_DIGESTS = 50;
8233
8544
  var MAX_CURATOR_COMPLIANCE_OBSERVATIONS = 200;
8234
8545
  var MAX_CURATOR_RECOMMENDATIONS = 200;
8235
- var _internals11 = {
8546
+ var _internals12 = {
8236
8547
  parseKnowledgeRecommendations,
8237
8548
  parseKnowledgeRecommendationsWithDiagnostics,
8238
8549
  readCuratorSummary,
@@ -8338,9 +8649,9 @@ ${digest.summary}`).join(`
8338
8649
  async function autoRetireSkills(directory, _curatorKnowledgePath, excludeSlugs) {
8339
8650
  const observations = [];
8340
8651
  try {
8341
- const skillListResult = await _internals11.listSkills(directory);
8342
- const usageEntries = _internals11.readSkillUsageEntries(directory);
8343
- const allArchivedIds = await _internals11.getArchivedKnowledgeIds(directory);
8652
+ const skillListResult = await _internals12.listSkills(directory);
8653
+ const usageEntries = _internals12.readSkillUsageEntries(directory);
8654
+ const allArchivedIds = await _internals12.getArchivedKnowledgeIds(directory);
8344
8655
  for (const active of skillListResult.active) {
8345
8656
  if (excludeSlugs?.has(active.slug))
8346
8657
  continue;
@@ -8362,7 +8673,7 @@ async function autoRetireSkills(directory, _curatorKnowledgePath, excludeSlugs)
8362
8673
  const violationRate = skillUsage.length > 0 ? violations / skillUsage.length : 0;
8363
8674
  if (violationRate > 0.3) {
8364
8675
  const reason = `auto-retire: violation rate ${(violationRate * 100).toFixed(0)}% exceeds 30% threshold`;
8365
- await _internals11.retireSkill(directory, active.slug, reason);
8676
+ await _internals12.retireSkill(directory, active.slug, reason);
8366
8677
  observations.push(`Skill '${active.slug}' auto-retired: ${reason}`);
8367
8678
  warn(`[curator] ${observations[observations.length - 1]}`);
8368
8679
  continue;
@@ -8370,15 +8681,15 @@ async function autoRetireSkills(directory, _curatorKnowledgePath, excludeSlugs)
8370
8681
  let archivedSourceMatched = false;
8371
8682
  if (allArchivedIds.size > 0) {
8372
8683
  try {
8373
- const content = await _internals11.readFileAsync(active.path, "utf-8");
8374
- const sourceIds = _internals11.parseDraftFrontmatter(content)?.sourceKnowledgeIds ?? [];
8684
+ const content = await _internals12.readFileAsync(active.path, "utf-8");
8685
+ const sourceIds = _internals12.parseDraftFrontmatter(content)?.sourceKnowledgeIds ?? [];
8375
8686
  archivedSourceMatched = sourceIds.some((id) => allArchivedIds.has(id));
8376
8687
  } catch {
8377
8688
  archivedSourceMatched = false;
8378
8689
  }
8379
8690
  }
8380
8691
  if (archivedSourceMatched) {
8381
- const result = await _internals11.retireOrMarkStale(directory, path16.dirname(active.path), allArchivedIds);
8692
+ const result = await _internals12.retireOrMarkStale(directory, path16.dirname(active.path), allArchivedIds);
8382
8693
  if (result.action === "retire") {
8383
8694
  observations.push(`Skill '${active.slug}' auto-retired: all source knowledge entries archived`);
8384
8695
  warn(`[curator] ${observations[observations.length - 1]}`);
@@ -8646,7 +8957,7 @@ async function transactCuratorSummary(directory, mutate) {
8646
8957
  const resolvedPath = validateSwarmPath(directory, "curator-summary.json");
8647
8958
  let invoked = false;
8648
8959
  let mutationResult;
8649
- await _internals11.transactFile(resolvedPath, _internals11.readCuratorSummaryState, _internals11.writeCuratorSummaryState, (state) => {
8960
+ await _internals12.transactFile(resolvedPath, _internals12.readCuratorSummaryState, _internals12.writeCuratorSummaryState, (state) => {
8650
8961
  invoked = true;
8651
8962
  const mutation = mutate(state.summary);
8652
8963
  mutationResult = mutation.result;
@@ -8795,8 +9106,8 @@ function checkPhaseCompliance(phaseEvents, agentsDispatched, requiredAgents, pha
8795
9106
  const observations = [];
8796
9107
  const timestamp = new Date().toISOString();
8797
9108
  for (const agent of requiredAgents) {
8798
- const normalizedAgent = _internals11.normalizeAgentName(agent);
8799
- const isDispatched = agentsDispatched.some((a) => _internals11.normalizeAgentName(a) === normalizedAgent);
9109
+ const normalizedAgent = _internals12.normalizeAgentName(agent);
9110
+ const isDispatched = agentsDispatched.some((a) => _internals12.normalizeAgentName(a) === normalizedAgent);
8800
9111
  if (!isDispatched) {
8801
9112
  observations.push({
8802
9113
  phase,
@@ -8815,7 +9126,7 @@ function checkPhaseCompliance(phaseEvents, agentsDispatched, requiredAgents, pha
8815
9126
  if (e.type === "agent.delegation") {
8816
9127
  const agent = e.agent;
8817
9128
  if (agent && typeof agent === "string") {
8818
- const normalized = _internals11.normalizeAgentName(agent);
9129
+ const normalized = _internals12.normalizeAgentName(agent);
8819
9130
  if (normalized === "coder") {
8820
9131
  coderDelegations.push({ event: e, index: i });
8821
9132
  } else if (normalized === "reviewer") {
@@ -8872,7 +9183,7 @@ function checkPhaseCompliance(phaseEvents, agentsDispatched, requiredAgents, pha
8872
9183
  if (e.type === "agent.delegation" && e.agent) {
8873
9184
  const agent = e.agent;
8874
9185
  if (agent && typeof agent === "string") {
8875
- const normalized = _internals11.normalizeAgentName(agent);
9186
+ const normalized = _internals12.normalizeAgentName(agent);
8876
9187
  if (normalized === "sme") {
8877
9188
  smeDelegations.push({ event: e, index: i });
8878
9189
  }
@@ -8896,7 +9207,7 @@ function checkPhaseCompliance(phaseEvents, agentsDispatched, requiredAgents, pha
8896
9207
  }
8897
9208
  async function runCuratorInit(directory, config, llmDelegate) {
8898
9209
  try {
8899
- const priorSummary = await _internals11.readCuratorSummary(directory);
9210
+ const priorSummary = await _internals12.readCuratorSummary(directory);
8900
9211
  const knowledgePath = resolveSwarmKnowledgePath(directory);
8901
9212
  const allEntries = await readKnowledge(knowledgePath);
8902
9213
  const highConfidenceEntries = allEntries.filter((e) => typeof e.confidence === "number" && e.confidence >= config.min_knowledge_confidence);
@@ -8937,7 +9248,7 @@ async function runCuratorInit(directory, config, llmDelegate) {
8937
9248
  const maxContextChars = config.max_summary_tokens * 2;
8938
9249
  briefingParts.push(contextMd.slice(0, maxContextChars));
8939
9250
  }
8940
- const latestPostMortemDigest = _internals11.readLatestPostMortemDigest(directory);
9251
+ const latestPostMortemDigest = _internals12.readLatestPostMortemDigest(directory);
8941
9252
  if (latestPostMortemDigest) {
8942
9253
  briefingParts.push(`
8943
9254
  ## Latest Post-Mortem`);
@@ -9024,7 +9335,7 @@ Could not load prior session context.`,
9024
9335
  }
9025
9336
  async function runCuratorPhase(directory, phase, agentsDispatched, config, knowledgeConfig, llmDelegate) {
9026
9337
  try {
9027
- const priorSummary = await _internals11.readCuratorSummary(directory);
9338
+ const priorSummary = await _internals12.readCuratorSummary(directory);
9028
9339
  if (priorSummary?.phase_digests.some((d) => d.phase === phase)) {
9029
9340
  const existingDigest = priorSummary.phase_digests.find((d) => d.phase === phase);
9030
9341
  return {
@@ -9037,10 +9348,10 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
9037
9348
  };
9038
9349
  }
9039
9350
  const eventsJsonlContent = await readSwarmFileAsync(directory, "events.jsonl");
9040
- const phaseEvents = eventsJsonlContent ? _internals11.filterPhaseEvents(eventsJsonlContent, phase) : [];
9351
+ const phaseEvents = eventsJsonlContent ? _internals12.filterPhaseEvents(eventsJsonlContent, phase) : [];
9041
9352
  const contextMd = await readSwarmFileAsync(directory, "context.md");
9042
9353
  const requiredAgents = ["reviewer", "test_engineer"];
9043
- const complianceObservations = _internals11.checkPhaseCompliance(phaseEvents, agentsDispatched, requiredAgents, phase);
9354
+ const complianceObservations = _internals12.checkPhaseCompliance(phaseEvents, agentsDispatched, requiredAgents, phase);
9044
9355
  const plan = await loadPlanJsonOnly(directory);
9045
9356
  const phaseData = plan?.phases.find((p) => p.id === phase);
9046
9357
  const tasksCompleted = phaseData ? phaseData.tasks.filter((t) => t.status === "completed").length : 0;
@@ -9064,7 +9375,7 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
9064
9375
  timestamp: new Date().toISOString(),
9065
9376
  summary: `Phase ${phase} completed. ${tasksCompleted}/${tasksTotal} tasks completed. ${complianceObservations.length} compliance observations.`,
9066
9377
  agents_used: [
9067
- ...new Set(agentsDispatched.map((a) => _internals11.normalizeAgentName(a)))
9378
+ ...new Set(agentsDispatched.map((a) => _internals12.normalizeAgentName(a)))
9068
9379
  ],
9069
9380
  tasks_completed: tasksCompleted,
9070
9381
  tasks_total: tasksTotal,
@@ -9116,7 +9427,7 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
9116
9427
  clearTimeout(timer);
9117
9428
  }
9118
9429
  if (llmOutput?.trim()) {
9119
- const parsed = _internals11.parseKnowledgeRecommendationsWithDiagnostics(llmOutput);
9430
+ const parsed = _internals12.parseKnowledgeRecommendationsWithDiagnostics(llmOutput);
9120
9431
  for (const diagnostic of parsed.diagnostics) {
9121
9432
  warn("[curator] skipped malformed recommendation line", {
9122
9433
  phase,
@@ -9161,7 +9472,7 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
9161
9472
  }
9162
9473
  const sessionId = `session-${Date.now()}`;
9163
9474
  const now = new Date().toISOString();
9164
- const summaryUpdated = await _internals11.mergeCuratorPhaseSummary(directory, {
9475
+ const summaryUpdated = await _internals12.mergeCuratorPhaseSummary(directory, {
9165
9476
  phase,
9166
9477
  phaseDigest,
9167
9478
  complianceObservations,
@@ -9192,7 +9503,7 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
9192
9503
  }
9193
9504
  if (config.skill_generation_enabled === true && skillCandidates.length > 0) {
9194
9505
  try {
9195
- const skillModule = await import("./skill-generator-w6qd9mde.js");
9506
+ const skillModule = await import("./skill-generator-tav44xpm.js");
9196
9507
  for (const cand of skillCandidates) {
9197
9508
  if (cand.confidence < (config.min_skill_confidence ?? DEFAULT_SKILL_MIN_CONFIDENCE)) {
9198
9509
  continue;
@@ -9210,8 +9521,8 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
9210
9521
  }
9211
9522
  const revisedSlugs = new Set;
9212
9523
  try {
9213
- const skillListResult = await _internals11.listSkills(directory);
9214
- const usageEntries = _internals11.readSkillUsageEntries(directory);
9524
+ const skillListResult = await _internals12.listSkills(directory);
9525
+ const usageEntries = _internals12.readSkillUsageEntries(directory);
9215
9526
  let revisionCallsThisPhase = 0;
9216
9527
  for (const active of skillListResult.active) {
9217
9528
  if (revisionCallsThisPhase >= MAX_REVISION_CALLS_PER_PHASE)
@@ -9235,8 +9546,8 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
9235
9546
  const violations = skillUsage.filter((e) => e.complianceVerdict === "violated").length;
9236
9547
  const violationRate = violations / skillUsage.length;
9237
9548
  if (violationRate > REVISION_VIOLATION_THRESHOLD && violationRate <= 0.3) {
9238
- const content = await _internals11.readFileAsync(active.path, "utf-8");
9239
- const fm = _internals11.parseDraftFrontmatter(content);
9549
+ const content = await _internals12.readFileAsync(active.path, "utf-8");
9550
+ const fm = _internals12.parseDraftFrontmatter(content);
9240
9551
  if (fm && fm.skillOrigin === "promoted_external")
9241
9552
  continue;
9242
9553
  const currentVersion = fm?.version ?? 1;
@@ -9247,7 +9558,7 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
9247
9558
  reviewerNotes: e.reviewerNotes,
9248
9559
  timestamp: e.timestamp
9249
9560
  }));
9250
- const result2 = await _internals11.reviseSkill({
9561
+ const result2 = await _internals12.reviseSkill({
9251
9562
  directory,
9252
9563
  slug: active.slug,
9253
9564
  skillPath: active.path,
@@ -9266,7 +9577,7 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
9266
9577
  } catch (revisionErr) {
9267
9578
  warn(`[curator] skill revision check failed: ${revisionErr instanceof Error ? revisionErr.message : String(revisionErr)}`);
9268
9579
  }
9269
- const autoRetireObservations = await _internals11.autoRetireSkills(directory, curatorKnowledgePath, revisedSlugs);
9580
+ const autoRetireObservations = await _internals12.autoRetireSkills(directory, curatorKnowledgePath, revisedSlugs);
9270
9581
  if (autoRetireObservations.length > 0) {
9271
9582
  const retireNote = ` [${autoRetireObservations.length} skill(s) auto-retired]`;
9272
9583
  phaseDigest.summary += retireNote;
@@ -9473,7 +9784,7 @@ async function applyCuratorKnowledgeUpdates(directory, recommendations, knowledg
9473
9784
  } catch {}
9474
9785
  }
9475
9786
  if (contradictedEntries.length > 0 && knowledgeConfig.contradiction_threshold_action === "quarantine") {
9476
- const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-qn7ew687.js");
9787
+ const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-5gwp1ar8.js");
9477
9788
  for (const { id } of contradictedEntries) {
9478
9789
  try {
9479
9790
  await maybeQuarantineOnContradiction(directory, id, knowledgeConfig.contradiction_quarantine_threshold, knowledgeConfig.contradiction_quarantine_window_days);
@@ -9829,18 +10140,18 @@ async function executePostMortemActions(directory, parsed, options) {
9829
10140
  proposals_rejected: 0,
9830
10141
  proposals_skipped: 0
9831
10142
  };
9832
- const knowledgeConfig = options.knowledgeConfig ?? await _internals12.loadDefaultKnowledgeConfig();
10143
+ const knowledgeConfig = options.knowledgeConfig ?? await _internals13.loadDefaultKnowledgeConfig();
9833
10144
  if (parsed.recommendations.length > 0) {
9834
10145
  try {
9835
- const knowledgeResult = await _internals12.applyCuratorKnowledgeUpdates(directory, parsed.recommendations, knowledgeConfig);
10146
+ const knowledgeResult = await _internals13.applyCuratorKnowledgeUpdates(directory, parsed.recommendations, knowledgeConfig);
9836
10147
  result.knowledge_applied = knowledgeResult.applied;
9837
10148
  result.knowledge_skipped = knowledgeResult.skipped;
9838
10149
  } catch (err) {
9839
10150
  warnings.push(`Post-mortem knowledge actions failed: ${err instanceof Error ? err.message : String(err)}`);
9840
10151
  }
9841
10152
  try {
9842
- const entries = await _internals12.readSwarmKnowledge(directory);
9843
- const hiveResult = await _internals12.checkHivePromotions(entries, knowledgeConfig);
10153
+ const entries = await _internals13.readSwarmKnowledge(directory);
10154
+ const hiveResult = await _internals13.checkHivePromotions(entries, knowledgeConfig);
9844
10155
  result.hive_promotions = hiveResult.new_promotions;
9845
10156
  result.hive_encounters_incremented = hiveResult.encounters_incremented;
9846
10157
  result.hive_advancements = hiveResult.advancements;
@@ -9850,7 +10161,7 @@ async function executePostMortemActions(directory, parsed, options) {
9850
10161
  }
9851
10162
  if (parsed.queueTriage.length > 0) {
9852
10163
  try {
9853
- const proposalResult = await _internals12.applyProposalTriage(directory, parsed.queueTriage);
10164
+ const proposalResult = await _internals13.applyProposalTriage(directory, parsed.queueTriage);
9854
10165
  result.proposals_approved = proposalResult.approved.length;
9855
10166
  result.proposals_rejected = proposalResult.rejected.length;
9856
10167
  result.proposals_skipped = proposalResult.skipped.length;
@@ -9863,7 +10174,7 @@ async function executePostMortemActions(directory, parsed, options) {
9863
10174
  async function verifyPostMortemKnowledgeActions(directory, recommendations) {
9864
10175
  if (recommendations.length === 0)
9865
10176
  return [];
9866
- const entries = await _internals12.readSwarmKnowledge(directory);
10177
+ const entries = await _internals13.readSwarmKnowledge(directory);
9867
10178
  const activeEntries = entries.filter((entry) => isActiveStatus(entry.status));
9868
10179
  const exactIds = new Set(activeEntries.map((entry) => entry.id));
9869
10180
  const prefixMatches = new Map;
@@ -9964,7 +10275,7 @@ async function repairPostMortemActions(llmOutput, diagnostics, options) {
9964
10275
  ].join(`
9965
10276
  `);
9966
10277
  const repaired = await options.llmDelegate("", repairPrompt, ac.signal);
9967
- const parsed = _internals12.parsePostMortemActions(repaired);
10278
+ const parsed = _internals13.parsePostMortemActions(repaired);
9968
10279
  if (parsed.diagnostics.length === 0) {
9969
10280
  return parsed;
9970
10281
  }
@@ -10017,7 +10328,7 @@ function collectRetrospectives(directory) {
10017
10328
  }
10018
10329
  async function collectDriftReports(directory) {
10019
10330
  try {
10020
- const reports = await _internals12.readPriorDriftReports(directory);
10331
+ const reports = await _internals13.readPriorDriftReports(directory);
10021
10332
  return reports.slice(-MAX_DRIFT_REPORTS).map((report) => JSON.stringify(report, null, 2));
10022
10333
  } catch {
10023
10334
  return [];
@@ -10240,7 +10551,7 @@ async function runCuratorPostMortem(directory, options = {}) {
10240
10551
  warnings
10241
10552
  };
10242
10553
  }
10243
- const lock = await _internals12.acquirePostMortemLock(directory, effectivePlanId);
10554
+ const lock = await _internals13.acquirePostMortemLock(directory, effectivePlanId);
10244
10555
  if (!lock.acquired) {
10245
10556
  return {
10246
10557
  success: false,
@@ -10317,20 +10628,20 @@ async function runCuratorPostMortem(directory, options = {}) {
10317
10628
  } finally {
10318
10629
  clearTimeout(timer);
10319
10630
  }
10320
- let parsedActions = _internals12.parsePostMortemActions(llmOutput);
10631
+ let parsedActions = _internals13.parsePostMortemActions(llmOutput);
10321
10632
  if (parsedActions.diagnostics.length > 0) {
10322
10633
  warnings.push(`Post-mortem structured action parse diagnostics: ${parsedActions.diagnostics.join("; ")}`);
10323
- const repaired = await _internals12.repairPostMortemActions(llmOutput, parsedActions.diagnostics, options);
10634
+ const repaired = await _internals13.repairPostMortemActions(llmOutput, parsedActions.diagnostics, options);
10324
10635
  if (repaired) {
10325
10636
  parsedActions = repaired;
10326
10637
  warnings.push("Post-mortem structured actions repaired by LLM.");
10327
10638
  }
10328
10639
  }
10329
10640
  llmSummary = parsedActions.summary;
10330
- const executed = await _internals12.executePostMortemActions(directory, parsedActions, options);
10641
+ const executed = await _internals13.executePostMortemActions(directory, parsedActions, options);
10331
10642
  actionResult = executed.result;
10332
10643
  warnings.push(...executed.warnings);
10333
- const knowledgeVerification = await _internals12.verifyPostMortemKnowledgeActions(directory, parsedActions.recommendations);
10644
+ const knowledgeVerification = await _internals13.verifyPostMortemKnowledgeActions(directory, parsedActions.recommendations);
10334
10645
  for (const item of knowledgeVerification) {
10335
10646
  if (item.status === "not_found" || item.status === "ambiguous_prefix" || item.status === "missing_entry_id") {
10336
10647
  warnings.push(`Post-mortem knowledge action ${item.action} for '${item.input_entry_id ?? "new"}' ${item.status}: ${item.reason}`);
@@ -10369,10 +10680,10 @@ ${actionSummary}`;
10369
10680
  } catch (err) {
10370
10681
  const msg = err instanceof Error ? err.message : String(err);
10371
10682
  warnings.push(`LLM delegate failed, falling back to data-only report: ${msg}`);
10372
- reportContent = _internals12.buildDataOnlyReport(effectivePlanId, planSummary, knowledgeSummary, curatorDigest, proposals, unactionable, retrospectives, driftReports, { scope, sessionID: options.sessionID, planLoaded });
10683
+ reportContent = _internals13.buildDataOnlyReport(effectivePlanId, planSummary, knowledgeSummary, curatorDigest, proposals, unactionable, retrospectives, driftReports, { scope, sessionID: options.sessionID, planLoaded });
10373
10684
  }
10374
10685
  } else {
10375
- reportContent = _internals12.buildDataOnlyReport(effectivePlanId, planSummary, knowledgeSummary, curatorDigest, proposals, unactionable, retrospectives, driftReports, { scope, sessionID: options.sessionID, planLoaded });
10686
+ reportContent = _internals13.buildDataOnlyReport(effectivePlanId, planSummary, knowledgeSummary, curatorDigest, proposals, unactionable, retrospectives, driftReports, { scope, sessionID: options.sessionID, planLoaded });
10376
10687
  }
10377
10688
  try {
10378
10689
  const { mkdirSync: mkdirSync8 } = await import("fs");
@@ -10413,7 +10724,7 @@ ${actionSummary}`;
10413
10724
  }
10414
10725
  }
10415
10726
  }
10416
- var _internals12 = {
10727
+ var _internals13 = {
10417
10728
  acquirePostMortemLock,
10418
10729
  collectKnowledgeSummary,
10419
10730
  collectRetrospectives,
@@ -10434,11 +10745,11 @@ var _internals12 = {
10434
10745
  return KnowledgeConfigSchema2.parse({});
10435
10746
  },
10436
10747
  applyCuratorKnowledgeUpdates: async (directory, recommendations, knowledgeConfig) => {
10437
- const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-qshyr2tc.js");
10748
+ const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-5xt89z05.js");
10438
10749
  return applyCuratorKnowledgeUpdates2(directory, recommendations, knowledgeConfig);
10439
10750
  },
10440
10751
  checkHivePromotions: async (entries, knowledgeConfig) => {
10441
- const { checkHivePromotions } = await import("./hive-promoter-5ngbmnrw.js");
10752
+ const { checkHivePromotions } = await import("./hive-promoter-q899q2m6.js");
10442
10753
  return checkHivePromotions(entries, knowledgeConfig);
10443
10754
  },
10444
10755
  applyProposalTriage: async (directory, triage) => {
@@ -10447,7 +10758,7 @@ var _internals12 = {
10447
10758
  activateProposal,
10448
10759
  listSkills: listSkills2,
10449
10760
  sanitizeSlug
10450
- } = await import("./skill-generator-w6qd9mde.js");
10761
+ } = await import("./skill-generator-tav44xpm.js");
10451
10762
  const result = {
10452
10763
  approved: [],
10453
10764
  rejected: [],
@@ -10666,7 +10977,7 @@ async function checkHivePromotions(swarmEntries, config) {
10666
10977
  total_hive_entries: hiveEntries.length
10667
10978
  };
10668
10979
  }
10669
- var _internals13 = {
10980
+ var _internals14 = {
10670
10981
  readSwarmEntries: (directory) => readKnowledge(resolveSwarmKnowledgePath(directory)),
10671
10982
  checkHivePromotions,
10672
10983
  readCuratorSummary,
@@ -10674,15 +10985,15 @@ var _internals13 = {
10674
10985
  };
10675
10986
  function createHivePromoterHook(directory, config) {
10676
10987
  const hook = async (_input, _output) => {
10677
- const swarmEntries = await _internals13.readSwarmEntries(directory);
10678
- const promotionSummary = await _internals13.checkHivePromotions(swarmEntries, config);
10679
- const curatorSummary = await _internals13.readCuratorSummary(directory);
10988
+ const swarmEntries = await _internals14.readSwarmEntries(directory);
10989
+ const promotionSummary = await _internals14.checkHivePromotions(swarmEntries, config);
10990
+ const curatorSummary = await _internals14.readCuratorSummary(directory);
10680
10991
  if (!curatorSummary)
10681
10992
  return;
10682
10993
  const hasActivity = promotionSummary.new_promotions > 0 || promotionSummary.encounters_incremented > 0 || promotionSummary.advancements > 0;
10683
10994
  if (!hasActivity)
10684
10995
  return;
10685
- await _internals13.appendCuratorRecommendation(directory, {
10996
+ await _internals14.appendCuratorRecommendation(directory, {
10686
10997
  action: "promote",
10687
10998
  lesson: `Hive promotion: ${promotionSummary.new_promotions} new, ${promotionSummary.encounters_incremented} encounters, ${promotionSummary.advancements} advancements, ${promotionSummary.total_hive_entries} total entries`,
10688
10999
  reason: JSON.stringify({
@@ -11023,7 +11334,7 @@ var SKILL_AUDIENCE_RUNNER_PATTERN = /^runner:(opencode|claude|codex)$/;
11023
11334
  var WORKFLOW_BOOST_MIN_CONTEXT = 0.05;
11024
11335
  var RECENCY_DECAY_MS = 30 * 24 * 60 * 60 * 1000;
11025
11336
  var SKILL_FRONTMATTER_READ_BYTES = 16 * 1024;
11026
- var _internals14 = {
11337
+ var _internals15 = {
11027
11338
  computeSkillRelevanceScore: null,
11028
11339
  rankSkillsForContext: null,
11029
11340
  getSkillStats: null,
@@ -11390,7 +11701,7 @@ function rankSkillsForContext(skills, taskContext, directory) {
11390
11701
  const results = [];
11391
11702
  for (const skillPath of skills) {
11392
11703
  const skillEntries = allEntries.filter((e) => e.skillPath === skillPath);
11393
- const metadata = _internals14.readSkillMetadata(skillPath, directory);
11704
+ const metadata = _internals15.readSkillMetadata(skillPath, directory);
11394
11705
  const score = computeSkillRelevanceScore(skillPath, taskContext, skillEntries, metadata);
11395
11706
  const entriesWithVerdict = skillEntries.filter((e) => e.complianceVerdict !== undefined && e.complianceVerdict !== "not_checked");
11396
11707
  const compliantCount = entriesWithVerdict.filter((e) => e.complianceVerdict === "compliant").length;
@@ -11449,7 +11760,7 @@ function formatSkillIndexWithContext(skills, directory, metadataBySkillPath) {
11449
11760
  } catch {}
11450
11761
  if (!hasHistory) {
11451
11762
  return skills.map((sp) => {
11452
- const meta = metadataBySkillPath?.get(sp) ?? _internals14.readSkillMetadata(sp, directory);
11763
+ const meta = metadataBySkillPath?.get(sp) ?? _internals15.readSkillMetadata(sp, directory);
11453
11764
  return ` - file:${meta.path} - ${meta.name}: ${meta.description}`;
11454
11765
  }).join(`
11455
11766
  `);
@@ -11457,7 +11768,7 @@ function formatSkillIndexWithContext(skills, directory, metadataBySkillPath) {
11457
11768
  const lines = [];
11458
11769
  for (const skillPath of skills) {
11459
11770
  const stats = getSkillStats(skillPath, directory);
11460
- const meta = metadataBySkillPath?.get(skillPath) ?? _internals14.readSkillMetadata(skillPath, directory);
11771
+ const meta = metadataBySkillPath?.get(skillPath) ?? _internals15.readSkillMetadata(skillPath, directory);
11461
11772
  const compliancePct = Math.round(stats.complianceRate * 100);
11462
11773
  const topAgentNames = stats.topAgents.slice(0, 3).map((a) => a.agent).join(", ");
11463
11774
  lines.push(` - file:${meta.path} - ${meta.name}: ${meta.description} (used: ${stats.totalUsage}, compliance: ${compliancePct}%)` + (stats.topAgents.length > 0 ? ` \u2192 ${topAgentNames}` : ""));
@@ -11465,16 +11776,16 @@ function formatSkillIndexWithContext(skills, directory, metadataBySkillPath) {
11465
11776
  return lines.join(`
11466
11777
  `);
11467
11778
  }
11468
- _internals14.computeSkillRelevanceScore = computeSkillRelevanceScore;
11469
- _internals14.rankSkillsForContext = rankSkillsForContext;
11470
- _internals14.getSkillStats = getSkillStats;
11471
- _internals14.formatSkillIndexWithContext = formatSkillIndexWithContext;
11472
- _internals14.parseSkillFrontmatter = parseSkillFrontmatter;
11473
- _internals14.readSkillMetadata = readSkillMetadata;
11474
- _internals14.extractSkillName = extractSkillName;
11475
- _internals14.computeRecencyScore = computeRecencyScore;
11476
- _internals14.computeContextMatchScore = computeContextMatchScore;
11477
- _internals14.computeTriggerMatchBoost = computeTriggerMatchBoost;
11779
+ _internals15.computeSkillRelevanceScore = computeSkillRelevanceScore;
11780
+ _internals15.rankSkillsForContext = rankSkillsForContext;
11781
+ _internals15.getSkillStats = getSkillStats;
11782
+ _internals15.formatSkillIndexWithContext = formatSkillIndexWithContext;
11783
+ _internals15.parseSkillFrontmatter = parseSkillFrontmatter;
11784
+ _internals15.readSkillMetadata = readSkillMetadata;
11785
+ _internals15.extractSkillName = extractSkillName;
11786
+ _internals15.computeRecencyScore = computeRecencyScore;
11787
+ _internals15.computeContextMatchScore = computeContextMatchScore;
11788
+ _internals15.computeTriggerMatchBoost = computeTriggerMatchBoost;
11478
11789
 
11479
11790
  // src/hooks/skill-propagation-gate.ts
11480
11791
  function parseSimpleYaml(content) {
@@ -11576,10 +11887,10 @@ function parseYamlValue(value) {
11576
11887
  }
11577
11888
  function loadRoutingSkills(directory, targetAgent) {
11578
11889
  const routingPath = path21.join(directory, ".opencode", "skill-routing.yaml");
11579
- if (!_internals15.existsSync(routingPath))
11890
+ if (!_internals16.existsSync(routingPath))
11580
11891
  return [];
11581
11892
  try {
11582
- const content = _internals15.readFileSync(routingPath, "utf-8");
11893
+ const content = _internals16.readFileSync(routingPath, "utf-8");
11583
11894
  const config = parseSimpleYaml(content);
11584
11895
  if (!config?.routing)
11585
11896
  return [];
@@ -11606,7 +11917,7 @@ var SKILL_SEARCH_ROOTS = [
11606
11917
  ".claude/skills"
11607
11918
  ];
11608
11919
  var MAX_SCORING_SESSION_ENTRIES = 500;
11609
- var _internals15 = {
11920
+ var _internals16 = {
11610
11921
  readdirSync: fs8.readdirSync.bind(fs8),
11611
11922
  existsSync: fs8.existsSync.bind(fs8),
11612
11923
  statSync: fs8.statSync.bind(fs8),
@@ -11639,11 +11950,11 @@ function discoverAvailableSkills(directory) {
11639
11950
  const results = [];
11640
11951
  for (const root of SKILL_SEARCH_ROOTS) {
11641
11952
  const rootPath = path21.join(directory, root);
11642
- if (!_internals15.existsSync(rootPath))
11953
+ if (!_internals16.existsSync(rootPath))
11643
11954
  continue;
11644
11955
  let entries;
11645
11956
  try {
11646
- entries = _internals15.readdirSync(rootPath);
11957
+ entries = _internals16.readdirSync(rootPath);
11647
11958
  } catch {
11648
11959
  continue;
11649
11960
  }
@@ -11651,11 +11962,11 @@ function discoverAvailableSkills(directory) {
11651
11962
  if (entry.startsWith("."))
11652
11963
  continue;
11653
11964
  const skillDir = path21.join(rootPath, entry);
11654
- if (_internals15.existsSync(path21.join(skillDir, "retired.marker")) || _internals15.existsSync(path21.join(skillDir, "stale.marker")))
11965
+ if (_internals16.existsSync(path21.join(skillDir, "retired.marker")) || _internals16.existsSync(path21.join(skillDir, "stale.marker")))
11655
11966
  continue;
11656
11967
  const skillFile = path21.join(skillDir, "SKILL.md");
11657
11968
  try {
11658
- if (_internals15.statSync(skillDir).isDirectory() && _internals15.existsSync(skillFile)) {
11969
+ if (_internals16.statSync(skillDir).isDirectory() && _internals16.existsSync(skillFile)) {
11659
11970
  results.push(path21.join(root, entry, "SKILL.md").replace(/\\/g, "/"));
11660
11971
  }
11661
11972
  } catch (err) {
@@ -11687,7 +11998,7 @@ function parseDelegationArgs(args) {
11687
11998
  }
11688
11999
  if (!targetAgent)
11689
12000
  return null;
11690
- const skillsField = prompt ? _internals15.extractSkillsFieldFromPrompt(prompt) : "";
12001
+ const skillsField = prompt ? _internals16.extractSkillsFieldFromPrompt(prompt) : "";
11691
12002
  return { targetAgent, skillsField };
11692
12003
  }
11693
12004
  function extractSkillsFieldFromPrompt(prompt) {
@@ -11728,10 +12039,10 @@ function writeWarnEvent(directory, record) {
11728
12039
  const filePath = path21.join(directory, ".swarm", "events.jsonl");
11729
12040
  try {
11730
12041
  const dir = path21.dirname(filePath);
11731
- if (!_internals15.existsSync(dir)) {
11732
- _internals15.mkdirSync(dir, { recursive: true });
12042
+ if (!_internals16.existsSync(dir)) {
12043
+ _internals16.mkdirSync(dir, { recursive: true });
11733
12044
  }
11734
- _internals15.appendFileSync(filePath, `${JSON.stringify(record)}
12045
+ _internals16.appendFileSync(filePath, `${JSON.stringify(record)}
11735
12046
  `, "utf-8");
11736
12047
  } catch (err) {
11737
12048
  warn(`[skill-propagation-gate] failed to write warning event: ${err instanceof Error ? err.message : String(err)}`);
@@ -11786,7 +12097,7 @@ function validateSkillReference(directory, reference, context, options) {
11786
12097
  };
11787
12098
  }
11788
12099
  try {
11789
- const root = _internals15.realpathSync(directory);
12100
+ const root = _internals16.realpathSync(directory);
11790
12101
  const lexicalPath = path21.resolve(root, withoutPrefix);
11791
12102
  if (!isWithinRoot(root, lexicalPath)) {
11792
12103
  return {
@@ -11794,10 +12105,10 @@ function validateSkillReference(directory, reference, context, options) {
11794
12105
  reason: "skill path resolves outside the project"
11795
12106
  };
11796
12107
  }
11797
- if (!_internals15.existsSync(lexicalPath) || !_internals15.statSync(lexicalPath).isFile()) {
12108
+ if (!_internals16.existsSync(lexicalPath) || !_internals16.statSync(lexicalPath).isFile()) {
11798
12109
  return { valid: false, reason: "skill file does not exist" };
11799
12110
  }
11800
- const realPath = _internals15.realpathSync(lexicalPath);
12111
+ const realPath = _internals16.realpathSync(lexicalPath);
11801
12112
  if (!isWithinRoot(root, realPath)) {
11802
12113
  return {
11803
12114
  valid: false,
@@ -11806,7 +12117,7 @@ function validateSkillReference(directory, reference, context, options) {
11806
12117
  }
11807
12118
  const normalizedPath = withoutPrefix.replace(/^\.\//, "");
11808
12119
  const validatedMetadataPath = path21.relative(root, realPath).replace(/\\/g, "/");
11809
- const metadata = _internals15.readSkillMetadata(validatedMetadataPath, root);
12120
+ const metadata = _internals16.readSkillMetadata(validatedMetadataPath, root);
11810
12121
  if (metadata.frontmatterStatus !== "valid" && metadata.frontmatterStatus !== "absent") {
11811
12122
  return {
11812
12123
  valid: false,
@@ -11838,18 +12149,18 @@ async function validateExplicitSkillReferencesBefore(directory, input, config) {
11838
12149
  if (!agentRaw || stripKnownSwarmPrefix(agentRaw) !== "architect") {
11839
12150
  return { blocked: false, reason: null };
11840
12151
  }
11841
- const parsed = _internals15.parseDelegationArgs(input.args);
12152
+ const parsed = _internals16.parseDelegationArgs(input.args);
11842
12153
  if (!parsed)
11843
12154
  return { blocked: false, reason: null };
11844
12155
  const targetBase = stripKnownSwarmPrefix(parsed.targetAgent);
11845
- if (!_internals15.SKILL_CAPABLE_AGENTS.has(targetBase)) {
12156
+ if (!_internals16.SKILL_CAPABLE_AGENTS.has(targetBase)) {
11846
12157
  return { blocked: false, reason: null };
11847
12158
  }
11848
12159
  const skillsValue = parsed.skillsField.trim();
11849
12160
  if (!skillsValue || skillsValue.toLowerCase() === "none") {
11850
12161
  return { blocked: false, reason: null };
11851
12162
  }
11852
- const fileReferences = _internals15.extractFileSkillReferences(skillsValue);
12163
+ const fileReferences = _internals16.extractFileSkillReferences(skillsValue);
11853
12164
  if (fileReferences.length === 0) {
11854
12165
  return { blocked: false, reason: null, validatedSkillPaths: [] };
11855
12166
  }
@@ -11862,7 +12173,7 @@ async function validateExplicitSkillReferencesBefore(directory, input, config) {
11862
12173
  const context = resolveSkillAudienceContext(config);
11863
12174
  const validatedSkillPaths = [];
11864
12175
  for (const reference of fileReferences) {
11865
- const result = _internals15.validateSkillReference(directory, reference, context, {
12176
+ const result = _internals16.validateSkillReference(directory, reference, context, {
11866
12177
  enforceAudience: true
11867
12178
  });
11868
12179
  if (!result.valid) {
@@ -11907,18 +12218,18 @@ async function skillPropagationGateBefore(directory, input, config) {
11907
12218
  const baseAgent = stripKnownSwarmPrefix(agentRaw);
11908
12219
  if (baseAgent !== "architect")
11909
12220
  return { blocked: false, reason: null, recommendedSkills: undefined };
11910
- const parsed = _internals15.parseDelegationArgs(input.args);
12221
+ const parsed = _internals16.parseDelegationArgs(input.args);
11911
12222
  if (!parsed)
11912
12223
  return { blocked: false, reason: null, recommendedSkills: undefined };
11913
12224
  const targetBase = stripKnownSwarmPrefix(parsed.targetAgent);
11914
- if (!_internals15.SKILL_CAPABLE_AGENTS.has(targetBase))
12225
+ if (!_internals16.SKILL_CAPABLE_AGENTS.has(targetBase))
11915
12226
  return { blocked: false, reason: null, recommendedSkills: undefined };
11916
12227
  const sessionID = typeof input.sessionID === "string" ? input.sessionID : "unknown";
11917
12228
  const audienceContext = resolveSkillAudienceContext(config);
11918
12229
  const availableSkills = [];
11919
12230
  const metadataBySkillPath = new Map;
11920
- for (const skillPath of _internals15.discoverAvailableSkills(directory)) {
11921
- const validation = _internals15.validateSkillReference(directory, skillPath, audienceContext, { enforceAudience: true, requireFilePrefix: false });
12231
+ for (const skillPath of _internals16.discoverAvailableSkills(directory)) {
12232
+ const validation = _internals16.validateSkillReference(directory, skillPath, audienceContext, { enforceAudience: true, requireFilePrefix: false });
11922
12233
  if (!validation.valid || !validation.skillPath)
11923
12234
  continue;
11924
12235
  availableSkills.push(validation.skillPath);
@@ -11929,7 +12240,7 @@ async function skillPropagationGateBefore(directory, input, config) {
11929
12240
  const skillsValue = parsed.skillsField.trim();
11930
12241
  if (skillsValue && skillsValue.toLowerCase() !== "none") {
11931
12242
  const prompt = typeof input.args?.prompt === "string" ? String(input.args.prompt) : "";
11932
- const taskId = _internals15.extractTaskIdFromPrompt(prompt);
12243
+ const taskId = _internals16.extractTaskIdFromPrompt(prompt);
11933
12244
  const skillPaths = explicitIntegrity.validatedSkillPaths ?? [];
11934
12245
  let coderSkillPaths = [];
11935
12246
  if (prompt) {
@@ -11938,19 +12249,19 @@ async function skillPropagationGateBefore(directory, input, config) {
11938
12249
  const trimmed = line.trim();
11939
12250
  if (trimmed.startsWith("SKILLS_USED_BY_CODER:")) {
11940
12251
  const fieldVal = trimmed.slice("SKILLS_USED_BY_CODER:".length).trim();
11941
- coderSkillPaths = _internals15.parseSkillPaths(fieldVal);
12252
+ coderSkillPaths = _internals16.parseSkillPaths(fieldVal);
11942
12253
  break;
11943
12254
  }
11944
12255
  }
11945
12256
  }
11946
12257
  const safeCoderSkillPaths = coderSkillPaths.flatMap((skillPath) => {
11947
- const validation = _internals15.validateSkillReference(directory, skillPath, audienceContext, { enforceAudience: false });
12258
+ const validation = _internals16.validateSkillReference(directory, skillPath, audienceContext, { enforceAudience: false });
11948
12259
  return validation.valid && validation.skillPath ? [validation.skillPath] : [];
11949
12260
  });
11950
12261
  const allPaths = [...new Set([...skillPaths, ...safeCoderSkillPaths])];
11951
12262
  for (const skillPath of allPaths) {
11952
12263
  try {
11953
- _internals15.appendSkillUsageEntry(directory, {
12264
+ _internals16.appendSkillUsageEntry(directory, {
11954
12265
  skillPath,
11955
12266
  agentName: targetBase,
11956
12267
  taskID: taskId,
@@ -11967,18 +12278,18 @@ async function skillPropagationGateBefore(directory, input, config) {
11967
12278
  let scored = [];
11968
12279
  if (skillsValue.toLowerCase() !== "none" && availableSkills.length > 0) {
11969
12280
  try {
11970
- const sessionEntries = _internals15.readSkillUsageEntriesTail(directory, {
12281
+ const sessionEntries = _internals16.readSkillUsageEntriesTail(directory, {
11971
12282
  sessionID
11972
12283
  });
11973
- if (sessionEntries.length > _internals15.MAX_SCORING_SESSION_ENTRIES) {
12284
+ if (sessionEntries.length > _internals16.MAX_SCORING_SESSION_ENTRIES) {
11974
12285
  scoringSkipped = true;
11975
- warn(`[skill-propagation-gate] skipping scoring \u2014 tail window has ${sessionEntries.length} session entries (limit: ${_internals15.MAX_SCORING_SESSION_ENTRIES})`);
12286
+ warn(`[skill-propagation-gate] skipping scoring \u2014 tail window has ${sessionEntries.length} session entries (limit: ${_internals16.MAX_SCORING_SESSION_ENTRIES})`);
11976
12287
  } else {
11977
12288
  const prompt = typeof input.args?.prompt === "string" ? String(input.args.prompt) : "";
11978
12289
  scored = availableSkills.map((skillPath) => {
11979
12290
  const skillEntries = sessionEntries.filter((e) => e.skillPath === skillPath);
11980
- const metadata = metadataBySkillPath.get(skillPath) ?? _internals15.readSkillMetadata(skillPath, directory);
11981
- const score = _internals15.computeSkillRelevanceScore(skillPath, prompt, skillEntries, metadata);
12291
+ const metadata = metadataBySkillPath.get(skillPath) ?? _internals16.readSkillMetadata(skillPath, directory);
12292
+ const score = _internals16.computeSkillRelevanceScore(skillPath, prompt, skillEntries, metadata);
11982
12293
  return { skillPath, score, usageCount: skillEntries.length };
11983
12294
  }).sort((a, b) => b.score - a.score || b.usageCount - a.usageCount);
11984
12295
  if (scored.length > 0) {
@@ -11992,11 +12303,11 @@ async function skillPropagationGateBefore(directory, input, config) {
11992
12303
  }
11993
12304
  }
11994
12305
  try {
11995
- const routingPaths = _internals15.loadRoutingSkills(directory, targetBase);
12306
+ const routingPaths = _internals16.loadRoutingSkills(directory, targetBase);
11996
12307
  if (routingPaths.length > 0) {
11997
12308
  const existingPaths = new Set(scored.map((s) => s.skillPath));
11998
12309
  for (const routingPath of routingPaths) {
11999
- const validation = _internals15.validateSkillReference(directory, routingPath, audienceContext, { enforceAudience: true, requireFilePrefix: false });
12310
+ const validation = _internals16.validateSkillReference(directory, routingPath, audienceContext, { enforceAudience: true, requireFilePrefix: false });
12000
12311
  if (!validation.valid || !validation.skillPath)
12001
12312
  continue;
12002
12313
  const eligibleRoutingPath = validation.skillPath;
@@ -12004,7 +12315,7 @@ async function skillPropagationGateBefore(directory, input, config) {
12004
12315
  metadataBySkillPath.set(eligibleRoutingPath, validation.metadata);
12005
12316
  }
12006
12317
  const routedSkillDir = path21.dirname(path21.join(directory, eligibleRoutingPath));
12007
- if (_internals15.existsSync(path21.join(routedSkillDir, "retired.marker")) || _internals15.existsSync(path21.join(routedSkillDir, "stale.marker")))
12318
+ if (_internals16.existsSync(path21.join(routedSkillDir, "retired.marker")) || _internals16.existsSync(path21.join(routedSkillDir, "stale.marker")))
12008
12319
  continue;
12009
12320
  if (!existingPaths.has(eligibleRoutingPath)) {
12010
12321
  scored.push({
@@ -12030,12 +12341,12 @@ async function skillPropagationGateBefore(directory, input, config) {
12030
12341
  } else if (typeof scored !== "undefined" && scored.length > 0) {
12031
12342
  skillsForIndex = scored.map((r) => r.skillPath);
12032
12343
  }
12033
- const formattedIndex = _internals15.formatSkillIndexWithContext(skillsForIndex, directory, metadataBySkillPath);
12344
+ const formattedIndex = _internals16.formatSkillIndexWithContext(skillsForIndex, directory, metadataBySkillPath);
12034
12345
  if (formattedIndex.length > 0) {
12035
12346
  const contextPath = path21.join(directory, ".swarm", "context.md");
12036
12347
  let existingContent = "";
12037
- if (_internals15.existsSync(contextPath)) {
12038
- existingContent = _internals15.readFileSync(contextPath, "utf-8");
12348
+ if (_internals16.existsSync(contextPath)) {
12349
+ existingContent = _internals16.readFileSync(contextPath, "utf-8");
12039
12350
  }
12040
12351
  const sectionHeader = "## Available Skills";
12041
12352
  const newSection = `${sectionHeader}
@@ -12055,10 +12366,10 @@ ${newSection}`;
12055
12366
  }
12056
12367
  }
12057
12368
  const swarmDir = path21.dirname(contextPath);
12058
- if (!_internals15.existsSync(swarmDir)) {
12059
- _internals15.mkdirSync(swarmDir, { recursive: true });
12369
+ if (!_internals16.existsSync(swarmDir)) {
12370
+ _internals16.mkdirSync(swarmDir, { recursive: true });
12060
12371
  }
12061
- _internals15.writeFileSync(contextPath, updatedContent, "utf-8");
12372
+ _internals16.writeFileSync(contextPath, updatedContent, "utf-8");
12062
12373
  }
12063
12374
  } catch (err) {
12064
12375
  warn(`[skill-propagation-gate] failed to write skill index to context.md: ${err instanceof Error ? err.message : String(err)}`);
@@ -12084,7 +12395,7 @@ ${newSection}`;
12084
12395
  });
12085
12396
  const warningMsg = `Skill propagation warning: Delegating to ${targetBase} without SKILLS field. ` + `Available skills: ${skillNames.join(", ")}`;
12086
12397
  try {
12087
- _internals15.writeWarnEvent(directory, {
12398
+ _internals16.writeWarnEvent(directory, {
12088
12399
  type: "skill_propagation_warn",
12089
12400
  timestamp: new Date().toISOString(),
12090
12401
  tool: toolName,
@@ -12116,17 +12427,17 @@ async function skillPropagationTransformScan(directory, output, sessionID, confi
12116
12427
  const validatedProvenancePaths = (fieldValue) => {
12117
12428
  if (remainingProvenanceValidationBudget <= 0)
12118
12429
  return [];
12119
- const references = _internals15.parseSkillPaths(fieldValue).slice(0, remainingProvenanceValidationBudget);
12430
+ const references = _internals16.parseSkillPaths(fieldValue).slice(0, remainingProvenanceValidationBudget);
12120
12431
  remainingProvenanceValidationBudget -= references.length;
12121
12432
  return references.flatMap((reference) => {
12122
- const validation = _internals15.validateSkillReference(directory, reference, audienceContext, { enforceAudience: true });
12433
+ const validation = _internals16.validateSkillReference(directory, reference, audienceContext, { enforceAudience: true });
12123
12434
  return validation.valid && validation.skillPath ? [validation.skillPath] : [];
12124
12435
  });
12125
12436
  };
12126
12437
  let dedupKeys = new Set;
12127
12438
  let existingEntries = [];
12128
12439
  try {
12129
- existingEntries = _internals15.readSkillUsageEntriesTail(directory, {
12440
+ existingEntries = _internals16.readSkillUsageEntriesTail(directory, {
12130
12441
  sessionID
12131
12442
  });
12132
12443
  dedupKeys = new Set(existingEntries.map((e, i) => {
@@ -12197,7 +12508,7 @@ async function skillPropagationTransformScan(directory, output, sessionID, confi
12197
12508
  if (isDuplicate(skillPath, "reviewer", resolvedTaskID))
12198
12509
  continue;
12199
12510
  try {
12200
- _internals15.appendSkillUsageEntry(directory, {
12511
+ _internals16.appendSkillUsageEntry(directory, {
12201
12512
  skillPath,
12202
12513
  agentName: "reviewer",
12203
12514
  taskID: resolvedTaskID,
@@ -12242,14 +12553,14 @@ async function skillPropagationTransformScan(directory, output, sessionID, confi
12242
12553
  }
12243
12554
  if (currentTargetAgent && skillsField && skillsField.toLowerCase() !== "none") {
12244
12555
  const skillPaths = validatedProvenancePaths(skillsField);
12245
- const taskId = _internals15.extractTaskIdFromPrompt(text);
12556
+ const taskId = _internals16.extractTaskIdFromPrompt(text);
12246
12557
  for (const skillPath of skillPaths) {
12247
12558
  if (hadRecordingError)
12248
12559
  break;
12249
12560
  if (isDuplicate(skillPath, currentTargetAgent, taskId))
12250
12561
  continue;
12251
12562
  try {
12252
- _internals15.appendSkillUsageEntry(directory, {
12563
+ _internals16.appendSkillUsageEntry(directory, {
12253
12564
  skillPath,
12254
12565
  agentName: currentTargetAgent,
12255
12566
  taskID: taskId,
@@ -12269,18 +12580,18 @@ async function skillPropagationTransformScan(directory, output, sessionID, confi
12269
12580
  break;
12270
12581
  }
12271
12582
  }
12272
- _internals15.skillPropagationGateBefore = skillPropagationGateBefore;
12273
- _internals15.skillPropagationTransformScan = skillPropagationTransformScan;
12274
- _internals15.writeWarnEvent = writeWarnEvent;
12275
- _internals15.discoverAvailableSkills = discoverAvailableSkills;
12276
- _internals15.parseDelegationArgs = parseDelegationArgs;
12277
- _internals15.parseSkillPaths = parseSkillPaths;
12278
- _internals15.extractFileSkillReferences = extractFileSkillReferences;
12279
- _internals15.validateSkillReference = validateSkillReference;
12280
- _internals15.extractTaskIdFromPrompt = extractTaskIdFromPrompt;
12281
- _internals15.extractSkillsFieldFromPrompt = extractSkillsFieldFromPrompt;
12282
- _internals15.formatSkillIndexWithContext = formatSkillIndexWithContext;
12283
- _internals15.loadRoutingSkills = loadRoutingSkills;
12583
+ _internals16.skillPropagationGateBefore = skillPropagationGateBefore;
12584
+ _internals16.skillPropagationTransformScan = skillPropagationTransformScan;
12585
+ _internals16.writeWarnEvent = writeWarnEvent;
12586
+ _internals16.discoverAvailableSkills = discoverAvailableSkills;
12587
+ _internals16.parseDelegationArgs = parseDelegationArgs;
12588
+ _internals16.parseSkillPaths = parseSkillPaths;
12589
+ _internals16.extractFileSkillReferences = extractFileSkillReferences;
12590
+ _internals16.validateSkillReference = validateSkillReference;
12591
+ _internals16.extractTaskIdFromPrompt = extractTaskIdFromPrompt;
12592
+ _internals16.extractSkillsFieldFromPrompt = extractSkillsFieldFromPrompt;
12593
+ _internals16.formatSkillIndexWithContext = formatSkillIndexWithContext;
12594
+ _internals16.loadRoutingSkills = loadRoutingSkills;
12284
12595
 
12285
12596
  // src/hooks/micro-reflector.ts
12286
12597
  var REFLECT_OUTCOMES = new Set([
@@ -12347,7 +12658,7 @@ function hashContent(content) {
12347
12658
  async function canonicalExistingPath(candidate) {
12348
12659
  let resolved = path23.resolve(candidate);
12349
12660
  try {
12350
- resolved = await _internals16.realpath(resolved);
12661
+ resolved = await _internals17.realpath(resolved);
12351
12662
  } catch {}
12352
12663
  return resolved;
12353
12664
  }
@@ -13128,9 +13439,9 @@ async function curateAndStoreSwarm(lessons, projectName, phaseInfo, directory, c
13128
13439
  } catch {}
13129
13440
  }
13130
13441
  if (!options?.skipAutoPromotion) {
13131
- await _internals16.runAutoPromotion(directory, config);
13442
+ await _internals17.runAutoPromotion(directory, config);
13132
13443
  if (phaseInfo.phase_number > 0) {
13133
- await _internals16.runAutoDemotion(directory, config, phaseInfo.phase_number);
13444
+ await _internals17.runAutoDemotion(directory, config, phaseInfo.phase_number);
13134
13445
  }
13135
13446
  }
13136
13447
  return { stored, reinforced, skipped, rejected, quarantined };
@@ -13245,7 +13556,7 @@ function createKnowledgeCuratorHook(directory, config, options = {}) {
13245
13556
  }
13246
13557
  inFlightEvidenceEntries.add(evidenceKey);
13247
13558
  try {
13248
- await _internals16.curateAndStoreSwarm(batch.lessons, batch.projectName, { phase_number: batch.phaseNumber }, directory, config, {
13559
+ await _internals17.curateAndStoreSwarm(batch.lessons, batch.projectName, { phase_number: batch.phaseNumber }, directory, config, {
13249
13560
  llmDelegate: options.llmDelegateFactory?.(trigger.sessionID),
13250
13561
  enrichmentQuota: options.enrichmentQuota
13251
13562
  });
@@ -13277,14 +13588,14 @@ function createKnowledgeCuratorHook(directory, config, options = {}) {
13277
13588
  const projectName = projectNameMatch ? projectNameMatch[1].trim() : "unknown";
13278
13589
  const phaseMatch = /^Phase:\s*(\d+)/m.exec(planContent);
13279
13590
  const phaseNumber = phaseMatch ? parseInt(phaseMatch[1], 10) : 1;
13280
- await _internals16.curateAndStoreSwarm(normalLessons, projectName, { phase_number: phaseNumber }, directory, config, {
13591
+ await _internals17.curateAndStoreSwarm(normalLessons, projectName, { phase_number: phaseNumber }, directory, config, {
13281
13592
  llmDelegate: options.llmDelegateFactory?.(trigger.sessionID),
13282
13593
  enrichmentQuota: options.enrichmentQuota
13283
13594
  });
13284
13595
  };
13285
13596
  return safeHook(handler);
13286
13597
  }
13287
- var _internals16 = {
13598
+ var _internals17 = {
13288
13599
  isWriteToEvidenceFile,
13289
13600
  curateAndStoreSwarm,
13290
13601
  runAutoPromotion,
@@ -13323,7 +13634,7 @@ async function runFinalizeRewardSweep(args) {
13323
13634
  return result;
13324
13635
  }
13325
13636
  const timestamp = args.timestamp ?? new Date().toISOString();
13326
- const provider = _internals17.createConfiguredMemoryProvider(directory, memoryConfig);
13637
+ const provider = _internals18.createConfiguredMemoryProvider(directory, memoryConfig);
13327
13638
  try {
13328
13639
  result.swept = true;
13329
13640
  for (const taskId of taskIds) {
@@ -13343,7 +13654,7 @@ async function runFinalizeRewardSweep(args) {
13343
13654
  }
13344
13655
  let taskRewarded = 0;
13345
13656
  for (const runId of runIds) {
13346
- const { memoriesRewarded } = await _internals17.applyCouncilReward(provider, {
13657
+ const { memoriesRewarded } = await _internals18.applyCouncilReward(provider, {
13347
13658
  runId,
13348
13659
  unitId: taskId,
13349
13660
  reward: FINALIZE_NEGATIVE_TERMINAL_REWARD,
@@ -13369,7 +13680,7 @@ async function runFinalizeRewardSweep(args) {
13369
13680
  }
13370
13681
  return result;
13371
13682
  }
13372
- var _internals17 = {
13683
+ var _internals18 = {
13373
13684
  createConfiguredMemoryProvider,
13374
13685
  applyCouncilReward
13375
13686
  };
@@ -14396,7 +14707,7 @@ async function reconcileStaleActiveSkills(directory, options = {}) {
14396
14707
  continue;
14397
14708
  }
14398
14709
  try {
14399
- const regen = await _internals18.regenerateSkill(directory, skill.slug, {
14710
+ const regen = await _internals19.regenerateSkill(directory, skill.slug, {
14400
14711
  evaluate: false
14401
14712
  });
14402
14713
  if (regen.regenerated) {
@@ -14646,7 +14957,7 @@ async function runSkillImprover(req) {
14646
14957
  autoApply
14647
14958
  };
14648
14959
  }
14649
- var _internals18 = {
14960
+ var _internals19 = {
14650
14961
  runSkillImprover,
14651
14962
  buildDeterministicProposal,
14652
14963
  buildLLMProposalFrame,
@@ -15049,13 +15360,13 @@ var write_retro = createSwarmTool({
15049
15360
  task_id: args.task_id !== undefined ? String(args.task_id) : undefined,
15050
15361
  metadata: args.metadata
15051
15362
  };
15052
- return await _internals19.executeWriteRetro(writeRetroArgs, directory);
15363
+ return await _internals20.executeWriteRetro(writeRetroArgs, directory);
15053
15364
  } catch {
15054
15365
  return JSON.stringify({ success: false, phase: rawPhase, message: "Invalid arguments" }, null, 2);
15055
15366
  }
15056
15367
  }
15057
15368
  });
15058
- var _internals19 = {
15369
+ var _internals20 = {
15059
15370
  executeWriteRetro,
15060
15371
  write_retro
15061
15372
  };
@@ -15364,8 +15675,8 @@ async function runFinalizeStage(ctx) {
15364
15675
  ];
15365
15676
  ctx.curationSucceeded = false;
15366
15677
  try {
15367
- ctx.curationResult = await _internals20.curateAndStoreSwarm(ctx.allLessons, ctx.projectName, { phase_number: 0 }, ctx.directory, ctx.config, {
15368
- llmDelegate: _internals20.createCuratorLLMDelegate(ctx.directory, "phase", ctx.options.sessionID),
15678
+ ctx.curationResult = await _internals21.curateAndStoreSwarm(ctx.allLessons, ctx.projectName, { phase_number: 0 }, ctx.directory, ctx.config, {
15679
+ llmDelegate: _internals21.createCuratorLLMDelegate(ctx.directory, "phase", ctx.options.sessionID),
15369
15680
  enrichmentQuota: {
15370
15681
  maxCalls: ctx.config.enrichment.max_calls_per_day,
15371
15682
  window: ctx.config.enrichment.quota_window
@@ -15384,7 +15695,7 @@ async function runFinalizeStage(ctx) {
15384
15695
  if (ctx.config.hive_enabled === false) {} else {
15385
15696
  try {
15386
15697
  const entries = await readKnowledge(resolveSwarmKnowledgePath(ctx.directory));
15387
- const result = await _internals20.checkHivePromotions(entries, ctx.config);
15698
+ const result = await _internals21.checkHivePromotions(entries, ctx.config);
15388
15699
  ctx.hivePromoted = result.new_promotions;
15389
15700
  } catch (hiveErr) {
15390
15701
  const msg = hiveErr instanceof Error ? hiveErr.message : String(hiveErr);
@@ -15405,7 +15716,7 @@ async function runFinalizeStage(ctx) {
15405
15716
  ctx.knowledgeSkillHint = ctx.sessionKnowledgeCreated > 0 ? `${ctx.sessionKnowledgeCreated} knowledge entries created this session. Consider running skill_improve or skill_generate to compile mature entries into skills.` : "";
15406
15717
  if (ctx.runSkillReview) {
15407
15718
  try {
15408
- const { config: loadedConfig } = _internals20.loadPluginConfigWithMeta(ctx.directory);
15719
+ const { config: loadedConfig } = _internals21.loadPluginConfigWithMeta(ctx.directory);
15409
15720
  const skillImproverConfig = SkillImproverConfigSchema.parse(loadedConfig.skill_improver ?? {});
15410
15721
  const skillReviewResult = await runAbortableSkillReview({
15411
15722
  directory: ctx.directory,
@@ -15468,7 +15779,7 @@ async function runFinalizeStage(ctx) {
15468
15779
  }
15469
15780
  if (!ctx.planAlreadyDone || ctx.guaranteeResult.closedPhaseIds.length > 0 || ctx.guaranteeResult.closedTaskIds.length > 0) {
15470
15781
  try {
15471
- await _internals20.closePlanTerminalState(ctx.directory, ctx.planData, {
15782
+ await _internals21.closePlanTerminalState(ctx.directory, ctx.planData, {
15472
15783
  closedPhaseIds: ctx.guaranteeResult.closedPhaseIds,
15473
15784
  closedTaskIds: ctx.guaranteeResult.closedTaskIds,
15474
15785
  originalStatuses: ctx.originalStatuses
@@ -15485,11 +15796,11 @@ async function runFinalizeStage(ctx) {
15485
15796
  }
15486
15797
  try {
15487
15798
  const { CuratorConfigSchema: CCS } = await import("./schema-aymfdrsb.js");
15488
- const { config: pmLoadedConfig } = _internals20.loadPluginConfigWithMeta(ctx.directory);
15799
+ const { config: pmLoadedConfig } = _internals21.loadPluginConfigWithMeta(ctx.directory);
15489
15800
  const curatorCfg = CCS.parse(pmLoadedConfig.curator ?? {});
15490
15801
  if (curatorCfg.enabled && curatorCfg.postmortem_enabled) {
15491
- const pmResult = await _internals20.runCuratorPostMortem(ctx.directory, {
15492
- llmDelegate: _internals20.createCuratorLLMDelegate(ctx.directory, "postmortem", ctx.options.sessionID),
15802
+ const pmResult = await _internals21.runCuratorPostMortem(ctx.directory, {
15803
+ llmDelegate: _internals21.createCuratorLLMDelegate(ctx.directory, "postmortem", ctx.options.sessionID),
15493
15804
  scope: "project",
15494
15805
  sessionID: ctx.options.sessionID
15495
15806
  });
@@ -15515,7 +15826,7 @@ async function copySqliteSafe(srcPath, destPath, laneEnv) {
15515
15826
  }
15516
15827
  let checkpointVerified = false;
15517
15828
  try {
15518
- const result = _internals20.spawnSync("sqlite3", [srcPath, "PRAGMA wal_checkpoint(TRUNCATE);"], {
15829
+ const result = _internals21.spawnSync("sqlite3", [srcPath, "PRAGMA wal_checkpoint(TRUNCATE);"], {
15519
15830
  cwd: path29.dirname(srcPath),
15520
15831
  encoding: "utf-8",
15521
15832
  stdio: ["ignore", "pipe", "pipe"],
@@ -15686,7 +15997,7 @@ async function runArchiveEvidenceRetention(ctx) {
15686
15997
  let maxAgeDays = 30;
15687
15998
  let maxBundles = 10;
15688
15999
  try {
15689
- const { config: evidenceLoadedConfig } = _internals20.loadPluginConfigWithMeta(ctx.directory);
16000
+ const { config: evidenceLoadedConfig } = _internals21.loadPluginConfigWithMeta(ctx.directory);
15690
16001
  const evidenceCfg = evidenceLoadedConfig.evidence ?? {};
15691
16002
  if (typeof evidenceCfg.max_age_days === "number") {
15692
16003
  maxAgeDays = evidenceCfg.max_age_days;
@@ -15696,7 +16007,7 @@ async function runArchiveEvidenceRetention(ctx) {
15696
16007
  }
15697
16008
  } catch {}
15698
16009
  try {
15699
- await _internals20.archiveEvidence(ctx.directory, maxAgeDays, maxBundles);
16010
+ await _internals21.archiveEvidence(ctx.directory, maxAgeDays, maxBundles);
15700
16011
  } catch (error2) {
15701
16012
  const msg = error2 instanceof Error ? error2.message : String(error2);
15702
16013
  ctx.warnings.push(`Evidence retention archive failed: ${msg}`);
@@ -15899,9 +16210,9 @@ async function runAlignStage(ctx) {
15899
16210
  const pruneBranches = ctx.args.includes("--prune-branches");
15900
16211
  let gitAlignResult = "";
15901
16212
  const prunedBranches = [];
15902
- const gitStatus = _internals20.getGitRepositoryStatus(ctx.directory);
16213
+ const gitStatus = _internals21.getGitRepositoryStatus(ctx.directory);
15903
16214
  if (gitStatus.isRepo) {
15904
- const aggressiveResult = await _internals20.resetToMainAfterMerge(ctx.directory, {
16215
+ const aggressiveResult = await _internals21.resetToMainAfterMerge(ctx.directory, {
15905
16216
  pruneBranches
15906
16217
  });
15907
16218
  if (aggressiveResult.success) {
@@ -15913,7 +16224,7 @@ async function runAlignStage(ctx) {
15913
16224
  ctx.warnings.push("Uncommitted changes were discarded during git alignment");
15914
16225
  }
15915
16226
  } else {
15916
- const alignResult = await _internals20.resetToRemoteBranch(ctx.directory, {
16227
+ const alignResult = await _internals21.resetToRemoteBranch(ctx.directory, {
15917
16228
  pruneBranches
15918
16229
  });
15919
16230
  gitAlignResult = alignResult.message;
@@ -15973,7 +16284,7 @@ async function handleCloseCommand(directory, args, options = {}) {
15973
16284
  let finalizeLock = {
15974
16285
  acquired: false
15975
16286
  };
15976
- finalizeLock = await _internals20.acquireFinalizeLock(directory);
16287
+ finalizeLock = await _internals21.acquireFinalizeLock(directory);
15977
16288
  if (!finalizeLock.acquired) {
15978
16289
  return `\u274C Another /swarm finalize is already running for this project. If you are certain no other run is active, wait for the lock to expire or remove the stale lock and retry.`;
15979
16290
  }
@@ -16004,7 +16315,7 @@ This project was already finalized in a previous /swarm close run. The plan has
16004
16315
  if (planExists) {
16005
16316
  planAlreadyDone = phases.length > 0 && phases.every((p) => p.status === "complete" || p.status === "completed" || p.status === "blocked" || p.status === "closed");
16006
16317
  }
16007
- const { config: loadedConfig } = _internals20.loadPluginConfigWithMeta(directory);
16318
+ const { config: loadedConfig } = _internals21.loadPluginConfigWithMeta(directory);
16008
16319
  const config = KnowledgeConfigSchema.parse(loadedConfig.knowledge ?? {});
16009
16320
  const ctx = {
16010
16321
  directory,
@@ -16048,7 +16359,7 @@ This project was already finalized in a previous /swarm close run. The plan has
16048
16359
  args
16049
16360
  };
16050
16361
  await runFinalizeStage(ctx);
16051
- await _internals20.runFinalizeRewardSweep({
16362
+ await _internals21.runFinalizeRewardSweep({
16052
16363
  directory,
16053
16364
  closedTaskIds: ctx.guaranteeResult.closedTaskIds,
16054
16365
  memoryConfig: loadedConfig.memory
@@ -16129,9 +16440,9 @@ This project was already finalized in a previous /swarm close run. The plan has
16129
16440
  }
16130
16441
  const sessionIdsToEnd = [...swarmState.agentSessions.keys()];
16131
16442
  for (const sessionId of sessionIdsToEnd) {
16132
- _internals20.endAgentSession(sessionId);
16443
+ _internals21.endAgentSession(sessionId);
16133
16444
  }
16134
- _internals20.resetSwarmStatePreservingSingletons();
16445
+ _internals21.resetSwarmStatePreservingSingletons();
16135
16446
  const retroWarnings = ctx.warnings.filter((w) => w.includes("Retrospective write") || w.includes("retrospective write") || w.includes("Session retrospective"));
16136
16447
  const otherWarnings = ctx.warnings.filter((w) => !w.includes("Retrospective write") && !w.includes("retrospective write") && !w.includes("Session retrospective"));
16137
16448
  let warningMsg = "";
@@ -16200,7 +16511,7 @@ async function acquireFinalizeLock(directory) {
16200
16511
  }
16201
16512
  return { acquired: false };
16202
16513
  }
16203
- var _internals20 = {
16514
+ var _internals21 = {
16204
16515
  ACTIVE_STATE_DIRS_TO_CLEAN,
16205
16516
  countSessionKnowledgeEntries,
16206
16517
  CLOSE_SKILL_REVIEW_TIMEOUT_MS,
@@ -16228,7 +16539,7 @@ var _internals20 = {
16228
16539
  endAgentSession,
16229
16540
  spawnSync: (cmd, args, options) => {
16230
16541
  const mergedEnv = mergeEnvForChild(options?.env, options?.envOverrides);
16231
- return child_process2.spawnSync(cmd, args, {
16542
+ return child_process3.spawnSync(cmd, args, {
16232
16543
  ...options,
16233
16544
  env: mergedEnv
16234
16545
  });
@@ -16256,7 +16567,7 @@ var MODES = new Set(CODEBASE_REVIEW_MODES);
16256
16567
  var DEFAULT_MODE = "phase0";
16257
16568
  var DEFAULT_SCOPE = "repository root";
16258
16569
  var FLAG_VALUE_MISSING = (token) => `Flag "${token}" requires a value`;
16259
- var USAGE = `Usage: /swarm codebase-review [scope] [--mode phase0|complete|defect|security|correctness|testing|ui|performance|ai-slop|enhancements|custom] [--tracks <list>] [--continue <run-id>] [--json] [--skip-update] [--allow-dirty]
16570
+ var USAGE2 = `Usage: /swarm codebase-review [scope] [--mode phase0|complete|defect|security|correctness|testing|ui|performance|ai-slop|enhancements|custom] [--tracks <list>] [--continue <run-id>] [--json] [--skip-update] [--allow-dirty]
16260
16571
 
16261
16572
  Run the codebase-review-swarm workflow in the current repository.
16262
16573
 
@@ -16349,12 +16660,12 @@ function parseArgs(args) {
16349
16660
  async function handleCodebaseReviewCommand(_directory, args) {
16350
16661
  const parsed = parseArgs(args);
16351
16662
  if (parsed.help) {
16352
- return USAGE;
16663
+ return USAGE2;
16353
16664
  }
16354
16665
  if (parsed.error) {
16355
16666
  return `Error: ${parsed.error}
16356
16667
 
16357
- ${USAGE}`;
16668
+ ${USAGE2}`;
16358
16669
  }
16359
16670
  const scope = sanitizeText(parsed.rest.join(" "), MAX_SCOPE_LEN) || DEFAULT_SCOPE;
16360
16671
  return [
@@ -16787,7 +17098,7 @@ function parseArgs2(args) {
16787
17098
  }
16788
17099
  return out;
16789
17100
  }
16790
- var USAGE2 = [
17101
+ var USAGE3 = [
16791
17102
  "Usage: /swarm council <question> [--spec-review]",
16792
17103
  "",
16793
17104
  " question The question to put to the council",
@@ -16800,7 +17111,7 @@ async function handleCouncilCommand(_directory, args) {
16800
17111
  const parsed = parseArgs2(args);
16801
17112
  const question = sanitizeQuestion(parsed.rest.join(" "));
16802
17113
  if (!question) {
16803
- return USAGE2;
17114
+ return USAGE3;
16804
17115
  }
16805
17116
  const tokens = ["MODE: COUNCIL"];
16806
17117
  if (parsed.preset) {
@@ -16818,17 +17129,17 @@ import * as fs11 from "fs";
16818
17129
  import * as path33 from "path";
16819
17130
 
16820
17131
  // src/turbo/epic/cochange-source.ts
16821
- import * as child_process4 from "child_process";
17132
+ import * as child_process5 from "child_process";
16822
17133
  import { promisify as promisify2 } from "util";
16823
17134
 
16824
17135
  // src/tools/co-change-analyzer.ts
16825
- import * as child_process3 from "child_process";
17136
+ import * as child_process4 from "child_process";
16826
17137
  import { randomUUID as randomUUID5 } from "crypto";
16827
17138
  import { readdir, readFile as readFile10, stat as stat3 } from "fs/promises";
16828
17139
  import * as path32 from "path";
16829
17140
  import { promisify } from "util";
16830
17141
  function getExecFileAsync() {
16831
- return promisify(child_process3.execFile);
17142
+ return promisify(child_process4.execFile);
16832
17143
  }
16833
17144
  async function parseGitLog(directory, maxCommits) {
16834
17145
  const commitMap = new Map;
@@ -17046,9 +17357,9 @@ async function detectDarkMatter(directory, options) {
17046
17357
  } catch {
17047
17358
  return [];
17048
17359
  }
17049
- const commitMap = await _internals21.parseGitLog(directory, maxCommitsToAnalyze);
17050
- const matrix = _internals21.buildCoChangeMatrix(commitMap, maxFilesPerCommit);
17051
- const staticEdges = await _internals21.getStaticEdges(directory);
17360
+ const commitMap = await _internals22.parseGitLog(directory, maxCommitsToAnalyze);
17361
+ const matrix = _internals22.buildCoChangeMatrix(commitMap, maxFilesPerCommit);
17362
+ const staticEdges = await _internals22.getStaticEdges(directory);
17052
17363
  const results = [];
17053
17364
  for (const entry of matrix.values()) {
17054
17365
  const key = `${entry.fileA}::${entry.fileB}`;
@@ -17164,11 +17475,11 @@ var co_change_analyzer = createSwarmTool({
17164
17475
  npmiThreshold,
17165
17476
  maxCommitsToAnalyze
17166
17477
  };
17167
- const pairs = await _internals21.detectDarkMatter(directory, options);
17168
- return _internals21.formatDarkMatterOutput(pairs);
17478
+ const pairs = await _internals22.detectDarkMatter(directory, options);
17479
+ return _internals22.formatDarkMatterOutput(pairs);
17169
17480
  }
17170
17481
  });
17171
- var _internals21 = {
17482
+ var _internals22 = {
17172
17483
  parseGitLog,
17173
17484
  buildCoChangeMatrix,
17174
17485
  getStaticEdges,
@@ -17178,14 +17489,14 @@ var _internals21 = {
17178
17489
  };
17179
17490
 
17180
17491
  // src/turbo/epic/cochange-source.ts
17181
- var execFileAsync = promisify2(child_process4.execFile);
17492
+ var execFileAsync = promisify2(child_process5.execFile);
17182
17493
  var MAX_TRACKED_DIRS = 10;
17183
17494
  var GIT_HEAD_TIMEOUT_MS = 5000;
17184
17495
  var DEFAULT_MAX_COMMITS = 500;
17185
17496
  var cache = new Map;
17186
17497
  async function readGitHead(directory) {
17187
17498
  try {
17188
- const { stdout } = await _internals22.execFile("git", ["rev-parse", "HEAD"], {
17499
+ const { stdout } = await _internals23.execFile("git", ["rev-parse", "HEAD"], {
17189
17500
  cwd: directory,
17190
17501
  timeout: GIT_HEAD_TIMEOUT_MS
17191
17502
  });
@@ -17211,9 +17522,9 @@ async function getCoChangeData(directory, options) {
17211
17522
  let entries;
17212
17523
  let commitsObserved;
17213
17524
  try {
17214
- const commitMap = await _internals22.parseGitLog(directory, maxCommits);
17525
+ const commitMap = await _internals23.parseGitLog(directory, maxCommits);
17215
17526
  commitsObserved = commitMap.size;
17216
- const matrix = _internals22.buildCoChangeMatrix(commitMap);
17527
+ const matrix = _internals23.buildCoChangeMatrix(commitMap);
17217
17528
  entries = Array.from(matrix.values());
17218
17529
  } catch {
17219
17530
  return { pairs: [], commitsObserved: 0 };
@@ -17237,10 +17548,10 @@ async function getCoChangePairs(directory, options) {
17237
17548
  const data = await getCoChangeData(directory, options);
17238
17549
  return data.pairs;
17239
17550
  }
17240
- var _internals22 = {
17551
+ var _internals23 = {
17241
17552
  execFile: execFileAsync,
17242
- parseGitLog: _internals21.parseGitLog,
17243
- buildCoChangeMatrix: _internals21.buildCoChangeMatrix
17553
+ parseGitLog: _internals22.parseGitLog,
17554
+ buildCoChangeMatrix: _internals22.buildCoChangeMatrix
17244
17555
  };
17245
17556
 
17246
17557
  // src/turbo/epic/cochange-conflict.ts
@@ -17522,7 +17833,7 @@ async function handleCouplingCommand(directory, args) {
17522
17833
 
17523
17834
  Usage: /swarm coupling [--phase <n>] [--threshold <-1..1>] [--min-co-changes <n>] [--format markdown|json] [--persist]`;
17524
17835
  }
17525
- const plan = await _internals23.loadPlanJsonOnly(directory);
17836
+ const plan = await _internals24.loadPlanJsonOnly(directory);
17526
17837
  if (plan === null) {
17527
17838
  return "No plan found at `.swarm/plan.json`. Run `/swarm plan` to create one before measuring coupling.";
17528
17839
  }
@@ -17546,7 +17857,7 @@ Usage: /swarm coupling [--phase <n>] [--threshold <-1..1>] [--min-co-changes <n>
17546
17857
  const scope = scopeFiles ?? task.files_touched ?? [];
17547
17858
  return { id: task.id, scope };
17548
17859
  });
17549
- const cochangePairs = await _internals23.getCoChangePairs(directory);
17860
+ const cochangePairs = await _internals24.getCoChangePairs(directory);
17550
17861
  const report = computeCouplingReport(tasks, cochangePairs, {
17551
17862
  npmi: parsed.threshold,
17552
17863
  minCoChanges: parsed.minCoChanges
@@ -17585,13 +17896,13 @@ _Warning: failed to persist report (${persistStatus.error})._`;
17585
17896
  }
17586
17897
  return `${formatCouplingReportMarkdown(report)}${persistTrailer}`;
17587
17898
  }
17588
- var _internals23 = {
17899
+ var _internals24 = {
17589
17900
  loadPlanJsonOnly,
17590
17901
  getCoChangePairs
17591
17902
  };
17592
17903
 
17593
17904
  // src/commands/curate.ts
17594
- var _internals24 = {
17905
+ var _internals25 = {
17595
17906
  checkHivePromotions,
17596
17907
  readKnowledge,
17597
17908
  resolveSwarmKnowledgePath,
@@ -17599,8 +17910,8 @@ var _internals24 = {
17599
17910
  loadCuratorDeps: async () => {
17600
17911
  const [{ CuratorConfigSchema }, curator, { createCuratorLLMDelegate: createCuratorLLMDelegate2 }] = await Promise.all([
17601
17912
  import("./schema-aymfdrsb.js"),
17602
- import("./curator-qshyr2tc.js"),
17603
- import("./curator-llm-factory-2xgznxyw.js")
17913
+ import("./curator-5xt89z05.js"),
17914
+ import("./curator-llm-factory-pnhvf3s3.js")
17604
17915
  ]);
17605
17916
  return { CuratorConfigSchema, curator, createCuratorLLMDelegate: createCuratorLLMDelegate2 };
17606
17917
  }
@@ -17608,15 +17919,15 @@ var _internals24 = {
17608
17919
  async function handleCurateCommand(directory, _args, options) {
17609
17920
  try {
17610
17921
  const config = KnowledgeConfigSchema.parse({});
17611
- const swarmPath = _internals24.resolveSwarmKnowledgePath(directory);
17612
- const swarmEntries = await _internals24.readKnowledge(swarmPath) ?? [];
17613
- const summary = await _internals24.checkHivePromotions(swarmEntries, config);
17922
+ const swarmPath = _internals25.resolveSwarmKnowledgePath(directory);
17923
+ const swarmEntries = await _internals25.readKnowledge(swarmPath) ?? [];
17924
+ const summary = await _internals25.checkHivePromotions(swarmEntries, config);
17614
17925
  if (options?.sessionID) {
17615
17926
  let onDemandPhase = 1;
17616
17927
  try {
17617
- const { CuratorConfigSchema, curator, createCuratorLLMDelegate: createCuratorLLMDelegate2 } = await _internals24.loadCuratorDeps();
17928
+ const { CuratorConfigSchema, curator, createCuratorLLMDelegate: createCuratorLLMDelegate2 } = await _internals25.loadCuratorDeps();
17618
17929
  const curatorConfig = CuratorConfigSchema.parse({});
17619
- const priorSummary = await _internals24.readSwarmFileAsync(directory, "curator-summary.json");
17930
+ const priorSummary = await _internals25.readSwarmFileAsync(directory, "curator-summary.json");
17620
17931
  if (priorSummary) {
17621
17932
  try {
17622
17933
  const parsed = JSON.parse(priorSummary);
@@ -17627,7 +17938,7 @@ async function handleCurateCommand(directory, _args, options) {
17627
17938
  }
17628
17939
  let planPhaseCount = Infinity;
17629
17940
  try {
17630
- const planRaw = await _internals24.readSwarmFileAsync(directory, "plan.json");
17941
+ const planRaw = await _internals25.readSwarmFileAsync(directory, "plan.json");
17631
17942
  if (planRaw) {
17632
17943
  const plan = JSON.parse(planRaw);
17633
17944
  if (Array.isArray(plan.phases))
@@ -17646,8 +17957,8 @@ async function handleCurateCommand(directory, _args, options) {
17646
17957
  summary.knowledge_skipped = applied.skipped;
17647
17958
  summary.curator_phase = onDemandPhase;
17648
17959
  try {
17649
- const updatedEntries = await _internals24.readKnowledge(swarmPath) ?? [];
17650
- const postUpdateHive = await _internals24.checkHivePromotions(updatedEntries, config);
17960
+ const updatedEntries = await _internals25.readKnowledge(swarmPath) ?? [];
17961
+ const postUpdateHive = await _internals25.checkHivePromotions(updatedEntries, config);
17651
17962
  summary.new_promotions += postUpdateHive.new_promotions;
17652
17963
  summary.encounters_incremented += postUpdateHive.encounters_incremented;
17653
17964
  summary.advancements += postUpdateHive.advancements;
@@ -17712,7 +18023,7 @@ async function handleDarkMatterCommand(directory, args) {
17712
18023
  }
17713
18024
  let pairs;
17714
18025
  try {
17715
- pairs = await _internals21.detectDarkMatter(directory, options);
18026
+ pairs = await _internals22.detectDarkMatter(directory, options);
17716
18027
  } catch (err) {
17717
18028
  const errMsg = err instanceof Error ? err.message : String(err);
17718
18029
  return `## Dark Matter Analysis Failed
@@ -17755,7 +18066,7 @@ var PROFILES = new Set([
17755
18066
  var DEFAULT_PROFILE = "standard";
17756
18067
  var DEFAULT_MAX_EXPLORERS = 6;
17757
18068
  var FULL_PROFILE_DEFAULT_MAX_EXPLORERS = 8;
17758
- var USAGE3 = `Usage: /swarm deep-dive <scope> [--profile standard|security|ux|architecture|full] [--max-explorers N] [--json] [--skip-update] [--allow-dirty]
18069
+ var USAGE4 = `Usage: /swarm deep-dive <scope> [--profile standard|security|ux|architecture|full] [--max-explorers N] [--json] [--skip-update] [--allow-dirty]
17759
18070
 
17760
18071
  Run a bounded, evidence-backed deep dive on an application section.
17761
18072
 
@@ -17844,11 +18155,11 @@ async function handleDeepDiveCommand(_directory, args) {
17844
18155
  if (parsed.error) {
17845
18156
  return `Error: ${parsed.error}
17846
18157
 
17847
- ${USAGE3}`;
18158
+ ${USAGE4}`;
17848
18159
  }
17849
18160
  const scope = sanitizeScope(parsed.rest.join(" "));
17850
18161
  if (!scope) {
17851
- return USAGE3;
18162
+ return USAGE4;
17852
18163
  }
17853
18164
  if (parsed.profile === "full" && !parsed.maxExplorersExplicit) {
17854
18165
  parsed.maxExplorers = FULL_PROFILE_DEFAULT_MAX_EXPLORERS;
@@ -17865,7 +18176,7 @@ var DEFAULT_MAX_RESEARCHERS = 3;
17865
18176
  var EXHAUSTIVE_DEFAULT_MAX_RESEARCHERS = 5;
17866
18177
  var DEFAULT_ROUNDS = 2;
17867
18178
  var EXHAUSTIVE_DEFAULT_ROUNDS = 3;
17868
- var USAGE4 = `Usage: /swarm deep-research <question> [--depth standard|exhaustive] [--max-researchers 1..6] [--rounds 1..4] [--brief]
18179
+ var USAGE5 = `Usage: /swarm deep-research <question> [--depth standard|exhaustive] [--max-researchers 1..6] [--rounds 1..4] [--brief]
17869
18180
 
17870
18181
  Run a multi-source, fact-checked deep research pass and synthesize a cited report.
17871
18182
 
@@ -17959,11 +18270,11 @@ async function handleDeepResearchCommand(_directory, args) {
17959
18270
  if (parsed.error) {
17960
18271
  return `Error: ${parsed.error}
17961
18272
 
17962
- ${USAGE4}`;
18273
+ ${USAGE5}`;
17963
18274
  }
17964
18275
  const question = sanitizeQuestion2(parsed.rest.join(" "));
17965
18276
  if (!question) {
17966
- return USAGE4;
18277
+ return USAGE5;
17967
18278
  }
17968
18279
  if (parsed.depth === "exhaustive") {
17969
18280
  if (!parsed.maxResearchersExplicit)
@@ -17976,7 +18287,7 @@ ${USAGE4}`;
17976
18287
 
17977
18288
  // src/commands/design-docs.ts
17978
18289
  var MAX_DESC_LEN = 2000;
17979
- var USAGE5 = `Usage: /swarm design-docs <description> [--out <dir>] [--lang <name>] [--update]
18290
+ var USAGE6 = `Usage: /swarm design-docs <description> [--out <dir>] [--lang <name>] [--update]
17980
18291
 
17981
18292
  Generate or sync language-agnostic design docs for the project under build:
17982
18293
  <out>/domain.md, <out>/technical-spec.md, <out>/behavior-spec.md,
@@ -18068,35 +18379,35 @@ async function handleDesignDocsCommand(directory, args) {
18068
18379
  if (parsed.error) {
18069
18380
  return `Error: ${parsed.error}
18070
18381
 
18071
- ${USAGE5}`;
18382
+ ${USAGE6}`;
18072
18383
  }
18073
18384
  try {
18074
18385
  const { config } = loadPluginConfigWithMeta(directory);
18075
18386
  if (config.design_docs?.enabled !== true) {
18076
18387
  return "Error: design docs are disabled. Set `design_docs.enabled: true` in " + `opencode-swarm.json to enable the docs_design agent and this command.
18077
18388
 
18078
- ` + USAGE5;
18389
+ ` + USAGE6;
18079
18390
  }
18080
18391
  } catch (configErr) {
18081
18392
  console.warn(`[design-docs] Could not read opencode-swarm.json (${String(configErr)}). ` + "Falling through \u2014 the architect will abort if docs_design is not registered.");
18082
18393
  }
18083
18394
  const description = sanitizeDescription(parsed.rest.join(" "));
18084
18395
  if (!description && !parsed.update) {
18085
- return USAGE5;
18396
+ return USAGE6;
18086
18397
  }
18087
18398
  const header = `[MODE: DESIGN_DOCS out=${parsed.out} lang=${parsed.lang} update=${parsed.update}] ${description}`;
18088
18399
  return header.trimEnd();
18089
18400
  }
18090
18401
 
18091
18402
  // src/services/diagnose-service.ts
18092
- import * as child_process5 from "child_process";
18403
+ import * as child_process6 from "child_process";
18093
18404
  import { existsSync as existsSync23, readdirSync as readdirSync4, readFileSync as readFileSync10, statSync as statSync6 } from "fs";
18094
18405
  import * as path36 from "path";
18095
18406
  import { fileURLToPath } from "url";
18096
18407
  // package.json
18097
18408
  var package_default = {
18098
18409
  name: "opencode-swarm",
18099
- version: "7.114.7",
18410
+ version: "7.114.9",
18100
18411
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
18101
18412
  main: "dist/index.js",
18102
18413
  types: "dist/index.d.ts",
@@ -18548,7 +18859,7 @@ function resolveCachePackageRoot(cachePath) {
18548
18859
  const nestedPackageRoot = path36.join(cachePath, "node_modules", "opencode-swarm");
18549
18860
  return existsSync23(nestedPackageRoot) ? nestedPackageRoot : cachePath;
18550
18861
  }
18551
- var _internals25 = {
18862
+ var _internals26 = {
18552
18863
  detectSandboxCapability: () => sandboxCapabilityProbe.detect(),
18553
18864
  getSandboxExecutor: getExecutor
18554
18865
  };
@@ -18804,7 +19115,7 @@ async function checkGitRepository(directory) {
18804
19115
  detail: "Invalid directory \u2014 cannot check git status"
18805
19116
  };
18806
19117
  }
18807
- child_process5.execSync("git rev-parse --git-dir", {
19118
+ child_process6.execSync("git rev-parse --git-dir", {
18808
19119
  cwd: directory,
18809
19120
  stdio: "pipe"
18810
19121
  });
@@ -19132,9 +19443,9 @@ async function checkCurator(directory) {
19132
19443
  }
19133
19444
  async function getSandboxStatus() {
19134
19445
  try {
19135
- const capability = await _internals25.detectSandboxCapability();
19446
+ const capability = await _internals26.detectSandboxCapability();
19136
19447
  const mechanism = capability.mechanism ?? "none";
19137
- const executor = await _internals25.getSandboxExecutor();
19448
+ const executor = await _internals26.getSandboxExecutor();
19138
19449
  const hasExecutor = executor !== null;
19139
19450
  if (hasExecutor) {
19140
19451
  const executorStrength = executor?.strength;
@@ -19886,7 +20197,7 @@ function readPromotionEvidence(directory) {
19886
20197
  }
19887
20198
 
19888
20199
  // src/commands/epic.ts
19889
- var _internals26 = {
20200
+ var _internals27 = {
19890
20201
  loadPluginConfigWithMeta,
19891
20202
  loadPlanJsonOnly,
19892
20203
  getCoChangeData,
@@ -19908,7 +20219,7 @@ async function handleEpicCommand(directory, args, sessionID) {
19908
20219
  if (!sessionID || sessionID.trim() === "") {
19909
20220
  return "Error: No active session context. Epic Mode requires an active session. Use /swarm epic from within an OpenCode session.";
19910
20221
  }
19911
- const session = _internals26.ensureAgentSession(sessionID, undefined, directory);
20222
+ const session = _internals27.ensureAgentSession(sessionID, undefined, directory);
19912
20223
  const arg0 = args[0]?.toLowerCase();
19913
20224
  switch (arg0) {
19914
20225
  case "status":
@@ -19935,7 +20246,7 @@ Usage:
19935
20246
  }
19936
20247
  function enableAndAck(directory, sessionID, session) {
19937
20248
  try {
19938
- _internals26.enableEpicMode(directory, sessionID);
20249
+ _internals27.enableEpicMode(directory, sessionID);
19939
20250
  } catch (err) {
19940
20251
  return `Error enabling Epic Mode: ${err instanceof Error ? err.message : String(err)}`;
19941
20252
  }
@@ -19951,7 +20262,7 @@ function enableAndAck(directory, sessionID, session) {
19951
20262
  }
19952
20263
  function disableAndAck(directory, sessionID, session) {
19953
20264
  try {
19954
- _internals26.disableEpicMode(directory, sessionID);
20265
+ _internals27.disableEpicMode(directory, sessionID);
19955
20266
  } catch (err) {
19956
20267
  return `Error disabling Epic Mode: ${err instanceof Error ? err.message : String(err)}`;
19957
20268
  }
@@ -19960,12 +20271,12 @@ function disableAndAck(directory, sessionID, session) {
19960
20271
  }
19961
20272
  function renderStatus(directory, sessionID) {
19962
20273
  const lines = ["## Epic Mode \u2014 Status", ""];
19963
- if (_internals26.isStateUnreadable(directory)) {
20274
+ if (_internals27.isStateUnreadable(directory)) {
19964
20275
  lines.push("**Epic Mode state is unreadable** (`.swarm/epic-state.json` is corrupt or has an unexpected shape). Status cannot be reported until the file is repaired or removed. The fail-closed marker means `epic_decide_phase` will refuse to compute a verdict in this state.");
19965
20276
  return lines.join(`
19966
20277
  `);
19967
20278
  }
19968
- const state = _internals26.loadEpicSessionState(directory, sessionID);
20279
+ const state = _internals27.loadEpicSessionState(directory, sessionID);
19969
20280
  if (!state) {
19970
20281
  lines.push("Epic Mode has not been toggled for this session.");
19971
20282
  return lines.join(`
@@ -20017,7 +20328,7 @@ function formatGreenfieldDetail(input) {
20017
20328
  function renderLast(directory) {
20018
20329
  let records;
20019
20330
  try {
20020
- records = _internals26.readPromotionEvidence(directory);
20331
+ records = _internals27.readPromotionEvidence(directory);
20021
20332
  } catch (err) {
20022
20333
  return `Error reading epic-promotions.jsonl: ${err instanceof Error ? err.message : String(err)}`;
20023
20334
  }
@@ -20072,7 +20383,7 @@ function renderLast(directory) {
20072
20383
  `);
20073
20384
  }
20074
20385
  function renderCalibration(directory) {
20075
- if (_internals26.isCalibrationStateUnreadable(directory)) {
20386
+ if (_internals27.isCalibrationStateUnreadable(directory)) {
20076
20387
  return [
20077
20388
  "## Epic Mode \u2014 Calibration",
20078
20389
  "",
@@ -20084,11 +20395,11 @@ function renderCalibration(directory) {
20084
20395
  }
20085
20396
  let state;
20086
20397
  try {
20087
- state = _internals26.loadCalibrationState(directory);
20398
+ state = _internals27.loadCalibrationState(directory);
20088
20399
  } catch (err) {
20089
20400
  return `Error reading calibration state: ${err instanceof Error ? err.message : String(err)}`;
20090
20401
  }
20091
- const { config } = _internals26.loadPluginConfigWithMeta(directory);
20402
+ const { config } = _internals27.loadPluginConfigWithMeta(directory);
20092
20403
  const staticThreshold = config.turbo?.epic?.mode?.activation_threshold ?? 0.3;
20093
20404
  const calibrationCfg = config.turbo?.epic?.calibration;
20094
20405
  const loosenWindow = calibrationCfg?.loosen_window ?? 10;
@@ -20136,7 +20447,7 @@ function renderCalibration(directory) {
20136
20447
  lines.push("");
20137
20448
  let recentDivergent = [];
20138
20449
  try {
20139
- const all = _internals26.readDivergenceHistory(directory, { limit: 50 });
20450
+ const all = _internals27.readDivergenceHistory(directory, { limit: 50 });
20140
20451
  recentDivergent = all.filter((r) => !r.isClean).slice(-5);
20141
20452
  } catch {}
20142
20453
  lines.push("### Recent divergent tasks (tightened the threshold)");
@@ -20153,11 +20464,11 @@ function renderCalibration(directory) {
20153
20464
  `);
20154
20465
  }
20155
20466
  async function renderDecide(directory) {
20156
- const plan = await _internals26.loadPlanJsonOnly(directory);
20467
+ const plan = await _internals27.loadPlanJsonOnly(directory);
20157
20468
  if (!plan) {
20158
20469
  return "No plan found at `.swarm/plan.json`. Run `/swarm plan` first.";
20159
20470
  }
20160
- const { config } = _internals26.loadPluginConfigWithMeta(directory);
20471
+ const { config } = _internals27.loadPluginConfigWithMeta(directory);
20161
20472
  const modeCfg = config.turbo?.epic?.mode;
20162
20473
  const cochangeCfg = config.turbo?.epic?.cochange;
20163
20474
  const activationThreshold = modeCfg?.activation_threshold ?? 0.3;
@@ -20167,20 +20478,20 @@ async function renderDecide(directory) {
20167
20478
  const tasks = [];
20168
20479
  for (const phase of plan.phases) {
20169
20480
  for (const task of phase.tasks) {
20170
- const scopeFiles = _internals26.readTaskScopes(directory, task.id);
20481
+ const scopeFiles = _internals27.readTaskScopes(directory, task.id);
20171
20482
  const scope = scopeFiles ?? task.files_touched ?? [];
20172
20483
  tasks.push({ id: task.id, scope });
20173
20484
  }
20174
20485
  }
20175
- const { pairs, commitsObserved } = await _internals26.getCoChangeData(directory);
20486
+ const { pairs, commitsObserved } = await _internals27.getCoChangeData(directory);
20176
20487
  const isGitProject = (() => {
20177
20488
  try {
20178
- return _internals26.isGitRepo(directory);
20489
+ return _internals27.isGitRepo(directory);
20179
20490
  } catch {
20180
20491
  return false;
20181
20492
  }
20182
20493
  })();
20183
- const verdict = _internals26.decideEpicActivation(tasks, pairs, commitsObserved, {
20494
+ const verdict = _internals27.decideEpicActivation(tasks, pairs, commitsObserved, {
20184
20495
  activationThreshold,
20185
20496
  minCommitsForSignal,
20186
20497
  cochangeNpmiThreshold,
@@ -20224,7 +20535,7 @@ function formatVerdict(verdict) {
20224
20535
  }
20225
20536
 
20226
20537
  // src/services/evidence-service.ts
20227
- var _internals27 = {
20538
+ var _internals28 = {
20228
20539
  loadEvidence,
20229
20540
  listEvidenceTaskIds
20230
20541
  };
@@ -20269,7 +20580,7 @@ function getVerdictEmoji(verdict) {
20269
20580
  return getVerdictIcon(verdict);
20270
20581
  }
20271
20582
  async function getTaskEvidenceData(directory, taskId) {
20272
- const result = await _internals27.loadEvidence(directory, taskId);
20583
+ const result = await _internals28.loadEvidence(directory, taskId);
20273
20584
  if (result.status !== "found") {
20274
20585
  return {
20275
20586
  hasEvidence: false,
@@ -20292,13 +20603,13 @@ async function getTaskEvidenceData(directory, taskId) {
20292
20603
  };
20293
20604
  }
20294
20605
  async function getEvidenceListData(directory) {
20295
- const taskIds = await _internals27.listEvidenceTaskIds(directory);
20606
+ const taskIds = await _internals28.listEvidenceTaskIds(directory);
20296
20607
  if (taskIds.length === 0) {
20297
20608
  return { hasEvidence: false, tasks: [] };
20298
20609
  }
20299
20610
  const tasks = [];
20300
20611
  for (const taskId of taskIds) {
20301
- const result = await _internals27.loadEvidence(directory, taskId);
20612
+ const result = await _internals28.loadEvidence(directory, taskId);
20302
20613
  if (result.status === "found") {
20303
20614
  tasks.push({
20304
20615
  taskId,
@@ -20378,7 +20689,7 @@ async function handleEvidenceCommand(directory, args) {
20378
20689
  return formatTaskEvidenceMarkdown(evidenceData);
20379
20690
  }
20380
20691
  async function handleEvidenceSummaryCommand(directory) {
20381
- const { buildEvidenceSummary } = await import("./evidence-summary-service-8g594znj.js");
20692
+ const { buildEvidenceSummary } = await import("./evidence-summary-service-fehwj116.js");
20382
20693
  const artifact = await buildEvidenceSummary(directory);
20383
20694
  if (!artifact) {
20384
20695
  return "No plan found. Run `/swarm plan` to check plan status.";
@@ -20926,7 +21237,7 @@ function extractCurrentPhaseFromPlan(plan) {
20926
21237
  if (!plan) {
20927
21238
  return { currentPhase: null, currentTask: null, incompleteTasks: [] };
20928
21239
  }
20929
- if (!_internals28.validatePlanPhases(plan)) {
21240
+ if (!_internals29.validatePlanPhases(plan)) {
20930
21241
  return { currentPhase: null, currentTask: null, incompleteTasks: [] };
20931
21242
  }
20932
21243
  let currentPhase = null;
@@ -21068,9 +21379,9 @@ function extractPhaseMetrics(content) {
21068
21379
  async function getHandoffData(directory) {
21069
21380
  const now = new Date().toISOString();
21070
21381
  const sessionContent = await readSwarmFileAsync(directory, "session/state.json");
21071
- const sessionState = _internals28.parseSessionState(sessionContent);
21382
+ const sessionState = _internals29.parseSessionState(sessionContent);
21072
21383
  const plan = await loadPlanJsonOnly(directory);
21073
- const planInfo = _internals28.extractCurrentPhaseFromPlan(plan);
21384
+ const planInfo = _internals29.extractCurrentPhaseFromPlan(plan);
21074
21385
  if (!plan) {
21075
21386
  const planMdContent = await readSwarmFileAsync(directory, "plan.md");
21076
21387
  if (planMdContent) {
@@ -21089,8 +21400,8 @@ async function getHandoffData(directory) {
21089
21400
  }
21090
21401
  }
21091
21402
  const contextContent = await readSwarmFileAsync(directory, "context.md");
21092
- const recentDecisions = _internals28.extractDecisions(contextContent);
21093
- const rawPhaseMetrics = _internals28.extractPhaseMetrics(contextContent);
21403
+ const recentDecisions = _internals29.extractDecisions(contextContent);
21404
+ const rawPhaseMetrics = _internals29.extractPhaseMetrics(contextContent);
21094
21405
  const phaseMetrics = sanitizeString(rawPhaseMetrics, 1000);
21095
21406
  let delegationState = null;
21096
21407
  if (sessionState?.delegationState) {
@@ -21254,7 +21565,7 @@ ${lines.join(`
21254
21565
  `)}
21255
21566
  \`\`\``;
21256
21567
  }
21257
- var _internals28 = {
21568
+ var _internals29 = {
21258
21569
  getHandoffData,
21259
21570
  formatHandoffMarkdown,
21260
21571
  formatContinuationPrompt,
@@ -21403,15 +21714,15 @@ async function writeSnapshot(directory, state) {
21403
21714
  }
21404
21715
  function createSnapshotWriterHook(directory) {
21405
21716
  return (_input, _output) => {
21406
- _writeInFlight = _writeInFlight.then(() => _internals29.writeSnapshot(directory, swarmState), () => _internals29.writeSnapshot(directory, swarmState));
21717
+ _writeInFlight = _writeInFlight.then(() => _internals30.writeSnapshot(directory, swarmState), () => _internals30.writeSnapshot(directory, swarmState));
21407
21718
  return _writeInFlight;
21408
21719
  };
21409
21720
  }
21410
21721
  async function flushPendingSnapshot(directory) {
21411
- _writeInFlight = _writeInFlight.then(() => _internals29.writeSnapshot(directory, swarmState), () => _internals29.writeSnapshot(directory, swarmState));
21722
+ _writeInFlight = _writeInFlight.then(() => _internals30.writeSnapshot(directory, swarmState), () => _internals30.writeSnapshot(directory, swarmState));
21412
21723
  await _writeInFlight;
21413
21724
  }
21414
- var _internals29 = {
21725
+ var _internals30 = {
21415
21726
  writeSnapshot,
21416
21727
  createSnapshotWriterHook,
21417
21728
  flushPendingSnapshot
@@ -21608,184 +21919,8 @@ async function handleHistoryCommand(directory, _args) {
21608
21919
  const historyData = await getHistoryData(directory);
21609
21920
  return formatHistoryMarkdown(historyData);
21610
21921
  }
21611
- // src/commands/_shared/url-security.ts
21612
- import * as child_process6 from "child_process";
21613
- var MAX_URL_LEN = 2048;
21614
- var IPV4_PRIVATE = /^10\./;
21615
- var IPV4_LOOPBACK = /^127\./;
21616
- var IPV4_LINK_LOCAL = /^169\.254\./;
21617
- var IPV4_PRIVATE_172 = /^172\.(1[6-9]|2\d|3[0-1])\./;
21618
- var IPV4_PRIVATE_192 = /^192\.168\./;
21619
- var IPV4_ZERO_NETWORK = /^0\./;
21620
- var IPV6_LINK_LOCAL = /^fe80:/i;
21621
- var IPV6_UNIQUE_LOCAL = /^f[cd][0-9a-f]{2}:/i;
21622
- var _internals30 = {
21623
- spawnSync: (cmd, args, options) => {
21624
- const mergedEnv = mergeEnvForChild(options?.env, options?.envOverrides);
21625
- return child_process6.spawnSync(cmd, args, {
21626
- ...options,
21627
- env: mergedEnv
21628
- });
21629
- }
21630
- };
21631
- function sanitizeUrl(raw) {
21632
- let urlStr = raw.trim();
21633
- urlStr = urlStr.replace(/\[\s*MODE\s*:[^\]]*\]/gi, "");
21634
- const fragmentIdx = urlStr.indexOf("#");
21635
- if (fragmentIdx !== -1) {
21636
- urlStr = urlStr.slice(0, fragmentIdx);
21637
- }
21638
- const queryIdx = urlStr.indexOf("?");
21639
- if (queryIdx !== -1) {
21640
- urlStr = urlStr.slice(0, queryIdx);
21641
- }
21642
- urlStr = urlStr.replace(/^[A-Za-z][A-Za-z0-9+.-]*:\/\/[^@/]+@/, "https://");
21643
- if (urlStr.length > MAX_URL_LEN) {
21644
- urlStr = urlStr.slice(0, MAX_URL_LEN);
21645
- }
21646
- return urlStr.trim();
21647
- }
21648
- function sanitizeErrorEcho(raw, maxLength = 80) {
21649
- let stripped = "";
21650
- for (const ch of raw) {
21651
- const cp = ch.codePointAt(0);
21652
- if (cp !== undefined && (cp <= 31 || cp === 127)) {
21653
- stripped += " ";
21654
- continue;
21655
- }
21656
- stripped += ch;
21657
- }
21658
- const collapsed = stripped.replace(/\s+/g, " ").trim();
21659
- if (collapsed.length <= maxLength)
21660
- return collapsed;
21661
- return `${collapsed.slice(0, maxLength)}\u2026`;
21662
- }
21663
- function containsControlCharacters(value) {
21664
- for (const ch of value) {
21665
- const cp = ch.codePointAt(0);
21666
- if (cp !== undefined && (cp <= 31 || cp === 127)) {
21667
- return true;
21668
- }
21669
- }
21670
- return false;
21671
- }
21672
- function hasNonAsciiHostname(hostname) {
21673
- for (const ch of hostname) {
21674
- const cp = ch.codePointAt(0);
21675
- if (cp !== undefined && cp > 127)
21676
- return true;
21677
- }
21678
- return false;
21679
- }
21680
- function isIpv4MappedPrivateHost(inner) {
21681
- if (IPV4_PRIVATE.test(inner) || IPV4_LOOPBACK.test(inner) || IPV4_LINK_LOCAL.test(inner) || IPV4_PRIVATE_172.test(inner) || IPV4_PRIVATE_192.test(inner) || IPV4_ZERO_NETWORK.test(inner)) {
21682
- return true;
21683
- }
21684
- const firstSegment = inner.split(":", 1)[0];
21685
- if (!firstSegment)
21686
- return false;
21687
- const firstWord = Number.parseInt(firstSegment, 16);
21688
- if (!Number.isFinite(firstWord))
21689
- return false;
21690
- return firstWord >= 0 && firstWord <= 255 || firstWord >= 2560 && firstWord <= 2815 || firstWord >= 32512 && firstWord <= 32767 || firstWord === 43518 || firstWord >= 44048 && firstWord <= 44063 || firstWord === 49320;
21691
- }
21692
- function isPrivateHost(url) {
21693
- const host = url.hostname.toLowerCase().replace(/^\[|\]$/g, "");
21694
- if (host === "localhost" || host === "::1" || host === "0.0.0.0" || IPV4_LOOPBACK.test(host) || IPV4_ZERO_NETWORK.test(host)) {
21695
- return true;
21696
- }
21697
- if (host.startsWith("localhost") || host === "localhost.com") {
21698
- return true;
21699
- }
21700
- if (IPV4_PRIVATE.test(host) || IPV4_LINK_LOCAL.test(host) || IPV4_PRIVATE_172.test(host) || IPV4_PRIVATE_192.test(host) || IPV6_LINK_LOCAL.test(host) || IPV6_UNIQUE_LOCAL.test(host)) {
21701
- return true;
21702
- }
21703
- if (host.startsWith("::ffff:")) {
21704
- const inner = host.slice(7);
21705
- if (isIpv4MappedPrivateHost(inner)) {
21706
- return true;
21707
- }
21708
- }
21709
- return false;
21710
- }
21711
- function validateAndSanitizeGithubUrl(rawUrl, resource) {
21712
- const sanitized = sanitizeUrl(rawUrl);
21713
- if (!sanitized) {
21714
- return { error: "Empty URL" };
21715
- }
21716
- if (!sanitized.startsWith("https://")) {
21717
- return { error: "URL must use HTTPS scheme" };
21718
- }
21719
- try {
21720
- const url = new URL(sanitized);
21721
- if (hasNonAsciiHostname(url.hostname)) {
21722
- return { error: "Non-ASCII hostnames are not allowed" };
21723
- }
21724
- if (isPrivateHost(url)) {
21725
- return { error: "Private or localhost URLs are not allowed" };
21726
- }
21727
- const githubPattern = new RegExp(`^https:\\/\\/github\\.com\\/([^/]+)\\/([^/]+)\\/${resource}\\/([0-9]+)\\/?$`);
21728
- if (!githubPattern.test(sanitized)) {
21729
- return {
21730
- error: resource === "issues" ? "URL must be a GitHub issue URL (https://github.com/owner/repo/issues/N)" : "URL must be a GitHub pull request URL (https://github.com/owner/repo/pull/N)"
21731
- };
21732
- }
21733
- return { sanitized };
21734
- } catch {
21735
- return { error: "Invalid URL format" };
21736
- }
21737
- }
21738
- function detectGitRemote(cwd, laneEnv) {
21739
- try {
21740
- const result = _internals30.spawnSync("git", ["remote", "get-url", "origin"], {
21741
- encoding: "utf-8",
21742
- stdio: ["ignore", "pipe", "pipe"],
21743
- timeout: 5000,
21744
- ...cwd ? { cwd } : {},
21745
- envOverrides: laneEnv
21746
- });
21747
- if (result.status !== 0 || result.error) {
21748
- return null;
21749
- }
21750
- const remoteUrl = (result.stdout ?? "").trim();
21751
- return remoteUrl || null;
21752
- } catch {
21753
- return null;
21754
- }
21755
- }
21756
- function parseGitRemoteUrl(remoteUrl) {
21757
- const httpsMatch = remoteUrl.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?\/?$/i);
21758
- if (httpsMatch) {
21759
- const owner = httpsMatch[1];
21760
- const repo = httpsMatch[2].replace(/\.git$/, "");
21761
- if (containsControlCharacters(owner) || containsControlCharacters(repo)) {
21762
- return null;
21763
- }
21764
- return { owner, repo };
21765
- }
21766
- const sshMatch = remoteUrl.match(/^git@github\.com:([^/]+)\/([^/]+?)(?:\.git)?$/i);
21767
- if (sshMatch) {
21768
- const owner = sshMatch[1];
21769
- const repo = sshMatch[2].replace(/\.git$/, "");
21770
- if (containsControlCharacters(owner) || containsControlCharacters(repo)) {
21771
- return null;
21772
- }
21773
- return { owner, repo };
21774
- }
21775
- const pathMatch = remoteUrl.match(/\/([^/]+)\/([^/]+?)(?:\.git)?\/?$/);
21776
- if (pathMatch) {
21777
- const owner = pathMatch[1];
21778
- const repo = pathMatch[2].replace(/\.git$/, "");
21779
- if (containsControlCharacters(owner) || containsControlCharacters(repo)) {
21780
- return null;
21781
- }
21782
- return { owner, repo };
21783
- }
21784
- return null;
21785
- }
21786
-
21787
21922
  // src/commands/issue.ts
21788
- var USAGE6 = [
21923
+ var USAGE7 = [
21789
21924
  "Usage: /swarm issue <url|owner/repo#N|N> [--plan] [--trace] [--no-repro]",
21790
21925
  "",
21791
21926
  "Ingest a GitHub issue into the swarm workflow.",
@@ -21800,7 +21935,7 @@ var USAGE6 = [
21800
21935
  " --no-repro Skip reproduction step"
21801
21936
  ].join(`
21802
21937
  `);
21803
- function validateAndSanitizeUrl(rawUrl) {
21938
+ function validateAndSanitizeUrl2(rawUrl) {
21804
21939
  return validateAndSanitizeGithubUrl(rawUrl, "issues");
21805
21940
  }
21806
21941
  function parseArgs7(args) {
@@ -21874,21 +22009,21 @@ function handleIssueCommand(directory, args) {
21874
22009
  const parsed = parseArgs7(args);
21875
22010
  const rawInput = parsed.rest.join(" ").trim();
21876
22011
  if (!rawInput) {
21877
- return USAGE6;
22012
+ return USAGE7;
21878
22013
  }
21879
22014
  const isFullUrl = /^https?:\/\//i.test(rawInput);
21880
22015
  const issueInfo = parseIssueRef(isFullUrl ? sanitizeUrl(rawInput) : rawInput, directory);
21881
22016
  if (!issueInfo) {
21882
22017
  return `Error: Could not parse issue reference from "${sanitizeErrorEcho(rawInput)}"
21883
22018
 
21884
- ${USAGE6}`;
22019
+ ${USAGE7}`;
21885
22020
  }
21886
22021
  const issueUrl = `https://github.com/${issueInfo.owner}/${issueInfo.repo}/issues/${issueInfo.number}`;
21887
- const result = validateAndSanitizeUrl(issueUrl);
22022
+ const result = validateAndSanitizeUrl2(issueUrl);
21888
22023
  if ("error" in result) {
21889
22024
  return `Error: ${result.error}
21890
22025
 
21891
- ${USAGE6}`;
22026
+ ${USAGE7}`;
21892
22027
  }
21893
22028
  const flags = [];
21894
22029
  if (parsed.plan)
@@ -22957,7 +23092,7 @@ async function readLatestLoopState(directory) {
22957
23092
  var _internals33 = {
22958
23093
  readLatestLoopState
22959
23094
  };
22960
- var USAGE7 = `Usage: /swarm loop <objective> [--max-cycles 1..5] [--autonomy checkpoint|auto] [--depth standard|exhaustive] [--resume]
23095
+ var USAGE8 = `Usage: /swarm loop <objective> [--max-cycles 1..5] [--autonomy checkpoint|auto] [--depth standard|exhaustive] [--resume]
22961
23096
 
22962
23097
  Run a compound-engineering loop: brainstorm \u2192 plan \u2192 build \u2192 review \u2192 improve,
22963
23098
  iterating until the objective is met or a budget stop condition fires.
@@ -23059,11 +23194,11 @@ async function handleLoopCommand(_directory, args) {
23059
23194
  if (parsed.error) {
23060
23195
  return `Error: ${parsed.error}
23061
23196
 
23062
- ${USAGE7}`;
23197
+ ${USAGE8}`;
23063
23198
  }
23064
23199
  const objective = sanitizeObjective(parsed.rest.join(" "));
23065
23200
  if (!objective && !parsed.resume) {
23066
- return USAGE7;
23201
+ return USAGE8;
23067
23202
  }
23068
23203
  let autonomy = parsed.autonomy;
23069
23204
  if (parsed.resume && !parsed.autonomyExplicit) {
@@ -24234,85 +24369,6 @@ async function handlePostMortemCommand(directory, args, options) {
24234
24369
  }
24235
24370
  }
24236
24371
 
24237
- // src/commands/pr-ref.ts
24238
- var MAX_INSTRUCTIONS_LEN = 1000;
24239
- function sanitizeInstructions(raw) {
24240
- const collapsed = raw.replace(/\s+/g, " ").trim();
24241
- const stripped = collapsed.replace(/\[\s*MODE\s*:[^\]]*\]/gi, "");
24242
- const normalized = stripped.replace(/\s+/g, " ").trim();
24243
- if (normalized.length <= MAX_INSTRUCTIONS_LEN)
24244
- return normalized;
24245
- return `${normalized.slice(0, MAX_INSTRUCTIONS_LEN)}\u2026`;
24246
- }
24247
- function validateAndSanitizeUrl2(rawUrl) {
24248
- return validateAndSanitizeGithubUrl(rawUrl, "pull");
24249
- }
24250
- function parsePrRef(input, cwd) {
24251
- const urlMatch = input.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+)\/pull\/(\d+)\/?$/i);
24252
- if (urlMatch) {
24253
- if (containsControlCharacters(urlMatch[1]) || containsControlCharacters(urlMatch[2])) {
24254
- return null;
24255
- }
24256
- return {
24257
- owner: urlMatch[1],
24258
- repo: urlMatch[2],
24259
- number: parseInt(urlMatch[3], 10)
24260
- };
24261
- }
24262
- const shorthandMatch = input.match(/^([^/]+)\/([^#]+)#(\d+)$/);
24263
- if (shorthandMatch) {
24264
- if (containsControlCharacters(shorthandMatch[1]) || containsControlCharacters(shorthandMatch[2])) {
24265
- return null;
24266
- }
24267
- return {
24268
- owner: shorthandMatch[1],
24269
- repo: shorthandMatch[2],
24270
- number: parseInt(shorthandMatch[3], 10)
24271
- };
24272
- }
24273
- const bareMatch = input.match(/^(\d+)$/);
24274
- if (bareMatch) {
24275
- const prNumber = parseInt(bareMatch[1], 10);
24276
- const remoteUrl = detectGitRemote(cwd, undefined);
24277
- if (!remoteUrl) {
24278
- return null;
24279
- }
24280
- const parsed = parseGitRemoteUrl(remoteUrl);
24281
- if (!parsed) {
24282
- return null;
24283
- }
24284
- return {
24285
- owner: parsed.owner,
24286
- repo: parsed.repo,
24287
- number: prNumber
24288
- };
24289
- }
24290
- return null;
24291
- }
24292
- function looksLikePrRef(token) {
24293
- return /^https?:\/\//i.test(token) || /^[^/]+\/[^#]+#\d+$/.test(token) || /^\d+$/.test(token);
24294
- }
24295
- function resolvePrCommandInput(rest, cwd) {
24296
- if (rest.length === 0) {
24297
- return null;
24298
- }
24299
- const refToken = rest[0];
24300
- const instructions = sanitizeInstructions(rest.slice(1).join(" "));
24301
- const isFullUrl = /^https?:\/\//i.test(refToken);
24302
- const prInfo = parsePrRef(isFullUrl ? sanitizeUrl(refToken) : refToken, cwd);
24303
- if (!prInfo) {
24304
- return {
24305
- error: `Could not parse PR reference from "${sanitizeErrorEcho(refToken)}"`
24306
- };
24307
- }
24308
- const prUrl = `https://github.com/${prInfo.owner}/${prInfo.repo}/pull/${prInfo.number}`;
24309
- const result = validateAndSanitizeUrl2(prUrl);
24310
- if ("error" in result) {
24311
- return { error: result.error };
24312
- }
24313
- return { prUrl: result.sanitized, instructions };
24314
- }
24315
-
24316
24372
  // src/commands/pr-feedback.ts
24317
24373
  function handlePrFeedbackCommand(directory, args) {
24318
24374
  const rest = args.filter((t) => t.trim().length > 0);
@@ -24499,7 +24555,7 @@ async function handlePrMonitorStatusCommand(directory, _args, sessionID, source)
24499
24555
  }
24500
24556
 
24501
24557
  // src/commands/pr-review.ts
24502
- var USAGE8 = [
24558
+ var USAGE9 = [
24503
24559
  "Usage: /swarm pr-review <url|owner/repo#N|N> [--council] [instructions...]",
24504
24560
  "",
24505
24561
  "Run a full swarm PR review on a GitHub pull request.",
@@ -24537,16 +24593,16 @@ function handlePrReviewCommand(directory, args) {
24537
24593
  if (parsed.unknownFlag) {
24538
24594
  return `Error: Unknown flag "${parsed.unknownFlag}"
24539
24595
 
24540
- ${USAGE8}`;
24596
+ ${USAGE9}`;
24541
24597
  }
24542
24598
  const resolved = resolvePrCommandInput(parsed.rest, directory);
24543
24599
  if (resolved === null) {
24544
- return USAGE8;
24600
+ return USAGE9;
24545
24601
  }
24546
24602
  if ("error" in resolved) {
24547
24603
  return `Error: ${resolved.error}
24548
24604
 
24549
- ${USAGE8}`;
24605
+ ${USAGE9}`;
24550
24606
  }
24551
24607
  const councilFlag = parsed.council ? "council=true" : "council=false";
24552
24608
  const signal = `[MODE: PR_REVIEW pr="${resolved.prUrl}" ${councilFlag}]`;
@@ -31392,7 +31448,7 @@ var _internals46 = {
31392
31448
  writeProjectedSpecSync
31393
31449
  };
31394
31450
  var SWARM_SPEC_REL = path61.join(".swarm", "spec.md");
31395
- var USAGE9 = `Usage:
31451
+ var USAGE10 = `Usage:
31396
31452
  /swarm sdd status [--json] [--source <provider>]
31397
31453
  /swarm sdd validate [--json] [--change <id>] [--source <provider>] [--feature <id>]
31398
31454
  /swarm sdd project [--dry-run] [--overwrite] [--json] [--change <id>] [--source <provider>] [--feature <id>]
@@ -31505,11 +31561,11 @@ async function handleSddStatusCommand(directory, args) {
31505
31561
  if (parsed.error)
31506
31562
  return `Error: ${parsed.error}
31507
31563
 
31508
- ${USAGE9}`;
31564
+ ${USAGE10}`;
31509
31565
  if (parsed.feature && parsed.source && parsed.source !== "speckit") {
31510
31566
  return `Error: --feature is only valid with --source speckit
31511
31567
 
31512
- ${USAGE9}`;
31568
+ ${USAGE10}`;
31513
31569
  }
31514
31570
  const speckitDetection = detectSpeckit(directory);
31515
31571
  const speckitPresent = speckitDetection.features.length > 0;
@@ -31576,11 +31632,11 @@ async function handleSddValidateCommand(directory, args) {
31576
31632
  if (parsed.error)
31577
31633
  return `Error: ${parsed.error}
31578
31634
 
31579
- ${USAGE9}`;
31635
+ ${USAGE10}`;
31580
31636
  if (parsed.feature && parsed.source && parsed.source !== "speckit") {
31581
31637
  return `Error: --feature is only valid with --source speckit
31582
31638
 
31583
- ${USAGE9}`;
31639
+ ${USAGE10}`;
31584
31640
  }
31585
31641
  let useSpeckit = false;
31586
31642
  const nativeSpecExists = fs29.existsSync(path61.join(directory, SWARM_SPEC_REL));
@@ -31609,7 +31665,7 @@ ${USAGE9}`;
31609
31665
  const resolution = resolveSpeckitProjection(directory);
31610
31666
  return parsed.json ? JSON.stringify({ valid: false, error: formatSpeckitError(resolution) }, null, 2) : `Error: ${formatSpeckitError(resolution)}
31611
31667
 
31612
- ${USAGE9}`;
31668
+ ${USAGE10}`;
31613
31669
  }
31614
31670
  }
31615
31671
  }
@@ -31620,7 +31676,7 @@ ${USAGE9}`;
31620
31676
  if (resolution.kind !== "ok" && resolution.kind !== "zero_requirements") {
31621
31677
  return parsed.json ? JSON.stringify({ valid: false, error: formatSpeckitError(resolution) }, null, 2) : `Error: ${formatSpeckitError(resolution)}
31622
31678
 
31623
- ${USAGE9}`;
31679
+ ${USAGE10}`;
31624
31680
  }
31625
31681
  const spec = resolution.kind === "ok" ? resolution.spec : null;
31626
31682
  const result2 = {
@@ -31725,16 +31781,16 @@ async function handleSddProjectCommand(directory, args) {
31725
31781
  if (parsed.error)
31726
31782
  return `Error: ${parsed.error}
31727
31783
 
31728
- ${USAGE9}`;
31784
+ ${USAGE10}`;
31729
31785
  if (parsed.feature && parsed.source && parsed.source !== "speckit") {
31730
31786
  return `Error: --feature is only valid with --source speckit
31731
31787
 
31732
- ${USAGE9}`;
31788
+ ${USAGE10}`;
31733
31789
  }
31734
31790
  if (parsed.source === "swarm") {
31735
31791
  return `Error: --source swarm selects the native .swarm/spec.md and does not generate a projection. Use --source openspec or --source speckit.
31736
31792
 
31737
- ${USAGE9}`;
31793
+ ${USAGE10}`;
31738
31794
  }
31739
31795
  if (!parsed.dryRun) {
31740
31796
  const nativeSpecPath = path61.join(directory, SWARM_SPEC_REL);
@@ -31744,7 +31800,7 @@ ${USAGE9}`;
31744
31800
  "Error: .swarm/spec.md already exists.",
31745
31801
  "Pass --overwrite to replace it.",
31746
31802
  "",
31747
- USAGE9
31803
+ USAGE10
31748
31804
  ].join(`
31749
31805
  `);
31750
31806
  }
@@ -31771,7 +31827,7 @@ ${USAGE9}`;
31771
31827
  const resolution = resolveSpeckitProjection(directory);
31772
31828
  return `Error: ${formatSpeckitError(resolution)}
31773
31829
 
31774
- ${USAGE9}`;
31830
+ ${USAGE10}`;
31775
31831
  }
31776
31832
  }
31777
31833
  }
@@ -31782,7 +31838,7 @@ ${USAGE9}`;
31782
31838
  if (resolution.kind !== "ok") {
31783
31839
  return `Error: ${formatSpeckitError(resolution)}
31784
31840
 
31785
- ${USAGE9}`;
31841
+ ${USAGE10}`;
31786
31842
  }
31787
31843
  const result2 = _internals46.writeProjectedSpecSync(directory, {
31788
31844
  source: "speckit",
@@ -31801,7 +31857,7 @@ ${USAGE9}`;
31801
31857
  }
31802
31858
  return `Error: ${result2.error}
31803
31859
 
31804
- ${USAGE9}`;
31860
+ ${USAGE10}`;
31805
31861
  }
31806
31862
  if (!result2.projection) {
31807
31863
  if (parsed.json) {
@@ -31815,7 +31871,7 @@ ${USAGE9}`;
31815
31871
  return [
31816
31872
  "SDD projection failed: no valid Spec-Kit projection could be built.",
31817
31873
  "",
31818
- USAGE9
31874
+ USAGE10
31819
31875
  ].join(`
31820
31876
  `);
31821
31877
  }
@@ -31858,7 +31914,7 @@ ${formatList(result2.projection.warnings)}` : ""
31858
31914
  }
31859
31915
  return `Error: ${result.error}
31860
31916
 
31861
- ${USAGE9}`;
31917
+ ${USAGE10}`;
31862
31918
  }
31863
31919
  if (!result.projection) {
31864
31920
  if (parsed.json) {
@@ -31872,7 +31928,7 @@ ${USAGE9}`;
31872
31928
  return [
31873
31929
  "SDD projection failed: no valid OpenSpec-compatible projection could be built.",
31874
31930
  "",
31875
- USAGE9
31931
+ USAGE10
31876
31932
  ].join(`
31877
31933
  `);
31878
31934
  }
@@ -31900,7 +31956,7 @@ ${formatList(result.projection.warnings)}` : ""
31900
31956
  `);
31901
31957
  }
31902
31958
  async function handleSddCommand(_directory, _args) {
31903
- return USAGE9;
31959
+ return USAGE10;
31904
31960
  }
31905
31961
 
31906
31962
  // src/commands/simulate.ts
@@ -31923,7 +31979,7 @@ async function handleSimulateCommand(directory, args) {
31923
31979
  }
31924
31980
  let darkMatterPairs;
31925
31981
  try {
31926
- darkMatterPairs = await _internals21.detectDarkMatter(directory, options);
31982
+ darkMatterPairs = await _internals22.detectDarkMatter(directory, options);
31927
31983
  } catch (err) {
31928
31984
  const errMsg = err instanceof Error ? err.message : String(err);
31929
31985
  return `## Simulate Report
@@ -32992,7 +33048,7 @@ function buildDetailedHelp(commandName, entry) {
32992
33048
  async function handleHelpCommand(ctx) {
32993
33049
  const targetCommand = ctx.args.join(" ");
32994
33050
  if (!targetCommand) {
32995
- const { buildHelpText } = await import("./index-z01r5483.js");
33051
+ const { buildHelpText } = await import("./index-54sevh81.js");
32996
33052
  return buildHelpText();
32997
33053
  }
32998
33054
  const tokens = targetCommand.split(/\s+/);
@@ -33001,7 +33057,7 @@ async function handleHelpCommand(ctx) {
33001
33057
  return _internals49.buildDetailedHelp(resolved.key, resolved.entry);
33002
33058
  }
33003
33059
  const similar = _internals49.findSimilarCommands(targetCommand);
33004
- const { buildHelpText: fullHelp } = await import("./index-z01r5483.js");
33060
+ const { buildHelpText: fullHelp } = await import("./index-54sevh81.js");
33005
33061
  if (similar.length > 0) {
33006
33062
  return `Command '/swarm ${targetCommand}' not found.
33007
33063
 
@@ -33134,7 +33190,7 @@ var COMMAND_REGISTRY = {
33134
33190
  },
33135
33191
  "guardrail explain": {
33136
33192
  handler: async (ctx) => {
33137
- const { handleGuardrailExplain } = await import("./guardrail-explain-4t8fnysh.js");
33193
+ const { handleGuardrailExplain } = await import("./guardrail-explain-7aztgtyh.js");
33138
33194
  return handleGuardrailExplain(ctx.directory, ctx.args);
33139
33195
  },
33140
33196
  description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
@@ -33144,7 +33200,7 @@ var COMMAND_REGISTRY = {
33144
33200
  },
33145
33201
  "guardrail-explain": {
33146
33202
  handler: async (ctx) => {
33147
- const { handleGuardrailExplain } = await import("./guardrail-explain-4t8fnysh.js");
33203
+ const { handleGuardrailExplain } = await import("./guardrail-explain-7aztgtyh.js");
33148
33204
  return handleGuardrailExplain(ctx.directory, ctx.args);
33149
33205
  },
33150
33206
  description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
@@ -33504,6 +33560,14 @@ Subcommands:
33504
33560
  category: "agent",
33505
33561
  toolPolicy: "none"
33506
33562
  },
33563
+ "ci-monitor": {
33564
+ handler: (ctx) => handleModeCommandWithBundledSkills(ctx, handleCiMonitorCommand),
33565
+ description: "Drive an already-reviewed, approved PR to green and merged (monitor CI, fix, merge) [pr]",
33566
+ args: "<pr-url|owner/repo#N|N>",
33567
+ details: "Triggers MODE: CI_MONITOR \u2014 takes an already human-reviewed, approved PR, exhaustively researches every CI failure, fixes it end-to-end, iterates until all required checks are green (max 5 fix cycles), then merges via `gh pr merge` with no merge-strategy flag. Invoke only after human review is complete; the skill re-verifies reviewDecision: APPROVED and mergeable state before doing anything destructive. Distinct from /swarm pr-subscribe, which passively watches a PR without a merge terminal. Supports full GitHub URL, owner/repo#N shorthand, or bare PR number (resolved against origin).",
33568
+ category: "agent",
33569
+ toolPolicy: "none"
33570
+ },
33507
33571
  "pr subscribe": {
33508
33572
  handler: (ctx) => handlePrSubscribeCommand(ctx.directory, ctx.args, ctx.sessionID),
33509
33573
  description: "Subscribe the current session to PR state-change notifications",
@@ -34544,6 +34608,7 @@ FILE: src/auth/login.ts
34544
34608
  INPUT: Validate email format, password >= 8 chars
34545
34609
  OUTPUT: Modified file
34546
34610
  CONSTRAINT: Do not modify other functions
34611
+ ACCEPTANCE: Populate from the plan task's acceptance criteria / FR / SC when the task has them (one item per line, or FR-/SC-style references), so the coder can gate its implementation on each. Omit the field entirely when the task has no structured acceptance criteria.
34547
34612
  SKILLS: file:.claude/skills/engineering-conventions/SKILL.md
34548
34613
 
34549
34614
  {{AGENT_PREFIX}}reviewer
@@ -34889,6 +34954,22 @@ HARD CONSTRAINTS (apply regardless of skill load success):
34889
34954
  - Honor any free-text instructions that follow the closing bracket of the signal as additional scope, without dropping any ledger item.
34890
34955
  - Quality is the only metric \u2014 time, tokens, and agent dispatches are irrelevant to correctness
34891
34956
 
34957
+ ### MODE: CI_MONITOR
34958
+ Activates when: architect receives \`[MODE: CI_MONITOR pr="https://github.com/..."]\` signal from the ci-monitor command handler.
34959
+
34960
+ Purpose: Drive an already human-reviewed, approved PR to a merged state \u2014 monitor its CI, exhaustively research and fix every failure, iterate until all required checks are green (max 5 fix cycles), then merge. This is the terminal closeout hop for a PR that just needs to get green and merge; it is NOT a review or feedback-ingestion mode. It is the first mode in this workflow that performs a merge, so it carries extra safety gates.
34961
+
34962
+ ACTION: Load skill ${bundledProjectSkillFileReference("swarm-ci-monitor")} immediately and follow its protocol.
34963
+
34964
+ HARD CONSTRAINTS (apply regardless of skill load success):
34965
+ - Do NOT invoke this mode's merge path without the user having named the PR explicitly \u2014 no auto-discovery.
34966
+ - Verify \`reviewDecision: APPROVED\` before entering the fix loop; abort with "human review not complete" if not.
34967
+ - Verify \`mergeable: MERGEABLE\` and an acceptable \`mergeStateStatus\` before entering the fix loop; do not bypass these gates even under time pressure.
34968
+ - Never use \`--admin\`, a forced merge strategy, or \`--delete-branch\` \u2014 let branch protection determine the merge method.
34969
+ - Re-verify review approval and mergeable state immediately before every merge attempt (Step 3 of the loaded skill) \u2014 a check that was green earlier is not sufficient.
34970
+ - Confirm the merge via the local git object DB (Step 4b), not only the GitHub API response, before reporting success.
34971
+ - Hard-stop at 5 fix-push cycles; escalate to the user rather than exceeding the budget.
34972
+
34892
34973
  ### MODE: ISSUE_INGEST
34893
34974
  Activates when the user invokes /swarm issue <url> or the architect receives an ISSUE_INGEST signal.
34894
34975
 
@@ -38293,7 +38374,6 @@ function resolveWriteTargets(command, writes, cwd) {
38293
38374
  };
38294
38375
  });
38295
38376
  }
38296
-
38297
38377
  // src/hooks/guardrails/index.ts
38298
38378
  var SPEC_DRIFT_BLOCKED_TOOLS = new Set([
38299
38379
  "save_plan",
@@ -39297,4 +39377,4 @@ function createCuratorLLMDelegate(directory, mode = "init", sessionId) {
39297
39377
  };
39298
39378
  }
39299
39379
 
39300
- export { package_default, handleAcknowledgeSpecDriftCommand, handleAgentsCommand, handleAnalyzeCommand, handleArchiveCommand, DC_SAFE_TARGETS, dcNormalizeCommand, dcUnwrapWrappers, dcSplitSegments, dcValidateTargets, dcCheckJunctionCreation, dcExtractWindowsCmdTargets, dcExtractPowerShellTargets, normalizeSwarmCommandInput, canonicalCommandKey, formatCommandNotFound, executeSwarmCommand, SWARM_COMMAND_TOOL_COMMANDS, SWARM_COMMAND_TOOL_ALLOWLIST, HUMAN_ONLY_SWARM_COMMANDS, classifySwarmCommandToolUse, classifySwarmCommandChatFallbackUse, detectPosixWrites, detectWindowsWrites, resolveWriteTargets, handleAutoProceedCommand, handleBenchmarkCommand, handleBrainstormCommand, handleCheckpointCommand, handleCiSimulateCommand, handleClarifyCommand, createCuratorLLMDelegate, _internals11 as _internals, normalizeRecommendationEntryIdToken, parseKnowledgeRecommendations, parseKnowledgeRecommendationsWithDiagnostics, parseStructuredCuratorBlocks, readCuratorSummary, writeCuratorSummary, appendCuratorRecommendation, mergeCuratorPhaseSummary, filterPhaseEvents, checkPhaseCompliance, runCuratorInit, runCuratorPhase, applyCuratorKnowledgeUpdates, isHiveEligible, checkHivePromotions, _internals13 as _internals1, createHivePromoterHook, promoteToHive, promoteFromSwarm, handleCloseCommand, handleCodebaseReviewCommand, handleConcurrencyCommand, handleConfigCommand, handleConsolidateCommand, handleCostsCommand, handleCouncilCommand, handleCurateCommand, handleDarkMatterCommand, handleDeepDiveCommand, handleDeepResearchCommand, getPluginConfigDir, getPluginCachePaths, getPluginLockFilePaths, handleDiagnoseCommand, handleDoctorCommand, handleEvidenceCommand, handleEvidenceSummaryCommand, handleExportCommand, handleFullAutoCommand, handleHandoffCommand, handleHistoryCommand, handleKnowledgeQuarantineCommand, handleKnowledgeRestoreCommand, handleKnowledgeMigrateCommand, handleKnowledgeListCommand, handleKnowledgeUnactionableCommand, handleKnowledgeRetryHardeningCommand, handleLearningCommand, handleLinkCommand, handleMemoryCommand, handleMemoryStatusCommand, handleMemoryValueLogCommand, handleMemoryMigrateCommand, handleMemoryImportCommand, handleMemoryExportCommand, handlePlanCommand, handlePreflightCommand, handlePromoteCommand, handleQaGatesCommand, handleResetCommand, handleResetSessionCommand, handleRetrieveCommand, handleRollbackCommand, handleSddStatusCommand, handleSddValidateCommand, handleSddProjectCommand, handleSddCommand, handleSimulateCommand, handleSpecifyCommand, handleStatusCommand, handleSyncPlanCommand, handleTurboCommand, handleUnlinkCommand, handleWriteRetroCommand, handleHelpCommand, COMMAND_REGISTRY, VALID_COMMANDS, _internals49 as _internals2, resolveCommand };
39380
+ export { package_default, handleAcknowledgeSpecDriftCommand, handleAgentsCommand, handleAnalyzeCommand, handleArchiveCommand, DC_SAFE_TARGETS, dcNormalizeCommand, dcUnwrapWrappers, dcSplitSegments, dcValidateTargets, dcCheckJunctionCreation, dcExtractWindowsCmdTargets, dcExtractPowerShellTargets, normalizeSwarmCommandInput, canonicalCommandKey, formatCommandNotFound, executeSwarmCommand, SWARM_COMMAND_TOOL_COMMANDS, SWARM_COMMAND_TOOL_ALLOWLIST, HUMAN_ONLY_SWARM_COMMANDS, classifySwarmCommandToolUse, classifySwarmCommandChatFallbackUse, detectPosixWrites, detectWindowsWrites, resolveWriteTargets, handleAutoProceedCommand, handleBenchmarkCommand, handleBrainstormCommand, handleCheckpointCommand, handleCiSimulateCommand, handleClarifyCommand, createCuratorLLMDelegate, _internals12 as _internals, normalizeRecommendationEntryIdToken, parseKnowledgeRecommendations, parseKnowledgeRecommendationsWithDiagnostics, parseStructuredCuratorBlocks, readCuratorSummary, writeCuratorSummary, appendCuratorRecommendation, mergeCuratorPhaseSummary, filterPhaseEvents, checkPhaseCompliance, runCuratorInit, runCuratorPhase, applyCuratorKnowledgeUpdates, isHiveEligible, checkHivePromotions, _internals14 as _internals1, createHivePromoterHook, promoteToHive, promoteFromSwarm, handleCloseCommand, handleCodebaseReviewCommand, handleConcurrencyCommand, handleConfigCommand, handleConsolidateCommand, handleCostsCommand, handleCouncilCommand, handleCurateCommand, handleDarkMatterCommand, handleDeepDiveCommand, handleDeepResearchCommand, getPluginConfigDir, getPluginCachePaths, getPluginLockFilePaths, handleDiagnoseCommand, handleDoctorCommand, handleEvidenceCommand, handleEvidenceSummaryCommand, handleExportCommand, handleFullAutoCommand, handleHandoffCommand, handleHistoryCommand, handleKnowledgeQuarantineCommand, handleKnowledgeRestoreCommand, handleKnowledgeMigrateCommand, handleKnowledgeListCommand, handleKnowledgeUnactionableCommand, handleKnowledgeRetryHardeningCommand, handleLearningCommand, handleLinkCommand, handleMemoryCommand, handleMemoryStatusCommand, handleMemoryValueLogCommand, handleMemoryMigrateCommand, handleMemoryImportCommand, handleMemoryExportCommand, handlePlanCommand, handlePreflightCommand, handlePromoteCommand, handleQaGatesCommand, handleResetCommand, handleResetSessionCommand, handleRetrieveCommand, handleRollbackCommand, handleSddStatusCommand, handleSddValidateCommand, handleSddProjectCommand, handleSddCommand, handleSimulateCommand, handleSpecifyCommand, handleStatusCommand, handleSyncPlanCommand, handleTurboCommand, handleUnlinkCommand, handleWriteRetroCommand, handleHelpCommand, COMMAND_REGISTRY, VALID_COMMANDS, _internals49 as _internals2, resolveCommand };