opencode-swarm 7.185.1 → 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/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-subscriptions.d.ts +23 -0
- package/dist/cli/{auto-checkpoint-2jecngee.js → auto-checkpoint-wd99h2bt.js} +4 -4
- package/dist/cli/{checkpoint-qm05wdbh.js → checkpoint-kjzwsxw2.js} +8 -8
- package/dist/cli/{coder-settlement-56prayae.js → coder-settlement-kp3ph56n.js} +3 -3
- package/dist/cli/{config-doctor-3b99vx74.js → config-doctor-28ggsms8.js} +2 -2
- package/dist/cli/{core-cxnqsrxp.js → core-pj2fz34e.js} +1 -1
- package/dist/cli/{curator-drift-dt4g79a4.js → curator-drift-q84jn9cc.js} +5 -5
- package/dist/cli/{curator-llm-factory-hkk29g2y.js → curator-llm-factory-13h02244.js} +25 -25
- package/dist/cli/{curator-5k3mktpe.js → curator-r0jfc7xw.js} +25 -25
- package/dist/cli/{evidence-summary-service-8e2fghz0.js → evidence-summary-service-rsectw2t.js} +9 -9
- package/dist/cli/{gate-evidence-vk8rebsx.js → gate-evidence-mpwhcm2s.js} +2 -2
- package/dist/cli/{guardrail-explain-ma658hkw.js → guardrail-explain-njv3pnsw.js} +26 -26
- package/dist/cli/{guardrail-log-m6mydjet.js → guardrail-log-r8zmh4rd.js} +3 -3
- package/dist/cli/{guardrail-reset-w41yndke.js → guardrail-reset-11cvwgbe.js} +25 -25
- package/dist/cli/{hive-promoter-400xzdds.js → hive-promoter-0vg8w79a.js} +25 -25
- package/dist/cli/{index-ek5gvpvm.js → index-151bdyf9.js} +3 -3
- package/dist/cli/{index-rtznwf0g.js → index-22f1ek6k.js} +25 -25
- package/dist/cli/{index-r9zc92pb.js → index-4dwhfbed.js} +27 -27
- package/dist/cli/{index-ss6b8jpz.js → index-4fd28s8v.js} +1 -1
- package/dist/cli/{index-ycqsnfd1.js → index-5pa0e0k3.js} +1 -1
- package/dist/cli/{index-07bk0zm9.js → index-6bfcsczm.js} +1 -1
- package/dist/cli/{index-2b3bgm20.js → index-6ndc8cmn.js} +1 -1
- package/dist/cli/{index-5n08z6qj.js → index-7xt5m1cz.js} +5 -5
- package/dist/cli/{index-nw16apxs.js → index-9th8npp7.js} +1 -1
- package/dist/cli/{index-dz5cbkrm.js → index-9y6cyc7z.js} +3 -3
- package/dist/cli/{index-ekyg4p8b.js → index-a1tpq5zr.js} +1 -1
- package/dist/cli/{index-nhw5rt5x.js → index-a6h5arqs.js} +3 -3
- package/dist/cli/{index-pa6fzbms.js → index-amamkcpy.js} +1 -1
- package/dist/cli/{index-dryhmaft.js → index-bajvxmnb.js} +2 -2
- package/dist/cli/{index-hgfkcb1q.js → index-bgpq7wn2.js} +754 -565
- package/dist/cli/{index-7jt24hpz.js → index-d7mcdyqb.js} +2 -2
- package/dist/cli/{index-cnbpht7m.js → index-fp4hxcsy.js} +1 -1
- package/dist/cli/{index-s7va6n84.js → index-hvmfa7m8.js} +1 -1
- package/dist/cli/{index-cp2nerjd.js → index-j972ags2.js} +38 -15
- package/dist/cli/{index-9h93zjm3.js → index-jxd67x6z.js} +1 -1
- package/dist/cli/{index-zt3taseq.js → index-kv3n7g8w.js} +1 -1
- package/dist/cli/{index-7n3h39h9.js → index-m94gfe82.js} +4 -4
- package/dist/cli/{index-m1bhg85z.js → index-nxjm66qb.js} +2 -2
- package/dist/cli/{index-fa014mra.js → index-p6bvzgp2.js} +3 -3
- package/dist/cli/{index-2c6e1p7j.js → index-p9m1nhds.js} +1 -1
- package/dist/cli/{index-rr1dggfe.js → index-qyjyd3ej.js} +1 -1
- package/dist/cli/{index-6wqv8f7d.js → index-vk3ngryj.js} +1 -1
- package/dist/cli/{index-ppj5bjaq.js → index-w2b8qq6d.js} +3 -3
- package/dist/cli/{index-pppjg0ct.js → index-wkv1qdb0.js} +13 -15
- package/dist/cli/{index-smwybqka.js → index-wmazt588.js} +1 -1
- package/dist/cli/index.js +26 -26
- package/dist/cli/{knowledge-escalator-30bb9fyg.js → knowledge-escalator-7xcd0zea.js} +6 -6
- package/dist/cli/{knowledge-events-gfbx97x0.js → knowledge-events-e4ts8y2v.js} +4 -4
- package/dist/cli/{knowledge-store-2ssd489f.js → knowledge-store-mmeqmjwj.js} +1 -1
- package/dist/cli/{knowledge-validator-7bxvezgv.js → knowledge-validator-w2ttgxyj.js} +2 -2
- package/dist/cli/{mcp-apr65eya.js → mcp-5dmm4fk2.js} +1 -1
- package/dist/cli/{model-preflight-g7b12yn2.js → model-preflight-kap3zp3g.js} +25 -25
- package/dist/cli/{pending-delegations-x8q7cxr7.js → pending-delegations-q3sj608s.js} +2 -2
- package/dist/cli/{pr-subscriptions-qwr6ybcb.js → pr-subscriptions-qw4wjv66.js} +4 -2
- package/dist/cli/{pr-workflow-gate-qd5tfkak.js → pr-workflow-gate-tdj50p2g.js} +25 -25
- package/dist/cli/{scan-cursor-1m6dj2s2.js → scan-cursor-fgecb928.js} +2 -2
- package/dist/cli/{schema-yvhamv41.js → schema-zrcgm9d9.js} +1 -1
- package/dist/cli/{scope-persistence-xdedbzdg.js → scope-persistence-08xd3kyb.js} +5 -5
- package/dist/cli/{server-nhdkvdt2.js → server-kng2nggc.js} +25 -25
- package/dist/cli/{skill-generator-fzvp9m8z.js → skill-generator-dztn1ctf.js} +7 -7
- package/dist/cli/{snapshot-coordination-init-xqxek8kn.js → snapshot-coordination-init-5q0hac3d.js} +25 -25
- package/dist/cli/{speckit-checkoff-57tf4079.js → speckit-checkoff-hhsy83m9.js} +3 -3
- package/dist/cli/{worktree-collision-ownership-80n814a8.js → worktree-collision-ownership-e2cqcmnw.js} +2 -2
- package/dist/cli/{worktree-isolation-kaxkr61t.js → worktree-isolation-refd2n16.js} +25 -25
- package/dist/git/pr.d.ts +73 -0
- package/dist/hooks/pr-workflow-gate.d.ts +2 -0
- package/dist/index.js +34 -34
- package/package.json +1 -1
|
@@ -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,
|
|
@@ -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,
|
|
@@ -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,7 +176,7 @@ 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,
|
|
@@ -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,
|
|
@@ -359,7 +359,7 @@ 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,
|
|
@@ -370,7 +370,7 @@ import {
|
|
|
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,
|
|
@@ -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,
|
|
@@ -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,
|
|
@@ -3389,7 +3389,7 @@ async function importLegacyPrWorkflowGateStateIfNeeded(directory, sessionID, all
|
|
|
3389
3389
|
return null;
|
|
3390
3390
|
throw error2;
|
|
3391
3391
|
}
|
|
3392
|
-
const legacy = allowSalvagedImport ? (await (await import("./pr-workflow-gate-
|
|
3392
|
+
const legacy = allowSalvagedImport ? (await (await import("./pr-workflow-gate-tdj50p2g.js")).readPrWorkflowGateStateForRecovery(directory, sessionID))?.state ?? null : await readPrWorkflowGateStateFileFromDisk(filePath, sessionID);
|
|
3393
3393
|
if (!legacy)
|
|
3394
3394
|
return null;
|
|
3395
3395
|
const namespace = workflowGateStateCoordinationNamespace(sessionID);
|
|
@@ -3476,7 +3476,7 @@ async function deleteStateWhileLocked(directory, sessionID, options = {}) {
|
|
|
3476
3476
|
let recoveryState = null;
|
|
3477
3477
|
if (!currentAuthoritative) {
|
|
3478
3478
|
if (options.allowSalvagedRead) {
|
|
3479
|
-
const { readPrWorkflowGateStateForRecovery } = await import("./pr-workflow-gate-
|
|
3479
|
+
const { readPrWorkflowGateStateForRecovery } = await import("./pr-workflow-gate-tdj50p2g.js");
|
|
3480
3480
|
recoveryState = (await readPrWorkflowGateStateForRecovery(directory, normalizedSessionID))?.state ?? null;
|
|
3481
3481
|
}
|
|
3482
3482
|
if (!recoveryState) {
|
|
@@ -15039,7 +15039,7 @@ function isLaneOwnedByCurrentSession(branchName, expectedSessionId) {
|
|
|
15039
15039
|
return extracted === expectedSessionId;
|
|
15040
15040
|
}
|
|
15041
15041
|
async function inspectStandardWorktreeCollisionOwnership(identity) {
|
|
15042
|
-
const collisionOwnership = await import("./worktree-collision-ownership-
|
|
15042
|
+
const collisionOwnership = await import("./worktree-collision-ownership-e2cqcmnw.js");
|
|
15043
15043
|
return collisionOwnership.inspectStandardWorktreeCollisionOwnership(identity);
|
|
15044
15044
|
}
|
|
15045
15045
|
async function runRecoveryGit(directory, args, timeoutMs = 15000) {
|
|
@@ -15465,7 +15465,7 @@ async function precreateStandardWorktreeSession(args) {
|
|
|
15465
15465
|
const laneProfile = computeLaneRuntimeProfile(worktreeConfig.runtime_isolation, laneIndex, handle.worktreePath);
|
|
15466
15466
|
if (laneProfile) {
|
|
15467
15467
|
try {
|
|
15468
|
-
const { writeLaneProfileToDiskReal } = await import("./core-
|
|
15468
|
+
const { writeLaneProfileToDiskReal } = await import("./core-pj2fz34e.js");
|
|
15469
15469
|
await writeLaneProfileToDiskReal(handle.worktreePath, laneProfile.laneIndex, laneProfile.envOverrides);
|
|
15470
15470
|
} catch {}
|
|
15471
15471
|
}
|
|
@@ -16444,7 +16444,7 @@ async function finishStandardWorktreeDispatch(directory, dispatch, config, callI
|
|
|
16444
16444
|
}
|
|
16445
16445
|
clearWorktreeMergeStatus(statusKey);
|
|
16446
16446
|
try {
|
|
16447
|
-
const { removeLaneProfileFromDiskReal } = await import("./core-
|
|
16447
|
+
const { removeLaneProfileFromDiskReal } = await import("./core-pj2fz34e.js");
|
|
16448
16448
|
await removeLaneProfileFromDiskReal(dispatch.handle.worktreePath, dispatch.laneIndex);
|
|
16449
16449
|
} catch {}
|
|
16450
16450
|
const state = serializationStateBySessionID.get(dispatch.parentSessionID);
|
|
@@ -24083,7 +24083,7 @@ function clearCriticalShownIds(sessionID) {
|
|
|
24083
24083
|
async function rehydratePrSubscriptions(sessionID, directory) {
|
|
24084
24084
|
const map = new Map;
|
|
24085
24085
|
try {
|
|
24086
|
-
const { listActive: listActive2 } = await import("./pr-subscriptions-
|
|
24086
|
+
const { listActive: listActive2 } = await import("./pr-subscriptions-qw4wjv66.js");
|
|
24087
24087
|
const records = await listActive2(directory);
|
|
24088
24088
|
for (const record of records) {
|
|
24089
24089
|
if (record.sessionID !== sessionID)
|
|
@@ -24568,11 +24568,11 @@ async function activatePrWorkflow(directory, sessionID, mode, options = {}) {
|
|
|
24568
24568
|
let existing = await readPrWorkflowGateStateFromDisk3(directory, normalizedSessionID);
|
|
24569
24569
|
if (existing?.mode === mode) {
|
|
24570
24570
|
if (mode === "PR_FEEDBACK" && options.prUrl) {
|
|
24571
|
-
const requestedTarget = canonicalGitHubPrUrl(options.prUrl);
|
|
24571
|
+
const requestedTarget = canonicalGitHubPrUrl(options.prUrl, options.forge);
|
|
24572
24572
|
if (!requestedTarget) {
|
|
24573
24573
|
throw new Error("BLOCKED: PR_FEEDBACK target must be a canonical GitHub PR URL");
|
|
24574
24574
|
}
|
|
24575
|
-
const existingTarget = existing.prFeedbackTargetUrl ? canonicalGitHubPrUrl(existing.prFeedbackTargetUrl) : null;
|
|
24575
|
+
const existingTarget = existing.prFeedbackTargetUrl ? canonicalGitHubPrUrl(existing.prFeedbackTargetUrl, options.forge) : null;
|
|
24576
24576
|
if (existingTarget && requestedTarget !== existingTarget) {
|
|
24577
24577
|
throw new Error(`BLOCKED: active PR_FEEDBACK targets a different GitHub pull request`);
|
|
24578
24578
|
}
|
|
@@ -24606,7 +24606,7 @@ async function activatePrWorkflow(directory, sessionID, mode, options = {}) {
|
|
|
24606
24606
|
const initialHead = options.prHeadSha ? await assertCurrentCheckoutHead(directory, options.prHeadSha, mode) : undefined;
|
|
24607
24607
|
const skillContractAdvisories = await ensurePrWorkflowSkillContractsFresh(directory, mode);
|
|
24608
24608
|
const timestamp = isoNow();
|
|
24609
|
-
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;
|
|
24610
24610
|
if (feedbackTargetUrl === null) {
|
|
24611
24611
|
throw new Error("BLOCKED: PR_FEEDBACK target must be a canonical GitHub PR URL");
|
|
24612
24612
|
}
|
|
@@ -29150,8 +29150,8 @@ async function readPrReviewFinalFindingPolicyForReport(directory, sessionID) {
|
|
|
29150
29150
|
const blockingFindingIds = policyProjection.blockingFindingIds.flatMap((id) => sourceIdsByPolicyFindingId.get(id) ?? [id]).sort();
|
|
29151
29151
|
return { policyVersion: 1, permittedVerdicts, blockingFindingIds };
|
|
29152
29152
|
}
|
|
29153
|
-
function canonicalGitHubPrUrl(value) {
|
|
29154
|
-
return canonicalForgePrUrl(value);
|
|
29153
|
+
function canonicalGitHubPrUrl(value, configured) {
|
|
29154
|
+
return canonicalForgePrUrl(value, configured);
|
|
29155
29155
|
}
|
|
29156
29156
|
function assertMatchingPrReviewFeedbackConsent(record, input) {
|
|
29157
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) {
|
|
@@ -32223,6 +32223,128 @@ async function readPrWorkflowGateStateForRecovery(directory, sessionID) {
|
|
|
32223
32223
|
// src/commands/registry.ts
|
|
32224
32224
|
init_logger();
|
|
32225
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
|
+
|
|
32226
32348
|
// src/commands/abort-pr-workflow.ts
|
|
32227
32349
|
var USAGE2 = [
|
|
32228
32350
|
"Usage: /swarm abort-pr-workflow [PR_REVIEW|PR_FEEDBACK] [reason...]",
|
|
@@ -32327,7 +32449,7 @@ import { createHash as createHash24 } from "crypto";
|
|
|
32327
32449
|
import { mkdir as mkdir6, readFile as readFile10, unlink as unlink2 } from "fs/promises";
|
|
32328
32450
|
import { dirname as dirname15 } from "path";
|
|
32329
32451
|
var SPEC_DRIFT_RECOVERY_AGENT = "spec-drift-recovery";
|
|
32330
|
-
var
|
|
32452
|
+
var _internals33 = {
|
|
32331
32453
|
appendEvent,
|
|
32332
32454
|
assertProjectRoot,
|
|
32333
32455
|
bunWrite,
|
|
@@ -32412,21 +32534,21 @@ async function writeWal3(walPath, wal) {
|
|
|
32412
32534
|
}
|
|
32413
32535
|
async function verifySnapshot(snapshotPath, currentSpec) {
|
|
32414
32536
|
if (!currentSpec) {
|
|
32415
|
-
await
|
|
32416
|
-
const stillExists = await
|
|
32537
|
+
await _internals33.unlinkIfExists(snapshotPath);
|
|
32538
|
+
const stillExists = await _internals33.readFileText(snapshotPath) !== null;
|
|
32417
32539
|
if (stillExists) {
|
|
32418
32540
|
throw new Error("spec snapshot verification failed: snapshot still exists after delete");
|
|
32419
32541
|
}
|
|
32420
32542
|
return;
|
|
32421
32543
|
}
|
|
32422
32544
|
await atomicWriteFile(snapshotPath, currentSpec.content);
|
|
32423
|
-
const written = await
|
|
32545
|
+
const written = await _internals33.readFileText(snapshotPath);
|
|
32424
32546
|
if (written !== currentSpec.content) {
|
|
32425
32547
|
throw new Error("spec snapshot verification failed: snapshot content does not match effective spec");
|
|
32426
32548
|
}
|
|
32427
32549
|
}
|
|
32428
32550
|
async function ensureSnapshotEvent(directory, plan, transitionId) {
|
|
32429
|
-
const events = await
|
|
32551
|
+
const events = await _internals33.readLedgerEvents(directory);
|
|
32430
32552
|
for (const event of events) {
|
|
32431
32553
|
const payload = event.payload;
|
|
32432
32554
|
const approval = payload?.approval;
|
|
@@ -32434,17 +32556,17 @@ async function ensureSnapshotEvent(directory, plan, transitionId) {
|
|
|
32434
32556
|
return;
|
|
32435
32557
|
}
|
|
32436
32558
|
}
|
|
32437
|
-
await
|
|
32559
|
+
await _internals33.takeSnapshotEvent(directory, plan, {
|
|
32438
32560
|
source: "spec_drift_recovery",
|
|
32439
32561
|
approvalMetadata: { specDriftTransitionId: transitionId }
|
|
32440
32562
|
});
|
|
32441
32563
|
}
|
|
32442
32564
|
async function appendEvent(directory, event) {
|
|
32443
|
-
const existing = await
|
|
32565
|
+
const existing = await _internals33.verifyEventPresence(directory, event.type, event.transitionId);
|
|
32444
32566
|
if (existing)
|
|
32445
32567
|
return;
|
|
32446
32568
|
appendCoreEventSync(directory, { ...event }, { dedupeOnAuthorityKey: true });
|
|
32447
|
-
const verified = await
|
|
32569
|
+
const verified = await _internals33.verifyEventPresence(directory, event.type, event.transitionId);
|
|
32448
32570
|
if (!verified) {
|
|
32449
32571
|
throw new Error(`spec drift audit verification failed for transition ${event.transitionId}`);
|
|
32450
32572
|
}
|
|
@@ -32466,7 +32588,7 @@ function buildRecoveryEvent(args) {
|
|
|
32466
32588
|
if (args.mode === "acknowledge") {
|
|
32467
32589
|
return {
|
|
32468
32590
|
type: "spec_drift_acknowledged",
|
|
32469
|
-
timestamp:
|
|
32591
|
+
timestamp: _internals33.now(),
|
|
32470
32592
|
phase: args.phase,
|
|
32471
32593
|
planTitle: args.planTitle,
|
|
32472
32594
|
acknowledgedBy: args.actor === "spec_write" ? "unknown" : args.actor,
|
|
@@ -32478,7 +32600,7 @@ function buildRecoveryEvent(args) {
|
|
|
32478
32600
|
}
|
|
32479
32601
|
return {
|
|
32480
32602
|
type: "spec_drift_repaired",
|
|
32481
|
-
timestamp:
|
|
32603
|
+
timestamp: _internals33.now(),
|
|
32482
32604
|
phase: args.phase,
|
|
32483
32605
|
planTitle: args.planTitle,
|
|
32484
32606
|
repairedBy: args.actor,
|
|
@@ -32489,11 +32611,11 @@ function buildRecoveryEvent(args) {
|
|
|
32489
32611
|
};
|
|
32490
32612
|
}
|
|
32491
32613
|
async function reconcileSpecDrift(directory, options) {
|
|
32492
|
-
|
|
32493
|
-
const markerPath =
|
|
32494
|
-
const walPath =
|
|
32495
|
-
const snapshotPath =
|
|
32496
|
-
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);
|
|
32497
32619
|
if (markerMaybe === null) {
|
|
32498
32620
|
return {
|
|
32499
32621
|
status: "no_marker",
|
|
@@ -32501,7 +32623,7 @@ async function reconcileSpecDrift(directory, options) {
|
|
|
32501
32623
|
message: "No spec drift detected."
|
|
32502
32624
|
};
|
|
32503
32625
|
}
|
|
32504
|
-
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()}`);
|
|
32505
32627
|
if (specLockResult && !specLockResult.acquired) {
|
|
32506
32628
|
return {
|
|
32507
32629
|
status: "retry_later",
|
|
@@ -32511,7 +32633,7 @@ async function reconcileSpecDrift(directory, options) {
|
|
|
32511
32633
|
}
|
|
32512
32634
|
let lockResult;
|
|
32513
32635
|
try {
|
|
32514
|
-
lockResult = await
|
|
32636
|
+
lockResult = await _internals33.tryAcquireLock(directory, "plan.json", SPEC_DRIFT_RECOVERY_AGENT, `${options.mode}-${Date.now()}`);
|
|
32515
32637
|
} catch (error2) {
|
|
32516
32638
|
if (specLockResult?.acquired && specLockResult.lock._release) {
|
|
32517
32639
|
await specLockResult.lock._release().catch(() => {});
|
|
@@ -32537,7 +32659,7 @@ async function reconcileSpecDrift(directory, options) {
|
|
|
32537
32659
|
let errorNewHash;
|
|
32538
32660
|
try {
|
|
32539
32661
|
try {
|
|
32540
|
-
const authoritativeMarkerRaw = await
|
|
32662
|
+
const authoritativeMarkerRaw = await _internals33.readFileText(markerPath);
|
|
32541
32663
|
if (authoritativeMarkerRaw === null) {
|
|
32542
32664
|
return {
|
|
32543
32665
|
status: "no_marker",
|
|
@@ -32545,14 +32667,14 @@ async function reconcileSpecDrift(directory, options) {
|
|
|
32545
32667
|
message: "No spec drift detected."
|
|
32546
32668
|
};
|
|
32547
32669
|
}
|
|
32548
|
-
const marker =
|
|
32670
|
+
const marker = _internals33.parseMarker(authoritativeMarkerRaw);
|
|
32549
32671
|
if (!marker) {
|
|
32550
32672
|
return buildCorruptMarkerResult(options.mode);
|
|
32551
32673
|
}
|
|
32552
32674
|
errorMarker = marker;
|
|
32553
32675
|
const markerHash = sha2563(authoritativeMarkerRaw);
|
|
32554
|
-
const existingWalRaw = await
|
|
32555
|
-
const existingWal = existingWalRaw === null ? null :
|
|
32676
|
+
const existingWalRaw = await _internals33.readFileText(walPath);
|
|
32677
|
+
const existingWal = existingWalRaw === null ? null : _internals33.parseWal(existingWalRaw);
|
|
32556
32678
|
if (existingWalRaw !== null && !existingWal) {
|
|
32557
32679
|
return {
|
|
32558
32680
|
status: "failed",
|
|
@@ -32562,7 +32684,7 @@ async function reconcileSpecDrift(directory, options) {
|
|
|
32562
32684
|
planTitle: marker.planTitle
|
|
32563
32685
|
};
|
|
32564
32686
|
}
|
|
32565
|
-
const currentSpec =
|
|
32687
|
+
const currentSpec = _internals33.readEffectiveSpecSync(directory);
|
|
32566
32688
|
const proposedNewHash = currentSpec?.hash ?? null;
|
|
32567
32689
|
const proposedTransitionId = buildTransitionId(options.mode, markerHash, marker.specHash_plan, proposedNewHash);
|
|
32568
32690
|
const proposedWal = {
|
|
@@ -32577,7 +32699,7 @@ async function reconcileSpecDrift(directory, options) {
|
|
|
32577
32699
|
newHash: proposedNewHash,
|
|
32578
32700
|
specContent: currentSpec?.content ?? null,
|
|
32579
32701
|
actor: options.actor,
|
|
32580
|
-
recordedAt:
|
|
32702
|
+
recordedAt: _internals33.now()
|
|
32581
32703
|
};
|
|
32582
32704
|
const markerReplacedDuringPrepared = existingWal?.state === "PREPARED" && existingWal.markerHash !== markerHash;
|
|
32583
32705
|
const wal = existingWal?.state === "PREPARED" || existingWal?.markerHash === markerHash ? existingWal : proposedWal;
|
|
@@ -32586,12 +32708,12 @@ async function reconcileSpecDrift(directory, options) {
|
|
|
32586
32708
|
errorTransitionId = transitionId;
|
|
32587
32709
|
errorNewHash = newHash;
|
|
32588
32710
|
if (wal === proposedWal) {
|
|
32589
|
-
await
|
|
32711
|
+
await _internals33.writeWal(walPath, wal);
|
|
32590
32712
|
}
|
|
32591
32713
|
if (wal.newHash === null !== (wal.specContent === null) || wal.specContent !== null && sha2563(wal.specContent) !== wal.newHash) {
|
|
32592
32714
|
throw new Error(`Spec drift recovery WAL ${transitionId} has inconsistent captured spec content`);
|
|
32593
32715
|
}
|
|
32594
|
-
let plan = await
|
|
32716
|
+
let plan = await _internals33.loadPlanJsonOnly(directory);
|
|
32595
32717
|
if (!plan) {
|
|
32596
32718
|
return {
|
|
32597
32719
|
status: "failed",
|
|
@@ -32622,13 +32744,13 @@ async function reconcileSpecDrift(directory, options) {
|
|
|
32622
32744
|
}
|
|
32623
32745
|
if (planMatchesOld) {
|
|
32624
32746
|
plan.specHash = newHash ?? undefined;
|
|
32625
|
-
await
|
|
32747
|
+
await _internals33.savePlan(directory, plan, {
|
|
32626
32748
|
planLockAlreadyHeld: true
|
|
32627
32749
|
});
|
|
32628
|
-
plan = await
|
|
32750
|
+
plan = await _internals33.loadPlanJsonOnly(directory) ?? plan;
|
|
32629
32751
|
}
|
|
32630
|
-
await
|
|
32631
|
-
await
|
|
32752
|
+
await _internals33.ensureSnapshotEvent(directory, plan, transitionId);
|
|
32753
|
+
await _internals33.verifySnapshot(snapshotPath, wal.specContent === null ? null : { content: wal.specContent });
|
|
32632
32754
|
const event = buildRecoveryEvent({
|
|
32633
32755
|
mode: wal.mode,
|
|
32634
32756
|
actor: wal.actor,
|
|
@@ -32639,15 +32761,15 @@ async function reconcileSpecDrift(directory, options) {
|
|
|
32639
32761
|
previousHash: wal.previousHash,
|
|
32640
32762
|
transitionId
|
|
32641
32763
|
});
|
|
32642
|
-
await
|
|
32643
|
-
await
|
|
32764
|
+
await _internals33.appendEvent(directory, event);
|
|
32765
|
+
await _internals33.writeWal(walPath, { ...wal, state: "COMMITTED" });
|
|
32644
32766
|
}
|
|
32645
32767
|
if (markerReplacedDuringPrepared) {
|
|
32646
32768
|
const preservedMarker = {
|
|
32647
32769
|
...marker,
|
|
32648
32770
|
specHash_plan: newHash,
|
|
32649
32771
|
reason: `prior prepared drift recovery committed before this marker: ${marker.reason}`,
|
|
32650
|
-
timestamp:
|
|
32772
|
+
timestamp: _internals33.now()
|
|
32651
32773
|
};
|
|
32652
32774
|
await atomicWriteFile(markerPath, `${JSON.stringify(preservedMarker, null, 2)}
|
|
32653
32775
|
`);
|
|
@@ -32662,7 +32784,7 @@ async function reconcileSpecDrift(directory, options) {
|
|
|
32662
32784
|
transitionId
|
|
32663
32785
|
};
|
|
32664
32786
|
}
|
|
32665
|
-
const latestSpec =
|
|
32787
|
+
const latestSpec = _internals33.readEffectiveSpecSync(directory);
|
|
32666
32788
|
if ((latestSpec?.hash ?? null) !== newHash) {
|
|
32667
32789
|
const refreshedMarker = {
|
|
32668
32790
|
planTitle: wal.planTitle,
|
|
@@ -32670,7 +32792,7 @@ async function reconcileSpecDrift(directory, options) {
|
|
|
32670
32792
|
specHash_plan: newHash,
|
|
32671
32793
|
specHash_current: latestSpec?.hash ?? null,
|
|
32672
32794
|
reason: "spec changed while drift recovery was committing",
|
|
32673
|
-
timestamp:
|
|
32795
|
+
timestamp: _internals33.now()
|
|
32674
32796
|
};
|
|
32675
32797
|
await atomicWriteFile(markerPath, `${JSON.stringify(refreshedMarker, null, 2)}
|
|
32676
32798
|
`);
|
|
@@ -32686,8 +32808,8 @@ async function reconcileSpecDrift(directory, options) {
|
|
|
32686
32808
|
};
|
|
32687
32809
|
}
|
|
32688
32810
|
try {
|
|
32689
|
-
await
|
|
32690
|
-
|
|
32811
|
+
await _internals33.unlinkIfExists(markerPath);
|
|
32812
|
+
_internals33.invalidateCachedArtifact(markerPath);
|
|
32691
32813
|
} catch (error2) {
|
|
32692
32814
|
return {
|
|
32693
32815
|
status: "cleanup_pending",
|
|
@@ -33184,7 +33306,7 @@ ${USAGE4}`;
|
|
|
33184
33306
|
|
|
33185
33307
|
// src/commands/archive.ts
|
|
33186
33308
|
init_loader();
|
|
33187
|
-
var
|
|
33309
|
+
var _internals34 = {
|
|
33188
33310
|
now: () => new Date
|
|
33189
33311
|
};
|
|
33190
33312
|
function artifactLabel(artifact) {
|
|
@@ -33240,7 +33362,7 @@ async function handleArchiveCommand(directory, args) {
|
|
|
33240
33362
|
const report = await archiveEvidence(directory, maxAgeDays, maxBundles, {
|
|
33241
33363
|
report: true,
|
|
33242
33364
|
dryRun,
|
|
33243
|
-
now:
|
|
33365
|
+
now: _internals34.now(),
|
|
33244
33366
|
cacheMaxBytes,
|
|
33245
33367
|
cacheMaxRecords
|
|
33246
33368
|
});
|
|
@@ -35207,7 +35329,7 @@ function createShadowCopy(directory, maxBytes = MAX_SHADOW_COPY_BYTES) {
|
|
|
35207
35329
|
const rel = path33.relative(directory, src);
|
|
35208
35330
|
const dest = path33.join(shadowRoot, rel);
|
|
35209
35331
|
fs21.mkdirSync(path33.dirname(dest), { recursive: true });
|
|
35210
|
-
const copied =
|
|
35332
|
+
const copied = _internals35.copyFileBounded(src, dest, maxBytes - copiedBytes);
|
|
35211
35333
|
if (copied === null) {
|
|
35212
35334
|
removeShadowRoot(shadowRoot);
|
|
35213
35335
|
return null;
|
|
@@ -35220,7 +35342,7 @@ function createShadowCopy(directory, maxBytes = MAX_SHADOW_COPY_BYTES) {
|
|
|
35220
35342
|
throw error2;
|
|
35221
35343
|
}
|
|
35222
35344
|
}
|
|
35223
|
-
var
|
|
35345
|
+
var _internals35 = {
|
|
35224
35346
|
computeEvidenceQualitySummary,
|
|
35225
35347
|
copyFileBounded,
|
|
35226
35348
|
createShadowCopy
|
|
@@ -35467,7 +35589,7 @@ async function evaluateAdvisoryCi(options) {
|
|
|
35467
35589
|
});
|
|
35468
35590
|
}
|
|
35469
35591
|
}
|
|
35470
|
-
const summary = await
|
|
35592
|
+
const summary = await _internals35.computeEvidenceQualitySummary(directory);
|
|
35471
35593
|
const q = summary.qualityMetrics;
|
|
35472
35594
|
const qualityRows = [
|
|
35473
35595
|
[
|
|
@@ -35861,7 +35983,7 @@ async function handleCiCommand(ctx) {
|
|
|
35861
35983
|
const signals = createSignalCancellation(controller);
|
|
35862
35984
|
signals.install();
|
|
35863
35985
|
try {
|
|
35864
|
-
const result = await
|
|
35986
|
+
const result = await _internals36.runAdvisoryCiRuntime({
|
|
35865
35987
|
directory: ctx.directory,
|
|
35866
35988
|
deadlineMs,
|
|
35867
35989
|
signal: controller.signal,
|
|
@@ -35910,134 +36032,10 @@ async function handleCiCommand(ctx) {
|
|
|
35910
36032
|
signals.dispose();
|
|
35911
36033
|
}
|
|
35912
36034
|
}
|
|
35913
|
-
var
|
|
36035
|
+
var _internals36 = { runAdvisoryCiRuntime };
|
|
35914
36036
|
|
|
35915
36037
|
// src/commands/pr-ref.ts
|
|
35916
36038
|
init_loader();
|
|
35917
|
-
|
|
35918
|
-
// src/commands/_shared/url-security.ts
|
|
35919
|
-
import * as child_process from "child_process";
|
|
35920
|
-
init_git_executable();
|
|
35921
|
-
var MAX_URL_LEN = 2048;
|
|
35922
|
-
var _internals36 = {
|
|
35923
|
-
spawnSync: (cmd, args, options) => {
|
|
35924
|
-
const mergedEnv = mergeEnvForChild(options?.env, options?.envOverrides);
|
|
35925
|
-
return child_process.spawnSync(cmd, args, {
|
|
35926
|
-
...options,
|
|
35927
|
-
env: mergedEnv
|
|
35928
|
-
});
|
|
35929
|
-
}
|
|
35930
|
-
};
|
|
35931
|
-
function sanitizeUrl(raw) {
|
|
35932
|
-
let urlStr = raw.trim();
|
|
35933
|
-
urlStr = urlStr.replace(/^([A-Za-z][A-Za-z0-9+.-]*:\/\/)\/?[^@/]+@/, "$1");
|
|
35934
|
-
urlStr = urlStr.replace(/\[\s*MODE\s*:[^\]]*\]/gi, "");
|
|
35935
|
-
urlStr = urlStr.replace(/^([A-Za-z][A-Za-z0-9+.-]*:\/\/)\/?[^@/]+@/, "$1");
|
|
35936
|
-
const fragmentIdx = urlStr.indexOf("#");
|
|
35937
|
-
if (fragmentIdx !== -1) {
|
|
35938
|
-
urlStr = urlStr.slice(0, fragmentIdx);
|
|
35939
|
-
}
|
|
35940
|
-
const queryIdx = urlStr.indexOf("?");
|
|
35941
|
-
if (queryIdx !== -1) {
|
|
35942
|
-
urlStr = urlStr.slice(0, queryIdx);
|
|
35943
|
-
}
|
|
35944
|
-
if (urlStr.length > MAX_URL_LEN) {
|
|
35945
|
-
urlStr = urlStr.slice(0, MAX_URL_LEN);
|
|
35946
|
-
}
|
|
35947
|
-
return urlStr.trim();
|
|
35948
|
-
}
|
|
35949
|
-
function sanitizeErrorEcho(raw, maxLength = 80) {
|
|
35950
|
-
let stripped = "";
|
|
35951
|
-
for (const ch of raw) {
|
|
35952
|
-
const cp = ch.codePointAt(0);
|
|
35953
|
-
if (cp !== undefined && (cp <= 31 || cp === 127)) {
|
|
35954
|
-
stripped += " ";
|
|
35955
|
-
continue;
|
|
35956
|
-
}
|
|
35957
|
-
stripped += ch;
|
|
35958
|
-
}
|
|
35959
|
-
const collapsed = stripped.replace(/\s+/g, " ").trim();
|
|
35960
|
-
if (collapsed.length <= maxLength)
|
|
35961
|
-
return collapsed;
|
|
35962
|
-
return `${collapsed.slice(0, maxLength)}\u2026`;
|
|
35963
|
-
}
|
|
35964
|
-
function validateAndSanitizeGithubUrl(rawUrl, resource, configured) {
|
|
35965
|
-
const sanitized = sanitizeUrl(rawUrl);
|
|
35966
|
-
if (!sanitized) {
|
|
35967
|
-
return { error: "Empty URL" };
|
|
35968
|
-
}
|
|
35969
|
-
if (!sanitized.startsWith("https://")) {
|
|
35970
|
-
return { error: "URL must use HTTPS scheme" };
|
|
35971
|
-
}
|
|
35972
|
-
try {
|
|
35973
|
-
const url = new URL(sanitized);
|
|
35974
|
-
if (hasNonAsciiHostname(url.hostname)) {
|
|
35975
|
-
return { error: "Non-ASCII hostnames are not allowed" };
|
|
35976
|
-
}
|
|
35977
|
-
if (isPrivateHost(url)) {
|
|
35978
|
-
return { error: "Private or localhost URLs are not allowed" };
|
|
35979
|
-
}
|
|
35980
|
-
const matched = matchForgeResourceUrl(sanitized, resource, configured);
|
|
35981
|
-
if (!matched) {
|
|
35982
|
-
return {
|
|
35983
|
-
error: resource === "issues" ? "URL must be a GitHub issue URL (https://github.com/owner/repo/issues/N) or a GitLab issue URL (https://<gitlab-host>/owner/repo/-/issues/N)" : "URL must be a GitHub pull request URL (https://github.com/owner/repo/pull/N) or a GitLab merge request URL (https://<gitlab-host>/owner/repo/-/merge_requests/N)"
|
|
35984
|
-
};
|
|
35985
|
-
}
|
|
35986
|
-
return { sanitized };
|
|
35987
|
-
} catch {
|
|
35988
|
-
return { error: "Invalid URL format" };
|
|
35989
|
-
}
|
|
35990
|
-
}
|
|
35991
|
-
function detectGitRemote(cwd, laneEnv) {
|
|
35992
|
-
try {
|
|
35993
|
-
const result = _internals36.spawnSync(resolveGitExecutable(), ["remote", "get-url", "origin"], {
|
|
35994
|
-
encoding: "utf-8",
|
|
35995
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
35996
|
-
timeout: 5000,
|
|
35997
|
-
...cwd ? { cwd } : {},
|
|
35998
|
-
envOverrides: laneEnv
|
|
35999
|
-
});
|
|
36000
|
-
if (result.status !== 0 || result.error) {
|
|
36001
|
-
return null;
|
|
36002
|
-
}
|
|
36003
|
-
const remoteUrl = (result.stdout ?? "").trim();
|
|
36004
|
-
return remoteUrl || null;
|
|
36005
|
-
} catch {
|
|
36006
|
-
return null;
|
|
36007
|
-
}
|
|
36008
|
-
}
|
|
36009
|
-
function parseGitRemoteUrl(remoteUrl) {
|
|
36010
|
-
const httpsMatch = remoteUrl.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?\/?$/i);
|
|
36011
|
-
if (httpsMatch) {
|
|
36012
|
-
const owner = httpsMatch[1];
|
|
36013
|
-
const repo = httpsMatch[2].replace(/\.git$/, "");
|
|
36014
|
-
if (containsControlCharacters(owner) || containsControlCharacters(repo)) {
|
|
36015
|
-
return null;
|
|
36016
|
-
}
|
|
36017
|
-
return { owner, repo };
|
|
36018
|
-
}
|
|
36019
|
-
const sshMatch = remoteUrl.match(/^git@github\.com:([^/]+)\/([^/]+?)(?:\.git)?$/i);
|
|
36020
|
-
if (sshMatch) {
|
|
36021
|
-
const owner = sshMatch[1];
|
|
36022
|
-
const repo = sshMatch[2].replace(/\.git$/, "");
|
|
36023
|
-
if (containsControlCharacters(owner) || containsControlCharacters(repo)) {
|
|
36024
|
-
return null;
|
|
36025
|
-
}
|
|
36026
|
-
return { owner, repo };
|
|
36027
|
-
}
|
|
36028
|
-
const pathMatch = remoteUrl.match(/\/([^/]+)\/([^/]+?)(?:\.git)?\/?$/);
|
|
36029
|
-
if (pathMatch) {
|
|
36030
|
-
const owner = pathMatch[1];
|
|
36031
|
-
const repo = pathMatch[2].replace(/\.git$/, "");
|
|
36032
|
-
if (containsControlCharacters(owner) || containsControlCharacters(repo)) {
|
|
36033
|
-
return null;
|
|
36034
|
-
}
|
|
36035
|
-
return { owner, repo };
|
|
36036
|
-
}
|
|
36037
|
-
return null;
|
|
36038
|
-
}
|
|
36039
|
-
|
|
36040
|
-
// src/commands/pr-ref.ts
|
|
36041
36039
|
var MAX_INSTRUCTIONS_LEN = 1000;
|
|
36042
36040
|
var GITHUB_CONTEXT = {
|
|
36043
36041
|
provider: "github",
|
|
@@ -40455,9 +40453,9 @@ function hashContent(content) {
|
|
|
40455
40453
|
return createHash27("sha1").update(content).digest("hex");
|
|
40456
40454
|
}
|
|
40457
40455
|
async function loadConfigForPolicyCurator(directory) {
|
|
40458
|
-
const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-
|
|
40456
|
+
const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-zrcgm9d9.js");
|
|
40459
40457
|
try {
|
|
40460
|
-
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-
|
|
40458
|
+
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-p6bvzgp2.js");
|
|
40461
40459
|
const { config: loadedConfig } = loadPluginConfigWithMeta2(directory);
|
|
40462
40460
|
return KnowledgeConfigSchema2.parse(loadedConfig.knowledge ?? {});
|
|
40463
40461
|
} catch {
|
|
@@ -43515,7 +43513,7 @@ async function resolveCuratorLLMDelegate(directory, mode, sessionId) {
|
|
|
43515
43513
|
const seam = _internals38.createCuratorLLMDelegate;
|
|
43516
43514
|
if (seam)
|
|
43517
43515
|
return seam(directory, mode, sessionId);
|
|
43518
|
-
const { createCuratorLLMDelegate } = await import("./curator-llm-factory-
|
|
43516
|
+
const { createCuratorLLMDelegate } = await import("./curator-llm-factory-13h02244.js");
|
|
43519
43517
|
return createCuratorLLMDelegate(directory, mode, sessionId);
|
|
43520
43518
|
}
|
|
43521
43519
|
async function reconcileCloseTerminalStateForPlan(directory, targetPlan, options) {
|
|
@@ -43910,7 +43908,7 @@ async function runFinalizeStage(ctx) {
|
|
|
43910
43908
|
}
|
|
43911
43909
|
}
|
|
43912
43910
|
try {
|
|
43913
|
-
const { CuratorConfigSchema: CCS } = await import("./schema-
|
|
43911
|
+
const { CuratorConfigSchema: CCS } = await import("./schema-zrcgm9d9.js");
|
|
43914
43912
|
const { config: pmLoadedConfig } = _internals38.loadPluginConfigWithMeta(ctx.directory);
|
|
43915
43913
|
const curatorCfg = CCS.parse(pmLoadedConfig.curator ?? {});
|
|
43916
43914
|
if (curatorCfg.enabled && curatorCfg.postmortem_enabled) {
|
|
@@ -46096,7 +46094,7 @@ function serializeAgentSession(s) {
|
|
|
46096
46094
|
}
|
|
46097
46095
|
async function writeSnapshot(directory, state) {
|
|
46098
46096
|
try {
|
|
46099
|
-
const { ensureSnapshotCoordinationReady } = await import("./snapshot-coordination-init-
|
|
46097
|
+
const { ensureSnapshotCoordinationReady } = await import("./snapshot-coordination-init-5q0hac3d.js");
|
|
46100
46098
|
await ensureSnapshotCoordinationReady(directory);
|
|
46101
46099
|
const snapshot = {
|
|
46102
46100
|
version: 3,
|
|
@@ -49274,7 +49272,7 @@ function planMerges(active, threshold, maxComparisons, maxMerges) {
|
|
|
49274
49272
|
};
|
|
49275
49273
|
}
|
|
49276
49274
|
async function sweepActiveNearDuplicates(directory, options = {}) {
|
|
49277
|
-
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-
|
|
49275
|
+
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-p6bvzgp2.js");
|
|
49278
49276
|
const { config } = loadPluginConfigWithMeta2(directory);
|
|
49279
49277
|
const sweepConfig = config.learning?.dedup_sweep;
|
|
49280
49278
|
if (sweepConfig?.enabled === false)
|
|
@@ -50155,14 +50153,14 @@ async function runCuratorInit(directory, config, llmDelegate) {
|
|
|
50155
50153
|
}));
|
|
50156
50154
|
if (llmDelegate) {
|
|
50157
50155
|
try {
|
|
50158
|
-
const userInput = [
|
|
50156
|
+
const userInput = sanitizeContextText([
|
|
50159
50157
|
"TASK: CURATOR_INIT",
|
|
50160
50158
|
`PRIOR_SUMMARY: ${priorSummary ? JSON.stringify(priorSummary) : "none"}`,
|
|
50161
50159
|
`KNOWLEDGE_ENTRIES: ${JSON.stringify(allEntriesForCurator)}`,
|
|
50162
|
-
`PROJECT_CONTEXT: ${contextMd?.slice(0, config.max_summary_tokens * 2) ?? "none"}`,
|
|
50163
|
-
`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")}`
|
|
50164
50162
|
].join(`
|
|
50165
|
-
`);
|
|
50163
|
+
`));
|
|
50166
50164
|
const systemPrompt = CURATOR_INIT_PROMPT;
|
|
50167
50165
|
const timeoutMs = config.llm_timeout_ms ?? DEFAULT_CURATOR_LLM_TIMEOUT_MS;
|
|
50168
50166
|
const ac = new AbortController;
|
|
@@ -50256,7 +50254,7 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
|
|
|
50256
50254
|
const phaseData = plan?.phases.find((p) => p.id === phase);
|
|
50257
50255
|
const tasksCompleted = phaseData ? phaseData.tasks.filter((t) => t.status === "completed").length : 0;
|
|
50258
50256
|
const tasksTotal = phaseData ? phaseData.tasks.length : 0;
|
|
50259
|
-
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))) : [];
|
|
50260
50258
|
const phaseDigest = {
|
|
50261
50259
|
phase,
|
|
50262
50260
|
timestamp: new Date().toISOString(),
|
|
@@ -50287,16 +50285,16 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
|
|
|
50287
50285
|
try {
|
|
50288
50286
|
const priorDigest = priorSummary?.digest ?? "none";
|
|
50289
50287
|
const systemPrompt = CURATOR_PHASE_PROMPT;
|
|
50290
|
-
const userInput = [
|
|
50288
|
+
const userInput = sanitizeContextText([
|
|
50291
50289
|
`TASK: CURATOR_PHASE ${phase}`,
|
|
50292
|
-
`PRIOR_DIGEST: ${priorDigest}`,
|
|
50290
|
+
`PRIOR_DIGEST: ${sanitizeContextText(priorDigest)}`,
|
|
50293
50291
|
`PHASE_EVENTS: ${JSON.stringify(phaseEvents.slice(0, 50))}`,
|
|
50294
50292
|
`PHASE_DECISIONS: ${JSON.stringify(keyDecisions)}`,
|
|
50295
50293
|
`AGENTS_DISPATCHED: ${JSON.stringify(agentsDispatched)}`,
|
|
50296
50294
|
`AGENTS_EXPECTED: ["reviewer", "test_engineer"]`,
|
|
50297
50295
|
`KNOWLEDGE_ENTRIES: ${JSON.stringify(knowledgeForCurator)}`
|
|
50298
50296
|
].join(`
|
|
50299
|
-
`);
|
|
50297
|
+
`));
|
|
50300
50298
|
const timeoutMs = config.llm_timeout_ms ?? DEFAULT_CURATOR_LLM_TIMEOUT_MS;
|
|
50301
50299
|
const ac = new AbortController;
|
|
50302
50300
|
const timer = setTimeout(() => ac.abort(), timeoutMs);
|
|
@@ -50398,7 +50396,7 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
|
|
|
50398
50396
|
}
|
|
50399
50397
|
if (config.skill_generation_enabled === true && skillCandidates.length > 0) {
|
|
50400
50398
|
try {
|
|
50401
|
-
const skillModule = await import("./skill-generator-
|
|
50399
|
+
const skillModule = await import("./skill-generator-dztn1ctf.js");
|
|
50402
50400
|
for (const cand of skillCandidates) {
|
|
50403
50401
|
if (cand.confidence < (config.min_skill_confidence ?? DEFAULT_SKILL_MIN_CONFIDENCE)) {
|
|
50404
50402
|
continue;
|
|
@@ -50870,7 +50868,7 @@ async function applyCuratorKnowledgeUpdates(directory, recommendations, knowledg
|
|
|
50870
50868
|
} catch {}
|
|
50871
50869
|
}
|
|
50872
50870
|
if (contradictedEntries.length > 0 && knowledgeConfig.contradiction_threshold_action === "quarantine") {
|
|
50873
|
-
const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-
|
|
50871
|
+
const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-7xcd0zea.js");
|
|
50874
50872
|
for (const { id } of contradictedEntries) {
|
|
50875
50873
|
try {
|
|
50876
50874
|
await maybeQuarantineOnContradiction(directory, id, knowledgeConfig.contradiction_quarantine_threshold, knowledgeConfig.contradiction_quarantine_window_days);
|
|
@@ -51383,9 +51381,9 @@ async function repairPostMortemActions(llmOutput, diagnostics, options) {
|
|
|
51383
51381
|
"Allowed queue_triage action values: apply, reject.",
|
|
51384
51382
|
"Do not include unsupported actions such as merge.",
|
|
51385
51383
|
"Diagnostics:",
|
|
51386
|
-
diagnostics.join("; "),
|
|
51384
|
+
diagnostics.map((d) => sanitizeContextText(d)).join("; "),
|
|
51387
51385
|
"Original output:",
|
|
51388
|
-
llmOutput.slice(0, 8000)
|
|
51386
|
+
sanitizeContextText(llmOutput).slice(0, 8000)
|
|
51389
51387
|
].join(`
|
|
51390
51388
|
`);
|
|
51391
51389
|
const repaired = await options.llmDelegate("", repairPrompt, ac.signal);
|
|
@@ -51601,8 +51599,8 @@ function assembleLLMInput(planId, scope, sessionID, planSummary, knowledgeSummar
|
|
|
51601
51599
|
const sections = [];
|
|
51602
51600
|
sections.push(`TASK: CURATOR_POSTMORTEM ${planId}`);
|
|
51603
51601
|
sections.push(`SCOPE: ${scope}${sessionID ? ` (${sessionID})` : ""}`);
|
|
51604
|
-
sections.push(`PLAN_SUMMARY: ${planSummary}`);
|
|
51605
|
-
sections.push(`CURATOR_DIGESTS: ${curatorDigest ?? "none"}`);
|
|
51602
|
+
sections.push(`PLAN_SUMMARY: ${sanitizeContextText(planSummary)}`);
|
|
51603
|
+
sections.push(`CURATOR_DIGESTS: ${sanitizeContextText(curatorDigest ?? "none")}`);
|
|
51606
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(`
|
|
51607
51605
|
`);
|
|
51608
51606
|
sections.push(`KNOWLEDGE_EVENTS_SUMMARY:
|
|
@@ -51633,9 +51631,9 @@ ${retroText}`);
|
|
|
51633
51631
|
sections.push(`DRIFT_REPORTS:
|
|
51634
51632
|
${driftText}`);
|
|
51635
51633
|
}
|
|
51636
|
-
return sections.join(`
|
|
51634
|
+
return sanitizeContextText(sections.join(`
|
|
51637
51635
|
|
|
51638
|
-
`);
|
|
51636
|
+
`));
|
|
51639
51637
|
}
|
|
51640
51638
|
async function runCuratorPostMortem(directory, options = {}) {
|
|
51641
51639
|
const warnings = [];
|
|
@@ -51702,7 +51700,7 @@ async function runCuratorPostMortem(directory, options = {}) {
|
|
|
51702
51700
|
warnings.push("Failed to collect knowledge summary.");
|
|
51703
51701
|
}
|
|
51704
51702
|
try {
|
|
51705
|
-
const { getScanStatus } = await import("./scan-cursor-
|
|
51703
|
+
const { getScanStatus } = await import("./scan-cursor-fgecb928.js");
|
|
51706
51704
|
const scanStatus = await getScanStatus(directory);
|
|
51707
51705
|
if (scanStatus.remaining_estimate > 0) {
|
|
51708
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.`);
|
|
@@ -51874,9 +51872,9 @@ var _internals57 = {
|
|
|
51874
51872
|
verifyPostMortemKnowledgeActions,
|
|
51875
51873
|
repairPostMortemActions,
|
|
51876
51874
|
loadDefaultKnowledgeConfig: async (directory) => {
|
|
51877
|
-
const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-
|
|
51875
|
+
const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-zrcgm9d9.js");
|
|
51878
51876
|
try {
|
|
51879
|
-
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-
|
|
51877
|
+
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-p6bvzgp2.js");
|
|
51880
51878
|
const loaded = loadPluginConfigWithMeta2(directory);
|
|
51881
51879
|
return KnowledgeConfigSchema2.parse(loaded.config.knowledge ?? {});
|
|
51882
51880
|
} catch {
|
|
@@ -51884,11 +51882,11 @@ var _internals57 = {
|
|
|
51884
51882
|
}
|
|
51885
51883
|
},
|
|
51886
51884
|
applyCuratorKnowledgeUpdates: async (directory, recommendations, knowledgeConfig, generation) => {
|
|
51887
|
-
const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-
|
|
51885
|
+
const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-r0jfc7xw.js");
|
|
51888
51886
|
return applyCuratorKnowledgeUpdates2(directory, recommendations, knowledgeConfig, generation);
|
|
51889
51887
|
},
|
|
51890
51888
|
checkHivePromotions: async (entries2, knowledgeConfig, directory) => {
|
|
51891
|
-
const { checkHivePromotions } = await import("./hive-promoter-
|
|
51889
|
+
const { checkHivePromotions } = await import("./hive-promoter-0vg8w79a.js");
|
|
51892
51890
|
return checkHivePromotions(entries2, knowledgeConfig, directory);
|
|
51893
51891
|
},
|
|
51894
51892
|
applyProposalTriage: async (directory, triage) => {
|
|
@@ -51897,7 +51895,7 @@ var _internals57 = {
|
|
|
51897
51895
|
activateProposal,
|
|
51898
51896
|
listSkills: listSkills2,
|
|
51899
51897
|
sanitizeSlug
|
|
51900
|
-
} = await import("./skill-generator-
|
|
51898
|
+
} = await import("./skill-generator-dztn1ctf.js");
|
|
51901
51899
|
const result = {
|
|
51902
51900
|
approved: [],
|
|
51903
51901
|
rejected: [],
|
|
@@ -51939,7 +51937,7 @@ var _internals57 = {
|
|
|
51939
51937
|
return result;
|
|
51940
51938
|
},
|
|
51941
51939
|
readPriorDriftReports: async (directory) => {
|
|
51942
|
-
const { readPriorDriftReports: readPriorDriftReports2 } = await import("./curator-drift-
|
|
51940
|
+
const { readPriorDriftReports: readPriorDriftReports2 } = await import("./curator-drift-q84jn9cc.js");
|
|
51943
51941
|
return readPriorDriftReports2(directory);
|
|
51944
51942
|
},
|
|
51945
51943
|
readSwarmKnowledge: (directory) => readKnowledge(resolveSwarmKnowledgePath(directory))
|
|
@@ -61735,9 +61733,9 @@ var _internals67 = {
|
|
|
61735
61733
|
loadPluginConfigWithMeta,
|
|
61736
61734
|
loadCuratorDeps: async () => {
|
|
61737
61735
|
const [{ CuratorConfigSchema }, curator, { createCuratorLLMDelegate }] = await Promise.all([
|
|
61738
|
-
import("./schema-
|
|
61739
|
-
import("./curator-
|
|
61740
|
-
import("./curator-llm-factory-
|
|
61736
|
+
import("./schema-zrcgm9d9.js"),
|
|
61737
|
+
import("./curator-r0jfc7xw.js"),
|
|
61738
|
+
import("./curator-llm-factory-13h02244.js")
|
|
61741
61739
|
]);
|
|
61742
61740
|
return { CuratorConfigSchema, curator, createCuratorLLMDelegate };
|
|
61743
61741
|
}
|
|
@@ -64130,7 +64128,7 @@ async function computeCurationDiagnostics(directory, entries2) {
|
|
|
64130
64128
|
let scanCompleted = false;
|
|
64131
64129
|
let scanRemaining = 0;
|
|
64132
64130
|
try {
|
|
64133
|
-
const { getScanStatus } = await import("./scan-cursor-
|
|
64131
|
+
const { getScanStatus } = await import("./scan-cursor-fgecb928.js");
|
|
64134
64132
|
const status = await getScanStatus(directory);
|
|
64135
64133
|
scanGeneration = status.generation;
|
|
64136
64134
|
scanCompleted = status.completed;
|
|
@@ -64140,10 +64138,10 @@ async function computeCurationDiagnostics(directory, entries2) {
|
|
|
64140
64138
|
try {
|
|
64141
64139
|
const { isLinked: isLinked2 } = await import("./knowledge-link-dv78fb9g.js");
|
|
64142
64140
|
if (isLinked2(directory)) {
|
|
64143
|
-
const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-
|
|
64141
|
+
const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-zrcgm9d9.js");
|
|
64144
64142
|
let config;
|
|
64145
64143
|
try {
|
|
64146
|
-
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-
|
|
64144
|
+
const { loadPluginConfigWithMeta: loadPluginConfigWithMeta2 } = await import("./index-p6bvzgp2.js");
|
|
64147
64145
|
const loaded = loadPluginConfigWithMeta2(directory);
|
|
64148
64146
|
config = KnowledgeConfigSchema2.parse(loaded.config.knowledge ?? {});
|
|
64149
64147
|
} catch {
|
|
@@ -65598,7 +65596,7 @@ async function handleDoctorCommand(directory, args) {
|
|
|
65598
65596
|
const result = runConfigDoctor(config, directory);
|
|
65599
65597
|
let output;
|
|
65600
65598
|
if (enableAutoFix && result.hasAutoFixableIssues) {
|
|
65601
|
-
const { runConfigDoctorWithFixes } = await import("./config-doctor-
|
|
65599
|
+
const { runConfigDoctorWithFixes } = await import("./config-doctor-28ggsms8.js");
|
|
65602
65600
|
const fixResult = await runConfigDoctorWithFixes(directory, config, true, {
|
|
65603
65601
|
applyLossy: true
|
|
65604
65602
|
});
|
|
@@ -65636,7 +65634,7 @@ async function handleDoctorCommand(directory, args) {
|
|
|
65636
65634
|
`;
|
|
65637
65635
|
}
|
|
65638
65636
|
try {
|
|
65639
|
-
const { runModelPreflight } = await import("./model-preflight-
|
|
65637
|
+
const { runModelPreflight } = await import("./model-preflight-kap3zp3g.js");
|
|
65640
65638
|
const preflight = await runModelPreflight(config, swarmState.opencodeClient, { generatedAgentNames: swarmState.generatedAgentNames });
|
|
65641
65639
|
const missingSelection = preflight.resolutions.filter((resolution) => resolution.status === "missing-selection");
|
|
65642
65640
|
const unresolved = preflight.catalogAvailable ? preflight.resolutions.filter((resolution) => resolution.status === "unresolved") : [];
|
|
@@ -66563,7 +66561,7 @@ async function handleEvidenceCommand(directory, args) {
|
|
|
66563
66561
|
return formatTaskEvidenceMarkdown(evidenceData);
|
|
66564
66562
|
}
|
|
66565
66563
|
async function handleEvidenceSummaryCommand(directory) {
|
|
66566
|
-
const { buildEvidenceSummary } = await import("./evidence-summary-service-
|
|
66564
|
+
const { buildEvidenceSummary } = await import("./evidence-summary-service-rsectw2t.js");
|
|
66567
66565
|
const artifact = await buildEvidenceSummary(directory);
|
|
66568
66566
|
if (!artifact) {
|
|
66569
66567
|
return "No plan found. Run `/swarm plan` to check plan status.";
|
|
@@ -90896,7 +90894,7 @@ function createCuratorLLMDelegate(directory, mode = "init", sessionId) {
|
|
|
90896
90894
|
}
|
|
90897
90895
|
const sdkOpts = signal ? { signal } : {};
|
|
90898
90896
|
try {
|
|
90899
|
-
const { getSwarmAgents: getSwarmAgents2, resolveFallbackModel: resolveFallbackModel2 } = await import("./index-
|
|
90897
|
+
const { getSwarmAgents: getSwarmAgents2, resolveFallbackModel: resolveFallbackModel2 } = await import("./index-22f1ek6k.js");
|
|
90900
90898
|
const createResult = await client.session.create({
|
|
90901
90899
|
...sessionId ? {
|
|
90902
90900
|
body: {
|
|
@@ -91188,8 +91186,8 @@ init_zod();
|
|
|
91188
91186
|
init_loader();
|
|
91189
91187
|
import { createHash as createHash51, randomUUID as randomUUID22 } from "crypto";
|
|
91190
91188
|
import * as fsSync9 from "fs";
|
|
91191
|
-
import * as
|
|
91192
|
-
import * as
|
|
91189
|
+
import * as fs64 from "fs/promises";
|
|
91190
|
+
import * as path128 from "path";
|
|
91193
91191
|
init_logger();
|
|
91194
91192
|
|
|
91195
91193
|
// src/background/pr-feedback-event-queue.ts
|
|
@@ -92154,6 +92152,228 @@ var _internals98 = {
|
|
|
92154
92152
|
|
|
92155
92153
|
// src/git/pr.ts
|
|
92156
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
|
|
92157
92377
|
init_logger();
|
|
92158
92378
|
|
|
92159
92379
|
// src/utils/untrusted-markdown.ts
|
|
@@ -92189,7 +92409,7 @@ var EvidencePlanSchema = exports_external.object({
|
|
|
92189
92409
|
}).passthrough()).optional()
|
|
92190
92410
|
}).passthrough();
|
|
92191
92411
|
function ghExec(args, cwd) {
|
|
92192
|
-
const ghBinary =
|
|
92412
|
+
const ghBinary = _internals100.resolveGhExecutable();
|
|
92193
92413
|
for (let attempt = 0;attempt < MAX_TRANSIENT_RETRIES; attempt++) {
|
|
92194
92414
|
const result = child_process5.spawnSync(ghBinary, args, {
|
|
92195
92415
|
cwd,
|
|
@@ -92245,12 +92465,18 @@ function spawnSyncWithTransientRetry(command, args, options) {
|
|
|
92245
92465
|
throw new Error(`${command} exited with null`);
|
|
92246
92466
|
}
|
|
92247
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) {
|
|
92248
92471
|
return new Promise((resolve40, reject) => {
|
|
92249
|
-
const
|
|
92250
|
-
const proc = child_process5.spawn(ghBinary, args, {
|
|
92472
|
+
const spawnOptions = {
|
|
92251
92473
|
cwd,
|
|
92252
92474
|
stdio: ["ignore", "pipe", "pipe"]
|
|
92253
|
-
}
|
|
92475
|
+
};
|
|
92476
|
+
if (opts?.env) {
|
|
92477
|
+
spawnOptions.env = mergeEnvForChild(undefined, opts.env);
|
|
92478
|
+
}
|
|
92479
|
+
const proc = child_process5.spawn(binary, args, spawnOptions);
|
|
92254
92480
|
const stdoutChunks = [];
|
|
92255
92481
|
const stderrChunks = [];
|
|
92256
92482
|
let stdoutBytes = 0;
|
|
@@ -92274,7 +92500,7 @@ async function ghExecAsync(args, cwd) {
|
|
|
92274
92500
|
proc.stdout?.on("data", (chunk) => {
|
|
92275
92501
|
stdoutBytes += chunk.length;
|
|
92276
92502
|
if (stdoutBytes > MAX_OUTPUT_BYTES2) {
|
|
92277
|
-
settle2(() => reject(new Error(
|
|
92503
|
+
settle2(() => reject(new Error(`${label} ${args[0]} stdout exceeded ${MAX_OUTPUT_BYTES2} bytes`)));
|
|
92278
92504
|
return;
|
|
92279
92505
|
}
|
|
92280
92506
|
stdoutChunks.push(chunk);
|
|
@@ -92282,13 +92508,13 @@ async function ghExecAsync(args, cwd) {
|
|
|
92282
92508
|
proc.stderr?.on("data", (chunk) => {
|
|
92283
92509
|
stderrBytes += chunk.length;
|
|
92284
92510
|
if (stderrBytes > MAX_OUTPUT_BYTES2) {
|
|
92285
|
-
settle2(() => reject(new Error(
|
|
92511
|
+
settle2(() => reject(new Error(`${label} ${args[0]} stderr exceeded ${MAX_OUTPUT_BYTES2} bytes`)));
|
|
92286
92512
|
return;
|
|
92287
92513
|
}
|
|
92288
92514
|
stderrChunks.push(chunk);
|
|
92289
92515
|
});
|
|
92290
92516
|
const timer = setTimeout(() => {
|
|
92291
|
-
settle2(() => reject(new Error(
|
|
92517
|
+
settle2(() => reject(new Error(`${label} ${args[0]} timed out after ${GIT_TIMEOUT_MS5}ms`)));
|
|
92292
92518
|
}, GIT_TIMEOUT_MS5);
|
|
92293
92519
|
proc.on("error", (err) => {
|
|
92294
92520
|
settle2(() => reject(err));
|
|
@@ -92297,7 +92523,7 @@ async function ghExecAsync(args, cwd) {
|
|
|
92297
92523
|
settle2(() => {
|
|
92298
92524
|
if (code !== 0) {
|
|
92299
92525
|
const stderr = Buffer.concat(stderrChunks).toString("utf-8");
|
|
92300
|
-
reject(new Error(stderr ||
|
|
92526
|
+
reject(new Error(stderr || `${label} exited with ${code}`));
|
|
92301
92527
|
} else {
|
|
92302
92528
|
const stdout = Buffer.concat(stdoutChunks).toString("utf-8");
|
|
92303
92529
|
resolve40(stdout);
|
|
@@ -92306,20 +92532,24 @@ async function ghExecAsync(args, cwd) {
|
|
|
92306
92532
|
});
|
|
92307
92533
|
});
|
|
92308
92534
|
}
|
|
92309
|
-
var
|
|
92535
|
+
var _internals100 = {
|
|
92310
92536
|
ghExec,
|
|
92311
92537
|
ghExecAsync,
|
|
92538
|
+
forgeExecAsync: forgeExecAsyncImpl,
|
|
92539
|
+
getMRPollSnapshot,
|
|
92540
|
+
getMRComments,
|
|
92312
92541
|
spawnSyncWithTransientRetry,
|
|
92313
92542
|
spawnSync: __spawnSyncSeam.spawnSync,
|
|
92314
92543
|
readLaneEnvFileFromDiskSync,
|
|
92315
92544
|
getMergeGroupRun,
|
|
92316
92545
|
resolveGhExecutable,
|
|
92317
|
-
resolveGitExecutable
|
|
92546
|
+
resolveGitExecutable,
|
|
92547
|
+
resolveGlabExecutable
|
|
92318
92548
|
};
|
|
92319
92549
|
async function getPRPollSnapshot(prNumber, repoFullName, cwd) {
|
|
92320
92550
|
let stdout;
|
|
92321
92551
|
try {
|
|
92322
|
-
stdout = await
|
|
92552
|
+
stdout = await _internals100.ghExecAsync([
|
|
92323
92553
|
"pr",
|
|
92324
92554
|
"view",
|
|
92325
92555
|
String(prNumber),
|
|
@@ -92376,7 +92606,7 @@ function numericIssueCommentId(url, fallbackId, fallbacks) {
|
|
|
92376
92606
|
async function getPRReviewComments(prNumber, repoFullName, cwd) {
|
|
92377
92607
|
let stdout;
|
|
92378
92608
|
try {
|
|
92379
|
-
stdout = await
|
|
92609
|
+
stdout = await _internals100.ghExecAsync(["api", `repos/${repoFullName}/pulls/${prNumber}/comments`], cwd);
|
|
92380
92610
|
} catch (err) {
|
|
92381
92611
|
throw new Error(`Failed to fetch review comments for ${repoFullName}#${prNumber}: ${err instanceof Error ? err.message : String(err)}`);
|
|
92382
92612
|
}
|
|
@@ -92389,6 +92619,129 @@ async function getPRReviewComments(prNumber, repoFullName, cwd) {
|
|
|
92389
92619
|
isReviewComment: true
|
|
92390
92620
|
}));
|
|
92391
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
|
+
}
|
|
92392
92745
|
async function getMergeGroupRun(statusCheckRollup, repoFullName, cwd) {
|
|
92393
92746
|
const mergeGroupCheck = statusCheckRollup.find((check) => check.name === "Merge pull request" && check.detailsUrl);
|
|
92394
92747
|
if (!mergeGroupCheck?.detailsUrl) {
|
|
@@ -92401,7 +92754,7 @@ async function getMergeGroupRun(statusCheckRollup, repoFullName, cwd) {
|
|
|
92401
92754
|
const runId = runIdMatch[1];
|
|
92402
92755
|
let stdout;
|
|
92403
92756
|
try {
|
|
92404
|
-
stdout = await
|
|
92757
|
+
stdout = await _internals100.ghExecAsync([
|
|
92405
92758
|
"run",
|
|
92406
92759
|
"view",
|
|
92407
92760
|
runId,
|
|
@@ -92430,7 +92783,7 @@ var registrationsByCanonical = new Map;
|
|
|
92430
92783
|
function resolveRegistration(directory) {
|
|
92431
92784
|
const lexical = canonicalRootKeyLexical(directory);
|
|
92432
92785
|
try {
|
|
92433
|
-
const freshKey =
|
|
92786
|
+
const freshKey = _internals101.canonicalRootKeyFresh(directory);
|
|
92434
92787
|
const canonical = registrationsByCanonical.get(freshKey);
|
|
92435
92788
|
if (canonical)
|
|
92436
92789
|
return canonical;
|
|
@@ -92452,8 +92805,10 @@ async function evaluatePrFeedbackCurrentHead(directory, repoFullName, prNumber)
|
|
|
92452
92805
|
async function dispatchPrFeedbackOversight(input) {
|
|
92453
92806
|
return await getPrFeedbackLoopRuntime(input.directory)?.dispatchOversight(input) ?? { dispatched: false, verdict: "unavailable", decision: "pending" };
|
|
92454
92807
|
}
|
|
92455
|
-
var
|
|
92808
|
+
var _internals101 = {
|
|
92456
92809
|
getPRPollSnapshot,
|
|
92810
|
+
getMRPollSnapshot,
|
|
92811
|
+
findSubscriptionRecordForPrUrl,
|
|
92457
92812
|
dispatchEphemeralAgent,
|
|
92458
92813
|
parseCriticResponseFields,
|
|
92459
92814
|
canonicalRootKeyFresh,
|
|
@@ -92462,11 +92817,11 @@ var _internals100 = {
|
|
|
92462
92817
|
};
|
|
92463
92818
|
|
|
92464
92819
|
// src/background/pr-feedback-loop.ts
|
|
92465
|
-
var PR_FEEDBACK_LOOP_STATE_REL =
|
|
92820
|
+
var PR_FEEDBACK_LOOP_STATE_REL = path128.join(".swarm", "pr-feedback-loop-state.json");
|
|
92466
92821
|
var PR_FEEDBACK_CLEANUP_DIR = "pr-feedback-loop-cleanups";
|
|
92467
|
-
var PR_FEEDBACK_EVIDENCE_DIR =
|
|
92822
|
+
var PR_FEEDBACK_EVIDENCE_DIR = path128.join(".swarm", "pr-feedback-evidence");
|
|
92468
92823
|
var PR_FEEDBACK_LOOP_STATE_LOCK_FILENAME = "pr-feedback-loop-state.lock";
|
|
92469
|
-
var PR_FEEDBACK_LOOP_STATE_LOCK_REL =
|
|
92824
|
+
var PR_FEEDBACK_LOOP_STATE_LOCK_REL = path128.join(".swarm", PR_FEEDBACK_LOOP_STATE_LOCK_FILENAME);
|
|
92470
92825
|
var MAX_TRACKED_SESSIONS5 = 200;
|
|
92471
92826
|
var MAX_IN_FLIGHT_SESSIONS = 64;
|
|
92472
92827
|
var MAX_CANCELLATION_REQUESTS = 64;
|
|
@@ -92482,7 +92837,7 @@ var LoopStateSchema = exports_external.object({
|
|
|
92482
92837
|
correlations: exports_external.record(exports_external.string(), exports_external.any()),
|
|
92483
92838
|
sessionTerminals: exports_external.record(exports_external.string(), exports_external.any()).default({})
|
|
92484
92839
|
});
|
|
92485
|
-
var
|
|
92840
|
+
var _internals102 = {
|
|
92486
92841
|
async evaluateCurrentHead(directory, repoFullName, prNumber) {
|
|
92487
92842
|
return evaluatePrFeedbackCurrentHead(directory, repoFullName, prNumber);
|
|
92488
92843
|
},
|
|
@@ -92491,13 +92846,20 @@ var _internals101 = {
|
|
|
92491
92846
|
},
|
|
92492
92847
|
async performAuthorizedAction(input) {
|
|
92493
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
|
+
});
|
|
92494
92855
|
await activatePrWorkflow(input.directory, input.sessionID, "PR_FEEDBACK", {
|
|
92495
92856
|
requireCheckoutPreflight: true,
|
|
92496
|
-
prUrl: input.event.prUrl
|
|
92857
|
+
prUrl: input.event.prUrl,
|
|
92858
|
+
forge: subscription?.forge
|
|
92497
92859
|
});
|
|
92498
92860
|
return {
|
|
92499
92861
|
performed: true,
|
|
92500
|
-
recordPath:
|
|
92862
|
+
recordPath: path128.join(".swarm", "pr-feedback-loop-state.json")
|
|
92501
92863
|
};
|
|
92502
92864
|
} catch (err) {
|
|
92503
92865
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -92519,13 +92881,13 @@ var _internals101 = {
|
|
|
92519
92881
|
listActive,
|
|
92520
92882
|
isProcessAlive: isProcessAlive3,
|
|
92521
92883
|
resetLoopStateLock() {
|
|
92522
|
-
|
|
92884
|
+
_internals102.beforeLoopStateLockWrite = undefined;
|
|
92523
92885
|
},
|
|
92524
92886
|
loopStateLockRelativePath: () => PR_FEEDBACK_LOOP_STATE_LOCK_REL,
|
|
92525
92887
|
reclaimAbandonedLoopStateLock,
|
|
92526
92888
|
removeLoopStateLockIfOwned
|
|
92527
92889
|
};
|
|
92528
|
-
var defaultLoopInternals = { ...
|
|
92890
|
+
var defaultLoopInternals = { ..._internals102 };
|
|
92529
92891
|
function emptyState2() {
|
|
92530
92892
|
return {
|
|
92531
92893
|
schemaVersion: 1,
|
|
@@ -92601,7 +92963,7 @@ function hasReservationIdentity(reservation) {
|
|
|
92601
92963
|
return Boolean(reservation?.workflowInstanceId.trim() && Number.isInteger(reservation?.ownerPid) && (reservation?.ownerPid ?? 0) > 0);
|
|
92602
92964
|
}
|
|
92603
92965
|
async function readLoopState(directory) {
|
|
92604
|
-
const file =
|
|
92966
|
+
const file = path128.join(directory, PR_FEEDBACK_LOOP_STATE_REL);
|
|
92605
92967
|
try {
|
|
92606
92968
|
const raw = fsSync9.readFileSync(file, "utf-8");
|
|
92607
92969
|
const parsed = LoopStateSchema.safeParse(JSON.parse(raw));
|
|
@@ -92632,7 +92994,7 @@ async function writeLoopState(directory, state) {
|
|
|
92632
92994
|
}
|
|
92633
92995
|
}
|
|
92634
92996
|
state.updatedAt = new Date().toISOString();
|
|
92635
|
-
await writePrWorkflowAtomicJson(directory, validateSwarmPath(directory,
|
|
92997
|
+
await writePrWorkflowAtomicJson(directory, validateSwarmPath(directory, path128.basename(PR_FEEDBACK_LOOP_STATE_REL)), state);
|
|
92636
92998
|
}
|
|
92637
92999
|
async function withLoopStateLock(directory, fn) {
|
|
92638
93000
|
const lock = await acquireLoopStateLock(directory);
|
|
@@ -92647,21 +93009,21 @@ async function acquireLoopStateLock(directory) {
|
|
|
92647
93009
|
const verifiedStateDirectory = await ensurePrWorkflowSafeParentDirectory(directory, lockPath);
|
|
92648
93010
|
for (let attempt = 0;attempt < LOOP_STATE_LOCK_MAX_ATTEMPTS; attempt++) {
|
|
92649
93011
|
try {
|
|
92650
|
-
const handle = await
|
|
93012
|
+
const handle = await fs64.open(lockPath, "wx");
|
|
92651
93013
|
const lock = {
|
|
92652
93014
|
ownerToken: randomUUID22(),
|
|
92653
93015
|
pid: process.pid,
|
|
92654
|
-
createdAtMs:
|
|
93016
|
+
createdAtMs: _internals102.now()
|
|
92655
93017
|
};
|
|
92656
93018
|
let writeError;
|
|
92657
93019
|
try {
|
|
92658
|
-
await
|
|
93020
|
+
await _internals102.beforeLoopStateLockWrite?.();
|
|
92659
93021
|
const [openedStat, pathStat, realLockPath] = await Promise.all([
|
|
92660
93022
|
handle.stat({ bigint: true }),
|
|
92661
|
-
|
|
92662
|
-
|
|
93023
|
+
fs64.lstat(lockPath, { bigint: true }),
|
|
93024
|
+
fs64.realpath(lockPath)
|
|
92663
93025
|
]);
|
|
92664
|
-
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)) {
|
|
92665
93027
|
throw new Error("BLOCKED: PR feedback loop state lock changed or escaped before initialization");
|
|
92666
93028
|
}
|
|
92667
93029
|
await handle.writeFile(JSON.stringify(lock), "utf8");
|
|
@@ -92702,17 +93064,17 @@ async function reclaimAbandonedLoopStateLock(lockPath) {
|
|
|
92702
93064
|
lock = null;
|
|
92703
93065
|
}
|
|
92704
93066
|
if (lock) {
|
|
92705
|
-
if (
|
|
93067
|
+
if (_internals102.isProcessAlive(lock.pid) && _internals102.now() - lock.createdAtMs < LOOP_STATE_LOCK_ALIVE_OWNER_STALE_MS) {
|
|
92706
93068
|
return false;
|
|
92707
93069
|
}
|
|
92708
93070
|
return removeLoopStateLockIfOwned(lockPath, lock.ownerToken);
|
|
92709
93071
|
}
|
|
92710
93072
|
try {
|
|
92711
|
-
const stat14 = await
|
|
92712
|
-
if (
|
|
93073
|
+
const stat14 = await fs64.stat(lockPath);
|
|
93074
|
+
if (_internals102.now() - stat14.mtimeMs < LOOP_STATE_LOCK_UNINITIALIZED_STALE_MS) {
|
|
92713
93075
|
return false;
|
|
92714
93076
|
}
|
|
92715
|
-
await
|
|
93077
|
+
await fs64.rm(lockPath, { force: true });
|
|
92716
93078
|
return true;
|
|
92717
93079
|
} catch (error2) {
|
|
92718
93080
|
if (error2.code === "ENOENT")
|
|
@@ -92723,7 +93085,7 @@ async function reclaimAbandonedLoopStateLock(lockPath) {
|
|
|
92723
93085
|
async function readLoopStateLock(lockPath) {
|
|
92724
93086
|
let raw;
|
|
92725
93087
|
try {
|
|
92726
|
-
raw = await
|
|
93088
|
+
raw = await fs64.readFile(lockPath, "utf8");
|
|
92727
93089
|
} catch (error2) {
|
|
92728
93090
|
if (error2.code === "ENOENT")
|
|
92729
93091
|
return null;
|
|
@@ -92747,7 +93109,7 @@ async function removeLoopStateLockIfOwned(lockPath, ownerToken) {
|
|
|
92747
93109
|
if (!lock || lock.ownerToken !== ownerToken)
|
|
92748
93110
|
return false;
|
|
92749
93111
|
try {
|
|
92750
|
-
await
|
|
93112
|
+
await fs64.rm(lockPath);
|
|
92751
93113
|
return true;
|
|
92752
93114
|
} catch {
|
|
92753
93115
|
return false;
|
|
@@ -92765,7 +93127,7 @@ function sameFileIdentity4(left, right) {
|
|
|
92765
93127
|
return left.dev === right.dev && left.ino === right.ino;
|
|
92766
93128
|
}
|
|
92767
93129
|
function normalizeComparablePath2(value) {
|
|
92768
|
-
const normalized =
|
|
93130
|
+
const normalized = path128.normalize(path128.resolve(value));
|
|
92769
93131
|
return process.platform === "win32" ? normalized.toLowerCase() : normalized;
|
|
92770
93132
|
}
|
|
92771
93133
|
function delay3(ms) {
|
|
@@ -92869,14 +93231,14 @@ async function cancelPrFeedbackLoopUnlocked(directory, sessionID, reason) {
|
|
|
92869
93231
|
clearedEvents: []
|
|
92870
93232
|
};
|
|
92871
93233
|
try {
|
|
92872
|
-
const { cancelPrFeedbackPublication: cancelPrFeedbackPublication2 } = await import("./pr-workflow-gate-
|
|
93234
|
+
const { cancelPrFeedbackPublication: cancelPrFeedbackPublication2 } = await import("./pr-workflow-gate-tdj50p2g.js");
|
|
92873
93235
|
await cancelPrFeedbackPublication2(directory, sessionID, reason);
|
|
92874
93236
|
} catch (err) {
|
|
92875
93237
|
warn(`[pr-feedback-loop] cancelPrFeedbackPublication failed (fail-open): ${err instanceof Error ? err.message : String(err)}`);
|
|
92876
93238
|
}
|
|
92877
93239
|
try {
|
|
92878
93240
|
await withLoopStateLock(directory, async () => {
|
|
92879
|
-
const readResult = await
|
|
93241
|
+
const readResult = await _internals102.readState(directory);
|
|
92880
93242
|
if (isCorruptState(readResult)) {
|
|
92881
93243
|
throw new Error("BLOCKED: loop state is corrupt during durable cancellation admission");
|
|
92882
93244
|
}
|
|
@@ -92889,7 +93251,7 @@ async function cancelPrFeedbackLoopUnlocked(directory, sessionID, reason) {
|
|
|
92889
93251
|
correlation.terminal = { state: "cancelled", reason };
|
|
92890
93252
|
}
|
|
92891
93253
|
const inFlight = correlation.inFlight;
|
|
92892
|
-
const ownerAlive = inFlight && hasReservationIdentity(inFlight) ?
|
|
93254
|
+
const ownerAlive = inFlight && hasReservationIdentity(inFlight) ? _internals102.isProcessAlive(inFlight.ownerPid) : false;
|
|
92893
93255
|
const reclaimedReservation = Boolean(inFlight && (inFlight.actionStartedAt === undefined || !ownerAlive));
|
|
92894
93256
|
if (reclaimedReservation) {
|
|
92895
93257
|
correlation.inFlight = null;
|
|
@@ -92904,7 +93266,7 @@ async function cancelPrFeedbackLoopUnlocked(directory, sessionID, reason) {
|
|
|
92904
93266
|
reason
|
|
92905
93267
|
};
|
|
92906
93268
|
}
|
|
92907
|
-
await
|
|
93269
|
+
await _internals102.writeState(directory, nextState);
|
|
92908
93270
|
return nextState;
|
|
92909
93271
|
});
|
|
92910
93272
|
} catch (err) {
|
|
@@ -92925,12 +93287,12 @@ async function cancelPrFeedbackLoopUnlocked(directory, sessionID, reason) {
|
|
|
92925
93287
|
}
|
|
92926
93288
|
}
|
|
92927
93289
|
const stamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
92928
|
-
receipt.path =
|
|
93290
|
+
receipt.path = path128.join(".swarm", PR_FEEDBACK_CLEANUP_DIR, `cancel-${stamp}.json`);
|
|
92929
93291
|
try {
|
|
92930
|
-
fsSync9.mkdirSync(
|
|
93292
|
+
fsSync9.mkdirSync(path128.join(directory, ".swarm", PR_FEEDBACK_CLEANUP_DIR), {
|
|
92931
93293
|
recursive: true
|
|
92932
93294
|
});
|
|
92933
|
-
fsSync9.writeFileSync(
|
|
93295
|
+
fsSync9.writeFileSync(path128.join(directory, receipt.path), JSON.stringify({
|
|
92934
93296
|
schemaVersion: 1,
|
|
92935
93297
|
at: new Date().toISOString(),
|
|
92936
93298
|
sessionID,
|
|
@@ -92982,228 +93344,6 @@ ${USAGE14}`;
|
|
|
92982
93344
|
|
|
92983
93345
|
// src/background/pr-monitor-worker.ts
|
|
92984
93346
|
init_warning_buffer();
|
|
92985
|
-
|
|
92986
|
-
// src/utils/glab-executable.ts
|
|
92987
|
-
init_warning_buffer();
|
|
92988
|
-
import { spawnSync as spawnSync6 } from "child_process";
|
|
92989
|
-
import * as fs64 from "fs";
|
|
92990
|
-
import * as os14 from "os";
|
|
92991
|
-
import * as path128 from "path";
|
|
92992
|
-
var GLAB_BINARY_ENV_VAR = "OPENCODE_SWARM_GLAB_BINARY";
|
|
92993
|
-
var PER_PROBE_TIMEOUT_MS2 = 250;
|
|
92994
|
-
var TOTAL_BUDGET_MS3 = 1000;
|
|
92995
|
-
var NEGATIVE_CACHE_TTL_MS2 = 60000;
|
|
92996
|
-
var BARE_GLAB = "glab";
|
|
92997
|
-
var PROBE_MAX_BUFFER_BYTES2 = 64 * 1024;
|
|
92998
|
-
var PROBE_OUTPUT_EXCERPT_CHARS2 = 60;
|
|
92999
|
-
var WINDOWS_PATH_EXTENSIONS2 = [".exe", ".cmd", ".bat"];
|
|
93000
|
-
var GLAB_VERSION_PATTERN = /^glab version \d+\.\d+/;
|
|
93001
|
-
function excerptProbeOutput2(raw) {
|
|
93002
|
-
return raw.slice(0, PROBE_OUTPUT_EXCERPT_CHARS2).replace(/[^\x20-\x7E]/g, " ").trim();
|
|
93003
|
-
}
|
|
93004
|
-
var cache3 = null;
|
|
93005
|
-
var lastAttempts2 = [];
|
|
93006
|
-
var cacheGeneration2 = 0;
|
|
93007
|
-
function windowsGlabAbsoluteCandidates(env) {
|
|
93008
|
-
const candidates = [];
|
|
93009
|
-
const push = (...parts) => {
|
|
93010
|
-
const candidate2 = path128.join(...parts);
|
|
93011
|
-
if (!candidates.includes(candidate2))
|
|
93012
|
-
candidates.push(candidate2);
|
|
93013
|
-
};
|
|
93014
|
-
if (env.ProgramFiles) {
|
|
93015
|
-
push(env.ProgramFiles, "GitLab CLI", "glab.exe");
|
|
93016
|
-
}
|
|
93017
|
-
if (env["ProgramFiles(x86)"]) {
|
|
93018
|
-
push(env["ProgramFiles(x86)"], "GitLab CLI", "glab.exe");
|
|
93019
|
-
}
|
|
93020
|
-
if (env.LOCALAPPDATA) {
|
|
93021
|
-
push(env.LOCALAPPDATA, "GitLab CLI", "glab.exe");
|
|
93022
|
-
push(env.LOCALAPPDATA, "Programs", "GitLab CLI", "glab.exe");
|
|
93023
|
-
}
|
|
93024
|
-
return candidates;
|
|
93025
|
-
}
|
|
93026
|
-
function platformCandidates2(platform, env) {
|
|
93027
|
-
if (platform === "win32") {
|
|
93028
|
-
return windowsGlabAbsoluteCandidates(env);
|
|
93029
|
-
}
|
|
93030
|
-
if (platform === "darwin") {
|
|
93031
|
-
return ["/opt/homebrew/bin/glab", "/usr/local/bin/glab", "/usr/bin/glab"];
|
|
93032
|
-
}
|
|
93033
|
-
return ["/usr/bin/glab", "/usr/local/bin/glab", "/bin/glab"];
|
|
93034
|
-
}
|
|
93035
|
-
function isAbsoluteForPlatform2(candidate2, platform) {
|
|
93036
|
-
return platform === "win32" ? path128.win32.isAbsolute(candidate2) : path128.posix.isAbsolute(candidate2);
|
|
93037
|
-
}
|
|
93038
|
-
function joinDirAndName2(dir, name, platform) {
|
|
93039
|
-
const sep22 = platform === "win32" ? "\\" : "/";
|
|
93040
|
-
const trimmed = dir.replace(/[\\/]+$/, "");
|
|
93041
|
-
return trimmed ? `${trimmed}${sep22}${name}` : `${sep22}${name}`;
|
|
93042
|
-
}
|
|
93043
|
-
function pathCandidates2(platform) {
|
|
93044
|
-
const pathValue = _internals102.env().PATH ?? "";
|
|
93045
|
-
if (!pathValue)
|
|
93046
|
-
return [];
|
|
93047
|
-
const dirs = pathValue.split(platform === "win32" ? ";" : ":").filter(Boolean);
|
|
93048
|
-
const names = platform === "win32" ? [...WINDOWS_PATH_EXTENSIONS2.map((ext) => `glab${ext}`), "glab"] : ["glab"];
|
|
93049
|
-
const out = [];
|
|
93050
|
-
for (const dir of dirs) {
|
|
93051
|
-
for (const name of names) {
|
|
93052
|
-
const candidate2 = joinDirAndName2(dir, name, platform);
|
|
93053
|
-
if (!out.includes(candidate2))
|
|
93054
|
-
out.push(candidate2);
|
|
93055
|
-
}
|
|
93056
|
-
}
|
|
93057
|
-
return out;
|
|
93058
|
-
}
|
|
93059
|
-
function envOverride2() {
|
|
93060
|
-
const raw = _internals102.env()[GLAB_BINARY_ENV_VAR];
|
|
93061
|
-
return raw && raw.trim() !== "" ? raw : undefined;
|
|
93062
|
-
}
|
|
93063
|
-
function buildCandidates2(platform) {
|
|
93064
|
-
const override = envOverride2();
|
|
93065
|
-
const overrideCandidate = override ? [{ source: "override", path: override }] : [];
|
|
93066
|
-
const seen = new Set(overrideCandidate.map((c) => c.path));
|
|
93067
|
-
const rest = [];
|
|
93068
|
-
for (const p of platformCandidates2(platform, _internals102.env())) {
|
|
93069
|
-
if (seen.has(p))
|
|
93070
|
-
continue;
|
|
93071
|
-
seen.add(p);
|
|
93072
|
-
rest.push({ source: "platform", path: p });
|
|
93073
|
-
}
|
|
93074
|
-
for (const p of pathCandidates2(platform)) {
|
|
93075
|
-
if (seen.has(p))
|
|
93076
|
-
continue;
|
|
93077
|
-
seen.add(p);
|
|
93078
|
-
rest.push({ source: "path", path: p });
|
|
93079
|
-
}
|
|
93080
|
-
return [...overrideCandidate, ...rest];
|
|
93081
|
-
}
|
|
93082
|
-
function probeCandidate2(candidatePath2, platform) {
|
|
93083
|
-
if (!isAbsoluteForPlatform2(candidatePath2, platform)) {
|
|
93084
|
-
return { accepted: false, reason: "not an absolute path" };
|
|
93085
|
-
}
|
|
93086
|
-
let stat14;
|
|
93087
|
-
try {
|
|
93088
|
-
stat14 = fs64.statSync(candidatePath2);
|
|
93089
|
-
} catch (err) {
|
|
93090
|
-
const code = err?.code;
|
|
93091
|
-
if (code === "ENOENT")
|
|
93092
|
-
return { accepted: false, reason: "no such file" };
|
|
93093
|
-
return {
|
|
93094
|
-
accepted: false,
|
|
93095
|
-
reason: `cannot stat (${code ?? "unknown error"})`
|
|
93096
|
-
};
|
|
93097
|
-
}
|
|
93098
|
-
if (stat14.isDirectory()) {
|
|
93099
|
-
return { accepted: false, reason: "is a directory" };
|
|
93100
|
-
}
|
|
93101
|
-
if (!stat14.isFile()) {
|
|
93102
|
-
return { accepted: false, reason: "not a regular file" };
|
|
93103
|
-
}
|
|
93104
|
-
let result;
|
|
93105
|
-
try {
|
|
93106
|
-
result = _internals102.spawnSync(candidatePath2, ["--version"], {
|
|
93107
|
-
cwd: os14.tmpdir(),
|
|
93108
|
-
stdio: ["ignore", "pipe", "ignore"],
|
|
93109
|
-
windowsHide: true,
|
|
93110
|
-
timeout: PER_PROBE_TIMEOUT_MS2,
|
|
93111
|
-
maxBuffer: PROBE_MAX_BUFFER_BYTES2
|
|
93112
|
-
});
|
|
93113
|
-
} catch (err) {
|
|
93114
|
-
return {
|
|
93115
|
-
accepted: false,
|
|
93116
|
-
reason: `spawn threw: ${err instanceof Error ? err.message : String(err)}`
|
|
93117
|
-
};
|
|
93118
|
-
}
|
|
93119
|
-
if (result.error) {
|
|
93120
|
-
return { accepted: false, reason: `spawn failed: ${result.error.message}` };
|
|
93121
|
-
}
|
|
93122
|
-
if (result.status !== 0) {
|
|
93123
|
-
const statusDescription = result.status !== null ? `exit ${result.status}` : `signal ${result.signal ?? "unknown"}`;
|
|
93124
|
-
return {
|
|
93125
|
-
accepted: false,
|
|
93126
|
-
reason: `glab --version returned ${statusDescription}`
|
|
93127
|
-
};
|
|
93128
|
-
}
|
|
93129
|
-
const versionOutput = (result.stdout ?? "").toString().trim();
|
|
93130
|
-
if (!GLAB_VERSION_PATTERN.test(versionOutput)) {
|
|
93131
|
-
const excerpt = excerptProbeOutput2(versionOutput);
|
|
93132
|
-
return {
|
|
93133
|
-
accepted: false,
|
|
93134
|
-
reason: excerpt ? `not glab: --version printed "${excerpt}"` : "not glab: --version printed nothing"
|
|
93135
|
-
};
|
|
93136
|
-
}
|
|
93137
|
-
return { accepted: true };
|
|
93138
|
-
}
|
|
93139
|
-
function probeCycle2(candidates, platform, attempts) {
|
|
93140
|
-
const start = _internals102.now();
|
|
93141
|
-
let budgetExceeded = false;
|
|
93142
|
-
for (const candidate2 of candidates) {
|
|
93143
|
-
if (_internals102.now() - start > TOTAL_BUDGET_MS3) {
|
|
93144
|
-
budgetExceeded = true;
|
|
93145
|
-
break;
|
|
93146
|
-
}
|
|
93147
|
-
const result = probeCandidate2(candidate2.path, platform);
|
|
93148
|
-
attempts.push({
|
|
93149
|
-
source: candidate2.source,
|
|
93150
|
-
candidate: candidate2.path,
|
|
93151
|
-
accepted: result.accepted,
|
|
93152
|
-
reason: result.accepted ? undefined : result.reason
|
|
93153
|
-
});
|
|
93154
|
-
if (candidate2.source === "override" && !result.accepted) {
|
|
93155
|
-
advisoryWarn(`[opencode-swarm] ${GLAB_BINARY_ENV_VAR} override "${candidate2.path}" is unusable (${result.reason}); falling back to automatic glab resolution.`);
|
|
93156
|
-
}
|
|
93157
|
-
if (result.accepted) {
|
|
93158
|
-
return { outcome: "accepted", path: candidate2.path };
|
|
93159
|
-
}
|
|
93160
|
-
}
|
|
93161
|
-
return budgetExceeded ? { outcome: "exhausted-budget" } : { outcome: "all-rejected" };
|
|
93162
|
-
}
|
|
93163
|
-
function readCache3() {
|
|
93164
|
-
if (cache3 === null)
|
|
93165
|
-
return null;
|
|
93166
|
-
if (cache3.kind === "success")
|
|
93167
|
-
return cache3;
|
|
93168
|
-
if (_internals102.now() < cache3.expiresAt)
|
|
93169
|
-
return cache3;
|
|
93170
|
-
cache3 = null;
|
|
93171
|
-
return null;
|
|
93172
|
-
}
|
|
93173
|
-
function applyProbeResult2(result, attempts, generation) {
|
|
93174
|
-
if (generation !== cacheGeneration2) {
|
|
93175
|
-
return result.outcome === "accepted" ? result.path : BARE_GLAB;
|
|
93176
|
-
}
|
|
93177
|
-
lastAttempts2 = attempts;
|
|
93178
|
-
if (result.outcome === "accepted") {
|
|
93179
|
-
cache3 = { kind: "success", path: result.path };
|
|
93180
|
-
return result.path;
|
|
93181
|
-
}
|
|
93182
|
-
cache3 = {
|
|
93183
|
-
kind: "fallback",
|
|
93184
|
-
expiresAt: _internals102.now() + NEGATIVE_CACHE_TTL_MS2
|
|
93185
|
-
};
|
|
93186
|
-
return BARE_GLAB;
|
|
93187
|
-
}
|
|
93188
|
-
function resolveGlabExecutable() {
|
|
93189
|
-
const cached = readCache3();
|
|
93190
|
-
if (cached)
|
|
93191
|
-
return cached.kind === "success" ? cached.path : BARE_GLAB;
|
|
93192
|
-
const platform = _internals102.platform();
|
|
93193
|
-
const attempts = [];
|
|
93194
|
-
const generation = cacheGeneration2;
|
|
93195
|
-
const candidates = buildCandidates2(platform);
|
|
93196
|
-
const result = probeCycle2(candidates, platform, attempts);
|
|
93197
|
-
return applyProbeResult2(result, attempts, generation);
|
|
93198
|
-
}
|
|
93199
|
-
var _internals102 = {
|
|
93200
|
-
spawnSync: spawnSync6,
|
|
93201
|
-
platform: () => process.platform,
|
|
93202
|
-
env: () => process.env,
|
|
93203
|
-
now: () => Date.now()
|
|
93204
|
-
};
|
|
93205
|
-
|
|
93206
|
-
// src/background/pr-monitor-worker.ts
|
|
93207
93347
|
var prMonitorWorkerRegistry = new Map;
|
|
93208
93348
|
function getPrMonitorWorkerHealth(directory) {
|
|
93209
93349
|
return prMonitorWorkerRegistry.get(directory)?.getHealth() ?? null;
|
|
@@ -93413,12 +93553,7 @@ class PrMonitorWorker {
|
|
|
93413
93553
|
async pollSinglePr(sub, isTimedOut, isProbe = false) {
|
|
93414
93554
|
const correlationId = sub.correlationId;
|
|
93415
93555
|
const forgeContext = detectForgeFromUrl(sub.prUrl) ?? (sub.forge ? { provider: sub.forge.provider, host: sub.forge.host } : null);
|
|
93416
|
-
|
|
93417
|
-
const glabBinary = resolveGlabExecutable();
|
|
93418
|
-
const glabStatus = glabBinary === "glab" ? "glab binary not resolved (bare-name fallback)" : "glab binary resolved";
|
|
93419
|
-
log("[PrMonitorWorker] GitLab MR monitoring unavailable: glab-backed polling is not wired yet (issue #2882); skipping gh poll for this subscription", { correlationId, glabStatus });
|
|
93420
|
-
return;
|
|
93421
|
-
}
|
|
93556
|
+
const isGitLab = forgeContext?.provider === "gitlab";
|
|
93422
93557
|
if (!this.circuitBreakerMap.has(correlationId) && sub.errorCount > 0) {
|
|
93423
93558
|
this.circuitBreakerMap.set(correlationId, {
|
|
93424
93559
|
errorCount: sub.errorCount,
|
|
@@ -93443,40 +93578,76 @@ class PrMonitorWorker {
|
|
|
93443
93578
|
return;
|
|
93444
93579
|
}
|
|
93445
93580
|
try {
|
|
93446
|
-
|
|
93447
|
-
|
|
93448
|
-
|
|
93449
|
-
|
|
93450
|
-
|
|
93451
|
-
|
|
93452
|
-
|
|
93453
|
-
});
|
|
93454
|
-
return;
|
|
93455
|
-
}
|
|
93456
|
-
let mergeGroupRunResult = null;
|
|
93457
|
-
let mergeGroupRunFetchSucceeded = false;
|
|
93458
|
-
try {
|
|
93459
|
-
mergeGroupRunResult = await _internals103.getMergeGroupRun(snapshot.status.statusCheckRollup, sub.repoFullName, this.directory);
|
|
93460
|
-
mergeGroupRunFetchSucceeded = true;
|
|
93461
|
-
} catch (err) {
|
|
93462
|
-
log("[PrMonitorWorker] Failed to fetch merge group run", {
|
|
93463
|
-
correlationId: sub.correlationId,
|
|
93464
|
-
error: err instanceof Error ? err.message : String(err)
|
|
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
|
|
93465
93588
|
});
|
|
93466
|
-
|
|
93467
|
-
|
|
93468
|
-
|
|
93469
|
-
|
|
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
|
|
93470
93614
|
});
|
|
93471
|
-
|
|
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);
|
|
93472
93650
|
}
|
|
93473
|
-
const changes = this.computeChanges(sub, {
|
|
93474
|
-
status: snapshot.status,
|
|
93475
|
-
comments: [...snapshot.comments, ...reviewComments],
|
|
93476
|
-
merge: snapshot.merge,
|
|
93477
|
-
review: snapshot.review,
|
|
93478
|
-
mergeGroupRun: mergeGroupRunResult
|
|
93479
|
-
}, mergeGroupRunFetchSucceeded);
|
|
93480
93651
|
await this.applyChanges(sub, changes, isTimedOut);
|
|
93481
93652
|
if (!isTimedOut?.()) {
|
|
93482
93653
|
this.circuitBreakerMap.delete(correlationId);
|
|
@@ -93512,7 +93683,7 @@ class PrMonitorWorker {
|
|
|
93512
93683
|
await this.handlePollError(sub, err instanceof Error ? err : new Error(String(err)));
|
|
93513
93684
|
}
|
|
93514
93685
|
}
|
|
93515
|
-
computeChanges(sub, current, mergeGroupRunFetchSucceeded) {
|
|
93686
|
+
computeChanges(sub, current, mergeGroupRunFetchSucceeded, gitLabPipelines) {
|
|
93516
93687
|
const events = [];
|
|
93517
93688
|
const snapshotUpdates = {
|
|
93518
93689
|
headRefOid: current.status.headRefOid,
|
|
@@ -93539,13 +93710,17 @@ class PrMonitorWorker {
|
|
|
93539
93710
|
}
|
|
93540
93711
|
});
|
|
93541
93712
|
}
|
|
93542
|
-
const
|
|
93543
|
-
|
|
93544
|
-
if (
|
|
93545
|
-
const
|
|
93546
|
-
|
|
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;
|
|
93547
93723
|
}
|
|
93548
|
-
snapshotUpdates.lastCheckRunSet = currentCheckSet;
|
|
93549
93724
|
if (current.comments.length > 0) {
|
|
93550
93725
|
const sorted2 = [...current.comments].sort((a, b) => a.createdAt.localeCompare(b.createdAt));
|
|
93551
93726
|
let newComments;
|
|
@@ -93877,6 +94052,8 @@ class PrMonitorWorker {
|
|
|
93877
94052
|
var _internals103 = {
|
|
93878
94053
|
getPRPollSnapshot,
|
|
93879
94054
|
getPRReviewComments,
|
|
94055
|
+
getMRPollSnapshot,
|
|
94056
|
+
getMRComments,
|
|
93880
94057
|
getMergeGroupRun,
|
|
93881
94058
|
listActive,
|
|
93882
94059
|
updateSnapshot,
|
|
@@ -94240,11 +94417,10 @@ async function handlePrSubscribeCommand(directory, args, sessionID) {
|
|
|
94240
94417
|
deliveryLine
|
|
94241
94418
|
].concat(prUrl.includes("/-/merge_requests/") ? [
|
|
94242
94419
|
"",
|
|
94243
|
-
"Note: live monitoring is
|
|
94244
|
-
"
|
|
94245
|
-
"
|
|
94246
|
-
"
|
|
94247
|
-
"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)."
|
|
94248
94424
|
] : []).join(`
|
|
94249
94425
|
`);
|
|
94250
94426
|
} catch (err) {
|
|
@@ -109309,7 +109485,7 @@ function buildDetailedHelp(commandName, entry) {
|
|
|
109309
109485
|
async function handleHelpCommand(ctx) {
|
|
109310
109486
|
const targetCommand = ctx.args.join(" ");
|
|
109311
109487
|
if (!targetCommand) {
|
|
109312
|
-
const { buildHelpText } = await import("./index-
|
|
109488
|
+
const { buildHelpText } = await import("./index-4dwhfbed.js");
|
|
109313
109489
|
return buildHelpText();
|
|
109314
109490
|
}
|
|
109315
109491
|
const tokens = targetCommand.split(/\s+/);
|
|
@@ -109323,7 +109499,7 @@ async function handleHelpCommand(ctx) {
|
|
|
109323
109499
|
> Note: \`/swarm ${resolved.key}\` is a deprecated alias for \`/swarm ${aliasTarget}\`.` : detailed;
|
|
109324
109500
|
}
|
|
109325
109501
|
const similar = _internals27.findSimilarCommands(targetCommand);
|
|
109326
|
-
const { buildHelpText: fullHelp } = await import("./index-
|
|
109502
|
+
const { buildHelpText: fullHelp } = await import("./index-4dwhfbed.js");
|
|
109327
109503
|
if (similar.length > 0) {
|
|
109328
109504
|
return `Command '/swarm ${targetCommand}' not found.
|
|
109329
109505
|
|
|
@@ -109358,6 +109534,18 @@ async function handleModeCommandWithBundledSkills(ctx, handler, mechanicalMode)
|
|
|
109358
109534
|
}
|
|
109359
109535
|
return result;
|
|
109360
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
|
+
}
|
|
109361
109549
|
async function handlePrFeedbackCommandWithTransition(ctx) {
|
|
109362
109550
|
if (ctx.packageRoot) {
|
|
109363
109551
|
await syncBundledProjectSkillsIfMissingAsync(ctx.directory, ctx.packageRoot, true);
|
|
@@ -109388,7 +109576,8 @@ async function handlePrFeedbackCommandWithTransition(ctx) {
|
|
|
109388
109576
|
} else {
|
|
109389
109577
|
await activatePrWorkflow(ctx.directory, ctx.sessionID, "PR_FEEDBACK", {
|
|
109390
109578
|
requireCheckoutPreflight: true,
|
|
109391
|
-
...parsed.prUrl ? { prUrl: parsed.prUrl } : {}
|
|
109579
|
+
...parsed.prUrl ? { prUrl: parsed.prUrl } : {},
|
|
109580
|
+
...parsed.prUrl ? { forge: resolveCommandForgeContext(ctx.directory, parsed.prUrl) } : {}
|
|
109392
109581
|
});
|
|
109393
109582
|
}
|
|
109394
109583
|
return handlePrFeedbackCommand(ctx.directory, ctx.args);
|
|
@@ -109638,7 +109827,7 @@ var COMMAND_REGISTRY = {
|
|
|
109638
109827
|
},
|
|
109639
109828
|
"guardrail explain": {
|
|
109640
109829
|
handler: async (ctx) => {
|
|
109641
|
-
const { handleGuardrailExplain } = await import("./guardrail-explain-
|
|
109830
|
+
const { handleGuardrailExplain } = await import("./guardrail-explain-njv3pnsw.js");
|
|
109642
109831
|
return handleGuardrailExplain(ctx.directory, ctx.args);
|
|
109643
109832
|
},
|
|
109644
109833
|
description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
|
|
@@ -109648,7 +109837,7 @@ var COMMAND_REGISTRY = {
|
|
|
109648
109837
|
},
|
|
109649
109838
|
"guardrail reset": {
|
|
109650
109839
|
handler: async (ctx) => {
|
|
109651
|
-
const { handleGuardrailReset } = await import("./guardrail-reset-
|
|
109840
|
+
const { handleGuardrailReset } = await import("./guardrail-reset-11cvwgbe.js");
|
|
109652
109841
|
return handleGuardrailReset(ctx.args, ctx.sessionID);
|
|
109653
109842
|
},
|
|
109654
109843
|
description: "Reset one exact active invocation/action circuit after repair",
|
|
@@ -109669,7 +109858,7 @@ var COMMAND_REGISTRY = {
|
|
|
109669
109858
|
},
|
|
109670
109859
|
"guardrail-log": {
|
|
109671
109860
|
handler: async (ctx) => {
|
|
109672
|
-
const { handleGuardrailLog } = await import("./guardrail-log-
|
|
109861
|
+
const { handleGuardrailLog } = await import("./guardrail-log-r8zmh4rd.js");
|
|
109673
109862
|
return handleGuardrailLog(ctx.directory, ctx.args);
|
|
109674
109863
|
},
|
|
109675
109864
|
description: "Read the guardrail decision log (use --blocks-only for blocks)",
|