opencode-swarm 7.185.1 → 7.186.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/.opencode/skills/swarm-pr-review/SKILL.md +3 -3
  2. package/.opencode/skills/swarm-pr-review/references/lane-output-recoverability.md +19 -1
  3. package/binaries/win32-arm64/swarm-sandbox-runner.exe +0 -0
  4. package/binaries/win32-x64/swarm-sandbox-runner.exe +0 -0
  5. package/dist/background/pr-feedback-event-queue.d.ts +3 -2
  6. package/dist/background/pr-feedback-loop-runtime.d.ts +4 -1
  7. package/dist/background/pr-feedback-loop.d.ts +2 -1
  8. package/dist/background/pr-monitor-worker.d.ts +9 -1
  9. package/dist/background/pr-review-trigger-contract.d.ts +8 -0
  10. package/dist/background/pr-subscriptions.d.ts +23 -0
  11. package/dist/cli/{auto-checkpoint-2jecngee.js → auto-checkpoint-fsd4a9q9.js} +7 -7
  12. package/dist/cli/{checkpoint-qm05wdbh.js → checkpoint-rc61fd93.js} +14 -14
  13. package/dist/cli/{coder-settlement-56prayae.js → coder-settlement-x198191a.js} +10 -10
  14. package/dist/cli/{config-doctor-3b99vx74.js → config-doctor-mj4ae4jn.js} +2 -2
  15. package/dist/cli/{core-cxnqsrxp.js → core-fvsjr20m.js} +3 -3
  16. package/dist/cli/{curation-policy-ytzwb080.js → curation-policy-pxwagyh7.js} +4 -4
  17. package/dist/cli/{curator-drift-dt4g79a4.js → curator-drift-t150w08d.js} +8 -8
  18. package/dist/cli/{curator-5k3mktpe.js → curator-h7j1xse4.js} +39 -39
  19. package/dist/cli/curator-llm-factory-29cswvhr.js +81 -0
  20. package/dist/cli/{evidence-summary-service-8e2fghz0.js → evidence-summary-service-h42y6hwq.js} +17 -17
  21. package/dist/cli/{gate-evidence-vk8rebsx.js → gate-evidence-c7caa5x2.js} +5 -5
  22. package/dist/cli/guardrail-explain-yfd11za1.js +82 -0
  23. package/dist/cli/{guardrail-log-m6mydjet.js → guardrail-log-hcr5rptq.js} +6 -6
  24. package/dist/cli/{guardrail-reset-w41yndke.js → guardrail-reset-fqgf5sdb.js} +39 -39
  25. package/dist/cli/{hive-promoter-400xzdds.js → hive-promoter-632ewk29.js} +39 -39
  26. package/dist/cli/{index-9g61bfj9.js → index-010en5sq.js} +1 -1
  27. package/dist/cli/{index-r9zc92pb.js → index-03d68zxw.js} +41 -41
  28. package/dist/cli/{index-s7va6n84.js → index-0t61279z.js} +3 -3
  29. package/dist/cli/{index-zt3taseq.js → index-3rd7gqfg.js} +2 -2
  30. package/dist/cli/{index-ek5gvpvm.js → index-4h6e73bx.js} +7 -7
  31. package/dist/cli/{index-2c6e1p7j.js → index-4z0zdcd7.js} +3 -3
  32. package/dist/cli/{index-afmyp3kt.js → index-5v1sqv3m.js} +1 -1
  33. package/dist/cli/{index-6wqv8f7d.js → index-8fnayk3x.js} +5 -5
  34. package/dist/cli/{index-2b3bgm20.js → index-8jq3jsas.js} +1 -1
  35. package/dist/cli/{index-xgdypzch.js → index-92bbwjek.js} +1 -1
  36. package/dist/cli/{index-62akgg9d.js → index-92y6cpqn.js} +1 -1
  37. package/dist/cli/{index-cnbpht7m.js → index-98j268bh.js} +3 -3
  38. package/dist/cli/{index-s68z4a39.js → index-9z9g1897.js} +2 -2
  39. package/dist/cli/{index-dryhmaft.js → index-ay508kfq.js} +3 -3
  40. package/dist/cli/{index-8nsjefpc.js → index-bpqw4n2f.js} +1 -1
  41. package/dist/cli/{index-6sffjy74.js → index-c5e1wr7h.js} +1 -1
  42. package/dist/cli/{index-pa6fzbms.js → index-chaa1v0b.js} +4 -4
  43. package/dist/cli/{index-cp2nerjd.js → index-dbcwvc1v.js} +43 -20
  44. package/dist/cli/{index-hgfkcb1q.js → index-ef3pecd4.js} +813 -583
  45. package/dist/cli/{index-nw16apxs.js → index-ezttvjcf.js} +5 -5
  46. package/dist/cli/{index-m1bhg85z.js → index-gbmsvfp2.js} +2 -2
  47. package/dist/cli/{index-zxck9sr7.js → index-gjrs1epm.js} +1 -1
  48. package/dist/cli/{index-9h93zjm3.js → index-hmwnegkz.js} +1 -1
  49. package/dist/cli/{index-7jt24hpz.js → index-hq9f7fwf.js} +2 -2
  50. package/dist/cli/{index-rtznwf0g.js → index-hw8w4mkh.js} +39 -39
  51. package/dist/cli/{index-07bk0zm9.js → index-j42256hj.js} +1 -1
  52. package/dist/cli/{index-ycqsnfd1.js → index-jwkybwv0.js} +4 -4
  53. package/dist/cli/{index-yj7etak0.js → index-m8dry0a6.js} +1 -1
  54. package/dist/cli/{index-dz5cbkrm.js → index-mnb1pg1n.js} +4 -4
  55. package/dist/cli/{index-rr1dggfe.js → index-nnmgg6z6.js} +1 -1
  56. package/dist/cli/{index-7n3h39h9.js → index-pe1wgpvg.js} +7 -7
  57. package/dist/cli/{index-pppjg0ct.js → index-ptp6d5mm.js} +18 -20
  58. package/dist/cli/{index-nen885g8.js → index-q9wnbz9q.js} +1 -1
  59. package/dist/cli/{index-5n08z6qj.js → index-qg0nhcke.js} +5 -5
  60. package/dist/cli/{index-ppj5bjaq.js → index-qj7ewgrf.js} +7 -7
  61. package/dist/cli/{index-nhw5rt5x.js → index-syt8wykh.js} +4 -4
  62. package/dist/cli/{index-74yxwf8y.js → index-t46swpqf.js} +1 -1
  63. package/dist/cli/{index-ekyg4p8b.js → index-teyvb5tr.js} +1 -1
  64. package/dist/cli/{index-ss6b8jpz.js → index-vvajq163.js} +2 -2
  65. package/dist/cli/{index-1fc5aj26.js → index-w12y73z5.js} +1 -1
  66. package/dist/cli/{index-vqz0avr4.js → index-wrhf5apg.js} +2 -2
  67. package/dist/cli/{index-smwybqka.js → index-xe34ymp8.js} +2 -2
  68. package/dist/cli/{index-fa014mra.js → index-xkxt1b08.js} +3 -3
  69. package/dist/cli/{index-373880cv.js → index-y7s92gte.js} +1 -1
  70. package/dist/cli/index.js +40 -40
  71. package/dist/cli/{knowledge-escalator-30bb9fyg.js → knowledge-escalator-gajaew60.js} +11 -11
  72. package/dist/cli/{knowledge-events-gfbx97x0.js → knowledge-events-fsbgfz4z.js} +9 -9
  73. package/dist/cli/{knowledge-link-dv78fb9g.js → knowledge-link-jnnk0nmk.js} +3 -3
  74. package/dist/cli/{knowledge-store-2ssd489f.js → knowledge-store-vaq1g1dx.js} +4 -4
  75. package/dist/cli/{knowledge-validator-7bxvezgv.js → knowledge-validator-pdr6m77a.js} +6 -6
  76. package/dist/cli/{mcp-apr65eya.js → mcp-5sn4e5t2.js} +1 -1
  77. package/dist/cli/{model-preflight-g7b12yn2.js → model-preflight-z9p55ssn.js} +39 -39
  78. package/dist/cli/{pending-delegations-x8q7cxr7.js → pending-delegations-asyc469v.js} +10 -10
  79. package/dist/cli/{pr-subscriptions-qwr6ybcb.js → pr-subscriptions-nacx8r6a.js} +12 -10
  80. package/dist/cli/{pr-workflow-gate-qd5tfkak.js → pr-workflow-gate-j3r636zg.js} +41 -39
  81. package/dist/cli/{runner-tb3eppeg.js → runner-fns4esbf.js} +4 -4
  82. package/dist/cli/{scan-cursor-1m6dj2s2.js → scan-cursor-y9rchz83.js} +5 -5
  83. package/dist/cli/{schema-yvhamv41.js → schema-g377jsvv.js} +1 -1
  84. package/dist/cli/{scope-persistence-xdedbzdg.js → scope-persistence-dtympt37.js} +13 -13
  85. package/dist/cli/{server-nhdkvdt2.js → server-n51pvxds.js} +39 -39
  86. package/dist/cli/{skill-generator-fzvp9m8z.js → skill-generator-k3hnf8xx.js} +13 -13
  87. package/dist/cli/{snapshot-coordination-init-xqxek8kn.js → snapshot-coordination-init-k1f93806.js} +39 -39
  88. package/dist/cli/{speckit-checkoff-57tf4079.js → speckit-checkoff-w7qbrzph.js} +4 -4
  89. package/dist/cli/{workspace-snapshot-kcfkk3a2.js → workspace-snapshot-1sa8m2ea.js} +3 -3
  90. package/dist/cli/{worktree-collision-ownership-80n814a8.js → worktree-collision-ownership-4yxah5wy.js} +11 -11
  91. package/dist/cli/{worktree-isolation-kaxkr61t.js → worktree-isolation-p0pz81a1.js} +39 -39
  92. package/dist/git/pr.d.ts +73 -0
  93. package/dist/hooks/pr-workflow-gate.d.ts +69 -0
  94. package/dist/index.js +39 -39
  95. package/dist/tools/write-pr-review-trigger-eval.d.ts +2 -1
  96. package/package.json +1 -1
  97. package/dist/cli/curator-llm-factory-hkk29g2y.js +0 -81
  98. package/dist/cli/guardrail-explain-ma658hkw.js +0 -82
@@ -8,13 +8,13 @@ import {
8
8
  protectedRoots,
9
9
  redactDecisionLineForArchive,
10
10
  stableCanonicalStringify
11
- } from "./index-ss6b8jpz.js";
11
+ } from "./index-vvajq163.js";
12
12
  import {
13
13
  detectStraySwarmDirs,
14
14
  readDoctorArtifact,
15
15
  removeStraySwarmDir,
16
16
  runConfigDoctor
17
- } from "./index-9h93zjm3.js";
17
+ } from "./index-hmwnegkz.js";
18
18
  import {
19
19
  archiveEvidence,
20
20
  checkRequirementCoverage,
@@ -26,7 +26,7 @@ import {
26
26
  sanitizeTaskId,
27
27
  saveEvidence,
28
28
  validateProjectRoot
29
- } from "./index-pa6fzbms.js";
29
+ } from "./index-chaa1v0b.js";
30
30
  import {
31
31
  LANGUAGE_REGISTRY,
32
32
  _internals as _internals3,
@@ -44,7 +44,7 @@ import {
44
44
  runEvaluation,
45
45
  runExternalTool,
46
46
  withDisposableWorktree
47
- } from "./index-1fc5aj26.js";
47
+ } from "./index-w12y73z5.js";
48
48
  import {
49
49
  EvaluationTaskV1Schema,
50
50
  GateAuditManifestV1Schema,
@@ -61,7 +61,7 @@ import {
61
61
  saveGateAuditResult,
62
62
  savePromotionDecision,
63
63
  saveTaskSetSnapshot
64
- } from "./index-62akgg9d.js";
64
+ } from "./index-92y6cpqn.js";
65
65
  import {
66
66
  canonicalHash,
67
67
  canonicalJson,
@@ -77,7 +77,7 @@ import {
77
77
  alreadyCuratedThisGeneration,
78
78
  claimNextScanBatch,
79
79
  resolveCohortId
80
- } from "./index-smwybqka.js";
80
+ } from "./index-xe34ymp8.js";
81
81
  import {
82
82
  CURATOR_CONSOLIDATION_PROMPT,
83
83
  CURATOR_INIT_PROMPT,
@@ -96,13 +96,13 @@ import {
96
96
  getGroupCommitWriter,
97
97
  importLegacyJsonl,
98
98
  readPriorDriftReports
99
- } from "./index-s7va6n84.js";
99
+ } from "./index-0t61279z.js";
100
100
  import {
101
101
  assertNoUnsettledCoderDispatch,
102
102
  listCoderSettlementWalStates,
103
103
  recoverCoderSettlement,
104
104
  recoverStaleCoderSettlements
105
- } from "./index-ek5gvpvm.js";
105
+ } from "./index-4h6e73bx.js";
106
106
  import {
107
107
  BUNDLED_PROJECT_SKILL_ROOT,
108
108
  DEFAULT_SKILL_MIN_CONFIDENCE,
@@ -123,11 +123,11 @@ import {
123
123
  retireSkill,
124
124
  selectCandidateEntries,
125
125
  syncBundledProjectSkillsIfMissingAsync
126
- } from "./index-dz5cbkrm.js";
126
+ } from "./index-mnb1pg1n.js";
127
127
  import {
128
128
  buildEscalationBriefing,
129
129
  readRecentEscalations
130
- } from "./index-5n08z6qj.js";
130
+ } from "./index-qg0nhcke.js";
131
131
  import {
132
132
  parsePorcelainV2Snapshot,
133
133
  resolveCommitCountSince,
@@ -155,7 +155,7 @@ import {
155
155
  resolveRemoteUrlIdentity,
156
156
  resolveRemoteUrlIdentityAsync,
157
157
  switchPrFeedbackTrackingCandidateAsync
158
- } from "./index-s68z4a39.js";
158
+ } from "./index-9z9g1897.js";
159
159
  import {
160
160
  buildCorrelationId,
161
161
  buildIssueUrl,
@@ -163,8 +163,8 @@ import {
163
163
  canonicalForgePrUrl,
164
164
  containsControlCharacters,
165
165
  detectForgeFromUrl,
166
+ findSubscriptionRecordForPrUrl,
166
167
  getPrSubscriptionHealth,
167
- getProviderCapabilities,
168
168
  hasNonAsciiHostname,
169
169
  isPrSubscriptionCapacityError,
170
170
  isPrivateHost,
@@ -176,12 +176,12 @@ import {
176
176
  sweepStale,
177
177
  unsubscribe,
178
178
  updateSnapshot
179
- } from "./index-cp2nerjd.js";
179
+ } from "./index-dbcwvc1v.js";
180
180
  import {
181
181
  WORKTREE_LIFECYCLE_LOCK_FILE,
182
182
  recordWorktreeProvisioningOwner,
183
183
  removeWorktreeProvisioningOwner
184
- } from "./index-vqz0avr4.js";
184
+ } from "./index-wrhf5apg.js";
185
185
  import {
186
186
  getLanguageForExtension
187
187
  } from "./index-pt7h91zc.js";
@@ -194,7 +194,7 @@ import {
194
194
  checkpoint,
195
195
  createSwarmTool,
196
196
  resolveWorkingDirectory
197
- } from "./index-nhw5rt5x.js";
197
+ } from "./index-syt8wykh.js";
198
198
  import {
199
199
  MAX_TRANSIENT_RETRIES,
200
200
  PlanRecoverySupersededError,
@@ -222,7 +222,7 @@ import {
222
222
  transientBackoff,
223
223
  updateTaskStatus,
224
224
  withPlanLifecycleLock
225
- } from "./index-pppjg0ct.js";
225
+ } from "./index-ptp6d5mm.js";
226
226
  import {
227
227
  containsControlChars,
228
228
  containsPathTraversal,
@@ -238,7 +238,7 @@ import {
238
238
  resolveSpeckitProjection,
239
239
  validateSpeckit,
240
240
  writeProjectedSpecSync
241
- } from "./index-2b3bgm20.js";
241
+ } from "./index-8jq3jsas.js";
242
242
  import {
243
243
  clearWorktreeMergeStatus,
244
244
  getAllWorktreeMergeFailures,
@@ -269,7 +269,7 @@ import {
269
269
  transitionTaskWorkflowEvidenceWithStatus,
270
270
  withTaskEvidenceTransaction,
271
271
  writeWorkflowWalFile
272
- } from "./index-cnbpht7m.js";
272
+ } from "./index-98j268bh.js";
273
273
  import {
274
274
  isPathUnderSwarmWorktreeBase,
275
275
  listLiveLaneOwners,
@@ -278,7 +278,7 @@ import {
278
278
  recordLiveLaneOwner,
279
279
  removeWorktree,
280
280
  resolveWorktreeBaseDir
281
- } from "./index-2c6e1p7j.js";
281
+ } from "./index-4z0zdcd7.js";
282
282
  import {
283
283
  DEFAULT_STALE_DELEGATION_TIMEOUT_MS,
284
284
  DELEGATION_COMPACTION_HIGH_WATER_BYTES,
@@ -312,7 +312,7 @@ import {
312
312
  scanBackgroundCoderReservationsForAdmission,
313
313
  scanDelegationsForRecovery,
314
314
  sweepStaleDelegations
315
- } from "./index-nw16apxs.js";
315
+ } from "./index-ezttvjcf.js";
316
316
  import {
317
317
  MAX_EVENT_LOG_ENTRIES,
318
318
  _internals,
@@ -331,7 +331,7 @@ import {
331
331
  recordKnowledgeEvent,
332
332
  recordPhaseCloseIntent,
333
333
  resolveKnowledgeEventsPath
334
- } from "./index-ppj5bjaq.js";
334
+ } from "./index-qj7ewgrf.js";
335
335
  import {
336
336
  estimateCharsForTokens,
337
337
  estimateTokens,
@@ -339,7 +339,7 @@ import {
339
339
  readSwarmFileAsync,
340
340
  safeHook,
341
341
  validateSwarmPath
342
- } from "./index-afmyp3kt.js";
342
+ } from "./index-5v1sqv3m.js";
343
343
  import {
344
344
  bunFile,
345
345
  bunSpawn,
@@ -359,18 +359,18 @@ import {
359
359
  validateActionableFields,
360
360
  validateLesson,
361
361
  validateSkillPath
362
- } from "./index-ycqsnfd1.js";
362
+ } from "./index-jwkybwv0.js";
363
363
  import {
364
364
  MAX_CURATION_PROPOSALS,
365
365
  authorizeCuration,
366
366
  buildConfigFingerprintInput
367
- } from "./index-8nsjefpc.js";
367
+ } from "./index-bpqw4n2f.js";
368
368
  import {
369
369
  cohortConfigFingerprint
370
370
  } from "./index-rtry5xyf.js";
371
371
  import {
372
372
  resolveWorktreeIsolationConfig
373
- } from "./index-7jt24hpz.js";
373
+ } from "./index-hq9f7fwf.js";
374
374
  import {
375
375
  RetrospectiveEvidenceSchema
376
376
  } from "./index-frcemc0b.js";
@@ -382,7 +382,7 @@ import {
382
382
  clearScopeBindings,
383
383
  readAuthoritativeScopeBindingSet,
384
384
  readDeclaredScopeFilesFromBindings
385
- } from "./index-6wqv8f7d.js";
385
+ } from "./index-8fnayk3x.js";
386
386
  import {
387
387
  clearPlanLedgerForReset,
388
388
  computePlanStructureHash,
@@ -398,7 +398,7 @@ import {
398
398
  replayFromLedgerWithStatus,
399
399
  resolvePlanningProfile,
400
400
  takeSnapshotEvent
401
- } from "./index-dryhmaft.js";
401
+ } from "./index-ay508kfq.js";
402
402
  import {
403
403
  CORE_EVENT_LOCKED,
404
404
  appendCoreEventSync,
@@ -408,7 +408,7 @@ import {
408
408
  hasSpecDriftAuditEvent,
409
409
  hasTaskRepairAuditEvent,
410
410
  readCoreEvents
411
- } from "./index-373880cv.js";
411
+ } from "./index-y7s92gte.js";
412
412
  import {
413
413
  DEFAULT_QA_GATES,
414
414
  computeProfileHash,
@@ -416,7 +416,7 @@ import {
416
416
  getEffectiveGates,
417
417
  getProfileLookupForIdentity,
418
418
  setGatesForIdentity
419
- } from "./index-9g61bfj9.js";
419
+ } from "./index-010en5sq.js";
420
420
  import {
421
421
  MAX_COORDINATION_STATE_LIST_ROWS,
422
422
  deleteCoordinationImports,
@@ -427,7 +427,7 @@ import {
427
427
  listCoordinationStates,
428
428
  transitionCoordinationState,
429
429
  withCoordinationTransaction
430
- } from "./index-nen885g8.js";
430
+ } from "./index-q9wnbz9q.js";
431
431
  import {
432
432
  DURABILITY_CLASSES,
433
433
  closeAllProjectDbs,
@@ -436,7 +436,7 @@ import {
436
436
  projectDbExists,
437
437
  projectDbPath,
438
438
  withImmediateTransaction
439
- } from "./index-74yxwf8y.js";
439
+ } from "./index-t46swpqf.js";
440
440
  import {
441
441
  canonicalExistingFilesystemPath,
442
442
  canonicalPathForFutureIo,
@@ -456,7 +456,7 @@ import {
456
456
  observeModelLimitResolution,
457
457
  observeStoreHealth,
458
458
  readLearningHealth
459
- } from "./index-xgdypzch.js";
459
+ } from "./index-92bbwjek.js";
460
460
  import {
461
461
  appendKnowledge,
462
462
  appendRejectedLesson,
@@ -487,7 +487,7 @@ import {
487
487
  transactFile,
488
488
  transactKnowledge,
489
489
  wordBigrams
490
- } from "./index-7n3h39h9.js";
490
+ } from "./index-pe1wgpvg.js";
491
491
  import {
492
492
  readTailJsonl,
493
493
  readTailJsonlDetailed,
@@ -508,10 +508,10 @@ import {
508
508
  resolveLinkDir,
509
509
  sanitizeLinkId,
510
510
  writeLinkPointer
511
- } from "./index-zxck9sr7.js";
511
+ } from "./index-gjrs1epm.js";
512
512
  import {
513
513
  atomicWriteFile
514
- } from "./index-6sffjy74.js";
514
+ } from "./index-c5e1wr7h.js";
515
515
  import {
516
516
  withEvidenceLock
517
517
  } from "./index-6cjpmvpa.js";
@@ -554,7 +554,7 @@ import {
554
554
  matchTempGrammar,
555
555
  parseTargetBasename,
556
556
  resetSwarmArtifactCache
557
- } from "./index-yj7etak0.js";
557
+ } from "./index-m8dry0a6.js";
558
558
  import {
559
559
  PlanSchema,
560
560
  TaskStatusSchema,
@@ -568,7 +568,7 @@ import {
568
568
  loadGateOverrides,
569
569
  loadPluginConfig,
570
570
  loadPluginConfigWithMeta
571
- } from "./index-ekyg4p8b.js";
571
+ } from "./index-teyvb5tr.js";
572
572
  import {
573
573
  addDeferredWarning,
574
574
  advisoryWarn,
@@ -600,7 +600,7 @@ import {
600
600
  resolveContextWindow,
601
601
  resolveGeneratedAgentRole,
602
602
  stripKnownSwarmPrefix
603
- } from "./index-rr1dggfe.js";
603
+ } from "./index-nnmgg6z6.js";
604
604
  import {
605
605
  AGENT_TOOL_MAP,
606
606
  ALL_AGENT_NAMES,
@@ -3389,7 +3389,7 @@ async function importLegacyPrWorkflowGateStateIfNeeded(directory, sessionID, all
3389
3389
  return null;
3390
3390
  throw error2;
3391
3391
  }
3392
- const legacy = allowSalvagedImport ? (await (await import("./pr-workflow-gate-qd5tfkak.js")).readPrWorkflowGateStateForRecovery(directory, sessionID))?.state ?? null : await readPrWorkflowGateStateFileFromDisk(filePath, sessionID);
3392
+ const legacy = allowSalvagedImport ? (await (await import("./pr-workflow-gate-j3r636zg.js")).readPrWorkflowGateStateForRecovery(directory, sessionID))?.state ?? null : await readPrWorkflowGateStateFileFromDisk(filePath, sessionID);
3393
3393
  if (!legacy)
3394
3394
  return null;
3395
3395
  const namespace = workflowGateStateCoordinationNamespace(sessionID);
@@ -3476,7 +3476,7 @@ async function deleteStateWhileLocked(directory, sessionID, options = {}) {
3476
3476
  let recoveryState = null;
3477
3477
  if (!currentAuthoritative) {
3478
3478
  if (options.allowSalvagedRead) {
3479
- const { readPrWorkflowGateStateForRecovery } = await import("./pr-workflow-gate-qd5tfkak.js");
3479
+ const { readPrWorkflowGateStateForRecovery } = await import("./pr-workflow-gate-j3r636zg.js");
3480
3480
  recoveryState = (await readPrWorkflowGateStateForRecovery(directory, normalizedSessionID))?.state ?? null;
3481
3481
  }
3482
3482
  if (!recoveryState) {
@@ -15039,7 +15039,7 @@ function isLaneOwnedByCurrentSession(branchName, expectedSessionId) {
15039
15039
  return extracted === expectedSessionId;
15040
15040
  }
15041
15041
  async function inspectStandardWorktreeCollisionOwnership(identity) {
15042
- const collisionOwnership = await import("./worktree-collision-ownership-80n814a8.js");
15042
+ const collisionOwnership = await import("./worktree-collision-ownership-4yxah5wy.js");
15043
15043
  return collisionOwnership.inspectStandardWorktreeCollisionOwnership(identity);
15044
15044
  }
15045
15045
  async function runRecoveryGit(directory, args, timeoutMs = 15000) {
@@ -15465,7 +15465,7 @@ async function precreateStandardWorktreeSession(args) {
15465
15465
  const laneProfile = computeLaneRuntimeProfile(worktreeConfig.runtime_isolation, laneIndex, handle.worktreePath);
15466
15466
  if (laneProfile) {
15467
15467
  try {
15468
- const { writeLaneProfileToDiskReal } = await import("./core-cxnqsrxp.js");
15468
+ const { writeLaneProfileToDiskReal } = await import("./core-fvsjr20m.js");
15469
15469
  await writeLaneProfileToDiskReal(handle.worktreePath, laneProfile.laneIndex, laneProfile.envOverrides);
15470
15470
  } catch {}
15471
15471
  }
@@ -16444,7 +16444,7 @@ async function finishStandardWorktreeDispatch(directory, dispatch, config, callI
16444
16444
  }
16445
16445
  clearWorktreeMergeStatus(statusKey);
16446
16446
  try {
16447
- const { removeLaneProfileFromDiskReal } = await import("./core-cxnqsrxp.js");
16447
+ const { removeLaneProfileFromDiskReal } = await import("./core-fvsjr20m.js");
16448
16448
  await removeLaneProfileFromDiskReal(dispatch.handle.worktreePath, dispatch.laneIndex);
16449
16449
  } catch {}
16450
16450
  const state = serializationStateBySessionID.get(dispatch.parentSessionID);
@@ -24083,7 +24083,7 @@ function clearCriticalShownIds(sessionID) {
24083
24083
  async function rehydratePrSubscriptions(sessionID, directory) {
24084
24084
  const map = new Map;
24085
24085
  try {
24086
- const { listActive: listActive2 } = await import("./pr-subscriptions-qwr6ybcb.js");
24086
+ const { listActive: listActive2 } = await import("./pr-subscriptions-nacx8r6a.js");
24087
24087
  const records = await listActive2(directory);
24088
24088
  for (const record of records) {
24089
24089
  if (record.sessionID !== sessionID)
@@ -24427,6 +24427,16 @@ var PrReviewValidationBatchRecordSchema = exports_external.object({
24427
24427
  }).strict()).min(1),
24428
24428
  validatedAt: exports_external.string().min(1)
24429
24429
  }).strict();
24430
+ var PrReviewMicroFamilyDispatchRecordSchema = exports_external.object({
24431
+ batchId: exports_external.string().min(1),
24432
+ prHeadSha: exports_external.string().min(1),
24433
+ lanes: exports_external.array(exports_external.object({
24434
+ laneId: exports_external.string().min(1),
24435
+ workflowLane: exports_external.string().min(1),
24436
+ ownedWorkflowLanes: exports_external.array(exports_external.string().min(1)).min(1).optional()
24437
+ }).strict()).min(1),
24438
+ admittedAt: exports_external.string().min(1)
24439
+ }).strict();
24430
24440
  var PrReviewBatchCoherenceRecordSchema = exports_external.object({
24431
24441
  validatedInventory: exports_external.array(exports_external.string().min(1)),
24432
24442
  reviewerItemBindings: exports_external.record(exports_external.string().min(1), exports_external.string().regex(/^[0-9a-f]{64}$/)).optional(),
@@ -24495,6 +24505,7 @@ var PrWorkflowGateStateSchema = exports_external.object({
24495
24505
  prReviewResilience: PrReviewResilienceStateRecordSchema.optional(),
24496
24506
  prReviewContractRetryDimensions: exports_external.array(PrReviewBaseDimensionIdSchema).max(PR_REVIEW_BASE_DIMENSION_IDS.length).optional(),
24497
24507
  prReviewTriggerLedger: exports_external.array(PrReviewInlineTriggerRowSchema).length(PR_REVIEW_REQUIRED_TRIGGER_IDS.length).optional(),
24508
+ prReviewMicroFamilyDispatches: exports_external.array(PrReviewMicroFamilyDispatchRecordSchema).max(MAX_WORKFLOW_BATCHES).optional(),
24498
24509
  prReviewTriggerEvalPath: exports_external.string().min(1).optional(),
24499
24510
  prReviewTriggerEvalRunId: exports_external.string().min(1).optional(),
24500
24511
  prReviewValidationBatches: exports_external.array(PrReviewValidationBatchRecordSchema).max(MAX_WORKFLOW_BATCHES).optional(),
@@ -24568,11 +24579,11 @@ async function activatePrWorkflow(directory, sessionID, mode, options = {}) {
24568
24579
  let existing = await readPrWorkflowGateStateFromDisk3(directory, normalizedSessionID);
24569
24580
  if (existing?.mode === mode) {
24570
24581
  if (mode === "PR_FEEDBACK" && options.prUrl) {
24571
- const requestedTarget = canonicalGitHubPrUrl(options.prUrl);
24582
+ const requestedTarget = canonicalGitHubPrUrl(options.prUrl, options.forge);
24572
24583
  if (!requestedTarget) {
24573
24584
  throw new Error("BLOCKED: PR_FEEDBACK target must be a canonical GitHub PR URL");
24574
24585
  }
24575
- const existingTarget = existing.prFeedbackTargetUrl ? canonicalGitHubPrUrl(existing.prFeedbackTargetUrl) : null;
24586
+ const existingTarget = existing.prFeedbackTargetUrl ? canonicalGitHubPrUrl(existing.prFeedbackTargetUrl, options.forge) : null;
24576
24587
  if (existingTarget && requestedTarget !== existingTarget) {
24577
24588
  throw new Error(`BLOCKED: active PR_FEEDBACK targets a different GitHub pull request`);
24578
24589
  }
@@ -24606,7 +24617,7 @@ async function activatePrWorkflow(directory, sessionID, mode, options = {}) {
24606
24617
  const initialHead = options.prHeadSha ? await assertCurrentCheckoutHead(directory, options.prHeadSha, mode) : undefined;
24607
24618
  const skillContractAdvisories = await ensurePrWorkflowSkillContractsFresh(directory, mode);
24608
24619
  const timestamp = isoNow();
24609
- const feedbackTargetUrl = mode === "PR_FEEDBACK" && options.prUrl ? canonicalGitHubPrUrl(options.prUrl) ? options.prUrl : null : undefined;
24620
+ const feedbackTargetUrl = mode === "PR_FEEDBACK" && options.prUrl ? canonicalGitHubPrUrl(options.prUrl, options.forge) ? options.prUrl : null : undefined;
24610
24621
  if (feedbackTargetUrl === null) {
24611
24622
  throw new Error("BLOCKED: PR_FEEDBACK target must be a canonical GitHub PR URL");
24612
24623
  }
@@ -26917,6 +26928,36 @@ async function assertPrReviewBaseCoverageSettled2(directory, sessionID, gateCont
26917
26928
  settlement: settled.settlement
26918
26929
  };
26919
26930
  }
26931
+ async function recordPrReviewMicroFamilyDispatch(directory, sessionID, lanes, options) {
26932
+ const state = await bindPrWorkflowHead(directory, sessionID, options.prHeadSha);
26933
+ if (state.mode !== "PR_REVIEW")
26934
+ throw wrongModeError(state, "PR_REVIEW");
26935
+ const batchId = normalizeBatchId(options.batchId);
26936
+ const previous = state.prReviewMicroFamilyDispatches ?? [];
26937
+ if (previous.some((record2) => record2.batchId === batchId)) {
26938
+ return state;
26939
+ }
26940
+ if (previous.length >= MAX_WORKFLOW_BATCHES) {
26941
+ throw new Error(`BLOCKED: PR_REVIEW micro-family dispatch ledger limit reached (${MAX_WORKFLOW_BATCHES} recorded acknowledgments). Nothing was appended and no lane was launched, so re-issuing this dispatch call is safe once the ledger has room. A healthy run records at most ~${11 * (1 + 2)} acknowledgments (11 families x initial dispatch + 2 retries), so reaching the cap indicates a dispatch loop. Recovery: let the active workflow settle or restart with abort_pr_workflow (kind "recovery").`);
26942
+ }
26943
+ const record = {
26944
+ batchId,
26945
+ prHeadSha: options.prHeadSha,
26946
+ lanes: normalizeWorkflowLanes(lanes).map((lane) => ({
26947
+ laneId: lane.laneId,
26948
+ workflowLane: lane.workflowLane,
26949
+ ...lane.ownedWorkflowLanes?.length ? { ownedWorkflowLanes: lane.ownedWorkflowLanes } : {}
26950
+ })),
26951
+ admittedAt: isoNow()
26952
+ };
26953
+ const nextState = {
26954
+ ...state,
26955
+ updatedAt: isoNow(),
26956
+ prReviewMicroFamilyDispatches: [...previous, record]
26957
+ };
26958
+ await persistState(directory, nextState);
26959
+ return nextState;
26960
+ }
26920
26961
  async function recordPrReviewValidationBatch(directory, sessionID, phase, lanes, options) {
26921
26962
  let state = await bindPrWorkflowHead(directory, sessionID, options.prHeadSha);
26922
26963
  if (state.mode !== "PR_REVIEW")
@@ -29150,8 +29191,8 @@ async function readPrReviewFinalFindingPolicyForReport(directory, sessionID) {
29150
29191
  const blockingFindingIds = policyProjection.blockingFindingIds.flatMap((id) => sourceIdsByPolicyFindingId.get(id) ?? [id]).sort();
29151
29192
  return { policyVersion: 1, permittedVerdicts, blockingFindingIds };
29152
29193
  }
29153
- function canonicalGitHubPrUrl(value) {
29154
- return canonicalForgePrUrl(value);
29194
+ function canonicalGitHubPrUrl(value, configured) {
29195
+ return canonicalForgePrUrl(value, configured);
29155
29196
  }
29156
29197
  function assertMatchingPrReviewFeedbackConsent(record, input) {
29157
29198
  if (record.session_id !== input.sessionID || record.run_id !== input.runId || record.handoff_path !== input.handoffPath || record.handoff_digest !== input.handoffDigest || canonicalGitHubPrUrl(record.pr_url) !== canonicalGitHubPrUrl(input.prUrl) || record.pr_head_sha.toLowerCase() !== input.prHeadSha.toLowerCase() || record.finding_ids_digest !== input.findingIdsDigest || record.source_workflow_instance_id !== input.sourceWorkflowInstanceId) {
@@ -32223,6 +32264,128 @@ async function readPrWorkflowGateStateForRecovery(directory, sessionID) {
32223
32264
  // src/commands/registry.ts
32224
32265
  init_logger();
32225
32266
 
32267
+ // src/commands/_shared/url-security.ts
32268
+ import * as child_process from "child_process";
32269
+ init_git_executable();
32270
+ var MAX_URL_LEN = 2048;
32271
+ var _internals32 = {
32272
+ spawnSync: (cmd, args, options) => {
32273
+ const mergedEnv = mergeEnvForChild(options?.env, options?.envOverrides);
32274
+ return child_process.spawnSync(cmd, args, {
32275
+ ...options,
32276
+ env: mergedEnv
32277
+ });
32278
+ }
32279
+ };
32280
+ function sanitizeUrl(raw) {
32281
+ let urlStr = raw.trim();
32282
+ urlStr = urlStr.replace(/^([A-Za-z][A-Za-z0-9+.-]*:\/\/)\/?[^@/]+@/, "$1");
32283
+ urlStr = urlStr.replace(/\[\s*MODE\s*:[^\]]*\]/gi, "");
32284
+ urlStr = urlStr.replace(/^([A-Za-z][A-Za-z0-9+.-]*:\/\/)\/?[^@/]+@/, "$1");
32285
+ const fragmentIdx = urlStr.indexOf("#");
32286
+ if (fragmentIdx !== -1) {
32287
+ urlStr = urlStr.slice(0, fragmentIdx);
32288
+ }
32289
+ const queryIdx = urlStr.indexOf("?");
32290
+ if (queryIdx !== -1) {
32291
+ urlStr = urlStr.slice(0, queryIdx);
32292
+ }
32293
+ if (urlStr.length > MAX_URL_LEN) {
32294
+ urlStr = urlStr.slice(0, MAX_URL_LEN);
32295
+ }
32296
+ return urlStr.trim();
32297
+ }
32298
+ function sanitizeErrorEcho(raw, maxLength = 80) {
32299
+ let stripped = "";
32300
+ for (const ch of raw) {
32301
+ const cp = ch.codePointAt(0);
32302
+ if (cp !== undefined && (cp <= 31 || cp === 127)) {
32303
+ stripped += " ";
32304
+ continue;
32305
+ }
32306
+ stripped += ch;
32307
+ }
32308
+ const collapsed = stripped.replace(/\s+/g, " ").trim();
32309
+ if (collapsed.length <= maxLength)
32310
+ return collapsed;
32311
+ return `${collapsed.slice(0, maxLength)}\u2026`;
32312
+ }
32313
+ function validateAndSanitizeGithubUrl(rawUrl, resource, configured) {
32314
+ const sanitized = sanitizeUrl(rawUrl);
32315
+ if (!sanitized) {
32316
+ return { error: "Empty URL" };
32317
+ }
32318
+ if (!sanitized.startsWith("https://")) {
32319
+ return { error: "URL must use HTTPS scheme" };
32320
+ }
32321
+ try {
32322
+ const url = new URL(sanitized);
32323
+ if (hasNonAsciiHostname(url.hostname)) {
32324
+ return { error: "Non-ASCII hostnames are not allowed" };
32325
+ }
32326
+ if (isPrivateHost(url)) {
32327
+ return { error: "Private or localhost URLs are not allowed" };
32328
+ }
32329
+ const matched = matchForgeResourceUrl(sanitized, resource, configured);
32330
+ if (!matched) {
32331
+ return {
32332
+ error: resource === "issues" ? "URL must be a GitHub issue URL (https://github.com/owner/repo/issues/N) or a GitLab issue URL (https://<gitlab-host>/owner/repo/-/issues/N)" : "URL must be a GitHub pull request URL (https://github.com/owner/repo/pull/N) or a GitLab merge request URL (https://<gitlab-host>/owner/repo/-/merge_requests/N)"
32333
+ };
32334
+ }
32335
+ return { sanitized };
32336
+ } catch {
32337
+ return { error: "Invalid URL format" };
32338
+ }
32339
+ }
32340
+ function detectGitRemote(cwd, laneEnv) {
32341
+ try {
32342
+ const result = _internals32.spawnSync(resolveGitExecutable(), ["remote", "get-url", "origin"], {
32343
+ encoding: "utf-8",
32344
+ stdio: ["ignore", "pipe", "pipe"],
32345
+ timeout: 5000,
32346
+ ...cwd ? { cwd } : {},
32347
+ envOverrides: laneEnv
32348
+ });
32349
+ if (result.status !== 0 || result.error) {
32350
+ return null;
32351
+ }
32352
+ const remoteUrl = (result.stdout ?? "").trim();
32353
+ return remoteUrl || null;
32354
+ } catch {
32355
+ return null;
32356
+ }
32357
+ }
32358
+ function parseGitRemoteUrl(remoteUrl) {
32359
+ const httpsMatch = remoteUrl.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?\/?$/i);
32360
+ if (httpsMatch) {
32361
+ const owner = httpsMatch[1];
32362
+ const repo = httpsMatch[2].replace(/\.git$/, "");
32363
+ if (containsControlCharacters(owner) || containsControlCharacters(repo)) {
32364
+ return null;
32365
+ }
32366
+ return { owner, repo };
32367
+ }
32368
+ const sshMatch = remoteUrl.match(/^git@github\.com:([^/]+)\/([^/]+?)(?:\.git)?$/i);
32369
+ if (sshMatch) {
32370
+ const owner = sshMatch[1];
32371
+ const repo = sshMatch[2].replace(/\.git$/, "");
32372
+ if (containsControlCharacters(owner) || containsControlCharacters(repo)) {
32373
+ return null;
32374
+ }
32375
+ return { owner, repo };
32376
+ }
32377
+ const pathMatch = remoteUrl.match(/\/([^/]+)\/([^/]+?)(?:\.git)?\/?$/);
32378
+ if (pathMatch) {
32379
+ const owner = pathMatch[1];
32380
+ const repo = pathMatch[2].replace(/\.git$/, "");
32381
+ if (containsControlCharacters(owner) || containsControlCharacters(repo)) {
32382
+ return null;
32383
+ }
32384
+ return { owner, repo };
32385
+ }
32386
+ return null;
32387
+ }
32388
+
32226
32389
  // src/commands/abort-pr-workflow.ts
32227
32390
  var USAGE2 = [
32228
32391
  "Usage: /swarm abort-pr-workflow [PR_REVIEW|PR_FEEDBACK] [reason...]",
@@ -32327,7 +32490,7 @@ import { createHash as createHash24 } from "crypto";
32327
32490
  import { mkdir as mkdir6, readFile as readFile10, unlink as unlink2 } from "fs/promises";
32328
32491
  import { dirname as dirname15 } from "path";
32329
32492
  var SPEC_DRIFT_RECOVERY_AGENT = "spec-drift-recovery";
32330
- var _internals32 = {
32493
+ var _internals33 = {
32331
32494
  appendEvent,
32332
32495
  assertProjectRoot,
32333
32496
  bunWrite,
@@ -32412,21 +32575,21 @@ async function writeWal3(walPath, wal) {
32412
32575
  }
32413
32576
  async function verifySnapshot(snapshotPath, currentSpec) {
32414
32577
  if (!currentSpec) {
32415
- await _internals32.unlinkIfExists(snapshotPath);
32416
- const stillExists = await _internals32.readFileText(snapshotPath) !== null;
32578
+ await _internals33.unlinkIfExists(snapshotPath);
32579
+ const stillExists = await _internals33.readFileText(snapshotPath) !== null;
32417
32580
  if (stillExists) {
32418
32581
  throw new Error("spec snapshot verification failed: snapshot still exists after delete");
32419
32582
  }
32420
32583
  return;
32421
32584
  }
32422
32585
  await atomicWriteFile(snapshotPath, currentSpec.content);
32423
- const written = await _internals32.readFileText(snapshotPath);
32586
+ const written = await _internals33.readFileText(snapshotPath);
32424
32587
  if (written !== currentSpec.content) {
32425
32588
  throw new Error("spec snapshot verification failed: snapshot content does not match effective spec");
32426
32589
  }
32427
32590
  }
32428
32591
  async function ensureSnapshotEvent(directory, plan, transitionId) {
32429
- const events = await _internals32.readLedgerEvents(directory);
32592
+ const events = await _internals33.readLedgerEvents(directory);
32430
32593
  for (const event of events) {
32431
32594
  const payload = event.payload;
32432
32595
  const approval = payload?.approval;
@@ -32434,17 +32597,17 @@ async function ensureSnapshotEvent(directory, plan, transitionId) {
32434
32597
  return;
32435
32598
  }
32436
32599
  }
32437
- await _internals32.takeSnapshotEvent(directory, plan, {
32600
+ await _internals33.takeSnapshotEvent(directory, plan, {
32438
32601
  source: "spec_drift_recovery",
32439
32602
  approvalMetadata: { specDriftTransitionId: transitionId }
32440
32603
  });
32441
32604
  }
32442
32605
  async function appendEvent(directory, event) {
32443
- const existing = await _internals32.verifyEventPresence(directory, event.type, event.transitionId);
32606
+ const existing = await _internals33.verifyEventPresence(directory, event.type, event.transitionId);
32444
32607
  if (existing)
32445
32608
  return;
32446
32609
  appendCoreEventSync(directory, { ...event }, { dedupeOnAuthorityKey: true });
32447
- const verified = await _internals32.verifyEventPresence(directory, event.type, event.transitionId);
32610
+ const verified = await _internals33.verifyEventPresence(directory, event.type, event.transitionId);
32448
32611
  if (!verified) {
32449
32612
  throw new Error(`spec drift audit verification failed for transition ${event.transitionId}`);
32450
32613
  }
@@ -32466,7 +32629,7 @@ function buildRecoveryEvent(args) {
32466
32629
  if (args.mode === "acknowledge") {
32467
32630
  return {
32468
32631
  type: "spec_drift_acknowledged",
32469
- timestamp: _internals32.now(),
32632
+ timestamp: _internals33.now(),
32470
32633
  phase: args.phase,
32471
32634
  planTitle: args.planTitle,
32472
32635
  acknowledgedBy: args.actor === "spec_write" ? "unknown" : args.actor,
@@ -32478,7 +32641,7 @@ function buildRecoveryEvent(args) {
32478
32641
  }
32479
32642
  return {
32480
32643
  type: "spec_drift_repaired",
32481
- timestamp: _internals32.now(),
32644
+ timestamp: _internals33.now(),
32482
32645
  phase: args.phase,
32483
32646
  planTitle: args.planTitle,
32484
32647
  repairedBy: args.actor,
@@ -32489,11 +32652,11 @@ function buildRecoveryEvent(args) {
32489
32652
  };
32490
32653
  }
32491
32654
  async function reconcileSpecDrift(directory, options) {
32492
- _internals32.assertProjectRoot(directory);
32493
- const markerPath = _internals32.validateSwarmPath(directory, "spec-staleness.json");
32494
- const walPath = _internals32.validateSwarmPath(directory, "spec-drift-recovery.json");
32495
- const snapshotPath = _internals32.validateSwarmPath(directory, "spec-snapshot.md");
32496
- const markerMaybe = await _internals32.readFileText(markerPath);
32655
+ _internals33.assertProjectRoot(directory);
32656
+ const markerPath = _internals33.validateSwarmPath(directory, "spec-staleness.json");
32657
+ const walPath = _internals33.validateSwarmPath(directory, "spec-drift-recovery.json");
32658
+ const snapshotPath = _internals33.validateSwarmPath(directory, "spec-snapshot.md");
32659
+ const markerMaybe = await _internals33.readFileText(markerPath);
32497
32660
  if (markerMaybe === null) {
32498
32661
  return {
32499
32662
  status: "no_marker",
@@ -32501,7 +32664,7 @@ async function reconcileSpecDrift(directory, options) {
32501
32664
  message: "No spec drift detected."
32502
32665
  };
32503
32666
  }
32504
- const specLockResult = options.specLockAlreadyHeld ? null : await _internals32.tryAcquireLock(directory, "spec.md", SPEC_DRIFT_RECOVERY_AGENT, `spec-${options.mode}-${Date.now()}`);
32667
+ const specLockResult = options.specLockAlreadyHeld ? null : await _internals33.tryAcquireLock(directory, "spec.md", SPEC_DRIFT_RECOVERY_AGENT, `spec-${options.mode}-${Date.now()}`);
32505
32668
  if (specLockResult && !specLockResult.acquired) {
32506
32669
  return {
32507
32670
  status: "retry_later",
@@ -32511,7 +32674,7 @@ async function reconcileSpecDrift(directory, options) {
32511
32674
  }
32512
32675
  let lockResult;
32513
32676
  try {
32514
- lockResult = await _internals32.tryAcquireLock(directory, "plan.json", SPEC_DRIFT_RECOVERY_AGENT, `${options.mode}-${Date.now()}`);
32677
+ lockResult = await _internals33.tryAcquireLock(directory, "plan.json", SPEC_DRIFT_RECOVERY_AGENT, `${options.mode}-${Date.now()}`);
32515
32678
  } catch (error2) {
32516
32679
  if (specLockResult?.acquired && specLockResult.lock._release) {
32517
32680
  await specLockResult.lock._release().catch(() => {});
@@ -32537,7 +32700,7 @@ async function reconcileSpecDrift(directory, options) {
32537
32700
  let errorNewHash;
32538
32701
  try {
32539
32702
  try {
32540
- const authoritativeMarkerRaw = await _internals32.readFileText(markerPath);
32703
+ const authoritativeMarkerRaw = await _internals33.readFileText(markerPath);
32541
32704
  if (authoritativeMarkerRaw === null) {
32542
32705
  return {
32543
32706
  status: "no_marker",
@@ -32545,14 +32708,14 @@ async function reconcileSpecDrift(directory, options) {
32545
32708
  message: "No spec drift detected."
32546
32709
  };
32547
32710
  }
32548
- const marker = _internals32.parseMarker(authoritativeMarkerRaw);
32711
+ const marker = _internals33.parseMarker(authoritativeMarkerRaw);
32549
32712
  if (!marker) {
32550
32713
  return buildCorruptMarkerResult(options.mode);
32551
32714
  }
32552
32715
  errorMarker = marker;
32553
32716
  const markerHash = sha2563(authoritativeMarkerRaw);
32554
- const existingWalRaw = await _internals32.readFileText(walPath);
32555
- const existingWal = existingWalRaw === null ? null : _internals32.parseWal(existingWalRaw);
32717
+ const existingWalRaw = await _internals33.readFileText(walPath);
32718
+ const existingWal = existingWalRaw === null ? null : _internals33.parseWal(existingWalRaw);
32556
32719
  if (existingWalRaw !== null && !existingWal) {
32557
32720
  return {
32558
32721
  status: "failed",
@@ -32562,7 +32725,7 @@ async function reconcileSpecDrift(directory, options) {
32562
32725
  planTitle: marker.planTitle
32563
32726
  };
32564
32727
  }
32565
- const currentSpec = _internals32.readEffectiveSpecSync(directory);
32728
+ const currentSpec = _internals33.readEffectiveSpecSync(directory);
32566
32729
  const proposedNewHash = currentSpec?.hash ?? null;
32567
32730
  const proposedTransitionId = buildTransitionId(options.mode, markerHash, marker.specHash_plan, proposedNewHash);
32568
32731
  const proposedWal = {
@@ -32577,7 +32740,7 @@ async function reconcileSpecDrift(directory, options) {
32577
32740
  newHash: proposedNewHash,
32578
32741
  specContent: currentSpec?.content ?? null,
32579
32742
  actor: options.actor,
32580
- recordedAt: _internals32.now()
32743
+ recordedAt: _internals33.now()
32581
32744
  };
32582
32745
  const markerReplacedDuringPrepared = existingWal?.state === "PREPARED" && existingWal.markerHash !== markerHash;
32583
32746
  const wal = existingWal?.state === "PREPARED" || existingWal?.markerHash === markerHash ? existingWal : proposedWal;
@@ -32586,12 +32749,12 @@ async function reconcileSpecDrift(directory, options) {
32586
32749
  errorTransitionId = transitionId;
32587
32750
  errorNewHash = newHash;
32588
32751
  if (wal === proposedWal) {
32589
- await _internals32.writeWal(walPath, wal);
32752
+ await _internals33.writeWal(walPath, wal);
32590
32753
  }
32591
32754
  if (wal.newHash === null !== (wal.specContent === null) || wal.specContent !== null && sha2563(wal.specContent) !== wal.newHash) {
32592
32755
  throw new Error(`Spec drift recovery WAL ${transitionId} has inconsistent captured spec content`);
32593
32756
  }
32594
- let plan = await _internals32.loadPlanJsonOnly(directory);
32757
+ let plan = await _internals33.loadPlanJsonOnly(directory);
32595
32758
  if (!plan) {
32596
32759
  return {
32597
32760
  status: "failed",
@@ -32622,13 +32785,13 @@ async function reconcileSpecDrift(directory, options) {
32622
32785
  }
32623
32786
  if (planMatchesOld) {
32624
32787
  plan.specHash = newHash ?? undefined;
32625
- await _internals32.savePlan(directory, plan, {
32788
+ await _internals33.savePlan(directory, plan, {
32626
32789
  planLockAlreadyHeld: true
32627
32790
  });
32628
- plan = await _internals32.loadPlanJsonOnly(directory) ?? plan;
32791
+ plan = await _internals33.loadPlanJsonOnly(directory) ?? plan;
32629
32792
  }
32630
- await _internals32.ensureSnapshotEvent(directory, plan, transitionId);
32631
- await _internals32.verifySnapshot(snapshotPath, wal.specContent === null ? null : { content: wal.specContent });
32793
+ await _internals33.ensureSnapshotEvent(directory, plan, transitionId);
32794
+ await _internals33.verifySnapshot(snapshotPath, wal.specContent === null ? null : { content: wal.specContent });
32632
32795
  const event = buildRecoveryEvent({
32633
32796
  mode: wal.mode,
32634
32797
  actor: wal.actor,
@@ -32639,15 +32802,15 @@ async function reconcileSpecDrift(directory, options) {
32639
32802
  previousHash: wal.previousHash,
32640
32803
  transitionId
32641
32804
  });
32642
- await _internals32.appendEvent(directory, event);
32643
- await _internals32.writeWal(walPath, { ...wal, state: "COMMITTED" });
32805
+ await _internals33.appendEvent(directory, event);
32806
+ await _internals33.writeWal(walPath, { ...wal, state: "COMMITTED" });
32644
32807
  }
32645
32808
  if (markerReplacedDuringPrepared) {
32646
32809
  const preservedMarker = {
32647
32810
  ...marker,
32648
32811
  specHash_plan: newHash,
32649
32812
  reason: `prior prepared drift recovery committed before this marker: ${marker.reason}`,
32650
- timestamp: _internals32.now()
32813
+ timestamp: _internals33.now()
32651
32814
  };
32652
32815
  await atomicWriteFile(markerPath, `${JSON.stringify(preservedMarker, null, 2)}
32653
32816
  `);
@@ -32662,7 +32825,7 @@ async function reconcileSpecDrift(directory, options) {
32662
32825
  transitionId
32663
32826
  };
32664
32827
  }
32665
- const latestSpec = _internals32.readEffectiveSpecSync(directory);
32828
+ const latestSpec = _internals33.readEffectiveSpecSync(directory);
32666
32829
  if ((latestSpec?.hash ?? null) !== newHash) {
32667
32830
  const refreshedMarker = {
32668
32831
  planTitle: wal.planTitle,
@@ -32670,7 +32833,7 @@ async function reconcileSpecDrift(directory, options) {
32670
32833
  specHash_plan: newHash,
32671
32834
  specHash_current: latestSpec?.hash ?? null,
32672
32835
  reason: "spec changed while drift recovery was committing",
32673
- timestamp: _internals32.now()
32836
+ timestamp: _internals33.now()
32674
32837
  };
32675
32838
  await atomicWriteFile(markerPath, `${JSON.stringify(refreshedMarker, null, 2)}
32676
32839
  `);
@@ -32686,8 +32849,8 @@ async function reconcileSpecDrift(directory, options) {
32686
32849
  };
32687
32850
  }
32688
32851
  try {
32689
- await _internals32.unlinkIfExists(markerPath);
32690
- _internals32.invalidateCachedArtifact(markerPath);
32852
+ await _internals33.unlinkIfExists(markerPath);
32853
+ _internals33.invalidateCachedArtifact(markerPath);
32691
32854
  } catch (error2) {
32692
32855
  return {
32693
32856
  status: "cleanup_pending",
@@ -33184,7 +33347,7 @@ ${USAGE4}`;
33184
33347
 
33185
33348
  // src/commands/archive.ts
33186
33349
  init_loader();
33187
- var _internals33 = {
33350
+ var _internals34 = {
33188
33351
  now: () => new Date
33189
33352
  };
33190
33353
  function artifactLabel(artifact) {
@@ -33240,7 +33403,7 @@ async function handleArchiveCommand(directory, args) {
33240
33403
  const report = await archiveEvidence(directory, maxAgeDays, maxBundles, {
33241
33404
  report: true,
33242
33405
  dryRun,
33243
- now: _internals33.now(),
33406
+ now: _internals34.now(),
33244
33407
  cacheMaxBytes,
33245
33408
  cacheMaxRecords
33246
33409
  });
@@ -35207,7 +35370,7 @@ function createShadowCopy(directory, maxBytes = MAX_SHADOW_COPY_BYTES) {
35207
35370
  const rel = path33.relative(directory, src);
35208
35371
  const dest = path33.join(shadowRoot, rel);
35209
35372
  fs21.mkdirSync(path33.dirname(dest), { recursive: true });
35210
- const copied = _internals34.copyFileBounded(src, dest, maxBytes - copiedBytes);
35373
+ const copied = _internals35.copyFileBounded(src, dest, maxBytes - copiedBytes);
35211
35374
  if (copied === null) {
35212
35375
  removeShadowRoot(shadowRoot);
35213
35376
  return null;
@@ -35220,7 +35383,7 @@ function createShadowCopy(directory, maxBytes = MAX_SHADOW_COPY_BYTES) {
35220
35383
  throw error2;
35221
35384
  }
35222
35385
  }
35223
- var _internals34 = {
35386
+ var _internals35 = {
35224
35387
  computeEvidenceQualitySummary,
35225
35388
  copyFileBounded,
35226
35389
  createShadowCopy
@@ -35467,7 +35630,7 @@ async function evaluateAdvisoryCi(options) {
35467
35630
  });
35468
35631
  }
35469
35632
  }
35470
- const summary = await _internals34.computeEvidenceQualitySummary(directory);
35633
+ const summary = await _internals35.computeEvidenceQualitySummary(directory);
35471
35634
  const q = summary.qualityMetrics;
35472
35635
  const qualityRows = [
35473
35636
  [
@@ -35861,7 +36024,7 @@ async function handleCiCommand(ctx) {
35861
36024
  const signals = createSignalCancellation(controller);
35862
36025
  signals.install();
35863
36026
  try {
35864
- const result = await _internals35.runAdvisoryCiRuntime({
36027
+ const result = await _internals36.runAdvisoryCiRuntime({
35865
36028
  directory: ctx.directory,
35866
36029
  deadlineMs,
35867
36030
  signal: controller.signal,
@@ -35910,134 +36073,10 @@ async function handleCiCommand(ctx) {
35910
36073
  signals.dispose();
35911
36074
  }
35912
36075
  }
35913
- var _internals35 = { runAdvisoryCiRuntime };
36076
+ var _internals36 = { runAdvisoryCiRuntime };
35914
36077
 
35915
36078
  // src/commands/pr-ref.ts
35916
36079
  init_loader();
35917
-
35918
- // src/commands/_shared/url-security.ts
35919
- import * as child_process from "child_process";
35920
- init_git_executable();
35921
- var MAX_URL_LEN = 2048;
35922
- var _internals36 = {
35923
- spawnSync: (cmd, args, options) => {
35924
- const mergedEnv = mergeEnvForChild(options?.env, options?.envOverrides);
35925
- return child_process.spawnSync(cmd, args, {
35926
- ...options,
35927
- env: mergedEnv
35928
- });
35929
- }
35930
- };
35931
- function sanitizeUrl(raw) {
35932
- let urlStr = raw.trim();
35933
- urlStr = urlStr.replace(/^([A-Za-z][A-Za-z0-9+.-]*:\/\/)\/?[^@/]+@/, "$1");
35934
- urlStr = urlStr.replace(/\[\s*MODE\s*:[^\]]*\]/gi, "");
35935
- urlStr = urlStr.replace(/^([A-Za-z][A-Za-z0-9+.-]*:\/\/)\/?[^@/]+@/, "$1");
35936
- const fragmentIdx = urlStr.indexOf("#");
35937
- if (fragmentIdx !== -1) {
35938
- urlStr = urlStr.slice(0, fragmentIdx);
35939
- }
35940
- const queryIdx = urlStr.indexOf("?");
35941
- if (queryIdx !== -1) {
35942
- urlStr = urlStr.slice(0, queryIdx);
35943
- }
35944
- if (urlStr.length > MAX_URL_LEN) {
35945
- urlStr = urlStr.slice(0, MAX_URL_LEN);
35946
- }
35947
- return urlStr.trim();
35948
- }
35949
- function sanitizeErrorEcho(raw, maxLength = 80) {
35950
- let stripped = "";
35951
- for (const ch of raw) {
35952
- const cp = ch.codePointAt(0);
35953
- if (cp !== undefined && (cp <= 31 || cp === 127)) {
35954
- stripped += " ";
35955
- continue;
35956
- }
35957
- stripped += ch;
35958
- }
35959
- const collapsed = stripped.replace(/\s+/g, " ").trim();
35960
- if (collapsed.length <= maxLength)
35961
- return collapsed;
35962
- return `${collapsed.slice(0, maxLength)}\u2026`;
35963
- }
35964
- function validateAndSanitizeGithubUrl(rawUrl, resource, configured) {
35965
- const sanitized = sanitizeUrl(rawUrl);
35966
- if (!sanitized) {
35967
- return { error: "Empty URL" };
35968
- }
35969
- if (!sanitized.startsWith("https://")) {
35970
- return { error: "URL must use HTTPS scheme" };
35971
- }
35972
- try {
35973
- const url = new URL(sanitized);
35974
- if (hasNonAsciiHostname(url.hostname)) {
35975
- return { error: "Non-ASCII hostnames are not allowed" };
35976
- }
35977
- if (isPrivateHost(url)) {
35978
- return { error: "Private or localhost URLs are not allowed" };
35979
- }
35980
- const matched = matchForgeResourceUrl(sanitized, resource, configured);
35981
- if (!matched) {
35982
- return {
35983
- error: resource === "issues" ? "URL must be a GitHub issue URL (https://github.com/owner/repo/issues/N) or a GitLab issue URL (https://<gitlab-host>/owner/repo/-/issues/N)" : "URL must be a GitHub pull request URL (https://github.com/owner/repo/pull/N) or a GitLab merge request URL (https://<gitlab-host>/owner/repo/-/merge_requests/N)"
35984
- };
35985
- }
35986
- return { sanitized };
35987
- } catch {
35988
- return { error: "Invalid URL format" };
35989
- }
35990
- }
35991
- function detectGitRemote(cwd, laneEnv) {
35992
- try {
35993
- const result = _internals36.spawnSync(resolveGitExecutable(), ["remote", "get-url", "origin"], {
35994
- encoding: "utf-8",
35995
- stdio: ["ignore", "pipe", "pipe"],
35996
- timeout: 5000,
35997
- ...cwd ? { cwd } : {},
35998
- envOverrides: laneEnv
35999
- });
36000
- if (result.status !== 0 || result.error) {
36001
- return null;
36002
- }
36003
- const remoteUrl = (result.stdout ?? "").trim();
36004
- return remoteUrl || null;
36005
- } catch {
36006
- return null;
36007
- }
36008
- }
36009
- function parseGitRemoteUrl(remoteUrl) {
36010
- const httpsMatch = remoteUrl.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?\/?$/i);
36011
- if (httpsMatch) {
36012
- const owner = httpsMatch[1];
36013
- const repo = httpsMatch[2].replace(/\.git$/, "");
36014
- if (containsControlCharacters(owner) || containsControlCharacters(repo)) {
36015
- return null;
36016
- }
36017
- return { owner, repo };
36018
- }
36019
- const sshMatch = remoteUrl.match(/^git@github\.com:([^/]+)\/([^/]+?)(?:\.git)?$/i);
36020
- if (sshMatch) {
36021
- const owner = sshMatch[1];
36022
- const repo = sshMatch[2].replace(/\.git$/, "");
36023
- if (containsControlCharacters(owner) || containsControlCharacters(repo)) {
36024
- return null;
36025
- }
36026
- return { owner, repo };
36027
- }
36028
- const pathMatch = remoteUrl.match(/\/([^/]+)\/([^/]+?)(?:\.git)?\/?$/);
36029
- if (pathMatch) {
36030
- const owner = pathMatch[1];
36031
- const repo = pathMatch[2].replace(/\.git$/, "");
36032
- if (containsControlCharacters(owner) || containsControlCharacters(repo)) {
36033
- return null;
36034
- }
36035
- return { owner, repo };
36036
- }
36037
- return null;
36038
- }
36039
-
36040
- // src/commands/pr-ref.ts
36041
36080
  var MAX_INSTRUCTIONS_LEN = 1000;
36042
36081
  var GITHUB_CONTEXT = {
36043
36082
  provider: "github",
@@ -40455,9 +40494,9 @@ function hashContent(content) {
40455
40494
  return createHash27("sha1").update(content).digest("hex");
40456
40495
  }
40457
40496
  async function loadConfigForPolicyCurator(directory) {
40458
- const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-yvhamv41.js");
40497
+ const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-g377jsvv.js");
40459
40498
  try {
40460
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-fa014mra.js");
40499
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-xkxt1b08.js");
40461
40500
  const { config: loadedConfig } = loadPluginConfigWithMeta2(directory);
40462
40501
  return KnowledgeConfigSchema2.parse(loadedConfig.knowledge ?? {});
40463
40502
  } catch {
@@ -43515,7 +43554,7 @@ async function resolveCuratorLLMDelegate(directory, mode, sessionId) {
43515
43554
  const seam = _internals38.createCuratorLLMDelegate;
43516
43555
  if (seam)
43517
43556
  return seam(directory, mode, sessionId);
43518
- const { createCuratorLLMDelegate } = await import("./curator-llm-factory-hkk29g2y.js");
43557
+ const { createCuratorLLMDelegate } = await import("./curator-llm-factory-29cswvhr.js");
43519
43558
  return createCuratorLLMDelegate(directory, mode, sessionId);
43520
43559
  }
43521
43560
  async function reconcileCloseTerminalStateForPlan(directory, targetPlan, options) {
@@ -43910,7 +43949,7 @@ async function runFinalizeStage(ctx) {
43910
43949
  }
43911
43950
  }
43912
43951
  try {
43913
- const { CuratorConfigSchema: CCS } = await import("./schema-yvhamv41.js");
43952
+ const { CuratorConfigSchema: CCS } = await import("./schema-g377jsvv.js");
43914
43953
  const { config: pmLoadedConfig } = _internals38.loadPluginConfigWithMeta(ctx.directory);
43915
43954
  const curatorCfg = CCS.parse(pmLoadedConfig.curator ?? {});
43916
43955
  if (curatorCfg.enabled && curatorCfg.postmortem_enabled) {
@@ -46096,7 +46135,7 @@ function serializeAgentSession(s) {
46096
46135
  }
46097
46136
  async function writeSnapshot(directory, state) {
46098
46137
  try {
46099
- const { ensureSnapshotCoordinationReady } = await import("./snapshot-coordination-init-xqxek8kn.js");
46138
+ const { ensureSnapshotCoordinationReady } = await import("./snapshot-coordination-init-k1f93806.js");
46100
46139
  await ensureSnapshotCoordinationReady(directory);
46101
46140
  const snapshot = {
46102
46141
  version: 3,
@@ -49274,7 +49313,7 @@ function planMerges(active, threshold, maxComparisons, maxMerges) {
49274
49313
  };
49275
49314
  }
49276
49315
  async function sweepActiveNearDuplicates(directory, options = {}) {
49277
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-fa014mra.js");
49316
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-xkxt1b08.js");
49278
49317
  const { config } = loadPluginConfigWithMeta2(directory);
49279
49318
  const sweepConfig = config.learning?.dedup_sweep;
49280
49319
  if (sweepConfig?.enabled === false)
@@ -50155,14 +50194,14 @@ async function runCuratorInit(directory, config, llmDelegate) {
50155
50194
  }));
50156
50195
  if (llmDelegate) {
50157
50196
  try {
50158
- const userInput = [
50197
+ const userInput = sanitizeContextText([
50159
50198
  "TASK: CURATOR_INIT",
50160
50199
  `PRIOR_SUMMARY: ${priorSummary ? JSON.stringify(priorSummary) : "none"}`,
50161
50200
  `KNOWLEDGE_ENTRIES: ${JSON.stringify(allEntriesForCurator)}`,
50162
- `PROJECT_CONTEXT: ${contextMd?.slice(0, config.max_summary_tokens * 2) ?? "none"}`,
50163
- `POST_MORTEM_DIGEST: ${latestPostMortemDigest ?? "none"}`
50201
+ `PROJECT_CONTEXT: ${sanitizeContextText(contextMd?.slice(0, config.max_summary_tokens * 2) ?? "none")}`,
50202
+ `POST_MORTEM_DIGEST: ${sanitizeContextText(latestPostMortemDigest ?? "none")}`
50164
50203
  ].join(`
50165
- `);
50204
+ `));
50166
50205
  const systemPrompt = CURATOR_INIT_PROMPT;
50167
50206
  const timeoutMs = config.llm_timeout_ms ?? DEFAULT_CURATOR_LLM_TIMEOUT_MS;
50168
50207
  const ac = new AbortController;
@@ -50256,7 +50295,7 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
50256
50295
  const phaseData = plan?.phases.find((p) => p.id === phase);
50257
50296
  const tasksCompleted = phaseData ? phaseData.tasks.filter((t) => t.status === "completed").length : 0;
50258
50297
  const tasksTotal = phaseData ? phaseData.tasks.length : 0;
50259
- const keyDecisions = contextMd ? extractContextDecisions(contextMd).map((decision) => decision.raw.trim().slice(2)) : [];
50298
+ const keyDecisions = contextMd ? extractContextDecisions(contextMd).map((decision) => sanitizeContextText(decision.raw.trim().slice(2))) : [];
50260
50299
  const phaseDigest = {
50261
50300
  phase,
50262
50301
  timestamp: new Date().toISOString(),
@@ -50287,16 +50326,16 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
50287
50326
  try {
50288
50327
  const priorDigest = priorSummary?.digest ?? "none";
50289
50328
  const systemPrompt = CURATOR_PHASE_PROMPT;
50290
- const userInput = [
50329
+ const userInput = sanitizeContextText([
50291
50330
  `TASK: CURATOR_PHASE ${phase}`,
50292
- `PRIOR_DIGEST: ${priorDigest}`,
50331
+ `PRIOR_DIGEST: ${sanitizeContextText(priorDigest)}`,
50293
50332
  `PHASE_EVENTS: ${JSON.stringify(phaseEvents.slice(0, 50))}`,
50294
50333
  `PHASE_DECISIONS: ${JSON.stringify(keyDecisions)}`,
50295
50334
  `AGENTS_DISPATCHED: ${JSON.stringify(agentsDispatched)}`,
50296
50335
  `AGENTS_EXPECTED: ["reviewer", "test_engineer"]`,
50297
50336
  `KNOWLEDGE_ENTRIES: ${JSON.stringify(knowledgeForCurator)}`
50298
50337
  ].join(`
50299
- `);
50338
+ `));
50300
50339
  const timeoutMs = config.llm_timeout_ms ?? DEFAULT_CURATOR_LLM_TIMEOUT_MS;
50301
50340
  const ac = new AbortController;
50302
50341
  const timer = setTimeout(() => ac.abort(), timeoutMs);
@@ -50398,7 +50437,7 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
50398
50437
  }
50399
50438
  if (config.skill_generation_enabled === true && skillCandidates.length > 0) {
50400
50439
  try {
50401
- const skillModule = await import("./skill-generator-fzvp9m8z.js");
50440
+ const skillModule = await import("./skill-generator-k3hnf8xx.js");
50402
50441
  for (const cand of skillCandidates) {
50403
50442
  if (cand.confidence < (config.min_skill_confidence ?? DEFAULT_SKILL_MIN_CONFIDENCE)) {
50404
50443
  continue;
@@ -50870,7 +50909,7 @@ async function applyCuratorKnowledgeUpdates(directory, recommendations, knowledg
50870
50909
  } catch {}
50871
50910
  }
50872
50911
  if (contradictedEntries.length > 0 && knowledgeConfig.contradiction_threshold_action === "quarantine") {
50873
- const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-30bb9fyg.js");
50912
+ const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-gajaew60.js");
50874
50913
  for (const { id } of contradictedEntries) {
50875
50914
  try {
50876
50915
  await maybeQuarantineOnContradiction(directory, id, knowledgeConfig.contradiction_quarantine_threshold, knowledgeConfig.contradiction_quarantine_window_days);
@@ -51383,9 +51422,9 @@ async function repairPostMortemActions(llmOutput, diagnostics, options) {
51383
51422
  "Allowed queue_triage action values: apply, reject.",
51384
51423
  "Do not include unsupported actions such as merge.",
51385
51424
  "Diagnostics:",
51386
- diagnostics.join("; "),
51425
+ diagnostics.map((d) => sanitizeContextText(d)).join("; "),
51387
51426
  "Original output:",
51388
- llmOutput.slice(0, 8000)
51427
+ sanitizeContextText(llmOutput).slice(0, 8000)
51389
51428
  ].join(`
51390
51429
  `);
51391
51430
  const repaired = await options.llmDelegate("", repairPrompt, ac.signal);
@@ -51601,8 +51640,8 @@ function assembleLLMInput(planId, scope, sessionID, planSummary, knowledgeSummar
51601
51640
  const sections = [];
51602
51641
  sections.push(`TASK: CURATOR_POSTMORTEM ${planId}`);
51603
51642
  sections.push(`SCOPE: ${scope}${sessionID ? ` (${sessionID})` : ""}`);
51604
- sections.push(`PLAN_SUMMARY: ${planSummary}`);
51605
- sections.push(`CURATOR_DIGESTS: ${curatorDigest ?? "none"}`);
51643
+ sections.push(`PLAN_SUMMARY: ${sanitizeContextText(planSummary)}`);
51644
+ sections.push(`CURATOR_DIGESTS: ${sanitizeContextText(curatorDigest ?? "none")}`);
51606
51645
  const eventsSummary = knowledgeSummary.map((e) => `${e.id}: applied=${e.applied} violated=${e.violated} ignored=${e.ignored} unacknowledged=${e.unacknowledged} confidence=${e.confidence.toFixed(2)} status=${e.status}`).join(`
51607
51646
  `);
51608
51647
  sections.push(`KNOWLEDGE_EVENTS_SUMMARY:
@@ -51633,9 +51672,9 @@ ${retroText}`);
51633
51672
  sections.push(`DRIFT_REPORTS:
51634
51673
  ${driftText}`);
51635
51674
  }
51636
- return sections.join(`
51675
+ return sanitizeContextText(sections.join(`
51637
51676
 
51638
- `);
51677
+ `));
51639
51678
  }
51640
51679
  async function runCuratorPostMortem(directory, options = {}) {
51641
51680
  const warnings = [];
@@ -51702,7 +51741,7 @@ async function runCuratorPostMortem(directory, options = {}) {
51702
51741
  warnings.push("Failed to collect knowledge summary.");
51703
51742
  }
51704
51743
  try {
51705
- const { getScanStatus } = await import("./scan-cursor-1m6dj2s2.js");
51744
+ const { getScanStatus } = await import("./scan-cursor-y9rchz83.js");
51706
51745
  const scanStatus = await getScanStatus(directory);
51707
51746
  if (scanStatus.remaining_estimate > 0) {
51708
51747
  warnings.push(`Fair scan: reviewed ${knowledgeSummary.length} entries this sweep (generation ${scanStatus.generation}); ${scanStatus.remaining_estimate} more eligible entries will be visited in future curation sweeps.`);
@@ -51874,9 +51913,9 @@ var _internals57 = {
51874
51913
  verifyPostMortemKnowledgeActions,
51875
51914
  repairPostMortemActions,
51876
51915
  loadDefaultKnowledgeConfig: async (directory) => {
51877
- const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-yvhamv41.js");
51916
+ const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-g377jsvv.js");
51878
51917
  try {
51879
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-fa014mra.js");
51918
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-xkxt1b08.js");
51880
51919
  const loaded = loadPluginConfigWithMeta2(directory);
51881
51920
  return KnowledgeConfigSchema2.parse(loaded.config.knowledge ?? {});
51882
51921
  } catch {
@@ -51884,11 +51923,11 @@ var _internals57 = {
51884
51923
  }
51885
51924
  },
51886
51925
  applyCuratorKnowledgeUpdates: async (directory, recommendations, knowledgeConfig, generation) => {
51887
- const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-5k3mktpe.js");
51926
+ const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-h7j1xse4.js");
51888
51927
  return applyCuratorKnowledgeUpdates2(directory, recommendations, knowledgeConfig, generation);
51889
51928
  },
51890
51929
  checkHivePromotions: async (entries2, knowledgeConfig, directory) => {
51891
- const { checkHivePromotions } = await import("./hive-promoter-400xzdds.js");
51930
+ const { checkHivePromotions } = await import("./hive-promoter-632ewk29.js");
51892
51931
  return checkHivePromotions(entries2, knowledgeConfig, directory);
51893
51932
  },
51894
51933
  applyProposalTriage: async (directory, triage) => {
@@ -51897,7 +51936,7 @@ var _internals57 = {
51897
51936
  activateProposal,
51898
51937
  listSkills: listSkills2,
51899
51938
  sanitizeSlug
51900
- } = await import("./skill-generator-fzvp9m8z.js");
51939
+ } = await import("./skill-generator-k3hnf8xx.js");
51901
51940
  const result = {
51902
51941
  approved: [],
51903
51942
  rejected: [],
@@ -51939,7 +51978,7 @@ var _internals57 = {
51939
51978
  return result;
51940
51979
  },
51941
51980
  readPriorDriftReports: async (directory) => {
51942
- const { readPriorDriftReports: readPriorDriftReports2 } = await import("./curator-drift-dt4g79a4.js");
51981
+ const { readPriorDriftReports: readPriorDriftReports2 } = await import("./curator-drift-t150w08d.js");
51943
51982
  return readPriorDriftReports2(directory);
51944
51983
  },
51945
51984
  readSwarmKnowledge: (directory) => readKnowledge(resolveSwarmKnowledgePath(directory))
@@ -61735,9 +61774,9 @@ var _internals67 = {
61735
61774
  loadPluginConfigWithMeta,
61736
61775
  loadCuratorDeps: async () => {
61737
61776
  const [{ CuratorConfigSchema }, curator, { createCuratorLLMDelegate }] = await Promise.all([
61738
- import("./schema-yvhamv41.js"),
61739
- import("./curator-5k3mktpe.js"),
61740
- import("./curator-llm-factory-hkk29g2y.js")
61777
+ import("./schema-g377jsvv.js"),
61778
+ import("./curator-h7j1xse4.js"),
61779
+ import("./curator-llm-factory-29cswvhr.js")
61741
61780
  ]);
61742
61781
  return { CuratorConfigSchema, curator, createCuratorLLMDelegate };
61743
61782
  }
@@ -64130,7 +64169,7 @@ async function computeCurationDiagnostics(directory, entries2) {
64130
64169
  let scanCompleted = false;
64131
64170
  let scanRemaining = 0;
64132
64171
  try {
64133
- const { getScanStatus } = await import("./scan-cursor-1m6dj2s2.js");
64172
+ const { getScanStatus } = await import("./scan-cursor-y9rchz83.js");
64134
64173
  const status = await getScanStatus(directory);
64135
64174
  scanGeneration = status.generation;
64136
64175
  scanCompleted = status.completed;
@@ -64138,19 +64177,19 @@ async function computeCurationDiagnostics(directory, entries2) {
64138
64177
  } catch {}
64139
64178
  let configMatch = null;
64140
64179
  try {
64141
- const { isLinked: isLinked2 } = await import("./knowledge-link-dv78fb9g.js");
64180
+ const { isLinked: isLinked2 } = await import("./knowledge-link-jnnk0nmk.js");
64142
64181
  if (isLinked2(directory)) {
64143
- const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-yvhamv41.js");
64182
+ const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-g377jsvv.js");
64144
64183
  let config;
64145
64184
  try {
64146
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-fa014mra.js");
64185
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-xkxt1b08.js");
64147
64186
  const loaded = loadPluginConfigWithMeta2(directory);
64148
64187
  config = KnowledgeConfigSchema2.parse(loaded.config.knowledge ?? {});
64149
64188
  } catch {
64150
64189
  config = KnowledgeConfigSchema2.parse({});
64151
64190
  }
64152
64191
  const { cohortConfigFingerprint: cohortConfigFingerprint2 } = await import("./config-fingerprint-v22xh5a2.js");
64153
- const { buildConfigFingerprintInput: buildConfigFingerprintInput2, readCohortConfigFingerprint } = await import("./curation-policy-ytzwb080.js");
64192
+ const { buildConfigFingerprintInput: buildConfigFingerprintInput2, readCohortConfigFingerprint } = await import("./curation-policy-pxwagyh7.js");
64154
64193
  const currentFp = cohortConfigFingerprint2(buildConfigFingerprintInput2(config));
64155
64194
  const cohortFp = await readCohortConfigFingerprint(directory);
64156
64195
  configMatch = cohortFp === null ? null : currentFp === cohortFp;
@@ -65598,7 +65637,7 @@ async function handleDoctorCommand(directory, args) {
65598
65637
  const result = runConfigDoctor(config, directory);
65599
65638
  let output;
65600
65639
  if (enableAutoFix && result.hasAutoFixableIssues) {
65601
- const { runConfigDoctorWithFixes } = await import("./config-doctor-3b99vx74.js");
65640
+ const { runConfigDoctorWithFixes } = await import("./config-doctor-mj4ae4jn.js");
65602
65641
  const fixResult = await runConfigDoctorWithFixes(directory, config, true, {
65603
65642
  applyLossy: true
65604
65643
  });
@@ -65636,7 +65675,7 @@ async function handleDoctorCommand(directory, args) {
65636
65675
  `;
65637
65676
  }
65638
65677
  try {
65639
- const { runModelPreflight } = await import("./model-preflight-g7b12yn2.js");
65678
+ const { runModelPreflight } = await import("./model-preflight-z9p55ssn.js");
65640
65679
  const preflight = await runModelPreflight(config, swarmState.opencodeClient, { generatedAgentNames: swarmState.generatedAgentNames });
65641
65680
  const missingSelection = preflight.resolutions.filter((resolution) => resolution.status === "missing-selection");
65642
65681
  const unresolved = preflight.catalogAvailable ? preflight.resolutions.filter((resolution) => resolution.status === "unresolved") : [];
@@ -66563,7 +66602,7 @@ async function handleEvidenceCommand(directory, args) {
66563
66602
  return formatTaskEvidenceMarkdown(evidenceData);
66564
66603
  }
66565
66604
  async function handleEvidenceSummaryCommand(directory) {
66566
- const { buildEvidenceSummary } = await import("./evidence-summary-service-8e2fghz0.js");
66605
+ const { buildEvidenceSummary } = await import("./evidence-summary-service-h42y6hwq.js");
66567
66606
  const artifact = await buildEvidenceSummary(directory);
66568
66607
  if (!artifact) {
66569
66608
  return "No plan found. Run `/swarm plan` to check plan status.";
@@ -90896,7 +90935,7 @@ function createCuratorLLMDelegate(directory, mode = "init", sessionId) {
90896
90935
  }
90897
90936
  const sdkOpts = signal ? { signal } : {};
90898
90937
  try {
90899
- const { getSwarmAgents: getSwarmAgents2, resolveFallbackModel: resolveFallbackModel2 } = await import("./index-rtznwf0g.js");
90938
+ const { getSwarmAgents: getSwarmAgents2, resolveFallbackModel: resolveFallbackModel2 } = await import("./index-hw8w4mkh.js");
90900
90939
  const createResult = await client.session.create({
90901
90940
  ...sessionId ? {
90902
90941
  body: {
@@ -91188,8 +91227,8 @@ init_zod();
91188
91227
  init_loader();
91189
91228
  import { createHash as createHash51, randomUUID as randomUUID22 } from "crypto";
91190
91229
  import * as fsSync9 from "fs";
91191
- import * as fs63 from "fs/promises";
91192
- import * as path127 from "path";
91230
+ import * as fs64 from "fs/promises";
91231
+ import * as path128 from "path";
91193
91232
  init_logger();
91194
91233
 
91195
91234
  // src/background/pr-feedback-event-queue.ts
@@ -92154,6 +92193,228 @@ var _internals98 = {
92154
92193
 
92155
92194
  // src/git/pr.ts
92156
92195
  init_git_executable();
92196
+
92197
+ // src/utils/glab-executable.ts
92198
+ init_warning_buffer();
92199
+ import { spawnSync as spawnSync5 } from "child_process";
92200
+ import * as fs63 from "fs";
92201
+ import * as os14 from "os";
92202
+ import * as path127 from "path";
92203
+ var GLAB_BINARY_ENV_VAR = "OPENCODE_SWARM_GLAB_BINARY";
92204
+ var PER_PROBE_TIMEOUT_MS2 = 250;
92205
+ var TOTAL_BUDGET_MS3 = 1000;
92206
+ var NEGATIVE_CACHE_TTL_MS2 = 60000;
92207
+ var BARE_GLAB = "glab";
92208
+ var PROBE_MAX_BUFFER_BYTES2 = 64 * 1024;
92209
+ var PROBE_OUTPUT_EXCERPT_CHARS2 = 60;
92210
+ var WINDOWS_PATH_EXTENSIONS2 = [".exe", ".cmd", ".bat"];
92211
+ var GLAB_VERSION_PATTERN = /^glab version \d+\.\d+/;
92212
+ function excerptProbeOutput2(raw) {
92213
+ return raw.slice(0, PROBE_OUTPUT_EXCERPT_CHARS2).replace(/[^\x20-\x7E]/g, " ").trim();
92214
+ }
92215
+ var cache3 = null;
92216
+ var lastAttempts2 = [];
92217
+ var cacheGeneration2 = 0;
92218
+ function windowsGlabAbsoluteCandidates(env) {
92219
+ const candidates = [];
92220
+ const push = (...parts) => {
92221
+ const candidate2 = path127.join(...parts);
92222
+ if (!candidates.includes(candidate2))
92223
+ candidates.push(candidate2);
92224
+ };
92225
+ if (env.ProgramFiles) {
92226
+ push(env.ProgramFiles, "GitLab CLI", "glab.exe");
92227
+ }
92228
+ if (env["ProgramFiles(x86)"]) {
92229
+ push(env["ProgramFiles(x86)"], "GitLab CLI", "glab.exe");
92230
+ }
92231
+ if (env.LOCALAPPDATA) {
92232
+ push(env.LOCALAPPDATA, "GitLab CLI", "glab.exe");
92233
+ push(env.LOCALAPPDATA, "Programs", "GitLab CLI", "glab.exe");
92234
+ }
92235
+ return candidates;
92236
+ }
92237
+ function platformCandidates2(platform, env) {
92238
+ if (platform === "win32") {
92239
+ return windowsGlabAbsoluteCandidates(env);
92240
+ }
92241
+ if (platform === "darwin") {
92242
+ return ["/opt/homebrew/bin/glab", "/usr/local/bin/glab", "/usr/bin/glab"];
92243
+ }
92244
+ return ["/usr/bin/glab", "/usr/local/bin/glab", "/bin/glab"];
92245
+ }
92246
+ function isAbsoluteForPlatform2(candidate2, platform) {
92247
+ return platform === "win32" ? path127.win32.isAbsolute(candidate2) : path127.posix.isAbsolute(candidate2);
92248
+ }
92249
+ function joinDirAndName2(dir, name, platform) {
92250
+ const sep22 = platform === "win32" ? "\\" : "/";
92251
+ const trimmed = dir.replace(/[\\/]+$/, "");
92252
+ return trimmed ? `${trimmed}${sep22}${name}` : `${sep22}${name}`;
92253
+ }
92254
+ function pathCandidates2(platform) {
92255
+ const pathValue = _internals99.env().PATH ?? "";
92256
+ if (!pathValue)
92257
+ return [];
92258
+ const dirs = pathValue.split(platform === "win32" ? ";" : ":").filter(Boolean);
92259
+ const names = platform === "win32" ? [...WINDOWS_PATH_EXTENSIONS2.map((ext) => `glab${ext}`), "glab"] : ["glab"];
92260
+ const out = [];
92261
+ for (const dir of dirs) {
92262
+ for (const name of names) {
92263
+ const candidate2 = joinDirAndName2(dir, name, platform);
92264
+ if (!out.includes(candidate2))
92265
+ out.push(candidate2);
92266
+ }
92267
+ }
92268
+ return out;
92269
+ }
92270
+ function envOverride2() {
92271
+ const raw = _internals99.env()[GLAB_BINARY_ENV_VAR];
92272
+ return raw && raw.trim() !== "" ? raw : undefined;
92273
+ }
92274
+ function buildCandidates2(platform) {
92275
+ const override = envOverride2();
92276
+ const overrideCandidate = override ? [{ source: "override", path: override }] : [];
92277
+ const seen = new Set(overrideCandidate.map((c) => c.path));
92278
+ const rest = [];
92279
+ for (const p of platformCandidates2(platform, _internals99.env())) {
92280
+ if (seen.has(p))
92281
+ continue;
92282
+ seen.add(p);
92283
+ rest.push({ source: "platform", path: p });
92284
+ }
92285
+ for (const p of pathCandidates2(platform)) {
92286
+ if (seen.has(p))
92287
+ continue;
92288
+ seen.add(p);
92289
+ rest.push({ source: "path", path: p });
92290
+ }
92291
+ return [...overrideCandidate, ...rest];
92292
+ }
92293
+ function probeCandidate2(candidatePath2, platform) {
92294
+ if (!isAbsoluteForPlatform2(candidatePath2, platform)) {
92295
+ return { accepted: false, reason: "not an absolute path" };
92296
+ }
92297
+ let stat13;
92298
+ try {
92299
+ stat13 = fs63.statSync(candidatePath2);
92300
+ } catch (err) {
92301
+ const code = err?.code;
92302
+ if (code === "ENOENT")
92303
+ return { accepted: false, reason: "no such file" };
92304
+ return {
92305
+ accepted: false,
92306
+ reason: `cannot stat (${code ?? "unknown error"})`
92307
+ };
92308
+ }
92309
+ if (stat13.isDirectory()) {
92310
+ return { accepted: false, reason: "is a directory" };
92311
+ }
92312
+ if (!stat13.isFile()) {
92313
+ return { accepted: false, reason: "not a regular file" };
92314
+ }
92315
+ let result;
92316
+ try {
92317
+ result = _internals99.spawnSync(candidatePath2, ["--version"], {
92318
+ cwd: os14.tmpdir(),
92319
+ stdio: ["ignore", "pipe", "ignore"],
92320
+ windowsHide: true,
92321
+ timeout: PER_PROBE_TIMEOUT_MS2,
92322
+ maxBuffer: PROBE_MAX_BUFFER_BYTES2
92323
+ });
92324
+ } catch (err) {
92325
+ return {
92326
+ accepted: false,
92327
+ reason: `spawn threw: ${err instanceof Error ? err.message : String(err)}`
92328
+ };
92329
+ }
92330
+ if (result.error) {
92331
+ return { accepted: false, reason: `spawn failed: ${result.error.message}` };
92332
+ }
92333
+ if (result.status !== 0) {
92334
+ const statusDescription = result.status !== null ? `exit ${result.status}` : `signal ${result.signal ?? "unknown"}`;
92335
+ return {
92336
+ accepted: false,
92337
+ reason: `glab --version returned ${statusDescription}`
92338
+ };
92339
+ }
92340
+ const versionOutput = (result.stdout ?? "").toString().trim();
92341
+ if (!GLAB_VERSION_PATTERN.test(versionOutput)) {
92342
+ const excerpt = excerptProbeOutput2(versionOutput);
92343
+ return {
92344
+ accepted: false,
92345
+ reason: excerpt ? `not glab: --version printed "${excerpt}"` : "not glab: --version printed nothing"
92346
+ };
92347
+ }
92348
+ return { accepted: true };
92349
+ }
92350
+ function probeCycle2(candidates, platform, attempts) {
92351
+ const start = _internals99.now();
92352
+ let budgetExceeded = false;
92353
+ for (const candidate2 of candidates) {
92354
+ if (_internals99.now() - start > TOTAL_BUDGET_MS3) {
92355
+ budgetExceeded = true;
92356
+ break;
92357
+ }
92358
+ const result = probeCandidate2(candidate2.path, platform);
92359
+ attempts.push({
92360
+ source: candidate2.source,
92361
+ candidate: candidate2.path,
92362
+ accepted: result.accepted,
92363
+ reason: result.accepted ? undefined : result.reason
92364
+ });
92365
+ if (candidate2.source === "override" && !result.accepted) {
92366
+ advisoryWarn(`[opencode-swarm] ${GLAB_BINARY_ENV_VAR} override "${candidate2.path}" is unusable (${result.reason}); falling back to automatic glab resolution.`);
92367
+ }
92368
+ if (result.accepted) {
92369
+ return { outcome: "accepted", path: candidate2.path };
92370
+ }
92371
+ }
92372
+ return budgetExceeded ? { outcome: "exhausted-budget" } : { outcome: "all-rejected" };
92373
+ }
92374
+ function readCache3() {
92375
+ if (cache3 === null)
92376
+ return null;
92377
+ if (cache3.kind === "success")
92378
+ return cache3;
92379
+ if (_internals99.now() < cache3.expiresAt)
92380
+ return cache3;
92381
+ cache3 = null;
92382
+ return null;
92383
+ }
92384
+ function applyProbeResult2(result, attempts, generation) {
92385
+ if (generation !== cacheGeneration2) {
92386
+ return result.outcome === "accepted" ? result.path : BARE_GLAB;
92387
+ }
92388
+ lastAttempts2 = attempts;
92389
+ if (result.outcome === "accepted") {
92390
+ cache3 = { kind: "success", path: result.path };
92391
+ return result.path;
92392
+ }
92393
+ cache3 = {
92394
+ kind: "fallback",
92395
+ expiresAt: _internals99.now() + NEGATIVE_CACHE_TTL_MS2
92396
+ };
92397
+ return BARE_GLAB;
92398
+ }
92399
+ function resolveGlabExecutable() {
92400
+ const cached = readCache3();
92401
+ if (cached)
92402
+ return cached.kind === "success" ? cached.path : BARE_GLAB;
92403
+ const platform = _internals99.platform();
92404
+ const attempts = [];
92405
+ const generation = cacheGeneration2;
92406
+ const candidates = buildCandidates2(platform);
92407
+ const result = probeCycle2(candidates, platform, attempts);
92408
+ return applyProbeResult2(result, attempts, generation);
92409
+ }
92410
+ var _internals99 = {
92411
+ spawnSync: spawnSync5,
92412
+ platform: () => process.platform,
92413
+ env: () => process.env,
92414
+ now: () => Date.now()
92415
+ };
92416
+
92417
+ // src/git/pr.ts
92157
92418
  init_logger();
92158
92419
 
92159
92420
  // src/utils/untrusted-markdown.ts
@@ -92189,7 +92450,7 @@ var EvidencePlanSchema = exports_external.object({
92189
92450
  }).passthrough()).optional()
92190
92451
  }).passthrough();
92191
92452
  function ghExec(args, cwd) {
92192
- const ghBinary = _internals99.resolveGhExecutable();
92453
+ const ghBinary = _internals100.resolveGhExecutable();
92193
92454
  for (let attempt = 0;attempt < MAX_TRANSIENT_RETRIES; attempt++) {
92194
92455
  const result = child_process5.spawnSync(ghBinary, args, {
92195
92456
  cwd,
@@ -92245,12 +92506,18 @@ function spawnSyncWithTransientRetry(command, args, options) {
92245
92506
  throw new Error(`${command} exited with null`);
92246
92507
  }
92247
92508
  async function ghExecAsync(args, cwd) {
92509
+ return _internals100.forgeExecAsync(_internals100.resolveGhExecutable(), args, cwd, "gh");
92510
+ }
92511
+ async function forgeExecAsyncImpl(binary, args, cwd, label, opts) {
92248
92512
  return new Promise((resolve40, reject) => {
92249
- const ghBinary = _internals99.resolveGhExecutable();
92250
- const proc = child_process5.spawn(ghBinary, args, {
92513
+ const spawnOptions = {
92251
92514
  cwd,
92252
92515
  stdio: ["ignore", "pipe", "pipe"]
92253
- });
92516
+ };
92517
+ if (opts?.env) {
92518
+ spawnOptions.env = mergeEnvForChild(undefined, opts.env);
92519
+ }
92520
+ const proc = child_process5.spawn(binary, args, spawnOptions);
92254
92521
  const stdoutChunks = [];
92255
92522
  const stderrChunks = [];
92256
92523
  let stdoutBytes = 0;
@@ -92274,7 +92541,7 @@ async function ghExecAsync(args, cwd) {
92274
92541
  proc.stdout?.on("data", (chunk) => {
92275
92542
  stdoutBytes += chunk.length;
92276
92543
  if (stdoutBytes > MAX_OUTPUT_BYTES2) {
92277
- settle2(() => reject(new Error(`gh ${args[0]} stdout exceeded ${MAX_OUTPUT_BYTES2} bytes`)));
92544
+ settle2(() => reject(new Error(`${label} ${args[0]} stdout exceeded ${MAX_OUTPUT_BYTES2} bytes`)));
92278
92545
  return;
92279
92546
  }
92280
92547
  stdoutChunks.push(chunk);
@@ -92282,13 +92549,13 @@ async function ghExecAsync(args, cwd) {
92282
92549
  proc.stderr?.on("data", (chunk) => {
92283
92550
  stderrBytes += chunk.length;
92284
92551
  if (stderrBytes > MAX_OUTPUT_BYTES2) {
92285
- settle2(() => reject(new Error(`gh ${args[0]} stderr exceeded ${MAX_OUTPUT_BYTES2} bytes`)));
92552
+ settle2(() => reject(new Error(`${label} ${args[0]} stderr exceeded ${MAX_OUTPUT_BYTES2} bytes`)));
92286
92553
  return;
92287
92554
  }
92288
92555
  stderrChunks.push(chunk);
92289
92556
  });
92290
92557
  const timer = setTimeout(() => {
92291
- settle2(() => reject(new Error(`gh ${args[0]} timed out after ${GIT_TIMEOUT_MS5}ms`)));
92558
+ settle2(() => reject(new Error(`${label} ${args[0]} timed out after ${GIT_TIMEOUT_MS5}ms`)));
92292
92559
  }, GIT_TIMEOUT_MS5);
92293
92560
  proc.on("error", (err) => {
92294
92561
  settle2(() => reject(err));
@@ -92297,7 +92564,7 @@ async function ghExecAsync(args, cwd) {
92297
92564
  settle2(() => {
92298
92565
  if (code !== 0) {
92299
92566
  const stderr = Buffer.concat(stderrChunks).toString("utf-8");
92300
- reject(new Error(stderr || `gh exited with ${code}`));
92567
+ reject(new Error(stderr || `${label} exited with ${code}`));
92301
92568
  } else {
92302
92569
  const stdout = Buffer.concat(stdoutChunks).toString("utf-8");
92303
92570
  resolve40(stdout);
@@ -92306,20 +92573,24 @@ async function ghExecAsync(args, cwd) {
92306
92573
  });
92307
92574
  });
92308
92575
  }
92309
- var _internals99 = {
92576
+ var _internals100 = {
92310
92577
  ghExec,
92311
92578
  ghExecAsync,
92579
+ forgeExecAsync: forgeExecAsyncImpl,
92580
+ getMRPollSnapshot,
92581
+ getMRComments,
92312
92582
  spawnSyncWithTransientRetry,
92313
92583
  spawnSync: __spawnSyncSeam.spawnSync,
92314
92584
  readLaneEnvFileFromDiskSync,
92315
92585
  getMergeGroupRun,
92316
92586
  resolveGhExecutable,
92317
- resolveGitExecutable
92587
+ resolveGitExecutable,
92588
+ resolveGlabExecutable
92318
92589
  };
92319
92590
  async function getPRPollSnapshot(prNumber, repoFullName, cwd) {
92320
92591
  let stdout;
92321
92592
  try {
92322
- stdout = await _internals99.ghExecAsync([
92593
+ stdout = await _internals100.ghExecAsync([
92323
92594
  "pr",
92324
92595
  "view",
92325
92596
  String(prNumber),
@@ -92376,7 +92647,7 @@ function numericIssueCommentId(url, fallbackId, fallbacks) {
92376
92647
  async function getPRReviewComments(prNumber, repoFullName, cwd) {
92377
92648
  let stdout;
92378
92649
  try {
92379
- stdout = await _internals99.ghExecAsync(["api", `repos/${repoFullName}/pulls/${prNumber}/comments`], cwd);
92650
+ stdout = await _internals100.ghExecAsync(["api", `repos/${repoFullName}/pulls/${prNumber}/comments`], cwd);
92380
92651
  } catch (err) {
92381
92652
  throw new Error(`Failed to fetch review comments for ${repoFullName}#${prNumber}: ${err instanceof Error ? err.message : String(err)}`);
92382
92653
  }
@@ -92389,6 +92660,129 @@ async function getPRReviewComments(prNumber, repoFullName, cwd) {
92389
92660
  isReviewComment: true
92390
92661
  }));
92391
92662
  }
92663
+ var MR_SYNTHESIZED_FIELD_MARKER = "NOT_AVAILABLE";
92664
+ function glabSpawnEnv(input) {
92665
+ if (!input.host || input.host === "gitlab.com")
92666
+ return;
92667
+ return { env: { GITLAB_HOST: input.host } };
92668
+ }
92669
+ function mapMrState(state) {
92670
+ if (state === "merged")
92671
+ return "MERGED";
92672
+ if (state === "closed")
92673
+ return "CLOSED";
92674
+ return "OPEN";
92675
+ }
92676
+ function mapMrMergeable(mr, detail) {
92677
+ if (mr.has_conflicts === true)
92678
+ return "CONFLICTING";
92679
+ if (mr.detailed_merge_status === "conflict")
92680
+ return "CONFLICTING";
92681
+ if (detail.merge_status === "cannot_be_merged")
92682
+ return "CONFLICTING";
92683
+ if (mr.detailed_merge_status === "mergeable")
92684
+ return "MERGEABLE";
92685
+ if (detail.merge_status === "can_be_merged")
92686
+ return "MERGEABLE";
92687
+ return "UNKNOWN";
92688
+ }
92689
+ function mapPipelineConclusion(status) {
92690
+ if (status === "success")
92691
+ return "success";
92692
+ if (status === "failed")
92693
+ return "failure";
92694
+ return null;
92695
+ }
92696
+ async function getMRPollSnapshot(input) {
92697
+ const overlay = glabSpawnEnv(input);
92698
+ const glabBinary = _internals100.resolveGlabExecutable();
92699
+ let viewStdout;
92700
+ try {
92701
+ viewStdout = await _internals100.forgeExecAsync(glabBinary, ["mr", "view", String(input.iid), "-R", input.projectPath, "-F", "json"], input.cwd, "glab", overlay);
92702
+ } catch (err) {
92703
+ throw new Error(`Failed to fetch MR view for ${input.projectPath}!${input.iid}: ${err instanceof Error ? err.message : String(err)}`);
92704
+ }
92705
+ const mr = JSON.parse(viewStdout);
92706
+ let detailStdout;
92707
+ try {
92708
+ detailStdout = await _internals100.forgeExecAsync(glabBinary, [
92709
+ "api",
92710
+ `projects/${encodeURIComponent(input.projectPath)}/merge_requests/${input.iid}`
92711
+ ], input.cwd, "glab", overlay);
92712
+ } catch (err) {
92713
+ throw new Error(`Failed to fetch MR detail for ${input.projectPath}!${input.iid}: ${err instanceof Error ? err.message : String(err)}`);
92714
+ }
92715
+ const detail = JSON.parse(detailStdout);
92716
+ let pipelines = [];
92717
+ let pipelinesFetchSucceeded = false;
92718
+ try {
92719
+ const pipelinesStdout = await _internals100.forgeExecAsync(glabBinary, [
92720
+ "api",
92721
+ `projects/${encodeURIComponent(input.projectPath)}/merge_requests/${input.iid}/pipelines?per_page=20`
92722
+ ], input.cwd, "glab", overlay);
92723
+ const rawPipelines = JSON.parse(pipelinesStdout);
92724
+ const headSha = typeof mr.sha === "string" ? mr.sha : "";
92725
+ const forHead = rawPipelines.filter((p) => typeof p.sha === "string" && p.sha === headSha).sort((a, b) => (Number(b.id) || 0) - (Number(a.id) || 0));
92726
+ const latest = forHead[0];
92727
+ const conclusion = mapPipelineConclusion(latest?.status);
92728
+ pipelines = latest && conclusion ? [
92729
+ {
92730
+ name: `pipeline #${String(latest.id ?? "")}`,
92731
+ status: "completed",
92732
+ conclusion,
92733
+ ...typeof latest.web_url === "string" ? { detailsUrl: latest.web_url } : {}
92734
+ }
92735
+ ] : [];
92736
+ pipelinesFetchSucceeded = true;
92737
+ } catch {
92738
+ pipelines = [];
92739
+ pipelinesFetchSucceeded = false;
92740
+ }
92741
+ const state = mapMrState(mr.state);
92742
+ const mergeable = mapMrMergeable(mr, detail);
92743
+ const reviewers = Array.isArray(mr.reviewers) ? mr.reviewers.length : 0;
92744
+ return {
92745
+ status: {
92746
+ number: input.iid,
92747
+ state,
92748
+ mergeable,
92749
+ mergeStateStatus: MR_SYNTHESIZED_FIELD_MARKER,
92750
+ headRefOid: typeof mr.sha === "string" ? mr.sha : "",
92751
+ statusCheckRollup: []
92752
+ },
92753
+ comments: [],
92754
+ merge: {
92755
+ mergeable,
92756
+ mergeStateStatus: MR_SYNTHESIZED_FIELD_MARKER,
92757
+ headRefOid: typeof mr.sha === "string" ? mr.sha : ""
92758
+ },
92759
+ review: {
92760
+ reviewDecision: "",
92761
+ reviewRequestCount: reviewers
92762
+ },
92763
+ pipelines,
92764
+ pipelinesFetchSucceeded
92765
+ };
92766
+ }
92767
+ async function getMRComments(input) {
92768
+ let stdout;
92769
+ try {
92770
+ stdout = await _internals100.forgeExecAsync(_internals100.resolveGlabExecutable(), [
92771
+ "api",
92772
+ `projects/${encodeURIComponent(input.projectPath)}/merge_requests/${input.iid}/notes?per_page=100&sort=asc&order_by=created_at`
92773
+ ], input.cwd, "glab", glabSpawnEnv(input));
92774
+ } catch (err) {
92775
+ throw new Error(`Failed to fetch MR comments for ${input.projectPath}!${input.iid}: ${err instanceof Error ? err.message : String(err)}`);
92776
+ }
92777
+ const notes = JSON.parse(stdout);
92778
+ return notes.filter((note) => note.system !== true).map((note) => ({
92779
+ id: String(note.id ?? ""),
92780
+ author: String(note.author?.username ?? ""),
92781
+ body: neutralizeUntrustedMarkdown(String(note.body ?? ""), "GitLab MR note"),
92782
+ createdAt: String(note.created_at ?? ""),
92783
+ isReviewComment: false
92784
+ }));
92785
+ }
92392
92786
  async function getMergeGroupRun(statusCheckRollup, repoFullName, cwd) {
92393
92787
  const mergeGroupCheck = statusCheckRollup.find((check) => check.name === "Merge pull request" && check.detailsUrl);
92394
92788
  if (!mergeGroupCheck?.detailsUrl) {
@@ -92401,7 +92795,7 @@ async function getMergeGroupRun(statusCheckRollup, repoFullName, cwd) {
92401
92795
  const runId = runIdMatch[1];
92402
92796
  let stdout;
92403
92797
  try {
92404
- stdout = await _internals99.ghExecAsync([
92798
+ stdout = await _internals100.ghExecAsync([
92405
92799
  "run",
92406
92800
  "view",
92407
92801
  runId,
@@ -92430,7 +92824,7 @@ var registrationsByCanonical = new Map;
92430
92824
  function resolveRegistration(directory) {
92431
92825
  const lexical = canonicalRootKeyLexical(directory);
92432
92826
  try {
92433
- const freshKey = _internals100.canonicalRootKeyFresh(directory);
92827
+ const freshKey = _internals101.canonicalRootKeyFresh(directory);
92434
92828
  const canonical = registrationsByCanonical.get(freshKey);
92435
92829
  if (canonical)
92436
92830
  return canonical;
@@ -92452,8 +92846,10 @@ async function evaluatePrFeedbackCurrentHead(directory, repoFullName, prNumber)
92452
92846
  async function dispatchPrFeedbackOversight(input) {
92453
92847
  return await getPrFeedbackLoopRuntime(input.directory)?.dispatchOversight(input) ?? { dispatched: false, verdict: "unavailable", decision: "pending" };
92454
92848
  }
92455
- var _internals100 = {
92849
+ var _internals101 = {
92456
92850
  getPRPollSnapshot,
92851
+ getMRPollSnapshot,
92852
+ findSubscriptionRecordForPrUrl,
92457
92853
  dispatchEphemeralAgent,
92458
92854
  parseCriticResponseFields,
92459
92855
  canonicalRootKeyFresh,
@@ -92462,11 +92858,11 @@ var _internals100 = {
92462
92858
  };
92463
92859
 
92464
92860
  // src/background/pr-feedback-loop.ts
92465
- var PR_FEEDBACK_LOOP_STATE_REL = path127.join(".swarm", "pr-feedback-loop-state.json");
92861
+ var PR_FEEDBACK_LOOP_STATE_REL = path128.join(".swarm", "pr-feedback-loop-state.json");
92466
92862
  var PR_FEEDBACK_CLEANUP_DIR = "pr-feedback-loop-cleanups";
92467
- var PR_FEEDBACK_EVIDENCE_DIR = path127.join(".swarm", "pr-feedback-evidence");
92863
+ var PR_FEEDBACK_EVIDENCE_DIR = path128.join(".swarm", "pr-feedback-evidence");
92468
92864
  var PR_FEEDBACK_LOOP_STATE_LOCK_FILENAME = "pr-feedback-loop-state.lock";
92469
- var PR_FEEDBACK_LOOP_STATE_LOCK_REL = path127.join(".swarm", PR_FEEDBACK_LOOP_STATE_LOCK_FILENAME);
92865
+ var PR_FEEDBACK_LOOP_STATE_LOCK_REL = path128.join(".swarm", PR_FEEDBACK_LOOP_STATE_LOCK_FILENAME);
92470
92866
  var MAX_TRACKED_SESSIONS5 = 200;
92471
92867
  var MAX_IN_FLIGHT_SESSIONS = 64;
92472
92868
  var MAX_CANCELLATION_REQUESTS = 64;
@@ -92482,7 +92878,7 @@ var LoopStateSchema = exports_external.object({
92482
92878
  correlations: exports_external.record(exports_external.string(), exports_external.any()),
92483
92879
  sessionTerminals: exports_external.record(exports_external.string(), exports_external.any()).default({})
92484
92880
  });
92485
- var _internals101 = {
92881
+ var _internals102 = {
92486
92882
  async evaluateCurrentHead(directory, repoFullName, prNumber) {
92487
92883
  return evaluatePrFeedbackCurrentHead(directory, repoFullName, prNumber);
92488
92884
  },
@@ -92491,13 +92887,20 @@ var _internals101 = {
92491
92887
  },
92492
92888
  async performAuthorizedAction(input) {
92493
92889
  try {
92890
+ const subscription = await findSubscriptionRecordForPrUrl(input.directory, {
92891
+ prUrl: input.event.prUrl,
92892
+ repoFullName: input.event.repoFullName,
92893
+ prNumber: input.event.prNumber,
92894
+ sessionID: input.sessionID
92895
+ });
92494
92896
  await activatePrWorkflow(input.directory, input.sessionID, "PR_FEEDBACK", {
92495
92897
  requireCheckoutPreflight: true,
92496
- prUrl: input.event.prUrl
92898
+ prUrl: input.event.prUrl,
92899
+ forge: subscription?.forge
92497
92900
  });
92498
92901
  return {
92499
92902
  performed: true,
92500
- recordPath: path127.join(".swarm", "pr-feedback-loop-state.json")
92903
+ recordPath: path128.join(".swarm", "pr-feedback-loop-state.json")
92501
92904
  };
92502
92905
  } catch (err) {
92503
92906
  const message = err instanceof Error ? err.message : String(err);
@@ -92519,13 +92922,13 @@ var _internals101 = {
92519
92922
  listActive,
92520
92923
  isProcessAlive: isProcessAlive3,
92521
92924
  resetLoopStateLock() {
92522
- _internals101.beforeLoopStateLockWrite = undefined;
92925
+ _internals102.beforeLoopStateLockWrite = undefined;
92523
92926
  },
92524
92927
  loopStateLockRelativePath: () => PR_FEEDBACK_LOOP_STATE_LOCK_REL,
92525
92928
  reclaimAbandonedLoopStateLock,
92526
92929
  removeLoopStateLockIfOwned
92527
92930
  };
92528
- var defaultLoopInternals = { ..._internals101 };
92931
+ var defaultLoopInternals = { ..._internals102 };
92529
92932
  function emptyState2() {
92530
92933
  return {
92531
92934
  schemaVersion: 1,
@@ -92601,7 +93004,7 @@ function hasReservationIdentity(reservation) {
92601
93004
  return Boolean(reservation?.workflowInstanceId.trim() && Number.isInteger(reservation?.ownerPid) && (reservation?.ownerPid ?? 0) > 0);
92602
93005
  }
92603
93006
  async function readLoopState(directory) {
92604
- const file = path127.join(directory, PR_FEEDBACK_LOOP_STATE_REL);
93007
+ const file = path128.join(directory, PR_FEEDBACK_LOOP_STATE_REL);
92605
93008
  try {
92606
93009
  const raw = fsSync9.readFileSync(file, "utf-8");
92607
93010
  const parsed = LoopStateSchema.safeParse(JSON.parse(raw));
@@ -92632,7 +93035,7 @@ async function writeLoopState(directory, state) {
92632
93035
  }
92633
93036
  }
92634
93037
  state.updatedAt = new Date().toISOString();
92635
- await writePrWorkflowAtomicJson(directory, validateSwarmPath(directory, path127.basename(PR_FEEDBACK_LOOP_STATE_REL)), state);
93038
+ await writePrWorkflowAtomicJson(directory, validateSwarmPath(directory, path128.basename(PR_FEEDBACK_LOOP_STATE_REL)), state);
92636
93039
  }
92637
93040
  async function withLoopStateLock(directory, fn) {
92638
93041
  const lock = await acquireLoopStateLock(directory);
@@ -92647,21 +93050,21 @@ async function acquireLoopStateLock(directory) {
92647
93050
  const verifiedStateDirectory = await ensurePrWorkflowSafeParentDirectory(directory, lockPath);
92648
93051
  for (let attempt = 0;attempt < LOOP_STATE_LOCK_MAX_ATTEMPTS; attempt++) {
92649
93052
  try {
92650
- const handle = await fs63.open(lockPath, "wx");
93053
+ const handle = await fs64.open(lockPath, "wx");
92651
93054
  const lock = {
92652
93055
  ownerToken: randomUUID22(),
92653
93056
  pid: process.pid,
92654
- createdAtMs: _internals101.now()
93057
+ createdAtMs: _internals102.now()
92655
93058
  };
92656
93059
  let writeError;
92657
93060
  try {
92658
- await _internals101.beforeLoopStateLockWrite?.();
93061
+ await _internals102.beforeLoopStateLockWrite?.();
92659
93062
  const [openedStat, pathStat, realLockPath] = await Promise.all([
92660
93063
  handle.stat({ bigint: true }),
92661
- fs63.lstat(lockPath, { bigint: true }),
92662
- fs63.realpath(lockPath)
93064
+ fs64.lstat(lockPath, { bigint: true }),
93065
+ fs64.realpath(lockPath)
92663
93066
  ]);
92664
- if (!openedStat.isFile() || pathStat.isSymbolicLink() || !pathStat.isFile() || !sameFileIdentity4(openedStat, pathStat) || normalizeComparablePath2(path127.dirname(realLockPath)) !== normalizeComparablePath2(verifiedStateDirectory)) {
93067
+ if (!openedStat.isFile() || pathStat.isSymbolicLink() || !pathStat.isFile() || !sameFileIdentity4(openedStat, pathStat) || normalizeComparablePath2(path128.dirname(realLockPath)) !== normalizeComparablePath2(verifiedStateDirectory)) {
92665
93068
  throw new Error("BLOCKED: PR feedback loop state lock changed or escaped before initialization");
92666
93069
  }
92667
93070
  await handle.writeFile(JSON.stringify(lock), "utf8");
@@ -92702,17 +93105,17 @@ async function reclaimAbandonedLoopStateLock(lockPath) {
92702
93105
  lock = null;
92703
93106
  }
92704
93107
  if (lock) {
92705
- if (_internals101.isProcessAlive(lock.pid) && _internals101.now() - lock.createdAtMs < LOOP_STATE_LOCK_ALIVE_OWNER_STALE_MS) {
93108
+ if (_internals102.isProcessAlive(lock.pid) && _internals102.now() - lock.createdAtMs < LOOP_STATE_LOCK_ALIVE_OWNER_STALE_MS) {
92706
93109
  return false;
92707
93110
  }
92708
93111
  return removeLoopStateLockIfOwned(lockPath, lock.ownerToken);
92709
93112
  }
92710
93113
  try {
92711
- const stat14 = await fs63.stat(lockPath);
92712
- if (_internals101.now() - stat14.mtimeMs < LOOP_STATE_LOCK_UNINITIALIZED_STALE_MS) {
93114
+ const stat14 = await fs64.stat(lockPath);
93115
+ if (_internals102.now() - stat14.mtimeMs < LOOP_STATE_LOCK_UNINITIALIZED_STALE_MS) {
92713
93116
  return false;
92714
93117
  }
92715
- await fs63.rm(lockPath, { force: true });
93118
+ await fs64.rm(lockPath, { force: true });
92716
93119
  return true;
92717
93120
  } catch (error2) {
92718
93121
  if (error2.code === "ENOENT")
@@ -92723,7 +93126,7 @@ async function reclaimAbandonedLoopStateLock(lockPath) {
92723
93126
  async function readLoopStateLock(lockPath) {
92724
93127
  let raw;
92725
93128
  try {
92726
- raw = await fs63.readFile(lockPath, "utf8");
93129
+ raw = await fs64.readFile(lockPath, "utf8");
92727
93130
  } catch (error2) {
92728
93131
  if (error2.code === "ENOENT")
92729
93132
  return null;
@@ -92747,7 +93150,7 @@ async function removeLoopStateLockIfOwned(lockPath, ownerToken) {
92747
93150
  if (!lock || lock.ownerToken !== ownerToken)
92748
93151
  return false;
92749
93152
  try {
92750
- await fs63.rm(lockPath);
93153
+ await fs64.rm(lockPath);
92751
93154
  return true;
92752
93155
  } catch {
92753
93156
  return false;
@@ -92765,7 +93168,7 @@ function sameFileIdentity4(left, right) {
92765
93168
  return left.dev === right.dev && left.ino === right.ino;
92766
93169
  }
92767
93170
  function normalizeComparablePath2(value) {
92768
- const normalized = path127.normalize(path127.resolve(value));
93171
+ const normalized = path128.normalize(path128.resolve(value));
92769
93172
  return process.platform === "win32" ? normalized.toLowerCase() : normalized;
92770
93173
  }
92771
93174
  function delay3(ms) {
@@ -92869,14 +93272,14 @@ async function cancelPrFeedbackLoopUnlocked(directory, sessionID, reason) {
92869
93272
  clearedEvents: []
92870
93273
  };
92871
93274
  try {
92872
- const { cancelPrFeedbackPublication: cancelPrFeedbackPublication2 } = await import("./pr-workflow-gate-qd5tfkak.js");
93275
+ const { cancelPrFeedbackPublication: cancelPrFeedbackPublication2 } = await import("./pr-workflow-gate-j3r636zg.js");
92873
93276
  await cancelPrFeedbackPublication2(directory, sessionID, reason);
92874
93277
  } catch (err) {
92875
93278
  warn(`[pr-feedback-loop] cancelPrFeedbackPublication failed (fail-open): ${err instanceof Error ? err.message : String(err)}`);
92876
93279
  }
92877
93280
  try {
92878
93281
  await withLoopStateLock(directory, async () => {
92879
- const readResult = await _internals101.readState(directory);
93282
+ const readResult = await _internals102.readState(directory);
92880
93283
  if (isCorruptState(readResult)) {
92881
93284
  throw new Error("BLOCKED: loop state is corrupt during durable cancellation admission");
92882
93285
  }
@@ -92889,7 +93292,7 @@ async function cancelPrFeedbackLoopUnlocked(directory, sessionID, reason) {
92889
93292
  correlation.terminal = { state: "cancelled", reason };
92890
93293
  }
92891
93294
  const inFlight = correlation.inFlight;
92892
- const ownerAlive = inFlight && hasReservationIdentity(inFlight) ? _internals101.isProcessAlive(inFlight.ownerPid) : false;
93295
+ const ownerAlive = inFlight && hasReservationIdentity(inFlight) ? _internals102.isProcessAlive(inFlight.ownerPid) : false;
92893
93296
  const reclaimedReservation = Boolean(inFlight && (inFlight.actionStartedAt === undefined || !ownerAlive));
92894
93297
  if (reclaimedReservation) {
92895
93298
  correlation.inFlight = null;
@@ -92904,7 +93307,7 @@ async function cancelPrFeedbackLoopUnlocked(directory, sessionID, reason) {
92904
93307
  reason
92905
93308
  };
92906
93309
  }
92907
- await _internals101.writeState(directory, nextState);
93310
+ await _internals102.writeState(directory, nextState);
92908
93311
  return nextState;
92909
93312
  });
92910
93313
  } catch (err) {
@@ -92925,12 +93328,12 @@ async function cancelPrFeedbackLoopUnlocked(directory, sessionID, reason) {
92925
93328
  }
92926
93329
  }
92927
93330
  const stamp = new Date().toISOString().replace(/[:.]/g, "-");
92928
- receipt.path = path127.join(".swarm", PR_FEEDBACK_CLEANUP_DIR, `cancel-${stamp}.json`);
93331
+ receipt.path = path128.join(".swarm", PR_FEEDBACK_CLEANUP_DIR, `cancel-${stamp}.json`);
92929
93332
  try {
92930
- fsSync9.mkdirSync(path127.join(directory, ".swarm", PR_FEEDBACK_CLEANUP_DIR), {
93333
+ fsSync9.mkdirSync(path128.join(directory, ".swarm", PR_FEEDBACK_CLEANUP_DIR), {
92931
93334
  recursive: true
92932
93335
  });
92933
- fsSync9.writeFileSync(path127.join(directory, receipt.path), JSON.stringify({
93336
+ fsSync9.writeFileSync(path128.join(directory, receipt.path), JSON.stringify({
92934
93337
  schemaVersion: 1,
92935
93338
  at: new Date().toISOString(),
92936
93339
  sessionID,
@@ -92982,228 +93385,6 @@ ${USAGE14}`;
92982
93385
 
92983
93386
  // src/background/pr-monitor-worker.ts
92984
93387
  init_warning_buffer();
92985
-
92986
- // src/utils/glab-executable.ts
92987
- init_warning_buffer();
92988
- import { spawnSync as spawnSync6 } from "child_process";
92989
- import * as fs64 from "fs";
92990
- import * as os14 from "os";
92991
- import * as path128 from "path";
92992
- var GLAB_BINARY_ENV_VAR = "OPENCODE_SWARM_GLAB_BINARY";
92993
- var PER_PROBE_TIMEOUT_MS2 = 250;
92994
- var TOTAL_BUDGET_MS3 = 1000;
92995
- var NEGATIVE_CACHE_TTL_MS2 = 60000;
92996
- var BARE_GLAB = "glab";
92997
- var PROBE_MAX_BUFFER_BYTES2 = 64 * 1024;
92998
- var PROBE_OUTPUT_EXCERPT_CHARS2 = 60;
92999
- var WINDOWS_PATH_EXTENSIONS2 = [".exe", ".cmd", ".bat"];
93000
- var GLAB_VERSION_PATTERN = /^glab version \d+\.\d+/;
93001
- function excerptProbeOutput2(raw) {
93002
- return raw.slice(0, PROBE_OUTPUT_EXCERPT_CHARS2).replace(/[^\x20-\x7E]/g, " ").trim();
93003
- }
93004
- var cache3 = null;
93005
- var lastAttempts2 = [];
93006
- var cacheGeneration2 = 0;
93007
- function windowsGlabAbsoluteCandidates(env) {
93008
- const candidates = [];
93009
- const push = (...parts) => {
93010
- const candidate2 = path128.join(...parts);
93011
- if (!candidates.includes(candidate2))
93012
- candidates.push(candidate2);
93013
- };
93014
- if (env.ProgramFiles) {
93015
- push(env.ProgramFiles, "GitLab CLI", "glab.exe");
93016
- }
93017
- if (env["ProgramFiles(x86)"]) {
93018
- push(env["ProgramFiles(x86)"], "GitLab CLI", "glab.exe");
93019
- }
93020
- if (env.LOCALAPPDATA) {
93021
- push(env.LOCALAPPDATA, "GitLab CLI", "glab.exe");
93022
- push(env.LOCALAPPDATA, "Programs", "GitLab CLI", "glab.exe");
93023
- }
93024
- return candidates;
93025
- }
93026
- function platformCandidates2(platform, env) {
93027
- if (platform === "win32") {
93028
- return windowsGlabAbsoluteCandidates(env);
93029
- }
93030
- if (platform === "darwin") {
93031
- return ["/opt/homebrew/bin/glab", "/usr/local/bin/glab", "/usr/bin/glab"];
93032
- }
93033
- return ["/usr/bin/glab", "/usr/local/bin/glab", "/bin/glab"];
93034
- }
93035
- function isAbsoluteForPlatform2(candidate2, platform) {
93036
- return platform === "win32" ? path128.win32.isAbsolute(candidate2) : path128.posix.isAbsolute(candidate2);
93037
- }
93038
- function joinDirAndName2(dir, name, platform) {
93039
- const sep22 = platform === "win32" ? "\\" : "/";
93040
- const trimmed = dir.replace(/[\\/]+$/, "");
93041
- return trimmed ? `${trimmed}${sep22}${name}` : `${sep22}${name}`;
93042
- }
93043
- function pathCandidates2(platform) {
93044
- const pathValue = _internals102.env().PATH ?? "";
93045
- if (!pathValue)
93046
- return [];
93047
- const dirs = pathValue.split(platform === "win32" ? ";" : ":").filter(Boolean);
93048
- const names = platform === "win32" ? [...WINDOWS_PATH_EXTENSIONS2.map((ext) => `glab${ext}`), "glab"] : ["glab"];
93049
- const out = [];
93050
- for (const dir of dirs) {
93051
- for (const name of names) {
93052
- const candidate2 = joinDirAndName2(dir, name, platform);
93053
- if (!out.includes(candidate2))
93054
- out.push(candidate2);
93055
- }
93056
- }
93057
- return out;
93058
- }
93059
- function envOverride2() {
93060
- const raw = _internals102.env()[GLAB_BINARY_ENV_VAR];
93061
- return raw && raw.trim() !== "" ? raw : undefined;
93062
- }
93063
- function buildCandidates2(platform) {
93064
- const override = envOverride2();
93065
- const overrideCandidate = override ? [{ source: "override", path: override }] : [];
93066
- const seen = new Set(overrideCandidate.map((c) => c.path));
93067
- const rest = [];
93068
- for (const p of platformCandidates2(platform, _internals102.env())) {
93069
- if (seen.has(p))
93070
- continue;
93071
- seen.add(p);
93072
- rest.push({ source: "platform", path: p });
93073
- }
93074
- for (const p of pathCandidates2(platform)) {
93075
- if (seen.has(p))
93076
- continue;
93077
- seen.add(p);
93078
- rest.push({ source: "path", path: p });
93079
- }
93080
- return [...overrideCandidate, ...rest];
93081
- }
93082
- function probeCandidate2(candidatePath2, platform) {
93083
- if (!isAbsoluteForPlatform2(candidatePath2, platform)) {
93084
- return { accepted: false, reason: "not an absolute path" };
93085
- }
93086
- let stat14;
93087
- try {
93088
- stat14 = fs64.statSync(candidatePath2);
93089
- } catch (err) {
93090
- const code = err?.code;
93091
- if (code === "ENOENT")
93092
- return { accepted: false, reason: "no such file" };
93093
- return {
93094
- accepted: false,
93095
- reason: `cannot stat (${code ?? "unknown error"})`
93096
- };
93097
- }
93098
- if (stat14.isDirectory()) {
93099
- return { accepted: false, reason: "is a directory" };
93100
- }
93101
- if (!stat14.isFile()) {
93102
- return { accepted: false, reason: "not a regular file" };
93103
- }
93104
- let result;
93105
- try {
93106
- result = _internals102.spawnSync(candidatePath2, ["--version"], {
93107
- cwd: os14.tmpdir(),
93108
- stdio: ["ignore", "pipe", "ignore"],
93109
- windowsHide: true,
93110
- timeout: PER_PROBE_TIMEOUT_MS2,
93111
- maxBuffer: PROBE_MAX_BUFFER_BYTES2
93112
- });
93113
- } catch (err) {
93114
- return {
93115
- accepted: false,
93116
- reason: `spawn threw: ${err instanceof Error ? err.message : String(err)}`
93117
- };
93118
- }
93119
- if (result.error) {
93120
- return { accepted: false, reason: `spawn failed: ${result.error.message}` };
93121
- }
93122
- if (result.status !== 0) {
93123
- const statusDescription = result.status !== null ? `exit ${result.status}` : `signal ${result.signal ?? "unknown"}`;
93124
- return {
93125
- accepted: false,
93126
- reason: `glab --version returned ${statusDescription}`
93127
- };
93128
- }
93129
- const versionOutput = (result.stdout ?? "").toString().trim();
93130
- if (!GLAB_VERSION_PATTERN.test(versionOutput)) {
93131
- const excerpt = excerptProbeOutput2(versionOutput);
93132
- return {
93133
- accepted: false,
93134
- reason: excerpt ? `not glab: --version printed "${excerpt}"` : "not glab: --version printed nothing"
93135
- };
93136
- }
93137
- return { accepted: true };
93138
- }
93139
- function probeCycle2(candidates, platform, attempts) {
93140
- const start = _internals102.now();
93141
- let budgetExceeded = false;
93142
- for (const candidate2 of candidates) {
93143
- if (_internals102.now() - start > TOTAL_BUDGET_MS3) {
93144
- budgetExceeded = true;
93145
- break;
93146
- }
93147
- const result = probeCandidate2(candidate2.path, platform);
93148
- attempts.push({
93149
- source: candidate2.source,
93150
- candidate: candidate2.path,
93151
- accepted: result.accepted,
93152
- reason: result.accepted ? undefined : result.reason
93153
- });
93154
- if (candidate2.source === "override" && !result.accepted) {
93155
- advisoryWarn(`[opencode-swarm] ${GLAB_BINARY_ENV_VAR} override "${candidate2.path}" is unusable (${result.reason}); falling back to automatic glab resolution.`);
93156
- }
93157
- if (result.accepted) {
93158
- return { outcome: "accepted", path: candidate2.path };
93159
- }
93160
- }
93161
- return budgetExceeded ? { outcome: "exhausted-budget" } : { outcome: "all-rejected" };
93162
- }
93163
- function readCache3() {
93164
- if (cache3 === null)
93165
- return null;
93166
- if (cache3.kind === "success")
93167
- return cache3;
93168
- if (_internals102.now() < cache3.expiresAt)
93169
- return cache3;
93170
- cache3 = null;
93171
- return null;
93172
- }
93173
- function applyProbeResult2(result, attempts, generation) {
93174
- if (generation !== cacheGeneration2) {
93175
- return result.outcome === "accepted" ? result.path : BARE_GLAB;
93176
- }
93177
- lastAttempts2 = attempts;
93178
- if (result.outcome === "accepted") {
93179
- cache3 = { kind: "success", path: result.path };
93180
- return result.path;
93181
- }
93182
- cache3 = {
93183
- kind: "fallback",
93184
- expiresAt: _internals102.now() + NEGATIVE_CACHE_TTL_MS2
93185
- };
93186
- return BARE_GLAB;
93187
- }
93188
- function resolveGlabExecutable() {
93189
- const cached = readCache3();
93190
- if (cached)
93191
- return cached.kind === "success" ? cached.path : BARE_GLAB;
93192
- const platform = _internals102.platform();
93193
- const attempts = [];
93194
- const generation = cacheGeneration2;
93195
- const candidates = buildCandidates2(platform);
93196
- const result = probeCycle2(candidates, platform, attempts);
93197
- return applyProbeResult2(result, attempts, generation);
93198
- }
93199
- var _internals102 = {
93200
- spawnSync: spawnSync6,
93201
- platform: () => process.platform,
93202
- env: () => process.env,
93203
- now: () => Date.now()
93204
- };
93205
-
93206
- // src/background/pr-monitor-worker.ts
93207
93388
  var prMonitorWorkerRegistry = new Map;
93208
93389
  function getPrMonitorWorkerHealth(directory) {
93209
93390
  return prMonitorWorkerRegistry.get(directory)?.getHealth() ?? null;
@@ -93413,12 +93594,7 @@ class PrMonitorWorker {
93413
93594
  async pollSinglePr(sub, isTimedOut, isProbe = false) {
93414
93595
  const correlationId = sub.correlationId;
93415
93596
  const forgeContext = detectForgeFromUrl(sub.prUrl) ?? (sub.forge ? { provider: sub.forge.provider, host: sub.forge.host } : null);
93416
- if (forgeContext && !getProviderCapabilities(forgeContext.provider).statusCheckRollup && !getProviderCapabilities(forgeContext.provider).reviewDecision && !getProviderCapabilities(forgeContext.provider).mergeStateStatus) {
93417
- const glabBinary = resolveGlabExecutable();
93418
- const glabStatus = glabBinary === "glab" ? "glab binary not resolved (bare-name fallback)" : "glab binary resolved";
93419
- log("[PrMonitorWorker] GitLab MR monitoring unavailable: glab-backed polling is not wired yet (issue #2882); skipping gh poll for this subscription", { correlationId, glabStatus });
93420
- return;
93421
- }
93597
+ const isGitLab = forgeContext?.provider === "gitlab";
93422
93598
  if (!this.circuitBreakerMap.has(correlationId) && sub.errorCount > 0) {
93423
93599
  this.circuitBreakerMap.set(correlationId, {
93424
93600
  errorCount: sub.errorCount,
@@ -93443,40 +93619,76 @@ class PrMonitorWorker {
93443
93619
  return;
93444
93620
  }
93445
93621
  try {
93446
- const [snapshot, reviewComments] = await Promise.all([
93447
- _internals103.getPRPollSnapshot(sub.prNumber, sub.repoFullName, this.directory),
93448
- _internals103.getPRReviewComments(sub.prNumber, sub.repoFullName, this.directory)
93449
- ]);
93450
- if (isTimedOut?.()) {
93451
- log("[PrMonitorWorker] Skipping late result \u2014 poll already timed out", {
93452
- correlationId: sub.correlationId
93622
+ let changes;
93623
+ if (isGitLab) {
93624
+ const glabBinary = resolveGlabExecutable();
93625
+ const glabStatus = glabBinary === "glab" ? "glab binary not resolved (bare-name fallback)" : "glab binary resolved";
93626
+ log("[PrMonitorWorker] Polling GitLab MR (glab-backed)", {
93627
+ correlationId,
93628
+ glabStatus
93453
93629
  });
93454
- return;
93455
- }
93456
- let mergeGroupRunResult = null;
93457
- let mergeGroupRunFetchSucceeded = false;
93458
- try {
93459
- mergeGroupRunResult = await _internals103.getMergeGroupRun(snapshot.status.statusCheckRollup, sub.repoFullName, this.directory);
93460
- mergeGroupRunFetchSucceeded = true;
93461
- } catch (err) {
93462
- log("[PrMonitorWorker] Failed to fetch merge group run", {
93463
- correlationId: sub.correlationId,
93464
- error: err instanceof Error ? err.message : String(err)
93465
- });
93466
- }
93467
- if (isTimedOut?.()) {
93468
- log("[PrMonitorWorker] Skipping late result \u2014 poll already timed out", {
93469
- correlationId: sub.correlationId
93630
+ const mrInput = {
93631
+ projectPath: sub.repoFullName,
93632
+ iid: sub.prNumber,
93633
+ cwd: this.directory,
93634
+ ...forgeContext ? { host: forgeContext.host } : {}
93635
+ };
93636
+ const [mrSnapshot, mrComments] = await Promise.all([
93637
+ _internals103.getMRPollSnapshot(mrInput),
93638
+ _internals103.getMRComments(mrInput)
93639
+ ]);
93640
+ if (isTimedOut?.()) {
93641
+ log("[PrMonitorWorker] Skipping late result \u2014 poll already timed out", {
93642
+ correlationId: sub.correlationId
93643
+ });
93644
+ return;
93645
+ }
93646
+ changes = this.computeChanges(sub, {
93647
+ status: mrSnapshot.status,
93648
+ comments: mrComments,
93649
+ merge: mrSnapshot.merge,
93650
+ review: mrSnapshot.review,
93651
+ mergeGroupRun: null
93652
+ }, true, {
93653
+ checks: mrSnapshot.pipelines,
93654
+ fetchSucceeded: mrSnapshot.pipelinesFetchSucceeded
93470
93655
  });
93471
- return;
93656
+ } else {
93657
+ const [snapshot, reviewComments] = await Promise.all([
93658
+ _internals103.getPRPollSnapshot(sub.prNumber, sub.repoFullName, this.directory),
93659
+ _internals103.getPRReviewComments(sub.prNumber, sub.repoFullName, this.directory)
93660
+ ]);
93661
+ if (isTimedOut?.()) {
93662
+ log("[PrMonitorWorker] Skipping late result \u2014 poll already timed out", {
93663
+ correlationId: sub.correlationId
93664
+ });
93665
+ return;
93666
+ }
93667
+ let mergeGroupRunResult = null;
93668
+ let mergeGroupRunFetchSucceeded = false;
93669
+ try {
93670
+ mergeGroupRunResult = await _internals103.getMergeGroupRun(snapshot.status.statusCheckRollup, sub.repoFullName, this.directory);
93671
+ mergeGroupRunFetchSucceeded = true;
93672
+ } catch (err) {
93673
+ log("[PrMonitorWorker] Failed to fetch merge group run", {
93674
+ correlationId: sub.correlationId,
93675
+ error: err instanceof Error ? err.message : String(err)
93676
+ });
93677
+ }
93678
+ if (isTimedOut?.()) {
93679
+ log("[PrMonitorWorker] Skipping late result \u2014 poll already timed out", {
93680
+ correlationId: sub.correlationId
93681
+ });
93682
+ return;
93683
+ }
93684
+ changes = this.computeChanges(sub, {
93685
+ status: snapshot.status,
93686
+ comments: [...snapshot.comments, ...reviewComments],
93687
+ merge: snapshot.merge,
93688
+ review: snapshot.review,
93689
+ mergeGroupRun: mergeGroupRunResult
93690
+ }, mergeGroupRunFetchSucceeded);
93472
93691
  }
93473
- const changes = this.computeChanges(sub, {
93474
- status: snapshot.status,
93475
- comments: [...snapshot.comments, ...reviewComments],
93476
- merge: snapshot.merge,
93477
- review: snapshot.review,
93478
- mergeGroupRun: mergeGroupRunResult
93479
- }, mergeGroupRunFetchSucceeded);
93480
93692
  await this.applyChanges(sub, changes, isTimedOut);
93481
93693
  if (!isTimedOut?.()) {
93482
93694
  this.circuitBreakerMap.delete(correlationId);
@@ -93512,7 +93724,7 @@ class PrMonitorWorker {
93512
93724
  await this.handlePollError(sub, err instanceof Error ? err : new Error(String(err)));
93513
93725
  }
93514
93726
  }
93515
- computeChanges(sub, current, mergeGroupRunFetchSucceeded) {
93727
+ computeChanges(sub, current, mergeGroupRunFetchSucceeded, gitLabPipelines) {
93516
93728
  const events = [];
93517
93729
  const snapshotUpdates = {
93518
93730
  headRefOid: current.status.headRefOid,
@@ -93539,13 +93751,17 @@ class PrMonitorWorker {
93539
93751
  }
93540
93752
  });
93541
93753
  }
93542
- const currentCheckSet = this.serializeChecks(current.status.statusCheckRollup);
93543
- snapshotUpdates.lastCheckRunSet = currentCheckSet;
93544
- if (sub.lastCheckRunSet !== undefined && currentCheckSet !== sub.lastCheckRunSet) {
93545
- const prevChecks = this.parseCheckSet(sub.lastCheckRunSet);
93546
- this.computeCIEvents(sub, prevChecks, current.status.statusCheckRollup, current.status.headRefOid, events);
93754
+ const ciChecks = gitLabPipelines ? gitLabPipelines.checks : current.status.statusCheckRollup;
93755
+ const gitlabNoTerminalVerdict = gitLabPipelines !== undefined && gitLabPipelines.checks.length === 0;
93756
+ if (!gitlabNoTerminalVerdict && (!gitLabPipelines || gitLabPipelines.fetchSucceeded)) {
93757
+ const currentCheckSet = this.serializeChecks(ciChecks);
93758
+ snapshotUpdates.lastCheckRunSet = currentCheckSet;
93759
+ if (sub.lastCheckRunSet !== undefined && currentCheckSet !== sub.lastCheckRunSet) {
93760
+ const prevChecks = this.parseCheckSet(sub.lastCheckRunSet);
93761
+ this.computeCIEvents(sub, prevChecks, ciChecks, current.status.headRefOid, events);
93762
+ }
93763
+ snapshotUpdates.lastCheckRunSet = currentCheckSet;
93547
93764
  }
93548
- snapshotUpdates.lastCheckRunSet = currentCheckSet;
93549
93765
  if (current.comments.length > 0) {
93550
93766
  const sorted2 = [...current.comments].sort((a, b) => a.createdAt.localeCompare(b.createdAt));
93551
93767
  let newComments;
@@ -93877,6 +94093,8 @@ class PrMonitorWorker {
93877
94093
  var _internals103 = {
93878
94094
  getPRPollSnapshot,
93879
94095
  getPRReviewComments,
94096
+ getMRPollSnapshot,
94097
+ getMRComments,
93880
94098
  getMergeGroupRun,
93881
94099
  listActive,
93882
94100
  updateSnapshot,
@@ -94240,11 +94458,10 @@ async function handlePrSubscribeCommand(directory, args, sessionID) {
94240
94458
  deliveryLine
94241
94459
  ].concat(prUrl.includes("/-/merge_requests/") ? [
94242
94460
  "",
94243
- "Note: live monitoring is NOT AVAILABLE for GitLab merge",
94244
- "requests yet \u2014 glab-backed polling is tracked as issue #2882.",
94245
- "The subscription is recorded and PR reference/gate/",
94246
- "publication workflows operate on this MR, but no CI/comment/",
94247
- "review events will be delivered until that lands."
94461
+ "Note: live GitLab MR monitoring is active (glab-backed:",
94462
+ "state, comments, and pipeline CI events). Review-decision",
94463
+ "and status-check rollup equivalents remain NOT AVAILABLE",
94464
+ "for GitLab \u2014 the monitor never fabricates them (issue #2733)."
94248
94465
  ] : []).join(`
94249
94466
  `);
94250
94467
  } catch (err) {
@@ -106680,7 +106897,7 @@ async function runValidationWithTransientRetry(input, candidateContent, baseline
106680
106897
  if (!input.dispatcher) {
106681
106898
  throw new Error("no evaluation dispatcher available (cannot run validation)");
106682
106899
  }
106683
- const { createModelEvaluationExecutor: createModelEvaluationExecutor2 } = await import("./runner-tb3eppeg.js");
106900
+ const { createModelEvaluationExecutor: createModelEvaluationExecutor2 } = await import("./runner-fns4esbf.js");
106684
106901
  const executor = createModelEvaluationExecutor2(input.dispatcher, input.sessionId);
106685
106902
  const result = await withProtectedSetIntegrity([evalInputRoot, ...protectedRoots(input.directory)], () => _internals129.evaluateCandidateV1({
106686
106903
  projectRoot: input.directory,
@@ -109309,7 +109526,7 @@ function buildDetailedHelp(commandName, entry) {
109309
109526
  async function handleHelpCommand(ctx) {
109310
109527
  const targetCommand = ctx.args.join(" ");
109311
109528
  if (!targetCommand) {
109312
- const { buildHelpText } = await import("./index-r9zc92pb.js");
109529
+ const { buildHelpText } = await import("./index-03d68zxw.js");
109313
109530
  return buildHelpText();
109314
109531
  }
109315
109532
  const tokens = targetCommand.split(/\s+/);
@@ -109323,7 +109540,7 @@ async function handleHelpCommand(ctx) {
109323
109540
  > Note: \`/swarm ${resolved.key}\` is a deprecated alias for \`/swarm ${aliasTarget}\`.` : detailed;
109324
109541
  }
109325
109542
  const similar = _internals27.findSimilarCommands(targetCommand);
109326
- const { buildHelpText: fullHelp } = await import("./index-r9zc92pb.js");
109543
+ const { buildHelpText: fullHelp } = await import("./index-03d68zxw.js");
109327
109544
  if (similar.length > 0) {
109328
109545
  return `Command '/swarm ${targetCommand}' not found.
109329
109546
 
@@ -109358,6 +109575,18 @@ async function handleModeCommandWithBundledSkills(ctx, handler, mechanicalMode)
109358
109575
  }
109359
109576
  return result;
109360
109577
  }
109578
+ function resolveCommandForgeContext(directory, prUrl) {
109579
+ if (detectForgeFromUrl(prUrl))
109580
+ return;
109581
+ try {
109582
+ const config = loadPluginConfig(directory);
109583
+ const remote = detectGitRemote(directory, undefined);
109584
+ const remotes = remote ? [remote] : [];
109585
+ return resolveForgeContextFromPluginConfig(config, remotes) ?? undefined;
109586
+ } catch {
109587
+ return;
109588
+ }
109589
+ }
109361
109590
  async function handlePrFeedbackCommandWithTransition(ctx) {
109362
109591
  if (ctx.packageRoot) {
109363
109592
  await syncBundledProjectSkillsIfMissingAsync(ctx.directory, ctx.packageRoot, true);
@@ -109388,7 +109617,8 @@ async function handlePrFeedbackCommandWithTransition(ctx) {
109388
109617
  } else {
109389
109618
  await activatePrWorkflow(ctx.directory, ctx.sessionID, "PR_FEEDBACK", {
109390
109619
  requireCheckoutPreflight: true,
109391
- ...parsed.prUrl ? { prUrl: parsed.prUrl } : {}
109620
+ ...parsed.prUrl ? { prUrl: parsed.prUrl } : {},
109621
+ ...parsed.prUrl ? { forge: resolveCommandForgeContext(ctx.directory, parsed.prUrl) } : {}
109392
109622
  });
109393
109623
  }
109394
109624
  return handlePrFeedbackCommand(ctx.directory, ctx.args);
@@ -109638,7 +109868,7 @@ var COMMAND_REGISTRY = {
109638
109868
  },
109639
109869
  "guardrail explain": {
109640
109870
  handler: async (ctx) => {
109641
- const { handleGuardrailExplain } = await import("./guardrail-explain-ma658hkw.js");
109871
+ const { handleGuardrailExplain } = await import("./guardrail-explain-yfd11za1.js");
109642
109872
  return handleGuardrailExplain(ctx.directory, ctx.args);
109643
109873
  },
109644
109874
  description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
@@ -109648,7 +109878,7 @@ var COMMAND_REGISTRY = {
109648
109878
  },
109649
109879
  "guardrail reset": {
109650
109880
  handler: async (ctx) => {
109651
- const { handleGuardrailReset } = await import("./guardrail-reset-w41yndke.js");
109881
+ const { handleGuardrailReset } = await import("./guardrail-reset-fqgf5sdb.js");
109652
109882
  return handleGuardrailReset(ctx.args, ctx.sessionID);
109653
109883
  },
109654
109884
  description: "Reset one exact active invocation/action circuit after repair",
@@ -109669,7 +109899,7 @@ var COMMAND_REGISTRY = {
109669
109899
  },
109670
109900
  "guardrail-log": {
109671
109901
  handler: async (ctx) => {
109672
- const { handleGuardrailLog } = await import("./guardrail-log-m6mydjet.js");
109902
+ const { handleGuardrailLog } = await import("./guardrail-log-hcr5rptq.js");
109673
109903
  return handleGuardrailLog(ctx.directory, ctx.args);
109674
109904
  },
109675
109905
  description: "Read the guardrail decision log (use --blocks-only for blocks)",
@@ -114977,4 +115207,4 @@ function getAgentConfigs(config, directory, sessionId, projectContext) {
114977
115207
  return result;
114978
115208
  }
114979
115209
 
114980
- export { resetActionCircuitExternally, getBlockingActionCircuit, resolveConfiguredAgentModel, resolveRegisteredAgentModel, resolveEffectiveAgentOverride, dcNormalizeCommand, dcUnwrapWrappers, dcSplitSegments, dcExtractRecursiveRmTargets, dcEvaluateRecursiveDeleteTargets, dcCheckJunctionCreation, dcExtractWindowsCmdTargets, dcExtractPowerShellTargets, getSharedClassifierGuardrailBlock, classifyCommand, MAX_PARALLEL_VERDICT_TASKS, computeParallelVerdict, resetArchitectPromptBudgetAdvisories, createArchitectAgent, createCoderAgent, GENERALIST_COUNCIL_PROMPT, SKEPTIC_COUNCIL_PROMPT, DOMAIN_EXPERT_COUNCIL_PROMPT, createCriticAgent, createCuratorAgent, createDesignerAgent, createDocsAgent, createResearcherAgent, SECURITY_CATEGORIES, createReviewerAgent, createSMEAgent, createTestEngineerAgent, _internals132 as _internals, stripSwarmPrefix, extractSwarmIdFromAgentName, resolveFallbackModel, getSwarmAgents, createAgents, resolvePrimaryAgentNames, getAgentConfigs, SWARM_COMMAND_TOOL_COMMANDS, SWARM_COMMAND_TOOL_ALLOWLIST, HUMAN_ONLY_SWARM_COMMANDS, classifySwarmCommandToolUse, classifySwarmCommandChatFallbackUse, detectPosixWrites, detectWindowsWrites, resolveWriteTargets, getAgentSession, parseLeanLaneIndex, computeLaneRuntimeProfile, MAX_TRACKED_STANDARD_WORKTREE_CALLS, awaitingMergeByCallID, standardWorktreeByCallID, standardWorktreeSerializationSessions, getStandardWorktreeDegradationReason, resetStandardWorktreeIsolationState, checkStandardWorktreeSerializationRelease, sanitizeWorktreeTaskId, preProvisionCollisionCheck, isLaneOwnedByCurrentSession, precreateStandardWorktreeSession, preserveBackgroundWorktreeOwnershipForCallId, preserveDirtyWorktreeForCallId, preserveDirtyWorktreeAtPath, cleanupStandardWorktreeForCallId, abortStandardWorktreeDispatch, finishStandardWorktreeDispatch, readLaneEnvFileFromDisk, _internals24 as _internals1, redactSecrets, prWorkflowSessionFileStem, ensurePrWorkflowSafeParentDirectory, writePrWorkflowAtomicJson, PrWorkflowCheckoutMutationTimeoutError, withPrWorkflowCheckoutMutationLock, PR_REVIEW_REPORT_VERDICTS, allowedPrReviewReportVerdicts, normalizePrReviewPartialBaseCoverageRecord, rollbackPrReviewPartialBaseCoverageAdmission, readPrReviewTerminalCoverageForReport, PR_REVIEW_REQUIRED_MICRO_LANE_IDS, PR_REVIEW_DEPTH_TIER_THRESHOLDS, PR_REVIEW_BASE_LANE_FLOORS, PR_REVIEW_TIER_L_CONSOLIDATED_LANE_FLOOR, PR_REVIEW_MICRO_LANE_FLOORS, computePrReviewDepthTier, MAX_PR_REVIEW_SUBMIT_REJECTIONS, MAX_PR_FEEDBACK_INVENTORY_AMENDMENTS, activatePrWorkflow, appendPrWorkflowSkillContractAdvisories, readPrWorkflowGateState, recordPrReviewSubmitRejection, latestPrReviewSubmitRejectionMessage, submitPrReviewResult, withPrWorkflowCheckoutPreparationLock, withInactivePrWorkflowCheckoutRestoreLock, clearPrWorkflowGateState, terminalizePrWorkflowGateForSession2 as terminalizePrWorkflowGateForSession, PR_WORKFLOW_PROBE_SKIPPED_NO_BUDGET_REASON, collectPrWorkflowPendingLaneLiveness, settlePresumedStalePrWorkflowLanes, abortPrWorkflow, recoverArmedPrWorkflow, bindPrWorkflowHead, rebindPrFeedbackHead, bindPrReviewBase, assertCurrentCheckoutHead, assertPrReviewCleanCheckout, enforcePrWorkflowDispatchLanesAsync, PrReviewResilienceCircuitOpenError, PrReviewResilienceRetryExhaustedError, enforcePrReviewBaseDimensions, rollbackPrReviewBaseAdmissionIfUnlaunched, admitPrReviewPartialBaseCoverage2 as admitPrReviewPartialBaseCoverage, assertPrReviewBaseCoverageSettled2 as assertPrReviewBaseCoverageSettled, recordPrReviewValidationBatch, assertPrReviewValidationSettled, declarePrFeedbackInventory, enforcePrFeedbackVerificationOwnership, assertPrFeedbackVerificationSettled, recordPrFeedbackStageA, recordPrFeedbackGateBatch, assertPrFeedbackGatePhaseSettled, assertPrFeedbackReadyToPublish, invalidatePrFeedbackPublication, describePrWorkflowPublicationSection, findDanglingLivePublicationGeneration, recordPrFeedbackPushAttemptResult, cancelPrFeedbackPublication, resolvePrReviewWriterRunId, markPrReviewTriggerEvaluationComplete, bindPrReviewTriggerLedger, assertPrReviewArtifactBoundary, assertPrReviewArtifactRecordsMatchAuthoritativeVerdicts, markPrReviewArtifactBoundary, markPrReviewHandoffComplete, readPrReviewFinalFindingPolicyForReport, transitionPrReviewToFeedback, declarePrFeedbackScope, resolvePrFeedbackScopeDeclaration, consumePrFeedbackScopeDeclaration, validatePrFeedbackScopeBinding, enforcePrWorkflowToolBefore, readPrReviewReentryBindingContext, hasActivePrReviewReentryAuthorization, reserveActivePrReviewReentryAuthorization, completePrWorkflow, _test_exports2 as _test_exports, normalizePrWorkflowShellCommand, describePrWorkflowRevisionDigestFailure, readAuthoritativePrReviewCriticSettlements, readAuthoritativePrReviewCriticVerdicts, formatPrReviewLaneValidationFailure, validatePrReviewDiscoveryLaneCompletion2 as validatePrReviewDiscoveryLaneCompletion, validatePrWorkflowTransportRecovery, prReviewDiscoveryArtifactCoversLane, MAX_SALVAGED_SCHEMA_ERROR_CHARS, readPrWorkflowGateStateForRecovery, handleAcknowledgeSpecDriftCommand, handleAgentsCommand, handleAnalyzeCommand, handleApproveWriteCommand, handleArchiveCommand, handleAutoProceedCommand, handleBenchmarkCommand, handleBrainstormCommand, handleCheckpointCommand, DEFAULT_CI_DEADLINE_MS2 as DEFAULT_CI_DEADLINE_MS, createSignalCancellation, handleCiCommand, handleCiSimulateCommand, handleClarifyCommand, safeRealpathSync, createCuratorLLMDelegate, startSnapshotCoordinationInitialization, ensureSnapshotCoordinationReady, retrySnapshotCoordinationInitialization, getSnapshotCoordinationStatus, beginSnapshotCoordinationReset, closeSnapshotCoordinationInitialization, markSnapshotCoordinationClosing, _snapshotCoordinationInternals, handleCloseCommand, _internals56 as _internals2, normalizeRecommendationEntryIdToken, parseKnowledgeRecommendations, parseKnowledgeRecommendationsWithDiagnostics, parseStructuredCuratorBlocks, readCuratorSummary, writeCuratorSummary, appendCuratorRecommendation, mergeCuratorPhaseSummary, filterPhaseEvents, checkPhaseCompliance, runCuratorInit, runCuratorPhase, applyCuratorKnowledgeUpdates, isHiveEligible, countDistinctProjects, checkHivePromotions, _internals60 as _internals3, createHivePromoterHook, promoteToHive, promoteFromSwarm, createMemoryGateway, handleCodebaseReviewCommand, handleConcurrencyCommand, handleConfigCommand, handleConsolidateCommand, handleCostsCommand, handleCouncilCommand, getCoChangePairs, handleCurateCommand, handleDarkMatterCommand, handleDeepDiveCommand, handleDeepResearchCommand, getHostConfigDir, getPluginCachePaths, getPluginLockFilePaths, VERSION_PINNED_LEAF, discoverVersionPinnedCachePaths, readCachePackageVersion, handleDiagnoseCommand, handleDoctorCommand, handleEvidenceCommand, handleEvidenceSummaryCommand, handleExportCommand, handleFullAutoCommand, computeQualityBudget, computeSastScan, handleGateAuditCommand, handleGateStatsCommand, handleHandoffCommand, handleBlueprintValidateCommand, handleBlueprintCurrentCommand, handleBlueprintHistoryCommand, handleBlueprintDiffCommand, handleBlueprintExportCommand, handleHarnessCandidateValidateCommand, handleHarnessCandidateShowCommand, handleHarnessCandidateDiffCommand, handleHistoryCommand, handleKnowledgeQuarantineCommand, handleKnowledgeRestoreCommand, handleKnowledgeMigrateCommand, handleKnowledgeListCommand, handleKnowledgeUnactionableCommand, handleKnowledgeRetryHardeningCommand, handleLearningCommand, handleLinkCommand, searchKnowledge, symbols, handleMemoryCommand, handleMemoryStatusCommand, handleMemoryValueLogCommand, handleMemoryMigrateCommand, handleMemoryImportCommand, handleMemoryExportCommand, handlePlanCommand, handlePreflightCommand, handlePromoteCommand, handleQaGatesCommand, handleRecoverCommand, handleResetCommand, handleResetSessionCommand, handleRetrieveCommand, handleReviewCommand, handleRollbackCommand, handleSddStatusCommand, handleSddValidateCommand, handleSddProjectCommand, handleSddCommand, handleSimulateCommand, handleSpecifyCommand, handleStatusCommand, handleSyncPlanCommand, handleTurboCommand, handleUnlinkCommand, handleWriteRetroCommand, handleHelpCommand, isCommandFailure, COMMAND_REGISTRY, VALID_COMMANDS, _internals27 as _internals4, resolveCommand, normalizeSwarmCommandInput, canonicalCommandKey, formatCommandNotFound, executeSwarmCommand };
115210
+ export { resetActionCircuitExternally, getBlockingActionCircuit, resolveConfiguredAgentModel, resolveRegisteredAgentModel, resolveEffectiveAgentOverride, dcNormalizeCommand, dcUnwrapWrappers, dcSplitSegments, dcExtractRecursiveRmTargets, dcEvaluateRecursiveDeleteTargets, dcCheckJunctionCreation, dcExtractWindowsCmdTargets, dcExtractPowerShellTargets, getSharedClassifierGuardrailBlock, classifyCommand, MAX_PARALLEL_VERDICT_TASKS, computeParallelVerdict, resetArchitectPromptBudgetAdvisories, createArchitectAgent, createCoderAgent, GENERALIST_COUNCIL_PROMPT, SKEPTIC_COUNCIL_PROMPT, DOMAIN_EXPERT_COUNCIL_PROMPT, createCriticAgent, createCuratorAgent, createDesignerAgent, createDocsAgent, createResearcherAgent, SECURITY_CATEGORIES, createReviewerAgent, createSMEAgent, createTestEngineerAgent, _internals132 as _internals, stripSwarmPrefix, extractSwarmIdFromAgentName, resolveFallbackModel, getSwarmAgents, createAgents, resolvePrimaryAgentNames, getAgentConfigs, SWARM_COMMAND_TOOL_COMMANDS, SWARM_COMMAND_TOOL_ALLOWLIST, HUMAN_ONLY_SWARM_COMMANDS, classifySwarmCommandToolUse, classifySwarmCommandChatFallbackUse, detectPosixWrites, detectWindowsWrites, resolveWriteTargets, getAgentSession, parseLeanLaneIndex, computeLaneRuntimeProfile, MAX_TRACKED_STANDARD_WORKTREE_CALLS, awaitingMergeByCallID, standardWorktreeByCallID, standardWorktreeSerializationSessions, getStandardWorktreeDegradationReason, resetStandardWorktreeIsolationState, checkStandardWorktreeSerializationRelease, sanitizeWorktreeTaskId, preProvisionCollisionCheck, isLaneOwnedByCurrentSession, precreateStandardWorktreeSession, preserveBackgroundWorktreeOwnershipForCallId, preserveDirtyWorktreeForCallId, preserveDirtyWorktreeAtPath, cleanupStandardWorktreeForCallId, abortStandardWorktreeDispatch, finishStandardWorktreeDispatch, readLaneEnvFileFromDisk, _internals24 as _internals1, redactSecrets, prWorkflowSessionFileStem, ensurePrWorkflowSafeParentDirectory, writePrWorkflowAtomicJson, PrWorkflowCheckoutMutationTimeoutError, withPrWorkflowCheckoutMutationLock, PR_REVIEW_REPORT_VERDICTS, allowedPrReviewReportVerdicts, normalizePrReviewPartialBaseCoverageRecord, rollbackPrReviewPartialBaseCoverageAdmission, readPrReviewTerminalCoverageForReport, PR_REVIEW_REQUIRED_MICRO_LANE_IDS, PR_REVIEW_DEPTH_TIER_THRESHOLDS, PR_REVIEW_BASE_LANE_FLOORS, PR_REVIEW_TIER_L_CONSOLIDATED_LANE_FLOOR, PR_REVIEW_MICRO_LANE_FLOORS, computePrReviewDepthTier, MAX_PR_REVIEW_SUBMIT_REJECTIONS, MAX_PR_FEEDBACK_INVENTORY_AMENDMENTS, activatePrWorkflow, appendPrWorkflowSkillContractAdvisories, readPrWorkflowGateState, recordPrReviewSubmitRejection, latestPrReviewSubmitRejectionMessage, submitPrReviewResult, withPrWorkflowCheckoutPreparationLock, withInactivePrWorkflowCheckoutRestoreLock, clearPrWorkflowGateState, terminalizePrWorkflowGateForSession2 as terminalizePrWorkflowGateForSession, PR_WORKFLOW_PROBE_SKIPPED_NO_BUDGET_REASON, collectPrWorkflowPendingLaneLiveness, settlePresumedStalePrWorkflowLanes, abortPrWorkflow, recoverArmedPrWorkflow, bindPrWorkflowHead, rebindPrFeedbackHead, bindPrReviewBase, assertCurrentCheckoutHead, assertPrReviewCleanCheckout, enforcePrWorkflowDispatchLanesAsync, PrReviewResilienceCircuitOpenError, PrReviewResilienceRetryExhaustedError, enforcePrReviewBaseDimensions, rollbackPrReviewBaseAdmissionIfUnlaunched, admitPrReviewPartialBaseCoverage2 as admitPrReviewPartialBaseCoverage, assertPrReviewBaseCoverageSettled2 as assertPrReviewBaseCoverageSettled, recordPrReviewMicroFamilyDispatch, recordPrReviewValidationBatch, assertPrReviewValidationSettled, declarePrFeedbackInventory, enforcePrFeedbackVerificationOwnership, assertPrFeedbackVerificationSettled, recordPrFeedbackStageA, recordPrFeedbackGateBatch, assertPrFeedbackGatePhaseSettled, assertPrFeedbackReadyToPublish, invalidatePrFeedbackPublication, describePrWorkflowPublicationSection, findDanglingLivePublicationGeneration, recordPrFeedbackPushAttemptResult, cancelPrFeedbackPublication, resolvePrReviewWriterRunId, markPrReviewTriggerEvaluationComplete, bindPrReviewTriggerLedger, assertPrReviewArtifactBoundary, assertPrReviewArtifactRecordsMatchAuthoritativeVerdicts, markPrReviewArtifactBoundary, markPrReviewHandoffComplete, readPrReviewFinalFindingPolicyForReport, transitionPrReviewToFeedback, declarePrFeedbackScope, resolvePrFeedbackScopeDeclaration, consumePrFeedbackScopeDeclaration, validatePrFeedbackScopeBinding, enforcePrWorkflowToolBefore, readPrReviewReentryBindingContext, hasActivePrReviewReentryAuthorization, reserveActivePrReviewReentryAuthorization, completePrWorkflow, _test_exports2 as _test_exports, normalizePrWorkflowShellCommand, describePrWorkflowRevisionDigestFailure, readAuthoritativePrReviewCriticSettlements, readAuthoritativePrReviewCriticVerdicts, formatPrReviewLaneValidationFailure, validatePrReviewDiscoveryLaneCompletion2 as validatePrReviewDiscoveryLaneCompletion, validatePrWorkflowTransportRecovery, prReviewDiscoveryArtifactCoversLane, MAX_SALVAGED_SCHEMA_ERROR_CHARS, readPrWorkflowGateStateForRecovery, handleAcknowledgeSpecDriftCommand, handleAgentsCommand, handleAnalyzeCommand, handleApproveWriteCommand, handleArchiveCommand, handleAutoProceedCommand, handleBenchmarkCommand, handleBrainstormCommand, handleCheckpointCommand, DEFAULT_CI_DEADLINE_MS2 as DEFAULT_CI_DEADLINE_MS, createSignalCancellation, handleCiCommand, handleCiSimulateCommand, handleClarifyCommand, safeRealpathSync, createCuratorLLMDelegate, startSnapshotCoordinationInitialization, ensureSnapshotCoordinationReady, retrySnapshotCoordinationInitialization, getSnapshotCoordinationStatus, beginSnapshotCoordinationReset, closeSnapshotCoordinationInitialization, markSnapshotCoordinationClosing, _snapshotCoordinationInternals, handleCloseCommand, _internals56 as _internals2, normalizeRecommendationEntryIdToken, parseKnowledgeRecommendations, parseKnowledgeRecommendationsWithDiagnostics, parseStructuredCuratorBlocks, readCuratorSummary, writeCuratorSummary, appendCuratorRecommendation, mergeCuratorPhaseSummary, filterPhaseEvents, checkPhaseCompliance, runCuratorInit, runCuratorPhase, applyCuratorKnowledgeUpdates, isHiveEligible, countDistinctProjects, checkHivePromotions, _internals60 as _internals3, createHivePromoterHook, promoteToHive, promoteFromSwarm, createMemoryGateway, handleCodebaseReviewCommand, handleConcurrencyCommand, handleConfigCommand, handleConsolidateCommand, handleCostsCommand, handleCouncilCommand, getCoChangePairs, handleCurateCommand, handleDarkMatterCommand, handleDeepDiveCommand, handleDeepResearchCommand, getHostConfigDir, getPluginCachePaths, getPluginLockFilePaths, VERSION_PINNED_LEAF, discoverVersionPinnedCachePaths, readCachePackageVersion, handleDiagnoseCommand, handleDoctorCommand, handleEvidenceCommand, handleEvidenceSummaryCommand, handleExportCommand, handleFullAutoCommand, computeQualityBudget, computeSastScan, handleGateAuditCommand, handleGateStatsCommand, handleHandoffCommand, handleBlueprintValidateCommand, handleBlueprintCurrentCommand, handleBlueprintHistoryCommand, handleBlueprintDiffCommand, handleBlueprintExportCommand, handleHarnessCandidateValidateCommand, handleHarnessCandidateShowCommand, handleHarnessCandidateDiffCommand, handleHistoryCommand, handleKnowledgeQuarantineCommand, handleKnowledgeRestoreCommand, handleKnowledgeMigrateCommand, handleKnowledgeListCommand, handleKnowledgeUnactionableCommand, handleKnowledgeRetryHardeningCommand, handleLearningCommand, handleLinkCommand, searchKnowledge, symbols, handleMemoryCommand, handleMemoryStatusCommand, handleMemoryValueLogCommand, handleMemoryMigrateCommand, handleMemoryImportCommand, handleMemoryExportCommand, handlePlanCommand, handlePreflightCommand, handlePromoteCommand, handleQaGatesCommand, handleRecoverCommand, handleResetCommand, handleResetSessionCommand, handleRetrieveCommand, handleReviewCommand, handleRollbackCommand, handleSddStatusCommand, handleSddValidateCommand, handleSddProjectCommand, handleSddCommand, handleSimulateCommand, handleSpecifyCommand, handleStatusCommand, handleSyncPlanCommand, handleTurboCommand, handleUnlinkCommand, handleWriteRetroCommand, handleHelpCommand, isCommandFailure, COMMAND_REGISTRY, VALID_COMMANDS, _internals27 as _internals4, resolveCommand, normalizeSwarmCommandInput, canonicalCommandKey, formatCommandNotFound, executeSwarmCommand };