opencode-swarm 7.185.0 → 7.186.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.
- package/README.md +5 -1
- package/binaries/win32-arm64/swarm-sandbox-runner.exe +0 -0
- package/binaries/win32-x64/swarm-sandbox-runner.exe +0 -0
- package/dist/background/pr-feedback-event-queue.d.ts +3 -2
- package/dist/background/pr-feedback-loop-runtime.d.ts +4 -1
- package/dist/background/pr-feedback-loop.d.ts +2 -1
- package/dist/background/pr-monitor-worker.d.ts +9 -1
- package/dist/background/pr-review-trigger-receipt-reader.d.ts +35 -0
- package/dist/background/pr-subscriptions.d.ts +23 -0
- package/dist/cli/{auto-checkpoint-adn8bg66.js → auto-checkpoint-wd99h2bt.js} +7 -7
- package/dist/cli/{checkpoint-dvyx8gee.js → checkpoint-kjzwsxw2.js} +14 -14
- package/dist/cli/{coder-settlement-95dv9r28.js → coder-settlement-kp3ph56n.js} +10 -10
- package/dist/cli/{config-doctor-f2jtx8y5.js → config-doctor-28ggsms8.js} +2 -2
- package/dist/cli/{core-xn2epqfk.js → core-pj2fz34e.js} +3 -3
- package/dist/cli/{curation-policy-swnyg1jr.js → curation-policy-ytzwb080.js} +4 -4
- package/dist/cli/{curator-drift-qem70sry.js → curator-drift-q84jn9cc.js} +8 -8
- package/dist/cli/curator-llm-factory-13h02244.js +81 -0
- package/dist/cli/{curator-91rqz7xg.js → curator-r0jfc7xw.js} +39 -39
- package/dist/cli/{evidence-summary-service-n7ndpen0.js → evidence-summary-service-rsectw2t.js} +17 -17
- package/dist/cli/{gate-evidence-ajh95p02.js → gate-evidence-mpwhcm2s.js} +5 -5
- package/dist/cli/guardrail-explain-njv3pnsw.js +82 -0
- package/dist/cli/{guardrail-log-b23sf549.js → guardrail-log-r8zmh4rd.js} +6 -6
- package/dist/cli/{guardrail-reset-e6njf0hv.js → guardrail-reset-11cvwgbe.js} +39 -39
- package/dist/cli/{hive-promoter-8dqvfwsx.js → hive-promoter-0vg8w79a.js} +39 -39
- package/dist/cli/{index-2tv5zp9x.js → index-151bdyf9.js} +7 -7
- package/dist/cli/{index-sz755xt1.js → index-1fc5aj26.js} +1 -1
- package/dist/cli/{index-73vnyt4b.js → index-22f1ek6k.js} +39 -39
- package/dist/cli/{index-gemq38en.js → index-373880cv.js} +1 -1
- package/dist/cli/{index-fkzv0hj4.js → index-4dwhfbed.js} +41 -41
- package/dist/cli/{index-gxjy9y0t.js → index-4fd28s8v.js} +2 -2
- package/dist/cli/{index-4ysdy8sx.js → index-5pa0e0k3.js} +4 -4
- package/dist/cli/{index-62z1vsvf.js → index-62akgg9d.js} +1 -1
- package/dist/cli/{index-26nhk01d.js → index-6bfcsczm.js} +1 -1
- package/dist/cli/{index-s0c1wxtt.js → index-6ndc8cmn.js} +1 -1
- package/dist/cli/{index-h5f5q60s.js → index-6sffjy74.js} +1 -1
- package/dist/cli/{index-s5xmvt3k.js → index-74yxwf8y.js} +1 -1
- package/dist/cli/{index-cah5ffkh.js → index-7xt5m1cz.js} +5 -5
- package/dist/cli/{index-97nbaxye.js → index-8nsjefpc.js} +1 -1
- package/dist/cli/{index-1zpgtnhp.js → index-9g61bfj9.js} +1 -1
- package/dist/cli/{index-2e7h9yw5.js → index-9th8npp7.js} +5 -5
- package/dist/cli/{index-359w27b1.js → index-9y6cyc7z.js} +4 -4
- package/dist/cli/{index-djen6c7q.js → index-a1tpq5zr.js} +1 -1
- package/dist/cli/{index-rcx4kb02.js → index-a6h5arqs.js} +4 -4
- package/dist/cli/{index-t9jr6zc7.js → index-afmyp3kt.js} +1 -1
- package/dist/cli/{index-tmd5j8kh.js → index-amamkcpy.js} +4 -4
- package/dist/cli/{index-hx9vyvx0.js → index-bajvxmnb.js} +3 -3
- package/dist/cli/{index-zkm995wa.js → index-bgpq7wn2.js} +856 -619
- package/dist/cli/{index-v5k5jw0r.js → index-d7mcdyqb.js} +2 -2
- package/dist/cli/{index-qccnny3g.js → index-fp4hxcsy.js} +3 -3
- package/dist/cli/{index-n0wyd905.js → index-hvmfa7m8.js} +3 -3
- package/dist/cli/{index-qqjqpmhj.js → index-j972ags2.js} +43 -20
- package/dist/cli/{index-vfr3z9rv.js → index-jxd67x6z.js} +1 -1
- package/dist/cli/{index-fmxty2h3.js → index-kv3n7g8w.js} +2 -2
- package/dist/cli/{index-9am1ry6w.js → index-m94gfe82.js} +7 -7
- package/dist/cli/{index-7jqnckzg.js → index-nen885g8.js} +1 -1
- package/dist/cli/{index-e5wczpj3.js → index-nxjm66qb.js} +2 -2
- package/dist/cli/{index-f3grtpy3.js → index-p6bvzgp2.js} +3 -3
- package/dist/cli/{index-zxm9h19f.js → index-p9m1nhds.js} +3 -3
- package/dist/cli/{index-w7sftxdy.js → index-qyjyd3ej.js} +1 -1
- package/dist/cli/{index-3fnpjy4g.js → index-s68z4a39.js} +2 -2
- package/dist/cli/{index-m7g4dsr4.js → index-vk3ngryj.js} +5 -5
- package/dist/cli/{index-yg15df3b.js → index-vqz0avr4.js} +2 -2
- package/dist/cli/{index-rp0pyywc.js → index-w2b8qq6d.js} +7 -7
- package/dist/cli/{index-6wy9m25t.js → index-wkv1qdb0.js} +18 -20
- package/dist/cli/{index-erv39311.js → index-wmazt588.js} +2 -2
- package/dist/cli/{index-p544ppcp.js → index-xgdypzch.js} +1 -1
- package/dist/cli/{index-580t912d.js → index-yj7etak0.js} +1 -1
- package/dist/cli/{index-zyz0xp2b.js → index-zxck9sr7.js} +1 -1
- package/dist/cli/index.js +40 -40
- package/dist/cli/{knowledge-escalator-xdz6vg62.js → knowledge-escalator-7xcd0zea.js} +11 -11
- package/dist/cli/{knowledge-events-dnca00ye.js → knowledge-events-e4ts8y2v.js} +9 -9
- package/dist/cli/{knowledge-link-y653vvr8.js → knowledge-link-dv78fb9g.js} +3 -3
- package/dist/cli/{knowledge-store-yc20na25.js → knowledge-store-mmeqmjwj.js} +4 -4
- package/dist/cli/{knowledge-validator-c2kfrqdy.js → knowledge-validator-w2ttgxyj.js} +6 -6
- package/dist/cli/{mcp-mefjep3p.js → mcp-5dmm4fk2.js} +1 -1
- package/dist/cli/{model-preflight-5xcxc75n.js → model-preflight-kap3zp3g.js} +39 -39
- package/dist/cli/{pending-delegations-emhmdkn4.js → pending-delegations-q3sj608s.js} +10 -10
- package/dist/cli/{pr-subscriptions-amc1z05d.js → pr-subscriptions-qw4wjv66.js} +12 -10
- package/dist/cli/{pr-workflow-gate-gpq41zx9.js → pr-workflow-gate-tdj50p2g.js} +39 -39
- package/dist/cli/{runner-ss88pbb2.js → runner-tb3eppeg.js} +4 -4
- package/dist/cli/{scan-cursor-71gq82ez.js → scan-cursor-fgecb928.js} +5 -5
- package/dist/cli/{schema-108trhk6.js → schema-zrcgm9d9.js} +1 -1
- package/dist/cli/{scope-persistence-9gfgvy3p.js → scope-persistence-08xd3kyb.js} +13 -13
- package/dist/cli/{server-pkk6y7fa.js → server-kng2nggc.js} +39 -39
- package/dist/cli/{skill-generator-7g6xjwhr.js → skill-generator-dztn1ctf.js} +13 -13
- package/dist/cli/{snapshot-coordination-init-pactfmsy.js → snapshot-coordination-init-5q0hac3d.js} +39 -39
- package/dist/cli/{speckit-checkoff-xyp4c36r.js → speckit-checkoff-hhsy83m9.js} +4 -4
- package/dist/cli/{workspace-snapshot-0hffyjhd.js → workspace-snapshot-kcfkk3a2.js} +3 -3
- package/dist/cli/{worktree-collision-ownership-g26m4c10.js → worktree-collision-ownership-e2cqcmnw.js} +11 -11
- package/dist/cli/{worktree-isolation-52529c62.js → worktree-isolation-refd2n16.js} +39 -39
- package/dist/git/pr.d.ts +73 -0
- package/dist/hooks/extractors.d.ts +24 -0
- package/dist/hooks/pr-workflow-gate.d.ts +2 -0
- package/dist/index.js +52 -48
- package/dist/pr-review/completion.d.ts +14 -1
- package/dist/pr-review/types.d.ts +8 -1
- package/dist/tools/write-pr-review-trigger-eval.d.ts +2 -0
- package/package.json +1 -1
- package/dist/cli/curator-llm-factory-tr6rabws.js +0 -81
- package/dist/cli/guardrail-explain-cne2701m.js +0 -82
|
@@ -8,13 +8,13 @@ import {
|
|
|
8
8
|
protectedRoots,
|
|
9
9
|
redactDecisionLineForArchive,
|
|
10
10
|
stableCanonicalStringify
|
|
11
|
-
} from "./index-
|
|
11
|
+
} from "./index-4fd28s8v.js";
|
|
12
12
|
import {
|
|
13
13
|
detectStraySwarmDirs,
|
|
14
14
|
readDoctorArtifact,
|
|
15
15
|
removeStraySwarmDir,
|
|
16
16
|
runConfigDoctor
|
|
17
|
-
} from "./index-
|
|
17
|
+
} from "./index-jxd67x6z.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-
|
|
29
|
+
} from "./index-amamkcpy.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-
|
|
47
|
+
} from "./index-1fc5aj26.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-
|
|
64
|
+
} from "./index-62akgg9d.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-
|
|
80
|
+
} from "./index-wmazt588.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-
|
|
99
|
+
} from "./index-hvmfa7m8.js";
|
|
100
100
|
import {
|
|
101
101
|
assertNoUnsettledCoderDispatch,
|
|
102
102
|
listCoderSettlementWalStates,
|
|
103
103
|
recoverCoderSettlement,
|
|
104
104
|
recoverStaleCoderSettlements
|
|
105
|
-
} from "./index-
|
|
105
|
+
} from "./index-151bdyf9.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-
|
|
126
|
+
} from "./index-9y6cyc7z.js";
|
|
127
127
|
import {
|
|
128
128
|
buildEscalationBriefing,
|
|
129
129
|
readRecentEscalations
|
|
130
|
-
} from "./index-
|
|
130
|
+
} from "./index-7xt5m1cz.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-
|
|
158
|
+
} from "./index-s68z4a39.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-
|
|
179
|
+
} from "./index-j972ags2.js";
|
|
180
180
|
import {
|
|
181
181
|
WORKTREE_LIFECYCLE_LOCK_FILE,
|
|
182
182
|
recordWorktreeProvisioningOwner,
|
|
183
183
|
removeWorktreeProvisioningOwner
|
|
184
|
-
} from "./index-
|
|
184
|
+
} from "./index-vqz0avr4.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-
|
|
197
|
+
} from "./index-a6h5arqs.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-
|
|
225
|
+
} from "./index-wkv1qdb0.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-
|
|
241
|
+
} from "./index-6ndc8cmn.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-
|
|
272
|
+
} from "./index-fp4hxcsy.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-
|
|
281
|
+
} from "./index-p9m1nhds.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-
|
|
315
|
+
} from "./index-9th8npp7.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-
|
|
334
|
+
} from "./index-w2b8qq6d.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-
|
|
342
|
+
} from "./index-afmyp3kt.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-
|
|
362
|
+
} from "./index-5pa0e0k3.js";
|
|
363
363
|
import {
|
|
364
364
|
MAX_CURATION_PROPOSALS,
|
|
365
365
|
authorizeCuration,
|
|
366
366
|
buildConfigFingerprintInput
|
|
367
|
-
} from "./index-
|
|
367
|
+
} from "./index-8nsjefpc.js";
|
|
368
368
|
import {
|
|
369
369
|
cohortConfigFingerprint
|
|
370
370
|
} from "./index-rtry5xyf.js";
|
|
371
371
|
import {
|
|
372
372
|
resolveWorktreeIsolationConfig
|
|
373
|
-
} from "./index-
|
|
373
|
+
} from "./index-d7mcdyqb.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-
|
|
385
|
+
} from "./index-vk3ngryj.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-
|
|
401
|
+
} from "./index-bajvxmnb.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-
|
|
411
|
+
} from "./index-373880cv.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-
|
|
419
|
+
} from "./index-9g61bfj9.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-
|
|
430
|
+
} from "./index-nen885g8.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-
|
|
439
|
+
} from "./index-74yxwf8y.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-
|
|
459
|
+
} from "./index-xgdypzch.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-
|
|
490
|
+
} from "./index-m94gfe82.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-
|
|
511
|
+
} from "./index-zxck9sr7.js";
|
|
512
512
|
import {
|
|
513
513
|
atomicWriteFile
|
|
514
|
-
} from "./index-
|
|
514
|
+
} from "./index-6sffjy74.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-
|
|
557
|
+
} from "./index-yj7etak0.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-
|
|
571
|
+
} from "./index-a1tpq5zr.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-
|
|
603
|
+
} from "./index-qyjyd3ej.js";
|
|
604
604
|
import {
|
|
605
605
|
AGENT_TOOL_MAP,
|
|
606
606
|
ALL_AGENT_NAMES,
|
|
@@ -770,7 +770,6 @@ init_loader();
|
|
|
770
770
|
// src/hooks/pr-workflow-gate.ts
|
|
771
771
|
init_zod();
|
|
772
772
|
import { createHash as createHash23, randomUUID as randomUUID6 } from "crypto";
|
|
773
|
-
import { readFileSync as readFileSync14, statSync as statSync10 } from "fs";
|
|
774
773
|
import * as fsp5 from "fs/promises";
|
|
775
774
|
import * as path28 from "path";
|
|
776
775
|
|
|
@@ -2586,6 +2585,33 @@ function parsePrReviewTriggerReceipt(input) {
|
|
|
2586
2585
|
return parsedReceipt(schemaVersion === 1 ? 1 : 0, validated.rows);
|
|
2587
2586
|
}
|
|
2588
2587
|
|
|
2588
|
+
// src/background/pr-review-trigger-receipt-reader.ts
|
|
2589
|
+
import { readFileSync as readFileSync2, statSync } from "fs";
|
|
2590
|
+
function readPrReviewTriggerReceiptForGate(directory, triggerEvalPath) {
|
|
2591
|
+
if (!triggerEvalPath)
|
|
2592
|
+
return { noReceipt: true };
|
|
2593
|
+
const triggerPath = validateSwarmPath(directory, triggerEvalPath);
|
|
2594
|
+
let triggerArtifact;
|
|
2595
|
+
try {
|
|
2596
|
+
const triggerStat = statSync(triggerPath);
|
|
2597
|
+
if (!triggerStat.isFile() || triggerStat.size > PR_REVIEW_TRIGGER_RECEIPT_MAX_BYTES) {
|
|
2598
|
+
throw new Error("trigger evaluation artifact exceeds its read bound");
|
|
2599
|
+
}
|
|
2600
|
+
triggerArtifact = JSON.parse(readFileSync2(triggerPath, "utf-8"));
|
|
2601
|
+
} catch {
|
|
2602
|
+
throw new Error("BLOCKED: PR_REVIEW trigger evaluation artifact is missing or invalid");
|
|
2603
|
+
}
|
|
2604
|
+
try {
|
|
2605
|
+
return { receipt: parsePrReviewTriggerReceipt(triggerArtifact) };
|
|
2606
|
+
} catch (error2) {
|
|
2607
|
+
throw new Error(`BLOCKED: PR_REVIEW trigger evaluation is invalid: ${error2 instanceof Error ? error2.message : String(error2)}`);
|
|
2608
|
+
}
|
|
2609
|
+
}
|
|
2610
|
+
function prReviewReceiptHasCoverageDegradations(directory, triggerEvalPath) {
|
|
2611
|
+
const read = readPrReviewTriggerReceiptForGate(directory, triggerEvalPath);
|
|
2612
|
+
return "noReceipt" in read ? false : read.receipt.coverageDegradations.length > 0;
|
|
2613
|
+
}
|
|
2614
|
+
|
|
2589
2615
|
// src/hooks/pr-workflow-gate.ts
|
|
2590
2616
|
init_constants();
|
|
2591
2617
|
init_schema();
|
|
@@ -3363,7 +3389,7 @@ async function importLegacyPrWorkflowGateStateIfNeeded(directory, sessionID, all
|
|
|
3363
3389
|
return null;
|
|
3364
3390
|
throw error2;
|
|
3365
3391
|
}
|
|
3366
|
-
const legacy = allowSalvagedImport ? (await (await import("./pr-workflow-gate-
|
|
3392
|
+
const legacy = allowSalvagedImport ? (await (await import("./pr-workflow-gate-tdj50p2g.js")).readPrWorkflowGateStateForRecovery(directory, sessionID))?.state ?? null : await readPrWorkflowGateStateFileFromDisk(filePath, sessionID);
|
|
3367
3393
|
if (!legacy)
|
|
3368
3394
|
return null;
|
|
3369
3395
|
const namespace = workflowGateStateCoordinationNamespace(sessionID);
|
|
@@ -3450,7 +3476,7 @@ async function deleteStateWhileLocked(directory, sessionID, options = {}) {
|
|
|
3450
3476
|
let recoveryState = null;
|
|
3451
3477
|
if (!currentAuthoritative) {
|
|
3452
3478
|
if (options.allowSalvagedRead) {
|
|
3453
|
-
const { readPrWorkflowGateStateForRecovery } = await import("./pr-workflow-gate-
|
|
3479
|
+
const { readPrWorkflowGateStateForRecovery } = await import("./pr-workflow-gate-tdj50p2g.js");
|
|
3454
3480
|
recoveryState = (await readPrWorkflowGateStateForRecovery(directory, normalizedSessionID))?.state ?? null;
|
|
3455
3481
|
}
|
|
3456
3482
|
if (!recoveryState) {
|
|
@@ -4494,7 +4520,7 @@ function rollbackPrReviewCircuitProbe(circuit, nowMs, openDurationMs) {
|
|
|
4494
4520
|
// src/pr-review/completion.ts
|
|
4495
4521
|
init_zod();
|
|
4496
4522
|
import { createHash as createHash8 } from "crypto";
|
|
4497
|
-
import { readFileSync as
|
|
4523
|
+
import { readFileSync as readFileSync3 } from "fs";
|
|
4498
4524
|
import * as fsp4 from "fs/promises";
|
|
4499
4525
|
import * as path6 from "path";
|
|
4500
4526
|
|
|
@@ -4697,14 +4723,20 @@ var PR_REVIEW_REPORT_VERDICTS = [
|
|
|
4697
4723
|
"REQUEST_CHANGES",
|
|
4698
4724
|
"INCOMPLETE"
|
|
4699
4725
|
];
|
|
4700
|
-
function allowedPrReviewReportVerdicts(kind, findings = []) {
|
|
4726
|
+
function allowedPrReviewReportVerdicts(kind, findings = [], options) {
|
|
4701
4727
|
if (kind === "PARTIAL" && findings.length === 0) {
|
|
4702
4728
|
return ["REQUEST_CHANGES", "INCOMPLETE"];
|
|
4703
4729
|
}
|
|
4730
|
+
const degraded = kind === "COMPLETE" && options?.disclosedCoverageDegradation === true;
|
|
4704
4731
|
const projection = evaluateFinalFindingPolicy({
|
|
4705
4732
|
policyVersion: 1,
|
|
4706
4733
|
finalStatus: "COMPLETE",
|
|
4707
|
-
coverage:
|
|
4734
|
+
coverage: degraded ? {
|
|
4735
|
+
kind: "base",
|
|
4736
|
+
quality: "degraded",
|
|
4737
|
+
disclosed: true,
|
|
4738
|
+
provenance: "valid"
|
|
4739
|
+
} : kind === "COMPLETE" ? { kind: "base", quality: "complete", provenance: "valid" } : kind === "PARTIAL" ? { kind: "base", quality: "partial", provenance: "valid" } : { kind: "base", quality: "none", provenance: "valid" },
|
|
4708
4740
|
findings: [...findings]
|
|
4709
4741
|
});
|
|
4710
4742
|
const supported = projection.permittedVerdicts.filter((value) => (value === "APPROVE" || value === "REQUEST_CHANGES" || value === "INCOMPLETE") && (kind === "COMPLETE" || value !== "APPROVE"));
|
|
@@ -5219,7 +5251,7 @@ async function admitPrReviewPartialBaseCoverage(directory, sessionID, runId, unr
|
|
|
5219
5251
|
} catch {}
|
|
5220
5252
|
};
|
|
5221
5253
|
try {
|
|
5222
|
-
const persisted =
|
|
5254
|
+
const persisted = readFileSync3(absolutePath, "utf8");
|
|
5223
5255
|
if (persisted !== raw) {
|
|
5224
5256
|
throw new Error("BLOCKED: partial base coverage disclosure path already contains different content");
|
|
5225
5257
|
}
|
|
@@ -5323,7 +5355,9 @@ async function readPrReviewTerminalCoverageForReport(directory, sessionID) {
|
|
|
5323
5355
|
failure_class: entry.failureClass
|
|
5324
5356
|
})),
|
|
5325
5357
|
liveDimensions: settlement.liveDimensions,
|
|
5326
|
-
allowedVerdicts: allowedPrReviewReportVerdicts(settlement.kind, []
|
|
5358
|
+
allowedVerdicts: allowedPrReviewReportVerdicts(settlement.kind, [], {
|
|
5359
|
+
disclosedCoverageDegradation: prReviewReceiptHasCoverageDegradations(directory, state.prReviewTriggerEvalPath)
|
|
5360
|
+
})
|
|
5327
5361
|
};
|
|
5328
5362
|
}
|
|
5329
5363
|
|
|
@@ -5892,6 +5926,9 @@ function reducePrReviewEvent(state, event) {
|
|
|
5892
5926
|
if (settlement.kind === "NO_COVERAGE" && verdict !== "INCOMPLETE") {
|
|
5893
5927
|
return rejected(state, "no_coverage_requires_incomplete", `a zero-coverage review must report INCOMPLETE, not ${verdict}`);
|
|
5894
5928
|
}
|
|
5929
|
+
if (settlement.kind === "COMPLETE" && event.disclosedDegradation === true && verdict === "APPROVE") {
|
|
5930
|
+
return rejected(state, "degraded_disclosure_cannot_approve", "a disclosed coverage degradation (dead family) can never emit APPROVE; report REQUEST_CHANGES with the disclosed degradation or INCOMPLETE");
|
|
5931
|
+
}
|
|
5895
5932
|
}
|
|
5896
5933
|
return applied(state);
|
|
5897
5934
|
}
|
|
@@ -15002,7 +15039,7 @@ function isLaneOwnedByCurrentSession(branchName, expectedSessionId) {
|
|
|
15002
15039
|
return extracted === expectedSessionId;
|
|
15003
15040
|
}
|
|
15004
15041
|
async function inspectStandardWorktreeCollisionOwnership(identity) {
|
|
15005
|
-
const collisionOwnership = await import("./worktree-collision-ownership-
|
|
15042
|
+
const collisionOwnership = await import("./worktree-collision-ownership-e2cqcmnw.js");
|
|
15006
15043
|
return collisionOwnership.inspectStandardWorktreeCollisionOwnership(identity);
|
|
15007
15044
|
}
|
|
15008
15045
|
async function runRecoveryGit(directory, args, timeoutMs = 15000) {
|
|
@@ -15428,7 +15465,7 @@ async function precreateStandardWorktreeSession(args) {
|
|
|
15428
15465
|
const laneProfile = computeLaneRuntimeProfile(worktreeConfig.runtime_isolation, laneIndex, handle.worktreePath);
|
|
15429
15466
|
if (laneProfile) {
|
|
15430
15467
|
try {
|
|
15431
|
-
const { writeLaneProfileToDiskReal } = await import("./core-
|
|
15468
|
+
const { writeLaneProfileToDiskReal } = await import("./core-pj2fz34e.js");
|
|
15432
15469
|
await writeLaneProfileToDiskReal(handle.worktreePath, laneProfile.laneIndex, laneProfile.envOverrides);
|
|
15433
15470
|
} catch {}
|
|
15434
15471
|
}
|
|
@@ -16407,7 +16444,7 @@ async function finishStandardWorktreeDispatch(directory, dispatch, config, callI
|
|
|
16407
16444
|
}
|
|
16408
16445
|
clearWorktreeMergeStatus(statusKey);
|
|
16409
16446
|
try {
|
|
16410
|
-
const { removeLaneProfileFromDiskReal } = await import("./core-
|
|
16447
|
+
const { removeLaneProfileFromDiskReal } = await import("./core-pj2fz34e.js");
|
|
16411
16448
|
await removeLaneProfileFromDiskReal(dispatch.handle.worktreePath, dispatch.laneIndex);
|
|
16412
16449
|
} catch {}
|
|
16413
16450
|
const state = serializationStateBySessionID.get(dispatch.parentSessionID);
|
|
@@ -16676,6 +16713,7 @@ function extractCurrentPhase(planContent) {
|
|
|
16676
16713
|
if (!planContent) {
|
|
16677
16714
|
return null;
|
|
16678
16715
|
}
|
|
16716
|
+
planContent = sanitizeContextText(planContent);
|
|
16679
16717
|
const lines = planContent.split(`
|
|
16680
16718
|
`);
|
|
16681
16719
|
for (let i = 0;i < Math.min(20, lines.length); i++) {
|
|
@@ -16687,6 +16725,15 @@ function extractCurrentPhase(planContent) {
|
|
|
16687
16725
|
return `Phase ${phaseNum}: ${description} [IN PROGRESS]`;
|
|
16688
16726
|
}
|
|
16689
16727
|
}
|
|
16728
|
+
for (let i = 0;i < Math.min(20, lines.length); i++) {
|
|
16729
|
+
const line = lines[i].trim();
|
|
16730
|
+
const blockedMatch = line.match(/^## Phase (\d+):?\s*(.*?)\s*\[BLOCKED\]/i);
|
|
16731
|
+
if (blockedMatch) {
|
|
16732
|
+
const phaseNum = blockedMatch[1];
|
|
16733
|
+
const description = blockedMatch[2]?.trim() || "";
|
|
16734
|
+
return `Phase ${phaseNum}: ${description} [BLOCKED]`;
|
|
16735
|
+
}
|
|
16736
|
+
}
|
|
16690
16737
|
for (let i = 0;i < Math.min(3, lines.length); i++) {
|
|
16691
16738
|
const line = lines[i].trim();
|
|
16692
16739
|
const phaseMatch = line.match(/Phase:\s*(\d+)/i);
|
|
@@ -16709,7 +16756,7 @@ function extractCurrentPhaseFromPlan(plan) {
|
|
|
16709
16756
|
blocked: "BLOCKED"
|
|
16710
16757
|
};
|
|
16711
16758
|
const statusText = statusMap[phase.status] || "PENDING";
|
|
16712
|
-
return `Phase ${phase.id}: ${phase.name} [${statusText}]
|
|
16759
|
+
return sanitizeContextText(`Phase ${phase.id}: ${phase.name} [${statusText}]`);
|
|
16713
16760
|
}
|
|
16714
16761
|
|
|
16715
16762
|
// src/hooks/task-result-classifier.ts
|
|
@@ -19047,7 +19094,7 @@ ${text}`;
|
|
|
19047
19094
|
|
|
19048
19095
|
// src/db/observability-event-store.ts
|
|
19049
19096
|
import { createHash as createHash21 } from "crypto";
|
|
19050
|
-
import { existsSync as existsSync11, readFileSync as
|
|
19097
|
+
import { existsSync as existsSync11, readFileSync as readFileSync12, statSync as statSync8 } from "fs";
|
|
19051
19098
|
import { join as join20 } from "path";
|
|
19052
19099
|
var MAX_OBSERVABILITY_EVENT_ROWS = 50000;
|
|
19053
19100
|
var MAX_EVENT_PAYLOAD_BYTES = 16 * 1024;
|
|
@@ -19263,7 +19310,7 @@ function syncObservabilityImport(directory) {
|
|
|
19263
19310
|
const filePath = join20(root, ".swarm", fileName);
|
|
19264
19311
|
let stats;
|
|
19265
19312
|
try {
|
|
19266
|
-
const st =
|
|
19313
|
+
const st = statSync8(filePath);
|
|
19267
19314
|
stats = { size: st.size, mtimeMs: st.mtimeMs };
|
|
19268
19315
|
} catch {
|
|
19269
19316
|
continue;
|
|
@@ -19276,7 +19323,7 @@ function syncObservabilityImport(directory) {
|
|
|
19276
19323
|
result.skippedUnchanged = false;
|
|
19277
19324
|
let content;
|
|
19278
19325
|
try {
|
|
19279
|
-
content =
|
|
19326
|
+
content = readFileSync12(filePath, "utf-8");
|
|
19280
19327
|
} catch {
|
|
19281
19328
|
continue;
|
|
19282
19329
|
}
|
|
@@ -19426,9 +19473,9 @@ var _internals28 = {
|
|
|
19426
19473
|
import {
|
|
19427
19474
|
existsSync as existsSync12,
|
|
19428
19475
|
mkdirSync as mkdirSync6,
|
|
19429
|
-
readFileSync as
|
|
19476
|
+
readFileSync as readFileSync13,
|
|
19430
19477
|
renameSync as renameSync4,
|
|
19431
|
-
statSync as
|
|
19478
|
+
statSync as statSync9,
|
|
19432
19479
|
writeFileSync as writeFileSync6
|
|
19433
19480
|
} from "fs";
|
|
19434
19481
|
import { join as join21 } from "path";
|
|
@@ -19449,7 +19496,7 @@ function statePath(directory) {
|
|
|
19449
19496
|
}
|
|
19450
19497
|
function loadState(directory) {
|
|
19451
19498
|
try {
|
|
19452
|
-
const raw =
|
|
19499
|
+
const raw = readFileSync13(statePath(directory), "utf-8");
|
|
19453
19500
|
const parsed = JSON.parse(raw);
|
|
19454
19501
|
if (parsed.v !== STATE_VERSION)
|
|
19455
19502
|
return null;
|
|
@@ -19460,7 +19507,7 @@ function loadState(directory) {
|
|
|
19460
19507
|
}
|
|
19461
19508
|
function readSpoolLines(directory) {
|
|
19462
19509
|
try {
|
|
19463
|
-
const content =
|
|
19510
|
+
const content = readFileSync13(spoolPath(directory), "utf-8");
|
|
19464
19511
|
return content.split(`
|
|
19465
19512
|
`).filter((l) => l.length > 0);
|
|
19466
19513
|
} catch {
|
|
@@ -19480,7 +19527,7 @@ function readOtlpExporterHealth(directory) {
|
|
|
19480
19527
|
let spoolRecords = 0;
|
|
19481
19528
|
let spoolBytes = 0;
|
|
19482
19529
|
try {
|
|
19483
|
-
const st =
|
|
19530
|
+
const st = statSync9(spoolPath(directory));
|
|
19484
19531
|
spoolBytes = st.size;
|
|
19485
19532
|
spoolRecords = readSpoolLines(directory).length;
|
|
19486
19533
|
} catch {}
|
|
@@ -22436,7 +22483,7 @@ function clearHydrationOwnershipState() {
|
|
|
22436
22483
|
}
|
|
22437
22484
|
|
|
22438
22485
|
// src/session/session-start-store.ts
|
|
22439
|
-
import { existsSync as existsSync14, mkdirSync as mkdirSync8, readFileSync as
|
|
22486
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync8, readFileSync as readFileSync14, writeFileSync as writeFileSync8 } from "fs";
|
|
22440
22487
|
import * as path26 from "path";
|
|
22441
22488
|
var SESSION_START_FILE = "session-start.jsonl";
|
|
22442
22489
|
function recordSessionStart(directory, startMs) {
|
|
@@ -22455,7 +22502,7 @@ function readEarliestSessionStart(directory) {
|
|
|
22455
22502
|
const filePath = path26.join(directory, ".swarm", "session", SESSION_START_FILE);
|
|
22456
22503
|
if (!existsSync14(filePath))
|
|
22457
22504
|
return null;
|
|
22458
|
-
const content =
|
|
22505
|
+
const content = readFileSync14(filePath, "utf-8");
|
|
22459
22506
|
const lines = content.split(`
|
|
22460
22507
|
`);
|
|
22461
22508
|
const validStartMs = [];
|
|
@@ -24036,7 +24083,7 @@ function clearCriticalShownIds(sessionID) {
|
|
|
24036
24083
|
async function rehydratePrSubscriptions(sessionID, directory) {
|
|
24037
24084
|
const map = new Map;
|
|
24038
24085
|
try {
|
|
24039
|
-
const { listActive: listActive2 } = await import("./pr-subscriptions-
|
|
24086
|
+
const { listActive: listActive2 } = await import("./pr-subscriptions-qw4wjv66.js");
|
|
24040
24087
|
const records = await listActive2(directory);
|
|
24041
24088
|
for (const record of records) {
|
|
24042
24089
|
if (record.sessionID !== sessionID)
|
|
@@ -24521,11 +24568,11 @@ async function activatePrWorkflow(directory, sessionID, mode, options = {}) {
|
|
|
24521
24568
|
let existing = await readPrWorkflowGateStateFromDisk3(directory, normalizedSessionID);
|
|
24522
24569
|
if (existing?.mode === mode) {
|
|
24523
24570
|
if (mode === "PR_FEEDBACK" && options.prUrl) {
|
|
24524
|
-
const requestedTarget = canonicalGitHubPrUrl(options.prUrl);
|
|
24571
|
+
const requestedTarget = canonicalGitHubPrUrl(options.prUrl, options.forge);
|
|
24525
24572
|
if (!requestedTarget) {
|
|
24526
24573
|
throw new Error("BLOCKED: PR_FEEDBACK target must be a canonical GitHub PR URL");
|
|
24527
24574
|
}
|
|
24528
|
-
const existingTarget = existing.prFeedbackTargetUrl ? canonicalGitHubPrUrl(existing.prFeedbackTargetUrl) : null;
|
|
24575
|
+
const existingTarget = existing.prFeedbackTargetUrl ? canonicalGitHubPrUrl(existing.prFeedbackTargetUrl, options.forge) : null;
|
|
24529
24576
|
if (existingTarget && requestedTarget !== existingTarget) {
|
|
24530
24577
|
throw new Error(`BLOCKED: active PR_FEEDBACK targets a different GitHub pull request`);
|
|
24531
24578
|
}
|
|
@@ -24559,7 +24606,7 @@ async function activatePrWorkflow(directory, sessionID, mode, options = {}) {
|
|
|
24559
24606
|
const initialHead = options.prHeadSha ? await assertCurrentCheckoutHead(directory, options.prHeadSha, mode) : undefined;
|
|
24560
24607
|
const skillContractAdvisories = await ensurePrWorkflowSkillContractsFresh(directory, mode);
|
|
24561
24608
|
const timestamp = isoNow();
|
|
24562
|
-
const feedbackTargetUrl = mode === "PR_FEEDBACK" && options.prUrl ? canonicalGitHubPrUrl(options.prUrl) ? options.prUrl : null : undefined;
|
|
24609
|
+
const feedbackTargetUrl = mode === "PR_FEEDBACK" && options.prUrl ? canonicalGitHubPrUrl(options.prUrl, options.forge) ? options.prUrl : null : undefined;
|
|
24563
24610
|
if (feedbackTargetUrl === null) {
|
|
24564
24611
|
throw new Error("BLOCKED: PR_FEEDBACK target must be a canonical GitHub PR URL");
|
|
24565
24612
|
}
|
|
@@ -29086,7 +29133,10 @@ async function readPrReviewFinalFindingPolicyForReport(directory, sessionID) {
|
|
|
29086
29133
|
const settlement = derivePrReviewDimensionSettlement(directory, state, ctx.revisionDigest);
|
|
29087
29134
|
const authority = await readAuthoritativeFindingPolicy(directory, state);
|
|
29088
29135
|
const findings = authority.policyFindings;
|
|
29089
|
-
const
|
|
29136
|
+
const disclosedDegradation = prReviewReceiptHasCoverageDegradations(directory, state.prReviewTriggerEvalPath);
|
|
29137
|
+
const permittedVerdicts = allowedPrReviewReportVerdicts(settlement.kind, findings, {
|
|
29138
|
+
disclosedCoverageDegradation: disclosedDegradation
|
|
29139
|
+
});
|
|
29090
29140
|
const policyProjection = evaluateFinalFindingPolicy({
|
|
29091
29141
|
policyVersion: FINDING_POLICY_VERSION,
|
|
29092
29142
|
finalStatus: "COMPLETE",
|
|
@@ -29100,8 +29150,8 @@ async function readPrReviewFinalFindingPolicyForReport(directory, sessionID) {
|
|
|
29100
29150
|
const blockingFindingIds = policyProjection.blockingFindingIds.flatMap((id) => sourceIdsByPolicyFindingId.get(id) ?? [id]).sort();
|
|
29101
29151
|
return { policyVersion: 1, permittedVerdicts, blockingFindingIds };
|
|
29102
29152
|
}
|
|
29103
|
-
function canonicalGitHubPrUrl(value) {
|
|
29104
|
-
return canonicalForgePrUrl(value);
|
|
29153
|
+
function canonicalGitHubPrUrl(value, configured) {
|
|
29154
|
+
return canonicalForgePrUrl(value, configured);
|
|
29105
29155
|
}
|
|
29106
29156
|
function assertMatchingPrReviewFeedbackConsent(record, input) {
|
|
29107
29157
|
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) {
|
|
@@ -29689,6 +29739,7 @@ async function completePrWorkflow(directory, sessionID, expectedMode, prHeadSha,
|
|
|
29689
29739
|
}
|
|
29690
29740
|
const ctx = await createPrReviewGateContext2(directory, state);
|
|
29691
29741
|
const settlement = derivePrReviewDimensionSettlement(directory, state, ctx.revisionDigest);
|
|
29742
|
+
let disclosedDegradation = settlement.kind === "COMPLETE" && prReviewReceiptHasCoverageDegradations(directory, state.prReviewTriggerEvalPath);
|
|
29692
29743
|
const dispatchCoverageFinalization = (finalizationSettlement) => {
|
|
29693
29744
|
const outcome = reducePrReviewEvent(state, {
|
|
29694
29745
|
type: "coverage_finalization_requested",
|
|
@@ -29698,7 +29749,8 @@ async function completePrWorkflow(directory, sessionID, expectedMode, prHeadSha,
|
|
|
29698
29749
|
unresolvedDimensions: finalizationSettlement.unresolvedDimensions,
|
|
29699
29750
|
liveDimensions: finalizationSettlement.liveDimensions
|
|
29700
29751
|
},
|
|
29701
|
-
requestedVerdict: verdict
|
|
29752
|
+
requestedVerdict: verdict,
|
|
29753
|
+
disclosedDegradation
|
|
29702
29754
|
});
|
|
29703
29755
|
if (outcome.status === "applied")
|
|
29704
29756
|
return;
|
|
@@ -29712,7 +29764,10 @@ async function completePrWorkflow(directory, sessionID, expectedMode, prHeadSha,
|
|
|
29712
29764
|
if (code === "no_coverage_requires_incomplete") {
|
|
29713
29765
|
throw new Error(`BLOCKED: PR_REVIEW NO_COVERAGE completion must report verdict INCOMPLETE; got "${verdict}". A zero-coverage report never approves and never claims a code-quality review.`);
|
|
29714
29766
|
}
|
|
29715
|
-
|
|
29767
|
+
if (code === "degraded_disclosure_cannot_approve") {
|
|
29768
|
+
throw new Error(`BLOCKED: PR_REVIEW ${finalizationSettlement.kind} completion discloses a coverage degradation (dead family) and cannot report verdict APPROVE; got "${verdict}". Report REQUEST_CHANGES with the disclosed degradation surfaced in the report, or INCOMPLETE.`);
|
|
29769
|
+
}
|
|
29770
|
+
const allowedList = allowedPrReviewReportVerdicts(finalizationSettlement.kind, [], { disclosedCoverageDegradation: disclosedDegradation }).join(" | ");
|
|
29716
29771
|
throw new Error(`BLOCKED: PR_REVIEW ${finalizationSettlement.kind} completion allows report_verdict ${allowedList}; got "${verdict}". Partial coverage never approves and never claims a full review.`);
|
|
29717
29772
|
};
|
|
29718
29773
|
dispatchCoverageFinalization(settlement);
|
|
@@ -29734,7 +29789,9 @@ async function completePrWorkflow(directory, sessionID, expectedMode, prHeadSha,
|
|
|
29734
29789
|
});
|
|
29735
29790
|
} catch {}
|
|
29736
29791
|
} else {
|
|
29737
|
-
const preAllowed = allowedPrReviewReportVerdicts(settlement.kind, []
|
|
29792
|
+
const preAllowed = allowedPrReviewReportVerdicts(settlement.kind, [], {
|
|
29793
|
+
disclosedCoverageDegradation: disclosedDegradation
|
|
29794
|
+
});
|
|
29738
29795
|
if (!preAllowed.includes(verdict)) {
|
|
29739
29796
|
throw new Error(`BLOCKED: PR_REVIEW ${settlement.kind} completion allows report_verdict ${preAllowed.join(" | ")}; got "${verdict}". Partial coverage never approves and never claims a full review.`);
|
|
29740
29797
|
}
|
|
@@ -29743,9 +29800,12 @@ async function completePrWorkflow(directory, sessionID, expectedMode, prHeadSha,
|
|
|
29743
29800
|
if (workflowIdentity(readyState) !== workflowIdentity(state) || readyState.revision !== state.revision) {
|
|
29744
29801
|
throw new Error("BLOCKED: PR_REVIEW state changed while checking terminal readiness; retry from current state");
|
|
29745
29802
|
}
|
|
29803
|
+
if (ready.settlement.kind === "COMPLETE") {
|
|
29804
|
+
disclosedDegradation = prReviewReceiptHasCoverageDegradations(directory, readyState.prReviewTriggerEvalPath);
|
|
29805
|
+
}
|
|
29746
29806
|
dispatchCoverageFinalization(ready.settlement);
|
|
29747
29807
|
const finalFindingAuthority = await readAuthoritativeFindingPolicy(directory, readyState);
|
|
29748
|
-
const policyAllowed = allowedPrReviewReportVerdicts(ready.settlement.kind, finalFindingAuthority.policyFindings);
|
|
29808
|
+
const policyAllowed = allowedPrReviewReportVerdicts(ready.settlement.kind, finalFindingAuthority.policyFindings, { disclosedCoverageDegradation: disclosedDegradation });
|
|
29749
29809
|
if (!policyAllowed.includes(verdict)) {
|
|
29750
29810
|
throw new Error(`BLOCKED: PR_REVIEW ${ready.settlement.kind} completion allows report_verdict ${policyAllowed.join(" | ")}; got "${verdict}". Final finding policy and coverage do not permit this report.`);
|
|
29751
29811
|
}
|
|
@@ -30840,23 +30900,11 @@ function derivePrReviewCandidateInventory2(directory, state, ctx) {
|
|
|
30840
30900
|
}
|
|
30841
30901
|
const degradedSourceKeys = new Set;
|
|
30842
30902
|
if (state.prReviewTriggerEvalPath) {
|
|
30843
|
-
const
|
|
30844
|
-
|
|
30845
|
-
|
|
30846
|
-
const triggerStat = statSync10(triggerPath);
|
|
30847
|
-
if (!triggerStat.isFile() || triggerStat.size > PR_REVIEW_TRIGGER_RECEIPT_MAX_BYTES) {
|
|
30848
|
-
throw new Error("trigger evaluation artifact exceeds its read bound");
|
|
30849
|
-
}
|
|
30850
|
-
triggerArtifact = JSON.parse(readFileSync14(triggerPath, "utf-8"));
|
|
30851
|
-
} catch {
|
|
30903
|
+
const receiptRead = readPrReviewTriggerReceiptForGate(directory, state.prReviewTriggerEvalPath);
|
|
30904
|
+
const receipt = "noReceipt" in receiptRead ? null : receiptRead.receipt;
|
|
30905
|
+
if (!receipt) {
|
|
30852
30906
|
throw new Error("BLOCKED: PR_REVIEW trigger evaluation artifact is missing or invalid");
|
|
30853
30907
|
}
|
|
30854
|
-
let receipt;
|
|
30855
|
-
try {
|
|
30856
|
-
receipt = parsePrReviewTriggerReceipt(triggerArtifact);
|
|
30857
|
-
} catch (error2) {
|
|
30858
|
-
throw new Error(`BLOCKED: PR_REVIEW trigger evaluation is invalid: ${error2 instanceof Error ? error2.message : String(error2)}`);
|
|
30859
|
-
}
|
|
30860
30908
|
for (const row of receipt.matchedRows) {
|
|
30861
30909
|
sources.push({
|
|
30862
30910
|
batchId: row.source_batch_id,
|
|
@@ -32175,6 +32223,128 @@ async function readPrWorkflowGateStateForRecovery(directory, sessionID) {
|
|
|
32175
32223
|
// src/commands/registry.ts
|
|
32176
32224
|
init_logger();
|
|
32177
32225
|
|
|
32226
|
+
// src/commands/_shared/url-security.ts
|
|
32227
|
+
import * as child_process from "child_process";
|
|
32228
|
+
init_git_executable();
|
|
32229
|
+
var MAX_URL_LEN = 2048;
|
|
32230
|
+
var _internals32 = {
|
|
32231
|
+
spawnSync: (cmd, args, options) => {
|
|
32232
|
+
const mergedEnv = mergeEnvForChild(options?.env, options?.envOverrides);
|
|
32233
|
+
return child_process.spawnSync(cmd, args, {
|
|
32234
|
+
...options,
|
|
32235
|
+
env: mergedEnv
|
|
32236
|
+
});
|
|
32237
|
+
}
|
|
32238
|
+
};
|
|
32239
|
+
function sanitizeUrl(raw) {
|
|
32240
|
+
let urlStr = raw.trim();
|
|
32241
|
+
urlStr = urlStr.replace(/^([A-Za-z][A-Za-z0-9+.-]*:\/\/)\/?[^@/]+@/, "$1");
|
|
32242
|
+
urlStr = urlStr.replace(/\[\s*MODE\s*:[^\]]*\]/gi, "");
|
|
32243
|
+
urlStr = urlStr.replace(/^([A-Za-z][A-Za-z0-9+.-]*:\/\/)\/?[^@/]+@/, "$1");
|
|
32244
|
+
const fragmentIdx = urlStr.indexOf("#");
|
|
32245
|
+
if (fragmentIdx !== -1) {
|
|
32246
|
+
urlStr = urlStr.slice(0, fragmentIdx);
|
|
32247
|
+
}
|
|
32248
|
+
const queryIdx = urlStr.indexOf("?");
|
|
32249
|
+
if (queryIdx !== -1) {
|
|
32250
|
+
urlStr = urlStr.slice(0, queryIdx);
|
|
32251
|
+
}
|
|
32252
|
+
if (urlStr.length > MAX_URL_LEN) {
|
|
32253
|
+
urlStr = urlStr.slice(0, MAX_URL_LEN);
|
|
32254
|
+
}
|
|
32255
|
+
return urlStr.trim();
|
|
32256
|
+
}
|
|
32257
|
+
function sanitizeErrorEcho(raw, maxLength = 80) {
|
|
32258
|
+
let stripped = "";
|
|
32259
|
+
for (const ch of raw) {
|
|
32260
|
+
const cp = ch.codePointAt(0);
|
|
32261
|
+
if (cp !== undefined && (cp <= 31 || cp === 127)) {
|
|
32262
|
+
stripped += " ";
|
|
32263
|
+
continue;
|
|
32264
|
+
}
|
|
32265
|
+
stripped += ch;
|
|
32266
|
+
}
|
|
32267
|
+
const collapsed = stripped.replace(/\s+/g, " ").trim();
|
|
32268
|
+
if (collapsed.length <= maxLength)
|
|
32269
|
+
return collapsed;
|
|
32270
|
+
return `${collapsed.slice(0, maxLength)}\u2026`;
|
|
32271
|
+
}
|
|
32272
|
+
function validateAndSanitizeGithubUrl(rawUrl, resource, configured) {
|
|
32273
|
+
const sanitized = sanitizeUrl(rawUrl);
|
|
32274
|
+
if (!sanitized) {
|
|
32275
|
+
return { error: "Empty URL" };
|
|
32276
|
+
}
|
|
32277
|
+
if (!sanitized.startsWith("https://")) {
|
|
32278
|
+
return { error: "URL must use HTTPS scheme" };
|
|
32279
|
+
}
|
|
32280
|
+
try {
|
|
32281
|
+
const url = new URL(sanitized);
|
|
32282
|
+
if (hasNonAsciiHostname(url.hostname)) {
|
|
32283
|
+
return { error: "Non-ASCII hostnames are not allowed" };
|
|
32284
|
+
}
|
|
32285
|
+
if (isPrivateHost(url)) {
|
|
32286
|
+
return { error: "Private or localhost URLs are not allowed" };
|
|
32287
|
+
}
|
|
32288
|
+
const matched = matchForgeResourceUrl(sanitized, resource, configured);
|
|
32289
|
+
if (!matched) {
|
|
32290
|
+
return {
|
|
32291
|
+
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)"
|
|
32292
|
+
};
|
|
32293
|
+
}
|
|
32294
|
+
return { sanitized };
|
|
32295
|
+
} catch {
|
|
32296
|
+
return { error: "Invalid URL format" };
|
|
32297
|
+
}
|
|
32298
|
+
}
|
|
32299
|
+
function detectGitRemote(cwd, laneEnv) {
|
|
32300
|
+
try {
|
|
32301
|
+
const result = _internals32.spawnSync(resolveGitExecutable(), ["remote", "get-url", "origin"], {
|
|
32302
|
+
encoding: "utf-8",
|
|
32303
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
32304
|
+
timeout: 5000,
|
|
32305
|
+
...cwd ? { cwd } : {},
|
|
32306
|
+
envOverrides: laneEnv
|
|
32307
|
+
});
|
|
32308
|
+
if (result.status !== 0 || result.error) {
|
|
32309
|
+
return null;
|
|
32310
|
+
}
|
|
32311
|
+
const remoteUrl = (result.stdout ?? "").trim();
|
|
32312
|
+
return remoteUrl || null;
|
|
32313
|
+
} catch {
|
|
32314
|
+
return null;
|
|
32315
|
+
}
|
|
32316
|
+
}
|
|
32317
|
+
function parseGitRemoteUrl(remoteUrl) {
|
|
32318
|
+
const httpsMatch = remoteUrl.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?\/?$/i);
|
|
32319
|
+
if (httpsMatch) {
|
|
32320
|
+
const owner = httpsMatch[1];
|
|
32321
|
+
const repo = httpsMatch[2].replace(/\.git$/, "");
|
|
32322
|
+
if (containsControlCharacters(owner) || containsControlCharacters(repo)) {
|
|
32323
|
+
return null;
|
|
32324
|
+
}
|
|
32325
|
+
return { owner, repo };
|
|
32326
|
+
}
|
|
32327
|
+
const sshMatch = remoteUrl.match(/^git@github\.com:([^/]+)\/([^/]+?)(?:\.git)?$/i);
|
|
32328
|
+
if (sshMatch) {
|
|
32329
|
+
const owner = sshMatch[1];
|
|
32330
|
+
const repo = sshMatch[2].replace(/\.git$/, "");
|
|
32331
|
+
if (containsControlCharacters(owner) || containsControlCharacters(repo)) {
|
|
32332
|
+
return null;
|
|
32333
|
+
}
|
|
32334
|
+
return { owner, repo };
|
|
32335
|
+
}
|
|
32336
|
+
const pathMatch = remoteUrl.match(/\/([^/]+)\/([^/]+?)(?:\.git)?\/?$/);
|
|
32337
|
+
if (pathMatch) {
|
|
32338
|
+
const owner = pathMatch[1];
|
|
32339
|
+
const repo = pathMatch[2].replace(/\.git$/, "");
|
|
32340
|
+
if (containsControlCharacters(owner) || containsControlCharacters(repo)) {
|
|
32341
|
+
return null;
|
|
32342
|
+
}
|
|
32343
|
+
return { owner, repo };
|
|
32344
|
+
}
|
|
32345
|
+
return null;
|
|
32346
|
+
}
|
|
32347
|
+
|
|
32178
32348
|
// src/commands/abort-pr-workflow.ts
|
|
32179
32349
|
var USAGE2 = [
|
|
32180
32350
|
"Usage: /swarm abort-pr-workflow [PR_REVIEW|PR_FEEDBACK] [reason...]",
|
|
@@ -32279,7 +32449,7 @@ import { createHash as createHash24 } from "crypto";
|
|
|
32279
32449
|
import { mkdir as mkdir6, readFile as readFile10, unlink as unlink2 } from "fs/promises";
|
|
32280
32450
|
import { dirname as dirname15 } from "path";
|
|
32281
32451
|
var SPEC_DRIFT_RECOVERY_AGENT = "spec-drift-recovery";
|
|
32282
|
-
var
|
|
32452
|
+
var _internals33 = {
|
|
32283
32453
|
appendEvent,
|
|
32284
32454
|
assertProjectRoot,
|
|
32285
32455
|
bunWrite,
|
|
@@ -32364,21 +32534,21 @@ async function writeWal3(walPath, wal) {
|
|
|
32364
32534
|
}
|
|
32365
32535
|
async function verifySnapshot(snapshotPath, currentSpec) {
|
|
32366
32536
|
if (!currentSpec) {
|
|
32367
|
-
await
|
|
32368
|
-
const stillExists = await
|
|
32537
|
+
await _internals33.unlinkIfExists(snapshotPath);
|
|
32538
|
+
const stillExists = await _internals33.readFileText(snapshotPath) !== null;
|
|
32369
32539
|
if (stillExists) {
|
|
32370
32540
|
throw new Error("spec snapshot verification failed: snapshot still exists after delete");
|
|
32371
32541
|
}
|
|
32372
32542
|
return;
|
|
32373
32543
|
}
|
|
32374
32544
|
await atomicWriteFile(snapshotPath, currentSpec.content);
|
|
32375
|
-
const written = await
|
|
32545
|
+
const written = await _internals33.readFileText(snapshotPath);
|
|
32376
32546
|
if (written !== currentSpec.content) {
|
|
32377
32547
|
throw new Error("spec snapshot verification failed: snapshot content does not match effective spec");
|
|
32378
32548
|
}
|
|
32379
32549
|
}
|
|
32380
32550
|
async function ensureSnapshotEvent(directory, plan, transitionId) {
|
|
32381
|
-
const events = await
|
|
32551
|
+
const events = await _internals33.readLedgerEvents(directory);
|
|
32382
32552
|
for (const event of events) {
|
|
32383
32553
|
const payload = event.payload;
|
|
32384
32554
|
const approval = payload?.approval;
|
|
@@ -32386,17 +32556,17 @@ async function ensureSnapshotEvent(directory, plan, transitionId) {
|
|
|
32386
32556
|
return;
|
|
32387
32557
|
}
|
|
32388
32558
|
}
|
|
32389
|
-
await
|
|
32559
|
+
await _internals33.takeSnapshotEvent(directory, plan, {
|
|
32390
32560
|
source: "spec_drift_recovery",
|
|
32391
32561
|
approvalMetadata: { specDriftTransitionId: transitionId }
|
|
32392
32562
|
});
|
|
32393
32563
|
}
|
|
32394
32564
|
async function appendEvent(directory, event) {
|
|
32395
|
-
const existing = await
|
|
32565
|
+
const existing = await _internals33.verifyEventPresence(directory, event.type, event.transitionId);
|
|
32396
32566
|
if (existing)
|
|
32397
32567
|
return;
|
|
32398
32568
|
appendCoreEventSync(directory, { ...event }, { dedupeOnAuthorityKey: true });
|
|
32399
|
-
const verified = await
|
|
32569
|
+
const verified = await _internals33.verifyEventPresence(directory, event.type, event.transitionId);
|
|
32400
32570
|
if (!verified) {
|
|
32401
32571
|
throw new Error(`spec drift audit verification failed for transition ${event.transitionId}`);
|
|
32402
32572
|
}
|
|
@@ -32418,7 +32588,7 @@ function buildRecoveryEvent(args) {
|
|
|
32418
32588
|
if (args.mode === "acknowledge") {
|
|
32419
32589
|
return {
|
|
32420
32590
|
type: "spec_drift_acknowledged",
|
|
32421
|
-
timestamp:
|
|
32591
|
+
timestamp: _internals33.now(),
|
|
32422
32592
|
phase: args.phase,
|
|
32423
32593
|
planTitle: args.planTitle,
|
|
32424
32594
|
acknowledgedBy: args.actor === "spec_write" ? "unknown" : args.actor,
|
|
@@ -32430,7 +32600,7 @@ function buildRecoveryEvent(args) {
|
|
|
32430
32600
|
}
|
|
32431
32601
|
return {
|
|
32432
32602
|
type: "spec_drift_repaired",
|
|
32433
|
-
timestamp:
|
|
32603
|
+
timestamp: _internals33.now(),
|
|
32434
32604
|
phase: args.phase,
|
|
32435
32605
|
planTitle: args.planTitle,
|
|
32436
32606
|
repairedBy: args.actor,
|
|
@@ -32441,11 +32611,11 @@ function buildRecoveryEvent(args) {
|
|
|
32441
32611
|
};
|
|
32442
32612
|
}
|
|
32443
32613
|
async function reconcileSpecDrift(directory, options) {
|
|
32444
|
-
|
|
32445
|
-
const markerPath =
|
|
32446
|
-
const walPath =
|
|
32447
|
-
const snapshotPath =
|
|
32448
|
-
const markerMaybe = await
|
|
32614
|
+
_internals33.assertProjectRoot(directory);
|
|
32615
|
+
const markerPath = _internals33.validateSwarmPath(directory, "spec-staleness.json");
|
|
32616
|
+
const walPath = _internals33.validateSwarmPath(directory, "spec-drift-recovery.json");
|
|
32617
|
+
const snapshotPath = _internals33.validateSwarmPath(directory, "spec-snapshot.md");
|
|
32618
|
+
const markerMaybe = await _internals33.readFileText(markerPath);
|
|
32449
32619
|
if (markerMaybe === null) {
|
|
32450
32620
|
return {
|
|
32451
32621
|
status: "no_marker",
|
|
@@ -32453,7 +32623,7 @@ async function reconcileSpecDrift(directory, options) {
|
|
|
32453
32623
|
message: "No spec drift detected."
|
|
32454
32624
|
};
|
|
32455
32625
|
}
|
|
32456
|
-
const specLockResult = options.specLockAlreadyHeld ? null : await
|
|
32626
|
+
const specLockResult = options.specLockAlreadyHeld ? null : await _internals33.tryAcquireLock(directory, "spec.md", SPEC_DRIFT_RECOVERY_AGENT, `spec-${options.mode}-${Date.now()}`);
|
|
32457
32627
|
if (specLockResult && !specLockResult.acquired) {
|
|
32458
32628
|
return {
|
|
32459
32629
|
status: "retry_later",
|
|
@@ -32463,7 +32633,7 @@ async function reconcileSpecDrift(directory, options) {
|
|
|
32463
32633
|
}
|
|
32464
32634
|
let lockResult;
|
|
32465
32635
|
try {
|
|
32466
|
-
lockResult = await
|
|
32636
|
+
lockResult = await _internals33.tryAcquireLock(directory, "plan.json", SPEC_DRIFT_RECOVERY_AGENT, `${options.mode}-${Date.now()}`);
|
|
32467
32637
|
} catch (error2) {
|
|
32468
32638
|
if (specLockResult?.acquired && specLockResult.lock._release) {
|
|
32469
32639
|
await specLockResult.lock._release().catch(() => {});
|
|
@@ -32489,7 +32659,7 @@ async function reconcileSpecDrift(directory, options) {
|
|
|
32489
32659
|
let errorNewHash;
|
|
32490
32660
|
try {
|
|
32491
32661
|
try {
|
|
32492
|
-
const authoritativeMarkerRaw = await
|
|
32662
|
+
const authoritativeMarkerRaw = await _internals33.readFileText(markerPath);
|
|
32493
32663
|
if (authoritativeMarkerRaw === null) {
|
|
32494
32664
|
return {
|
|
32495
32665
|
status: "no_marker",
|
|
@@ -32497,14 +32667,14 @@ async function reconcileSpecDrift(directory, options) {
|
|
|
32497
32667
|
message: "No spec drift detected."
|
|
32498
32668
|
};
|
|
32499
32669
|
}
|
|
32500
|
-
const marker =
|
|
32670
|
+
const marker = _internals33.parseMarker(authoritativeMarkerRaw);
|
|
32501
32671
|
if (!marker) {
|
|
32502
32672
|
return buildCorruptMarkerResult(options.mode);
|
|
32503
32673
|
}
|
|
32504
32674
|
errorMarker = marker;
|
|
32505
32675
|
const markerHash = sha2563(authoritativeMarkerRaw);
|
|
32506
|
-
const existingWalRaw = await
|
|
32507
|
-
const existingWal = existingWalRaw === null ? null :
|
|
32676
|
+
const existingWalRaw = await _internals33.readFileText(walPath);
|
|
32677
|
+
const existingWal = existingWalRaw === null ? null : _internals33.parseWal(existingWalRaw);
|
|
32508
32678
|
if (existingWalRaw !== null && !existingWal) {
|
|
32509
32679
|
return {
|
|
32510
32680
|
status: "failed",
|
|
@@ -32514,7 +32684,7 @@ async function reconcileSpecDrift(directory, options) {
|
|
|
32514
32684
|
planTitle: marker.planTitle
|
|
32515
32685
|
};
|
|
32516
32686
|
}
|
|
32517
|
-
const currentSpec =
|
|
32687
|
+
const currentSpec = _internals33.readEffectiveSpecSync(directory);
|
|
32518
32688
|
const proposedNewHash = currentSpec?.hash ?? null;
|
|
32519
32689
|
const proposedTransitionId = buildTransitionId(options.mode, markerHash, marker.specHash_plan, proposedNewHash);
|
|
32520
32690
|
const proposedWal = {
|
|
@@ -32529,7 +32699,7 @@ async function reconcileSpecDrift(directory, options) {
|
|
|
32529
32699
|
newHash: proposedNewHash,
|
|
32530
32700
|
specContent: currentSpec?.content ?? null,
|
|
32531
32701
|
actor: options.actor,
|
|
32532
|
-
recordedAt:
|
|
32702
|
+
recordedAt: _internals33.now()
|
|
32533
32703
|
};
|
|
32534
32704
|
const markerReplacedDuringPrepared = existingWal?.state === "PREPARED" && existingWal.markerHash !== markerHash;
|
|
32535
32705
|
const wal = existingWal?.state === "PREPARED" || existingWal?.markerHash === markerHash ? existingWal : proposedWal;
|
|
@@ -32538,12 +32708,12 @@ async function reconcileSpecDrift(directory, options) {
|
|
|
32538
32708
|
errorTransitionId = transitionId;
|
|
32539
32709
|
errorNewHash = newHash;
|
|
32540
32710
|
if (wal === proposedWal) {
|
|
32541
|
-
await
|
|
32711
|
+
await _internals33.writeWal(walPath, wal);
|
|
32542
32712
|
}
|
|
32543
32713
|
if (wal.newHash === null !== (wal.specContent === null) || wal.specContent !== null && sha2563(wal.specContent) !== wal.newHash) {
|
|
32544
32714
|
throw new Error(`Spec drift recovery WAL ${transitionId} has inconsistent captured spec content`);
|
|
32545
32715
|
}
|
|
32546
|
-
let plan = await
|
|
32716
|
+
let plan = await _internals33.loadPlanJsonOnly(directory);
|
|
32547
32717
|
if (!plan) {
|
|
32548
32718
|
return {
|
|
32549
32719
|
status: "failed",
|
|
@@ -32574,13 +32744,13 @@ async function reconcileSpecDrift(directory, options) {
|
|
|
32574
32744
|
}
|
|
32575
32745
|
if (planMatchesOld) {
|
|
32576
32746
|
plan.specHash = newHash ?? undefined;
|
|
32577
|
-
await
|
|
32747
|
+
await _internals33.savePlan(directory, plan, {
|
|
32578
32748
|
planLockAlreadyHeld: true
|
|
32579
32749
|
});
|
|
32580
|
-
plan = await
|
|
32750
|
+
plan = await _internals33.loadPlanJsonOnly(directory) ?? plan;
|
|
32581
32751
|
}
|
|
32582
|
-
await
|
|
32583
|
-
await
|
|
32752
|
+
await _internals33.ensureSnapshotEvent(directory, plan, transitionId);
|
|
32753
|
+
await _internals33.verifySnapshot(snapshotPath, wal.specContent === null ? null : { content: wal.specContent });
|
|
32584
32754
|
const event = buildRecoveryEvent({
|
|
32585
32755
|
mode: wal.mode,
|
|
32586
32756
|
actor: wal.actor,
|
|
@@ -32591,15 +32761,15 @@ async function reconcileSpecDrift(directory, options) {
|
|
|
32591
32761
|
previousHash: wal.previousHash,
|
|
32592
32762
|
transitionId
|
|
32593
32763
|
});
|
|
32594
|
-
await
|
|
32595
|
-
await
|
|
32764
|
+
await _internals33.appendEvent(directory, event);
|
|
32765
|
+
await _internals33.writeWal(walPath, { ...wal, state: "COMMITTED" });
|
|
32596
32766
|
}
|
|
32597
32767
|
if (markerReplacedDuringPrepared) {
|
|
32598
32768
|
const preservedMarker = {
|
|
32599
32769
|
...marker,
|
|
32600
32770
|
specHash_plan: newHash,
|
|
32601
32771
|
reason: `prior prepared drift recovery committed before this marker: ${marker.reason}`,
|
|
32602
|
-
timestamp:
|
|
32772
|
+
timestamp: _internals33.now()
|
|
32603
32773
|
};
|
|
32604
32774
|
await atomicWriteFile(markerPath, `${JSON.stringify(preservedMarker, null, 2)}
|
|
32605
32775
|
`);
|
|
@@ -32614,7 +32784,7 @@ async function reconcileSpecDrift(directory, options) {
|
|
|
32614
32784
|
transitionId
|
|
32615
32785
|
};
|
|
32616
32786
|
}
|
|
32617
|
-
const latestSpec =
|
|
32787
|
+
const latestSpec = _internals33.readEffectiveSpecSync(directory);
|
|
32618
32788
|
if ((latestSpec?.hash ?? null) !== newHash) {
|
|
32619
32789
|
const refreshedMarker = {
|
|
32620
32790
|
planTitle: wal.planTitle,
|
|
@@ -32622,7 +32792,7 @@ async function reconcileSpecDrift(directory, options) {
|
|
|
32622
32792
|
specHash_plan: newHash,
|
|
32623
32793
|
specHash_current: latestSpec?.hash ?? null,
|
|
32624
32794
|
reason: "spec changed while drift recovery was committing",
|
|
32625
|
-
timestamp:
|
|
32795
|
+
timestamp: _internals33.now()
|
|
32626
32796
|
};
|
|
32627
32797
|
await atomicWriteFile(markerPath, `${JSON.stringify(refreshedMarker, null, 2)}
|
|
32628
32798
|
`);
|
|
@@ -32638,8 +32808,8 @@ async function reconcileSpecDrift(directory, options) {
|
|
|
32638
32808
|
};
|
|
32639
32809
|
}
|
|
32640
32810
|
try {
|
|
32641
|
-
await
|
|
32642
|
-
|
|
32811
|
+
await _internals33.unlinkIfExists(markerPath);
|
|
32812
|
+
_internals33.invalidateCachedArtifact(markerPath);
|
|
32643
32813
|
} catch (error2) {
|
|
32644
32814
|
return {
|
|
32645
32815
|
status: "cleanup_pending",
|
|
@@ -33136,7 +33306,7 @@ ${USAGE4}`;
|
|
|
33136
33306
|
|
|
33137
33307
|
// src/commands/archive.ts
|
|
33138
33308
|
init_loader();
|
|
33139
|
-
var
|
|
33309
|
+
var _internals34 = {
|
|
33140
33310
|
now: () => new Date
|
|
33141
33311
|
};
|
|
33142
33312
|
function artifactLabel(artifact) {
|
|
@@ -33192,7 +33362,7 @@ async function handleArchiveCommand(directory, args) {
|
|
|
33192
33362
|
const report = await archiveEvidence(directory, maxAgeDays, maxBundles, {
|
|
33193
33363
|
report: true,
|
|
33194
33364
|
dryRun,
|
|
33195
|
-
now:
|
|
33365
|
+
now: _internals34.now(),
|
|
33196
33366
|
cacheMaxBytes,
|
|
33197
33367
|
cacheMaxRecords
|
|
33198
33368
|
});
|
|
@@ -35159,7 +35329,7 @@ function createShadowCopy(directory, maxBytes = MAX_SHADOW_COPY_BYTES) {
|
|
|
35159
35329
|
const rel = path33.relative(directory, src);
|
|
35160
35330
|
const dest = path33.join(shadowRoot, rel);
|
|
35161
35331
|
fs21.mkdirSync(path33.dirname(dest), { recursive: true });
|
|
35162
|
-
const copied =
|
|
35332
|
+
const copied = _internals35.copyFileBounded(src, dest, maxBytes - copiedBytes);
|
|
35163
35333
|
if (copied === null) {
|
|
35164
35334
|
removeShadowRoot(shadowRoot);
|
|
35165
35335
|
return null;
|
|
@@ -35172,7 +35342,7 @@ function createShadowCopy(directory, maxBytes = MAX_SHADOW_COPY_BYTES) {
|
|
|
35172
35342
|
throw error2;
|
|
35173
35343
|
}
|
|
35174
35344
|
}
|
|
35175
|
-
var
|
|
35345
|
+
var _internals35 = {
|
|
35176
35346
|
computeEvidenceQualitySummary,
|
|
35177
35347
|
copyFileBounded,
|
|
35178
35348
|
createShadowCopy
|
|
@@ -35419,7 +35589,7 @@ async function evaluateAdvisoryCi(options) {
|
|
|
35419
35589
|
});
|
|
35420
35590
|
}
|
|
35421
35591
|
}
|
|
35422
|
-
const summary = await
|
|
35592
|
+
const summary = await _internals35.computeEvidenceQualitySummary(directory);
|
|
35423
35593
|
const q = summary.qualityMetrics;
|
|
35424
35594
|
const qualityRows = [
|
|
35425
35595
|
[
|
|
@@ -35813,7 +35983,7 @@ async function handleCiCommand(ctx) {
|
|
|
35813
35983
|
const signals = createSignalCancellation(controller);
|
|
35814
35984
|
signals.install();
|
|
35815
35985
|
try {
|
|
35816
|
-
const result = await
|
|
35986
|
+
const result = await _internals36.runAdvisoryCiRuntime({
|
|
35817
35987
|
directory: ctx.directory,
|
|
35818
35988
|
deadlineMs,
|
|
35819
35989
|
signal: controller.signal,
|
|
@@ -35862,134 +36032,10 @@ async function handleCiCommand(ctx) {
|
|
|
35862
36032
|
signals.dispose();
|
|
35863
36033
|
}
|
|
35864
36034
|
}
|
|
35865
|
-
var
|
|
36035
|
+
var _internals36 = { runAdvisoryCiRuntime };
|
|
35866
36036
|
|
|
35867
36037
|
// src/commands/pr-ref.ts
|
|
35868
36038
|
init_loader();
|
|
35869
|
-
|
|
35870
|
-
// src/commands/_shared/url-security.ts
|
|
35871
|
-
import * as child_process from "child_process";
|
|
35872
|
-
init_git_executable();
|
|
35873
|
-
var MAX_URL_LEN = 2048;
|
|
35874
|
-
var _internals36 = {
|
|
35875
|
-
spawnSync: (cmd, args, options) => {
|
|
35876
|
-
const mergedEnv = mergeEnvForChild(options?.env, options?.envOverrides);
|
|
35877
|
-
return child_process.spawnSync(cmd, args, {
|
|
35878
|
-
...options,
|
|
35879
|
-
env: mergedEnv
|
|
35880
|
-
});
|
|
35881
|
-
}
|
|
35882
|
-
};
|
|
35883
|
-
function sanitizeUrl(raw) {
|
|
35884
|
-
let urlStr = raw.trim();
|
|
35885
|
-
urlStr = urlStr.replace(/^([A-Za-z][A-Za-z0-9+.-]*:\/\/)\/?[^@/]+@/, "$1");
|
|
35886
|
-
urlStr = urlStr.replace(/\[\s*MODE\s*:[^\]]*\]/gi, "");
|
|
35887
|
-
urlStr = urlStr.replace(/^([A-Za-z][A-Za-z0-9+.-]*:\/\/)\/?[^@/]+@/, "$1");
|
|
35888
|
-
const fragmentIdx = urlStr.indexOf("#");
|
|
35889
|
-
if (fragmentIdx !== -1) {
|
|
35890
|
-
urlStr = urlStr.slice(0, fragmentIdx);
|
|
35891
|
-
}
|
|
35892
|
-
const queryIdx = urlStr.indexOf("?");
|
|
35893
|
-
if (queryIdx !== -1) {
|
|
35894
|
-
urlStr = urlStr.slice(0, queryIdx);
|
|
35895
|
-
}
|
|
35896
|
-
if (urlStr.length > MAX_URL_LEN) {
|
|
35897
|
-
urlStr = urlStr.slice(0, MAX_URL_LEN);
|
|
35898
|
-
}
|
|
35899
|
-
return urlStr.trim();
|
|
35900
|
-
}
|
|
35901
|
-
function sanitizeErrorEcho(raw, maxLength = 80) {
|
|
35902
|
-
let stripped = "";
|
|
35903
|
-
for (const ch of raw) {
|
|
35904
|
-
const cp = ch.codePointAt(0);
|
|
35905
|
-
if (cp !== undefined && (cp <= 31 || cp === 127)) {
|
|
35906
|
-
stripped += " ";
|
|
35907
|
-
continue;
|
|
35908
|
-
}
|
|
35909
|
-
stripped += ch;
|
|
35910
|
-
}
|
|
35911
|
-
const collapsed = stripped.replace(/\s+/g, " ").trim();
|
|
35912
|
-
if (collapsed.length <= maxLength)
|
|
35913
|
-
return collapsed;
|
|
35914
|
-
return `${collapsed.slice(0, maxLength)}\u2026`;
|
|
35915
|
-
}
|
|
35916
|
-
function validateAndSanitizeGithubUrl(rawUrl, resource, configured) {
|
|
35917
|
-
const sanitized = sanitizeUrl(rawUrl);
|
|
35918
|
-
if (!sanitized) {
|
|
35919
|
-
return { error: "Empty URL" };
|
|
35920
|
-
}
|
|
35921
|
-
if (!sanitized.startsWith("https://")) {
|
|
35922
|
-
return { error: "URL must use HTTPS scheme" };
|
|
35923
|
-
}
|
|
35924
|
-
try {
|
|
35925
|
-
const url = new URL(sanitized);
|
|
35926
|
-
if (hasNonAsciiHostname(url.hostname)) {
|
|
35927
|
-
return { error: "Non-ASCII hostnames are not allowed" };
|
|
35928
|
-
}
|
|
35929
|
-
if (isPrivateHost(url)) {
|
|
35930
|
-
return { error: "Private or localhost URLs are not allowed" };
|
|
35931
|
-
}
|
|
35932
|
-
const matched = matchForgeResourceUrl(sanitized, resource, configured);
|
|
35933
|
-
if (!matched) {
|
|
35934
|
-
return {
|
|
35935
|
-
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)"
|
|
35936
|
-
};
|
|
35937
|
-
}
|
|
35938
|
-
return { sanitized };
|
|
35939
|
-
} catch {
|
|
35940
|
-
return { error: "Invalid URL format" };
|
|
35941
|
-
}
|
|
35942
|
-
}
|
|
35943
|
-
function detectGitRemote(cwd, laneEnv) {
|
|
35944
|
-
try {
|
|
35945
|
-
const result = _internals36.spawnSync(resolveGitExecutable(), ["remote", "get-url", "origin"], {
|
|
35946
|
-
encoding: "utf-8",
|
|
35947
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
35948
|
-
timeout: 5000,
|
|
35949
|
-
...cwd ? { cwd } : {},
|
|
35950
|
-
envOverrides: laneEnv
|
|
35951
|
-
});
|
|
35952
|
-
if (result.status !== 0 || result.error) {
|
|
35953
|
-
return null;
|
|
35954
|
-
}
|
|
35955
|
-
const remoteUrl = (result.stdout ?? "").trim();
|
|
35956
|
-
return remoteUrl || null;
|
|
35957
|
-
} catch {
|
|
35958
|
-
return null;
|
|
35959
|
-
}
|
|
35960
|
-
}
|
|
35961
|
-
function parseGitRemoteUrl(remoteUrl) {
|
|
35962
|
-
const httpsMatch = remoteUrl.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?\/?$/i);
|
|
35963
|
-
if (httpsMatch) {
|
|
35964
|
-
const owner = httpsMatch[1];
|
|
35965
|
-
const repo = httpsMatch[2].replace(/\.git$/, "");
|
|
35966
|
-
if (containsControlCharacters(owner) || containsControlCharacters(repo)) {
|
|
35967
|
-
return null;
|
|
35968
|
-
}
|
|
35969
|
-
return { owner, repo };
|
|
35970
|
-
}
|
|
35971
|
-
const sshMatch = remoteUrl.match(/^git@github\.com:([^/]+)\/([^/]+?)(?:\.git)?$/i);
|
|
35972
|
-
if (sshMatch) {
|
|
35973
|
-
const owner = sshMatch[1];
|
|
35974
|
-
const repo = sshMatch[2].replace(/\.git$/, "");
|
|
35975
|
-
if (containsControlCharacters(owner) || containsControlCharacters(repo)) {
|
|
35976
|
-
return null;
|
|
35977
|
-
}
|
|
35978
|
-
return { owner, repo };
|
|
35979
|
-
}
|
|
35980
|
-
const pathMatch = remoteUrl.match(/\/([^/]+)\/([^/]+?)(?:\.git)?\/?$/);
|
|
35981
|
-
if (pathMatch) {
|
|
35982
|
-
const owner = pathMatch[1];
|
|
35983
|
-
const repo = pathMatch[2].replace(/\.git$/, "");
|
|
35984
|
-
if (containsControlCharacters(owner) || containsControlCharacters(repo)) {
|
|
35985
|
-
return null;
|
|
35986
|
-
}
|
|
35987
|
-
return { owner, repo };
|
|
35988
|
-
}
|
|
35989
|
-
return null;
|
|
35990
|
-
}
|
|
35991
|
-
|
|
35992
|
-
// src/commands/pr-ref.ts
|
|
35993
36039
|
var MAX_INSTRUCTIONS_LEN = 1000;
|
|
35994
36040
|
var GITHUB_CONTEXT = {
|
|
35995
36041
|
provider: "github",
|
|
@@ -40407,9 +40453,9 @@ function hashContent(content) {
|
|
|
40407
40453
|
return createHash27("sha1").update(content).digest("hex");
|
|
40408
40454
|
}
|
|
40409
40455
|
async function loadConfigForPolicyCurator(directory) {
|
|
40410
|
-
const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-
|
|
40456
|
+
const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-zrcgm9d9.js");
|
|
40411
40457
|
try {
|
|
40412
|
-
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-
|
|
40458
|
+
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-p6bvzgp2.js");
|
|
40413
40459
|
const { config: loadedConfig } = loadPluginConfigWithMeta2(directory);
|
|
40414
40460
|
return KnowledgeConfigSchema2.parse(loadedConfig.knowledge ?? {});
|
|
40415
40461
|
} catch {
|
|
@@ -43467,7 +43513,7 @@ async function resolveCuratorLLMDelegate(directory, mode, sessionId) {
|
|
|
43467
43513
|
const seam = _internals38.createCuratorLLMDelegate;
|
|
43468
43514
|
if (seam)
|
|
43469
43515
|
return seam(directory, mode, sessionId);
|
|
43470
|
-
const { createCuratorLLMDelegate } = await import("./curator-llm-factory-
|
|
43516
|
+
const { createCuratorLLMDelegate } = await import("./curator-llm-factory-13h02244.js");
|
|
43471
43517
|
return createCuratorLLMDelegate(directory, mode, sessionId);
|
|
43472
43518
|
}
|
|
43473
43519
|
async function reconcileCloseTerminalStateForPlan(directory, targetPlan, options) {
|
|
@@ -43862,7 +43908,7 @@ async function runFinalizeStage(ctx) {
|
|
|
43862
43908
|
}
|
|
43863
43909
|
}
|
|
43864
43910
|
try {
|
|
43865
|
-
const { CuratorConfigSchema: CCS } = await import("./schema-
|
|
43911
|
+
const { CuratorConfigSchema: CCS } = await import("./schema-zrcgm9d9.js");
|
|
43866
43912
|
const { config: pmLoadedConfig } = _internals38.loadPluginConfigWithMeta(ctx.directory);
|
|
43867
43913
|
const curatorCfg = CCS.parse(pmLoadedConfig.curator ?? {});
|
|
43868
43914
|
if (curatorCfg.enabled && curatorCfg.postmortem_enabled) {
|
|
@@ -46048,7 +46094,7 @@ function serializeAgentSession(s) {
|
|
|
46048
46094
|
}
|
|
46049
46095
|
async function writeSnapshot(directory, state) {
|
|
46050
46096
|
try {
|
|
46051
|
-
const { ensureSnapshotCoordinationReady } = await import("./snapshot-coordination-init-
|
|
46097
|
+
const { ensureSnapshotCoordinationReady } = await import("./snapshot-coordination-init-5q0hac3d.js");
|
|
46052
46098
|
await ensureSnapshotCoordinationReady(directory);
|
|
46053
46099
|
const snapshot = {
|
|
46054
46100
|
version: 3,
|
|
@@ -49226,7 +49272,7 @@ function planMerges(active, threshold, maxComparisons, maxMerges) {
|
|
|
49226
49272
|
};
|
|
49227
49273
|
}
|
|
49228
49274
|
async function sweepActiveNearDuplicates(directory, options = {}) {
|
|
49229
|
-
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-
|
|
49275
|
+
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-p6bvzgp2.js");
|
|
49230
49276
|
const { config } = loadPluginConfigWithMeta2(directory);
|
|
49231
49277
|
const sweepConfig = config.learning?.dedup_sweep;
|
|
49232
49278
|
if (sweepConfig?.enabled === false)
|
|
@@ -50107,14 +50153,14 @@ async function runCuratorInit(directory, config, llmDelegate) {
|
|
|
50107
50153
|
}));
|
|
50108
50154
|
if (llmDelegate) {
|
|
50109
50155
|
try {
|
|
50110
|
-
const userInput = [
|
|
50156
|
+
const userInput = sanitizeContextText([
|
|
50111
50157
|
"TASK: CURATOR_INIT",
|
|
50112
50158
|
`PRIOR_SUMMARY: ${priorSummary ? JSON.stringify(priorSummary) : "none"}`,
|
|
50113
50159
|
`KNOWLEDGE_ENTRIES: ${JSON.stringify(allEntriesForCurator)}`,
|
|
50114
|
-
`PROJECT_CONTEXT: ${contextMd?.slice(0, config.max_summary_tokens * 2) ?? "none"}`,
|
|
50115
|
-
`POST_MORTEM_DIGEST: ${latestPostMortemDigest ?? "none"}`
|
|
50160
|
+
`PROJECT_CONTEXT: ${sanitizeContextText(contextMd?.slice(0, config.max_summary_tokens * 2) ?? "none")}`,
|
|
50161
|
+
`POST_MORTEM_DIGEST: ${sanitizeContextText(latestPostMortemDigest ?? "none")}`
|
|
50116
50162
|
].join(`
|
|
50117
|
-
`);
|
|
50163
|
+
`));
|
|
50118
50164
|
const systemPrompt = CURATOR_INIT_PROMPT;
|
|
50119
50165
|
const timeoutMs = config.llm_timeout_ms ?? DEFAULT_CURATOR_LLM_TIMEOUT_MS;
|
|
50120
50166
|
const ac = new AbortController;
|
|
@@ -50208,7 +50254,7 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
|
|
|
50208
50254
|
const phaseData = plan?.phases.find((p) => p.id === phase);
|
|
50209
50255
|
const tasksCompleted = phaseData ? phaseData.tasks.filter((t) => t.status === "completed").length : 0;
|
|
50210
50256
|
const tasksTotal = phaseData ? phaseData.tasks.length : 0;
|
|
50211
|
-
const keyDecisions = contextMd ? extractContextDecisions(contextMd).map((decision) => decision.raw.trim().slice(2)) : [];
|
|
50257
|
+
const keyDecisions = contextMd ? extractContextDecisions(contextMd).map((decision) => sanitizeContextText(decision.raw.trim().slice(2))) : [];
|
|
50212
50258
|
const phaseDigest = {
|
|
50213
50259
|
phase,
|
|
50214
50260
|
timestamp: new Date().toISOString(),
|
|
@@ -50239,16 +50285,16 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
|
|
|
50239
50285
|
try {
|
|
50240
50286
|
const priorDigest = priorSummary?.digest ?? "none";
|
|
50241
50287
|
const systemPrompt = CURATOR_PHASE_PROMPT;
|
|
50242
|
-
const userInput = [
|
|
50288
|
+
const userInput = sanitizeContextText([
|
|
50243
50289
|
`TASK: CURATOR_PHASE ${phase}`,
|
|
50244
|
-
`PRIOR_DIGEST: ${priorDigest}`,
|
|
50290
|
+
`PRIOR_DIGEST: ${sanitizeContextText(priorDigest)}`,
|
|
50245
50291
|
`PHASE_EVENTS: ${JSON.stringify(phaseEvents.slice(0, 50))}`,
|
|
50246
50292
|
`PHASE_DECISIONS: ${JSON.stringify(keyDecisions)}`,
|
|
50247
50293
|
`AGENTS_DISPATCHED: ${JSON.stringify(agentsDispatched)}`,
|
|
50248
50294
|
`AGENTS_EXPECTED: ["reviewer", "test_engineer"]`,
|
|
50249
50295
|
`KNOWLEDGE_ENTRIES: ${JSON.stringify(knowledgeForCurator)}`
|
|
50250
50296
|
].join(`
|
|
50251
|
-
`);
|
|
50297
|
+
`));
|
|
50252
50298
|
const timeoutMs = config.llm_timeout_ms ?? DEFAULT_CURATOR_LLM_TIMEOUT_MS;
|
|
50253
50299
|
const ac = new AbortController;
|
|
50254
50300
|
const timer = setTimeout(() => ac.abort(), timeoutMs);
|
|
@@ -50350,7 +50396,7 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
|
|
|
50350
50396
|
}
|
|
50351
50397
|
if (config.skill_generation_enabled === true && skillCandidates.length > 0) {
|
|
50352
50398
|
try {
|
|
50353
|
-
const skillModule = await import("./skill-generator-
|
|
50399
|
+
const skillModule = await import("./skill-generator-dztn1ctf.js");
|
|
50354
50400
|
for (const cand of skillCandidates) {
|
|
50355
50401
|
if (cand.confidence < (config.min_skill_confidence ?? DEFAULT_SKILL_MIN_CONFIDENCE)) {
|
|
50356
50402
|
continue;
|
|
@@ -50822,7 +50868,7 @@ async function applyCuratorKnowledgeUpdates(directory, recommendations, knowledg
|
|
|
50822
50868
|
} catch {}
|
|
50823
50869
|
}
|
|
50824
50870
|
if (contradictedEntries.length > 0 && knowledgeConfig.contradiction_threshold_action === "quarantine") {
|
|
50825
|
-
const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-
|
|
50871
|
+
const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-7xcd0zea.js");
|
|
50826
50872
|
for (const { id } of contradictedEntries) {
|
|
50827
50873
|
try {
|
|
50828
50874
|
await maybeQuarantineOnContradiction(directory, id, knowledgeConfig.contradiction_quarantine_threshold, knowledgeConfig.contradiction_quarantine_window_days);
|
|
@@ -51335,9 +51381,9 @@ async function repairPostMortemActions(llmOutput, diagnostics, options) {
|
|
|
51335
51381
|
"Allowed queue_triage action values: apply, reject.",
|
|
51336
51382
|
"Do not include unsupported actions such as merge.",
|
|
51337
51383
|
"Diagnostics:",
|
|
51338
|
-
diagnostics.join("; "),
|
|
51384
|
+
diagnostics.map((d) => sanitizeContextText(d)).join("; "),
|
|
51339
51385
|
"Original output:",
|
|
51340
|
-
llmOutput.slice(0, 8000)
|
|
51386
|
+
sanitizeContextText(llmOutput).slice(0, 8000)
|
|
51341
51387
|
].join(`
|
|
51342
51388
|
`);
|
|
51343
51389
|
const repaired = await options.llmDelegate("", repairPrompt, ac.signal);
|
|
@@ -51553,8 +51599,8 @@ function assembleLLMInput(planId, scope, sessionID, planSummary, knowledgeSummar
|
|
|
51553
51599
|
const sections = [];
|
|
51554
51600
|
sections.push(`TASK: CURATOR_POSTMORTEM ${planId}`);
|
|
51555
51601
|
sections.push(`SCOPE: ${scope}${sessionID ? ` (${sessionID})` : ""}`);
|
|
51556
|
-
sections.push(`PLAN_SUMMARY: ${planSummary}`);
|
|
51557
|
-
sections.push(`CURATOR_DIGESTS: ${curatorDigest ?? "none"}`);
|
|
51602
|
+
sections.push(`PLAN_SUMMARY: ${sanitizeContextText(planSummary)}`);
|
|
51603
|
+
sections.push(`CURATOR_DIGESTS: ${sanitizeContextText(curatorDigest ?? "none")}`);
|
|
51558
51604
|
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(`
|
|
51559
51605
|
`);
|
|
51560
51606
|
sections.push(`KNOWLEDGE_EVENTS_SUMMARY:
|
|
@@ -51585,9 +51631,9 @@ ${retroText}`);
|
|
|
51585
51631
|
sections.push(`DRIFT_REPORTS:
|
|
51586
51632
|
${driftText}`);
|
|
51587
51633
|
}
|
|
51588
|
-
return sections.join(`
|
|
51634
|
+
return sanitizeContextText(sections.join(`
|
|
51589
51635
|
|
|
51590
|
-
`);
|
|
51636
|
+
`));
|
|
51591
51637
|
}
|
|
51592
51638
|
async function runCuratorPostMortem(directory, options = {}) {
|
|
51593
51639
|
const warnings = [];
|
|
@@ -51654,7 +51700,7 @@ async function runCuratorPostMortem(directory, options = {}) {
|
|
|
51654
51700
|
warnings.push("Failed to collect knowledge summary.");
|
|
51655
51701
|
}
|
|
51656
51702
|
try {
|
|
51657
|
-
const { getScanStatus } = await import("./scan-cursor-
|
|
51703
|
+
const { getScanStatus } = await import("./scan-cursor-fgecb928.js");
|
|
51658
51704
|
const scanStatus = await getScanStatus(directory);
|
|
51659
51705
|
if (scanStatus.remaining_estimate > 0) {
|
|
51660
51706
|
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.`);
|
|
@@ -51826,9 +51872,9 @@ var _internals57 = {
|
|
|
51826
51872
|
verifyPostMortemKnowledgeActions,
|
|
51827
51873
|
repairPostMortemActions,
|
|
51828
51874
|
loadDefaultKnowledgeConfig: async (directory) => {
|
|
51829
|
-
const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-
|
|
51875
|
+
const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-zrcgm9d9.js");
|
|
51830
51876
|
try {
|
|
51831
|
-
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-
|
|
51877
|
+
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-p6bvzgp2.js");
|
|
51832
51878
|
const loaded = loadPluginConfigWithMeta2(directory);
|
|
51833
51879
|
return KnowledgeConfigSchema2.parse(loaded.config.knowledge ?? {});
|
|
51834
51880
|
} catch {
|
|
@@ -51836,11 +51882,11 @@ var _internals57 = {
|
|
|
51836
51882
|
}
|
|
51837
51883
|
},
|
|
51838
51884
|
applyCuratorKnowledgeUpdates: async (directory, recommendations, knowledgeConfig, generation) => {
|
|
51839
|
-
const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-
|
|
51885
|
+
const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-r0jfc7xw.js");
|
|
51840
51886
|
return applyCuratorKnowledgeUpdates2(directory, recommendations, knowledgeConfig, generation);
|
|
51841
51887
|
},
|
|
51842
51888
|
checkHivePromotions: async (entries2, knowledgeConfig, directory) => {
|
|
51843
|
-
const { checkHivePromotions } = await import("./hive-promoter-
|
|
51889
|
+
const { checkHivePromotions } = await import("./hive-promoter-0vg8w79a.js");
|
|
51844
51890
|
return checkHivePromotions(entries2, knowledgeConfig, directory);
|
|
51845
51891
|
},
|
|
51846
51892
|
applyProposalTriage: async (directory, triage) => {
|
|
@@ -51849,7 +51895,7 @@ var _internals57 = {
|
|
|
51849
51895
|
activateProposal,
|
|
51850
51896
|
listSkills: listSkills2,
|
|
51851
51897
|
sanitizeSlug
|
|
51852
|
-
} = await import("./skill-generator-
|
|
51898
|
+
} = await import("./skill-generator-dztn1ctf.js");
|
|
51853
51899
|
const result = {
|
|
51854
51900
|
approved: [],
|
|
51855
51901
|
rejected: [],
|
|
@@ -51891,7 +51937,7 @@ var _internals57 = {
|
|
|
51891
51937
|
return result;
|
|
51892
51938
|
},
|
|
51893
51939
|
readPriorDriftReports: async (directory) => {
|
|
51894
|
-
const { readPriorDriftReports: readPriorDriftReports2 } = await import("./curator-drift-
|
|
51940
|
+
const { readPriorDriftReports: readPriorDriftReports2 } = await import("./curator-drift-q84jn9cc.js");
|
|
51895
51941
|
return readPriorDriftReports2(directory);
|
|
51896
51942
|
},
|
|
51897
51943
|
readSwarmKnowledge: (directory) => readKnowledge(resolveSwarmKnowledgePath(directory))
|
|
@@ -61687,9 +61733,9 @@ var _internals67 = {
|
|
|
61687
61733
|
loadPluginConfigWithMeta,
|
|
61688
61734
|
loadCuratorDeps: async () => {
|
|
61689
61735
|
const [{ CuratorConfigSchema }, curator, { createCuratorLLMDelegate }] = await Promise.all([
|
|
61690
|
-
import("./schema-
|
|
61691
|
-
import("./curator-
|
|
61692
|
-
import("./curator-llm-factory-
|
|
61736
|
+
import("./schema-zrcgm9d9.js"),
|
|
61737
|
+
import("./curator-r0jfc7xw.js"),
|
|
61738
|
+
import("./curator-llm-factory-13h02244.js")
|
|
61693
61739
|
]);
|
|
61694
61740
|
return { CuratorConfigSchema, curator, createCuratorLLMDelegate };
|
|
61695
61741
|
}
|
|
@@ -64082,7 +64128,7 @@ async function computeCurationDiagnostics(directory, entries2) {
|
|
|
64082
64128
|
let scanCompleted = false;
|
|
64083
64129
|
let scanRemaining = 0;
|
|
64084
64130
|
try {
|
|
64085
|
-
const { getScanStatus } = await import("./scan-cursor-
|
|
64131
|
+
const { getScanStatus } = await import("./scan-cursor-fgecb928.js");
|
|
64086
64132
|
const status = await getScanStatus(directory);
|
|
64087
64133
|
scanGeneration = status.generation;
|
|
64088
64134
|
scanCompleted = status.completed;
|
|
@@ -64090,19 +64136,19 @@ async function computeCurationDiagnostics(directory, entries2) {
|
|
|
64090
64136
|
} catch {}
|
|
64091
64137
|
let configMatch = null;
|
|
64092
64138
|
try {
|
|
64093
|
-
const { isLinked: isLinked2 } = await import("./knowledge-link-
|
|
64139
|
+
const { isLinked: isLinked2 } = await import("./knowledge-link-dv78fb9g.js");
|
|
64094
64140
|
if (isLinked2(directory)) {
|
|
64095
|
-
const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-
|
|
64141
|
+
const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-zrcgm9d9.js");
|
|
64096
64142
|
let config;
|
|
64097
64143
|
try {
|
|
64098
|
-
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-
|
|
64144
|
+
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-p6bvzgp2.js");
|
|
64099
64145
|
const loaded = loadPluginConfigWithMeta2(directory);
|
|
64100
64146
|
config = KnowledgeConfigSchema2.parse(loaded.config.knowledge ?? {});
|
|
64101
64147
|
} catch {
|
|
64102
64148
|
config = KnowledgeConfigSchema2.parse({});
|
|
64103
64149
|
}
|
|
64104
64150
|
const { cohortConfigFingerprint: cohortConfigFingerprint2 } = await import("./config-fingerprint-v22xh5a2.js");
|
|
64105
|
-
const { buildConfigFingerprintInput: buildConfigFingerprintInput2, readCohortConfigFingerprint } = await import("./curation-policy-
|
|
64151
|
+
const { buildConfigFingerprintInput: buildConfigFingerprintInput2, readCohortConfigFingerprint } = await import("./curation-policy-ytzwb080.js");
|
|
64106
64152
|
const currentFp = cohortConfigFingerprint2(buildConfigFingerprintInput2(config));
|
|
64107
64153
|
const cohortFp = await readCohortConfigFingerprint(directory);
|
|
64108
64154
|
configMatch = cohortFp === null ? null : currentFp === cohortFp;
|
|
@@ -65550,7 +65596,7 @@ async function handleDoctorCommand(directory, args) {
|
|
|
65550
65596
|
const result = runConfigDoctor(config, directory);
|
|
65551
65597
|
let output;
|
|
65552
65598
|
if (enableAutoFix && result.hasAutoFixableIssues) {
|
|
65553
|
-
const { runConfigDoctorWithFixes } = await import("./config-doctor-
|
|
65599
|
+
const { runConfigDoctorWithFixes } = await import("./config-doctor-28ggsms8.js");
|
|
65554
65600
|
const fixResult = await runConfigDoctorWithFixes(directory, config, true, {
|
|
65555
65601
|
applyLossy: true
|
|
65556
65602
|
});
|
|
@@ -65588,7 +65634,7 @@ async function handleDoctorCommand(directory, args) {
|
|
|
65588
65634
|
`;
|
|
65589
65635
|
}
|
|
65590
65636
|
try {
|
|
65591
|
-
const { runModelPreflight } = await import("./model-preflight-
|
|
65637
|
+
const { runModelPreflight } = await import("./model-preflight-kap3zp3g.js");
|
|
65592
65638
|
const preflight = await runModelPreflight(config, swarmState.opencodeClient, { generatedAgentNames: swarmState.generatedAgentNames });
|
|
65593
65639
|
const missingSelection = preflight.resolutions.filter((resolution) => resolution.status === "missing-selection");
|
|
65594
65640
|
const unresolved = preflight.catalogAvailable ? preflight.resolutions.filter((resolution) => resolution.status === "unresolved") : [];
|
|
@@ -66515,7 +66561,7 @@ async function handleEvidenceCommand(directory, args) {
|
|
|
66515
66561
|
return formatTaskEvidenceMarkdown(evidenceData);
|
|
66516
66562
|
}
|
|
66517
66563
|
async function handleEvidenceSummaryCommand(directory) {
|
|
66518
|
-
const { buildEvidenceSummary } = await import("./evidence-summary-service-
|
|
66564
|
+
const { buildEvidenceSummary } = await import("./evidence-summary-service-rsectw2t.js");
|
|
66519
66565
|
const artifact = await buildEvidenceSummary(directory);
|
|
66520
66566
|
if (!artifact) {
|
|
66521
66567
|
return "No plan found. Run `/swarm plan` to check plan status.";
|
|
@@ -90848,7 +90894,7 @@ function createCuratorLLMDelegate(directory, mode = "init", sessionId) {
|
|
|
90848
90894
|
}
|
|
90849
90895
|
const sdkOpts = signal ? { signal } : {};
|
|
90850
90896
|
try {
|
|
90851
|
-
const { getSwarmAgents: getSwarmAgents2, resolveFallbackModel: resolveFallbackModel2 } = await import("./index-
|
|
90897
|
+
const { getSwarmAgents: getSwarmAgents2, resolveFallbackModel: resolveFallbackModel2 } = await import("./index-22f1ek6k.js");
|
|
90852
90898
|
const createResult = await client.session.create({
|
|
90853
90899
|
...sessionId ? {
|
|
90854
90900
|
body: {
|
|
@@ -91140,8 +91186,8 @@ init_zod();
|
|
|
91140
91186
|
init_loader();
|
|
91141
91187
|
import { createHash as createHash51, randomUUID as randomUUID22 } from "crypto";
|
|
91142
91188
|
import * as fsSync9 from "fs";
|
|
91143
|
-
import * as
|
|
91144
|
-
import * as
|
|
91189
|
+
import * as fs64 from "fs/promises";
|
|
91190
|
+
import * as path128 from "path";
|
|
91145
91191
|
init_logger();
|
|
91146
91192
|
|
|
91147
91193
|
// src/background/pr-feedback-event-queue.ts
|
|
@@ -92106,6 +92152,228 @@ var _internals98 = {
|
|
|
92106
92152
|
|
|
92107
92153
|
// src/git/pr.ts
|
|
92108
92154
|
init_git_executable();
|
|
92155
|
+
|
|
92156
|
+
// src/utils/glab-executable.ts
|
|
92157
|
+
init_warning_buffer();
|
|
92158
|
+
import { spawnSync as spawnSync5 } from "child_process";
|
|
92159
|
+
import * as fs63 from "fs";
|
|
92160
|
+
import * as os14 from "os";
|
|
92161
|
+
import * as path127 from "path";
|
|
92162
|
+
var GLAB_BINARY_ENV_VAR = "OPENCODE_SWARM_GLAB_BINARY";
|
|
92163
|
+
var PER_PROBE_TIMEOUT_MS2 = 250;
|
|
92164
|
+
var TOTAL_BUDGET_MS3 = 1000;
|
|
92165
|
+
var NEGATIVE_CACHE_TTL_MS2 = 60000;
|
|
92166
|
+
var BARE_GLAB = "glab";
|
|
92167
|
+
var PROBE_MAX_BUFFER_BYTES2 = 64 * 1024;
|
|
92168
|
+
var PROBE_OUTPUT_EXCERPT_CHARS2 = 60;
|
|
92169
|
+
var WINDOWS_PATH_EXTENSIONS2 = [".exe", ".cmd", ".bat"];
|
|
92170
|
+
var GLAB_VERSION_PATTERN = /^glab version \d+\.\d+/;
|
|
92171
|
+
function excerptProbeOutput2(raw) {
|
|
92172
|
+
return raw.slice(0, PROBE_OUTPUT_EXCERPT_CHARS2).replace(/[^\x20-\x7E]/g, " ").trim();
|
|
92173
|
+
}
|
|
92174
|
+
var cache3 = null;
|
|
92175
|
+
var lastAttempts2 = [];
|
|
92176
|
+
var cacheGeneration2 = 0;
|
|
92177
|
+
function windowsGlabAbsoluteCandidates(env) {
|
|
92178
|
+
const candidates = [];
|
|
92179
|
+
const push = (...parts) => {
|
|
92180
|
+
const candidate2 = path127.join(...parts);
|
|
92181
|
+
if (!candidates.includes(candidate2))
|
|
92182
|
+
candidates.push(candidate2);
|
|
92183
|
+
};
|
|
92184
|
+
if (env.ProgramFiles) {
|
|
92185
|
+
push(env.ProgramFiles, "GitLab CLI", "glab.exe");
|
|
92186
|
+
}
|
|
92187
|
+
if (env["ProgramFiles(x86)"]) {
|
|
92188
|
+
push(env["ProgramFiles(x86)"], "GitLab CLI", "glab.exe");
|
|
92189
|
+
}
|
|
92190
|
+
if (env.LOCALAPPDATA) {
|
|
92191
|
+
push(env.LOCALAPPDATA, "GitLab CLI", "glab.exe");
|
|
92192
|
+
push(env.LOCALAPPDATA, "Programs", "GitLab CLI", "glab.exe");
|
|
92193
|
+
}
|
|
92194
|
+
return candidates;
|
|
92195
|
+
}
|
|
92196
|
+
function platformCandidates2(platform, env) {
|
|
92197
|
+
if (platform === "win32") {
|
|
92198
|
+
return windowsGlabAbsoluteCandidates(env);
|
|
92199
|
+
}
|
|
92200
|
+
if (platform === "darwin") {
|
|
92201
|
+
return ["/opt/homebrew/bin/glab", "/usr/local/bin/glab", "/usr/bin/glab"];
|
|
92202
|
+
}
|
|
92203
|
+
return ["/usr/bin/glab", "/usr/local/bin/glab", "/bin/glab"];
|
|
92204
|
+
}
|
|
92205
|
+
function isAbsoluteForPlatform2(candidate2, platform) {
|
|
92206
|
+
return platform === "win32" ? path127.win32.isAbsolute(candidate2) : path127.posix.isAbsolute(candidate2);
|
|
92207
|
+
}
|
|
92208
|
+
function joinDirAndName2(dir, name, platform) {
|
|
92209
|
+
const sep22 = platform === "win32" ? "\\" : "/";
|
|
92210
|
+
const trimmed = dir.replace(/[\\/]+$/, "");
|
|
92211
|
+
return trimmed ? `${trimmed}${sep22}${name}` : `${sep22}${name}`;
|
|
92212
|
+
}
|
|
92213
|
+
function pathCandidates2(platform) {
|
|
92214
|
+
const pathValue = _internals99.env().PATH ?? "";
|
|
92215
|
+
if (!pathValue)
|
|
92216
|
+
return [];
|
|
92217
|
+
const dirs = pathValue.split(platform === "win32" ? ";" : ":").filter(Boolean);
|
|
92218
|
+
const names = platform === "win32" ? [...WINDOWS_PATH_EXTENSIONS2.map((ext) => `glab${ext}`), "glab"] : ["glab"];
|
|
92219
|
+
const out = [];
|
|
92220
|
+
for (const dir of dirs) {
|
|
92221
|
+
for (const name of names) {
|
|
92222
|
+
const candidate2 = joinDirAndName2(dir, name, platform);
|
|
92223
|
+
if (!out.includes(candidate2))
|
|
92224
|
+
out.push(candidate2);
|
|
92225
|
+
}
|
|
92226
|
+
}
|
|
92227
|
+
return out;
|
|
92228
|
+
}
|
|
92229
|
+
function envOverride2() {
|
|
92230
|
+
const raw = _internals99.env()[GLAB_BINARY_ENV_VAR];
|
|
92231
|
+
return raw && raw.trim() !== "" ? raw : undefined;
|
|
92232
|
+
}
|
|
92233
|
+
function buildCandidates2(platform) {
|
|
92234
|
+
const override = envOverride2();
|
|
92235
|
+
const overrideCandidate = override ? [{ source: "override", path: override }] : [];
|
|
92236
|
+
const seen = new Set(overrideCandidate.map((c) => c.path));
|
|
92237
|
+
const rest = [];
|
|
92238
|
+
for (const p of platformCandidates2(platform, _internals99.env())) {
|
|
92239
|
+
if (seen.has(p))
|
|
92240
|
+
continue;
|
|
92241
|
+
seen.add(p);
|
|
92242
|
+
rest.push({ source: "platform", path: p });
|
|
92243
|
+
}
|
|
92244
|
+
for (const p of pathCandidates2(platform)) {
|
|
92245
|
+
if (seen.has(p))
|
|
92246
|
+
continue;
|
|
92247
|
+
seen.add(p);
|
|
92248
|
+
rest.push({ source: "path", path: p });
|
|
92249
|
+
}
|
|
92250
|
+
return [...overrideCandidate, ...rest];
|
|
92251
|
+
}
|
|
92252
|
+
function probeCandidate2(candidatePath2, platform) {
|
|
92253
|
+
if (!isAbsoluteForPlatform2(candidatePath2, platform)) {
|
|
92254
|
+
return { accepted: false, reason: "not an absolute path" };
|
|
92255
|
+
}
|
|
92256
|
+
let stat13;
|
|
92257
|
+
try {
|
|
92258
|
+
stat13 = fs63.statSync(candidatePath2);
|
|
92259
|
+
} catch (err) {
|
|
92260
|
+
const code = err?.code;
|
|
92261
|
+
if (code === "ENOENT")
|
|
92262
|
+
return { accepted: false, reason: "no such file" };
|
|
92263
|
+
return {
|
|
92264
|
+
accepted: false,
|
|
92265
|
+
reason: `cannot stat (${code ?? "unknown error"})`
|
|
92266
|
+
};
|
|
92267
|
+
}
|
|
92268
|
+
if (stat13.isDirectory()) {
|
|
92269
|
+
return { accepted: false, reason: "is a directory" };
|
|
92270
|
+
}
|
|
92271
|
+
if (!stat13.isFile()) {
|
|
92272
|
+
return { accepted: false, reason: "not a regular file" };
|
|
92273
|
+
}
|
|
92274
|
+
let result;
|
|
92275
|
+
try {
|
|
92276
|
+
result = _internals99.spawnSync(candidatePath2, ["--version"], {
|
|
92277
|
+
cwd: os14.tmpdir(),
|
|
92278
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
92279
|
+
windowsHide: true,
|
|
92280
|
+
timeout: PER_PROBE_TIMEOUT_MS2,
|
|
92281
|
+
maxBuffer: PROBE_MAX_BUFFER_BYTES2
|
|
92282
|
+
});
|
|
92283
|
+
} catch (err) {
|
|
92284
|
+
return {
|
|
92285
|
+
accepted: false,
|
|
92286
|
+
reason: `spawn threw: ${err instanceof Error ? err.message : String(err)}`
|
|
92287
|
+
};
|
|
92288
|
+
}
|
|
92289
|
+
if (result.error) {
|
|
92290
|
+
return { accepted: false, reason: `spawn failed: ${result.error.message}` };
|
|
92291
|
+
}
|
|
92292
|
+
if (result.status !== 0) {
|
|
92293
|
+
const statusDescription = result.status !== null ? `exit ${result.status}` : `signal ${result.signal ?? "unknown"}`;
|
|
92294
|
+
return {
|
|
92295
|
+
accepted: false,
|
|
92296
|
+
reason: `glab --version returned ${statusDescription}`
|
|
92297
|
+
};
|
|
92298
|
+
}
|
|
92299
|
+
const versionOutput = (result.stdout ?? "").toString().trim();
|
|
92300
|
+
if (!GLAB_VERSION_PATTERN.test(versionOutput)) {
|
|
92301
|
+
const excerpt = excerptProbeOutput2(versionOutput);
|
|
92302
|
+
return {
|
|
92303
|
+
accepted: false,
|
|
92304
|
+
reason: excerpt ? `not glab: --version printed "${excerpt}"` : "not glab: --version printed nothing"
|
|
92305
|
+
};
|
|
92306
|
+
}
|
|
92307
|
+
return { accepted: true };
|
|
92308
|
+
}
|
|
92309
|
+
function probeCycle2(candidates, platform, attempts) {
|
|
92310
|
+
const start = _internals99.now();
|
|
92311
|
+
let budgetExceeded = false;
|
|
92312
|
+
for (const candidate2 of candidates) {
|
|
92313
|
+
if (_internals99.now() - start > TOTAL_BUDGET_MS3) {
|
|
92314
|
+
budgetExceeded = true;
|
|
92315
|
+
break;
|
|
92316
|
+
}
|
|
92317
|
+
const result = probeCandidate2(candidate2.path, platform);
|
|
92318
|
+
attempts.push({
|
|
92319
|
+
source: candidate2.source,
|
|
92320
|
+
candidate: candidate2.path,
|
|
92321
|
+
accepted: result.accepted,
|
|
92322
|
+
reason: result.accepted ? undefined : result.reason
|
|
92323
|
+
});
|
|
92324
|
+
if (candidate2.source === "override" && !result.accepted) {
|
|
92325
|
+
advisoryWarn(`[opencode-swarm] ${GLAB_BINARY_ENV_VAR} override "${candidate2.path}" is unusable (${result.reason}); falling back to automatic glab resolution.`);
|
|
92326
|
+
}
|
|
92327
|
+
if (result.accepted) {
|
|
92328
|
+
return { outcome: "accepted", path: candidate2.path };
|
|
92329
|
+
}
|
|
92330
|
+
}
|
|
92331
|
+
return budgetExceeded ? { outcome: "exhausted-budget" } : { outcome: "all-rejected" };
|
|
92332
|
+
}
|
|
92333
|
+
function readCache3() {
|
|
92334
|
+
if (cache3 === null)
|
|
92335
|
+
return null;
|
|
92336
|
+
if (cache3.kind === "success")
|
|
92337
|
+
return cache3;
|
|
92338
|
+
if (_internals99.now() < cache3.expiresAt)
|
|
92339
|
+
return cache3;
|
|
92340
|
+
cache3 = null;
|
|
92341
|
+
return null;
|
|
92342
|
+
}
|
|
92343
|
+
function applyProbeResult2(result, attempts, generation) {
|
|
92344
|
+
if (generation !== cacheGeneration2) {
|
|
92345
|
+
return result.outcome === "accepted" ? result.path : BARE_GLAB;
|
|
92346
|
+
}
|
|
92347
|
+
lastAttempts2 = attempts;
|
|
92348
|
+
if (result.outcome === "accepted") {
|
|
92349
|
+
cache3 = { kind: "success", path: result.path };
|
|
92350
|
+
return result.path;
|
|
92351
|
+
}
|
|
92352
|
+
cache3 = {
|
|
92353
|
+
kind: "fallback",
|
|
92354
|
+
expiresAt: _internals99.now() + NEGATIVE_CACHE_TTL_MS2
|
|
92355
|
+
};
|
|
92356
|
+
return BARE_GLAB;
|
|
92357
|
+
}
|
|
92358
|
+
function resolveGlabExecutable() {
|
|
92359
|
+
const cached = readCache3();
|
|
92360
|
+
if (cached)
|
|
92361
|
+
return cached.kind === "success" ? cached.path : BARE_GLAB;
|
|
92362
|
+
const platform = _internals99.platform();
|
|
92363
|
+
const attempts = [];
|
|
92364
|
+
const generation = cacheGeneration2;
|
|
92365
|
+
const candidates = buildCandidates2(platform);
|
|
92366
|
+
const result = probeCycle2(candidates, platform, attempts);
|
|
92367
|
+
return applyProbeResult2(result, attempts, generation);
|
|
92368
|
+
}
|
|
92369
|
+
var _internals99 = {
|
|
92370
|
+
spawnSync: spawnSync5,
|
|
92371
|
+
platform: () => process.platform,
|
|
92372
|
+
env: () => process.env,
|
|
92373
|
+
now: () => Date.now()
|
|
92374
|
+
};
|
|
92375
|
+
|
|
92376
|
+
// src/git/pr.ts
|
|
92109
92377
|
init_logger();
|
|
92110
92378
|
|
|
92111
92379
|
// src/utils/untrusted-markdown.ts
|
|
@@ -92141,7 +92409,7 @@ var EvidencePlanSchema = exports_external.object({
|
|
|
92141
92409
|
}).passthrough()).optional()
|
|
92142
92410
|
}).passthrough();
|
|
92143
92411
|
function ghExec(args, cwd) {
|
|
92144
|
-
const ghBinary =
|
|
92412
|
+
const ghBinary = _internals100.resolveGhExecutable();
|
|
92145
92413
|
for (let attempt = 0;attempt < MAX_TRANSIENT_RETRIES; attempt++) {
|
|
92146
92414
|
const result = child_process5.spawnSync(ghBinary, args, {
|
|
92147
92415
|
cwd,
|
|
@@ -92197,12 +92465,18 @@ function spawnSyncWithTransientRetry(command, args, options) {
|
|
|
92197
92465
|
throw new Error(`${command} exited with null`);
|
|
92198
92466
|
}
|
|
92199
92467
|
async function ghExecAsync(args, cwd) {
|
|
92468
|
+
return _internals100.forgeExecAsync(_internals100.resolveGhExecutable(), args, cwd, "gh");
|
|
92469
|
+
}
|
|
92470
|
+
async function forgeExecAsyncImpl(binary, args, cwd, label, opts) {
|
|
92200
92471
|
return new Promise((resolve40, reject) => {
|
|
92201
|
-
const
|
|
92202
|
-
const proc = child_process5.spawn(ghBinary, args, {
|
|
92472
|
+
const spawnOptions = {
|
|
92203
92473
|
cwd,
|
|
92204
92474
|
stdio: ["ignore", "pipe", "pipe"]
|
|
92205
|
-
}
|
|
92475
|
+
};
|
|
92476
|
+
if (opts?.env) {
|
|
92477
|
+
spawnOptions.env = mergeEnvForChild(undefined, opts.env);
|
|
92478
|
+
}
|
|
92479
|
+
const proc = child_process5.spawn(binary, args, spawnOptions);
|
|
92206
92480
|
const stdoutChunks = [];
|
|
92207
92481
|
const stderrChunks = [];
|
|
92208
92482
|
let stdoutBytes = 0;
|
|
@@ -92226,7 +92500,7 @@ async function ghExecAsync(args, cwd) {
|
|
|
92226
92500
|
proc.stdout?.on("data", (chunk) => {
|
|
92227
92501
|
stdoutBytes += chunk.length;
|
|
92228
92502
|
if (stdoutBytes > MAX_OUTPUT_BYTES2) {
|
|
92229
|
-
settle2(() => reject(new Error(
|
|
92503
|
+
settle2(() => reject(new Error(`${label} ${args[0]} stdout exceeded ${MAX_OUTPUT_BYTES2} bytes`)));
|
|
92230
92504
|
return;
|
|
92231
92505
|
}
|
|
92232
92506
|
stdoutChunks.push(chunk);
|
|
@@ -92234,13 +92508,13 @@ async function ghExecAsync(args, cwd) {
|
|
|
92234
92508
|
proc.stderr?.on("data", (chunk) => {
|
|
92235
92509
|
stderrBytes += chunk.length;
|
|
92236
92510
|
if (stderrBytes > MAX_OUTPUT_BYTES2) {
|
|
92237
|
-
settle2(() => reject(new Error(
|
|
92511
|
+
settle2(() => reject(new Error(`${label} ${args[0]} stderr exceeded ${MAX_OUTPUT_BYTES2} bytes`)));
|
|
92238
92512
|
return;
|
|
92239
92513
|
}
|
|
92240
92514
|
stderrChunks.push(chunk);
|
|
92241
92515
|
});
|
|
92242
92516
|
const timer = setTimeout(() => {
|
|
92243
|
-
settle2(() => reject(new Error(
|
|
92517
|
+
settle2(() => reject(new Error(`${label} ${args[0]} timed out after ${GIT_TIMEOUT_MS5}ms`)));
|
|
92244
92518
|
}, GIT_TIMEOUT_MS5);
|
|
92245
92519
|
proc.on("error", (err) => {
|
|
92246
92520
|
settle2(() => reject(err));
|
|
@@ -92249,7 +92523,7 @@ async function ghExecAsync(args, cwd) {
|
|
|
92249
92523
|
settle2(() => {
|
|
92250
92524
|
if (code !== 0) {
|
|
92251
92525
|
const stderr = Buffer.concat(stderrChunks).toString("utf-8");
|
|
92252
|
-
reject(new Error(stderr ||
|
|
92526
|
+
reject(new Error(stderr || `${label} exited with ${code}`));
|
|
92253
92527
|
} else {
|
|
92254
92528
|
const stdout = Buffer.concat(stdoutChunks).toString("utf-8");
|
|
92255
92529
|
resolve40(stdout);
|
|
@@ -92258,20 +92532,24 @@ async function ghExecAsync(args, cwd) {
|
|
|
92258
92532
|
});
|
|
92259
92533
|
});
|
|
92260
92534
|
}
|
|
92261
|
-
var
|
|
92535
|
+
var _internals100 = {
|
|
92262
92536
|
ghExec,
|
|
92263
92537
|
ghExecAsync,
|
|
92538
|
+
forgeExecAsync: forgeExecAsyncImpl,
|
|
92539
|
+
getMRPollSnapshot,
|
|
92540
|
+
getMRComments,
|
|
92264
92541
|
spawnSyncWithTransientRetry,
|
|
92265
92542
|
spawnSync: __spawnSyncSeam.spawnSync,
|
|
92266
92543
|
readLaneEnvFileFromDiskSync,
|
|
92267
92544
|
getMergeGroupRun,
|
|
92268
92545
|
resolveGhExecutable,
|
|
92269
|
-
resolveGitExecutable
|
|
92546
|
+
resolveGitExecutable,
|
|
92547
|
+
resolveGlabExecutable
|
|
92270
92548
|
};
|
|
92271
92549
|
async function getPRPollSnapshot(prNumber, repoFullName, cwd) {
|
|
92272
92550
|
let stdout;
|
|
92273
92551
|
try {
|
|
92274
|
-
stdout = await
|
|
92552
|
+
stdout = await _internals100.ghExecAsync([
|
|
92275
92553
|
"pr",
|
|
92276
92554
|
"view",
|
|
92277
92555
|
String(prNumber),
|
|
@@ -92328,7 +92606,7 @@ function numericIssueCommentId(url, fallbackId, fallbacks) {
|
|
|
92328
92606
|
async function getPRReviewComments(prNumber, repoFullName, cwd) {
|
|
92329
92607
|
let stdout;
|
|
92330
92608
|
try {
|
|
92331
|
-
stdout = await
|
|
92609
|
+
stdout = await _internals100.ghExecAsync(["api", `repos/${repoFullName}/pulls/${prNumber}/comments`], cwd);
|
|
92332
92610
|
} catch (err) {
|
|
92333
92611
|
throw new Error(`Failed to fetch review comments for ${repoFullName}#${prNumber}: ${err instanceof Error ? err.message : String(err)}`);
|
|
92334
92612
|
}
|
|
@@ -92341,6 +92619,129 @@ async function getPRReviewComments(prNumber, repoFullName, cwd) {
|
|
|
92341
92619
|
isReviewComment: true
|
|
92342
92620
|
}));
|
|
92343
92621
|
}
|
|
92622
|
+
var MR_SYNTHESIZED_FIELD_MARKER = "NOT_AVAILABLE";
|
|
92623
|
+
function glabSpawnEnv(input) {
|
|
92624
|
+
if (!input.host || input.host === "gitlab.com")
|
|
92625
|
+
return;
|
|
92626
|
+
return { env: { GITLAB_HOST: input.host } };
|
|
92627
|
+
}
|
|
92628
|
+
function mapMrState(state) {
|
|
92629
|
+
if (state === "merged")
|
|
92630
|
+
return "MERGED";
|
|
92631
|
+
if (state === "closed")
|
|
92632
|
+
return "CLOSED";
|
|
92633
|
+
return "OPEN";
|
|
92634
|
+
}
|
|
92635
|
+
function mapMrMergeable(mr, detail) {
|
|
92636
|
+
if (mr.has_conflicts === true)
|
|
92637
|
+
return "CONFLICTING";
|
|
92638
|
+
if (mr.detailed_merge_status === "conflict")
|
|
92639
|
+
return "CONFLICTING";
|
|
92640
|
+
if (detail.merge_status === "cannot_be_merged")
|
|
92641
|
+
return "CONFLICTING";
|
|
92642
|
+
if (mr.detailed_merge_status === "mergeable")
|
|
92643
|
+
return "MERGEABLE";
|
|
92644
|
+
if (detail.merge_status === "can_be_merged")
|
|
92645
|
+
return "MERGEABLE";
|
|
92646
|
+
return "UNKNOWN";
|
|
92647
|
+
}
|
|
92648
|
+
function mapPipelineConclusion(status) {
|
|
92649
|
+
if (status === "success")
|
|
92650
|
+
return "success";
|
|
92651
|
+
if (status === "failed")
|
|
92652
|
+
return "failure";
|
|
92653
|
+
return null;
|
|
92654
|
+
}
|
|
92655
|
+
async function getMRPollSnapshot(input) {
|
|
92656
|
+
const overlay = glabSpawnEnv(input);
|
|
92657
|
+
const glabBinary = _internals100.resolveGlabExecutable();
|
|
92658
|
+
let viewStdout;
|
|
92659
|
+
try {
|
|
92660
|
+
viewStdout = await _internals100.forgeExecAsync(glabBinary, ["mr", "view", String(input.iid), "-R", input.projectPath, "-F", "json"], input.cwd, "glab", overlay);
|
|
92661
|
+
} catch (err) {
|
|
92662
|
+
throw new Error(`Failed to fetch MR view for ${input.projectPath}!${input.iid}: ${err instanceof Error ? err.message : String(err)}`);
|
|
92663
|
+
}
|
|
92664
|
+
const mr = JSON.parse(viewStdout);
|
|
92665
|
+
let detailStdout;
|
|
92666
|
+
try {
|
|
92667
|
+
detailStdout = await _internals100.forgeExecAsync(glabBinary, [
|
|
92668
|
+
"api",
|
|
92669
|
+
`projects/${encodeURIComponent(input.projectPath)}/merge_requests/${input.iid}`
|
|
92670
|
+
], input.cwd, "glab", overlay);
|
|
92671
|
+
} catch (err) {
|
|
92672
|
+
throw new Error(`Failed to fetch MR detail for ${input.projectPath}!${input.iid}: ${err instanceof Error ? err.message : String(err)}`);
|
|
92673
|
+
}
|
|
92674
|
+
const detail = JSON.parse(detailStdout);
|
|
92675
|
+
let pipelines = [];
|
|
92676
|
+
let pipelinesFetchSucceeded = false;
|
|
92677
|
+
try {
|
|
92678
|
+
const pipelinesStdout = await _internals100.forgeExecAsync(glabBinary, [
|
|
92679
|
+
"api",
|
|
92680
|
+
`projects/${encodeURIComponent(input.projectPath)}/merge_requests/${input.iid}/pipelines?per_page=20`
|
|
92681
|
+
], input.cwd, "glab", overlay);
|
|
92682
|
+
const rawPipelines = JSON.parse(pipelinesStdout);
|
|
92683
|
+
const headSha = typeof mr.sha === "string" ? mr.sha : "";
|
|
92684
|
+
const forHead = rawPipelines.filter((p) => typeof p.sha === "string" && p.sha === headSha).sort((a, b) => (Number(b.id) || 0) - (Number(a.id) || 0));
|
|
92685
|
+
const latest = forHead[0];
|
|
92686
|
+
const conclusion = mapPipelineConclusion(latest?.status);
|
|
92687
|
+
pipelines = latest && conclusion ? [
|
|
92688
|
+
{
|
|
92689
|
+
name: `pipeline #${String(latest.id ?? "")}`,
|
|
92690
|
+
status: "completed",
|
|
92691
|
+
conclusion,
|
|
92692
|
+
...typeof latest.web_url === "string" ? { detailsUrl: latest.web_url } : {}
|
|
92693
|
+
}
|
|
92694
|
+
] : [];
|
|
92695
|
+
pipelinesFetchSucceeded = true;
|
|
92696
|
+
} catch {
|
|
92697
|
+
pipelines = [];
|
|
92698
|
+
pipelinesFetchSucceeded = false;
|
|
92699
|
+
}
|
|
92700
|
+
const state = mapMrState(mr.state);
|
|
92701
|
+
const mergeable = mapMrMergeable(mr, detail);
|
|
92702
|
+
const reviewers = Array.isArray(mr.reviewers) ? mr.reviewers.length : 0;
|
|
92703
|
+
return {
|
|
92704
|
+
status: {
|
|
92705
|
+
number: input.iid,
|
|
92706
|
+
state,
|
|
92707
|
+
mergeable,
|
|
92708
|
+
mergeStateStatus: MR_SYNTHESIZED_FIELD_MARKER,
|
|
92709
|
+
headRefOid: typeof mr.sha === "string" ? mr.sha : "",
|
|
92710
|
+
statusCheckRollup: []
|
|
92711
|
+
},
|
|
92712
|
+
comments: [],
|
|
92713
|
+
merge: {
|
|
92714
|
+
mergeable,
|
|
92715
|
+
mergeStateStatus: MR_SYNTHESIZED_FIELD_MARKER,
|
|
92716
|
+
headRefOid: typeof mr.sha === "string" ? mr.sha : ""
|
|
92717
|
+
},
|
|
92718
|
+
review: {
|
|
92719
|
+
reviewDecision: "",
|
|
92720
|
+
reviewRequestCount: reviewers
|
|
92721
|
+
},
|
|
92722
|
+
pipelines,
|
|
92723
|
+
pipelinesFetchSucceeded
|
|
92724
|
+
};
|
|
92725
|
+
}
|
|
92726
|
+
async function getMRComments(input) {
|
|
92727
|
+
let stdout;
|
|
92728
|
+
try {
|
|
92729
|
+
stdout = await _internals100.forgeExecAsync(_internals100.resolveGlabExecutable(), [
|
|
92730
|
+
"api",
|
|
92731
|
+
`projects/${encodeURIComponent(input.projectPath)}/merge_requests/${input.iid}/notes?per_page=100&sort=asc&order_by=created_at`
|
|
92732
|
+
], input.cwd, "glab", glabSpawnEnv(input));
|
|
92733
|
+
} catch (err) {
|
|
92734
|
+
throw new Error(`Failed to fetch MR comments for ${input.projectPath}!${input.iid}: ${err instanceof Error ? err.message : String(err)}`);
|
|
92735
|
+
}
|
|
92736
|
+
const notes = JSON.parse(stdout);
|
|
92737
|
+
return notes.filter((note) => note.system !== true).map((note) => ({
|
|
92738
|
+
id: String(note.id ?? ""),
|
|
92739
|
+
author: String(note.author?.username ?? ""),
|
|
92740
|
+
body: neutralizeUntrustedMarkdown(String(note.body ?? ""), "GitLab MR note"),
|
|
92741
|
+
createdAt: String(note.created_at ?? ""),
|
|
92742
|
+
isReviewComment: false
|
|
92743
|
+
}));
|
|
92744
|
+
}
|
|
92344
92745
|
async function getMergeGroupRun(statusCheckRollup, repoFullName, cwd) {
|
|
92345
92746
|
const mergeGroupCheck = statusCheckRollup.find((check) => check.name === "Merge pull request" && check.detailsUrl);
|
|
92346
92747
|
if (!mergeGroupCheck?.detailsUrl) {
|
|
@@ -92353,7 +92754,7 @@ async function getMergeGroupRun(statusCheckRollup, repoFullName, cwd) {
|
|
|
92353
92754
|
const runId = runIdMatch[1];
|
|
92354
92755
|
let stdout;
|
|
92355
92756
|
try {
|
|
92356
|
-
stdout = await
|
|
92757
|
+
stdout = await _internals100.ghExecAsync([
|
|
92357
92758
|
"run",
|
|
92358
92759
|
"view",
|
|
92359
92760
|
runId,
|
|
@@ -92382,7 +92783,7 @@ var registrationsByCanonical = new Map;
|
|
|
92382
92783
|
function resolveRegistration(directory) {
|
|
92383
92784
|
const lexical = canonicalRootKeyLexical(directory);
|
|
92384
92785
|
try {
|
|
92385
|
-
const freshKey =
|
|
92786
|
+
const freshKey = _internals101.canonicalRootKeyFresh(directory);
|
|
92386
92787
|
const canonical = registrationsByCanonical.get(freshKey);
|
|
92387
92788
|
if (canonical)
|
|
92388
92789
|
return canonical;
|
|
@@ -92404,8 +92805,10 @@ async function evaluatePrFeedbackCurrentHead(directory, repoFullName, prNumber)
|
|
|
92404
92805
|
async function dispatchPrFeedbackOversight(input) {
|
|
92405
92806
|
return await getPrFeedbackLoopRuntime(input.directory)?.dispatchOversight(input) ?? { dispatched: false, verdict: "unavailable", decision: "pending" };
|
|
92406
92807
|
}
|
|
92407
|
-
var
|
|
92808
|
+
var _internals101 = {
|
|
92408
92809
|
getPRPollSnapshot,
|
|
92810
|
+
getMRPollSnapshot,
|
|
92811
|
+
findSubscriptionRecordForPrUrl,
|
|
92409
92812
|
dispatchEphemeralAgent,
|
|
92410
92813
|
parseCriticResponseFields,
|
|
92411
92814
|
canonicalRootKeyFresh,
|
|
@@ -92414,11 +92817,11 @@ var _internals100 = {
|
|
|
92414
92817
|
};
|
|
92415
92818
|
|
|
92416
92819
|
// src/background/pr-feedback-loop.ts
|
|
92417
|
-
var PR_FEEDBACK_LOOP_STATE_REL =
|
|
92820
|
+
var PR_FEEDBACK_LOOP_STATE_REL = path128.join(".swarm", "pr-feedback-loop-state.json");
|
|
92418
92821
|
var PR_FEEDBACK_CLEANUP_DIR = "pr-feedback-loop-cleanups";
|
|
92419
|
-
var PR_FEEDBACK_EVIDENCE_DIR =
|
|
92822
|
+
var PR_FEEDBACK_EVIDENCE_DIR = path128.join(".swarm", "pr-feedback-evidence");
|
|
92420
92823
|
var PR_FEEDBACK_LOOP_STATE_LOCK_FILENAME = "pr-feedback-loop-state.lock";
|
|
92421
|
-
var PR_FEEDBACK_LOOP_STATE_LOCK_REL =
|
|
92824
|
+
var PR_FEEDBACK_LOOP_STATE_LOCK_REL = path128.join(".swarm", PR_FEEDBACK_LOOP_STATE_LOCK_FILENAME);
|
|
92422
92825
|
var MAX_TRACKED_SESSIONS5 = 200;
|
|
92423
92826
|
var MAX_IN_FLIGHT_SESSIONS = 64;
|
|
92424
92827
|
var MAX_CANCELLATION_REQUESTS = 64;
|
|
@@ -92434,7 +92837,7 @@ var LoopStateSchema = exports_external.object({
|
|
|
92434
92837
|
correlations: exports_external.record(exports_external.string(), exports_external.any()),
|
|
92435
92838
|
sessionTerminals: exports_external.record(exports_external.string(), exports_external.any()).default({})
|
|
92436
92839
|
});
|
|
92437
|
-
var
|
|
92840
|
+
var _internals102 = {
|
|
92438
92841
|
async evaluateCurrentHead(directory, repoFullName, prNumber) {
|
|
92439
92842
|
return evaluatePrFeedbackCurrentHead(directory, repoFullName, prNumber);
|
|
92440
92843
|
},
|
|
@@ -92443,13 +92846,20 @@ var _internals101 = {
|
|
|
92443
92846
|
},
|
|
92444
92847
|
async performAuthorizedAction(input) {
|
|
92445
92848
|
try {
|
|
92849
|
+
const subscription = await findSubscriptionRecordForPrUrl(input.directory, {
|
|
92850
|
+
prUrl: input.event.prUrl,
|
|
92851
|
+
repoFullName: input.event.repoFullName,
|
|
92852
|
+
prNumber: input.event.prNumber,
|
|
92853
|
+
sessionID: input.sessionID
|
|
92854
|
+
});
|
|
92446
92855
|
await activatePrWorkflow(input.directory, input.sessionID, "PR_FEEDBACK", {
|
|
92447
92856
|
requireCheckoutPreflight: true,
|
|
92448
|
-
prUrl: input.event.prUrl
|
|
92857
|
+
prUrl: input.event.prUrl,
|
|
92858
|
+
forge: subscription?.forge
|
|
92449
92859
|
});
|
|
92450
92860
|
return {
|
|
92451
92861
|
performed: true,
|
|
92452
|
-
recordPath:
|
|
92862
|
+
recordPath: path128.join(".swarm", "pr-feedback-loop-state.json")
|
|
92453
92863
|
};
|
|
92454
92864
|
} catch (err) {
|
|
92455
92865
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -92471,13 +92881,13 @@ var _internals101 = {
|
|
|
92471
92881
|
listActive,
|
|
92472
92882
|
isProcessAlive: isProcessAlive3,
|
|
92473
92883
|
resetLoopStateLock() {
|
|
92474
|
-
|
|
92884
|
+
_internals102.beforeLoopStateLockWrite = undefined;
|
|
92475
92885
|
},
|
|
92476
92886
|
loopStateLockRelativePath: () => PR_FEEDBACK_LOOP_STATE_LOCK_REL,
|
|
92477
92887
|
reclaimAbandonedLoopStateLock,
|
|
92478
92888
|
removeLoopStateLockIfOwned
|
|
92479
92889
|
};
|
|
92480
|
-
var defaultLoopInternals = { ...
|
|
92890
|
+
var defaultLoopInternals = { ..._internals102 };
|
|
92481
92891
|
function emptyState2() {
|
|
92482
92892
|
return {
|
|
92483
92893
|
schemaVersion: 1,
|
|
@@ -92553,7 +92963,7 @@ function hasReservationIdentity(reservation) {
|
|
|
92553
92963
|
return Boolean(reservation?.workflowInstanceId.trim() && Number.isInteger(reservation?.ownerPid) && (reservation?.ownerPid ?? 0) > 0);
|
|
92554
92964
|
}
|
|
92555
92965
|
async function readLoopState(directory) {
|
|
92556
|
-
const file =
|
|
92966
|
+
const file = path128.join(directory, PR_FEEDBACK_LOOP_STATE_REL);
|
|
92557
92967
|
try {
|
|
92558
92968
|
const raw = fsSync9.readFileSync(file, "utf-8");
|
|
92559
92969
|
const parsed = LoopStateSchema.safeParse(JSON.parse(raw));
|
|
@@ -92584,7 +92994,7 @@ async function writeLoopState(directory, state) {
|
|
|
92584
92994
|
}
|
|
92585
92995
|
}
|
|
92586
92996
|
state.updatedAt = new Date().toISOString();
|
|
92587
|
-
await writePrWorkflowAtomicJson(directory, validateSwarmPath(directory,
|
|
92997
|
+
await writePrWorkflowAtomicJson(directory, validateSwarmPath(directory, path128.basename(PR_FEEDBACK_LOOP_STATE_REL)), state);
|
|
92588
92998
|
}
|
|
92589
92999
|
async function withLoopStateLock(directory, fn) {
|
|
92590
93000
|
const lock = await acquireLoopStateLock(directory);
|
|
@@ -92599,21 +93009,21 @@ async function acquireLoopStateLock(directory) {
|
|
|
92599
93009
|
const verifiedStateDirectory = await ensurePrWorkflowSafeParentDirectory(directory, lockPath);
|
|
92600
93010
|
for (let attempt = 0;attempt < LOOP_STATE_LOCK_MAX_ATTEMPTS; attempt++) {
|
|
92601
93011
|
try {
|
|
92602
|
-
const handle = await
|
|
93012
|
+
const handle = await fs64.open(lockPath, "wx");
|
|
92603
93013
|
const lock = {
|
|
92604
93014
|
ownerToken: randomUUID22(),
|
|
92605
93015
|
pid: process.pid,
|
|
92606
|
-
createdAtMs:
|
|
93016
|
+
createdAtMs: _internals102.now()
|
|
92607
93017
|
};
|
|
92608
93018
|
let writeError;
|
|
92609
93019
|
try {
|
|
92610
|
-
await
|
|
93020
|
+
await _internals102.beforeLoopStateLockWrite?.();
|
|
92611
93021
|
const [openedStat, pathStat, realLockPath] = await Promise.all([
|
|
92612
93022
|
handle.stat({ bigint: true }),
|
|
92613
|
-
|
|
92614
|
-
|
|
93023
|
+
fs64.lstat(lockPath, { bigint: true }),
|
|
93024
|
+
fs64.realpath(lockPath)
|
|
92615
93025
|
]);
|
|
92616
|
-
if (!openedStat.isFile() || pathStat.isSymbolicLink() || !pathStat.isFile() || !sameFileIdentity4(openedStat, pathStat) || normalizeComparablePath2(
|
|
93026
|
+
if (!openedStat.isFile() || pathStat.isSymbolicLink() || !pathStat.isFile() || !sameFileIdentity4(openedStat, pathStat) || normalizeComparablePath2(path128.dirname(realLockPath)) !== normalizeComparablePath2(verifiedStateDirectory)) {
|
|
92617
93027
|
throw new Error("BLOCKED: PR feedback loop state lock changed or escaped before initialization");
|
|
92618
93028
|
}
|
|
92619
93029
|
await handle.writeFile(JSON.stringify(lock), "utf8");
|
|
@@ -92654,17 +93064,17 @@ async function reclaimAbandonedLoopStateLock(lockPath) {
|
|
|
92654
93064
|
lock = null;
|
|
92655
93065
|
}
|
|
92656
93066
|
if (lock) {
|
|
92657
|
-
if (
|
|
93067
|
+
if (_internals102.isProcessAlive(lock.pid) && _internals102.now() - lock.createdAtMs < LOOP_STATE_LOCK_ALIVE_OWNER_STALE_MS) {
|
|
92658
93068
|
return false;
|
|
92659
93069
|
}
|
|
92660
93070
|
return removeLoopStateLockIfOwned(lockPath, lock.ownerToken);
|
|
92661
93071
|
}
|
|
92662
93072
|
try {
|
|
92663
|
-
const stat14 = await
|
|
92664
|
-
if (
|
|
93073
|
+
const stat14 = await fs64.stat(lockPath);
|
|
93074
|
+
if (_internals102.now() - stat14.mtimeMs < LOOP_STATE_LOCK_UNINITIALIZED_STALE_MS) {
|
|
92665
93075
|
return false;
|
|
92666
93076
|
}
|
|
92667
|
-
await
|
|
93077
|
+
await fs64.rm(lockPath, { force: true });
|
|
92668
93078
|
return true;
|
|
92669
93079
|
} catch (error2) {
|
|
92670
93080
|
if (error2.code === "ENOENT")
|
|
@@ -92675,7 +93085,7 @@ async function reclaimAbandonedLoopStateLock(lockPath) {
|
|
|
92675
93085
|
async function readLoopStateLock(lockPath) {
|
|
92676
93086
|
let raw;
|
|
92677
93087
|
try {
|
|
92678
|
-
raw = await
|
|
93088
|
+
raw = await fs64.readFile(lockPath, "utf8");
|
|
92679
93089
|
} catch (error2) {
|
|
92680
93090
|
if (error2.code === "ENOENT")
|
|
92681
93091
|
return null;
|
|
@@ -92699,7 +93109,7 @@ async function removeLoopStateLockIfOwned(lockPath, ownerToken) {
|
|
|
92699
93109
|
if (!lock || lock.ownerToken !== ownerToken)
|
|
92700
93110
|
return false;
|
|
92701
93111
|
try {
|
|
92702
|
-
await
|
|
93112
|
+
await fs64.rm(lockPath);
|
|
92703
93113
|
return true;
|
|
92704
93114
|
} catch {
|
|
92705
93115
|
return false;
|
|
@@ -92717,7 +93127,7 @@ function sameFileIdentity4(left, right) {
|
|
|
92717
93127
|
return left.dev === right.dev && left.ino === right.ino;
|
|
92718
93128
|
}
|
|
92719
93129
|
function normalizeComparablePath2(value) {
|
|
92720
|
-
const normalized =
|
|
93130
|
+
const normalized = path128.normalize(path128.resolve(value));
|
|
92721
93131
|
return process.platform === "win32" ? normalized.toLowerCase() : normalized;
|
|
92722
93132
|
}
|
|
92723
93133
|
function delay3(ms) {
|
|
@@ -92821,14 +93231,14 @@ async function cancelPrFeedbackLoopUnlocked(directory, sessionID, reason) {
|
|
|
92821
93231
|
clearedEvents: []
|
|
92822
93232
|
};
|
|
92823
93233
|
try {
|
|
92824
|
-
const { cancelPrFeedbackPublication: cancelPrFeedbackPublication2 } = await import("./pr-workflow-gate-
|
|
93234
|
+
const { cancelPrFeedbackPublication: cancelPrFeedbackPublication2 } = await import("./pr-workflow-gate-tdj50p2g.js");
|
|
92825
93235
|
await cancelPrFeedbackPublication2(directory, sessionID, reason);
|
|
92826
93236
|
} catch (err) {
|
|
92827
93237
|
warn(`[pr-feedback-loop] cancelPrFeedbackPublication failed (fail-open): ${err instanceof Error ? err.message : String(err)}`);
|
|
92828
93238
|
}
|
|
92829
93239
|
try {
|
|
92830
93240
|
await withLoopStateLock(directory, async () => {
|
|
92831
|
-
const readResult = await
|
|
93241
|
+
const readResult = await _internals102.readState(directory);
|
|
92832
93242
|
if (isCorruptState(readResult)) {
|
|
92833
93243
|
throw new Error("BLOCKED: loop state is corrupt during durable cancellation admission");
|
|
92834
93244
|
}
|
|
@@ -92841,7 +93251,7 @@ async function cancelPrFeedbackLoopUnlocked(directory, sessionID, reason) {
|
|
|
92841
93251
|
correlation.terminal = { state: "cancelled", reason };
|
|
92842
93252
|
}
|
|
92843
93253
|
const inFlight = correlation.inFlight;
|
|
92844
|
-
const ownerAlive = inFlight && hasReservationIdentity(inFlight) ?
|
|
93254
|
+
const ownerAlive = inFlight && hasReservationIdentity(inFlight) ? _internals102.isProcessAlive(inFlight.ownerPid) : false;
|
|
92845
93255
|
const reclaimedReservation = Boolean(inFlight && (inFlight.actionStartedAt === undefined || !ownerAlive));
|
|
92846
93256
|
if (reclaimedReservation) {
|
|
92847
93257
|
correlation.inFlight = null;
|
|
@@ -92856,7 +93266,7 @@ async function cancelPrFeedbackLoopUnlocked(directory, sessionID, reason) {
|
|
|
92856
93266
|
reason
|
|
92857
93267
|
};
|
|
92858
93268
|
}
|
|
92859
|
-
await
|
|
93269
|
+
await _internals102.writeState(directory, nextState);
|
|
92860
93270
|
return nextState;
|
|
92861
93271
|
});
|
|
92862
93272
|
} catch (err) {
|
|
@@ -92877,12 +93287,12 @@ async function cancelPrFeedbackLoopUnlocked(directory, sessionID, reason) {
|
|
|
92877
93287
|
}
|
|
92878
93288
|
}
|
|
92879
93289
|
const stamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
92880
|
-
receipt.path =
|
|
93290
|
+
receipt.path = path128.join(".swarm", PR_FEEDBACK_CLEANUP_DIR, `cancel-${stamp}.json`);
|
|
92881
93291
|
try {
|
|
92882
|
-
fsSync9.mkdirSync(
|
|
93292
|
+
fsSync9.mkdirSync(path128.join(directory, ".swarm", PR_FEEDBACK_CLEANUP_DIR), {
|
|
92883
93293
|
recursive: true
|
|
92884
93294
|
});
|
|
92885
|
-
fsSync9.writeFileSync(
|
|
93295
|
+
fsSync9.writeFileSync(path128.join(directory, receipt.path), JSON.stringify({
|
|
92886
93296
|
schemaVersion: 1,
|
|
92887
93297
|
at: new Date().toISOString(),
|
|
92888
93298
|
sessionID,
|
|
@@ -92934,228 +93344,6 @@ ${USAGE14}`;
|
|
|
92934
93344
|
|
|
92935
93345
|
// src/background/pr-monitor-worker.ts
|
|
92936
93346
|
init_warning_buffer();
|
|
92937
|
-
|
|
92938
|
-
// src/utils/glab-executable.ts
|
|
92939
|
-
init_warning_buffer();
|
|
92940
|
-
import { spawnSync as spawnSync6 } from "child_process";
|
|
92941
|
-
import * as fs64 from "fs";
|
|
92942
|
-
import * as os14 from "os";
|
|
92943
|
-
import * as path128 from "path";
|
|
92944
|
-
var GLAB_BINARY_ENV_VAR = "OPENCODE_SWARM_GLAB_BINARY";
|
|
92945
|
-
var PER_PROBE_TIMEOUT_MS2 = 250;
|
|
92946
|
-
var TOTAL_BUDGET_MS3 = 1000;
|
|
92947
|
-
var NEGATIVE_CACHE_TTL_MS2 = 60000;
|
|
92948
|
-
var BARE_GLAB = "glab";
|
|
92949
|
-
var PROBE_MAX_BUFFER_BYTES2 = 64 * 1024;
|
|
92950
|
-
var PROBE_OUTPUT_EXCERPT_CHARS2 = 60;
|
|
92951
|
-
var WINDOWS_PATH_EXTENSIONS2 = [".exe", ".cmd", ".bat"];
|
|
92952
|
-
var GLAB_VERSION_PATTERN = /^glab version \d+\.\d+/;
|
|
92953
|
-
function excerptProbeOutput2(raw) {
|
|
92954
|
-
return raw.slice(0, PROBE_OUTPUT_EXCERPT_CHARS2).replace(/[^\x20-\x7E]/g, " ").trim();
|
|
92955
|
-
}
|
|
92956
|
-
var cache3 = null;
|
|
92957
|
-
var lastAttempts2 = [];
|
|
92958
|
-
var cacheGeneration2 = 0;
|
|
92959
|
-
function windowsGlabAbsoluteCandidates(env) {
|
|
92960
|
-
const candidates = [];
|
|
92961
|
-
const push = (...parts) => {
|
|
92962
|
-
const candidate2 = path128.join(...parts);
|
|
92963
|
-
if (!candidates.includes(candidate2))
|
|
92964
|
-
candidates.push(candidate2);
|
|
92965
|
-
};
|
|
92966
|
-
if (env.ProgramFiles) {
|
|
92967
|
-
push(env.ProgramFiles, "GitLab CLI", "glab.exe");
|
|
92968
|
-
}
|
|
92969
|
-
if (env["ProgramFiles(x86)"]) {
|
|
92970
|
-
push(env["ProgramFiles(x86)"], "GitLab CLI", "glab.exe");
|
|
92971
|
-
}
|
|
92972
|
-
if (env.LOCALAPPDATA) {
|
|
92973
|
-
push(env.LOCALAPPDATA, "GitLab CLI", "glab.exe");
|
|
92974
|
-
push(env.LOCALAPPDATA, "Programs", "GitLab CLI", "glab.exe");
|
|
92975
|
-
}
|
|
92976
|
-
return candidates;
|
|
92977
|
-
}
|
|
92978
|
-
function platformCandidates2(platform, env) {
|
|
92979
|
-
if (platform === "win32") {
|
|
92980
|
-
return windowsGlabAbsoluteCandidates(env);
|
|
92981
|
-
}
|
|
92982
|
-
if (platform === "darwin") {
|
|
92983
|
-
return ["/opt/homebrew/bin/glab", "/usr/local/bin/glab", "/usr/bin/glab"];
|
|
92984
|
-
}
|
|
92985
|
-
return ["/usr/bin/glab", "/usr/local/bin/glab", "/bin/glab"];
|
|
92986
|
-
}
|
|
92987
|
-
function isAbsoluteForPlatform2(candidate2, platform) {
|
|
92988
|
-
return platform === "win32" ? path128.win32.isAbsolute(candidate2) : path128.posix.isAbsolute(candidate2);
|
|
92989
|
-
}
|
|
92990
|
-
function joinDirAndName2(dir, name, platform) {
|
|
92991
|
-
const sep22 = platform === "win32" ? "\\" : "/";
|
|
92992
|
-
const trimmed = dir.replace(/[\\/]+$/, "");
|
|
92993
|
-
return trimmed ? `${trimmed}${sep22}${name}` : `${sep22}${name}`;
|
|
92994
|
-
}
|
|
92995
|
-
function pathCandidates2(platform) {
|
|
92996
|
-
const pathValue = _internals102.env().PATH ?? "";
|
|
92997
|
-
if (!pathValue)
|
|
92998
|
-
return [];
|
|
92999
|
-
const dirs = pathValue.split(platform === "win32" ? ";" : ":").filter(Boolean);
|
|
93000
|
-
const names = platform === "win32" ? [...WINDOWS_PATH_EXTENSIONS2.map((ext) => `glab${ext}`), "glab"] : ["glab"];
|
|
93001
|
-
const out = [];
|
|
93002
|
-
for (const dir of dirs) {
|
|
93003
|
-
for (const name of names) {
|
|
93004
|
-
const candidate2 = joinDirAndName2(dir, name, platform);
|
|
93005
|
-
if (!out.includes(candidate2))
|
|
93006
|
-
out.push(candidate2);
|
|
93007
|
-
}
|
|
93008
|
-
}
|
|
93009
|
-
return out;
|
|
93010
|
-
}
|
|
93011
|
-
function envOverride2() {
|
|
93012
|
-
const raw = _internals102.env()[GLAB_BINARY_ENV_VAR];
|
|
93013
|
-
return raw && raw.trim() !== "" ? raw : undefined;
|
|
93014
|
-
}
|
|
93015
|
-
function buildCandidates2(platform) {
|
|
93016
|
-
const override = envOverride2();
|
|
93017
|
-
const overrideCandidate = override ? [{ source: "override", path: override }] : [];
|
|
93018
|
-
const seen = new Set(overrideCandidate.map((c) => c.path));
|
|
93019
|
-
const rest = [];
|
|
93020
|
-
for (const p of platformCandidates2(platform, _internals102.env())) {
|
|
93021
|
-
if (seen.has(p))
|
|
93022
|
-
continue;
|
|
93023
|
-
seen.add(p);
|
|
93024
|
-
rest.push({ source: "platform", path: p });
|
|
93025
|
-
}
|
|
93026
|
-
for (const p of pathCandidates2(platform)) {
|
|
93027
|
-
if (seen.has(p))
|
|
93028
|
-
continue;
|
|
93029
|
-
seen.add(p);
|
|
93030
|
-
rest.push({ source: "path", path: p });
|
|
93031
|
-
}
|
|
93032
|
-
return [...overrideCandidate, ...rest];
|
|
93033
|
-
}
|
|
93034
|
-
function probeCandidate2(candidatePath2, platform) {
|
|
93035
|
-
if (!isAbsoluteForPlatform2(candidatePath2, platform)) {
|
|
93036
|
-
return { accepted: false, reason: "not an absolute path" };
|
|
93037
|
-
}
|
|
93038
|
-
let stat14;
|
|
93039
|
-
try {
|
|
93040
|
-
stat14 = fs64.statSync(candidatePath2);
|
|
93041
|
-
} catch (err) {
|
|
93042
|
-
const code = err?.code;
|
|
93043
|
-
if (code === "ENOENT")
|
|
93044
|
-
return { accepted: false, reason: "no such file" };
|
|
93045
|
-
return {
|
|
93046
|
-
accepted: false,
|
|
93047
|
-
reason: `cannot stat (${code ?? "unknown error"})`
|
|
93048
|
-
};
|
|
93049
|
-
}
|
|
93050
|
-
if (stat14.isDirectory()) {
|
|
93051
|
-
return { accepted: false, reason: "is a directory" };
|
|
93052
|
-
}
|
|
93053
|
-
if (!stat14.isFile()) {
|
|
93054
|
-
return { accepted: false, reason: "not a regular file" };
|
|
93055
|
-
}
|
|
93056
|
-
let result;
|
|
93057
|
-
try {
|
|
93058
|
-
result = _internals102.spawnSync(candidatePath2, ["--version"], {
|
|
93059
|
-
cwd: os14.tmpdir(),
|
|
93060
|
-
stdio: ["ignore", "pipe", "ignore"],
|
|
93061
|
-
windowsHide: true,
|
|
93062
|
-
timeout: PER_PROBE_TIMEOUT_MS2,
|
|
93063
|
-
maxBuffer: PROBE_MAX_BUFFER_BYTES2
|
|
93064
|
-
});
|
|
93065
|
-
} catch (err) {
|
|
93066
|
-
return {
|
|
93067
|
-
accepted: false,
|
|
93068
|
-
reason: `spawn threw: ${err instanceof Error ? err.message : String(err)}`
|
|
93069
|
-
};
|
|
93070
|
-
}
|
|
93071
|
-
if (result.error) {
|
|
93072
|
-
return { accepted: false, reason: `spawn failed: ${result.error.message}` };
|
|
93073
|
-
}
|
|
93074
|
-
if (result.status !== 0) {
|
|
93075
|
-
const statusDescription = result.status !== null ? `exit ${result.status}` : `signal ${result.signal ?? "unknown"}`;
|
|
93076
|
-
return {
|
|
93077
|
-
accepted: false,
|
|
93078
|
-
reason: `glab --version returned ${statusDescription}`
|
|
93079
|
-
};
|
|
93080
|
-
}
|
|
93081
|
-
const versionOutput = (result.stdout ?? "").toString().trim();
|
|
93082
|
-
if (!GLAB_VERSION_PATTERN.test(versionOutput)) {
|
|
93083
|
-
const excerpt = excerptProbeOutput2(versionOutput);
|
|
93084
|
-
return {
|
|
93085
|
-
accepted: false,
|
|
93086
|
-
reason: excerpt ? `not glab: --version printed "${excerpt}"` : "not glab: --version printed nothing"
|
|
93087
|
-
};
|
|
93088
|
-
}
|
|
93089
|
-
return { accepted: true };
|
|
93090
|
-
}
|
|
93091
|
-
function probeCycle2(candidates, platform, attempts) {
|
|
93092
|
-
const start = _internals102.now();
|
|
93093
|
-
let budgetExceeded = false;
|
|
93094
|
-
for (const candidate2 of candidates) {
|
|
93095
|
-
if (_internals102.now() - start > TOTAL_BUDGET_MS3) {
|
|
93096
|
-
budgetExceeded = true;
|
|
93097
|
-
break;
|
|
93098
|
-
}
|
|
93099
|
-
const result = probeCandidate2(candidate2.path, platform);
|
|
93100
|
-
attempts.push({
|
|
93101
|
-
source: candidate2.source,
|
|
93102
|
-
candidate: candidate2.path,
|
|
93103
|
-
accepted: result.accepted,
|
|
93104
|
-
reason: result.accepted ? undefined : result.reason
|
|
93105
|
-
});
|
|
93106
|
-
if (candidate2.source === "override" && !result.accepted) {
|
|
93107
|
-
advisoryWarn(`[opencode-swarm] ${GLAB_BINARY_ENV_VAR} override "${candidate2.path}" is unusable (${result.reason}); falling back to automatic glab resolution.`);
|
|
93108
|
-
}
|
|
93109
|
-
if (result.accepted) {
|
|
93110
|
-
return { outcome: "accepted", path: candidate2.path };
|
|
93111
|
-
}
|
|
93112
|
-
}
|
|
93113
|
-
return budgetExceeded ? { outcome: "exhausted-budget" } : { outcome: "all-rejected" };
|
|
93114
|
-
}
|
|
93115
|
-
function readCache3() {
|
|
93116
|
-
if (cache3 === null)
|
|
93117
|
-
return null;
|
|
93118
|
-
if (cache3.kind === "success")
|
|
93119
|
-
return cache3;
|
|
93120
|
-
if (_internals102.now() < cache3.expiresAt)
|
|
93121
|
-
return cache3;
|
|
93122
|
-
cache3 = null;
|
|
93123
|
-
return null;
|
|
93124
|
-
}
|
|
93125
|
-
function applyProbeResult2(result, attempts, generation) {
|
|
93126
|
-
if (generation !== cacheGeneration2) {
|
|
93127
|
-
return result.outcome === "accepted" ? result.path : BARE_GLAB;
|
|
93128
|
-
}
|
|
93129
|
-
lastAttempts2 = attempts;
|
|
93130
|
-
if (result.outcome === "accepted") {
|
|
93131
|
-
cache3 = { kind: "success", path: result.path };
|
|
93132
|
-
return result.path;
|
|
93133
|
-
}
|
|
93134
|
-
cache3 = {
|
|
93135
|
-
kind: "fallback",
|
|
93136
|
-
expiresAt: _internals102.now() + NEGATIVE_CACHE_TTL_MS2
|
|
93137
|
-
};
|
|
93138
|
-
return BARE_GLAB;
|
|
93139
|
-
}
|
|
93140
|
-
function resolveGlabExecutable() {
|
|
93141
|
-
const cached = readCache3();
|
|
93142
|
-
if (cached)
|
|
93143
|
-
return cached.kind === "success" ? cached.path : BARE_GLAB;
|
|
93144
|
-
const platform = _internals102.platform();
|
|
93145
|
-
const attempts = [];
|
|
93146
|
-
const generation = cacheGeneration2;
|
|
93147
|
-
const candidates = buildCandidates2(platform);
|
|
93148
|
-
const result = probeCycle2(candidates, platform, attempts);
|
|
93149
|
-
return applyProbeResult2(result, attempts, generation);
|
|
93150
|
-
}
|
|
93151
|
-
var _internals102 = {
|
|
93152
|
-
spawnSync: spawnSync6,
|
|
93153
|
-
platform: () => process.platform,
|
|
93154
|
-
env: () => process.env,
|
|
93155
|
-
now: () => Date.now()
|
|
93156
|
-
};
|
|
93157
|
-
|
|
93158
|
-
// src/background/pr-monitor-worker.ts
|
|
93159
93347
|
var prMonitorWorkerRegistry = new Map;
|
|
93160
93348
|
function getPrMonitorWorkerHealth(directory) {
|
|
93161
93349
|
return prMonitorWorkerRegistry.get(directory)?.getHealth() ?? null;
|
|
@@ -93365,12 +93553,7 @@ class PrMonitorWorker {
|
|
|
93365
93553
|
async pollSinglePr(sub, isTimedOut, isProbe = false) {
|
|
93366
93554
|
const correlationId = sub.correlationId;
|
|
93367
93555
|
const forgeContext = detectForgeFromUrl(sub.prUrl) ?? (sub.forge ? { provider: sub.forge.provider, host: sub.forge.host } : null);
|
|
93368
|
-
|
|
93369
|
-
const glabBinary = resolveGlabExecutable();
|
|
93370
|
-
const glabStatus = glabBinary === "glab" ? "glab binary not resolved (bare-name fallback)" : "glab binary resolved";
|
|
93371
|
-
log("[PrMonitorWorker] GitLab MR monitoring unavailable: glab-backed polling is not wired yet (issue #2882); skipping gh poll for this subscription", { correlationId, glabStatus });
|
|
93372
|
-
return;
|
|
93373
|
-
}
|
|
93556
|
+
const isGitLab = forgeContext?.provider === "gitlab";
|
|
93374
93557
|
if (!this.circuitBreakerMap.has(correlationId) && sub.errorCount > 0) {
|
|
93375
93558
|
this.circuitBreakerMap.set(correlationId, {
|
|
93376
93559
|
errorCount: sub.errorCount,
|
|
@@ -93395,40 +93578,76 @@ class PrMonitorWorker {
|
|
|
93395
93578
|
return;
|
|
93396
93579
|
}
|
|
93397
93580
|
try {
|
|
93398
|
-
|
|
93399
|
-
|
|
93400
|
-
|
|
93401
|
-
|
|
93402
|
-
|
|
93403
|
-
|
|
93404
|
-
|
|
93581
|
+
let changes;
|
|
93582
|
+
if (isGitLab) {
|
|
93583
|
+
const glabBinary = resolveGlabExecutable();
|
|
93584
|
+
const glabStatus = glabBinary === "glab" ? "glab binary not resolved (bare-name fallback)" : "glab binary resolved";
|
|
93585
|
+
log("[PrMonitorWorker] Polling GitLab MR (glab-backed)", {
|
|
93586
|
+
correlationId,
|
|
93587
|
+
glabStatus
|
|
93405
93588
|
});
|
|
93406
|
-
|
|
93407
|
-
|
|
93408
|
-
|
|
93409
|
-
|
|
93410
|
-
|
|
93411
|
-
|
|
93412
|
-
|
|
93413
|
-
|
|
93414
|
-
|
|
93415
|
-
|
|
93416
|
-
|
|
93417
|
-
|
|
93418
|
-
|
|
93419
|
-
|
|
93420
|
-
|
|
93421
|
-
|
|
93589
|
+
const mrInput = {
|
|
93590
|
+
projectPath: sub.repoFullName,
|
|
93591
|
+
iid: sub.prNumber,
|
|
93592
|
+
cwd: this.directory,
|
|
93593
|
+
...forgeContext ? { host: forgeContext.host } : {}
|
|
93594
|
+
};
|
|
93595
|
+
const [mrSnapshot, mrComments] = await Promise.all([
|
|
93596
|
+
_internals103.getMRPollSnapshot(mrInput),
|
|
93597
|
+
_internals103.getMRComments(mrInput)
|
|
93598
|
+
]);
|
|
93599
|
+
if (isTimedOut?.()) {
|
|
93600
|
+
log("[PrMonitorWorker] Skipping late result \u2014 poll already timed out", {
|
|
93601
|
+
correlationId: sub.correlationId
|
|
93602
|
+
});
|
|
93603
|
+
return;
|
|
93604
|
+
}
|
|
93605
|
+
changes = this.computeChanges(sub, {
|
|
93606
|
+
status: mrSnapshot.status,
|
|
93607
|
+
comments: mrComments,
|
|
93608
|
+
merge: mrSnapshot.merge,
|
|
93609
|
+
review: mrSnapshot.review,
|
|
93610
|
+
mergeGroupRun: null
|
|
93611
|
+
}, true, {
|
|
93612
|
+
checks: mrSnapshot.pipelines,
|
|
93613
|
+
fetchSucceeded: mrSnapshot.pipelinesFetchSucceeded
|
|
93422
93614
|
});
|
|
93423
|
-
|
|
93615
|
+
} else {
|
|
93616
|
+
const [snapshot, reviewComments] = await Promise.all([
|
|
93617
|
+
_internals103.getPRPollSnapshot(sub.prNumber, sub.repoFullName, this.directory),
|
|
93618
|
+
_internals103.getPRReviewComments(sub.prNumber, sub.repoFullName, this.directory)
|
|
93619
|
+
]);
|
|
93620
|
+
if (isTimedOut?.()) {
|
|
93621
|
+
log("[PrMonitorWorker] Skipping late result \u2014 poll already timed out", {
|
|
93622
|
+
correlationId: sub.correlationId
|
|
93623
|
+
});
|
|
93624
|
+
return;
|
|
93625
|
+
}
|
|
93626
|
+
let mergeGroupRunResult = null;
|
|
93627
|
+
let mergeGroupRunFetchSucceeded = false;
|
|
93628
|
+
try {
|
|
93629
|
+
mergeGroupRunResult = await _internals103.getMergeGroupRun(snapshot.status.statusCheckRollup, sub.repoFullName, this.directory);
|
|
93630
|
+
mergeGroupRunFetchSucceeded = true;
|
|
93631
|
+
} catch (err) {
|
|
93632
|
+
log("[PrMonitorWorker] Failed to fetch merge group run", {
|
|
93633
|
+
correlationId: sub.correlationId,
|
|
93634
|
+
error: err instanceof Error ? err.message : String(err)
|
|
93635
|
+
});
|
|
93636
|
+
}
|
|
93637
|
+
if (isTimedOut?.()) {
|
|
93638
|
+
log("[PrMonitorWorker] Skipping late result \u2014 poll already timed out", {
|
|
93639
|
+
correlationId: sub.correlationId
|
|
93640
|
+
});
|
|
93641
|
+
return;
|
|
93642
|
+
}
|
|
93643
|
+
changes = this.computeChanges(sub, {
|
|
93644
|
+
status: snapshot.status,
|
|
93645
|
+
comments: [...snapshot.comments, ...reviewComments],
|
|
93646
|
+
merge: snapshot.merge,
|
|
93647
|
+
review: snapshot.review,
|
|
93648
|
+
mergeGroupRun: mergeGroupRunResult
|
|
93649
|
+
}, mergeGroupRunFetchSucceeded);
|
|
93424
93650
|
}
|
|
93425
|
-
const changes = this.computeChanges(sub, {
|
|
93426
|
-
status: snapshot.status,
|
|
93427
|
-
comments: [...snapshot.comments, ...reviewComments],
|
|
93428
|
-
merge: snapshot.merge,
|
|
93429
|
-
review: snapshot.review,
|
|
93430
|
-
mergeGroupRun: mergeGroupRunResult
|
|
93431
|
-
}, mergeGroupRunFetchSucceeded);
|
|
93432
93651
|
await this.applyChanges(sub, changes, isTimedOut);
|
|
93433
93652
|
if (!isTimedOut?.()) {
|
|
93434
93653
|
this.circuitBreakerMap.delete(correlationId);
|
|
@@ -93464,7 +93683,7 @@ class PrMonitorWorker {
|
|
|
93464
93683
|
await this.handlePollError(sub, err instanceof Error ? err : new Error(String(err)));
|
|
93465
93684
|
}
|
|
93466
93685
|
}
|
|
93467
|
-
computeChanges(sub, current, mergeGroupRunFetchSucceeded) {
|
|
93686
|
+
computeChanges(sub, current, mergeGroupRunFetchSucceeded, gitLabPipelines) {
|
|
93468
93687
|
const events = [];
|
|
93469
93688
|
const snapshotUpdates = {
|
|
93470
93689
|
headRefOid: current.status.headRefOid,
|
|
@@ -93491,13 +93710,17 @@ class PrMonitorWorker {
|
|
|
93491
93710
|
}
|
|
93492
93711
|
});
|
|
93493
93712
|
}
|
|
93494
|
-
const
|
|
93495
|
-
|
|
93496
|
-
if (
|
|
93497
|
-
const
|
|
93498
|
-
|
|
93713
|
+
const ciChecks = gitLabPipelines ? gitLabPipelines.checks : current.status.statusCheckRollup;
|
|
93714
|
+
const gitlabNoTerminalVerdict = gitLabPipelines !== undefined && gitLabPipelines.checks.length === 0;
|
|
93715
|
+
if (!gitlabNoTerminalVerdict && (!gitLabPipelines || gitLabPipelines.fetchSucceeded)) {
|
|
93716
|
+
const currentCheckSet = this.serializeChecks(ciChecks);
|
|
93717
|
+
snapshotUpdates.lastCheckRunSet = currentCheckSet;
|
|
93718
|
+
if (sub.lastCheckRunSet !== undefined && currentCheckSet !== sub.lastCheckRunSet) {
|
|
93719
|
+
const prevChecks = this.parseCheckSet(sub.lastCheckRunSet);
|
|
93720
|
+
this.computeCIEvents(sub, prevChecks, ciChecks, current.status.headRefOid, events);
|
|
93721
|
+
}
|
|
93722
|
+
snapshotUpdates.lastCheckRunSet = currentCheckSet;
|
|
93499
93723
|
}
|
|
93500
|
-
snapshotUpdates.lastCheckRunSet = currentCheckSet;
|
|
93501
93724
|
if (current.comments.length > 0) {
|
|
93502
93725
|
const sorted2 = [...current.comments].sort((a, b) => a.createdAt.localeCompare(b.createdAt));
|
|
93503
93726
|
let newComments;
|
|
@@ -93829,6 +94052,8 @@ class PrMonitorWorker {
|
|
|
93829
94052
|
var _internals103 = {
|
|
93830
94053
|
getPRPollSnapshot,
|
|
93831
94054
|
getPRReviewComments,
|
|
94055
|
+
getMRPollSnapshot,
|
|
94056
|
+
getMRComments,
|
|
93832
94057
|
getMergeGroupRun,
|
|
93833
94058
|
listActive,
|
|
93834
94059
|
updateSnapshot,
|
|
@@ -94192,11 +94417,10 @@ async function handlePrSubscribeCommand(directory, args, sessionID) {
|
|
|
94192
94417
|
deliveryLine
|
|
94193
94418
|
].concat(prUrl.includes("/-/merge_requests/") ? [
|
|
94194
94419
|
"",
|
|
94195
|
-
"Note: live monitoring is
|
|
94196
|
-
"
|
|
94197
|
-
"
|
|
94198
|
-
"
|
|
94199
|
-
"review events will be delivered until that lands."
|
|
94420
|
+
"Note: live GitLab MR monitoring is active (glab-backed:",
|
|
94421
|
+
"state, comments, and pipeline CI events). Review-decision",
|
|
94422
|
+
"and status-check rollup equivalents remain NOT AVAILABLE",
|
|
94423
|
+
"for GitLab \u2014 the monitor never fabricates them (issue #2733)."
|
|
94200
94424
|
] : []).join(`
|
|
94201
94425
|
`);
|
|
94202
94426
|
} catch (err) {
|
|
@@ -106632,7 +106856,7 @@ async function runValidationWithTransientRetry(input, candidateContent, baseline
|
|
|
106632
106856
|
if (!input.dispatcher) {
|
|
106633
106857
|
throw new Error("no evaluation dispatcher available (cannot run validation)");
|
|
106634
106858
|
}
|
|
106635
|
-
const { createModelEvaluationExecutor: createModelEvaluationExecutor2 } = await import("./runner-
|
|
106859
|
+
const { createModelEvaluationExecutor: createModelEvaluationExecutor2 } = await import("./runner-tb3eppeg.js");
|
|
106636
106860
|
const executor = createModelEvaluationExecutor2(input.dispatcher, input.sessionId);
|
|
106637
106861
|
const result = await withProtectedSetIntegrity([evalInputRoot, ...protectedRoots(input.directory)], () => _internals129.evaluateCandidateV1({
|
|
106638
106862
|
projectRoot: input.directory,
|
|
@@ -109261,7 +109485,7 @@ function buildDetailedHelp(commandName, entry) {
|
|
|
109261
109485
|
async function handleHelpCommand(ctx) {
|
|
109262
109486
|
const targetCommand = ctx.args.join(" ");
|
|
109263
109487
|
if (!targetCommand) {
|
|
109264
|
-
const { buildHelpText } = await import("./index-
|
|
109488
|
+
const { buildHelpText } = await import("./index-4dwhfbed.js");
|
|
109265
109489
|
return buildHelpText();
|
|
109266
109490
|
}
|
|
109267
109491
|
const tokens = targetCommand.split(/\s+/);
|
|
@@ -109275,7 +109499,7 @@ async function handleHelpCommand(ctx) {
|
|
|
109275
109499
|
> Note: \`/swarm ${resolved.key}\` is a deprecated alias for \`/swarm ${aliasTarget}\`.` : detailed;
|
|
109276
109500
|
}
|
|
109277
109501
|
const similar = _internals27.findSimilarCommands(targetCommand);
|
|
109278
|
-
const { buildHelpText: fullHelp } = await import("./index-
|
|
109502
|
+
const { buildHelpText: fullHelp } = await import("./index-4dwhfbed.js");
|
|
109279
109503
|
if (similar.length > 0) {
|
|
109280
109504
|
return `Command '/swarm ${targetCommand}' not found.
|
|
109281
109505
|
|
|
@@ -109310,6 +109534,18 @@ async function handleModeCommandWithBundledSkills(ctx, handler, mechanicalMode)
|
|
|
109310
109534
|
}
|
|
109311
109535
|
return result;
|
|
109312
109536
|
}
|
|
109537
|
+
function resolveCommandForgeContext(directory, prUrl) {
|
|
109538
|
+
if (detectForgeFromUrl(prUrl))
|
|
109539
|
+
return;
|
|
109540
|
+
try {
|
|
109541
|
+
const config = loadPluginConfig(directory);
|
|
109542
|
+
const remote = detectGitRemote(directory, undefined);
|
|
109543
|
+
const remotes = remote ? [remote] : [];
|
|
109544
|
+
return resolveForgeContextFromPluginConfig(config, remotes) ?? undefined;
|
|
109545
|
+
} catch {
|
|
109546
|
+
return;
|
|
109547
|
+
}
|
|
109548
|
+
}
|
|
109313
109549
|
async function handlePrFeedbackCommandWithTransition(ctx) {
|
|
109314
109550
|
if (ctx.packageRoot) {
|
|
109315
109551
|
await syncBundledProjectSkillsIfMissingAsync(ctx.directory, ctx.packageRoot, true);
|
|
@@ -109340,7 +109576,8 @@ async function handlePrFeedbackCommandWithTransition(ctx) {
|
|
|
109340
109576
|
} else {
|
|
109341
109577
|
await activatePrWorkflow(ctx.directory, ctx.sessionID, "PR_FEEDBACK", {
|
|
109342
109578
|
requireCheckoutPreflight: true,
|
|
109343
|
-
...parsed.prUrl ? { prUrl: parsed.prUrl } : {}
|
|
109579
|
+
...parsed.prUrl ? { prUrl: parsed.prUrl } : {},
|
|
109580
|
+
...parsed.prUrl ? { forge: resolveCommandForgeContext(ctx.directory, parsed.prUrl) } : {}
|
|
109344
109581
|
});
|
|
109345
109582
|
}
|
|
109346
109583
|
return handlePrFeedbackCommand(ctx.directory, ctx.args);
|
|
@@ -109590,7 +109827,7 @@ var COMMAND_REGISTRY = {
|
|
|
109590
109827
|
},
|
|
109591
109828
|
"guardrail explain": {
|
|
109592
109829
|
handler: async (ctx) => {
|
|
109593
|
-
const { handleGuardrailExplain } = await import("./guardrail-explain-
|
|
109830
|
+
const { handleGuardrailExplain } = await import("./guardrail-explain-njv3pnsw.js");
|
|
109594
109831
|
return handleGuardrailExplain(ctx.directory, ctx.args);
|
|
109595
109832
|
},
|
|
109596
109833
|
description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
|
|
@@ -109600,7 +109837,7 @@ var COMMAND_REGISTRY = {
|
|
|
109600
109837
|
},
|
|
109601
109838
|
"guardrail reset": {
|
|
109602
109839
|
handler: async (ctx) => {
|
|
109603
|
-
const { handleGuardrailReset } = await import("./guardrail-reset-
|
|
109840
|
+
const { handleGuardrailReset } = await import("./guardrail-reset-11cvwgbe.js");
|
|
109604
109841
|
return handleGuardrailReset(ctx.args, ctx.sessionID);
|
|
109605
109842
|
},
|
|
109606
109843
|
description: "Reset one exact active invocation/action circuit after repair",
|
|
@@ -109621,7 +109858,7 @@ var COMMAND_REGISTRY = {
|
|
|
109621
109858
|
},
|
|
109622
109859
|
"guardrail-log": {
|
|
109623
109860
|
handler: async (ctx) => {
|
|
109624
|
-
const { handleGuardrailLog } = await import("./guardrail-log-
|
|
109861
|
+
const { handleGuardrailLog } = await import("./guardrail-log-r8zmh4rd.js");
|
|
109625
109862
|
return handleGuardrailLog(ctx.directory, ctx.args);
|
|
109626
109863
|
},
|
|
109627
109864
|
description: "Read the guardrail decision log (use --blocks-only for blocks)",
|