opencode-swarm 7.128.0 → 7.129.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/{curation-policy-82czah39.js → curation-policy-vn1ybh31.js} +2 -2
- package/dist/cli/{curator-x5dzf1p7.js → curator-2nhjd2mn.js} +13 -13
- package/dist/cli/{curator-drift-24bdacdc.js → curator-drift-y1wm4atk.js} +1 -1
- package/dist/cli/{curator-llm-factory-rz4cbq28.js → curator-llm-factory-xbstvmpx.js} +13 -13
- package/dist/cli/{evidence-summary-service-thx1c3me.js → evidence-summary-service-hf7qq777.js} +2 -2
- package/dist/cli/{guardrail-explain-fwvxteqe.js → guardrail-explain-87wprr65.js} +14 -14
- package/dist/cli/{hive-promoter-z8gc80zq.js → hive-promoter-va29r2p0.js} +13 -13
- package/dist/cli/{index-nmedh7bw.js → index-3yd6bbnp.js} +14 -14
- package/dist/cli/{index-gn62e04k.js → index-5fnc76da.js} +1 -1
- package/dist/cli/{index-hv2p03f3.js → index-6w02qz7t.js} +250 -5
- package/dist/cli/{index-23zsx7dm.js → index-g4mnf3p5.js} +1 -1
- package/dist/cli/{index-npycj2tr.js → index-gczs3jy7.js} +41086 -40944
- package/dist/cli/{index-1mwdhq2p.js → index-kj86tyrs.js} +1 -1
- package/dist/cli/{index-edv27z4p.js → index-kxw2sx1d.js} +3 -1
- package/dist/cli/{index-kk1scggc.js → index-kzvwb2se.js} +1 -1
- package/dist/cli/{index-ff3j65em.js → index-m8vrw3pt.js} +4 -4
- package/dist/cli/{index-3ntrn97w.js → index-pgyp3tta.js} +1 -1
- package/dist/cli/{index-2445sx3d.js → index-s80bsjkj.js} +13 -4
- package/dist/cli/{index-rczj39pc.js → index-ty0xttaz.js} +1 -1
- package/dist/cli/{index-72envp1b.js → index-w2kp2zvf.js} +3 -3
- package/dist/cli/{index-ns62nv6t.js → index-waqvy9a5.js} +2 -2
- package/dist/cli/{index-c4mcheyz.js → index-wy5jy3m9.js} +3 -3
- package/dist/cli/{index-ecxwhwz7.js → index-y2pfmd0z.js} +1 -1
- package/dist/cli/index.js +13 -13
- package/dist/cli/{knowledge-escalator-b3k4b8pk.js → knowledge-escalator-5ytt2y9n.js} +3 -3
- package/dist/cli/{knowledge-events-4z5rkefv.js → knowledge-events-qnyfrsfv.js} +1 -1
- package/dist/cli/{knowledge-store-c0t16yr4.js → knowledge-store-yeybvcqw.js} +1 -1
- package/dist/cli/{knowledge-validator-cs33ws57.js → knowledge-validator-g2c4mbwa.js} +4 -4
- package/dist/cli/{pending-delegations-a1bbpp8b.js → pending-delegations-37t4xecr.js} +2 -2
- package/dist/cli/{pr-subscriptions-bxpqde8w.js → pr-subscriptions-zqbmctwz.js} +2 -2
- package/dist/cli/{scan-cursor-rgnarf67.js → scan-cursor-c5mcce5r.js} +2 -2
- package/dist/cli/{skill-generator-e8c2r816.js → skill-generator-c77e0y98.js} +5 -5
- package/dist/config/index.d.ts +1 -1
- package/dist/config/loader-recovery.d.ts +95 -0
- package/dist/config/loader.d.ts +26 -1
- package/dist/config/sanitize-malformed-values.d.ts +53 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +19 -19
- package/package.json +1 -1
|
@@ -608,7 +608,7 @@ async function applyKnowledgeVerdictFeedback(directory, options) {
|
|
|
608
608
|
deltas.push({ id, delta });
|
|
609
609
|
}
|
|
610
610
|
if (deltas.length > 0) {
|
|
611
|
-
const { bumpKnowledgeConfidenceBatch } = await import("./knowledge-store-
|
|
611
|
+
const { bumpKnowledgeConfidenceBatch } = await import("./knowledge-store-yeybvcqw.js");
|
|
612
612
|
await bumpKnowledgeConfidenceBatch(directory, deltas, options?.floorOptions);
|
|
613
613
|
}
|
|
614
614
|
return {
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
_internals,
|
|
4
|
+
getSafeDefaultConfigLoadResult,
|
|
4
5
|
loadAgentPrompt,
|
|
5
6
|
loadPluginConfig,
|
|
6
7
|
loadPluginConfigWithMeta,
|
|
7
8
|
loadPluginConfigWithMetaAsync,
|
|
8
9
|
resolveWorktreeIsolationConfig
|
|
9
|
-
} from "./index-
|
|
10
|
+
} from "./index-6w02qz7t.js";
|
|
10
11
|
import {
|
|
11
12
|
ApprovalEvidenceSchema,
|
|
12
13
|
BaseEvidenceSchema,
|
|
@@ -83,6 +84,7 @@ export {
|
|
|
83
84
|
loadAgentPrompt,
|
|
84
85
|
isSubagent,
|
|
85
86
|
isQAAgent,
|
|
87
|
+
getSafeDefaultConfigLoadResult,
|
|
86
88
|
_internals,
|
|
87
89
|
WorktreeIsolationConfigSchema,
|
|
88
90
|
TurboConfigSchema,
|
|
@@ -6,13 +6,13 @@ import {
|
|
|
6
6
|
resolveSwarmKnowledgePath,
|
|
7
7
|
transactKnowledge,
|
|
8
8
|
wordBigrams
|
|
9
|
-
} from "./index-
|
|
9
|
+
} from "./index-w2kp2zvf.js";
|
|
10
10
|
import {
|
|
11
11
|
countEntryContradictionsInWindow,
|
|
12
12
|
countEntryViolationsInWindow,
|
|
13
13
|
readKnowledgeEvents,
|
|
14
14
|
recordKnowledgeEvent
|
|
15
|
-
} from "./index-
|
|
15
|
+
} from "./index-kj86tyrs.js";
|
|
16
16
|
import {
|
|
17
17
|
init_knowledge_types,
|
|
18
18
|
isActiveStatus
|
|
@@ -190,11 +190,11 @@ async function maybeQuarantineOnContradiction(directory, entryId, threshold, win
|
|
|
190
190
|
alreadyInactive: true
|
|
191
191
|
};
|
|
192
192
|
}
|
|
193
|
-
const { quarantineEntry } = await import("./knowledge-validator-
|
|
193
|
+
const { quarantineEntry } = await import("./knowledge-validator-g2c4mbwa.js");
|
|
194
194
|
let policyConfig;
|
|
195
195
|
try {
|
|
196
196
|
const { KnowledgeConfigSchema } = await import("./schema-2x7wsb0n.js");
|
|
197
|
-
const { loadPluginConfigWithMeta } = await import("./index-
|
|
197
|
+
const { loadPluginConfigWithMeta } = await import("./index-kxw2sx1d.js");
|
|
198
198
|
const { config: loadedConfig } = loadPluginConfigWithMeta(directory);
|
|
199
199
|
policyConfig = KnowledgeConfigSchema.parse(loadedConfig.knowledge ?? {});
|
|
200
200
|
} catch {
|
|
@@ -140,8 +140,9 @@ async function readSwarmFileAsync(directory, filename, cache) {
|
|
|
140
140
|
cache.set(key, promise);
|
|
141
141
|
return promise;
|
|
142
142
|
}
|
|
143
|
-
const
|
|
144
|
-
const
|
|
143
|
+
const ENOENT_MAX_ATTEMPTS = 5;
|
|
144
|
+
const ENOENT_RETRY_DELAY_MS = 10;
|
|
145
|
+
const maxAttempts = 6;
|
|
145
146
|
for (let attempt = 0;attempt < maxAttempts; attempt++) {
|
|
146
147
|
try {
|
|
147
148
|
const resolvedPath = _internals.validateSwarmPath(directory, filename);
|
|
@@ -150,10 +151,18 @@ async function readSwarmFileAsync(directory, filename, cache) {
|
|
|
150
151
|
return await file.text();
|
|
151
152
|
});
|
|
152
153
|
} catch (err) {
|
|
153
|
-
const
|
|
154
|
-
if (
|
|
154
|
+
const code = err?.code;
|
|
155
|
+
if (code === "ENOENT") {
|
|
156
|
+
if (attempt >= ENOENT_MAX_ATTEMPTS - 1)
|
|
157
|
+
return null;
|
|
158
|
+
await new Promise((resolve2) => setTimeout(resolve2, ENOENT_RETRY_DELAY_MS));
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
const isAvRetryable = code === "EBUSY" || code === "EPERM" || code === "EACCES";
|
|
162
|
+
if (!isAvRetryable || attempt === maxAttempts - 1) {
|
|
155
163
|
return null;
|
|
156
164
|
}
|
|
165
|
+
const retryDelayMs = 10 * 2 ** attempt;
|
|
157
166
|
await new Promise((resolve2) => setTimeout(resolve2, retryDelayMs));
|
|
158
167
|
}
|
|
159
168
|
}
|
|
@@ -650,7 +650,7 @@ async function applyConfidenceFloorAction(directory, touched, options) {
|
|
|
650
650
|
const recovered = touched.filter((e) => e.confidence > CONFIDENCE_FLOOR + FLOOR_EPSILON && e.confidence_floor_demoted);
|
|
651
651
|
if (atFloor.length === 0 && recovered.length === 0)
|
|
652
652
|
return;
|
|
653
|
-
const { readKnowledgeCounterRollups, effectiveRetrievalOutcomes } = await import("./knowledge-events-
|
|
653
|
+
const { readKnowledgeCounterRollups, effectiveRetrievalOutcomes } = await import("./knowledge-events-qnyfrsfv.js");
|
|
654
654
|
const rollups = await readKnowledgeCounterRollups(directory);
|
|
655
655
|
const flagIds = new Set;
|
|
656
656
|
for (const e of atFloor) {
|
|
@@ -717,11 +717,11 @@ async function applyConfidenceFloorAction(directory, touched, options) {
|
|
|
717
717
|
});
|
|
718
718
|
}
|
|
719
719
|
if (action === "quarantine" && toQuarantine.length > 0) {
|
|
720
|
-
const { quarantineEntry } = await import("./knowledge-validator-
|
|
720
|
+
const { quarantineEntry } = await import("./knowledge-validator-g2c4mbwa.js");
|
|
721
721
|
const { KnowledgeConfigSchema } = await import("./schema-2x7wsb0n.js");
|
|
722
722
|
let config;
|
|
723
723
|
try {
|
|
724
|
-
const { loadPluginConfigWithMeta } = await import("./index-
|
|
724
|
+
const { loadPluginConfigWithMeta } = await import("./index-kxw2sx1d.js");
|
|
725
725
|
const { config: loadedConfig } = loadPluginConfigWithMeta(directory);
|
|
726
726
|
config = KnowledgeConfigSchema.parse(loadedConfig.knowledge ?? {});
|
|
727
727
|
} catch {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
authorizeCuration
|
|
4
|
-
} from "./index-
|
|
4
|
+
} from "./index-pgyp3tta.js";
|
|
5
5
|
import {
|
|
6
6
|
findNearDuplicate,
|
|
7
7
|
inferTags,
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
resolveSwarmKnowledgePath,
|
|
10
10
|
resolveSwarmRejectedPath,
|
|
11
11
|
transactKnowledge
|
|
12
|
-
} from "./index-
|
|
12
|
+
} from "./index-w2kp2zvf.js";
|
|
13
13
|
import {
|
|
14
14
|
resolveKnowledgeStoreDir
|
|
15
15
|
} from "./index-q27bajqb.js";
|
|
@@ -2,18 +2,18 @@
|
|
|
2
2
|
import {
|
|
3
3
|
ALLOWED_SKILL_PATH_PREFIXES,
|
|
4
4
|
validateSkillPath
|
|
5
|
-
} from "./index-
|
|
5
|
+
} from "./index-waqvy9a5.js";
|
|
6
6
|
import {
|
|
7
7
|
computeOutcomeSignal,
|
|
8
8
|
readKnowledge,
|
|
9
9
|
resolveHiveKnowledgePath,
|
|
10
10
|
resolveSwarmKnowledgePath,
|
|
11
11
|
transactKnowledge
|
|
12
|
-
} from "./index-
|
|
12
|
+
} from "./index-w2kp2zvf.js";
|
|
13
13
|
import {
|
|
14
14
|
effectiveRetrievalOutcomes,
|
|
15
15
|
readKnowledgeCounterRollups
|
|
16
|
-
} from "./index-
|
|
16
|
+
} from "./index-kj86tyrs.js";
|
|
17
17
|
import {
|
|
18
18
|
init_knowledge_types,
|
|
19
19
|
isActiveStatus
|
package/dist/cli/index.js
CHANGED
|
@@ -7,28 +7,28 @@ import {
|
|
|
7
7
|
getPluginLockFilePaths,
|
|
8
8
|
package_default,
|
|
9
9
|
resolveCommand
|
|
10
|
-
} from "./index-
|
|
10
|
+
} from "./index-gczs3jy7.js";
|
|
11
11
|
import"./index-v4n224r1.js";
|
|
12
12
|
import"./index-cpssctv1.js";
|
|
13
|
-
import"./index-
|
|
13
|
+
import"./index-kzvwb2se.js";
|
|
14
14
|
import"./index-4905hd2m.js";
|
|
15
15
|
import"./index-134d35c1.js";
|
|
16
16
|
import"./index-6n2jpz7x.js";
|
|
17
|
-
import"./index-
|
|
18
|
-
import"./index-
|
|
19
|
-
import"./index-
|
|
17
|
+
import"./index-wy5jy3m9.js";
|
|
18
|
+
import"./index-m8vrw3pt.js";
|
|
19
|
+
import"./index-5fnc76da.js";
|
|
20
20
|
import"./index-vxv732ex.js";
|
|
21
21
|
import"./index-c8s9a3zh.js";
|
|
22
22
|
import"./index-9ss2m4rs.js";
|
|
23
|
-
import"./index-
|
|
24
|
-
import"./index-
|
|
25
|
-
import"./index-
|
|
23
|
+
import"./index-g4mnf3p5.js";
|
|
24
|
+
import"./index-waqvy9a5.js";
|
|
25
|
+
import"./index-pgyp3tta.js";
|
|
26
26
|
import"./index-rtry5xyf.js";
|
|
27
|
-
import"./index-
|
|
28
|
-
import"./index-
|
|
27
|
+
import"./index-w2kp2zvf.js";
|
|
28
|
+
import"./index-kj86tyrs.js";
|
|
29
29
|
import"./index-ae75rja9.js";
|
|
30
30
|
import"./index-q27bajqb.js";
|
|
31
|
-
import"./index-
|
|
31
|
+
import"./index-6w02qz7t.js";
|
|
32
32
|
import"./index-k5jrywpr.js";
|
|
33
33
|
import"./index-n832052r.js";
|
|
34
34
|
import {
|
|
@@ -43,8 +43,8 @@ import"./index-2tn5h2zp.js";
|
|
|
43
43
|
import"./index-1kz6da87.js";
|
|
44
44
|
import"./index-w9cb5zwh.js";
|
|
45
45
|
import"./index-4rhhvd1a.js";
|
|
46
|
-
import"./index-
|
|
47
|
-
import"./index-
|
|
46
|
+
import"./index-y2pfmd0z.js";
|
|
47
|
+
import"./index-s80bsjkj.js";
|
|
48
48
|
import"./index-z6xqpmqg.js";
|
|
49
49
|
import"./index-zjygnfay.js";
|
|
50
50
|
import"./index-zgwm4ryv.js";
|
|
@@ -8,9 +8,9 @@ import {
|
|
|
8
8
|
maybeEscalateOnViolation,
|
|
9
9
|
maybeQuarantineOnContradiction,
|
|
10
10
|
readRecentEscalations
|
|
11
|
-
} from "./index-
|
|
12
|
-
import"./index-
|
|
13
|
-
import"./index-
|
|
11
|
+
} from "./index-m8vrw3pt.js";
|
|
12
|
+
import"./index-w2kp2zvf.js";
|
|
13
|
+
import"./index-kj86tyrs.js";
|
|
14
14
|
import"./index-ae75rja9.js";
|
|
15
15
|
import"./index-q27bajqb.js";
|
|
16
16
|
import"./index-bk5tah7q.js";
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
resolveKnowledgeCounterBaselinePath,
|
|
27
27
|
resolveKnowledgeEventsPath,
|
|
28
28
|
resolveLegacyApplicationLogPath
|
|
29
|
-
} from "./index-
|
|
29
|
+
} from "./index-kj86tyrs.js";
|
|
30
30
|
import"./index-ae75rja9.js";
|
|
31
31
|
import"./index-q27bajqb.js";
|
|
32
32
|
import"./index-zgwm4ryv.js";
|
|
@@ -23,11 +23,11 @@ import {
|
|
|
23
23
|
validateLesson,
|
|
24
24
|
validateSkillCandidatePath,
|
|
25
25
|
validateSkillPath
|
|
26
|
-
} from "./index-
|
|
27
|
-
import"./index-
|
|
26
|
+
} from "./index-waqvy9a5.js";
|
|
27
|
+
import"./index-pgyp3tta.js";
|
|
28
28
|
import"./index-rtry5xyf.js";
|
|
29
|
-
import"./index-
|
|
30
|
-
import"./index-
|
|
29
|
+
import"./index-w2kp2zvf.js";
|
|
30
|
+
import"./index-kj86tyrs.js";
|
|
31
31
|
import"./index-ae75rja9.js";
|
|
32
32
|
import"./index-q27bajqb.js";
|
|
33
33
|
import"./index-bk5tah7q.js";
|
|
@@ -9,8 +9,8 @@ import {
|
|
|
9
9
|
readDelegations,
|
|
10
10
|
recordPendingDelegation,
|
|
11
11
|
sweepStaleDelegations
|
|
12
|
-
} from "./index-
|
|
13
|
-
import"./index-
|
|
12
|
+
} from "./index-y2pfmd0z.js";
|
|
13
|
+
import"./index-s80bsjkj.js";
|
|
14
14
|
import"./index-z6xqpmqg.js";
|
|
15
15
|
import"./index-zjygnfay.js";
|
|
16
16
|
import"./index-zgwm4ryv.js";
|
|
@@ -9,8 +9,8 @@ import {
|
|
|
9
9
|
sweepStale,
|
|
10
10
|
unsubscribe,
|
|
11
11
|
updateSnapshot
|
|
12
|
-
} from "./index-
|
|
13
|
-
import"./index-
|
|
12
|
+
} from "./index-g4mnf3p5.js";
|
|
13
|
+
import"./index-s80bsjkj.js";
|
|
14
14
|
import"./index-z6xqpmqg.js";
|
|
15
15
|
import"./index-zjygnfay.js";
|
|
16
16
|
import"./index-zgwm4ryv.js";
|
|
@@ -4,8 +4,8 @@ import {
|
|
|
4
4
|
alreadyCuratedThisGeneration,
|
|
5
5
|
claimNextScanBatch,
|
|
6
6
|
getScanStatus
|
|
7
|
-
} from "./index-
|
|
8
|
-
import"./index-
|
|
7
|
+
} from "./index-5fnc76da.js";
|
|
8
|
+
import"./index-w2kp2zvf.js";
|
|
9
9
|
import"./index-ae75rja9.js";
|
|
10
10
|
import"./index-q27bajqb.js";
|
|
11
11
|
import"./index-bk5tah7q.js";
|
|
@@ -33,12 +33,12 @@ import {
|
|
|
33
33
|
sanitizeSlug,
|
|
34
34
|
selectCandidateEntries,
|
|
35
35
|
writeEvalStub
|
|
36
|
-
} from "./index-
|
|
37
|
-
import"./index-
|
|
38
|
-
import"./index-
|
|
36
|
+
} from "./index-wy5jy3m9.js";
|
|
37
|
+
import"./index-waqvy9a5.js";
|
|
38
|
+
import"./index-pgyp3tta.js";
|
|
39
39
|
import"./index-rtry5xyf.js";
|
|
40
|
-
import"./index-
|
|
41
|
-
import"./index-
|
|
40
|
+
import"./index-w2kp2zvf.js";
|
|
41
|
+
import"./index-kj86tyrs.js";
|
|
42
42
|
import"./index-ae75rja9.js";
|
|
43
43
|
import"./index-q27bajqb.js";
|
|
44
44
|
import"./index-bk5tah7q.js";
|
package/dist/config/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export { ALL_AGENT_NAMES, ALL_SUBAGENT_NAMES, DEFAULT_MODELS, isQAAgent, isSubag
|
|
|
3
3
|
export type { ApprovalEvidence, BaseEvidence, DiffEvidence, Evidence, EvidenceBundle, EvidenceType, EvidenceVerdict, NoteEvidence, ReviewEvidence, TestEvidence, } from './evidence-schema';
|
|
4
4
|
export { ApprovalEvidenceSchema, BaseEvidenceSchema, DiffEvidenceSchema, EVIDENCE_MAX_JSON_BYTES, EVIDENCE_MAX_PATCH_BYTES, EVIDENCE_MAX_TASK_BYTES, EvidenceBundleSchema, EvidenceSchema, EvidenceTypeSchema, EvidenceVerdictSchema, NoteEvidenceSchema, ReviewEvidenceSchema, TestEvidenceSchema, } from './evidence-schema';
|
|
5
5
|
export type { ConfigBuildResult, ConfigLoadResult, ConfigRecovery, } from './loader';
|
|
6
|
-
export { loadAgentPrompt, loadPluginConfig, loadPluginConfigWithMeta, loadPluginConfigWithMetaAsync, } from './loader';
|
|
6
|
+
export { getSafeDefaultConfigLoadResult, loadAgentPrompt, loadPluginConfig, loadPluginConfigWithMeta, loadPluginConfigWithMetaAsync, } from './loader';
|
|
7
7
|
import { loadPluginConfigWithMeta } from './loader';
|
|
8
8
|
/**
|
|
9
9
|
* Test-only dependency-injection seam — see `gitignore-warning.ts:_internals`
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config loader recovery persistence module.
|
|
3
|
+
*
|
|
4
|
+
* Persists recovery metadata emitted by the config loader so that:
|
|
5
|
+
* - `/swarm config doctor` can surface stale recovery artifacts
|
|
6
|
+
* (left by a prior process that crashed before cleanup).
|
|
7
|
+
* - Post-init flush (via `flushPendingLoaderRecovery`) can record
|
|
8
|
+
* recovery warnings without blocking plugin init.
|
|
9
|
+
* - Stale artifacts from older loads are cleaned up atomically
|
|
10
|
+
* when a newer load completes successfully (SC-002.3).
|
|
11
|
+
*
|
|
12
|
+
* Conflict resolution: every completed load writes a recovery artifact
|
|
13
|
+
* tagged with the tuple `{loadStartedAt, pid, inProcessCounter}`. When
|
|
14
|
+
* an artifact already exists, the new load wins iff its tuple is
|
|
15
|
+
* numerically greater than the existing one (component-wise comparison).
|
|
16
|
+
* This prevents a slower or earlier process from overwriting a newer
|
|
17
|
+
* recovery result.
|
|
18
|
+
*
|
|
19
|
+
* Artifact format (JSON):
|
|
20
|
+
* ```json
|
|
21
|
+
* {
|
|
22
|
+
* "loadStartedAt": number,
|
|
23
|
+
* "pid": number,
|
|
24
|
+
* "inProcessCounter": number,
|
|
25
|
+
* "sources": string[],
|
|
26
|
+
* "fingerprint": string,
|
|
27
|
+
* "warnings": RecoveryWarning[]
|
|
28
|
+
* }
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* Lives under `src/config/` alongside `loader.ts` so the loader can
|
|
32
|
+
* import it without cross-module dependency violations.
|
|
33
|
+
*/
|
|
34
|
+
import * as fsPromises from 'node:fs/promises';
|
|
35
|
+
import { bunWrite } from '../utils/bun-compat.js';
|
|
36
|
+
import type { RecoveryWarning } from './sanitize-malformed-values.js';
|
|
37
|
+
/** Shape of the on-disk recovery artifact. */
|
|
38
|
+
export interface LoaderRecoveryArtifact {
|
|
39
|
+
/** Date.now() when the config load started. */
|
|
40
|
+
loadStartedAt: number;
|
|
41
|
+
/** process.pid of the loading process. */
|
|
42
|
+
pid: number;
|
|
43
|
+
/** Monotonic per-process counter for same-process disambiguation. */
|
|
44
|
+
inProcessCounter: number;
|
|
45
|
+
/** Sorted source paths that contributed to the config merge. */
|
|
46
|
+
sources: string[];
|
|
47
|
+
/** SHA-256 fingerprint of the merged raw config. */
|
|
48
|
+
fingerprint: string;
|
|
49
|
+
/** Recovery warnings from the load (empty for clean loads). */
|
|
50
|
+
warnings: RecoveryWarning[];
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Input shape accepted by the public API.
|
|
54
|
+
* Matches `LoadPluginConfigWithRecoveryResult.pendingPersistence`
|
|
55
|
+
* from `loader.ts`.
|
|
56
|
+
*/
|
|
57
|
+
export type PendingLoaderRecoveryData = Omit<LoaderRecoveryArtifact, 'warnings'> & {
|
|
58
|
+
warnings: RecoveryWarning[];
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Test-only dependency-injection seam — replaces `fsPromises.readFile`
|
|
62
|
+
* and `bunWrite` so tests can exercise failure paths without
|
|
63
|
+
* `mock.module` leakage (AGENTS.md §7).
|
|
64
|
+
*/
|
|
65
|
+
export declare const _internals: {
|
|
66
|
+
readFile: typeof fsPromises.readFile;
|
|
67
|
+
write: typeof bunWrite;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Persist loader recovery data to `<directory>/.swarm/advisories/loader-recovery.json`.
|
|
71
|
+
*
|
|
72
|
+
* Every completed load atomically writes the artifact under deterministic
|
|
73
|
+
* conflict resolution: the new load wins iff its `{loadStartedAt, pid,
|
|
74
|
+
* inProcessCounter}` tuple is numerically greater than the existing artifact's.
|
|
75
|
+
* Clean loads (no recovery warnings) write `warnings: []`, which serves as
|
|
76
|
+
* the SC-002.3 stale-artifact cleanup signal.
|
|
77
|
+
*
|
|
78
|
+
* Failures (filesystem errors, permission issues) are logged via
|
|
79
|
+
* `advisoryWarn` and never thrown — this is best-effort persistence.
|
|
80
|
+
*
|
|
81
|
+
* @param directory - Project root directory (the `.swarm/` parent).
|
|
82
|
+
* @param data - Recovery data from the loader's `pendingPersistence`.
|
|
83
|
+
*/
|
|
84
|
+
export declare function persistLoaderRecovery(directory: string, data: PendingLoaderRecoveryData): Promise<void>;
|
|
85
|
+
/**
|
|
86
|
+
* Synchronous wrapper that defers `persistLoaderRecovery` via `queueMicrotask`.
|
|
87
|
+
*
|
|
88
|
+
* This is designed for the post-init flush path (task 1.5) where the caller
|
|
89
|
+
* must not await the write — the write is fire-and-forget, with errors
|
|
90
|
+
* routed to `advisoryWarn` inside `persistLoaderRecovery`.
|
|
91
|
+
*
|
|
92
|
+
* @param directory - Project root directory (the `.swarm/` parent).
|
|
93
|
+
* @param pendingData - Recovery data from the loader's `pendingPersistence`.
|
|
94
|
+
*/
|
|
95
|
+
export declare function flushPendingLoaderRecovery(directory: string, pendingData: PendingLoaderRecoveryData): void;
|
package/dist/config/loader.d.ts
CHANGED
|
@@ -24,10 +24,14 @@ export declare function formatZodIssues(error: z.ZodError): string;
|
|
|
24
24
|
* the remaining configuration was preserved.
|
|
25
25
|
* 'user_only' – project config was discarded (failed validation and
|
|
26
26
|
* targeted recovery); user config alone was used.
|
|
27
|
+
* 'sanitized_values' – merged and user configs both failed, but recursive
|
|
28
|
+
* malformed-value recovery (step 7b, issue #1690)
|
|
29
|
+
* dropped the smallest invalid leaves/sections so the
|
|
30
|
+
* remaining valid configuration could load.
|
|
27
31
|
* 'guardrails_defaults'– neither merged nor user config was recoverable;
|
|
28
32
|
* fell back to fail-secure guardrails-only defaults.
|
|
29
33
|
*/
|
|
30
|
-
export type ConfigRecovery = 'none' | 'stripped_keys' | 'user_only' | 'guardrails_defaults';
|
|
34
|
+
export type ConfigRecovery = 'none' | 'stripped_keys' | 'user_only' | 'sanitized_values' | 'guardrails_defaults';
|
|
31
35
|
/** Full result from the shared config-build core. */
|
|
32
36
|
export type ConfigBuildResult = {
|
|
33
37
|
config: PluginConfig;
|
|
@@ -71,6 +75,27 @@ export declare function loadPluginConfig(directory: string): PluginConfig;
|
|
|
71
75
|
* exactly once, no double-read.
|
|
72
76
|
*/
|
|
73
77
|
export declare function loadPluginConfigWithMeta(directory: string): ConfigLoadResult;
|
|
78
|
+
/**
|
|
79
|
+
* Safe-default `ConfigLoadResult` for init-path timeout / error fallback.
|
|
80
|
+
*
|
|
81
|
+
* Produces the same shape `loadPluginConfigWithMeta[Async]` returns when no
|
|
82
|
+
* config file exists on disk: empty config + guardrails enabled + no recovery.
|
|
83
|
+
* Used by `src/index.ts` when the parallelized config read times out or fails
|
|
84
|
+
* (Invariant 1 — init must remain bounded). A parity test in
|
|
85
|
+
* `tests/unit/config/loader-safe-default.test.ts` asserts this matches the
|
|
86
|
+
* classification fields the loader returns for a missing config file.
|
|
87
|
+
*
|
|
88
|
+
* Classification fields:
|
|
89
|
+
* - `loadedFromFile: false` — on timeout we cannot know whether a file
|
|
90
|
+
* existed (the `stat` itself may have stalled); `false` is the safe
|
|
91
|
+
* choice that avoids the guardrails-disabled warning gated by this
|
|
92
|
+
* flag at `src/index.ts` (the only init-path consumer).
|
|
93
|
+
* - `configHadErrors: false` — we did not observe a corrupt/oversized
|
|
94
|
+
* config, only a slow one; fail-closed consumers (e.g. the Full-Auto
|
|
95
|
+
* `locked` activation guard) treat this as "config defaults", which
|
|
96
|
+
* matches the runtime behavior of the safe-default `PluginConfig`.
|
|
97
|
+
*/
|
|
98
|
+
export declare function getSafeDefaultConfigLoadResult(): ConfigLoadResult;
|
|
74
99
|
/**
|
|
75
100
|
* Async variant of `loadPluginConfigWithMeta`. Used by the plugin entry
|
|
76
101
|
* (issue #704) so initialization does not perform synchronous fs reads.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fixed-point recovery helper for malformed config values.
|
|
3
|
+
*
|
|
4
|
+
* Given a Zod schema and a raw config object, this module iteratively
|
|
5
|
+
* removes malformed fields/sections until the config validates cleanly.
|
|
6
|
+
* It uses ONLY `safeParse` + `issue.path`/`issue.code`/`issue.keys` as
|
|
7
|
+
* signals — no schema introspection (`_def`, `.shape`, `instanceof` along
|
|
8
|
+
* paths), making it robust across Zod versions (v3 and v4+).
|
|
9
|
+
*
|
|
10
|
+
* Algorithm (SME-designed fixed-point):
|
|
11
|
+
* 1. Fast path: if `safeParse` succeeds, return the original reference
|
|
12
|
+
* (no clone cost on the happy path).
|
|
13
|
+
* 2. Deep-clone the input exactly once.
|
|
14
|
+
* 3. Loop: parse → build leaf drop-set from issue paths → remove deepest
|
|
15
|
+
* leaves first → re-parse. If no new leaves found but fresh issues
|
|
16
|
+
* remain, escalate to nearest non-removed ancestor. If still stuck,
|
|
17
|
+
* drop entire implicated top-level sections.
|
|
18
|
+
* 4. Terminate when parse succeeds or fuel is exhausted.
|
|
19
|
+
* 5. Emit ancestor-suppressed, deterministically-ordered warnings.
|
|
20
|
+
*
|
|
21
|
+
* This is a PURE function — no side effects, no I/O, no logging.
|
|
22
|
+
*/
|
|
23
|
+
import type { z } from 'zod';
|
|
24
|
+
/** Dotted path identifying the dropped unit, e.g. "council.enabled" or "pr_monitor". */
|
|
25
|
+
export interface RecoveryWarning {
|
|
26
|
+
section: string;
|
|
27
|
+
/** Currently always 'warn'; reserved for future severity levels. */
|
|
28
|
+
severity: 'warn';
|
|
29
|
+
/** Human-readable description of what was dropped and why. */
|
|
30
|
+
message: string;
|
|
31
|
+
/** Full Zod error path if available (for debugging / downstream use). */
|
|
32
|
+
path?: string;
|
|
33
|
+
}
|
|
34
|
+
export interface SanitizeResult {
|
|
35
|
+
/** The recovered config object. Keys omitted here will be filled by Zod defaults
|
|
36
|
+
* at parse time — callers should re-parse this through the schema. */
|
|
37
|
+
config: Record<string, unknown>;
|
|
38
|
+
/** Warnings for every field or section that was dropped during recovery. */
|
|
39
|
+
recoveryWarnings: RecoveryWarning[];
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Attempt to recover a malformed config by iteratively dropping invalid
|
|
43
|
+
* values until the config validates. This is a generic helper that works
|
|
44
|
+
* with any Zod schema and avoids all schema introspection.
|
|
45
|
+
*
|
|
46
|
+
* The returned `config` is the cleaned raw config — callers should pass it
|
|
47
|
+
* through `schema.parse()` to get fully typed output with defaults applied.
|
|
48
|
+
*
|
|
49
|
+
* @param schema - The Zod schema to validate against.
|
|
50
|
+
* @param rawConfig - The raw parsed-config object (not yet Zod-validated).
|
|
51
|
+
* @returns The cleaned config plus any warnings emitted during recovery.
|
|
52
|
+
*/
|
|
53
|
+
export declare function sanitizeMalformedValues(schema: z.ZodTypeAny, rawConfig: Record<string, unknown>): SanitizeResult;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import type { Plugin } from '@opencode-ai/plugin';
|
|
2
|
+
import { loadPluginConfigWithMetaAsync } from './config';
|
|
2
3
|
import { createRepoGraphBuilderHook } from './hooks';
|
|
4
|
+
import { loadSnapshot } from './session/snapshot-reader.js';
|
|
5
|
+
import { ensureSwarmGitExcluded } from './utils/gitignore-warning';
|
|
3
6
|
/**
|
|
4
7
|
* FIFO-cap a session-keyed Map to at most `max` entries, evicting oldest first.
|
|
5
8
|
* Values tracked by these maps are plain data (timestamps/usage snapshots), never
|
|
@@ -18,6 +21,9 @@ declare function schedulePostResolutionTasks(tasks: readonly PostResolutionTask[
|
|
|
18
21
|
export declare function overrideIndexInternalsForTest(overrides: {
|
|
19
22
|
createRepoGraphBuilderHook?: typeof createRepoGraphBuilderHook;
|
|
20
23
|
schedulePostResolutionTasks?: typeof schedulePostResolutionTasks;
|
|
24
|
+
loadPluginConfigWithMetaAsync?: typeof loadPluginConfigWithMetaAsync;
|
|
25
|
+
loadSnapshot?: typeof loadSnapshot;
|
|
26
|
+
ensureSwarmGitExcluded?: typeof ensureSwarmGitExcluded;
|
|
21
27
|
}): () => void;
|
|
22
28
|
export declare function schedulePostResolutionTasksForTest(tasks: readonly PostResolutionTask[]): void;
|
|
23
29
|
declare const _default: {
|