opencode-swarm 7.177.0 → 7.178.0

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 (118) hide show
  1. package/binaries/win32-arm64/swarm-sandbox-runner.exe +0 -0
  2. package/binaries/win32-x64/swarm-sandbox-runner.exe +0 -0
  3. package/dist/agents/architect.d.ts +9 -1
  4. package/dist/cli/{capability-probe-pdwwz8gs.js → capability-probe-8k8ebeyp.js} +2 -2
  5. package/dist/cli/{coder-settlement-pm07553t.js → coder-settlement-d2bfb25j.js} +13 -13
  6. package/dist/cli/{config-doctor-3mwx2rwq.js → config-doctor-905x2s1c.js} +4 -4
  7. package/dist/cli/{core-ty985ae1.js → core-k7wfx1wx.js} +4 -4
  8. package/dist/cli/{curation-policy-d8s9w1z8.js → curation-policy-n4hd2wsa.js} +5 -5
  9. package/dist/cli/{curator-drift-4m984tvy.js → curator-drift-smqmej5v.js} +4 -4
  10. package/dist/cli/curator-llm-factory-qhhxev17.js +72 -0
  11. package/dist/cli/{curator-pch7ww87.js → curator-wyadq69k.js} +40 -40
  12. package/dist/cli/{evidence-summary-service-cxed89n3.js → evidence-summary-service-r3wcprfk.js} +19 -19
  13. package/dist/cli/{gate-evidence-ymye7yew.js → gate-evidence-tq9rb2aj.js} +8 -8
  14. package/dist/cli/guardrail-explain-kvgejh24.js +73 -0
  15. package/dist/cli/{guardrail-log-pgggycf9.js → guardrail-log-m6twga6x.js} +9 -9
  16. package/dist/cli/{guardrail-reset-aghymhr5.js → guardrail-reset-86esv8cr.js} +40 -40
  17. package/dist/cli/hive-promoter-s87hkb40.js +87 -0
  18. package/dist/cli/{index-zzr7f594.js → index-18hjycr1.js} +1 -1
  19. package/dist/cli/{index-w7aedfce.js → index-29begjkp.js} +8 -8
  20. package/dist/cli/{index-7nsvszwn.js → index-2b1whj28.js} +2 -2
  21. package/dist/cli/{index-7bvzssz0.js → index-2bmhe2jn.js} +4 -4
  22. package/dist/cli/{index-hxdswvtv.js → index-2mdk6nt9.js} +7 -7
  23. package/dist/cli/{index-rz4gpt3n.js → index-2vhkwy6v.js} +3 -3
  24. package/dist/cli/{index-fpbcxykc.js → index-6b295cas.js} +87 -1
  25. package/dist/cli/{index-yzjaj53h.js → index-9rwhas09.js} +1 -1
  26. package/dist/cli/{index-8dy3qf4q.js → index-at0ygwwp.js} +5 -5
  27. package/dist/cli/{index-q1jterxw.js → index-azy3tw6c.js} +2 -2
  28. package/dist/cli/{index-eefz8ghz.js → index-bfz1jvcn.js} +1 -1
  29. package/dist/cli/{index-gwnbprzk.js → index-d5dexrv1.js} +4 -4
  30. package/dist/cli/{index-wemtrnch.js → index-ffqy30e5.js} +2 -2
  31. package/dist/cli/{index-5w51tawb.js → index-gg44hytk.js} +9 -9
  32. package/dist/cli/{index-ebmep9me.js → index-heg4em8j.js} +591 -261
  33. package/dist/cli/{index-z8j7jqxt.js → index-j1v54ahd.js} +4 -3
  34. package/dist/cli/{index-tj0sdxg9.js → index-j3rkh9mp.js} +2 -2
  35. package/dist/cli/{index-zbq9091c.js → index-jzxeymr0.js} +13 -13
  36. package/dist/cli/{index-zwam9stk.js → index-ke3m026z.js} +6 -6
  37. package/dist/cli/{index-r18n5f17.js → index-kfk403mc.js} +5 -5
  38. package/dist/cli/{index-5frh43fj.js → index-m2n1rhgv.js} +12 -0
  39. package/dist/cli/{index-k6bjkqw8.js → index-mpcp6rmj.js} +1 -1
  40. package/dist/cli/{index-fnmt1ema.js → index-p27az2hc.js} +4 -4
  41. package/dist/cli/{index-5d2avnj9.js → index-pm7c6f66.js} +2 -2
  42. package/dist/cli/{index-vfp9hjgv.js → index-q9vb5e7n.js} +1 -1
  43. package/dist/cli/{index-0z5s71kn.js → index-qk29b7s4.js} +42 -42
  44. package/dist/cli/{index-by7xpk8f.js → index-qs8eth8h.js} +37 -6
  45. package/dist/cli/{index-ef2fa774.js → index-rp0jk48x.js} +7 -7
  46. package/dist/cli/{index-9ftc8saz.js → index-sqngtwyq.js} +1 -1
  47. package/dist/cli/{index-tzxk6ct7.js → index-swxaa0zs.js} +40 -40
  48. package/dist/cli/{index-xnednxvm.js → index-tnjmn0dn.js} +1 -1
  49. package/dist/cli/{index-rgapg88w.js → index-vfc7d22n.js} +7 -3
  50. package/dist/cli/{index-1bq6hkw5.js → index-w4yjy3vp.js} +1 -1
  51. package/dist/cli/{index-73arkdgf.js → index-wbkxbgk8.js} +9 -5
  52. package/dist/cli/{index-2jtmevrr.js → index-wfbh1bx8.js} +3 -3
  53. package/dist/cli/{index-4chr4gbq.js → index-wkde35ej.js} +9 -9
  54. package/dist/cli/{index-76qm2c2y.js → index-wvghb3x6.js} +4 -4
  55. package/dist/cli/{index-v2he8xfj.js → index-y6a2bkp1.js} +2 -2
  56. package/dist/cli/{index-eya03h5m.js → index-y74n1sy8.js} +7 -7
  57. package/dist/cli/{index-tbswvz8s.js → index-yeh78c1g.js} +2 -2
  58. package/dist/cli/{index-en0p0hqp.js → index-yj1kr0ft.js} +1 -1
  59. package/dist/cli/{index-nzz58tbs.js → index-zex7644g.js} +2 -2
  60. package/dist/cli/{index-exhm2ztr.js → index-zmb8fjp5.js} +1 -1
  61. package/dist/cli/{index-mcq6xs4k.js → index-zsm8h8y1.js} +4 -4
  62. package/dist/cli/{index-yhaxn5r7.js → index-zsp9de3k.js} +2 -2
  63. package/dist/cli/index.js +41 -41
  64. package/dist/cli/{knowledge-escalator-praedffr.js → knowledge-escalator-rgz471df.js} +13 -13
  65. package/dist/cli/{knowledge-events-sn5gs5q9.js → knowledge-events-4mq0ypx9.js} +11 -11
  66. package/dist/cli/{knowledge-link-9z3fha35.js → knowledge-link-npk50523.js} +4 -4
  67. package/dist/cli/{knowledge-store-838sgd97.js → knowledge-store-gft25s5t.js} +5 -5
  68. package/dist/cli/{knowledge-validator-bsxgarqv.js → knowledge-validator-ejqacbx4.js} +7 -7
  69. package/dist/cli/{mcp-skh29erk.js → mcp-emaeeq4s.js} +48 -7
  70. package/dist/cli/mcp.d.ts +9 -0
  71. package/dist/cli/{model-preflight-gk1jysa8.js → model-preflight-kh9dwts2.js} +1 -1
  72. package/dist/cli/{pending-delegations-6zr5es4b.js → pending-delegations-4bhkcykk.js} +11 -11
  73. package/dist/cli/{pr-subscriptions-x2rr3gva.js → pr-subscriptions-h1n6dbds.js} +11 -11
  74. package/dist/cli/{pr-workflow-gate-jx30c9vz.js → pr-workflow-gate-wn6v5za8.js} +40 -40
  75. package/dist/cli/{runner-yhfmejzb.js → runner-ffy5ahhz.js} +5 -5
  76. package/dist/cli/{scan-cursor-6h85e2g0.js → scan-cursor-e63t0g5b.js} +6 -6
  77. package/dist/cli/{schema-8h1b602y.js → schema-4k4hr33y.js} +4 -2
  78. package/dist/cli/{scope-persistence-rb99xjr0.js → scope-persistence-qcw3rtxq.js} +16 -16
  79. package/dist/cli/{server-kdjc5aw8.js → server-58s1wwap.js} +2055 -736
  80. package/dist/cli/{skill-generator-nz7wjabh.js → skill-generator-fhj13jmq.js} +15 -15
  81. package/dist/cli/{snapshot-coordination-init-hexx2msp.js → snapshot-coordination-init-5fawrj35.js} +40 -40
  82. package/dist/cli/{telemetry-w774xb8g.js → telemetry-ca8dmn26.js} +1 -1
  83. package/dist/cli/{workspace-snapshot-9gqna7gq.js → workspace-snapshot-v5qyjxg0.js} +3 -3
  84. package/dist/cli/{worktree-collision-ownership-ecwj3ehp.js → worktree-collision-ownership-hjk0jx19.js} +12 -12
  85. package/dist/cli/{worktree-isolation-0x9fx30v.js → worktree-isolation-aj20bs6q.js} +40 -40
  86. package/dist/commands/dashboard.d.ts +15 -0
  87. package/dist/commands/registry.d.ts +7 -0
  88. package/dist/config/schema.d.ts +16 -0
  89. package/dist/dashboard/assets.d.ts +12 -0
  90. package/dist/dashboard/index.d.ts +74 -0
  91. package/dist/dashboard/server.d.ts +94 -0
  92. package/dist/dashboard/views.d.ts +131 -0
  93. package/dist/events/core-events.d.ts +1 -1
  94. package/dist/hooks/delegation-gate.d.ts +26 -0
  95. package/dist/hooks/index.d.ts +1 -1
  96. package/dist/hooks/tool-summarizer.d.ts +7 -2
  97. package/dist/index.js +437 -276
  98. package/dist/mcp/adapters/knowledge-add.d.ts +19 -0
  99. package/dist/mcp/adapters/receipt-status.d.ts +3 -0
  100. package/dist/mcp/adapters/scope-validation.d.ts +3 -0
  101. package/dist/mcp/registry.d.ts +26 -14
  102. package/dist/mcp/server.d.ts +5 -0
  103. package/dist/mcp/write-receipts.d.ts +168 -0
  104. package/dist/summaries/index.d.ts +1 -1
  105. package/dist/summaries/manager.d.ts +27 -1
  106. package/dist/tools/approve-retry-sounding-board.d.ts +5 -0
  107. package/dist/tools/index.d.ts +3 -0
  108. package/dist/tools/knowledge-receipt-status.d.ts +8 -0
  109. package/dist/tools/manifest.d.ts +3 -0
  110. package/dist/tools/scope-validate.d.ts +55 -0
  111. package/dist/tools/tool-metadata.d.ts +12 -0
  112. package/dist/types/events.d.ts +5 -1
  113. package/dist/utils/path-security.d.ts +21 -0
  114. package/opencode-swarm.schema.json +14 -0
  115. package/package.json +1 -1
  116. package/dist/cli/curator-llm-factory-zbs6hm60.js +0 -72
  117. package/dist/cli/guardrail-explain-1zy8c3vn.js +0 -73
  118. package/dist/cli/hive-promoter-3dp8qbqc.js +0 -87
@@ -16,7 +16,7 @@ import {
16
16
  resolveExecutableFromPath,
17
17
  runEvaluation,
18
18
  runExternalTool
19
- } from "./index-vfp9hjgv.js";
19
+ } from "./index-q9vb5e7n.js";
20
20
  import {
21
21
  finalizeShellAuditForClose,
22
22
  isPolicyProtectedPath,
@@ -26,20 +26,20 @@ import {
26
26
  protectedRoots,
27
27
  redactDecisionLineForArchive,
28
28
  stableCanonicalStringify
29
- } from "./index-by7xpk8f.js";
29
+ } from "./index-qs8eth8h.js";
30
30
  import {
31
31
  canonicalProjectKey,
32
32
  closeGroupCommitWriter,
33
33
  getGlobalEventBus,
34
34
  getGroupCommitWriter,
35
35
  importLegacyJsonl
36
- } from "./index-eefz8ghz.js";
36
+ } from "./index-bfz1jvcn.js";
37
37
  import {
38
38
  detectStraySwarmDirs,
39
39
  readDoctorArtifact,
40
40
  removeStraySwarmDir,
41
41
  runConfigDoctor
42
- } from "./index-rgapg88w.js";
42
+ } from "./index-vfc7d22n.js";
43
43
  import {
44
44
  MAX_TRANSIENT_RETRIES,
45
45
  archiveEvidence,
@@ -81,7 +81,7 @@ import {
81
81
  updateTaskStatus,
82
82
  validateProjectRoot,
83
83
  withPlanLifecycleLock
84
- } from "./index-zbq9091c.js";
84
+ } from "./index-jzxeymr0.js";
85
85
  import {
86
86
  EvaluationTaskV1Schema,
87
87
  GateAuditManifestV1Schema,
@@ -98,7 +98,7 @@ import {
98
98
  saveGateAuditResult,
99
99
  savePromotionDecision,
100
100
  saveTaskSetSnapshot
101
- } from "./index-k6bjkqw8.js";
101
+ } from "./index-mpcp6rmj.js";
102
102
  import {
103
103
  canonicalHash,
104
104
  canonicalJson,
@@ -125,7 +125,7 @@ import {
125
125
  isCanonicalPathWithinRoot,
126
126
  validateSymlinkBoundary,
127
127
  validateTargetWithinRoot
128
- } from "./index-fpbcxykc.js";
128
+ } from "./index-6b295cas.js";
129
129
  import {
130
130
  BUNDLED_PROJECT_SKILL_ROOT,
131
131
  DEFAULT_SKILL_MIN_CONFIDENCE,
@@ -146,15 +146,15 @@ import {
146
146
  retireSkill,
147
147
  selectCandidateEntries,
148
148
  syncBundledProjectSkillsIfMissingAsync
149
- } from "./index-mcq6xs4k.js";
149
+ } from "./index-zsm8h8y1.js";
150
150
  import {
151
151
  readRecentEscalations
152
- } from "./index-8dy3qf4q.js";
152
+ } from "./index-at0ygwwp.js";
153
153
  import {
154
154
  alreadyCuratedThisGeneration,
155
155
  claimNextScanBatch,
156
156
  resolveCohortId
157
- } from "./index-nzz58tbs.js";
157
+ } from "./index-zex7644g.js";
158
158
  import {
159
159
  CURATOR_CONSOLIDATION_PROMPT,
160
160
  CURATOR_INIT_PROMPT,
@@ -174,7 +174,7 @@ import {
174
174
  sweepStale,
175
175
  unsubscribe,
176
176
  updateSnapshot
177
- } from "./index-eya03h5m.js";
177
+ } from "./index-y74n1sy8.js";
178
178
  import {
179
179
  clearWorktreeMergeStatus,
180
180
  getAllWorktreeMergeFailures,
@@ -186,7 +186,7 @@ import {
186
186
  listCoderSettlementWalStates,
187
187
  recoverCoderSettlement,
188
188
  recoverStaleCoderSettlements
189
- } from "./index-4chr4gbq.js";
189
+ } from "./index-wkde35ej.js";
190
190
  import {
191
191
  parsePorcelainV2Snapshot,
192
192
  resolveCommitCountSince,
@@ -214,12 +214,12 @@ import {
214
214
  resolveRemoteUrlIdentity,
215
215
  resolveRemoteUrlIdentityAsync,
216
216
  switchPrFeedbackTrackingCandidateAsync
217
- } from "./index-5d2avnj9.js";
217
+ } from "./index-pm7c6f66.js";
218
218
  import {
219
219
  WORKTREE_LIFECYCLE_LOCK_FILE,
220
220
  recordWorktreeProvisioningOwner,
221
221
  removeWorktreeProvisioningOwner
222
- } from "./index-7nsvszwn.js";
222
+ } from "./index-2b1whj28.js";
223
223
  import {
224
224
  getLanguageForExtension
225
225
  } from "./index-pt7h91zc.js";
@@ -257,7 +257,7 @@ import {
257
257
  transitionTaskWorkflowEvidence,
258
258
  withTaskEvidenceTransaction,
259
259
  writeWorkflowWalFile
260
- } from "./index-r18n5f17.js";
260
+ } from "./index-kfk403mc.js";
261
261
  import {
262
262
  isPathUnderSwarmWorktreeBase,
263
263
  listLiveLaneOwners,
@@ -266,7 +266,7 @@ import {
266
266
  recordLiveLaneOwner,
267
267
  removeWorktree,
268
268
  resolveWorktreeBaseDir
269
- } from "./index-fnmt1ema.js";
269
+ } from "./index-p27az2hc.js";
270
270
  import {
271
271
  DEFAULT_STALE_DELEGATION_TIMEOUT_MS,
272
272
  DELEGATION_COMPACTION_HIGH_WATER_BYTES,
@@ -300,7 +300,7 @@ import {
300
300
  scanBackgroundCoderReservationsForAdmission,
301
301
  scanDelegationsForRecovery,
302
302
  sweepStaleDelegations
303
- } from "./index-ef2fa774.js";
303
+ } from "./index-rp0jk48x.js";
304
304
  import {
305
305
  MAX_EVENT_LOG_ENTRIES,
306
306
  _internals,
@@ -316,13 +316,13 @@ import {
316
316
  recordKnowledgeEvent,
317
317
  recordPhaseCloseIntent,
318
318
  resolveKnowledgeEventsPath
319
- } from "./index-w7aedfce.js";
319
+ } from "./index-29begjkp.js";
320
320
  import {
321
321
  estimateTokens,
322
322
  readSwarmFileAsync,
323
323
  safeHook,
324
324
  validateSwarmPath
325
- } from "./index-exhm2ztr.js";
325
+ } from "./index-zmb8fjp5.js";
326
326
  import {
327
327
  bunFile,
328
328
  bunSpawn,
@@ -342,18 +342,18 @@ import {
342
342
  validateActionableFields,
343
343
  validateLesson,
344
344
  validateSkillPath
345
- } from "./index-gwnbprzk.js";
345
+ } from "./index-d5dexrv1.js";
346
346
  import {
347
347
  MAX_CURATION_PROPOSALS,
348
348
  authorizeCuration,
349
349
  buildConfigFingerprintInput
350
- } from "./index-wemtrnch.js";
350
+ } from "./index-ffqy30e5.js";
351
351
  import {
352
352
  cohortConfigFingerprint
353
353
  } from "./index-rtry5xyf.js";
354
354
  import {
355
355
  resolveWorktreeIsolationConfig
356
- } from "./index-rz4gpt3n.js";
356
+ } from "./index-2vhkwy6v.js";
357
357
  import {
358
358
  RetrospectiveEvidenceSchema
359
359
  } from "./index-frcemc0b.js";
@@ -364,7 +364,7 @@ import {
364
364
  clearScopeBindingFromDisk,
365
365
  clearScopeBindings,
366
366
  readScopeFromDisk
367
- } from "./index-5w51tawb.js";
367
+ } from "./index-gg44hytk.js";
368
368
  import {
369
369
  clearPlanLedgerForReset,
370
370
  computePlanStructureHash,
@@ -380,7 +380,7 @@ import {
380
380
  replayFromLedgerWithStatus,
381
381
  resolvePlanningProfile,
382
382
  takeSnapshotEvent
383
- } from "./index-zwam9stk.js";
383
+ } from "./index-ke3m026z.js";
384
384
  import {
385
385
  CORE_EVENT_LOCKED,
386
386
  appendCoreEventSync,
@@ -390,7 +390,7 @@ import {
390
390
  hasSpecDriftAuditEvent,
391
391
  hasTaskRepairAuditEvent,
392
392
  readCoreEvents
393
- } from "./index-z8j7jqxt.js";
393
+ } from "./index-j1v54ahd.js";
394
394
  import {
395
395
  DEFAULT_QA_GATES,
396
396
  computeProfileHash,
@@ -398,7 +398,7 @@ import {
398
398
  getEffectiveGates,
399
399
  getProfileLookupForIdentity,
400
400
  setGatesForIdentity
401
- } from "./index-v2he8xfj.js";
401
+ } from "./index-y6a2bkp1.js";
402
402
  import {
403
403
  MAX_COORDINATION_STATE_LIST_ROWS,
404
404
  deleteCoordinationImports,
@@ -410,7 +410,7 @@ import {
410
410
  listCoordinationStates,
411
411
  transitionCoordinationState,
412
412
  withCoordinationTransaction
413
- } from "./index-1bq6hkw5.js";
413
+ } from "./index-w4yjy3vp.js";
414
414
  import {
415
415
  DURABILITY_CLASSES,
416
416
  closeAllProjectDbs,
@@ -418,7 +418,7 @@ import {
418
418
  getProjectDb,
419
419
  projectDbExists,
420
420
  projectDbPath
421
- } from "./index-xnednxvm.js";
421
+ } from "./index-tnjmn0dn.js";
422
422
  import {
423
423
  loadDatabaseCtor
424
424
  } from "./index-rdm3px0g.js";
@@ -433,7 +433,7 @@ import {
433
433
  observeCuratorCompliance,
434
434
  observeStoreHealth,
435
435
  readLearningHealth
436
- } from "./index-tbswvz8s.js";
436
+ } from "./index-yeh78c1g.js";
437
437
  import {
438
438
  appendKnowledge,
439
439
  appendRejectedLesson,
@@ -463,7 +463,7 @@ import {
463
463
  transactFile,
464
464
  transactKnowledge,
465
465
  wordBigrams
466
- } from "./index-hxdswvtv.js";
466
+ } from "./index-2mdk6nt9.js";
467
467
  import {
468
468
  readTailJsonl,
469
469
  readTailJsonlDetailed,
@@ -484,7 +484,7 @@ import {
484
484
  resolveLinkDir,
485
485
  sanitizeLinkId,
486
486
  writeLinkPointer
487
- } from "./index-en0p0hqp.js";
487
+ } from "./index-yj1kr0ft.js";
488
488
  import {
489
489
  assertProjectRoot,
490
490
  atomicWriteFile,
@@ -493,7 +493,7 @@ import {
493
493
  listActiveLocks,
494
494
  tryAcquireLock,
495
495
  withEvidenceLock
496
- } from "./index-tj0sdxg9.js";
496
+ } from "./index-j3rkh9mp.js";
497
497
  import {
498
498
  require_proper_lockfile
499
499
  } from "./index-7g4c7s5r.js";
@@ -507,7 +507,7 @@ import {
507
507
  pseudonymousRef,
508
508
  resolveLineageSalt,
509
509
  telemetry
510
- } from "./index-2jtmevrr.js";
510
+ } from "./index-wfbh1bx8.js";
511
511
  import {
512
512
  atomicWriteSwarmFile,
513
513
  atomicWriteSwarmFileSync,
@@ -515,7 +515,7 @@ import {
515
515
  matchTempGrammar,
516
516
  parseTargetBasename,
517
517
  resetSwarmArtifactCache
518
- } from "./index-yhaxn5r7.js";
518
+ } from "./index-zsp9de3k.js";
519
519
  import {
520
520
  canonicalRootKey,
521
521
  canonicalRootKeyFresh,
@@ -532,7 +532,7 @@ import {
532
532
  loadGateOverrides,
533
533
  loadPluginConfig,
534
534
  loadPluginConfigWithMeta
535
- } from "./index-zzr7f594.js";
535
+ } from "./index-18hjycr1.js";
536
536
  import {
537
537
  init_git_executable,
538
538
  resolveGitExecutable,
@@ -561,7 +561,7 @@ import {
561
561
  resolveAutoReviewConfig,
562
562
  resolveGeneratedAgentRole,
563
563
  stripKnownSwarmPrefix
564
- } from "./index-73arkdgf.js";
564
+ } from "./index-wbkxbgk8.js";
565
565
  import {
566
566
  AGENT_TOOL_MAP,
567
567
  ALL_AGENT_NAMES,
@@ -584,7 +584,7 @@ import {
584
584
  init_agent_names,
585
585
  init_constants,
586
586
  init_tool_metadata
587
- } from "./index-5frh43fj.js";
587
+ } from "./index-m2n1rhgv.js";
588
588
  import {
589
589
  KNOWLEDGE_SCHEMA_VERSION,
590
590
  OUTCOME_BLOCK_THRESHOLD,
@@ -602,11 +602,12 @@ import {
602
602
  init_executor,
603
603
  isUntrustedEnvKey,
604
604
  isValidEnvKey
605
- } from "./index-76qm2c2y.js";
605
+ } from "./index-wvghb3x6.js";
606
606
  import {
607
607
  init_path_identity,
608
- sanitizeDiagnosticText
609
- } from "./index-yzjaj53h.js";
608
+ sanitizeDiagnosticText,
609
+ unsafePathTextReason
610
+ } from "./index-9rwhas09.js";
610
611
  import {
611
612
  criticalWarn,
612
613
  error,
@@ -3175,7 +3176,7 @@ async function importLegacyPrWorkflowGateStateIfNeeded(directory, sessionID, all
3175
3176
  return null;
3176
3177
  throw error2;
3177
3178
  }
3178
- const legacy = allowSalvagedImport ? (await (await import("./pr-workflow-gate-jx30c9vz.js")).readPrWorkflowGateStateForRecovery(directory, sessionID))?.state ?? null : await readPrWorkflowGateStateFileFromDisk(filePath, sessionID);
3179
+ const legacy = allowSalvagedImport ? (await (await import("./pr-workflow-gate-wn6v5za8.js")).readPrWorkflowGateStateForRecovery(directory, sessionID))?.state ?? null : await readPrWorkflowGateStateFileFromDisk(filePath, sessionID);
3179
3180
  if (!legacy)
3180
3181
  return null;
3181
3182
  const namespace = workflowGateStateCoordinationNamespace(sessionID);
@@ -3245,7 +3246,7 @@ async function deleteStateWhileLocked(directory, sessionID, options = {}) {
3245
3246
  let recoveryState = null;
3246
3247
  if (!currentAuthoritative) {
3247
3248
  if (options.allowSalvagedRead) {
3248
- const { readPrWorkflowGateStateForRecovery } = await import("./pr-workflow-gate-jx30c9vz.js");
3249
+ const { readPrWorkflowGateStateForRecovery } = await import("./pr-workflow-gate-wn6v5za8.js");
3249
3250
  recoveryState = (await readPrWorkflowGateStateForRecovery(directory, normalizedSessionID))?.state ?? null;
3250
3251
  }
3251
3252
  if (!recoveryState) {
@@ -14214,7 +14215,7 @@ function isLaneOwnedByCurrentSession(branchName, expectedSessionId) {
14214
14215
  return extracted === expectedSessionId;
14215
14216
  }
14216
14217
  async function inspectStandardWorktreeCollisionOwnership(identity) {
14217
- const collisionOwnership = await import("./worktree-collision-ownership-ecwj3ehp.js");
14218
+ const collisionOwnership = await import("./worktree-collision-ownership-hjk0jx19.js");
14218
14219
  return collisionOwnership.inspectStandardWorktreeCollisionOwnership(identity);
14219
14220
  }
14220
14221
  async function runRecoveryGit(directory, args, timeoutMs = 15000) {
@@ -14640,7 +14641,7 @@ async function precreateStandardWorktreeSession(args) {
14640
14641
  const laneProfile = computeLaneRuntimeProfile(worktreeConfig.runtime_isolation, laneIndex, handle.worktreePath);
14641
14642
  if (laneProfile) {
14642
14643
  try {
14643
- const { writeLaneProfileToDiskReal } = await import("./core-ty985ae1.js");
14644
+ const { writeLaneProfileToDiskReal } = await import("./core-k7wfx1wx.js");
14644
14645
  await writeLaneProfileToDiskReal(handle.worktreePath, laneProfile.laneIndex, laneProfile.envOverrides);
14645
14646
  } catch {}
14646
14647
  }
@@ -15619,7 +15620,7 @@ async function finishStandardWorktreeDispatch(directory, dispatch, config, callI
15619
15620
  }
15620
15621
  clearWorktreeMergeStatus(statusKey);
15621
15622
  try {
15622
- const { removeLaneProfileFromDiskReal } = await import("./core-ty985ae1.js");
15623
+ const { removeLaneProfileFromDiskReal } = await import("./core-k7wfx1wx.js");
15623
15624
  await removeLaneProfileFromDiskReal(dispatch.handle.worktreePath, dispatch.laneIndex);
15624
15625
  } catch {}
15625
15626
  const state = serializationStateBySessionID.get(dispatch.parentSessionID);
@@ -18938,8 +18939,12 @@ function getSandboxSkipSummary(sessionID) {
18938
18939
  init_path_identity();
18939
18940
 
18940
18941
  // src/hooks/shell-write-detect.ts
18942
+ init_path_identity();
18941
18943
  import * as path20 from "path";
18942
18944
  import parse from "bash-parser";
18945
+ function unsafeShellCommandTextReason(value) {
18946
+ return unsafePathTextReason(value.replace(/[\r\n]/g, ""));
18947
+ }
18943
18948
  function buildDedupeKey(category, operator, path21) {
18944
18949
  return `${category}|${operator}|${path21 ?? "null"}`;
18945
18950
  }
@@ -18950,16 +18955,20 @@ var REDIRECT_WRITE_TOKENS = new Set([
18950
18955
  "LESSGREAT"
18951
18956
  ]);
18952
18957
  var REDIRECT_HERE_TOKENS = new Set(["DLESS", "DLESSDASH"]);
18958
+ var REDIRECT_GREATAND_TOKENS = new Set(["GREATAND"]);
18953
18959
  var REDIRECT_ALL_WRITE_TOKENS = new Set([
18954
18960
  ...REDIRECT_WRITE_TOKENS,
18955
- ...REDIRECT_HERE_TOKENS
18961
+ ...REDIRECT_HERE_TOKENS,
18962
+ ...REDIRECT_GREATAND_TOKENS
18956
18963
  ]);
18957
18964
  var BUILTIN_WRITE_COMMANDS = new Set([
18958
18965
  "cp",
18959
18966
  "mv",
18960
18967
  "install",
18961
18968
  "ln",
18962
- "truncate"
18969
+ "truncate",
18970
+ "unlink",
18971
+ "rmdir"
18963
18972
  ]);
18964
18973
  var INPLACE_EDIT_COMMANDS = new Set(["sed", "perl", "awk"]);
18965
18974
  var INTERPRETER_EVAL_COMMANDS = new Set([
@@ -18970,7 +18979,13 @@ var INTERPRETER_EVAL_COMMANDS = new Set([
18970
18979
  "bun",
18971
18980
  "ruby",
18972
18981
  "perl",
18973
- "php"
18982
+ "php",
18983
+ "bash",
18984
+ "sh",
18985
+ "dash",
18986
+ "zsh",
18987
+ "ksh",
18988
+ "eval"
18974
18989
  ]);
18975
18990
  var NETWORK_DOWNLOAD_COMMANDS = new Set(["curl", "wget", "scp"]);
18976
18991
  var ARCHIVE_EXTRACT_COMMANDS = new Set([
@@ -19023,6 +19038,9 @@ function detectBuiltinWritesFromString(cmd) {
19023
19038
  if (tokens.length === 0)
19024
19039
  return null;
19025
19040
  const name = tokens[0].toLowerCase();
19041
+ if (name === "rmdir" && tokens.some((token) => /^\/(?:s|q)$/i.test(token))) {
19042
+ return null;
19043
+ }
19026
19044
  if (BUILTIN_WRITE_COMMANDS.has(name)) {
19027
19045
  for (let i = tokens.length - 1;i >= 1; i--) {
19028
19046
  if (!tokens[i].startsWith("-")) {
@@ -19190,6 +19208,9 @@ function isNullDevice(path21) {
19190
19208
  function isNumeric(s) {
19191
19209
  return /^\d+$/.test(s);
19192
19210
  }
19211
+ function isNonFileGreatAndTarget(path21) {
19212
+ return path21 !== null && (isNumeric(path21) || path21 === "-");
19213
+ }
19193
19214
  function detectRedirects(cmd) {
19194
19215
  const results = [];
19195
19216
  results.push(...detectHereDocMarkers(cmd));
@@ -19207,7 +19228,7 @@ function detectRedirects(cmd) {
19207
19228
  const fileNode = r.file;
19208
19229
  const path21 = extractRedirectPath(fileNode);
19209
19230
  const opLabel = operatorLabel(opNode);
19210
- if (REDIRECT_WRITE_TOKENS.has(opType)) {
19231
+ if (REDIRECT_WRITE_TOKENS.has(opType) || REDIRECT_GREATAND_TOKENS.has(opType) && !isNonFileGreatAndTarget(path21)) {
19211
19232
  results.push({ category: "redirect", operator: opLabel, path: path21 });
19212
19233
  } else if (REDIRECT_HERE_TOKENS.has(opType)) {
19213
19234
  results.push({ category: "here_doc", operator: opLabel, path: path21 });
@@ -19284,6 +19305,9 @@ function detectBuiltinWrites(cmd) {
19284
19305
  if (!BUILTIN_WRITE_COMMANDS.has(lowerName))
19285
19306
  return results;
19286
19307
  const suffixWords = getSuffixWords(cmd);
19308
+ if (lowerName === "rmdir" && suffixWords.some((word) => /^\/(?:s|q)$/i.test(word))) {
19309
+ return results;
19310
+ }
19287
19311
  if (lowerName === "truncate") {
19288
19312
  for (const word of suffixWords) {
19289
19313
  if (!word.startsWith("-") && !isNumeric(word)) {
@@ -19368,8 +19392,21 @@ function detectInterpreterEval(cmd) {
19368
19392
  bun: ["-e", "-p", "-pe"],
19369
19393
  ruby: ["-e"],
19370
19394
  perl: ["-e", "-E"],
19371
- php: ["-r", "-R", "-F"]
19372
- };
19395
+ php: ["-r", "-R", "-F"],
19396
+ bash: ["-c"],
19397
+ sh: ["-c"],
19398
+ dash: ["-c"],
19399
+ zsh: ["-c"],
19400
+ ksh: ["-c"]
19401
+ };
19402
+ if (lowerName === "eval") {
19403
+ results.push({
19404
+ category: "interpreter_eval",
19405
+ operator: "eval",
19406
+ path: null
19407
+ });
19408
+ return results;
19409
+ }
19373
19410
  const relevantFlags = evalFlags[lowerName] ?? [];
19374
19411
  const hasEvalFlag = suffixWords.some((word) => relevantFlags.some((f) => word === f || word.startsWith(f) && word.length > f.length));
19375
19412
  if (!hasEvalFlag)
@@ -19576,7 +19613,7 @@ function detectGitDestructive(cmd) {
19576
19613
  }
19577
19614
  return results;
19578
19615
  }
19579
- function splitWindowsCommands(command) {
19616
+ function splitWindowsCommands(command, shell) {
19580
19617
  const commands = [];
19581
19618
  let current = "";
19582
19619
  let inSingleQuote = false;
@@ -19584,7 +19621,7 @@ function splitWindowsCommands(command) {
19584
19621
  let parenDepth = 0;
19585
19622
  for (let i = 0;i < command.length; i++) {
19586
19623
  const ch = command[i];
19587
- if (ch === "'" && !inDoubleQuote) {
19624
+ if (shell === "powershell" && ch === "'" && !inDoubleQuote) {
19588
19625
  inSingleQuote = !inSingleQuote;
19589
19626
  } else if (ch === '"' && !inSingleQuote) {
19590
19627
  inDoubleQuote = !inDoubleQuote;
@@ -19593,6 +19630,12 @@ function splitWindowsCommands(command) {
19593
19630
  } else if (ch === ")" && !inSingleQuote && !inDoubleQuote) {
19594
19631
  parenDepth--;
19595
19632
  }
19633
+ if (shell === "powershell" && (ch === ";" || ch === "{" || ch === "}") && !inSingleQuote && !inDoubleQuote && parenDepth === 0) {
19634
+ if (current.trim())
19635
+ commands.push(current.trim());
19636
+ current = "";
19637
+ continue;
19638
+ }
19596
19639
  if (ch === "|" && !inSingleQuote && !inDoubleQuote && parenDepth === 0) {
19597
19640
  if (current.trim())
19598
19641
  commands.push(current.trim());
@@ -19608,6 +19651,10 @@ function splitWindowsCommands(command) {
19608
19651
  continue;
19609
19652
  }
19610
19653
  if (ch === "&" && !inSingleQuote && !inDoubleQuote && parenDepth === 0) {
19654
+ if (command[i - 1] === ">") {
19655
+ current += ch;
19656
+ continue;
19657
+ }
19611
19658
  if (!(i + 1 < command.length && command[i + 1] === "&")) {
19612
19659
  if (current.trim())
19613
19660
  commands.push(current.trim());
@@ -19632,38 +19679,148 @@ var _PS_WRITE_CMDLETS = new Set([
19632
19679
  "Invoke-WebRequest",
19633
19680
  "Start-Process"
19634
19681
  ]);
19635
- var _PS_WRITE_ALIASES = new Set(["echo", "write"]);
19682
+ function detectPowerShellRedirects(command) {
19683
+ const results = [];
19684
+ let inSingleQuote = false;
19685
+ let inDoubleQuote = false;
19686
+ const isBoundary = (character) => character === undefined || /[\s;|&()]/.test(character);
19687
+ for (let index = 0;index < command.length; index++) {
19688
+ const character = command[index];
19689
+ if (inSingleQuote) {
19690
+ if (character === "'") {
19691
+ if (command[index + 1] === "'") {
19692
+ index++;
19693
+ } else {
19694
+ inSingleQuote = false;
19695
+ }
19696
+ }
19697
+ continue;
19698
+ }
19699
+ if (inDoubleQuote) {
19700
+ if (character === "`" && index + 1 < command.length) {
19701
+ index++;
19702
+ continue;
19703
+ }
19704
+ if (character === '"')
19705
+ inDoubleQuote = false;
19706
+ continue;
19707
+ }
19708
+ if (character === "'") {
19709
+ inSingleQuote = true;
19710
+ continue;
19711
+ }
19712
+ if (character === '"') {
19713
+ inDoubleQuote = true;
19714
+ continue;
19715
+ }
19716
+ if (character !== ">")
19717
+ continue;
19718
+ const operator = command[index + 1] === ">" ? ">>" : ">";
19719
+ let cursor = index + operator.length;
19720
+ while (/\s/.test(command[cursor] ?? ""))
19721
+ cursor++;
19722
+ if (command[cursor] === "&") {
19723
+ cursor++;
19724
+ while (/\s/.test(command[cursor] ?? ""))
19725
+ cursor++;
19726
+ const descriptorStart = cursor;
19727
+ while (/\d/.test(command[cursor] ?? ""))
19728
+ cursor++;
19729
+ const descriptor = command.slice(descriptorStart, cursor);
19730
+ if (descriptor && isBoundary(command[cursor])) {
19731
+ index = Math.max(index, cursor - 1);
19732
+ continue;
19733
+ }
19734
+ results.push({ category: "redirect", operator, path: null });
19735
+ index = Math.max(index, cursor - 1);
19736
+ continue;
19737
+ }
19738
+ let pathValue = null;
19739
+ if (cursor < command.length) {
19740
+ const quote = command[cursor];
19741
+ if (quote === '"' || quote === "'") {
19742
+ cursor++;
19743
+ const pathStart = cursor;
19744
+ let closed = false;
19745
+ while (cursor < command.length) {
19746
+ if (quote === '"' && command[cursor] === "`") {
19747
+ cursor += 2;
19748
+ continue;
19749
+ }
19750
+ if (command[cursor] === quote) {
19751
+ if (quote === "'" && command[cursor + 1] === "'") {
19752
+ cursor += 2;
19753
+ continue;
19754
+ }
19755
+ pathValue = command.slice(pathStart, cursor);
19756
+ cursor++;
19757
+ closed = true;
19758
+ break;
19759
+ }
19760
+ cursor++;
19761
+ }
19762
+ if (!closed)
19763
+ pathValue = null;
19764
+ } else {
19765
+ const pathStart = cursor;
19766
+ while (cursor < command.length && !/\s|[;|&()<>]/.test(command[cursor] ?? "")) {
19767
+ cursor++;
19768
+ }
19769
+ if (cursor > pathStart)
19770
+ pathValue = command.slice(pathStart, cursor);
19771
+ }
19772
+ }
19773
+ results.push({ category: "redirect", operator, path: pathValue });
19774
+ index = Math.max(index, cursor - 1);
19775
+ }
19776
+ if (inSingleQuote || inDoubleQuote) {
19777
+ results.push({ category: "redirect", operator: ">", path: null });
19778
+ }
19779
+ return results;
19780
+ }
19636
19781
  function detectPowerShellWrites(command) {
19637
19782
  const results = [];
19638
19783
  const trimmed = command.trim();
19639
19784
  if (!trimmed)
19640
19785
  return results;
19786
+ if (/^(?:powershell|pwsh)(?:\.exe)?\s+/i.test(trimmed) && /(?:^|\s)-(?:e|ec|enc|encodedcommand)(?=\s|=|$)/i.test(trimmed)) {
19787
+ results.push({
19788
+ category: "interpreter_eval",
19789
+ operator: "PowerShell -EncodedCommand",
19790
+ path: null
19791
+ });
19792
+ return results;
19793
+ }
19641
19794
  let innerCommand = trimmed;
19642
- const cmdMatch = trimmed.match(/^(?:powershell|pwsh)\s+(?:-Command|-C)\s+(.*)$/i);
19795
+ const cmdMatch = trimmed.match(/^(?:powershell|pwsh)(?:\.exe)?\s+(?:-Command|-C)\s+(.*)$/i);
19643
19796
  if (cmdMatch) {
19644
19797
  innerCommand = cmdMatch[1].trim();
19645
19798
  if (innerCommand.startsWith('"') && innerCommand.endsWith('"') || innerCommand.startsWith("'") && innerCommand.endsWith("'")) {
19646
19799
  innerCommand = innerCommand.slice(1, -1);
19647
19800
  }
19648
19801
  }
19649
- const redirectMatch = innerCommand.match(/^(.*?)\s+((?:>){1,2})\s*(\S+)$/);
19650
- if (redirectMatch) {
19651
- const beforeRedirect = redirectMatch[1];
19652
- const op = redirectMatch[2];
19653
- const path21 = redirectMatch[3];
19654
- const fdRedirectPattern = /\d>\s*$|\s\d>&$/;
19655
- if (!fdRedirectPattern.test(`${beforeRedirect} ${op}`)) {
19656
- results.push({ category: "redirect", operator: op, path: path21 });
19657
- }
19802
+ if (/(?:^|[;{}|&])\s*(?:Set-Location|Push-Location|Pop-Location|cd|chdir|sl)\b/i.test(innerCommand)) {
19803
+ results.push({
19804
+ category: "builtin_write",
19805
+ operator: "working-directory mutation",
19806
+ path: null
19807
+ });
19808
+ }
19809
+ if (/[({]\s*(?:Out-File|Set-Content|Add-Content|Clear-Content|Copy-Item|Move-Item|Remove-Item)\b/i.test(innerCommand)) {
19810
+ results.push({
19811
+ category: "interpreter_eval",
19812
+ operator: "nested PowerShell script block",
19813
+ path: null
19814
+ });
19658
19815
  }
19659
- const leadingRedirect = innerCommand.match(/^((?:>){1,2})\s+(\S+)$/);
19660
- if (leadingRedirect) {
19816
+ if (/(?:^|[;|])\s*&\s*(?:['"$({]|\S+\s*\()/i.test(innerCommand) || /(?:^|[;|])\s*(?:Invoke-Expression|IEX)\b/i.test(innerCommand)) {
19661
19817
  results.push({
19662
- category: "redirect",
19663
- operator: leadingRedirect[1],
19664
- path: leadingRedirect[2]
19818
+ category: "interpreter_eval",
19819
+ operator: "dynamic PowerShell invocation",
19820
+ path: null
19665
19821
  });
19666
19822
  }
19823
+ results.push(...detectPowerShellRedirects(innerCommand));
19667
19824
  const iwrMatch = trimmed.match(/^(?:Invoke-WebRequest|curl)\s.*?(?:-OutFile\s+(\S+)|-o\s+(\S+))/i);
19668
19825
  if (iwrMatch) {
19669
19826
  const path21 = iwrMatch[1] || iwrMatch[2];
@@ -19678,27 +19835,31 @@ function detectPowerShellWrites(command) {
19678
19835
  function detectPsContentCmdlet(cmd) {
19679
19836
  const cmdletMatch = cmd.match(/^(Out-File|Set-Content|Add-Content|Clear-Content)\b/i);
19680
19837
  if (!cmdletMatch)
19681
- return null;
19838
+ return [];
19682
19839
  const cmdletName = cmdletMatch[1];
19683
19840
  const rest = cmd.slice(cmdletMatch[0].length).trim();
19684
- const pathFlagMatch = rest.match(/(?:-Path|-FilePath|-LiteralPath)\s+("([^"]+)"|'([^']+)'|(\S+))/i);
19841
+ const pathFlagMatch = rest.match(/(?:-Path|-FilePath|-LiteralPath)\s+((?:"[^"]*"|'[^']*'|[^,\s]+)(?:\s*,\s*(?:"[^"]*"|'[^']*'|[^,\s]+))*)/i);
19685
19842
  if (pathFlagMatch) {
19686
- const path21 = pathFlagMatch[2] ?? pathFlagMatch[3] ?? pathFlagMatch[4] ?? "";
19687
- return { category: "redirect", operator: cmdletName, path: path21 };
19843
+ const paths = pathFlagMatch[1].split(/\s*,\s*/).map((value) => value.replace(/^(["'])|(["'])$/g, ""));
19844
+ return paths.map((path21) => ({
19845
+ category: "redirect",
19846
+ operator: cmdletName,
19847
+ path: path21 || null
19848
+ }));
19849
+ }
19850
+ if (/(?:-Path|-FilePath|-LiteralPath)(?:\s|$)/i.test(rest)) {
19851
+ return [{ category: "redirect", operator: cmdletName, path: null }];
19688
19852
  }
19689
19853
  const tokens = rest.match(/(?:[^\s"-]+|"[^"]*"|'[^']*'|-[^\s]+)/g) ?? [];
19690
19854
  for (const token of tokens) {
19691
19855
  if (token.startsWith("-"))
19692
19856
  continue;
19693
19857
  const path21 = token.replace(/^["']|["']$/g, "");
19694
- return { category: "redirect", operator: cmdletName, path: path21 };
19858
+ return [{ category: "redirect", operator: cmdletName, path: path21 }];
19695
19859
  }
19696
- return null;
19697
- }
19698
- const contentResult = detectPsContentCmdlet(innerCommand);
19699
- if (contentResult) {
19700
- results.push(contentResult);
19860
+ return [];
19701
19861
  }
19862
+ results.push(...detectPsContentCmdlet(innerCommand));
19702
19863
  const pipeContentMatch = innerCommand.match(/\|\s*(Out-File|Set-Content|Add-Content|Clear-Content)\b\s*(.*)$/i);
19703
19864
  if (pipeContentMatch) {
19704
19865
  const cmdletName = pipeContentMatch[1];
@@ -19791,27 +19952,6 @@ function detectPowerShellWrites(command) {
19791
19952
  }
19792
19953
  }
19793
19954
  }
19794
- const aliasRedirectMatch = trimmed.match(/^(echo|write)\s+(\S+.*?)\s*(?:>|\s{2,})/i);
19795
- if (aliasRedirectMatch) {
19796
- const _aliasPart = aliasRedirectMatch[0];
19797
- const _afterAlias = trimmed.slice(aliasRedirectMatch[0].length);
19798
- const fullRedirectMatch = trimmed.match(/((?:>){1,2})\s*(\S+)$/);
19799
- if (fullRedirectMatch) {
19800
- results.push({
19801
- category: "redirect",
19802
- operator: fullRedirectMatch[1],
19803
- path: fullRedirectMatch[2]
19804
- });
19805
- }
19806
- }
19807
- const bareAliasMatch = trimmed.match(/^(echo|write)\s+.*?\s+((?:>){1,2})\s*(\S+)$/i);
19808
- if (bareAliasMatch) {
19809
- results.push({
19810
- category: "redirect",
19811
- operator: bareAliasMatch[2],
19812
- path: bareAliasMatch[3]
19813
- });
19814
- }
19815
19955
  return results;
19816
19956
  }
19817
19957
  var _CMD_WRITE_BUILTINS = new Set([
@@ -19823,6 +19963,108 @@ var _CMD_WRITE_BUILTINS = new Set([
19823
19963
  "md",
19824
19964
  "ren"
19825
19965
  ]);
19966
+ var _CMD_COPY_MOVE_SWITCHES = new Set([
19967
+ "/a",
19968
+ "/b",
19969
+ "/d",
19970
+ "/f",
19971
+ "/n",
19972
+ "/v",
19973
+ "/y",
19974
+ "/-y",
19975
+ "/z"
19976
+ ]);
19977
+ function tokenizeCmdArguments(command) {
19978
+ const tokens = [];
19979
+ let current = "";
19980
+ let inDoubleQuote = false;
19981
+ for (let index = 0;index < command.length; index++) {
19982
+ const character = command[index];
19983
+ if (character === "^" && !inDoubleQuote) {
19984
+ if (index + 1 < command.length)
19985
+ current += command[++index];
19986
+ continue;
19987
+ }
19988
+ if (character === '"') {
19989
+ inDoubleQuote = !inDoubleQuote;
19990
+ continue;
19991
+ }
19992
+ if (/\s/.test(character) && !inDoubleQuote) {
19993
+ if (current) {
19994
+ tokens.push(current);
19995
+ current = "";
19996
+ }
19997
+ continue;
19998
+ }
19999
+ current += character;
20000
+ }
20001
+ if (current)
20002
+ tokens.push(current);
20003
+ return tokens;
20004
+ }
20005
+ function detectCmdRedirects(command) {
20006
+ const results = [];
20007
+ let inDoubleQuote = false;
20008
+ const isTokenBoundary = (character) => character === undefined || /[\s&|()]/.test(character);
20009
+ for (let index = 0;index < command.length; index++) {
20010
+ const character = command[index];
20011
+ if (character === "^" && !inDoubleQuote) {
20012
+ index++;
20013
+ continue;
20014
+ }
20015
+ if (character === '"') {
20016
+ inDoubleQuote = !inDoubleQuote;
20017
+ continue;
20018
+ }
20019
+ if (inDoubleQuote || character !== ">")
20020
+ continue;
20021
+ const operator = command[index + 1] === ">" ? ">>" : ">";
20022
+ const targetStart = index + operator.length;
20023
+ let cursor = targetStart;
20024
+ while (/\s/.test(command[cursor] ?? ""))
20025
+ cursor++;
20026
+ if (command[cursor] === "&") {
20027
+ cursor++;
20028
+ while (/\s/.test(command[cursor] ?? ""))
20029
+ cursor++;
20030
+ const descriptorStart = cursor;
20031
+ while (/\d/.test(command[cursor] ?? ""))
20032
+ cursor++;
20033
+ const descriptor = command.slice(descriptorStart, cursor);
20034
+ if (descriptor && isTokenBoundary(command[cursor])) {
20035
+ index = Math.max(index, cursor - 1);
20036
+ continue;
20037
+ }
20038
+ results.push({ category: "redirect", operator, path: null });
20039
+ index = Math.max(index, cursor - 1);
20040
+ continue;
20041
+ }
20042
+ let pathValue = null;
20043
+ if (cursor < command.length) {
20044
+ const quote = command[cursor];
20045
+ if (quote === '"') {
20046
+ const closingQuote = command.indexOf(quote, cursor + 1);
20047
+ if (closingQuote !== -1) {
20048
+ pathValue = command.slice(cursor + 1, closingQuote);
20049
+ cursor = closingQuote + 1;
20050
+ }
20051
+ } else {
20052
+ const pathStart = cursor;
20053
+ while (cursor < command.length && !/[\s&|()<>]/.test(command[cursor] ?? "")) {
20054
+ cursor++;
20055
+ }
20056
+ if (cursor > pathStart)
20057
+ pathValue = command.slice(pathStart, cursor);
20058
+ }
20059
+ }
20060
+ results.push({ category: "redirect", operator, path: pathValue });
20061
+ index = Math.max(index, cursor - 1);
20062
+ }
20063
+ if (inDoubleQuote) {
20064
+ results.push({ category: "redirect", operator: ">", path: null });
20065
+ }
20066
+ return results;
20067
+ }
19826
20068
  function detectCmdWrites(command) {
19827
20069
  const results = [];
19828
20070
  const trimmed = command.trim();
@@ -19836,46 +20078,30 @@ function detectCmdWrites(command) {
19836
20078
  innerCommand = innerCommand.slice(1, -1);
19837
20079
  }
19838
20080
  }
19839
- const redirectMatch = innerCommand.match(/^(.*?)\s+((?:>){1,2})\s*(\S+)$/);
19840
- if (redirectMatch) {
19841
- const beforeRedirect = redirectMatch[1];
19842
- const op = redirectMatch[2];
19843
- const path21 = redirectMatch[3];
19844
- const fdRedirectPattern = /\d>&?$/;
19845
- if (!fdRedirectPattern.test(beforeRedirect)) {
19846
- results.push({ category: "redirect", operator: op, path: path21 });
19847
- }
19848
- }
19849
- const leadingRedirect = innerCommand.match(/^((?:>){1,2})\s+(\S+)$/);
19850
- if (leadingRedirect) {
19851
- results.push({
19852
- category: "redirect",
19853
- operator: leadingRedirect[1],
19854
- path: leadingRedirect[2]
19855
- });
20081
+ if (/^(?:powershell|pwsh)(?:\.exe)?\s+/i.test(innerCommand)) {
20082
+ results.push(...detectPowerShellWrites(innerCommand));
19856
20083
  }
20084
+ results.push(...detectCmdRedirects(innerCommand));
19857
20085
  function detectCmdCopy(cmd) {
19858
- const directMatch = cmd.match(/^copy\s+(\S+|"[^"]+"|'[^']+')\s+(\S+|"[^"]+"|'[^']+')/i);
19859
- if (directMatch) {
19860
- const dest = directMatch[2].replace(/^["']|["']$/g, "");
19861
- return { category: "builtin_write", operator: "copy", path: dest };
19862
- }
19863
- const ifExistMatch = cmd.match(/if\s+exist\s+\S+.*?copy\s+(\S+|"[^"]+"|'[^']+')\s+(\S+|"[^"]+"|'[^']+')/i);
19864
- if (ifExistMatch) {
19865
- const dest = ifExistMatch[2].replace(/^["']|["']$/g, "");
20086
+ const commandMatch = cmd.match(/(?:^|\s)copy(?=\s|$)/i);
20087
+ if (commandMatch) {
20088
+ const start = (commandMatch.index ?? 0) + commandMatch[0].length;
20089
+ const positional = tokenizeCmdArguments(cmd.slice(start)).filter((token) => !_CMD_COPY_MOVE_SWITCHES.has(token.toLowerCase()));
20090
+ if (positional.length < 2)
20091
+ return null;
20092
+ const dest = positional[positional.length - 1];
19866
20093
  return { category: "builtin_write", operator: "copy", path: dest };
19867
20094
  }
19868
20095
  return null;
19869
20096
  }
19870
20097
  function detectCmdMove(cmd) {
19871
- const directMatch = cmd.match(/^move\s+(\S+|"[^"]+"|'[^']+')\s+(\S+|"[^"]+"|'[^']+')/i);
19872
- if (directMatch) {
19873
- const dest = directMatch[2].replace(/^["']|["']$/g, "");
19874
- return { category: "builtin_write", operator: "move", path: dest };
19875
- }
19876
- const ifExistMatch = cmd.match(/if\s+exist\s+\S+.*?move\s+(\S+|"[^"]+"|'[^']+')\s+(\S+|"[^"]+"|'[^']+')/i);
19877
- if (ifExistMatch) {
19878
- const dest = ifExistMatch[2].replace(/^["']|["']$/g, "");
20098
+ const commandMatch = cmd.match(/(?:^|\s)move(?=\s|$)/i);
20099
+ if (commandMatch) {
20100
+ const start = (commandMatch.index ?? 0) + commandMatch[0].length;
20101
+ const positional = tokenizeCmdArguments(cmd.slice(start)).filter((token) => !_CMD_COPY_MOVE_SWITCHES.has(token.toLowerCase()));
20102
+ if (positional.length < 2)
20103
+ return null;
20104
+ const dest = positional[positional.length - 1];
19879
20105
  return { category: "builtin_write", operator: "move", path: dest };
19880
20106
  }
19881
20107
  return null;
@@ -19924,36 +20150,25 @@ function detectCmdWrites(command) {
19924
20150
  results.push({ category: "builtin_write", operator: "md", path: path21 });
19925
20151
  }
19926
20152
  }
19927
- const echoMatch = trimmed.match(/^echo\s+(\S+.*?)\s+((?:>){1,2})\s*(\S+)$/i);
19928
- if (echoMatch) {
19929
- results.push({
19930
- category: "redirect",
19931
- operator: echoMatch[2],
19932
- path: echoMatch[3]
19933
- });
19934
- }
19935
- const echoDotMatch = trimmed.match(/^echo\.\s+((?:>){1,2})\s*(\S+)$/i);
19936
- if (echoDotMatch) {
19937
- results.push({
19938
- category: "redirect",
19939
- operator: echoDotMatch[1],
19940
- path: echoDotMatch[2]
19941
- });
19942
- }
19943
- const setMatch = trimmed.match(/^set\s+\S+\s*=\s*\S*\s*((?:>){1,2})\s*(\S+)$/i);
19944
- if (setMatch) {
19945
- results.push({
19946
- category: "redirect",
19947
- operator: setMatch[1],
19948
- path: setMatch[2]
19949
- });
19950
- }
19951
20153
  return results;
19952
20154
  }
19953
20155
  function detectPosixWrites(command) {
19954
20156
  if (!command || typeof command !== "string") {
19955
20157
  return { writes: [], hasWrites: false };
19956
20158
  }
20159
+ if (unsafeShellCommandTextReason(command)) {
20160
+ return {
20161
+ writes: [
20162
+ {
20163
+ category: "interpreter_eval",
20164
+ operator: "unsafe command text",
20165
+ path: null
20166
+ }
20167
+ ],
20168
+ hasWrites: true,
20169
+ parseError: true
20170
+ };
20171
+ }
19957
20172
  let ast;
19958
20173
  let parseFailed = false;
19959
20174
  try {
@@ -19997,8 +20212,21 @@ function detectWindowsWrites(command, shell) {
19997
20212
  if (!command || typeof command !== "string") {
19998
20213
  return { writes: [], hasWrites: false };
19999
20214
  }
20215
+ if (unsafeShellCommandTextReason(command)) {
20216
+ return {
20217
+ writes: [
20218
+ {
20219
+ category: "interpreter_eval",
20220
+ operator: "unsafe command text",
20221
+ path: null
20222
+ }
20223
+ ],
20224
+ hasWrites: true,
20225
+ parseError: true
20226
+ };
20227
+ }
20000
20228
  try {
20001
- const subCommands = splitWindowsCommands(command);
20229
+ const subCommands = splitWindowsCommands(command, shell);
20002
20230
  const allWrites = [];
20003
20231
  for (const subCmd of subCommands) {
20004
20232
  const writes2 = shell === "powershell" ? detectPowerShellWrites(subCmd) : detectCmdWrites(subCmd);
@@ -20024,10 +20252,18 @@ function isDynamicPath(pathText) {
20024
20252
  return true;
20025
20253
  if (/\$\{[^}]+\}/.test(pathText))
20026
20254
  return true;
20255
+ if (/%[A-Za-z_][A-Za-z0-9_]*%/.test(pathText))
20256
+ return true;
20027
20257
  if (/\$\([^)]+\)/.test(pathText))
20028
20258
  return true;
20029
20259
  if (/`[^`]+`/.test(pathText))
20030
20260
  return true;
20261
+ if (/^~(?:[^/\\\s]*)?(?:[/\\]|$)/.test(pathText))
20262
+ return true;
20263
+ if (/%~[A-Za-z]*(?:\d+|\*)/.test(pathText))
20264
+ return true;
20265
+ if (/%(?:\d+|\*)/.test(pathText))
20266
+ return true;
20031
20267
  return false;
20032
20268
  }
20033
20269
  function resolvePath(pathText, cwd) {
@@ -20201,7 +20437,7 @@ function getWritesFromRedirectNode(redirect, _context) {
20201
20437
  const fileNode = r.file;
20202
20438
  const path21 = extractRedirectPath(fileNode);
20203
20439
  const opLabel = operatorLabel(opNode);
20204
- if (REDIRECT_WRITE_TOKENS.has(opType)) {
20440
+ if (REDIRECT_WRITE_TOKENS.has(opType) || REDIRECT_GREATAND_TOKENS.has(opType) && !isNonFileGreatAndTarget(path21)) {
20205
20441
  return [{ category: "redirect", operator: opLabel, path: path21 }];
20206
20442
  } else if (REDIRECT_HERE_TOKENS.has(opType)) {
20207
20443
  return [{ category: "here_doc", operator: opLabel, path: path21 }];
@@ -22238,7 +22474,7 @@ function getDisplayFinalPromptPressure() {
22238
22474
  async function rehydratePrSubscriptions(sessionID, directory) {
22239
22475
  const map = new Map;
22240
22476
  try {
22241
- const { listActive: listActive2 } = await import("./pr-subscriptions-x2rr3gva.js");
22477
+ const { listActive: listActive2 } = await import("./pr-subscriptions-h1n6dbds.js");
22242
22478
  const records = await listActive2(directory);
22243
22479
  for (const record of records) {
22244
22480
  if (record.sessionID !== sessionID)
@@ -39113,9 +39349,9 @@ function hashContent(content) {
39113
39349
  return createHash24("sha1").update(content).digest("hex");
39114
39350
  }
39115
39351
  async function loadConfigForPolicyCurator(directory) {
39116
- const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-8h1b602y.js");
39352
+ const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-4k4hr33y.js");
39117
39353
  try {
39118
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-7bvzssz0.js");
39354
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-2bmhe2jn.js");
39119
39355
  const { config: loadedConfig } = loadPluginConfigWithMeta2(directory);
39120
39356
  return KnowledgeConfigSchema2.parse(loadedConfig.knowledge ?? {});
39121
39357
  } catch {
@@ -42173,7 +42409,7 @@ async function resolveCuratorLLMDelegate(directory, mode, sessionId) {
42173
42409
  const seam = _internals36.createCuratorLLMDelegate;
42174
42410
  if (seam)
42175
42411
  return seam(directory, mode, sessionId);
42176
- const { createCuratorLLMDelegate } = await import("./curator-llm-factory-zbs6hm60.js");
42412
+ const { createCuratorLLMDelegate } = await import("./curator-llm-factory-qhhxev17.js");
42177
42413
  return createCuratorLLMDelegate(directory, mode, sessionId);
42178
42414
  }
42179
42415
  async function reconcileCloseTerminalStateForPlan(directory, targetPlan, options) {
@@ -42568,7 +42804,7 @@ async function runFinalizeStage(ctx) {
42568
42804
  }
42569
42805
  }
42570
42806
  try {
42571
- const { CuratorConfigSchema: CCS } = await import("./schema-8h1b602y.js");
42807
+ const { CuratorConfigSchema: CCS } = await import("./schema-4k4hr33y.js");
42572
42808
  const { config: pmLoadedConfig } = _internals36.loadPluginConfigWithMeta(ctx.directory);
42573
42809
  const curatorCfg = CCS.parse(pmLoadedConfig.curator ?? {});
42574
42810
  if (curatorCfg.enabled && curatorCfg.postmortem_enabled) {
@@ -43805,7 +44041,14 @@ function isTerminal(state) {
43805
44041
  }
43806
44042
 
43807
44043
  // src/summaries/manager.ts
43808
- import { mkdirSync as mkdirSync14, readdirSync as readdirSync4, renameSync as renameSync11, rmSync as rmSync6, statSync as statSync17 } from "fs";
44044
+ import {
44045
+ linkSync,
44046
+ mkdirSync as mkdirSync14,
44047
+ readdirSync as readdirSync4,
44048
+ rmSync as rmSync6,
44049
+ statSync as statSync17,
44050
+ unlinkSync as unlinkSync10
44051
+ } from "fs";
43809
44052
  import * as path52 from "path";
43810
44053
  var SUMMARY_ID_REGEX = /^S\d+$/;
43811
44054
  function sanitizeSummaryId(id) {
@@ -44345,7 +44588,7 @@ async function countStaleSummaries(projectRoot, retentionDays, now2) {
44345
44588
 
44346
44589
  // src/session/snapshot-coordination-init.ts
44347
44590
  import { createHash as createHash28, randomUUID as randomUUID10 } from "crypto";
44348
- import { existsSync as existsSync27, readFileSync as readFileSync19, renameSync as renameSync12 } from "fs";
44591
+ import { existsSync as existsSync27, readFileSync as readFileSync19, renameSync as renameSync11 } from "fs";
44349
44592
  init_warning_buffer();
44350
44593
 
44351
44594
  // src/session/snapshot-reader.ts
@@ -44358,7 +44601,7 @@ import {
44358
44601
  fsyncSync as fsyncSync3,
44359
44602
  mkdirSync as mkdirSync15,
44360
44603
  openSync as openSync11,
44361
- unlinkSync as unlinkSync10
44604
+ unlinkSync as unlinkSync11
44362
44605
  } from "fs";
44363
44606
  import { rename as fsRename } from "fs/promises";
44364
44607
  import * as path55 from "path";
@@ -44506,7 +44749,7 @@ function serializeAgentSession(s) {
44506
44749
  }
44507
44750
  async function writeSnapshot(directory, state) {
44508
44751
  try {
44509
- const { ensureSnapshotCoordinationReady } = await import("./snapshot-coordination-init-hexx2msp.js");
44752
+ const { ensureSnapshotCoordinationReady } = await import("./snapshot-coordination-init-5fawrj35.js");
44510
44753
  await ensureSnapshotCoordinationReady(directory);
44511
44754
  const snapshot = {
44512
44755
  version: 3,
@@ -44550,7 +44793,7 @@ async function writeSnapshotProjection(directory, snapshot) {
44550
44793
  await renameWithTransientRetry(tempPath, resolvedPath);
44551
44794
  } finally {
44552
44795
  try {
44553
- unlinkSync10(tempPath);
44796
+ unlinkSync11(tempPath);
44554
44797
  } catch {}
44555
44798
  }
44556
44799
  invalidateCachedArtifact(resolvedPath);
@@ -45070,7 +45313,7 @@ function markSnapshotCoordinationClosing(directory) {
45070
45313
  var _snapshotCoordinationInternals = {
45071
45314
  entries,
45072
45315
  initialize: initializeSnapshotCoordination,
45073
- renameLegacySnapshot: renameSync12,
45316
+ renameLegacySnapshot: renameSync11,
45074
45317
  writeProjection: writeSnapshotProjection,
45075
45318
  timeoutMs: READY_TIMEOUT_MS
45076
45319
  };
@@ -47432,7 +47675,7 @@ function planMerges(active, threshold, maxComparisons, maxMerges) {
47432
47675
  };
47433
47676
  }
47434
47677
  async function sweepActiveNearDuplicates(directory, options = {}) {
47435
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-7bvzssz0.js");
47678
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-2bmhe2jn.js");
47436
47679
  const { config } = loadPluginConfigWithMeta2(directory);
47437
47680
  const sweepConfig = config.learning?.dedup_sweep;
47438
47681
  if (sweepConfig?.enabled === false)
@@ -48556,7 +48799,7 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
48556
48799
  }
48557
48800
  if (config.skill_generation_enabled === true && skillCandidates.length > 0) {
48558
48801
  try {
48559
- const skillModule = await import("./skill-generator-nz7wjabh.js");
48802
+ const skillModule = await import("./skill-generator-fhj13jmq.js");
48560
48803
  for (const cand of skillCandidates) {
48561
48804
  if (cand.confidence < (config.min_skill_confidence ?? DEFAULT_SKILL_MIN_CONFIDENCE)) {
48562
48805
  continue;
@@ -49028,7 +49271,7 @@ async function applyCuratorKnowledgeUpdates(directory, recommendations, knowledg
49028
49271
  } catch {}
49029
49272
  }
49030
49273
  if (contradictedEntries.length > 0 && knowledgeConfig.contradiction_threshold_action === "quarantine") {
49031
- const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-praedffr.js");
49274
+ const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-rgz471df.js");
49032
49275
  for (const { id } of contradictedEntries) {
49033
49276
  try {
49034
49277
  await maybeQuarantineOnContradiction(directory, id, knowledgeConfig.contradiction_quarantine_threshold, knowledgeConfig.contradiction_quarantine_window_days);
@@ -49860,7 +50103,7 @@ async function runCuratorPostMortem(directory, options = {}) {
49860
50103
  warnings.push("Failed to collect knowledge summary.");
49861
50104
  }
49862
50105
  try {
49863
- const { getScanStatus } = await import("./scan-cursor-6h85e2g0.js");
50106
+ const { getScanStatus } = await import("./scan-cursor-e63t0g5b.js");
49864
50107
  const scanStatus = await getScanStatus(directory);
49865
50108
  if (scanStatus.remaining_estimate > 0) {
49866
50109
  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.`);
@@ -50032,9 +50275,9 @@ var _internals54 = {
50032
50275
  verifyPostMortemKnowledgeActions,
50033
50276
  repairPostMortemActions,
50034
50277
  loadDefaultKnowledgeConfig: async (directory) => {
50035
- const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-8h1b602y.js");
50278
+ const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-4k4hr33y.js");
50036
50279
  try {
50037
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-7bvzssz0.js");
50280
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-2bmhe2jn.js");
50038
50281
  const loaded = loadPluginConfigWithMeta2(directory);
50039
50282
  return KnowledgeConfigSchema2.parse(loaded.config.knowledge ?? {});
50040
50283
  } catch {
@@ -50042,11 +50285,11 @@ var _internals54 = {
50042
50285
  }
50043
50286
  },
50044
50287
  applyCuratorKnowledgeUpdates: async (directory, recommendations, knowledgeConfig, generation) => {
50045
- const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-pch7ww87.js");
50288
+ const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-wyadq69k.js");
50046
50289
  return applyCuratorKnowledgeUpdates2(directory, recommendations, knowledgeConfig, generation);
50047
50290
  },
50048
50291
  checkHivePromotions: async (entries2, knowledgeConfig, directory) => {
50049
- const { checkHivePromotions } = await import("./hive-promoter-3dp8qbqc.js");
50292
+ const { checkHivePromotions } = await import("./hive-promoter-s87hkb40.js");
50050
50293
  return checkHivePromotions(entries2, knowledgeConfig, directory);
50051
50294
  },
50052
50295
  applyProposalTriage: async (directory, triage) => {
@@ -50055,7 +50298,7 @@ var _internals54 = {
50055
50298
  activateProposal,
50056
50299
  listSkills: listSkills2,
50057
50300
  sanitizeSlug
50058
- } = await import("./skill-generator-nz7wjabh.js");
50301
+ } = await import("./skill-generator-fhj13jmq.js");
50059
50302
  const result = {
50060
50303
  approved: [],
50061
50304
  rejected: [],
@@ -50097,7 +50340,7 @@ var _internals54 = {
50097
50340
  return result;
50098
50341
  },
50099
50342
  readPriorDriftReports: async (directory) => {
50100
- const { readPriorDriftReports } = await import("./curator-drift-4m984tvy.js");
50343
+ const { readPriorDriftReports } = await import("./curator-drift-smqmej5v.js");
50101
50344
  return readPriorDriftReports(directory);
50102
50345
  },
50103
50346
  readSwarmKnowledge: (directory) => readKnowledge(resolveSwarmKnowledgePath(directory))
@@ -54274,7 +54517,7 @@ function resolveRerankerCacheDir() {
54274
54517
  }
54275
54518
 
54276
54519
  // src/memory/jsonl-migration.ts
54277
- import { existsSync as existsSync35, renameSync as renameSync14, unlinkSync as unlinkSync12 } from "fs";
54520
+ import { existsSync as existsSync35, renameSync as renameSync13, unlinkSync as unlinkSync13 } from "fs";
54278
54521
  import { copyFile, mkdir as mkdir14, readFile as readFile17, stat as stat6, writeFile as writeFile9 } from "fs/promises";
54279
54522
  import * as path69 from "path";
54280
54523
  var LEGACY_JSONL_MIGRATION_VERSION = 2;
@@ -54342,30 +54585,30 @@ async function writeJsonlExport(rootDirectory, config, memories, proposals, outc
54342
54585
  const memoriesTempPath = path69.join(path69.dirname(memoriesPath), `${path69.basename(memoriesPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
54343
54586
  try {
54344
54587
  await writeFile9(memoriesTempPath, toJsonl(memories), "utf-8");
54345
- renameSync14(memoriesTempPath, memoriesPath);
54588
+ renameSync13(memoriesTempPath, memoriesPath);
54346
54589
  } catch (err) {
54347
54590
  try {
54348
- unlinkSync12(memoriesTempPath);
54591
+ unlinkSync13(memoriesTempPath);
54349
54592
  } catch {}
54350
54593
  throw err;
54351
54594
  }
54352
54595
  const proposalsTempPath = path69.join(path69.dirname(proposalsPath), `${path69.basename(proposalsPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
54353
54596
  try {
54354
54597
  await writeFile9(proposalsTempPath, toJsonl(proposals), "utf-8");
54355
- renameSync14(proposalsTempPath, proposalsPath);
54598
+ renameSync13(proposalsTempPath, proposalsPath);
54356
54599
  } catch (err) {
54357
54600
  try {
54358
- unlinkSync12(proposalsTempPath);
54601
+ unlinkSync13(proposalsTempPath);
54359
54602
  } catch {}
54360
54603
  throw err;
54361
54604
  }
54362
54605
  const outcomesTempPath = path69.join(path69.dirname(outcomesPath), `${path69.basename(outcomesPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
54363
54606
  try {
54364
54607
  await writeFile9(outcomesTempPath, toJsonl(outcomeEvents), "utf-8");
54365
- renameSync14(outcomesTempPath, outcomesPath);
54608
+ renameSync13(outcomesTempPath, outcomesPath);
54366
54609
  } catch (err) {
54367
54610
  try {
54368
- unlinkSync12(outcomesTempPath);
54611
+ unlinkSync13(outcomesTempPath);
54369
54612
  } catch {}
54370
54613
  throw err;
54371
54614
  }
@@ -54378,10 +54621,10 @@ async function writeMigrationReport(rootDirectory, report, config = {}) {
54378
54621
  try {
54379
54622
  await writeFile9(reportTempPath, `${JSON.stringify(report, null, 2)}
54380
54623
  `, "utf-8");
54381
- renameSync14(reportTempPath, reportPath);
54624
+ renameSync13(reportTempPath, reportPath);
54382
54625
  } catch (err) {
54383
54626
  try {
54384
- unlinkSync12(reportTempPath);
54627
+ unlinkSync13(reportTempPath);
54385
54628
  } catch {}
54386
54629
  throw err;
54387
54630
  }
@@ -58541,7 +58784,7 @@ function wireCloseInternals() {
58541
58784
  archiveEvidence,
58542
58785
  endAgentSession,
58543
58786
  flushAndDrainTelemetry: async () => {
58544
- const { flushAndDrainTelemetry } = await import("./telemetry-w774xb8g.js");
58787
+ const { flushAndDrainTelemetry } = await import("./telemetry-ca8dmn26.js");
58545
58788
  return flushAndDrainTelemetry();
58546
58789
  },
58547
58790
  finalizeContextTelemetry,
@@ -59893,9 +60136,9 @@ var _internals64 = {
59893
60136
  loadPluginConfigWithMeta,
59894
60137
  loadCuratorDeps: async () => {
59895
60138
  const [{ CuratorConfigSchema }, curator, { createCuratorLLMDelegate }] = await Promise.all([
59896
- import("./schema-8h1b602y.js"),
59897
- import("./curator-pch7ww87.js"),
59898
- import("./curator-llm-factory-zbs6hm60.js")
60139
+ import("./schema-4k4hr33y.js"),
60140
+ import("./curator-wyadq69k.js"),
60141
+ import("./curator-llm-factory-qhhxev17.js")
59899
60142
  ]);
59900
60143
  return { CuratorConfigSchema, curator, createCuratorLLMDelegate };
59901
60144
  }
@@ -60045,6 +60288,122 @@ Ensure this is a git repository with commit history.`;
60045
60288
  return output;
60046
60289
  }
60047
60290
 
60291
+ // src/dashboard/index.ts
60292
+ init_logger();
60293
+
60294
+ // src/db/health.ts
60295
+ import { existsSync as existsSync40, statSync as statSync23 } from "fs";
60296
+ import { join as join58 } from "path";
60297
+ var SWARM_DB_QUICK_CHECK_MAX_BYTES = 64 * 1024 * 1024;
60298
+ function getSwarmDbHealthSnapshot(directory) {
60299
+ try {
60300
+ const size = statSync23(projectDbPath(directory)).size;
60301
+ if (size > SWARM_DB_QUICK_CHECK_MAX_BYTES) {
60302
+ return { kind: "too_large", sizeBytes: size };
60303
+ }
60304
+ } catch {
60305
+ return { kind: "absent" };
60306
+ }
60307
+ const staleMarker = existsSync40(join58(canonicalProjectKey(directory), ".swarm", "db-migration-failure.json"));
60308
+ try {
60309
+ const db = getProjectDb(directory);
60310
+ return {
60311
+ kind: "open",
60312
+ quickCheck: db.query("PRAGMA quick_check").get()?.quick_check ?? "unknown",
60313
+ journalMode: db.query("PRAGMA journal_mode").get()?.journal_mode ?? "unknown",
60314
+ pageCount: db.query("PRAGMA page_count").get()?.page_count ?? -1,
60315
+ migrationFailures: db.query("SELECT COUNT(*) as n FROM migration_failures").get()?.n ?? 0,
60316
+ staleMarker
60317
+ };
60318
+ } catch (err) {
60319
+ const category = err && typeof err === "object" && "category" in err ? String(err.category) : "unknown";
60320
+ return {
60321
+ kind: "error",
60322
+ category,
60323
+ message: err instanceof Error ? err.message : String(err)
60324
+ };
60325
+ }
60326
+ }
60327
+
60328
+ // src/dashboard/views.ts
60329
+ var LANE_STALE_HORIZON_MS = 30 * 60000;
60330
+
60331
+ // src/dashboard/server.ts
60332
+ var MAX_RESPONSE_BYTES = 256 * 1024;
60333
+ var LOOPBACK_HOSTS = new Set(["127.0.0.1", "localhost", "::1"]);
60334
+
60335
+ // src/dashboard/index.ts
60336
+ var registry = new Map;
60337
+ function getDashboardHandle(directory) {
60338
+ return registry.get(canonicalProjectKey(directory))?.handle ?? null;
60339
+ }
60340
+
60341
+ // src/commands/dashboard.ts
60342
+ async function readStatusFileRecord(directory) {
60343
+ try {
60344
+ const raw = await readSwarmFileAsync(directory, "dashboard-status.json");
60345
+ if (!raw)
60346
+ return null;
60347
+ const parsed = JSON.parse(raw);
60348
+ return typeof parsed === "object" && parsed !== null ? parsed : null;
60349
+ } catch {
60350
+ return null;
60351
+ }
60352
+ }
60353
+ async function handleDashboardCommand(directory, _args) {
60354
+ const handle = getDashboardHandle(directory);
60355
+ if (handle && handle.listening) {
60356
+ return [
60357
+ "## Swarm dashboard",
60358
+ "",
60359
+ `Status: **listening** on 127.0.0.1:${handle.port} (read-only, token-protected)`,
60360
+ "",
60361
+ `Open: ${handle.url ?? "(url unavailable)"}`,
60362
+ "",
60363
+ "Views: gates & circuits, pending-delegation age bands, lane liveness, task board, activity timeline.",
60364
+ "This page is read-only; abort/recover actions stay in the swarm commands and tools."
60365
+ ].join(`
60366
+ `);
60367
+ }
60368
+ const record = await readStatusFileRecord(directory);
60369
+ if (record && typeof record.status === "string") {
60370
+ if (record.status === "disabled_port_conflict") {
60371
+ return [
60372
+ "## Swarm dashboard",
60373
+ "",
60374
+ "**Disabled \u2014 port conflict.** The configured `dashboard.port` is already in use (or the bind failed), so no listener is running.",
60375
+ "",
60376
+ "Fix: free the port or set another `dashboard.port` in your opencode-swarm.json, then restart the host."
60377
+ ].join(`
60378
+ `);
60379
+ }
60380
+ if (record.status === "stopped") {
60381
+ return [
60382
+ "## Swarm dashboard",
60383
+ "",
60384
+ "The dashboard listener was stopped (host shutdown). It restarts with the next host boot when `dashboard.port` is set."
60385
+ ].join(`
60386
+ `);
60387
+ }
60388
+ }
60389
+ return [
60390
+ "## Swarm dashboard",
60391
+ "",
60392
+ "**Disabled (default).** The local mission-control dashboard is opt-in.",
60393
+ "",
60394
+ "To enable, set a loopback port in your opencode-swarm.json:",
60395
+ "",
60396
+ "```json",
60397
+ "{",
60398
+ ' "dashboard": { "port": 47832 }',
60399
+ "}",
60400
+ "```",
60401
+ "",
60402
+ "When enabled, a read-only, token-protected view (gates & circuits, delegation age bands, lane liveness, task board, activity timeline) serves on 127.0.0.1 and starts after plugin init; port 0 or absent keeps it fully off."
60403
+ ].join(`
60404
+ `);
60405
+ }
60406
+
60048
60407
  // src/commands/dataset.ts
60049
60408
  import { createHash as createHash38 } from "crypto";
60050
60409
 
@@ -61411,42 +61770,6 @@ function readCachePackageVersion(cachePath) {
61411
61770
 
61412
61771
  // src/services/diagnose-service.ts
61413
61772
  init_loader();
61414
-
61415
- // src/db/health.ts
61416
- import { existsSync as existsSync42, statSync as statSync24 } from "fs";
61417
- import { join as join61 } from "path";
61418
- var SWARM_DB_QUICK_CHECK_MAX_BYTES = 64 * 1024 * 1024;
61419
- function getSwarmDbHealthSnapshot(directory) {
61420
- try {
61421
- const size = statSync24(projectDbPath(directory)).size;
61422
- if (size > SWARM_DB_QUICK_CHECK_MAX_BYTES) {
61423
- return { kind: "too_large", sizeBytes: size };
61424
- }
61425
- } catch {
61426
- return { kind: "absent" };
61427
- }
61428
- const staleMarker = existsSync42(join61(canonicalProjectKey(directory), ".swarm", "db-migration-failure.json"));
61429
- try {
61430
- const db = getProjectDb(directory);
61431
- return {
61432
- kind: "open",
61433
- quickCheck: db.query("PRAGMA quick_check").get()?.quick_check ?? "unknown",
61434
- journalMode: db.query("PRAGMA journal_mode").get()?.journal_mode ?? "unknown",
61435
- pageCount: db.query("PRAGMA page_count").get()?.page_count ?? -1,
61436
- migrationFailures: db.query("SELECT COUNT(*) as n FROM migration_failures").get()?.n ?? 0,
61437
- staleMarker
61438
- };
61439
- } catch (err) {
61440
- const category = err && typeof err === "object" && "category" in err ? String(err.category) : "unknown";
61441
- return {
61442
- kind: "error",
61443
- category,
61444
- message: err instanceof Error ? err.message : String(err)
61445
- };
61446
- }
61447
- }
61448
-
61449
- // src/services/diagnose-service.ts
61450
61773
  init_capability_probe();
61451
61774
  init_executor();
61452
61775
  init_path_identity();
@@ -61807,7 +62130,7 @@ import { homedir as homedir6 } from "os";
61807
62130
  import { join as join62 } from "path";
61808
62131
  var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
61809
62132
  var SEMVER_REGEX = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*)(?:\.(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*))*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$/;
61810
- var MAX_RESPONSE_BYTES = 256 * 1024;
62133
+ var MAX_RESPONSE_BYTES2 = 256 * 1024;
61811
62134
  function cacheDir() {
61812
62135
  const xdg = process.env.XDG_CACHE_HOME;
61813
62136
  const base = xdg && xdg.length > 0 ? xdg : join62(homedir6(), ".cache");
@@ -62147,7 +62470,7 @@ async function computeCurationDiagnostics(directory, entries2) {
62147
62470
  let scanCompleted = false;
62148
62471
  let scanRemaining = 0;
62149
62472
  try {
62150
- const { getScanStatus } = await import("./scan-cursor-6h85e2g0.js");
62473
+ const { getScanStatus } = await import("./scan-cursor-e63t0g5b.js");
62151
62474
  const status = await getScanStatus(directory);
62152
62475
  scanGeneration = status.generation;
62153
62476
  scanCompleted = status.completed;
@@ -62155,19 +62478,19 @@ async function computeCurationDiagnostics(directory, entries2) {
62155
62478
  } catch {}
62156
62479
  let configMatch = null;
62157
62480
  try {
62158
- const { isLinked: isLinked2 } = await import("./knowledge-link-9z3fha35.js");
62481
+ const { isLinked: isLinked2 } = await import("./knowledge-link-npk50523.js");
62159
62482
  if (isLinked2(directory)) {
62160
- const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-8h1b602y.js");
62483
+ const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-4k4hr33y.js");
62161
62484
  let config;
62162
62485
  try {
62163
- const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-7bvzssz0.js");
62486
+ const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-2bmhe2jn.js");
62164
62487
  const loaded = loadPluginConfigWithMeta2(directory);
62165
62488
  config = KnowledgeConfigSchema2.parse(loaded.config.knowledge ?? {});
62166
62489
  } catch {
62167
62490
  config = KnowledgeConfigSchema2.parse({});
62168
62491
  }
62169
62492
  const { cohortConfigFingerprint: cohortConfigFingerprint2 } = await import("./config-fingerprint-v22xh5a2.js");
62170
- const { buildConfigFingerprintInput: buildConfigFingerprintInput2, readCohortConfigFingerprint } = await import("./curation-policy-d8s9w1z8.js");
62493
+ const { buildConfigFingerprintInput: buildConfigFingerprintInput2, readCohortConfigFingerprint } = await import("./curation-policy-n4hd2wsa.js");
62171
62494
  const currentFp = cohortConfigFingerprint2(buildConfigFingerprintInput2(config));
62172
62495
  const cohortFp = await readCohortConfigFingerprint(directory);
62173
62496
  configMatch = cohortFp === null ? null : currentFp === cohortFp;
@@ -63603,7 +63926,7 @@ async function handleDoctorCommand(directory, args) {
63603
63926
  const result = runConfigDoctor(config, directory);
63604
63927
  let output;
63605
63928
  if (enableAutoFix && result.hasAutoFixableIssues) {
63606
- const { runConfigDoctorWithFixes } = await import("./config-doctor-3mwx2rwq.js");
63929
+ const { runConfigDoctorWithFixes } = await import("./config-doctor-905x2s1c.js");
63607
63930
  const fixResult = await runConfigDoctorWithFixes(directory, config, true, {
63608
63931
  applyLossy: true
63609
63932
  });
@@ -63641,7 +63964,7 @@ async function handleDoctorCommand(directory, args) {
63641
63964
  `;
63642
63965
  }
63643
63966
  try {
63644
- const { runModelPreflight } = await import("./model-preflight-gk1jysa8.js");
63967
+ const { runModelPreflight } = await import("./model-preflight-kh9dwts2.js");
63645
63968
  const preflight = await runModelPreflight(config, swarmState.opencodeClient);
63646
63969
  if (preflight.catalogAvailable) {
63647
63970
  const unresolved = preflight.resolutions.filter((resolution) => resolution.status === "unresolved");
@@ -64557,7 +64880,7 @@ async function handleEvidenceCommand(directory, args) {
64557
64880
  return formatTaskEvidenceMarkdown(evidenceData);
64558
64881
  }
64559
64882
  async function handleEvidenceSummaryCommand(directory) {
64560
- const { buildEvidenceSummary } = await import("./evidence-summary-service-cxed89n3.js");
64883
+ const { buildEvidenceSummary } = await import("./evidence-summary-service-r3wcprfk.js");
64561
64884
  const artifact = await buildEvidenceSummary(directory);
64562
64885
  if (!artifact) {
64563
64886
  return "No plan found. Run `/swarm plan` to check plan status.";
@@ -65752,7 +66075,7 @@ init_zod();
65752
66075
 
65753
66076
  // src/mutation/engine.ts
65754
66077
  import { spawnSync as spawnSync4 } from "child_process";
65755
- import { unlinkSync as unlinkSync16, writeFileSync as writeFileSync17 } from "fs";
66078
+ import { unlinkSync as unlinkSync17, writeFileSync as writeFileSync17 } from "fs";
65756
66079
  import * as path88 from "path";
65757
66080
  init_git_executable();
65758
66081
 
@@ -66124,7 +66447,7 @@ async function executeMutation(patch, testCommand, testFiles, workingDir, option
66124
66447
  revertError = new Error(`Failed to revert mutation ${patch.id}: ${revertErr}. Working tree may be dirty.`);
66125
66448
  }
66126
66449
  try {
66127
- unlinkSync16(patchFile);
66450
+ unlinkSync17(patchFile);
66128
66451
  } catch (_unlinkErr) {}
66129
66452
  }
66130
66453
  }
@@ -72428,10 +72751,10 @@ import {
72428
72751
  opendirSync as opendirSync2,
72429
72752
  openSync as openSync16,
72430
72753
  readFileSync as readFileSync44,
72431
- renameSync as renameSync18,
72754
+ renameSync as renameSync17,
72432
72755
  rmSync as rmSync14,
72433
72756
  statSync as statSync29,
72434
- unlinkSync as unlinkSync18,
72757
+ unlinkSync as unlinkSync19,
72435
72758
  writeSync as writeSync2
72436
72759
  } from "fs";
72437
72760
  import * as path96 from "path";
@@ -83822,7 +84145,7 @@ init_schema();
83822
84145
 
83823
84146
  // src/memory/memory-family-migration.ts
83824
84147
  var import_proper_lockfile10 = __toESM(require_proper_lockfile(), 1);
83825
- import { copyFileSync as copyFileSync4, existsSync as existsSync58, readFileSync as readFileSync51, unlinkSync as unlinkSync20 } from "fs";
84148
+ import { copyFileSync as copyFileSync4, existsSync as existsSync58, readFileSync as readFileSync51, unlinkSync as unlinkSync21 } from "fs";
83826
84149
  import { mkdir as mkdir21, rename as rename10 } from "fs/promises";
83827
84150
  import * as path111 from "path";
83828
84151
  init_logger();
@@ -84085,10 +84408,10 @@ async function mergeStagedSqlite(destStoragePath, stagedPath) {
84085
84408
  }
84086
84409
  db.close();
84087
84410
  try {
84088
- unlinkSync20(stagedPath);
84411
+ unlinkSync21(stagedPath);
84089
84412
  for (const suffix of ["-wal", "-shm"]) {
84090
84413
  try {
84091
- unlinkSync20(`${stagedPath}${suffix}`);
84414
+ unlinkSync21(`${stagedPath}${suffix}`);
84092
84415
  } catch {}
84093
84416
  }
84094
84417
  } catch {}
@@ -84612,7 +84935,7 @@ function createCuratorLLMDelegate(directory, mode = "init", sessionId) {
84612
84935
  }
84613
84936
  const sdkOpts = signal ? { signal } : {};
84614
84937
  try {
84615
- const { getSwarmAgents: getSwarmAgents2, resolveFallbackModel: resolveFallbackModel2 } = await import("./index-tzxk6ct7.js");
84938
+ const { getSwarmAgents: getSwarmAgents2, resolveFallbackModel: resolveFallbackModel2 } = await import("./index-swxaa0zs.js");
84616
84939
  const createResult = await client.session.create({
84617
84940
  ...sessionId ? {
84618
84941
  body: {
@@ -94400,7 +94723,7 @@ async function handleResetSessionCommand(directory, args, sessionID) {
94400
94723
  "",
94401
94724
  "Session state cleared. Plan, evidence, and knowledge preserved.",
94402
94725
  "",
94403
- "**All circuit breakers and revision limits have been cleared.** You can continue in this session \u2014 fresh state will be initialized automatically on the next tool call."
94726
+ "In-memory circuit breakers and revision limits have been cleared. " + "Durable per-task retry gates (the coder retry circuit breaker, bound " + "to commit settlement in the events audit log and .swarm/evidence/) " + "intentionally survive this reset. If a task is blocked with " + "TASK_RETRY_CRITIC_REQUIRED waiting for a critic_sounding_board " + "APPROVED verdict that was already obtained, have the architect " + "record it with the approve_retry_sounding_board tool."
94404
94727
  ].join(`
94405
94728
  `);
94406
94729
  }
@@ -94765,12 +95088,12 @@ function resolveReviewAgentNames(generatedAgentNames, activeAgentName) {
94765
95088
  const validator = names.find((name) => name === preferredValidator) ?? preferredValidator;
94766
95089
  return { reviewer, validator };
94767
95090
  }
94768
- function reviewFallbackModelStrings(agentName, registry) {
94769
- return registry?.[agentName]?.fallbackModels ?? [];
95091
+ function reviewFallbackModelStrings(agentName, registry2) {
95092
+ return registry2?.[agentName]?.fallbackModels ?? [];
94770
95093
  }
94771
- function resolveReviewFallbackModels(agentName, registry) {
95094
+ function resolveReviewFallbackModels(agentName, registry2) {
94772
95095
  const result = [];
94773
- for (const configured of reviewFallbackModelStrings(agentName, registry)) {
95096
+ for (const configured of reviewFallbackModelStrings(agentName, registry2)) {
94774
95097
  try {
94775
95098
  const parsed = parseModelString2(configured);
94776
95099
  if (parsed)
@@ -97365,8 +97688,8 @@ import {
97365
97688
  existsSync as existsSync69,
97366
97689
  mkdirSync as mkdirSync39,
97367
97690
  readFileSync as readFileSync60,
97368
- renameSync as renameSync21,
97369
- unlinkSync as unlinkSync26,
97691
+ renameSync as renameSync20,
97692
+ unlinkSync as unlinkSync27,
97370
97693
  writeFileSync as writeFileSync23
97371
97694
  } from "fs";
97372
97695
  import * as path131 from "path";
@@ -97384,8 +97707,8 @@ function writeSkillFileAtomic(targetPath, content) {
97384
97707
  }
97385
97708
  var _internals115 = {
97386
97709
  writeFileSync: writeFileSync23,
97387
- renameSync: renameSync21,
97388
- unlinkSync: unlinkSync26
97710
+ renameSync: renameSync20,
97711
+ unlinkSync: unlinkSync27
97389
97712
  };
97390
97713
  async function activateCandidate(input) {
97391
97714
  const skillPath = path131.join(input.directory, ".opencode", "skills", "generated", input.skillSlug, "SKILL.md");
@@ -98530,7 +98853,7 @@ async function runValidationWithTransientRetry(input, candidateContent, baseline
98530
98853
  if (!input.dispatcher) {
98531
98854
  throw new Error("no evaluation dispatcher available (cannot run validation)");
98532
98855
  }
98533
- const { createModelEvaluationExecutor: createModelEvaluationExecutor2 } = await import("./runner-yhfmejzb.js");
98856
+ const { createModelEvaluationExecutor: createModelEvaluationExecutor2 } = await import("./runner-ffy5ahhz.js");
98534
98857
  const executor = createModelEvaluationExecutor2(input.dispatcher, input.sessionId);
98535
98858
  const result = await withProtectedSetIntegrity([evalInputRoot, ...protectedRoots(input.directory)], () => _internals119.evaluateCandidateV1({
98536
98859
  projectRoot: input.directory,
@@ -101159,7 +101482,7 @@ function buildDetailedHelp(commandName, entry) {
101159
101482
  async function handleHelpCommand(ctx) {
101160
101483
  const targetCommand = ctx.args.join(" ");
101161
101484
  if (!targetCommand) {
101162
- const { buildHelpText } = await import("./index-0z5s71kn.js");
101485
+ const { buildHelpText } = await import("./index-qk29b7s4.js");
101163
101486
  return buildHelpText();
101164
101487
  }
101165
101488
  const tokens = targetCommand.split(/\s+/);
@@ -101173,7 +101496,7 @@ async function handleHelpCommand(ctx) {
101173
101496
  > Note: \`/swarm ${resolved.key}\` is a deprecated alias for \`/swarm ${aliasTarget}\`.` : detailed;
101174
101497
  }
101175
101498
  const similar = _internals24.findSimilarCommands(targetCommand);
101176
- const { buildHelpText: fullHelp } = await import("./index-0z5s71kn.js");
101499
+ const { buildHelpText: fullHelp } = await import("./index-qk29b7s4.js");
101177
101500
  if (similar.length > 0) {
101178
101501
  return `Command '/swarm ${targetCommand}' not found.
101179
101502
 
@@ -101488,7 +101811,7 @@ var COMMAND_REGISTRY = {
101488
101811
  },
101489
101812
  "guardrail explain": {
101490
101813
  handler: async (ctx) => {
101491
- const { handleGuardrailExplain } = await import("./guardrail-explain-1zy8c3vn.js");
101814
+ const { handleGuardrailExplain } = await import("./guardrail-explain-kvgejh24.js");
101492
101815
  return handleGuardrailExplain(ctx.directory, ctx.args);
101493
101816
  },
101494
101817
  description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
@@ -101498,7 +101821,7 @@ var COMMAND_REGISTRY = {
101498
101821
  },
101499
101822
  "guardrail reset": {
101500
101823
  handler: async (ctx) => {
101501
- const { handleGuardrailReset } = await import("./guardrail-reset-aghymhr5.js");
101824
+ const { handleGuardrailReset } = await import("./guardrail-reset-86esv8cr.js");
101502
101825
  return handleGuardrailReset(ctx.args, ctx.sessionID);
101503
101826
  },
101504
101827
  description: "Reset one exact active invocation/action circuit after repair",
@@ -101519,7 +101842,7 @@ var COMMAND_REGISTRY = {
101519
101842
  },
101520
101843
  "guardrail-log": {
101521
101844
  handler: async (ctx) => {
101522
- const { handleGuardrailLog } = await import("./guardrail-log-pgggycf9.js");
101845
+ const { handleGuardrailLog } = await import("./guardrail-log-m6twga6x.js");
101523
101846
  return handleGuardrailLog(ctx.directory, ctx.args);
101524
101847
  },
101525
101848
  description: "Read the guardrail decision log (use --blocks-only for blocks)",
@@ -101680,6 +102003,13 @@ var COMMAND_REGISTRY = {
101680
102003
  category: "diagnostics",
101681
102004
  toolPolicy: "agent"
101682
102005
  },
102006
+ dashboard: {
102007
+ handler: (ctx) => handleDashboardCommand(ctx.directory, ctx.args),
102008
+ description: "Show the opt-in local mission-control dashboard URL and status (issue #2509)",
102009
+ details: "Read-only status for the opt-in loopback dashboard over durable swarm state (gates & circuits, delegation age bands, lane liveness, task board, activity timeline). Disabled by default; enable with dashboard.port > 0 in opencode-swarm.json. Never starts or stops the listener \u2014 lifecycle belongs to plugin init; the dashboard itself performs no mutations.",
102010
+ category: "diagnostics",
102011
+ toolPolicy: "agent"
102012
+ },
101683
102013
  learning: {
101684
102014
  handler: (ctx) => handleLearningCommand(ctx.directory, ctx.args),
101685
102015
  description: "Show learning metrics and violation trends",